@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,29 @@
|
|
|
1
|
+
// Shared, renderer-agnostic metadata for the Clamp story.
|
|
2
|
+
|
|
3
|
+
import { ControlType, type StoryMeta } from '@gjsify/stories';
|
|
4
|
+
|
|
5
|
+
export const clampMeta: StoryMeta = {
|
|
6
|
+
title: 'Layout/Clamp',
|
|
7
|
+
description:
|
|
8
|
+
'Adw.Clamp limits its child to a maximum width and centres it, tightening the layout as space shrinks.',
|
|
9
|
+
controls: [
|
|
10
|
+
{
|
|
11
|
+
name: 'maximumSize',
|
|
12
|
+
label: 'Maximum size',
|
|
13
|
+
type: ControlType.RANGE,
|
|
14
|
+
min: 200,
|
|
15
|
+
max: 600,
|
|
16
|
+
step: 10,
|
|
17
|
+
defaultValue: 400,
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: 'tighteningThreshold',
|
|
21
|
+
label: 'Tightening threshold',
|
|
22
|
+
type: ControlType.RANGE,
|
|
23
|
+
min: 100,
|
|
24
|
+
max: 600,
|
|
25
|
+
step: 10,
|
|
26
|
+
defaultValue: 300,
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// Adw.Clamp — constrains its child to a maximum size, centring it within wider space.
|
|
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 { clampMeta } from './clamp.meta.js';
|
|
9
|
+
|
|
10
|
+
/** Story: Adw.Clamp constraining a wide child so the clamping is visible. */
|
|
11
|
+
export class ClampStory extends StoryWidget {
|
|
12
|
+
private _clamp: Adw.Clamp | null = null;
|
|
13
|
+
|
|
14
|
+
static {
|
|
15
|
+
GObject.registerClass({ GTypeName: 'AdwStorybookClamp' }, ClampStory);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
constructor() {
|
|
19
|
+
super(StoryWidget.fromMeta(ClampStory.getMetadata(), 'Default'));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
static getMetadata(): StoryMeta {
|
|
23
|
+
return { ...clampMeta, component: Adw.Clamp.$gtype };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
initialize(): void {
|
|
27
|
+
const inner = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL, widthRequest: 520 });
|
|
28
|
+
inner.add_css_class('card');
|
|
29
|
+
|
|
30
|
+
const label = new Gtk.Label({
|
|
31
|
+
label: 'This content is clamped — it stops growing past the maximum size and stays centred.',
|
|
32
|
+
wrap: true,
|
|
33
|
+
xalign: 0,
|
|
34
|
+
hexpand: true,
|
|
35
|
+
marginTop: 18,
|
|
36
|
+
marginBottom: 18,
|
|
37
|
+
marginStart: 18,
|
|
38
|
+
marginEnd: 18,
|
|
39
|
+
});
|
|
40
|
+
inner.append(label);
|
|
41
|
+
|
|
42
|
+
this._clamp = new Adw.Clamp({
|
|
43
|
+
maximumSize: this.args.maximumSize as number,
|
|
44
|
+
tighteningThreshold: this.args.tighteningThreshold as number,
|
|
45
|
+
child: inner,
|
|
46
|
+
});
|
|
47
|
+
this.addContent(this._clamp);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
updateArgs(_args: StoryArgs): void {
|
|
51
|
+
if (!this._clamp) return;
|
|
52
|
+
this._clamp.maximumSize = this.args.maximumSize as number;
|
|
53
|
+
this._clamp.tighteningThreshold = this.args.tighteningThreshold as number;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
GObject.type_ensure(ClampStory.$gtype);
|
|
58
|
+
|
|
59
|
+
export const ClampStories: StoryModule = { stories: [ClampStory] };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Shared, renderer-agnostic metadata for the Header Bar story.
|
|
2
|
+
|
|
3
|
+
import { ControlType, type StoryMeta } from '@gjsify/stories';
|
|
4
|
+
|
|
5
|
+
export const headerBarMeta: StoryMeta = {
|
|
6
|
+
title: 'Layout/Header Bar',
|
|
7
|
+
description:
|
|
8
|
+
'Adw.HeaderBar hosts a custom title widget with start and end controls — the standard top chrome of an Adwaita window.',
|
|
9
|
+
controls: [
|
|
10
|
+
{ name: 'title', label: 'Title', type: ControlType.TEXT, defaultValue: 'Text Editor' },
|
|
11
|
+
{ name: 'subtitle', label: 'Subtitle', type: ControlType.TEXT, defaultValue: 'notes.md' },
|
|
12
|
+
{ name: 'showTitle', label: 'Show title', type: ControlType.BOOLEAN, defaultValue: true },
|
|
13
|
+
],
|
|
14
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// Adw.HeaderBar — a window header bar with a custom title widget and packed buttons.
|
|
2
|
+
// original implementation.
|
|
3
|
+
|
|
4
|
+
import Adw from '@girs/adw-1';
|
|
5
|
+
import Gtk from '@girs/gtk-4.0';
|
|
6
|
+
import Gio from '@girs/gio-2.0';
|
|
7
|
+
import GObject from '@girs/gobject-2.0';
|
|
8
|
+
import { type StoryArgs, type StoryMeta, type StoryModule, StoryWidget } from '@gjsify/storybook';
|
|
9
|
+
import { headerBarMeta } from './header-bar.meta.js';
|
|
10
|
+
|
|
11
|
+
/** Story: Adw.HeaderBar with an Adw.WindowTitle, a start icon button and an end menu button. */
|
|
12
|
+
export class HeaderBarStory extends StoryWidget {
|
|
13
|
+
private _headerBar: Adw.HeaderBar | null = null;
|
|
14
|
+
private _title: Adw.WindowTitle | null = null;
|
|
15
|
+
|
|
16
|
+
static {
|
|
17
|
+
GObject.registerClass({ GTypeName: 'AdwStorybookHeaderBar' }, HeaderBarStory);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
constructor() {
|
|
21
|
+
super(StoryWidget.fromMeta(HeaderBarStory.getMetadata(), 'Default'));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
static getMetadata(): StoryMeta {
|
|
25
|
+
return { ...headerBarMeta, component: Adw.HeaderBar.$gtype };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
initialize(): void {
|
|
29
|
+
this._title = new Adw.WindowTitle({
|
|
30
|
+
title: this.args.title as string,
|
|
31
|
+
subtitle: this.args.subtitle as string,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
this._headerBar = new Adw.HeaderBar({
|
|
35
|
+
titleWidget: this._title,
|
|
36
|
+
showTitle: this.args.showTitle as boolean,
|
|
37
|
+
widthRequest: 460,
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const backButton = new Gtk.Button({ iconName: 'go-previous-symbolic' });
|
|
41
|
+
backButton.add_css_class('flat');
|
|
42
|
+
this._headerBar.pack_start(backButton);
|
|
43
|
+
|
|
44
|
+
const menu = new Gio.Menu();
|
|
45
|
+
menu.append('New Window', 'app.new-window');
|
|
46
|
+
menu.append('Preferences', 'app.preferences');
|
|
47
|
+
menu.append('About', 'app.about');
|
|
48
|
+
|
|
49
|
+
const menuButton = new Gtk.MenuButton({ iconName: 'open-menu-symbolic', menuModel: menu });
|
|
50
|
+
menuButton.add_css_class('flat');
|
|
51
|
+
this._headerBar.pack_end(menuButton);
|
|
52
|
+
|
|
53
|
+
this.addContent(this._headerBar);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
updateArgs(_args: StoryArgs): void {
|
|
57
|
+
if (!this._headerBar || !this._title) return;
|
|
58
|
+
this._title.title = this.args.title as string;
|
|
59
|
+
this._title.subtitle = this.args.subtitle as string;
|
|
60
|
+
this._headerBar.showTitle = this.args.showTitle as boolean;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
GObject.type_ensure(HeaderBarStory.$gtype);
|
|
65
|
+
|
|
66
|
+
export const HeaderBarStories: StoryModule = { stories: [HeaderBarStory] };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// Shared, renderer-agnostic metadata for the Toolbar View story.
|
|
2
|
+
|
|
3
|
+
import { ControlType, type StoryMeta } from '@gjsify/stories';
|
|
4
|
+
|
|
5
|
+
export const toolbarViewMeta: StoryMeta = {
|
|
6
|
+
title: 'Layout/Toolbar View',
|
|
7
|
+
description:
|
|
8
|
+
'Adw.ToolbarView pins a top header bar and a bottom toolbar around its content, each independently revealable.',
|
|
9
|
+
controls: [
|
|
10
|
+
{ name: 'revealTopBars', label: 'Reveal top bars', type: ControlType.BOOLEAN, defaultValue: true },
|
|
11
|
+
{
|
|
12
|
+
name: 'revealBottomBars',
|
|
13
|
+
label: 'Reveal bottom bars',
|
|
14
|
+
type: ControlType.BOOLEAN,
|
|
15
|
+
defaultValue: true,
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// Adw.ToolbarView — wraps content between revealable top and bottom toolbars.
|
|
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 { toolbarViewMeta } from './toolbar-view.meta.js';
|
|
9
|
+
|
|
10
|
+
/** Story: Adw.ToolbarView with a header bar, status-page content and a bottom action bar. */
|
|
11
|
+
export class ToolbarViewStory extends StoryWidget {
|
|
12
|
+
private _view: Adw.ToolbarView | null = null;
|
|
13
|
+
|
|
14
|
+
static {
|
|
15
|
+
GObject.registerClass({ GTypeName: 'AdwStorybookToolbarView' }, ToolbarViewStory);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
constructor() {
|
|
19
|
+
super(StoryWidget.fromMeta(ToolbarViewStory.getMetadata(), 'Default'));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
static getMetadata(): StoryMeta {
|
|
23
|
+
return { ...toolbarViewMeta, component: Adw.ToolbarView.$gtype };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
initialize(): void {
|
|
27
|
+
this._view = new Adw.ToolbarView({
|
|
28
|
+
widthRequest: 460,
|
|
29
|
+
heightRequest: 320,
|
|
30
|
+
revealTopBars: this.args.revealTopBars as boolean,
|
|
31
|
+
revealBottomBars: this.args.revealBottomBars as boolean,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const header = new Adw.HeaderBar({
|
|
35
|
+
titleWidget: new Adw.WindowTitle({ title: 'Documents', subtitle: '12 items' }),
|
|
36
|
+
});
|
|
37
|
+
this._view.add_top_bar(header);
|
|
38
|
+
|
|
39
|
+
const content = new Adw.StatusPage({
|
|
40
|
+
iconName: 'folder-documents-symbolic',
|
|
41
|
+
title: 'Your library',
|
|
42
|
+
description: 'Content sits between the toolbars and scrolls independently of them.',
|
|
43
|
+
});
|
|
44
|
+
this._view.content = content;
|
|
45
|
+
|
|
46
|
+
const bottomBar = new Gtk.ActionBar();
|
|
47
|
+
const addButton = new Gtk.Button({ iconName: 'list-add-symbolic' });
|
|
48
|
+
addButton.add_css_class('flat');
|
|
49
|
+
const removeButton = new Gtk.Button({ iconName: 'list-remove-symbolic' });
|
|
50
|
+
removeButton.add_css_class('flat');
|
|
51
|
+
bottomBar.pack_start(addButton);
|
|
52
|
+
bottomBar.pack_start(removeButton);
|
|
53
|
+
bottomBar.set_center_widget(new Gtk.Label({ label: 'Selection: none' }));
|
|
54
|
+
const shareButton = new Gtk.Button({ iconName: 'send-to-symbolic' });
|
|
55
|
+
shareButton.add_css_class('flat');
|
|
56
|
+
bottomBar.pack_end(shareButton);
|
|
57
|
+
this._view.add_bottom_bar(bottomBar);
|
|
58
|
+
|
|
59
|
+
this.addContent(this._view);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
updateArgs(_args: StoryArgs): void {
|
|
63
|
+
if (!this._view) return;
|
|
64
|
+
this._view.revealTopBars = this.args.revealTopBars as boolean;
|
|
65
|
+
this._view.revealBottomBars = this.args.revealBottomBars as boolean;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
GObject.type_ensure(ToolbarViewStory.$gtype);
|
|
70
|
+
|
|
71
|
+
export const ToolbarViewStories: StoryModule = { stories: [ToolbarViewStory] };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Shared, renderer-agnostic metadata for the Wrap Box story.
|
|
2
|
+
|
|
3
|
+
import { ControlType, type StoryMeta } from '@gjsify/stories';
|
|
4
|
+
|
|
5
|
+
export const wrapBoxMeta: StoryMeta = {
|
|
6
|
+
title: 'Layout/Wrap Box',
|
|
7
|
+
description:
|
|
8
|
+
'Adw.WrapBox flows its children horizontally and wraps them onto new lines when they run out of room.',
|
|
9
|
+
controls: [
|
|
10
|
+
{
|
|
11
|
+
name: 'childSpacing',
|
|
12
|
+
label: 'Child spacing',
|
|
13
|
+
type: ControlType.RANGE,
|
|
14
|
+
min: 0,
|
|
15
|
+
max: 36,
|
|
16
|
+
step: 1,
|
|
17
|
+
defaultValue: 8,
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: 'lineSpacing',
|
|
21
|
+
label: 'Line spacing',
|
|
22
|
+
type: ControlType.RANGE,
|
|
23
|
+
min: 0,
|
|
24
|
+
max: 36,
|
|
25
|
+
step: 1,
|
|
26
|
+
defaultValue: 8,
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// Adw.WrapBox — a box that lays children out in a line, wrapping onto new lines as needed.
|
|
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 { wrapBoxMeta } from './wrap-box.meta.js';
|
|
9
|
+
|
|
10
|
+
/** Story: Adw.WrapBox flowing a set of chip-like buttons across multiple lines. */
|
|
11
|
+
export class WrapBoxStory extends StoryWidget {
|
|
12
|
+
private _wrap: Adw.WrapBox | null = null;
|
|
13
|
+
|
|
14
|
+
static {
|
|
15
|
+
GObject.registerClass({ GTypeName: 'AdwStorybookWrapBox' }, WrapBoxStory);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
constructor() {
|
|
19
|
+
super(StoryWidget.fromMeta(WrapBoxStory.getMetadata(), 'Default'));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
static getMetadata(): StoryMeta {
|
|
23
|
+
return { ...wrapBoxMeta, component: Adw.WrapBox.$gtype };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
initialize(): void {
|
|
27
|
+
this._wrap = new Adw.WrapBox({
|
|
28
|
+
childSpacing: this.args.childSpacing as number,
|
|
29
|
+
lineSpacing: this.args.lineSpacing as number,
|
|
30
|
+
widthRequest: 460,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const tags = ['Design', 'Adwaita', 'GNOME', 'GTK', 'Typescript', 'Storybook', 'Wrapping', 'Layout'];
|
|
34
|
+
for (const tag of tags) {
|
|
35
|
+
const chip = new Gtk.Button({ label: tag });
|
|
36
|
+
chip.add_css_class('pill');
|
|
37
|
+
this._wrap.append(chip);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
this.addContent(this._wrap);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
updateArgs(_args: StoryArgs): void {
|
|
44
|
+
if (!this._wrap) return;
|
|
45
|
+
this._wrap.childSpacing = this.args.childSpacing as number;
|
|
46
|
+
this._wrap.lineSpacing = this.args.lineSpacing as number;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
GObject.type_ensure(WrapBoxStory.$gtype);
|
|
51
|
+
|
|
52
|
+
export const WrapBoxStories: StoryModule = { stories: [WrapBoxStory] };
|
package/src/metas.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Barrel re-exporting all renderer-agnostic story metadata (*.meta.ts) so
|
|
2
|
+
// sibling renderer packages (e.g. the NativeScript storybook showcase) can
|
|
3
|
+
// import the SAME metadata the GTK *.story.ts and browser *.web.ts use,
|
|
4
|
+
// keeping all three targets in lockstep for 1:1 comparison.
|
|
5
|
+
// Auto-generated grouping; safe to edit. Exported via package.json "./metas".
|
|
6
|
+
|
|
7
|
+
export * from './buttons/button-content.meta.js';
|
|
8
|
+
export * from './buttons/button-styles.meta.js';
|
|
9
|
+
export * from './buttons/split-button.meta.js';
|
|
10
|
+
export * from './buttons/toggle-group.meta.js';
|
|
11
|
+
export * from './feedback/about-dialog.meta.js';
|
|
12
|
+
export * from './feedback/alert-dialog.meta.js';
|
|
13
|
+
export * from './feedback/preferences-dialog.meta.js';
|
|
14
|
+
export * from './feedback/toast.meta.js';
|
|
15
|
+
export * from './layout/clamp.meta.js';
|
|
16
|
+
export * from './layout/header-bar.meta.js';
|
|
17
|
+
export * from './layout/toolbar-view.meta.js';
|
|
18
|
+
export * from './layout/wrap-box.meta.js';
|
|
19
|
+
export * from './navigation/bottom-sheet.meta.js';
|
|
20
|
+
export * from './navigation/navigation-split-view.meta.js';
|
|
21
|
+
export * from './navigation/navigation-view.meta.js';
|
|
22
|
+
export * from './navigation/overlay-split-view.meta.js';
|
|
23
|
+
export * from './navigation/sidebar.meta.js';
|
|
24
|
+
export * from './presentation/avatar.meta.js';
|
|
25
|
+
export * from './presentation/banner.meta.js';
|
|
26
|
+
export * from './presentation/spinner.meta.js';
|
|
27
|
+
export * from './presentation/status-page.meta.js';
|
|
28
|
+
export * from './presentation/window-title.meta.js';
|
|
29
|
+
export * from './rows/action-row.meta.js';
|
|
30
|
+
export * from './rows/button-row.meta.js';
|
|
31
|
+
export * from './rows/combo-row.meta.js';
|
|
32
|
+
export * from './rows/entry-row.meta.js';
|
|
33
|
+
export * from './rows/expander-row.meta.js';
|
|
34
|
+
export * from './rows/password-entry-row.meta.js';
|
|
35
|
+
export * from './rows/preferences-group.meta.js';
|
|
36
|
+
export * from './rows/spin-row.meta.js';
|
|
37
|
+
export * from './rows/switch-row.meta.js';
|
|
38
|
+
export * from './view-switching/carousel.meta.js';
|
|
39
|
+
export * from './view-switching/inline-view-switcher.meta.js';
|
|
40
|
+
export * from './view-switching/tab-view.meta.js';
|
|
41
|
+
export * from './view-switching/view-switcher.meta.js';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Shared, renderer-agnostic metadata for the Bottom Sheet story.
|
|
2
|
+
|
|
3
|
+
import { ControlType, type StoryMeta } from '@gjsify/stories';
|
|
4
|
+
|
|
5
|
+
export const bottomSheetMeta: StoryMeta = {
|
|
6
|
+
title: 'Navigation/Bottom Sheet',
|
|
7
|
+
description: 'Adw.BottomSheet — a sheet that slides up over the content. Toggle "Open" to reveal it.',
|
|
8
|
+
controls: [
|
|
9
|
+
{ name: 'open', label: 'Open', type: ControlType.BOOLEAN, defaultValue: true },
|
|
10
|
+
{ name: 'modal', label: 'Modal', type: ControlType.BOOLEAN, defaultValue: true },
|
|
11
|
+
{ name: 'canClose', label: 'Can close', type: ControlType.BOOLEAN, defaultValue: true },
|
|
12
|
+
],
|
|
13
|
+
};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// Adw.BottomSheet — a content area with a sheet that slides up from the bottom.
|
|
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 { bottomSheetMeta } from './bottom-sheet.meta.js';
|
|
9
|
+
|
|
10
|
+
/** Story: Adw.BottomSheet with a toggleable sheet child. */
|
|
11
|
+
export class BottomSheetStory extends StoryWidget {
|
|
12
|
+
private _sheet: Adw.BottomSheet | null = null;
|
|
13
|
+
|
|
14
|
+
static {
|
|
15
|
+
GObject.registerClass({ GTypeName: 'AdwStorybookBottomSheet' }, BottomSheetStory);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
constructor() {
|
|
19
|
+
super(StoryWidget.fromMeta(BottomSheetStory.getMetadata(), 'Default'));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
static getMetadata(): StoryMeta {
|
|
23
|
+
return { ...bottomSheetMeta, component: Adw.BottomSheet.$gtype };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
private buildContent(): Gtk.Widget {
|
|
27
|
+
const toggle = new Gtk.Button({
|
|
28
|
+
label: 'Toggle sheet',
|
|
29
|
+
halign: Gtk.Align.CENTER,
|
|
30
|
+
valign: Gtk.Align.CENTER,
|
|
31
|
+
vexpand: true,
|
|
32
|
+
});
|
|
33
|
+
toggle.add_css_class('pill');
|
|
34
|
+
toggle.add_css_class('suggested-action');
|
|
35
|
+
toggle.connect('clicked', () => {
|
|
36
|
+
if (this._sheet) this._sheet.open = !this._sheet.open;
|
|
37
|
+
});
|
|
38
|
+
return toggle;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
private buildSheet(): Gtk.Widget {
|
|
42
|
+
const box = new Gtk.Box({
|
|
43
|
+
orientation: Gtk.Orientation.VERTICAL,
|
|
44
|
+
spacing: 12,
|
|
45
|
+
marginTop: 18,
|
|
46
|
+
marginBottom: 24,
|
|
47
|
+
marginStart: 18,
|
|
48
|
+
marginEnd: 18,
|
|
49
|
+
});
|
|
50
|
+
box.append(new Gtk.Label({ label: 'Share track', halign: Gtk.Align.START, cssClasses: ['title-2'] }));
|
|
51
|
+
|
|
52
|
+
const group = new Adw.PreferencesGroup();
|
|
53
|
+
for (const [title, icon] of [
|
|
54
|
+
['Copy link', 'edit-copy-symbolic'],
|
|
55
|
+
['Send to a friend', 'mail-send-symbolic'],
|
|
56
|
+
['Add to playlist', 'list-add-symbolic'],
|
|
57
|
+
] as const) {
|
|
58
|
+
const row = new Adw.ActionRow({ title });
|
|
59
|
+
row.add_prefix(new Gtk.Image({ iconName: icon }));
|
|
60
|
+
row.activatable = true;
|
|
61
|
+
group.add(row);
|
|
62
|
+
}
|
|
63
|
+
box.append(group);
|
|
64
|
+
return box;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
initialize(): void {
|
|
68
|
+
this._sheet = new Adw.BottomSheet({
|
|
69
|
+
content: this.buildContent(),
|
|
70
|
+
sheet: this.buildSheet(),
|
|
71
|
+
open: this.args.open as boolean,
|
|
72
|
+
modal: this.args.modal as boolean,
|
|
73
|
+
canClose: this.args.canClose as boolean,
|
|
74
|
+
widthRequest: 480,
|
|
75
|
+
heightRequest: 340,
|
|
76
|
+
});
|
|
77
|
+
this.addContent(this._sheet);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
updateArgs(_args: StoryArgs): void {
|
|
81
|
+
if (!this._sheet) return;
|
|
82
|
+
this._sheet.open = this.args.open as boolean;
|
|
83
|
+
this._sheet.modal = this.args.modal as boolean;
|
|
84
|
+
this._sheet.canClose = this.args.canClose as boolean;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
GObject.type_ensure(BottomSheetStory.$gtype);
|
|
89
|
+
|
|
90
|
+
export const BottomSheetStories: StoryModule = { stories: [BottomSheetStory] };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Shared, renderer-agnostic metadata for the Navigation Split View story.
|
|
2
|
+
|
|
3
|
+
import { ControlType, type StoryMeta } from '@gjsify/stories';
|
|
4
|
+
|
|
5
|
+
export const navigationSplitViewMeta: StoryMeta = {
|
|
6
|
+
title: 'Navigation/Navigation Split View',
|
|
7
|
+
description:
|
|
8
|
+
'Adw.NavigationSplitView — a resizable sidebar beside a content pane. When collapsed it folds into a navigation stack.',
|
|
9
|
+
controls: [
|
|
10
|
+
{ name: 'showContent', label: 'Show content', type: ControlType.BOOLEAN, defaultValue: true },
|
|
11
|
+
{ name: 'collapsed', label: 'Collapsed', type: ControlType.BOOLEAN, defaultValue: false },
|
|
12
|
+
],
|
|
13
|
+
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// Adw.NavigationSplitView — a two-pane sidebar/content split that collapses
|
|
2
|
+
// into a single navigation stack. 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 { navigationSplitViewMeta } from './navigation-split-view.meta.js';
|
|
9
|
+
|
|
10
|
+
/** Story: Adw.NavigationSplitView with a boxed-list sidebar and a content page. */
|
|
11
|
+
export class NavigationSplitViewStory extends StoryWidget {
|
|
12
|
+
private _view: Adw.NavigationSplitView | null = null;
|
|
13
|
+
|
|
14
|
+
static {
|
|
15
|
+
GObject.registerClass({ GTypeName: 'AdwStorybookNavigationSplitView' }, NavigationSplitViewStory);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
constructor() {
|
|
19
|
+
super(StoryWidget.fromMeta(NavigationSplitViewStory.getMetadata(), 'Default'));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
static getMetadata(): StoryMeta {
|
|
23
|
+
return { ...navigationSplitViewMeta, component: Adw.NavigationSplitView.$gtype };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
private buildSidebar(): Adw.NavigationPage {
|
|
27
|
+
const group = new Adw.PreferencesGroup();
|
|
28
|
+
for (const [title, subtitle, icon] of [
|
|
29
|
+
['All Mail', '128 messages', 'mail-unread-symbolic'],
|
|
30
|
+
['Starred', '6 messages', 'starred-symbolic'],
|
|
31
|
+
['Drafts', '2 messages', 'document-edit-symbolic'],
|
|
32
|
+
['Archive', '512 messages', 'folder-symbolic'],
|
|
33
|
+
] as const) {
|
|
34
|
+
const row = new Adw.ActionRow({ title, subtitle });
|
|
35
|
+
row.add_prefix(new Gtk.Image({ iconName: icon }));
|
|
36
|
+
row.activatable = true;
|
|
37
|
+
group.add(row);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const toolbarView = new Adw.ToolbarView();
|
|
41
|
+
toolbarView.add_top_bar(new Adw.HeaderBar());
|
|
42
|
+
toolbarView.content = group;
|
|
43
|
+
|
|
44
|
+
return new Adw.NavigationPage({ title: 'Mailboxes', child: toolbarView });
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
private buildContent(): Adw.NavigationPage {
|
|
48
|
+
const status = new Adw.StatusPage({
|
|
49
|
+
iconName: 'mail-unread-symbolic',
|
|
50
|
+
title: 'All Mail',
|
|
51
|
+
description: 'Select a conversation from the list to read it here.',
|
|
52
|
+
vexpand: true,
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const toolbarView = new Adw.ToolbarView();
|
|
56
|
+
toolbarView.add_top_bar(new Adw.HeaderBar());
|
|
57
|
+
toolbarView.content = status;
|
|
58
|
+
|
|
59
|
+
return new Adw.NavigationPage({ title: 'All Mail', child: toolbarView });
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
initialize(): void {
|
|
63
|
+
this._view = new Adw.NavigationSplitView({
|
|
64
|
+
sidebar: this.buildSidebar(),
|
|
65
|
+
content: this.buildContent(),
|
|
66
|
+
showContent: this.args.showContent as boolean,
|
|
67
|
+
collapsed: this.args.collapsed as boolean,
|
|
68
|
+
widthRequest: 480,
|
|
69
|
+
heightRequest: 340,
|
|
70
|
+
});
|
|
71
|
+
this.addContent(this._view);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
updateArgs(_args: StoryArgs): void {
|
|
75
|
+
if (!this._view) return;
|
|
76
|
+
this._view.showContent = this.args.showContent as boolean;
|
|
77
|
+
this._view.collapsed = this.args.collapsed as boolean;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
GObject.type_ensure(NavigationSplitViewStory.$gtype);
|
|
82
|
+
|
|
83
|
+
export const NavigationSplitViewStories: StoryModule = { stories: [NavigationSplitViewStory] };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Shared, renderer-agnostic metadata for the Navigation View story.
|
|
2
|
+
|
|
3
|
+
import { ControlType, type StoryMeta } from '@gjsify/stories';
|
|
4
|
+
|
|
5
|
+
export const navigationViewMeta: StoryMeta = {
|
|
6
|
+
title: 'Navigation/Navigation View',
|
|
7
|
+
description:
|
|
8
|
+
'Adw.NavigationView — a navigation stack. The root page pushes a detail page, which gets an automatic back button.',
|
|
9
|
+
controls: [
|
|
10
|
+
{ name: 'rootTitle', label: 'Root title', type: ControlType.TEXT, defaultValue: 'Contacts' },
|
|
11
|
+
{ name: 'detailTitle', label: 'Detail title', type: ControlType.TEXT, defaultValue: 'Ada Lovelace' },
|
|
12
|
+
{
|
|
13
|
+
name: 'animateTransitions',
|
|
14
|
+
label: 'Animate transitions',
|
|
15
|
+
type: ControlType.BOOLEAN,
|
|
16
|
+
defaultValue: true,
|
|
17
|
+
},
|
|
18
|
+
],
|
|
19
|
+
};
|