@blotch/dolan 22.2.3 → 22.2.5

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 (227) hide show
  1. package/dist/commands/add.js +9 -1
  2. package/dist/commands/add.js.map +1 -1
  3. package/dist/commands/add.test.js +38 -3
  4. package/dist/commands/add.test.js.map +1 -1
  5. package/dist/commands/doctor.js +258 -21
  6. package/dist/commands/doctor.js.map +1 -1
  7. package/dist/commands/doctor.test.js +425 -11
  8. package/dist/commands/doctor.test.js.map +1 -1
  9. package/dist/commands/init.d.ts +2 -2
  10. package/dist/commands/init.js +38 -18
  11. package/dist/commands/init.js.map +1 -1
  12. package/dist/commands/init.test.js +105 -2
  13. package/dist/commands/init.test.js.map +1 -1
  14. package/dist/commands/theme.js +1 -1
  15. package/dist/commands/theme.js.map +1 -1
  16. package/dist/commands/update.d.ts +7 -0
  17. package/dist/commands/update.js +194 -50
  18. package/dist/commands/update.js.map +1 -1
  19. package/dist/commands/update.test.js +570 -3
  20. package/dist/commands/update.test.js.map +1 -1
  21. package/dist/lockfile.d.ts +17 -0
  22. package/dist/lockfile.js +56 -1
  23. package/dist/lockfile.js.map +1 -1
  24. package/dist/lockfile.test.d.ts +1 -0
  25. package/dist/lockfile.test.js +65 -0
  26. package/dist/lockfile.test.js.map +1 -0
  27. package/dist/registry.d.ts +6 -0
  28. package/dist/registry.js +119 -11
  29. package/dist/registry.js.map +1 -1
  30. package/dist/registry.test.js +61 -6
  31. package/dist/registry.test.js.map +1 -1
  32. package/dist/test-utils.d.ts +27 -0
  33. package/dist/test-utils.js +45 -1
  34. package/dist/test-utils.js.map +1 -1
  35. package/dist/testing/fire-lynx-event.d.ts +14 -0
  36. package/dist/testing/fire-lynx-event.js +19 -0
  37. package/dist/testing/fire-lynx-event.js.map +1 -0
  38. package/dist/testing/fire-lynx-event.test.d.ts +1 -0
  39. package/dist/testing/fire-lynx-event.test.js +44 -0
  40. package/dist/testing/fire-lynx-event.test.js.map +1 -0
  41. package/dist/testing/lynx-main-thread.d.ts +22 -0
  42. package/dist/testing/lynx-main-thread.js +11 -0
  43. package/dist/testing/lynx-main-thread.js.map +1 -0
  44. package/dist/testing/lynx-main-thread.test.d.ts +1 -0
  45. package/dist/testing/lynx-main-thread.test.js +24 -0
  46. package/dist/testing/lynx-main-thread.test.js.map +1 -0
  47. package/dist/testing/set-input-signal.d.ts +5 -4
  48. package/dist/testing/set-input-signal.js +5 -4
  49. package/dist/testing/set-input-signal.js.map +1 -1
  50. package/dist/ui/boolean-inputs.test.ts +76 -0
  51. package/dist/ui/components/accordion/accordion.test.ts +158 -144
  52. package/dist/ui/components/accordion/accordion.ts +19 -14
  53. package/dist/ui/components/action-sheet/action-sheet.test.ts +637 -183
  54. package/dist/ui/components/action-sheet/action-sheet.ts +339 -55
  55. package/dist/ui/components/action-sheet/index.ts +1 -0
  56. package/dist/ui/components/alert/alert.test.ts +67 -19
  57. package/dist/ui/components/alert/alert.ts +14 -16
  58. package/dist/ui/components/alert-dialog/alert-dialog.test.ts +740 -129
  59. package/dist/ui/components/alert-dialog/alert-dialog.ts +672 -58
  60. package/dist/ui/components/alert-dialog/index.ts +5 -0
  61. package/dist/ui/components/area-chart/area-chart.test.ts +81 -1
  62. package/dist/ui/components/area-chart/area-chart.ts +3 -2
  63. package/dist/ui/components/avatar/avatar.test.ts +89 -45
  64. package/dist/ui/components/badge/badge.test.ts +57 -23
  65. package/dist/ui/components/badge/badge.ts +14 -15
  66. package/dist/ui/components/bar-chart/bar-chart.test.ts +82 -1
  67. package/dist/ui/components/bottom-sheet/bottom-sheet.test.ts +1314 -273
  68. package/dist/ui/components/bottom-sheet/bottom-sheet.ts +1046 -119
  69. package/dist/ui/components/bottom-sheet/index.ts +7 -1
  70. package/dist/ui/components/button/button.test.ts +646 -2
  71. package/dist/ui/components/button/button.ts +443 -64
  72. package/dist/ui/components/button/index.ts +2 -0
  73. package/dist/ui/components/button-group/button-group.test.ts +528 -2
  74. package/dist/ui/components/button-group/button-group.ts +428 -70
  75. package/dist/ui/components/button-group/index.ts +3 -0
  76. package/dist/ui/components/candlestick-chart/candlestick-chart.test.ts +82 -1
  77. package/dist/ui/components/card/card.test.ts +97 -61
  78. package/dist/ui/components/card/card.ts +2 -1
  79. package/dist/ui/components/chart/chart-presets.test.ts +197 -1
  80. package/dist/ui/components/chart/chart-presets.ts +14 -7
  81. package/dist/ui/components/chart/chart-theme.ts +12 -0
  82. package/dist/ui/components/chart/chart.test.ts +1031 -0
  83. package/dist/ui/components/chart/chart.ts +66 -46
  84. package/dist/ui/components/checkbox/checkbox.test.ts +124 -42
  85. package/dist/ui/components/checkbox/checkbox.ts +25 -24
  86. package/dist/ui/components/collapsible/collapsible.test.ts +158 -81
  87. package/dist/ui/components/collapsible/collapsible.ts +21 -15
  88. package/dist/ui/components/context-menu/context-menu.test.ts +224 -0
  89. package/dist/ui/components/context-menu/context-menu.ts +110 -0
  90. package/dist/ui/components/context-menu/index.ts +1 -0
  91. package/dist/ui/components/dialog/dialog.test.ts +210 -152
  92. package/dist/ui/components/dialog/dialog.ts +35 -29
  93. package/dist/ui/components/dock/dock-scroll.test.ts +130 -0
  94. package/dist/ui/components/dock/dock-scroll.ts +142 -0
  95. package/dist/ui/components/dock/dock-search.test.ts +594 -0
  96. package/dist/ui/components/dock/dock.test.ts +752 -0
  97. package/dist/ui/components/dock/dock.ts +1438 -0
  98. package/dist/ui/components/dock/index.ts +2 -0
  99. package/dist/ui/components/dynamic-color/dynamic-color.test.ts +144 -0
  100. package/dist/ui/components/dynamic-color/dynamic-color.ts +146 -0
  101. package/dist/ui/components/dynamic-color/index.ts +5 -0
  102. package/dist/ui/components/empty-state/empty-state.test.ts +28 -39
  103. package/dist/ui/components/glass/concentric-radius.test.ts +13 -0
  104. package/dist/ui/components/glass/concentric-radius.ts +17 -0
  105. package/dist/ui/components/glass/glass-design.test.ts +78 -0
  106. package/dist/ui/components/glass/glass-design.ts +119 -0
  107. package/dist/ui/components/glass/glass.test.ts +376 -0
  108. package/dist/ui/components/glass/glass.ts +430 -0
  109. package/dist/ui/components/glass/index.ts +19 -0
  110. package/dist/ui/components/icon/icon-theme.test.ts +64 -0
  111. package/dist/ui/components/icon/icon-theme.ts +70 -16
  112. package/dist/ui/components/icon/icon.test.ts +52 -41
  113. package/dist/ui/components/input/input.test.ts +178 -101
  114. package/dist/ui/components/input/input.ts +17 -13
  115. package/dist/ui/components/label/label.test.ts +11 -24
  116. package/dist/ui/components/label/label.ts +8 -2
  117. package/dist/ui/components/line-chart/line-chart.test.ts +76 -1
  118. package/dist/ui/components/line-chart/line-chart.ts +3 -2
  119. package/dist/ui/components/list/list.test.ts +80 -49
  120. package/dist/ui/components/list/list.ts +5 -4
  121. package/dist/ui/components/menu/index.ts +25 -0
  122. package/dist/ui/components/menu/menu-placement.test.ts +153 -0
  123. package/dist/ui/components/menu/menu-placement.ts +159 -0
  124. package/dist/ui/components/menu/menu-popup.test.ts +636 -0
  125. package/dist/ui/components/menu/menu-popup.ts +565 -0
  126. package/dist/ui/components/menu/menu.test.ts +523 -0
  127. package/dist/ui/components/menu/menu.ts +455 -0
  128. package/dist/ui/components/nav-drawer/nav-drawer.test.ts +425 -260
  129. package/dist/ui/components/nav-drawer/nav-drawer.ts +75 -58
  130. package/dist/ui/components/navigation-bar/index.ts +1 -0
  131. package/dist/ui/components/navigation-bar/navigation-bar.test.ts +425 -0
  132. package/dist/ui/components/navigation-bar/navigation-bar.ts +411 -0
  133. package/dist/ui/components/pagination/pagination.test.ts +136 -86
  134. package/dist/ui/components/popover/index.ts +9 -0
  135. package/dist/ui/components/popover/popover-panel.test.ts +735 -0
  136. package/dist/ui/components/popover/popover-panel.ts +603 -0
  137. package/dist/ui/components/popover/popover.test.ts +286 -0
  138. package/dist/ui/components/popover/popover.ts +207 -0
  139. package/dist/ui/components/progress/progress.test.ts +102 -46
  140. package/dist/ui/components/progress/progress.ts +54 -55
  141. package/dist/ui/components/radio-group/radio-group.test.ts +128 -83
  142. package/dist/ui/components/radio-group/radio-group.ts +26 -25
  143. package/dist/ui/components/scatter-chart/scatter-chart.test.ts +74 -1
  144. package/dist/ui/components/scroll-area/scroll-area.test.ts +72 -36
  145. package/dist/ui/components/scroll-area/scroll-area.ts +4 -3
  146. package/dist/ui/components/search-field/index.ts +15 -0
  147. package/dist/ui/components/search-field/keyboard.test.ts +147 -0
  148. package/dist/ui/components/search-field/keyboard.ts +123 -0
  149. package/dist/ui/components/search-field/search-field.test.ts +549 -0
  150. package/dist/ui/components/search-field/search-field.ts +628 -0
  151. package/dist/ui/components/segmented-control/index.ts +8 -0
  152. package/dist/ui/components/segmented-control/segmented-control.test.ts +861 -0
  153. package/dist/ui/components/segmented-control/segmented-control.ts +884 -0
  154. package/dist/ui/components/select/select.test.ts +138 -78
  155. package/dist/ui/components/select/select.ts +19 -12
  156. package/dist/ui/components/separator/separator.test.ts +18 -17
  157. package/dist/ui/components/sheet/sheet.test.ts +151 -11
  158. package/dist/ui/components/sheet/sheet.ts +68 -5
  159. package/dist/ui/components/skeleton/skeleton.test.ts +24 -7
  160. package/dist/ui/components/skeleton/skeleton.ts +10 -16
  161. package/dist/ui/components/slider/index.ts +1 -0
  162. package/dist/ui/components/slider/slider.test.ts +695 -0
  163. package/dist/ui/components/slider/slider.ts +901 -0
  164. package/dist/ui/components/spinner/spinner.test.ts +64 -46
  165. package/dist/ui/components/spinner/spinner.ts +16 -19
  166. package/dist/ui/components/switch/index.ts +1 -1
  167. package/dist/ui/components/switch/switch.test.ts +534 -48
  168. package/dist/ui/components/switch/switch.ts +613 -48
  169. package/dist/ui/components/tab-bar/index.ts +1 -0
  170. package/dist/ui/components/tab-bar/tab-bar.test.ts +280 -0
  171. package/dist/ui/components/tab-bar/tab-bar.ts +230 -0
  172. package/dist/ui/components/tabs/index.ts +7 -1
  173. package/dist/ui/components/tabs/tabs.test.ts +484 -150
  174. package/dist/ui/components/tabs/tabs.ts +344 -149
  175. package/dist/ui/components/textarea/textarea.test.ts +206 -100
  176. package/dist/ui/components/textarea/textarea.ts +16 -13
  177. package/dist/ui/components/toast/toast.test.ts +434 -350
  178. package/dist/ui/components/toast/toast.ts +42 -51
  179. package/dist/ui/components/toggle/index.ts +1 -0
  180. package/dist/ui/components/toggle/toggle.test.ts +559 -146
  181. package/dist/ui/components/toggle/toggle.ts +241 -26
  182. package/dist/ui/components/toolbar/bar-scroll.test.ts +310 -0
  183. package/dist/ui/components/toolbar/bar-scroll.ts +372 -0
  184. package/dist/ui/components/toolbar/index.ts +12 -0
  185. package/dist/ui/components/toolbar/toolbar.test.ts +438 -0
  186. package/dist/ui/components/toolbar/toolbar.ts +535 -0
  187. package/dist/ui/theme/chart-colors.test.ts +8 -3
  188. package/dist/ui/theme/dark.css +38 -2
  189. package/dist/ui/theme/default.css +55 -7
  190. package/dist/ui/theme/icon-colors.test.ts +8 -3
  191. package/dist/ui/theme/rgb-channels.test.ts +84 -0
  192. package/dist/ui/theme/tailwind-build.test.ts +114 -0
  193. package/dist/ui/theme/tailwind-css.test.ts +83 -0
  194. package/dist/ui/theme/tailwind-plugin.test.ts +42 -2
  195. package/dist/ui/theme/tailwind-plugin.ts +93 -29
  196. package/dist/ui/theme/tailwind.css +113 -0
  197. package/dist/ui/utils/animate.test.ts +13 -1
  198. package/dist/utils/analyze.d.ts +19 -0
  199. package/dist/utils/analyze.js +16 -0
  200. package/dist/utils/analyze.js.map +1 -1
  201. package/dist/utils/analyze.test.js +14 -1
  202. package/dist/utils/analyze.test.js.map +1 -1
  203. package/dist/utils/installed.d.ts +25 -1
  204. package/dist/utils/installed.js +33 -0
  205. package/dist/utils/installed.js.map +1 -1
  206. package/dist/utils/installed.test.js +55 -1
  207. package/dist/utils/installed.test.js.map +1 -1
  208. package/dist/utils/resolve-paths.d.ts +4 -4
  209. package/dist/utils/resolve-paths.js +5 -7
  210. package/dist/utils/resolve-paths.js.map +1 -1
  211. package/dist/utils/resolve-paths.test.js +9 -5
  212. package/dist/utils/resolve-paths.test.js.map +1 -1
  213. package/dist/utils/tailwind.d.ts +45 -0
  214. package/dist/utils/tailwind.js +90 -0
  215. package/dist/utils/tailwind.js.map +1 -0
  216. package/dist/utils/tailwind.test.d.ts +1 -0
  217. package/dist/utils/tailwind.test.js +134 -0
  218. package/dist/utils/tailwind.test.js.map +1 -0
  219. package/package.json +9 -1
  220. package/dist/ui/components/area-chart/area-chart-render.test.ts +0 -63
  221. package/dist/ui/components/bar-chart/bar-chart-render.test.ts +0 -58
  222. package/dist/ui/components/button/button-render.test.ts +0 -132
  223. package/dist/ui/components/button-group/button-group-render.test.ts +0 -146
  224. package/dist/ui/components/candlestick-chart/candlestick-chart-render.test.ts +0 -59
  225. package/dist/ui/components/chart/chart-render.test.ts +0 -730
  226. package/dist/ui/components/line-chart/line-chart-render.test.ts +0 -83
  227. package/dist/ui/components/scatter-chart/scatter-chart-render.test.ts +0 -64
