ngwr 11.1.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/circular-text/styles/_index.scss +11 -0
- package/command-palette/styles/_index.scss +12 -0
- 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-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-cascader.mjs +12 -0
- 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-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-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-gradient-text-testing.mjs +223 -0
- package/fesm2022/ngwr-gradient-text-testing.mjs.map +1 -0
- 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-marquee-testing.mjs +336 -0
- package/fesm2022/ngwr-marquee-testing.mjs.map +1 -0
- 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-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-star-border-testing.mjs +172 -0
- package/fesm2022/ngwr-star-border-testing.mjs.map +1 -0
- 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 +19 -1
- 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-version.mjs +1 -1
- package/fesm2022/ngwr-version.mjs.map +1 -1
- package/fesm2022/ngwr-waves-testing.mjs +128 -0
- package/fesm2022/ngwr-waves-testing.mjs.map +1 -0
- 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/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/skills/ngwr/SKILL.md +115 -0
- package/skills/ngwr/references/catalog.md +212 -0
- package/skills/ngwr/references/setup.md +73 -0
- 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
|
@@ -0,0 +1,196 @@
|
|
|
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-circular-text>` a harness query matches. */
|
|
11
|
+
interface WrCircularTextHarnessFilters extends BaseHarnessFilters {
|
|
12
|
+
/**
|
|
13
|
+
* Match the string the ring announces — the readable copy, not the characters.
|
|
14
|
+
* A string is an exact match, a RegExp is tested.
|
|
15
|
+
*
|
|
16
|
+
* Matched against the accessible copy rather than the host's text because the host
|
|
17
|
+
* carries both: one readable span AND one span per character, so its text reads back
|
|
18
|
+
* as the string twice over and a filter written against it would depend on the split.
|
|
19
|
+
*/
|
|
20
|
+
readonly text?: string | RegExp;
|
|
21
|
+
/**
|
|
22
|
+
* Match on how many characters the ring was laid out from — the divisor every angle is
|
|
23
|
+
* derived from, and the blunt way to address one of two rings without spelling their
|
|
24
|
+
* strings out.
|
|
25
|
+
*/
|
|
26
|
+
readonly characterCount?: number;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @license
|
|
31
|
+
*
|
|
32
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
33
|
+
* found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Test harness for `<wr-circular-text>`.
|
|
38
|
+
*
|
|
39
|
+
* **The ring's geometry is the component's real output, and it is exact without a
|
|
40
|
+
* browser.** Each character is placed by an inline `transform` the component computes —
|
|
41
|
+
* `rotate(360 / N × i deg)` and then a push outward by the orbit radius — so
|
|
42
|
+
* {@link getCharacterAngles} reads the entire layout back as numbers. A broken circle
|
|
43
|
+
* shows up as uneven angles, as an offset that varies per character, or as a surrogate
|
|
44
|
+
* pair torn into two glyphs, and none of those need a single measured pixel.
|
|
45
|
+
*
|
|
46
|
+
* **The spin does not exist in the DOM, and every method that would report it is absent
|
|
47
|
+
* on purpose.** The rotation is one Web Animation on the ring wrapper, advanced by a
|
|
48
|
+
* compositor, and `spinDuration` reaches nothing but that animation's `duration` option
|
|
49
|
+
* — so there is no `getSpinDurationSeconds()` (it would report whatever the spec's own
|
|
50
|
+
* `animate` stub recorded, which is the test reading back its own fixture), no
|
|
51
|
+
* `isSpinning()` and no `getRotationAngle()` (both live on `Animation.currentTime`, in an
|
|
52
|
+
* API jsdom does not implement). There is no `hover()` either: hovering swaps that
|
|
53
|
+
* duration through listeners on the host and changes not one attribute, so a harness
|
|
54
|
+
* hover would appear to work and assert nothing. `pause()` / `resume()` are missing for
|
|
55
|
+
* the same reason — the state is the private `Animation` object, never the document.
|
|
56
|
+
* `respectsReducedMotion()` is the same shape once more: the component honours it by NOT
|
|
57
|
+
* calling `animate`, which is a spec assertion against a stub rather than something a
|
|
58
|
+
* harness can read.
|
|
59
|
+
*
|
|
60
|
+
* **The radius is exposed as text, not as pixels.** `--wr-circular-text-size` and
|
|
61
|
+
* `--wr-circular-text-radius` are declared in the stylesheet, so a test running no
|
|
62
|
+
* stylesheets reads them back empty — hence {@link getOrbitOffsets} hands over the CSS
|
|
63
|
+
* each character carries verbatim instead of a `getRadiusPx()` nobody could compute, and
|
|
64
|
+
* there is no `getCharacterPositions()`: every rect in a unit test is 0×0.
|
|
65
|
+
*
|
|
66
|
+
* **{@link isBonkers} is the one hover mode with a DOM footprint, and the INPUT sets it,
|
|
67
|
+
* not the pointer.** `onHover="goBonkers"` puts the modifier on the host at render time;
|
|
68
|
+
* the scale it enables is a CSS `:hover` rule the harness cannot see. Reading it as "the
|
|
69
|
+
* pointer is over the ring" is exactly backwards.
|
|
70
|
+
*
|
|
71
|
+
* **What is announced and what is drawn are two questions.** The string is carried once
|
|
72
|
+
* in a visually-hidden span, and the ring as a whole is `aria-hidden` so a screen reader
|
|
73
|
+
* hears the word rather than spelling it out — {@link getAccessibleText} is the first,
|
|
74
|
+
* {@link getText} the second, and a spec that read only the second would pass on a
|
|
75
|
+
* component announcing `N. G. W. R.`
|
|
76
|
+
*
|
|
77
|
+
* jsdom implements no Web Animations API and this component animates on mount, so a spec
|
|
78
|
+
* has to supply one of the two halves before the fixture is created — either the API, or
|
|
79
|
+
* a reason not to reach for it:
|
|
80
|
+
*
|
|
81
|
+
* ```ts
|
|
82
|
+
* // Either: mount under reduced motion, where the component never animates at all.
|
|
83
|
+
* // (jsdom has no matchMedia, so WrPlatform must be provided as a value.)
|
|
84
|
+
* TestBed.configureTestingModule({ providers: [{ provide: WrPlatform, useValue: reducedMotion }] });
|
|
85
|
+
*
|
|
86
|
+
* // Or: stub the API. Save the descriptor and put it back by hand in afterEach — this
|
|
87
|
+
* // is an assignment, not a spy, so it leaks into whichever file vitest runs next.
|
|
88
|
+
* Reflect.set(Element.prototype, 'animate', () => ({ cancel: () => undefined }));
|
|
89
|
+
* ```
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```ts
|
|
93
|
+
* const ring = await loader.getHarness(WrCircularTextHarness.with({ text: 'NGWR' }));
|
|
94
|
+
*
|
|
95
|
+
* expect(await ring.getCharacters()).toEqual(['N', 'G', 'W', 'R']);
|
|
96
|
+
* expect(await ring.getCharacterAngles()).toEqual([0, 90, 180, 270]);
|
|
97
|
+
* expect(await ring.getText()).toBe(await ring.getAccessibleText());
|
|
98
|
+
* ```
|
|
99
|
+
*
|
|
100
|
+
* @see https://ngwr.dev/guides/testing
|
|
101
|
+
*/
|
|
102
|
+
declare class WrCircularTextHarness extends ComponentHarness {
|
|
103
|
+
static hostSelector: string;
|
|
104
|
+
/** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */
|
|
105
|
+
static with(options?: WrCircularTextHarnessFilters): HarnessPredicate<WrCircularTextHarness>;
|
|
106
|
+
private readonly chars;
|
|
107
|
+
/**
|
|
108
|
+
* The whole string, as the one readable copy holds it.
|
|
109
|
+
*
|
|
110
|
+
* All a screen reader gets, the ring itself being out of the tree — lose this span and
|
|
111
|
+
* the component becomes a nameless pile of hidden letters, with no other symptom
|
|
112
|
+
* anywhere in the DOM.
|
|
113
|
+
*
|
|
114
|
+
* Untrimmed, deliberately: a ring is usually given a separator-padded string like
|
|
115
|
+
* `'HELLO * NGWR * '`, whose trailing space is a real character that takes a slot on
|
|
116
|
+
* the circle. {@link getText} is meant to compare equal to this, and a trimmed read on
|
|
117
|
+
* either side would forgive losing it.
|
|
118
|
+
*/
|
|
119
|
+
getAccessibleText(): Promise<string>;
|
|
120
|
+
/**
|
|
121
|
+
* The characters laid out around the circle, in DOM order.
|
|
122
|
+
*
|
|
123
|
+
* Pins the splitting rule — `Array.from(text())`, so a surrogate pair is ONE slot and
|
|
124
|
+
* not two broken halves, and a space is its own slot rather than being collapsed away.
|
|
125
|
+
* DOM order is the only order there is: every character is absolutely positioned, so
|
|
126
|
+
* the sequence here is what the angles below are indexed by.
|
|
127
|
+
*/
|
|
128
|
+
getCharacters(): Promise<string[]>;
|
|
129
|
+
/**
|
|
130
|
+
* Everything the ring draws, put back together in DOM order.
|
|
131
|
+
*
|
|
132
|
+
* The assertion this exists for is `getText() === getAccessibleText()`: the split has
|
|
133
|
+
* to be lossless. Read from the character spans rather than from the host, because the
|
|
134
|
+
* host also holds the readable copy and would report the string twice over.
|
|
135
|
+
*/
|
|
136
|
+
getText(): Promise<string>;
|
|
137
|
+
/** How many slots the circle was divided into — the divisor every angle is derived from. */
|
|
138
|
+
getCharacterCount(): Promise<number>;
|
|
139
|
+
/**
|
|
140
|
+
* Where each character sits on the circle, in degrees, in DOM order.
|
|
141
|
+
*
|
|
142
|
+
* The component's whole geometric output, and the one thing that tells a ring from a
|
|
143
|
+
* crowded arc: the angles must start at 0 and be exactly `360 / N` apart. Empty text
|
|
144
|
+
* yields an empty array — no characters, no angles.
|
|
145
|
+
*
|
|
146
|
+
* Throws for a character carrying no rotation of its own rather than reporting `0` or
|
|
147
|
+
* `NaN` for it. Both of those describe a ring collapsed onto a single point as though
|
|
148
|
+
* nothing were wrong, and that is precisely the failure this method exists to catch.
|
|
149
|
+
*/
|
|
150
|
+
getCharacterAngles(): Promise<number[]>;
|
|
151
|
+
/**
|
|
152
|
+
* How far each character is pushed out from the centre, as the CSS the component wrote.
|
|
153
|
+
*
|
|
154
|
+
* A string rather than a number, and that is the honest answer: the distance is
|
|
155
|
+
* `calc(-1 * var(--wr-circular-text-radius))`, a custom property the STYLESHEET
|
|
156
|
+
* declares, so there is no pixel value to resolve in a test that loads no stylesheet.
|
|
157
|
+
* What matters is assertable anyway — every character must be pushed out by the SAME
|
|
158
|
+
* offset, along the same axis. A per-character or axis-mixed one is the classic bug
|
|
159
|
+
* that turns the ring into a diagonal line, and it survives every other check here
|
|
160
|
+
* because the angles stay perfect while it happens.
|
|
161
|
+
*
|
|
162
|
+
* Throws on the same unplaced character {@link getCharacterAngles} does, for the same
|
|
163
|
+
* reason.
|
|
164
|
+
*/
|
|
165
|
+
getOrbitOffsets(): Promise<string[]>;
|
|
166
|
+
/**
|
|
167
|
+
* Whether the host carries the `wr-circular-text--bonkers` modifier.
|
|
168
|
+
*
|
|
169
|
+
* Set from the `onHover` INPUT being `'goBonkers'` — at render time, before anyone has
|
|
170
|
+
* hovered anything — which is the one assumption a spec author makes backwards here.
|
|
171
|
+
* It is also the only one of the four hover modes with any DOM footprint at all; the
|
|
172
|
+
* other three exist purely as a number handed to a Web Animation.
|
|
173
|
+
*/
|
|
174
|
+
isBonkers(): Promise<boolean>;
|
|
175
|
+
/**
|
|
176
|
+
* Whether the ring is out of the accessibility tree.
|
|
177
|
+
*
|
|
178
|
+
* ONE attribute answers this, and that is the contract rather than an approximation:
|
|
179
|
+
* `aria-hidden` sits on the `__spin` wrapper, so the letters underneath inherit it and
|
|
180
|
+
* none of them carries the attribute itself — which keeps it off the nodes the rotation
|
|
181
|
+
* touches. Asserting it per character would fail on a component that is behaving.
|
|
182
|
+
*
|
|
183
|
+
* Answers for the wrapper even when the text is empty, and that is deliberate: the
|
|
184
|
+
* wrapper is always rendered, so there is no vacuous case to guard against — a ring
|
|
185
|
+
* with nothing in it is still correctly hidden or incorrectly readable.
|
|
186
|
+
*
|
|
187
|
+
* Assert it together with {@link getAccessibleText}: hidden letters AND no readable
|
|
188
|
+
* copy is an element with no accessible name at all, which passes either check alone.
|
|
189
|
+
*/
|
|
190
|
+
areCharactersHiddenFromAssistiveTech(): Promise<boolean>;
|
|
191
|
+
/** Each character's placement, parsed once out of the inline transform it carries. */
|
|
192
|
+
private placements;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export { WrCircularTextHarness };
|
|
196
|
+
export type { WrCircularTextHarnessFilters };
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { BaseHarnessFilters, ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';
|
|
2
|
+
import { WrSegmentedHarness } from 'ngwr/segmented/testing';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @license
|
|
6
|
+
*
|
|
7
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
8
|
+
* found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/** Which set of numeric fields the picker is showing. */
|
|
12
|
+
type WrColorPickerTab = 'hex' | 'rgb' | 'hsl';
|
|
13
|
+
/** Narrows which `<wr-color-picker>` a harness query matches. */
|
|
14
|
+
interface WrColorPickerHarnessFilters extends BaseHarnessFilters {
|
|
15
|
+
/**
|
|
16
|
+
* Match the picker's current colour, as the preview swatch paints it — always
|
|
17
|
+
* hex, whatever `format` writes into `value`. A string is an exact match, a
|
|
18
|
+
* RegExp is tested.
|
|
19
|
+
*/
|
|
20
|
+
readonly color?: string | RegExp;
|
|
21
|
+
/** Match only pickers showing this tab. */
|
|
22
|
+
readonly tab?: WrColorPickerTab;
|
|
23
|
+
/** Match only enabled (`false`) or only disabled (`true`) pickers. */
|
|
24
|
+
readonly disabled?: boolean;
|
|
25
|
+
}
|
|
26
|
+
/** Narrows which `[wrColorPickerTrigger]` a harness query matches. */
|
|
27
|
+
interface WrColorPickerTriggerHarnessFilters extends BaseHarnessFilters {
|
|
28
|
+
/** Match the trigger's own text, an exact string or a RegExp. */
|
|
29
|
+
readonly text?: string | RegExp;
|
|
30
|
+
/** Match only open (`true`) or only closed (`false`) triggers. */
|
|
31
|
+
readonly open?: boolean;
|
|
32
|
+
}
|
|
33
|
+
/** The percentage each of the picker's thumbs sits at along its surface. */
|
|
34
|
+
interface WrColorPickerThumbs {
|
|
35
|
+
/** Saturation across, value down — both 0–100, and `y` is inverted (0 % is full brightness). */
|
|
36
|
+
readonly sv: {
|
|
37
|
+
readonly x: number;
|
|
38
|
+
readonly y: number;
|
|
39
|
+
};
|
|
40
|
+
/** Hue along its slider, 0–100 (so 50 is 180°). */
|
|
41
|
+
readonly hue: number;
|
|
42
|
+
/** Alpha along its slider, 0–100, or `null` when the picker has no alpha. */
|
|
43
|
+
readonly alpha: number | null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @license
|
|
48
|
+
*
|
|
49
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
50
|
+
* found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
|
|
51
|
+
*/
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Test harness for `<wr-color-picker>` — the inline picker, and the one the
|
|
55
|
+
* `[wrColorPickerTrigger]` directive mounts in an overlay.
|
|
56
|
+
*
|
|
57
|
+
* **What this harness will not do: drag.** The SV canvas and the hue / alpha
|
|
58
|
+
* sliders are pointer surfaces that read `getBoundingClientRect()` and divide by
|
|
59
|
+
* its width. A unit test has no layout, so every box is 0×0 and the division is
|
|
60
|
+
* `NaN` — a `setHue()` built on a synthetic pointer event would report success and
|
|
61
|
+
* write nothing, or write garbage. The numeric fields reach the same state and are
|
|
62
|
+
* also the only keyboard path the component has, so they are the whole write API
|
|
63
|
+
* here. {@link getThumbs} reads where the thumbs ARE, from the percentages the
|
|
64
|
+
* component writes inline, which is how a spec checks a surface followed a value.
|
|
65
|
+
*
|
|
66
|
+
* **And it will not read the preview swatch.** The preview paints the current
|
|
67
|
+
* colour as a CSS background, and jsdom normalises that to `rgb(…)` — dropping the
|
|
68
|
+
* alpha channel entirely, so `#ff880080` and `#ff8800ff` come back identical. A
|
|
69
|
+
* `getColor()` reading it would answer one thing in a unit test and another in a
|
|
70
|
+
* browser. {@link getHex} is the colour: the field holds the canonical 8-digit
|
|
71
|
+
* string, alpha included, whatever `format` writes into `value`.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```ts
|
|
75
|
+
* const picker = await loader.getHarness(WrColorPickerHarness);
|
|
76
|
+
*
|
|
77
|
+
* await picker.setHex('#3969e2');
|
|
78
|
+
* expect(await picker.getHex()).toBe('#3969e2ff');
|
|
79
|
+
*
|
|
80
|
+
* await picker.setTab('rgb');
|
|
81
|
+
* expect(await picker.getRgb()).toEqual({ r: 57, g: 105, b: 226 });
|
|
82
|
+
* ```
|
|
83
|
+
*
|
|
84
|
+
* @see https://ngwr.dev/guides/testing
|
|
85
|
+
*/
|
|
86
|
+
declare class WrColorPickerHarness extends ComponentHarness {
|
|
87
|
+
static hostSelector: string;
|
|
88
|
+
/** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */
|
|
89
|
+
static with(options?: WrColorPickerHarnessFilters): HarnessPredicate<WrColorPickerHarness>;
|
|
90
|
+
private readonly hexField;
|
|
91
|
+
private readonly tabs;
|
|
92
|
+
/**
|
|
93
|
+
* The tab switcher, as a {@link WrSegmentedHarness}.
|
|
94
|
+
*
|
|
95
|
+
* Handed back rather than re-queried: the switcher IS a `<wr-segmented>`, which
|
|
96
|
+
* already knows that the roving tab stop is not the selection and how the sliding
|
|
97
|
+
* thumb reports itself. Re-reading its buttons here would be a second, worse copy.
|
|
98
|
+
*/
|
|
99
|
+
getTabs(): Promise<WrSegmentedHarness>;
|
|
100
|
+
/** Which set of numeric fields is showing. */
|
|
101
|
+
getTab(): Promise<WrColorPickerTab>;
|
|
102
|
+
/** Show a different set of numeric fields. An already-active tab is left alone. */
|
|
103
|
+
setTab(tab: WrColorPickerTab): Promise<void>;
|
|
104
|
+
/**
|
|
105
|
+
* The canonical hex string, as the HEX field shows it — 8 digits while `alpha` is
|
|
106
|
+
* on, 6 while it is off.
|
|
107
|
+
*
|
|
108
|
+
* This is the picker's colour, and deliberately not the same thing as its `value`:
|
|
109
|
+
* `format` decides whether `value` is written as hex, `rgb()` or `hsl()`, while the
|
|
110
|
+
* field always shows hex. A spec that cares about the emitted string should read
|
|
111
|
+
* the bound signal; one that cares about the COLOUR should read this.
|
|
112
|
+
*
|
|
113
|
+
* Throws off the HEX tab, where the field does not exist — see {@link setTab}.
|
|
114
|
+
*/
|
|
115
|
+
getHex(): Promise<string>;
|
|
116
|
+
/**
|
|
117
|
+
* Type a colour into the HEX field.
|
|
118
|
+
*
|
|
119
|
+
* Typed rather than assigned, because that is the path the component is built
|
|
120
|
+
* around: it re-parses on every keystroke and applies the first spelling that
|
|
121
|
+
* parses, so a partial `#ff8` commits a colour on its way to `#ff8800`. An
|
|
122
|
+
* unparseable string leaves the committed colour ALONE and lives in the field
|
|
123
|
+
* until {@link blurHex} snaps it back — assert that rather than expecting a throw.
|
|
124
|
+
*/
|
|
125
|
+
setHex(value: string): Promise<void>;
|
|
126
|
+
/**
|
|
127
|
+
* Blur the HEX field — re-syncing it with the committed colour and emitting
|
|
128
|
+
* `touch`.
|
|
129
|
+
*
|
|
130
|
+
* The re-sync is the visible half: a field left holding text that never parsed
|
|
131
|
+
* goes back to the canonical hex here, and nowhere else.
|
|
132
|
+
*/
|
|
133
|
+
blurHex(): Promise<void>;
|
|
134
|
+
/** Whether the HEX field currently holds focus. */
|
|
135
|
+
isHexFocused(): Promise<boolean>;
|
|
136
|
+
/** The three RGB channels as the RGB tab shows them. Throws off that tab. */
|
|
137
|
+
getRgb(): Promise<{
|
|
138
|
+
r: number;
|
|
139
|
+
g: number;
|
|
140
|
+
b: number;
|
|
141
|
+
}>;
|
|
142
|
+
/** Write one RGB channel, 0–255. Out-of-range numbers are clamped by the component. */
|
|
143
|
+
setRgbChannel(channel: 'r' | 'g' | 'b', value: number): Promise<void>;
|
|
144
|
+
/**
|
|
145
|
+
* Hue, saturation and lightness as the HSL tab shows them — degrees and whole
|
|
146
|
+
* percents, already rounded for display. Throws off that tab.
|
|
147
|
+
*/
|
|
148
|
+
getHsl(): Promise<{
|
|
149
|
+
h: number;
|
|
150
|
+
s: number;
|
|
151
|
+
l: number;
|
|
152
|
+
}>;
|
|
153
|
+
/** Write one HSL channel — `h` in degrees, `s` / `l` in percent. */
|
|
154
|
+
setHslChannel(channel: 'h' | 's' | 'l', value: number): Promise<void>;
|
|
155
|
+
/**
|
|
156
|
+
* Alpha as the whole percent the numeric tabs show, or `null` when the picker was
|
|
157
|
+
* built without alpha.
|
|
158
|
+
*
|
|
159
|
+
* Only the RGB and HSL tabs carry the field — the HEX tab spells alpha into the
|
|
160
|
+
* hex string instead — so this throws on the HEX tab rather than answering `null`,
|
|
161
|
+
* which would read as "this picker has no alpha".
|
|
162
|
+
*/
|
|
163
|
+
getAlphaPercent(): Promise<number | null>;
|
|
164
|
+
/** Write alpha as a whole percent, 0–100. */
|
|
165
|
+
setAlphaPercent(value: number): Promise<void>;
|
|
166
|
+
/**
|
|
167
|
+
* Whether the picker offers alpha at all.
|
|
168
|
+
*
|
|
169
|
+
* From the host modifier, which is the one answer that holds on every tab: the
|
|
170
|
+
* alpha SLIDER is always rendered when it is on, while the `A%` field only exists
|
|
171
|
+
* on the two numeric tabs.
|
|
172
|
+
*/
|
|
173
|
+
hasAlpha(): Promise<boolean>;
|
|
174
|
+
/**
|
|
175
|
+
* Whether the picker refuses interaction.
|
|
176
|
+
*
|
|
177
|
+
* Read from the modifier the host paints rather than from a field's `disabled`
|
|
178
|
+
* property, because the fields come and go with the tab while the state does not —
|
|
179
|
+
* and the drag surfaces, which have no `disabled` of their own, are gated by the
|
|
180
|
+
* same signal.
|
|
181
|
+
*/
|
|
182
|
+
isDisabled(): Promise<boolean>;
|
|
183
|
+
/** The preset colours offered under the fields, as the strings the consumer passed. */
|
|
184
|
+
getSwatches(): Promise<string[]>;
|
|
185
|
+
/**
|
|
186
|
+
* Click a preset.
|
|
187
|
+
*
|
|
188
|
+
* Matched on the string the consumer passed, which is what the button publishes as
|
|
189
|
+
* its accessible name — the rendered background is a CSS colour and would come back
|
|
190
|
+
* normalised and alpha-stripped. Throws when nothing matches, naming what is offered.
|
|
191
|
+
*/
|
|
192
|
+
pickSwatch(color: string): Promise<void>;
|
|
193
|
+
/**
|
|
194
|
+
* Where the three thumbs sit, in percent along their surfaces.
|
|
195
|
+
*
|
|
196
|
+
* The component writes these as inline `left` / `top` percentages, so they are
|
|
197
|
+
* readable with no layout at all — which makes them the only evidence a spec has
|
|
198
|
+
* that the surfaces followed a colour set through the fields. A measured position
|
|
199
|
+
* would be zero for all three.
|
|
200
|
+
*/
|
|
201
|
+
getThumbs(): Promise<WrColorPickerThumbs>;
|
|
202
|
+
/** The HEX field's value without the tab check — for filters, which must not throw. */
|
|
203
|
+
private readHex;
|
|
204
|
+
private requireHexField;
|
|
205
|
+
private channelValues;
|
|
206
|
+
private writeChannel;
|
|
207
|
+
private requireTab;
|
|
208
|
+
/** Every numeric input of the current tab, keyed by the label printed under it. */
|
|
209
|
+
private inputsByLabel;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* @license
|
|
214
|
+
*
|
|
215
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
216
|
+
* found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
|
|
217
|
+
*/
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Test harness for `[wrColorPickerTrigger]` — the element that opens a
|
|
221
|
+
* `<wr-color-picker>` in an overlay.
|
|
222
|
+
*
|
|
223
|
+
* The trigger stays in your fixture; the picker it opens does not. So this harness
|
|
224
|
+
* is loaded from the fixture loader like any element, and {@link getPicker} reaches
|
|
225
|
+
* ACROSS into the overlay container for you — scoped by the panel id the trigger
|
|
226
|
+
* publishes through `aria-controls`, never by `.wr-color-picker-overlay`, which
|
|
227
|
+
* answers with whichever trigger opened first.
|
|
228
|
+
*
|
|
229
|
+
* @example
|
|
230
|
+
* ```ts
|
|
231
|
+
* const trigger = await loader.getHarness(WrColorPickerTriggerHarness);
|
|
232
|
+
* const picker = await trigger.open();
|
|
233
|
+
*
|
|
234
|
+
* await picker.setHex('#3969e2');
|
|
235
|
+
* await trigger.sendEscape();
|
|
236
|
+
* expect(await trigger.isOpen()).toBe(false);
|
|
237
|
+
* ```
|
|
238
|
+
*
|
|
239
|
+
* @see https://ngwr.dev/guides/testing
|
|
240
|
+
*/
|
|
241
|
+
declare class WrColorPickerTriggerHarness extends ComponentHarness {
|
|
242
|
+
static hostSelector: string;
|
|
243
|
+
/** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */
|
|
244
|
+
static with(options?: WrColorPickerTriggerHarnessFilters): HarnessPredicate<WrColorPickerTriggerHarness>;
|
|
245
|
+
/** The trigger's own text, trimmed. */
|
|
246
|
+
getText(): Promise<string>;
|
|
247
|
+
/** Whether the picker is showing, from the trigger's `aria-expanded`. */
|
|
248
|
+
isOpen(): Promise<boolean>;
|
|
249
|
+
/**
|
|
250
|
+
* Whether the trigger refuses to open.
|
|
251
|
+
*
|
|
252
|
+
* From `aria-disabled`, which the directive writes for its own `disabled` input.
|
|
253
|
+
* The host is usually a `<button>`, but the directive does not touch its `disabled`
|
|
254
|
+
* PROPERTY — a consumer who binds that as well turns the element off at the DOM
|
|
255
|
+
* level, which is a stronger thing and reads here too.
|
|
256
|
+
*/
|
|
257
|
+
isDisabled(): Promise<boolean>;
|
|
258
|
+
/**
|
|
259
|
+
* The picker this trigger opened, or `null` while it is closed.
|
|
260
|
+
*
|
|
261
|
+
* Scoped by the id in `aria-controls`, so two triggers open at once — which
|
|
262
|
+
* nothing in the component prevents, since only an outside click closes one —
|
|
263
|
+
* answer with their own panels rather than with whichever came first.
|
|
264
|
+
*/
|
|
265
|
+
getPicker(): Promise<WrColorPickerHarness | null>;
|
|
266
|
+
/**
|
|
267
|
+
* Open the picker and hand it back. An already-open trigger is left alone.
|
|
268
|
+
*
|
|
269
|
+
* Throws on a disabled trigger rather than answering `null` three lines later:
|
|
270
|
+
* `toggle()` returns early while `disabled` is set, so the click lands and nothing
|
|
271
|
+
* happens at all.
|
|
272
|
+
*/
|
|
273
|
+
open(): Promise<WrColorPickerHarness>;
|
|
274
|
+
/** Close the picker. An already-closed trigger is left alone. */
|
|
275
|
+
close(): Promise<void>;
|
|
276
|
+
/** Click the trigger once, whichever way that takes it. */
|
|
277
|
+
toggle(): Promise<void>;
|
|
278
|
+
/**
|
|
279
|
+
* Press Escape.
|
|
280
|
+
*
|
|
281
|
+
* Sent to the TRIGGER, and it still reaches the picker: the overlay listens through
|
|
282
|
+
* the CDK's keyboard dispatcher, which keeps one document listener and routes to
|
|
283
|
+
* the top-most overlay — so this does not depend on where focus happens to be.
|
|
284
|
+
*/
|
|
285
|
+
sendEscape(): Promise<void>;
|
|
286
|
+
/** The role the trigger claims to open — `dialog`. */
|
|
287
|
+
getHasPopup(): Promise<string | null>;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
export { WrColorPickerHarness, WrColorPickerTriggerHarness };
|
|
291
|
+
export type { WrColorPickerHarnessFilters, WrColorPickerTab, WrColorPickerThumbs, WrColorPickerTriggerHarnessFilters };
|
|
@@ -236,7 +236,17 @@ declare class WrColorPicker implements FormValueControl<string> {
|
|
|
236
236
|
protected readonly alphaPercent: _angular_core.Signal<number>;
|
|
237
237
|
protected readonly tabOptions: readonly WrSegmentedOption<Tab>[];
|
|
238
238
|
protected readonly classes: _angular_core.Signal<string>;
|
|
239
|
-
/**
|
|
239
|
+
/**
|
|
240
|
+
* The one write we just made, held only until the sync effect has seen it.
|
|
241
|
+
*
|
|
242
|
+
* It exists so a drag keeps its continuous HSV values instead of being
|
|
243
|
+
* re-quantised through its own hex round-trip. It used to be set and never
|
|
244
|
+
* cleared, which turned "ignore this write" into "ignore this STRING,
|
|
245
|
+
* forever": after the picker emitted `#ff0000` once, an app writing
|
|
246
|
+
* `#ff0000` back — a reset button, a form patch, an undo — was silently
|
|
247
|
+
* dropped for the rest of the component's life, and the surface kept
|
|
248
|
+
* whatever colour the user had dragged to.
|
|
249
|
+
*/
|
|
240
250
|
private lastEmitted;
|
|
241
251
|
constructor();
|
|
242
252
|
protected onPointerDown(event: PointerEvent, surface: Edges): void;
|
|
@@ -301,6 +311,8 @@ declare class WrColorPickerTrigger {
|
|
|
301
311
|
private readonly destroyRef;
|
|
302
312
|
protected readonly isOpen: _angular_core.WritableSignal<boolean>;
|
|
303
313
|
private overlayRef;
|
|
314
|
+
/** @internal Public so the host binding can read it. */
|
|
315
|
+
protected readonly panelId: string;
|
|
304
316
|
constructor();
|
|
305
317
|
/** Toggle the picker. Open if closed, close if open. */
|
|
306
318
|
toggle(): void;
|
|
@@ -66,7 +66,21 @@ declare class WrContextMenu {
|
|
|
66
66
|
*/
|
|
67
67
|
protected readonly openMenuId: _angular_core.WritableSignal<string | null>;
|
|
68
68
|
private overlayRef;
|
|
69
|
-
|
|
69
|
+
/**
|
|
70
|
+
* Panes waiting out their exit animation, keyed by the timer that disposes
|
|
71
|
+
* them.
|
|
72
|
+
*
|
|
73
|
+
* A SET, because one handle cannot hold two closings. It used to be a single
|
|
74
|
+
* `closingTimer`, and the second close inside the 220ms window cleared the
|
|
75
|
+
* first one's timer instead of its own — so the previous pane's `dispose()`
|
|
76
|
+
* never ran. `onContextMenu` closes and immediately re-opens, so right-clicking
|
|
77
|
+
* one target faster than the animation orphaned a pane per click: an
|
|
78
|
+
* `opacity: 0` box with `pointer-events: auto` eating clicks, a never-destroyed
|
|
79
|
+
* embedded view, a capture-phase document scroll listener still moving it, and
|
|
80
|
+
* an undetached ref still registered with CDK's keyboard dispatcher — which
|
|
81
|
+
* swallowed Escape for the whole page.
|
|
82
|
+
*/
|
|
83
|
+
private readonly closingPanes;
|
|
70
84
|
private leaveTimer;
|
|
71
85
|
private pressTimer;
|
|
72
86
|
private pressX;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { WrCalendarDayHarness } from 'ngwr/calendar/testing';
|
|
2
|
+
export { WrCalendarDayHarness as WrDatePickerDayHarness } from 'ngwr/calendar/testing';
|
|
3
|
+
import { BaseHarnessFilters, ComponentHarness, TestElement, HarnessLoader, HarnessPredicate } from '@angular/cdk/testing';
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* @license
|
|
@@ -77,68 +79,6 @@ interface WrDatePickerTimeFields {
|
|
|
77
79
|
readonly seconds?: number;
|
|
78
80
|
}
|
|
79
81
|
|
|
80
|
-
/**
|
|
81
|
-
* @license
|
|
82
|
-
*
|
|
83
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
84
|
-
* found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
|
|
85
|
-
*/
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Test harness for one day cell of the calendar inside a date-picker popup.
|
|
89
|
-
*
|
|
90
|
-
* Reached through `WrDatePickerHarness.getDay()` / `getDays()` (or the range
|
|
91
|
-
* picker's), which scope it to ONE picker's panel — the cells are in the overlay
|
|
92
|
-
* container, so a bare query would answer with whichever picker opened first.
|
|
93
|
-
*
|
|
94
|
-
* State is read the way a screen reader reads it (`role`, `aria-selected`,
|
|
95
|
-
* `aria-disabled`) with the `.wr-calendar__day--*` modifiers filling in what
|
|
96
|
-
* ARIA has no word for: today, the spill days of the neighbouring months, and
|
|
97
|
-
* the interior of a picked range.
|
|
98
|
-
*
|
|
99
|
-
* @see https://ngwr.dev/guides/testing
|
|
100
|
-
*/
|
|
101
|
-
declare class WrDatePickerDayHarness extends ComponentHarness {
|
|
102
|
-
static hostSelector: string;
|
|
103
|
-
/** Build a predicate that narrows the query. */
|
|
104
|
-
static with(options?: WrDatePickerDayHarnessFilters): HarnessPredicate<WrDatePickerDayHarness>;
|
|
105
|
-
/** The day number as rendered. */
|
|
106
|
-
getText(): Promise<string>;
|
|
107
|
-
/** The day number as a number, for mapping a list of cells to dates. */
|
|
108
|
-
getDayOfMonth(): Promise<number>;
|
|
109
|
-
/** `'gridcell'` — the cell is a button, and the grid semantics are what a spec should assert. */
|
|
110
|
-
getRole(): Promise<string | null>;
|
|
111
|
-
/** Whether this day is (one end of) the current selection. */
|
|
112
|
-
isSelected(): Promise<boolean>;
|
|
113
|
-
/**
|
|
114
|
-
* Whether the day refuses selection — `min` / `max` or `dateFilter` ruled it
|
|
115
|
-
* out, or the whole calendar is disabled.
|
|
116
|
-
*/
|
|
117
|
-
isDisabled(): Promise<boolean>;
|
|
118
|
-
/** Whether the cell is today's date. */
|
|
119
|
-
isToday(): Promise<boolean>;
|
|
120
|
-
/**
|
|
121
|
-
* Whether the cell belongs to a neighbouring month. The grid is always 6x7, so
|
|
122
|
-
* every month is padded with days that are selectable but not "in" the month —
|
|
123
|
-
* which is why {@link WrDatePickerHarness.getDay} skips them.
|
|
124
|
-
*/
|
|
125
|
-
isOutOfMonth(): Promise<boolean>;
|
|
126
|
-
/** Whether the day lies strictly between the two ends of a picked range. */
|
|
127
|
-
isInRange(): Promise<boolean>;
|
|
128
|
-
/**
|
|
129
|
-
* Whether this is the roving cell — the grid's single tab stop, and where the
|
|
130
|
-
* arrow keys move from.
|
|
131
|
-
*
|
|
132
|
-
* At most ONE cell answers `true`, and it is not always one: the calendar's
|
|
133
|
-
* roving date does not follow `next()` / `previous()`, so a grid navigated away
|
|
134
|
-
* from that month has no active cell (and, deliberately or not, no tab stop)
|
|
135
|
-
* until a cell is clicked or the arrows move it.
|
|
136
|
-
*/
|
|
137
|
-
isActive(): Promise<boolean>;
|
|
138
|
-
/** Click the cell. A disabled cell swallows the click — assert, do not assume. */
|
|
139
|
-
click(): Promise<void>;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
82
|
/**
|
|
143
83
|
* @license
|
|
144
84
|
*
|
|
@@ -277,12 +217,12 @@ declare abstract class WrDatePickerHarnessBase extends ComponentHarness {
|
|
|
277
217
|
* them, since the grid is always six weeks and pads into the neighbouring
|
|
278
218
|
* months.
|
|
279
219
|
*/
|
|
280
|
-
getDays(filters?: WrDatePickerDayHarnessFilters): Promise<
|
|
220
|
+
getDays(filters?: WrDatePickerDayHarnessFilters): Promise<WrCalendarDayHarness[]>;
|
|
281
221
|
/**
|
|
282
222
|
* One day of the month on show. The padding days of the neighbouring months are
|
|
283
223
|
* skipped, so `getDay(1)` is the 1st of THIS month and never the 1st of the next.
|
|
284
224
|
*/
|
|
285
|
-
getDay(dayOfMonth: number): Promise<
|
|
225
|
+
getDay(dayOfMonth: number): Promise<WrCalendarDayHarness>;
|
|
286
226
|
/** Click a day of the month on show. */
|
|
287
227
|
selectDay(dayOfMonth: number): Promise<void>;
|
|
288
228
|
/** The trigger button. Both components render it with the same class. */
|
|
@@ -514,5 +454,5 @@ declare class WrDateRangePickerHarness extends WrDatePickerHarnessBase {
|
|
|
514
454
|
private timePanel;
|
|
515
455
|
}
|
|
516
456
|
|
|
517
|
-
export {
|
|
457
|
+
export { WrDatePickerHarness, WrDateRangePickerHarness };
|
|
518
458
|
export type { WrDatePickerDayHarnessFilters, WrDatePickerHarnessFilters, WrDatePickerTimeFields, WrDateRangePickerHarnessFilters };
|