@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
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Sam Apostel
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# bedrock
|
|
2
|
+
|
|
3
|
+
Headless React primitives built on the browser instead of on top of it.
|
|
4
|
+
|
|
5
|
+
Radix-shaped anatomy — compound components, `asChild`, the same part names you
|
|
6
|
+
already type. Different foundation: the top layer, invoker commands, anchor
|
|
7
|
+
positioning, and `@starting-style` do the work that `Portal`, `Presence`,
|
|
8
|
+
`DismissableLayer`, and Floating UI used to do.
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm i @apostel/bedrock
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Docs, and a compat table that tests the browser you open it in:
|
|
15
|
+
**<https://bedrock.sams.land>**
|
|
16
|
+
|
|
17
|
+
## The shape
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
import { Dialog } from '@apostel/bedrock'
|
|
21
|
+
|
|
22
|
+
<Dialog.Root>
|
|
23
|
+
<Dialog.Trigger>Delete project</Dialog.Trigger>
|
|
24
|
+
<Dialog.Content>
|
|
25
|
+
<Dialog.Title>Delete project?</Dialog.Title>
|
|
26
|
+
<Dialog.Description>This cannot be undone.</Dialog.Description>
|
|
27
|
+
<Dialog.Close>Cancel</Dialog.Close>
|
|
28
|
+
<button onClick={destroy}>Delete</button>
|
|
29
|
+
</Dialog.Content>
|
|
30
|
+
</Dialog.Root>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
That renders roughly:
|
|
34
|
+
|
|
35
|
+
```html
|
|
36
|
+
<button commandfor="d1" command="show-modal">Delete project</button>
|
|
37
|
+
<dialog id="d1">…</dialog>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
No effect opens it. No state hook holds it. No portal moves it. The button is
|
|
41
|
+
wired to the dialog by the parser, so it works before hydration and keeps
|
|
42
|
+
working if your JS bundle fails to load.
|
|
43
|
+
|
|
44
|
+
## Two roots
|
|
45
|
+
|
|
46
|
+
The DOM owns open state. Most of the time that's all you need, so that's the
|
|
47
|
+
default — and it costs nothing.
|
|
48
|
+
|
|
49
|
+
**`Dialog.Root`** — the DOM opens and closes itself. Accepts `defaultOpen` and a
|
|
50
|
+
read-only `onOpenChange`, which is a `toggle` listener and nothing more. This
|
|
51
|
+
covers the common case that gets miscategorised as "controlled": *I need to know
|
|
52
|
+
when it closed so I can reset the form.*
|
|
53
|
+
|
|
54
|
+
**`Dialog.Root` from `@apostel/bedrock/controlled`** — React gets a veto. Your
|
|
55
|
+
`open` prop decides whether an open is allowed to proceed.
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
import { Dialog } from '@apostel/bedrock/controlled'
|
|
59
|
+
|
|
60
|
+
<Dialog.Root open={open} onOpenChange={setOpen}>
|
|
61
|
+
{/* identical children */}
|
|
62
|
+
</Dialog.Root>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Same component names, same parts, same props on every part. Swapping is a
|
|
66
|
+
one-line import change, and a codemod if you're doing it across a repo.
|
|
67
|
+
|
|
68
|
+
The two entry points are separate module graphs, so if nothing in your app
|
|
69
|
+
imports `/controlled`, none of the reconciliation code reaches your bundle. This
|
|
70
|
+
is a real guarantee from the `exports` map, not a tree-shaking hope.
|
|
71
|
+
|
|
72
|
+
### How the veto works
|
|
73
|
+
|
|
74
|
+
Controlled mode is **DOM leads, React vetoes**, not React-owns-state:
|
|
75
|
+
|
|
76
|
+
1. User clicks. The browser fires `beforetoggle`, which is cancelable for
|
|
77
|
+
popovers. If your `open` prop disagrees, we `preventDefault()` and nothing
|
|
78
|
+
moved.
|
|
79
|
+
2. `onOpenChange` fires either way, so you can decide.
|
|
80
|
+
3. If your prop changes without user interaction, a reconciliation effect moves
|
|
81
|
+
the DOM to match.
|
|
82
|
+
|
|
83
|
+
Where the platform gives no cancelable hook, step 1 is skipped and step 3 puts
|
|
84
|
+
things back — one frame of visible movement in the refuse case only. Modal
|
|
85
|
+
dialogs get an extra veto on close via `request-close` and the `cancel` event.
|
|
86
|
+
|
|
87
|
+
## `asChild` and the button rule
|
|
88
|
+
|
|
89
|
+
Invoker commands work on `<button>` only. Interest invokers also work on `<a>`.
|
|
90
|
+
So this is fine:
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
<Tooltip.Trigger asChild><a href="/pricing">Pricing</a></Tooltip.Trigger>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
and this is not:
|
|
97
|
+
|
|
98
|
+
```tsx
|
|
99
|
+
<Dialog.Trigger asChild><div onClick={…}>Open</div></Dialog.Trigger>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
A trigger that isn't a button gets no `commandfor` wiring, which means no
|
|
103
|
+
keyboard activation and no implicit `aria-expanded`. That's an accessibility
|
|
104
|
+
regression, and it's silent, so we make noise about it: **development throws**
|
|
105
|
+
at mount, with the tag it found and the tags that part accepts. Production logs
|
|
106
|
+
an error at the same check point.
|
|
107
|
+
|
|
108
|
+
There is no fallback click handler. Attaching one would ship the exact
|
|
109
|
+
imperative trigger machinery this library exists to delete, to every consumer,
|
|
110
|
+
forever — and nobody removes a fallback that works.
|
|
111
|
+
|
|
112
|
+
If you're wrapping a third-party component that renders a div and can't change
|
|
113
|
+
it, take the props and own the consequences:
|
|
114
|
+
|
|
115
|
+
```tsx
|
|
116
|
+
const props = useDialogTrigger(id)
|
|
117
|
+
<ThirdPartyThing {...props} />
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
The same check catches `<button>` inside a `<form>` without `type="button"`.
|
|
121
|
+
Submit buttons can't invoke popovers — submitting and opening are conflicting
|
|
122
|
+
behaviours — and that one bites people more often than the div case.
|
|
123
|
+
|
|
124
|
+
## What's native and what still ships JS
|
|
125
|
+
|
|
126
|
+
Be clear-eyed about this. The platform deleted positioning and layering. It did
|
|
127
|
+
not delete focus management.
|
|
128
|
+
|
|
129
|
+
**Almost entirely native** — AspectRatio, Separator, Label, VisuallyHidden,
|
|
130
|
+
Progress, Slider, ScrollArea, Collapsible, Accordion, Checkbox, Switch,
|
|
131
|
+
RadioGroup, Select, Dialog, AlertDialog, Popover.
|
|
132
|
+
|
|
133
|
+
Several of those are one element and no state at all: `Progress` is
|
|
134
|
+
`<progress>`, `Slider` is `<input type="range">`, `Select` is a `<select>` under
|
|
135
|
+
`appearance: base-select`, and `Accordion` gets single-open exclusivity from
|
|
136
|
+
`<details name>` rather than from an effect that closes its siblings.
|
|
137
|
+
|
|
138
|
+
**Native layering, small JS state layer** — Tooltip, HoverCard, Avatar, Toggle,
|
|
139
|
+
Toast.
|
|
140
|
+
|
|
141
|
+
**Still substantially JS** — DropdownMenu, ContextMenu, Menubar,
|
|
142
|
+
NavigationMenu, Tabs, Toolbar, ToggleGroup.
|
|
143
|
+
|
|
144
|
+
The reason is short: there is no native roving tabindex, no native typeahead, no
|
|
145
|
+
focus trap for non-modal layers, and no way to anchor to a pointer coordinate.
|
|
146
|
+
Every menu-shaped primitive needs all four, and they all share one `roving.ts` —
|
|
147
|
+
which ships from either entry point, so the two-root split saves them almost
|
|
148
|
+
nothing. The docs say that rather than implying otherwise.
|
|
149
|
+
|
|
150
|
+
Measured, not estimated — esbuild, minified, gzipped, React external:
|
|
151
|
+
|
|
152
|
+
| primitive | bedrock | Radix | |
|
|
153
|
+
| --- | --- | --- | --- |
|
|
154
|
+
| Checkbox | **0.70 kB** | 5.9 kB | 8.5× |
|
|
155
|
+
| Slider | **0.74 kB** | 9.8 kB | 13× |
|
|
156
|
+
| Select | **0.84 kB** | 31.5 kB | 37× |
|
|
157
|
+
| Accordion | **1.61 kB** | 8.8 kB | 5.5× |
|
|
158
|
+
| Dialog | **1.95 kB** | 13.7 kB | 7× |
|
|
159
|
+
| Popover | **2.11 kB** | 24.2 kB | 11× |
|
|
160
|
+
| Tooltip | **2.55 kB** | 19.3 kB | 7.6× |
|
|
161
|
+
| DropdownMenu | **3.55 kB** | 31.6 kB | 8.9× |
|
|
162
|
+
|
|
163
|
+
The ratio narrows as the roving module gets involved and widens where the
|
|
164
|
+
platform has a whole element to hand over. The bigger win is behavioural — no
|
|
165
|
+
z-index fights, no portal-and-clipping bugs, no positioning recalculation on
|
|
166
|
+
every scroll frame.
|
|
167
|
+
|
|
168
|
+
## Browser support
|
|
169
|
+
|
|
170
|
+
Latest Chrome, deliberately, for now.
|
|
171
|
+
|
|
172
|
+
`appearance: base-select`, `interpolate-size`, `::scroll-marker`, and
|
|
173
|
+
`popover=hint` are shipped or shipping across engines, so that bet is about
|
|
174
|
+
timing. `interestfor` is the one that isn't standardised yet, and it's what
|
|
175
|
+
drives Tooltip and HoverCard triggers.
|
|
176
|
+
|
|
177
|
+
Because of that, **no platform feature appears in a public prop name.**
|
|
178
|
+
`Tooltip.Root` takes `delayDuration`; today it becomes `interest-show-delay`,
|
|
179
|
+
tomorrow it might become a timer. Feature detection lives in one module, every
|
|
180
|
+
non-Baseline CSS block sits behind `@supports`, and the implementation can be
|
|
181
|
+
swapped without a major version.
|
|
182
|
+
|
|
183
|
+
## Styling
|
|
184
|
+
|
|
185
|
+
Ship `bedrock.css` or don't — every part takes `className` and renders one
|
|
186
|
+
element. Open and closed states are selectable with `:open` and
|
|
187
|
+
`:popover-open`; enter and exit animation is `@starting-style` plus
|
|
188
|
+
`transition-behavior: allow-discrete`, no `forceMount`, no presence wrapper.
|
|
189
|
+
|
|
190
|
+
## Docs
|
|
191
|
+
|
|
192
|
+
[`docs/`](./docs/README.md) — getting started, the Dialog API, styling, the
|
|
193
|
+
[migration guide](./docs/migration-from-radix.md), and a
|
|
194
|
+
[shadcn registry](./docs/shadcn-registry.md) that swaps Radix for bedrock in
|
|
195
|
+
shadcn's own components.
|
|
196
|
+
|
|
197
|
+
[`docs/compat.html`](./docs/compat.html) — live at
|
|
198
|
+
<https://bedrock.sams.land/compat.html> — tests every platform feature bedrock
|
|
199
|
+
uses in whatever browser you open it in, and says what each missing one does to
|
|
200
|
+
your UI. Chrome 141 scores 20 of 21.
|
|
201
|
+
|
|
202
|
+
Migrating with an agent: [`skills/migrate-to-bedrock`](./skills/migrate-to-bedrock/SKILL.md),
|
|
203
|
+
a Claude Code skill that does the mechanical work and brings you the four
|
|
204
|
+
decisions it cannot make for you.
|
|
205
|
+
|
|
206
|
+
Contributing is [`CONTRIBUTING.md`](./CONTRIBUTING.md); releasing is
|
|
207
|
+
[`RELEASING.md`](./RELEASING.md).
|
|
208
|
+
|
|
209
|
+
[`docs/gaps.md`](./docs/gaps.md) is the case against adopting this. Read it
|
|
210
|
+
first if you are evaluating.
|
|
211
|
+
|
|
212
|
+
## Status
|
|
213
|
+
|
|
214
|
+
Pre-alpha, but no longer a list: all 29 primitives exist, with 97 Playwright
|
|
215
|
+
tests against real Chrome. What is missing is soak time, other engines, and the
|
|
216
|
+
things named in [gaps](./docs/gaps.md) — not components.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type ReactElement } from 'react';
|
|
2
|
+
export interface AccessibleIconProps {
|
|
3
|
+
/** What a screen reader should announce in place of the glyph. */
|
|
4
|
+
label: string;
|
|
5
|
+
children: ReactElement;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Radix hides the icon and appends a visually hidden `<span>` carrying the
|
|
9
|
+
* label. Two elements, one of them off-screen text that has to be styled.
|
|
10
|
+
*
|
|
11
|
+
* `role="img"` plus `aria-label` says the same thing to assistive technology in
|
|
12
|
+
* one element and no CSS — an image with an accessible name, which is what an
|
|
13
|
+
* icon is.
|
|
14
|
+
*/
|
|
15
|
+
export declare function AccessibleIconRoot({ label, children }: AccessibleIconProps): ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
16
|
+
//# sourceMappingURL=parts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parts.d.ts","sourceRoot":"","sources":["../../src/accessible-icon/parts.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgC,KAAK,YAAY,EAAE,MAAM,OAAO,CAAA;AAGvE,MAAM,WAAW,mBAAmB;IAClC,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,YAAY,CAAA;CACvB;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,mBAAmB,8EAe1E"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { cloneElement, isValidElement } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Radix hides the icon and appends a visually hidden `<span>` carrying the
|
|
4
|
+
* label. Two elements, one of them off-screen text that has to be styled.
|
|
5
|
+
*
|
|
6
|
+
* `role="img"` plus `aria-label` says the same thing to assistive technology in
|
|
7
|
+
* one element and no CSS — an image with an accessible name, which is what an
|
|
8
|
+
* icon is.
|
|
9
|
+
*/
|
|
10
|
+
export function AccessibleIconRoot({ label, children }) {
|
|
11
|
+
if (!isValidElement(children)) {
|
|
12
|
+
throw new Error('[bedrock] AccessibleIcon expects exactly one React element child.');
|
|
13
|
+
}
|
|
14
|
+
const props = children.props;
|
|
15
|
+
return cloneElement(children, {
|
|
16
|
+
...props,
|
|
17
|
+
role: 'img',
|
|
18
|
+
'aria-label': label,
|
|
19
|
+
'aria-hidden': undefined,
|
|
20
|
+
focusable: false,
|
|
21
|
+
'data-bedrock-accessible-icon': '',
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=parts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parts.js","sourceRoot":"","sources":["../../src/accessible-icon/parts.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAqB,MAAM,OAAO,CAAA;AASvE;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAuB;IACzE,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAA;IACtF,CAAC;IAED,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAiB,CAAA;IAExC,OAAO,YAAY,CAAC,QAAQ,EAAE;QAC5B,GAAG,KAAK;QACR,IAAI,EAAE,KAAK;QACX,YAAY,EAAE,KAAK;QACnB,aAAa,EAAE,SAAS;QACxB,SAAS,EAAE,KAAK;QAChB,8BAA8B,EAAE,EAAE;KACvB,CAAC,CAAA;AAChB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type ComponentPropsWithRef } from 'react';
|
|
2
|
+
import type { AsChildProps } from '../types.js';
|
|
3
|
+
export interface ControlledAccordionRootProps extends Omit<ComponentPropsWithRef<'div'>, 'defaultValue'>, AsChildProps {
|
|
4
|
+
type?: 'single' | 'multiple';
|
|
5
|
+
value: string | string[];
|
|
6
|
+
orientation?: 'horizontal' | 'vertical';
|
|
7
|
+
onValueChange?: ((value: string[]) => void) | undefined;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Reconciles by walking its own subtree rather than by telling each item what
|
|
11
|
+
* to do, which is what keeps `Accordion.Item` byte-identical under both roots.
|
|
12
|
+
* Items publish their value as a data attribute; nothing about that costs the
|
|
13
|
+
* plain root anything.
|
|
14
|
+
*
|
|
15
|
+
* `<details>` has no cancelable toggle, so this cannot refuse before the fact:
|
|
16
|
+
* the disclosure moves, you are told, and it moves back if you decline.
|
|
17
|
+
*/
|
|
18
|
+
export declare function AccordionRoot({ asChild, children, type, value, orientation, onValueChange, ref, ...props }: ControlledAccordionRootProps): import("react").JSX.Element;
|
|
19
|
+
//# sourceMappingURL=controlled-root.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controlled-root.d.ts","sourceRoot":"","sources":["../../src/accordion/controlled-root.tsx"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,qBAAqB,EAE3B,MAAM,OAAO,CAAA;AAGd,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAG5C,MAAM,WAAW,4BACf,SAAQ,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC,EAAE,YAAY;IACxE,IAAI,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAA;IAC5B,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACxB,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAA;IACvC,aAAa,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;CACxD;AAMD;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,QAAQ,EACR,IAAe,EACf,KAAK,EACL,WAAwB,EACxB,aAAa,EACb,GAAG,EACH,GAAG,KAAK,EACT,EAAE,4BAA4B,+BAuD9B"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useId, useMemo, useRef, } from 'react';
|
|
3
|
+
import { useComposedRefs } from '../compose-refs.js';
|
|
4
|
+
import { Slot } from '../slot.js';
|
|
5
|
+
import { AccordionContext } from './shared.js';
|
|
6
|
+
function toArray(value) {
|
|
7
|
+
return Array.isArray(value) ? value : [value];
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Reconciles by walking its own subtree rather than by telling each item what
|
|
11
|
+
* to do, which is what keeps `Accordion.Item` byte-identical under both roots.
|
|
12
|
+
* Items publish their value as a data attribute; nothing about that costs the
|
|
13
|
+
* plain root anything.
|
|
14
|
+
*
|
|
15
|
+
* `<details>` has no cancelable toggle, so this cannot refuse before the fact:
|
|
16
|
+
* the disclosure moves, you are told, and it moves back if you decline.
|
|
17
|
+
*/
|
|
18
|
+
export function AccordionRoot({ asChild, children, type = 'single', value, orientation = 'vertical', onValueChange, ref, ...props }) {
|
|
19
|
+
const name = useId();
|
|
20
|
+
const Part = asChild ? Slot : 'div';
|
|
21
|
+
const nodeRef = useRef(null);
|
|
22
|
+
const changeRef = useRef(onValueChange);
|
|
23
|
+
changeRef.current = onValueChange;
|
|
24
|
+
const values = useMemo(() => toArray(value), [value]);
|
|
25
|
+
const report = useCallback((changed, open) => {
|
|
26
|
+
const next = open
|
|
27
|
+
? [...new Set([...values, changed])]
|
|
28
|
+
: values.filter((entry) => entry !== changed);
|
|
29
|
+
changeRef.current?.(next);
|
|
30
|
+
}, [values]);
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
const root = nodeRef.current;
|
|
33
|
+
if (!root)
|
|
34
|
+
return;
|
|
35
|
+
for (const item of root.querySelectorAll('[data-bedrock-accordion-item]')) {
|
|
36
|
+
const itemValue = item.dataset.value;
|
|
37
|
+
const shouldBeOpen = itemValue !== undefined && values.includes(itemValue);
|
|
38
|
+
if (item.open !== shouldBeOpen)
|
|
39
|
+
item.open = shouldBeOpen;
|
|
40
|
+
}
|
|
41
|
+
}, [values]);
|
|
42
|
+
const context = useMemo(() => ({
|
|
43
|
+
name: type === 'single' ? name : undefined,
|
|
44
|
+
orientation,
|
|
45
|
+
report,
|
|
46
|
+
value: values,
|
|
47
|
+
defaultValue: [],
|
|
48
|
+
}), [name, type, orientation, report, values]);
|
|
49
|
+
return (_jsx(AccordionContext.Provider, { value: context, children: _jsx(Part, { ...props, ref: useComposedRefs(ref, (node) => {
|
|
50
|
+
nodeRef.current = node;
|
|
51
|
+
}), "data-orientation": orientation, "data-bedrock-accordion": "", children: children }) }));
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=controlled-root.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controlled-root.js","sourceRoot":"","sources":["../../src/accordion/controlled-root.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type ComponentPropsWithRef } from 'react';
|
|
2
|
+
import type { AsChildProps } from '../types.js';
|
|
3
|
+
export interface AccordionItemProps extends Omit<ComponentPropsWithRef<'details'>, 'value'>, AsChildProps {
|
|
4
|
+
value: string;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* A `<details>`, sharing its `name` with its siblings when the root is
|
|
9
|
+
* `type="single"`. Exclusivity is the browser's, so it survives with no
|
|
10
|
+
* JavaScript and cannot get out of step with React state.
|
|
11
|
+
*/
|
|
12
|
+
export declare function AccordionItem({ asChild, children, value, disabled, ref, ...props }: AccordionItemProps): import("react").JSX.Element;
|
|
13
|
+
export interface AccordionHeaderProps extends ComponentPropsWithRef<'summary'>, AsChildProps {
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The `<summary>`. Radix renders `<h3><button aria-expanded>`; the platform's
|
|
17
|
+
* disclosure pattern is a summary, which carries the expanded state itself.
|
|
18
|
+
*
|
|
19
|
+
* If you need the heading semantics the APG asks for, put a heading *inside*
|
|
20
|
+
* this — `<Accordion.Header><h3>…</h3></Accordion.Header>` is valid and keeps
|
|
21
|
+
* the summary's behaviour.
|
|
22
|
+
*/
|
|
23
|
+
export declare function AccordionHeader({ asChild, ...props }: AccordionHeaderProps): import("react").JSX.Element;
|
|
24
|
+
export interface AccordionTriggerProps extends ComponentPropsWithRef<'span'>, AsChildProps {
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Sits inside the header and is not itself interactive — the summary already
|
|
28
|
+
* is, and nesting a button inside it would produce two tab stops for one
|
|
29
|
+
* control. It exists so Radix-shaped markup keeps its styling hook.
|
|
30
|
+
*/
|
|
31
|
+
export declare function AccordionTrigger({ asChild, ...props }: AccordionTriggerProps): import("react").JSX.Element;
|
|
32
|
+
export interface AccordionContentProps extends ComponentPropsWithRef<'div'>, AsChildProps {
|
|
33
|
+
}
|
|
34
|
+
export declare function AccordionContent({ asChild, children, ...props }: AccordionContentProps): import("react").JSX.Element;
|
|
35
|
+
//# sourceMappingURL=parts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parts.d.ts","sourceRoot":"","sources":["../../src/accordion/parts.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgC,KAAK,qBAAqB,EAAoB,MAAM,OAAO,CAAA;AAKlG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAG5C,MAAM,WAAW,kBACf,SAAQ,IAAI,CAAC,qBAAqB,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,EAAE,YAAY;IACrE,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,GAAG,EACH,GAAG,KAAK,EACT,EAAE,kBAAkB,+BAiCpB;AAED,MAAM,WAAW,oBAAqB,SAAQ,qBAAqB,CAAC,SAAS,CAAC,EAAE,YAAY;CAAG;AAE/F;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,EAAE,OAAO,EAAE,GAAG,KAAK,EAAE,EAAE,oBAAoB,+BAI1E;AAED,MAAM,WAAW,qBAAsB,SAAQ,qBAAqB,CAAC,MAAM,CAAC,EAAE,YAAY;CAAG;AAE7F;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,OAAO,EAAE,GAAG,KAAK,EAAE,EAAE,qBAAqB,+BAI5E;AAED,MAAM,WAAW,qBAAsB,SAAQ,qBAAqB,CAAC,KAAK,CAAC,EAAE,YAAY;CAAG;AAE5F,wBAAgB,gBAAgB,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,qBAAqB,+BAUtF"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useMemo, useRef } from 'react';
|
|
3
|
+
import { useClientRender } from '../client-render.js';
|
|
4
|
+
import { useComposedRefs } from '../compose-refs.js';
|
|
5
|
+
import { useOpenState } from '../open-state.js';
|
|
6
|
+
import { Slot } from '../slot.js';
|
|
7
|
+
import { AccordionItemContext, useAccordionContext, useAccordionItemContext } from './shared.js';
|
|
8
|
+
/**
|
|
9
|
+
* A `<details>`, sharing its `name` with its siblings when the root is
|
|
10
|
+
* `type="single"`. Exclusivity is the browser's, so it survives with no
|
|
11
|
+
* JavaScript and cannot get out of step with React state.
|
|
12
|
+
*/
|
|
13
|
+
export function AccordionItem({ asChild, children, value, disabled, ref, ...props }) {
|
|
14
|
+
const { name, report, value: controlled, defaultValue } = useAccordionContext('Accordion.Item');
|
|
15
|
+
const Part = asChild ? Slot : 'details';
|
|
16
|
+
const reportRef = useRef(report);
|
|
17
|
+
reportRef.current = report;
|
|
18
|
+
const onToggle = useCallback((next) => reportRef.current(value, next), [value]);
|
|
19
|
+
const startsOpen = (controlled ?? defaultValue).includes(value);
|
|
20
|
+
const { open, observe } = useOpenState(onToggle, startsOpen);
|
|
21
|
+
const startsOpenRef = useRef(startsOpen);
|
|
22
|
+
const item = useMemo(() => ({ value, open }), [value, open]);
|
|
23
|
+
return (_jsx(AccordionItemContext.Provider, { value: item, children: _jsx(Part, { ...props, name: name, open: startsOpenRef.current, "data-value": value, "data-disabled": disabled ? '' : undefined, ref: useComposedRefs(ref, observe), "data-bedrock-accordion-item": "", children: children }) }));
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The `<summary>`. Radix renders `<h3><button aria-expanded>`; the platform's
|
|
27
|
+
* disclosure pattern is a summary, which carries the expanded state itself.
|
|
28
|
+
*
|
|
29
|
+
* If you need the heading semantics the APG asks for, put a heading *inside*
|
|
30
|
+
* this — `<Accordion.Header><h3>…</h3></Accordion.Header>` is valid and keeps
|
|
31
|
+
* the summary's behaviour.
|
|
32
|
+
*/
|
|
33
|
+
export function AccordionHeader({ asChild, ...props }) {
|
|
34
|
+
const Part = asChild ? Slot : 'summary';
|
|
35
|
+
return _jsx(Part, { ...props, "data-bedrock-accordion-header": "" });
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Sits inside the header and is not itself interactive — the summary already
|
|
39
|
+
* is, and nesting a button inside it would produce two tab stops for one
|
|
40
|
+
* control. It exists so Radix-shaped markup keeps its styling hook.
|
|
41
|
+
*/
|
|
42
|
+
export function AccordionTrigger({ asChild, ...props }) {
|
|
43
|
+
const Part = asChild ? Slot : 'span';
|
|
44
|
+
return _jsx(Part, { ...props, "data-bedrock-accordion-trigger": "" });
|
|
45
|
+
}
|
|
46
|
+
export function AccordionContent({ asChild, children, ...props }) {
|
|
47
|
+
const { open } = useAccordionItemContext('Accordion.Content');
|
|
48
|
+
const onClient = useClientRender();
|
|
49
|
+
const Part = asChild ? Slot : 'div';
|
|
50
|
+
return (_jsx(Part, { ...props, "data-bedrock-accordion-content": "", children: open || !onClient ? children : null }));
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=parts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parts.js","sourceRoot":"","sources":["../../src/accordion/parts.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type ComponentPropsWithRef } from 'react';
|
|
2
|
+
import type { AsChildProps } from '../types.js';
|
|
3
|
+
export interface AccordionRootProps extends ComponentPropsWithRef<'div'>, AsChildProps {
|
|
4
|
+
/**
|
|
5
|
+
* `single` gives the items a shared name, which is what makes the browser
|
|
6
|
+
* close the others. `multiple` leaves them independent.
|
|
7
|
+
*/
|
|
8
|
+
type?: 'single' | 'multiple';
|
|
9
|
+
defaultValue?: string | string[];
|
|
10
|
+
orientation?: 'horizontal' | 'vertical';
|
|
11
|
+
/** Reports which items are open after a change. Cannot refuse. */
|
|
12
|
+
onValueChange?(value: string[]): void;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Renders a plain container. All the behaviour is in the items, and all of it
|
|
16
|
+
* is `<details name>` — no roving state, no open registry, no effect that
|
|
17
|
+
* closes siblings.
|
|
18
|
+
*
|
|
19
|
+
* `type="single"` therefore always allows closing the open item, because a
|
|
20
|
+
* `<summary>` toggles. Radix's `collapsible={false}` has no native equivalent
|
|
21
|
+
* and is not offered.
|
|
22
|
+
*/
|
|
23
|
+
export declare function AccordionRoot({ asChild, children, type, defaultValue, orientation, onValueChange, ...props }: AccordionRootProps): import("react").JSX.Element;
|
|
24
|
+
//# sourceMappingURL=root.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"root.d.ts","sourceRoot":"","sources":["../../src/accordion/root.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,qBAAqB,EAE3B,MAAM,OAAO,CAAA;AAEd,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAG5C,MAAM,WAAW,kBAAmB,SAAQ,qBAAqB,CAAC,KAAK,CAAC,EAAE,YAAY;IACpF;;;OAGG;IACH,IAAI,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAA;IAC5B,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAChC,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAA;IACvC,kEAAkE;IAClE,aAAa,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;CACtC;AAOD;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,QAAQ,EACR,IAAe,EACf,YAAY,EACZ,WAAwB,EACxB,aAAa,EACb,GAAG,KAAK,EACT,EAAE,kBAAkB,+BAwCpB"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useId, useMemo, useRef, } from 'react';
|
|
3
|
+
import { Slot } from '../slot.js';
|
|
4
|
+
import { AccordionContext } from './shared.js';
|
|
5
|
+
function toArray(value) {
|
|
6
|
+
if (value === undefined)
|
|
7
|
+
return [];
|
|
8
|
+
return Array.isArray(value) ? value : [value];
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Renders a plain container. All the behaviour is in the items, and all of it
|
|
12
|
+
* is `<details name>` — no roving state, no open registry, no effect that
|
|
13
|
+
* closes siblings.
|
|
14
|
+
*
|
|
15
|
+
* `type="single"` therefore always allows closing the open item, because a
|
|
16
|
+
* `<summary>` toggles. Radix's `collapsible={false}` has no native equivalent
|
|
17
|
+
* and is not offered.
|
|
18
|
+
*/
|
|
19
|
+
export function AccordionRoot({ asChild, children, type = 'single', defaultValue, orientation = 'vertical', onValueChange, ...props }) {
|
|
20
|
+
const name = useId();
|
|
21
|
+
const Part = asChild ? Slot : 'div';
|
|
22
|
+
const changeRef = useRef(onValueChange);
|
|
23
|
+
changeRef.current = onValueChange;
|
|
24
|
+
// Tracked in a ref rather than state: the DOM is the source of truth, and the
|
|
25
|
+
// root has nothing to re-render when an item opens. Read once, as the name of
|
|
26
|
+
// the prop says.
|
|
27
|
+
const initialValues = useRef(toArray(defaultValue));
|
|
28
|
+
const openValues = useRef(initialValues.current);
|
|
29
|
+
const report = useCallback((value, open) => {
|
|
30
|
+
const next = open
|
|
31
|
+
? [...new Set([...openValues.current, value])]
|
|
32
|
+
: openValues.current.filter((entry) => entry !== value);
|
|
33
|
+
openValues.current = next;
|
|
34
|
+
changeRef.current?.(next);
|
|
35
|
+
}, []);
|
|
36
|
+
const context = useMemo(() => ({
|
|
37
|
+
name: type === 'single' ? name : undefined,
|
|
38
|
+
orientation,
|
|
39
|
+
report,
|
|
40
|
+
value: undefined,
|
|
41
|
+
defaultValue: initialValues.current,
|
|
42
|
+
}), [name, type, orientation, report]);
|
|
43
|
+
return (_jsx(AccordionContext.Provider, { value: context, children: _jsx(Part, { ...props, "data-orientation": orientation, "data-bedrock-accordion": "", children: children }) }));
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=root.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"root.js","sourceRoot":"","sources":["../../src/accordion/root.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,WAAW,EACX,KAAK,EACL,OAAO,EACP,MAAM,GAGP,MAAM,OAAO,CAAA;AACd,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AAE9B,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAc3C,SAAS,OAAO,CAAC,KAAoC;IACnD,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,CAAA;IAClC,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;AAC/C,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAAC,EAC5B,OAAO,EACP,QAAQ,EACR,IAAI,GAAG,QAAQ,EACf,YAAY,EACZ,WAAW,GAAG,UAAU,EACxB,aAAa,EACb,GAAG,KAAK,EACW;IACnB,MAAM,IAAI,GAAG,KAAK,EAAE,CAAA;IACpB,MAAM,IAAI,GAAgB,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAA;IAEhD,MAAM,SAAS,GAAG,MAAM,CAAC,aAAa,CAAC,CAAA;IACvC,SAAS,CAAC,OAAO,GAAG,aAAa,CAAA;IAEjC,8EAA8E;IAC9E,8EAA8E;IAC9E,iBAAiB;IACjB,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAA;IACnD,MAAM,UAAU,GAAG,MAAM,CAAW,aAAa,CAAC,OAAO,CAAC,CAAA;IAE1D,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,KAAa,EAAE,IAAa,EAAE,EAAE;QAC1D,MAAM,IAAI,GAAG,IAAI;YACf,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;YAC9C,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC,CAAA;QAEzD,UAAU,CAAC,OAAO,GAAG,IAAI,CAAA;QACzB,SAAS,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAA;IAC3B,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,MAAM,OAAO,GAAG,OAAO,CACrB,GAAG,EAAE,CAAC,CAAC;QACL,IAAI,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;QAC1C,WAAW;QACX,MAAM;QACN,KAAK,EAAE,SAAS;QAChB,YAAY,EAAE,aAAa,CAAC,OAAO;KACpC,CAAC,EACF,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,CAAC,CAClC,CAAA;IAED,OAAO,CACL,KAAC,gBAAgB,CAAC,QAAQ,IAAC,KAAK,EAAE,OAAO,YACvC,KAAC,IAAI,OAAK,KAAK,sBAAoB,WAAW,4BAAyB,EAAE,YACtE,QAAQ,GACJ,GACmB,CAC7B,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface AccordionContextValue {
|
|
2
|
+
/**
|
|
3
|
+
* Shared `name` for the items. A group of `<details>` with the same name is
|
|
4
|
+
* mutually exclusive in the browser — that is the whole of `type="single"`,
|
|
5
|
+
* with no state and no JavaScript.
|
|
6
|
+
*/
|
|
7
|
+
name: string | undefined;
|
|
8
|
+
orientation: 'horizontal' | 'vertical';
|
|
9
|
+
/** Reported up from an item's `toggle`, for `onValueChange`. */
|
|
10
|
+
report(value: string, open: boolean): void;
|
|
11
|
+
/** Which values the root wants open, when it is the controlled root. */
|
|
12
|
+
value: readonly string[] | undefined;
|
|
13
|
+
defaultValue: readonly string[];
|
|
14
|
+
}
|
|
15
|
+
export declare const AccordionContext: import("react").Context<AccordionContextValue | null>;
|
|
16
|
+
export declare function useAccordionContext(part: string): AccordionContextValue;
|
|
17
|
+
export interface AccordionItemContextValue {
|
|
18
|
+
value: string;
|
|
19
|
+
open: boolean;
|
|
20
|
+
}
|
|
21
|
+
export declare const AccordionItemContext: import("react").Context<AccordionItemContextValue | null>;
|
|
22
|
+
export declare function useAccordionItemContext(part: string): AccordionItemContextValue;
|
|
23
|
+
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/accordion/shared.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,IAAI,EAAE,MAAM,GAAG,SAAS,CAAA;IACxB,WAAW,EAAE,YAAY,GAAG,UAAU,CAAA;IACtC,gEAAgE;IAChE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAAA;IAC1C,wEAAwE;IACxE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAA;IACpC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAA;CAChC;AAED,eAAO,MAAM,gBAAgB,uDAAoD,CAAA;AAEjF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,qBAAqB,CAIvE;AAED,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,OAAO,CAAA;CACd;AAED,eAAO,MAAM,oBAAoB,2DAAwD,CAAA;AAEzF,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,yBAAyB,CAI/E"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
export const AccordionContext = createContext(null);
|
|
3
|
+
export function useAccordionContext(part) {
|
|
4
|
+
const context = useContext(AccordionContext);
|
|
5
|
+
if (!context)
|
|
6
|
+
throw new Error(`[bedrock] ${part} must be used inside Accordion.Root.`);
|
|
7
|
+
return context;
|
|
8
|
+
}
|
|
9
|
+
export const AccordionItemContext = createContext(null);
|
|
10
|
+
export function useAccordionItemContext(part) {
|
|
11
|
+
const context = useContext(AccordionItemContext);
|
|
12
|
+
if (!context)
|
|
13
|
+
throw new Error(`[bedrock] ${part} must be used inside Accordion.Item.`);
|
|
14
|
+
return context;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/accordion/shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAiBjD,MAAM,CAAC,MAAM,gBAAgB,GAAG,aAAa,CAA+B,IAAI,CAAC,CAAA;AAEjF,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,MAAM,OAAO,GAAG,UAAU,CAAC,gBAAgB,CAAC,CAAA;IAC5C,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,aAAa,IAAI,sCAAsC,CAAC,CAAA;IACtF,OAAO,OAAO,CAAA;AAChB,CAAC;AAOD,MAAM,CAAC,MAAM,oBAAoB,GAAG,aAAa,CAAmC,IAAI,CAAC,CAAA;AAEzF,MAAM,UAAU,uBAAuB,CAAC,IAAY;IAClD,MAAM,OAAO,GAAG,UAAU,CAAC,oBAAoB,CAAC,CAAA;IAChD,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,aAAa,IAAI,sCAAsC,CAAC,CAAA;IACtF,OAAO,OAAO,CAAA;AAChB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ComponentPropsWithRef } from 'react';
|
|
2
|
+
import { type DialogContentProps } from '../dialog/parts.js';
|
|
3
|
+
export type AlertDialogContentProps = DialogContentProps;
|
|
4
|
+
/**
|
|
5
|
+
* A Dialog announced as an alert dialog. The difference is `role`, plus the
|
|
6
|
+
* convention that the only ways out are the buttons you provide — which is the
|
|
7
|
+
* native default, since a modal `<dialog>` has no light dismiss to disable.
|
|
8
|
+
*
|
|
9
|
+
* Escape still closes, exactly as it does in Radix's AlertDialog.
|
|
10
|
+
*/
|
|
11
|
+
export declare function AlertDialogContent(props: AlertDialogContentProps): import("react").JSX.Element;
|
|
12
|
+
export type AlertDialogActionProps = ComponentPropsWithRef<'button'>;
|
|
13
|
+
/** A close button that runs your handler. Both Action and Cancel dismiss. */
|
|
14
|
+
export declare function AlertDialogAction(props: AlertDialogActionProps): import("react").JSX.Element;
|
|
15
|
+
export declare function AlertDialogCancel(props: AlertDialogActionProps): import("react").JSX.Element;
|
|
16
|
+
//# sourceMappingURL=parts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parts.d.ts","sourceRoot":"","sources":["../../src/alert-dialog/parts.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,OAAO,CAAA;AAClD,OAAO,EAA8B,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAErF,MAAM,MAAM,uBAAuB,GAAG,kBAAkB,CAAA;AAExD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,+BAEhE;AAED,MAAM,MAAM,sBAAsB,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAA;AAEpE,6EAA6E;AAC7E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,+BAE9D;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,+BAE9D"}
|