@llui/components 0.4.10 → 0.5.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.
Files changed (243) hide show
  1. package/dist/components/accordion.d.ts +13 -13
  2. package/dist/components/accordion.d.ts.map +1 -1
  3. package/dist/components/accordion.js +9 -9
  4. package/dist/components/accordion.js.map +1 -1
  5. package/dist/components/alert-dialog.d.ts +8 -8
  6. package/dist/components/alert-dialog.d.ts.map +1 -1
  7. package/dist/components/alert-dialog.js +2 -2
  8. package/dist/components/alert-dialog.js.map +1 -1
  9. package/dist/components/angle-slider.d.ts +13 -13
  10. package/dist/components/angle-slider.d.ts.map +1 -1
  11. package/dist/components/angle-slider.js +11 -11
  12. package/dist/components/angle-slider.js.map +1 -1
  13. package/dist/components/async-list.d.ts +7 -7
  14. package/dist/components/async-list.d.ts.map +1 -1
  15. package/dist/components/async-list.js +5 -8
  16. package/dist/components/async-list.js.map +1 -1
  17. package/dist/components/avatar.d.ts +9 -9
  18. package/dist/components/avatar.d.ts.map +1 -1
  19. package/dist/components/avatar.js +7 -7
  20. package/dist/components/avatar.js.map +1 -1
  21. package/dist/components/carousel.d.ts +18 -18
  22. package/dist/components/carousel.d.ts.map +1 -1
  23. package/dist/components/carousel.js +12 -12
  24. package/dist/components/carousel.js.map +1 -1
  25. package/dist/components/cascade-select.d.ts +12 -12
  26. package/dist/components/cascade-select.d.ts.map +1 -1
  27. package/dist/components/cascade-select.js +8 -8
  28. package/dist/components/cascade-select.js.map +1 -1
  29. package/dist/components/checkbox.d.ts +14 -14
  30. package/dist/components/checkbox.d.ts.map +1 -1
  31. package/dist/components/checkbox.js +12 -12
  32. package/dist/components/checkbox.js.map +1 -1
  33. package/dist/components/clipboard.d.ts +8 -8
  34. package/dist/components/clipboard.d.ts.map +1 -1
  35. package/dist/components/clipboard.js +6 -6
  36. package/dist/components/clipboard.js.map +1 -1
  37. package/dist/components/collapsible.d.ts +11 -11
  38. package/dist/components/collapsible.d.ts.map +1 -1
  39. package/dist/components/collapsible.js +9 -9
  40. package/dist/components/collapsible.js.map +1 -1
  41. package/dist/components/color-picker.d.ts +19 -19
  42. package/dist/components/color-picker.d.ts.map +1 -1
  43. package/dist/components/color-picker.js +21 -21
  44. package/dist/components/color-picker.js.map +1 -1
  45. package/dist/components/combobox.d.ts +25 -25
  46. package/dist/components/combobox.d.ts.map +1 -1
  47. package/dist/components/combobox.js +54 -59
  48. package/dist/components/combobox.js.map +1 -1
  49. package/dist/components/context-menu.d.ts +14 -14
  50. package/dist/components/context-menu.d.ts.map +1 -1
  51. package/dist/components/context-menu.js +15 -19
  52. package/dist/components/context-menu.js.map +1 -1
  53. package/dist/components/date-input.d.ts +13 -13
  54. package/dist/components/date-input.d.ts.map +1 -1
  55. package/dist/components/date-input.js +11 -11
  56. package/dist/components/date-input.js.map +1 -1
  57. package/dist/components/date-picker.d.ts +11 -11
  58. package/dist/components/date-picker.d.ts.map +1 -1
  59. package/dist/components/date-picker.js +7 -7
  60. package/dist/components/date-picker.js.map +1 -1
  61. package/dist/components/dialog.d.ts +15 -15
  62. package/dist/components/dialog.d.ts.map +1 -1
  63. package/dist/components/dialog.js +45 -50
  64. package/dist/components/dialog.js.map +1 -1
  65. package/dist/components/drawer.d.ts +13 -13
  66. package/dist/components/drawer.d.ts.map +1 -1
  67. package/dist/components/drawer.js +44 -49
  68. package/dist/components/drawer.js.map +1 -1
  69. package/dist/components/editable.d.ts +11 -11
  70. package/dist/components/editable.d.ts.map +1 -1
  71. package/dist/components/editable.js +9 -9
  72. package/dist/components/editable.js.map +1 -1
  73. package/dist/components/file-upload.d.ts +19 -19
  74. package/dist/components/file-upload.d.ts.map +1 -1
  75. package/dist/components/file-upload.js +14 -14
  76. package/dist/components/file-upload.js.map +1 -1
  77. package/dist/components/floating-panel.d.ts +14 -14
  78. package/dist/components/floating-panel.d.ts.map +1 -1
  79. package/dist/components/floating-panel.js +13 -14
  80. package/dist/components/floating-panel.js.map +1 -1
  81. package/dist/components/form.d.ts +9 -9
  82. package/dist/components/form.d.ts.map +1 -1
  83. package/dist/components/form.js +7 -7
  84. package/dist/components/form.js.map +1 -1
  85. package/dist/components/hover-card.d.ts +9 -9
  86. package/dist/components/hover-card.d.ts.map +1 -1
  87. package/dist/components/hover-card.js +12 -13
  88. package/dist/components/hover-card.js.map +1 -1
  89. package/dist/components/image-cropper.d.ts +8 -8
  90. package/dist/components/image-cropper.d.ts.map +1 -1
  91. package/dist/components/image-cropper.js +7 -8
  92. package/dist/components/image-cropper.js.map +1 -1
  93. package/dist/components/in-view.d.ts +6 -6
  94. package/dist/components/in-view.d.ts.map +1 -1
  95. package/dist/components/in-view.js +2 -2
  96. package/dist/components/in-view.js.map +1 -1
  97. package/dist/components/listbox.d.ts +16 -16
  98. package/dist/components/listbox.d.ts.map +1 -1
  99. package/dist/components/listbox.js +16 -16
  100. package/dist/components/listbox.js.map +1 -1
  101. package/dist/components/marquee.d.ts +8 -8
  102. package/dist/components/marquee.d.ts.map +1 -1
  103. package/dist/components/marquee.js +8 -11
  104. package/dist/components/marquee.js.map +1 -1
  105. package/dist/components/menu.d.ts +15 -15
  106. package/dist/components/menu.d.ts.map +1 -1
  107. package/dist/components/menu.js +16 -17
  108. package/dist/components/menu.js.map +1 -1
  109. package/dist/components/navigation-menu.d.ts +12 -12
  110. package/dist/components/navigation-menu.d.ts.map +1 -1
  111. package/dist/components/navigation-menu.js +8 -8
  112. package/dist/components/navigation-menu.js.map +1 -1
  113. package/dist/components/number-input.d.ts +18 -18
  114. package/dist/components/number-input.d.ts.map +1 -1
  115. package/dist/components/number-input.js +16 -20
  116. package/dist/components/number-input.js.map +1 -1
  117. package/dist/components/pagination.d.ts +13 -13
  118. package/dist/components/pagination.d.ts.map +1 -1
  119. package/dist/components/pagination.js +11 -17
  120. package/dist/components/pagination.js.map +1 -1
  121. package/dist/components/password-input.d.ts +11 -11
  122. package/dist/components/password-input.d.ts.map +1 -1
  123. package/dist/components/password-input.js +11 -11
  124. package/dist/components/password-input.js.map +1 -1
  125. package/dist/components/pin-input.d.ts +9 -9
  126. package/dist/components/pin-input.d.ts.map +1 -1
  127. package/dist/components/pin-input.js +9 -9
  128. package/dist/components/pin-input.js.map +1 -1
  129. package/dist/components/popover.d.ts +11 -11
  130. package/dist/components/popover.d.ts.map +1 -1
  131. package/dist/components/popover.js +61 -60
  132. package/dist/components/popover.js.map +1 -1
  133. package/dist/components/presence.d.ts +7 -5
  134. package/dist/components/presence.d.ts.map +1 -1
  135. package/dist/components/presence.js +5 -3
  136. package/dist/components/presence.js.map +1 -1
  137. package/dist/components/progress.d.ts +14 -14
  138. package/dist/components/progress.d.ts.map +1 -1
  139. package/dist/components/progress.js +12 -12
  140. package/dist/components/progress.js.map +1 -1
  141. package/dist/components/qr-code.d.ts +7 -7
  142. package/dist/components/qr-code.d.ts.map +1 -1
  143. package/dist/components/qr-code.js +7 -7
  144. package/dist/components/qr-code.js.map +1 -1
  145. package/dist/components/radio-group.d.ts +15 -15
  146. package/dist/components/radio-group.d.ts.map +1 -1
  147. package/dist/components/radio-group.js +12 -13
  148. package/dist/components/radio-group.js.map +1 -1
  149. package/dist/components/rating-group.d.ts +13 -13
  150. package/dist/components/rating-group.d.ts.map +1 -1
  151. package/dist/components/rating-group.js +10 -11
  152. package/dist/components/rating-group.js.map +1 -1
  153. package/dist/components/scroll-area.d.ts +10 -10
  154. package/dist/components/scroll-area.d.ts.map +1 -1
  155. package/dist/components/scroll-area.js +10 -15
  156. package/dist/components/scroll-area.js.map +1 -1
  157. package/dist/components/select.d.ts +26 -26
  158. package/dist/components/select.d.ts.map +1 -1
  159. package/dist/components/select.js +29 -33
  160. package/dist/components/select.js.map +1 -1
  161. package/dist/components/signature-pad.d.ts +12 -12
  162. package/dist/components/signature-pad.d.ts.map +1 -1
  163. package/dist/components/signature-pad.js +10 -10
  164. package/dist/components/signature-pad.js.map +1 -1
  165. package/dist/components/slider.d.ts +22 -22
  166. package/dist/components/slider.d.ts.map +1 -1
  167. package/dist/components/slider.js +17 -17
  168. package/dist/components/slider.js.map +1 -1
  169. package/dist/components/sortable.d.ts +11 -11
  170. package/dist/components/sortable.d.ts.map +1 -1
  171. package/dist/components/sortable.js +20 -20
  172. package/dist/components/sortable.js.map +1 -1
  173. package/dist/components/splitter.d.ts +15 -15
  174. package/dist/components/splitter.d.ts.map +1 -1
  175. package/dist/components/splitter.js +15 -15
  176. package/dist/components/splitter.js.map +1 -1
  177. package/dist/components/steps.d.ts +14 -14
  178. package/dist/components/steps.d.ts.map +1 -1
  179. package/dist/components/steps.js +10 -16
  180. package/dist/components/steps.js.map +1 -1
  181. package/dist/components/switch.d.ts +12 -12
  182. package/dist/components/switch.d.ts.map +1 -1
  183. package/dist/components/switch.js +10 -10
  184. package/dist/components/switch.js.map +1 -1
  185. package/dist/components/tabs.d.ts +15 -15
  186. package/dist/components/tabs.d.ts.map +1 -1
  187. package/dist/components/tabs.js +11 -11
  188. package/dist/components/tabs.js.map +1 -1
  189. package/dist/components/tags-input.d.ts +14 -14
  190. package/dist/components/tags-input.d.ts.map +1 -1
  191. package/dist/components/tags-input.js +10 -10
  192. package/dist/components/tags-input.js.map +1 -1
  193. package/dist/components/theme-switch.d.ts +5 -5
  194. package/dist/components/theme-switch.d.ts.map +1 -1
  195. package/dist/components/theme-switch.js +3 -3
  196. package/dist/components/theme-switch.js.map +1 -1
  197. package/dist/components/time-picker.d.ts +19 -19
  198. package/dist/components/time-picker.d.ts.map +1 -1
  199. package/dist/components/time-picker.js +17 -17
  200. package/dist/components/time-picker.js.map +1 -1
  201. package/dist/components/timer.d.ts +10 -10
  202. package/dist/components/timer.d.ts.map +1 -1
  203. package/dist/components/timer.js +8 -8
  204. package/dist/components/timer.js.map +1 -1
  205. package/dist/components/toast.d.ts +8 -8
  206. package/dist/components/toast.d.ts.map +1 -1
  207. package/dist/components/toast.js +4 -4
  208. package/dist/components/toast.js.map +1 -1
  209. package/dist/components/toc.d.ts +12 -12
  210. package/dist/components/toc.d.ts.map +1 -1
  211. package/dist/components/toc.js +8 -8
  212. package/dist/components/toc.js.map +1 -1
  213. package/dist/components/toggle-group.d.ts +13 -13
  214. package/dist/components/toggle-group.d.ts.map +1 -1
  215. package/dist/components/toggle-group.js +9 -9
  216. package/dist/components/toggle-group.js.map +1 -1
  217. package/dist/components/toggle.d.ts +8 -8
  218. package/dist/components/toggle.d.ts.map +1 -1
  219. package/dist/components/toggle.js +6 -6
  220. package/dist/components/toggle.js.map +1 -1
  221. package/dist/components/tooltip.d.ts +10 -10
  222. package/dist/components/tooltip.d.ts.map +1 -1
  223. package/dist/components/tooltip.js +13 -14
  224. package/dist/components/tooltip.js.map +1 -1
  225. package/dist/components/tour.d.ts +7 -7
  226. package/dist/components/tour.d.ts.map +1 -1
  227. package/dist/components/tour.js +5 -5
  228. package/dist/components/tour.js.map +1 -1
  229. package/dist/components/tree-view.d.ts +19 -19
  230. package/dist/components/tree-view.d.ts.map +1 -1
  231. package/dist/components/tree-view.js +23 -23
  232. package/dist/components/tree-view.js.map +1 -1
  233. package/dist/patterns/confirm-dialog.d.ts +4 -4
  234. package/dist/patterns/confirm-dialog.d.ts.map +1 -1
  235. package/dist/patterns/confirm-dialog.js +7 -9
  236. package/dist/patterns/confirm-dialog.js.map +1 -1
  237. package/package.json +3 -3
  238. package/dist/components/enter-view.d.ts +0 -73
  239. package/dist/components/enter-view.d.ts.map +0 -1
  240. package/dist/components/enter-view.js +0 -51
  241. package/dist/utils/validators.d.ts +0 -34
  242. package/dist/utils/validators.d.ts.map +0 -1
  243. package/dist/utils/validators.js +0 -83
