@foldkit/ui 0.163.0-canary.c9e82fbb078a → 0.163.0-canary.ca7e5731a9f5

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.
@@ -3,11 +3,11 @@ import { type Update } from 'foldkit';
3
3
  import { type ChildAttribute, type Html } from 'foldkit/html';
4
4
  import { type Reflect } from 'foldkit/submodel';
5
5
  import * as Subscription from 'foldkit/subscription';
6
- /** Schema for the slider component's private interaction state. The current
6
+ /** Schema for the Slider's private interaction state. The current
7
7
  * value is owned by the parent and passed in via `ViewInputs.value`, so it is
8
- * not stored here. `min`/`max`/`step` are configuration the drag subscription
9
- * reads to map pointer positions into values. `dragState` tracks the active
10
- * drag phase and captures the pre-drag value so Escape can restore it. */
8
+ * not stored here. `min`, `max`, and `step` configure how the drag Subscription
9
+ * maps pointer positions into values. `dragState` tracks the active drag phase
10
+ * and captures the pre-drag value so Escape can restore it. */
11
11
  export declare const Model: Schema.Struct<{
12
12
  readonly id: Schema.String;
13
13
  readonly min: Schema.Number;
@@ -21,7 +21,7 @@ export declare const Model: Schema.Struct<{
21
21
  }>;
22
22
  }>;
23
23
  export type Model = typeof Model.Type;
