Skip to content

Commit b4c2b47

Browse files
authored
Merge pull request #116 from digi-trust/master
v1.2.0 Customizable CSS
2 parents f6011c0 + 0604623 commit b4c2b47

30 files changed

+510
-172
lines changed

.eslintrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
"no-eval": 2,
6060
"no-implied-eval": 2,
6161
"no-new-func": 2,
62-
"guard-for-in": 2,
62+
"guard-for-in": 0,
6363
"eqeqeq": 1,
6464
"no-else-return": 2,
6565
"no-redeclare": 2,

src/components/app.jsx

Lines changed: 91 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,74 @@ export default class App extends Component {
1111
store: this.props.store
1212
};
1313

14+
elementsWithReplaceableCss = {
15+
// Tables
16+
"thead tr": {"background-color": this.props.config.css["color-table-background"]},
17+
"tr[class*=even]": {"background-color": this.props.config.css["color-table-background"]},
18+
19+
// Purposes
20+
"div[class*=purposes_purposeItem]": {
21+
"background-color": this.props.config.css["color-secondary"],
22+
"color": this.props.config.css["color-text-secondary"]
23+
},
24+
"div[class*=selectedPurpose]": {
25+
"background-color": this.props.config.css["color-primary"],
26+
"color": this.props.config.css["color-background"],
27+
},
28+
29+
// Footer
30+
"div[class*=footer_footer]": {
31+
"border-top": "3px solid " + this.props.config.css["color-border"],
32+
"background-color": this.props.config.css["color-background"]
33+
},
34+
"div[class*=footerV2_extended]": {"border-top": "3px solid " + this.props.config.css["color-border"]},
35+
"div[class*=footerV2_container]": {"background-color": this.props.config.css["color-background"]},
36+
"svg": {
37+
"background-color": this.props.config.css["color-background"],
38+
"fill": this.props.config.css["color-primary"]
39+
},
40+
41+
// Vendors
42+
"[class*=active]": {"color": this.props.config.css["color-primary"]},
43+
44+
// Application wide
45+
"div[name^=content]": {
46+
"box-shadow": "0 0 0 3px " + this.props.config.css["color-border"],
47+
"background-color": this.props.config.css["color-background"]
48+
},
49+
":not([name*=ctrl])": {
50+
"font-family": this.props.config.css["font-family"]
51+
},
52+
"[class*=primaryText]": {"color": this.props.config.css["color-text-primary"]},
53+
"[class*=secondaryText]": {"color": this.props.config.css["color-text-secondary"]},
54+
"a": {"color": this.props.config.css["color-linkColor"]},
55+
"span[class*=isSelected] [class*=visualizationGlow]": {"background-color": this.props.config.css["color-primary"]},
56+
"span[class*=isSelected] [class*=visualizationContainer]": {"background-color": this.props.config.css["color-primary"]},
57+
"[class*=button]": {
58+
"color": this.props.config.css["color-background"],
59+
"background-color": this.props.config.css["color-primary"],
60+
},
61+
"[class*=button_invert]": {
62+
"color": this.props.config.css["color-primary"],
63+
"border": "2px solid " + this.props.config.css["color-primary"],
64+
"background-color": this.props.config.css["color-background"]
65+
},
66+
};
67+
68+
updateCSSPrefs = () => {
69+
const elems = this.elementsWithReplaceableCss;
70+
const base = this.base;
71+
for(let elem in elems) {
72+
let cssRules = elems[elem];
73+
let selectedEls = base.querySelectorAll(elem) || [];
74+
selectedEls.forEach(function(currentEl) {
75+
for(let cssProp in cssRules) {
76+
currentEl.style[cssProp] = cssRules[cssProp];
77+
}
78+
})
79+
}
80+
};
81+
1482
onSave = () => {
1583
const { store, notify } = this.props;
1684
store.persist();
@@ -19,7 +87,6 @@ export default class App extends Component {
1987
store.toggleFooterShowing(true);
2088
};
2189

22-
2390
updateState = (store) => {
2491
this.setState({ store });
2592
};
@@ -29,8 +96,24 @@ export default class App extends Component {
2996
store.subscribe(this.updateState);
3097
}
3198

32-
render(props, state) {
99+
componentDidMount() {
100+
const { store } = this.state;
101+
const { config } = this.props;
102+
103+
if (config.css["custom-font-url"]) {
104+
let head = document.head;
105+
let link = document.createElement("link");
106+
link.type = "text/css";
107+
link.rel = "stylesheet";
108+
link.href = config.css["custom-font-url"];
109+
head.appendChild(link);
110+
}
33111

112+
store.subscribe(this.updateCSSPrefs);
113+
this.updateCSSPrefs();
114+
}
115+
116+
render(props, state) {
34117
const { store } = state;
35118
const { config } = props;
36119
const userLocalization = config.localization[currentLocale];
@@ -41,15 +124,21 @@ export default class App extends Component {
41124
store={store}
42125
localization={userLocalization}
43126
onSave={this.onSave}
127+
config={config}
128+
updateCSSPrefs={this.updateCSSPrefs}
44129
/>
45130
<PopupFooter
46131
store={store}
47132
localization={userLocalization}
48133
onSave={this.onSave}
134+
config={config}
135+
updateCSSPrefs={this.updateCSSPrefs}
49136
/>
50137
<Footer
51138
store={store}
52139
localization={userLocalization}
140+
config={config}
141+
updateCSSPrefs={this.updateCSSPrefs}
53142
/>
54143
</div>
55144
);

src/components/app.less

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
font-family: 'acumin-pro-wide', sans-serif;
77
font-weight: 400;
88
font-size: 16px;
9-
line-height: 1.5;
9+
line-height: @line-height;
1010

1111
* {
1212
box-sizing: border-box;

src/components/app.test.js

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { h, render } from 'preact';
33
import { expect } from 'chai';
44
import style from './app.less';
55
import Store from '../lib/store';
6-
6+
import config from '../lib/config';
77
import App from './app';
88

99
describe('App', () => {
@@ -25,14 +25,14 @@ describe('App', () => {
2525

2626

2727
it('should render app content', () => {
28-
render(<App store={new Store()} config={{localization: {}}} />, scratch);
28+
render(<App store={new Store()} config={config} />, scratch);
2929
expect(scratch.innerHTML).to.contain(style.gdpr);
3030
});
3131

32-
it('add a listener to the store to receive updates', () => {
32+
it('add listeners to the store to receive updates and to know when to update CSS', () => {
3333
const store = new Store();
34-
render(<App store={store} config={{localization: {}}} />, scratch);
35-
expect(store.listeners.size).to.equal(1);
34+
render(<App store={store} config={config} />, scratch);
35+
expect(store.listeners.size).to.equal(2);
3636
});
3737

3838
it('persist state on save', () => {
@@ -44,8 +44,8 @@ describe('App', () => {
4444
let app;
4545
render(<App
4646
store={store}
47+
config={config}
4748
notify={notify}
48-
config={{localization: {}}}
4949
ref={ref => app = ref}
5050
/>, scratch);
5151

@@ -62,13 +62,29 @@ describe('App', () => {
6262
let app;
6363
render(<App
6464
store={store}
65+
config={config}
6566
notify={() => {}}
66-
config={{localization: {}}}
6767
ref={ref => app = ref}
6868
/>, scratch);
6969

7070
expect(app.state.store.vendorConsentData.selectedVendorIds).to.deep.equal(new Set());
7171
store.selectVendor(1, true);
7272
expect(app.state.store.vendorConsentData.selectedVendorIds).to.deep.equal(new Set([1]));
7373
});
74+
75+
it('respects css config', () => {
76+
const store = new Store();
77+
config.update({ css: { 'font-family': 'MonoType' }});
78+
let app;
79+
render(<App
80+
store={store}
81+
config={config}
82+
notify={() => {}}
83+
ref={ref => app = ref}
84+
/>, scratch);
85+
86+
expect(app.props.config.css['font-family']).to.equal('MonoType');
87+
expect(scratch.style['font-family']).to.not.equal('MonoType');
88+
expect(scratch.innerHTML).to.contain('style="font-family: MonoType;"');
89+
});
7490
});

src/components/closebutton/closebutton.jsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ export default class CloseButton extends Component {
1010
hasBorder: true
1111
};
1212

13+
componentDidMount() {
14+
this.props.updateCSSPrefs();
15+
}
16+
1317
render(props) {
1418
const {
1519
onClick,

src/components/footer/footer.jsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,27 @@ export default class Footer extends Component {
2727
showConsentTool();
2828
};
2929

30+
componentDidMount() {
31+
this.props.updateCSSPrefs();
32+
}
33+
3034
render(props) {
31-
const { store, localization } = props;
35+
const { store, localization, config, updateCSSPrefs } = props;
3236
const { isFooterShowing } = store;
3337

3438
return (
3539
<div
3640
class={style.footer}
37-
style={{ display: isFooterShowing ? 'flex' : 'none' }}
41+
style={{ display: isFooterShowing && config.showFooterAfterSubmit ? 'flex' : 'none' }}
3842
>
3943
<CloseButton
4044
hasBorder={false}
4145
class={style.close}
4246
onClick={this.handleClose}
47+
config={config}
48+
updateCSSPrefs={updateCSSPrefs}
4349
/>
44-
<LocalLabel providedValue={localization && localization.footer ? localization.footer.closedMessage : ''} localizeKey='closedMessage' class={style.message}>A reminder you can control your user privacy preferences</LocalLabel>
50+
<LocalLabel providedValue={localization && localization.footer ? localization.footer.closedMessage : ''} localizeKey='closedMessage' class={style.message + " primaryText"}>A reminder you can control your user privacy preferences</LocalLabel>
4551
<a class={style.openConsent} onClick={this.handleShowConsent}>
4652
<LocalLabel providedValue={localization && localization.footer ? localization.footer.closedMessageLink : ''} localizeKey='closedMessageLink'>here</LocalLabel>
4753
</a>

src/components/footer/footer.less

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
align-items: center;
1212
justify-content: center;
1313
background: white;
14-
border-top: 2px solid @color-primary;
1514

1615
.openConsent {
1716
margin-left: 3px;

src/components/popup/details/details.jsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,19 @@ export default class Details extends Component {
5656
}
5757
};
5858

59+
componentDidMount() {
60+
this.props.updateCSSPrefs();
61+
};
62+
5963
render(props, state) {
6064
const {
6165
onCancel,
6266
onSave,
6367
onClose,
6468
store,
65-
localization
69+
localization,
70+
config,
71+
updateCSSPrefs
6672
} = props;
6773

6874
const {
@@ -89,7 +95,7 @@ export default class Details extends Component {
8995
return (
9096
<div class={style.details}>
9197
<div class={style.header}>
92-
<LocalLabel class={style.title} providedValue={localization && localization.details ? localization.details.title : ''} localizeKey='title'>Privacy Preferences</LocalLabel>
98+
<LocalLabel class={style.title + " primaryText"} providedValue={localization && localization.details ? localization.details.title : ''} localizeKey='title'>Privacy Preferences</LocalLabel>
9399
</div>
94100
<div class={style.body}>
95101
<Panel selectedIndex={selectedPanelIndex}>
@@ -104,6 +110,8 @@ export default class Details extends Component {
104110
selectPurpose={selectPurpose}
105111
selectCustomPurpose={selectCustomPurpose}
106112
onShowVendors={this.handleShowVendors}
113+
config={config}
114+
updateCSSPrefs={updateCSSPrefs}
107115
/>
108116
<Vendors
109117
localization={localization}
@@ -113,6 +121,8 @@ export default class Details extends Component {
113121
vendors={vendors}
114122
onShowPurposes={this.handleShowPurposes}
115123
onHandleEnableAll={this.handleEnableAll}
124+
config={config}
125+
updateCSSPrefs={updateCSSPrefs}
116126
/>
117127
</Panel>
118128
</div>

src/components/popup/details/details.test.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ describe('Details', () => {
1616
it('should render with purpose panel initially', () => {
1717
const store = new Store();
1818
store.isConsentToolShowing = false;
19-
const details = <Details store={store} />;
19+
const details = <Details updateCSSPrefs={() => {}} store={store} />;
2020
expect(details).to.contain(purposesStyle.purposes);
2121
});
2222

@@ -26,6 +26,7 @@ describe('Details', () => {
2626

2727
let details;
2828
render(<Details
29+
updateCSSPrefs={() => {}}
2930
store={store}
3031
ref={ref => details = ref}
3132
/>, scratch);

0 commit comments

Comments
 (0)