foldkit 0.41.0 → 0.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/README.md +1 -0
  2. package/dist/devtools/overlay.d.ts.map +1 -1
  3. package/dist/devtools/overlay.js +8 -5
  4. package/dist/runtime/runtime.d.ts +2 -0
  5. package/dist/runtime/runtime.d.ts.map +1 -1
  6. package/dist/runtime/runtime.js +17 -3
  7. package/dist/runtime/subscription.d.ts +6 -8
  8. package/dist/runtime/subscription.d.ts.map +1 -1
  9. package/dist/runtime/subscription.js +5 -1
  10. package/dist/ui/checkbox/index.d.ts +3 -3
  11. package/dist/ui/checkbox/index.d.ts.map +1 -1
  12. package/dist/ui/checkbox/index.js +11 -8
  13. package/dist/ui/combobox/multi.d.ts +4 -3
  14. package/dist/ui/combobox/multi.d.ts.map +1 -1
  15. package/dist/ui/combobox/multi.js +4 -4
  16. package/dist/ui/combobox/public.d.ts +2 -2
  17. package/dist/ui/combobox/public.d.ts.map +1 -1
  18. package/dist/ui/combobox/public.js +1 -1
  19. package/dist/ui/combobox/shared.d.ts +12 -1
  20. package/dist/ui/combobox/shared.d.ts.map +1 -1
  21. package/dist/ui/combobox/shared.js +32 -19
  22. package/dist/ui/combobox/single.d.ts +4 -3
  23. package/dist/ui/combobox/single.d.ts.map +1 -1
  24. package/dist/ui/combobox/single.js +4 -4
  25. package/dist/ui/dialog/index.d.ts +11 -3
  26. package/dist/ui/dialog/index.d.ts.map +1 -1
  27. package/dist/ui/dialog/index.js +15 -7
  28. package/dist/ui/dialog/public.d.ts +1 -1
  29. package/dist/ui/dialog/public.d.ts.map +1 -1
  30. package/dist/ui/dialog/public.js +1 -1
  31. package/dist/ui/disclosure/index.d.ts +8 -3
  32. package/dist/ui/disclosure/index.d.ts.map +1 -1
  33. package/dist/ui/disclosure/index.js +12 -7
  34. package/dist/ui/disclosure/public.d.ts +2 -2
  35. package/dist/ui/disclosure/public.d.ts.map +1 -1
  36. package/dist/ui/disclosure/public.js +1 -1
  37. package/dist/ui/dragAndDrop/index.d.ts +285 -0
  38. package/dist/ui/dragAndDrop/index.d.ts.map +1 -0
  39. package/dist/ui/dragAndDrop/index.js +511 -0
  40. package/dist/ui/dragAndDrop/public.d.ts +3 -0
  41. package/dist/ui/dragAndDrop/public.d.ts.map +1 -0
  42. package/dist/ui/dragAndDrop/public.js +1 -0
  43. package/dist/ui/index.d.ts +1 -0
  44. package/dist/ui/index.d.ts.map +1 -1
  45. package/dist/ui/index.js +1 -0
  46. package/dist/ui/listbox/multi.d.ts +4 -3
  47. package/dist/ui/listbox/multi.d.ts.map +1 -1
  48. package/dist/ui/listbox/multi.js +4 -4
  49. package/dist/ui/listbox/public.d.ts +3 -3
  50. package/dist/ui/listbox/public.d.ts.map +1 -1
  51. package/dist/ui/listbox/public.js +2 -2
  52. package/dist/ui/listbox/shared.d.ts +14 -1
  53. package/dist/ui/listbox/shared.d.ts.map +1 -1
  54. package/dist/ui/listbox/shared.js +31 -16
  55. package/dist/ui/listbox/single.d.ts +10 -5
  56. package/dist/ui/listbox/single.d.ts.map +1 -1
  57. package/dist/ui/listbox/single.js +8 -5
  58. package/dist/ui/menu/index.d.ts +19 -3
  59. package/dist/ui/menu/index.d.ts.map +1 -1
  60. package/dist/ui/menu/index.js +39 -21
  61. package/dist/ui/menu/public.d.ts +2 -2
  62. package/dist/ui/menu/public.d.ts.map +1 -1
  63. package/dist/ui/menu/public.js +1 -1
  64. package/dist/ui/popover/index.d.ts +20 -3
  65. package/dist/ui/popover/index.d.ts.map +1 -1
  66. package/dist/ui/popover/index.js +31 -14
  67. package/dist/ui/popover/public.d.ts +2 -2
  68. package/dist/ui/popover/public.d.ts.map +1 -1
  69. package/dist/ui/popover/public.js +1 -1
  70. package/dist/ui/radioGroup/index.d.ts +10 -5
  71. package/dist/ui/radioGroup/index.d.ts.map +1 -1
  72. package/dist/ui/radioGroup/index.js +18 -20
  73. package/dist/ui/radioGroup/public.d.ts +2 -2
  74. package/dist/ui/radioGroup/public.d.ts.map +1 -1
  75. package/dist/ui/radioGroup/public.js +1 -1
  76. package/dist/ui/switch/index.d.ts +3 -3
  77. package/dist/ui/switch/index.d.ts.map +1 -1
  78. package/dist/ui/switch/index.js +11 -8
  79. package/dist/ui/tabs/index.d.ts +8 -3
  80. package/dist/ui/tabs/index.d.ts.map +1 -1
  81. package/dist/ui/tabs/index.js +15 -8
  82. package/dist/ui/tabs/public.d.ts +2 -2
  83. package/dist/ui/tabs/public.d.ts.map +1 -1
  84. package/dist/ui/tabs/public.js +1 -1
  85. package/package.json +1 -1
