@owlmeans/web-consent 0.1.18-rc.44 → 0.1.18-rc.46

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 CHANGED
@@ -14,7 +14,7 @@ The `web-consent` skill covers the components, the `consent` skill the model beh
14
14
  ## Installation
15
15
 
16
16
  ```bash
17
- bun add @owlmeans/web-consent@^0.1.18-rc.44
17
+ bun add @owlmeans/web-consent@^0.1.18-rc.46
18
18
  ```
19
19
 
20
20
  Peer dependencies the app provides: `react`, `tailwindcss`, `tailwind-merge`, `clsx`, `lucide-react`.
@@ -49,7 +49,7 @@ Tailwind entry must scan the package's `src`:
49
49
 
50
50
  At the application root or layout. It opens itself when no decision is stored and renders only the
51
51
  re-open button once one is. A first-time visitor is asked with a tall bar across the bottom of a
52
- transparent overlay — "Cookie preferences", "Accept only mandatory", "Accept all" — and every later
52
+ dimmed overlay — "Cookie preferences", "Accept only mandatory", "Accept all" — and every later
53
53
  opening is the preferences window; `mode="window"` asks with the window straight away.
54
54
 
55
55
  ```tsx
@@ -186,7 +186,7 @@ re-exported; import them from `@owlmeans/consent`.
186
186
  | Selector | Element |
187
187
  |---|---|
188
188
  | `[data-consent-dialog]` | whichever surface asks — the bar or the window (`data-consent-mode="bar\|window"`) |
189
- | `[data-consent-bar]`, `[data-consent-overlay]` | the bar, and the transparent overlay it sits on |
189
+ | `[data-consent-bar]`, `[data-consent-overlay]` | the bar, and the dimmed overlay it sits on |
190
190
  | `[data-consent-preferences]`, `[data-consent-mandatory]`, `[data-consent-accept-all]` | the bar's three answers |
191
191
  | `[data-consent-save]`, `[data-consent-accept-all]` | the window's two actions |
192
192
  | `[data-consent-locating="first"]`, `[data-consent-spinner]` | the locating overlay and its spinner |
@@ -230,7 +230,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
230
230
  your project's skill store (`.agents/skills/`):
231
231
 
232
232
  ```sh
233
- npx @owlmeans/agent-skills@^0.1.18-rc.52
233
+ npx @owlmeans/agent-skills@^0.1.18-rc.55
234
234
  ```
235
235
 
236
236
  The embedded files are version-matched to this package release. Do not edit them
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
3
  "package": "@owlmeans/web-consent",
4
- "version": "0.1.18-rc.44",
5
- "generatedAt": "2026-10-08T21:27:54.304Z",
4
+ "version": "0.1.18-rc.46",
5
+ "generatedAt": "2026-10-16T22:27:59.065Z",
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.44"` in `dependencies`
11
+ **Install:** `"@owlmeans/web-consent": "^0.1.18-rc.46"` 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**
@@ -108,8 +108,8 @@ import { CookieConsent } from '@owlmeans/web-consent'
108
108
 
109
109
  ## The bar
110
110
 
111
- A tall bar across the bottom of a **transparent** overlay (`[data-consent-overlay]`,
112
- `fixed inset-0 bg-transparent`): the page stays in sight and scrolls, but nothing on it can be
111
+ A tall bar across the bottom of a **dimmed** overlay (`[data-consent-overlay]`,
112
+ `fixed inset-0 bg-black/70`): the page stays in sight and scrolls, but nothing on it can be
113
113
  pressed until the visitor answers. The bar (`fixed inset-x-0 bottom-0 max-h-[85vh] border-t
114
114
  bg-background`) holds, left to right on a wide screen and stacked on a phone:
115
115
 
@@ -140,7 +140,8 @@ follow the flat rule those apps are held to: **no gradient, shadow, glow, glass
140
140
 
141
141
  | Part | Classes |
142
142
  |---|---|
143
- | Bar overlay, locating overlay | `bg-transparent` — the page stays in sight |
143
+ | Bar overlay | `bg-black/70`, matching the preferences window — the page is dimmed beneath the opaque bar |
144
+ | Locating overlay | `bg-transparent` — a quick region lookup flashes no backdrop |
144
145
  | Bar | `border-t border-border bg-background text-foreground`, no shadow |
