@gjsify/adwaita-web 0.54.0 → 0.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adwaita-web.css +8066 -3033
- 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 +1 -1
- 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/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,320 @@
|
|
|
1
|
+
// <gtk-column-view> — the list view with columns and a header, the web counterpart of
|
|
2
|
+
// `Gtk.ColumnView`.
|
|
3
|
+
//
|
|
4
|
+
// IT EXTENDS `<gtk-list-view>` BECAUSE UPSTREAM DOES THE SAME THING ONE LAYER DOWN. A
|
|
5
|
+
// `GtkColumnView` is not a `GtkListBase`, but its own CSS node tree says where its rows
|
|
6
|
+
// come from — `columnview > header` plus `columnview > listview > row > cell`
|
|
7
|
+
// (gtkcolumnview.c) — and `show-row-separators` is passed STRAIGHT THROUGH to that inner
|
|
8
|
+
// list view. So the model, the factory, the splice, the selection and the rubberband are
|
|
9
|
+
// the base element's, and what is added here is the header and the cells.
|
|
10
|
+
//
|
|
11
|
+
// A COLUMN DRAWS ONE PORTABLE FIELD, OR ITS OWN FACTORY. Upstream a column pulls whatever
|
|
12
|
+
// its factory wants off an arbitrary GObject; a portable item is `value` and `label` and
|
|
13
|
+
// nothing else by contract (ADR 0046 § 2), so `key` chooses between those two and anything
|
|
14
|
+
// richer is a `factory` — which is what GTK demands of every column anyway. Two columns
|
|
15
|
+
// over `label` and `value` is the name/id table this makes directly authorable, and it is
|
|
16
|
+
// what the gallery block shows.
|
|
17
|
+
//
|
|
18
|
+
// SORTING IS STATE, NOT AN ORDERING, and that is upstream's division of labour rather
|
|
19
|
+
// than a shortfall: `gtk_column_view_get_sorter` hands an app a `GtkSorter` to put on a
|
|
20
|
+
// `GtkSortListModel`, and the view itself never reorders anything. So a click on a
|
|
21
|
+
// sortable header runs `columnViewSort` — `gtk_column_view_sorter_add_column`'s rule, a
|
|
22
|
+
// second click on the primary column inverting it — moves the indicator and emits
|
|
23
|
+
// `notify::sorter`. The consumer re-assigns `model`, and the splice puts the rows where
|
|
24
|
+
// the new order wants them.
|
|
25
|
+
//
|
|
26
|
+
// Attributes: model, selection-mode, single-click-activate, enable-rubberband,
|
|
27
|
+
// tab-behavior (the base element's), plus `columns` (JSON), `show-row-separators`,
|
|
28
|
+
// `show-column-separators` and `reorderable`, which are `Gtk.ColumnView`'s own.
|
|
29
|
+
// Properties: everything `<gtk-list-view>` publishes, plus columns, sorter, reorderable,
|
|
30
|
+
// showRowSeparators, showColumnSeparators.
|
|
31
|
+
// Events: `activate`, `notify::selected` (the base element's), and `notify::sorter`
|
|
32
|
+
// (CustomEvent, bubbles, detail = { sorter }).
|
|
33
|
+
// A11Y: `grid` with `row`, `columnheader` and `gridcell`. GTK declares `TREE_GRID`
|
|
34
|
+
// (gtkcolumnview.c) because a column view may hold `Gtk.TreeExpander`s; the port
|
|
35
|
+
// announces the non-tree role and `<gtk-tree-expander>` contributes the `aria-level`
|
|
36
|
+
// and `aria-expanded` of any row that is a tree row, so a flat table does not promise
|
|
37
|
+
// a hierarchy it has not got.
|
|
38
|
+
//
|
|
39
|
+
// Reference: refs/gtk/gtk/gtkcolumnview.c (the widget, its CSS nodes and its roles)
|
|
40
|
+
// Reference: refs/gtk/gtk/gtkcolumnviewsorter.c:294-344 (the header-click rule)
|
|
41
|
+
// Reference: refs/libadwaita/src/stylesheet/widgets/_column-view.scss:1-112
|
|
42
|
+
// Copyright (c) GNOME contributors (GTK/libadwaita). LGPLv2.1+.
|
|
43
|
+
// Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
|
|
44
|
+
|
|
45
|
+
import {
|
|
46
|
+
columnViewSort,
|
|
47
|
+
columnViewTracks,
|
|
48
|
+
dataGridTrackTemplate,
|
|
49
|
+
listItemField,
|
|
50
|
+
normalizeColumnViewColumns,
|
|
51
|
+
parseColumnViewColumns,
|
|
52
|
+
type AdwColumnViewColumn,
|
|
53
|
+
type AdwColumnViewSort,
|
|
54
|
+
type AdwListItemContext,
|
|
55
|
+
type AdwListItemFactory,
|
|
56
|
+
} from '@gjsify/adwaita-core';
|
|
57
|
+
|
|
58
|
+
import { LIST_ITEM_LABEL_CLASS } from '../list-view-dom.js';
|
|
59
|
+
|
|
60
|
+
import { createGtkImage } from './gtk-image.js';
|
|
61
|
+
import { GtkListView } from './gtk-list-view.js';
|
|
62
|
+
|
|
63
|
+
/** A per-column renderer — `Gtk.ColumnViewColumn:factory`, keyed by the column's id. */
|
|
64
|
+
export type GtkColumnViewFactories = Readonly<Record<string, AdwListItemFactory<Node>>>;
|
|
65
|
+
|
|
66
|
+
export class GtkColumnView extends GtkListView {
|
|
67
|
+
private _headerEl!: HTMLDivElement;
|
|
68
|
+
private _columns: AdwColumnViewColumn[] = [];
|
|
69
|
+
private _factories: GtkColumnViewFactories = {};
|
|
70
|
+
private _sorter: AdwColumnViewSort | null = null;
|
|
71
|
+
private _dragged: string | null = null;
|
|
72
|
+
|
|
73
|
+
static get observedAttributes() {
|
|
74
|
+
return [
|
|
75
|
+
'model',
|
|
76
|
+
'columns',
|
|
77
|
+
'selection-mode',
|
|
78
|
+
'single-click-activate',
|
|
79
|
+
'enable-rubberband',
|
|
80
|
+
'tab-behavior',
|
|
81
|
+
'show-row-separators',
|
|
82
|
+
'show-column-separators',
|
|
83
|
+
'reorderable',
|
|
84
|
+
];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** `Gtk.ColumnView:columns`, as descriptors rather than as a read-only `Gio.ListModel`. */
|
|
88
|
+
get columns(): AdwColumnViewColumn[] {
|
|
89
|
+
return this._columns.map((column) => ({ ...column }));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
set columns(value: readonly AdwColumnViewColumn[] | null) {
|
|
93
|
+
this._columns = normalizeColumnViewColumns(value);
|
|
94
|
+
this._renderHeader();
|
|
95
|
+
this._renderRows();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** Per-column factories, keyed by `Gtk.ColumnViewColumn:id`. */
|
|
99
|
+
get columnFactories(): GtkColumnViewFactories {
|
|
100
|
+
return this._factories;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
set columnFactories(value: GtkColumnViewFactories | null) {
|
|
104
|
+
this._factories = value ?? {};
|
|
105
|
+
this._renderRows();
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** `gtk_column_view_get_sorter`'s state — which column, which direction. */
|
|
109
|
+
get sorter(): AdwColumnViewSort | null {
|
|
110
|
+
return this._sorter === null ? null : { ...this._sorter };
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
set sorter(value: AdwColumnViewSort | null) {
|
|
114
|
+
this._applySorter(value);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
get showRowSeparators(): boolean {
|
|
118
|
+
return this.hasAttribute('show-row-separators');
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
set showRowSeparators(value: boolean) {
|
|
122
|
+
this.toggleAttribute('show-row-separators', !!value);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
get showColumnSeparators(): boolean {
|
|
126
|
+
return this.hasAttribute('show-column-separators');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
set showColumnSeparators(value: boolean) {
|
|
130
|
+
this.toggleAttribute('show-column-separators', !!value);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
get reorderable(): boolean {
|
|
134
|
+
return this.hasAttribute('reorderable');
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
set reorderable(value: boolean) {
|
|
138
|
+
this.toggleAttribute('reorderable', !!value);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
connectedCallback() {
|
|
142
|
+
// ONCE, not per connect: a re-parent runs this again, and building a second header
|
|
143
|
+
// left the view with two of them — caught by the re-parent suite, which compares
|
|
144
|
+
// the subtree before and after a move.
|
|
145
|
+
const first = this._headerEl === undefined;
|
|
146
|
+
if (first) {
|
|
147
|
+
this._columns = parseColumnViewColumns(this.getAttribute('columns'));
|
|
148
|
+
this._headerEl = document.createElement('div');
|
|
149
|
+
this._headerEl.className = 'adw-column-view-header';
|
|
150
|
+
this._headerEl.setAttribute('role', 'row');
|
|
151
|
+
}
|
|
152
|
+
super.connectedCallback();
|
|
153
|
+
// Before the rows, as `columnview > header` precedes `columnview > listview`.
|
|
154
|
+
if (first) this.insertBefore(this._headerEl, this.firstChild);
|
|
155
|
+
this._renderHeader();
|
|
156
|
+
this._renderRows();
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
attributeChangedCallback(name?: string) {
|
|
160
|
+
if (name === 'columns') {
|
|
161
|
+
this._columns = parseColumnViewColumns(this.getAttribute('columns'));
|
|
162
|
+
this._renderHeader();
|
|
163
|
+
this._renderRows();
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
super.attributeChangedCallback(name);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
protected override _applyAttributes(): void {
|
|
170
|
+
super._applyAttributes();
|
|
171
|
+
// `show-row-separators` is passed to the inner list view, which is what wears
|
|
172
|
+
// `.separators`; `show-column-separators` is the column view's own class.
|
|
173
|
+
this.classList.toggle('separators', this.showRowSeparators);
|
|
174
|
+
this.classList.toggle('column-separators', this.showColumnSeparators);
|
|
175
|
+
this.setAttribute('role', 'grid');
|
|
176
|
+
this.removeAttribute('aria-multiselectable');
|
|
177
|
+
// `Gtk.ColumnView` derives from `Gtk.Widget`, not `Gtk.ListBase`, and implements no
|
|
178
|
+
// `GtkOrientable`: its rows always run down and its columns across. So the axis
|
|
179
|
+
// class the base element carries is dropped rather than inherited, and
|
|
180
|
+
// `observedAttributes` above lists no `orientation` for an author to set.
|
|
181
|
+
this.classList.remove('horizontal');
|
|
182
|
+
if (this._headerEl !== undefined) this._applyTracks(this._headerEl);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
protected override get _viewClass(): string {
|
|
186
|
+
return 'adw-column-view';
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
protected override get _rowClass(): string {
|
|
190
|
+
return 'adw-column-view-row';
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
protected override _createRow(position: number): HTMLElement | null {
|
|
194
|
+
const row = super._createRow(position);
|
|
195
|
+
if (row === null) return null;
|
|
196
|
+
row.setAttribute('role', 'row');
|
|
197
|
+
// The base element put the factory's node straight into the row; a column view
|
|
198
|
+
// puts one `cell` per column there instead.
|
|
199
|
+
row.replaceChildren();
|
|
200
|
+
const context = this._state.itemContext(position);
|
|
201
|
+
if (context !== null) {
|
|
202
|
+
for (const column of this._columns) {
|
|
203
|
+
if (column.visible === false) continue;
|
|
204
|
+
row.appendChild(this._createCell(column, context));
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
this._applyTracks(row);
|
|
208
|
+
return row;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/** One `cell`: the column's own factory, or the portable field its `key` names. */
|
|
212
|
+
private _createCell(column: AdwColumnViewColumn, context: AdwListItemContext): HTMLElement {
|
|
213
|
+
const cell = document.createElement('div');
|
|
214
|
+
cell.className = 'adw-column-view-cell';
|
|
215
|
+
cell.setAttribute('role', 'gridcell');
|
|
216
|
+
const factory = this._factories[column.id ?? column.key];
|
|
217
|
+
if (factory !== undefined) {
|
|
218
|
+
cell.appendChild(factory(context));
|
|
219
|
+
} else {
|
|
220
|
+
const label = document.createElement('span');
|
|
221
|
+
label.className = LIST_ITEM_LABEL_CLASS;
|
|
222
|
+
label.textContent = listItemField(context.item, column.key);
|
|
223
|
+
cell.appendChild(label);
|
|
224
|
+
}
|
|
225
|
+
return cell;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/** The header row — one button per visible column, with its sort indicator. */
|
|
229
|
+
private _renderHeader(): void {
|
|
230
|
+
if (this._headerEl === undefined) return;
|
|
231
|
+
this._headerEl.replaceChildren();
|
|
232
|
+
for (const column of this._columns) {
|
|
233
|
+
if (column.visible === false) continue;
|
|
234
|
+
this._headerEl.appendChild(this._createHeaderCell(column));
|
|
235
|
+
}
|
|
236
|
+
this._applyTracks(this._headerEl);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
private _createHeaderCell(column: AdwColumnViewColumn): HTMLElement {
|
|
240
|
+
const id = column.id ?? column.key;
|
|
241
|
+
const button = document.createElement('button');
|
|
242
|
+
button.type = 'button';
|
|
243
|
+
button.className = 'adw-column-view-header-cell';
|
|
244
|
+
button.setAttribute('role', 'columnheader');
|
|
245
|
+
button.dataset.columnId = id;
|
|
246
|
+
|
|
247
|
+
const text = document.createElement('span');
|
|
248
|
+
text.className = 'adw-column-view-header-title';
|
|
249
|
+
text.textContent = column.title ?? column.key;
|
|
250
|
+
button.appendChild(text);
|
|
251
|
+
|
|
252
|
+
if (column.sortable === true) {
|
|
253
|
+
const sorted = this._sorter !== null && this._sorter.column === id;
|
|
254
|
+
// libadwaita draws `pan-up-symbolic` / `pan-down-symbolic` in a
|
|
255
|
+
// `sort-indicator` node (_column-view.scss:52-62); this package's icon subset
|
|
256
|
+
// carries `go-down`, and `.ascending` turns it over — the same substitution
|
|
257
|
+
// `<adw-expander-row>` makes for its chevron.
|
|
258
|
+
const indicator = createGtkImage('go-down', 'adw-column-view-sort-indicator');
|
|
259
|
+
indicator.classList.toggle('ascending', sorted && !this._sorter!.descending);
|
|
260
|
+
indicator.classList.toggle('descending', sorted && this._sorter!.descending);
|
|
261
|
+
indicator.hidden = !sorted;
|
|
262
|
+
button.appendChild(indicator);
|
|
263
|
+
button.setAttribute('aria-sort', sorted ? (this._sorter!.descending ? 'descending' : 'ascending') : 'none');
|
|
264
|
+
button.addEventListener('click', () => this._applySorter(columnViewSort(this._sorter, column)));
|
|
265
|
+
} else {
|
|
266
|
+
button.disabled = true;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
if (this.reorderable) this._makeDraggable(button, id);
|
|
270
|
+
return button;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Column reordering by dragging a header — `Gtk.ColumnView:reorderable`.
|
|
275
|
+
*
|
|
276
|
+
* The HTML drag-and-drop events rather than a pointer drag, because the header is a
|
|
277
|
+
* `<button>` and a pointer drag would have to suppress its own click; `draggable`
|
|
278
|
+
* suppresses it for us, which is also what keeps a drag from sorting the column it
|
|
279
|
+
* started on.
|
|
280
|
+
*/
|
|
281
|
+
private _makeDraggable(button: HTMLElement, id: string): void {
|
|
282
|
+
button.draggable = true;
|
|
283
|
+
button.addEventListener('dragstart', (event) => {
|
|
284
|
+
this._dragged = id;
|
|
285
|
+
(event as DragEvent).dataTransfer?.setData('text/plain', id);
|
|
286
|
+
});
|
|
287
|
+
button.addEventListener('dragover', (event) => event.preventDefault());
|
|
288
|
+
button.addEventListener('drop', (event) => {
|
|
289
|
+
event.preventDefault();
|
|
290
|
+
const from = this._columns.findIndex((column) => (column.id ?? column.key) === this._dragged);
|
|
291
|
+
const to = this._columns.findIndex((column) => (column.id ?? column.key) === id);
|
|
292
|
+
this._dragged = null;
|
|
293
|
+
if (from < 0 || to < 0 || from === to) return;
|
|
294
|
+
const moved = this._columns.splice(from, 1);
|
|
295
|
+
this._columns.splice(to, 0, ...moved);
|
|
296
|
+
this._renderHeader();
|
|
297
|
+
this._renderRows();
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
private _applySorter(next: AdwColumnViewSort | null): void {
|
|
302
|
+
const same =
|
|
303
|
+
(next === null && this._sorter === null) ||
|
|
304
|
+
(next !== null &&
|
|
305
|
+
this._sorter !== null &&
|
|
306
|
+
next.column === this._sorter.column &&
|
|
307
|
+
next.descending === this._sorter.descending);
|
|
308
|
+
this._sorter = next === null ? null : { ...next };
|
|
309
|
+
if (same) return;
|
|
310
|
+
this._renderHeader();
|
|
311
|
+
this.dispatchEvent(new CustomEvent('notify::sorter', { bubbles: true, detail: { sorter: this.sorter } }));
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/** One track list for the header and every row, so the two cannot fall out of step. */
|
|
315
|
+
private _applyTracks(element: HTMLElement): void {
|
|
316
|
+
element.style.gridTemplateColumns = dataGridTrackTemplate(columnViewTracks(this._columns));
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
customElements.define('gtk-column-view', GtkColumnView);
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
// <gtk-drag-icon> — the thing that follows the pointer while a drag is in flight.
|
|
2
|
+
//
|
|
3
|
+
// THIS WIDGET IS NOT ONE AN APPLICATION BUILDS, and the C says so in its own docs
|
|
4
|
+
// (gtkdragicon.c:42-58): a `GtkDragIcon` is a `GtkRoot` created FOR A DRAG, cached on that
|
|
5
|
+
// drag and destroyed when the drag ends. `gtk_drag_icon_get_for_drag (drag)` returns the
|
|
6
|
+
// one in use, creating it if there is none. Everything else on the class is about the ONE
|
|
7
|
+
// thing it holds: `set_child` (:461-490) unparents the previous child, parents the new one
|
|
8
|
+
// and notifies; `gtk_drag_icon_move_resize` (:138-150) is the whole of "follows the
|
|
9
|
+
// pointer"; `surface_compute_size` (:180-188) sizes the drag surface to the child's
|
|
10
|
+
// PREFERRED size, which is why an icon is exactly as big as what it carries; and
|
|
11
|
+
// `gtk_drag_icon_init` sets `can_target` FALSE (:386-390), because a drag icon takes no
|
|
12
|
+
// input — GTK's own note is "drag icons do not allow user input" (:56-57).
|
|
13
|
+
//
|
|
14
|
+
// WHAT A BROWSER CAN AND CANNOT DO HERE, ALL OF IT WRITTEN DOWN:
|
|
15
|
+
//
|
|
16
|
+
// · the PLATFORM PAINTS ITS OWN DRAG IMAGE and offers no way to hand a live widget to
|
|
17
|
+
// it. So the element does the next best thing and is explicit about it: it asks the
|
|
18
|
+
// browser for a transparent drag image (`setDragImage`), which is why the browser's
|
|
19
|
+
// ghost is invisible, and mirrors the icon as a fixed-position element that follows
|
|
20
|
+
// the pointer for the length of the drag. Where a browser refuses the transparent
|
|
21
|
+
// image the platform ghost shows as well, and the element says so rather than
|
|
22
|
+
// pretending the mirror is the drag surface.
|
|
23
|
+
// · the ICON IS PER DRAG and cannot be a custom element that comes and goes, so
|
|
24
|
+
// `getForDrag` keys the icon on the drag's `dataTransfer` — the one object a browser
|
|
25
|
+
// gives per drag operation — in the same spirit as GTK's `g_object_get_qdata` on the
|
|
26
|
+
// `GdkDrag`, and it REUSES a `<gtk-drag-icon>` the page already declared rather than
|
|
27
|
+
// creating a node for the one drag that markup is obviously for. A declared icon
|
|
28
|
+
// already following a pointer belongs to that drag, so a second drag gets its own.
|
|
29
|
+
// `dragend` hides the icon rather than destroying it, which is the same end state
|
|
30
|
+
// through an API that cannot destroy itself.
|
|
31
|
+
// · the HOTSPOT is at the cursor. `gtk_drag_icon_set_from_paintable` calls
|
|
32
|
+
// `gdk_drag_set_hotspot (drag, hot_x, hot_y)` (:452) and `move_resize` aligns the
|
|
33
|
+
// icon's top-left to it; a browser drag image is positioned by an OFFSET passed once
|
|
34
|
+
// at `dragstart`, so the mirror puts the icon's top-left AT the pointer — the hotspot
|
|
35
|
+
// `(0, 0)` — and the header of `setFromPaintable` says what that costs.
|
|
36
|
+
//
|
|
37
|
+
// THE CSS NODE IS `dnd`, which libadwaita styles ONCE for the whole widget
|
|
38
|
+
// (`refs/libadwaita/src/stylesheet/_common.scss:30-32`) and twice more for a `dnd tab`
|
|
39
|
+
// (`_tab-view.scss:138-155`, the drag of a tab out of a tab view). The first is transcribed
|
|
40
|
+
// in `_drag_icon.scss`; the tab half selects a `tab` node, which is a `GtkTabView`'s tab
|
|
41
|
+
// rather than a property of this widget, so it belongs to the tab view's own element and
|
|
42
|
+
// is cited here instead of being guessed at.
|
|
43
|
+
//
|
|
44
|
+
// A11Y: nothing focusable and no role, which is `can_target = FALSE` in CSS. A drag icon is
|
|
45
|
+
// pointed at, not reached; it takes no focus, no pointer events and announces nothing.
|
|
46
|
+
//
|
|
47
|
+
// Events: `notify::child` (CustomEvent, bubbles, detail `{ child }`) on a real change — the
|
|
48
|
+
// one notify the class has (:489). There is no signal of its own.
|
|
49
|
+
//
|
|
50
|
+
// Reference: refs/gtk/gtk/gtkdragicon.c
|
|
51
|
+
// Reference: refs/libadwaita/src/stylesheet/_common.scss:30-32, widgets/_tab-view.scss:138-155
|
|
52
|
+
// Copyright (c) The GTK Team. LGPLv2.1+.
|
|
53
|
+
// Copyright (c) GNOME contributors (libadwaita). LGPLv2.1+.
|
|
54
|
+
// Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
|
|
55
|
+
|
|
56
|
+
/** The `rgba()` string a `GdkRGBA` value paints, as the colour swatch shows it. */
|
|
57
|
+
interface Rgba {
|
|
58
|
+
readonly red: number;
|
|
59
|
+
readonly green: number;
|
|
60
|
+
readonly blue: number;
|
|
61
|
+
readonly alpha?: number;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** One icon per drag operation, keyed on the `dataTransfer` a browser gives per drag. */
|
|
65
|
+
const ICON_BY_DRAG = new WeakMap<DataTransfer, GtkDragIcon>();
|
|
66
|
+
|
|
67
|
+
export class GtkDragIcon extends HTMLElement {
|
|
68
|
+
private _pointerX = 0;
|
|
69
|
+
private _pointerY = 0;
|
|
70
|
+
private _dragging = false;
|
|
71
|
+
/** The document listeners, released the moment the drag ends (see `_begin`). */
|
|
72
|
+
private _onDragOver: ((event: DragEvent) => void) | null = null;
|
|
73
|
+
private _onDragEnd: ((event: DragEvent) => void) | null = null;
|
|
74
|
+
/** The drag this icon is for: GTK destroys the icon when THAT drag ends (:57-58). */
|
|
75
|
+
private _transfer: DataTransfer | null = null;
|
|
76
|
+
|
|
77
|
+
static get observedAttributes() {
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* `gtk_drag_icon_get_for_drag` (:392-421), for a browser drag: the icon in use, or a
|
|
83
|
+
* new one. A declared `<gtk-drag-icon>` this drag can have is that one — see the header
|
|
84
|
+
* for when it cannot.
|
|
85
|
+
*/
|
|
86
|
+
static getForDrag(event: DragEvent): GtkDragIcon {
|
|
87
|
+
const transfer = event.dataTransfer;
|
|
88
|
+
const cached = transfer === null ? undefined : ICON_BY_DRAG.get(transfer);
|
|
89
|
+
if (cached !== undefined) return cached;
|
|
90
|
+
|
|
91
|
+
// A DECLARED icon is this drag's only if no other drag is using it: the C gives
|
|
92
|
+
// every drag an icon of its own, so a declared icon already following a pointer is
|
|
93
|
+
// left to that drag and a second one gets a node of its own.
|
|
94
|
+
const declared = document.querySelector('gtk-drag-icon');
|
|
95
|
+
const free = declared instanceof GtkDragIcon && !declared.dragging ? declared : null;
|
|
96
|
+
const icon = free ?? (document.createElement('gtk-drag-icon') as GtkDragIcon);
|
|
97
|
+
if (free === null) document.body.appendChild(icon);
|
|
98
|
+
if (transfer !== null) ICON_BY_DRAG.set(transfer, icon);
|
|
99
|
+
icon.beginDrag(event);
|
|
100
|
+
return icon;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* `gtk_drag_icon_create_widget_for_value` (:529-556): the widget a drag shows for a
|
|
105
|
+
* value. The C answers for SIX types — a string is a `GtkLabel` (:531-534), a
|
|
106
|
+
* `GDK_TYPE_PAINTABLE` and a `G_TYPE_FILE` are `GtkImage`s with the `large-icons`
|
|
107
|
+
* class (:535-543, :554-573), a `GdkRGBA` is a `GtkColorSwatch` (:544-553), a
|
|
108
|
+
* `GtkTextBuffer` is a `GtkPicture` of its selection and a `GSK_TYPE_RENDER_NODE` an
|
|
109
|
+
* image of its bounds (:574-602) — and returns `NULL` for anything else (:603-605).
|
|
110
|
+
*
|
|
111
|
+
* TWO OF THE SIX HAVE AN ANSWER HERE, and the other four are NAMED rather than
|
|
112
|
+
* quietly folded into the `null`: a paintable and a file are a picture an icon theme
|
|
113
|
+
* picks, which a browser has no query for (`g_file_query_info (… "standard::icon")`
|
|
114
|
+
* is a file-system answer), and a text buffer's drag icon is a PAINTED selection
|
|
115
|
+
* (`gtk_text_util_create_rich_drag_icon`) that this package has no text view to take
|
|
116
|
+
* one from. `null` for those is the C's own answer for a value it cannot make a
|
|
117
|
+
* widget for, so the return type still means what it means in the C.
|
|
118
|
+
*
|
|
119
|
+
* The swatch is a painted div rather than a `<gtk-color-swatch>`: this package ships no
|
|
120
|
+
* colour-swatch element, and for a drag icon the swatch is nothing but the colour it
|
|
121
|
+
* carries — `set_can_drag`/`set_can_drop` FALSE (:546-547), so it takes no input and
|
|
122
|
+
* accepts none.
|
|
123
|
+
*/
|
|
124
|
+
static createWidgetForValue(value: string | Rgba | null): Element | null {
|
|
125
|
+
if (typeof value === 'string') {
|
|
126
|
+
const label = document.createElement('gtk-label');
|
|
127
|
+
label.setAttribute('label', value);
|
|
128
|
+
return label;
|
|
129
|
+
}
|
|
130
|
+
if (value === null) return null;
|
|
131
|
+
const swatch = document.createElement('div');
|
|
132
|
+
swatch.className = 'adw-drag-icon-swatch';
|
|
133
|
+
const alpha = value.alpha ?? 1;
|
|
134
|
+
swatch.style.backgroundColor = `rgba(${Math.round(value.red * 255)}, ${Math.round(value.green * 255)}, ${Math.round(
|
|
135
|
+
value.blue * 255,
|
|
136
|
+
)}, ${alpha})`;
|
|
137
|
+
return swatch;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* `GtkDragIcon:child` — the widget displayed as the drag icon, `null` until set. GTK's
|
|
142
|
+
* setter unparents the old child, parents the new one and notifies (:468-490); the
|
|
143
|
+
* getter here is the light-DOM child, so an icon declared in markup with content needs
|
|
144
|
+
* no imperative call at all.
|
|
145
|
+
*/
|
|
146
|
+
get child(): Element | null {
|
|
147
|
+
return this.firstElementChild;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
set child(node: Element | null) {
|
|
151
|
+
if (this.child === node) return;
|
|
152
|
+
// `gtk_widget_unparent (self->child)` — the old child leaves rather than being
|
|
153
|
+
// duplicated, and `gtk_widget_set_visible` in the C is the icon showing itself.
|
|
154
|
+
this.replaceChildren();
|
|
155
|
+
if (node !== null) this.appendChild(node);
|
|
156
|
+
this.dispatchEvent(new CustomEvent('notify::child', { bubbles: true, detail: { child: node } }));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** `set_child` + `show` — the shape a drag source actually uses. */
|
|
160
|
+
setChild(node: Element | null): void {
|
|
161
|
+
this.child = node;
|
|
162
|
+
if (node !== null) this._render();
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
connectedCallback() {
|
|
166
|
+
// `gtk_widget_set_can_target (self, FALSE)` (:386-390), in CSS: the icon is pointed
|
|
167
|
+
// at, and takes no pointer event of any kind.
|
|
168
|
+
this.style.pointerEvents = 'none';
|
|
169
|
+
if (this._dragging) this._observe();
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
disconnectedCallback() {
|
|
173
|
+
this._unobserve();
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* The drag has begun. The platform's own ghost is asked away with a transparent image,
|
|
178
|
+
* and from here the icon follows the pointer — `gtk_drag_icon_move_resize` (:138-150)
|
|
179
|
+
* on every `dragover`, which is the one event a browser delivers continuously while a
|
|
180
|
+
* drag is in flight.
|
|
181
|
+
*/
|
|
182
|
+
beginDrag(event: DragEvent): void {
|
|
183
|
+
const transfer = event.dataTransfer;
|
|
184
|
+
if (transfer !== null) {
|
|
185
|
+
// A 1×1 transparent canvas is the smallest drag image a browser accepts; where
|
|
186
|
+
// `setDragImage` is refused the platform ghost shows as well, which is the one
|
|
187
|
+
// thing about this widget a page cannot fully own.
|
|
188
|
+
try {
|
|
189
|
+
const blank = document.createElement('canvas');
|
|
190
|
+
blank.width = 1;
|
|
191
|
+
blank.height = 1;
|
|
192
|
+
transfer.setDragImage(blank, 0, 0);
|
|
193
|
+
} catch {
|
|
194
|
+
// Nothing to do: the mirror still follows the pointer.
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
this._pointerX = event.clientX;
|
|
198
|
+
this._pointerY = event.clientY;
|
|
199
|
+
this._transfer = transfer;
|
|
200
|
+
this._dragging = true;
|
|
201
|
+
this._observe();
|
|
202
|
+
this._render();
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/** The drag ended: GTK destroys the icon, and this hides it instead. */
|
|
206
|
+
endDrag(): void {
|
|
207
|
+
this._dragging = false;
|
|
208
|
+
this._transfer = null;
|
|
209
|
+
this._unobserve();
|
|
210
|
+
this.hidden = true;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/** Whether a drag is in flight — the C's mapped flag, and what `hidden` answers to. */
|
|
214
|
+
get dragging(): boolean {
|
|
215
|
+
return this._dragging;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
private _observe(): void {
|
|
219
|
+
if (this._onDragOver !== null) return;
|
|
220
|
+
this._onDragOver = (event: DragEvent) => {
|
|
221
|
+
// `dragover` is the only event a browser delivers continuously during a drag,
|
|
222
|
+
// and it reaches the document from whatever is under the pointer.
|
|
223
|
+
this._pointerX = event.clientX;
|
|
224
|
+
this._pointerY = event.clientY;
|
|
225
|
+
this._render();
|
|
226
|
+
};
|
|
227
|
+
this._onDragEnd = (event: DragEvent) => {
|
|
228
|
+
// Another drag ending is not this icon's drag ending, and the C is per-drag:
|
|
229
|
+
// `gdk_drag_begin`/`gdk_drag_end` on one `GdkDrag`, one icon with it.
|
|
230
|
+
if (event.dataTransfer === null || event.dataTransfer === this._transfer) this.endDrag();
|
|
231
|
+
};
|
|
232
|
+
document.addEventListener('dragover', this._onDragOver);
|
|
233
|
+
document.addEventListener('dragend', this._onDragEnd);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
private _unobserve(): void {
|
|
237
|
+
if (this._onDragOver !== null) document.removeEventListener('dragover', this._onDragOver);
|
|
238
|
+
if (this._onDragEnd !== null) document.removeEventListener('dragend', this._onDragEnd);
|
|
239
|
+
this._onDragOver = null;
|
|
240
|
+
this._onDragEnd = null;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* `gtk_drag_icon_move_resize` (:138-150): the icon is moved to the pointer. Fixed
|
|
245
|
+
* positioning plus a transform is the one CSS door into the top layer a page has, and
|
|
246
|
+
* the hotspot is `(0, 0)` — see the header for why.
|
|
247
|
+
*/
|
|
248
|
+
private _render(): void {
|
|
249
|
+
this.hidden = !this._dragging;
|
|
250
|
+
if (!this._dragging) return;
|
|
251
|
+
this.style.left = '0px';
|
|
252
|
+
this.style.top = '0px';
|
|
253
|
+
this.style.transform = `translate3d(${Math.round(this._pointerX)}px, ${Math.round(this._pointerY)}px, 0)`;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
customElements.define('gtk-drag-icon', GtkDragIcon);
|