@tickboxhq/vue 0.0.12 → 0.0.13
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/dist/index.d.ts +28 -2
- package/dist/index.js +8 -4
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,32 @@
|
|
|
1
1
|
import * as vue from 'vue';
|
|
2
2
|
import { InjectionKey, PropType, ComputedRef } from 'vue';
|
|
3
|
-
import { ConsentStore, ConsentConfig, Jurisdiction, ConsentMode
|
|
3
|
+
import { ResolvedCategory, ConsentStore, ConsentConfig, Jurisdiction, ConsentMode } from '@tickboxhq/core';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Shape passed to the `<ConsentBanner>` and `<ConsentNotice>` slot.
|
|
7
|
+
*
|
|
8
|
+
* Different from `ConsentApi` (returned by `useConsent()`): the slot exposes
|
|
9
|
+
* a snapshot of plain values rather than `ComputedRef`s, since the slot is
|
|
10
|
+
* already re-invoked on every state change.
|
|
11
|
+
*/
|
|
12
|
+
type ConsentSlotApi = {
|
|
13
|
+
ready: boolean;
|
|
14
|
+
isOpen: boolean;
|
|
15
|
+
noticeOpen: boolean;
|
|
16
|
+
decisions: Record<string, boolean>;
|
|
17
|
+
resolved: ResolvedCategory[];
|
|
18
|
+
storedAt: number | null;
|
|
19
|
+
grant: (id: string) => void;
|
|
20
|
+
deny: (id: string) => void;
|
|
21
|
+
grantAll: () => void;
|
|
22
|
+
denyAll: () => void;
|
|
23
|
+
save: () => void;
|
|
24
|
+
reset: () => void;
|
|
25
|
+
open: () => void;
|
|
26
|
+
close: () => void;
|
|
27
|
+
dismissNotice: () => void;
|
|
28
|
+
isGranted: (id: string) => boolean;
|
|
29
|
+
};
|
|
4
30
|
|
|
5
31
|
/**
|
|
6
32
|
* Headless banner component. Renders nothing while the store is hydrating
|
|
@@ -109,4 +135,4 @@ type CategoryApi = {
|
|
|
109
135
|
declare function useConsent(): ConsentApi;
|
|
110
136
|
declare function useConsent(categoryId: string): CategoryApi;
|
|
111
137
|
|
|
112
|
-
export { type CategoryApi, type ConsentApi, ConsentBanner, ConsentNotice, ConsentProvider, ConsentStoreKey, useConsent };
|
|
138
|
+
export { type CategoryApi, type ConsentApi, ConsentBanner, ConsentNotice, ConsentProvider, type ConsentSlotApi, ConsentStoreKey, useConsent };
|
package/dist/index.js
CHANGED
|
@@ -57,9 +57,10 @@ var ConsentBanner = defineComponent({
|
|
|
57
57
|
const api = useConsent();
|
|
58
58
|
return () => {
|
|
59
59
|
if (!api.ready.value || !api.isOpen.value) return null;
|
|
60
|
-
|
|
60
|
+
const slotApi = {
|
|
61
61
|
ready: api.ready.value,
|
|
62
62
|
isOpen: api.isOpen.value,
|
|
63
|
+
noticeOpen: api.noticeOpen.value,
|
|
63
64
|
decisions: api.decisions.value,
|
|
64
65
|
resolved: api.resolved.value,
|
|
65
66
|
storedAt: api.storedAt.value,
|
|
@@ -71,8 +72,10 @@ var ConsentBanner = defineComponent({
|
|
|
71
72
|
reset: api.reset,
|
|
72
73
|
open: api.open,
|
|
73
74
|
close: api.close,
|
|
75
|
+
dismissNotice: api.dismissNotice,
|
|
74
76
|
isGranted: api.isGranted
|
|
75
|
-
}
|
|
77
|
+
};
|
|
78
|
+
return slots.default?.(slotApi);
|
|
76
79
|
};
|
|
77
80
|
}
|
|
78
81
|
});
|
|
@@ -82,7 +85,7 @@ var ConsentNotice = defineComponent({
|
|
|
82
85
|
const api = useConsent();
|
|
83
86
|
return () => {
|
|
84
87
|
if (!api.ready.value || !api.noticeOpen.value) return null;
|
|
85
|
-
|
|
88
|
+
const slotApi = {
|
|
86
89
|
ready: api.ready.value,
|
|
87
90
|
isOpen: api.isOpen.value,
|
|
88
91
|
noticeOpen: api.noticeOpen.value,
|
|
@@ -99,7 +102,8 @@ var ConsentNotice = defineComponent({
|
|
|
99
102
|
close: api.close,
|
|
100
103
|
dismissNotice: api.dismissNotice,
|
|
101
104
|
isGranted: api.isGranted
|
|
102
|
-
}
|
|
105
|
+
};
|
|
106
|
+
return slots.default?.(slotApi);
|
|
103
107
|
};
|
|
104
108
|
}
|
|
105
109
|
});
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/keys.ts","../src/use-consent.ts","../src/banner.ts","../src/notice.ts","../src/provider.ts"],"names":["defineComponent"],"mappings":"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","file":"index.js","sourcesContent":["import type { ConsentStore } from '@tickboxhq/core'\nimport type { InjectionKey } from 'vue'\n\nexport const ConsentStoreKey: InjectionKey<ConsentStore> = Symbol('TickboxConsentStore')\n","import type { ConsentMode, ConsentState, ResolvedCategory } from '@tickboxhq/core'\nimport { type ComputedRef, type Ref, computed, inject, onScopeDispose, shallowRef } from 'vue'\nimport { ConsentStoreKey } from './keys.js'\n\nexport type ConsentApi = {\n ready: ComputedRef<boolean>\n isOpen: ComputedRef<boolean>\n noticeOpen: ComputedRef<boolean>\n decisions: ComputedRef<Record<string, boolean>>\n resolved: ComputedRef<ResolvedCategory[]>\n storedAt: ComputedRef<number | null>\n grant: (id: string) => void\n deny: (id: string) => void\n grantAll: () => void\n denyAll: () => void\n save: () => void\n reset: () => void\n open: () => void\n close: () => void\n dismissNotice: () => void\n isGranted: (id: string) => boolean\n}\n\nexport type CategoryApi = {\n granted: ComputedRef<boolean>\n required: ComputedRef<boolean>\n mode: ComputedRef<ConsentMode>\n grant: () => void\n deny: () => void\n}\n\nexport function useConsent(): ConsentApi\nexport function useConsent(categoryId: string): CategoryApi\nexport function useConsent(categoryId?: string): ConsentApi | CategoryApi {\n const store = inject(ConsentStoreKey)\n if (!store) {\n throw new Error('[@tickboxhq/vue] useConsent must be called inside a <ConsentProvider>.')\n }\n\n const stateRef: Ref<ConsentState> = shallowRef(store.getState())\n const unsubscribe = store.subscribe((next) => {\n stateRef.value = next\n })\n onScopeDispose(unsubscribe)\n\n if (categoryId !== undefined) {\n return {\n granted: computed(() => stateRef.value.decisions[categoryId] === true),\n required: computed(\n () => stateRef.value.resolved.find((r) => r.id === categoryId)?.required ?? false,\n ),\n mode: computed(\n () => stateRef.value.resolved.find((r) => r.id === categoryId)?.mode ?? 'consent',\n ),\n grant: () => store.grant(categoryId),\n deny: () => store.deny(categoryId),\n }\n }\n\n return {\n ready: computed(() => stateRef.value.ready),\n isOpen: computed(() => stateRef.value.isOpen),\n noticeOpen: computed(() => stateRef.value.noticeOpen),\n decisions: computed(() => stateRef.value.decisions),\n resolved: computed(() => stateRef.value.resolved),\n storedAt: computed(() => stateRef.value.storedAt),\n grant: (id) => store.grant(id),\n deny: (id) => store.deny(id),\n grantAll: () => store.grantAll(),\n denyAll: () => store.denyAll(),\n save: () => store.save(),\n reset: () => store.reset(),\n open: () => store.open(),\n close: () => store.close(),\n dismissNotice: () => store.dismissNotice(),\n isGranted: (id) => stateRef.value.decisions[id] === true,\n }\n}\n","import { defineComponent } from 'vue'\nimport { useConsent } from './use-consent.js'\n\n/**\n * Headless banner component. Renders nothing while the store is hydrating\n * (`!ready`) or when the banner is closed. Uses the default scoped slot to\n * pass the consent API down.\n *\n * @example\n * ```vue\n * <ConsentBanner v-slot=\"{ resolved, grantAll, denyAll, save }\">\n * <div class=\"banner\">\n * <CategoryRow v-for=\"c in resolved\" :key=\"c.id\" :category=\"c\" />\n * <button @click=\"denyAll\">Reject All</button>\n * <button @click=\"grantAll\">Accept All</button>\n * </div>\n * </ConsentBanner>\n * ```\n */\nexport const ConsentBanner = defineComponent({\n name: 'ConsentBanner',\n setup(_, { slots }) {\n const api = useConsent()\n return () => {\n if (!api.ready.value || !api.isOpen.value) return null\n return slots.default?.({\n ready: api.ready.value,\n isOpen: api.isOpen.value,\n decisions: api.decisions.value,\n resolved: api.resolved.value,\n storedAt: api.storedAt.value,\n grant: api.grant,\n deny: api.deny,\n grantAll: api.grantAll,\n denyAll: api.denyAll,\n save: api.save,\n reset: api.reset,\n open: api.open,\n close: api.close,\n isGranted: api.isGranted,\n })\n }\n },\n})\n\nexport default ConsentBanner\n","import { defineComponent } from 'vue'\nimport { useConsent } from './use-consent.js'\n\n/**\n * Headless notice card. Renders nothing while the store is hydrating\n * (`!ready`) or when there's nothing to notify about (`!noticeOpen`).\n *\n * Use this for sites that have only `notice`-mode categories (e.g. UK DUAA\n * analytics like Plausible / GoatCounter). For sites with any `consent`-mode\n * category, use `<ConsentBanner>` instead — the banner already covers\n * notice-mode categories in its list, and `noticeOpen` will stay false.\n *\n * @example\n * ```vue\n * <ConsentNotice v-slot=\"{ save, deny }\">\n * <div class=\"toast\">\n * <p>We use privacy-friendly analytics.</p>\n * <button @click=\"() => { deny('analytics'); save() }\">Opt out</button>\n * <button @click=\"save\">Got it</button>\n * </div>\n * </ConsentNotice>\n * ```\n */\nexport const ConsentNotice = defineComponent({\n name: 'ConsentNotice',\n setup(_, { slots }) {\n const api = useConsent()\n return () => {\n if (!api.ready.value || !api.noticeOpen.value) return null\n return slots.default?.({\n ready: api.ready.value,\n isOpen: api.isOpen.value,\n noticeOpen: api.noticeOpen.value,\n decisions: api.decisions.value,\n resolved: api.resolved.value,\n storedAt: api.storedAt.value,\n grant: api.grant,\n deny: api.deny,\n grantAll: api.grantAll,\n denyAll: api.denyAll,\n save: api.save,\n reset: api.reset,\n open: api.open,\n close: api.close,\n dismissNotice: api.dismissNotice,\n isGranted: api.isGranted,\n })\n }\n },\n})\n\nexport default ConsentNotice\n","import { type ConsentConfig, ConsentStore, type Jurisdiction, applyConsent } from '@tickboxhq/core'\nimport { type PropType, defineComponent, onMounted, provide } from 'vue'\nimport { ConsentStoreKey } from './keys.js'\n\nexport const ConsentProvider = defineComponent({\n name: 'ConsentProvider',\n props: {\n config: {\n type: Object as PropType<ConsentConfig>,\n required: true,\n },\n jurisdiction: {\n type: Object as PropType<Jurisdiction>,\n default: undefined,\n },\n applyEffects: {\n type: Boolean,\n default: true,\n },\n },\n setup(props, { slots }) {\n const j =\n props.jurisdiction ??\n (typeof props.config.jurisdiction !== 'string' ? props.config.jurisdiction : undefined)\n if (!j) {\n throw new Error(\n '[@tickboxhq/vue] jurisdiction is \"auto\" but no `jurisdiction` prop was passed. ' +\n 'Resolve it (e.g. via resolveJurisdictionByCountry) and pass it explicitly.',\n )\n }\n\n const store = new ConsentStore(props.config, {\n jurisdiction: j,\n storage: props.config.storage,\n applyEffects: props.applyEffects,\n onApply: props.applyEffects\n ? (state) => applyConsent(state, { consentMode: props.config.consentMode })\n : undefined,\n })\n\n provide(ConsentStoreKey, store)\n\n onMounted(() => {\n store.hydrate()\n })\n\n return () => slots.default?.()\n },\n})\n\nexport default ConsentProvider\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/keys.ts","../src/use-consent.ts","../src/banner.ts","../src/notice.ts","../src/provider.ts"],"names":["defineComponent"],"mappings":"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","file":"index.js","sourcesContent":["import type { ConsentStore } from '@tickboxhq/core'\nimport type { InjectionKey } from 'vue'\n\nexport const ConsentStoreKey: InjectionKey<ConsentStore> = Symbol('TickboxConsentStore')\n","import type { ConsentMode, ConsentState, ResolvedCategory } from '@tickboxhq/core'\nimport { type ComputedRef, type Ref, computed, inject, onScopeDispose, shallowRef } from 'vue'\nimport { ConsentStoreKey } from './keys.js'\n\nexport type ConsentApi = {\n ready: ComputedRef<boolean>\n isOpen: ComputedRef<boolean>\n noticeOpen: ComputedRef<boolean>\n decisions: ComputedRef<Record<string, boolean>>\n resolved: ComputedRef<ResolvedCategory[]>\n storedAt: ComputedRef<number | null>\n grant: (id: string) => void\n deny: (id: string) => void\n grantAll: () => void\n denyAll: () => void\n save: () => void\n reset: () => void\n open: () => void\n close: () => void\n dismissNotice: () => void\n isGranted: (id: string) => boolean\n}\n\nexport type CategoryApi = {\n granted: ComputedRef<boolean>\n required: ComputedRef<boolean>\n mode: ComputedRef<ConsentMode>\n grant: () => void\n deny: () => void\n}\n\nexport function useConsent(): ConsentApi\nexport function useConsent(categoryId: string): CategoryApi\nexport function useConsent(categoryId?: string): ConsentApi | CategoryApi {\n const store = inject(ConsentStoreKey)\n if (!store) {\n throw new Error('[@tickboxhq/vue] useConsent must be called inside a <ConsentProvider>.')\n }\n\n const stateRef: Ref<ConsentState> = shallowRef(store.getState())\n const unsubscribe = store.subscribe((next) => {\n stateRef.value = next\n })\n onScopeDispose(unsubscribe)\n\n if (categoryId !== undefined) {\n return {\n granted: computed(() => stateRef.value.decisions[categoryId] === true),\n required: computed(\n () => stateRef.value.resolved.find((r) => r.id === categoryId)?.required ?? false,\n ),\n mode: computed(\n () => stateRef.value.resolved.find((r) => r.id === categoryId)?.mode ?? 'consent',\n ),\n grant: () => store.grant(categoryId),\n deny: () => store.deny(categoryId),\n }\n }\n\n return {\n ready: computed(() => stateRef.value.ready),\n isOpen: computed(() => stateRef.value.isOpen),\n noticeOpen: computed(() => stateRef.value.noticeOpen),\n decisions: computed(() => stateRef.value.decisions),\n resolved: computed(() => stateRef.value.resolved),\n storedAt: computed(() => stateRef.value.storedAt),\n grant: (id) => store.grant(id),\n deny: (id) => store.deny(id),\n grantAll: () => store.grantAll(),\n denyAll: () => store.denyAll(),\n save: () => store.save(),\n reset: () => store.reset(),\n open: () => store.open(),\n close: () => store.close(),\n dismissNotice: () => store.dismissNotice(),\n isGranted: (id) => stateRef.value.decisions[id] === true,\n }\n}\n","import type { ConsentMode, ResolvedCategory } from '@tickboxhq/core'\nimport { defineComponent } from 'vue'\nimport { useConsent } from './use-consent.js'\n\n/**\n * Shape passed to the `<ConsentBanner>` and `<ConsentNotice>` slot.\n *\n * Different from `ConsentApi` (returned by `useConsent()`): the slot exposes\n * a snapshot of plain values rather than `ComputedRef`s, since the slot is\n * already re-invoked on every state change.\n */\nexport type ConsentSlotApi = {\n ready: boolean\n isOpen: boolean\n noticeOpen: boolean\n decisions: Record<string, boolean>\n resolved: ResolvedCategory[]\n storedAt: number | null\n grant: (id: string) => void\n deny: (id: string) => void\n grantAll: () => void\n denyAll: () => void\n save: () => void\n reset: () => void\n open: () => void\n close: () => void\n dismissNotice: () => void\n isGranted: (id: string) => boolean\n}\n\n/**\n * Convenience re-export so users typing slot scope don't have to import\n * from core directly.\n */\nexport type { ConsentMode }\n\n/**\n * Headless banner component. Renders nothing while the store is hydrating\n * (`!ready`) or when the banner is closed. Uses the default scoped slot to\n * pass the consent API down.\n *\n * @example\n * ```vue\n * <ConsentBanner v-slot=\"{ resolved, grantAll, denyAll, save }\">\n * <div class=\"banner\">\n * <CategoryRow v-for=\"c in resolved\" :key=\"c.id\" :category=\"c\" />\n * <button @click=\"denyAll\">Reject All</button>\n * <button @click=\"grantAll\">Accept All</button>\n * </div>\n * </ConsentBanner>\n * ```\n */\nexport const ConsentBanner = defineComponent({\n name: 'ConsentBanner',\n setup(_, { slots }) {\n const api = useConsent()\n return () => {\n if (!api.ready.value || !api.isOpen.value) return null\n const slotApi: ConsentSlotApi = {\n ready: api.ready.value,\n isOpen: api.isOpen.value,\n noticeOpen: api.noticeOpen.value,\n decisions: api.decisions.value,\n resolved: api.resolved.value,\n storedAt: api.storedAt.value,\n grant: api.grant,\n deny: api.deny,\n grantAll: api.grantAll,\n denyAll: api.denyAll,\n save: api.save,\n reset: api.reset,\n open: api.open,\n close: api.close,\n dismissNotice: api.dismissNotice,\n isGranted: api.isGranted,\n }\n return slots.default?.(slotApi)\n }\n },\n})\n\nexport default ConsentBanner\n","import { defineComponent } from 'vue'\nimport type { ConsentSlotApi } from './banner.js'\nimport { useConsent } from './use-consent.js'\n\n/**\n * Headless notice card. Renders nothing while the store is hydrating\n * (`!ready`) or when there's nothing to notify about (`!noticeOpen`).\n *\n * Use this for sites that have only `notice`-mode categories (e.g. UK DUAA\n * analytics like Plausible / GoatCounter). For sites with any `consent`-mode\n * category, use `<ConsentBanner>` instead — the banner already covers\n * notice-mode categories in its list, and `noticeOpen` will stay false.\n *\n * @example\n * ```vue\n * <ConsentNotice v-slot=\"{ save, deny }\">\n * <div class=\"toast\">\n * <p>We use privacy-friendly analytics.</p>\n * <button @click=\"() => { deny('analytics'); save() }\">Opt out</button>\n * <button @click=\"save\">Got it</button>\n * </div>\n * </ConsentNotice>\n * ```\n */\nexport const ConsentNotice = defineComponent({\n name: 'ConsentNotice',\n setup(_, { slots }) {\n const api = useConsent()\n return () => {\n if (!api.ready.value || !api.noticeOpen.value) return null\n const slotApi: ConsentSlotApi = {\n ready: api.ready.value,\n isOpen: api.isOpen.value,\n noticeOpen: api.noticeOpen.value,\n decisions: api.decisions.value,\n resolved: api.resolved.value,\n storedAt: api.storedAt.value,\n grant: api.grant,\n deny: api.deny,\n grantAll: api.grantAll,\n denyAll: api.denyAll,\n save: api.save,\n reset: api.reset,\n open: api.open,\n close: api.close,\n dismissNotice: api.dismissNotice,\n isGranted: api.isGranted,\n }\n return slots.default?.(slotApi)\n }\n },\n})\n\nexport default ConsentNotice\n","import { type ConsentConfig, ConsentStore, type Jurisdiction, applyConsent } from '@tickboxhq/core'\nimport { type PropType, defineComponent, onMounted, provide } from 'vue'\nimport { ConsentStoreKey } from './keys.js'\n\nexport const ConsentProvider = defineComponent({\n name: 'ConsentProvider',\n props: {\n config: {\n type: Object as PropType<ConsentConfig>,\n required: true,\n },\n jurisdiction: {\n type: Object as PropType<Jurisdiction>,\n default: undefined,\n },\n applyEffects: {\n type: Boolean,\n default: true,\n },\n },\n setup(props, { slots }) {\n const j =\n props.jurisdiction ??\n (typeof props.config.jurisdiction !== 'string' ? props.config.jurisdiction : undefined)\n if (!j) {\n throw new Error(\n '[@tickboxhq/vue] jurisdiction is \"auto\" but no `jurisdiction` prop was passed. ' +\n 'Resolve it (e.g. via resolveJurisdictionByCountry) and pass it explicitly.',\n )\n }\n\n const store = new ConsentStore(props.config, {\n jurisdiction: j,\n storage: props.config.storage,\n applyEffects: props.applyEffects,\n onApply: props.applyEffects\n ? (state) => applyConsent(state, { consentMode: props.config.consentMode })\n : undefined,\n })\n\n provide(ConsentStoreKey, store)\n\n onMounted(() => {\n store.hydrate()\n })\n\n return () => slots.default?.()\n },\n})\n\nexport default ConsentProvider\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tickboxhq/vue",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.13",
|
|
4
4
|
"description": "Vue 3 bindings for Tickbox consent management",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://tickbox.dev",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"access": "public"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@tickboxhq/core": "0.0.
|
|
30
|
+
"@tickboxhq/core": "0.0.13"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"vue": "^3.4.0"
|