@gjsify/adwaita-web 0.54.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 (439) hide show
  1. package/dist/adwaita-web.css +8066 -3033
  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 +1 -1
  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/style-classes.spec.ts +9 -8
  436. package/src/styles.generated.ts +1 -1
  437. package/src/tab-chip.ts +200 -0
  438. package/src/template-classes.ts +45 -0
  439. package/src/test.browser.mts +152 -0
@@ -0,0 +1,158 @@
1
+ // DOM-level tests for <gtk-window-handle>: the three titlebar gestures and what they raise.
2
+ // The gestures are the whole widget — it has one property, a `child` slot, and no box of its
3
+ // own — so what is asserted here is the ACTIONS, in the vocabulary
4
+ // `perform_titlebar_action_fallback` uses when a compositor has no opinion.
5
+ import { describe, expect, it } from '@gjsify/unit';
6
+
7
+ import type { GtkWindowHandle } from './elements/gtk-window-handle.js';
8
+
9
+ function mount(): { el: GtkWindowHandle; host: HTMLElement } {
10
+ const host = document.createElement('div');
11
+ host.style.width = '400px';
12
+ host.style.height = '40px';
13
+ document.body.appendChild(host);
14
+ const el = document.createElement('gtk-window-handle') as GtkWindowHandle;
15
+ el.style.display = 'contents';
16
+ const title = document.createElement('gtk-label');
17
+ title.setAttribute('label', 'Untitled');
18
+ el.appendChild(title);
19
+ host.appendChild(el);
20
+ return { el, host };
21
+ }
22
+
23
+ /** Every `event` name dispatched on `el`, with its `detail`. */
24
+ function record(el: HTMLElement, ...events: string[]): Map<string, unknown[]> {
25
+ const seen = new Map<string, unknown[]>();
26
+ for (const name of events) {
27
+ const details: unknown[] = [];
28
+ seen.set(name, details);
29
+ el.addEventListener(name, (e) => details.push((e as CustomEvent).detail));
30
+ }
31
+ return seen;
32
+ }
33
+
34
+ const click = (el: HTMLElement, init: MouseEventInit = {}): void => {
35
+ el.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, ...init }));
36
+ };
37
+
38
+ const pointer = (el: HTMLElement, type: string, init: PointerEventInit = {}): void => {
39
+ el.dispatchEvent(new PointerEvent(type, { bubbles: true, cancelable: true, ...init }));
40
+ };
41
+
42
+ export const GtkWindowHandleTest = async () => {
43
+ await describe('<gtk-window-handle> the titlebar actions', async () => {
44
+ await it('is a generic role and contributes no box of its own', async () => {
45
+ const { el, host } = mount();
46
+ expect(el.getAttribute('role')).toBe('generic');
47
+ // `display: contents` IS `GtkBinLayout`'s "the child takes the whole
48
+ // allocation", and what makes a handle usable as a titlebar strip.
49
+ expect(getComputedStyle(el).display).toBe('contents');
50
+ host.remove();
51
+ });
52
+
53
+ await it('turns a DOUBLE CLICK into toggle-maximize, and a single click into nothing', async () => {
54
+ const { el, host } = mount();
55
+ const seen = record(el, 'titlebar-action', 'window.toggle-maximized');
56
+ click(el, { button: 0, detail: 1 });
57
+ expect(seen.get('titlebar-action')?.length).toBe(0);
58
+ click(el, { button: 0, detail: 2 });
59
+ expect(seen.get('titlebar-action')?.length).toBe(1);
60
+ expect(seen.get('window.toggle-maximized')?.length).toBe(1);
61
+ const detail = seen.get('titlebar-action')?.[0] as {
62
+ action: string;
63
+ gesture: string;
64
+ windowAction: string;
65
+ };
66
+ expect(detail.action).toBe('toggle-maximize');
67
+ expect(detail.gesture).toBe('double-click');
68
+ expect(detail.windowAction).toBe('window.toggle-maximized');
69
+ host.remove();
70
+ });
71
+
72
+ await it('turns a right click into the window menu, as its setting says', async () => {
73
+ const { el, host } = mount();
74
+ const seen = record(el, 'window.menu', 'window-move');
75
+ click(el, { button: 2 });
76
+ expect(seen.get('window.menu')?.length).toBe(1);
77
+ host.remove();
78
+ });
79
+
80
+ await it('reads each gesture off its OWN setting default, and refuses a value GTK does not know', async () => {
81
+ const { el, host } = mount();
82
+ // The three pspecs are not the same (gtksettings.c:868-896): a middle click does
83
+ // NOTHING by default, which is the whole point of there being three settings.
84
+ expect(el.actionFor('double-click')).toBe('toggle-maximize');
85
+ expect(el.actionFor('middle-click')).toBe('none');
86
+ expect(el.actionFor('right-click')).toBe('menu');
87
+ el.setAttribute('double-click-action', 'minimize');
88
+ expect(el.actionFor('double-click')).toBe('minimize');
89
+ const seen = record(el, 'window.minimize');
90
+ click(el, { button: 0, detail: 2 });
91
+ expect(seen.get('window.minimize')?.length).toBe(1);
92
+ // An unknown value is `none`, which is the C's own refusal branch — a typo must
93
+ // not minimize a window.
94
+ el.setAttribute('double-click-action', 'minimise');
95
+ expect(el.actionFor('double-click')).toBe('none');
96
+ const none = record(el, 'window.minimize');
97
+ click(el, { button: 0, detail: 2 });
98
+ expect(none.get('window.minimize')?.length).toBe(0);
99
+ // A maximization VARIANT maximizes: `perform_titlebar_action_fallback` matches
100
+ // `toggle-maximize` by prefix, "treat all maximization variants the same"
101
+ // (gtkwindowhandle.c:311-315).
102
+ el.setAttribute('double-click-action', 'toggle-maximize-fullscreen');
103
+ expect(el.actionFor('double-click')).toBe('toggle-maximize');
104
+ host.remove();
105
+ });
106
+
107
+ await it('reports `none` on titlebar-action all the same, which is the gesture itself', async () => {
108
+ const { el, host } = mount();
109
+ const seen = record(el, 'titlebar-action', 'window.menu');
110
+ // A middle click, which is `none` by default (gtksettings.c:881-883) — the gesture
111
+ // still happened, so it is still reported, and nothing else fires.
112
+ click(el, { button: 1 });
113
+ expect(seen.get('titlebar-action')?.length).toBe(1);
114
+ expect(seen.get('window.menu')?.length).toBe(0);
115
+ // Taken apart before the property is read: `(x?.[0] as T).gesture` would throw
116
+ // a TypeError instead of failing the assertion if the array were empty.
117
+ const middle = seen.get('titlebar-action')?.[0] as { gesture: string } | undefined;
118
+ expect(middle?.gesture).toBe('middle-click');
119
+ el.setAttribute('right-click-action', 'none');
120
+ const right = record(el, 'titlebar-action', 'window.menu');
121
+ click(el, { button: 2 });
122
+ expect(right.get('titlebar-action')?.length).toBe(1);
123
+ expect(right.get('window.menu')?.length).toBe(0);
124
+ host.remove();
125
+ });
126
+ });
127
+
128
+ await describe('<gtk-window-handle> the drag', async () => {
129
+ await it('raises window-move once the pointer passes the drag threshold', async () => {
130
+ const { el, host } = mount();
131
+ const seen = record(el, 'window-move');
132
+ pointer(el, 'pointerdown', { pointerId: 1, clientX: 10, clientY: 20 });
133
+ // Under the threshold nothing has happened, which is `gtk_drag_check_threshold_double`.
134
+ pointer(el, 'pointermove', { pointerId: 1, clientX: 10, clientY: 21 });
135
+ expect(seen.get('window-move')?.length).toBe(0);
136
+ pointer(el, 'pointermove', { pointerId: 1, clientX: 60, clientY: 20 });
137
+ expect(seen.get('window-move')?.length).toBe(1);
138
+ // The sequence is reset afterwards, so the gesture does not repeat.
139
+ pointer(el, 'pointermove', { pointerId: 1, clientX: 90, clientY: 20 });
140
+ expect(seen.get('window-move')?.length).toBe(1);
141
+ host.remove();
142
+ });
143
+
144
+ await it('denies the drag once a multi-click has claimed the sequence', async () => {
145
+ const { el, host } = mount();
146
+ const seen = record(el, 'window-move');
147
+ pointer(el, 'pointerdown', { pointerId: 1, clientX: 10, clientY: 20 });
148
+ pointer(el, 'pointerdown', { pointerId: 1, clientX: 10, clientY: 20 });
149
+ // The second press of a double click: the click gesture claims the sequence and
150
+ // `gtk_event_controller_reset` denies the drag with it (gtkwindowhandle.c:400-406),
151
+ // which is where a browser knows the press count.
152
+ click(el, { button: 0, detail: 2 });
153
+ pointer(el, 'pointermove', { pointerId: 1, clientX: 90, clientY: 20 });
154
+ expect(seen.get('window-move')?.length).toBe(0);
155
+ host.remove();
156
+ });
157
+ });
158
+ };
@@ -0,0 +1,190 @@
1
+ // DOM-level tests for <gtk-window>. A window in a page is a FRAME, and this file holds that
2
+ // honest: the two shapes its titlebar strip can be in (the application's `titlebar` slot, or
3
+ // the server-side decoration a page has to draw for itself), the four properties that decide
4
+ // which frame buttons appear, and the two branches of `gtk_window_close`
5
+ // (gtkwindow.c:1274-1287).
6
+ import { describe, expect, it } from '@gjsify/unit';
7
+
8
+ import type { GtkWindow } from './elements/gtk-window.js';
9
+
10
+ function mount(attrs: Record<string, string> = {}): { el: GtkWindow; host: HTMLElement } {
11
+ const host = document.createElement('div');
12
+ document.body.appendChild(host);
13
+ const el = document.createElement('gtk-window') as GtkWindow;
14
+ for (const [name, value] of Object.entries(attrs)) el.setAttribute(name, value);
15
+ host.appendChild(el);
16
+ return { el, host };
17
+ }
18
+
19
+ function content(el: GtkWindow): HTMLElement {
20
+ return el.querySelector('.adw-gtk-window-content') as HTMLElement;
21
+ }
22
+
23
+ function titlebar(el: GtkWindow): HTMLElement {
24
+ return el.querySelector('.adw-gtk-window-titlebar') as HTMLElement;
25
+ }
26
+
27
+ export const GtkWindowTest = async () => {
28
+ await describe('<gtk-window> structure', async () => {
29
+ await it('is a titlebar strip over a content box', async () => {
30
+ // The two strips `connectedCallback` installs, in `strips()` order.
31
+ const { el, host } = mount();
32
+ expect([...el.children].map((node) => node.className)).toStrictEqual([
33
+ 'adw-gtk-window-titlebar',
34
+ 'adw-gtk-window-content',
35
+ ]);
36
+ expect(titlebar(el).hidden).toBe(false);
37
+ host.remove();
38
+ });
39
+
40
+ await it('routes every unslotted child into the content box, in document order', async () => {
41
+ const { el, host } = mount();
42
+ const first = document.createElement('span');
43
+ first.textContent = 'a';
44
+ const second = document.createElement('span');
45
+ second.textContent = 'b';
46
+ el.append(first, second);
47
+ await Promise.resolve();
48
+ expect([...content(el).children]).toStrictEqual([first, second]);
49
+ host.remove();
50
+ });
51
+
52
+ await it('a `titlebar` child takes the whole strip, decorations and all', async () => {
53
+ // GTK hands the titlebar the window's decorations; a `Gtk.HeaderBar` brings its
54
+ // own window controls with it.
55
+ const { el, host } = mount();
56
+ const bar = document.createElement('gtk-header-bar');
57
+ // `titlebar` is a PROPERTY on Gtk.Window (gtkwindow.c:1138) and the buildable's
58
+ // single child is something else, so the slot name is how the markup spells it.
59
+ bar.setAttribute('slot', 'titlebar');
60
+ el.appendChild(bar);
61
+ await Promise.resolve();
62
+ await Promise.resolve();
63
+ expect(bar.parentElement).toBe(titlebar(el));
64
+ // The WINDOW's own two are gone, and the bar brings its own pair instead — which is
65
+ // what `show-title-buttons` is for (gtkheaderbar.c:198-249).
66
+ expect([...titlebar(el).children]).toStrictEqual([bar]);
67
+ expect(el.querySelectorAll('gtk-window-controls').length).toBe(2);
68
+ host.remove();
69
+ });
70
+
71
+ await it('with no titlebar it draws the SSD a window manager would have', async () => {
72
+ const { el, host } = mount({ title: 'Documents' });
73
+ expect([...titlebar(el).children].map((node) => node.localName)).toStrictEqual([
74
+ 'gtk-window-controls',
75
+ 'span',
76
+ 'gtk-window-controls',
77
+ ]);
78
+ expect(titlebar(el).querySelector('.adw-gtk-window-title')?.getAttribute('title')).toBe('Documents');
79
+ host.remove();
80
+ });
81
+
82
+ await it('`decorated="false"` HIDES the strip, frame buttons and all', async () => {
83
+ // gtk_window_set_decorated (gtkwindow.c:1014) takes the titlebar OUT OF THE FRAME,
84
+ // which is not the same as discarding it: the window keeps the widget and an
85
+ // undecorating write puts it back. So the strip is hidden, not emptied.
86
+ const { el, host } = mount();
87
+ el.decorated = false;
88
+ expect(titlebar(el).hidden).toBe(true);
89
+ expect(el.querySelector('gtk-window-controls')).not.toBe(null);
90
+ el.decorated = true;
91
+ expect(titlebar(el).hidden).toBe(false);
92
+ host.remove();
93
+ });
94
+ });
95
+
96
+ await describe('<gtk-window> frame properties', async () => {
97
+ await it('`maximized` and `fullscreened` square the frame off', async () => {
98
+ // _window.scss:66-72 — the two states with no corners and no shadow.
99
+ const { el, host } = mount();
100
+ el.maximized = true;
101
+ expect(el.classList.contains('maximized')).toBe(true);
102
+ el.maximized = false;
103
+ el.setAttribute('fullscreened', '');
104
+ expect(el.classList.contains('fullscreen')).toBe(true);
105
+ host.remove();
106
+ });
107
+
108
+ await it('`default-width`/`default-height` size the frame, and an absent one clears it', async () => {
109
+ const { el, host } = mount({ 'default-width': '480', 'default-height': '320' });
110
+ expect(el.style.width).toBe('480px');
111
+ expect(el.style.height).toBe('320px');
112
+ el.removeAttribute('default-width');
113
+ expect(el.style.width).toBe('');
114
+ host.remove();
115
+ });
116
+
117
+ await it("`title` is the window's accessible name", async () => {
118
+ const { el, host } = mount({ title: 'Documents' });
119
+ expect(el.getAttribute('aria-label')).toBe('Documents');
120
+ el.removeAttribute('title');
121
+ expect(el.hasAttribute('aria-label')).toBe(false);
122
+ host.remove();
123
+ });
124
+
125
+ await it('the frame buttons follow `deletable` and `resizable`', async () => {
126
+ // One read each, through the controls the window draws.
127
+ const { el, host } = mount();
128
+ el.deletable = false;
129
+ el.resizable = false;
130
+ await Promise.resolve();
131
+ await Promise.resolve();
132
+ expect(el.querySelector('.adw-window-controls-button.close')).toBe(null);
133
+ expect(el.querySelector('.adw-window-controls-button.maximize')).toBe(null);
134
+ expect(el.querySelector('.adw-window-controls-button.minimize')).not.toBe(null);
135
+ host.remove();
136
+ });
137
+
138
+ await it('the maximize button toggles `maximized` and says so', async () => {
139
+ const { el, host } = mount();
140
+ const button = el.querySelector('.adw-window-controls-button.maximize') as HTMLButtonElement;
141
+ expect(button.getAttribute('aria-label')).toBe('Maximize');
142
+ button.click();
143
+ expect(el.maximized).toBe(true);
144
+ host.remove();
145
+ });
146
+
147
+ await it('notifies once per real change', async () => {
148
+ const { el, host } = mount();
149
+ const events: unknown[] = [];
150
+ el.addEventListener('notify::resizable', (e) => events.push((e as CustomEvent).detail));
151
+ el.resizable = false;
152
+ el.resizable = false;
153
+ expect(events).toStrictEqual([{ resizable: false }]);
154
+ host.remove();
155
+ });
156
+ });
157
+
158
+ await describe('<gtk-window> close', async () => {
159
+ await it("detaches the frame, which is GTK's destroy branch", async () => {
160
+ // gtkwindow.c:1282-1285 — no hide-on-close, so `gtk_window_destroy`.
161
+ const { el, host } = mount();
162
+ let seen = 0;
163
+ el.addEventListener('close-request', () => {
164
+ seen += 1;
165
+ });
166
+ expect(el.close()).toBe(true);
167
+ expect(seen).toBe(1);
168
+ expect(el.isConnected).toBe(false);
169
+ host.remove();
170
+ });
171
+
172
+ await it('hides the frame when `hide-on-close` is set', async () => {
173
+ // gtkwindow.c:945 and the first branch of :1282.
174
+ const { el, host } = mount({ 'hide-on-close': 'true' });
175
+ el.close();
176
+ expect(el.isConnected).toBe(true);
177
+ expect(el.hidden).toBe(true);
178
+ host.remove();
179
+ });
180
+
181
+ await it('a handler that cancels `close-request` takes the whole thing over', async () => {
182
+ // gtkwindow.c:1300-1320 — `g_signal_stop_emission_by_name` on the default handler.
183
+ const { el, host } = mount();
184
+ el.addEventListener('close-request', (e) => e.preventDefault());
185
+ expect(el.close()).toBe(false);
186
+ expect(el.isConnected).toBe(true);
187
+ host.remove();
188
+ });
189
+ });
190
+ };
package/src/index.ts CHANGED
@@ -81,7 +81,8 @@ export type { AdwUndershootEdges } from './scroll-shading.js';
81
81
  // spec itself — has a route to it that is not a `.spec.ts` import; see that file's header
