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,6 +1,7 @@
1
- import { Schema as S } from 'effect';
1
+ import { Option, Schema as S } from 'effect';
2
2
  import type { Command } from '../../command/index.js';
3
- import { type Attribute, type Html } from '../../html/index.js';
3
+ import { type ChildAttribute, type Html } from '../../html/index.js';
4
+ import type { Reflect } from '../../submodel/submodel.js';
4
5
  /** Schema for the checkbox component's state, tracking the checked status. */
5
6
  export declare const Model: S.Struct<{
6
7
  readonly id: S.String;
@@ -9,10 +10,35 @@ export declare const Model: S.Struct<{
9
10
  export type Model = typeof Model.Type;
10
11
  /** Sent when the user toggles the checkbox via click or Space key. */
11
12
  export declare const Toggled: import("../../schema/index.js").CallableTaggedStruct<"Toggled", {}>;
13
+ /** Sent to set the checked state to a specific value. Use this for
14
+ * programmatic state assignment (e.g. a "select all" handler that forces
15
+ * all child checkboxes to the same state) where `Toggled`'s flip semantics
16
+ * would not reliably reach the desired state. */
17
+ export declare const SetChecked: import("../../schema/index.js").CallableTaggedStruct<"SetChecked", {
18
+ isChecked: S.Boolean;
19
+ }>;
12
20
  /** Schema for all messages the checkbox component can produce. */
13
- export declare const Message: import("../../schema/index.js").CallableTaggedStruct<"Toggled", {}>;
21
+ export declare const Message: S.Union<readonly [import("../../schema/index.js").CallableTaggedStruct<"Toggled", {}>, import("../../schema/index.js").CallableTaggedStruct<"SetChecked", {
22
+ isChecked: S.Boolean;
23
+ }>]>;
14
24
  export type Toggled = typeof Toggled.Type;
25
+ export type SetChecked = typeof SetChecked.Type;
15
26
  export type Message = typeof Message.Type;
27
+ /** Sent to the parent each time the checkbox toggles. Carries the new
28
+ * checked state. Consumers pattern-match this in their `GotCheckboxMessage`
29
+ * handler to lift the toggle into a domain Message (e.g., persisting the
30
+ * flag, dispatching a save command). */
31
+ export declare const ToggledChecked: import("../../schema/index.js").CallableTaggedStruct<"ToggledChecked", {
32
+ isChecked: S.Boolean;
33
+ }>;
34
+ /** Union of out-messages the checkbox component can produce. Surfaced as
35
+ * the third element of `update`'s return tuple and pattern-matched by
36
+ * the parent. */
37
+ export declare const OutMessage: S.Union<readonly [import("../../schema/index.js").CallableTaggedStruct<"ToggledChecked", {
38
+ isChecked: S.Boolean;
39
+ }>]>;
40
+ export type ToggledChecked = typeof ToggledChecked.Type;
41
+ export type OutMessage = typeof OutMessage.Type;
16
42
  /** Configuration for creating a checkbox model with `init`. */
17
43
  export type InitConfig = Readonly<{
18
44
  id: string;
@@ -20,28 +46,74 @@ export type InitConfig = Readonly<{
20
46
  }>;
21
47
  /** Creates an initial checkbox model from a config. Defaults to unchecked. */
22
48
  export declare const init: (config: InitConfig) => Model;
23
- /** Processes a checkbox message and returns the next model and commands. */
24
- export declare const update: (model: Model, _message: Message) => readonly [Model, ReadonlyArray<Command<Message>>];
25
- /** Attribute groups the checkbox component provides to the consumer's `toView` callback. */
26
- export type CheckboxAttributes<ParentMessage> = Readonly<{
27
- checkbox: ReadonlyArray<Attribute<ParentMessage>>;
28
- label: ReadonlyArray<Attribute<ParentMessage>>;
29
- description: ReadonlyArray<Attribute<ParentMessage>>;
30
- hiddenInput: ReadonlyArray<Attribute<ParentMessage>>;
49
+ /** Processes a checkbox message and returns the next model, commands,
50
+ * and a `ToggledChecked` OutMessage carrying the new checked state. */
51
+ export declare const update: (model: Model, message: Message) => readonly [Model, ReadonlyArray<Command<Message>>, Option.Option<OutMessage>];
52
+ /** Programmatically sets the checked state. Emits a `ToggledChecked`
53
+ * OutMessage just like a user-initiated toggle. Use this in domain-event
54
+ * handlers where you need to force a specific state (e.g. "select all"). */
55
+ export declare const setChecked: (model: Model, isChecked: boolean) => readonly [Model, ReadonlyArray<Command<Message>>, Option.Option<OutMessage>];
56
+ /** Reflects an externally-sourced checked state onto the model without
57
+ * emitting an OutMessage. Use this to mirror external truth (saved
58
+ * settings, a server value) onto the checkbox without triggering the
59
+ * downstream reaction a user toggle would cause. Contrast with
60
+ * `setChecked`, which emits `ToggledChecked` so the parent reacts to a
61
+ * programmatic assignment the same way it reacts to a user toggle. Returns
62
+ * the model directly because it produces no commands and no OutMessage. */
63
+ export declare const reflectChecked: Reflect<Model, boolean>;
64
+ /** Attribute groups the checkbox component provides to the consumer's
65
+ * `toView` callback. Each group is a `ReadonlyArray<ChildAttribute>`:
66
+ * attributes published from inside Checkbox's own boundary that the
67
+ * consumer can spread directly into its own element attribute arrays:
68
+ *
69
+ * ```ts
70
+ * toView: attributes =>
71
+ * h.div(
72
+ * [...attributes.checkbox, h.Class('my-class'), h.OnClick(MyOwnMsg())],
73
+ * [...],
74
+ * )
75
+ * ```
76
+ *
77
+ * Checkbox's own `OnClick(Toggled())` handlers (carried inside
78
+ * `attributes.checkbox` etc.) dispatch `Toggled` through Checkbox's
79
+ * boundary wrap at event-fire time. The consumer's own
80
+ * `OnClick(MyOwnMsg())` lives in the parent's boundary and dispatches
81
+ * unwrapped. The two routes are tracked separately by the runtime; the
82
+ * consumer never has to think about which boundary an attribute belongs
83
+ * to. */
84
+ export type CheckboxAttributes = Readonly<{
85
+ checkbox: ReadonlyArray<ChildAttribute>;
86
+ label: ReadonlyArray<ChildAttribute>;
87
+ description: ReadonlyArray<ChildAttribute>;
88
+ hiddenInput: ReadonlyArray<ChildAttribute>;
31
89
  }>;
32
- /** Configuration for rendering a checkbox with `view`. */
33
- export type ViewConfig<ParentMessage> = Readonly<{
34
- model: Model;
35
- toParentMessage: (message: Toggled) => ParentMessage;
36
- toView: (attributes: CheckboxAttributes<ParentMessage>) => Html;
90
+ /** Per-render view inputs passed to `view` via `h.submodel`'s `viewInputs` field.
91
+ * Slot content (`toView`) and behavioral flags live here; the parent
92
+ * declares them at the embed site rather than threading them through the
93
+ * Submodel as a generic-parameterized callback. */
94
+ export type ViewInputs = Readonly<{
95
+ toView: (attributes: CheckboxAttributes) => Html;
37
96
  isDisabled?: boolean;
38
97
  isIndeterminate?: boolean;
39
98
  name?: string;
40
99
  value?: string;
41
100
  }>;
42
- /** Renders an accessible checkbox by building ARIA attribute groups and delegating layout to the consumer's `toView` callback. */
43
- export declare const view: <ParentMessage>(config: ViewConfig<ParentMessage>) => Html;
44
- /** Creates a memoized checkbox view. Static config is captured in a closure;
45
- * only `model` and `toParentMessage` are compared per render via `createLazy`. */
46
- export declare const lazy: <ParentMessage>(staticConfig: Omit<ViewConfig<ParentMessage>, "model" | "toParentMessage">) => ((model: Model, toParentMessage: ViewConfig<ParentMessage>["toParentMessage"]) => Html);
101
+ /** Renders an accessible checkbox by building ARIA attribute groups and
102
+ * delegating layout to the consumer's `toView` callback. Embedded via
103
+ * `h.submodel`. */
104
+ export declare const view: import("../../html/submodel.js").SubmodelView<{
105
+ readonly id: string;
106
+ readonly isChecked: boolean;
107
+ }, {
108
+ readonly _tag: "Toggled";
109
+ } | {
110
+ readonly _tag: "SetChecked";
111
+ readonly isChecked: boolean;
112
+ }, Readonly<{
113
+ toView: (attributes: CheckboxAttributes) => Html;
114
+ isDisabled?: boolean;
115
+ isIndeterminate?: boolean;
116
+ name?: string;
117
+ value?: string;
118
+ }>>;
47
119
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/checkbox/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,MAAM,IAAI,CAAC,EAAE,MAAM,QAAQ,CAAA;AAExD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;AACrD,OAAO,EACL,KAAK,SAAS,EACd,KAAK,IAAI,EAGV,MAAM,qBAAqB,CAAA;AAM5B,8EAA8E;AAC9E,eAAO,MAAM,KAAK;;;EAGhB,CAAA;AAEF,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAA;AAIrC,sEAAsE;AACtE,eAAO,MAAM,OAAO,qEAAe,CAAA;AAEnC,kEAAkE;AAClE,eAAO,MAAM,OAAO,qEAAU,CAAA;AAE9B,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAA;AAEzC,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAA;AAIzC,+DAA+D;AAC/D,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAC,CAAA;AAEF,8EAA8E;AAC9E,eAAO,MAAM,IAAI,GAAI,QAAQ,UAAU,KAAG,KAGxC,CAAA;AAIF,4EAA4E;AAC5E,eAAO,MAAM,MAAM,GACjB,OAAO,KAAK,EACZ,UAAU,OAAO,KAChB,SAAS,CAAC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAGlD,CAAA;AAID,4FAA4F;AAC5F,MAAM,MAAM,kBAAkB,CAAC,aAAa,IAAI,QAAQ,CAAC;IACvD,QAAQ,EAAE,aAAa,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAA;IACjD,KAAK,EAAE,aAAa,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAA;IAC9C,WAAW,EAAE,aAAa,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAA;IACpD,WAAW,EAAE,aAAa,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAA;CACrD,CAAC,CAAA;AAEF,0DAA0D;AAC1D,MAAM,MAAM,UAAU,CAAC,aAAa,IAAI,QAAQ,CAAC;IAC/C,KAAK,EAAE,KAAK,CAAA;IACZ,eAAe,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,aAAa,CAAA;IACpD,MAAM,EAAE,CAAC,UAAU,EAAE,kBAAkB,CAAC,aAAa,CAAC,KAAK,IAAI,CAAA;IAC/D,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAC,CAAA;AAKF,kIAAkI;AAClI,eAAO,MAAM,IAAI,GAAI,aAAa,EAChC,QAAQ,UAAU,CAAC,aAAa,CAAC,KAChC,IA6DF,CAAA;AAED;mFACmF;AACnF,eAAO,MAAM,IAAI,GAAI,aAAa,EAChC,cAAc,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,OAAO,GAAG,iBAAiB,CAAC,KACzE,CAAC,CACF,KAAK,EAAE,KAAK,EACZ,eAAe,EAAE,UAAU,CAAC,aAAa,CAAC,CAAC,iBAAiB,CAAC,KAC1D,IAAI,CAgBR,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/checkbox/index.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { Match as M, Option, Schema as S } from 'effect';
2
- import { createLazy, html, } from '../../html/index.js';
1
+ import { Function, Match as M, Option, Schema as S } from 'effect';
2
+ import { childAttributes, defineView, html, } from '../../html/index.js';
3
3
  import { m } from '../../message/index.js';
4
4
  import { evo } from '../../struct/index.js';
5
5
  // MODEL
@@ -11,26 +11,68 @@ export const Model = S.Struct({
11
11
  // MESSAGE
12
12
  /** Sent when the user toggles the checkbox via click or Space key. */
13
13
  export const Toggled = m('Toggled');
14
+ /** Sent to set the checked state to a specific value. Use this for
15
+ * programmatic state assignment (e.g. a "select all" handler that forces
16
+ * all child checkboxes to the same state) where `Toggled`'s flip semantics
17
+ * would not reliably reach the desired state. */
18
+ export const SetChecked = m('SetChecked', { isChecked: S.Boolean });
14
19
  /** Schema for all messages the checkbox component can produce. */
15
- export const Message = Toggled;
20
+ export const Message = S.Union([Toggled, SetChecked]);
21
+ // OUT MESSAGE
22
+ /** Sent to the parent each time the checkbox toggles. Carries the new
23
+ * checked state. Consumers pattern-match this in their `GotCheckboxMessage`
24
+ * handler to lift the toggle into a domain Message (e.g., persisting the
25
+ * flag, dispatching a save command). */
26
+ export const ToggledChecked = m('ToggledChecked', { isChecked: S.Boolean });
27
+ /** Union of out-messages the checkbox component can produce. Surfaced as
28
+ * the third element of `update`'s return tuple and pattern-matched by
29
+ * the parent. */
30
+ export const OutMessage = S.Union([ToggledChecked]);
16
31
  /** Creates an initial checkbox model from a config. Defaults to unchecked. */
17
32
  export const init = (config) => ({
18
33
  id: config.id,
19
34
  isChecked: config.isChecked ?? false,
20
35
  });
21
36
  // UPDATE
22
- /** Processes a checkbox message and returns the next model and commands. */
23
- export const update = (model, _message) => [
24
- evo(model, { isChecked: isChecked => !isChecked }),
25
- [],
26
- ];
37
+ /** Processes a checkbox message and returns the next model, commands,
38
+ * and a `ToggledChecked` OutMessage carrying the new checked state. */
39
+ export const update = (model, message) => M.value(message).pipe(M.withReturnType(), M.tagsExhaustive({
40
+ Toggled: () => {
41
+ const nextIsChecked = !model.isChecked;
42
+ return [
43
+ evo(model, { isChecked: () => nextIsChecked }),
44
+ [],
45
+ Option.some(ToggledChecked({ isChecked: nextIsChecked })),
46
+ ];
47
+ },
48
+ SetChecked: ({ isChecked }) => [
49
+ evo(model, { isChecked: () => isChecked }),
50
+ [],
51
+ Option.some(ToggledChecked({ isChecked })),
52
+ ],
53
+ }));
54
+ /** Programmatically sets the checked state. Emits a `ToggledChecked`
55
+ * OutMessage just like a user-initiated toggle. Use this in domain-event
56
+ * handlers where you need to force a specific state (e.g. "select all"). */
57
+ export const setChecked = (model, isChecked) => update(model, SetChecked({ isChecked }));
58
+ /** Reflects an externally-sourced checked state onto the model without
59
+ * emitting an OutMessage. Use this to mirror external truth (saved
60
+ * settings, a server value) onto the checkbox without triggering the
61
+ * downstream reaction a user toggle would cause. Contrast with
62
+ * `setChecked`, which emits `ToggledChecked` so the parent reacts to a
63
+ * programmatic assignment the same way it reacts to a user toggle. Returns
64
+ * the model directly because it produces no commands and no OutMessage. */
65
+ export const reflectChecked = Function.dual(2, (model, isChecked) => evo(model, { isChecked: () => isChecked }));
27
66
  const labelId = (id) => `${id}-label`;
28
67
  const descriptionId = (id) => `${id}-description`;
29
- /** Renders an accessible checkbox by building ARIA attribute groups and delegating layout to the consumer's `toView` callback. */
30
- export const view = (config) => {
68
+ /** Renders an accessible checkbox by building ARIA attribute groups and
69
+ * delegating layout to the consumer's `toView` callback. Embedded via
70
+ * `h.submodel`. */
71
+ export const view = defineView((model, viewInputs) => {
31
72
  const h = html();
32
- const { model: { id, isChecked }, toParentMessage, isDisabled = false, isIndeterminate = false, name, value: formValue = 'on', } = config;
33
- const handleKeyUp = (key) => M.value(key).pipe(M.when(' ', () => Option.some(toParentMessage(Toggled()))), M.orElse(() => Option.none()));
73
+ const { id, isChecked } = model;
74
+ const { isDisabled = false, isIndeterminate = false, name, value: formValue = 'on', } = viewInputs;
75
+ const handleKeyUp = (key) => M.value(key).pipe(M.when(' ', () => Option.some(Toggled())), M.orElse(() => Option.none()));
34
76
  const stateAttributes = isIndeterminate
35
77
  ? [h.DataAttribute('indeterminate', '')]
36
78
  : isChecked
@@ -49,33 +91,20 @@ export const view = (config) => {
49
91
  ...disabledAttributes,
50
92
  ...(isDisabled
51
93
  ? []
52
- : [
53
- h.OnClick(toParentMessage(Toggled())),
54
- h.OnKeyUpPreventDefault(handleKeyUp),
55
- ]),
94
+ : [h.OnClick(Toggled()), h.OnKeyUpPreventDefault(handleKeyUp)]),
56
95
  ];
57
96
  const labelAttributes = [
58
97
  h.Id(labelId(id)),
59
- ...(isDisabled ? [] : [h.OnClick(toParentMessage(Toggled()))]),
98
+ ...(isDisabled ? [] : [h.OnClick(Toggled())]),
60
99
  ];
61
100
  const descriptionAttributes = [h.Id(descriptionId(id))];
62
101
  const hiddenInputAttributes = name
63
102
  ? [h.Type('hidden'), h.Name(name), h.Value(isChecked ? formValue : '')]
64
103
  : [];
65
- return config.toView({
66
- checkbox: checkboxAttributes,
67
- label: labelAttributes,
68
- description: descriptionAttributes,
69
- hiddenInput: hiddenInputAttributes,
104
+ return viewInputs.toView({
105
+ checkbox: childAttributes(checkboxAttributes),
106
+ label: childAttributes(labelAttributes),
107
+ description: childAttributes(descriptionAttributes),
108
+ hiddenInput: childAttributes(hiddenInputAttributes),
70
109
  });
71
- };
72
- /** Creates a memoized checkbox view. Static config is captured in a closure;
73
- * only `model` and `toParentMessage` are compared per render via `createLazy`. */
74
- export const lazy = (staticConfig) => {
75
- const lazyView = createLazy();
76
- return (model, toParentMessage) => lazyView((currentModel, currentToParentMessage) => view({
77
- ...staticConfig,
78
- model: currentModel,
79
- toParentMessage: currentToParentMessage,
80
- }), [model, toParentMessage]);
81
- };
110
+ });
@@ -1,3 +1,3 @@
1
- export { init, update, view, lazy, Model, Message } from './index.js';
2
- export type { Toggled, InitConfig, ViewConfig, CheckboxAttributes, } from './index.js';
1
+ export { init, update, setChecked, reflectChecked, view, Model, Message, OutMessage, SetChecked, ToggledChecked, } from './index.js';
2
+ export type { Toggled, InitConfig, ViewInputs, CheckboxAttributes, } from './index.js';
3
3
  //# sourceMappingURL=public.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/ui/checkbox/public.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAErE,YAAY,EACV,OAAO,EACP,UAAU,EACV,UAAU,EACV,kBAAkB,GACnB,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/ui/checkbox/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,MAAM,EACN,UAAU,EACV,cAAc,EACd,IAAI,EACJ,KAAK,EACL,OAAO,EACP,UAAU,EACV,UAAU,EACV,cAAc,GACf,MAAM,YAAY,CAAA;AAEnB,YAAY,EACV,OAAO,EACP,UAAU,EACV,UAAU,EACV,kBAAkB,GACnB,MAAM,YAAY,CAAA"}
@@ -1 +1 @@
1
- export { init, update, view, lazy, Model, Message } from './index.js';
1
+ export { init, update, setChecked, reflectChecked, view, Model, Message, OutMessage, SetChecked, ToggledChecked, } from './index.js';
@@ -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 multi-select combobox component's state, tracking open/closed status, active item, input value, and selected items. */
6
7
  export declare const Model: S.Struct<{
7
8
  readonly selectedItems: S.$Array<S.String>;
@@ -87,9 +88,9 @@ export declare const update: (model: {
87
88
  } | {
88
89
  readonly _tag: "CompletedUnlockScroll";
89
90
  } | {
90
- readonly _tag: "CompletedSetupInert";
91
+ readonly _tag: "CompletedInertOthers";
91
92
  } | {
92
- readonly _tag: "CompletedTeardownInert";
93
+ readonly _tag: "CompletedRestoreInert";
93
94
  } | {
94
95
  readonly _tag: "CompletedScrollIntoView";
95
96
  } | {
@@ -146,95 +147,38 @@ export declare const update: (model: {
146
147
  } | {
147
148
  readonly _tag: "PressedToggleButton";
148
149
  }, never, never>;
149
- }>[]];
150
+ }>[], Option.Option<Readonly<{
151
+ readonly _tag: "Selected";
152
+ readonly value: string;
153
+ readonly wasAdded: boolean;
154
+ }>>];
155
+ type UpdateReturn = ReturnType<typeof update>;
150
156
  /** Programmatically opens the combobox, updating the model and returning
151
157
  * focus and modal commands. Use this in domain-event handlers to open the combobox. */
152
- export declare const open: (model: Model) => readonly [Model, ReadonlyArray<Command.Command<Message>>];
158
+ export declare const open: (model: Model) => UpdateReturn;
153
159
  /** Programmatically closes the combobox, updating the model and returning
154
160
  * focus and modal commands. Use this in domain-event handlers to close the combobox. */
155
- export declare const close: (model: Model) => readonly [Model, ReadonlyArray<Command.Command<Message>>];
156
- /** Programmatically toggles an item in the multi-select combobox. Use this in domain-event handlers when the combobox uses `onSelectedItem`. */
157
- export declare const selectItem: (model: Model, item: string) => readonly [Model, ReadonlyArray<Command.Command<Message>>];
158
- /** Configuration for rendering a multi-select combobox with `view`. */
159
- export type ViewConfig<ParentMessage, Item extends string> = BaseViewConfig<ParentMessage, Item, Model>;
160
- /** Renders a headless multi-select combobox with keyboard navigation, selection tracking, and aria-activedescendant focus management. */
161
- export declare const view: <ParentMessage, Item extends string>(config: Readonly<{
162
- model: {
163
- readonly selectedItems: readonly string[];
164
- readonly id: string;
165
- readonly isOpen: boolean;
166
- readonly isAnimated: boolean;
167
- readonly isModal: boolean;
168
- readonly nullable: boolean;
169
- readonly immediate: boolean;
170
- readonly selectInputOnFocus: boolean;
171
- readonly animation: {
172
- readonly id: string;
173
- readonly isShowing: boolean;
174
- readonly transitionState: "Idle" | "EnterStart" | "EnterAnimating" | "LeaveStart" | "LeaveAnimating";
175
- };
176
- readonly maybeActiveItemIndex: Option.Option<number>;
177
- readonly activationTrigger: "Pointer" | "Keyboard";
178
- readonly inputValue: string;
179
- readonly maybeLastPointerPosition: Option.Option<{
180
- readonly screenX: number;
181
- readonly screenY: number;
182
- }>;
183
- };
184
- 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 | {
185
- readonly _tag: "CompletedAnchorCombobox";
186
- } | {
187
- readonly _tag: "CompletedAttachComboboxPreventBlur";
188
- } | {
189
- readonly _tag: "CompletedAttachComboboxSelectOnFocus";
190
- } | {
191
- readonly _tag: "CompletedPortalComboboxBackdrop";
192
- }) => ParentMessage;
193
- onSelectedItem?: (value: string) => ParentMessage;
194
- items: readonly Item[];
195
- itemToConfig: (item: Item, context: Readonly<{
196
- isActive: boolean;
197
- isDisabled: boolean;
198
- isSelected: boolean;
199
- }>) => Readonly<{
200
- className?: string;
201
- content: Html;
202
- }>;
203
- itemToValue: (item: Item, index: number) => string;
204
- itemToDisplayText: (item: Item, index: number) => string;
205
- isItemDisabled?: (item: Item, index: number) => boolean;
206
- inputClassName?: string;
207
- inputAttributes?: readonly import("../../html/index.js").Attribute<ParentMessage>[];
208
- inputPlaceholder?: string;
209
- inputWrapperClassName?: string;
210
- inputWrapperAttributes?: readonly import("../../html/index.js").Attribute<ParentMessage>[];
211
- itemsClassName?: string;
212
- itemsAttributes?: readonly import("../../html/index.js").Attribute<ParentMessage>[];
213
- itemsScrollClassName?: string;
214
- itemsScrollAttributes?: readonly import("../../html/index.js").Attribute<ParentMessage>[];
215
- backdropClassName?: string;
216
- backdropAttributes?: readonly import("../../html/index.js").Attribute<ParentMessage>[];
217
- className?: string;
218
- attributes?: readonly import("../../html/index.js").Attribute<ParentMessage>[];
219
- buttonContent?: Html;
220
- buttonClassName?: string;
221
- buttonAttributes?: readonly import("../../html/index.js").Attribute<ParentMessage>[];
222
- formName?: string;
223
- isDisabled?: boolean;
224
- isInvalid?: boolean;
225
- openOnFocus?: boolean;
226
- itemGroupKey?: (item: Item, index: number) => string;
227
- groupToHeading?: (groupKey: string) => Readonly<{
228
- content: Html;
229
- className?: string;
230
- }> | undefined;
231
- groupClassName?: string;
232
- groupAttributes?: readonly import("../../html/index.js").Attribute<ParentMessage>[];
233
- separatorClassName?: string;
234
- separatorAttributes?: readonly import("../../html/index.js").Attribute<ParentMessage>[];
235
- anchor?: import("./public.js").AnchorConfig;
236
- }>) => Html;
237
- /** Creates a memoized multi-select combobox view. Static config is captured in a closure;
238
- * only `model` and `toParentMessage` are compared per render via `createLazy`. */
239
- 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);
161
+ export declare const close: (model: Model) => UpdateReturn;
162
+ /** Programmatically toggles an item in the multi-select combobox. Emits `Selected({ value, wasAdded })`. */
163
+ export declare const selectItem: (model: Model, item: string) => UpdateReturn;
164
+ /** Reflects an externally-sourced selection set onto the model without
165
+ * emitting an OutMessage or running selection side effects. Use this to
166
+ * mirror external truth (URL parameters, restored storage, a server push)
167
+ * onto the combobox's selected items. Contrast with `selectItem`, which
168
+ * toggles a single item as a user *choice* and emits `Selected`. Returns
169
+ * the model directly because it produces no commands and no OutMessage. */
170
+ export declare const reflectSelectedItems: Reflect<Model, ReadonlyArray<string>>;
171
+ /** Per-render view inputs passed to the view via `h.submodel`'s `viewInputs` field. */
172
+ export type ViewInputs<Item extends string> = BaseViewInputs<Item>;
173
+ /** Pairs the multi-select combobox's `view` and `update` (and programmatic
174
+ * helpers) behind a single Item-typed entry point. */
175
+ export declare const create: <Item extends string = string>() => Readonly<{
176
+ view: SubmodelView<Model, Message, BaseViewInputs<Item>>;
177
+ update: (model: Model, message: Message) => readonly [Model, ReadonlyArray<Command.Command<Message>>, Option.Option<OutMessage<Item>>];
178
+ selectItem: (model: Model, item: Item) => readonly [Model, ReadonlyArray<Command.Command<Message>>, Option.Option<OutMessage<Item>>];
179
+ open: (model: Model) => readonly [Model, ReadonlyArray<Command.Command<Message>>, Option.Option<OutMessage<Item>>];
180
+ close: (model: Model) => readonly [Model, ReadonlyArray<Command.Command<Message>>, Option.Option<OutMessage<Item>>];
181
+ reflectSelectedItems: Reflect<Model, ReadonlyArray<Item>>;
182
+ }>;
183
+ export {};
240
184
  //# sourceMappingURL=multi.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"multi.d.ts","sourceRoot":"","sources":["../../../src/ui/combobox/multi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAAE,MAAM,IAAI,CAAC,EAAE,MAAM,QAAQ,CAAA;AAEnD,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,yIAAyI;AACzI,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;EAGhB,CAAA;AAEF,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAA;AAIrC,8RAA8R;AAC9R,MAAM,MAAM,UAAU,GAAG,cAAc,GACrC,QAAQ,CAAC;IACP,aAAa,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CACtC,CAAC,CAAA;AAEJ,2IAA2I;AAC3I,eAAO,MAAM,IAAI,GAAI,QAAQ,UAAU,KAAG,KAGxC,CAAA;AAcF,yJAAyJ;AACzJ,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAwBjB,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,gJAAgJ;AAChJ,eAAO,MAAM,UAAU,GACrB,OAAO,KAAK,EACZ,MAAM,MAAM,KACX,SAAS,CAAC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CACD,CAAA;AAI1D,uEAAuE;AACvE,MAAM,MAAM,UAAU,CAAC,aAAa,EAAE,IAAI,SAAS,MAAM,IAAI,cAAc,CACzE,aAAa,EACb,IAAI,EACJ,KAAK,CACN,CAAA;AAED,yIAAyI;AACzI,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAIf,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":"multi.d.ts","sourceRoot":"","sources":["../../../src/ui/combobox/multi.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,6 @@
1
- import { Array, Option, Schema as S } from 'effect';
2
- import { createLazy } from '../../html/index.js';
1
+ import { Array, Function, Option, Schema as S } 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 multi-select combobox component's state, tracking open/closed status, active item, input value, and selected items. */
7
6
  export const Model = S.Struct({
@@ -32,8 +31,15 @@ export const update = makeUpdate({
32
31
  });
33
32
  },
34
33
  handleSelectedItem: (model, item) => {
35
- const nextSelectedItems = toggleItem(model.selectedItems, item);
36
- return [evo(model, { selectedItems: () => nextSelectedItems }), []];
34
+ const wasAdded = !Array.contains(model.selectedItems, item);
35
+ const nextSelectedItems = wasAdded
36
+ ? Array.append(model.selectedItems, item)
37
+ : Array.filter(model.selectedItems, selected => selected !== item);
38
+ return [
39
+ evo(model, { selectedItems: () => nextSelectedItems }),
40
+ [],
41
+ Option.some(SharedSelected({ value: item, wasAdded })),
42
+ ];
37
43
  },
38
44
  handleImmediateActivation: (model, item) => evo(model, {
39
45
  selectedItems: () => toggleItem(model.selectedItems, item),
@@ -45,20 +51,31 @@ export const open = (model) => update(model, Opened({ maybeActiveItemIndex: Opti
45
51
  /** Programmatically closes the combobox, updating the model and returning
46
52
  * focus and modal commands. Use this in domain-event handlers to close the combobox. */
47
53
  export const close = (model) => update(model, Closed());
48
- /** Programmatically toggles an item in the multi-select combobox. Use this in domain-event handlers when the combobox uses `onSelectedItem`. */
54
+ /** Programmatically toggles an item in the multi-select combobox. Emits `Selected({ value, wasAdded })`. */
49
55
  export const selectItem = (model, item) => update(model, SelectedItem({ item, displayText: item }));
50
- /** Renders a headless multi-select combobox with keyboard navigation, selection tracking, and aria-activedescendant focus management. */
51
- export const view = makeView({
56
+ /** Reflects an externally-sourced selection set onto the model without
57
+ * emitting an OutMessage or running selection side effects. Use this to
58
+ * mirror external truth (URL parameters, restored storage, a server push)
59
+ * onto the combobox's selected items. Contrast with `selectItem`, which
60
+ * toggles a single item as a user *choice* and emits `Selected`. Returns
61
+ * the model directly because it produces no commands and no OutMessage. */
62
+ export const reflectSelectedItems = Function.dual(2, (model, items) => evo(model, { selectedItems: () => items }));
63
+ const internalView = makeView({
52
64
  isItemSelected: (model, itemValue) => Array.contains(model.selectedItems, itemValue),
53
65
  ariaMultiSelectable: true,
54
66
  });
55
- /** Creates a memoized multi-select combobox view. Static config is captured in a closure;
56
- * only `model` and `toParentMessage` are compared per render via `createLazy`. */
57
- export const lazy = (staticConfig) => {
58
- const lazyView = createLazy();
59
- return (model, toParentMessage) => lazyView((currentModel, currentToParentMessage) => view({
60
- ...staticConfig,
61
- model: currentModel,
62
- toParentMessage: currentToParentMessage,
63
- }), [model, toParentMessage]);
67
+ /** Pairs the multi-select combobox's `view` and `update` (and programmatic
68
+ * helpers) behind a single Item-typed entry point. */
69
+ export const create = () => {
70
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
71
+ const typedUpdate = update;
72
+ return {
73
+ view: internalView(),
74
+ update: typedUpdate,
75
+ selectItem: (model, item) => typedUpdate(model, SelectedItem({ item, displayText: item })),
76
+ open: model => typedUpdate(model, Opened({ maybeActiveItemIndex: Option.none() })),
77
+ close: model => typedUpdate(model, Closed()),
78
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
79
+ reflectSelectedItems: reflectSelectedItems,
80
+ };
64
81
  };
@@ -1,3 +1,3 @@
1
- export { init, update, open, close, selectItem, view, lazy, Model, } from './multi.js';
2
- export type { InitConfig, ViewConfig } from './multi.js';
1
+ export { init, create, Model } from './multi.js';
2
+ export type { InitConfig, ViewInputs } from './multi.js';
3
3
  //# sourceMappingURL=multiPublic.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"multiPublic.d.ts","sourceRoot":"","sources":["../../../src/ui/combobox/multiPublic.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,MAAM,EACN,IAAI,EACJ,KAAK,EACL,UAAU,EACV,IAAI,EACJ,IAAI,EACJ,KAAK,GACN,MAAM,YAAY,CAAA;AACnB,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"multiPublic.d.ts","sourceRoot":"","sources":["../../../src/ui/combobox/multiPublic.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAChD,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA"}
@@ -1 +1 @@
1
- export { init, update, open, close, selectItem, view, lazy, Model, } from './multi.js';
1
+ export { init, create, Model } from './multi.js';
@@ -1,7 +1,7 @@
1
- export { init, update, open, close, selectItem, view, lazy, Model, } from './single.js';
2
- export { Message, SelectedItem, CompletedLockScroll, CompletedUnlockScroll, CompletedSetupInert, CompletedTeardownInert, CompletedFocusInput, CompletedScrollIntoView, CompletedClickItem, CompletedAnchorCombobox, CompletedAttachComboboxPreventBlur, CompletedAttachComboboxSelectOnFocus, CompletedPortalComboboxBackdrop, AnchorCombobox, AttachComboboxPreventBlur, AttachComboboxSelectOnFocus, PortalComboboxBackdrop, GotAnimationMessage, LockScroll, UnlockScroll, InertOthers, RestoreInert, FocusInput, ScrollIntoView, ClickItem, DetectMovementOrAnimationEnd, } from './shared.js';
1
+ export { init, create, Model } from './single.js';
2
+ export { Message, OutMessage, Selected, SelectedItem, CompletedLockScroll, CompletedUnlockScroll, CompletedInertOthers, CompletedRestoreInert, CompletedFocusInput, CompletedScrollIntoView, CompletedClickItem, CompletedAnchorCombobox, CompletedAttachComboboxPreventBlur, CompletedAttachComboboxSelectOnFocus, CompletedPortalComboboxBackdrop, AnchorCombobox, AttachComboboxPreventBlur, AttachComboboxSelectOnFocus, PortalComboboxBackdrop, GotAnimationMessage, LockScroll, UnlockScroll, InertOthers, RestoreInert, FocusInput, ScrollIntoView, ClickItem, DetectMovementOrAnimationEnd, } from './shared.js';
3
3
  export type { ActivationTrigger, Opened, Closed, BlurredInput, ActivatedItem, DeactivatedItem, MovedPointerOverItem, RequestedItemClick, UpdatedInputValue, PressedToggleButton, ItemConfig, GroupHeading, } from './shared.js';
4
- export type { InitConfig, ViewConfig } from './single.js';
4
+ export type { InitConfig, ViewInputs } from './single.js';
5
5
  export type { AnchorConfig } from '../anchor.js';
6
6
  export * as Multi from './multiPublic.js';
7
7
  //# sourceMappingURL=public.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/ui/combobox/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,MAAM,EACN,IAAI,EACJ,KAAK,EACL,UAAU,EACV,IAAI,EACJ,IAAI,EACJ,KAAK,GACN,MAAM,aAAa,CAAA;AAEpB,OAAO,EACL,OAAO,EACP,YAAY,EACZ,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,EACnB,uBAAuB,EACvB,kBAAkB,EAClB,uBAAuB,EACvB,kCAAkC,EAClC,oCAAoC,EACpC,+BAA+B,EAC/B,cAAc,EACd,yBAAyB,EACzB,2BAA2B,EAC3B,sBAAsB,EACtB,mBAAmB,EACnB,UAAU,EACV,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,UAAU,EACV,cAAc,EACd,SAAS,EACT,4BAA4B,GAC7B,MAAM,aAAa,CAAA;AAEpB,YAAY,EACV,iBAAiB,EACjB,MAAM,EACN,MAAM,EACN,YAAY,EACZ,aAAa,EACb,eAAe,EACf,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,UAAU,EACV,YAAY,GACb,MAAM,aAAa,CAAA;AAEpB,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAEzD,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAEhD,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAA"}
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/ui/combobox/public.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAEjD,OAAO,EACL,OAAO,EACP,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,EACnB,uBAAuB,EACvB,kBAAkB,EAClB,uBAAuB,EACvB,kCAAkC,EAClC,oCAAoC,EACpC,+BAA+B,EAC/B,cAAc,EACd,yBAAyB,EACzB,2BAA2B,EAC3B,sBAAsB,EACtB,mBAAmB,EACnB,UAAU,EACV,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,UAAU,EACV,cAAc,EACd,SAAS,EACT,4BAA4B,GAC7B,MAAM,aAAa,CAAA;AAEpB,YAAY,EACV,iBAAiB,EACjB,MAAM,EACN,MAAM,EACN,YAAY,EACZ,aAAa,EACb,eAAe,EACf,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,UAAU,EACV,YAAY,GACb,MAAM,aAAa,CAAA;AAEpB,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAEzD,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAEhD,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAA"}
@@ -1,3 +1,3 @@
1
- export { init, update, open, close, selectItem, view, lazy, Model, } from './single.js';
2
- export { Message, SelectedItem, CompletedLockScroll, CompletedUnlockScroll, CompletedSetupInert, CompletedTeardownInert, CompletedFocusInput, CompletedScrollIntoView, CompletedClickItem, CompletedAnchorCombobox, CompletedAttachComboboxPreventBlur, CompletedAttachComboboxSelectOnFocus, CompletedPortalComboboxBackdrop, AnchorCombobox, AttachComboboxPreventBlur, AttachComboboxSelectOnFocus, PortalComboboxBackdrop, GotAnimationMessage, LockScroll, UnlockScroll, InertOthers, RestoreInert, FocusInput, ScrollIntoView, ClickItem, DetectMovementOrAnimationEnd, } from './shared.js';
1
+ export { init, create, Model } from './single.js';
2
+ export { Message, OutMessage, Selected, SelectedItem, CompletedLockScroll, CompletedUnlockScroll, CompletedInertOthers, CompletedRestoreInert, CompletedFocusInput, CompletedScrollIntoView, CompletedClickItem, CompletedAnchorCombobox, CompletedAttachComboboxPreventBlur, CompletedAttachComboboxSelectOnFocus, CompletedPortalComboboxBackdrop, AnchorCombobox, AttachComboboxPreventBlur, AttachComboboxSelectOnFocus, PortalComboboxBackdrop, GotAnimationMessage, LockScroll, UnlockScroll, InertOthers, RestoreInert, FocusInput, ScrollIntoView, ClickItem, DetectMovementOrAnimationEnd, } from './shared.js';
3
3
  export * as Multi from './multiPublic.js';