@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,332 @@
1
+ // <adw-view-switcher-sidebar> — an adaptive sidebar that drives an `<adw-view-stack>`
2
+ // (the web counterpart of Adw.ViewSwitcherSidebar, libadwaita 1.9). It is an
3
+ // `<adw-sidebar>` filled from the stack's page list, which is the whole difference
4
+ // from every other Adw switcher: the pages can be GROUPED into sections, each row
5
+ // carries an icon, a title and an unread dot or a badge, and the whole thing collapses
6
+ // from a sidebar into a page of boxed lists (`mode`).
7
+ //
8
+ // It is a COMPOSITE and it says so: this element owns one `<adw-sidebar>` and drives it
9
+ // from the stack, rather than reimplementing a sidebar. The rows, the section headers,
10
+ // the selection, the filter and the empty state are the `<adw-sidebar>` element's; what
11
+ // lives here is the C half — `populate_sidebar`, `activated_cb` and the properties.
12
+ //
13
+ // THE RULES THAT ARE C AND NOT MARKUP (adw-view-switcher-sidebar.c):
14
+ //
15
+ // · `populate_sidebar` (:225-249): a page with `starts-section` opens a section and the
16
+ // one before it is flushed; the FIRST page opens a section whatever it says, because
17
+ // the test is `if (!section || get_starts_section (page))`; and the heading is the
18
+ // opening page's `section-title`. The grouping itself is core's
19
+ // {@link viewSwitcherSidebarSections}, pinned by the conformance vectors.
20
+ // · `add_item` (:184-206): each item's title, icon, use-underline and visibility are BOUND
21
+ // to the page's, so a later change reaches the row without a rebuild here.
22
+ // · `update_badge` (:133-181): no attention and no count means NO indicator at all; a
23
+ // count replaces the dot with a label capped at `999+` (`> 999`, so 999 prints); and
24
+ // `.needs-attention` rides on the bin whether or not there is a number. The bin is the
25
+ // item's `suffix`, which is what `<adw-sidebar>`'s `badge-number` /`needs-attention`
26
+ // attributes spell.
27
+ // · `activated_cb` (:104-112): activating a row selects the stack page at the SAME index
28
+ // and only then emits `activated` — the signal an `Adw.NavigationSplitView` listens to
29
+ // in order to reveal its content pane, so firing it before the selection moved would
30
+ // reveal the previous page.
31
+ // · `selection_changed_cb` (:258-271): the row follows the stack, not the other way round,
32
+ // which is what keeps a programmatic `visible-child-name` write highlighted.
33
+ //
34
+ // `stack`, `filter`, `placeholder`, `prefix` and `suffix` are all widget- or object-valued
35
+ // properties: `stack` is an element id in the attribute and an element in the property,
36
+ // `filter` is a property (a function, which no attribute can carry), and the three widget
37
+ // ones are `slot="…"` children — the `AdwTabPage:child` rule, because a `.blp`'s
38
+ // `placeholder: …` authors a slot.
39
+ //
40
+ // A11Y: `<adw-sidebar>` carries `role="listbox"`, so the host adds nothing; the sections
41
+ // are headings inside it, and the C signal has no row identity of its own to forward.
42
+ //
43
+ // KNOWN_GAPS: none — `mode` is this widget's only scalar property and it is observed.
44
+ //
45
+ // Reference: refs/libadwaita/src/adw-view-switcher-sidebar.c (populate_sidebar,
46
+ // add_item, update_badge, activated_cb, selection_changed_cb, the six pspecs)
47
+ // Reference: refs/libadwaita/src/adw-sidebar.c (the widget it drives)
48
+ // Reference: refs/libadwaita/src/stylesheet/widgets/_sidebars.scss:250-277
49
+ // (`view-switcher-sidebar .indicator`)
50
+ // Copyright (c) 2025 GNOME Foundation Inc. (libadwaita). LGPLv2.1-or-later.
51
+ // Modifications: Implemented as a Web Component for @gjsify/adwaita-web; the sidebar it
52
+ // drives is a real `<adw-sidebar>` and the icon nodes are <gtk-image>.
53
+
54
+ import { viewSwitcherPagesFromStack, viewSwitcherSidebarSections } from '@gjsify/adwaita-core';
55
+ import type { AdwSidebarItemSpec, AdwSidebarSectionSpec, SidebarItemFilter } from '@gjsify/adwaita-core';
56
+
57
+ import { bindSlottedChildren } from '../slotted-children.js';
58
+ import type { AdwSidebar } from './adw-sidebar.js';
59
+ import type { AdwViewStack } from './adw-view-stack.js';
60
+
61
+ export class AdwViewSwitcherSidebar extends HTMLElement {
62
+ private _sidebar!: AdwSidebar;
63
+ private _placeholderEl!: HTMLDivElement;
64
+ private _prefixEl!: HTMLDivElement;
65
+ private _suffixEl!: HTMLDivElement;
66
+ private _stack: AdwViewStack | null = null;
67
+ private _filter: SidebarItemFilter | null = null;
68
+ private _initialized = false;
69
+
70
+ static get observedAttributes() {
71
+ return ['stack', 'mode'];
72
+ }
73
+
74
+ /** `AdwViewSwitcherSidebar:stack` — the stack the sidebar controls. */
75
+ get stack(): AdwViewStack | null {
76
+ return this._stack;
77
+ }
78
+
79
+ set stack(value: AdwViewStack | string | null) {
80
+ this.setStack(value === null ? null : typeof value === 'string' ? this._resolveStack(value) : value);
81
+ }
82
+
83
+ /**
84
+ * `adw_view_switcher_sidebar_set_stack`: unbind the old stack's four connections, bind
85
+ * the new one's, and populate. A NULL stack is refused, exactly as C is
86
+ * (`g_return_if_fail (!stack)`, :284) — an overview-less sidebar is not a state the C
87
+ * has, and inventing one here would give a reader a widget libadwaita cannot build.
88
+ */
89
+ setStack(stack: AdwViewStack | null): void {
90
+ if (stack === null) return;
91
+ if (this._stack === stack) return;
92
+ this._unbindStack();
93
+ this._stack = stack;
94
+ this._bindStack();
95
+ this._populate();
96
+ this._syncSelection();
97
+ this.dispatchEvent(new CustomEvent('notify::stack', { bubbles: true, detail: { stack } }));
98
+ }
99
+
100
+ /** `AdwViewSwitcherSidebar:mode` — `sidebar` (default) or `page`. */
101
+ get mode(): 'sidebar' | 'page' {
102
+ return this.getAttribute('mode') === 'page' ? 'page' : 'sidebar';
103
+ }
104
+
105
+ set mode(value: 'sidebar' | 'page') {
106
+ this.setAttribute('mode', value);
107
+ }
108
+
109
+ /**
110
+ * `AdwViewSwitcherSidebar:filter` — a `GtkFilter`, which on this renderer is the
111
+ * sidebar's own predicate. A property and not an attribute: it is a FUNCTION, and
112
+ * markup cannot carry one.
113
+ */
114
+ get filter(): SidebarItemFilter | null {
115
+ return this._filter;
116
+ }
117
+
118
+ set filter(value: SidebarItemFilter | null) {
119
+ this._filter = value;
120
+ if (this._initialized) {
121
+ this._sidebar.filter = value;
122
+ this._applyEmptyState();
123
+ }
124
+ }
125
+
126
+ /** `AdwViewSwitcherSidebar:placeholder` — shown when no item survives. */
127
+ get placeholder(): HTMLElement | null {
128
+ return this._placeholderEl.firstElementChild as HTMLElement | null;
129
+ }
130
+
131
+ set placeholder(value: HTMLElement | null) {
132
+ if (value === null) this._placeholderEl.replaceChildren();
133
+ else this._placeholderEl.replaceChildren(value);
134
+ this._applyEmptyState();
135
+ }
136
+
137
+ /**
138
+ * `AdwViewSwitcherSidebar:prefix` (1.10) — shown above the items.
139
+ *
140
+ * NOT `prefix`. `HTMLElement.prefix` is the RDFa attribute and a STRING, and a
141
+ * property of a different type cannot shadow it (TS2416). The GIR name is kept in the
142
+ * SLOT (`slot="prefix"`, what a `.blp`'s `prefix: …` authors) and here in the header.
143
+ */
144
+ get prefixWidget(): HTMLElement | null {
145
+ return this._prefixEl.firstElementChild as HTMLElement | null;
146
+ }
147
+
148
+ set prefixWidget(value: HTMLElement | null) {
149
+ if (value === null) this._prefixEl.replaceChildren();
150
+ else this._prefixEl.replaceChildren(value);
151
+ }
152
+
153
+ /** `AdwViewSwitcherSidebar:suffix` (1.10) — shown below the items. `suffixWidget`, as `prefixWidget`. */
154
+ get suffixWidget(): HTMLElement | null {
155
+ return this._suffixEl.firstElementChild as HTMLElement | null;
156
+ }
157
+
158
+ set suffixWidget(value: HTMLElement | null) {
159
+ if (value === null) this._suffixEl.replaceChildren();
160
+ else this._suffixEl.replaceChildren(value);
161
+ }
162
+
163
+ connectedCallback() {
164
+ if (this._initialized) {
165
+ this._bindStack();
166
+ this._populate();
167
+ return;
168
+ }
169
+ this._initialized = true;
170
+
171
+ this._prefixEl = document.createElement('div');
172
+ this._prefixEl.className = 'view-switcher-sidebar-prefix';
173
+ this._suffixEl = document.createElement('div');
174
+ this._suffixEl.className = 'view-switcher-sidebar-suffix';
175
+ this._placeholderEl = document.createElement('div');
176
+ this._placeholderEl.className = 'view-switcher-sidebar-placeholder';
177
+ this._placeholderEl.hidden = true;
178
+
179
+ // The widget C composes (`adw_view_switcher_sidebar_init`, :555-560): an
180
+ // `AdwSidebar`, parented to the widget, with `activated` re-emitted.
181
+ this._sidebar = document.createElement('adw-sidebar') as AdwSidebar;
182
+ this._sidebar.addEventListener('activated', this._onSidebarActivated);
183
+
184
+ const box = document.createElement('div');
185
+ box.className = 'view-switcher-sidebar-box';
186
+ box.append(this._sidebar, this._placeholderEl);
187
+
188
+ // `placeholder`, `prefix` and `suffix` are widget PROPERTIES, so a `.blp`'s
189
+ // `placeholder: …` authors `slot="placeholder"` — the rule `adw-tab-page` states.
190
+ // `install` is what routes the author's children out BEFORE the host is emptied,
191
+ // and it takes the structure this element owns; a bare `replaceChildren` here
192
+ // would destroy every declared slotted child.
193
+ bindSlottedChildren(this, [
194
+ { name: 'placeholder', into: this._placeholderEl },
195
+ { name: 'prefix', into: this._prefixEl },
196
+ { name: 'suffix', into: this._suffixEl },
197
+ ]).install(this._prefixEl, box, this._suffixEl);
198
+ this._applyMode();
199
+
200
+ const declared = this.getAttribute('stack');
201
+ this.setStack(declared === null ? this._findStack() : this._resolveStack(declared));
202
+ // A widget with NO stack is C's own starting state (`set_stack` refuses NULL, so
203
+ // `populate_sidebar` never ran) and it reads as the empty sidebar plus the
204
+ // placeholder — which only `_applyEmptyState` decides.
205
+ this._applyEmptyState();
206
+ }
207
+
208
+ disconnectedCallback() {
209
+ this._unbindStack();
210
+ }
211
+
212
+ attributeChangedCallback(name: string, _old: string | null, value: string | null) {
213
+ if (!this._initialized) return;
214
+ if (name === 'stack') this.setStack(value === null ? this._findStack() : this._resolveStack(value));
215
+ else if (name === 'mode') this._applyMode();
216
+ }
217
+
218
+ private _resolveStack(ref: string): AdwViewStack | null {
219
+ return (document.getElementById(ref) as AdwViewStack | null) ?? this._findStack();
220
+ }
221
+
222
+ /** The stack this sidebar is next to, when the author named no id. */
223
+ private _findStack(): AdwViewStack | null {
224
+ const parent = this.parentElement;
225
+ return (parent?.querySelector('adw-view-stack') as AdwViewStack | null) ?? null;
226
+ }
227
+
228
+ /** `set_stack`'s four connections (:270-282), read off the stack's own events. */
229
+ private _bindStack(): void {
230
+ this._unbindStack();
231
+ for (const type of STACK_EVENTS) this._stack?.addEventListener(type, this._onStackChange);
232
+ }
233
+
234
+ private _unbindStack(): void {
235
+ for (const type of STACK_EVENTS) this._stack?.removeEventListener(type, this._onStackChange);
236
+ }
237
+
238
+ private _onStackChange = (): void => {
239
+ this._populate();
240
+ this._syncSelection();
241
+ };
242
+
243
+ /**
244
+ * `activated_cb` (:104-112) — the row's index is the stack's index, so the two lists
245
+ * are kept one for one. The selection moves FIRST: `activated` is the signal a split
246
+ * view reveals its content pane on, and a handler that read the stack in that callback
247
+ * would otherwise see the page the user was leaving.
248
+ */
249
+ private _onSidebarActivated = (event: Event): void => {
250
+ // The `<adw-sidebar>` is an IMPLEMENTATION DETAIL of this composite — the widget C
251
+ // parents in `adw_view_switcher_sidebar_init` is private, and only `activated` is
252
+ // re-emitted from it. Its own event bubbles, so without this a listener on the
253
+ // host sees the inner one AND the re-emission, and `index` arrives twice.
254
+ event.stopPropagation();
255
+ const index = (event as CustomEvent).detail.index as number;
256
+ const stack = this._stack;
257
+ if (stack === null) return;
258
+ stack.selectNthPage(index);
259
+ this.dispatchEvent(new CustomEvent('activated', { bubbles: true, detail: { index } }));
260
+ };
261
+
262
+ /**
263
+ * `populate_sidebar` (:225-249) — one `AdwSidebarSection` per group of pages, each
264
+ * holding one `AdwSidebarItem` per page. The grouping is core's, so the browser and
265
+ * any second renderer derive the sections from the same table.
266
+ */
267
+ private _populate(): void {
268
+ const stack = this._stack;
269
+ if (stack === null) {
270
+ this._sidebar.sections = [];
271
+ this._applyEmptyState();
272
+ return;
273
+ }
274
+ const pages = viewSwitcherPagesFromStack(stack.pages);
275
+ this._sidebar.sections = viewSwitcherSidebarSections(pages).map((section) => this._toSectionSpec(section));
276
+ this._applyEmptyState();
277
+ }
278
+
279
+ private _toSectionSpec(section: ReturnType<typeof viewSwitcherSidebarSections>[number]): AdwSidebarSectionSpec {
280
+ const items: AdwSidebarItemSpec[] = section.pages.map((page) => ({
281
+ // `g_object_bind_property (page, "title", item, "title", …)`: the row shows the
282
+ // page's title, never a resolved fallback — `createViewSwitcherPage` has already
283
+ // resolved it against the page NAME, which is what C binds too.
284
+ title: page.title ?? '',
285
+ iconName: page.iconName ?? '',
286
+ visible: page.visible,
287
+ badgeNumber: page.badgeNumber,
288
+ needsAttention: page.needsAttention,
289
+ }));
290
+ // `section-title` bound to the SECTION's title; an empty one is the separator
291
+ // header, which is `<adw-sidebar-section>`'s own rule (`update_header_page_cb`).
292
+ return { title: section.title, items };
293
+ }
294
+
295
+ /**
296
+ * `selection_changed_cb` (:258-271) — the row follows the stack's visible page. Read as
297
+ * the INDEX, because the sidebar's flat index space is the unfiltered one (ADR 0004),
298
+ * so page position and row position are the same number.
299
+ */
300
+ private _syncSelection(): void {
301
+ const stack = this._stack;
302
+ if (stack === null) return;
303
+ const index = stack.visibleChildIndex;
304
+ if (index < 0) return;
305
+ if (this._sidebar.selected !== index) this._sidebar.selected = index;
306
+ }
307
+
308
+ private _applyMode(): void {
309
+ const page = this.mode === 'page';
310
+ this.classList.toggle('page', page);
311
+ this._sidebar.mode = this.mode;
312
+ }
313
+
314
+ /**
315
+ * `placeholder` (:449-460) — shown when the sidebar has no items, or when the filter
316
+ * took them all. The `<adw-sidebar>` knows the filtered list (`visibleItems` is empty),
317
+ * which is the C condition in `AdwSidebar`'s own words.
318
+ */
319
+ private _applyEmptyState(): void {
320
+ // `<adw-sidebar>`'s OWN answer, which counts the FILTERED model — the condition
321
+ // `update_placeholder` binds the placeholder to. Counting the DOM rows here would
322
+ // find them all still standing, because a filter HIDES a row and never removes it.
323
+ const empty = this._sidebar.classList.contains('empty');
324
+ this._placeholderEl.hidden = !empty;
325
+ this.classList.toggle('empty', empty);
326
+ }
327
+ }
328
+
329
+ /** The stack signals `set_stack` connects to: the page list, its sections and the selection. */
330
+ const STACK_EVENTS = ['items-changed', 'notify::visible-child'] as const;
331
+
332
+ customElements.define('adw-view-switcher-sidebar', AdwViewSwitcherSidebar);
@@ -1,17 +1,191 @@
1
- // <adw-window> — Adwaita application window frame.
2
- // Provides rounded corners, shadow, and flex column layout.
3
- // Adapted from Adwaita Web UI Framework (https://github.com/mclellac/adwaita-web).
4
- // Copyright (c) 2025 csm. MIT License.
5
- // Modifications: Reimplemented as Web Component for @gjsify/adwaita-web.
1
+ // <adw-window> — the web counterpart of Adw.Window: a freeform window with no
2
+ // titlebar area. Adw.Window styles nothing itself — you pair it with
3
+ // Adw.ToolbarView and an Adw.HeaderBar (or a Gtk.HeaderBar) to get the chrome —
4
+ // so this element owns the FRAME and the window's own state, and the chrome is
5
+ // whatever you put in it.
6
+ //
7
+ // THE FRAME IS IN-PAGE, and that is the whole difference from GTK. A document has
8
+ // no window manager, so this element is a box on the page, not a toplevel: no
9
+ // titlebar, no `.tiled`/`.maximized`/`.solid-csd` decoration classes, no focus
10
+ // stealing on present. What IS ported is the frame libadwaita draws for a CSD
11
+ // window (border-radius, the three-layer shadow, the 1px outline), the size
12
+ // request GTK makes for an AdwWindow, the content property, the breakpoints and
13
+ // the open-dialog bookkeeping.
14
+ //
15
+ // Children are placed in the content area (the Adw.Window:content property).
16
+ // The window supports breakpoints via addBreakpoint() and tracks open dialogs
17
+ // presented inside it. The default size is 360×200, matching the C source.
18
+ //
19
+ // Attributes:
20
+ // width, height — the size REQUEST in px, the one `gtk_widget_set_size_request
21
+ // (GTK_WIDGET (self), 360, 200)` makes in adw_window_init (C:344). Absent, the
22
+ // element keeps that default; an explicit attribute overrides it.
23
+ //
24
+ // Properties: `content` (the Adw.Window:content child), `breakpoints`,
25
+ // `currentBreakpoint` (Adw.Window:current-breakpoint), `dialogs` and
26
+ // `visibleDialog` (Adw.Window:dialogs / :visible-dialog), `contentArea`.
27
+ //
28
+ // NOT PORTED: `adaptive-preview` — a debug mode that lets you resize the window to
29
+ // a set of device sizes, opened from GTK Inspector or Ctrl+Shift+M. A browser has
30
+ // no inspector and no device to simulate; a CSS media query does the same job and
31
+ // the breakpoints below are how libadwaita itself does it. Ledgered in KNOWN_GAPS.
32
+ //
33
+ // Reference: refs/libadwaita/src/adw-window.c (AdwWindow behaviour)
34
+ // Reference: refs/libadwaita/src/stylesheet/widgets/_window.scss (window frame)
35
+ // Copyright (c) 2020-2023 Alice Mikhaylenko / Purism SPC (libadwaita). LGPLv2.1+
36
+ // Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
37
+
38
+ import { AdwBreakpoint } from '@gjsify/adwaita-core';
39
+ import { addBreakpoints } from '../breakpoints.js';
40
+ import { bindSlottedChildren } from '../slotted-children.js';
41
+
42
+ /** The default minimum size of an AdwWindow, from adw_window_init (C:344). */
43
+ const DEFAULT_WIDTH = 360;
44
+ const DEFAULT_HEIGHT = 200;
6
45
 
