@gunkin/uiify 0.0.15-alpha → 0.0.16-alpha

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.
Files changed (61) hide show
  1. package/README.md +34 -1
  2. package/agents/components.md +1 -0
  3. package/agents/index.md +7 -1
  4. package/agents/reference/components/table-of-contents.md +185 -0
  5. package/dist/components/index.d.ts +1 -0
  6. package/dist/components/index.d.ts.map +1 -1
  7. package/dist/components/index.js +1 -0
  8. package/dist/components/index.js.map +1 -1
  9. package/dist/components/table-of-contents/TableOfContents.d.ts +22 -0
  10. package/dist/components/table-of-contents/TableOfContents.d.ts.map +1 -0
  11. package/dist/components/table-of-contents/TableOfContents.js +142 -0
  12. package/dist/components/table-of-contents/TableOfContents.js.map +1 -0
  13. package/dist/components/table-of-contents/client/TableOfContentsClient.d.ts +18 -0
  14. package/dist/components/table-of-contents/client/TableOfContentsClient.d.ts.map +1 -0
  15. package/dist/components/table-of-contents/client/TableOfContentsClient.js +140 -0
  16. package/dist/components/table-of-contents/client/TableOfContentsClient.js.map +1 -0
  17. package/dist/components/table-of-contents/client/TableOfContentsClientParts.d.ts +7 -0
  18. package/dist/components/table-of-contents/client/TableOfContentsClientParts.d.ts.map +1 -0
  19. package/dist/components/table-of-contents/client/TableOfContentsClientParts.js +48 -0
  20. package/dist/components/table-of-contents/client/TableOfContentsClientParts.js.map +1 -0
  21. package/dist/components/table-of-contents/client/index.d.ts +5 -0
  22. package/dist/components/table-of-contents/client/index.d.ts.map +1 -0
  23. package/dist/components/table-of-contents/client/index.js +23 -0
  24. package/dist/components/table-of-contents/client/index.js.map +1 -0
  25. package/dist/components/table-of-contents/client/table-of-contents-context.d.ts +3 -0
  26. package/dist/components/table-of-contents/client/table-of-contents-context.d.ts.map +1 -0
  27. package/dist/components/table-of-contents/client/table-of-contents-context.js +7 -0
  28. package/dist/components/table-of-contents/client/table-of-contents-context.js.map +1 -0
  29. package/dist/components/table-of-contents/client/table-of-contents-interactions.d.ts +3 -0
  30. package/dist/components/table-of-contents/client/table-of-contents-interactions.d.ts.map +1 -0
  31. package/dist/components/table-of-contents/client/table-of-contents-interactions.js +144 -0
  32. package/dist/components/table-of-contents/client/table-of-contents-interactions.js.map +1 -0
  33. package/dist/components/table-of-contents/client/table-of-contents-pointer.d.ts +3 -0
  34. package/dist/components/table-of-contents/client/table-of-contents-pointer.d.ts.map +1 -0
  35. package/dist/components/table-of-contents/client/table-of-contents-pointer.js +94 -0
  36. package/dist/components/table-of-contents/client/table-of-contents-pointer.js.map +1 -0
  37. package/dist/components/table-of-contents/client.d.ts +1 -0
  38. package/dist/components/table-of-contents/client.js +1 -0
  39. package/dist/components/table-of-contents/index.d.ts +3 -0
  40. package/dist/components/table-of-contents/index.d.ts.map +1 -0
  41. package/dist/components/table-of-contents/index.js +21 -0
  42. package/dist/components/table-of-contents/index.js.map +1 -0
  43. package/dist/components/table-of-contents/scrollspy-selection.d.ts +4 -0
  44. package/dist/components/table-of-contents/scrollspy-selection.d.ts.map +1 -0
  45. package/dist/components/table-of-contents/scrollspy-selection.js +31 -0
  46. package/dist/components/table-of-contents/scrollspy-selection.js.map +1 -0
  47. package/dist/components/table-of-contents/scrollspy.d.ts +4 -0
  48. package/dist/components/table-of-contents/scrollspy.d.ts.map +1 -0
  49. package/dist/components/table-of-contents/scrollspy.js +178 -0
  50. package/dist/components/table-of-contents/scrollspy.js.map +1 -0
  51. package/dist/components/table-of-contents/types.d.ts +123 -0
  52. package/dist/components/table-of-contents/types.d.ts.map +1 -0
  53. package/dist/components/table-of-contents/types.js +1 -0
  54. package/dist/components/table-of-contents/types.js.map +1 -0
  55. package/dist/components/table-of-contents.d.ts +1 -0
  56. package/dist/components/table-of-contents.js +1 -0
  57. package/dist/styles/index.css +1 -1
  58. package/package.json +3 -2
  59. package/skills/uiify/SKILL.md +167 -0
  60. package/skills/uiify/scripts/lint.mjs +56 -0
  61. package/skills/uiify/scripts/static.mjs +95 -0
package/README.md CHANGED
@@ -7,7 +7,7 @@ Native-first, accessible React 19 components that work before hydration.
7
7
  ## Install
8
8
 
9
9
  ```bash
10
- npm install @gunkin/uiify@alpha react react-dom
10
+ npm install @gunkin/uiify react react-dom
11
11
  ```
12
12
 
13
13
  ## Use
@@ -44,6 +44,39 @@ For @gunkin/uiify, read node_modules/@gunkin/uiify/agents/index.md
44
44
 
45
45
  In a monorepo with hoisted dependencies, point to the nearest `node_modules/@gunkin/uiify`.
46
46
 