@@ -0,0 +1,511 @@
1
+ import { Array, Effect, Equal, Equivalence, Function, Match as M, Option, Schema as S, Stream, pipe, } from 'effect';
2
+ import * as Command from '../../command';
3
+ import { html } from '../../html';
4
+ import { m } from '../../message';
5
+ import { makeSubscriptions } from '../../runtime/subscription';
6
+ import { ts } from '../../schema';
7
+ import { evo } from '../../struct';
8
+ import * as Task from '../../task';
9
+ // MODEL
10
+ const Orientation = S.Literal('Horizontal', 'Vertical');
11
+ const ScreenPoint = S.Struct({
12
+ screenX: S.Number,
13
+ screenY: S.Number,
14
+ });
15
+ const ClientPoint = S.Struct({
16
+ clientX: S.Number,
17
+ clientY: S.Number,
18
+ });
19
+ const DropTarget = S.Struct({
20
+ containerId: S.String,
21
+ index: S.Number,
22
+ });
23
+ const Idle = ts('Idle');
24
+ const Pending = ts('Pending', {
25
+ itemId: S.String,
26
+ containerId: S.String,
27
+ index: S.Number,
28
+ origin: ScreenPoint,
29
+ });
30
+ const Dragging = ts('Dragging', {
31
+ itemId: S.String,
32
+ sourceContainerId: S.String,
33
+ sourceIndex: S.Number,
34
+ origin: ScreenPoint,
35
+ current: ClientPoint,
36
+ maybeDropTarget: S.OptionFromSelf(DropTarget),
37
+ });
38
+ const KeyboardDragging = ts('KeyboardDragging', {
39
+ itemId: S.String,
40
+ sourceContainerId: S.String,
41
+ sourceIndex: S.Number,
42
+ targetContainerId: S.String,
43
+ targetIndex: S.Number,
44
+ });
45
+ const DragState = S.Union(Idle, Pending, Dragging, KeyboardDragging);
46
+ /** Schema for the drag-and-drop component's state, tracking its unique ID, orientation, and current drag phase. */
47
+ export const Model = S.Struct({
48
+ id: S.String,
49
+ orientation: Orientation,
50
+ activationThreshold: S.Number,
51
+ dragState: DragState,
52
+ });
53
+ // MESSAGE
54
+ /** The user pressed a pointer on a draggable item. */
55
+ export const PressedDraggable = m('PressedDraggable', {
56
+ itemId: S.String,
57
+ containerId: S.String,
58
+ index: S.Number,
59
+ screenX: S.Number,
60
+ screenY: S.Number,
61
+ });
62
+ /** The pointer moved during a drag, with collision detection results. */
63
+ export const MovedPointer = m('MovedPointer', {
64
+ screenX: S.Number,
65
+ screenY: S.Number,
66
+ clientX: S.Number,
67
+ clientY: S.Number,
68
+ maybeDropTarget: S.OptionFromSelf(DropTarget),
69
+ });
70
+ /** The pointer was released. */
71
+ export const ReleasedPointer = m('ReleasedPointer');
72
+ /** Escape was pressed during a drag. */
73
+ export const CancelledDrag = m('CancelledDrag');
74
+ /** The user activated keyboard drag with Space or Enter on a focused draggable. */
75
+ export const ActivatedKeyboardDrag = m('ActivatedKeyboardDrag', {
76
+ itemId: S.String,
77
+ containerId: S.String,
78
+ index: S.Number,
79
+ });
80
+ /** The ResolveKeyboardMove Command resolved the next keyboard drag position. */
81
+ export const ResolvedKeyboardMove = m('ResolvedKeyboardMove', {
82
+ targetContainerId: S.String,
83
+ targetIndex: S.Number,
84
+ });
85
+ /** The user confirmed a keyboard drop with Space or Enter. */
86
+ export const ConfirmedKeyboardDrop = m('ConfirmedKeyboardDrop');
87
+ /** The user pressed an arrow key during keyboard drag. */
88
+ export const PressedArrowKey = m('PressedArrowKey', {
89
+ direction: S.Literal('Up', 'Down', 'Left', 'Right', 'NextContainer', 'PreviousContainer'),
90
+ });
91
+ /** An animation frame fired during auto-scroll. */
92
+ export const CompletedAutoScroll = m('CompletedAutoScroll');
93
+ /** The FocusItem Command completed. */
94
+ export const CompletedFocusItem = m('CompletedFocusItem');
95
+ /** Union of all messages the drag-and-drop component can produce. */
96
+ export const Message = S.Union(PressedDraggable, MovedPointer, ReleasedPointer, CancelledDrag, ActivatedKeyboardDrag, ResolvedKeyboardMove, ConfirmedKeyboardDrop, PressedArrowKey, CompletedAutoScroll, CompletedFocusItem);
97
+ // OUT MESSAGE
98
+ /** Emitted when a drag completes with a valid drop target. The parent uses this to commit the reorder. */
99
+ export const Reordered = ts('Reordered', {
100
+ itemId: S.String,
101
+ fromContainerId: S.String,
102
+ fromIndex: S.Number,
103
+ toContainerId: S.String,
104
+ toIndex: S.Number,
105
+ });
106
+ /** Emitted when a drag is cancelled via Escape or pointer release without a drop target. */
107
+ export const Cancelled = ts('Cancelled');
108
+ /** Union of all out-messages the drag-and-drop component can emit to its parent. */
109
+ export const OutMessage = S.Union(Reordered, Cancelled);
110
+ // INIT
111
+ /** Configuration for creating a drag-and-drop model with `init`. */
112
+ const DEFAULT_ACTIVATION_THRESHOLD_PIXELS = 5;
113
+ /** Creates an initial drag-and-drop model. Starts in the Idle state with Vertical orientation and 5px activation threshold by default. */
114
+ export const init = (config) => ({
115
+ id: config.id,
116
+ orientation: config.orientation ?? 'Vertical',
117
+ activationThreshold: config.activationThreshold ?? DEFAULT_ACTIVATION_THRESHOLD_PIXELS,
118
+ dragState: Idle(),
119
+ });
120
+ /** Resolves the next keyboard drag position by querying the DOM for adjacent sortable items and containers. */
121
+ export const ResolveKeyboardMove = Command.define('ResolveKeyboardMove', ResolvedKeyboardMove);
122
+ /** Focuses a draggable item by ID after keyboard drop or cancel. */
123
+ export const FocusItem = Command.define('FocusItem', CompletedFocusItem);
124
+ const focusItem = (itemId) => FocusItem(Task.focus(`[data-draggable-id="${itemId}"]`).pipe(Effect.ignore, Effect.as(CompletedFocusItem())));
125
+ const resolveWithinContainer = (config) => {
126
+ const container = document.querySelector(`[data-droppable-id="${config.containerId}"]`);
127
+ if (!container) {
128
+ return ResolvedKeyboardMove({
129
+ targetContainerId: config.containerId,
130
+ targetIndex: config.currentIndex,
131
+ });
132
+ }
133
+ const itemCount = pipe(container.querySelectorAll('[data-sortable-id]'), Array.fromIterable, Array.filter(({ dataset }) => dataset['sortableId'] !== config.itemId), Array.length);
134
+ const nextIndex = config.isForward
135
+ ? Math.min(config.currentIndex + 1, itemCount)
136
+ : Math.max(config.currentIndex - 1, 0);
137
+ return ResolvedKeyboardMove({
138
+ targetContainerId: config.containerId,
139
+ targetIndex: nextIndex,
140
+ });
141
+ };
142
+ const resolveBetweenContainers = (config) => {
143
+ const allContainers = Array.fromIterable(document.querySelectorAll('[data-droppable-id]'));
144
+ const currentContainerIndex = pipe(allContainers, Array.findFirstIndex(({ dataset }) => dataset['droppableId'] === config.currentContainerId), Option.getOrElse(() => 0));
145
+ const nextContainerIndex = config.isForward
146
+ ? Math.min(currentContainerIndex + 1, allContainers.length - 1)
147
+ : Math.max(currentContainerIndex - 1, 0);
148
+ const nextContainerId = allContainers[nextContainerIndex]?.dataset['droppableId'] ??
149
+ config.currentContainerId;
150
+ return ResolvedKeyboardMove({
151
+ targetContainerId: nextContainerId,
152
+ targetIndex: 0,
153
+ });
154
+ };
155
+ const resolveKeyboardMoveTarget = (config) => Effect.sync(() => M.value(config.direction).pipe(M.withReturnType(), M.whenOr('Down', 'Right', () => resolveWithinContainer({
156
+ itemId: config.itemId,
157
+ containerId: config.currentContainerId,
158
+ currentIndex: config.currentIndex,
159
+ isForward: true,
160
+ })), M.whenOr('Up', 'Left', () => resolveWithinContainer({
161
+ itemId: config.itemId,
162
+ containerId: config.currentContainerId,
163
+ currentIndex: config.currentIndex,
164
+ isForward: false,
165
+ })), M.when('NextContainer', () => resolveBetweenContainers({
166
+ currentContainerId: config.currentContainerId,
167
+ isForward: true,
168
+ })), M.when('PreviousContainer', () => resolveBetweenContainers({
169
+ currentContainerId: config.currentContainerId,
170
+ isForward: false,
171
+ })), M.exhaustive));
172
+ const withUpdateReturn = M.withReturnType();
173
+ /** Processes a drag-and-drop message and returns the next model, commands, and an optional out-message for the parent. */
174
+ export const update = (model, message) => M.value(message).pipe(withUpdateReturn, M.tagsExhaustive({
175
+ PressedDraggable: ({ itemId, containerId, index, screenX, screenY }) => [
176
+ evo(model, {
177
+ dragState: () => Pending({
178
+ itemId,
179
+ containerId,
180
+ index,
181
+ origin: { screenX, screenY },
182
+ }),
183
+ }),
184
+ [],
185
+ Option.none(),
186
+ ],
187
+ MovedPointer: ({ screenX, screenY, clientX, clientY, maybeDropTarget }) => M.value(model.dragState).pipe(withUpdateReturn, M.tag('Pending', pending => {
188
+ const deltaX = screenX - pending.origin.screenX;
189
+ const deltaY = screenY - pending.origin.screenY;
190
+ const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
191
+ if (distance < model.activationThreshold) {
192
+ return [model, [], Option.none()];
193
+ }
194
+ return [
195
+ evo(model, {
196
+ dragState: () => Dragging({
197
+ itemId: pending.itemId,
198
+ sourceContainerId: pending.containerId,
199
+ sourceIndex: pending.index,
200
+ origin: pending.origin,
201
+ current: { clientX, clientY },
202
+ maybeDropTarget,
203
+ }),
204
+ }),
205
+ [],
206
+ Option.none(),
207
+ ];
208
+ }), M.tag('Dragging', dragging => [
209
+ evo(model, {
210
+ dragState: () => Dragging({
211
+ ...dragging,
212
+ current: { clientX, clientY },
213
+ maybeDropTarget,
214
+ }),
215
+ }),
216
+ [],
217
+ Option.none(),
218
+ ]), M.orElse(() => [model, [], Option.none()])),
219
+ ReleasedPointer: () => M.value(model.dragState).pipe(withUpdateReturn, M.tag('Pending', () => [
220
+ evo(model, { dragState: () => Idle() }),
221
+ [],
222
+ Option.none(),
223
+ ]), M.tag('Dragging', dragging => Option.match(dragging.maybeDropTarget, {
224
+ onNone: () => [
225
+ evo(model, { dragState: () => Idle() }),
226
+ [],
227
+ Option.some(Cancelled()),
228
+ ],
229
+ onSome: dropTarget => [
230
+ evo(model, { dragState: () => Idle() }),
231
+ [],
232
+ Option.some(Reordered({
233
+ itemId: dragging.itemId,
234
+ fromContainerId: dragging.sourceContainerId,
235
+ fromIndex: dragging.sourceIndex,
236
+ toContainerId: dropTarget.containerId,
237
+ toIndex: dropTarget.index,
238
+ })),
239
+ ],
240
+ })), M.orElse(() => [model, [], Option.none()])),
241
+ CancelledDrag: () => {
242
+ const maybeFocusCommand = Option.liftPredicate(model.dragState, dragState => dragState._tag === 'KeyboardDragging').pipe(Option.map(({ itemId }) => focusItem(itemId)));
243
+ const maybeOutMessage = Option.liftPredicate(model.dragState._tag, _tag => _tag === 'Dragging' || _tag === 'KeyboardDragging').pipe(Option.map(() => Cancelled()));
244
+ return [
245
+ evo(model, { dragState: () => Idle() }),
246
+ Option.toArray(maybeFocusCommand),
247
+ maybeOutMessage,
248
+ ];
249
+ },
250
+ ActivatedKeyboardDrag: ({ itemId, containerId, index }) => [
251
+ evo(model, {
252
+ dragState: () => KeyboardDragging({
253
+ itemId,
254
+ sourceContainerId: containerId,
255
+ sourceIndex: index,
256
+ targetContainerId: containerId,
257
+ targetIndex: index,
258
+ }),
259
+ }),
260
+ [],
261
+ Option.none(),
262
+ ],
263
+ ResolvedKeyboardMove: ({ targetContainerId, targetIndex }) => M.value(model.dragState).pipe(withUpdateReturn, M.tag('KeyboardDragging', keyboardDragging => [
264
+ evo(model, {
265
+ dragState: () => KeyboardDragging({
266
+ ...keyboardDragging,
267
+ targetContainerId,
268
+ targetIndex,
269
+ }),
270
+ }),
271
+ [],
272
+ Option.none(),
273
+ ]), M.orElse(() => [model, [], Option.none()])),
274
+ ConfirmedKeyboardDrop: () => M.value(model.dragState).pipe(withUpdateReturn, M.tag('KeyboardDragging', keyboardDragging => [
275
+ evo(model, { dragState: () => Idle() }),
276
+ [focusItem(keyboardDragging.itemId)],
277
+ Option.some(Reordered({
278
+ itemId: keyboardDragging.itemId,
279
+ fromContainerId: keyboardDragging.sourceContainerId,
280
+ fromIndex: keyboardDragging.sourceIndex,
281
+ toContainerId: keyboardDragging.targetContainerId,
282
+ toIndex: keyboardDragging.targetIndex,
283
+ })),
284
+ ]), M.orElse(() => [model, [], Option.none()])),
285
+ PressedArrowKey: ({ direction }) => M.value(model.dragState).pipe(withUpdateReturn, M.tag('KeyboardDragging', keyboardDragging => [
286
+ model,
287
+ [
288
+ ResolveKeyboardMove(resolveKeyboardMoveTarget({
289
+ itemId: keyboardDragging.itemId,
290
+ currentContainerId: keyboardDragging.targetContainerId,
291
+ currentIndex: keyboardDragging.targetIndex,
292
+ direction,
293
+ })),
294
+ ],
295
+ Option.none(),
296
+ ]), M.orElse(() => [model, [], Option.none()])),
297
+ CompletedAutoScroll: () => [model, [], Option.none()],
298
+ CompletedFocusItem: () => [model, [], Option.none()],
299
+ }));
300
+ // SUBSCRIPTION
301
+ const DragActivity = S.Literal('Idle', 'Active');
302
+ const PointerDragActivity = S.Literal('Idle', 'Active');
303
+ const KeyboardDragActivity = S.Literal('Idle', 'Active');
304
+ const resolveDropTarget = (clientX, clientY, orientation) => {
305
+ const maybeContainer = pipe(document.elementsFromPoint(clientX, clientY), Array.fromIterable, Array.findFirst(element => element.hasAttribute('data-droppable-id')));
306
+ return Option.flatMap(maybeContainer, container => {
307
+ const containerId = container.getAttribute('data-droppable-id');
308
+ if (!containerId) {
309
+ return Option.none();
310
+ }
311
+ const sortableItems = Array.fromIterable(container.querySelectorAll('[data-sortable-id]'));
312
+ const insertionIndex = pipe(sortableItems, Array.findFirstIndex(item => {
313
+ const rect = item.getBoundingClientRect();
314
+ return M.value(orientation).pipe(M.when('Vertical', () => clientY < rect.top + rect.height / 2), M.when('Horizontal', () => clientX < rect.left + rect.width / 2), M.exhaustive);
315
+ }), Option.getOrElse(() => sortableItems.length));
316
+ return Option.some({ containerId, index: insertionIndex });
317
+ });
318
+ };
319
+ const DEFAULT_AUTO_SCROLL_EDGE_PIXELS = 40;
320
+ const DEFAULT_AUTO_SCROLL_MAX_SPEED = 15;
321
+ const autoScroll = (clientY) => {
322
+ const viewportHeight = window.innerHeight;
323
+ const distanceFromTop = clientY;
324
+ const distanceFromBottom = viewportHeight - clientY;
325
+ if (distanceFromTop < DEFAULT_AUTO_SCROLL_EDGE_PIXELS) {
326
+ const speed = DEFAULT_AUTO_SCROLL_MAX_SPEED *
327
+ (1 - distanceFromTop / DEFAULT_AUTO_SCROLL_EDGE_PIXELS);
328
+ window.scrollBy(0, -speed);
329
+ }
330
+ else if (distanceFromBottom < DEFAULT_AUTO_SCROLL_EDGE_PIXELS) {
331
+ const speed = DEFAULT_AUTO_SCROLL_MAX_SPEED *
332
+ (1 - distanceFromBottom / DEFAULT_AUTO_SCROLL_EDGE_PIXELS);
333
+ window.scrollBy(0, speed);
334
+ }
335
+ };
336
+ const pointerDragActivityFromModel = (model) => M.value(model.dragState).pipe(M.withReturnType(), M.tag('Pending', 'Dragging', () => 'Active'), M.orElse(() => 'Idle'));
337
+ const dragActivityFromModel = (model) => M.value(model.dragState).pipe(M.withReturnType(), M.tag('Idle', () => 'Idle'), M.orElse(() => 'Active'));
338
+ const keyboardDragActivityFromModel = (model) => M.value(model.dragState).pipe(M.withReturnType(), M.tag('KeyboardDragging', () => 'Active'), M.orElse(() => 'Idle'));
339
+ /** Schema describing the subscription dependencies for document-level drag tracking. */
340
+ export const SubscriptionDeps = S.Struct({
341
+ documentPointer: S.Struct({
342
+ dragActivity: PointerDragActivity,
343
+ orientation: Orientation,
344
+ }),
345
+ documentEscape: S.Struct({ dragActivity: DragActivity }),
346
+ documentKeyboard: S.Struct({ dragActivity: KeyboardDragActivity }),
347
+ autoScroll: S.Struct({
348
+ isDragging: S.Boolean,
349
+ clientY: S.Number,
350
+ }),
351
+ });
352
+ /** Document-level subscriptions for pointer and keyboard events during drag operations. */
353
+ export const subscriptions = makeSubscriptions(SubscriptionDeps)({
354
+ documentPointer: {
355
+ modelToDependencies: model => ({
356
+ dragActivity: pointerDragActivityFromModel(model),
357
+ orientation: model.orientation,
358
+ }),
359
+ dependenciesToStream: ({ dragActivity, orientation }) => {
360
+ const pointerEvents = Stream.merge(Stream.fromEventListener(document, 'pointermove').pipe(Stream.mapEffect(event => Effect.sync(() => MovedPointer({
361
+ screenX: event.screenX,
362
+ screenY: event.screenY,
363
+ clientX: event.clientX,
364
+ clientY: event.clientY,
365
+ maybeDropTarget: resolveDropTarget(event.clientX, event.clientY, orientation),
366
+ })))), Stream.fromEventListener(document, 'pointerup').pipe(Stream.map(() => ReleasedPointer())));
367
+ // NOTE: prevents text selection and locks cursor to grabbing during
368
+ // pointer drag. Uses a <style> element for cursor because inline styles
369
+ // on <html> don't override descendant elements' cursor values.
370
+ const documentDragStyles = Stream.async(_emit => {
371
+ document.documentElement.style.setProperty('user-select', 'none');
372
+ document.documentElement.style.setProperty('-webkit-user-select', 'none');
373
+ const cursorStyle = document.createElement('style');
374
+ cursorStyle.textContent = '* { cursor: grabbing !important; }';
375
+ document.head.appendChild(cursorStyle);
376
+ return Effect.sync(() => {
377
+ document.documentElement.style.removeProperty('user-select');
378
+ document.documentElement.style.removeProperty('-webkit-user-select');
379
+ cursorStyle.remove();
380
+ });
381
+ });
382
+ return Stream.when(Stream.merge(pointerEvents, documentDragStyles), () => dragActivity === 'Active');
383
+ },
384
+ },
385
+ documentEscape: {
386
+ modelToDependencies: model => ({
387
+ dragActivity: dragActivityFromModel(model),
388
+ }),
389
+ dependenciesToStream: ({ dragActivity }) => Stream.when(Stream.fromEventListener(document, 'keydown').pipe(Stream.filter(({ key }) => key === 'Escape'), Stream.map(() => CancelledDrag())), () => dragActivity === 'Active'),
390
+ },
391
+ documentKeyboard: {
392
+ modelToDependencies: model => ({
393
+ dragActivity: keyboardDragActivityFromModel(model),
394
+ }),
395
+ dependenciesToStream: ({ dragActivity }) => Stream.when(Stream.fromEventListener(document, 'keydown').pipe(Stream.mapEffect((event) => Effect.sync(() => {
396
+ // NOTE: the draggable's OnKeyDownPreventDefault calls preventDefault on
397
+ // the Space that activates keyboard drag — skip it here so the same
398
+ // keypress doesn't also confirm the drop in the same tick.
399
+ if (event.defaultPrevented) {
400
+ return Option.none();
401
+ }
402
+ if (event.key === 'Tab') {
403
+ event.preventDefault();
404
+ return Option.some(PressedArrowKey({
405
+ direction: event.shiftKey
406
+ ? 'PreviousContainer'
407
+ : 'NextContainer',
408
+ }));
409
+ }
410
+ if (event.key === ' ' || event.key === 'Enter') {
411
+ event.preventDefault();
412
+ return Option.some(ConfirmedKeyboardDrop());
413
+ }
414
+ return Option.map(arrowKeyToDirection(event.key), direction => {
415
+ event.preventDefault();
416
+ return PressedArrowKey({ direction });
417
+ });
418
+ })), Stream.filterMap(Function.identity)), () => dragActivity === 'Active'),
419
+ },
420
+ autoScroll: {
421
+ modelToDependencies: model => ({
422
+ isDragging: model.dragState._tag === 'Dragging',
423
+ clientY: model.dragState._tag === 'Dragging'
424
+ ? model.dragState.current.clientY
425
+ : 0,
426
+ }),
427
+ equivalence: Equivalence.struct({ isDragging: Equivalence.boolean }),
428
+ dependenciesToStream: ({ isDragging }, readDependencies) => Stream.when(Stream.async(emit => {
429
+ let animationFrameId = 0;
430
+ const step = () => {
431
+ autoScroll(readDependencies().clientY);
432
+ emit.single(CompletedAutoScroll());
433
+ animationFrameId = requestAnimationFrame(step);
434
+ };
435
+ animationFrameId = requestAnimationFrame(step);
436
+ return Effect.sync(() => cancelAnimationFrame(animationFrameId));
437
+ }), () => isDragging),
438
+ },
439
+ });
440
+ // VIEW
441
+ const LEFT_MOUSE_BUTTON = 0;
442
+ const arrowKeyToDirection = (key) => M.value(key).pipe(M.withReturnType(), M.when('ArrowUp', () => 'Up'), M.when('ArrowDown', () => 'Down'), M.when('ArrowLeft', () => 'Left'), M.when('ArrowRight', () => 'Right'), M.option);
443
+ /** Returns attributes the parent attaches to a draggable element. Handles pointer-down, keyboard activation, and ARIA. */
444
+ export const draggable = (config) => {
445
+ const { AriaRoleDescription, DataAttribute, OnKeyDownPreventDefault, OnPointerDown, Role, Style, Tabindex, } = html();
446
+ const isKeyboardDragActivationKey = (key) => key === ' ' || key === 'Enter';
447
+ const handleKeyDown = (key) => {
448
+ if (isKeyboardDragActivationKey(key) &&
449
+ config.model.dragState._tag === 'Idle') {
450
+ return Option.some(config.toParentMessage(ActivatedKeyboardDrag({
451
+ itemId: config.itemId,
452
+ containerId: config.containerId,
453
+ index: config.index,
454
+ })));
455
+ }
456
+ return Option.none();
457
+ };
458
+ return [
459
+ DataAttribute('draggable-id', config.itemId),
460
+ DataAttribute('sortable-id', config.itemId),
461
+ Role('option'),
462
+ AriaRoleDescription('draggable'),
463
+ Tabindex(0),
464
+ OnPointerDown((_pointerType, button, screenX, screenY) => pipe(button, Option.liftPredicate(Equal.equals(LEFT_MOUSE_BUTTON)), Option.map(() => config.toParentMessage(PressedDraggable({
465
+ itemId: config.itemId,
466
+ containerId: config.containerId,
467
+ index: config.index,
468
+ screenX,
469
+ screenY,
470
+ }))))),
471
+ OnKeyDownPreventDefault(handleKeyDown),
472
+ Style({
473
+ 'touch-action': 'none',
474
+ 'user-select': 'none',
475
+ '-webkit-user-select': 'none',
476
+ }),
477
+ ];
478
+ };
479
+ /** Returns attributes the parent attaches to a droppable container element. */
480
+ export const droppable = (containerId, label) => {
481
+ const { AriaLabel, DataAttribute, Role } = html();
482
+ return [
483
+ DataAttribute('droppable-id', containerId),
484
+ Role('listbox'),
485
+ ...(label ? [AriaLabel(label)] : []),
486
+ ];
487
+ };
488
+ /** Returns attributes the parent attaches to a sortable item element. Typically combined with `draggable`. */
489
+ export const sortable = (itemId) => {
490
+ const { DataAttribute } = html();
491
+ return [DataAttribute('sortable-id', itemId)];
492
+ };
493
+ const ghostTransform = (clientX, clientY) => `translate3d(${String(clientX)}px, ${String(clientY)}px, 0)`;
494
+ /** Returns positioning styles for the ghost element, or None when not dragging with a pointer. */
495
+ export const ghostStyle = (model) => M.value(model.dragState).pipe(M.tag('Dragging', dragging => ({
496
+ position: 'fixed',
497
+ top: '0',
498
+ left: '0',
499
+ transform: ghostTransform(dragging.current.clientX, dragging.current.clientY),
500
+ 'pointer-events': 'none',
501
+ 'z-index': '9999',
502
+ })), M.option);
503
+ /** Returns true when the component is actively dragging (pointer or keyboard). */
504
+ export const isDragging = ({ dragState: { _tag } }) => _tag === 'Dragging' || _tag === 'KeyboardDragging';
505
+ /** Returns the ID of the item currently being dragged or pending, if any. */
506
+ export const maybeDraggedItemId = (model) => M.value(model.dragState).pipe(M.tag('Pending', pending => pending.itemId), M.tag('Dragging', dragging => dragging.itemId), M.tag('KeyboardDragging', keyboardDragging => keyboardDragging.itemId), M.option);
507
+ /** Returns the current drop target, if any. Populated during pointer drag (from collision detection) and keyboard drag (from resolved position). */
508
+ export const maybeDropTarget = (model) => M.value(model.dragState).pipe(M.tag('Dragging', dragging => dragging.maybeDropTarget), M.tag('KeyboardDragging', keyboardDragging => Option.some({
509
+ containerId: keyboardDragging.targetContainerId,
510
+ index: keyboardDragging.targetIndex,
511
+ })), M.orElse(() => Option.none()));
@@ -0,0 +1,3 @@
1
+ export { init, update, draggable, droppable, sortable, ghostStyle, isDragging, maybeDraggedItemId, maybeDropTarget, subscriptions, SubscriptionDeps, Model, Message, OutMessage, PressedDraggable, MovedPointer, ReleasedPointer, CancelledDrag, ActivatedKeyboardDrag, ResolvedKeyboardMove, ConfirmedKeyboardDrop, PressedArrowKey, CompletedAutoScroll, CompletedFocusItem, FocusItem, ResolveKeyboardMove, Reordered, Cancelled, } from './index';
2
+ export type { InitConfig, DraggableConfig, DraggableMessage } from './index';
3
+ //# sourceMappingURL=public.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/ui/dragAndDrop/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,MAAM,EACN,SAAS,EACT,SAAS,EACT,QAAQ,EACR,UAAU,EACV,UAAU,EACV,kBAAkB,EAClB,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,KAAK,EACL,OAAO,EACP,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,aAAa,EACb,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,SAAS,EACT,mBAAmB,EACnB,SAAS,EACT,SAAS,GACV,MAAM,SAAS,CAAA;AAEhB,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA"}
@@ -0,0 +1 @@
1
+ export { init, update, draggable, droppable, sortable, ghostStyle, isDragging, maybeDraggedItemId, maybeDropTarget, subscriptions, SubscriptionDeps, Model, Message, OutMessage, PressedDraggable, MovedPointer, ReleasedPointer, CancelledDrag, ActivatedKeyboardDrag, ResolvedKeyboardMove, ConfirmedKeyboardDrop, PressedArrowKey, CompletedAutoScroll, CompletedFocusItem, FocusItem, ResolveKeyboardMove, Reordered, Cancelled, } from './index';
@@ -2,6 +2,7 @@ export * as Button from './button/public';
2
2
  export * as Checkbox from './checkbox/public';
