@gjsify/adwaita-web 0.54.0 → 0.56.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/dist/adwaita-web.css +8146 -3011
- package/dist/adwaita-web.css.map +1 -1
- package/lib/types/adw-application-window.spec.d.ts +1 -0
- package/lib/types/adw-bin.spec.d.ts +1 -0
- package/lib/types/adw-breakpoint-bin.spec.d.ts +1 -0
- package/lib/types/adw-clamp-scrollable.spec.d.ts +1 -0
- package/lib/types/adw-multi-layout-view.spec.d.ts +1 -0
- package/lib/types/adw-preferences-row.spec.d.ts +1 -0
- package/lib/types/adw-shortcuts.spec.d.ts +1 -0
- package/lib/types/adw-status-page.spec.d.ts +1 -0
- package/lib/types/adw-tab-bar.spec.d.ts +1 -0
- package/lib/types/adw-tab-button.spec.d.ts +1 -0
- package/lib/types/adw-tab-overview.spec.d.ts +1 -0
- package/lib/types/adw-view-switcher-sidebar.spec.d.ts +1 -0
- package/lib/types/adw-window.spec.d.ts +1 -0
- package/lib/types/attributes.d.ts +19 -0
- package/lib/types/breakpoints.d.ts +14 -3
- package/lib/types/construct-vectors.spec.d.ts +1 -0
- package/lib/types/elements/adw-action-row.d.ts +4 -0
- package/lib/types/elements/adw-application-window.d.ts +27 -0
- package/lib/types/elements/adw-bin.d.ts +17 -0
- package/lib/types/elements/adw-breakpoint-bin.d.ts +67 -0
- package/lib/types/elements/adw-clamp-scrollable.d.ts +38 -0
- package/lib/types/elements/adw-combo-row.d.ts +4 -0
- package/lib/types/elements/adw-dialog.d.ts +10 -0
- package/lib/types/elements/adw-entry-row.d.ts +6 -0
- package/lib/types/elements/adw-expander-row.d.ts +2 -0
- package/lib/types/elements/adw-header-bar.d.ts +6 -0
- package/lib/types/elements/adw-layout-slot.d.ts +19 -0
- package/lib/types/elements/adw-multi-layout-view.d.ts +101 -0
- package/lib/types/elements/adw-overlay-split-view.d.ts +13 -0
- package/lib/types/elements/adw-preferences-row.d.ts +31 -0
- package/lib/types/elements/adw-shortcuts-dialog.d.ts +13 -0
- package/lib/types/elements/adw-shortcuts-item.d.ts +36 -0
- package/lib/types/elements/adw-shortcuts-section.d.ts +14 -0
- package/lib/types/elements/adw-sidebar.d.ts +8 -2
- package/lib/types/elements/adw-spin-row.d.ts +6 -0
- package/lib/types/elements/adw-switch-row.d.ts +7 -0
- package/lib/types/elements/adw-tab-bar.d.ts +108 -0
- package/lib/types/elements/adw-tab-button.d.ts +32 -0
- package/lib/types/elements/adw-tab-overview.d.ts +199 -0
- package/lib/types/elements/adw-tab-view.d.ts +19 -23
- package/lib/types/elements/adw-toggle-group.d.ts +17 -0
- package/lib/types/elements/adw-view-switcher-sidebar.d.ts +84 -0
- package/lib/types/elements/adw-window.d.ts +40 -0
- package/lib/types/elements/gtk-about-dialog.d.ts +146 -0
- package/lib/types/elements/gtk-application-window.d.ts +34 -0
- package/lib/types/elements/gtk-aspect-frame.d.ts +27 -0
- package/lib/types/elements/gtk-button.d.ts +9 -0
- package/lib/types/elements/gtk-calendar.d.ts +159 -0
- package/lib/types/elements/gtk-center-box.d.ts +39 -0
- package/lib/types/elements/gtk-color-dialog-button.d.ts +69 -0
- package/lib/types/elements/gtk-column-view.d.ts +50 -0
- package/lib/types/elements/gtk-drag-icon.d.ts +78 -0
- package/lib/types/elements/gtk-drawing-area.d.ts +95 -0
- package/lib/types/elements/gtk-editable-label.d.ts +33 -0
- package/lib/types/elements/gtk-emoji-chooser.d.ts +84 -0
- package/lib/types/elements/gtk-entry.d.ts +20 -1
- package/lib/types/elements/gtk-expander.d.ts +49 -0
- package/lib/types/elements/gtk-fixed.d.ts +13 -0
- package/lib/types/elements/gtk-flow-box-child.d.ts +14 -0
- package/lib/types/elements/gtk-flow-box.d.ts +87 -0
- package/lib/types/elements/gtk-font-dialog-button.d.ts +83 -0
- package/lib/types/elements/gtk-frame.d.ts +24 -0
- package/lib/types/elements/gtk-gl-area.d.ts +136 -0
- package/lib/types/elements/gtk-graphics-offload.d.ts +24 -0
- package/lib/types/elements/gtk-grid-view.d.ts +39 -0
- package/lib/types/elements/gtk-grid.d.ts +27 -0
- package/lib/types/elements/gtk-header-bar.d.ts +60 -0
- package/lib/types/elements/gtk-inscription.d.ts +64 -0
- package/lib/types/elements/gtk-label.d.ts +3 -0
- package/lib/types/elements/gtk-level-bar.d.ts +59 -0
- package/lib/types/elements/gtk-link-button.d.ts +29 -0
- package/lib/types/elements/gtk-list-box-row.d.ts +54 -0
- package/lib/types/elements/gtk-list-box.d.ts +100 -0
- package/lib/types/elements/gtk-list-view.d.ts +73 -0
- package/lib/types/elements/gtk-media-controls.d.ts +142 -0
- package/lib/types/elements/gtk-notebook.d.ts +148 -0
- package/lib/types/elements/gtk-overlay.d.ts +22 -0
- package/lib/types/elements/gtk-page-setup-unix-dialog.d.ts +87 -0
- package/lib/types/elements/gtk-paned.d.ts +121 -0
- package/lib/types/elements/gtk-password-entry.d.ts +27 -0
- package/lib/types/elements/gtk-picture.d.ts +66 -0
- package/lib/types/elements/gtk-popover-bin.d.ts +82 -0
- package/lib/types/elements/gtk-popover-menu-bar.d.ts +66 -0
- package/lib/types/elements/gtk-popover-menu.d.ts +83 -0
- package/lib/types/elements/gtk-popover.d.ts +28 -3
- package/lib/types/elements/gtk-print-unix-dialog.d.ts +167 -0
- package/lib/types/elements/gtk-revealer.d.ts +55 -0
- package/lib/types/elements/gtk-scale-button.d.ts +59 -0
- package/lib/types/elements/gtk-scale.d.ts +98 -0
- package/lib/types/elements/gtk-scrollbar.d.ts +124 -0
- package/lib/types/elements/gtk-scrolled-window.d.ts +129 -0
- package/lib/types/elements/gtk-search-bar.d.ts +39 -0
- package/lib/types/elements/gtk-search-entry.d.ts +27 -0
- package/lib/types/elements/gtk-separator.d.ts +10 -0
- package/lib/types/elements/gtk-spin-button.d.ts +94 -0
- package/lib/types/elements/gtk-spinner.d.ts +14 -0
- package/lib/types/elements/gtk-stack-sidebar.d.ts +43 -0
- package/lib/types/elements/gtk-stack-switcher.d.ts +58 -0
- package/lib/types/elements/gtk-stack.d.ts +154 -0
- package/lib/types/elements/gtk-switch.d.ts +4 -1
- package/lib/types/elements/gtk-text-view.d.ts +62 -0
- package/lib/types/elements/gtk-text.d.ts +45 -0
- package/lib/types/elements/gtk-toggle-button.d.ts +45 -0
- package/lib/types/elements/gtk-tree-expander.d.ts +38 -0
- package/lib/types/elements/gtk-video.d.ts +97 -0
- package/lib/types/elements/gtk-viewport.d.ts +84 -0
- package/lib/types/elements/gtk-window-controls.d.ts +80 -0
- package/lib/types/elements/gtk-window-handle.d.ts +39 -0
- package/lib/types/elements/gtk-window.d.ts +103 -0
- package/lib/types/elements/justification.d.ts +2 -0
- package/lib/types/elements/popover-menu.d.ts +18 -0
- package/lib/types/elements/roving-focus.d.ts +29 -1
- package/lib/types/emoji-data.d.ts +38 -0
- package/lib/types/font-description.d.ts +96 -0
- package/lib/types/gtk-about-dialog.spec.d.ts +1 -0
- package/lib/types/gtk-action-bar.spec.d.ts +1 -0
- package/lib/types/gtk-application-window.spec.d.ts +1 -0
- package/lib/types/gtk-aspect-frame.spec.d.ts +1 -0
- package/lib/types/gtk-calendar.spec.d.ts +1 -0
- package/lib/types/gtk-center-box.spec.d.ts +1 -0
- package/lib/types/gtk-color-dialog-button.spec.d.ts +1 -0
- package/lib/types/gtk-column-view.spec.d.ts +1 -0
- package/lib/types/gtk-drag-icon.spec.d.ts +1 -0
- package/lib/types/gtk-drawing-area.spec.d.ts +1 -0
- package/lib/types/gtk-editable-label.spec.d.ts +1 -0
- package/lib/types/gtk-emoji-chooser.spec.d.ts +1 -0
- package/lib/types/gtk-expander.spec.d.ts +1 -0
- package/lib/types/gtk-fixed.spec.d.ts +1 -0
- package/lib/types/gtk-flow-box.spec.d.ts +1 -0
- package/lib/types/gtk-font-dialog-button.spec.d.ts +1 -0
- package/lib/types/gtk-frame.spec.d.ts +1 -0
- package/lib/types/gtk-gl-area.spec.d.ts +1 -0
- package/lib/types/gtk-graphics-offload.spec.d.ts +1 -0
- package/lib/types/gtk-grid-view.spec.d.ts +1 -0
- package/lib/types/gtk-grid.spec.d.ts +1 -0
- package/lib/types/gtk-header-bar.spec.d.ts +1 -0
- package/lib/types/gtk-inscription.spec.d.ts +1 -0
- package/lib/types/gtk-level-bar.spec.d.ts +1 -0
- package/lib/types/gtk-link-button.spec.d.ts +1 -0
- package/lib/types/gtk-list-box.spec.d.ts +1 -0
- package/lib/types/gtk-list-view.spec.d.ts +1 -0
- package/lib/types/gtk-media-controls.spec.d.ts +1 -0
- package/lib/types/gtk-notebook.spec.d.ts +1 -0
- package/lib/types/gtk-overlay.spec.d.ts +1 -0
- package/lib/types/gtk-paned.spec.d.ts +1 -0
- package/lib/types/gtk-password-entry.spec.d.ts +1 -0
- package/lib/types/gtk-picture.spec.d.ts +1 -0
- package/lib/types/gtk-popover-bin.spec.d.ts +1 -0
- package/lib/types/gtk-popover-menu-bar.spec.d.ts +1 -0
- package/lib/types/gtk-popover-menu.spec.d.ts +1 -0
- package/lib/types/gtk-popover-role.spec.d.ts +1 -0
- package/lib/types/gtk-popover.spec.d.ts +1 -0
- package/lib/types/gtk-print-dialogs.spec.d.ts +1 -0
- package/lib/types/gtk-revealer.spec.d.ts +1 -0
- package/lib/types/gtk-scale-button.spec.d.ts +1 -0
- package/lib/types/gtk-scale.spec.d.ts +1 -0
- package/lib/types/gtk-scrollbar.spec.d.ts +1 -0
- package/lib/types/gtk-scrolled-window.spec.d.ts +1 -0
- package/lib/types/gtk-search-bar.spec.d.ts +1 -0
- package/lib/types/gtk-search-entry.spec.d.ts +1 -0
- package/lib/types/gtk-separator.spec.d.ts +1 -0
- package/lib/types/gtk-spin-button.spec.d.ts +1 -0
- package/lib/types/gtk-spinner.spec.d.ts +1 -0
- package/lib/types/gtk-stack-sidebar.spec.d.ts +1 -0
- package/lib/types/gtk-stack-switcher.spec.d.ts +1 -0
- package/lib/types/gtk-stack.spec.d.ts +1 -0
- package/lib/types/gtk-text-view.spec.d.ts +1 -0
- package/lib/types/gtk-text.spec.d.ts +1 -0
- package/lib/types/gtk-toggle-button.spec.d.ts +1 -0
- package/lib/types/gtk-tree-expander.spec.d.ts +1 -0
- package/lib/types/gtk-video.spec.d.ts +1 -0
- package/lib/types/gtk-viewport.spec.d.ts +1 -0
- package/lib/types/gtk-window-controls.spec.d.ts +1 -0
- package/lib/types/gtk-window-handle.spec.d.ts +1 -0
- package/lib/types/gtk-window.spec.d.ts +1 -0
- package/lib/types/index.d.ts +4 -1
- package/lib/types/list-view-dom.d.ts +44 -0
- package/lib/types/namespace/adw.d.ts +12 -0
- package/lib/types/namespace/gtk.d.ts +61 -0
- package/lib/types/page-setup.d.ts +100 -0
- package/lib/types/row-line-clamp.d.ts +20 -0
- package/lib/types/row-tooltip.d.ts +8 -0
- package/lib/types/row-tooltip.spec.d.ts +1 -0
- package/lib/types/scroll-shading.d.ts +15 -1
- package/lib/types/shared-tree-builder.d.ts +75 -17
- package/lib/types/shared-tree-mount.spec.d.ts +1 -0
- package/lib/types/signals.d.ts +4 -0
- package/lib/types/styles.generated.d.ts +1 -1
- package/lib/types/tab-chip.d.ts +73 -0
- package/lib/types/template-classes.d.ts +11 -0
- package/lib/types/widget-size.spec.d.ts +1 -0
- package/package.json +12 -8
- package/scss/_action_row.scss +41 -17
- package/scss/_application_window.scss +26 -0
- package/scss/_aspect_frame.scss +25 -0
- package/scss/_bin.scss +26 -0
- package/scss/_button.scss +45 -0
- package/scss/_button_row.scss +5 -0
- package/scss/_calendar.scss +176 -0
- package/scss/_center_box.scss +25 -0
- package/scss/_checks.scss +6 -1
- package/scss/_clamp_scrollable.scss +28 -0
- package/scss/_color_button.scss +67 -0
- package/scss/_column_view.scss +126 -0
- package/scss/_drag_icon.scss +55 -0
- package/scss/_drawing.scss +85 -0
- package/scss/_emoji_chooser.scss +213 -0
- package/scss/_entry.scss +13 -5
- package/scss/_entry_row.scss +1 -1
- package/scss/_expander.scss +113 -0
- package/scss/_expander_row.scss +36 -3
- package/scss/_fixed.scss +29 -0
- package/scss/_flow_box.scss +94 -0
- package/scss/_font_button.scss +63 -0
- package/scss/_frame.scss +41 -0
- package/scss/_grid.scss +19 -0
- package/scss/_grid_view.scss +46 -0
- package/scss/_gtk_about_dialog.scss +186 -0
- package/scss/_headerbar.scss +134 -1
- package/scss/_icons.generated.scss +186 -0
- package/scss/_inscription.scss +125 -0
- package/scss/_level_bar.scss +190 -0
- package/scss/_link.scss +82 -0
- package/scss/_list_box.scss +88 -0
- package/scss/_list_view.scss +96 -0
- package/scss/_media_controls.scss +139 -0
- package/scss/_overlay.scss +68 -0
- package/scss/_paned.scss +130 -0
- package/scss/_password_entry.scss +83 -0
- package/scss/_picture.scss +80 -0
- package/scss/_popover_bin.scss +53 -0
- package/scss/_popover_menu_bar.scss +104 -0
- package/scss/_preferences_row.scss +60 -0
- package/scss/_print_dialogs.scss +328 -0
- package/scss/_reset.scss +21 -19
- package/scss/_revealer.scss +37 -0
- package/scss/_row.scss +36 -5
- package/scss/_scale.scss +298 -0
- package/scss/_scale_button.scss +167 -0
- package/scss/_scrollbar.scss +230 -0
- package/scss/_scrolled_window.scss +131 -0
- package/scss/_search_bar.scss +118 -0
- package/scss/_search_entry.scss +86 -0
- package/scss/_separator.scss +44 -0
- package/scss/_shortcuts_dialog.scss +100 -0
- package/scss/_spin_button.scss +172 -0
- package/scss/_spin_row.scss +56 -8
- package/scss/_spinner.scss +85 -4
- package/scss/_stack.scss +729 -0
- package/scss/_status_page.scss +1 -1
- package/scss/_switch.scss +13 -5
- package/scss/_switch_row.scss +10 -0
- package/scss/_tab_bar.scss +317 -0
- package/scss/_tab_button.scss +98 -0
- package/scss/_tab_overview.scss +483 -0
- package/scss/_text.scss +182 -0
- package/scss/_theme.scss +1 -1
- package/scss/_toggle_group.scss +28 -0
- package/scss/_tree_expander.scss +62 -0
- package/scss/_variables.scss +1 -1
- package/scss/_video.scss +146 -0
- package/scss/_view_switcher_sidebar.scss +112 -0
- package/scss/_viewport.scss +50 -0
- package/scss/_widget.scss +14 -3
- package/scss/_window.scss +131 -2
- package/scss/_window_handle.scss +20 -0
- package/scss/adwaita-skin.scss +109 -0
- package/src/adw-action-rows.spec.ts +331 -0
- package/src/adw-application-window.spec.ts +118 -0
- package/src/adw-bin.spec.ts +75 -0
- package/src/adw-breakpoint-bin.spec.ts +324 -0
- package/src/adw-clamp-scrollable.spec.ts +189 -0
- package/src/adw-header-bar.spec.ts +18 -0
- package/src/adw-multi-layout-view.spec.ts +243 -0
- package/src/adw-preferences-row.spec.ts +164 -0
- package/src/adw-row-state.spec.ts +142 -0
- package/src/adw-shortcuts.spec.ts +155 -0
- package/src/adw-status-page.spec.ts +124 -0
- package/src/adw-tab-bar.spec.ts +287 -0
- package/src/adw-tab-button.spec.ts +101 -0
- package/src/adw-tab-overview.spec.ts +443 -0
- package/src/adw-view-switcher-sidebar.spec.ts +281 -0
- package/src/adw-window.spec.ts +129 -0
- package/src/attributes.ts +52 -0
- package/src/breakpoints.ts +25 -8
- package/src/capabilities.d.mts +3 -0
- package/src/capabilities.mjs +21 -0
- package/src/connect-lifecycle.spec.ts +12 -0
- package/src/construct-vectors.spec.ts +175 -0
- package/src/elements/adw-action-row.ts +31 -2
- package/src/elements/adw-alert-dialog.ts +4 -1
- package/src/elements/adw-application-window.ts +154 -0
- package/src/elements/adw-bin.ts +101 -0
- package/src/elements/adw-breakpoint-bin.ts +287 -0
- package/src/elements/adw-button-row.ts +7 -1
- package/src/elements/adw-clamp-scrollable.ts +207 -0
- package/src/elements/adw-combo-row.ts +26 -1
- package/src/elements/adw-dialog.ts +19 -0
- package/src/elements/adw-entry-row.ts +22 -12
- package/src/elements/adw-expander-row.ts +34 -1
- package/src/elements/adw-header-bar.ts +18 -4
- package/src/elements/adw-layout-slot.ts +95 -0
- package/src/elements/adw-multi-layout-view.ts +326 -0
- package/src/elements/adw-overlay-split-view.ts +29 -6
- package/src/elements/adw-preferences-row.ts +153 -0
- package/src/elements/adw-shortcuts-dialog.ts +52 -0
- package/src/elements/adw-shortcuts-item.ts +171 -0
- package/src/elements/adw-shortcuts-section.ts +86 -0
- package/src/elements/adw-sidebar.ts +74 -7
- package/src/elements/adw-spin-row.ts +37 -2
- package/src/elements/adw-status-page.ts +10 -2
- package/src/elements/adw-switch-row.ts +53 -2
- package/src/elements/adw-tab-bar.ts +529 -0
- package/src/elements/adw-tab-button.ts +194 -0
- package/src/elements/adw-tab-overview.ts +1011 -0
- package/src/elements/adw-tab-view.ts +66 -145
- package/src/elements/adw-toggle-group.ts +138 -14
- package/src/elements/adw-view-stack.ts +18 -0
- package/src/elements/adw-view-switcher-sidebar.ts +332 -0
- package/src/elements/adw-window.ts +190 -11
- package/src/elements/checks.ts +35 -8
- package/src/elements/gtk-about-dialog.ts +811 -0
- package/src/elements/gtk-application-window.ts +108 -0
- package/src/elements/gtk-aspect-frame.ts +160 -0
- package/src/elements/gtk-button.ts +12 -0
- package/src/elements/gtk-calendar.ts +757 -0
- package/src/elements/gtk-center-box.ts +184 -0
- package/src/elements/gtk-color-dialog-button.ts +278 -0
- package/src/elements/gtk-column-view.ts +320 -0
- package/src/elements/gtk-drag-icon.ts +257 -0
- package/src/elements/gtk-drawing-area.ts +303 -0
- package/src/elements/gtk-editable-label.ts +204 -0
- package/src/elements/gtk-emoji-chooser.ts +542 -0
- package/src/elements/gtk-entry.ts +39 -5
- package/src/elements/gtk-expander.ts +301 -0
- package/src/elements/gtk-fixed.ts +99 -0
- package/src/elements/gtk-flow-box-child.ts +68 -0
- package/src/elements/gtk-flow-box.ts +480 -0
- package/src/elements/gtk-font-dialog-button.ts +432 -0
- package/src/elements/gtk-frame.ts +174 -0
- package/src/elements/gtk-gl-area.ts +476 -0
- package/src/elements/gtk-graphics-offload.ts +130 -0
- package/src/elements/gtk-grid-view.ts +168 -0
- package/src/elements/gtk-grid.ts +127 -0
- package/src/elements/gtk-header-bar.ts +273 -0
- package/src/elements/gtk-inscription.ts +387 -0
- package/src/elements/gtk-label.ts +19 -11
- package/src/elements/gtk-level-bar.ts +323 -0
- package/src/elements/gtk-link-button.ts +138 -0
- package/src/elements/gtk-list-box-row.ts +195 -0
- package/src/elements/gtk-list-box.ts +413 -0
- package/src/elements/gtk-list-view.ts +370 -0
- package/src/elements/gtk-media-controls.ts +509 -0
- package/src/elements/gtk-notebook.ts +664 -0
- package/src/elements/gtk-overlay.ts +149 -0
- package/src/elements/gtk-page-setup-unix-dialog.ts +420 -0
- package/src/elements/gtk-paned.ts +597 -0
- package/src/elements/gtk-password-entry.ts +170 -0
- package/src/elements/gtk-picture.ts +254 -0
- package/src/elements/gtk-popover-bin.ts +332 -0
- package/src/elements/gtk-popover-menu-bar.ts +355 -0
- package/src/elements/gtk-popover-menu.ts +339 -0
- package/src/elements/gtk-popover.ts +92 -10
- package/src/elements/gtk-print-unix-dialog.ts +989 -0
- package/src/elements/gtk-progress-bar.ts +24 -11
- package/src/elements/gtk-revealer.ts +406 -0
- package/src/elements/gtk-scale-button.ts +358 -0
- package/src/elements/gtk-scale.ts +492 -0
- package/src/elements/gtk-scrollbar.ts +528 -0
- package/src/elements/gtk-scrolled-window.ts +653 -0
- package/src/elements/gtk-search-bar.ts +200 -0
- package/src/elements/gtk-search-entry.ts +172 -0
- package/src/elements/gtk-separator.ts +52 -0
- package/src/elements/gtk-spin-button.ts +475 -0
- package/src/elements/gtk-spinner.ts +126 -0
- package/src/elements/gtk-stack-sidebar.ts +212 -0
- package/src/elements/gtk-stack-switcher.ts +279 -0
- package/src/elements/gtk-stack.ts +748 -0
- package/src/elements/gtk-switch.ts +52 -19
- package/src/elements/gtk-text-view.ts +290 -0
- package/src/elements/gtk-text.ts +219 -0
- package/src/elements/gtk-toggle-button.ts +239 -0
- package/src/elements/gtk-tree-expander.ts +243 -0
- package/src/elements/gtk-video.ts +423 -0
- package/src/elements/gtk-viewport.ts +277 -0
- package/src/elements/gtk-window-controls.ts +341 -0
- package/src/elements/gtk-window-handle.ts +221 -0
- package/src/elements/gtk-window.ts +372 -0
- package/src/elements/justification.ts +24 -0
- package/src/elements/popover-menu.ts +24 -0
- package/src/elements/roving-focus.ts +53 -21
- package/src/emoji-data.ts +577 -0
- package/src/entry-rows.spec.ts +31 -0
- package/src/font-description.ts +238 -0
- package/src/gtk-about-dialog.spec.ts +250 -0
- package/src/gtk-action-bar.spec.ts +89 -0
- package/src/gtk-application-window.spec.ts +107 -0
- package/src/gtk-aspect-frame.spec.ts +114 -0
- package/src/gtk-calendar.spec.ts +589 -0
- package/src/gtk-center-box.spec.ts +125 -0
- package/src/gtk-color-dialog-button.spec.ts +141 -0
- package/src/gtk-column-view.spec.ts +154 -0
- package/src/gtk-drag-icon.spec.ts +190 -0
- package/src/gtk-drawing-area.spec.ts +211 -0
- package/src/gtk-editable-label.spec.ts +190 -0
- package/src/gtk-emoji-chooser.spec.ts +173 -0
- package/src/gtk-entry.spec.ts +23 -0
- package/src/gtk-expander.spec.ts +170 -0
- package/src/gtk-fixed.spec.ts +97 -0
- package/src/gtk-flow-box.spec.ts +289 -0
- package/src/gtk-font-dialog-button.spec.ts +166 -0
- package/src/gtk-frame.spec.ts +119 -0
- package/src/gtk-gl-area.spec.ts +361 -0
- package/src/gtk-graphics-offload.spec.ts +119 -0
- package/src/gtk-grid-view.spec.ts +106 -0
- package/src/gtk-grid.spec.ts +122 -0
- package/src/gtk-header-bar.spec.ts +202 -0
- package/src/gtk-inscription.spec.ts +235 -0
- package/src/gtk-level-bar.spec.ts +199 -0
- package/src/gtk-link-button.spec.ts +117 -0
- package/src/gtk-list-box.spec.ts +422 -0
- package/src/gtk-list-view.spec.ts +203 -0
- package/src/gtk-media-controls.spec.ts +295 -0
- package/src/gtk-notebook.spec.ts +546 -0
- package/src/gtk-overlay.spec.ts +141 -0
- package/src/gtk-paned.spec.ts +267 -0
- package/src/gtk-password-entry.spec.ts +150 -0
- package/src/gtk-picture.spec.ts +172 -0
- package/src/gtk-popover-bin.spec.ts +229 -0
- package/src/gtk-popover-menu-bar.spec.ts +296 -0
- package/src/gtk-popover-menu.spec.ts +261 -0
- package/src/gtk-popover-role.spec.ts +138 -0
- package/src/gtk-popover.spec.ts +264 -0
- package/src/gtk-print-dialogs.spec.ts +251 -0
- package/src/gtk-revealer.spec.ts +164 -0
- package/src/gtk-scale-button.spec.ts +218 -0
- package/src/gtk-scale.spec.ts +213 -0
- package/src/gtk-scrollbar.spec.ts +244 -0
- package/src/gtk-scrolled-window.spec.ts +262 -0
- package/src/gtk-search-bar.spec.ts +179 -0
- package/src/gtk-search-entry.spec.ts +142 -0
- package/src/gtk-separator.spec.ts +74 -0
- package/src/gtk-spin-button.spec.ts +186 -0
- package/src/gtk-spinner.spec.ts +130 -0
- package/src/gtk-stack-sidebar.spec.ts +217 -0
- package/src/gtk-stack-switcher.spec.ts +249 -0
- package/src/gtk-stack.spec.ts +432 -0
- package/src/gtk-text-view.spec.ts +189 -0
- package/src/gtk-text.spec.ts +163 -0
- package/src/gtk-toggle-button.spec.ts +186 -0
- package/src/gtk-tree-expander.spec.ts +201 -0
- package/src/gtk-video.spec.ts +240 -0
- package/src/gtk-viewport.spec.ts +140 -0
- package/src/gtk-window-controls.spec.ts +232 -0
- package/src/gtk-window-handle.spec.ts +158 -0
- package/src/gtk-window.spec.ts +202 -0
- package/src/index.ts +9 -1
- package/src/keyboard-operable.spec.ts +77 -9
- package/src/list-view-dom.ts +121 -0
- package/src/namespace/adw.ts +12 -0
- package/src/namespace/gtk.ts +61 -0
- package/src/page-setup.ts +222 -0
- package/src/row-line-clamp.ts +74 -0
- package/src/row-tooltip.spec.ts +313 -0
- package/src/row-tooltip.ts +52 -0
- package/src/scroll-shading.ts +18 -1
- package/src/shared-tree-builder.ts +336 -41
- package/src/shared-tree-mount.spec.ts +130 -0
- package/src/shared-trees.spec.ts +15 -0
- package/src/signals.ts +15 -0
- package/src/style-classes.spec.ts +9 -8
- package/src/styles.generated.ts +1 -1
- package/src/tab-chip.ts +200 -0
- package/src/template-classes.ts +45 -0
- package/src/test.browser.mts +160 -0
- package/src/widget-size.spec.ts +117 -0
|
@@ -45,21 +45,27 @@
|
|
|
45
45
|
// Modifications: Implemented as a Web Component for @gjsify/adwaita-web; the
|
|
46
46
|
// tab icon + indicator nodes are <gtk-image>.
|
|
47
47
|
|
|
48
|
-
import { TabViewState,
|
|
48
|
+
import { TabViewState, tabsRevealed } from '@gjsify/adwaita-core';
|
|
49
49
|
import type { AdwTabPageSpec, AdwTabPageState, TabViewPagesChange, TabViewSelectionChange } from '@gjsify/adwaita-core';
|
|
50
50
|
|
|
51
51
|
import { bindSlottedChildren } from '../slotted-children.js';
|
|
52
|
-
import { type
|
|
52
|
+
import { type TabChip, createTabChip, refreshTabChip, refreshTabChipClose, scrollChipIntoBar } from '../tab-chip.js';
|
|
53
53
|
|
|
54
54
|
export type AdwTabViewPage = AdwTabPageState<HTMLElement>;
|
|
55
55
|
|
|
56
56
|
export type AdwTabViewPageSpec = AdwTabPageSpec<HTMLElement>;
|
|
57
57
|
|
|
58
58
|
/** The live `<adw-tab-page>` properties, each mapped onto a state setter. */
|
|
59
|
-
const PAGE_ATTRIBUTES = [
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
const PAGE_ATTRIBUTES = [
|
|
60
|
+
'title',
|
|
61
|
+
'tooltip',
|
|
62
|
+
'icon',
|
|
63
|
+
'indicator-icon',
|
|
64
|
+
'keyword',
|
|
65
|
+
'loading',
|
|
66
|
+
'needs-attention',
|
|
67
|
+
'pinned',
|
|
68
|
+
];
|
|
63
69
|
|
|
64
70
|
/**
|
|
65
71
|
* A single page. Declared as a child of <adw-tab-view>; the element itself becomes the
|
|
@@ -109,6 +115,8 @@ export class AdwTabView extends HTMLElement {
|
|
|
109
115
|
private readonly _pagesEl: HTMLDivElement;
|
|
110
116
|
/** Tab chips keyed by page id — the bar is edited in place, never rebuilt. */
|
|
111
117
|
private readonly _tabs = new Map<string, HTMLButtonElement>();
|
|
118
|
+
/** The same chips as {@link _tabs}, held as the shared builder's parts for a refresh. */
|
|
119
|
+
private readonly _chips = new Map<string, TabChip>();
|
|
112
120
|
/** Page panels keyed by page id; kept so a DETACHED page's node is still reachable. */
|
|
113
121
|
private readonly _panels = new Map<string, HTMLElement>();
|
|
114
122
|
private readonly _hovered = new Set<string>();
|
|
@@ -258,6 +266,9 @@ export class AdwTabView extends HTMLElement {
|
|
|
258
266
|
case 'indicator-icon':
|
|
259
267
|
this._state.setPageIndicatorIcon(id, value);
|
|
260
268
|
return;
|
|
269
|
+
case 'keyword':
|
|
270
|
+
this._state.setPageKeyword(id, value);
|
|
271
|
+
return;
|
|
261
272
|
case 'loading':
|
|
262
273
|
this._state.setPageLoading(id, value !== null);
|
|
263
274
|
return;
|
|
@@ -428,10 +439,25 @@ export class AdwTabView extends HTMLElement {
|
|
|
428
439
|
return this._state.setPageTooltip(id, tooltip);
|
|
429
440
|
}
|
|
430
441
|
|
|
442
|
+
/**
|
|
443
|
+
* Set a page's search keyword (`AdwTabPage:keyword`) — the string the tab overview's
|
|
444
|
+
* search matches on beside the title and the tooltip ("Use keywords to search in
|
|
445
|
+
* e.g. page URLs in a web browser", adw-tab-overview.c:1646-1648).
|
|
446
|
+
*/
|
|
447
|
+
setPageKeyword(id: string, keyword: string | null): boolean {
|
|
448
|
+
return this._state.setPageKeyword(id, keyword);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/** Set a page's icon name (`adw_tab_page_set_icon`). */
|
|
431
452
|
setPageIcon(id: string, icon: string | null): boolean {
|
|
432
453
|
return this._state.setPageIcon(id, icon);
|
|
433
454
|
}
|
|
434
455
|
|
|
456
|
+
/** Set a page's indicator icon (`adw_tab_page_set_indicator_icon`). */
|
|
457
|
+
setPageIndicatorIcon(id: string, indicatorIcon: string | null): boolean {
|
|
458
|
+
return this._state.setPageIndicatorIcon(id, indicatorIcon);
|
|
459
|
+
}
|
|
460
|
+
|
|
435
461
|
setPageLoading(id: string, loading: boolean): boolean {
|
|
436
462
|
return this._state.setPageLoading(id, loading);
|
|
437
463
|
}
|
|
@@ -488,6 +514,7 @@ export class AdwTabView extends HTMLElement {
|
|
|
488
514
|
case 'detached': {
|
|
489
515
|
this._tabs.get(change.id)?.remove();
|
|
490
516
|
this._tabs.delete(change.id);
|
|
517
|
+
this._chips.delete(change.id);
|
|
491
518
|
this._hovered.delete(change.id);
|
|
492
519
|
// The page is already out of the model, so its node has to come
|
|
493
520
|
// from here rather than from `getPage(id)?.content`.
|
|
@@ -516,64 +543,28 @@ export class AdwTabView extends HTMLElement {
|
|
|
516
543
|
}
|
|
517
544
|
|
|
518
545
|
private _insertTab(page: AdwTabViewPage, position: number): void {
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
// `AdwTabPage:loading` swaps the icon image for an `AdwSpinnerPaintable` — the
|
|
532
|
-
// SAME paintable `Adw.Spinner` uses (`update_icons`). So this is a real
|
|
533
|
-
// `<adw-spinner>` in the icon's slot, not a ring drawn again in CSS: a CSS copy
|
|
534
|
-
// inherits every spinner defect independently.
|
|
535
|
-
const spinner = document.createElement('adw-spinner');
|
|
536
|
-
spinner.className = 'adw-tab-spinner';
|
|
537
|
-
spinner.setAttribute('size', '16');
|
|
538
|
-
spinner.hidden = true;
|
|
539
|
-
tab.appendChild(spinner);
|
|
540
|
-
|
|
541
|
-
const label = document.createElement('span');
|
|
542
|
-
label.className = 'adw-tab-title';
|
|
543
|
-
tab.appendChild(label);
|
|
544
|
-
|
|
545
|
-
tab.appendChild(createGtkImage(null, 'adw-tab-indicator'));
|
|
546
|
-
|
|
547
|
-
// Close affordance — a small flat button drawn with a CSS "×" glyph. NOT because
|
|
548
|
-
// the glyph is unavailable: `window-close` is in the ICONS map and has a mask class
|
|
549
|
-
// (the comment that used to stand here said otherwise, and was read by two more
|
|
550
|
-
// widgets). It is a SIZING difference — upstream's close button is 24px around a
|
|
551
|
-
// 16px symbolic (adw-tab.ui:77), this strip's chip budgets 18px, and a 16px-grid
|
|
552
|
-
// symbolic scaled into it is a design change, not a rename.
|
|
553
|
-
// `can-focus=False` in C, so it stays out of the tab order here too.
|
|
554
|
-
const close = document.createElement('button');
|
|
555
|
-
close.type = 'button';
|
|
556
|
-
close.className = 'adw-tab-close';
|
|
557
|
-
close.tabIndex = -1;
|
|
558
|
-
close.setAttribute('aria-label', 'Close tab');
|
|
559
|
-
close.addEventListener('click', (event) => {
|
|
560
|
-
event.stopPropagation();
|
|
561
|
-
this._state.closePage(page.id);
|
|
562
|
-
});
|
|
563
|
-
tab.appendChild(close);
|
|
564
|
-
|
|
565
|
-
tab.addEventListener('click', () => this._state.setSelectedPage(page.id));
|
|
566
|
-
tab.addEventListener('pointerenter', () => {
|
|
567
|
-
this._hovered.add(page.id);
|
|
568
|
-
this._refreshCloseVisibility(page.id);
|
|
569
|
-
});
|
|
570
|
-
tab.addEventListener('pointerleave', () => {
|
|
571
|
-
this._hovered.delete(page.id);
|
|
572
|
-
this._refreshCloseVisibility(page.id);
|
|
546
|
+
// The chip itself is the shared one (`../tab-chip.js`), which `<adw-tab-bar>` builds
|
|
547
|
+
// too — the five nodes, their classes and every derivation off the page live there,
|
|
548
|
+
// and what is left here is this widget's own business: where the chip goes in the
|
|
549
|
+
// strip, which page it answers to, and the close affordance's focus policy.
|
|
550
|
+
const chip = createTabChip({
|
|
551
|
+
onSelect: () => this._state.setSelectedPage(page.id),
|
|
552
|
+
onClose: () => this._state.closePage(page.id),
|
|
553
|
+
onHover: (hovering) => {
|
|
554
|
+
if (hovering) this._hovered.add(page.id);
|
|
555
|
+
else this._hovered.delete(page.id);
|
|
556
|
+
this._refreshCloseVisibility(page.id);
|
|
557
|
+
},
|
|
573
558
|
});
|
|
559
|
+
chip.el.dataset.pageId = page.id;
|
|
560
|
+
// `can-focus=False` in C (adw-tab.ui:77), and it lives in the WIDGET rather than in
|
|
561
|
+
// the shared builder because the roving obligation belongs to the file that
|
|
562
|
+
// registers the arrow keys — see scripts/check-adwaita-keyboard-contract.mjs.
|
|
563
|
+
chip.close.tabIndex = -1;
|
|
574
564
|
|
|
575
|
-
this._tabBoxEl.insertBefore(
|
|
576
|
-
this._tabs.set(page.id,
|
|
565
|
+
this._tabBoxEl.insertBefore(chip.el, this._tabBoxEl.children[position] ?? null);
|
|
566
|
+
this._tabs.set(page.id, chip.el);
|
|
567
|
+
this._chips.set(page.id, chip);
|
|
577
568
|
|
|
578
569
|
const panel = page.content;
|
|
579
570
|
if (panel) {
|
|
@@ -600,79 +591,25 @@ export class AdwTabView extends HTMLElement {
|
|
|
600
591
|
const page = this._state.getPage(id);
|
|
601
592
|
const tab = this._tabs.get(id);
|
|
602
593
|
if (!page || !tab) return;
|
|
603
|
-
|
|
604
|
-
const label = tab.querySelector('.adw-tab-title') as HTMLElement | null;
|
|
605
|
-
if (label) label.textContent = page.title;
|
|
606
|
-
// The tooltip is Pango MARKUP when the page sets one of its own. The DOM `title`
|
|
607
|
-
// attribute is a TEXT sink, so the markup is shown verbatim rather than pushed
|
|
608
|
-
// through an HTML sink — interpreting it would execute page-supplied markup.
|
|
609
|
-
tab.title = tabTooltip(page);
|
|
610
|
-
tab.classList.toggle('pinned', page.pinned);
|
|
611
|
-
tab.classList.toggle('needs-attention', page.needsAttention);
|
|
612
|
-
tab.classList.toggle('closing', page.closing);
|
|
613
|
-
|
|
614
|
-
const icons = tabIconState(page, this.getAttribute('default-icon'));
|
|
615
|
-
const icon = tab.querySelector('.adw-tab-icon') as GtkImage | null;
|
|
616
|
-
if (icon) {
|
|
617
|
-
icon.iconName = icons.icon;
|
|
618
|
-
// The two occupy the same slot and are never both visible: C
|
|
619
|
-
// REPLACES the image's contents rather than stacking a second node.
|
|
620
|
-
icon.hidden = !icons.iconVisible || icons.spinner;
|
|
621
|
-
}
|
|
622
|
-
const spinner = tab.querySelector('.adw-tab-spinner') as HTMLElement | null;
|
|
623
|
-
// The spinner is mounted only while it spins, so an idle tab holds no
|
|
624
|
-
// element in the shared rAF ticker.
|
|
625
|
-
if (spinner) spinner.hidden = !(icons.spinner && icons.iconVisible);
|
|
626
|
-
const indicator = tab.querySelector('.adw-tab-indicator') as GtkImage | null;
|
|
627
|
-
if (indicator) {
|
|
628
|
-
indicator.iconName = page.indicatorIcon;
|
|
629
|
-
indicator.hidden = !icons.indicatorVisible;
|
|
630
|
-
}
|
|
594
|
+
refreshTabChip(this._chips.get(id) as TabChip, page, this.getAttribute('default-icon'));
|
|
631
595
|
this._refreshCloseVisibility(id);
|
|
632
596
|
}
|
|
633
597
|
|
|
634
598
|
/**
|
|
635
|
-
*
|
|
636
|
-
*
|
|
637
|
-
*
|
|
638
|
-
*
|
|
639
|
-
*
|
|
640
|
-
*
|
|
641
|
-
* merely sits indented then measured every chip against the wrong origin and
|
|
642
|
-
* reported all of them clipped.
|
|
643
|
-
*/
|
|
644
|
-
private _tabPosition(tab: HTMLElement): number {
|
|
645
|
-
return tab.getBoundingClientRect().left - this._barEl.getBoundingClientRect().left + this._barEl.scrollLeft;
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
/**
|
|
649
|
-
* `tabCloseVisible`, with its pinned gate. `dragging` is constantly false — tab
|
|
650
|
-
* drag-and-drop is compositor work and is not modelled — and `fullyVisible` is
|
|
651
|
-
* measured against the bar's scroll window, which is what the C term means for a
|
|
652
|
-
* horizontally scrolled bar.
|
|
599
|
+
* The close affordance's visibility, and both halves of it now live in `../tab-chip.js`
|
|
600
|
+
* — `tabCloseVisible` and the geometry it is measured with, in the BAR's own scroll
|
|
601
|
+
* space. The incident that moved them there is recorded beside `chipPosition`: the
|
|
602
|
+
* measurement once used `offsetLeft`, which is relative to whichever positioned ancestor
|
|
603
|
+
* the HOST page happens to have, so a tab view that merely sat indented reported every
|
|
604
|
+
* chip clipped and swallowed the close button on hover.
|
|
653
605
|
*/
|
|
654
606
|
private _refreshCloseVisibility(id: string): void {
|
|
655
607
|
const page = this._state.getPage(id);
|
|
656
|
-
const
|
|
657
|
-
if (!page || !
|
|
658
|
-
|
|
659
|
-
if (!close) return;
|
|
660
|
-
|
|
661
|
-
const barLeft = this._barEl.scrollLeft;
|
|
662
|
-
const pos = this._tabPosition(tab);
|
|
663
|
-
// `update_visible` (adw-tab-box.c:769-797). C also demands SPACING of slack on
|
|
664
|
-
// both sides; that term is deliberately NOT transplanted, because it is not
|
|
665
|
-
// slack there either: the allocation loop starts the first tab at `pos = SPACING`
|
|
666
|
-
// and puts SPACING between tabs (:3270-3286), so `pos - SPACING >= value` is
|
|
667
|
-
// exactly "flush against the leading edge". This strip has no such gaps, so the
|
|
668
|
-
// same term would report the first chip clipped and hide its close button.
|
|
669
|
-
const fullyVisible = pos >= barLeft && pos + tab.offsetWidth <= barLeft + this._barEl.clientWidth;
|
|
670
|
-
close.hidden = !tabCloseVisible({
|
|
608
|
+
const chip = this._chips.get(id);
|
|
609
|
+
if (!page || !chip) return;
|
|
610
|
+
refreshTabChipClose(this._barEl, chip, page, {
|
|
671
611
|
hovering: this._hovered.has(id),
|
|
672
|
-
fullyVisible,
|
|
673
612
|
selected: this._state.selectedId === id,
|
|
674
|
-
dragging: false,
|
|
675
|
-
pinned: page.pinned,
|
|
676
613
|
});
|
|
677
614
|
}
|
|
678
615
|
|
|
@@ -714,30 +651,14 @@ export class AdwTabView extends HTMLElement {
|
|
|
714
651
|
|
|
715
652
|
/**
|
|
716
653
|
* `scroll_to_tab_full` (adw-tab-box.c:928-961), called on every selection the way
|
|
717
|
-
* `select_page` calls it (:1728)
|
|
718
|
-
*
|
|
719
|
-
*
|
|
720
|
-
* The bar is the only thing C ever scrolls for a tab: `scroll_to_tab_full` writes
|
|
721
|
-
* `self->adjustment`, the strip's own adjustment, and nothing else. The DOM has no
|
|
722
|
-
* such narrow API: `focus()` and `scrollIntoView()` both walk EVERY scrollable
|
|
723
|
-
* ancestor up to the window. So this moves `scrollLeft` by hand, and the focus call
|
|
724
|
-
* below passes `preventScroll`.
|
|
654
|
+
* `select_page` calls it (:1728) — `scrollChipIntoBar` in `../tab-chip.js`, with the
|
|
655
|
+
* reasoning and the SPACING slack that is deliberately not transplanted.
|
|
725
656
|
*/
|
|
726
657
|
private _scrollSelectedTabIntoBar(): void {
|
|
727
658
|
const id = this._state.selectedId;
|
|
728
659
|
const tab = id === null ? undefined : this._tabs.get(id);
|
|
729
660
|
if (!tab) return;
|
|
730
|
-
|
|
731
|
-
const width = tab.offsetWidth;
|
|
732
|
-
// Unmeasured (detached, or still inside connectedCallback): nothing to scroll to.
|
|
733
|
-
if (pageSize <= 0 || width <= 0) return;
|
|
734
|
-
|
|
735
|
-
const value = this._barEl.scrollLeft;
|
|
736
|
-
const pos = this._tabPosition(tab);
|
|
737
|
-
const padding = Math.min(width, pageSize - width) / 2;
|
|
738
|
-
if (pos - TAB_SPACING < value) this._barEl.scrollLeft = pos - padding;
|
|
739
|
-
else if (pos + width + TAB_SPACING > value + pageSize)
|
|
740
|
-
this._barEl.scrollLeft = pos + width + padding - pageSize;
|
|
661
|
+
scrollChipIntoBar(this._barEl, tab);
|
|
741
662
|
}
|
|
742
663
|
|
|
743
664
|
private _applyBarVisibility(): void {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// <adw-toggle-group> — the web counterpart of Adw.ToggleGroup: a linked set of toggle
|
|
2
2
|
// buttons where exactly one is active. Toggles are `<adw-toggle>` children carrying
|
|
3
|
-
// `label` and/or `icon-name` and an optional `name`, which the
|
|
4
|
-
// selects by (read at connect, like the rest). The `flat` / `round`
|
|
3
|
+
// `label` and/or `icon-name`, an optional `tooltip`, and an optional `name`, which the
|
|
4
|
+
// group's `active-name` selects by (read at connect, like the rest). The `flat` / `round`
|
|
5
|
+
// attributes mirror the upstream
|
|
5
6
|
// `.flat` / `.round` style classes. `notify::active` (CustomEvent, bubbles, detail
|
|
6
7
|
// `{ active }`) mirrors the `active` GObject property.
|
|
7
8
|
//
|
|
@@ -47,6 +48,28 @@
|
|
|
47
48
|
// C does for the only layout this element has, it matches the three sibling tab lists,
|
|
48
49
|
// and it leaves ArrowUp/ArrowDown to the page instead of swallowing a scroll.
|
|
49
50
|
//
|
|
51
|
+
// SENSITIVITY HAS TWO DOORS, and both are the GTK ones. `GtkWidget:sensitive` on the GROUP
|
|
52
|
+
// is the `sensitive` attribute, read by VALUE rather than by presence because the property
|
|
53
|
+
// is TRUE by default and `<adw-toggle-group>` must not read as insensitive (`src/attributes.ts`).
|
|
54
|
+
// `AdwToggle:enabled` is per toggle.
|
|
55
|
+
//
|
|
56
|
+
// PER-TOGGLE `enabled` IS REACHABLE, and the issue's warning does not close it. `add_toggle`
|
|
57
|
+
// spends it at add time — `gtk_widget_set_sensitive (toggle->button, toggle->enabled)`
|
|
58
|
+
// (adw-toggle-group.c:871) — and `adw_toggle_set_enabled` applies it to that same button
|
|
59
|
+
// afterwards (:1663), so nothing about the order is load-bearing. What makes the door awkward
|
|
60
|
+
// is not the order but the TYPE: `AdwToggle` is not a widget and has no `set_sensitive`, so
|
|
61
|
+
// `add_toggle` is the only public way in and it wants an `AdwToggle` this element never
|
|
62
|
+
// builds. Here the door is the rendered `<button>` — which is exactly what `add_toggle` spends
|
|
63
|
+
// the flag on — so the element reads `enabled` where `add_toggle` would have read it and lands
|
|
64
|
+
// in the same state. One consequence is ported with it: an insensitive toggle cannot be the
|
|
65
|
+
// active one (`set_active_toggle`, :720), which is also what makes a disabled `<button>`
|
|
66
|
+
// agree with the selection rather than sitting checked and unreachable.
|
|
67
|
+
//
|
|
68
|
+
// The roving walk is FILTERED, which `roving-focus.ts` requires of every caller: a disabled
|
|
69
|
+
// `<button>` cannot take focus, and leaving one in strands the user on a `focus()` the browser
|
|
70
|
+
// refuses. `status/open-todos/adwaita-web.md` made adding that filter the price of the
|
|
71
|
+
// attribute; this is that change.
|
|
72
|
+
//
|
|
50
73
|
// Reference: refs/libadwaita/src/adw-toggle-group.c (AdwToggleGroup behaviour)
|
|
51
74
|
// Reference: refs/libadwaita/src/stylesheet/widgets/_toggle-group.scss
|
|
52
75
|
// Reference: refs/adwaita-web/adwaita-web/scss/_toggle_group.scss
|
|
@@ -57,13 +80,34 @@
|
|
|
57
80
|
|
|
58
81
|
import { ToggleGroupState, keptToggles, toggleIndexOfName } from '@gjsify/adwaita-core';
|
|
59
82
|
|
|
83
|
+
import { booleanAttribute } from '../attributes.js';
|
|
60
84
|
import { createGtkImage } from './gtk-image.js';
|
|
61
85
|
import { attachRovingFocus } from './roving-focus.js';
|
|
62
86
|
|
|
63
87
|
/** A single toggle. Children of <adw-toggle-group>; consumed at connect time. */
|
|
64
88
|
export class AdwToggle extends HTMLElement {
|
|
89
|
+
// `tooltip` joins because `AdwToggle:tooltip` exists upstream (:467) and an
|
|
90
|
+
// icon-only toggle has no other text — `tooltip` is what NAMES it, so it is not a
|
|
91
|
+
// decoration. It produces no disabled or hidden button, which is the invariant
|
|
92
|
+
// `keyboard-operable.spec.ts` pins this list for.
|
|
93
|
+
//
|
|
94
|
+
// `enabled` is the one that DOES change the invariant, and the pinned list is what
|
|
95
|
+
// forced the roving filter to land in the same change.
|
|
65
96
|
static get observedAttributes() {
|
|
66
|
-
return ['label', 'icon-name'];
|
|
97
|
+
return ['label', 'icon-name', 'tooltip', 'enabled'];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {
|
|
101
|
+
if (name === 'enabled' && oldValue !== newValue) {
|
|
102
|
+
// Notify the parent group that this toggle's enabled state changed.
|
|
103
|
+
this.dispatchEvent(
|
|
104
|
+
new CustomEvent('toggle-enabled-changed', {
|
|
105
|
+
bubbles: true,
|
|
106
|
+
composed: true,
|
|
107
|
+
detail: { enabled: newValue !== 'false' },
|
|
108
|
+
}),
|
|
109
|
+
);
|
|
110
|
+
}
|
|
67
111
|
}
|
|
68
112
|
}
|
|
69
113
|
|
|
@@ -77,9 +121,32 @@ export class AdwToggleGroup extends HTMLElement {
|
|
|
77
121
|
private _stateAttr: 'aria-checked' | 'aria-selected' = 'aria-checked';
|
|
78
122
|
/** Each toggle's `name`, in order — what `active-name` resolves against. */
|
|
79
123
|
private _names: (string | null)[] = [];
|
|
124
|
+
/** `AdwToggle:enabled` per rendered button, in order — `add_toggle` spends this at add time. */
|
|
125
|
+
private _enabled: boolean[] = [];
|
|
126
|
+
/** The authored <adw-toggle> elements, kept to observe live `enabled` changes. */
|
|
127
|
+
private _toggles: AdwToggle[] = [];
|
|
80
128
|
|
|
81
129
|
static get observedAttributes() {
|
|
82
|
-
return ['active', 'active-name', 'flat', 'round'];
|
|
130
|
+
return ['active', 'active-name', 'flat', 'round', 'sensitive'];
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* `GtkWidget:sensitive` — whether the whole group is insensitive.
|
|
135
|
+
*
|
|
136
|
+
* TRUE unless the attribute says `false`, because the property defaults to TRUE and a
|
|
137
|
+
* boolean attribute read by PRESENCE would leave every group on a page insensitive.
|
|
138
|
+
*/
|
|
139
|
+
get sensitive(): boolean {
|
|
140
|
+
return booleanAttribute(this.getAttribute('sensitive'), true);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
set sensitive(value: boolean) {
|
|
144
|
+
this.setAttribute('sensitive', value ? 'true' : 'false');
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/** Whether the toggle at `index` is enabled (`AdwToggle:enabled`) — false once disabled. */
|
|
148
|
+
isToggleEnabled(index: number): boolean {
|
|
149
|
+
return this._enabled[index] ?? false;
|
|
83
150
|
}
|
|
84
151
|
|
|
85
152
|
/** Zero-based index of the active toggle. */
|
|
@@ -154,19 +221,33 @@ export class AdwToggleGroup extends HTMLElement {
|
|
|
154
221
|
// in the C.
|
|
155
222
|
this._innerEl.setAttribute('role', 'none');
|
|
156
223
|
|
|
224
|
+
this._toggles = toggles;
|
|
157
225
|
this._buttons = toggles.map((toggle, index) => {
|
|
158
226
|
const btn = document.createElement('button');
|
|
159
227
|
btn.type = 'button';
|
|
160
228
|
btn.className = 'adw-toggle';
|
|
161
229
|
btn.setAttribute('role', toggleRole);
|
|
230
|
+
// `add_toggle` reads `enabled` while building the button (:871), and a toggle
|
|
231
|
+
// with no `enabled` attribute is the TRUE default (:513).
|
|
232
|
+
this._enabled[index] = booleanAttribute(toggle.getAttribute('enabled'), true);
|
|
162
233
|
|
|
163
234
|
const label = toggle.getAttribute('label') ?? '';
|
|
164
235
|
const icon = toggle.getAttribute('icon-name') ?? '';
|
|
236
|
+
const tooltip = toggle.getAttribute('tooltip') ?? '';
|
|
165
237
|
if (icon) btn.appendChild(createGtkImage(icon));
|
|
166
238
|
if (label) btn.appendChild(document.createTextNode(label));
|
|
167
239
|
|
|
168
|
-
//
|
|
169
|
-
|
|
240
|
+
// `update_button` (adw-toggle-group.c:215) sets the tooltip FIRST and
|
|
241
|
+
// unconditionally, so it is a property of the button whatever else it holds.
|
|
242
|
+
btn.title = tooltip;
|
|
243
|
+
|
|
244
|
+
// The accessible NAME falls through in upstream's order (:226-282): a label
|
|
245
|
+
// names the toggle and the tooltip is then GTK's automatic DESCRIPTION; with
|
|
246
|
+
// no label, the TOOLTIP becomes the name. The icon name is the last resort —
|
|
247
|
+
// it is a symbolic identifier, not words, which is exactly why an icon-only
|
|
248
|
+
// toggle was undiscoverable without this.
|
|
249
|
+
if (!label && tooltip) btn.setAttribute('aria-label', tooltip);
|
|
250
|
+
else if (icon && !label) btn.setAttribute('aria-label', icon);
|
|
170
251
|
|
|
171
252
|
btn.addEventListener('click', () => this._selectIndex(index));
|
|
172
253
|
return btn;
|
|
@@ -175,6 +256,21 @@ export class AdwToggleGroup extends HTMLElement {
|
|
|
175
256
|
this._innerEl.append(...this._buttons);
|
|
176
257
|
this.replaceChildren(this._innerEl);
|
|
177
258
|
|
|
259
|
+
// Observe live `enabled` changes on the authored <adw-toggle> elements.
|
|
260
|
+
// Upstream's `adw_toggle_set_enabled` is a live setter (:1663); the port
|
|
261
|
+
// snapshots at connect, so a later `toggle.setAttribute('enabled', 'false')`
|
|
262
|
+
// had no effect. The `AdwToggle` element fires `toggle-enabled-changed`
|
|
263
|
+
// from its attributeChangedCallback; we update `_enabled` and re-render.
|
|
264
|
+
for (let i = 0; i < this._toggles.length; i++) {
|
|
265
|
+
this._toggles[i].addEventListener('toggle-enabled-changed', (event: Event) => {
|
|
266
|
+
const { enabled } = (event as CustomEvent<{ enabled: boolean }>).detail;
|
|
267
|
+
if (this._enabled[i] !== enabled) {
|
|
268
|
+
this._enabled[i] = enabled;
|
|
269
|
+
this._render();
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
|
|
178
274
|
// Hand the segments to the headless state machine (it needs the count to
|
|
179
275
|
// bound the selection), then seed the active index from the attribute.
|
|
180
276
|
this._state.setLabels(
|
|
@@ -188,16 +284,13 @@ export class AdwToggleGroup extends HTMLElement {
|
|
|
188
284
|
this._applyActiveName();
|
|
189
285
|
this._render();
|
|
190
286
|
|
|
191
|
-
// No `
|
|
192
|
-
//
|
|
193
|
-
//
|
|
194
|
-
// untestable. `AdwToggle.observedAttributes` is pinned in
|
|
195
|
-
// `keyboard-operable.spec.ts` so the day it grows, this decision has to be
|
|
196
|
-
// revisited instead of silently becoming a focus trap.
|
|
287
|
+
// No `hidden` filter, because no `<adw-toggle>` attribute can produce one — and now
|
|
288
|
+
// there IS a `disabled` one, so the filter `roving-focus.ts` asks of every caller is
|
|
289
|
+
// here. `status/open-todos/adwaita-web.md` made that the price of `enabled`.
|
|
197
290
|
attachRovingFocus({
|
|
198
291
|
host: this,
|
|
199
292
|
orientation: 'horizontal',
|
|
200
|
-
items: () => this._buttons,
|
|
293
|
+
items: () => this._buttons.filter((btn) => !btn.disabled),
|
|
201
294
|
// Same path a click takes, so an arrow key cannot drift from a press.
|
|
202
295
|
select: (item) => this._selectIndex(this._buttons.findIndex((btn) => btn === item)),
|
|
203
296
|
});
|
|
@@ -214,7 +307,7 @@ export class AdwToggleGroup extends HTMLElement {
|
|
|
214
307
|
this._applyActiveName();
|
|
215
308
|
return;
|
|
216
309
|
}
|
|
217
|
-
// flat
|
|
310
|
+
// `sensitive`, flat and round: styling and per-button state, both `_render`.
|
|
218
311
|
this._render();
|
|
219
312
|
}
|
|
220
313
|
|
|
@@ -238,6 +331,10 @@ export class AdwToggleGroup extends HTMLElement {
|
|
|
238
331
|
}
|
|
239
332
|
|
|
240
333
|
private _selectIndex(index: number): void {
|
|
334
|
+
// `set_active_toggle` refuses a toggle that is not enabled (:720), so an insensitive
|
|
335
|
+
// one can never become the active one — the check is the core state machine's guard
|
|
336
|
+
// plus this one, in C's order.
|
|
337
|
+
if (!this._enabled[index]) return;
|
|
241
338
|
// The core state machine guards the no-op/out-of-range cases and notifies
|
|
242
339
|
// the subscriber (which re-renders) only on a real change.
|
|
243
340
|
if (!this._state.setSelected(index)) return;
|
|
@@ -251,14 +348,41 @@ export class AdwToggleGroup extends HTMLElement {
|
|
|
251
348
|
this.classList.toggle('flat', this.hasAttribute('flat'));
|
|
252
349
|
this.classList.toggle('round', this.hasAttribute('round'));
|
|
253
350
|
const active = this._state.selected;
|
|
351
|
+
const sensitive = this.sensitive;
|
|
352
|
+
// The group node's own `:disabled` rule (_toggle-group.scss:16) needs the UA's
|
|
353
|
+
// `:disabled`, which a custom element never is — `_expander.scss` records why, and
|
|
354
|
+
// writes the rule against the attribute for the same reason.
|
|
355
|
+
this.toggleAttribute('disabled', !sensitive);
|
|
254
356
|
this._buttons.forEach((btn, index) => {
|
|
255
357
|
const isActive = index === active;
|
|
256
358
|
btn.classList.toggle('active', isActive);
|
|
257
359
|
btn.setAttribute(this._stateAttr, String(isActive));
|
|
360
|
+
// `GtkWidget:sensitive` on the GROUP reaches every child in GTK, because
|
|
361
|
+
// `gtk_widget_is_sensitive` ANDs the parent chain; a `<button disabled>` is the
|
|
362
|
+
// browser's half of that, and it is also what takes the toggle out of the tab
|
|
363
|
+
// order and out of the roving walk.
|
|
364
|
+
btn.disabled = !sensitive || !this._enabled[index];
|
|
258
365
|
// The roving tabindex: Tab enters on the ACTIVE toggle, the way
|
|
259
366
|
// `adw_toggle_group_grab_focus` grabs it, and leaves the group from there.
|
|
260
367
|
btn.tabIndex = isActive ? 0 : -1;
|
|
261
368
|
});
|
|
369
|
+
// An insensitive toggle can never BE the active one, so an active-but-disabled toggle
|
|
370
|
+
// — `active="1"` authored next to `<adw-toggle enabled="false">` — would be a
|
|
371
|
+
// checked radio nothing can reach. Upstream cannot express the pair at all
|
|
372
|
+
// (`set_active_toggle` clears the selection instead, :720), so the selection moves
|
|
373
|
+
// to the first enabled toggle, which is the one Tab then enters on.
|
|
374
|
+
if (!this._enabled[active]) this._activateFirstEnabled();
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/** Select the first enabled toggle, if there is one — the C's "no active" repair. */
|
|
378
|
+
private _activateFirstEnabled(): void {
|
|
379
|
+
const first = this._enabled.findIndex((enabled) => enabled);
|
|
380
|
+
if (first === -1) return;
|
|
381
|
+
this._state.setSelected(first);
|
|
382
|
+
this.setAttribute('active', String(first));
|
|
383
|
+
// The state change came from _render, not user interaction, but the active
|
|
384
|
+
// index changed — emit notify::active so consumers stay in sync.
|
|
385
|
+
this.dispatchEvent(new CustomEvent('notify::active', { bubbles: true, detail: { active: first } }));
|
|
262
386
|
}
|
|
263
387
|
}
|
|
264
388
|
|
|
@@ -140,6 +140,17 @@ export class AdwViewStack extends HTMLElement {
|
|
|
140
140
|
// `hidden` is the DOM spelling of AdwViewStackPage:visible, which
|
|
141
141
|
// gates the auto-pick and refuses selection.
|
|
142
142
|
visible: !pageEl.hasAttribute('hidden'),
|
|
143
|
+
// The five a bound switcher reads. Each was reachable only from the
|
|
144
|
+
// imperative API before, which left `AdwViewSwitcherSidebar`'s grouping
|
|
145
|
+
// (`starts-section`, `section-title`) and its badge dots unreachable
|
|
146
|
+
// from markup at all — the stack page is where they live.
|
|
147
|
+
badgeNumber: pageEl.hasAttribute('badge-number')
|
|
148
|
+
? Number.parseInt(pageEl.getAttribute('badge-number') ?? '0', 10)
|
|
149
|
+
: 0,
|
|
150
|
+
needsAttention: pageEl.hasAttribute('needs-attention'),
|
|
151
|
+
useUnderline: pageEl.hasAttribute('use-underline'),
|
|
152
|
+
startsSection: pageEl.hasAttribute('starts-section'),
|
|
153
|
+
sectionTitle: pageEl.getAttribute('section-title'),
|
|
143
154
|
});
|
|
144
155
|
this.replaceChild(element, pageEl);
|
|
145
156
|
}
|
|
@@ -150,6 +161,13 @@ export class AdwViewStack extends HTMLElement {
|
|
|
150
161
|
if (initialName !== null) this._state.setVisibleName(initialName, false);
|
|
151
162
|
this._applyVisibility();
|
|
152
163
|
this._reflectName();
|
|
164
|
+
// Adopting the declared pages IS an items-changed, and a bound switcher needs to
|
|
165
|
+
// hear it: it connects while this element is still un-upgraded (custom elements
|
|
166
|
+
// upgrade in document order, and a `<adw-view-switcher-sidebar>` beside a stack
|
|
167
|
+
// connects FIRST), so it read an empty page list. The `notify::visible-child`
|
|
168
|
+
// the auto-pick emits covers the first page alone — a stack of two left every
|
|
169
|
+
// bound switcher showing one row.
|
|
170
|
+
this._emitItemsChanged();
|
|
153
171
|
}
|
|
154
172
|
|
|
155
173
|
attributeChangedCallback(name: string, _old: string | null, value: string | null) {
|