@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.
Files changed (440) hide show
  1. package/dist/adwaita-web.css +8070 -3037
  2. package/dist/adwaita-web.css.map +1 -1
  3. package/lib/types/adw-application-window.spec.d.ts +1 -0
  4. package/lib/types/adw-bin.spec.d.ts +1 -0
  5. package/lib/types/adw-breakpoint-bin.spec.d.ts +1 -0
  6. package/lib/types/adw-clamp-scrollable.spec.d.ts +1 -0
  7. package/lib/types/adw-multi-layout-view.spec.d.ts +1 -0
  8. package/lib/types/adw-preferences-row.spec.d.ts +1 -0
  9. package/lib/types/adw-shortcuts.spec.d.ts +1 -0
  10. package/lib/types/adw-tab-bar.spec.d.ts +1 -0
  11. package/lib/types/adw-tab-button.spec.d.ts +1 -0
  12. package/lib/types/adw-tab-overview.spec.d.ts +1 -0
  13. package/lib/types/adw-view-switcher-sidebar.spec.d.ts +1 -0
  14. package/lib/types/adw-window.spec.d.ts +1 -0
  15. package/lib/types/breakpoints.d.ts +14 -3
  16. package/lib/types/construct-vectors.spec.d.ts +1 -0
  17. package/lib/types/elements/adw-application-window.d.ts +27 -0
  18. package/lib/types/elements/adw-bin.d.ts +17 -0
  19. package/lib/types/elements/adw-breakpoint-bin.d.ts +67 -0
  20. package/lib/types/elements/adw-clamp-scrollable.d.ts +38 -0
  21. package/lib/types/elements/adw-dialog.d.ts +10 -0
  22. package/lib/types/elements/adw-layout-slot.d.ts +19 -0
  23. package/lib/types/elements/adw-multi-layout-view.d.ts +101 -0
  24. package/lib/types/elements/adw-preferences-row.d.ts +31 -0
  25. package/lib/types/elements/adw-shortcuts-dialog.d.ts +13 -0
  26. package/lib/types/elements/adw-shortcuts-item.d.ts +36 -0
  27. package/lib/types/elements/adw-shortcuts-section.d.ts +14 -0
  28. package/lib/types/elements/adw-sidebar.d.ts +5 -0
  29. package/lib/types/elements/adw-switch-row.d.ts +3 -0
  30. package/lib/types/elements/adw-tab-bar.d.ts +108 -0
  31. package/lib/types/elements/adw-tab-button.d.ts +32 -0
  32. package/lib/types/elements/adw-tab-overview.d.ts +199 -0
  33. package/lib/types/elements/adw-tab-view.d.ts +19 -23
  34. package/lib/types/elements/adw-view-switcher-sidebar.d.ts +84 -0
  35. package/lib/types/elements/adw-window.d.ts +40 -0
  36. package/lib/types/elements/gtk-about-dialog.d.ts +146 -0
  37. package/lib/types/elements/gtk-application-window.d.ts +34 -0
  38. package/lib/types/elements/gtk-aspect-frame.d.ts +27 -0
  39. package/lib/types/elements/gtk-button.d.ts +9 -0
  40. package/lib/types/elements/gtk-calendar.d.ts +159 -0
  41. package/lib/types/elements/gtk-center-box.d.ts +39 -0
  42. package/lib/types/elements/gtk-color-dialog-button.d.ts +69 -0
  43. package/lib/types/elements/gtk-column-view.d.ts +50 -0
  44. package/lib/types/elements/gtk-drag-icon.d.ts +78 -0
  45. package/lib/types/elements/gtk-drawing-area.d.ts +95 -0
  46. package/lib/types/elements/gtk-editable-label.d.ts +33 -0
  47. package/lib/types/elements/gtk-emoji-chooser.d.ts +84 -0
  48. package/lib/types/elements/gtk-entry.d.ts +20 -1
  49. package/lib/types/elements/gtk-expander.d.ts +49 -0
  50. package/lib/types/elements/gtk-fixed.d.ts +13 -0
  51. package/lib/types/elements/gtk-flow-box-child.d.ts +14 -0
  52. package/lib/types/elements/gtk-flow-box.d.ts +87 -0
  53. package/lib/types/elements/gtk-font-dialog-button.d.ts +83 -0
  54. package/lib/types/elements/gtk-frame.d.ts +24 -0
  55. package/lib/types/elements/gtk-gl-area.d.ts +136 -0
  56. package/lib/types/elements/gtk-graphics-offload.d.ts +24 -0
  57. package/lib/types/elements/gtk-grid-view.d.ts +39 -0
  58. package/lib/types/elements/gtk-grid.d.ts +27 -0
  59. package/lib/types/elements/gtk-header-bar.d.ts +60 -0
  60. package/lib/types/elements/gtk-inscription.d.ts +64 -0
  61. package/lib/types/elements/gtk-label.d.ts +3 -0
  62. package/lib/types/elements/gtk-level-bar.d.ts +59 -0
  63. package/lib/types/elements/gtk-link-button.d.ts +29 -0
  64. package/lib/types/elements/gtk-list-box-row.d.ts +54 -0
  65. package/lib/types/elements/gtk-list-box.d.ts +100 -0
  66. package/lib/types/elements/gtk-list-view.d.ts +73 -0
  67. package/lib/types/elements/gtk-media-controls.d.ts +142 -0
  68. package/lib/types/elements/gtk-notebook.d.ts +148 -0
  69. package/lib/types/elements/gtk-overlay.d.ts +22 -0
  70. package/lib/types/elements/gtk-page-setup-unix-dialog.d.ts +87 -0
  71. package/lib/types/elements/gtk-paned.d.ts +121 -0
  72. package/lib/types/elements/gtk-password-entry.d.ts +27 -0
  73. package/lib/types/elements/gtk-picture.d.ts +66 -0
  74. package/lib/types/elements/gtk-popover-bin.d.ts +82 -0
  75. package/lib/types/elements/gtk-popover-menu-bar.d.ts +66 -0
  76. package/lib/types/elements/gtk-popover-menu.d.ts +83 -0
  77. package/lib/types/elements/gtk-popover.d.ts +28 -3
  78. package/lib/types/elements/gtk-print-unix-dialog.d.ts +167 -0
  79. package/lib/types/elements/gtk-revealer.d.ts +55 -0
  80. package/lib/types/elements/gtk-scale-button.d.ts +59 -0
  81. package/lib/types/elements/gtk-scale.d.ts +98 -0
  82. package/lib/types/elements/gtk-scrollbar.d.ts +124 -0
  83. package/lib/types/elements/gtk-scrolled-window.d.ts +121 -0
  84. package/lib/types/elements/gtk-search-bar.d.ts +39 -0
  85. package/lib/types/elements/gtk-search-entry.d.ts +27 -0
  86. package/lib/types/elements/gtk-separator.d.ts +10 -0
  87. package/lib/types/elements/gtk-spin-button.d.ts +94 -0
  88. package/lib/types/elements/gtk-spinner.d.ts +14 -0
  89. package/lib/types/elements/gtk-stack-sidebar.d.ts +43 -0
  90. package/lib/types/elements/gtk-stack-switcher.d.ts +58 -0
  91. package/lib/types/elements/gtk-stack.d.ts +154 -0
  92. package/lib/types/elements/gtk-switch.d.ts +4 -1
  93. package/lib/types/elements/gtk-text-view.d.ts +62 -0
  94. package/lib/types/elements/gtk-text.d.ts +45 -0
  95. package/lib/types/elements/gtk-toggle-button.d.ts +45 -0
  96. package/lib/types/elements/gtk-tree-expander.d.ts +38 -0
  97. package/lib/types/elements/gtk-video.d.ts +97 -0
  98. package/lib/types/elements/gtk-viewport.d.ts +84 -0
  99. package/lib/types/elements/gtk-window-controls.d.ts +80 -0
  100. package/lib/types/elements/gtk-window-handle.d.ts +39 -0
  101. package/lib/types/elements/gtk-window.d.ts +97 -0
  102. package/lib/types/elements/justification.d.ts +2 -0
  103. package/lib/types/elements/popover-menu.d.ts +18 -0
  104. package/lib/types/elements/roving-focus.d.ts +29 -1
  105. package/lib/types/emoji-data.d.ts +38 -0
  106. package/lib/types/font-description.d.ts +96 -0
  107. package/lib/types/gtk-about-dialog.spec.d.ts +1 -0
  108. package/lib/types/gtk-action-bar.spec.d.ts +1 -0
  109. package/lib/types/gtk-application-window.spec.d.ts +1 -0
  110. package/lib/types/gtk-aspect-frame.spec.d.ts +1 -0
  111. package/lib/types/gtk-calendar.spec.d.ts +1 -0
  112. package/lib/types/gtk-center-box.spec.d.ts +1 -0
  113. package/lib/types/gtk-color-dialog-button.spec.d.ts +1 -0
  114. package/lib/types/gtk-column-view.spec.d.ts +1 -0
  115. package/lib/types/gtk-drag-icon.spec.d.ts +1 -0
  116. package/lib/types/gtk-drawing-area.spec.d.ts +1 -0
  117. package/lib/types/gtk-editable-label.spec.d.ts +1 -0
  118. package/lib/types/gtk-emoji-chooser.spec.d.ts +1 -0
  119. package/lib/types/gtk-expander.spec.d.ts +1 -0
  120. package/lib/types/gtk-fixed.spec.d.ts +1 -0
  121. package/lib/types/gtk-flow-box.spec.d.ts +1 -0
  122. package/lib/types/gtk-font-dialog-button.spec.d.ts +1 -0
  123. package/lib/types/gtk-frame.spec.d.ts +1 -0
  124. package/lib/types/gtk-gl-area.spec.d.ts +1 -0
  125. package/lib/types/gtk-graphics-offload.spec.d.ts +1 -0
  126. package/lib/types/gtk-grid-view.spec.d.ts +1 -0
  127. package/lib/types/gtk-grid.spec.d.ts +1 -0
  128. package/lib/types/gtk-header-bar.spec.d.ts +1 -0
  129. package/lib/types/gtk-inscription.spec.d.ts +1 -0
  130. package/lib/types/gtk-level-bar.spec.d.ts +1 -0
  131. package/lib/types/gtk-link-button.spec.d.ts +1 -0
  132. package/lib/types/gtk-list-box.spec.d.ts +1 -0
  133. package/lib/types/gtk-list-view.spec.d.ts +1 -0
  134. package/lib/types/gtk-media-controls.spec.d.ts +1 -0
  135. package/lib/types/gtk-notebook.spec.d.ts +1 -0
  136. package/lib/types/gtk-overlay.spec.d.ts +1 -0
  137. package/lib/types/gtk-paned.spec.d.ts +1 -0
  138. package/lib/types/gtk-password-entry.spec.d.ts +1 -0
  139. package/lib/types/gtk-picture.spec.d.ts +1 -0
  140. package/lib/types/gtk-popover-bin.spec.d.ts +1 -0
  141. package/lib/types/gtk-popover-menu-bar.spec.d.ts +1 -0
  142. package/lib/types/gtk-popover-menu.spec.d.ts +1 -0
  143. package/lib/types/gtk-popover-role.spec.d.ts +1 -0
  144. package/lib/types/gtk-popover.spec.d.ts +1 -0
  145. package/lib/types/gtk-print-dialogs.spec.d.ts +1 -0
  146. package/lib/types/gtk-revealer.spec.d.ts +1 -0
  147. package/lib/types/gtk-scale-button.spec.d.ts +1 -0
  148. package/lib/types/gtk-scale.spec.d.ts +1 -0
  149. package/lib/types/gtk-scrollbar.spec.d.ts +1 -0
  150. package/lib/types/gtk-scrolled-window.spec.d.ts +1 -0
  151. package/lib/types/gtk-search-bar.spec.d.ts +1 -0
  152. package/lib/types/gtk-search-entry.spec.d.ts +1 -0
  153. package/lib/types/gtk-separator.spec.d.ts +1 -0
  154. package/lib/types/gtk-spin-button.spec.d.ts +1 -0
  155. package/lib/types/gtk-spinner.spec.d.ts +1 -0
  156. package/lib/types/gtk-stack-sidebar.spec.d.ts +1 -0
  157. package/lib/types/gtk-stack-switcher.spec.d.ts +1 -0
  158. package/lib/types/gtk-stack.spec.d.ts +1 -0
  159. package/lib/types/gtk-text-view.spec.d.ts +1 -0
  160. package/lib/types/gtk-text.spec.d.ts +1 -0
  161. package/lib/types/gtk-toggle-button.spec.d.ts +1 -0
  162. package/lib/types/gtk-tree-expander.spec.d.ts +1 -0
  163. package/lib/types/gtk-video.spec.d.ts +1 -0
  164. package/lib/types/gtk-viewport.spec.d.ts +1 -0
  165. package/lib/types/gtk-window-controls.spec.d.ts +1 -0
  166. package/lib/types/gtk-window-handle.spec.d.ts +1 -0
  167. package/lib/types/gtk-window.spec.d.ts +1 -0
  168. package/lib/types/index.d.ts +4 -1
  169. package/lib/types/list-view-dom.d.ts +44 -0
  170. package/lib/types/namespace/adw.d.ts +12 -0
  171. package/lib/types/namespace/gtk.d.ts +61 -0
  172. package/lib/types/page-setup.d.ts +100 -0
  173. package/lib/types/scroll-shading.d.ts +15 -1
  174. package/lib/types/shared-tree-builder.d.ts +30 -2
  175. package/lib/types/signals.d.ts +4 -0
  176. package/lib/types/styles.generated.d.ts +1 -1
  177. package/lib/types/tab-chip.d.ts +73 -0
  178. package/lib/types/template-classes.d.ts +11 -0
  179. package/package.json +12 -8
  180. package/scss/_action_row.scss +2 -2
  181. package/scss/_application_window.scss +26 -0
  182. package/scss/_aspect_frame.scss +25 -0
  183. package/scss/_bin.scss +26 -0
  184. package/scss/_button.scss +45 -0
  185. package/scss/_calendar.scss +176 -0
  186. package/scss/_center_box.scss +25 -0
  187. package/scss/_checks.scss +6 -1
  188. package/scss/_clamp_scrollable.scss +28 -0
  189. package/scss/_color_button.scss +67 -0
  190. package/scss/_column_view.scss +126 -0
  191. package/scss/_drag_icon.scss +55 -0
  192. package/scss/_drawing.scss +85 -0
  193. package/scss/_emoji_chooser.scss +213 -0
  194. package/scss/_entry.scss +13 -5
  195. package/scss/_entry_row.scss +1 -1
  196. package/scss/_expander.scss +113 -0
  197. package/scss/_fixed.scss +29 -0
  198. package/scss/_flow_box.scss +94 -0
  199. package/scss/_font_button.scss +63 -0
  200. package/scss/_frame.scss +41 -0
  201. package/scss/_grid.scss +19 -0
  202. package/scss/_grid_view.scss +46 -0
  203. package/scss/_gtk_about_dialog.scss +186 -0
  204. package/scss/_headerbar.scss +132 -0
  205. package/scss/_icons.generated.scss +186 -0
  206. package/scss/_inscription.scss +125 -0
  207. package/scss/_level_bar.scss +190 -0
  208. package/scss/_link.scss +82 -0
  209. package/scss/_list_box.scss +88 -0
  210. package/scss/_list_view.scss +96 -0
  211. package/scss/_media_controls.scss +139 -0
  212. package/scss/_overlay.scss +68 -0
  213. package/scss/_paned.scss +130 -0
  214. package/scss/_password_entry.scss +83 -0
  215. package/scss/_picture.scss +80 -0
  216. package/scss/_popover_bin.scss +53 -0
  217. package/scss/_popover_menu_bar.scss +104 -0
  218. package/scss/_preferences_row.scss +51 -0
  219. package/scss/_print_dialogs.scss +328 -0
  220. package/scss/_reset.scss +21 -19
  221. package/scss/_revealer.scss +37 -0
  222. package/scss/_row.scss +20 -5
  223. package/scss/_scale.scss +298 -0
  224. package/scss/_scale_button.scss +167 -0
  225. package/scss/_scrollbar.scss +230 -0
  226. package/scss/_scrolled_window.scss +131 -0
  227. package/scss/_search_bar.scss +118 -0
  228. package/scss/_search_entry.scss +86 -0
  229. package/scss/_separator.scss +44 -0
  230. package/scss/_shortcuts_dialog.scss +100 -0
  231. package/scss/_spin_button.scss +172 -0
  232. package/scss/_spin_row.scss +56 -8
  233. package/scss/_spinner.scss +85 -4
  234. package/scss/_stack.scss +729 -0
  235. package/scss/_switch.scss +13 -5
  236. package/scss/_switch_row.scss +10 -0
  237. package/scss/_tab_bar.scss +317 -0
  238. package/scss/_tab_button.scss +98 -0
  239. package/scss/_tab_overview.scss +483 -0
  240. package/scss/_text.scss +182 -0
  241. package/scss/_theme.scss +1 -1
  242. package/scss/_tree_expander.scss +62 -0
  243. package/scss/_variables.scss +43 -21
  244. package/scss/_video.scss +146 -0
  245. package/scss/_view_switcher_sidebar.scss +112 -0
  246. package/scss/_viewport.scss +50 -0
  247. package/scss/_window.scss +118 -1
  248. package/scss/_window_handle.scss +20 -0
  249. package/scss/adwaita-skin.scss +109 -0
  250. package/src/adw-action-rows.spec.ts +76 -0
  251. package/src/adw-application-window.spec.ts +118 -0
  252. package/src/adw-bin.spec.ts +75 -0
  253. package/src/adw-breakpoint-bin.spec.ts +324 -0
  254. package/src/adw-clamp-scrollable.spec.ts +189 -0
  255. package/src/adw-multi-layout-view.spec.ts +243 -0
  256. package/src/adw-preferences-row.spec.ts +164 -0
  257. package/src/adw-row-state.spec.ts +142 -0
  258. package/src/adw-shortcuts.spec.ts +155 -0
  259. package/src/adw-tab-bar.spec.ts +287 -0
  260. package/src/adw-tab-button.spec.ts +101 -0
  261. package/src/adw-tab-overview.spec.ts +443 -0
  262. package/src/adw-view-switcher-sidebar.spec.ts +281 -0
  263. package/src/adw-window.spec.ts +129 -0
  264. package/src/breakpoints.ts +25 -8
  265. package/src/capabilities.d.mts +3 -0
  266. package/src/capabilities.mjs +18 -0
  267. package/src/connect-lifecycle.spec.ts +12 -0
  268. package/src/construct-vectors.spec.ts +175 -0
  269. package/src/elements/adw-application-window.ts +154 -0
  270. package/src/elements/adw-bin.ts +101 -0
  271. package/src/elements/adw-breakpoint-bin.ts +287 -0
  272. package/src/elements/adw-clamp-scrollable.ts +207 -0
  273. package/src/elements/adw-dialog.ts +19 -0
  274. package/src/elements/adw-layout-slot.ts +95 -0
  275. package/src/elements/adw-multi-layout-view.ts +326 -0
  276. package/src/elements/adw-preferences-row.ts +150 -0
  277. package/src/elements/adw-shortcuts-dialog.ts +52 -0
  278. package/src/elements/adw-shortcuts-item.ts +171 -0
  279. package/src/elements/adw-shortcuts-section.ts +86 -0
  280. package/src/elements/adw-sidebar.ts +42 -3
  281. package/src/elements/adw-switch-row.ts +28 -1
  282. package/src/elements/adw-tab-bar.ts +529 -0
  283. package/src/elements/adw-tab-button.ts +194 -0
  284. package/src/elements/adw-tab-overview.ts +1011 -0
  285. package/src/elements/adw-tab-view.ts +66 -145
  286. package/src/elements/adw-toggle-group.ts +20 -5
  287. package/src/elements/adw-view-stack.ts +18 -0
  288. package/src/elements/adw-view-switcher-sidebar.ts +332 -0
  289. package/src/elements/adw-window.ts +185 -11
  290. package/src/elements/checks.ts +35 -8
  291. package/src/elements/gtk-about-dialog.ts +811 -0
  292. package/src/elements/gtk-application-window.ts +108 -0
  293. package/src/elements/gtk-aspect-frame.ts +160 -0
  294. package/src/elements/gtk-button.ts +12 -0
  295. package/src/elements/gtk-calendar.ts +757 -0
  296. package/src/elements/gtk-center-box.ts +184 -0
  297. package/src/elements/gtk-color-dialog-button.ts +278 -0
  298. package/src/elements/gtk-column-view.ts +320 -0
  299. package/src/elements/gtk-drag-icon.ts +257 -0
  300. package/src/elements/gtk-drawing-area.ts +303 -0
  301. package/src/elements/gtk-editable-label.ts +204 -0
  302. package/src/elements/gtk-emoji-chooser.ts +542 -0
  303. package/src/elements/gtk-entry.ts +39 -5
  304. package/src/elements/gtk-expander.ts +301 -0
  305. package/src/elements/gtk-fixed.ts +99 -0
  306. package/src/elements/gtk-flow-box-child.ts +68 -0
  307. package/src/elements/gtk-flow-box.ts +480 -0
  308. package/src/elements/gtk-font-dialog-button.ts +432 -0
  309. package/src/elements/gtk-frame.ts +174 -0
  310. package/src/elements/gtk-gl-area.ts +476 -0
  311. package/src/elements/gtk-graphics-offload.ts +130 -0
  312. package/src/elements/gtk-grid-view.ts +168 -0
  313. package/src/elements/gtk-grid.ts +127 -0
  314. package/src/elements/gtk-header-bar.ts +273 -0
  315. package/src/elements/gtk-inscription.ts +387 -0
  316. package/src/elements/gtk-label.ts +19 -11
  317. package/src/elements/gtk-level-bar.ts +323 -0
  318. package/src/elements/gtk-link-button.ts +138 -0
  319. package/src/elements/gtk-list-box-row.ts +195 -0
  320. package/src/elements/gtk-list-box.ts +413 -0
  321. package/src/elements/gtk-list-view.ts +370 -0
  322. package/src/elements/gtk-media-controls.ts +509 -0
  323. package/src/elements/gtk-notebook.ts +664 -0
  324. package/src/elements/gtk-overlay.ts +149 -0
  325. package/src/elements/gtk-page-setup-unix-dialog.ts +420 -0
  326. package/src/elements/gtk-paned.ts +597 -0
  327. package/src/elements/gtk-password-entry.ts +170 -0
  328. package/src/elements/gtk-picture.ts +254 -0
  329. package/src/elements/gtk-popover-bin.ts +332 -0
  330. package/src/elements/gtk-popover-menu-bar.ts +355 -0
  331. package/src/elements/gtk-popover-menu.ts +339 -0
  332. package/src/elements/gtk-popover.ts +92 -10
  333. package/src/elements/gtk-print-unix-dialog.ts +989 -0
  334. package/src/elements/gtk-progress-bar.ts +24 -11
  335. package/src/elements/gtk-revealer.ts +406 -0
  336. package/src/elements/gtk-scale-button.ts +358 -0
  337. package/src/elements/gtk-scale.ts +492 -0
  338. package/src/elements/gtk-scrollbar.ts +528 -0
  339. package/src/elements/gtk-scrolled-window.ts +642 -0
  340. package/src/elements/gtk-search-bar.ts +200 -0
  341. package/src/elements/gtk-search-entry.ts +172 -0
  342. package/src/elements/gtk-separator.ts +52 -0
  343. package/src/elements/gtk-spin-button.ts +475 -0
  344. package/src/elements/gtk-spinner.ts +126 -0
  345. package/src/elements/gtk-stack-sidebar.ts +212 -0
  346. package/src/elements/gtk-stack-switcher.ts +279 -0
  347. package/src/elements/gtk-stack.ts +748 -0
  348. package/src/elements/gtk-switch.ts +52 -19
  349. package/src/elements/gtk-text-view.ts +290 -0
  350. package/src/elements/gtk-text.ts +219 -0
  351. package/src/elements/gtk-toggle-button.ts +239 -0
  352. package/src/elements/gtk-tree-expander.ts +243 -0
  353. package/src/elements/gtk-video.ts +423 -0
  354. package/src/elements/gtk-viewport.ts +277 -0
  355. package/src/elements/gtk-window-controls.ts +341 -0
  356. package/src/elements/gtk-window-handle.ts +221 -0
  357. package/src/elements/gtk-window.ts +366 -0
  358. package/src/elements/justification.ts +24 -0
  359. package/src/elements/popover-menu.ts +24 -0
  360. package/src/elements/roving-focus.ts +53 -21
  361. package/src/emoji-data.ts +577 -0
  362. package/src/entry-rows.spec.ts +31 -0
  363. package/src/font-description.ts +238 -0
  364. package/src/gtk-about-dialog.spec.ts +250 -0
  365. package/src/gtk-action-bar.spec.ts +89 -0
  366. package/src/gtk-application-window.spec.ts +107 -0
  367. package/src/gtk-aspect-frame.spec.ts +114 -0
  368. package/src/gtk-calendar.spec.ts +589 -0
  369. package/src/gtk-center-box.spec.ts +125 -0
  370. package/src/gtk-color-dialog-button.spec.ts +141 -0
  371. package/src/gtk-column-view.spec.ts +154 -0
  372. package/src/gtk-drag-icon.spec.ts +190 -0
  373. package/src/gtk-drawing-area.spec.ts +211 -0
  374. package/src/gtk-editable-label.spec.ts +190 -0
  375. package/src/gtk-emoji-chooser.spec.ts +173 -0
  376. package/src/gtk-entry.spec.ts +23 -0
  377. package/src/gtk-expander.spec.ts +170 -0
  378. package/src/gtk-fixed.spec.ts +97 -0
  379. package/src/gtk-flow-box.spec.ts +289 -0
  380. package/src/gtk-font-dialog-button.spec.ts +166 -0
  381. package/src/gtk-frame.spec.ts +119 -0
  382. package/src/gtk-gl-area.spec.ts +361 -0
  383. package/src/gtk-graphics-offload.spec.ts +119 -0
  384. package/src/gtk-grid-view.spec.ts +106 -0
  385. package/src/gtk-grid.spec.ts +122 -0
  386. package/src/gtk-header-bar.spec.ts +202 -0
  387. package/src/gtk-inscription.spec.ts +235 -0
  388. package/src/gtk-level-bar.spec.ts +199 -0
  389. package/src/gtk-link-button.spec.ts +117 -0
  390. package/src/gtk-list-box.spec.ts +422 -0
  391. package/src/gtk-list-view.spec.ts +203 -0
  392. package/src/gtk-media-controls.spec.ts +295 -0
  393. package/src/gtk-notebook.spec.ts +546 -0
  394. package/src/gtk-overlay.spec.ts +141 -0
  395. package/src/gtk-paned.spec.ts +267 -0
  396. package/src/gtk-password-entry.spec.ts +150 -0
  397. package/src/gtk-picture.spec.ts +172 -0
  398. package/src/gtk-popover-bin.spec.ts +229 -0
  399. package/src/gtk-popover-menu-bar.spec.ts +296 -0
  400. package/src/gtk-popover-menu.spec.ts +261 -0
  401. package/src/gtk-popover-role.spec.ts +138 -0
  402. package/src/gtk-popover.spec.ts +264 -0
  403. package/src/gtk-print-dialogs.spec.ts +251 -0
  404. package/src/gtk-revealer.spec.ts +164 -0
  405. package/src/gtk-scale-button.spec.ts +218 -0
  406. package/src/gtk-scale.spec.ts +213 -0
  407. package/src/gtk-scrollbar.spec.ts +244 -0
  408. package/src/gtk-scrolled-window.spec.ts +262 -0
  409. package/src/gtk-search-bar.spec.ts +179 -0
  410. package/src/gtk-search-entry.spec.ts +142 -0
  411. package/src/gtk-separator.spec.ts +74 -0
  412. package/src/gtk-spin-button.spec.ts +186 -0
  413. package/src/gtk-spinner.spec.ts +130 -0
  414. package/src/gtk-stack-sidebar.spec.ts +217 -0
  415. package/src/gtk-stack-switcher.spec.ts +249 -0
  416. package/src/gtk-stack.spec.ts +432 -0
  417. package/src/gtk-text-view.spec.ts +189 -0
  418. package/src/gtk-text.spec.ts +163 -0
  419. package/src/gtk-toggle-button.spec.ts +186 -0
  420. package/src/gtk-tree-expander.spec.ts +201 -0
  421. package/src/gtk-video.spec.ts +240 -0
  422. package/src/gtk-viewport.spec.ts +140 -0
  423. package/src/gtk-window-controls.spec.ts +232 -0
  424. package/src/gtk-window-handle.spec.ts +158 -0
  425. package/src/gtk-window.spec.ts +190 -0
  426. package/src/index.ts +9 -1
  427. package/src/keyboard-operable.spec.ts +33 -1
  428. package/src/list-view-dom.ts +121 -0
  429. package/src/namespace/adw.ts +12 -0
  430. package/src/namespace/gtk.ts +61 -0
  431. package/src/page-setup.ts +222 -0
  432. package/src/scroll-shading.ts +18 -1
  433. package/src/shared-tree-builder.ts +263 -21
  434. package/src/signals.ts +15 -0
  435. package/src/source-view/theme.ts +11 -5
  436. package/src/style-classes.spec.ts +9 -8
  437. package/src/styles.generated.ts +1 -1
  438. package/src/tab-chip.ts +200 -0
  439. package/src/template-classes.ts +45 -0
  440. package/src/test.browser.mts +152 -0
