@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,48 @@
1
+ // Gtk.SearchBar — the strip that reveals a search entry when search starts.
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 { searchBarMeta } from './search-bar.meta.js';
8
+
9
+ /** Story: a Gtk.SearchBar over a Gtk.SearchEntry, its two properties bound to args. */
10
+ export class SearchBarStory extends StoryWidget {
11
+ private _bar: Gtk.SearchBar | null = null;
12
+ private _entry: Gtk.SearchEntry | null = null;
13
+
14
+ static {
15
+ GObject.registerClass({ GTypeName: 'AdwStorybookSearchBar' }, SearchBarStory);
16
+ }
17
+
18
+ constructor() {
19
+ super(StoryWidget.fromMeta(SearchBarStory.getMetadata(), 'Default'));
20
+ }
21
+
22
+ static getMetadata(): StoryMeta {
23
+ return { ...searchBarMeta, component: Gtk.SearchBar.$gtype };
24
+ }
25
+
26
+ initialize(): void {
27
+ this._entry = new Gtk.SearchEntry({ hexpand: true });
28
+ this._bar = new Gtk.SearchBar({ child: this._entry });
29
+ // The entry is the bar's own child here, which is the case `connect_entry` handles
30
+ // without a call (gtksearchbar.c:611-625).
31
+ this._apply();
32
+ this.addContent(this._bar);
33
+ }
34
+
35
+ updateArgs(_args: StoryArgs): void {
36
+ this._apply();
37
+ }
38
+
39
+ private _apply(): void {
40
+ if (!this._bar) return;
41
+ this._bar.search_mode_enabled = this.args.searchModeEnabled as boolean;
42
+ this._bar.show_close_button = this.args.showCloseButton as boolean;
43
+ }
44
+ }
45
+
46
+ GObject.type_ensure(SearchBarStory.$gtype);
47
+
48
+ export const SearchBarStories: StoryModule = { stories: [SearchBarStory] };
@@ -0,0 +1,49 @@
1
+ // Shared, renderer-agnostic metadata for the Text View story. Imported by the GTK
2
+ // renderer (text-view.story.ts) and the browser renderer (browser/text/text-view.web.ts),
3
+ // so both expose identical controls.
4
+
5
+ import { ControlType, type StoryMeta } from '@gjsify/stories';
6
+
7
+ export const textViewMeta: StoryMeta = {
8
+ title: 'Text/Text View',
9
+ description:
10
+ 'Gtk.TextView — the multi-line editor. Its text lives in a Gtk.TextBuffer rather than in a ' +
11
+ "property, wrap-mode and justification are Pango's, and accepts-tab defaults to TRUE, which is " +
12
+ "the opposite of a browser's.",
13
+ controls: [
14
+ {
15
+ name: 'text',
16
+ label: 'Text',
17
+ type: ControlType.TEXT,
18
+ defaultValue: 'A text view holds as many lines as it is given.\nTab inserts a tab character.',
19
+ },
20
+ {
21
+ name: 'wrapMode',
22
+ label: 'Wrap mode',
23
+ type: ControlType.SELECT,
24
+ options: [
25
+ { label: 'None', value: 'none' },
26
+ { label: 'Char', value: 'char' },
27
+ { label: 'Word', value: 'word' },
28
+ { label: 'Word or char', value: 'word-char' },
29
+ ],
30
+ defaultValue: 'none',
31
+ },
32
+ {
33
+ name: 'justification',
34
+ label: 'Justification',
35
+ type: ControlType.SELECT,
36
+ options: [
37
+ { label: 'Left', value: 'left' },
38
+ { label: 'Right', value: 'right' },
39
+ { label: 'Center', value: 'center' },
40
+ { label: 'Fill', value: 'fill' },
41
+ ],
42
+ defaultValue: 'left',
43
+ },
44
+ { name: 'monospace', label: 'Monospace', type: ControlType.BOOLEAN, defaultValue: false },
45
+ { name: 'acceptsTab', label: 'Tab inserts a tab', type: ControlType.BOOLEAN, defaultValue: true },
46
+ { name: 'cursorVisible', label: 'Show cursor', type: ControlType.BOOLEAN, defaultValue: true },
47
+ { name: 'topMargin', label: 'Top margin', type: ControlType.NUMBER, defaultValue: 6 },
48
+ ],
49
+ };
@@ -0,0 +1,69 @@
1
+ // Gtk.TextView — the multi-line editor, its Pango layout properties and the buffer's text.
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 { textViewMeta } from './text-view.meta.js';
8
+
9
+ /** Story: a Gtk.TextView in a scrolled window, its buffer and layout properties bound to args. */
10
+ export class TextViewStory extends StoryWidget {
11
+ private _buffer: Gtk.TextBuffer | null = null;
12
+ private _view: Gtk.TextView | null = null;
13
+
14
+ static {
15
+ GObject.registerClass({ GTypeName: 'AdwStorybookTextView' }, TextViewStory);
16
+ }
17
+
18
+ constructor() {
19
+ super(StoryWidget.fromMeta(TextViewStory.getMetadata(), 'Default'));
20
+ }
21
+
22
+ static getMetadata(): StoryMeta {
23
+ return { ...textViewMeta, component: Gtk.TextView.$gtype };
24
+ }
25
+
26
+ initialize(): void {
27
+ // The text is the BUFFER's, not a property of the view's — which is why the browser
28
+ // element takes its text from its light DOM and why this block is refused a static tree.
29
+ this._buffer = new Gtk.TextBuffer();
30
+ this._view = new Gtk.TextView({
31
+ buffer: this._buffer,
32
+ hexpand: true,
33
+ vexpand: false,
34
+ top_margin: 6,
35
+ });
36
+ const scroller = new Gtk.ScrolledWindow({
37
+ hscrollbar_policy: Gtk.PolicyType.AUTOMATIC,
38
+ vscrollbar_policy: Gtk.PolicyType.AUTOMATIC,
39
+ hexpand: true,
40
+ vexpand: false,
41
+ child: this._view,
42
+ });
43
+ scroller.set_size_request(320, -1);
44
+ this._apply();
45
+ this.addContent(scroller);
46
+ }
47
+
48
+ updateArgs(_args: StoryArgs): void {
49
+ this._apply();
50
+ }
51
+
52
+ private _apply(): void {
53
+ if (!this._buffer || !this._view) return;
54
+ const text = this.args.text as string;
55
+ if (this._buffer.text !== text) {
56
+ this._buffer.text = text;
57
+ }
58
+ this._view.wrap_mode = (this.args.wrapMode ?? 'none') as Gtk.WrapMode;
59
+ this._view.justification = (this.args.justification ?? 'left') as Gtk.Justification;
60
+ this._view.monospace = this.args.monospace as boolean;
61
+ this._view.accepts_tab = this.args.acceptsTab as boolean;
62
+ this._view.cursor_visible = this.args.cursorVisible as boolean;
63
+ this._view.top_margin = Number(this.args.topMargin ?? 0);
64
+ }
65
+ }
66
+
67
+ GObject.type_ensure(TextViewStory.$gtype);
68
+
69
+ export const TextViewStories: StoryModule = { stories: [TextViewStory] };
@@ -0,0 +1,21 @@
1
+ // Shared, renderer-agnostic metadata for the Text story. Imported by the GTK
2
+ // renderer (text.story.ts) and the browser renderer (browser/text/text.web.ts),
3
+ // so both expose identical controls.
4
+
5
+ import { ControlType, type StoryMeta } from '@gjsify/stories';
6
+
7
+ export const textMeta: StoryMeta = {
8
+ title: 'Text/Text',
9
+ description:
10
+ 'Gtk.Text — the single-line text widget every Gtk.Entry is built on. Standalone it is a ' +
11
+ 'field with a placeholder and a length limit; visibility=false masks it, propagate-text-width ' +
12
+ 'grows it with its text.',
13
+ controls: [
14
+ { name: 'text', label: 'Text', type: ControlType.TEXT, defaultValue: 'Ada Lovelace' },
15
+ { name: 'placeholderText', label: 'Placeholder', type: ControlType.TEXT, defaultValue: '' },
16
+ { name: 'editable', label: 'Editable', type: ControlType.BOOLEAN, defaultValue: true },
17
+ { name: 'visibility', label: 'Visible', type: ControlType.BOOLEAN, defaultValue: true },
18
+ { name: 'maxLength', label: 'Max length (0 = none)', type: ControlType.NUMBER, defaultValue: 0 },
19
+ { name: 'propagateTextWidth', label: 'Grow with text', type: ControlType.BOOLEAN, defaultValue: false },
20
+ ],
21
+ };
@@ -0,0 +1,50 @@
1
+ // Gtk.Text — the single-line text widget every Gtk.Entry is built on, shown standalone.
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 { textMeta } from './text.meta.js';
8
+
9
+ /** Story: a Gtk.Text with its text, placeholder, mask, limit and width policy bound to args. */
10
+ export class TextStory extends StoryWidget {
11
+ private _text: Gtk.Text | null = null;
12
+
13
+ static {
14
+ GObject.registerClass({ GTypeName: 'AdwStorybookText' }, TextStory);
15
+ }
16
+
17
+ constructor() {
18
+ super(StoryWidget.fromMeta(TextStory.getMetadata(), 'Default'));
19
+ }
20
+
21
+ static getMetadata(): StoryMeta {
22
+ return { ...textMeta, component: Gtk.Text.$gtype };
23
+ }
24
+
25
+ initialize(): void {
26
+ this._text = new Gtk.Text({ halign: Gtk.Align.CENTER });
27
+ this._apply();
28
+ this.addContent(this._text);
29
+ }
30
+
31
+ updateArgs(_args: StoryArgs): void {
32
+ this._apply();
33
+ }
34
+
35
+ private _apply(): void {
36
+ if (!this._text) return;
37
+ // The two booleans GTK's pspec defaults to TRUE, written through the PROPERTY rather
38
+ // than a bare attribute, exactly as the element reads them (gtktext.c:1774-1805).
39
+ this._text.text = this.args.text as string;
40
+ this._text.placeholder_text = this.args.placeholderText as string;
41
+ this._text.editable = this.args.editable as boolean;
42
+ this._text.visibility = this.args.visibility as boolean;
43
+ this._text.max_length = Number(this.args.maxLength ?? 0);
44
+ this._text.propagate_text_width = this.args.propagateTextWidth as boolean;
45
+ }
46
+ }
47
+
48
+ GObject.type_ensure(TextStory.$gtype);
49
+
50
+ export const TextStories: StoryModule = { stories: [TextStory] };
@@ -0,0 +1,44 @@
1
+ // Shared, renderer-agnostic metadata for the Notebook story. Imported by the GTK
2
+ // renderer (notebook.story.ts) and the browser renderer
3
+ // (browser/view-switching/notebook.web.ts) so the two expose identical controls.
4
+
5
+ import { ControlType, type StoryMeta } from '@gjsify/stories';
6
+
7
+ /**
8
+ * The pages both renderers build. The third carries NO `tab-label` on purpose — that is
9
+ * the page `gtk_notebook_update_labels` numbers "Page 3" (gtknotebook.c:4353-4373), the
10
+ * fallback a page gets rather than no tab at all.
11
+ */
12
+ export const NOTEBOOK_PAGES = [
13
+ { name: 'overview', label: 'Overview', body: 'A notebook brings its own tab strip.' },
14
+ { name: 'activity', label: 'Activity', body: 'tab-pos says which edge the strip is on.' },
15
+ { name: 'notes', label: '', body: 'No tab-label: the tab reads "Page 3".' },
16
+ ] as const;
17
+
18
+ export const notebookMeta: StoryMeta = {
19
+ title: 'View Switching/Notebook',
20
+ description:
21
+ 'Gtk.Notebook — the older page container, a stack that brings its own tab bar. `tab-pos` ' +
22
+ 'picks the edge (top, bottom, left, right), `show-tabs` takes the strip away, `show-border` ' +
23
+ 'is the bevel around the pages — a CSS class in C — and `page` is the current page by INDEX ' +
24
+ 'rather than by name. A GtkNotebookPage is a GObject rather than a widget, so its tab-label ' +
25
+ 'and friends live on the page itself, and a page without one gets the number "Page N" as ' +
26
+ 'its tab text. `enable-popup` puts the pages in a right-click menu.',
27
+ controls: [
28
+ {
29
+ name: 'tabPos',
30
+ label: 'Tab position',
31
+ type: ControlType.SELECT,
32
+ options: [
33
+ { label: 'Top', value: 'top' },
34
+ { label: 'Bottom', value: 'bottom' },
35
+ { label: 'Left', value: 'left' },
36
+ { label: 'Right', value: 'right' },
37
+ ],
38
+ defaultValue: 'top',
39
+ },
40
+ { name: 'showTabs', label: 'Show tabs', type: ControlType.BOOLEAN, defaultValue: true },
41
+ { name: 'showBorder', label: 'Show border', type: ControlType.BOOLEAN, defaultValue: true },
42
+ { name: 'enablePopup', label: 'Enable popup (right-click)', type: ControlType.BOOLEAN, defaultValue: false },
43
+ ],
44
+ };
@@ -0,0 +1,77 @@
1
+ // Gtk.Notebook — the older page container, which brings its own tab bar.
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 { NOTEBOOK_PAGES, notebookMeta } from './notebook.meta.js';
8
+
9
+ /** The `GtkPositionType` nicks this story offers (gtknotebook.c:1113-1117). */
10
+ const POSITIONS: Readonly<Record<string, Gtk.PositionType>> = {
11
+ top: Gtk.PositionType.TOP,
12
+ bottom: Gtk.PositionType.BOTTOM,
13
+ left: Gtk.PositionType.LEFT,
14
+ right: Gtk.PositionType.RIGHT,
15
+ };
16
+
17
+ /** Story: a three-page Gtk.Notebook whose tab strip moves with `tab-pos`. */
18
+ export class NotebookStory extends StoryWidget {
19
+ private _notebook: Gtk.Notebook | null = null;
20
+
21
+ static {
22
+ GObject.registerClass({ GTypeName: 'AdwStorybookNotebook' }, NotebookStory);
23
+ }
24
+
25
+ constructor() {
26
+ super(StoryWidget.fromMeta(NotebookStory.getMetadata(), 'Default'));
27
+ }
28
+
29
+ static getMetadata(): StoryMeta {
30
+ return { ...notebookMeta, component: Gtk.Notebook.$gtype };
31
+ }
32
+
33
+ initialize(): void {
34
+ this._notebook = new Gtk.Notebook({ vexpand: true, widthRequest: 480, heightRequest: 320 });
35
+
36
+ for (const page of NOTEBOOK_PAGES) {
37
+ const box = new Gtk.Box({
38
+ orientation: Gtk.Orientation.VERTICAL,
39
+ halign: Gtk.Align.CENTER,
40
+ valign: Gtk.Align.CENTER,
41
+ spacing: 6,
42
+ });
43
+ box.append(new Gtk.Label({ label: page.label || page.name, cssClasses: ['title-4'] }));
44
+ box.append(new Gtk.Label({ label: page.body, cssClasses: ['title-2'] }));
45
+
46
+ // `append_page_menu` rather than `append_page`: a GtkNotebookPage is a GObject
47
+ // whose tab-label AND menu-label are two properties, and only the `_menu` form
48
+ // takes both (gtknotebook.c:5871-5884). The third page passes `null` for the
49
+ // tab label, which is what makes C number it "Page 3" instead of drawing no
50
+ // tab at all (`gtk_notebook_update_labels`, gtknotebook.c:4353-4373).
51
+ const label = page.label ? new Gtk.Label({ label: page.label }) : null;
52
+ const menu = new Gtk.Label({ label: page.label || page.name });
53
+ this._notebook.append_page_menu(box, label, menu);
54
+ }
55
+
56
+ this._apply();
57
+ this.addContent(this._notebook);
58
+ }
59
+
60
+ updateArgs(_args: StoryArgs): void {
61
+ this._apply();
62
+ }
63
+
64
+ private _apply(): void {
65
+ if (!this._notebook) return;
66
+ // The ORDER is the C's own: `tab_pos` is read by the layout, so it goes first, and
67
+ // `show-border` last because it is a style class either way (gtknotebook.c:6134).
68
+ this._notebook.tab_pos = POSITIONS[this.args.tabPos as string] ?? Gtk.PositionType.TOP;
69
+ this._notebook.show_tabs = this.args.showTabs as boolean;
70
+ this._notebook.enable_popup = this.args.enablePopup as boolean;
71
+ this._notebook.show_border = this.args.showBorder as boolean;
72
+ }
73
+ }
74
+
75
+ GObject.type_ensure(NotebookStory.$gtype);
76
+
77
+ export const NotebookStories: StoryModule = { stories: [NotebookStory] };
@@ -0,0 +1,50 @@
1
+ // Shared, renderer-agnostic metadata for the Stack Sidebar story. Imported by the
2
+ // GTK renderer (stack-sidebar.story.ts) and the browser renderer
3
+ // (browser/view-switching/stack-sidebar.web.ts) so the two expose identical controls.
4
+
5
+ import { ControlType, type StoryMeta } from '@gjsify/stories';
6
+
7
+ /**
8
+ * The pages both renderers build. Two carry a title, one carries ONLY an icon — which
9
+ * is the page the sidebar skips and the switcher shows, the one visible difference
10
+ * between the two widgets' visibility rules (`update_row`, gtkstacksidebar.c:186,
11
+ * against `update_button`, gtkstackswitcher.c:200).
12
+ */
13
+ // ONE LINE PER PAGE, deliberately: `check-storybook-category-order.mjs` reads the
14
+ // categories out of every `^\s*title: '…'` line in a `*.meta.ts`, so a page table
15
+ // formatted one field per line reads as a category named after its first page. The
16
+ // lines are kept under the print width so the formatter does not wrap them back.
17
+ export const STACK_SIDEBAR_PAGES = [
18
+ { name: 'inbox', title: 'Inbox', icon: 'mail-unread-symbolic', attn: false, body: 'Three unread conversations.' },
19
+ { name: 'starred', title: 'Starred', icon: 'starred-symbolic', attn: false, body: 'Messages marked important.' },
20
+ { name: 'drafts', title: 'Drafts', icon: 'document-edit-symbolic', attn: true, body: 'One draft needs attention.' },
21
+ {
22
+ name: 'settings',
23
+ title: '',
24
+ icon: 'preferences-system-symbolic',
25
+ attn: false,
26
+ body: 'No row: a title is the row.',
27
+ },
28
+ ] as const;
29
+
30
+ export const stackSidebarMeta: StoryMeta = {
31
+ title: 'View Switching/Stack Sidebar',
32
+ description:
33
+ "Gtk.StackSidebar — a vertical list of a Gtk.Stack's pages, the sidebar counterpart of the stack " +
34
+ "switcher. A row is made of the page's TITLE alone: `update_row` never reads `icon-name`, so the page " +
35
+ 'with only an icon at the end of this story gets no row at all, where the switcher would show an icon ' +
36
+ 'button for it. `needs-attention` puts a dot in front of the label.',
37
+ controls: [
38
+ {
39
+ name: 'transitionType',
40
+ label: 'Transition type',
41
+ type: ControlType.SELECT,
42
+ options: [
43
+ { label: 'None', value: 'none' },
44
+ { label: 'Crossfade', value: 'crossfade' },
45
+ { label: 'Slide left / right', value: 'slide-left-right' },
46
+ ],
47
+ defaultValue: 'slide-left-right',
48
+ },
49
+ ],
50
+ };
@@ -0,0 +1,85 @@
1
+ // Gtk.StackSidebar — a list of a Gtk.Stack's pages beside the stack itself.
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 { STACK_SIDEBAR_PAGES, stackSidebarMeta } from './stack-sidebar.meta.js';
8
+
9
+ /** The nicks this story offers, as the C enum members they name (gtkstack.c:95-121). */
10
+ const TRANSITIONS: Readonly<Record<string, Gtk.StackTransitionType>> = {
11
+ none: Gtk.StackTransitionType.NONE,
12
+ crossfade: Gtk.StackTransitionType.CROSSFADE,
13
+ 'slide-left-right': Gtk.StackTransitionType.SLIDE_LEFT_RIGHT,
14
+ };
15
+
16
+ /** Story: a four-page Gtk.Stack with a Gtk.StackSidebar down its left-hand side. */
17
+ export class StackSidebarStory extends StoryWidget {
18
+ private _stack: Gtk.Stack | null = null;
19
+
20
+ static {
21
+ GObject.registerClass({ GTypeName: 'AdwStorybookStackSidebar' }, StackSidebarStory);
22
+ }
23
+
24
+ constructor() {
25
+ super(StoryWidget.fromMeta(StackSidebarStory.getMetadata(), 'Default'));
26
+ }
27
+
28
+ static getMetadata(): StoryMeta {
29
+ return { ...stackSidebarMeta, component: Gtk.StackSidebar.$gtype };
30
+ }
31
+
32
+ initialize(): void {
33
+ this._stack = new Gtk.Stack({ vexpand: true, transitionDuration: 200 });
34
+
35
+ for (const page of STACK_SIDEBAR_PAGES) {
36
+ const label = new Gtk.Label({ label: page.body });
37
+ label.add_css_class('title-2');
38
+ const box = new Gtk.Box({
39
+ orientation: Gtk.Orientation.VERTICAL,
40
+ halign: Gtk.Align.CENTER,
41
+ valign: Gtk.Align.CENTER,
42
+ spacing: 6,
43
+ });
44
+ box.append(new Gtk.Label({ label: page.title || page.name, cssClasses: ['title-4'] }));
45
+ box.append(label);
46
+
47
+ // The last page carries an icon and NO title, which is the page a sidebar row
48
+ // cannot represent: `update_row` reads title, needs-attention and visible, and
49
+ // never `icon-name` (gtkstacksidebar.c:178-184).
50
+ const info = this._stack.add_titled(box, page.name, page.title);
51
+ info.icon_name = page.icon;
52
+ info.needs_attention = page.attn;
53
+ info.use_underline = true;
54
+ }
55
+
56
+ const sidebar = new Gtk.StackSidebar({ stack: this._stack });
57
+
58
+ // The pane a sidebar belongs in, which is where GTK puts one too.
59
+ const pane = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL, spacing: 0 });
60
+ pane.append(sidebar);
61
+
62
+ const root = new Gtk.Paned({ orientation: Gtk.Orientation.HORIZONTAL, widthRequest: 480, heightRequest: 320 });
63
+ root.set_start_child(pane);
64
+ root.set_end_child(this._stack);
65
+ root.set_position(180);
66
+
67
+ this._apply();
68
+ this.addContent(root);
69
+ }
70
+
71
+ updateArgs(_args: StoryArgs): void {
72
+ this._apply();
73
+ }
74
+
75
+ private _apply(): void {
76
+ if (!this._stack) return;
77
+ // `transition-type` FIRST: a new type is what `set_visible_child` consults when
78
+ // it resolves a two-way nick (gtkstack.c:1546-1561).
79
+ this._stack.transition_type = TRANSITIONS[this.args.transitionType as string] ?? Gtk.StackTransitionType.NONE;
80
+ }
81
+ }
82
+
83
+ GObject.type_ensure(StackSidebarStory.$gtype);
84
+
85
+ export const StackSidebarStories: StoryModule = { stories: [StackSidebarStory] };
@@ -0,0 +1,53 @@
1
+ // Shared, renderer-agnostic metadata for the Stack Switcher story. Imported by the
2
+ // GTK renderer (stack-switcher.story.ts) and the browser renderer
3
+ // (browser/view-switching/stack-switcher.web.ts) so the two expose identical controls.
4
+
5
+ import { ControlType, type StoryMeta } from '@gjsify/stories';
6
+
7
+ /**
8
+ * The pages both renderers build. `icon` is empty for a text-only page and
9
+ * `attn` marks the page `needs-attention`, which is what the switcher draws a dot
10
+ * for — both are the `rebuild_child` / `update_button` branches of the widget.
11
+ */
12
+ // ONE LINE PER PAGE, deliberately: `check-storybook-category-order.mjs` reads the
13
+ // categories out of every `^\s*title: '…'` line in a `*.meta.ts`, so a page table
14
+ // formatted one field per line reads as a category named after its first page. The
15
+ // lines are kept under the print width so the formatter does not wrap them back.
16
+ export const STACK_SWITCHER_PAGES = [
17
+ { name: 'inbox', title: 'Inbox', icon: 'mail-unread-symbolic', attn: false, body: 'Three unread conversations.' },
18
+ { name: 'starred', title: 'Starred', icon: 'starred-symbolic', attn: false, body: 'Messages marked important.' },
19
+ { name: 'archive', title: 'Archive', icon: '', attn: false, body: 'Older conversations kept for reference.' },
20
+ { name: 'drafts', title: '', icon: 'document-edit-symbolic', attn: true, body: 'One draft needs your attention.' },
21
+ ] as const;
22
+
23
+ export const stackSwitcherMeta: StoryMeta = {
24
+ title: 'View Switching/Stack Switcher',
25
+ description:
26
+ 'Gtk.StackSwitcher — a linked row of toggle buttons, one per page of a Gtk.Stack. A page with a title ' +
27
+ 'and no icon gets a label button; one with an icon and no title gets an icon button and puts the title on ' +
28
+ 'the switcher as a tooltip; a page with NEITHER is left out of the row entirely. `orientation` turns the ' +
29
+ 'row vertical, and `needs-attention` on a page puts a dot on its button.',
30
+ controls: [
31
+ {
32
+ name: 'orientation',
33
+ label: 'Orientation',
34
+ type: ControlType.SELECT,
35
+ options: [
36
+ { label: 'Horizontal', value: 'horizontal' },
37
+ { label: 'Vertical', value: 'vertical' },
38
+ ],
39
+ defaultValue: 'horizontal',
40
+ },
41
+ {
42
+ name: 'transitionType',
43
+ label: 'Transition type',
44
+ type: ControlType.SELECT,
45
+ options: [
46
+ { label: 'None', value: 'none' },
47
+ { label: 'Crossfade', value: 'crossfade' },
48
+ { label: 'Slide left / right', value: 'slide-left-right' },
49
+ ],
50
+ defaultValue: 'slide-left-right',
51
+ },
52
+ ],
53
+ };
@@ -0,0 +1,95 @@
1
+ // Gtk.StackSwitcher — a linked row of toggle buttons switching over a Gtk.Stack.
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 { STACK_SWITCHER_PAGES, stackSwitcherMeta } from './stack-switcher.meta.js';
8
+
9
+ /** The nicks this story offers, as the C enum members they name (gtkstack.c:95-121). */
10
+ const TRANSITIONS: Readonly<Record<string, Gtk.StackTransitionType>> = {
11
+ none: Gtk.StackTransitionType.NONE,
12
+ crossfade: Gtk.StackTransitionType.CROSSFADE,
13
+ 'slide-left-right': Gtk.StackTransitionType.SLIDE_LEFT_RIGHT,
14
+ };
15
+
16
+ /** Story: a four-page Gtk.Stack under a Gtk.StackSwitcher, covering both button shapes. */
17
+ export class StackSwitcherStory extends StoryWidget {
18
+ private _stack: Gtk.Stack | null = null;
19
+ private _switcher: Gtk.StackSwitcher | null = null;
20
+
21
+ static {
22
+ GObject.registerClass({ GTypeName: 'AdwStorybookStackSwitcher' }, StackSwitcherStory);
23
+ }
24
+
25
+ constructor() {
26
+ super(StoryWidget.fromMeta(StackSwitcherStory.getMetadata(), 'Default'));
27
+ }
28
+
29
+ static getMetadata(): StoryMeta {
30
+ return { ...stackSwitcherMeta, component: Gtk.StackSwitcher.$gtype };
31
+ }
32
+
33
+ initialize(): void {
34
+ this._stack = new Gtk.Stack({ vexpand: true, transitionDuration: 200 });
35
+
36
+ for (const page of STACK_SWITCHER_PAGES) {
37
+ const label = new Gtk.Label({ label: page.body });
38
+ label.add_css_class('title-2');
39
+ const box = new Gtk.Box({
40
+ orientation: Gtk.Orientation.VERTICAL,
41
+ halign: Gtk.Align.CENTER,
42
+ valign: Gtk.Align.CENTER,
43
+ spacing: 6,
44
+ });
45
+ box.append(new Gtk.Label({ label: page.title || page.name, cssClasses: ['title-4'] }));
46
+ box.append(label);
47
+
48
+ // The four shapes `rebuild_child` and `update_row` branch on
49
+ // (gtkstackswitcher.c:137-207): title + icon, title only, icon only, and
50
+ // the last page with `needs-attention`.
51
+ if (page.icon) {
52
+ const info = this._stack.add_titled(box, page.name, page.title);
53
+ info.icon_name = page.icon;
54
+ info.needs_attention = page.attn;
55
+ info.use_underline = true;
56
+ } else {
57
+ const info = this._stack.add_titled(box, page.name, page.title);
58
+ info.needs_attention = page.attn;
59
+ info.use_underline = true;
60
+ }
61
+ }
62
+
63
+ this._switcher = new Gtk.StackSwitcher({ stack: this._stack, halign: Gtk.Align.CENTER });
64
+
65
+ const root = new Gtk.Box({
66
+ orientation: Gtk.Orientation.VERTICAL,
67
+ spacing: 12,
68
+ widthRequest: 480,
69
+ heightRequest: 320,
70
+ });
71
+ root.append(this._switcher);
72
+ root.append(this._stack);
73
+
74
+ this._apply();
75
+ this.addContent(root);
76
+ }
77
+
78
+ updateArgs(_args: StoryArgs): void {
79
+ this._apply();
80
+ }
81
+
82
+ private _apply(): void {
83
+ if (!this._stack || !this._switcher) return;
84
+ // `transition-type` FIRST: a new type is what `set_visible_child` consults when
85
+ // it resolves a two-way nick (gtkstack.c:1546-1561).
86
+ this._stack.transition_type = TRANSITIONS[this.args.transitionType as string] ?? Gtk.StackTransitionType.NONE;
87
+ // `GtkStackSwitcher` is a GtkOrientable (gtkstackswitcher.c:47).
88
+ this._switcher.orientation =
89
+ (this.args.orientation as string) === 'vertical' ? Gtk.Orientation.VERTICAL : Gtk.Orientation.HORIZONTAL;
90
+ }
91
+ }
92
+
93
+ GObject.type_ensure(StackSwitcherStory.$gtype);
94
+
95
+ export const StackSwitcherStories: StoryModule = { stories: [StackSwitcherStory] };