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
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import { BaseHarnessFilters, ContentContainerComponentHarness, HarnessPredicate, ComponentHarness } from '@angular/cdk/testing';
|
|
2
|
+
import { WrWindowState } from 'ngwr/window';
|
|
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
|
+
/** Narrows which `<wr-window>` a harness query matches. */
|
|
12
|
+
interface WrWindowHarnessFilters extends BaseHarnessFilters {
|
|
13
|
+
/** Match the title-bar text — a string is an exact match, a RegExp is tested. */
|
|
14
|
+
readonly title?: string | RegExp;
|
|
15
|
+
/** Match windows in one visual state. */
|
|
16
|
+
readonly state?: WrWindowState;
|
|
17
|
+
}
|
|
18
|
+
/** Narrows which `<wr-window-taskbar>` a harness query matches. */
|
|
19
|
+
interface WrWindowTaskbarHarnessFilters extends BaseHarnessFilters {
|
|
20
|
+
/** Match the edge the taskbar is pinned to. */
|
|
21
|
+
readonly position?: 'top' | 'bottom';
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Where a window is and how big, in CSS pixels — the numbers the component writes
|
|
25
|
+
* inline, not a measured box.
|
|
26
|
+
*/
|
|
27
|
+
interface WrWindowBox {
|
|
28
|
+
readonly x: number;
|
|
29
|
+
readonly y: number;
|
|
30
|
+
readonly width: number;
|
|
31
|
+
readonly height: number;
|
|
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 a window opened through `WrWindowManager.open()`.
|
|
43
|
+
*
|
|
44
|
+
* `WrWindow` is deliberately not exported — a window is always a service call — so
|
|
45
|
+
* there is nothing in your fixture to load: each window is a portal in its own
|
|
46
|
+
* overlay pane, and this comes from
|
|
47
|
+
* `TestbedHarnessEnvironment.documentRootLoader()`.
|
|
48
|
+
*
|
|
49
|
+
* It is a CONTENT CONTAINER, like `WrDialogHarness`: the component you opened is
|
|
50
|
+
* projected into the window's body, so `window.getHarness(WrButtonHarness…)` reads
|
|
51
|
+
* ITS buttons and cannot reach another window's. That matters more here than
|
|
52
|
+
* anywhere else, because windows are explicitly non-modal and several are normally
|
|
53
|
+
* open at once.
|
|
54
|
+
*
|
|
55
|
+
* **Geometry is read from the inline styles the component writes**, never measured:
|
|
56
|
+
* a window is positioned with `left` / `top` / `width` / `height` in pixels, and a
|
|
57
|
+
* unit test has no layout to measure. That also makes {@link getBox} the way to
|
|
58
|
+
* assert a move or a resize — including the ones a drag would produce, which no
|
|
59
|
+
* synthetic pointer event can, since the drag divides by a rect that is 0×0 here.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* const rootLoader = TestbedHarnessEnvironment.documentRootLoader(fixture);
|
|
64
|
+
* windows.open(EditorComponent, { title: 'Untitled.md' });
|
|
65
|
+
* await fixture.whenStable();
|
|
66
|
+
*
|
|
67
|
+
* const win = await rootLoader.getHarness(WrWindowHarness.with({ title: 'Untitled.md' }));
|
|
68
|
+
* await win.maximize();
|
|
69
|
+
* expect(await win.getState()).toBe('maximized');
|
|
70
|
+
* ```
|
|
71
|
+
*
|
|
72
|
+
* @see https://ngwr.dev/guides/testing
|
|
73
|
+
*/
|
|
74
|
+
declare class WrWindowHarness extends ContentContainerComponentHarness {
|
|
75
|
+
static hostSelector: string;
|
|
76
|
+
/** Build a predicate that narrows the query — windows come in stacks. */
|
|
77
|
+
static with(options?: WrWindowHarnessFilters): HarnessPredicate<WrWindowHarness>;
|
|
78
|
+
private readonly titleEl;
|
|
79
|
+
/**
|
|
80
|
+
* Whether this window is still on the page.
|
|
81
|
+
*
|
|
82
|
+
* For a harness you are already HOLDING: closing disposes the overlay, so this
|
|
83
|
+
* flips to `false` where a fresh `getHarnessOrNull()` comes back `null`. A
|
|
84
|
+
* MINIMIZED window is still open — it is a state, not a dismissal — and this
|
|
85
|
+
* stays `true` for one.
|
|
86
|
+
*/
|
|
87
|
+
isOpen(): Promise<boolean>;
|
|
88
|
+
/** The title-bar text. */
|
|
89
|
+
getTitle(): Promise<string>;
|
|
90
|
+
/** The projected `[wrWindowTitleExtra]` content, trimmed — empty when there is none. */
|
|
91
|
+
getTitleExtraText(): Promise<string>;
|
|
92
|
+
/** The window's visual state, from the host modifier. */
|
|
93
|
+
getState(): Promise<WrWindowState>;
|
|
94
|
+
/**
|
|
95
|
+
* The OS the chrome is dressed as — `macos`, `windows` or `linux`.
|
|
96
|
+
*
|
|
97
|
+
* Worth asserting because it is not cosmetic: on macOS the buttons are a
|
|
98
|
+
* traffic-light cluster in close → minimize → maximize order, and the Linux
|
|
99
|
+
* chrome renders neither minimize nor maximize UNLESS `showMinimize` /
|
|
100
|
+
* `showMaximize` asks for them. "No minimize on Linux" is a default, not an
|
|
101
|
+
* invariant — see {@link hasMinimizeButton}.
|
|
102
|
+
*/
|
|
103
|
+
getOs(): Promise<string>;
|
|
104
|
+
/** The title-bar density — `normal` or `compact`. */
|
|
105
|
+
getChromeSize(): Promise<string>;
|
|
106
|
+
/**
|
|
107
|
+
* Where the window is and how big, in CSS pixels.
|
|
108
|
+
*
|
|
109
|
+
* From the inline styles the component writes, which is the only readable answer
|
|
110
|
+
* without layout — and the same numbers a drag or a snap would change.
|
|
111
|
+
*/
|
|
112
|
+
getBox(): Promise<WrWindowBox>;
|
|
113
|
+
/**
|
|
114
|
+
* The window's stacking order.
|
|
115
|
+
*
|
|
116
|
+
* The manager hands out a z-index per focus, so this is how a spec asserts that
|
|
117
|
+
* clicking a window brought it to the front — the one thing a window manager
|
|
118
|
+
* exists to do, and the reason these panes are deliberately kept OUT of the
|
|
119
|
+
* browser's top layer, which orders strictly by entry.
|
|
120
|
+
*/
|
|
121
|
+
getZIndex(): Promise<number>;
|
|
122
|
+
/** Whether the resize handles are rendered — `resizable`, and only in the normal state. */
|
|
123
|
+
isResizable(): Promise<boolean>;
|
|
124
|
+
/** The resize handles currently rendered, by their edge / corner suffix. */
|
|
125
|
+
getResizeHandles(): Promise<string[]>;
|
|
126
|
+
/** The body text of the window — the component you opened, as rendered. */
|
|
127
|
+
getBodyText(): Promise<string>;
|
|
128
|
+
/** The projected `[wrWindowStatusBar]` content, trimmed. */
|
|
129
|
+
getStatusBarText(): Promise<string>;
|
|
130
|
+
/** Whether the chrome offers a close button (`showClose`). */
|
|
131
|
+
hasCloseButton(): Promise<boolean>;
|
|
132
|
+
/**
|
|
133
|
+
* Whether the chrome offers a minimize button.
|
|
134
|
+
*
|
|
135
|
+
* `false` on Linux BY DEFAULT — that chrome is close-only by convention, which
|
|
136
|
+
* is a real behavioural difference and not a style. `showMinimize: true`
|
|
137
|
+
* overrides it, and a spec that asserts "no minimize on Linux" without saying
|
|
138
|
+
* which of the two it means will pass for the wrong reason.
|
|
139
|
+
*/
|
|
140
|
+
hasMinimizeButton(): Promise<boolean>;
|
|
141
|
+
/** Whether the chrome offers a maximize button. Also `false` on Linux by default. */
|
|
142
|
+
hasMaximizeButton(): Promise<boolean>;
|
|
143
|
+
/** The close button's accessible name — the buttons are icon-only, so it is their only name. */
|
|
144
|
+
getCloseLabel(): Promise<string | null>;
|
|
145
|
+
/**
|
|
146
|
+
* The minimize button's accessible name, which flips to the restore wording while
|
|
147
|
+
* the window is minimized — the same button does both.
|
|
148
|
+
*/
|
|
149
|
+
getMinimizeLabel(): Promise<string | null>;
|
|
150
|
+
/** The maximize button's accessible name, which flips while the window is maximized. */
|
|
151
|
+
getMaximizeLabel(): Promise<string | null>;
|
|
152
|
+
/** Click the close button. Throws on a window opened `showClose: false`. */
|
|
153
|
+
close(): Promise<void>;
|
|
154
|
+
/**
|
|
155
|
+
* Click the minimize button — which RESTORES a minimized window, since it is the
|
|
156
|
+
* same control.
|
|
157
|
+
*/
|
|
158
|
+
minimize(): Promise<void>;
|
|
159
|
+
/** Click the maximize button — which restores a maximized window down. */
|
|
160
|
+
maximize(): Promise<void>;
|
|
161
|
+
/**
|
|
162
|
+
* Double-click the title bar, the other way to maximize.
|
|
163
|
+
*
|
|
164
|
+
* A separate gesture worth its own assertion, and it does NOT follow the
|
|
165
|
+
* button: only an explicit `showMaximize: false` turns it off. The Linux
|
|
166
|
+
* chrome hides the button by convention and keeps the gesture — which is also
|
|
167
|
+
* the only way out of a window that reached `maximized` without one.
|
|
168
|
+
*/
|
|
169
|
+
doubleClickChrome(): Promise<void>;
|
|
170
|
+
/** Click the window body — which pulls it to the front of the stack. */
|
|
171
|
+
focusWindow(): Promise<void>;
|
|
172
|
+
/** Press Escape. A window opened `closeOnEscape: false` ignores it — assert, do not assume. */
|
|
173
|
+
sendEscape(): Promise<void>;
|
|
174
|
+
/** The role the window announces — `dialog`, on a non-modal window. */
|
|
175
|
+
getRole(): Promise<string | null>;
|
|
176
|
+
/**
|
|
177
|
+
* Whether the window takes its accessible name from its own title element.
|
|
178
|
+
*
|
|
179
|
+
* Resolved rather than trusted: `aria-labelledby` naming an element that is not
|
|
180
|
+
* this window's title is not a name, and with several windows open the ids are
|
|
181
|
+
* the only thing keeping them apart.
|
|
182
|
+
*/
|
|
183
|
+
isLabelledByTitle(): Promise<boolean>;
|
|
184
|
+
/** Whether the window is hidden from assistive tech (`aria-hidden`, set while closed). */
|
|
185
|
+
isHiddenFromAssistiveTech(): Promise<boolean>;
|
|
186
|
+
private chromeAction;
|
|
187
|
+
private requireAction;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* @license
|
|
192
|
+
*
|
|
193
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
194
|
+
* found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
|
|
195
|
+
*/
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Test harness for `<wr-window-taskbar>` — the rail of minimized windows.
|
|
199
|
+
*
|
|
200
|
+
* The taskbar IS an element in your template, so it comes from the normal fixture
|
|
201
|
+
* loader, unlike the windows it lists. It renders nothing but its own host until a
|
|
202
|
+
* window is minimized; {@link isEmpty} is the question, and {@link getTabTitles}
|
|
203
|
+
* answers `[]` rather than throwing, because "no minimized windows" is the ordinary
|
|
204
|
+
* state rather than a mistake.
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* ```ts
|
|
208
|
+
* const taskbar = await loader.getHarness(WrWindowTaskbarHarness);
|
|
209
|
+
*
|
|
210
|
+
* await (await rootLoader.getHarness(WrWindowHarness)).minimize();
|
|
211
|
+
* expect(await taskbar.getTabTitles()).toEqual(['Untitled.md']);
|
|
212
|
+
* await taskbar.restore('Untitled.md');
|
|
213
|
+
* ```
|
|
214
|
+
*
|
|
215
|
+
* @see https://ngwr.dev/guides/testing
|
|
216
|
+
*/
|
|
217
|
+
declare class WrWindowTaskbarHarness extends ComponentHarness {
|
|
218
|
+
static hostSelector: string;
|
|
219
|
+
/** Build a predicate that narrows the query. */
|
|
220
|
+
static with(options?: WrWindowTaskbarHarnessFilters): HarnessPredicate<WrWindowTaskbarHarness>;
|
|
221
|
+
/** The edge the rail is pinned to. */
|
|
222
|
+
getPosition(): Promise<'top' | 'bottom'>;
|
|
223
|
+
/**
|
|
224
|
+
* The rail's accessible name — it is a `role="toolbar"`, and an unnamed one is
|
|
225
|
+
* announced as nothing.
|
|
226
|
+
*/
|
|
227
|
+
getRailLabel(): Promise<string | null>;
|
|
228
|
+
/** Whether nothing is minimized — the rail draws no markup at all then. */
|
|
229
|
+
isEmpty(): Promise<boolean>;
|
|
230
|
+
/**
|
|
231
|
+
* The titles in the rail, in order.
|
|
232
|
+
*
|
|
233
|
+
* A window opened without a title still gets a tab, named by the catalog's
|
|
234
|
+
* fallback rather than left blank — a nameless tab is unreachable by voice and
|
|
235
|
+
* indistinguishable from its neighbours.
|
|
236
|
+
*/
|
|
237
|
+
getTabTitles(): Promise<string[]>;
|
|
238
|
+
/** A tab's accessible name — the restore wording with the window's title in it. */
|
|
239
|
+
getRestoreLabel(title: string): Promise<string | null>;
|
|
240
|
+
/** Click a tab — restoring that window and focusing it. */
|
|
241
|
+
restore(title: string): Promise<void>;
|
|
242
|
+
/**
|
|
243
|
+
* Click a tab's ✕ — closing the window WITHOUT restoring it.
|
|
244
|
+
*
|
|
245
|
+
* Still worth asserting separately now that the two are siblings rather than
|
|
246
|
+
* nested: they sit inside one pill and look like one control, so a close that
|
|
247
|
+
* also restored would flash a closing window's content and look plausible.
|
|
248
|
+
*/
|
|
249
|
+
closeTab(title: string): Promise<void>;
|
|
250
|
+
/**
|
|
251
|
+
* The tab's BUTTON, not the pill around it.
|
|
252
|
+
*
|
|
253
|
+
* `.wr-window-taskbar__tab` is a plain container — it carries the pill's look
|
|
254
|
+
* and nothing else, because the close beside it cannot be a control nested in
|
|
255
|
+
* a control. The name and the click both belong to `__tab-restore`.
|
|
256
|
+
*/
|
|
257
|
+
private requireTab;
|
|
258
|
+
/** Which tab carries this title — one lookup for both the tab and its close button. */
|
|
259
|
+
private indexOf;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export { WrWindowHarness, WrWindowTaskbarHarness };
|
|
263
|
+
export type { WrWindowBox, WrWindowHarnessFilters, WrWindowTaskbarHarnessFilters };
|
package/types/ngwr-window.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
2
|
import { ComponentRef, WritableSignal, Signal, InjectionToken } from '@angular/core';
|
|
3
3
|
import { OverlayRef } from '@angular/cdk/overlay';
|
|
4
4
|
import { ReplaySubject, Subject } from 'rxjs';
|
|
5
5
|
import { ComponentType } from '@angular/cdk/portal';
|
|
6
|
+
import * as ngwr_i18n from 'ngwr/i18n';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* @license
|
|
@@ -35,8 +36,10 @@ type WrWindowChromeSize = 'compact' | 'normal';
|
|
|
35
36
|
* - `macos` — traffic-light dots on the LEFT (red close, yellow minimize,
|
|
36
37
|
* green maximize). Glyphs (×, −, +) appear when the cluster is hovered.
|
|
37
38
|
* - `windows` — monochrome glyph buttons on the RIGHT.
|
|
38
|
-
* - `linux` — close-only on the right
|
|
39
|
-
*
|
|
39
|
+
* - `linux` — close-only on the right, the GNOME convention. That is a DEFAULT
|
|
40
|
+
* and not a rule: `showMinimize` / `showMaximize` set to `true` put the
|
|
41
|
+
* buttons back, which is what a Linux user needs before a window can be
|
|
42
|
+
* minimized into `<wr-window-taskbar>`.
|
|
40
43
|
*/
|
|
41
44
|
type WrWindowOs = 'auto' | 'macos' | 'windows' | 'linux';
|
|
42
45
|
|
|
@@ -129,8 +132,16 @@ interface WrWindowConfig<D = unknown> {
|
|
|
129
132
|
readonly closeOnEscape?: boolean;
|
|
130
133
|
/** Snap-on-drag mode. @default 'none' */
|
|
131
134
|
readonly snap?: WrWindowSnap;
|
|
135
|
+
/**
|
|
136
|
+
* Show the minimize control. Omit to follow the chrome — every OS but Linux
|
|
137
|
+
* shows it, and the Linux preset is close-only by convention. Pass `true` to
|
|
138
|
+
* override that, which is what a Linux user needs before a window can reach
|
|
139
|
+
* `<wr-window-taskbar>`.
|
|
140
|
+
*/
|
|
132
141
|
readonly showMinimize?: boolean;
|
|
142
|
+
/** Show the maximize control. Omit to follow the chrome, as with {@link showMinimize}. */
|
|
133
143
|
readonly showMaximize?: boolean;
|
|
144
|
+
/** Show the close control. Every chrome closes, so this is not per-OS. */
|
|
134
145
|
readonly showClose?: boolean;
|
|
135
146
|
/** Show in `<wr-window-taskbar>` when minimized. @default true */
|
|
136
147
|
readonly taskbar?: boolean;
|
|
@@ -420,8 +431,8 @@ declare class WrWindowManager {
|
|
|
420
431
|
private applyRestore;
|
|
421
432
|
/** Drop a saved workspace. */
|
|
422
433
|
clearLayout(name: string): void;
|
|
423
|
-
static ɵfac:
|
|
424
|
-
static ɵprov:
|
|
434
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrWindowManager, never>;
|
|
435
|
+
static ɵprov: _angular_core.ɵɵInjectableDeclaration<WrWindowManager>;
|
|
425
436
|
}
|
|
426
437
|
|
|
427
438
|
/**
|
|
@@ -442,16 +453,22 @@ declare class WrWindowManager {
|
|
|
442
453
|
* @see https://ngwr.dev/reference/components/window
|
|
443
454
|
*/
|
|
444
455
|
declare class WrWindowTaskbar {
|
|
456
|
+
/** @internal */ protected readonly railLabel: _angular_core.Signal<string>;
|
|
457
|
+
/** @internal */ protected readonly closeLabel: _angular_core.Signal<string>;
|
|
458
|
+
/** @internal */ protected readonly untitled: _angular_core.Signal<string>;
|
|
459
|
+
/** @internal */ protected readonly restoreLabel: (params?: ngwr_i18n.WrI18nParams) => string;
|
|
445
460
|
/** Edge the taskbar pins itself to. @default 'bottom' */
|
|
446
|
-
readonly position:
|
|
461
|
+
readonly position: _angular_core.InputSignal<"top" | "bottom">;
|
|
447
462
|
private readonly manager;
|
|
448
463
|
/** @internal — minimized windows that haven't opted out via `taskbar: false`. */
|
|
449
|
-
protected readonly items:
|
|
450
|
-
protected readonly classes:
|
|
464
|
+
protected readonly items: _angular_core.Signal<WrWindowRef<unknown, unknown>[]>;
|
|
465
|
+
protected readonly classes: _angular_core.Signal<string>;
|
|
466
|
+
/** A window with no title still needs a name in the rail. */
|
|
467
|
+
protected tabTitle(ref: WrWindowRef<unknown, unknown>): string;
|
|
451
468
|
protected restore(ref: WrWindowRef<unknown, unknown>): void;
|
|
452
469
|
protected close(ref: WrWindowRef<unknown, unknown>, event: Event): void;
|
|
453
|
-
static ɵfac:
|
|
454
|
-
static ɵcmp:
|
|
470
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrWindowTaskbar, never>;
|
|
471
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrWindowTaskbar, "wr-window-taskbar", never, { "position": { "alias": "position"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
455
472
|
}
|
|
456
473
|
|
|
457
474
|
export { WR_WINDOW_DATA, WR_WINDOW_REF, WrWindowManager, WrWindowRef, WrWindowTaskbar };
|
|
@@ -197,8 +197,9 @@
|
|
|
197
197
|
|
|
198
198
|
// OS preset: Linux (GNOME-style) — chrome-action retains the windows
|
|
199
199
|
// look but the chrome bar is slightly taller and the
|
|
200
|
-
// title stays left-aligned
|
|
201
|
-
//
|
|
200
|
+
// title stays left-aligned. Close-only is the template's
|
|
201
|
+
// DEFAULT here, not a rule: `[showMinimize]="true"` puts
|
|
202
|
+
// the button back.
|
|
202
203
|
&--os-linux {
|
|
203
204
|
.wr-window__chrome {
|
|
204
205
|
height: 2.5rem;
|
|
@@ -384,30 +385,45 @@
|
|
|
384
385
|
pointer-events: auto;
|
|
385
386
|
}
|
|
386
387
|
|
|
388
|
+
// The pill, which is now a container rather than the button itself — the
|
|
389
|
+
// close beside it has to be a sibling, not a control nested in a control.
|
|
390
|
+
// The class stays: consumers style against it, and it still names the pill.
|
|
387
391
|
&__tab {
|
|
388
|
-
appearance: none;
|
|
389
|
-
background: transparent;
|
|
390
|
-
border: 0;
|
|
391
392
|
display: inline-flex;
|
|
392
393
|
align-items: center;
|
|
393
|
-
gap: 0.
|
|
394
|
-
|
|
395
|
-
//
|
|
396
|
-
padding-inline: 0.75rem 0.
|
|
394
|
+
gap: 0.125rem;
|
|
395
|
+
// Roomy where the title starts, tight against the trailing close button,
|
|
396
|
+
// which now carries its own padding to reach a 24px target.
|
|
397
|
+
padding-inline: 0.75rem 0.125rem;
|
|
397
398
|
border-radius: var(--wr-border-radius-sm);
|
|
398
399
|
color: var(--wr-color-on-surface);
|
|
399
|
-
font-family: inherit;
|
|
400
400
|
font-size: var(--wr-text-sm);
|
|
401
401
|
line-height: 1.25rem;
|
|
402
|
-
cursor: pointer;
|
|
403
402
|
max-width: 12rem;
|
|
404
|
-
transition:
|
|
405
|
-
background var(--wr-transition-base),
|
|
406
|
-
color var(--wr-transition-base);
|
|
403
|
+
transition: background var(--wr-transition-base);
|
|
407
404
|
|
|
408
405
|
&:hover {
|
|
409
406
|
background: rgba(var(--wr-color-outline-rgb), 0.6);
|
|
410
407
|
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
&__tab-restore {
|
|
411
|
+
appearance: none;
|
|
412
|
+
background: transparent;
|
|
413
|
+
border: 0;
|
|
414
|
+
padding-block: 0.25rem;
|
|
415
|
+
padding-inline: 0;
|
|
416
|
+
flex: 1 1 auto;
|
|
417
|
+
min-width: 0;
|
|
418
|
+
display: inline-flex;
|
|
419
|
+
align-items: center;
|
|
420
|
+
border-radius: var(--wr-border-radius-sm);
|
|
421
|
+
color: inherit;
|
|
422
|
+
font-family: inherit;
|
|
423
|
+
font-size: inherit;
|
|
424
|
+
line-height: inherit;
|
|
425
|
+
cursor: pointer;
|
|
426
|
+
text-align: start;
|
|
411
427
|
|
|
412
428
|
&:focus-visible {
|
|
413
429
|
@include theme.focus-ring;
|
|
@@ -424,9 +440,16 @@
|
|
|
424
440
|
}
|
|
425
441
|
|
|
426
442
|
&__tab-close {
|
|
443
|
+
appearance: none;
|
|
444
|
+
border: 0;
|
|
445
|
+
background: transparent;
|
|
427
446
|
flex: 0 0 auto;
|
|
428
|
-
|
|
429
|
-
|
|
447
|
+
// 24px, which is what WCAG 2.5.8 asks of a pointer target. The glyph is
|
|
448
|
+
// still 9px and the pill is 28px tall, so the box grows into padding that
|
|
449
|
+
// was already there rather than changing the taskbar's height.
|
|
450
|
+
width: 1.5rem;
|
|
451
|
+
height: 1.5rem;
|
|
452
|
+
padding: 0;
|
|
430
453
|
display: inline-flex;
|
|
431
454
|
align-items: center;
|
|
432
455
|
justify-content: center;
|
|
@@ -438,6 +461,11 @@
|
|
|
438
461
|
color: var(--wr-color-surface);
|
|
439
462
|
background: var(--wr-color-danger);
|
|
440
463
|
}
|
|
464
|
+
|
|
465
|
+
&:focus-visible {
|
|
466
|
+
@include theme.focus-ring;
|
|
467
|
+
outline-offset: -2px;
|
|
468
|
+
}
|
|
441
469
|
}
|
|
442
470
|
}
|
|
443
471
|
|