3
3
  export * as Combobox from './combobox/public';
4
4
  export * as Dialog from './dialog/public';
5
+ export * as DragAndDrop from './dragAndDrop/public';
5
6
  export * as Disclosure from './disclosure/public';
6
7
  export * as Fieldset from './fieldset/public';
7
8
  export * as Input from './input/public';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,iBAAiB,CAAA;AACzC,OAAO,KAAK,QAAQ,MAAM,mBAAmB,CAAA;AAC7C,OAAO,KAAK,QAAQ,MAAM,mBAAmB,CAAA;AAC7C,OAAO,KAAK,MAAM,MAAM,iBAAiB,CAAA;AACzC,OAAO,KAAK,UAAU,MAAM,qBAAqB,CAAA;AACjD,OAAO,KAAK,QAAQ,MAAM,mBAAmB,CAAA;AAC7C,OAAO,KAAK,KAAK,MAAM,gBAAgB,CAAA;AACvC,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAA;AAC3C,OAAO,KAAK,IAAI,MAAM,eAAe,CAAA;AACrC,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAA;AAC3C,OAAO,KAAK,UAAU,MAAM,qBAAqB,CAAA;AACjD,OAAO,KAAK,MAAM,MAAM,iBAAiB,CAAA;AACzC,OAAO,KAAK,MAAM,MAAM,iBAAiB,CAAA;AACzC,OAAO,KAAK,QAAQ,MAAM,mBAAmB,CAAA;AAC7C,OAAO,KAAK,IAAI,MAAM,eAAe,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,iBAAiB,CAAA;AACzC,OAAO,KAAK,QAAQ,MAAM,mBAAmB,CAAA;AAC7C,OAAO,KAAK,QAAQ,MAAM,mBAAmB,CAAA;AAC7C,OAAO,KAAK,MAAM,MAAM,iBAAiB,CAAA;AACzC,OAAO,KAAK,WAAW,MAAM,sBAAsB,CAAA;AACnD,OAAO,KAAK,UAAU,MAAM,qBAAqB,CAAA;AACjD,OAAO,KAAK,QAAQ,MAAM,mBAAmB,CAAA;AAC7C,OAAO,KAAK,KAAK,MAAM,gBAAgB,CAAA;AACvC,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAA;AAC3C,OAAO,KAAK,IAAI,MAAM,eAAe,CAAA;AACrC,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAA;AAC3C,OAAO,KAAK,UAAU,MAAM,qBAAqB,CAAA;AACjD,OAAO,KAAK,MAAM,MAAM,iBAAiB,CAAA;AACzC,OAAO,KAAK,MAAM,MAAM,iBAAiB,CAAA;AACzC,OAAO,KAAK,QAAQ,MAAM,mBAAmB,CAAA;AAC7C,OAAO,KAAK,IAAI,MAAM,eAAe,CAAA"}
