@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.
- package/README.md +120 -0
- package/dist/adw-runasync.mjs +1 -0
- package/dist/gjs.js +91 -0
- package/dist/interact-probe.node.mjs +87 -0
- package/dist/probe.node.mjs +87 -0
- package/dist/render-probe.node.mjs +87 -0
- package/dist/runasync-probe.mjs +1 -0
- package/dist/storybook.node.mjs +87 -0
- package/package.json +64 -0
- package/src/browser/buttons/button-content.web.ts +55 -0
- package/src/browser/buttons/button-styles.web.ts +79 -0
- package/src/browser/buttons/split-button.web.ts +86 -0
- package/src/browser/buttons/toggle-group.web.ts +56 -0
- package/src/browser/embed.ts +46 -0
- package/src/browser/feedback/about-dialog.web.ts +82 -0
- package/src/browser/feedback/alert-dialog.web.ts +72 -0
- package/src/browser/feedback/preferences-dialog.web.ts +106 -0
- package/src/browser/feedback/toast.web.ts +62 -0
- package/src/browser/index.html +23 -0
- package/src/browser/layout/clamp.web.ts +45 -0
- package/src/browser/layout/header-bar.web.ts +56 -0
- package/src/browser/layout/toolbar-view.web.ts +95 -0
- package/src/browser/layout/wrap-box.web.ts +45 -0
- package/src/browser/main.ts +14 -0
- package/src/browser/navigation/bottom-sheet.web.ts +119 -0
- package/src/browser/navigation/navigation-split-view.web.ts +99 -0
- package/src/browser/navigation/navigation-view.web.ts +104 -0
- package/src/browser/navigation/overlay-split-view.web.ts +106 -0
- package/src/browser/navigation/sidebar.web.ts +84 -0
- package/src/browser/presentation/avatar.web.ts +36 -0
- package/src/browser/presentation/banner.web.ts +41 -0
- package/src/browser/presentation/spinner.web.ts +28 -0
- package/src/browser/presentation/status-page.web.ts +43 -0
- package/src/browser/presentation/window-title.web.ts +34 -0
- package/src/browser/rows/action-row.web.ts +61 -0
- package/src/browser/rows/button-row.web.ts +64 -0
- package/src/browser/rows/combo-row.web.ts +44 -0
- package/src/browser/rows/entry-row.web.ts +42 -0
- package/src/browser/rows/expander-row.web.ts +53 -0
- package/src/browser/rows/password-entry-row.web.ts +43 -0
- package/src/browser/rows/preferences-group.web.ts +68 -0
- package/src/browser/rows/spin-row.web.ts +47 -0
- package/src/browser/rows/switch-row.web.ts +43 -0
- package/src/browser/stories.ts +82 -0
- package/src/browser/view-switching/carousel.web.ts +106 -0
- package/src/browser/view-switching/inline-view-switcher.web.ts +55 -0
- package/src/browser/view-switching/tab-view.web.ts +64 -0
- package/src/browser/view-switching/view-switcher.web.ts +55 -0
- package/src/buttons/button-content.meta.ts +26 -0
- package/src/buttons/button-content.story.ts +49 -0
- package/src/buttons/button-styles.meta.ts +26 -0
- package/src/buttons/button-styles.story.ts +77 -0
- package/src/buttons/split-button.meta.ts +45 -0
- package/src/buttons/split-button.story.ts +102 -0
- package/src/buttons/toggle-group.meta.ts +34 -0
- package/src/buttons/toggle-group.story.ts +56 -0
- package/src/feedback/about-dialog.meta.ts +13 -0
- package/src/feedback/about-dialog.story.ts +64 -0
- package/src/feedback/alert-dialog.meta.ts +19 -0
- package/src/feedback/alert-dialog.story.ts +61 -0
- package/src/feedback/preferences-dialog.meta.ts +13 -0
- package/src/feedback/preferences-dialog.story.ts +92 -0
- package/src/feedback/toast.meta.ts +23 -0
- package/src/feedback/toast.story.ts +66 -0
- package/src/layout/clamp.meta.ts +29 -0
- package/src/layout/clamp.story.ts +59 -0
- package/src/layout/header-bar.meta.ts +14 -0
- package/src/layout/header-bar.story.ts +66 -0
- package/src/layout/toolbar-view.meta.ts +18 -0
- package/src/layout/toolbar-view.story.ts +71 -0
- package/src/layout/wrap-box.meta.ts +29 -0
- package/src/layout/wrap-box.story.ts +52 -0
- package/src/metas.ts +41 -0
- package/src/navigation/bottom-sheet.meta.ts +13 -0
- package/src/navigation/bottom-sheet.story.ts +90 -0
- package/src/navigation/navigation-split-view.meta.ts +13 -0
- package/src/navigation/navigation-split-view.story.ts +83 -0
- package/src/navigation/navigation-view.meta.ts +19 -0
- package/src/navigation/navigation-view.story.ts +77 -0
- package/src/navigation/overlay-split-view.meta.ts +13 -0
- package/src/navigation/overlay-split-view.story.ts +82 -0
- package/src/navigation/sidebar.meta.ts +30 -0
- package/src/navigation/sidebar.story.ts +85 -0
- package/src/presentation/avatar.meta.ts +24 -0
- package/src/presentation/avatar.story.ts +46 -0
- package/src/presentation/banner.meta.ts +19 -0
- package/src/presentation/banner.story.ts +53 -0
- package/src/presentation/spinner.meta.ts +9 -0
- package/src/presentation/spinner.story.ts +47 -0
- package/src/presentation/status-page.meta.ts +29 -0
- package/src/presentation/status-page.story.ts +55 -0
- package/src/presentation/window-title.meta.ts +12 -0
- package/src/presentation/window-title.story.ts +42 -0
- package/src/rows/action-row.meta.ts +30 -0
- package/src/rows/action-row.story.ts +62 -0
- package/src/rows/button-row.meta.ts +34 -0
- package/src/rows/button-row.story.ts +61 -0
- package/src/rows/combo-row.meta.ts +29 -0
- package/src/rows/combo-row.story.ts +51 -0
- package/src/rows/entry-row.meta.ts +13 -0
- package/src/rows/entry-row.story.ts +49 -0
- package/src/rows/expander-row.meta.ts +25 -0
- package/src/rows/expander-row.story.ts +54 -0
- package/src/rows/password-entry-row.meta.ts +12 -0
- package/src/rows/password-entry-row.story.ts +47 -0
- package/src/rows/preferences-group.meta.ts +18 -0
- package/src/rows/preferences-group.story.ts +67 -0
- package/src/rows/spin-row.meta.ts +29 -0
- package/src/rows/spin-row.story.ts +56 -0
- package/src/rows/switch-row.meta.ts +18 -0
- package/src/rows/switch-row.story.ts +49 -0
- package/src/view-switching/carousel.meta.ts +35 -0
- package/src/view-switching/carousel.story.ts +131 -0
- package/src/view-switching/inline-view-switcher.meta.ts +25 -0
- package/src/view-switching/inline-view-switcher.story.ts +88 -0
- package/src/view-switching/tab-view.meta.ts +12 -0
- package/src/view-switching/tab-view.story.ts +72 -0
- package/src/view-switching/view-switcher.meta.ts +23 -0
- package/src/view-switching/view-switcher.story.ts +87 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// Gtk.Button style classes — .pill, .circular, .suggested-action,
|
|
2
|
+
// .destructive-action, .flat. 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 { buttonStylesMeta } from './button-styles.meta.js';
|
|
9
|
+
|
|
10
|
+
const STYLE_CLASSES = ['pill', 'circular', 'suggested-action', 'destructive-action', 'flat'] as const;
|
|
11
|
+
|
|
12
|
+
/** Story: a row of Gtk.Buttons demonstrating the standard Adwaita style classes. */
|
|
13
|
+
export class ButtonStylesStory extends StoryWidget {
|
|
14
|
+
private _demo: Gtk.Button | null = null;
|
|
15
|
+
|
|
16
|
+
static {
|
|
17
|
+
GObject.registerClass({ GTypeName: 'AdwStorybookButtonStyles' }, ButtonStylesStory);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
constructor() {
|
|
21
|
+
super(StoryWidget.fromMeta(ButtonStylesStory.getMetadata(), 'Default'));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
static getMetadata(): StoryMeta {
|
|
25
|
+
return { ...buttonStylesMeta, component: Gtk.Button.$gtype };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
initialize(): void {
|
|
29
|
+
// Adw.WrapBox so the row reflows onto multiple lines instead of
|
|
30
|
+
// overflowing when the preview is narrow.
|
|
31
|
+
const box = new Adw.WrapBox({ childSpacing: 12, lineSpacing: 12, halign: Gtk.Align.CENTER });
|
|
32
|
+
|
|
33
|
+
const pill = new Gtk.Button({ label: 'Pill' });
|
|
34
|
+
pill.add_css_class('pill');
|
|
35
|
+
box.append(pill);
|
|
36
|
+
|
|
37
|
+
const circular = new Gtk.Button({ iconName: 'list-add-symbolic' });
|
|
38
|
+
circular.add_css_class('circular');
|
|
39
|
+
box.append(circular);
|
|
40
|
+
|
|
41
|
+
const suggested = new Gtk.Button({ label: 'Suggested' });
|
|
42
|
+
suggested.add_css_class('suggested-action');
|
|
43
|
+
box.append(suggested);
|
|
44
|
+
|
|
45
|
+
const destructive = new Gtk.Button({ label: 'Delete' });
|
|
46
|
+
destructive.add_css_class('destructive-action');
|
|
47
|
+
box.append(destructive);
|
|
48
|
+
|
|
49
|
+
const flat = new Gtk.Button({ label: 'Flat' });
|
|
50
|
+
flat.add_css_class('flat');
|
|
51
|
+
box.append(flat);
|
|
52
|
+
|
|
53
|
+
this._demo = new Gtk.Button({ label: this.args.label as string });
|
|
54
|
+
this._applyStyle(this.args.style as string);
|
|
55
|
+
box.append(this._demo);
|
|
56
|
+
|
|
57
|
+
this.addContent(box);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
private _applyStyle(style: string): void {
|
|
61
|
+
if (!this._demo) return;
|
|
62
|
+
for (const cls of STYLE_CLASSES) {
|
|
63
|
+
this._demo.remove_css_class(cls);
|
|
64
|
+
}
|
|
65
|
+
this._demo.add_css_class(style);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
updateArgs(_args: StoryArgs): void {
|
|
69
|
+
if (!this._demo) return;
|
|
70
|
+
this._demo.label = this.args.label as string;
|
|
71
|
+
this._applyStyle(this.args.style as string);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
GObject.type_ensure(ButtonStylesStory.$gtype);
|
|
76
|
+
|
|
77
|
+
export const ButtonStylesStories: StoryModule = { stories: [ButtonStylesStory] };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// Shared, renderer-agnostic metadata for the Split Button stories. Imported by
|
|
2
|
+
// both the GTK renderer (split-button.story.ts) and the browser renderer
|
|
3
|
+
// (browser/buttons/split-button.web.ts) so the two expose identical controls.
|
|
4
|
+
|
|
5
|
+
import { ControlType, type StoryMeta } from '@gjsify/stories';
|
|
6
|
+
|
|
7
|
+
export const splitButtonMeta: StoryMeta = {
|
|
8
|
+
title: 'Buttons/Split Button',
|
|
9
|
+
description: 'Adw.SplitButton — a primary action button paired with a dropdown menu of related actions.',
|
|
10
|
+
controls: [
|
|
11
|
+
{ name: 'label', label: 'Label', type: ControlType.TEXT, defaultValue: 'Save' },
|
|
12
|
+
{
|
|
13
|
+
name: 'iconName',
|
|
14
|
+
label: 'Icon',
|
|
15
|
+
type: ControlType.SELECT,
|
|
16
|
+
options: [
|
|
17
|
+
{ label: 'None', value: '' },
|
|
18
|
+
{ label: 'Save', value: 'document-save-symbolic' },
|
|
19
|
+
{ label: 'Send', value: 'mail-send-symbolic' },
|
|
20
|
+
{ label: 'Add', value: 'list-add-symbolic' },
|
|
21
|
+
],
|
|
22
|
+
defaultValue: 'document-save-symbolic',
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const splitButtonFlatMeta: StoryMeta = {
|
|
28
|
+
title: 'Buttons/Split Button Flat',
|
|
29
|
+
description: 'Adw.SplitButton with the .flat style class, as used inside header bars and toolbars.',
|
|
30
|
+
controls: [
|
|
31
|
+
{ name: 'label', label: 'Label', type: ControlType.TEXT, defaultValue: 'Reply' },
|
|
32
|
+
{
|
|
33
|
+
name: 'iconName',
|
|
34
|
+
label: 'Icon',
|
|
35
|
+
type: ControlType.SELECT,
|
|
36
|
+
options: [
|
|
37
|
+
{ label: 'None', value: '' },
|
|
38
|
+
{ label: 'Reply', value: 'mail-reply-sender-symbolic' },
|
|
39
|
+
{ label: 'Edit', value: 'document-edit-symbolic' },
|
|
40
|
+
{ label: 'Open', value: 'document-open-symbolic' },
|
|
41
|
+
],
|
|
42
|
+
defaultValue: 'mail-reply-sender-symbolic',
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// Adw.SplitButton — a button with a main action plus an attached dropdown menu.
|
|
2
|
+
// original implementation.
|
|
3
|
+
|
|
4
|
+
import Adw from '@girs/adw-1';
|
|
5
|
+
import Gio from '@girs/gio-2.0';
|
|
6
|
+
import GObject from '@girs/gobject-2.0';
|
|
7
|
+
import { type StoryArgs, type StoryMeta, type StoryModule, StoryWidget } from '@gjsify/storybook';
|
|
8
|
+
import { splitButtonFlatMeta, splitButtonMeta } from './split-button.meta.js';
|
|
9
|
+
|
|
10
|
+
/** Builds the shared dropdown menu model used by both split-button variants. */
|
|
11
|
+
function buildMenu(): Gio.Menu {
|
|
12
|
+
const menu = new Gio.Menu();
|
|
13
|
+
menu.append('Save as…', 'app.save-as');
|
|
14
|
+
menu.append('Export', 'app.export');
|
|
15
|
+
menu.append('Print', 'app.print');
|
|
16
|
+
return menu;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Story: Adw.SplitButton with a primary action and a dropdown menu. */
|
|
20
|
+
export class SplitButtonStory extends StoryWidget {
|
|
21
|
+
private _widget: Adw.SplitButton | null = null;
|
|
22
|
+
|
|
23
|
+
static {
|
|
24
|
+
GObject.registerClass({ GTypeName: 'AdwStorybookSplitButton' }, SplitButtonStory);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
constructor() {
|
|
28
|
+
super(StoryWidget.fromMeta(SplitButtonStory.getMetadata(), 'Default'));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
static getMetadata(): StoryMeta {
|
|
32
|
+
return { ...splitButtonMeta, component: Adw.SplitButton.$gtype };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
initialize(): void {
|
|
36
|
+
this._widget = new Adw.SplitButton({
|
|
37
|
+
label: this.args.label as string,
|
|
38
|
+
menuModel: buildMenu(),
|
|
39
|
+
});
|
|
40
|
+
const iconName = this.args.iconName as string;
|
|
41
|
+
if (iconName) {
|
|
42
|
+
this._widget.iconName = iconName;
|
|
43
|
+
}
|
|
44
|
+
this.addContent(this._widget);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
updateArgs(_args: StoryArgs): void {
|
|
48
|
+
if (!this._widget) return;
|
|
49
|
+
const iconName = this.args.iconName as string;
|
|
50
|
+
if (iconName) {
|
|
51
|
+
this._widget.iconName = iconName;
|
|
52
|
+
} else {
|
|
53
|
+
this._widget.label = this.args.label as string;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
GObject.type_ensure(SplitButtonStory.$gtype);
|
|
59
|
+
|
|
60
|
+
/** Story: a flat-styled Adw.SplitButton, suited to header bars and toolbars. */
|
|
61
|
+
export class SplitButtonFlatStory extends StoryWidget {
|
|
62
|
+
private _widget: Adw.SplitButton | null = null;
|
|
63
|
+
|
|
64
|
+
static {
|
|
65
|
+
GObject.registerClass({ GTypeName: 'AdwStorybookSplitButtonFlat' }, SplitButtonFlatStory);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
constructor() {
|
|
69
|
+
super(StoryWidget.fromMeta(SplitButtonFlatStory.getMetadata(), 'Default'));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
static getMetadata(): StoryMeta {
|
|
73
|
+
return { ...splitButtonFlatMeta, component: Adw.SplitButton.$gtype };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
initialize(): void {
|
|
77
|
+
this._widget = new Adw.SplitButton({
|
|
78
|
+
label: this.args.label as string,
|
|
79
|
+
menuModel: buildMenu(),
|
|
80
|
+
});
|
|
81
|
+
this._widget.add_css_class('flat');
|
|
82
|
+
const iconName = this.args.iconName as string;
|
|
83
|
+
if (iconName) {
|
|
84
|
+
this._widget.iconName = iconName;
|
|
85
|
+
}
|
|
86
|
+
this.addContent(this._widget);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
updateArgs(_args: StoryArgs): void {
|
|
90
|
+
if (!this._widget) return;
|
|
91
|
+
const iconName = this.args.iconName as string;
|
|
92
|
+
if (iconName) {
|
|
93
|
+
this._widget.iconName = iconName;
|
|
94
|
+
} else {
|
|
95
|
+
this._widget.label = this.args.label as string;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
GObject.type_ensure(SplitButtonFlatStory.$gtype);
|
|
101
|
+
|
|
102
|
+
export const SplitButtonStories: StoryModule = { stories: [SplitButtonStory, SplitButtonFlatStory] };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// Shared, renderer-agnostic metadata for the Toggle Group story. Imported by
|
|
2
|
+
// both the GTK renderer (toggle-group.story.ts) and the browser renderer
|
|
3
|
+
// (browser/buttons/toggle-group.web.ts) so the two expose identical controls.
|
|
4
|
+
|
|
5
|
+
import { ControlType, type StoryMeta } from '@gjsify/stories';
|
|
6
|
+
|
|
7
|
+
export const toggleGroupMeta: StoryMeta = {
|
|
8
|
+
title: 'Buttons/Toggle Group',
|
|
9
|
+
description: 'Adw.ToggleGroup — a linked group of Adw.Toggle buttons where exactly one is active.',
|
|
10
|
+
controls: [
|
|
11
|
+
{
|
|
12
|
+
name: 'active',
|
|
13
|
+
label: 'Active toggle',
|
|
14
|
+
type: ControlType.SELECT,
|
|
15
|
+
options: [
|
|
16
|
+
{ label: 'List', value: 0 },
|
|
17
|
+
{ label: 'Grid', value: 1 },
|
|
18
|
+
{ label: 'Columns', value: 2 },
|
|
19
|
+
],
|
|
20
|
+
defaultValue: 0,
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: 'style',
|
|
24
|
+
label: 'Style',
|
|
25
|
+
type: ControlType.SELECT,
|
|
26
|
+
options: [
|
|
27
|
+
{ label: 'Default', value: 'default' },
|
|
28
|
+
{ label: 'Flat', value: 'flat' },
|
|
29
|
+
{ label: 'Round', value: 'round' },
|
|
30
|
+
],
|
|
31
|
+
defaultValue: 'default',
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// Adw.ToggleGroup — a linked set of Adw.Toggle buttons with a single active item.
|
|
2
|
+
// original implementation.
|
|
3
|
+
|
|
4
|
+
import Adw from '@girs/adw-1';
|
|
5
|
+
import GObject from '@girs/gobject-2.0';
|
|
6
|
+
import { type StoryArgs, type StoryMeta, type StoryModule, StoryWidget } from '@gjsify/storybook';
|
|
7
|
+
import { toggleGroupMeta } from './toggle-group.meta.js';
|
|
8
|
+
|
|
9
|
+
const STYLE_CLASSES = ['flat', 'round'] as const;
|
|
10
|
+
|
|
11
|
+
/** Story: Adw.ToggleGroup populated with three Adw.Toggle items. */
|
|
12
|
+
export class ToggleGroupStory extends StoryWidget {
|
|
13
|
+
private _toggleGroup: Adw.ToggleGroup | null = null;
|
|
14
|
+
|
|
15
|
+
static {
|
|
16
|
+
GObject.registerClass({ GTypeName: 'AdwStorybookToggleGroup' }, ToggleGroupStory);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
constructor() {
|
|
20
|
+
super(StoryWidget.fromMeta(ToggleGroupStory.getMetadata(), 'Default'));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
static getMetadata(): StoryMeta {
|
|
24
|
+
return { ...toggleGroupMeta, component: Adw.ToggleGroup.$gtype };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
initialize(): void {
|
|
28
|
+
this._toggleGroup = new Adw.ToggleGroup();
|
|
29
|
+
this._toggleGroup.add(new Adw.Toggle({ label: 'List', iconName: 'view-list-symbolic' }));
|
|
30
|
+
this._toggleGroup.add(new Adw.Toggle({ label: 'Grid', iconName: 'view-grid-symbolic' }));
|
|
31
|
+
this._toggleGroup.add(new Adw.Toggle({ label: 'Columns', iconName: 'view-columns-symbolic' }));
|
|
32
|
+
this._toggleGroup.active = this.args.active as number;
|
|
33
|
+
this._applyStyle(this.args.style as string);
|
|
34
|
+
this.addContent(this._toggleGroup);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
private _applyStyle(style: string): void {
|
|
38
|
+
if (!this._toggleGroup) return;
|
|
39
|
+
for (const cls of STYLE_CLASSES) {
|
|
40
|
+
this._toggleGroup.remove_css_class(cls);
|
|
41
|
+
}
|
|
42
|
+
if (style !== 'default') {
|
|
43
|
+
this._toggleGroup.add_css_class(style);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
updateArgs(_args: StoryArgs): void {
|
|
48
|
+
if (!this._toggleGroup) return;
|
|
49
|
+
this._toggleGroup.active = this.args.active as number;
|
|
50
|
+
this._applyStyle(this.args.style as string);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
GObject.type_ensure(ToggleGroupStory.$gtype);
|
|
55
|
+
|
|
56
|
+
export const ToggleGroupStories: StoryModule = { stories: [ToggleGroupStory] };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Shared, renderer-agnostic metadata for the About Dialog story.
|
|
2
|
+
|
|
3
|
+
import { ControlType, type StoryMeta } from '@gjsify/stories';
|
|
4
|
+
|
|
5
|
+
export const aboutDialogMeta: StoryMeta = {
|
|
6
|
+
title: 'Feedback/About Dialog',
|
|
7
|
+
description:
|
|
8
|
+
'Adw.AboutDialog — the standard Adwaita about window with application name, version, credits and license.',
|
|
9
|
+
controls: [
|
|
10
|
+
{ name: 'applicationName', label: 'Application name', type: ControlType.TEXT, defaultValue: 'Adwaita Storybook' },
|
|
11
|
+
{ name: 'version', label: 'Version', type: ControlType.TEXT, defaultValue: '0.11.0' },
|
|
12
|
+
],
|
|
13
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// Adw.AboutDialog — the standard Adwaita "About" window for an application.
|
|
2
|
+
// 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 { aboutDialogMeta } from './about-dialog.meta.js';
|
|
9
|
+
|
|
10
|
+
/** Story: Adw.AboutDialog presented from a button, with app metadata + credits. */
|
|
11
|
+
export class AboutDialogStory extends StoryWidget {
|
|
12
|
+
private _button: Gtk.Button | null = null;
|
|
13
|
+
|
|
14
|
+
static {
|
|
15
|
+
GObject.registerClass({ GTypeName: 'AdwStorybookAboutDialog' }, AboutDialogStory);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
constructor() {
|
|
19
|
+
super(StoryWidget.fromMeta(AboutDialogStory.getMetadata(), 'Default'));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
static getMetadata(): StoryMeta {
|
|
23
|
+
return { ...aboutDialogMeta, component: Adw.AboutDialog.$gtype };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
initialize(): void {
|
|
27
|
+
this._button = new Gtk.Button({
|
|
28
|
+
label: 'Show dialog',
|
|
29
|
+
halign: Gtk.Align.CENTER,
|
|
30
|
+
valign: Gtk.Align.CENTER,
|
|
31
|
+
});
|
|
32
|
+
this._button.add_css_class('pill');
|
|
33
|
+
this._button.add_css_class('suggested-action');
|
|
34
|
+
this._button.connect('clicked', () => this._present());
|
|
35
|
+
|
|
36
|
+
this.addContent(this._button);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
private _present(): void {
|
|
40
|
+
const dialog = new Adw.AboutDialog({
|
|
41
|
+
applicationName: this.args.applicationName as string,
|
|
42
|
+
applicationIcon: 'application-x-executable-symbolic',
|
|
43
|
+
developerName: 'A GJSify Project',
|
|
44
|
+
version: this.args.version as string,
|
|
45
|
+
comments: 'A live catalogue of native GTK and Adwaita widgets, rendered under GJS.',
|
|
46
|
+
website: 'https://github.com/gjsify/gjsify',
|
|
47
|
+
issueUrl: 'https://github.com/gjsify/gjsify/issues',
|
|
48
|
+
licenseType: Gtk.License.MIT_X11,
|
|
49
|
+
developers: ['Ada Lovelace', 'Grace Hopper'],
|
|
50
|
+
designers: ['Margaret Hamilton'],
|
|
51
|
+
copyright: '© 2026 The GJSify Project',
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
dialog.present(this);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
updateArgs(_args: StoryArgs): void {
|
|
58
|
+
// The dialog reads the latest args each time it is presented; nothing to mutate live.
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
GObject.type_ensure(AboutDialogStory.$gtype);
|
|
63
|
+
|
|
64
|
+
export const AboutDialogStories: StoryModule = { stories: [AboutDialogStory] };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Shared, renderer-agnostic metadata for the Alert Dialog story.
|
|
2
|
+
|
|
3
|
+
import { ControlType, type StoryMeta } from '@gjsify/stories';
|
|
4
|
+
|
|
5
|
+
export const alertDialogMeta: StoryMeta = {
|
|
6
|
+
title: 'Feedback/Alert Dialog',
|
|
7
|
+
description:
|
|
8
|
+
'Adw.AlertDialog — a modal dialog with a heading, body text and responses, including a destructive action.',
|
|
9
|
+
controls: [
|
|
10
|
+
{ name: 'heading', label: 'Heading', type: ControlType.TEXT, defaultValue: 'Delete Project?' },
|
|
11
|
+
{
|
|
12
|
+
name: 'body',
|
|
13
|
+
label: 'Body',
|
|
14
|
+
type: ControlType.TEXT,
|
|
15
|
+
defaultValue:
|
|
16
|
+
'This will permanently remove the project and all of its files. This action cannot be undone.',
|
|
17
|
+
},
|
|
18
|
+
],
|
|
19
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// Adw.AlertDialog — a modal dialog with a heading, body and a row of responses.
|
|
2
|
+
// 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 { alertDialogMeta } from './alert-dialog.meta.js';
|
|
9
|
+
|
|
10
|
+
/** Story: Adw.AlertDialog presented from a button, with cancel/destructive responses. */
|
|
11
|
+
export class AlertDialogStory extends StoryWidget {
|
|
12
|
+
private _button: Gtk.Button | null = null;
|
|
13
|
+
|
|
14
|
+
static {
|
|
15
|
+
GObject.registerClass({ GTypeName: 'AdwStorybookAlertDialog' }, AlertDialogStory);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
constructor() {
|
|
19
|
+
super(StoryWidget.fromMeta(AlertDialogStory.getMetadata(), 'Default'));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
static getMetadata(): StoryMeta {
|
|
23
|
+
return { ...alertDialogMeta, component: Adw.AlertDialog.$gtype };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
initialize(): void {
|
|
27
|
+
this._button = new Gtk.Button({
|
|
28
|
+
label: 'Show dialog',
|
|
29
|
+
halign: Gtk.Align.CENTER,
|
|
30
|
+
valign: Gtk.Align.CENTER,
|
|
31
|
+
});
|
|
32
|
+
this._button.add_css_class('pill');
|
|
33
|
+
this._button.add_css_class('suggested-action');
|
|
34
|
+
this._button.connect('clicked', () => this._present());
|
|
35
|
+
|
|
36
|
+
this.addContent(this._button);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
private _present(): void {
|
|
40
|
+
const dialog = new Adw.AlertDialog({
|
|
41
|
+
heading: this.args.heading as string,
|
|
42
|
+
body: this.args.body as string,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
dialog.add_response('cancel', 'Cancel');
|
|
46
|
+
dialog.add_response('delete', 'Delete');
|
|
47
|
+
dialog.set_response_appearance('delete', Adw.ResponseAppearance.DESTRUCTIVE);
|
|
48
|
+
dialog.set_default_response('cancel');
|
|
49
|
+
dialog.set_close_response('cancel');
|
|
50
|
+
|
|
51
|
+
dialog.present(this);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
updateArgs(_args: StoryArgs): void {
|
|
55
|
+
// The dialog reads the latest args each time it is presented; nothing to mutate live.
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
GObject.type_ensure(AlertDialogStory.$gtype);
|
|
60
|
+
|
|
61
|
+
export const AlertDialogStories: StoryModule = { stories: [AlertDialogStory] };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Shared, renderer-agnostic metadata for the Preferences Dialog story.
|
|
2
|
+
|
|
3
|
+
import { ControlType, type StoryMeta } from '@gjsify/stories';
|
|
4
|
+
|
|
5
|
+
export const preferencesDialogMeta: StoryMeta = {
|
|
6
|
+
title: 'Feedback/Preferences Dialog',
|
|
7
|
+
description:
|
|
8
|
+
'Adw.PreferencesDialog — a preferences window with a page, a group and a handful of boxed-list rows.',
|
|
9
|
+
controls: [
|
|
10
|
+
{ name: 'pageTitle', label: 'Page title', type: ControlType.TEXT, defaultValue: 'General' },
|
|
11
|
+
{ name: 'groupTitle', label: 'Group title', type: ControlType.TEXT, defaultValue: 'Appearance' },
|
|
12
|
+
],
|
|
13
|
+
};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// Adw.PreferencesDialog — a multi-page preferences window built from pages,
|
|
2
|
+
// groups and rows. 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 { preferencesDialogMeta } from './preferences-dialog.meta.js';
|
|
9
|
+
|
|
10
|
+
/** Story: Adw.PreferencesDialog presented from a button, with one page of rows. */
|
|
11
|
+
export class PreferencesDialogStory extends StoryWidget {
|
|
12
|
+
private _button: Gtk.Button | null = null;
|
|
13
|
+
|
|
14
|
+
static {
|
|
15
|
+
GObject.registerClass({ GTypeName: 'AdwStorybookPreferencesDialog' }, PreferencesDialogStory);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
constructor() {
|
|
19
|
+
super(StoryWidget.fromMeta(PreferencesDialogStory.getMetadata(), 'Default'));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
static getMetadata(): StoryMeta {
|
|
23
|
+
return { ...preferencesDialogMeta, component: Adw.PreferencesDialog.$gtype };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
initialize(): void {
|
|
27
|
+
this._button = new Gtk.Button({
|
|
28
|
+
label: 'Show dialog',
|
|
29
|
+
halign: Gtk.Align.CENTER,
|
|
30
|
+
valign: Gtk.Align.CENTER,
|
|
31
|
+
});
|
|
32
|
+
this._button.add_css_class('pill');
|
|
33
|
+
this._button.add_css_class('suggested-action');
|
|
34
|
+
this._button.connect('clicked', () => this._present());
|
|
35
|
+
|
|
36
|
+
this.addContent(this._button);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
private _present(): void {
|
|
40
|
+
const dialog = new Adw.PreferencesDialog();
|
|
41
|
+
|
|
42
|
+
const page = new Adw.PreferencesPage({
|
|
43
|
+
title: this.args.pageTitle as string,
|
|
44
|
+
iconName: 'preferences-system-symbolic',
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const group = new Adw.PreferencesGroup({
|
|
48
|
+
title: this.args.groupTitle as string,
|
|
49
|
+
description: 'Control how the application looks and behaves.',
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
group.add(
|
|
53
|
+
new Adw.SwitchRow({
|
|
54
|
+
title: 'Dark style',
|
|
55
|
+
subtitle: 'Use a dark colour scheme',
|
|
56
|
+
active: true,
|
|
57
|
+
}),
|
|
58
|
+
);
|
|
59
|
+
group.add(
|
|
60
|
+
new Adw.ComboRow({
|
|
61
|
+
title: 'Accent colour',
|
|
62
|
+
model: new Gtk.StringList({ strings: ['Blue', 'Teal', 'Green', 'Orange', 'Purple'] }),
|
|
63
|
+
selected: 0,
|
|
64
|
+
}),
|
|
65
|
+
);
|
|
66
|
+
group.add(
|
|
67
|
+
new Adw.SpinRow({
|
|
68
|
+
title: 'Font size',
|
|
69
|
+
adjustment: new Gtk.Adjustment({
|
|
70
|
+
lower: 8,
|
|
71
|
+
upper: 24,
|
|
72
|
+
value: 12,
|
|
73
|
+
stepIncrement: 1,
|
|
74
|
+
pageIncrement: 4,
|
|
75
|
+
}),
|
|
76
|
+
}),
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
page.add(group);
|
|
80
|
+
dialog.add(page);
|
|
81
|
+
|
|
82
|
+
dialog.present(this);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
updateArgs(_args: StoryArgs): void {
|
|
86
|
+
// The dialog is rebuilt from the latest args each time it is presented.
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
GObject.type_ensure(PreferencesDialogStory.$gtype);
|
|
91
|
+
|
|
92
|
+
export const PreferencesDialogStories: StoryModule = { stories: [PreferencesDialogStory] };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Shared, renderer-agnostic metadata for the Toast story.
|
|
2
|
+
|
|
3
|
+
import { ControlType, type StoryMeta } from '@gjsify/stories';
|
|
4
|
+
|
|
5
|
+
export const toastMeta: StoryMeta = {
|
|
6
|
+
title: 'Feedback/Toast',
|
|
7
|
+
description:
|
|
8
|
+
'Adw.Toast — a transient notification, with an optional action button, shown over an Adw.ToastOverlay.',
|
|
9
|
+
controls: [
|
|
10
|
+
{ name: 'title', label: 'Toast text', type: ControlType.TEXT, defaultValue: 'File moved to Trash' },
|
|
11
|
+
{
|
|
12
|
+
name: 'timeout',
|
|
13
|
+
label: 'Timeout (s)',
|
|
14
|
+
type: ControlType.NUMBER,
|
|
15
|
+
min: 0,
|
|
16
|
+
max: 10,
|
|
17
|
+
step: 1,
|
|
18
|
+
defaultValue: 3,
|
|
19
|
+
},
|
|
20
|
+
{ name: 'hasButton', label: 'Action button', type: ControlType.BOOLEAN, defaultValue: true },
|
|
21
|
+
{ name: 'buttonLabel', label: 'Button label', type: ControlType.TEXT, defaultValue: 'Undo' },
|
|
22
|
+
],
|
|
23
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// Adw.Toast — a transient notification shown over content via Adw.ToastOverlay.
|
|
2
|
+
// 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 { toastMeta } from './toast.meta.js';
|
|
9
|
+
|
|
10
|
+
/** Story: Adw.Toast presented through an Adw.ToastOverlay on button press. */
|
|
11
|
+
export class ToastStory extends StoryWidget {
|
|
12
|
+
private _overlay: Adw.ToastOverlay | null = null;
|
|
13
|
+
|
|
14
|
+
static {
|
|
15
|
+
GObject.registerClass({ GTypeName: 'AdwStorybookToast' }, ToastStory);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
constructor() {
|
|
19
|
+
super(StoryWidget.fromMeta(ToastStory.getMetadata(), 'Default'));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
static getMetadata(): StoryMeta {
|
|
23
|
+
return { ...toastMeta, component: Adw.Toast.$gtype };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
initialize(): void {
|
|
27
|
+
const button = new Gtk.Button({
|
|
28
|
+
label: 'Show toast',
|
|
29
|
+
halign: Gtk.Align.CENTER,
|
|
30
|
+
valign: Gtk.Align.CENTER,
|
|
31
|
+
});
|
|
32
|
+
button.add_css_class('pill');
|
|
33
|
+
button.add_css_class('suggested-action');
|
|
34
|
+
button.connect('clicked', () => this._showToast());
|
|
35
|
+
|
|
36
|
+
this._overlay = new Adw.ToastOverlay({
|
|
37
|
+
child: button,
|
|
38
|
+
widthRequest: 360,
|
|
39
|
+
heightRequest: 220,
|
|
40
|
+
});
|
|
41
|
+
this.addContent(this._overlay);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
private _showToast(): void {
|
|
45
|
+
if (!this._overlay) return;
|
|
46
|
+
|
|
47
|
+
const toast = new Adw.Toast({
|
|
48
|
+
title: this.args.title as string,
|
|
49
|
+
timeout: this.args.timeout as number,
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
if (this.args.hasButton as boolean) {
|
|
53
|
+
toast.buttonLabel = this.args.buttonLabel as string;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
this._overlay.add_toast(toast);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
updateArgs(_args: StoryArgs): void {
|
|
60
|
+
// Toasts are built on demand in _showToast(); nothing to re-apply to the overlay.
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
GObject.type_ensure(ToastStory.$gtype);
|
|
65
|
+
|
|
66
|
+
export const ToastStories: StoryModule = { stories: [ToastStory] };
|