@gjsify/adwaita-web 0.19.0 → 0.21.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.
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const AdwButtonRowTest: () => Promise<void>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/adwaita-web",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"description": "Adwaita/Libadwaita web components for browser targets",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -41,13 +41,13 @@
|
|
|
41
41
|
"@codemirror/language": "^6.12.4",
|
|
42
42
|
"@codemirror/state": "^6.7.0",
|
|
43
43
|
"@codemirror/view": "^6.43.4",
|
|
44
|
-
"@gjsify/adwaita-fonts": "^0.
|
|
45
|
-
"@gjsify/adwaita-icons": "^0.
|
|
44
|
+
"@gjsify/adwaita-fonts": "^0.21.0",
|
|
45
|
+
"@gjsify/adwaita-icons": "^0.21.0",
|
|
46
46
|
"@lezer/highlight": "^1.2.3"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@gjsify/cli": "^0.
|
|
50
|
-
"@gjsify/unit": "^0.
|
|
49
|
+
"@gjsify/cli": "^0.21.0",
|
|
50
|
+
"@gjsify/unit": "^0.21.0",
|
|
51
51
|
"sass": "^1.101.0",
|
|
52
52
|
"typescript": "^6.0.3"
|
|
53
53
|
},
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// DOM-level behaviour tests for <adw-button-row>. Runs in a real browser via the
|
|
2
|
+
// @gjsify/adwaita-web browser test axis. The regression this guards: a
|
|
3
|
+
// declaratively-parsed row (attributes already present when connectedCallback
|
|
4
|
+
// runs) must not crash. Setting the default `activatable` attribute inside
|
|
5
|
+
// connectedCallback re-enters attributeChangedCallback → _render(); if that runs
|
|
6
|
+
// before the title/icon elements are built, it threw
|
|
7
|
+
// "Cannot set properties of undefined (setting 'textContent')".
|
|
8
|
+
import { describe, expect, it } from '@gjsify/unit';
|
|
9
|
+
|
|
10
|
+
import type { AdwButtonRow } from './elements/adw-button-row.js';
|
|
11
|
+
|
|
12
|
+
/** Parse a row from HTML so its attributes are present at connectedCallback. */
|
|
13
|
+
function parseRow(html: string): { row: AdwButtonRow; host: HTMLElement } {
|
|
14
|
+
const host = document.createElement('div');
|
|
15
|
+
document.body.appendChild(host);
|
|
16
|
+
host.innerHTML = html;
|
|
17
|
+
return { row: host.querySelector('adw-button-row') as AdwButtonRow, host };
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const AdwButtonRowTest = async () => {
|
|
21
|
+
await describe('adw-button-row', async () => {
|
|
22
|
+
await it('parses a declarative row with a start icon without throwing', async () => {
|
|
23
|
+
const errors: string[] = [];
|
|
24
|
+
const onError = (event: ErrorEvent) => errors.push(event.message);
|
|
25
|
+
window.addEventListener('error', onError);
|
|
26
|
+
|
|
27
|
+
// No `activatable` attribute → connectedCallback sets the default,
|
|
28
|
+
// which used to re-enter _render() before the elements existed.
|
|
29
|
+
const { row, host } = parseRow(
|
|
30
|
+
'<adw-button-row title="Add account" start-icon-name="list-add" class="suggested-action"></adw-button-row>',
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
// Let any reported reaction error surface on the window.
|
|
34
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
35
|
+
window.removeEventListener('error', onError);
|
|
36
|
+
|
|
37
|
+
expect(errors.length).toBe(0);
|
|
38
|
+
expect(row.textContent).toContain('Add account');
|
|
39
|
+
// The start icon span carries the adw-icon class derived from the name.
|
|
40
|
+
expect(row.querySelector('.adw-icon--list-add') !== null).toBe(true);
|
|
41
|
+
// Activatable by default.
|
|
42
|
+
expect(row.classList.contains('activatable')).toBe(true);
|
|
43
|
+
host.remove();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
await it('honours activatable="false"', async () => {
|
|
47
|
+
const { row, host } = parseRow('<adw-button-row title="Locked" activatable="false"></adw-button-row>');
|
|
48
|
+
expect(row.classList.contains('activatable')).toBe(false);
|
|
49
|
+
host.remove();
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
await it('emits `activated` on click when activatable', async () => {
|
|
53
|
+
const { row, host } = parseRow('<adw-button-row title="Add account"></adw-button-row>');
|
|
54
|
+
let activated = false;
|
|
55
|
+
row.addEventListener('activated', () => {
|
|
56
|
+
activated = true;
|
|
57
|
+
});
|
|
58
|
+
row.click();
|
|
59
|
+
expect(activated).toBe(true);
|
|
60
|
+
host.remove();
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
};
|
|
@@ -23,13 +23,6 @@ export class AdwButtonRow extends HTMLElement {
|
|
|
23
23
|
|
|
24
24
|
connectedCallback() {
|
|
25
25
|
if (this._initialized) return;
|
|
26
|
-
this._initialized = true;
|
|
27
|
-
|
|
28
|
-
// Adw.ButtonRow is activatable by default; only an explicit
|
|
29
|
-
// activatable="false" turns it off.
|
|
30
|
-
if (!this.hasAttribute('activatable')) {
|
|
31
|
-
this.setAttribute('activatable', '');
|
|
32
|
-
}
|
|
33
26
|
|
|
34
27
|
this._contentsEl = document.createElement('div');
|
|
35
28
|
this._contentsEl.className = 'adw-button-row-contents';
|
|
@@ -42,6 +35,19 @@ export class AdwButtonRow extends HTMLElement {
|
|
|
42
35
|
|
|
43
36
|
this._contentsEl.append(this._startIconEl, this._titleEl);
|
|
44
37
|
this.replaceChildren(this._contentsEl);
|
|
38
|
+
|
|
39
|
+
// Adw.ButtonRow is activatable by default; only an explicit
|
|
40
|
+
// activatable="false" turns it off. Set this while still uninitialized
|
|
41
|
+
// so the re-entrant attributeChangedCallback is a no-op — the explicit
|
|
42
|
+
// _render() below does the first render, once the elements above exist.
|
|
43
|
+
// (Setting _initialized before the elements were built made this
|
|
44
|
+
// setAttribute re-enter _render() and crash on a declaratively-parsed
|
|
45
|
+
// row, where connectedCallback runs with attributes already present.)
|
|
46
|
+
if (!this.hasAttribute('activatable')) {
|
|
47
|
+
this.setAttribute('activatable', '');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
this._initialized = true;
|
|
45
51
|
this._render();
|
|
46
52
|
|
|
47
53
|
this.addEventListener('click', () => {
|
package/src/test.browser.mts
CHANGED
|
@@ -7,9 +7,10 @@ import { run } from '@gjsify/unit';
|
|
|
7
7
|
// Registers the custom elements (side-effect) + injects the compiled CSS.
|
|
8
8
|
import '@gjsify/adwaita-web';
|
|
9
9
|
|
|
10
|
+
import { AdwButtonRowTest } from './adw-button-row.spec.js';
|
|
10
11
|
import { AdwDataGridTest } from './adw-data-grid.spec.js';
|
|
11
12
|
import { AdwDialogTest } from './adw-dialog.spec.js';
|
|
12
13
|
import { AdwDropDownTest } from './adw-drop-down.spec.js';
|
|
13
14
|
import { AdwTabViewTest } from './adw-tab-view.spec.js';
|
|
14
15
|
|
|
15
|
-
run({ AdwDataGridTest, AdwDialogTest, AdwDropDownTest, AdwTabViewTest });
|
|
16
|
+
run({ AdwButtonRowTest, AdwDataGridTest, AdwDialogTest, AdwDropDownTest, AdwTabViewTest });
|