7
46
  export class AdwWindow extends HTMLElement {
47
+ private _initialized = false;
48
+ private _contentEl!: HTMLDivElement;
49
+ private _breakpoints: AdwBreakpoint[] = [];
50
+ private _disposeBreakpoints: (() => void) | null = null;
51
+ private _openDialogs: HTMLElement[] = [];
52
+
53
+ static get observedAttributes() {
54
+ return ['width', 'height'];
55
+ }
56
+
57
+ /** The content area — the Adw.Window:content property. */
58
+ get contentArea(): HTMLDivElement {
59
+ return this._contentEl;
60
+ }
61
+
62
+ /** The content widget — the first child of the content area. */
63
+ get content(): HTMLElement | null {
64
+ return this._contentEl.firstElementChild as HTMLElement | null;
65
+ }
66
+
67
+ set content(value: HTMLElement | null) {
68
+ if (value) {
69
+ this._contentEl.appendChild(value);
70
+ }
71
+ }
72
+
73
+ /** The breakpoints added to this window. */
74
+ get breakpoints(): readonly AdwBreakpoint[] {
75
+ return this._breakpoints;
76
+ }
77
+
78
+ /** The currently applied breakpoint, or null when none is. */
79
+ get currentBreakpoint(): AdwBreakpoint | null {
80
+ return this._breakpoints.find((bp) => bp.applied) ?? null;
81
+ }
82
+
83
+ /** The open dialogs presented inside this window (Adw.Window:dialogs). */
84
+ get dialogs(): readonly HTMLElement[] {
85
+ // A dialog taken out of the document never raises `notify::open` on the way
86
+ // out, so a dialog that was REMOVED while open would otherwise stay listed
87
+ // for the rest of the window's life.
88
+ this._openDialogs = this._openDialogs.filter((dialog) => dialog.isConnected);
89
+ return this._openDialogs;
90
+ }
91
+
92
+ /** The currently visible dialog, or null when none is (Adw.Window:visible-dialog). */
93
+ get visibleDialog(): HTMLElement | null {
94
+ const dialogs = this.dialogs;
95
+ return dialogs.length > 0 ? (dialogs[dialogs.length - 1] as HTMLElement) : null;
96
+ }
97
+
98
+ /**
99
+ * Add a breakpoint to this window (adw_window_add_breakpoint).
100
+ * The breakpoint evaluates against the window's own box and sets a
101
+ * `data-breakpoint` attribute when applied.
102
+ */
103
+ addBreakpoint(condition: string): AdwBreakpoint {
104
+ const bp = new AdwBreakpoint(condition, {
105
+ onApply: () => (this.dataset.breakpoint = condition),
106
+ onUnapply: () => {
107
+ if (this.dataset.breakpoint === condition) delete this.dataset.breakpoint;
108
+ },
109
+ });
110
+ this._breakpoints.push(bp);
111
+ // Re-evaluated against a box that may have changed since the last add.
112
+ this._bindBreakpoints();
113
+ return bp;
114
+ }
115
+
8
116
  connectedCallback() {
9
- // Light DOM: children remain in place, element itself is the styled container.
10
- // Set dimensions from attributes if provided.
11
- const w = this.getAttribute('width');
12
- const h = this.getAttribute('height');
13
- if (w) this.style.width = `${w}px`;
14
- if (h) this.style.height = `${h}px`;
117
+ this._buildOnce();
118
+ // EVERY connect, not only the first — see `_bindBreakpoints`.
119
+ this._bindBreakpoints();
120
+ }
121
+
122
+ disconnectedCallback() {
123
+ this._disposeBreakpoints?.();
124
+ this._disposeBreakpoints = null;
125
+ }
126
+
127
+ attributeChangedCallback(name: string) {
128
+ // The size request is read from the ATTRIBUTE, so it is applied on every
129
+ // change — including one that arrived before the element was connected, which
130
+ // is the ordinary case for markup already sitting in a document.
131
+ if (name === 'width' || name === 'height') this._applySizeRequest();
132
+ }
133
+
134
+ private _buildOnce() {
135
+ if (this._initialized) return;
136
+ this._initialized = true;
137
+
138
+ this._applySizeRequest();
139
+
140
+ this._contentEl = document.createElement('div');
141
+ this._contentEl.className = 'adw-window-content';
142
+
143
+ // Children are the content — the Adw.Window buildable default, and `content` is
144
+ // ALSO its name, because a `.blp` writes `content:` on the window and an authored
145
+ // tree needs the name to route it: `refuseUnknownSlots` in
146
+ // `src/shared-tree-builder.ts` throws on a slot a defined element does not
147
+ // declare, and `showcases/gtk/effect-adw-services/src/window.blp` is rooted at
148
+ // one. The content area becomes the host's own child, so a child appended later
149
+ // lands in it too (`bindSlottedChildren` is LIVE, see `src/slotted-children.ts`).
150
+ bindSlottedChildren(this, [{ name: 'content', into: this._contentEl }, { into: this._contentEl }]).install(
151
+ this._contentEl,
152
+ );
153
+
154
+ // Track open dialogs presented inside this window: an AdwDialog raises
155
+ // `notify::open`, which bubbles to here.
156
+ this.addEventListener('notify::open', (e) => {
157
+ const dialog = e.target as HTMLElement;
158
+ if (dialog === this) return;
159
+ if (dialog.hasAttribute('open')) {
160
+ if (!this._openDialogs.includes(dialog)) this._openDialogs.push(dialog);
161
+ } else {
162
+ this._openDialogs = this._openDialogs.filter((d) => d !== dialog);
163
+ }
164
+ });
165
+ }
166
+
167
+ /**
168
+ * Bind the breakpoints to THIS box.
169
+ *
170
+ * NOT once per lifetime: `disconnectedCallback` releases the disposer, so a
171
+ * window moved between parents would come back deaf — and a window is exactly
172
+ * the thing a client-side route change re-parents. Re-binding is cheap and
173
+ * idempotent, and it re-measures the new box on the way.
174
+ */
175
+ private _bindBreakpoints() {
176
+ this._disposeBreakpoints?.();
177
+ this._disposeBreakpoints = null;
178
+ if (this._initialized && this._breakpoints.length > 0) {
179
+ this._disposeBreakpoints = addBreakpoints(this, this._breakpoints);
180
+ }
181
+ }
182
+
183
+ /** The window's size request — GTK's, not CSS's, so an absent attribute means the default. */
184
+ private _applySizeRequest() {
185
+ const width = this.getAttribute('width');
186
+ const height = this.getAttribute('height');
187
+ this.style.width = width ? `${width}px` : `${DEFAULT_WIDTH}px`;
188
+ this.style.height = height ? `${height}px` : `${DEFAULT_HEIGHT}px`;
15
189
  }
16
190
  }
