@gjsify/example-gtk-adwaita-storybook 0.54.0 → 0.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser-main.js +8089 -3038
- package/dist/gjs.js +14 -9
- package/dist/gjs.node.mjs +10 -5
- package/package.json +5 -5
- package/src/browser/buttons/color-dialog-button.web.ts +42 -0
- package/src/browser/buttons/font-dialog-button.web.ts +42 -0
- package/src/browser/buttons/link-button.web.ts +37 -0
- package/src/browser/buttons/scale-button.web.ts +36 -0
- package/src/browser/buttons/toggle-button.web.ts +35 -0
- package/src/browser/controls/check-button.web.ts +38 -0
- package/src/browser/controls/gtk-spinner.web.ts +39 -0
- package/src/browser/controls/level-bar.web.ts +43 -0
- package/src/browser/controls/password-entry.web.ts +36 -0
- package/src/browser/controls/progress-bar.web.ts +39 -0
- package/src/browser/controls/scale.web.ts +44 -0
- package/src/browser/controls/search-entry.web.ts +49 -0
- package/src/browser/controls/spin-button.web.ts +40 -0
- package/src/browser/controls/switch.web.ts +38 -0
- package/src/browser/drawing/drag-icon.web.ts +112 -0
- package/src/browser/drawing/drawing-area.web.ts +66 -0
- package/src/browser/drawing/gl-area.web.ts +162 -0
- package/src/browser/drawing/graphics-offload.web.ts +74 -0
- package/src/browser/feedback/dialog.web.ts +76 -0
- package/src/browser/feedback/emoji-chooser.web.ts +93 -0
- package/src/browser/feedback/gtk-about-dialog.web.ts +105 -0
- package/src/browser/feedback/page-setup-unix-dialog.web.ts +93 -0
- package/src/browser/feedback/print-unix-dialog.web.ts +111 -0
- package/src/browser/feedback/shortcuts-dialog.web.ts +90 -0
- package/src/browser/layout/application-window.web.ts +94 -0
- package/src/browser/layout/aspect-frame.web.ts +49 -0
- package/src/browser/layout/bin.web.ts +41 -0
- package/src/browser/layout/breakpoint-bin.web.ts +61 -0
- package/src/browser/layout/center-box.web.ts +45 -0
- package/src/browser/layout/clamp-scrollable.web.ts +47 -0
- package/src/browser/layout/expander.web.ts +52 -0
- package/src/browser/layout/fixed.web.ts +51 -0
- package/src/browser/layout/frame.web.ts +40 -0
- package/src/browser/layout/grid.web.ts +46 -0
- package/src/browser/layout/layout-slot.web.ts +60 -0
- package/src/browser/layout/multi-layout-view.web.ts +94 -0
- package/src/browser/layout/overlay.web.ts +57 -0
- package/src/browser/layout/paned.web.ts +69 -0
- package/src/browser/layout/popover-bin.web.ts +54 -0
- package/src/browser/layout/popover-menu.web.ts +48 -0
- package/src/browser/layout/popover.web.ts +61 -0
- package/src/browser/layout/revealer.web.ts +53 -0
- package/src/browser/layout/scrollbar.web.ts +54 -0
- package/src/browser/layout/scrolled-window.web.ts +52 -0
- package/src/browser/layout/separator.web.ts +47 -0
- package/src/browser/layout/viewport.web.ts +51 -0
- package/src/browser/layout/window.web.ts +60 -0
- package/src/browser/media/image.web.ts +39 -0
- package/src/browser/media/inscription.web.ts +52 -0
- package/src/browser/media/media-controls.web.ts +65 -0
- package/src/browser/media/picture.web.ts +56 -0
- package/src/browser/media/video.web.ts +56 -0
- package/src/browser/navigation/popover-menu-bar.web.ts +40 -0
- package/src/browser/presentation/calendar.web.ts +49 -0
- package/src/browser/presentation/column-view.web.ts +45 -0
- package/src/browser/presentation/flow-box.web.ts +52 -0
- package/src/browser/presentation/grid-view.web.ts +37 -0
- package/src/browser/presentation/list-box.web.ts +48 -0
- package/src/browser/presentation/list-view.web.ts +36 -0
- package/src/browser/presentation/tree-expander.web.ts +68 -0
- package/src/browser/presentation/window-handle.web.ts +42 -0
- package/src/browser/rows/preferences-row.web.ts +43 -0
- package/src/browser/stories.ts +158 -0
- package/src/browser/text/editable-label.web.ts +45 -0
- package/src/browser/text/search-bar.web.ts +45 -0
- package/src/browser/text/text-view.web.ts +54 -0
- package/src/browser/text/text.web.ts +48 -0
- package/src/browser/view-switching/notebook.web.ts +67 -0
- package/src/browser/view-switching/stack-sidebar.web.ts +68 -0
- package/src/browser/view-switching/stack-switcher.web.ts +70 -0
- package/src/browser/view-switching/stack.web.ts +72 -0
- package/src/browser/view-switching/tab-bar.web.ts +105 -0
- package/src/browser/view-switching/tab-button.web.ts +52 -0
- package/src/browser/view-switching/tab-overview.web.ts +87 -0
- package/src/browser/view-switching/view-switcher-sidebar.web.ts +77 -0
- package/src/browser/windows/action-bar.web.ts +66 -0
- package/src/browser/windows/gtk-application-window.web.ts +67 -0
- package/src/browser/windows/gtk-header-bar.web.ts +61 -0
- package/src/browser/windows/gtk-window.web.ts +58 -0
- package/src/browser/windows/window-controls.web.ts +54 -0
- package/src/buttons/color-dialog-button.meta.ts +16 -0
- package/src/buttons/color-dialog-button.story.ts +49 -0
- package/src/buttons/font-dialog-button.meta.ts +29 -0
- package/src/buttons/font-dialog-button.story.ts +52 -0
- package/src/buttons/link-button.meta.ts +18 -0
- package/src/buttons/link-button.story.ts +48 -0
- package/src/buttons/scale-button.meta.ts +34 -0
- package/src/buttons/scale-button.story.ts +50 -0
- package/src/buttons/toggle-button.meta.ts +17 -0
- package/src/buttons/toggle-button.story.ts +46 -0
- package/src/controls/check-button.meta.ts +19 -0
- package/src/controls/check-button.story.ts +56 -0
- package/src/controls/gtk-spinner.meta.ts +24 -0
- package/src/controls/gtk-spinner.story.ts +53 -0
- package/src/controls/level-bar.meta.ts +39 -0
- package/src/controls/level-bar.story.ts +58 -0
- package/src/controls/password-entry.meta.ts +18 -0
- package/src/controls/password-entry.story.ts +54 -0
- package/src/controls/progress-bar.meta.ts +20 -0
- package/src/controls/progress-bar.story.ts +53 -0
- package/src/controls/scale.meta.ts +47 -0
- package/src/controls/scale.story.ts +66 -0
- package/src/controls/search-entry.meta.ts +18 -0
- package/src/controls/search-entry.story.ts +57 -0
- package/src/controls/spin-button.meta.ts +40 -0
- package/src/controls/spin-button.story.ts +55 -0
- package/src/controls/switch.meta.ts +18 -0
- package/src/controls/switch.story.ts +50 -0
- package/src/drawing/drag-icon.meta.ts +39 -0
- package/src/drawing/drag-icon.story.ts +117 -0
- package/src/drawing/drawing-area.meta.ts +45 -0
- package/src/drawing/drawing-area.story.ts +78 -0
- package/src/drawing/gl-area.meta.ts +30 -0
- package/src/drawing/gl-area.story.ts +113 -0
- package/src/drawing/graphics-offload.meta.ts +39 -0
- package/src/drawing/graphics-offload.story.ts +73 -0
- package/src/feedback/dialog.meta.ts +25 -0
- package/src/feedback/dialog.story.ts +78 -0
- package/src/feedback/emoji-chooser.meta.ts +10 -0
- package/src/feedback/emoji-chooser.story.ts +98 -0
- package/src/feedback/gtk-about-dialog.meta.ts +29 -0
- package/src/feedback/gtk-about-dialog.story.ts +90 -0
- package/src/feedback/page-setup-unix-dialog.meta.ts +37 -0
- package/src/feedback/page-setup-unix-dialog.story.ts +70 -0
- package/src/feedback/print-unix-dialog.meta.ts +30 -0
- package/src/feedback/print-unix-dialog.story.ts +93 -0
- package/src/feedback/shortcuts-dialog.meta.ts +12 -0
- package/src/feedback/shortcuts-dialog.story.ts +79 -0
- package/src/layout/application-window.meta.ts +16 -0
- package/src/layout/application-window.story.ts +97 -0
- package/src/layout/aspect-frame.meta.ts +19 -0
- package/src/layout/aspect-frame.story.ts +62 -0
- package/src/layout/bin.meta.ts +15 -0
- package/src/layout/bin.story.ts +56 -0
- package/src/layout/breakpoint-bin.meta.ts +38 -0
- package/src/layout/breakpoint-bin.story.ts +62 -0
- package/src/layout/center-box.meta.ts +26 -0
- package/src/layout/center-box.story.ts +54 -0
- package/src/layout/clamp-scrollable.meta.ts +30 -0
- package/src/layout/clamp-scrollable.story.ts +51 -0
- package/src/layout/expander.meta.ts +30 -0
- package/src/layout/expander.story.ts +62 -0
- package/src/layout/fixed.meta.ts +16 -0
- package/src/layout/fixed.story.ts +54 -0
- package/src/layout/frame.meta.ts +24 -0
- package/src/layout/frame.story.ts +51 -0
- package/src/layout/grid.meta.ts +45 -0
- package/src/layout/grid.story.ts +80 -0
- package/src/layout/layout-slot.meta.ts +22 -0
- package/src/layout/layout-slot.story.ts +68 -0
- package/src/layout/multi-layout-view.meta.ts +31 -0
- package/src/layout/multi-layout-view.story.ts +101 -0
- package/src/layout/overlay.meta.ts +42 -0
- package/src/layout/overlay.story.ts +72 -0
- package/src/layout/paned.meta.ts +45 -0
- package/src/layout/paned.story.ts +70 -0
- package/src/layout/popover-bin.meta.ts +29 -0
- package/src/layout/popover-bin.story.ts +66 -0
- package/src/layout/popover-menu.meta.ts +54 -0
- package/src/layout/popover-menu.story.ts +119 -0
- package/src/layout/popover.meta.ts +38 -0
- package/src/layout/popover.story.ts +66 -0
- package/src/layout/revealer.meta.ts +44 -0
- package/src/layout/revealer.story.ts +79 -0
- package/src/layout/scrollbar.meta.ts +33 -0
- package/src/layout/scrollbar.story.ts +61 -0
- package/src/layout/scrolled-window.meta.ts +57 -0
- package/src/layout/scrolled-window.story.ts +74 -0
- package/src/layout/separator.meta.ts +25 -0
- package/src/layout/separator.story.ts +53 -0
- package/src/layout/viewport.meta.ts +19 -0
- package/src/layout/viewport.story.ts +53 -0
- package/src/layout/window.meta.ts +13 -0
- package/src/layout/window.story.ts +66 -0
- package/src/media/image.meta.ts +24 -0
- package/src/media/image.story.ts +48 -0
- package/src/media/inscription.meta.ts +45 -0
- package/src/media/inscription.story.ts +64 -0
- package/src/media/media-controls.meta.ts +30 -0
- package/src/media/media-controls.story.ts +58 -0
- package/src/media/picture.meta.ts +42 -0
- package/src/media/picture.story.ts +81 -0
- package/src/media/video.meta.ts +32 -0
- package/src/media/video.story.ts +57 -0
- package/src/metas.ts +79 -0
- package/src/navigation/popover-menu-bar.meta.ts +51 -0
- package/src/navigation/popover-menu-bar.story.ts +72 -0
- package/src/presentation/calendar.meta.ts +28 -0
- package/src/presentation/calendar.story.ts +64 -0
- package/src/presentation/column-view.meta.ts +30 -0
- package/src/presentation/column-view.story.ts +73 -0
- package/src/presentation/flow-box.meta.ts +51 -0
- package/src/presentation/flow-box.story.ts +72 -0
- package/src/presentation/grid-view.meta.ts +28 -0
- package/src/presentation/grid-view.story.ts +64 -0
- package/src/presentation/list-box.meta.ts +55 -0
- package/src/presentation/list-box.story.ts +68 -0
- package/src/presentation/list-view.meta.ts +38 -0
- package/src/presentation/list-view.story.ts +73 -0
- package/src/presentation/tree-expander.meta.ts +24 -0
- package/src/presentation/tree-expander.story.ts +105 -0
- package/src/presentation/window-handle.meta.ts +27 -0
- package/src/presentation/window-handle.story.ts +53 -0
- package/src/rows/preferences-row.meta.ts +15 -0
- package/src/rows/preferences-row.story.ts +50 -0
- package/src/text/editable-label.meta.ts +17 -0
- package/src/text/editable-label.story.ts +47 -0
- package/src/text/search-bar.meta.ts +17 -0
- package/src/text/search-bar.story.ts +48 -0
- package/src/text/text-view.meta.ts +49 -0
- package/src/text/text-view.story.ts +69 -0
- package/src/text/text.meta.ts +21 -0
- package/src/text/text.story.ts +50 -0
- package/src/view-switching/notebook.meta.ts +44 -0
- package/src/view-switching/notebook.story.ts +77 -0
- package/src/view-switching/stack-sidebar.meta.ts +50 -0
- package/src/view-switching/stack-sidebar.story.ts +85 -0
- package/src/view-switching/stack-switcher.meta.ts +53 -0
- package/src/view-switching/stack-switcher.story.ts +95 -0
- package/src/view-switching/stack.meta.ts +53 -0
- package/src/view-switching/stack.story.ts +95 -0
- package/src/view-switching/tab-bar.meta.ts +22 -0
- package/src/view-switching/tab-bar.story.ts +85 -0
- package/src/view-switching/tab-button.meta.ts +14 -0
- package/src/view-switching/tab-button.story.ts +52 -0
- package/src/view-switching/tab-overview.meta.ts +21 -0
- package/src/view-switching/tab-overview.story.ts +86 -0
- package/src/view-switching/view-switcher-sidebar.meta.ts +42 -0
- package/src/view-switching/view-switcher-sidebar.story.ts +73 -0
- package/src/windows/action-bar.meta.ts +27 -0
- package/src/windows/action-bar.story.ts +65 -0
- package/src/windows/gtk-application-window.meta.ts +27 -0
- package/src/windows/gtk-application-window.story.ts +89 -0
- package/src/windows/gtk-header-bar.meta.ts +39 -0
- package/src/windows/gtk-header-bar.story.ts +76 -0
- package/src/windows/gtk-window.meta.ts +30 -0
- package/src/windows/gtk-window.story.ts +64 -0
- package/src/windows/window-controls.meta.ts +42 -0
- package/src/windows/window-controls.story.ts +61 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// Browser port of the Gtk.AboutDialog story. Shares metadata with gtk-about-dialog.story.ts.
|
|
2
|
+
|
|
3
|
+
import { StoryElement, type StoryArgs, type StoryMeta, type WebStoryModule } from '@gjsify/adwaita-storybook';
|
|
4
|
+
import { gtkAboutDialogMeta } from '../../feedback/gtk-about-dialog.meta.js';
|
|
5
|
+
|
|
6
|
+
/** The imperative half of the `<gtk-about-dialog>` element the markup cannot spell. */
|
|
7
|
+
interface AboutDialogElement extends HTMLElement {
|
|
8
|
+
authors: string[];
|
|
9
|
+
documenters: string[];
|
|
10
|
+
artists: string[];
|
|
11
|
+
translatorCredits: string;
|
|
12
|
+
addCreditSection(name: string, people: readonly string[]): void;
|
|
13
|
+
present(): void;
|
|
14
|
+
set licenseType(value: string);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export class GtkAboutDialogWebStory extends StoryElement {
|
|
18
|
+
private _dialog: AboutDialogElement | null = null;
|
|
19
|
+
private _button: HTMLButtonElement | null = null;
|
|
20
|
+
|
|
21
|
+
constructor() {
|
|
22
|
+
super(GtkAboutDialogWebStory.getMetadata(), 'Default');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
static getMetadata(): StoryMeta {
|
|
26
|
+
return gtkAboutDialogMeta;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
initialize(): void {
|
|
30
|
+
const center = document.createElement('div');
|
|
31
|
+
center.style.display = 'flex';
|
|
32
|
+
center.style.alignItems = 'center';
|
|
33
|
+
center.style.justifyContent = 'center';
|
|
34
|
+
center.style.minHeight = '160px';
|
|
35
|
+
|
|
36
|
+
this._button = document.createElement('button');
|
|
37
|
+
this._button.textContent = 'Show dialog';
|
|
38
|
+
this._button.setAttribute('pill', '');
|
|
39
|
+
this._button.setAttribute('suggested', '');
|
|
40
|
+
this._button.addEventListener('click', () => this._present());
|
|
41
|
+
center.appendChild(this._button);
|
|
42
|
+
|
|
43
|
+
// The dialog is a fixed full-cover overlay — mount it on the body so the scrim
|
|
44
|
+
// covers the whole viewport, not just the clamped story stage.
|
|
45
|
+
this._dialog = document.createElement('gtk-about-dialog') as AboutDialogElement;
|
|
46
|
+
document.body.appendChild(this._dialog);
|
|
47
|
+
|
|
48
|
+
this.addContent(center);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
private _present(): void {
|
|
52
|
+
const dialog = this._dialog;
|
|
53
|
+
if (dialog === null) return;
|
|
54
|
+
// A fresh presentation, because `close()` resets the stack to the main page and
|
|
55
|
+
// the credits page is populated lazily.
|
|
56
|
+
dialog.setAttribute('program-name', (this.args.programName as string) ?? 'Calculator');
|
|
57
|
+
dialog.setAttribute('version', (this.args.version as string) ?? '48.1');
|
|
58
|
+
dialog.setAttribute('logo-icon-name', 'application-x-executable');
|
|
59
|
+
dialog.setAttribute('comments', 'An arithmetic calculator for the GNOME desktop.');
|
|
60
|
+
dialog.setAttribute('website', 'https://gitlab.gnome.org/World/gnome-calculator');
|
|
61
|
+
dialog.setAttribute('website-label', 'GNOME Calculator');
|
|
62
|
+
dialog.setAttribute('copyright', '© 2026 The GNOME Project');
|
|
63
|
+
dialog.setAttribute('system-information', 'GTK 4.24.0\nglibc 2.42\nBuilt with meson 1.6');
|
|
64
|
+
|
|
65
|
+
const type = (this.args.licenseType as string) ?? 'gpl-3-0';
|
|
66
|
+
if (type === 'custom') {
|
|
67
|
+
// A CUSTOM licence is the only one whose text `:license` supplies — every other
|
|
68
|
+
// type overwrites it with the warranty preamble.
|
|
69
|
+
dialog.setAttribute(
|
|
70
|
+
'license',
|
|
71
|
+
'Permission is hereby granted, free of charge, to any person obtaining a copy…',
|
|
72
|
+
);
|
|
73
|
+
} else {
|
|
74
|
+
dialog.removeAttribute('license');
|
|
75
|
+
}
|
|
76
|
+
dialog.licenseType = type;
|
|
77
|
+
|
|
78
|
+
dialog.authors = [];
|
|
79
|
+
dialog.documenters = [];
|
|
80
|
+
dialog.artists = [];
|
|
81
|
+
dialog.removeAttribute('translator-credits');
|
|
82
|
+
if (this.args.withCredits as boolean) {
|
|
83
|
+
dialog.authors = ['Ada Lovelace <ada@example.org>', 'Grace Hopper'];
|
|
84
|
+
dialog.documenters = ['Barbara Liskov'];
|
|
85
|
+
dialog.artists = ['Margaret Hamilton'];
|
|
86
|
+
dialog.translatorCredits = 'Alan Turing\nKatherine Johnson';
|
|
87
|
+
dialog.addCreditSection('Reviewed by', ['Tony Hoare <tony@example.org>']);
|
|
88
|
+
}
|
|
89
|
+
dialog.present();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
updateArgs(_args: StoryArgs): void {
|
|
93
|
+
// The dialog reads the latest args each time it is presented; nothing to mutate live.
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
teardown(): void {
|
|
97
|
+
// The dialog lives on the body, not the story stage — remove it when the story is
|
|
98
|
+
// deselected so it does not leak across navigations.
|
|
99
|
+
if (this._dialog?.parentNode) this._dialog.parentNode.removeChild(this._dialog);
|
|
100
|
+
this._dialog = null;
|
|
101
|
+
this._button = null;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export const GtkAboutDialogWebStories: WebStoryModule = { stories: [GtkAboutDialogWebStory] };
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// Browser port of the Page Setup Dialog story. Shares metadata with
|
|
2
|
+
// page-setup-unix-dialog.story.ts.
|
|
3
|
+
|
|
4
|
+
import { StoryElement, type StoryArgs, type StoryMeta, type WebStoryModule } from '@gjsify/adwaita-storybook';
|
|
5
|
+
import { pageSetupUnixDialogMeta } from '../../feedback/page-setup-unix-dialog.meta.js';
|
|
6
|
+
|
|
7
|
+
/** The plain-data `PageSetup` the element's property takes. */
|
|
8
|
+
interface PageSetupData {
|
|
9
|
+
paperSize: string;
|
|
10
|
+
orientation: string;
|
|
11
|
+
margins: { top: number; bottom: number; left: number; right: number };
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** The imperative half of `<gtk-page-setup-unix-dialog>`. */
|
|
15
|
+
interface PageSetupDialogElement extends HTMLElement {
|
|
16
|
+
pageSetup: PageSetupData;
|
|
17
|
+
unit: 'mm' | 'inch';
|
|
18
|
+
present(): void;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** The default margins of a paper size, in millimetres — `gtk_paper_size_get_default_*`. */
|
|
22
|
+
const DEFAULT_MARGIN_MM = 0.25 * 25.4;
|
|
23
|
+
const TALL_BOTTOM_MARGIN_MM = 0.56 * 25.4;
|
|
24
|
+
|
|
25
|
+
function marginsFor(paperSize: string): PageSetupData['margins'] {
|
|
26
|
+
const tall = paperSize === 'na_letter' || paperSize === 'na_legal' || paperSize === 'iso_a4';
|
|
27
|
+
return {
|
|
28
|
+
top: DEFAULT_MARGIN_MM,
|
|
29
|
+
bottom: tall ? TALL_BOTTOM_MARGIN_MM : DEFAULT_MARGIN_MM,
|
|
30
|
+
left: DEFAULT_MARGIN_MM,
|
|
31
|
+
right: DEFAULT_MARGIN_MM,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export class PageSetupUnixDialogWebStory extends StoryElement {
|
|
36
|
+
private _dialog: PageSetupDialogElement | null = null;
|
|
37
|
+
|
|
38
|
+
constructor() {
|
|
39
|
+
super(PageSetupUnixDialogWebStory.getMetadata(), 'Default');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
static getMetadata(): StoryMeta {
|
|
43
|
+
return pageSetupUnixDialogMeta;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
initialize(): void {
|
|
47
|
+
const center = document.createElement('div');
|
|
48
|
+
center.style.display = 'flex';
|
|
49
|
+
center.style.alignItems = 'center';
|
|
50
|
+
center.style.justifyContent = 'center';
|
|
51
|
+
center.style.minHeight = '160px';
|
|
52
|
+
|
|
53
|
+
const button = document.createElement('button');
|
|
54
|
+
button.textContent = 'Page Setup…';
|
|
55
|
+
button.setAttribute('pill', '');
|
|
56
|
+
button.setAttribute('suggested', '');
|
|
57
|
+
button.addEventListener('click', () => this._present());
|
|
58
|
+
center.appendChild(button);
|
|
59
|
+
|
|
60
|
+
// Mounted on the body so the scrim covers the whole viewport, like every dialog here.
|
|
61
|
+
this._dialog = document.createElement('gtk-page-setup-unix-dialog') as PageSetupDialogElement;
|
|
62
|
+
document.body.appendChild(this._dialog);
|
|
63
|
+
|
|
64
|
+
this.addContent(center);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private _present(): void {
|
|
68
|
+
const dialog = this._dialog;
|
|
69
|
+
if (dialog === null) return;
|
|
70
|
+
const paperSize = (this.args.paperSize as string) ?? 'iso_a4';
|
|
71
|
+
// `set_page_setup` selects the matching row and appends the setup when none matches,
|
|
72
|
+
// which is why the margins are spelled out here rather than left to the drop down.
|
|
73
|
+
dialog.pageSetup = {
|
|
74
|
+
paperSize,
|
|
75
|
+
orientation: (this.args.orientation as string) ?? 'portrait',
|
|
76
|
+
margins: marginsFor(paperSize),
|
|
77
|
+
};
|
|
78
|
+
dialog.present();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
updateArgs(_args: StoryArgs): void {
|
|
82
|
+
// The dialog reads the latest args each time it is presented; nothing to mutate live.
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
teardown(): void {
|
|
86
|
+
if (this._dialog?.parentNode) this._dialog.parentNode.removeChild(this._dialog);
|
|
87
|
+
this._dialog = null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export const PageSetupUnixDialogWebStories: WebStoryModule = {
|
|
92
|
+
stories: [PageSetupUnixDialogWebStory],
|
|
93
|
+
};
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// Browser port of the Print Dialog story. Shares metadata with print-unix-dialog.story.ts.
|
|
2
|
+
|
|
3
|
+
import { StoryElement, type StoryArgs, type StoryMeta, type WebStoryModule } from '@gjsify/adwaita-storybook';
|
|
4
|
+
import { printUnixDialogMeta } from '../../feedback/print-unix-dialog.meta.js';
|
|
5
|
+
|
|
6
|
+
/** The plain-data `PageSetup` the element's property takes. */
|
|
7
|
+
interface PageSetupData {
|
|
8
|
+
paperSize: string;
|
|
9
|
+
orientation: string;
|
|
10
|
+
margins: { top: number; bottom: number; left: number; right: number };
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** The imperative half of `<gtk-print-unix-dialog>`. */
|
|
14
|
+
interface PrintDialogElement extends HTMLElement {
|
|
15
|
+
currentPage: number;
|
|
16
|
+
/** Not a property of `Gtk.PrintUnixDialog`: which range button the dialog shows. */
|
|
17
|
+
range: 'all' | 'current' | 'selection' | 'pages';
|
|
18
|
+
supportSelection: boolean;
|
|
19
|
+
hasSelection: boolean;
|
|
20
|
+
manualCapabilities: string[];
|
|
21
|
+
embedPageSetup: boolean;
|
|
22
|
+
pageSetup: PageSetupData;
|
|
23
|
+
printSettings: Record<string, string>;
|
|
24
|
+
printers: Array<{ name: string; location?: string; acceptsJobs?: boolean; capabilities?: string[] }>;
|
|
25
|
+
present(): void;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** The two printers the story offers — GTK's list comes from a print backend. */
|
|
29
|
+
const PRINTERS = [
|
|
30
|
+
{ name: 'Office Laser', location: 'Building A, floor 2', acceptsJobs: true },
|
|
31
|
+
{ name: 'Lobby Printer', location: 'Building A, ground floor', acceptsJobs: false },
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
const MARGINS = { top: 6.35, bottom: 14.224, left: 6.35, right: 6.35 };
|
|
35
|
+
|
|
36
|
+
export class PrintUnixDialogWebStory extends StoryElement {
|
|
37
|
+
private _dialog: PrintDialogElement | null = null;
|
|
38
|
+
|
|
39
|
+
constructor() {
|
|
40
|
+
super(PrintUnixDialogWebStory.getMetadata(), 'Default');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
static getMetadata(): StoryMeta {
|
|
44
|
+
return printUnixDialogMeta;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
initialize(): void {
|
|
48
|
+
const center = document.createElement('div');
|
|
49
|
+
center.style.display = 'flex';
|
|
50
|
+
center.style.alignItems = 'center';
|
|
51
|
+
center.style.justifyContent = 'center';
|
|
52
|
+
center.style.minHeight = '160px';
|
|
53
|
+
|
|
54
|
+
const button = document.createElement('button');
|
|
55
|
+
button.textContent = 'Print…';
|
|
56
|
+
button.setAttribute('pill', '');
|
|
57
|
+
button.setAttribute('suggested', '');
|
|
58
|
+
button.addEventListener('click', () => this._present());
|
|
59
|
+
center.appendChild(button);
|
|
60
|
+
|
|
61
|
+
this._dialog = document.createElement('gtk-print-unix-dialog') as PrintDialogElement;
|
|
62
|
+
document.body.appendChild(this._dialog);
|
|
63
|
+
|
|
64
|
+
this.addContent(center);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private _present(): void {
|
|
68
|
+
const dialog = this._dialog;
|
|
69
|
+
if (dialog === null) return;
|
|
70
|
+
// The application half of the capability mask, spelled the way the GIR's nick set
|
|
71
|
+
// is: `|`-separated nicks.
|
|
72
|
+
dialog.manualCapabilities = String(this.args.capabilities ?? '')
|
|
73
|
+
.split('|')
|
|
74
|
+
.map((nick) => nick.trim())
|
|
75
|
+
.filter((nick) => nick.length > 0);
|
|
76
|
+
dialog.currentPage = 2;
|
|
77
|
+
// Which of the four range buttons is active. The element keeps it as a property
|
|
78
|
+
// because a radio group's value is not an attribute in the C either — the C's is
|
|
79
|
+
// whatever `dialog_get_page_range` reads off the four check buttons.
|
|
80
|
+
dialog.range = (this.args.range as 'all' | 'current' | 'selection' | 'pages') ?? 'all';
|
|
81
|
+
dialog.supportSelection = true;
|
|
82
|
+
dialog.hasSelection = true;
|
|
83
|
+
// The paper size and orientation drop downs are insensitive until the page setup is
|
|
84
|
+
// embedded (gtk_print_unix_dialog_set_embed_page_setup), and the story embeds it so
|
|
85
|
+
// the Page Setup page has something to show.
|
|
86
|
+
dialog.embedPageSetup = true;
|
|
87
|
+
dialog.pageSetup = {
|
|
88
|
+
paperSize: 'iso_a4',
|
|
89
|
+
orientation: 'portrait',
|
|
90
|
+
margins: MARGINS,
|
|
91
|
+
};
|
|
92
|
+
dialog.printSettings = {
|
|
93
|
+
copies: String(this.args.copies ?? 1),
|
|
94
|
+
collate: '0',
|
|
95
|
+
reverse: '0',
|
|
96
|
+
};
|
|
97
|
+
dialog.printers = PRINTERS;
|
|
98
|
+
dialog.present();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
updateArgs(_args: StoryArgs): void {
|
|
102
|
+
// The dialog reads the latest args each time it is presented; nothing to mutate live.
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
teardown(): void {
|
|
106
|
+
if (this._dialog?.parentNode) this._dialog.parentNode.removeChild(this._dialog);
|
|
107
|
+
this._dialog = null;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export const PrintUnixDialogWebStories: WebStoryModule = { stories: [PrintUnixDialogWebStory] };
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// Browser port of the Shortcuts Dialog story. Shares metadata with shortcuts-dialog.story.ts.
|
|
2
|
+
|
|
3
|
+
import { StoryElement, type StoryArgs, type StoryMeta, type WebStoryModule } from '@gjsify/adwaita-storybook';
|
|
4
|
+
import { shortcutsDialogMeta } from '../../feedback/shortcuts-dialog.meta.js';
|
|
5
|
+
|
|
6
|
+
/** Build one `<adw-shortcuts-item>`, the markup form of `new Adw.ShortcutsItem(…)`. */
|
|
7
|
+
function item(title: string, attrs: Record<string, string> = {}): HTMLElement {
|
|
8
|
+
const el = document.createElement('adw-shortcuts-item');
|
|
9
|
+
el.setAttribute('title', title);
|
|
10
|
+
for (const [name, value] of Object.entries(attrs)) el.setAttribute(name, value);
|
|
11
|
+
return el;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** Build one `<adw-shortcuts-section>`; omit the title for a continuation group. */
|
|
15
|
+
function section(title: string | null, items: HTMLElement[]): HTMLElement {
|
|
16
|
+
const el = document.createElement('adw-shortcuts-section');
|
|
17
|
+
if (title !== null) el.setAttribute('title', title);
|
|
18
|
+
el.append(...items);
|
|
19
|
+
return el;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Story: adw-shortcuts-dialog presented from a button, with two sections of
|
|
24
|
+
* shortcuts — a 1:1 port of the GTK ShortcutsDialogStory.
|
|
25
|
+
*/
|
|
26
|
+
export class ShortcutsDialogWebStory extends StoryElement {
|
|
27
|
+
constructor() {
|
|
28
|
+
super(ShortcutsDialogWebStory.getMetadata(), 'Default');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
static getMetadata(): StoryMeta {
|
|
32
|
+
return shortcutsDialogMeta;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
initialize(): void {
|
|
36
|
+
const button = document.createElement('gtk-button');
|
|
37
|
+
button.textContent = 'Show dialog';
|
|
38
|
+
button.setAttribute('pill', '');
|
|
39
|
+
button.setAttribute('suggested', '');
|
|
40
|
+
button.addEventListener('click', () => this._present());
|
|
41
|
+
|
|
42
|
+
// Centre the trigger button so the preview matches the GTK story's
|
|
43
|
+
// centred halign/valign placement.
|
|
44
|
+
const center = document.createElement('div');
|
|
45
|
+
center.style.display = 'flex';
|
|
46
|
+
center.style.alignItems = 'center';
|
|
47
|
+
center.style.justifyContent = 'center';
|
|
48
|
+
center.style.minHeight = '160px';
|
|
49
|
+
center.append(button);
|
|
50
|
+
|
|
51
|
+
this.addContent(center);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Build + present a fresh dialog, reading the latest args (as the GTK story does). */
|
|
55
|
+
private _present(): void {
|
|
56
|
+
const dialog = document.createElement('adw-shortcuts-dialog');
|
|
57
|
+
dialog.setAttribute('title', this.args.title as string);
|
|
58
|
+
|
|
59
|
+
// SECTIONS ARE CHILDREN here: `Adw.ShortcutsDialog`'s only method is `add()`, and
|
|
60
|
+
// the class documents "add it as a child when using UI files" as the other route.
|
|
61
|
+
dialog.append(
|
|
62
|
+
section('General', [
|
|
63
|
+
item('Open Menu', { accelerator: 'F10' }),
|
|
64
|
+
// An accelerator for an action comes from a GtkApplication, which a
|
|
65
|
+
// document has no way to ask — so the row stands for the action alone.
|
|
66
|
+
item('Preferences', { 'action-name': 'app.preferences' }),
|
|
67
|
+
item('Quit', { accelerator: '<Control>q' }),
|
|
68
|
+
]),
|
|
69
|
+
// No title: the section below is a continuation of the one above, which is
|
|
70
|
+
// what the class documents an untitled section for.
|
|
71
|
+
section(null, [
|
|
72
|
+
item('Move Tab Left', { accelerator: '<Shift><Control>Page_Up', direction: 'ltr' }),
|
|
73
|
+
item('Move Tab Left', { accelerator: '<Shift><Control>Page_Up', direction: 'rtl' }),
|
|
74
|
+
]),
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
// A DISCONNECTED element is attached to `document.body` on present, the
|
|
78
|
+
// `Adw.Dialog.present(parent)` idiom; one already in the DOM is revealed in
|
|
79
|
+
// place and stays reusable.
|
|
80
|
+
(dialog as HTMLElement & { present(): void }).present();
|
|
81
|
+
|
|
82
|
+
dialog.addEventListener('closed', () => dialog.remove(), { once: true });
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
updateArgs(_args: StoryArgs): void {
|
|
86
|
+
// The dialog reads the latest args each time it is presented; nothing to mutate live.
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export const ShortcutsDialogWebStories: WebStoryModule = { stories: [ShortcutsDialogWebStory] };
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// Browser port of the Application Window story. Shares metadata with
|
|
2
|
+
// application-window.story.ts.
|
|
3
|
+
|
|
4
|
+
import { StoryElement, type StoryArgs, type StoryMeta, type WebStoryModule } from '@gjsify/adwaita-storybook';
|
|
5
|
+
import { applicationWindowMeta } from '../../layout/application-window.meta.js';
|
|
6
|
+
|
|
7
|
+
/** The same menu both stories build, in the portable form (ADR 0042). */
|
|
8
|
+
const MENU_MODEL = [
|
|
9
|
+
{
|
|
10
|
+
label: 'File',
|
|
11
|
+
submenu: [
|
|
12
|
+
{ label: 'New Window', action: 'app.new-window' },
|
|
13
|
+
{ label: 'Quit', action: 'app.quit' },
|
|
14
|
+
],
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
label: 'Help',
|
|
18
|
+
submenu: [
|
|
19
|
+
{ label: 'Keyboard Shortcuts', action: 'app.shortcuts' },
|
|
20
|
+
{ label: 'About', action: 'app.about' },
|
|
21
|
+
],
|
|
22
|
+
},
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Story: adw-application-window with its menubar, a header bar and a status page —
|
|
27
|
+
* a 1:1 port of the GTK ApplicationWindowStory.
|
|
28
|
+
*/
|
|
29
|
+
export class ApplicationWindowWebStory extends StoryElement {
|
|
30
|
+
private _window: HTMLElement | null = null;
|
|
31
|
+
private _title: HTMLElement | null = null;
|
|
32
|
+
|
|
33
|
+
constructor() {
|
|
34
|
+
super(ApplicationWindowWebStory.getMetadata(), 'Default');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
static getMetadata(): StoryMeta {
|
|
38
|
+
return applicationWindowMeta;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
initialize(): void {
|
|
42
|
+
this._title = document.createElement('adw-window-title');
|
|
43
|
+
this._title.setAttribute('slot', 'title');
|
|
44
|
+
|
|
45
|
+
const backButton = document.createElement('gtk-button');
|
|
46
|
+
backButton.setAttribute('slot', 'start');
|
|
47
|
+
backButton.setAttribute('icon', 'go-previous');
|
|
48
|
+
backButton.setAttribute('flat', '');
|
|
49
|
+
|
|
50
|
+
const headerBar = document.createElement('adw-header-bar');
|
|
51
|
+
headerBar.style.width = '460px';
|
|
52
|
+
headerBar.append(backButton, this._title);
|
|
53
|
+
|
|
54
|
+
const toolbarView = document.createElement('adw-toolbar-view');
|
|
55
|
+
toolbarView.append(headerBar);
|
|
56
|
+
|
|
57
|
+
const statusPage = document.createElement('adw-status-page');
|
|
58
|
+
statusPage.setAttribute('title', 'Your Library');
|
|
59
|
+
statusPage.setAttribute('description', 'Content sits between the toolbars and scrolls independently of them.');
|
|
60
|
+
toolbarView.append(statusPage);
|
|
61
|
+
|
|
62
|
+
const window = document.createElement('adw-application-window');
|
|
63
|
+
window.setAttribute('width', '460');
|
|
64
|
+
window.setAttribute('height', '260');
|
|
65
|
+
// The model an application would OWN on GTK. `show-menubar` decides whether the
|
|
66
|
+
// window draws it, exactly as `Gtk.ApplicationWindow:show-menubar` does.
|
|
67
|
+
window.setAttribute('menu-model', JSON.stringify(MENU_MODEL));
|
|
68
|
+
this.applyMenubar(window, this.args.showMenubar as boolean);
|
|
69
|
+
window.append(toolbarView);
|
|
70
|
+
|
|
71
|
+
this._window = window;
|
|
72
|
+
this._sync();
|
|
73
|
+
this.addContent(window);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
updateArgs(_args: StoryArgs): void {
|
|
77
|
+
if (this._window) this.applyMenubar(this._window, this.args.showMenubar as boolean);
|
|
78
|
+
this._sync();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** The flag and the bar are ONE decision, the way the application window treats them. */
|
|
82
|
+
private applyMenubar(window: HTMLElement, showing: boolean): void {
|
|
83
|
+
if (showing) window.setAttribute('show-menubar', '');
|
|
84
|
+
else window.removeAttribute('show-menubar');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
private _sync(): void {
|
|
88
|
+
if (!this._title) return;
|
|
89
|
+
this._title.setAttribute('title', this.args.title as string);
|
|
90
|
+
this._title.setAttribute('subtitle', this.args.subtitle as string);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export const ApplicationWindowWebStories: WebStoryModule = { stories: [ApplicationWindowWebStory] };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// Browser port of the Aspect Frame story. Shares metadata with aspect-frame.story.ts.
|
|
2
|
+
|
|
3
|
+
import { StoryElement, type StoryArgs, type StoryMeta, type WebStoryModule } from '@gjsify/adwaita-storybook';
|
|
4
|
+
import { aspectFrameMeta } from '../../layout/aspect-frame.meta.js';
|
|
5
|
+
|
|
6
|
+
export class AspectFrameWebStory extends StoryElement {
|
|
7
|
+
private _frame: HTMLElement | null = null;
|
|
8
|
+
|
|
9
|
+
constructor() {
|
|
10
|
+
super(AspectFrameWebStory.getMetadata(), 'Default');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
static getMetadata(): StoryMeta {
|
|
14
|
+
return aspectFrameMeta;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
initialize(): void {
|
|
18
|
+
this._frame = document.createElement('gtk-aspect-frame');
|
|
19
|
+
// The GTK story asks for 320x180, which is what makes the ratio visible in both.
|
|
20
|
+
this._frame.style.width = '320px';
|
|
21
|
+
this._frame.style.height = '180px';
|
|
22
|
+
const body = document.createElement('gtk-label');
|
|
23
|
+
body.setAttribute(
|
|
24
|
+
'label',
|
|
25
|
+
'The frame gives this child the ratio above, and puts it where xalign and yalign say.',
|
|
26
|
+
);
|
|
27
|
+
body.style.padding = '12px';
|
|
28
|
+
this._frame.append(body);
|
|
29
|
+
this._apply();
|
|
30
|
+
this.addContent(this._frame);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
updateArgs(_args: StoryArgs): void {
|
|
34
|
+
this._apply();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
private _apply(): void {
|
|
38
|
+
if (!this._frame) return;
|
|
39
|
+
this._frame.setAttribute('ratio', String(this.args.ratio as number));
|
|
40
|
+
// Read, and it may well move nothing: the child fills the frame's width here, so
|
|
41
|
+
// there is no horizontal slack left for `xalign` to place it in — the divergence
|
|
42
|
+
// `gtk-aspect-frame.ts`'s header states. `yalign` below is the axis that moves.
|
|
43
|
+
this._frame.setAttribute('xalign', String(this.args.xalign as number));
|
|
44
|
+
this._frame.setAttribute('yalign', String(this.args.yalign as number));
|
|
45
|
+
this._frame.setAttribute('obey-child', String(this.args.obeyChild as boolean));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export const AspectFrameWebStories: WebStoryModule = { stories: [AspectFrameWebStory] };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Browser port of the Bin story. Shares metadata with bin.story.ts.
|
|
2
|
+
|
|
3
|
+
import { StoryElement, type StoryArgs, type StoryMeta, type WebStoryModule } from '@gjsify/adwaita-storybook';
|
|
4
|
+
import type { Adw } from '@gjsify/adwaita-web';
|
|
5
|
+
import { binMeta } from '../../layout/bin.meta.js';
|
|
6
|
+
|
|
7
|
+
export class BinWebStory extends StoryElement {
|
|
8
|
+
private _bin: Adw.Bin | null = null;
|
|
9
|
+
|
|
10
|
+
constructor() {
|
|
11
|
+
super(BinWebStory.getMetadata(), 'Default');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
static getMetadata(): StoryMeta {
|
|
15
|
+
return binMeta;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
initialize(): void {
|
|
19
|
+
this._bin = document.createElement('adw-bin') as Adw.Bin;
|
|
20
|
+
this._bin.style.width = '320px';
|
|
21
|
+
this._apply();
|
|
22
|
+
this.addContent(this._bin);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
updateArgs(_args: StoryArgs): void {
|
|
26
|
+
this._apply();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
private _apply(): void {
|
|
30
|
+
if (!this._bin) return;
|
|
31
|
+
const swap = this.args.swap as boolean;
|
|
32
|
+
const card = document.createElement('adw-card');
|
|
33
|
+
card.style.padding = '18px';
|
|
34
|
+
card.style.boxSizing = 'border-box';
|
|
35
|
+
card.textContent = swap ? 'The first child was replaced, not stacked.' : (this.args.label as string);
|
|
36
|
+
// `child` is `adw_bin_set_child`: the old child leaves.
|
|
37
|
+
this._bin.child = card;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export const BinWebStories: WebStoryModule = { stories: [BinWebStory] };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// Browser port of the Breakpoint Bin story. Shares metadata with breakpoint-bin.story.ts.
|
|
2
|
+
|
|
3
|
+
import { StoryElement, type StoryArgs, type StoryMeta, type WebStoryModule } from '@gjsify/adwaita-storybook';
|
|
4
|
+
import { breakpointBinMeta } from '../../layout/breakpoint-bin.meta.js';
|
|
5
|
+
|
|
6
|
+
export class BreakpointBinWebStory extends StoryElement {
|
|
7
|
+
private _bin: HTMLElement | null = null;
|
|
8
|
+
private _label: HTMLElement | null = null;
|
|
9
|
+
|
|
10
|
+
constructor() {
|
|
11
|
+
super(BreakpointBinWebStory.getMetadata(), 'Default');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
static getMetadata(): StoryMeta {
|
|
15
|
+
return breakpointBinMeta;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
initialize(): void {
|
|
19
|
+
this._bin = document.createElement('adw-breakpoint-bin');
|
|
20
|
+
// The C's own advice: a bin carrying breakpoints has no minimum size, so the stage
|
|
21
|
+
// is what decides how much room there is (adw-breakpoint-bin.c:57-61).
|
|
22
|
+
this._bin.style.minWidth = '150px';
|
|
23
|
+
this._bin.style.height = '60px';
|
|
24
|
+
this._label = document.createElement('gtk-label');
|
|
25
|
+
// The selector a `breakpoints` setter addresses its target by, so the id is the
|
|
26
|
+
// contract between the attribute and this element.
|
|
27
|
+
this._label.id = 'narrow';
|
|
28
|
+
this._label.classList.add('title-1');
|
|
29
|
+
this._bin.appendChild(this._label);
|
|
30
|
+
|
|
31
|
+
this._apply();
|
|
32
|
+
this.addContent(this._bin);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
updateArgs(_args: StoryArgs): void {
|
|
36
|
+
this._apply();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The `breakpoints` attribute, then the wide label.
|
|
41
|
+
*
|
|
42
|
+
* The attribute is written BEFORE the label's wide value so the setter registers
|
|
43
|
+
* against the wide value as its original — the order the C gets for free, because
|
|
44
|
+
* `add_setters` is called after the label was built.
|
|
45
|
+
*/
|
|
46
|
+
private _apply(): void {
|
|
47
|
+
if (!this._bin || !this._label) return;
|
|
48
|
+
this._label.setAttribute('label', this.args.wideLabel as string);
|
|
49
|
+
this._bin.setAttribute(
|
|
50
|
+
'breakpoints',
|
|
51
|
+
JSON.stringify([
|
|
52
|
+
{
|
|
53
|
+
condition: this.args.condition as string,
|
|
54
|
+
setters: [{ target: '#narrow', property: 'label', value: this.args.narrowLabel as string }],
|
|
55
|
+
},
|
|
56
|
+
]),
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export const BreakpointBinWebStories: WebStoryModule = { stories: [BreakpointBinWebStory] };
|