47
+ ### `/uiify` page-building skill
48
+
49
+ The package also includes the `/uiify` AI skill. Use it when an agent is creating or improving a
50
+ web page with UIify: it maps the brief to available components, plans the page in `DESIGN.md`,
51
+ implements the page in `src/App.tsx` when that file exists, and reports the checks it could run.
52
+ It uses the installed package's component references and follows UIify's public styling and
53
+ accessibility contracts. Invoke it explicitly so it runs only for page-building work.
54
+
55
+ Install the skill into the directory your agent reads:
56
+
57
+ ```bash
58
+ # Cross-tool Agent Skills location (Codex, Copilot, Cursor, and compatible tools)
59
+ mkdir -p .agents/skills/uiify
60
+ cp -R node_modules/@gunkin/uiify/skills/uiify/. .agents/skills/uiify/
61
+
62
+ # For Claude Code, use this location instead
63
+ mkdir -p .claude/skills/uiify
64
+ cp -R node_modules/@gunkin/uiify/skills/uiify/. .claude/skills/uiify/
65
+ ```
66
+
67
+ Then invoke `/uiify <page brief>` in Claude Code, or use the explicit skill invocation supported by
68
+ your agent. Add `--auto` to run all stages without confirmation gates. Interactive runs pause at
69
+ each stage so you can stop before implementation. The skill writes its design state to `DESIGN.md`
70
+ and page code under `src/`; it does not create a page when `src/App.tsx` is absent.
71
+
72
+ ### Keeping the skill current when developing UIify
73
+
74
+ When changing a UIify component, update its public component reference and example when its API or
75
+ usage changes, and update the harness catalog when its coverage or gap status changes. Then run
76
+ `npm run checks:fix` from the repository root. This regenerates the consumer AI docs and `/uiify`
77
+ skill, then checks their tests and freshness. Review and commit generated changes with the component
78
+ change. `npm run check:ai-harness` runs the focused tests and freshness checks without rewriting files.
79
+
47
80
  Documentation: https://uiify.gunkin.dev/
48
81
 
49
82
  MIT © Anton Gunkin
@@ -67,6 +67,7 @@ its exports, props and shapes; exact types are in the `.d.ts` file listed in the
67
67
  | [otp-input](./reference/components/otp-input.md) | `@gunkin/uiify/components/otp-input` | 2 | none | `input` | `dist/components/otp-input.d.ts` | |
68
68
  | [color-picker](./reference/components/color-picker.md) | `@gunkin/uiify/components/color-picker` | 1 | S1 | `input[type=color]` | `dist/components/color-picker.d.ts` | |
69
69
  | [virtual-scroll](./reference/components/virtual-scroll.md) | `@gunkin/uiify/components/virtual-scroll` | 2 | none | `div[overflow]` | `dist/components/virtual-scroll.d.ts` | |
70
+ | [table-of-contents](./reference/components/table-of-contents.md) | `@gunkin/uiify/components/table-of-contents` | 2 | S1 | `nav + button[popovertarget] + [popover] + a[href]` | `dist/components/table-of-contents.d.ts` | Base entry is a server-pure native navigation shell; /client adds enhancements. Native links and popover invocation/dismissal work without JavaScript. |
70
71
 
71
72
  ## Elements
72
73
 
package/agents/index.md CHANGED
@@ -74,7 +74,7 @@ export function BillingLink() {
74
74
  }
75
75
  ```
76
76
 
77
- Parts do not share React context. Each part names its root with an id you choose:
77
+ Native server parts do not share React context. Each part names its root with an id you choose:
78
78
 
79
79
  ```tsx
80
80
  import { Field } from "@gunkin/uiify/components/field";
@@ -171,3 +171,9 @@ Check a component's tier in `components.md` before importing it into a Server Co
171
171
 
172
172
  Some components also have sub-entries such as `@gunkin/uiify/components/modal/client` for
173
173
  controlled state. They are listed under **Sub-entries** in the component's reference file.
