@zcomponent/core 0.0.23 → 0.0.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -119,4 +119,94 @@
119
119
 
120
120
  .zcomponent-textalert-shown {
121
121
  opacity: 1;
122
+ }
123
+
124
+ .zcomponent-cookieconsent {
125
+ z-index: 10000000;
126
+ position: fixed;
127
+ top: 0;
128
+ left: 0;
129
+ width: 100%;
130
+ height: 100%;
131
+ background: rgba(0, 0, 0, 0.7);
132
+ display: flex;
133
+ flex-direction: column;
134
+ align-items: center;
135
+ }
136
+
137
+ #zcomponent-cookieconsent-panel {
138
+ background: white;
139
+ border-top-left-radius: 8px;
140
+ border-top-right-radius: 8px;
141
+ margin-top: auto;
142
+ max-width: 500px;
143
+ font-family: sans-serif;
144
+ padding: 24px;
145
+ margin-left: 24px;
146
+ margin-right: 24px;
147
+ max-height: 80%;
148
+ overflow: scroll;
149
+ }
150
+
151
+ #zcomponent-cookieconsent-panel > h1 {
152
+ font-size: 24px;
153
+ }
154
+
155
+ #zcomponent-cookieconsent-panel button {
156
+ padding: 12px 24px;
157
+ background: none;
158
+ border: 2px solid black;
159
+ border-radius: 4px;
160
+ color: black;
161
+ }
162
+
163
+ #zcomponent-cookieconsent-panel button {
164
+ padding: 12px 24px;
165
+ background: none;
166
+ border: 2px solid black;
167
+ border-radius: 4px;
168
+ color: black;
169
+ display: block;
170
+ outline: none;
171
+ }
172
+
173
+ #zcomponent-cookieconsent-panel #zcomponent-cookieconsent-settings {
174
+ padding: 0;
175
+ border: 0;
176
+ background: none;
177
+ font-weight: bold;
178
+ text-decoration: underline;
179
+ padding-top: 12px;
180
+ }
181
+
182
+ .zcomponent-cookieconsent-type {
183
+ position: relative;
184
+ }
185
+
186
+ .zcomponent-cookieconsent-type input {
187
+ float: right;
188
+ /* top: 0px; */
189
+ /* right: 0px; */
190
+ width: 32px;
191
+ height: 32px;
192
+ }
193
+
194
+ #zcomponent-cookieconsent-panel h3 {
195
+ margin-bottom: 6px;
196
+ }
197
+
198
+ #zcomponent-cookieconsent-panel h5 {
199
+ margin-bottom: 6px;
200
+ }
201
+
202
+ #zcomponent-cookieconsent-panel #zcomponent-cookieconsent-save {
203
+ padding-top: 12px;
204
+ }
205
+
206
+ #zcomponent-cookieconsent-panel ul {
207
+ list-style-type: none;
208
+ }
209
+
210
+ #zcomponent-cookieconsent-privacypolicy {
211
+ padding-bottom: 12px;
122
212
  }
