@spectral_labs/ui 1.6.1 → 1.8.0-next.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 (163) hide show
  1. package/LICENSE +21 -0
  2. package/THIRD_PARTY_NOTICES.md +201 -0
  3. package/dist/components/command/command.svelte.d.ts +30 -0
  4. package/dist/components/command/command.svelte.d.ts.map +1 -1
  5. package/dist/components/command/command.svelte.js +85 -4
  6. package/dist/components/command/components/command-group.svelte +25 -15
  7. package/dist/components/command/components/command-group.svelte.d.ts.map +1 -1
  8. package/dist/components/command/components/command-input.svelte +54 -5
  9. package/dist/components/command/components/command-input.svelte.d.ts +1 -1
  10. package/dist/components/command/components/command-input.svelte.d.ts.map +1 -1
  11. package/dist/components/command/components/command-list.svelte +22 -3
  12. package/dist/components/command/components/command-list.svelte.d.ts.map +1 -1
  13. package/dist/components/command/components/command-root.svelte +43 -4
  14. package/dist/components/command/components/command-root.svelte.d.ts.map +1 -1
  15. package/dist/components/command/index.d.ts +1 -0
  16. package/dist/components/command/index.d.ts.map +1 -1
  17. package/dist/components/command/types.d.ts +59 -4
  18. package/dist/components/command/types.d.ts.map +1 -1
  19. package/package.json +8 -2
  20. package/dist/components/__tests__/overlay-scrim-source.test.js +0 -134
  21. package/dist/components/accordion/__tests__/AccordionTest.svelte +0 -31
  22. package/dist/components/accordion/__tests__/accordion.test.svelte.js +0 -139
  23. package/dist/components/alert-dialog/__tests__/AlertDialogTest.svelte +0 -28
  24. package/dist/components/alert-dialog/__tests__/alert-dialog.a11y.test.js +0 -42
  25. package/dist/components/alert-dialog/__tests__/alert-dialog.integration.test.svelte.js +0 -51
  26. package/dist/components/alert-dialog/__tests__/alert-dialog.test.svelte.js +0 -113
  27. package/dist/components/app-bar/__tests__/app-bar.test.svelte.js +0 -30
  28. package/dist/components/aspect-ratio/__tests__/aspect-ratio.test.svelte.js +0 -22
  29. package/dist/components/avatar/__tests__/avatar.test.svelte.js +0 -26
  30. package/dist/components/badge/__tests__/badge.test.svelte.js +0 -30
  31. package/dist/components/bottom-sheet/__tests__/BottomSheetTest.svelte +0 -22
  32. package/dist/components/bottom-sheet/__tests__/bottom-sheet.test.svelte.js +0 -83
  33. package/dist/components/button/__tests__/button.test.svelte.js +0 -63
  34. package/dist/components/calendar/__tests__/CalendarTest.svelte +0 -56
  35. package/dist/components/calendar/__tests__/calendar.test.svelte.js +0 -190
  36. package/dist/components/card/__tests__/card.test.svelte.js +0 -30
  37. package/dist/components/checkbox/__tests__/checkbox.test.svelte.js +0 -44
  38. package/dist/components/chips/__tests__/chips.test.svelte.js +0 -26
  39. package/dist/components/collapsible/__tests__/CollapsibleTest.svelte +0 -18
  40. package/dist/components/collapsible/__tests__/collapsible.test.svelte.js +0 -125
  41. package/dist/components/combobox/__tests__/ComboboxTest.svelte +0 -40
  42. package/dist/components/combobox/__tests__/combobox.test.svelte.js +0 -255
  43. package/dist/components/command/__tests__/CommandTest.svelte +0 -77
  44. package/dist/components/command/__tests__/command-item-passthrough.test.svelte.js +0 -284
  45. package/dist/components/command/__tests__/command.a11y.test.js +0 -30
  46. package/dist/components/command/__tests__/command.integration.test.svelte.js +0 -68
  47. package/dist/components/command/__tests__/command.test.svelte.js +0 -230
  48. package/dist/components/context-menu/__tests__/ContextMenuNonInteractiveTest.svelte +0 -32
  49. package/dist/components/context-menu/__tests__/ContextMenuTest.svelte +0 -25
  50. package/dist/components/context-menu/__tests__/context-menu.test.svelte.js +0 -141
  51. package/dist/components/date-field/__tests__/DateFieldTest.svelte +0 -20
  52. package/dist/components/date-field/__tests__/date-field.test.svelte.js +0 -139
  53. package/dist/components/date-picker/__tests__/DatePickerTest.svelte +0 -20
  54. package/dist/components/date-picker/__tests__/date-picker.test.svelte.js +0 -190
  55. package/dist/components/date-range-field/__tests__/DateRangeFieldTest.svelte +0 -20
  56. package/dist/components/date-range-field/__tests__/date-range-field.test.svelte.js +0 -130
  57. package/dist/components/date-range-picker/__tests__/DateRangePickerTest.svelte +0 -18
  58. package/dist/components/date-range-picker/__tests__/date-range-picker.test.svelte.js +0 -156
  59. package/dist/components/dialog/__tests__/DialogTest.svelte +0 -34
  60. package/dist/components/dialog/__tests__/dialog.test.svelte.js +0 -184
  61. package/dist/components/drop-zone/__tests__/drop-zone.test.svelte.js +0 -26
  62. package/dist/components/dropdown-menu/__tests__/DropdownMenuRadioTest.svelte +0 -90
  63. package/dist/components/dropdown-menu/__tests__/DropdownMenuTest.svelte +0 -71
  64. package/dist/components/dropdown-menu/__tests__/dropdown-menu-radio-group.test.svelte.js +0 -306
  65. package/dist/components/dropdown-menu/__tests__/dropdown-menu.test.svelte.js +0 -567
  66. package/dist/components/empty-state/__tests__/empty-state.test.svelte.js +0 -26
  67. package/dist/components/fab/__tests__/fab.test.svelte.js +0 -30
  68. package/dist/components/field/__tests__/FieldTest.svelte +0 -26
  69. package/dist/components/field/__tests__/field.test.svelte.js +0 -74
  70. package/dist/components/grid-list/__tests__/GridListTest.svelte +0 -46
  71. package/dist/components/grid-list/__tests__/grid-list.test.svelte.js +0 -231
  72. package/dist/components/hover-card/__tests__/HoverCardTest.svelte +0 -30
  73. package/dist/components/hover-card/__tests__/hover-card.test.svelte.js +0 -236
  74. package/dist/components/indicator/__tests__/indicator.test.svelte.js +0 -30
  75. package/dist/components/input/__tests__/input.test.svelte.js +0 -67
  76. package/dist/components/label/__tests__/label.test.svelte.js +0 -22
  77. package/dist/components/language-select/__tests__/language-select.test.svelte.js +0 -199
  78. package/dist/components/language-select/__tests__/languages.test.js +0 -87
  79. package/dist/components/link-preview/__tests__/LinkPreviewTest.svelte +0 -37
  80. package/dist/components/link-preview/__tests__/link-preview.a11y.test.js +0 -28
  81. package/dist/components/link-preview/__tests__/link-preview.integration.test.svelte.js +0 -54
  82. package/dist/components/link-preview/__tests__/link-preview.test.svelte.js +0 -215
  83. package/dist/components/list/__tests__/list.test.svelte.js +0 -22
  84. package/dist/components/menubar/__tests__/MenubarTest.svelte +0 -52
  85. package/dist/components/menubar/__tests__/menubar.a11y.test.js +0 -28
  86. package/dist/components/menubar/__tests__/menubar.integration.test.svelte.js +0 -57
  87. package/dist/components/menubar/__tests__/menubar.test.svelte.js +0 -328
  88. package/dist/components/meter/__tests__/meter.test.svelte.js +0 -26
  89. package/dist/components/nav-bar/__tests__/nav-bar.test.svelte.js +0 -23
  90. package/dist/components/nav-drawer/__tests__/nav-drawer.test.svelte.js +0 -28
  91. package/dist/components/nav-rail/__tests__/nav-rail.test.svelte.js +0 -28
  92. package/dist/components/pagination/__tests__/pagination.test.svelte.js +0 -26
  93. package/dist/components/pin-input/__tests__/pin-input.test.svelte.js +0 -71
  94. package/dist/components/popover/__tests__/PopoverTest.svelte +0 -27
  95. package/dist/components/popover/__tests__/popover.test.svelte.js +0 -196
  96. package/dist/components/progress/__tests__/progress.test.svelte.js +0 -32
  97. package/dist/components/radio-group/__tests__/radio-group.test.svelte.js +0 -22
  98. package/dist/components/range-calendar/__tests__/RangeCalendarTest.svelte +0 -23
  99. package/dist/components/range-calendar/__tests__/range-calendar.test.svelte.js +0 -105
  100. package/dist/components/rating-group/__tests__/rating-group.test.svelte.js +0 -26
  101. package/dist/components/scroll-area/__tests__/scroll-area.test.svelte.js +0 -34
  102. package/dist/components/search-field/__tests__/SearchFieldTest.svelte +0 -34
  103. package/dist/components/search-field/__tests__/search-field.test.svelte.js +0 -118
  104. package/dist/components/select/__tests__/SelectLabelPersistenceTest.svelte +0 -31
  105. package/dist/components/select/__tests__/SelectTest.svelte +0 -33
  106. package/dist/components/select/__tests__/select.test.svelte.js +0 -221
  107. package/dist/components/separator/__tests__/separator.test.svelte.js +0 -39
  108. package/dist/components/sheet/__tests__/SheetTest.svelte +0 -34
  109. package/dist/components/sheet/__tests__/sheet.test.svelte.js +0 -193
  110. package/dist/components/side-sheet/__tests__/side-sheet.test.svelte.js +0 -138
  111. package/dist/components/sidebar/__tests__/SidebarFullTest.svelte +0 -45
  112. package/dist/components/sidebar/__tests__/SidebarTest.svelte +0 -9
  113. package/dist/components/sidebar/__tests__/sidebar.test.svelte.js +0 -186
  114. package/dist/components/simple-dialog/__tests__/SimpleDialogTest.svelte +0 -40
  115. package/dist/components/simple-dialog/__tests__/simple-dialog.test.svelte.js +0 -50
  116. package/dist/components/simple-tooltip/__tests__/SimpleTooltipTest.svelte +0 -19
  117. package/dist/components/simple-tooltip/__tests__/simple-tooltip.test.svelte.js +0 -61
  118. package/dist/components/slider/__tests__/slider.test.svelte.js +0 -42
  119. package/dist/components/sortable-list/__tests__/NestedSortableListTest.svelte +0 -49
  120. package/dist/components/sortable-list/__tests__/SortableListTest.svelte +0 -42
  121. package/dist/components/sortable-list/__tests__/sortable-list.nested.test.svelte.js +0 -112
  122. package/dist/components/sortable-list/__tests__/sortable-list.test.svelte.js +0 -175
  123. package/dist/components/splitter/__tests__/splitter.test.svelte.js +0 -26
  124. package/dist/components/switch/__tests__/switch.test.svelte.js +0 -44
  125. package/dist/components/table/__tests__/table.test.svelte.js +0 -22
  126. package/dist/components/tabs/__tests__/TabsTest.svelte +0 -32
  127. package/dist/components/tabs/__tests__/tabs.test.svelte.js +0 -227
  128. package/dist/components/textarea/__tests__/textarea.test.svelte.js +0 -55
  129. package/dist/components/time-field/__tests__/TimeFieldTest.svelte +0 -20
  130. package/dist/components/time-field/__tests__/time-field.test.svelte.js +0 -100
  131. package/dist/components/time-range-field/__tests__/TimeRangeFieldTest.svelte +0 -20
  132. package/dist/components/time-range-field/__tests__/time-range-field.test.svelte.js +0 -124
  133. package/dist/components/toast/__tests__/toast.test.svelte.js +0 -46
  134. package/dist/components/toggle/__tests__/toggle.test.svelte.js +0 -38
  135. package/dist/components/toggle-group/__tests__/toggle-group.test.svelte.js +0 -22
  136. package/dist/components/toolbar/__tests__/ToolbarCompositionTest.svelte +0 -18
  137. package/dist/components/toolbar/__tests__/ToolbarTabstopTest.svelte +0 -10
  138. package/dist/components/toolbar/__tests__/toolbar.test.svelte.js +0 -63
  139. package/dist/components/tooltip/__tests__/TooltipTest.svelte +0 -22
  140. package/dist/components/tooltip/__tests__/tooltip.test.svelte.js +0 -225
  141. package/dist/components/tree/__tests__/TreeLabelContentTest.svelte +0 -21
  142. package/dist/components/tree/__tests__/TreeTest.svelte +0 -24
  143. package/dist/components/tree/__tests__/tree.test.svelte.js +0 -229
  144. package/dist/components/virtualizer/__tests__/waterfall-layout.test.js +0 -82
  145. package/dist/internal/announcer/__tests__/announcer.test.js +0 -42
  146. package/dist/internal/dismissible-layer/__tests__/dismissible-layer.test.js +0 -196
  147. package/dist/internal/drag-drop/__tests__/auto-scroll.test.js +0 -104
  148. package/dist/internal/drag-drop/__tests__/drag-session.test.svelte.js +0 -803
  149. package/dist/internal/drag-drop/__tests__/drag-source.test.svelte.js +0 -130
  150. package/dist/internal/drag-drop/__tests__/drop-delegate.test.js +0 -223
  151. package/dist/internal/drag-drop/__tests__/types.test.js +0 -20
  152. package/dist/internal/escape-layer/__tests__/escape-layer.test.js +0 -113
  153. package/dist/internal/focus-scope/__tests__/focus-scope.test.js +0 -225
  154. package/dist/internal/grace-area/__tests__/grace-area.test.js +0 -67
  155. package/dist/internal/helpers/__tests__/helpers.test.js +0 -123
  156. package/dist/internal/portal/__tests__/PortalTest.svelte +0 -21
  157. package/dist/internal/portal/__tests__/portal.test.js +0 -29
  158. package/dist/internal/portal/__tests__/portal.test.svelte.js +0 -57
  159. package/dist/internal/scroll-lock/__tests__/scroll-lock.test.js +0 -160
  160. package/dist/internal/typeahead/__tests__/typeahead.test.js +0 -61
  161. package/src/themes/__tests__/carbon-dark-contrast.test.ts +0 -170
  162. package/src/themes/__tests__/generated-css-drift.test.ts +0 -53
  163. package/src/themes/__tests__/scrim-opaque.test.ts +0 -52
