@apostel/bedrock 0.1.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/LICENSE +21 -0
- package/README.md +216 -0
- package/dist/accessible-icon/parts.d.ts +16 -0
- package/dist/accessible-icon/parts.d.ts.map +1 -0
- package/dist/accessible-icon/parts.js +24 -0
- package/dist/accessible-icon/parts.js.map +1 -0
- package/dist/accordion/controlled-root.d.ts +19 -0
- package/dist/accordion/controlled-root.d.ts.map +1 -0
- package/dist/accordion/controlled-root.js +53 -0
- package/dist/accordion/controlled-root.js.map +1 -0
- package/dist/accordion/parts.d.ts +35 -0
- package/dist/accordion/parts.d.ts.map +1 -0
- package/dist/accordion/parts.js +52 -0
- package/dist/accordion/parts.js.map +1 -0
- package/dist/accordion/root.d.ts +24 -0
- package/dist/accordion/root.d.ts.map +1 -0
- package/dist/accordion/root.js +45 -0
- package/dist/accordion/root.js.map +1 -0
- package/dist/accordion/shared.d.ts +23 -0
- package/dist/accordion/shared.d.ts.map +1 -0
- package/dist/accordion/shared.js +16 -0
- package/dist/accordion/shared.js.map +1 -0
- package/dist/alert-dialog/parts.d.ts +16 -0
- package/dist/alert-dialog/parts.d.ts.map +1 -0
- package/dist/alert-dialog/parts.js +20 -0
- package/dist/alert-dialog/parts.js.map +1 -0
- package/dist/anchor.d.ts +27 -0
- package/dist/anchor.d.ts.map +1 -0
- package/dist/anchor.js +70 -0
- package/dist/anchor.js.map +1 -0
- package/dist/aspect-ratio/parts.d.ts +16 -0
- package/dist/aspect-ratio/parts.d.ts.map +1 -0
- package/dist/aspect-ratio/parts.js +15 -0
- package/dist/aspect-ratio/parts.js.map +1 -0
- package/dist/avatar/parts.d.ts +23 -0
- package/dist/avatar/parts.d.ts.map +1 -0
- package/dist/avatar/parts.js +51 -0
- package/dist/avatar/parts.js.map +1 -0
- package/dist/bedrock.css +64 -0
- package/dist/capabilities.d.ts +25 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/capabilities.js +40 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/checkbox/controlled-root.d.ts +18 -0
- package/dist/checkbox/controlled-root.d.ts.map +1 -0
- package/dist/checkbox/controlled-root.js +28 -0
- package/dist/checkbox/controlled-root.js.map +1 -0
- package/dist/checkbox/parts.d.ts +29 -0
- package/dist/checkbox/parts.d.ts.map +1 -0
- package/dist/checkbox/parts.js +42 -0
- package/dist/checkbox/parts.js.map +1 -0
- package/dist/client-render.d.ts +10 -0
- package/dist/client-render.d.ts.map +1 -0
- package/dist/client-render.js +14 -0
- package/dist/client-render.js.map +1 -0
- package/dist/collapsible/controlled-root.d.ts +17 -0
- package/dist/collapsible/controlled-root.d.ts.map +1 -0
- package/dist/collapsible/controlled-root.js +21 -0
- package/dist/collapsible/controlled-root.js.map +1 -0
- package/dist/collapsible/parts.d.ts +14 -0
- package/dist/collapsible/parts.d.ts.map +1 -0
- package/dist/collapsible/parts.js +24 -0
- package/dist/collapsible/parts.js.map +1 -0
- package/dist/collapsible/root.d.ts +16 -0
- package/dist/collapsible/root.d.ts.map +1 -0
- package/dist/collapsible/root.js +28 -0
- package/dist/collapsible/root.js.map +1 -0
- package/dist/collapsible/shared.d.ts +11 -0
- package/dist/collapsible/shared.d.ts.map +1 -0
- package/dist/collapsible/shared.js +26 -0
- package/dist/collapsible/shared.js.map +1 -0
- package/dist/compose-refs.d.ts +29 -0
- package/dist/compose-refs.d.ts.map +1 -0
- package/dist/compose-refs.js +67 -0
- package/dist/compose-refs.js.map +1 -0
- package/dist/context-menu/root.d.ts +17 -0
- package/dist/context-menu/root.d.ts.map +1 -0
- package/dist/context-menu/root.js +50 -0
- package/dist/context-menu/root.js.map +1 -0
- package/dist/controlled.d.ts +120 -0
- package/dist/controlled.d.ts.map +1 -0
- package/dist/controlled.js +91 -0
- package/dist/controlled.js.map +1 -0
- package/dist/create-controlled-root.d.ts +29 -0
- package/dist/create-controlled-root.d.ts.map +1 -0
- package/dist/create-controlled-root.js +92 -0
- package/dist/create-controlled-root.js.map +1 -0
- package/dist/dialog/controlled-root.d.ts +15 -0
- package/dist/dialog/controlled-root.d.ts.map +1 -0
- package/dist/dialog/controlled-root.js +21 -0
- package/dist/dialog/controlled-root.js.map +1 -0
- package/dist/dialog/parts.d.ts +18 -0
- package/dist/dialog/parts.d.ts.map +1 -0
- package/dist/dialog/parts.js +80 -0
- package/dist/dialog/parts.js.map +1 -0
- package/dist/dialog/root.d.ts +22 -0
- package/dist/dialog/root.d.ts.map +1 -0
- package/dist/dialog/root.js +39 -0
- package/dist/dialog/root.js.map +1 -0
- package/dist/dialog/shared.d.ts +32 -0
- package/dist/dialog/shared.d.ts.map +1 -0
- package/dist/dialog/shared.js +53 -0
- package/dist/dialog/shared.js.map +1 -0
- package/dist/dropdown-menu/controlled-root.d.ts +7 -0
- package/dist/dropdown-menu/controlled-root.d.ts.map +1 -0
- package/dist/dropdown-menu/controlled-root.js +13 -0
- package/dist/dropdown-menu/controlled-root.js.map +1 -0
- package/dist/dropdown-menu/root.d.ts +13 -0
- package/dist/dropdown-menu/root.d.ts.map +1 -0
- package/dist/dropdown-menu/root.js +22 -0
- package/dist/dropdown-menu/root.js.map +1 -0
- package/dist/hover-card/controlled-root.d.ts +9 -0
- package/dist/hover-card/controlled-root.d.ts.map +1 -0
- package/dist/hover-card/controlled-root.js +15 -0
- package/dist/hover-card/controlled-root.js.map +1 -0
- package/dist/hover-card/root.d.ts +13 -0
- package/dist/hover-card/root.d.ts.map +1 -0
- package/dist/hover-card/root.js +19 -0
- package/dist/hover-card/root.js.map +1 -0
- package/dist/index.d.ts +274 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +211 -0
- package/dist/index.js.map +1 -0
- package/dist/interest.d.ts +30 -0
- package/dist/interest.d.ts.map +1 -0
- package/dist/interest.js +94 -0
- package/dist/interest.js.map +1 -0
- package/dist/label/parts.d.ts +14 -0
- package/dist/label/parts.d.ts.map +1 -0
- package/dist/label/parts.js +21 -0
- package/dist/label/parts.js.map +1 -0
- package/dist/menu/parts.d.ts +64 -0
- package/dist/menu/parts.d.ts.map +1 -0
- package/dist/menu/parts.js +131 -0
- package/dist/menu/parts.js.map +1 -0
- package/dist/menu/shared.d.ts +7 -0
- package/dist/menu/shared.d.ts.map +1 -0
- package/dist/menu/shared.js +9 -0
- package/dist/menu/shared.js.map +1 -0
- package/dist/menubar/parts.d.ts +20 -0
- package/dist/menubar/parts.d.ts.map +1 -0
- package/dist/menubar/parts.js +34 -0
- package/dist/menubar/parts.js.map +1 -0
- package/dist/navigation-menu/parts.d.ts +28 -0
- package/dist/navigation-menu/parts.d.ts.map +1 -0
- package/dist/navigation-menu/parts.js +46 -0
- package/dist/navigation-menu/parts.js.map +1 -0
- package/dist/open-state.d.ts +23 -0
- package/dist/open-state.d.ts.map +1 -0
- package/dist/open-state.js +106 -0
- package/dist/open-state.js.map +1 -0
- package/dist/popover/controlled-root.d.ts +14 -0
- package/dist/popover/controlled-root.d.ts.map +1 -0
- package/dist/popover/controlled-root.js +17 -0
- package/dist/popover/controlled-root.js.map +1 -0
- package/dist/popover/parts.d.ts +27 -0
- package/dist/popover/parts.d.ts.map +1 -0
- package/dist/popover/parts.js +39 -0
- package/dist/popover/parts.js.map +1 -0
- package/dist/popover/root.d.ts +24 -0
- package/dist/popover/root.d.ts.map +1 -0
- package/dist/popover/root.js +24 -0
- package/dist/popover/root.js.map +1 -0
- package/dist/popover/shared.d.ts +22 -0
- package/dist/popover/shared.d.ts.map +1 -0
- package/dist/popover/shared.js +25 -0
- package/dist/popover/shared.js.map +1 -0
- package/dist/progress/parts.d.ts +25 -0
- package/dist/progress/parts.d.ts.map +1 -0
- package/dist/progress/parts.js +32 -0
- package/dist/progress/parts.js.map +1 -0
- package/dist/radio-group/controlled-root.d.ts +19 -0
- package/dist/radio-group/controlled-root.d.ts.map +1 -0
- package/dist/radio-group/controlled-root.js +29 -0
- package/dist/radio-group/controlled-root.js.map +1 -0
- package/dist/radio-group/parts.d.ts +36 -0
- package/dist/radio-group/parts.d.ts.map +1 -0
- package/dist/radio-group/parts.js +62 -0
- package/dist/radio-group/parts.js.map +1 -0
- package/dist/roving.d.ts +26 -0
- package/dist/roving.d.ts.map +1 -0
- package/dist/roving.js +124 -0
- package/dist/roving.js.map +1 -0
- package/dist/scroll-area/parts.d.ts +29 -0
- package/dist/scroll-area/parts.d.ts.map +1 -0
- package/dist/scroll-area/parts.js +44 -0
- package/dist/scroll-area/parts.js.map +1 -0
- package/dist/select/parts.d.ts +57 -0
- package/dist/select/parts.d.ts.map +1 -0
- package/dist/select/parts.js +76 -0
- package/dist/select/parts.js.map +1 -0
- package/dist/separator/parts.d.ts +14 -0
- package/dist/separator/parts.d.ts.map +1 -0
- package/dist/separator/parts.js +15 -0
- package/dist/separator/parts.js.map +1 -0
- package/dist/slider/parts.d.ts +32 -0
- package/dist/slider/parts.d.ts.map +1 -0
- package/dist/slider/parts.js +52 -0
- package/dist/slider/parts.js.map +1 -0
- package/dist/slot.d.ts +3 -0
- package/dist/slot.d.ts.map +1 -0
- package/dist/slot.js +49 -0
- package/dist/slot.js.map +1 -0
- package/dist/switch/parts.d.ts +21 -0
- package/dist/switch/parts.d.ts.map +1 -0
- package/dist/switch/parts.js +31 -0
- package/dist/switch/parts.js.map +1 -0
- package/dist/tabs/controlled-root.d.ts +11 -0
- package/dist/tabs/controlled-root.d.ts.map +1 -0
- package/dist/tabs/controlled-root.js +15 -0
- package/dist/tabs/controlled-root.js.map +1 -0
- package/dist/tabs/parts.d.ts +20 -0
- package/dist/tabs/parts.d.ts.map +1 -0
- package/dist/tabs/parts.js +42 -0
- package/dist/tabs/parts.js.map +1 -0
- package/dist/tabs/root.d.ts +15 -0
- package/dist/tabs/root.d.ts.map +1 -0
- package/dist/tabs/root.js +26 -0
- package/dist/tabs/root.js.map +1 -0
- package/dist/tabs/shared.d.ts +12 -0
- package/dist/tabs/shared.d.ts.map +1 -0
- package/dist/tabs/shared.js +11 -0
- package/dist/tabs/shared.js.map +1 -0
- package/dist/toast/parts.d.ts +40 -0
- package/dist/toast/parts.d.ts.map +1 -0
- package/dist/toast/parts.js +102 -0
- package/dist/toast/parts.js.map +1 -0
- package/dist/toggle/controlled-root.d.ts +9 -0
- package/dist/toggle/controlled-root.d.ts.map +1 -0
- package/dist/toggle/controlled-root.js +14 -0
- package/dist/toggle/controlled-root.js.map +1 -0
- package/dist/toggle/parts.d.ts +20 -0
- package/dist/toggle/parts.d.ts.map +1 -0
- package/dist/toggle/parts.js +29 -0
- package/dist/toggle/parts.js.map +1 -0
- package/dist/toggle-group/parts.d.ts +28 -0
- package/dist/toggle-group/parts.d.ts.map +1 -0
- package/dist/toggle-group/parts.js +57 -0
- package/dist/toggle-group/parts.js.map +1 -0
- package/dist/toolbar/parts.d.ts +22 -0
- package/dist/toolbar/parts.d.ts.map +1 -0
- package/dist/toolbar/parts.js +27 -0
- package/dist/toolbar/parts.js.map +1 -0
- package/dist/tooltip/controlled-root.d.ts +9 -0
- package/dist/tooltip/controlled-root.d.ts.map +1 -0
- package/dist/tooltip/controlled-root.js +15 -0
- package/dist/tooltip/controlled-root.js.map +1 -0
- package/dist/tooltip/parts.d.ts +23 -0
- package/dist/tooltip/parts.d.ts.map +1 -0
- package/dist/tooltip/parts.js +28 -0
- package/dist/tooltip/parts.js.map +1 -0
- package/dist/tooltip/root.d.ts +13 -0
- package/dist/tooltip/root.d.ts.map +1 -0
- package/dist/tooltip/root.js +17 -0
- package/dist/tooltip/root.js.map +1 -0
- package/dist/tooltip/shared.d.ts +13 -0
- package/dist/tooltip/shared.d.ts.map +1 -0
- package/dist/tooltip/shared.js +9 -0
- package/dist/tooltip/shared.js.map +1 -0
- package/dist/tooltip/use-controlled-interest-root.d.ts +19 -0
- package/dist/tooltip/use-controlled-interest-root.d.ts.map +1 -0
- package/dist/tooltip/use-controlled-interest-root.js +31 -0
- package/dist/tooltip/use-controlled-interest-root.js.map +1 -0
- package/dist/tooltip/use-interest-root.d.ts +16 -0
- package/dist/tooltip/use-interest-root.d.ts.map +1 -0
- package/dist/tooltip/use-interest-root.js +39 -0
- package/dist/tooltip/use-interest-root.js.map +1 -0
- package/dist/types.d.ts +55 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/validate-element.d.ts +12 -0
- package/dist/validate-element.d.ts.map +1 -0
- package/dist/validate-element.js +21 -0
- package/dist/validate-element.js.map +1 -0
- package/dist/validate-trigger.d.ts +14 -0
- package/dist/validate-trigger.d.ts.map +1 -0
- package/dist/validate-trigger.js +59 -0
- package/dist/validate-trigger.js.map +1 -0
- package/dist/visually-hidden/parts.d.ts +12 -0
- package/dist/visually-hidden/parts.d.ts.map +1 -0
- package/dist/visually-hidden/parts.js +25 -0
- package/dist/visually-hidden/parts.js.map +1 -0
- package/package.json +81 -0
- package/skills/migrate-to-bedrock/SKILL.md +188 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { useCallback, useEffect, useId, useRef, useState } from 'react';
|
|
2
|
+
import { useOpenState } from './open-state.js';
|
|
3
|
+
/**
|
|
4
|
+
* Builds the context value for a controlled root.
|
|
5
|
+
*
|
|
6
|
+
* This is the entire cost of controlled mode, and it lives on the root. Every
|
|
7
|
+
* child part — Trigger, Content, Close — is byte-identical under both roots and
|
|
8
|
+
* never branches on which one it's under. If children had to ask "am I
|
|
9
|
+
* controlled?", the branch would ship in both bundles and the split would buy
|
|
10
|
+
* nothing.
|
|
11
|
+
*
|
|
12
|
+
* The model is DOM leads, React vetoes:
|
|
13
|
+
*
|
|
14
|
+
* 1. The user acts. `beforetoggle` fires. Where it's cancelable — popovers —
|
|
15
|
+
* and the `open` prop disagrees, we preventDefault and nothing moved.
|
|
16
|
+
* 2. `onOpenChange` fires regardless, so the consumer can decide.
|
|
17
|
+
* 3. An effect on `open` reconciles the DOM whenever the prop changes without
|
|
18
|
+
* user interaction.
|
|
19
|
+
*
|
|
20
|
+
* Where step 1 isn't available, step 3 is the whole mechanism: the DOM moves,
|
|
21
|
+
* we report, and if the consumer refuses we put it back. That's one frame of
|
|
22
|
+
* visible movement, in the refusal case only. Worth knowing; not worth a
|
|
23
|
+
* synchronous re-render to avoid.
|
|
24
|
+
*/
|
|
25
|
+
export function useControlledRoot({ open, onOpenChange }, adapter) {
|
|
26
|
+
const id = useId();
|
|
27
|
+
const [node, setNode] = useState(null);
|
|
28
|
+
// The same DOM-observed open state the plain root publishes, from the same
|
|
29
|
+
// hook. It is deliberately not derived from the `open` prop: during a refused
|
|
30
|
+
// open the prop and the DOM disagree, and children follow the DOM.
|
|
31
|
+
const { open: domOpen, observe } = useOpenState();
|
|
32
|
+
// Read through refs inside listeners so we never rebind on every render.
|
|
33
|
+
const openRef = useRef(open);
|
|
34
|
+
const changeRef = useRef(onOpenChange);
|
|
35
|
+
openRef.current = open;
|
|
36
|
+
changeRef.current = onOpenChange;
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
if (!node)
|
|
39
|
+
return;
|
|
40
|
+
const onBeforeToggle = (event) => {
|
|
41
|
+
const next = event.newState === 'open';
|
|
42
|
+
if (next === openRef.current)
|
|
43
|
+
return;
|
|
44
|
+
if (event.cancelable)
|
|
45
|
+
event.preventDefault();
|
|
46
|
+
changeRef.current?.(next);
|
|
47
|
+
};
|
|
48
|
+
// Only reached when beforetoggle couldn't be canceled.
|
|
49
|
+
const onToggle = (event) => {
|
|
50
|
+
const next = event.newState === 'open';
|
|
51
|
+
if (next !== openRef.current)
|
|
52
|
+
changeRef.current?.(next);
|
|
53
|
+
};
|
|
54
|
+
const onCloseVeto = (event) => {
|
|
55
|
+
if (openRef.current)
|
|
56
|
+
event.preventDefault();
|
|
57
|
+
changeRef.current?.(false);
|
|
58
|
+
};
|
|
59
|
+
node.addEventListener('beforetoggle', onBeforeToggle);
|
|
60
|
+
node.addEventListener('toggle', onToggle);
|
|
61
|
+
if (adapter.closeVetoEvent)
|
|
62
|
+
node.addEventListener(adapter.closeVetoEvent, onCloseVeto);
|
|
63
|
+
return () => {
|
|
64
|
+
node.removeEventListener('beforetoggle', onBeforeToggle);
|
|
65
|
+
node.removeEventListener('toggle', onToggle);
|
|
66
|
+
if (adapter.closeVetoEvent)
|
|
67
|
+
node.removeEventListener(adapter.closeVetoEvent, onCloseVeto);
|
|
68
|
+
};
|
|
69
|
+
}, [node, adapter]);
|
|
70
|
+
// Reconcile: the prop is the source of truth once React has settled.
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
if (!node)
|
|
73
|
+
return;
|
|
74
|
+
if (adapter.isOpen(node) === open)
|
|
75
|
+
return;
|
|
76
|
+
// Note for adapter authors: a state update from a discrete event is flushed
|
|
77
|
+
// synchronously, so this runs while the browser is still inside the dispatch
|
|
78
|
+
// it is reacting to. An adapter whose close is a *request* — anything built
|
|
79
|
+
// on a close watcher — will find that call silently dropped as re-entrant.
|
|
80
|
+
// Adapters must close outright here; the veto already happened.
|
|
81
|
+
if (open)
|
|
82
|
+
adapter.open(node);
|
|
83
|
+
else
|
|
84
|
+
adapter.close(node);
|
|
85
|
+
}, [node, open, adapter]);
|
|
86
|
+
const registerContent = useCallback((next) => {
|
|
87
|
+
observe(next);
|
|
88
|
+
setNode(next);
|
|
89
|
+
}, [observe]);
|
|
90
|
+
return { id, open: domOpen, registerContent };
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=create-controlled-root.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-controlled-root.js","sourceRoot":"","sources":["../src/create-controlled-root.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type ControlledRootProps } from '../create-controlled-root.js';
|
|
3
|
+
export interface ControlledDialogRootProps extends ControlledRootProps {
|
|
4
|
+
children?: ReactNode;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Same name, same parts, same props on every part as the plain root — swapping
|
|
8
|
+
* between them is an import change and nothing else.
|
|
9
|
+
*
|
|
10
|
+
* All the extra weight is `useControlledRoot`. The context this publishes is
|
|
11
|
+
* the same shape the plain root publishes, so no child part can tell the
|
|
12
|
+
* difference, and none of this reaches an app that never imports it.
|
|
13
|
+
*/
|
|
14
|
+
export declare function DialogRoot({ children, ...props }: ControlledDialogRootProps): import("react").JSX.Element;
|
|
15
|
+
//# sourceMappingURL=controlled-root.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controlled-root.d.ts","sourceRoot":"","sources":["../../src/dialog/controlled-root.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAC/C,OAAO,EAAqB,KAAK,mBAAmB,EAAE,MAAM,2BAA2B,CAAA;AAGvF,MAAM,WAAW,yBAA0B,SAAQ,mBAAmB;IACpE,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,yBAAyB,+BAS3E"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
import { useControlledRoot } from '../create-controlled-root.js';
|
|
4
|
+
import { DialogContext, dialogAdapter, useDialogLabelling } from './shared.js';
|
|
5
|
+
/**
|
|
6
|
+
* Same name, same parts, same props on every part as the plain root — swapping
|
|
7
|
+
* between them is an import change and nothing else.
|
|
8
|
+
*
|
|
9
|
+
* All the extra weight is `useControlledRoot`. The context this publishes is
|
|
10
|
+
* the same shape the plain root publishes, so no child part can tell the
|
|
11
|
+
* difference, and none of this reaches an app that never imports it.
|
|
12
|
+
*/
|
|
13
|
+
export function DialogRoot({ children, ...props }) {
|
|
14
|
+
const context = useControlledRoot(props, dialogAdapter);
|
|
15
|
+
// Its own id: the labelling ids have to be stable and unique per root, and
|
|
16
|
+
// useControlledRoot already made one for the invoker wiring.
|
|
17
|
+
const labelling = useDialogLabelling(context.id);
|
|
18
|
+
const value = useMemo(() => ({ ...context, ...labelling }), [context, labelling]);
|
|
19
|
+
return _jsx(DialogContext.Provider, { value: value, children: children });
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=controlled-root.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controlled-root.js","sourceRoot":"","sources":["../../src/dialog/controlled-root.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAkB,MAAM,OAAO,CAAA;AAC/C,OAAO,EAAE,iBAAiB,EAA4B,MAAM,2BAA2B,CAAA;AACvF,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAM3E;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAA6B;IAC1E,MAAM,OAAO,GAAG,iBAAiB,CAAC,KAAK,EAAE,aAAa,CAAC,CAAA;IACvD,2EAA2E;IAC3E,6DAA6D;IAC7D,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IAEhD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,GAAG,SAAS,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAA;IAEjF,OAAO,KAAC,aAAa,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YAAG,QAAQ,GAA0B,CAAA;AAClF,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type ComponentPropsWithRef } from 'react';
|
|
2
|
+
import type { AsChildProps } from '../types.js';
|
|
3
|
+
export interface DialogTriggerProps extends ComponentPropsWithRef<'button'>, AsChildProps {
|
|
4
|
+
}
|
|
5
|
+
export declare function DialogTrigger({ asChild, ref, ...props }: DialogTriggerProps): import("react").JSX.Element;
|
|
6
|
+
export interface DialogContentProps extends ComponentPropsWithRef<'dialog'>, AsChildProps {
|
|
7
|
+
}
|
|
8
|
+
export declare function DialogContent({ asChild, ref, children, ...props }: DialogContentProps): import("react").JSX.Element;
|
|
9
|
+
export interface DialogTitleProps extends ComponentPropsWithRef<'h2'>, AsChildProps {
|
|
10
|
+
}
|
|
11
|
+
export declare function DialogTitle({ asChild, ...props }: DialogTitleProps): import("react").JSX.Element;
|
|
12
|
+
export interface DialogDescriptionProps extends ComponentPropsWithRef<'p'>, AsChildProps {
|
|
13
|
+
}
|
|
14
|
+
export declare function DialogDescription({ asChild, ...props }: DialogDescriptionProps): import("react").JSX.Element;
|
|
15
|
+
export interface DialogCloseProps extends ComponentPropsWithRef<'button'>, AsChildProps {
|
|
16
|
+
}
|
|
17
|
+
export declare function DialogClose({ asChild, ref, ...props }: DialogCloseProps): import("react").JSX.Element;
|
|
18
|
+
//# sourceMappingURL=parts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parts.d.ts","sourceRoot":"","sources":["../../src/dialog/parts.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,qBAAqB,EAG3B,MAAM,OAAO,CAAA;AAId,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAK5C,MAAM,WAAW,kBAAmB,SAAQ,qBAAqB,CAAC,QAAQ,CAAC,EAAE,YAAY;CAAG;AAE5F,wBAAgB,aAAa,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,KAAK,EAAE,EAAE,kBAAkB,+BAyB3E;AAED,MAAM,WAAW,kBAAmB,SAAQ,qBAAqB,CAAC,QAAQ,CAAC,EAAE,YAAY;CAAG;AAiB5F,wBAAgB,aAAa,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,kBAAkB,+BAoDrF;AAED,MAAM,WAAW,gBAAiB,SAAQ,qBAAqB,CAAC,IAAI,CAAC,EAAE,YAAY;CAAG;AAEtF,wBAAgB,WAAW,CAAC,EAAE,OAAO,EAAE,GAAG,KAAK,EAAE,EAAE,gBAAgB,+BASlE;AAED,MAAM,WAAW,sBAAuB,SAAQ,qBAAqB,CAAC,GAAG,CAAC,EAAE,YAAY;CAAG;AAE3F,wBAAgB,iBAAiB,CAAC,EAAE,OAAO,EAAE,GAAG,KAAK,EAAE,EAAE,sBAAsB,+BAO9E;AAED,MAAM,WAAW,gBAAiB,SAAQ,qBAAqB,CAAC,QAAQ,CAAC,EAAE,YAAY;CAAG;AAE1F,wBAAgB,WAAW,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,KAAK,EAAE,EAAE,gBAAgB,+BAkBvE"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cloneElement, isValidElement, useEffect, } from 'react';
|
|
3
|
+
import { useClientRender } from '../client-render.js';
|
|
4
|
+
import { useComposedRefs } from '../compose-refs.js';
|
|
5
|
+
import { Slot } from '../slot.js';
|
|
6
|
+
import { validateElement } from '../validate-element.js';
|
|
7
|
+
import { validateTrigger } from '../validate-trigger.js';
|
|
8
|
+
import { useDialogContext } from './shared.js';
|
|
9
|
+
export function DialogTrigger({ asChild, ref, ...props }) {
|
|
10
|
+
const { id, open } = useDialogContext('Dialog.Trigger');
|
|
11
|
+
const Part = asChild ? Slot : 'button';
|
|
12
|
+
return (_jsx(Part, { ...props,
|
|
13
|
+
// After the spread: the invoker wiring is the part, not a default.
|
|
14
|
+
type: "button", commandfor: id, command: "show-modal", "aria-expanded": open, "aria-controls": open ? id : undefined, "data-bedrock-dialog-trigger": "", ref: useComposedRefs(ref, (node) => validateTrigger(node, 'command', 'Dialog.Trigger')) }));
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Radix's rule, and it is the right one: an `aria-describedby` you pass is
|
|
18
|
+
* *added to*, not swapped for, the Description's id — the description is still
|
|
19
|
+
* rendered, so dropping its reference would be a lie about the markup.
|
|
20
|
+
*
|
|
21
|
+
* Duplicates and stray whitespace are normalised, because an id list is a set
|
|
22
|
+
* and `' a\ta a b '` is the shape these arrive in.
|
|
23
|
+
*/
|
|
24
|
+
function mergeIds(passed, own) {
|
|
25
|
+
const ids = [...(passed ?? '').split(/\s+/), ...(own ?? '').split(/\s+/)].filter(Boolean);
|
|
26
|
+
const unique = [...new Set(ids)];
|
|
27
|
+
return unique.length > 0 ? unique.join(' ') : undefined;
|
|
28
|
+
}
|
|
29
|
+
export function DialogContent({ asChild, ref, children, ...props }) {
|
|
30
|
+
const { id, open, registerContent, labelledBy, describedBy } = useDialogContext('Dialog.Content');
|
|
31
|
+
const onClient = useClientRender();
|
|
32
|
+
// The <dialog> itself is always rendered — the trigger's `commandfor` has to
|
|
33
|
+
// resolve to something, always. Its children are not: they mount when the
|
|
34
|
+
// browser opens it and unmount once the exit animation is done, so closing
|
|
35
|
+
// resets whatever they were holding.
|
|
36
|
+
const mounted = open || !onClient;
|
|
37
|
+
// `in` rather than `??`, so passing an explicit undefined removes the
|
|
38
|
+
// association — the escape hatch for a dialog labelled some other way.
|
|
39
|
+
const Part = asChild ? Slot : 'dialog';
|
|
40
|
+
// A label is one thing, so yours replaces ours. A description is a list, so
|
|
41
|
+
// yours joins ours. `in` rather than `??` either way, so passing an explicit
|
|
42
|
+
// undefined still removes the association entirely.
|
|
43
|
+
const label = 'aria-labelledby' in props ? props['aria-labelledby'] : labelledBy;
|
|
44
|
+
const description = 'aria-describedby' in props ? mergeIds(props['aria-describedby'], describedBy) : describedBy;
|
|
45
|
+
// With `asChild` the child *is* the <dialog>, so gating it would unmount the
|
|
46
|
+
// element the trigger points at. What gets gated is one level deeper: the
|
|
47
|
+
// child's own children.
|
|
48
|
+
const body = asChild && isValidElement(children)
|
|
49
|
+
? cloneElement(children, {}, mounted ? (children.props.children ?? null) : null)
|
|
50
|
+
: mounted
|
|
51
|
+
? children
|
|
52
|
+
: null;
|
|
53
|
+
return (_jsx(Part, { ...props,
|
|
54
|
+
// The trigger's `commandfor` points here, so this id is load-bearing and
|
|
55
|
+
// is not forwarded from props the way every other part's id is.
|
|
56
|
+
id: id, "aria-labelledby": label, "aria-describedby": description, "data-bedrock-dialog": "", ref: useComposedRefs(ref, registerContent, (node) => validateElement(node, 'DIALOG', 'Dialog.Content')), children: body }));
|
|
57
|
+
}
|
|
58
|
+
export function DialogTitle({ asChild, ...props }) {
|
|
59
|
+
const { id, registerTitle } = useDialogContext('Dialog.Title');
|
|
60
|
+
const Part = asChild ? Slot : 'h2';
|
|
61
|
+
// Announces itself so Content can point `aria-labelledby` at something that
|
|
62
|
+
// exists. A reference to a missing element is a dialog with no name.
|
|
63
|
+
useEffect(() => registerTitle(), [registerTitle]);
|
|
64
|
+
return _jsx(Part, { ...props, id: `${id}-title`, "data-bedrock-dialog-title": "" });
|
|
65
|
+
}
|
|
66
|
+
export function DialogDescription({ asChild, ...props }) {
|
|
67
|
+
const { id, registerDescription } = useDialogContext('Dialog.Description');
|
|
68
|
+
const Part = asChild ? Slot : 'p';
|
|
69
|
+
useEffect(() => registerDescription(), [registerDescription]);
|
|
70
|
+
return _jsx(Part, { ...props, id: `${id}-description`, "data-bedrock-dialog-description": "" });
|
|
71
|
+
}
|
|
72
|
+
export function DialogClose({ asChild, ref, ...props }) {
|
|
73
|
+
const { id } = useDialogContext('Dialog.Close');
|
|
74
|
+
const Part = asChild ? Slot : 'button';
|
|
75
|
+
return (_jsx(Part, { ...props, type: "button", commandfor: id,
|
|
76
|
+
// Never `close`: that skips `cancel`, the only cancelable close hook a
|
|
77
|
+
// <dialog> has, and the controlled root's close veto is built on it.
|
|
78
|
+
command: "request-close", "data-bedrock-dialog-close": "", ref: useComposedRefs(ref, (node) => validateTrigger(node, 'command', 'Dialog.Close')) }));
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=parts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parts.js","sourceRoot":"","sources":["../../src/dialog/parts.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
export interface DialogRootProps {
|
|
3
|
+
children?: ReactNode;
|
|
4
|
+
/** Open on mount. Read once; later changes do nothing. */
|
|
5
|
+
defaultOpen?: boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Fires after the DOM has already moved. Read-only by design — it is a
|
|
8
|
+
* `toggle` listener, not a state hook. If React needs to refuse an open or a
|
|
9
|
+
* close, import Dialog from '@apostel/bedrock/controlled' instead.
|
|
10
|
+
*/
|
|
11
|
+
onOpenChange?(open: boolean): void;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The default root. Nothing here opens or closes the dialog: the trigger's
|
|
15
|
+
* `commandfor` does that in the parser, before hydration and without us.
|
|
16
|
+
*
|
|
17
|
+
* What's left is a `toggle` listener, which is what "I need to know when it
|
|
18
|
+
* closed so I can reset the form" actually needs, and which is why that case
|
|
19
|
+
* doesn't have to reach for the controlled entry point.
|
|
20
|
+
*/
|
|
21
|
+
export declare function DialogRoot({ children, defaultOpen, onOpenChange }: DialogRootProps): import("react").JSX.Element;
|
|
22
|
+
//# sourceMappingURL=root.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"root.d.ts","sourceRoot":"","sources":["../../src/dialog/root.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAuC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAI3E,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,0DAA0D;IAC1D,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB;;;;OAIG;IACH,YAAY,CAAC,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAA;CACnC;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,EAAE,QAAQ,EAAE,WAAmB,EAAE,YAAY,EAAE,EAAE,eAAe,+BAqC1F"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useId, useMemo, useRef } from 'react';
|
|
3
|
+
import { useOpenState } from '../open-state.js';
|
|
4
|
+
import { DialogContext, dialogAdapter, useDialogLabelling } from './shared.js';
|
|
5
|
+
/**
|
|
6
|
+
* The default root. Nothing here opens or closes the dialog: the trigger's
|
|
7
|
+
* `commandfor` does that in the parser, before hydration and without us.
|
|
8
|
+
*
|
|
9
|
+
* What's left is a `toggle` listener, which is what "I need to know when it
|
|
10
|
+
* closed so I can reset the form" actually needs, and which is why that case
|
|
11
|
+
* doesn't have to reach for the controlled entry point.
|
|
12
|
+
*/
|
|
13
|
+
export function DialogRoot({ children, defaultOpen = false, onOpenChange }) {
|
|
14
|
+
const id = useId();
|
|
15
|
+
// Read through refs inside the listener so a changing callback never forces
|
|
16
|
+
// us to detach and reattach.
|
|
17
|
+
const changeRef = useRef(onOpenChange);
|
|
18
|
+
changeRef.current = onOpenChange;
|
|
19
|
+
const report = useCallback((next) => changeRef.current?.(next), []);
|
|
20
|
+
const { open, observe } = useOpenState(report, defaultOpen);
|
|
21
|
+
const labelling = useDialogLabelling(id);
|
|
22
|
+
const defaultOpenRef = useRef(defaultOpen);
|
|
23
|
+
const openedRef = useRef(false);
|
|
24
|
+
const registerContent = useCallback((node) => {
|
|
25
|
+
observe(node);
|
|
26
|
+
if (!node)
|
|
27
|
+
return;
|
|
28
|
+
// The `open` attribute renders a <dialog> inline — no top layer, no
|
|
29
|
+
// backdrop, no focus trap — so it is not the declarative form of
|
|
30
|
+
// showModal() and can't stand in for it here. Once, on first mount.
|
|
31
|
+
if (defaultOpenRef.current && !openedRef.current) {
|
|
32
|
+
openedRef.current = true;
|
|
33
|
+
dialogAdapter.open(node);
|
|
34
|
+
}
|
|
35
|
+
}, [observe]);
|
|
36
|
+
const context = useMemo(() => ({ id, open, registerContent, ...labelling }), [id, open, registerContent, labelling]);
|
|
37
|
+
return _jsx(DialogContext.Provider, { value: context, children: children });
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=root.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"root.js","sourceRoot":"","sources":["../../src/dialog/root.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAkB,MAAM,OAAO,CAAA;AAC3E,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAc3E;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAC,EAAE,QAAQ,EAAE,WAAW,GAAG,KAAK,EAAE,YAAY,EAAmB;IACzF,MAAM,EAAE,GAAG,KAAK,EAAE,CAAA;IAElB,4EAA4E;IAC5E,6BAA6B;IAC7B,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC,CAAA;IACtC,SAAS,CAAC,OAAO,GAAG,YAAY,CAAA;IAEhC,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,IAAa,EAAE,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAA;IAC5E,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,YAAY,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;IAC3D,MAAM,SAAS,GAAG,kBAAkB,CAAC,EAAE,CAAC,CAAA;IAExC,MAAM,cAAc,GAAG,MAAM,CAAC,WAAW,CAAC,CAAA;IAC1C,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;IAE/B,MAAM,eAAe,GAAG,WAAW,CACjC,CAAC,IAAwB,EAAE,EAAE;QAC3B,OAAO,CAAC,IAAI,CAAC,CAAA;QACb,IAAI,CAAC,IAAI;YAAE,OAAM;QAEjB,oEAAoE;QACpE,iEAAiE;QACjE,oEAAoE;QACpE,IAAI,cAAc,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;YACjD,SAAS,CAAC,OAAO,GAAG,IAAI,CAAA;YACxB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC1B,CAAC;IACH,CAAC,EACD,CAAC,OAAO,CAAC,CACV,CAAA;IAED,MAAM,OAAO,GAAG,OAAO,CACrB,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,GAAG,SAAS,EAAE,CAAC,EACnD,CAAC,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,SAAS,CAAC,CACvC,CAAA;IAED,OAAO,KAAC,aAAa,CAAC,QAAQ,IAAC,KAAK,EAAE,OAAO,YAAG,QAAQ,GAA0B,CAAA;AACpF,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { OpenStateAdapter, RootContextValue } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Whether a `Title` and a `Description` are actually rendered.
|
|
4
|
+
*
|
|
5
|
+
* `aria-labelledby` pointing at an element that does not exist is a broken
|
|
6
|
+
* reference, not a harmless one — the dialog ends up with no accessible name
|
|
7
|
+
* and nothing says so. Deriving the id from the root's id is not enough; the
|
|
8
|
+
* parts have to say they are there.
|
|
9
|
+
*/
|
|
10
|
+
export interface DialogLabelling {
|
|
11
|
+
labelledBy: string | undefined;
|
|
12
|
+
describedBy: string | undefined;
|
|
13
|
+
registerTitle(): () => void;
|
|
14
|
+
registerDescription(): () => void;
|
|
15
|
+
}
|
|
16
|
+
export type DialogContextValue = RootContextValue & DialogLabelling;
|
|
17
|
+
export declare const DialogContext: import("react").Context<DialogContextValue | null>;
|
|
18
|
+
export declare function useDialogContext(part: string): DialogContextValue;
|
|
19
|
+
export declare function useDialogLabelling(id: string): DialogLabelling;
|
|
20
|
+
export declare const dialogAdapter: OpenStateAdapter;
|
|
21
|
+
/**
|
|
22
|
+
* Escape hatch for consumers who must attach a trigger to something that
|
|
23
|
+
* isn't a button — a third-party component they can't change, typically.
|
|
24
|
+
*
|
|
25
|
+
* Named, deliberate, and documented as your problem: the props are handed over
|
|
26
|
+
* without any of the accessibility guarantees that Dialog.Trigger enforces.
|
|
27
|
+
*/
|
|
28
|
+
export declare function useDialogTrigger(): {
|
|
29
|
+
readonly commandfor: string;
|
|
30
|
+
readonly command: "show-modal";
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/dialog/shared.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAElE;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IAC9B,WAAW,EAAE,MAAM,GAAG,SAAS,CAAA;IAC/B,aAAa,IAAI,MAAM,IAAI,CAAA;IAC3B,mBAAmB,IAAI,MAAM,IAAI,CAAA;CAClC;AAED,MAAM,MAAM,kBAAkB,GAAG,gBAAgB,GAAG,eAAe,CAAA;AAEnE,eAAO,MAAM,aAAa,oDAAiD,CAAA;AAE3E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,CAIjE;AAcD,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,CAa9D;AAED,eAAO,MAAM,aAAa,EAAE,gBAW3B,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB;;;EAK/B"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { createContext, useCallback, useContext, useMemo, useState } from 'react';
|
|
2
|
+
export const DialogContext = createContext(null);
|
|
3
|
+
export function useDialogContext(part) {
|
|
4
|
+
const context = useContext(DialogContext);
|
|
5
|
+
if (!context)
|
|
6
|
+
throw new Error(`[bedrock] ${part} must be used inside Dialog.Root.`);
|
|
7
|
+
return context;
|
|
8
|
+
}
|
|
9
|
+
/** Counted rather than boolean: two Titles is a bug, but it is the consumer's. */
|
|
10
|
+
function useCount() {
|
|
11
|
+
const [count, setCount] = useState(0);
|
|
12
|
+
const register = useCallback(() => {
|
|
13
|
+
setCount((n) => n + 1);
|
|
14
|
+
return () => setCount((n) => n - 1);
|
|
15
|
+
}, []);
|
|
16
|
+
return [count > 0, register];
|
|
17
|
+
}
|
|
18
|
+
export function useDialogLabelling(id) {
|
|
19
|
+
const [hasTitle, registerTitle] = useCount();
|
|
20
|
+
const [hasDescription, registerDescription] = useCount();
|
|
21
|
+
return useMemo(() => ({
|
|
22
|
+
labelledBy: hasTitle ? `${id}-title` : undefined,
|
|
23
|
+
describedBy: hasDescription ? `${id}-description` : undefined,
|
|
24
|
+
registerTitle,
|
|
25
|
+
registerDescription,
|
|
26
|
+
}), [id, hasTitle, hasDescription, registerTitle, registerDescription]);
|
|
27
|
+
}
|
|
28
|
+
export const dialogAdapter = {
|
|
29
|
+
isOpen: (node) => node.open,
|
|
30
|
+
open: (node) => node.showModal(),
|
|
31
|
+
// close(), not requestClose(), and only here. This runs when React has
|
|
32
|
+
// already decided — the user's close was offered to `cancel` and either
|
|
33
|
+
// refused or accepted, so asking a second time is both wrong and impossible:
|
|
34
|
+
// a close watcher ignores requestClose() re-entered from its own cancel
|
|
35
|
+
// action, and drops the call without an error. Dialog.Close still uses
|
|
36
|
+
// command="request-close", which is what keeps the veto vetoable.
|
|
37
|
+
close: (node) => node.close(),
|
|
38
|
+
closeVetoEvent: 'cancel',
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Escape hatch for consumers who must attach a trigger to something that
|
|
42
|
+
* isn't a button — a third-party component they can't change, typically.
|
|
43
|
+
*
|
|
44
|
+
* Named, deliberate, and documented as your problem: the props are handed over
|
|
45
|
+
* without any of the accessibility guarantees that Dialog.Trigger enforces.
|
|
46
|
+
*/
|
|
47
|
+
export function useDialogTrigger() {
|
|
48
|
+
const { id } = useDialogContext('useDialogTrigger');
|
|
49
|
+
// Lowercase: react-dom 19.2 doesn't recognise a camelCased `commandFor` and
|
|
50
|
+
// warns the consumer about a prop they never wrote.
|
|
51
|
+
return { commandfor: id, command: 'show-modal' };
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/dialog/shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAoBjF,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAA4B,IAAI,CAAC,CAAA;AAE3E,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,MAAM,OAAO,GAAG,UAAU,CAAC,aAAa,CAAC,CAAA;IACzC,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,aAAa,IAAI,mCAAmC,CAAC,CAAA;IACnF,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,kFAAkF;AAClF,SAAS,QAAQ;IACf,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;IAErC,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE;QAChC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;QACtB,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;IACrC,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,OAAO,CAAC,KAAK,GAAG,CAAC,EAAE,QAAQ,CAAU,CAAA;AACvC,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,EAAU;IAC3C,MAAM,CAAC,QAAQ,EAAE,aAAa,CAAC,GAAG,QAAQ,EAAE,CAAA;IAC5C,MAAM,CAAC,cAAc,EAAE,mBAAmB,CAAC,GAAG,QAAQ,EAAE,CAAA;IAExD,OAAO,OAAO,CACZ,GAAG,EAAE,CAAC,CAAC;QACL,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS;QAChD,WAAW,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC,SAAS;QAC7D,aAAa;QACb,mBAAmB;KACpB,CAAC,EACF,CAAC,EAAE,EAAE,QAAQ,EAAE,cAAc,EAAE,aAAa,EAAE,mBAAmB,CAAC,CACnE,CAAA;AACH,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAqB;IAC7C,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAE,IAA0B,CAAC,IAAI;IAClD,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAE,IAA0B,CAAC,SAAS,EAAE;IACvD,uEAAuE;IACvE,wEAAwE;IACxE,6EAA6E;IAC7E,wEAAwE;IACxE,uEAAuE;IACvE,kEAAkE;IAClE,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAE,IAA0B,CAAC,KAAK,EAAE;IACpD,cAAc,EAAE,QAAQ;CACzB,CAAA;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,EAAE,EAAE,EAAE,GAAG,gBAAgB,CAAC,kBAAkB,CAAC,CAAA;IACnD,4EAA4E;IAC5E,oDAAoD;IACpD,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,OAAO,EAAE,YAAY,EAAW,CAAA;AAC3D,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type ControlledRootProps } from '../create-controlled-root.js';
|
|
3
|
+
export interface ControlledDropdownMenuRootProps extends ControlledRootProps {
|
|
4
|
+
children?: ReactNode;
|
|
5
|
+
}
|
|
6
|
+
export declare function DropdownMenuRoot({ children, ...props }: ControlledDropdownMenuRootProps): import("react").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=controlled-root.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controlled-root.d.ts","sourceRoot":"","sources":["../../src/dropdown-menu/controlled-root.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAE/C,OAAO,EAAqB,KAAK,mBAAmB,EAAE,MAAM,2BAA2B,CAAA;AAIvF,MAAM,WAAW,+BAAgC,SAAQ,mBAAmB;IAC1E,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB;AAED,wBAAgB,gBAAgB,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,+BAA+B,+BAMvF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
import { anchorName } from '../anchor.js';
|
|
4
|
+
import { useControlledRoot } from '../create-controlled-root.js';
|
|
5
|
+
import { MenuContext } from '../menu/shared.js';
|
|
6
|
+
import { popoverAdapter } from '../popover/shared.js';
|
|
7
|
+
export function DropdownMenuRoot({ children, ...props }) {
|
|
8
|
+
const context = useControlledRoot(props, popoverAdapter);
|
|
9
|
+
const anchor = useMemo(() => anchorName(context.id), [context.id]);
|
|
10
|
+
const value = useMemo(() => ({ ...context, anchor }), [context, anchor]);
|
|
11
|
+
return _jsx(MenuContext.Provider, { value: value, children: children });
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=controlled-root.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controlled-root.js","sourceRoot":"","sources":["../../src/dropdown-menu/controlled-root.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAkB,MAAM,OAAO,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AACtC,OAAO,EAAE,iBAAiB,EAA4B,MAAM,2BAA2B,CAAA;AACvF,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAMlD,MAAM,UAAU,gBAAgB,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAmC;IACtF,MAAM,OAAO,GAAG,iBAAiB,CAAC,KAAK,EAAE,cAAc,CAAC,CAAA;IACxD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAA;IAClE,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAA;IAExE,OAAO,KAAC,WAAW,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YAAG,QAAQ,GAAwB,CAAA;AAC9E,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
export interface DropdownMenuRootProps {
|
|
3
|
+
children?: ReactNode;
|
|
4
|
+
onOpenChange?(open: boolean): void;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* The same shape as Popover.Root, because a dropdown menu *is* a popover with a
|
|
8
|
+
* roving list inside it. What it does not share is the bundle saving: the
|
|
9
|
+
* roving module ships either way, so `/controlled` costs almost nothing extra
|
|
10
|
+
* here and the docs do not pretend otherwise.
|
|
11
|
+
*/
|
|
12
|
+
export declare function DropdownMenuRoot({ children, onOpenChange }: DropdownMenuRootProps): import("react").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=root.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"root.d.ts","sourceRoot":"","sources":["../../src/dropdown-menu/root.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAuC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAK3E,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,YAAY,CAAC,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAA;CACnC;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,qBAAqB,+BAgBjF"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useId, useMemo, useRef } from 'react';
|
|
3
|
+
import { anchorName } from '../anchor.js';
|
|
4
|
+
import { MenuContext } from '../menu/shared.js';
|
|
5
|
+
import { useOpenState } from '../open-state.js';
|
|
6
|
+
/**
|
|
7
|
+
* The same shape as Popover.Root, because a dropdown menu *is* a popover with a
|
|
8
|
+
* roving list inside it. What it does not share is the bundle saving: the
|
|
9
|
+
* roving module ships either way, so `/controlled` costs almost nothing extra
|
|
10
|
+
* here and the docs do not pretend otherwise.
|
|
11
|
+
*/
|
|
12
|
+
export function DropdownMenuRoot({ children, onOpenChange }) {
|
|
13
|
+
const id = useId();
|
|
14
|
+
const anchor = useMemo(() => anchorName(id), [id]);
|
|
15
|
+
const changeRef = useRef(onOpenChange);
|
|
16
|
+
changeRef.current = onOpenChange;
|
|
17
|
+
const report = useCallback((next) => changeRef.current?.(next), []);
|
|
18
|
+
const { open, observe } = useOpenState(report);
|
|
19
|
+
const context = useMemo(() => ({ id, open, anchor, registerContent: observe }), [id, open, anchor, observe]);
|
|
20
|
+
return _jsx(MenuContext.Provider, { value: context, children: children });
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=root.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"root.js","sourceRoot":"","sources":["../../src/dropdown-menu/root.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAkB,MAAM,OAAO,CAAA;AAC3E,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAO5C;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAyB;IAChF,MAAM,EAAE,GAAG,KAAK,EAAE,CAAA;IAClB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IAElD,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC,CAAA;IACtC,SAAS,CAAC,OAAO,GAAG,YAAY,CAAA;IAEhC,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,IAAa,EAAE,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAA;IAC5E,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,YAAY,CAAC,MAAM,CAAC,CAAA;IAE9C,MAAM,OAAO,GAAG,OAAO,CACrB,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,CAAC,EACtD,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,CAC5B,CAAA;IAED,OAAO,KAAC,WAAW,CAAC,QAAQ,IAAC,KAAK,EAAE,OAAO,YAAG,QAAQ,GAAwB,CAAA;AAChF,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { ControlledRootProps } from '../create-controlled-root.js';
|
|
3
|
+
export interface ControlledHoverCardRootProps extends ControlledRootProps {
|
|
4
|
+
children?: ReactNode;
|
|
5
|
+
openDelay?: number;
|
|
6
|
+
closeDelay?: number;
|
|
7
|
+
}
|
|
8
|
+
export declare function HoverCardRoot({ children, openDelay, closeDelay, ...props }: ControlledHoverCardRootProps): import("react").JSX.Element;
|
|
9
|
+
//# sourceMappingURL=controlled-root.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controlled-root.d.ts","sourceRoot":"","sources":["../../src/hover-card/controlled-root.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAA;AAIpE,MAAM,WAAW,4BAA6B,SAAQ,mBAAmB;IACvE,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,SAAe,EACf,UAAgB,EAChB,GAAG,KAAK,EACT,EAAE,4BAA4B,+BAW9B"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { TooltipContext } from '../tooltip/shared.js';
|
|
3
|
+
import { useControlledInterestRoot } from '../tooltip/use-controlled-interest-root.js';
|
|
4
|
+
export function HoverCardRoot({ children, openDelay = 700, closeDelay = 300, ...props }) {
|
|
5
|
+
const context = useControlledInterestRoot({
|
|
6
|
+
...props,
|
|
7
|
+
showDelay: openDelay,
|
|
8
|
+
hideDelay: closeDelay,
|
|
9
|
+
hoverableContent: true,
|
|
10
|
+
kind: 'auto',
|
|
11
|
+
role: undefined,
|
|
12
|
+
});
|
|
13
|
+
return _jsx(TooltipContext.Provider, { value: context, children: children });
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=controlled-root.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controlled-root.js","sourceRoot":"","sources":["../../src/hover-card/controlled-root.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAClD,OAAO,EAAE,yBAAyB,EAAE,MAAM,yCAAyC,CAAA;AAQnF,MAAM,UAAU,aAAa,CAAC,EAC5B,QAAQ,EACR,SAAS,GAAG,GAAG,EACf,UAAU,GAAG,GAAG,EAChB,GAAG,KAAK,EACqB;IAC7B,MAAM,OAAO,GAAG,yBAAyB,CAAC;QACxC,GAAG,KAAK;QACR,SAAS,EAAE,SAAS;QACpB,SAAS,EAAE,UAAU;QACrB,gBAAgB,EAAE,IAAI;QACtB,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,SAAS;KAChB,CAAC,CAAA;IAEF,OAAO,KAAC,cAAc,CAAC,QAAQ,IAAC,KAAK,EAAE,OAAO,YAAG,QAAQ,GAA2B,CAAA;AACtF,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
export interface HoverCardRootProps {
|
|
3
|
+
children?: ReactNode;
|
|
4
|
+
openDelay?: number;
|
|
5
|
+
closeDelay?: number;
|
|
6
|
+
onOpenChange?(open: boolean): void;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* A Tooltip whose content you can put the pointer into, and which is a region
|
|
10
|
+
* rather than a label. Same machinery, three different arguments.
|
|
11
|
+
*/
|
|
12
|
+
export declare function HoverCardRoot({ children, openDelay, closeDelay, onOpenChange, }: HoverCardRootProps): import("react").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=root.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"root.d.ts","sourceRoot":"","sources":["../../src/hover-card/root.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAItC,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAA;CACnC;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,SAAe,EACf,UAAgB,EAChB,YAAY,GACb,EAAE,kBAAkB,+BAWpB"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { TooltipContext } from '../tooltip/shared.js';
|
|
3
|
+
import { useInterestRoot } from '../tooltip/use-interest-root.js';
|
|
4
|
+
/**
|
|
5
|
+
* A Tooltip whose content you can put the pointer into, and which is a region
|
|
6
|
+
* rather than a label. Same machinery, three different arguments.
|
|
7
|
+
*/
|
|
8
|
+
export function HoverCardRoot({ children, openDelay = 700, closeDelay = 300, onOpenChange, }) {
|
|
9
|
+
const context = useInterestRoot({
|
|
10
|
+
showDelay: openDelay,
|
|
11
|
+
hideDelay: closeDelay,
|
|
12
|
+
hoverableContent: true,
|
|
13
|
+
kind: 'auto',
|
|
14
|
+
role: undefined,
|
|
15
|
+
onOpenChange,
|
|
16
|
+
});
|
|
17
|
+
return _jsx(TooltipContext.Provider, { value: context, children: children });
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=root.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"root.js","sourceRoot":"","sources":["../../src/hover-card/root.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAA;AAS9D;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,EAC5B,QAAQ,EACR,SAAS,GAAG,GAAG,EACf,UAAU,GAAG,GAAG,EAChB,YAAY,GACO;IACnB,MAAM,OAAO,GAAG,eAAe,CAAC;QAC9B,SAAS,EAAE,SAAS;QACpB,SAAS,EAAE,UAAU;QACrB,gBAAgB,EAAE,IAAI;QACtB,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,SAAS;QACf,YAAY;KACb,CAAC,CAAA;IAEF,OAAO,KAAC,cAAc,CAAC,QAAQ,IAAC,KAAK,EAAE,OAAO,YAAG,QAAQ,GAA2B,CAAA;AACtF,CAAC"}
|