@@ -0,0 +1,157 @@
1
+ import { Component } from "../component";
2
+ import { ContextManager } from "../context";
3
+ import { Observable } from "../observable";
4
+ export interface DefaultCookieConsentConstructorProps {
5
+ /**
6
+ * Show the cookie consent dialog when the experience starts, rather than when the component is initialized.
7
+ * @zui
8
+ * @zdefault false
9
+ */
10
+ waitForStart: boolean;
11
+ /**
12
+ * Only show the cookie consent dialog if the experience contains analytics components that indicate they use cookies.
13
+ * @zui
14
+ * @zdefault true
15
+ */
16
+ onlyShowIfVendors: boolean;
17
+ /**
18
+ * Previews how the consent dialog looks at design time.
19
+ * @zui
20
+ * @zdefault false
21
+ */
22
+ preview: boolean;
23
+ }
24
+ /**
25
+ * @zcomponent
26
+ * @zgroup Cookie Consent
27
+ * @zicon cookie
28
+ */
29
+ export declare class DefaultCookieConsent extends Component {
30
+ constructorProps: DefaultCookieConsentConstructorProps;
31
+ /**
32
+ * @zprop
33
+ * @zgroup Consent Screen
34
+ * @zgrouppriority 20
35
+ * @zdefault "This website uses cookies to store information on your computer."
36
+ */
37
+ title: Observable<string>;
38
+ /**
39
+ * @zprop
40
+ * @zgroup Consent Screen
41
+ * @zgrouppriority 20
42
+ * @zdefault "Some of these cookies are essential, while others help us to improve your experience by providing insights into how the site is being used."
43
+ */
44
+ description: Observable<string>;
45
+ /**
46
+ * @zprop
47
+ * @zgroup Settings
48
+ * @zgrouppriority 10
49
+ * @zdefault "Privacy Policy"
50
+ */
51
+ privacyPolicyText: Observable<string>;
52
+ /**
53
+ * @zprop
54
+ * @zgroup Settings
55
+ * @zgrouppriority 10
56
+ * @zdefault ""
57
+ */
58
+ privacyPolicyURL: Observable<string>;
59
+ /**
60
+ * @zprop
61
+ * @zgroup Consent Screen
62
+ * @zgrouppriority 20
63
+ * @zdefault "I Accept Cookies"
64
+ */
65
+ acceptButton: Observable<string>;
66
+ /**
67
+ * @zprop
68
+ * @zgroup Consent Screen
69
+ * @zgrouppriority 20
70
+ * @zdefault "Settings"
71
+ */
72
+ settingsButton: Observable<string>;
73
+ /**
74
+ * @zprop
75
+ * @zgroup Consent Screen
76
+ * @zgrouppriority 20
77
+ * @zdefault "Save"
78
+ */
79
+ saveButton: Observable<string>;
80
+ /**
81
+ * @zprop
82
+ * @zgroup Settings
83
+ * @zgrouppriority 10
84
+ * @zdefault "Essential"
85
+ */
86
+ essentialTitle: Observable<string>;
87
+ /**
88
+ * @zprop
89
+ * @zgroup Settings
90
+ * @zgrouppriority 10
91
+ * @zdefault "Cookies that are necessary to provide the service."
92
+ */
93
+ essentialDescription: Observable<string>;
94
+ /**
95
+ * @zprop
96
+ * @zgroup Settings
97
+ * @zgrouppriority 10
98
+ * @zdefault "Functional"
99
+ */
100
+ functionalTitle: Observable<string>;
101
+ /**
102
+ * @zprop
103
+ * @zgroup Settings
104
+ * @zgrouppriority 10
105
+ * @zdefault "Cookies that provide you with useful functionality, such as saving your preferences."
106
+ */
107
+ functionalDescription: Observable<string>;
108
+ /**
109
+ * @zprop
110
+ * @zgroup Settings
111
+ * @zgrouppriority 10
112
+ * @zdefault "Performance"
113
+ */
114
+ performanceTitle: Observable<string>;
115
+ /**
116
+ * @zprop
117
+ * @zgroup Settings
118
+ * @zgrouppriority 10
119
+ * @zdefault "Cookies that help us measure and understand how the site is being used."
120
+ */
121
+ performanceDescription: Observable<string>;
122
+ /**
123
+ * @zprop
124
+ * @zgroup Settings
125
+ * @zgrouppriority 10
126
+ * @zdefault "Marketing"
127
+ */
128
+ marketingTitle: Observable<string>;
129
+ /**
130
+ * @zprop
131
+ * @zgroup Settings
132
+ * @zgrouppriority 10
133
+ * @zdefault "Cookies that help us market our site and services."
134
+ */
135
+ marketingDescription: Observable<string>;
136
+ /**
137
+ * @zprop
138
+ * @zgroup Settings
139
+ * @zgrouppriority 10
140
+ * @zdefault "Required"
141
+ */
142
+ required: Observable<string>;
143
+ private _dom;
144
+ private _functional;
145
+ private _performance;
146
+ private _marketing;
147
+ constructor(contextManager: ContextManager, constructorProps: DefaultCookieConsentConstructorProps);
148
+ private _loadDOM;
149
+ private _save;
150
+ private _createEntry;
151
+ private _getConsentStatus;
152
+ private _setConsentStatus;
153
+ show(isSettings: boolean): void;
154
+ hide(): void;
155
+ acceptAll(): void;
156
+ dispose(): never;
157
+ }
@@ -0,0 +1,205 @@
1
+ import { Component } from "../component";
2
+ import { ConsentStatus, CookieConsentContext, CookieType, Status, useCookieConsentFunctional, useCookieConsentMarketing, useCookieConsentPerformance, useMarketingVendors, usePerformanceVendors } from "../contexts/cookieconsentcontext";
3
+ import { isDesignTime } from "../contexts/environmentcontext";
4
+ import { constructed, started } from "../contexts/loadcontext";
5
+ import { Observable } from "../observable";
6
+ const html = `
7
+ <div id='zcomponent-cookieconsent-panel'>
8
+ <h1 id='zcomponent-cookieconsent-title'></h1>
9
+ <p id='zcomponent-cookieconsent-description'></p>
10
+ <a id='zcomponent-cookieconsent-privacypolicy' target='_blank' ref='noreferrer noopener'></a>
11
+ </div>
12
+ `;
13
+ /**
14
+ * @zcomponent
15
+ * @zgroup Cookie Consent
16
+ * @zicon cookie
17
+ */
18
+ export class DefaultCookieConsent extends Component {
19
+ constructor(contextManager, constructorProps) {
20
+ super(contextManager, constructorProps);
21
+ this.constructorProps = constructorProps;
22
+ this._dom = document.createElement('div');
23
+ this._functional = document.createElement('input');
24
+ this._performance = document.createElement('input');
25
+ this._marketing = document.createElement('input');
26
+ const context = contextManager.get(CookieConsentContext);
27
+ context.functionalCookies.value = this._getConsentStatus(CookieType.functional);
28
+ context.performanceCookies.value = this._getConsentStatus(CookieType.performance);
29
+ context.marketingCookies.value = this._getConsentStatus(CookieType.marketing);
30
+ context.status.value = Status.initialized;
31
+ context.showSettings.value = () => this.show(true);
32
+ this._dom.classList.add('zcomponent-cookieconsent');
33
+ this.privacyPolicyText = new Observable('Privacy Policy');
34
+ this.privacyPolicyURL = new Observable('');
35
+ if (constructorProps.waitForStart)
36
+ started(contextManager).then(() => this.show(false));
37
+ else
38
+ constructed(contextManager).then(() => this.show(false));
39
+ }
40
+ _loadDOM(isSettings) {
41
+ this._dom.innerHTML = html;
42
+ this._functional.type = 'checkbox';
43
+ this._performance.type = 'checkbox';
44
+ this._marketing.type = 'checkbox';
45
+ const panel = this._dom.querySelector('#zcomponent-cookieconsent-panel');
46
+ if (!panel)
47
+ return;
48
+ const title = this._dom.querySelector('#zcomponent-cookieconsent-title');
49
+ this.title = new Observable('This website uses cookies to store information on your computer.', v => { if (title)
50
+ title.textContent = v; });
51
+ const description = this._dom.querySelector('#zcomponent-cookieconsent-description');
52
+ this.description = new Observable('Some of these cookies are essential, while others help us to improve your experience by providing insights into how the site is being used.', v => { if (description)
53
+ description.textContent = v; });
54
+ const privacyPolicy = this._dom.querySelector('#zcomponent-cookieconsent-privacypolicy');
55
+ this.privacyPolicyText.addListener(val => { if (privacyPolicy && privacyPolicy instanceof HTMLAnchorElement)
56
+ privacyPolicy.innerText = val; });
57
+ this.privacyPolicyURL.addListener(val => {
58
+ if (!privacyPolicy || !(privacyPolicy instanceof HTMLAnchorElement))
59
+ return;
60
+ privacyPolicy.style.display = val.length === 0 ? 'none' : 'block';
61
+ privacyPolicy.href = val;
62
+ });
63
+ if (isSettings) {
64
+ this.essentialTitle = new Observable('Essential');
65
+ this.essentialDescription = new Observable('Cookies that are necessary to provide the service.');
66
+ this.functionalTitle = new Observable('Functional');
67
+ this.functionalDescription = new Observable('Cookies that provide you with useful functionality, such as saving your preferences.');
68
+ this.performanceTitle = new Observable('Performance');
69
+ this.performanceDescription = new Observable('Cookies that help us measure and understand how the site is being used.');
70
+ this.marketingTitle = new Observable('Marketing');
71
+ this.marketingDescription = new Observable('Cookies that help us market our site and services.');
72
+ const requiredDOM = document.createElement('span');
73
+ requiredDOM.innerText = 'Required';
74
+ this.required = new Observable('Required', val => requiredDOM.innerText = val);
75
+ requiredDOM.style.float = 'right';
76
+ panel.appendChild(this._createEntry(this.essentialTitle, this.essentialDescription, [], requiredDOM));
77
+ panel.appendChild(this._createEntry(this.functionalTitle, this.functionalDescription, [], this._functional));
78
+ panel.appendChild(this._createEntry(this.performanceTitle, this.performanceDescription, usePerformanceVendors(this.contextManager), this._performance));
79
+ panel.appendChild(this._createEntry(this.marketingTitle, this.marketingDescription, useMarketingVendors(this.contextManager), this._marketing));
80
+ this._functional.checked = useCookieConsentFunctional(this.contextManager).value === ConsentStatus.granted;
81
+ this._performance.checked = useCookieConsentPerformance(this.contextManager).value === ConsentStatus.granted;
82
+ this._marketing.checked = useCookieConsentMarketing(this.contextManager).value === ConsentStatus.granted;
83
+ const saveButton = document.createElement('button');
84
+ saveButton.id = 'zcomponent-cookieconsent-save';
85
+ this.saveButton = new Observable('Save', v => { saveButton.textContent = v; });
86
+ panel.appendChild(saveButton);
87
+ if (!isDesignTime(this.contextManager)) {
88
+ saveButton.addEventListener('click', () => this._save());
89
+ }
90
+ return;
91
+ }
92
+ const acceptButton = document.createElement('button');
93
+ acceptButton.id = 'zcomponent-cookieconsent-accept';
94
+ this.acceptButton = new Observable('I Accept Cookies', v => { acceptButton.textContent = v; });
95
+ panel.appendChild(acceptButton);
96
+ const settingsButton = document.createElement('button');
97
+ settingsButton.id = 'zcomponent-cookieconsent-settings';
98
+ this.settingsButton = new Observable('Settings', v => { settingsButton.textContent = v; });
99
+ settingsButton.addEventListener('click', () => {
100
+ console.log('Settings click');
101
+ this._loadDOM(true);
102
+ });
103
+ panel.appendChild(settingsButton);
104
+ if (!isDesignTime(this.contextManager)) {
105
+ acceptButton.addEventListener('click', () => this.acceptAll());
106
+ }
107
+ this._dom.addEventListener('click', () => { });
108
+ }
109
+ _save() {
110
+ this._setConsentStatus(CookieType.essential, ConsentStatus.granted);
111
+ this._setConsentStatus(CookieType.functional, this._functional.checked ? ConsentStatus.granted : ConsentStatus.rejected);
112
+ this._setConsentStatus(CookieType.performance, this._performance.checked ? ConsentStatus.granted : ConsentStatus.rejected);
113
+ this._setConsentStatus(CookieType.marketing, this._marketing.checked ? ConsentStatus.granted : ConsentStatus.rejected);
114
+ this.hide();
115
+ }
116
+ _createEntry(title, description, vendors, elm) {
117
+ const container = document.createElement('div');
118
+ container.classList.add('zcomponent-cookieconsent-type');
119
+ container.appendChild(elm);
120
+ const header = document.createElement('h3');
121
+ title.addListener(val => header.innerText = val);
122
+ container.appendChild(header);
123
+ const descriptionDom = document.createElement('div');
124
+ description.addListener(val => descriptionDom.innerText = val);
125
+ container.appendChild(descriptionDom);
126
+ if (vendors.length === 0)
127
+ return container;
128
+ const ul = document.createElement('ul');
129
+ for (const vendor of vendors) {
130
+ const li = document.createElement('li');
131
+ ul.appendChild(li);
132
+ const header = document.createElement('h5');
133
+ header.innerText = vendor.name;
134
+ li.appendChild(header);
135
+ li.append(vendor.description);
136
+ li.append(document.createElement('br'));
137
+ if (vendor.privacyPolicyUrl?.length > 0) {
138
+ const privacy = document.createElement('a');
139
+ this.privacyPolicyText.addListener(val => privacy.innerText = val);
140
+ privacy.href = vendor.privacyPolicyUrl;
141
+ privacy.rel = 'noreferrer noopener';
142
+ privacy.target = '_blank';
143
+ li.appendChild(privacy);
144
+ }
145
+ }
146
+ container.appendChild(ul);
147
+ return container;
148
+ }
149
+ _getConsentStatus(type) {
150
+ const val = window.localStorage.getItem('zcomponent-cookieconsent-' + type);
151
+ if (val === null)
152
+ return ConsentStatus.unknown;
153
+ if (val === '1')
154
+ return ConsentStatus.granted;
155
+ return ConsentStatus.rejected;
156
+ }
157
+ _setConsentStatus(type, status) {
158
+ if (status === ConsentStatus.unknown)
159
+ window.localStorage.removeItem('zcomponent-cookieconsent-' + type);
160
+ else
161
+ window.localStorage.setItem('zcomponent-cookieconsent-' + type, status === ConsentStatus.granted ? '1' : '0');
162
+ if (type === CookieType.functional)
163
+ useCookieConsentFunctional(this.contextManager).value = status;
164
+ if (type === CookieType.performance)
165
+ useCookieConsentPerformance(this.contextManager).value = status;
166
+ if (type === CookieType.marketing)
167
+ useCookieConsentMarketing(this.contextManager).value = status;
168
+ }
169
+ show(isSettings) {
170
+ const designTimeOverride = isDesignTime(this.contextManager) && (this.constructorProps.preview ?? false);
171
+ if (isDesignTime(this.contextManager) && !designTimeOverride)
172
+ return;
173
+ const context = this.contextManager.get(CookieConsentContext);
174
+ if (context.functionalCookies.value !== ConsentStatus.unknown &&
175
+ context.marketingCookies.value !== ConsentStatus.unknown &&
176
+ context.performanceCookies.value !== ConsentStatus.unknown &&
177
+ !designTimeOverride)
178
+ return;
179
+ this._loadDOM(isSettings);
180
+ const acceptedEssential = window.localStorage.getItem('zcomponent-cookieconsent-essential');
181
+ if (acceptedEssential !== null && !designTimeOverride)
182
+ return;
183
+ if ((this.constructorProps.onlyShowIfVendors ?? true) && !designTimeOverride) {
184
+ const performanceVendors = usePerformanceVendors(this.contextManager);
185
+ const marketingVendors = useMarketingVendors(this.contextManager);
186
+ if (performanceVendors.length === 0 && marketingVendors.length === 0)
187
+ return;
188
+ }
189
+ document.body.appendChild(this._dom);
190
+ }
191
+ hide() {
192
+ this._dom.remove();
193
+ }
194
+ acceptAll() {
195
+ this._setConsentStatus(CookieType.essential, ConsentStatus.granted);
196
+ this._setConsentStatus(CookieType.functional, ConsentStatus.granted);
197
+ this._setConsentStatus(CookieType.performance, ConsentStatus.granted);
198
+ this._setConsentStatus(CookieType.marketing, ConsentStatus.granted);
199
+ this.hide();
200
+ }
201
+ dispose() {
202
+ this._dom.remove();
203
+ return super.dispose();
204
+ }
205
+ }
@@ -10,6 +10,12 @@ export declare enum ConsentStatus {
10
10
  "granted" = "granted",
11
11
  "rejected" = "rejected"
12
12
  }
