@owlmeans/web-consent 0.1.18-rc.15 → 0.1.18-rc.16
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 +1 -1
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/web-consent/SKILL.md +20 -1
- package/build/consent/widget.d.ts +18 -0
- package/build/consent/widget.d.ts.map +1 -0
- package/build/consent/widget.js +31 -0
- package/build/consent/widget.js.map +1 -0
- package/build/index.d.ts +1 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1 -0
- package/build/index.js.map +1 -1
- package/build/types.d.ts +9 -0
- package/build/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/consent/widget.tsx +43 -0
- package/src/index.ts +1 -0
- package/src/types.ts +10 -0
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
|
|
|
6
6
|
your project's skill store (`.agents/skills/`):
|
|
7
7
|
|
|
8
8
|
```sh
|
|
9
|
-
npx @owlmeans/agent-skills@^0.1.18-rc.
|
|
9
|
+
npx @owlmeans/agent-skills@^0.1.18-rc.21
|
|
10
10
|
```
|
|
11
11
|
|
|
12
12
|
The embedded files are version-matched to this package release. Do not edit them
|
package/agent-meta/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
3
|
"package": "@owlmeans/web-consent",
|
|
4
|
-
"version": "0.1.18-rc.
|
|
5
|
-
"generatedAt": "2026-09-
|
|
4
|
+
"version": "0.1.18-rc.16",
|
|
5
|
+
"generatedAt": "2026-09-15T12:21:31.925Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -8,7 +8,7 @@ user-invocable: false
|
|
|
8
8
|
# @owlmeans/web-consent
|
|
9
9
|
|
|
10
10
|
**Layer:** Web (React)
|
|
11
|
-
**Install:** `"@owlmeans/web-consent": "^0.1.18-rc.
|
|
11
|
+
**Install:** `"@owlmeans/web-consent": "^0.1.18-rc.16"` in `dependencies`
|
|
12
12
|
|
|
13
13
|
The browser components of the consent set. The model — categories, storage, migration, the store,
|
|
14
14
|
Consent Mode signalling — is `@owlmeans/consent`, and this package re-exports a **named selection**
|
|
@@ -35,6 +35,7 @@ components — see below.
|
|
|
35
35
|
| Export | Description |
|
|
36
36
|
|--------|-------------|
|
|
37
37
|
| `CookieConsent` | The preferences dialog **and** the persistent re-open button |
|
|
38
|
+
| `ConsentMenuWidget` | A plain row a HOST'S OWN menu renders to reopen the dialog, in place of (or beside) `CookieConsent`'s own floating button — see below |
|
|
38
39
|
| `CookiePolicy` | The cookie-policy page, generated from the configuration in force |
|
|
39
40
|
| `ConsentToggle` | One category row — locked and labelled when the category is required |
|
|
40
41
|
| `useConsent(opts?)` | This document's consent state and the actions over it (`UseConsentModel`) — **it also initialises the store on mount**, see below |
|
|
@@ -78,6 +79,24 @@ precondition in `@owlmeans/client-iam` raises — it says so and relabels the pr
|
|
|
78
79
|
twice. Word that path as an acknowledgement, never as "you must consent to essential cookies": a
|
|
79
80
|
required category is disclosure, not a question.
|
|
80
81
|
|
|
82
|
+
## A menu row for a host that already has one
|
|
83
|
+
|
|
84
|
+
`ConsentMenuWidget` renders one row — icon, translated label, `onClick` reopening the dialog
|
|
85
|
+
(`openConsent('reopen')` by default, or a caller's own `onSelect`) — for a host whose own
|
|
86
|
+
navigation already carries a settings menu and would rather offer cookie preferences there than as
|
|
87
|
+
a second floating button. It calls `openConsent` directly, never `useConsent()`, for the same
|
|
88
|
+
init-on-mount reason as everywhere else in this document.
|
|
89
|
+
|
|
90
|
+
**It carries no presence signalling of its own.** A host that wants `CookieConsent`'s floating
|
|
91
|
+
button to hide while this row is reachable needs to know that itself, from something that stays
|
|
92
|
+
mounted for as long as the row is reachable — never from the row's own mount. A row placed inside a
|
|
93
|
+
host menu's lazily-rendered content (Radix's `DropdownMenuContent`, and most headless menu
|
|
94
|
+
primitives, only mount their children while the menu is actually OPEN) reports "present" for a
|
|
95
|
+
fraction of the time the menu itself is on screen, and the floating button reappears the instant
|
|
96
|
+
the menu closes. `@owlmeans/web-panel/consent`'s `useConsentMenuPresence()` is the fix for a
|
|
97
|
+
context-aware host: call it from the menu's own always-mounted shell component, not from inside the
|
|
98
|
+
row. A context-free host (an Astro island with its own menu) owns that judgement itself.
|
|
99
|
+
|
|
81
100
|
## Reading the decision
|
|
82
101
|
|
|
83
102
|
```tsx
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { FC } from 'react';
|
|
2
|
+
import type { ConsentMenuWidgetProps } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* One row a HOST'S OWN menu can render to reopen the preferences dialog, in place of (or beside)
|
|
5
|
+
* the floating button `CookieConsent` renders itself. No outer row padding here — the host's own
|
|
6
|
+
* menu-row wrapper supplies that, the same way it does for any other widget row it renders.
|
|
7
|
+
*
|
|
8
|
+
* Carries no presence signalling of its own: a host whose menu only mounts this row while its
|
|
9
|
+
* dropdown/menu content is actually open (Radix's `DropdownMenuContent`, for one) would report
|
|
10
|
+
* "present" only for that brief window. A host that wants to hide `CookieConsent`'s floating
|
|
11
|
+
* button while this row is reachable announces that from whatever component of its own stays
|
|
12
|
+
* mounted for the menu's whole lifetime — see `useConsentMenuPresence` in `@owlmeans/web-panel/consent`.
|
|
13
|
+
*
|
|
14
|
+
* Uses `openConsent` directly rather than the `useConsent()` hook: that hook's mount itself
|
|
15
|
+
* triggers `consentStore.init()`, which a row that only needs to trigger a reopen must not do.
|
|
16
|
+
*/
|
|
17
|
+
export declare const ConsentMenuWidget: FC<ConsentMenuWidgetProps>;
|
|
18
|
+
//# sourceMappingURL=widget.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"widget.d.ts","sourceRoot":"","sources":["../../src/consent/widget.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAA;AAI/B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AAEzD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,iBAAiB,EAAE,EAAE,CAAC,sBAAsB,CAqBxD,CAAA"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback } from 'react';
|
|
3
|
+
import { Cookie } from 'lucide-react';
|
|
4
|
+
import { defaultConsentTranslate, openConsent } from '@owlmeans/consent';
|
|
5
|
+
import { cn } from '../lib/utils.js';
|
|
6
|
+
/**
|
|
7
|
+
* One row a HOST'S OWN menu can render to reopen the preferences dialog, in place of (or beside)
|
|
8
|
+
* the floating button `CookieConsent` renders itself. No outer row padding here — the host's own
|
|
9
|
+
* menu-row wrapper supplies that, the same way it does for any other widget row it renders.
|
|
10
|
+
*
|
|
11
|
+
* Carries no presence signalling of its own: a host whose menu only mounts this row while its
|
|
12
|
+
* dropdown/menu content is actually open (Radix's `DropdownMenuContent`, for one) would report
|
|
13
|
+
* "present" only for that brief window. A host that wants to hide `CookieConsent`'s floating
|
|
14
|
+
* button while this row is reachable announces that from whatever component of its own stays
|
|
15
|
+
* mounted for the menu's whole lifetime — see `useConsentMenuPresence` in `@owlmeans/web-panel/consent`.
|
|
16
|
+
*
|
|
17
|
+
* Uses `openConsent` directly rather than the `useConsent()` hook: that hook's mount itself
|
|
18
|
+
* triggers `consentStore.init()`, which a row that only needs to trigger a reopen must not do.
|
|
19
|
+
*/
|
|
20
|
+
export const ConsentMenuWidget = props => {
|
|
21
|
+
const t = props.translate ?? defaultConsentTranslate(props.locale);
|
|
22
|
+
const onClick = useCallback(() => {
|
|
23
|
+
if (props.onSelect != null) {
|
|
24
|
+
props.onSelect();
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
openConsent('reopen');
|
|
28
|
+
}, [props.onSelect]);
|
|
29
|
+
return _jsxs("button", { type: "button", onClick: onClick, "data-consent-menu-widget": true, className: cn('flex w-full min-w-0 items-center gap-2 rounded-md text-left text-sm text-popover-foreground transition-colors hover:bg-accent', props.className), children: [_jsx(Cookie, { className: "h-4 w-4 shrink-0", "aria-hidden": "true" }), _jsx("span", { className: "flex-1 truncate", children: props.label ?? t('openPreferences', 'Cookie preferences') })] });
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=widget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"widget.js","sourceRoot":"","sources":["../../src/consent/widget.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAEnC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AACrC,OAAO,EAAE,uBAAuB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACxE,OAAO,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAA;AAGpC;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAA+B,KAAK,CAAC,EAAE;IACnE,MAAM,CAAC,GAAG,KAAK,CAAC,SAAS,IAAI,uBAAuB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IAElE,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE;QAC/B,IAAI,KAAK,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC;YAC3B,KAAK,CAAC,QAAQ,EAAE,CAAA;YAChB,OAAM;QACR,CAAC;QACD,WAAW,CAAC,QAAQ,CAAC,CAAA;IACvB,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAA;IAEpB,OAAO,kBACL,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,OAAO,oCAC9B,SAAS,EAAE,EAAE,CACX,+HAA+H,EAC/H,KAAK,CAAC,SAAS,CAChB,aAED,KAAC,MAAM,IAAC,SAAS,EAAC,kBAAkB,iBAAa,MAAM,GAAG,EAC1D,eAAM,SAAS,EAAC,iBAAiB,YAAE,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,GAAQ,IAC7F,CAAA;AACX,CAAC,CAAA"}
|
package/build/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export type * from './types.js';
|
|
2
2
|
export * from './hooks.js';
|
|
3
3
|
export * from './consent/component.js';
|
|
4
|
+
export * from './consent/widget.js';
|
|
4
5
|
export * from './consent/toggle.js';
|
|
5
6
|
export * from './policy/component.js';
|
|
6
7
|
export { consentStore, openConsent, isConsented, readConsent, writeConsent, clearConsent, migrateConsent, applyConsent, pushConsentDefaults, consentBootstrapScript, consentDefaults, consentUpdate, gtagConsent, DEFAULT_CONSENT_CATEGORIES, DEFAULT_CONSENT_MESSAGES, defaultConsentTranslate, interpolate, CONSENT_KEY, CONSENT_COOKIE_DAYS, CONSENT_SCHEMA_VERSION, CONSENT_LOCALES, CONSENT_ESSENTIAL, CONSENT_ANALYTICS, CONSENT_MARKETING, } from '@owlmeans/consent';
|
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,YAAY,CAAA;AAC/B,cAAc,YAAY,CAAA;AAC1B,cAAc,wBAAwB,CAAA;AACtC,cAAc,qBAAqB,CAAA;AACnC,cAAc,uBAAuB,CAAA;AAErC,OAAO,EACL,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAC/E,cAAc,EAAE,YAAY,EAAE,mBAAmB,EAAE,sBAAsB,EACzE,eAAe,EAAE,aAAa,EAAE,WAAW,EAC3C,0BAA0B,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,WAAW,EAC1F,WAAW,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,eAAe,EACzE,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,GACxD,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EACV,eAAe,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAC1F,YAAY,EAAE,aAAa,GAC5B,MAAM,mBAAmB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,YAAY,CAAA;AAC/B,cAAc,YAAY,CAAA;AAC1B,cAAc,wBAAwB,CAAA;AACtC,cAAc,qBAAqB,CAAA;AACnC,cAAc,qBAAqB,CAAA;AACnC,cAAc,uBAAuB,CAAA;AAErC,OAAO,EACL,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAC/E,cAAc,EAAE,YAAY,EAAE,mBAAmB,EAAE,sBAAsB,EACzE,eAAe,EAAE,aAAa,EAAE,WAAW,EAC3C,0BAA0B,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,WAAW,EAC1F,WAAW,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,eAAe,EACzE,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,GACxD,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EACV,eAAe,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAC1F,YAAY,EAAE,aAAa,GAC5B,MAAM,mBAAmB,CAAA"}
|
package/build/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from './hooks.js';
|
|
2
2
|
export * from './consent/component.js';
|
|
3
|
+
export * from './consent/widget.js';
|
|
3
4
|
export * from './consent/toggle.js';
|
|
4
5
|
export * from './policy/component.js';
|
|
5
6
|
export { consentStore, openConsent, isConsented, readConsent, writeConsent, clearConsent, migrateConsent, applyConsent, pushConsentDefaults, consentBootstrapScript, consentDefaults, consentUpdate, gtagConsent, DEFAULT_CONSENT_CATEGORIES, DEFAULT_CONSENT_MESSAGES, defaultConsentTranslate, interpolate, CONSENT_KEY, CONSENT_COOKIE_DAYS, CONSENT_SCHEMA_VERSION, CONSENT_LOCALES, CONSENT_ESSENTIAL, CONSENT_ANALYTICS, CONSENT_MARKETING, } from '@owlmeans/consent';
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,YAAY,CAAA;AAC1B,cAAc,wBAAwB,CAAA;AACtC,cAAc,qBAAqB,CAAA;AACnC,cAAc,uBAAuB,CAAA;AAErC,OAAO,EACL,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAC/E,cAAc,EAAE,YAAY,EAAE,mBAAmB,EAAE,sBAAsB,EACzE,eAAe,EAAE,aAAa,EAAE,WAAW,EAC3C,0BAA0B,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,WAAW,EAC1F,WAAW,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,eAAe,EACzE,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,GACxD,MAAM,mBAAmB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,YAAY,CAAA;AAC1B,cAAc,wBAAwB,CAAA;AACtC,cAAc,qBAAqB,CAAA;AACnC,cAAc,qBAAqB,CAAA;AACnC,cAAc,uBAAuB,CAAA;AAErC,OAAO,EACL,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAC/E,cAAc,EAAE,YAAY,EAAE,mBAAmB,EAAE,sBAAsB,EACzE,eAAe,EAAE,aAAa,EAAE,WAAW,EAC3C,0BAA0B,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,WAAW,EAC1F,WAAW,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,eAAe,EACzE,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,GACxD,MAAM,mBAAmB,CAAA"}
|
package/build/types.d.ts
CHANGED
|
@@ -36,6 +36,15 @@ export interface CookiePolicyProps {
|
|
|
36
36
|
cookieDays?: number;
|
|
37
37
|
className?: string;
|
|
38
38
|
}
|
|
39
|
+
export interface ConsentMenuWidgetProps {
|
|
40
|
+
locale?: string;
|
|
41
|
+
/** `(key, defaultValue) => string`. Defaults to the built-in seven-language bundle. */
|
|
42
|
+
translate?: (key: string, defaultValue: string) => string;
|
|
43
|
+
label?: string;
|
|
44
|
+
className?: string;
|
|
45
|
+
/** Defaults to `openConsent('reopen')` — the same call the floating button itself makes. */
|
|
46
|
+
onSelect?: () => void;
|
|
47
|
+
}
|
|
39
48
|
export interface UseConsentModel {
|
|
40
49
|
record: ConsentRecord | null;
|
|
41
50
|
open: boolean;
|
package/build/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EAAE,aAAa,EAAE,aAAa,EAC9C,MAAM,mBAAmB,CAAA;AAE1B,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,UAAU,CAAC,EAAE,eAAe,EAAE,CAAA;IAC9B,uFAAuF;IACvF,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,MAAM,CAAA;IACzD;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,mEAAmE;IACnE,KAAK,CAAC,EAAE,WAAW,EAAE,CAAA;IACrB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,wFAAwF;IACxF,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,MAAM,CAAA;IACzD,UAAU,CAAC,EAAE,eAAe,EAAE,CAAA;IAC9B,0FAA0F;IAC1F,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,aAAa,GAAG,IAAI,CAAA;IAC5B,IAAI,EAAE,OAAO,CAAA;IACb,MAAM,EAAE,aAAa,GAAG,IAAI,CAAA;IAC5B,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAA;IACjC,IAAI,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,CAAA;IACrC,SAAS,EAAE,MAAM,IAAI,CAAA;IACrB,UAAU,EAAE,CAAC,MAAM,CAAC,EAAE,aAAa,KAAK,IAAI,CAAA;IAC5C,KAAK,EAAE,MAAM,IAAI,CAAA;CAClB"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EAAE,aAAa,EAAE,aAAa,EAC9C,MAAM,mBAAmB,CAAA;AAE1B,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,UAAU,CAAC,EAAE,eAAe,EAAE,CAAA;IAC9B,uFAAuF;IACvF,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,MAAM,CAAA;IACzD;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,mEAAmE;IACnE,KAAK,CAAC,EAAE,WAAW,EAAE,CAAA;IACrB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,wFAAwF;IACxF,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,MAAM,CAAA;IACzD,UAAU,CAAC,EAAE,eAAe,EAAE,CAAA;IAC9B,0FAA0F;IAC1F,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,uFAAuF;IACvF,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,MAAM,CAAA;IACzD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,4FAA4F;IAC5F,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,aAAa,GAAG,IAAI,CAAA;IAC5B,IAAI,EAAE,OAAO,CAAA;IACb,MAAM,EAAE,aAAa,GAAG,IAAI,CAAA;IAC5B,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAA;IACjC,IAAI,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,CAAA;IACrC,SAAS,EAAE,MAAM,IAAI,CAAA;IACrB,UAAU,EAAE,CAAC,MAAM,CAAC,EAAE,aAAa,KAAK,IAAI,CAAA;IAC5C,KAAK,EAAE,MAAM,IAAI,CAAA;CAClB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/web-consent",
|
|
3
|
-
"version": "0.1.18-rc.
|
|
3
|
+
"version": "0.1.18-rc.16",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@owlmeans/dep-config": "workspace:*",
|
|
36
|
-
"@owlmeans/test-ui": "^0.1.18-rc.
|
|
36
|
+
"@owlmeans/test-ui": "^0.1.18-rc.24",
|
|
37
37
|
"@tailwindcss/vite": "^4.0.0",
|
|
38
38
|
"@types/bun": "^1.4.0",
|
|
39
39
|
"@types/react": "^19.2.17",
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { useCallback } from 'react'
|
|
2
|
+
import type { FC } from 'react'
|
|
3
|
+
import { Cookie } from 'lucide-react'
|
|
4
|
+
import { defaultConsentTranslate, openConsent } from '@owlmeans/consent'
|
|
5
|
+
import { cn } from '../lib/utils.js'
|
|
6
|
+
import type { ConsentMenuWidgetProps } from '../types.js'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* One row a HOST'S OWN menu can render to reopen the preferences dialog, in place of (or beside)
|
|
10
|
+
* the floating button `CookieConsent` renders itself. No outer row padding here — the host's own
|
|
11
|
+
* menu-row wrapper supplies that, the same way it does for any other widget row it renders.
|
|
12
|
+
*
|
|
13
|
+
* Carries no presence signalling of its own: a host whose menu only mounts this row while its
|
|
14
|
+
* dropdown/menu content is actually open (Radix's `DropdownMenuContent`, for one) would report
|
|
15
|
+
* "present" only for that brief window. A host that wants to hide `CookieConsent`'s floating
|
|
16
|
+
* button while this row is reachable announces that from whatever component of its own stays
|
|
17
|
+
* mounted for the menu's whole lifetime — see `useConsentMenuPresence` in `@owlmeans/web-panel/consent`.
|
|
18
|
+
*
|
|
19
|
+
* Uses `openConsent` directly rather than the `useConsent()` hook: that hook's mount itself
|
|
20
|
+
* triggers `consentStore.init()`, which a row that only needs to trigger a reopen must not do.
|
|
21
|
+
*/
|
|
22
|
+
export const ConsentMenuWidget: FC<ConsentMenuWidgetProps> = props => {
|
|
23
|
+
const t = props.translate ?? defaultConsentTranslate(props.locale)
|
|
24
|
+
|
|
25
|
+
const onClick = useCallback(() => {
|
|
26
|
+
if (props.onSelect != null) {
|
|
27
|
+
props.onSelect()
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
openConsent('reopen')
|
|
31
|
+
}, [props.onSelect])
|
|
32
|
+
|
|
33
|
+
return <button
|
|
34
|
+
type="button" onClick={onClick} data-consent-menu-widget
|
|
35
|
+
className={cn(
|
|
36
|
+
'flex w-full min-w-0 items-center gap-2 rounded-md text-left text-sm text-popover-foreground transition-colors hover:bg-accent',
|
|
37
|
+
props.className
|
|
38
|
+
)}
|
|
39
|
+
>
|
|
40
|
+
<Cookie className="h-4 w-4 shrink-0" aria-hidden="true" />
|
|
41
|
+
<span className="flex-1 truncate">{props.label ?? t('openPreferences', 'Cookie preferences')}</span>
|
|
42
|
+
</button>
|
|
43
|
+
}
|
package/src/index.ts
CHANGED
package/src/types.ts
CHANGED
|
@@ -42,6 +42,16 @@ export interface CookiePolicyProps {
|
|
|
42
42
|
className?: string
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
export interface ConsentMenuWidgetProps {
|
|
46
|
+
locale?: string
|
|
47
|
+
/** `(key, defaultValue) => string`. Defaults to the built-in seven-language bundle. */
|
|
48
|
+
translate?: (key: string, defaultValue: string) => string
|
|
49
|
+
label?: string
|
|
50
|
+
className?: string
|
|
51
|
+
/** Defaults to `openConsent('reopen')` — the same call the floating button itself makes. */
|
|
52
|
+
onSelect?: () => void
|
|
53
|
+
}
|
|
54
|
+
|
|
45
55
|
export interface UseConsentModel {
|
|
46
56
|
record: ConsentRecord | null
|
|
47
57
|
open: boolean
|