@@ -0,0 +1,287 @@
1
+ // <adw-breakpoint-bin> — a bin whose one child rearranges itself at size thresholds.
2
+ // `Adw.BreakpointBin` gives breakpoints a home without a window: it holds a list of
3
+ // `Adw.Breakpoint`s, and on every allocation the LAST one whose condition holds is
4
+ // picked and its setters written. If none holds, the child's original values stand.
5
+ //
6
+ // The picking, the restore order and what a restore restores to are all
7
+ // `@gjsify/adwaita-core`'s `BreakpointBinState` (ADR 0004), driven from real
8
+ // `ResizeObserver` deliveries — the four rules it encodes are quoted at the top of
9
+ // `packages/web/adwaita-core/src/breakpoint-bin.ts`, each with its `file:lines`.
10
+ //
11
+ // WHAT THE ATTRIBUTE CARRIES. `Adw.Breakpoint` is a GObject, not a widget, and
12
+ // `adw_breakpoint_bin_add_breakpoint()` is the whole API — so a browser port needs a
13
+ // MARKUP form and there is no GIR property for one. `breakpoints` is a JSON array of
14
+ // `{ condition, setters: [{ target, property, value }] }`:
15
+ //
16
+ // * `condition` is an Adwaita condition string, parsed by the same grammar as every
17
+ // other breakpoint in this package (`max-width: 720px`).
18
+ // * `target` is a CSS selector for a DESCENDANT. The C says it in the docs —
19
+ // "Breakpoints are only allowed to modify widgets inside the AdwBreakpointBin, but
20
+ // not on the AdwBreakpointBin itself" — and the selector cannot escape the subtree
21
+ // because it is resolved with `querySelector` on this element.
22
+ // * `property` is an ATTRIBUTE name and `value` its value. An attribute is the only
23
+ // thing a browser can write on another custom element portably, and this package's
24
+ // own properties ARE attributes (`<adw-label label>` above).
25
+ // * `originalValue` is read ONCE, when the setter is registered, exactly as
26
+ // `g_object_get_property` is at `adw_breakpoint_add_setter` (adw-breakpoint.c:1627).
27
+ // An attribute the element did not have is restored by REMOVING it.
28
+ //
29
+ // `Adw.BreakpointBin` also measures itself differently once it holds a breakpoint:
30
+ // `adw_breakpoint_bin_measure` forces its MINIMUM to 0 (:388) and
31
+ // `adw_breakpoint_bin_get_request_mode` answers CONSTANT_SIZE (:362). That is the
32
+ // documented rule — "Adding a breakpoint to AdwBreakpointBin will result in it having
33
+ // no minimum size" — and it is why the element sets `min-width`/`min-height` to 0 and
34
+ // `overflow: hidden` (the C's own `gtk_widget_set_overflow(…, GTK_OVERFLOW_HIDDEN)`,
35
+ // :669) while a `breakpoints` attribute is present.
36
+ //
37
+ // Attributes:
38
+ // breakpoints (JSON — the breakpoints to add, in ORDER: a later one beats an earlier
39
+ // one when both match. `current-breakpoint` is reported as the index.)
40
+ //
41
+ // Events:
42
+ // `notify::current-breakpoint` (CustomEvent, bubbles, `detail = { currentBreakpoint }`)
43
+ // when the picked breakpoint changes — mirrors the GObject property of that name,
44
+ // which is read-only and notified on every change (adw-breakpoint-bin.c:477).
45
+ // `breakpoint-unapply` (CustomEvent, bubbles, `detail = { index }`) BEFORE the writes,
46
+ // `breakpoint-apply` (CustomEvent, bubbles, `detail = { index }`) AFTER them — the
47
+ // order of `adw_breakpoint_transition` (adw-breakpoint.c:1793, :1819). A listener on
48
+ // the apply end therefore sees the INCOMING values and one on the unapply end the
49
+ // OUTGOING ones; neither ever sees the restore in between.
50
+ //
51
+ // A11Y: `role="group"`. There is no box of its own: GTK clips overflow and gives the
52
+ // child the allocation, which a light-DOM passthrough already is.
53
+ //
54
+ // NOT PORTED: `adw_breakpoint_bin_set_pass_through()` (:893). It makes `contains()`
55
+ // return FALSE so the bin claims no event of its own (adw-breakpoint-bin.c:327); a
56
+ // browser has no `contains` override for that, and the property is private API besides.
57
+ // `adw_breakpoint_bin_set_natural_size()` (:906) and
58
+ // `adw_breakpoint_bin_set_warnings()` (:853) are the same shape — private helpers with
59
+ // no GIR property, no attribute, and nothing for a page to set.
60
+ //
61
+ // Reference: refs/libadwaita/src/adw-breakpoint-bin.c
62
+ // Reference: refs/libadwaita/src/adw-breakpoint.c (adw_breakpoint_transition)
63
+ // Copyright (c) 2023 Purism SPC (libadwaita). LGPLv2.1+.
64
+ // Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
65
+
66
+ import { BreakpointBinState } from '@gjsify/adwaita-core';
67
+ import type { BreakpointSetter } from '@gjsify/adwaita-core';
68
+
69
+ import { observeAdaptiveSize } from '../breakpoints.js';
70
+
71
+ /** One authored setter, as it reads in the `breakpoints` attribute. */
72
+ interface AuthoredSetter {
73
+ readonly target: string;
74
+ readonly property: string;
75
+ readonly value: string;
76
+ }
77
+
78
+ /** One authored breakpoint, as it reads in the `breakpoints` attribute. */
79
+ interface AuthoredBreakpoint {
80
+ readonly condition: string;
81
+ readonly setters: readonly AuthoredSetter[];
82
+ }
83
+
84
+ /** `breaks` parsed, or `[]` for anything that is not an array of breakpoints. */
85
+ function parseBreakpoints(raw: string | null): AuthoredBreakpoint[] {
86
+ if (!raw) return [];
87
+ let parsed: unknown;
88
+ try {
89
+ parsed = JSON.parse(raw);
90
+ } catch {
91
+ // A typo in a condition must not empty the bin: `adw_breakpoint_check_condition`
92
+ // returns FALSE for an unparseable condition (adw-breakpoint.c:1831), so C drops
93
+ // that ONE breakpoint. Silently losing all of them would be a different widget.
94
+ console.error('<adw-breakpoint-bin>: `breakpoints` is not JSON; no breakpoint is applied.');
95
+ return [];
96
+ }
97
+ if (!Array.isArray(parsed)) return [];
98
+ return parsed.flatMap((entry) => {
99
+ if (typeof entry !== 'object' || entry === null) return [];
100
+ const { condition, setters } = entry as Partial<AuthoredBreakpoint>;
101
+ if (typeof condition !== 'string') return [];
102
+ return [{ condition, setters: Array.isArray(setters) ? setters : [] }];
103
+ });
104
+ }
105
+
106
+ export class AdwBreakpointBin extends HTMLElement {
107
+ /** The C's own structure: a list of breakpoints, and at most one picked. */
108
+ private _state = new BreakpointBinState<Element>();
109
+ private _dispose: (() => void) | undefined;
110
+ /**
111
+ * What the last binding applied, carried across every rebind.
112
+ *
113
+ * `BreakpointBinState.inherit` exists for exactly this and its docblock records the
114
+ * measurement: a browser element rebinds on every `connectedCallback`, and a bin that
115
+ * restarts at "none applied" reads the size that LEFT the old breakpoint's range as
116
+ * no change at all and leaves the child holding what the old bin wrote.
117
+ */
118
+ private _applied: number | null = null;
119
+ /** Registration is deferred to the first allocation; see `_observe`. */
120
+ private _pendingSync = false;
121
+ /**
122
+ * What each setter's target held when the setter was FIRST registered, keyed by
123
+ * target + property + value.
124
+ *
125
+ * Carried across a REBIND because a rebind is not a re-registration. Upstream
126
+ * `adw_breakpoint_add_setter` captures the original once, at the call
127
+ * (`g_object_get_property`, adw-breakpoint.c:1627), and the widget outlives every
128
+ * resize; a browser element rebinds on every connect, and re-reading the original
129
+ * then would capture the value the OUTGOING breakpoint had already written — so the
130
+ * restore would write back the applied value and the widget would never recover.
131
+ * Measured: a bin applied at 400px, moved to a 500px parent and widened to 900px
132
+ * kept its narrow label for good.
133
+ *
134
+ * Cleared when the AUTHOR rewrites `breakpoints`, which is a new
135
+ * `add_breakpoint`/`add_setters` sequence and captures new originals.
136
+ */
137
+ private _originals = new Map<string, string | null>();
138
+
139
+ static get observedAttributes() {
140
+ return ['breakpoints'];
141
+ }
142
+
143
+ /** `Adw.BreakpointBin:current-breakpoint` — the picked index, or null. Read-only. */
144
+ get currentBreakpoint(): number | null {
145
+ return this._state.current;
146
+ }
147
+
148
+ /** `adw_breakpoint_bin_get_current_breakpoint()` (:841), under its property name. */
149
+ get currentBreakpointAttribute(): string | null {
150
+ const current = this._state.current;
151
+ return current === null ? null : String(current);
152
+ }
153
+
154
+ /** `Adw.BreakpointBin:child` — the bin has one child, the one every breakpoint writes. */
155
+ get child(): Element | null {
156
+ return this.firstElementChild;
157
+ }
158
+
159
+ connectedCallback() {
160
+ this.setAttribute('role', 'group');
161
+ // A GTK widget is a box and an unknown custom element is `inline`, which measures
162
+ // zero — and a bin measuring zero matches every condition forever. libadwaita
163
+ // ships no rule for this widget, so the box model is set here rather than
164
+ // invented in a partial.
165
+ this.style.display = 'block';
166
+ this._syncSizing();
167
+ // Registration waits for the first allocation: `connectedCallback` of a bin fires
168
+ // while its OWN markup is still being parsed, so `#caption` below it does not
169
+ // exist yet and a setter resolved here would be dropped rather than restored.
170
+ // `ResizeObserver` delivers its first observation after layout, by which time the
171
+ // tree is whole and nothing has been written yet — so the originals are still the
172
+ // ones `adw_breakpoint_add_setter` would have captured.
173
+ this._pendingSync = true;
174
+ this._observe();
175
+ }
176
+
177
+ disconnectedCallback() {
178
+ this._dispose?.();
179
+ this._dispose = undefined;
180
+ }
181
+
182
+ attributeChangedCallback(name?: string) {
183
+ if (name !== 'breakpoints' || !this.isConnected) return;
184
+ // The tree IS whole by the time anything rewrites the attribute, so a change
185
+ // registers immediately rather than one allocation later — and it is a NEW
186
+ // sequence of `add_breakpoint` calls, so the originals are captured afresh.
187
+ this._originals.clear();
188
+ this._syncBreakpoints();
189
+ }
190
+
191
+ /**
192
+ * Rebuild the state from the attribute, keeping the applied breakpoint.
193
+ *
194
+ * The originals are read on the way, because `inherit` restores what the NEW
195
+ * definitions captured: a restore read off a child the outgoing breakpoint already
196
+ * changed would restore it to the applied value, which is no restore at all.
197
+ */
198
+ private _syncBreakpoints(): void {
199
+ this._pendingSync = false;
200
+ const authored = parseBreakpoints(this.getAttribute('breakpoints'));
201
+ this._state = new BreakpointBinState<Element>();
202
+ for (const breakpoint of authored) {
203
+ const setters: BreakpointSetter<Element>[] = [];
204
+ for (const setter of breakpoint.setters) {
205
+ if (typeof setter?.target !== 'string' || typeof setter.property !== 'string') continue;
206
+ const target = this.querySelector(setter.target);
207
+ // An unmatched selector is a setter that would write to nothing; C's
208
+ // `add_setters` needs a live object and refuses one that is not.
209
+ if (target === null) continue;
210
+ const key = `${setter.target}\u0000${setter.property}\u0000${setter.value}`;
211
+ if (!this._originals.has(key)) this._originals.set(key, target.getAttribute(setter.property));
212
+ setters.push({
213
+ object: target,
214
+ property: setter.property,
215
+ value: setter.value,
216
+ originalValue: this._originals.get(key) ?? null,
217
+ });
218
+ }
219
+ this._state.add({ condition: breakpoint.condition, setters });
220
+ }
221
+ this._state.inherit(this._applied);
222
+ this._state.setHasChild(this.child !== null);
223
+ this._write(this._state.current);
224
+ this._syncSizing();
225
+ }
226
+
227
+ /**
228
+ * The size source. `ResizeObserver` delivers an initial observation, so the pick is
229
+ * settled before first paint — the same seam `src/breakpoints.ts` gives every other
230
+ * adaptive element, re-created on every connect so a widget MOVED between parents
231
+ * tracks its conditions again.
232
+ *
233
+ * The CHILD is read here rather than cached, because
234
+ * `adw_breakpoint_bin_size_allocate` tests it on every allocation (:427) and a child
235
+ * appended after connect is then a child.
236
+ */
237
+ private _observe(): void {
238
+ this._dispose?.();
239
+ this._dispose = observeAdaptiveSize(this, (size) => {
240
+ if (this._pendingSync) this._syncBreakpoints();
241
+ this._state.setHasChild(this.child !== null);
242
+ const transition = this._state.evaluate(size);
243
+ if (transition === null) return;
244
+ this._emit(transition.from, 'breakpoint-unapply');
245
+ this._perform(transition.writes);
246
+ this._write(transition.to);
247
+ this._emit(transition.to, 'breakpoint-apply');
248
+ this.dispatchEvent(
249
+ new CustomEvent('notify::current-breakpoint', {
250
+ bubbles: true,
251
+ detail: { currentBreakpoint: this.currentBreakpointAttribute },
252
+ }),
253
+ );
254
+ });
255
+ }
256
+
257
+ private _perform(writes: readonly { object: Element; property: string; value: unknown }[]): void {
258
+ for (const write of writes) {
259
+ // A `null` original is an attribute that was ABSENT, and `removeAttribute`
260
+ // is its restore — the one that makes unapply the exact inverse of apply.
261
+ if (write.value === null) write.object.removeAttribute(write.property);
262
+ else write.object.setAttribute(write.property, String(write.value));
263
+ }
264
+ }
265
+
266
+ private _write(index: number | null): void {
267
+ this._applied = index;
268
+ }
269
+
270
+ private _emit(index: number | null, type: string): void {
271
+ if (index === null) return;
272
+ this.dispatchEvent(new CustomEvent(type, { bubbles: true, detail: { index } }));
273
+ }
274
+
275
+ /** The measure rules of a bin that holds breakpoints (:356, :388, :669). */
276
+ private _syncSizing(): void {
277
+ const adaptive = this._state.length > 0;
278
+ // `display` and the clip are left to the author's stylesheet on purpose: the
279
+ // MINIMUM is the documented rule, and writing `display` from here would fight a
280
+ // host page that lays the bin out in a grid.
281
+ this.style.minWidth = adaptive ? '0px' : '';
282
+ this.style.minHeight = adaptive ? '0px' : '';
283
+ if (adaptive) this.style.overflow = 'hidden';
284
+ }
285
+ }
286
+
287
+ customElements.define('adw-breakpoint-bin', AdwBreakpointBin);
@@ -0,0 +1,207 @@
1
+ // <adw-clamp-scrollable> — the CLAMP whose child scrolls, and the widget
2
+ // `AdwClamp`'s own header points at for anything that must scroll inside a readable
3
+ // width (`adw-clamp-scrollable.c:20-27`: "The primary use case for AdwClampScrollable is
4
+ // clamping Gtk.ListView").
5
+ //
6
+ // SAME ARITHMETIC AS `<adw-clamp>`, both halves of it: the allocation is
7
+ // `clampAllocate` out of `@gjsify/adwaita-core` — `lower`/`max`/`upper`, the
8
+ // ease-out-cubic tightening region and the `small`/`medium`/`large` class stamped on the
9
+ // CHILD — reached through `normalizeClampSize` and the `AdwLengthUnit` conversion
10
+ // `adw-clamp-layout.c:166-171` does per property. The difference is the ORIENTATION and
11
+ // the scrolling.
12
+ //
13
+ // THE ORIENTATION IS THE WIDGET, NOT THE CLAMP'S. `set_orientation` forwards to the
14
+ // layout manager (adw-clamp-scrollable.c:78-92) and the cap lands on the width for a
15
+ // horizontal clamp and on the HEIGHT for a vertical one
16
+ // (`child_size_from_clamp` measures along `self->orientation`). A vertical clamp
17
+ // therefore centres on the block axis here, where `<adw-clamp>` has no axis to pick.
18
+ //
19
+ // THE SCROLLING MOVES FROM THE CHILD TO THE HOST, and that is the one deviation worth
20
+ // naming. In C the child IS the `Gtk.Scrollable`: the widget binds its `hadjustment`,
21
+ // `vadjustment`, `hscroll-policy` and `vscroll-policy` onto it
22
+ // (adw-clamp-scrollable.c:440-455) and a child that is not scrollable is four
23
+ // `gbinding` warnings at exit 0. A DOM element cannot hand its scrolling to a child that
24
+ // does not know it is inside one, so the scrollport is this element (`overflow`) and the
25
+ // child is what gets capped — the same visible contract, one level up. `hscroll-policy`
26
+ // and `vscroll-policy` therefore land on the HOST's overflow, which is where the C's
27
+ // policy ultimately decided whether the child ever scrolled.
28
+ //
29
+ // `hadjustment`/`vadjustment` have no attribute here: they are `Gtk.Adjustment`
30
+ // objects (a widget-valued property on every renderer), and the browser's scroll
31
+ // position is its own `scrollTop`/`scrollLeft`. That is a PORT-ONLY gap against the
32
+ // `Gtk.Scrollable` interface rather than against `AdwClampScrollable`'s own property
33
+ // list, which is why `check-adwaita-element-properties.mjs` has no entry for it.
34
+ //
35
+ // A11Y: no role. `adw_clamp_scrollable_class_init` sets none.
36
+ //
37
+ // Reference: refs/libadwaita/src/adw-clamp-scrollable.c (set_orientation, set_child,
38
+ // the four adjustment bindings, class_init's layout manager + `clamp` node)
39
+ // Reference: refs/libadwaita/src/adw-clamp-layout.c (child_size_from_clamp, allocate)
40
+ // Copyright (c) 2020 Purism SPC / GNOME contributors (libadwaita). LGPLv2.1+.
41
+ // Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
42
+
43
+ import {
44
+ ADW_CLAMP_DEFAULTS,
45
+ ADW_CLAMP_SIZE_CLASSES,
46
+ type AdwLengthUnit,
47
+ adwLengthToPx,
48
+ clampAllocate,
49
+ normalizeBoxOrientation,
50
+ normalizeClampSize,
51
+ normalizeLengthUnit,
52
+ type BoxOrientation,
53
+ } from '@gjsify/adwaita-core';
54
+
55
+ import { bindSlottedChildren } from '../slotted-children.js';
56
+
57
+ /** `Gtk.ScrollablePolicy`'s three nicks, in enum order. */
58
+ export type ScrollPolicy = 'automatic' | 'always' | 'never';
59
+
60
+ /** `adw_scrollable_policy_to_overflow` — the policy as the CSS `overflow` keyword. */
61
+ const POLICY_OVERFLOW: Record<ScrollPolicy, string> = {
62
+ automatic: 'auto',
63
+ always: 'scroll',
64
+ never: 'hidden',
65
+ };
66
+
67
+ export class AdwClampScrollable extends HTMLElement {
68
+ private _resize: ResizeObserver | null = null;
69
+ private _mutations: MutationObserver | null = null;
70
+
71
+ static get observedAttributes() {
72
+ return ['maximum-size', 'tightening-threshold', 'unit', 'orientation', 'hscroll-policy', 'vscroll-policy'];
73
+ }
74
+
75
+ /** `AdwClampScrollable:maximum-size` — the cap, in `unit`. Default 600. */
76
+ get maximumSize(): number {
77
+ return normalizeClampSize(this.getAttribute('maximum-size'), ADW_CLAMP_DEFAULTS.maximumSize);
78
+ }
79
+
80
+ set maximumSize(value: number) {
81
+ this.setAttribute('maximum-size', String(value));
82
+ }
83
+
84
+ /** `AdwClampScrollable:tightening-threshold` — where the easing starts. Default 400. */
85
+ get tighteningThreshold(): number {
86
+ return normalizeClampSize(this.getAttribute('tightening-threshold'), ADW_CLAMP_DEFAULTS.tighteningThreshold);
87
+ }
88
+
89
+ set tighteningThreshold(value: number) {
90
+ this.setAttribute('tightening-threshold', String(value));
91
+ }
92
+
93
+ /** `AdwClampScrollable:unit` — the length unit both sizes are written in. Default `sp`. */
94
+ get unit(): AdwLengthUnit {
95
+ return normalizeLengthUnit(this.getAttribute('unit'), 'sp');
96
+ }
97
+
98
+ set unit(value: AdwLengthUnit) {
99
+ this.setAttribute('unit', value);
100
+ }
101
+
102
+ /** `GtkOrientable:orientation`, which this class overrides. Default horizontal. */
103
+ get orientation(): BoxOrientation {
104
+ return normalizeBoxOrientation(this.getAttribute('orientation'));
105
+ }
106
+
107
+ set orientation(value: BoxOrientation) {
108
+ this.setAttribute('orientation', value);
109
+ }
110
+
111
+ connectedCallback() {
112
+ // `AdwClampScrollable:child` is a widget PROPERTY, so a `.blp`'s `child: …`
113
+ // authors `slot="child"`. Every child here is already the content, so only the
114
+ // NAME is enrolled — the reason `adw-clamp.ts` gives for not calling
115
+ // `.install()`.
116
+ bindSlottedChildren(this, [{ name: 'child', into: this }]);
117
+
118
+ // ResizeObserver delivers an initial observation on `observe()`, so the first
119
+ // allocation lands before paint without a seeding pass.
120
+ this._resize = new ResizeObserver(() => this._allocate());
121
+ this._resize.observe(this);
122
+ // A child appended after connect is capped too; without this it keeps whatever
123
+ // width it arrived with.
124
+ this._mutations = new MutationObserver(() => this._allocate());
125
+ this._mutations.observe(this, { childList: true });
126
+
127
+ this._applyOverflow();
128
+ this._allocate();
129
+ }
130
+
131
+ disconnectedCallback() {
132
+ this._resize?.disconnect();
133
+ this._resize = null;
134
+ this._mutations?.disconnect();
135
+ this._mutations = null;
136
+ }
137
+
138
+ attributeChangedCallback() {
139
+ this._applyOverflow();
140
+ this._allocate();
141
+ }
142
+
143
+ /**
144
+ * `Gtk.Scrollable:hscroll-policy` / `vscroll-policy` — the two overrides the class
145
+ * re-declares (adw-clamp-scrollable.c:118-141) and then binds onto the child. They
146
+ * decide here whether this element scrolls at all, which is the question they answer
147
+ * in C.
148
+ */
149
+ private _applyOverflow(): void {
150
+ const horizontal = this.getAttribute('hscroll-policy') as ScrollPolicy | null;
151
+ const vertical = this.getAttribute('vscroll-policy') as ScrollPolicy | null;
152
+ this.style.overflowX = horizontal === null ? 'auto' : (POLICY_OVERFLOW[horizontal] ?? 'auto');
153
+ this.style.overflowY = vertical === null ? 'auto' : (POLICY_OVERFLOW[vertical] ?? 'auto');
154
+ }
155
+
156
+ /**
157
+ * `adw_clamp_layout_allocate`, against the AVAILABLE size on the clamped axis.
158
+ *
159
+ * The cap sits on the CHILD, never here: this element is the scrollport, so a cap on
160
+ * itself would feed its own capped width back into its ResizeObserver — a feedback
161
+ * loop rather than a measurement (the reasoning `<adw-clamp>` carries in full).
162
+ */
163
+ private _allocate(): void {
164
+ const vertical = this.orientation === 'vertical';
165
+ const unit = this.unit;
166
+ const available = vertical ? this.clientHeight : this.clientWidth;
167
+
168
+ // `childMin` is 0, as in `<adw-clamp>`: a child that declares a minimum keeps it
169
+ // (CSS 2.1 §10.4 lets `min-*` beat `max-*`), and one that declares none has a
170
+ // minimum of 0 — the value a synchronous re-measure would arrive at anyway.
171
+ const params = {
172
+ maximumSize: adwLengthToPx(unit, this.maximumSize),
173
+ tighteningThreshold: adwLengthToPx(unit, this.tighteningThreshold),
174
+ childMin: 0,
175
+ childNat: 0,
176
+ };
177
+
178
+ for (const child of Array.from(this.children) as HTMLElement[]) {
179
+ if (available <= 0) {
180
+ // GTK's equivalent is `for_size = -1`: leave the child alone rather than
181
+ // capping it at 0 and collapsing the page.
182
+ child.style.maxWidth = '';
183
+ child.style.maxHeight = '';
184
+ child.style.marginInline = '';
185
+ child.style.marginBlock = '';
186
+ for (const cls of ADW_CLAMP_SIZE_CLASSES) child.classList.remove(cls);
187
+ continue;
188
+ }
189
+
190
+ const { childSize, sizeClass } = clampAllocate(available, params);
191
+ if (vertical) {
192
+ child.style.maxWidth = '';
193
+ child.style.maxHeight = `${childSize}px`;
194
+ child.style.marginInline = '';
195
+ child.style.marginBlock = 'auto';
196
+ } else {
197
+ child.style.maxWidth = `${childSize}px`;
198
+ child.style.maxHeight = '';
199
+ child.style.marginInline = 'auto';
200
+ child.style.marginBlock = '';
201
+ }
202
+ for (const cls of ADW_CLAMP_SIZE_CLASSES) child.classList.toggle(cls, cls === sizeClass);
203
+ }
204
+ }
205
+ }
206
+
207
+ customElements.define('adw-clamp-scrollable', AdwClampScrollable);
@@ -19,6 +19,12 @@
19
19
  // Events, all bubbling CustomEvents: `notify::open` (detail `{ open }`), `closed`