17
191
 
@@ -17,12 +17,36 @@
17
17
  // - {@link resolveCheckState} — indeterminate outranks checked, read off the cascade
18
18
  // in libadwaita's `_checks.scss`, and what `aria-checked` needs.
19
19
  //
20
- // NOT DERIVED FROM GTK. `GtkCheckButton` is a GTK widget and libadwaita has no
21
- // `adw-checkbox.c`, so its group semantics (`gtk_check_button_set_group`, whether a
22
- // fresh group starts with a member active) and the exact meaning of
23
- // `GtkCheckButton:inconsistent` are not guessed at. Where a rule was needed the HTML
24
- // one is used and cited as such — clearing `indeterminate` on activation is the HTML
25
- // pre-click activation step, not a reading of GTK.
20
+ // WHAT C SAYS, NOW THAT IT IS READABLE. `GtkCheckButton` is a GTK widget and libadwaita
21
+ // has no `adw-checkbox.c`, so everything here is read off
22
+ // `refs/gtk/gtk/gtkcheckbutton.c`:
23
+ //
24
+ // · The state attribute is `checked`, not GIR's `active` (gtkcheckbutton.c:647-658),
25
+ // and the third state is `indeterminate`, not GIR's `inconsistent` (:680-691) — the
26
+ // CSS node GTK raises is `GTK_STATE_FLAG_INCONSISTENT` (:871-880) and libadwaita
27
+ // styles `.adw-check-indicator:indeterminate`, so the browser names both states the
28
+ // way the cascade reads them.
29
+ // · `inconsistent` OUTRANKS `active`, and that is not an inference:
30
+ // `update_accessible_state` tests inconsistent first and only then active
31
+ // (:409-426). {@link resolveCheckState} is that order.
32
+ // · A grouped check button is a check button with `group` set: GTK then names the
33
+ // indicator node `radio` instead of `check` and raises
34
+ // `GTK_ACCESSIBLE_ROLE_RADIO` on BOTH members (gtkcheckbutton.c:99-108, :1115,
35
+ // :1140-1141) — which is why `<adw-radio>` is this same class with a different
36
+ // `inputType`.
37
+ // · The active member of a group cannot be clicked off: both the gesture handler and
38
+ // `real_activate` return early when the button is active AND has a group neighbour
39
+ // (:395-396, :617-622). `<adw-radio>` gets this from `RadioGroupState`, and
40
+ // `<gtk-check-button>` cannot reach a group at all here.
41
+ //
42
+ // ONE PLACE THIS PORT DIVERGES, DELIBERATELY AND CITED. GTK does NOT clear
43
+ // `inconsistent` when the user activates the button — `real_activate` only flips
44
+ // `active` (gtkcheckbutton.c:617-628) and the property's own documentation says turning
45
+ // the inconsistent state off again "has to be done manually" (:855-856). HTML's
46
+ // pre-click activation steps clear `indeterminate` before the toggle, and this element
47
+ // wraps a real `<input>`, so the clear happens for us. That is the HTML spec's rule, not
48
+ // a reading of GTK, and it is the one behaviour an application cannot observe a
49
+ // difference over: the result is a definite state either way.
26
50
  //
