@gjsify/example-gtk-adwaita-storybook 0.19.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 (119) hide show
  1. package/README.md +120 -0
  2. package/dist/adw-runasync.mjs +1 -0
  3. package/dist/gjs.js +91 -0
  4. package/dist/interact-probe.node.mjs +87 -0
  5. package/dist/probe.node.mjs +87 -0
  6. package/dist/render-probe.node.mjs +87 -0
  7. package/dist/runasync-probe.mjs +1 -0
  8. package/dist/storybook.node.mjs +87 -0
  9. package/package.json +64 -0
  10. package/src/browser/buttons/button-content.web.ts +55 -0
  11. package/src/browser/buttons/button-styles.web.ts +79 -0
  12. package/src/browser/buttons/split-button.web.ts +86 -0
  13. package/src/browser/buttons/toggle-group.web.ts +56 -0
  14. package/src/browser/embed.ts +46 -0
  15. package/src/browser/feedback/about-dialog.web.ts +82 -0
  16. package/src/browser/feedback/alert-dialog.web.ts +72 -0
  17. package/src/browser/feedback/preferences-dialog.web.ts +106 -0
  18. package/src/browser/feedback/toast.web.ts +62 -0
  19. package/src/browser/index.html +23 -0
  20. package/src/browser/layout/clamp.web.ts +45 -0
  21. package/src/browser/layout/header-bar.web.ts +56 -0
  22. package/src/browser/layout/toolbar-view.web.ts +95 -0
  23. package/src/browser/layout/wrap-box.web.ts +45 -0
  24. package/src/browser/main.ts +14 -0
  25. package/src/browser/navigation/bottom-sheet.web.ts +119 -0
  26. package/src/browser/navigation/navigation-split-view.web.ts +99 -0
  27. package/src/browser/navigation/navigation-view.web.ts +104 -0
  28. package/src/browser/navigation/overlay-split-view.web.ts +106 -0
  29. package/src/browser/navigation/sidebar.web.ts +84 -0
  30. package/src/browser/presentation/avatar.web.ts +36 -0
  31. package/src/browser/presentation/banner.web.ts +41 -0
  32. package/src/browser/presentation/spinner.web.ts +28 -0
  33. package/src/browser/presentation/status-page.web.ts +43 -0
  34. package/src/browser/presentation/window-title.web.ts +34 -0
  35. package/src/browser/rows/action-row.web.ts +61 -0
  36. package/src/browser/rows/button-row.web.ts +64 -0
  37. package/src/browser/rows/combo-row.web.ts +44 -0
  38. package/src/browser/rows/entry-row.web.ts +42 -0
  39. package/src/browser/rows/expander-row.web.ts +53 -0
  40. package/src/browser/rows/password-entry-row.web.ts +43 -0
  41. package/src/browser/rows/preferences-group.web.ts +68 -0
  42. package/src/browser/rows/spin-row.web.ts +47 -0
  43. package/src/browser/rows/switch-row.web.ts +43 -0
  44. package/src/browser/stories.ts +82 -0
  45. package/src/browser/view-switching/carousel.web.ts +106 -0
  46. package/src/browser/view-switching/inline-view-switcher.web.ts +55 -0
  47. package/src/browser/view-switching/tab-view.web.ts +64 -0
  48. package/src/browser/view-switching/view-switcher.web.ts +55 -0
  49. package/src/buttons/button-content.meta.ts +26 -0
  50. package/src/buttons/button-content.story.ts +49 -0
  51. package/src/buttons/button-styles.meta.ts +26 -0
  52. package/src/buttons/button-styles.story.ts +77 -0
  53. package/src/buttons/split-button.meta.ts +45 -0
  54. package/src/buttons/split-button.story.ts +102 -0
  55. package/src/buttons/toggle-group.meta.ts +34 -0
  56. package/src/buttons/toggle-group.story.ts +56 -0
  57. package/src/feedback/about-dialog.meta.ts +13 -0
  58. package/src/feedback/about-dialog.story.ts +64 -0
  59. package/src/feedback/alert-dialog.meta.ts +19 -0
  60. package/src/feedback/alert-dialog.story.ts +61 -0
  61. package/src/feedback/preferences-dialog.meta.ts +13 -0
  62. package/src/feedback/preferences-dialog.story.ts +92 -0
  63. package/src/feedback/toast.meta.ts +23 -0
  64. package/src/feedback/toast.story.ts +66 -0
  65. package/src/layout/clamp.meta.ts +29 -0
  66. package/src/layout/clamp.story.ts +59 -0
  67. package/src/layout/header-bar.meta.ts +14 -0
  68. package/src/layout/header-bar.story.ts +66 -0
  69. package/src/layout/toolbar-view.meta.ts +18 -0
  70. package/src/layout/toolbar-view.story.ts +71 -0
  71. package/src/layout/wrap-box.meta.ts +29 -0
  72. package/src/layout/wrap-box.story.ts +52 -0
  73. package/src/metas.ts +41 -0
  74. package/src/navigation/bottom-sheet.meta.ts +13 -0
  75. package/src/navigation/bottom-sheet.story.ts +90 -0
  76. package/src/navigation/navigation-split-view.meta.ts +13 -0
  77. package/src/navigation/navigation-split-view.story.ts +83 -0
  78. package/src/navigation/navigation-view.meta.ts +19 -0
  79. package/src/navigation/navigation-view.story.ts +77 -0
  80. package/src/navigation/overlay-split-view.meta.ts +13 -0
  81. package/src/navigation/overlay-split-view.story.ts +82 -0
  82. package/src/navigation/sidebar.meta.ts +30 -0
  83. package/src/navigation/sidebar.story.ts +85 -0
  84. package/src/presentation/avatar.meta.ts +24 -0
  85. package/src/presentation/avatar.story.ts +46 -0
  86. package/src/presentation/banner.meta.ts +19 -0
  87. package/src/presentation/banner.story.ts +53 -0
  88. package/src/presentation/spinner.meta.ts +9 -0
  89. package/src/presentation/spinner.story.ts +47 -0
  90. package/src/presentation/status-page.meta.ts +29 -0
  91. package/src/presentation/status-page.story.ts +55 -0
  92. package/src/presentation/window-title.meta.ts +12 -0
  93. package/src/presentation/window-title.story.ts +42 -0
  94. package/src/rows/action-row.meta.ts +30 -0
  95. package/src/rows/action-row.story.ts +62 -0
  96. package/src/rows/button-row.meta.ts +34 -0
  97. package/src/rows/button-row.story.ts +61 -0
  98. package/src/rows/combo-row.meta.ts +29 -0
  99. package/src/rows/combo-row.story.ts +51 -0
  100. package/src/rows/entry-row.meta.ts +13 -0
  101. package/src/rows/entry-row.story.ts +49 -0
  102. package/src/rows/expander-row.meta.ts +25 -0
  103. package/src/rows/expander-row.story.ts +54 -0
  104. package/src/rows/password-entry-row.meta.ts +12 -0
  105. package/src/rows/password-entry-row.story.ts +47 -0
  106. package/src/rows/preferences-group.meta.ts +18 -0
  107. package/src/rows/preferences-group.story.ts +67 -0
  108. package/src/rows/spin-row.meta.ts +29 -0
  109. package/src/rows/spin-row.story.ts +56 -0
  110. package/src/rows/switch-row.meta.ts +18 -0
  111. package/src/rows/switch-row.story.ts +49 -0
  112. package/src/view-switching/carousel.meta.ts +35 -0
  113. package/src/view-switching/carousel.story.ts +131 -0
  114. package/src/view-switching/inline-view-switcher.meta.ts +25 -0
  115. package/src/view-switching/inline-view-switcher.story.ts +88 -0
  116. package/src/view-switching/tab-view.meta.ts +12 -0
  117. package/src/view-switching/tab-view.story.ts +72 -0
  118. package/src/view-switching/view-switcher.meta.ts +23 -0
  119. package/src/view-switching/view-switcher.story.ts +87 -0
