foldkit 0.41.0 → 0.43.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 (85) hide show
  1. package/README.md +1 -0
  2. package/dist/devtools/overlay.d.ts.map +1 -1
  3. package/dist/devtools/overlay.js +8 -5
  4. package/dist/runtime/runtime.d.ts +2 -0
  5. package/dist/runtime/runtime.d.ts.map +1 -1
  6. package/dist/runtime/runtime.js +17 -3
  7. package/dist/runtime/subscription.d.ts +6 -8
  8. package/dist/runtime/subscription.d.ts.map +1 -1
  9. package/dist/runtime/subscription.js +5 -1
  10. package/dist/ui/checkbox/index.d.ts +3 -3
  11. package/dist/ui/checkbox/index.d.ts.map +1 -1
  12. package/dist/ui/checkbox/index.js +11 -8
  13. package/dist/ui/combobox/multi.d.ts +4 -3
  14. package/dist/ui/combobox/multi.d.ts.map +1 -1
  15. package/dist/ui/combobox/multi.js +4 -4
  16. package/dist/ui/combobox/public.d.ts +2 -2
  17. package/dist/ui/combobox/public.d.ts.map +1 -1
  18. package/dist/ui/combobox/public.js +1 -1
  19. package/dist/ui/combobox/shared.d.ts +12 -1
  20. package/dist/ui/combobox/shared.d.ts.map +1 -1
  21. package/dist/ui/combobox/shared.js +32 -19
  22. package/dist/ui/combobox/single.d.ts +4 -3
  23. package/dist/ui/combobox/single.d.ts.map +1 -1
  24. package/dist/ui/combobox/single.js +4 -4
  25. package/dist/ui/dialog/index.d.ts +11 -3
  26. package/dist/ui/dialog/index.d.ts.map +1 -1
  27. package/dist/ui/dialog/index.js +15 -7
  28. package/dist/ui/dialog/public.d.ts +1 -1
  29. package/dist/ui/dialog/public.d.ts.map +1 -1
  30. package/dist/ui/dialog/public.js +1 -1
  31. package/dist/ui/disclosure/index.d.ts +8 -3
  32. package/dist/ui/disclosure/index.d.ts.map +1 -1
  33. package/dist/ui/disclosure/index.js +12 -7
  34. package/dist/ui/disclosure/public.d.ts +2 -2
  35. package/dist/ui/disclosure/public.d.ts.map +1 -1
  36. package/dist/ui/disclosure/public.js +1 -1
  37. package/dist/ui/dragAndDrop/index.d.ts +285 -0
  38. package/dist/ui/dragAndDrop/index.d.ts.map +1 -0
  39. package/dist/ui/dragAndDrop/index.js +511 -0
  40. package/dist/ui/dragAndDrop/public.d.ts +3 -0
  41. package/dist/ui/dragAndDrop/public.d.ts.map +1 -0
  42. package/dist/ui/dragAndDrop/public.js +1 -0
  43. package/dist/ui/index.d.ts +1 -0
  44. package/dist/ui/index.d.ts.map +1 -1
  45. package/dist/ui/index.js +1 -0
  46. package/dist/ui/listbox/multi.d.ts +4 -3
  47. package/dist/ui/listbox/multi.d.ts.map +1 -1
  48. package/dist/ui/listbox/multi.js +4 -4
  49. package/dist/ui/listbox/public.d.ts +3 -3
  50. package/dist/ui/listbox/public.d.ts.map +1 -1
  51. package/dist/ui/listbox/public.js +2 -2
  52. package/dist/ui/listbox/shared.d.ts +14 -1
  53. package/dist/ui/listbox/shared.d.ts.map +1 -1
  54. package/dist/ui/listbox/shared.js +31 -16
  55. package/dist/ui/listbox/single.d.ts +10 -5
  56. package/dist/ui/listbox/single.d.ts.map +1 -1
  57. package/dist/ui/listbox/single.js +8 -5
  58. package/dist/ui/menu/index.d.ts +19 -3
  59. package/dist/ui/menu/index.d.ts.map +1 -1
  60. package/dist/ui/menu/index.js +39 -21
  61. package/dist/ui/menu/public.d.ts +2 -2
  62. package/dist/ui/menu/public.d.ts.map +1 -1
  63. package/dist/ui/menu/public.js +1 -1
  64. package/dist/ui/popover/index.d.ts +20 -3
  65. package/dist/ui/popover/index.d.ts.map +1 -1
  66. package/dist/ui/popover/index.js +31 -14
  67. package/dist/ui/popover/public.d.ts +2 -2
  68. package/dist/ui/popover/public.d.ts.map +1 -1
  69. package/dist/ui/popover/public.js +1 -1
  70. package/dist/ui/radioGroup/index.d.ts +10 -5
  71. package/dist/ui/radioGroup/index.d.ts.map +1 -1
  72. package/dist/ui/radioGroup/index.js +18 -20
  73. package/dist/ui/radioGroup/public.d.ts +2 -2
  74. package/dist/ui/radioGroup/public.d.ts.map +1 -1
  75. package/dist/ui/radioGroup/public.js +1 -1
  76. package/dist/ui/switch/index.d.ts +3 -3
  77. package/dist/ui/switch/index.d.ts.map +1 -1
  78. package/dist/ui/switch/index.js +11 -8
  79. package/dist/ui/tabs/index.d.ts +8 -3
  80. package/dist/ui/tabs/index.d.ts.map +1 -1
  81. package/dist/ui/tabs/index.js +15 -8
  82. package/dist/ui/tabs/public.d.ts +2 -2
  83. package/dist/ui/tabs/public.d.ts.map +1 -1
  84. package/dist/ui/tabs/public.js +1 -1
  85. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/ui/menu/public.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAElE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAE/C,YAAY,EACV,iBAAiB,EACjB,MAAM,EACN,MAAM,EACN,WAAW,EACX,aAAa,EACb,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,kBAAkB,EAClB,QAAQ,EACR,aAAa,EACb,sBAAsB,EACtB,sBAAsB,EACtB,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,EACvB,eAAe,EACf,sBAAsB,EACtB,UAAU,EACV,UAAU,EACV,UAAU,EACV,YAAY,GACb,MAAM,SAAS,CAAA;AAEhB,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA"}
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/ui/menu/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,MAAM,EACN,UAAU,EACV,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,OAAO,EACP,YAAY,EACZ,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,EACnB,oBAAoB,EACpB,uBAAuB,EACvB,kBAAkB,EAClB,aAAa,EACb,uBAAuB,EACvB,eAAe,EACf,sBAAsB,EACtB,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,UAAU,EACV,WAAW,EACX,cAAc,EACd,SAAS,EACT,gBAAgB,EAChB,kBAAkB,EAClB,6BAA6B,GAC9B,MAAM,SAAS,CAAA;AAEhB,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAE/C,YAAY,EACV,iBAAiB,EACjB,MAAM,EACN,MAAM,EACN,WAAW,EACX,aAAa,EACb,eAAe,EACf,oBAAoB,EACpB,kBAAkB,EAClB,QAAQ,EACR,sBAAsB,EACtB,sBAAsB,EACtB,iBAAiB,EACjB,qBAAqB,EACrB,UAAU,EACV,UAAU,EACV,UAAU,EACV,YAAY,GACb,MAAM,SAAS,CAAA;AAEhB,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA"}
@@ -1,2 +1,2 @@
1
- export { init, update, view, lazy, Model, Message } from './index';
1
+ export { init, update, selectItem, view, lazy, Model, Message, SelectedItem, CompletedLockScroll, CompletedUnlockScroll, CompletedSetupInert, CompletedTeardownInert, CompletedFocusItems, CompletedFocusButton, CompletedScrollIntoView, CompletedClickItem, ClearedSearch, AdvancedTransitionFrame, EndedTransition, DetectedButtonMovement, RequestFrame, LockScroll, UnlockScroll, InertOthers, RestoreInert, FocusItems, FocusButton, ScrollIntoView, ClickItem, DelayClearSearch, WaitForTransitions, DetectMovementOrTransitionEnd, } from './index';
2
2
  export { TransitionState } from '../transition';
