@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,155 @@
|
|
|
1
|
+
// DOM-level behaviour tests for the shortcuts trio — <adw-shortcuts-dialog> and the
|
|
2
|
+
// two markup-only objects it holds. Runs in a real browser via the @gjsify/adwaita-web
|
|
3
|
+
// browser test axis (tests/browser Playwright harness).
|
|
4
|
+
//
|
|
5
|
+
// The dialog half is <adw-dialog>'s own spec; what is here is the content model and the
|
|
6
|
+
// rules the C states for an item (adw-shortcuts-item.c:19-28).
|
|
7
|
+
import { describe, expect, it } from '@gjsify/unit';
|
|
8
|
+
|
|
9
|
+
import type { AdwShortcutsDialog } from './elements/adw-shortcuts-dialog.js';
|
|
10
|
+
import type { AdwShortcutsSection } from './elements/adw-shortcuts-section.js';
|
|
11
|
+
|
|
12
|
+
type Item = HTMLElement & { hasAccelerator: boolean; subtitle: string; accelerator: string };
|
|
13
|
+
|
|
14
|
+
function item(title: string, accelerator = '', subtitle = ''): Item {
|
|
15
|
+
const el = document.createElement('adw-shortcuts-item') as Item;
|
|
16
|
+
el.setAttribute('title', title);
|
|
17
|
+
if (accelerator) el.setAttribute('accelerator', accelerator);
|
|
18
|
+
if (subtitle) el.setAttribute('subtitle', subtitle);
|
|
19
|
+
return el;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function section(title: string | null, ...items: Item[]): AdwShortcutsSection {
|
|
23
|
+
const el = document.createElement('adw-shortcuts-section') as AdwShortcutsSection;
|
|
24
|
+
if (title !== null) el.setAttribute('title', title);
|
|
25
|
+
el.append(...items);
|
|
26
|
+
return el;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function dialog(...sections: AdwShortcutsSection[]): AdwShortcutsDialog {
|
|
30
|
+
const el = document.createElement('adw-shortcuts-dialog') as AdwShortcutsDialog;
|
|
31
|
+
el.setAttribute('title', 'Keyboard Shortcuts');
|
|
32
|
+
el.append(...sections);
|
|
33
|
+
document.body.appendChild(el);
|
|
34
|
+
return el;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const AdwShortcutsTest = async () => {
|
|
38
|
+
await describe('adw-shortcuts-dialog is an adw-dialog', async () => {
|
|
39
|
+
await it('carries the dialog chrome and its title', async () => {
|
|
40
|
+
const dlg = dialog(section('General'));
|
|
41
|
+
// The flat header with the close button is the base's, and the class is
|
|
42
|
+
// `dialog.shortcuts` upstream — which is why the element adds it as a class
|
|
43
|
+
// of its own rather than a wrapper element.
|
|
44
|
+
expect(dlg.classList.contains('adw-dialog')).toBe(true);
|
|
45
|
+
expect(dlg.classList.contains('adw-shortcuts-dialog')).toBe(true);
|
|
46
|
+
expect(dlg.querySelector('.adw-dialog-header')).not.toBeNull();
|
|
47
|
+
expect(dlg.querySelector('.adw-dialog-title')?.textContent).toBe('Keyboard Shortcuts');
|
|
48
|
+
dlg.remove();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
await it('presents and closes through the inherited dialog API', async () => {
|
|
52
|
+
const dlg = dialog(section('General'));
|
|
53
|
+
expect(dlg.open).toBe(false);
|
|
54
|
+
dlg.present();
|
|
55
|
+
expect(dlg.open).toBe(true);
|
|
56
|
+
dlg.close();
|
|
57
|
+
expect(dlg.open).toBe(false);
|
|
58
|
+
dlg.remove();
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
await it('holds its sections inside the dialog content area', async () => {
|
|
62
|
+
const dlg = dialog(section('General'), section('Navigation'));
|
|
63
|
+
expect(dlg.sections.length).toBe(2);
|
|
64
|
+
// The sections sit in the base's own content area — no wrapper of this
|
|
65
|
+
// class's own — so the dialog's padding and scrolling wrap them the way
|
|
66
|
+
// they wrap any other child, and a section added later lands there too.
|
|
67
|
+
expect(dlg.sections.every((el) => el.parentElement === dlg.contentArea)).toBe(true);
|
|
68
|
+
dlg.remove();
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
await it('routes a section appended after connect into the content area', async () => {
|
|
72
|
+
const dlg = dialog(section('General'));
|
|
73
|
+
const late = section('Navigation');
|
|
74
|
+
dlg.appendChild(late);
|
|
75
|
+
// The routing is a MutationObserver (`bindSlottedChildren`), so the move is
|
|
76
|
+
// a microtask away rather than synchronous with the append.
|
|
77
|
+
await Promise.resolve();
|
|
78
|
+
expect(dlg.sections.length).toBe(2);
|
|
79
|
+
expect(late.parentElement).toBe(dlg.contentArea);
|
|
80
|
+
dlg.remove();
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
await describe('adw-shortcuts-section', async () => {
|
|
85
|
+
await it('draws a heading only when it has a title', async () => {
|
|
86
|
+
// The class documents an untitled section as the way to subdivide a section
|
|
87
|
+
// into groups, and libadwaita draws no heading for one.
|
|
88
|
+
const titled = section('General', item('Open Menu', 'F10'));
|
|
89
|
+
const untitled = section(null, item('Move Tab Left', '<Shift><Ctrl>Page_Up'));
|
|
90
|
+
document.body.append(titled, untitled);
|
|
91
|
+
|
|
92
|
+
const titledHeading = titled.querySelector('.adw-shortcuts-section-title') as HTMLElement;
|
|
93
|
+
const untitledHeading = untitled.querySelector('.adw-shortcuts-section-title') as HTMLElement;
|
|
94
|
+
expect(titledHeading.hidden).toBe(false);
|
|
95
|
+
expect(untitledHeading.hidden).toBe(true);
|
|
96
|
+
titled.remove();
|
|
97
|
+
untitled.remove();
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
await it('exposes its items in document order', async () => {
|
|
101
|
+
const sec = section('General', item('Open Menu', 'F10'), item('Quit', '<Control>Q'));
|
|
102
|
+
document.body.appendChild(sec);
|
|
103
|
+
expect(sec.items.map((el) => el.getAttribute('title'))).toStrictEqual(['Open Menu', 'Quit']);
|
|
104
|
+
sec.remove();
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
await describe('adw-shortcuts-item', async () => {
|
|
109
|
+
await it('draws the accelerator as keycaps', async () => {
|
|
110
|
+
const el = item('Open Menu', 'F10');
|
|
111
|
+
document.body.appendChild(el);
|
|
112
|
+
const label = el.querySelector('adw-shortcut-label');
|
|
113
|
+
expect(label?.getAttribute('accelerator')).toBe('F10');
|
|
114
|
+
expect(el.hasAccelerator).toBe(true);
|
|
115
|
+
el.remove();
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
await it('draws no keycaps for an item that stands for an action alone', async () => {
|
|
119
|
+
// An accelerator for an action comes from Gtk.Application, which a document
|
|
120
|
+
// has no way to ask, so the row is allowed to carry the action alone.
|
|
121
|
+
const el = item('Preferences');
|
|
122
|
+
el.setAttribute('action-name', 'app.preferences');
|
|
123
|
+
document.body.appendChild(el);
|
|
124
|
+
expect(el.hasAccelerator).toBe(false);
|
|
125
|
+
expect((el.querySelector('adw-shortcut-label') as HTMLElement | null)?.hidden).toBe(true);
|
|
126
|
+
el.remove();
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
await it('draws the subtitle only when there is one', async () => {
|
|
130
|
+
const withSub = item('Move Tab Left', '<Shift><Ctrl>Page_Up', 'Move the current tab');
|
|
131
|
+
const without = item('Quit', '<Control>Q');
|
|
132
|
+
document.body.append(withSub, without);
|
|
133
|
+
const sub = withSub.querySelector('.adw-shortcuts-item-subtitle') as HTMLElement;
|
|
134
|
+
expect(sub.hidden).toBe(false);
|
|
135
|
+
expect(sub.textContent).toBe('Move the current tab');
|
|
136
|
+
expect((without.querySelector('.adw-shortcuts-item-subtitle') as HTMLElement).hidden).toBe(true);
|
|
137
|
+
withSub.remove();
|
|
138
|
+
without.remove();
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
await it('hides a row that belongs to the other text direction', async () => {
|
|
142
|
+
// adw-shortcuts-item.c:25-28 — one dialog carries both an LTR and an RTL
|
|
143
|
+
// accelerator for the same action, and each row shows in its own direction.
|
|
144
|
+
const rtl = item('Move Tab Left', '<Shift><Ctrl>Page_Up');
|
|
145
|
+
rtl.setAttribute('direction', 'rtl');
|
|
146
|
+
const both = item('Quit', '<Control>Q');
|
|
147
|
+
document.body.append(rtl, both);
|
|
148
|
+
// The harness document is LTR, so the RTL row is the one that hides.
|
|
149
|
+
expect(rtl.hidden).toBe(true);
|
|
150
|
+
expect(both.hidden).toBe(false);
|
|
151
|
+
rtl.remove();
|
|
152
|
+
both.remove();
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
};
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
// DOM-level tests for <adw-tab-bar>: the strip libadwaita binds to a view through
|
|
2
|
+
// `Adw.TabBar:view`. Everything under test is derived from a live view, so each case
|
|
3
|
+
// drives the view and reads the bar — the same arrangement `adw-tab-button.spec.ts` uses
|
|
4
|
+
// for the one widget that is also a view's companion.
|
|
5
|
+
import { describe, expect, it } from '@gjsify/unit';
|
|
6
|
+
|
|
7
|
+
import type { AdwTabBar } from './elements/adw-tab-bar.js';
|
|
8
|
+
import type { AdwTabView } from './elements/adw-tab-view.js';
|
|
9
|
+
|
|
10
|
+
const settle = () => new Promise<void>((resolve) => setTimeout(resolve, 0));
|
|
11
|
+
|
|
12
|
+
let serial = 0;
|
|
13
|
+
|
|
14
|
+
/** A view with `titles`, a bar bound to it BY ID, and the action widgets' slots empty. */
|
|
15
|
+
function mount(titles: readonly string[]): { bar: AdwTabBar; view: AdwTabView; host: HTMLElement } {
|
|
16
|
+
const id = `bar-view-${(serial += 1)}`;
|
|
17
|
+
const host = document.createElement('div');
|
|
18
|
+
const pages = titles.map((title) => `<adw-tab-page title="${title}"></adw-tab-page>`).join('');
|
|
19
|
+
host.innerHTML = `<adw-tab-view id="${id}">${pages}</adw-tab-view><adw-tab-bar view="${id}"></adw-tab-bar>`;
|
|
20
|
+
document.body.appendChild(host);
|
|
21
|
+
return {
|
|
22
|
+
bar: host.querySelector('adw-tab-bar') as AdwTabBar,
|
|
23
|
+
view: host.querySelector('adw-tab-view') as AdwTabView,
|
|
24
|
+
host,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const chips = (bar: AdwTabBar) => [...bar.querySelectorAll('.adw-tab')] as HTMLElement[];
|
|
29
|
+
const chipTitles = (bar: AdwTabBar) => chips(bar).map((chip) => chip.querySelector('.adw-tab-title')?.textContent);
|
|
30
|
+
|
|
31
|
+
export const AdwTabBarTest = async () => {
|
|
32
|
+
await describe('<adw-tab-bar> binds to a view', async () => {
|
|
33
|
+
await it('resolves `view` by element id and draws one chip per page', async () => {
|
|
34
|
+
const { bar, view, host } = mount(['One', 'Two', 'Three']);
|
|
35
|
+
expect(bar.view).toBe(view);
|
|
36
|
+
expect(chipTitles(bar)).toStrictEqual(['One', 'Two', 'Three']);
|
|
37
|
+
host.remove();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
await it('takes the view directly through the property', async () => {
|
|
41
|
+
const view = document.createElement('adw-tab-view') as AdwTabView;
|
|
42
|
+
document.body.appendChild(view);
|
|
43
|
+
view.appendPage({ id: 'a', title: 'A' });
|
|
44
|
+
const bar = document.createElement('adw-tab-bar') as AdwTabBar;
|
|
45
|
+
document.body.appendChild(bar);
|
|
46
|
+
bar.view = view;
|
|
47
|
+
expect(bar.view).toBe(view);
|
|
48
|
+
expect(chipTitles(bar)).toStrictEqual(['A']);
|
|
49
|
+
bar.remove();
|
|
50
|
+
view.remove();
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
await it('follows pages added, removed and reordered after connect', async () => {
|
|
54
|
+
const { bar, view, host } = mount(['One', 'Two']);
|
|
55
|
+
const first = view.pages[0].id;
|
|
56
|
+
view.appendPage({ id: 'three', title: 'Three' });
|
|
57
|
+
expect(chipTitles(bar)).toStrictEqual(['One', 'Two', 'Three']);
|
|
58
|
+
view.reorderPage('three', 0);
|
|
59
|
+
expect(chipTitles(bar)).toStrictEqual(['Three', 'One', 'Two']);
|
|
60
|
+
view.closePage(first);
|
|
61
|
+
expect(chipTitles(bar)).toStrictEqual(['Three', 'Two']);
|
|
62
|
+
host.remove();
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
await it('reflects a title change without rebuilding the chip', async () => {
|
|
66
|
+
const { bar, view, host } = mount(['One']);
|
|
67
|
+
const chip = chips(bar)[0];
|
|
68
|
+
view.setPageTitle(view.pages[0].id, 'Renamed');
|
|
69
|
+
expect(chips(bar)[0]).toBe(chip);
|
|
70
|
+
expect(chip.querySelector('.adw-tab-title')?.textContent).toBe('Renamed');
|
|
71
|
+
host.remove();
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
await describe('<adw-tab-bar> selection', async () => {
|
|
76
|
+
await it('marks the selected chip and moves the roving tabindex with it', async () => {
|
|
77
|
+
const { bar, view, host } = mount(['One', 'Two']);
|
|
78
|
+
expect(chips(bar).map((chip) => chip.classList.contains('active'))).toStrictEqual([true, false]);
|
|
79
|
+
expect(chips(bar).map((chip) => chip.tabIndex)).toStrictEqual([0, -1]);
|
|
80
|
+
|
|
81
|
+
view.selectNthPage(1);
|
|
82
|
+
expect(chips(bar).map((chip) => chip.classList.contains('active'))).toStrictEqual([false, true]);
|
|
83
|
+
expect(chips(bar).map((chip) => chip.tabIndex)).toStrictEqual([-1, 0]);
|
|
84
|
+
expect(chips(bar).map((chip) => chip.getAttribute('aria-selected'))).toStrictEqual(['false', 'true']);
|
|
85
|
+
host.remove();
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
await it('selects on a chip press and closes on the close affordance', async () => {
|
|
89
|
+
const { bar, view, host } = mount(['One', 'Two']);
|
|
90
|
+
const second = view.pages[1].id;
|
|
91
|
+
chips(bar)[1].dispatchEvent(new MouseEvent('click', { bubbles: true }));
|
|
92
|
+
expect(view.selectedId).toBe(second);
|
|
93
|
+
|
|
94
|
+
const close = chips(bar)[1].querySelector('.adw-tab-close') as HTMLElement;
|
|
95
|
+
// The close affordance is hidden until the tab is hovered or selected, and this
|
|
96
|
+
// one is the selected tab, so `tabCloseVisible` shows it on its own.
|
|
97
|
+
expect(close.hidden).toBe(false);
|
|
98
|
+
close.dispatchEvent(new MouseEvent('click', { bubbles: true }));
|
|
99
|
+
expect(chipTitles(bar)).toStrictEqual(['One']);
|
|
100
|
+
host.remove();
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
await it('ArrowRight and End move the selection from the keyboard', async () => {
|
|
104
|
+
const { bar, view, host } = mount(['One', 'Two', 'Three']);
|
|
105
|
+
const ids = view.pages.map((page) => page.id);
|
|
106
|
+
chips(bar)[0].dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight', bubbles: true }));
|
|
107
|
+
expect(view.selectedId).toBe(ids[1]);
|
|
108
|
+
chips(bar)[1].dispatchEvent(new KeyboardEvent('keydown', { key: 'End', bubbles: true }));
|
|
109
|
+
expect(view.selectedId).toBe(ids[2]);
|
|
110
|
+
host.remove();
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
await describe('<adw-tab-bar> tabs-revealed', async () => {
|
|
115
|
+
await it('is up without `autohide`, whatever the page count', async () => {
|
|
116
|
+
const { bar, host } = mount(['One']);
|
|
117
|
+
expect(bar.tabsRevealed).toBe(true);
|
|
118
|
+
expect(bar.hidden).toBe(false);
|
|
119
|
+
host.remove();
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
await it('hides with `autohide` on a single page and comes back for two', async () => {
|
|
123
|
+
const { bar, view, host } = mount(['One']);
|
|
124
|
+
bar.autohide = true;
|
|
125
|
+
// `tabsRevealed` reads the LIVE attribute, so the write is the whole input.
|
|
126
|
+
expect(bar.tabsRevealed).toBe(false);
|
|
127
|
+
expect(bar.hidden).toBe(true);
|
|
128
|
+
|
|
129
|
+
view.appendPage({ id: 'two', title: 'Two' });
|
|
130
|
+
expect(bar.tabsRevealed).toBe(true);
|
|
131
|
+
expect(bar.hidden).toBe(false);
|
|
132
|
+
host.remove();
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
await it('stays up with `autohide` on a single PINNED page', async () => {
|
|
136
|
+
const { bar, host } = mount(['Pinned']);
|
|
137
|
+
bar.autohide = true;
|
|
138
|
+
const page = bar.view?.pages[0];
|
|
139
|
+
expect(page?.pinned).toBe(false);
|
|
140
|
+
// A declared `<adw-tab-page>` with no `page-id` gets a generated one, which an
|
|
141
|
+
// author cannot predict — so the pin goes in through the page's own id.
|
|
142
|
+
bar.view?.setPagePinned(page?.id ?? '', true);
|
|
143
|
+
expect(bar.tabsRevealed).toBe(true);
|
|
144
|
+
expect(bar.hidden).toBe(false);
|
|
145
|
+
host.remove();
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
await describe('<adw-tab-bar> properties', async () => {
|
|
150
|
+
await it('carries expand-tabs and inverted as attributes, and says so', async () => {
|
|
151
|
+
const { bar, host } = mount(['One', 'Two']);
|
|
152
|
+
expect(bar.expandTabs).toBe(false);
|
|
153
|
+
expect(bar.inverted).toBe(false);
|
|
154
|
+
bar.expandTabs = true;
|
|
155
|
+
bar.inverted = true;
|
|
156
|
+
expect(bar.hasAttribute('expand-tabs')).toBe(true);
|
|
157
|
+
expect(bar.hasAttribute('inverted')).toBe(true);
|
|
158
|
+
host.remove();
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
await it('notifies each property on a real change', async () => {
|
|
162
|
+
const { bar, host } = mount(['One']);
|
|
163
|
+
const seen: string[] = [];
|
|
164
|
+
for (const name of ['autohide', 'expand-tabs', 'inverted', 'extra-drag-preload']) {
|
|
165
|
+
bar.addEventListener(`notify::${name}`, () => seen.push(name));
|
|
166
|
+
}
|
|
167
|
+
bar.autohide = true;
|
|
168
|
+
bar.inverted = true;
|
|
169
|
+
expect(seen).toStrictEqual(['autohide', 'inverted']);
|
|
170
|
+
host.remove();
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
await it('notifies `view` when it is rebound', async () => {
|
|
174
|
+
const { bar, view, host } = mount(['One']);
|
|
175
|
+
let notified = false;
|
|
176
|
+
bar.addEventListener('notify::view', () => (notified = true));
|
|
177
|
+
const other = document.createElement('adw-tab-view') as AdwTabView;
|
|
178
|
+
document.body.appendChild(other);
|
|
179
|
+
other.appendPage({ id: 'z', title: 'Z' });
|
|
180
|
+
bar.setView(other);
|
|
181
|
+
expect(notified).toBe(true);
|
|
182
|
+
expect(chipTitles(bar)).toStrictEqual(['Z']);
|
|
183
|
+
bar.setView(view);
|
|
184
|
+
expect(chipTitles(bar)).toStrictEqual(['One']);
|
|
185
|
+
other.remove();
|
|
186
|
+
host.remove();
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
await describe('<adw-tab-bar> action widgets', async () => {
|
|
191
|
+
await it('routes a `slot="start-action-widget"` child into the leading bin', async () => {
|
|
192
|
+
const { bar, host } = mount(['One']);
|
|
193
|
+
const button = document.createElement('button');
|
|
194
|
+
button.slot = 'start-action-widget';
|
|
195
|
+
// Appended AFTER connect on purpose: `bindSlottedChildren` observes the host, so
|
|
196
|
+
// a late child lands where a parse-time one would — on the observer's microtask,
|
|
197
|
+
// which is why the read below waits for one.
|
|
198
|
+
bar.appendChild(button);
|
|
199
|
+
await settle();
|
|
200
|
+
expect(bar.startActionWidget).toBe(button);
|
|
201
|
+
expect(bar.querySelector('.adw-tab-bar-start-action button')).toBe(button);
|
|
202
|
+
// The bin leads the box, which is the order `AdwTabBar`'s template puts the two
|
|
203
|
+
// action bins in (adw-tab-bar.ui).
|
|
204
|
+
expect(bar.querySelector('.adw-tab-box')?.previousElementSibling).toBe(
|
|
205
|
+
bar.querySelector('.adw-tab-bar-start-action'),
|
|
206
|
+
);
|
|
207
|
+
host.remove();
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
await it('routes a `slot="end-action-widget"` child into the trailing bin', async () => {
|
|
211
|
+
const { bar, host } = mount(['One']);
|
|
212
|
+
const button = document.createElement('button');
|
|
213
|
+
button.slot = 'end-action-widget';
|
|
214
|
+
bar.appendChild(button);
|
|
215
|
+
await settle();
|
|
216
|
+
expect(bar.endActionWidget).toBe(button);
|
|
217
|
+
expect(bar.querySelector('.adw-tab-bar-end-action button')).toBe(button);
|
|
218
|
+
host.remove();
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
await it('takes an action widget through the property too', async () => {
|
|
222
|
+
const { bar, host } = mount(['One']);
|
|
223
|
+
const button = document.createElement('button');
|
|
224
|
+
bar.endActionWidget = button;
|
|
225
|
+
expect(bar.querySelector('.adw-tab-bar-end-action')?.lastElementChild).toBe(button);
|
|
226
|
+
bar.endActionWidget = null;
|
|
227
|
+
expect(bar.endActionWidget).toBe(null);
|
|
228
|
+
host.remove();
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
await describe('<adw-tab-bar> overflow and the extra drop target', async () => {
|
|
233
|
+
await it('reports `is-overflowing` off the strip, not off the chip count', async () => {
|
|
234
|
+
const { bar, host } = mount(['One', 'Two']);
|
|
235
|
+
// Nothing is scrolled yet, so the strip fits its chips and does NOT overflow:
|
|
236
|
+
// the indicator is the adjustment's answer, not a threshold on `nPages`.
|
|
237
|
+
expect(bar.isOverflowing).toBe(false);
|
|
238
|
+
expect((bar.querySelector('.adw-tab-box-overflow') as HTMLElement).hidden).toBe(true);
|
|
239
|
+
host.remove();
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
await it('dispatches `extra-drag-value` on hover-start and carries the action back', async () => {
|
|
243
|
+
const { bar, host } = mount(['One']);
|
|
244
|
+
bar.setupExtraDropTarget(['text/plain']);
|
|
245
|
+
let seen: unknown = 'unset';
|
|
246
|
+
bar.addEventListener('extra-drag-value', (event) => {
|
|
247
|
+
seen = (event as CustomEvent).detail.action;
|
|
248
|
+
(event as CustomEvent).detail.action = 'move';
|
|
249
|
+
});
|
|
250
|
+
const transfer = new DataTransfer();
|
|
251
|
+
transfer.setData('text/plain', 'payload');
|
|
252
|
+
bar.dispatchEvent(new DragEvent('dragover', { dataTransfer: transfer, bubbles: true, cancelable: true }));
|
|
253
|
+
// Hover-start emits a NULL action, and `extra-drag-preferred-action` is whatever
|
|
254
|
+
// the handler answered with.
|
|
255
|
+
expect(seen).toBe(null);
|
|
256
|
+
expect(bar.extraDragPreferredAction).toBe('move');
|
|
257
|
+
host.remove();
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
await it('dispatches a cancelable `extra-drag-drop` carrying the dropped data', async () => {
|
|
261
|
+
const { bar, host } = mount(['One']);
|
|
262
|
+
bar.setupExtraDropTarget(['text/plain'], ['copy']);
|
|
263
|
+
let detail: { action: unknown; data: unknown } | null = null;
|
|
264
|
+
bar.addEventListener('extra-drag-drop', (event) => {
|
|
265
|
+
detail = (event as CustomEvent).detail;
|
|
266
|
+
});
|
|
267
|
+
const transfer = new DataTransfer();
|
|
268
|
+
transfer.setData('text/plain', 'payload');
|
|
269
|
+
bar.dispatchEvent(new DragEvent('drop', { dataTransfer: transfer, bubbles: true, cancelable: true }));
|
|
270
|
+
expect(detail?.data).toBe('payload');
|
|
271
|
+
expect(detail?.action).toBe('copy');
|
|
272
|
+
host.remove();
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
await it('leaves a drop of an unlisted type to the page', async () => {
|
|
276
|
+
const { bar, host } = mount(['One']);
|
|
277
|
+
bar.setupExtraDropTarget(['text/plain']);
|
|
278
|
+
let dropped = false;
|
|
279
|
+
bar.addEventListener('extra-drag-drop', () => (dropped = true));
|
|
280
|
+
const transfer = new DataTransfer();
|
|
281
|
+
transfer.setData('application/x-elsewhere', 'payload');
|
|
282
|
+
bar.dispatchEvent(new DragEvent('drop', { dataTransfer: transfer, bubbles: true, cancelable: true }));
|
|
283
|
+
expect(dropped).toBe(false);
|
|
284
|
+
host.remove();
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// DOM-level tests for <adw-tab-button>: the page counter (`update_icon`,
|
|
2
|
+
// adw-tab-button.c:102-133) and the attention dot (`update_needs_attention`,
|
|
3
|
+
// adw-tab-button.c:135-161). The counter is DERIVED from a view, so every test drives the
|
|
4
|
+
// view and reads the button.
|
|
5
|
+
import { describe, expect, it } from '@gjsify/unit';
|
|
6
|
+
|
|
7
|
+
import type { AdwTabButton } from './elements/adw-tab-button.js';
|
|
8
|
+
import type { AdwTabView } from './elements/adw-tab-view.js';
|
|
9
|
+
|
|
10
|
+
const settle = () => new Promise<void>((resolve) => setTimeout(resolve, 0));
|
|
11
|
+
|
|
12
|
+
let serial = 0;
|
|
13
|
+
|
|
14
|
+
function mount(pages: number): { button: AdwTabButton; view: AdwTabView; host: HTMLElement } {
|
|
15
|
+
const id = `tb-view-${(serial += 1)}`;
|
|
16
|
+
const host = document.createElement('div');
|
|
17
|
+
const rows = Array.from({ length: pages }, (_, i) => `<adw-tab-page title="Page ${i}"></adw-tab-page>`);
|
|
18
|
+
host.innerHTML = `<adw-tab-view id="${id}">${rows.join('')}</adw-tab-view><adw-tab-button view="${id}"></adw-tab-button>`;
|
|
19
|
+
document.body.appendChild(host);
|
|
20
|
+
return {
|
|
21
|
+
button: host.querySelector('adw-tab-button') as AdwTabButton,
|
|
22
|
+
view: host.querySelector('adw-tab-view') as AdwTabView,
|
|
23
|
+
host,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const label = (button: AdwTabButton) => button.querySelector('.adw-tab-button-label') as HTMLElement;
|
|
28
|
+
const dot = (button: AdwTabButton) => button.querySelector('.adw-tab-button-indicator') as HTMLElement;
|
|
29
|
+
|
|
30
|
+
export const AdwTabButtonTest = async () => {
|
|
31
|
+
await describe('<adw-tab-button> counter', async () => {
|
|
32
|
+
await it('shows the page count of the view it is bound to', async () => {
|
|
33
|
+
const { button, view, host } = mount(3);
|
|
34
|
+
expect(button.view).toBe(view);
|
|
35
|
+
expect(label(button).textContent).toBe('3');
|
|
36
|
+
expect(label(button).classList.contains('small')).toBe(false);
|
|
37
|
+
host.remove();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
await it('follows pages added and removed', async () => {
|
|
41
|
+
const { button, view, host } = mount(2);
|
|
42
|
+
// A page added after the view connected goes through its API: declared
|
|
43
|
+
// `<adw-tab-page>` children are adopted on connect only.
|
|
44
|
+
view.appendPage({ id: 'late', title: 'Late' });
|
|
45
|
+
expect(label(button).textContent).toBe('3');
|
|
46
|
+
view.closePage('late');
|
|
47
|
+
expect(label(button).textContent).toBe('2');
|
|
48
|
+
host.remove();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
await it('is `small` from ten pages and a glyph instead of a number from a hundred', async () => {
|
|
52
|
+
const ten = mount(10);
|
|
53
|
+
expect(label(ten.button).textContent).toBe('10');
|
|
54
|
+
expect(label(ten.button).classList.contains('small')).toBe(true);
|
|
55
|
+
ten.host.remove();
|
|
56
|
+
|
|
57
|
+
const hundred = mount(100);
|
|
58
|
+
expect(label(hundred.button).hidden).toBe(true);
|
|
59
|
+
expect(hundred.button.querySelector('.adw-tab-button-indicatorbin')?.classList.contains('overflow')).toBe(
|
|
60
|
+
true,
|
|
61
|
+
);
|
|
62
|
+
hundred.host.remove();
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
await it('without a view the plate stays, with a zero on it', async () => {
|
|
66
|
+
const host = document.createElement('div');
|
|
67
|
+
host.innerHTML = '<adw-tab-button></adw-tab-button>';
|
|
68
|
+
document.body.appendChild(host);
|
|
69
|
+
const button = host.firstElementChild as AdwTabButton;
|
|
70
|
+
expect(button.view).toBeNull();
|
|
71
|
+
expect(label(button).textContent).toBe('0');
|
|
72
|
+
host.remove();
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
await describe('<adw-tab-button> needs-attention', async () => {
|
|
77
|
+
await it('lights up for a page that is NOT the selected one', async () => {
|
|
78
|
+
const { button, view, host } = mount(3);
|
|
79
|
+
expect(dot(button).hidden).toBe(true);
|
|
80
|
+
view.querySelectorAll('adw-tab-page')[2].setAttribute('needs-attention', '');
|
|
81
|
+
await settle();
|
|
82
|
+
expect(dot(button).hidden).toBe(false);
|
|
83
|
+
host.remove();
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
await it('ignores the selected page, which is already in front of the user', async () => {
|
|
87
|
+
const { button, view, host } = mount(3);
|
|
88
|
+
view.querySelectorAll('adw-tab-page')[0].setAttribute('needs-attention', '');
|
|
89
|
+
await settle();
|
|
90
|
+
expect(dot(button).hidden).toBe(true);
|
|
91
|
+
host.remove();
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
await it('is a real button the platform activates', async () => {
|
|
95
|
+
const { button, host } = mount(1);
|
|
96
|
+
expect(button.getAttribute('role')).toBe('button');
|
|
97
|
+
expect(button.querySelector('button')).not.toBeNull();
|
|
98
|
+
host.remove();
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
};
|