@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,303 @@
|
|
|
1
|
+
// <gtk-drawing-area> — a blank widget you draw on. It owns no painting of its own: it
|
|
2
|
+
// carries a SIZE, a CALLBACK and a resize notification, and everything you can see is
|
|
3
|
+
// what the callback painted.
|
|
4
|
+
//
|
|
5
|
+
// WHAT THE C ACTUALLY DOES, IN FOUR PLACES (gtkdrawingarea.c):
|
|
6
|
+
//
|
|
7
|
+
// · `gtk_drawing_area_measure` (:210-231) returns `content_width` / `content_height`
|
|
8
|
+
// as BOTH the minimum and the natural size of the matching orientation. A zero — the
|
|
9
|
+
// default — means the widget has no intrinsic size on that axis at all, so the parent
|
|
10
|
+
// decides; a non-zero one is a floor the parent cannot allocate below, not a fixed
|
|
11
|
+
// size. `_drawing.scss` spells that pair as `width`/`min-width`.
|
|
12
|
+
// · `gtk_drawing_area_size_allocate` (:233-238) does nothing but emit `::resize` with
|
|
13
|
+
// the new width and height. That is the whole allocation path: no re-measure, no
|
|
14
|
+
// re-layout, one signal.
|
|
15
|
+
// · `gtk_drawing_area_snapshot` (:240-267) returns early WITHOUT calling the draw
|
|
16
|
+
// function when none is set, appends a cairo region the size of the allocation and
|
|
17
|
+
// calls it with `width`/`height` from the allocation, not from the properties.
|
|
18
|
+
// · `gtk_drawing_area_set_draw_func` (:474-491) runs the previous `destroy` notifier,
|
|
19
|
+
// stores the triple and calls `gtk_widget_queue_draw`, so installing a function
|
|
20
|
+
// repaints. `set_draw_func(NULL)` is therefore a documented way to blank the widget.
|
|
21
|
+
//
|
|
22
|
+
// THE CALLBACK. GTK's is `(area, cr, width, height, user_data)`. The `user_data` /
|
|
23
|
+
// `destroy` pair is what this renderer has no use for — a JS closure holds its own
|
|
24
|
+
// captures and the garbage collector is the notifier — so the browser signature drops
|
|
25
|
+
// both and the element keeps the first four in the C's order. Replacing a function is a
|
|
26
|
+
// plain assignment; there is no second copy to leak, which is the only thing the
|
|
27
|
+
// `destroy` notifier is for.
|
|
28
|
+
//
|
|
29
|
+
// LOGICAL PIXELS, ONCE. The cairo region GTK hands the callback is in the widget's LOGICAL
|
|
30
|
+
// size (`:248-262` — the allocation, unscaled), and GTK scales the surface at composite
|
|
31
|
+
// time. A `<canvas>` is a PIXEL buffer whose `width`/`height` attributes are its backing
|
|
32
|
+
// store, so the element multiplies that by the device pixel ratio and scales the 2D
|
|
33
|
+
// context by the same factor before calling in. The callback still draws in logical
|
|
34
|
+
// pixels, which is the property an application port depends on.
|
|
35
|
+
//
|
|
36
|
+
// EACH FRAME STARTS EMPTY. GTK's renderer builds every frame into a fresh surface, so a
|
|
37
|
+
// draw function that paints a background covers what was there; a canvas keeps its pixels
|
|
38
|
+
// between frames, so the element clears the allocation before calling in. Without that a
|
|
39
|
+
// second frame would composite over the first — the one difference a naive port shows and
|
|
40
|
+
// the reason this is written down rather than left to the reader.
|
|
41
|
+
//
|
|
42
|
+
// A11Y: no role, and none invented. GtkDrawingArea is a blank widget with no accessible
|
|
43
|
+
// role of its own, so naming one would add an interface GTK does not have. A drawing
|
|
44
|
+
// area that shows text owes the screen reader a label from the application, which an
|
|
45
|
+
// ordinary `aria-label` on the element already does.
|
|
46
|
+
//
|
|
47
|
+
// Events: `resize` (CustomEvent, bubbles, detail `{ width, height }` — GtkDrawingArea's
|
|
48
|
+
// own signal, gtkdrawingarea.c:311-328) on the first allocation and every change of one,
|
|
49
|
+
// and `notify::<prop>` (CustomEvent, bubbles, detail `{ <prop>: value }`) on a real change.
|
|
50
|
+
//
|
|
51
|
+
// Reference: refs/gtk/gtk/gtkdrawingarea.c
|
|
52
|
+
// Copyright (c) The GTK Team. LGPLv2.1+.
|
|
53
|
+
// Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
|
|
54
|
+
|
|
55
|
+
import { glibClamp } from '@gjsify/adwaita-core';
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* `GtkDrawingAreaDrawFunc` with the `user_data` / `destroy` pair dropped — see the header.
|
|
59
|
+
*
|
|
60
|
+
* @param area the drawing area being painted, as the C's first argument
|
|
61
|
+
* @param cr a 2D context over the whole allocation, in logical pixels
|
|
62
|
+
* @param width the width of the allocation — NOT of `content-width`
|
|
63
|
+
* @param height the height of the allocation — NOT of `content-height`
|
|
64
|
+
*/
|
|
65
|
+
export type GtkDrawingAreaDrawFunc = (
|
|
66
|
+
area: GtkDrawingArea,
|
|
67
|
+
cr: CanvasRenderingContext2D,
|
|
68
|
+
width: number,
|
|
69
|
+
height: number,
|
|
70
|
+
) => void;
|
|
71
|
+
|
|
72
|
+
/** `G_MAXINT`, the top of `g_param_spec_int`'s range (:288-304). */
|
|
73
|
+
const MAX_INT = 2147483647;
|
|
74
|
+
|
|
75
|
+
/** A missing or unparseable attribute is `0`, which is also the GIR default. */
|
|
76
|
+
function intAttribute(element: HTMLElement, name: string): number {
|
|
77
|
+
const raw = Number.parseInt(element.getAttribute(name) ?? '', 10);
|
|
78
|
+
return Number.isFinite(raw) ? raw : 0;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export class GtkDrawingArea extends HTMLElement {
|
|
82
|
+
private _canvas!: HTMLCanvasElement;
|
|
83
|
+
private _context: CanvasRenderingContext2D | null = null;
|
|
84
|
+
private _initialized = false;
|
|
85
|
+
private _drawFunc: GtkDrawingAreaDrawFunc | null = null;
|
|
86
|
+
/** The last allocation the draw function was called with, as `::resize` sees it. */
|
|
87
|
+
private _width = -1;
|
|
88
|
+
private _height = -1;
|
|
89
|
+
/** The last device pixel ratio the backing store was built for. */
|
|
90
|
+
private _scale = 1;
|
|
91
|
+
private _resize: ResizeObserver | null = null;
|
|
92
|
+
private _frame: number | null = null;
|
|
93
|
+
|
|
94
|
+
static get observedAttributes() {
|
|
95
|
+
return ['content-width', 'content-height'];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** `Gtk.DrawingArea:content-width` — the minimum AND natural width. Defaults to 0. */
|
|
99
|
+
get contentWidth(): number {
|
|
100
|
+
return intAttribute(this, 'content-width');
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
set contentWidth(v: number) {
|
|
104
|
+
// The pspec range is 0…G_MAXINT (:290-294), so a write outside it is clamped
|
|
105
|
+
// rather than refused — which is what `set_property` does with the value.
|
|
106
|
+
this._write('content-width', String(glibClamp(Math.trunc(v) || 0, 0, MAX_INT)));
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** `Gtk.DrawingArea:content-height` — the minimum AND natural height. Defaults to 0. */
|
|
110
|
+
get contentHeight(): number {
|
|
111
|
+
return intAttribute(this, 'content-height');
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
set contentHeight(v: number) {
|
|
115
|
+
this._write('content-height', String(glibClamp(Math.trunc(v) || 0, 0, MAX_INT)));
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Every GObject setter here returns early when the value is already right
|
|
120
|
+
* (gtkdrawingarea.c:373, :423), while `setAttribute` runs the reaction for a write
|
|
121
|
+
* that changes nothing — so the guard that makes "notify only on a real change" true
|
|
122
|
+
* for the numeric half is the same one `<gtk-level-bar>` uses.
|
|
123
|
+
*/
|
|
124
|
+
private _write(name: string, value: string): void {
|
|
125
|
+
if (this.getAttribute(name) !== value) this.setAttribute(name, value);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** `GtkDrawingAreaDrawFunc`, or `null` — GTK's default, which paints nothing (:251). */
|
|
129
|
+
get drawFunc(): GtkDrawingAreaDrawFunc | null {
|
|
130
|
+
return this._drawFunc;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
set drawFunc(fn: GtkDrawingAreaDrawFunc | null) {
|
|
134
|
+
this.setDrawFunc(fn);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* `gtk_drawing_area_set_draw_func` (gtkdrawingarea.c:474-491): store the function and
|
|
139
|
+
* `queue_draw`, which is what repaints. Passing `null` clears it, and the next
|
|
140
|
+
* snapshot leaves the widget blank — the C's early return at :251.
|
|
141
|
+
*/
|
|
142
|
+
setDrawFunc(fn: GtkDrawingAreaDrawFunc | null): void {
|
|
143
|
+
this._drawFunc = fn;
|
|
144
|
+
this.queueDraw();
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* `gtk_widget_queue_draw` on this widget: the documented way to ask for the draw
|
|
149
|
+
* function to be called again (gtkdrawingarea.c:127-129).
|
|
150
|
+
*
|
|
151
|
+
* AND WHY IT IS NOT IMMEDIATE. `queue_draw` marks the window dirty and the frame clock
|
|
152
|
+
* draws it on the next frame, so a draw function that calls `queue_draw` keeps
|
|
153
|
+
* ANIMATING rather than recursing — and a 2D canvas drawn synchronously would turn the
|
|
154
|
+
* same application into a stack overflow. One animation frame is the browser's frame
|
|
155
|
+
* clock, and coalescing through it is what makes "paint from the function" a loop and
|
|
156
|
+
* not a crash. Several requests before the frame are one frame, as in the C.
|
|
157
|
+
*/
|
|
158
|
+
queueDraw(): void {
|
|
159
|
+
if (!this._initialized || this._frame !== null) return;
|
|
160
|
+
this._frame = requestAnimationFrame(() => {
|
|
161
|
+
this._frame = null;
|
|
162
|
+
this._draw();
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
connectedCallback() {
|
|
167
|
+
if (this._initialized) {
|
|
168
|
+
// The teardown below released the observer on the way out, so a re-parent has
|
|
169
|
+
// to arm it again — see `scripts/check-adwaita-connect-rebind.mjs`.
|
|
170
|
+
this._observe();
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
this._initialized = true;
|
|
174
|
+
|
|
175
|
+
this._canvas = document.createElement('canvas');
|
|
176
|
+
this._canvas.className = 'adw-drawing-area-canvas';
|
|
177
|
+
this._context = this._canvas.getContext('2d');
|
|
178
|
+
this.replaceChildren(this._canvas);
|
|
179
|
+
this._publishSize();
|
|
180
|
+
this._observe();
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
disconnectedCallback() {
|
|
184
|
+
this._resize?.disconnect();
|
|
185
|
+
this._resize = null;
|
|
186
|
+
if (this._frame !== null) cancelAnimationFrame(this._frame);
|
|
187
|
+
this._frame = null;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
attributeChangedCallback(name: string) {
|
|
191
|
+
if (!this._initialized) return;
|
|
192
|
+
// A size property is a REQUEST, not a repaint: it changes the element's own box,
|
|
193
|
+
// the observer hears the allocation that follows, and the paint is redone then.
|
|
194
|
+
// `notify` fires either way, and the custom property the partial reads is
|
|
195
|
+
// republished first so the CSS floor moves with the property.
|
|
196
|
+
if (name === 'content-width' || name === 'content-height') this._publishSize();
|
|
197
|
+
this._notify(name);
|
|
198
|
+
if (name === 'content-width' || name === 'content-height') this.queueDraw();
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* `measure` returns one number per axis as the minimum AND the natural size
|
|
203
|
+
* (gtkdrawingarea.c:210-231), and CSS has a property for each half — so the element
|
|
204
|
+
* publishes the number once and `_drawing.scss` reads it twice. A zero removes the
|
|
205
|
+
* property rather than declaring `0px`, because `var(--adw-drawing-width, auto)` is
|
|
206
|
+
* how "no intrinsic size" is spelled.
|
|
207
|
+
*/
|
|
208
|
+
private _publishSize(): void {
|
|
209
|
+
const size: [string, number][] = [
|
|
210
|
+
['--adw-drawing-width', this.contentWidth],
|
|
211
|
+
['--adw-drawing-height', this.contentHeight],
|
|
212
|
+
];
|
|
213
|
+
for (const [property, value] of size) {
|
|
214
|
+
if (value > 0) this.style.setProperty(property, `${value}px`);
|
|
215
|
+
else this.style.removeProperty(property);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
private _observe(): void {
|
|
220
|
+
if (this._resize) return;
|
|
221
|
+
// ResizeObserver delivers an initial observation on observe(), so the first draw
|
|
222
|
+
// lands without a separate seeding pass — the `::resize` signal GTK emits "once
|
|
223
|
+
// when the widget is realized" (:312-313).
|
|
224
|
+
this._resize = new ResizeObserver((entries) => {
|
|
225
|
+
for (const entry of entries) {
|
|
226
|
+
const box = entry.borderBoxSize?.[0];
|
|
227
|
+
this._allocated(
|
|
228
|
+
box ? box.inlineSize : entry.contentRect.width,
|
|
229
|
+
box ? box.blockSize : entry.contentRect.height,
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
this._resize.observe(this);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* `gtk_drawing_area_size_allocate` (:233-238) emits `::resize` and does nothing else —
|
|
238
|
+
* the signal IS the allocation path. The browser learns the allocation from the
|
|
239
|
+
* observer instead, so the signal is emitted from here, and only when the allocation
|
|
240
|
+
* really changed: GTK reaches `size_allocate` on every layout pass, and the signal
|
|
241
|
+
* is documented as firing "each time the widget is changed" (:312-314).
|
|
242
|
+
*/
|
|
243
|
+
private _allocated(width: number, height: number): void {
|
|
244
|
+
const changed = width !== this._width || height !== this._height;
|
|
245
|
+
this._width = width;
|
|
246
|
+
this._height = height;
|
|
247
|
+
if (changed) {
|
|
248
|
+
this.dispatchEvent(new CustomEvent('resize', { bubbles: true, detail: { width, height } }));
|
|
249
|
+
}
|
|
250
|
+
this._draw();
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* One frame. `gtk_drawing_area_snapshot` (:240-267) measures the ALLOCATION, not the
|
|
255
|
+
* properties, and calls the function with it; the browser gets the allocation from the
|
|
256
|
+
* observer instead of from the snapshot, and the drawing itself is the 2D context the
|
|
257
|
+
* canvas already owns.
|
|
258
|
+
*/
|
|
259
|
+
private _draw(): void {
|
|
260
|
+
if (!this._canvas || this._width < 0) return;
|
|
261
|
+
const width = this._width;
|
|
262
|
+
const height = this._height;
|
|
263
|
+
// The cairo region is the allocation unscaled (:248-262); the backing store is the
|
|
264
|
+
// same size in device pixels, and the context carries the ratio.
|
|
265
|
+
const scale = this._devicePixelRatio();
|
|
266
|
+
const pixelWidth = Math.round(width * scale);
|
|
267
|
+
const pixelHeight = Math.round(height * scale);
|
|
268
|
+
if (this._canvas.width !== pixelWidth) this._canvas.width = pixelWidth;
|
|
269
|
+
if (this._canvas.height !== pixelHeight) this._canvas.height = pixelHeight;
|
|
270
|
+
this._scale = scale;
|
|
271
|
+
|
|
272
|
+
const context = this._context;
|
|
273
|
+
if (!context) return;
|
|
274
|
+
// `setTransform` rather than `scale`, so a second frame does not compound the ratio.
|
|
275
|
+
context.setTransform(scale, 0, 0, scale, 0, 0);
|
|
276
|
+
// A fresh surface per frame, as GTK's renderer gives the callback.
|
|
277
|
+
context.clearRect(0, 0, width, height);
|
|
278
|
+
|
|
279
|
+
if (this._drawFunc) this._drawFunc(this, context, width, height);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/** The backing store is rebuilt when the display's ratio changes, not every frame. */
|
|
283
|
+
private _devicePixelRatio(): number {
|
|
284
|
+
return typeof window === 'undefined' ? 1 : window.devicePixelRatio || 1;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/** The `notify::` detail for `name`: the PROPERTY, parsed, not the raw attribute. */
|
|
288
|
+
private _notify(name: string): void {
|
|
289
|
+
const value = name === 'content-width' ? this.contentWidth : this.contentHeight;
|
|
290
|
+
this.dispatchEvent(new CustomEvent(`notify::${name}`, { bubbles: true, detail: { [name]: value } }));
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/** The last allocation, as `::resize` reported it — the spec reads it back. */
|
|
294
|
+
get allocation(): { width: number; height: number } {
|
|
295
|
+
return { width: this._width, height: this._height };
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/** The ratio the backing store was built at, as the header describes. */
|
|
299
|
+
get pixelScale(): number {
|
|
300
|
+
return this._scale;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
customElements.define('gtk-drawing-area', GtkDrawingArea);
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
// <gtk-editable-label> — `GtkEditableLabel`, a label you click and edit in place.
|
|
2
|
+
//
|
|
3
|
+
// IT IS A STACK, NOT A FIELD. The C builds `stack > { label, entry }`, puts a
|
|
4
|
+
// `Gtk.Text` in the entry slot, and `editing` IS "the entry is the stack's visible child"
|
|
5
|
+
// (gtkeditablelabel.c:319-331,595-599). Two elements therefore stand for one widget, and
|
|
6
|
+
// which of them shows is the whole of its state — `.editing` on the host is the class the
|
|
7
|
+
// C adds and removes around every transition (gtkeditablelabel.c:609-663), and it is what
|
|
8
|
+
// libadwaita's `editablelabel > stack > text` selector keys on.
|
|
9
|
+
//
|
|
10
|
+
// THE KEYS ARE THE BEHAVIOUR. Enter on the label starts editing; Enter in the entry COMMITS
|
|
11
|
+
// (the drafted text becomes the label's); Escape in the entry DISCARDS it (the entry is
|
|
12
|
+
// reset to what the label says, gtkeditablelabel.c:637-656). A click on the label starts
|
|
13
|
+
// editing — the gesture is on the LABEL, not on the widget (gtkeditablelabel.c:193-215,
|
|
14
|
+
// 351-353) — and focus leaving the widget commits after the C's 100 ms grace period, which
|
|
15
|
+
// exists so a focus move INSIDE the widget is not read as leaving
|
|
16
|
+
// (gtkeditablelabel.c:293-318). `editable` FALSE stops editing without committing and
|
|
17
|
+
// refuses to start it (gtkeditablelabel.c:414-427).
|
|
18
|
+
//
|
|
19
|
+
// `text` is `Gtk.Editable:text`, what the label shows. While the entry is visible it holds a
|
|
20
|
+
// DRAFT, which is why the C syncs the label from `notify::text` only while it is not
|
|
21
|
+
// editing (gtkeditablelabel.c:237-248) and why a discarded edit resets the entry rather
|
|
22
|
+
// than the label.
|
|
23
|
+
//
|
|
24
|
+
// A11y: GTK declares no role for this widget (`gtkeditablelabel.c` calls no
|
|
25
|
+
// `set_accessible_role`) and makes it focusable (gtkeditablelabel.c:320), so the host owns
|
|
26
|
+
// the tab stop while it shows the label and the entry holds it while it edits.
|
|
27
|
+
//
|
|
28
|
+
// NOT PORTED, one line each, declared in `check-adwaita-element-properties.mjs`: the
|
|
29
|
+
// drag-and-drop target and source (GTK drops a string onto the label and drags its text out,
|
|
30
|
+
// gtkeditablelabel.c:250-291), the context menu (a `Gtk.PopoverMenu` over a right click,
|
|
31
|
+
// gtkeditablelabel.c:145-190) and `Gtk.Editable`'s undo stack (`enable-undo`, which no
|
|
32
|
+
// attribute can carry and a native input does not expose).
|
|
33
|
+
//
|
|
34
|
+
// Reference: refs/gtk/gtk/gtkeditablelabel.c:40-95 (the node tree and the keys),
|
|
35
|
+
// 193-215,237-248,293-331,414-427,609-663 (gesture, text sync, focus grace, editable,
|
|
36
|
+
// start/stop editing)
|
|
37
|
+
// Reference: refs/libadwaita/src/stylesheet/widgets/_labels.scss:1-11,90-97
|
|
38
|
+
// (`label {}`, `editablelabel > stack > text`)
|
|
39
|
+
// Copyright (c) The GTK Team, GNOME contributors. LGPLv2.1+.
|
|
40
|
+
// Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
|
|
41
|
+
|
|
42
|
+
/** The C's grace period between a focus leaving the widget and the commit it triggers. */
|
|
43
|
+
const FOCUS_OUT_GRACE_MS = 100;
|
|
44
|
+
|
|
45
|
+
export class GtkEditableLabel extends HTMLElement {
|
|
46
|
+
private _label!: HTMLSpanElement;
|
|
47
|
+
private _entry!: HTMLInputElement;
|
|
48
|
+
private _initialized = false;
|
|
49
|
+
private _grace: ReturnType<typeof setTimeout> | null = null;
|
|
50
|
+
|
|
51
|
+
static get observedAttributes() {
|
|
52
|
+
return ['text', 'editable', 'editing'];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** `Gtk.Editable:text` — what the label shows, which is the committed draft. */
|
|
56
|
+
get text(): string {
|
|
57
|
+
return this.getAttribute('text') ?? '';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
set text(value: string) {
|
|
61
|
+
this.setAttribute('text', value ?? '');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** `Gtk.Editable:editable` — defaults TRUE. FALSE refuses to start editing. */
|
|
65
|
+
get editable(): boolean {
|
|
66
|
+
const raw = this.getAttribute('editable');
|
|
67
|
+
return raw === null ? true : raw !== 'false';
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
set editable(value: boolean) {
|
|
71
|
+
if (value) this.removeAttribute('editable');
|
|
72
|
+
else this.setAttribute('editable', 'false');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* `GtkEditableLabel:editing` — TRUE while the entry is the stack's visible child, so it
|
|
77
|
+
* is the ATTRIBUTE as on every other boolean here. Setting it is what starts or stops
|
|
78
|
+
* editing, because the C's property setter does exactly that (gtkeditablelabel.c:406-411).
|
|
79
|
+
*/
|
|
80
|
+
get editing(): boolean {
|
|
81
|
+
return this.hasAttribute('editing');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
set editing(value: boolean) {
|
|
85
|
+
this.toggleAttribute('editing', !!value);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** `gtk_editable_label_start_editing` — refused while `editable` is FALSE, as in the C. */
|
|
89
|
+
startEditing(): void {
|
|
90
|
+
if (!this.editable) return;
|
|
91
|
+
this.editing = true;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* `gtk_editable_label_stop_editing` — `commit` decides whether the drafted text becomes
|
|
96
|
+
* the label's; FALSE resets the entry to the label instead (gtkeditablelabel.c:637-656).
|
|
97
|
+
*/
|
|
98
|
+
stopEditing(commit = false): void {
|
|
99
|
+
if (!this.editing) return;
|
|
100
|
+
if (commit) this.setAttribute('text', this._entry.value);
|
|
101
|
+
this.editing = false;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** The inner native entry, for focus and selection. */
|
|
105
|
+
get entry(): HTMLInputElement {
|
|
106
|
+
return this._entry;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
connectedCallback() {
|
|
110
|
+
if (this._initialized) return;
|
|
111
|
+
this._initialized = true;
|
|
112
|
+
|
|
113
|
+
this._label = document.createElement('span');
|
|
114
|
+
this._label.className = 'adw-editable-label-label';
|
|
115
|
+
this._label.addEventListener('click', () => this.startEditing());
|
|
116
|
+
|
|
117
|
+
this._entry = document.createElement('input');
|
|
118
|
+
this._entry.className = 'adw-editable-label-entry';
|
|
119
|
+
this._entry.type = 'text';
|
|
120
|
+
// The C moves focus onto the entry to start editing and back onto the widget to stop
|
|
121
|
+
// (gtkeditablelabel.c:614,652), so the host is the tab stop only while it shows the
|
|
122
|
+
// label — otherwise a Tab would walk through two controls for one widget.
|
|
123
|
+
this._entry.tabIndex = -1;
|
|
124
|
+
this._entry.addEventListener('keydown', (event) => {
|
|
125
|
+
if (event.key === 'Enter') {
|
|
126
|
+
event.preventDefault();
|
|
127
|
+
// Consumed here: Enter in the entry is its `activate` signal
|
|
128
|
+
// (gtkeditablelabel.c:232-234), and letting it reach the widget would start
|
|
129
|
+
// editing again the moment the commit stopped it.
|
|
130
|
+
event.stopPropagation();
|
|
131
|
+
this.stopEditing(true);
|
|
132
|
+
} else if (event.key === 'Escape') {
|
|
133
|
+
event.preventDefault();
|
|
134
|
+
event.stopPropagation();
|
|
135
|
+
this.stopEditing(false);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
this.replaceChildren(this._label, this._entry);
|
|
140
|
+
// Enter and Space start editing as a KEY BINDING of the WIDGET, not of the label node
|
|
141
|
+
// inside it (gtkeditablelabel.c:54-63), so the listener is on the host.
|
|
142
|
+
this.addEventListener('keydown', (event) => {
|
|
143
|
+
if (this.editing || (event.key !== 'Enter' && event.key !== ' ')) return;
|
|
144
|
+
event.preventDefault();
|
|
145
|
+
this.startEditing();
|
|
146
|
+
});
|
|
147
|
+
// Leaving the WIDGET is what commits, not leaving the entry, and the C waits out its
|
|
148
|
+
// grace period first so a focus move WITHIN the widget is not read as leaving it.
|
|
149
|
+
this.addEventListener('focusout', (event) => {
|
|
150
|
+
const next = event.relatedTarget;
|
|
151
|
+
if (next instanceof Node && this.contains(next)) return;
|
|
152
|
+
if (this._grace !== null) clearTimeout(this._grace);
|
|
153
|
+
this._grace = setTimeout(() => {
|
|
154
|
+
this._grace = null;
|
|
155
|
+
if (this.editing) this.stopEditing(true);
|
|
156
|
+
}, FOCUS_OUT_GRACE_MS);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
this._render();
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
disconnectedCallback() {
|
|
163
|
+
if (this._grace !== null) clearTimeout(this._grace);
|
|
164
|
+
this._grace = null;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
attributeChangedCallback(name: string, _old: string | null, value: string | null) {
|
|
168
|
+
if (!this._initialized) return;
|
|
169
|
+
switch (name) {
|
|
170
|
+
case 'text':
|
|
171
|
+
// The label's text only follows the property while nothing is being drafted,
|
|
172
|
+
// which is the condition `text_changed` tests in the C.
|
|
173
|
+
if (!this.editing) this._render();
|
|
174
|
+
break;
|
|
175
|
+
case 'editable':
|
|
176
|
+
if (value === 'false') this.stopEditing(false);
|
|
177
|
+
break;
|
|
178
|
+
case 'editing':
|
|
179
|
+
this._render();
|
|
180
|
+
if (this.editing) this._entry.focus();
|
|
181
|
+
else this.focus();
|
|
182
|
+
this.dispatchEvent(
|
|
183
|
+
new CustomEvent('notify::editing', { bubbles: true, detail: { editing: this.editing } }),
|
|
184
|
+
);
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
private _render(): void {
|
|
190
|
+
const editing = this.editing;
|
|
191
|
+
this.classList.toggle('editing', editing);
|
|
192
|
+
this._label.hidden = editing;
|
|
193
|
+
this._entry.hidden = !editing;
|
|
194
|
+
this._label.textContent = this.text;
|
|
195
|
+
this._entry.value = this.text;
|
|
196
|
+
// The tab stop FOLLOWS the state: the widget is focusable while it shows the label
|
|
197
|
+
// and hands the focus to the entry while it edits (gtkeditablelabel.c:614,652), so
|
|
198
|
+
// a Tab never reaches a control the user cannot see.
|
|
199
|
+
if (editing) this.removeAttribute('tabindex');
|
|
200
|
+
else this.setAttribute('tabindex', '0');
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
customElements.define('gtk-editable-label', GtkEditableLabel);
|