@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,748 @@
1
+ // <gtk-stack> — one visible child out of many, with an animated change between them:
2
+ // a settings panel, a wizard, an image viewer. It is the widget GtkStackSwitcher and
3
+ // GtkStackSidebar switch over, and the content half of GtkNotebook.
4
+ //
5
+ // THE CHILD IS THE PAGE. Upstream `GtkStackPage` is a GObject, not a widget
6
+ // (gtkstack.c:212-233, `struct _GtkStackPage`), so it has no element of its own: its six
7
+ // properties (gtkstack.c:499-573) are ATTRIBUTES on the child element and the page
8
+ // descriptor {@link GtkStackPageInfo} is what `getPage()` hands back. `child` — the one
9
+ // property that cannot be an attribute (gtkstack.c:501-507) — is the element itself.
10
+ // name — the child's `name` ATTRIBUTE, the id `visible-child-name` speaks
11
+ // title — `title` attribute; NULL (absent) means NO LABEL, never a fallback
12
+ // to `name`: `rebuild_child` builds no child at all when both title
13
+ // and icon-name are NULL (gtkstackswitcher.c:158-176)
14
+ // icon-name — `icon-name` attribute
15
+ // needs-attention — `needs-attention` attribute; the switcher puts a `.needs-attention`
16
+ // class on its button from it (gtkstackswitcher.c:203-206)
17
+ // use-underline — `use-underline` attribute, read by the switcher's label
18
+ // visible — NOT an attribute: the DOM's own `hidden`, which is the browser's
19
+ // spelling of GtkWidget:visible. This element reads `hidden` and
20
+ // never writes it — see the note on the render pass below.
21
+ //
22
+ // CSS NODES, PORTED VERBATIM (gtkstack.c:1067, :1564-1613):
23
+ // stack[.transitioning]
24
+ // ├── page.visible-page
25
+ // └── page.visible-page.transitioning-in / .transitioning-out
26
+ // GTK paints every non-visible child by NOT allocating it; the browser half is
27
+ // `display: none` on everything but the visible page. During a transition both pages
28
+ // exist (`last_visible_child`, gtkstack.c:1509-1519), so both are laid out and the
29
+ // transition gives each one a direction.
30
+ //
31
+ // WHICH CHILD IS VISIBLE. `set_visible_child`'s guards, in order (gtkstack.c:1428-1586):
32
+ // · a NULL child means "the FIRST VISIBLE one" (:1437-1450) — which is why hiding the
33
+ // visible page falls back rather than blanking the stack (`update_child_visible`,
34
+ // :3147-3153 calls it with NULL);
35
+ // · the page's WIDGET must be visible as well as its own `visible` flag, else nothing
36
+ // happens at all (:1591-1594, :2329-2332) — so `visible-child-name` naming a `hidden`
37
+ // child is a no-op, not a blank stack;
38
+ // · an unknown name is refused with a warning and NO change (:2323-2327), and a page
39
+ // with no name is never matched (`:info->name != NULL &&`, :2314);
40
+ // · the same page twice is not a change (:1452-1453), so no notify and no transition.
41
+ // Both `visible-child` and `visible-child-name` then notify (`:1564-1567`), in that order.
42
+ //
43
+ // TRANSITIONS. `transition-type` is one of the 23 nicks of `GtkStackTransitionType`
44
+ // (gtkstack.c:95-121); the CSS in `_stack.scss` implements each. Three decisions are C:
45
+ // · the EFFECTIVE type, from `get_effective_transition_type` (gtkstack.c:1320-1390):
46
+ // reduced motion turns every transition into a crossfade when the stack is
47
+ // homogeneous on BOTH axes and into nothing when it is not (:1324-1335), and RTL
48
+ // swaps the four left/right pairs and the two rotates (:1341-1371) while the
49
+ // two-way types are left alone (they have no direction until the next decision);
50
+ // · the DIRECTION of a two-way type, from `get_simple_transition_type` on whether the
51
+ // incoming page sits AFTER the outgoing one (`i_first`, gtkstack.c:1540-1556) — the
52
+ // browser reverses the animation instead of having a second set of keyframes;
53
+ // · a direction-dependent type with NO outgoing page (a first page shown into an empty
54
+ // stack) collapses to `none` (:1531-1535), exactly as C does.
55
+ // A transition runs only while the stack is on screen and animations are on (:1400-1401);
56
+ // `transition-duration` is the progress tracker's length (:1408-1411) and 0 means no
57
+ // animation at all (:1402-1403). `transition-running` is READ-ONLY and is reflected, so
58
+ // the stylesheet can key off it — C notifies it from the tick callback, once at the end
59
+ // (gtkstack.c:1284) and once when the ticks are unscheduled (:1314).
60
+ //
61
+ // HOMOGENEOUS. `gtk_stack_measure` measures ONLY the visible child on an axis the stack
62
+ // is homogeneous on, and the MAX over the rest otherwise (gtkstack.c:2899-2905); the
63
+ // browser analogue is the visible page filling the stack on a homogeneous axis and
64
+ // taking its own width on the other (see `_stack.scss`).
65
+ //
66
+ // A11Y: `role="group"`, GtkStack's own accessible role (gtkstack.c:1068), and the
67
+ // non-visible pages carry `aria-hidden="true"` — `gtk_accessible_update_state
68
+ // (…, GTK_ACCESSIBLE_STATE_HIDDEN, …)` on the PAGE (gtkstack.c:1526-1532, :1543-1547,
69
+ // :1610-1613).
70
+ //
71
+ // Events: `notify::<prop>` (CustomEvent, bubbles, detail `{ <prop>: value }`) on every
72
+ // real change; `items-changed` and `selection-changed` (bubbles, detail
73
+ // `{ position, removed, added }` / `{ position, nItems }`) are the `pages` model of
74
+ // gtkstack.c:698-745 speaking as DOM events instead of as a GtkSelectionModel;
75
+ // `page-updated` (bubbles, detail `{ child }`) is GtkStackPage's own `notify`, which
76
+ // `on_page_updated` binds a switcher to (gtkstackswitcher.c:311-321); `transition-start`
77
+ // (detail `{ duration }`) and `transition-end` are the widget's two signals
78
+ // (gtkstack.c:1420, :1587).
79
+ //
80
+ // NOT PORTED, and why — properties an attribute cannot carry, not behaviour left out:
81
+ // · `visible-child` (gtkstack.c:1005-1012) takes a Gtk.Widget, and the browser has no
82
+ // widget values; `visible-child-name` (:1014-1021) is the same selection by name and
83
+ // IS implemented. `visibleChild` returns the child ELEMENT for the same selection.
84
+ // · `pages` (:1055-1060) is a GtkSelectionModel; the browser half is `pages` (the page
85
+ // descriptors), `items-changed`, `selection-changed` and `isSelected()`.
86
+ // · `GtkStackPage:child` (gtkstack.c:501-507) is construct-only and is the child node.
87
+ // · `gtk_stack_set_visible_child_full` (:2306-2334) takes a per-call transition; the
88
+ // browser half is `setVisibleChild(child, transitionType?)`.
89
+ //
90
+ // Reference: refs/gtk/gtk/gtkstack.c
91
+ // Copyright (c) The GTK Team. LGPLv2.1+.
92
+ // Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
93
+
94
+ /** `GtkStackTransitionType`, spelled as the GIR's enum nicks (gtkstack.c:95-121). */
95
+ export type StackTransitionType =
96
+ | 'none'
97
+ | 'crossfade'
98
+ | 'slide-right'
99
+ | 'slide-left'
100
+ | 'slide-up'
101
+ | 'slide-down'
102
+ | 'slide-left-right'
103
+ | 'slide-up-down'
104
+ | 'over-up'
105
+ | 'over-down'
106
+ | 'over-left'
107
+ | 'over-right'
108
+ | 'under-up'
109
+ | 'under-down'
110
+ | 'under-left'
111
+ | 'under-right'
112
+ | 'over-up-down'
113
+ | 'over-down-up'
114
+ | 'over-left-right'
115
+ | 'over-right-left'
116
+ | 'rotate-left'
117
+ | 'rotate-right'
118
+ | 'rotate-left-right';
119
+
120
+ const TRANSITION_TYPES: readonly string[] = [
121
+ 'none',
122
+ 'crossfade',
123
+ 'slide-right',
124
+ 'slide-left',
125
+ 'slide-up',
126
+ 'slide-down',
127
+ 'slide-left-right',
128
+ 'slide-up-down',
129
+ 'over-up',
130
+ 'over-down',
131
+ 'over-left',
132
+ 'over-right',
133
+ 'under-up',
134
+ 'under-down',
135
+ 'under-left',
136
+ 'under-right',
137
+ 'over-up-down',
138
+ 'over-down-up',
139
+ 'over-left-right',
140
+ 'over-right-left',
141
+ 'rotate-left',
142
+ 'rotate-right',
143
+ 'rotate-left-right',
144
+ ];
145
+
146
+ /**
147
+ * The types whose direction depends on WHERE the incoming page sits (gtkstack.c:1539-1556):
148
+ * `get_simple_transition_type` resolves them to the one-directional type before the
149
+ * animation starts. `slide-left-right`, `slide-up-down`, `over-*-*` and `rotate-left-right`.
150
+ */
151
+ const DIRECTION_DEPENDENT = new Set([
152
+ 'slide-left-right',
153
+ 'slide-up-down',
154
+ 'over-up-down',
155
+ 'over-down-up',
156
+ 'over-left-right',
157
+ 'over-right-left',
158
+ 'rotate-left-right',
159
+ ]);
160
+
161
+ /**
162
+ * The RTL swaps of `get_effective_transition_type` (gtkstack.c:1341-1371): four pairs,
163
+ * and nothing else — the two-way types fall through `default:` unchanged, because they
164
+ * have no direction until `get_simple_transition_type` gives them one.
165
+ */
166
+ const RTL_SWAP: Readonly<Record<string, StackTransitionType>> = {
167
+ 'slide-left': 'slide-right',
168
+ 'slide-right': 'slide-left',
169
+ 'rotate-left': 'rotate-right',
170
+ 'rotate-right': 'rotate-left',
171
+ 'over-left': 'over-right',
172
+ 'over-right': 'over-left',
173
+ 'under-left': 'under-right',
174
+ 'under-right': 'under-left',
175
+ };
176
+
177
+ /**
178
+ * `get_simple_transition_type` (gtkstack.c:1162-1200), transcribed pair by pair. The
179
+ * result is one of the ONE-DIRECTIONAL types, so the stylesheet needs one rule each and
180
+ * no direction attribute of its own.
181
+ */
182
+ function simpleTransitionType(newChildFirst: boolean, type: StackTransitionType): StackTransitionType {
183
+ switch (type) {
184
+ case 'slide-left-right':
185
+ return newChildFirst ? 'slide-right' : 'slide-left';
186
+ case 'rotate-left-right':
187
+ return newChildFirst ? 'rotate-right' : 'rotate-left';
188
+ case 'slide-up-down':
189
+ return newChildFirst ? 'slide-down' : 'slide-up';
190
+ // The two-way OVER types resolve to UNDER when the new page comes first: the page
191
+ // that moves is the one already on screen in either case.
192
+ case 'over-up-down':
193
+ return newChildFirst ? 'under-down' : 'over-up';
194
+ case 'over-down-up':
195
+ return newChildFirst ? 'under-up' : 'over-down';
196
+ case 'over-left-right':
197
+ return newChildFirst ? 'under-right' : 'over-left';
198
+ case 'over-right-left':
199
+ return newChildFirst ? 'under-left' : 'over-right';
200
+ default:
201
+ return type;
202
+ }
203
+ }
204
+
205
+ /** The browser's page descriptor — the stand-in for the `GtkStackPage` GObject. */
206
+ export interface GtkStackPageInfo {
207
+ /** `GtkStackPage:name`, `''` for a page with no `name` attribute. */
208
+ name: string;
209
+ /** `GtkStackPage:title` — `null` when absent, which is C's NULL and means NO label. */
210
+ title: string | null;
211
+ /** `GtkStackPage:icon-name` — `null` when absent. */
212
+ iconName: string | null;
213
+ /** `GtkStackPage:needs-attention`. */
214
+ needsAttention: boolean;
215
+ /** `GtkStackPage:use-underline`. */
216
+ useUnderline: boolean;
217
+ /** `GtkStackPage:visible` AND `GtkWidget:visible` — the child's `hidden` attribute. */
218
+ visible: boolean;
219
+ /** `GtkStackPage:child`: the page's own node. */
220
+ child: HTMLElement;
221
+ }
222
+
223
+ /** The five `GtkStackPage` string/boolean properties this element reads off a child. */
224
+ const PAGE_ATTRIBUTES = ['name', 'title', 'icon-name', 'use-underline', 'needs-attention'];
225
+
226
+ export class GtkStack extends HTMLElement {
227
+ /** The child that is visible, or `null` — C's `priv->visible_child`. */
228
+ private _visible: HTMLElement | null = null;
229
+ /** C's `priv->last_visible_child`: the page being animated away. */
230
+ private _lastVisible: HTMLElement | null = null;
231
+ private _initialized = false;
232
+ private _initializedChildren = new WeakSet<HTMLElement>();
233
+ private _observer: MutationObserver | null = null;
234
+ private _timer: ReturnType<typeof setTimeout> | null = null;
235
+ private _running = false;
236
+
237
+ static get observedAttributes() {
238
+ return [
239
+ 'visible-child-name',
240
+ 'transition-type',
241
+ 'transition-duration',
242
+ 'hhomogeneous',
243
+ 'vhomogeneous',
244
+ 'interpolate-size',
245
+ ];
246
+ }
247
+
248
+ /** `Gtk.Stack:visible-child-name` — the name of the visible child. */
249
+ get visibleChildName(): string | null {
250
+ return this.getAttribute('visible-child-name');
251
+ }
252
+
253
+ set visibleChildName(v: string | null) {
254
+ this._write('visible-child-name', v);
255
+ }
256
+
257
+ /**
258
+ * `Gtk.Stack:visible-child` as the browser can spell it: the visible child ELEMENT
259
+ * (the C property takes a `Gtk.Widget`, which no attribute can carry). Writes go
260
+ * through the child's own `name`, so it is `visible-child-name` that is read back.
261
+ */
262
+ get visibleChild(): HTMLElement | null {
263
+ return this._visible;
264
+ }
265
+
266
+ set visibleChild(child: HTMLElement | null) {
267
+ this.setVisibleChild(child);
268
+ }
269
+
270
+ /** `Gtk.Stack:transition-type`. An unknown nick reads as `none`, the GIR default. */
271
+ get transitionType(): StackTransitionType {
272
+ const raw = this.getAttribute('transition-type');
273
+ return raw !== null && TRANSITION_TYPES.includes(raw) ? (raw as StackTransitionType) : 'none';
274
+ }
275
+
276
+ set transitionType(v: StackTransitionType) {
277
+ this._write('transition-type', v);
278
+ }
279
+
280
+ /** `Gtk.Stack:transition-duration` in milliseconds. `0` disables the animation. */
281
+ get transitionDuration(): number {
282
+ return this._duration();
283
+ }
284
+
285
+ set transitionDuration(v: number) {
286
+ this._write('transition-duration', String(v));
287
+ }
288
+
289
+ /**
290
+ * `Gtk.Stack:hhomogeneous` — the same width for every child. Defaults to TRUE
291
+ * (gtkstack.c:981-987), which is why this one is NOT a boolean attribute: an absent
292
+ * attribute already means true, so the spelling has to be able to say false.
293
+ */
294
+ get hhomogeneous(): boolean {
295
+ return this._flag('hhomogeneous', true);
296
+ }
297
+
298
+ set hhomogeneous(v: boolean) {
299
+ this._write('hhomogeneous', v ? '' : 'false');
300
+ }
301
+
302
+ /** `Gtk.Stack:vhomogeneous` — the same height for every child. Defaults to TRUE. */
303
+ get vhomogeneous(): boolean {
304
+ return this._flag('vhomogeneous', true);
305
+ }
306
+
307
+ set vhomogeneous(v: boolean) {
308
+ this._write('vhomogeneous', v ? '' : 'false');
309
+ }
310
+
311
+ /** `Gtk.Stack:interpolate-size` — let the size change smoothly too. */
312
+ get interpolateSize(): boolean {
313
+ return this.hasAttribute('interpolate-size');
314
+ }
315
+
316
+ set interpolateSize(v: boolean) {
317
+ this.toggleAttribute('interpolate-size', !!v);
318
+ }
319
+
320
+ /** `Gtk.Stack:transition-running` — READ-ONLY; reflected for the stylesheet. */
321
+ get transitionRunning(): boolean {
322
+ return this.hasAttribute('transition-running');
323
+ }
324
+
325
+ /**
326
+ * `Gtk.Stack:pages` — the page descriptors in child order, the browser half of the
327
+ * `GtkStackPages` selection model (gtkstack.c:698-745).
328
+ */
329
+ get pages(): GtkStackPageInfo[] {
330
+ return this._children().map((child) => this._page(child));
331
+ }
332
+
333
+ /** `gtk_stack_get_child_by_name` (gtkstack.c:1889-1916), `null` when not found. */
334
+ getChildByName(name: string): HTMLElement | null {
335
+ return this._children().find((child) => this._page(child).name === name) ?? null;
336
+ }
337
+
338
+ /** `gtk_stack_get_page` (gtkstack.c:1870-1887) as a descriptor, `null` when absent. */
339
+ getPage(child: HTMLElement): GtkStackPageInfo | null {
340
+ return this._children().includes(child) ? this._page(child) : null;
341
+ }
342
+
343
+ /** `gtk_stack_pages_is_selected` (gtkstack.c:647-666) for the model this element is. */
344
+ isSelected(child: HTMLElement): boolean {
345
+ return this._visible === child;
346
+ }
347
+
348
+ /** `gtk_stack_add_titled` (gtkstack.c:1644-1663) — append a named, titled child. */
349
+ addTitled(child: HTMLElement, name: string | null, title?: string | null): HTMLElement {
350
+ if (name !== null) child.setAttribute('name', name);
351
+ if (title !== undefined && title !== null) child.setAttribute('title', title);
352
+ return this.addChild(child);
353
+ }
354
+
355
+ /** `gtk_stack_add_named` (gtkstack.c:1687-1696). */
356
+ addNamed(child: HTMLElement, name: string | null): HTMLElement {
357
+ return this.addTitled(child, name);
358
+ }
359
+
360
+ /** `gtk_stack_add_child` (gtkstack.c:1665-1685) — the unnamed form. */
361
+ addChild(child: HTMLElement): HTMLElement {
362
+ this.appendChild(child);
363
+ this._initChild(child);
364
+ // `gtk_stack_add_page`'s tail (gtkstack.c:1773-1775): a page added while NOTHING
365
+ // is visible becomes the visible one. C reads the widget's own visibility; on the
366
+ // browser the child is not `hidden` yet, unless the author said so.
367
+ if (this._initialized && !this._visible && !child.hasAttribute('hidden')) this._show(child);
368
+ return child;
369
+ }
370
+
371
+ /**
372
+ * `gtk_stack_remove` (gtkstack.c:1834-1868), named `removePage` because
373
+ * `HTMLElement.remove()` already occupies the short spelling — the same rename
374
+ * `Adw.ViewStack.remove` took in `adw-view-stack.ts`.
375
+ */
376
+ removePage(child: HTMLElement): void {
377
+ child.remove();
378
+ }
379
+
380
+ /**
381
+ * `gtk_stack_set_visible_child` (gtkstack.c:2244-2281), with `gtk_stack_set_visible_
382
+ * child_full`'s per-call transition (gtkstack.c:2306-2334). A child that is not in
383
+ * this stack, or whose page is not visible, changes nothing — C warns and returns.
384
+ */
385
+ setVisibleChild(child: HTMLElement | null, transitionType?: StackTransitionType): boolean {
386
+ if (!child) {
387
+ // `set_visible_child (stack, NULL)` is the first-visible scan (gtkstack.c:1437).
388
+ return this._show(this._firstVisible(), transitionType);
389
+ }
390
+ if (!this._children().includes(child)) return false;
391
+ return this._show(child, transitionType);
392
+ }
393
+
394
+ /** `gtk_stack_set_visible_child_name` (gtkstack.c:2283-2304). */
395
+ setVisibleChildName(name: string | null): boolean {
396
+ if (name === null) return false;
397
+ const child = this._children().find((page) => this._page(page).name === name);
398
+ // An unknown name is refused with NO change (gtkstack.c:2323-2327); a page with no
399
+ // name is never matched at all (`:info->name != NULL &&`, :2314).
400
+ if (!child) return false;
401
+ return this._show(child);
402
+ }
403
+
404
+ connectedCallback() {
405
+ if (this._initialized) {
406
+ this._render();
407
+ return;
408
+ }
409
+ this._initialized = true;
410
+ this.setAttribute('role', 'group');
411
+ for (const child of this._children()) this._initChild(child);
412
+ // `add_page` connects the stack to each page's `notify::visible`
413
+ // (gtkstack.c:1771), which is the browser's mutation observer.
414
+ this._observer = new MutationObserver((records) => this._onChildMutations(records));
415
+ this._observer.observe(this, {
416
+ childList: true,
417
+ subtree: true,
418
+ attributes: true,
419
+ attributeFilter: [...PAGE_ATTRIBUTES, 'hidden'],
420
+ });
421
+ // Adding the FIRST visible page makes it the visible one (gtkstack.c:1773-1775).
422
+ if (!this._visible) this._show(this._firstVisible());
423
+ this._render();
424
+ }
425
+
426
+ disconnectedCallback() {
427
+ this._observer?.disconnect();
428
+ this._observer = null;
429
+ if (this._timer !== null) clearTimeout(this._timer);
430
+ this._timer = null;
431
+ // The observer is re-created in the guarded branch of `connectedCallback`, and a
432
+ // re-parent runs it again with `_initialized` already set — so dropping the flag
433
+ // here is what makes the second connect take that branch rather than the build
434
+ // branch. The same shape `adw-source-view` uses.
435
+ this._initialized = false;
436
+ }
437
+
438
+ attributeChangedCallback(name: string) {
439
+ if (!this._initialized) return;
440
+ if (name === 'visible-child-name') {
441
+ this.setVisibleChildName(this.getAttribute('visible-child-name'));
442
+ return;
443
+ }
444
+ this._render();
445
+ this._notify(name);
446
+ }
447
+
448
+ /**
449
+ * The `notify::` detail for `name`: the PROPERTY, parsed, not the raw attribute —
450
+ * `transition-type` in particular reads as `none` for an unknown nick.
451
+ */
452
+ private _property(name: string): string | number | boolean | null {
453
+ switch (name) {
454
+ case 'transition-type':
455
+ return this.transitionType;
456
+ case 'transition-duration':
457
+ return this.transitionDuration;
458
+ case 'hhomogeneous':
459
+ return this.hhomogeneous;
460
+ case 'vhomogeneous':
461
+ return this.vhomogeneous;
462
+ case 'interpolate-size':
463
+ return this.interpolateSize;
464
+ default:
465
+ return this.visibleChildName;
466
+ }
467
+ }
468
+
469
+ private _notify(name: string): void {
470
+ this.dispatchEvent(
471
+ new CustomEvent(`notify::${name}`, { bubbles: true, detail: { [name]: this._property(name) } }),
472
+ );
473
+ }
474
+
475
+ private _write(name: string, value: string | null): void {
476
+ if (value === null) this.removeAttribute(name);
477
+ else if (this.getAttribute(name) !== value) this.setAttribute(name, value);
478
+ }
479
+
480
+ /** A boolean property that DEFAULTS TO TRUE: absent means true, like C's spec. */
481
+ private _flag(name: string, fallback: boolean): boolean {
482
+ const raw = this.getAttribute(name);
483
+ if (raw === null) return fallback;
484
+ return raw !== 'false';
485
+ }
486
+
487
+ /**
488
+ * `Gtk.Stack:transition-duration`, the `g_param_spec_uint` default of 200
489
+ * (gtkstack.c:1024). An unparseable or negative value is the uint clamp to 0 that
490
+ * the property's own range produces (gtkstack.c:1051-1060), and 0 is what stops the
491
+ * transition from starting at all (gtkstack.c:1402-1403).
492
+ */
493
+ private _duration(): number {
494
+ const raw = this.getAttribute('transition-duration');
495
+ if (raw === null) return 200;
496
+ const parsed = Number.parseInt(raw, 10);
497
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
498
+ }
499
+
500
+ /** The pages, in child order — `priv->children`, never the shadow root. */
501
+ private _children(): HTMLElement[] {
502
+ return Array.from(this.children) as HTMLElement[];
503
+ }
504
+
505
+ /** The page descriptor of one child (gtkstack.c:499-573). */
506
+ private _page(child: HTMLElement): GtkStackPageInfo {
507
+ return {
508
+ name: child.getAttribute('name') ?? '',
509
+ title: child.getAttribute('title'),
510
+ iconName: child.getAttribute('icon-name'),
511
+ useUnderline: child.hasAttribute('use-underline'),
512
+ needsAttention: child.hasAttribute('needs-attention'),
513
+ // `hidden` is the browser's GtkWidget:visible, and `GtkStackPage:visible` is
514
+ // the SAME state here (update_child_visible's `page->visible && widget
515
+ // visible`, gtkstack.c:3145) — so the attribute is the whole of it.
516
+ visible: !child.hasAttribute('hidden'),
517
+ child,
518
+ };
519
+ }
520
+
521
+ /** `set_visible_child`'s "pick first visible" scan (gtkstack.c:1437-1450). */
522
+ private _firstVisible(): HTMLElement | null {
523
+ return this._children().find((child) => this._page(child).visible) ?? null;
524
+ }
525
+
526
+ private _initChild(child: HTMLElement): void {
527
+ if (this._initializedChildren.has(child)) return;
528
+ this._initializedChildren.add(child);
529
+ child.classList.add('adw-stack-page');
530
+ }
531
+
532
+ private _onChildMutations(records: MutationRecord[]): void {
533
+ let added = 0;
534
+ let removed = 0;
535
+ let position = -1;
536
+ let pageUpdated = false;
537
+ for (const record of records) {
538
+ if (record.type === 'childList') {
539
+ for (const node of Array.from(record.removedNodes)) {
540
+ if (node === this._visible) this._visible = null;
541
+ if (node === this._lastVisible) this._lastVisible = null;
542
+ removed += 1;
543
+ }
544
+ for (const node of Array.from(record.addedNodes)) {
545
+ if (!(node instanceof HTMLElement)) continue;
546
+ this._initChild(node);
547
+ added += 1;
548
+ if (position === -1) position = this._children().indexOf(node);
549
+ }
550
+ continue;
551
+ }
552
+ const name = record.attributeName;
553
+ if (!name) continue;
554
+ if (name === 'hidden') {
555
+ // `stack_child_visibility_notify_cb` (gtkstack.c:1617-1633) re-runs
556
+ // `update_child_visible`: hiding the visible page falls back to the first
557
+ // visible one (which is what the NULL means, :1437-1450), and showing one
558
+ // while none is visible picks it up (:3147-3149).
559
+ this._show(this._firstVisible());
560
+ continue;
561
+ }
562
+ if (PAGE_ATTRIBUTES.includes(name)) pageUpdated = true;
563
+ }
564
+ if (removed > 0 || added > 0) {
565
+ this.dispatchEvent(
566
+ new CustomEvent('items-changed', {
567
+ bubbles: true,
568
+ detail: { position: position === -1 ? this._children().length : position, removed, added },
569
+ }),
570
+ );
571
+ }
572
+ if (pageUpdated) {
573
+ for (const record of records) {
574
+ if (record.type !== 'attributes') continue;
575
+ const target = record.target as HTMLElement;
576
+ this.dispatchEvent(new CustomEvent('page-updated', { bubbles: true, detail: { child: target } }));
577
+ // `gtk_stack_page_set_name` re-notifies `visible-child-name` when the
578
+ // renamed page IS the visible one (gtkstack.c:3169-3171) — the selection
579
+ // did not move, but the name it is addressed by did.
580
+ if (target === this._visible && record.attributeName === 'name') {
581
+ this._write('visible-child-name', this._nameOrNull(this._page(target).name));
582
+ this.dispatchEvent(
583
+ new CustomEvent('notify::visible-child-name', {
584
+ bubbles: true,
585
+ detail: { 'visible-child-name': this.visibleChildName },
586
+ }),
587
+ );
588
+ }
589
+ }
590
+ this._render();
591
+ }
592
+ }
593
+
594
+ /** C's NULL page name is an ABSENT attribute, not the empty string (gtkstack.c:2216). */
595
+ private _nameOrNull(name: string): string | null {
596
+ return name === '' ? null : name;
597
+ }
598
+
599
+ /**
600
+ * `set_visible_child` (gtkstack.c:1428-1586) reduced to what a browser can decide,
601
+ * with the guards kept in C's order. Returns whether the visible child changed.
602
+ */
603
+ private _show(child: HTMLElement | null, transitionType?: StackTransitionType): boolean {
604
+ if (!child) return false;
605
+ const page = this._page(child);
606
+ // The page's WIDGET must be visible, else C does nothing at all (gtkstack.c:1591).
607
+ if (!page.visible) return false;
608
+ if (this._visible === child) return false;
609
+
610
+ const previous = this._visible;
611
+ this._visible = child;
612
+ // The name of the page the selection is BY, kept on the element so a switcher and
613
+ // the host agree without re-walking the children (gtkstack.c:2216-2224).
614
+ this._write('visible-child-name', this._nameOrNull(page.name));
615
+ this._lastVisible = previous;
616
+ this._render();
617
+
618
+ // Both properties notify, visible-child FIRST (gtkstack.c:1564-1567).
619
+ this.dispatchEvent(
620
+ new CustomEvent('notify::visible-child', { bubbles: true, detail: { 'visible-child': child } }),
621
+ );
622
+ this.dispatchEvent(
623
+ new CustomEvent('notify::visible-child-name', {
624
+ bubbles: true,
625
+ detail: { 'visible-child-name': this.visibleChildName },
626
+ }),
627
+ );
628
+ if (previous) {
629
+ const position = Math.min(this._children().indexOf(previous), this._children().indexOf(child));
630
+ this.dispatchEvent(
631
+ new CustomEvent('selection-changed', { bubbles: true, detail: { position, nItems: 2 } }),
632
+ );
633
+ } else {
634
+ this.dispatchEvent(
635
+ new CustomEvent('selection-changed', {
636
+ bubbles: true,
637
+ detail: { position: this._children().indexOf(child), nItems: 1 },
638
+ }),
639
+ );
640
+ }
641
+
642
+ this._startTransition(previous, transitionType ?? this.transitionType);
643
+ return true;
644
+ }
645
+
646
+ /**
647
+ * `gtk_stack_start_transition` (gtkstack.c:1389-1426) with
648
+ * `get_effective_transition_type` (gtkstack.c:1320-1390) and, for a two-way type,
649
+ * `get_simple_transition_type` on the page ORDER (gtkstack.c:1539-1561,
650
+ * :1162-1200). The result is always a SIMPLE type, which is what the stylesheet
651
+ * keys on — C resolves the two-way pair into one of the one-directional types
652
+ * before the animation starts, and so does this.
653
+ */
654
+ private _startTransition(outgoing: HTMLElement | null, requested: StackTransitionType): void {
655
+ if (this._timer !== null) {
656
+ clearTimeout(this._timer);
657
+ this._timer = null;
658
+ }
659
+ let type = this._effectiveType(requested);
660
+ // A direction-dependent type with NO outgoing page collapses to none
661
+ // (gtkstack.c:1541-1545).
662
+ if (DIRECTION_DEPENDENT.has(type) && !outgoing) type = 'none';
663
+ else if (DIRECTION_DEPENDENT.has(type) && outgoing) {
664
+ type = simpleTransitionType(this._newChildFirst(outgoing), type);
665
+ }
666
+ // `transition_duration != 0` is one half of the branch that starts the tracker at
667
+ // all (gtkstack.c:1402-1403), so a zero duration is as still as `none` — the
668
+ // other half is `effective_transition_type != NONE`.
669
+ if (type === 'none' || !outgoing || this._duration() === 0) {
670
+ this._running = false;
671
+ this.removeAttribute('transition-running');
672
+ this.classList.remove('transitioning');
673
+ this._lastVisible = null;
674
+ this._render();
675
+ return;
676
+ }
677
+ this.dataset.transitionType = type;
678
+ this._running = true;
679
+ this.setAttribute('transition-running', '');
680
+ this.classList.add('transitioning');
681
+ this._render();
682
+ this.dispatchEvent(
683
+ new CustomEvent('transition-start', { bubbles: true, detail: { duration: this._duration() } }),
684
+ );
685
+ this._timer = setTimeout(() => {
686
+ this._timer = null;
687
+ this._running = false;
688
+ this.removeAttribute('transition-running');
689
+ this.classList.remove('transitioning');
690
+ delete this.dataset.transitionType;
691
+ this._lastVisible = null;
692
+ this._render();
693
+ this.dispatchEvent(new CustomEvent('transition-end', { bubbles: true }));
694
+ }, this._duration());
695
+ }
696
+
697
+ /**
698
+ * `i_first` (gtkstack.c:1548-1557): whether the incoming page was ADDED EARLIER than
699
+ * the outgoing one. C walks the children from the start and breaks on whichever it
700
+ * meets first, so the answer is a comparison of positions.
701
+ */
702
+ private _newChildFirst(outgoing: HTMLElement): boolean {
703
+ const children = this._children();
704
+ return children.indexOf(this._visible as HTMLElement) < children.indexOf(outgoing);
705
+ }
706
+
707
+ /** `get_effective_transition_type` (gtkstack.c:1320-1390): reduced motion, then RTL. */
708
+ private _effectiveType(requested: StackTransitionType): StackTransitionType {
709
+ let type = requested;
710
+ if (type !== 'none') {
711
+ if (this._reducedMotion()) {
712
+ // Homogeneous on BOTH axes keeps a crossfade; otherwise there is nothing
713
+ // to animate (gtkstack.c:1327-1334).
714
+ type = this.hhomogeneous && this.vhomogeneous ? 'crossfade' : 'none';
715
+ } else if (this.getAttribute('dir') === 'rtl') {
716
+ type = RTL_SWAP[type] ?? type;
717
+ }
718
+ }
719
+ return type;
720
+ }
721
+
722
+ /** `gtk_widget_get_settings`'s `gtk-interface-reduced-motion`, read from the media query. */
723
+ private _reducedMotion(): boolean {
724
+ return typeof matchMedia === 'function' && matchMedia('(prefers-reduced-motion: reduce)').matches;
725
+ }
726
+
727
+ /**
728
+ * The render pass: which page is visible, which is animating out, and the two
729
+ * `aria-hidden` states GTK raises on the PAGES (gtkstack.c:1526-1532, :1543-1547,
730
+ * :1610-1613). `hidden` is never written — it is the author's own
731
+ * `GtkStackPage:visible`, and overwriting it would destroy the distinction C keeps
732
+ * between the page flag and the widget's own visibility.
733
+ */
734
+ private _render(): void {
735
+ if (!this._initialized) return;
736
+ for (const child of this._children()) {
737
+ const visible = child === this._visible;
738
+ child.classList.toggle('visible-page', visible);
739
+ child.classList.toggle('transitioning-in', visible && this._running);
740
+ child.classList.toggle('transitioning-out', !visible && child === this._lastVisible && this._running);
741
+ if (visible) child.removeAttribute('aria-hidden');
742
+ else child.setAttribute('aria-hidden', 'true');
743
+ }
744
+ this.style.setProperty('--stack-transition-duration', `${this._duration()}ms`);
745
+ }
746
+ }
747
+
748
+ customElements.define('gtk-stack', GtkStack);