20
20
  // (Adw.Dialog::closed), `close-attempt` (Adw.Dialog::close-attempt).
21
21
  //
22
+ // SUBCLASSING: `decorateHeader(header)` is the one hook, and it exists for
23
+ // `<gtk-about-dialog>`, whose headerbar carries a stack switcher in the title position
24
+ // instead of a title (gtkaboutdialog.ui). Chrome, focus, Escape and dismissal stay here,
25
+ // so a subclass that wants a different header adds to this one rather than building a
26
+ // second scrim.
27
+ //
22
28
  // Reference: refs/libadwaita/src/adw-dialog.c (present/close/can-close, Escape, focus)
23
29
  // Reference: refs/libadwaita/src/stylesheet/widgets/_dialogs.scss (floating sheet + bottom sheet)
24
30
  // Copyright (c) 2023-2024 GNOME Foundation Inc. (libadwaita). LGPLv2.1+.
@@ -223,6 +229,17 @@ export class AdwDialog extends HTMLElement {
223
229
  this._modal.dismiss();
224
230
  }
225
231
 
232
+ /**
233
+ * Add to the header bar, called at the end of every render.
234
+ *
235
+ * The hook is for a DIALOG whose header is not a title plus a close button, which is
236
+ * what `<gtk-about-dialog>` needs: `gtkaboutdialog.ui` puts a `GtkStackSwitcher` in
237
+ * the titlebar's title-widget position and no title text at all. An empty body is the
238
+ * default, so every other dialog is unaffected — and the header element is the one
239
+ * the base already owns, so a subclass never reaches into private state to get it.
240
+ */
241
+ protected decorateHeader(_header: HTMLElement): void {}
242
+
226
243
  private _render(): void {
227
244
  this.classList.toggle('open', this.open);
228
245
 
@@ -244,6 +261,8 @@ export class AdwDialog extends HTMLElement {
244
261
  const locked = !this.canClose;
245
262
  this._closeBtn.disabled = locked;
246
263
  this._closeBtn.classList.toggle('locked', locked);
264
+
265
+ this.decorateHeader(this._headerEl);
247
266
  }
248
267
  }