package/dist/ui/index.js CHANGED
@@ -2,6 +2,7 @@ export * as Button from './button/public';
2
2
  export * as Checkbox from './checkbox/public';
3
3
  export * as Combobox from './combobox/public';
4
4
  export * as Dialog from './dialog/public';
5
+ export * as DragAndDrop from './dragAndDrop/public';
5
6
  export * as Disclosure from './disclosure/public';
6
7
  export * as Fieldset from './fieldset/public';
7
8
  export * as Input from './input/public';
@@ -153,7 +153,8 @@ export declare const view: <Message, Item>(config: Readonly<{
153
153
  } & {
154
154
  readonly selectedItems: readonly string[];
155
155
  };
156
- toMessage: (message: import("./shared").Opened | import("./shared").Closed | import("./shared").ClosedByTab | import("./shared").ActivatedItem | import("./shared").DeactivatedItem | import("./shared").SelectedItem | import("./shared").MovedPointerOverItem | import("./shared").RequestedItemClick | import("./shared").Searched | import("./shared").PressedPointerOnButton | import("./shared").IgnoredMouseClick | import("./shared").SuppressedSpaceScroll) => Message;
156
+ toParentMessage: (message: import("./shared").Opened | import("./shared").Closed | import("./shared").ClosedByTab | import("./shared").ActivatedItem | import("./shared").DeactivatedItem | import("./shared").SelectedItem | import("./shared").MovedPointerOverItem | import("./shared").RequestedItemClick | import("./shared").Searched | import("./shared").PressedPointerOnButton | import("./shared").IgnoredMouseClick | import("./shared").SuppressedSpaceScroll) => Message;
157
+ onSelectedItem?: (value: string) => Message;
157
158
  items: readonly Item[];
158
159
  itemToConfig: (item: Item, context: Readonly<{
159
160
  isActive: boolean;
@@ -200,6 +201,6 @@ export declare const view: <Message, Item>(config: Readonly<{
200
201
  isInvalid?: boolean;
201
202
  }>) => Html;
202
203
  /** Creates a memoized multi-select listbox view. Static config is captured in a closure;
203
- * only `model` and `toMessage` are compared per render via `createLazy`. */
204
- export declare const lazy: <Message, Item>(staticConfig: Omit<ViewConfig<Message, Item>, "model" | "toMessage">) => ((model: Model, toMessage: BaseViewConfig<Message, Item, Model>["toMessage"]) => Html);
204
+ * only `model` and `toParentMessage` are compared per render via `createLazy`. */
205
+ export declare const lazy: <Message, Item>(staticConfig: Omit<ViewConfig<Message, Item>, "model" | "toParentMessage" | "onSelectedItem">) => ((model: Model, toParentMessage: BaseViewConfig<Message, Item, Model>["toParentMessage"]) => Html);
205
206
  //# sourceMappingURL=multi.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"multi.d.ts","sourceRoot":"","sources":["../../../src/ui/listbox/multi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAAE,MAAM,IAAI,CAAC,EAAQ,MAAM,QAAQ,CAAA;AAEzD,OAAO,EAAE,KAAK,IAAI,EAAc,MAAM,YAAY,CAAA;AAElD,OAAO,EACL,KAAK,cAAc,EAEnB,KAAK,cAAc,EAIpB,MAAM,UAAU,CAAA;AAIjB,iKAAiK;AACjK,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;GAEjB,CAAA;AAED,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAA;AAIrC,6RAA6R;AAC7R,MAAM,MAAM,UAAU,GAAG,cAAc,GACrC,QAAQ,CAAC;IACP,aAAa,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CACtC,CAAC,CAAA;AAEJ,4HAA4H;AAC5H,eAAO,MAAM,IAAI,GAAI,QAAQ,UAAU,KAAG,KAGxC,CAAA;AAIF,wJAAwJ;AACxJ,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAMjB,CAAA;AAIF,sEAAsE;AACtE,MAAM,MAAM,UAAU,CAAC,OAAO,EAAE,IAAI,IAAI,cAAc,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,CAAA;AAE5E,0JAA0J;AAC1J,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAYf,CAAA;AAEF;6EAC6E;AAC7E,eAAO,MAAM,IAAI,GAAI,OAAO,EAAE,IAAI,EAChC,cAAc,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,WAAW,CAAC,KACnE,CAAC,CACF,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,cAAc,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,WAAW,CAAC,KACzD,IAAI,CAgBR,CAAA"}
1
+ {"version":3,"file":"multi.d.ts","sourceRoot":"","sources":["../../../src/ui/listbox/multi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAAE,MAAM,IAAI,CAAC,EAAQ,MAAM,QAAQ,CAAA;AAEzD,OAAO,EAAE,KAAK,IAAI,EAAc,MAAM,YAAY,CAAA;AAElD,OAAO,EACL,KAAK,cAAc,EAEnB,KAAK,cAAc,EAIpB,MAAM,UAAU,CAAA;AAIjB,iKAAiK;AACjK,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;GAEjB,CAAA;AAED,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAA;AAIrC,6RAA6R;AAC7R,MAAM,MAAM,UAAU,GAAG,cAAc,GACrC,QAAQ,CAAC;IACP,aAAa,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CACtC,CAAC,CAAA;AAEJ,4HAA4H;AAC5H,eAAO,MAAM,IAAI,GAAI,QAAQ,UAAU,KAAG,KAGxC,CAAA;AAIF,wJAAwJ;AACxJ,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAMjB,CAAA;AAIF,sEAAsE;AACtE,MAAM,MAAM,UAAU,CAAC,OAAO,EAAE,IAAI,IAAI,cAAc,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,CAAA;AAE5E,0JAA0J;AAC1J,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAYf,CAAA;AAEF;mFACmF;AACnF,eAAO,MAAM,IAAI,GAAI,OAAO,EAAE,IAAI,EAChC,cAAc,IAAI,CAChB,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,EACzB,OAAO,GAAG,iBAAiB,GAAG,gBAAgB,CAC/C,KACA,CAAC,CACF,KAAK,EAAE,KAAK,EACZ,eAAe,EAAE,cAAc,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,iBAAiB,CAAC,KACrE,IAAI,CAoBR,CAAA"}
@@ -25,12 +25,12 @@ export const view = makeView({
25
25
  ariaMultiSelectable: true,
26
26
  });
27
27
  /** Creates a memoized multi-select listbox view. Static config is captured in a closure;
28
- * only `model` and `toMessage` are compared per render via `createLazy`. */
28
+ * only `model` and `toParentMessage` are compared per render via `createLazy`. */
29
29
  export const lazy = (staticConfig) => {
30
30
  const lazyView = createLazy();
31
- return (model, toMessage) => lazyView((currentModel, currentToMessage) => view({
31
+ return (model, toParentMessage) => lazyView((currentModel, currentToMessage) => view({
32
32
  ...staticConfig,
33
33
  model: currentModel,
34
- toMessage: currentToMessage,
35
- }), [model, toMessage]);
34
+ toParentMessage: currentToMessage,
35
+ }), [model, toParentMessage]);
36
36
  };
@@ -1,7 +1,7 @@
1
- export { init, update, view, lazy, Model } from './single';
2
- export { Message, Orientation } from './shared';
1
+ export { init, update, selectItem, view, lazy, Model } from './single';
2
+ export { Message, Orientation, SelectedItem, CompletedLockScroll, CompletedUnlockScroll, CompletedSetupInert, CompletedTeardownInert, CompletedFocusButton, CompletedFocusItems, CompletedScrollIntoView, CompletedClickItem, ClearedSearch, AdvancedTransitionFrame, EndedTransition, DetectedButtonMovement, RequestFrame, LockScroll, UnlockScroll, InertOthers, RestoreInert, FocusButton, FocusItems, ScrollIntoView, ClickItem, DelayClearSearch, WaitForTransitions, DetectMovementOrTransitionEnd, } from './shared';
3
3
  export { TransitionState } from '../transition';
4
- export type { ActivationTrigger, Opened, Closed, ClosedByTab, ActivatedItem, DeactivatedItem, SelectedItem, MovedPointerOverItem, RequestedItemClick, Searched, ClearedSearch, PressedPointerOnButton, DetectedButtonMovement, CompletedLockScroll, CompletedUnlockScroll, CompletedSetupInert, CompletedTeardownInert, CompletedFocusButton, CompletedFocusItems, CompletedScrollIntoView, CompletedClickItem, IgnoredMouseClick, SuppressedSpaceScroll, AdvancedTransitionFrame, EndedTransition, ItemConfig, GroupHeading, } from './shared';
4
+ export type { ActivationTrigger, Opened, Closed, ClosedByTab, ActivatedItem, DeactivatedItem, MovedPointerOverItem, RequestedItemClick, Searched, PressedPointerOnButton, IgnoredMouseClick, SuppressedSpaceScroll, ItemConfig, GroupHeading, } from './shared';
5
5
  export type { InitConfig, ViewConfig } from './single';
6
6
  export type { AnchorConfig } from '../anchor';
7
7
  export * as Multi from './multiPublic';
@@ -1 +1 @@
1
- {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/ui/listbox/public.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,UAAU,CAAA;AAE1D,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAE/C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAE/C,YAAY,EACV,iBAAiB,EACjB,MAAM,EACN,MAAM,EACN,WAAW,EACX,aAAa,EACb,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,kBAAkB,EAClB,QAAQ,EACR,aAAa,EACb,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACnB,uBAAuB,EACvB,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,EACvB,eAAe,EACf,UAAU,EACV,YAAY,GACb,MAAM,UAAU,CAAA;AAEjB,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAEtD,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAE7C,OAAO,KAAK,KAAK,MAAM,eAAe,CAAA"}
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/ui/listbox/public.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,UAAU,CAAA;AAEtE,OAAO,EACL,OAAO,EACP,WAAW,EACX,YAAY,EACZ,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACnB,uBAAuB,EACvB,kBAAkB,EAClB,aAAa,EACb,uBAAuB,EACvB,eAAe,EACf,sBAAsB,EACtB,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,WAAW,EACX,UAAU,EACV,cAAc,EACd,SAAS,EACT,gBAAgB,EAChB,kBAAkB,EAClB,6BAA6B,GAC9B,MAAM,UAAU,CAAA;AAEjB,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAE/C,YAAY,EACV,iBAAiB,EACjB,MAAM,EACN,MAAM,EACN,WAAW,EACX,aAAa,EACb,eAAe,EACf,oBAAoB,EACpB,kBAAkB,EAClB,QAAQ,EACR,sBAAsB,EACtB,iBAAiB,EACjB,qBAAqB,EACrB,UAAU,EACV,YAAY,GACb,MAAM,UAAU,CAAA;AAEjB,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAEtD,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAE7C,OAAO,KAAK,KAAK,MAAM,eAAe,CAAA"}
@@ -1,4 +1,4 @@
1
- export { init, update, view, lazy, Model } from './single';
2
- export { Message, Orientation } from './shared';
1
+ export { init, update, selectItem, view, lazy, Model } from './single';
2
+ export { Message, Orientation, SelectedItem, CompletedLockScroll, CompletedUnlockScroll, CompletedSetupInert, CompletedTeardownInert, CompletedFocusButton, CompletedFocusItems, CompletedScrollIntoView, CompletedClickItem, ClearedSearch, AdvancedTransitionFrame, EndedTransition, DetectedButtonMovement, RequestFrame, LockScroll, UnlockScroll, InertOthers, RestoreInert, FocusButton, FocusItems, ScrollIntoView, ClickItem, DelayClearSearch, WaitForTransitions, DetectMovementOrTransitionEnd, } from './shared';
3
3
  export { TransitionState } from '../transition';
4
4
  export * as Multi from './multiPublic';