@gjsify/adwaita-web 0.64.1-next.247 → 0.64.2-next.252

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.
Files changed (92) hide show
  1. package/README.md +40 -15
  2. package/dist/adwaita-web.css +39 -9
  3. package/dist/adwaita-web.css.map +1 -1
  4. package/lib/types/application.d.ts +1 -1
  5. package/lib/types/child-slot.spec.d.ts +1 -0
  6. package/lib/types/container-fill.spec.d.ts +1 -0
  7. package/lib/types/elements/adw-alert-dialog.d.ts +77 -17
  8. package/lib/types/elements/adw-toast-overlay.d.ts +8 -29
  9. package/lib/types/elements/adw-window-features.d.ts +8 -0
  10. package/lib/types/elements/gtk-application-window.d.ts +1 -4
  11. package/lib/types/elements/gtk-emoji-chooser.d.ts +2 -0
  12. package/lib/types/elements/gtk-image.d.ts +7 -0
  13. package/lib/types/elements/gtk-popover-menu.d.ts +2 -0
  14. package/lib/types/elements/gtk-popover.d.ts +5 -0
  15. package/lib/types/elements/gtk-stack-page.d.ts +28 -0
  16. package/lib/types/elements/gtk-stack.d.ts +11 -0
  17. package/lib/types/elements/gtk-window.d.ts +16 -1
  18. package/lib/types/gio-resource.spec.d.ts +1 -0
  19. package/lib/types/gobject-elements.d.ts +9 -0
  20. package/lib/types/icon-theme.d.ts +33 -7
  21. package/lib/types/index.d.ts +2 -2
  22. package/lib/types/learn6502-window.spec.d.ts +1 -0
  23. package/lib/types/namespace/adw.d.ts +1 -1
  24. package/lib/types/namespace/gio.d.ts +1 -0
  25. package/lib/types/namespace/gtk.d.ts +2 -0
  26. package/lib/types/shared-tree-builder.d.ts +31 -0
  27. package/lib/types/styles.generated.d.ts +1 -1
  28. package/lib/types/widget-visible.spec.d.ts +1 -0
  29. package/lib/types/window-maximize.spec.d.ts +1 -0
  30. package/package.json +12 -12
  31. package/scss/_bin.scss +6 -3
  32. package/scss/_overlay.scss +11 -1
  33. package/scss/_reset.scss +1 -1
  34. package/scss/_stack.scss +8 -2
  35. package/scss/_toast.scss +13 -3
  36. package/scss/_window.scss +16 -0
  37. package/src/adw-alert-dialog.spec.ts +71 -5
  38. package/src/adw-bin.spec.ts +4 -3
  39. package/src/adw-header-bar.spec.ts +18 -0
  40. package/src/adw-toast-overlay.spec.ts +68 -24
  41. package/src/application.spec.ts +45 -0
  42. package/src/application.ts +15 -18
  43. package/src/capabilities.mjs +1 -3
  44. package/src/child-slot.spec.ts +71 -0
  45. package/src/construct-vectors.spec.ts +51 -6
  46. package/src/container-fill.spec.ts +70 -0
  47. package/src/elements/adw-alert-dialog.ts +174 -44
  48. package/src/elements/adw-application-window.ts +0 -3
  49. package/src/elements/adw-breakpoint-bin.ts +3 -0
  50. package/src/elements/adw-dialog.ts +3 -1
  51. package/src/elements/adw-header-bar.ts +4 -0
  52. package/src/elements/adw-toast-overlay.ts +35 -69
  53. package/src/elements/adw-window-features.ts +14 -2
  54. package/src/elements/gtk-application-window.ts +3 -8
  55. package/src/elements/gtk-drag-icon.ts +4 -0
  56. package/src/elements/gtk-emoji-chooser.ts +5 -0
  57. package/src/elements/gtk-flow-box-child.ts +3 -1
  58. package/src/elements/gtk-graphics-offload.ts +3 -1
  59. package/src/elements/gtk-image.ts +47 -6
  60. package/src/elements/gtk-list-box-row.ts +3 -1
  61. package/src/elements/gtk-overlay.ts +5 -4
  62. package/src/elements/gtk-paned.ts +7 -1
  63. package/src/elements/gtk-popover-bin.ts +3 -0
  64. package/src/elements/gtk-popover-menu.ts +5 -0
  65. package/src/elements/gtk-popover.ts +12 -0
  66. package/src/elements/gtk-search-bar.ts +5 -5
  67. package/src/elements/gtk-stack-page.ts +111 -0
  68. package/src/elements/gtk-stack.ts +50 -5
  69. package/src/elements/gtk-tree-expander.ts +3 -0
  70. package/src/elements/gtk-viewport.ts +4 -0
  71. package/src/elements/gtk-window-handle.ts +4 -0
  72. package/src/elements/gtk-window.ts +55 -6
  73. package/src/gio-resource.spec.ts +137 -0
  74. package/src/gobject-elements.ts +28 -0
  75. package/src/gtk-stack.spec.ts +170 -0
  76. package/src/icon-theme.spec.ts +8 -3
  77. package/src/icon-theme.ts +102 -18
  78. package/src/index.ts +2 -2
  79. package/src/keyboard-operable.spec.ts +3 -3
  80. package/src/learn6502-window.spec.ts +113 -0
  81. package/src/namespace/adw.ts +1 -1
  82. package/src/namespace/gio.ts +10 -0
  83. package/src/namespace/gtk.ts +2 -0
  84. package/src/shared-tree-builder.ts +105 -10
  85. package/src/shared-trees.spec.ts +15 -1
  86. package/src/slotted-children.spec.ts +24 -0
  87. package/src/slotted-children.ts +18 -2
  88. package/src/styles.generated.ts +1 -1
  89. package/src/test.browser.mts +12 -0
  90. package/src/value-lists.spec.ts +3 -3
  91. package/src/widget-visible.spec.ts +104 -0
  92. package/src/window-maximize.spec.ts +93 -0
