@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,358 @@
|
|
|
1
|
+
// <gtk-scale-button> — a button whose press opens a scale: the volume control of a
|
|
2
|
+
// media player, the brightness slider of a toolbar. GTK builds it from a TOGGLE BUTTON
|
|
3
|
+
// with an icon plus a popover ("dock") holding a box of [minus, scale, plus]
|
|
4
|
+
// (gtk/ui/gtkscalebutton.ui), and every rule below is transcribed from the C rather than
|
|
5
|
+
// guessed, because most of them are visible and none is "the slider just works".
|
|
6
|
+
//
|
|
7
|
+
// · THE ICON FOLLOWS THE VALUE. `gtk_scale_button_update_icon` (:1040-1098): no icon
|
|
8
|
+
// list at all draws `image-missing`; ONE icon is used for every value; TWO split the
|
|
9
|
+
// range in half; THREE or more put the first at `lower`, the second at `upper`, and
|
|
10
|
+
// spread the rest evenly over what is between — `2 + floor((value - lower) / ((upper
|
|
11
|
+
// - lower) / (n - 2)))`. With exactly three names that step is the whole span, so the
|
|
12
|
+
// interior shares ONE icon and the spread is what FIVE names buy; that is the C's
|
|
13
|
+
// arithmetic and it is transcribed rather than rounded into a nicer story.
|
|
14
|
+
// · THE DEFAULTS ARE GTKS. `gtk_adjustment_new (0, 0, 100, 2, 20, 0)` (:452) — 0…100 by
|
|
15
|
+
// 2, a page of 20 — and a VERTICAL orientation (:449-450), which is why the button
|
|
16
|
+
// grows upwards.
|
|
17
|
+
// · THE STEPS MOVE BY THE PAGE INCREMENT, not the step (:984-1013), and each stepper
|
|
18
|
+
// goes INSENSITIVE at its end: `value < upper` for plus, `lower < value` for minus
|
|
19
|
+
// (:1099-1100).
|
|
20
|
+
// · THE SCROLL HANDLER CLAMPS rather than wrapping, one step per notch, and consumes the
|
|
21
|
+
// event (:917-935).
|
|
22
|
+
//
|
|
23
|
+
// The scale itself is an `<input type="range">`, the substitution the NativeScript port
|
|
24
|
+
// already makes for `GtkScale` (`slider-row`); `Gtk.Scale` gets its own element in
|
|
25
|
+
// another work package, and until then this is the one range control in the package.
|
|
26
|
+
// `SpinState` is `@gjsify/adwaita-core`'s portable adjustment (ADR 0047), which names
|
|
27
|
+
// `GtkScaleButton.adjustment` as one of the seven properties it exists for.
|
|
28
|
+
//
|
|
29
|
+
// `active` is READ-ONLY upstream (`G_PARAM_READABLE`, :277-283): pressing the button
|
|
30
|
+
// toggles it, and the dock popping up or down follows. So it is a getter here and not an
|
|
31
|
+
// attribute — writing one would be a second door GTK does not have.
|
|
32
|
+
//
|
|
33
|
+
// The key bindings are GTK's (:355-388): Space, Return and Enter pop the scale up,
|
|
34
|
+
// Escape puts it down.
|
|
35
|
+
//
|
|
36
|
+
// A11Y: GTK's role is GROUP (:402), and GTK pushes VALUE_MIN/MAX/NOW onto the ScaleButton
|
|
37
|
+
// itself (:474-480, 1111-1113) — the upper bound being `upper - page_size`, the effective
|
|
38
|
+
// end of the range. Both land here where they belong: the role on the host, the values on
|
|
39
|
+
// the range that owns them.
|
|
40
|
+
//
|
|
41
|
+
// Reference: refs/gtk/gtk/gtkscalebutton.c (icon selection, orientation, the steppers,
|
|
42
|
+
// the scroll handler, the key bindings)
|
|
43
|
+
// Reference: refs/gtk/gtk/ui/gtkscalebutton.ui:13-56 (the template: the dock and its box)
|
|
44
|
+
// Reference: refs/libadwaita/src/stylesheet/widgets/_scale.scss (trough, highlight, slider)
|
|
45
|
+
// Copyright (c) GNOME contributors (libadwaita). LGPLv2.1+.
|
|
46
|
+
// Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
|
|
47
|
+
|
|
48
|
+
import { SpinState, adjustmentRange, parseAdjustment, type AdwAdjustmentInput } from '@gjsify/adwaita-core';
|
|
49
|
+
|
|
50
|
+
import { createGtkImage } from './gtk-image.js';
|
|
51
|
+
// SIDE-EFFECT import, for the reason `gtk-menu-button.ts` carries one: the binding is
|
|
52
|
+
// used in type position only, so a combined `import { GtkPopover }` would be elided by
|
|
53
|
+
// TypeScript and take the registration with it.
|
|
54
|
+
import './gtk-popover.js';
|
|
55
|
+
import type { GtkPopover } from './gtk-popover.js';
|
|
56
|
+
|
|
57
|
+
/** `gtk_adjustment_new (0, 0, 100, 2, 20, 0)` — the adjustment a bare scale button has. */
|
|
58
|
+
const GTK_ADJUSTMENT: AdwAdjustmentInput = {
|
|
59
|
+
lower: 0,
|
|
60
|
+
upper: 100,
|
|
61
|
+
stepIncrement: 2,
|
|
62
|
+
pageIncrement: 20,
|
|
63
|
+
pageSize: 0,
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export class GtkScaleButton extends HTMLElement {
|
|
67
|
+
private readonly _state = new SpinState();
|
|
68
|
+
private _buttonEl!: HTMLButtonElement;
|
|
69
|
+
private _glyph!: HTMLElement;
|
|
70
|
+
private _dockEl!: GtkPopover;
|
|
71
|
+
private _rangeEl!: HTMLInputElement;
|
|
72
|
+
private _minusEl!: HTMLButtonElement;
|
|
73
|
+
private _plusEl!: HTMLButtonElement;
|
|
74
|
+
private _icons: string[] = [];
|
|
75
|
+
private _initialized = false;
|
|
76
|
+
/** Set while a render writes the range, so its `input` echo is not fed back. */
|
|
77
|
+
private _syncing = false;
|
|
78
|
+
|
|
79
|
+
static get observedAttributes() {
|
|
80
|
+
return ['value', 'icons', 'adjustment', 'has-frame', 'orientation'];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** `Gtk.ScaleButton:value` — always inside the adjustment's range. */
|
|
84
|
+
get value(): number {
|
|
85
|
+
return this._state.value;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
set value(value: number) {
|
|
89
|
+
this._applyValue(value);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** `Gtk.ScaleButton:active` — read-only upstream, so read-only here. */
|
|
93
|
+
get active(): boolean {
|
|
94
|
+
return this._buttonEl?.classList.contains('checked') ?? false;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** `Gtk.ScaleButton:icons` — the icon names the value picks from. */
|
|
98
|
+
get icons(): string[] {
|
|
99
|
+
return [...this._icons];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
set icons(value: string[]) {
|
|
103
|
+
this.setAttribute('icons', JSON.stringify(value));
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** `Gtk.ScaleButton:has-frame` — false by default, which is a flat button here. */
|
|
107
|
+
get hasFrame(): boolean {
|
|
108
|
+
return this.hasAttribute('has-frame');
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
set hasFrame(value: boolean) {
|
|
112
|
+
this.toggleAttribute('has-frame', !!value);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** `GtkOrientable:orientation` — vertical by default, the GTK shape of the button. */
|
|
116
|
+
get orientation(): 'horizontal' | 'vertical' {
|
|
117
|
+
return this.getAttribute('orientation') === 'horizontal' ? 'horizontal' : 'vertical';
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
set orientation(value: 'horizontal' | 'vertical') {
|
|
121
|
+
this.setAttribute('orientation', value);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
connectedCallback() {
|
|
125
|
+
if (this._initialized) return;
|
|
126
|
+
this._initialized = true;
|
|
127
|
+
this.setAttribute('role', 'group');
|
|
128
|
+
|
|
129
|
+
this._glyph = createGtkImage('image-missing', 'scale-button-glyph');
|
|
130
|
+
this._buttonEl = document.createElement('button');
|
|
131
|
+
this._buttonEl.type = 'button';
|
|
132
|
+
this._buttonEl.className = 'adw-button scale-button-icon flat';
|
|
133
|
+
this._buttonEl.setAttribute('aria-expanded', 'false');
|
|
134
|
+
this._buttonEl.appendChild(this._glyph);
|
|
135
|
+
|
|
136
|
+
this._minusEl = this._stepButton('list-remove-symbolic', 'Decrease');
|
|
137
|
+
this._plusEl = this._stepButton('list-add-symbolic', 'Increase');
|
|
138
|
+
|
|
139
|
+
this._rangeEl = document.createElement('input');
|
|
140
|
+
this._rangeEl.type = 'range';
|
|
141
|
+
this._rangeEl.className = 'scale-button-range';
|
|
142
|
+
this._rangeEl.addEventListener('input', () => {
|
|
143
|
+
if (this._syncing) return;
|
|
144
|
+
this._applyValue(Number(this._rangeEl.value));
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
const box = document.createElement('div');
|
|
148
|
+
box.className = 'scale-button-box';
|
|
149
|
+
// `apply_orientation` REORDERS the box so a vertical scale reads plus above minus
|
|
150
|
+
// (:869-889). Reversing the column is the same arrangement without moving nodes,
|
|
151
|
+
// which would take focus off a stepper mid-click.
|
|
152
|
+
box.append(this._minusEl, this._rangeEl, this._plusEl);
|
|
153
|
+
|
|
154
|
+
this._dockEl = document.createElement('gtk-popover') as GtkPopover;
|
|
155
|
+
// `gtk/ui/gtkscalebutton.ui` gives the dock the `scale-popup` style class.
|
|
156
|
+
this._dockEl.classList.add('scale-popup');
|
|
157
|
+
this._dockEl.replaceChildren(box);
|
|
158
|
+
this._dockEl.anchor = this._buttonEl;
|
|
159
|
+
|
|
160
|
+
this.replaceChildren(this._buttonEl, this._dockEl);
|
|
161
|
+
|
|
162
|
+
this._buttonEl.addEventListener('click', () => this._toggleDock());
|
|
163
|
+
this._minusEl.addEventListener('click', () => this._step(-1));
|
|
164
|
+
this._plusEl.addEventListener('click', () => this._step(1));
|
|
165
|
+
// The dock putting ITSELF down is what releases the button, so an outside click or
|
|
166
|
+
// Escape reaches the same state as pressing it again (:436-441).
|
|
167
|
+
this._dockEl.subscribe((open) => this._renderDock(open));
|
|
168
|
+
this.addEventListener(
|
|
169
|
+
'wheel',
|
|
170
|
+
(event) => {
|
|
171
|
+
if (event.deltaY === 0) return;
|
|
172
|
+
event.preventDefault();
|
|
173
|
+
this._applyValue(this._state.value - Math.sign(event.deltaY) * this._state.adjustment.stepIncrement);
|
|
174
|
+
},
|
|
175
|
+
{ passive: false },
|
|
176
|
+
);
|
|
177
|
+
this.addEventListener('keydown', (event) => this._onKeyDown(event));
|
|
178
|
+
|
|
179
|
+
// The attribute doors, read once here: `attributeChangedCallback` runs BEFORE
|
|
180
|
+
// `connectedCallback` for an attribute the markup already carried, and it returns
|
|
181
|
+
// early while uninitialised — so an authored `icons` would otherwise be dropped.
|
|
182
|
+
this._icons = parseIcons(this.getAttribute('icons'));
|
|
183
|
+
this._syncAdjustment();
|
|
184
|
+
this._render();
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
attributeChangedCallback(name?: string) {
|
|
188
|
+
if (!this._initialized) return;
|
|
189
|
+
if (name === 'adjustment') {
|
|
190
|
+
this._syncAdjustment();
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
if (name === 'icons') {
|
|
194
|
+
this._icons = parseIcons(this.getAttribute('icons'));
|
|
195
|
+
this._render();
|
|
196
|
+
this.dispatchEvent(new CustomEvent('notify::icons', { bubbles: true }));
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
if (name === 'value') {
|
|
200
|
+
const raw = this.getAttribute('value');
|
|
201
|
+
// An absent or unreadable `value` is no write at all, not a write of zero: a
|
|
202
|
+
// `<gtk-scale-button>` with no `value` opens at the bottom of its range, which
|
|
203
|
+
// is what the adjustment `gtk_scale_button_init` builds gives.
|
|
204
|
+
if (raw === null || raw.trim() === '') return;
|
|
205
|
+
const value = Number(raw);
|
|
206
|
+
if (Number.isFinite(value)) this._applyValue(value);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
this._render();
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/** `cb_scale_value_changed` (:1092-1114) — the icon, the steppers, then the signals. */
|
|
213
|
+
private _applyValue(value: number): void {
|
|
214
|
+
const changed = this._state.setValue(value);
|
|
215
|
+
this._render();
|
|
216
|
+
if (!changed) return;
|
|
217
|
+
const current = this._state.value;
|
|
218
|
+
this.setAttribute('value', String(current));
|
|
219
|
+
this.dispatchEvent(new CustomEvent('value-changed', { bubbles: true, detail: { value: current } }));
|
|
220
|
+
this.dispatchEvent(new CustomEvent('notify::value', { bubbles: true, detail: { value: current } }));
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/** The range, from GTK's default with whatever `adjustment` authored over it. */
|
|
224
|
+
private _syncAdjustment(): void {
|
|
225
|
+
const authored = parseAdjustment(this.getAttribute('adjustment'));
|
|
226
|
+
const input: AdwAdjustmentInput = { ...GTK_ADJUSTMENT, ...authored };
|
|
227
|
+
// `value` belongs to the widget, not to the range: an adjustment that authored one
|
|
228
|
+
// must not silently move what the button already held — and an authored `value`
|
|
229
|
+
// attribute is read here, because the callback that would have applied it ran
|
|
230
|
+
// before this element was connected.
|
|
231
|
+
const raw = this.getAttribute('value');
|
|
232
|
+
const authoredValue = raw === null || raw.trim() === '' ? Number.NaN : Number(raw);
|
|
233
|
+
input.value = Number.isFinite(authoredValue) ? authoredValue : this._state.value;
|
|
234
|
+
this._state.configure(input);
|
|
235
|
+
this._render();
|
|
236
|
+
this.dispatchEvent(new CustomEvent('notify::adjustment', { bubbles: true }));
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
private _render(): void {
|
|
240
|
+
if (!this._initialized) return;
|
|
241
|
+
const value = this._state.value;
|
|
242
|
+
const [low, high] = adjustmentRange(this._state.adjustment);
|
|
243
|
+
|
|
244
|
+
const icon = selectIcon(this._icons, value, low, high);
|
|
245
|
+
if (this._glyph.getAttribute('icon-name') !== icon) this._glyph.setAttribute('icon-name', icon);
|
|
246
|
+
this._buttonEl.setAttribute('aria-label', icon);
|
|
247
|
+
|
|
248
|
+
this._syncing = true;
|
|
249
|
+
this._rangeEl.min = String(low);
|
|
250
|
+
this._rangeEl.max = String(high);
|
|
251
|
+
this._rangeEl.step = String(this._state.adjustment.stepIncrement);
|
|
252
|
+
this._rangeEl.value = String(value);
|
|
253
|
+
this._rangeEl.setAttribute('aria-valuemin', String(low));
|
|
254
|
+
this._rangeEl.setAttribute('aria-valuemax', String(high));
|
|
255
|
+
this._rangeEl.setAttribute('aria-valuenow', String(value));
|
|
256
|
+
this._syncing = false;
|
|
257
|
+
|
|
258
|
+
this._minusEl.disabled = !(low < value);
|
|
259
|
+
this._plusEl.disabled = !(value < high);
|
|
260
|
+
this._buttonEl.classList.toggle('flat', !this.hasFrame);
|
|
261
|
+
this.classList.toggle('horizontal', this.orientation === 'horizontal');
|
|
262
|
+
this.classList.toggle('vertical', this.orientation === 'vertical');
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
private _stepButton(icon: string, label: string): HTMLButtonElement {
|
|
266
|
+
const button = document.createElement('button');
|
|
267
|
+
button.type = 'button';
|
|
268
|
+
button.className = 'adw-button scale-button-step flat';
|
|
269
|
+
button.setAttribute('aria-label', label);
|
|
270
|
+
button.appendChild(createGtkImage(icon));
|
|
271
|
+
return button;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
private _toggleDock(): void {
|
|
275
|
+
if (this.active) this._dock('popdown');
|
|
276
|
+
else this._dock('popup');
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/** `gtk_scale_popup` (:940-948) — press the button in, which pops the dock up. */
|
|
280
|
+
private _dock(signal: 'popup' | 'popdown'): void {
|
|
281
|
+
const open = signal === 'popup';
|
|
282
|
+
if (this.active === open) return;
|
|
283
|
+
this._buttonEl.classList.toggle('checked', open);
|
|
284
|
+
this._buttonEl.setAttribute('aria-expanded', String(open));
|
|
285
|
+
if (open) {
|
|
286
|
+
this._dockEl.popup();
|
|
287
|
+
// `cb_popup_mapped` (:1116-1122) hands focus to the scale.
|
|
288
|
+
this._rangeEl.focus();
|
|
289
|
+
} else {
|
|
290
|
+
this._dockEl.popdown();
|
|
291
|
+
this._buttonEl.focus();
|
|
292
|
+
}
|
|
293
|
+
this.dispatchEvent(new CustomEvent(signal, { bubbles: true }));
|
|
294
|
+
this.dispatchEvent(new CustomEvent('notify::active', { bubbles: true, detail: { active: open } }));
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/** The dock closing on its own — an outside click or Escape. */
|
|
298
|
+
private _renderDock(open: boolean): void {
|
|
299
|
+
this._dock(open ? 'popup' : 'popdown');
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/** `button_click` (:1000-1013): one PAGE increment, and the end of the range stops it. */
|
|
303
|
+
private _step(direction: 1 | -1): void {
|
|
304
|
+
this._applyValue(this._state.value + direction * this._state.adjustment.pageIncrement);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/** Space / Return / Enter pop up, Escape pops down — the bindings `class_init` adds. */
|
|
308
|
+
private _onKeyDown(event: KeyboardEvent): void {
|
|
309
|
+
if (event.key === 'Escape') {
|
|
310
|
+
if (!this.active) return;
|
|
311
|
+
event.preventDefault();
|
|
312
|
+
this._dock('popdown');
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
// Only the ICON button pops. The steppers answer Space themselves as buttons, and
|
|
316
|
+
// the range needs every key it has.
|
|
317
|
+
if (event.target !== this._buttonEl) return;
|
|
318
|
+
if (event.key !== ' ' && event.key !== 'Enter' && event.key !== 'Return') return;
|
|
319
|
+
event.preventDefault();
|
|
320
|
+
this._toggleDock();
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
customElements.define('gtk-scale-button', GtkScaleButton);
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* `gtk_scale_button_update_icon` (:1040-1098) — which of the icon names the value picks.
|
|
328
|
+
* Transcribed including the arithmetic, because "spread evenly" is only true of the
|
|
329
|
+
* interior: `lower` and `upper` always take the first two names.
|
|
330
|
+
*/
|
|
331
|
+
export function selectIcon(icons: string[], value: number, lower: number, upper: number): string {
|
|
332
|
+
const first = icons[0];
|
|
333
|
+
if (first === undefined || first === '') return 'image-missing';
|
|
334
|
+
if (icons.length === 1) return first;
|
|
335
|
+
if (icons.length === 2) return value < (upper - lower) / 2 + lower ? first : (icons[1] ?? first);
|
|
336
|
+
if (value === lower) return first;
|
|
337
|
+
if (value === upper) return icons[1] ?? first;
|
|
338
|
+
const step = (upper - lower) / (icons.length - 2);
|
|
339
|
+
return icons[Math.floor((value - lower) / step) + 2] ?? first;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* The `icons` attribute, as the portable array a list-model property takes elsewhere
|
|
344
|
+
* (ADR 0046). Total in every failure mode, because malformed JSON is an author slip that
|
|
345
|
+
* must not stop the element upgrading — and an empty list has an answer of its own,
|
|
346
|
+
* `image-missing` (:1046-1050).
|
|
347
|
+
*/
|
|
348
|
+
export function parseIcons(raw: string | null | undefined): string[] {
|
|
349
|
+
if (!raw) return [];
|
|
350
|
+
let parsed: unknown;
|
|
351
|
+
try {
|
|
352
|
+
parsed = JSON.parse(raw);
|
|
353
|
+
} catch {
|
|
354
|
+
return [];
|
|
355
|
+
}
|
|
356
|
+
if (!Array.isArray(parsed)) return [];
|
|
357
|
+
return parsed.filter((name): name is string => typeof name === 'string');
|
|
358
|
+
}
|