foldkit 0.101.0 → 0.102.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 (208) hide show
  1. package/README.md +2 -1
  2. package/dist/canvas/view.d.ts +1 -1
  3. package/dist/canvas/view.d.ts.map +1 -1
  4. package/dist/canvas/view.js +5 -5
  5. package/dist/command/index.d.ts +71 -0
  6. package/dist/command/index.d.ts.map +1 -1
  7. package/dist/command/index.js +34 -1
  8. package/dist/command/public.d.ts +1 -1
  9. package/dist/command/public.d.ts.map +1 -1
  10. package/dist/command/public.js +1 -1
  11. package/dist/devTools/overlay.d.ts.map +1 -1
  12. package/dist/devTools/overlay.js +137 -110
  13. package/dist/dom/dom.d.ts +8 -11
  14. package/dist/dom/dom.d.ts.map +1 -1
  15. package/dist/dom/dom.js +8 -11
  16. package/dist/dom/elementMovement.d.ts +1 -3
  17. package/dist/dom/elementMovement.d.ts.map +1 -1
  18. package/dist/dom/elementMovement.js +1 -3
  19. package/dist/dom/inert.d.ts +2 -4
  20. package/dist/dom/inert.d.ts.map +1 -1
  21. package/dist/dom/inert.js +2 -4
  22. package/dist/dom/scrollLock.d.ts +2 -2
  23. package/dist/dom/scrollLock.js +2 -2
  24. package/dist/dom/waitForAnimation.d.ts +1 -1
  25. package/dist/dom/waitForAnimation.js +1 -1
  26. package/dist/html/boundary.d.ts +98 -0
  27. package/dist/html/boundary.d.ts.map +1 -0
  28. package/dist/html/boundary.js +176 -0
  29. package/dist/html/childAttribute.d.ts +44 -0
  30. package/dist/html/childAttribute.d.ts.map +1 -0
  31. package/dist/html/childAttribute.js +34 -0
  32. package/dist/html/index.d.ts +70 -23
  33. package/dist/html/index.d.ts.map +1 -1
  34. package/dist/html/index.js +639 -575
  35. package/dist/html/lazy.d.ts +12 -7
  36. package/dist/html/lazy.d.ts.map +1 -1
  37. package/dist/html/lazy.js +30 -11
  38. package/dist/html/public.d.ts +2 -2
  39. package/dist/html/public.d.ts.map +1 -1
  40. package/dist/html/public.js +1 -1
  41. package/dist/html/runtimeSingleton.d.ts +72 -0
  42. package/dist/html/runtimeSingleton.d.ts.map +1 -0
  43. package/dist/html/runtimeSingleton.js +112 -0
  44. package/dist/html/submodel.d.ts +98 -0
  45. package/dist/html/submodel.d.ts.map +1 -0
  46. package/dist/html/submodel.js +190 -0
  47. package/dist/index.d.ts +1 -0
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +1 -0
  50. package/dist/render/render.d.ts +1 -1
  51. package/dist/render/render.js +1 -1
  52. package/dist/runtime/messagePriority.d.ts +5 -1
  53. package/dist/runtime/messagePriority.d.ts.map +1 -1
  54. package/dist/runtime/messagePriority.js +25 -4
  55. package/dist/runtime/runtime.d.ts +1 -1
  56. package/dist/runtime/runtime.d.ts.map +1 -1
  57. package/dist/runtime/runtime.js +115 -61
  58. package/dist/submodel/public.d.ts +4 -0
  59. package/dist/submodel/public.d.ts.map +1 -0
  60. package/dist/submodel/public.js +1 -0
  61. package/dist/submodel/submodel.d.ts +32 -0
  62. package/dist/submodel/submodel.d.ts.map +1 -0
  63. package/dist/submodel/submodel.js +1 -0
  64. package/dist/test/apps/disabledButton.d.ts +4 -5
  65. package/dist/test/apps/disabledButton.d.ts.map +1 -1
  66. package/dist/test/apps/disabledButton.js +16 -16
  67. package/dist/test/scene.d.ts +8 -8
  68. package/dist/test/scene.d.ts.map +1 -1
  69. package/dist/test/scene.js +25 -13
  70. package/dist/test/story.d.ts +15 -8
  71. package/dist/test/story.d.ts.map +1 -1
  72. package/dist/test/story.js +21 -9
  73. package/dist/ui/animation/index.d.ts +30 -14
  74. package/dist/ui/animation/index.d.ts.map +1 -1
  75. package/dist/ui/animation/index.js +9 -19
  76. package/dist/ui/animation/public.d.ts +2 -2
  77. package/dist/ui/animation/public.d.ts.map +1 -1
  78. package/dist/ui/animation/public.js +1 -1
  79. package/dist/ui/calendar/index.d.ts +199 -84
  80. package/dist/ui/calendar/index.d.ts.map +1 -1
  81. package/dist/ui/calendar/index.js +129 -140
  82. package/dist/ui/calendar/public.d.ts +2 -2
  83. package/dist/ui/calendar/public.d.ts.map +1 -1
  84. package/dist/ui/calendar/public.js +1 -1
  85. package/dist/ui/checkbox/index.d.ts +93 -21
  86. package/dist/ui/checkbox/index.d.ts.map +1 -1
  87. package/dist/ui/checkbox/index.js +62 -33
  88. package/dist/ui/checkbox/public.d.ts +2 -2
  89. package/dist/ui/checkbox/public.d.ts.map +1 -1
  90. package/dist/ui/checkbox/public.js +1 -1
  91. package/dist/ui/combobox/multi.d.ts +35 -91
  92. package/dist/ui/combobox/multi.d.ts.map +1 -1
  93. package/dist/ui/combobox/multi.js +34 -17
  94. package/dist/ui/combobox/multiPublic.d.ts +2 -2
  95. package/dist/ui/combobox/multiPublic.d.ts.map +1 -1
  96. package/dist/ui/combobox/multiPublic.js +1 -1
  97. package/dist/ui/combobox/public.d.ts +3 -3
  98. package/dist/ui/combobox/public.d.ts.map +1 -1
  99. package/dist/ui/combobox/public.js +2 -2
  100. package/dist/ui/combobox/shared.d.ts +56 -31
  101. package/dist/ui/combobox/shared.d.ts.map +1 -1
  102. package/dist/ui/combobox/shared.js +333 -322
  103. package/dist/ui/combobox/single.d.ts +46 -93
  104. package/dist/ui/combobox/single.d.ts.map +1 -1
  105. package/dist/ui/combobox/single.js +44 -17
  106. package/dist/ui/datePicker/index.d.ts +256 -48
  107. package/dist/ui/datePicker/index.d.ts.map +1 -1
  108. package/dist/ui/datePicker/index.js +149 -104
  109. package/dist/ui/datePicker/public.d.ts +2 -2
  110. package/dist/ui/datePicker/public.d.ts.map +1 -1
  111. package/dist/ui/datePicker/public.js +1 -1
  112. package/dist/ui/dialog/index.d.ts +95 -39
  113. package/dist/ui/dialog/index.d.ts.map +1 -1
  114. package/dist/ui/dialog/index.js +71 -62
  115. package/dist/ui/dialog/public.d.ts +2 -2
  116. package/dist/ui/dialog/public.d.ts.map +1 -1
  117. package/dist/ui/dialog/public.js +1 -1
  118. package/dist/ui/disclosure/index.d.ts +71 -31
  119. package/dist/ui/disclosure/index.d.ts.map +1 -1
  120. package/dist/ui/disclosure/index.js +57 -62
  121. package/dist/ui/disclosure/public.d.ts +2 -2
  122. package/dist/ui/disclosure/public.d.ts.map +1 -1
  123. package/dist/ui/disclosure/public.js +1 -1
  124. package/dist/ui/dragAndDrop/index.d.ts +6 -6
  125. package/dist/ui/dragAndDrop/index.d.ts.map +1 -1
  126. package/dist/ui/dragAndDrop/index.js +7 -7
  127. package/dist/ui/dragAndDrop/public.d.ts +1 -1
  128. package/dist/ui/dragAndDrop/public.d.ts.map +1 -1
  129. package/dist/ui/dragAndDrop/public.js +1 -1
  130. package/dist/ui/fileDrop/index.d.ts +42 -46
  131. package/dist/ui/fileDrop/index.d.ts.map +1 -1
  132. package/dist/ui/fileDrop/index.js +30 -46
  133. package/dist/ui/fileDrop/public.d.ts +2 -2
  134. package/dist/ui/fileDrop/public.d.ts.map +1 -1
  135. package/dist/ui/fileDrop/public.js +1 -1
  136. package/dist/ui/listbox/multi.d.ts +39 -84
  137. package/dist/ui/listbox/multi.d.ts.map +1 -1
  138. package/dist/ui/listbox/multi.js +38 -20
  139. package/dist/ui/listbox/multiPublic.d.ts +2 -2
  140. package/dist/ui/listbox/multiPublic.d.ts.map +1 -1
  141. package/dist/ui/listbox/multiPublic.js +1 -1
  142. package/dist/ui/listbox/public.d.ts +3 -3
  143. package/dist/ui/listbox/public.d.ts.map +1 -1
  144. package/dist/ui/listbox/public.js +2 -2
  145. package/dist/ui/listbox/shared.d.ts +71 -30
  146. package/dist/ui/listbox/shared.d.ts.map +1 -1
  147. package/dist/ui/listbox/shared.js +319 -296
  148. package/dist/ui/listbox/single.d.ts +57 -85
  149. package/dist/ui/listbox/single.d.ts.map +1 -1
  150. package/dist/ui/listbox/single.js +48 -24
  151. package/dist/ui/menu/index.d.ts +80 -36
  152. package/dist/ui/menu/index.d.ts.map +1 -1
  153. package/dist/ui/menu/index.js +117 -86
  154. package/dist/ui/menu/public.d.ts +2 -2
  155. package/dist/ui/menu/public.d.ts.map +1 -1
  156. package/dist/ui/menu/public.js +1 -1
  157. package/dist/ui/popover/index.d.ts +117 -44
  158. package/dist/ui/popover/index.d.ts.map +1 -1
  159. package/dist/ui/popover/index.js +88 -101
  160. package/dist/ui/popover/public.d.ts +2 -2
  161. package/dist/ui/popover/public.d.ts.map +1 -1
  162. package/dist/ui/popover/public.js +1 -1
  163. package/dist/ui/radioGroup/index.d.ts +122 -45
  164. package/dist/ui/radioGroup/index.d.ts.map +1 -1
  165. package/dist/ui/radioGroup/index.js +111 -72
  166. package/dist/ui/radioGroup/public.d.ts +2 -2
  167. package/dist/ui/radioGroup/public.d.ts.map +1 -1
  168. package/dist/ui/radioGroup/public.js +1 -1
  169. package/dist/ui/slider/index.d.ts +72 -34
  170. package/dist/ui/slider/index.d.ts.map +1 -1
  171. package/dist/ui/slider/index.js +40 -49
  172. package/dist/ui/slider/public.d.ts +2 -2
  173. package/dist/ui/slider/public.d.ts.map +1 -1
  174. package/dist/ui/slider/public.js +1 -1
  175. package/dist/ui/switch/index.d.ts +74 -21
  176. package/dist/ui/switch/index.d.ts.map +1 -1
  177. package/dist/ui/switch/index.js +62 -33
  178. package/dist/ui/switch/public.d.ts +2 -2
  179. package/dist/ui/switch/public.d.ts.map +1 -1
  180. package/dist/ui/switch/public.js +1 -1
  181. package/dist/ui/tabs/index.d.ts +107 -45
  182. package/dist/ui/tabs/index.d.ts.map +1 -1
  183. package/dist/ui/tabs/index.js +99 -81
  184. package/dist/ui/tabs/public.d.ts +2 -2
  185. package/dist/ui/tabs/public.d.ts.map +1 -1
  186. package/dist/ui/tabs/public.js +1 -1
  187. package/dist/ui/toast/index.d.ts +93 -109
  188. package/dist/ui/toast/index.d.ts.map +1 -1
  189. package/dist/ui/toast/index.js +16 -29
  190. package/dist/ui/toast/schema.d.ts +15 -4
  191. package/dist/ui/toast/schema.d.ts.map +1 -1
  192. package/dist/ui/toast/schema.js +11 -4
  193. package/dist/ui/toast/update.d.ts +36 -18
  194. package/dist/ui/toast/update.d.ts.map +1 -1
  195. package/dist/ui/toast/update.js +33 -14
  196. package/dist/ui/tooltip/index.d.ts +94 -42
  197. package/dist/ui/tooltip/index.d.ts.map +1 -1
  198. package/dist/ui/tooltip/index.js +64 -73
  199. package/dist/ui/tooltip/public.d.ts +2 -2
  200. package/dist/ui/tooltip/public.d.ts.map +1 -1
  201. package/dist/ui/tooltip/public.js +1 -1
  202. package/dist/ui/virtualList/index.d.ts +18 -41
  203. package/dist/ui/virtualList/index.d.ts.map +1 -1
  204. package/dist/ui/virtualList/index.js +17 -37
  205. package/dist/ui/virtualList/public.d.ts +2 -2
  206. package/dist/ui/virtualList/public.d.ts.map +1 -1
  207. package/dist/ui/virtualList/public.js +1 -1
  208. package/package.json +1 -1
