@gjsify/adwaita-web 0.54.0 → 0.56.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.
Files changed (479) hide show
  1. package/README.md +8 -0
  2. package/dist/adwaita-web.css +8146 -3011
  3. package/dist/adwaita-web.css.map +1 -1
  4. package/lib/types/adw-application-window.spec.d.ts +1 -0
  5. package/lib/types/adw-bin.spec.d.ts +1 -0
  6. package/lib/types/adw-breakpoint-bin.spec.d.ts +1 -0
  7. package/lib/types/adw-clamp-scrollable.spec.d.ts +1 -0
  8. package/lib/types/adw-multi-layout-view.spec.d.ts +1 -0
  9. package/lib/types/adw-preferences-row.spec.d.ts +1 -0
  10. package/lib/types/adw-shortcuts.spec.d.ts +1 -0
  11. package/lib/types/adw-status-page.spec.d.ts +1 -0
  12. package/lib/types/adw-tab-bar.spec.d.ts +1 -0
  13. package/lib/types/adw-tab-button.spec.d.ts +1 -0
  14. package/lib/types/adw-tab-overview.spec.d.ts +1 -0
  15. package/lib/types/adw-view-switcher-sidebar.spec.d.ts +1 -0
  16. package/lib/types/adw-window.spec.d.ts +1 -0
  17. package/lib/types/attributes.d.ts +19 -0
  18. package/lib/types/breakpoints.d.ts +14 -3
  19. package/lib/types/construct-vectors.spec.d.ts +1 -0
  20. package/lib/types/elements/adw-action-row.d.ts +4 -0
  21. package/lib/types/elements/adw-application-window.d.ts +27 -0
  22. package/lib/types/elements/adw-bin.d.ts +17 -0
  23. package/lib/types/elements/adw-breakpoint-bin.d.ts +67 -0
  24. package/lib/types/elements/adw-clamp-scrollable.d.ts +38 -0
  25. package/lib/types/elements/adw-combo-row.d.ts +4 -0
  26. package/lib/types/elements/adw-dialog.d.ts +10 -0
  27. package/lib/types/elements/adw-entry-row.d.ts +6 -0
  28. package/lib/types/elements/adw-expander-row.d.ts +2 -0
  29. package/lib/types/elements/adw-header-bar.d.ts +6 -0
  30. package/lib/types/elements/adw-layout-slot.d.ts +19 -0
  31. package/lib/types/elements/adw-multi-layout-view.d.ts +101 -0
  32. package/lib/types/elements/adw-overlay-split-view.d.ts +13 -0
  33. package/lib/types/elements/adw-preferences-row.d.ts +31 -0
  34. package/lib/types/elements/adw-shortcuts-dialog.d.ts +13 -0
  35. package/lib/types/elements/adw-shortcuts-item.d.ts +36 -0
  36. package/lib/types/elements/adw-shortcuts-section.d.ts +14 -0
  37. package/lib/types/elements/adw-sidebar.d.ts +8 -2
  38. package/lib/types/elements/adw-spin-row.d.ts +6 -0
  39. package/lib/types/elements/adw-switch-row.d.ts +7 -0
  40. package/lib/types/elements/adw-tab-bar.d.ts +108 -0
  41. package/lib/types/elements/adw-tab-button.d.ts +32 -0
  42. package/lib/types/elements/adw-tab-overview.d.ts +199 -0
  43. package/lib/types/elements/adw-tab-view.d.ts +19 -23
  44. package/lib/types/elements/adw-toggle-group.d.ts +17 -0
  45. package/lib/types/elements/adw-view-switcher-sidebar.d.ts +84 -0
  46. package/lib/types/elements/adw-window.d.ts +40 -0
  47. package/lib/types/elements/gtk-about-dialog.d.ts +146 -0
  48. package/lib/types/elements/gtk-application-window.d.ts +34 -0
  49. package/lib/types/elements/gtk-aspect-frame.d.ts +27 -0
  50. package/lib/types/elements/gtk-button.d.ts +9 -0
  51. package/lib/types/elements/gtk-calendar.d.ts +159 -0
  52. package/lib/types/elements/gtk-center-box.d.ts +39 -0
  53. package/lib/types/elements/gtk-color-dialog-button.d.ts +69 -0
  54. package/lib/types/elements/gtk-column-view.d.ts +50 -0
  55. package/lib/types/elements/gtk-drag-icon.d.ts +78 -0
  56. package/lib/types/elements/gtk-drawing-area.d.ts +95 -0
  57. package/lib/types/elements/gtk-editable-label.d.ts +33 -0
  58. package/lib/types/elements/gtk-emoji-chooser.d.ts +84 -0
  59. package/lib/types/elements/gtk-entry.d.ts +20 -1
  60. package/lib/types/elements/gtk-expander.d.ts +49 -0
  61. package/lib/types/elements/gtk-fixed.d.ts +13 -0
  62. package/lib/types/elements/gtk-flow-box-child.d.ts +14 -0
  63. package/lib/types/elements/gtk-flow-box.d.ts +87 -0
  64. package/lib/types/elements/gtk-font-dialog-button.d.ts +83 -0
  65. package/lib/types/elements/gtk-frame.d.ts +24 -0
  66. package/lib/types/elements/gtk-gl-area.d.ts +136 -0
  67. package/lib/types/elements/gtk-graphics-offload.d.ts +24 -0
  68. package/lib/types/elements/gtk-grid-view.d.ts +39 -0
  69. package/lib/types/elements/gtk-grid.d.ts +27 -0
  70. package/lib/types/elements/gtk-header-bar.d.ts +60 -0
  71. package/lib/types/elements/gtk-inscription.d.ts +64 -0
  72. package/lib/types/elements/gtk-label.d.ts +3 -0
  73. package/lib/types/elements/gtk-level-bar.d.ts +59 -0
  74. package/lib/types/elements/gtk-link-button.d.ts +29 -0
  75. package/lib/types/elements/gtk-list-box-row.d.ts +54 -0
  76. package/lib/types/elements/gtk-list-box.d.ts +100 -0
  77. package/lib/types/elements/gtk-list-view.d.ts +73 -0
  78. package/lib/types/elements/gtk-media-controls.d.ts +142 -0
  79. package/lib/types/elements/gtk-notebook.d.ts +148 -0
  80. package/lib/types/elements/gtk-overlay.d.ts +22 -0
  81. package/lib/types/elements/gtk-page-setup-unix-dialog.d.ts +87 -0
  82. package/lib/types/elements/gtk-paned.d.ts +121 -0
  83. package/lib/types/elements/gtk-password-entry.d.ts +27 -0
  84. package/lib/types/elements/gtk-picture.d.ts +66 -0
  85. package/lib/types/elements/gtk-popover-bin.d.ts +82 -0
  86. package/lib/types/elements/gtk-popover-menu-bar.d.ts +66 -0
  87. package/lib/types/elements/gtk-popover-menu.d.ts +83 -0
  88. package/lib/types/elements/gtk-popover.d.ts +28 -3
  89. package/lib/types/elements/gtk-print-unix-dialog.d.ts +167 -0
  90. package/lib/types/elements/gtk-revealer.d.ts +55 -0
  91. package/lib/types/elements/gtk-scale-button.d.ts +59 -0
  92. package/lib/types/elements/gtk-scale.d.ts +98 -0
  93. package/lib/types/elements/gtk-scrollbar.d.ts +124 -0
  94. package/lib/types/elements/gtk-scrolled-window.d.ts +129 -0
  95. package/lib/types/elements/gtk-search-bar.d.ts +39 -0
  96. package/lib/types/elements/gtk-search-entry.d.ts +27 -0
  97. package/lib/types/elements/gtk-separator.d.ts +10 -0
  98. package/lib/types/elements/gtk-spin-button.d.ts +94 -0
  99. package/lib/types/elements/gtk-spinner.d.ts +14 -0
  100. package/lib/types/elements/gtk-stack-sidebar.d.ts +43 -0
  101. package/lib/types/elements/gtk-stack-switcher.d.ts +58 -0
  102. package/lib/types/elements/gtk-stack.d.ts +154 -0
  103. package/lib/types/elements/gtk-switch.d.ts +4 -1
  104. package/lib/types/elements/gtk-text-view.d.ts +62 -0
  105. package/lib/types/elements/gtk-text.d.ts +45 -0
  106. package/lib/types/elements/gtk-toggle-button.d.ts +45 -0
  107. package/lib/types/elements/gtk-tree-expander.d.ts +38 -0
  108. package/lib/types/elements/gtk-video.d.ts +97 -0
  109. package/lib/types/elements/gtk-viewport.d.ts +84 -0
  110. package/lib/types/elements/gtk-window-controls.d.ts +80 -0
  111. package/lib/types/elements/gtk-window-handle.d.ts +39 -0
  112. package/lib/types/elements/gtk-window.d.ts +103 -0
  113. package/lib/types/elements/justification.d.ts +2 -0
  114. package/lib/types/elements/popover-menu.d.ts +18 -0
  115. package/lib/types/elements/roving-focus.d.ts +29 -1
  116. package/lib/types/emoji-data.d.ts +38 -0
  117. package/lib/types/font-description.d.ts +96 -0
  118. package/lib/types/gtk-about-dialog.spec.d.ts +1 -0
  119. package/lib/types/gtk-action-bar.spec.d.ts +1 -0
  120. package/lib/types/gtk-application-window.spec.d.ts +1 -0
  121. package/lib/types/gtk-aspect-frame.spec.d.ts +1 -0
  122. package/lib/types/gtk-calendar.spec.d.ts +1 -0
  123. package/lib/types/gtk-center-box.spec.d.ts +1 -0
  124. package/lib/types/gtk-color-dialog-button.spec.d.ts +1 -0
  125. package/lib/types/gtk-column-view.spec.d.ts +1 -0
  126. package/lib/types/gtk-drag-icon.spec.d.ts +1 -0
  127. package/lib/types/gtk-drawing-area.spec.d.ts +1 -0
  128. package/lib/types/gtk-editable-label.spec.d.ts +1 -0
  129. package/lib/types/gtk-emoji-chooser.spec.d.ts +1 -0
  130. package/lib/types/gtk-expander.spec.d.ts +1 -0
  131. package/lib/types/gtk-fixed.spec.d.ts +1 -0
  132. package/lib/types/gtk-flow-box.spec.d.ts +1 -0
  133. package/lib/types/gtk-font-dialog-button.spec.d.ts +1 -0
  134. package/lib/types/gtk-frame.spec.d.ts +1 -0
  135. package/lib/types/gtk-gl-area.spec.d.ts +1 -0
  136. package/lib/types/gtk-graphics-offload.spec.d.ts +1 -0
  137. package/lib/types/gtk-grid-view.spec.d.ts +1 -0
  138. package/lib/types/gtk-grid.spec.d.ts +1 -0
  139. package/lib/types/gtk-header-bar.spec.d.ts +1 -0
  140. package/lib/types/gtk-inscription.spec.d.ts +1 -0
  141. package/lib/types/gtk-level-bar.spec.d.ts +1 -0
  142. package/lib/types/gtk-link-button.spec.d.ts +1 -0
  143. package/lib/types/gtk-list-box.spec.d.ts +1 -0
  144. package/lib/types/gtk-list-view.spec.d.ts +1 -0
  145. package/lib/types/gtk-media-controls.spec.d.ts +1 -0
  146. package/lib/types/gtk-notebook.spec.d.ts +1 -0
  147. package/lib/types/gtk-overlay.spec.d.ts +1 -0
  148. package/lib/types/gtk-paned.spec.d.ts +1 -0
  149. package/lib/types/gtk-password-entry.spec.d.ts +1 -0
  150. package/lib/types/gtk-picture.spec.d.ts +1 -0
  151. package/lib/types/gtk-popover-bin.spec.d.ts +1 -0
  152. package/lib/types/gtk-popover-menu-bar.spec.d.ts +1 -0
  153. package/lib/types/gtk-popover-menu.spec.d.ts +1 -0
  154. package/lib/types/gtk-popover-role.spec.d.ts +1 -0
  155. package/lib/types/gtk-popover.spec.d.ts +1 -0
  156. package/lib/types/gtk-print-dialogs.spec.d.ts +1 -0
  157. package/lib/types/gtk-revealer.spec.d.ts +1 -0
  158. package/lib/types/gtk-scale-button.spec.d.ts +1 -0
  159. package/lib/types/gtk-scale.spec.d.ts +1 -0
  160. package/lib/types/gtk-scrollbar.spec.d.ts +1 -0
  161. package/lib/types/gtk-scrolled-window.spec.d.ts +1 -0
  162. package/lib/types/gtk-search-bar.spec.d.ts +1 -0
  163. package/lib/types/gtk-search-entry.spec.d.ts +1 -0
  164. package/lib/types/gtk-separator.spec.d.ts +1 -0
  165. package/lib/types/gtk-spin-button.spec.d.ts +1 -0
  166. package/lib/types/gtk-spinner.spec.d.ts +1 -0
  167. package/lib/types/gtk-stack-sidebar.spec.d.ts +1 -0
  168. package/lib/types/gtk-stack-switcher.spec.d.ts +1 -0
  169. package/lib/types/gtk-stack.spec.d.ts +1 -0
  170. package/lib/types/gtk-text-view.spec.d.ts +1 -0
  171. package/lib/types/gtk-text.spec.d.ts +1 -0
  172. package/lib/types/gtk-toggle-button.spec.d.ts +1 -0
  173. package/lib/types/gtk-tree-expander.spec.d.ts +1 -0
  174. package/lib/types/gtk-video.spec.d.ts +1 -0
  175. package/lib/types/gtk-viewport.spec.d.ts +1 -0
  176. package/lib/types/gtk-window-controls.spec.d.ts +1 -0
  177. package/lib/types/gtk-window-handle.spec.d.ts +1 -0
  178. package/lib/types/gtk-window.spec.d.ts +1 -0
  179. package/lib/types/index.d.ts +4 -1
  180. package/lib/types/list-view-dom.d.ts +44 -0
  181. package/lib/types/namespace/adw.d.ts +12 -0
  182. package/lib/types/namespace/gtk.d.ts +61 -0
  183. package/lib/types/page-setup.d.ts +100 -0
  184. package/lib/types/row-line-clamp.d.ts +20 -0
  185. package/lib/types/row-tooltip.d.ts +8 -0
  186. package/lib/types/row-tooltip.spec.d.ts +1 -0
  187. package/lib/types/scroll-shading.d.ts +15 -1
  188. package/lib/types/shared-tree-builder.d.ts +75 -17
  189. package/lib/types/shared-tree-mount.spec.d.ts +1 -0
  190. package/lib/types/signals.d.ts +4 -0
  191. package/lib/types/styles.generated.d.ts +1 -1
  192. package/lib/types/tab-chip.d.ts +73 -0
  193. package/lib/types/template-classes.d.ts +11 -0
  194. package/lib/types/widget-size.spec.d.ts +1 -0
  195. package/package.json +12 -8
  196. package/scss/_action_row.scss +41 -17
  197. package/scss/_application_window.scss +26 -0
  198. package/scss/_aspect_frame.scss +25 -0
  199. package/scss/_bin.scss +26 -0
  200. package/scss/_button.scss +45 -0
  201. package/scss/_button_row.scss +5 -0
  202. package/scss/_calendar.scss +176 -0
  203. package/scss/_center_box.scss +25 -0
  204. package/scss/_checks.scss +6 -1
  205. package/scss/_clamp_scrollable.scss +28 -0
  206. package/scss/_color_button.scss +67 -0
  207. package/scss/_column_view.scss +126 -0
  208. package/scss/_drag_icon.scss +55 -0
  209. package/scss/_drawing.scss +85 -0
  210. package/scss/_emoji_chooser.scss +213 -0
  211. package/scss/_entry.scss +13 -5
  212. package/scss/_entry_row.scss +1 -1
  213. package/scss/_expander.scss +113 -0
  214. package/scss/_expander_row.scss +36 -3
  215. package/scss/_fixed.scss +29 -0
  216. package/scss/_flow_box.scss +94 -0
  217. package/scss/_font_button.scss +63 -0
  218. package/scss/_frame.scss +41 -0
  219. package/scss/_grid.scss +19 -0
  220. package/scss/_grid_view.scss +46 -0
  221. package/scss/_gtk_about_dialog.scss +186 -0
  222. package/scss/_headerbar.scss +134 -1
  223. package/scss/_icons.generated.scss +186 -0
  224. package/scss/_inscription.scss +125 -0
  225. package/scss/_level_bar.scss +190 -0
  226. package/scss/_link.scss +82 -0
  227. package/scss/_list_box.scss +88 -0
  228. package/scss/_list_view.scss +96 -0
  229. package/scss/_media_controls.scss +139 -0
  230. package/scss/_overlay.scss +68 -0
  231. package/scss/_paned.scss +130 -0
  232. package/scss/_password_entry.scss +83 -0
  233. package/scss/_picture.scss +80 -0
  234. package/scss/_popover_bin.scss +53 -0
  235. package/scss/_popover_menu_bar.scss +104 -0
  236. package/scss/_preferences_row.scss +60 -0
  237. package/scss/_print_dialogs.scss +328 -0
  238. package/scss/_reset.scss +21 -19
  239. package/scss/_revealer.scss +37 -0
  240. package/scss/_row.scss +36 -5
  241. package/scss/_scale.scss +298 -0
  242. package/scss/_scale_button.scss +167 -0
  243. package/scss/_scrollbar.scss +230 -0
  244. package/scss/_scrolled_window.scss +131 -0
  245. package/scss/_search_bar.scss +118 -0
  246. package/scss/_search_entry.scss +86 -0
  247. package/scss/_separator.scss +44 -0
  248. package/scss/_shortcuts_dialog.scss +100 -0
  249. package/scss/_spin_button.scss +172 -0
  250. package/scss/_spin_row.scss +56 -8
  251. package/scss/_spinner.scss +85 -4
  252. package/scss/_stack.scss +729 -0
  253. package/scss/_status_page.scss +1 -1
  254. package/scss/_switch.scss +13 -5
  255. package/scss/_switch_row.scss +10 -0
  256. package/scss/_tab_bar.scss +317 -0
  257. package/scss/_tab_button.scss +98 -0
  258. package/scss/_tab_overview.scss +483 -0
  259. package/scss/_text.scss +182 -0
  260. package/scss/_theme.scss +1 -1
  261. package/scss/_toggle_group.scss +28 -0
  262. package/scss/_tree_expander.scss +62 -0
  263. package/scss/_variables.scss +1 -1
  264. package/scss/_video.scss +146 -0
  265. package/scss/_view_switcher_sidebar.scss +112 -0
  266. package/scss/_viewport.scss +50 -0
  267. package/scss/_widget.scss +14 -3
  268. package/scss/_window.scss +131 -2
  269. package/scss/_window_handle.scss +20 -0
  270. package/scss/adwaita-skin.scss +109 -0
  271. package/src/adw-action-rows.spec.ts +331 -0
  272. package/src/adw-application-window.spec.ts +118 -0
  273. package/src/adw-bin.spec.ts +75 -0
  274. package/src/adw-breakpoint-bin.spec.ts +324 -0
  275. package/src/adw-clamp-scrollable.spec.ts +189 -0
  276. package/src/adw-header-bar.spec.ts +18 -0
  277. package/src/adw-multi-layout-view.spec.ts +243 -0
  278. package/src/adw-preferences-row.spec.ts +164 -0
  279. package/src/adw-row-state.spec.ts +142 -0
  280. package/src/adw-shortcuts.spec.ts +155 -0
  281. package/src/adw-status-page.spec.ts +124 -0
  282. package/src/adw-tab-bar.spec.ts +287 -0
  283. package/src/adw-tab-button.spec.ts +101 -0
  284. package/src/adw-tab-overview.spec.ts +443 -0
  285. package/src/adw-view-switcher-sidebar.spec.ts +281 -0
  286. package/src/adw-window.spec.ts +129 -0
  287. package/src/attributes.ts +52 -0
  288. package/src/breakpoints.ts +25 -8
  289. package/src/capabilities.d.mts +3 -0
  290. package/src/capabilities.mjs +21 -0
  291. package/src/connect-lifecycle.spec.ts +12 -0
  292. package/src/construct-vectors.spec.ts +175 -0
  293. package/src/elements/adw-action-row.ts +31 -2
  294. package/src/elements/adw-alert-dialog.ts +4 -1
  295. package/src/elements/adw-application-window.ts +154 -0
  296. package/src/elements/adw-bin.ts +101 -0
  297. package/src/elements/adw-breakpoint-bin.ts +287 -0
  298. package/src/elements/adw-button-row.ts +7 -1
  299. package/src/elements/adw-clamp-scrollable.ts +207 -0
  300. package/src/elements/adw-combo-row.ts +26 -1
  301. package/src/elements/adw-dialog.ts +19 -0
  302. package/src/elements/adw-entry-row.ts +22 -12
  303. package/src/elements/adw-expander-row.ts +34 -1
  304. package/src/elements/adw-header-bar.ts +18 -4
  305. package/src/elements/adw-layout-slot.ts +95 -0
  306. package/src/elements/adw-multi-layout-view.ts +326 -0
  307. package/src/elements/adw-overlay-split-view.ts +29 -6
  308. package/src/elements/adw-preferences-row.ts +153 -0
  309. package/src/elements/adw-shortcuts-dialog.ts +52 -0
  310. package/src/elements/adw-shortcuts-item.ts +171 -0
  311. package/src/elements/adw-shortcuts-section.ts +86 -0
  312. package/src/elements/adw-sidebar.ts +74 -7
  313. package/src/elements/adw-spin-row.ts +37 -2
  314. package/src/elements/adw-status-page.ts +10 -2
  315. package/src/elements/adw-switch-row.ts +53 -2
  316. package/src/elements/adw-tab-bar.ts +529 -0
  317. package/src/elements/adw-tab-button.ts +194 -0
  318. package/src/elements/adw-tab-overview.ts +1011 -0
  319. package/src/elements/adw-tab-view.ts +66 -145
  320. package/src/elements/adw-toggle-group.ts +138 -14
  321. package/src/elements/adw-view-stack.ts +18 -0
  322. package/src/elements/adw-view-switcher-sidebar.ts +332 -0
  323. package/src/elements/adw-window.ts +190 -11
  324. package/src/elements/checks.ts +35 -8
  325. package/src/elements/gtk-about-dialog.ts +811 -0
  326. package/src/elements/gtk-application-window.ts +108 -0
  327. package/src/elements/gtk-aspect-frame.ts +160 -0
  328. package/src/elements/gtk-button.ts +12 -0
  329. package/src/elements/gtk-calendar.ts +757 -0
  330. package/src/elements/gtk-center-box.ts +184 -0
  331. package/src/elements/gtk-color-dialog-button.ts +278 -0
  332. package/src/elements/gtk-column-view.ts +320 -0
  333. package/src/elements/gtk-drag-icon.ts +257 -0
  334. package/src/elements/gtk-drawing-area.ts +303 -0
  335. package/src/elements/gtk-editable-label.ts +204 -0
  336. package/src/elements/gtk-emoji-chooser.ts +542 -0
  337. package/src/elements/gtk-entry.ts +39 -5
  338. package/src/elements/gtk-expander.ts +301 -0
  339. package/src/elements/gtk-fixed.ts +99 -0
  340. package/src/elements/gtk-flow-box-child.ts +68 -0
  341. package/src/elements/gtk-flow-box.ts +480 -0
  342. package/src/elements/gtk-font-dialog-button.ts +432 -0
  343. package/src/elements/gtk-frame.ts +174 -0
  344. package/src/elements/gtk-gl-area.ts +476 -0
  345. package/src/elements/gtk-graphics-offload.ts +130 -0
  346. package/src/elements/gtk-grid-view.ts +168 -0
  347. package/src/elements/gtk-grid.ts +127 -0
  348. package/src/elements/gtk-header-bar.ts +273 -0
  349. package/src/elements/gtk-inscription.ts +387 -0
  350. package/src/elements/gtk-label.ts +19 -11
  351. package/src/elements/gtk-level-bar.ts +323 -0
  352. package/src/elements/gtk-link-button.ts +138 -0
  353. package/src/elements/gtk-list-box-row.ts +195 -0
  354. package/src/elements/gtk-list-box.ts +413 -0
  355. package/src/elements/gtk-list-view.ts +370 -0
  356. package/src/elements/gtk-media-controls.ts +509 -0
  357. package/src/elements/gtk-notebook.ts +664 -0
  358. package/src/elements/gtk-overlay.ts +149 -0
  359. package/src/elements/gtk-page-setup-unix-dialog.ts +420 -0
  360. package/src/elements/gtk-paned.ts +597 -0
  361. package/src/elements/gtk-password-entry.ts +170 -0
  362. package/src/elements/gtk-picture.ts +254 -0
  363. package/src/elements/gtk-popover-bin.ts +332 -0
  364. package/src/elements/gtk-popover-menu-bar.ts +355 -0
  365. package/src/elements/gtk-popover-menu.ts +339 -0
  366. package/src/elements/gtk-popover.ts +92 -10
  367. package/src/elements/gtk-print-unix-dialog.ts +989 -0
  368. package/src/elements/gtk-progress-bar.ts +24 -11
  369. package/src/elements/gtk-revealer.ts +406 -0
  370. package/src/elements/gtk-scale-button.ts +358 -0
  371. package/src/elements/gtk-scale.ts +492 -0
  372. package/src/elements/gtk-scrollbar.ts +528 -0
  373. package/src/elements/gtk-scrolled-window.ts +653 -0
  374. package/src/elements/gtk-search-bar.ts +200 -0
  375. package/src/elements/gtk-search-entry.ts +172 -0
  376. package/src/elements/gtk-separator.ts +52 -0
  377. package/src/elements/gtk-spin-button.ts +475 -0
  378. package/src/elements/gtk-spinner.ts +126 -0
  379. package/src/elements/gtk-stack-sidebar.ts +212 -0
  380. package/src/elements/gtk-stack-switcher.ts +279 -0
  381. package/src/elements/gtk-stack.ts +748 -0
  382. package/src/elements/gtk-switch.ts +52 -19
  383. package/src/elements/gtk-text-view.ts +290 -0
  384. package/src/elements/gtk-text.ts +219 -0
  385. package/src/elements/gtk-toggle-button.ts +239 -0
  386. package/src/elements/gtk-tree-expander.ts +243 -0
  387. package/src/elements/gtk-video.ts +423 -0
  388. package/src/elements/gtk-viewport.ts +277 -0
  389. package/src/elements/gtk-window-controls.ts +341 -0
  390. package/src/elements/gtk-window-handle.ts +221 -0
  391. package/src/elements/gtk-window.ts +372 -0
  392. package/src/elements/justification.ts +24 -0
  393. package/src/elements/popover-menu.ts +24 -0
  394. package/src/elements/roving-focus.ts +53 -21
  395. package/src/emoji-data.ts +577 -0
  396. package/src/entry-rows.spec.ts +31 -0
  397. package/src/font-description.ts +238 -0
  398. package/src/gtk-about-dialog.spec.ts +250 -0
  399. package/src/gtk-action-bar.spec.ts +89 -0
  400. package/src/gtk-application-window.spec.ts +107 -0
  401. package/src/gtk-aspect-frame.spec.ts +114 -0
  402. package/src/gtk-calendar.spec.ts +589 -0
  403. package/src/gtk-center-box.spec.ts +125 -0
  404. package/src/gtk-color-dialog-button.spec.ts +141 -0
  405. package/src/gtk-column-view.spec.ts +154 -0
  406. package/src/gtk-drag-icon.spec.ts +190 -0
  407. package/src/gtk-drawing-area.spec.ts +211 -0
  408. package/src/gtk-editable-label.spec.ts +190 -0
  409. package/src/gtk-emoji-chooser.spec.ts +173 -0
  410. package/src/gtk-entry.spec.ts +23 -0
  411. package/src/gtk-expander.spec.ts +170 -0
  412. package/src/gtk-fixed.spec.ts +97 -0
  413. package/src/gtk-flow-box.spec.ts +289 -0
  414. package/src/gtk-font-dialog-button.spec.ts +166 -0
  415. package/src/gtk-frame.spec.ts +119 -0
  416. package/src/gtk-gl-area.spec.ts +361 -0
  417. package/src/gtk-graphics-offload.spec.ts +119 -0
  418. package/src/gtk-grid-view.spec.ts +106 -0
  419. package/src/gtk-grid.spec.ts +122 -0
  420. package/src/gtk-header-bar.spec.ts +202 -0
  421. package/src/gtk-inscription.spec.ts +235 -0
  422. package/src/gtk-level-bar.spec.ts +199 -0
  423. package/src/gtk-link-button.spec.ts +117 -0
  424. package/src/gtk-list-box.spec.ts +422 -0
  425. package/src/gtk-list-view.spec.ts +203 -0
  426. package/src/gtk-media-controls.spec.ts +295 -0
  427. package/src/gtk-notebook.spec.ts +546 -0
  428. package/src/gtk-overlay.spec.ts +141 -0
  429. package/src/gtk-paned.spec.ts +267 -0
  430. package/src/gtk-password-entry.spec.ts +150 -0
  431. package/src/gtk-picture.spec.ts +172 -0
  432. package/src/gtk-popover-bin.spec.ts +229 -0
  433. package/src/gtk-popover-menu-bar.spec.ts +296 -0
  434. package/src/gtk-popover-menu.spec.ts +261 -0
  435. package/src/gtk-popover-role.spec.ts +138 -0
  436. package/src/gtk-popover.spec.ts +264 -0
  437. package/src/gtk-print-dialogs.spec.ts +251 -0
  438. package/src/gtk-revealer.spec.ts +164 -0
  439. package/src/gtk-scale-button.spec.ts +218 -0
  440. package/src/gtk-scale.spec.ts +213 -0
  441. package/src/gtk-scrollbar.spec.ts +244 -0
  442. package/src/gtk-scrolled-window.spec.ts +262 -0
  443. package/src/gtk-search-bar.spec.ts +179 -0
  444. package/src/gtk-search-entry.spec.ts +142 -0
  445. package/src/gtk-separator.spec.ts +74 -0
  446. package/src/gtk-spin-button.spec.ts +186 -0
  447. package/src/gtk-spinner.spec.ts +130 -0
  448. package/src/gtk-stack-sidebar.spec.ts +217 -0
  449. package/src/gtk-stack-switcher.spec.ts +249 -0
  450. package/src/gtk-stack.spec.ts +432 -0
  451. package/src/gtk-text-view.spec.ts +189 -0
  452. package/src/gtk-text.spec.ts +163 -0
  453. package/src/gtk-toggle-button.spec.ts +186 -0
  454. package/src/gtk-tree-expander.spec.ts +201 -0
  455. package/src/gtk-video.spec.ts +240 -0
  456. package/src/gtk-viewport.spec.ts +140 -0
  457. package/src/gtk-window-controls.spec.ts +232 -0
  458. package/src/gtk-window-handle.spec.ts +158 -0
  459. package/src/gtk-window.spec.ts +202 -0
  460. package/src/index.ts +9 -1
  461. package/src/keyboard-operable.spec.ts +77 -9
  462. package/src/list-view-dom.ts +121 -0
  463. package/src/namespace/adw.ts +12 -0
  464. package/src/namespace/gtk.ts +61 -0
  465. package/src/page-setup.ts +222 -0
  466. package/src/row-line-clamp.ts +74 -0
  467. package/src/row-tooltip.spec.ts +313 -0
  468. package/src/row-tooltip.ts +52 -0
  469. package/src/scroll-shading.ts +18 -1
  470. package/src/shared-tree-builder.ts +336 -41
  471. package/src/shared-tree-mount.spec.ts +130 -0
  472. package/src/shared-trees.spec.ts +15 -0
  473. package/src/signals.ts +15 -0
  474. package/src/style-classes.spec.ts +9 -8
  475. package/src/styles.generated.ts +1 -1
  476. package/src/tab-chip.ts +200 -0
  477. package/src/template-classes.ts +45 -0
  478. package/src/test.browser.mts +160 -0
  479. package/src/widget-size.spec.ts +117 -0
