@gjsify/adwaita-web 0.64.12-next.281 → 0.64.13-next.283
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 +31 -0
- package/dist/adwaita-web.css.map +1 -1
- package/lib/types/elements/adw-combo-row.d.ts +34 -15
- package/lib/types/elements/adw-expander-row.d.ts +3 -0
- package/lib/types/elements/gtk-drop-down.d.ts +31 -5
- package/lib/types/elements/gtk-label.d.ts +64 -0
- package/lib/types/label-markup.d.ts +30 -0
- package/lib/types/namespace/gdk.d.ts +1 -1
- package/lib/types/pango-markup.d.ts +17 -0
- package/lib/types/styles.generated.d.ts +1 -1
- package/package.json +12 -12
- package/scss/_labels.scss +19 -0
- package/scss/_link.scss +73 -7
- package/src/adw-action-rows.spec.ts +19 -0
- package/src/adw-row-state.spec.ts +200 -63
- package/src/construct-vectors.spec.ts +4 -2
- package/src/elements/adw-combo-row.ts +93 -47
- package/src/elements/adw-expander-row.ts +46 -16
- package/src/elements/gtk-drop-down.ts +111 -35
- package/src/elements/gtk-label.ts +206 -16
- package/src/elements/gtk-page-setup-unix-dialog.ts +8 -6
- package/src/file-chooser-host.ts +2 -1
- package/src/gtk-drop-down.spec.ts +91 -75
- package/src/gtk-label.spec.ts +431 -11
- package/src/gtk-switch.spec.ts +8 -0
- package/src/gtk-value-doors.spec.ts +70 -32
- package/src/label-markup.ts +193 -0
- package/src/namespace/gdk.ts +1 -0
- package/src/pango-markup.ts +9 -3
- package/src/split-button.spec.ts +7 -4
- package/src/styles.generated.ts +1 -1
- package/src/value-lists.spec.ts +2 -2
|
@@ -8,7 +8,9 @@
|
|
|
8
8
|
// composes the same `ComboState` and drives the same table from its own DOM
|
|
9
9
|
// (`adw-row-state.spec.ts`) — it could not while two of its four step ops had no DOM
|
|
10
10
|
// spelling there, its model arriving through an attribute at connect time only (#1525).
|
|
11
|
-
// The two
|
|
11
|
+
// The two used to part on ONE row — `an index past the end`, which this element rejected
|
|
12
|
+
// and the row accepted — and that carve-out is GONE: ADR 0122 § 4 measured libadwaita,
|
|
13
|
+
// found the rejection right, and the row adopted it. Both selectors now drive every row.
|
|
12
14
|
import { describe, it, expect } from '@gjsify/unit';
|
|
13
15
|
|
|
14
16
|
import {
|
|
@@ -17,9 +19,13 @@ import {
|
|
|
17
19
|
LIST_MODEL_OWNERSHIP_VECTORS,
|
|
18
20
|
LIST_NORMALIZE_VECTORS,
|
|
19
21
|
LIST_PARSE_VECTORS,
|
|
22
|
+
applyListMutation,
|
|
20
23
|
applyListReadback,
|
|
24
|
+
listModelForInput,
|
|
21
25
|
} from '@gjsify/adwaita-core/conformance';
|
|
22
|
-
import type { ComboSelectionStep
|
|
26
|
+
import type { ComboSelectionStep } from '@gjsify/adwaita-core/conformance';
|
|
27
|
+
import { GjsifyOptionList } from '@gjsify/adwaita-core';
|
|
28
|
+
import type { AdwComboOptionInput } from '@gjsify/adwaita-core';
|
|
23
29
|
|
|
24
30
|
import type { GtkDropDown } from './elements/gtk-drop-down.js';
|
|
25
31
|
|
|
@@ -29,6 +35,20 @@ function makeDropDown(): GtkDropDown {
|
|
|
29
35
|
return el;
|
|
30
36
|
}
|
|
31
37
|
|
|
38
|
+
/**
|
|
39
|
+
* Assign a model built out of an authored array.
|
|
40
|
+
*
|
|
41
|
+
* The array itself no longer goes to the property — ADR 0122 § 4 narrowed `model` to a real
|
|
42
|
+
* `Gio.ListModel` — so every test below that is about something OTHER than the door says so
|
|
43
|
+
* in one place. The tests that ARE about the door (`LIST_NORMALIZE_VECTORS` and the array
|
|
44
|
+
* refusal in `gtk-value-doors.spec.ts`) write to `model` directly.
|
|
45
|
+
*/
|
|
46
|
+
function setModel(dd: GtkDropDown, options: readonly AdwComboOptionInput[]): GjsifyOptionList {
|
|
47
|
+
const list = GjsifyOptionList.new(options);
|
|
48
|
+
dd.model = list;
|
|
49
|
+
return list;
|
|
50
|
+
}
|
|
51
|
+
|
|
32
52
|
/** The text the closed button shows — the rendered `selectedLabel`. */
|
|
33
53
|
function labelText(dd: GtkDropDown): string {
|
|
34
54
|
return dd.querySelector('.adw-drop-down-label')?.textContent ?? '';
|
|
@@ -42,12 +62,21 @@ function openChooser(dd: GtkDropDown): void {
|
|
|
42
62
|
/**
|
|
43
63
|
* Replay one vector step against the real element — property sets for the
|
|
44
64
|
* programmatic ops, a popover gesture for the interactive one.
|
|
65
|
+
*
|
|
66
|
+
* Every `setModel` builds a FRESH list, which is what makes `setModelAgain` — assigning the
|
|
67
|
+
* identity the element already holds — a distinct step rather than a repeat of the one above
|
|
68
|
+
* it.
|
|
45
69
|
*/
|
|
46
70
|
function applyStep(dd: GtkDropDown, step: ComboSelectionStep): void {
|
|
47
71
|
switch (step.op) {
|
|
48
72
|
case 'setModel':
|
|
49
|
-
dd
|
|
73
|
+
setModel(dd, [...step.model]);
|
|
74
|
+
return;
|
|
75
|
+
case 'setModelAgain': {
|
|
76
|
+
const held = dd.model;
|
|
77
|
+
dd.model = held;
|
|
50
78
|
return;
|
|
79
|
+
}
|
|
51
80
|
case 'setSelectedIndex':
|
|
52
81
|
dd.selected = step.index;
|
|
53
82
|
return;
|
|
@@ -67,23 +96,6 @@ function applyStep(dd: GtkDropDown, step: ComboSelectionStep): void {
|
|
|
67
96
|
}
|
|
68
97
|
}
|
|
69
98
|
|
|
70
|
-
/**
|
|
71
|
-
* The ONE row this element answers differently, on purpose: its published `selected`
|
|
72
|
-
* contract REJECTS an out-of-range set (`_selectIndex` gates on `ComboState.hasIndex`)
|
|
73
|
-
* where the core state accepts it and reports an empty value — the split
|
|
74
|
-
* `ComboState.hasIndex`'s doc records and `<adw-combo-row>` takes the other side of. The
|
|
75
|
-
* row is still driven below, against the element's answer, so neither policy can change
|
|
76
|
-
* silently.
|
|
77
|
-
*/
|
|
78
|
-
const DROP_DOWN_REJECTS = 'an index past the end';
|
|
79
|
-
|
|
80
|
-
/** The named vector — a hard failure if the table renamed it out from under the carve-out. */
|
|
81
|
-
function vectorNamed(name: string): ComboSelectionVector {
|
|
82
|
-
const vector = COMBO_SELECTION_VECTORS.find((v) => v.name === name);
|
|
83
|
-
if (!vector) throw new Error(`COMBO_SELECTION_VECTORS has no row "${name}" — this spec's carve-out is stale`);
|
|
84
|
-
return vector;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
99
|
/** Mount a drop-down and record every `change` detail it dispatches. */
|
|
88
100
|
function mountRecording(): { dd: GtkDropDown; changes: unknown[] } {
|
|
89
101
|
const dd = makeDropDown();
|
|
@@ -95,8 +107,6 @@ function mountRecording(): { dd: GtkDropDown; changes: unknown[] } {
|
|
|
95
107
|
export const GtkDropDownTest = async () => {
|
|
96
108
|
await describe('gtk-drop-down selection (libadwaita conformance vectors)', async () => {
|
|
97
109
|
for (const vector of COMBO_SELECTION_VECTORS) {
|
|
98
|
-
if (vector.name === DROP_DOWN_REJECTS) continue;
|
|
99
|
-
|
|
100
110
|
await it(`${vector.name} — ${vector.rule}`, async () => {
|
|
101
111
|
const { dd, changes } = mountRecording();
|
|
102
112
|
for (const step of vector.steps) applyStep(dd, step);
|
|
@@ -115,43 +125,24 @@ export const GtkDropDownTest = async () => {
|
|
|
115
125
|
dd.remove();
|
|
116
126
|
});
|
|
117
127
|
}
|
|
118
|
-
|
|
119
|
-
await it(`${DROP_DOWN_REJECTS} — rejected here: the element's published contract, not the state's`, async () => {
|
|
120
|
-
const vector = vectorNamed(DROP_DOWN_REJECTS);
|
|
121
|
-
const { dd, changes } = mountRecording();
|
|
122
|
-
|
|
123
|
-
for (const step of vector.steps.slice(0, -1)) applyStep(dd, step);
|
|
124
|
-
const before = { selected: dd.selected, value: dd.selectedValue, label: labelText(dd) };
|
|
125
|
-
// The out-of-range set itself, which the core state would accept and report
|
|
126
|
-
// as nothing-to-draw (`value`/`label` both empty below).
|
|
127
|
-
expect(vector.value).toBe('');
|
|
128
|
-
expect(vector.label).toBe('');
|
|
129
|
-
applyStep(dd, vector.steps[vector.steps.length - 1]);
|
|
130
|
-
|
|
131
|
-
// The element refused it: the selection did not move, and a refusal
|
|
132
|
-
// is not a change, so nothing was dispatched either.
|
|
133
|
-
expect({ selected: dd.selected, value: dd.selectedValue, label: labelText(dd) }).toStrictEqual(before);
|
|
134
|
-
expect(changes).toStrictEqual([]);
|
|
135
|
-
dd.remove();
|
|
136
|
-
});
|
|
137
128
|
});
|
|
138
129
|
|
|
139
130
|
await describe('gtk-drop-down model', async () => {
|
|
140
131
|
await it('accepts a string[] (value === label)', async () => {
|
|
141
132
|
const dd = makeDropDown();
|
|
142
|
-
dd
|
|
143
|
-
expect(dd.
|
|
144
|
-
expect(dd.
|
|
133
|
+
setModel(dd, ['One', 'Two', 'Three']);
|
|
134
|
+
expect(dd.options.length).toBe(3);
|
|
135
|
+
expect(dd.options[0]).toStrictEqual({ value: 'One', label: 'One' });
|
|
145
136
|
expect(dd.querySelector('.adw-drop-down-label')?.textContent).toBe('One');
|
|
146
137
|
dd.remove();
|
|
147
138
|
});
|
|
148
139
|
|
|
149
140
|
await it('accepts {value,label}[] and shows the selected label', async () => {
|
|
150
141
|
const dd = makeDropDown();
|
|
151
|
-
dd
|
|
142
|
+
setModel(dd, [
|
|
152
143
|
{ value: 'a', label: 'Apple' },
|
|
153
144
|
{ value: 'b', label: 'Banana' },
|
|
154
|
-
];
|
|
145
|
+
]);
|
|
155
146
|
dd.selected = 1;
|
|
156
147
|
expect(dd.querySelector('.adw-drop-down-label')?.textContent).toBe('Banana');
|
|
157
148
|
expect(dd.selectedValue).toBe('b');
|
|
@@ -163,7 +154,7 @@ export const GtkDropDownTest = async () => {
|
|
|
163
154
|
dd.setAttribute('model', '[{"value":"x","label":"Ex"},{"value":"y","label":"Why"}]');
|
|
164
155
|
dd.setAttribute('selected', '1');
|
|
165
156
|
document.body.appendChild(dd);
|
|
166
|
-
expect(dd.
|
|
157
|
+
expect(dd.options.length).toBe(2);
|
|
167
158
|
expect(dd.selected).toBe(1);
|
|
168
159
|
expect(dd.selectedValue).toBe('y');
|
|
169
160
|
dd.remove();
|
|
@@ -171,7 +162,7 @@ export const GtkDropDownTest = async () => {
|
|
|
171
162
|
|
|
172
163
|
await it('renders one popover item per option', async () => {
|
|
173
164
|
const dd = makeDropDown();
|
|
174
|
-
dd
|
|
165
|
+
setModel(dd, ['a', 'b', 'c']);
|
|
175
166
|
expect(dd.querySelectorAll('.adw-drop-down-item').length).toBe(3);
|
|
176
167
|
dd.remove();
|
|
177
168
|
});
|
|
@@ -179,8 +170,10 @@ export const GtkDropDownTest = async () => {
|
|
|
179
170
|
for (const vector of LIST_NORMALIZE_VECTORS) {
|
|
180
171
|
await it(`normalize — ${vector.rule}`, async () => {
|
|
181
172
|
const dd = makeDropDown();
|
|
182
|
-
|
|
183
|
-
|
|
173
|
+
// `listModelForInput` is the table's own answer to which door a row reaches
|
|
174
|
+
// through now that `model` takes no array (ADR 0122 § 4).
|
|
175
|
+
dd.model = listModelForInput(vector.input);
|
|
176
|
+
expect(dd.options).toStrictEqual([...vector.model]);
|
|
184
177
|
expect(
|
|
185
178
|
[...dd.querySelectorAll('.adw-drop-down-item-label')].map((label) => label.textContent),
|
|
186
179
|
).toStrictEqual(vector.model.map((item) => item.label));
|
|
@@ -198,21 +191,26 @@ export const GtkDropDownTest = async () => {
|
|
|
198
191
|
// Set AFTER connect, so the attribute reaches the callback rather than the
|
|
199
192
|
// seeding path: a total parser has to be total on the live door too.
|
|
200
193
|
dd.setAttribute('model', vector.attribute);
|
|
201
|
-
expect(dd.
|
|
194
|
+
expect(dd.options).toStrictEqual([...vector.model]);
|
|
202
195
|
dd.remove();
|
|
203
196
|
});
|
|
204
197
|
}
|
|
205
198
|
|
|
206
|
-
// The half no pure test reaches: a
|
|
199
|
+
// The half no pure test reaches: a markup update must SPLICE the row buttons, not
|
|
207
200
|
// rebuild them. Identity is what says which happened — and it is what a user feels,
|
|
208
201
|
// because a rebuilt row loses its focus and the popover its scroll position.
|
|
202
|
+
//
|
|
203
|
+
// Driven through the ATTRIBUTE, which is the door that still computes a splice: it
|
|
204
|
+
// reconciles the element's own authored list (ADR 0122 amendment A4) and so keeps its
|
|
205
|
+
// identity. A `model` PROPERTY write cannot answer these rows any more — a different
|
|
206
|
+
// list is a replacement, and a replacement carries nothing over by definition.
|
|
209
207
|
for (const vector of LIST_ITEMS_CHANGED_VECTORS) {
|
|
210
208
|
await it(`items-changed — ${vector.rule}`, async () => {
|
|
211
209
|
const dd = makeDropDown();
|
|
212
|
-
dd.model
|
|
210
|
+
dd.setAttribute('model', JSON.stringify(vector.previous));
|
|
213
211
|
const before = [...dd.querySelectorAll('.adw-drop-down-item')];
|
|
214
212
|
|
|
215
|
-
dd.model
|
|
213
|
+
dd.setAttribute('model', JSON.stringify(vector.next));
|
|
216
214
|
|
|
217
215
|
const after = [...dd.querySelectorAll('.adw-drop-down-item')];
|
|
218
216
|
expect(after.map((item) => item.querySelector('.adw-drop-down-item-label')?.textContent)).toStrictEqual(
|
|
@@ -223,19 +221,23 @@ export const GtkDropDownTest = async () => {
|
|
|
223
221
|
});
|
|
224
222
|
}
|
|
225
223
|
|
|
226
|
-
// WHO OWNS the
|
|
227
|
-
// the reason `adw-row-state.spec.ts` gives
|
|
224
|
+
// WHO OWNS the options either side of the model, and what the model's own API moves
|
|
225
|
+
// — the row buttons are what shows it, for the reason `adw-row-state.spec.ts` gives
|
|
226
|
+
// on the same table.
|
|
228
227
|
for (const vector of LIST_MODEL_OWNERSHIP_VECTORS) {
|
|
229
228
|
await it(`ownership — ${vector.rule}`, async () => {
|
|
230
229
|
const dd = makeDropDown();
|
|
231
230
|
const input = vector.initial.map((item) => ({ ...item }));
|
|
232
|
-
|
|
231
|
+
const list = setModel(dd, input);
|
|
233
232
|
const before = [...dd.querySelectorAll('.adw-drop-down-item')];
|
|
234
233
|
|
|
235
|
-
|
|
236
|
-
|
|
234
|
+
if (vector.source === 'model') applyListMutation(list, vector.op);
|
|
235
|
+
else applyListReadback(vector.source === 'input' ? input : dd.options, vector.op);
|
|
237
236
|
|
|
238
|
-
expect(dd.
|
|
237
|
+
expect(dd.options).toStrictEqual([...vector.model]);
|
|
238
|
+
// None of these ops is a replacement, so the element must still be pointing
|
|
239
|
+
// at the list it was handed.
|
|
240
|
+
expect(dd.model).toBe(list);
|
|
239
241
|
const after = [...dd.querySelectorAll('.adw-drop-down-item')];
|
|
240
242
|
expect(after.map((item) => item.querySelector('.adw-drop-down-item-label')?.textContent)).toStrictEqual(
|
|
241
243
|
vector.model.map((item) => item.label),
|
|
@@ -250,9 +252,10 @@ export const GtkDropDownTest = async () => {
|
|
|
250
252
|
// not, so the handler asks the list where the row is now.
|
|
251
253
|
await it('a row that a splice shifted still selects itself', async () => {
|
|
252
254
|
const dd = makeDropDown();
|
|
253
|
-
|
|
255
|
+
// Through the attribute door, the one that splices — see the items-changed loop.
|
|
256
|
+
dd.setAttribute('model', '["b","c"]');
|
|
254
257
|
const rowForB = dd.querySelectorAll('.adw-drop-down-item')[0] as HTMLButtonElement;
|
|
255
|
-
dd.model
|
|
258
|
+
dd.setAttribute('model', '["a","b","c"]');
|
|
256
259
|
expect(dd.querySelectorAll('.adw-drop-down-item')[1]).toBe(rowForB);
|
|
257
260
|
|
|
258
261
|
(dd.querySelector('.adw-drop-down-button') as HTMLButtonElement).click();
|
|
@@ -265,11 +268,11 @@ export const GtkDropDownTest = async () => {
|
|
|
265
268
|
await describe('gtk-drop-down selected ↔ value sync', async () => {
|
|
266
269
|
await it('selectedValue setter finds the index by value', async () => {
|
|
267
270
|
const dd = makeDropDown();
|
|
268
|
-
dd
|
|
271
|
+
setModel(dd, [
|
|
269
272
|
{ value: 'r', label: 'Red' },
|
|
270
273
|
{ value: 'g', label: 'Green' },
|
|
271
274
|
{ value: 'b', label: 'Blue' },
|
|
272
|
-
];
|
|
275
|
+
]);
|
|
273
276
|
dd.selectedValue = 'b';
|
|
274
277
|
expect(dd.selected).toBe(2);
|
|
275
278
|
expect(dd.querySelector('.adw-drop-down-label')?.textContent).toBe('Blue');
|
|
@@ -278,7 +281,7 @@ export const GtkDropDownTest = async () => {
|
|
|
278
281
|
|
|
279
282
|
await it('get_selected / set_selected are the GTK spelling of `selected`', async () => {
|
|
280
283
|
const dd = makeDropDown();
|
|
281
|
-
dd
|
|
284
|
+
setModel(dd, ['a', 'b', 'c']);
|
|
282
285
|
(dd as unknown as { set_selected(n: number): void }).set_selected(2);
|
|
283
286
|
expect(dd.selected).toBe(2);
|
|
284
287
|
expect((dd as unknown as { get_selected(): number }).get_selected()).toBe(2);
|
|
@@ -289,7 +292,7 @@ export const GtkDropDownTest = async () => {
|
|
|
289
292
|
|
|
290
293
|
await it('selected reflects to the attribute + marks the row', async () => {
|
|
291
294
|
const dd = makeDropDown();
|
|
292
|
-
dd
|
|
295
|
+
setModel(dd, ['a', 'b']);
|
|
293
296
|
dd.selected = 1;
|
|
294
297
|
expect(dd.getAttribute('selected')).toBe('1');
|
|
295
298
|
const items = dd.querySelectorAll('.adw-drop-down-item');
|
|
@@ -298,10 +301,23 @@ export const GtkDropDownTest = async () => {
|
|
|
298
301
|
dd.remove();
|
|
299
302
|
});
|
|
300
303
|
|
|
301
|
-
|
|
304
|
+
// `selected-item` is the MODEL'S OWN item, by identity (ADR 0122 § 4) — not a
|
|
305
|
+
// `{ value, label }` descriptor, which is what this read used to hand back. The
|
|
306
|
+
// identity is the point: it is what every `selected-item` consumer compares.
|
|
307
|
+
await it('selectedItem is the model’s own item, by identity', async () => {
|
|
308
|
+
const dd = makeDropDown();
|
|
309
|
+
const list = setModel(dd, [{ value: 'k', label: 'Key' }]);
|
|
310
|
+
expect(dd.selectedItem).toBe(list.get_item(0));
|
|
311
|
+
expect((dd as unknown as { get_selected_item(): unknown }).get_selected_item()).toBe(list.get_item(0));
|
|
312
|
+
dd.remove();
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
await it('selectedItem is null with no model and with no selection', async () => {
|
|
302
316
|
const dd = makeDropDown();
|
|
303
|
-
dd.model
|
|
304
|
-
expect(dd.selectedItem).
|
|
317
|
+
expect(dd.model).toBeNull();
|
|
318
|
+
expect(dd.selectedItem).toBeNull();
|
|
319
|
+
setModel(dd, []);
|
|
320
|
+
expect(dd.selectedItem).toBeNull();
|
|
305
321
|
dd.remove();
|
|
306
322
|
});
|
|
307
323
|
|
|
@@ -309,7 +325,7 @@ export const GtkDropDownTest = async () => {
|
|
|
309
325
|
// The property setters can run BEFORE connectedCallback builds the DOM, where
|
|
310
326
|
// _updateLabel would touch an undefined label element.
|
|
311
327
|
const dd = document.createElement('gtk-drop-down') as GtkDropDown;
|
|
312
|
-
dd
|
|
328
|
+
setModel(dd, ['a', 'b', 'c']);
|
|
313
329
|
dd.selected = 2;
|
|
314
330
|
expect(dd.isConnected).toBe(false);
|
|
315
331
|
document.body.appendChild(dd);
|
|
@@ -323,7 +339,7 @@ export const GtkDropDownTest = async () => {
|
|
|
323
339
|
await describe('gtk-drop-down notify-on-change', async () => {
|
|
324
340
|
await it('a programmatic set fires notify::selected but NOT change (DOM <select> semantics)', async () => {
|
|
325
341
|
const dd = makeDropDown();
|
|
326
|
-
dd
|
|
342
|
+
setModel(dd, ['a', 'b', 'c']);
|
|
327
343
|
let notifyCount = 0;
|
|
328
344
|
let changeCount = 0;
|
|
329
345
|
dd.addEventListener('notify::selected', () => notifyCount++);
|
|
@@ -346,7 +362,7 @@ export const GtkDropDownTest = async () => {
|
|
|
346
362
|
|
|
347
363
|
await it('a popover item click selects, fires change + closes', async () => {
|
|
348
364
|
const dd = makeDropDown();
|
|
349
|
-
dd
|
|
365
|
+
setModel(dd, ['a', 'b', 'c']);
|
|
350
366
|
let change: unknown = null;
|
|
351
367
|
dd.addEventListener('change', (e) => {
|
|
352
368
|
change = (e as CustomEvent).detail;
|
|
@@ -365,7 +381,7 @@ export const GtkDropDownTest = async () => {
|
|
|
365
381
|
await describe('gtk-drop-down popover behaviour', async () => {
|
|
366
382
|
await it('opens on button click and closes on outside pointerdown', async () => {
|
|
367
383
|
const dd = makeDropDown();
|
|
368
|
-
dd
|
|
384
|
+
setModel(dd, ['a', 'b']);
|
|
369
385
|
const button = dd.querySelector('.adw-drop-down-button') as HTMLButtonElement;
|
|
370
386
|
const popover = dd.querySelector('.adw-drop-down-popover') as HTMLElement;
|
|
371
387
|
expect(popover.hidden).toBe(true);
|
|
@@ -381,7 +397,7 @@ export const GtkDropDownTest = async () => {
|
|
|
381
397
|
|
|
382
398
|
await it('a disabled dropdown does not open', async () => {
|
|
383
399
|
const dd = makeDropDown();
|
|
384
|
-
dd
|
|
400
|
+
setModel(dd, ['a', 'b']);
|
|
385
401
|
dd.setAttribute('disabled', '');
|
|
386
402
|
(dd.querySelector('.adw-drop-down-button') as HTMLButtonElement).click();
|
|
387
403
|
expect(dd.active).toBe(false);
|
|
@@ -392,7 +408,7 @@ export const GtkDropDownTest = async () => {
|
|
|
392
408
|
await describe('gtk-drop-down search', async () => {
|
|
393
409
|
await it('renders a search entry and filters the list', async () => {
|
|
394
410
|
const dd = makeDropDown();
|
|
395
|
-
dd
|
|
411
|
+
setModel(dd, ['Apple', 'Banana', 'Cherry']);
|
|
396
412
|
dd.enableSearch = true;
|
|
397
413
|
const search = dd.querySelector('.adw-drop-down-search') as HTMLInputElement;
|
|
398
414
|
expect(search).toBeTruthy();
|