82
82
  // for why `mountSharedTree` and not `buildSharedTree` alone is the instantiation half.
83
83
  export { buildSharedTree, mountSharedTree } from './shared-tree-builder.js';
84
- export type { MountedSharedTree } from './shared-tree-builder.js';
84
+ export type { MountedSharedTree, SizeSource } from './shared-tree-builder.js';
85
+ export { registerTemplateClass } from './template-classes.js';
85
86
 
86
87
  // The stylesheet compiles a chosen SUBSET of `@gjsify/adwaita-icons` (the whole set is
87
88
  // ~1.07 MB of data-URI), so a name outside it draws the `image-missing` fallback. This is
@@ -156,6 +157,13 @@ export { AdwViewSwitcherPage } from './elements/adw-view-switcher.js';
156
157
  export { AdwViewStackPage } from './elements/adw-inline-view-switcher.js';
157
158
  export { AdwSidebarItem, AdwSidebarSection } from './elements/adw-sidebar.js';
158
159
 
160
+ // The two halves of a shortcuts dialog, and the same objection the four above state:
161
+ // `AdwShortcutsSection` and `AdwShortcutsItem` descend from `GObject.Object` (they are
162
+ // `add()`ed to a dialog, not packed into one), so there is no GIR name to export them
163
+ // under. `AdwShortcutsDialog` itself IS a widget and has its namespace member.
164
+ export { AdwShortcutsSection } from './elements/adw-shortcuts-section.js';
165
+ export { AdwShortcutsItem } from './elements/adw-shortcuts-item.js';
166
+
159
167
  // Slot wrappers and a declarative response: on GTK these are `set_content()`,