13
+ export declare enum CookieType {
14
+ "essential" = "essential",
15
+ "functional" = "functional",
16
+ "performance" = "performance",
17
+ "marketing" = "marketing"
18
+ }
13
19
  export interface Vendor {
14
20
  name: string;
15
21
  description: string;
@@ -12,6 +12,13 @@ export var ConsentStatus;
12
12
  ConsentStatus["granted"] = "granted";
13
13
  ConsentStatus["rejected"] = "rejected";
14
14
  })(ConsentStatus || (ConsentStatus = {}));
15
+ export var CookieType;
16
+ (function (CookieType) {
17
+ CookieType["essential"] = "essential";
18
+ CookieType["functional"] = "functional";
19
+ CookieType["performance"] = "performance";
20
+ CookieType["marketing"] = "marketing";
21
+ })(CookieType || (CookieType = {}));
15
22
  export class CookieConsentContext extends Context {
16
23
  constructor() {
17
24
  super(...arguments);
@@ -12,11 +12,14 @@ export declare class LoadContext extends Context {
12
12
  progressPercent: Observable<number, never>;
13
13
  private _startedResolved;
14
14
  started: Promise<void>;
15
+ private _constructedResolved;
16
+ constructed: Promise<void>;
15
17
  private _loadables;
16
18
  private _startWhenLoaded;
17
19
  private _totalLoadables;
18
20
  private _loadedCount;
19
21
  start(): void;
22
+ constructionComplete(): void;
20
23
  private _update;
21
24
  startWhenLoaded(): void;
22
25
  registerLoadable(p: Promise<any>): void;
@@ -32,3 +35,5 @@ export declare function registerLoadable(mgr: ContextManager, p: Promise<any>):
32
35
  export declare function start(mgr: ContextManager): void;
33
36
  export declare function startWhenLoaded(mgr: ContextManager): void;
34
37
  export declare function started(mgr: ContextManager): Promise<void>;
38
+ export declare function constructed(mgr: ContextManager): Promise<void>;
39
+ export declare function constructionComplete(mgr: ContextManager): void;
@@ -13,6 +13,7 @@ export class LoadContext extends Context {
13
13
  /** @zui */
14
14
  this.progressPercent = new Observable(0);
15
15
  this.started = new Promise(resolve => this._startedResolved = resolve);
16
+ this.constructed = new Promise(resolve => this._constructedResolved = resolve);
16
17
  this._loadables = new Set();
17
18
  this._startWhenLoaded = false;
18
19
  this._totalLoadables = 0;
@@ -26,6 +27,10 @@ export class LoadContext extends Context {
26
27
  if (document.body)
27
28
  document.body.classList.add('zcomponent-started');
28
29
  }
30
+ constructionComplete() {
31
+ this._constructedResolved();
32
+ this.isConstructed.value = true;
33
+ }
29
34
  _update() {
30
35
  if (this._loadables.size > 0 && this.isLoaded.value === true) {
31
36
  this.isLoaded.value = false;
@@ -94,3 +99,9 @@ export function startWhenLoaded(mgr) {
94
99
  export function started(mgr) {
95
100
  return mgr.get(LoadContext).started;
96
101
  }
102
+ export function constructed(mgr) {
103
+ return mgr.get(LoadContext).constructed;
104
+ }
105
+ export function constructionComplete(mgr) {
106
+ return mgr.get(LoadContext).constructionComplete();
107
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zcomponent/core",
3
- "version": "0.0.23",
3
+ "version": "0.0.24",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",