174
+
175
+ TableOfContents has a server-pure base entry for native popover buttons and fragment links.
176
+ Import `@gunkin/uiify/components/table-of-contents/client` for scrollspy, hover opening,
177
+ pinning and controlled `value`/`open`. Provide unique `Content.id` and matching `Trigger.target`,
178
+ label the navigation and trigger, and match each `Indicator.value` to a target heading ID.
179
+ The client Root owns context for its parts. A permanent list omits Trigger and Content.
@@ -0,0 +1,185 @@
1
+ <!-- Generated from the package source. Do not edit by hand. -->
2
+ # table-of-contents
3
+
4
+ - Import: `@gunkin/uiify/components/table-of-contents`
5
+ - Tier 2 (Client component — pre-hydration SSR); state source S1; native element `nav + button[popovertarget] + [popover] + a[href]`
6
+ - Without JavaScript: pre-hydration-only
7
+ - Types file: `dist/components/table-of-contents.d.ts`
8
+ - Note: Base entry is a server-pure native navigation shell; /client adds enhancements. Native links and popover invocation/dismissal work without JavaScript.
9
+
10
+ ## Exports
11
+
12
+ - Runtime: `TableOfContents`, `TableOfContentsRoot`, `TableOfContentsTrigger`, `TableOfContentsRail`, `TableOfContentsIndicator`, `TableOfContentsContent`, `TableOfContentsList`, `TableOfContentsLink`
13
+ - Types: `TableOfContentsLevel`, `TableOfContentsRootOwnProps`, `TableOfContentsRootProps`, `TableOfContentsTriggerOwnProps`, `TableOfContentsTriggerProps`, `TableOfContentsRailOwnProps`, `TableOfContentsRailProps`, `TableOfContentsIndicatorOwnProps`, `TableOfContentsIndicatorProps`, `TableOfContentsContentOwnProps`, `TableOfContentsContentProps`, `TableOfContentsListOwnProps`, `TableOfContentsListProps`, `TableOfContentsLinkOwnProps`, `TableOfContentsLinkProps`
14
+
15
+ ## Values
16
+
17
+ - `TableOfContentsLevel`: `1 | 2 | 3 | 4 | 5 | 6`
18
+
19
+ ## Props and shapes
20
+
21
+ ### TableOfContentsRootOwnProps
22
+
23
+ | Member | Type | Required | Description |
24
+ | --- | --- | --- | --- |
25
+ | `children` | `ReactNode` | no | |
26
+
27
+ ### TableOfContentsTriggerOwnProps
28
+
29
+ | Member | Type | Required | Description |
30
+ | --- | --- | --- | --- |
31
+ | `children` | `ReactNode` | no | |
32
+ | `target` | `string` | yes | |
33
+
34
+ ### TableOfContentsRailOwnProps
35
+
36
+ | Member | Type | Required | Description |
37
+ | --- | --- | --- | --- |
38
+ | `children` | `ReactNode` | no | |
39
+
40
+ ### TableOfContentsIndicatorOwnProps
41
+
42
+ | Member | Type | Required | Description |
43
+ | --- | --- | --- | --- |
44
+ | `ref` | `Ref<HTMLElement>` | no | |
45
+ | `style` | `CSSProperties` | no | |
46
+ | `children` | `ReactNode` | no | |
47
+ | `value` | `string` | yes | Stable target ID matching a Link fragment. |
48
+ | `level` | `TableOfContentsLevel` | no | |
49
+ | `selected` | `boolean` | no | |
50
+
51
+ ### TableOfContentsContentOwnProps
52
+
53
+ | Member | Type | Required | Description |
54
+ | --- | --- | --- | --- |
55
+ | `children` | `ReactNode` | no | |
56
+ | `id` | `string` | yes | |
57
+ | `side` | `AnchorSide` | no | |
58
+ | `align` | `AnchorAlign` | no | |
59
+
60
+ ### TableOfContentsListOwnProps
61
+
62
+ | Member | Type | Required | Description |
63
+ | --- | --- | --- | --- |
64
+ | `children` | `ReactNode` | no | |
65
+
66
+ ### TableOfContentsLinkOwnProps
67
+
68
+ | Member | Type | Required | Description |
69
+ | --- | --- | --- | --- |
70
+ | `style` | `CSSProperties` | no | |
71
+ | `"aria-current"` | `AriaAttributes["aria-current"]` | no | |
72
+ | `children` | `ReactNode` | no | |
73
+ | `href` | `string` | yes | Native same-page anchor; external URLs are not tracked by scrollspy. |
74
+ | `level` | `TableOfContentsLevel` | no | |
75
+ | `selected` | `boolean` | no | |
76
+
77
+ ### TableOfContentsTargetSnapshot
78
+
79
+ | Member | Type | Required | Description |
80
+ | --- | --- | --- | --- |
81
+ | `value` | `string` | yes | |
82
+ | `start` | `number` | yes | |
83
+ | `visible` | `boolean` | yes | |
84
+
85
+ ### TableOfContentsScrollSnapshot
86
+
87
+ | Member | Type | Required | Description |
88
+ | --- | --- | --- | --- |
89
+ | `targets` | `readonly TableOfContentsTargetSnapshot[]` | yes | |
90
+ | `viewportStart` | `number` | yes | |
91
+ | `viewportEnd` | `number` | yes | |
92
+ | `offset` | `number` | yes | |
93
+ | `contentEnd` | `number \| null` | yes | |
94
+
95
+ ### TableOfContentsObserverOptions
96
+
97
+ | Member | Type | Required | Description |
98
+ | --- | --- | --- | --- |
99
+ | `root` | `HTMLElement` | yes | |
100
+ | `scrollTarget` | `string \| undefined` | no | |
101
+ | `contentTarget` | `string \| undefined` | no | |
102
+ | `offset` | `number` | yes | |
103
+ | `onValueChange` | `(value: string \| null) => void` | yes | |
104
+
105
+ ### TableOfContentsObserver
106
+
107
+ | Member | Type | Required | Description |
108
+ | --- | --- | --- | --- |
109
+ | `refresh` | `() => void` | yes | |
110
+ | `destroy` | `() => void` | yes | |
111
+
112
+ ### TableOfContentsClientRootOwnProps
113
+
114
+ Extends: `TableOfContentsRootOwnProps`
115
+
116
+ | Member | Type | Required | Description |
117
+ | --- | --- | --- | --- |
118
+ | `ref` | `Ref<HTMLElement>` | no | |
119
+ | `className` | `string` | no | |
120
+ | `style` | `CSSProperties` | no | |
121
+ | `onClick` | `MouseEventHandler<HTMLElement>` | no | |
122
+ | `scrollSpy` | `boolean` | no | |
123
+ | `scrollTarget` | `string` | no | Scroll-container element ID; omitted tracks the owning window. |
124
+ | `contentTarget` | `string` | no | Content element ID used for target scope and end-of-content selection. |
125
+ | `offset` | `number` | no | |
126
+ | `value` | `string \| null` | no | |
127
+ | `defaultValue` | `string \| null` | no | |
128
+ | `onValueChange` | `(value: string \| null) => void` | no | |
129
+ | `open` | `boolean` | no | |
130
+ | `defaultOpen` | `boolean` | no | Applied after hydration; the native SSR surface starts closed. |
131
+ | `onOpenChange` | `(open: boolean) => void` | no | |
132
+ | `openOnHover` | `boolean` | no | |
133
+ | `openDelay` | `number` | no | |
134
+ | `closeDelay` | `number` | no | |
135
+
136
+ ### TableOfContentsClientContextValue
137
+
138
+ | Member | Type | Required | Description |
139
+ | --- | --- | --- | --- |
140
+ | `value` | `string \| null` | yes | |
141
+ | `open` | `boolean` | yes | |
142
+ | `documentUrl` | `string \| undefined` | yes | |
143
+
144
+ ### TableOfContentsInteractionOptions
145
+
146
+ | Member | Type | Required | Description |
147
+ | --- | --- | --- | --- |
148
+ | `root` | `HTMLElement` | yes | |
149
+ | `getOpen` | `() => boolean` | yes | |
150
+ | `requestOpen` | `(open: boolean) => void` | yes | |
151
+ | `controlled` | `boolean` | yes | |
152
+ | `openOnHover` | `boolean` | yes | |
153
+ | `openDelay` | `number` | yes | |
154
+ | `closeDelay` | `number` | yes | |
155
+
156
+ ### TableOfContentsInteractions
157
+
158
+ | Member | Type | Required | Description |
159
+ | --- | --- | --- | --- |
160
+ | `click` | `(event: MouseEvent) => void` | yes | |
161
+ | `destroy` | `() => void` | yes | |
162
+
163
+ ### TableOfContentsPointerOptions
164
+
165
+ | Member | Type | Required | Description |
166
+ | --- | --- | --- | --- |
167
+ | `root` | `HTMLElement` | yes | |
168
+
169
+ ## Other types
170
+
171
+ - `TableOfContentsRootProps<TAs>`: `RenderableProps<TAs, TableOfContentsRootOwnProps, Record<string, never>, HTMLElement>`
172
+ - `TableOfContentsTriggerProps<TAs>`: `NativeButtonProps<TAs, TableOfContentsTriggerOwnProps>`
173
+ - `TableOfContentsRailProps<TAs>`: `RenderableProps<TAs, TableOfContentsRailOwnProps, Record<string, never>, HTMLElement>`
174
+ - `TableOfContentsIndicatorProps<TAs>`: `RenderableProps<TAs, TableOfContentsIndicatorOwnProps, { selected: boolean }, HTMLElement>`
175
+ - `TableOfContentsContentProps<TAs>`: `RenderableProps<TAs, TableOfContentsContentOwnProps, Record<string, never>, HTMLElement>`
176
+ - `TableOfContentsListProps<TAs>`: `RenderableProps<TAs, TableOfContentsListOwnProps, Record<string, never>, HTMLElement>`
177
+ - `TableOfContentsLinkProps<TAs>`: `RenderableProps<TAs, TableOfContentsLinkOwnProps, { selected: boolean }, HTMLAnchorElement>`
178
+ - `TableOfContentsClientRootProps<TAs>`: `RenderableProps<TAs, TableOfContentsClientRootOwnProps, { value: string | null; open: boolean }, HTMLElement>`
179
+
180
+ ## Sub-entries
181
+
182
+ ### `@gunkin/uiify/components/table-of-contents/client`
183
+
184
+ - Runtime: `TableOfContents`, `TableOfContentsRoot`, `TableOfContentsTrigger`, `TableOfContentsContent`, `TableOfContentsLink`, `TableOfContentsIndicator`, `TableOfContentsRail`, `TableOfContentsList`
185
+ - Types: `TableOfContentsClientRootOwnProps`, `TableOfContentsClientRootProps`, `TableOfContentsLevel`, `TableOfContentsTriggerProps`, `TableOfContentsRailProps`, `TableOfContentsContentProps`, `TableOfContentsListProps`, `TableOfContentsLinkProps`, `TableOfContentsIndicatorProps`
@@ -41,4 +41,5 @@ export * from "./drawer/index.js";
41
41
  export * from "./context-menu/index.js";