@@ -1,196 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
2
- import { DismissibleLayerState, resetDismissibleLayerStack } from '../dismissible-layer.svelte.js';
3
- // jsdom does not define PointerEvent — polyfill it for tests
4
- if (typeof globalThis.PointerEvent === 'undefined') {
5
- // @ts-expect-error — minimal polyfill for testing
6
- globalThis.PointerEvent = class PointerEvent extends MouseEvent {
7
- constructor(type, init) {
8
- super(type, init);
9
- }
10
- };
11
- }
12
- function createElement(rect) {
13
- const el = document.createElement('div');
14
- document.body.appendChild(el);
15
- // Override getBoundingClientRect for rect-based inside checks
16
- if (rect) {
17
- el.getBoundingClientRect = () => ({
18
- x: rect.x ?? 0,
19
- y: rect.y ?? 0,
20
- width: rect.width ?? 100,
21
- height: rect.height ?? 100,
22
- top: rect.top ?? 0,
23
- right: rect.right ?? 100,
24
- bottom: rect.bottom ?? 100,
25
- left: rect.left ?? 0,
26
- toJSON: () => ({}),
27
- });
28
- }
29
- return el;
30
- }
31
- function pointerDownOutside(x = 500, y = 500) {
32
- const event = new PointerEvent('pointerdown', {
33
- bubbles: true,
34
- clientX: x,
35
- clientY: y,
36
- });
37
- document.dispatchEvent(event);
38
- }
39
- function pointerDownOn(element) {
40
- const event = new PointerEvent('pointerdown', {
41
- bubbles: true,
42
- clientX: 0,
43
- clientY: 0,
44
- });
45
- element.dispatchEvent(event);
46
- }
47
- describe('dismissibleLayerState', () => {
48
- beforeEach(() => {
49
- resetDismissibleLayerStack();
50
- });
51
- afterEach(() => {
52
- resetDismissibleLayerStack();
53
- // Clean up any DOM elements
54
- document.body.innerHTML = '';
55
- });
56
- it('calls onInteractOutside when clicking outside the element', () => {
57
- const el = createElement({ top: 0, left: 0, right: 100, bottom: 100 });
58
- const onInteractOutside = vi.fn();
59
- const props = {
60
- enabled: true,
61
- element: el,
62
- onInteractOutside,
63
- behavior: 'close',
64
- };
65
- const layer = new DismissibleLayerState(props);
66
- layer.mount();
67
- // Click outside the element's bounds
68
- pointerDownOutside(500, 500);
69
- expect(onInteractOutside).toHaveBeenCalledOnce();
70
- expect(onInteractOutside).toHaveBeenCalledWith(expect.objectContaining({ type: 'pointerdown' }));
71
- layer.unmount();
72
- });
73
- it('does NOT call onInteractOutside when clicking inside the element', () => {
74
- const el = createElement();
75
- const onInteractOutside = vi.fn();
76
- const props = {
77
- enabled: true,
78
- element: el,
79
- onInteractOutside,
80
- behavior: 'close',
81
- };
82
- const layer = new DismissibleLayerState(props);
83
- layer.mount();
84
- // Click on the element itself (DOM containment check)
85
- pointerDownOn(el);
86
- expect(onInteractOutside).not.toHaveBeenCalled();
87
- layer.unmount();
88
- });
89
- describe('stack behavior', () => {
90
- it('only topmost layer handles the event', () => {
91
- const el1 = createElement({ top: 0, left: 0, right: 100, bottom: 100 });
92
- const el2 = createElement({ top: 200, left: 200, right: 300, bottom: 300 });
93
- const onInteractOutside1 = vi.fn();
94
- const onInteractOutside2 = vi.fn();
95
- const layer1 = new DismissibleLayerState({
96
- enabled: true,
97
- element: el1,
98
- onInteractOutside: onInteractOutside1,
99
- behavior: 'close',
100
- });
101
- const layer2 = new DismissibleLayerState({
102
- enabled: true,
103
- element: el2,
104
- onInteractOutside: onInteractOutside2,
105
- behavior: 'close',
106
- });
107
- layer1.mount();
108
- layer2.mount();
109
- // Click outside both elements
110
- pointerDownOutside(500, 500);
111
- // Only topmost (layer2) should have been called
112
- expect(onInteractOutside2).toHaveBeenCalledOnce();
113
- expect(onInteractOutside1).not.toHaveBeenCalled();
114
- layer2.unmount();
115
- layer1.unmount();
116
- });
117
- });
118
- describe('ignore behavior', () => {
119
- it('respects ignore behavior — does not fire callback', () => {
120
- const el = createElement({ top: 0, left: 0, right: 100, bottom: 100 });
121
- const onInteractOutside = vi.fn();
122
- const layer = new DismissibleLayerState({
123
- enabled: true,
124
- element: el,
125
- onInteractOutside,
126
- behavior: 'ignore',
127
- });
128
- layer.mount();
129
- pointerDownOutside(500, 500);
130
- expect(onInteractOutside).not.toHaveBeenCalled();
131
- layer.unmount();
132
- });
133
- });
134
- describe('defer-otherwise-close behavior', () => {
135
- it('falls through to bottom layer', () => {
136
- const el1 = createElement({ top: 0, left: 0, right: 100, bottom: 100 });
137
- const el2 = createElement({ top: 200, left: 200, right: 300, bottom: 300 });
138
- const onInteractOutside1 = vi.fn();
139
- const onInteractOutside2 = vi.fn();
140
- const layer1 = new DismissibleLayerState({
141
- enabled: true,
142
- element: el1,
143
- onInteractOutside: onInteractOutside1,
144
- behavior: 'defer-otherwise-close',
145
- });
146
- const layer2 = new DismissibleLayerState({
147
- enabled: true,
148
- element: el2,
149
- onInteractOutside: onInteractOutside2,
150
- behavior: 'defer-otherwise-close',
151
- });
152
- layer1.mount();
153
- layer2.mount();
154
- // Click outside both elements
155
- pointerDownOutside(500, 500);
156
- // Top layer defers, bottom layer handles it
157
- expect(onInteractOutside2).not.toHaveBeenCalled();
158
- expect(onInteractOutside1).toHaveBeenCalledOnce();
159
- layer2.unmount();
160
- layer1.unmount();
161
- });
162
- });
163
- describe('cleanup', () => {
164
- it('cleans up when all layers unmount', () => {
165
- const el = createElement({ top: 0, left: 0, right: 100, bottom: 100 });
166
- const onInteractOutside = vi.fn();
167
- const layer = new DismissibleLayerState({
168
- enabled: true,
169
- element: el,
170
- onInteractOutside,
171
- behavior: 'close',
172
- });
173
- layer.mount();
174
- layer.unmount();
175
- // After unmount, clicking should NOT trigger anything
176
- pointerDownOutside(500, 500);
177
- expect(onInteractOutside).not.toHaveBeenCalled();
178
- });
179
- });
180
- describe('enabled prop', () => {
181
- it('respects enabled=false — does not register in stack', () => {
182
- const el = createElement({ top: 0, left: 0, right: 100, bottom: 100 });
183
- const onInteractOutside = vi.fn();
184
- const layer = new DismissibleLayerState({
185
- enabled: false,
186
- element: el,
187
- onInteractOutside,
188
- behavior: 'close',
189
- });
190
- layer.mount();
191
- pointerDownOutside(500, 500);
192
- expect(onInteractOutside).not.toHaveBeenCalled();
193
- layer.unmount();
194
- });
195
- });
196
- });
@@ -1,104 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
2
- import { AutoScroll } from '../auto-scroll.svelte.js';
3
- function createScrollableElement(opts = {}) {
4
- const el = document.createElement('div');
5
- Object.defineProperty(el, 'getBoundingClientRect', {
6
- value: () => ({
7
- top: 0,
8
- left: 0,
9
- bottom: opts.height ?? 400,
10
- right: opts.width ?? 400,
11
- width: opts.width ?? 400,
12
- height: opts.height ?? 400,
13
- x: 0,
14
- y: 0,
15
- toJSON() { },
16
- }),
17
- });
18
- // Make it scrollable
19
- let _scrollTop = opts.scrollTop ?? 0;
20
- let _scrollLeft = opts.scrollLeft ?? 0;
21
- Object.defineProperty(el, 'scrollHeight', { value: opts.scrollHeight ?? 800 });
22
- Object.defineProperty(el, 'scrollWidth', { value: opts.scrollWidth ?? 800 });
23
- Object.defineProperty(el, 'clientHeight', { value: opts.height ?? 400 });
24
- Object.defineProperty(el, 'clientWidth', { value: opts.width ?? 400 });
25
- Object.defineProperty(el, 'scrollTop', {
26
- get: () => _scrollTop,
27
- set: (v) => {
28
- _scrollTop = v;
29
- },
30
- });
31
- Object.defineProperty(el, 'scrollLeft', {
32
- get: () => _scrollLeft,
33
- set: (v) => {
34
- _scrollLeft = v;
35
- },
36
- });
37
- // Mock getComputedStyle
38
- vi.spyOn(window, 'getComputedStyle').mockReturnValue({
39
- overflowY: opts.overflowY ?? 'auto',
40
- overflowX: opts.overflowX ?? 'auto',
41
- });
42
- return el;
43
- }
44
- describe('autoScroll', () => {
45
- let autoScroll;
46
- beforeEach(() => {
47
- autoScroll = new AutoScroll();
48
- vi.useFakeTimers();
49
- });
50
- afterEach(() => {
51
- autoScroll.teardown();
52
- vi.restoreAllMocks();
53
- vi.useRealTimers();
54
- });
55
- it('creates without error', () => {
56
- expect(autoScroll).toBeDefined();
57
- });
58
- it('does not throw when moving without setup', () => {
59
- expect(() => autoScroll.move(100, 100)).not.toThrow();
60
- });
61
- it('does not throw when tearing down without setup', () => {
62
- expect(() => autoScroll.teardown()).not.toThrow();
63
- });
64
- it('sets up with a scrollable element', () => {
65
- const el = createScrollableElement();
66
- expect(() => autoScroll.setup(el)).not.toThrow();
67
- });
68
- it('detects top edge and would scroll up', () => {
69
- const el = createScrollableElement({ scrollTop: 100 });
70
- autoScroll.setup(el);
71
- // Point near top edge (within 30px)
72
- autoScroll.move(200, 10);
73
- // Run one animation frame
74
- vi.advanceTimersByTime(16);
75
- // scrollTop should have decreased
76
- expect(el.scrollTop).toBeLessThan(100);
77
- });
78
- it('detects bottom edge and would scroll down', () => {
79
- const el = createScrollableElement({ height: 400, scrollHeight: 800, scrollTop: 0 });
80
- autoScroll.setup(el);
81
- // Point near bottom edge
82
- autoScroll.move(200, 390);
83
- vi.advanceTimersByTime(16);
84
- expect(el.scrollTop).toBeGreaterThan(0);
85
- });
86
- it('does not scroll when pointer is in center', () => {
87
- const el = createScrollableElement({ scrollTop: 100 });
88
- autoScroll.setup(el);
89
- // Point in center
90
- autoScroll.move(200, 200);
91
- vi.advanceTimersByTime(16);
92
- expect(el.scrollTop).toBe(100); // unchanged
93
- });
94
- it('stops scrolling on teardown', () => {
95
- const el = createScrollableElement({ scrollTop: 100 });
96
- autoScroll.setup(el);
97
- autoScroll.move(200, 10); // trigger scroll
98
- autoScroll.teardown();
99
- const scrollBefore = el.scrollTop;
100
- vi.advanceTimersByTime(100);
101
- // Should not have changed after teardown (or only 1 frame)
102
- expect(Math.abs(el.scrollTop - scrollBefore)).toBeLessThanOrEqual(8); // max 1 frame of scroll
103
- });
104
- });