27
51
  // NAMING. The state attribute is `checked`, not GtkCheckButton's `active`:
28
52
  // these elements wrap a real `<input>`, `checked` is the spelling every author
@@ -53,9 +77,11 @@
53
77
  // indeterminate state announces as `mixed` for BOTH — HTML has a native mixed
54
78
  // checkbox (`input.indeterminate`) but no mixed radio.
55
79
  //
80
+ // Reference: refs/gtk/gtk/gtkcheckbutton.c:99-112,395-426,617-628,647-714,773-774,849-886,925-974
56
81
  // Reference: refs/libadwaita/src/stylesheet/widgets/_checks.scss
57
82
  // Reference: refs/adwaita-web/adwaita-web/scss/{_checkbox,_radio}.scss
58
83
  // Copyright (c) GNOME contributors (libadwaita). LGPLv2.1+.
84
+ // Copyright (c) The GTK Team. LGPLv2.1+.
59
85
  // Copyright (c) 2025 csm (adwaita-web). MIT License.
60
86
  // Modifications: Implemented as Web Components for @gjsify/adwaita-web.
61
87
 
@@ -211,8 +237,9 @@ export class GtkCheckButton extends AdwCheckBase {
211
237
 
212
238
  protected activate(): void {
213
239
  // HTML's pre-click activation steps clear `indeterminate` before the toggle, so a
214
- // user can always reach a definite state. That rule is the HTML spec's, not a
215
- // reading of `GtkCheckButton:inconsistent`.
240
+ // user can always reach a definite state. GTK does NOT: `gtk_check_button_real_activate`
241
+ // only flips `active` (gtkcheckbutton.c:617-628) and says turning the inconsistent
242
+ // state off again "has to be done manually" (:855-856). This is the HTML rule.
216
243
  this.indeterminate = false;
217
244
  this.checked = !this.checked;
218
245
  }