@gjsify/example-gtk-adwaita-storybook 0.54.0 → 0.56.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.
Files changed (243) hide show
  1. package/dist/browser-main.js +8169 -3016
  2. package/dist/gjs.js +14 -9
  3. package/dist/gjs.node.mjs +10 -5
  4. package/package.json +5 -5
  5. package/src/browser/buttons/color-dialog-button.web.ts +42 -0
  6. package/src/browser/buttons/font-dialog-button.web.ts +42 -0
  7. package/src/browser/buttons/link-button.web.ts +37 -0
  8. package/src/browser/buttons/scale-button.web.ts +36 -0
  9. package/src/browser/buttons/toggle-button.web.ts +35 -0
  10. package/src/browser/controls/check-button.web.ts +38 -0
  11. package/src/browser/controls/gtk-spinner.web.ts +39 -0
  12. package/src/browser/controls/level-bar.web.ts +43 -0
  13. package/src/browser/controls/password-entry.web.ts +36 -0
  14. package/src/browser/controls/progress-bar.web.ts +39 -0
  15. package/src/browser/controls/scale.web.ts +44 -0
  16. package/src/browser/controls/search-entry.web.ts +49 -0
  17. package/src/browser/controls/spin-button.web.ts +40 -0
  18. package/src/browser/controls/switch.web.ts +38 -0
  19. package/src/browser/drawing/drag-icon.web.ts +112 -0
  20. package/src/browser/drawing/drawing-area.web.ts +66 -0
  21. package/src/browser/drawing/gl-area.web.ts +162 -0
  22. package/src/browser/drawing/graphics-offload.web.ts +74 -0
  23. package/src/browser/feedback/dialog.web.ts +76 -0
  24. package/src/browser/feedback/emoji-chooser.web.ts +93 -0
  25. package/src/browser/feedback/gtk-about-dialog.web.ts +105 -0
  26. package/src/browser/feedback/page-setup-unix-dialog.web.ts +93 -0
  27. package/src/browser/feedback/print-unix-dialog.web.ts +111 -0
  28. package/src/browser/feedback/shortcuts-dialog.web.ts +90 -0
  29. package/src/browser/layout/application-window.web.ts +94 -0
  30. package/src/browser/layout/aspect-frame.web.ts +49 -0
  31. package/src/browser/layout/bin.web.ts +41 -0
  32. package/src/browser/layout/breakpoint-bin.web.ts +61 -0
  33. package/src/browser/layout/center-box.web.ts +45 -0
  34. package/src/browser/layout/clamp-scrollable.web.ts +47 -0
  35. package/src/browser/layout/expander.web.ts +52 -0
  36. package/src/browser/layout/fixed.web.ts +51 -0
  37. package/src/browser/layout/frame.web.ts +40 -0
  38. package/src/browser/layout/grid.web.ts +46 -0
  39. package/src/browser/layout/layout-slot.web.ts +60 -0
  40. package/src/browser/layout/multi-layout-view.web.ts +94 -0
  41. package/src/browser/layout/overlay.web.ts +57 -0
  42. package/src/browser/layout/paned.web.ts +69 -0
  43. package/src/browser/layout/popover-bin.web.ts +54 -0
  44. package/src/browser/layout/popover-menu.web.ts +48 -0
  45. package/src/browser/layout/popover.web.ts +61 -0
  46. package/src/browser/layout/revealer.web.ts +53 -0
  47. package/src/browser/layout/scrollbar.web.ts +54 -0
  48. package/src/browser/layout/scrolled-window.web.ts +52 -0
  49. package/src/browser/layout/separator.web.ts +47 -0
  50. package/src/browser/layout/viewport.web.ts +51 -0
  51. package/src/browser/layout/window.web.ts +60 -0
  52. package/src/browser/media/image.web.ts +39 -0
  53. package/src/browser/media/inscription.web.ts +52 -0
  54. package/src/browser/media/media-controls.web.ts +65 -0
  55. package/src/browser/media/picture.web.ts +56 -0
  56. package/src/browser/media/video.web.ts +56 -0
  57. package/src/browser/navigation/popover-menu-bar.web.ts +40 -0
  58. package/src/browser/presentation/calendar.web.ts +49 -0
  59. package/src/browser/presentation/column-view.web.ts +45 -0
  60. package/src/browser/presentation/flow-box.web.ts +52 -0
  61. package/src/browser/presentation/grid-view.web.ts +37 -0
  62. package/src/browser/presentation/list-box.web.ts +48 -0
  63. package/src/browser/presentation/list-view.web.ts +36 -0
  64. package/src/browser/presentation/tree-expander.web.ts +68 -0
  65. package/src/browser/presentation/window-handle.web.ts +42 -0
  66. package/src/browser/rows/preferences-row.web.ts +43 -0
  67. package/src/browser/stories.ts +158 -0
  68. package/src/browser/text/editable-label.web.ts +45 -0
  69. package/src/browser/text/search-bar.web.ts +45 -0
  70. package/src/browser/text/text-view.web.ts +54 -0
  71. package/src/browser/text/text.web.ts +48 -0
  72. package/src/browser/view-switching/notebook.web.ts +67 -0
  73. package/src/browser/view-switching/stack-sidebar.web.ts +68 -0
  74. package/src/browser/view-switching/stack-switcher.web.ts +70 -0
  75. package/src/browser/view-switching/stack.web.ts +72 -0
  76. package/src/browser/view-switching/tab-bar.web.ts +105 -0
  77. package/src/browser/view-switching/tab-button.web.ts +52 -0
  78. package/src/browser/view-switching/tab-overview.web.ts +87 -0
  79. package/src/browser/view-switching/view-switcher-sidebar.web.ts +77 -0
  80. package/src/browser/windows/action-bar.web.ts +66 -0
  81. package/src/browser/windows/gtk-application-window.web.ts +67 -0
  82. package/src/browser/windows/gtk-header-bar.web.ts +61 -0
  83. package/src/browser/windows/gtk-window.web.ts +58 -0
  84. package/src/browser/windows/window-controls.web.ts +54 -0
  85. package/src/buttons/color-dialog-button.meta.ts +16 -0
  86. package/src/buttons/color-dialog-button.story.ts +49 -0
  87. package/src/buttons/font-dialog-button.meta.ts +29 -0
  88. package/src/buttons/font-dialog-button.story.ts +52 -0
  89. package/src/buttons/link-button.meta.ts +18 -0
  90. package/src/buttons/link-button.story.ts +48 -0
  91. package/src/buttons/scale-button.meta.ts +34 -0
  92. package/src/buttons/scale-button.story.ts +50 -0
  93. package/src/buttons/toggle-button.meta.ts +17 -0
  94. package/src/buttons/toggle-button.story.ts +46 -0
  95. package/src/controls/check-button.meta.ts +19 -0
  96. package/src/controls/check-button.story.ts +56 -0
  97. package/src/controls/gtk-spinner.meta.ts +24 -0
  98. package/src/controls/gtk-spinner.story.ts +53 -0
  99. package/src/controls/level-bar.meta.ts +39 -0
  100. package/src/controls/level-bar.story.ts +58 -0
  101. package/src/controls/password-entry.meta.ts +18 -0
  102. package/src/controls/password-entry.story.ts +54 -0
  103. package/src/controls/progress-bar.meta.ts +20 -0
  104. package/src/controls/progress-bar.story.ts +53 -0
  105. package/src/controls/scale.meta.ts +47 -0
  106. package/src/controls/scale.story.ts +66 -0
  107. package/src/controls/search-entry.meta.ts +18 -0
  108. package/src/controls/search-entry.story.ts +57 -0
  109. package/src/controls/spin-button.meta.ts +40 -0
  110. package/src/controls/spin-button.story.ts +55 -0
  111. package/src/controls/switch.meta.ts +18 -0
  112. package/src/controls/switch.story.ts +50 -0
  113. package/src/drawing/drag-icon.meta.ts +39 -0
  114. package/src/drawing/drag-icon.story.ts +117 -0
  115. package/src/drawing/drawing-area.meta.ts +45 -0
  116. package/src/drawing/drawing-area.story.ts +78 -0
  117. package/src/drawing/gl-area.meta.ts +30 -0
  118. package/src/drawing/gl-area.story.ts +113 -0
  119. package/src/drawing/graphics-offload.meta.ts +39 -0
  120. package/src/drawing/graphics-offload.story.ts +73 -0
  121. package/src/feedback/dialog.meta.ts +25 -0
  122. package/src/feedback/dialog.story.ts +78 -0
  123. package/src/feedback/emoji-chooser.meta.ts +10 -0
  124. package/src/feedback/emoji-chooser.story.ts +98 -0
  125. package/src/feedback/gtk-about-dialog.meta.ts +29 -0
  126. package/src/feedback/gtk-about-dialog.story.ts +90 -0
  127. package/src/feedback/page-setup-unix-dialog.meta.ts +37 -0
  128. package/src/feedback/page-setup-unix-dialog.story.ts +70 -0
  129. package/src/feedback/print-unix-dialog.meta.ts +30 -0
  130. package/src/feedback/print-unix-dialog.story.ts +93 -0
  131. package/src/feedback/shortcuts-dialog.meta.ts +12 -0
  132. package/src/feedback/shortcuts-dialog.story.ts +79 -0
  133. package/src/layout/application-window.meta.ts +16 -0
  134. package/src/layout/application-window.story.ts +97 -0
  135. package/src/layout/aspect-frame.meta.ts +19 -0
  136. package/src/layout/aspect-frame.story.ts +62 -0
  137. package/src/layout/bin.meta.ts +15 -0
  138. package/src/layout/bin.story.ts +56 -0
  139. package/src/layout/breakpoint-bin.meta.ts +38 -0
  140. package/src/layout/breakpoint-bin.story.ts +62 -0
  141. package/src/layout/center-box.meta.ts +26 -0
  142. package/src/layout/center-box.story.ts +54 -0
  143. package/src/layout/clamp-scrollable.meta.ts +30 -0
  144. package/src/layout/clamp-scrollable.story.ts +51 -0
  145. package/src/layout/expander.meta.ts +30 -0
  146. package/src/layout/expander.story.ts +62 -0
  147. package/src/layout/fixed.meta.ts +16 -0
  148. package/src/layout/fixed.story.ts +54 -0
  149. package/src/layout/frame.meta.ts +24 -0
  150. package/src/layout/frame.story.ts +51 -0
  151. package/src/layout/grid.meta.ts +45 -0
  152. package/src/layout/grid.story.ts +80 -0
  153. package/src/layout/layout-slot.meta.ts +22 -0
  154. package/src/layout/layout-slot.story.ts +68 -0
  155. package/src/layout/multi-layout-view.meta.ts +31 -0
  156. package/src/layout/multi-layout-view.story.ts +101 -0
  157. package/src/layout/overlay.meta.ts +42 -0
  158. package/src/layout/overlay.story.ts +72 -0
  159. package/src/layout/paned.meta.ts +45 -0
  160. package/src/layout/paned.story.ts +70 -0
  161. package/src/layout/popover-bin.meta.ts +29 -0
  162. package/src/layout/popover-bin.story.ts +66 -0
  163. package/src/layout/popover-menu.meta.ts +54 -0
  164. package/src/layout/popover-menu.story.ts +119 -0
  165. package/src/layout/popover.meta.ts +38 -0
  166. package/src/layout/popover.story.ts +66 -0
  167. package/src/layout/revealer.meta.ts +44 -0
  168. package/src/layout/revealer.story.ts +79 -0
  169. package/src/layout/scrollbar.meta.ts +33 -0
  170. package/src/layout/scrollbar.story.ts +61 -0
  171. package/src/layout/scrolled-window.meta.ts +57 -0
  172. package/src/layout/scrolled-window.story.ts +74 -0
  173. package/src/layout/separator.meta.ts +25 -0
  174. package/src/layout/separator.story.ts +53 -0
  175. package/src/layout/viewport.meta.ts +19 -0
  176. package/src/layout/viewport.story.ts +53 -0
  177. package/src/layout/window.meta.ts +13 -0
  178. package/src/layout/window.story.ts +66 -0
  179. package/src/media/image.meta.ts +24 -0
  180. package/src/media/image.story.ts +48 -0
  181. package/src/media/inscription.meta.ts +45 -0
  182. package/src/media/inscription.story.ts +64 -0
  183. package/src/media/media-controls.meta.ts +30 -0
  184. package/src/media/media-controls.story.ts +58 -0
  185. package/src/media/picture.meta.ts +42 -0
  186. package/src/media/picture.story.ts +81 -0
  187. package/src/media/video.meta.ts +32 -0
  188. package/src/media/video.story.ts +57 -0
  189. package/src/metas.ts +79 -0
  190. package/src/navigation/popover-menu-bar.meta.ts +51 -0
  191. package/src/navigation/popover-menu-bar.story.ts +72 -0
  192. package/src/presentation/calendar.meta.ts +28 -0
  193. package/src/presentation/calendar.story.ts +64 -0
  194. package/src/presentation/column-view.meta.ts +30 -0
  195. package/src/presentation/column-view.story.ts +73 -0
  196. package/src/presentation/flow-box.meta.ts +51 -0
  197. package/src/presentation/flow-box.story.ts +72 -0
  198. package/src/presentation/grid-view.meta.ts +28 -0
  199. package/src/presentation/grid-view.story.ts +64 -0
  200. package/src/presentation/list-box.meta.ts +55 -0
  201. package/src/presentation/list-box.story.ts +68 -0
  202. package/src/presentation/list-view.meta.ts +38 -0
  203. package/src/presentation/list-view.story.ts +73 -0
  204. package/src/presentation/tree-expander.meta.ts +24 -0
  205. package/src/presentation/tree-expander.story.ts +105 -0
  206. package/src/presentation/window-handle.meta.ts +27 -0
  207. package/src/presentation/window-handle.story.ts +53 -0
  208. package/src/rows/preferences-row.meta.ts +15 -0
  209. package/src/rows/preferences-row.story.ts +50 -0
  210. package/src/text/editable-label.meta.ts +17 -0
  211. package/src/text/editable-label.story.ts +47 -0
  212. package/src/text/search-bar.meta.ts +17 -0
  213. package/src/text/search-bar.story.ts +48 -0
  214. package/src/text/text-view.meta.ts +49 -0
  215. package/src/text/text-view.story.ts +69 -0
  216. package/src/text/text.meta.ts +21 -0
  217. package/src/text/text.story.ts +50 -0
  218. package/src/view-switching/notebook.meta.ts +44 -0
  219. package/src/view-switching/notebook.story.ts +77 -0
  220. package/src/view-switching/stack-sidebar.meta.ts +50 -0
  221. package/src/view-switching/stack-sidebar.story.ts +85 -0
  222. package/src/view-switching/stack-switcher.meta.ts +53 -0
  223. package/src/view-switching/stack-switcher.story.ts +95 -0
  224. package/src/view-switching/stack.meta.ts +53 -0
  225. package/src/view-switching/stack.story.ts +95 -0
  226. package/src/view-switching/tab-bar.meta.ts +22 -0
  227. package/src/view-switching/tab-bar.story.ts +85 -0
  228. package/src/view-switching/tab-button.meta.ts +14 -0
  229. package/src/view-switching/tab-button.story.ts +52 -0
  230. package/src/view-switching/tab-overview.meta.ts +21 -0
  231. package/src/view-switching/tab-overview.story.ts +86 -0
  232. package/src/view-switching/view-switcher-sidebar.meta.ts +42 -0
  233. package/src/view-switching/view-switcher-sidebar.story.ts +73 -0
  234. package/src/windows/action-bar.meta.ts +27 -0
  235. package/src/windows/action-bar.story.ts +65 -0
  236. package/src/windows/gtk-application-window.meta.ts +27 -0
  237. package/src/windows/gtk-application-window.story.ts +89 -0
  238. package/src/windows/gtk-header-bar.meta.ts +39 -0
  239. package/src/windows/gtk-header-bar.story.ts +76 -0
  240. package/src/windows/gtk-window.meta.ts +30 -0
  241. package/src/windows/gtk-window.story.ts +64 -0
  242. package/src/windows/window-controls.meta.ts +42 -0
  243. package/src/windows/window-controls.story.ts +61 -0
