@ethlete/components 1.0.0-next.66 → 1.0.0-next.67
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/CHANGELOG.md +181 -0
- package/fesm2022/ethlete-components-testing.mjs +524 -0
- package/fesm2022/ethlete-components-testing.mjs.map +1 -0
- package/fesm2022/ethlete-components.mjs +5798 -2911
- package/fesm2022/ethlete-components.mjs.map +1 -1
- package/generators/generators.json +35 -0
- package/generators/migrate-cascader-tree-internals/cascader-tree-internals.js +6 -0
- package/generators/migrate-cascader-tree-internals/migration.js +11 -0
- package/generators/migrate-cascader-tree-internals/schema.json +26 -0
- package/generators/migrate-duration-format-internals/duration-format-internals.js +6 -0
- package/generators/migrate-duration-format-internals/migration.js +11 -0
- package/generators/migrate-duration-format-internals/schema.json +26 -0
- package/generators/migrate-error-color-theme-signal/error-color-theme-signal.js +37 -0
- package/generators/migrate-error-color-theme-signal/migration.js +55 -0
- package/generators/migrate-error-color-theme-signal/schema.json +26 -0
- package/generators/migrate-line-chart-stacked-area-mix/line-chart-stacked-area-mix.js +48 -0
- package/generators/migrate-line-chart-stacked-area-mix/migration.js +35 -0
- package/generators/migrate-line-chart-stacked-area-mix/schema.json +26 -0
- package/generators/migrate-loader-determinate/loader-determinate.js +87 -0
- package/generators/migrate-loader-determinate/migration.js +49 -0
- package/generators/migrate-loader-determinate/schema.json +26 -0
- package/generators/migrate-select-input-renames/migration.js +41 -0
- package/generators/migrate-select-input-renames/schema.json +26 -0
- package/generators/migrate-select-input-renames/select-input-renames.js +37 -0
- package/generators/migrate-time-picker-ring/migration.js +17 -0
- package/generators/migrate-time-picker-ring/schema.json +26 -0
- package/generators/migrate-time-picker-ring/time-picker-ring.js +25 -0
- package/migrations.json +75 -0
- package/package.json +17 -17
- package/types/ethlete-components-testing.d.ts +311 -0
- package/types/ethlete-components.d.ts +9648 -10578
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { runRemovedExportsMigration, } from '../removed-exports/run-removed-exports-migration.js';
|
|
2
|
+
import { REMOVED_SELECTORS, replaceSetActiveSide, TIME_PICKER_RING_REMOVALS } from './time-picker-ring.js';
|
|
3
|
+
export const TIME_PICKER_RING_REPORT_PATH = 'time-picker-ring-migration-tasks.md';
|
|
4
|
+
export default async function migrateTimePickerRing(tree, schema) {
|
|
5
|
+
await runRemovedExportsMigration(tree, schema, {
|
|
6
|
+
title: 'Moving the time picker to the ring API',
|
|
7
|
+
removed: TIME_PICKER_RING_REMOVALS,
|
|
8
|
+
reportPath: TIME_PICKER_RING_REPORT_PATH,
|
|
9
|
+
rewrite: (_tree, filePath, content) => {
|
|
10
|
+
if (REMOVED_SELECTORS.test(content)) {
|
|
11
|
+
console.warn(`\n⚠️ ${filePath} uses etTimePickerColumn or etTimePickerOption, which are removed. See the time picker guide: /components/time-picker.`);
|
|
12
|
+
}
|
|
13
|
+
return replaceSetActiveSide(content);
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=migration.js.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/schema",
|
|
3
|
+
"$id": "migrate-time-picker-ring",
|
|
4
|
+
"title": "Replace the removed time picker setActiveSide with activeSide.set, and mark the removed column and option directives",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"projects": {
|
|
8
|
+
"type": "array",
|
|
9
|
+
"items": { "type": "string" },
|
|
10
|
+
"description": "Nx projects to scan. Defaults to every project in the workspace.",
|
|
11
|
+
"alias": "project"
|
|
12
|
+
},
|
|
13
|
+
"include": {
|
|
14
|
+
"type": "array",
|
|
15
|
+
"items": { "type": "string" },
|
|
16
|
+
"description": "Path prefixes to scan, relative to the workspace root (e.g. 'apps/shop'). Unioned with `projects`.",
|
|
17
|
+
"alias": "includePath"
|
|
18
|
+
},
|
|
19
|
+
"skipFormat": {
|
|
20
|
+
"type": "boolean",
|
|
21
|
+
"description": "Skip formatting files after migration",
|
|
22
|
+
"default": false
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"required": []
|
|
26
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const GUIDE = 'See the time picker guide (/components/time-picker).';
|
|
2
|
+
export const TIME_PICKER_RING_REMOVALS = [
|
|
3
|
+
{
|
|
4
|
+
name: 'TimePickerColumnDirective',
|
|
5
|
+
dropFromArrays: ['imports'],
|
|
6
|
+
todo: `TimePickerColumnDirective is removed; the time picker is a ring. ${GUIDE}`,
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
name: 'TimePickerOptionDirective',
|
|
10
|
+
dropFromArrays: ['imports'],
|
|
11
|
+
todo: `TimePickerOptionDirective is removed; the time picker is a ring. ${GUIDE}`,
|
|
12
|
+
},
|
|
13
|
+
];
|
|
14
|
+
export const REMOVED_SELECTORS = /\betTimePicker(?:Column|Option)\b/;
|
|
15
|
+
const TIME_PICKER_USE = /TimePicker|etTimePicker|et-time-picker/;
|
|
16
|
+
const SET_ACTIVE_SIDE = /(\.\s*)setActiveSide(\s*\()/g;
|
|
17
|
+
export const mentionsTimePicker = (content) => TIME_PICKER_USE.test(content);
|
|
18
|
+
/** Returns the source or template with every `.setActiveSide(` call turned into `.activeSide.set(`, or `null` when there is none. */
|
|
19
|
+
export const replaceSetActiveSide = (content) => {
|
|
20
|
+
if (!mentionsTimePicker(content))
|
|
21
|
+
return null;
|
|
22
|
+
const next = content.replace(SET_ACTIVE_SIDE, '$1activeSide.set$2');
|
|
23
|
+
return next === content ? null : next;
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=time-picker-ring.js.map
|
package/migrations.json
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
"name": "query-error-labels",
|
|
5
5
|
"version": "1.0.0-next.33",
|
|
6
6
|
"kind": "auto",
|
|
7
|
+
"level": "required",
|
|
7
8
|
"description": "Find the query-error call sites the English-only label default changes, and report where German must be opted back in.",
|
|
8
9
|
"generator": "@ethlete/components:migrate-query-error-labels",
|
|
9
10
|
"docs": "/components/query-error"
|
|
@@ -12,6 +13,7 @@
|
|
|
12
13
|
"name": "rich-text-editor-link-editor",
|
|
13
14
|
"version": "1.0.0-next.33",
|
|
14
15
|
"kind": "auto",
|
|
16
|
+
"level": "required",
|
|
15
17
|
"description": "Find the rich text editors that lose the link editor popover, and report where to opt back in.",
|
|
16
18
|
"generator": "@ethlete/components:migrate-rich-text-editor-link-editor",
|
|
17
19
|
"docs": "/components/rich-text-editor"
|
|
@@ -20,6 +22,7 @@
|
|
|
20
22
|
"name": "rich-text-editor-tools",
|
|
21
23
|
"version": "1.0.0-next.36",
|
|
22
24
|
"kind": "auto",
|
|
25
|
+
"level": "required",
|
|
23
26
|
"description": "Find the rich text editors that lose the heading, quote, code-block and link tools, and report where to opt back in.",
|
|
24
27
|
"generator": "@ethlete/components:migrate-rich-text-editor-tools",
|
|
25
28
|
"docs": "/components/rich-text-editor"
|
|
@@ -28,6 +31,7 @@
|
|
|
28
31
|
"name": "rich-text-editor-floating-toolbar",
|
|
29
32
|
"version": "1.0.0-next.36",
|
|
30
33
|
"kind": "auto",
|
|
34
|
+
"level": "required",
|
|
31
35
|
"description": "Find the rich text editors that lose the selection toolbar, and report where to opt back in.",
|
|
32
36
|
"generator": "@ethlete/components:migrate-rich-text-editor-floating-toolbar",
|
|
33
37
|
"docs": "/components/rich-text-editor"
|
|
@@ -36,6 +40,7 @@
|
|
|
36
40
|
"name": "bracket-ethlete-renames",
|
|
37
41
|
"version": "1.0.0-next.64",
|
|
38
42
|
"kind": "auto",
|
|
43
|
+
"level": "required",
|
|
39
44
|
"description": "Rename generateTournamentModeFormEthleteRounds to generateTournamentModeFromEthleteRounds.",
|
|
40
45
|
"generator": "@ethlete/components:migrate-bracket-ethlete-renames",
|
|
41
46
|
"docs": "/components/bracket"
|
|
@@ -44,6 +49,7 @@
|
|
|
44
49
|
"name": "bracket-default-cards",
|
|
45
50
|
"version": "1.0.0-next.64",
|
|
46
51
|
"kind": "auto",
|
|
52
|
+
"level": "required",
|
|
47
53
|
"description": "Spread BRACKET_DEFAULT_CARDS into provideBracketConfig, and report the brackets that need it by hand.",
|
|
48
54
|
"generator": "@ethlete/components:migrate-bracket-default-cards",
|
|
49
55
|
"docs": "/components/bracket"
|
|
@@ -52,6 +58,7 @@
|
|
|
52
58
|
"name": "overlay-nav-tab-imports",
|
|
53
59
|
"version": "1.0.0-next.64",
|
|
54
60
|
"kind": "auto",
|
|
61
|
+
"level": "required",
|
|
55
62
|
"description": "Add OVERLAY_NAV_TAB_IMPORTS where a NAV_TAB_IMPORTS component renders et-overlay-nav-tab-link.",
|
|
56
63
|
"generator": "@ethlete/components:migrate-overlay-nav-tab-imports",
|
|
57
64
|
"docs": "/components/tabs"
|
|
@@ -60,6 +67,7 @@
|
|
|
60
67
|
"name": "youtube-player-slot-directive",
|
|
61
68
|
"version": "1.0.0-next.64",
|
|
62
69
|
"kind": "auto",
|
|
70
|
+
"level": "required",
|
|
63
71
|
"description": "Remove YoutubePlayerSlotDirective and YOUTUBE_PLAYER_SLOT_TOKEN, and mark the uses that need a YoutubePlayerSlotComponent.",
|
|
64
72
|
"generator": "@ethlete/components:migrate-youtube-player-slot-directive",
|
|
65
73
|
"docs": "/components/stream"
|
|
@@ -68,6 +76,7 @@
|
|
|
68
76
|
"name": "chart-baseline-y",
|
|
69
77
|
"version": "1.0.0-next.65",
|
|
70
78
|
"kind": "auto",
|
|
79
|
+
"level": "required",
|
|
71
80
|
"description": "Rename the removed chart-grid baselineY alias to baseline.",
|
|
72
81
|
"generator": "@ethlete/components:migrate-chart-baseline-y",
|
|
73
82
|
"docs": "/components/chart"
|
|
@@ -76,6 +85,7 @@
|
|
|
76
85
|
"name": "grid-engine-internals",
|
|
77
86
|
"version": "1.0.0-next.65",
|
|
78
87
|
"kind": "auto",
|
|
88
|
+
"level": "required",
|
|
79
89
|
"description": "Remove the grid layout engine internals from @ethlete/components imports and mark the uses that need another approach.",
|
|
80
90
|
"generator": "@ethlete/components:migrate-grid-engine-internals",
|
|
81
91
|
"docs": "/components/grid"
|
|
@@ -84,6 +94,7 @@
|
|
|
84
94
|
"name": "overlay-fullscreen-animation",
|
|
85
95
|
"version": "1.0.0-next.65",
|
|
86
96
|
"kind": "auto",
|
|
97
|
+
"level": "required",
|
|
87
98
|
"description": "Remove the overlay fullscreen animation internals from @ethlete/components imports and mark the uses that need another approach.",
|
|
88
99
|
"generator": "@ethlete/components:migrate-overlay-fullscreen-animation",
|
|
89
100
|
"docs": "/components/overlays"
|
|
@@ -92,9 +103,73 @@
|
|
|
92
103
|
"name": "stream-default-components",
|
|
93
104
|
"version": "1.0.0-next.65",
|
|
94
105
|
"kind": "auto",
|
|
106
|
+
"level": "required",
|
|
95
107
|
"description": "Spread STREAM_DEFAULT_COMPONENTS into provideStreamConfig, add it to the app config of an app without one, and report the rest.",
|
|
96
108
|
"generator": "@ethlete/components:migrate-stream-default-components",
|
|
97
109
|
"docs": "/components/stream"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"name": "time-picker-ring",
|
|
113
|
+
"version": "1.0.0-next.67",
|
|
114
|
+
"kind": "auto",
|
|
115
|
+
"level": "required",
|
|
116
|
+
"description": "Replace the removed time picker setActiveSide with activeSide.set, and mark the removed column and option directives.",
|
|
117
|
+
"generator": "@ethlete/components:migrate-time-picker-ring",
|
|
118
|
+
"docs": "/components/time-picker"
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"name": "cascader-tree-internals",
|
|
122
|
+
"version": "1.0.0-next.67",
|
|
123
|
+
"kind": "auto",
|
|
124
|
+
"level": "required",
|
|
125
|
+
"description": "Remove the cascader tree helpers from @ethlete/components imports and mark the uses that need another approach.",
|
|
126
|
+
"generator": "@ethlete/components:migrate-cascader-tree-internals",
|
|
127
|
+
"docs": "/components/cascader"
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"name": "duration-format-internals",
|
|
131
|
+
"version": "1.0.0-next.67",
|
|
132
|
+
"kind": "auto",
|
|
133
|
+
"level": "required",
|
|
134
|
+
"description": "Remove the duration format helpers from @ethlete/components imports and mark the uses that need another approach.",
|
|
135
|
+
"generator": "@ethlete/components:migrate-duration-format-internals",
|
|
136
|
+
"docs": "/components/date-time-inputs"
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"name": "line-chart-stacked-area-mix",
|
|
140
|
+
"version": "1.0.0-next.67",
|
|
141
|
+
"kind": "auto",
|
|
142
|
+
"level": "required",
|
|
143
|
+
"description": "Rename --et-line-chart-stacked-area-opacity to --et-line-chart-stacked-area-mix and map each opacity to a percentage.",
|
|
144
|
+
"generator": "@ethlete/components:migrate-line-chart-stacked-area-mix",
|
|
145
|
+
"docs": "/components/line-chart"
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"name": "error-color-theme-signal",
|
|
149
|
+
"version": "1.0.0-next.67",
|
|
150
|
+
"kind": "auto",
|
|
151
|
+
"level": "required",
|
|
152
|
+
"description": "Call errorColorTheme() where an injectFormSupport() result or a TableComponent reads it, now that it is a signal.",
|
|
153
|
+
"generator": "@ethlete/components:migrate-error-color-theme-signal",
|
|
154
|
+
"docs": "/components/forms"
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"name": "select-input-renames",
|
|
158
|
+
"version": "1.0.0-next.67",
|
|
159
|
+
"kind": "auto",
|
|
160
|
+
"level": "required",
|
|
161
|
+
"description": "Rename the et-select inputs error, customValueSeparators and normalizeCustomValue, and the tag input inputs maxTags and normalizeTag, in templates.",
|
|
162
|
+
"generator": "@ethlete/components:migrate-select-input-renames",
|
|
163
|
+
"docs": "/components/select"
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
"name": "loader-determinate",
|
|
167
|
+
"version": "1.0.0-next.67",
|
|
168
|
+
"kind": "auto",
|
|
169
|
+
"level": "required",
|
|
170
|
+
"description": "Remove determinate from et-spinner and indeterminate from et-progress-bar, which now follow whether value is bound, and rewrite value where the mode was dynamic.",
|
|
171
|
+
"generator": "@ethlete/components:migrate-loader-determinate",
|
|
172
|
+
"docs": "/components/loader"
|
|
98
173
|
}
|
|
99
174
|
]
|
|
100
175
|
}
|
package/package.json
CHANGED
|
@@ -1,33 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ethlete/components",
|
|
3
|
-
"version": "1.0.0-next.
|
|
3
|
+
"version": "1.0.0-next.67",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@ethlete/bracket": "^1.0.0-next.
|
|
7
|
+
"@ethlete/bracket": "^1.0.0-next.3",
|
|
8
8
|
"tslib": "^2.3.0"
|
|
9
9
|
},
|
|
10
10
|
"peerDependencies": {
|
|
11
|
-
"@
|
|
12
|
-
"@angular/
|
|
13
|
-
"@angular/
|
|
14
|
-
"@angular/
|
|
15
|
-
"@angular/
|
|
16
|
-
"@angular/
|
|
17
|
-
"@
|
|
18
|
-
"@date-fns/tz": "1.5.0",
|
|
11
|
+
"@angular/common": "^22.1.0",
|
|
12
|
+
"@angular/compiler": "^22.1.0",
|
|
13
|
+
"@angular/core": "^22.1.0",
|
|
14
|
+
"@angular/forms": "^22.1.0",
|
|
15
|
+
"@angular/platform-browser": "^22.1.0",
|
|
16
|
+
"@angular/router": "^22.1.0",
|
|
17
|
+
"@date-fns/tz": "^1.2.0",
|
|
19
18
|
"@ethlete/core": "^5.0.0-beta.11",
|
|
20
19
|
"@ethlete/query": "^6.0.0-beta.8",
|
|
21
20
|
"@ethlete/types": "^2.0.0-beta.4",
|
|
22
|
-
"@floating-ui/dom": "1.
|
|
23
|
-
"@nx/devkit": "23.
|
|
24
|
-
"date-fns": "4.
|
|
25
|
-
"rxjs": "7.8.
|
|
21
|
+
"@floating-ui/dom": "^1.6.0",
|
|
22
|
+
"@nx/devkit": "^23.0.0",
|
|
23
|
+
"date-fns": "^4.0.0",
|
|
24
|
+
"rxjs": "^7.8.0"
|
|
26
25
|
},
|
|
27
26
|
"peerDependenciesMeta": {
|
|
28
|
-
"@analogjs/vitest-angular": {
|
|
29
|
-
"optional": true
|
|
30
|
-
},
|
|
31
27
|
"@date-fns/tz": {
|
|
32
28
|
"optional": true
|
|
33
29
|
},
|
|
@@ -51,6 +47,10 @@
|
|
|
51
47
|
".": {
|
|
52
48
|
"types": "./types/ethlete-components.d.ts",
|
|
53
49
|
"default": "./fesm2022/ethlete-components.mjs"
|
|
50
|
+
},
|
|
51
|
+
"./testing": {
|
|
52
|
+
"types": "./types/ethlete-components-testing.d.ts",
|
|
53
|
+
"default": "./fesm2022/ethlete-components-testing.mjs"
|
|
54
54
|
}
|
|
55
55
|
},
|
|
56
56
|
"type": "module"
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
import { Type, Provider } from '@angular/core';
|
|
3
|
+
import { ComponentFixture } from '@angular/core/testing';
|
|
4
|
+
import { OverlayRuntimeCloseSource } from '@ethlete/core';
|
|
5
|
+
import { OverlayRef, OverlayConfig, SelectDirective, TabBarDirective } from '@ethlete/components';
|
|
6
|
+
|
|
7
|
+
type ControlDriverOptions = {
|
|
8
|
+
/** Matches the element carrying the directive, when the host template nests it. */
|
|
9
|
+
directiveSelector?: string;
|
|
10
|
+
};
|
|
11
|
+
/** The host, the directive under test, and queries scoped to the fixture - what every driver needs. */
|
|
12
|
+
declare const createControlDriver: <T, D>(fixture: ComponentFixture<T>, directiveType: Type<D>, { directiveSelector }?: ControlDriverOptions) => {
|
|
13
|
+
fixture: ComponentFixture<T>;
|
|
14
|
+
host: T;
|
|
15
|
+
control: D;
|
|
16
|
+
detectChanges: () => void;
|
|
17
|
+
tick: () => void;
|
|
18
|
+
element: () => HTMLElement;
|
|
19
|
+
directive: <X>(type: Type<X>, selector?: string) => X;
|
|
20
|
+
query: <E extends HTMLElement = HTMLElement>(selector: string) => E | null;
|
|
21
|
+
queryAll: <E extends HTMLElement = HTMLElement>(selector: string) => E[];
|
|
22
|
+
text: (selector: string) => string | null;
|
|
23
|
+
click: (element: HTMLElement) => void;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Types masked date/time text one character at a time, with the caret tracking the insertion -
|
|
28
|
+
* what `InputMaskDirective`'s live reformatting needs, unlike a whole-string {@link typeInField}.
|
|
29
|
+
*/
|
|
30
|
+
declare const typeMasked: (field: HTMLInputElement, text: string) => void;
|
|
31
|
+
/**
|
|
32
|
+
* Driver for every date-time control that pairs text fields with a picker overlay: date, date
|
|
33
|
+
* range, date-time, time and time range. The picker trigger is matched by its directive, so a test
|
|
34
|
+
* host can put it on any element; the fields are matched by CSS, defaulting to the only `input`.
|
|
35
|
+
*/
|
|
36
|
+
declare const createDatePickerDriver: <T, D extends {
|
|
37
|
+
closePicker: () => void;
|
|
38
|
+
}>(fixture: ComponentFixture<T>, directiveType: Type<D>, options?: ControlDriverOptions) => {
|
|
39
|
+
dayCell: (label: string) => HTMLButtonElement | null;
|
|
40
|
+
clickDayCell: (label: string) => void;
|
|
41
|
+
field: (selector?: string) => HTMLInputElement;
|
|
42
|
+
fields: () => HTMLInputElement[];
|
|
43
|
+
type: (text: string, selector?: string) => void;
|
|
44
|
+
typeMasked: (text: string, selector?: string) => void;
|
|
45
|
+
typeAndBlur: (text: string, selector?: string) => void;
|
|
46
|
+
focusField: (selector?: string) => void;
|
|
47
|
+
blurField: (selector?: string) => void;
|
|
48
|
+
pressInField: (key: string, selector?: string) => KeyboardEvent;
|
|
49
|
+
settle: () => Promise<void>;
|
|
50
|
+
trigger: <E extends HTMLElement = HTMLElement>() => E;
|
|
51
|
+
pane: () => HTMLElement | null;
|
|
52
|
+
paneEl: <E extends HTMLElement = HTMLElement>(selector: string) => E | null;
|
|
53
|
+
paneEls: <E extends HTMLElement = HTMLElement>(selector: string) => E[];
|
|
54
|
+
open: () => Promise<void>;
|
|
55
|
+
close: () => Promise<void>;
|
|
56
|
+
closeAndRemovePanes: () => void;
|
|
57
|
+
press: (key: string) => KeyboardEvent;
|
|
58
|
+
escape: () => KeyboardEvent;
|
|
59
|
+
pointerDownOutside: () => void;
|
|
60
|
+
clickInPane: (selector: string) => void;
|
|
61
|
+
fixture: ComponentFixture<T>;
|
|
62
|
+
host: T;
|
|
63
|
+
control: D;
|
|
64
|
+
detectChanges: () => void;
|
|
65
|
+
tick: () => void;
|
|
66
|
+
element: () => HTMLElement;
|
|
67
|
+
directive: <X>(type: Type<X>, selector?: string) => X;
|
|
68
|
+
query: <E extends HTMLElement = HTMLElement>(selector: string) => E | null;
|
|
69
|
+
queryAll: <E extends HTMLElement = HTMLElement>(selector: string) => E[];
|
|
70
|
+
text: (selector: string) => string | null;
|
|
71
|
+
click: (element: HTMLElement) => void;
|
|
72
|
+
};
|
|
73
|
+
type DatePickerDriver<T, D extends {
|
|
74
|
+
closePicker: () => void;
|
|
75
|
+
}> = ReturnType<typeof createDatePickerDriver<T, D>>;
|
|
76
|
+
|
|
77
|
+
declare const tick: () => void;
|
|
78
|
+
declare const flushFrames: () => Promise<void>;
|
|
79
|
+
declare const resetOverlays: () => void;
|
|
80
|
+
/**
|
|
81
|
+
* The newest overlay pane in the document.
|
|
82
|
+
*
|
|
83
|
+
* Overlays render into the document, not into the fixture, and jsdom fires no transition events -
|
|
84
|
+
* so a pane stuck in its leave transition stays reachable. Scope every pane query through here, or
|
|
85
|
+
* a stale pane answers it.
|
|
86
|
+
*/
|
|
87
|
+
declare const latestPane: () => HTMLElement | null;
|
|
88
|
+
declare const hostDirective: <T>(fixture: ComponentFixture<unknown>, type: Type<T>) => T;
|
|
89
|
+
declare const directiveAt: <T>(fixture: ComponentFixture<unknown>, type: Type<T>, selector: string) => T;
|
|
90
|
+
declare const hostElement: (fixture: ComponentFixture<unknown>) => HTMLElement;
|
|
91
|
+
/**
|
|
92
|
+
* Queries the fixture's root element, narrowing `nativeElement` (typed `any`) to `HTMLElement`
|
|
93
|
+
* once - a generic call directly through `fixture.nativeElement.querySelectorAll<E>(...)` fails
|
|
94
|
+
* with TS2347 and collapses every downstream member access to `{}`.
|
|
95
|
+
*/
|
|
96
|
+
declare const queryAll: <E extends Element = HTMLElement>(fixture: ComponentFixture<unknown>, selector: string) => E[];
|
|
97
|
+
/** Single-result counterpart of {@link queryAll}. */
|
|
98
|
+
declare const query: <E extends Element = HTMLElement>(fixture: ComponentFixture<unknown>, selector: string) => E | null;
|
|
99
|
+
declare const pressKey: (target: EventTarget, key: string, init?: KeyboardEventInit) => KeyboardEvent;
|
|
100
|
+
declare const focusEvent: (target: EventTarget, type: "focus" | "blur") => void;
|
|
101
|
+
declare const pointerEnter: (target: EventTarget) => void;
|
|
102
|
+
declare const pointerEvent: (target: EventTarget, type: string, init?: PointerEventInit) => void;
|
|
103
|
+
declare const setInputValue: (input: HTMLInputElement, value: string) => void;
|
|
104
|
+
declare const focusField: (field: HTMLInputElement) => void;
|
|
105
|
+
declare const typeInField: (field: HTMLInputElement, text: string) => void;
|
|
106
|
+
/**
|
|
107
|
+
* Types `text` one character at a time, each with its own `input` event and the caret left after
|
|
108
|
+
* the inserted character - what a real keyboard produces. Use it instead of {@link typeInField}
|
|
109
|
+
* whenever the control reads or rewrites the element between keystrokes; a whole-string
|
|
110
|
+
* {@link setInputValue} hides every defect that only appears mid-entry.
|
|
111
|
+
*/
|
|
112
|
+
declare const typeChars: (field: HTMLInputElement, text: string) => void;
|
|
113
|
+
declare const blurField: (field: HTMLInputElement) => void;
|
|
114
|
+
declare const pointerDownOutside: () => void;
|
|
115
|
+
type ClipboardPayload = Readonly<Record<string, string>>;
|
|
116
|
+
/** jsdom has no `DataTransfer`, so the clipboard payload is faked onto the event. */
|
|
117
|
+
declare const pasteInto: (target: EventTarget, payload: ClipboardPayload | string) => void;
|
|
118
|
+
declare const textOf: (element: Element | null | undefined) => string | null;
|
|
119
|
+
|
|
120
|
+
type TestOverlayRef<TComponent extends object = object, TResult = unknown> = OverlayRef<TComponent, TResult> & {
|
|
121
|
+
/** Every `close()` / `forceClose()` call, in order, including ones a close guard vetoed. */
|
|
122
|
+
readonly closeCalls: readonly {
|
|
123
|
+
result: TResult | undefined;
|
|
124
|
+
source: OverlayRuntimeCloseSource;
|
|
125
|
+
forced: boolean;
|
|
126
|
+
}[];
|
|
127
|
+
/** Whether a close got past the close guards. */
|
|
128
|
+
readonly isClosed: () => boolean;
|
|
129
|
+
};
|
|
130
|
+
/**
|
|
131
|
+
* A standalone `OverlayRef` for unit-testing an overlay component without opening it: `close(result)`
|
|
132
|
+
* runs the registered close guards, records the call and emits `beforeClosed` / `afterClosed`
|
|
133
|
+
* (replayed, so a late subscriber still sees the result). Pair it with {@link provideTestOverlayRef}.
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* const ref = createTestOverlayRef<ProductResult>();
|
|
137
|
+
* TestBed.configureTestingModule({ providers: [provideTestOverlayRef(ref)] });
|
|
138
|
+
* // … press the component's save button …
|
|
139
|
+
* expect(ref.closeCalls.at(-1)?.result).toEqual({ saved: true });
|
|
140
|
+
*/
|
|
141
|
+
declare const createTestOverlayRef: <TResult = unknown, TComponent extends object = object>(config?: OverlayConfig) => TestOverlayRef<TComponent, TResult>;
|
|
142
|
+
/** Provides `ref` (a fresh {@link createTestOverlayRef} by default) as `OVERLAY_REF`, so `definition.injectRef()` resolves it. */
|
|
143
|
+
declare const provideTestOverlayRef: <TResult = unknown>(ref?: TestOverlayRef<object, TResult>) => Provider[];
|
|
144
|
+
|
|
145
|
+
type FieldControlDriverOptions = ControlDriverOptions & {
|
|
146
|
+
/** Matches the editable field, when it is not the host's only `input`. */
|
|
147
|
+
fieldSelector?: string;
|
|
148
|
+
};
|
|
149
|
+
/**
|
|
150
|
+
* The plumbing every text-field form control driver needs: the host component, the directive, the
|
|
151
|
+
* native field, and the value / focus / key events a user produces on it.
|
|
152
|
+
*/
|
|
153
|
+
declare const createFieldControlDriver: <T, D>(fixture: ComponentFixture<T>, directiveType: Type<D>, { fieldSelector, ...controlOptions }?: FieldControlDriverOptions) => {
|
|
154
|
+
field: () => HTMLInputElement;
|
|
155
|
+
fieldValue: () => string;
|
|
156
|
+
placeholder: () => string;
|
|
157
|
+
type: (text: string) => void;
|
|
158
|
+
/** Types one character at a time - what a keyboard produces, unlike `type`'s single event. */
|
|
159
|
+
typeChars: (text: string) => void;
|
|
160
|
+
typeAndBlur: (text: string) => void;
|
|
161
|
+
focus: () => void;
|
|
162
|
+
blur: () => void;
|
|
163
|
+
press: (key: string, init?: KeyboardEventInit) => KeyboardEvent;
|
|
164
|
+
pointer: (target: EventTarget, type: string, init?: PointerEventInit) => void;
|
|
165
|
+
fixture: ComponentFixture<T>;
|
|
166
|
+
host: T;
|
|
167
|
+
control: D;
|
|
168
|
+
detectChanges: () => void;
|
|
169
|
+
tick: () => void;
|
|
170
|
+
element: () => HTMLElement;
|
|
171
|
+
directive: <X>(type: Type<X>, selector?: string) => X;
|
|
172
|
+
query: <E extends HTMLElement = HTMLElement>(selector: string) => E | null;
|
|
173
|
+
queryAll: <E extends HTMLElement = HTMLElement>(selector: string) => E[];
|
|
174
|
+
text: (selector: string) => string | null;
|
|
175
|
+
click: (element: HTMLElement) => void;
|
|
176
|
+
};
|
|
177
|
+
type FieldControlDriver<T, D> = ReturnType<typeof createFieldControlDriver<T, D>>;
|
|
178
|
+
|
|
179
|
+
type OverlayControlDriverOptions<D> = ControlDriverOptions & {
|
|
180
|
+
/** The element the user clicks to open the overlay. */
|
|
181
|
+
triggerSelector?: string;
|
|
182
|
+
/** How this control closes its overlay from code. */
|
|
183
|
+
hide: (control: D) => void;
|
|
184
|
+
};
|
|
185
|
+
/**
|
|
186
|
+
* The plumbing every overlay-backed form control driver needs: the host component, the directive,
|
|
187
|
+
* the trigger, the overlay pane, and the open/close dance jsdom needs two frames for.
|
|
188
|
+
*/
|
|
189
|
+
declare const createOverlayControlDriver: <T, D>(fixture: ComponentFixture<T>, directiveType: Type<D>, { triggerSelector, hide, ...controlOptions }: OverlayControlDriverOptions<D>) => {
|
|
190
|
+
settle: () => Promise<void>;
|
|
191
|
+
trigger: <E extends HTMLElement = HTMLElement>() => E;
|
|
192
|
+
pane: () => HTMLElement | null;
|
|
193
|
+
paneEl: <E extends HTMLElement = HTMLElement>(selector: string) => E | null;
|
|
194
|
+
paneEls: <E extends HTMLElement = HTMLElement>(selector: string) => E[];
|
|
195
|
+
open: () => Promise<void>;
|
|
196
|
+
close: () => Promise<void>;
|
|
197
|
+
closeAndRemovePanes: () => void;
|
|
198
|
+
press: (key: string) => KeyboardEvent;
|
|
199
|
+
escape: () => KeyboardEvent;
|
|
200
|
+
pointerDownOutside: () => void;
|
|
201
|
+
clickInPane: (selector: string) => void;
|
|
202
|
+
fixture: ComponentFixture<T>;
|
|
203
|
+
host: T;
|
|
204
|
+
control: D;
|
|
205
|
+
detectChanges: () => void;
|
|
206
|
+
tick: () => void;
|
|
207
|
+
element: () => HTMLElement;
|
|
208
|
+
directive: <X>(type: Type<X>, selector?: string) => X;
|
|
209
|
+
query: <E extends HTMLElement = HTMLElement>(selector: string) => E | null;
|
|
210
|
+
queryAll: <E extends HTMLElement = HTMLElement>(selector: string) => E[];
|
|
211
|
+
text: (selector: string) => string | null;
|
|
212
|
+
click: (element: HTMLElement) => void;
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
declare const createSelectDriver: <T>(fixture: ComponentFixture<T>, controlOptions?: ControlDriverOptions) => {
|
|
216
|
+
select: SelectDirective<unknown>;
|
|
217
|
+
searchInput: () => HTMLInputElement;
|
|
218
|
+
valueEl: () => HTMLElement | null;
|
|
219
|
+
valueText: () => string | null;
|
|
220
|
+
chips: () => HTMLElement[];
|
|
221
|
+
chipLabels: () => (string | null)[];
|
|
222
|
+
chipRemoveButton: (index: number) => HTMLElement | null;
|
|
223
|
+
listbox: () => HTMLElement | null;
|
|
224
|
+
paneText: () => string | null;
|
|
225
|
+
options: () => HTMLElement[];
|
|
226
|
+
visibleOptions: () => HTMLElement[];
|
|
227
|
+
activeOption: () => HTMLElement | null;
|
|
228
|
+
activeLabel: () => string | null;
|
|
229
|
+
optionLabels: () => (string | null)[];
|
|
230
|
+
visibleLabels: () => (string | null)[];
|
|
231
|
+
optionByLabel: (label: string) => HTMLElement | null;
|
|
232
|
+
optionGroups: () => HTMLElement[];
|
|
233
|
+
groupsHidden: () => boolean[];
|
|
234
|
+
groupOptionCounts: () => number[];
|
|
235
|
+
groupLabel: (index: number) => string | null;
|
|
236
|
+
virtualPadding: () => {
|
|
237
|
+
start: number;
|
|
238
|
+
end: number;
|
|
239
|
+
};
|
|
240
|
+
clickOption: (index: number) => void;
|
|
241
|
+
clickOptionByLabel: (label: string) => void;
|
|
242
|
+
removeChip: (index: number) => void;
|
|
243
|
+
hover: (element: HTMLElement) => void;
|
|
244
|
+
type: (text: string) => void;
|
|
245
|
+
pressInSearch: (key: string) => KeyboardEvent;
|
|
246
|
+
paste: (text: string) => void;
|
|
247
|
+
settle: () => Promise<void>;
|
|
248
|
+
trigger: <E extends HTMLElement = HTMLElement>() => E;
|
|
249
|
+
pane: () => HTMLElement | null;
|
|
250
|
+
paneEl: <E extends HTMLElement = HTMLElement>(selector: string) => E | null;
|
|
251
|
+
paneEls: <E extends HTMLElement = HTMLElement>(selector: string) => E[];
|
|
252
|
+
open: () => Promise<void>;
|
|
253
|
+
close: () => Promise<void>;
|
|
254
|
+
closeAndRemovePanes: () => void;
|
|
255
|
+
press: (key: string) => KeyboardEvent;
|
|
256
|
+
escape: () => KeyboardEvent;
|
|
257
|
+
pointerDownOutside: () => void;
|
|
258
|
+
clickInPane: (selector: string) => void;
|
|
259
|
+
fixture: ComponentFixture<T>;
|
|
260
|
+
host: T;
|
|
261
|
+
control: SelectDirective<unknown>;
|
|
262
|
+
detectChanges: () => void;
|
|
263
|
+
tick: () => void;
|
|
264
|
+
element: () => HTMLElement;
|
|
265
|
+
directive: <X>(type: _angular_core.Type<X>, selector?: string) => X;
|
|
266
|
+
query: <E extends HTMLElement = HTMLElement>(selector: string) => E | null;
|
|
267
|
+
queryAll: <E extends HTMLElement = HTMLElement>(selector: string) => E[];
|
|
268
|
+
text: (selector: string) => string | null;
|
|
269
|
+
click: (element: HTMLElement) => void;
|
|
270
|
+
};
|
|
271
|
+
type SelectDriver<T> = ReturnType<typeof createSelectDriver<T>>;
|
|
272
|
+
|
|
273
|
+
type TabBarDriverOptions = ControlDriverOptions & {
|
|
274
|
+
/** Matches every trigger inside the bar. Defaults to the role every `TabBarTriggerDirective` host carries. */
|
|
275
|
+
triggerSelector?: string;
|
|
276
|
+
};
|
|
277
|
+
/**
|
|
278
|
+
* Wraps a mounted `[etTabBar]` host with the roving-tabindex vocabulary its keyboard model needs:
|
|
279
|
+
* which trigger is currently the tab stop, and dispatching a key from wherever focus actually is.
|
|
280
|
+
*/
|
|
281
|
+
declare const createTabBarDriver: <T>(fixture: ComponentFixture<T>, options?: TabBarDriverOptions) => {
|
|
282
|
+
triggers: () => HTMLButtonElement[];
|
|
283
|
+
trigger: (index: number) => HTMLButtonElement;
|
|
284
|
+
tabbableTrigger: () => HTMLButtonElement | null;
|
|
285
|
+
focusTabbable: () => void;
|
|
286
|
+
press: (key: string, init?: KeyboardEventInit) => KeyboardEvent;
|
|
287
|
+
focusedIndex: () => number;
|
|
288
|
+
selectedIndex: () => number;
|
|
289
|
+
fixture: ComponentFixture<T>;
|
|
290
|
+
host: T;
|
|
291
|
+
control: TabBarDirective;
|
|
292
|
+
detectChanges: () => void;
|
|
293
|
+
tick: () => void;
|
|
294
|
+
element: () => HTMLElement;
|
|
295
|
+
directive: <X>(type: _angular_core.Type<X>, selector?: string) => X;
|
|
296
|
+
query: <E extends HTMLElement = HTMLElement>(selector: string) => E | null;
|
|
297
|
+
queryAll: <E extends HTMLElement = HTMLElement>(selector: string) => E[];
|
|
298
|
+
text: (selector: string) => string | null;
|
|
299
|
+
click: (element: HTMLElement) => void;
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Installs the browser APIs jsdom lacks and `@ethlete/components` needs to render: `ResizeObserver`,
|
|
304
|
+
* `IntersectionObserver`, `matchMedia` and `Element.prototype.animate`. Call it once in a test setup file;
|
|
305
|
+
* an API that already exists is left alone. The fakes never report: observers never fire, no media query
|
|
306
|
+
* matches, and an animation finishes on the next microtask.
|
|
307
|
+
*/
|
|
308
|
+
declare const setupComponentsTestEnvironment: () => void;
|
|
309
|
+
|
|
310
|
+
export { blurField, createControlDriver, createDatePickerDriver, createFieldControlDriver, createOverlayControlDriver, createSelectDriver, createTabBarDriver, createTestOverlayRef, directiveAt, flushFrames, focusEvent, focusField, hostDirective, hostElement, latestPane, pasteInto, pointerDownOutside, pointerEnter, pointerEvent, pressKey, provideTestOverlayRef, query, queryAll, resetOverlays, setInputValue, setupComponentsTestEnvironment, textOf, tick, typeChars, typeInField, typeMasked };
|
|
311
|
+
export type { ClipboardPayload, ControlDriverOptions, DatePickerDriver, FieldControlDriver, FieldControlDriverOptions, OverlayControlDriverOptions, SelectDriver, TabBarDriverOptions, TestOverlayRef };
|