@@ -1,4 +1,4 @@
1
- import type { Send, TransitionOptions } from '@llui/dom';
1
+ import type { Send, Signal, TransitionOptions } from '@llui/dom';
2
2
  import { type Placement } from '../utils/floating.js';
3
3
  /**
4
4
  * Menu — a dropdown list of items triggered by a button. Keyboard navigation
@@ -82,13 +82,13 @@ export interface MenuInit {
82
82
  }
83
83
  export declare function init(opts?: MenuInit): MenuState;
84
84
  export declare function update(state: MenuState, msg: MenuMsg): [MenuState, never[]];
85
- export interface MenuItemParts<S> {
85
+ export interface MenuItemParts {
86
86
  item: {
87
87
  role: 'menuitem';
88
88
  id: string;
89
- 'aria-disabled': (s: S) => 'true' | undefined;
90
- 'data-state': (s: S) => 'highlighted' | undefined;
91
- 'data-disabled': (s: S) => '' | undefined;
89
+ 'aria-disabled': Signal<'true' | undefined>;
90
+ 'data-state': Signal<'highlighted' | undefined>;
91
+ 'data-disabled': Signal<'' | undefined>;
92
92
  'data-scope': 'menu';
93
93
  'data-part': 'item';
94
94
  'data-value': string;
@@ -97,14 +97,14 @@ export interface MenuItemParts<S> {
97
97
  onPointerMove: (e: PointerEvent) => void;
98
98
  };
99
99
  }
100
- export interface MenuParts<S> {
100
+ export interface MenuParts {
101
101
  trigger: {
102
102
  type: 'button';
103
103
  'aria-haspopup': 'menu';
104
- 'aria-expanded': (s: S) => boolean;
104
+ 'aria-expanded': Signal<boolean>;
105
105
  'aria-controls': string;
106
106
  id: string;
107
- 'data-state': (s: S) => 'open' | 'closed';
107
+ 'data-state': Signal<'open' | 'closed'>;
108
108
  'data-scope': 'menu';
109
109
  'data-part': 'trigger';
110
110
  onClick: (e: MouseEvent) => void;
@@ -120,23 +120,23 @@ export interface MenuParts<S> {
120
120
  id: string;
121
121
  'aria-labelledby': string;
122
122
  tabIndex: -1;
123
- 'data-state': (s: S) => 'open' | 'closed';
123
+ 'data-state': Signal<'open' | 'closed'>;
124
124
  'data-scope': 'menu';
125
125
  'data-part': 'content';
126
126
  onKeyDown: (e: KeyboardEvent) => void;
127
127
  };
128
- item: (value: string) => MenuItemParts<S>;
128
+ item: (value: string) => MenuItemParts;
129
129
  }
130
130
  export interface ConnectOptions {
131
131
  id: string;
132
132
  /** Called when an item is activated (Enter/Space/click). */
133
133
  onSelect?: (value: string) => void;
134
134
  }
