@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,287 @@
|
|
|
1
|
+
// <adw-breakpoint-bin> — a bin whose one child rearranges itself at size thresholds.
|
|
2
|
+
// `Adw.BreakpointBin` gives breakpoints a home without a window: it holds a list of
|
|
3
|
+
// `Adw.Breakpoint`s, and on every allocation the LAST one whose condition holds is
|
|
4
|
+
// picked and its setters written. If none holds, the child's original values stand.
|
|
5
|
+
//
|
|
6
|
+
// The picking, the restore order and what a restore restores to are all
|
|
7
|
+
// `@gjsify/adwaita-core`'s `BreakpointBinState` (ADR 0004), driven from real
|
|
8
|
+
// `ResizeObserver` deliveries — the four rules it encodes are quoted at the top of
|
|
9
|
+
// `packages/web/adwaita-core/src/breakpoint-bin.ts`, each with its `file:lines`.
|
|
10
|
+
//
|
|
11
|
+
// WHAT THE ATTRIBUTE CARRIES. `Adw.Breakpoint` is a GObject, not a widget, and
|
|
12
|
+
// `adw_breakpoint_bin_add_breakpoint()` is the whole API — so a browser port needs a
|
|
13
|
+
// MARKUP form and there is no GIR property for one. `breakpoints` is a JSON array of
|
|
14
|
+
// `{ condition, setters: [{ target, property, value }] }`:
|
|
15
|
+
//
|
|
16
|
+
// * `condition` is an Adwaita condition string, parsed by the same grammar as every
|
|
17
|
+
// other breakpoint in this package (`max-width: 720px`).
|
|
18
|
+
// * `target` is a CSS selector for a DESCENDANT. The C says it in the docs —
|
|
19
|
+
// "Breakpoints are only allowed to modify widgets inside the AdwBreakpointBin, but
|
|
20
|
+
// not on the AdwBreakpointBin itself" — and the selector cannot escape the subtree
|
|
21
|
+
// because it is resolved with `querySelector` on this element.
|
|
22
|
+
// * `property` is an ATTRIBUTE name and `value` its value. An attribute is the only
|
|
23
|
+
// thing a browser can write on another custom element portably, and this package's
|
|
24
|
+
// own properties ARE attributes (`<adw-label label>` above).
|
|
25
|
+
// * `originalValue` is read ONCE, when the setter is registered, exactly as
|
|
26
|
+
// `g_object_get_property` is at `adw_breakpoint_add_setter` (adw-breakpoint.c:1627).
|
|
27
|
+
// An attribute the element did not have is restored by REMOVING it.
|
|
28
|
+
//
|
|
29
|
+
// `Adw.BreakpointBin` also measures itself differently once it holds a breakpoint:
|
|
30
|
+
// `adw_breakpoint_bin_measure` forces its MINIMUM to 0 (:388) and
|
|
31
|
+
// `adw_breakpoint_bin_get_request_mode` answers CONSTANT_SIZE (:362). That is the
|
|
32
|
+
// documented rule — "Adding a breakpoint to AdwBreakpointBin will result in it having
|
|
33
|
+
// no minimum size" — and it is why the element sets `min-width`/`min-height` to 0 and
|
|
34
|
+
// `overflow: hidden` (the C's own `gtk_widget_set_overflow(…, GTK_OVERFLOW_HIDDEN)`,
|
|
35
|
+
// :669) while a `breakpoints` attribute is present.
|
|
36
|
+
//
|
|
37
|
+
// Attributes:
|
|
38
|
+
// breakpoints (JSON — the breakpoints to add, in ORDER: a later one beats an earlier
|
|
39
|
+
// one when both match. `current-breakpoint` is reported as the index.)
|
|
40
|
+
//
|
|
41
|
+
// Events:
|
|
42
|
+
// `notify::current-breakpoint` (CustomEvent, bubbles, `detail = { currentBreakpoint }`)
|
|
43
|
+
// when the picked breakpoint changes — mirrors the GObject property of that name,
|
|
44
|
+
// which is read-only and notified on every change (adw-breakpoint-bin.c:477).
|
|
45
|
+
// `breakpoint-unapply` (CustomEvent, bubbles, `detail = { index }`) BEFORE the writes,
|
|
46
|
+
// `breakpoint-apply` (CustomEvent, bubbles, `detail = { index }`) AFTER them — the
|
|
47
|
+
// order of `adw_breakpoint_transition` (adw-breakpoint.c:1793, :1819). A listener on
|
|
48
|
+
// the apply end therefore sees the INCOMING values and one on the unapply end the
|
|
49
|
+
// OUTGOING ones; neither ever sees the restore in between.
|
|
50
|
+
//
|
|
51
|
+
// A11Y: `role="group"`. There is no box of its own: GTK clips overflow and gives the
|
|
52
|
+
// child the allocation, which a light-DOM passthrough already is.
|
|
53
|
+
//
|
|
54
|
+
// NOT PORTED: `adw_breakpoint_bin_set_pass_through()` (:893). It makes `contains()`
|
|
55
|
+
// return FALSE so the bin claims no event of its own (adw-breakpoint-bin.c:327); a
|
|
56
|
+
// browser has no `contains` override for that, and the property is private API besides.
|
|
57
|
+
// `adw_breakpoint_bin_set_natural_size()` (:906) and
|
|
58
|
+
// `adw_breakpoint_bin_set_warnings()` (:853) are the same shape — private helpers with
|
|
59
|
+
// no GIR property, no attribute, and nothing for a page to set.
|
|
60
|
+
//
|
|
61
|
+
// Reference: refs/libadwaita/src/adw-breakpoint-bin.c
|
|
62
|
+
// Reference: refs/libadwaita/src/adw-breakpoint.c (adw_breakpoint_transition)
|
|
63
|
+
// Copyright (c) 2023 Purism SPC (libadwaita). LGPLv2.1+.
|
|
64
|
+
// Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
|
|
65
|
+
|
|
66
|
+
import { BreakpointBinState } from '@gjsify/adwaita-core';
|
|
67
|
+
import type { BreakpointSetter } from '@gjsify/adwaita-core';
|
|
68
|
+
|
|
69
|
+
import { observeAdaptiveSize } from '../breakpoints.js';
|
|
70
|
+
|
|
71
|
+
/** One authored setter, as it reads in the `breakpoints` attribute. */
|
|
72
|
+
interface AuthoredSetter {
|
|
73
|
+
readonly target: string;
|
|
74
|
+
readonly property: string;
|
|
75
|
+
readonly value: string;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** One authored breakpoint, as it reads in the `breakpoints` attribute. */
|
|
79
|
+
interface AuthoredBreakpoint {
|
|
80
|
+
readonly condition: string;
|
|
81
|
+
readonly setters: readonly AuthoredSetter[];
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** `breaks` parsed, or `[]` for anything that is not an array of breakpoints. */
|
|
85
|
+
function parseBreakpoints(raw: string | null): AuthoredBreakpoint[] {
|
|
86
|
+
if (!raw) return [];
|
|
87
|
+
let parsed: unknown;
|
|
88
|
+
try {
|
|
89
|
+
parsed = JSON.parse(raw);
|
|
90
|
+
} catch {
|
|
91
|
+
// A typo in a condition must not empty the bin: `adw_breakpoint_check_condition`
|
|
92
|
+
// returns FALSE for an unparseable condition (adw-breakpoint.c:1831), so C drops
|
|
93
|
+
// that ONE breakpoint. Silently losing all of them would be a different widget.
|
|
94
|
+
console.error('<adw-breakpoint-bin>: `breakpoints` is not JSON; no breakpoint is applied.');
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
97
|
+
if (!Array.isArray(parsed)) return [];
|
|
98
|
+
return parsed.flatMap((entry) => {
|
|
99
|
+
if (typeof entry !== 'object' || entry === null) return [];
|
|
100
|
+
const { condition, setters } = entry as Partial<AuthoredBreakpoint>;
|
|
101
|
+
if (typeof condition !== 'string') return [];
|
|
102
|
+
return [{ condition, setters: Array.isArray(setters) ? setters : [] }];
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export class AdwBreakpointBin extends HTMLElement {
|
|
107
|
+
/** The C's own structure: a list of breakpoints, and at most one picked. */
|
|
108
|
+
private _state = new BreakpointBinState<Element>();
|
|
109
|
+
private _dispose: (() => void) | undefined;
|
|
110
|
+
/**
|
|
111
|
+
* What the last binding applied, carried across every rebind.
|
|
112
|
+
*
|
|
113
|
+
* `BreakpointBinState.inherit` exists for exactly this and its docblock records the
|
|
114
|
+
* measurement: a browser element rebinds on every `connectedCallback`, and a bin that
|
|
115
|
+
* restarts at "none applied" reads the size that LEFT the old breakpoint's range as
|
|
116
|
+
* no change at all and leaves the child holding what the old bin wrote.
|
|
117
|
+
*/
|
|
118
|
+
private _applied: number | null = null;
|
|
119
|
+
/** Registration is deferred to the first allocation; see `_observe`. */
|
|
120
|
+
private _pendingSync = false;
|
|
121
|
+
/**
|
|
122
|
+
* What each setter's target held when the setter was FIRST registered, keyed by
|
|
123
|
+
* target + property + value.
|
|
124
|
+
*
|
|
125
|
+
* Carried across a REBIND because a rebind is not a re-registration. Upstream
|
|
126
|
+
* `adw_breakpoint_add_setter` captures the original once, at the call
|
|
127
|
+
* (`g_object_get_property`, adw-breakpoint.c:1627), and the widget outlives every
|
|
128
|
+
* resize; a browser element rebinds on every connect, and re-reading the original
|
|
129
|
+
* then would capture the value the OUTGOING breakpoint had already written — so the
|
|
130
|
+
* restore would write back the applied value and the widget would never recover.
|
|
131
|
+
* Measured: a bin applied at 400px, moved to a 500px parent and widened to 900px
|
|
132
|
+
* kept its narrow label for good.
|
|
133
|
+
*
|
|
134
|
+
* Cleared when the AUTHOR rewrites `breakpoints`, which is a new
|
|
135
|
+
* `add_breakpoint`/`add_setters` sequence and captures new originals.
|
|
136
|
+
*/
|
|
137
|
+
private _originals = new Map<string, string | null>();
|
|
138
|
+
|
|
139
|
+
static get observedAttributes() {
|
|
140
|
+
return ['breakpoints'];
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** `Adw.BreakpointBin:current-breakpoint` — the picked index, or null. Read-only. */
|
|
144
|
+
get currentBreakpoint(): number | null {
|
|
145
|
+
return this._state.current;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/** `adw_breakpoint_bin_get_current_breakpoint()` (:841), under its property name. */
|
|
149
|
+
get currentBreakpointAttribute(): string | null {
|
|
150
|
+
const current = this._state.current;
|
|
151
|
+
return current === null ? null : String(current);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/** `Adw.BreakpointBin:child` — the bin has one child, the one every breakpoint writes. */
|
|
155
|
+
get child(): Element | null {
|
|
156
|
+
return this.firstElementChild;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
connectedCallback() {
|
|
160
|
+
this.setAttribute('role', 'group');
|
|
161
|
+
// A GTK widget is a box and an unknown custom element is `inline`, which measures
|
|
162
|
+
// zero — and a bin measuring zero matches every condition forever. libadwaita
|
|
163
|
+
// ships no rule for this widget, so the box model is set here rather than
|
|
164
|
+
// invented in a partial.
|
|
165
|
+
this.style.display = 'block';
|
|
166
|
+
this._syncSizing();
|
|
167
|
+
// Registration waits for the first allocation: `connectedCallback` of a bin fires
|
|
168
|
+
// while its OWN markup is still being parsed, so `#caption` below it does not
|
|
169
|
+
// exist yet and a setter resolved here would be dropped rather than restored.
|
|
170
|
+
// `ResizeObserver` delivers its first observation after layout, by which time the
|
|
171
|
+
// tree is whole and nothing has been written yet — so the originals are still the
|
|
172
|
+
// ones `adw_breakpoint_add_setter` would have captured.
|
|
173
|
+
this._pendingSync = true;
|
|
174
|
+
this._observe();
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
disconnectedCallback() {
|
|
178
|
+
this._dispose?.();
|
|
179
|
+
this._dispose = undefined;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
attributeChangedCallback(name?: string) {
|
|
183
|
+
if (name !== 'breakpoints' || !this.isConnected) return;
|
|
184
|
+
// The tree IS whole by the time anything rewrites the attribute, so a change
|
|
185
|
+
// registers immediately rather than one allocation later — and it is a NEW
|
|
186
|
+
// sequence of `add_breakpoint` calls, so the originals are captured afresh.
|
|
187
|
+
this._originals.clear();
|
|
188
|
+
this._syncBreakpoints();
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Rebuild the state from the attribute, keeping the applied breakpoint.
|
|
193
|
+
*
|
|
194
|
+
* The originals are read on the way, because `inherit` restores what the NEW
|
|
195
|
+
* definitions captured: a restore read off a child the outgoing breakpoint already
|
|
196
|
+
* changed would restore it to the applied value, which is no restore at all.
|
|
197
|
+
*/
|
|
198
|
+
private _syncBreakpoints(): void {
|
|
199
|
+
this._pendingSync = false;
|
|
200
|
+
const authored = parseBreakpoints(this.getAttribute('breakpoints'));
|
|
201
|
+
this._state = new BreakpointBinState<Element>();
|
|
202
|
+
for (const breakpoint of authored) {
|
|
203
|
+
const setters: BreakpointSetter<Element>[] = [];
|
|
204
|
+
for (const setter of breakpoint.setters) {
|
|
205
|
+
if (typeof setter?.target !== 'string' || typeof setter.property !== 'string') continue;
|
|
206
|
+
const target = this.querySelector(setter.target);
|
|
207
|
+
// An unmatched selector is a setter that would write to nothing; C's
|
|
208
|
+
// `add_setters` needs a live object and refuses one that is not.
|
|
209
|
+
if (target === null) continue;
|
|
210
|
+
const key = `${setter.target}\u0000${setter.property}\u0000${setter.value}`;
|
|
211
|
+
if (!this._originals.has(key)) this._originals.set(key, target.getAttribute(setter.property));
|
|
212
|
+
setters.push({
|
|
213
|
+
object: target,
|
|
214
|
+
property: setter.property,
|
|
215
|
+
value: setter.value,
|
|
216
|
+
originalValue: this._originals.get(key) ?? null,
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
this._state.add({ condition: breakpoint.condition, setters });
|
|
220
|
+
}
|
|
221
|
+
this._state.inherit(this._applied);
|
|
222
|
+
this._state.setHasChild(this.child !== null);
|
|
223
|
+
this._write(this._state.current);
|
|
224
|
+
this._syncSizing();
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* The size source. `ResizeObserver` delivers an initial observation, so the pick is
|
|
229
|
+
* settled before first paint — the same seam `src/breakpoints.ts` gives every other
|
|
230
|
+
* adaptive element, re-created on every connect so a widget MOVED between parents
|
|
231
|
+
* tracks its conditions again.
|
|
232
|
+
*
|
|
233
|
+
* The CHILD is read here rather than cached, because
|
|
234
|
+
* `adw_breakpoint_bin_size_allocate` tests it on every allocation (:427) and a child
|
|
235
|
+
* appended after connect is then a child.
|
|
236
|
+
*/
|
|
237
|
+
private _observe(): void {
|
|
238
|
+
this._dispose?.();
|
|
239
|
+
this._dispose = observeAdaptiveSize(this, (size) => {
|
|
240
|
+
if (this._pendingSync) this._syncBreakpoints();
|
|
241
|
+
this._state.setHasChild(this.child !== null);
|
|
242
|
+
const transition = this._state.evaluate(size);
|
|
243
|
+
if (transition === null) return;
|
|
244
|
+
this._emit(transition.from, 'breakpoint-unapply');
|
|
245
|
+
this._perform(transition.writes);
|
|
246
|
+
this._write(transition.to);
|
|
247
|
+
this._emit(transition.to, 'breakpoint-apply');
|
|
248
|
+
this.dispatchEvent(
|
|
249
|
+
new CustomEvent('notify::current-breakpoint', {
|
|
250
|
+
bubbles: true,
|
|
251
|
+
detail: { currentBreakpoint: this.currentBreakpointAttribute },
|
|
252
|
+
}),
|
|
253
|
+
);
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
private _perform(writes: readonly { object: Element; property: string; value: unknown }[]): void {
|
|
258
|
+
for (const write of writes) {
|
|
259
|
+
// A `null` original is an attribute that was ABSENT, and `removeAttribute`
|
|
260
|
+
// is its restore — the one that makes unapply the exact inverse of apply.
|
|
261
|
+
if (write.value === null) write.object.removeAttribute(write.property);
|
|
262
|
+
else write.object.setAttribute(write.property, String(write.value));
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
private _write(index: number | null): void {
|
|
267
|
+
this._applied = index;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
private _emit(index: number | null, type: string): void {
|
|
271
|
+
if (index === null) return;
|
|
272
|
+
this.dispatchEvent(new CustomEvent(type, { bubbles: true, detail: { index } }));
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/** The measure rules of a bin that holds breakpoints (:356, :388, :669). */
|
|
276
|
+
private _syncSizing(): void {
|
|
277
|
+
const adaptive = this._state.length > 0;
|
|
278
|
+
// `display` and the clip are left to the author's stylesheet on purpose: the
|
|
279
|
+
// MINIMUM is the documented rule, and writing `display` from here would fight a
|
|
280
|
+
// host page that lays the bin out in a grid.
|
|
281
|
+
this.style.minWidth = adaptive ? '0px' : '';
|
|
282
|
+
this.style.minHeight = adaptive ? '0px' : '';
|
|
283
|
+
if (adaptive) this.style.overflow = 'hidden';
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
customElements.define('adw-breakpoint-bin', AdwBreakpointBin);
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
// <adw-clamp-scrollable> — the CLAMP whose child scrolls, and the widget
|
|
2
|
+
// `AdwClamp`'s own header points at for anything that must scroll inside a readable
|
|
3
|
+
// width (`adw-clamp-scrollable.c:20-27`: "The primary use case for AdwClampScrollable is
|
|
4
|
+
// clamping Gtk.ListView").
|
|
5
|
+
//
|
|
6
|
+
// SAME ARITHMETIC AS `<adw-clamp>`, both halves of it: the allocation is
|
|
7
|
+
// `clampAllocate` out of `@gjsify/adwaita-core` — `lower`/`max`/`upper`, the
|
|
8
|
+
// ease-out-cubic tightening region and the `small`/`medium`/`large` class stamped on the
|
|
9
|
+
// CHILD — reached through `normalizeClampSize` and the `AdwLengthUnit` conversion
|
|
10
|
+
// `adw-clamp-layout.c:166-171` does per property. The difference is the ORIENTATION and
|
|
11
|
+
// the scrolling.
|
|
12
|
+
//
|
|
13
|
+
// THE ORIENTATION IS THE WIDGET, NOT THE CLAMP'S. `set_orientation` forwards to the
|
|
14
|
+
// layout manager (adw-clamp-scrollable.c:78-92) and the cap lands on the width for a
|
|
15
|
+
// horizontal clamp and on the HEIGHT for a vertical one
|
|
16
|
+
// (`child_size_from_clamp` measures along `self->orientation`). A vertical clamp
|
|
17
|
+
// therefore centres on the block axis here, where `<adw-clamp>` has no axis to pick.
|
|
18
|
+
//
|
|
19
|
+
// THE SCROLLING MOVES FROM THE CHILD TO THE HOST, and that is the one deviation worth
|
|
20
|
+
// naming. In C the child IS the `Gtk.Scrollable`: the widget binds its `hadjustment`,
|
|
21
|
+
// `vadjustment`, `hscroll-policy` and `vscroll-policy` onto it
|
|
22
|
+
// (adw-clamp-scrollable.c:440-455) and a child that is not scrollable is four
|
|
23
|
+
// `gbinding` warnings at exit 0. A DOM element cannot hand its scrolling to a child that
|
|
24
|
+
// does not know it is inside one, so the scrollport is this element (`overflow`) and the
|
|
25
|
+
// child is what gets capped — the same visible contract, one level up. `hscroll-policy`
|
|
26
|
+
// and `vscroll-policy` therefore land on the HOST's overflow, which is where the C's
|
|
27
|
+
// policy ultimately decided whether the child ever scrolled.
|
|
28
|
+
//
|
|
29
|
+
// `hadjustment`/`vadjustment` have no attribute here: they are `Gtk.Adjustment`
|
|
30
|
+
// objects (a widget-valued property on every renderer), and the browser's scroll
|
|
31
|
+
// position is its own `scrollTop`/`scrollLeft`. That is a PORT-ONLY gap against the
|
|
32
|
+
// `Gtk.Scrollable` interface rather than against `AdwClampScrollable`'s own property
|
|
33
|
+
// list, which is why `check-adwaita-element-properties.mjs` has no entry for it.
|
|
34
|
+
//
|
|
35
|
+
// A11Y: no role. `adw_clamp_scrollable_class_init` sets none.
|
|
36
|
+
//
|
|
37
|
+
// Reference: refs/libadwaita/src/adw-clamp-scrollable.c (set_orientation, set_child,
|
|
38
|
+
// the four adjustment bindings, class_init's layout manager + `clamp` node)
|
|
39
|
+
// Reference: refs/libadwaita/src/adw-clamp-layout.c (child_size_from_clamp, allocate)
|
|
40
|
+
// Copyright (c) 2020 Purism SPC / GNOME contributors (libadwaita). LGPLv2.1+.
|
|
41
|
+
// Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
|
|
42
|
+
|
|
43
|
+
import {
|
|
44
|
+
ADW_CLAMP_DEFAULTS,
|
|
45
|
+
ADW_CLAMP_SIZE_CLASSES,
|
|
46
|
+
type AdwLengthUnit,
|
|
47
|
+
adwLengthToPx,
|
|
48
|
+
clampAllocate,
|
|
49
|
+
normalizeBoxOrientation,
|
|
50
|
+
normalizeClampSize,
|
|
51
|
+
normalizeLengthUnit,
|
|
52
|
+
type BoxOrientation,
|
|
53
|
+
} from '@gjsify/adwaita-core';
|
|
54
|
+
|
|
55
|
+
import { bindSlottedChildren } from '../slotted-children.js';
|
|
56
|
+
|
|
57
|
+
/** `Gtk.ScrollablePolicy`'s three nicks, in enum order. */
|
|
58
|
+
export type ScrollPolicy = 'automatic' | 'always' | 'never';
|
|
59
|
+
|
|
60
|
+
/** `adw_scrollable_policy_to_overflow` — the policy as the CSS `overflow` keyword. */
|
|
61
|
+
const POLICY_OVERFLOW: Record<ScrollPolicy, string> = {
|
|
62
|
+
automatic: 'auto',
|
|
63
|
+
always: 'scroll',
|
|
64
|
+
never: 'hidden',
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export class AdwClampScrollable extends HTMLElement {
|
|
68
|
+
private _resize: ResizeObserver | null = null;
|
|
69
|
+
private _mutations: MutationObserver | null = null;
|
|
70
|
+
|
|
71
|
+
static get observedAttributes() {
|
|
72
|
+
return ['maximum-size', 'tightening-threshold', 'unit', 'orientation', 'hscroll-policy', 'vscroll-policy'];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** `AdwClampScrollable:maximum-size` — the cap, in `unit`. Default 600. */
|
|
76
|
+
get maximumSize(): number {
|
|
77
|
+
return normalizeClampSize(this.getAttribute('maximum-size'), ADW_CLAMP_DEFAULTS.maximumSize);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
set maximumSize(value: number) {
|
|
81
|
+
this.setAttribute('maximum-size', String(value));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** `AdwClampScrollable:tightening-threshold` — where the easing starts. Default 400. */
|
|
85
|
+
get tighteningThreshold(): number {
|
|
86
|
+
return normalizeClampSize(this.getAttribute('tightening-threshold'), ADW_CLAMP_DEFAULTS.tighteningThreshold);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
set tighteningThreshold(value: number) {
|
|
90
|
+
this.setAttribute('tightening-threshold', String(value));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** `AdwClampScrollable:unit` — the length unit both sizes are written in. Default `sp`. */
|
|
94
|
+
get unit(): AdwLengthUnit {
|
|
95
|
+
return normalizeLengthUnit(this.getAttribute('unit'), 'sp');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
set unit(value: AdwLengthUnit) {
|
|
99
|
+
this.setAttribute('unit', value);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** `GtkOrientable:orientation`, which this class overrides. Default horizontal. */
|
|
103
|
+
get orientation(): BoxOrientation {
|
|
104
|
+
return normalizeBoxOrientation(this.getAttribute('orientation'));
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
set orientation(value: BoxOrientation) {
|
|
108
|
+
this.setAttribute('orientation', value);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
connectedCallback() {
|
|
112
|
+
// `AdwClampScrollable:child` is a widget PROPERTY, so a `.blp`'s `child: …`
|
|
113
|
+
// authors `slot="child"`. Every child here is already the content, so only the
|
|
114
|
+
// NAME is enrolled — the reason `adw-clamp.ts` gives for not calling
|
|
115
|
+
// `.install()`.
|
|
116
|
+
bindSlottedChildren(this, [{ name: 'child', into: this }]);
|
|
117
|
+
|
|
118
|
+
// ResizeObserver delivers an initial observation on `observe()`, so the first
|
|
119
|
+
// allocation lands before paint without a seeding pass.
|
|
120
|
+
this._resize = new ResizeObserver(() => this._allocate());
|
|
121
|
+
this._resize.observe(this);
|
|
122
|
+
// A child appended after connect is capped too; without this it keeps whatever
|
|
123
|
+
// width it arrived with.
|
|
124
|
+
this._mutations = new MutationObserver(() => this._allocate());
|
|
125
|
+
this._mutations.observe(this, { childList: true });
|
|
126
|
+
|
|
127
|
+
this._applyOverflow();
|
|
128
|
+
this._allocate();
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
disconnectedCallback() {
|
|
132
|
+
this._resize?.disconnect();
|
|
133
|
+
this._resize = null;
|
|
134
|
+
this._mutations?.disconnect();
|
|
135
|
+
this._mutations = null;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
attributeChangedCallback() {
|
|
139
|
+
this._applyOverflow();
|
|
140
|
+
this._allocate();
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* `Gtk.Scrollable:hscroll-policy` / `vscroll-policy` — the two overrides the class
|
|
145
|
+
* re-declares (adw-clamp-scrollable.c:118-141) and then binds onto the child. They
|
|
146
|
+
* decide here whether this element scrolls at all, which is the question they answer
|
|
147
|
+
* in C.
|
|
148
|
+
*/
|
|
149
|
+
private _applyOverflow(): void {
|
|
150
|
+
const horizontal = this.getAttribute('hscroll-policy') as ScrollPolicy | null;
|
|
151
|
+
const vertical = this.getAttribute('vscroll-policy') as ScrollPolicy | null;
|
|
152
|
+
this.style.overflowX = horizontal === null ? 'auto' : (POLICY_OVERFLOW[horizontal] ?? 'auto');
|
|
153
|
+
this.style.overflowY = vertical === null ? 'auto' : (POLICY_OVERFLOW[vertical] ?? 'auto');
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* `adw_clamp_layout_allocate`, against the AVAILABLE size on the clamped axis.
|
|
158
|
+
*
|
|
159
|
+
* The cap sits on the CHILD, never here: this element is the scrollport, so a cap on
|
|
160
|
+
* itself would feed its own capped width back into its ResizeObserver — a feedback
|
|
161
|
+
* loop rather than a measurement (the reasoning `<adw-clamp>` carries in full).
|
|
162
|
+
*/
|
|
163
|
+
private _allocate(): void {
|
|
164
|
+
const vertical = this.orientation === 'vertical';
|
|
165
|
+
const unit = this.unit;
|
|
166
|
+
const available = vertical ? this.clientHeight : this.clientWidth;
|
|
167
|
+
|
|
168
|
+
// `childMin` is 0, as in `<adw-clamp>`: a child that declares a minimum keeps it
|
|
169
|
+
// (CSS 2.1 §10.4 lets `min-*` beat `max-*`), and one that declares none has a
|
|
170
|
+
// minimum of 0 — the value a synchronous re-measure would arrive at anyway.
|
|
171
|
+
const params = {
|
|
172
|
+
maximumSize: adwLengthToPx(unit, this.maximumSize),
|
|
173
|
+
tighteningThreshold: adwLengthToPx(unit, this.tighteningThreshold),
|
|
174
|
+
childMin: 0,
|
|
175
|
+
childNat: 0,
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
for (const child of Array.from(this.children) as HTMLElement[]) {
|
|
179
|
+
if (available <= 0) {
|
|
180
|
+
// GTK's equivalent is `for_size = -1`: leave the child alone rather than
|
|
181
|
+
// capping it at 0 and collapsing the page.
|
|
182
|
+
child.style.maxWidth = '';
|
|
183
|
+
child.style.maxHeight = '';
|
|
184
|
+
child.style.marginInline = '';
|
|
185
|
+
child.style.marginBlock = '';
|
|
186
|
+
for (const cls of ADW_CLAMP_SIZE_CLASSES) child.classList.remove(cls);
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const { childSize, sizeClass } = clampAllocate(available, params);
|
|
191
|
+
if (vertical) {
|
|
192
|
+
child.style.maxWidth = '';
|
|
193
|
+
child.style.maxHeight = `${childSize}px`;
|
|
194
|
+
child.style.marginInline = '';
|
|
195
|
+
child.style.marginBlock = 'auto';
|
|
196
|
+
} else {
|
|
197
|
+
child.style.maxWidth = `${childSize}px`;
|
|
198
|
+
child.style.maxHeight = '';
|
|
199
|
+
child.style.marginInline = 'auto';
|
|
200
|
+
child.style.marginBlock = '';
|
|
201
|
+
}
|
|
202
|
+
for (const cls of ADW_CLAMP_SIZE_CLASSES) child.classList.toggle(cls, cls === sizeClass);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
customElements.define('adw-clamp-scrollable', AdwClampScrollable);
|
|
@@ -19,6 +19,12 @@
|
|
|
19
19
|
// Events, all bubbling CustomEvents: `notify::open` (detail `{ open }`), `closed`
|
|
20
20
|
// (Adw.Dialog::closed), `close-attempt` (Adw.Dialog::close-attempt).
|
|
21
21
|
//
|
|
22
|
+
// SUBCLASSING: `decorateHeader(header)` is the one hook, and it exists for
|
|
23
|
+
// `<gtk-about-dialog>`, whose headerbar carries a stack switcher in the title position
|
|
24
|
+
// instead of a title (gtkaboutdialog.ui). Chrome, focus, Escape and dismissal stay here,
|
|
25
|
+
// so a subclass that wants a different header adds to this one rather than building a
|
|
26
|
+
// second scrim.
|
|
27
|
+
//
|
|
22
28
|
// Reference: refs/libadwaita/src/adw-dialog.c (present/close/can-close, Escape, focus)
|
|
23
29
|
// Reference: refs/libadwaita/src/stylesheet/widgets/_dialogs.scss (floating sheet + bottom sheet)
|
|
24
30
|
// Copyright (c) 2023-2024 GNOME Foundation Inc. (libadwaita). LGPLv2.1+.
|
|
@@ -223,6 +229,17 @@ export class AdwDialog extends HTMLElement {
|
|
|
223
229
|
this._modal.dismiss();
|
|
224
230
|
}
|
|
225
231
|
|
|
232
|
+
/**
|
|
233
|
+
* Add to the header bar, called at the end of every render.
|
|
234
|
+
*
|
|
235
|
+
* The hook is for a DIALOG whose header is not a title plus a close button, which is
|
|
236
|
+
* what `<gtk-about-dialog>` needs: `gtkaboutdialog.ui` puts a `GtkStackSwitcher` in
|
|
237
|
+
* the titlebar's title-widget position and no title text at all. An empty body is the
|
|
238
|
+
* default, so every other dialog is unaffected — and the header element is the one
|
|
239
|
+
* the base already owns, so a subclass never reaches into private state to get it.
|
|
240
|
+
*/
|
|
241
|
+
protected decorateHeader(_header: HTMLElement): void {}
|
|
242
|
+
|
|
226
243
|
private _render(): void {
|
|
227
244
|
this.classList.toggle('open', this.open);
|
|
228
245
|
|
|
@@ -244,6 +261,8 @@ export class AdwDialog extends HTMLElement {
|
|
|
244
261
|
const locked = !this.canClose;
|
|
245
262
|
this._closeBtn.disabled = locked;
|
|
246
263
|
this._closeBtn.classList.toggle('locked', locked);
|
|
264
|
+
|
|
265
|
+
this.decorateHeader(this._headerEl);
|
|
247
266
|
}
|
|
248
267
|
}
|
|
249
268
|
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// <adw-layout-slot> — one named hole inside a layout of an `Adw.MultiLayoutView`.
|
|
2
|
+
//
|
|
3
|
+
// `AdwLayoutSlot` is a bin with an ID and nothing else: it takes a child when the view
|
|
4
|
+
// inserts the child whose ID matches, and its `visible` property is bound to that
|
|
5
|
+
// child's so hiding the child hides the hole (:151). The ID is what pairs the two
|
|
6
|
+
// sides — `adw_multi_layout_view_set_child(id, widget)` finds the layout's slots by
|
|
7
|
+
// `g_hash_table_lookup (self->slots, id)` (:139) — and it is CONSTRUCT-ONLY
|
|
8
|
+
// (adw-layout-slot.c:145), so it is read once and never written.
|
|
9
|
+
//
|
|
10
|
+
// DUPLICATE IDs ACROSS LAYOUTS ARE THE WIDGET'S OWN MODEL, not a mistake here: the
|
|
11
|
+
// canonical example in the C documentation puts an `AdwLayoutSlot` with `id="primary"`
|
|
12
|
+
// in BOTH layouts of one view, because that is how a child follows a layout change. The
|
|
13
|
+
// element never resolves a slot by document lookup, only from the subtree of the layout
|
|
14
|
+
// it is currently mounting, so two of them with one ID are ordinary.
|
|
15
|
+
//
|
|
16
|
+
// Attributes:
|
|
17
|
+
// id (`AdwLayoutSlot:id` — the slot ID. Construct-only upstream, so changing it here
|
|
18
|
+
// after connect re-registers the slot and warns, as `g_error` does for a slot
|
|
19
|
+
// constructed without one (adw-layout-slot.c:68).)
|
|
20
|
+
//
|
|
21
|
+
// A11Y: `role="group"`, the accessible role libadwaita installs on the class
|
|
22
|
+
// (adw-layout-slot.c:131).
|
|
23
|
+
//
|
|
24
|
+
// There is no box of its own (`display: contents`, so the child takes the allocation the
|
|
25
|
+
// container would have given the slot) and libadwaita ships NO rule for this widget —
|
|
26
|
+
// `src/stylesheet/widgets/` has no `layout-slot` partial and no selector names the node,
|
|
27
|
+
// so there is nothing to port and nothing invented to replace it.
|
|
28
|
+
//
|
|
29
|
+
// Reference: refs/libadwaita/src/adw-layout-slot.c
|
|
30
|
+
// Copyright (c) 2023-2024 Purism SPC / GNOME Foundation Inc. (libadwaita). LGPLv2.1+.
|
|
31
|
+
// Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
|
|
32
|
+
|
|
33
|
+
import { AdwMultiLayoutView } from './adw-multi-layout-view.js';
|
|
34
|
+
|
|
35
|
+
export class AdwLayoutSlot extends HTMLElement {
|
|
36
|
+
private _registered = false;
|
|
37
|
+
|
|
38
|
+
static get observedAttributes() {
|
|
39
|
+
return ['id'];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** `adw_layout_slot_get_slot_id()` (:184), read under its property's name. */
|
|
43
|
+
get slotId(): string | null {
|
|
44
|
+
return this.getAttribute('id');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
connectedCallback() {
|
|
48
|
+
this.setAttribute('role', 'group');
|
|
49
|
+
// `display: contents` inline rather than in a partial: libadwaita styles nothing
|
|
50
|
+
// here, and a host page that wants the slot to box its child sets one rule.
|
|
51
|
+
this.style.display = 'contents';
|
|
52
|
+
this._register();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
disconnectedCallback() {
|
|
56
|
+
this._registered = false;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
attributeChangedCallback(name?: string) {
|
|
60
|
+
if (!this.isConnected || name !== 'id') return;
|
|
61
|
+
if (this._registered) {
|
|
62
|
+
// `G_PARAM_CONSTRUCT_ONLY`: upstream cannot change a slot's ID either, and
|
|
63
|
+
// the bin's `slots` table is keyed by it — `register_slot` refuses a second
|
|
64
|
+
// entry under one ID (adw-multi-layout-view.c:693). Saying so beats
|
|
65
|
+
// silently leaving the view holding the old pairing.
|
|
66
|
+
console.warn('<adw-layout-slot>: `id` is construct-only upstream; re-registering the slot.');
|
|
67
|
+
}
|
|
68
|
+
this._register();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Hand this slot to the nearest `<adw-multi-layout-view>` ancestor.
|
|
73
|
+
*
|
|
74
|
+
* `adw_layout_slot_root` walks up for the view and calls
|
|
75
|
+
* `adw_multi_layout_view_register_slot` (adw-layout-slot.c:55). The view's own
|
|
76
|
+
* mount path is the authority — it registers only while it is building a layout —
|
|
77
|
+
* so a call arriving outside that window is refused there, exactly as
|
|
78
|
+
* `accepting_slots` refuses it upstream.
|
|
79
|
+
*/
|
|
80
|
+
private _register(): void {
|
|
81
|
+
const id = this.slotId;
|
|
82
|
+
if (id === null || id === '') {
|
|
83
|
+
console.error('<adw-layout-slot> created without an `id` — libadwaita refuses this with g_error.');
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
// `instanceof` rather than a cast on `closest(…)`: an ancestor that is present
|
|
87
|
+
// but not upgraded yet satisfies a cast and fails at the call, and this is on the
|
|
88
|
+
// connect path of every slot.
|
|
89
|
+
const view = this.closest('adw-multi-layout-view');
|
|
90
|
+
if (view instanceof AdwMultiLayoutView) view.registerSlot(id, this);
|
|
91
|
+
this._registered = true;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
customElements.define('adw-layout-slot', AdwLayoutSlot);
|