foldkit 0.40.0 → 0.42.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.
- package/README.md +20 -18
- package/dist/devtools/overlay.d.ts.map +1 -1
- package/dist/devtools/overlay.js +35 -6
- package/dist/devtools/store.d.ts +2 -1
- package/dist/devtools/store.d.ts.map +1 -1
- package/dist/devtools/store.js +4 -1
- package/dist/runtime/browserListeners.d.ts +2 -2
- package/dist/runtime/browserListeners.js +11 -11
- package/dist/runtime/crashUI.d.ts.map +1 -1
- package/dist/runtime/crashUI.js +1 -3
- package/dist/runtime/public.d.ts +2 -2
- package/dist/runtime/public.d.ts.map +1 -1
- package/dist/runtime/public.js +1 -1
- package/dist/runtime/runtime.d.ts +33 -46
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +25 -43
- package/dist/ui/checkbox/index.d.ts +3 -3
- package/dist/ui/checkbox/index.d.ts.map +1 -1
- package/dist/ui/checkbox/index.js +11 -8
- package/dist/ui/combobox/multi.d.ts +4 -3
- package/dist/ui/combobox/multi.d.ts.map +1 -1
- package/dist/ui/combobox/multi.js +4 -4
- package/dist/ui/combobox/public.d.ts +2 -2
- package/dist/ui/combobox/public.d.ts.map +1 -1
- package/dist/ui/combobox/public.js +1 -1
- package/dist/ui/combobox/shared.d.ts +12 -1
- package/dist/ui/combobox/shared.d.ts.map +1 -1
- package/dist/ui/combobox/shared.js +32 -19
- package/dist/ui/combobox/single.d.ts +4 -3
- package/dist/ui/combobox/single.d.ts.map +1 -1
- package/dist/ui/combobox/single.js +4 -4
- package/dist/ui/dialog/index.d.ts +11 -3
- package/dist/ui/dialog/index.d.ts.map +1 -1
- package/dist/ui/dialog/index.js +15 -7
- package/dist/ui/dialog/public.d.ts +1 -1
- package/dist/ui/dialog/public.d.ts.map +1 -1
- package/dist/ui/dialog/public.js +1 -1
- package/dist/ui/disclosure/index.d.ts +8 -3
- package/dist/ui/disclosure/index.d.ts.map +1 -1
- package/dist/ui/disclosure/index.js +12 -7
- package/dist/ui/disclosure/public.d.ts +2 -2
- package/dist/ui/disclosure/public.d.ts.map +1 -1
- package/dist/ui/disclosure/public.js +1 -1
- package/dist/ui/listbox/multi.d.ts +4 -3
- package/dist/ui/listbox/multi.d.ts.map +1 -1
- package/dist/ui/listbox/multi.js +4 -4
- package/dist/ui/listbox/public.d.ts +3 -3
- package/dist/ui/listbox/public.d.ts.map +1 -1
- package/dist/ui/listbox/public.js +2 -2
- package/dist/ui/listbox/shared.d.ts +14 -1
- package/dist/ui/listbox/shared.d.ts.map +1 -1
- package/dist/ui/listbox/shared.js +31 -16
- package/dist/ui/listbox/single.d.ts +10 -5
- package/dist/ui/listbox/single.d.ts.map +1 -1
- package/dist/ui/listbox/single.js +8 -5
- package/dist/ui/menu/index.d.ts +19 -3
- package/dist/ui/menu/index.d.ts.map +1 -1
- package/dist/ui/menu/index.js +39 -21
- package/dist/ui/menu/public.d.ts +2 -2
- package/dist/ui/menu/public.d.ts.map +1 -1
- package/dist/ui/menu/public.js +1 -1
- package/dist/ui/popover/index.d.ts +20 -3
- package/dist/ui/popover/index.d.ts.map +1 -1
- package/dist/ui/popover/index.js +31 -14
- package/dist/ui/popover/public.d.ts +2 -2
- package/dist/ui/popover/public.d.ts.map +1 -1
- package/dist/ui/popover/public.js +1 -1
- package/dist/ui/radioGroup/index.d.ts +10 -5
- package/dist/ui/radioGroup/index.d.ts.map +1 -1
- package/dist/ui/radioGroup/index.js +18 -20
- package/dist/ui/radioGroup/public.d.ts +2 -2
- package/dist/ui/radioGroup/public.d.ts.map +1 -1
- package/dist/ui/radioGroup/public.js +1 -1
- package/dist/ui/switch/index.d.ts +3 -3
- package/dist/ui/switch/index.d.ts.map +1 -1
- package/dist/ui/switch/index.js +11 -8
- package/dist/ui/tabs/index.d.ts +8 -3
- package/dist/ui/tabs/index.d.ts.map +1 -1
- package/dist/ui/tabs/index.js +15 -8
- package/dist/ui/tabs/public.d.ts +2 -2
- package/dist/ui/tabs/public.d.ts.map +1 -1
- package/dist/ui/tabs/public.js +1 -1
- package/package.json +1 -1
|
@@ -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 `
|
|
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 `
|
|
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
|
-
|
|
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 `
|
|
83
|
-
export declare const lazy: <Message, RadioOption extends string>(staticConfig: Omit<ViewConfig<Message, RadioOption>, "model" | "
|
|
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":"AAAA,OAAO,EAML,MAAM,IAAI,CAAC,EAGZ,MAAM,QAAQ,CAAA;AAEf,OAAO,KAAK,OAAO,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,IAAI,EAAoB,MAAM,YAAY,CAAA;AAQxE,+FAA+F;AAC/F,eAAO,MAAM,WAAW,uCAAsC,CAAA;AAC9D,MAAM,MAAM,WAAW,GAAG,OAAO,WAAW,CAAC,IAAI,CAAA;AAEjD,iGAAiG;AACjG,eAAO,MAAM,KAAK;;;;EAIhB,CAAA;AAEF,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAA;AAIrC,6EAA6E;AAC7E,eAAO,MAAM,cAAc;;;EAGzB,CAAA;AACF,oDAAoD;AACpD,eAAO,MAAM,oBAAoB,yEAA4B,CAAA;AAE7D,mEAAmE;AACnE,eAAO,MAAM,OAAO,EAAE,CAAC,CAAC,KAAK,CAC3B;IAAC,OAAO,cAAc;IAAE,OAAO,oBAAoB;CAAC,CACL,CAAA;AAEjD,MAAM,MAAM,cAAc,GAAG,OAAO,cAAc,CAAC,IAAI,CAAA;AACvD,MAAM,MAAM,oBAAoB,GAAG,OAAO,oBAAoB,CAAC,IAAI,CAAA;AAEnE,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAA;AAIzC,kEAAkE;AAClE,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,WAAW,CAAC,EAAE,WAAW,CAAA;CAC1B,CAAC,CAAA;AAEF,6GAA6G;AAC7G,eAAO,MAAM,IAAI,GAAI,QAAQ,UAAU,KAAG,KAIxC,CAAA;AAMF,eAAO,MAAM,WAAW;;EAAsD,CAAA;AAE9E,+EAA+E;AAC/E,eAAO,MAAM,MAAM,GACjB,OAAO,KAAK,EACZ,SAAS,OAAO,KACf,SAAS,CAAC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAuBxD,CAAA;AAIH,gGAAgG;AAChG,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;CAC/C,CAAC,CAAA;AAEF;
|
|
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 },
|
|
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 =>
|
|
86
|
-
|
|
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(
|
|
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 `
|
|
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,
|
|
157
|
+
return (model, toParentMessage) => lazyView((currentModel, currentToMessage) => view({
|
|
160
158
|
...staticConfig,
|
|
161
159
|
model: currentModel,
|
|
162
|
-
|
|
163
|
-
}), [model,
|
|
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 {
|
|
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,
|
|
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
|
-
|
|
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 `
|
|
45
|
-
export declare const lazy: <Message>(staticConfig: Omit<ViewConfig<Message>, "model" | "
|
|
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,
|
|
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"}
|
package/dist/ui/switch/index.js
CHANGED
|
@@ -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 },
|
|
33
|
-
const handleKeyUp = (key) => M.value(key).pipe(M.when(' ', () => Option.some(
|
|
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
|
-
: [
|
|
48
|
+
: [
|
|
49
|
+
OnClick(toParentMessage(Toggled())),
|
|
50
|
+
OnKeyUpPreventDefault(handleKeyUp),
|
|
51
|
+
]),
|
|
49
52
|
];
|
|
50
53
|
const labelAttributes = [
|
|
51
54
|
Id(labelId(id)),
|
|
52
|
-
...(isDisabled ? [] : [OnClick(
|
|
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 `
|
|
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,
|
|
72
|
+
return (model, toParentMessage) => lazyView((currentModel, currentToMessage) => view({
|
|
70
73
|
...staticConfig,
|
|
71
74
|
model: currentModel,
|
|
72
|
-
|
|
73
|
-
}), [model,
|
|
75
|
+
toParentMessage: currentToMessage,
|
|
76
|
+
}), [model, toParentMessage]);
|
|
74
77
|
};
|
package/dist/ui/tabs/index.d.ts
CHANGED
|
@@ -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
|
-
|
|
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 `
|
|
84
|
-
export declare const lazy: <Message, Tab extends string>(staticConfig: Omit<ViewConfig<Message, Tab>, "model" | "
|
|
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":"AAAA,OAAO,EAKL,MAAM,IAAI,CAAC,EAGZ,MAAM,QAAQ,CAAA;AAEf,OAAO,KAAK,OAAO,MAAM,eAAe,CAAA;AACxC,OAAO,EACL,KAAK,SAAS,EACd,KAAK,IAAI,EACT,KAAK,OAAO,EAGb,MAAM,YAAY,CAAA;AAMnB,OAAO,EAAE,SAAS,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAI1E,yFAAyF;AACzF,eAAO,MAAM,WAAW,uCAAsC,CAAA;AAC9D,MAAM,MAAM,WAAW,GAAG,OAAO,WAAW,CAAC,IAAI,CAAA;AAEjD,yGAAyG;AACzG,eAAO,MAAM,cAAc,oCAAmC,CAAA;AAC9D,MAAM,MAAM,cAAc,GAAG,OAAO,cAAc,CAAC,IAAI,CAAA;AAEvD,kGAAkG;AAClG,eAAO,MAAM,KAAK;;;;;EAKhB,CAAA;AAEF,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAA;AAIrC,sGAAsG;AACtG,eAAO,MAAM,WAAW;;EAAwC,CAAA;AAChE,wFAAwF;AACxF,eAAO,MAAM,UAAU;;EAAuC,CAAA;AAC9D,iDAAiD;AACjD,eAAO,MAAM,iBAAiB,sEAAyB,CAAA;AAEvD,4DAA4D;AAC5D,eAAO,MAAM,OAAO,EAAE,CAAC,CAAC,KAAK,CAC3B;IAAC,OAAO,WAAW;IAAE,OAAO,UAAU;IAAE,OAAO,iBAAiB;CAAC,CACZ,CAAA;AAEvD,MAAM,MAAM,WAAW,GAAG,OAAO,WAAW,CAAC,IAAI,CAAA;AACjD,MAAM,MAAM,UAAU,GAAG,OAAO,UAAU,CAAC,IAAI,CAAA;AAE/C,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAA;AAIzC,2DAA2D;AAC3D,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,cAAc,CAAC,EAAE,cAAc,CAAA;CAChC,CAAC,CAAA;AAEF,mGAAmG;AACnG,eAAO,MAAM,IAAI,GAAI,QAAQ,UAAU,KAAG,KASzC,CAAA;AAID,eAAO,MAAM,QAAQ;;EAAgD,CAAA;AAErE,wEAAwE;AACxE,eAAO,MAAM,MAAM,GACjB,OAAO,KAAK,EACZ,SAAS,OAAO,KACf,SAAS,CAAC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAyCxD,CAAA;AAIH,sEAAsE;AACtE,MAAM,MAAM,SAAS,CAAC,OAAO,GAAG,OAAO,IAAI,QAAQ,CAAC;IAClD,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,gBAAgB,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA;IACpD,aAAa,EAAE,IAAI,CAAA;IACnB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,eAAe,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA;IACnD,YAAY,EAAE,IAAI,CAAA;CACnB,CAAC,CAAA;AAEF,2DAA2D;AAC3D,MAAM,MAAM,UAAU,CAAC,OAAO,EAAE,GAAG,SAAS,MAAM,IAAI,QAAQ,CAAC;IAC7D,KAAK,EAAE,KAAK,CAAA;IACZ,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/tabs/index.ts"],"names":[],"mappings":"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"}
|
package/dist/ui/tabs/index.js
CHANGED
|
@@ -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 },
|
|
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(
|
|
84
|
-
const handleManualKeyDown = (key) => M.value(key).pipe(M.whenOr(nextKey, previousKey, 'Home', 'End', 'PageUp', 'PageDown', () => Option.some(
|
|
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(
|
|
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 `
|
|
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,
|
|
166
|
+
return (model, toParentMessage) => lazyView((currentModel, currentToMessage) => view({
|
|
160
167
|
...staticConfig,
|
|
161
168
|
model: currentModel,
|
|
162
|
-
|
|
163
|
-
}), [model,
|
|
169
|
+
toParentMessage: currentToMessage,
|
|
170
|
+
}), [model, toParentMessage]);
|
|
164
171
|
};
|
package/dist/ui/tabs/public.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { init, update, view, lazy, Model, Message } from './index';
|
|
2
|
-
export type { Orientation, ActivationMode,
|
|
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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/ui/tabs/public.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/ui/tabs/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,MAAM,EACN,SAAS,EACT,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,OAAO,EACP,WAAW,EACX,UAAU,EACV,iBAAiB,EACjB,QAAQ,GACT,MAAM,SAAS,CAAA;AAEhB,YAAY,EACV,WAAW,EACX,cAAc,EACd,UAAU,EACV,UAAU,EACV,SAAS,GACV,MAAM,SAAS,CAAA"}
|
package/dist/ui/tabs/public.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { init, update, view, lazy, Model, Message } from './index';
|
|
1
|
+
export { init, update, selectTab, view, lazy, Model, Message, TabSelected, TabFocused, CompletedFocusTab, FocusTab, } from './index';
|