@@ -1,7 +1,8 @@
1
1
  import { Option, Schema as S } from 'effect';
2
2
  import type * as Command from '../../command/index.js';
3
- import { type Html } from '../../html/index.js';
4
- import { type BaseInitConfig, type BaseViewConfig, Closed, type Message, Opened, SelectedItem } from './shared.js';
3
+ import type { SubmodelView } from '../../html/index.js';
4
+ import type { Reflect } from '../../submodel/submodel.js';
5
+ import { type BaseInitConfig, type BaseViewInputs, type Message, type OutMessage } from './shared.js';
5
6
  /** Schema for the single-select combobox component's state, tracking open/closed status, active item, input value, selected item, and display text. */
6
7
  export declare const Model: S.Struct<{
7
8
  readonly maybeSelectedItem: S.Option<S.String>;
@@ -91,9 +92,9 @@ export declare const update: (model: {
91
92
  } | {
92
93
  readonly _tag: "CompletedUnlockScroll";
93
94
  } | {
94
- readonly _tag: "CompletedSetupInert";
95
+ readonly _tag: "CompletedInertOthers";
95
96
  } | {
96
- readonly _tag: "CompletedTeardownInert";
97
+ readonly _tag: "CompletedRestoreInert";
97
98
  } | {
98
99
  readonly _tag: "CompletedScrollIntoView";
99
100
  } | {
@@ -150,97 +151,49 @@ export declare const update: (model: {
150
151
  } | {
151
152
  readonly _tag: "PressedToggleButton";
152
153
  }, never, never>;
153
- }>[]];
154
+ }>[], Option.Option<Readonly<{
155
+ readonly _tag: "Selected";
156
+ readonly value: string;
157
+ readonly wasAdded: boolean;
158
+ }>>];
159
+ type UpdateReturn = ReturnType<typeof update>;
154
160
  /** Programmatically opens the combobox, updating the model and returning
155
161
  * focus and modal commands. Use this in domain-event handlers to open the combobox. */