@@ -1,110 +1,170 @@
1
- import { render, waitForUpdate } from '@blotch/angular-lynx-testing-library';
1
+ import { Component, signal } from '@angular/core';
2
+ import {
3
+ fireEvent,
4
+ render,
5
+ waitForUpdate,
6
+ within,
7
+ } from '@blotch/angular-lynx-testing-library';
2
8
  import { describe, expect, it } from 'vitest';
3
- import { setInputSignal } from '../../../test-utils/set-input-signal';
4
9
  import { ICON_LIGHT_COLORS } from '../icon/icon-theme';
5
10
  import { UiPagination } from './pagination';
6
11
 
12
+ @Component({
13
+ imports: [UiPagination],
14
+ template: `
15
+ <ui-pagination
16
+ [(page)]="page"
17
+ [totalPages]="totalPages()"
18
+ [siblingCount]="siblingCount()"
19
+ class="mt-4"
20
+ />
21
+ `,
22
+ })
23
+ class PaginationHost {
24
+ readonly page = signal(1);
25
+ readonly totalPages = signal(5);
26
+ readonly siblingCount = signal(1);
27
+ }
28
+
29
+ @Component({
30
+ imports: [UiPagination],
31
+ template: `
32
+ <ui-pagination
33
+ [totalPages]="2"
34
+ previousLabel="Back"
35
+ nextLabel="Forward"
36
+ [pageLabel]="resultsLabel"
37
+ />
38
+ `,
39
+ })
40
+ class LabeledPaginationHost {
41
+ readonly resultsLabel = (page: number, current: boolean): string =>
42
+ current ? `Results ${page}, showing` : `Results ${page}`;
43
+ }
44
+
7
45
  /**
8
- * The screen reader labels of the row's buttons, in order.
46
+ * Renders the row at a page of a total, with `siblingCount` pages on each
47
+ * side of the current one.
9
48
  */
