@uibit/consent-guard 0.1.0 → 0.2.0
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.
- package/README.md +10 -0
- package/custom-elements.json +473 -2
- package/dist/consent-guard.d.ts +4 -1
- package/dist/consent-guard.d.ts.map +1 -1
- package/dist/consent-guard.js +4 -1
- package/dist/consent-guard.js.map +1 -1
- package/dist/frameworks/angular/index.ts +17 -14
- package/dist/frameworks/astro/index.d.ts +4 -1
- package/dist/frameworks/preact/index.d.ts +3 -1
- package/dist/frameworks/react/index.ts +66 -0
- package/dist/frameworks/solid/index.d.ts +2 -2
- package/dist/frameworks/stencil/index.d.ts +3 -1
- package/dist/frameworks/svelte/index.svelte +39 -13
- package/dist/frameworks/vue/index.ts +51 -20
- package/package.json +7 -7
- package/dist/frameworks/react/index.d.ts +0 -18
package/README.md
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
# Consent Guard
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@uibit/consent-guard)
|
|
4
|
+
|
|
5
|
+
|
|
3
6
|
[Interactive Demonstration](https://rawlings.github.io/uibit/components/consent-guard)
|
|
4
7
|
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @uibit/consent-guard
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
|
|
5
15
|
Consent Guard provides a polished, content-specific consent interface that respects user privacy without interrupting the user experience. By replacing third-party embeddings with clear, informative placeholders, it gives users control over which services load, building trust and meeting compliance requirements.
|
|
6
16
|
|
|
7
17
|
## Value Delivery
|
package/custom-elements.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"declarations": [
|
|
9
9
|
{
|
|
10
10
|
"kind": "class",
|
|
11
|
-
"description": "Gate any content behind a consent prompt. Shows the `placeholder` slot until
|
|
11
|
+
"description": "Gate any content behind a consent prompt. Shows the `placeholder` slot until",
|
|
12
12
|
"name": "ConsentGuard",
|
|
13
13
|
"cssParts": [
|
|
14
14
|
{
|
|
@@ -57,6 +57,211 @@
|
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
]
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"kind": "field",
|
|
63
|
+
"name": "locale",
|
|
64
|
+
"type": {
|
|
65
|
+
"text": "string"
|
|
66
|
+
},
|
|
67
|
+
"default": "''",
|
|
68
|
+
"description": "BCP 47 locale string for formatting and localization. Defaults to inherited document language.",
|
|
69
|
+
"attribute": "locale",
|
|
70
|
+
"inheritedFrom": {
|
|
71
|
+
"name": "UIBitElement",
|
|
72
|
+
"module": "../../platform/core/src/element.ts"
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"kind": "field",
|
|
77
|
+
"name": "resolvedLocale",
|
|
78
|
+
"type": {
|
|
79
|
+
"text": "string | undefined"
|
|
80
|
+
},
|
|
81
|
+
"description": "Resolves the active locale for formatting and localization.\nChecks the `locale` property first, then traverses up the DOM to find\nthe nearest ancestor with a `lang` attribute, and finally falls back\nto undefined (which defaults to browser locale).",
|
|
82
|
+
"readonly": true,
|
|
83
|
+
"inheritedFrom": {
|
|
84
|
+
"name": "UIBitElement",
|
|
85
|
+
"module": "../../platform/core/src/element.ts"
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"kind": "field",
|
|
90
|
+
"name": "_disposables",
|
|
91
|
+
"type": {
|
|
92
|
+
"text": "Set<() => void>"
|
|
93
|
+
},
|
|
94
|
+
"privacy": "private",
|
|
95
|
+
"default": "new Set()",
|
|
96
|
+
"inheritedFrom": {
|
|
97
|
+
"name": "UIBitElement",
|
|
98
|
+
"module": "../../platform/core/src/element.ts"
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"kind": "method",
|
|
103
|
+
"name": "createProperty",
|
|
104
|
+
"static": true,
|
|
105
|
+
"parameters": [
|
|
106
|
+
{
|
|
107
|
+
"name": "name",
|
|
108
|
+
"type": {
|
|
109
|
+
"text": "PropertyKey"
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"name": "options",
|
|
114
|
+
"optional": true,
|
|
115
|
+
"type": {
|
|
116
|
+
"text": "PropertyDeclaration"
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
],
|
|
120
|
+
"description": "Overrides createProperty to automatically map camelCase property names\nto kebab-case attribute names by default.",
|
|
121
|
+
"inheritedFrom": {
|
|
122
|
+
"name": "UIBitElement",
|
|
123
|
+
"module": "../../platform/core/src/element.ts"
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"kind": "method",
|
|
128
|
+
"name": "finalizeStyles",
|
|
129
|
+
"static": true,
|
|
130
|
+
"return": {
|
|
131
|
+
"type": {
|
|
132
|
+
"text": "Array<any>"
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
"parameters": [
|
|
136
|
+
{
|
|
137
|
+
"name": "styles",
|
|
138
|
+
"optional": true,
|
|
139
|
+
"type": {
|
|
140
|
+
"text": "CSSResultGroup"
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
],
|
|
144
|
+
"description": "Automatically prepends basic layout resets (border-box) to the\ncomponent's final styles.",
|
|
145
|
+
"inheritedFrom": {
|
|
146
|
+
"name": "UIBitElement",
|
|
147
|
+
"module": "../../platform/core/src/element.ts"
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"kind": "method",
|
|
152
|
+
"name": "dispatchCustomEvent",
|
|
153
|
+
"return": {
|
|
154
|
+
"type": {
|
|
155
|
+
"text": "boolean"
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
"parameters": [
|
|
159
|
+
{
|
|
160
|
+
"name": "name",
|
|
161
|
+
"type": {
|
|
162
|
+
"text": "string"
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
"name": "detail",
|
|
167
|
+
"optional": true,
|
|
168
|
+
"type": {
|
|
169
|
+
"text": "T"
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"name": "options",
|
|
174
|
+
"optional": true,
|
|
175
|
+
"type": {
|
|
176
|
+
"text": "Omit<CustomEventInit<T>, 'detail'>"
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
],
|
|
180
|
+
"description": "Helper to dispatch a custom event with standard bubbles and composed options.",
|
|
181
|
+
"inheritedFrom": {
|
|
182
|
+
"name": "UIBitElement",
|
|
183
|
+
"module": "../../platform/core/src/element.ts"
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"kind": "method",
|
|
188
|
+
"name": "getCssPropertyValue",
|
|
189
|
+
"return": {
|
|
190
|
+
"type": {
|
|
191
|
+
"text": "string"
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
"parameters": [
|
|
195
|
+
{
|
|
196
|
+
"name": "propertyName",
|
|
197
|
+
"type": {
|
|
198
|
+
"text": "string"
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
],
|
|
202
|
+
"description": "Helper to retrieve a computed CSS custom property value from the element.",
|
|
203
|
+
"inheritedFrom": {
|
|
204
|
+
"name": "UIBitElement",
|
|
205
|
+
"module": "../../platform/core/src/element.ts"
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"kind": "method",
|
|
210
|
+
"name": "registerDisposable",
|
|
211
|
+
"parameters": [
|
|
212
|
+
{
|
|
213
|
+
"name": "cleanup",
|
|
214
|
+
"type": {
|
|
215
|
+
"text": "() => void"
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
],
|
|
219
|
+
"description": "Register a cleanup function to be executed when the element is disconnected from the DOM.",
|
|
220
|
+
"inheritedFrom": {
|
|
221
|
+
"name": "UIBitElement",
|
|
222
|
+
"module": "../../platform/core/src/element.ts"
|
|
223
|
+
}
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
"kind": "method",
|
|
227
|
+
"name": "listen",
|
|
228
|
+
"return": {
|
|
229
|
+
"type": {
|
|
230
|
+
"text": "() => void"
|
|
231
|
+
}
|
|
232
|
+
},
|
|
233
|
+
"parameters": [
|
|
234
|
+
{
|
|
235
|
+
"name": "target",
|
|
236
|
+
"type": {
|
|
237
|
+
"text": "EventTarget"
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
"name": "type",
|
|
242
|
+
"type": {
|
|
243
|
+
"text": "K"
|
|
244
|
+
}
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
"name": "listener",
|
|
248
|
+
"type": {
|
|
249
|
+
"text": "(this: EventTarget, ev: HTMLElementEventMap[K]) => any"
|
|
250
|
+
}
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
"name": "options",
|
|
254
|
+
"optional": true,
|
|
255
|
+
"type": {
|
|
256
|
+
"text": "boolean | AddEventListenerOptions"
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
],
|
|
260
|
+
"description": "Utility to add an event listener that is automatically cleaned up when the element is disconnected.",
|
|
261
|
+
"inheritedFrom": {
|
|
262
|
+
"name": "UIBitElement",
|
|
263
|
+
"module": "../../platform/core/src/element.ts"
|
|
264
|
+
}
|
|
60
265
|
}
|
|
61
266
|
],
|
|
62
267
|
"events": [
|
|
@@ -65,12 +270,34 @@
|
|
|
65
270
|
"name": "consent-accepted"
|
|
66
271
|
}
|
|
67
272
|
],
|
|
273
|
+
"cssStates": [
|
|
274
|
+
{
|
|
275
|
+
"name": "accepted",
|
|
276
|
+
"description": "Active when the user has accepted cookie/tracking terms."
|
|
277
|
+
}
|
|
278
|
+
],
|
|
68
279
|
"superclass": {
|
|
69
280
|
"name": "UIBitElement",
|
|
70
281
|
"package": "@uibit/core"
|
|
71
282
|
},
|
|
283
|
+
"summary": "A cookie and privacy consent guard wrapping third-party embedded resources.\nthe user grants consent, then reveals the default slot.\n\nConsent is triggered by clicking any element with `[data-consent-accept]`\ninside the placeholder slot, or by calling the `accept()` method programmatically.\n\nContent in the default slot is kept `display:none` until consent is granted,\nso iframes with `loading=\"lazy\"` will not make network requests beforehand.",
|
|
72
284
|
"tagName": "uibit-consent-guard",
|
|
73
|
-
"customElement": true
|
|
285
|
+
"customElement": true,
|
|
286
|
+
"attributes": [
|
|
287
|
+
{
|
|
288
|
+
"name": "locale",
|
|
289
|
+
"type": {
|
|
290
|
+
"text": "string"
|
|
291
|
+
},
|
|
292
|
+
"default": "''",
|
|
293
|
+
"description": "BCP 47 locale string for formatting and localization. Defaults to inherited document language.",
|
|
294
|
+
"fieldName": "locale",
|
|
295
|
+
"inheritedFrom": {
|
|
296
|
+
"name": "UIBitElement",
|
|
297
|
+
"module": "../../platform/core/src/element.ts"
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
]
|
|
74
301
|
}
|
|
75
302
|
],
|
|
76
303
|
"exports": [
|
|
@@ -144,6 +371,250 @@
|
|
|
144
371
|
"path": "src/types.ts",
|
|
145
372
|
"declarations": [],
|
|
146
373
|
"exports": []
|
|
374
|
+
},
|
|
375
|
+
{
|
|
376
|
+
"kind": "javascript-module",
|
|
377
|
+
"path": "../../platform/core/src/element.ts",
|
|
378
|
+
"declarations": [
|
|
379
|
+
{
|
|
380
|
+
"kind": "class",
|
|
381
|
+
"description": "A foundational base class for all UIBit web components.\nProvides custom event helpers, default kebab-case attribute mapping,\nautomatic cleanup/disposable tracking, and auto-injected reset styles.",
|
|
382
|
+
"name": "UIBitElement",
|
|
383
|
+
"members": [
|
|
384
|
+
{
|
|
385
|
+
"kind": "field",
|
|
386
|
+
"name": "locale",
|
|
387
|
+
"type": {
|
|
388
|
+
"text": "string"
|
|
389
|
+
},
|
|
390
|
+
"default": "''",
|
|
391
|
+
"description": "BCP 47 locale string for formatting and localization. Defaults to inherited document language.",
|
|
392
|
+
"attribute": "locale"
|
|
393
|
+
},
|
|
394
|
+
{
|
|
395
|
+
"kind": "field",
|
|
396
|
+
"name": "resolvedLocale",
|
|
397
|
+
"type": {
|
|
398
|
+
"text": "string | undefined"
|
|
399
|
+
},
|
|
400
|
+
"description": "Resolves the active locale for formatting and localization.\nChecks the `locale` property first, then traverses up the DOM to find\nthe nearest ancestor with a `lang` attribute, and finally falls back\nto undefined (which defaults to browser locale).",
|
|
401
|
+
"readonly": true
|
|
402
|
+
},
|
|
403
|
+
{
|
|
404
|
+
"kind": "field",
|
|
405
|
+
"name": "_disposables",
|
|
406
|
+
"type": {
|
|
407
|
+
"text": "Set<() => void>"
|
|
408
|
+
},
|
|
409
|
+
"privacy": "private",
|
|
410
|
+
"default": "new Set()"
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
"kind": "method",
|
|
414
|
+
"name": "createProperty",
|
|
415
|
+
"static": true,
|
|
416
|
+
"parameters": [
|
|
417
|
+
{
|
|
418
|
+
"name": "name",
|
|
419
|
+
"type": {
|
|
420
|
+
"text": "PropertyKey"
|
|
421
|
+
}
|
|
422
|
+
},
|
|
423
|
+
{
|
|
424
|
+
"name": "options",
|
|
425
|
+
"optional": true,
|
|
426
|
+
"type": {
|
|
427
|
+
"text": "PropertyDeclaration"
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
],
|
|
431
|
+
"description": "Overrides createProperty to automatically map camelCase property names\nto kebab-case attribute names by default."
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
"kind": "method",
|
|
435
|
+
"name": "finalizeStyles",
|
|
436
|
+
"static": true,
|
|
437
|
+
"return": {
|
|
438
|
+
"type": {
|
|
439
|
+
"text": "Array<any>"
|
|
440
|
+
}
|
|
441
|
+
},
|
|
442
|
+
"parameters": [
|
|
443
|
+
{
|
|
444
|
+
"name": "styles",
|
|
445
|
+
"optional": true,
|
|
446
|
+
"type": {
|
|
447
|
+
"text": "CSSResultGroup"
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
],
|
|
451
|
+
"description": "Automatically prepends basic layout resets (border-box) to the\ncomponent's final styles."
|
|
452
|
+
},
|
|
453
|
+
{
|
|
454
|
+
"kind": "method",
|
|
455
|
+
"name": "dispatchCustomEvent",
|
|
456
|
+
"return": {
|
|
457
|
+
"type": {
|
|
458
|
+
"text": "boolean"
|
|
459
|
+
}
|
|
460
|
+
},
|
|
461
|
+
"parameters": [
|
|
462
|
+
{
|
|
463
|
+
"name": "name",
|
|
464
|
+
"type": {
|
|
465
|
+
"text": "string"
|
|
466
|
+
}
|
|
467
|
+
},
|
|
468
|
+
{
|
|
469
|
+
"name": "detail",
|
|
470
|
+
"optional": true,
|
|
471
|
+
"type": {
|
|
472
|
+
"text": "T"
|
|
473
|
+
}
|
|
474
|
+
},
|
|
475
|
+
{
|
|
476
|
+
"name": "options",
|
|
477
|
+
"optional": true,
|
|
478
|
+
"type": {
|
|
479
|
+
"text": "Omit<CustomEventInit<T>, 'detail'>"
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
],
|
|
483
|
+
"description": "Helper to dispatch a custom event with standard bubbles and composed options."
|
|
484
|
+
},
|
|
485
|
+
{
|
|
486
|
+
"kind": "method",
|
|
487
|
+
"name": "getCssPropertyValue",
|
|
488
|
+
"return": {
|
|
489
|
+
"type": {
|
|
490
|
+
"text": "string"
|
|
491
|
+
}
|
|
492
|
+
},
|
|
493
|
+
"parameters": [
|
|
494
|
+
{
|
|
495
|
+
"name": "propertyName",
|
|
496
|
+
"type": {
|
|
497
|
+
"text": "string"
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
],
|
|
501
|
+
"description": "Helper to retrieve a computed CSS custom property value from the element."
|
|
502
|
+
},
|
|
503
|
+
{
|
|
504
|
+
"kind": "method",
|
|
505
|
+
"name": "registerDisposable",
|
|
506
|
+
"parameters": [
|
|
507
|
+
{
|
|
508
|
+
"name": "cleanup",
|
|
509
|
+
"type": {
|
|
510
|
+
"text": "() => void"
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
],
|
|
514
|
+
"description": "Register a cleanup function to be executed when the element is disconnected from the DOM."
|
|
515
|
+
},
|
|
516
|
+
{
|
|
517
|
+
"kind": "method",
|
|
518
|
+
"name": "listen",
|
|
519
|
+
"return": {
|
|
520
|
+
"type": {
|
|
521
|
+
"text": "() => void"
|
|
522
|
+
}
|
|
523
|
+
},
|
|
524
|
+
"parameters": [
|
|
525
|
+
{
|
|
526
|
+
"name": "target",
|
|
527
|
+
"type": {
|
|
528
|
+
"text": "EventTarget"
|
|
529
|
+
}
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
"name": "type",
|
|
533
|
+
"type": {
|
|
534
|
+
"text": "K"
|
|
535
|
+
}
|
|
536
|
+
},
|
|
537
|
+
{
|
|
538
|
+
"name": "listener",
|
|
539
|
+
"type": {
|
|
540
|
+
"text": "(this: EventTarget, ev: HTMLElementEventMap[K]) => any"
|
|
541
|
+
}
|
|
542
|
+
},
|
|
543
|
+
{
|
|
544
|
+
"name": "options",
|
|
545
|
+
"optional": true,
|
|
546
|
+
"type": {
|
|
547
|
+
"text": "boolean | AddEventListenerOptions"
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
],
|
|
551
|
+
"description": "Utility to add an event listener that is automatically cleaned up when the element is disconnected."
|
|
552
|
+
},
|
|
553
|
+
{
|
|
554
|
+
"kind": "method",
|
|
555
|
+
"name": "listen",
|
|
556
|
+
"return": {
|
|
557
|
+
"type": {
|
|
558
|
+
"text": "() => void"
|
|
559
|
+
}
|
|
560
|
+
},
|
|
561
|
+
"parameters": [
|
|
562
|
+
{
|
|
563
|
+
"name": "target",
|
|
564
|
+
"type": {
|
|
565
|
+
"text": "EventTarget"
|
|
566
|
+
}
|
|
567
|
+
},
|
|
568
|
+
{
|
|
569
|
+
"name": "type",
|
|
570
|
+
"type": {
|
|
571
|
+
"text": "string"
|
|
572
|
+
}
|
|
573
|
+
},
|
|
574
|
+
{
|
|
575
|
+
"name": "listener",
|
|
576
|
+
"type": {
|
|
577
|
+
"text": "EventListenerOrEventListenerObject"
|
|
578
|
+
}
|
|
579
|
+
},
|
|
580
|
+
{
|
|
581
|
+
"name": "options",
|
|
582
|
+
"optional": true,
|
|
583
|
+
"type": {
|
|
584
|
+
"text": "boolean | AddEventListenerOptions"
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
]
|
|
588
|
+
}
|
|
589
|
+
],
|
|
590
|
+
"attributes": [
|
|
591
|
+
{
|
|
592
|
+
"name": "locale",
|
|
593
|
+
"type": {
|
|
594
|
+
"text": "string"
|
|
595
|
+
},
|
|
596
|
+
"default": "''",
|
|
597
|
+
"description": "BCP 47 locale string for formatting and localization. Defaults to inherited document language.",
|
|
598
|
+
"fieldName": "locale"
|
|
599
|
+
}
|
|
600
|
+
],
|
|
601
|
+
"superclass": {
|
|
602
|
+
"name": "LitElement",
|
|
603
|
+
"package": "lit"
|
|
604
|
+
},
|
|
605
|
+
"customElement": true
|
|
606
|
+
}
|
|
607
|
+
],
|
|
608
|
+
"exports": [
|
|
609
|
+
{
|
|
610
|
+
"kind": "js",
|
|
611
|
+
"name": "UIBitElement",
|
|
612
|
+
"declaration": {
|
|
613
|
+
"name": "UIBitElement",
|
|
614
|
+
"module": "../../platform/core/src/element.ts"
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
]
|
|
147
618
|
}
|
|
148
619
|
]
|
|
149
620
|
}
|
package/dist/consent-guard.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { UIBitElement } from '@uibit/core';
|
|
2
2
|
/**
|
|
3
3
|
* Gate any content behind a consent prompt. Shows the `placeholder` slot until
|
|
4
|
+
|
|
5
|
+
* @summary A cookie and privacy consent guard wrapping third-party embedded resources.
|
|
4
6
|
* the user grants consent, then reveals the default slot.
|
|
5
7
|
*
|
|
6
8
|
* Consent is triggered by clicking any element with `[data-consent-accept]`
|
|
@@ -17,7 +19,8 @@ import { UIBitElement } from '@uibit/core';
|
|
|
17
19
|
*
|
|
18
20
|
* @csspart placeholder - Wrapper around the placeholder slot
|
|
19
21
|
* @csspart content - Wrapper around the default slot
|
|
20
|
-
|
|
22
|
+
|
|
23
|
+
* @cssstate accepted - Active when the user has accepted cookie/tracking terms.*/
|
|
21
24
|
export declare class ConsentGuard extends UIBitElement {
|
|
22
25
|
static styles: import("lit").CSSResult;
|
|
23
26
|
private _consented;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consent-guard.d.ts","sourceRoot":"","sources":["../src/consent-guard.ts"],"names":[],"mappings":"AACA,OAAO,EAAiB,YAAY,EAAE,MAAM,aAAa,CAAC;AAG1D
|
|
1
|
+
{"version":3,"file":"consent-guard.d.ts","sourceRoot":"","sources":["../src/consent-guard.ts"],"names":[],"mappings":"AACA,OAAO,EAAiB,YAAY,EAAE,MAAM,aAAa,CAAC;AAG1D;;;;;;;;;;;;;;;;;;;;;kFAqBkF;AAClF,qBACa,YAAa,SAAQ,YAAY;IAC5C,MAAM,CAAC,MAAM,0BAsBX;IAEO,OAAO,CAAC,UAAU,CAAS;IAEpC,sCAAsC;IACtC,MAAM,SAKL;IAED,OAAO,CAAC,mBAAmB;IAO3B,MAAM,oCASL;CACF;eAEc,YAAY"}
|
package/dist/consent-guard.js
CHANGED
|
@@ -9,6 +9,8 @@ import { customElement, UIBitElement } from '@uibit/core';
|
|
|
9
9
|
import { state } from 'lit/decorators.js';
|
|
10
10
|
/**
|
|
11
11
|
* Gate any content behind a consent prompt. Shows the `placeholder` slot until
|
|
12
|
+
|
|
13
|
+
* @summary A cookie and privacy consent guard wrapping third-party embedded resources.
|
|
12
14
|
* the user grants consent, then reveals the default slot.
|
|
13
15
|
*
|
|
14
16
|
* Consent is triggered by clicking any element with `[data-consent-accept]`
|
|
@@ -25,7 +27,8 @@ import { state } from 'lit/decorators.js';
|
|
|
25
27
|
*
|
|
26
28
|
* @csspart placeholder - Wrapper around the placeholder slot
|
|
27
29
|
* @csspart content - Wrapper around the default slot
|
|
28
|
-
|
|
30
|
+
|
|
31
|
+
* @cssstate accepted - Active when the user has accepted cookie/tracking terms.*/
|
|
29
32
|
let ConsentGuard = class ConsentGuard extends UIBitElement {
|
|
30
33
|
constructor() {
|
|
31
34
|
super(...arguments);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consent-guard.js","sourceRoot":"","sources":["../src/consent-guard.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C
|
|
1
|
+
{"version":3,"file":"consent-guard.js","sourceRoot":"","sources":["../src/consent-guard.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C;;;;;;;;;;;;;;;;;;;;;kFAqBkF;AAE3E,IAAM,YAAY,GAAlB,MAAM,YAAa,SAAQ,YAAY;IAAvC;;QAyBY,eAAU,GAAG,KAAK,CAAC;IA2BtC,CAAC;aAnDQ,WAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;GAsBlB,AAtBY,CAsBX;IAIF,sCAAsC;IACtC,MAAM;QACJ,IAAI,IAAI,CAAC,UAAU;YAAE,OAAO;QAC5B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QACnC,IAAI,CAAC,mBAAmB,CAAC,kBAAkB,CAAC,CAAC;IAC/C,CAAC;IAEO,mBAAmB,CAAC,CAAQ;QAClC,MAAM,IAAI,GAAG,CAAC,CAAC,YAAY,EAAe,CAAC;QAC3C,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,YAAY,WAAW,IAAI,EAAE,CAAC,YAAY,CAAC,qBAAqB,CAAC,CAAC,EAAE,CAAC;YACzF,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,CAAC;IACH,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAA;2DAC4C,IAAI,CAAC,mBAAmB;;;;;;KAM9E,CAAC;IACJ,CAAC;CACF,CAAA;AA3BkB;IAAhB,KAAK,EAAE;gDAA4B;AAzBzB,YAAY;IADxB,aAAa,CAAC,qBAAqB,CAAC;GACxB,YAAY,CAoDxB;;AAED,eAAe,YAAY,CAAC"}
|
|
@@ -1,20 +1,23 @@
|
|
|
1
|
-
import { Component, ChangeDetectionStrategy, ElementRef, output } from '@angular/core';
|
|
1
|
+
import { Component, ChangeDetectionStrategy, ElementRef, input, effect, output } from '@angular/core';
|
|
2
2
|
import '@uibit/consent-guard';
|
|
3
3
|
import type { ConsentGuard as HTMLElementClass } from '@uibit/consent-guard';
|
|
4
|
-
|
|
5
4
|
@Component({
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
selector: 'uibit-consent-guard',
|
|
6
|
+
template: '<ng-content></ng-content>',
|
|
7
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
8
|
+
standalone: true,
|
|
9
|
+
host: {
|
|
10
|
+
'(consent-accepted)': 'consentAccepted.emit($event)'
|
|
11
|
+
}
|
|
13
12
|
})
|
|
14
13
|
export class NgxConsentGuard {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
constructor(private el: ElementRef<HTMLElementClass>){
|
|
15
|
+
effect(()=>{
|
|
16
|
+
if (this.el.nativeElement) {
|
|
17
|
+
this.el.nativeElement.locale = this.locale();
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
readonly locale = input<string>('');
|
|
22
|
+
readonly consentAccepted = output<CustomEvent<any>>();
|
|
20
23
|
}
|
|
@@ -4,7 +4,10 @@ import '@uibit/consent-guard';
|
|
|
4
4
|
declare global {
|
|
5
5
|
namespace astroHTML.JSX {
|
|
6
6
|
interface IntrinsicElements {
|
|
7
|
-
'uibit-consent-guard': Partial<HTMLElementClass> & astroHTML.JSX.HTMLAttributes
|
|
7
|
+
'uibit-consent-guard': Partial<HTMLElementClass> & astroHTML.JSX.HTMLAttributes & {
|
|
8
|
+
locale?: string;
|
|
9
|
+
"on:consent-accepted"?: (event: Event) => void;
|
|
10
|
+
};
|
|
8
11
|
}
|
|
9
12
|
}
|
|
10
13
|
}
|
|
@@ -6,7 +6,9 @@ declare module 'preact' {
|
|
|
6
6
|
namespace JSX {
|
|
7
7
|
interface IntrinsicElements {
|
|
8
8
|
'uibit-consent-guard': JSX.HTMLAttributes<HTMLElementClass> & {
|
|
9
|
-
|
|
9
|
+
locale?: string;
|
|
10
|
+
onConsentAccepted?: (event: Event) => void;
|
|
11
|
+
"on:consent-accepted"?: (event: Event) => void;
|
|
10
12
|
};
|
|
11
13
|
}
|
|
12
14
|
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import React, { useRef, useEffect, useLayoutEffect, useImperativeHandle } from 'react';
|
|
2
|
+
import type { ConsentGuard as HTMLElementClass } from '@uibit/consent-guard';
|
|
3
|
+
import '@uibit/consent-guard';
|
|
4
|
+
const useTypeOfLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
|
|
5
|
+
export interface ConsentGuardProps extends Omit<React.HTMLAttributes<HTMLElementClass>, 'locale' | 'onConsentAccepted'> {
|
|
6
|
+
children?: React.ReactNode;
|
|
7
|
+
locale?: string;
|
|
8
|
+
onConsentAccepted?: (event: Event) => void;
|
|
9
|
+
}
|
|
10
|
+
export const ConsentGuard = ({ ref, children, ...props }: ConsentGuardProps & {
|
|
11
|
+
ref?: React.Ref<HTMLElementClass>;
|
|
12
|
+
})=>{
|
|
13
|
+
const innerRef = useRef<HTMLElementClass>(null);
|
|
14
|
+
const propsRef = useRef(props);
|
|
15
|
+
propsRef.current = props;
|
|
16
|
+
useImperativeHandle(ref, ()=>innerRef.current!);
|
|
17
|
+
useTypeOfLayoutEffect(()=>{
|
|
18
|
+
const element = innerRef.current;
|
|
19
|
+
if (element && props.locale !== undefined) {
|
|
20
|
+
(element as any).locale = props.locale;
|
|
21
|
+
}
|
|
22
|
+
}, [
|
|
23
|
+
props.locale
|
|
24
|
+
]);
|
|
25
|
+
useTypeOfLayoutEffect(()=>{
|
|
26
|
+
const element = innerRef.current;
|
|
27
|
+
if (!element) return;
|
|
28
|
+
const handleEvent = (event: Event)=>{
|
|
29
|
+
if (propsRef.current.onConsentAccepted) {
|
|
30
|
+
propsRef.current.onConsentAccepted(event as any);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
element.addEventListener('consent-accepted', handleEvent);
|
|
34
|
+
return ()=>{
|
|
35
|
+
element.removeEventListener('consent-accepted', handleEvent);
|
|
36
|
+
};
|
|
37
|
+
}, []);
|
|
38
|
+
const domProps = {
|
|
39
|
+
...props
|
|
40
|
+
};
|
|
41
|
+
const customPropNames = [
|
|
42
|
+
'locale',
|
|
43
|
+
'onConsentAccepted'
|
|
44
|
+
];
|
|
45
|
+
for (const key of customPropNames){
|
|
46
|
+
delete (domProps as any)[key];
|
|
47
|
+
}
|
|
48
|
+
return React.createElement('uibit-consent-guard', {
|
|
49
|
+
ref: innerRef,
|
|
50
|
+
...domProps
|
|
51
|
+
}, children);
|
|
52
|
+
};
|
|
53
|
+
declare global {
|
|
54
|
+
namespace React {
|
|
55
|
+
namespace JSX {
|
|
56
|
+
interface IntrinsicElements {
|
|
57
|
+
'uibit-consent-guard': React.ClassAttributes<HTMLElementClass> & React.HTMLAttributes<HTMLElementClass> & {
|
|
58
|
+
children?: React.ReactNode;
|
|
59
|
+
class?: string;
|
|
60
|
+
locale?: string;
|
|
61
|
+
onConsentAccepted?: (event: CustomEvent<any>) => void;
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -6,8 +6,8 @@ declare module 'solid-js' {
|
|
|
6
6
|
namespace JSX {
|
|
7
7
|
interface IntrinsicElements {
|
|
8
8
|
'uibit-consent-guard': Partial<HTMLElementClass> & JSX.HTMLAttributes<HTMLElementClass> & {
|
|
9
|
-
|
|
10
|
-
"on:consent-accepted"?: (event:
|
|
9
|
+
locale?: string;
|
|
10
|
+
"on:consent-accepted"?: (event: Event) => void;
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
13
|
}
|
|
@@ -5,7 +5,9 @@ declare module '@stencil/core' {
|
|
|
5
5
|
export namespace JSX {
|
|
6
6
|
interface IntrinsicElements {
|
|
7
7
|
'uibit-consent-guard': HTMLElementClass & {
|
|
8
|
-
|
|
8
|
+
locale?: string;
|
|
9
|
+
onConsentAccepted?: (event: Event) => void;
|
|
10
|
+
"on:consent-accepted"?: (event: Event) => void;
|
|
9
11
|
};
|
|
10
12
|
}
|
|
11
13
|
}
|
|
@@ -1,27 +1,53 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import '@uibit/consent-guard';
|
|
3
3
|
import type { ConsentGuard as HTMLElementClass } from '@uibit/consent-guard';
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
|
|
5
|
+
let {
|
|
6
|
+
locale = $bindable(),
|
|
6
7
|
placeholder = undefined,
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
(default) = undefined,
|
|
9
|
+
children,
|
|
10
|
+
...restProps
|
|
9
11
|
} = $props<{
|
|
10
|
-
children?:
|
|
11
|
-
|
|
12
|
+
children?: import('svelte').Snippet;
|
|
13
|
+
locale?: string;
|
|
12
14
|
placeholder?: import('svelte').Snippet;
|
|
13
15
|
(default)?: import('svelte').Snippet;
|
|
16
|
+
[key: string]: any;
|
|
14
17
|
}>();
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
|
|
19
|
+
let elementRef: HTMLElementClass | null = $state(null);
|
|
20
|
+
|
|
21
|
+
$effect(() => {
|
|
22
|
+
if (elementRef && locale !== undefined && elementRef.locale !== locale) {
|
|
23
|
+
elementRef.locale = locale;
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
$effect(() => {
|
|
28
|
+
const element = elementRef;
|
|
29
|
+
if (!element) return;
|
|
30
|
+
|
|
31
|
+
const handleEvent = () => {
|
|
32
|
+
if (locale !== element.locale) {
|
|
33
|
+
locale = element.locale as any;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const events = ['change', 'input', 'consent-accepted'];
|
|
38
|
+
for (const event of events) {
|
|
39
|
+
element.addEventListener(event, handleEvent);
|
|
40
|
+
}
|
|
41
|
+
return () => {
|
|
42
|
+
for (const event of events) {
|
|
43
|
+
element.removeEventListener(event, handleEvent);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
20
46
|
});
|
|
21
|
-
|
|
47
|
+
|
|
22
48
|
</script>
|
|
23
49
|
|
|
24
|
-
<uibit-consent-guard bind:this={elementRef} {
|
|
50
|
+
<uibit-consent-guard bind:this={elementRef} {...restProps}>
|
|
25
51
|
{#if placeholder}
|
|
26
52
|
<div slot="placeholder">
|
|
27
53
|
{@render placeholder()}
|
|
@@ -1,24 +1,55 @@
|
|
|
1
|
-
import { defineComponent, h } from 'vue';
|
|
1
|
+
import { defineComponent, h, ref, watch } from 'vue';
|
|
2
2
|
import type { ConsentGuard as HTMLElementClass } from '@uibit/consent-guard';
|
|
3
3
|
import '@uibit/consent-guard';
|
|
4
|
-
|
|
5
4
|
export const ConsentGuard = defineComponent({
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
5
|
+
name: 'ConsentGuard',
|
|
6
|
+
props: {
|
|
7
|
+
locale: {
|
|
8
|
+
type: [
|
|
9
|
+
String,
|
|
10
|
+
Number,
|
|
11
|
+
Boolean,
|
|
12
|
+
Array,
|
|
13
|
+
Object
|
|
14
|
+
] as any
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
emits: [
|
|
18
|
+
'consent-accepted'
|
|
19
|
+
],
|
|
20
|
+
setup (props, { slots, emit }) {
|
|
21
|
+
const elementRef = ref<HTMLElementClass | null>(null);
|
|
22
|
+
if (false) {
|
|
23
|
+
watch(()=>props.modelValue, (newVal)=>{
|
|
24
|
+
if (elementRef.value && newVal !== undefined && elementRef.value.value !== newVal) {
|
|
25
|
+
elementRef.value.value = newVal;
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
watch(()=>props.value, (newVal)=>{
|
|
29
|
+
if (elementRef.value && newVal !== undefined && elementRef.value.value !== newVal) {
|
|
30
|
+
elementRef.value.value = newVal;
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
watch(()=>props.locale, (newVal)=>{
|
|
35
|
+
if (elementRef.value && newVal !== undefined) {
|
|
36
|
+
(elementRef.value as any).locale = newVal;
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
return ()=>{
|
|
40
|
+
const eventListeners: Record<string, any> = {};
|
|
41
|
+
eventListeners['onConsent-accepted'] = (event: Event)=>{
|
|
42
|
+
emit('consent-accepted', event);
|
|
43
|
+
};
|
|
44
|
+
const mergedProps = {
|
|
45
|
+
...props,
|
|
46
|
+
...eventListeners,
|
|
47
|
+
ref: elementRef
|
|
48
|
+
};
|
|
49
|
+
if (false && props.modelValue !== undefined) {
|
|
50
|
+
(mergedProps as any).value = props.modelValue;
|
|
51
|
+
}
|
|
52
|
+
return h('uibit-consent-guard', mergedProps, slots.default?.());
|
|
53
|
+
};
|
|
54
|
+
}
|
|
24
55
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uibit/consent-guard",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Gate any third-party content behind a consent prompt. The component manages show/hide state only — you provide both the placeholder UI and the content, keeping it composable and unbiased.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
},
|
|
13
13
|
"./consent-guard.css": "./dist/consent-guard.css",
|
|
14
14
|
"./custom-elements.json": "./custom-elements.json",
|
|
15
|
-
"./react": "./dist/frameworks/react/index.
|
|
15
|
+
"./react": "./dist/frameworks/react/index.ts",
|
|
16
16
|
"./vue": "./dist/frameworks/vue/index.ts",
|
|
17
17
|
"./svelte": "./dist/frameworks/svelte/index.svelte",
|
|
18
18
|
"./angular": "./dist/frameworks/angular/index.ts",
|
|
@@ -47,13 +47,13 @@
|
|
|
47
47
|
"directory": "packages/components/consent-guard"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@uibit/core": "0.
|
|
50
|
+
"@uibit/core": "0.2.0"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@types/node": "^20.19.43",
|
|
54
54
|
"lit": "^3.3.3",
|
|
55
55
|
"typescript": "7.0.2",
|
|
56
|
-
"@uibit/codegen": "0.
|
|
56
|
+
"@uibit/codegen": "0.2.0"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
59
|
"lit": "^3.0.0",
|
|
@@ -84,9 +84,9 @@
|
|
|
84
84
|
"tagName": "uibit-consent-guard"
|
|
85
85
|
},
|
|
86
86
|
"scripts": {
|
|
87
|
-
"build": "cem analyze --
|
|
88
|
-
"dev": "concurrently \"cem analyze --
|
|
89
|
-
"analyze": "cem analyze --
|
|
87
|
+
"build": "cem analyze --config ../custom-elements-manifest.config.js && uibit-codegen --package . && tsc",
|
|
88
|
+
"dev": "concurrently \"cem analyze --config ../custom-elements-manifest.config.js --watch\" \"tsc --watch\"",
|
|
89
|
+
"analyze": "cem analyze --config ../custom-elements-manifest.config.js",
|
|
90
90
|
"typecheck": "tsc --noEmit"
|
|
91
91
|
}
|
|
92
92
|
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { HTMLAttributes, ClassAttributes } from 'react';
|
|
2
|
-
import type { ConsentGuard as HTMLElementClass } from '@uibit/consent-guard';
|
|
3
|
-
import '@uibit/consent-guard';
|
|
4
|
-
|
|
5
|
-
declare global {
|
|
6
|
-
namespace React {
|
|
7
|
-
namespace JSX {
|
|
8
|
-
interface IntrinsicElements {
|
|
9
|
-
'uibit-consent-guard': ClassAttributes<HTMLElementClass> & HTMLAttributes<HTMLElementClass> & {
|
|
10
|
-
children?: React.ReactNode;
|
|
11
|
-
class?: string;
|
|
12
|
-
|
|
13
|
-
onConsentAccepted?: (event: any) => void;
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
}
|