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
@@ -120,15 +120,25 @@ export const closedBaseModel = (model) => constrainedEvo(model, {
120
120
  maybeLastPointerPosition: () => Option.none(),
121
121
  });
122
122
  /** Creates a combobox update function from variant-specific handlers. Shared logic (open, close, activate, transition) is handled internally; only close, selection, and immediate-activation behavior varies by variant. */
123
+ /** Advances the combobox's enter/leave transition by waiting a double-rAF. */
123
124
  export const RequestFrame = Command.define('RequestFrame', AdvancedTransitionFrame);
125
+ /** Prevents page scrolling while the combobox popup is open in modal mode. */
124
126
  export const LockScroll = Command.define('LockScroll', CompletedLockScroll);
127
+ /** Re-enables page scrolling after the combobox popup closes. */
125
128
  export const UnlockScroll = Command.define('UnlockScroll', CompletedUnlockScroll);
129
+ /** Marks all elements outside the combobox as inert for modal behavior. */
126
130
  export const InertOthers = Command.define('InertOthers', CompletedSetupInert);
131
+ /** Removes the inert attribute from elements outside the combobox. */
127
132
  export const RestoreInert = Command.define('RestoreInert', CompletedTeardownInert);
133
+ /** Moves focus to the combobox input after selection or close. */
128
134
  export const FocusInput = Command.define('FocusInput', CompletedFocusInput);
135
+ /** Scrolls the active combobox item into view after keyboard navigation. */
129
136
  export const ScrollIntoView = Command.define('ScrollIntoView', CompletedScrollIntoView);
137
+ /** Programmatically clicks the active combobox item's DOM element. */
130
138
  export const ClickItem = Command.define('ClickItem', CompletedClickItem);
139
+ /** Waits for all CSS transitions on the combobox items container to complete. */
131
140
  export const WaitForTransitions = Command.define('WaitForTransitions', EndedTransition);
141
+ /** Detects whether the combobox input moved or the leave transition ended — whichever comes first. */
132
142
  export const DetectMovementOrTransitionEnd = Command.define('DetectMovementOrTransitionEnd', DetectedInputMovement, EndedTransition);