160
168
  // `set_sheet()` and `add_response()` — calls, not widgets.
161
169
  export { AdwBottomSheetBottomBar, AdwBottomSheetContent, AdwBottomSheetSheet } from './elements/adw-bottom-sheet.js';
@@ -633,7 +633,10 @@ export const AdwKeyboardOperableTest = async () => {
633
633
  // disabled toggle is otherwise a `focus()` the browser refuses, with nothing
634
634
  // in the walk to step over it. Grow this list and add the filter and its spec
635
635
  // in the same change (status/open-todos/README.md, `<adw-toggle>` has no `enabled`).
636
- expect([...AdwToggle.observedAttributes]).toStrictEqual(['label', 'icon-name']);
636
+ //
637
+ // `tooltip` joined the list and is NOT a counterexample: it sets `title` and
638
+ // `aria-label`, which change neither reachability nor rendering.
639
+ expect([...AdwToggle.observedAttributes]).toStrictEqual(['label', 'icon-name', 'tooltip']);
637
640
  });
638
641
 
639
642
  await it('adw-toggle-group notifies once per arrow, through the click path', async () => {
@@ -895,6 +898,35 @@ export const AdwKeyboardOperableTest = async () => {
895
898
  host.remove();
896
899
  });
897
900
 
901
+ // `<gtk-editable-label>` is the one GTK widget here whose focus moves WITH its
902
+ // state: the label is focusable and `editing` hands the focus to the entry
903
+ // (gtkeditablelabel.c:614,652), so the tab stop has to move with it or a Tab would
904
+ // reach a control the user cannot see.
905
+ await it('gtk-editable-label moves its tab stop with its state', () => {
906
+ const host = mount('<gtk-editable-label id="k-ed" text="Ada"></gtk-editable-label>');
907
+ const el = document.getElementById('k-ed') as HTMLElement & {
908
+ entry: HTMLInputElement;
909
+ startEditing: () => void;
910
+ stopEditing: (commit?: boolean) => void;
911
+ };
912
+
913
+ expect(el.getAttribute('tabindex')).toBe('0');
914
+ expect(el.entry.tabIndex).toBe(-1);
915
+ el.focus();
916
+ expect(document.activeElement).toBe(el);
917
+
918
+ el.startEditing();
919
+ expect(el.hasAttribute('tabindex')).toBe(false);
920
+ expect(document.activeElement).toBe(el.entry);
921
+
922
+ // …and back: the widget owns the focus once the edit is over, so the next Tab
923
+ // starts from the label rather than from inside a collapsed edit mode.
924
+ el.stopEditing(true);
925
+ expect(el.getAttribute('tabindex')).toBe('0');
926
+ expect(document.activeElement).toBe(el);
927
+ host.remove();
928
+ });
929
+
898
930
  await it('activates on Enter and Space, and lets a child keep its own keys', () => {
899
931
  const host = mount(
900
932
  '<adw-action-row id="k-keys" title="Keys" activatable></adw-action-row>' +
@@ -0,0 +1,121 @@
1
+ // What `<gtk-list-view>`, `<gtk-grid-view>` and `<gtk-column-view>` share in the DOM —
2
+ // the default factory and the rubber band (ADR 0089).
3
+ //
4
+ // The three views derive from `GtkListBase` upstream and share its item manager, its
5
+ // selection function and its rubberband gesture. The SELECTION half of that is portable
6
+ // and lives in `@gjsify/adwaita-core`'s `ListViewState` (ADR 0004); what is left here is
7
+ // genuinely a DOM job — a pointer drag, a rectangle, and the node a factory builds — and
8
+ // is shared for the reason the second copy always is: three elements writing the same
9
+ // hit test is three places for it to be subtly different.
10
+ //
11
+ // Reference: refs/gtk/gtk/gtklistbase.c (the rubberband gesture and its `rubberband` node)
12
+ // Reference: refs/libadwaita/src/stylesheet/widgets/_views.scss:47-50 (`rubberband`)
13
+ // Copyright (c) GNOME contributors (GTK/libadwaita). LGPLv2.1+.
14
+
15
+ import type { AdwListItemContext, AdwListItemFactory } from '@gjsify/adwaita-core';
16
+
17
+ /** The class every row/cell label carries, so one stylesheet rule reaches all three views. */
18
+ export const LIST_ITEM_LABEL_CLASS = 'adw-list-item-label';
19
+
20
+ /**
21
+ * What a view draws for an item when no `factory` was set.
22
+ *
23
+ * GTK HAS NO DEFAULT FACTORY — `gtk_list_view_new (model, NULL)` is legal and draws empty
24
+ * rows, which on a documentation surface is indistinguishable from a broken widget. So
25
+ * the port's default is the factory every upstream example writes by hand: a label bound
26
+ * to the item. Setting `factory` replaces it, and that is the only way to get GTK's own
27
+ * answer back.
28
+ */
29
+ export const defaultListItemFactory: AdwListItemFactory<Node> = (context: AdwListItemContext) => {
30
+ const label = document.createElement('span');
31
+ label.className = LIST_ITEM_LABEL_CLASS;
32
+ label.textContent = context.item.label;
33
+ return label;
34
+ };
35
+
36
+ /** What {@link attachRubberBand} needs to know about the view it bands. */
37
+ export interface AdwRubberBandInit {
38
+ /** The element the pointer listeners sit on. */
39
+ host: HTMLElement;
40
+ /** The positioned box the band is drawn inside — the row container. */
41
+ surface: HTMLElement;
42
+ /** Whether a drag may start right now: `enable-rubberband` AND a multiple selection. */
43
+ enabled: () => boolean;
44
+ /** The row elements, in model order. */
45
+ rows: () => readonly HTMLElement[];
46
+ /** Select every position the band covers, replacing the selection. */
47
+ selectPositions: (positions: readonly number[]) => void;
48
+ }
49
+
50
+ /**
51
+ * Rubberband selection — drag on the view's background to select what the rectangle
52
+ * covers.
53
+ *
54
+ * GTK runs this as a drag gesture on `GtkListBase` and draws a `rubberband` CSS node,
55
+ * which libadwaita styles as an accent border over a 20% accent fill
56
+ * (`_views.scss:47-50`); this builds the same node and lets that rule reach it.
57
+ *
58
+ * THE DRAG MUST START ON THE BACKGROUND. A press that lands on a row is that row's click
59
+ * — GTK's row gesture claims the sequence — so starting a band there would make every
60
+ * click a one-pixel drag and swallow the row's own selection step.
61
+ *
62
+ * The hit test is `getBoundingClientRect` per row against the band, which is the same
63
+ * question GTK answers against its tile areas. It is recomputed per pointermove rather
64
+ * than cached: a row's box can change mid-drag (a scroll, a factory that lays out late),
65
+ * and a cached rectangle would select the wrong rows without anything looking wrong.
66
+ */
67
+ export function attachRubberBand(init: AdwRubberBandInit): void {
68
+ let band: HTMLElement | null = null;
69
+ let origin: { x: number; y: number } | null = null;
70
+ let pointerId: number | null = null;
71
+
72
+ const stop = () => {
73
+ band?.remove();
74
+ band = null;
75
+ origin = null;
76
+ if (pointerId !== null && init.host.hasPointerCapture(pointerId)) {
77
+ init.host.releasePointerCapture(pointerId);
78
+ }
79
+ pointerId = null;
80
+ };
81
+
82
+ init.host.addEventListener('pointerdown', (event) => {
83
+ if (event.button !== 0 || !init.enabled()) return;
84
+ const target = event.target as Node | null;
85
+ if (target !== null && init.rows().some((row) => row === target || row.contains(target))) return;
86
+
87
+ origin = { x: event.clientX, y: event.clientY };
88
+ pointerId = event.pointerId;
89
+ init.host.setPointerCapture(event.pointerId);
90
+ band = document.createElement('div');
91
+ band.className = 'adw-rubberband';
92
+ band.setAttribute('aria-hidden', 'true');
93
+ init.surface.appendChild(band);
94
+ });
95
+
96
+ init.host.addEventListener('pointermove', (event) => {
97
+ if (origin === null || band === null) return;
98
+ const box = init.surface.getBoundingClientRect();
99
+ const left = Math.min(origin.x, event.clientX);
100
+ const top = Math.min(origin.y, event.clientY);
101
+ const width = Math.abs(event.clientX - origin.x);
102
+ const height = Math.abs(event.clientY - origin.y);
103
+ band.style.left = `${left - box.left}px`;
104
+ band.style.top = `${top - box.top}px`;
105
+ band.style.width = `${width}px`;
106
+ band.style.height = `${height}px`;
107
+
108
+ const covered: number[] = [];
109
+ init.rows().forEach((row, position) => {
110
+ const rect = row.getBoundingClientRect();
111
+ const hit =
112
+ rect.right >= left && rect.left <= left + width && rect.bottom >= top && rect.top <= top + height;
113
+ if (hit) covered.push(position);
114
+ });
115
+ init.selectPositions(covered);
116
+ });
117
+
118
+ for (const name of ['pointerup', 'pointercancel', 'lostpointercapture']) {
119
+ init.host.addEventListener(name, stop);
120
+ }
121
+ }
@@ -56,21 +56,27 @@
56
56
  export { AdwAboutDialog as AboutDialog } from '../elements/adw-about-dialog.js';
57
57
  export { AdwActionRow as ActionRow } from '../elements/adw-action-row.js';
58
58
  export { AdwAlertDialog as AlertDialog } from '../elements/adw-alert-dialog.js';
59
+ export { AdwApplicationWindow as ApplicationWindow } from '../elements/adw-application-window.js';
59
60
  export { AdwAvatar as Avatar } from '../elements/adw-avatar.js';
60
61
  export { AdwBanner as Banner } from '../elements/adw-banner.js';
62
+ export { AdwBin as Bin } from '../elements/adw-bin.js';
61
63
  export { AdwBottomSheet as BottomSheet } from '../elements/adw-bottom-sheet.js';
64
+ export { AdwBreakpointBin as BreakpointBin } from '../elements/adw-breakpoint-bin.js';
62
65
  export { AdwButtonContent as ButtonContent } from '../elements/adw-button-content.js';
63
66
  export { AdwButtonRow as ButtonRow } from '../elements/adw-button-row.js';
64
67
  export { AdwCarousel as Carousel } from '../elements/adw-carousel.js';
65
68
  export { AdwCarouselIndicatorDots as CarouselIndicatorDots } from '../elements/adw-carousel.js';
66
69
  export { AdwCarouselIndicatorLines as CarouselIndicatorLines } from '../elements/adw-carousel.js';
67
70
  export { AdwClamp as Clamp } from '../elements/adw-clamp.js';
71
+ export { AdwClampScrollable as ClampScrollable } from '../elements/adw-clamp-scrollable.js';
68
72
  export { AdwComboRow as ComboRow } from '../elements/adw-combo-row.js';
69
73
  export { AdwDialog as Dialog } from '../elements/adw-dialog.js';
70
74
  export { AdwEntryRow as EntryRow } from '../elements/adw-entry-row.js';
71
75
  export { AdwExpanderRow as ExpanderRow } from '../elements/adw-expander-row.js';
72
76
  export { AdwHeaderBar as HeaderBar } from '../elements/adw-header-bar.js';
73
77
  export { AdwInlineViewSwitcher as InlineViewSwitcher } from '../elements/adw-inline-view-switcher.js';
78
+ export { AdwLayoutSlot as LayoutSlot } from '../elements/adw-layout-slot.js';
79
+ export { AdwMultiLayoutView as MultiLayoutView } from '../elements/adw-multi-layout-view.js';
74
80
  export { AdwNavigationPage as NavigationPage } from '../elements/adw-navigation-view.js';
75
81
  export { AdwNavigationSplitView as NavigationSplitView } from '../elements/adw-navigation-split-view.js';
76
82
  export { AdwNavigationView as NavigationView } from '../elements/adw-navigation-view.js';
@@ -79,13 +85,18 @@ export { AdwPasswordEntryRow as PasswordEntryRow } from '../elements/adw-passwor
79
85
  export { AdwPreferencesDialog as PreferencesDialog } from '../elements/adw-preferences-dialog.js';
80
86
  export { AdwPreferencesGroup as PreferencesGroup } from '../elements/adw-preferences-group.js';
81
87
  export { AdwPreferencesPage as PreferencesPage } from '../elements/adw-preferences-dialog.js';
88
+ export { AdwPreferencesRow as PreferencesRow } from '../elements/adw-preferences-row.js';
82
89
  export { AdwShortcutLabel as ShortcutLabel } from '../elements/adw-shortcut-label.js';
90
+ export { AdwShortcutsDialog as ShortcutsDialog } from '../elements/adw-shortcuts-dialog.js';
83
91
  export { AdwSidebar as Sidebar } from '../elements/adw-sidebar.js';
84
92
  export { AdwSpinRow as SpinRow } from '../elements/adw-spin-row.js';
85
93
  export { AdwSpinner as Spinner } from '../elements/adw-spinner.js';
86
94
  export { AdwSplitButton as SplitButton } from '../elements/adw-split-button.js';
87
95
  export { AdwStatusPage as StatusPage } from '../elements/adw-status-page.js';
88
96
  export { AdwSwitchRow as SwitchRow } from '../elements/adw-switch-row.js';
97
+ export { AdwTabBar as TabBar } from '../elements/adw-tab-bar.js';
98
+ export { AdwTabButton as TabButton } from '../elements/adw-tab-button.js';
99
+ export { AdwTabOverview as TabOverview } from '../elements/adw-tab-overview.js';
89
100
  export { AdwTabView as TabView } from '../elements/adw-tab-view.js';
90
101
  export { AdwToastOverlay as ToastOverlay } from '../elements/adw-toast-overlay.js';
91
102
  export { AdwToggle as Toggle } from '../elements/adw-toggle-group.js';
@@ -93,6 +104,7 @@ export { AdwToggleGroup as ToggleGroup } from '../elements/adw-toggle-group.js';
93
104
  export { AdwToolbarView as ToolbarView } from '../elements/adw-toolbar-view.js';
94
105
  export { AdwViewStack as ViewStack } from '../elements/adw-view-stack.js';
95
106
  export { AdwViewSwitcher as ViewSwitcher } from '../elements/adw-view-switcher.js';
107
+ export { AdwViewSwitcherSidebar as ViewSwitcherSidebar } from '../elements/adw-view-switcher-sidebar.js';
96
108
  export { AdwViewSwitcherBar as ViewSwitcherBar } from '../elements/adw-view-switcher-bar.js';
97
109
  export { AdwWindow as Window } from '../elements/adw-window.js';
98
110
  export { AdwWindowTitle as WindowTitle } from '../elements/adw-window-title.js';