@gjsify/adwaita-web 0.30.0 → 0.32.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/dist/adwaita-web.css +786 -272
- package/dist/adwaita-web.css.map +1 -1
- package/lib/types/adw-about-dialog.spec.d.ts +1 -0
- package/lib/types/adw-action-rows.spec.d.ts +1 -0
- package/lib/types/adw-avatar.spec.d.ts +1 -0
- package/lib/types/adw-banner.spec.d.ts +1 -0
- package/lib/types/adw-button-content.spec.d.ts +1 -0
- package/lib/types/adw-carousel.spec.d.ts +1 -0
- package/lib/types/adw-checks.spec.d.ts +1 -0
- package/lib/types/adw-header-bar.spec.d.ts +1 -0
- package/lib/types/adw-icon.spec.d.ts +1 -0
- package/lib/types/adw-progress-bar.spec.d.ts +1 -0
- package/lib/types/adw-sidebar.spec.d.ts +1 -0
- package/lib/types/adw-switch.spec.d.ts +1 -0
- package/lib/types/adw-wrap-box.spec.d.ts +1 -0
- package/lib/types/bottom-sheet.spec.d.ts +1 -0
- package/lib/types/breakpoints.d.ts +22 -0
- package/lib/types/breakpoints.spec.d.ts +1 -0
- package/lib/types/chrome.spec.d.ts +1 -0
- package/lib/types/elements/adw-about-dialog.d.ts +47 -8
- package/lib/types/elements/adw-action-row.d.ts +35 -0
- package/lib/types/elements/adw-avatar.d.ts +11 -0
- package/lib/types/elements/adw-bottom-sheet.d.ts +33 -4
- package/lib/types/elements/adw-button-content.d.ts +12 -0
- package/lib/types/elements/adw-button-row.d.ts +10 -1
- package/lib/types/elements/adw-carousel.d.ts +111 -8
- package/lib/types/elements/adw-checks.d.ts +57 -0
- package/lib/types/elements/adw-clamp.d.ts +4 -1
- package/lib/types/elements/adw-data-grid.d.ts +11 -31
- package/lib/types/elements/adw-drop-down.d.ts +17 -20
- package/lib/types/elements/adw-entry-row.d.ts +93 -3
- package/lib/types/elements/adw-expander-row.d.ts +7 -1
- package/lib/types/elements/adw-header-bar.d.ts +15 -0
- package/lib/types/elements/adw-icon.d.ts +25 -0
- package/lib/types/elements/adw-inline-view-switcher.d.ts +37 -11
- package/lib/types/elements/adw-menu-button.d.ts +6 -6
- package/lib/types/elements/adw-navigation-split-view.d.ts +6 -0
- package/lib/types/elements/adw-navigation-view.d.ts +63 -20
- package/lib/types/elements/adw-overlay-split-view.d.ts +38 -0
- package/lib/types/elements/adw-password-entry-row.d.ts +19 -10
- package/lib/types/elements/adw-popover.d.ts +58 -0
- package/lib/types/elements/adw-preferences-dialog.d.ts +57 -2
- package/lib/types/elements/adw-preferences-group.d.ts +31 -0
- package/lib/types/elements/adw-progress-bar.d.ts +38 -0
- package/lib/types/elements/adw-sidebar.d.ts +37 -5
- package/lib/types/elements/adw-split-button.d.ts +53 -7
- package/lib/types/elements/adw-switch-row.d.ts +11 -2
- package/lib/types/elements/adw-switch.d.ts +15 -0
- package/lib/types/elements/adw-tab-view.d.ts +129 -12
- package/lib/types/elements/adw-toolbar-view.d.ts +5 -0
- package/lib/types/elements/adw-view-stack.d.ts +27 -19
- package/lib/types/elements/adw-view-switcher-bar.d.ts +23 -7
- package/lib/types/elements/adw-view-switcher.d.ts +22 -11
- package/lib/types/elements/adw-window-title.d.ts +3 -1
- package/lib/types/elements/view-switcher-dom.d.ts +44 -0
- package/lib/types/entry-rows.spec.d.ts +1 -0
- package/lib/types/index.d.ts +7 -0
- package/lib/types/navigation-view.spec.d.ts +1 -0
- package/lib/types/preferences-search.d.ts +20 -0
- package/lib/types/preferences.spec.d.ts +1 -0
- package/lib/types/split-button.spec.d.ts +1 -0
- package/lib/types/split-views.spec.d.ts +1 -0
- package/lib/types/styles.generated.d.ts +1 -1
- package/lib/types/tab-view.spec.d.ts +1 -0
- package/lib/types/view-stack.spec.d.ts +1 -0
- package/lib/types/view-switcher.spec.d.ts +1 -0
- package/package.json +6 -6
- package/scss/_banner.scss +13 -0
- package/scss/_bottom_sheet.scss +5 -6
- package/scss/_button.scss +3 -26
- package/scss/_button_content.scss +28 -0
- package/scss/_checks.scss +228 -0
- package/scss/_clamp.scss +9 -3
- package/scss/_data_grid.scss +15 -7
- package/scss/_drop_down.scss +12 -55
- package/scss/_expander_row.scss +5 -50
- package/scss/_icon.scss +51 -0
- package/scss/_icons.generated.scss +6 -0
- package/scss/_inline_view_switcher.scss +34 -0
- package/scss/_labels.scss +135 -0
- package/scss/_menu_button.scss +10 -70
- package/scss/_popover.scss +186 -0
- package/scss/_preferences.scss +29 -0
- package/scss/_preferences_dialog.scss +17 -0
- package/scss/_progress_bar.scss +161 -0
- package/scss/_reset.scss +18 -7
- package/scss/_spinner.scss +7 -3
- package/scss/_split_button.scss +6 -50
- package/scss/_switch.scss +90 -0
- package/scss/_switch_row.scss +6 -52
- package/scss/_tab_view.scss +64 -0
- package/scss/_theme.scss +10 -0
- package/scss/_toolbar_view.scss +74 -0
- package/scss/_variables.scss +34 -0
- package/scss/_view_switcher.scss +40 -0
- package/scss/_view_switcher_bar.scss +37 -0
- package/scss/_wrap_box.scss +56 -6
- package/scss/adwaita-skin.scss +23 -0
- package/src/adw-about-dialog.spec.ts +350 -0
- package/src/adw-action-rows.spec.ts +342 -0
- package/src/adw-avatar.spec.ts +139 -0
- package/src/adw-banner.spec.ts +152 -0
- package/src/adw-button-content.spec.ts +183 -0
- package/src/adw-button-row.spec.ts +12 -6
- package/src/adw-carousel.spec.ts +389 -0
- package/src/adw-checks.spec.ts +368 -0
- package/src/adw-drop-down.spec.ts +123 -0
- package/src/adw-header-bar.spec.ts +83 -0
- package/src/adw-icon.spec.ts +167 -0
- package/src/adw-progress-bar.spec.ts +173 -0
- package/src/adw-sidebar.spec.ts +332 -0
- package/src/adw-switch.spec.ts +242 -0
- package/src/adw-tab-view.spec.ts +12 -3
- package/src/adw-view-switcher-bar.spec.ts +61 -13
- package/src/adw-wrap-box.spec.ts +194 -0
- package/src/bottom-sheet.spec.ts +325 -0
- package/src/breakpoints.spec.ts +147 -0
- package/src/breakpoints.ts +67 -0
- package/src/chrome.spec.ts +301 -0
- package/src/elements/adw-about-dialog.ts +223 -163
- package/src/elements/adw-action-row.ts +120 -10
- package/src/elements/adw-avatar.ts +48 -54
- package/src/elements/adw-banner.ts +46 -10
- package/src/elements/adw-bottom-sheet.ts +145 -60
- package/src/elements/adw-button-content.ts +107 -33
- package/src/elements/adw-button-row.ts +61 -37
- package/src/elements/adw-button.ts +5 -7
- package/src/elements/adw-carousel.ts +467 -105
- package/src/elements/adw-checks.ts +299 -0
- package/src/elements/adw-clamp.ts +80 -10
- package/src/elements/adw-combo-row.ts +15 -7
- package/src/elements/adw-data-grid.ts +43 -91
- package/src/elements/adw-drop-down.ts +117 -128
- package/src/elements/adw-entry-row.ts +404 -36
- package/src/elements/adw-expander-row.ts +61 -29
- package/src/elements/adw-header-bar.ts +31 -6
- package/src/elements/adw-icon.ts +148 -0
- package/src/elements/adw-inline-view-switcher.ts +240 -129
- package/src/elements/adw-menu-button.ts +93 -70
- package/src/elements/adw-navigation-split-view.ts +48 -7
- package/src/elements/adw-navigation-view.ts +286 -148
- package/src/elements/adw-overlay-split-view.ts +164 -14
- package/src/elements/adw-password-entry-row.ts +111 -89
- package/src/elements/adw-popover.ts +283 -0
- package/src/elements/adw-preferences-dialog.ts +120 -21
- package/src/elements/adw-preferences-group.ts +128 -22
- package/src/elements/adw-progress-bar.ts +189 -0
- package/src/elements/adw-sidebar.ts +301 -142
- package/src/elements/adw-spin-row.ts +11 -5
- package/src/elements/adw-spinner.ts +23 -8
- package/src/elements/adw-split-button.ts +371 -92
- package/src/elements/adw-status-page.ts +9 -9
- package/src/elements/adw-switch-row.ts +100 -30
- package/src/elements/adw-switch.ts +129 -0
- package/src/elements/adw-tab-view.ts +682 -129
- package/src/elements/adw-toggle-group.ts +5 -7
- package/src/elements/adw-toolbar-view.ts +84 -21
- package/src/elements/adw-view-stack.ts +162 -85
- package/src/elements/adw-view-switcher-bar.ts +163 -81
- package/src/elements/adw-view-switcher.ts +231 -112
- package/src/elements/adw-window-title.ts +44 -11
- package/src/elements/adw-wrap-box.ts +131 -35
- package/src/elements/view-switcher-dom.ts +108 -0
- package/src/entry-rows.spec.ts +391 -0
- package/src/index.ts +23 -0
- package/src/navigation-view.spec.ts +435 -0
- package/src/preferences-search.ts +135 -0
- package/src/preferences.spec.ts +250 -0
- package/src/source-view/adw-source-view.ts +2 -5
- package/src/split-button.spec.ts +470 -0
- package/src/split-views.spec.ts +309 -0
- package/src/styles.generated.ts +1 -1
- package/src/tab-view.spec.ts +451 -0
- package/src/test.browser.mts +49 -0
- package/src/view-stack.spec.ts +272 -0
- package/src/view-switcher.spec.ts +446 -0
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
// DOM-level conformance tests for the chrome elements — <adw-clamp>,
|
|
2
|
+
// <adw-spinner> and <adw-toolbar-view> — driven by the SAME vectors the
|
|
3
|
+
// NativeScript renderer asserts against (`@gjsify/adwaita-core/conformance`).
|
|
4
|
+
//
|
|
5
|
+
// Each of the three used to answer a question libadwaita had already answered,
|
|
6
|
+
// and answered it differently from the NativeScript port: the clamp was a plain
|
|
7
|
+
// `max-width` with no tightening and a `maximum-size="0"` that collapsed the
|
|
8
|
+
// child to nothing, the spinner defaulted to 24px and stroked a 2px ring where
|
|
9
|
+
// Adwaita strokes 3px, and the toolbar view carried none of the four style
|
|
10
|
+
// classes at all. Nothing failed, because nothing compared them.
|
|
11
|
+
//
|
|
12
|
+
// Sizes are driven by really resizing a host element and awaiting a real
|
|
13
|
+
// ResizeObserver delivery, the same way `breakpoints.spec.ts` does — never by
|
|
14
|
+
// faking one.
|
|
15
|
+
import { describe, expect, it } from '@gjsify/unit';
|
|
16
|
+
|
|
17
|
+
import { ADW_SPINNER_MIN_SIZE, spinnerGeometry } from '@gjsify/adwaita-core';
|
|
18
|
+
import {
|
|
19
|
+
CLAMP_ALLOCATE_VECTORS,
|
|
20
|
+
CLAMP_PROPERTY_VECTORS,
|
|
21
|
+
SPINNER_GEOMETRY_VECTORS,
|
|
22
|
+
SPINNER_SIZE_VECTORS,
|
|
23
|
+
TOOLBAR_VIEW_CLASS_VECTORS,
|
|
24
|
+
} from '@gjsify/adwaita-core/conformance';
|
|
25
|
+
|
|
26
|
+
/** Wait for a ResizeObserver delivery (it runs after layout, before paint). */
|
|
27
|
+
function settle(): Promise<void> {
|
|
28
|
+
return new Promise((resolve) => {
|
|
29
|
+
requestAnimationFrame(() => requestAnimationFrame(() => resolve()));
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** A fixed-width host in the document, plus a way to resize it. */
|
|
34
|
+
function mountSized(width: number): { host: HTMLElement; resize: (w: number) => Promise<void> } {
|
|
35
|
+
const host = document.createElement('div');
|
|
36
|
+
host.style.width = `${width}px`;
|
|
37
|
+
document.body.appendChild(host);
|
|
38
|
+
return {
|
|
39
|
+
host,
|
|
40
|
+
resize: async (w: number) => {
|
|
41
|
+
host.style.width = `${w}px`;
|
|
42
|
+
await settle();
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** A clamp with one block child, mounted in a host of `available` px. */
|
|
48
|
+
function mountClamp(available: number): {
|
|
49
|
+
host: HTMLElement;
|
|
50
|
+
clamp: HTMLElement;
|
|
51
|
+
child: HTMLElement;
|
|
52
|
+
resize: (w: number) => Promise<void>;
|
|
53
|
+
} {
|
|
54
|
+
const { host, resize } = mountSized(available);
|
|
55
|
+
const clamp = document.createElement('adw-clamp');
|
|
56
|
+
const child = document.createElement('div');
|
|
57
|
+
// A bare block child fills the clamp and is capped by the max-width the
|
|
58
|
+
// element writes — the same shape every story uses.
|
|
59
|
+
child.textContent = 'clamped';
|
|
60
|
+
clamp.appendChild(child);
|
|
61
|
+
host.appendChild(clamp);
|
|
62
|
+
return { host, clamp, child, resize };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** The child width a clamp settles on, rounded to the pixel it renders at. */
|
|
66
|
+
function clampedWidth(child: HTMLElement): number {
|
|
67
|
+
return Math.round(child.getBoundingClientRect().width);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** The three classes `adw_clamp_layout_allocate` stamps on the child. */
|
|
71
|
+
function sizeClassOf(child: HTMLElement): string | null {
|
|
72
|
+
for (const cls of ['small', 'medium', 'large']) {
|
|
73
|
+
if (child.classList.contains(cls)) return cls;
|
|
74
|
+
}
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** A toolbar view with bars of the given pixel heights (0 = no bar at all). */
|
|
79
|
+
function mountToolbarView(topBarHeight: number, bottomBarHeight: number): { host: HTMLElement; view: HTMLElement } {
|
|
80
|
+
const { host } = mountSized(400);
|
|
81
|
+
host.style.height = '300px';
|
|
82
|
+
const view = document.createElement('adw-toolbar-view');
|
|
83
|
+
for (const [slot, height] of [
|
|
84
|
+
['top', topBarHeight],
|
|
85
|
+
['bottom', bottomBarHeight],
|
|
86
|
+
] as const) {
|
|
87
|
+
if (height <= 0) continue;
|
|
88
|
+
const bar = document.createElement('div');
|
|
89
|
+
bar.setAttribute('slot', slot);
|
|
90
|
+
bar.style.height = `${height}px`;
|
|
91
|
+
view.appendChild(bar);
|
|
92
|
+
}
|
|
93
|
+
host.appendChild(view);
|
|
94
|
+
return { host, view };
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export const AdwChromeTest = async () => {
|
|
98
|
+
await describe('adw-clamp allocation (AdwClampLayout conformance vectors)', async () => {
|
|
99
|
+
// The browser resolves the child's own minimum through the normal
|
|
100
|
+
// `min-width` cascade, so only the rows that pass a zero child minimum
|
|
101
|
+
// describe what this element can be held to.
|
|
102
|
+
const vectors = CLAMP_ALLOCATE_VECTORS.filter((v) => v.params.childMin === 0);
|
|
103
|
+
|
|
104
|
+
for (const { availableSize, params, childSize, sizeClass, offset, rule } of vectors) {
|
|
105
|
+
await it(`${availableSize}px available → a ${childSize}px ${sizeClass} child — ${rule}`, async () => {
|
|
106
|
+
const { host, clamp, child } = mountClamp(availableSize);
|
|
107
|
+
clamp.setAttribute('maximum-size', String(params.maximumSize));
|
|
108
|
+
clamp.setAttribute('tightening-threshold', String(params.tighteningThreshold));
|
|
109
|
+
await settle();
|
|
110
|
+
|
|
111
|
+
expect(clampedWidth(child)).toBe(childSize);
|
|
112
|
+
expect(sizeClassOf(child)).toBe(sizeClass);
|
|
113
|
+
// `margin-inline: auto` splits the remainder evenly; libadwaita
|
|
114
|
+
// truncates, so the two can differ by half a pixel.
|
|
115
|
+
const leading = child.getBoundingClientRect().left - clamp.getBoundingClientRect().left;
|
|
116
|
+
expect(Math.abs(leading - offset) <= 1).toBe(true);
|
|
117
|
+
|
|
118
|
+
host.remove();
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
await it('follows the viewport instead of pinning the child to the maximum', async () => {
|
|
123
|
+
// The NativeScript twin's bug in browser form: a narrow clamp must
|
|
124
|
+
// hand the child ALL of the available width, not the cap.
|
|
125
|
+
const { host, clamp, child, resize } = mountClamp(1000);
|
|
126
|
+
await settle();
|
|
127
|
+
expect(clampedWidth(child)).toBe(600);
|
|
128
|
+
await resize(360);
|
|
129
|
+
expect(clampedWidth(child)).toBe(360);
|
|
130
|
+
expect(Math.round(clamp.getBoundingClientRect().width)).toBe(360);
|
|
131
|
+
host.remove();
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
await it('honours tightening-threshold, which the element used to ignore', async () => {
|
|
135
|
+
// The storybook has exposed this control all along and only the GTK
|
|
136
|
+
// pane responded to it.
|
|
137
|
+
const { host, clamp, child } = mountClamp(700);
|
|
138
|
+
clamp.setAttribute('maximum-size', '600');
|
|
139
|
+
clamp.setAttribute('tightening-threshold', '400');
|
|
140
|
+
await settle();
|
|
141
|
+
expect(clampedWidth(child)).toBe(575);
|
|
142
|
+
|
|
143
|
+
// Raising the threshold above the maximum removes the easing.
|
|
144
|
+
clamp.setAttribute('tightening-threshold', '800');
|
|
145
|
+
await settle();
|
|
146
|
+
expect(clampedWidth(child)).toBe(600);
|
|
147
|
+
host.remove();
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
await it('clamps children appended after it was connected', async () => {
|
|
151
|
+
// The element only saw its children once, at connect time — the same
|
|
152
|
+
// "evaluated once" shape the toolbar view's empty-bar handling has.
|
|
153
|
+
const { host } = mountSized(1000);
|
|
154
|
+
const clamp = document.createElement('adw-clamp');
|
|
155
|
+
host.appendChild(clamp);
|
|
156
|
+
await settle();
|
|
157
|
+
|
|
158
|
+
const late = document.createElement('div');
|
|
159
|
+
late.textContent = 'appended later';
|
|
160
|
+
clamp.appendChild(late);
|
|
161
|
+
await settle();
|
|
162
|
+
|
|
163
|
+
expect(clampedWidth(late)).toBe(600);
|
|
164
|
+
host.remove();
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
await describe('adw-clamp maximum-size parsing (g_param_spec_int range)', async () => {
|
|
169
|
+
for (const { value, fallback, size, rule } of CLAMP_PROPERTY_VECTORS) {
|
|
170
|
+
// Only the rows whose fallback is the real property default describe
|
|
171
|
+
// what an attribute on THIS element resolves to.
|
|
172
|
+
if (fallback !== 600) continue;
|
|
173
|
+
|
|
174
|
+
await it(`maximum-size ${JSON.stringify(value ?? null)} caps at ${size}px — ${rule}`, async () => {
|
|
175
|
+
const { host, clamp, child } = mountClamp(1000);
|
|
176
|
+
// `null`/`undefined` are the ABSENT attribute, so nothing is set.
|
|
177
|
+
if (value !== null && value !== undefined) clamp.setAttribute('maximum-size', String(value));
|
|
178
|
+
await settle();
|
|
179
|
+
|
|
180
|
+
// 1000px is past `upper` for every cap in the table, so the child
|
|
181
|
+
// sits exactly at the resolved property and it is readable off
|
|
182
|
+
// the rendered width.
|
|
183
|
+
expect(clampedWidth(child)).toBe(size);
|
|
184
|
+
host.remove();
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
await it('recovers the default after an unparsable value, instead of freezing on the old cap', async () => {
|
|
189
|
+
// `parseFloat('abc')` produced `max-width: NaNpx`, which the CSSOM
|
|
190
|
+
// rejects — so the element silently kept whatever cap it had.
|
|
191
|
+
const { host, clamp, child } = mountClamp(1000);
|
|
192
|
+
clamp.setAttribute('maximum-size', '300');
|
|
193
|
+
await settle();
|
|
194
|
+
expect(clampedWidth(child)).toBe(300);
|
|
195
|
+
|
|
196
|
+
clamp.setAttribute('maximum-size', 'abc');
|
|
197
|
+
await settle();
|
|
198
|
+
expect(clampedWidth(child)).toBe(600);
|
|
199
|
+
host.remove();
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
await describe('adw-spinner geometry (AdwSpinnerPaintable conformance vectors)', async () => {
|
|
204
|
+
for (const { width, height, diameter, lineWidth, rule } of SPINNER_GEOMETRY_VECTORS) {
|
|
205
|
+
// The element is the ring itself, so only the square, allocatable
|
|
206
|
+
// boxes describe what a `size` attribute can produce.
|
|
207
|
+
if (width !== height || width < ADW_SPINNER_MIN_SIZE) continue;
|
|
208
|
+
|
|
209
|
+
await it(`size ${width} draws a ${diameter}px ring stroked ${lineWidth}px — ${rule}`, () => {
|
|
210
|
+
const { host } = mountSized(200);
|
|
211
|
+
const spinner = document.createElement('adw-spinner');
|
|
212
|
+
spinner.setAttribute('size', String(width));
|
|
213
|
+
host.appendChild(spinner);
|
|
214
|
+
|
|
215
|
+
expect(spinner.offsetWidth).toBe(diameter);
|
|
216
|
+
expect(spinner.offsetHeight).toBe(diameter);
|
|
217
|
+
expect(Number.parseFloat(spinner.style.borderWidth)).toBe(lineWidth);
|
|
218
|
+
host.remove();
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
await it('strokes 3px at 24 and 6px at 48, where it used to stroke 2 and 4', () => {
|
|
223
|
+
const { host } = mountSized(200);
|
|
224
|
+
const spinner = document.createElement('adw-spinner');
|
|
225
|
+
host.appendChild(spinner);
|
|
226
|
+
const strokeAt = (size: number) => {
|
|
227
|
+
spinner.setAttribute('size', String(size));
|
|
228
|
+
return Number.parseFloat(spinner.style.borderWidth);
|
|
229
|
+
};
|
|
230
|
+
expect(strokeAt(24)).toBe(3);
|
|
231
|
+
expect(strokeAt(48)).toBe(6);
|
|
232
|
+
expect(strokeAt(64)).toBe(8);
|
|
233
|
+
host.remove();
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
await describe('adw-spinner sizing (adw_spinner_measure minimum = natural)', async () => {
|
|
238
|
+
for (const { value, size, rule } of SPINNER_SIZE_VECTORS) {
|
|
239
|
+
await it(`size ${JSON.stringify(value ?? null)} → a ${spinnerGeometry(size, size).diameter}px ring — ${rule}`, () => {
|
|
240
|
+
const { host } = mountSized(400);
|
|
241
|
+
const spinner = document.createElement('adw-spinner');
|
|
242
|
+
if (value !== null && value !== undefined) spinner.setAttribute('size', String(value));
|
|
243
|
+
host.appendChild(spinner);
|
|
244
|
+
|
|
245
|
+
expect(spinner.offsetWidth).toBe(spinnerGeometry(size, size).diameter);
|
|
246
|
+
host.remove();
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
await it('defaults to the measured 16, not the invented 24', () => {
|
|
251
|
+
const { host } = mountSized(400);
|
|
252
|
+
const spinner = document.createElement('adw-spinner');
|
|
253
|
+
host.appendChild(spinner);
|
|
254
|
+
expect(spinner.offsetWidth).toBe(ADW_SPINNER_MIN_SIZE);
|
|
255
|
+
host.remove();
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
await describe('adw-toolbar-view style classes (update_undershoots + the style setters)', async () => {
|
|
260
|
+
for (const { input, view, topBar, bottomBar, rule } of TOOLBAR_VIEW_CLASS_VECTORS) {
|
|
261
|
+
await it(`${input.topBarStyle}/${input.bottomBarStyle} → [${view.join(' ')}] — ${rule}`, () => {
|
|
262
|
+
const { host, view: element } = mountToolbarView(input.topBarHeight, input.bottomBarHeight);
|
|
263
|
+
element.setAttribute('top-bar-style', input.topBarStyle);
|
|
264
|
+
element.setAttribute('bottom-bar-style', input.bottomBarStyle);
|
|
265
|
+
if (input.extendContentToTopEdge) element.setAttribute('extend-content-to-top-edge', '');
|
|
266
|
+
if (input.extendContentToBottomEdge) element.setAttribute('extend-content-to-bottom-edge', '');
|
|
267
|
+
|
|
268
|
+
const topEl = element.querySelector('.adw-toolbar-view-top') as HTMLElement;
|
|
269
|
+
const bottomEl = element.querySelector('.adw-toolbar-view-bottom') as HTMLElement;
|
|
270
|
+
|
|
271
|
+
for (const cls of ['undershoot-top', 'undershoot-bottom']) {
|
|
272
|
+
expect(element.classList.contains(cls)).toBe(view.includes(cls));
|
|
273
|
+
}
|
|
274
|
+
for (const cls of ['raised', 'border']) {
|
|
275
|
+
expect(topEl.classList.contains(cls)).toBe(topBar.includes(cls));
|
|
276
|
+
expect(bottomEl.classList.contains(cls)).toBe(bottomBar.includes(cls));
|
|
277
|
+
}
|
|
278
|
+
host.remove();
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
await it('drops the undershoot again when the style stops being flat', () => {
|
|
283
|
+
const { host, view } = mountToolbarView(46, 0);
|
|
284
|
+
expect(view.classList.contains('undershoot-top')).toBe(true);
|
|
285
|
+
view.setAttribute('top-bar-style', 'raised');
|
|
286
|
+
expect(view.classList.contains('undershoot-top')).toBe(false);
|
|
287
|
+
view.setAttribute('top-bar-style', 'flat');
|
|
288
|
+
expect(view.classList.contains('undershoot-top')).toBe(true);
|
|
289
|
+
host.remove();
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
await it('treats an unknown style as flat, the way the enum guard does', () => {
|
|
293
|
+
const { host, view } = mountToolbarView(46, 0);
|
|
294
|
+
view.setAttribute('top-bar-style', 'shadowed');
|
|
295
|
+
const topEl = view.querySelector('.adw-toolbar-view-top') as HTMLElement;
|
|
296
|
+
expect(topEl.classList.contains('raised')).toBe(false);
|
|
297
|
+
expect(view.classList.contains('undershoot-top')).toBe(true);
|
|
298
|
+
host.remove();
|
|
299
|
+
});
|
|
300
|
+
});
|
|
301
|
+
};
|