156
- export declare const open: (model: Model) => readonly [Model, ReadonlyArray<Command.Command<Message>>];
162
+ export declare const open: (model: Model) => UpdateReturn;
157
163
  /** Programmatically closes the combobox, updating the model and returning
158
164
  * focus and modal commands. Use this in domain-event handlers to close the combobox. */
159
- export declare const close: (model: Model) => readonly [Model, ReadonlyArray<Command.Command<Message>>];
160
- /** Programmatically selects an item in the single-select combobox, closing the combobox and returning
161
- * focus commands. Use this in domain-event handlers when the combobox uses `onSelectedItem`. */
162
- export declare const selectItem: (model: Model, item: string, displayText: string) => readonly [Model, ReadonlyArray<Command.Command<Message>>];
163
- /** Configuration for rendering a single-select combobox with `view`. */
164
- export type ViewConfig<ParentMessage, Item extends string> = BaseViewConfig<ParentMessage, Item, Model>;
165
- /** Renders a headless single-select combobox with keyboard navigation, selection tracking, and aria-activedescendant focus management. */
166
- export declare const view: <ParentMessage, Item extends string>(config: Readonly<{
167
- model: {
168
- readonly maybeSelectedItem: Option.Option<string>;
169
- readonly maybeSelectedDisplayText: Option.Option<string>;
170
- readonly id: string;
171
- readonly isOpen: boolean;
172
- readonly isAnimated: boolean;
173
- readonly isModal: boolean;
174
- readonly nullable: boolean;
175
- readonly immediate: boolean;
176
- readonly selectInputOnFocus: boolean;
177
- readonly animation: {
178
- readonly id: string;
179
- readonly isShowing: boolean;
180
- readonly transitionState: "Idle" | "EnterStart" | "EnterAnimating" | "LeaveStart" | "LeaveAnimating";
181
- };
182
- readonly maybeActiveItemIndex: Option.Option<number>;
183
- readonly activationTrigger: "Pointer" | "Keyboard";
184
- readonly inputValue: string;
185
- readonly maybeLastPointerPosition: Option.Option<{
186
- readonly screenX: number;
187
- readonly screenY: number;
188
- }>;
189
- };
190
- toParentMessage: (message: Opened | Closed | import("./shared.js").BlurredInput | import("./shared.js").ActivatedItem | import("./shared.js").DeactivatedItem | SelectedItem | import("./shared.js").MovedPointerOverItem | import("./shared.js").RequestedItemClick | import("./shared.js").UpdatedInputValue | import("./shared.js").PressedToggleButton | {
191
- readonly _tag: "CompletedAnchorCombobox";
192
- } | {
193
- readonly _tag: "CompletedAttachComboboxPreventBlur";
194
- } | {
195
- readonly _tag: "CompletedAttachComboboxSelectOnFocus";
196
- } | {
197
- readonly _tag: "CompletedPortalComboboxBackdrop";
198
- }) => ParentMessage;
199
- onSelectedItem?: (value: string) => ParentMessage;
200
- items: readonly Item[];
201
- itemToConfig: (item: Item, context: Readonly<{
202
- isActive: boolean;
203
- isDisabled: boolean;
204
- isSelected: boolean;
205
- }>) => Readonly<{
206
- className?: string;
207
- content: Html;
208
- }>;
209
- itemToValue: (item: Item, index: number) => string;
210
- itemToDisplayText: (item: Item, index: number) => string;
211
- isItemDisabled?: (item: Item, index: number) => boolean;
212
- inputClassName?: string;
213
- inputAttributes?: readonly import("../../html/index.js").Attribute<ParentMessage>[];
214
- inputPlaceholder?: string;
215
- inputWrapperClassName?: string;
216
- inputWrapperAttributes?: readonly import("../../html/index.js").Attribute<ParentMessage>[];
217
- itemsClassName?: string;
218
- itemsAttributes?: readonly import("../../html/index.js").Attribute<ParentMessage>[];
219
- itemsScrollClassName?: string;
220
- itemsScrollAttributes?: readonly import("../../html/index.js").Attribute<ParentMessage>[];
221
- backdropClassName?: string;
222
- backdropAttributes?: readonly import("../../html/index.js").Attribute<ParentMessage>[];
223
- className?: string;
224
- attributes?: readonly import("../../html/index.js").Attribute<ParentMessage>[];
225
- buttonContent?: Html;
226
- buttonClassName?: string;
227
- buttonAttributes?: readonly import("../../html/index.js").Attribute<ParentMessage>[];
228
- formName?: string;
229
- isDisabled?: boolean;
230
- isInvalid?: boolean;
231
- openOnFocus?: boolean;
232
- itemGroupKey?: (item: Item, index: number) => string;
233
- groupToHeading?: (groupKey: string) => Readonly<{
234
- content: Html;
235
- className?: string;
236
- }> | undefined;
237
- groupClassName?: string;
238
- groupAttributes?: readonly import("../../html/index.js").Attribute<ParentMessage>[];
239
- separatorClassName?: string;
240
- separatorAttributes?: readonly import("../../html/index.js").Attribute<ParentMessage>[];
241
- anchor?: import("./public.js").AnchorConfig;
242
- }>) => Html;
243
- /** Creates a memoized single-select combobox view. Static config is captured in a closure;
244
- * only `model` and `toParentMessage` are compared per render via `createLazy`. */
245
- export declare const lazy: <ParentMessage, Item extends string>(staticConfig: Omit<ViewConfig<ParentMessage, Item>, "model" | "toParentMessage" | "onSelectedItem">) => ((model: Model, toParentMessage: BaseViewConfig<ParentMessage, Item, Model>["toParentMessage"]) => Html);
165
+ export declare const close: (model: Model) => UpdateReturn;
166
+ /** Programmatically selects an item in the single-select combobox. Emits `Selected({ value, wasAdded })`. */
167
+ export declare const selectItem: (model: Model, item: string, displayText: string) => UpdateReturn;
168
+ /** Reflects an externally-sourced selection onto the model without
169
+ * emitting an OutMessage or running selection side effects (no close, no
170
+ * focus). Sets the selected item, its display text, and the input text
171
+ * together, so the input shows the reflected selection. Pass
172
+ * `Option.none()` to clear. Use this to mirror external truth (a URL
173
+ * parameter, restored storage, a server push) onto the combobox.
174
+ * Contrast with `selectItem`, a user/programmatic *choice* that emits
175
+ * `Selected`. Returns the model directly because it produces no commands
176
+ * and no OutMessage. */
177
+ export declare const reflectSelectedItem: Reflect<Model, Option.Option<{
178
+ readonly item: string;
179
+ readonly displayText: string;
180
+ }>>;
181
+ /** Per-render view inputs passed to the view via `h.submodel`'s `viewInputs` field. */
182
+ export type ViewInputs<Item extends string> = BaseViewInputs<Item>;
183
+ /** Pairs the single-select combobox's `view` and `update` (and programmatic
184
+ * helpers) behind a single Item-typed entry point. See `Ui.Listbox.create`
185
+ * for the rationale; the combobox factory follows the same shape with
186
+ * `selectItem` taking both `item` and `displayText`. */
187
+ export declare const create: <Item extends string = string>() => Readonly<{
188
+ view: SubmodelView<Model, Message, BaseViewInputs<Item>>;
189
+ update: (model: Model, message: Message) => readonly [Model, ReadonlyArray<Command.Command<Message>>, Option.Option<OutMessage<Item>>];
190
+ selectItem: (model: Model, item: Item, displayText: string) => readonly [Model, ReadonlyArray<Command.Command<Message>>, Option.Option<OutMessage<Item>>];
191
+ open: (model: Model) => readonly [Model, ReadonlyArray<Command.Command<Message>>, Option.Option<OutMessage<Item>>];
192
+ close: (model: Model) => readonly [Model, ReadonlyArray<Command.Command<Message>>, Option.Option<OutMessage<Item>>];
193
+ reflectSelectedItem: Reflect<Model, Option.Option<{
194
+ readonly item: Item;
195
+ readonly displayText: string;
196
+ }>>;
197
+ }>;
198
+ export {};
246
199
  //# sourceMappingURL=single.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"single.d.ts","sourceRoot":"","sources":["../../../src/ui/combobox/single.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAAE,MAAM,IAAI,CAAC,EAAQ,MAAM,QAAQ,CAAA;AAEzD,OAAO,KAAK,KAAK,OAAO,MAAM,wBAAwB,CAAA;AACtD,OAAO,EAAE,KAAK,IAAI,EAAc,MAAM,qBAAqB,CAAA;AAE3D,OAAO,EACL,KAAK,cAAc,EAEnB,KAAK,cAAc,EACnB,MAAM,EACN,KAAK,OAAO,EACZ,MAAM,EACN,YAAY,EAKb,MAAM,aAAa,CAAA;AAIpB,uJAAuJ;AACvJ,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;EAIhB,CAAA;AAEF,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAA;AAIrC,8RAA8R;AAC9R,MAAM,MAAM,UAAU,GAAG,cAAc,GACrC,QAAQ,CAAC;IACP,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAC7B,CAAC,CAAA;AAEJ,4IAA4I;AAC5I,eAAO,MAAM,IAAI,GAAI,QAAQ,UAAU,KAAG,KAMxC,CAAA;AAIF,uIAAuI;AACvI,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAiDjB,CAAA;AAEF;wFACwF;AACxF,eAAO,MAAM,IAAI,GACf,OAAO,KAAK,KACX,SAAS,CAAC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CACK,CAAA;AAEhE;yFACyF;AACzF,eAAO,MAAM,KAAK,GAChB,OAAO,KAAK,KACX,SAAS,CAAC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAClC,CAAA;AAEzB;iGACiG;AACjG,eAAO,MAAM,UAAU,GACrB,OAAO,KAAK,EACZ,MAAM,MAAM,EACZ,aAAa,MAAM,KAClB,SAAS,CAAC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CACP,CAAA;AAIpD,wEAAwE;AACxE,MAAM,MAAM,UAAU,CAAC,aAAa,EAAE,IAAI,SAAS,MAAM,IAAI,cAAc,CACzE,aAAa,EACb,IAAI,EACJ,KAAK,CACN,CAAA;AAED,0IAA0I;AAC1I,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAOf,CAAA;AAEF;mFACmF;AACnF,eAAO,MAAM,IAAI,GAAI,aAAa,EAAE,IAAI,SAAS,MAAM,EACrD,cAAc,IAAI,CAChB,UAAU,CAAC,aAAa,EAAE,IAAI,CAAC,EAC/B,OAAO,GAAG,iBAAiB,GAAG,gBAAgB,CAC/C,KACA,CAAC,CACF,KAAK,EAAE,KAAK,EACZ,eAAe,EAAE,cAAc,CAC7B,aAAa,EACb,IAAI,EACJ,KAAK,CACN,CAAC,iBAAiB,CAAC,KACjB,IAAI,CAoBR,CAAA"}