249
268
 
@@ -0,0 +1,95 @@
1
+ // <adw-layout-slot> — one named hole inside a layout of an `Adw.MultiLayoutView`.
2
+ //
3
+ // `AdwLayoutSlot` is a bin with an ID and nothing else: it takes a child when the view
4
+ // inserts the child whose ID matches, and its `visible` property is bound to that
5
+ // child's so hiding the child hides the hole (:151). The ID is what pairs the two
6
+ // sides — `adw_multi_layout_view_set_child(id, widget)` finds the layout's slots by
7
+ // `g_hash_table_lookup (self->slots, id)` (:139) — and it is CONSTRUCT-ONLY
8
+ // (adw-layout-slot.c:145), so it is read once and never written.
9
+ //
10
+ // DUPLICATE IDs ACROSS LAYOUTS ARE THE WIDGET'S OWN MODEL, not a mistake here: the
11
+ // canonical example in the C documentation puts an `AdwLayoutSlot` with `id="primary"`
12
+ // in BOTH layouts of one view, because that is how a child follows a layout change. The
13
+ // element never resolves a slot by document lookup, only from the subtree of the layout
14
+ // it is currently mounting, so two of them with one ID are ordinary.
15
+ //
16
+ // Attributes:
17
+ // id (`AdwLayoutSlot:id` — the slot ID. Construct-only upstream, so changing it here
18
+ // after connect re-registers the slot and warns, as `g_error` does for a slot
19
+ // constructed without one (adw-layout-slot.c:68).)
20
+ //
21
+ // A11Y: `role="group"`, the accessible role libadwaita installs on the class
22
+ // (adw-layout-slot.c:131).
23
+ //
24
+ // There is no box of its own (`display: contents`, so the child takes the allocation the
25
+ // container would have given the slot) and libadwaita ships NO rule for this widget —
26
+ // `src/stylesheet/widgets/` has no `layout-slot` partial and no selector names the node,
27
+ // so there is nothing to port and nothing invented to replace it.
28
+ //
29
+ // Reference: refs/libadwaita/src/adw-layout-slot.c
30
+ // Copyright (c) 2023-2024 Purism SPC / GNOME Foundation Inc. (libadwaita). LGPLv2.1+.
31
+ // Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
32
+
33
+ import { AdwMultiLayoutView } from './adw-multi-layout-view.js';
34
+
35
+ export class AdwLayoutSlot extends HTMLElement {
36
+ private _registered = false;
37
+
38
+ static get observedAttributes() {
39
+ return ['id'];
40
+ }
41
+
42
+ /** `adw_layout_slot_get_slot_id()` (:184), read under its property's name. */
43
+ get slotId(): string | null {
44
+ return this.getAttribute('id');
45
+ }
46
+
47
+ connectedCallback() {
48
+ this.setAttribute('role', 'group');
49
+ // `display: contents` inline rather than in a partial: libadwaita styles nothing
50
+ // here, and a host page that wants the slot to box its child sets one rule.
51
+ this.style.display = 'contents';
52
+ this._register();
53
+ }
54
+
55
+ disconnectedCallback() {
56
+ this._registered = false;
57
+ }
58
+
59
+ attributeChangedCallback(name?: string) {
60
+ if (!this.isConnected || name !== 'id') return;
61
+ if (this._registered) {
62
+ // `G_PARAM_CONSTRUCT_ONLY`: upstream cannot change a slot's ID either, and
63
+ // the bin's `slots` table is keyed by it — `register_slot` refuses a second
64
+ // entry under one ID (adw-multi-layout-view.c:693). Saying so beats
65
+ // silently leaving the view holding the old pairing.
66
+ console.warn('<adw-layout-slot>: `id` is construct-only upstream; re-registering the slot.');
67
+ }
68
+ this._register();
69
+ }
70
+
71
+ /**
72
+ * Hand this slot to the nearest `<adw-multi-layout-view>` ancestor.
73
+ *
74
+ * `adw_layout_slot_root` walks up for the view and calls
75
+ * `adw_multi_layout_view_register_slot` (adw-layout-slot.c:55). The view's own
76
+ * mount path is the authority — it registers only while it is building a layout —
77
+ * so a call arriving outside that window is refused there, exactly as
78
+ * `accepting_slots` refuses it upstream.
79
+ */
80
+ private _register(): void {
81
+ const id = this.slotId;
82
+ if (id === null || id === '') {
83
+ console.error('<adw-layout-slot> created without an `id` — libadwaita refuses this with g_error.');
84
+ return;
85
+ }
86
+ // `instanceof` rather than a cast on `closest(…)`: an ancestor that is present
87
+ // but not upgraded yet satisfies a cast and fails at the call, and this is on the
88
+ // connect path of every slot.
89
+ const view = this.closest('adw-multi-layout-view');
90
+ if (view instanceof AdwMultiLayoutView) view.registerSlot(id, this);
91
+ this._registered = true;
92
+ }
93
+ }
94
+
95
+ customElements.define('adw-layout-slot', AdwLayoutSlot);