@@ -0,0 +1,149 @@
1
+ // <gtk-overlay> — other widgets stacked ON TOP of one main child.
2
+ //
3
+ // `Gtk.Overlay` owns ONE property, `child`, and it is a widget: the main child, the one
4
+ // the overlay sizes ITSELF to ("An overlay's minimum and natural sizes are those of its
5
+ // main child", gtkoverlay.c:56-58). Every other knob lives on `GtkOverlayLayoutChild` —
6
+ // `measure` (does this child's size count towards the overlay's?) and `clip-overlay` (is
7
+ // it clipped to the parent?) — which GTK reaches per child through
8
+ // `gtk_overlay_set_measure_overlay()` / `_set_clip_overlay()`, and a reader reaches in
9
+ // markup as the child's own placement. Both are one CSS switch here, so they are declared
10
+ // on the CHILD and this element does not observe them. Neither is a scalar of
11
+ // `GtkOverlay`, which is why the element observes none.
12
+ //
13
+ // THE PLACEMENT IS `gtk_overlay_get_child_position` (gtkoverlay.c:130-196) IN CSS, and
14
+ // the mapping is one-to-one because that function is already an alignment rule:
15
+ //
16
+ // · it fills the overlay with the main child's own allocation — `_childEl` is
17
+ // `display: contents`, so the authored child is laid out as a direct child of the
18
+ // host and the overlay takes its size;
19
+ // · each overlay child is given `min(w, natural)` and then placed by its own
20
+ // `halign`/`valign` — exactly what an auto margin does in a flex box, which is why
21
+ // the generic `[halign]` / `[valign]` rules in `_widget.scss` place an overlay child
22
+ // with no rule of its own;
23
+ // · `GTK_ALIGN_FILL` — the DEFAULT for both properties — grows the child to the whole
24
+ // allocation on that axis (gtkoverlay.c:156, :180). In flex that is `align-self:
25
+ // stretch` on the cross axis, and on the main axis a `flex-grow` this partial gives
26
+ // only to a child that named no `halign` (`:not([halign])`): a child that DID name
27
+ // one also carries an auto margin, and an auto margin would be handed the space a
28
+ // grow factor had already spent.
29
+ //
30
+ // The layer does not intercept input meant for the main child: it is `pointer-events: none`
31
+ // with each overlay child re-enabling them on its own box, because GTK delivers an event
32
+ // to the widget whose ALLOCATION it lands in and to nothing else.
33
+ //
34
+ // `.left` / `.right` / `.top` / `.bottom` are the classes `gtk_overlay_child_update_style_classes`
35
+ // adds to an overlay child (gtkoverlaylayout.c:335-388), which the widget's own doc
36
+ // section publishes as part of the CSS node contract (gtkoverlay.c:66-71): one per edge
37
+ // the child's alignment actually pinned it to. `halign=start` in an RTL row is the RIGHT
38
+ // edge, which is what `effective_align` (gtkoverlay.c:111-128) decides before the classes
39
+ // are read.
40
+ //
41
+ // A11Y: no role of its own — GtkOverlay is a plain GtkWidget, and naming one would flatten
42
+ // the child a screen reader should be able to reach. The MAIN child keeps the name; an
43
+ // overlay child that is itself a widget keeps its own.
44
+ //
45
+ // Reference: refs/gtk/gtk/gtkoverlay.c (child, get_child_position, compute_expand)
46
+ // Reference: refs/gtk/gtk/gtkoverlaylayout.c (measure, clip_overlay, the edge classes)
47
+ // Copyright (c) The GTK Team. LGPLv2.1+.
48
+ // Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
49
+
50
+ import { bindSlottedChildren } from '../slotted-children.js';
51
+
52
+ /** The edges `gtk_overlay_child_update_style_classes` can pin a child to. */
53
+ const EDGES = ['left', 'right', 'top', 'bottom'] as const;
54
+
55
+ export class GtkOverlay extends HTMLElement {
56
+ private _childEl!: HTMLDivElement;
57
+ private _layerEl!: HTMLDivElement;
58
+ private _initialized = false;
59
+ /**
60
+ * GTK recomputes the edge classes on every allocation of an overlay child, which is a
61
+ * frame-clock fact this renderer does not have; a ResizeObserver on the layer is the
62
+ * honest substitute — it fires on the changes the C would answer to.
63
+ */
64
+ private _resize: ResizeObserver | null = null;
65
+ /** The two things a child can do that change which edge it is pinned to. */
66
+ private _mutations: MutationObserver | null = null;
67
+
68
+ static get observedAttributes() {
69
+ return [];
70
+ }
71
+
72
+ /** `Gtk.Overlay:child` — the main child, as the light-DOM node the host adopted. */
73
+ get child(): Element | null {
74
+ return this._childEl?.firstElementChild ?? null;
75
+ }
76
+
77
+ /** The absolutely-positioned layer every `slot="overlay"` child lands in. */
78
+ get overlayLayer(): HTMLDivElement {
79
+ return this._layerEl;
80
+ }
81
+
82
+ connectedCallback() {
83
+ if (this._initialized) {
84
+ // The teardown below released both observers on the way out, so a re-parent has
85
+ // to arm them again — see `scripts/check-adwaita-connect-rebind.mjs`.
86
+ this._observe();
87
+ return;
88
+ }
89
+ this._initialized = true;
90
+
91
+ this._childEl = document.createElement('div');
92
+ this._childEl.className = 'adw-overlay-child';
93
+
94
+ this._layerEl = document.createElement('div');
95
+ this._layerEl.className = 'adw-overlay-layer';
96
+
97
+ // GtkBuildable's `<child type="overlay">` becomes the `overlay` SLOT name, and the
98
+ // bare `<child>` — the default — is the main child, which is the pairing
99
+ // `packages/framework/gtk-host/src/descriptors/gtk.ts` curates for `GtkOverlay`
100
+ // (`slots: { child, overlay }`, `defaultSlot: 'child'`).
101
+ bindSlottedChildren(this, [{ into: this._childEl }, { name: 'overlay', into: this._layerEl }]).install(
102
+ this._childEl,
103
+ this._layerEl,
104
+ );
105
+
106
+ this._observe();
107
+ }
108
+
109
+ disconnectedCallback() {
110
+ this._resize?.disconnect();
111
+ this._resize = null;
112
+ this._mutations?.disconnect();
113
+ this._mutations = null;
114
+ }
115
+
116
+ private _observe(): void {
117
+ if (this._resize) return;
118
+ // ResizeObserver delivers an initial observation on observe(), so the first edge
119
+ // classes land before paint without a separate seeding pass.
120
+ this._resize = new ResizeObserver(() => this._syncEdgeClasses());
121
+ this._resize.observe(this._layerEl);
122
+ // A child adopted after `install()` and an alignment rewritten on one are both
123
+ // changes GTK would see at the next allocation of that child; the layer itself does
124
+ // not resize, so the observer is what hears them. `subtree` is what makes it hear
125
+ // them — `halign` is on a CHILD of the layer, not on the layer.
126
+ this._mutations = new MutationObserver(() => this._syncEdgeClasses());
127
+ this._mutations.observe(this._layerEl, { childList: true, attributes: true, subtree: true });
128
+ this._syncEdgeClasses();
129
+ }
130
+
131
+ private _syncEdgeClasses(): void {
132
+ // `effective_align` first: under RTL a `halign="start"` child is pinned to the
133
+ // RIGHT edge, and the class has to say so.
134
+ const rtl = this.matches(':dir(rtl)');
135
+ for (const child of this._layerEl.children) {
136
+ const halign = child.getAttribute('halign');
137
+ const valign = child.getAttribute('valign');
138
+ const pinned: Record<(typeof EDGES)[number], boolean> = {
139
+ left: rtl ? halign === 'end' : halign === 'start',
140
+ right: rtl ? halign === 'start' : halign === 'end',
141
+ top: valign === 'start',
142
+ bottom: valign === 'end',
143
+ };
144
+ for (const edge of EDGES) child.classList.toggle(edge, pinned[edge]);
145
+ }
146
+ }
147
+ }
148
+
149
+ customElements.define('gtk-overlay', GtkOverlay);
@@ -0,0 +1,420 @@
1
+ // <adw-page-setup-unix-dialog> — the browser counterpart of `GtkPageSetupUnixDialog`:
2
+ // the page-setup dialog Unix platforms have instead of a native one, which is a
3
+ // two-column grid — "Format for:" and "Paper size:" drop downs, a label that reports the
4
+ // chosen sheet's size and margins, and four orientation radios — over the Cancel / Apply
5
+ // action area (gtkpagesetupunixdialog.ui).
6
+ //
7
+ // The DIALOG CHROME IS `<adw-dialog>`'s, not a copy: this element extends it, so the
8
+ // scrim, the sheet, `present()`/`close()`, `can-close`, Escape, the Tab trap and the
9
+ // return-focus are the ones `adw-dialog.ts` owns. There is no `aria-modal` below for the
10
+ // reason `modal-surface.ts` exists.
11
+ //
12
+ // WHAT IS PORTED FROM `gtkpagesetupunixdialog.c`
13
+ //
14
+ // · the twelve `common_paper_sizes` (:121-134) in `fill_paper_sizes_from_printer`
15
+ // (:470-491), each with `gtk_paper_size_set_paper_size_and_default_margins`'s
16
+ // defaults — all of `src/page-setup.ts`, which holds the sizes, the margins and the
17
+ // `double_to_string` munging (:594-628) the label is built from;
18
+ // · `paper_size_changed` (:635-758): selecting a size rewrites the label to
19
+ // `W × H unit` and puts the four margins in its TOOLTIP, and selecting the
20
+ // `Manage Custom Sizes…` row snaps back to the previous setup and opens the custom
21
+ // paper dialog — which is not reachable here (see below), so the row falls back to the
22
+ // previous setup exactly as the C does before it presents anything;
23
+ // · `get_orientation` / `set_orientation` (:788-838): four check buttons in one group,
24
+ // read and written through the same four members;
25
+ // · `set_page_setup` (:823-833) and `get_page_setup` (:840-863): the property is the
26
+ // page setup, and reading it returns the current SELECTION with the orientation the
27
+ // radios hold — the size lookup walks the drop-down's model, which is why setting a
28
+ // setup whose margins no row has appends it (`set_paper_size`, :429-467 with
29
+ // `add_item` TRUE);
30
+ // · `set_print_settings` (:897-931) / `get_print_settings` (:940): the only thing a
31
+ // print settings object does here is select the printer named by its
32
+ // `format-for-printer` key, and `printer_changed_callback` (:557-609) writes that key
33
+ // back whenever the printer changes;
34
+ // · `gtk_page_setup_unix_dialog_new` (:771-786): a NULL title means "Page Setup";
35
+ // · `match_func` (:235-238): a VIRTUAL printer — the "Any Printer" row every dialog
36
+ // starts with — is not a real target, so selecting it falls back to the common paper
37
+ // sizes instead of a printer's own list.
38
+ //
39
+ // NOT PORTED, and it needs a print subsystem rather than a browser: the printer list. GTK
40
+ // builds it from `gtk_print_backend_load_modules` (:397-420), i.e. CUPS over D-Bus. With
41
+ // no backends there is exactly the row the C synthesises in code — "Any Printer" / "For
42
+ // portable documents" (:281-297) — plus whatever `printers` a caller supplies, which is
43
+ // the honest shape for a page: the list is an INPUT here, not a discovery. The
44
+ // `Manage Custom Sizes…` row is present and behaves as the C does before it presents the
45
+ // custom-paper dialog, which needs the same backends to read and write the user's
46
+ // printer's paper list.
47
+ //
48
+ // Attributes: `title`, `open`, `can-close`, `content-width`, `content-height`,
49
+ // `presentation-mode`, `show-header` from the `<adw-dialog>` chrome it extends. The widget
50
+ // declares NO GObject properties of its own — `page-setup` and `print-settings` are
51
+ // `GtkPageSetup` / `GtkPrintSettings` OBJECTS, which is why they are element properties
52
+ // carrying the plain data `src/page-setup.ts` defines.
53
+ //
54
+ // Properties: `pageSetup` (get/set, the plain `PageSetup`), `printSettings` (get/set, the
55
+ // one `format-for-printer` key), `printers` (get/set, `{ name, location }[]`).
56
+ //
57
+ // Events: the base class's `notify::open` (`{ open }`) and `closed`, plus `response`
58
+ // (detail `{ responseId }`) for the action area's two buttons — GTK_RESPONSE_CANCEL (-6)
59
+ // and GTK_RESPONSE_OK (-5), the ids `gtk_dialog_add_buttons` passes.
60
+ //
61
+ // A11y: role `dialog` from `AdwModalSurface`; the two drop downs are labelled by the
62
+ // grid labels beside them (`aria-labelledby`), and the four orientation buttons are one
63
+ // radio group, as GTK's `group` property makes them.
64
+ //
65
+ // Reference: refs/gtk/gtk/print/gtkpagesetupunixdialog.c (every rule above, by line)
66
+ // Reference: refs/gtk/gtk/print/ui/gtkpagesetupunixdialog.ui (the grid and its labels)
67
+ // Reference: refs/libadwaita/src/stylesheet/widgets/_dialogs.scss:36-42
68
+ // (`window.pagesetup:not(.ssd-frame)`: a FLAT titlebar)
69
+ // Reference: packages/web/adwaita-web/src/elements/adw-dialog.ts (the chrome reused)
70
+ // Copyright (c) 2006-2024 Red Hat, Inc. / Christian Persch / The GTK authors. LGPLv2.1+.
71
+ // Modifications: Implemented as a Web Component for @gjsify/adwaita-web; the page setup is
72
+ // the plain data of packages/web/adwaita-web/src/page-setup.ts.
73
+
74
+ import {
75
+ COMMON_PAPER_SIZES,
76
+ type PageOrientation,
77
+ type PageSetup,
78
+ type PageUnit,
79
+ defaultMargins,
80
+ defaultPageSetup,
81
+ pageSetupEquals,
82
+ paperMarginsTooltip,
83
+ paperSizeLabel,
84
+ paperSizeOf,
85
+ } from '../page-setup.js';
86
+
87
+ import { AdwDialog } from './adw-dialog.js';
88
+
89
+ /** `GTK_RESPONSE_CANCEL` / `GTK_RESPONSE_OK` — what `gtk_dialog_add_buttons` passes. */
90
+ const RESPONSE_CANCEL = -6;
91
+ const RESPONSE_OK = -5;
92
+
93
+ /** The pseudo printer every dialog starts with (gtkpagesetupunixdialog.c:281-297). */
94
+ const ANY_PRINTER = { name: 'Any Printer', location: 'For portable documents' };
95
+
96
+ /** The last row of the paper-size drop down, and the label it carries. */
97
+ const MANAGE_CUSTOM = 'Manage Custom Sizes…';
98
+
99
+ /** The four orientation check buttons, in the `.ui`'s grid order. */
100
+ const ORIENTATIONS: Array<[PageOrientation, string]> = [
101
+ ['portrait', 'Portrait'],
102
+ ['reverse-portrait', 'Reverse portrait'],
103
+ ['landscape', 'Landscape'],
104
+ ['reverse-landscape', 'Reverse landscape'],
105
+ ];
106
+
107
+ /** One row of the "Format for:" drop down. */
108
+ export interface PrinterInfo {
109
+ /** `gtk_printer_get_name` — what `format-for-printer` is compared against. */
110
+ readonly name: string;
111
+ /** `gtk_printer_get_location`, the dimmed second line of the row. */
112
+ readonly location?: string;
113
+ }
114
+
115
+ /** The one `GtkPrintSettings` key this dialog reads or writes. */
116
+ export interface PrintSettingsData {
117
+ /** `format-for-printer` — the printer name the settings belong to. */
118
+ readonly 'format-for-printer'?: string;
119
+ }
120
+
121
+ export class GtkPageSetupUnixDialog extends AdwDialog {
122
+ private _built = false;
123
+
124
+ static get observedAttributes(): string[] {
125
+ // `GtkPageSetupUnixDialog` declares NO GObject properties of its own: `page-setup`
126
+ // and `print-settings` are `GtkPageSetup` / `GtkPrintSettings` objects, which an
127
+ // attribute cannot carry, so they are the plain-data properties below. What is
128
+ // observed is the `<adw-dialog>` chrome this element extends.
129
+ return [...AdwDialog.observedAttributes];
130
+ }
131
+ private _printerEl!: HTMLElement & { selected: number };
132
+ private _paperEl!: HTMLElement & { selected: number };
133
+ private _sizeLabelEl!: HTMLDivElement;
134
+ private _radios = new Map<PageOrientation, HTMLElement & { checked: boolean }>();
135
+ private _printers: PrinterInfo[] = [];
136
+ /** The setups in the drop-down, in the order the C appends them. */
137
+ private _setups: PageSetup[] = [];
138
+ /** `last_setup` — the size the drop down is put back to when a row is not a size. */
139
+ private _lastSetup: PageSetup | null = null;
140
+ private _printSettings: PrintSettingsData | null = null;
141
+ private _unit: PageUnit = 'mm';
142
+
143
+ /** The unit the two labels speak — `_gtk_print_get_default_user_units` is mm here. */
144
+ get unit(): PageUnit {
145
+ return this._unit;
146
+ }
147
+
148
+ set unit(value: PageUnit) {
149
+ this._unit = value;
150
+ if (this._built) this._renderSetup();
151
+ }
152
+
153
+ /**
154
+ * The printer list GTK discovers through a print backend. A browser has no CUPS, so
155
+ * this is an INPUT; the row every dialog starts with is added by the element itself.
156
+ */
157
+ get printers(): PrinterInfo[] {
158
+ return this._printers.map((printer) => ({ ...printer }));
159
+ }
160
+
161
+ set printers(value: readonly PrinterInfo[]) {
162
+ this._printers = value.map((printer) => ({ ...printer }));
163
+ if (this._built) this._renderSetup();
164
+ }
165
+
166
+ /**
167
+ * The current page setup — `gtk_page_setup_unix_dialog_get_page_setup`, which returns
168
+ * the SELECTED setup with the orientation the radios hold.
169
+ */
170
+ get pageSetup(): PageSetup {
171
+ return { ...this._current(), orientation: this._orientation() };
172
+ }
173
+
174
+ /**
175
+ * `gtk_page_setup_unix_dialog_set_page_setup`: select the matching row, appending the
176
+ * setup when no row matches (`set_paper_size` with `add_item` TRUE), then set the
177
+ * orientation radios.
178
+ */
179
+ set pageSetup(value: PageSetup) {
180
+ const index = this._setups.findIndex((setup) => pageSetupEquals(setup, value));
181
+ if (index < 0) {
182
+ this._setups.push(value);
183
+ this._paperEl.selected = this._setups.length - 1;
184
+ } else if (this._paperEl.selected !== index) {
185
+ this._paperEl.selected = index;
186
+ }
187
+ this._setOrientation(value.orientation);
188
+ if (this._built) this._renderSetup();
189
+ }
190
+
191
+ /** `gtk_page_setup_unix_dialog_get_print_settings` — the object, not a copy of it. */
192
+ get printSettings(): PrintSettingsData | null {
193
+ return this._printSettings;
194
+ }
195
+
196
+ /** Selects the printer named by `format-for-printer`, as the setter does. */
197
+ set printSettings(value: PrintSettingsData | null) {
198
+ this._printSettings = value;
199
+ const wanted = value?.['format-for-printer'];
200
+ if (wanted === undefined) return;
201
+ const index = this._printerRows().findIndex((printer) => printer.name === wanted);
202
+ if (index >= 0) this._printerEl.selected = index;
203
+ }
204
+
205
+ connectedCallback(): void {
206
+ if (this._built) {
207
+ super.connectedCallback();
208
+ return;
209
+ }
210
+ super.connectedCallback();
211
+ // `gtk_page_setup_unix_dialog_new`: a NULL title means "Page Setup".
212
+ if (!this.hasAttribute('title')) this.setAttribute('title', 'Page Setup');
213
+
214
+ // The twelve common sizes are what the dialog starts with (`init` fills them
215
+ // from the printer, and with no printer that is the common list) — without
216
+ // them the drop-down holds only the `Manage Custom Sizes…` row.
217
+ this._fillPaperSizes();
218
+ // The base adopts the author's light-DOM children into `contentArea` on
219
+ // connect; rebuilding around them must keep them, AFTER the dialog's own UI —
220
+ // which is also where children appended later land (`slotted-children.spec.ts`
221
+ // pins the equality, path and index).
222
+ const adopted = [...this.contentArea.childNodes];
223
+ this.contentArea.replaceChildren(this._build());
224
+ for (const node of adopted) this.contentArea.appendChild(node);
225
+ this._renderSetup();
226
+ // The dialog opens on the default setup — `gtk_page_setup_new` is A4 — so the
227
+ // drop down selects the row that matches it, not the list's first row. AFTER
228
+ // the render above: setting the model clamps the selection, so selecting first
229
+ // would be clamped away and the label would read the wrong sheet.
230
+ const initial = this._setups.findIndex((setup) => setup.paperSize === defaultPageSetup().paperSize);
231
+ if (initial >= 0 && this._paperEl.selected !== initial) {
232
+ this._paperEl.selected = initial;
233
+ this._renderSetup();
234
+ }
235
+ // `_built` goes last: either `setAttribute` above re-enters through
236
+ // `attributeChangedCallback`, and rendering a half-built dialog throws.
237
+ this._built = true;
238
+ }
239
+
240
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {
241
+ super.attributeChangedCallback(name, oldValue, newValue);
242
+ if (!this._built || oldValue === newValue) return;
243
+ if (name === 'title') return;
244
+ this._renderSetup();
245
+ }
246
+
247
+ // ------------------------------------------------------------- building
248
+
249
+ private _build(): HTMLElement {
250
+ const grid = document.createElement('div');
251
+ grid.className = 'adw-page-setup-grid';
252
+
253
+ this._printerEl = this._dropDown('printer', '_Format for:');
254
+ this._printerEl.addEventListener('notify::selected', () => this._printerChanged());
255
+ grid.append(this._label('_Format for:'), this._printerEl);
256
+
257
+ this._paperEl = this._dropDown('paper', '_Paper size:');
258
+ this._paperEl.addEventListener('notify::selected', () => this._paperChanged());
259
+ grid.append(this._label('_Paper size:'), this._paperEl);
260
+
261
+ this._sizeLabelEl = document.createElement('div');
262
+ this._sizeLabelEl.className = 'adw-page-setup-size-label';
263
+ this._sizeLabelEl.setAttribute('aria-live', 'polite');
264
+ grid.append(this._sizeLabelEl);
265
+
266
+ grid.append(this._label('_Orientation:'));
267
+ for (const [orientation, label] of ORIENTATIONS) {
268
+ const radio = document.createElement('adw-radio') as HTMLElement & { checked: boolean };
269
+ radio.className = 'adw-page-setup-orientation';
270
+ radio.setAttribute('label', label);
271
+ // One group, as `group: portrait_radio` makes them in the `.ui`.
272
+ radio.setAttribute('name', 'adw-page-setup-orientation');
273
+ radio.setAttribute('value', orientation);
274
+ radio.addEventListener('notify::checked', () => this._orientationChanged());
275
+ this._radios.set(orientation, radio);
276
+ grid.appendChild(radio);
277
+ }
278
+
279
+ grid.appendChild(this._actions());
280
+ return grid;
281
+ }
282
+
283
+ /** A `GtkDropDown` with its label as the accessible name, `column-span 3`. */
284
+ private _dropDown(kind: 'printer' | 'paper', label: string): HTMLElement & { selected: number } {
285
+ const dropdown = document.createElement('gtk-drop-down') as HTMLElement & { selected: number };
286
+ dropdown.className = `adw-page-setup-${kind}`;
287
+ dropdown.setAttribute('aria-label', label.replace('_', ''));
288
+ return dropdown;
289
+ }
290
+
291
+ /** A grid label — right-aligned, `use-underline` in the `.ui`, no keyvals here. */
292
+ private _label(text: string): HTMLElement {
293
+ const label = document.createElement('div');
294
+ label.className = 'adw-page-setup-label';
295
+ label.textContent = text.replace('_', '');
296
+ return label;
297
+ }
298
+
299
+ /**
300
+ * The `.dialog-action-area` row: `_Cancel` (GTK_RESPONSE_CANCEL) and `_Apply`
301
+ * (GTK_RESPONSE_OK), which is the label `gtk_dialog_add_buttons` gives the OK response
302
+ * in this dialog. Escape is the close action the base class already binds.
303
+ */
304
+ private _actions(): HTMLElement {
305
+ const actions = document.createElement('div');
306
+ actions.className = 'adw-page-setup-actions';
307
+
308
+ const cancel = document.createElement('button');
309
+ cancel.type = 'button';
310
+ cancel.className = 'adw-page-setup-cancel';
311
+ cancel.textContent = 'Cancel';
312
+ cancel.addEventListener('click', () => this._respond(RESPONSE_CANCEL));
313
+
314
+ const apply = document.createElement('button');
315
+ apply.type = 'button';
316
+ apply.className = 'adw-page-setup-apply suggested-action';
317
+ apply.textContent = 'Apply';
318
+ apply.addEventListener('click', () => this._respond(RESPONSE_OK));
319
+
320
+ actions.append(cancel, apply);
321
+ return actions;
322
+ }
323
+
324
+ private _respond(responseId: number): void {
325
+ this.dispatchEvent(new CustomEvent('response', { bubbles: true, detail: { responseId } }));
326
+ this.close();
327
+ }
328
+
329
+ // ------------------------------------------------------------- rendering
330
+
331
+ /** The drop-down's rows: the pseudo printer first, then the caller's. */
332
+ private _printerRows(): PrinterInfo[] {
333
+ return [ANY_PRINTER, ...this._printers];
334
+ }
335
+
336
+ /**
337
+ * `fill_paper_sizes_from_printer` (:470-491): with no printer — which includes the
338
+ * "Any Printer" row, because `printer_changed_callback` clears it before the call
339
+ * (:576-580) — the list is the twelve common sizes. A REAL printer would bring its
340
+ * own `gtk_printer_list_papers`, which needs the backend this port has not.
341
+ */
342
+ private _fillPaperSizes(): void {
343
+ this._setups = COMMON_PAPER_SIZES.map((size) => ({
344
+ paperSize: size.name,
345
+ orientation: 'portrait' as PageOrientation,
346
+ margins: defaultMargins(size),
347
+ }));
348
+ }
349
+
350
+ /** The selected setup, before the radios' orientation is folded in. */
351
+ private _current(): PageSetup {
352
+ return this._setups[this._paperEl.selected] ?? defaultPageSetup();
353
+ }
354
+
355
+ private _orientation(): PageOrientation {
356
+ for (const [orientation, radio] of this._radios) if (radio.checked) return orientation;
357
+ return 'portrait';
358
+ }
359
+
360
+ private _setOrientation(orientation: PageOrientation): void {
361
+ const radio = this._radios.get(orientation);
362
+ if (radio !== undefined) radio.checked = true;
363
+ }
364
+
365
+ private _renderSetup(): void {
366
+ const printers = this._printerRows();
367
+ this._printerEl.setAttribute('model', JSON.stringify(printers.map((printer) => printer.name)));
368
+ if (this._printerEl.selected >= printers.length) this._printerEl.selected = 0;
369
+
370
+ const labels = [...this._setups.map((setup) => paperSizeOf(setup).displayName), MANAGE_CUSTOM];
371
+ this._paperEl.setAttribute('model', JSON.stringify(labels));
372
+ if (this._paperEl.selected >= labels.length) this._paperEl.selected = 0;
373
+
374
+ const setup = this._current();
375
+ this._sizeLabelEl.textContent = paperSizeLabel(setup, this._unit);
376
+ this._sizeLabelEl.title = paperMarginsTooltip(setup, this._unit);
377
+ }
378
+
379
+ /** `printer_changed_callback` (:557-609): the paper list follows the printer. */
380
+ private _printerChanged(): void {
381
+ const selected = this._printerRows()[this._printerEl.selected];
382
+ // "Any Printer" is not a target: `match_func` (:235) filters virtual printers out
383
+ // of the list, and `printer_changed_callback` clears the row before refilling.
384
+ if (selected === undefined || selected.name === ANY_PRINTER.name) this._fillPaperSizes();
385
+ this._renderSetup();
386
+ // The `format-for-printer` key is written on every printer change, but only if the
387
+ // dialog was GIVEN a print settings object — the C guards it with
388
+ // `if (dialog->print_settings)` (:597), and a dialog that never had one keeps none.
389
+ if (this._printSettings !== null) this._printSettings = { 'format-for-printer': selected?.name };
390
+ }
391
+
392
+ /** `paper_size_changed` (:635-758). */
393
+ private _paperChanged(): void {
394
+ const selected = this._paperEl.selected;
395
+ if (selected >= this._setups.length) {
396
+ // The `Manage Custom Sizes…` row: the C puts the drop down back to the
397
+ // previous setup and THEN presents the custom paper dialog, which needs the
398
+ // print backends this port has not. The put-back is the half that is here.
399
+ const fallback = this._lastSetup ?? defaultPageSetup();
400
+ this._setups.push(fallback);
401
+ this._paperEl.selected = this._setups.length - 1;
402
+ this._renderSetup();
403
+ return;
404
+ }
405
+ this._lastSetup = this._setups[selected] ?? null;
406
+ this._renderSetup();
407
+ }
408
+
409
+ /** The radios' side of `get_orientation` — the label follows them. */
410
+ private _orientationChanged(): void {
411
+ if (!this._built) return;
412
+ this._setups[this._paperEl.selected] = {
413
+ ...this._current(),
414
+ orientation: this._orientation(),
415
+ };
416
+ this._renderSetup();
417
+ }
418
+ }
419
+
420
+ customElements.define('gtk-page-setup-unix-dialog', GtkPageSetupUnixDialog);