foldkit 0.101.0 → 0.102.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/canvas/view.d.ts +1 -1
- package/dist/canvas/view.d.ts.map +1 -1
- package/dist/canvas/view.js +5 -5
- package/dist/command/index.d.ts +71 -0
- package/dist/command/index.d.ts.map +1 -1
- package/dist/command/index.js +34 -1
- package/dist/command/public.d.ts +1 -1
- package/dist/command/public.d.ts.map +1 -1
- package/dist/command/public.js +1 -1
- package/dist/devTools/overlay.d.ts.map +1 -1
- package/dist/devTools/overlay.js +137 -110
- package/dist/dom/dom.d.ts +8 -11
- package/dist/dom/dom.d.ts.map +1 -1
- package/dist/dom/dom.js +8 -11
- package/dist/dom/elementMovement.d.ts +1 -3
- package/dist/dom/elementMovement.d.ts.map +1 -1
- package/dist/dom/elementMovement.js +1 -3
- package/dist/dom/inert.d.ts +2 -4
- package/dist/dom/inert.d.ts.map +1 -1
- package/dist/dom/inert.js +2 -4
- package/dist/dom/scrollLock.d.ts +2 -2
- package/dist/dom/scrollLock.js +2 -2
- package/dist/dom/waitForAnimation.d.ts +1 -1
- package/dist/dom/waitForAnimation.js +1 -1
- package/dist/html/boundary.d.ts +98 -0
- package/dist/html/boundary.d.ts.map +1 -0
- package/dist/html/boundary.js +176 -0
- package/dist/html/childAttribute.d.ts +44 -0
- package/dist/html/childAttribute.d.ts.map +1 -0
- package/dist/html/childAttribute.js +34 -0
- package/dist/html/index.d.ts +70 -23
- package/dist/html/index.d.ts.map +1 -1
- package/dist/html/index.js +639 -575
- package/dist/html/lazy.d.ts +12 -7
- package/dist/html/lazy.d.ts.map +1 -1
- package/dist/html/lazy.js +30 -11
- package/dist/html/public.d.ts +2 -2
- package/dist/html/public.d.ts.map +1 -1
- package/dist/html/public.js +1 -1
- package/dist/html/runtimeSingleton.d.ts +72 -0
- package/dist/html/runtimeSingleton.d.ts.map +1 -0
- package/dist/html/runtimeSingleton.js +112 -0
- package/dist/html/submodel.d.ts +98 -0
- package/dist/html/submodel.d.ts.map +1 -0
- package/dist/html/submodel.js +190 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/render/render.d.ts +1 -1
- package/dist/render/render.js +1 -1
- package/dist/runtime/messagePriority.d.ts +5 -1
- package/dist/runtime/messagePriority.d.ts.map +1 -1
- package/dist/runtime/messagePriority.js +25 -4
- package/dist/runtime/runtime.d.ts +1 -1
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +115 -61
- package/dist/submodel/public.d.ts +4 -0
- package/dist/submodel/public.d.ts.map +1 -0
- package/dist/submodel/public.js +1 -0
- package/dist/submodel/submodel.d.ts +32 -0
- package/dist/submodel/submodel.d.ts.map +1 -0
- package/dist/submodel/submodel.js +1 -0
- package/dist/test/apps/disabledButton.d.ts +4 -5
- package/dist/test/apps/disabledButton.d.ts.map +1 -1
- package/dist/test/apps/disabledButton.js +16 -16
- package/dist/test/scene.d.ts +8 -8
- package/dist/test/scene.d.ts.map +1 -1
- package/dist/test/scene.js +25 -13
- package/dist/test/story.d.ts +15 -8
- package/dist/test/story.d.ts.map +1 -1
- package/dist/test/story.js +21 -9
- package/dist/ui/animation/index.d.ts +30 -14
- package/dist/ui/animation/index.d.ts.map +1 -1
- package/dist/ui/animation/index.js +9 -19
- package/dist/ui/animation/public.d.ts +2 -2
- package/dist/ui/animation/public.d.ts.map +1 -1
- package/dist/ui/animation/public.js +1 -1
- package/dist/ui/calendar/index.d.ts +199 -84
- package/dist/ui/calendar/index.d.ts.map +1 -1
- package/dist/ui/calendar/index.js +129 -140
- package/dist/ui/calendar/public.d.ts +2 -2
- package/dist/ui/calendar/public.d.ts.map +1 -1
- package/dist/ui/calendar/public.js +1 -1
- package/dist/ui/checkbox/index.d.ts +93 -21
- package/dist/ui/checkbox/index.d.ts.map +1 -1
- package/dist/ui/checkbox/index.js +62 -33
- package/dist/ui/checkbox/public.d.ts +2 -2
- package/dist/ui/checkbox/public.d.ts.map +1 -1
- package/dist/ui/checkbox/public.js +1 -1
- package/dist/ui/combobox/multi.d.ts +35 -91
- package/dist/ui/combobox/multi.d.ts.map +1 -1
- package/dist/ui/combobox/multi.js +34 -17
- package/dist/ui/combobox/multiPublic.d.ts +2 -2
- package/dist/ui/combobox/multiPublic.d.ts.map +1 -1
- package/dist/ui/combobox/multiPublic.js +1 -1
- package/dist/ui/combobox/public.d.ts +3 -3
- package/dist/ui/combobox/public.d.ts.map +1 -1
- package/dist/ui/combobox/public.js +2 -2
- package/dist/ui/combobox/shared.d.ts +56 -31
- package/dist/ui/combobox/shared.d.ts.map +1 -1
- package/dist/ui/combobox/shared.js +333 -322
- package/dist/ui/combobox/single.d.ts +46 -93
- package/dist/ui/combobox/single.d.ts.map +1 -1
- package/dist/ui/combobox/single.js +44 -17
- package/dist/ui/datePicker/index.d.ts +256 -48
- package/dist/ui/datePicker/index.d.ts.map +1 -1
- package/dist/ui/datePicker/index.js +149 -104
- package/dist/ui/datePicker/public.d.ts +2 -2
- package/dist/ui/datePicker/public.d.ts.map +1 -1
- package/dist/ui/datePicker/public.js +1 -1
- package/dist/ui/dialog/index.d.ts +95 -39
- package/dist/ui/dialog/index.d.ts.map +1 -1
- package/dist/ui/dialog/index.js +71 -62
- package/dist/ui/dialog/public.d.ts +2 -2
- 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 +71 -31
- package/dist/ui/disclosure/index.d.ts.map +1 -1
- package/dist/ui/disclosure/index.js +57 -62
- 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/dragAndDrop/index.d.ts +6 -6
- package/dist/ui/dragAndDrop/index.d.ts.map +1 -1
- package/dist/ui/dragAndDrop/index.js +7 -7
- package/dist/ui/dragAndDrop/public.d.ts +1 -1
- package/dist/ui/dragAndDrop/public.d.ts.map +1 -1
- package/dist/ui/dragAndDrop/public.js +1 -1
- package/dist/ui/fileDrop/index.d.ts +42 -46
- package/dist/ui/fileDrop/index.d.ts.map +1 -1
- package/dist/ui/fileDrop/index.js +30 -46
- package/dist/ui/fileDrop/public.d.ts +2 -2
- package/dist/ui/fileDrop/public.d.ts.map +1 -1
- package/dist/ui/fileDrop/public.js +1 -1
- package/dist/ui/listbox/multi.d.ts +39 -84
- package/dist/ui/listbox/multi.d.ts.map +1 -1
- package/dist/ui/listbox/multi.js +38 -20
- package/dist/ui/listbox/multiPublic.d.ts +2 -2
- package/dist/ui/listbox/multiPublic.d.ts.map +1 -1
- package/dist/ui/listbox/multiPublic.js +1 -1
- 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 +71 -30
- package/dist/ui/listbox/shared.d.ts.map +1 -1
- package/dist/ui/listbox/shared.js +319 -296
- package/dist/ui/listbox/single.d.ts +57 -85
- package/dist/ui/listbox/single.d.ts.map +1 -1
- package/dist/ui/listbox/single.js +48 -24
- package/dist/ui/menu/index.d.ts +80 -36
- package/dist/ui/menu/index.d.ts.map +1 -1
- package/dist/ui/menu/index.js +117 -86
- 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 +117 -44
- package/dist/ui/popover/index.d.ts.map +1 -1
- package/dist/ui/popover/index.js +88 -101
- 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 +122 -45
- package/dist/ui/radioGroup/index.d.ts.map +1 -1
- package/dist/ui/radioGroup/index.js +111 -72
- 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/slider/index.d.ts +72 -34
- package/dist/ui/slider/index.d.ts.map +1 -1
- package/dist/ui/slider/index.js +40 -49
- package/dist/ui/slider/public.d.ts +2 -2
- package/dist/ui/slider/public.d.ts.map +1 -1
- package/dist/ui/slider/public.js +1 -1
- package/dist/ui/switch/index.d.ts +74 -21
- package/dist/ui/switch/index.d.ts.map +1 -1
- package/dist/ui/switch/index.js +62 -33
- package/dist/ui/switch/public.d.ts +2 -2
- package/dist/ui/switch/public.d.ts.map +1 -1
- package/dist/ui/switch/public.js +1 -1
- package/dist/ui/tabs/index.d.ts +107 -45
- package/dist/ui/tabs/index.d.ts.map +1 -1
- package/dist/ui/tabs/index.js +99 -81
- 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/dist/ui/toast/index.d.ts +93 -109
- package/dist/ui/toast/index.d.ts.map +1 -1
- package/dist/ui/toast/index.js +16 -29
- package/dist/ui/toast/schema.d.ts +15 -4
- package/dist/ui/toast/schema.d.ts.map +1 -1
- package/dist/ui/toast/schema.js +11 -4
- package/dist/ui/toast/update.d.ts +36 -18
- package/dist/ui/toast/update.d.ts.map +1 -1
- package/dist/ui/toast/update.js +33 -14
- package/dist/ui/tooltip/index.d.ts +94 -42
- package/dist/ui/tooltip/index.d.ts.map +1 -1
- package/dist/ui/tooltip/index.js +64 -73
- package/dist/ui/tooltip/public.d.ts +2 -2
- package/dist/ui/tooltip/public.d.ts.map +1 -1
- package/dist/ui/tooltip/public.js +1 -1
- package/dist/ui/virtualList/index.d.ts +18 -41
- package/dist/ui/virtualList/index.d.ts.map +1 -1
- package/dist/ui/virtualList/index.js +17 -37
- package/dist/ui/virtualList/public.d.ts +2 -2
- package/dist/ui/virtualList/public.d.ts.map +1 -1
- package/dist/ui/virtualList/public.js +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/slider/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/slider/index.ts"],"names":[],"mappings":"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"}
|
package/dist/ui/slider/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Effect, Equal, Match as M, Option, Schema as S, Stream, String as String_, pipe, } from 'effect';
|
|
2
|
-
import {
|
|
1
|
+
import { Effect, Equal, Function, Match as M, Option, Schema as S, Stream, String as String_, pipe, } from 'effect';
|
|
2
|
+
import { childAttributes, defineView, html, } from '../../html/index.js';
|
|
3
3
|
import { m } from '../../message/index.js';
|
|
4
4
|
import * as Subscription from '../../runtime/subscription.js';
|
|
5
5
|
import { ts } from '../../schema/index.js';
|
|
@@ -53,11 +53,12 @@ export const Message = S.Union([
|
|
|
53
53
|
PressedKeyboardNavigation,
|
|
54
54
|
]);
|
|
55
55
|
// OUT MESSAGE
|
|
56
|
-
/** Emitted when the slider value changes. The parent
|
|
57
|
-
*
|
|
58
|
-
|
|
56
|
+
/** Emitted when the slider value changes. The parent can handle this to
|
|
57
|
+
* update its own state or dispatch its own Commands, for example to run
|
|
58
|
+
* validation or trigger a downstream Command. */
|
|
59
|
+
export const ChangedValue = m('ChangedValue', { value: S.Number });
|
|
59
60
|
/** Union of all out-messages the slider component can emit to its parent. */
|
|
60
|
-
export const OutMessage = ChangedValue;
|
|
61
|
+
export const OutMessage = S.Union([ChangedValue]);
|
|
61
62
|
/** Creates an initial slider model from a config. The initial value is
|
|
62
63
|
* snapped to the step and clamped into range. */
|
|
63
64
|
export const init = (config) => ({
|
|
@@ -129,13 +130,13 @@ export const update = (model, message) => M.value(message).pipe(withUpdateReturn
|
|
|
129
130
|
// off-center on a non-zero-width thumb.
|
|
130
131
|
PressedPointer: ({ value }) => M.value(model.dragState).pipe(withUpdateReturn, M.tag('Dragging', () => [model, [], Option.none()]), M.orElse(() => {
|
|
131
132
|
const snapped = snapAndClamp(value, model.min, model.max, model.step);
|
|
132
|
-
const [modelWithValue, commands,
|
|
133
|
+
const [modelWithValue, commands, maybeOutMessage] = withValue(model, snapped, []);
|
|
133
134
|
return [
|
|
134
135
|
evo(modelWithValue, {
|
|
135
136
|
dragState: () => Dragging({ originValue: model.value }),
|
|
136
137
|
}),
|
|
137
138
|
commands,
|
|
138
|
-
|
|
139
|
+
maybeOutMessage,
|
|
139
140
|
];
|
|
140
141
|
})),
|
|
141
142
|
MovedDragPointer: ({ value }) => M.value(model.dragState).pipe(withUpdateReturn, M.tag('Dragging', () => withValue(model, snapAndClamp(value, model.min, model.max, model.step), [])), M.orElse(() => [model, [], Option.none()])),
|
|
@@ -152,23 +153,23 @@ export const update = (model, message) => M.value(message).pipe(withUpdateReturn
|
|
|
152
153
|
}), M.orElse(() => [model, [], Option.none()])),
|
|
153
154
|
PressedKeyboardNavigation: ({ direction }) => withValue(model, nextValueForDirection(model, direction), []),
|
|
154
155
|
}));
|
|
155
|
-
/**
|
|
156
|
-
* new range. Use this when min/max derive from
|
|
157
|
-
* bounded buffer whose first/last index shifts over
|
|
158
|
-
* this runs even while the user is Dragging: a
|
|
159
|
-
* cannot leave the value out of bounds. */
|
|
160
|
-
export const
|
|
156
|
+
/** Reflects an externally-driven range onto the slider. Snaps and clamps the
|
|
157
|
+
* current value into the new range. Use this when min/max derive from
|
|
158
|
+
* external state (e.g. a bounded buffer whose first/last index shifts over
|
|
159
|
+
* time). Unlike `reflectValue`, this runs even while the user is Dragging: a
|
|
160
|
+
* structural range change cannot leave the value out of bounds. */
|
|
161
|
+
export const reflectRange = Function.dual(2, (model, range) => evo(model, {
|
|
161
162
|
min: () => range.min,
|
|
162
163
|
max: () => range.max,
|
|
163
164
|
value: current => snapAndClamp(current, range.min, range.max, model.step),
|
|
164
|
-
});
|
|
165
|
-
/**
|
|
166
|
-
*
|
|
167
|
-
* Does not emit `ChangedValue`; use when the value is being driven by
|
|
165
|
+
}));
|
|
166
|
+
/** Reflects an externally-driven value onto the slider, snapped and clamped
|
|
167
|
+
* into range; a no-op while the user is dragging, since drag state owns the
|
|
168
|
+
* value. Does not emit `ChangedValue`; use when the value is being driven by
|
|
168
169
|
* external state rather than user input. */
|
|
169
|
-
export const
|
|
170
|
+
export const reflectValue = Function.dual(2, (model, value) => M.value(model.dragState).pipe(M.withReturnType(), M.tag('Dragging', () => model), M.orElse(() => evo(model, {
|
|
170
171
|
value: () => snapAndClamp(value, model.min, model.max, model.step),
|
|
171
|
-
})));
|
|
172
|
+
}))));
|
|
172
173
|
// SUBSCRIPTION
|
|
173
174
|
const DragActivity = S.Literals(['Idle', 'Active']);
|
|
174
175
|
const dragActivityFromModel = (model) => M.value(model.dragState).pipe(M.withReturnType(), M.tag('Dragging', () => 'Active'), M.orElse(() => 'Idle'));
|
|
@@ -237,21 +238,21 @@ const keyToDirection = (key) => M.value(key).pipe(M.withReturnType(), M.whenOr('
|
|
|
237
238
|
const percentString = (fraction) => `${Math.round(fraction * 10000) / 100}%`;
|
|
238
239
|
/** Renders an accessible slider by building ARIA attribute groups and
|
|
239
240
|
* delegating layout to the consumer's `toView` callback. Follows the
|
|
240
|
-
* WAI-ARIA slider pattern
|
|
241
|
+
* WAI-ARIA slider pattern: role="slider" on the thumb, aria-valuemin /
|
|
241
242
|
* aria-valuemax / aria-valuenow, keyboard navigation by step / page / home /
|
|
242
243
|
* end. Pointer drag is handled by the component's drag subscriptions. */
|
|
243
|
-
export const view = (
|
|
244
|
+
export const view = defineView((model, viewInputs) => {
|
|
244
245
|
const h = html();
|
|
245
|
-
const {
|
|
246
|
+
const { formatValue, isDisabled = false, name, getTrackRoot = () => document, } = viewInputs;
|
|
246
247
|
const { id, value, min, max } = model;
|
|
247
248
|
const isDragging = model.dragState._tag === 'Dragging';
|
|
248
249
|
const fraction = fractionOfValue(model);
|
|
249
|
-
const handleKeyDown = (key) => Option.map(keyToDirection(key), direction =>
|
|
250
|
-
const pointerAtClientX = (clientX) => Option.map(trackElement(id, getTrackRoot()), element =>
|
|
250
|
+
const handleKeyDown = (key) => Option.map(keyToDirection(key), direction => PressedKeyboardNavigation({ direction }));
|
|
251
|
+
const pointerAtClientX = (clientX) => Option.map(trackElement(id, getTrackRoot()), element => PressedPointer({
|
|
251
252
|
value: valueFromClientX(clientX, element, min, max),
|
|
252
|
-
}))
|
|
253
|
+
}));
|
|
253
254
|
const trackPointerHandler = (_pointerType, button, _screenX, _screenY, _timeStamp, clientX) => pipe(button, Option.liftPredicate(Equal.equals(LEFT_MOUSE_BUTTON)), Option.flatMap(() => pointerAtClientX(clientX)));
|
|
254
|
-
const thumbPointerHandler = (_pointerType, button) => pipe(button, Option.liftPredicate(Equal.equals(LEFT_MOUSE_BUTTON)), Option.map(() =>
|
|
255
|
+
const thumbPointerHandler = (_pointerType, button) => pipe(button, Option.liftPredicate(Equal.equals(LEFT_MOUSE_BUTTON)), Option.map(() => PressedThumb()));
|
|
255
256
|
const stateAttributes = [
|
|
256
257
|
...(isDragging ? [h.DataAttribute('dragging', '')] : []),
|
|
257
258
|
...(isDisabled ? [h.DataAttribute('disabled', '')] : []),
|
|
@@ -282,11 +283,11 @@ export const view = (config) => {
|
|
|
282
283
|
...stateAttributes,
|
|
283
284
|
];
|
|
284
285
|
const resolveThumbLabel = () => {
|
|
285
|
-
if (
|
|
286
|
-
return [h.AriaLabel(
|
|
286
|
+
if (viewInputs.ariaLabel !== undefined) {
|
|
287
|
+
return [h.AriaLabel(viewInputs.ariaLabel)];
|
|
287
288
|
}
|
|
288
|
-
else if (
|
|
289
|
-
return [h.AriaLabelledBy(
|
|
289
|
+
else if (viewInputs.ariaLabelledBy !== undefined) {
|
|
290
|
+
return [h.AriaLabelledBy(viewInputs.ariaLabelledBy)];
|
|
290
291
|
}
|
|
291
292
|
else {
|
|
292
293
|
return [h.AriaLabelledBy(labelId(id))];
|
|
@@ -324,22 +325,12 @@ export const view = (config) => {
|
|
|
324
325
|
const hiddenInputAttributes = name !== undefined
|
|
325
326
|
? [h.Type('hidden'), h.Name(name), h.Value(value.toString())]
|
|
326
327
|
: [];
|
|
327
|
-
return
|
|
328
|
-
root: rootAttributes,
|
|
329
|
-
track: trackAttributes,
|
|
330
|
-
filledTrack: filledTrackAttributes,
|
|
331
|
-
thumb: thumbAttributes,
|
|
332
|
-
label: labelAttributes,
|
|
333
|
-
hiddenInput: hiddenInputAttributes,
|
|
328
|
+
return viewInputs.toView({
|
|
329
|
+
root: childAttributes(rootAttributes),
|
|
330
|
+
track: childAttributes(trackAttributes),
|
|
331
|
+
filledTrack: childAttributes(filledTrackAttributes),
|
|
332
|
+
thumb: childAttributes(thumbAttributes),
|
|
333
|
+
label: childAttributes(labelAttributes),
|
|
334
|
+
hiddenInput: childAttributes(hiddenInputAttributes),
|
|
334
335
|
});
|
|
335
|
-
};
|
|
336
|
-
/** Creates a memoized slider view. Static config is captured in a closure;
|
|
337
|
-
* only `model` and `toParentMessage` are compared per render via `createLazy`. */
|
|
338
|
-
export const lazy = (staticConfig) => {
|
|
339
|
-
const lazyView = createLazy();
|
|
340
|
-
return (model, toParentMessage) => lazyView((currentModel, currentToParentMessage) => view({
|
|
341
|
-
...staticConfig,
|
|
342
|
-
model: currentModel,
|
|
343
|
-
toParentMessage: currentToParentMessage,
|
|
344
|
-
}), [model, toParentMessage]);
|
|
345
|
-
};
|
|
336
|
+
});
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { init, update,
|
|
2
|
-
export type { InitConfig,
|
|
1
|
+
export { init, update, reflectRange, reflectValue, view, subscriptions, subscriptionsForRoot, fractionOfValue, Model, Message, OutMessage, } from './index.js';
|
|
2
|
+
export type { InitConfig, ViewInputs, SliderAttributes, PressedThumb, PressedPointer, MovedDragPointer, ReleasedDragPointer, CancelledDrag, PressedKeyboardNavigation, } from './index.js';
|
|
3
3
|
//# sourceMappingURL=public.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/ui/slider/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,MAAM,EACN,
|
|
1
|
+
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/ui/slider/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,MAAM,EACN,YAAY,EACZ,YAAY,EACZ,IAAI,EACJ,aAAa,EACb,oBAAoB,EACpB,eAAe,EACf,KAAK,EACL,OAAO,EACP,UAAU,GACX,MAAM,YAAY,CAAA;AAEnB,YAAY,EACV,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,aAAa,EACb,yBAAyB,GAC1B,MAAM,YAAY,CAAA"}
|
package/dist/ui/slider/public.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { init, update,
|
|
1
|
+
export { init, update, reflectRange, reflectValue, view, subscriptions, subscriptionsForRoot, fractionOfValue, Model, Message, OutMessage, } from './index.js';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { Schema as S } from 'effect';
|
|
1
|
+
import { Option, Schema as S } from 'effect';
|
|
2
2
|
import type { Command } from '../../command/index.js';
|
|
3
|
-
import { type
|
|
3
|
+
import { type ChildAttribute, type Html } from '../../html/index.js';
|
|
4
|
+
import type { Reflect } from '../../submodel/submodel.js';
|
|
4
5
|
/** Schema for the switch component's state, tracking the toggle's checked status. */
|
|
5
6
|
export declare const Model: S.Struct<{
|
|
6
7
|
readonly id: S.String;
|
|
@@ -9,10 +10,35 @@ export declare const Model: S.Struct<{
|
|
|
9
10
|
export type Model = typeof Model.Type;
|
|
10
11
|
/** Sent when the user toggles the switch via click or Space key. */
|
|
11
12
|
export declare const Toggled: import("../../schema/index.js").CallableTaggedStruct<"Toggled", {}>;
|
|
13
|
+
/** Sent to set the checked state to a specific value. Use this for
|
|
14
|
+
* programmatic state assignment (e.g. a "select all" handler that forces
|
|
15
|
+
* all child switches to the same state) where `Toggled`'s flip semantics
|
|
16
|
+
* would not reliably reach the desired state. */
|
|
17
|
+
export declare const SetChecked: import("../../schema/index.js").CallableTaggedStruct<"SetChecked", {
|
|
18
|
+
isChecked: S.Boolean;
|
|
19
|
+
}>;
|
|
12
20
|
/** Schema for all messages the switch component can produce. */
|
|
13
|
-
export declare const Message: import("../../schema/index.js").CallableTaggedStruct<"Toggled", {}
|
|
21
|
+
export declare const Message: S.Union<readonly [import("../../schema/index.js").CallableTaggedStruct<"Toggled", {}>, import("../../schema/index.js").CallableTaggedStruct<"SetChecked", {
|
|
22
|
+
isChecked: S.Boolean;
|
|
23
|
+
}>]>;
|
|
14
24
|
export type Toggled = typeof Toggled.Type;
|
|
25
|
+
export type SetChecked = typeof SetChecked.Type;
|
|
15
26
|
export type Message = typeof Message.Type;
|
|
27
|
+
/** Sent to the parent each time the switch toggles. Carries the new
|
|
28
|
+
* checked state. Consumers pattern-match this in their `GotSwitchMessage`
|
|
29
|
+
* handler to lift the toggle into a domain Message (e.g., persisting the
|
|
30
|
+
* setting, dispatching a sync command). */
|
|
31
|
+
export declare const ToggledChecked: import("../../schema/index.js").CallableTaggedStruct<"ToggledChecked", {
|
|
32
|
+
isChecked: S.Boolean;
|
|
33
|
+
}>;
|
|
34
|
+
/** Union of out-messages the switch component can produce. Surfaced as
|
|
35
|
+
* the third element of `update`'s return tuple and pattern-matched by
|
|
36
|
+
* the parent. */
|
|
37
|
+
export declare const OutMessage: S.Union<readonly [import("../../schema/index.js").CallableTaggedStruct<"ToggledChecked", {
|
|
38
|
+
isChecked: S.Boolean;
|
|
39
|
+
}>]>;
|
|
40
|
+
export type ToggledChecked = typeof ToggledChecked.Type;
|
|
41
|
+
export type OutMessage = typeof OutMessage.Type;
|
|
16
42
|
/** Configuration for creating a switch model with `init`. */
|
|
17
43
|
export type InitConfig = Readonly<{
|
|
18
44
|
id: string;
|
|
@@ -20,27 +46,54 @@ export type InitConfig = Readonly<{
|
|
|
20
46
|
}>;
|
|
21
47
|
/** Creates an initial switch model from a config. Defaults to unchecked. */
|
|
22
48
|
export declare const init: (config: InitConfig) => Model;
|
|
23
|
-
/** Processes a switch message and returns the next model
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
49
|
+
/** Processes a switch message and returns the next model, commands, and
|
|
50
|
+
* a `ToggledChecked` OutMessage carrying the new checked state. */
|
|
51
|
+
export declare const update: (model: Model, message: Message) => readonly [Model, ReadonlyArray<Command<Message>>, Option.Option<OutMessage>];
|
|
52
|
+
/** Programmatically sets the checked state. Emits a `ToggledChecked`
|
|
53
|
+
* OutMessage just like a user-initiated toggle. Use this in domain-event
|
|
54
|
+
* handlers where you need to force a specific state. */
|
|
55
|
+
export declare const setChecked: (model: Model, isChecked: boolean) => readonly [Model, ReadonlyArray<Command<Message>>, Option.Option<OutMessage>];
|
|
56
|
+
/** Reflects an externally-sourced checked state onto the model without
|
|
57
|
+
* emitting an OutMessage. Use this to mirror external truth (saved
|
|
58
|
+
* settings, a server value) onto the switch without triggering the
|
|
59
|
+
* downstream reaction a user toggle would cause. Contrast with
|
|
60
|
+
* `setChecked`, which emits `ToggledChecked` so the parent reacts to a
|
|
61
|
+
* programmatic assignment the same way it reacts to a user toggle. Returns
|
|
62
|
+
* the model directly because it produces no commands and no OutMessage. */
|
|
63
|
+
export declare const reflectChecked: Reflect<Model, boolean>;
|
|
64
|
+
/** Attribute groups the switch component provides to the consumer's
|
|
65
|
+
* `toView` callback. Each group is a `ReadonlyArray<ChildAttribute>`
|
|
66
|
+
* whose event handlers dispatch through the Switch's boundary at
|
|
67
|
+
* event-fire time. See {@link Checkbox.CheckboxAttributes} for the full
|
|
68
|
+
* routing model. */
|
|
69
|
+
export type SwitchAttributes = Readonly<{
|
|
70
|
+
button: ReadonlyArray<ChildAttribute>;
|
|
71
|
+
label: ReadonlyArray<ChildAttribute>;
|
|
72
|
+
description: ReadonlyArray<ChildAttribute>;
|
|
73
|
+
hiddenInput: ReadonlyArray<ChildAttribute>;
|
|
31
74
|
}>;
|
|
32
|
-
/**
|
|
33
|
-
export type
|
|
34
|
-
|
|
35
|
-
toParentMessage: (message: Toggled) => ParentMessage;
|
|
36
|
-
toView: (attributes: SwitchAttributes<ParentMessage>) => Html;
|
|
75
|
+
/** Per-render view inputs passed to `view` via `h.submodel`'s `viewInputs` field. */
|
|
76
|
+
export type ViewInputs = Readonly<{
|
|
77
|
+
toView: (attributes: SwitchAttributes) => Html;
|
|
37
78
|
isDisabled?: boolean;
|
|
38
79
|
name?: string;
|
|
39
80
|
value?: string;
|
|
40
81
|
}>;
|
|
41
|
-
/** Renders an accessible switch toggle by building ARIA attribute groups
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
82
|
+
/** Renders an accessible switch toggle by building ARIA attribute groups
|
|
83
|
+
* and delegating layout to the consumer's `toView` callback. Designed
|
|
84
|
+
* to be embedded via `h.submodel`. */
|
|
85
|
+
export declare const view: import("../../html/submodel.js").SubmodelView<{
|
|
86
|
+
readonly id: string;
|
|
87
|
+
readonly isChecked: boolean;
|
|
88
|
+
}, {
|
|
89
|
+
readonly _tag: "Toggled";
|
|
90
|
+
} | {
|
|
91
|
+
readonly _tag: "SetChecked";
|
|
92
|
+
readonly isChecked: boolean;
|
|
93
|
+
}, Readonly<{
|
|
94
|
+
toView: (attributes: SwitchAttributes) => Html;
|
|
95
|
+
isDisabled?: boolean;
|
|
96
|
+
name?: string;
|
|
97
|
+
value?: string;
|
|
98
|
+
}>>;
|
|
46
99
|
//# 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,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/switch/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,MAAM,EAAE,MAAM,IAAI,CAAC,EAAE,MAAM,QAAQ,CAAA;AAElE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;AACrD,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,IAAI,EAIV,MAAM,qBAAqB,CAAA;AAG5B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAA;AAIzD,qFAAqF;AACrF,eAAO,MAAM,KAAK;;;EAGhB,CAAA;AAEF,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAA;AAIrC,oEAAoE;AACpE,eAAO,MAAM,OAAO,qEAAe,CAAA;AAEnC;;;kDAGkD;AAClD,eAAO,MAAM,UAAU;;EAA4C,CAAA;AAEnE,gEAAgE;AAChE,eAAO,MAAM,OAAO;;IAAiC,CAAA;AAErD,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAA;AAEzC,MAAM,MAAM,UAAU,GAAG,OAAO,UAAU,CAAC,IAAI,CAAA;AAE/C,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAA;AAIzC;;;4CAG4C;AAC5C,eAAO,MAAM,cAAc;;EAAgD,CAAA;AAE3E;;kBAEkB;AAClB,eAAO,MAAM,UAAU;;IAA4B,CAAA;AAEnD,MAAM,MAAM,cAAc,GAAG,OAAO,cAAc,CAAC,IAAI,CAAA;AACvD,MAAM,MAAM,UAAU,GAAG,OAAO,UAAU,CAAC,IAAI,CAAA;AAI/C,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;oEACoE;AACpE,eAAO,MAAM,MAAM,GACjB,OAAO,KAAK,EACZ,SAAS,OAAO,KACf,SAAS,CACV,KAAK,EACL,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,EAC/B,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAyBxB,CAAA;AAEH;;yDAEyD;AACzD,eAAO,MAAM,UAAU,GACrB,OAAO,KAAK,EACZ,WAAW,OAAO,KACjB,SAAS,CACV,KAAK,EACL,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,EAC/B,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CACkB,CAAA;AAE7C;;;;;;4EAM4E;AAC5E,eAAO,MAAM,cAAc,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAIlD,CAAA;AAID;;;;qBAIqB;AACrB,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,MAAM,EAAE,aAAa,CAAC,cAAc,CAAC,CAAA;IACrC,KAAK,EAAE,aAAa,CAAC,cAAc,CAAC,CAAA;IACpC,WAAW,EAAE,aAAa,CAAC,cAAc,CAAC,CAAA;IAC1C,WAAW,EAAE,aAAa,CAAC,cAAc,CAAC,CAAA;CAC3C,CAAC,CAAA;AAEF,qFAAqF;AACrF,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,MAAM,EAAE,CAAC,UAAU,EAAE,gBAAgB,KAAK,IAAI,CAAA;IAC9C,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAC,CAAA;AAKF;;uCAEuC;AACvC,eAAO,MAAM,IAAI;;;;;;;;;YAZP,CAAC,UAAU,EAAE,gBAAgB,KAAK,IAAI;iBACjC,OAAO;WACb,MAAM;YACL,MAAM;GA2Df,CAAA"}
|
package/dist/ui/switch/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Match as M, Option, Schema as S } from 'effect';
|
|
2
|
-
import {
|
|
1
|
+
import { Function, Match as M, Option, Schema as S } from 'effect';
|
|
2
|
+
import { childAttributes, defineView, html, } from '../../html/index.js';
|
|
3
3
|
import { m } from '../../message/index.js';
|
|
4
4
|
import { evo } from '../../struct/index.js';
|
|
5
5
|
// MODEL
|
|
@@ -11,26 +11,68 @@ export const Model = S.Struct({
|
|
|
11
11
|
// MESSAGE
|
|
12
12
|
/** Sent when the user toggles the switch via click or Space key. */
|
|
13
13
|
export const Toggled = m('Toggled');
|
|
14
|
+
/** Sent to set the checked state to a specific value. Use this for
|
|
15
|
+
* programmatic state assignment (e.g. a "select all" handler that forces
|
|
16
|
+
* all child switches to the same state) where `Toggled`'s flip semantics
|
|
17
|
+
* would not reliably reach the desired state. */
|
|
18
|
+
export const SetChecked = m('SetChecked', { isChecked: S.Boolean });
|
|
14
19
|
/** Schema for all messages the switch component can produce. */
|
|
15
|
-
export const Message = Toggled;
|
|
20
|
+
export const Message = S.Union([Toggled, SetChecked]);
|
|
21
|
+
// OUT MESSAGE
|
|
22
|
+
/** Sent to the parent each time the switch toggles. Carries the new
|
|
23
|
+
* checked state. Consumers pattern-match this in their `GotSwitchMessage`
|
|
24
|
+
* handler to lift the toggle into a domain Message (e.g., persisting the
|
|
25
|
+
* setting, dispatching a sync command). */
|
|
26
|
+
export const ToggledChecked = m('ToggledChecked', { isChecked: S.Boolean });
|
|
27
|
+
/** Union of out-messages the switch component can produce. Surfaced as
|
|
28
|
+
* the third element of `update`'s return tuple and pattern-matched by
|
|
29
|
+
* the parent. */
|
|
30
|
+
export const OutMessage = S.Union([ToggledChecked]);
|
|
16
31
|
/** Creates an initial switch model from a config. Defaults to unchecked. */
|
|
17
32
|
export const init = (config) => ({
|
|
18
33
|
id: config.id,
|
|
19
34
|
isChecked: config.isChecked ?? false,
|
|
20
35
|
});
|
|
21
36
|
// UPDATE
|
|
22
|
-
/** Processes a switch message and returns the next model
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
37
|
+
/** Processes a switch message and returns the next model, commands, and
|
|
38
|
+
* a `ToggledChecked` OutMessage carrying the new checked state. */
|
|
39
|
+
export const update = (model, message) => M.value(message).pipe(M.withReturnType(), M.tagsExhaustive({
|
|
40
|
+
Toggled: () => {
|
|
41
|
+
const nextIsChecked = !model.isChecked;
|
|
42
|
+
return [
|
|
43
|
+
evo(model, { isChecked: () => nextIsChecked }),
|
|
44
|
+
[],
|
|
45
|
+
Option.some(ToggledChecked({ isChecked: nextIsChecked })),
|
|
46
|
+
];
|
|
47
|
+
},
|
|
48
|
+
SetChecked: ({ isChecked }) => [
|
|
49
|
+
evo(model, { isChecked: () => isChecked }),
|
|
50
|
+
[],
|
|
51
|
+
Option.some(ToggledChecked({ isChecked })),
|
|
52
|
+
],
|
|
53
|
+
}));
|
|
54
|
+
/** Programmatically sets the checked state. Emits a `ToggledChecked`
|
|
55
|
+
* OutMessage just like a user-initiated toggle. Use this in domain-event
|
|
56
|
+
* handlers where you need to force a specific state. */
|
|
57
|
+
export const setChecked = (model, isChecked) => update(model, SetChecked({ isChecked }));
|
|
58
|
+
/** Reflects an externally-sourced checked state onto the model without
|
|
59
|
+
* emitting an OutMessage. Use this to mirror external truth (saved
|
|
60
|
+
* settings, a server value) onto the switch without triggering the
|
|
61
|
+
* downstream reaction a user toggle would cause. Contrast with
|
|
62
|
+
* `setChecked`, which emits `ToggledChecked` so the parent reacts to a
|
|
63
|
+
* programmatic assignment the same way it reacts to a user toggle. Returns
|
|
64
|
+
* the model directly because it produces no commands and no OutMessage. */
|
|
65
|
+
export const reflectChecked = Function.dual(2, (model, isChecked) => evo(model, { isChecked: () => isChecked }));
|
|
27
66
|
const labelId = (id) => `${id}-label`;
|
|
28
67
|
const descriptionId = (id) => `${id}-description`;
|
|
29
|
-
/** Renders an accessible switch toggle by building ARIA attribute groups
|
|
30
|
-
|
|
68
|
+
/** Renders an accessible switch toggle by building ARIA attribute groups
|
|
69
|
+
* and delegating layout to the consumer's `toView` callback. Designed
|
|
70
|
+
* to be embedded via `h.submodel`. */
|
|
71
|
+
export const view = defineView((model, viewInputs) => {
|
|
31
72
|
const h = html();
|
|
32
|
-
const {
|
|
33
|
-
const
|
|
73
|
+
const { id, isChecked } = model;
|
|
74
|
+
const { isDisabled = false, name, value: formValue = 'on' } = viewInputs;
|
|
75
|
+
const handleKeyUp = (key) => M.value(key).pipe(M.when(' ', () => Option.some(Toggled())), M.orElse(() => Option.none()));
|
|
34
76
|
const checkedAttributes = isChecked ? [h.DataAttribute('checked', '')] : [];
|
|
35
77
|
const disabledAttributes = isDisabled
|
|
36
78
|
? [h.AriaDisabled(true), h.DataAttribute('disabled', '')]
|
|
@@ -45,33 +87,20 @@ export const view = (config) => {
|
|
|
45
87
|
...disabledAttributes,
|
|
46
88
|
...(isDisabled
|
|
47
89
|
? []
|
|
48
|
-
: [
|
|
49
|
-
h.OnClick(toParentMessage(Toggled())),
|
|
50
|
-
h.OnKeyUpPreventDefault(handleKeyUp),
|
|
51
|
-
]),
|
|
90
|
+
: [h.OnClick(Toggled()), h.OnKeyUpPreventDefault(handleKeyUp)]),
|
|
52
91
|
];
|
|
53
92
|
const labelAttributes = [
|
|
54
93
|
h.Id(labelId(id)),
|
|
55
|
-
...(isDisabled ? [] : [h.OnClick(
|
|
94
|
+
...(isDisabled ? [] : [h.OnClick(Toggled())]),
|
|
56
95
|
];
|
|
57
96
|
const descriptionAttributes = [h.Id(descriptionId(id))];
|
|
58
97
|
const hiddenInputAttributes = name
|
|
59
98
|
? [h.Type('hidden'), h.Name(name), h.Value(isChecked ? formValue : '')]
|
|
60
99
|
: [];
|
|
61
|
-
return
|
|
62
|
-
button: buttonAttributes,
|
|
63
|
-
label: labelAttributes,
|
|
64
|
-
description: descriptionAttributes,
|
|
65
|
-
hiddenInput: hiddenInputAttributes,
|
|
100
|
+
return viewInputs.toView({
|
|
101
|
+
button: childAttributes(buttonAttributes),
|
|
102
|
+
label: childAttributes(labelAttributes),
|
|
103
|
+
description: childAttributes(descriptionAttributes),
|
|
104
|
+
hiddenInput: childAttributes(hiddenInputAttributes),
|
|
66
105
|
});
|
|
67
|
-
};
|
|
68
|
-
/** Creates a memoized switch view. Static config is captured in a closure;
|
|
69
|
-
* only `model` and `toParentMessage` are compared per render via `createLazy`. */
|
|
70
|
-
export const lazy = (staticConfig) => {
|
|
71
|
-
const lazyView = createLazy();
|
|
72
|
-
return (model, toParentMessage) => lazyView((currentModel, currentToParentMessage) => view({
|
|
73
|
-
...staticConfig,
|
|
74
|
-
model: currentModel,
|
|
75
|
-
toParentMessage: currentToParentMessage,
|
|
76
|
-
}), [model, toParentMessage]);
|
|
77
|
-
};
|
|
106
|
+
});
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { init, update,
|
|
2
|
-
export type { Toggled, InitConfig,
|
|
1
|
+
export { init, update, setChecked, reflectChecked, view, Model, Message, OutMessage, SetChecked, ToggledChecked, } from './index.js';
|
|
2
|
+
export type { Toggled, InitConfig, ViewInputs, SwitchAttributes, } from './index.js';
|
|
3
3
|
//# sourceMappingURL=public.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/ui/switch/public.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/ui/switch/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,MAAM,EACN,UAAU,EACV,cAAc,EACd,IAAI,EACJ,KAAK,EACL,OAAO,EACP,UAAU,EACV,UAAU,EACV,cAAc,GACf,MAAM,YAAY,CAAA;AAEnB,YAAY,EACV,OAAO,EACP,UAAU,EACV,UAAU,EACV,gBAAgB,GACjB,MAAM,YAAY,CAAA"}
|
package/dist/ui/switch/public.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { init, update,
|
|
1
|
+
export { init, update, setChecked, reflectChecked, view, Model, Message, OutMessage, SetChecked, ToggledChecked, } from './index.js';
|