10
- const labels = (container: Element): (string | null)[] =>
11
- Array.from(container.querySelectorAll('[accessibility-element]')).map((el) =>
12
- el.getAttribute('accessibility-label'),
49
+ const renderPagination = async (
50
+ totalPages: number,
51
+ page = 1,
52
+ siblingCount = 1,
53
+ ) => {
54
+ const result = await render(PaginationHost);
55
+ const host = result.componentRef.instance as PaginationHost;
56
+ host.totalPages.set(totalPages);
57
+ host.siblingCount.set(siblingCount);
58
+ host.page.set(page);
59
+ await waitForUpdate();
60
+ return {
61
+ ...result,
62
+ host,
63
+ /** The button a screen reader reads as `label`. */
64
+ button: (label: string) => result.getByRole('button', { name: label }),
65
+ };
66
+ };
67
+
68
+ /**
69
+ * What the row shows between its arrows, in order: page numbers and gaps.
70
+ */
71
+ const shown = (container: Element): (string | null)[] =>
72
+ Array.from(container.querySelectorAll('text')).map(
73
+ (el) => el.textContent?.trim() ?? null,
13
74
  );
14
75
 
15
- describe('UiPagination', () => {
16
- const setup = async (totalPages: number, page = 1, siblingCount = 1) => {
17
- const { componentRef, container } = await render(UiPagination);
18
- const inst = componentRef.instance as UiPagination;
19
- setInputSignal(inst.totalPages, totalPages);
20
- setInputSignal(inst.siblingCount, siblingCount);
21
- inst.page.set(page);
22
- await waitForUpdate();
23
- return { inst, container };
24
- };
76
+ /**
77
+ * The screen reader labels of the row's buttons, in order. getAllByRole()
78
+ * finds only what a screen reader reaches as a button, so this also checks
79
+ * each one's traits and accessibility-element.
80
+ */
81
+ const labels = (container: Element): (string | null)[] =>
82
+ within(container as HTMLElement)
83
+ .getAllByRole('button')
84
+ .map((button) => button.getAttribute('accessibility-label'));
25
85
 
26
- it('renders the pagination controls', async () => {
27
- const { container } = await setup(5, 2);
28
- expect(container).toBeTruthy();
86
+ describe('UiPagination', () => {
87
+ it('lists every page when they all fit, with the given class', async () => {
88
+ // With one sibling, up to 5 + 1 * 2 = 7 pages fit without gaps.
89
+ const { container } = await renderPagination(7, 3);
90
+ expect(shown(container)).toEqual(['1', '2', '3', '4', '5', '6', '7']);
91
+ expect(container.querySelector('.gap-1')?.classList).toContain('mt-4');
29
92
  });
30
93
 
31
- it('lists every page when total fits the un-truncated window', async () => {
32
- // With siblings=1 the threshold is 5+2 = 7, so a total of 5 stays inline.
33
- const { container } = await setup(5, 3);
34
- // Each page should render its numeric label.
35
- const text = container.textContent ?? '';
36
- expect(text).toContain('1');
37
- expect(text).toContain('5');
38
- expect(text).not.toContain('...');
94
+ it('leaves a gap before the last page near the start', async () => {
95
+ const { container } = await renderPagination(10, 2);
96
+ expect(shown(container)).toEqual(['1', '2', '3', '...', '10']);
39
97
  });
40
98
 
41
- it('inserts a trailing ellipsis when the window is near the start', async () => {
42
- // total=10, page=2, siblings=1 → rangeStart=2, rangeEnd=3; gap on right only.
43
- const { container } = await setup(10, 2);
44
- expect(container.textContent ?? '').toContain('...');
99
+ it('leaves a gap after the first page near the end', async () => {
100
+ const { container } = await renderPagination(10, 9);
101
+ expect(shown(container)).toEqual(['1', '...', '8', '9', '10']);
45
102
  });
46
103
 
47
- it('inserts a leading ellipsis when the window is near the end', async () => {
48
- // total=10, page=9, siblings=1 → rangeStart=8, rangeEnd=9; gap on left only.
49
- const { container } = await setup(10, 9);
50
- expect(container.textContent ?? '').toContain('...');
104
+ it('leaves gaps on both sides in the middle', async () => {
105
+ const { container } = await renderPagination(10, 5);
106
+ expect(shown(container)).toEqual(['1', '...', '4', '5', '6', '...', '10']);
51
107
  });
52
108
 
53
- it('inserts leading and trailing ellipses when the window sits in the middle', async () => {
54
- // total=10, page=5, siblings=1 → rangeStart=4, rangeEnd=6; gaps on both sides.
55
- const { container } = await setup(10, 5);
56
- // Two ellipses in the DOM as separate <text> nodes.
57
- expect(
58
- container.textContent?.match(/\.\.\./g)?.length,
59
- ).toBeGreaterThanOrEqual(1);
109
+ it('widens the window around the current page with more siblings', async () => {
110
+ const { container } = await renderPagination(12, 6, 2);
111
+ expect(shown(container)).toEqual([
112
+ '1',
113
+ '...',
114
+ '4',
115
+ '5',
116
+ '6',
117
+ '7',
118
+ '8',
119
+ '...',
120
+ '12',
121
+ ]);
60
122
  });
61
123
 
62
- it('prev() decrements page when > 1', async () => {
63
- const { inst } = await setup(5, 3);
64
- (inst as unknown as { prev: () => void }).prev();
65
- await waitForUpdate();
66
- expect(inst.page()).toBe(2);
124
+ it('highlights the current page', async () => {
125
+ const { button } = await renderPagination(3, 2);
126
+ expect(button('Page 2, current page').classList).toContain('bg-primary');
127
+ expect(button('Page 1').classList).toContain('bg-transparent');
128
+ expect(button('Page 2, current page').textContent?.trim()).toBe('2');
67
129
  });
68
130
 
69
- it('prev() is a no-op at page 1', async () => {
70
- const { inst } = await setup(5, 1);
71
- (inst as unknown as { prev: () => void }).prev();
131
+ it('goes to a tapped page', async () => {
132
+ const { host, button } = await renderPagination(5, 1);
133
+ fireEvent.tap(button('Page 4'));
72
134
  await waitForUpdate();
73
- expect(inst.page()).toBe(1);
135
+ expect(host.page()).toBe(4);
136
+ expect(button('Page 4, current page').classList).toContain('bg-primary');
74
137
  });
75
138
 
76
- it('next() increments page when < totalPages', async () => {
77
- const { inst } = await setup(5, 3);
78
- (inst as unknown as { next: () => void }).next();
139
+ it('steps back and forward with the arrows', async () => {
140
+ const { host, button } = await renderPagination(5, 3);
141
+ fireEvent.tap(button('Previous page'));
79
142
  await waitForUpdate();
80
- expect(inst.page()).toBe(4);
81
- });
143
+ expect(host.page()).toBe(2);
82
144
 
83
- it('next() is a no-op at the last page', async () => {
84
- const { inst } = await setup(5, 5);
85
- (inst as unknown as { next: () => void }).next();
145
+ fireEvent.tap(button('Next page'));
146
+ fireEvent.tap(button('Next page'));
86
147
  await waitForUpdate();
87
- expect(inst.page()).toBe(5);
148
+ expect(host.page()).toBe(4);
88
149
  });
89
150
 
90
- it('goTo() jumps the page directly', async () => {
91
- const { inst } = await setup(5, 1);
92
- (inst as unknown as { goTo: (n: number) => void }).goTo(4);
151
+ it("dims the arrow that can't go further, and ignores its taps", async () => {
152
+ const first = await renderPagination(5, 1);
153
+ expect(first.button('Previous page').classList).toContain('opacity-50');
154
+ expect(first.button('Next page').classList).not.toContain('opacity-50');
155
+ fireEvent.tap(first.button('Previous page'));
93
156
  await waitForUpdate();
94
- expect(inst.page()).toBe(4);
95
- });
157
+ expect(first.host.page()).toBe(1);
96
158
 
97
- it('active page carries the primary variant class', async () => {
98
- const { container } = await setup(3, 2);
99
- // The active page's tile background is bg-primary; the others are transparent.
100
- const primary = Array.from(container.querySelectorAll('view')).find((el) =>
101
- el.getAttribute('class')?.includes('bg-primary'),
102
- );
103
- expect(primary).toBeTruthy();
159
+ const last = await renderPagination(5, 5);
160
+ expect(last.button('Next page').classList).toContain('opacity-50');
161
+ fireEvent.tap(last.button('Next page'));
162
+ await waitForUpdate();
163
+ expect(last.host.page()).toBe(5);
104
164
  });
105
165
 
106
166
  it('labels every button for screen readers', async () => {
107
- const { container } = await setup(3, 2);
167
+ const { container } = await renderPagination(3, 2);
108
168
  expect(labels(container)).toEqual([
109
169
  'Previous page',
110
170
  'Page 1',
@@ -112,20 +172,10 @@ describe('UiPagination', () => {
112
172
  'Page 3',
113
173
  'Next page',
114
174
  ]);
115
- const buttons = container.querySelectorAll('[accessibility-element]');
116
- for (const button of Array.from(buttons)) {
117
- expect(button.getAttribute('accessibility-traits')).toBe('button');
118
- }
119
175
  });
120
176
 
121
177
  it('takes its own labels', async () => {
122
- const { inst, container } = await setup(2, 1);
123
- setInputSignal(inst.previousLabel, 'Back');
124
- setInputSignal(inst.nextLabel, 'Forward');
125
- setInputSignal(inst.pageLabel, (page: number, current: boolean) =>
126
- current ? `Results ${page}, showing` : `Results ${page}`,
127
- );
128
- await waitForUpdate();
178
+ const { container } = await render(LabeledPaginationHost);
129
179
  expect(labels(container)).toEqual([
130
180
  'Back',
131
181
  'Results 1, showing',
@@ -135,7 +185,7 @@ describe('UiPagination', () => {
135
185
  });
136
186
 
137
187
  it('hides the gaps from screen readers', async () => {
138
- const { container } = await setup(10, 5);
188
+ const { container } = await renderPagination(10, 5);
139
189
  const gaps = Array.from(container.querySelectorAll('text'))
140
190
  .filter((el) => el.textContent === '...')
141
191
  .map((el) =>
@@ -145,7 +195,7 @@ describe('UiPagination', () => {
145
195
  });
146
196
 
147
197
  it("draws the arrows in the theme's foreground", async () => {
148
- const { container } = await setup(3, 2);
198
+ const { container } = await renderPagination(3, 2);
149
199
  const arrows = Array.from(container.querySelectorAll('svg')).map((el) =>
150
200
  el.getAttribute('content'),
151
201
  );
@@ -0,0 +1,9 @@
1
+ export { UiPopover, UiPopoverContent, UiPopoverTrigger } from './popover';
2
+ export {
3
+ ARROW_HEIGHT,
4
+ ARROW_WIDTH,
5
+ UiPopoverPanel,
6
+ popoverArrow,
7
+ type PopoverAnchor,
8
+ type PopoverPhase,
9
+ } from './popover-panel';