@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,239 @@
1
+ // <gtk-toggle-button> — a button that stays pressed. `Gtk.ToggleButton` IS a `Gtk.Button`
2
+ // with two more properties, `active` and `group`, so this element extends `<gtk-button>`
3
+ // and inherits its label, icon, child and style-class attributes unchanged; only the
4
+ // state and the mutual exclusion are new.
5
+ //
6
+ // `active` is the ATTRIBUTE, as it is on `<gtk-switch>` — `toggleAttribute` is
7
+ // idempotent, so "notify only on a real change" needs no guard and no core state class
8
+ // (ADR 0004: trivial behaviour gets none). A click, Space or Enter on the inner button
9
+ // flips it. `toggled` (GtkToggleButton's own signal) and `notify::active` (CustomEvent,
10
+ // bubbles, detail `{ active }`) fire on EVERY change, programmatic included, the way
11
+ // GObject notifies.
12
+ //
13
+ // `group` IS `gtk_toggle_button_set_group` — the doubly-linked list of
14
+ // `group_next`/`group_prev` (gtktogglebutton.c:121-122, 511-556), transcribed rather than
15
+ // approximated, because THREE of its rules are visible and none of them is "only one can
16
+ // be active":
17
+ //
18
+ // · Activating a member walks `group_prev` to the FIRST of the group and deactivates
19
+ // every member from there along `group_next`, then activates this one — the target is
20
+ // deactivated even when this button was not in that group yet (:424-437).
21
+ // · An ACTIVE member that has at least one link cannot be clicked off (:211-212), so a
22
+ // group never reaches a state with nothing pressed. `b.set_group (a)` makes B the
23
+ // member with the link, so it is B that stops being clickable-off — not A, and this
24
+ // is the rule a reader gets wrong.
25
+ // · Setting the group to the button ITSELF is refused (`g_return_if_fail
26
+ // (toggle_button != group)`, :518) and a change that would put the button directly
27
+ // before the same target again is a no-op (:539-540). Both are what keep the list
28
+ // acyclic; a cycle is undefined behaviour upstream (:503) and is left undefined here
29
+ // rather than detected.
30
+ //
31
+ // The property takes the other BUTTON, like `set_group`; the `group` ATTRIBUTE names it
32
+ // by `id`, which is the only spelling markup has for a widget reference, and it resolves
33
+ // through `document.getElementById`. It needs an `id` on the partner for that, so the
34
+ // property is the door that always works and the attribute the declarative one.
35
+ //
36
+ // `dispose` unlinks a button from its group (gtktogglebutton.c:225). The DOM has no
37
+ // terminal moment for an element that is merely re-parented, so nothing is unlinked on
38
+ // `disconnectedCallback`: the links are between the two buttons, and a row that moves
39
+ // keeps its group.
40
+ //
41
+ // The inner button wears libadwaita's `:checked` as a `.checked` class, and `aria-pressed`
42
+ // carries the same state for assistive technology.
43
+ //
44
+ // Reference: refs/gtk/gtk/gtktogglebutton.c (active, group, the clicked handler)
45
+ // Reference: refs/libadwaita/src/stylesheet/widgets/_buttons.scss (`:checked`)
46
+ // Copyright (c) GNOME contributors (libadwaita). LGPLv2.1+.
47
+ // Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
48
+
49
+ import type { DispatchedSignals } from '../signals.js';
50
+ import { GtkButton } from './gtk-button.js';
51
+
52
+ /**
53
+ * How far {@link GtkToggleButton._groupFirst} walks before it gives up. A group of real
54
+ * buttons is two or three long; the number only bounds what a cycle can cost.
55
+ */
56
+ const GROUP_WALK_LIMIT = 1024;
57
+
58
+ export class GtkToggleButton extends GtkButton {
59
+ static override readonly signals: DispatchedSignals = {
60
+ ...GtkButton.signals,
61
+ toggled: 'toggled',
62
+ 'notify::active': 'notify::active',
63
+ };
64
+
65
+ private _wired = false;
66
+ /** The other end of the group link, both halves of `GtkToggleButtonPrivate`. */
67
+ private _groupNext: GtkToggleButton | null = null;
68
+ private _groupPrev: GtkToggleButton | null = null;
69
+ /** Guards the `group` property ↔ attribute loop, as `gtk-popover` guards its `open`. */
70
+ private _reflectingGroup = false;
71
+
72
+ static get observedAttributes() {
73
+ return [...GtkButton.observedAttributes, 'active', 'group'];
74
+ }
75
+
76
+ /** Whether the button is pressed in. */
77
+ get active(): boolean {
78
+ return this.hasAttribute('active');
79
+ }
80
+
81
+ set active(value: boolean) {
82
+ const next = !!value;
83
+ if (this.active === next) return;
84
+ // Before the attribute moves, so a `toggled` listener on the member being
85
+ // released reads this one as still released — `gtk_toggle_button_set_active`
86
+ // clears the group first and sets `priv->active` after (:424-439).
87
+ if (next && this._grouped) this._clearGroup();
88
+ this.toggleAttribute('active', next);
89
+ }
90
+
91
+ /**
92
+ * `Gtk.ToggleButton:group` — the button this one joins, or `null` to leave the group.
93
+ *
94
+ * `G_PARAM_WRITABLE` upstream (:310-313), so there is deliberately NO getter: the
95
+ * member's own links are the state, and reading them back is not what GTK offers.
96
+ */
97
+ set group(value: GtkToggleButton | null) {
98
+ this._reflectingGroup = true;
99
+ // The partner needs an `id` for the attribute to name it; without one the links
100
+ // below still stand, and the attribute stays absent rather than naming nothing.
101
+ if (value === null || value.id === '') this.removeAttribute('group');
102
+ else this.setAttribute('group', value.id);
103
+ this._reflectingGroup = false;
104
+ this._setGroup(value);
105
+ }
106
+
107
+ /** Whether this button has at least one group link — `group_prev || group_next`. */
108
+ private get _grouped(): boolean {
109
+ return this._groupNext !== null || this._groupPrev !== null;
110
+ }
111
+
112
+ connectedCallback() {
113
+ super.connectedCallback();
114
+ if (this._wired) return;
115
+ this._wired = true;
116
+ // A disabled native button never emits `click`, so there is no guard to write here.
117
+ this.button.addEventListener('click', () => {
118
+ // `gtk_toggle_button_clicked` refuses to release an active member that has a
119
+ // link, so a group always keeps exactly one button pressed.
120
+ if (this.active && this._grouped) return;
121
+ this.active = !this.active;
122
+ });
123
+ // A `group` written in server-rendered markup was seen by `attributeChangedCallback`
124
+ // before this element was connected — and it may name a button that is not in the
125
+ // DOM yet. Linking once the tree is whole is the only moment both ends exist.
126
+ if (this.hasAttribute('group')) {
127
+ this._setGroup(resolveGroupTarget(this.getAttribute('group'), this));
128
+ }
129
+ }
130
+
131
+ // Optional because `GtkButton`'s own callback declares no parameter, and an override
132
+ // may not demand one the base signature does not pass.
133
+ attributeChangedCallback(name?: string) {
134
+ if (name === 'group' && !this._reflectingGroup && this.isConnected) {
135
+ this._setGroup(resolveGroupTarget(this.getAttribute('group'), this));
136
+ }
137
+ super.attributeChangedCallback();
138
+ if (name !== 'active' || !this.isConnected) return;
139
+ // The setter already cleared the group; this arm is the DECLARATIVE door, where
140
+ // the attribute moved without going through it.
141
+ if (this.active && this._grouped) this._clearGroup();
142
+ this.dispatchEvent(new CustomEvent('toggled', { bubbles: true }));
143
+ this.dispatchEvent(new CustomEvent('notify::active', { bubbles: true, detail: { active: this.active } }));
144
+ }
145
+
146
+ /**
147
+ * `gtk_toggle_button_set_group` — insert this button DIRECTLY BEFORE `group`, or
148
+ * unlink it when `group` is null. The three arms are the C's, in order.
149
+ */
150
+ private _setGroup(group: GtkToggleButton | null): void {
151
+ // `g_return_if_fail (toggle_button != group)`: a critical, and the list stays as it
152
+ // was. `console.error` is the browser's channel for "this is wrong, the page
153
+ // continues"; throwing from an attribute callback is not deliverable to the author.
154
+ if (group === this) {
155
+ console.error('<gtk-toggle-button> cannot be its own group; the group is unchanged.');
156
+ return;
157
+ }
158
+ if (group === null) {
159
+ if (this._groupPrev) this._groupPrev._groupNext = this._groupNext;
160
+ if (this._groupNext) this._groupNext._groupPrev = this._groupPrev;
161
+ this._groupNext = null;
162
+ this._groupPrev = null;
163
+ } else {
164
+ // Already directly before it — the one assignment that changes nothing, and
165
+ // the reason setting the same group twice notifies once.
166
+ if (this._groupNext === group) return;
167
+ // NOTE: no unlink from a previous group first, because the C has none
168
+ // (:542-554). `a.group = b; a.group = c;` leaves `b` linked to `a`, which is
169
+ // upstream's behaviour and is ported rather than repaired: a list that
170
+ // silently dropped the old link would make the two renderers disagree about
171
+ // what the property does.
172
+ this._groupPrev = null;
173
+ if (group._groupPrev) {
174
+ const previous = group._groupPrev;
175
+ previous._groupNext = this;
176
+ this._groupPrev = previous;
177
+ }
178
+ group._groupPrev = this;
179
+ this._groupNext = group;
180
+ }
181
+ this.dispatchEvent(new CustomEvent('notify::group', { bubbles: true }));
182
+ }
183
+
184
+ /**
185
+ * Release every OTHER member of the group — `get_group_first()` walked backwards,
186
+ * then the chain forwards, skipping this one (:426-434).
187
+ */
188
+ private _clearGroup(): void {
189
+ const first = this._groupFirst();
190
+ for (let iter: GtkToggleButton | null = first; iter !== null; iter = iter._groupNext) {
191
+ if (iter !== this) iter.active = false;
192
+ }
193
+ }
194
+
195
+ /**
196
+ * `get_group_first` (:242-262) — the walk backwards along `group_prev`.
197
+ *
198
+ * Written as recursion rather than a loop accumulator so no local ever holds `this`,
199
+ * which the walk does not need: the C's `g_assert (group_first)` is its proof that the
200
+ * walk terminates on a member, and the same proof is the `depth` guard here.
201
+ */
202
+ private _groupFirst(depth = 0): GtkToggleButton {
203
+ const previous = this._groupPrev;
204
+ // A CYCLE is undefined behaviour upstream (:503, "setting up groups in a cycle
205
+ // leads to undefined behavior") and is left that way — but a cycle must not spin
206
+ // the page, so the walk stops rather than hanging.
207
+ if (previous === null || depth > GROUP_WALK_LIMIT) return this;
208
+ return previous._groupFirst(depth + 1);
209
+ }
210
+
211
+ protected override decorate(button: HTMLButtonElement): void {
212
+ button.classList.toggle('checked', this.active);
213
+ button.setAttribute('aria-pressed', String(this.active));
214
+ }
215
+ }
216
+
217
+ customElements.define('gtk-toggle-button', GtkToggleButton);
218
+
219
+ /**
220
+ * The `group` attribute's value: the partner's id, resolved. A name that is not a
221
+ * toggle button is refused the way `set_group`'s `Gtk.IS_TOGGLE_BUTTON` precondition is,
222
+ * because linking to a non-toggle would break every walk in {@link _clearGroup}.
223
+ */
224
+ function resolveGroupTarget(id: string | null, from: GtkToggleButton): GtkToggleButton | null {
225
+ if (id === null || id === '') return null;
226
+ const target = document.getElementById(id);
227
+ if (target === null) {
228
+ console.error(`<gtk-toggle-button group="${id}"> names no element; the group is unchanged.`);
229
+ return null;
230
+ }
231
+ // The partner can sit LATER in the document than this button and so not be upgraded
232
+ // yet — `document.getElementById` finds the element without running its constructor.
233
+ if (!(target instanceof GtkToggleButton)) customElements.upgrade(target);
234
+ if (!(target instanceof GtkToggleButton) || target === from) {
235
+ console.error(`<gtk-toggle-button group="${id}"> names no other toggle button; the group is unchanged.`);
236
+ return null;
237
+ }
238
+ return target;
239
+ }
@@ -0,0 +1,243 @@
1
+ // <gtk-tree-expander> — the indent + disclosure arrow a tree row wears in front of its
2
+ // contents, the web counterpart of `Gtk.TreeExpander`.
3
+ //
4
+ // THE `Gtk.TreeListRow` IS THREE NUMBERS HERE (ADR 0089). Upstream the expander WATCHES a
5
+ // row object a `GtkTreeListModel` produced from a create-model callback — a function from
6
+ // an item to its children, called lazily, with the parent chain held by the model.
7
+ // Porting the object would mean porting that model, which is the sorting/filtering/
8
+ // virtualisation half ADR 0046 § 7 refused for the same reason. What the expander
9
+ // actually READS off the row is its depth, whether it can expand and whether it is
10
+ // expanded, so those three are the attributes — `depth`, `expandable`, `expanded` — and
11
+ // `list-row` has no attribute at all.
12
+ //
13
+ // WHAT THAT COSTS, stated rather than absorbed: upstream an expander exists BEFORE a row
14
+ // is assigned, and `gtk_tree_expander_update_for_list_row` has a whole branch for it that
15
+ // unparents every ornament. Here the row IS the attributes, so an expander carrying none
16
+ // of them is a root leaf — which is the common authored case — and there is no rowless
17
+ // state for that branch to be. `TREE_EXPANDER_LAYOUT_VECTORS` carries the row anyway,
18
+ // because the core function still answers it, and the element's own suite says which row
19
+ // it therefore cannot drive.
20
+ //
21
+ // THE NODE ARITHMETIC IS CORE'S (ADR 0004). `treeExpanderLayout` is
22
+ // `gtk_tree_expander_update_for_list_row` (gtktreeexpander.c:166-265), including the part
23
+ // that is easy to get wrong: with no expander drawn, `indent-for-icon` adds ONE to the
24
+ // depth so a leaf lines up with its expandable siblings' content, and the accessible
25
+ // level is computed AFTER that increment. `treeExpanderAction` is the shortcut table from
26
+ // the same file.
27
+ //
28
+ // THE CHILD STAYS IN THE LIGHT DOM, so a `.blp`'s `child` property, a slot assignment and
29
+ // plain markup are all the same thing: the indents and the expander are INSERTED BEFORE
30
+ // it, exactly as `gtk_widget_insert_before (…, self->child)` does, and are removed again
31
+ // when the row says they are not needed.
32
+ //
33
+ // Attributes:
34
+ // hide-expander — boolean; `Gtk.TreeExpander:hide-expander`.
35
+ // indent-for-depth — the GIR default is TRUE, so this is the OFF switch: the attribute
36
+ // is read as `indent-for-depth="false"`, not as a bare flag.
37
+ // indent-for-icon — the same, and the same default.
38
+ // depth — the row's depth, 0 at the root (`gtk_tree_list_row_get_depth`).
39
+ // expandable — boolean; `gtk_tree_list_row_is_expandable`.
40
+ // expanded — boolean; `Gtk.TreeListRow:expanded`.
41
+ // Properties: hideExpander, indentForDepth, indentForIcon, depth, expandable, expanded.
42
+ // Events: `notify::expanded` (CustomEvent, bubbles, detail = { expanded }) — every change,
43
+ // programmatic included, which is what `Gtk.TreeListRow` notifies.
44
+ // A11Y: `role="button"` with `aria-expanded` and `aria-level`, which is what GTK has used
45
+ // since 4.12 (gtktreeexpander.c:246-266); before that it was `group`.
46
+ //
47
+ // Reference: refs/gtk/gtk/gtktreeexpander.c:166-265 (the node arithmetic)
48
+ // Reference: refs/gtk/gtk/gtktreeexpander.c:654-691 (the shortcuts), :709-734 (drag-hover)
49
+ // Reference: refs/libadwaita/src/stylesheet/widgets/_expanders.scss:1-10 (the expander node)
50
+ // Reference: refs/libadwaita/src/stylesheet/widgets/_column-view.scss:128-130 (border-spacing)
51
+ // Copyright (c) GNOME contributors (GTK/libadwaita). LGPLv2.1+.
52
+ // Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
53
+
54
+ import {
55
+ treeExpanderAction,
56
+ treeExpanderExpanded,
57
+ treeExpanderLayout,
58
+ type AdwTreeExpanderLayout,
59
+ } from '@gjsify/adwaita-core';
60
+
61
+ import { createGtkImage } from './gtk-image.js';
62
+
63
+ /** `TIMEOUT_EXPAND` — how long a drag hovers before the row opens (gtktreeexpander.c:717). */
64
+ const TIMEOUT_EXPAND = 500;
65
+
66
+ export class GtkTreeExpander extends HTMLElement {
67
+ private _ornaments: HTMLElement[] = [];
68
+ private _expandTimer: ReturnType<typeof setTimeout> | null = null;
69
+ private _initialized = false;
70
+
71
+ static get observedAttributes() {
72
+ return ['hide-expander', 'indent-for-depth', 'indent-for-icon', 'depth', 'expandable', 'expanded'];
73
+ }
74
+
75
+ get hideExpander(): boolean {
76
+ return this.hasAttribute('hide-expander');
77
+ }
78
+
79
+ set hideExpander(value: boolean) {
80
+ this.toggleAttribute('hide-expander', !!value);
81
+ }
82
+
83
+ /** Default TRUE (gtktreeexpander.c:750), so only the literal `false` turns it off. */
84
+ get indentForDepth(): boolean {
85
+ return this.getAttribute('indent-for-depth') !== 'false';
86
+ }
87
+
88
+ set indentForDepth(value: boolean) {
89
+ this.setAttribute('indent-for-depth', String(!!value));
90
+ }
91
+
92
+ /** Default TRUE (gtktreeexpander.c:749), read the same way as `indent-for-depth`. */
93
+ get indentForIcon(): boolean {
94
+ return this.getAttribute('indent-for-icon') !== 'false';
95
+ }
96
+
97
+ set indentForIcon(value: boolean) {
98
+ this.setAttribute('indent-for-icon', String(!!value));
99
+ }
100
+
101
+ /** The row's depth — 0 at the root, as `gtk_tree_list_row_get_depth` reports it. */
102
+ get depth(): number {
103
+ const parsed = Number.parseInt(this.getAttribute('depth') ?? '', 10);
104
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
105
+ }
106
+
107
+ set depth(value: number) {
108
+ this.setAttribute('depth', String(value));
109
+ }
110
+
111
+ get expandable(): boolean {
112
+ return this.hasAttribute('expandable');
113
+ }
114
+
115
+ set expandable(value: boolean) {
116
+ this.toggleAttribute('expandable', !!value);
117
+ }
118
+
119
+ get expanded(): boolean {
120
+ return this.hasAttribute('expanded');
121
+ }
122
+
123
+ set expanded(value: boolean) {
124
+ this.toggleAttribute('expanded', !!value);
125
+ }
126
+
127
+ /** What this expander draws, as counts — `treeExpanderLayout`'s answer for it. */
128
+ get layout(): AdwTreeExpanderLayout {
129
+ return treeExpanderLayout(
130
+ { depth: this.depth, expandable: this.expandable, expanded: this.expanded },
131
+ {
132
+ hideExpander: this.hideExpander,
133
+ indentForDepth: this.indentForDepth,
134
+ indentForIcon: this.indentForIcon,
135
+ },
136
+ );
137
+ }
138
+
139
+ connectedCallback() {
140
+ if (!this._initialized) {
141
+ this._initialized = true;
142
+ if (!this.hasAttribute('tabindex')) this.tabIndex = 0;
143
+ this._wire();
144
+ }
145
+ this.setAttribute('role', 'button');
146
+ this._render();
147
+ }
148
+
149
+ /** The listeners, installed once — they sit on the element, so a re-parent keeps them. */
150
+ private _wire(): void {
151
+ this.addEventListener('keydown', (event) => {
152
+ const action = treeExpanderAction(event.key, {
153
+ ctrlKey: event.ctrlKey,
154
+ shiftKey: event.shiftKey,
155
+ rtl: globalThis.getComputedStyle(this).direction === 'rtl',
156
+ });
157
+ if (action === 'none') return;
158
+ event.preventDefault();
159
+ this.expanded = treeExpanderExpanded(this.expanded, action);
160
+ });
161
+
162
+ // A drag that rests over a collapsed row opens it, so a drop can reach a child
163
+ // the tree has not shown yet (gtktreeexpander.c:719-745).
164
+ this.addEventListener('dragenter', () => {
165
+ if (this.expanded || this._expandTimer !== null) return;
166
+ this._expandTimer = setTimeout(() => {
167
+ this._expandTimer = null;
168
+ this.expanded = true;
169
+ }, TIMEOUT_EXPAND);
170
+ });
171
+ for (const name of ['dragleave', 'drop']) {
172
+ this.addEventListener(name, () => this._cancelExpandTimer());
173
+ }
174
+ }
175
+
176
+ disconnectedCallback() {
177
+ // Cleanup beside creation: `gtk_tree_expander_dispose` clears the same timer, and
178
+ // a pending one here would expand a row that is no longer in the document.
179
+ this._cancelExpandTimer();
180
+ }
181
+
182
+ attributeChangedCallback(name?: string) {
183
+ if (!this._initialized) return;
184
+ this._render();
185
+ if (name === 'expanded') {
186
+ this.dispatchEvent(
187
+ new CustomEvent('notify::expanded', { bubbles: true, detail: { expanded: this.expanded } }),
188
+ );
189
+ }
190
+ }
191
+
192
+ private _cancelExpandTimer(): void {
193
+ if (this._expandTimer === null) return;
194
+ clearTimeout(this._expandTimer);
195
+ this._expandTimer = null;
196
+ }
197
+
198
+ /**
199
+ * Rebuild the indents and the expander in front of the child.
200
+ *
201
+ * Every ornament is dropped and rebuilt rather than diffed: there are at most
202
+ * depth + 1 of them, they hold no state and no focus, and a diff over two kinds of
203
+ * node is where the leaf/expandable transition would go wrong.
204
+ */
205
+ private _render(): void {
206
+ for (const ornament of this._ornaments) ornament.remove();
207
+ this._ornaments = [];
208
+
209
+ const layout = this.layout;
210
+ const before = this.firstChild;
211
+ for (let i = 0; i < layout.indents; i++) {
212
+ const indent = document.createElement('span');
213
+ indent.className = 'adw-tree-expander-indent';
214
+ indent.setAttribute('aria-hidden', 'true');
215
+ this.insertBefore(indent, before);
216
+ this._ornaments.push(indent);
217
+ }
218
+
219
+ if (layout.expander === 'none') {
220
+ this.removeAttribute('aria-expanded');
221
+ } else {
222
+ // libadwaita's `expander` node is `pan-end-symbolic`, turning to
223
+ // `pan-down-symbolic` when `:checked` (_expanders.scss:1-10). This package's
224
+ // icon subset carries `go-next`, and `.expanded` rotates it a quarter turn —
225
+ // the substitution `<adw-expander-row>` already makes for its chevron.
226
+ const icon = createGtkImage('go-next', 'adw-tree-expander-icon');
227
+ icon.classList.toggle('expanded', layout.expander === 'expanded');
228
+ icon.addEventListener('click', (event) => {
229
+ // The gesture is on the ICON upstream, not on the whole widget: the rest
230
+ // of the row belongs to the list view's own click.
231
+ event.stopPropagation();
232
+ this.expanded = !this.expanded;
233
+ });
234
+ this.insertBefore(icon, before);
235
+ this._ornaments.push(icon);
236
+ this.setAttribute('aria-expanded', String(layout.expander === 'expanded'));
237
+ }
238
+
239
+ this.setAttribute('aria-level', String(layout.level));
240
+ }
241
+ }
242
+
243
+ customElements.define('gtk-tree-expander', GtkTreeExpander);