@@ -0,0 +1,45 @@
1
+ // Browser port of the Center Box story. Shares metadata with center-box.story.ts.
2
+
3
+ import { StoryElement, type StoryArgs, type StoryMeta, type WebStoryModule } from '@gjsify/adwaita-storybook';
4
+ import { centerBoxMeta } from '../../layout/center-box.meta.js';
5
+
6
+ export class CenterBoxWebStory extends StoryElement {
7
+ private _box: HTMLElement | null = null;
8
+
9
+ constructor() {
10
+ super(CenterBoxWebStory.getMetadata(), 'Default');
11
+ }
12
+
13
+ static getMetadata(): StoryMeta {
14
+ return centerBoxMeta;
15
+ }
16
+
17
+ initialize(): void {
18
+ this._box = document.createElement('gtk-center-box');
19
+ this._box.style.padding = '12px';
20
+ for (const [slot, text] of [
21
+ ['start-widget', 'Start'],
22
+ ['center-widget', 'Centre'],
23
+ ['end-widget', 'End'],
24
+ ] as const) {
25
+ const child = document.createElement('gtk-label');
26
+ child.setAttribute('slot', slot);
27
+ child.setAttribute('label', text);
28
+ this._box.append(child);
29
+ }
30
+ this._apply();
31
+ this.addContent(this._box);
32
+ }
33
+
34
+ updateArgs(_args: StoryArgs): void {
35
+ this._apply();
36
+ }
37
+
38
+ private _apply(): void {
39
+ if (!this._box) return;
40
+ this._box.toggleAttribute('shrink-center-last', this.args.shrinkCenterLast as boolean);
41
+ this._box.setAttribute('baseline-position', this.args.baselinePosition as string);
42
+ }
43
+ }
44
+
45
+ export const CenterBoxWebStories: WebStoryModule = { stories: [CenterBoxWebStory] };
@@ -0,0 +1,47 @@
1
+ // Browser port of the Clamp Scrollable story. Shares metadata with clamp-scrollable.story.ts.
2
+
3
+ import { StoryElement, type StoryArgs, type StoryMeta, type WebStoryModule } from '@gjsify/adwaita-storybook';
4
+ import { clampScrollableMeta } from '../../layout/clamp-scrollable.meta.js';
5
+
6
+ const LINES = Array.from({ length: 24 }, (_, i) => `Line ${i + 1}: held at the clamp's width while it scrolls.`);
7
+
8
+ export class ClampScrollableWebStory extends StoryElement {
9
+ private _clamp: HTMLElement | null = null;
10
+
11
+ constructor() {
12
+ super(ClampScrollableWebStory.getMetadata(), 'Default');
13
+ }
14
+
15
+ static getMetadata(): StoryMeta {
16
+ return clampScrollableMeta;
17
+ }
18
+
19
+ initialize(): void {
20
+ const text = document.createElement('div');
21
+ text.style.padding = '12px 0';
22
+ for (const line of LINES) {
23
+ const row = document.createElement('div');
24
+ row.textContent = line;
25
+ text.append(row);
26
+ }
27
+
28
+ this._clamp = document.createElement('adw-clamp-scrollable');
29
+ this._clamp.style.width = '640px';
30
+ this._clamp.style.height = '240px';
31
+ this._clamp.append(text);
32
+ this._sync();
33
+ this.addContent(this._clamp);
34
+ }
35
+
36
+ updateArgs(_args: StoryArgs): void {
37
+ this._sync();
38
+ }
39
+
40
+ private _sync(): void {
41
+ if (!this._clamp) return;
42
+ this._clamp.setAttribute('maximum-size', String(this.args.maximumSize as number));
43
+ this._clamp.setAttribute('tightening-threshold', String(this.args.tighteningThreshold as number));
44
+ }
45
+ }
46
+
47
+ export const ClampScrollableWebStories: WebStoryModule = { stories: [ClampScrollableWebStory] };
@@ -0,0 +1,52 @@
1
+ // Browser port of the Expander story. Shares metadata with expander.story.ts.
2
+
3
+ import { StoryElement, type StoryArgs, type StoryMeta, type WebStoryModule } from '@gjsify/adwaita-storybook';
4
+ import { expanderMeta } from '../../layout/expander.meta.js';
5
+
6
+ export class ExpanderWebStory extends StoryElement {
7
+ private _expander: HTMLElement | null = null;
8
+
9
+ constructor() {
10
+ super(ExpanderWebStory.getMetadata(), 'Default');
11
+ }
12
+
13
+ static getMetadata(): StoryMeta {
14
+ return expanderMeta;
15
+ }
16
+
17
+ initialize(): void {
18
+ this._expander = document.createElement('gtk-expander');
19
+ this._expander.style.width = '320px';
20
+
21
+ const content = document.createElement('gtk-box');
22
+ content.setAttribute('orientation', 'vertical');
23
+ content.setAttribute('spacing', '6');
24
+ content.style.padding = '12px';
25
+ for (const line of ['Notifications', 'Sound', 'Network']) {
26
+ const label = document.createElement('gtk-label');
27
+ label.setAttribute('label', line);
28
+ content.appendChild(label);
29
+ }
30
+ this._expander.appendChild(content);
31
+
32
+ this._apply();
33
+ this.addContent(this._expander);
34
+ }
35
+
36
+ updateArgs(_args: StoryArgs): void {
37
+ this._apply();
38
+ }
39
+
40
+ private _apply(): void {
41
+ if (!this._expander) return;
42
+ // `set_label` builds a real GtkLabel out of the string with `use_underline` and
43
+ // `use_markup` forwarded to it (gtkexpander.c:974-979), so the two flags are set
44
+ // BEFORE the text — the order the C's own docs give.
45
+ this._expander.toggleAttribute('use-underline', this.args.useUnderline as boolean);
46
+ this._expander.setAttribute('label', String(this.args.label));
47
+ this._expander.toggleAttribute('resize-toplevel', this.args.resizeToplevel as boolean);
48
+ this._expander.toggleAttribute('expanded', this.args.expanded as boolean);
49
+ }
50
+ }
51
+
52
+ export const ExpanderWebStories: WebStoryModule = { stories: [ExpanderWebStory] };
@@ -0,0 +1,51 @@
1
+ // Browser port of the Fixed story. Shares metadata with fixed.story.ts.
2
+
3
+ import { StoryElement, type StoryArgs, type StoryMeta, type WebStoryModule } from '@gjsify/adwaita-storybook';
4
+ import { fixedMeta } from '../../layout/fixed.meta.js';
5
+
6
+ /** What `move()` is on `<gtk-fixed>`, and the only reason this story casts. */
7
+ type MovableFixed = HTMLElement & { move(child: HTMLElement, x: number, y: number): void };
8
+
9
+ export class FixedWebStory extends StoryElement {
10
+ private _fixed: MovableFixed | null = null;
11
+ private _cells: HTMLElement[] = [];
12
+
13
+ constructor() {
14
+ super(FixedWebStory.getMetadata(), 'Default');
15
+ }
16
+
17
+ static getMetadata(): StoryMeta {
18
+ return fixedMeta;
19
+ }
20
+
21
+ initialize(): void {
22
+ const fixed = document.createElement('gtk-fixed') as MovableFixed;
23
+ this._fixed = fixed;
24
+ for (const text of ['at (x, y)', 'at (x + 96, y + 40)']) {
25
+ const cell = document.createElement('gtk-label');
26
+ cell.setAttribute('label', text);
27
+ this._cells.push(cell);
28
+ fixed.append(cell);
29
+ }
30
+ this._apply();
31
+ this.addContent(fixed);
32
+ }
33
+
34
+ updateArgs(_args: StoryArgs): void {
35
+ this._apply();
36
+ }
37
+
38
+ private _apply(): void {
39
+ const fixed = this._fixed;
40
+ if (fixed === null) return;
41
+ const x = this.args.offsetX as number;
42
+ const y = this.args.offsetY as number;
43
+ const [first, second] = this._cells;
44
+ // The two offsets the GTK story hands to `gtk_fixed_move`, through `move()` — the
45
+ // markup form of the same numbers is the child's own CSS position.
46
+ if (first !== undefined) fixed.move(first, x, y);
47
+ if (second !== undefined) fixed.move(second, x + 96, y + 40);
48
+ }
49
+ }
50
+
51
+ export const FixedWebStories: WebStoryModule = { stories: [FixedWebStory] };
@@ -0,0 +1,40 @@
1
+ // Browser port of the Frame story. Shares metadata with frame.story.ts.
2
+
3
+ import { StoryElement, type StoryArgs, type StoryMeta, type WebStoryModule } from '@gjsify/adwaita-storybook';
4
+ import { frameMeta } from '../../layout/frame.meta.js';
5
+
6
+ export class FrameWebStory extends StoryElement {
7
+ private _frame: HTMLElement | null = null;
8
+
9
+ constructor() {
10
+ super(FrameWebStory.getMetadata(), 'Default');
11
+ }
12
+
13
+ static getMetadata(): StoryMeta {
14
+ return frameMeta;
15
+ }
16
+
17
+ initialize(): void {
18
+ this._frame = document.createElement('gtk-frame');
19
+ const body = document.createElement('gtk-label');
20
+ body.setAttribute('label', 'A framed region: the label sits in the top edge of the border.');
21
+ body.style.padding = '12px';
22
+ this._frame.append(body);
23
+ this._apply();
24
+ this.addContent(this._frame);
25
+ }
26
+
27
+ updateArgs(_args: StoryArgs): void {
28
+ this._apply();
29
+ }
30
+
31
+ private _apply(): void {
32
+ if (!this._frame) return;
33
+ const label = this.args.label as string;
34
+ if (label === '') this._frame.removeAttribute('label');
35
+ else this._frame.setAttribute('label', label);
36
+ this._frame.setAttribute('label-xalign', String(this.args.labelXalign as number));
37
+ }
38
+ }
39
+
40
+ export const FrameWebStories: WebStoryModule = { stories: [FrameWebStory] };
@@ -0,0 +1,46 @@
1
+ // Browser port of the Grid story. Shares metadata with grid.story.ts.
2
+
3
+ import { StoryElement, type StoryArgs, type StoryMeta, type WebStoryModule } from '@gjsify/adwaita-storybook';
4
+ import { gridMeta } from '../../layout/grid.meta.js';
5
+
6
+ export class GridWebStory extends StoryElement {
7
+ private _grid: HTMLElement | null = null;
8
+
9
+ constructor() {
10
+ super(GridWebStory.getMetadata(), 'Default');
11
+ }
12
+
13
+ static getMetadata(): StoryMeta {
14
+ return gridMeta;
15
+ }
16
+
17
+ initialize(): void {
18
+ this._grid = document.createElement('gtk-grid');
19
+ this._grid.style.padding = '12px';
20
+ // Source order IS the placement here: a CSS grid fills row by row, which is what
21
+ // `attach(child, -1, -1, 1, 1)` does in the GTK rendering.
22
+ for (const text of ['Name', 'Value', 'Unit', 'editable']) {
23
+ const cell = document.createElement('gtk-label');
24
+ cell.setAttribute('label', text);
25
+ cell.style.padding = '6px';
26
+ this._grid.append(cell);
27
+ }
28
+ this._apply();
29
+ this.addContent(this._grid);
30
+ }
31
+
32
+ updateArgs(_args: StoryArgs): void {
33
+ this._apply();
34
+ }
35
+
36
+ private _apply(): void {
37
+ if (!this._grid) return;
38
+ this._grid.setAttribute('column-spacing', String(this.args.columnSpacing as number));
39
+ this._grid.setAttribute('row-spacing', String(this.args.rowSpacing as number));
40
+ this._grid.toggleAttribute('column-homogeneous', this.args.columnHomogeneous as boolean);
41
+ this._grid.toggleAttribute('row-homogeneous', this.args.rowHomogeneous as boolean);
42
+ this._grid.setAttribute('orientation', this.args.orientation as string);
43
+ }
44
+ }
45
+
46
+ export const GridWebStories: WebStoryModule = { stories: [GridWebStory] };
@@ -0,0 +1,60 @@
1
+ // Browser port of the Layout Slot story. Shares metadata with layout-slot.story.ts.
2
+
3
+ import { StoryElement, type StoryArgs, type StoryMeta, type WebStoryModule } from '@gjsify/adwaita-storybook';
4
+ import { layoutSlotMeta } from '../../layout/layout-slot.meta.js';
5
+
6
+ /**
7
+ * A slot only ever exists inside a layout, and a layout only ever exists inside a
8
+ * multi-layout view — the view is what inserts the child whose id matches the slot's. So
9
+ * this story builds the whole pair and names the SLOT, which is the half a reader cannot
10
+ * see anywhere else: the `visible` binding the view installs between the two
11
+ * (adw-multi-layout-view.c:151).
12
+ */
13
+ export class LayoutSlotWebStory extends StoryElement {
14
+ private _view: HTMLElement | null = null;
15
+ private _child: HTMLElement | null = null;
16
+
17
+ constructor() {
18
+ super(LayoutSlotWebStory.getMetadata(), 'Default');
19
+ }
20
+
21
+ static getMetadata(): StoryMeta {
22
+ return layoutSlotMeta;
23
+ }
24
+
25
+ initialize(): void {
26
+ this._child = document.createElement('adw-navigation-page');
27
+ this._child.setAttribute('tag', 'primary');
28
+ this._child.setAttribute('slot', 'primary');
29
+ const label = document.createElement('gtk-label');
30
+ label.setAttribute('label', 'The child the view inserted here.');
31
+ this._child.appendChild(label);
32
+
33
+ this._view = document.createElement('adw-multi-layout-view');
34
+ this._view.style.width = '360px';
35
+ this._view.style.height = '120px';
36
+ const layout = document.createElement('div');
37
+ layout.setAttribute('name', 'only');
38
+ const slot = document.createElement('adw-layout-slot');
39
+ slot.setAttribute('id', 'primary');
40
+ layout.appendChild(slot);
41
+ this._view.appendChild(layout);
42
+ this._view.appendChild(this._child);
43
+
44
+ this._apply();
45
+ this.addContent(this._view);
46
+ }
47
+
48
+ updateArgs(_args: StoryArgs): void {
49
+ this._apply();
50
+ }
51
+
52
+ private _apply(): void {
53
+ if (!this._child) return;
54
+ this._child.setAttribute('title', this.args.label as string);
55
+ // The binding is child → slot, one way: the slot cannot show what the child hides.
56
+ this._child.toggleAttribute('hidden', !(this.args.visible as boolean));
57
+ }
58
+ }
59
+
60
+ export const LayoutSlotWebStories: WebStoryModule = { stories: [LayoutSlotWebStory] };
@@ -0,0 +1,94 @@
1
+ // Browser port of the Multi Layout View story. Shares metadata with multi-layout-view.story.ts.
2
+
3
+ import { StoryElement, type StoryArgs, type StoryMeta, type WebStoryModule } from '@gjsify/adwaita-storybook';
4
+ import { multiLayoutViewMeta } from '../../layout/multi-layout-view.meta.js';
5
+
6
+ /** The two ids every layout here carries: the content, and the secondary pane. */
7
+ const PRIMARY = 'primary';
8
+ const SECONDARY = 'secondary';
9
+
10
+ /** One arrangement: a split view whose two panes are slots, so the children land by id. */
11
+ function arrangement(collapsed: boolean): Element {
12
+ const view = document.createElement('adw-navigation-split-view');
13
+ if (collapsed) view.setAttribute('collapsed', '');
14
+ view.setAttribute('min-sidebar-width', '160');
15
+ view.style.width = '420px';
16
+ view.style.height = '220px';
17
+ for (const [slot, id] of [
18
+ ['sidebar', SECONDARY],
19
+ ['content', PRIMARY],
20
+ ] as const) {
21
+ const hole = document.createElement('adw-layout-slot');
22
+ hole.setAttribute('id', id);
23
+ hole.setAttribute('slot', slot);
24
+ view.appendChild(hole);
25
+ }
26
+ return view;
27
+ }
28
+
29
+ export class MultiLayoutViewWebStory extends StoryElement {
30
+ private _view: HTMLElement | null = null;
31
+ private _details: Element | null = null;
32
+
33
+ constructor() {
34
+ super(MultiLayoutViewWebStory.getMetadata(), 'Default');
35
+ }
36
+
37
+ static getMetadata(): StoryMeta {
38
+ return multiLayoutViewMeta;
39
+ }
40
+
41
+ initialize(): void {
42
+ this._view = document.createElement('adw-multi-layout-view');
43
+ this._view.style.width = '420px';
44
+ this._view.style.height = '220px';
45
+ // The FIRST declared layout is the one made current, the way `add_layout` does it.
46
+ for (const [name, collapsed] of [
47
+ ['wide', false],
48
+ ['narrow', true],
49
+ ] as const) {
50
+ const layout = arrangement(collapsed);
51
+ layout.setAttribute('name', name);
52
+ this._view.appendChild(layout);
53
+ }
54
+
55
+ const inbox = page('Inbox', '12 unread');
56
+ inbox.setAttribute('slot', PRIMARY);
57
+ this._details = page('Message');
58
+ this._details.setAttribute('slot', SECONDARY);
59
+ this._view.appendChild(inbox);
60
+ this._view.appendChild(this._details);
61
+
62
+ this._apply();
63
+ this.addContent(this._view);
64
+ }
65
+
66
+ updateArgs(_args: StoryArgs): void {
67
+ this._apply();
68
+ }
69
+
70
+ private _apply(): void {
71
+ if (!this._view || !this._details) return;
72
+ // `visible` is bound one way, child to slot, so hiding the CHILD is what takes the
73
+ // hole with it.
74
+ this._details.toggleAttribute('hidden', !(this.args.showDetails as boolean));
75
+ this._view.setAttribute('layout-name', this.args.layoutName as string);
76
+ }
77
+ }
78
+
79
+ /** A page with a title and a line of text — a stand-in for the GTK list the story builds. */
80
+ function page(title: string, subtitle = ''): HTMLElement {
81
+ const el = document.createElement('adw-navigation-page');
82
+ el.setAttribute('title', title);
83
+ el.setAttribute('tag', title.toLowerCase());
84
+ const box = document.createElement('gtk-box');
85
+ box.setAttribute('orientation', 'vertical');
86
+ const row = document.createElement('adw-action-row');
87
+ row.setAttribute('title', title);
88
+ if (subtitle !== '') row.setAttribute('subtitle', subtitle);
89
+ box.appendChild(row);
90
+ el.appendChild(box);
91
+ return el;
92
+ }
93
+
94
+ export const MultiLayoutViewWebStories: WebStoryModule = { stories: [MultiLayoutViewWebStory] };
@@ -0,0 +1,57 @@
1
+ // Browser port of the Overlay story. Shares metadata with overlay.story.ts.
2
+
3
+ import { StoryElement, type StoryArgs, type StoryMeta, type WebStoryModule } from '@gjsify/adwaita-storybook';
4
+ import { overlayMeta } from '../../layout/overlay.meta.js';
5
+
6
+ export class OverlayWebStory extends StoryElement {
7
+ private _overlay: HTMLElement | null = null;
8
+ private _badge: HTMLElement | null = null;
9
+
10
+ constructor() {
11
+ super(OverlayWebStory.getMetadata(), 'Default');
12
+ }
13
+
14
+ static getMetadata(): StoryMeta {
15
+ return overlayMeta;
16
+ }
17
+
18
+ initialize(): void {
19
+ this._overlay = document.createElement('gtk-overlay');
20
+ this._overlay.style.width = '260px';
21
+ this._overlay.style.height = '160px';
22
+
23
+ const main = document.createElement('gtk-label');
24
+ main.setAttribute('label', 'Main child — its size is the overlay');
25
+ main.classList.add('dimmed');
26
+ this._overlay.appendChild(main);
27
+
28
+ this._badge = document.createElement('gtk-label');
29
+ this._badge.setAttribute('slot', 'overlay');
30
+ this._badge.setAttribute('label', '2');
31
+ this._badge.classList.add('osd');
32
+ this._overlay.appendChild(this._badge);
33
+
34
+ this._apply();
35
+ this.addContent(this._overlay);
36
+ }
37
+
38
+ updateArgs(_args: StoryArgs): void {
39
+ this._apply();
40
+ }
41
+
42
+ private _apply(): void {
43
+ if (!this._badge) return;
44
+ // `fill` is `GtkWidget`'s DEFAULT alignment and has no `Gtk.Align` member, so it is
45
+ // spelled as an absent attribute — the same choice the GTK story makes with
46
+ // `unset_property`.
47
+ const align = (value: unknown, name: string) => {
48
+ if (value === 'fill') this._badge?.removeAttribute(name);
49
+ else this._badge?.setAttribute(name, String(value));
50
+ };
51
+ align(this.args.halign, 'halign');
52
+ align(this.args.valign, 'valign');
53
+ this._badge.hidden = !(this.args.showLabel as boolean);
54
+ }
55
+ }
56
+
57
+ export const OverlayWebStories: WebStoryModule = { stories: [OverlayWebStory] };
@@ -0,0 +1,69 @@
1
+ // Browser port of the Paned story. Shares metadata with paned.story.ts.
2
+
3
+ import { StoryElement, type StoryArgs, type StoryMeta, type WebStoryModule } from '@gjsify/adwaita-storybook';
4
+ import { panedMeta } from '../../layout/paned.meta.js';
5
+
6
+ function pane(label: string, request: number): HTMLElement {
7
+ const box = document.createElement('gtk-box');
8
+ box.setAttribute('orientation', 'vertical');
9
+ box.setAttribute('spacing', '4');
10
+ box.style.padding = '12px';
11
+
12
+ const title = document.createElement('gtk-label');
13
+ title.setAttribute('label', label);
14
+ box.appendChild(title);
15
+
16
+ const hint = document.createElement('gtk-label');
17
+ hint.setAttribute('label', `${request}px of size request`);
18
+ hint.classList.add('dimmed');
19
+ box.appendChild(hint);
20
+ return box;
21
+ }
22
+
23
+ export class PanedWebStory extends StoryElement {
24
+ private _paned: HTMLElement | null = null;
25
+
26
+ constructor() {
27
+ super(PanedWebStory.getMetadata(), 'Default');
28
+ }
29
+
30
+ static getMetadata(): StoryMeta {
31
+ return panedMeta;
32
+ }
33
+
34
+ initialize(): void {
35
+ this._paned = document.createElement('gtk-paned');
36
+ this._paned.style.width = '400px';
37
+ this._paned.style.height = '140px';
38
+ this._paned.appendChild(pane('First child', 100));
39
+
40
+ const end = pane('Second child', 300);
41
+ end.setAttribute('slot', 'end');
42
+ this._paned.appendChild(end);
43
+
44
+ this._apply();
45
+ this.addContent(this._paned);
46
+ }
47
+
48
+ updateArgs(_args: StoryArgs): void {
49
+ this._apply();
50
+ }
51
+
52
+ private _apply(): void {
53
+ if (!this._paned) return;
54
+ this._paned.setAttribute('orientation', String(this.args.orientation));
55
+ this._paned.toggleAttribute('wide-handle', this.args.wideHandle as boolean);
56
+ // All four of these default to TRUE in the pspec, so `"false"` is how one is turned
57
+ // off — the same rule `<adw-navigation-view can-pop>` reads. The END child's shrink
58
+ // is not a control: GTK's GtkBuildable sets it alongside the child and there is no
59
+ // second thing to compare it against here.
60
+ this._paned.setAttribute('resize-start-child', this.args.resizeStartChild ? 'true' : 'false');
61
+ this._paned.setAttribute('resize-end-child', this.args.resizeEndChild ? 'true' : 'false');
62
+ this._paned.setAttribute('shrink-start-child', this.args.shrinkStartChild ? 'true' : 'false');
63
+ // `position = -1` is the C's "let the size requests decide" (gtkpaned.c:1874), which
64
+ // is why the control's floor is -1 rather than 0.
65
+ this._paned.setAttribute('position', String(this.args.position));
66
+ }
67
+ }
68
+
69
+ export const PanedWebStories: WebStoryModule = { stories: [PanedWebStory] };
@@ -0,0 +1,54 @@
1
+ // Browser port of the Popover Bin story. Shares metadata with popover-bin.story.ts.
2
+
3
+ import { StoryElement, type StoryArgs, type StoryMeta, type WebStoryModule } from '@gjsify/adwaita-storybook';
4
+ import { POPOVER_BIN_ITEMS, popoverBinMeta } from '../../layout/popover-bin.meta.js';
5
+
6
+ export class PopoverBinWebStory extends StoryElement {
7
+ private _bin!: HTMLElement;
8
+
9
+ constructor() {
10
+ super(PopoverBinWebStory.getMetadata(), 'Default');
11
+ }
12
+
13
+ static getMetadata(): StoryMeta {
14
+ return popoverBinMeta;
15
+ }
16
+
17
+ initialize(): void {
18
+ this._bin = document.createElement('gtk-popover-bin');
19
+
20
+ // A row-shaped child is what `.has-open-popup` is FOR — libadwaita's `_lists.scss`
21
+ // reads it on a list row and `_sidebars.scss` on a sidebar row — and the bin keeps
22
+ // it highlighted while its popup is up.
23
+ const row = document.createElement('gtk-button');
24
+ row.setAttribute('label', 'Right-click me');
25
+ this._bin.appendChild(row);
26
+
27
+ // The Menu key / the action, which is how a keyboard reaches the same popup the
28
+ // gesture does (`gtk_shortcut_trigger_create_for_menu`, gtkpopoverbin.c:643-649).
29
+ this._bin.addEventListener('keydown', (event) => {
30
+ const key = event as KeyboardEvent;
31
+ if (key.key === 'ContextMenu' && !key.shiftKey) {
32
+ key.preventDefault();
33
+ this._bin.dispatchEvent(new CustomEvent('menu.popup', { bubbles: true }));
34
+ const popover = this._bin.querySelector('gtk-popover-menu') as HTMLElement & { open: boolean };
35
+ popover.open = true;
36
+ }
37
+ });
38
+
39
+ this._apply();
40
+ this.addContent(this._bin);
41
+ }
42
+
43
+ updateArgs(_args: StoryArgs): void {
44
+ this._apply();
45
+ }
46
+
47
+ private _apply(): void {
48
+ if (!this._bin) return;
49
+ this._bin.setAttribute('menu-model', JSON.stringify(POPOVER_BIN_ITEMS));
50
+ this._bin.setAttribute('handle-input', String(this.args.handleInput as boolean));
51
+ }
52
+ }
53
+
54
+ export const PopoverBinWebStories: WebStoryModule = { stories: [PopoverBinWebStory] };
@@ -0,0 +1,48 @@
1
+ // Browser port of the Popover Menu story. Shares metadata with popover-menu.story.ts.
2
+
3
+ import { StoryElement, type StoryArgs, type StoryMeta, type WebStoryModule } from '@gjsify/adwaita-storybook';
4
+ import { POPOVER_MENU_ITEMS, popoverMenuMeta } from '../../layout/popover-menu.meta.js';
5
+
6
+ /** The two members the story drives that are properties rather than attributes. */
7
+ interface PopoverSurface extends HTMLElement {
8
+ open: boolean;
9
+ }
10
+
11
+ export class PopoverMenuWebStory extends StoryElement {
12
+ private _anchor!: HTMLButtonElement;
13
+ private _popover!: PopoverSurface;
14
+
15
+ constructor() {
16
+ super(PopoverMenuWebStory.getMetadata(), 'Default');
17
+ }
18
+
19
+ static getMetadata(): StoryMeta {
20
+ return popoverMenuMeta;
21
+ }
22
+
23
+ initialize(): void {
24
+ this._anchor = document.createElement('button');
25
+ this._anchor.textContent = 'Open menu';
26
+ this._popover = document.createElement('gtk-popover-menu') as unknown as PopoverSurface;
27
+ this._popover.setAttribute('menu-model', JSON.stringify(POPOVER_MENU_ITEMS));
28
+ this._anchor.appendChild(this._popover);
29
+ this._apply();
30
+ this.addContent(this._anchor);
31
+ }
32
+
33
+ updateArgs(_args: StoryArgs): void {
34
+ this._apply();
35
+ }
36
+
37
+ private _apply(): void {
38
+ if (!this._popover) return;
39
+ // `start`/`end` are what GTK's LEFT/RIGHT become on a surface placed with logical
40
+ // properties, so one control name serves both renderers.
41
+ this._popover.setAttribute('position', this.args.position as string);
42
+ this._popover.setAttribute('align', this.args.align as string);
43
+ this._popover.setAttribute('autohide', String(this.args.autohide as boolean));
44
+ this._popover.setAttribute('menu-title', this.args.menuTitle as string);
45
+ }
46
+ }
47
+
48
+ export const PopoverMenuWebStories: WebStoryModule = { stories: [PopoverMenuWebStory] };