24
- /** Union of all messages the slider component can produce. */
24
+ /** Union of all Messages the Slider can produce. */
25
25
  export declare const Message: import("foldkit/message").MessageUnion<{
26
26
  readonly PressedThumb: {
27
27
  originValue: Schema.Number;
@@ -47,25 +47,25 @@ export type MovedDragPointer = typeof Message.MovedDragPointer.Type;
47
47
  export type ReleasedDragPointer = typeof Message.ReleasedDragPointer.Type;
48
48
  export type CancelledDrag = typeof Message.CancelledDrag.Type;
49
49
  export type PressedKeyboardNavigation = typeof Message.PressedKeyboardNavigation.Type;
50
- /** Union of all out-messages the slider component can emit to its parent. */
50
+ /** Union of all OutMessages the Slider can emit to its parent. */
51
51
  export declare const OutMessage: import("foldkit/message").MessageUnion<{
52
52
  readonly ChangedValue: {
53
53
  value: Schema.Number;
54
54
  };
55
55
  }>;
56
56
  export type OutMessage = typeof OutMessage.Type;
57
- /** Configuration for creating a slider model with `init`. */
57
+ /** Configuration for creating a Slider Model with `init`. */
58
58
  export type InitConfig = Readonly<{
59
59
  id: string;
60
60
  min: number;
61
61
  max: number;
62
62
  step: number;
63
63
  }>;
64
- /** Creates an initial slider model from a config. The value lives in the
64
+ /** Creates an initial Slider Model from a config. The value lives in the
65
65
  * parent Model; initialize it there and snap it with {@link snapAndClamp}. */
66
66
  export declare const init: (config: InitConfig) => Model;
67
67
  /** Snaps a value to the nearest step and clamps it into `[min, max]`. Exported
68
- * so a parent can conform the value it owns to the slider's range, for example
68
+ * so a parent can conform the value it owns to the Slider's range, for example
69
69
  * when seeding the initial value or reacting to an external update. */
70
70
  export declare const snapAndClamp: (value: number, min: number, max: number, step: number) => number;
71
71
  /** Computes the fraction (0–1) of a value between min and max. Returns 0 when
@@ -121,10 +121,13 @@ export declare const reflectRange: Reflect<Model, Readonly<{
121
121
  min: number;
122
122
  max: number;
123
123
  }>>;
124
- /** Builds slider drag subscriptions, looking up the track
125
- * element through the supplied root resolver. Use this when the slider is
126
- * rendered inside a Shadow DOM. The root is read lazily so consumers can
127
- * resolve it at subscription time. */
124
+ /** Maps a pointer position to a Slider value. Vertical tracks place `min` at
125
+ * the bottom and `max` at the top. Edge-aligned tracks measure the rendered
126
+ * thumb and map the pointer across the same inset range it travels through. */
127
+ export declare const valueFromPointer: (clientX: number, clientY: number, track: Element, min: number, max: number) => number;
128
+ /** Builds Slider drag Subscriptions that find the track through the supplied
129
+ * root resolver. Use this when the Slider is rendered inside a Shadow DOM.
130
+ * The resolver runs at subscription time. */
128
131
  export declare const subscriptionsForRoot: (getTrackRoot: () => Document | ShadowRoot) => {
129
132
  readonly dragPointer: Subscription.EntryWithoutKeepAlive<{
130
133
  readonly id: string;
@@ -198,7 +201,7 @@ export declare const subscriptionsForRoot: (getTrackRoot: () => Document | Shado
198
201
  readonly __subscription: never;
199
202
  };
200
203
  };
201
- /** Default drag subscriptions, with the track looked up via `document`. */
204
+ /** Default drag Subscriptions, with the track looked up via `document`. */
202
205
  export declare const subscriptions: {
203
206
  readonly dragPointer: Subscription.EntryWithoutKeepAlive<{
204
207
  readonly id: string;
@@ -272,8 +275,8 @@ export declare const subscriptions: {
272
275
  readonly __subscription: never;
273
276
  };
274
277
  };
275
- /** Attribute groups the slider component provides to the consumer's `toView`
276
- * callback. Each bundle carries the boundary's captured dispatch, so the
278
+ /** Attribute groups the Slider provides to the consumer's `toView`
279
+ * callback. Each group carries the boundary's captured dispatch, so the
277
280
  * consumer can spread it directly into element attributes without manual
278
281
  * Message wrapping. */
279
282
  export type SliderAttributes = Readonly<{
@@ -284,12 +287,32 @@ export type SliderAttributes = Readonly<{
284
287
  label: ReadonlyArray<ChildAttribute>;
285
288
  hiddenInput: ReadonlyArray<ChildAttribute>;
286
289
  }>;
290
+ /** Direction in which the Slider lays out its track and maps pointer input. */
291
+ export declare const Orientation: Schema.Literals<readonly ["Horizontal", "Vertical"]>;
292
+ export type Orientation = typeof Orientation.Type;
293
+ /** Whether the thumb's center or outer edge aligns with the track endpoints. */
294
+ export declare const ThumbAlignment: Schema.Literals<readonly ["Center", "Edge"]>;
295
+ export type ThumbAlignment = typeof ThumbAlignment.Type;
287
296
  /** Per-render view inputs passed to `view` via `h.submodel`'s `viewInputs` field. */
288
297
  export type ViewInputs = Readonly<{
289
298
  /** The current value, read straight from the parent Model. The thumb
290
299
  * position, `aria-valuenow`, and the filled track all derive from it. */
291
300
  value: number;
292
301
  toView: (attributes: SliderAttributes) => Html;
302
+ /** Layout axis for the track, filled track, and thumb. Vertical Sliders
303
+ * place `min` at the bottom and `max` at the top. */
304
+ orientation?: Orientation;
305
+ /** How the thumb aligns within the track. `Center` keeps the thumb's
306
+ * center on the value point and lets it overflow by half its size at the
307
+ * extremes, matching the Slider's previous behavior. `Edge` insets the
308
+ * thumb's travel by `thumbSize` so it stays fully inside the track.
309
+ * Defaults to `Center` so existing Sliders keep their geometry. */
310
+ thumbAlignment?: ThumbAlignment;
311
+ /** CSS length of the thumb along the track axis, used only when
312
+ * `thumbAlignment` is `Edge` to inset the thumb's travel and align the
313
+ * fill with the thumb's center. Set this to the size your `toView`
314
+ * callback styles the thumb with. Defaults to `0.75rem`. */
315
+ thumbSize?: string;
293
316
  ariaLabel?: string;
294
317
  ariaLabelledBy?: string;
295
318
  formatValue?: (value: number) => string;
@@ -309,17 +332,16 @@ export type ViewInputs = Readonly<{
309
332
  * way. */
310
333
  isReadOnly?: boolean;
311
334
  name?: string;
312
- /** Resolves the root that holds the slider track when looking it up by its
313
- * `data-slider-track-id` attribute. Defaults to `document`. Provide a
314
- * ShadowRoot when rendering the slider inside a shadow tree so pointer
315
- * events on the track can map clientX into a value. */
335
+ /** Resolves the DOM root containing the Slider track. Defaults to `document`.
336
+ * Provide a ShadowRoot when rendering the Slider inside a shadow tree so pointer
337
+ * events on the track can map the pointer position into a value. */
316
338
  getTrackRoot?: () => Document | ShadowRoot;
317
339
  }>;
318
340
  /** Renders an accessible slider by building ARIA attribute groups and
319
341
  * delegating layout to the consumer's `toView` callback. Follows the
320
342
  * WAI-ARIA slider pattern: role="slider" on the thumb, aria-valuemin /
321
343
  * aria-valuemax / aria-valuenow, keyboard navigation by step / page / home /
322
- * end. Pointer drag is handled by the component's drag subscriptions. */
344
+ * end. Pointer drag is handled by the Slider's drag Subscriptions. */
323
345
  export declare const view: import("foldkit/submodel").View<{
324
346
  readonly id: string;
325
347
  readonly min: number;
@@ -354,6 +376,20 @@ export declare const view: import("foldkit/submodel").View<{
354
376
  * position, `aria-valuenow`, and the filled track all derive from it. */
355
377
  value: number;
356
378
  toView: (attributes: SliderAttributes) => Html;
379
+ /** Layout axis for the track, filled track, and thumb. Vertical Sliders
380
+ * place `min` at the bottom and `max` at the top. */
381
+ orientation?: Orientation;
382
+ /** How the thumb aligns within the track. `Center` keeps the thumb's
383
+ * center on the value point and lets it overflow by half its size at the
384
+ * extremes, matching the Slider's previous behavior. `Edge` insets the
385
+ * thumb's travel by `thumbSize` so it stays fully inside the track.
386
+ * Defaults to `Center` so existing Sliders keep their geometry. */
387
+ thumbAlignment?: ThumbAlignment;
388
+ /** CSS length of the thumb along the track axis, used only when
389
+ * `thumbAlignment` is `Edge` to inset the thumb's travel and align the
390
+ * fill with the thumb's center. Set this to the size your `toView`
391
+ * callback styles the thumb with. Defaults to `0.75rem`. */
392
+ thumbSize?: string;
357
393
  ariaLabel?: string;
358
394
  ariaLabelledBy?: string;
359
395
  formatValue?: (value: number) => string;
@@ -373,10 +409,9 @@ export declare const view: import("foldkit/submodel").View<{
373
409
  * way. */
374
410
  isReadOnly?: boolean;
375
411
  name?: string;
376
- /** Resolves the root that holds the slider track when looking it up by its
377
- * `data-slider-track-id` attribute. Defaults to `document`. Provide a
378
- * ShadowRoot when rendering the slider inside a shadow tree so pointer
379
- * events on the track can map clientX into a value. */
412
+ /** Resolves the DOM root containing the Slider track. Defaults to `document`.
413
+ * Provide a ShadowRoot when rendering the Slider inside a shadow tree so pointer
414
+ * events on the track can map the pointer position into a value. */
380
415
  getTrackRoot?: () => Document | ShadowRoot;
381
416
  }>>;
382
417
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/slider/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/slider/index.ts"],"names":[],"mappings":"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"}
@@ -6,17 +6,17 @@ import { defineTaggedUnion } from 'foldkit/schema';
6
6
  import { modifyFields } from 'foldkit/struct';
7
7
  import { defineView } from 'foldkit/submodel';
8
8
  import * as Subscription from 'foldkit/subscription';
9
- import { attributeSelector } from '../internal/selectors.js';
9
+ import { attributeSelector, idSelector } from '../internal/selectors.js';
10
10
  // MODEL
11
11
  const DragState = defineTaggedUnion({
12
12
  Idle: {},
13
13
  Dragging: { originValue: Schema.Number },
14
14
  });
15
- /** Schema for the slider component's private interaction state. The current
15
+ /** Schema for the Slider's private interaction state. The current
16
16
  * value is owned by the parent and passed in via `ViewInputs.value`, so it is
17
- * not stored here. `min`/`max`/`step` are configuration the drag subscription
18
- * reads to map pointer positions into values. `dragState` tracks the active
19
- * drag phase and captures the pre-drag value so Escape can restore it. */
17
+ * not stored here. `min`, `max`, and `step` configure how the drag Subscription
18
+ * maps pointer positions into values. `dragState` tracks the active drag phase
19
+ * and captures the pre-drag value so Escape can restore it. */
20
20
  export const Model = Schema.Struct({
21
21
  id: Schema.String,
22
22
  min: Schema.Number,
@@ -25,7 +25,7 @@ export const Model = Schema.Struct({
25
25
  dragState: DragState,
26
26
  });
27
27
  // MESSAGE
28
- /** Union of all messages the slider component can produce. */
28
+ /** Union of all Messages the Slider can produce. */
29
29
  export const Message = defineMessageUnion({
30
30
  PressedThumb: { originValue: Schema.Number },
31
31
  PressedPointer: {
@@ -48,11 +48,11 @@ export const Message = defineMessageUnion({
48
48
  },
49
49
  });
50
50
  // OUT MESSAGE
51
- /** Union of all out-messages the slider component can emit to its parent. */
51
+ /** Union of all OutMessages the Slider can emit to its parent. */
52
52
  export const OutMessage = defineMessageUnion({
53
53
  ChangedValue: { value: Schema.Number },
54
54
  });
55
- /** Creates an initial slider model from a config. The value lives in the
55
+ /** Creates an initial Slider Model from a config. The value lives in the
56
56
  * parent Model; initialize it there and snap it with {@link snapAndClamp}. */
57
57
  export const init = (config) => (__foldkitBrandViewResult(({
58
58
  id: config.id,
@@ -75,7 +75,7 @@ const roundToStepPrecision = (value, step) => {
75
75
  };
76
76
  const clamp = (value, min, max) => __foldkitBrandViewResult((Math.min(Math.max(value, min), max)), "@foldkit/ui/slider/index.js#clamp");
77
77
  /** Snaps a value to the nearest step and clamps it into `[min, max]`. Exported
78
- * so a parent can conform the value it owns to the slider's range, for example
78
+ * so a parent can conform the value it owns to the Slider's range, for example
79
79
  * when seeding the initial value or reacting to an external update. */
80
80
  export const snapAndClamp = (value, min, max, step) => {
81
81
  const snapped = min + Math.round((value - min) / step) * step;
@@ -155,21 +155,64 @@ export const reflectRange = Function.dual(2, (model, range) => __foldkitBrandVie
155
155
  // SUBSCRIPTION
156
156
  const DragActivity = Schema.Literals(['Idle', 'Active']);
157
157
  const dragActivityFromModel = (model) => __foldkitBrandViewResult((Match.value(model.dragState).pipe(Match.withReturnType(), Match.tag('Dragging', () => __foldkitBrandViewResult(('Active'), "@foldkit/ui/slider/index.js#anonymous~18")), Match.orElse(() => __foldkitBrandViewResult(('Idle'), "@foldkit/ui/slider/index.js#anonymous~19")))), "@foldkit/ui/slider/index.js#dragActivityFromModel");
158
- const trackElement = (id, root) => __foldkitBrandViewResult((Option.fromNullishOr(root.querySelector(attributeSelector('data-slider-track-id', id)))), "@foldkit/ui/slider/index.js#trackElement");
159
- const valueFromClientX = (clientX, trackElement_, min, max) => {
160
- const rect = trackElement_.getBoundingClientRect();
161
- if (rect.width === 0) {
162
- return __foldkitBrandViewResult((min), "@foldkit/ui/slider/index.js#valueFromClientX");
158
+ const findTrackElement = (sliderId, trackRoot) => __foldkitBrandViewResult((Option.fromNullishOr(trackRoot.querySelector(attributeSelector('data-slider-track-id', sliderId)))), "@foldkit/ui/slider/index.js#findTrackElement");
159
+ const isVerticalTrack = (track) => __foldkitBrandViewResult((track.getAttribute('data-orientation') === 'vertical' ||
160
+ track.hasAttribute('data-vertical')), "@foldkit/ui/slider/index.js#isVerticalTrack");
161
+ const isEdgeAlignedTrack = (track) => __foldkitBrandViewResult((track.getAttribute('data-thumb-alignment') === 'edge'), "@foldkit/ui/slider/index.js#isEdgeAlignedTrack");
162
+ const findThumbElementForTrack = (track) => __foldkitBrandViewResult((pipe(track.getAttribute('data-slider-track-id'), Option.fromNullishOr, Option.flatMap(sliderId => {
163
+ const thumbSelector = idSelector(`${sliderId}-thumb`);
164
+ const maybeSliderRoot = Option.fromNullishOr(track.closest(attributeSelector('data-slider-id', sliderId)));
165
+ return __foldkitBrandViewResult((Option.match(maybeSliderRoot, {
166
+ onNone: () => __foldkitBrandViewResult((Option.fromNullishOr(track.ownerDocument.getElementById(`${sliderId}-thumb`))), "@foldkit/ui/slider/index.js#onNone~2"),
167
+ onSome: sliderRoot => __foldkitBrandViewResult((Option.fromNullishOr(sliderRoot.querySelector(thumbSelector))), "@foldkit/ui/slider/index.js#onSome~2"),
168
+ })), "@foldkit/ui/slider/index.js#anonymous~20");
169
+ }))), "@foldkit/ui/slider/index.js#findThumbElementForTrack");
170
+ const edgeInsetForTrack = (track) => {
171
+ if (!isEdgeAlignedTrack(track)) {
172
+ return __foldkitBrandViewResult((0), "@foldkit/ui/slider/index.js#edgeInsetForTrack");
173
+ }
174
+ const maybeThumb = findThumbElementForTrack(track);
175
+ if (Option.isNone(maybeThumb)) {
176
+ return __foldkitBrandViewResult((0), "@foldkit/ui/slider/index.js#edgeInsetForTrack");
177
+ }
178
+ const thumbRect = maybeThumb.value.getBoundingClientRect();
179
+ const thumbSize = isVerticalTrack(track) ? thumbRect.height : thumbRect.width;
180
+ return __foldkitBrandViewResult((thumbSize / 2), "@foldkit/ui/slider/index.js#edgeInsetForTrack");
181
+ };
182
+ const fractionOfPointerPosition = (pointerPosition, trackSize, edgeInset) => {
183
+ const travelSize = trackSize - edgeInset * 2;
184
+ if (travelSize <= 0) {
185
+ return __foldkitBrandViewResult((clamp(pointerPosition / trackSize, 0, 1)), "@foldkit/ui/slider/index.js#fractionOfPointerPosition");
163
186
  }
164
187
  else {
165
- const fraction = clamp((clientX - rect.left) / rect.width, 0, 1);
166
- return __foldkitBrandViewResult((min + fraction * (max - min)), "@foldkit/ui/slider/index.js#valueFromClientX");
188
+ return __foldkitBrandViewResult((clamp((pointerPosition - edgeInset) / travelSize, 0, 1)), "@foldkit/ui/slider/index.js#fractionOfPointerPosition");
167
189
  }
168
190
  };
169
- /** Builds slider drag subscriptions, looking up the track
170
- * element through the supplied root resolver. Use this when the slider is
171
- * rendered inside a Shadow DOM. The root is read lazily so consumers can
172
- * resolve it at subscription time. */
191
+ /** Maps a pointer position to a Slider value. Vertical tracks place `min` at
192
+ * the bottom and `max` at the top. Edge-aligned tracks measure the rendered
193
+ * thumb and map the pointer across the same inset range it travels through. */
194
+ export const valueFromPointer = (clientX, clientY, track, min, max) => {
195
+ const trackRect = track.getBoundingClientRect();
196
+ if (isVerticalTrack(track)) {
197
+ if (trackRect.height === 0) {
198
+ return __foldkitBrandViewResult((min), "@foldkit/ui/slider/index.js#valueFromPointer");
199
+ }
200
+ else {
201
+ const fraction = fractionOfPointerPosition(trackRect.bottom - clientY, trackRect.height, edgeInsetForTrack(track));
202
+ return __foldkitBrandViewResult((min + fraction * (max - min)), "@foldkit/ui/slider/index.js#valueFromPointer");
203
+ }
204
+ }
205
+ if (trackRect.width === 0) {
206
+ return __foldkitBrandViewResult((min), "@foldkit/ui/slider/index.js#valueFromPointer");
207
+ }
208
+ else {
209
+ const fraction = fractionOfPointerPosition(clientX - trackRect.left, trackRect.width, edgeInsetForTrack(track));
210
+ return __foldkitBrandViewResult((min + fraction * (max - min)), "@foldkit/ui/slider/index.js#valueFromPointer");
211
+ }
212
+ };
213
+ /** Builds Slider drag Subscriptions that find the track through the supplied
214
+ * root resolver. Use this when the Slider is rendered inside a Shadow DOM.
215
+ * The resolver runs at subscription time. */
173
216
  export const subscriptionsForRoot = (getTrackRoot) => __foldkitBrandViewResult((Subscription.make()(entry => (__foldkitBrandViewResult(({
174
217
  dragPointer: entry({
175
218
  dragActivity: DragActivity,
@@ -184,9 +227,9 @@ export const subscriptionsForRoot = (getTrackRoot) => __foldkitBrandViewResult((
184
227
  max: model.max,
185
228
  }), "@foldkit/ui/slider/index.js#modelToDependencies")),
186
229
  dependenciesToStream: ({ dragActivity, id, min, max }) => {
187
- const pointerEvents = Stream.merge(Stream.fromEventListener(document, 'pointermove').pipe(Stream.mapEffect(event => __foldkitBrandViewResult((Effect.sync(() => __foldkitBrandViewResult((Option.map(trackElement(id, getTrackRoot()), element => __foldkitBrandViewResult((Message.MovedDragPointer({
188
- value: valueFromClientX(event.clientX, element, min, max),
189
- })), "@foldkit/ui/slider/index.js#anonymous~23"))), "@foldkit/ui/slider/index.js#anonymous~22"))), "@foldkit/ui/slider/index.js#anonymous~21")), Stream.filter(Option.isSome), Stream.map(option => __foldkitBrandViewResult((option.value), "@foldkit/ui/slider/index.js#anonymous~24"))), Stream.fromEventListener(document, 'pointerup').pipe(Stream.map(() => __foldkitBrandViewResult((Message.ReleasedDragPointer()), "@foldkit/ui/slider/index.js#anonymous~25"))));
230
+ const pointerEvents = Stream.merge(Stream.fromEventListener(document, 'pointermove').pipe(Stream.mapEffect(event => __foldkitBrandViewResult((Effect.sync(() => __foldkitBrandViewResult((Option.map(findTrackElement(id, getTrackRoot()), track => __foldkitBrandViewResult((Message.MovedDragPointer({
231
+ value: valueFromPointer(event.clientX, event.clientY, track, min, max),
232
+ })), "@foldkit/ui/slider/index.js#anonymous~24"))), "@foldkit/ui/slider/index.js#anonymous~23"))), "@foldkit/ui/slider/index.js#anonymous~22")), Stream.filter(Option.isSome), Stream.map(option => __foldkitBrandViewResult((option.value), "@foldkit/ui/slider/index.js#anonymous~25"))), Stream.fromEventListener(document, 'pointerup').pipe(Stream.map(() => __foldkitBrandViewResult((Message.ReleasedDragPointer()), "@foldkit/ui/slider/index.js#anonymous~26"))));
190
233
  // NOTE: prevents text selection and locks cursor to grabbing while the
191
234
  // user drags the thumb. Matches the approach used in drag-and-drop.
192
235
  const documentDragStyles = Stream.callback(() => __foldkitBrandViewResult((Effect.acquireRelease(Effect.sync(() => {
@@ -195,54 +238,113 @@ export const subscriptionsForRoot = (getTrackRoot) => __foldkitBrandViewResult((
195
238
  const cursorStyle = document.createElement('style');
196
239
  cursorStyle.textContent = '* { cursor: grabbing !important; }';
197
240
  document.head.appendChild(cursorStyle);
198
- return __foldkitBrandViewResult((cursorStyle), "@foldkit/ui/slider/index.js#anonymous~27");
241
+ return __foldkitBrandViewResult((cursorStyle), "@foldkit/ui/slider/index.js#anonymous~28");
199
242
  }), cursorStyle => __foldkitBrandViewResult((Effect.sync(() => {
200
243
  document.documentElement.style.removeProperty('user-select');
201
244
  document.documentElement.style.removeProperty('-webkit-user-select');
202
245
  cursorStyle.remove();
203
- })), "@foldkit/ui/slider/index.js#anonymous~28")).pipe(Effect.flatMap(() => __foldkitBrandViewResult((Effect.never), "@foldkit/ui/slider/index.js#anonymous~30")))), "@foldkit/ui/slider/index.js#anonymous~26"));
204
- return __foldkitBrandViewResult((Stream.when(Stream.merge(pointerEvents, documentDragStyles), Effect.sync(() => __foldkitBrandViewResult((dragActivity === 'Active'), "@foldkit/ui/slider/index.js#anonymous~31")))), "@foldkit/ui/slider/index.js#dependenciesToStream");
246
+ })), "@foldkit/ui/slider/index.js#anonymous~29")).pipe(Effect.flatMap(() => __foldkitBrandViewResult((Effect.never), "@foldkit/ui/slider/index.js#anonymous~31")))), "@foldkit/ui/slider/index.js#anonymous~27"));
247
+ return __foldkitBrandViewResult((Stream.when(Stream.merge(pointerEvents, documentDragStyles), Effect.sync(() => __foldkitBrandViewResult((dragActivity === 'Active'), "@foldkit/ui/slider/index.js#anonymous~32")))), "@foldkit/ui/slider/index.js#dependenciesToStream");
205
248
  },
206
249
  }),
207
250
  dragEscape: entry({ dragActivity: DragActivity }, {
208
251
  modelToDependencies: model => (__foldkitBrandViewResult(({
209
252
  dragActivity: dragActivityFromModel(model),
210
253
  }), "@foldkit/ui/slider/index.js#modelToDependencies~2")),
211
- dependenciesToStream: ({ dragActivity }) => __foldkitBrandViewResult((Stream.when(Stream.fromEventListener(document, 'keydown').pipe(Stream.filter(({ key }) => __foldkitBrandViewResult((key === 'Escape'), "@foldkit/ui/slider/index.js#anonymous~32")), Stream.map(() => __foldkitBrandViewResult((Message.CancelledDrag()), "@foldkit/ui/slider/index.js#anonymous~33"))), Effect.sync(() => __foldkitBrandViewResult((dragActivity === 'Active'), "@foldkit/ui/slider/index.js#anonymous~34")))), "@foldkit/ui/slider/index.js#dependenciesToStream~2"),
254
+ dependenciesToStream: ({ dragActivity }) => __foldkitBrandViewResult((Stream.when(Stream.fromEventListener(document, 'keydown').pipe(Stream.filter(({ key }) => __foldkitBrandViewResult((key === 'Escape'), "@foldkit/ui/slider/index.js#anonymous~33")), Stream.map(() => __foldkitBrandViewResult((Message.CancelledDrag()), "@foldkit/ui/slider/index.js#anonymous~34"))), Effect.sync(() => __foldkitBrandViewResult((dragActivity === 'Active'), "@foldkit/ui/slider/index.js#anonymous~35")))), "@foldkit/ui/slider/index.js#dependenciesToStream~2"),
212
255
  }),
213
- }), "@foldkit/ui/slider/index.js#anonymous~20")))), "@foldkit/ui/slider/index.js#subscriptionsForRoot");
214
- /** Default drag subscriptions, with the track looked up via `document`. */
215
- export const subscriptions = subscriptionsForRoot(() => __foldkitBrandViewResult((document), "@foldkit/ui/slider/index.js#anonymous~35"));
256
+ }), "@foldkit/ui/slider/index.js#anonymous~21")))), "@foldkit/ui/slider/index.js#subscriptionsForRoot");
257
+ /** Default drag Subscriptions, with the track looked up via `document`. */
258
+ export const subscriptions = subscriptionsForRoot(() => __foldkitBrandViewResult((document), "@foldkit/ui/slider/index.js#anonymous~36"));
216
259
  // VIEW
217
260
  const LEFT_MOUSE_BUTTON = 0;
218
261
  const labelId = (id) => __foldkitBrandViewResult((`${id}-label`), "@foldkit/ui/slider/index.js#labelId");
219
- const keyToDirection = (key) => __foldkitBrandViewResult((Match.value(key).pipe(Match.withReturnType(), Match.whenOr('ArrowRight', 'ArrowUp', () => __foldkitBrandViewResult(('StepIncrement'), "@foldkit/ui/slider/index.js#anonymous~36")), Match.whenOr('ArrowLeft', 'ArrowDown', () => __foldkitBrandViewResult(('StepDecrement'), "@foldkit/ui/slider/index.js#anonymous~37")), Match.when('PageUp', () => __foldkitBrandViewResult(('PageIncrement'), "@foldkit/ui/slider/index.js#anonymous~38")), Match.when('PageDown', () => __foldkitBrandViewResult(('PageDecrement'), "@foldkit/ui/slider/index.js#anonymous~39")), Match.when('Home', () => __foldkitBrandViewResult(('Min'), "@foldkit/ui/slider/index.js#anonymous~40")), Match.when('End', () => __foldkitBrandViewResult(('Max'), "@foldkit/ui/slider/index.js#anonymous~41")), Match.option)), "@foldkit/ui/slider/index.js#keyToDirection");
262
+ const keyToDirection = (key) => __foldkitBrandViewResult((Match.value(key).pipe(Match.withReturnType(), Match.whenOr('ArrowRight', 'ArrowUp', () => __foldkitBrandViewResult(('StepIncrement'), "@foldkit/ui/slider/index.js#anonymous~37")), Match.whenOr('ArrowLeft', 'ArrowDown', () => __foldkitBrandViewResult(('StepDecrement'), "@foldkit/ui/slider/index.js#anonymous~38")), Match.when('PageUp', () => __foldkitBrandViewResult(('PageIncrement'), "@foldkit/ui/slider/index.js#anonymous~39")), Match.when('PageDown', () => __foldkitBrandViewResult(('PageDecrement'), "@foldkit/ui/slider/index.js#anonymous~40")), Match.when('Home', () => __foldkitBrandViewResult(('Min'), "@foldkit/ui/slider/index.js#anonymous~41")), Match.when('End', () => __foldkitBrandViewResult(('Max'), "@foldkit/ui/slider/index.js#anonymous~42")), Match.option)), "@foldkit/ui/slider/index.js#keyToDirection");
220
263
  const percentString = (fraction) => __foldkitBrandViewResult((`${Math.round(fraction * 10000) / 100}%`), "@foldkit/ui/slider/index.js#percentString");
264
+ /** Direction in which the Slider lays out its track and maps pointer input. */
265
+ export const Orientation = Schema.Literals(['Horizontal', 'Vertical']);
266
+ /** Whether the thumb's center or outer edge aligns with the track endpoints. */
267
+ export const ThumbAlignment = Schema.Literals(['Center', 'Edge']);
268
+ const filledTrackStyle = (orientation, thumbAlignment, thumbSize, fraction) => __foldkitBrandViewResult((Match.value({ orientation, thumbAlignment }).pipe(Match.withReturnType(), Match.when({ orientation: 'Vertical', thumbAlignment: 'Center' }, () => (__foldkitBrandViewResult(({
269
+ position: 'absolute',
270
+ bottom: '0',
271
+ left: '0',
272
+ right: '0',
273
+ height: percentString(fraction),
274
+ width: '100%',
275
+ 'pointer-events': 'none',
276
+ }), "@foldkit/ui/slider/index.js#anonymous~43"))), Match.when({ orientation: 'Vertical', thumbAlignment: 'Edge' }, () => (__foldkitBrandViewResult(({
277
+ position: 'absolute',
278
+ bottom: '0',
279
+ left: '0',
280
+ right: '0',
281
+ height: `calc((100% - ${thumbSize}) * ${fraction} + ${thumbSize} / 2)`,
282
+ width: '100%',
283
+ 'pointer-events': 'none',
284
+ }), "@foldkit/ui/slider/index.js#anonymous~44"))), Match.when({ orientation: 'Horizontal', thumbAlignment: 'Center' }, () => (__foldkitBrandViewResult(({
285
+ position: 'absolute',
286
+ left: '0',
287
+ top: '0',
288
+ bottom: '0',
289
+ width: percentString(fraction),
290
+ 'pointer-events': 'none',
291
+ }), "@foldkit/ui/slider/index.js#anonymous~45"))), Match.when({ orientation: 'Horizontal', thumbAlignment: 'Edge' }, () => (__foldkitBrandViewResult(({
292
+ position: 'absolute',
293
+ left: '0',
294
+ top: '0',
295
+ bottom: '0',
296
+ width: `calc((100% - ${thumbSize}) * ${fraction} + ${thumbSize} / 2)`,
297
+ 'pointer-events': 'none',
298
+ }), "@foldkit/ui/slider/index.js#anonymous~46"))), Match.exhaustive)), "@foldkit/ui/slider/index.js#filledTrackStyle");
299
+ const thumbStyle = (orientation, thumbAlignment, thumbSize, fraction) => __foldkitBrandViewResult((Match.value({ orientation, thumbAlignment }).pipe(Match.withReturnType(), Match.when({ orientation: 'Vertical', thumbAlignment: 'Center' }, () => (__foldkitBrandViewResult(({
300
+ position: 'absolute',
301
+ bottom: percentString(fraction),
302
+ left: '50%',
303
+ transform: 'translateX(-50%) translateY(50%)',
304
+ 'touch-action': 'none',
305
+ }), "@foldkit/ui/slider/index.js#anonymous~47"))), Match.when({ orientation: 'Vertical', thumbAlignment: 'Edge' }, () => (__foldkitBrandViewResult(({
306
+ position: 'absolute',
307
+ bottom: `calc((100% - ${thumbSize}) * ${fraction})`,
308
+ left: '50%',
309
+ transform: 'translateX(-50%)',
310
+ 'touch-action': 'none',
311
+ }), "@foldkit/ui/slider/index.js#anonymous~48"))), Match.when({ orientation: 'Horizontal', thumbAlignment: 'Center' }, () => (__foldkitBrandViewResult(({
312
+ position: 'absolute',
313
+ left: percentString(fraction),
314
+ transform: 'translateX(-50%)',
315
+ 'touch-action': 'none',
316
+ }), "@foldkit/ui/slider/index.js#anonymous~49"))), Match.when({ orientation: 'Horizontal', thumbAlignment: 'Edge' }, () => (__foldkitBrandViewResult(({
317
+ position: 'absolute',
318
+ left: `calc((100% - ${thumbSize}) * ${fraction})`,
319
+ 'touch-action': 'none',
320
+ }), "@foldkit/ui/slider/index.js#anonymous~50"))), Match.exhaustive)), "@foldkit/ui/slider/index.js#thumbStyle");
221
321
  /** Renders an accessible slider by building ARIA attribute groups and
222
322
  * delegating layout to the consumer's `toView` callback. Follows the
223
323
  * WAI-ARIA slider pattern: role="slider" on the thumb, aria-valuemin /
224
324
  * aria-valuemax / aria-valuenow, keyboard navigation by step / page / home /
225
- * end. Pointer drag is handled by the component's drag subscriptions. */
325
+ * end. Pointer drag is handled by the Slider's drag Subscriptions. */
226
326
  export const view = defineView((model, viewInputs, h) => {
227
- const { value, formatValue, isDisabled = false, isReadOnly = false, name, getTrackRoot = () => __foldkitBrandViewResult((document), "@foldkit/ui/slider/index.js#anonymous~43"), } = viewInputs;
327
+ const { value, formatValue, isDisabled = false, isReadOnly = false, name, orientation = 'Horizontal', thumbAlignment = 'Center', thumbSize = '0.75rem', getTrackRoot = () => __foldkitBrandViewResult((document), "@foldkit/ui/slider/index.js#anonymous~52"), } = viewInputs;
228
328
  const { id, min, max } = model;
229
329
  const isDragging = model.dragState._tag === 'Dragging';
230
330
  const fraction = fractionOfValue(value, min, max);
231
- const handleKeyDown = (key) => __foldkitBrandViewResult((Option.map(keyToDirection(key), direction => __foldkitBrandViewResult((Message.PressedKeyboardNavigation({ direction, value })), "@foldkit/ui/slider/index.js#anonymous~44"))), "@foldkit/ui/slider/index.js#handleKeyDown");
232
- const pointerAtClientX = (clientX) => __foldkitBrandViewResult((Option.map(trackElement(id, getTrackRoot()), element => __foldkitBrandViewResult((Message.PressedPointer({
233
- value: valueFromClientX(clientX, element, min, max),
331
+ const handleKeyDown = (key) => __foldkitBrandViewResult((Option.map(keyToDirection(key), direction => __foldkitBrandViewResult((Message.PressedKeyboardNavigation({ direction, value })), "@foldkit/ui/slider/index.js#anonymous~53"))), "@foldkit/ui/slider/index.js#handleKeyDown");
332
+ const pressedPointerMessageAt = (clientX, clientY) => __foldkitBrandViewResult((Option.map(findTrackElement(id, getTrackRoot()), track => __foldkitBrandViewResult((Message.PressedPointer({
333
+ value: valueFromPointer(clientX, clientY, track, min, max),
234
334
  originValue: value,
235
- })), "@foldkit/ui/slider/index.js#anonymous~45"))), "@foldkit/ui/slider/index.js#pointerAtClientX");
236
- const trackPointerHandler = (_pointerType, button, _screenX, _screenY, _timeStamp, clientX) => __foldkitBrandViewResult((pipe(button, Option.liftPredicate(Equal.equals(LEFT_MOUSE_BUTTON)), Option.flatMap(() => __foldkitBrandViewResult((pointerAtClientX(clientX)), "@foldkit/ui/slider/index.js#anonymous~46")))), "@foldkit/ui/slider/index.js#trackPointerHandler");
237
- const thumbPointerHandler = (_pointerType, button) => __foldkitBrandViewResult((pipe(button, Option.liftPredicate(Equal.equals(LEFT_MOUSE_BUTTON)), Option.map(() => __foldkitBrandViewResult((Message.PressedThumb({ originValue: value })), "@foldkit/ui/slider/index.js#anonymous~47")))), "@foldkit/ui/slider/index.js#thumbPointerHandler");
335
+ })), "@foldkit/ui/slider/index.js#anonymous~54"))), "@foldkit/ui/slider/index.js#pressedPointerMessageAt");
336
+ const trackPointerHandler = (_pointerType, button, _screenX, _screenY, _timeStamp, clientX, clientY) => __foldkitBrandViewResult((pipe(button, Option.liftPredicate(Equal.equals(LEFT_MOUSE_BUTTON)), Option.flatMap(() => __foldkitBrandViewResult((pressedPointerMessageAt(clientX, clientY)), "@foldkit/ui/slider/index.js#anonymous~55")))), "@foldkit/ui/slider/index.js#trackPointerHandler");
337
+ const thumbPointerHandler = (_pointerType, button) => __foldkitBrandViewResult((pipe(button, Option.liftPredicate(Equal.equals(LEFT_MOUSE_BUTTON)), Option.map(() => __foldkitBrandViewResult((Message.PressedThumb({ originValue: value })), "@foldkit/ui/slider/index.js#anonymous~56")))), "@foldkit/ui/slider/index.js#thumbPointerHandler");
238
338
  const stateAttributes = [
239
339
  ...(isDragging ? [h.DataAttribute('dragging', '')] : []),
240
340
  ...(isDisabled ? [h.DataAttribute('disabled', '')] : []),
241
341
  ...(isReadOnly ? [h.DataAttribute('readonly', '')] : []),
242
342
  ];
343
+ const orientationAttributeValue = String.toLowerCase(orientation);
243
344
  const rootAttributes = [
244
345
  h.DataAttribute('slider-id', id),
245
- h.DataAttribute('orientation', 'horizontal'),
346
+ h.DataAttribute('orientation', orientationAttributeValue),
347
+ h.DataAttribute(orientationAttributeValue, ''),
246
348
  ...stateAttributes,
247
349
  ];
248
350
  const isInteractive = !isDisabled && !isReadOnly;
@@ -251,19 +353,15 @@ export const view = defineView((model, viewInputs, h) => {
251
353
  : [];
252
354
  const trackAttributes = [
253
355
  h.DataAttribute('slider-track-id', id),
356
+ h.DataAttribute('orientation', orientationAttributeValue),
357
+ h.DataAttribute(orientationAttributeValue, ''),
358
+ h.DataAttribute('thumb-alignment', String.toLowerCase(thumbAlignment)),
254
359
  h.Style({ position: 'relative', 'touch-action': 'none' }),
255
360
  ...stateAttributes,
256
361
  ...trackInteractionAttributes,
257
362
  ];
258
363
  const filledTrackAttributes = [
259
- h.Style({
260
- position: 'absolute',
261
- left: '0',
262
- top: '0',
263
- bottom: '0',
264
- width: percentString(fraction),
265
- 'pointer-events': 'none',
266
- }),
364
+ h.Style(filledTrackStyle(orientation, thumbAlignment, thumbSize, fraction)),
267
365
  ...stateAttributes,
268
366
  ];
269
367
  const resolveThumbLabel = () => {
@@ -289,7 +387,7 @@ export const view = defineView((model, viewInputs, h) => {
289
387
  h.Id(`${id}-thumb`),
290
388
  h.Role('slider'),
291
389
  h.Tabindex(0),
292
- h.AriaOrientation('horizontal'),
390
+ h.AriaOrientation(orientationAttributeValue),
293
391
  h.AriaValuemin(min),
294
392
  h.AriaValuemax(max),
295
393
  h.AriaValuenow(value),
@@ -297,12 +395,7 @@ export const view = defineView((model, viewInputs, h) => {
297
395
  ...thumbLabelAttributes,
298
396
  ...(isDisabled ? [h.AriaDisabled(true)] : []),
299
397
  ...(isReadOnly ? [h.AriaReadonly(true)] : []),
300
- h.Style({
301
- position: 'absolute',
302
- left: percentString(fraction),
303
- transform: 'translateX(-50%)',
304
- 'touch-action': 'none',
305
- }),
398
+ h.Style(thumbStyle(orientation, thumbAlignment, thumbSize, fraction)),
306
399
  ...stateAttributes,
307
400
  ...thumbInteractionAttributes,
308
401
  ];
@@ -317,5 +410,5 @@ export const view = defineView((model, viewInputs, h) => {
317
410
  thumb: childAttributes(thumbAttributes),
318
411
  label: childAttributes(labelAttributes),
319
412
  hiddenInput: childAttributes(hiddenInputAttributes),
320
- })), "@foldkit/ui/slider/index.js#anonymous~42");
413
+ })), "@foldkit/ui/slider/index.js#anonymous~51");
321
414
  });
@@ -1,3 +1,3 @@
1
- export { init, update, reflectRange, view, subscriptions, subscriptionsForRoot, fractionOfValue, snapAndClamp, Model, Message, OutMessage, type PressedThumb, type PressedPointer, type MovedDragPointer, type ReleasedDragPointer, type CancelledDrag, type PressedKeyboardNavigation, } from './index.js';
1
+ export { init, update, reflectRange, view, subscriptions, subscriptionsForRoot, fractionOfValue, snapAndClamp, valueFromPointer, Model, Message, Orientation, OutMessage, ThumbAlignment, type PressedThumb, type PressedPointer, type MovedDragPointer, type ReleasedDragPointer, type CancelledDrag, type PressedKeyboardNavigation, } from './index.js';
2
2
  export type { InitConfig, ViewInputs, SliderAttributes } from './index.js';
3
3
  //# sourceMappingURL=public.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/slider/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,MAAM,EACN,YAAY,EACZ,IAAI,EACJ,aAAa,EACb,oBAAoB,EACpB,eAAe,EACf,YAAY,EACZ,KAAK,EACL,OAAO,EACP,UAAU,EACV,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAClB,KAAK,yBAAyB,GAC/B,MAAM,YAAY,CAAA;AAEnB,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/slider/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,MAAM,EACN,YAAY,EACZ,IAAI,EACJ,aAAa,EACb,oBAAoB,EACpB,eAAe,EACf,YAAY,EACZ,gBAAgB,EAChB,KAAK,EACL,OAAO,EACP,WAAW,EACX,UAAU,EACV,cAAc,EACd,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAClB,KAAK,yBAAyB,GAC/B,MAAM,YAAY,CAAA;AAEnB,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA"}
@@ -1 +1 @@
1
- export { init, update, reflectRange, view, subscriptions, subscriptionsForRoot, fractionOfValue, snapAndClamp, Model, Message, OutMessage, } from './index.js';
1
+ export { init, update, reflectRange, view, subscriptions, subscriptionsForRoot, fractionOfValue, snapAndClamp, valueFromPointer, Model, Message, Orientation, OutMessage, ThumbAlignment, } from './index.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@foldkit/ui",
3
- "version": "0.163.0-canary.c9e82fbb078a",
3
+ "version": "0.163.0-canary.ca7e5731a9f5",
4
4
  "description": "Headless, accessible UI components for Foldkit",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -122,7 +122,7 @@
122
122
  ],
123
123
  "peerDependencies": {
124
124
  "effect": "4.0.0-rc.116",
125
- "foldkit": "0.163.0-canary.c9e82fbb078a"
125
+ "foldkit": "0.163.0-canary.ca7e5731a9f5"
126
126
  },
127
127
  "dependencies": {
128
128
  "@floating-ui/dom": "^1.8.0"
@@ -134,8 +134,8 @@
134
134
  "rimraf": "^6.1.3",
135
135
  "typescript": "^7.0.2",
136
136
  "vitest": "^5.0.0",
137
- "@foldkit/vite-plugin": "0.24.0-canary.c9e82fbb078a",
138
- "foldkit": "0.163.0-canary.c9e82fbb078a"
137
+ "@foldkit/vite-plugin": "0.24.0-canary.ca7e5731a9f5",
138
+ "foldkit": "0.163.0-canary.ca7e5731a9f5"
139
139
  },
140
140
  "keywords": [
141
141
  "foldkit",