42
42
  export * from "./header/index.js";
43
43
  export * from "./virtual-scroll/index.js";
44
+ export * from "./table-of-contents/index.js";
44
45
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAIA,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,2BAA2B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAIA,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,2BAA2B,CAAC;AAE1C,cAAc,8BAA8B,CAAC"}
@@ -41,4 +41,5 @@ export * from "./drawer/index.js";
41
41
  export * from "./context-menu/index.js";
42
42
  export * from "./header/index.js";
43
43
  export * from "./virtual-scroll/index.js";
44
+ export * from "./table-of-contents/index.js";
44
45
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/index.ts"],"sourcesContent":["// @gunkin/uiify/components — root barrel export.\n// Each component task appends one line here:\n// export * from \"./<name>/index.js\";\n\nexport * from \"./button/index.js\";\nexport * from \"./checkbox/index.js\";\nexport * from \"./modal/index.js\";\nexport * from \"./dropdown-menu/index.js\";\nexport * from \"./hover-card/index.js\";\nexport * from \"./input/index.js\";\nexport * from \"./popup/index.js\";\nexport * from \"./radio-group/index.js\";\nexport * from \"./slider/index.js\";\nexport * from \"./switch/index.js\";\nexport * from \"./tabs/index.js\";\nexport * from \"./textarea/index.js\";\nexport * from \"./toggle-group/index.js\";\nexport * from \"./toolbar/index.js\";\nexport * from \"./toggle/index.js\";\nexport * from \"./tooltip/index.js\";\nexport * from \"./accordion/index.js\";\nexport * from \"./alert-modal/index.js\";\nexport * from \"./combobox/index.js\";\nexport * from \"./toast/index.js\";\nexport * from \"./select/index.js\";\nexport * from \"./spinner/index.js\";\nexport * from \"./skeleton/index.js\";\nexport * from \"./collapsible/index.js\";\nexport * from \"./breadcrumb/index.js\";\nexport * from \"./pagination/index.js\";\nexport * from \"./table/index.js\";\nexport * from \"./number-field/index.js\";\nexport * from \"./otp-input/index.js\";\nexport * from \"./segmented-control/index.js\";\nexport * from \"./rating/index.js\";\nexport * from \"./field/index.js\";\nexport * from \"./form/index.js\";\nexport * from \"./tags-input/index.js\";\nexport * from \"./file-upload/index.js\";\nexport * from \"./color-picker/index.js\";\nexport * from \"./carousel/index.js\";\nexport * from \"./candle-chart/index.js\";\nexport * from \"./line-chart/index.js\";\nexport * from \"./drawer/index.js\";\nexport * from \"./context-menu/index.js\";\nexport * from \"./header/index.js\";\nexport * from \"./virtual-scroll/index.js\";\n"],"mappings":"AAIA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
1
+ {"version":3,"sources":["../../src/components/index.ts"],"sourcesContent":["// @gunkin/uiify/components — root barrel export.\n// Each component task appends one line here:\n// export * from \"./<name>/index.js\";\n\nexport * from \"./button/index.js\";\nexport * from \"./checkbox/index.js\";\nexport * from \"./modal/index.js\";\nexport * from \"./dropdown-menu/index.js\";\nexport * from \"./hover-card/index.js\";\nexport * from \"./input/index.js\";\nexport * from \"./popup/index.js\";\nexport * from \"./radio-group/index.js\";\nexport * from \"./slider/index.js\";\nexport * from \"./switch/index.js\";\nexport * from \"./tabs/index.js\";\nexport * from \"./textarea/index.js\";\nexport * from \"./toggle-group/index.js\";\nexport * from \"./toolbar/index.js\";\nexport * from \"./toggle/index.js\";\nexport * from \"./tooltip/index.js\";\nexport * from \"./accordion/index.js\";\nexport * from \"./alert-modal/index.js\";\nexport * from \"./combobox/index.js\";\nexport * from \"./toast/index.js\";\nexport * from \"./select/index.js\";\nexport * from \"./spinner/index.js\";\nexport * from \"./skeleton/index.js\";\nexport * from \"./collapsible/index.js\";\nexport * from \"./breadcrumb/index.js\";\nexport * from \"./pagination/index.js\";\nexport * from \"./table/index.js\";\nexport * from \"./number-field/index.js\";\nexport * from \"./otp-input/index.js\";\nexport * from \"./segmented-control/index.js\";\nexport * from \"./rating/index.js\";\nexport * from \"./field/index.js\";\nexport * from \"./form/index.js\";\nexport * from \"./tags-input/index.js\";\nexport * from \"./file-upload/index.js\";\nexport * from \"./color-picker/index.js\";\nexport * from \"./carousel/index.js\";\nexport * from \"./candle-chart/index.js\";\nexport * from \"./line-chart/index.js\";\nexport * from \"./drawer/index.js\";\nexport * from \"./context-menu/index.js\";\nexport * from \"./header/index.js\";\nexport * from \"./virtual-scroll/index.js\";\n\nexport * from \"./table-of-contents/index.js\";\n"],"mappings":"AAIA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AAEd,cAAc;","names":[]}
@@ -0,0 +1,22 @@
1
+ import type { ElementType, ReactElement } from "react";
2
+ import type { TableOfContentsRootProps, TableOfContentsTriggerProps, TableOfContentsRailProps, TableOfContentsIndicatorProps, TableOfContentsContentProps, TableOfContentsListProps, TableOfContentsLinkProps } from "./types.js";
3
+ export declare function TableOfContentsRoot<TAs extends ElementType = "nav">(props: TableOfContentsRootProps<TAs>): ReactElement | null;
4
+ export declare function TableOfContentsTrigger<TAs extends ElementType = "button">(props: TableOfContentsTriggerProps<TAs>): ReactElement;
5
+ export declare namespace TableOfContentsTrigger {
6
+ var displayName: string;
7
+ }
8
+ export declare function TableOfContentsRail<TAs extends ElementType = "span">(props: TableOfContentsRailProps<TAs>): ReactElement | null;
9
+ export declare function TableOfContentsIndicator<TAs extends ElementType = "span">(props: TableOfContentsIndicatorProps<TAs>): ReactElement | null;
10
+ export declare function TableOfContentsContent<TAs extends ElementType = "div">(props: TableOfContentsContentProps<TAs>): ReactElement | null;
11
+ export declare function TableOfContentsList<TAs extends ElementType = "div">(props: TableOfContentsListProps<TAs>): ReactElement | null;
12
+ export declare function TableOfContentsLink<TAs extends ElementType = "a">(props: TableOfContentsLinkProps<TAs>): ReactElement | null;
13
+ export declare const TableOfContents: {
14
+ Root: typeof TableOfContentsRoot;
15
+ Trigger: typeof TableOfContentsTrigger;
16
+ Rail: typeof TableOfContentsRail;
17
+ Indicator: typeof TableOfContentsIndicator;
18
+ Content: typeof TableOfContentsContent;
19
+ List: typeof TableOfContentsList;
20
+ Link: typeof TableOfContentsLink;
21
+ };
22
+ //# sourceMappingURL=TableOfContents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TableOfContents.d.ts","sourceRoot":"","sources":["../../../src/components/table-of-contents/TableOfContents.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAiB,WAAW,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAMtE,OAAO,KAAK,EACV,wBAAwB,EACxB,2BAA2B,EAC3B,wBAAwB,EACxB,6BAA6B,EAC7B,2BAA2B,EAC3B,wBAAwB,EACxB,wBAAwB,EACzB,MAAM,YAAY,CAAC;AAMpB,wBAAgB,mBAAmB,CAAC,GAAG,SAAS,WAAW,GAAG,KAAK,EACjE,KAAK,EAAE,wBAAwB,CAAC,GAAG,CAAC,GACnC,YAAY,GAAG,IAAI,CASrB;AACD,wBAAgB,sBAAsB,CAAC,GAAG,SAAS,WAAW,GAAG,QAAQ,EACvE,KAAK,EAAE,2BAA2B,CAAC,GAAG,CAAC,GACtC,YAAY,CAUd;yBAZe,sBAAsB;;;AAatC,wBAAgB,mBAAmB,CAAC,GAAG,SAAS,WAAW,GAAG,MAAM,EAClE,KAAK,EAAE,wBAAwB,CAAC,GAAG,CAAC,GACnC,YAAY,GAAG,IAAI,CASrB;AACD,wBAAgB,wBAAwB,CAAC,GAAG,SAAS,WAAW,GAAG,MAAM,EACvE,KAAK,EAAE,6BAA6B,CAAC,GAAG,CAAC,GACxC,YAAY,GAAG,IAAI,CAuBrB;AACD,wBAAgB,sBAAsB,CAAC,GAAG,SAAS,WAAW,GAAG,KAAK,EACpE,KAAK,EAAE,2BAA2B,CAAC,GAAG,CAAC,GACtC,YAAY,GAAG,IAAI,CAsBrB;AACD,wBAAgB,mBAAmB,CAAC,GAAG,SAAS,WAAW,GAAG,KAAK,EACjE,KAAK,EAAE,wBAAwB,CAAC,GAAG,CAAC,GACnC,YAAY,GAAG,IAAI,CASrB;AACD,wBAAgB,mBAAmB,CAAC,GAAG,SAAS,WAAW,GAAG,GAAG,EAC/D,KAAK,EAAE,wBAAwB,CAAC,GAAG,CAAC,GACnC,YAAY,GAAG,IAAI,CAuBrB;AAED,eAAO,MAAM,eAAe;;;;;;;;CAQ3B,CAAC"}
@@ -0,0 +1,142 @@
1
+ import { createElement } from "react";
2
+ import { useRenderElement } from "../../core/render.js";
3
+ import {
4
+ createAnchorPositionerProps,
5
+ createAnchorTriggerProps
6
+ } from "../../core/anchor-position/props.js";
7
+ function anchorFor(target) {
8
+ return `--uiify-toc-${Array.from(target, (c) => c.codePointAt(0)?.toString(16)).join("-")}`;
9
+ }
10
+ function TableOfContentsRoot(props) {
11
+ const { as, render, ...rest } = props;
12
+ return useRenderElement({
13
+ as,
14
+ render,
15
+ defaultTag: "nav",
16
+ props: { ...rest, "data-uiify-table-of-contents": "" },
17
+ state: {}
18
+ });
19
+ }
20
+ function TableOfContentsTrigger(props) {
21
+ const { as, target, ...rest } = props;
22
+ return createElement(as ?? "button", {
23
+ ...rest,
24
+ ...createAnchorTriggerProps(anchorFor(target)),
25
+ "data-part": "trigger",
26
+ type: "button",
27
+ popoverTarget: target,
28
+ popoverTargetAction: "toggle"
29
+ });
30
+ }
31
+ function TableOfContentsRail(props) {
32
+ const { as, render, ...rest } = props;
33
+ return useRenderElement({
34
+ as,
35
+ render,
36
+ defaultTag: "span",
37
+ props: { ...rest, "aria-hidden": true, "data-part": "rail" },
38
+ state: {}
39
+ });
40
+ }
41
+ function TableOfContentsIndicator(props) {
42
+ const {
43
+ as,
44
+ render,
45
+ value: _value,
46
+ level = 2,
47
+ selected = false,
48
+ style,
49
+ ...rest
50
+ } = props;
51
+ return useRenderElement({
52
+ as,
53
+ render,
54
+ defaultTag: "span",
55
+ props: {
56
+ ...rest,
57
+ style: { ...style, "--uiify-toc-level": level },
58
+ "aria-hidden": true,
59
+ "data-part": "indicator",
60
+ "data-selected": selected ? "" : void 0
61
+ },
62
+ state: { selected }
63
+ });
64
+ }
65
+ function TableOfContentsContent(props) {
66
+ const {
67
+ as,
68
+ render,
69
+ side = "left",
70
+ align = "start",
71
+ id,
72
+ ...rest
73
+ } = props;
74
+ return useRenderElement({
75
+ as,
76
+ render,
77
+ defaultTag: "div",
78
+ props: {
79
+ ...rest,
80
+ ...createAnchorPositionerProps({ anchorName: anchorFor(id), side, align }),
81
+ id,
82
+ popover: "auto",
83
+ "data-part": "content"
84
+ },
85
+ state: {}
86
+ });
87
+ }
88
+ function TableOfContentsList(props) {
89
+ const { as, render, ...rest } = props;
90
+ return useRenderElement({
91
+ as,
92
+ render,
93
+ defaultTag: "div",
94
+ props: { ...rest, "data-part": "list" },
95
+ state: {}
96
+ });
97
+ }
98
+ function TableOfContentsLink(props) {
99
+ const {
100
+ as,
101
+ render,
102
+ level = 2,
103
+ selected,
104
+ style,
105
+ ...rest
106
+ } = props;
107
+ const current = selected ?? rest["aria-current"] === "location";
108
+ return useRenderElement({
109
+ as,
110
+ render,
111
+ defaultTag: "a",
112
+ props: {
113
+ ...rest,
114
+ style: { ...style, "--uiify-toc-level": level },
115
+ "data-part": "link",
116
+ "data-selected": current ? "" : void 0,
117
+ ...selected === void 0 ? {} : { "aria-current": selected ? "location" : void 0 }
118
+ },
119
+ state: { selected: current }
120
+ });
121
+ }
122
+ const TableOfContents = {
123
+ Root: TableOfContentsRoot,
124
+ Trigger: TableOfContentsTrigger,
125
+ Rail: TableOfContentsRail,
126
+ Indicator: TableOfContentsIndicator,
127
+ Content: TableOfContentsContent,
128
+ List: TableOfContentsList,
129
+ Link: TableOfContentsLink
130
+ };
131
+ TableOfContentsTrigger.displayName = "TableOfContentsTrigger";
132
+ export {
133
+ TableOfContents,
134
+ TableOfContentsContent,
135
+ TableOfContentsIndicator,
136
+ TableOfContentsLink,
137
+ TableOfContentsList,
138
+ TableOfContentsRail,
139
+ TableOfContentsRoot,
140
+ TableOfContentsTrigger
141
+ };
142
+ //# sourceMappingURL=TableOfContents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/table-of-contents/TableOfContents.tsx"],"sourcesContent":["// Informed by studying Mantine TableOfContents, Fumadocs TOC and Tocbot.\n// Independently written; see NOTICE and the clean-room research notes.\nimport { createElement } from \"react\";\nimport type { CSSProperties, ElementType, ReactElement } from \"react\";\nimport { useRenderElement } from \"../../core/render.js\";\nimport {\n createAnchorPositionerProps,\n createAnchorTriggerProps,\n} from \"../../core/anchor-position/props.js\";\nimport type {\n TableOfContentsRootProps,\n TableOfContentsTriggerProps,\n TableOfContentsRailProps,\n TableOfContentsIndicatorProps,\n TableOfContentsContentProps,\n TableOfContentsListProps,\n TableOfContentsLinkProps,\n} from \"./types.js\";\n\nfunction anchorFor(target: string): string {\n return `--uiify-toc-${Array.from(target, (c) => c.codePointAt(0)?.toString(16)).join(\"-\")}`;\n}\n\nexport function TableOfContentsRoot<TAs extends ElementType = \"nav\">(\n props: TableOfContentsRootProps<TAs>,\n): ReactElement | null {\n const { as, render, ...rest } = props as TableOfContentsRootProps<\"nav\">;\n return useRenderElement({\n as,\n render,\n defaultTag: \"nav\",\n props: { ...rest, \"data-uiify-table-of-contents\": \"\" },\n state: {},\n });\n}\nexport function TableOfContentsTrigger<TAs extends ElementType = \"button\">(\n props: TableOfContentsTriggerProps<TAs>,\n): ReactElement {\n const { as, target, ...rest } = props as TableOfContentsTriggerProps<\"button\">;\n return createElement(as ?? \"button\", {\n ...rest,\n ...createAnchorTriggerProps(anchorFor(target)),\n \"data-part\": \"trigger\",\n type: \"button\",\n popoverTarget: target,\n popoverTargetAction: \"toggle\",\n });\n}\nexport function TableOfContentsRail<TAs extends ElementType = \"span\">(\n props: TableOfContentsRailProps<TAs>,\n): ReactElement | null {\n const { as, render, ...rest } = props as TableOfContentsRailProps<\"span\">;\n return useRenderElement({\n as,\n render,\n defaultTag: \"span\",\n props: { ...rest, \"aria-hidden\": true, \"data-part\": \"rail\" },\n state: {},\n });\n}\nexport function TableOfContentsIndicator<TAs extends ElementType = \"span\">(\n props: TableOfContentsIndicatorProps<TAs>,\n): ReactElement | null {\n const {\n as,\n render,\n value: _value,\n level = 2,\n selected = false,\n style,\n ...rest\n } = props as TableOfContentsIndicatorProps<\"span\">;\n return useRenderElement({\n as,\n render,\n defaultTag: \"span\",\n props: {\n ...rest,\n style: { ...style, \"--uiify-toc-level\": level } as CSSProperties,\n \"aria-hidden\": true,\n \"data-part\": \"indicator\",\n \"data-selected\": selected ? \"\" : undefined,\n },\n state: { selected },\n });\n}\nexport function TableOfContentsContent<TAs extends ElementType = \"div\">(\n props: TableOfContentsContentProps<TAs>,\n): ReactElement | null {\n const {\n as,\n render,\n side = \"left\",\n align = \"start\",\n id,\n ...rest\n } = props as TableOfContentsContentProps<\"div\">;\n return useRenderElement({\n as,\n render,\n defaultTag: \"div\",\n props: {\n ...rest,\n ...createAnchorPositionerProps({ anchorName: anchorFor(id), side, align }),\n id,\n popover: \"auto\",\n \"data-part\": \"content\",\n },\n state: {},\n });\n}\nexport function TableOfContentsList<TAs extends ElementType = \"div\">(\n props: TableOfContentsListProps<TAs>,\n): ReactElement | null {\n const { as, render, ...rest } = props as TableOfContentsListProps<\"div\">;\n return useRenderElement({\n as,\n render,\n defaultTag: \"div\",\n props: { ...rest, \"data-part\": \"list\" },\n state: {},\n });\n}\nexport function TableOfContentsLink<TAs extends ElementType = \"a\">(\n props: TableOfContentsLinkProps<TAs>,\n): ReactElement | null {\n const {\n as,\n render,\n level = 2,\n selected,\n style,\n ...rest\n } = props as TableOfContentsLinkProps<\"a\">;\n const current = selected ?? rest[\"aria-current\"] === \"location\";\n return useRenderElement({\n as,\n render,\n defaultTag: \"a\",\n props: {\n ...rest,\n style: { ...style, \"--uiify-toc-level\": level } as CSSProperties,\n \"data-part\": \"link\",\n \"data-selected\": current ? \"\" : undefined,\n ...(selected === undefined ? {} : { \"aria-current\": selected ? \"location\" : undefined }),\n },\n state: { selected: current },\n });\n}\n\nexport const TableOfContents = {\n Root: TableOfContentsRoot,\n Trigger: TableOfContentsTrigger,\n Rail: TableOfContentsRail,\n Indicator: TableOfContentsIndicator,\n Content: TableOfContentsContent,\n List: TableOfContentsList,\n Link: TableOfContentsLink,\n};\n\nTableOfContentsTrigger.displayName = \"TableOfContentsTrigger\";\n"],"mappings":"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","names":[]}
@@ -0,0 +1,18 @@
1
+ import type { ElementType, ReactElement } from "react";
2
+ import { TableOfContentsRail as NativeRail, TableOfContentsList as NativeList } from "../TableOfContents.js";
3
+ import { TableOfContentsClientTrigger, TableOfContentsClientContent, TableOfContentsClientLink, TableOfContentsClientIndicator } from "./TableOfContentsClientParts.js";
4
+ import type { TableOfContentsClientRootProps } from "../types.js";
5
+ export declare function TableOfContentsClientRoot<TAs extends ElementType = "nav">(props: TableOfContentsClientRootProps<TAs>): ReactElement;
6
+ export declare namespace TableOfContentsClientRoot {
7
+ var displayName: string;
8
+ }
9
+ export declare const TableOfContents: {
10
+ Root: typeof TableOfContentsClientRoot;
11
+ Trigger: typeof TableOfContentsClientTrigger;
12
+ Rail: typeof NativeRail;
13
+ Content: typeof TableOfContentsClientContent;
14
+ List: typeof NativeList;
15
+ Link: typeof TableOfContentsClientLink;
16
+ Indicator: typeof TableOfContentsClientIndicator;
17
+ };
18
+ //# sourceMappingURL=TableOfContentsClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TableOfContentsClient.d.ts","sourceRoot":"","sources":["../../../../src/components/table-of-contents/client/TableOfContentsClient.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAiC,MAAM,OAAO,CAAC;AAMtF,OAAO,EACL,mBAAmB,IAAI,UAAU,EACjC,mBAAmB,IAAI,UAAU,EAClC,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,4BAA4B,EAC5B,4BAA4B,EAC5B,yBAAyB,EACzB,8BAA8B,EAC/B,MAAM,iCAAiC,CAAC;AAIzC,OAAO,KAAK,EAAE,8BAA8B,EAA+B,MAAM,aAAa,CAAC;AAE/F,wBAAgB,yBAAyB,CAAC,GAAG,SAAS,WAAW,GAAG,KAAK,EACvE,KAAK,EAAE,8BAA8B,CAAC,GAAG,CAAC,GACzC,YAAY,CA4Gd;yBA9Ge,yBAAyB;;;AA+GzC,eAAO,MAAM,eAAe;;;;;;;;CAQ3B,CAAC"}
@@ -0,0 +1,140 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { useEffect, useRef, useState } from "react";
4
+ import { useControllableState } from "../../../hooks/use-controllable-state.js";
5
+ import { useEventCallback } from "../../../hooks/use-event-callback.js";
6
+ import { useMergedRefs } from "../../../hooks/use-merged-refs.js";
7
+ import { useIsomorphicLayoutEffect } from "../../../hooks/use-isomorphic-layout-effect.js";
8
+ import { useRenderElement } from "../../../core/render.js";
9
+ import {
10
+ TableOfContentsRail as NativeRail,
11
+ TableOfContentsList as NativeList
12
+ } from "../TableOfContents.js";
13
+ import { observeTableOfContents } from "../scrollspy.js";
14
+ import {
15
+ TableOfContentsClientTrigger,
16
+ TableOfContentsClientContent,
17
+ TableOfContentsClientLink,
18
+ TableOfContentsClientIndicator
19
+ } from "./TableOfContentsClientParts.js";
20
+ import { TableOfContentsContext } from "./table-of-contents-context.js";
21
+ import { attachTableOfContentsInteractions } from "./table-of-contents-interactions.js";
22
+ import { attachTableOfContentsPointer } from "./table-of-contents-pointer.js";
23
+ function TableOfContentsClientRoot(props) {
24
+ const {
25
+ as,
26
+ render,
27
+ ref,
28
+ children,
29
+ onClick,
30
+ scrollSpy = true,
31
+ scrollTarget,
32
+ contentTarget,
33
+ offset = 0,
34
+ value: controlledValue,
35
+ defaultValue = null,
36
+ onValueChange,
37
+ open: controlledOpen,
38
+ defaultOpen = false,
39
+ onOpenChange,
40
+ openOnHover = true,
41
+ openDelay = 100,
42
+ closeDelay = 200,
43
+ ...rest
44
+ } = props;
45
+ const rootRef = useRef(null), mergedRef = useMergedRefs(rootRef, ref);
46
+ const [value, setValue] = useControllableState({
47
+ value: controlledValue,
48
+ defaultValue,
49
+ onChange: onValueChange
50
+ });
51
+ const [open, setOpen] = useControllableState({
52
+ value: controlledOpen,
53
+ defaultValue: defaultOpen,
54
+ onChange: onOpenChange
55
+ });
56
+ const [documentUrl, setDocumentUrl] = useState();
57
+ const ready = documentUrl !== void 0;
58
+ const interactions = useRef(null);
59
+ const getOpen = useEventCallback(() => open);
60
+ const controlled = controlledOpen !== void 0;
61
+ useIsomorphicLayoutEffect(() => {
62
+ const root = rootRef.current, panel = root?.querySelector('[data-part="content"]');
63
+ if (!root) return;
64
+ setDocumentUrl(root.ownerDocument.URL);
65
+ if (!panel) return;
66
+ const actual = panel.matches(":popover-open");
67
+ if (!ready && controlledOpen === void 0 && actual && !open) {
68
+ setOpen(true);
69
+ return;
70
+ }
71
+ if (actual !== open) {
72
+ if (open) panel.showPopover();
73
+ else panel.hidePopover();
74
+ }
75
+ }, [open, children, controlledOpen, setOpen, ready]);
76
+ useEffect(() => {
77
+ const root = rootRef.current;
78
+ if (!root) return;
79
+ const controller = attachTableOfContentsInteractions({
80
+ root,
81
+ getOpen,
82
+ requestOpen: setOpen,
83
+ controlled,
84
+ openOnHover,
85
+ openDelay,
86
+ closeDelay
87
+ });
88
+ interactions.current = controller;
89
+ const clearPointer = attachTableOfContentsPointer({ root });
90
+ return () => {
91
+ controller.destroy();
92
+ interactions.current = null;
93
+ clearPointer();
94
+ };
95
+ }, [controlled, openOnHover, openDelay, closeDelay, getOpen, setOpen, as]);
96
+ useEffect(() => {
97
+ if (!scrollSpy || !rootRef.current) return;
98
+ const controller = observeTableOfContents({
99
+ root: rootRef.current,
100
+ scrollTarget,
101
+ contentTarget,
102
+ offset: Math.max(0, offset),
103
+ onValueChange: setValue
104
+ });
105
+ return () => controller.destroy();
106
+ }, [scrollSpy, scrollTarget, contentTarget, offset, setValue]);
107
+ const element = useRenderElement({
108
+ as,
109
+ render,
110
+ defaultTag: "nav",
111
+ props: {
112
+ ...rest,
113
+ children,
114
+ ref: mergedRef,
115
+ "data-uiify-table-of-contents": "",
116
+ "data-state": ready && open ? "open" : "closed",
117
+ onClick(event) {
118
+ onClick?.(event);
119
+ interactions.current?.click(event.nativeEvent);
120
+ }
121
+ },
122
+ state: { value, open: ready && open }
123
+ });
124
+ return /* @__PURE__ */ jsx(TableOfContentsContext, { value: { value, open: ready && open, documentUrl }, children: element });
125
+ }
126
+ const TableOfContents = {
127
+ Root: TableOfContentsClientRoot,
128
+ Trigger: TableOfContentsClientTrigger,
129
+ Rail: NativeRail,
130
+ Content: TableOfContentsClientContent,
131
+ List: NativeList,
132
+ Link: TableOfContentsClientLink,
133
+ Indicator: TableOfContentsClientIndicator
134
+ };
135
+ TableOfContentsClientRoot.displayName = "TableOfContentsClientRoot";
136
+ export {
137
+ TableOfContents,
138
+ TableOfContentsClientRoot
139
+ };
140
+ //# sourceMappingURL=TableOfContentsClient.js.map