@gjsify/adwaita-web 0.64.2-next.252 → 0.64.2-next.254

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 (293) hide show
  1. package/README.md +10 -80
  2. package/dist/adwaita-web.css +52 -3
  3. package/dist/adwaita-web.css.map +1 -1
  4. package/lib/types/accessible.d.ts +8 -0
  5. package/lib/types/compute-expand.d.ts +5 -0
  6. package/lib/types/compute-expand.spec.d.ts +1 -0
  7. package/lib/types/elements/adw-about-dialog.d.ts +28 -1
  8. package/lib/types/elements/adw-action-row.d.ts +2 -1
  9. package/lib/types/elements/adw-alert-dialog.d.ts +3 -2
  10. package/lib/types/elements/adw-avatar.d.ts +2 -1
  11. package/lib/types/elements/adw-banner.d.ts +2 -1
  12. package/lib/types/elements/adw-bin.d.ts +2 -1
  13. package/lib/types/elements/adw-bottom-sheet.d.ts +5 -4
  14. package/lib/types/elements/adw-breakpoint-bin.d.ts +2 -1
  15. package/lib/types/elements/adw-button-content.d.ts +2 -1
  16. package/lib/types/elements/adw-button-row.d.ts +2 -1
  17. package/lib/types/elements/adw-card.d.ts +2 -1
  18. package/lib/types/elements/adw-carousel.d.ts +20 -3
  19. package/lib/types/elements/adw-clamp-scrollable.d.ts +2 -1
  20. package/lib/types/elements/adw-clamp.d.ts +2 -1
  21. package/lib/types/elements/adw-combo-row.d.ts +6 -1
  22. package/lib/types/elements/adw-data-grid.d.ts +2 -1
  23. package/lib/types/elements/adw-dialog.d.ts +2 -1
  24. package/lib/types/elements/adw-entry-row.d.ts +2 -1
  25. package/lib/types/elements/adw-expander-row.d.ts +2 -1
  26. package/lib/types/elements/adw-header-bar.d.ts +2 -1
  27. package/lib/types/elements/adw-inline-view-switcher.d.ts +3 -2
  28. package/lib/types/elements/adw-layout-slot.d.ts +2 -1
  29. package/lib/types/elements/adw-multi-layout-view.d.ts +2 -1
  30. package/lib/types/elements/adw-navigation-split-view.d.ts +2 -1
  31. package/lib/types/elements/adw-navigation-view.d.ts +3 -2
  32. package/lib/types/elements/adw-overlay-split-view.d.ts +2 -1
  33. package/lib/types/elements/adw-preferences-dialog.d.ts +5 -4
  34. package/lib/types/elements/adw-preferences-group.d.ts +2 -1
  35. package/lib/types/elements/adw-preferences-row.d.ts +2 -1
  36. package/lib/types/elements/adw-shortcut-label.d.ts +2 -1
  37. package/lib/types/elements/adw-shortcuts-item.d.ts +2 -1
  38. package/lib/types/elements/adw-shortcuts-section.d.ts +2 -1
  39. package/lib/types/elements/adw-sidebar.d.ts +4 -3
  40. package/lib/types/elements/adw-spin-row.d.ts +2 -1
  41. package/lib/types/elements/adw-spinner.d.ts +2 -1
  42. package/lib/types/elements/adw-split-button.d.ts +2 -1
  43. package/lib/types/elements/adw-status-page.d.ts +2 -1
  44. package/lib/types/elements/adw-switch-row.d.ts +4 -1
  45. package/lib/types/elements/adw-tab-bar.d.ts +2 -1
  46. package/lib/types/elements/adw-tab-button.d.ts +2 -1
  47. package/lib/types/elements/adw-tab-overview.d.ts +2 -1
  48. package/lib/types/elements/adw-tab-view.d.ts +3 -2
  49. package/lib/types/elements/adw-toast-overlay.d.ts +2 -1
  50. package/lib/types/elements/adw-toggle-group.d.ts +3 -2
  51. package/lib/types/elements/adw-toolbar-view.d.ts +2 -1
  52. package/lib/types/elements/adw-view-stack.d.ts +3 -1
  53. package/lib/types/elements/adw-view-switcher-bar.d.ts +2 -1
  54. package/lib/types/elements/adw-view-switcher-sidebar.d.ts +2 -1
  55. package/lib/types/elements/adw-view-switcher.d.ts +3 -2
  56. package/lib/types/elements/adw-window-title.d.ts +2 -1
  57. package/lib/types/elements/adw-wrap-box.d.ts +2 -1
  58. package/lib/types/elements/checks.d.ts +16 -1
  59. package/lib/types/elements/gtk-action-bar.d.ts +2 -1
  60. package/lib/types/elements/gtk-aspect-frame.d.ts +2 -1
  61. package/lib/types/elements/gtk-box.d.ts +5 -1
  62. package/lib/types/elements/gtk-button.d.ts +5 -7
  63. package/lib/types/elements/gtk-calendar.d.ts +2 -1
  64. package/lib/types/elements/gtk-center-box.d.ts +2 -1
  65. package/lib/types/elements/gtk-color-dialog-button.d.ts +2 -1
  66. package/lib/types/elements/gtk-drag-icon.d.ts +2 -1
  67. package/lib/types/elements/gtk-drawing-area.d.ts +2 -1
  68. package/lib/types/elements/gtk-drop-down.d.ts +2 -1
  69. package/lib/types/elements/gtk-editable-label.d.ts +2 -1
  70. package/lib/types/elements/gtk-entry.d.ts +2 -1
  71. package/lib/types/elements/gtk-expander.d.ts +2 -1
  72. package/lib/types/elements/gtk-fixed.d.ts +2 -1
  73. package/lib/types/elements/gtk-flow-box-child.d.ts +2 -1
  74. package/lib/types/elements/gtk-flow-box.d.ts +2 -1
  75. package/lib/types/elements/gtk-font-dialog-button.d.ts +2 -1
  76. package/lib/types/elements/gtk-frame.d.ts +2 -1
  77. package/lib/types/elements/gtk-gl-area.d.ts +2 -1
  78. package/lib/types/elements/gtk-graphics-offload.d.ts +2 -1
  79. package/lib/types/elements/gtk-grid.d.ts +2 -1
  80. package/lib/types/elements/gtk-header-bar.d.ts +2 -1
  81. package/lib/types/elements/gtk-image.d.ts +5 -6
  82. package/lib/types/elements/gtk-inscription.d.ts +2 -1
  83. package/lib/types/elements/gtk-label.d.ts +10 -3
  84. package/lib/types/elements/gtk-level-bar.d.ts +2 -1
  85. package/lib/types/elements/gtk-list-box-row.d.ts +2 -1
  86. package/lib/types/elements/gtk-list-box.d.ts +2 -1
  87. package/lib/types/elements/gtk-list-view.d.ts +2 -1
  88. package/lib/types/elements/gtk-media-controls.d.ts +2 -1
  89. package/lib/types/elements/gtk-menu-button.d.ts +2 -1
  90. package/lib/types/elements/gtk-notebook.d.ts +2 -1
  91. package/lib/types/elements/gtk-overlay.d.ts +2 -1
  92. package/lib/types/elements/gtk-paned.d.ts +2 -1
  93. package/lib/types/elements/gtk-picture.d.ts +2 -1
  94. package/lib/types/elements/gtk-popover-bin.d.ts +2 -1
  95. package/lib/types/elements/gtk-popover-menu-bar.d.ts +2 -1
  96. package/lib/types/elements/gtk-popover.d.ts +2 -1
  97. package/lib/types/elements/gtk-progress-bar.d.ts +2 -1
  98. package/lib/types/elements/gtk-revealer.d.ts +2 -1
  99. package/lib/types/elements/gtk-scale-button.d.ts +2 -1
  100. package/lib/types/elements/gtk-scale.d.ts +2 -1
  101. package/lib/types/elements/gtk-scrollbar.d.ts +2 -1
  102. package/lib/types/elements/gtk-scrolled-window.d.ts +2 -1
  103. package/lib/types/elements/gtk-search-bar.d.ts +2 -1
  104. package/lib/types/elements/gtk-separator.d.ts +2 -1
  105. package/lib/types/elements/gtk-spin-button.d.ts +2 -1
  106. package/lib/types/elements/gtk-spinner.d.ts +2 -1
  107. package/lib/types/elements/gtk-stack-page.d.ts +2 -1
  108. package/lib/types/elements/gtk-stack-sidebar.d.ts +2 -1
  109. package/lib/types/elements/gtk-stack-switcher.d.ts +2 -1
  110. package/lib/types/elements/gtk-stack.d.ts +2 -1
  111. package/lib/types/elements/gtk-switch.d.ts +2 -1
  112. package/lib/types/elements/gtk-text-view.d.ts +2 -1
  113. package/lib/types/elements/gtk-text.d.ts +2 -1
  114. package/lib/types/elements/gtk-tree-expander.d.ts +2 -1
  115. package/lib/types/elements/gtk-video.d.ts +2 -1
  116. package/lib/types/elements/gtk-viewport.d.ts +2 -1
  117. package/lib/types/elements/gtk-window-controls.d.ts +2 -1
  118. package/lib/types/elements/gtk-window-handle.d.ts +2 -1
  119. package/lib/types/elements/gtk-window.d.ts +2 -1
  120. package/lib/types/gobject-elements.d.ts +7 -1
  121. package/lib/types/gtksource/gtk-source-view.d.ts +2 -1
  122. package/lib/types/{icon-registry.spec.d.ts → icon-masks.spec.d.ts} +1 -1
  123. package/lib/types/icon-theme.d.ts +15 -35
  124. package/lib/types/index.d.ts +1 -2
  125. package/lib/types/namespace/gdk.d.ts +1 -0
  126. package/lib/types/namespace/gio.d.ts +1 -0
  127. package/lib/types/namespace/glib.d.ts +2 -1
  128. package/lib/types/signals.d.ts +5 -1
  129. package/lib/types/source-view/adw-source-view.d.ts +2 -1
  130. package/lib/types/styles.generated.d.ts +1 -1
  131. package/lib/types/widget-element.d.ts +25 -0
  132. package/lib/types/widget-map.spec.d.ts +1 -0
  133. package/lib/types/widget-mapping.d.ts +7 -0
  134. package/package.json +12 -12
  135. package/scss/_about_dialog.scss +46 -1
  136. package/scss/_checks.scss +5 -2
  137. package/scss/_icon.scss +3 -4
  138. package/scss/_labels.scss +2 -2
  139. package/scss/_overlay_split_view.scss +10 -0
  140. package/scss/_scrolled_window.scss +15 -0
  141. package/scss/_widget.scss +5 -1
  142. package/src/accessible.ts +29 -0
  143. package/src/adw-about-dialog.spec.ts +81 -12
  144. package/src/adw-action-rows.spec.ts +2 -2
  145. package/src/adw-button-content.spec.ts +1 -1
  146. package/src/adw-carousel.spec.ts +49 -1
  147. package/src/capabilities.mjs +1 -0
  148. package/src/checks.spec.ts +51 -1
  149. package/src/compute-expand.spec.ts +186 -0
  150. package/src/compute-expand.ts +134 -0
  151. package/src/construct-vectors.spec.ts +46 -1
  152. package/src/elements/adw-about-dialog.ts +152 -9
  153. package/src/elements/adw-action-row.ts +2 -1
  154. package/src/elements/adw-alert-dialog.ts +3 -2
  155. package/src/elements/adw-avatar.ts +2 -1
  156. package/src/elements/adw-banner.ts +2 -1
  157. package/src/elements/adw-bin.ts +2 -1
  158. package/src/elements/adw-bottom-sheet.ts +5 -4
  159. package/src/elements/adw-breakpoint-bin.ts +2 -1
  160. package/src/elements/adw-button-content.ts +2 -1
  161. package/src/elements/adw-button-row.ts +2 -1
  162. package/src/elements/adw-card.ts +2 -1
  163. package/src/elements/adw-carousel.ts +62 -3
  164. package/src/elements/adw-clamp-scrollable.ts +2 -1
  165. package/src/elements/adw-clamp.ts +2 -1
  166. package/src/elements/adw-combo-row.ts +15 -1
  167. package/src/elements/adw-data-grid.ts +2 -1
  168. package/src/elements/adw-dialog.ts +2 -1
  169. package/src/elements/adw-entry-row.ts +2 -1
  170. package/src/elements/adw-expander-row.ts +2 -1
  171. package/src/elements/adw-header-bar.ts +2 -1
  172. package/src/elements/adw-inline-view-switcher.ts +3 -2
  173. package/src/elements/adw-layout-slot.ts +2 -1
  174. package/src/elements/adw-multi-layout-view.ts +2 -1
  175. package/src/elements/adw-navigation-split-view.ts +2 -1
  176. package/src/elements/adw-navigation-view.ts +3 -2
  177. package/src/elements/adw-overlay-split-view.ts +2 -1
  178. package/src/elements/adw-preferences-dialog.ts +6 -4
  179. package/src/elements/adw-preferences-group.ts +2 -1
  180. package/src/elements/adw-preferences-row.ts +2 -1
  181. package/src/elements/adw-shortcut-label.ts +2 -1
  182. package/src/elements/adw-shortcuts-item.ts +2 -1
  183. package/src/elements/adw-shortcuts-section.ts +2 -1
  184. package/src/elements/adw-sidebar.ts +4 -3
  185. package/src/elements/adw-spin-row.ts +2 -1
  186. package/src/elements/adw-spinner.ts +2 -1
  187. package/src/elements/adw-split-button.ts +2 -1
  188. package/src/elements/adw-status-page.ts +2 -1
  189. package/src/elements/adw-switch-row.ts +10 -1
  190. package/src/elements/adw-tab-bar.ts +2 -1
  191. package/src/elements/adw-tab-button.ts +2 -1
  192. package/src/elements/adw-tab-overview.ts +2 -1
  193. package/src/elements/adw-tab-view.ts +3 -2
  194. package/src/elements/adw-toast-overlay.ts +2 -1
  195. package/src/elements/adw-toggle-group.ts +3 -2
  196. package/src/elements/adw-toolbar-view.ts +2 -1
  197. package/src/elements/adw-view-stack.ts +39 -1
  198. package/src/elements/adw-view-switcher-bar.ts +2 -1
  199. package/src/elements/adw-view-switcher-sidebar.ts +2 -1
  200. package/src/elements/adw-view-switcher.ts +3 -2
  201. package/src/elements/adw-window-title.ts +2 -1
  202. package/src/elements/adw-wrap-box.ts +2 -1
  203. package/src/elements/checks.ts +85 -6
  204. package/src/elements/gtk-action-bar.ts +2 -1
  205. package/src/elements/gtk-aspect-frame.ts +2 -1
  206. package/src/elements/gtk-box.ts +56 -1
  207. package/src/elements/gtk-button.ts +10 -22
  208. package/src/elements/gtk-calendar.ts +2 -1
  209. package/src/elements/gtk-center-box.ts +2 -1
  210. package/src/elements/gtk-color-dialog-button.ts +2 -1
  211. package/src/elements/gtk-drag-icon.ts +2 -1
  212. package/src/elements/gtk-drawing-area.ts +2 -1
  213. package/src/elements/gtk-drop-down.ts +2 -1
  214. package/src/elements/gtk-editable-label.ts +2 -1
  215. package/src/elements/gtk-entry.ts +2 -1
  216. package/src/elements/gtk-expander.ts +2 -1
  217. package/src/elements/gtk-fixed.ts +2 -1
  218. package/src/elements/gtk-flow-box-child.ts +2 -1
  219. package/src/elements/gtk-flow-box.ts +2 -1
  220. package/src/elements/gtk-font-dialog-button.ts +2 -1
  221. package/src/elements/gtk-frame.ts +2 -1
  222. package/src/elements/gtk-gl-area.ts +2 -1
  223. package/src/elements/gtk-graphics-offload.ts +2 -1
  224. package/src/elements/gtk-grid.ts +2 -1
  225. package/src/elements/gtk-header-bar.ts +2 -1
  226. package/src/elements/gtk-image.ts +14 -15
  227. package/src/elements/gtk-inscription.ts +2 -1
  228. package/src/elements/gtk-label.ts +12 -5
  229. package/src/elements/gtk-level-bar.ts +2 -1
  230. package/src/elements/gtk-list-box-row.ts +2 -1
  231. package/src/elements/gtk-list-box.ts +2 -1
  232. package/src/elements/gtk-list-view.ts +2 -1
  233. package/src/elements/gtk-media-controls.ts +2 -1
  234. package/src/elements/gtk-menu-button.ts +2 -1
  235. package/src/elements/gtk-notebook.ts +2 -1
  236. package/src/elements/gtk-overlay.ts +2 -1
  237. package/src/elements/gtk-paned.ts +2 -1
  238. package/src/elements/gtk-picture.ts +2 -1
  239. package/src/elements/gtk-popover-bin.ts +2 -1
  240. package/src/elements/gtk-popover-menu-bar.ts +2 -1
  241. package/src/elements/gtk-popover.ts +2 -1
  242. package/src/elements/gtk-progress-bar.ts +2 -1
  243. package/src/elements/gtk-revealer.ts +2 -1
  244. package/src/elements/gtk-scale-button.ts +2 -1
  245. package/src/elements/gtk-scale.ts +2 -1
  246. package/src/elements/gtk-scrollbar.ts +2 -1
  247. package/src/elements/gtk-scrolled-window.ts +8 -5
  248. package/src/elements/gtk-search-bar.ts +2 -1
  249. package/src/elements/gtk-separator.ts +2 -1
  250. package/src/elements/gtk-spin-button.ts +2 -1
  251. package/src/elements/gtk-spinner.ts +2 -1
  252. package/src/elements/gtk-stack-page.ts +2 -1
  253. package/src/elements/gtk-stack-sidebar.ts +2 -1
  254. package/src/elements/gtk-stack-switcher.ts +2 -1
  255. package/src/elements/gtk-stack.ts +2 -1
  256. package/src/elements/gtk-switch.ts +2 -1
  257. package/src/elements/gtk-text-view.ts +2 -1
  258. package/src/elements/gtk-text.ts +2 -1
  259. package/src/elements/gtk-tree-expander.ts +2 -1
  260. package/src/elements/gtk-video.ts +2 -1
  261. package/src/elements/gtk-viewport.ts +2 -1
  262. package/src/elements/gtk-window-controls.ts +2 -1
  263. package/src/elements/gtk-window-handle.ts +2 -1
  264. package/src/elements/gtk-window.ts +2 -1
  265. package/src/gio.spec.ts +13 -3
  266. package/src/glib.spec.ts +9 -0
  267. package/src/gobject-elements.ts +18 -4
  268. package/src/gtk-label.spec.ts +39 -0
  269. package/src/gtk-scrolled-window.spec.ts +6 -6
  270. package/src/gtk-value-doors.spec.ts +19 -0
  271. package/src/gtk-window.spec.ts +2 -2
  272. package/src/gtksource/gtk-source-view.ts +2 -1
  273. package/src/{icon-registry.spec.ts → icon-masks.spec.ts} +4 -100
  274. package/src/icon-theme.spec.ts +69 -124
  275. package/src/icon-theme.ts +29 -119
  276. package/src/index.ts +3 -7
  277. package/src/namespace/gdk.ts +1 -0
  278. package/src/namespace/gio.ts +8 -0
  279. package/src/namespace/glib.ts +4 -0
  280. package/src/shared-tree-builder.ts +26 -3
  281. package/src/signals.ts +11 -2
  282. package/src/source-view/adw-source-view.ts +2 -1
  283. package/src/split-button.spec.ts +1 -1
  284. package/src/style-manager.spec.ts +13 -0
  285. package/src/style-manager.ts +6 -0
  286. package/src/styles.generated.ts +1 -1
  287. package/src/test.browser.mts +6 -2
  288. package/src/widget-element.ts +75 -0
  289. package/src/widget-map.spec.ts +116 -0
  290. package/src/widget-mapping.ts +100 -0
  291. package/src/widget-visible.spec.ts +44 -0
  292. package/lib/types/icon-registry.d.ts +0 -37
  293. package/src/icon-registry.ts +0 -163