133
143
  export const makeUpdate = (handlers) => {
134
144
  const withUpdateReturn = M.withReturnType();
@@ -318,7 +328,13 @@ export const makeUpdate = (handlers) => {
318
328
  /** Creates a combobox view function from variant-specific behavior. Shared rendering logic (input, items, transitions, keyboard navigation) is handled internally; only selection display varies by variant. */
319
329
  export const makeView = (behavior) => (config) => {
320
330
  const { div, input, AriaActiveDescendant, AriaControls, AriaDisabled, AriaExpanded, AriaInvalid, AriaLabelledBy, AriaMultiSelectable, AriaSelected, Attribute, Autocomplete, Class, DataAttribute, Id, Name, OnBlur, OnClick, OnDestroy, OnFocus, OnInput, OnInsert, OnKeyDownPreventDefault, OnPointerLeave, OnPointerMove, Placeholder, Role, Style, Tabindex, Type, Value, keyed, } = html();
321
- const { model: { id, isOpen, immediate, transitionState, maybeActiveItemIndex }, toMessage, items, itemToConfig, itemToValue, itemToDisplayText, isItemDisabled, inputClassName, inputAttributes = [], inputPlaceholder, inputWrapperClassName, inputWrapperAttributes = [], itemsClassName, itemsAttributes = [], itemsScrollClassName, itemsScrollAttributes = [], backdropClassName, backdropAttributes = [], className, attributes = [], buttonContent, buttonClassName, buttonAttributes = [], formName, isDisabled, isInvalid, openOnFocus, itemGroupKey, groupToHeading, groupClassName, groupAttributes = [], separatorClassName, separatorAttributes = [], anchor, } = config;
331
+ const { model: { id, isOpen, immediate, transitionState, maybeActiveItemIndex }, toParentMessage, onSelectedItem, items, itemToConfig, itemToValue, itemToDisplayText, isItemDisabled, inputClassName, inputAttributes = [], inputPlaceholder, inputWrapperClassName, inputWrapperAttributes = [], itemsClassName, itemsAttributes = [], itemsScrollClassName, itemsScrollAttributes = [], backdropClassName, backdropAttributes = [], className, attributes = [], buttonContent, buttonClassName, buttonAttributes = [], formName, isDisabled, isInvalid, openOnFocus, itemGroupKey, groupToHeading, groupClassName, groupAttributes = [], separatorClassName, separatorAttributes = [], anchor, } = config;
332
+ const dispatchSelectedItem = (item, index) => onSelectedItem
333
+ ? onSelectedItem(itemToValue(item, index))
334
+ : toParentMessage(SelectedItem({
335
+ item: itemToValue(item, index),
336
+ displayText: itemToDisplayText(item, index),
337
+ }));
322
338
  const isLeaving = transitionState === 'LeaveStart' || transitionState === 'LeaveAnimating';
323
339
  const isVisible = isOpen || isLeaving;
324
340
  const transitionAttributes = M.value(transitionState).pipe(M.when('EnterStart', () => [
@@ -350,24 +366,24 @@ export const makeView = (behavior) => (config) => {
350
366
  })));
351
367
  const handleInputKeyDown = (key) => M.value(key).pipe(M.when('ArrowDown', () => {
352
368
  if (!isOpen) {
353
- return Option.some(toMessage(Opened({
369
+ return Option.some(toParentMessage(Opened({
354
370
  maybeActiveItemIndex: Option.some(firstEnabledIndex),
355
371
  })));
356
372
  }
357
373
  const targetIndex = resolveActiveIndex('ArrowDown');
358
- return Option.some(toMessage(ActivatedItem({
374
+ return Option.some(toParentMessage(ActivatedItem({
359
375
  index: targetIndex,
360
376
  activationTrigger: 'Keyboard',
361
377
  maybeImmediateSelection: resolveImmediateSelection(targetIndex),
362
378
  })));
363
379
  }), M.when('ArrowUp', () => {
364
380
  if (!isOpen) {
365
- return Option.some(toMessage(Opened({
381
+ return Option.some(toParentMessage(Opened({
366
382
  maybeActiveItemIndex: Option.some(lastEnabledIndex),
367
383
  })));
368
384
  }
369
385
  const targetIndex = resolveActiveIndex('ArrowUp');
370
- return Option.some(toMessage(ActivatedItem({
386
+ return Option.some(toParentMessage(ActivatedItem({
371
387
  index: targetIndex,
372
388
  activationTrigger: 'Keyboard',
373
389
  maybeImmediateSelection: resolveImmediateSelection(targetIndex),
@@ -376,18 +392,18 @@ export const makeView = (behavior) => (config) => {
376
392
  if (!isOpen) {
377
393
  return Option.none();
378
394
  }
379
- return Option.map(maybeActiveItemIndex, index => toMessage(RequestedItemClick({ index })));
395
+ return Option.map(maybeActiveItemIndex, index => toParentMessage(RequestedItemClick({ index })));
380
396
  }), M.when('Escape', () => {
381
397
  if (!isOpen) {
382
398
  return Option.none();
383
399
  }
384
- return Option.some(toMessage(Closed()));
400
+ return Option.some(toParentMessage(Closed()));
385
401
  }), M.whenOr('Home', 'End', () => {
386
402
  if (!isOpen) {
387
403
  return Option.none();
388
404
  }
389
405
  const targetIndex = resolveActiveIndex(key);
390
- return Option.some(toMessage(ActivatedItem({
406
+ return Option.some(toParentMessage(ActivatedItem({
391
407
  index: targetIndex,
392
408
  activationTrigger: 'Keyboard',
393
409
  maybeImmediateSelection: resolveImmediateSelection(targetIndex),
@@ -416,12 +432,12 @@ export const makeView = (behavior) => (config) => {
416
432
  ...(isDisabled
417
433
  ? [AriaDisabled(true), DataAttribute('disabled', '')]
418
434
  : [
419
- OnInput(value => toMessage(UpdatedInputValue({ value }))),
435
+ OnInput(value => toParentMessage(UpdatedInputValue({ value }))),
420
436
  OnKeyDownPreventDefault(handleInputKeyDown),
421
- OnBlur(toMessage(ClosedByTab())),
437
+ OnBlur(toParentMessage(ClosedByTab())),
422
438
  ...(openOnFocus
423
439
  ? [
424
- OnFocus(toMessage(Opened({ maybeActiveItemIndex: Option.none() }))),
440
+ OnFocus(toParentMessage(Opened({ maybeActiveItemIndex: Option.none() }))),
425
441
  ]
426
442
  : []),
427
443
  ]),
@@ -490,16 +506,13 @@ export const makeView = (behavior) => (config) => {
490
506
  : []),
491
507
  ...(isInteractive
492
508
  ? [
493
- OnClick(toMessage(SelectedItem({
494
- item: itemToValue(item, index),
495
- displayText: itemToDisplayText(item, index),
496
- }))),
509
+ OnClick(dispatchSelectedItem(item, index)),
497
510
  ...(isActiveItem
498
511
  ? []
499
512
  : [
500
- OnPointerMove((screenX, screenY, pointerType) => OptionExt.when(pointerType !== 'touch', toMessage(MovedPointerOverItem({ index, screenX, screenY })))),
513
+ OnPointerMove((screenX, screenY, pointerType) => OptionExt.when(pointerType !== 'touch', toParentMessage(MovedPointerOverItem({ index, screenX, screenY })))),
501
514
  ]),
502
- OnPointerLeave(pointerType => OptionExt.when(pointerType !== 'touch', toMessage(DeactivatedItem()))),
515
+ OnPointerLeave(pointerType => OptionExt.when(pointerType !== 'touch', toParentMessage(DeactivatedItem()))),
503
516
  ]
504
517
  : []),
505
518
  ...(itemConfig.className ? [Class(itemConfig.className)] : []),
@@ -548,7 +561,7 @@ export const makeView = (behavior) => (config) => {
548
561
  });
549
562
  };
550
563
  const backdrop = keyed('div')(`${id}-backdrop`, [
551
- ...(isLeaving ? [] : [OnClick(toMessage(Closed()))]),
564
+ ...(isLeaving ? [] : [OnClick(toParentMessage(Closed()))]),
552
565
  ...(backdropClassName ? [Class(backdropClassName)] : []),
553
566
  ...backdropAttributes,
554
567
  ], []);
@@ -582,7 +595,7 @@ export const makeView = (behavior) => (config) => {
582
595
  Attribute('aria-haspopup', 'listbox'),
583
596
  ...(isDisabled
584
597
  ? [AriaDisabled(true), DataAttribute('disabled', '')]
585
- : [OnClick(toMessage(PressedToggleButton()))]),
598
+ : [OnClick(toParentMessage(PressedToggleButton()))]),
586
599
  OnInsert(preventBlurOnPointerDown),
587
600
  ...(buttonClassName ? [Class(buttonClassName)] : []),
588
601
  ...buttonAttributes,
@@ -151,7 +151,8 @@ export declare const view: <Message, Item extends string>(config: Readonly<{
151
151
  readonly maybeSelectedItem: Option.Option<string>;
152
152
  readonly maybeSelectedDisplayText: Option.Option<string>;
153
153
  };
154
- toMessage: (message: import("./shared").Opened | import("./shared").Closed | import("./shared").ClosedByTab | import("./shared").ActivatedItem | import("./shared").DeactivatedItem | import("./shared").SelectedItem | import("./shared").MovedPointerOverItem | import("./shared").RequestedItemClick | import("./shared").UpdatedInputValue | import("./shared").PressedToggleButton | import("./shared").CompletedLockScroll | import("./shared").CompletedUnlockScroll | import("./shared").CompletedSetupInert | import("./shared").CompletedTeardownInert | import("./shared").CompletedFocusInput | import("./shared").CompletedScrollIntoView | import("./shared").CompletedClickItem) => Message;
154
+ toParentMessage: (message: import("./shared").Opened | import("./shared").Closed | import("./shared").ClosedByTab | import("./shared").ActivatedItem | import("./shared").DeactivatedItem | import("./shared").SelectedItem | import("./shared").MovedPointerOverItem | import("./shared").RequestedItemClick | import("./shared").UpdatedInputValue | import("./shared").PressedToggleButton | import("./shared").CompletedLockScroll | import("./shared").CompletedUnlockScroll | import("./shared").CompletedSetupInert | import("./shared").CompletedTeardownInert | import("./shared").CompletedFocusInput | import("./shared").CompletedScrollIntoView | import("./shared").CompletedClickItem) => Message;
155
+ onSelectedItem?: (value: string) => Message;
155
156
  items: readonly Item[];
156
157
  itemToConfig: (item: Item, context: Readonly<{
157
158
  isActive: boolean;
@@ -202,6 +203,6 @@ export declare const view: <Message, Item extends string>(config: Readonly<{
202
203
  }>;
203
204
  }>) => Html;
204
205
  /** Creates a memoized single-select combobox view. Static config is captured in a closure;
205
- * only `model` and `toMessage` are compared per render via `createLazy`. */
206
- export declare const lazy: <Message, Item extends string>(staticConfig: Omit<ViewConfig<Message, Item>, "model" | "toMessage">) => ((model: Model, toMessage: BaseViewConfig<Message, Item, Model>["toMessage"]) => Html);
206
+ * only `model` and `toParentMessage` are compared per render via `createLazy`. */
207
+ export declare const lazy: <Message, Item extends string>(staticConfig: Omit<ViewConfig<Message, Item>, "model" | "toParentMessage" | "onSelectedItem">) => ((model: Model, toParentMessage: BaseViewConfig<Message, Item, Model>["toParentMessage"]) => Html);
207
208
  //# sourceMappingURL=single.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"single.d.ts","sourceRoot":"","sources":["../../../src/ui/combobox/single.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAAE,MAAM,IAAI,CAAC,EAAQ,MAAM,QAAQ,CAAA;AAEzD,OAAO,EAAE,KAAK,IAAI,EAAc,MAAM,YAAY,CAAA;AAElD,OAAO,EACL,KAAK,cAAc,EAEnB,KAAK,cAAc,EAKpB,MAAM,UAAU,CAAA;AAIjB,uJAAuJ;AACvJ,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;GAOjB,CAAA;AAED,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAA;AAIrC,8RAA8R;AAC9R,MAAM,MAAM,UAAU,GAAG,cAAc,GACrC,QAAQ,CAAC;IACP,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAC7B,CAAC,CAAA;AAEJ,4IAA4I;AAC5I,eAAO,MAAM,IAAI,GAAI,QAAQ,UAAU,KAAG,KAMxC,CAAA;AAIF,uIAAuI;AACvI,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAqDjB,CAAA;AAIF,wEAAwE;AACxE,MAAM,MAAM,UAAU,CAAC,OAAO,EAAE,IAAI,SAAS,MAAM,IAAI,cAAc,CACnE,OAAO,EACP,IAAI,EACJ,KAAK,CACN,CAAA;AAED,0IAA0I;AAC1I,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAOf,CAAA;AAEF;6EAC6E;AAC7E,eAAO,MAAM,IAAI,GAAI,OAAO,EAAE,IAAI,SAAS,MAAM,EAC/C,cAAc,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,WAAW,CAAC,KACnE,CAAC,CACF,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,cAAc,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,WAAW,CAAC,KACzD,IAAI,CAgBR,CAAA"}
1
+ {"version":3,"file":"single.d.ts","sourceRoot":"","sources":["../../../src/ui/combobox/single.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAAE,MAAM,IAAI,CAAC,EAAQ,MAAM,QAAQ,CAAA;AAEzD,OAAO,EAAE,KAAK,IAAI,EAAc,MAAM,YAAY,CAAA;AAElD,OAAO,EACL,KAAK,cAAc,EAEnB,KAAK,cAAc,EAKpB,MAAM,UAAU,CAAA;AAIjB,uJAAuJ;AACvJ,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;GAOjB,CAAA;AAED,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAA;AAIrC,8RAA8R;AAC9R,MAAM,MAAM,UAAU,GAAG,cAAc,GACrC,QAAQ,CAAC;IACP,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAC7B,CAAC,CAAA;AAEJ,4IAA4I;AAC5I,eAAO,MAAM,IAAI,GAAI,QAAQ,UAAU,KAAG,KAMxC,CAAA;AAIF,uIAAuI;AACvI,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAqDjB,CAAA;AAIF,wEAAwE;AACxE,MAAM,MAAM,UAAU,CAAC,OAAO,EAAE,IAAI,SAAS,MAAM,IAAI,cAAc,CACnE,OAAO,EACP,IAAI,EACJ,KAAK,CACN,CAAA;AAED,0IAA0I;AAC1I,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAOf,CAAA;AAEF;mFACmF;AACnF,eAAO,MAAM,IAAI,GAAI,OAAO,EAAE,IAAI,SAAS,MAAM,EAC/C,cAAc,IAAI,CAChB,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,EACzB,OAAO,GAAG,iBAAiB,GAAG,gBAAgB,CAC/C,KACA,CAAC,CACF,KAAK,EAAE,KAAK,EACZ,eAAe,EAAE,cAAc,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,iBAAiB,CAAC,KACrE,IAAI,CAoBR,CAAA"}
@@ -62,12 +62,12 @@ export const view = makeView({
62
62
  ariaMultiSelectable: false,
63
63
  });
64
64
  /** Creates a memoized single-select combobox view. Static config is captured in a closure;
65
- * only `model` and `toMessage` are compared per render via `createLazy`. */
65
+ * only `model` and `toParentMessage` are compared per render via `createLazy`. */
66
66
  export const lazy = (staticConfig) => {
67
67
  const lazyView = createLazy();
68
- return (model, toMessage) => lazyView((currentModel, currentToMessage) => view({
68
+ return (model, toParentMessage) => lazyView((currentModel, currentToMessage) => view({
69
69
  ...staticConfig,
70
70
  model: currentModel,
71
- toMessage: currentToMessage,
72
- }), [model, toMessage]);
71
+ toParentMessage: currentToMessage,
72
+ }), [model, toParentMessage]);
73
73
  };
@@ -46,15 +46,19 @@ export type InitConfig = Readonly<{
46
46
  /** Creates an initial dialog model from a config. Defaults to closed and non-animated. */
47
47
  export declare const init: (config: InitConfig) => Model;
48
48
  type UpdateReturn = readonly [Model, ReadonlyArray<Command.Command<Message>>];
49
+ /** Advances the dialog's enter/leave transition by waiting a double-rAF. */
49
50
  export declare const RequestFrame: Command.CommandDefinition<"RequestFrame", {
50
51
  readonly _tag: "AdvancedTransitionFrame";
51
52
  }>;
53
+ /** Locks page scroll and calls `showModal()` on the native dialog element. */
52
54
  export declare const ShowDialog: Command.CommandDefinition<"ShowDialog", {
53
55
  readonly _tag: "CompletedShowDialog";
54
56
  }>;
57
+ /** Calls `close()` on the native dialog element and unlocks page scroll. */
55
58
  export declare const CloseDialog: Command.CommandDefinition<"CloseDialog", {
56
59
  readonly _tag: "CompletedCloseDialog";
57
60
  }>;
61
+ /** Waits for all CSS transitions on the dialog panel to complete. */
58
62
  export declare const WaitForTransitions: Command.CommandDefinition<"WaitForTransitions", {
59
63
  readonly _tag: "EndedTransition";
60
64
  }>;
@@ -67,7 +71,8 @@ export declare const descriptionId: (model: Model) => string;
67
71
  /** Configuration for rendering a dialog with `view`. */
68
72
  export type ViewConfig<Message> = Readonly<{
69
73
  model: Model;
70
- toMessage: (message: Closed | CompletedShowDialog | CompletedCloseDialog) => Message;
74
+ toParentMessage: (message: Closed | CompletedShowDialog | CompletedCloseDialog) => Message;
75
+ onClosed?: () => Message;
71
76
  panelContent: Html;
72
77
  panelClassName?: string;
73
78
  panelAttributes?: ReadonlyArray<Attribute<Message>>;
@@ -76,10 +81,13 @@ export type ViewConfig<Message> = Readonly<{
76
81
  className?: string;
77
82
  attributes?: ReadonlyArray<Attribute<Message>>;
78
83
  }>;
84
+ /** Programmatically closes the dialog, updating the model and returning
85
+ * close commands. Use this in domain-event handlers when the dialog uses `onClosed`. */
86
+ export declare const close: (model: Model) => readonly [Model, ReadonlyArray<Command.Command<Message>>];
79
87
  /** Renders a headless dialog component backed by the native `<dialog>` element with `showModal()`. */
80
88
  export declare const view: <Message>(config: ViewConfig<Message>) => Html;
81
89
  /** Creates a memoized dialog 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>(staticConfig: Omit<ViewConfig<Message>, "model" | "toMessage">) => ((model: Model, toMessage: ViewConfig<Message>["toMessage"]) => Html);
90
+ * only `model` and `toParentMessage` are compared per render via `createLazy`. */
91
+ export declare const lazy: <Message>(staticConfig: Omit<ViewConfig<Message>, "model" | "toParentMessage" | "onClosed">) => ((model: Model, toParentMessage: ViewConfig<Message>["toParentMessage"]) => Html);
84
92
  export {};
85
93
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/dialog/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqC,MAAM,IAAI,CAAC,EAAE,MAAM,QAAQ,CAAA;AAEvE,OAAO,KAAK,OAAO,MAAM,eAAe,CAAA;AAExC,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,IAAI,EAAoB,MAAM,YAAY,CAAA;AAQxE,oIAAoI;AACpI,eAAO,MAAM,KAAK;;;;;;EAMhB,CAAA;AAEF,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAA;AAIrC,wEAAwE;AACxE,eAAO,MAAM,MAAM,2DAAc,CAAA;AACjC,wHAAwH;AACxH,eAAO,MAAM,MAAM,2DAAc,CAAA;AACjC,6EAA6E;AAC7E,eAAO,MAAM,mBAAmB,wEAA2B,CAAA;AAC3D,iFAAiF;AACjF,eAAO,MAAM,oBAAoB,yEAA4B,CAAA;AAC7D,oGAAoG;AACpG,eAAO,MAAM,uBAAuB,4EAA+B,CAAA;AACnE,mFAAmF;AACnF,eAAO,MAAM,eAAe,oEAAuB,CAAA;AAEnD,8DAA8D;AAC9D,eAAO,MAAM,OAAO,EAAE,CAAC,CAAC,KAAK,CAC3B;IACE,OAAO,MAAM;IACb,OAAO,MAAM;IACb,OAAO,mBAAmB;IAC1B,OAAO,oBAAoB;IAC3B,OAAO,uBAAuB;IAC9B,OAAO,eAAe;CACvB,CAQF,CAAA;AAED,MAAM,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC,IAAI,CAAA;AACvC,MAAM,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC,IAAI,CAAA;AACvC,MAAM,MAAM,mBAAmB,GAAG,OAAO,mBAAmB,CAAC,IAAI,CAAA;AACjE,MAAM,MAAM,oBAAoB,GAAG,OAAO,oBAAoB,CAAC,IAAI,CAAA;AAEnE,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAA;AAIzC,iIAAiI;AACjI,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAC,CAAA;AAEF,0FAA0F;AAC1F,eAAO,MAAM,IAAI,GAAI,QAAQ,UAAU,KAAG,KAMxC,CAAA;AAOF,KAAK,YAAY,GAAG,SAAS,CAAC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;AAG7E,eAAO,MAAM,YAAY;;EAGxB,CAAA;AACD,eAAO,MAAM,UAAU;;EAAoD,CAAA;AAC3E,eAAO,MAAM,WAAW;;EAAsD,CAAA;AAC9E,eAAO,MAAM,kBAAkB;;EAG9B,CAAA;AAED,0EAA0E;AAC1E,eAAO,MAAM,MAAM,GAAI,OAAO,KAAK,EAAE,SAAS,OAAO,KAAG,YA0HvD,CAAA;AAID,iGAAiG;AACjG,eAAO,MAAM,OAAO,GAAI,OAAO,KAAK,KAAG,MAA6B,CAAA;AAEpE,wGAAwG;AACxG,eAAO,MAAM,aAAa,GAAI,OAAO,KAAK,KAAG,MAAmC,CAAA;AAEhF,wDAAwD;AACxD,MAAM,MAAM,UAAU,CAAC,OAAO,IAAI,QAAQ,CAAC;IACzC,KAAK,EAAE,KAAK,CAAA;IACZ,SAAS,EAAE,CACT,OAAO,EAAE,MAAM,GAAG,mBAAmB,GAAG,oBAAoB,KACzD,OAAO,CAAA;IACZ,YAAY,EAAE,IAAI,CAAA;IAClB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,eAAe,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA;IACnD,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,kBAAkB,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA;IACtD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA;CAC/C,CAAC,CAAA;AAEF,sGAAsG;AACtG,eAAO,MAAM,IAAI,GAAI,OAAO,EAAE,QAAQ,UAAU,CAAC,OAAO,CAAC,KAAG,IAiG3D,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/dialog/index.ts"],"names":[],"mappings":"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"}
@@ -42,9 +42,13 @@ export const init = (config) => ({
42
42
  const dialogSelector = (id) => `#${id}`;
43
43
  const panelSelector = (id) => `#${id}-panel`;
44
44
  const withUpdateReturn = M.withReturnType();
45
+ /** Advances the dialog's enter/leave transition by waiting a double-rAF. */
45
46
  export const RequestFrame = Command.define('RequestFrame', AdvancedTransitionFrame);
47
+ /** Locks page scroll and calls `showModal()` on the native dialog element. */
46
48
  export const ShowDialog = Command.define('ShowDialog', CompletedShowDialog);
49
+ /** Calls `close()` on the native dialog element and unlocks page scroll. */
47
50
  export const CloseDialog = Command.define('CloseDialog', CompletedCloseDialog);
51
+ /** Waits for all CSS transitions on the dialog panel to complete. */
48
52
  export const WaitForTransitions = Command.define('WaitForTransitions', EndedTransition);
49
53
  /** Processes a dialog message and returns the next model and commands. */
50
54
  export const update = (model, message) => {
@@ -111,10 +115,14 @@ export const update = (model, message) => {
111
115
  export const titleId = (model) => `${model.id}-title`;
112
116
  /** Returns the ID used for `aria-describedby` on the dialog. Apply this to your description element. */
113
117
  export const descriptionId = (model) => `${model.id}-description`;
118
+ /** Programmatically closes the dialog, updating the model and returning
119
+ * close commands. Use this in domain-event handlers when the dialog uses `onClosed`. */
120
+ export const close = (model) => update(model, Closed());
114
121
  /** Renders a headless dialog component backed by the native `<dialog>` element with `showModal()`. */
115
122
  export const view = (config) => {
116
123
  const { AriaDescribedBy, AriaLabelledBy, Class, DataAttribute, Id, OnCancel, OnClick, Style, keyed, } = html();
117
- const { model: { id, isOpen, transitionState }, toMessage, panelContent, panelClassName, panelAttributes = [], backdropClassName, backdropAttributes = [], className, attributes = [], } = config;
124
+ const { model: { id, isOpen, transitionState }, toParentMessage, onClosed, panelContent, panelClassName, panelAttributes = [], backdropClassName, backdropAttributes = [], className, attributes = [], } = config;
125
+ const dispatchClosed = () => onClosed ? onClosed() : toParentMessage(Closed());
118
126
  const isLeaving = transitionState === 'LeaveStart' || transitionState === 'LeaveAnimating';
119
127
  const isVisible = isOpen || isLeaving;
120
128
  const transitionAttributes = M.value(transitionState).pipe(M.when('EnterStart', () => [
@@ -136,7 +144,7 @@ export const view = (config) => {
136
144
  Id(id),
137
145
  AriaLabelledBy(`${id}-title`),
138
146
  AriaDescribedBy(`${id}-description`),
139
- OnCancel(toMessage(Closed())),
147
+ OnCancel(dispatchClosed()),
140
148
  Style({
141
149
  width: '100%',
142
150
  height: '100%',
@@ -153,7 +161,7 @@ export const view = (config) => {
153
161
  const backdrop = keyed('div')(`${id}-backdrop`, [
154
162
  Style({ minHeight: '100vh' }),
155
163
  ...transitionAttributes,
156
- ...(isLeaving ? [] : [OnClick(toMessage(Closed()))]),
164
+ ...(isLeaving ? [] : [OnClick(dispatchClosed())]),
157
165
  ...(backdropClassName ? [Class(backdropClassName)] : []),
158
166
  ...backdropAttributes,
159
167
  ], []);
@@ -167,12 +175,12 @@ export const view = (config) => {
167
175
  return keyed('dialog')(id, dialogAttributes, content);
168
176
  };
169
177
  /** Creates a memoized dialog view. Static config is captured in a closure;
170
- * only `model` and `toMessage` are compared per render via `createLazy`. */
178
+ * only `model` and `toParentMessage` are compared per render via `createLazy`. */
171
179
  export const lazy = (staticConfig) => {
172
180
  const lazyView = createLazy();
173
- return (model, toMessage) => lazyView((currentModel, currentToMessage) => view({
181
+ return (model, toParentMessage) => lazyView((currentModel, currentToMessage) => view({
174
182
  ...staticConfig,
175
183
  model: currentModel,
176
- toMessage: currentToMessage,
177
- }), [model, toMessage]);
184
+ toParentMessage: currentToMessage,
185
+ }), [model, toParentMessage]);
178
186
  };
@@ -1,3 +1,3 @@
1
- export { init, update, view, lazy, titleId, descriptionId, Model, Message, Opened, Closed, CompletedShowDialog, CompletedCloseDialog, AdvancedTransitionFrame, EndedTransition, } from './index';
1
+ export { init, update, close, view, lazy, titleId, descriptionId, Model, Message, Opened, Closed, CompletedShowDialog, CompletedCloseDialog, AdvancedTransitionFrame, EndedTransition, RequestFrame, ShowDialog, CloseDialog, WaitForTransitions, } from './index';
2
2
  export type { InitConfig, ViewConfig } from './index';
3
3
  //# sourceMappingURL=public.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/ui/dialog/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,MAAM,EACN,IAAI,EACJ,IAAI,EACJ,OAAO,EACP,aAAa,EACb,KAAK,EACL,OAAO,EACP,MAAM,EACN,MAAM,EACN,mBAAmB,EACnB,oBAAoB,EACpB,uBAAuB,EACvB,eAAe,GAChB,MAAM,SAAS,CAAA;AAEhB,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA"}
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/ui/dialog/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,MAAM,EACN,KAAK,EACL,IAAI,EACJ,IAAI,EACJ,OAAO,EACP,aAAa,EACb,KAAK,EACL,OAAO,EACP,MAAM,EACN,MAAM,EACN,mBAAmB,EACnB,oBAAoB,EACpB,uBAAuB,EACvB,eAAe,EACf,YAAY,EACZ,UAAU,EACV,WAAW,EACX,kBAAkB,GACnB,MAAM,SAAS,CAAA;AAEhB,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA"}
@@ -1 +1 @@
1
- export { init, update, view, lazy, titleId, descriptionId, Model, Message, Opened, Closed, CompletedShowDialog, CompletedCloseDialog, AdvancedTransitionFrame, EndedTransition, } from './index';
1
+ export { init, update, close, view, lazy, titleId, descriptionId, Model, Message, Opened, Closed, CompletedShowDialog, CompletedCloseDialog, AdvancedTransitionFrame, EndedTransition, RequestFrame, ShowDialog, CloseDialog, WaitForTransitions, } from './index';
@@ -30,6 +30,7 @@ export type InitConfig = Readonly<{
30
30
  }>;
31
31
  /** Creates an initial disclosure model from a config. Defaults to closed. */
32
32
  export declare const init: (config: InitConfig) => Model;
33
+ /** Moves focus to the disclosure's toggle button. */
33
34
  export declare const FocusButton: Command.CommandDefinition<"FocusButton", {
34
35
  readonly _tag: "CompletedFocusButton";
35
36
  }>;
@@ -38,7 +39,8 @@ export declare const update: (model: Model, message: Message) => readonly [Model
38
39
  /** Configuration for rendering a disclosure with `view`. */
39
40
  export type ViewConfig<Message> = Readonly<{
40
41
  model: Model;
41
- toMessage: (message: Toggled | Closed | CompletedFocusButton) => Message;
42
+ toParentMessage: (message: Toggled | Closed | CompletedFocusButton) => Message;
43
+ onToggled?: () => Message;
42
44
  buttonClassName?: string;
43
45
  buttonAttributes?: ReadonlyArray<Attribute<Message>>;
44
46
  buttonContent: Html;
@@ -52,9 +54,12 @@ export type ViewConfig<Message> = Readonly<{
52
54
  className?: string;
53
55
  attributes?: ReadonlyArray<Attribute<Message>>;
54
56
  }>;
57
+ /** Programmatically toggles the disclosure, updating the model and returning
58
+ * focus commands. Use this in domain-event handlers when the disclosure uses `onToggled`. */
59
+ export declare const toggle: (model: Model) => readonly [Model, ReadonlyArray<Command.Command<Message>>];
55
60
  /** Renders a headless disclosure component with accessible ARIA attributes and keyboard support. */
56
61
  export declare const view: <Message>(config: ViewConfig<Message>) => Html;
57
62
  /** Creates a memoized disclosure view. Static config is captured in a closure;
58
- * only `model` and `toMessage` are compared per render via `createLazy`. */
59
- export declare const lazy: <Message>(staticConfig: Omit<ViewConfig<Message>, "model" | "toMessage">) => ((model: Model, toMessage: ViewConfig<Message>["toMessage"]) => Html);
63
+ * only `model` and `toParentMessage` are compared per render via `createLazy`. */
64
+ export declare const lazy: <Message>(staticConfig: Omit<ViewConfig<Message>, "model" | "toParentMessage" | "onToggled">) => ((model: Model, toParentMessage: ViewConfig<Message>["toParentMessage"]) => Html);
60
65
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/disclosure/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/disclosure/index.ts"],"names":[],"mappings":"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"}
@@ -28,6 +28,7 @@ export const init = (config) => ({
28
28
  const buttonId = (id) => `${id}-button`;
29
29
  const buttonSelector = (id) => `#${CSS.escape(buttonId(id))}`;
30
30
  const panelId = (id) => `${id}-panel`;
31
+ /** Moves focus to the disclosure's toggle button. */
31
32
  export const FocusButton = Command.define('FocusButton', CompletedFocusButton);
32
33
  /** Processes a disclosure message and returns the next model and commands. */
33
34
  export const update = (model, message) => M.value(message).pipe(M.withReturnType(), M.tagsExhaustive({
@@ -44,12 +45,16 @@ export const update = (model, message) => M.value(message).pipe(M.withReturnType
44
45
  },
45
46
  CompletedFocusButton: () => [model, []],
46
47
  }));
48
+ /** Programmatically toggles the disclosure, updating the model and returning
49
+ * focus commands. Use this in domain-event handlers when the disclosure uses `onToggled`. */
50
+ export const toggle = (model) => update(model, Toggled());
47
51
  /** Renders a headless disclosure component with accessible ARIA attributes and keyboard support. */
48
52
  export const view = (config) => {
49
53
  const { div, empty, AriaControls, AriaDisabled, AriaExpanded, Class, DataAttribute, Disabled, Hidden, Id, OnClick, OnKeyDownPreventDefault, Tabindex, Type, keyed, } = html();
50
- const { model: { id, isOpen }, toMessage, buttonClassName, buttonAttributes = [], buttonContent, panelClassName, panelAttributes = [], panelContent, isDisabled, persistPanel, buttonElement = 'button', panelElement = 'div', className, attributes = [], } = config;
54
+ const { model: { id, isOpen }, toParentMessage, onToggled, buttonClassName, buttonAttributes = [], buttonContent, panelClassName, panelAttributes = [], panelContent, isDisabled, persistPanel, buttonElement = 'button', panelElement = 'div', className, attributes = [], } = config;
55
+ const dispatchToggled = () => onToggled ? onToggled() : toParentMessage(Toggled());
51
56
  const isNativeButton = buttonElement === 'button';
52
- const handleKeyDown = (key) => M.value(key).pipe(M.whenOr('Enter', ' ', () => Option.some(toMessage(Toggled()))), M.orElse(() => Option.none()));
57
+ const handleKeyDown = (key) => M.value(key).pipe(M.whenOr('Enter', ' ', () => Option.some(dispatchToggled())), M.orElse(() => Option.none()));
53
58
  const disabledAttributes = [
54
59
  Disabled(true),
55
60
  AriaDisabled(true),
@@ -58,7 +63,7 @@ export const view = (config) => {
58
63
  const interactionAttributes = isDisabled
59
64
  ? disabledAttributes
60
65
  : [
61
- OnClick(toMessage(Toggled())),
66
+ OnClick(dispatchToggled()),
62
67
  ...(!isNativeButton ? [OnKeyDownPreventDefault(handleKeyDown)] : []),
63
68
  ];
64
69
  const resolvedButtonAttributes = [
@@ -90,12 +95,12 @@ export const view = (config) => {
90
95
  ]);
91
96
  };
92
97
  /** Creates a memoized disclosure view. Static config is captured in a closure;
93
- * only `model` and `toMessage` are compared per render via `createLazy`. */
98
+ * only `model` and `toParentMessage` are compared per render via `createLazy`. */
94
99
  export const lazy = (staticConfig) => {
95
100
  const lazyView = createLazy();
96
- return (model, toMessage) => lazyView((currentModel, currentToMessage) => view({
101
+ return (model, toParentMessage) => lazyView((currentModel, currentToMessage) => view({
97
102
  ...staticConfig,
98
103
  model: currentModel,
99
- toMessage: currentToMessage,
100
- }), [model, toMessage]);
104
+ toParentMessage: currentToMessage,
105
+ }), [model, toParentMessage]);
101
106
  };
@@ -1,3 +1,3 @@
1
- export { init, update, view, lazy, Model, Message } from './index';
2
- export type { Toggled, Closed, CompletedFocusButton, InitConfig, ViewConfig, } from './index';
1
+ export { init, update, toggle, view, lazy, Model, Message, Toggled, Closed, CompletedFocusButton, FocusButton, } from './index';
2
+ export type { InitConfig, ViewConfig } from './index';
3
3
  //# sourceMappingURL=public.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/ui/disclosure/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,OAAO,EACP,MAAM,EACN,oBAAoB,EACpB,UAAU,EACV,UAAU,GACX,MAAM,SAAS,CAAA"}
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/ui/disclosure/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,MAAM,EACN,MAAM,EACN,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,OAAO,EACP,OAAO,EACP,MAAM,EACN,oBAAoB,EACpB,WAAW,GACZ,MAAM,SAAS,CAAA;AAEhB,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA"}
@@ -1 +1 @@
1
- export { init, update, view, lazy, Model, Message } from './index';
1
+ export { init, update, toggle, view, lazy, Model, Message, Toggled, Closed, CompletedFocusButton, FocusButton, } from './index';