@gjsify/example-gtk-adwaita-storybook 0.38.1 → 0.40.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/dist/browser-main.js +54 -8
- package/dist/gjs.js +33 -11
- package/dist/gjs.node.mjs +32 -10
- package/package.json +5 -5
- package/src/browser/buttons/menu-button.web.ts +37 -0
- package/src/browser/controls/drop-down.web.ts +36 -0
- package/src/browser/controls/entry.web.ts +40 -0
- package/src/browser/overview/widgets.web.ts +33 -14
- package/src/browser/stories.ts +19 -2
- package/src/browser/view-switching/view-switcher-bar.web.ts +67 -0
- package/src/buttons/menu-button.meta.ts +29 -0
- package/src/buttons/menu-button.story.ts +60 -0
- package/src/controls/drop-down.meta.ts +25 -0
- package/src/controls/drop-down.story.ts +49 -0
- package/src/controls/entry.meta.ts +18 -0
- package/src/controls/entry.story.ts +47 -0
- package/src/metas.ts +4 -0
- package/src/overview/widgets.meta.ts +48 -0
- package/src/overview/widgets.story.ts +42 -19
- package/src/view-switching/view-switcher-bar.meta.ts +20 -0
- package/src/view-switching/view-switcher-bar.story.ts +61 -0
|
@@ -33,6 +33,54 @@ export const OVERVIEW_ADVANCED_ROWS: ReadonlyArray<OverviewExpanderRow> = [
|
|
|
33
33
|
/** The accent names the gallery's combo row offers — a plain widget demo, not the real setting. */
|
|
34
34
|
export const OVERVIEW_ACCENT_OPTIONS: readonly string[] = ['Blue', 'Teal', 'Green', 'Orange'];
|
|
35
35
|
|
|
36
|
+
/**
|
|
37
|
+
* The gallery's preference-group headings.
|
|
38
|
+
*
|
|
39
|
+
* Shared for the same reason the rows are: they were literals repeated in all
|
|
40
|
+
* three renderings, and the NativeScript copy had drifted to UPPERCASE
|
|
41
|
+
* (`APPEARANCE`) while GTK and the browser used title case. It was the only file
|
|
42
|
+
* in that showcase spelling group titles that way, so it read as a house style
|
|
43
|
+
* without being one — `Adw.PreferencesGroup:title` is rendered as given on every
|
|
44
|
+
* target, and libadwaita does not upper-case it.
|
|
45
|
+
*/
|
|
46
|
+
export const OVERVIEW_GROUP_TITLES = {
|
|
47
|
+
appearance: 'Appearance',
|
|
48
|
+
account: 'Account',
|
|
49
|
+
shortcuts: 'Shortcuts',
|
|
50
|
+
actions: 'Actions',
|
|
51
|
+
} as const;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Every remaining string the gallery puts on screen.
|
|
55
|
+
*
|
|
56
|
+
* The rows, shortcuts and accent names were already shared; the labels around
|
|
57
|
+
* them were not, and that is where the uppercase drift got in. Sharing only the
|
|
58
|
+
* headings would fix the one instance and leave the class — a literal repeated in
|
|
59
|
+
* three renderings, with nothing comparing them — so the whole content of the
|
|
60
|
+
* gallery lives here and each target only decides how to BUILD it.
|
|
61
|
+
*/
|
|
62
|
+
export const OVERVIEW_TEXT = {
|
|
63
|
+
bannerTitle: 'You have unsaved changes',
|
|
64
|
+
bannerButton: 'Save',
|
|
65
|
+
darkMode: 'Dark mode',
|
|
66
|
+
darkModeSubtitle: 'Use the dark Adwaita palette',
|
|
67
|
+
notifications: 'Notifications',
|
|
68
|
+
notificationsSubtitle: 'Show toasts for events',
|
|
69
|
+
accentColor: 'Accent color',
|
|
70
|
+
name: 'Name',
|
|
71
|
+
nameValue: 'Ada Lovelace',
|
|
72
|
+
email: 'Email',
|
|
73
|
+
emailValue: 'ada@example.com',
|
|
74
|
+
devices: 'Devices',
|
|
75
|
+
advanced: 'Advanced',
|
|
76
|
+
advancedSubtitle: 'More options',
|
|
77
|
+
save: 'Save changes',
|
|
78
|
+
delete: 'Delete account',
|
|
79
|
+
} as const;
|
|
80
|
+
|
|
81
|
+
/** The spin row's range and starting value, shared so the three agree on it too. */
|
|
82
|
+
export const OVERVIEW_DEVICES = { value: 3, lower: 1, upper: 10, step: 1 } as const;
|
|
83
|
+
|
|
36
84
|
/** The shortcut rows, so the newest widget appears in context and not only alone. */
|
|
37
85
|
export const OVERVIEW_SHORTCUTS: ReadonlyArray<{ title: string; accelerator: string }> = [
|
|
38
86
|
{ title: 'Copy', accelerator: '<Control>C' },
|
|
@@ -8,7 +8,10 @@ import { type StoryArgs, type StoryMeta, type StoryModule, StoryWidget } from '@
|
|
|
8
8
|
import {
|
|
9
9
|
OVERVIEW_ACCENT_OPTIONS,
|
|
10
10
|
OVERVIEW_ADVANCED_ROWS,
|
|
11
|
+
OVERVIEW_DEVICES,
|
|
12
|
+
OVERVIEW_GROUP_TITLES,
|
|
11
13
|
OVERVIEW_SHORTCUTS,
|
|
14
|
+
OVERVIEW_TEXT,
|
|
12
15
|
overviewWidgetsMeta,
|
|
13
16
|
} from './widgets.meta.js';
|
|
14
17
|
|
|
@@ -32,8 +35,8 @@ export class OverviewWidgetsStory extends StoryWidget {
|
|
|
32
35
|
const box = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL, hexpand: true });
|
|
33
36
|
|
|
34
37
|
this._banner = new Adw.Banner({
|
|
35
|
-
title:
|
|
36
|
-
button_label:
|
|
38
|
+
title: OVERVIEW_TEXT.bannerTitle,
|
|
39
|
+
button_label: OVERVIEW_TEXT.bannerButton,
|
|
37
40
|
revealed: this.args.revealed as boolean,
|
|
38
41
|
});
|
|
39
42
|
box.append(this._banner);
|
|
@@ -43,14 +46,24 @@ export class OverviewWidgetsStory extends StoryWidget {
|
|
|
43
46
|
// --- Appearance: switches and a combo. A widget demo only — the
|
|
44
47
|
// storybook's OWN appearance lives in the header bar's dialog, and wiring
|
|
45
48
|
// these to it would give one setting two controls that disagree.
|
|
46
|
-
const appearance = new Adw.PreferencesGroup({ title:
|
|
49
|
+
const appearance = new Adw.PreferencesGroup({ title: OVERVIEW_GROUP_TITLES.appearance });
|
|
47
50
|
appearance.add(
|
|
48
|
-
new Adw.SwitchRow({
|
|
51
|
+
new Adw.SwitchRow({
|
|
52
|
+
title: OVERVIEW_TEXT.darkMode,
|
|
53
|
+
subtitle: OVERVIEW_TEXT.darkModeSubtitle,
|
|
54
|
+
active: false,
|
|
55
|
+
}),
|
|
56
|
+
);
|
|
57
|
+
appearance.add(
|
|
58
|
+
new Adw.SwitchRow({
|
|
59
|
+
title: OVERVIEW_TEXT.notifications,
|
|
60
|
+
subtitle: OVERVIEW_TEXT.notificationsSubtitle,
|
|
61
|
+
active: true,
|
|
62
|
+
}),
|
|
49
63
|
);
|
|
50
|
-
appearance.add(new Adw.SwitchRow({ title: 'Notifications', subtitle: 'Show toasts for events', active: true }));
|
|
51
64
|
appearance.add(
|
|
52
65
|
new Adw.ComboRow({
|
|
53
|
-
title:
|
|
66
|
+
title: OVERVIEW_TEXT.accentColor,
|
|
54
67
|
model: Gtk.StringList.new([...OVERVIEW_ACCENT_OPTIONS]),
|
|
55
68
|
selected: 0,
|
|
56
69
|
}),
|
|
@@ -58,26 +71,36 @@ export class OverviewWidgetsStory extends StoryWidget {
|
|
|
58
71
|
page.add(appearance);
|
|
59
72
|
|
|
60
73
|
// --- Account: entries, a spin row, and a nested expander ---
|
|
61
|
-
const account = new Adw.PreferencesGroup({ title:
|
|
74
|
+
const account = new Adw.PreferencesGroup({ title: OVERVIEW_GROUP_TITLES.account });
|
|
62
75
|
|
|
63
|
-
const name = new Adw.EntryRow({ title:
|
|
64
|
-
name.set_text(
|
|
76
|
+
const name = new Adw.EntryRow({ title: OVERVIEW_TEXT.name });
|
|
77
|
+
name.set_text(OVERVIEW_TEXT.nameValue);
|
|
65
78
|
account.add(name);
|
|
66
79
|
|
|
67
|
-
const email = new Adw.EntryRow({ title:
|
|
68
|
-
email.set_text(
|
|
80
|
+
const email = new Adw.EntryRow({ title: OVERVIEW_TEXT.email });
|
|
81
|
+
email.set_text(OVERVIEW_TEXT.emailValue);
|
|
69
82
|
account.add(email);
|
|
70
83
|
|
|
71
84
|
const devices = new Adw.SpinRow({
|
|
72
|
-
title:
|
|
73
|
-
adjustment: new Gtk.Adjustment({
|
|
85
|
+
title: OVERVIEW_TEXT.devices,
|
|
86
|
+
adjustment: new Gtk.Adjustment({
|
|
87
|
+
value: OVERVIEW_DEVICES.value,
|
|
88
|
+
lower: OVERVIEW_DEVICES.lower,
|
|
89
|
+
upper: OVERVIEW_DEVICES.upper,
|
|
90
|
+
step_increment: OVERVIEW_DEVICES.step,
|
|
91
|
+
page_increment: OVERVIEW_DEVICES.step,
|
|
92
|
+
}),
|
|
74
93
|
});
|
|
75
94
|
// The displayed value does not always follow the adjustment through
|
|
76
95
|
// property-init ordering, so it is set explicitly.
|
|
77
|
-
devices.set_value(
|
|
96
|
+
devices.set_value(OVERVIEW_DEVICES.value);
|
|
78
97
|
account.add(devices);
|
|
79
98
|
|
|
80
|
-
const advanced = new Adw.ExpanderRow({
|
|
99
|
+
const advanced = new Adw.ExpanderRow({
|
|
100
|
+
title: OVERVIEW_TEXT.advanced,
|
|
101
|
+
subtitle: OVERVIEW_TEXT.advancedSubtitle,
|
|
102
|
+
expanded: true,
|
|
103
|
+
});
|
|
81
104
|
for (const row of OVERVIEW_ADVANCED_ROWS) {
|
|
82
105
|
advanced.add_row(
|
|
83
106
|
row.kind === 'switch'
|
|
@@ -89,7 +112,7 @@ export class OverviewWidgetsStory extends StoryWidget {
|
|
|
89
112
|
page.add(account);
|
|
90
113
|
|
|
91
114
|
// --- Shortcuts: the newest widget, in context ---
|
|
92
|
-
const shortcuts = new Adw.PreferencesGroup({ title:
|
|
115
|
+
const shortcuts = new Adw.PreferencesGroup({ title: OVERVIEW_GROUP_TITLES.shortcuts });
|
|
93
116
|
for (const shortcut of OVERVIEW_SHORTCUTS) {
|
|
94
117
|
const row = new Adw.ActionRow({ title: shortcut.title });
|
|
95
118
|
row.add_suffix(new Adw.ShortcutLabel({ accelerator: shortcut.accelerator, valign: Gtk.Align.CENTER }));
|
|
@@ -98,7 +121,7 @@ export class OverviewWidgetsStory extends StoryWidget {
|
|
|
98
121
|
page.add(shortcuts);
|
|
99
122
|
|
|
100
123
|
// --- Actions: the two button styles side by side ---
|
|
101
|
-
const actions = new Adw.PreferencesGroup({ title:
|
|
124
|
+
const actions = new Adw.PreferencesGroup({ title: OVERVIEW_GROUP_TITLES.actions });
|
|
102
125
|
const buttons = new Gtk.Box({
|
|
103
126
|
orientation: Gtk.Orientation.HORIZONTAL,
|
|
104
127
|
spacing: 12,
|
|
@@ -106,10 +129,10 @@ export class OverviewWidgetsStory extends StoryWidget {
|
|
|
106
129
|
margin_top: 6,
|
|
107
130
|
margin_bottom: 6,
|
|
108
131
|
});
|
|
109
|
-
const save = new Gtk.Button({ label:
|
|
132
|
+
const save = new Gtk.Button({ label: OVERVIEW_TEXT.save });
|
|
110
133
|
save.add_css_class('suggested-action');
|
|
111
134
|
buttons.append(save);
|
|
112
|
-
const remove = new Gtk.Button({ label:
|
|
135
|
+
const remove = new Gtk.Button({ label: OVERVIEW_TEXT.delete });
|
|
113
136
|
remove.add_css_class('destructive-action');
|
|
114
137
|
buttons.append(remove);
|
|
115
138
|
actions.add(buttons);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Shared, renderer-agnostic metadata for the View Switcher Bar story. Imported by the
|
|
2
|
+
// GTK renderer (view-switcher-bar.story.ts), the browser renderer
|
|
3
|
+
// (browser/view-switching/view-switcher-bar.web.ts) and the NativeScript one.
|
|
4
|
+
|
|
5
|
+
import { ControlType, type StoryMeta } from '@gjsify/stories';
|
|
6
|
+
|
|
7
|
+
/** The three pages every rendering puts in its stack, so the bar has the same buttons. */
|
|
8
|
+
export const VIEW_SWITCHER_BAR_PAGES: ReadonlyArray<{ name: string; title: string; icon: string }> = [
|
|
9
|
+
{ name: 'inbox', title: 'Inbox', icon: 'mail-unread-symbolic' },
|
|
10
|
+
{ name: 'starred', title: 'Starred', icon: 'starred-symbolic' },
|
|
11
|
+
{ name: 'archive', title: 'Archive', icon: 'folder-symbolic' },
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
export const viewSwitcherBarMeta: StoryMeta = {
|
|
15
|
+
title: 'View Switching/View Switcher Bar',
|
|
16
|
+
description:
|
|
17
|
+
'Adw.ViewSwitcherBar — the narrow-window switcher, pinned to the bottom of a toolbar view. `reveal` ' +
|
|
18
|
+
'is a REQUEST, not a state: a stack with fewer than two pages stays collapsed however loudly it is asked.',
|
|
19
|
+
controls: [{ name: 'reveal', label: 'Reveal', type: ControlType.BOOLEAN, defaultValue: true }],
|
|
20
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// Adw.ViewSwitcherBar — the narrow-window switcher, pinned to the bottom.
|
|
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 { VIEW_SWITCHER_BAR_PAGES, viewSwitcherBarMeta } from './view-switcher-bar.meta.js';
|
|
8
|
+
|
|
9
|
+
/** Story: an Adw.ViewSwitcherBar at the bottom of a toolbar view, driving its stack. */
|
|
10
|
+
export class ViewSwitcherBarStory extends StoryWidget {
|
|
11
|
+
private _bar: Adw.ViewSwitcherBar | null = null;
|
|
12
|
+
|
|
13
|
+
static {
|
|
14
|
+
GObject.registerClass({ GTypeName: 'AdwStorybookViewSwitcherBar' }, ViewSwitcherBarStory);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
constructor() {
|
|
18
|
+
super(StoryWidget.fromMeta(ViewSwitcherBarStory.getMetadata(), 'Default'));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
static getMetadata(): StoryMeta {
|
|
22
|
+
return { ...viewSwitcherBarMeta, component: Adw.ViewSwitcherBar.$gtype };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
initialize(): void {
|
|
26
|
+
const stack = new Adw.ViewStack({ vexpand: true });
|
|
27
|
+
for (const page of VIEW_SWITCHER_BAR_PAGES) {
|
|
28
|
+
const status = new Adw.StatusPage({
|
|
29
|
+
iconName: page.icon,
|
|
30
|
+
title: page.title,
|
|
31
|
+
description: `The ${page.title.toLowerCase()} page.`,
|
|
32
|
+
vexpand: true,
|
|
33
|
+
});
|
|
34
|
+
stack.add_titled_with_icon(status, page.name, page.title, page.icon);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
this._bar = new Adw.ViewSwitcherBar({ stack });
|
|
38
|
+
this._apply();
|
|
39
|
+
|
|
40
|
+
// The bar belongs at an edge — a toolbar view is where libadwaita puts it,
|
|
41
|
+
// and it is what makes the story show the bar's real position rather than a
|
|
42
|
+
// widget floating in the middle of the preview.
|
|
43
|
+
const view = new Adw.ToolbarView({ content: stack, widthRequest: 360, heightRequest: 360 });
|
|
44
|
+
view.add_bottom_bar(this._bar);
|
|
45
|
+
|
|
46
|
+
this.addContent(view);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
updateArgs(_args: StoryArgs): void {
|
|
50
|
+
this._apply();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
private _apply(): void {
|
|
54
|
+
if (!this._bar) return;
|
|
55
|
+
this._bar.reveal = this.args.reveal as boolean;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
GObject.type_ensure(ViewSwitcherBarStory.$gtype);
|
|
60
|
+
|
|
61
|
+
export const ViewSwitcherBarStories: StoryModule = { stories: [ViewSwitcherBarStory] };
|