@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,323 @@
1
+ // <gtk-level-bar> — a filled portion of a bounded range: a password strength meter, a
2
+ // battery. It is NOT a progress bar: the value may go DOWN, and it is drawn in
3
+ // PROPORTION to an interval (`min-value`…`max-value`), not to a 0…1 fraction.
4
+ //
5
+ // CSS NODES, PORTED VERBATIM (gtklevelbar.c:99-116):
6
+ // levelbar[.discrete] ─╮
7
+ // ├── trough │
8
+ // │ ├── block.filled.level-name
9
+ // │ └── block.empty
10
+ // The `level-name` class on a filled block IS the public API for colouring a bar —
11
+ // libadwaita paints `.low` warning, `.high`/`:not(.empty)` accent and `.full` success
12
+ // off it (refs/libadwaita/src/stylesheet/widgets/_level-bar.scss:71-93), and an
13
+ // application adds its own offset to add its own class (gtklevelbar.c:59-76).
14
+ //
15
+ // WHICH CLASS, FROM THE OFFSETS. `update_level_style_classes` walks the offsets in
16
+ // ASCENDING order and stops at the first one that can name the current value
17
+ // (gtklevelbar.c:604-625): the lowest offset at or above the value wins, and the lowest
18
+ // one of all wins even when the value sits below it. Three offsets exist before any
19
+ // code runs — `low` 0.25, `high` 0.75, `full` 1.0 (gtklevelbar.c:1058-1060) — so
20
+ // `value = 0` already reads `low`, exactly as it does in GTK.
21
+ //
22
+ // HOW MANY BLOCKS. Continuous is ONE drawn level with two nodes under the trough (the
23
+ // empty one and the filled one painted on top, gtklevelbar.c:344-362); discrete is
24
+ // `MAX(1, round(max) − round(min))` drawn blocks (gtklevelbar.c:285-294) of which
25
+ // `MIN(blocks, round(value) − round(min))` are filled (gtklevelbar.c:630-633). `inverted`
26
+ // counts from the other end — it reverses which block index is filled, it does not
27
+ // reverse the DOM (gtklevelbar.c:637, 648).
28
+ //
29
+ // SETTING AN END MOVES THE VALUE. `set_min_value` pushes `value` up to the new minimum
30
+ // and `set_max_value` pushes it down to the new maximum (gtklevelbar.c:1191-1192,
31
+ // :1229-1230), and the maximum additionally CLAMPS every offset into the new interval
32
+ // (:1234, :667-682) — the minimum deliberately does not. Both are GObject property
33
+ // setters, so each fires `notify::` for the value it moved as well as its own.
34
+ //
35
+ // A11Y: `role="meter"`, which is GtkLevelBar's own accessible role
36
+ // (gtklevelbar.c:1033), with `aria-valuemin` / `aria-valuemax` / `aria-valuenow` over
37
+ // the REAL interval rather than 0…1 (gtklevelbar.c:1070-1074, :1199-1202, :1238-1241,
38
+ // :1266-1268).
39
+ //
40
+ // Events: `notify::<prop>` (CustomEvent, bubbles, detail `{ <prop>: value }`) on every
41
+ // real change, and `offset-changed` (CustomEvent, bubbles, detail `{ name }`), GtkLevelBar's
42
+ // own DETAILED signal (gtklevelbar.c:936-958, :1410) — the browser has no per-name signal
43
+ // channel, so the name rides in the detail.
44
+ //
45
+ // Reference: refs/gtk/gtk/gtklevelbar.c
46
+ // Copyright (c) The GTK Team. LGPLv2.1+.
47
+ // Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
48
+
49
+ import { normalizeBoxOrientation, type BoxOrientation } from '@gjsify/adwaita-core';
50
+
51
+ /** `GtkLevelBarMode`, spelled as the GIR's enum nicks (:1004-1008). */
52
+ type LevelBarMode = 'continuous' | 'discrete';
53
+
54
+ /** The offsets GTK installs before any application code runs (gtklevelbar.c:1058-1060). */
55
+ const DEFAULT_OFFSETS: readonly (readonly [string, number])[] = [
56
+ ['low', 0.25],
57
+ ['high', 0.75],
58
+ ['full', 1.0],
59
+ ];
60
+
61
+ /**
62
+ * The offset that names `value`, transcribed from `update_level_style_classes`
63
+ * (gtklevelbar.c:604-625): ascending, first offset at or above the value wins, and an
64
+ * offset whose PREDECESSOR is not below the value names nothing — the walk continues.
65
+ * Keeping the `previous < value` test rather than simplifying it away is the point:
66
+ * two offsets sharing a value make the two spellings disagree, and only one is C.
67
+ */
68
+ function levelClassFor(offsets: readonly (readonly [string, number])[], value: number): string | null {
69
+ for (let i = 0; i < offsets.length; i++) {
70
+ const [name, threshold] = offsets[i];
71
+ if (value > threshold) continue;
72
+ const previous = i === 0 ? null : offsets[i - 1][1];
73
+ if (previous === null || previous < value) return name;
74
+ }
75
+ return null;
76
+ }
77
+
78
+ /** A missing or unparseable attribute is `fallback`, which is also the GIR default. */
79
+ function numberAttribute(element: HTMLElement, name: string, fallback: number): number {
80
+ const raw = Number.parseFloat(element.getAttribute(name) ?? '');
81
+ return Number.isFinite(raw) ? raw : fallback;
82
+ }
83
+
84
+ export class GtkLevelBar extends HTMLElement {
85
+ private _trough!: HTMLSpanElement;
86
+ private _initialized = false;
87
+ /** Offset name → value, kept sorted ascending exactly as the C's `GList` is. */
88
+ private _offsets: (readonly [string, number])[] = DEFAULT_OFFSETS.map((entry) => [...entry] as const);
89
+
90
+ static get observedAttributes() {
91
+ return ['value', 'min-value', 'max-value', 'mode', 'inverted', 'orientation', 'disabled'];
92
+ }
93
+
94
+ /** `Gtk.LevelBar:value` — the filled level. */
95
+ get value(): number {
96
+ return numberAttribute(this, 'value', 0);
97
+ }
98
+
99
+ set value(v: number) {
100
+ this._write('value', String(v));
101
+ }
102
+
103
+ /** `Gtk.LevelBar:min-value` — the low end of the interval. Defaults to 0. */
104
+ get minValue(): number {
105
+ return numberAttribute(this, 'min-value', 0);
106
+ }
107
+
108
+ set minValue(v: number) {
109
+ this._write('min-value', String(v));
110
+ }
111
+
112
+ /** `Gtk.LevelBar:max-value` — the high end of the interval. Defaults to 1. */
113
+ get maxValue(): number {
114
+ return numberAttribute(this, 'max-value', 1);
115
+ }
116
+
117
+ set maxValue(v: number) {
118
+ this._write('max-value', String(v));
119
+ }
120
+
121
+ /** `Gtk.LevelBar:mode` — one filled block, or one per unit of the interval. */
122
+ get mode(): LevelBarMode {
123
+ return this.getAttribute('mode') === 'discrete' ? 'discrete' : 'continuous';
124
+ }
125
+
126
+ set mode(v: LevelBarMode) {
127
+ this._write('mode', v);
128
+ }
129
+
130
+ /** `Gtk.LevelBar:inverted` — grow from the far end. */
131
+ get inverted(): boolean {
132
+ return this.hasAttribute('inverted');
133
+ }
134
+
135
+ set inverted(v: boolean) {
136
+ this.toggleAttribute('inverted', !!v);
137
+ }
138
+
139
+ /** `GtkOrientable:orientation` (gtklevelbar.c:825-835). Horizontal fills rightwards. */
140
+ get orientation(): BoxOrientation {
141
+ return normalizeBoxOrientation(this.getAttribute('orientation'));
142
+ }
143
+
144
+ set orientation(v: BoxOrientation) {
145
+ this._write('orientation', v);
146
+ }
147
+
148
+ /**
149
+ * `setAttribute` runs the custom-element reaction for a write that changes nothing,
150
+ * while every GObject setter here returns early when the value is already right
151
+ * (gtklevelbar.c:1186-1187, :1224-1225, :1300-1301, :1260-1261). This is the guard
152
+ * that makes "notify only on a real change" true for the numeric and enum half.
153
+ */
154
+ private _write(name: string, value: string): void {
155
+ if (this.getAttribute(name) !== value) this.setAttribute(name, value);
156
+ }
157
+
158
+ get disabled(): boolean {
159
+ return this.hasAttribute('disabled');
160
+ }
161
+
162
+ set disabled(v: boolean) {
163
+ this.toggleAttribute('disabled', !!v);
164
+ }
165
+
166
+ /**
167
+ * `gtk_level_bar_add_offset_value` (gtklevelbar.c:1395-1411): replaces the value of
168
+ * an offset of the same name, keeps the list sorted, refuses a value outside the
169
+ * interval (`g_return_if_fail (gtk_level_bar_value_in_interval (…))`, :1403), and
170
+ * emits `offset-changed` — but only when the value actually moved (:259-260).
171
+ */
172
+ addOffsetValue(name: string, value: number): void {
173
+ if (value < this.minValue || value > this.maxValue) return;
174
+ const existing = this._offsets.findIndex(([key]) => key === name);
175
+ if (existing !== -1 && this._offsets[existing][1] === value) return;
176
+ if (existing !== -1) this._offsets.splice(existing, 1);
177
+ this._offsets.push([name, value]);
178
+ this._offsets.sort((a, b) => a[1] - b[1]);
179
+ this._render();
180
+ this.dispatchEvent(new CustomEvent('offset-changed', { bubbles: true, detail: { name } }));
181
+ }
182
+
183
+ /** `gtk_level_bar_remove_offset_value` (gtklevelbar.c:1362-1377). */
184
+ removeOffsetValue(name: string): void {
185
+ const existing = this._offsets.findIndex(([key]) => key === name);
186
+ if (existing === -1) return;
187
+ this._offsets.splice(existing, 1);
188
+ this._render();
189
+ }
190
+
191
+ /** `gtk_level_bar_get_offset_value` (gtklevelbar.c:1423-1443) — `null` when absent. */
192
+ offsetValue(name: string): number | null {
193
+ return this._offsets.find(([key]) => key === name)?.[1] ?? null;
194
+ }
195
+
196
+ connectedCallback() {
197
+ if (this._initialized) {
198
+ this._render();
199
+ return;
200
+ }
201
+ this._initialized = true;
202
+
203
+ this._trough = document.createElement('span');
204
+ this._trough.className = 'adw-level-bar-trough';
205
+ this.replaceChildren(this._trough);
206
+
207
+ this.setAttribute('role', 'meter');
208
+ this._render();
209
+ }
210
+
211
+ attributeChangedCallback(name: string) {
212
+ if (!this._initialized || name === 'disabled') return;
213
+ // A NEW interval endpoint drags the value with it (gtklevelbar.c:1191-1192,
214
+ // :1229-1230); writing the clamped value back re-enters here as a `value` change,
215
+ // so the value notifies first and the endpoint second — the C's order, where
216
+ // `set_value_internal` runs before the endpoint's own `g_object_notify_by_pspec`
217
+ // (:1164 before :1204, :1243). `set_max_value` clamps the OFFSETS as well, and on
218
+ // both paths.
219
+ if (name === 'min-value' && this.value < this.minValue) {
220
+ this._write('value', String(this.minValue));
221
+ this._notify(name);
222
+ return;
223
+ }
224
+ if (name === 'max-value') {
225
+ this._clampOffsets();
226
+ if (this.value > this.maxValue) {
227
+ this._write('value', String(this.maxValue));
228
+ this._notify(name);
229
+ return;
230
+ }
231
+ }
232
+ this._render();
233
+ this._notify(name);
234
+ }
235
+
236
+ private _notify(name: string): void {
237
+ this.dispatchEvent(
238
+ new CustomEvent(`notify::${name}`, { bubbles: true, detail: { [name]: this._property(name) } }),
239
+ );
240
+ }
241
+
242
+ /** One interval endpoint CLAMPS every offset into the new range — the other does not. */
243
+ private _clampOffsets(): void {
244
+ for (let i = 0; i < this._offsets.length; i++) {
245
+ const [name, value] = this._offsets[i];
246
+ if (value < this.minValue) this._offsets[i] = [name, this.minValue];
247
+ else if (value > this.maxValue) this._offsets[i] = [name, this.maxValue];
248
+ }
249
+ }
250
+
251
+ /** The `notify::` detail for `name`: the PROPERTY, parsed, not the raw attribute. */
252
+ private _property(name: string): string | number | boolean {
253
+ switch (name) {
254
+ case 'value':
255
+ return this.value;
256
+ case 'min-value':
257
+ return this.minValue;
258
+ case 'max-value':
259
+ return this.maxValue;
260
+ case 'mode':
261
+ return this.mode;
262
+ case 'inverted':
263
+ return this.inverted;
264
+ default:
265
+ return this.orientation;
266
+ }
267
+ }
268
+
269
+ private _render(): void {
270
+ if (!this._trough) return;
271
+ const discrete = this.mode === 'discrete';
272
+ const vertical = this.orientation === 'vertical';
273
+ // `update_mode_style_classes` puts exactly one of the two on the node
274
+ // (gtklevelbar.c:574-590), and libadwaita's `levelbar.horizontal` /
275
+ // `levelbar.vertical` selectors are what read them.
276
+ this.classList.toggle('continuous', !discrete);
277
+ this.classList.toggle('discrete', discrete);
278
+ this.classList.toggle('vertical', vertical);
279
+ this.classList.toggle('horizontal', !vertical);
280
+
281
+ const min = this.minValue;
282
+ const max = this.maxValue;
283
+ const value = this.value;
284
+ // `gtk_level_bar_get_num_blocks` (gtklevelbar.c:285-294) — the node count is one
285
+ // MORE than the block count in continuous mode: the empty level is its own node.
286
+ const blocks = discrete ? Math.max(1, Math.round(max) - Math.round(min)) : 1;
287
+ const level = levelClassFor(this._offsets, value);
288
+
289
+ this._trough.replaceChildren();
290
+ if (!discrete) {
291
+ // The empty level is allocated full size and the filled one painted over it
292
+ // (gtklevelbar.c:344-362); at value 0 the filled node is never allocated at
293
+ // all (:429-430), which is what `hidden` stands for here.
294
+ const empty = this._block('empty', null);
295
+ const filled = this._block('filled', level);
296
+ filled.style.setProperty('--level-fraction', String(max > min ? (value - min) / (max - min) : 0));
297
+ filled.hidden = value === 0;
298
+ this._trough.append(empty, filled);
299
+ } else {
300
+ const count = Math.min(blocks, Math.max(0, Math.round(value) - Math.round(min)));
301
+ for (let i = 0; i < blocks; i++) {
302
+ // `inverted` fills from the far end by reversing the INDEX, so the first
303
+ // DOM block is filled last (gtklevelbar.c:637, 648).
304
+ const isFilled = this.inverted ? i >= blocks - count : i < count;
305
+ this._trough.append(this._block(isFilled ? 'filled' : 'empty', isFilled ? level : null));
306
+ }
307
+ }
308
+
309
+ this.setAttribute('aria-valuemin', String(min));
310
+ this.setAttribute('aria-valuemax', String(max));
311
+ this.setAttribute('aria-valuenow', String(value));
312
+ }
313
+
314
+ /** One `block` node, `filled` or `empty`, wearing the offset's class (:635-652). */
315
+ private _block(state: 'filled' | 'empty', level: string | null): HTMLSpanElement {
316
+ const block = document.createElement('span');
317
+ block.className = `adw-level-bar-block ${state}`;
318
+ if (state === 'filled' && level) block.classList.add(level);
319
+ return block;
320
+ }
321
+ }
322
+
323
+ customElements.define('gtk-level-bar', GtkLevelBar);
@@ -0,0 +1,138 @@
1
+ // <gtk-link-button> — a button that follows a URI. `Gtk.LinkButton` IS a `Gtk.Button`
2
+ // with two properties of its own, so this element extends `<gtk-button>` and inherits
3
+ // its label, icon, child and style-class attributes unchanged; `uri` and `visited` are
4
+ // the whole of the addition.
5
+ //
6
+ // `visited` is the state a browser already knows: once a link has been followed it is
7
+ // drawn in the visited colour and announces as visited. GTK reaches that through two
8
+ // state flags — `GTK_STATE_FLAG_LINK` when unvisited, `GTK_STATE_FLAG_VISITED` when
9
+ // visited (gtklinkbutton.c:359, 742-749) — and here it is one `.visited` class on the
10
+ // inner button, because the stylesheet has to be able to select on it.
11
+ //
12
+ // THE ORDER OF TWO OPERATIONS IS GTK'S, not ours. `gtk_link_button_set_uri()` ends with
13
+ // `gtk_link_button_set_visited (link_button, FALSE)` (gtklinkbutton.c:695): pointing the
14
+ // button somewhere else un-visits it, because the new target has not been seen. And
15
+ // `gtk_link_button_activate_link()` — the DEFAULT handler of `::activate-link` — sets it
16
+ // visited AFTER handing the URI to the launcher (:550). The state follows the click.
17
+ //
18
+ // `::activate-link` is a BOOLEAN-ACCUMULATOR signal: a handler returning TRUE stops the
19
+ // default handler from running (gtklinkbutton.c:216-238). The DOM spelling of "return
20
+ // TRUE" is `preventDefault()` on a cancelable event, so `activate-link` is dispatched
21
+ // cancelable and the launch happens only when nothing cancelled it.
22
+ //
23
+ // WHAT THE LAUNCH IS HERE. GTK hands the URI to the desktop's handler
24
+ // (`GtkUriLauncher`, gtklinkbutton.c:528-548), which opens it in ANOTHER application and
25
+ // leaves the button's window standing. The browser's equivalent of "another
26
+ // application" is another tab, so the URI goes to `window.open(uri, '_blank',
27
+ // 'noopener')` — deliberately not `location.assign`, which would tear the page down the
28
+ // way a desktop does not.
29
+ //
30
+ // NOT PORTED, and it is not a property: the CONTEXT MENU. `GtkLinkButton` installs
31
+ // `clipboard.copy` and `menu.popup` actions and binds Shift+F10 / Menu to them
32
+ // (gtklinkbutton.c:247-264), opening a `GtkPopoverMenu` with one entry. A browser
33
+ // already owns the context menu on a button, and taking it over would remove the
34
+ // platform's menu from every link on the page — so `::activate-link` is the whole of
35
+ // the activation surface here.
36
+ //
37
+ // A11Y: GTK's role is LINK (gtklinkbutton.c:244). A native `<button>` keeps the button
38
+ // role — a `<button role="link">` would stop being announced as pressable — and the URI
39
+ // rides along in the tooltip exactly as `gtk_link_button_query_tooltip_cb` puts it there
40
+ // when the button has no tooltip of its own and its label is not already the URI
41
+ // (:646-672).
42
+ //
43
+ // Reference: refs/gtk/gtk/gtklinkbutton.c (uri, visited, activate-link, the tooltip)
44
+ // Reference: refs/libadwaita/src/stylesheet/widgets/_links.scss (`button.link`)
45
+ // Copyright (c) GNOME contributors (libadwaita). LGPLv2.1+.
46
+ // Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
47
+
48
+ import { GtkButton } from './gtk-button.js';
49
+
50
+ export class GtkLinkButton extends GtkButton {
51
+ private _wired = false;
52
+
53
+ static get observedAttributes() {
54
+ return [...GtkButton.observedAttributes, 'uri', 'visited'];
55
+ }
56
+
57
+ /** `Gtk.LinkButton:uri` — the address this button points at. */
58
+ get uri(): string {
59
+ return this.getAttribute('uri') ?? '';
60
+ }
61
+
62
+ set uri(value: string) {
63
+ this.setAttribute('uri', value);
64
+ }
65
+
66
+ /**
67
+ * `Gtk.LinkButton:visited` — whether the link has been followed. The state flag
68
+ * GTK swaps here is what the stylesheet paints as `:visited`, and the `VISITED`
69
+ * accessibility state beside it; see the header.
70
+ */
71
+ get visited(): boolean {
72
+ return this.hasAttribute('visited');
73
+ }
74
+
75
+ set visited(value: boolean) {
76
+ this.toggleAttribute('visited', !!value);
77
+ }
78
+
79
+ connectedCallback() {
80
+ super.connectedCallback();
81
+ if (this._wired) return;
82
+ this._wired = true;
83
+ this.button.addEventListener('click', () => this._activateLink());
84
+ }
85
+
86
+ // Optional because `GtkButton`'s own callback declares no parameter, and an override
87
+ // may not demand one the base signature does not pass.
88
+ attributeChangedCallback(name?: string) {
89
+ // A new destination has not been seen: `gtk_link_button_set_uri()` unsets
90
+ // `visited` itself (gtklinkbutton.c:695), and only for `uri` — writing `visited`
91
+ // directly is the author's own state change and has to survive.
92
+ if (name === 'uri' && this.isConnected) this.visited = false;
93
+ super.attributeChangedCallback();
94
+ if (name === 'visited' && this.isConnected) {
95
+ this.dispatchEvent(
96
+ new CustomEvent('notify::visited', { bubbles: true, detail: { visited: this.visited } }),
97
+ );
98
+ }
99
+ }
100
+
101
+ /**
102
+ * `::activate-link` — cancelable, because the signal is a boolean accumulator
103
+ * (gtklinkbutton.c:216-238) and `preventDefault()` is the DOM spelling of a handler
104
+ * returning TRUE. Nothing cancelled ⇒ the default handler runs.
105
+ */
106
+ private _activateLink(): void {
107
+ const event = new CustomEvent('activate-link', { bubbles: true, cancelable: true });
108
+ this.dispatchEvent(event);
109
+ if (event.defaultPrevented) return;
110
+ const { uri } = this;
111
+ // `gtk_link_button_new()` requires a URI (`g_return_val_if_fail (uri != NULL)`),
112
+ // so a button without one is half-written and there is nothing to launch.
113
+ if (uri === '') return;
114
+ this.launch(uri);
115
+ this.visited = true;
116
+ }
117
+
118
+ /**
119
+ * The launcher call, on its own method so a caller (or a spec) can stand in for the
120
+ * window the desktop would have opened.
121
+ */
122
+ protected launch(uri: string): void {
123
+ window.open(uri, '_blank', 'noopener');
124
+ }
125
+
126
+ protected override decorate(button: HTMLButtonElement): void {
127
+ button.classList.add('link');
128
+ button.classList.toggle('visited', this.visited);
129
+ const label = (this.getAttribute('label') ?? '').trim();
130
+ const tooltip = this.getAttribute('tooltip') ?? this.getAttribute('tooltip-text');
131
+ // `query_tooltip_cb` shows the URI only when the label would not repeat it.
132
+ if (tooltip === null && label !== '' && this.uri !== '' && this.uri !== label) {
133
+ button.title = this.uri;
134
+ }
135
+ }
136
+ }
137
+
138
+ customElements.define('gtk-link-button', GtkLinkButton);
@@ -0,0 +1,195 @@
1
+ // <gtk-list-box-row> — one row of a `Gtk.ListBox`: the `activatable` / `selectable` pair and
2
+ // the child that fills it, the web counterpart of `Gtk.ListBoxRow`.
3
+ //
4
+ // BOTH PROPERTIES DEFAULT TRUE (gtklistbox.c:3961-3962), so on this element they are INVERTED
5
+ // flags and the attribute is read as `activatable="false"` — the same convention
6
+ // `<gtk-tree-expander>` uses for `indent-for-depth`, and for the same reason: a bare
7
+ // `activatable` on an element whose GIR default is TRUE would mean the opposite of what it
8
+ // reads like. The alternative — a present-means-true attribute — cannot express "true", which
9
+ // is the DEFAULT case and therefore the common one.
10
+ //
11
+ // THE `.activatable` CLASS IS NOT `activatable`. `gtk_list_box_update_row`
12
+ // (gtklistbox.c:3600-3624) sets it when the row is activatable OR when it is selectable and
13
+ // the BOX is not in `GTK_SELECTION_NONE`, and removes it otherwise. So a row in a
14
+ // `selection-mode="none"` box with `activatable="false"` carries no class, and the same row
15
+ // in a `selection-mode="single"` box does. The row therefore asks its parent, and the parent
16
+ // owns that answer for every row at once — which is what `<gtk-list-box>`'s `_syncRows`
17
+ // calls down into here for.
18
+ //
19
+ // `aria-selected` IS THE PARENT'S TOO, for the same C line: the accessible state is only
20
+ // published when `selectable && can_select`, so a row in a `none` box must NOT announce
21
+ // itself as unselected, and this element sets nothing of its own — `<gtk-list-box>` writes
22
+ // the attribute.
23
+ //
24
+ // ENTER AND SPACE ARE THE ROW'S, and the C says so twice: `attachRowActivation` is the
25
+ // module that makes a `GtkListBoxRow` a tab stop, and `gtk_list_box_row_class_init` installs
26
+ // the `activate` signal this row dispatches (gtklistbox.c:3905-3910).
27
+ //
28
+ // WHAT IS NOT HERE, and why: `action-name` / `action-target` are `g_param_spec_override`s of
29
+ // `GtkActionable` (gtklistbox.c:3946-3950), a `GAction` name and a `GVariant` target over a
30
+ // `GActionMap` — there is no map here to look a name up in, and a target is a value rather
31
+ // than a string. `get_index()` and `is_selected()` are METHODS over the box's children
32
+ // sequence and are answered from the DOM (`index`, `selected`), so a row moved by
33
+ // `insert_child_before` keeps reporting where it IS. The GIR puts `action-name` and
34
+ // `action-target` in the `GtkActionableProps` chain rather than in the row's own body, so
35
+ // `check-adwaita-element-properties` reads the row's OWN surface — which is exactly the two
36
+ // booleans this element observes, and neither has a gap entry.
37
+ //
38
+ // Reference: refs/gtk/gtk/gtklistbox.c:3307-3331 (child), :3594-3722 (activatable, selectable,
39
+ // the `.activatable` class and the accessible state), :3877-3966 (class init, the signal, the
40
+ // defaults and the css name)
41
+ // Reference: refs/libadwaita/src/stylesheet/widgets/_lists.scss:16-19, :47-95 (row)
42
+ // Copyright (c) GNOME contributors (GTK/libadwaita). LGPLv2.1+.
43
+ // Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
44
+
45
+ import { bindSlottedChildren } from '../slotted-children.js';
46
+ import { type AdwRowActivation, attachRowActivation } from './row-activation.js';
47
+
48
+ export class GtkListBoxRow extends HTMLElement {
49
+ private _contentsEl!: HTMLDivElement;
50
+ private _activation?: AdwRowActivation;
51
+ private _initialized = false;
52
+
53
+ static get observedAttributes() {
54
+ return ['activatable', 'selectable'];
55
+ }
56
+
57
+ /**
58
+ * `GtkListBoxRow:activatable` — TRUE by default (gtklistbox.c:3961), so this is the OFF
59
+ * switch and the attribute is read as `activatable="false"`.
60
+ */
61
+ get activatable(): boolean {
62
+ return this.getAttribute('activatable') !== 'false';
63
+ }
64
+
65
+ set activatable(value: boolean) {
66
+ this.setAttribute('activatable', String(!!value));
67
+ }
68
+
69
+ /**
70
+ * `GtkListBoxRow:selectable` — TRUE by default (gtklistbox.c:3962), read the same way as
71
+ * `activatable`.
72
+ */
73
+ get selectable(): boolean {
74
+ return this.getAttribute('selectable') !== 'false';
75
+ }
76
+
77
+ set selectable(value: boolean) {
78
+ this.setAttribute('selectable', String(!!value));
79
+ }
80
+
81
+ /** Where this row sits in its box, or -1 while it has no box. */
82
+ get index(): number {
83
+ return this.parentElement ? [...this.parentElement.children].indexOf(this) : -1;
84
+ }
85
+
86
+ /**
87
+ * Whether this row is selected — `gtk_list_box_row_is_selected`, answered by the parent so
88
+ * a row moved between boxes never carries a stale answer.
89
+ */
90
+ get selected(): boolean {
91
+ return this.classList.contains('selected');
92
+ }
93
+
94
+ /** `GtkListBoxRow:child`, as the light-DOM child it already is. */
95
+ get child(): Element | null {
96
+ return this._contentsEl.firstElementChild;
97
+ }
98
+
99
+ connectedCallback() {
100
+ if (this._initialized) {
101
+ // Re-entering a document: nothing here is torn down, so only the parent's derived
102
+ // state needs re-asking, and it re-asks on its own child list change.
103
+ return;
104
+ }
105
+ this._initialized = true;
106
+
107
+ this._contentsEl = document.createElement('div');
108
+ this._contentsEl.className = 'adw-list-box-row-contents';
109
+
110
+ // `child` is a WIDGET property, so it is a slot here (gtklistbox.c:3307-3331): the
111
+ // authored child lands in the same node `gtk_list_box_row_set_child` would put it in,
112
+ // and a child appended after connect lands there too.
113
+ bindSlottedChildren(this, [{ into: this._contentsEl }]).install(this._contentsEl);
114
+
115
+ // GTK declares the accessible role unconditionally (gtklistbox.c:3955), so there is
116
+ // no `selection-mode` to condition it on here.
117
+ this.setAttribute('role', 'listitem');
118
+ // `gtk_list_box_row_init` adds `.activatable` and makes the row focusable BEFORE any
119
+ // box exists (gtklistbox.c:3959-3966), because both properties default TRUE — so the
120
+ // class is already right for a row nobody has adopted yet, and it is the tab stop. The
121
+ // box NARROWS it in `syncClasses`, which is where `can_select` enters — and it also
122
+ // takes the tab stop over, see {@link claim}.
123
+ //
124
+ // A custom element's connect reactions are enqueued PARENT FIRST, so a row inside a
125
+ // box reaches this line AFTER `<gtk-list-box>` has already answered for it, with
126
+ // `can_select` already answered from `selection-mode`. Deriving the pre-adoption
127
+ // answer here would put back what the box just removed: `.activatable` on every row
128
+ // of a `selection-mode="none"` box, and — because `syncClasses` also re-derives the
129
+ // tab stop — every row back in the Tab order under `tab-behavior`, which is the
130
+ // measured defect `gtk-list-box.spec.ts`'s tab-behavior block exists to catch.
131
+ if (this._claimed) this._syncActivation();
132
+ else this.syncClasses(true);
133
+ }
134
+
135
+ /**
136
+ * Hand this row's `.activatable` class and tab stop to its box.
137
+ *
138
+ * Both are the box's to derive and neither is derivable here: `can_select` is the BOX's
139
+ * `selection-mode` (gtklistbox.c:3606-3609) and the tab stop is `GtkListBox:tab-behavior`,
140
+ * where `all` gives every activatable row its own stop and `item`/`cell` hand out a
141
+ * roving one — the split `gtk_list_box_focus` draws by walking rows between Tab presses
142
+ * only under `GTK_LIST_TAB_ALL` (gtklistbox.c:2037, :2067). The keys stay the row's:
143
+ * Enter and Space are `GtkListBoxRow`'s own (see `row-activation.ts`).
144
+ */
145
+ claim(): void {
146
+ this._claimed = true;
147
+ }
148
+
149
+ /** Give the row back to itself, for a box that no longer manages it. */
150
+ release(): void {
151
+ this._claimed = false;
152
+ // `gtk_list_box_update_row (NULL, row)` answers `can_select = FALSE` (gtklistbox.c:3606-3609),
153
+ // so what is left is the row's own `activatable` flag.
154
+ this.syncClasses(false);
155
+ }
156
+
157
+ /** What the box last said about itself; TRUE until a box narrows it. */
158
+ private _canSelect = true;
159
+
160
+ /** Set by {@link claim}. While it is set the row derives neither class nor tab stop. */
161
+ private _claimed = false;
162
+
163
+ attributeChangedCallback() {
164
+ if (!this._initialized) return;
165
+ // Both flags feed the class, so a write to either re-derives it against the box's LAST
166
+ // answer — not against a fresh default, which would resurrect the class on a row whose
167
+ // box has `selection-mode="none"`.
168
+ this.syncClasses(this._canSelect);
169
+ }
170
+
171
+ /**
172
+ * Re-derive the tab stop and the `.activatable` class.
173
+ *
174
+ * Public because the box owns the second half of the class rule — it knows
175
+ * `selection-mode`, this row does not — and calls this for every row when that changes.
176
+ */
177
+ syncClasses(canSelect: boolean): void {
178
+ this._canSelect = canSelect;
179
+ // `gtk_list_box_update_row` :3611-3615.
180
+ this.classList.toggle('activatable', this.activatable || (this.selectable && canSelect));
181
+ this._syncActivation();
182
+ }
183
+
184
+ private _syncActivation(): void {
185
+ this._activation ??= attachRowActivation({
186
+ row: this,
187
+ activatable: () => this.classList.contains('activatable'),
188
+ activate: () => this.dispatchEvent(new CustomEvent('activate', { bubbles: true })),
189
+ });
190
+ // The KEYS are installed either way; only the tab stop belongs to a claimed row.
191
+ if (!this._claimed) this._activation.sync();
192
+ }
193
+ }
194
+
195
+ customElements.define('gtk-list-box-row', GtkListBoxRow);