@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,480 @@
1
+ // <gtk-flow-box> — a wrapping grid of `<gtk-flow-box-child>` cells with GTK's four selection
2
+ // modes, the web counterpart of `Gtk.FlowBox`.
3
+ //
4
+ // THE SELECTION IS THE SAME CORE MODULE `<gtk-list-box>` USES, and that is not a
5
+ // coincidence to be lucky about: `gtk_flow_box_update_selection` (gtkflowbox.c:1077-1131) and
6
+ // `gtk_list_box_update_selection_full` (gtklistbox.c:1799-1871) are line for line the same
7
+ // function with `child` spelled `row`, down to the `browse` branch and the anchor that stays
8
+ // put on a `Shift`-extend. `listBoxSelect` and its three siblings in
9
+ // `@gjsify/adwaita-core` (ADR 0004) hold them both; a second copy here would be the drift the
10
+ // core module exists to prevent. What is NOT shared is the layout, and the whole difference
11
+ // is `orientation`.
12
+ //
13
+ // HORIZONTAL IS THE DEFAULT, and it is the one thing a reader of the GIR will get wrong:
14
+ // `gtk_flow_box_init` sets `priv->orientation = GTK_ORIENTATION_HORIZONTAL`
15
+ // (gtkflowbox.c:3981) where every `Gtk.Box` in this package answers horizontal too but
16
+ // `GtkListBase` answers VERTICAL. So this box fills ROWS first, and `orientation="vertical"`
17
+ // is the off switch.
18
+ //
19
+ // THE LAYOUT IS `flex-wrap`, which IS GTK's allocation: GTK hands each child a slot on a
20
+ // running line in the given orientation and starts a new one when the next would not fit
21
+ // (gtkflowbox.c:1640-1900), and `flex-flow: row wrap` with a per-child `max-width` of
22
+ // `100% / max-children-per-line` is that rule. `min-children-per-line` becomes the matching
23
+ // `min-width`, so a narrow viewport asks each child for a smaller share instead of overflowing
24
+ // — which is the property's own documented job ("ensures that a reasonably small height will
25
+ // be requested for the overall minimum width of the box", gtkflowbox.c:3747-3755).
26
+ // `homogeneous` is `flex: 1 1 0`, GTK's equal allotment (gtkflowbox.c:1647, :1781).
27
+ //
28
+ // THE ARROWS MOVE BY VISUAL POSITION, not by index, and that is the one place this element
29
+ // diverges from the default roving step. GTK binds Left/Right as
30
+ // `GTK_MOVEMENT_VISUAL_POSITIONS` and Up/Down as `GTK_MOVEMENT_DISPLAY_LINES`
31
+ // (gtkflowbox.c:3944-3951): against a grid those are different steps, so from the last cell of
32
+ // a full line "left" is one row up by POSITION where by index it is simply the next cell.
33
+ // Both are derived from the children's own layout boxes, which is the only place a browser has
34
+ // the geometry GTK measures.
35
+ //
36
+ // WHAT IS NOT HERE, and why nothing was lost. `set_filter_func` / `set_sort_func` are FUNCTION
37
+ // properties with no markup form. `get_child_at_index` / `get_child_at_pos` / `insert` /
38
+ // `prepend` / `remove` are METHODS over a children sequence — `insert` and `prepend` are
39
+ // reachable as markup (append the child in the position it should take), `remove` as
40
+ // `child.remove()`, and the two getters as the `children` collection and the `index` on a
41
+ // cell. `set_hadjustment` / `set_vadjustment` are the scrolled-window relationship ADR 0047
42
+ // gave a portable value for. `get_selected_children` is the `selectedChildren` getter.
43
+ //
44
+ // Reference: refs/gtk/gtk/gtkflowbox.c:750-790 (property enum), :943-1131 (selection),
45
+ // :3676-3990 (class init, properties, the key table, css name, role), :3977-4010 (the
46
+ // defaults), :4702-4800 (the public select/unselect API)
47
+ // Reference: refs/libadwaita/src/stylesheet/widgets/_views.scss:52-91 (flowbox > flowboxchild)
48
+ // Copyright (c) GNOME contributors (GTK/libadwaita). LGPLv2.1+.
49
+ // Modifications: Implemented as a Web Component for @gjsify/adwaita-web; the selection rules
50
+ // composed from @gjsify/adwaita-core.
51
+
52
+ import {
53
+ listBoxSelect,
54
+ listBoxSelectAll,
55
+ listBoxSelectRow,
56
+ listBoxUnselectAll,
57
+ listBoxUnselectRow,
58
+ normalizeBoxSelectionMode,
59
+ type AdwBoxSelectionMode,
60
+ } from '@gjsify/adwaita-core';
61
+
62
+ import type { GtkFlowBoxChild } from './gtk-flow-box-child.js';
63
+ import { attachRovingFocus } from './roving-focus.js';
64
+
65
+ // SIDE-EFFECT import, separate from the type import above for the reason
66
+ // `gtk-list-box.ts` states at its own: a combined import would be elided and take the
67
+ // registration with it.
68
+ import './gtk-flow-box-child.js';
69
+
70
+ /** `GtkFlowBox:max-children-per-line`'s default — `DEFAULT_MAX_CHILDREN_PER_LINE` (:728). */
71
+ export const ADW_FLOW_BOX_MAX_CHILDREN_PER_LINE = 7;
72
+
73
+ /** `GtkFlowBox:orientation` — HORIZONTAL by default here, unlike a `GtkListBase` (:3981). */
74
+ export type AdwFlowBoxOrientation = 'horizontal' | 'vertical';
75
+
76
+ export class GtkFlowBox extends HTMLElement {
77
+ private _children: GtkFlowBoxChild[] = [];
78
+ private _selection: number[] = [];
79
+ /** `priv->selected_child`, `-1` for the C's NULL. */
80
+ private _anchor = -1;
81
+ private _initialized = false;
82
+
83
+ static get observedAttributes() {
84
+ return [
85
+ 'selection-mode',
86
+ 'activate-on-single-click',
87
+ 'accept-unpaired-release',
88
+ 'homogeneous',
89
+ 'min-children-per-line',
90
+ 'max-children-per-line',
91
+ 'row-spacing',
92
+ 'column-spacing',
93
+ 'orientation',
94
+ ];
95
+ }
96
+
97
+ get selectionMode(): AdwBoxSelectionMode {
98
+ return normalizeBoxSelectionMode(this.getAttribute('selection-mode'));
99
+ }
100
+
101
+ set selectionMode(value: AdwBoxSelectionMode) {
102
+ this.setAttribute('selection-mode', value);
103
+ }
104
+
105
+ /** Default TRUE (gtkflowbox.c:3723), so the attribute is the OFF switch. */
106
+ get activateOnSingleClick(): boolean {
107
+ return this.getAttribute('activate-on-single-click') !== 'false';
108
+ }
109
+
110
+ set activateOnSingleClick(value: boolean) {
111
+ this.setAttribute('activate-on-single-click', String(!!value));
112
+ }
113
+
114
+ /** Default FALSE (gtkflowbox.c:3731). Read as boolean because a browser always pairs a
115
+ * click's halves somewhere; see `<gtk-list-box>`'s header for the rest. */
116
+ get acceptUnpairedRelease(): boolean {
117
+ return this.hasAttribute('accept-unpaired-release');
118
+ }
119
+
120
+ set acceptUnpairedRelease(value: boolean) {
121
+ this.toggleAttribute('accept-unpaired-release', !!value);
122
+ }
123
+
124
+ get homogeneous(): boolean {
125
+ return this.hasAttribute('homogeneous');
126
+ }
127
+
128
+ set homogeneous(value: boolean) {
129
+ this.toggleAttribute('homogeneous', !!value);
130
+ }
131
+
132
+ /** `GtkFlowBox:min-children-per-line` — 0 is the ParamSpec default (:3758). */
133
+ get minChildrenPerLine(): number {
134
+ return count(this.getAttribute('min-children-per-line'), 0);
135
+ }
136
+
137
+ set minChildrenPerLine(value: number) {
138
+ this.setAttribute('min-children-per-line', String(value));
139
+ }
140
+
141
+ /** `GtkFlowBox:max-children-per-line` — 7 is the default, and the ParamSpec's MINIMUM is 1. */
142
+ get maxChildrenPerLine(): number {
143
+ return Math.max(1, count(this.getAttribute('max-children-per-line'), ADW_FLOW_BOX_MAX_CHILDREN_PER_LINE));
144
+ }
145
+
146
+ set maxChildrenPerLine(value: number) {
147
+ this.setAttribute('max-children-per-line', String(value));
148
+ }
149
+
150
+ get rowSpacing(): number {
151
+ return count(this.getAttribute('row-spacing'), 0);
152
+ }
153
+
154
+ set rowSpacing(value: number) {
155
+ this.setAttribute('row-spacing', String(value));
156
+ }
157
+
158
+ get columnSpacing(): number {
159
+ return count(this.getAttribute('column-spacing'), 0);
160
+ }
161
+
162
+ set columnSpacing(value: number) {
163
+ this.setAttribute('column-spacing', String(value));
164
+ }
165
+
166
+ get orientation(): AdwFlowBoxOrientation {
167
+ return this.getAttribute('orientation') === 'vertical' ? 'vertical' : 'horizontal';
168
+ }
169
+
170
+ set orientation(value: AdwFlowBoxOrientation) {
171
+ this.setAttribute('orientation', value);
172
+ }
173
+
174
+ /**
175
+ * The cells, in document order — GTK's `children` sequence.
176
+ *
177
+ * NOT spelled `children`: that name is `HTMLElement.children`, an `HTMLCollection`, and
178
+ * shadowing it on an element that HAS children would break `firstElementChild` consumers
179
+ * and the DOM's own `[...el.children]` idiom everywhere else in this package.
180
+ */
181
+ get cells(): readonly GtkFlowBoxChild[] {
182
+ return this._children;
183
+ }
184
+
185
+ /** The selected positions, ascending. A method upstream (`get_selected_children`). */
186
+ get selectedChildren(): number[] {
187
+ return [...this._selection];
188
+ }
189
+
190
+ set selectedChildren(value: Iterable<number> | number | null) {
191
+ for (const position of typeof value === 'number' ? [value] : (value ?? [])) {
192
+ this.selectChild(this._children[position] ?? null);
193
+ }
194
+ }
195
+
196
+ get selectedChildElements(): GtkFlowBoxChild[] {
197
+ return this._selection.map((position) => this._children[position]).filter((child) => child !== undefined);
198
+ }
199
+
200
+ connectedCallback() {
201
+ if (this._initialized) return;
202
+ this._initialized = true;
203
+
204
+ this.addEventListener('click', (event) => this._onClick(event));
205
+ this.addEventListener('dblclick', (event) => this._onDoubleClick(event));
206
+ this.addEventListener('keydown', (event) => this._onKeyDown(event));
207
+
208
+ attachRovingFocus({
209
+ host: this,
210
+ // A FUNCTION, twice: `orientation` is a live property and it decides BOTH which
211
+ // keys move and what one of them means.
212
+ orientation: () => this.orientation,
213
+ items: () => this._children,
214
+ // `flex-flow: <orientation> wrap` lays children out in LINES along the
215
+ // orientation, so one along the line is one index.
216
+ step: (items, from, direction) => {
217
+ const to = from + direction;
218
+ return to < 0 || to >= items.length ? null : to;
219
+ },
220
+ crossAxis: {
221
+ orientation: () => (this.orientation === 'horizontal' ? 'vertical' : 'horizontal'),
222
+ // Read per press, not per install: `orientation` is a live property.
223
+ step: (items, from, direction) => visualStep(items, from, direction, this.orientation),
224
+ },
225
+ select: (child) => this._updateSelection(child as GtkFlowBoxChild, {}),
226
+ });
227
+
228
+ // A cell appended AFTER connect has to join the selection from its first frame; the
229
+ // observer watches THIS element, so there is nothing to release on disconnect
230
+ // (`slotted-children.ts` states why).
231
+ new MutationObserver(() => this._collectChildren()).observe(this, { childList: true });
232
+
233
+ this._applyAttributes();
234
+ this._collectChildren();
235
+ }
236
+
237
+ attributeChangedCallback() {
238
+ if (!this._initialized) return;
239
+ this._applyAttributes();
240
+ this._syncChildren();
241
+ }
242
+
243
+ /** `gtk_flow_box_select_child` (gtkflowbox.c:4731-4739). `null` is the C's unselect-all. */
244
+ selectChild(child: GtkFlowBoxChild | null): void {
245
+ const result = listBoxSelectRow(
246
+ this._selection,
247
+ this._anchor,
248
+ child === null ? null : this._children.indexOf(child),
249
+ this._children.length,
250
+ this.selectionMode,
251
+ );
252
+ if (same(result.selection, this._selection) && result.anchor === this._anchor) return;
253
+ this._selection = result.selection;
254
+ this._anchor = result.anchor;
255
+ this._emitSelection(child);
256
+ }
257
+
258
+ /** `gtk_flow_box_unselect_child` (gtkflowbox.c:4749-4756). */
259
+ unselectChild(child: GtkFlowBoxChild): void {
260
+ const result = listBoxUnselectRow(
261
+ this._selection,
262
+ this._anchor,
263
+ this._children.indexOf(child),
264
+ this._children.length,
265
+ this.selectionMode,
266
+ );
267
+ if (same(result.selection, this._selection)) return;
268
+ this._selection = result.selection;
269
+ this._emitSelection(null);
270
+ }
271
+
272
+ /** `gtk_flow_box_select_all` — refused unless the mode is `multiple` (:4770-4771). */
273
+ selectAll(): void {
274
+ const next = listBoxSelectAll(this._children.length, this.selectionMode);
275
+ if (next === null) return;
276
+ this._selection = next;
277
+ this._anchor = next.length > 0 ? next[0]! : -1;
278
+ this._emitSelection(this.selectedChildElements[0] ?? null);
279
+ }
280
+
281
+ /** `gtk_flow_box_unselect_all` — refused in `browse` (:4792-4793). */
282
+ unselectAll(): void {
283
+ if (listBoxUnselectAll(this._selection, this.selectionMode) === null) return;
284
+ this._selection = [];
285
+ this._anchor = -1;
286
+ this._emitSelection(null);
287
+ }
288
+
289
+ /**
290
+ * The properties, as inline custom properties, so the flex rules in `_flow_box.scss` stay
291
+ * declarative and a `homogeneous` write is one class flip.
292
+ */
293
+ private _applyAttributes(): void {
294
+ this.classList.toggle('homogeneous', this.homogeneous);
295
+ this.classList.toggle('vertical', this.orientation === 'vertical');
296
+ this.style.setProperty('--adw-flow-box-row-spacing', `${this.rowSpacing}px`);
297
+ this.style.setProperty('--adw-flow-box-column-spacing', `${this.columnSpacing}px`);
298
+ this.style.setProperty('--adw-flow-box-max-children-per-line', String(this.maxChildrenPerLine));
299
+ if (this.minChildrenPerLine > 0) {
300
+ this.style.setProperty('--adw-flow-box-min-children-per-line', String(this.minChildrenPerLine));
301
+ } else {
302
+ this.style.removeProperty('--adw-flow-box-min-children-per-line');
303
+ }
304
+ const selectable = this.selectionMode !== 'none';
305
+ // `GTK_ACCESSIBLE_ROLE_GRID` (:3973). GTK declares it unconditionally and no role
306
+ // carries the selection better in ARIA: `grid`/`gridcell` is what a wrapping grid IS,
307
+ // and the per-cell `aria-selected` is what does the announcing.
308
+ this.setAttribute('role', 'grid');
309
+ if (this.selectionMode === 'multiple') this.setAttribute('aria-multiselectable', 'true');
310
+ else this.removeAttribute('aria-multiselectable');
311
+ // `aria-readonly` is the one ARIA state `none` has and `multiple` does not, and it is
312
+ // what tells a screen reader that the cells will not take a click.
313
+ if (selectable) this.removeAttribute('aria-readonly');
314
+ else this.setAttribute('aria-readonly', 'true');
315
+ }
316
+
317
+ private _collectChildren(): void {
318
+ const next = [...this.querySelectorAll(':scope > gtk-flow-box-child')] as GtkFlowBoxChild[];
319
+ if (next.length === this._children.length && next.every((child, index) => child === this._children[index])) {
320
+ return;
321
+ }
322
+ this._children = next;
323
+ this._selection = this._selection.filter((position) => position < this._children.length);
324
+ if (this._anchor >= this._children.length) this._anchor = -1;
325
+ this._syncChildren();
326
+ }
327
+
328
+ /**
329
+ * The `GTK_STATE_FLAG_SELECTED` each selected cell raises and the accessible state that
330
+ * goes with it (`gtk_flow_box_child_set_selected`, gtkflowbox.c:943-962). The accessible
331
+ * state is published ONLY while the box can select, which is the same reset the list box
332
+ * does (:3617-3623).
333
+ */
334
+ private _syncChildren(): void {
335
+ const canSelect = this.selectionMode !== 'none';
336
+ const selection = new Set(this._selection);
337
+ this._children.forEach((child, position) => {
338
+ const isSelected = selection.has(position);
339
+ child.classList.toggle('selected', isSelected);
340
+ child.classList.toggle('activatable', canSelect);
341
+ if (canSelect) child.setAttribute('aria-selected', String(isSelected));
342
+ else child.removeAttribute('aria-selected');
343
+ });
344
+ }
345
+
346
+ private _onClick(event: MouseEvent): void {
347
+ const child = this._childAt(event.target);
348
+ if (child === null && !this.acceptUnpairedRelease) return;
349
+ if (child !== null) {
350
+ this._updateSelection(child, { modify: event.ctrlKey || event.metaKey, extend: event.shiftKey });
351
+ }
352
+ // `activate-on-single-click` defaults TRUE (gtkflowbox.c:3723), so a FIRST click
353
+ // activates, and a SECOND one when it is off; `detail` is the only thing that can tell
354
+ // them apart, which is why the threshold is the property and not a constant.
355
+ if (event.detail < (this.activateOnSingleClick ? 1 : 2)) return;
356
+ if (child !== null) this._activate(child);
357
+ }
358
+
359
+ private _onDoubleClick(event: MouseEvent): void {
360
+ if (this.activateOnSingleClick) return;
361
+ const child = this._childAt(event.target);
362
+ if (child === null) return;
363
+ this._activate(child);
364
+ }
365
+
366
+ /**
367
+ * `Ctrl`+Space is `toggle-cursor-child` (gtkflowbox.c:3957-3959); Enter and Space are the
368
+ * CELL's, via `activate-cursor-child` (:3836) and `GtkFlowBoxChild`'s own `activate`.
369
+ */
370
+ private _onKeyDown(event: KeyboardEvent): void {
371
+ if (!event.ctrlKey || event.altKey || event.metaKey || event.key !== ' ') return;
372
+ const child = this._childAt(event.target);
373
+ if (child === null) return;
374
+ event.preventDefault();
375
+ this._updateSelection(child, { modify: true });
376
+ }
377
+
378
+ private _childAt(target: EventTarget | null): GtkFlowBoxChild | null {
379
+ if (!(target instanceof Element)) return null;
380
+ const child = target.closest('gtk-flow-box-child');
381
+ return this.contains(child) ? (child as GtkFlowBoxChild) : null;
382
+ }
383
+
384
+ /** One click or `Ctrl`+Space — `gtk_flow_box_update_selection` (:1077-1131). */
385
+ private _updateSelection(child: GtkFlowBoxChild, step: { modify?: boolean; extend?: boolean }): void {
386
+ const result = listBoxSelect(
387
+ this._selection,
388
+ this._anchor,
389
+ this._children.indexOf(child),
390
+ this._children.length,
391
+ this.selectionMode,
392
+ step,
393
+ );
394
+ if (same(result.selection, this._selection)) return;
395
+ this._selection = result.selection;
396
+ this._anchor = result.anchor;
397
+ this._emitSelection(result.selection.includes(this._children.indexOf(child)) ? child : null);
398
+ }
399
+
400
+ /** `gtk_flow_box_select_and_activate` (:1136-1148) — the `child-activated` signal. */
401
+ private _activate(child: GtkFlowBoxChild): void {
402
+ this.dispatchEvent(new CustomEvent('child-activated', { bubbles: true, detail: { child } }));
403
+ child.dispatchEvent(new CustomEvent('activate', { bubbles: true }));
404
+ }
405
+
406
+ /** `child-activated`'s companion `selected-children-changed` (:3820-3826) plus the notify. */
407
+ private _emitSelection(child: GtkFlowBoxChild | null): void {
408
+ this._syncChildren();
409
+ this.dispatchEvent(new CustomEvent('selected-children-changed', { bubbles: true }));
410
+ this.dispatchEvent(new CustomEvent('child-selected', { bubbles: true, detail: { child } }));
411
+ this.dispatchEvent(
412
+ new CustomEvent('notify::selected-children', {
413
+ bubbles: true,
414
+ detail: { selectedChildren: [...this._selection] },
415
+ }),
416
+ );
417
+ }
418
+ }
419
+
420
+ /**
421
+ * `GTK_MOVEMENT_VISUAL_POSITIONS` / `GTK_MOVEMENT_DISPLAY_LINES` over a wrapped flex line
422
+ * (gtkflowbox.c:1390-1520): the neighbour in that DIRECTION, found by the children's own
423
+ * layout boxes.
424
+ *
425
+ * The line count comes from grouping the children by their offset along the wrap axis — which
426
+ * is the same thing GTK knows from its allocation, measured rather than asked for. Where the
427
+ * target line is short the step falls back to the nearest child on that line, or to the one
428
+ * along the line, exactly as the C's search does when no cell sits in that position.
429
+ */
430
+ const visualStep = (
431
+ items: readonly HTMLElement[],
432
+ from: number,
433
+ direction: -1 | 1,
434
+ orientation: AdwFlowBoxOrientation,
435
+ ): number | null => {
436
+ if (items.length < 2) return null;
437
+ const vertical = orientation === 'vertical';
438
+ // Along-line is `offsetTop` for a row-wrap box and `offsetLeft` for a column-wrap one —
439
+ // `flex-flow: <orientation> wrap` puts the NEXT child beside this one along that axis.
440
+ const alongLine = (item: HTMLElement): number => (vertical ? item.offsetLeft : item.offsetTop);
441
+ const acrossLine = (item: HTMLElement): number => (vertical ? item.offsetTop : item.offsetLeft);
442
+
443
+ const current = items[from] as HTMLElement;
444
+ const line = alongLine(current);
445
+ const position = acrossLine(current);
446
+ const wanted = direction > 0 ? line + 1 : line - 1;
447
+
448
+ let nearest: number | null = null;
449
+ let nearestDistance = Number.POSITIVE_INFINITY;
450
+ for (let index = 0; index < items.length; index++) {
451
+ const item = items[index] as HTMLElement;
452
+ if (alongLine(item) !== wanted) continue;
453
+ const distance = Math.abs(acrossLine(item) - position);
454
+ if (nearest === null || distance < nearestDistance) {
455
+ nearest = index;
456
+ nearestDistance = distance;
457
+ }
458
+ }
459
+ if (nearest !== null) return nearest;
460
+
461
+ // No cell on the line the cursor wanted — a SHORT last line, or the very first line going
462
+ // back. The C's search then falls back to walking the current line, and so does this:
463
+ // one along it, in the direction asked for.
464
+ const neighbour = from + direction;
465
+ if (neighbour < 0 || neighbour >= items.length) return null;
466
+ return alongLine(items[neighbour] as HTMLElement) === line ? neighbour : null;
467
+ };
468
+
469
+ /** Selection equality without an allocation — both arrays are sorted ascending. */
470
+ function same(next: readonly number[], current: readonly number[]): boolean {
471
+ return next.length === current.length && next.every((position, index) => position === current[index]);
472
+ }
473
+
474
+ /** A `guint` property read, with the ParamSpec's own default for an absent or broken value. */
475
+ function count(raw: string | null, fallback: number): number {
476
+ const parsed = Number.parseInt(raw ?? '', 10);
477
+ return Number.isFinite(parsed) && parsed >= 0 ? parsed : fallback;
478
+ }
479
+
480
+ customElements.define('gtk-flow-box', GtkFlowBox);