ngwr 11.0.0 → 11.2.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.
- package/action-sheet/styles/_index.scss +4 -1
- package/anchor/styles/_index.scss +2 -1
- package/calendar/styles/_index.scss +11 -2
- package/cascader/styles/_index.scss +3 -1
- package/circular-text/styles/_index.scss +11 -0
- package/command-palette/styles/_index.scss +14 -1
- package/context-menu/styles/_index.scss +2 -1
- package/falling-text/styles/_index.scss +2 -1
- package/fesm2022/ngwr-action-sheet-testing.mjs +313 -0
- package/fesm2022/ngwr-action-sheet-testing.mjs.map +1 -0
- package/fesm2022/ngwr-bar-chart-testing.mjs +89 -0
- package/fesm2022/ngwr-bar-chart-testing.mjs.map +1 -0
- package/fesm2022/ngwr-blur-text-testing.mjs +203 -0
- package/fesm2022/ngwr-blur-text-testing.mjs.map +1 -0
- package/fesm2022/ngwr-blur-text.mjs +15 -1
- package/fesm2022/ngwr-blur-text.mjs.map +1 -1
- package/fesm2022/ngwr-border-glow-testing.mjs +325 -0
- package/fesm2022/ngwr-border-glow-testing.mjs.map +1 -0
- package/fesm2022/ngwr-border-glow.mjs +2 -2
- package/fesm2022/ngwr-breadcrumbs.mjs +2 -2
- package/fesm2022/ngwr-calendar-heatmap-testing.mjs +95 -0
- package/fesm2022/ngwr-calendar-heatmap-testing.mjs.map +1 -0
- package/fesm2022/ngwr-calendar-testing.mjs +368 -0
- package/fesm2022/ngwr-calendar-testing.mjs.map +1 -0
- package/fesm2022/ngwr-calendar.mjs +43 -3
- package/fesm2022/ngwr-calendar.mjs.map +1 -1
- package/fesm2022/ngwr-card.mjs +2 -2
- package/fesm2022/ngwr-cascader.mjs +14 -2
- package/fesm2022/ngwr-cascader.mjs.map +1 -1
- package/fesm2022/ngwr-checkbox.mjs +8 -0
- package/fesm2022/ngwr-checkbox.mjs.map +1 -1
- package/fesm2022/ngwr-circular-text-testing.mjs +230 -0
- package/fesm2022/ngwr-circular-text-testing.mjs.map +1 -0
- package/fesm2022/ngwr-circular-text.mjs +2 -2
- package/fesm2022/ngwr-circular-text.mjs.map +1 -1
- package/fesm2022/ngwr-color-picker-testing.mjs +432 -0
- package/fesm2022/ngwr-color-picker-testing.mjs.map +1 -0
- package/fesm2022/ngwr-color-picker.mjs +29 -3
- package/fesm2022/ngwr-color-picker.mjs.map +1 -1
- package/fesm2022/ngwr-context-menu.mjs +25 -5
- package/fesm2022/ngwr-context-menu.mjs.map +1 -1
- package/fesm2022/ngwr-date-picker-testing.mjs +10 -79
- package/fesm2022/ngwr-date-picker-testing.mjs.map +1 -1
- package/fesm2022/ngwr-decrypt-text-testing.mjs +261 -0
- package/fesm2022/ngwr-decrypt-text-testing.mjs.map +1 -0
- package/fesm2022/ngwr-decrypt-text.mjs +6 -1
- package/fesm2022/ngwr-decrypt-text.mjs.map +1 -1
- package/fesm2022/ngwr-donut-chart-testing.mjs +93 -0
- package/fesm2022/ngwr-donut-chart-testing.mjs.map +1 -0
- package/fesm2022/ngwr-drag-drop.mjs +2 -2
- package/fesm2022/ngwr-drawer.mjs +36 -7
- package/fesm2022/ngwr-drawer.mjs.map +1 -1
- package/fesm2022/ngwr-dropdown.mjs +32 -2
- package/fesm2022/ngwr-dropdown.mjs.map +1 -1
- package/fesm2022/ngwr-event-calendar-testing.mjs +446 -0
- package/fesm2022/ngwr-event-calendar-testing.mjs.map +1 -0
- package/fesm2022/ngwr-event-calendar.mjs +43 -18
- package/fesm2022/ngwr-event-calendar.mjs.map +1 -1
- package/fesm2022/ngwr-falling-text-testing.mjs +218 -0
- package/fesm2022/ngwr-falling-text-testing.mjs.map +1 -0
- package/fesm2022/ngwr-falling-text.mjs +2 -2
- package/fesm2022/ngwr-falling-text.mjs.map +1 -1
- package/fesm2022/ngwr-fuzzy-text-testing.mjs +134 -0
- package/fesm2022/ngwr-fuzzy-text-testing.mjs.map +1 -0
- package/fesm2022/ngwr-gauge-testing.mjs +86 -0
- package/fesm2022/ngwr-gauge-testing.mjs.map +1 -0
- package/fesm2022/ngwr-glitch-text-testing.mjs +181 -0
- package/fesm2022/ngwr-glitch-text-testing.mjs.map +1 -0
- package/fesm2022/ngwr-glitch-text.mjs +2 -2
- package/fesm2022/ngwr-gradient-text-testing.mjs +223 -0
- package/fesm2022/ngwr-gradient-text-testing.mjs.map +1 -0
- package/fesm2022/ngwr-gradient-text.mjs +2 -2
- package/fesm2022/ngwr-i18n-en.mjs +14 -0
- package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ru.mjs +14 -0
- package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
- package/fesm2022/ngwr-image-cropper-testing.mjs +156 -0
- package/fesm2022/ngwr-image-cropper-testing.mjs.map +1 -0
- package/fesm2022/ngwr-image-cropper.mjs +10 -3
- package/fesm2022/ngwr-image-cropper.mjs.map +1 -1
- package/fesm2022/ngwr-input-number.mjs +73 -6
- package/fesm2022/ngwr-input-number.mjs.map +1 -1
- package/fesm2022/ngwr-knob-testing.mjs +220 -0
- package/fesm2022/ngwr-knob-testing.mjs.map +1 -0
- package/fesm2022/ngwr-lightbox-testing.mjs +223 -0
- package/fesm2022/ngwr-lightbox-testing.mjs.map +1 -0
- package/fesm2022/ngwr-lightbox.mjs +9 -2
- package/fesm2022/ngwr-lightbox.mjs.map +1 -1
- package/fesm2022/ngwr-line-chart-testing.mjs +119 -0
- package/fesm2022/ngwr-line-chart-testing.mjs.map +1 -0
- package/fesm2022/ngwr-list.mjs +2 -2
- package/fesm2022/ngwr-loading-bar.mjs +2 -2
- package/fesm2022/ngwr-marquee-testing.mjs +336 -0
- package/fesm2022/ngwr-marquee-testing.mjs.map +1 -0
- package/fesm2022/ngwr-marquee.mjs +2 -2
- package/fesm2022/ngwr-meter-group-testing.mjs +80 -0
- package/fesm2022/ngwr-meter-group-testing.mjs.map +1 -0
- package/fesm2022/ngwr-overlay.mjs +28 -1
- package/fesm2022/ngwr-overlay.mjs.map +1 -1
- package/fesm2022/ngwr-popover.mjs +14 -0
- package/fesm2022/ngwr-popover.mjs.map +1 -1
- package/fesm2022/ngwr-rotating-text-testing.mjs +220 -0
- package/fesm2022/ngwr-rotating-text-testing.mjs.map +1 -0
- package/fesm2022/ngwr-rotating-text.mjs +2 -2
- package/fesm2022/ngwr-rotating-text.mjs.map +1 -1
- package/fesm2022/ngwr-select.mjs +70 -11
- package/fesm2022/ngwr-select.mjs.map +1 -1
- package/fesm2022/ngwr-shiny-text-testing.mjs +237 -0
- package/fesm2022/ngwr-shiny-text-testing.mjs.map +1 -0
- package/fesm2022/ngwr-shiny-text.mjs +2 -2
- package/fesm2022/ngwr-slider.mjs +44 -6
- package/fesm2022/ngwr-slider.mjs.map +1 -1
- package/fesm2022/ngwr-sparkline-testing.mjs +76 -0
- package/fesm2022/ngwr-sparkline-testing.mjs.map +1 -0
- package/fesm2022/ngwr-speed-dial-testing.mjs +279 -0
- package/fesm2022/ngwr-speed-dial-testing.mjs.map +1 -0
- package/fesm2022/ngwr-splash-cursor-testing.mjs +89 -0
- package/fesm2022/ngwr-splash-cursor-testing.mjs.map +1 -0
- package/fesm2022/ngwr-split-text-testing.mjs +224 -0
- package/fesm2022/ngwr-split-text-testing.mjs.map +1 -0
- package/fesm2022/ngwr-split-text.mjs +15 -1
- package/fesm2022/ngwr-split-text.mjs.map +1 -1
- package/fesm2022/ngwr-splitter-testing.mjs +245 -0
- package/fesm2022/ngwr-splitter-testing.mjs.map +1 -0
- package/fesm2022/ngwr-spotlight-card-testing.mjs +368 -0
- package/fesm2022/ngwr-spotlight-card-testing.mjs.map +1 -0
- package/fesm2022/ngwr-spotlight-card.mjs +2 -2
- package/fesm2022/ngwr-star-border-testing.mjs +172 -0
- package/fesm2022/ngwr-star-border-testing.mjs.map +1 -0
- package/fesm2022/ngwr-star-border.mjs +2 -2
- package/fesm2022/ngwr-table.mjs +13 -3
- package/fesm2022/ngwr-table.mjs.map +1 -1
- package/fesm2022/ngwr-tabs.mjs +15 -1
- package/fesm2022/ngwr-tabs.mjs.map +1 -1
- package/fesm2022/ngwr-tilt-card-testing.mjs +190 -0
- package/fesm2022/ngwr-tilt-card-testing.mjs.map +1 -0
- package/fesm2022/ngwr-tilt-card.mjs +21 -3
- package/fesm2022/ngwr-tilt-card.mjs.map +1 -1
- package/fesm2022/ngwr-toast.mjs +36 -7
- package/fesm2022/ngwr-toast.mjs.map +1 -1
- package/fesm2022/ngwr-tour-testing.mjs +173 -0
- package/fesm2022/ngwr-tour-testing.mjs.map +1 -0
- package/fesm2022/ngwr-tour.mjs +2 -2
- package/fesm2022/ngwr-tour.mjs.map +1 -1
- package/fesm2022/ngwr-tree.mjs +10 -3
- package/fesm2022/ngwr-tree.mjs.map +1 -1
- package/fesm2022/ngwr-typewriter-testing.mjs +228 -0
- package/fesm2022/ngwr-typewriter-testing.mjs.map +1 -0
- package/fesm2022/ngwr-typewriter.mjs +2 -2
- package/fesm2022/ngwr-version.mjs +1 -1
- package/fesm2022/ngwr-version.mjs.map +1 -1
- package/fesm2022/ngwr-virtual-scroll.mjs +2 -2
- package/fesm2022/ngwr-waves-testing.mjs +128 -0
- package/fesm2022/ngwr-waves-testing.mjs.map +1 -0
- package/fesm2022/ngwr-waves.mjs +2 -2
- package/fesm2022/ngwr-window-testing.mjs +361 -0
- package/fesm2022/ngwr-window-testing.mjs.map +1 -0
- package/fesm2022/ngwr-window.mjs +84 -10
- package/fesm2022/ngwr-window.mjs.map +1 -1
- package/file-upload/styles/_index.scss +7 -2
- package/i18n/en.json +16 -2
- package/i18n/ru.json +16 -2
- package/llms-full.txt +147 -0
- package/llms.txt +27 -8
- package/mcp/providers.js +29 -0
- package/mcp/tools.js +1 -29
- package/package.json +145 -1
- package/result/styles/_index.scss +3 -1
- package/segmented/styles/_index.scss +5 -1
- package/select/styles/_index.scss +3 -1
- package/skills/ngwr/SKILL.md +115 -0
- package/skills/ngwr/references/catalog.md +212 -0
- package/skills/ngwr/references/setup.md +73 -0
- package/stepper/styles/_index.scss +18 -2
- package/table/styles/_index.scss +3 -1
- package/theme/styles/_colors.scss +15 -2
- package/theme/styles/_dark.scss +24 -12
- package/tree/styles/_index.scss +4 -2
- package/types/ngwr-action-sheet-testing.d.ts +260 -0
- package/types/ngwr-bar-chart-testing.d.ts +77 -0
- package/types/ngwr-blur-text-testing.d.ts +180 -0
- package/types/ngwr-blur-text.d.ts +12 -0
- package/types/ngwr-border-glow-testing.d.ts +219 -0
- package/types/ngwr-calendar-heatmap-testing.d.ts +79 -0
- package/types/ngwr-calendar-testing.d.ts +277 -0
- package/types/ngwr-calendar.d.ts +10 -0
- package/types/ngwr-checkbox.d.ts +13 -0
- package/types/ngwr-circular-text-testing.d.ts +196 -0
- package/types/ngwr-color-picker-testing.d.ts +291 -0
- package/types/ngwr-color-picker.d.ts +13 -1
- package/types/ngwr-context-menu.d.ts +15 -1
- package/types/ngwr-date-picker-testing.d.ts +6 -66
- package/types/ngwr-decrypt-text-testing.d.ts +222 -0
- package/types/ngwr-donut-chart-testing.d.ts +79 -0
- package/types/ngwr-drawer.d.ts +12 -0
- package/types/ngwr-dropdown.d.ts +9 -0
- package/types/ngwr-event-calendar-testing.d.ts +301 -0
- package/types/ngwr-event-calendar.d.ts +9 -6
- package/types/ngwr-falling-text-testing.d.ts +186 -0
- package/types/ngwr-fuzzy-text-testing.d.ts +130 -0
- package/types/ngwr-gauge-testing.d.ts +71 -0
- package/types/ngwr-glitch-text-testing.d.ts +172 -0
- package/types/ngwr-gradient-text-testing.d.ts +173 -0
- package/types/ngwr-image-cropper-testing.d.ts +134 -0
- package/types/ngwr-image-cropper.d.ts +1 -0
- package/types/ngwr-input-number.d.ts +33 -1
- package/types/ngwr-knob-testing.d.ts +150 -0
- package/types/ngwr-lightbox-testing.d.ts +154 -0
- package/types/ngwr-lightbox.d.ts +6 -0
- package/types/ngwr-line-chart-testing.d.ts +93 -0
- package/types/ngwr-marquee-testing.d.ts +280 -0
- package/types/ngwr-meter-group-testing.d.ts +67 -0
- package/types/ngwr-overlay.d.ts +19 -1
- package/types/ngwr-rotating-text-testing.d.ts +191 -0
- package/types/ngwr-select.d.ts +32 -0
- package/types/ngwr-shiny-text-testing.d.ts +165 -0
- package/types/ngwr-slider.d.ts +15 -0
- package/types/ngwr-sparkline-testing.d.ts +69 -0
- package/types/ngwr-speed-dial-testing.d.ts +195 -0
- package/types/ngwr-splash-cursor-testing.d.ts +95 -0
- package/types/ngwr-split-text-testing.d.ts +209 -0
- package/types/ngwr-split-text.d.ts +12 -0
- package/types/ngwr-splitter-testing.d.ts +174 -0
- package/types/ngwr-spotlight-card-testing.d.ts +303 -0
- package/types/ngwr-star-border-testing.d.ts +135 -0
- package/types/ngwr-table.d.ts +10 -1
- package/types/ngwr-tilt-card-testing.d.ts +158 -0
- package/types/ngwr-tilt-card.d.ts +2 -0
- package/types/ngwr-toast.d.ts +14 -5
- package/types/ngwr-tour-testing.d.ts +143 -0
- package/types/ngwr-tree.d.ts +7 -0
- package/types/ngwr-typewriter-testing.d.ts +201 -0
- package/types/ngwr-version.d.ts +1 -1
- package/types/ngwr-waves-testing.d.ts +121 -0
- package/types/ngwr-window-testing.d.ts +263 -0
- package/types/ngwr-window.d.ts +27 -10
- package/window/styles/_index.scss +44 -16
package/types/ngwr-toast.d.ts
CHANGED
|
@@ -105,12 +105,21 @@ interface WrToastConfig {
|
|
|
105
105
|
* @default 5
|
|
106
106
|
*/
|
|
107
107
|
readonly maxStack: number;
|
|
108
|
-
/**
|
|
108
|
+
/**
|
|
109
|
+
* Labels rendered in the UI. Keep short.
|
|
110
|
+
*
|
|
111
|
+
* `null` — the default for every one of them — means "resolve it from the
|
|
112
|
+
* `ngwr/i18n` catalog", which is what makes a Russian app announce a Russian
|
|
113
|
+
* close button without configuring the toast at all. They were English
|
|
114
|
+
* literals here until v11, so the four `toast.*` keys in the shipped catalogs
|
|
115
|
+
* were never read by anything. A string set here still WINS over the catalog:
|
|
116
|
+
* this is the consumer's explicit override, not a default.
|
|
117
|
+
*/
|
|
109
118
|
readonly labels: {
|
|
110
|
-
readonly close: string;
|
|
111
|
-
readonly copy: string;
|
|
112
|
-
readonly copied: string;
|
|
113
|
-
readonly closeAll: string;
|
|
119
|
+
readonly close: string | null;
|
|
120
|
+
readonly copy: string | null;
|
|
121
|
+
readonly copied: string | null;
|
|
122
|
+
readonly closeAll: string | null;
|
|
114
123
|
};
|
|
115
124
|
}
|
|
116
125
|
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { BaseHarnessFilters, ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @license
|
|
5
|
+
*
|
|
6
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
7
|
+
* found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** Narrows which tour popup a harness query matches. */
|
|
11
|
+
interface WrTourHarnessFilters extends BaseHarnessFilters {
|
|
12
|
+
/** Match the step's heading — a string is an exact match, a RegExp is tested. */
|
|
13
|
+
readonly title?: string | RegExp;
|
|
14
|
+
/** Match the step's body copy. */
|
|
15
|
+
readonly content?: string | RegExp;
|
|
16
|
+
}
|
|
17
|
+
/** Which step of how many, as the popup prints it. */
|
|
18
|
+
interface WrTourProgress {
|
|
19
|
+
/** One-based, the way the card counts. */
|
|
20
|
+
readonly current: number;
|
|
21
|
+
/** How many steps the tour was STARTED with — not how many it will show. */
|
|
22
|
+
readonly total: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @license
|
|
27
|
+
*
|
|
28
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
29
|
+
* found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Test harness for the card `WrTour` shows beside the spotlit element.
|
|
34
|
+
*
|
|
35
|
+
* `WrTour` is a service with no element of its own, so there is nothing in your
|
|
36
|
+
* fixture to load: the popup is a portal in the NGWR overlay container, and this
|
|
37
|
+
* comes from `TestbedHarnessEnvironment.documentRootLoader()`. **One card exists at
|
|
38
|
+
* a time** — the service tears the whole step down before opening the next — so a
|
|
39
|
+
* harness held across {@link next} is pointed at a detached element, and a fresh one
|
|
40
|
+
* has to be fetched per step.
|
|
41
|
+
*
|
|
42
|
+
* **The card is rebuilt per step, and that is what makes `getHarnessOrNull` the way
|
|
43
|
+
* to ask whether a tour is running.** There is no "closed" state to read: the popup,
|
|
44
|
+
* the overlay and the spotlight all go away together.
|
|
45
|
+
*
|
|
46
|
+
* **What "last" means here is not `current === total`.** A step whose target is not
|
|
47
|
+
* on the page is skipped, so a tour of three steps can show two, and the service
|
|
48
|
+
* looks AHEAD for a reachable one to decide what the primary button says.
|
|
49
|
+
* {@link getProgress} reports the printed count, {@link getPrimaryLabel} what the
|
|
50
|
+
* button actually reads — asserting the second is what catches a card that says
|
|
51
|
+
* "Next" and then ends the tour.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```ts
|
|
55
|
+
* const rootLoader = TestbedHarnessEnvironment.documentRootLoader(fixture);
|
|
56
|
+
* tour.start(steps);
|
|
57
|
+
* await fixture.whenStable();
|
|
58
|
+
*
|
|
59
|
+
* const card = await rootLoader.getHarness(WrTourHarness);
|
|
60
|
+
* expect(await card.getTitle()).toBe('Search');
|
|
61
|
+
* await card.next();
|
|
62
|
+
* ```
|
|
63
|
+
*
|
|
64
|
+
* @see https://ngwr.dev/guides/testing
|
|
65
|
+
*/
|
|
66
|
+
declare class WrTourHarness extends ComponentHarness {
|
|
67
|
+
static hostSelector: string;
|
|
68
|
+
/** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */
|
|
69
|
+
static with(options?: WrTourHarnessFilters): HarnessPredicate<WrTourHarness>;
|
|
70
|
+
/**
|
|
71
|
+
* Whether this card is still on the page.
|
|
72
|
+
*
|
|
73
|
+
* For a harness you are already HOLDING: moving to another step disposes the
|
|
74
|
+
* overlay, so this flips to `false` where a fresh `getHarnessOrNull()` answers
|
|
75
|
+
* with the NEW card rather than with nothing.
|
|
76
|
+
*/
|
|
77
|
+
isShowing(): Promise<boolean>;
|
|
78
|
+
/** The step's heading, or `null` for a step given no `title`. */
|
|
79
|
+
getTitle(): Promise<string | null>;
|
|
80
|
+
/** The step's body copy. */
|
|
81
|
+
getContent(): Promise<string>;
|
|
82
|
+
/** The progress line as printed, e.g. `Step 2 of 4`. */
|
|
83
|
+
getProgressText(): Promise<string>;
|
|
84
|
+
/**
|
|
85
|
+
* The two numbers out of the progress line, or `null` when it does not hold two.
|
|
86
|
+
*
|
|
87
|
+
* Parsed from the rendered string rather than asked of the service, because the
|
|
88
|
+
* service is not something a harness can reach — and the string is what the user
|
|
89
|
+
* actually gets. A catalog that spells the numbers as words, or reverses them,
|
|
90
|
+
* makes this `null` instead of a wrong answer; assert {@link getProgressText} in
|
|
91
|
+
* that case.
|
|
92
|
+
*
|
|
93
|
+
* `total` is how many steps the tour was STARTED with, not how many it will show:
|
|
94
|
+
* a step whose target is missing is skipped and still counted here, which is the
|
|
95
|
+
* component's own choice and worth knowing before writing an assertion on it.
|
|
96
|
+
*/
|
|
97
|
+
getProgress(): Promise<WrTourProgress | null>;
|
|
98
|
+
/**
|
|
99
|
+
* The name the card announces — its title and the progress line, or just the
|
|
100
|
+
* progress line for an untitled step.
|
|
101
|
+
*
|
|
102
|
+
* The card is an `aria-modal` dialog, so it needs a name; the progress line is
|
|
103
|
+
* what an untitled step has instead of one.
|
|
104
|
+
*/
|
|
105
|
+
getAccessibleName(): Promise<string | null>;
|
|
106
|
+
/** Whether the card announces itself as a modal dialog. */
|
|
107
|
+
isModal(): Promise<boolean>;
|
|
108
|
+
/**
|
|
109
|
+
* Whether the card offers a Back button — which is the same question as "is this
|
|
110
|
+
* the first step", since the button is only rendered past it.
|
|
111
|
+
*/
|
|
112
|
+
hasBack(): Promise<boolean>;
|
|
113
|
+
/**
|
|
114
|
+
* What the primary button READS — the "next" label, or the "done" one on the last
|
|
115
|
+
* step the user will see.
|
|
116
|
+
*
|
|
117
|
+
* The assertion worth writing, and not derivable from the count: the service looks
|
|
118
|
+
* ahead for a step whose target is still on the page, so a tour whose last step is
|
|
119
|
+
* hidden ends one card early and this is the only place that shows.
|
|
120
|
+
*/
|
|
121
|
+
getPrimaryLabel(): Promise<string>;
|
|
122
|
+
/** The Skip button's label. */
|
|
123
|
+
getSkipLabel(): Promise<string>;
|
|
124
|
+
/** The Back button's label. Throws on the first step, where there is none. */
|
|
125
|
+
getBackLabel(): Promise<string>;
|
|
126
|
+
/**
|
|
127
|
+
* Press the primary button — the next step, or the end of the tour.
|
|
128
|
+
*
|
|
129
|
+
* Composed through {@link WrButtonHarness} rather than clicking an element: these
|
|
130
|
+
* are `wr-btn`s, and that harness already knows how one reports being off.
|
|
131
|
+
*/
|
|
132
|
+
next(): Promise<void>;
|
|
133
|
+
/** Press Back. Throws on the first step, where the button is not rendered. */
|
|
134
|
+
back(): Promise<void>;
|
|
135
|
+
/** Press Skip — ending the tour without finishing it. */
|
|
136
|
+
skipTour(): Promise<void>;
|
|
137
|
+
private primary;
|
|
138
|
+
private skip;
|
|
139
|
+
private backButton;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export { WrTourHarness };
|
|
143
|
+
export type { WrTourHarnessFilters, WrTourProgress };
|
package/types/ngwr-tree.d.ts
CHANGED
|
@@ -93,6 +93,13 @@ declare class WrTree<TId = string> implements FormValueControl<unknown> {
|
|
|
93
93
|
readonly openOn: _angular_core.InputSignal<"inline" | "overlay">;
|
|
94
94
|
/** Placeholder shown on the trigger when no node is selected. */
|
|
95
95
|
readonly placeholder: _angular_core.InputSignal<string>;
|
|
96
|
+
/**
|
|
97
|
+
* The same fall-through `wr-select` has had all along: an unset placeholder
|
|
98
|
+
* takes the catalog's `tree.placeholder`, so an overlay trigger with nothing
|
|
99
|
+
* selected reads "Select…" in the app's language instead of rendering an
|
|
100
|
+
* empty span. The key shipped in both catalogs and nothing read it.
|
|
101
|
+
*/
|
|
102
|
+
protected readonly resolvedPlaceholder: _angular_core.Signal<string>;
|
|
96
103
|
/**
|
|
97
104
|
* Accessible name of the overlay trigger. Falls back to the placeholder, then
|
|
98
105
|
* to `select.label` — a `role="combobox"` with nothing selected and no
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { BaseHarnessFilters, ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @license
|
|
5
|
+
*
|
|
6
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
7
|
+
* found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** Narrows which `<wr-typewriter>` a harness query matches. */
|
|
11
|
+
interface WrTypewriterHarnessFilters extends BaseHarnessFilters {
|
|
12
|
+
/**
|
|
13
|
+
* Match what the machine has typed SO FAR — a prefix while it is still going, the
|
|
14
|
+
* whole sentence once it settles, and the empty string before the first tick. A
|
|
15
|
+
* string is an exact match, a RegExp is tested.
|
|
16
|
+
*
|
|
17
|
+
* There is nothing steadier to match on: the component holds no copy of the phrase
|
|
18
|
+
* it is working towards, so a filter cannot address a typewriter by what it is
|
|
19
|
+
* going to say. Pin the clock first — `vi.useFakeTimers` and an explicit advance —
|
|
20
|
+
* or match a RegExp loose enough to survive whichever frame the query lands on.
|
|
21
|
+
*/
|
|
22
|
+
readonly text?: string | RegExp;
|
|
23
|
+
/**
|
|
24
|
+
* Match typewriters showing a caret (`true`) or none at all (`false`).
|
|
25
|
+
*
|
|
26
|
+
* The cursor is REMOVED from the DOM rather than hidden, so this changes mid-run on
|
|
27
|
+
* anything with `hideCursorWhileTyping` — see `WrTypewriterHarness.hasCursor`. On a
|
|
28
|
+
* default typewriter it is stable, and it is the one way to tell two otherwise
|
|
29
|
+
* identical machines apart.
|
|
30
|
+
*/
|
|
31
|
+
readonly hasCursor?: boolean;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @license
|
|
36
|
+
*
|
|
37
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
38
|
+
* found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Test harness for `<wr-typewriter>`.
|
|
43
|
+
*
|
|
44
|
+
* **The typed string is the entire component, and it is a moving target.**
|
|
45
|
+
* {@link getText} reads the one text node the machine writes into, which mid-run holds
|
|
46
|
+
* a FRAGMENT — `'Hell'` on the way to `'Hello'` — and between sentences holds whatever
|
|
47
|
+
* is left of the previous one. That is not a limitation to work around; it is what the
|
|
48
|
+
* component renders, and pinning it tick by tick is what proves the machine types one
|
|
49
|
+
* character at a time, deletes one at a time, pauses, cycles, and stops when told not to
|
|
50
|
+
* loop. Install fake timers for `setTimeout` / `clearTimeout` only and advance the clock
|
|
51
|
+
* yourself before every read — awaiting a harness method flushes microtasks, never
|
|
52
|
+
* timers, so an unadvanced read answers with the previous frame.
|
|
53
|
+
*
|
|
54
|
+
* **What is typed is also what is announced, and no second copy exists.** There is
|
|
55
|
+
* deliberately no `getAccessibleText()` here: the component renders one plain text node
|
|
56
|
+
* and nothing else, so a screen reader landing mid-word hears the fragment. (Its sibling
|
|
57
|
+
* `wr-rotating-text` carries a visually-hidden copy of the whole phrase; this one does
|
|
58
|
+
* not, and inventing a method that implied otherwise would report an accessible layer
|
|
59
|
+
* that is not there.) The single a11y decision the component does make is the caret, and
|
|
60
|
+
* {@link isCursorDecorative} is how a spec holds it: without `aria-hidden` every phrase
|
|
61
|
+
* is announced as `Hello pipe`, and nothing else in the DOM would change.
|
|
62
|
+
*
|
|
63
|
+
* **The methods that are missing are missing on purpose.** There is no `isTyping()` or
|
|
64
|
+
* `getPhase()` — the phase is a private signal that never reaches the document, and its
|
|
65
|
+
* only proxy, the caret vanishing, exists solely when `hideCursorWhileTyping` is set, so
|
|
66
|
+
* the method would report "not typing" for the DEFAULT configuration while the machine
|
|
67
|
+
* types. No `isComplete()` / `isFinished()`: a machine stopped on its last sentence and
|
|
68
|
+
* one pausing between sentences render the identical string and the identical caret, so
|
|
69
|
+
* assert the `sentenceComplete` output instead. No `isCursorBlinking()` /
|
|
70
|
+
* `getCursorOpacity()`: the blink is a `@keyframes` rule from a stylesheet a unit test
|
|
71
|
+
* never loads, and a mid-animation opacity is a number that means nothing.
|
|
72
|
+
* No `isVisible()` / `waitForVisible()`: `startOnVisible` hangs off an
|
|
73
|
+
* `IntersectionObserver` jsdom does not implement, so any answer would be the spec's own
|
|
74
|
+
* stub echoing back. And no `getTypingSpeed()` / `getDeletingSpeed()` /
|
|
75
|
+
* `getPauseDuration()` / `getInitialDelay()`: none of them is ever written to the DOM, so
|
|
76
|
+
* reading them would mean reading the component instance rather than the rendered
|
|
77
|
+
* control. They are observable exactly once — as the cadence of {@link getText}.
|
|
78
|
+
*
|
|
79
|
+
* What DOES survive a test with no layout, besides the string: the caret's presence,
|
|
80
|
+
* glyph and `aria-hidden`, and the two values the host writes inline —
|
|
81
|
+
* {@link getColor} and {@link getCursorBlinkDuration}.
|
|
82
|
+
*
|
|
83
|
+
* ```ts
|
|
84
|
+
* // jsdom implements no IntersectionObserver, so `[startOnVisible]` throws on boot.
|
|
85
|
+
* vi.stubGlobal('IntersectionObserver', StubObserver);
|
|
86
|
+
* // Fake these two and no more: faking the microtask queue deadlocks `whenStable`,
|
|
87
|
+
* // which is where the machine boots and where every harness read stabilizes.
|
|
88
|
+
* vi.useFakeTimers({ toFake: ['setTimeout', 'clearTimeout'] });
|
|
89
|
+
* ```
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```ts
|
|
93
|
+
* const typewriter = await loader.getHarness(WrTypewriterHarness);
|
|
94
|
+
*
|
|
95
|
+
* vi.advanceTimersByTime(0); // the first tick is scheduled at `initialDelay`
|
|
96
|
+
* expect(await typewriter.getText()).toBe('H');
|
|
97
|
+
*
|
|
98
|
+
* vi.advanceTimersByTime(50);
|
|
99
|
+
* expect(await typewriter.getText()).toBe('He');
|
|
100
|
+
* expect(await typewriter.isCursorDecorative()).toBe(true);
|
|
101
|
+
* ```
|
|
102
|
+
*
|
|
103
|
+
* @see https://ngwr.dev/guides/testing
|
|
104
|
+
*/
|
|
105
|
+
declare class WrTypewriterHarness extends ComponentHarness {
|
|
106
|
+
static hostSelector: string;
|
|
107
|
+
/** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */
|
|
108
|
+
static with(options?: WrTypewriterHarnessFilters): HarnessPredicate<WrTypewriterHarness>;
|
|
109
|
+
private readonly content;
|
|
110
|
+
private readonly cursor;
|
|
111
|
+
/**
|
|
112
|
+
* What has been typed so far — a FRAGMENT while the machine is running.
|
|
113
|
+
*
|
|
114
|
+
* This is the whole state machine in one string, and every timing input is observable
|
|
115
|
+
* only through it: one character per `typingSpeed`, one fewer per `deletingSpeed`, the
|
|
116
|
+
* `pauseDuration` gap, the swap to the next entry in `[texts]`, and the stop that
|
|
117
|
+
* `[loop]="false"` puts on the last sentence. `reverseMode` shows up here too, and
|
|
118
|
+
* `[...await getText()].length` is what proves the reversal counted CODE POINTS: a
|
|
119
|
+
* `split('')` reversal turns one emoji into two lone surrogates, which is a pair of
|
|
120
|
+
* broken glyphs on screen and the same character count as a correct answer.
|
|
121
|
+
*
|
|
122
|
+
* Untrimmed, because the fragment is what it is: a phrase typed as far as `'Hello '`
|
|
123
|
+
* genuinely has a trailing space, and trimming would make that frame indistinguishable
|
|
124
|
+
* from the one before it.
|
|
125
|
+
*
|
|
126
|
+
* The empty string is a real state, not a failure — nothing has been typed until the
|
|
127
|
+
* first tick fires, and a deletion run passes back through it on its way to the next
|
|
128
|
+
* sentence.
|
|
129
|
+
*/
|
|
130
|
+
getText(): Promise<string>;
|
|
131
|
+
/**
|
|
132
|
+
* Whether a caret is in the document at all.
|
|
133
|
+
*
|
|
134
|
+
* The component removes the element rather than hiding it, which makes this two
|
|
135
|
+
* questions at once. Statically it answers `showCursor`. While the machine runs it
|
|
136
|
+
* also answers `hideCursorWhileTyping` — and the caret going away is the ONLY evidence
|
|
137
|
+
* anywhere in the DOM that the component considers itself mid-phase, since the phase
|
|
138
|
+
* signal is private. Do not read that as `isTyping()`, though: with
|
|
139
|
+
* `hideCursorWhileTyping` off, which is the default, the caret stays put from the first
|
|
140
|
+
* character to the last.
|
|
141
|
+
*/
|
|
142
|
+
hasCursor(): Promise<boolean>;
|
|
143
|
+
/**
|
|
144
|
+
* The caret glyph, or `null` when there is no caret.
|
|
145
|
+
*
|
|
146
|
+
* `null` rather than `''` on purpose: "no cursor element" and "a cursor element
|
|
147
|
+
* rendering nothing" are different failures, and an interpolated glyph that stopped
|
|
148
|
+
* arriving is exactly the second one. Untrimmed, since a caret can legitimately be a
|
|
149
|
+
* space-padded glyph and `TestElement.text()` would erase it.
|
|
150
|
+
*/
|
|
151
|
+
getCursorCharacter(): Promise<string | null>;
|
|
152
|
+
/**
|
|
153
|
+
* Whether the caret is kept out of the accessibility tree.
|
|
154
|
+
*
|
|
155
|
+
* The component's one deliberate a11y decision, and a silent one to lose: drop the
|
|
156
|
+
* attribute and nothing on screen changes while every phrase starts being announced as
|
|
157
|
+
* `Hello pipe`.
|
|
158
|
+
*
|
|
159
|
+
* Throws when there is no caret. `false` would read as "the caret is announced", which
|
|
160
|
+
* is the opposite of what an absent caret means — and it is the answer a component that
|
|
161
|
+
* stopped rendering its cursor entirely would also give. Ask {@link hasCursor} first
|
|
162
|
+
* when the caret's presence is itself in question.
|
|
163
|
+
*/
|
|
164
|
+
isCursorDecorative(): Promise<boolean>;
|
|
165
|
+
/**
|
|
166
|
+
* The caret's blink half-cycle in seconds, from the custom property the host writes.
|
|
167
|
+
*
|
|
168
|
+
* The blink itself is a CSS keyframe and unobservable, so this custom property is the
|
|
169
|
+
* only channel `[cursorBlinkDuration]` has into it — a binding that quietly stopped
|
|
170
|
+
* writing it would leave the blink stuck at the stylesheet's default with no other
|
|
171
|
+
* symptom anywhere.
|
|
172
|
+
*
|
|
173
|
+
* Throws rather than answering when the property is missing or unparseable, and says
|
|
174
|
+
* which it was. The stylesheet's own `0.5s` fallback is never applied in a test that
|
|
175
|
+
* loads no stylesheets, so an absent property reads as the empty string here — and
|
|
176
|
+
* `0.5` returned from a `parseFloat('')` would be indistinguishable from the component
|
|
177
|
+
* writing the default correctly.
|
|
178
|
+
*/
|
|
179
|
+
getCursorBlinkDuration(): Promise<number>;
|
|
180
|
+
/**
|
|
181
|
+
* The colour the host paints the phrase in, exactly as it is written inline.
|
|
182
|
+
*
|
|
183
|
+
* `[textColors]` cycles per SENTENCE, so this is how a spec pins that the colour index
|
|
184
|
+
* follows the sentence index rather than drifting; and with no colours given the
|
|
185
|
+
* component writes the literal `inherit`, which is a value worth asserting rather than
|
|
186
|
+
* an absence.
|
|
187
|
+
*
|
|
188
|
+
* Read off the `style` ATTRIBUTE rather than through `getCssValue`, which would answer
|
|
189
|
+
* from a computed style. jsdom hands `inherit` straight back, so `getCssValue` would
|
|
190
|
+
* agree here and lie in a real browser, where the keyword resolves to whatever rgb
|
|
191
|
+
* triple the parent happens to carry.
|
|
192
|
+
*
|
|
193
|
+
* Throws when the host carries no `color` declaration: the component writes one on
|
|
194
|
+
* every render, so its absence means the binding is gone, and any string returned in
|
|
195
|
+
* its place would be a guess at what the page inherits.
|
|
196
|
+
*/
|
|
197
|
+
getColor(): Promise<string>;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export { WrTypewriterHarness };
|
|
201
|
+
export type { WrTypewriterHarnessFilters };
|
package/types/ngwr-version.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ import { InjectionToken } from '@angular/core';
|
|
|
16
16
|
* Distinct from `Version` exported by `@angular/core`, which reports the
|
|
17
17
|
* loaded Angular runtime version (e.g. `'22.0.0'`), not ngwr's.
|
|
18
18
|
*/
|
|
19
|
-
declare const NGWR_VERSION = "11.
|
|
19
|
+
declare const NGWR_VERSION = "11.2.0";
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* @license
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { BaseHarnessFilters, ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @license
|
|
5
|
+
*
|
|
6
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
7
|
+
* found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** Narrows which `<wr-waves>` a harness query matches. */
|
|
11
|
+
interface WrWavesHarnessFilters extends BaseHarnessFilters {
|
|
12
|
+
/**
|
|
13
|
+
* Match only fields whose canvas has drawn (`true`) or only fields still showing the
|
|
14
|
+
* stand-in grid (`false`). A wave field has no name of its own, so this is the one
|
|
15
|
+
* state that tells two of them apart — see `WrWavesHarness.isPainted`, which explains
|
|
16
|
+
* why the answer is always `false` in a unit test.
|
|
17
|
+
*/
|
|
18
|
+
readonly painted?: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @license
|
|
23
|
+
*
|
|
24
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
25
|
+
* found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Test harness for `<wr-waves>` — a field of lines drifting on perlin noise.
|
|
30
|
+
*
|
|
31
|
+
* **The lines themselves are unreadable and always will be.** They are strokes on a 2D
|
|
32
|
+
* canvas, seeded from the host's measured box and redrawn every frame; a unit test has
|
|
33
|
+
* no box and no drawing context, so there is nothing to count and nothing to compare.
|
|
34
|
+
* What the component publishes to the DOM is small, deliberate and worth pinning: the
|
|
35
|
+
* handover flag {@link isPainted}, the pitch {@link getLineGapPx} that the CSS stand-in
|
|
36
|
+
* grid draws at before the canvas takes over, and the surface itself.
|
|
37
|
+
*
|
|
38
|
+
* Two style reads, taken two different ways, and the difference is the point.
|
|
39
|
+
* {@link getBackgroundColor} is computed, because nothing but the component declares
|
|
40
|
+
* that property and the resolved value is what gets painted. {@link getLineGapPx} is
|
|
41
|
+
* read from the inline declaration, because the stylesheet declares
|
|
42
|
+
* `--wr-waves-x-gap` too — as the stand-in's own 10px fallback — so a computed read
|
|
43
|
+
* would answer `10px` on a component that had stopped publishing anything, which is
|
|
44
|
+
* precisely the break the method exists to catch.
|
|
45
|
+
*
|
|
46
|
+
* There is no `getLineCount()`, `getPoints()` or `getCanvasSize()`: the grid is seeded
|
|
47
|
+
* from `getBoundingClientRect()`, which is 0×0 here, and the numbers that fall out of
|
|
48
|
+
* that describe nothing. No `getLineColor()` either — it is a canvas `strokeStyle`
|
|
49
|
+
* resolved from a themed custom property that only a stylesheet can supply. No
|
|
50
|
+
* `moveMouse()`: the pointer listeners are on `window` and are only installed once a
|
|
51
|
+
* context exists. And no `isReducedMotion()`, which is the sharpest of them — the
|
|
52
|
+
* reduced-motion path draws one static grid through the same code and sets the same
|
|
53
|
+
* flag, so the DOM is identical either way and any answer would be a guess.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```ts
|
|
57
|
+
* const waves = await loader.getHarness(WrWavesHarness);
|
|
58
|
+
*
|
|
59
|
+
* expect(await waves.hasCanvas()).toBe(true);
|
|
60
|
+
* expect(await waves.isDecorative()).toBe(true);
|
|
61
|
+
* expect(await waves.getLineGapPx()).toBe(10);
|
|
62
|
+
* ```
|
|
63
|
+
*
|
|
64
|
+
* @see https://ngwr.dev/guides/testing
|
|
65
|
+
*/
|
|
66
|
+
declare class WrWavesHarness extends ComponentHarness {
|
|
67
|
+
static hostSelector: string;
|
|
68
|
+
/** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */
|
|
69
|
+
static with(options?: WrWavesHarnessFilters): HarnessPredicate<WrWavesHarness>;
|
|
70
|
+
private readonly canvas;
|
|
71
|
+
/**
|
|
72
|
+
* Whether the canvas has drawn a frame and retired the CSS stand-in grid.
|
|
73
|
+
*
|
|
74
|
+
* **In a unit test this is always `false`, and asserting exactly that is the point.**
|
|
75
|
+
* jsdom hands back no 2D context, so the component must leave the stand-in up rather
|
|
76
|
+
* than declare itself painted over a blank box — the flag is set inside the draw for
|
|
77
|
+
* that reason, not at the end of the boot. A spec that waits for this to turn `true`
|
|
78
|
+
* waits forever.
|
|
79
|
+
*/
|
|
80
|
+
isPainted(): Promise<boolean>;
|
|
81
|
+
/**
|
|
82
|
+
* The horizontal gap between lines, in pixels, as the component publishes it.
|
|
83
|
+
*
|
|
84
|
+
* `[xGap]` feeds the canvas maths, which is invisible here — but it is also published
|
|
85
|
+
* to the stand-in grid, and that is the half a spec can hold: a field whose stand-in
|
|
86
|
+
* draws at 10px and whose canvas then arrives at 40px changes pitch under the reader
|
|
87
|
+
* on hydration, a visible pop that nothing else can catch.
|
|
88
|
+
*/
|
|
89
|
+
getLineGapPx(): Promise<number>;
|
|
90
|
+
/**
|
|
91
|
+
* The fill behind the lines, resolved.
|
|
92
|
+
*
|
|
93
|
+
* Comes back as the browser reports it rather than as it was authored — the default
|
|
94
|
+
* `'transparent'` reads as `'rgba(0, 0, 0, 0)'` and `'#5227ff'` as
|
|
95
|
+
* `'rgb(82, 39, 255)'` — which is true in jsdom and in a real browser alike, so an
|
|
96
|
+
* assertion written against it travels. Worth pinning because the alternative
|
|
97
|
+
* implementation is to fill the canvas instead, and a canvas fill is invisible to
|
|
98
|
+
* everything until it has painted: the background has to be a real declaration on the
|
|
99
|
+
* host so the field is the right colour from the prerendered HTML onwards.
|
|
100
|
+
*/
|
|
101
|
+
getBackgroundColor(): Promise<string>;
|
|
102
|
+
/**
|
|
103
|
+
* Whether the field is hidden from assistive tech.
|
|
104
|
+
*
|
|
105
|
+
* A background canvas has nothing to announce, so losing this leaves a screen reader
|
|
106
|
+
* stopping on a nameless graphic in front of the section's actual content.
|
|
107
|
+
*/
|
|
108
|
+
isDecorative(): Promise<boolean>;
|
|
109
|
+
/**
|
|
110
|
+
* Whether the drawing surface is in the markup.
|
|
111
|
+
*
|
|
112
|
+
* It is there in every state, including the ones where nothing is ever drawn on it —
|
|
113
|
+
* prerendered, no 2D context, reduced motion. That is the contract: the element goes
|
|
114
|
+
* up and the component stops, so the stand-in grid has something to sit behind and
|
|
115
|
+
* {@link isPainted} has something to answer about.
|
|
116
|
+
*/
|
|
117
|
+
hasCanvas(): Promise<boolean>;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export { WrWavesHarness };
|
|
121
|
+
export type { WrWavesHarnessFilters };
|