@@ -67,6 +67,7 @@ import { AdwButtonContentTest } from './adw-button-content.spec.js';
67
67
  import { GtkImageTest } from './gtk-image.spec.js';
68
68
  import { AdwIconRegistryTest } from './icon-registry.spec.js';
69
69
  import { AdwIconThemeTest } from './icon-theme.spec.js';
70
+ import { GioResourceTest } from './gio-resource.spec.js';
70
71
  import { GtkSwitchTest } from './gtk-switch.spec.js';
71
72
  import { AdwChecksTest } from './checks.spec.js';
72
73
  import { GtkProgressBarTest } from './gtk-progress-bar.spec.js';
@@ -82,6 +83,7 @@ import { GtkListViewTest } from './gtk-list-view.spec.js';
82
83
  import { GtkHeaderBarTest } from './gtk-header-bar.spec.js';
83
84
  import { GtkWindowControlsTest } from './gtk-window-controls.spec.js';
84
85
  import { GtkWindowTest } from './gtk-window.spec.js';
86
+ import { WindowMaximizeTest } from './window-maximize.spec.js';
85
87
  import { GtkApplicationWindowTest } from './gtk-application-window.spec.js';
86
88
  import { GtkActionBarTest } from './gtk-action-bar.spec.js';
87
89
  import { GtkSeparatorTest } from './gtk-separator.spec.js';
@@ -92,6 +94,7 @@ import { GtkTreeExpanderTest } from './gtk-tree-expander.spec.js';
92
94
  import { GtkToggleButtonTest } from './gtk-toggle-button.spec.js';
93
95
  import { GtkExpanderTest } from './gtk-expander.spec.js';
94
96
  import { GtkOverlayTest } from './gtk-overlay.spec.js';
97
+ import { ContainerFillTest } from './container-fill.spec.js';
95
98
  import { GtkPanedTest } from './gtk-paned.spec.js';
96
99
  import { GtkRevealerTest } from './gtk-revealer.spec.js';
97
100
  import { GtkScaleTest } from './gtk-scale.spec.js';
