@gjsify/adwaita-web 0.51.0 → 0.52.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 +255 -27
- package/dist/adwaita-web.css.map +1 -1
- package/lib/types/blueprint-layout.spec.d.ts +1 -0
- package/lib/types/blueprint-markup.spec.d.ts +4 -0
- package/lib/types/blueprint-tree.spec.d.ts +1 -0
- package/lib/types/elements/adw-bottom-sheet.d.ts +31 -13
- package/lib/types/elements/adw-carousel.d.ts +5 -0
- package/lib/types/elements/adw-header-bar.d.ts +15 -0
- package/lib/types/elements/adw-inline-view-switcher.d.ts +1 -0
- package/lib/types/elements/adw-navigation-view.d.ts +1 -0
- package/lib/types/elements/adw-sidebar.d.ts +10 -0
- package/lib/types/elements/adw-tab-view.d.ts +1 -0
- package/lib/types/elements/adw-toggle-group.d.ts +11 -0
- package/lib/types/elements/gtk-action-bar.d.ts +19 -0
- package/lib/types/elements/gtk-box.d.ts +17 -0
- package/lib/types/elements/gtk-button.d.ts +2 -0
- package/lib/types/elements/gtk-label.d.ts +122 -0
- package/lib/types/gio-menu.spec.d.ts +1 -0
- package/lib/types/gtk-box.spec.d.ts +1 -0
- package/lib/types/gtk-label.spec.d.ts +1 -0
- package/lib/types/gtk-value-doors.spec.d.ts +1 -0
- package/lib/types/index.d.ts +4 -1
- package/lib/types/namespace/gio.d.ts +1 -0
- package/lib/types/namespace/gtk.d.ts +5 -0
- package/lib/types/shared-tree-builder.d.ts +64 -0
- package/lib/types/source-view/asm6502.d.ts +1 -20
- package/lib/types/source-view/index.d.ts +3 -2
- package/lib/types/source-view/theme.d.ts +1 -1
- package/lib/types/string-list-slot.d.ts +4 -0
- package/lib/types/styles.generated.d.ts +1 -1
- package/lib/types/tags.spec.d.ts +1 -0
- package/lib/types/value-lists.spec.d.ts +1 -0
- package/package.json +8 -6
- package/scss/_action_bar.scss +51 -0
- package/scss/_banner.scss +8 -1
- package/scss/_bottom_sheet.scss +57 -0
- package/scss/_box.scss +23 -0
- package/scss/_button.scss +29 -7
- package/scss/_button_content.scss +6 -1
- package/scss/_button_row.scss +5 -2
- package/scss/_carousel.scss +6 -0
- package/scss/_labels.scss +126 -12
- package/scss/_navigation_split_view.scss +18 -0
- package/scss/_overlay_split_view.scss +5 -0
- package/scss/_reset.scss +29 -4
- package/scss/_split_button.scss +5 -2
- package/scss/_status_page.scss +31 -17
- package/scss/_theme.scss +11 -3
- package/scss/_toolbar_view.scss +10 -0
- package/scss/_variables.scss +1 -0
- package/scss/_widget.scss +55 -0
- package/scss/_window_title.scss +9 -0
- package/scss/adwaita-skin.scss +8 -2
- package/src/adw-banner.spec.ts +16 -0
- package/src/adw-button-row.spec.ts +8 -0
- package/src/adw-header-bar.spec.ts +17 -0
- package/src/blueprint-layout.spec.ts +223 -0
- package/src/blueprint-markup.spec.ts +155 -0
- package/src/blueprint-tree.spec.ts +174 -0
- package/src/bottom-sheet.spec.ts +166 -1
- package/src/chrome.spec.ts +5 -2
- package/src/elements/adw-bottom-sheet.ts +166 -59
- package/src/elements/adw-carousel.ts +10 -5
- package/src/elements/adw-clamp.ts +12 -0
- package/src/elements/adw-combo-row.ts +13 -4
- package/src/elements/adw-header-bar.ts +46 -3
- package/src/elements/adw-inline-view-switcher.ts +11 -0
- package/src/elements/adw-navigation-view.ts +10 -0
- package/src/elements/adw-sidebar.ts +22 -0
- package/src/elements/adw-spin-row.ts +44 -5
- package/src/elements/adw-status-page.ts +12 -6
- package/src/elements/adw-tab-view.ts +20 -3
- package/src/elements/adw-toggle-group.ts +45 -4
- package/src/elements/adw-toolbar-view.ts +9 -0
- package/src/elements/gtk-action-bar.ts +90 -0
- package/src/elements/gtk-box.ts +87 -0
- package/src/elements/gtk-button.ts +60 -13
- package/src/elements/gtk-drop-down.ts +10 -1
- package/src/elements/gtk-label.ts +415 -0
- package/src/gio-menu.spec.ts +125 -0
- package/src/globals.d.ts +7 -0
- package/src/gtk-box.spec.ts +168 -0
- package/src/gtk-button.spec.ts +123 -1
- package/src/gtk-label.spec.ts +595 -0
- package/src/gtk-value-doors.spec.ts +104 -0
- package/src/index.ts +14 -1
- package/src/keyboard-operable.spec.ts +2 -1
- package/src/namespace/gio.ts +19 -0
- package/src/namespace/gtk.ts +14 -0
- package/src/shared-tree-builder.ts +268 -0
- package/src/shared-trees.spec.ts +296 -32
- package/src/source-view/adw-source-view.ts +3 -3
- package/src/source-view/asm6502.ts +11 -191
- package/src/source-view/index.ts +17 -11
- package/src/source-view/theme.ts +16 -16
- package/src/split-button.spec.ts +7 -0
- package/src/string-list-slot.ts +21 -0
- package/src/styles.generated.ts +1 -1
- package/src/tags.spec.ts +51 -0
- package/src/test.browser.mts +18 -0
- package/src/value-lists.spec.ts +93 -0
- package/lib/types/source-view/hex.d.ts +0 -21
- package/src/source-view/hex.ts +0 -37
package/src/tags.spec.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// `hostTagOf`/`attributeOf` (`@gjsify/adwaita-core/tags`) against `HOST_TAG_VECTORS`/
|
|
2
|
+
// `ATTRIBUTE_OF_VECTORS` (`@gjsify/adwaita-core/conformance`) — a real `document.createElement`
|
|
3
|
+
// and a real `Element#getAttribute`, not the function compared to itself.
|
|
4
|
+
//
|
|
5
|
+
// `shared-trees.spec.ts` in this same directory calls both functions too, but only to BUILD
|
|
6
|
+
// the tree it renders; it checks the result against `hostTagOf`/`attributeOf` called a
|
|
7
|
+
// second time on the same input, which is the same function agreeing with itself, not a
|
|
8
|
+
// vector. This suite is the one that holds a call to a value nobody derived from calling it.
|
|
9
|
+
import { describe, expect, it } from '@gjsify/unit';
|
|
10
|
+
|
|
11
|
+
import { ATTRIBUTE_OF_VECTORS, HOST_TAG_VECTORS } from '@gjsify/adwaita-core/conformance';
|
|
12
|
+
import { attributeOf, hostTagOf } from '@gjsify/adwaita-core/tags';
|
|
13
|
+
|
|
14
|
+
export const AdwTagsTest = async () => {
|
|
15
|
+
await describe('hostTagOf (conformance vectors)', async () => {
|
|
16
|
+
for (const vector of HOST_TAG_VECTORS) {
|
|
17
|
+
await it(`${vector.gtype || '(empty)'} — ${vector.rule}`, () => {
|
|
18
|
+
if (vector.error !== undefined) {
|
|
19
|
+
let caught: unknown;
|
|
20
|
+
try {
|
|
21
|
+
hostTagOf(vector.gtype);
|
|
22
|
+
} catch (error) {
|
|
23
|
+
caught = error;
|
|
24
|
+
}
|
|
25
|
+
expect(caught instanceof Error ? caught.message : undefined).toBe(vector.error);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const tag = hostTagOf(vector.gtype);
|
|
29
|
+
expect(tag).toBe(vector.expected);
|
|
30
|
+
// A REAL element, not just a string comparison: the browser accepts the
|
|
31
|
+
// produced tag as a custom-element-shaped name and hands one back under it.
|
|
32
|
+
expect(document.createElement(tag).tagName.toLowerCase()).toBe(vector.expected);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
await describe('attributeOf (conformance vectors)', async () => {
|
|
38
|
+
for (const vector of ATTRIBUTE_OF_VECTORS) {
|
|
39
|
+
await it(`${vector.prop || '(empty)'} — ${vector.rule}`, () => {
|
|
40
|
+
expect(attributeOf(vector.prop)).toBe(vector.expected);
|
|
41
|
+
// The empty attribute name is not settable at all (`InvalidCharacterError`),
|
|
42
|
+
// so that row's DOM half stops at the string check above, like the other
|
|
43
|
+
// conformance drivers do for a row their surface cannot reach.
|
|
44
|
+
if (vector.expected === '') return;
|
|
45
|
+
const el = document.createElement('div');
|
|
46
|
+
el.setAttribute(attributeOf(vector.prop), 'x');
|
|
47
|
+
expect(el.getAttribute(vector.expected)).toBe('x');
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
};
|
package/src/test.browser.mts
CHANGED
|
@@ -36,6 +36,8 @@ import { AdwWrapBoxTest } from './adw-wrap-box.spec.js';
|
|
|
36
36
|
import { AdwHeaderBarTest } from './adw-header-bar.spec.js';
|
|
37
37
|
import { GtkEntryTest } from './gtk-entry.spec.js';
|
|
38
38
|
import { GtkMenuButtonTest } from './gtk-menu-button.spec.js';
|
|
39
|
+
import { GioMenuTest } from './gio-menu.spec.js';
|
|
40
|
+
import { GtkValueDoorsTest } from './gtk-value-doors.spec.js';
|
|
39
41
|
import { GtkButtonTest } from './gtk-button.spec.js';
|
|
40
42
|
import { AdwBannerTest } from './adw-banner.spec.js';
|
|
41
43
|
import { AdwButtonContentTest } from './adw-button-content.spec.js';
|
|
@@ -44,6 +46,8 @@ import { AdwIconRegistryTest } from './icon-registry.spec.js';
|
|
|
44
46
|
import { GtkSwitchTest } from './gtk-switch.spec.js';
|
|
45
47
|
import { AdwChecksTest } from './checks.spec.js';
|
|
46
48
|
import { GtkProgressBarTest } from './gtk-progress-bar.spec.js';
|
|
49
|
+
import { GtkBoxTest } from './gtk-box.spec.js';
|
|
50
|
+
import { GtkLabelTest } from './gtk-label.spec.js';
|
|
47
51
|
import { AdwAboutDialogTest } from './adw-about-dialog.spec.js';
|
|
48
52
|
import { AdwStyleClassesTest } from './style-classes.spec.js';
|
|
49
53
|
import { AdwAccentTest } from './adw-accent.spec.js';
|
|
@@ -54,9 +58,19 @@ import { AdwSlottedChildrenTest } from './slotted-children.spec.js';
|
|
|
54
58
|
import { AdwKeyboardOperableTest } from './keyboard-operable.spec.js';
|
|
55
59
|
import { AdwFontsTest } from './adw-fonts.spec.js';
|
|
56
60
|
import { AdwSharedTreesTest } from './shared-trees.spec.js';
|
|
61
|
+
import { AdwBlueprintTreeTest } from './blueprint-tree.spec.js';
|
|
62
|
+
import { AdwValueListsTest } from './value-lists.spec.js';
|
|
63
|
+
import { AdwBlueprintLayoutTest } from './blueprint-layout.spec.js';
|
|
64
|
+
import { AdwBlueprintMarkupTest } from './blueprint-markup.spec.js';
|
|
65
|
+
import { AdwTagsTest } from './tags.spec.js';
|
|
57
66
|
|
|
58
67
|
run({
|
|
59
68
|
AdwSharedTreesTest,
|
|
69
|
+
AdwBlueprintTreeTest,
|
|
70
|
+
AdwValueListsTest,
|
|
71
|
+
AdwBlueprintLayoutTest,
|
|
72
|
+
AdwBlueprintMarkupTest,
|
|
73
|
+
AdwTagsTest,
|
|
60
74
|
AdwKeyboardOperableTest,
|
|
61
75
|
AdwConnectLifecycleTest,
|
|
62
76
|
AdwEmptySectionsTest,
|
|
@@ -73,6 +87,8 @@ run({
|
|
|
73
87
|
GtkSwitchTest,
|
|
74
88
|
AdwChecksTest,
|
|
75
89
|
GtkProgressBarTest,
|
|
90
|
+
GtkBoxTest,
|
|
91
|
+
GtkLabelTest,
|
|
76
92
|
AdwAvatarTest,
|
|
77
93
|
AdwCarouselTest,
|
|
78
94
|
AdwBottomSheetTest,
|
|
@@ -97,6 +113,8 @@ run({
|
|
|
97
113
|
AdwHeaderBarTest,
|
|
98
114
|
GtkEntryTest,
|
|
99
115
|
GtkMenuButtonTest,
|
|
116
|
+
GioMenuTest,
|
|
117
|
+
GtkValueDoorsTest,
|
|
100
118
|
GtkButtonTest,
|
|
101
119
|
AdwViewStackTest,
|
|
102
120
|
AdwNavigationViewTest,
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// A `.blp`'s string lists and dialog responses, built by this renderer — ADR 0072.
|
|
2
|
+
//
|
|
3
|
+
// Each `VALUE_LIST_VECTORS` row is a Blueprint source and what GTK builds from it, measured
|
|
4
|
+
// with `Gtk.Builder`. The source goes through the real parser and projection, refused on any
|
|
5
|
+
// loss as the `?shared-tree` door refuses it, then through `mountSharedTree`, and the widget
|
|
6
|
+
// is read back: the options a combo row or drop-down paints, the buttons a dialog registered.
|
|
7
|
+
// Before ADR 0072 the projection dropped both lists, so the same sources rendered an EMPTY
|
|
8
|
+
// combo row and a dialog with no buttons, at exit 0.
|
|
9
|
+
//
|
|
10
|
+
// The NativeScript driver (`packages/nativescript-bridge/adwaita/src/value-lists.spec.ts`)
|
|
11
|
+
// drives the same rows through its own builder.
|
|
12
|
+
|
|
13
|
+
import { describe, expect, it } from '@gjsify/unit';
|
|
14
|
+
|
|
15
|
+
import { parseBlueprint, projectToSharedNode } from '@gjsify/blueprint';
|
|
16
|
+
import { VALUE_LIST_VECTORS } from '@gjsify/adwaita-core/conformance';
|
|
17
|
+
import type { SharedTreeNode } from '@gjsify/adwaita-core/conformance';
|
|
18
|
+
|
|
19
|
+
import type { AdwAlertDialog } from './elements/adw-alert-dialog.js';
|
|
20
|
+
import type { AdwComboRow } from './elements/adw-combo-row.js';
|
|
21
|
+
import { mountSharedTree } from './shared-tree-builder.js';
|
|
22
|
+
|
|
23
|
+
/** A Blueprint object as the `?shared-tree` door hands it over, refused on any loss. */
|
|
24
|
+
function blueprintTree(body: string): SharedTreeNode {
|
|
25
|
+
const { node, lost } = projectToSharedNode(
|
|
26
|
+
parseBlueprint(`using Gtk 4.0;\nusing Adw 1;\n\n${body}\n`, 'value-lists.spec.blp'),
|
|
27
|
+
);
|
|
28
|
+
if (lost.length > 0) {
|
|
29
|
+
throw new Error(`the projection dropped ${lost.map((loss) => `${loss.kind} at line ${loss.line}`).join(', ')}`);
|
|
30
|
+
}
|
|
31
|
+
return node as SharedTreeNode;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** The option labels the widget paints, which is what a reader sees. */
|
|
35
|
+
const paintedOptions = (el: HTMLElement) =>
|
|
36
|
+
[...el.querySelectorAll('option, .adw-drop-down-item-label')].map((node) => node.textContent);
|
|
37
|
+
|
|
38
|
+
/** Mount, run, and unmount even when the body throws. */
|
|
39
|
+
function mounted(tree: SharedTreeNode, body: (root: HTMLElement) => void): void {
|
|
40
|
+
const { root, unmount } = mountSharedTree(tree);
|
|
41
|
+
try {
|
|
42
|
+
body(root);
|
|
43
|
+
} finally {
|
|
44
|
+
unmount();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export const AdwValueListsTest = async () => {
|
|
49
|
+
await describe('adwaita-web: VALUE_LIST_VECTORS through a .blp', async () => {
|
|
50
|
+
for (const vector of VALUE_LIST_VECTORS) {
|
|
51
|
+
await it(vector.rule, () => {
|
|
52
|
+
mounted(blueprintTree(vector.blueprint), (root) => {
|
|
53
|
+
if (vector.strings !== undefined) {
|
|
54
|
+
const model = (root as unknown as Pick<AdwComboRow, 'model'>).model;
|
|
55
|
+
expect(JSON.stringify(model.map((option) => option.label))).toBe(
|
|
56
|
+
JSON.stringify(vector.strings),
|
|
57
|
+
);
|
|
58
|
+
expect(JSON.stringify(paintedOptions(root))).toBe(JSON.stringify(vector.strings));
|
|
59
|
+
// Consumed as data, as GtkBuilder leaves no list model in the widget tree.
|
|
60
|
+
expect(root.querySelector('gtk-string-list')).toBe(null);
|
|
61
|
+
}
|
|
62
|
+
if (vector.responses !== undefined) {
|
|
63
|
+
const dialog = root as unknown as AdwAlertDialog;
|
|
64
|
+
const read = vector.responses.map(({ id }) => ({
|
|
65
|
+
id,
|
|
66
|
+
label: dialog.getResponseLabel(id),
|
|
67
|
+
appearance: dialog.getResponseAppearance(id),
|
|
68
|
+
enabled: dialog.getResponseEnabled(id),
|
|
69
|
+
}));
|
|
70
|
+
expect(JSON.stringify(read)).toBe(JSON.stringify(vector.responses));
|
|
71
|
+
// The buttons the dialog paints, in the order the source wrote them.
|
|
72
|
+
const painted = [...root.querySelectorAll('.adw-alert-dialog-response')].map(
|
|
73
|
+
(button) => button.textContent,
|
|
74
|
+
);
|
|
75
|
+
expect(JSON.stringify(painted)).toBe(JSON.stringify(vector.responses.map((r) => r.label)));
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
await describe('adwaita-web: an extension no element takes is refused', async () => {
|
|
83
|
+
await it('a string list at a slot the parent has no destination for', () => {
|
|
84
|
+
const tree = blueprintTree('Gtk.Box { Gtk.StringList { strings [ "a" ] } }');
|
|
85
|
+
expect(() => mountSharedTree(tree)).toThrow();
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
await it('responses on an element that is not a dialog', () => {
|
|
89
|
+
const tree: SharedTreeNode = { tag: 'GtkBox', extensions: { responses: [{ id: 'ok', label: 'OK' }] } };
|
|
90
|
+
expect(() => mountSharedTree(tree)).toThrow();
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
};
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/** Bytes represented per visual line in the hex monitor / hexdump gutter. */
|
|
2
|
-
export declare const HEX_ADDRESS_STRIDE = 16;
|
|
3
|
-
/**
|
|
4
|
-
* Format a 1-based CodeMirror line number as a 4-digit uppercase hex address, the way the
|
|
5
|
-
* native GtkSourceView hex gutter renders monitor/hexdump rows: each row advances the
|
|
6
|
-
* address by `stride` bytes from `start` (the base address of the first row, e.g. 0x0600
|
|
7
|
-
* for a 6502 program). `lineNo` is 1-based, per CodeMirror's `formatNumber` contract.
|
|
8
|
-
*/
|
|
9
|
-
export declare function formatHexAddress(lineNo: number, start: number, stride?: number): string;
|
|
10
|
-
/**
|
|
11
|
-
* Format a 1-based CodeMirror line number for the normal (decimal) gutter, offset so
|
|
12
|
-
* `start` is the value shown on the first line — the web twin of the native renderer's
|
|
13
|
-
* `line + startValue`.
|
|
14
|
-
*/
|
|
15
|
-
export declare function formatLineNumber(lineNo: number, start?: number): string;
|
|
16
|
-
/**
|
|
17
|
-
* Strip every whitespace character from `text` — the copy-without-spaces
|
|
18
|
-
* transform the native hex monitor applies so a copied address/byte run pastes
|
|
19
|
-
* as a compact hex string. Mirrors `text.replace(/\s/g, '')` in the GTK widget.
|
|
20
|
-
*/
|
|
21
|
-
export declare function stripWhitespace(text: string): string;
|
package/src/source-view/hex.ts
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
// Pure, framework-free helpers for <adw-source-view>. They carry no CodeMirror
|
|
2
|
-
// or DOM dependency so they stay unit-testable on any runtime and drive the
|
|
3
|
-
// gutter formatter + the hex copy-without-spaces behaviour.
|
|
4
|
-
// Reference: packages/app-gnome/src/gutter-renderer-line-numbers.ts (native parity)
|
|
5
|
-
// Reference: packages/app-gnome/src/widgets/source-view.ts onCopyHexClipboard()
|
|
6
|
-
|
|
7
|
-
/** Bytes represented per visual line in the hex monitor / hexdump gutter. */
|
|
8
|
-
export const HEX_ADDRESS_STRIDE = 16;
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Format a 1-based CodeMirror line number as a 4-digit uppercase hex address, the way the
|
|
12
|
-
* native GtkSourceView hex gutter renders monitor/hexdump rows: each row advances the
|
|
13
|
-
* address by `stride` bytes from `start` (the base address of the first row, e.g. 0x0600
|
|
14
|
-
* for a 6502 program). `lineNo` is 1-based, per CodeMirror's `formatNumber` contract.
|
|
15
|
-
*/
|
|
16
|
-
export function formatHexAddress(lineNo: number, start: number, stride: number = HEX_ADDRESS_STRIDE): string {
|
|
17
|
-
const address = start + (lineNo - 1) * stride;
|
|
18
|
-
return address.toString(16).padStart(4, '0').toUpperCase();
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Format a 1-based CodeMirror line number for the normal (decimal) gutter, offset so
|
|
23
|
-
* `start` is the value shown on the first line — the web twin of the native renderer's
|
|
24
|
-
* `line + startValue`.
|
|
25
|
-
*/
|
|
26
|
-
export function formatLineNumber(lineNo: number, start: number = 1): string {
|
|
27
|
-
return String(lineNo - 1 + start);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Strip every whitespace character from `text` — the copy-without-spaces
|
|
32
|
-
* transform the native hex monitor applies so a copied address/byte run pastes
|
|
33
|
-
* as a compact hex string. Mirrors `text.replace(/\s/g, '')` in the GTK widget.
|
|
34
|
-
*/
|
|
35
|
-
export function stripWhitespace(text: string): string {
|
|
36
|
-
return text.replace(/\s/g, '');
|
|
37
|
-
}
|