@gjsify/adwaita-web 0.53.0 → 0.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adwaita-web.css +8070 -3037
- 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-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/breakpoints.d.ts +14 -3
- package/lib/types/construct-vectors.spec.d.ts +1 -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-dialog.d.ts +10 -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-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 +5 -0
- package/lib/types/elements/adw-switch-row.d.ts +3 -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-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 +121 -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 +97 -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/scroll-shading.d.ts +15 -1
- package/lib/types/shared-tree-builder.d.ts +30 -2
- 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/package.json +12 -8
- package/scss/_action_row.scss +2 -2
- 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/_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/_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 +132 -0
- 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 +51 -0
- package/scss/_print_dialogs.scss +328 -0
- package/scss/_reset.scss +21 -19
- package/scss/_revealer.scss +37 -0
- package/scss/_row.scss +20 -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/_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/_tree_expander.scss +62 -0
- package/scss/_variables.scss +43 -21
- package/scss/_video.scss +146 -0
- package/scss/_view_switcher_sidebar.scss +112 -0
- package/scss/_viewport.scss +50 -0
- package/scss/_window.scss +118 -1
- package/scss/_window_handle.scss +20 -0
- package/scss/adwaita-skin.scss +109 -0
- package/src/adw-action-rows.spec.ts +76 -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-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-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/breakpoints.ts +25 -8
- package/src/capabilities.d.mts +3 -0
- package/src/capabilities.mjs +18 -0
- package/src/connect-lifecycle.spec.ts +12 -0
- package/src/construct-vectors.spec.ts +175 -0
- 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-clamp-scrollable.ts +207 -0
- package/src/elements/adw-dialog.ts +19 -0
- package/src/elements/adw-layout-slot.ts +95 -0
- package/src/elements/adw-multi-layout-view.ts +326 -0
- package/src/elements/adw-preferences-row.ts +150 -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 +42 -3
- package/src/elements/adw-switch-row.ts +28 -1
- 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 +20 -5
- 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 +185 -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 +642 -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 +366 -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 +190 -0
- package/src/index.ts +9 -1
- package/src/keyboard-operable.spec.ts +33 -1
- 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/scroll-shading.ts +18 -1
- package/src/shared-tree-builder.ts +263 -21
- package/src/signals.ts +15 -0
- package/src/source-view/theme.ts +11 -5
- 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 +152 -0
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
// <adw-tab-bar> — libadwaita's tab bar as the separate WIDGET it is: a strip of chips
|
|
2
|
+
// bound to an `<adw-tab-view>` through `Adw.TabBar:view`, with action widgets on either
|
|
3
|
+
// side of the tabs.
|
|
4
|
+
//
|
|
5
|
+
// WHY A SECOND BAR. Upstream the bar is its own `G_DEFINE_FINAL_TYPE` over `AdwTabBox`
|
|
6
|
+
// (adw-tab-bar.c:90), and `<adw-tab-view>` here carries a MERGED one: the bar that widget
|
|
7
|
+
// drew before this element existed is still what it draws, and this file does not change
|
|
8
|
+
// that. What changes is that a document can now put the two parts together the way
|
|
9
|
+
// libadwaita does — a bar over a view, or a bar over a view it does not own — which is the
|
|
10
|
+
// only reason `Adw.TabBar` has a block here at all.
|
|
11
|
+
//
|
|
12
|
+
// `view` is a widget REFERENCE (`Adw.TabView`), which on this renderer is an element id the
|
|
13
|
+
// way `<adw-tab-button view>` and `<adw-view-switcher-bar stack>` are one; the property
|
|
14
|
+
// setter takes the element directly for code. Both are the same shape of divergence:
|
|
15
|
+
// `scripts/generate-adwaita-attribute-comments.mjs`'s `id-reference` ledger entry.
|
|
16
|
+
//
|
|
17
|
+
// THE CHIP AND THE TWO MEASUREMENTS live in `../tab-chip.js`, shared with `<adw-tab-view>`
|
|
18
|
+
// so the two bars cannot drift apart; what is here is what is genuinely this widget's —
|
|
19
|
+
// the scroll window, the selection, the reveal rule and the two action slots.
|
|
20
|
+
//
|
|
21
|
+
// THE C RULES THE DOM DOES NOT SHOW:
|
|
22
|
+
// - `tabs-revealed` hides the strip when the view has 0 or 1 tab, no pinned tab and no
|
|
23
|
+
// tab in flight (`adw_tab_bar_update_tabs_revealed`), which `tabsRevealed` from
|
|
24
|
+
// `@gjsify/adwaita-core` decides — the same call `<adw-tab-view>` makes for its own
|
|
25
|
+
// bar, over the same three terms.
|
|
26
|
+
// - `is-overflowing` is the strip's own adjustment: not the chip count, not a width
|
|
27
|
+
// estimate. It is `scrollWidth > clientWidth`, which is what the revealer over the box
|
|
28
|
+
// (`tabbox > revealer > indicator`) and the scrolled window agree on.
|
|
29
|
+
// - a lone tab draws no background (`tabbox.single-tab tab`), and the separators either
|
|
30
|
+
// side of the SELECTED or HOVERED tab are the ones C hides (`update_separators`).
|
|
31
|
+
// - `inverted` puts the close button at the BEGINNING of a non-pinned tab and the
|
|
32
|
+
// indicator at the end, rather than the opposite (adw-tab-bar.c:636-644).
|
|
33
|
+
//
|
|
34
|
+
// MODIFICATIONS, both about defaults an HTML boolean attribute cannot carry. `autohide` and
|
|
35
|
+
// `expand-tabs` default TRUE upstream (`DEFAULT_TAB_AUTOHIDE`, and the tab box's own
|
|
36
|
+
// default), and a present attribute is the only spelling a markup fence has, so both are
|
|
37
|
+
// OPT-IN here: `autohide` on the element hides the strip with a single tab, and without
|
|
38
|
+
// `expand-tabs` the chips sit at their minimum size. `<adw-tab-view>`'s merged bar made the
|
|
39
|
+
// same trade for `autohide` and says so in its header.
|
|
40
|
+
//
|
|
41
|
+
// NOT PORTED: `setup_extra_drop_target`'s PRELOAD step. `extra-drag-preload` is observed
|
|
42
|
+
// and exposed, the `extra-drag-value` signal is dispatched on hover-start with a `NULL`
|
|
43
|
+
// action exactly as C does, and `extra-drag-preferred-action` carries whatever a handler
|
|
44
|
+
// put there — but a browser only exposes drag data at DROP time (`DataTransfer.getData`
|
|
45
|
+
// returns nothing during `dragover`, by the HTML drag and drop specification), so the
|
|
46
|
+
// "read the data while the pointer is still over the widget" half has nothing to read. The
|
|
47
|
+
// hover-start signal is emitted either way, which is the part of the contract an
|
|
48
|
+
// application acts on.
|
|
49
|
+
//
|
|
50
|
+
// Events (all CustomEvent, all bubbling): `notify::view`, `notify::autohide`,
|
|
51
|
+
// `notify::expand-tabs`, `notify::inverted`, `notify::extra-drag-preload`
|
|
52
|
+
// (`detail: { <prop> }`); `extra-drag-value` (`{ action }`, `action` is `null` on
|
|
53
|
+
// hover-start and whatever a handler set on the next hover); and `extra-drag-drop`
|
|
54
|
+
// (`{ action, data }`), CANCELABLE, whose `preventDefault()` refuses the drop — the C
|
|
55
|
+
// handler's `TRUE`/`FALSE` return.
|
|
56
|
+
//
|
|
57
|
+
// A11Y: `role="tablist"` on the host over real `<button role="tab">` children, so Enter and
|
|
58
|
+
// Space arrive through the platform, and the roving tabindex moves with the selection.
|
|
59
|
+
//
|
|
60
|
+
// KNOWN_GAPS: none, and not by omission. `AdwTabBar` declares seven WRITABLE properties
|
|
61
|
+
// (`generated/props.ts`), three of them widget-valued and out of the ledger's scope; the
|
|
62
|
+
// other four — `autohide`, `expand-tabs`, `inverted` and `extra-drag-preload` — are all
|
|
63
|
+
// attributes here. Its three read-ONLY properties (`tabs-revealed`, `is-overflowing`,
|
|
64
|
+
// `extra-drag-preferred-action`) are getters rather than attributes, and the generated
|
|
65
|
+
// table carries no row for a property nothing can set.
|
|
66
|
+
//
|
|
67
|
+
// Reference: refs/libadwaita/src/adw-tab-bar.c (view, action widgets, autohide,
|
|
68
|
+
// expand-tabs, inverted, is-overflowing, extra drop target, tabs-revealed)
|
|
69
|
+
// Reference: refs/libadwaita/src/adw-tab-box.c (the box, its single-tab class, SPACING)
|
|
70
|
+
// Reference: refs/libadwaita/src/stylesheet/widgets/_tab-view.scss:1-113 (tabbar, tabbox,
|
|
71
|
+
// tab, start/end action) and :154-176 (the chip's own metrics)
|
|
72
|
+
// Copyright (c) 2024-2025 Alice Mikhaylenko / Purism SPC. LGPLv2.1+.
|
|
73
|
+
// Modifications: Implemented as a Web Component for @gjsify/adwaita-web; `view` is an
|
|
74
|
+
// element id, the drag target is the DOM drag and drop API, and the chips are the shared
|
|
75
|
+
// ones from `../tab-chip.js`.
|
|
76
|
+
|
|
77
|
+
import { tabsRevealed } from '@gjsify/adwaita-core';
|
|
78
|
+
|
|
79
|
+
import { bindSlottedChildren } from '../slotted-children.js';
|
|
80
|
+
import { type TabChip, createTabChip, refreshTabChip, refreshTabChipClose, scrollChipIntoBar } from '../tab-chip.js';
|
|
81
|
+
import type { AdwTabView } from './adw-tab-view.js';
|
|
82
|
+
|
|
83
|
+
/** `set_view`'s connections: the page list, the selection, and each page's own state. */
|
|
84
|
+
const VIEW_EVENTS = [
|
|
85
|
+
'page-attached',
|
|
86
|
+
'page-detached',
|
|
87
|
+
'page-reordered',
|
|
88
|
+
'page-updated',
|
|
89
|
+
'page-pinned',
|
|
90
|
+
'notify::selected-page',
|
|
91
|
+
] as const;
|
|
92
|
+
|
|
93
|
+
/** The CSS classes a chip's own layout reads — the states C puts on the widget. */
|
|
94
|
+
|
|
95
|
+
export class AdwTabBar extends HTMLElement {
|
|
96
|
+
private _boxEl!: HTMLDivElement;
|
|
97
|
+
private _startEl!: HTMLDivElement;
|
|
98
|
+
private _endEl!: HTMLDivElement;
|
|
99
|
+
private _indicatorEl!: HTMLDivElement;
|
|
100
|
+
private _chips = new Map<string, TabChip>();
|
|
101
|
+
private _hovered = new Set<string>();
|
|
102
|
+
private _view: AdwTabView | null = null;
|
|
103
|
+
private _initialized = false;
|
|
104
|
+
private _preferredAction: string | null = null;
|
|
105
|
+
private _dropTypes: readonly string[] = [];
|
|
106
|
+
private _dropActions: readonly string[] = [];
|
|
107
|
+
private _dropArmed = false;
|
|
108
|
+
|
|
109
|
+
static get observedAttributes() {
|
|
110
|
+
return ['view', 'autohide', 'expand-tabs', 'inverted', 'extra-drag-preload'];
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** `Adw.TabBar:view` — the tab view this bar controls. */
|
|
114
|
+
get view(): AdwTabView | null {
|
|
115
|
+
return this._view;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
set view(value: AdwTabView | string | null) {
|
|
119
|
+
this.setView(value === null ? null : typeof value === 'string' ? this._resolveView(value) : value);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* `Adw.TabBar:start-action-widget` — the widget shown BEFORE the tabs.
|
|
124
|
+
*
|
|
125
|
+
* READ OUT OF THE BIN rather than remembered: a `slot="start-action-widget"` child and
|
|
126
|
+
* this setter are two spellings of one property, and a second copy of the truth is where
|
|
127
|
+
* they drift apart. `bindSlottedChildren` moves the node; the bin holds it.
|
|
128
|
+
*/
|
|
129
|
+
get startActionWidget(): HTMLElement | null {
|
|
130
|
+
return (this._startEl?.firstElementChild as HTMLElement | null) ?? null;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
set startActionWidget(widget: HTMLElement | null) {
|
|
134
|
+
if (this.startActionWidget === widget) return;
|
|
135
|
+
this._startEl.replaceChildren(...(widget === null ? [] : [widget]));
|
|
136
|
+
this.dispatchEvent(new CustomEvent('notify::start-action-widget', { bubbles: true, detail: { widget } }));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/** `Adw.TabBar:end-action-widget` — the widget shown AFTER the tabs. */
|
|
140
|
+
get endActionWidget(): HTMLElement | null {
|
|
141
|
+
return (this._endEl?.firstElementChild as HTMLElement | null) ?? null;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
set endActionWidget(widget: HTMLElement | null) {
|
|
145
|
+
if (this.endActionWidget === widget) return;
|
|
146
|
+
this._endEl.replaceChildren(...(widget === null ? [] : [widget]));
|
|
147
|
+
this.dispatchEvent(new CustomEvent('notify::end-action-widget', { bubbles: true, detail: { widget } }));
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* `Adw.TabBar:autohide` — whether the strip hides itself when it has nothing to show.
|
|
152
|
+
* TRUE upstream, opt-in here; see the header.
|
|
153
|
+
*/
|
|
154
|
+
get autohide(): boolean {
|
|
155
|
+
return this.hasAttribute('autohide');
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
set autohide(value: boolean) {
|
|
159
|
+
if (value) this.setAttribute('autohide', '');
|
|
160
|
+
else this.removeAttribute('autohide');
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/** `Adw.TabBar:expand-tabs` — chips fill the strip instead of sitting at minimum size. */
|
|
164
|
+
get expandTabs(): boolean {
|
|
165
|
+
return this.hasAttribute('expand-tabs');
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
set expandTabs(value: boolean) {
|
|
169
|
+
if (value) this.setAttribute('expand-tabs', '');
|
|
170
|
+
else this.removeAttribute('expand-tabs');
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/** `Adw.TabBar:inverted` — close button first, indicator last. */
|
|
174
|
+
get inverted(): boolean {
|
|
175
|
+
return this.hasAttribute('inverted');
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
set inverted(value: boolean) {
|
|
179
|
+
if (value) this.setAttribute('inverted', '');
|
|
180
|
+
else this.removeAttribute('inverted');
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/** `Adw.TabBar:extra-drag-preload` — see the header for the half a browser cannot do. */
|
|
184
|
+
get extraDragPreload(): boolean {
|
|
185
|
+
return this.hasAttribute('extra-drag-preload');
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
set extraDragPreload(value: boolean) {
|
|
189
|
+
if (value) this.setAttribute('extra-drag-preload', '');
|
|
190
|
+
else this.removeAttribute('extra-drag-preload');
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/** `Adw.TabBar:tabs-revealed` — read-only, and `tabsRevealed`'s answer. */
|
|
194
|
+
get tabsRevealed(): boolean {
|
|
195
|
+
return tabsRevealed({
|
|
196
|
+
autohide: this.autohide,
|
|
197
|
+
nPages: this._view?.nPages ?? 0,
|
|
198
|
+
nPinnedPages: this._view?.nPinnedPages ?? 0,
|
|
199
|
+
// Tab transfer between views is drag-and-drop, i.e. compositor work, and is
|
|
200
|
+
// not modelled — the same `false` `<adw-tab-view>` passes.
|
|
201
|
+
isTransferringPage: false,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/** `Adw.TabBar:is-overflowing` — read-only, measured off the strip's own scroll window. */
|
|
206
|
+
get isOverflowing(): boolean {
|
|
207
|
+
if (!this._initialized) return false;
|
|
208
|
+
return this.scrollWidth > this.clientWidth;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/** `Adw.TabBar:extra-drag-preferred-action` — read-only, set by a drag handler. */
|
|
212
|
+
get extraDragPreferredAction(): string | null {
|
|
213
|
+
return this._preferredAction;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/** `adw_tab_bar_set_view`: rebind, then redraw every chip from the new view's pages. */
|
|
217
|
+
setView(view: AdwTabView | null): void {
|
|
218
|
+
if (this._view === view) return;
|
|
219
|
+
this._unbindView();
|
|
220
|
+
this._view = view;
|
|
221
|
+
this._bindView();
|
|
222
|
+
this._syncChips();
|
|
223
|
+
this._applyRevealed();
|
|
224
|
+
this.dispatchEvent(new CustomEvent('notify::view', { bubbles: true, detail: { view } }));
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
connectedCallback() {
|
|
228
|
+
if (this._initialized) {
|
|
229
|
+
// Re-entering a document: `disconnectedCallback` dropped the listeners, so a
|
|
230
|
+
// bar that was merely MOVED has to get them back here or it stops noticing pages.
|
|
231
|
+
this._bindView();
|
|
232
|
+
this._syncChips();
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
this._initialized = true;
|
|
236
|
+
|
|
237
|
+
this.classList.add('adw-tab-bar');
|
|
238
|
+
this.setAttribute('role', 'tablist');
|
|
239
|
+
|
|
240
|
+
this._startEl = document.createElement('div');
|
|
241
|
+
this._startEl.className = 'adw-tab-bar-start-action';
|
|
242
|
+
|
|
243
|
+
this._boxEl = document.createElement('div');
|
|
244
|
+
this._boxEl.className = 'adw-tab-box';
|
|
245
|
+
|
|
246
|
+
this._indicatorEl = document.createElement('div');
|
|
247
|
+
this._indicatorEl.className = 'adw-tab-box-overflow';
|
|
248
|
+
this._indicatorEl.hidden = true;
|
|
249
|
+
this._boxEl.appendChild(this._indicatorEl);
|
|
250
|
+
|
|
251
|
+
this._endEl = document.createElement('div');
|
|
252
|
+
this._endEl.className = 'adw-tab-bar-end-action';
|
|
253
|
+
|
|
254
|
+
// `AdwBin`s on both sides of the box (adw-tab-bar.ui): the action widgets are
|
|
255
|
+
// widget-typed PROPERTIES, so a document spells them as `slot=` children. The three
|
|
256
|
+
// boxes go in through `install`, which is how the router learns which children are
|
|
257
|
+
// the widget's OWN structure — `src/slotted-children.ts` has the incident, and a
|
|
258
|
+
// plain `replaceChildren` here would leave them to be read as authored children.
|
|
259
|
+
bindSlottedChildren(this, [
|
|
260
|
+
{ name: 'start-action-widget', into: this._startEl },
|
|
261
|
+
{ name: 'end-action-widget', into: this._endEl },
|
|
262
|
+
]).install(this._startEl, this._boxEl, this._endEl);
|
|
263
|
+
|
|
264
|
+
const ref = this.getAttribute('view');
|
|
265
|
+
this.setView(ref === null ? null : this._resolveView(ref));
|
|
266
|
+
this._bindView();
|
|
267
|
+
this._syncChips();
|
|
268
|
+
this._applyRevealed();
|
|
269
|
+
|
|
270
|
+
this.addEventListener('keydown', (event) => this._onKeyDown(event as KeyboardEvent));
|
|
271
|
+
// The extra drop target's two platform events, attached ALWAYS and inert until
|
|
272
|
+
// `setupExtraDropTarget` names the types: a drag over a bar that has no target is
|
|
273
|
+
// the page's own business, and rebinding on every setup call would be a second
|
|
274
|
+
// place to forget one.
|
|
275
|
+
this.addEventListener('dragover', this._onDragOver);
|
|
276
|
+
this.addEventListener('drop', this._onDrop);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
disconnectedCallback() {
|
|
280
|
+
this._unbindView();
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
attributeChangedCallback(name: string, _old: string | null, value: string | null) {
|
|
284
|
+
if (!this._initialized) return;
|
|
285
|
+
switch (name) {
|
|
286
|
+
case 'view':
|
|
287
|
+
this.setView(value === null ? null : this._resolveView(value));
|
|
288
|
+
return;
|
|
289
|
+
case 'autohide':
|
|
290
|
+
this._applyRevealed();
|
|
291
|
+
break;
|
|
292
|
+
case 'expand-tabs':
|
|
293
|
+
case 'inverted':
|
|
294
|
+
case 'extra-drag-preload':
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
// Every one of the four notifies, and only on a real change: `attributeChangedCallback`
|
|
298
|
+
// fires for a write that writes the value it already holds, and C's `set_property`
|
|
299
|
+
// does the same (adw-tab-bar.c:520-546), so the event is dispatched here rather than
|
|
300
|
+
// from the attribute itself.
|
|
301
|
+
if (value !== null || name === 'view') {
|
|
302
|
+
this.dispatchEvent(new CustomEvent(`notify::${name}`, { bubbles: true, detail: { [name]: value } }));
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* `adw_tab_bar_setup_extra_drop_target`: the DOM half of an extra drop target.
|
|
308
|
+
*
|
|
309
|
+
* `types` is the list of MIME types the widget accepts and `actions` the list of drop
|
|
310
|
+
* effects it will let through, which is the pair the C call takes. A drop of any other
|
|
311
|
+
* type is not ours and is left to the page.
|
|
312
|
+
*/
|
|
313
|
+
setupExtraDropTarget(types: readonly string[], actions: readonly string[] = ['copy', 'move']): void {
|
|
314
|
+
this._dropTypes = types;
|
|
315
|
+
this._dropActions = actions;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
private _resolveView(ref: string): AdwTabView | null {
|
|
319
|
+
// Resolved NOW, because the view is normally EARLIER in the document (the pages
|
|
320
|
+
// below the chrome), which is the same reason `<adw-tab-button>` resolves its `view`
|
|
321
|
+
// on connect rather than on the first attribute write.
|
|
322
|
+
return (document.getElementById(ref) as AdwTabView | null) ?? null;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/** `set_view`'s connections, as the view's own events rather than GObject notifications. */
|
|
326
|
+
private _bindView(): void {
|
|
327
|
+
this._unbindView();
|
|
328
|
+
for (const type of VIEW_EVENTS) this._view?.addEventListener(type, this._onViewChange);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
private _unbindView(): void {
|
|
332
|
+
for (const type of VIEW_EVENTS) this._view?.removeEventListener(type, this._onViewChange);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
private _onViewChange = (): void => {
|
|
336
|
+
this._syncChips();
|
|
337
|
+
this._applyRevealed();
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* The whole strip, rebuilt in place: the page list is the model, and C edits the box
|
|
342
|
+
* rather than rebuilding it, so a chip that survives keeps its node, its hover state and
|
|
343
|
+
* its focus.
|
|
344
|
+
*/
|
|
345
|
+
private _syncChips(): void {
|
|
346
|
+
const pages = this._view?.pages ?? [];
|
|
347
|
+
const seen = new Set<string>();
|
|
348
|
+
pages.forEach((page, position) => {
|
|
349
|
+
seen.add(page.id);
|
|
350
|
+
const existing = this._chips.get(page.id);
|
|
351
|
+
if (existing === undefined) {
|
|
352
|
+
const chip = createTabChip({
|
|
353
|
+
onSelect: () => this._view?.setSelectedPage(page.id),
|
|
354
|
+
onClose: () => this._view?.closePage(page.id),
|
|
355
|
+
onHover: (hovering) => {
|
|
356
|
+
if (hovering) this._hovered.add(page.id);
|
|
357
|
+
else this._hovered.delete(page.id);
|
|
358
|
+
this._refreshOne(page.id);
|
|
359
|
+
},
|
|
360
|
+
});
|
|
361
|
+
chip.el.dataset.pageId = page.id;
|
|
362
|
+
// `can-focus=False` on AdwTab's close button (adw-tab.ui:77). It lives HERE
|
|
363
|
+
// rather than in the shared chip builder because the roving obligation is
|
|
364
|
+
// discharged by the file that registers the arrow keys
|
|
365
|
+
// (scripts/check-adwaita-keyboard-contract.mjs), and a builder has none.
|
|
366
|
+
chip.close.tabIndex = -1;
|
|
367
|
+
this._chips.set(page.id, chip);
|
|
368
|
+
this._boxEl.insertBefore(chip.el, this._boxEl.children[position] ?? null);
|
|
369
|
+
} else if (this._boxEl.children[position] !== existing.el) {
|
|
370
|
+
this._boxEl.insertBefore(existing.el, this._boxEl.children[position] ?? null);
|
|
371
|
+
}
|
|
372
|
+
this._refreshOne(page.id);
|
|
373
|
+
});
|
|
374
|
+
for (const [id, chip] of this._chips) {
|
|
375
|
+
if (seen.has(id)) continue;
|
|
376
|
+
chip.el.remove();
|
|
377
|
+
this._chips.delete(id);
|
|
378
|
+
this._hovered.delete(id);
|
|
379
|
+
}
|
|
380
|
+
this._applyActiveState();
|
|
381
|
+
this._boxEl.classList.toggle('single-tab', pages.length <= 1);
|
|
382
|
+
this._applyOverflow();
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
private _refreshOne(id: string): void {
|
|
386
|
+
const page = this._view?.pages.find((candidate) => candidate.id === id);
|
|
387
|
+
const chip = this._chips.get(id);
|
|
388
|
+
if (page === undefined || chip === undefined) return;
|
|
389
|
+
refreshTabChip(chip, page, this._view?.getAttribute('default-icon'));
|
|
390
|
+
refreshTabChipClose(this, chip, page, {
|
|
391
|
+
hovering: this._hovered.has(id),
|
|
392
|
+
selected: this._view?.selectedId === id,
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* `update_selected_tab`: the selected chip takes the `:selected` state, the roving
|
|
398
|
+
* tabindex follows it, and the strip scrolls it into view the way C does on EVERY
|
|
399
|
+
* selection (`adw-tab-bar.c:934` -> `adw-tab-box.c:1728`).
|
|
400
|
+
*/
|
|
401
|
+
private _applyActiveState(): void {
|
|
402
|
+
const selected = this._view?.selectedId ?? null;
|
|
403
|
+
for (const [id, chip] of this._chips) {
|
|
404
|
+
const active = id === selected;
|
|
405
|
+
// Only `active` is the bar's own state; `pinned`, `needs-attention` and
|
|
406
|
+
// `closing` come off the PAGE and `refreshTabChip` owns them.
|
|
407
|
+
chip.el.classList.toggle('active', active);
|
|
408
|
+
chip.el.setAttribute('aria-selected', String(active));
|
|
409
|
+
chip.el.tabIndex = active ? 0 : -1;
|
|
410
|
+
const page = this._view?.pages.find((candidate) => candidate.id === id);
|
|
411
|
+
if (page !== undefined)
|
|
412
|
+
refreshTabChipClose(this, chip, page, { hovering: this._hovered.has(id), selected: active });
|
|
413
|
+
}
|
|
414
|
+
if (selected === null) return;
|
|
415
|
+
const chip = this._chips.get(selected);
|
|
416
|
+
if (chip !== undefined) scrollChipIntoBar(this, chip.el);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/** `update_tabs_revealed`: the strip is up or it is not. */
|
|
420
|
+
private _applyRevealed(): void {
|
|
421
|
+
this.hidden = !this.tabsRevealed;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* `is-overflowing`, and the revealer over the box that reads it
|
|
426
|
+
* (`tabbox > revealer > indicator`, _tab-view.scss:44-55): a two-pixel accent bar under
|
|
427
|
+
* the chips, shown exactly while the strip cannot show them all.
|
|
428
|
+
*/
|
|
429
|
+
private _applyOverflow(): void {
|
|
430
|
+
this._indicatorEl.hidden = !this.isOverflowing;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* `Adw.TabView`'s shortcut table as the BAR sees it (`adw-tab-bar.c` connects the same
|
|
435
|
+
* moves), plus the ArrowLeft/ArrowRight movement `role=tablist` promises. Ctrl+Tab WRAPS
|
|
436
|
+
* and Ctrl+Page-Up/Down does not — the same `last` flag that separates them in C.
|
|
437
|
+
*/
|
|
438
|
+
private _onKeyDown(event: KeyboardEvent): void {
|
|
439
|
+
const view = this._view;
|
|
440
|
+
if (view === null) return;
|
|
441
|
+
let handled = false;
|
|
442
|
+
|
|
443
|
+
if (event.ctrlKey && event.key === 'Tab') {
|
|
444
|
+
handled = event.shiftKey ? view.cyclePreviousPage() : view.cycleNextPage();
|
|
445
|
+
} else if (event.ctrlKey && (event.key === 'PageUp' || event.key === 'PageDown')) {
|
|
446
|
+
handled = event.key === 'PageUp' ? view.selectPreviousPage() : view.selectNextPage();
|
|
447
|
+
} else if (event.ctrlKey && (event.key === 'Home' || event.key === 'End')) {
|
|
448
|
+
handled = event.key === 'Home' ? view.selectFirstPage() : view.selectLastPage();
|
|
449
|
+
} else if (event.altKey && /^[0-9]$/.test(event.key)) {
|
|
450
|
+
const digit = Number.parseInt(event.key, 10);
|
|
451
|
+
handled = view.selectNthPage(digit === 0 ? 9 : digit - 1);
|
|
452
|
+
} else if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {
|
|
453
|
+
handled = event.key === 'ArrowLeft' ? view.selectPreviousPage() : view.selectNextPage();
|
|
454
|
+
} else if (event.key === 'Home' || event.key === 'End') {
|
|
455
|
+
// `role=tablist`'s own two keys, and the halves `Ctrl+Home` / `Ctrl+End` do not
|
|
456
|
+
// cover: C reaches the last tab through the same selection call, so this is the
|
|
457
|
+
// same move with the reordering pair left to the Ctrl branches above.
|
|
458
|
+
handled = event.key === 'Home' ? view.selectFirstPage() : view.selectLastPage();
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
if (!handled) return;
|
|
462
|
+
event.preventDefault();
|
|
463
|
+
// `preventScroll` because a bare `focus()` scrolls every scrollable ancestor up to
|
|
464
|
+
// and including the WINDOW, while C only ever moves the strip.
|
|
465
|
+
const id = view.selectedId;
|
|
466
|
+
if (id !== null) this._chips.get(id)?.el.focus({ preventScroll: true });
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// --- the extra drop target, in the DOM's own vocabulary -----------------------
|
|
470
|
+
|
|
471
|
+
private _onDragOver = (event: DragEvent): void => {
|
|
472
|
+
if (this._dropTypes.length === 0 || event.dataTransfer === null) return;
|
|
473
|
+
const type = [...this._dropTypes].find((candidate) => event.dataTransfer?.types.includes(candidate));
|
|
474
|
+
if (type === undefined) return;
|
|
475
|
+
event.preventDefault();
|
|
476
|
+
if (event.dataTransfer.dropEffect !== 'none') event.dataTransfer.dropEffect = this._dropEffects(event);
|
|
477
|
+
this._armHoverValue();
|
|
478
|
+
};
|
|
479
|
+
|
|
480
|
+
private _onDrop = (event: DragEvent): void => {
|
|
481
|
+
if (this._dropTypes.length === 0 || event.dataTransfer === null) return;
|
|
482
|
+
const type = [...this._dropTypes].find((candidate) => event.dataTransfer?.types.includes(candidate));
|
|
483
|
+
if (type === undefined) return;
|
|
484
|
+
event.preventDefault();
|
|
485
|
+
const action = this._dropEffects(event);
|
|
486
|
+
const proceed = this.dispatchEvent(
|
|
487
|
+
new CustomEvent('extra-drag-drop', {
|
|
488
|
+
bubbles: true,
|
|
489
|
+
cancelable: true,
|
|
490
|
+
detail: { action, data: event.dataTransfer.getData(type) },
|
|
491
|
+
}),
|
|
492
|
+
);
|
|
493
|
+
// The C handler returns whether it took the drop; a cancelled event is the same
|
|
494
|
+
// refusal, and the platform has to be told either way.
|
|
495
|
+
event.dataTransfer.dropEffect = proceed ? action : 'none';
|
|
496
|
+
};
|
|
497
|
+
|
|
498
|
+
/** `dropEffect` is the DOM's own name for `Gdk.DragAction`, and it takes the same words. */
|
|
499
|
+
private _dropEffects(_event: DragEvent): DataTransfer['dropEffect'] {
|
|
500
|
+
const action = this._preferredAction;
|
|
501
|
+
if (action !== null && this._dropActions.includes(action)) return action as DataTransfer['dropEffect'];
|
|
502
|
+
return (this._dropActions[0] ?? 'copy') as DataTransfer['dropEffect'];
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* `extra-drag-value` on hover-start with a `NULL` action (adw-tab-bar.c: the signal is
|
|
507
|
+
* emitted whenever an item starts hovering, whatever `extra-drag-preload` says), and
|
|
508
|
+
* `extra-drag-preferred-action` is whatever the handler answered with.
|
|
509
|
+
*/
|
|
510
|
+
private _armHoverValue(): void {
|
|
511
|
+
if (this._dropArmed) return;
|
|
512
|
+
this._dropArmed = true;
|
|
513
|
+
const event = new CustomEvent('extra-drag-value', {
|
|
514
|
+
bubbles: true,
|
|
515
|
+
cancelable: true,
|
|
516
|
+
detail: { action: null },
|
|
517
|
+
});
|
|
518
|
+
this.dispatchEvent(event);
|
|
519
|
+
const answer = (event as CustomEvent).detail.action as string | null;
|
|
520
|
+
if (answer !== this._preferredAction) {
|
|
521
|
+
this._preferredAction = answer;
|
|
522
|
+
this.dispatchEvent(
|
|
523
|
+
new CustomEvent('notify::extra-drag-preferred-action', { bubbles: true, detail: { action: answer } }),
|
|
524
|
+
);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
customElements.define('adw-tab-bar', AdwTabBar);
|