@blotch/dolan 22.2.2 → 22.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/add.d.ts +6 -2
- package/dist/commands/add.js +41 -11
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/add.test.js +162 -9
- package/dist/commands/add.test.js.map +1 -1
- package/dist/commands/diff.d.ts +2 -1
- package/dist/commands/diff.js +38 -25
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/diff.test.js +72 -11
- package/dist/commands/diff.test.js.map +1 -1
- package/dist/commands/doctor.js +228 -34
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/doctor.test.js +367 -10
- package/dist/commands/doctor.test.js.map +1 -1
- package/dist/commands/eject.js +7 -0
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/eject.test.js +39 -0
- package/dist/commands/eject.test.js.map +1 -1
- package/dist/commands/info.js +3 -2
- package/dist/commands/info.js.map +1 -1
- package/dist/commands/init.d.ts +37 -1
- package/dist/commands/init.js +169 -40
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/init.test.js +392 -27
- package/dist/commands/init.test.js.map +1 -1
- package/dist/commands/install-packages.d.ts +6 -0
- package/dist/commands/install-packages.js +20 -0
- package/dist/commands/install-packages.js.map +1 -0
- package/dist/commands/install-packages.test.d.ts +1 -0
- package/dist/commands/install-packages.test.js +55 -0
- package/dist/commands/install-packages.test.js.map +1 -0
- package/dist/commands/list.js +21 -14
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/list.test.js +62 -5
- package/dist/commands/list.test.js.map +1 -1
- package/dist/commands/outdated.js +11 -10
- package/dist/commands/outdated.js.map +1 -1
- package/dist/commands/outdated.test.js +20 -5
- package/dist/commands/outdated.test.js.map +1 -1
- package/dist/commands/remove.d.ts +4 -0
- package/dist/commands/remove.js +17 -4
- package/dist/commands/remove.js.map +1 -1
- package/dist/commands/remove.test.js +53 -2
- package/dist/commands/remove.test.js.map +1 -1
- package/dist/commands/theme.js +1 -1
- package/dist/commands/theme.js.map +1 -1
- package/dist/commands/update.d.ts +11 -0
- package/dist/commands/update.js +174 -58
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/update.test.js +587 -33
- package/dist/commands/update.test.js.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/lockfile.d.ts +7 -0
- package/dist/lockfile.js +36 -0
- package/dist/lockfile.js.map +1 -1
- package/dist/lockfile.test.d.ts +1 -0
- package/dist/lockfile.test.js +25 -0
- package/dist/lockfile.test.js.map +1 -0
- package/dist/registry.d.ts +14 -0
- package/dist/registry.js +78 -24
- package/dist/registry.js.map +1 -1
- package/dist/registry.test.js +119 -38
- package/dist/registry.test.js.map +1 -1
- package/dist/test-utils.d.ts +5 -0
- package/dist/test-utils.js +6 -1
- package/dist/test-utils.js.map +1 -1
- package/dist/testing/fire-lynx-event.d.ts +14 -0
- package/dist/testing/fire-lynx-event.js +19 -0
- package/dist/testing/fire-lynx-event.js.map +1 -0
- package/dist/testing/fire-lynx-event.test.d.ts +1 -0
- package/dist/testing/fire-lynx-event.test.js +44 -0
- package/dist/testing/fire-lynx-event.test.js.map +1 -0
- package/dist/testing/lynx-main-thread.d.ts +22 -0
- package/dist/testing/lynx-main-thread.js +11 -0
- package/dist/testing/lynx-main-thread.js.map +1 -0
- package/dist/testing/lynx-main-thread.test.d.ts +1 -0
- package/dist/testing/lynx-main-thread.test.js +24 -0
- package/dist/testing/lynx-main-thread.test.js.map +1 -0
- package/dist/testing/set-input-signal.d.ts +14 -0
- package/dist/testing/set-input-signal.js +21 -0
- package/dist/testing/set-input-signal.js.map +1 -0
- package/dist/testing/set-input-signal.test.d.ts +1 -0
- package/dist/testing/set-input-signal.test.js +20 -0
- package/dist/testing/set-input-signal.test.js.map +1 -0
- package/dist/ui/components/accordion/accordion.test.ts +158 -144
- package/dist/ui/components/accordion/accordion.ts +19 -14
- package/dist/ui/components/action-sheet/action-sheet.test.ts +283 -151
- package/dist/ui/components/action-sheet/action-sheet.ts +77 -43
- package/dist/ui/components/alert/alert.test.ts +67 -19
- package/dist/ui/components/alert/alert.ts +14 -16
- package/dist/ui/components/alert-dialog/alert-dialog.test.ts +208 -94
- package/dist/ui/components/alert-dialog/alert-dialog.ts +75 -38
- package/dist/ui/components/area-chart/area-chart.test.ts +134 -119
- package/dist/ui/components/area-chart/area-chart.ts +100 -315
- package/dist/ui/components/area-chart/index.ts +2 -3
- package/dist/ui/components/avatar/avatar.test.ts +89 -45
- package/dist/ui/components/badge/badge.test.ts +57 -23
- package/dist/ui/components/badge/badge.ts +12 -14
- package/dist/ui/components/bar-chart/bar-chart.test.ts +172 -45
- package/dist/ui/components/bar-chart/bar-chart.ts +140 -294
- package/dist/ui/components/bar-chart/index.ts +3 -3
- package/dist/ui/components/bottom-sheet/bottom-sheet.test.ts +386 -128
- package/dist/ui/components/bottom-sheet/bottom-sheet.ts +170 -53
- package/dist/ui/components/button/button.test.ts +611 -2
- package/dist/ui/components/button/button.ts +434 -49
- package/dist/ui/components/button/index.ts +2 -0
- package/dist/ui/components/button-group/button-group.test.ts +484 -2
- package/dist/ui/components/button-group/button-group.ts +380 -68
- package/dist/ui/components/button-group/index.ts +3 -0
- package/dist/ui/components/candlestick-chart/candlestick-chart.test.ts +183 -58
- package/dist/ui/components/candlestick-chart/candlestick-chart.ts +150 -323
- package/dist/ui/components/candlestick-chart/index.ts +3 -4
- package/dist/ui/components/card/card.test.ts +82 -62
- package/dist/ui/components/chart/chart-focus.test.ts +132 -0
- package/dist/ui/components/chart/chart-focus.ts +115 -0
- package/dist/ui/components/chart/chart-presets.test.ts +335 -0
- package/dist/ui/components/chart/chart-presets.ts +278 -0
- package/dist/ui/components/chart/chart-scene.test.ts +589 -0
- package/dist/ui/components/chart/chart-scene.ts +483 -0
- package/dist/ui/components/chart/chart-theme.test.ts +85 -0
- package/dist/ui/components/chart/chart-theme.ts +210 -0
- package/dist/ui/components/chart/chart-zoom.test.ts +159 -0
- package/dist/ui/components/chart/chart-zoom.ts +162 -0
- package/dist/ui/components/chart/chart.test.ts +1017 -0
- package/dist/ui/components/chart/chart.ts +934 -0
- package/dist/ui/components/chart/index.ts +24 -0
- package/dist/ui/components/checkbox/checkbox.test.ts +124 -42
- package/dist/ui/components/checkbox/checkbox.ts +23 -23
- package/dist/ui/components/collapsible/collapsible.test.ts +158 -81
- package/dist/ui/components/collapsible/collapsible.ts +19 -14
- package/dist/ui/components/context-menu/context-menu.test.ts +224 -0
- package/dist/ui/components/context-menu/context-menu.ts +110 -0
- package/dist/ui/components/context-menu/index.ts +1 -0
- package/dist/ui/components/dialog/dialog.test.ts +213 -108
- package/dist/ui/components/dialog/dialog.ts +72 -35
- package/dist/ui/components/dock/dock-scroll.test.ts +130 -0
- package/dist/ui/components/dock/dock-scroll.ts +133 -0
- package/dist/ui/components/dock/dock.test.ts +749 -0
- package/dist/ui/components/dock/dock.ts +960 -0
- package/dist/ui/components/dock/index.ts +2 -0
- package/dist/ui/components/empty-state/empty-state.test.ts +28 -39
- package/dist/ui/components/glass/concentric-radius.test.ts +13 -0
- package/dist/ui/components/glass/concentric-radius.ts +17 -0
- package/dist/ui/components/glass/glass-design.test.ts +78 -0
- package/dist/ui/components/glass/glass-design.ts +119 -0
- package/dist/ui/components/glass/glass.test.ts +338 -0
- package/dist/ui/components/glass/glass.ts +360 -0
- package/dist/ui/components/glass/index.ts +18 -0
- package/dist/ui/components/icon/icon-theme.test.ts +169 -0
- package/dist/ui/components/icon/icon-theme.ts +227 -0
- package/dist/ui/components/icon/icon.test.ts +85 -25
- package/dist/ui/components/icon/icon.ts +38 -21
- package/dist/ui/components/input/input.test.ts +178 -101
- package/dist/ui/components/input/input.ts +15 -12
- package/dist/ui/components/label/label.test.ts +11 -24
- package/dist/ui/components/line-chart/index.ts +2 -3
- package/dist/ui/components/line-chart/line-chart.test.ts +149 -56
- package/dist/ui/components/line-chart/line-chart.ts +83 -241
- package/dist/ui/components/list/list.test.ts +119 -21
- package/dist/ui/components/list/list.ts +21 -15
- package/dist/ui/components/menu/index.ts +25 -0
- package/dist/ui/components/menu/menu-placement.test.ts +153 -0
- package/dist/ui/components/menu/menu-placement.ts +159 -0
- package/dist/ui/components/menu/menu-popup.test.ts +632 -0
- package/dist/ui/components/menu/menu-popup.ts +544 -0
- package/dist/ui/components/menu/menu.test.ts +429 -0
- package/dist/ui/components/menu/menu.ts +415 -0
- package/dist/ui/components/nav-drawer/nav-drawer.test.ts +435 -191
- package/dist/ui/components/nav-drawer/nav-drawer.ts +127 -56
- package/dist/ui/components/pagination/pagination.test.ts +177 -65
- package/dist/ui/components/pagination/pagination.ts +55 -8
- package/dist/ui/components/progress/progress.test.ts +102 -46
- package/dist/ui/components/progress/progress.ts +52 -54
- package/dist/ui/components/radio-group/radio-group.test.ts +128 -83
- package/dist/ui/components/radio-group/radio-group.ts +24 -24
- package/dist/ui/components/scatter-chart/index.ts +2 -3
- package/dist/ui/components/scatter-chart/scatter-chart.test.ts +131 -26
- package/dist/ui/components/scatter-chart/scatter-chart.ts +104 -250
- package/dist/ui/components/scroll-area/scroll-area.test.ts +95 -24
- package/dist/ui/components/scroll-area/scroll-area.ts +8 -8
- package/dist/ui/components/select/select.test.ts +138 -78
- package/dist/ui/components/select/select.ts +17 -11
- package/dist/ui/components/separator/separator.test.ts +18 -17
- package/dist/ui/components/sheet/sheet.test.ts +64 -11
- package/dist/ui/components/sheet/sheet.ts +9 -1
- package/dist/ui/components/skeleton/skeleton.test.ts +24 -7
- package/dist/ui/components/skeleton/skeleton.ts +10 -16
- package/dist/ui/components/spinner/spinner.test.ts +67 -22
- package/dist/ui/components/spinner/spinner.ts +48 -41
- package/dist/ui/components/switch/switch.test.ts +116 -46
- package/dist/ui/components/switch/switch.ts +8 -13
- package/dist/ui/components/tab-bar/index.ts +1 -0
- package/dist/ui/components/tab-bar/tab-bar.test.ts +280 -0
- package/dist/ui/components/tab-bar/tab-bar.ts +230 -0
- package/dist/ui/components/tabs/tabs.test.ts +215 -157
- package/dist/ui/components/tabs/tabs.ts +110 -118
- package/dist/ui/components/textarea/textarea.test.ts +206 -100
- package/dist/ui/components/textarea/textarea.ts +14 -12
- package/dist/ui/components/toast/toast.test.ts +436 -315
- package/dist/ui/components/toast/toast.ts +62 -55
- package/dist/ui/components/toggle/toggle.test.ts +247 -140
- package/dist/ui/theme/chart-colors.test.ts +35 -0
- package/dist/ui/theme/dark.css +46 -2
- package/dist/ui/theme/default.css +63 -7
- package/dist/ui/theme/icon-colors.test.ts +35 -0
- package/dist/ui/theme/rgb-channels.test.ts +84 -0
- package/dist/ui/theme/tailwind-build.test.ts +114 -0
- package/dist/ui/theme/tailwind-css.test.ts +83 -0
- package/dist/ui/theme/tailwind-plugin.test.ts +42 -2
- package/dist/ui/theme/tailwind-plugin.ts +98 -25
- package/dist/ui/theme/tailwind.css +113 -0
- package/dist/ui/utils/animate.test.ts +13 -1
- package/dist/utils/analyze.d.ts +14 -0
- package/dist/utils/analyze.js +15 -0
- package/dist/utils/analyze.js.map +1 -1
- package/dist/utils/analyze.test.js +14 -1
- package/dist/utils/analyze.test.js.map +1 -1
- package/dist/utils/installed.d.ts +29 -0
- package/dist/utils/installed.js +43 -0
- package/dist/utils/installed.js.map +1 -0
- package/dist/utils/installed.test.d.ts +1 -0
- package/dist/utils/installed.test.js +57 -0
- package/dist/utils/installed.test.js.map +1 -0
- package/dist/utils/interactive.d.ts +9 -0
- package/dist/utils/interactive.js +10 -0
- package/dist/utils/interactive.js.map +1 -0
- package/dist/utils/interactive.test.d.ts +1 -0
- package/dist/utils/interactive.test.js +24 -0
- package/dist/utils/interactive.test.js.map +1 -0
- package/dist/utils/packages.d.ts +36 -0
- package/dist/utils/packages.js +70 -0
- package/dist/utils/packages.js.map +1 -0
- package/dist/utils/packages.test.d.ts +1 -0
- package/dist/utils/packages.test.js +89 -0
- package/dist/utils/packages.test.js.map +1 -0
- package/dist/utils/resolve-paths.d.ts +17 -1
- package/dist/utils/resolve-paths.js +21 -3
- package/dist/utils/resolve-paths.js.map +1 -1
- package/dist/utils/resolve-paths.test.js +38 -2
- package/dist/utils/resolve-paths.test.js.map +1 -1
- package/dist/utils/tailwind.d.ts +25 -0
- package/dist/utils/tailwind.js +51 -0
- package/dist/utils/tailwind.js.map +1 -0
- package/dist/utils/tailwind.test.d.ts +1 -0
- package/dist/utils/tailwind.test.js +71 -0
- package/dist/utils/tailwind.test.js.map +1 -0
- package/package.json +13 -1
- package/dist/ui/components/area-chart/area-chart-render.test.ts +0 -121
- package/dist/ui/components/bar-chart/bar-chart-render.test.ts +0 -174
- package/dist/ui/components/button/button-render.test.ts +0 -113
- package/dist/ui/components/button-group/button-group-render.test.ts +0 -146
- package/dist/ui/components/candlestick-chart/candlestick-chart-render.test.ts +0 -174
- package/dist/ui/components/cartesian-chart/cartesian-chart-render.test.ts +0 -188
- package/dist/ui/components/cartesian-chart/cartesian-chart.test.ts +0 -525
- package/dist/ui/components/cartesian-chart/cartesian-chart.ts +0 -1140
- package/dist/ui/components/cartesian-chart/index.ts +0 -18
- package/dist/ui/components/line-chart/line-chart-render.test.ts +0 -121
- package/dist/ui/components/scatter-chart/scatter-chart-render.test.ts +0 -157
|
@@ -1,8 +1,25 @@
|
|
|
1
1
|
import { Component, signal } from '@angular/core';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
fireEvent,
|
|
4
|
+
render,
|
|
5
|
+
waitForUpdate,
|
|
6
|
+
} from '@blotch/angular-lynx-testing-library';
|
|
3
7
|
import { LYNX_ELEMENTS } from '@blotch/angular-lynx';
|
|
4
|
-
import {
|
|
5
|
-
|
|
8
|
+
import {
|
|
9
|
+
type MockInstance,
|
|
10
|
+
afterEach,
|
|
11
|
+
beforeEach,
|
|
12
|
+
describe,
|
|
13
|
+
expect,
|
|
14
|
+
it,
|
|
15
|
+
vi,
|
|
16
|
+
} from 'vitest';
|
|
17
|
+
import { DURATION } from '../../utils/animate';
|
|
18
|
+
import { fireLynxEvent } from '../../../test-utils/fire-lynx-event';
|
|
19
|
+
import {
|
|
20
|
+
type LynxMainThread,
|
|
21
|
+
lynxMainThread,
|
|
22
|
+
} from '../../../test-utils/lynx-main-thread';
|
|
6
23
|
import {
|
|
7
24
|
UiActionSheet,
|
|
8
25
|
UiActionSheetCancel,
|
|
@@ -11,7 +28,6 @@ import {
|
|
|
11
28
|
} from './action-sheet';
|
|
12
29
|
|
|
13
30
|
@Component({
|
|
14
|
-
standalone: true,
|
|
15
31
|
imports: [
|
|
16
32
|
UiActionSheet,
|
|
17
33
|
UiActionSheetTitle,
|
|
@@ -20,192 +36,308 @@ import {
|
|
|
20
36
|
LYNX_ELEMENTS,
|
|
21
37
|
],
|
|
22
38
|
template: `
|
|
23
|
-
<ui-action-sheet [(open)]="open">
|
|
24
|
-
<ui-action-sheet-title>Pick</ui-action-sheet-title>
|
|
25
|
-
<ui-action-sheet-item>
|
|
26
|
-
<ui-action-sheet-
|
|
39
|
+
<ui-action-sheet [(open)]="open" class="pb-8" (closed)="closed()">
|
|
40
|
+
<ui-action-sheet-title class="py-4">Pick</ui-action-sheet-title>
|
|
41
|
+
<ui-action-sheet-item (pressed)="shared()">Share</ui-action-sheet-item>
|
|
42
|
+
<ui-action-sheet-item
|
|
43
|
+
variant="destructive"
|
|
44
|
+
class="bg-muted"
|
|
45
|
+
(pressed)="deleted()"
|
|
46
|
+
>
|
|
47
|
+
Delete
|
|
48
|
+
</ui-action-sheet-item>
|
|
49
|
+
<ui-action-sheet-cancel class="mt-2" />
|
|
27
50
|
</ui-action-sheet>
|
|
28
51
|
`,
|
|
29
52
|
})
|
|
30
53
|
class ActionSheetHost {
|
|
31
|
-
open =
|
|
54
|
+
readonly open = signal(false);
|
|
55
|
+
readonly closed = vi.fn();
|
|
56
|
+
readonly shared = vi.fn();
|
|
57
|
+
readonly deleted = vi.fn();
|
|
32
58
|
}
|
|
33
59
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
60
|
+
/**
|
|
61
|
+
* A cancel button given its own label.
|
|
62
|
+
*/
|
|
63
|
+
@Component({
|
|
64
|
+
imports: [UiActionSheet, UiActionSheetCancel],
|
|
65
|
+
template: `
|
|
66
|
+
<ui-action-sheet>
|
|
67
|
+
<ui-action-sheet-cancel label="Dismiss" />
|
|
68
|
+
</ui-action-sheet>
|
|
69
|
+
`,
|
|
70
|
+
})
|
|
71
|
+
class CancelLabelHost {}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* The Lynx function an element's `invoke()` calls to run one of its UI
|
|
75
|
+
* methods, such as moving a screen reader's focus. The testing library
|
|
76
|
+
* defines it on the global object.
|
|
77
|
+
*/
|
|
78
|
+
type InvokeUIMethod = {
|
|
79
|
+
__InvokeUIMethod: (
|
|
80
|
+
element: Element,
|
|
81
|
+
method: string,
|
|
82
|
+
params: Record<string, unknown>,
|
|
83
|
+
callback: (result: { code: number }) => void,
|
|
84
|
+
) => void;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
/** `__ElementAnimate`'s first argument for starting an animation. */
|
|
88
|
+
const START = 0;
|
|
89
|
+
|
|
90
|
+
const renderSheet = async () => {
|
|
91
|
+
const result = await render(ActionSheetHost);
|
|
92
|
+
const { container } = result;
|
|
93
|
+
return {
|
|
94
|
+
...result,
|
|
95
|
+
host: result.componentRef.instance as ActionSheetHost,
|
|
96
|
+
overlay: container.querySelector('overlay')!,
|
|
97
|
+
backdrop: container.querySelector('overlay > view')!,
|
|
98
|
+
panel: container.querySelector('[accessibility-exclusive-focus]')!,
|
|
99
|
+
// A button's pressable tile: the view around its label.
|
|
100
|
+
button: (label: string) => result.getByText(label).parentElement!,
|
|
42
101
|
};
|
|
102
|
+
};
|
|
43
103
|
|
|
44
|
-
|
|
45
|
-
|
|
104
|
+
/**
|
|
105
|
+
* Opens the action sheet and waits out its open sequence: the overlay shows
|
|
106
|
+
* on one tick, and the panel slides in on the next.
|
|
107
|
+
*/
|
|
108
|
+
const openSheet = async (host: ActionSheetHost) => {
|
|
109
|
+
host.open.set(true);
|
|
110
|
+
for (let i = 0; i < 3; i++) await waitForUpdate();
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Waits for the close sequence to finish: the panel slides out, then the
|
|
115
|
+
* overlay hides and `closed` fires. Polled rather than timed, since the
|
|
116
|
+
* sequence only starts on the update after `open` changes.
|
|
117
|
+
*/
|
|
118
|
+
const waitForClose = async (host: ActionSheetHost) => {
|
|
119
|
+
await vi.waitFor(() => expect(host.closed).toHaveBeenCalled());
|
|
120
|
+
await waitForUpdate();
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* The scale a button's inline style holds, if any.
|
|
125
|
+
*/
|
|
126
|
+
const scaleOf = (element: Element) =>
|
|
127
|
+
(element as HTMLElement).style.getPropertyValue('transform');
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Presses a button and lets go every way Lynx reports it, checking that it
|
|
131
|
+
* scales down while pressed and back up once released.
|
|
132
|
+
*/
|
|
133
|
+
const expectPressFeedback = (button: Element) => {
|
|
134
|
+
fireEvent.touchstart(button);
|
|
135
|
+
expect(scaleOf(button)).toBe('scale(0.985)');
|
|
136
|
+
fireEvent.touchend(button);
|
|
137
|
+
expect(scaleOf(button)).toBe('scale(1)');
|
|
138
|
+
|
|
139
|
+
// A scroll that takes the touch over cancels it: the button scales back.
|
|
140
|
+
fireEvent.touchstart(button);
|
|
141
|
+
fireEvent.touchcancel(button);
|
|
142
|
+
expect(scaleOf(button)).toBe('scale(1)');
|
|
143
|
+
|
|
144
|
+
// On web, the mouse drives the same feedback.
|
|
145
|
+
fireEvent.mousedown(button);
|
|
146
|
+
expect(scaleOf(button)).toBe('scale(0.985)');
|
|
147
|
+
fireEvent.mouseup(button);
|
|
148
|
+
expect(scaleOf(button)).toBe('scale(1)');
|
|
149
|
+
|
|
150
|
+
fireEvent.mousedown(button);
|
|
151
|
+
fireLynxEvent(button, 'mouseleave');
|
|
152
|
+
expect(scaleOf(button)).toBe('scale(1)');
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
describe('UiActionSheet', () => {
|
|
156
|
+
// Watched per test: the testing library resets the main thread after each.
|
|
157
|
+
let animate: MockInstance<LynxMainThread['__ElementAnimate']>;
|
|
158
|
+
beforeEach(() => {
|
|
159
|
+
animate = vi.spyOn(lynxMainThread(), '__ElementAnimate');
|
|
160
|
+
});
|
|
161
|
+
afterEach(() => animate.mockRestore());
|
|
162
|
+
|
|
163
|
+
it('stays hidden until opened, then shows its title and buttons', async () => {
|
|
164
|
+
const { host, overlay, getByText } = await renderSheet();
|
|
165
|
+
expect(overlay.getAttribute('style')).toContain('display: none');
|
|
166
|
+
expect(overlay.getAttribute('visible')).toBe('false');
|
|
167
|
+
|
|
168
|
+
await openSheet(host);
|
|
169
|
+
expect(overlay.getAttribute('style')).not.toContain('display: none');
|
|
170
|
+
expect(overlay.getAttribute('visible')).toBe('true');
|
|
46
171
|
expect(getByText('Pick')).toBeTruthy();
|
|
47
|
-
expect(getByText('
|
|
172
|
+
expect(getByText('Share')).toBeTruthy();
|
|
173
|
+
expect(getByText('Delete')).toBeTruthy();
|
|
48
174
|
expect(getByText('Cancel')).toBeTruthy();
|
|
49
175
|
});
|
|
50
176
|
|
|
51
|
-
it(
|
|
52
|
-
const {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
(inst as unknown as { onBackdropTap: () => void }).onBackdropTap();
|
|
57
|
-
expect(inst.open()).toBe(false);
|
|
177
|
+
it("merges the class into the panel's own", async () => {
|
|
178
|
+
const { panel } = await renderSheet();
|
|
179
|
+
expect(panel.classList).toContain('pb-8');
|
|
180
|
+
expect(panel.classList).not.toContain('pb-6');
|
|
181
|
+
expect(panel.classList).toContain('px-4');
|
|
58
182
|
});
|
|
59
183
|
|
|
60
|
-
it('
|
|
61
|
-
const {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
184
|
+
it('fades the backdrop in and slides the panel up when opened', async () => {
|
|
185
|
+
const { host, backdrop, panel } = await renderSheet();
|
|
186
|
+
await openSheet(host);
|
|
187
|
+
expect(animate).toHaveBeenCalledWith(backdrop, [
|
|
188
|
+
START,
|
|
189
|
+
expect.any(String),
|
|
190
|
+
[{ opacity: 0 }, { opacity: 1 }],
|
|
191
|
+
expect.objectContaining({ duration: DURATION.normal }),
|
|
192
|
+
]);
|
|
193
|
+
expect(animate).toHaveBeenCalledWith(panel, [
|
|
194
|
+
START,
|
|
195
|
+
expect.any(String),
|
|
196
|
+
[
|
|
197
|
+
{ transform: 'translateY(100%)', opacity: 0.8 },
|
|
198
|
+
{ transform: 'translateY(0%)', opacity: 1 },
|
|
199
|
+
],
|
|
200
|
+
expect.objectContaining({ duration: DURATION.slow }),
|
|
201
|
+
]);
|
|
66
202
|
});
|
|
67
203
|
|
|
68
|
-
it('panel
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
204
|
+
it('moves a screen reader into the panel and keeps it there while open', async () => {
|
|
205
|
+
const invoke = vi.spyOn(
|
|
206
|
+
globalThis as unknown as InvokeUIMethod,
|
|
207
|
+
'__InvokeUIMethod',
|
|
208
|
+
);
|
|
209
|
+
const { host, panel } = await renderSheet();
|
|
210
|
+
expect(panel.getAttribute('accessibility-exclusive-focus')).toBe('false');
|
|
75
211
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
212
|
+
await openSheet(host);
|
|
213
|
+
expect(invoke).toHaveBeenCalledWith(
|
|
214
|
+
panel,
|
|
215
|
+
'requestAccessibilityFocus',
|
|
216
|
+
expect.anything(),
|
|
217
|
+
expect.any(Function),
|
|
218
|
+
);
|
|
219
|
+
expect(panel.getAttribute('accessibility-exclusive-focus')).toBe('true');
|
|
220
|
+
invoke.mockRestore();
|
|
221
|
+
});
|
|
81
222
|
|
|
82
|
-
|
|
83
|
-
await
|
|
84
|
-
await
|
|
85
|
-
await waitForUpdate();
|
|
223
|
+
it('closes when the backdrop is tapped, sliding the panel down', async () => {
|
|
224
|
+
const { host, overlay, backdrop, panel } = await renderSheet();
|
|
225
|
+
await openSheet(host);
|
|
86
226
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
await
|
|
90
|
-
expect(
|
|
227
|
+
fireEvent.tap(backdrop);
|
|
228
|
+
expect(host.open()).toBe(false);
|
|
229
|
+
await waitForClose(host);
|
|
230
|
+
expect(animate).toHaveBeenCalledWith(backdrop, [
|
|
231
|
+
START,
|
|
232
|
+
expect.any(String),
|
|
233
|
+
[{ opacity: 1 }, { opacity: 0 }],
|
|
234
|
+
expect.objectContaining({ duration: DURATION.normal }),
|
|
235
|
+
]);
|
|
236
|
+
expect(animate).toHaveBeenCalledWith(panel, [
|
|
237
|
+
START,
|
|
238
|
+
expect.any(String),
|
|
239
|
+
[
|
|
240
|
+
{ transform: 'translateY(0%)', opacity: 1 },
|
|
241
|
+
{ transform: 'translateY(100%)', opacity: 0.8 },
|
|
242
|
+
],
|
|
243
|
+
expect.objectContaining({ duration: DURATION.normal }),
|
|
244
|
+
]);
|
|
245
|
+
// Once the slide is over, the overlay hides and `closed` fires, only for
|
|
246
|
+
// this close: an action sheet that starts closed hasn't closed before.
|
|
247
|
+
expect(overlay.getAttribute('style')).toContain('display: none');
|
|
248
|
+
expect(host.closed).toHaveBeenCalledOnce();
|
|
91
249
|
});
|
|
92
250
|
|
|
93
|
-
it('open
|
|
94
|
-
const {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
inst.open.set(false);
|
|
100
|
-
await waitForUpdate();
|
|
101
|
-
expect(inst.open()).toBe(false);
|
|
251
|
+
it('stays open when the panel is tapped', async () => {
|
|
252
|
+
const { host, panel } = await renderSheet();
|
|
253
|
+
await openSheet(host);
|
|
254
|
+
// The panel catches its taps, so they never reach the backdrop.
|
|
255
|
+
fireEvent.tap(panel, { eventType: 'catchEvent' });
|
|
256
|
+
expect(host.open()).toBe(true);
|
|
102
257
|
});
|
|
103
258
|
|
|
104
|
-
it('
|
|
105
|
-
const
|
|
106
|
-
const
|
|
107
|
-
|
|
259
|
+
it('stops its close timers when it is destroyed while closing', async () => {
|
|
260
|
+
const warn = vi.spyOn(console, 'warn');
|
|
261
|
+
const { host, unmount } = await renderSheet();
|
|
262
|
+
await openSheet(host);
|
|
263
|
+
host.open.set(false);
|
|
108
264
|
await waitForUpdate();
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
).
|
|
265
|
+
// Destroyed during the close animation, as an `@if` around the action
|
|
266
|
+
// sheet would do. Its close timer (DURATION.normal + 20) used to fire
|
|
267
|
+
// anyway and emit `closed` from the destroyed output.
|
|
268
|
+
unmount();
|
|
269
|
+
await new Promise((resolve) => setTimeout(resolve, DURATION.normal + 50));
|
|
270
|
+
const warnings = warn.mock.calls.map(([message]) => String(message));
|
|
271
|
+
warn.mockRestore();
|
|
272
|
+
expect(warnings.filter((message) => message.includes('NG0953'))).toEqual(
|
|
273
|
+
[],
|
|
274
|
+
);
|
|
275
|
+
expect(host.closed).not.toHaveBeenCalled();
|
|
114
276
|
});
|
|
115
277
|
});
|
|
116
278
|
|
|
117
279
|
describe('UiActionSheetTitle', () => {
|
|
118
|
-
it('
|
|
119
|
-
const {
|
|
120
|
-
|
|
121
|
-
expect(
|
|
280
|
+
it('shows its text muted, with the class on its container', async () => {
|
|
281
|
+
const { getByText } = await renderSheet();
|
|
282
|
+
const title = getByText('Pick');
|
|
283
|
+
expect(title.classList).toContain('text-muted-foreground');
|
|
284
|
+
expect(title.parentElement?.classList).toContain('py-4');
|
|
285
|
+
expect(title.parentElement?.classList).not.toContain('py-3');
|
|
122
286
|
});
|
|
123
287
|
});
|
|
124
288
|
|
|
125
289
|
describe('UiActionSheetItem', () => {
|
|
126
|
-
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
parent.open.set(true);
|
|
130
|
-
await waitForUpdate();
|
|
290
|
+
it('reports the press and closes the action sheet when tapped', async () => {
|
|
291
|
+
const { host, button } = await renderSheet();
|
|
292
|
+
await openSheet(host);
|
|
131
293
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
};
|
|
294
|
+
fireEvent.tap(button('Share'));
|
|
295
|
+
expect(host.shared).toHaveBeenCalledOnce();
|
|
296
|
+
expect(host.deleted).not.toHaveBeenCalled();
|
|
297
|
+
expect(host.open()).toBe(false);
|
|
298
|
+
});
|
|
137
299
|
|
|
138
|
-
it('
|
|
139
|
-
const {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
expect(
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
const inst = itemResult.componentRef.instance as unknown as {
|
|
154
|
-
onPressStart: () => void;
|
|
155
|
-
onPressEnd: () => void;
|
|
156
|
-
onPressCancel: () => void;
|
|
157
|
-
};
|
|
158
|
-
expect(() => inst.onPressStart()).not.toThrow();
|
|
159
|
-
expect(() => inst.onPressEnd()).not.toThrow();
|
|
160
|
-
expect(() => inst.onPressCancel()).not.toThrow();
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
it('applies destructive variant text class', async () => {
|
|
164
|
-
const { itemResult } = await renderItem();
|
|
165
|
-
const inst = itemResult.componentRef.instance as UiActionSheetItem;
|
|
166
|
-
setInputSignal(inst.variant, 'destructive');
|
|
167
|
-
await waitForUpdate();
|
|
168
|
-
const text = itemResult.container.querySelector('text');
|
|
169
|
-
expect(text?.getAttribute('class')).toContain('text-destructive');
|
|
300
|
+
it('colors its label by variant', async () => {
|
|
301
|
+
const { getByText } = await renderSheet();
|
|
302
|
+
expect(getByText('Share').classList).toContain('text-primary');
|
|
303
|
+
expect(getByText('Delete').classList).toContain('text-destructive');
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
it("merges the class into its tile's own", async () => {
|
|
307
|
+
const { button } = await renderSheet();
|
|
308
|
+
expect(button('Delete').classList).toContain('bg-muted');
|
|
309
|
+
expect(button('Delete').classList).toContain('border-t');
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
it('scales down while pressed, and back on release', async () => {
|
|
313
|
+
const { button } = await renderSheet();
|
|
314
|
+
expectPressFeedback(button('Share'));
|
|
170
315
|
});
|
|
171
316
|
});
|
|
172
317
|
|
|
173
318
|
describe('UiActionSheetCancel', () => {
|
|
174
|
-
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
parent.open.set(true);
|
|
178
|
-
await waitForUpdate();
|
|
319
|
+
it('closes the action sheet when tapped', async () => {
|
|
320
|
+
const { host, button } = await renderSheet();
|
|
321
|
+
await openSheet(host);
|
|
179
322
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
323
|
+
fireEvent.tap(button('Cancel'));
|
|
324
|
+
expect(host.open()).toBe(false);
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
it('shows Cancel, or the label it is given', async () => {
|
|
328
|
+
expect((await renderSheet()).getByText('Cancel')).toBeTruthy();
|
|
329
|
+
const { getByText } = await render(CancelLabelHost);
|
|
330
|
+
expect(getByText('Dismiss')).toBeTruthy();
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
it("merges the class into its tile's own", async () => {
|
|
334
|
+
const { button } = await renderSheet();
|
|
335
|
+
expect(button('Cancel').classList).toContain('mt-2');
|
|
336
|
+
expect(button('Cancel').classList).toContain('bg-card');
|
|
337
|
+
});
|
|
185
338
|
|
|
186
|
-
it('
|
|
187
|
-
const {
|
|
188
|
-
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
it('onTap closes the parent sheet', async () => {
|
|
192
|
-
const { parent, cancelResult } = await renderCancel();
|
|
193
|
-
const inst = cancelResult.componentRef.instance as unknown as {
|
|
194
|
-
onTap: () => void;
|
|
195
|
-
};
|
|
196
|
-
inst.onTap();
|
|
197
|
-
expect(parent.open()).toBe(false);
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
it('press handlers run cleanly', async () => {
|
|
201
|
-
const { cancelResult } = await renderCancel();
|
|
202
|
-
const inst = cancelResult.componentRef.instance as unknown as {
|
|
203
|
-
onPressStart: () => void;
|
|
204
|
-
onPressEnd: () => void;
|
|
205
|
-
onPressCancel: () => void;
|
|
206
|
-
};
|
|
207
|
-
expect(() => inst.onPressStart()).not.toThrow();
|
|
208
|
-
expect(() => inst.onPressEnd()).not.toThrow();
|
|
209
|
-
expect(() => inst.onPressCancel()).not.toThrow();
|
|
339
|
+
it('scales down while pressed, and back on release', async () => {
|
|
340
|
+
const { button } = await renderSheet();
|
|
341
|
+
expectPressFeedback(button('Cancel'));
|
|
210
342
|
});
|
|
211
343
|
});
|