@gjsify/example-gtk-adwaita-storybook 0.53.0 → 0.55.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 +8093 -3042
  2. package/dist/gjs.js +15 -10
  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,19 @@
1
+ // Shared, renderer-agnostic metadata for the Aspect Frame story. Imported by the GTK
2
+ // renderer (aspect-frame.story.ts) and the browser renderer
3
+ // (browser/layout/aspect-frame.web.ts), so both expose identical controls.
4
+
5
+ import { ControlType, type StoryMeta } from '@gjsify/stories';
6
+
7
+ export const aspectFrameMeta: StoryMeta = {
8
+ title: 'Layout/Aspect Frame',
9
+ description:
10
+ 'Gtk.AspectFrame — one child, given a width/height ratio and a place in the space left over. ' +
11
+ 'obey-child is TRUE by default and takes the ratio from the child itself, so the story starts with ' +
12
+ 'it FALSE or the ratio control would be inert.',
13
+ controls: [
14
+ { name: 'ratio', label: 'Ratio', type: ControlType.RANGE, min: 0.5, max: 3, step: 0.25, defaultValue: 2 },
15
+ { name: 'xalign', label: 'Xalign', type: ControlType.RANGE, min: 0, max: 1, step: 0.5, defaultValue: 0.5 },
16
+ { name: 'yalign', label: 'Yalign', type: ControlType.RANGE, min: 0, max: 1, step: 0.5, defaultValue: 0.5 },
17
+ { name: 'obeyChild', label: 'Obey child', type: ControlType.BOOLEAN, defaultValue: false },
18
+ ],
19
+ };
@@ -0,0 +1,62 @@
1
+ // Gtk.AspectFrame — one child, given a shape and a place.
2
+ // original implementation.
3
+
4
+ import Gtk from 'gi://Gtk?version=4.0';
5
+ import GObject from 'gi://GObject?version=2.0';
6
+ import { type StoryArgs, type StoryMeta, type StoryModule, StoryWidget } from '@gjsify/storybook';
7
+ import { aspectFrameMeta } from './aspect-frame.meta.js';
8
+
9
+ /** Story: a Gtk.AspectFrame over a box, with its ratio and both alignments bound to args. */
10
+ export class AspectFrameStory extends StoryWidget {
11
+ private _frame: Gtk.AspectFrame | null = null;
12
+
13
+ static {
14
+ GObject.registerClass({ GTypeName: 'AdwStorybookAspectFrame' }, AspectFrameStory);
15
+ }
16
+
17
+ constructor() {
18
+ super(StoryWidget.fromMeta(AspectFrameStory.getMetadata(), 'Default'));
19
+ }
20
+
21
+ static getMetadata(): StoryMeta {
22
+ return { ...aspectFrameMeta, component: Gtk.AspectFrame.$gtype };
23
+ }
24
+
25
+ initialize(): void {
26
+ this._frame = new Gtk.AspectFrame({
27
+ hexpand: true,
28
+ valign: Gtk.Align.CENTER,
29
+ width_request: 320,
30
+ height_request: 180,
31
+ });
32
+ const body = new Gtk.Label({
33
+ label: 'The frame gives this child the ratio above, and puts it where xalign and yalign say.',
34
+ });
35
+ body.set_margin_top(12);
36
+ body.set_margin_bottom(12);
37
+ body.set_margin_start(12);
38
+ body.set_margin_end(12);
39
+ body.set_vexpand(true);
40
+ this._frame.set_child(body);
41
+ this._apply();
42
+ this.addContent(this._frame);
43
+ }
44
+
45
+ updateArgs(_args: StoryArgs): void {
46
+ this._apply();
47
+ }
48
+
49
+ private _apply(): void {
50
+ if (!this._frame) return;
51
+ this._frame.ratio = this.args.ratio as number;
52
+ this._frame.xalign = this.args.xalign as number;
53
+ this._frame.yalign = this.args.yalign as number;
54
+ // TRUE makes the child\'s own ratio win and `ratio` inert — set LAST, so the control
55
+ // order above is the order the story reads it in.
56
+ this._frame.obeyChild = this.args.obeyChild as boolean;
57
+ }
58
+ }
59
+
60
+ GObject.type_ensure(AspectFrameStory.$gtype);
61
+
62
+ export const AspectFrameStories: StoryModule = { stories: [AspectFrameStory] };
@@ -0,0 +1,15 @@
1
+ // Shared, renderer-agnostic metadata for the Bin story. Imported by the GTK renderer
2
+ // (bin.story.ts) and the browser renderer (browser/layout/bin.web.ts).
3
+
4
+ import { ControlType, type StoryMeta } from '@gjsify/stories';
5
+
6
+ export const binMeta: StoryMeta = {
7
+ title: 'Layout/Bin',
8
+ description:
9
+ 'Adw.Bin — a widget with exactly one child. It draws nothing of its own and gives the child its whole ' +
10
+ 'allocation; setting a new child replaces the old one.',
11
+ controls: [
12
+ { name: 'label', label: 'Child label', type: ControlType.TEXT, defaultValue: 'The one child of this bin.' },
13
+ { name: 'swap', label: 'Replace the child', type: ControlType.BOOLEAN, defaultValue: false },
14
+ ],
15
+ };
@@ -0,0 +1,56 @@
1
+ // Adw.Bin — one child, replaced rather than stacked.
2
+ // original implementation.
3
+
4
+ import Adw from 'gi://Adw?version=1';
5
+ import Gtk from 'gi://Gtk?version=4.0';
6
+ import GObject from 'gi://GObject?version=2.0';
7
+ import { type StoryArgs, type StoryMeta, type StoryModule, StoryWidget } from '@gjsify/storybook';
8
+ import { binMeta } from './bin.meta.js';
9
+
10
+ /** Story: an Adw.Bin whose child is swapped for another by `set_child`. */
11
+ export class BinStory extends StoryWidget {
12
+ private _bin: Adw.Bin | null = null;
13
+
14
+ static {
15
+ GObject.registerClass({ GTypeName: 'AdwStorybookBin' }, BinStory);
16
+ }
17
+
18
+ constructor() {
19
+ super(StoryWidget.fromMeta(BinStory.getMetadata(), 'Default'));
20
+ }
21
+
22
+ static getMetadata(): StoryMeta {
23
+ return { ...binMeta, component: Adw.Bin.$gtype };
24
+ }
25
+
26
+ initialize(): void {
27
+ this._bin = new Adw.Bin({ widthRequest: 320 });
28
+ this._apply();
29
+ this.addContent(this._bin);
30
+ }
31
+
32
+ updateArgs(_args: StoryArgs): void {
33
+ this._apply();
34
+ }
35
+
36
+ private _apply(): void {
37
+ if (!this._bin) return;
38
+ const swap = this.args.swap as boolean;
39
+ const label = new Gtk.Label({
40
+ label: swap ? 'The first child was replaced, not stacked.' : (this.args.label as string),
41
+ wrap: true,
42
+ marginTop: 18,
43
+ marginBottom: 18,
44
+ marginStart: 18,
45
+ marginEnd: 18,
46
+ });
47
+ const card = new Gtk.Box();
48
+ card.add_css_class('card');
49
+ card.append(label);
50
+ this._bin.child = card;
51
+ }
52
+ }
53
+
54
+ GObject.type_ensure(BinStory.$gtype);
55
+
56
+ export const BinStories: StoryModule = { stories: [BinStory] };
@@ -0,0 +1,38 @@
1
+ // Shared, renderer-agnostic metadata for the Breakpoint Bin story. Imported by the GTK
2
+ // renderer (breakpoint-bin.story.ts) and the browser renderer
3
+ // (browser/layout/breakpoint-bin.web.ts), so both expose identical controls.
4
+
5
+ import { ControlType, type StoryMeta } from '@gjsify/stories';
6
+
7
+ export const breakpointBinMeta: StoryMeta = {
8
+ title: 'Layout/Breakpoint Bin',
9
+ description:
10
+ 'Adw.BreakpointBin gives breakpoints a home without a window: its one child rearranges ' +
11
+ 'itself at a size threshold, and the bin applies the LAST breakpoint whose condition ' +
12
+ 'holds. Resize the stage to see it.',
13
+ controls: [
14
+ {
15
+ name: 'condition',
16
+ label: 'Condition',
17
+ type: ControlType.SELECT,
18
+ options: [
19
+ { label: 'max-width: 480px', value: 'max-width: 480px' },
20
+ { label: 'max-width: 320px', value: 'max-width: 320px' },
21
+ { label: 'max-height: 200px', value: 'max-height: 200px' },
22
+ ],
23
+ defaultValue: 'max-width: 480px',
24
+ },
25
+ {
26
+ name: 'narrowLabel',
27
+ label: 'Narrow label',
28
+ type: ControlType.TEXT,
29
+ defaultValue: 'Narrow',
30
+ },
31
+ {
32
+ name: 'wideLabel',
33
+ label: 'Wide label',
34
+ type: ControlType.TEXT,
35
+ defaultValue: 'Wide',
36
+ },
37
+ ],
38
+ };
@@ -0,0 +1,62 @@
1
+ // Adw.BreakpointBin — a bin whose one child rearranges itself at a size threshold.
2
+ // original implementation.
3
+
4
+ import Adw from 'gi://Adw?version=1';
5
+ import Gtk from 'gi://Gtk?version=4.0';
6
+ import GObject from 'gi://GObject?version=2.0';
7
+ import { type StoryArgs, type StoryMeta, type StoryModule, StoryWidget } from '@gjsify/storybook';
8
+ import { breakpointBinMeta } from './breakpoint-bin.meta.js';
9
+
10
+ /** Story: a label that reads "Narrow" below the condition and "Wide" above it. */
11
+ export class BreakpointBinStory extends StoryWidget {
12
+ private _bin: Adw.BreakpointBin | null = null;
13
+ private _label: Gtk.Label | null = null;
14
+ private _breakpoint: Adw.Breakpoint | null = null;
15
+
16
+ static {
17
+ GObject.registerClass({ GTypeName: 'AdwStorybookBreakpointBin' }, BreakpointBinStory);
18
+ }
19
+
20
+ constructor() {
21
+ super(StoryWidget.fromMeta(BreakpointBinStory.getMetadata(), 'Default'));
22
+ }
23
+
24
+ static getMetadata(): StoryMeta {
25
+ return { ...breakpointBinMeta, component: Adw.BreakpointBin.$gtype };
26
+ }
27
+
28
+ initialize(): void {
29
+ this._label = new Gtk.Label({ label: this.args.wideLabel as string, ellipsize: 3 /* PANGO_ELLIPSIZE_END */ });
30
+ this._label.add_css_class('title-1');
31
+ this._bin = new Adw.BreakpointBin();
32
+ // The C's own advice: a bin carrying breakpoints has no minimum size, so the stage
33
+ // is what decides how much room there is (adw-breakpoint-bin.c:57-61).
34
+ this._bin.set_size_request(150, 60);
35
+ this._bin.set_child(this._label);
36
+
37
+ this._apply();
38
+ this.addContent(this._bin);
39
+ }
40
+
41
+ updateArgs(_args: StoryArgs): void {
42
+ this._apply();
43
+ }
44
+
45
+ /** Rebuild the one breakpoint from the controls, then re-add it to the bin. */
46
+ private _apply(): void {
47
+ if (!this._bin || !this._label) return;
48
+ const condition = Adw.BreakpointCondition.parse(this.args.condition as string);
49
+ if (condition === null) return;
50
+ if (this._breakpoint !== null) this._bin.remove_breakpoint(this._breakpoint);
51
+ this._breakpoint = Adw.Breakpoint.new(condition);
52
+ this._breakpoint.add_setter(this._label, 'label', this.args.narrowLabel as string);
53
+ this._bin.add_breakpoint(this._breakpoint);
54
+ // The wide value is what the markup declared, so a rebuild restores to it rather
55
+ // than to whatever the previous breakpoint left behind.
56
+ this._label.label = this.args.wideLabel as string;
57
+ }
58
+ }
59
+
60
+ GObject.type_ensure(BreakpointBinStory.$gtype);
61
+
62
+ export const BreakpointBinStories: StoryModule = { stories: [BreakpointBinStory] };
@@ -0,0 +1,26 @@
1
+ // Shared, renderer-agnostic metadata for the Center Box story. Imported by the GTK
2
+ // renderer (center-box.story.ts) and the browser renderer
3
+ // (browser/layout/center-box.web.ts), so both expose identical controls.
4
+
5
+ import { ControlType, type StoryMeta } from '@gjsify/stories';
6
+
7
+ export const centerBoxMeta: StoryMeta = {
8
+ title: 'Layout/Center Box',
9
+ description:
10
+ 'Gtk.CenterBox — three widgets, pinned to the start, the centre and the end, with the space between ' +
11
+ 'them going to whichever child can grow. shrink-center-last decides who gives up space first.',
12
+ controls: [
13
+ { name: 'shrinkCenterLast', label: 'Shrink center last', type: ControlType.BOOLEAN, defaultValue: true },
14
+ {
15
+ name: 'baselinePosition',
16
+ label: 'Baseline position',
17
+ type: ControlType.SELECT,
18
+ options: [
19
+ { label: 'Top', value: 'top' },
20
+ { label: 'Center', value: 'center' },
21
+ { label: 'Bottom', value: 'bottom' },
22
+ ],
23
+ defaultValue: 'center',
24
+ },
25
+ ],
26
+ };
@@ -0,0 +1,54 @@
1
+ // Gtk.CenterBox — three widgets pinned start, centre, end.
2
+ // original implementation.
3
+
4
+ import Gtk from 'gi://Gtk?version=4.0';
5
+ import GObject from 'gi://GObject?version=2.0';
6
+ import { type StoryArgs, type StoryMeta, type StoryModule, StoryWidget } from '@gjsify/storybook';
7
+ import { centerBoxMeta } from './center-box.meta.js';
8
+
9
+ /** `Gtk.BaselinePosition`'s three members, by the nick the shared meta carries. */
10
+ const BASELINE_POSITIONS: Record<string, Gtk.BaselinePosition> = {
11
+ top: Gtk.BaselinePosition.TOP,
12
+ center: Gtk.BaselinePosition.CENTER,
13
+ bottom: Gtk.BaselinePosition.BOTTOM,
14
+ };
15
+
16
+ /** Story: a Gtk.CenterBox whose three slots are filled and whose two properties bind args. */
17
+ export class CenterBoxStory extends StoryWidget {
18
+ private _box: Gtk.CenterBox | null = null;
19
+
20
+ static {
21
+ GObject.registerClass({ GTypeName: 'AdwStorybookCenterBox' }, CenterBoxStory);
22
+ }
23
+
24
+ constructor() {
25
+ super(StoryWidget.fromMeta(CenterBoxStory.getMetadata(), 'Default'));
26
+ }
27
+
28
+ static getMetadata(): StoryMeta {
29
+ return { ...centerBoxMeta, component: Gtk.CenterBox.$gtype };
30
+ }
31
+
32
+ initialize(): void {
33
+ this._box = new Gtk.CenterBox({ margin_top: 12, margin_bottom: 12, margin_start: 12, margin_end: 12 });
34
+ this._box.set_start_widget(new Gtk.Label({ label: 'Start', hexpand: false }));
35
+ this._box.set_center_widget(new Gtk.Label({ label: 'Centre', hexpand: true }));
36
+ this._box.set_end_widget(new Gtk.Label({ label: 'End', hexpand: false }));
37
+ this._apply();
38
+ this.addContent(this._box);
39
+ }
40
+
41
+ updateArgs(_args: StoryArgs): void {
42
+ this._apply();
43
+ }
44
+
45
+ private _apply(): void {
46
+ if (!this._box) return;
47
+ this._box.shrinkCenterLast = this.args.shrinkCenterLast as boolean;
48
+ this._box.baselinePosition = BASELINE_POSITIONS[this.args.baselinePosition as string];
49
+ }
50
+ }
51
+
52
+ GObject.type_ensure(CenterBoxStory.$gtype);
53
+
54
+ export const CenterBoxStories: StoryModule = { stories: [CenterBoxStory] };
@@ -0,0 +1,30 @@
1
+ // Shared, renderer-agnostic metadata for the Clamp Scrollable story.
2
+
3
+ import { ControlType, type StoryMeta } from '@gjsify/stories';
4
+
5
+ export const clampScrollableMeta: StoryMeta = {
6
+ title: 'Layout/Clamp Scrollable',
7
+ description:
8
+ 'Adw.ClampScrollable — a clamp whose child scrolls. The scrollbar stays at the edge of the window while ' +
9
+ 'the content is held at a maximum width.',
10
+ controls: [
11
+ {
12
+ name: 'maximumSize',
13
+ label: 'Maximum size',
14
+ type: ControlType.RANGE,
15
+ min: 200,
16
+ max: 600,
17
+ step: 10,
18
+ defaultValue: 400,
19
+ },
20
+ {
21
+ name: 'tighteningThreshold',
22
+ label: 'Tightening threshold',
23
+ type: ControlType.RANGE,
24
+ min: 100,
25
+ max: 600,
26
+ step: 10,
27
+ defaultValue: 300,
28
+ },
29
+ ],
30
+ };
@@ -0,0 +1,51 @@
1
+ // Adw.ClampScrollable — a clamp around a scrolling child.
2
+ // original implementation.
3
+
4
+ import Adw from 'gi://Adw?version=1';
5
+ import Gtk from 'gi://Gtk?version=4.0';
6
+ import GObject from 'gi://GObject?version=2.0';
7
+ import { type StoryArgs, type StoryMeta, type StoryModule, StoryWidget } from '@gjsify/storybook';
8
+ import { clampScrollableMeta } from './clamp-scrollable.meta.js';
9
+
10
+ const LINES = Array.from({ length: 24 }, (_, i) => `Line ${i + 1}: held at the clamp's width while it scrolls.`);
11
+
12
+ /** Story: a Gtk.TextView (a Gtk.Scrollable) inside an Adw.ClampScrollable inside a scrolled window. */
13
+ export class ClampScrollableStory extends StoryWidget {
14
+ private _clamp: Adw.ClampScrollable | null = null;
15
+
16
+ static {
17
+ GObject.registerClass({ GTypeName: 'AdwStorybookClampScrollable' }, ClampScrollableStory);
18
+ }
19
+
20
+ constructor() {
21
+ super(StoryWidget.fromMeta(ClampScrollableStory.getMetadata(), 'Default'));
22
+ }
23
+
24
+ static getMetadata(): StoryMeta {
25
+ return { ...clampScrollableMeta, component: Adw.ClampScrollable.$gtype };
26
+ }
27
+
28
+ initialize(): void {
29
+ const text = new Gtk.TextView({ editable: false, cursorVisible: false, topMargin: 12, bottomMargin: 12 });
30
+ text.buffer.set_text(LINES.join('\n'), -1);
31
+
32
+ this._clamp = new Adw.ClampScrollable({
33
+ maximumSize: this.args.maximumSize as number,
34
+ tighteningThreshold: this.args.tighteningThreshold as number,
35
+ child: text,
36
+ });
37
+
38
+ const scrolled = new Gtk.ScrolledWindow({ child: this._clamp, widthRequest: 640, heightRequest: 240 });
39
+ this.addContent(scrolled);
40
+ }
41
+
42
+ updateArgs(_args: StoryArgs): void {
43
+ if (!this._clamp) return;
44
+ this._clamp.maximumSize = this.args.maximumSize as number;
45
+ this._clamp.tighteningThreshold = this.args.tighteningThreshold as number;
46
+ }
47
+ }
48
+
49
+ GObject.type_ensure(ClampScrollableStory.$gtype);
50
+
51
+ export const ClampScrollableStories: StoryModule = { stories: [ClampScrollableStory] };
@@ -0,0 +1,30 @@
1
+ // Shared, renderer-agnostic metadata for the Expander story. Imported by the GTK renderer
2
+ // (expander.story.ts) and the browser renderer (browser/layout/expander.web.ts), so both
3
+ // expose identical controls.
4
+
5
+ import { ControlType, type StoryMeta } from '@gjsify/stories';
6
+
7
+ export const expanderMeta: StoryMeta = {
8
+ title: 'Layout/Expander',
9
+ description:
10
+ 'Gtk.Expander — a title the user clicks to reveal the child below it. The arrow is its ' +
11
+ 'own CSS node and `:checked` is set on THAT node, not on the widget, which is what ' +
12
+ "libadwaita's _expanders.scss keys the glyph swap on. `use-underline` marks a mnemonic " +
13
+ 'with `_`, and Alt+that character activates the expander.',
14
+ controls: [
15
+ { name: 'expanded', label: 'Expanded', type: ControlType.BOOLEAN, defaultValue: false },
16
+ { name: 'useUnderline', label: 'Label marks a mnemonic', type: ControlType.BOOLEAN, defaultValue: false },
17
+ {
18
+ name: 'label',
19
+ label: 'Label',
20
+ type: ControlType.TEXT,
21
+ defaultValue: '_More options',
22
+ },
23
+ {
24
+ name: 'resizeToplevel',
25
+ label: 'Resize the toplevel',
26
+ type: ControlType.BOOLEAN,
27
+ defaultValue: false,
28
+ },
29
+ ],
30
+ };
@@ -0,0 +1,62 @@
1
+ // Gtk.Expander — the disclosure, with the label's mnemonic and the toplevel-resize flag.
2
+ // original implementation.
3
+
4
+ import Gtk from 'gi://Gtk?version=4.0';
5
+ import GObject from 'gi://GObject?version=2.0';
6
+ import { type StoryArgs, type StoryMeta, type StoryModule, StoryWidget } from '@gjsify/storybook';
7
+ import { expanderMeta } from './expander.meta.js';
8
+
9
+ /** Story: a Gtk.Expander over a small box of rows. */
10
+ export class ExpanderStory extends StoryWidget {
11
+ private _expander: Gtk.Expander | null = null;
12
+
13
+ static {
14
+ GObject.registerClass({ GTypeName: 'AdwStorybookExpander' }, ExpanderStory);
15
+ }
16
+
17
+ constructor() {
18
+ super(StoryWidget.fromMeta(ExpanderStory.getMetadata(), 'Default'));
19
+ }
20
+
21
+ static getMetadata(): StoryMeta {
22
+ return { ...expanderMeta, component: Gtk.Expander.$gtype };
23
+ }
24
+
25
+ initialize(): void {
26
+ const content = new Gtk.Box({
27
+ orientation: Gtk.Orientation.VERTICAL,
28
+ spacing: 6,
29
+ margin_top: 12,
30
+ margin_bottom: 12,
31
+ margin_start: 12,
32
+ margin_end: 12,
33
+ });
34
+ for (const line of ['Notifications', 'Sound', 'Network']) {
35
+ content.append(new Gtk.Label({ label: line }));
36
+ }
37
+
38
+ this._expander = new Gtk.Expander();
39
+ this._expander.set_child(content);
40
+ this._apply();
41
+ this.addContent(this._expander);
42
+ }
43
+
44
+ updateArgs(_args: StoryArgs): void {
45
+ this._apply();
46
+ }
47
+
48
+ private _apply(): void {
49
+ if (!this._expander) return;
50
+ // `set_label` builds a real GtkLabel out of the string with `use_underline` and
51
+ // `use_markup` forwarded to it (gtkexpander.c:974-979), so the two flags are set
52
+ // BEFORE the text — the order the C's own docs give.
53
+ this._expander.use_underline = this.args.useUnderline as boolean;
54
+ this._expander.label = String(this.args.label);
55
+ this._expander.resize_toplevel = this.args.resizeToplevel as boolean;
56
+ this._expander.expanded = this.args.expanded as boolean;
57
+ }
58
+ }
59
+
60
+ GObject.type_ensure(ExpanderStory.$gtype);
61
+
62
+ export const ExpanderStories: StoryModule = { stories: [ExpanderStory] };
@@ -0,0 +1,16 @@
1
+ // Shared, renderer-agnostic metadata for the Fixed story. Imported by the GTK
2
+ // renderer (fixed.story.ts) and the browser renderer (browser/layout/fixed.web.ts),
3
+ // so both expose identical controls.
4
+
5
+ import { ControlType, type StoryMeta } from '@gjsify/stories';
6
+
7
+ export const fixedMeta: StoryMeta = {
8
+ title: 'Layout/Fixed',
9
+ description:
10
+ 'Gtk.Fixed — children at pixel positions, which is the whole of its API: it declares no property of ' +
11
+ 'its own. The two offsets are the arguments of gtk_fixed_put().',
12
+ controls: [
13
+ { name: 'offsetX', label: 'Offset x', type: ControlType.RANGE, min: 0, max: 80, step: 4, defaultValue: 24 },
14
+ { name: 'offsetY', label: 'Offset y', type: ControlType.RANGE, min: 0, max: 80, step: 4, defaultValue: 16 },
15
+ ],
16
+ };
@@ -0,0 +1,54 @@
1
+ // Gtk.Fixed — children at pixel positions.
2
+ // original implementation.
3
+
4
+ import Gtk from 'gi://Gtk?version=4.0';
5
+ import GObject from 'gi://GObject?version=2.0';
6
+ import { type StoryArgs, type StoryMeta, type StoryModule, StoryWidget } from '@gjsify/storybook';
7
+ import { fixedMeta } from './fixed.meta.js';
8
+
9
+ /** Story: two labels in a Gtk.Fixed, both moved to the offsets the args carry. */
10
+ export class FixedStory extends StoryWidget {
11
+ private _fixed: Gtk.Fixed | null = null;
12
+ private _first: Gtk.Label | null = null;
13
+ private _second: Gtk.Label | null = null;
14
+
15
+ static {
16
+ GObject.registerClass({ GTypeName: 'AdwStorybookFixed' }, FixedStory);
17
+ }
18
+
19
+ constructor() {
20
+ super(StoryWidget.fromMeta(FixedStory.getMetadata(), 'Default'));
21
+ }
22
+
23
+ static getMetadata(): StoryMeta {
24
+ return { ...fixedMeta, component: Gtk.Fixed.$gtype };
25
+ }
26
+
27
+ initialize(): void {
28
+ this._fixed = new Gtk.Fixed();
29
+ this._first = new Gtk.Label({ label: 'at (x, y)' });
30
+ this._second = new Gtk.Label({ label: 'at (x + 96, y + 40)' });
31
+ this._fixed.put(this._first, 0, 0);
32
+ this._fixed.put(this._second, 0, 0);
33
+ this._apply();
34
+ this.addContent(this._fixed);
35
+ }
36
+
37
+ updateArgs(_args: StoryArgs): void {
38
+ this._apply();
39
+ }
40
+
41
+ private _apply(): void {
42
+ if (!this._fixed || !this._first || !this._second) return;
43
+ const x = this.args.offsetX as number;
44
+ const y = this.args.offsetY as number;
45
+ // `move` rather than `put`: both children are already in this fixed, and GTK's
46
+ // `gtk_fixed_move` is the method that only relocates.
47
+ this._fixed.move(this._first, x, y);
48
+ this._fixed.move(this._second, x + 96, y + 40);
49
+ }
50
+ }
51
+
52
+ GObject.type_ensure(FixedStory.$gtype);
53
+
54
+ export const FixedStories: StoryModule = { stories: [FixedStory] };
@@ -0,0 +1,24 @@
1
+ // Shared, renderer-agnostic metadata for the Frame story. Imported by the GTK
2
+ // renderer (frame.story.ts) and the browser renderer (browser/layout/frame.web.ts),
3
+ // so both expose identical controls.
4
+
5
+ import { ControlType, type StoryMeta } from '@gjsify/stories';
6
+
7
+ export const frameMeta: StoryMeta = {
8
+ title: 'Layout/Frame',
9
+ description:
10
+ 'Gtk.Frame — a 1px border with a label embedded in its top edge. GTK draws the label as its own ' +
11
+ 'widget above the child, and label-xalign says where across the frame it sits.',
12
+ controls: [
13
+ { name: 'label', label: 'Label', type: ControlType.TEXT, defaultValue: 'Details' },
14
+ {
15
+ name: 'labelXalign',
16
+ label: 'Label xalign',
17
+ type: ControlType.RANGE,
18
+ defaultValue: 0,
19
+ min: 0,
20
+ max: 1,
21
+ step: 0.5,
22
+ },
23
+ ],
24
+ };
@@ -0,0 +1,51 @@
1
+ // Gtk.Frame — a 1px border with a label in its top edge.
2
+ // original implementation.
3
+
4
+ import Gtk from 'gi://Gtk?version=4.0';
5
+ import GObject from 'gi://GObject?version=2.0';
6
+ import { type StoryArgs, type StoryMeta, type StoryModule, StoryWidget } from '@gjsify/storybook';
7
+ import { frameMeta } from './frame.meta.js';
8
+
9
+ /** Story: a Gtk.Frame with its label text and label alignment bound to args. */
10
+ export class FrameStory extends StoryWidget {
11
+ private _frame: Gtk.Frame | null = null;
12
+
13
+ static {
14
+ GObject.registerClass({ GTypeName: 'AdwStorybookFrame' }, FrameStory);
15
+ }
16
+
17
+ constructor() {
18
+ super(StoryWidget.fromMeta(FrameStory.getMetadata(), 'Default'));
19
+ }
20
+
21
+ static getMetadata(): StoryMeta {
22
+ return { ...frameMeta, component: Gtk.Frame.$gtype };
23
+ }
24
+
25
+ initialize(): void {
26
+ this._frame = new Gtk.Frame({ halign: Gtk.Align.CENTER });
27
+ const body = new Gtk.Label({ label: 'A framed region: the label sits in the top edge of the border.' });
28
+ body.set_margin_top(12);
29
+ body.set_margin_bottom(12);
30
+ body.set_margin_start(12);
31
+ body.set_margin_end(12);
32
+ this._frame.set_child(body);
33
+ this._apply();
34
+ this.addContent(this._frame);
35
+ }
36
+
37
+ updateArgs(_args: StoryArgs): void {
38
+ this._apply();
39
+ }
40
+
41
+ private _apply(): void {
42
+ if (!this._frame) return;
43
+ this._frame.label = this.args.label as string;
44
+ // `gtk_frame_set_label_align` clamps to 0…1, exactly as the pspec does.
45
+ this._frame.set_label_align(this.args.labelXalign as number);
46
+ }
47
+ }
48
+
49
+ GObject.type_ensure(FrameStory.$gtype);
50
+
51
+ export const FrameStories: StoryModule = { stories: [FrameStory] };