@@ -56,6 +56,7 @@ import {
56
56
  } from './view-switcher-dom.js';
57
57
  import { type GtkImage, createGtkImage } from './gtk-image.js';
58
58
  import { attachRovingFocus } from './roving-focus.js';
59
+ import { WidgetElement } from '../widget-element.js';
59
60
 
60
61
  /** The DOM nodes one page owns — the switcher paints the derived model onto them. */
61
62
  interface PageNodes {
@@ -75,9 +76,9 @@ interface PageNodes {
75
76
  * switcher watches them with a `MutationObserver` instead — the DOM stand-in for
76
77
  * the per-page `notify` C rebinds on.
77
78
  */
78
- export class AdwViewSwitcherPage extends HTMLElement {}
79
+ export class AdwViewSwitcherPage extends WidgetElement {}
79
80
 
80
- export class AdwViewSwitcher extends HTMLElement {
81
+ export class AdwViewSwitcher extends WidgetElement {
81
82
  /**
82
83
  * The dwell timer, injectable so a test can hand in a clock and drive
83
84
  * `VIEW_SWITCHER_DRAG_VECTORS` against the real element. Replace it before the
@@ -22,8 +22,9 @@
22
22
  // title/subtitle state composed from @gjsify/adwaita-core.
23
23
 
24
24
  import { WindowTitleState } from '@gjsify/adwaita-core';
25
+ import { WidgetElement } from '../widget-element.js';
25
26
 
26
- export class AdwWindowTitle extends HTMLElement {
27
+ export class AdwWindowTitle extends WidgetElement {
27
28
  private _titleEl!: HTMLSpanElement;
28
29
  private _subtitleEl!: HTMLSpanElement;
29
30
  /** The headless title/subtitle pair + change detection (ADR 0004). */
@@ -41,6 +41,7 @@ import {
41
41
  wrapPolicyFlexShrink,
42
42
  type AdwLengthUnit,
43
43
  } from '@gjsify/adwaita-core';
44
+ import { WidgetElement } from '../widget-element.js';
44
45
 
45
46
  /**
46
47
  * The attributes that carry a property, in the order the C installs them.
@@ -80,7 +81,7 @@ function alignToJustifyContent(align: number): string {
80
81
  return 'flex-end';
81
82
  }
82
83
 
83
- export class AdwWrapBox extends HTMLElement {
84
+ export class AdwWrapBox extends WidgetElement {
84
85
  private _initialized = false;
85
86
 
86
87
  static get observedAttributes() {
@@ -37,7 +37,9 @@
37
37
  // · The active member of a group cannot be clicked off: both the gesture handler and
38
38
  // `real_activate` return early when the button is active AND has a group neighbour
39
39
  // (:395-396, :617-622). `<adw-radio>` gets this from `RadioGroupState`, and
40
- // `<gtk-check-button>` cannot reach a group at all here.
40
+ // `<gtk-check-button>` from `group` / `set_group` over the core's `check-group.ts`. A
41
+ // grouped `<gtk-check-button>` draws the round radio (the `radio` attribute) and its
42
+ // input announces `role="radio"`.
41
43
  //
42
44
  // ONE PLACE THIS PORT DIVERGES, DELIBERATELY AND CITED. GTK does NOT clear
43
45
  // `inconsistent` when the user activates the button — `real_activate` only flips
@@ -75,7 +77,8 @@
75
77
  // A11Y: the inner input carries the role (native `checkbox` / `radio`) and an
76
78
  // explicit `aria-checked` derived from {@link resolveCheckState}, so the
77
79
  // indeterminate state announces as `mixed` for BOTH — HTML has a native mixed
78
- // checkbox (`input.indeterminate`) but no mixed radio.
80
+ // checkbox (`input.indeterminate`) but no mixed radio. The host's `aria-label` /
81
+ // `aria-description` (a `.blp`'s `accessibility { }`) are copied onto it too.
79
82
  //
80
83
  // Reference: refs/gtk/gtk/gtkcheckbutton.c:99-112,395-426,617-628,647-714,773-774,849-886,925-974
81
84
  // Reference: refs/libadwaita/src/stylesheet/widgets/_checks.scss
@@ -85,9 +88,18 @@
85
88
  // Copyright (c) 2025 csm (adwaita-web). MIT License.
86
89
  // Modifications: Implemented as Web Components for @gjsify/adwaita-web.
87
90
 
88
- import { RadioGroupState, resolveCheckState } from '@gjsify/adwaita-core';
91
+ import {
92
+ RadioGroupState,
93
+ checkActivationFlips,
94
+ checkGroupNeighbours,
95
+ isRadioCheck,
96
+ resolveCheckState,
97
+ setCheckGroup,
98
+ } from '@gjsify/adwaita-core';
89
99
 
100
+ import { FORWARDED_ARIA, forwardAccessibleName } from '../accessible.js';
90
101
  import type { DispatchedSignals } from '../signals.js';
102
+ import { WidgetElement } from '../widget-element.js';
91
103
 
92
104
  /**
93
105
  * The document's radio groups. ONE registry, as global as a bare
@@ -104,7 +116,7 @@ const radioGroups = new RadioGroupState();
104
116
  * `.adw-check-indicator` and `.adw-check-label`, which are the Adwaita SKIN, and the
105
117
  * skin is not what the tag names. It is also not a widget — nothing registers it.
106
118
  */
107
- abstract class AdwCheckBase extends HTMLElement {
119
+ abstract class AdwCheckBase extends WidgetElement {
108
120
  protected _input!: HTMLInputElement;
109
121
  protected _indicator!: HTMLSpanElement;
110
122
  protected _label!: HTMLSpanElement;
@@ -240,6 +252,7 @@ abstract class AdwCheckBase extends HTMLElement {
240
252
  this._input.setAttribute('aria-checked', state === 'indeterminate' ? 'mixed' : String(state === 'checked'));
241
253
  this._input.disabled = this.disabled;
242
254
  this._label.hidden = this._label.childNodes.length === 0;
255
+ forwardAccessibleName(this, this._input);
243
256
  }
244
257
  }
245
258
 
@@ -252,14 +265,80 @@ export class GtkCheckButton extends AdwCheckBase {
252
265
  };
253
266
 
254
267
  static get observedAttributes() {
255
- return ['checked', 'active', 'indeterminate', 'disabled', 'label'];
268
+ return ['checked', 'active', 'indeterminate', 'disabled', 'label', 'group', ...FORWARDED_ARIA];
256
269
  }
257
270
 
258
271
  protected get inputType(): 'checkbox' {
259
272
  return 'checkbox';
260
273
  }
261
274
 
275
+ /**
276
+ * `Gtk.CheckButton:group`, WRITE-ONLY as in GTK (`G_PARAM_WRITABLE`, gtkcheckbutton.c:665-668):
277
+ * another check button, or its id as a projected `.blp` writes it, or `null` to leave.
278
+ */
279
+ set group(value: GtkCheckButton | string | null) {
280
+ if (typeof value === 'string') {
281
+ this.setAttribute('group', value);
282
+ return;
283
+ }
284
+ this.set_group(value);
285
+ }
286
+
287
+ /** `gtk_check_button_set_group`. */
288
+ set_group(group: GtkCheckButton | null): void {
289
+ setCheckGroup(this, group);
290
+ this.render();
291
+ group?.render();
292
+ }
293
+
294
+ get_active(): boolean {
295
+ return this.checked;
296
+ }
297
+
298
+ set_active(active: boolean): void {
299
+ this.checked = active;
300
+ }
301
+
302
+ attributeChangedCallback(name: string) {
303
+ // `set_active (TRUE)` deactivates every member of the group (gtkcheckbutton.c:955-968).
304
+ if (name === 'checked' && this.checked) {
305
+ for (const other of checkGroupNeighbours(this)) other.checked = false;
306
+ }
307
+ if (name === 'group' && this.isConnected) this._resolveGroup();
308
+ super.attributeChangedCallback(name);
309
+ }
310
+
311
+ protected onConnected(): void {
312
+ this._resolveGroup();
313
+ }
314
+
315
+ /** The `group` attribute names a check button by id, looked up once the tree is in a document. */
316
+ private _resolveGroup(): void {
317
+ const id = this.getAttribute('group');
318
+ if (id === null) return;
319
+ const root = this.getRootNode() as Document | ShadowRoot;
320
+ const found = root.getElementById?.(id) ?? document.getElementById(id);
321
+ if (!(found instanceof GtkCheckButton)) {
322
+ throw new Error(`gtk-check-button group="${id}" names no gtk-check-button in this document`);
323
+ }
324
+ this.set_group(found);
325
+ }
326
+
327
+ protected render(): void {
328
+ if (this._input === undefined) return;
329
+ super.render();
330
+ const radio = isRadioCheck(this);
331
+ this.toggleAttribute('radio', radio);
332
+ if (radio) this._input.setAttribute('role', 'radio');
333
+ else this._input.removeAttribute('role');
334
+ }
335
+
262
336
  protected activate(): void {
337
+ // The active member of a group cannot be activated off (gtkcheckbutton.c:395-396, :617-622).
338
+ if (!checkActivationFlips(this, this.checked)) {
339
+ this.render();
340
+ return;
341
+ }
263
342
  // HTML's pre-click activation steps clear `indeterminate` before the toggle, so a
264
343
  // user can always reach a definite state. GTK does NOT: `gtk_check_button_real_activate`
265
344
  // only flips `active` (gtkcheckbutton.c:617-628) and says turning the inconsistent
@@ -274,7 +353,7 @@ export class AdwRadio extends AdwCheckBase {
274
353
  private _unsubscribe: (() => void) | null = null;
275
354
 
276
355
  static get observedAttributes() {
277
- return ['checked', 'indeterminate', 'disabled', 'label', 'name', 'value'];
356
+ return ['checked', 'indeterminate', 'disabled', 'label', 'name', 'value', ...FORWARDED_ARIA];
278
357
  }
279
358
 
280
359
  protected get inputType(): 'radio' {
@@ -20,8 +20,9 @@
20
20
  // Copyright (c) The GTK Team. LGPLv2.1+.
21
21
 
22
22
  import { bindSlottedChildren } from '../slotted-children.js';
23
+ import { WidgetElement } from '../widget-element.js';
23
24
 
24
- export class GtkActionBar extends HTMLElement {
25
+ export class GtkActionBar extends WidgetElement {
25
26
  private _initialized = false;
26
27
  private _startEl: HTMLDivElement | null = null;
27
28
  private _centerEl: HTMLDivElement | null = null;
@@ -38,6 +38,7 @@
38
38
  import { glibClamp, labelYalignAlignItems } from '@gjsify/adwaita-core';
39
39
 
40
40
  import { bindSlottedChildren } from '../slotted-children.js';
41
+ import { WidgetElement } from '../widget-element.js';
41
42
 
42
43
  /** `Gtk.AspectFrame:ratio`'s pspec range and default (gtkaspectframe.c:124-125, :172-175). */
43
44
  const RATIO_MIN = 0.0001;
@@ -58,7 +59,7 @@ function normalizeRatio(value: string | null): number {
58
59
  return Number.isFinite(parsed) ? glibClamp(parsed, RATIO_MIN, RATIO_MAX) : RATIO_DEFAULT;
59
60
  }
60
61
 
61
- export class GtkAspectFrame extends HTMLElement {
62
+ export class GtkAspectFrame extends WidgetElement {
62
63
  static get observedAttributes() {
63
64
  return ['ratio', 'xalign', 'yalign', 'obey-child'];
64
65
  }
@@ -19,15 +19,35 @@
19
19
  // Children are not moved or wrapped: the element IS the flex container, so a child in the
20
20
  // light DOM is a child of the layout, which is what `gtk_box_append` means.
21
21
  //
22
+ // EXPAND IS THE COMPUTED VALUE, not the attribute: GtkBoxLayout grows a child when
23
+ // `gtk_widget_compute_expand` says so (gtkboxlayout.c:391), and that is true for a bin whose
24
+ // descendant set `hexpand` too. `compute-expand.ts` computes it; the box writes it on each
25
+ // child that authored no value of its own as `data-computed-hexpand` / `-vexpand`, which
26
+ // `_widget.scss` grows like the attribute. A MutationObserver over the box's subtree is the
27
+ // substitute for `gtk_widget_queue_compute_expand`, which walks up from any widget whose
28
+ // expand or visibility changed — so a runtime reparent or a toggled `hexpand` deep inside a
29
+ // child lands one microtask later.
30
+ //
22
31
  // Reference: refs/gtk/gtk/gtkbox.c (the three properties, the `box` CSS name)
23
32
  // Copyright (c) The GTK Team. LGPLv2.1+.
24
33
 
25
34
  import { normalizeBoxOrientation, normalizeBoxSpacing, type BoxOrientation } from '@gjsify/adwaita-core';
35
+ import { WidgetElement } from '../widget-element.js';
36
+
37
+ import { computeExpand, explicitExpand, type ExpandOrientation } from '../compute-expand.js';
26
38
 
27
39
  /** The attributes that carry a property — also the `notify::` roster. */
28
40
  const PROPERTY_ATTRIBUTES = ['orientation', 'spacing', 'homogeneous'] as const;
29
41
 
30
- export class GtkBox extends HTMLElement {
42
+ /** The marker per axis a child carries while its computed expand is true. */
43
+ const COMPUTED_EXPAND: Record<ExpandOrientation, string> = {
44
+ horizontal: 'data-computed-hexpand',
45
+ vertical: 'data-computed-vexpand',
46
+ };
47
+
48
+ export class GtkBox extends WidgetElement {
49
+ private _expandObserver: MutationObserver | null = null;
50
+
31
51
  static get observedAttributes() {
32
52
  return [...PROPERTY_ATTRIBUTES];
33
53
  }
@@ -61,6 +81,22 @@ export class GtkBox extends HTMLElement {
61
81
 
62
82
  connectedCallback() {
63
83
  this._sync();
84
+ this._syncComputedExpand();
85
+ if (this._expandObserver) return;
86
+ this._expandObserver = new MutationObserver((records) => {
87
+ if (records.some(affectsExpand)) this._syncComputedExpand();
88
+ });
89
+ this._expandObserver.observe(this, {
90
+ childList: true,
91
+ subtree: true,
92
+ attributes: true,
93
+ attributeFilter: ['hexpand', 'vexpand', 'hidden'],
94
+ });
95
+ }
96
+
97
+ disconnectedCallback() {
98
+ this._expandObserver?.disconnect();
99
+ this._expandObserver = null;
64
100
  }
65
101
 
66
102
  attributeChangedCallback(name: string, old: string | null, value: string | null) {
@@ -82,6 +118,25 @@ export class GtkBox extends HTMLElement {
82
118
  this.style.flexDirection = this.orientation === 'vertical' ? 'column' : 'row';
83
119
  this.style.gap = `${this.spacing}px`;
84
120
  }
121
+
122
+ private _syncComputedExpand(): void {
123
+ for (const child of this.children) {
124
+ for (const orientation of ['horizontal', 'vertical'] as const) {
125
+ const grows = explicitExpand(child, orientation) === undefined && computeExpand(child, orientation);
126
+ child.toggleAttribute(COMPUTED_EXPAND[orientation], grows);
127
+ }
128
+ }
129
+ }
130
+ }
131
+
132
+ /**
133
+ * Text rewritten inside a label (a hex dump does it every frame) adds and removes only text
134
+ * nodes; no widget came or went, so the computed expand cannot have changed.
135
+ */
136
+ function affectsExpand(record: MutationRecord): boolean {
137
+ if (record.type !== 'childList') return true;
138
+ const isElement = (node: Node): boolean => node.nodeType === Node.ELEMENT_NODE;
139
+ return [...record.addedNodes].some(isElement) || [...record.removedNodes].some(isElement);
85
140
  }
86
141
 
87
142
  customElements.define('gtk-box', GtkBox);
@@ -16,14 +16,16 @@
16
16
 
17
17
  import { buttonStyleClasses } from '@gjsify/adwaita-core';
18
18
 
19
+ import { FORWARDED_ARIA, forwardAccessibleName } from '../accessible.js';
19
20
  import { bindSlottedChildren } from '../slotted-children.js';
20
21
  import type { DispatchedSignals } from '../signals.js';
21
22
  import { createGtkImage } from './gtk-image.js';
23
+ import { TooltipElement } from '../widget-element.js';
22
24
 
23
25
  /** The boolean attributes that select a style class; the mapping lives in the core. */
24
26
  const STYLE_ATTRIBUTES = ['flat', 'suggested', 'destructive', 'circular', 'pill'] as const;
25
27
 
26
- export class GtkButton extends HTMLElement {
28
+ export class GtkButton extends TooltipElement {
27
29
  /** The GTK signals this element dispatches, each with the DOM event it arrives as (ADR 0093). */
28
30
  static readonly signals: DispatchedSignals = { clicked: 'click' };
29
31
 
@@ -47,12 +49,14 @@ export class GtkButton extends HTMLElement {
47
49
  'circular',
48
50
  'pill',
49
51
  'class',
52
+ ...FORWARDED_ARIA,
50
53
  ];
51
54
  }
52
55
 
53
56
  /**
54
- * `Gtk.Button:icon-name` and `Gtk.Widget:tooltip-text`, the GObject spellings: a class that
55
- * holds a button as a template child writes `button.icon_name = …`, which must reach the DOM.
57
+ * `Gtk.Button:icon-name`, the GObject spelling: a class that holds a button as a template
58
+ * child writes `button.icon_name = …`, which must reach the DOM. `Gtk.Widget:tooltip-text`
59
+ * comes from `TooltipElement`.
56
60
  */
57
61
  get icon_name(): string | null {
58
62
  return this.getAttribute('icon-name');
@@ -66,18 +70,6 @@ export class GtkButton extends HTMLElement {
66
70
  set iconName(value: string | null) {
67
71
  this.icon_name = value;
68
72
  }
69
- get tooltip_text(): string | null {
70
- return this.getAttribute('tooltip-text');
71
- }
72
- set tooltip_text(value: string | null) {
73
- this.reflect('tooltip-text', value);
74
- }
75
- get tooltipText(): string | null {
76
- return this.tooltip_text;
77
- }
78
- set tooltipText(value: string | null) {
79
- this.tooltip_text = value;
80
- }
81
73
 
82
74
  private reflect(attribute: string, value: string | null): void {
83
75
  if (value === null || value === undefined) this.removeAttribute(attribute);
@@ -148,13 +140,9 @@ export class GtkButton extends HTMLElement {
148
140
  const tooltip = this.getAttribute('tooltip') ?? this.getAttribute('tooltip-text');
149
141
  btn.title = tooltip ?? '';
150
142
  // An icon-only button has no text content, so screen readers would
151
- // announce it as unlabeled. Give it an accessible name — prefer the
152
- // tooltip, fall back to the symbolic icon name (WCAG 4.1.2).
153
- if (icon && !label) {
154
- btn.setAttribute('aria-label', tooltip ?? icon);
155
- } else {
156
- btn.removeAttribute('aria-label');
157
- }
143
+ // announce it as unlabeled. Give it an accessible name — the one the tree
144
+ // wrote first, then the tooltip, then the symbolic icon name (WCAG 4.1.2).
145
+ if (!forwardAccessibleName(this, btn) && icon && !label) btn.setAttribute('aria-label', tooltip ?? icon);
158
146
  btn.disabled = this.hasAttribute('disabled');
159
147
  this.decorate(btn);
160
148
  }
@@ -68,6 +68,7 @@ import {
68
68
  } from '@gjsify/adwaita-core';
69
69
 
70
70
  import { createGtkImage } from './gtk-image.js';
71
+ import { WidgetElement } from '../widget-element.js';
71
72
 
72
73
  /** The seven abbreviated day names, Sunday first — `default_abbreviated_dayname` (:745-757). */
73
74
  const DAY_NAMES = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
@@ -99,7 +100,7 @@ const ARROWS: readonly { step: AdwCalendarStep; icon: string; tooltip: string }[
99
100
  /** The arrow a cell's disabled state keys off — `calendar_update_navigation_buttons` (:1055-1084). */
100
101
  type ArrowName = 'previousMonth' | 'nextMonth' | 'previousYear' | 'nextYear';
101
102
 
102
- export class GtkCalendar extends HTMLElement {
103
+ export class GtkCalendar extends WidgetElement {
103
104
  private _headerEl!: HTMLDivElement;
104
105
  private _monthEl!: HTMLSpanElement;
105
106
  private _yearEl!: HTMLSpanElement;
@@ -41,6 +41,7 @@
41
41
  import { labelYalignAlignItems } from '@gjsify/adwaita-core';
42
42
 
43
43
  import { bindSlottedChildren } from '../slotted-children.js';
44
+ import { WidgetElement } from '../widget-element.js';
44
45
 
45
46
  /** `Gtk.BaselinePosition`'s three nicks, in the order GTK measures them (gtkcenterbox.c:267-271). */
46
47
  const BASELINE_POSITIONS = { top: 0, center: 0.5, bottom: 1 } as const;
@@ -51,7 +52,7 @@ export type BaselinePosition = keyof typeof BASELINE_POSITIONS;
51
52
  const SHRINK_FIRST = 100;
52
53
  const SHRINK_LAST = 1;
53
54
 
54
- export class GtkCenterBox extends HTMLElement {
55
+ export class GtkCenterBox extends WidgetElement {
55
56
  static get observedAttributes() {
56
57
  return ['baseline-position', 'shrink-center-last'];
57
58
  }
@@ -37,6 +37,7 @@
37
37
  // Reference: refs/libadwaita/src/stylesheet/widgets/_linked.scss:6 (`colorbutton > button`)
38
38
  // Copyright (c) GNOME contributors (libadwaita). LGPLv2.1+.
39
39
  // Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
40
+ import { WidgetElement } from '../widget-element.js';
40
41
 
41
42
  /** A `GdkRGBA` — the four channels of `GtkColorDialogButton:rgba`, each 0…1. */
42
43
  export interface GdkRgbaValue {
@@ -62,7 +63,7 @@ export interface ColorDialogParameters {
62
63
  /** `gtk_color_dialog_button_init`'s own colour: `{ 0.75, 0.25, 0.25, 1.0 }` (:170). */
63
64
  const INITIAL_RGBA: GdkRgbaValue = { red: 0.75, green: 0.25, blue: 0.25, alpha: 1 };
64
65
 
65
- export class GtkColorDialogButton extends HTMLElement {
66
+ export class GtkColorDialogButton extends WidgetElement {
66
67
  private _buttonEl!: HTMLButtonElement;
67
68
  private _swatchEl!: HTMLSpanElement;
68
69
  private _inputEl!: HTMLInputElement;
@@ -54,6 +54,7 @@
54
54
  // Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
55
55
 
56
56
  import { bindSlottedChildren } from '../slotted-children.js';
57
+ import { WidgetElement } from '../widget-element.js';
57
58
 
58
59
  /** The `rgba()` string a `GdkRGBA` value paints, as the colour swatch shows it. */
59
60
  interface Rgba {
@@ -66,7 +67,7 @@ interface Rgba {
66
67
  /** One icon per drag operation, keyed on the `dataTransfer` a browser gives per drag. */
67
68
  const ICON_BY_DRAG = new WeakMap<DataTransfer, GtkDragIcon>();
68
69
 
69
- export class GtkDragIcon extends HTMLElement {
70
+ export class GtkDragIcon extends WidgetElement {
70
71
  private _pointerX = 0;
71
72
  private _pointerY = 0;
72
73
  private _dragging = false;
@@ -53,6 +53,7 @@
53
53
  // Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
54
54
 
55
55
  import { glibClamp } from '@gjsify/adwaita-core';
56
+ import { WidgetElement } from '../widget-element.js';
56
57
 
57
58
  /**
58
59
  * `GtkDrawingAreaDrawFunc` with the `user_data` / `destroy` pair dropped — see the header.
@@ -78,7 +79,7 @@ function intAttribute(element: HTMLElement, name: string): number {
78
79
  return Number.isFinite(raw) ? raw : 0;
79
80
  }
80
81
 
81
- export class GtkDrawingArea extends HTMLElement {
82
+ export class GtkDrawingArea extends WidgetElement {
82
83
  private _canvas!: HTMLCanvasElement;
83
84
  private _context: CanvasRenderingContext2D | null = null;
84
85
  private _initialized = false;
@@ -75,6 +75,7 @@ import type { DispatchedSignals } from '../signals.js';
75
75
  import { stringListSlot } from '../string-list-slot.js';
76
76
 
77
77
  import { createGtkImage } from './gtk-image.js';
78
+ import { WidgetElement } from '../widget-element.js';
78
79
 
79
80
  /**
80
81
  * A dropdown option — `value` is the stable id, `label` the shown text. An alias of
@@ -83,7 +84,7 @@ import { createGtkImage } from './gtk-image.js';
83
84
  */
84
85
  export type GtkDropDownOption = AdwComboOption;
85
86
 
86
- export class GtkDropDown extends HTMLElement {
87
+ export class GtkDropDown extends WidgetElement {
87
88
  /** The GTK signals this element dispatches, each with the DOM event it arrives as (ADR 0093). */
88
89
  static readonly signals: DispatchedSignals = {
89
90
  'notify::selected': 'notify::selected',
@@ -38,11 +38,12 @@
38
38
  // (`label {}`, `editablelabel > stack > text`)
39
39
  // Copyright (c) The GTK Team, GNOME contributors. LGPLv2.1+.
40
40
  // Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
41
+ import { WidgetElement } from '../widget-element.js';
41
42
 
42
43
  /** The C's grace period between a focus leaving the widget and the commit it triggers. */
43
44
  const FOCUS_OUT_GRACE_MS = 100;
44
45
 
45
- export class GtkEditableLabel extends HTMLElement {
46
+ export class GtkEditableLabel extends WidgetElement {
46
47
  private _label!: HTMLSpanElement;
47
48
  private _entry!: HTMLInputElement;
48
49
  private _initialized = false;
@@ -23,8 +23,9 @@
23
23
  import { ENTRY_ROW_MAX_LENGTH_LIMIT, clampEntryText, entryTextLength } from '@gjsify/adwaita-core';
24
24
 
25
25
  import type { DispatchedSignals } from '../signals.js';
26
+ import { WidgetElement } from '../widget-element.js';
26
27
 
27
- export class GtkEntry extends HTMLElement {
28
+ export class GtkEntry extends WidgetElement {
28
29
  /**
29
30
  * `protected`, not `private`: `GtkPasswordEntry` and `GtkSearchEntry` subclass this
30
31
  * element and restyle or wrap the very input it builds (the password field's Caps Lock
@@ -78,6 +78,7 @@ import { attachRowActivation } from './row-activation.js';
78
78
  // elided by TypeScript and take the `customElements.define` with it.
79
79
  import './gtk-label.js';
80
80
  import type { GtkLabel } from './gtk-label.js';
81
+ import { WidgetElement } from '../widget-element.js';
81
82
 
82
83
  /** `expander { -gtk-icon-source: -gtk-icontheme('pan-end-symbolic') }` (_expanders.scss). */
83
84
  const ARROW_ICON = 'pan-end';
@@ -85,7 +86,7 @@ const ARROW_ICON = 'pan-end';
85
86
  /** Stable ids for the `aria-controls` relation, which GTK sets on the child itself. */
86
87
  let labelChildCounter = 0;
87
88
 
88
- export class GtkExpander extends HTMLElement {
89
+ export class GtkExpander extends WidgetElement {
89
90
  private _box!: HTMLDivElement;
90
91
  private _titleEl!: HTMLDivElement;
91
92
  private _arrowEl!: HTMLElement;
@@ -32,8 +32,9 @@
32
32
  // Reference: refs/gtk/gtk/gtkfixedlayout.c:224-300
33
33
  // Copyright (c) The GTK Team. LGPLv2.1+.
34
34
  // Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
35
+ import { WidgetElement } from '../widget-element.js';
35
36
 
36
- export class GtkFixed extends HTMLElement {
37
+ export class GtkFixed extends WidgetElement {
37
38
  private _resize: ResizeObserver | null = null;
38
39
  private _mutations: MutationObserver | null = null;
39
40
 
@@ -26,8 +26,9 @@
26
26
  // Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
27
27
 
28
28
  import { bindSlottedChildren } from '../slotted-children.js';
29
+ import { WidgetElement } from '../widget-element.js';
29
30
 
30
- export class GtkFlowBoxChild extends HTMLElement {
31
+ export class GtkFlowBoxChild extends WidgetElement {
31
32
  private _contentsEl!: HTMLDivElement;
32
33
  private _initialized = false;
33
34
 
@@ -66,6 +66,7 @@ import { attachRovingFocus } from './roving-focus.js';
66
66
  // `gtk-list-box.ts` states at its own: a combined import would be elided and take the
67
67
  // registration with it.
68
68
  import './gtk-flow-box-child.js';
69
+ import { WidgetElement } from '../widget-element.js';
69
70
 
70
71
  /** `GtkFlowBox:max-children-per-line`'s default — `DEFAULT_MAX_CHILDREN_PER_LINE` (:728). */
71
72
  export const ADW_FLOW_BOX_MAX_CHILDREN_PER_LINE = 7;
@@ -73,7 +74,7 @@ export const ADW_FLOW_BOX_MAX_CHILDREN_PER_LINE = 7;
73
74
  /** `GtkFlowBox:orientation` — HORIZONTAL by default here, unlike a `GtkListBase` (:3981). */
74
75
  export type AdwFlowBoxOrientation = 'horizontal' | 'vertical';
75
76
 
76
- export class GtkFlowBox extends HTMLElement {
77
+ export class GtkFlowBox extends WidgetElement {
77
78
  private _children: GtkFlowBoxChild[] = [];
78
79
  private _selection: number[] = [];
79
80
  /** `priv->selected_child`, `-1` for the C's NULL. */
@@ -71,6 +71,7 @@ import './gtk-popover.js';
71
71
  import type { GtkPopover } from './gtk-popover.js';
72
72
 
73
73
  import './gtk-separator.js';
74
+ import { WidgetElement } from '../widget-element.js';
74
75
 
75
76
  /** `GtkFontLevel`'s four values, under the nicks a string property carries. */
76
77
  export type FontLevel = 'family' | 'face' | 'font' | 'features';
@@ -103,7 +104,7 @@ const FACE_GRID: readonly { weight: number; slant: PangoFontDescription['slant']
103
104
  { weight: 700, slant: 'italic' },
104
105
  ];
105
106
 
106
- export class GtkFontDialogButton extends HTMLElement {
107
+ export class GtkFontDialogButton extends WidgetElement {
107
108
  private _buttonEl!: HTMLButtonElement;
108
109
  private _labelEl!: HTMLSpanElement;
109
110
  private _sizeBoxEl!: HTMLSpanElement;
@@ -32,6 +32,7 @@
32
32
  import { glibClamp, labelYalignAlignItems } from '@gjsify/adwaita-core';
33
33
 
34
34
  import { bindSlottedChildren } from '../slotted-children.js';
35
+ import { WidgetElement } from '../widget-element.js';
35
36
 
36
37
  /** `Gtk.Frame:label-xalign`'s pspec default (gtkframe.c:180-183, and `:253`). */
37
38
  const LABEL_XALIGN_DEFAULT = 0;
@@ -42,7 +43,7 @@ function normalizeLabelXalign(value: string | null): number {
42
43
  return Number.isFinite(parsed) ? glibClamp(parsed, 0, 1) : LABEL_XALIGN_DEFAULT;
43
44
  }
44
45
 
45
- export class GtkFrame extends HTMLElement {
46
+ export class GtkFrame extends WidgetElement {
46
47
  private _mutations: MutationObserver | null = null;
47
48
 
48
49
  static get observedAttributes() {
@@ -58,6 +58,7 @@
58
58
  // Reference: refs/gtk/gtk/gtkglarea.c
59
59
  // Copyright (c) The GTK Team. LGPLv2.1+.
60
60
  // Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
61
+ import { WidgetElement } from '../widget-element.js';
61
62
 
62
63
  /** `GdkGLAPI`'s nicks, as `GdkGLAPINickSet` spells them. */
63
64
  const APIS = ['gl', 'gles'] as const;
@@ -85,7 +86,7 @@ function booleanAttribute(element: HTMLElement, name: string, fallback: boolean)
85
86
  return raw !== 'false' && raw !== '0';
86
87
  }
87
88
 
88
- export class GtkGLArea extends HTMLElement {
89
+ export class GtkGLArea extends WidgetElement {
89
90
  private _canvas!: HTMLCanvasElement;
90
91
  private _messageEl: HTMLDivElement | null = null;
91
92
  private _initialized = false;
@@ -42,6 +42,7 @@
42
42
  // Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
43
43
 
44
44
  import { bindSlottedChildren } from '../slotted-children.js';
45
+ import { WidgetElement } from '../widget-element.js';
45
46
 
46
47
  /** `GtkGraphicsOffloadEnabled`, spelled as the GIR's enum nicks. */
47
48
  type OffloadEnabled = 'enabled' | 'disabled';
@@ -52,7 +53,7 @@ function booleanAttribute(element: HTMLElement, name: string, fallback: boolean)
52
53
  return raw !== 'false' && raw !== '0';
53
54
  }
54
55
 
55
- export class GtkGraphicsOffload extends HTMLElement {
56
+ export class GtkGraphicsOffload extends WidgetElement {
56
57
  private _childEl!: HTMLDivElement;
57
58
  private _initialized = false;
58
59