1
+ {"version":3,"file":"single.d.ts","sourceRoot":"","sources":["../../../src/ui/combobox/single.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,6 @@
1
- import { Array, Option, Schema as S, pipe } from 'effect';
2
- import { createLazy } from '../../html/index.js';
1
+ import { Array, Function, Option, Schema as S, pipe } from 'effect';
3
2
  import { evo } from '../../struct/index.js';
4
- import { BaseModel, Closed, Opened, SelectedItem, baseInit, closedBaseModel, makeUpdate, makeView, } from './shared.js';
3
+ import { BaseModel, Closed, Opened, SelectedItem, Selected as SharedSelected, baseInit, closedBaseModel, makeUpdate, makeView, } from './shared.js';
5
4
  // MODEL
6
5
  /** Schema for the single-select combobox component's state, tracking open/closed status, active item, input value, selected item, and display text. */
7
6
  export const Model = S.Struct({
@@ -32,7 +31,8 @@ export const update = makeUpdate({
32
31
  },
33
32
  handleSelectedItem: (model, item, displayText, context) => {
34
33
  const isAlreadySelected = Option.exists(model.maybeSelectedItem, selectedItem => selectedItem === item);
35
- const nextModel = model.nullable && isAlreadySelected
34
+ const nullableDeselect = model.nullable && isAlreadySelected;
35
+ const nextModel = nullableDeselect
36
36
  ? evo(closedBaseModel(model), {
37
37
  inputValue: () => '',
38
38
  maybeSelectedItem: () => Option.none(),
@@ -46,6 +46,7 @@ export const update = makeUpdate({
46
46
  return [
47
47
  nextModel,
48
48
  pipe(Array.getSomes([context.maybeUnlockScroll, context.maybeRestoreInert]), Array.prepend(context.focusInput)),
49
+ Option.some(SharedSelected({ value: item, wasAdded: !nullableDeselect })),
49
50
  ];
50
51
  },
51
52
  handleImmediateActivation: (model, item, displayText) => evo(model, {
@@ -59,21 +60,47 @@ export const open = (model) => update(model, Opened({ maybeActiveItemIndex: Opti
59
60
  /** Programmatically closes the combobox, updating the model and returning
60
61
  * focus and modal commands. Use this in domain-event handlers to close the combobox. */
61
62
  export const close = (model) => update(model, Closed());
62
- /** Programmatically selects an item in the single-select combobox, closing the combobox and returning
63
- * focus commands. Use this in domain-event handlers when the combobox uses `onSelectedItem`. */
63
+ /** Programmatically selects an item in the single-select combobox. Emits `Selected({ value, wasAdded })`. */
64
64
  export const selectItem = (model, item, displayText) => update(model, SelectedItem({ item, displayText }));
65
- /** Renders a headless single-select combobox with keyboard navigation, selection tracking, and aria-activedescendant focus management. */
66
- export const view = makeView({
65
+ /** Reflects an externally-sourced selection onto the model without
66
+ * emitting an OutMessage or running selection side effects (no close, no
67
+ * focus). Sets the selected item, its display text, and the input text
68
+ * together, so the input shows the reflected selection. Pass
69
+ * `Option.none()` to clear. Use this to mirror external truth (a URL
70
+ * parameter, restored storage, a server push) onto the combobox.
71
+ * Contrast with `selectItem`, a user/programmatic *choice* that emits
72
+ * `Selected`. Returns the model directly because it produces no commands
73
+ * and no OutMessage. */
74
+ export const reflectSelectedItem = Function.dual(2, (model, maybeSelection) => Option.match(maybeSelection, {
75
+ onNone: () => evo(model, {
76
+ maybeSelectedItem: () => Option.none(),
77
+ maybeSelectedDisplayText: () => Option.none(),
78
+ inputValue: () => '',
79
+ }),
80
+ onSome: ({ item, displayText }) => evo(model, {
81
+ maybeSelectedItem: () => Option.some(item),
82
+ maybeSelectedDisplayText: () => Option.some(displayText),
83
+ inputValue: () => displayText,
84
+ }),
85
+ }));
86
+ const internalView = makeView({
67
87
  isItemSelected: (model, itemValue) => Option.exists(model.maybeSelectedItem, selectedItem => selectedItem === itemValue),
68
88
  ariaMultiSelectable: false,
69
89
  });
70
- /** Creates a memoized single-select combobox view. Static config is captured in a closure;
71
- * only `model` and `toParentMessage` are compared per render via `createLazy`. */
72
- export const lazy = (staticConfig) => {
73
- const lazyView = createLazy();
74
- return (model, toParentMessage) => lazyView((currentModel, currentToParentMessage) => view({
75
- ...staticConfig,
76
- model: currentModel,
77
- toParentMessage: currentToParentMessage,
78
- }), [model, toParentMessage]);
90
+ /** Pairs the single-select combobox's `view` and `update` (and programmatic
91
+ * helpers) behind a single Item-typed entry point. See `Ui.Listbox.create`
92
+ * for the rationale; the combobox factory follows the same shape with
93
+ * `selectItem` taking both `item` and `displayText`. */
94
+ export const create = () => {
95
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
96
+ const typedUpdate = update;
97
+ return {
98
+ view: internalView(),
99
+ update: typedUpdate,
100
+ selectItem: (model, item, displayText) => typedUpdate(model, SelectedItem({ item, displayText })),
101
+ open: model => typedUpdate(model, Opened({ maybeActiveItemIndex: Option.none() })),
102
+ close: model => typedUpdate(model, Closed()),
103
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
104
+ reflectSelectedItem: reflectSelectedItem,
105
+ };
79
106
  };