@@ -79,30 +79,39 @@ export type InitConfig = Readonly<{
79
79
  /** Creates an initial popover model from a config. Defaults to closed. */
80
80
  export declare const init: (config: InitConfig) => Model;
81
81
  type UpdateReturn = readonly [Model, ReadonlyArray<Command.Command<Message>>];
82
+ /** Advances the popover's enter/leave transition by waiting a double-rAF. */
82
83
  export declare const RequestFrame: Command.CommandDefinition<"RequestFrame", {
83
84
  readonly _tag: "AdvancedTransitionFrame";
84
85
  }>;
86
+ /** Prevents page scrolling while the popover is open in modal mode. */
85
87
  export declare const LockScroll: Command.CommandDefinition<"LockScroll", {
86
88
  readonly _tag: "CompletedLockScroll";
87
89
  }>;
90
+ /** Re-enables page scrolling after the popover closes. */
88
91
  export declare const UnlockScroll: Command.CommandDefinition<"UnlockScroll", {
89
92
  readonly _tag: "CompletedUnlockScroll";
90
93
  }>;
94
+ /** Marks all elements outside the popover as inert for modal behavior. */
91
95
  export declare const InertOthers: Command.CommandDefinition<"InertOthers", {
92
96
  readonly _tag: "CompletedSetupInert";
93
97
  }>;
98
+ /** Removes the inert attribute from elements outside the popover. */
94
99
  export declare const RestoreInert: Command.CommandDefinition<"RestoreInert", {
95
100
  readonly _tag: "CompletedTeardownInert";
96
101
  }>;
102
+ /** Moves focus to the popover panel after opening. */
97
103
  export declare const FocusPanel: Command.CommandDefinition<"FocusPanel", {
98
104
  readonly _tag: "CompletedFocusPanel";
99
105
  }>;
106
+ /** Moves focus back to the popover button after closing. */
100
107
  export declare const FocusButton: Command.CommandDefinition<"FocusButton", {
101
108
  readonly _tag: "CompletedFocusButton";
102
109
  }>;
110
+ /** Waits for all CSS transitions on the popover panel to complete. */
103
111
  export declare const WaitForTransitions: Command.CommandDefinition<"WaitForTransitions", {
104
112
  readonly _tag: "EndedTransition";
105
113
  }>;
114
+ /** Detects whether the popover button moved or the leave transition ended — whichever comes first. */
106
115
  export declare const DetectMovementOrTransitionEnd: Command.CommandDefinition<"DetectMovementOrTransitionEnd", {
107
116
  readonly _tag: "EndedTransition";
108
117
  } | {
@@ -110,10 +119,18 @@ export declare const DetectMovementOrTransitionEnd: Command.CommandDefinition<"D
110
119
  }>;
111
120
  /** Processes a popover message and returns the next model and commands. */
112
121
  export declare const update: (model: Model, message: Message) => UpdateReturn;
122
+ /** Programmatically opens the popover, updating the model and returning
123
+ * focus and modal commands. Use this in domain-event handlers when the popover uses `onOpened`. */
124
+ export declare const open: (model: Model) => readonly [Model, ReadonlyArray<Command.Command<Message>>];
125
+ /** Programmatically closes the popover, updating the model and returning
126
+ * focus and modal commands. Use this in domain-event handlers when the popover uses `onClosed`. */
127
+ export declare const close: (model: Model) => readonly [Model, ReadonlyArray<Command.Command<Message>>];
113
128
  /** Configuration for rendering a popover with `view`. */
114
129
  export type ViewConfig<Message> = Readonly<{
115
130
  model: Model;
116
- toMessage: (message: Opened | Closed | ClosedByTab | PressedPointerOnButton | IgnoredMouseClick | SuppressedSpaceScroll) => Message;
131
+ toParentMessage: (message: Opened | Closed | ClosedByTab | PressedPointerOnButton | IgnoredMouseClick | SuppressedSpaceScroll) => Message;
132
+ onOpened?: () => Message;
133
+ onClosed?: () => Message;
117
134
  anchor: AnchorConfig;
118
135
  buttonContent: Html;
119
136
  buttonClassName?: string;
@@ -130,7 +147,7 @@ export type ViewConfig<Message> = Readonly<{
130
147
  /** Renders a headless popover with a trigger button and a floating panel. Uses the disclosure ARIA pattern (aria-expanded + aria-controls) with no role on the panel. */
131
148
  export declare const view: <Message>(config: ViewConfig<Message>) => Html;
132
149
  /** Creates a memoized popover view. Static config is captured in a closure;
133
- * only `model` and `toMessage` are compared per render via `createLazy`. */
134
- export declare const lazy: <Message>(staticConfig: Omit<ViewConfig<Message>, "model" | "toMessage">) => ((model: Model, toMessage: ViewConfig<Message>["toMessage"]) => Html);
150
+ * only `model` and `toParentMessage` are compared per render via `createLazy`. */
151
+ export declare const lazy: <Message>(staticConfig: Omit<ViewConfig<Message>, "model" | "toParentMessage" | "onOpened" | "onClosed">) => ((model: Model, toParentMessage: ViewConfig<Message>["toParentMessage"]) => Html);
135
152
  export {};
136
153
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/popover/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/popover/index.ts"],"names":[],"mappings":"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"}
@@ -73,14 +73,23 @@ const closedModel = (model) => evo(model, {
73
73
  const buttonSelector = (id) => `#${id}-button`;
74
74
  const panelSelector = (id) => `#${id}-panel`;
75
75
  const withUpdateReturn = M.withReturnType();
76
+ /** Advances the popover's enter/leave transition by waiting a double-rAF. */
76
77
  export const RequestFrame = Command.define('RequestFrame', AdvancedTransitionFrame);
78
+ /** Prevents page scrolling while the popover is open in modal mode. */
77
79
  export const LockScroll = Command.define('LockScroll', CompletedLockScroll);
80
+ /** Re-enables page scrolling after the popover closes. */
78
81
  export const UnlockScroll = Command.define('UnlockScroll', CompletedUnlockScroll);
82
+ /** Marks all elements outside the popover as inert for modal behavior. */
79
83
  export const InertOthers = Command.define('InertOthers', CompletedSetupInert);
84
+ /** Removes the inert attribute from elements outside the popover. */
80
85
  export const RestoreInert = Command.define('RestoreInert', CompletedTeardownInert);
86
+ /** Moves focus to the popover panel after opening. */
81
87
  export const FocusPanel = Command.define('FocusPanel', CompletedFocusPanel);
88
+ /** Moves focus back to the popover button after closing. */
82
89
  export const FocusButton = Command.define('FocusButton', CompletedFocusButton);
90
+ /** Waits for all CSS transitions on the popover panel to complete. */
83
91
  export const WaitForTransitions = Command.define('WaitForTransitions', EndedTransition);
92
+ /** Detects whether the popover button moved or the leave transition ended — whichever comes first. */
84
93
  export const DetectMovementOrTransitionEnd = Command.define('DetectMovementOrTransitionEnd', DetectedButtonMovement, EndedTransition);
85
94
  /** Processes a popover message and returns the next model and commands. */
86
95
  export const update = (model, message) => {
@@ -170,10 +179,18 @@ export const update = (model, message) => {
170
179
  SuppressedSpaceScroll: () => [model, []],
171
180
  }));
172
181
  };
182
+ /** Programmatically opens the popover, updating the model and returning
183
+ * focus and modal commands. Use this in domain-event handlers when the popover uses `onOpened`. */
184
+ export const open = (model) => update(model, Opened());
185
+ /** Programmatically closes the popover, updating the model and returning
186
+ * focus and modal commands. Use this in domain-event handlers when the popover uses `onClosed`. */
187
+ export const close = (model) => update(model, Closed());
173
188
  /** Renders a headless popover with a trigger button and a floating panel. Uses the disclosure ARIA pattern (aria-expanded + aria-controls) with no role on the panel. */
174
189
  export const view = (config) => {
175
190
  const { div, AriaControls, AriaDisabled, AriaExpanded, Class, DataAttribute, Id, OnBlur, OnClick, OnDestroy, OnInsert, OnKeyDownPreventDefault, OnKeyUpPreventDefault, OnPointerDown, Style, Tabindex, Type, keyed, } = html();
176
- const { model: { id, isOpen, transitionState, maybeLastButtonPointerType }, toMessage, anchor, buttonContent, buttonClassName, buttonAttributes = [], panelContent, panelClassName, panelAttributes = [], backdropClassName, backdropAttributes = [], isDisabled, className, attributes = [], } = config;
191
+ const { model: { id, isOpen, transitionState, maybeLastButtonPointerType }, toParentMessage, onOpened, onClosed, anchor, buttonContent, buttonClassName, buttonAttributes = [], panelContent, panelClassName, panelAttributes = [], backdropClassName, backdropAttributes = [], isDisabled, className, attributes = [], } = config;
192
+ const dispatchOpened = () => onOpened ? onOpened() : toParentMessage(Opened());
193
+ const dispatchClosed = () => onClosed ? onClosed() : toParentMessage(Closed());
177
194
  const isLeaving = transitionState === 'LeaveStart' || transitionState === 'LeaveAnimating';
178
195
  const isVisible = isOpen || isLeaving;
179
196
  const transitionAttributes = M.value(transitionState).pipe(M.when('EnterStart', () => [
@@ -191,25 +208,25 @@ export const view = (config) => {
191
208
  DataAttribute('leave', ''),
192
209
  DataAttribute('transition', ''),
193
210
  ]), M.orElse(() => []));
194
- const handleButtonKeyDown = (key) => M.value(key).pipe(M.whenOr('Enter', ' ', 'ArrowDown', () => Option.some(toMessage(isOpen ? Closed() : Opened()))), M.orElse(() => Option.none()));
195
- const handleButtonPointerDown = (pointerType, button) => Option.some(toMessage(PressedPointerOnButton({
211
+ const handleButtonKeyDown = (key) => M.value(key).pipe(M.whenOr('Enter', ' ', 'ArrowDown', () => Option.some(isOpen ? dispatchClosed() : dispatchOpened())), M.orElse(() => Option.none()));
212
+ const handleButtonPointerDown = (pointerType, button) => Option.some(toParentMessage(PressedPointerOnButton({
196
213
  pointerType,
197
214
  button,
198
215
  })));
199
216
  const handleButtonClick = () => {
200
217
  const isMouse = Option.exists(maybeLastButtonPointerType, type => type === 'mouse');
201
218
  if (isMouse) {
202
- return toMessage(IgnoredMouseClick());
219
+ return toParentMessage(IgnoredMouseClick());
203
220
  }
204
221
  else if (isOpen) {
205
- return toMessage(Closed());
222
+ return dispatchClosed();
206
223
  }
207
224
  else {
208
- return toMessage(Opened());
225
+ return dispatchOpened();
209
226
  }
210
227
  };
211
- const handleSpaceKeyUp = (key) => OptionExt.when(key === ' ', toMessage(SuppressedSpaceScroll()));
212
- const handlePanelKeyDown = (key) => M.value(key).pipe(M.when('Escape', () => Option.some(toMessage(Closed()))), M.orElse(() => Option.none()));
228
+ const handleSpaceKeyUp = (key) => OptionExt.when(key === ' ', toParentMessage(SuppressedSpaceScroll()));
229
+ const handlePanelKeyDown = (key) => M.value(key).pipe(M.when('Escape', () => Option.some(dispatchClosed())), M.orElse(() => Option.none()));
213
230
  const resolvedButtonAttributes = [
214
231
  Id(`${id}-button`),
215
232
  Type('button'),
@@ -246,13 +263,13 @@ export const view = (config) => {
246
263
  ? []
247
264
  : [
248
265
  OnKeyDownPreventDefault(handlePanelKeyDown),
249
- OnBlur(toMessage(ClosedByTab())),
266
+ OnBlur(toParentMessage(ClosedByTab())),
250
267
  ]),
251
268
  ...(panelClassName ? [Class(panelClassName)] : []),
252
269
  ...panelAttributes,
253
270
  ];
254
271
  const backdrop = keyed('div')(`${id}-backdrop`, [
255
- ...(isLeaving ? [] : [OnClick(toMessage(Closed()))]),
272
+ ...(isLeaving ? [] : [OnClick(dispatchClosed())]),
256
273
  ...(backdropClassName ? [Class(backdropClassName)] : []),
257
274
  ...backdropAttributes,
258
275
  ], []);
@@ -273,12 +290,12 @@ export const view = (config) => {
273
290
  ]);
274
291
  };
275
292
  /** Creates a memoized popover view. Static config is captured in a closure;
276
- * only `model` and `toMessage` are compared per render via `createLazy`. */
293
+ * only `model` and `toParentMessage` are compared per render via `createLazy`. */
277
294
  export const lazy = (staticConfig) => {
278
295
  const lazyView = createLazy();
279
- return (model, toMessage) => lazyView((currentModel, currentToMessage) => view({
296
+ return (model, toParentMessage) => lazyView((currentModel, currentToMessage) => view({
280
297
  ...staticConfig,
281
298
  model: currentModel,
282
- toMessage: currentToMessage,
283
- }), [model, toMessage]);
299
+ toParentMessage: currentToMessage,
300
+ }), [model, toParentMessage]);
284
301
  };
@@ -1,5 +1,5 @@
1
- export { init, update, view, lazy, Model, Message } from './index';
1
+ export { init, update, open, close, view, lazy, Model, Message, Opened, Closed, CompletedFocusPanel, CompletedFocusButton, CompletedLockScroll, CompletedUnlockScroll, CompletedSetupInert, CompletedTeardownInert, AdvancedTransitionFrame, EndedTransition, DetectedButtonMovement, RequestFrame, LockScroll, UnlockScroll, InertOthers, RestoreInert, FocusPanel, FocusButton, WaitForTransitions, DetectMovementOrTransitionEnd, } from './index';
2
2
  export { TransitionState } from '../transition';
3
- export type { Opened, Closed, ClosedByTab, PressedPointerOnButton, IgnoredMouseClick, SuppressedSpaceScroll, InitConfig, ViewConfig, } from './index';
3
+ export type { ClosedByTab, PressedPointerOnButton, IgnoredMouseClick, SuppressedSpaceScroll, InitConfig, ViewConfig, } from './index';
4
4
  export type { AnchorConfig } from '../anchor';
5
5
  //# sourceMappingURL=public.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/ui/popover/public.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAElE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAE/C,YAAY,EACV,MAAM,EACN,MAAM,EACN,WAAW,EACX,sBAAsB,EACtB,iBAAiB,EACjB,qBAAqB,EACrB,UAAU,EACV,UAAU,GACX,MAAM,SAAS,CAAA;AAEhB,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA"}
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/ui/popover/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,MAAM,EACN,IAAI,EACJ,KAAK,EACL,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,OAAO,EACP,MAAM,EACN,MAAM,EACN,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,EACvB,eAAe,EACf,sBAAsB,EACtB,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,UAAU,EACV,WAAW,EACX,kBAAkB,EAClB,6BAA6B,GAC9B,MAAM,SAAS,CAAA;AAEhB,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAE/C,YAAY,EACV,WAAW,EACX,sBAAsB,EACtB,iBAAiB,EACjB,qBAAqB,EACrB,UAAU,EACV,UAAU,GACX,MAAM,SAAS,CAAA;AAEhB,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA"}
@@ -1,2 +1,2 @@
1
- export { init, update, view, lazy, Model, Message } from './index';
1
+ export { init, update, open, close, view, lazy, Model, Message, Opened, Closed, CompletedFocusPanel, CompletedFocusButton, CompletedLockScroll, CompletedUnlockScroll, CompletedSetupInert, CompletedTeardownInert, AdvancedTransitionFrame, EndedTransition, DetectedButtonMovement, RequestFrame, LockScroll, UnlockScroll, InertOthers, RestoreInert, FocusPanel, FocusButton, WaitForTransitions, DetectMovementOrTransitionEnd, } from './index';
2
2
  export { TransitionState } from '../transition';
@@ -34,11 +34,15 @@ export type InitConfig = Readonly<{
34
34
  }>;
35
35
  /** Creates an initial radio group model from a config. Defaults to no selection and vertical orientation. */
36
36
  export declare const init: (config: InitConfig) => Model;
37
+ /** Moves focus to the radio option at the given index. */
37
38
  export declare const FocusOption: Command.CommandDefinition<"FocusOption", {
38
39
  readonly _tag: "CompletedFocusOption";
39
40
  }>;
40
41
  /** Processes a radio group message and returns the next model and commands. */
41
42
  export declare const update: (model: Model, message: Message) => readonly [Model, ReadonlyArray<Command.Command<Message>>];
43
+ /** Programmatically selects a value in the radio group, updating the model and returning
44
+ * focus commands. Use this in domain-event handlers when the radio group uses `onSelected`. */
45
+ export declare const select: (model: Model, value: string, options: ReadonlyArray<string>) => readonly [Model, ReadonlyArray<Command.Command<Message>>];
42
46
  /** Attribute groups the radio group component provides for each option's `content` callback. */
43
47
  export type OptionAttributes<Message> = Readonly<{
44
48
  option: ReadonlyArray<Attribute<Message>>;
@@ -46,12 +50,12 @@ export type OptionAttributes<Message> = Readonly<{
46
50
  description: ReadonlyArray<Attribute<Message>>;
47
51
  }>;
48
52
  /** Configuration for an individual radio option. The `value` field carries the generic `RadioOption` type
49
- * so it flows through to `toMessage` callbacks without widening to `string`. */
53
+ * so it flows through to `toParentMessage` callbacks without widening to `string`. */
50
54
  export type OptionConfig<Message, RadioOption extends string = string> = Readonly<{
51
55
  value: RadioOption;
52
56
  content: (attributes: OptionAttributes<Message>) => Html;
53
57
  }>;
54
- /** The `SelectedOption` message as seen by `toMessage` callbacks, with `value` narrowed
58
+ /** The `SelectedOption` message as seen by `toParentMessage` callbacks, with `value` narrowed
55
59
  * to the generic `RadioOption` type instead of `string`. */
56
60
  export type NarrowedSelectedOption<RadioOption extends string> = Readonly<{
57
61
  readonly _tag: 'SelectedOption';
@@ -61,7 +65,8 @@ export type NarrowedSelectedOption<RadioOption extends string> = Readonly<{
61
65
  /** Configuration for rendering a radio group with `view`. */
62
66
  export type ViewConfig<Message, RadioOption extends string> = Readonly<{
63
67
  model: Model;
64
- toMessage: (message: NarrowedSelectedOption<RadioOption> | CompletedFocusOption) => Message;
68
+ toParentMessage: (message: NarrowedSelectedOption<RadioOption> | CompletedFocusOption) => Message;
69
+ onSelected?: (value: RadioOption, index: number) => Message;
65
70
  options: ReadonlyArray<RadioOption>;
66
71
  optionToConfig: (option: RadioOption, context: Readonly<{
67
72
  isSelected: boolean;
@@ -79,6 +84,6 @@ export type ViewConfig<Message, RadioOption extends string> = Readonly<{
79
84
  /** Renders an accessible radio group by building ARIA attribute groups and delegating layout to the consumer's `optionToConfig` callback. */
80
85
  export declare const view: <Message, RadioOption extends string>(config: ViewConfig<Message, RadioOption>) => Html;
81
86
  /** Creates a memoized radio group view. Static config is captured in a closure;
82
- * only `model` and `toMessage` are compared per render via `createLazy`. */
83
- export declare const lazy: <Message, RadioOption extends string>(staticConfig: Omit<ViewConfig<Message, RadioOption>, "model" | "toMessage">) => ((model: Model, toMessage: ViewConfig<Message, RadioOption>["toMessage"]) => Html);
87
+ * only `model` and `toParentMessage` are compared per render via `createLazy`. */
88
+ export declare const lazy: <Message, RadioOption extends string>(staticConfig: Omit<ViewConfig<Message, RadioOption>, "model" | "toParentMessage" | "onSelected">) => ((model: Model, toParentMessage: ViewConfig<Message, RadioOption>["toParentMessage"]) => Html);
84
89
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/radioGroup/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/radioGroup/index.ts"],"names":[],"mappings":"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"}
@@ -32,6 +32,7 @@ export const init = (config) => ({
32
32
  });
33
33
  // UPDATE
34
34
  const optionId = (id, index) => `${id}-option-${index}`;
35
+ /** Moves focus to the radio option at the given index. */
35
36
  export const FocusOption = Command.define('FocusOption', CompletedFocusOption);
36
37
  /** Processes a radio group message and returns the next model and commands. */
37
38
  export const update = (model, message) => M.value(message).pipe(M.withReturnType(), M.tagsExhaustive({
@@ -46,12 +47,21 @@ export const update = (model, message) => M.value(message).pipe(M.withReturnType
46
47
  },
47
48
  CompletedFocusOption: () => [model, []],
48
49
  }));
50
+ /** Programmatically selects a value in the radio group, updating the model and returning
51
+ * focus commands. Use this in domain-event handlers when the radio group uses `onSelected`. */
52
+ export const select = (model, value, options) => pipe(options, Array.findFirstIndex(option => option === value), Option.match({
53
+ onNone: () => [model, []],
54
+ onSome: index => update(model, SelectedOption({ value, index })),
55
+ }));
49
56
  const labelId = (id, index) => `${id}-option-${index}-label`;
50
57
  const descriptionId = (id, index) => `${id}-option-${index}-description`;
51
58
  /** Renders an accessible radio group by building ARIA attribute groups and delegating layout to the consumer's `optionToConfig` callback. */
52
59
  export const view = (config) => {
53
60
  const { div, input, AriaChecked, AriaDescribedBy, AriaDisabled, AriaLabel, AriaLabelledBy, AriaOrientation, Class, DataAttribute, Id, Name, OnClick, OnKeyDownPreventDefault, Role, Tabindex, Type, Value, } = html();
54
- const { model, model: { id, selectedValue }, toMessage, options, optionToConfig, isOptionDisabled: isOptionDisabledFn, orientation = model.orientation, ariaLabel, className, attributes = [], name, isDisabled: isGroupDisabled = false, } = config;
61
+ const { model, model: { id, selectedValue }, toParentMessage, onSelected, options, optionToConfig, isOptionDisabled: isOptionDisabledFn, orientation = model.orientation, ariaLabel, className, attributes = [], name, isDisabled: isGroupDisabled = false, } = config;
62
+ const dispatchSelected = (value, index) => onSelected
63
+ ? onSelected(value, index)
64
+ : toParentMessage({ _tag: 'SelectedOption', value, index });
55
65
  const isDisabled = (index) => {
56
66
  if (isGroupDisabled) {
57
67
  return true;
@@ -82,16 +92,8 @@ export const view = (config) => {
82
92
  const resolveKeyIndex = keyToIndex(nextKey, previousKey, options.length, focusedIndex, isDisabled);
83
93
  const handleKeyDown = (currentIndex) => (key) => M.value(key).pipe(M.whenOr(nextKey, previousKey, 'Home', 'End', 'PageUp', 'PageDown', () => {
84
94
  const nextIndex = resolveKeyIndex(key);
85
- return pipe(optionValues, Array.get(nextIndex), Option.map(value => toMessage({
86
- _tag: 'SelectedOption',
87
- value,
88
- index: nextIndex,
89
- })));
90
- }), M.when(' ', () => pipe(optionValues, Array.get(currentIndex), Option.map(value => toMessage({
91
- _tag: 'SelectedOption',
92
- value,
93
- index: currentIndex,
94
- })))), M.orElse(() => Option.none()));
95
+ return pipe(optionValues, Array.get(nextIndex), Option.map(value => dispatchSelected(value, nextIndex)));
96
+ }), M.when(' ', () => pipe(optionValues, Array.get(currentIndex), Option.map(value => dispatchSelected(value, currentIndex)))), M.orElse(() => Option.none()));
95
97
  const renderedOptions = Array.map(options, (option, index) => {
96
98
  const isSelected = Option.exists(selectedIndex, selectedIdx => selectedIdx === index);
97
99
  const isFocusable = index === focusedIndex;
@@ -119,11 +121,7 @@ export const view = (config) => {
119
121
  ...(isOptionDisabled
120
122
  ? []
121
123
  : [
122
- OnClick(toMessage({
123
- _tag: 'SelectedOption',
124
- value: optionConfig.value,
125
- index,
126
- })),
124
+ OnClick(dispatchSelected(optionConfig.value, index)),
127
125
  OnKeyDownPreventDefault(handleKeyDown(index)),
128
126
  ]),
129
127
  ];
@@ -153,12 +151,12 @@ export const view = (config) => {
153
151
  return div(groupAttributes, [...renderedOptions, ...hiddenInputs]);
154
152
  };
155
153
  /** Creates a memoized radio group view. Static config is captured in a closure;
156
- * only `model` and `toMessage` are compared per render via `createLazy`. */
154
+ * only `model` and `toParentMessage` are compared per render via `createLazy`. */
157
155
  export const lazy = (staticConfig) => {
158
156
  const lazyView = createLazy();
159
- return (model, toMessage) => lazyView((currentModel, currentToMessage) => view({
157
+ return (model, toParentMessage) => lazyView((currentModel, currentToMessage) => view({
160
158
  ...staticConfig,
161
159
  model: currentModel,
162
- toMessage: currentToMessage,
163
- }), [model, toMessage]);
160
+ toParentMessage: currentToMessage,
161
+ }), [model, toParentMessage]);
164
162
  };
@@ -1,3 +1,3 @@
1
- export { init, update, view, lazy, Model, Message } from './index';
2
- export type { SelectedOption, NarrowedSelectedOption, Orientation, InitConfig, ViewConfig, OptionAttributes, OptionConfig, } from './index';
1
+ export { init, update, select, view, lazy, Model, Message, SelectedOption, CompletedFocusOption, FocusOption, } from './index';
2
+ export type { NarrowedSelectedOption, Orientation, InitConfig, ViewConfig, OptionAttributes, OptionConfig, } from './index';
3
3
  //# sourceMappingURL=public.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/ui/radioGroup/public.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAElE,YAAY,EACV,cAAc,EACd,sBAAsB,EACtB,WAAW,EACX,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,YAAY,GACb,MAAM,SAAS,CAAA"}
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/ui/radioGroup/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,MAAM,EACN,MAAM,EACN,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,OAAO,EACP,cAAc,EACd,oBAAoB,EACpB,WAAW,GACZ,MAAM,SAAS,CAAA;AAEhB,YAAY,EACV,sBAAsB,EACtB,WAAW,EACX,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,YAAY,GACb,MAAM,SAAS,CAAA"}
@@ -1 +1 @@
1
- export { init, update, view, lazy, Model, Message } from './index';
1
+ export { init, update, select, view, lazy, Model, Message, SelectedOption, CompletedFocusOption, FocusOption, } from './index';
@@ -32,7 +32,7 @@ export type SwitchAttributes<Message> = Readonly<{
32
32
  /** Configuration for rendering a switch with `view`. */
33
33
  export type ViewConfig<Message> = Readonly<{
34
34
  model: Model;
35
- toMessage: (message: Toggled) => Message;
35
+ toParentMessage: (message: Toggled) => Message;
36
36
  toView: (attributes: SwitchAttributes<Message>) => Html;
37
37
  isDisabled?: boolean;
38
38
  name?: string;
@@ -41,6 +41,6 @@ export type ViewConfig<Message> = Readonly<{
41
41
  /** Renders an accessible switch toggle by building ARIA attribute groups and delegating layout to the consumer's `toView` callback. */
42
42
  export declare const view: <Message>(config: ViewConfig<Message>) => Html;
43
43
  /** Creates a memoized switch view. Static config is captured in a closure;
44
- * only `model` and `toMessage` are compared per render via `createLazy`. */
45
- export declare const lazy: <Message>(staticConfig: Omit<ViewConfig<Message>, "model" | "toMessage">) => ((model: Model, toMessage: ViewConfig<Message>["toMessage"]) => Html);
44
+ * only `model` and `toParentMessage` are compared per render via `createLazy`. */
45
+ export declare const lazy: <Message>(staticConfig: Omit<ViewConfig<Message>, "model" | "toParentMessage">) => ((model: Model, toParentMessage: ViewConfig<Message>["toParentMessage"]) => Html);
46
46
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/switch/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,MAAM,IAAI,CAAC,EAAE,MAAM,QAAQ,CAAA;AAExD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,IAAI,EAAoB,MAAM,YAAY,CAAA;AAMxE,qFAAqF;AACrF,eAAO,MAAM,KAAK;;;EAGhB,CAAA;AAEF,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAA;AAIrC,oEAAoE;AACpE,eAAO,MAAM,OAAO,4DAAe,CAAA;AAEnC,gEAAgE;AAChE,eAAO,MAAM,OAAO,4DAAU,CAAA;AAE9B,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAA;AAEzC,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAA;AAIzC,6DAA6D;AAC7D,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAC,CAAA;AAEF,4EAA4E;AAC5E,eAAO,MAAM,IAAI,GAAI,QAAQ,UAAU,KAAG,KAGxC,CAAA;AAIF,0EAA0E;AAC1E,eAAO,MAAM,MAAM,GACjB,OAAO,KAAK,EACZ,UAAU,OAAO,KAChB,SAAS,CAAC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAGlD,CAAA;AAID,0FAA0F;AAC1F,MAAM,MAAM,gBAAgB,CAAC,OAAO,IAAI,QAAQ,CAAC;IAC/C,MAAM,EAAE,aAAa,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA;IACzC,KAAK,EAAE,aAAa,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA;IACxC,WAAW,EAAE,aAAa,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA;IAC9C,WAAW,EAAE,aAAa,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA;CAC/C,CAAC,CAAA;AAEF,wDAAwD;AACxD,MAAM,MAAM,UAAU,CAAC,OAAO,IAAI,QAAQ,CAAC;IACzC,KAAK,EAAE,KAAK,CAAA;IACZ,SAAS,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAA;IACxC,MAAM,EAAE,CAAC,UAAU,EAAE,gBAAgB,CAAC,OAAO,CAAC,KAAK,IAAI,CAAA;IACvD,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAC,CAAA;AAKF,uIAAuI;AACvI,eAAO,MAAM,IAAI,GAAI,OAAO,EAAE,QAAQ,UAAU,CAAC,OAAO,CAAC,KAAG,IAmE3D,CAAA;AAED;6EAC6E;AAC7E,eAAO,MAAM,IAAI,GAAI,OAAO,EAC1B,cAAc,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,WAAW,CAAC,KAC7D,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,KAAK,IAAI,CAgBtE,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/switch/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,MAAM,IAAI,CAAC,EAAE,MAAM,QAAQ,CAAA;AAExD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,IAAI,EAAoB,MAAM,YAAY,CAAA;AAMxE,qFAAqF;AACrF,eAAO,MAAM,KAAK;;;EAGhB,CAAA;AAEF,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAA;AAIrC,oEAAoE;AACpE,eAAO,MAAM,OAAO,4DAAe,CAAA;AAEnC,gEAAgE;AAChE,eAAO,MAAM,OAAO,4DAAU,CAAA;AAE9B,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAA;AAEzC,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAA;AAIzC,6DAA6D;AAC7D,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAC,CAAA;AAEF,4EAA4E;AAC5E,eAAO,MAAM,IAAI,GAAI,QAAQ,UAAU,KAAG,KAGxC,CAAA;AAIF,0EAA0E;AAC1E,eAAO,MAAM,MAAM,GACjB,OAAO,KAAK,EACZ,UAAU,OAAO,KAChB,SAAS,CAAC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAGlD,CAAA;AAID,0FAA0F;AAC1F,MAAM,MAAM,gBAAgB,CAAC,OAAO,IAAI,QAAQ,CAAC;IAC/C,MAAM,EAAE,aAAa,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA;IACzC,KAAK,EAAE,aAAa,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA;IACxC,WAAW,EAAE,aAAa,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA;IAC9C,WAAW,EAAE,aAAa,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA;CAC/C,CAAC,CAAA;AAEF,wDAAwD;AACxD,MAAM,MAAM,UAAU,CAAC,OAAO,IAAI,QAAQ,CAAC;IACzC,KAAK,EAAE,KAAK,CAAA;IACZ,eAAe,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAA;IAC9C,MAAM,EAAE,CAAC,UAAU,EAAE,gBAAgB,CAAC,OAAO,CAAC,KAAK,IAAI,CAAA;IACvD,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAC,CAAA;AAKF,uIAAuI;AACvI,eAAO,MAAM,IAAI,GAAI,OAAO,EAAE,QAAQ,UAAU,CAAC,OAAO,CAAC,KAAG,IAsE3D,CAAA;AAED;mFACmF;AACnF,eAAO,MAAM,IAAI,GAAI,OAAO,EAC1B,cAAc,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,iBAAiB,CAAC,KACnE,CAAC,CACF,KAAK,EAAE,KAAK,EACZ,eAAe,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,iBAAiB,CAAC,KACpD,IAAI,CAgBR,CAAA"}
@@ -29,8 +29,8 @@ const descriptionId = (id) => `${id}-description`;
29
29
  /** Renders an accessible switch toggle by building ARIA attribute groups and delegating layout to the consumer's `toView` callback. */
30
30
  export const view = (config) => {
31
31
  const { AriaChecked, AriaDescribedBy, AriaDisabled, AriaLabelledBy, DataAttribute, Id, Name, OnClick, OnKeyUpPreventDefault, Role, Tabindex, Type, Value, } = html();
32
- const { model: { id, isChecked }, toMessage, isDisabled = false, name, value: formValue = 'on', } = config;
33
- const handleKeyUp = (key) => M.value(key).pipe(M.when(' ', () => Option.some(toMessage(Toggled()))), M.orElse(() => Option.none()));
32
+ const { model: { id, isChecked }, toParentMessage, isDisabled = false, name, value: formValue = 'on', } = config;
33
+ const handleKeyUp = (key) => M.value(key).pipe(M.when(' ', () => Option.some(toParentMessage(Toggled()))), M.orElse(() => Option.none()));
34
34
  const checkedAttributes = isChecked ? [DataAttribute('checked', '')] : [];
35
35
  const disabledAttributes = isDisabled
36
36
  ? [AriaDisabled(true), DataAttribute('disabled', '')]
@@ -45,11 +45,14 @@ export const view = (config) => {
45
45
  ...disabledAttributes,
46
46
  ...(isDisabled
47
47
  ? []
48
- : [OnClick(toMessage(Toggled())), OnKeyUpPreventDefault(handleKeyUp)]),
48
+ : [
49
+ OnClick(toParentMessage(Toggled())),
50
+ OnKeyUpPreventDefault(handleKeyUp),
51
+ ]),
49
52
  ];
50
53
  const labelAttributes = [
51
54
  Id(labelId(id)),
52
- ...(isDisabled ? [] : [OnClick(toMessage(Toggled()))]),
55
+ ...(isDisabled ? [] : [OnClick(toParentMessage(Toggled()))]),
53
56
  ];
54
57
  const descriptionAttributes = [Id(descriptionId(id))];
55
58
  const hiddenInputAttributes = name
@@ -63,12 +66,12 @@ export const view = (config) => {
63
66
  });
64
67
  };
65
68
  /** Creates a memoized switch view. Static config is captured in a closure;
66
- * only `model` and `toMessage` are compared per render via `createLazy`. */
69
+ * only `model` and `toParentMessage` are compared per render via `createLazy`. */
67
70
  export const lazy = (staticConfig) => {
68
71
  const lazyView = createLazy();
69
- return (model, toMessage) => lazyView((currentModel, currentToMessage) => view({
72
+ return (model, toParentMessage) => lazyView((currentModel, currentToMessage) => view({
70
73
  ...staticConfig,
71
74
  model: currentModel,
72
- toMessage: currentToMessage,
73
- }), [model, toMessage]);
75
+ toParentMessage: currentToMessage,
76
+ }), [model, toParentMessage]);
74
77
  };
@@ -43,6 +43,7 @@ export type InitConfig = Readonly<{
43
43
  }>;
44
44
  /** Creates an initial tabs model from a config. Defaults to first tab and automatic activation. */
45
45
  export declare const init: (config: InitConfig) => Model;
46
+ /** Moves focus to the tab at the given index. */
46
47
  export declare const FocusTab: Command.CommandDefinition<"FocusTab", {
47
48
  readonly _tag: "CompletedFocusTab";
48
49
  }>;
@@ -60,7 +61,8 @@ export type TabConfig<Message = unknown> = Readonly<{
60
61
  /** Configuration for rendering a tab group with `view`. */
61
62
  export type ViewConfig<Message, Tab extends string> = Readonly<{
62
63
  model: Model;
63
- toMessage: (message: TabSelected | TabFocused) => Message;
64
+ toParentMessage: (message: TabSelected | TabFocused) => Message;
65
+ onTabSelected?: (index: number) => Message;
64
66
  tabs: ReadonlyArray<Tab>;
65
67
  tabToConfig: (tab: Tab, context: {
66
68
  isActive: boolean;
@@ -77,9 +79,12 @@ export type ViewConfig<Message, Tab extends string> = Readonly<{
77
79
  tabListAttributes?: ReadonlyArray<Attribute<Message>>;
78
80
  tabListAriaLabel: string;
79
81
  }>;
82
+ /** Programmatically selects a tab at the given index, updating the model and returning
83
+ * focus commands. Use this in domain-event handlers when the tab group uses `onTabSelected`. */
84
+ export declare const selectTab: (model: Model, index: number) => readonly [Model, ReadonlyArray<Command.Command<Message>>];
80
85
  /** Renders a headless tab group with accessible ARIA roles, roving tabindex, and keyboard navigation. */
81
86
  export declare const view: <Message, Tab extends string>(config: ViewConfig<Message, Tab>) => Html;
82
87
  /** Creates a memoized tabs view. Static config is captured in a closure;
83
- * only `model` and `toMessage` are compared per render via `createLazy`. */
84
- export declare const lazy: <Message, Tab extends string>(staticConfig: Omit<ViewConfig<Message, Tab>, "model" | "toMessage">) => ((model: Model, toMessage: ViewConfig<Message, Tab>["toMessage"]) => Html);
88
+ * only `model` and `toParentMessage` are compared per render via `createLazy`. */
89
+ export declare const lazy: <Message, Tab extends string>(staticConfig: Omit<ViewConfig<Message, Tab>, "model" | "toParentMessage" | "onTabSelected">) => ((model: Model, toParentMessage: ViewConfig<Message, Tab>["toParentMessage"]) => Html);
85
90
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/tabs/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/tabs/index.ts"],"names":[],"mappings":"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"}
@@ -38,6 +38,7 @@ export const init = (config) => {
38
38
  };
39
39
  };
40
40
  // UPDATE
41
+ /** Moves focus to the tab at the given index. */
41
42
  export const FocusTab = Command.define('FocusTab', CompletedFocusTab);
42
43
  /** Processes a tabs message and returns the next model and commands. */
43
44
  export const update = (model, message) => M.value(message).pipe(M.withReturnType(), M.tagsExhaustive({
@@ -66,10 +67,16 @@ export const update = (model, message) => M.value(message).pipe(M.withReturnType
66
67
  }));
67
68
  const tabPanelId = (id, index) => `${id}-panel-${index}`;
68
69
  const tabId = (id, index) => `${id}-tab-${index}`;
70
+ /** Programmatically selects a tab at the given index, updating the model and returning
71
+ * focus commands. Use this in domain-event handlers when the tab group uses `onTabSelected`. */
72
+ export const selectTab = (model, index) => update(model, TabSelected({ index }));
69
73
  /** Renders a headless tab group with accessible ARIA roles, roving tabindex, and keyboard navigation. */
70
74
  export const view = (config) => {
71
75
  const { div, empty, AriaControls, AriaDisabled, AriaLabel, AriaLabelledBy, AriaOrientation, AriaSelected, Class, DataAttribute, Disabled, Hidden, Id, OnClick, OnKeyDownPreventDefault, Role, Tabindex, Type, keyed, } = html();
72
- const { model, model: { id, activationMode, focusedIndex }, toMessage, tabs, tabToConfig, isTabDisabled, persistPanels, orientation = 'Horizontal', tabListElement = 'div', tabElement = 'button', panelElement = 'div', className, attributes = [], tabListClassName, tabListAttributes = [], tabListAriaLabel, } = config;
76
+ const { model, model: { id, activationMode, focusedIndex }, toParentMessage, onTabSelected, tabs, tabToConfig, isTabDisabled, persistPanels, orientation = 'Horizontal', tabListElement = 'div', tabElement = 'button', panelElement = 'div', className, attributes = [], tabListClassName, tabListAttributes = [], tabListAriaLabel, } = config;
77
+ const dispatchTabSelected = (index) => onTabSelected
78
+ ? onTabSelected(index)
79
+ : toParentMessage(TabSelected({ index }));
73
80
  const isDisabled = (index) => !!isTabDisabled &&
74
81
  pipe(tabs, Array.get(index), Option.exists(tab => isTabDisabled(tab, index)));
75
82
  const { nextKey, previousKey } = M.value(orientation).pipe(M.when('Horizontal', () => ({
@@ -80,8 +87,8 @@ export const view = (config) => {
80
87
  previousKey: 'ArrowUp',
81
88
  })), M.exhaustive);
82
89
  const resolveKeyIndex = keyToIndex(nextKey, previousKey, tabs.length, focusedIndex, isDisabled);
83
- const handleAutomaticKeyDown = (key) => M.value(key).pipe(M.whenOr(nextKey, previousKey, 'Home', 'End', 'PageUp', 'PageDown', () => Option.some(toMessage(TabSelected({ index: resolveKeyIndex(key) })))), M.whenOr('Enter', ' ', () => Option.some(toMessage(TabSelected({ index: focusedIndex })))), M.orElse(() => Option.none()));
84
- const handleManualKeyDown = (key) => M.value(key).pipe(M.whenOr(nextKey, previousKey, 'Home', 'End', 'PageUp', 'PageDown', () => Option.some(toMessage(TabFocused({ index: resolveKeyIndex(key) })))), M.whenOr('Enter', ' ', () => Option.some(toMessage(TabSelected({ index: focusedIndex })))), M.orElse(() => Option.none()));
90
+ const handleAutomaticKeyDown = (key) => M.value(key).pipe(M.whenOr(nextKey, previousKey, 'Home', 'End', 'PageUp', 'PageDown', () => Option.some(dispatchTabSelected(resolveKeyIndex(key)))), M.whenOr('Enter', ' ', () => Option.some(dispatchTabSelected(focusedIndex))), M.orElse(() => Option.none()));
91
+ const handleManualKeyDown = (key) => M.value(key).pipe(M.whenOr(nextKey, previousKey, 'Home', 'End', 'PageUp', 'PageDown', () => Option.some(toParentMessage(TabFocused({ index: resolveKeyIndex(key) })))), M.whenOr('Enter', ' ', () => Option.some(dispatchTabSelected(focusedIndex))), M.orElse(() => Option.none()));
85
92
  const handleKeyDown = (key) => M.value(activationMode).pipe(M.when('Automatic', () => handleAutomaticKeyDown(key)), M.when('Manual', () => handleManualKeyDown(key)), M.exhaustive);
86
93
  const tabButtons = Array.map(tabs, (tab, index) => {
87
94
  const isActive = index === model.activeIndex;
@@ -98,7 +105,7 @@ export const view = (config) => {
98
105
  ...(isActive ? [DataAttribute('selected', '')] : []),
99
106
  ...(isTabDisabledAtIndex
100
107
  ? [Disabled(true), AriaDisabled(true), DataAttribute('disabled', '')]
101
- : [OnClick(toMessage(TabSelected({ index })))]),
108
+ : [OnClick(dispatchTabSelected(index))]),
102
109
  OnKeyDownPreventDefault(handleKeyDown),
103
110
  ...(tabConfig.buttonClassName
104
111
  ? [Class(tabConfig.buttonClassName)]
@@ -153,12 +160,12 @@ export const view = (config) => {
153
160
  ]);
154
161
  };
155
162
  /** Creates a memoized tabs view. Static config is captured in a closure;
156
- * only `model` and `toMessage` are compared per render via `createLazy`. */
163
+ * only `model` and `toParentMessage` are compared per render via `createLazy`. */
157
164
  export const lazy = (staticConfig) => {
158
165
  const lazyView = createLazy();
159
- return (model, toMessage) => lazyView((currentModel, currentToMessage) => view({
166
+ return (model, toParentMessage) => lazyView((currentModel, currentToMessage) => view({
160
167
  ...staticConfig,
161
168
  model: currentModel,
162
- toMessage: currentToMessage,
163
- }), [model, toMessage]);
169
+ toParentMessage: currentToMessage,
170
+ }), [model, toParentMessage]);
164
171
  };
@@ -1,3 +1,3 @@
1
- export { init, update, view, lazy, Model, Message } from './index';
2
- export type { Orientation, ActivationMode, TabSelected, TabFocused, InitConfig, ViewConfig, TabConfig, } from './index';
1
+ export { init, update, selectTab, view, lazy, Model, Message, TabSelected, TabFocused, CompletedFocusTab, FocusTab, } from './index';
2
+ export type { Orientation, ActivationMode, InitConfig, ViewConfig, TabConfig, } from './index';
3
3
  //# sourceMappingURL=public.d.ts.map