135
- export declare function connect<S>(get: (s: S) => MenuState, send: Send<MenuMsg>, opts: ConnectOptions): MenuParts<S>;
136
- export interface OverlayOptions<S> {
137
- get: (s: S) => MenuState;
135
+ export declare function connect(state: Signal<MenuState>, send: Send<MenuMsg>, opts: ConnectOptions): MenuParts;
136
+ export interface OverlayOptions {
137
+ state: Signal<MenuState>;
138
138
  send: Send<MenuMsg>;
139
- parts: MenuParts<S>;
139
+ parts: MenuParts;
140
140
  content: () => Node[];
141
141
  placement?: Placement;
142
142
  offset?: number;
@@ -145,7 +145,7 @@ export interface OverlayOptions<S> {
145
145
  transition?: TransitionOptions;
146
146
  target?: string | HTMLElement;
147
147
  }
148
- export declare function overlay<S>(opts: OverlayOptions<S>): Node[];
148
+ export declare function overlay(opts: OverlayOptions): Node;
149
149
  export declare const menu: {
150
150
  init: typeof init;
151
151
  update: typeof update;
@@ -1 +1 @@
1
- {"version":3,"file":"menu.d.ts","sourceRoot":"","sources":["../../src/components/menu.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"menu.d.ts","sourceRoot":"","sources":["../../src/components/menu.ts"],"names":[],"mappings":"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"}
@@ -109,7 +109,7 @@ export function update(state, msg) {
109
109
  }
110
110
  }
111
111
  }
112
- export function connect(get, send, opts) {
112
+ export function connect(state, send, opts) {
113
113
  const base = opts.id;
114
114
  const triggerId = `${base}:trigger`;
115
115
  const contentId = `${base}:content`;
@@ -165,10 +165,10 @@ export function connect(get, send, opts) {
165
165
  trigger: {
166
166
  type: 'button',
167
167
  'aria-haspopup': 'menu',
168
- 'aria-expanded': (s) => get(s).open,
168
+ 'aria-expanded': state.map((s) => s.open),
169
169
  'aria-controls': contentId,
170
170
  id: triggerId,
171
- 'data-state': (s) => (get(s).open ? 'open' : 'closed'),
171
+ 'data-state': state.map((s) => (s.open ? 'open' : 'closed')),
172
172
  'data-scope': 'menu',
173
173
  'data-part': 'trigger',
174
174
  onClick: tagSend(send, ['toggle'], () => send({ type: 'toggle' })),
@@ -194,7 +194,7 @@ export function connect(get, send, opts) {
194
194
  id: contentId,
195
195
  'aria-labelledby': triggerId,
196
196
  tabIndex: -1,
197
- 'data-state': (s) => (get(s).open ? 'open' : 'closed'),
197
+ 'data-state': state.map((s) => (s.open ? 'open' : 'closed')),
198
198
  'data-scope': 'menu',
199
199
  'data-part': 'content',
200
200
  onKeyDown: handleMenuKey,
@@ -203,9 +203,9 @@ export function connect(get, send, opts) {
203
203
  item: {
204
204
  role: 'menuitem',
205
205
  id: itemId(value),
206
- 'aria-disabled': (s) => (get(s).disabledItems.includes(value) ? 'true' : undefined),
207
- 'data-state': (s) => (get(s).highlighted === value ? 'highlighted' : undefined),
208
- 'data-disabled': (s) => (get(s).disabledItems.includes(value) ? '' : undefined),
206
+ 'aria-disabled': state.map((s) => (s.disabledItems.includes(value) ? 'true' : undefined)),
207
+ 'data-state': state.map((s) => (s.highlighted === value ? 'highlighted' : undefined)),
208
+ 'data-disabled': state.map((s) => (s.disabledItems.includes(value) ? '' : undefined)),
209
209
  'data-scope': 'menu',
210
210
  'data-part': 'item',
211
211
  'data-value': value,
@@ -220,7 +220,7 @@ export function connect(get, send, opts) {
220
220
  };
221
221
  }
222
222
  export function overlay(opts) {
223
- const target = opts.target ?? 'body';
223
+ const rawTarget = opts.target ?? 'body';
224
224
  const placement = opts.placement ?? 'bottom-start';
225
225
  const offset = opts.offset ?? 4;
226
226
  const flip = opts.flip !== false;
@@ -228,11 +228,12 @@ export function overlay(opts) {
228
228
  const parts = opts.parts;
229
229
  const contentId = parts.content.id;
230
230
  const triggerId = parts.trigger.id;
231
- return show({
232
- when: (s) => opts.get(s).open,
233
- render: () => portal({
234
- target,
235
- render: () => {
231
+ return show(opts.state.map((s) => s.open), () => {
232
+ const targetEl = typeof rawTarget === 'string'
233
+ ? (document.querySelector(rawTarget) ?? document.body)
234
+ : rawTarget;
235
+ return [
236
+ portal(() => {
236
237
  onMount(() => {
237
238
  const contentEl = document.getElementById(contentId);
238
239
  const triggerEl = document.getElementById(triggerId);
@@ -267,10 +268,8 @@ export function overlay(opts) {
267
268
  };
268
269
  });
269
270
  return [div(parts.positioner, opts.content())];
270
- },
271
- }),
272
- enter: opts.transition?.enter,
273
- leave: opts.transition?.leave,
271
+ }, targetEl),
272
+ ];
274
273
  });
275
274
  }
276
275
  export const menu = { init, update, connect, overlay };
@@ -1 +1 @@
1
- {"version":3,"file":"menu.js","sourceRoot":"","sources":["../../src/components/menu.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Send, TransitionOptions } from '@llui/dom'\nimport { show, portal, onMount, div, tagSend } from '@llui/dom'\nimport { pushDismissable } from '../utils/dismissable.js'\nimport { attachFloating, type Placement } from '../utils/floating.js'\nimport {\n typeaheadAccumulate,\n typeaheadMatchByItems,\n isTypeaheadKey,\n TYPEAHEAD_TIMEOUT_MS,\n} from '../utils/typeahead.js'\n\n/**\n * Menu — a dropdown list of items triggered by a button. Keyboard navigation\n * (arrows, Home, End), typeahead (first-letter matching), Enter/Space to\n * activate the focused item, Escape to close.\n *\n * Items are opaque string values (keys); the user's view renders the\n * label/icon/etc. The machine tracks which item is currently \"highlighted\"\n * (= the one that will activate on Enter). On open, the first item is\n * highlighted by default unless `defaultHighlighted` is provided.\n */\n\nexport interface MenuState {\n open: boolean\n items: string[]\n disabledItems: string[]\n highlighted: string | null\n /** Accumulator for typeahead search. */\n typeahead: string\n typeaheadExpiresAt: number\n}\n\nexport type MenuMsg =\n /** @intent(\"Open the menu\") */\n | { type: 'open' }\n /** @intent(\"Close the menu\") */\n | { type: 'close' }\n /** @intent(\"Toggle the menu open/closed\") */\n | { type: 'toggle' }\n /** @humanOnly */\n | { type: 'highlight'; value: string | null }\n /** @humanOnly */\n | { type: 'highlightNext' }\n /** @humanOnly */\n | { type: 'highlightPrev' }\n /** @humanOnly */\n | { type: 'highlightFirst' }\n /** @humanOnly */\n | { type: 'highlightLast' }\n /** @intent(\"Activate the currently-highlighted menu item\") */\n | { type: 'selectHighlighted' }\n /** @intent(\"Activate the menu item with the given value\") */\n | { type: 'select'; value: string }\n /** @humanOnly */\n | { type: 'setItems'; items: string[]; disabled?: string[] }\n /** @humanOnly */\n | { type: 'typeahead'; char: string; now: number }\n\nexport interface MenuInit {\n open?: boolean\n items?: string[]\n disabledItems?: string[]\n highlighted?: string | null\n}\n\nexport function init(opts: MenuInit = {}): MenuState {\n return {\n open: opts.open ?? false,\n items: opts.items ?? [],\n disabledItems: opts.disabledItems ?? [],\n highlighted: opts.highlighted ?? null,\n typeahead: '',\n typeaheadExpiresAt: 0,\n }\n}\n\nfunction firstEnabled(items: string[], disabled: string[]): string | null {\n for (const v of items) if (!disabled.includes(v)) return v\n return null\n}\n\nfunction lastEnabled(items: string[], disabled: string[]): string | null {\n for (let i = items.length - 1; i >= 0; i--) {\n const v = items[i]!\n if (!disabled.includes(v)) return v\n }\n return null\n}\n\nfunction nextEnabled(\n items: string[],\n disabled: string[],\n from: string | null,\n delta: 1 | -1,\n): string | null {\n if (items.length === 0) return null\n const start = from === null ? -1 : items.indexOf(from)\n const n = items.length\n for (let i = 1; i <= n; i++) {\n const idx = start === -1 && delta === 1 ? i - 1 : (start + delta * i + n * n) % n\n const v = items[idx]!\n if (!disabled.includes(v)) return v\n }\n return null\n}\n\nexport function update(state: MenuState, msg: MenuMsg): [MenuState, never[]] {\n switch (msg.type) {\n case 'open': {\n const highlighted = state.highlighted ?? firstEnabled(state.items, state.disabledItems)\n return [{ ...state, open: true, highlighted }, []]\n }\n case 'close':\n return [{ ...state, open: false, highlighted: null, typeahead: '' }, []]\n case 'toggle':\n if (state.open) {\n return [{ ...state, open: false, highlighted: null, typeahead: '' }, []]\n }\n return [\n {\n ...state,\n open: true,\n highlighted: state.highlighted ?? firstEnabled(state.items, state.disabledItems),\n },\n [],\n ]\n case 'highlight':\n if (msg.value !== null && state.disabledItems.includes(msg.value)) return [state, []]\n return [{ ...state, highlighted: msg.value }, []]\n case 'highlightNext': {\n const to = nextEnabled(state.items, state.disabledItems, state.highlighted, 1)\n return [{ ...state, highlighted: to }, []]\n }\n case 'highlightPrev': {\n const to = nextEnabled(state.items, state.disabledItems, state.highlighted, -1)\n return [{ ...state, highlighted: to }, []]\n }\n case 'highlightFirst':\n return [{ ...state, highlighted: firstEnabled(state.items, state.disabledItems) }, []]\n case 'highlightLast':\n return [{ ...state, highlighted: lastEnabled(state.items, state.disabledItems) }, []]\n case 'selectHighlighted':\n if (state.highlighted === null) return [state, []]\n return [{ ...state, open: false, highlighted: null, typeahead: '' }, []]\n case 'select':\n if (state.disabledItems.includes(msg.value)) return [state, []]\n return [{ ...state, open: false, highlighted: null, typeahead: '' }, []]\n case 'setItems': {\n const disabled = msg.disabled ?? state.disabledItems\n const highlighted =\n state.highlighted &&\n msg.items.includes(state.highlighted) &&\n !disabled.includes(state.highlighted)\n ? state.highlighted\n : null\n return [{ ...state, items: msg.items, disabledItems: disabled, highlighted }, []]\n }\n case 'typeahead': {\n const acc = typeaheadAccumulate(state.typeahead, msg.char, msg.now, state.typeaheadExpiresAt)\n const startIdx = state.highlighted ? state.items.indexOf(state.highlighted) : null\n const matchIdx = typeaheadMatchByItems(state.items, state.disabledItems, acc, startIdx)\n const match = matchIdx === null ? null : state.items[matchIdx]!\n return [\n {\n ...state,\n typeahead: acc,\n typeaheadExpiresAt: msg.now + TYPEAHEAD_TIMEOUT_MS,\n highlighted: match ?? state.highlighted,\n },\n [],\n ]\n }\n }\n}\n\nexport interface MenuItemParts<S> {\n item: {\n role: 'menuitem'\n id: string\n 'aria-disabled': (s: S) => 'true' | undefined\n 'data-state': (s: S) => 'highlighted' | undefined\n 'data-disabled': (s: S) => '' | undefined\n 'data-scope': 'menu'\n 'data-part': 'item'\n 'data-value': string\n tabIndex: -1\n onClick: (e: MouseEvent) => void\n onPointerMove: (e: PointerEvent) => void\n }\n}\n\nexport interface MenuParts<S> {\n trigger: {\n type: 'button'\n 'aria-haspopup': 'menu'\n 'aria-expanded': (s: S) => boolean\n 'aria-controls': string\n id: string\n 'data-state': (s: S) => 'open' | 'closed'\n 'data-scope': 'menu'\n 'data-part': 'trigger'\n onClick: (e: MouseEvent) => void\n onKeyDown: (e: KeyboardEvent) => void\n }\n positioner: {\n 'data-scope': 'menu'\n 'data-part': 'positioner'\n style: string\n }\n content: {\n role: 'menu'\n id: string\n 'aria-labelledby': string\n tabIndex: -1\n 'data-state': (s: S) => 'open' | 'closed'\n 'data-scope': 'menu'\n 'data-part': 'content'\n onKeyDown: (e: KeyboardEvent) => void\n }\n item: (value: string) => MenuItemParts<S>\n}\n\nexport interface ConnectOptions {\n id: string\n /** Called when an item is activated (Enter/Space/click). */\n onSelect?: (value: string) => void\n}\n\nexport function connect<S>(\n get: (s: S) => MenuState,\n send: Send<MenuMsg>,\n opts: ConnectOptions,\n): MenuParts<S> {\n const base = opts.id\n const triggerId = `${base}:trigger`\n const contentId = `${base}:content`\n const itemId = (v: string): string => `${base}:item:${v}`\n\n // Keyboard navigation dispatches a fixed vocabulary of MenuMsg\n // variants. `tagSend` propagates the user's translator tag (when\n // `send` is a tagged dispatch translator) onto this handler so the\n // agent's `list_actions` surfaces the user-side variants the\n // translator forwards. Without a translator, the library variants\n // listed here are what `update()` actually receives.\n const handleMenuKey = tagSend(\n send,\n [\n 'highlightNext',\n 'highlightPrev',\n 'highlightFirst',\n 'highlightLast',\n 'selectHighlighted',\n 'close',\n 'typeahead',\n ],\n (e: KeyboardEvent): void => {\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault()\n send({ type: 'highlightNext' })\n return\n case 'ArrowUp':\n e.preventDefault()\n send({ type: 'highlightPrev' })\n return\n case 'Home':\n e.preventDefault()\n send({ type: 'highlightFirst' })\n return\n case 'End':\n e.preventDefault()\n send({ type: 'highlightLast' })\n return\n case 'Enter':\n case ' ':\n e.preventDefault()\n send({ type: 'selectHighlighted' })\n return\n case 'Escape':\n e.preventDefault()\n send({ type: 'close' })\n return\n default:\n if (isTypeaheadKey(e)) {\n send({ type: 'typeahead', char: e.key, now: Date.now() })\n }\n }\n },\n )\n\n return {\n trigger: {\n type: 'button',\n 'aria-haspopup': 'menu',\n 'aria-expanded': (s) => get(s).open,\n 'aria-controls': contentId,\n id: triggerId,\n 'data-state': (s) => (get(s).open ? 'open' : 'closed'),\n 'data-scope': 'menu',\n 'data-part': 'trigger',\n onClick: tagSend(send, ['toggle'], () => send({ type: 'toggle' })),\n onKeyDown: tagSend(send, ['open', 'highlightLast'], (e: KeyboardEvent) => {\n if (e.key === 'ArrowDown' || e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n send({ type: 'open' })\n } else if (e.key === 'ArrowUp') {\n e.preventDefault()\n send({ type: 'open' })\n send({ type: 'highlightLast' })\n }\n }),\n },\n positioner: {\n 'data-scope': 'menu',\n 'data-part': 'positioner',\n style: 'position:absolute;top:0;left:0;',\n },\n content: {\n role: 'menu',\n id: contentId,\n 'aria-labelledby': triggerId,\n tabIndex: -1,\n 'data-state': (s) => (get(s).open ? 'open' : 'closed'),\n 'data-scope': 'menu',\n 'data-part': 'content',\n onKeyDown: handleMenuKey,\n },\n item: (value: string): MenuItemParts<S> => ({\n item: {\n role: 'menuitem',\n id: itemId(value),\n 'aria-disabled': (s) => (get(s).disabledItems.includes(value) ? 'true' : undefined),\n 'data-state': (s) => (get(s).highlighted === value ? 'highlighted' : undefined),\n 'data-disabled': (s) => (get(s).disabledItems.includes(value) ? '' : undefined),\n 'data-scope': 'menu',\n 'data-part': 'item',\n 'data-value': value,\n tabIndex: -1,\n onClick: tagSend(send, ['select'], () => {\n send({ type: 'select', value })\n opts.onSelect?.(value)\n }),\n onPointerMove: tagSend(send, ['highlight'], () => send({ type: 'highlight', value })),\n },\n }),\n }\n}\n\nexport interface OverlayOptions<S> {\n get: (s: S) => MenuState\n send: Send<MenuMsg>\n parts: MenuParts<S>\n content: () => Node[]\n placement?: Placement\n offset?: number\n flip?: boolean\n shift?: boolean\n transition?: TransitionOptions\n target?: string | HTMLElement\n}\n\nexport function overlay<S>(opts: OverlayOptions<S>): Node[] {\n const target = opts.target ?? 'body'\n const placement = opts.placement ?? 'bottom-start'\n const offset = opts.offset ?? 4\n const flip = opts.flip !== false\n const shift = opts.shift !== false\n const parts = opts.parts\n const contentId = parts.content.id\n const triggerId = parts.trigger.id\n\n return show<S, MenuMsg>({\n when: (s) => opts.get(s).open,\n render: () =>\n portal({\n target,\n render: () => {\n onMount(() => {\n const contentEl = document.getElementById(contentId)\n const triggerEl = document.getElementById(triggerId)\n if (!contentEl || !triggerEl) return\n\n const cleanups: Array<() => void> = []\n\n const positioner = contentEl.closest('[data-part=\"positioner\"]') as HTMLElement | null\n const floatingEl = positioner ?? contentEl\n cleanups.push(\n attachFloating({\n anchor: triggerEl,\n floating: floatingEl,\n placement,\n offset,\n flip,\n shift,\n }),\n )\n\n cleanups.push(\n pushDismissable({\n element: contentEl,\n ignore: () => [triggerEl],\n onDismiss: () => {\n opts.send({ type: 'close' })\n triggerEl.focus()\n },\n }),\n )\n\n // Auto-focus content so keyboard navigation works immediately.\n // preventScroll avoids a page jump when the portaled content\n // is briefly at position (0,0) before floating-ui positions it.\n contentEl.focus({ preventScroll: true })\n\n return () => {\n for (let i = cleanups.length - 1; i >= 0; i--) cleanups[i]!()\n }\n })\n return [div(parts.positioner, opts.content())]\n },\n }),\n enter: opts.transition?.enter,\n leave: opts.transition?.leave,\n })\n}\n\nexport const menu = { init, update, connect, overlay }\n"]}
1
+ {"version":3,"file":"menu.js","sourceRoot":"","sources":["../../src/components/menu.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Send, Signal, TransitionOptions } from '@llui/dom'\nimport { show, portal, onMount, div, tagSend } from '@llui/dom'\nimport { pushDismissable } from '../utils/dismissable.js'\nimport { attachFloating, type Placement } from '../utils/floating.js'\nimport {\n typeaheadAccumulate,\n typeaheadMatchByItems,\n isTypeaheadKey,\n TYPEAHEAD_TIMEOUT_MS,\n} from '../utils/typeahead.js'\n\n/**\n * Menu — a dropdown list of items triggered by a button. Keyboard navigation\n * (arrows, Home, End), typeahead (first-letter matching), Enter/Space to\n * activate the focused item, Escape to close.\n *\n * Items are opaque string values (keys); the user's view renders the\n * label/icon/etc. The machine tracks which item is currently \"highlighted\"\n * (= the one that will activate on Enter). On open, the first item is\n * highlighted by default unless `defaultHighlighted` is provided.\n */\n\nexport interface MenuState {\n open: boolean\n items: string[]\n disabledItems: string[]\n highlighted: string | null\n /** Accumulator for typeahead search. */\n typeahead: string\n typeaheadExpiresAt: number\n}\n\nexport type MenuMsg =\n /** @intent(\"Open the menu\") */\n | { type: 'open' }\n /** @intent(\"Close the menu\") */\n | { type: 'close' }\n /** @intent(\"Toggle the menu open/closed\") */\n | { type: 'toggle' }\n /** @humanOnly */\n | { type: 'highlight'; value: string | null }\n /** @humanOnly */\n | { type: 'highlightNext' }\n /** @humanOnly */\n | { type: 'highlightPrev' }\n /** @humanOnly */\n | { type: 'highlightFirst' }\n /** @humanOnly */\n | { type: 'highlightLast' }\n /** @intent(\"Activate the currently-highlighted menu item\") */\n | { type: 'selectHighlighted' }\n /** @intent(\"Activate the menu item with the given value\") */\n | { type: 'select'; value: string }\n /** @humanOnly */\n | { type: 'setItems'; items: string[]; disabled?: string[] }\n /** @humanOnly */\n | { type: 'typeahead'; char: string; now: number }\n\nexport interface MenuInit {\n open?: boolean\n items?: string[]\n disabledItems?: string[]\n highlighted?: string | null\n}\n\nexport function init(opts: MenuInit = {}): MenuState {\n return {\n open: opts.open ?? false,\n items: opts.items ?? [],\n disabledItems: opts.disabledItems ?? [],\n highlighted: opts.highlighted ?? null,\n typeahead: '',\n typeaheadExpiresAt: 0,\n }\n}\n\nfunction firstEnabled(items: string[], disabled: string[]): string | null {\n for (const v of items) if (!disabled.includes(v)) return v\n return null\n}\n\nfunction lastEnabled(items: string[], disabled: string[]): string | null {\n for (let i = items.length - 1; i >= 0; i--) {\n const v = items[i]!\n if (!disabled.includes(v)) return v\n }\n return null\n}\n\nfunction nextEnabled(\n items: string[],\n disabled: string[],\n from: string | null,\n delta: 1 | -1,\n): string | null {\n if (items.length === 0) return null\n const start = from === null ? -1 : items.indexOf(from)\n const n = items.length\n for (let i = 1; i <= n; i++) {\n const idx = start === -1 && delta === 1 ? i - 1 : (start + delta * i + n * n) % n\n const v = items[idx]!\n if (!disabled.includes(v)) return v\n }\n return null\n}\n\nexport function update(state: MenuState, msg: MenuMsg): [MenuState, never[]] {\n switch (msg.type) {\n case 'open': {\n const highlighted = state.highlighted ?? firstEnabled(state.items, state.disabledItems)\n return [{ ...state, open: true, highlighted }, []]\n }\n case 'close':\n return [{ ...state, open: false, highlighted: null, typeahead: '' }, []]\n case 'toggle':\n if (state.open) {\n return [{ ...state, open: false, highlighted: null, typeahead: '' }, []]\n }\n return [\n {\n ...state,\n open: true,\n highlighted: state.highlighted ?? firstEnabled(state.items, state.disabledItems),\n },\n [],\n ]\n case 'highlight':\n if (msg.value !== null && state.disabledItems.includes(msg.value)) return [state, []]\n return [{ ...state, highlighted: msg.value }, []]\n case 'highlightNext': {\n const to = nextEnabled(state.items, state.disabledItems, state.highlighted, 1)\n return [{ ...state, highlighted: to }, []]\n }\n case 'highlightPrev': {\n const to = nextEnabled(state.items, state.disabledItems, state.highlighted, -1)\n return [{ ...state, highlighted: to }, []]\n }\n case 'highlightFirst':\n return [{ ...state, highlighted: firstEnabled(state.items, state.disabledItems) }, []]\n case 'highlightLast':\n return [{ ...state, highlighted: lastEnabled(state.items, state.disabledItems) }, []]\n case 'selectHighlighted':\n if (state.highlighted === null) return [state, []]\n return [{ ...state, open: false, highlighted: null, typeahead: '' }, []]\n case 'select':\n if (state.disabledItems.includes(msg.value)) return [state, []]\n return [{ ...state, open: false, highlighted: null, typeahead: '' }, []]\n case 'setItems': {\n const disabled = msg.disabled ?? state.disabledItems\n const highlighted =\n state.highlighted &&\n msg.items.includes(state.highlighted) &&\n !disabled.includes(state.highlighted)\n ? state.highlighted\n : null\n return [{ ...state, items: msg.items, disabledItems: disabled, highlighted }, []]\n }\n case 'typeahead': {\n const acc = typeaheadAccumulate(state.typeahead, msg.char, msg.now, state.typeaheadExpiresAt)\n const startIdx = state.highlighted ? state.items.indexOf(state.highlighted) : null\n const matchIdx = typeaheadMatchByItems(state.items, state.disabledItems, acc, startIdx)\n const match = matchIdx === null ? null : state.items[matchIdx]!\n return [\n {\n ...state,\n typeahead: acc,\n typeaheadExpiresAt: msg.now + TYPEAHEAD_TIMEOUT_MS,\n highlighted: match ?? state.highlighted,\n },\n [],\n ]\n }\n }\n}\n\nexport interface MenuItemParts {\n item: {\n role: 'menuitem'\n id: string\n 'aria-disabled': Signal<'true' | undefined>\n 'data-state': Signal<'highlighted' | undefined>\n 'data-disabled': Signal<'' | undefined>\n 'data-scope': 'menu'\n 'data-part': 'item'\n 'data-value': string\n tabIndex: -1\n onClick: (e: MouseEvent) => void\n onPointerMove: (e: PointerEvent) => void\n }\n}\n\nexport interface MenuParts {\n trigger: {\n type: 'button'\n 'aria-haspopup': 'menu'\n 'aria-expanded': Signal<boolean>\n 'aria-controls': string\n id: string\n 'data-state': Signal<'open' | 'closed'>\n 'data-scope': 'menu'\n 'data-part': 'trigger'\n onClick: (e: MouseEvent) => void\n onKeyDown: (e: KeyboardEvent) => void\n }\n positioner: {\n 'data-scope': 'menu'\n 'data-part': 'positioner'\n style: string\n }\n content: {\n role: 'menu'\n id: string\n 'aria-labelledby': string\n tabIndex: -1\n 'data-state': Signal<'open' | 'closed'>\n 'data-scope': 'menu'\n 'data-part': 'content'\n onKeyDown: (e: KeyboardEvent) => void\n }\n item: (value: string) => MenuItemParts\n}\n\nexport interface ConnectOptions {\n id: string\n /** Called when an item is activated (Enter/Space/click). */\n onSelect?: (value: string) => void\n}\n\nexport function connect(\n state: Signal<MenuState>,\n send: Send<MenuMsg>,\n opts: ConnectOptions,\n): MenuParts {\n const base = opts.id\n const triggerId = `${base}:trigger`\n const contentId = `${base}:content`\n const itemId = (v: string): string => `${base}:item:${v}`\n\n // Keyboard navigation dispatches a fixed vocabulary of MenuMsg\n // variants. `tagSend` propagates the user's translator tag (when\n // `send` is a tagged dispatch translator) onto this handler so the\n // agent's `list_actions` surfaces the user-side variants the\n // translator forwards. Without a translator, the library variants\n // listed here are what `update()` actually receives.\n const handleMenuKey = tagSend(\n send,\n [\n 'highlightNext',\n 'highlightPrev',\n 'highlightFirst',\n 'highlightLast',\n 'selectHighlighted',\n 'close',\n 'typeahead',\n ],\n (e: KeyboardEvent): void => {\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault()\n send({ type: 'highlightNext' })\n return\n case 'ArrowUp':\n e.preventDefault()\n send({ type: 'highlightPrev' })\n return\n case 'Home':\n e.preventDefault()\n send({ type: 'highlightFirst' })\n return\n case 'End':\n e.preventDefault()\n send({ type: 'highlightLast' })\n return\n case 'Enter':\n case ' ':\n e.preventDefault()\n send({ type: 'selectHighlighted' })\n return\n case 'Escape':\n e.preventDefault()\n send({ type: 'close' })\n return\n default:\n if (isTypeaheadKey(e)) {\n send({ type: 'typeahead', char: e.key, now: Date.now() })\n }\n }\n },\n )\n\n return {\n trigger: {\n type: 'button',\n 'aria-haspopup': 'menu',\n 'aria-expanded': state.map((s) => s.open),\n 'aria-controls': contentId,\n id: triggerId,\n 'data-state': state.map((s) => (s.open ? 'open' : 'closed')),\n 'data-scope': 'menu',\n 'data-part': 'trigger',\n onClick: tagSend(send, ['toggle'], () => send({ type: 'toggle' })),\n onKeyDown: tagSend(send, ['open', 'highlightLast'], (e: KeyboardEvent) => {\n if (e.key === 'ArrowDown' || e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n send({ type: 'open' })\n } else if (e.key === 'ArrowUp') {\n e.preventDefault()\n send({ type: 'open' })\n send({ type: 'highlightLast' })\n }\n }),\n },\n positioner: {\n 'data-scope': 'menu',\n 'data-part': 'positioner',\n style: 'position:absolute;top:0;left:0;',\n },\n content: {\n role: 'menu',\n id: contentId,\n 'aria-labelledby': triggerId,\n tabIndex: -1,\n 'data-state': state.map((s) => (s.open ? 'open' : 'closed')),\n 'data-scope': 'menu',\n 'data-part': 'content',\n onKeyDown: handleMenuKey,\n },\n item: (value: string): MenuItemParts => ({\n item: {\n role: 'menuitem',\n id: itemId(value),\n 'aria-disabled': state.map((s) => (s.disabledItems.includes(value) ? 'true' : undefined)),\n 'data-state': state.map((s) => (s.highlighted === value ? 'highlighted' : undefined)),\n 'data-disabled': state.map((s) => (s.disabledItems.includes(value) ? '' : undefined)),\n 'data-scope': 'menu',\n 'data-part': 'item',\n 'data-value': value,\n tabIndex: -1,\n onClick: tagSend(send, ['select'], () => {\n send({ type: 'select', value })\n opts.onSelect?.(value)\n }),\n onPointerMove: tagSend(send, ['highlight'], () => send({ type: 'highlight', value })),\n },\n }),\n }\n}\n\nexport interface OverlayOptions {\n state: Signal<MenuState>\n send: Send<MenuMsg>\n parts: MenuParts\n content: () => Node[]\n placement?: Placement\n offset?: number\n flip?: boolean\n shift?: boolean\n transition?: TransitionOptions\n target?: string | HTMLElement\n}\n\nexport function overlay(opts: OverlayOptions): Node {\n const rawTarget = opts.target ?? 'body'\n const placement = opts.placement ?? 'bottom-start'\n const offset = opts.offset ?? 4\n const flip = opts.flip !== false\n const shift = opts.shift !== false\n const parts = opts.parts\n const contentId = parts.content.id\n const triggerId = parts.trigger.id\n\n return show(\n opts.state.map((s) => s.open),\n () => {\n const targetEl =\n typeof rawTarget === 'string'\n ? (document.querySelector(rawTarget) ?? document.body)\n : rawTarget\n return [\n portal(() => {\n onMount(() => {\n const contentEl = document.getElementById(contentId)\n const triggerEl = document.getElementById(triggerId)\n if (!contentEl || !triggerEl) return\n\n const cleanups: Array<() => void> = []\n\n const positioner = contentEl.closest('[data-part=\"positioner\"]') as HTMLElement | null\n const floatingEl = positioner ?? contentEl\n cleanups.push(\n attachFloating({\n anchor: triggerEl,\n floating: floatingEl,\n placement,\n offset,\n flip,\n shift,\n }),\n )\n\n cleanups.push(\n pushDismissable({\n element: contentEl,\n ignore: () => [triggerEl],\n onDismiss: () => {\n opts.send({ type: 'close' })\n triggerEl.focus()\n },\n }),\n )\n\n // Auto-focus content so keyboard navigation works immediately.\n // preventScroll avoids a page jump when the portaled content\n // is briefly at position (0,0) before floating-ui positions it.\n contentEl.focus({ preventScroll: true })\n\n return () => {\n for (let i = cleanups.length - 1; i >= 0; i--) cleanups[i]!()\n }\n })\n return [div(parts.positioner, opts.content())]\n }, targetEl),\n ]\n },\n )\n}\n\nexport const menu = { init, update, connect, overlay }\n"]}
@@ -1,4 +1,4 @@
1
- import type { Send } from '@llui/dom';
1
+ import type { Send, Signal } from '@llui/dom';
2
2
  /**
3
3
  * Navigation menu — multi-level menu bar with hover/focus-triggered
4
4
  * submenus. Unlike `menu` (a single dropdown), navigation-menu supports
@@ -61,18 +61,18 @@ export interface NavMenuInit {
61
61
  export declare function init(opts?: NavMenuInit): NavMenuState;
62
62
  export declare function update(state: NavMenuState, msg: NavMenuMsg): [NavMenuState, never[]];
63
63
  export declare function isOpen(state: NavMenuState, id: string): boolean;
64
- export interface NavItemParts<S> {
64
+ export interface NavItemParts {
65
65
  trigger: {
66
66
  type: 'button';
67
67
  role: 'menuitem';
68
68
  id: string;
69
69
  'aria-haspopup': 'menu' | undefined;
70
- 'aria-expanded': (s: S) => boolean | undefined;
70
+ 'aria-expanded': Signal<boolean | undefined>;
71
71
  'data-scope': 'navigation-menu';
72
72
  'data-part': 'trigger';
73
- 'data-state': (s: S) => 'open' | 'closed';
73
+ 'data-state': Signal<'open' | 'closed'>;
74
74
  'data-value': string;
75
- tabIndex: (s: S) => number;
75
+ tabIndex: Signal<number>;
76
76
  onClick: (e: MouseEvent) => void;
77
77
  onPointerEnter: (e: PointerEvent) => void;
78
78
  onFocus: (e: FocusEvent) => void;
@@ -83,25 +83,25 @@ export interface NavItemParts<S> {
83
83
  'aria-labelledby': string;
84
84
  'data-scope': 'navigation-menu';
85
85
  'data-part': 'content';
86
- 'data-state': (s: S) => 'open' | 'closed';
87
- hidden: (s: S) => boolean;
86
+ 'data-state': Signal<'open' | 'closed'>;
87
+ hidden: Signal<boolean>;
88
88
  onPointerEnter: (e: PointerEvent) => void;
89
89
  };
90
90
  }
91
- export interface NavMenuParts<S> {
91
+ export interface NavMenuParts {
92
92
  root: {
93
93
  role: 'menubar';
94
- 'aria-label': string | ((s: S) => string);
94
+ 'aria-label': string;
95
95
  'data-scope': 'navigation-menu';
96
96
  'data-part': 'root';
97
- 'data-disabled': (s: S) => '' | undefined;
97
+ 'data-disabled': Signal<'' | undefined>;
98
98
  onPointerLeave: (e: PointerEvent) => void;
99
99
  onPointerEnter: (e: PointerEvent) => void;
100
100
  };
101
101
  item: (id: string, options: {
102
102
  isBranch: boolean;
103
103
  ancestorIds?: string[];
104
- }) => NavItemParts<S>;
104
+ }) => NavItemParts;
105
105
  }
106
106
  export interface ConnectOptions {
107
107
  id: string;
@@ -113,7 +113,7 @@ export interface ConnectOptions {
113
113
  */
114
114
  closeOnLeave?: boolean;
115
115
  }
116
- export declare function connect<S>(get: (s: S) => NavMenuState, send: Send<NavMenuMsg>, opts: ConnectOptions): NavMenuParts<S>;
116
+ export declare function connect(state: Signal<NavMenuState>, send: Send<NavMenuMsg>, opts: ConnectOptions): NavMenuParts;
117
117
  export declare const navigationMenu: {
118
118
  init: typeof init;
119
119
  update: typeof update;
@@ -1 +1 @@
1
- {"version":3,"file":"navigation-menu.d.ts","sourceRoot":"","sources":["../../src/components/navigation-menu.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"navigation-menu.d.ts","sourceRoot":"","sources":["../../src/components/navigation-menu.ts"],"names":[],"mappings":"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"}
@@ -46,7 +46,7 @@ export function update(state, msg) {
46
46
  export function isOpen(state, id) {
47
47
  return state.open.includes(id);
48
48
  }
49
- export function connect(get, send, opts) {
49
+ export function connect(state, send, opts) {
50
50
  const locale = useContext(LocaleContext);
51
51
  const triggerId = (v) => `${opts.id}:trigger:${v}`;
52
52
  const contentId = (v) => `${opts.id}:content:${v}`;
@@ -71,10 +71,10 @@ export function connect(get, send, opts) {
71
71
  return {
72
72
  root: {
73
73
  role: 'menubar',
74
- 'aria-label': opts.label ?? ((s) => locale(s).navigationMenu.label),
74
+ 'aria-label': opts.label ?? locale.navigationMenu.label,
75
75
  'data-scope': 'navigation-menu',
76
76
  'data-part': 'root',
77
- 'data-disabled': (s) => (get(s).disabled ? '' : undefined),
77
+ 'data-disabled': state.map((st) => (st.disabled ? '' : undefined)),
78
78
  onPointerLeave: () => scheduleClose(),
79
79
  onPointerEnter: () => cancelClose(),
80
80
  },
@@ -86,12 +86,12 @@ export function connect(get, send, opts) {
86
86
  role: 'menuitem',
87
87
  id: triggerId(id),
88
88
  'aria-haspopup': options.isBranch ? 'menu' : undefined,
89
- 'aria-expanded': (s) => (options.isBranch ? isOpen(get(s), id) : undefined),
89
+ 'aria-expanded': state.map((st) => (options.isBranch ? isOpen(st, id) : undefined)),
90
90
  'data-scope': 'navigation-menu',
91
91
  'data-part': 'trigger',
92
- 'data-state': (s) => (isOpen(get(s), id) ? 'open' : 'closed'),
92
+ 'data-state': state.map((st) => (isOpen(st, id) ? 'open' : 'closed')),
93
93
  'data-value': id,
94
- tabIndex: (s) => (get(s).focused === id ? 0 : -1),
94
+ tabIndex: state.map((st) => (st.focused === id ? 0 : -1)),
95
95
  onClick: tagSend(send, ['toggleBranch'], () => {
96
96
  if (options.isBranch) {
97
97
  send({ type: 'toggleBranch', id, ancestorIds });
@@ -111,8 +111,8 @@ export function connect(get, send, opts) {
111
111
  'aria-labelledby': triggerId(id),
112
112
  'data-scope': 'navigation-menu',
113
113
  'data-part': 'content',
114
- 'data-state': (s) => (isOpen(get(s), id) ? 'open' : 'closed'),
115
- hidden: (s) => !isOpen(get(s), id),
114
+ 'data-state': state.map((st) => (isOpen(st, id) ? 'open' : 'closed')),
115
+ hidden: state.map((st) => !isOpen(st, id)),
116
116
  onPointerEnter: tagSend(send, ['openBranch'], () => {
117
117
  cancelClose();
118
118
  if (options.isBranch) {
@@ -1 +1 @@
1
- {"version":3,"file":"navigation-menu.js","sourceRoot":"","sources":["../../src/components/navigation-menu.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Send } from '@llui/dom'\nimport { useContext, tagSend } from '@llui/dom'\nimport { LocaleContext } from '../locale.js'\nimport type { Locale } from '../locale.js'\n\n/**\n * Navigation menu — multi-level menu bar with hover/focus-triggered\n * submenus. Unlike `menu` (a single dropdown), navigation-menu supports\n * nested submenus arbitrarily deep and is typically used for primary\n * site navigation.\n *\n * State tracks the currently focused item id and the ids of all\n * currently-open branches. The consumer provides the tree structure\n * (items with optional children); the machine doesn't index the\n * hierarchy itself — it just maintains open-paths and lets the view\n * handle traversal.\n *\n * Typical interaction model (delay-based):\n * - Pointer enter on a branch → openBranch after openDelay\n * - Pointer leave of the whole tree → closeAll after closeDelay\n * - Click/keyboard activation → toggleBranch immediately\n *\n * The consumer is responsible for debouncing via setTimeout; the machine\n * just responds to the dispatched messages.\n */\n\nexport interface NavMenuState {\n /** Ids of open branches, in open order (root-first). Closing an\n * ancestor automatically closes its descendants. */\n open: string[]\n focused: string | null\n disabled: boolean\n}\n\nexport type NavMenuMsg =\n /** @intent(\"Open the submenu identified by id, closing any open siblings\") */\n | { type: 'openBranch'; id: string; ancestorIds: string[] }\n /** @intent(\"Close the submenu identified by id (also closes its descendants)\") */\n | { type: 'closeBranch'; id: string }\n /** @intent(\"Toggle the submenu identified by id open/closed\") */\n | { type: 'toggleBranch'; id: string; ancestorIds: string[] }\n /** @intent(\"Close every open submenu\") */\n | { type: 'closeAll' }\n /** @humanOnly */\n | { type: 'focus'; id: string | null }\n\nexport interface NavMenuInit {\n open?: string[]\n focused?: string | null\n disabled?: boolean\n}\n\nexport function init(opts: NavMenuInit = {}): NavMenuState {\n return {\n open: opts.open ?? [],\n focused: opts.focused ?? null,\n disabled: opts.disabled ?? false,\n }\n}\n\nexport function update(state: NavMenuState, msg: NavMenuMsg): [NavMenuState, never[]] {\n if (state.disabled) return [state, []]\n switch (msg.type) {\n case 'openBranch': {\n // Close any siblings of `id` at the same ancestor path, then add it.\n // Sibling detection: an entry is a sibling if its ancestor set matches\n // msg.ancestorIds and it isn't msg.id. We don't track ancestors in\n // state, so: filter `open` to keep only entries that are themselves\n // an ancestor of msg.id, plus msg.id.\n const keep = new Set([...msg.ancestorIds, msg.id])\n const open = state.open.filter((o) => keep.has(o))\n if (!open.includes(msg.id)) open.push(msg.id)\n return [{ ...state, open }, []]\n }\n case 'closeBranch': {\n // Close this branch and any descendants that follow it in the open\n // list. Since open is ordered root-first, descendants come after.\n const idx = state.open.indexOf(msg.id)\n if (idx === -1) return [state, []]\n const open = state.open.slice(0, idx)\n return [{ ...state, open }, []]\n }\n case 'toggleBranch':\n if (state.open.includes(msg.id)) {\n return update(state, { type: 'closeBranch', id: msg.id })\n }\n return update(state, { type: 'openBranch', id: msg.id, ancestorIds: msg.ancestorIds })\n case 'closeAll':\n return [{ ...state, open: [] }, []]\n case 'focus':\n return [{ ...state, focused: msg.id }, []]\n }\n}\n\nexport function isOpen(state: NavMenuState, id: string): boolean {\n return state.open.includes(id)\n}\n\nexport interface NavItemParts<S> {\n trigger: {\n type: 'button'\n role: 'menuitem'\n id: string\n 'aria-haspopup': 'menu' | undefined\n 'aria-expanded': (s: S) => boolean | undefined\n 'data-scope': 'navigation-menu'\n 'data-part': 'trigger'\n 'data-state': (s: S) => 'open' | 'closed'\n 'data-value': string\n tabIndex: (s: S) => number\n onClick: (e: MouseEvent) => void\n onPointerEnter: (e: PointerEvent) => void\n onFocus: (e: FocusEvent) => void\n }\n content: {\n role: 'menu'\n id: string\n 'aria-labelledby': string\n 'data-scope': 'navigation-menu'\n 'data-part': 'content'\n 'data-state': (s: S) => 'open' | 'closed'\n hidden: (s: S) => boolean\n onPointerEnter: (e: PointerEvent) => void\n }\n}\n\nexport interface NavMenuParts<S> {\n root: {\n role: 'menubar'\n 'aria-label': string | ((s: S) => string)\n 'data-scope': 'navigation-menu'\n 'data-part': 'root'\n 'data-disabled': (s: S) => '' | undefined\n onPointerLeave: (e: PointerEvent) => void\n onPointerEnter: (e: PointerEvent) => void\n }\n item: (id: string, options: { isBranch: boolean; ancestorIds?: string[] }) => NavItemParts<S>\n}\n\nexport interface ConnectOptions {\n id: string\n label?: string\n /**\n * Whether pointer-leaving the whole menu closes everything. Default: true.\n * The consumer can inject their own close delay by intercepting\n * onPointerLeave + calling setTimeout + dispatching closeAll.\n */\n closeOnLeave?: boolean\n}\n\nexport function connect<S>(\n get: (s: S) => NavMenuState,\n send: Send<NavMenuMsg>,\n opts: ConnectOptions,\n): NavMenuParts<S> {\n const locale = useContext<S, Locale>(LocaleContext)\n const triggerId = (v: string): string => `${opts.id}:trigger:${v}`\n const contentId = (v: string): string => `${opts.id}:content:${v}`\n const closeOnLeave = opts.closeOnLeave !== false\n let closeTimer: ReturnType<typeof setTimeout> | null = null\n\n const scheduleClose = (): void => {\n if (!closeOnLeave) return\n if (closeTimer) clearTimeout(closeTimer)\n closeTimer = setTimeout(() => {\n send({ type: 'closeAll' })\n closeTimer = null\n }, 150)\n }\n\n const cancelClose = (): void => {\n if (closeTimer) {\n clearTimeout(closeTimer)\n closeTimer = null\n }\n }\n\n return {\n root: {\n role: 'menubar',\n 'aria-label': opts.label ?? ((s: S) => locale(s).navigationMenu.label),\n 'data-scope': 'navigation-menu',\n 'data-part': 'root',\n 'data-disabled': (s) => (get(s).disabled ? '' : undefined),\n onPointerLeave: () => scheduleClose(),\n onPointerEnter: () => cancelClose(),\n },\n item: (id: string, options: { isBranch: boolean; ancestorIds?: string[] }): NavItemParts<S> => {\n const ancestorIds = options.ancestorIds ?? []\n return {\n trigger: {\n type: 'button',\n role: 'menuitem',\n id: triggerId(id),\n 'aria-haspopup': options.isBranch ? 'menu' : undefined,\n 'aria-expanded': (s) => (options.isBranch ? isOpen(get(s), id) : undefined),\n 'data-scope': 'navigation-menu',\n 'data-part': 'trigger',\n 'data-state': (s) => (isOpen(get(s), id) ? 'open' : 'closed'),\n 'data-value': id,\n tabIndex: (s) => (get(s).focused === id ? 0 : -1),\n onClick: tagSend(send, ['toggleBranch'], () => {\n if (options.isBranch) {\n send({ type: 'toggleBranch', id, ancestorIds })\n }\n }),\n onPointerEnter: tagSend(send, ['openBranch'], () => {\n cancelClose()\n if (options.isBranch) {\n send({ type: 'openBranch', id, ancestorIds })\n }\n }),\n onFocus: tagSend(send, ['focus'], () => send({ type: 'focus', id })),\n },\n content: {\n role: 'menu',\n id: contentId(id),\n 'aria-labelledby': triggerId(id),\n 'data-scope': 'navigation-menu',\n 'data-part': 'content',\n 'data-state': (s) => (isOpen(get(s), id) ? 'open' : 'closed'),\n hidden: (s) => !isOpen(get(s), id),\n onPointerEnter: tagSend(send, ['openBranch'], () => {\n cancelClose()\n if (options.isBranch) {\n send({ type: 'openBranch', id, ancestorIds })\n }\n }),\n },\n }\n },\n }\n}\n\nexport const navigationMenu = { init, update, connect, isOpen }\n"]}
1
+ {"version":3,"file":"navigation-menu.js","sourceRoot":"","sources":["../../src/components/navigation-menu.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Send, Signal } from '@llui/dom'\nimport { useContext, tagSend } from '@llui/dom'\nimport { LocaleContext } from '../locale.js'\n\n/**\n * Navigation menu — multi-level menu bar with hover/focus-triggered\n * submenus. Unlike `menu` (a single dropdown), navigation-menu supports\n * nested submenus arbitrarily deep and is typically used for primary\n * site navigation.\n *\n * State tracks the currently focused item id and the ids of all\n * currently-open branches. The consumer provides the tree structure\n * (items with optional children); the machine doesn't index the\n * hierarchy itself — it just maintains open-paths and lets the view\n * handle traversal.\n *\n * Typical interaction model (delay-based):\n * - Pointer enter on a branch → openBranch after openDelay\n * - Pointer leave of the whole tree → closeAll after closeDelay\n * - Click/keyboard activation → toggleBranch immediately\n *\n * The consumer is responsible for debouncing via setTimeout; the machine\n * just responds to the dispatched messages.\n */\n\nexport interface NavMenuState {\n /** Ids of open branches, in open order (root-first). Closing an\n * ancestor automatically closes its descendants. */\n open: string[]\n focused: string | null\n disabled: boolean\n}\n\nexport type NavMenuMsg =\n /** @intent(\"Open the submenu identified by id, closing any open siblings\") */\n | { type: 'openBranch'; id: string; ancestorIds: string[] }\n /** @intent(\"Close the submenu identified by id (also closes its descendants)\") */\n | { type: 'closeBranch'; id: string }\n /** @intent(\"Toggle the submenu identified by id open/closed\") */\n | { type: 'toggleBranch'; id: string; ancestorIds: string[] }\n /** @intent(\"Close every open submenu\") */\n | { type: 'closeAll' }\n /** @humanOnly */\n | { type: 'focus'; id: string | null }\n\nexport interface NavMenuInit {\n open?: string[]\n focused?: string | null\n disabled?: boolean\n}\n\nexport function init(opts: NavMenuInit = {}): NavMenuState {\n return {\n open: opts.open ?? [],\n focused: opts.focused ?? null,\n disabled: opts.disabled ?? false,\n }\n}\n\nexport function update(state: NavMenuState, msg: NavMenuMsg): [NavMenuState, never[]] {\n if (state.disabled) return [state, []]\n switch (msg.type) {\n case 'openBranch': {\n // Close any siblings of `id` at the same ancestor path, then add it.\n // Sibling detection: an entry is a sibling if its ancestor set matches\n // msg.ancestorIds and it isn't msg.id. We don't track ancestors in\n // state, so: filter `open` to keep only entries that are themselves\n // an ancestor of msg.id, plus msg.id.\n const keep = new Set([...msg.ancestorIds, msg.id])\n const open = state.open.filter((o) => keep.has(o))\n if (!open.includes(msg.id)) open.push(msg.id)\n return [{ ...state, open }, []]\n }\n case 'closeBranch': {\n // Close this branch and any descendants that follow it in the open\n // list. Since open is ordered root-first, descendants come after.\n const idx = state.open.indexOf(msg.id)\n if (idx === -1) return [state, []]\n const open = state.open.slice(0, idx)\n return [{ ...state, open }, []]\n }\n case 'toggleBranch':\n if (state.open.includes(msg.id)) {\n return update(state, { type: 'closeBranch', id: msg.id })\n }\n return update(state, { type: 'openBranch', id: msg.id, ancestorIds: msg.ancestorIds })\n case 'closeAll':\n return [{ ...state, open: [] }, []]\n case 'focus':\n return [{ ...state, focused: msg.id }, []]\n }\n}\n\nexport function isOpen(state: NavMenuState, id: string): boolean {\n return state.open.includes(id)\n}\n\nexport interface NavItemParts {\n trigger: {\n type: 'button'\n role: 'menuitem'\n id: string\n 'aria-haspopup': 'menu' | undefined\n 'aria-expanded': Signal<boolean | undefined>\n 'data-scope': 'navigation-menu'\n 'data-part': 'trigger'\n 'data-state': Signal<'open' | 'closed'>\n 'data-value': string\n tabIndex: Signal<number>\n onClick: (e: MouseEvent) => void\n onPointerEnter: (e: PointerEvent) => void\n onFocus: (e: FocusEvent) => void\n }\n content: {\n role: 'menu'\n id: string\n 'aria-labelledby': string\n 'data-scope': 'navigation-menu'\n 'data-part': 'content'\n 'data-state': Signal<'open' | 'closed'>\n hidden: Signal<boolean>\n onPointerEnter: (e: PointerEvent) => void\n }\n}\n\nexport interface NavMenuParts {\n root: {\n role: 'menubar'\n 'aria-label': string\n 'data-scope': 'navigation-menu'\n 'data-part': 'root'\n 'data-disabled': Signal<'' | undefined>\n onPointerLeave: (e: PointerEvent) => void\n onPointerEnter: (e: PointerEvent) => void\n }\n item: (id: string, options: { isBranch: boolean; ancestorIds?: string[] }) => NavItemParts\n}\n\nexport interface ConnectOptions {\n id: string\n label?: string\n /**\n * Whether pointer-leaving the whole menu closes everything. Default: true.\n * The consumer can inject their own close delay by intercepting\n * onPointerLeave + calling setTimeout + dispatching closeAll.\n */\n closeOnLeave?: boolean\n}\n\nexport function connect(\n state: Signal<NavMenuState>,\n send: Send<NavMenuMsg>,\n opts: ConnectOptions,\n): NavMenuParts {\n const locale = useContext(LocaleContext)\n const triggerId = (v: string): string => `${opts.id}:trigger:${v}`\n const contentId = (v: string): string => `${opts.id}:content:${v}`\n const closeOnLeave = opts.closeOnLeave !== false\n let closeTimer: ReturnType<typeof setTimeout> | null = null\n\n const scheduleClose = (): void => {\n if (!closeOnLeave) return\n if (closeTimer) clearTimeout(closeTimer)\n closeTimer = setTimeout(() => {\n send({ type: 'closeAll' })\n closeTimer = null\n }, 150)\n }\n\n const cancelClose = (): void => {\n if (closeTimer) {\n clearTimeout(closeTimer)\n closeTimer = null\n }\n }\n\n return {\n root: {\n role: 'menubar',\n 'aria-label': opts.label ?? locale.navigationMenu.label,\n 'data-scope': 'navigation-menu',\n 'data-part': 'root',\n 'data-disabled': state.map((st) => (st.disabled ? '' : undefined)),\n onPointerLeave: () => scheduleClose(),\n onPointerEnter: () => cancelClose(),\n },\n item: (id: string, options: { isBranch: boolean; ancestorIds?: string[] }): NavItemParts => {\n const ancestorIds = options.ancestorIds ?? []\n return {\n trigger: {\n type: 'button',\n role: 'menuitem',\n id: triggerId(id),\n 'aria-haspopup': options.isBranch ? 'menu' : undefined,\n 'aria-expanded': state.map((st) => (options.isBranch ? isOpen(st, id) : undefined)),\n 'data-scope': 'navigation-menu',\n 'data-part': 'trigger',\n 'data-state': state.map((st) => (isOpen(st, id) ? 'open' : 'closed')),\n 'data-value': id,\n tabIndex: state.map((st) => (st.focused === id ? 0 : -1)),\n onClick: tagSend(send, ['toggleBranch'], () => {\n if (options.isBranch) {\n send({ type: 'toggleBranch', id, ancestorIds })\n }\n }),\n onPointerEnter: tagSend(send, ['openBranch'], () => {\n cancelClose()\n if (options.isBranch) {\n send({ type: 'openBranch', id, ancestorIds })\n }\n }),\n onFocus: tagSend(send, ['focus'], () => send({ type: 'focus', id })),\n },\n content: {\n role: 'menu',\n id: contentId(id),\n 'aria-labelledby': triggerId(id),\n 'data-scope': 'navigation-menu',\n 'data-part': 'content',\n 'data-state': state.map((st) => (isOpen(st, id) ? 'open' : 'closed')),\n hidden: state.map((st) => !isOpen(st, id)),\n onPointerEnter: tagSend(send, ['openBranch'], () => {\n cancelClose()\n if (options.isBranch) {\n send({ type: 'openBranch', id, ancestorIds })\n }\n }),\n },\n }\n },\n }\n}\n\nexport const navigationMenu = { init, update, connect, isOpen }\n"]}
@@ -1,4 +1,4 @@
1
- import type { Send } from '@llui/dom';
1
+ import type { Send, Signal } from '@llui/dom';
2
2
  /**
3
3
  * Number input — numeric field with increment/decrement buttons. Clamps
4
4
  * to min/max and snaps to step. Keyboard: Arrow Up/Down, PageUp/PageDown,
@@ -62,24 +62,24 @@ export interface NumberInputInit {
62
62
  }
63
63
  export declare function init(opts?: NumberInputInit): NumberInputState;
64
64
  export declare function update(state: NumberInputState, msg: NumberInputMsg): [NumberInputState, never[]];
65
- export interface NumberInputParts<S> {
65
+ export interface NumberInputParts {
66
66
  root: {
67
67
  'data-scope': 'number-input';
68
68
  'data-part': 'root';
69
- 'data-disabled': (s: S) => '' | undefined;
69
+ 'data-disabled': Signal<'' | undefined>;
70
70
  };
71
71
  input: {
72
72
  type: 'text';
73
73
  role: 'spinbutton';
74
74
  inputMode: 'decimal';
75
- 'aria-valuemin': (s: S) => number | undefined;
76
- 'aria-valuemax': (s: S) => number | undefined;
77
- 'aria-valuenow': (s: S) => number | undefined;
78
- 'aria-disabled': (s: S) => 'true' | undefined;
79
- 'aria-readonly': (s: S) => 'true' | undefined;
80
- disabled: (s: S) => boolean;
81
- readOnly: (s: S) => boolean;
82
- value: (s: S) => string;
75
+ 'aria-valuemin': Signal<number | undefined>;
76
+ 'aria-valuemax': Signal<number | undefined>;
77
+ 'aria-valuenow': Signal<number | undefined>;
78
+ 'aria-disabled': Signal<'true' | undefined>;
79
+ 'aria-readonly': Signal<'true' | undefined>;
80
+ disabled: Signal<boolean>;
81
+ readOnly: Signal<boolean>;
82
+ value: Signal<string>;
83
83
  'data-scope': 'number-input';
84
84
  'data-part': 'input';
85
85
  onInput: (e: Event) => void;
@@ -88,9 +88,9 @@ export interface NumberInputParts<S> {
88
88
  };
89
89
  increment: {
90
90
  type: 'button';
91
- 'aria-label': string | ((s: S) => string);
92
- 'aria-disabled': (s: S) => 'true' | undefined;
93
- disabled: (s: S) => boolean;
91
+ 'aria-label': string;
92
+ 'aria-disabled': Signal<'true' | undefined>;
93
+ disabled: Signal<boolean>;
94
94
  'data-scope': 'number-input';
95
95
  'data-part': 'increment';
96
96
  tabIndex: -1;
@@ -98,9 +98,9 @@ export interface NumberInputParts<S> {
98
98
  };
99
99
  decrement: {
100
100
  type: 'button';
101
- 'aria-label': string | ((s: S) => string);
102
- 'aria-disabled': (s: S) => 'true' | undefined;
103
- disabled: (s: S) => boolean;
101
+ 'aria-label': string;
102
+ 'aria-disabled': Signal<'true' | undefined>;
103
+ disabled: Signal<boolean>;
104
104
  'data-scope': 'number-input';
105
105
  'data-part': 'decrement';
106
106
  tabIndex: -1;
@@ -113,7 +113,7 @@ export interface ConnectOptions {
113
113
  /** Validate the numeric value before committing. Non-empty array blocks setValue. */
114
114
  validate?: (value: number) => string[] | null;
115
115
  }
116
- export declare function connect<S>(get: (s: S) => NumberInputState, send: Send<NumberInputMsg>, opts?: ConnectOptions): NumberInputParts<S>;
116
+ export declare function connect(state: Signal<NumberInputState>, send: Send<NumberInputMsg>, opts?: ConnectOptions): NumberInputParts;
117
117
  export declare const numberInput: {
118
118
  init: typeof init;
119
119
  update: typeof update;
@@ -1 +1 @@
1
- {"version":3,"file":"number-input.d.ts","sourceRoot":"","sources":["../../src/components/number-input.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"number-input.d.ts","sourceRoot":"","sources":["../../src/components/number-input.ts"],"names":[],"mappings":"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"}