@gjsify/adwaita-web 0.64.1 → 0.64.2-next.254
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 +22 -88
- package/dist/adwaita-web.css +91 -12
- package/dist/adwaita-web.css.map +1 -1
- package/lib/types/accessible.d.ts +8 -0
- package/lib/types/application.d.ts +1 -1
- package/lib/types/child-slot.spec.d.ts +1 -0
- package/lib/types/compute-expand.d.ts +5 -0
- package/lib/types/compute-expand.spec.d.ts +1 -0
- package/lib/types/container-fill.spec.d.ts +1 -0
- package/lib/types/elements/adw-about-dialog.d.ts +28 -1
- package/lib/types/elements/adw-action-row.d.ts +2 -1
- package/lib/types/elements/adw-alert-dialog.d.ts +80 -19
- package/lib/types/elements/adw-avatar.d.ts +2 -1
- package/lib/types/elements/adw-banner.d.ts +2 -1
- package/lib/types/elements/adw-bin.d.ts +2 -1
- package/lib/types/elements/adw-bottom-sheet.d.ts +5 -4
- package/lib/types/elements/adw-breakpoint-bin.d.ts +2 -1
- package/lib/types/elements/adw-button-content.d.ts +2 -1
- package/lib/types/elements/adw-button-row.d.ts +2 -1
- package/lib/types/elements/adw-card.d.ts +2 -1
- package/lib/types/elements/adw-carousel.d.ts +20 -3
- package/lib/types/elements/adw-clamp-scrollable.d.ts +2 -1
- package/lib/types/elements/adw-clamp.d.ts +2 -1
- package/lib/types/elements/adw-combo-row.d.ts +6 -1
- package/lib/types/elements/adw-data-grid.d.ts +2 -1
- package/lib/types/elements/adw-dialog.d.ts +2 -1
- package/lib/types/elements/adw-entry-row.d.ts +2 -1
- package/lib/types/elements/adw-expander-row.d.ts +2 -1
- package/lib/types/elements/adw-header-bar.d.ts +2 -1
- package/lib/types/elements/adw-inline-view-switcher.d.ts +3 -2
- package/lib/types/elements/adw-layout-slot.d.ts +2 -1
- package/lib/types/elements/adw-multi-layout-view.d.ts +2 -1
- package/lib/types/elements/adw-navigation-split-view.d.ts +2 -1
- package/lib/types/elements/adw-navigation-view.d.ts +3 -2
- package/lib/types/elements/adw-overlay-split-view.d.ts +2 -1
- package/lib/types/elements/adw-preferences-dialog.d.ts +5 -4
- package/lib/types/elements/adw-preferences-group.d.ts +2 -1
- package/lib/types/elements/adw-preferences-row.d.ts +2 -1
- package/lib/types/elements/adw-shortcut-label.d.ts +2 -1
- package/lib/types/elements/adw-shortcuts-item.d.ts +2 -1
- package/lib/types/elements/adw-shortcuts-section.d.ts +2 -1
- package/lib/types/elements/adw-sidebar.d.ts +4 -3
- package/lib/types/elements/adw-spin-row.d.ts +2 -1
- package/lib/types/elements/adw-spinner.d.ts +2 -1
- package/lib/types/elements/adw-split-button.d.ts +2 -1
- package/lib/types/elements/adw-status-page.d.ts +2 -1
- package/lib/types/elements/adw-switch-row.d.ts +4 -1
- package/lib/types/elements/adw-tab-bar.d.ts +2 -1
- package/lib/types/elements/adw-tab-button.d.ts +2 -1
- package/lib/types/elements/adw-tab-overview.d.ts +2 -1
- package/lib/types/elements/adw-tab-view.d.ts +3 -2
- package/lib/types/elements/adw-toast-overlay.d.ts +10 -30
- package/lib/types/elements/adw-toggle-group.d.ts +3 -2
- package/lib/types/elements/adw-toolbar-view.d.ts +2 -1
- package/lib/types/elements/adw-view-stack.d.ts +3 -1
- package/lib/types/elements/adw-view-switcher-bar.d.ts +2 -1
- package/lib/types/elements/adw-view-switcher-sidebar.d.ts +2 -1
- package/lib/types/elements/adw-view-switcher.d.ts +3 -2
- package/lib/types/elements/adw-window-features.d.ts +8 -0
- package/lib/types/elements/adw-window-title.d.ts +2 -1
- package/lib/types/elements/adw-wrap-box.d.ts +2 -1
- package/lib/types/elements/checks.d.ts +16 -1
- package/lib/types/elements/gtk-action-bar.d.ts +2 -1
- package/lib/types/elements/gtk-application-window.d.ts +1 -4
- package/lib/types/elements/gtk-aspect-frame.d.ts +2 -1
- package/lib/types/elements/gtk-box.d.ts +5 -1
- package/lib/types/elements/gtk-button.d.ts +5 -7
- package/lib/types/elements/gtk-calendar.d.ts +2 -1
- package/lib/types/elements/gtk-center-box.d.ts +2 -1
- package/lib/types/elements/gtk-color-dialog-button.d.ts +2 -1
- package/lib/types/elements/gtk-drag-icon.d.ts +2 -1
- package/lib/types/elements/gtk-drawing-area.d.ts +2 -1
- package/lib/types/elements/gtk-drop-down.d.ts +2 -1
- package/lib/types/elements/gtk-editable-label.d.ts +2 -1
- package/lib/types/elements/gtk-emoji-chooser.d.ts +2 -0
- package/lib/types/elements/gtk-entry.d.ts +2 -1
- package/lib/types/elements/gtk-expander.d.ts +2 -1
- package/lib/types/elements/gtk-fixed.d.ts +2 -1
- package/lib/types/elements/gtk-flow-box-child.d.ts +2 -1
- package/lib/types/elements/gtk-flow-box.d.ts +2 -1
- package/lib/types/elements/gtk-font-dialog-button.d.ts +2 -1
- package/lib/types/elements/gtk-frame.d.ts +2 -1
- package/lib/types/elements/gtk-gl-area.d.ts +2 -1
- package/lib/types/elements/gtk-graphics-offload.d.ts +2 -1
- package/lib/types/elements/gtk-grid.d.ts +2 -1
- package/lib/types/elements/gtk-header-bar.d.ts +2 -1
- package/lib/types/elements/gtk-image.d.ts +5 -6
- package/lib/types/elements/gtk-inscription.d.ts +2 -1
- package/lib/types/elements/gtk-label.d.ts +10 -3
- package/lib/types/elements/gtk-level-bar.d.ts +2 -1
- package/lib/types/elements/gtk-list-box-row.d.ts +2 -1
- package/lib/types/elements/gtk-list-box.d.ts +2 -1
- package/lib/types/elements/gtk-list-view.d.ts +2 -1
- package/lib/types/elements/gtk-media-controls.d.ts +2 -1
- package/lib/types/elements/gtk-menu-button.d.ts +2 -1
- package/lib/types/elements/gtk-notebook.d.ts +2 -1
- package/lib/types/elements/gtk-overlay.d.ts +2 -1
- package/lib/types/elements/gtk-paned.d.ts +2 -1
- package/lib/types/elements/gtk-picture.d.ts +2 -1
- package/lib/types/elements/gtk-popover-bin.d.ts +2 -1
- package/lib/types/elements/gtk-popover-menu-bar.d.ts +2 -1
- package/lib/types/elements/gtk-popover-menu.d.ts +2 -0
- package/lib/types/elements/gtk-popover.d.ts +7 -1
- package/lib/types/elements/gtk-progress-bar.d.ts +2 -1
- package/lib/types/elements/gtk-revealer.d.ts +2 -1
- package/lib/types/elements/gtk-scale-button.d.ts +2 -1
- package/lib/types/elements/gtk-scale.d.ts +2 -1
- package/lib/types/elements/gtk-scrollbar.d.ts +2 -1
- package/lib/types/elements/gtk-scrolled-window.d.ts +2 -1
- package/lib/types/elements/gtk-search-bar.d.ts +2 -1
- package/lib/types/elements/gtk-separator.d.ts +2 -1
- package/lib/types/elements/gtk-spin-button.d.ts +2 -1
- package/lib/types/elements/gtk-spinner.d.ts +2 -1
- package/lib/types/elements/gtk-stack-page.d.ts +29 -0
- package/lib/types/elements/gtk-stack-sidebar.d.ts +2 -1
- package/lib/types/elements/gtk-stack-switcher.d.ts +2 -1
- package/lib/types/elements/gtk-stack.d.ts +13 -1
- package/lib/types/elements/gtk-switch.d.ts +2 -1
- package/lib/types/elements/gtk-text-view.d.ts +2 -1
- package/lib/types/elements/gtk-text.d.ts +2 -1
- package/lib/types/elements/gtk-tree-expander.d.ts +2 -1
- package/lib/types/elements/gtk-video.d.ts +2 -1
- package/lib/types/elements/gtk-viewport.d.ts +2 -1
- package/lib/types/elements/gtk-window-controls.d.ts +2 -1
- package/lib/types/elements/gtk-window-handle.d.ts +2 -1
- package/lib/types/elements/gtk-window.d.ts +18 -2
- package/lib/types/gobject-elements.d.ts +15 -0
- package/lib/types/gtksource/gtk-source-view.d.ts +2 -1
- package/lib/types/{icon-registry.spec.d.ts → icon-masks.spec.d.ts} +1 -1
- package/lib/types/icon-theme.d.ts +15 -35
- package/lib/types/index.d.ts +3 -4
- package/lib/types/learn6502-window.spec.d.ts +1 -0
- package/lib/types/namespace/adw.d.ts +1 -1
- package/lib/types/namespace/gdk.d.ts +1 -0
- package/lib/types/namespace/gio.d.ts +1 -0
- package/lib/types/namespace/glib.d.ts +2 -1
- package/lib/types/namespace/gtk.d.ts +2 -0
- package/lib/types/shared-tree-builder.d.ts +31 -0
- package/lib/types/signals.d.ts +5 -1
- package/lib/types/source-view/adw-source-view.d.ts +2 -1
- package/lib/types/styles.generated.d.ts +1 -1
- package/lib/types/widget-element.d.ts +25 -0
- package/lib/types/widget-map.spec.d.ts +1 -0
- package/lib/types/widget-mapping.d.ts +7 -0
- package/lib/types/widget-visible.spec.d.ts +1 -0
- package/lib/types/window-maximize.spec.d.ts +1 -0
- package/package.json +13 -12
- package/scss/_about_dialog.scss +46 -1
- package/scss/_bin.scss +6 -3
- package/scss/_checks.scss +5 -2
- package/scss/_icon.scss +3 -4
- package/scss/_labels.scss +2 -2
- package/scss/_overlay.scss +11 -1
- package/scss/_overlay_split_view.scss +10 -0
- package/scss/_reset.scss +1 -1
- package/scss/_scrolled_window.scss +15 -0
- package/scss/_stack.scss +8 -2
- package/scss/_toast.scss +13 -3
- package/scss/_widget.scss +5 -1
- package/scss/_window.scss +16 -0
- package/src/accessible.ts +29 -0
- package/src/adw-about-dialog.spec.ts +81 -12
- package/src/adw-action-rows.spec.ts +2 -2
- package/src/adw-alert-dialog.spec.ts +71 -5
- package/src/adw-bin.spec.ts +4 -3
- package/src/adw-button-content.spec.ts +1 -1
- package/src/adw-carousel.spec.ts +49 -1
- package/src/adw-header-bar.spec.ts +18 -0
- package/src/adw-toast-overlay.spec.ts +68 -24
- package/src/application.spec.ts +44 -0
- package/src/application.ts +13 -18
- package/src/capabilities.mjs +2 -3
- package/src/checks.spec.ts +51 -1
- package/src/child-slot.spec.ts +71 -0
- package/src/compute-expand.spec.ts +186 -0
- package/src/compute-expand.ts +134 -0
- package/src/construct-vectors.spec.ts +97 -7
- package/src/container-fill.spec.ts +70 -0
- package/src/elements/adw-about-dialog.ts +152 -9
- package/src/elements/adw-action-row.ts +2 -1
- package/src/elements/adw-alert-dialog.ts +177 -46
- package/src/elements/adw-application-window.ts +0 -3
- package/src/elements/adw-avatar.ts +2 -1
- package/src/elements/adw-banner.ts +2 -1
- package/src/elements/adw-bin.ts +2 -1
- package/src/elements/adw-bottom-sheet.ts +5 -4
- package/src/elements/adw-breakpoint-bin.ts +5 -1
- package/src/elements/adw-button-content.ts +2 -1
- package/src/elements/adw-button-row.ts +2 -1
- package/src/elements/adw-card.ts +2 -1
- package/src/elements/adw-carousel.ts +62 -3
- package/src/elements/adw-clamp-scrollable.ts +2 -1
- package/src/elements/adw-clamp.ts +2 -1
- package/src/elements/adw-combo-row.ts +15 -1
- package/src/elements/adw-data-grid.ts +2 -1
- package/src/elements/adw-dialog.ts +5 -2
- package/src/elements/adw-entry-row.ts +2 -1
- package/src/elements/adw-expander-row.ts +2 -1
- package/src/elements/adw-header-bar.ts +6 -1
- package/src/elements/adw-inline-view-switcher.ts +3 -2
- package/src/elements/adw-layout-slot.ts +2 -1
- package/src/elements/adw-multi-layout-view.ts +2 -1
- package/src/elements/adw-navigation-split-view.ts +2 -1
- package/src/elements/adw-navigation-view.ts +3 -2
- package/src/elements/adw-overlay-split-view.ts +2 -1
- package/src/elements/adw-preferences-dialog.ts +6 -4
- package/src/elements/adw-preferences-group.ts +2 -1
- package/src/elements/adw-preferences-row.ts +2 -1
- package/src/elements/adw-shortcut-label.ts +2 -1
- package/src/elements/adw-shortcuts-item.ts +2 -1
- package/src/elements/adw-shortcuts-section.ts +2 -1
- package/src/elements/adw-sidebar.ts +4 -3
- package/src/elements/adw-spin-row.ts +2 -1
- package/src/elements/adw-spinner.ts +2 -1
- package/src/elements/adw-split-button.ts +2 -1
- package/src/elements/adw-status-page.ts +2 -1
- package/src/elements/adw-switch-row.ts +10 -1
- package/src/elements/adw-tab-bar.ts +2 -1
- package/src/elements/adw-tab-button.ts +2 -1
- package/src/elements/adw-tab-overview.ts +2 -1
- package/src/elements/adw-tab-view.ts +3 -2
- package/src/elements/adw-toast-overlay.ts +37 -70
- package/src/elements/adw-toggle-group.ts +3 -2
- package/src/elements/adw-toolbar-view.ts +2 -1
- package/src/elements/adw-view-stack.ts +39 -1
- package/src/elements/adw-view-switcher-bar.ts +2 -1
- package/src/elements/adw-view-switcher-sidebar.ts +2 -1
- package/src/elements/adw-view-switcher.ts +3 -2
- package/src/elements/adw-window-features.ts +14 -2
- package/src/elements/adw-window-title.ts +2 -1
- package/src/elements/adw-wrap-box.ts +2 -1
- package/src/elements/checks.ts +85 -6
- package/src/elements/gtk-action-bar.ts +2 -1
- package/src/elements/gtk-application-window.ts +3 -8
- package/src/elements/gtk-aspect-frame.ts +2 -1
- package/src/elements/gtk-box.ts +56 -1
- package/src/elements/gtk-button.ts +10 -22
- package/src/elements/gtk-calendar.ts +2 -1
- package/src/elements/gtk-center-box.ts +2 -1
- package/src/elements/gtk-color-dialog-button.ts +2 -1
- package/src/elements/gtk-drag-icon.ts +6 -1
- package/src/elements/gtk-drawing-area.ts +2 -1
- package/src/elements/gtk-drop-down.ts +2 -1
- package/src/elements/gtk-editable-label.ts +2 -1
- package/src/elements/gtk-emoji-chooser.ts +5 -0
- package/src/elements/gtk-entry.ts +2 -1
- package/src/elements/gtk-expander.ts +2 -1
- package/src/elements/gtk-fixed.ts +2 -1
- package/src/elements/gtk-flow-box-child.ts +5 -2
- package/src/elements/gtk-flow-box.ts +2 -1
- package/src/elements/gtk-font-dialog-button.ts +2 -1
- package/src/elements/gtk-frame.ts +2 -1
- package/src/elements/gtk-gl-area.ts +2 -1
- package/src/elements/gtk-graphics-offload.ts +5 -2
- package/src/elements/gtk-grid.ts +2 -1
- package/src/elements/gtk-header-bar.ts +2 -1
- package/src/elements/gtk-image.ts +14 -15
- package/src/elements/gtk-inscription.ts +2 -1
- package/src/elements/gtk-label.ts +12 -5
- package/src/elements/gtk-level-bar.ts +2 -1
- package/src/elements/gtk-list-box-row.ts +5 -2
- package/src/elements/gtk-list-box.ts +2 -1
- package/src/elements/gtk-list-view.ts +2 -1
- package/src/elements/gtk-media-controls.ts +2 -1
- package/src/elements/gtk-menu-button.ts +2 -1
- package/src/elements/gtk-notebook.ts +2 -1
- package/src/elements/gtk-overlay.ts +7 -5
- package/src/elements/gtk-paned.ts +9 -2
- package/src/elements/gtk-picture.ts +2 -1
- package/src/elements/gtk-popover-bin.ts +5 -1
- package/src/elements/gtk-popover-menu-bar.ts +2 -1
- package/src/elements/gtk-popover-menu.ts +5 -0
- package/src/elements/gtk-popover.ts +14 -1
- package/src/elements/gtk-progress-bar.ts +2 -1
- package/src/elements/gtk-revealer.ts +2 -1
- package/src/elements/gtk-scale-button.ts +2 -1
- package/src/elements/gtk-scale.ts +2 -1
- package/src/elements/gtk-scrollbar.ts +2 -1
- package/src/elements/gtk-scrolled-window.ts +8 -5
- package/src/elements/gtk-search-bar.ts +7 -6
- package/src/elements/gtk-separator.ts +2 -1
- package/src/elements/gtk-spin-button.ts +2 -1
- package/src/elements/gtk-spinner.ts +2 -1
- package/src/elements/gtk-stack-page.ts +112 -0
- package/src/elements/gtk-stack-sidebar.ts +2 -1
- package/src/elements/gtk-stack-switcher.ts +2 -1
- package/src/elements/gtk-stack.ts +52 -6
- package/src/elements/gtk-switch.ts +2 -1
- package/src/elements/gtk-text-view.ts +2 -1
- package/src/elements/gtk-text.ts +2 -1
- package/src/elements/gtk-tree-expander.ts +5 -1
- package/src/elements/gtk-video.ts +2 -1
- package/src/elements/gtk-viewport.ts +6 -1
- package/src/elements/gtk-window-controls.ts +2 -1
- package/src/elements/gtk-window-handle.ts +6 -1
- package/src/elements/gtk-window.ts +57 -7
- package/src/gio.spec.ts +13 -3
- package/src/glib.spec.ts +9 -0
- package/src/gobject-elements.ts +44 -2
- package/src/gtk-label.spec.ts +39 -0
- package/src/gtk-scrolled-window.spec.ts +6 -6
- package/src/gtk-stack.spec.ts +170 -0
- package/src/gtk-value-doors.spec.ts +19 -0
- package/src/gtk-window.spec.ts +2 -2
- package/src/gtksource/gtk-source-view.ts +2 -1
- package/src/{icon-registry.spec.ts → icon-masks.spec.ts} +4 -100
- package/src/icon-theme.spec.ts +69 -124
- package/src/icon-theme.ts +29 -119
- package/src/index.ts +5 -9
- package/src/keyboard-operable.spec.ts +3 -3
- package/src/learn6502-window.spec.ts +113 -0
- package/src/namespace/adw.ts +1 -1
- package/src/namespace/gdk.ts +1 -0
- package/src/namespace/gio.ts +8 -0
- package/src/namespace/glib.ts +4 -0
- package/src/namespace/gtk.ts +2 -0
- package/src/shared-tree-builder.ts +131 -13
- package/src/shared-trees.spec.ts +15 -1
- package/src/signals.ts +11 -2
- package/src/slotted-children.spec.ts +24 -0
- package/src/slotted-children.ts +18 -2
- package/src/source-view/adw-source-view.ts +2 -1
- package/src/split-button.spec.ts +1 -1
- package/src/style-manager.spec.ts +13 -0
- package/src/style-manager.ts +6 -0
- package/src/styles.generated.ts +1 -1
- package/src/test.browser.mts +16 -2
- package/src/value-lists.spec.ts +3 -3
- package/src/widget-element.ts +75 -0
- package/src/widget-map.spec.ts +116 -0
- package/src/widget-mapping.ts +100 -0
- package/src/widget-visible.spec.ts +148 -0
- package/src/window-maximize.spec.ts +93 -0
- package/lib/types/icon-registry.d.ts +0 -37
- package/src/icon-registry.ts +0 -163
|
@@ -2,44 +2,35 @@
|
|
|
2
2
|
// content and shows transient toast strips (title, optional action button, close
|
|
3
3
|
// affordance) layered over the bottom of its own bounds.
|
|
4
4
|
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
5
|
+
// A toast is an `Adw.Toast` and goes in through `add_toast(toast)`, exactly as on GTK, so a
|
|
6
|
+
// GNOME app's toast code runs here unchanged. The QUEUE — one toast at a time, priority,
|
|
7
|
+
// re-add, auto-dismiss — is HEADLESS and lives in `@gjsify/adwaita-core` (ADR 0004) as
|
|
8
|
+
// {@link ToastOverlayQueue}; this element keeps only the DOM half: build the strip on
|
|
9
|
+
// `onShow`, tear it down on `onHide`, run the enter/exit transitions.
|
|
9
10
|
//
|
|
10
11
|
// Adapted from Adwaita Web UI Framework (https://github.com/mclellac/adwaita-web).
|
|
11
12
|
// Reference: refs/adwaita-web/adwaita-web/scss/_toast.scss, _toast_overlay.scss
|
|
12
|
-
// Reference: refs/libadwaita/src/adw-toast-overlay.c, adw-toast.c (add_toast queues,
|
|
13
|
-
// one toast is shown at a time,
|
|
13
|
+
// Reference: refs/libadwaita/src/adw-toast-overlay.c, adw-toast-widget.c (add_toast queues,
|
|
14
|
+
// one toast is shown at a time, the button emits button-clicked, activates the action and
|
|
15
|
+
// dismisses)
|
|
14
16
|
// Copyright (c) 2025 csm (adwaita-web). MIT License.
|
|
15
17
|
// Copyright (c) GNOME contributors (libadwaita). LGPLv2.1+.
|
|
16
|
-
// Modifications: Reimplemented as Web Component for @gjsify/adwaita-web;
|
|
17
|
-
// extended addToast() with action button + close button + options API; the
|
|
18
|
+
// Modifications: Reimplemented as Web Component for @gjsify/adwaita-web; the
|
|
18
19
|
// queue/auto-dismiss state machine composed from @gjsify/adwaita-core.
|
|
19
20
|
|
|
20
|
-
import {
|
|
21
|
+
import { ToastOverlayQueue } from '@gjsify/adwaita-core';
|
|
21
22
|
|
|
23
|
+
import { activateWidgetAction } from '../application.js';
|
|
24
|
+
import { renderPangoMarkup } from '../pango-markup.js';
|
|
22
25
|
import { bindSlottedChildren } from '../slotted-children.js';
|
|
23
26
|
import { createGtkImage } from './gtk-image.js';
|
|
24
|
-
import type { ToastScheduler, ToastTimerHandle } from '@gjsify/adwaita-core';
|
|
27
|
+
import type { Toast, ToastScheduler, ToastTimerHandle } from '@gjsify/adwaita-core';
|
|
28
|
+
import { WidgetElement } from '../widget-element.js';
|
|
25
29
|
|
|
26
30
|
// The timing seam is re-exported so a consumer can type a custom scheduler for
|
|
27
31
|
// {@link AdwToastOverlay.scheduler} without depending on the core package.
|
|
28
32
|
export type { ToastScheduler, ToastTimerHandle } from '@gjsify/adwaita-core';
|
|
29
33
|
|
|
30
|
-
/** Options for {@link AdwToastOverlay.addToast}, mirroring Adw.Toast's properties. */
|
|
31
|
-
export interface AdwToastOptions {
|
|
32
|
-
/** Seconds before the toast auto-dismisses; `0` keeps it until dismissed. Mirrors Adw.Toast:timeout (default 5). */
|
|
33
|
-
timeout?: number;
|
|
34
|
-
/** Label for the action button; omitted/empty means no button. Mirrors Adw.Toast:button-label. */
|
|
35
|
-
buttonLabel?: string;
|
|
36
|
-
/** Invoked when the action button is pressed. Mirrors the activation of Adw.Toast:action-name. */
|
|
37
|
-
onAction?: () => void;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/** Default toast lifetime in SECONDS — this element's public unit (Adw.Toast:timeout). */
|
|
41
|
-
const DEFAULT_TIMEOUT_SECONDS = 5;
|
|
42
|
-
|
|
43
34
|
/**
|
|
44
35
|
* Fallback budget in ms for the exit transition: must stay at or above the
|
|
45
36
|
* `.adw-toast.hiding` transition-duration in `_toast.scss` (0.15s today), because it
|
|
@@ -53,21 +44,19 @@ const domScheduler: ToastScheduler = {
|
|
|
53
44
|
cancel: (handle) => clearTimeout(handle as ReturnType<typeof setTimeout>),
|
|
54
45
|
};
|
|
55
46
|
|
|
56
|
-
export class AdwToastOverlay extends
|
|
47
|
+
export class AdwToastOverlay extends WidgetElement {
|
|
57
48
|
private _toasts!: HTMLDivElement;
|
|
58
49
|
private _initialized = false;
|
|
59
|
-
/** The headless
|
|
60
|
-
private readonly _queue:
|
|
50
|
+
/** The headless queue of `adw-toast-overlay.c` (ADR 0004). */
|
|
51
|
+
private readonly _queue: ToastOverlayQueue;
|
|
61
52
|
/** The timing source the queue's auto-dismiss runs on — swappable, see {@link scheduler}. */
|
|
62
53
|
private _scheduler: ToastScheduler = domScheduler;
|
|
63
|
-
/** The strip currently mounted for {@link
|
|
54
|
+
/** The strip currently mounted for {@link ToastOverlayQueue.current}, if any. */
|
|
64
55
|
private _currentEl: HTMLDivElement | null = null;
|
|
65
|
-
/** Per-toast action callbacks (the core toast descriptor carries only the label). */
|
|
66
|
-
private readonly _actions = new WeakMap<AdwToast, () => void>();
|
|
67
56
|
|
|
68
57
|
constructor() {
|
|
69
58
|
super();
|
|
70
|
-
this._queue = new
|
|
59
|
+
this._queue = new ToastOverlayQueue({
|
|
71
60
|
// Indirect through `this._scheduler` so the timing source stays
|
|
72
61
|
// swappable after construction (the queue takes its scheduler once).
|
|
73
62
|
scheduler: {
|
|
@@ -97,7 +86,7 @@ export class AdwToastOverlay extends HTMLElement {
|
|
|
97
86
|
this._toasts = document.createElement('div');
|
|
98
87
|
this._toasts.className = 'adw-toast-overlay-toasts';
|
|
99
88
|
|
|
100
|
-
bindSlottedChildren(this, [{ into: content }]).install(content, this._toasts);
|
|
89
|
+
bindSlottedChildren(this, [{ name: 'child', into: content }, { into: content }]).install(content, this._toasts);
|
|
101
90
|
}
|
|
102
91
|
|
|
103
92
|
/**
|
|
@@ -115,7 +104,7 @@ export class AdwToastOverlay extends HTMLElement {
|
|
|
115
104
|
}
|
|
116
105
|
|
|
117
106
|
/** The toast currently on screen, or `null` when nothing is shown. */
|
|
118
|
-
get currentToast():
|
|
107
|
+
get currentToast(): Toast | null {
|
|
119
108
|
return this._queue.current;
|
|
120
109
|
}
|
|
121
110
|
|
|
@@ -124,45 +113,21 @@ export class AdwToastOverlay extends HTMLElement {
|
|
|
124
113
|
return this._queue.pending;
|
|
125
114
|
}
|
|
126
115
|
|
|
127
|
-
/**
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
* immediately when the slot is free, otherwise it waits its turn.
|
|
131
|
-
*
|
|
132
|
-
* `options` is either an {@link AdwToastOptions} bag or, as a legacy shorthand, a
|
|
133
|
-
* timeout in MILLISECONDS.
|
|
134
|
-
*/
|
|
135
|
-
addToast(title: string, options: number | AdwToastOptions = {}): void {
|
|
136
|
-
// Ensure the toast container exists even if addToast() races a not-yet
|
|
116
|
+
/** `adw_toast_overlay_add_toast`: show `toast` now, or queue it by its priority. */
|
|
117
|
+
add_toast(toast: Toast): void {
|
|
118
|
+
// Ensure the toast container exists even if add_toast() races a not-yet
|
|
137
119
|
// connected element (mirrors Adw.ToastOverlay queuing before realize).
|
|
138
120
|
if (!this._toasts) this.connectedCallback();
|
|
139
|
-
|
|
140
|
-
// Back-compat: the original signature was addToast(title, timeoutMs).
|
|
141
|
-
const opts: AdwToastOptions = typeof options === 'number' ? { timeout: options / 1000 } : options;
|
|
142
|
-
|
|
143
|
-
// This element's public timeout unit is SECONDS (Adw.Toast:timeout); the
|
|
144
|
-
// headless descriptor counts milliseconds.
|
|
145
|
-
const toast = new AdwToast(title, {
|
|
146
|
-
timeout: (opts.timeout ?? DEFAULT_TIMEOUT_SECONDS) * 1000,
|
|
147
|
-
buttonLabel: opts.buttonLabel,
|
|
148
|
-
});
|
|
149
|
-
if (opts.onAction) this._actions.set(toast, opts.onAction);
|
|
150
|
-
|
|
151
|
-
this._queue.add(toast);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/** Dismiss the visible toast early; the next queued toast takes its place. */
|
|
155
|
-
dismiss(): void {
|
|
156
|
-
this._queue.dismiss();
|
|
121
|
+
this._queue.add_toast(toast);
|
|
157
122
|
}
|
|
158
123
|
|
|
159
|
-
/**
|
|
160
|
-
|
|
161
|
-
this._queue.
|
|
124
|
+
/** `adw_toast_overlay_dismiss_all`: dismiss every queued toast, then the visible one. */
|
|
125
|
+
dismiss_all(): void {
|
|
126
|
+
this._queue.dismiss_all();
|
|
162
127
|
}
|
|
163
128
|
|
|
164
129
|
/** Build + attach the strip for `toast` — the DOM half of the queue's `onShow`. */
|
|
165
|
-
private _mountToast(toast:
|
|
130
|
+
private _mountToast(toast: Toast): void {
|
|
166
131
|
const el = document.createElement('div');
|
|
167
132
|
el.className = 'adw-toast';
|
|
168
133
|
|
|
@@ -171,18 +136,20 @@ export class AdwToastOverlay extends HTMLElement {
|
|
|
171
136
|
|
|
172
137
|
const titleEl = document.createElement('span');
|
|
173
138
|
titleEl.className = 'adw-toast-title';
|
|
174
|
-
|
|
139
|
+
if (toast.use_markup) renderPangoMarkup(titleEl, toast.title);
|
|
140
|
+
else titleEl.textContent = toast.title;
|
|
175
141
|
wrapper.appendChild(titleEl);
|
|
176
142
|
el.appendChild(wrapper);
|
|
177
143
|
|
|
178
|
-
if (toast.
|
|
144
|
+
if (toast.button_label) {
|
|
179
145
|
const button = document.createElement('button');
|
|
180
146
|
button.type = 'button';
|
|
181
147
|
button.className = 'adw-toast-action-button';
|
|
182
|
-
button.textContent = toast.
|
|
148
|
+
button.textContent = toast.button_label;
|
|
183
149
|
button.addEventListener('click', () => {
|
|
184
|
-
|
|
185
|
-
this.
|
|
150
|
+
toast.emit('button-clicked');
|
|
151
|
+
if (toast.action_name) activateWidgetAction(this, toast.action_name);
|
|
152
|
+
toast.dismiss();
|
|
186
153
|
});
|
|
187
154
|
el.appendChild(button);
|
|
188
155
|
}
|
|
@@ -197,7 +164,7 @@ export class AdwToastOverlay extends HTMLElement {
|
|
|
197
164
|
close.className = 'adw-toast-close-button';
|
|
198
165
|
close.setAttribute('aria-label', 'Close');
|
|
199
166
|
close.appendChild(createGtkImage('window-close'));
|
|
200
|
-
close.addEventListener('click', () =>
|
|
167
|
+
close.addEventListener('click', () => toast.dismiss());
|
|
201
168
|
el.appendChild(close);
|
|
202
169
|
|
|
203
170
|
this._toasts.appendChild(el);
|
|
@@ -83,9 +83,10 @@ import { ToggleGroupState, keptToggles, toggleIndexOfName } from '@gjsify/adwait
|
|
|
83
83
|
import { booleanAttribute } from '../attributes.js';
|
|
84
84
|
import { createGtkImage } from './gtk-image.js';
|
|
85
85
|
import { attachRovingFocus } from './roving-focus.js';
|
|
86
|
+
import { WidgetElement } from '../widget-element.js';
|
|
86
87
|
|
|
87
88
|
/** A single toggle. Children of <adw-toggle-group>; consumed at connect time. */
|
|
88
|
-
export class AdwToggle extends
|
|
89
|
+
export class AdwToggle extends WidgetElement {
|
|
89
90
|
// `tooltip` joins because `AdwToggle:tooltip` exists upstream (:467) and an
|
|
90
91
|
// icon-only toggle has no other text — `tooltip` is what NAMES it, so it is not a
|
|
91
92
|
// decoration. It produces no disabled or hidden button, which is the invariant
|
|
@@ -111,7 +112,7 @@ export class AdwToggle extends HTMLElement {
|
|
|
111
112
|
}
|
|
112
113
|
}
|
|
113
114
|
|
|
114
|
-
export class AdwToggleGroup extends
|
|
115
|
+
export class AdwToggleGroup extends WidgetElement {
|
|
115
116
|
private _innerEl!: HTMLDivElement;
|
|
116
117
|
private _buttons: HTMLButtonElement[] = [];
|
|
117
118
|
/** The headless segment list + guarded selection state machine (ADR 0004). */
|
|
@@ -33,8 +33,9 @@ import {
|
|
|
33
33
|
import { bindEmptySections } from '../empty-sections.js';
|
|
34
34
|
import { AdwScrollShading } from '../scroll-shading.js';
|
|
35
35
|
import { bindSlottedChildren } from '../slotted-children.js';
|
|
36
|
+
import { WidgetElement } from '../widget-element.js';
|
|
36
37
|
|
|
37
|
-
export class AdwToolbarView extends
|
|
38
|
+
export class AdwToolbarView extends WidgetElement {
|
|
38
39
|
private _topEl!: HTMLDivElement;
|
|
39
40
|
private _contentEl!: HTMLDivElement;
|
|
40
41
|
private _bottomEl!: HTMLDivElement;
|
|
@@ -51,10 +51,11 @@ import { ViewStackState } from '@gjsify/adwaita-core';
|
|
|
51
51
|
import type { AdwViewStackPageInfo as CorePageInfo, ViewStackStateChange } from '@gjsify/adwaita-core';
|
|
52
52
|
|
|
53
53
|
import type { DispatchedSignals } from '../signals.js';
|
|
54
|
+
import { WidgetElement } from '../widget-element.js';
|
|
54
55
|
|
|
55
56
|
export type AdwViewStackPageInfo = CorePageInfo<HTMLElement>;
|
|
56
57
|
|
|
57
|
-
export class AdwViewStack extends
|
|
58
|
+
export class AdwViewStack extends WidgetElement {
|
|
58
59
|
/** The GTK signals this element dispatches, each with the DOM event it arrives as (ADR 0093). */
|
|
59
60
|
static readonly signals: DispatchedSignals = {
|
|
60
61
|
'notify::visible-child': 'notify::visible-child',
|
|
@@ -73,6 +74,11 @@ export class AdwViewStack extends HTMLElement {
|
|
|
73
74
|
// Subscribing touches no attributes and no children, so it is legal in a
|
|
74
75
|
// custom element constructor — unlike anything DOM-shaped.
|
|
75
76
|
this._state.subscribe((change) => this._onStateChange(change));
|
|
77
|
+
// A page moved out by plain DOM (`otherBox.append(page)`) is `gtk_widget_unparent`
|
|
78
|
+
// reaching the stack's `remove`: `stack_remove` (adw-view-stack.c:1184-1205) drops
|
|
79
|
+
// the page, so it must not stay in the model or keep the stack's marks elsewhere.
|
|
80
|
+
// Observing the element itself touches no attribute and no child.
|
|
81
|
+
new MutationObserver((records) => this._onChildrenRemoved(records)).observe(this, { childList: true });
|
|
76
82
|
}
|
|
77
83
|
|
|
78
84
|
get pages(): readonly AdwViewStackPageInfo[] {
|
|
@@ -217,6 +223,7 @@ export class AdwViewStack extends HTMLElement {
|
|
|
217
223
|
const content = this._state.pages[this._state.indexOfName(name)]?.content;
|
|
218
224
|
if (!this._state.removePage(name)) return false;
|
|
219
225
|
content?.remove();
|
|
226
|
+
if (content) clearPageMarks(content);
|
|
220
227
|
this._applyVisibility();
|
|
221
228
|
this._reflectName();
|
|
222
229
|
this._emitItemsChanged();
|
|
@@ -271,6 +278,25 @@ export class AdwViewStack extends HTMLElement {
|
|
|
271
278
|
);
|
|
272
279
|
}
|
|
273
280
|
|
|
281
|
+
private _onChildrenRemoved(records: MutationRecord[]): void {
|
|
282
|
+
let changed = false;
|
|
283
|
+
for (const record of records) {
|
|
284
|
+
for (const node of record.removedNodes) {
|
|
285
|
+
// Re-appended into this same stack (a reorder) is still a child.
|
|
286
|
+
if (!(node instanceof HTMLElement) || node.parentElement === this) continue;
|
|
287
|
+
const page = this._state.pages.find((p) => p.content === node);
|
|
288
|
+
if (page === undefined) continue;
|
|
289
|
+
this._state.removePage(page.name);
|
|
290
|
+
clearPageMarks(node);
|
|
291
|
+
changed = true;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
if (!changed) return;
|
|
295
|
+
this._applyVisibility();
|
|
296
|
+
this._reflectName();
|
|
297
|
+
this._emitItemsChanged();
|
|
298
|
+
}
|
|
299
|
+
|
|
274
300
|
private _applyVisibility(): void {
|
|
275
301
|
const selected = this._state.visibleIndex;
|
|
276
302
|
this._state.pages.forEach((page, index) => {
|
|
@@ -299,3 +325,15 @@ export class AdwViewStack extends HTMLElement {
|
|
|
299
325
|
}
|
|
300
326
|
|
|
301
327
|
customElements.define('adw-view-stack', AdwViewStack);
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* What the stack wrote on a page's content, taken back once it is no longer a page: the
|
|
331
|
+
* class, the name, `active-view` and the `hidden` that is `gtk_widget_set_child_visible`
|
|
332
|
+
* (adw-view-stack.c:1138) — a child-visible flag the stack owns, which `gtk_widget_unparent`
|
|
333
|
+
* resets, not the widget's own visibility.
|
|
334
|
+
*/
|
|
335
|
+
function clearPageMarks(content: HTMLElement): void {
|
|
336
|
+
content.classList.remove('adw-view-stack-child', 'active-view');
|
|
337
|
+
delete content.dataset.name;
|
|
338
|
+
content.hidden = false;
|
|
339
|
+
}
|
|
@@ -25,6 +25,7 @@ import type { AdwViewStack } from './adw-view-stack.js';
|
|
|
25
25
|
import { applyDescription, applyIndicator, applySwitcherIcon } from './view-switcher-dom.js';
|
|
26
26
|
import { type GtkImage, createGtkImage } from './gtk-image.js';
|
|
27
27
|
import { attachRovingFocus } from './roving-focus.js';
|
|
28
|
+
import { WidgetElement } from '../widget-element.js';
|
|
28
29
|
|
|
29
30
|
/** The DOM nodes one bar button owns — the bar paints the derived model onto them. */
|
|
30
31
|
interface BarButtonNodes {
|
|
@@ -34,7 +35,7 @@ interface BarButtonNodes {
|
|
|
34
35
|
indicator: HTMLSpanElement;
|
|
35
36
|
}
|
|
36
37
|
|
|
37
|
-
export class AdwViewSwitcherBar extends
|
|
38
|
+
export class AdwViewSwitcherBar extends WidgetElement {
|
|
38
39
|
private readonly _barState = new ViewSwitcherBarState();
|
|
39
40
|
private _barEl!: HTMLDivElement;
|
|
40
41
|
private _nodes: BarButtonNodes[] = [];
|
|
@@ -57,8 +57,9 @@ import type { AdwSidebarItemSpec, AdwSidebarSectionSpec, SidebarItemFilter } fro
|
|
|
57
57
|
import { bindSlottedChildren } from '../slotted-children.js';
|
|
58
58
|
import type { AdwSidebar } from './adw-sidebar.js';
|
|
59
59
|
import type { AdwViewStack } from './adw-view-stack.js';
|
|
60
|
+
import { WidgetElement } from '../widget-element.js';
|
|
60
61
|
|
|
61
|
-
export class AdwViewSwitcherSidebar extends
|
|
62
|
+
export class AdwViewSwitcherSidebar extends WidgetElement {
|
|
62
63
|
private _sidebar!: AdwSidebar;
|
|
63
64
|
private _placeholderEl!: HTMLDivElement;
|
|
64
65
|
private _prefixEl!: HTMLDivElement;
|
|
@@ -56,6 +56,7 @@ import {
|
|
|
56
56
|
} from './view-switcher-dom.js';
|
|
57
57
|
import { type GtkImage, createGtkImage } from './gtk-image.js';
|
|
58
58
|
import { attachRovingFocus } from './roving-focus.js';
|
|
59
|
+
import { WidgetElement } from '../widget-element.js';
|
|
59
60
|
|
|
60
61
|
/** The DOM nodes one page owns — the switcher paints the derived model onto them. */
|
|
61
62
|
interface PageNodes {
|
|
@@ -75,9 +76,9 @@ interface PageNodes {
|
|
|
75
76
|
* switcher watches them with a `MutationObserver` instead — the DOM stand-in for
|
|
76
77
|
* the per-page `notify` C rebinds on.
|
|
77
78
|
*/
|
|
78
|
-
export class AdwViewSwitcherPage extends
|
|
79
|
+
export class AdwViewSwitcherPage extends WidgetElement {}
|
|
79
80
|
|
|
80
|
-
export class AdwViewSwitcher extends
|
|
81
|
+
export class AdwViewSwitcher extends WidgetElement {
|
|
81
82
|
/**
|
|
82
83
|
* The dwell timer, injectable so a test can hand in a clock and drive
|
|
83
84
|
* `VIEW_SWITCHER_DRAG_VECTORS` against the real element. Replace it before the
|
|
@@ -23,6 +23,15 @@ function requested(host: HTMLElement, name: string, fallback: number): number {
|
|
|
23
23
|
return Number.isFinite(value) && value >= 0 ? value : fallback;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
/**
|
|
27
|
+
* A maximized or fullscreen `Gtk.Window` ignores its default size and fills the monitor's work
|
|
28
|
+
* area (gtkwindow.c: the default size is only the RESTORED size). The page's work area is the
|
|
29
|
+
* frame's containing block, which the skin sizes from these two attributes.
|
|
30
|
+
*/
|
|
31
|
+
export function fillsContainingBlock(host: HTMLElement): boolean {
|
|
32
|
+
return ['maximized', 'fullscreened'].some((name) => host.hasAttribute(name) && host.getAttribute(name) !== 'false');
|
|
33
|
+
}
|
|
34
|
+
|
|
26
35
|
export class AdwWindowFeatures {
|
|
27
36
|
private _contentEl: HTMLDivElement | null = null;
|
|
28
37
|
private _breakpoints: AdwBreakpoint[] = [];
|
|
@@ -128,13 +137,16 @@ export class AdwWindowFeatures {
|
|
|
128
137
|
* size; `width-request`/`height-request` override it). `default-width/height` is only
|
|
129
138
|
* a default: an authored size is the box, and an absent one leaves the box to the
|
|
130
139
|
* stylesheet, which fills the viewport — a page has no window manager to pick a size.
|
|
140
|
+
* While maximized or fullscreened the default size is not applied at all: the stylesheet
|
|
141
|
+
* fills the containing block, and the minimum still holds.
|
|
131
142
|
*/
|
|
132
143
|
applySizeRequest(): void {
|
|
133
144
|
const host = this._host;
|
|
134
145
|
host.style.minWidth = `${requested(host, 'width-request', DEFAULT_WIDTH)}px`;
|
|
135
146
|
host.style.minHeight = `${requested(host, 'height-request', DEFAULT_HEIGHT)}px`;
|
|
136
|
-
const
|
|
137
|
-
const
|
|
147
|
+
const fills = fillsContainingBlock(host);
|
|
148
|
+
const width = fills ? null : (host.getAttribute('default-width') ?? host.getAttribute('width'));
|
|
149
|
+
const height = fills ? null : (host.getAttribute('default-height') ?? host.getAttribute('height'));
|
|
138
150
|
if (width) host.style.width = `${width}px`;
|
|
139
151
|
else host.style.removeProperty('width');
|
|
140
152
|
if (height) host.style.height = `${height}px`;
|
|
@@ -22,8 +22,9 @@
|
|
|
22
22
|
// title/subtitle state composed from @gjsify/adwaita-core.
|
|
23
23
|
|
|
24
24
|
import { WindowTitleState } from '@gjsify/adwaita-core';
|
|
25
|
+
import { WidgetElement } from '../widget-element.js';
|
|
25
26
|
|
|
26
|
-
export class AdwWindowTitle extends
|
|
27
|
+
export class AdwWindowTitle extends WidgetElement {
|
|
27
28
|
private _titleEl!: HTMLSpanElement;
|
|
28
29
|
private _subtitleEl!: HTMLSpanElement;
|
|
29
30
|
/** The headless title/subtitle pair + change detection (ADR 0004). */
|
|
@@ -41,6 +41,7 @@ import {
|
|
|
41
41
|
wrapPolicyFlexShrink,
|
|
42
42
|
type AdwLengthUnit,
|
|
43
43
|
} from '@gjsify/adwaita-core';
|
|
44
|
+
import { WidgetElement } from '../widget-element.js';
|
|
44
45
|
|
|
45
46
|
/**
|
|
46
47
|
* The attributes that carry a property, in the order the C installs them.
|
|
@@ -80,7 +81,7 @@ function alignToJustifyContent(align: number): string {
|
|
|
80
81
|
return 'flex-end';
|
|
81
82
|
}
|
|
82
83
|
|
|
83
|
-
export class AdwWrapBox extends
|
|
84
|
+
export class AdwWrapBox extends WidgetElement {
|
|
84
85
|
private _initialized = false;
|
|
85
86
|
|
|
86
87
|
static get observedAttributes() {
|
package/src/elements/checks.ts
CHANGED
|
@@ -37,7 +37,9 @@
|
|
|
37
37
|
// · The active member of a group cannot be clicked off: both the gesture handler and
|
|
38
38
|
// `real_activate` return early when the button is active AND has a group neighbour
|
|
39
39
|
// (:395-396, :617-622). `<adw-radio>` gets this from `RadioGroupState`, and
|
|
40
|
-
// `<gtk-check-button>`
|
|
40
|
+
// `<gtk-check-button>` from `group` / `set_group` over the core's `check-group.ts`. A
|
|
41
|
+
// grouped `<gtk-check-button>` draws the round radio (the `radio` attribute) and its
|
|
42
|
+
// input announces `role="radio"`.
|
|
41
43
|
//
|
|
42
44
|
// ONE PLACE THIS PORT DIVERGES, DELIBERATELY AND CITED. GTK does NOT clear
|
|
43
45
|
// `inconsistent` when the user activates the button — `real_activate` only flips
|
|
@@ -75,7 +77,8 @@
|
|
|
75
77
|
// A11Y: the inner input carries the role (native `checkbox` / `radio`) and an
|
|
76
78
|
// explicit `aria-checked` derived from {@link resolveCheckState}, so the
|
|
77
79
|
// indeterminate state announces as `mixed` for BOTH — HTML has a native mixed
|
|
78
|
-
// checkbox (`input.indeterminate`) but no mixed radio.
|
|
80
|
+
// checkbox (`input.indeterminate`) but no mixed radio. The host's `aria-label` /
|
|
81
|
+
// `aria-description` (a `.blp`'s `accessibility { }`) are copied onto it too.
|
|
79
82
|
//
|
|
80
83
|
// Reference: refs/gtk/gtk/gtkcheckbutton.c:99-112,395-426,617-628,647-714,773-774,849-886,925-974
|
|
81
84
|
// Reference: refs/libadwaita/src/stylesheet/widgets/_checks.scss
|
|
@@ -85,9 +88,18 @@
|
|
|
85
88
|
// Copyright (c) 2025 csm (adwaita-web). MIT License.
|
|
86
89
|
// Modifications: Implemented as Web Components for @gjsify/adwaita-web.
|
|
87
90
|
|
|
88
|
-
import {
|
|
91
|
+
import {
|
|
92
|
+
RadioGroupState,
|
|
93
|
+
checkActivationFlips,
|
|
94
|
+
checkGroupNeighbours,
|
|
95
|
+
isRadioCheck,
|
|
96
|
+
resolveCheckState,
|
|
97
|
+
setCheckGroup,
|
|
98
|
+
} from '@gjsify/adwaita-core';
|
|
89
99
|
|
|
100
|
+
import { FORWARDED_ARIA, forwardAccessibleName } from '../accessible.js';
|
|
90
101
|
import type { DispatchedSignals } from '../signals.js';
|
|
102
|
+
import { WidgetElement } from '../widget-element.js';
|
|
91
103
|
|
|
92
104
|
/**
|
|
93
105
|
* The document's radio groups. ONE registry, as global as a bare
|
|
@@ -104,7 +116,7 @@ const radioGroups = new RadioGroupState();
|
|
|
104
116
|
* `.adw-check-indicator` and `.adw-check-label`, which are the Adwaita SKIN, and the
|
|
105
117
|
* skin is not what the tag names. It is also not a widget — nothing registers it.
|
|
106
118
|
*/
|
|
107
|
-
abstract class AdwCheckBase extends
|
|
119
|
+
abstract class AdwCheckBase extends WidgetElement {
|
|
108
120
|
protected _input!: HTMLInputElement;
|
|
109
121
|
protected _indicator!: HTMLSpanElement;
|
|
110
122
|
protected _label!: HTMLSpanElement;
|
|
@@ -240,6 +252,7 @@ abstract class AdwCheckBase extends HTMLElement {
|
|
|
240
252
|
this._input.setAttribute('aria-checked', state === 'indeterminate' ? 'mixed' : String(state === 'checked'));
|
|
241
253
|
this._input.disabled = this.disabled;
|
|
242
254
|
this._label.hidden = this._label.childNodes.length === 0;
|
|
255
|
+
forwardAccessibleName(this, this._input);
|
|
243
256
|
}
|
|
244
257
|
}
|
|
245
258
|
|
|
@@ -252,14 +265,80 @@ export class GtkCheckButton extends AdwCheckBase {
|
|
|
252
265
|
};
|
|
253
266
|
|
|
254
267
|
static get observedAttributes() {
|
|
255
|
-
return ['checked', 'active', 'indeterminate', 'disabled', 'label'];
|
|
268
|
+
return ['checked', 'active', 'indeterminate', 'disabled', 'label', 'group', ...FORWARDED_ARIA];
|
|
256
269
|
}
|
|
257
270
|
|
|
258
271
|
protected get inputType(): 'checkbox' {
|
|
259
272
|
return 'checkbox';
|
|
260
273
|
}
|
|
261
274
|
|
|
275
|
+
/**
|
|
276
|
+
* `Gtk.CheckButton:group`, WRITE-ONLY as in GTK (`G_PARAM_WRITABLE`, gtkcheckbutton.c:665-668):
|
|
277
|
+
* another check button, or its id as a projected `.blp` writes it, or `null` to leave.
|
|
278
|
+
*/
|
|
279
|
+
set group(value: GtkCheckButton | string | null) {
|
|
280
|
+
if (typeof value === 'string') {
|
|
281
|
+
this.setAttribute('group', value);
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
this.set_group(value);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/** `gtk_check_button_set_group`. */
|
|
288
|
+
set_group(group: GtkCheckButton | null): void {
|
|
289
|
+
setCheckGroup(this, group);
|
|
290
|
+
this.render();
|
|
291
|
+
group?.render();
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
get_active(): boolean {
|
|
295
|
+
return this.checked;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
set_active(active: boolean): void {
|
|
299
|
+
this.checked = active;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
attributeChangedCallback(name: string) {
|
|
303
|
+
// `set_active (TRUE)` deactivates every member of the group (gtkcheckbutton.c:955-968).
|
|
304
|
+
if (name === 'checked' && this.checked) {
|
|
305
|
+
for (const other of checkGroupNeighbours(this)) other.checked = false;
|
|
306
|
+
}
|
|
307
|
+
if (name === 'group' && this.isConnected) this._resolveGroup();
|
|
308
|
+
super.attributeChangedCallback(name);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
protected onConnected(): void {
|
|
312
|
+
this._resolveGroup();
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/** The `group` attribute names a check button by id, looked up once the tree is in a document. */
|
|
316
|
+
private _resolveGroup(): void {
|
|
317
|
+
const id = this.getAttribute('group');
|
|
318
|
+
if (id === null) return;
|
|
319
|
+
const root = this.getRootNode() as Document | ShadowRoot;
|
|
320
|
+
const found = root.getElementById?.(id) ?? document.getElementById(id);
|
|
321
|
+
if (!(found instanceof GtkCheckButton)) {
|
|
322
|
+
throw new Error(`gtk-check-button group="${id}" names no gtk-check-button in this document`);
|
|
323
|
+
}
|
|
324
|
+
this.set_group(found);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
protected render(): void {
|
|
328
|
+
if (this._input === undefined) return;
|
|
329
|
+
super.render();
|
|
330
|
+
const radio = isRadioCheck(this);
|
|
331
|
+
this.toggleAttribute('radio', radio);
|
|
332
|
+
if (radio) this._input.setAttribute('role', 'radio');
|
|
333
|
+
else this._input.removeAttribute('role');
|
|
334
|
+
}
|
|
335
|
+
|
|
262
336
|
protected activate(): void {
|
|
337
|
+
// The active member of a group cannot be activated off (gtkcheckbutton.c:395-396, :617-622).
|
|
338
|
+
if (!checkActivationFlips(this, this.checked)) {
|
|
339
|
+
this.render();
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
263
342
|
// HTML's pre-click activation steps clear `indeterminate` before the toggle, so a
|
|
264
343
|
// user can always reach a definite state. GTK does NOT: `gtk_check_button_real_activate`
|
|
265
344
|
// only flips `active` (gtkcheckbutton.c:617-628) and says turning the inconsistent
|
|
@@ -274,7 +353,7 @@ export class AdwRadio extends AdwCheckBase {
|
|
|
274
353
|
private _unsubscribe: (() => void) | null = null;
|
|
275
354
|
|
|
276
355
|
static get observedAttributes() {
|
|
277
|
-
return ['checked', 'indeterminate', 'disabled', 'label', 'name', 'value'];
|
|
356
|
+
return ['checked', 'indeterminate', 'disabled', 'label', 'name', 'value', ...FORWARDED_ARIA];
|
|
278
357
|
}
|
|
279
358
|
|
|
280
359
|
protected get inputType(): 'radio' {
|
|
@@ -20,8 +20,9 @@
|
|
|
20
20
|
// Copyright (c) The GTK Team. LGPLv2.1+.
|
|
21
21
|
|
|
22
22
|
import { bindSlottedChildren } from '../slotted-children.js';
|
|
23
|
+
import { WidgetElement } from '../widget-element.js';
|
|
23
24
|
|
|
24
|
-
export class GtkActionBar extends
|
|
25
|
+
export class GtkActionBar extends WidgetElement {
|
|
25
26
|
private _initialized = false;
|
|
26
27
|
private _startEl: HTMLDivElement | null = null;
|
|
27
28
|
private _centerEl: HTMLDivElement | null = null;
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
//
|
|
17
17
|
// THE `win.` / `app.` PREFIXES. `GtkApplicationWindow` exports window actions under `win.` and
|
|
18
18
|
// application-wide ones under `app.` (:48-56), and any `GtkActionable` inside the window can
|
|
19
|
-
// activate either. `
|
|
19
|
+
// activate either. `installActionMap` installs the `Gio.ActionMap` half on the prototype
|
|
20
20
|
// (`add_action`, `lookup_action`, `remove_action`, the `win.` registry); the `Gio.ActionGroup`
|
|
21
21
|
// half stays off because a window's `activate_action` is the widget's. Plain `<gtk-window>` has
|
|
22
22
|
// no ActionMap. What this element adds over it is that map, the strip and the property that shows it.
|
|
@@ -26,17 +26,12 @@
|
|
|
26
26
|
// Copyright (c) The GTK Team. LGPLv2.1+.
|
|
27
27
|
// Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
|
|
28
28
|
|
|
29
|
-
import type
|
|
30
|
-
import type { GtkApplication } from '../application.js';
|
|
29
|
+
import { installActionMap, type ActionLike } from '@gjsify/adwaita-core';
|
|
31
30
|
import type { DispatchedSignals } from '../signals.js';
|
|
32
31
|
import type { AdwSlot } from '../slotted-children.js';
|
|
33
32
|
import { GtkWindow } from './gtk-window.js';
|
|
34
|
-
import { defineWindowApplication } from '../application.js';
|
|
35
33
|
|
|
36
34
|
export class GtkApplicationWindow extends GtkWindow {
|
|
37
|
-
/** `Gtk.Window:application`: setting it is `add_window` (ADR 0098), set by `defineWindowApplication`. */
|
|
38
|
-
declare application: GtkApplication | null;
|
|
39
|
-
|
|
40
35
|
/** `Gio.ActionMap.add_action`: installed by `installActionMap`; the action is reachable as `win.<name>`. */
|
|
41
36
|
declare add_action: (action: ActionLike) => void;
|
|
42
37
|
/** `Gio.ActionMap.lookup_action`: the window's own action, or `null`. */
|
|
@@ -127,4 +122,4 @@ export class GtkApplicationWindow extends GtkWindow {
|
|
|
127
122
|
|
|
128
123
|
customElements.define('gtk-application-window', GtkApplicationWindow);
|
|
129
124
|
|
|
130
|
-
|
|
125
|
+
installActionMap(GtkApplicationWindow.prototype);
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
import { glibClamp, labelYalignAlignItems } from '@gjsify/adwaita-core';
|
|
39
39
|
|
|
40
40
|
import { bindSlottedChildren } from '../slotted-children.js';
|
|
41
|
+
import { WidgetElement } from '../widget-element.js';
|
|
41
42
|
|
|
42
43
|
/** `Gtk.AspectFrame:ratio`'s pspec range and default (gtkaspectframe.c:124-125, :172-175). */
|
|
43
44
|
const RATIO_MIN = 0.0001;
|
|
@@ -58,7 +59,7 @@ function normalizeRatio(value: string | null): number {
|
|
|
58
59
|
return Number.isFinite(parsed) ? glibClamp(parsed, RATIO_MIN, RATIO_MAX) : RATIO_DEFAULT;
|
|
59
60
|
}
|
|
60
61
|
|
|
61
|
-
export class GtkAspectFrame extends
|
|
62
|
+
export class GtkAspectFrame extends WidgetElement {
|
|
62
63
|
static get observedAttributes() {
|
|
63
64
|
return ['ratio', 'xalign', 'yalign', 'obey-child'];
|
|
64
65
|
}
|