@llui/components 0.0.1

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 (213) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +143 -0
  3. package/dist/components/accordion.d.ts +115 -0
  4. package/dist/components/accordion.d.ts.map +1 -0
  5. package/dist/components/accordion.js +138 -0
  6. package/dist/components/alert-dialog.d.ts +45 -0
  7. package/dist/components/alert-dialog.d.ts.map +1 -0
  8. package/dist/components/alert-dialog.js +12 -0
  9. package/dist/components/angle-slider.d.ts +121 -0
  10. package/dist/components/angle-slider.d.ts.map +1 -0
  11. package/dist/components/angle-slider.js +145 -0
  12. package/dist/components/async-list.d.ts +104 -0
  13. package/dist/components/async-list.d.ts.map +1 -0
  14. package/dist/components/async-list.js +117 -0
  15. package/dist/components/avatar.d.ts +58 -0
  16. package/dist/components/avatar.d.ts.map +1 -0
  17. package/dist/components/avatar.js +43 -0
  18. package/dist/components/carousel.d.ts +128 -0
  19. package/dist/components/carousel.d.ts.map +1 -0
  20. package/dist/components/carousel.js +131 -0
  21. package/dist/components/cascade-select.d.ts +95 -0
  22. package/dist/components/cascade-select.d.ts.map +1 -0
  23. package/dist/components/cascade-select.js +100 -0
  24. package/dist/components/checkbox.d.ts +74 -0
  25. package/dist/components/checkbox.d.ts.map +1 -0
  26. package/dist/components/checkbox.js +73 -0
  27. package/dist/components/clipboard.d.ts +72 -0
  28. package/dist/components/clipboard.d.ts.map +1 -0
  29. package/dist/components/clipboard.js +73 -0
  30. package/dist/components/collapsible.d.ts +64 -0
  31. package/dist/components/collapsible.d.ts.map +1 -0
  32. package/dist/components/collapsible.js +51 -0
  33. package/dist/components/color-picker.d.ts +125 -0
  34. package/dist/components/color-picker.d.ts.map +1 -0
  35. package/dist/components/color-picker.js +169 -0
  36. package/dist/components/combobox.d.ts +163 -0
  37. package/dist/components/combobox.d.ts.map +1 -0
  38. package/dist/components/combobox.js +345 -0
  39. package/dist/components/context-menu.d.ts +105 -0
  40. package/dist/components/context-menu.d.ts.map +1 -0
  41. package/dist/components/context-menu.js +177 -0
  42. package/dist/components/date-input.d.ts +117 -0
  43. package/dist/components/date-input.d.ts.map +1 -0
  44. package/dist/components/date-input.js +149 -0
  45. package/dist/components/date-picker.d.ts +142 -0
  46. package/dist/components/date-picker.d.ts.map +1 -0
  47. package/dist/components/date-picker.js +294 -0
  48. package/dist/components/dialog.d.ts +152 -0
  49. package/dist/components/dialog.d.ts.map +1 -0
  50. package/dist/components/dialog.js +140 -0
  51. package/dist/components/drawer.d.ts +106 -0
  52. package/dist/components/drawer.d.ts.map +1 -0
  53. package/dist/components/drawer.js +136 -0
  54. package/dist/components/editable.d.ts +92 -0
  55. package/dist/components/editable.d.ts.map +1 -0
  56. package/dist/components/editable.js +112 -0
  57. package/dist/components/file-upload.d.ts +251 -0
  58. package/dist/components/file-upload.d.ts.map +1 -0
  59. package/dist/components/file-upload.js +324 -0
  60. package/dist/components/floating-panel.d.ts +171 -0
  61. package/dist/components/floating-panel.d.ts.map +1 -0
  62. package/dist/components/floating-panel.js +198 -0
  63. package/dist/components/hover-card.d.ts +85 -0
  64. package/dist/components/hover-card.d.ts.map +1 -0
  65. package/dist/components/hover-card.js +128 -0
  66. package/dist/components/image-cropper.d.ts +129 -0
  67. package/dist/components/image-cropper.d.ts.map +1 -0
  68. package/dist/components/image-cropper.js +208 -0
  69. package/dist/components/index.d.ts +109 -0
  70. package/dist/components/index.d.ts.map +1 -0
  71. package/dist/components/index.js +54 -0
  72. package/dist/components/listbox.d.ts +98 -0
  73. package/dist/components/listbox.d.ts.map +1 -0
  74. package/dist/components/listbox.js +174 -0
  75. package/dist/components/marquee.d.ts +84 -0
  76. package/dist/components/marquee.d.ts.map +1 -0
  77. package/dist/components/marquee.js +73 -0
  78. package/dist/components/menu.d.ts +131 -0
  79. package/dist/components/menu.d.ts.map +1 -0
  80. package/dist/components/menu.js +262 -0
  81. package/dist/components/navigation-menu.d.ts +111 -0
  82. package/dist/components/navigation-menu.d.ts.map +1 -0
  83. package/dist/components/navigation-menu.js +102 -0
  84. package/dist/components/number-input.d.ts +106 -0
  85. package/dist/components/number-input.d.ts.map +1 -0
  86. package/dist/components/number-input.js +178 -0
  87. package/dist/components/pagination.d.ts +113 -0
  88. package/dist/components/pagination.d.ts.map +1 -0
  89. package/dist/components/pagination.js +135 -0
  90. package/dist/components/password-input.d.ts +64 -0
  91. package/dist/components/password-input.d.ts.map +1 -0
  92. package/dist/components/password-input.js +52 -0
  93. package/dist/components/pin-input.d.ts +89 -0
  94. package/dist/components/pin-input.d.ts.map +1 -0
  95. package/dist/components/pin-input.js +139 -0
  96. package/dist/components/popover.d.ts +116 -0
  97. package/dist/components/popover.d.ts.map +1 -0
  98. package/dist/components/popover.js +146 -0
  99. package/dist/components/presence.d.ts +71 -0
  100. package/dist/components/presence.d.ts.map +1 -0
  101. package/dist/components/presence.js +57 -0
  102. package/dist/components/progress.d.ts +74 -0
  103. package/dist/components/progress.d.ts.map +1 -0
  104. package/dist/components/progress.js +80 -0
  105. package/dist/components/qr-code.d.ts +114 -0
  106. package/dist/components/qr-code.d.ts.map +1 -0
  107. package/dist/components/qr-code.js +108 -0
  108. package/dist/components/radio-group.d.ts +89 -0
  109. package/dist/components/radio-group.d.ts.map +1 -0
  110. package/dist/components/radio-group.js +161 -0
  111. package/dist/components/rating-group.d.ts +88 -0
  112. package/dist/components/rating-group.d.ts.map +1 -0
  113. package/dist/components/rating-group.js +122 -0
  114. package/dist/components/scroll-area.d.ts +124 -0
  115. package/dist/components/scroll-area.d.ts.map +1 -0
  116. package/dist/components/scroll-area.js +152 -0
  117. package/dist/components/select.d.ts +161 -0
  118. package/dist/components/select.d.ts.map +1 -0
  119. package/dist/components/select.js +333 -0
  120. package/dist/components/signature-pad.d.ts +138 -0
  121. package/dist/components/signature-pad.d.ts.map +1 -0
  122. package/dist/components/signature-pad.js +142 -0
  123. package/dist/components/slider.d.ts +117 -0
  124. package/dist/components/slider.d.ts.map +1 -0
  125. package/dist/components/slider.js +210 -0
  126. package/dist/components/splitter.d.ts +87 -0
  127. package/dist/components/splitter.d.ts.map +1 -0
  128. package/dist/components/splitter.js +119 -0
  129. package/dist/components/steps.d.ts +104 -0
  130. package/dist/components/steps.d.ts.map +1 -0
  131. package/dist/components/steps.js +133 -0
  132. package/dist/components/switch.d.ts +66 -0
  133. package/dist/components/switch.d.ts.map +1 -0
  134. package/dist/components/switch.js +59 -0
  135. package/dist/components/tabs.d.ts +146 -0
  136. package/dist/components/tabs.d.ts.map +1 -0
  137. package/dist/components/tabs.js +244 -0
  138. package/dist/components/tags-input.d.ts +118 -0
  139. package/dist/components/tags-input.d.ts.map +1 -0
  140. package/dist/components/tags-input.js +168 -0
  141. package/dist/components/time-picker.d.ts +121 -0
  142. package/dist/components/time-picker.d.ts.map +1 -0
  143. package/dist/components/time-picker.js +147 -0
  144. package/dist/components/timer.d.ts +131 -0
  145. package/dist/components/timer.d.ts.map +1 -0
  146. package/dist/components/timer.js +117 -0
  147. package/dist/components/toast.d.ts +119 -0
  148. package/dist/components/toast.d.ts.map +1 -0
  149. package/dist/components/toast.js +102 -0
  150. package/dist/components/toc.d.ts +119 -0
  151. package/dist/components/toc.d.ts.map +1 -0
  152. package/dist/components/toc.js +107 -0
  153. package/dist/components/toggle-group.d.ts +80 -0
  154. package/dist/components/toggle-group.d.ts.map +1 -0
  155. package/dist/components/toggle-group.js +93 -0
  156. package/dist/components/toggle.d.ts +47 -0
  157. package/dist/components/toggle.d.ts.map +1 -0
  158. package/dist/components/toggle.js +41 -0
  159. package/dist/components/tooltip.d.ts +92 -0
  160. package/dist/components/tooltip.d.ts.map +1 -0
  161. package/dist/components/tooltip.js +147 -0
  162. package/dist/components/tour.d.ts +145 -0
  163. package/dist/components/tour.d.ts.map +1 -0
  164. package/dist/components/tour.js +133 -0
  165. package/dist/components/tree-view.d.ts +216 -0
  166. package/dist/components/tree-view.d.ts.map +1 -0
  167. package/dist/components/tree-view.js +293 -0
  168. package/dist/index.d.ts +3 -0
  169. package/dist/index.d.ts.map +1 -0
  170. package/dist/index.js +4 -0
  171. package/dist/patterns/confirm-dialog.d.ts +92 -0
  172. package/dist/patterns/confirm-dialog.d.ts.map +1 -0
  173. package/dist/patterns/confirm-dialog.js +92 -0
  174. package/dist/patterns/index.d.ts +3 -0
  175. package/dist/patterns/index.d.ts.map +1 -0
  176. package/dist/patterns/index.js +1 -0
  177. package/dist/utils/anatomy.d.ts +40 -0
  178. package/dist/utils/anatomy.d.ts.map +1 -0
  179. package/dist/utils/anatomy.js +41 -0
  180. package/dist/utils/aria-hidden.d.ts +12 -0
  181. package/dist/utils/aria-hidden.d.ts.map +1 -0
  182. package/dist/utils/aria-hidden.js +72 -0
  183. package/dist/utils/dismissable.d.ts +25 -0
  184. package/dist/utils/dismissable.d.ts.map +1 -0
  185. package/dist/utils/dismissable.js +65 -0
  186. package/dist/utils/dom.d.ts +8 -0
  187. package/dist/utils/dom.d.ts.map +1 -0
  188. package/dist/utils/dom.js +21 -0
  189. package/dist/utils/floating.d.ts +44 -0
  190. package/dist/utils/floating.d.ts.map +1 -0
  191. package/dist/utils/floating.js +44 -0
  192. package/dist/utils/focus-trap.d.ts +18 -0
  193. package/dist/utils/focus-trap.d.ts.map +1 -0
  194. package/dist/utils/focus-trap.js +85 -0
  195. package/dist/utils/focusables.d.ts +6 -0
  196. package/dist/utils/focusables.d.ts.map +1 -0
  197. package/dist/utils/focusables.js +65 -0
  198. package/dist/utils/index.d.ts +18 -0
  199. package/dist/utils/index.d.ts.map +1 -0
  200. package/dist/utils/index.js +10 -0
  201. package/dist/utils/interact-outside.d.ts +26 -0
  202. package/dist/utils/interact-outside.d.ts.map +1 -0
  203. package/dist/utils/interact-outside.js +46 -0
  204. package/dist/utils/remove-scroll.d.ts +8 -0
  205. package/dist/utils/remove-scroll.d.ts.map +1 -0
  206. package/dist/utils/remove-scroll.js +37 -0
  207. package/dist/utils/tree-collection.d.ts +61 -0
  208. package/dist/utils/tree-collection.d.ts.map +1 -0
  209. package/dist/utils/tree-collection.js +137 -0
  210. package/dist/utils/typeahead.d.ts +49 -0
  211. package/dist/utils/typeahead.d.ts.map +1 -0
  212. package/dist/utils/typeahead.js +81 -0
  213. package/package.json +282 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Franco Ponticelli
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,143 @@
1
+ # @llui/components
2
+
3
+ 54 headless UI components for [LLui](../../README.md). Pure state machines with no DOM opinions — you own the markup and styling via `data-scope` / `data-part` attributes.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pnpm add @llui/components
9
+ ```
10
+
11
+ Peer dependency: `@llui/dom`.
12
+
13
+ ## Usage
14
+
15
+ Each component exports `init`, `update`, `connect`, and a barrel object:
16
+
17
+ ```typescript
18
+ import { component, div, button } from '@llui/dom'
19
+ import { tabs } from '@llui/components/tabs'
20
+
21
+ type State = { tabs: tabs.TabsState }
22
+ type Msg = { type: 'tabs'; msg: tabs.TabsMsg }
23
+
24
+ const App = component<State, Msg, never>({
25
+ name: 'App',
26
+ init: () => [{ tabs: tabs.init({ items: ['a', 'b', 'c'], value: 'a' }) }, []],
27
+ update: (s, m) => {
28
+ const [t] = tabs.update(s.tabs, m.msg)
29
+ return [{ tabs: t }, []]
30
+ },
31
+ view: ({ send, text }) => {
32
+ const t = tabs.connect<State>(
33
+ (s) => s.tabs,
34
+ (m) => send({ type: 'tabs', msg: m }),
35
+ { id: 'demo' },
36
+ )
37
+ return [
38
+ div({ ...t.root }, [
39
+ div({ ...t.list }, [
40
+ button({ ...t.item('a').trigger }, [text('Tab A')]),
41
+ button({ ...t.item('b').trigger }, [text('Tab B')]),
42
+ button({ ...t.item('c').trigger }, [text('Tab C')]),
43
+ ]),
44
+ div({ ...t.item('a').panel }, [text('Content A')]),
45
+ div({ ...t.item('b').panel }, [text('Content B')]),
46
+ div({ ...t.item('c').panel }, [text('Content C')]),
47
+ ]),
48
+ ]
49
+ },
50
+ })
51
+ ```
52
+
53
+ ### Pattern
54
+
55
+ 1. **`init(opts?)`** — creates the initial state
56
+ 2. **`update(state, msg)`** — pure reducer, returns `[newState, effects[]]`
57
+ 3. **`connect(get, send, opts?)`** — returns parts objects with reactive props, ARIA attributes, and event handlers. Spread parts onto your elements: `div({ ...parts.root }, [...])`
58
+ 4. **Overlay helpers** (dialog, popover, menu, etc.) — `overlay()` wires up portals, focus traps, dismiss layers, and positioning
59
+
60
+ ### Composition with `sliceHandler`
61
+
62
+ ```typescript
63
+ import { mergeHandlers, sliceHandler } from '@llui/dom'
64
+
65
+ const update = mergeHandlers<State, Msg, never>(
66
+ sliceHandler({
67
+ get: (s) => s.tabs,
68
+ set: (s, v) => ({ ...s, tabs: v }),
69
+ narrow: (m) => (m.type === 'tabs' ? m.msg : null),
70
+ sub: tabs.update,
71
+ }),
72
+ // ... more slices
73
+ )
74
+ ```
75
+
76
+ ## Components (54)
77
+
78
+ ### Form controls
79
+
80
+ accordion, checkbox, collapsible, editable, number-input, password-input, pin-input, radio-group, rating-group, slider, switch, tabs, tags-input, toggle, toggle-group
81
+
82
+ ### Overlays
83
+
84
+ alert-dialog, combobox, context-menu, dialog, drawer, hover-card, menu, navigation-menu, popover, select, toast, tooltip, tour
85
+
86
+ ### Data display
87
+
88
+ async-list, avatar, carousel, cascade-select, listbox, pagination, progress, qr-code, scroll-area, steps, toc, tree-view
89
+
90
+ ### Pickers
91
+
92
+ color-picker, date-input, date-picker, time-picker, angle-slider
93
+
94
+ ### Media / canvas
95
+
96
+ file-upload, floating-panel, image-cropper, marquee, presence, signature-pad, timer
97
+
98
+ ### Patterns
99
+
100
+ `@llui/components/patterns/confirm-dialog` — pre-wired alert-dialog for destructive confirmations.
101
+
102
+ ## Utilities
103
+
104
+ Shared helpers used internally and exported for advanced use:
105
+
106
+ | Utility | Purpose |
107
+ | ---------------- | ------------------------------------------------------------------------ |
108
+ | `typeahead` | First-letter search across menu, select, listbox, tree-view |
109
+ | `TreeCollection` | Indexed tree traversal — visibleItems, labels, indeterminate computation |
110
+ | `floating` | `@floating-ui/dom` wrapper for popover/menu positioning |
111
+ | `focus-trap` | Stack-based focus containment for modals |
112
+ | `dismissable` | Esc / outside-click dismiss layer stack |
113
+ | `aria-hidden` | `aria-hidden` on siblings of a modal for screen readers |
114
+ | `remove-scroll` | Body scroll lock for modals/drawers |
115
+
116
+ ## Sub-path imports
117
+
118
+ Every component has its own entry point for tree-shaking:
119
+
120
+ ```typescript
121
+ import { tabs } from '@llui/components/tabs'
122
+ import { dialog } from '@llui/components/dialog'
123
+ import { timer } from '@llui/components/timer'
124
+ ```
125
+
126
+ ## Validation
127
+
128
+ Input components accept an optional `validate` callback on `ConnectOptions` that gates state changes:
129
+
130
+ ```typescript
131
+ const parts = editable.connect<S>(get, send, {
132
+ validate: (value) => {
133
+ if (value.length < 3) return ['Too short']
134
+ return null // valid
135
+ },
136
+ })
137
+ ```
138
+
139
+ Supported on: editable, number-input, tags-input, pin-input, file-upload.
140
+
141
+ ## License
142
+
143
+ MIT
@@ -0,0 +1,115 @@
1
+ import type { Send } from '@llui/dom';
2
+ /**
3
+ * Accordion — a stack of expandable panels. Items are identified by a string
4
+ * value. Either a single item is expandable at a time (default) or many
5
+ * (`multiple: true`). `collapsible: false` prevents closing the only open
6
+ * item in single mode.
7
+ *
8
+ * Items themselves are provided by the user's view (accordion is agnostic to
9
+ * item data). The `connect()` API returns a `root` prop set and an `item(value)`
10
+ * factory that produces `trigger` and `content` prop sets scoped to that item.
11
+ */
12
+ export interface AccordionState {
13
+ /** Values of currently-expanded items. */
14
+ value: string[];
15
+ multiple: boolean;
16
+ collapsible: boolean;
17
+ disabled: boolean;
18
+ /** Ordered list of item values (for keyboard navigation). */
19
+ items: string[];
20
+ }
21
+ export type AccordionMsg = {
22
+ type: 'toggle';
23
+ value: string;
24
+ } | {
25
+ type: 'open';
26
+ value: string;
27
+ } | {
28
+ type: 'close';
29
+ value: string;
30
+ } | {
31
+ type: 'setValue';
32
+ value: string[];
33
+ } | {
34
+ type: 'setItems';
35
+ items: string[];
36
+ } | {
37
+ type: 'focusNext';
38
+ value: string;
39
+ } | {
40
+ type: 'focusPrev';
41
+ value: string;
42
+ } | {
43
+ type: 'focusFirst';
44
+ } | {
45
+ type: 'focusLast';
46
+ };
47
+ export interface AccordionInit {
48
+ value?: string[];
49
+ multiple?: boolean;
50
+ collapsible?: boolean;
51
+ disabled?: boolean;
52
+ items?: string[];
53
+ }
54
+ export declare function init(opts?: AccordionInit): AccordionState;
55
+ export declare function update(state: AccordionState, msg: AccordionMsg): [AccordionState, never[]];
56
+ export interface AccordionItemParts<S> {
57
+ trigger: {
58
+ type: 'button';
59
+ 'aria-expanded': (s: S) => boolean;
60
+ 'aria-controls': string;
61
+ id: string;
62
+ 'data-state': (s: S) => 'open' | 'closed';
63
+ 'data-disabled': (s: S) => '' | undefined;
64
+ disabled: (s: S) => boolean;
65
+ 'data-scope': 'accordion';
66
+ 'data-part': 'trigger';
67
+ 'data-value': string;
68
+ onClick: (e: MouseEvent) => void;
69
+ onKeyDown: (e: KeyboardEvent) => void;
70
+ };
71
+ content: {
72
+ role: 'region';
73
+ id: string;
74
+ 'aria-labelledby': string;
75
+ 'data-state': (s: S) => 'open' | 'closed';
76
+ 'data-scope': 'accordion';
77
+ 'data-part': 'content';
78
+ hidden: (s: S) => boolean;
79
+ };
80
+ item: {
81
+ 'data-state': (s: S) => 'open' | 'closed';
82
+ 'data-disabled': (s: S) => '' | undefined;
83
+ 'data-scope': 'accordion';
84
+ 'data-part': 'item';
85
+ 'data-value': string;
86
+ };
87
+ }
88
+ export interface AccordionParts<S> {
89
+ root: {
90
+ role: 'region';
91
+ 'data-scope': 'accordion';
92
+ 'data-part': 'root';
93
+ 'data-orientation': 'vertical';
94
+ };
95
+ item: (value: string) => AccordionItemParts<S>;
96
+ }
97
+ export interface ConnectOptions {
98
+ /** Namespace prefix for part ids (for ARIA wiring). Should be unique per instance. */
99
+ id: string;
100
+ }
101
+ export declare function connect<S>(get: (s: S) => AccordionState, send: Send<AccordionMsg>, opts: ConnectOptions): AccordionParts<S>;
102
+ /**
103
+ * Helper: compute the next/prev item value given a focus message + current state.
104
+ * Users' view/onMount can use this to move DOM focus to the correct trigger.
105
+ */
106
+ export declare function focusTarget(state: AccordionState, msg: Extract<AccordionMsg, {
107
+ type: `focus${string}`;
108
+ }>): string | null;
109
+ export declare const accordion: {
110
+ init: typeof init;
111
+ update: typeof update;
112
+ connect: typeof connect;
113
+ focusTarget: typeof focusTarget;
114
+ };
115
+ //# sourceMappingURL=accordion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accordion.d.ts","sourceRoot":"","sources":["../../src/components/accordion.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,138 @@
1
+ export function init(opts = {}) {
2
+ return {
3
+ value: opts.value ?? [],
4
+ multiple: opts.multiple ?? false,
5
+ collapsible: opts.collapsible ?? true,
6
+ disabled: opts.disabled ?? false,
7
+ items: opts.items ?? [],
8
+ };
9
+ }
10
+ function toggleValue(state, value) {
11
+ const isOpen = state.value.includes(value);
12
+ if (state.multiple) {
13
+ return isOpen ? state.value.filter((v) => v !== value) : [...state.value, value];
14
+ }
15
+ // single mode
16
+ if (isOpen) {
17
+ return state.collapsible ? [] : state.value;
18
+ }
19
+ return [value];
20
+ }
21
+ export function update(state, msg) {
22
+ if (state.disabled)
23
+ return [state, []];
24
+ switch (msg.type) {
25
+ case 'toggle':
26
+ return [{ ...state, value: toggleValue(state, msg.value) }, []];
27
+ case 'open':
28
+ if (state.value.includes(msg.value))
29
+ return [state, []];
30
+ return [{ ...state, value: state.multiple ? [...state.value, msg.value] : [msg.value] }, []];
31
+ case 'close':
32
+ if (!state.value.includes(msg.value))
33
+ return [state, []];
34
+ if (!state.multiple && !state.collapsible)
35
+ return [state, []];
36
+ return [{ ...state, value: state.value.filter((v) => v !== msg.value) }, []];
37
+ case 'setValue':
38
+ return [{ ...state, value: msg.value }, []];
39
+ case 'setItems':
40
+ return [{ ...state, items: msg.items }, []];
41
+ // Focus messages don't mutate state but are emitted so user handlers can respond.
42
+ case 'focusNext':
43
+ case 'focusPrev':
44
+ case 'focusFirst':
45
+ case 'focusLast':
46
+ return [state, []];
47
+ }
48
+ }
49
+ export function connect(get, send, opts) {
50
+ const base = opts.id;
51
+ const triggerId = (v) => `${base}:trigger:${v}`;
52
+ const contentId = (v) => `${base}:content:${v}`;
53
+ return {
54
+ root: {
55
+ role: 'region',
56
+ 'data-scope': 'accordion',
57
+ 'data-part': 'root',
58
+ 'data-orientation': 'vertical',
59
+ },
60
+ item: (value) => ({
61
+ trigger: {
62
+ type: 'button',
63
+ 'aria-expanded': (s) => get(s).value.includes(value),
64
+ 'aria-controls': contentId(value),
65
+ id: triggerId(value),
66
+ 'data-state': (s) => (get(s).value.includes(value) ? 'open' : 'closed'),
67
+ 'data-disabled': (s) => (get(s).disabled ? '' : undefined),
68
+ disabled: (s) => get(s).disabled,
69
+ 'data-scope': 'accordion',
70
+ 'data-part': 'trigger',
71
+ 'data-value': value,
72
+ onClick: () => send({ type: 'toggle', value }),
73
+ onKeyDown: (e) => {
74
+ switch (e.key) {
75
+ case 'ArrowDown':
76
+ e.preventDefault();
77
+ send({ type: 'focusNext', value });
78
+ return;
79
+ case 'ArrowUp':
80
+ e.preventDefault();
81
+ send({ type: 'focusPrev', value });
82
+ return;
83
+ case 'Home':
84
+ e.preventDefault();
85
+ send({ type: 'focusFirst' });
86
+ return;
87
+ case 'End':
88
+ e.preventDefault();
89
+ send({ type: 'focusLast' });
90
+ return;
91
+ case ' ':
92
+ case 'Enter':
93
+ e.preventDefault();
94
+ send({ type: 'toggle', value });
95
+ return;
96
+ }
97
+ },
98
+ },
99
+ content: {
100
+ role: 'region',
101
+ id: contentId(value),
102
+ 'aria-labelledby': triggerId(value),
103
+ 'data-state': (s) => (get(s).value.includes(value) ? 'open' : 'closed'),
104
+ 'data-scope': 'accordion',
105
+ 'data-part': 'content',
106
+ hidden: (s) => !get(s).value.includes(value),
107
+ },
108
+ item: {
109
+ 'data-state': (s) => (get(s).value.includes(value) ? 'open' : 'closed'),
110
+ 'data-disabled': (s) => (get(s).disabled ? '' : undefined),
111
+ 'data-scope': 'accordion',
112
+ 'data-part': 'item',
113
+ 'data-value': value,
114
+ },
115
+ }),
116
+ };
117
+ }
118
+ /**
119
+ * Helper: compute the next/prev item value given a focus message + current state.
120
+ * Users' view/onMount can use this to move DOM focus to the correct trigger.
121
+ */
122
+ export function focusTarget(state, msg) {
123
+ const items = state.items;
124
+ if (items.length === 0)
125
+ return null;
126
+ if (msg.type === 'focusFirst')
127
+ return items[0];
128
+ if (msg.type === 'focusLast')
129
+ return items[items.length - 1];
130
+ const idx = items.indexOf(msg.value);
131
+ if (idx === -1)
132
+ return null;
133
+ if (msg.type === 'focusNext')
134
+ return items[(idx + 1) % items.length];
135
+ // focusPrev
136
+ return items[(idx - 1 + items.length) % items.length];
137
+ }
138
+ export const accordion = { init, update, connect, focusTarget };
@@ -0,0 +1,45 @@
1
+ import type { Send, TransitionOptions } from '@llui/dom';
2
+ import { init, update, type DialogState, type DialogMsg, type DialogParts, type ConnectOptions as DialogConnectOptions } from './dialog';
3
+ /**
4
+ * Alert dialog — a variant of dialog for destructive confirmations or
5
+ * blocking messages. Uses `role="alertdialog"` and defaults to:
6
+ * - `closeOnOutsideClick: false` (user must choose an action explicitly)
7
+ *
8
+ * Shares state, messages, and part structure with `dialog`. Render a
9
+ * `cancelTrigger` alongside the `closeTrigger` and let the application
10
+ * dispatch a follow-up action after the dialog closes.
11
+ */
12
+ export type { DialogState as AlertDialogState, DialogMsg as AlertDialogMsg };
13
+ export { init, update };
14
+ export interface AlertDialogConnectOptions extends Omit<DialogConnectOptions, 'role'> {
15
+ /** Accessible label for the cancel button (default: 'Cancel'). */
16
+ cancelLabel?: string;
17
+ /** Accessible label for the confirm button (default: 'Confirm'). */
18
+ confirmLabel?: string;
19
+ }
20
+ export type AlertDialogParts<S> = DialogParts<S>;
21
+ export declare function connect<S>(get: (s: S) => DialogState, send: Send<DialogMsg>, opts: AlertDialogConnectOptions): AlertDialogParts<S>;
22
+ export interface AlertDialogOverlayOptions<S> {
23
+ get: (s: S) => DialogState;
24
+ send: Send<DialogMsg>;
25
+ parts: AlertDialogParts<S>;
26
+ content: () => Node[];
27
+ transition?: TransitionOptions;
28
+ closeOnEscape?: boolean;
29
+ /** Whether outside-click should dismiss (default: false for alert dialogs). */
30
+ closeOnOutsideClick?: boolean;
31
+ trapFocus?: boolean;
32
+ lockScroll?: boolean;
33
+ hideSiblings?: boolean;
34
+ target?: string | HTMLElement;
35
+ initialFocus?: Element | (() => Element | null);
36
+ restoreFocus?: boolean;
37
+ }
38
+ export declare function overlay<S>(opts: AlertDialogOverlayOptions<S>): Node[];
39
+ export declare const alertDialog: {
40
+ init: typeof init;
41
+ update: typeof update;
42
+ connect: typeof connect;
43
+ overlay: typeof overlay;
44
+ };
45
+ //# sourceMappingURL=alert-dialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alert-dialog.d.ts","sourceRoot":"","sources":["../../src/components/alert-dialog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AACxD,OAAO,EACL,IAAI,EACJ,MAAM,EAGN,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,cAAc,IAAI,oBAAoB,EAC5C,MAAM,UAAU,CAAA;AAEjB;;;;;;;;GAQG;AAEH,YAAY,EAAE,WAAW,IAAI,gBAAgB,EAAE,SAAS,IAAI,cAAc,EAAE,CAAA;AAE5E,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;AAEvB,MAAM,WAAW,yBAA0B,SAAQ,IAAI,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACnF,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,oEAAoE;IACpE,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAA;AAEhD,wBAAgB,OAAO,CAAC,CAAC,EACvB,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,WAAW,EAC1B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EACrB,IAAI,EAAE,yBAAyB,GAC9B,gBAAgB,CAAC,CAAC,CAAC,CAErB;AAED,MAAM,WAAW,yBAAyB,CAAC,CAAC;IAC1C,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,WAAW,CAAA;IAC1B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;IACrB,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAA;IAC1B,OAAO,EAAE,MAAM,IAAI,EAAE,CAAA;IACrB,UAAU,CAAC,EAAE,iBAAiB,CAAA;IAC9B,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,+EAA+E;IAC/E,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,CAAA;IAC7B,YAAY,CAAC,EAAE,OAAO,GAAG,CAAC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAA;IAC/C,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,yBAAyB,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,CAKrE;AAED,eAAO,MAAM,WAAW;;;;;CAAqC,CAAA"}
@@ -0,0 +1,12 @@
1
+ import { init, update, connect as dialogConnect, overlay as dialogOverlay, } from './dialog';
2
+ export { init, update };
3
+ export function connect(get, send, opts) {
4
+ return dialogConnect(get, send, { ...opts, role: 'alertdialog' });
5
+ }
6
+ export function overlay(opts) {
7
+ return dialogOverlay({
8
+ ...opts,
9
+ closeOnOutsideClick: opts.closeOnOutsideClick ?? false,
10
+ });
11
+ }
12
+ export const alertDialog = { init, update, connect, overlay };
@@ -0,0 +1,121 @@
1
+ import type { Send } from '@llui/dom';
2
+ /**
3
+ * Angle slider — a circular input that selects a value in 0..360 degrees
4
+ * by dragging a thumb around a control. The state machine tracks the
5
+ * current angle; the view layer computes angles from pointer positions
6
+ * (helpers exported for that purpose).
7
+ *
8
+ * Typical view wiring: on pointerdown/pointermove, read the control
9
+ * element's bounding rect, compute the angle from `(pointerX, pointerY)`
10
+ * to the rect center via `angleFromPoint()`, and dispatch `setValue`.
11
+ *
12
+ * Keyboard: Arrow keys adjust by `step`; Home/End jump to min/max;
13
+ * PageUp/PageDown adjust by `step * 10`.
14
+ */
15
+ export interface AngleSliderState {
16
+ value: number;
17
+ min: number;
18
+ max: number;
19
+ step: number;
20
+ disabled: boolean;
21
+ readOnly: boolean;
22
+ }
23
+ export type AngleSliderMsg = {
24
+ type: 'setValue';
25
+ value: number;
26
+ } | {
27
+ type: 'increment';
28
+ steps?: number;
29
+ } | {
30
+ type: 'decrement';
31
+ steps?: number;
32
+ } | {
33
+ type: 'setMin';
34
+ min: number;
35
+ } | {
36
+ type: 'setMax';
37
+ max: number;
38
+ };
39
+ export interface AngleSliderInit {
40
+ value?: number;
41
+ min?: number;
42
+ max?: number;
43
+ step?: number;
44
+ disabled?: boolean;
45
+ readOnly?: boolean;
46
+ }
47
+ export declare function init(opts?: AngleSliderInit): AngleSliderState;
48
+ export declare function update(state: AngleSliderState, msg: AngleSliderMsg): [AngleSliderState, never[]];
49
+ /**
50
+ * Compute the angle in degrees from the center of a rect to a point.
51
+ * 0° = up (12 o'clock), increases clockwise. Result is in 0..360.
52
+ *
53
+ * Useful inside a pointermove handler:
54
+ * const rect = control.getBoundingClientRect()
55
+ * const angle = angleFromPoint(rect, e.clientX, e.clientY)
56
+ * send({ type: 'setValue', value: angle })
57
+ */
58
+ export declare function angleFromPoint(rect: DOMRect, x: number, y: number): number;
59
+ /** Convert an angle to (x, y) on a unit circle (radius 1 at origin). */
60
+ export declare function pointFromAngle(angleDeg: number): {
61
+ x: number;
62
+ y: number;
63
+ };
64
+ export interface AngleSliderParts<S> {
65
+ root: {
66
+ role: 'slider';
67
+ 'aria-valuemin': (s: S) => number;
68
+ 'aria-valuemax': (s: S) => number;
69
+ 'aria-valuenow': (s: S) => number;
70
+ 'aria-valuetext': (s: S) => string;
71
+ 'aria-orientation': 'horizontal';
72
+ 'aria-disabled': (s: S) => 'true' | undefined;
73
+ 'aria-readonly': (s: S) => 'true' | undefined;
74
+ tabIndex: (s: S) => number;
75
+ 'data-scope': 'angle-slider';
76
+ 'data-part': 'root';
77
+ 'data-disabled': (s: S) => '' | undefined;
78
+ onKeyDown: (e: KeyboardEvent) => void;
79
+ };
80
+ control: {
81
+ 'data-scope': 'angle-slider';
82
+ 'data-part': 'control';
83
+ };
84
+ /**
85
+ * The draggable thumb element. Its position is typically computed via
86
+ * CSS custom properties `--angle` (0..360) that the consumer sets from
87
+ * `state.value` using pointFromAngle() or a CSS `transform: rotate()`.
88
+ */
89
+ thumb: {
90
+ 'data-scope': 'angle-slider';
91
+ 'data-part': 'thumb';
92
+ 'data-value': (s: S) => string;
93
+ };
94
+ valueText: {
95
+ 'data-scope': 'angle-slider';
96
+ 'data-part': 'value-text';
97
+ };
98
+ /** A hidden input for form participation. */
99
+ hiddenInput: {
100
+ type: 'hidden';
101
+ value: (s: S) => string;
102
+ name?: string;
103
+ 'data-scope': 'angle-slider';
104
+ 'data-part': 'hidden-input';
105
+ };
106
+ }
107
+ export interface ConnectOptions {
108
+ /** Name for the hidden input (form integration). */
109
+ name?: string;
110
+ /** Formatter for aria-valuetext (default: "{value}°"). */
111
+ format?: (value: number) => string;
112
+ }
113
+ export declare function connect<S>(get: (s: S) => AngleSliderState, send: Send<AngleSliderMsg>, opts?: ConnectOptions): AngleSliderParts<S>;
114
+ export declare const angleSlider: {
115
+ init: typeof init;
116
+ update: typeof update;
117
+ connect: typeof connect;
118
+ angleFromPoint: typeof angleFromPoint;
119
+ pointFromAngle: typeof pointFromAngle;
120
+ };
121
+ //# sourceMappingURL=angle-slider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"angle-slider.d.ts","sourceRoot":"","sources":["../../src/components/angle-slider.ts"],"names":[],"mappings":"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"}