145
146
  | Bar answers | "Accept only mandatory" and "Accept All" both the accent pill; "Cookie preferences" outlined |
146
147
  | Spinner | `text-muted-foreground motion-safe:animate-spin` |
@@ -3,7 +3,7 @@ import type { ConsentBarProps } from './types.local.js';
3
3
  /**
4
4
  * The first question a visitor is asked, as a tall bar across the bottom of the page.
5
5
  *
6
- * It sits on a TRANSPARENT overlay: the page stays in sight and scrolls, but nothing on it can be
6
+ * It sits on a dimmed overlay: the page stays in sight and scrolls, but nothing on it can be
7
7
  * pressed until the visitor answers. The text says what the essential cookies do, names the
8
8
  * optional categories in force (as a list after a colon, so no language has to decline a label),
9
9
  * that they stay off until allowed, and that the choice can be changed or withdrawn — then the
@@ -9,7 +9,7 @@ import { ConsentLinks } from './links.js';
9
9
  /**
10
10
  * The first question a visitor is asked, as a tall bar across the bottom of the page.
11
11
  *
12
- * It sits on a TRANSPARENT overlay: the page stays in sight and scrolls, but nothing on it can be
12
+ * It sits on a dimmed overlay: the page stays in sight and scrolls, but nothing on it can be
13
13
  * pressed until the visitor answers. The text says what the essential cookies do, names the
14
14
  * optional categories in force (as a list after a colon, so no language has to decline a label),
15
15
  * that they stay off until allowed, and that the choice can be changed or withdrawn — then the
@@ -32,6 +32,6 @@ export const ConsentBar = props => {
32
32
  const description = optional.length > 0
33
33
  ? consentI18nHelper.interpolate(t('barDescription', 'We use essential cookies to make this site work — for signing in, security and remembering your choices. With your consent we would also use these optional cookies: {{categories}}. They stay off until you allow them, and you can change or withdraw your choice at any time in the cookie preferences.'), { categories: optional.map(category => t(category.labelKey, category.key)).join(', ') })
34
34
  : t('barDescriptionEssential', 'This site uses only essential cookies — for signing in, security and remembering your choices. They need no consent and cannot be switched off.');
35
- return _jsx("div", { className: "fixed inset-0 z-[999998] bg-transparent", "data-consent-overlay": true, children: _jsx("div", { ref: surface, tabIndex: -1, className: webConsentUtils.cn('fixed inset-x-0 bottom-0 z-[999999] max-h-[85vh] overflow-y-auto border-t border-border bg-background text-foreground outline-none', props.barClassName), role: "dialog", "aria-modal": "true", "aria-labelledby": "cc-bar-title", "aria-describedby": domains.length > 1 ? 'cc-bar-desc cc-bar-domains' : 'cc-bar-desc', "data-consent-dialog": true, "data-consent-bar": true, "data-consent-mode": "bar", children: _jsxs("div", { className: "mx-auto flex max-w-6xl flex-col gap-6 px-4 py-6 sm:px-8 sm:py-8 lg:flex-row lg:items-end lg:gap-10", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "mb-3 flex items-center gap-3", children: [_jsx("div", { className: "flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-full bg-muted text-primary", children: _jsx(Cookie, { className: "h-5 w-5", "aria-hidden": "true" }) }), _jsx("h2", { id: "cc-bar-title", className: "text-balance text-lg font-extrabold tracking-tight text-foreground sm:text-xl", children: t('barTitle', 'Cookies on this site') })] }), _jsx("p", { id: "cc-bar-desc", className: "text-pretty text-sm leading-relaxed text-muted-foreground", children: description }), domains.length > 1 && _jsx("p", { id: "cc-bar-domains", "data-consent-domains": true, className: "mt-2 text-pretty text-xs text-muted-foreground", children: consentI18nHelper.interpolate(t('domains', 'This choice applies to {{domains}}.'), { domains: domains.join(', ') }) }), _jsx(ConsentLinks, { t: t, policyHref: props.policyHref, links: props.links, className: "mt-1" })] }), _jsxs("div", { className: "flex w-full flex-col gap-3 sm:flex-row sm:flex-wrap sm:justify-end lg:w-auto lg:max-w-xl lg:flex-shrink-0", children: [_jsx("button", { type: "button", onClick: props.onPreferences, "data-consent-preferences": true, className: webConsentUtils.cn(BAR_PILL, OUTLINED), children: t('openPreferences', 'Cookie preferences') }), optional.length > 0 && _jsx("button", { type: "button", onClick: props.onMandatory, "data-consent-mandatory": true, className: webConsentUtils.cn(BAR_PILL, ACCENT), children: t('acceptMandatory', 'Accept only mandatory') }), _jsx("button", { type: "button", onClick: props.onAcceptAll, "data-consent-accept-all": true, className: webConsentUtils.cn(BAR_PILL, ACCENT), children: t('acceptAll', 'Accept All') })] })] }) }) });
35
+ return _jsx("div", { className: "fixed inset-0 z-[999998] bg-black/70", "data-consent-overlay": true, children: _jsx("div", { ref: surface, tabIndex: -1, className: webConsentUtils.cn('fixed inset-x-0 bottom-0 z-[999999] max-h-[85vh] overflow-y-auto border-t border-border bg-background text-foreground outline-none', props.barClassName), role: "dialog", "aria-modal": "true", "aria-labelledby": "cc-bar-title", "aria-describedby": domains.length > 1 ? 'cc-bar-desc cc-bar-domains' : 'cc-bar-desc', "data-consent-dialog": true, "data-consent-bar": true, "data-consent-mode": "bar", children: _jsxs("div", { className: "mx-auto flex max-w-6xl flex-col gap-6 px-4 py-6 sm:px-8 sm:py-8 lg:flex-row lg:items-end lg:gap-10", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "mb-3 flex items-center gap-3", children: [_jsx("div", { className: "flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-full bg-muted text-primary", children: _jsx(Cookie, { className: "h-5 w-5", "aria-hidden": "true" }) }), _jsx("h2", { id: "cc-bar-title", className: "text-balance text-lg font-extrabold tracking-tight text-foreground sm:text-xl", children: t('barTitle', 'Cookies on this site') })] }), _jsx("p", { id: "cc-bar-desc", className: "text-pretty text-sm leading-relaxed text-muted-foreground", children: description }), domains.length > 1 && _jsx("p", { id: "cc-bar-domains", "data-consent-domains": true, className: "mt-2 text-pretty text-xs text-muted-foreground", children: consentI18nHelper.interpolate(t('domains', 'This choice applies to {{domains}}.'), { domains: domains.join(', ') }) }), _jsx(ConsentLinks, { t: t, policyHref: props.policyHref, links: props.links, className: "mt-1" })] }), _jsxs("div", { className: "flex w-full flex-col gap-3 sm:flex-row sm:flex-wrap sm:justify-end lg:w-auto lg:max-w-xl lg:flex-shrink-0", children: [_jsx("button", { type: "button", onClick: props.onPreferences, "data-consent-preferences": true, className: webConsentUtils.cn(BAR_PILL, OUTLINED), children: t('openPreferences', 'Cookie preferences') }), optional.length > 0 && _jsx("button", { type: "button", onClick: props.onMandatory, "data-consent-mandatory": true, className: webConsentUtils.cn(BAR_PILL, ACCENT), children: t('acceptMandatory', 'Accept only mandatory') }), _jsx("button", { type: "button", onClick: props.onAcceptAll, "data-consent-accept-all": true, className: webConsentUtils.cn(BAR_PILL, ACCENT), children: t('acceptAll', 'Accept All') })] })] }) }) });
36
36
  };
37
37
  //# sourceMappingURL=bar.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bar.js","sourceRoot":"","sources":["../../src/consent/bar.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bar.js","sourceRoot":"","sources":["../../src/consent/bar.tsx"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { type FC } from 'react';
2
2
  import type { ConsentLocatingProps } from './types.local.js';
3
3
  /**
4
- * While the visitor's country is being found: the same transparent overlay the bar sits on — the
4
+ * While the visitor's country is being found: a transparent overlay — the
5
5
  * page stays in sight and out of reach — with a spinner and no bar. The spinner itself waits
6
6
  * `CONSENT_LOCATING_DELAY`, so an answer from the edge in a few milliseconds flashes nothing; the
7
7
  * status text is there from the start for assistive technology.
@@ -3,7 +3,7 @@ import { useEffect, useState } from 'react';
3
3
  import { LoaderCircle } from 'lucide-react';
4
4
  import { CONSENT_LOCATING_DELAY } from './consts.local.js';
5
5
  /**
6
- * While the visitor's country is being found: the same transparent overlay the bar sits on — the
6
+ * While the visitor's country is being found: a transparent overlay — the
7
7
  * page stays in sight and out of reach — with a spinner and no bar. The spinner itself waits
8
8
  * `CONSENT_LOCATING_DELAY`, so an answer from the edge in a few milliseconds flashes nothing; the
9
9
  * status text is there from the start for assistive technology.
package/build/types.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { ConsentCategory, ConsentGeoOptions, ConsentLinkerOptions, ConsentLocating, ConsentReason, ConsentRecord, ConsentService } from '@owlmeans/consent';
2
2
  /**
3
- * How a first-time visitor is asked: `bar` — a tall bar across the bottom of a transparent overlay
3
+ * How a first-time visitor is asked: `bar` — a tall bar across the bottom of a dimmed overlay
4
4
  * that blocks the page but leaves it in sight, with "Cookie preferences", "Accept only mandatory" and
5
5
  * "Accept all" — or `window`, the preferences window straight away. Either way every later opening
6
6
  * (the bar's own "Cookie preferences", a footer link, the corner button, the sign-in gate) is the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owlmeans/web-consent",
3
- "version": "0.1.18-rc.44",
3
+ "version": "0.1.18-rc.46",
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.51",
36
+ "@owlmeans/test-ui": "^0.1.18-rc.53",
37
37
  "@tailwindcss/vite": "^4.3.3",
38
38
  "@types/bun": "^1.4.2",
39
39
  "@types/react": "^19.3.0",
@@ -10,7 +10,7 @@ import type { ConsentBarProps } from './types.local.js'
10
10
  /**
11
11
  * The first question a visitor is asked, as a tall bar across the bottom of the page.
12
12
  *
13
- * It sits on a TRANSPARENT overlay: the page stays in sight and scrolls, but nothing on it can be
13
+ * It sits on a dimmed overlay: the page stays in sight and scrolls, but nothing on it can be
14
14
  * pressed until the visitor answers. The text says what the essential cookies do, names the
15
15
  * optional categories in force (as a list after a colon, so no language has to decline a label),
16
16
  * that they stay off until allowed, and that the choice can be changed or withdrawn — then the
@@ -38,7 +38,7 @@ export const ConsentBar: FC<ConsentBarProps> = props => {
38
38
  )
39
39
  : t('barDescriptionEssential', 'This site uses only essential cookies — for signing in, security and remembering your choices. They need no consent and cannot be switched off.')
40
40
 
41
- return <div className="fixed inset-0 z-[999998] bg-transparent" data-consent-overlay>
41
+ return <div className="fixed inset-0 z-[999998] bg-black/70" data-consent-overlay>
42
42
  <div
43
43
  ref={surface} tabIndex={-1}
44
44
  className={webConsentUtils.cn(
@@ -4,7 +4,7 @@ import { CONSENT_LOCATING_DELAY } from './consts.local.js'
4
4
  import type { ConsentLocatingProps } from './types.local.js'
5
5
 
6
6
  /**
7
- * While the visitor's country is being found: the same transparent overlay the bar sits on — the
7
+ * While the visitor's country is being found: a transparent overlay — the
8
8
  * page stays in sight and out of reach — with a spinner and no bar. The spinner itself waits
9
9
  * `CONSENT_LOCATING_DELAY`, so an answer from the edge in a few milliseconds flashes nothing; the
10
10
  * status text is there from the start for assistive technology.
package/src/types.ts CHANGED
@@ -4,7 +4,7 @@ import type {
4
4
  } from '@owlmeans/consent'
5
5
 
6
6
  /**
7
- * How a first-time visitor is asked: `bar` — a tall bar across the bottom of a transparent overlay
7
+ * How a first-time visitor is asked: `bar` — a tall bar across the bottom of a dimmed overlay
8
8
  * that blocks the page but leaves it in sight, with "Cookie preferences", "Accept only mandatory" and
9
9
  * "Accept all" — or `window`, the preferences window straight away. Either way every later opening
10
10
  * (the bar's own "Cookie preferences", a footer link, the corner button, the sign-in gate) is the
package/tests/bar.spec.ts CHANGED
@@ -107,7 +107,7 @@ describe('@owlmeans/web-consent — the bar', () => {
107
107
  }
108
108
  }, TIMEOUT)
109
109
 
110
- test('the bar is flat, sits on a transparent overlay, and both answers are equally prominent', async () => {
110
+ test('the bar is flat, sits on a dimmed overlay, and both answers are equally prominent', async () => {
111
111
  const { page, close } = await mountComponent({ url: `${base}/` })
112
112
  try {
113
113
  const bar = page.locator('[data-consent-bar]')
@@ -117,7 +117,7 @@ describe('@owlmeans/web-consent — the bar', () => {
117
117
  .map(element => element.getAttribute('class') ?? '').join(' '))
118
118
 
119
119
  expect(classes).not.toMatch(/\b(?:bg-gradient|from-|to-secondary|backdrop-|blur|shadow|ring-primary)/)
120
- expect(await overlay.getAttribute('class')).toMatch(/\bbg-transparent\b/)
120
+ expect(await overlay.getAttribute('class')).toContain('bg-black/70')
121
121
  expect(await overlay.getAttribute('class')).toMatch(/\binset-0\b/)
122
122
  expect(await bar.getAttribute('class')).toMatch(/\bbottom-0\b/)
123
123
  expect(await bar.getAttribute('class')).toMatch(/\bbg-background\b/)
@@ -141,8 +141,8 @@ describe('@owlmeans/web-consent — the bar', () => {
141
141
  }
142
142
  }, TIMEOUT)
143
143
 
144
- test('styled: the page stays in sight and out of reach, the bar sits at the very bottom', async () => {
145
- const { page, close } = await mountComponent({ url: `${base}/?styled=1` })
144
+ test.each(['light', 'dark'])('styled (%s): the page is dimmed and out of reach, the bar sits at the very bottom', async theme => {
145
+ const { page, close } = await mountComponent({ url: `${base}/?styled=1&theme=${theme}` })
146
146
  try {
147
147
  const bar = page.locator('[data-consent-bar]')
148
148
  await bar.waitFor()
@@ -153,15 +153,23 @@ describe('@owlmeans/web-consent — the bar', () => {
153
153
  expect(Math.round(box.width)).toBe(viewport.width)
154
154
  const blocked = await page.evaluate(() => {
155
155
  const hit = document.elementFromPoint(10, 10)
156
+ const canvas = document.createElement('canvas')
157
+ canvas.width = canvas.height = 1
158
+ const context = canvas.getContext('2d')!
159
+ context.fillStyle = hit == null ? 'transparent' : getComputedStyle(hit).backgroundColor
160
+ context.fillRect(0, 0, 1, 1)
156
161
 
157
162
  return {
158
163
  overlay: hit?.closest('[data-consent-overlay]') != null,
159
- background: hit == null ? null : getComputedStyle(hit).backgroundColor,
164
+ background: Array.from(context.getImageData(0, 0, 1, 1).data),
165
+ opacity: hit == null ? null : getComputedStyle(hit).opacity,
160
166
  }
161
167
  })
162
- // The page's own top-left corner is covered by the overlay — and the overlay paints nothing.
168
+ // Dim the page with the same translucent black as the preferences window, in both themes.
163
169
  expect(blocked.overlay).toBe(true)
164
- expect(blocked.background).toBe('rgba(0, 0, 0, 0)')
170
+ expect(blocked.background).toEqual([0, 0, 0, 179])
171
+ expect(blocked.opacity).toBe('1')
172
+ expect(await bar.evaluate(root => getComputedStyle(root).opacity)).toBe('1')
165
173
  // The remount button under the overlay cannot be pressed.
166
174
  await expect(page.locator('#remount').click({ timeout: 1_000 })).rejects.toThrow()
167
175
  } finally {