@@ -160,6 +163,9 @@ import { AdwValueListsTest } from './value-lists.spec.js';
160
163
  import { AdwBlueprintLayoutTest } from './blueprint-layout.spec.js';
161
164
  import { AdwWidgetSizeTest } from './widget-size.spec.js';
162
165
  import { AdwSharedTreeMountTest } from './shared-tree-mount.spec.js';
166
+ import { AdwWidgetVisibleTest } from './widget-visible.spec.js';
167
+ import { AdwChildSlotTest } from './child-slot.spec.js';
168
+ import { AdwLearn6502WindowTest } from './learn6502-window.spec.js';
163
169
  import { AdwBlueprintMarkupTest } from './blueprint-markup.spec.js';
164
170
  import { AdwTagsTest } from './tags.spec.js';
165
171
  import { AdwFontStackTest } from './font-stack.spec.js';
@@ -182,6 +188,9 @@ run({
182
188
  AdwBlueprintLayoutTest,
183
189
  AdwWidgetSizeTest,
184
190
  AdwSharedTreeMountTest,
191
+ AdwWidgetVisibleTest,
192
+ AdwChildSlotTest,
193
+ AdwLearn6502WindowTest,
185
194
  AdwBlueprintMarkupTest,
186
195
  AdwTagsTest,
187
196
  AdwKeyboardOperableTest,
@@ -202,6 +211,7 @@ run({
202
211
  GtkImageTest,
203
212
  AdwIconRegistryTest,
204
213
  AdwIconThemeTest,
214
+ GioResourceTest,
205
215
  GtkSwitchTest,
206
216
  AdwChecksTest,
207
217
  GtkProgressBarTest,
@@ -217,6 +227,7 @@ run({
217
227
  GtkHeaderBarTest,
218
228
  GtkWindowControlsTest,
219
229
  GtkWindowTest,
230
+ WindowMaximizeTest,
220
231
  GtkApplicationWindowTest,
221
232
  GtkActionBarTest,
222
233
  GtkSeparatorTest,
@@ -232,6 +243,7 @@ run({
232
243
  GtkToggleButtonTest,
233
244
  GtkExpanderTest,
234
245
  GtkOverlayTest,
246
+ ContainerFillTest,
235
247
  GtkPanedTest,
236
248
  GtkRevealerTest,
237
249
  GtkScaleTest,
@@ -63,9 +63,9 @@ export const AdwValueListsTest = async () => {
63
63
  const dialog = root as unknown as AdwAlertDialog;
64
64
  const read = vector.responses.map(({ id }) => ({
65
65
  id,
66
- label: dialog.getResponseLabel(id),
67
- appearance: dialog.getResponseAppearance(id),
68
- enabled: dialog.getResponseEnabled(id),
66
+ label: dialog.get_response_label(id),
67
+ appearance: dialog.get_response_appearance(id),
68
+ enabled: dialog.get_response_enabled(id),
69
69
  }));
70
70
  expect(JSON.stringify(read)).toBe(JSON.stringify(vector.responses));
71
71
  // The buttons the dialog paints, in the order the source wrote them.
@@ -0,0 +1,104 @@
1
+ // `Gtk.Widget:visible` on a built element: an authored `visible: false`, `get_visible()` /
2
+ // `set_visible()`, the property, and a breakpoint setter that writes it and restores it.
3
+ import { describe, expect, it } from '@gjsify/unit';
4
+ import type { SharedTreeNode } from '@gjsify/adwaita-core/conformance';
5
+
6
+ import { mountSharedTree } from './shared-tree-builder.js';
7
+
8
+ function settle(): Promise<void> {
9
+ return new Promise((resolve) => {
10
+ requestAnimationFrame(() => requestAnimationFrame(() => resolve()));
11
+ });
12
+ }
13
+
14
+ type Widget = HTMLElement & { visible: boolean; get_visible(): boolean; set_visible(value: boolean): void };
15
+
16
+ const tree = (width: number, authored: boolean): SharedTreeNode => ({
17
+ tag: 'AdwApplicationWindow',
18
+ props: { 'default-width': width, 'default-height': 400 },
19
+ breakpoints: [
20
+ {
21
+ condition: 'max-width: 599sp',
22
+ setters: [{ object: 'target', property: 'visible', value: false }],
23
+ },
24
+ ],
25
+ children: [
26
+ {
27
+ tag: 'GtkBox',
28
+ slot: 'content',
29
+ children: [{ tag: 'GtkButton', id: 'target', props: authored ? {} : { visible: false } }],
30
+ },
31
+ ],
32
+ });
33
+
34
+ export const AdwWidgetVisibleTest = async () => {
35
+ await describe('adwaita-web: Gtk.Widget:visible on a built element', async () => {
36
+ await it('an authored `visible: false` hides the widget', () => {
37
+ const { root, unmount } = mountSharedTree({
38
+ tag: 'GtkBox',
39
+ children: [{ tag: 'GtkButton', id: 'b', props: { visible: false } }],
40
+ });
41
+ const button = root.querySelector('#b') as Widget;
42
+ expect(button.hidden).toBe(true);
43
+ expect(button.visible).toBe(false);
44
+ expect(button.get_visible()).toBe(false);
45
+ unmount();
46
+ });
47
+
48
+ await it('is visible by default, and an authored `true` shows it', () => {
49
+ const { root, unmount } = mountSharedTree({
50
+ tag: 'GtkBox',
51
+ children: [
52
+ { tag: 'GtkButton', id: 'a' },
53
+ { tag: 'GtkButton', id: 'b', props: { visible: true } },
54
+ ],
55
+ });
56
+ expect((root.querySelector('#a') as Widget).get_visible()).toBe(true);
57
+ expect((root.querySelector('#b') as Widget).hidden).toBe(false);
58
+ unmount();
59
+ });
60
+
61
+ await it('set_visible() and the property round-trip', () => {
62
+ const { root, unmount } = mountSharedTree({
63
+ tag: 'GtkBox',
64
+ children: [{ tag: 'GtkButton', id: 'b' }],
65
+ });
66
+ const button = root.querySelector('#b') as Widget;
67
+ button.set_visible(false);
68
+ expect(button.hidden).toBe(true);
69
+ button.visible = true;
70
+ expect(button.hidden).toBe(false);
71
+ expect(button.get_visible()).toBe(true);
72
+ unmount();
73
+ });
74
+
75
+ await it('a breakpoint setter hides the widget and unapplying restores it', async () => {
76
+ const narrow = mountSharedTree(tree(400, true));
77
+ await settle();
78
+ expect((narrow.root.querySelector('#target') as Widget).visible).toBe(false);
79
+ narrow.unmount();
80
+
81
+ const wide = mountSharedTree(tree(1000, true));
82
+ await settle();
83
+ expect((wide.root.querySelector('#target') as Widget).visible).toBe(true);
84
+ wide.unmount();
85
+ });
86
+
87
+ await it('unapplying a breakpoint restores an authored `false`', async () => {
88
+ const { root, unmount } = mountSharedTree(tree(1000, false));
89
+ await settle();
90
+ expect((root.querySelector('#target') as Widget).visible).toBe(false);
91
+ unmount();
92
+ });
93
+
94
+ await it('<gtk-stack-page> and <adw-sidebar> keep their own `visible`', () => {
95
+ const page = document.createElement('gtk-stack-page') as Widget;
96
+ page.visible = false;
97
+ expect(page.hasAttribute('hidden')).toBe(true);
98
+ const item = document.createElement('adw-sidebar-item') as Widget;
99
+ item.visible = false;
100
+ expect(item.getAttribute('visible')).toBe('false');
101
+ expect(item.hasAttribute('hidden')).toBe(true);
102
+ });
103
+ });
104
+ };
@@ -0,0 +1,93 @@
1
+ // A maximized or fullscreen `Gtk.Window` ignores its default size and fills the work area
2
+ // (gtkwindow.c); on a page that is the frame's containing block. Driven through layout, because
3
+ // the claim is about the box, not about a class name. One body for the three window elements.
4
+ import { describe, expect, it } from '@gjsify/unit';
5
+
6
+ import type { GtkWindow } from './elements/gtk-window.js';
7
+
8
+ const TAGS = ['gtk-window', 'adw-window', 'adw-application-window'] as const;
9
+
10
+ function mount(tag: string, attrs: Record<string, string> = {}): { el: GtkWindow; host: HTMLElement } {
11
+ const host = document.createElement('div');
12
+ host.style.cssText = 'position:relative;width:500px;height:400px';
13
+ document.body.appendChild(host);
14
+ const el = document.createElement(tag) as GtkWindow;
15
+ el.setAttribute('default-width', '360');
16
+ el.setAttribute('default-height', '240');
17
+ for (const [name, value] of Object.entries(attrs)) el.setAttribute(name, value);
18
+ host.appendChild(el);
19
+ return { el, host };
20
+ }
21
+
22
+ function size(el: HTMLElement): string {
23
+ const rect = el.getBoundingClientRect();
24
+ return `${Math.round(rect.width)}x${Math.round(rect.height)}`;
25
+ }
26
+
27
+ export const WindowMaximizeTest = async () => {
28
+ for (const tag of TAGS) {
29
+ await describe(`<${tag}> maximized fills its containing block`, async () => {
30
+ await it('opens at the default size, fills the box maximized, and restores on unmaximize', async () => {
31
+ const { el, host } = mount(tag);
32
+ expect(size(el)).toBe('360x240');
33
+ el.maximize();
34
+ expect(size(el)).toBe('500x400');
35
+ expect(el.style.width).toBe('');
36
+ el.unmaximize();
37
+ expect(size(el)).toBe('360x240');
38
+ host.remove();
39
+ });
40
+
41
+ await it('fills the box through the `maximized` property and `toggle-maximized`', async () => {
42
+ const { el, host } = mount(tag);
43
+ el.maximized = true;
44
+ expect(size(el)).toBe('500x400');
45
+ el.maximized = false;
46
+ expect(size(el)).toBe('360x240');
47
+ el.dispatchEvent(new CustomEvent('window-action', { detail: { action: 'toggle-maximized' } }));
48
+ expect(size(el)).toBe('500x400');
49
+ el.dispatchEvent(new CustomEvent('window-action', { detail: { action: 'toggle-maximized' } }));
50
+ expect(size(el)).toBe('360x240');
51
+ host.remove();
52
+ });
53
+
54
+ await it('fills the box fullscreened and restores on unfullscreen', async () => {
55
+ const { el, host } = mount(tag);
56
+ el.fullscreen();
57
+ expect(el.is_fullscreen()).toBe(true);
58
+ expect(size(el)).toBe('500x400');
59
+ el.unfullscreen();
60
+ expect(size(el)).toBe('360x240');
61
+ host.remove();
62
+ });
63
+
64
+ await it('stays filled until both states are gone', async () => {
65
+ const { el, host } = mount(tag);
66
+ el.maximize();
67
+ el.fullscreen();
68
+ el.unmaximize();
69
+ expect(size(el)).toBe('500x400');
70
+ el.unfullscreen();
71
+ expect(size(el)).toBe('360x240');
72
+ host.remove();
73
+ });
74
+
75
+ await it('fills the box already maximized when it is connected', async () => {
76
+ const { el, host } = mount(tag, { maximized: 'true' });
77
+ expect(size(el)).toBe('500x400');
78
+ host.remove();
79
+ });
80
+ });
81
+ }
82
+
83
+ await describe('<adw-window> maximized keeps its size request as a minimum', async () => {
84
+ await it('does not shrink below width-request/height-request', async () => {
85
+ const { el, host } = mount('adw-window', { 'width-request': '600', 'height-request': '450' });
86
+ el.maximize();
87
+ const [width, height] = size(el).split('x').map(Number);
88
+ expect(width >= 600).toBe(true);
89
+ expect(height >= 450).toBe(true);
90
+ host.remove();
91
+ });
92
+ });
93
+ };