@@ -0,0 +1,43 @@
1
+ // Browser port of the Password Entry Row story. Shares metadata with
2
+ // password-entry-row.story.ts.
3
+
4
+ import { StoryElement, type StoryArgs, type StoryMeta, type WebStoryModule } from '@gjsify/adwaita-storybook';
5
+ import { passwordEntryRowMeta } from '../../rows/password-entry-row.meta.js';
6
+
7
+ export class PasswordEntryRowWebStory extends StoryElement {
8
+ private _row: HTMLElement | null = null;
9
+
10
+ constructor() {
11
+ super(PasswordEntryRowWebStory.getMetadata(), 'Default');
12
+ }
13
+
14
+ static getMetadata(): StoryMeta {
15
+ return passwordEntryRowMeta;
16
+ }
17
+
18
+ initialize(): void {
19
+ this._row = document.createElement('adw-password-entry-row');
20
+ this._syncRow();
21
+
22
+ const group = document.createElement('adw-preferences-group');
23
+ group.append(this._row);
24
+
25
+ const clamp = document.createElement('adw-clamp');
26
+ clamp.setAttribute('maximum-size', '400');
27
+ clamp.append(group);
28
+
29
+ this.addContent(clamp);
30
+ }
31
+
32
+ updateArgs(_args: StoryArgs): void {
33
+ this._syncRow();
34
+ }
35
+
36
+ private _syncRow(): void {
37
+ if (!this._row) return;
38
+ this._row.setAttribute('title', this.args.title as string);
39
+ this._row.setAttribute('text', this.args.text as string);
40
+ }
41
+ }
42
+
43
+ export const PasswordEntryRowWebStories: WebStoryModule = { stories: [PasswordEntryRowWebStory] };
@@ -0,0 +1,68 @@
1
+ // Browser port of the Preferences Group story. Shares metadata with
2
+ // preferences-group.story.ts.
3
+
4
+ import { StoryElement, type StoryArgs, type StoryMeta, type WebStoryModule } from '@gjsify/adwaita-storybook';
5
+ import { preferencesGroupMeta } from '../../rows/preferences-group.meta.js';
6
+
7
+ const REGION_OPTIONS = ['Europe', 'Americas', 'Asia', 'Oceania'];
8
+
9
+ export class PreferencesGroupWebStory extends StoryElement {
10
+ private _group: HTMLElement | null = null;
11
+
12
+ constructor() {
13
+ super(PreferencesGroupWebStory.getMetadata(), 'Default');
14
+ }
15
+
16
+ static getMetadata(): StoryMeta {
17
+ return preferencesGroupMeta;
18
+ }
19
+
20
+ initialize(): void {
21
+ this._group = document.createElement('adw-preferences-group');
22
+
23
+ // Header-suffix: a flat "Sign out" button at the trailing edge of the
24
+ // header — mirrors the native story's `headerSuffix` Gtk.Button.
25
+ const signOut = document.createElement('button');
26
+ signOut.className = 'adw-button flat';
27
+ signOut.textContent = 'Sign out';
28
+ signOut.setAttribute('slot', 'header-suffix');
29
+ this._group.append(signOut);
30
+
31
+ const nameRow = document.createElement('adw-entry-row');
32
+ nameRow.setAttribute('title', 'Display name');
33
+ nameRow.setAttribute('text', 'Grace Hopper');
34
+ this._group.append(nameRow);
35
+
36
+ const syncRow = document.createElement('adw-switch-row');
37
+ syncRow.setAttribute('title', 'Sync over Wi-Fi only');
38
+ syncRow.setAttribute('subtitle', 'Avoid using mobile data for backups');
39
+ syncRow.setAttribute('active', '');
40
+ this._group.append(syncRow);
41
+
42
+ const regionRow = document.createElement('adw-combo-row');
43
+ regionRow.setAttribute('title', 'Region');
44
+ regionRow.setAttribute('items', JSON.stringify(REGION_OPTIONS));
45
+ regionRow.setAttribute('selected', '0');
46
+ this._group.append(regionRow);
47
+
48
+ this._syncGroup();
49
+
50
+ const clamp = document.createElement('adw-clamp');
51
+ clamp.setAttribute('maximum-size', '400');
52
+ clamp.append(this._group);
53
+
54
+ this.addContent(clamp);
55
+ }
56
+
57
+ updateArgs(_args: StoryArgs): void {
58
+ this._syncGroup();
59
+ }
60
+
61
+ private _syncGroup(): void {
62
+ if (!this._group) return;
63
+ this._group.setAttribute('title', this.args.title as string);
64
+ this._group.setAttribute('description', this.args.description as string);
65
+ }
66
+ }
67
+
68
+ export const PreferencesGroupWebStories: WebStoryModule = { stories: [PreferencesGroupWebStory] };
@@ -0,0 +1,47 @@
1
+ // Browser port of the Spin Row story. Shares metadata with spin-row.story.ts.
2
+
3
+ import { StoryElement, type StoryArgs, type StoryMeta, type WebStoryModule } from '@gjsify/adwaita-storybook';
4
+ import { spinRowMeta } from '../../rows/spin-row.meta.js';
5
+
6
+ export class SpinRowWebStory extends StoryElement {
7
+ private _row: HTMLElement | null = null;
8
+
9
+ constructor() {
10
+ super(SpinRowWebStory.getMetadata(), 'Default');
11
+ }
12
+
13
+ static getMetadata(): StoryMeta {
14
+ return spinRowMeta;
15
+ }
16
+
17
+ initialize(): void {
18
+ this._row = document.createElement('adw-spin-row');
19
+ this._row.setAttribute('min', '0');
20
+ this._row.setAttribute('max', '100');
21
+ this._syncRow();
22
+
23
+ const group = document.createElement('adw-preferences-group');
24
+ group.append(this._row);
25
+
26
+ const clamp = document.createElement('adw-clamp');
27
+ clamp.setAttribute('maximum-size', '400');
28
+ clamp.append(group);
29
+
30
+ this.addContent(clamp);
31
+ }
32
+
33
+ updateArgs(_args: StoryArgs): void {
34
+ this._syncRow();
35
+ }
36
+
37
+ private _syncRow(): void {
38
+ if (!this._row) return;
39
+ this._row.setAttribute('title', this.args.title as string);
40
+ // Mirror Adw.SpinRow.digits via the step's decimal precision.
41
+ const digits = this.args.digits as number;
42
+ this._row.setAttribute('step', String(10 ** -digits));
43
+ this._row.setAttribute('value', String(this.args.value as number));
44
+ }
45
+ }
46
+
47
+ export const SpinRowWebStories: WebStoryModule = { stories: [SpinRowWebStory] };
@@ -0,0 +1,43 @@
1
+ // Browser port of the Switch Row story. Shares metadata with switch-row.story.ts.
2
+
3
+ import { StoryElement, type StoryArgs, type StoryMeta, type WebStoryModule } from '@gjsify/adwaita-storybook';
4
+ import { switchRowMeta } from '../../rows/switch-row.meta.js';
5
+
6
+ export class SwitchRowWebStory extends StoryElement {
7
+ private _row: HTMLElement | null = null;
8
+
9
+ constructor() {
10
+ super(SwitchRowWebStory.getMetadata(), 'Default');
11
+ }
12
+
13
+ static getMetadata(): StoryMeta {
14
+ return switchRowMeta;
15
+ }
16
+
17
+ initialize(): void {
18
+ this._row = document.createElement('adw-switch-row');
19
+ this._syncRow();
20
+
21
+ const group = document.createElement('adw-preferences-group');
22
+ group.append(this._row);
23
+
24
+ const clamp = document.createElement('adw-clamp');
25
+ clamp.setAttribute('maximum-size', '400');
26
+ clamp.append(group);
27
+
28
+ this.addContent(clamp);
29
+ }
30
+
31
+ updateArgs(_args: StoryArgs): void {
32
+ this._syncRow();
33
+ }
34
+
35
+ private _syncRow(): void {
36
+ if (!this._row) return;
37
+ this._row.setAttribute('title', this.args.title as string);
38
+ this._row.setAttribute('subtitle', this.args.subtitle as string);
39
+ this._row.toggleAttribute('active', this.args.active as boolean);
40
+ }
41
+ }
42
+
43
+ export const SwitchRowWebStories: WebStoryModule = { stories: [SwitchRowWebStory] };
@@ -0,0 +1,82 @@
1
+ // Shared story list for the Adwaita storybook's browser target. Both the
2
+ // standalone entry (`main.ts`, `mountStorybook(document.body, …)`) and the
3
+ // embeddable `mount(container)` (`embed.ts`, used by the gjsify website) draw
4
+ // from this single list so the two stay in lockstep.
5
+ //
6
+ // Order mirrors the native sidebar's category order (Presentation, Boxed
7
+ // Lists, Buttons, …).
8
+
9
+ import type { WebStoryModule } from '@gjsify/adwaita-storybook';
10
+ import { AvatarWebStories } from './presentation/avatar.web.js';
11
+ import { BannerWebStories } from './presentation/banner.web.js';
12
+ import { SpinnerWebStories } from './presentation/spinner.web.js';
13
+ import { StatusPageWebStories } from './presentation/status-page.web.js';
14
+ import { WindowTitleWebStories } from './presentation/window-title.web.js';
15
+ import { ActionRowWebStories } from './rows/action-row.web.js';
16
+ import { ButtonRowWebStories } from './rows/button-row.web.js';
17
+ import { ComboRowWebStories } from './rows/combo-row.web.js';
18
+ import { EntryRowWebStories } from './rows/entry-row.web.js';
19
+ import { ExpanderRowWebStories } from './rows/expander-row.web.js';
20
+ import { PasswordEntryRowWebStories } from './rows/password-entry-row.web.js';
21
+ import { PreferencesGroupWebStories } from './rows/preferences-group.web.js';
22
+ import { SpinRowWebStories } from './rows/spin-row.web.js';
23
+ import { SwitchRowWebStories } from './rows/switch-row.web.js';
24
+ import { ButtonContentWebStories } from './buttons/button-content.web.js';
25
+ import { ButtonStylesWebStories } from './buttons/button-styles.web.js';
26
+ import { SplitButtonWebStories } from './buttons/split-button.web.js';
27
+ import { ToggleGroupWebStories } from './buttons/toggle-group.web.js';
28
+ import { ClampWebStories } from './layout/clamp.web.js';
29
+ import { HeaderBarWebStories } from './layout/header-bar.web.js';
30
+ import { ToolbarViewWebStories } from './layout/toolbar-view.web.js';
31
+ import { WrapBoxWebStories } from './layout/wrap-box.web.js';
32
+ import { CarouselWebStories } from './view-switching/carousel.web.js';
33
+ import { InlineViewSwitcherWebStories } from './view-switching/inline-view-switcher.web.js';
34
+ import { TabViewWebStories } from './view-switching/tab-view.web.js';
35
+ import { ViewSwitcherWebStories } from './view-switching/view-switcher.web.js';
36
+ import { BottomSheetWebStories } from './navigation/bottom-sheet.web.js';
37
+ import { NavigationSplitViewWebStories } from './navigation/navigation-split-view.web.js';
38
+ import { NavigationViewWebStories } from './navigation/navigation-view.web.js';
39
+ import { OverlaySplitViewWebStories } from './navigation/overlay-split-view.web.js';
40
+ import { SidebarWebStories } from './navigation/sidebar.web.js';
41
+ import { AboutDialogWebStories } from './feedback/about-dialog.web.js';
42
+ import { AlertDialogWebStories } from './feedback/alert-dialog.web.js';
43
+ import { PreferencesDialogWebStories } from './feedback/preferences-dialog.web.js';
44
+ import { ToastWebStories } from './feedback/toast.web.js';
45
+
46
+ export const stories: WebStoryModule[] = [
47
+ AvatarWebStories,
48
+ BannerWebStories,
49
+ SpinnerWebStories,
50
+ StatusPageWebStories,
51
+ WindowTitleWebStories,
52
+ ActionRowWebStories,
53
+ ButtonRowWebStories,
54
+ ComboRowWebStories,
55
+ EntryRowWebStories,
56
+ ExpanderRowWebStories,
57
+ PasswordEntryRowWebStories,
58
+ PreferencesGroupWebStories,
59
+ SpinRowWebStories,
60
+ SwitchRowWebStories,
61
+ ButtonContentWebStories,
62
+ ButtonStylesWebStories,
63
+ SplitButtonWebStories,
64
+ ToggleGroupWebStories,
65
+ ClampWebStories,
66
+ HeaderBarWebStories,
67
+ ToolbarViewWebStories,
68
+ WrapBoxWebStories,
69
+ CarouselWebStories,
70
+ InlineViewSwitcherWebStories,
71
+ TabViewWebStories,
72
+ ViewSwitcherWebStories,
73
+ BottomSheetWebStories,
74
+ NavigationSplitViewWebStories,
75
+ NavigationViewWebStories,
76
+ OverlaySplitViewWebStories,
77
+ SidebarWebStories,
78
+ AboutDialogWebStories,
79
+ AlertDialogWebStories,
80
+ PreferencesDialogWebStories,
81
+ ToastWebStories,
82
+ ];
@@ -0,0 +1,106 @@
1
+ // Browser port of the Carousel stories — adw-carousel with three card pages,
2
+ // paired with the dot / line page indicators. Shares its metadata/controls with
3
+ // the GTK twin (carousel.story.ts). Adw.Carousel has two indicator widgets, so
4
+ // this module exports two stories (Dots + Lines), mirroring the native file.
5
+
6
+ import { StoryElement, type StoryArgs, type StoryMeta, type WebStoryModule } from '@gjsify/adwaita-storybook';
7
+ import { carouselDotsMeta, carouselLinesMeta } from '../../view-switching/carousel.meta.js';
8
+
9
+ // Subtle tints over the window background — libadwaita's .card.accent/.success/
10
+ // .warning are a faint colour wash on the card, not a saturated fill.
11
+ const PAGES: ReadonlyArray<{ title: string; accent: string }> = [
12
+ { title: 'Welcome', accent: 'color-mix(in srgb, var(--accent-bg-color) 14%, var(--window-bg-color))' },
13
+ { title: 'Discover', accent: 'color-mix(in srgb, #2ec27e 14%, var(--window-bg-color))' },
14
+ { title: 'Get started', accent: 'color-mix(in srgb, #e5a50a 14%, var(--window-bg-color))' },
15
+ ];
16
+
17
+ let nextCarouselId = 0;
18
+
19
+ /** Build a single accent-tinted card page, sized like the native demo. */
20
+ function buildPage(title: string, accent: string): HTMLElement {
21
+ const card = document.createElement('adw-card');
22
+ card.style.cssText = [
23
+ 'width:440px',
24
+ 'height:260px',
25
+ 'display:flex',
26
+ 'align-items:center',
27
+ 'justify-content:center',
28
+ `background-color:${accent}`,
29
+ 'color:#ffffff',
30
+ 'box-sizing:border-box',
31
+ ].join(';');
32
+
33
+ const label = document.createElement('span');
34
+ label.textContent = title;
35
+ // .title-1 in libadwaita ≈ 24pt bold.
36
+ label.style.cssText = 'font-size:24pt;font-weight:800;';
37
+ card.appendChild(label);
38
+ return card;
39
+ }
40
+
41
+ /** Shared body for both indicator variants — only the indicator tag differs. */
42
+ abstract class CarouselWebStoryBase extends StoryElement {
43
+ private _carousel: HTMLElement | null = null;
44
+
45
+ /** The indicator tag this variant pairs with the carousel. */
46
+ protected abstract indicatorTag(): string;
47
+
48
+ initialize(): void {
49
+ const carousel = document.createElement('adw-carousel');
50
+ carousel.id = `adw-carousel-${nextCarouselId++}`;
51
+ carousel.style.cssText = 'width:480px;height:280px;';
52
+ carousel.toggleAttribute('allow-scroll-wheel', this.args.allowScrollWheel as boolean);
53
+ carousel.toggleAttribute('allow-long-swipes', this.args.allowLongSwipes as boolean);
54
+ for (const page of PAGES) {
55
+ carousel.appendChild(buildPage(page.title, page.accent));
56
+ }
57
+ this._carousel = carousel;
58
+
59
+ const indicator = document.createElement(this.indicatorTag());
60
+ indicator.setAttribute('for', carousel.id);
61
+
62
+ const box = document.createElement('div');
63
+ box.style.cssText = 'display:flex;flex-direction:column;gap:12px;width:480px;align-items:center;';
64
+ box.append(carousel, indicator);
65
+
66
+ this.addContent(box);
67
+ }
68
+
69
+ updateArgs(_args: StoryArgs): void {
70
+ if (!this._carousel) return;
71
+ this._carousel.toggleAttribute('allow-scroll-wheel', this.args.allowScrollWheel as boolean);
72
+ this._carousel.toggleAttribute('allow-long-swipes', this.args.allowLongSwipes as boolean);
73
+ }
74
+ }
75
+
76
+ /** Story: adw-carousel with dot indicators. */
77
+ export class CarouselDotsWebStory extends CarouselWebStoryBase {
78
+ constructor() {
79
+ super(CarouselDotsWebStory.getMetadata(), 'Default');
80
+ }
81
+
82
+ static getMetadata(): StoryMeta {
83
+ return carouselDotsMeta;
84
+ }
85
+
86
+ protected indicatorTag(): string {
87
+ return 'adw-carousel-indicator-dots';
88
+ }
89
+ }
90
+
91
+ /** Story: adw-carousel with line indicators. */
92
+ export class CarouselLinesWebStory extends CarouselWebStoryBase {
93
+ constructor() {
94
+ super(CarouselLinesWebStory.getMetadata(), 'Default');
95
+ }
96
+
97
+ static getMetadata(): StoryMeta {
98
+ return carouselLinesMeta;
99
+ }
100
+
101
+ protected indicatorTag(): string {
102
+ return 'adw-carousel-indicator-lines';
103
+ }
104
+ }
105
+
106
+ export const CarouselWebStories: WebStoryModule = { stories: [CarouselDotsWebStory, CarouselLinesWebStory] };
@@ -0,0 +1,55 @@
1
+ // Browser port of the Inline View Switcher story — adw-inline-view-switcher
2
+ // driving a stack of three adw-view-stack-page children, with the display-mode
3
+ // control (labels / icons / both). Shares its metadata/controls with the GTK
4
+ // twin (inline-view-switcher.story.ts).
5
+
6
+ import { StoryElement, type StoryArgs, type StoryMeta, type WebStoryModule } from '@gjsify/adwaita-storybook';
7
+ import { inlineViewSwitcherMeta } from '../../view-switching/inline-view-switcher.meta.js';
8
+
9
+ // The three pages, mirroring the native demo (Overview / Activity / Settings).
10
+ const PAGES: ReadonlyArray<{ id: string; title: string; icon: string; body: string }> = [
11
+ { id: 'overview', title: 'Overview', icon: 'view-grid', body: 'A quick summary of your project.' },
12
+ { id: 'activity', title: 'Activity', icon: 'document-edit', body: 'Recent edits and changes.' },
13
+ { id: 'settings', title: 'Settings', icon: 'emblem-system', body: 'Configure how things behave.' },
14
+ ];
15
+
16
+ export class InlineViewSwitcherWebStory extends StoryElement {
17
+ private _switcher: HTMLElement | null = null;
18
+
19
+ constructor() {
20
+ super(InlineViewSwitcherWebStory.getMetadata(), 'Default');
21
+ }
22
+
23
+ static getMetadata(): StoryMeta {
24
+ return inlineViewSwitcherMeta;
25
+ }
26
+
27
+ initialize(): void {
28
+ const switcher = document.createElement('adw-inline-view-switcher');
29
+ for (const { id, title, icon, body } of PAGES) {
30
+ const page = document.createElement('adw-view-stack-page');
31
+ page.setAttribute('title', title);
32
+ page.setAttribute('icon-name', icon);
33
+
34
+ // A status-page body per page (mirrors the native Adw.StatusPage pages).
35
+ const status = document.createElement('adw-status-page');
36
+ status.id = id;
37
+ status.setAttribute('icon', icon);
38
+ status.setAttribute('title', title);
39
+ status.setAttribute('description', body);
40
+ page.appendChild(status);
41
+
42
+ switcher.appendChild(page);
43
+ }
44
+ switcher.setAttribute('display-mode', this.args.displayMode as string);
45
+ this._switcher = switcher;
46
+ this.addContent(switcher);
47
+ }
48
+
49
+ updateArgs(_args: StoryArgs): void {
50
+ if (!this._switcher) return;
51
+ this._switcher.setAttribute('display-mode', this.args.displayMode as string);
52
+ }
53
+ }
54
+
55
+ export const InlineViewSwitcherWebStories: WebStoryModule = { stories: [InlineViewSwitcherWebStory] };
@@ -0,0 +1,64 @@
1
+ // Browser port of the Tab View story — an adw-tab-view with three adw-tab-page
2
+ // children, each holding an adw-status-page body, plus the autohide control.
3
+ // Shares its metadata/controls with the GTK twin (tab-view.story.ts).
4
+
5
+ import { StoryElement, type StoryArgs, type StoryMeta, type WebStoryModule } from '@gjsify/adwaita-storybook';
6
+ import { tabViewMeta } from '../../view-switching/tab-view.meta.js';
7
+
8
+ const TABS: ReadonlyArray<{ title: string; body: string }> = [
9
+ { title: 'Overview', body: 'A summary of everything at a glance.' },
10
+ { title: 'Details', body: 'The specifics, broken down line by line.' },
11
+ { title: 'History', body: 'A log of every change made so far.' },
12
+ ];
13
+
14
+ export class TabViewWebStory extends StoryElement {
15
+ private _tabView: HTMLElement | null = null;
16
+
17
+ constructor() {
18
+ super(TabViewWebStory.getMetadata(), 'Default');
19
+ }
20
+
21
+ static getMetadata(): StoryMeta {
22
+ return tabViewMeta;
23
+ }
24
+
25
+ initialize(): void {
26
+ const tabView = document.createElement('adw-tab-view');
27
+ tabView.style.width = '480px';
28
+ tabView.style.height = '340px';
29
+
30
+ for (const tab of TABS) {
31
+ const page = document.createElement('adw-tab-page');
32
+ page.setAttribute('title', tab.title);
33
+ page.appendChild(this._buildPageBody(tab.title, tab.body));
34
+ tabView.appendChild(page);
35
+ }
36
+
37
+ this._tabView = tabView;
38
+ this._applyAutohide(this.args.autohide as boolean);
39
+ this.addContent(tabView);
40
+ }
41
+
42
+ updateArgs(_args: StoryArgs): void {
43
+ if (!this._tabView) return;
44
+ this._applyAutohide(this.args.autohide as boolean);
45
+ }
46
+
47
+ // `view-grid` stands in for the native `view-paged-symbolic` — the closest
48
+ // icon in @gjsify/adwaita-icons.
49
+ private _buildPageBody(title: string, body: string): HTMLElement {
50
+ const status = document.createElement('adw-status-page');
51
+ status.setAttribute('icon', 'view-grid');
52
+ status.setAttribute('title', title);
53
+ status.setAttribute('description', body);
54
+ return status;
55
+ }
56
+
57
+ private _applyAutohide(autohide: boolean): void {
58
+ if (!this._tabView) return;
59
+ if (autohide) this._tabView.setAttribute('autohide', '');
60
+ else this._tabView.removeAttribute('autohide');
61
+ }
62
+ }
63
+
64
+ export const TabViewWebStories: WebStoryModule = { stories: [TabViewWebStory] };
@@ -0,0 +1,55 @@
1
+ // Browser port of the View Switcher story — adw-view-switcher with three
2
+ // adw-view-switcher-page children (each an adw-status-page body) and the
3
+ // wide/narrow policy. Shares its metadata/controls with the GTK twin
4
+ // (view-switcher.story.ts).
5
+
6
+ import { StoryElement, type StoryArgs, type StoryMeta, type WebStoryModule } from '@gjsify/adwaita-storybook';
7
+ import { viewSwitcherMeta } from '../../view-switching/view-switcher.meta.js';
8
+
9
+ // The three pages, mirroring the native demo (Inbox / Starred / Archive).
10
+ const PAGES: ReadonlyArray<{ name: string; title: string; icon: string; description: string }> = [
11
+ { name: 'inbox', title: 'Inbox', icon: 'mail-unread', description: 'You have three unread conversations.' },
12
+ { name: 'starred', title: 'Starred', icon: 'starred', description: 'Messages you have marked as important.' },
13
+ { name: 'archive', title: 'Archive', icon: 'folder', description: 'Older conversations kept for reference.' },
14
+ ];
15
+
16
+ export class ViewSwitcherWebStory extends StoryElement {
17
+ private _switcher: HTMLElement | null = null;
18
+
19
+ constructor() {
20
+ super(ViewSwitcherWebStory.getMetadata(), 'Default');
21
+ }
22
+
23
+ static getMetadata(): StoryMeta {
24
+ return viewSwitcherMeta;
25
+ }
26
+
27
+ initialize(): void {
28
+ const switcher = document.createElement('adw-view-switcher');
29
+ for (const { name, title, icon, description } of PAGES) {
30
+ const page = document.createElement('adw-view-switcher-page');
31
+ page.setAttribute('name', name);
32
+ page.setAttribute('title', title);
33
+ page.setAttribute('icon-name', icon);
34
+
35
+ const status = document.createElement('adw-status-page');
36
+ status.setAttribute('icon', icon);
37
+ status.setAttribute('title', title);
38
+ status.setAttribute('description', description);
39
+ page.appendChild(status);
40
+
41
+ switcher.appendChild(page);
42
+ }
43
+ switcher.setAttribute('policy', this.args.policy as string);
44
+ switcher.style.width = '480px';
45
+ this._switcher = switcher;
46
+ this.addContent(switcher);
47
+ }
48
+
49
+ updateArgs(_args: StoryArgs): void {
50
+ if (!this._switcher) return;
51
+ this._switcher.setAttribute('policy', this.args.policy as string);
52
+ }
53
+ }
54
+
55
+ export const ViewSwitcherWebStories: WebStoryModule = { stories: [ViewSwitcherWebStory] };
@@ -0,0 +1,26 @@
1
+ // Shared, renderer-agnostic metadata for the Button Content story. Imported by
2
+ // both the GTK renderer (button-content.story.ts) and the browser renderer
3
+ // (browser/buttons/button-content.web.ts) so the two expose identical controls.
4
+
5
+ import { ControlType, type StoryMeta } from '@gjsify/stories';
6
+
7
+ export const buttonContentMeta: StoryMeta = {
8
+ title: 'Buttons/Button Content',
9
+ description: 'Adw.ButtonContent — pairs a symbolic icon with a label inside a Gtk.Button.',
10
+ controls: [
11
+ { name: 'label', label: 'Label', type: ControlType.TEXT, defaultValue: 'Download' },
12
+ {
13
+ name: 'iconName',
14
+ label: 'Icon',
15
+ type: ControlType.SELECT,
16
+ options: [
17
+ { label: 'Download', value: 'folder-download-symbolic' },
18
+ { label: 'Add', value: 'list-add-symbolic' },
19
+ { label: 'Send', value: 'mail-send-symbolic' },
20
+ { label: 'Star', value: 'starred-symbolic' },
21
+ ],
22
+ defaultValue: 'folder-download-symbolic',
23
+ },
24
+ { name: 'canShrink', label: 'Can shrink', type: ControlType.BOOLEAN, defaultValue: false },
25
+ ],
26
+ };
@@ -0,0 +1,49 @@
1
+ // Adw.ButtonContent — an icon-plus-label child for a Gtk.Button, with optional
2
+ // shrinking. original implementation.
3
+
4
+ import Adw from '@girs/adw-1';
5
+ import Gtk from '@girs/gtk-4.0';
6
+ import GObject from '@girs/gobject-2.0';
7
+ import { type StoryArgs, type StoryMeta, type StoryModule, StoryWidget } from '@gjsify/storybook';
8
+ import { buttonContentMeta } from './button-content.meta.js';
9
+
10
+ /** Story: Adw.ButtonContent placed inside a Gtk.Button. */
11
+ export class ButtonContentStory extends StoryWidget {
12
+ private _content: Adw.ButtonContent | null = null;
13
+ private _button: Gtk.Button | null = null;
14
+
15
+ static {
16
+ GObject.registerClass({ GTypeName: 'AdwStorybookButtonContent' }, ButtonContentStory);
17
+ }
18
+
19
+ constructor() {
20
+ super(StoryWidget.fromMeta(ButtonContentStory.getMetadata(), 'Default'));
21
+ }
22
+
23
+ static getMetadata(): StoryMeta {
24
+ return { ...buttonContentMeta, component: Adw.ButtonContent.$gtype };
25
+ }
26
+
27
+ initialize(): void {
28
+ this._content = new Adw.ButtonContent({
29
+ label: this.args.label as string,
30
+ iconName: this.args.iconName as string,
31
+ canShrink: this.args.canShrink as boolean,
32
+ });
33
+ this._button = new Gtk.Button({ child: this._content });
34
+ this._button.add_css_class('suggested-action');
35
+ this._button.add_css_class('pill');
36
+ this.addContent(this._button);
37
+ }
38
+
39
+ updateArgs(_args: StoryArgs): void {
40
+ if (!this._content) return;
41
+ this._content.label = this.args.label as string;
42
+ this._content.iconName = this.args.iconName as string;
43
+ this._content.canShrink = this.args.canShrink as boolean;
44
+ }
45
+ }
46
+
47
+ GObject.type_ensure(ButtonContentStory.$gtype);
48
+
49
+ export const ButtonContentStories: StoryModule = { stories: [ButtonContentStory] };
@@ -0,0 +1,26 @@
1
+ // Shared, renderer-agnostic metadata for the Button Styles story. Imported by
2
+ // both the GTK renderer (button-styles.story.ts) and the browser renderer
3
+ // (browser/buttons/button-styles.web.ts) so the two expose identical controls.
4
+
5
+ import { ControlType, type StoryMeta } from '@gjsify/stories';
6
+
7
+ export const buttonStylesMeta: StoryMeta = {
8
+ title: 'Buttons/Button Styles',
9
+ description: 'Buttons with Adwaita style classes: .pill, .circular, .suggested-action, .destructive-action, .flat.',
10
+ controls: [
11
+ { name: 'label', label: 'Demo label', type: ControlType.TEXT, defaultValue: 'Click me' },
12
+ {
13
+ name: 'style',
14
+ label: 'Demo style',
15
+ type: ControlType.SELECT,
16
+ options: [
17
+ { label: 'Pill', value: 'pill' },
18
+ { label: 'Circular (icon)', value: 'circular' },
19
+ { label: 'Suggested', value: 'suggested-action' },
20
+ { label: 'Destructive', value: 'destructive-action' },
21
+ { label: 'Flat', value: 'flat' },
22
+ ],
23
+ defaultValue: 'suggested-action',
24
+ },
25
+ ],
26
+ };