@camunda/design-system 0.32.1 → 0.32.2
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/carbon-compat/c3-cluster-tag.d.ts.map +1 -1
- package/dist/carbon-compat/c3-cluster-tag.js +10 -4
- package/dist/carbon-compat/c3-cluster-tag.js.map +1 -1
- package/dist/src/components/ui/alert-dialog.d.ts +1 -1
- package/dist/src/components/ui/alert-dialog.d.ts.map +1 -1
- package/dist/src/components/ui/alert-dialog.js +6 -2
- package/dist/src/components/ui/alert-dialog.js.map +1 -1
- package/dist/src/components/ui/button.js +1 -1
- package/dist/src/components/ui/button.js.map +1 -1
- package/dist/src/components/ui/c4-provider.d.ts.map +1 -1
- package/dist/src/components/ui/c4-provider.js +6 -0
- package/dist/src/components/ui/c4-provider.js.map +1 -1
- package/dist/src/components/ui/dialog.d.ts +1 -1
- package/dist/src/components/ui/dialog.d.ts.map +1 -1
- package/dist/src/components/ui/dialog.js +9 -2
- package/dist/src/components/ui/dialog.js.map +1 -1
- package/dist/src/components/ui/dropdown.d.ts +1 -1
- package/dist/src/components/ui/dropdown.d.ts.map +1 -1
- package/dist/src/components/ui/dropdown.js +6 -2
- package/dist/src/components/ui/dropdown.js.map +1 -1
- package/dist/src/components/ui/popover.d.ts +1 -1
- package/dist/src/components/ui/popover.d.ts.map +1 -1
- package/dist/src/components/ui/popover.js +6 -2
- package/dist/src/components/ui/popover.js.map +1 -1
- package/dist/src/components/ui/select.d.ts +1 -1
- package/dist/src/components/ui/select.d.ts.map +1 -1
- package/dist/src/components/ui/select.js +7 -3
- package/dist/src/components/ui/select.js.map +1 -1
- package/dist/src/components/ui/sheet.d.ts +1 -1
- package/dist/src/components/ui/sheet.d.ts.map +1 -1
- package/dist/src/components/ui/sheet.js +6 -2
- package/dist/src/components/ui/sheet.js.map +1 -1
- package/dist/src/lib/focus-visible-on-close.d.ts +39 -0
- package/dist/src/lib/focus-visible-on-close.d.ts.map +1 -0
- package/dist/src/lib/focus-visible-on-close.js +61 -0
- package/dist/src/lib/focus-visible-on-close.js.map +1 -0
- package/dist/src/lib/inert-aria-hidden.d.ts +34 -0
- package/dist/src/lib/inert-aria-hidden.d.ts.map +1 -0
- package/dist/src/lib/inert-aria-hidden.js +76 -0
- package/dist/src/lib/inert-aria-hidden.js.map +1 -0
- package/dist/styles.css +790 -1625
- package/package.json +12 -12
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Makes the focus ring visible when a modal overlay restores focus to its
|
|
3
|
+
* trigger on close (#259 follow-up).
|
|
4
|
+
*
|
|
5
|
+
* Why: Radix restores focus with a programmatic `.focus()`. The browser's
|
|
6
|
+
* `:focus-visible` heuristic shows a ring only when the last input was a
|
|
7
|
+
* keyboard, so closing an overlay by mouse (clicking the X or the backdrop)
|
|
8
|
+
* returns focus to the trigger with no visible ring — a keyboard user who
|
|
9
|
+
* happened to click cannot see where focus landed. We stamp a transient marker
|
|
10
|
+
* on the restored element so the DS `Button` shows its ring regardless of the
|
|
11
|
+
* input modality that closed the overlay.
|
|
12
|
+
*
|
|
13
|
+
* The marker is self-clearing: it is removed on the next `pointerdown` anywhere
|
|
14
|
+
* and when the element loses focus. Without that, a sticky attribute would show
|
|
15
|
+
* a ring on every ordinary mouse click of that Button — a worse regression than
|
|
16
|
+
* the missing ring it fixes.
|
|
17
|
+
*
|
|
18
|
+
* Styling target: the marker lands on the element Radix focuses — the trigger,
|
|
19
|
+
* a DS `Button` in every DS overlay. A non-`Button` custom trigger would carry
|
|
20
|
+
* the attribute but has no matching ring style; same known-scope caveat as the
|
|
21
|
+
* inert body-child mirror in `inert-aria-hidden.ts`.
|
|
22
|
+
*/
|
|
23
|
+
export const FOCUS_VISIBLE_RESTORE_ATTR = "data-focus-visible-restore";
|
|
24
|
+
/**
|
|
25
|
+
* Use as a Radix overlay `Content`'s `onCloseAutoFocus`. Does not
|
|
26
|
+
* `preventDefault`, so Radix still restores focus to the trigger; on the next
|
|
27
|
+
* frame the restored element (`document.activeElement`) is stamped with the
|
|
28
|
+
* self-clearing marker. No-ops if a prior handler already prevented the default
|
|
29
|
+
* restore.
|
|
30
|
+
*/
|
|
31
|
+
export function markFocusVisibleOnClose(event) {
|
|
32
|
+
if (event.defaultPrevented || typeof requestAnimationFrame === "undefined") {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
requestAnimationFrame(() => {
|
|
36
|
+
const el = document.activeElement;
|
|
37
|
+
if (!(el instanceof HTMLElement) || el === document.body)
|
|
38
|
+
return;
|
|
39
|
+
el.setAttribute(FOCUS_VISIBLE_RESTORE_ATTR, "");
|
|
40
|
+
const clear = () => {
|
|
41
|
+
el.removeAttribute(FOCUS_VISIBLE_RESTORE_ATTR);
|
|
42
|
+
el.removeEventListener("blur", clear);
|
|
43
|
+
document.removeEventListener("pointerdown", clear, true);
|
|
44
|
+
};
|
|
45
|
+
el.addEventListener("blur", clear);
|
|
46
|
+
document.addEventListener("pointerdown", clear, true);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Wraps a Radix overlay `Content`'s `onCloseAutoFocus`: runs the consumer's
|
|
51
|
+
* handler first (so it can `preventDefault`), then stamps the focus-visible
|
|
52
|
+
* marker. Use in every DS overlay whose trigger is a `Button` so the restored
|
|
53
|
+
* focus ring is visible regardless of the closing input modality.
|
|
54
|
+
*/
|
|
55
|
+
export function composeCloseAutoFocus(handler) {
|
|
56
|
+
return (event) => {
|
|
57
|
+
handler?.(event);
|
|
58
|
+
markFocusVisibleOnClose(event);
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=focus-visible-on-close.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"focus-visible-on-close.js","sourceRoot":"","sources":["../../../src/lib/focus-visible-on-close.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,CAAC,MAAM,0BAA0B,GAAG,4BAA4B,CAAC;AAEvE;;;;;;GAMG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAAY;IAClD,IAAI,KAAK,CAAC,gBAAgB,IAAI,OAAO,qBAAqB,KAAK,WAAW,EAAE,CAAC;QAC3E,OAAO;IACT,CAAC;IACD,qBAAqB,CAAC,GAAG,EAAE;QACzB,MAAM,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC;QAClC,IAAI,CAAC,CAAC,EAAE,YAAY,WAAW,CAAC,IAAI,EAAE,KAAK,QAAQ,CAAC,IAAI;YAAE,OAAO;QACjE,EAAE,CAAC,YAAY,CAAC,0BAA0B,EAAE,EAAE,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,GAAG,EAAE;YACjB,EAAE,CAAC,eAAe,CAAC,0BAA0B,CAAC,CAAC;YAC/C,EAAE,CAAC,mBAAmB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YACtC,QAAQ,CAAC,mBAAmB,CAAC,aAAa,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAC3D,CAAC,CAAC;QACF,EAAE,CAAC,gBAAgB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACnC,QAAQ,CAAC,gBAAgB,CAAC,aAAa,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CACnC,OAAgC;IAEhC,OAAO,CAAC,KAAK,EAAE,EAAE;QACf,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC;QACjB,uBAAuB,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mirrors native `inert` onto the page background while a modal Radix overlay
|
|
3
|
+
* (Dialog, AlertDialog, DropdownMenu, Select, Sheet, modal Popover) is open.
|
|
4
|
+
*
|
|
5
|
+
* Why this exists (#259): those primitives call the `aria-hidden` package's
|
|
6
|
+
* `hideOthers()` on open, which marks every background sibling
|
|
7
|
+
* `aria-hidden="true"` (plus a `data-aria-hidden` counter) but leaves it
|
|
8
|
+
* keyboard-focusable. That trips axe's `aria-hidden-focus` rule
|
|
9
|
+
* (WCAG 4.1.2 / 2.4.3) on every consuming app. Radix's pinned version uses
|
|
10
|
+
* `hideOthers()`, not `inertOthers()`, so we add `inert` ourselves.
|
|
11
|
+
*
|
|
12
|
+
* Scope: only direct children of `document.body` are inerted — those are the
|
|
13
|
+
* real page-background roots (app root, portal-less content). This matches
|
|
14
|
+
* Radix's default body-level portals: `hideOthers()` marks the portal's
|
|
15
|
+
* body-level siblings (the background) plus the overlay's in-portal sibling
|
|
16
|
+
* (the backdrop). The backdrop lives *inside* the portal (not a body child), so
|
|
17
|
+
* it is left untouched — inerting it would block click-outside-to-close.
|
|
18
|
+
*
|
|
19
|
+
* Known limitation: an app that both mounts into a non-body container AND
|
|
20
|
+
* configures Radix to portal inside that same container would have its
|
|
21
|
+
* background marked at a nested level, not as a body child, and would fall
|
|
22
|
+
* outside this scope. DS overlays use the default (body) portal, so this does
|
|
23
|
+
* not affect them.
|
|
24
|
+
*
|
|
25
|
+
* We only ever clear `inert` on elements we set it on (tracked in a WeakSet), so
|
|
26
|
+
* a consumer's own `inert` is never clobbered.
|
|
27
|
+
*/
|
|
28
|
+
/**
|
|
29
|
+
* Installs a single document-wide observer that keeps `inert` in sync with the
|
|
30
|
+
* `data-aria-hidden` marker Radix applies. Idempotent — safe to call from every
|
|
31
|
+
* C4Provider mount; only the first call installs anything.
|
|
32
|
+
*/
|
|
33
|
+
export declare function installAriaHiddenInert(): void;
|
|
34
|
+
//# sourceMappingURL=inert-aria-hidden.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inert-aria-hidden.d.ts","sourceRoot":"","sources":["../../../src/lib/inert-aria-hidden.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAUH;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAqC7C"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mirrors native `inert` onto the page background while a modal Radix overlay
|
|
3
|
+
* (Dialog, AlertDialog, DropdownMenu, Select, Sheet, modal Popover) is open.
|
|
4
|
+
*
|
|
5
|
+
* Why this exists (#259): those primitives call the `aria-hidden` package's
|
|
6
|
+
* `hideOthers()` on open, which marks every background sibling
|
|
7
|
+
* `aria-hidden="true"` (plus a `data-aria-hidden` counter) but leaves it
|
|
8
|
+
* keyboard-focusable. That trips axe's `aria-hidden-focus` rule
|
|
9
|
+
* (WCAG 4.1.2 / 2.4.3) on every consuming app. Radix's pinned version uses
|
|
10
|
+
* `hideOthers()`, not `inertOthers()`, so we add `inert` ourselves.
|
|
11
|
+
*
|
|
12
|
+
* Scope: only direct children of `document.body` are inerted — those are the
|
|
13
|
+
* real page-background roots (app root, portal-less content). This matches
|
|
14
|
+
* Radix's default body-level portals: `hideOthers()` marks the portal's
|
|
15
|
+
* body-level siblings (the background) plus the overlay's in-portal sibling
|
|
16
|
+
* (the backdrop). The backdrop lives *inside* the portal (not a body child), so
|
|
17
|
+
* it is left untouched — inerting it would block click-outside-to-close.
|
|
18
|
+
*
|
|
19
|
+
* Known limitation: an app that both mounts into a non-body container AND
|
|
20
|
+
* configures Radix to portal inside that same container would have its
|
|
21
|
+
* background marked at a nested level, not as a body child, and would fall
|
|
22
|
+
* outside this scope. DS overlays use the default (body) portal, so this does
|
|
23
|
+
* not affect them.
|
|
24
|
+
*
|
|
25
|
+
* We only ever clear `inert` on elements we set it on (tracked in a WeakSet), so
|
|
26
|
+
* a consumer's own `inert` is never clobbered.
|
|
27
|
+
*/
|
|
28
|
+
const HIDDEN_SELECTOR = '[data-aria-hidden][aria-hidden="true"]';
|
|
29
|
+
let installed = false;
|
|
30
|
+
function isBackgroundRoot(el) {
|
|
31
|
+
return el.parentElement === document.body && el instanceof HTMLElement;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Installs a single document-wide observer that keeps `inert` in sync with the
|
|
35
|
+
* `data-aria-hidden` marker Radix applies. Idempotent — safe to call from every
|
|
36
|
+
* C4Provider mount; only the first call installs anything.
|
|
37
|
+
*/
|
|
38
|
+
export function installAriaHiddenInert() {
|
|
39
|
+
if (typeof document === "undefined" || installed)
|
|
40
|
+
return;
|
|
41
|
+
installed = true;
|
|
42
|
+
const owned = new WeakSet();
|
|
43
|
+
const sync = (el) => {
|
|
44
|
+
if (!isBackgroundRoot(el))
|
|
45
|
+
return;
|
|
46
|
+
const shouldInert = el.matches(HIDDEN_SELECTOR);
|
|
47
|
+
if (shouldInert && !el.inert) {
|
|
48
|
+
el.inert = true;
|
|
49
|
+
owned.add(el);
|
|
50
|
+
}
|
|
51
|
+
else if (!shouldInert && owned.has(el)) {
|
|
52
|
+
el.inert = false;
|
|
53
|
+
owned.delete(el);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
// Cover state that already exists at install time (an overlay may open before
|
|
57
|
+
// the first provider mounts, or the provider itself lives inside the overlay).
|
|
58
|
+
document.body.querySelectorAll(HIDDEN_SELECTOR).forEach(sync);
|
|
59
|
+
const observer = new MutationObserver((records) => {
|
|
60
|
+
for (const record of records)
|
|
61
|
+
sync(record.target);
|
|
62
|
+
});
|
|
63
|
+
// Watch only the marker attributes anywhere under body (cheap — the filter
|
|
64
|
+
// scopes callbacks to two attributes). This is the primary path: Radix
|
|
65
|
+
// toggles `aria-hidden`/`data-aria-hidden` on the background *after* the
|
|
66
|
+
// portal is inserted, so the attribute mutation always fires. Any background
|
|
67
|
+
// already marked at install time is handled by the scan above. Clearing the
|
|
68
|
+
// marker on close removes `inert` here; the FocusRestoredOnClose regression
|
|
69
|
+
// story guards that this lands before Radix restores focus to the trigger.
|
|
70
|
+
observer.observe(document.body, {
|
|
71
|
+
subtree: true,
|
|
72
|
+
attributes: true,
|
|
73
|
+
attributeFilter: ["aria-hidden", "data-aria-hidden"],
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=inert-aria-hidden.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inert-aria-hidden.js","sourceRoot":"","sources":["../../../src/lib/inert-aria-hidden.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,MAAM,eAAe,GAAG,wCAAwC,CAAC;AAEjE,IAAI,SAAS,GAAG,KAAK,CAAC;AAEtB,SAAS,gBAAgB,CAAC,EAAW;IACnC,OAAO,EAAE,CAAC,aAAa,KAAK,QAAQ,CAAC,IAAI,IAAI,EAAE,YAAY,WAAW,CAAC;AACzE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB;IACpC,IAAI,OAAO,QAAQ,KAAK,WAAW,IAAI,SAAS;QAAE,OAAO;IACzD,SAAS,GAAG,IAAI,CAAC;IAEjB,MAAM,KAAK,GAAG,IAAI,OAAO,EAAe,CAAC;IAEzC,MAAM,IAAI,GAAG,CAAC,EAAW,EAAE,EAAE;QAC3B,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC;YAAE,OAAO;QAClC,MAAM,WAAW,GAAG,EAAE,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QAChD,IAAI,WAAW,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;YAC7B,EAAE,CAAC,KAAK,GAAG,IAAI,CAAC;YAChB,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,CAAC;aAAM,IAAI,CAAC,WAAW,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YACzC,EAAE,CAAC,KAAK,GAAG,KAAK,CAAC;YACjB,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACnB,CAAC;IACH,CAAC,CAAC;IAEF,8EAA8E;IAC9E,+EAA+E;IAC/E,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9D,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAC,CAAC,OAAO,EAAE,EAAE;QAChD,KAAK,MAAM,MAAM,IAAI,OAAO;YAAE,IAAI,CAAC,MAAM,CAAC,MAAiB,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IACH,2EAA2E;IAC3E,uEAAuE;IACvE,yEAAyE;IACzE,6EAA6E;IAC7E,4EAA4E;IAC5E,4EAA4E;IAC5E,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE;QAC9B,OAAO,EAAE,IAAI;QACb,UAAU,EAAE,IAAI;QAChB,eAAe,EAAE,CAAC,aAAa,EAAE,kBAAkB,CAAC;KACrD,CAAC,CAAC;AACL,CAAC"}
|