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

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
@@ -20,7 +20,7 @@
20
20
  // properties of the same name, hyphenated):
21
21
  // application-name the application's display name (shown as a title-1)
22
22
  // application-icon an icon name, by convention the application ID; drawn in
23
- // colour once `registerColorIcon(id, …)` registered it, else
23
+ // colour from the app's GResource icons (ADR 0116), else
24
24
  // as a symbolic glyph or `image-missing` (`<gtk-image>`'s
25
25
  // lookup); absent one, no icon is drawn
26
26
  // developer-name the developer / vendor line below the name
@@ -34,16 +34,22 @@
34
34
  // license the license text/name (Legal page); with a `license-url`
35
35
  // the name becomes a link
36
36
  // license-url a URL the license name links to
37
+ // release-notes AppStream release-notes markup — a What's New row + page,
38
+ // the buffer from the core's `releaseNotesBuffer`
39
+ // release-notes-version the version the What's New heading names, else `version`
40
+ // debug-info an opaque blob — a Troubleshooting row + page with Copy Text
37
41
  // open (boolean) whether the dialog is presented
38
42
  //
39
43
  // List-valued credits are set via properties (string arrays), mirroring the
40
44
  // AdwAboutDialog `developers` / `designers` / `artists` / `documenters` properties
41
45
  // — entries may be `Name`, `Name <email>` or `Name https://url`, parsed by the
42
- // core's `parseCreditPerson` (`parse_person`).
46
+ // core's `parseCreditPerson` (`parse_person`). `add_link (title, url)` appends a
47
+ // Details-page link row, as on GTK.
43
48
  //
44
- // NOT implemented here, so the core derivations see them empty: `release-notes` +
45
- // the What's New page, `debug-info` + the Troubleshooting page, `add_link`,
46
- // `add_credit_section`, `translator-credits` and the Acknowledgements page.
49
+ // NOT implemented here, so the core derivations see them empty: `add_credit_section`,
50
+ // `translator-credits`, the Acknowledgements page, and the debug page's "Save As…"
51
+ // button (`debug-info-filename`), which needs a file dialog. `new_from_appdata` is
52
+ // refused by name: it needs an AppStream parser.
47
53
  //
48
54
  // Events (CustomEvent, bubbles): `notify::open` (detail `{ open }`), `closed`, and
49
55
  // `activate-link` (detail `{ uri }`, CANCELABLE — the signal's `true_handled`
@@ -63,21 +69,29 @@ import {
63
69
  ADW_ABOUT_DIALOG_LABELS,
64
70
  type AdwCreditPerson,
65
71
  GTK_LICENSE,
72
+ type ReleaseNotesSegment,
73
+ Toast,
66
74
  aboutDialogVisibility,
67
75
  creditsSections,
68
76
  legalSectionVisible,
77
+ refuseNewFromAppdata,
78
+ releaseNotesBuffer,
69
79
  stripMnemonic,
70
80
  } from '@gjsify/adwaita-core';
71
81
 
82
+ import { webClipboardHost } from '../clipboard-host.js';
83
+ import type { AdwToastOverlay } from './adw-toast-overlay.js';
84
+ import './adw-toast-overlay.js';
72
85
  import { createGtkImage } from './gtk-image.js';
73
86
  import { AdwModalSurface } from './modal-surface.js';
87
+ import { WidgetElement } from '../widget-element.js';
74
88
 
75
89
  /** A template label with its mnemonic marker removed — this renderer has no accelerator layer. */
76
90
  function rowLabel(key: keyof typeof ADW_ABOUT_DIALOG_LABELS): string {
77
91
  return stripMnemonic(ADW_ABOUT_DIALOG_LABELS[key]);
78
92
  }
79
93
 
80
- export class AdwAboutDialog extends HTMLElement {
94
+ export class AdwAboutDialog extends WidgetElement {
81
95
  private _initialized = false;
82
96
 
83
97
  // Layout nodes (rebuilt from attributes on each render).
@@ -94,6 +108,15 @@ export class AdwAboutDialog extends HTMLElement {
94
108
  private _artists: string[] = [];
95
109
  private _documenters: string[] = [];
96
110
 
111
+ /** `add_link` rows, in order; `has_custom_links` latches with the first. */
112
+ private _links: { title: string; url: string }[] = [];
113
+ /**
114
+ * The What's New buffer. Only the two release-notes setters rebuild it, never
115
+ * `version` (`update_release_notes` is called from those two alone).
116
+ */
117
+ private _releaseNotesSegments: ReleaseNotesSegment[] = [];
118
+ private _toastOverlay!: AdwToastOverlay;
119
+
97
120
  static get observedAttributes() {
98
121
  return [
99
122
  'application-name',
@@ -107,10 +130,18 @@ export class AdwAboutDialog extends HTMLElement {
107
130
  'copyright',
108
131
  'license',
109
132
  'license-url',
133
+ 'release-notes',
134
+ 'release-notes-version',
135
+ 'debug-info',
110
136
  'open',
111
137
  ];
112
138
  }
113
139
 
140
+ /** `adw_about_dialog_new_from_appdata`, refused by name. */
141
+ static new_from_appdata(_resourcePath: string, _releaseNotesVersion?: string | null): never {
142
+ refuseNewFromAppdata();
143
+ }
144
+
114
145
  get applicationName(): string {
115
146
  return this.getAttribute('application-name') ?? '';
116
147
  }
@@ -199,6 +230,36 @@ export class AdwAboutDialog extends HTMLElement {
199
230
  this.setAttribute('license-url', value);
200
231
  }
201
232
 
233
+ get releaseNotes(): string {
234
+ return this.getAttribute('release-notes') ?? '';
235
+ }
236
+
237
+ set releaseNotes(value: string) {
238
+ this.setAttribute('release-notes', value);
239
+ }
240
+
241
+ get releaseNotesVersion(): string {
242
+ return this.getAttribute('release-notes-version') ?? '';
243
+ }
244
+
245
+ set releaseNotesVersion(value: string) {
246
+ this.setAttribute('release-notes-version', value);
247
+ }
248
+
249
+ get debugInfo(): string {
250
+ return this.getAttribute('debug-info') ?? '';
251
+ }
252
+
253
+ set debugInfo(value: string) {
254
+ this.setAttribute('debug-info', value);
255
+ }
256
+
257
+ /** `adw_about_dialog_add_link`: a Details-page link row; `_` marks a mnemonic. */
258
+ add_link(title: string, url: string): void {
259
+ this._links.push({ title, url });
260
+ if (this._initialized) this._render();
261
+ }
262
+
202
263
  get open(): boolean {
203
264
  return this.hasAttribute('open');
204
265
  }
@@ -269,6 +330,11 @@ export class AdwAboutDialog extends HTMLElement {
269
330
  // revealer shows it separately in GTK.
270
331
  this._sheetEl.setAttribute('aria-label', ADW_ABOUT_DIALOG_LABELS.dialogTitle);
271
332
 
333
+ // The template's `toast_overlay`, around the navigation view: "Copied to
334
+ // clipboard" is shown inside the sheet.
335
+ this._toastOverlay = document.createElement('adw-toast-overlay') as AdwToastOverlay;
336
+ this._sheetEl.appendChild(this._toastOverlay);
337
+
272
338
  this.replaceChildren(this._scrimEl, this._sheetEl);
273
339
 
274
340
  // The role, `aria-modal`, Escape, the Tab trap and the return-focus. No
@@ -286,8 +352,19 @@ export class AdwAboutDialog extends HTMLElement {
286
352
  }
287
353
 
288
354
  attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null) {
289
- if (!this._initialized) return;
290
355
  if (oldValue === newValue) return;
356
+ // Before the guard: the heading reads `version` as it is when the NOTES change.
357
+ if (name === 'release-notes' || name === 'release-notes-version') {
358
+ this._releaseNotesSegments = releaseNotesBuffer(
359
+ {
360
+ releaseNotes: this.releaseNotes,
361
+ releaseNotesVersion: this.releaseNotesVersion,
362
+ version: this.version,
363
+ },
364
+ ADW_ABOUT_DIALOG_LABELS,
365
+ ).segments;
366
+ }
367
+ if (!this._initialized) return;
291
368
  if (name === 'open') {
292
369
  this._syncOpen();
293
370
  this.dispatchEvent(new CustomEvent('notify::open', { bubbles: true, detail: { open: this.open } }));
@@ -344,20 +421,31 @@ export class AdwAboutDialog extends HTMLElement {
344
421
  website: this.website,
345
422
  supportUrl: this.supportUrl,
346
423
  issueUrl: this.issueUrl,
424
+ debugInfo: this.debugInfo,
425
+ releaseNotes: this.releaseNotes,
426
+ hasCustomLinks: this._links.length > 0,
347
427
  hasCredits: sections.length > 0,
348
428
  hasLegal: this._hasLegal(),
349
429
  });
350
430
 
431
+ this._navView?.remove();
351
432
  this._navView = document.createElement('adw-navigation-view');
352
433
  this._navView.append(this._buildMainPage(visibility));
353
434
 
354
- // The Details page exists exactly when its row does — `details_row` is
435
+ // A subpage exists exactly when its row does — `details_row` is
355
436
  // `has_comments || show_links`, i.e. "the page has content".
437
+ if (visibility.whatsNewRow) this._navView.append(this._buildWhatsNewPage());
356
438
  if (visibility.detailsRow) this._navView.append(this._buildDetailsPage(visibility));
439
+ if (visibility.troubleshootingRow) {
440
+ this._navView.append(this._buildTroubleshootingPage(), this._buildDebugInfoPage());
441
+ }
357
442
  if (visibility.creditsRow) this._navView.append(this._buildCreditsPage(sections));
358
443
  if (visibility.legalRow) this._navView.append(this._buildLegalPage());
359
444
 
360
- this._sheetEl.replaceChildren(this._navView);
445
+ // Straight into the overlay's content box: appended to the overlay itself, the view
446
+ // is re-homed a microtask later, and that move drops the focus `present` put in it.
447
+ const content = this._toastOverlay.querySelector(':scope > .adw-toast-overlay-content');
448
+ (content ?? this._toastOverlay).appendChild(this._navView);
361
449
 
362
450
  this.classList.toggle('open', this.open);
363
451
  }
@@ -471,6 +559,9 @@ export class AdwAboutDialog extends HTMLElement {
471
559
  // support_group, credits_legal_group) — groups, not one list, and the
472
560
  // stylesheet already spaces consecutive `.adw-about-dialog-rows` apart.
473
561
  const detailsGroupRows: HTMLElement[] = [];
562
+ if (visibility.whatsNewRow) {
563
+ detailsGroupRows.push(this._buildNavRow(rowLabel('whatsNewRow'), 'whatsnew'));
564
+ }
474
565
  if (visibility.detailsRow) {
475
566
  detailsGroupRows.push(this._buildNavRow(rowLabel('detailsRow'), 'details'));
476
567
  }
@@ -485,6 +576,9 @@ export class AdwAboutDialog extends HTMLElement {
485
576
  if (visibility.issueRow) {
486
577
  supportGroupRows.push(this._buildLinkRow(rowLabel('issueRow'), this.issueUrl));
487
578
  }
579
+ if (visibility.troubleshootingRow) {
580
+ supportGroupRows.push(this._buildNavRow(rowLabel('troubleshootingRow'), 'troubleshooting'));
581
+ }
488
582
 
489
583
  const creditsLegalRows: HTMLElement[] = [];
490
584
  if (visibility.creditsRow) creditsLegalRows.push(this._buildNavRow(rowLabel('creditsRow'), 'credits'));
@@ -559,12 +653,61 @@ export class AdwAboutDialog extends HTMLElement {
559
653
  if (visibility.detailsWebsiteRow) {
560
654
  rows.push(this._buildLinkRow(rowLabel('websiteRow'), this.website));
561
655
  }
656
+ for (const link of this._links) rows.push(this._buildLinkRow(stripMnemonic(link.title), link.url));
562
657
  body.appendChild(this._buildGroup('links', rows));
563
658
  }
564
659
 
565
660
  return page;
566
661
  }
567
662
 
663
+ /** The release-notes buffer as tagged runs, white space kept (a GtkTextView). */
664
+ private _buildWhatsNewPage(): HTMLElement {
665
+ const { page, body } = this._buildPage('whatsnew', ADW_ABOUT_DIALOG_LABELS.whatsNewPage, false);
666
+ const notes = document.createElement('div');
667
+ notes.className = 'adw-about-dialog-release-notes';
668
+ for (const segment of this._releaseNotesSegments) {
669
+ const span = document.createElement('span');
670
+ if (segment.tag !== null) span.dataset['tag'] = segment.tag;
671
+ span.textContent = segment.text;
672
+ notes.appendChild(span);
673
+ }
674
+ body.appendChild(notes);
675
+ return page;
676
+ }
677
+
678
+ private _buildTroubleshootingPage(): HTMLElement {
679
+ const { page, body } = this._buildPage('troubleshooting', ADW_ABOUT_DIALOG_LABELS.troubleshootingPage, false);
680
+ const intro = document.createElement('p');
681
+ intro.className = 'adw-about-dialog-comments';
682
+ intro.textContent = ADW_ABOUT_DIALOG_LABELS.troubleshootingIntro;
683
+ body.append(intro, this._buildGroup(null, [this._buildNavRow(rowLabel('debugInfoRow'), 'debuginfo')]));
684
+ return page;
685
+ }
686
+
687
+ /** The debug text and Copy Text — the `about.copy-property` action on `debug-info`. */
688
+ private _buildDebugInfoPage(): HTMLElement {
689
+ const { page, body } = this._buildPage('debuginfo', ADW_ABOUT_DIALOG_LABELS.debugInfoPage, false);
690
+ const text = document.createElement('pre');
691
+ text.className = 'adw-about-dialog-debug-info';
692
+ text.textContent = this.debugInfo;
693
+
694
+ const copy = document.createElement('button');
695
+ copy.type = 'button';
696
+ copy.className = 'adw-button pill adw-about-dialog-copy';
697
+ copy.textContent = rowLabel('copyText');
698
+ copy.addEventListener('click', () => this._copyProperty(this.debugInfo));
699
+
700
+ body.append(text, copy);
701
+ return page;
702
+ }
703
+
704
+ /** `copy_property_cb`: an empty value copies nothing and shows no toast. */
705
+ private _copyProperty(value: string): void {
706
+ if (value.length === 0) return;
707
+ void Promise.resolve(webClipboardHost.writeText(value)).catch(() => undefined);
708
+ this._toastOverlay.add_toast(new Toast({ title: ADW_ABOUT_DIALOG_LABELS.copiedToast }));
709
+ }
710
+
568
711
  private _buildLinkRow(title: string, uri: string): HTMLElement {
569
712
  const row = document.createElement('adw-action-row');
570
713
  row.setAttribute('title', title);
@@ -31,6 +31,7 @@ import { installElementApi } from '../gobject-elements.js';
31
31
  import type { DispatchedSignals } from '../signals.js';
32
32
  import { type AdwRowActivation, attachRowActivation } from './row-activation.js';
33
33
  import { applyRowLineClamp, parseRowLinesAttribute } from '../row-line-clamp.js';
34
+ import { TooltipElement } from '../widget-element.js';
34
35
 
35
36
  /**
36
37
  * Attributes whose change means the activatable widget's sensitivity may have
@@ -45,7 +46,7 @@ function isSensitive(widget: HTMLElement): boolean {
45
46
  return widget.getAttribute('aria-disabled') !== 'true';
46
47
  }
47
48
 
48
- export class AdwActionRow extends HTMLElement {
49
+ export class AdwActionRow extends TooltipElement {
49
50
  /** The GTK signals this element dispatches, each with the DOM event it arrives as (ADR 0093). */
50
51
  static readonly signals: DispatchedSignals = { activated: 'activated' };
51
52
 
@@ -75,6 +75,7 @@ import { bindEmptySections } from '../empty-sections.js';
75
75
  import { bindSlottedChildren } from '../slotted-children.js';
76
76
  import { AdwModalSurface } from './modal-surface.js';
77
77
  import { booleanAttribute } from '../attributes.js';
78
+ import { WidgetElement } from '../widget-element.js';
78
79
 
79
80
  /** Response button appearance — mirrors Adw.ResponseAppearance. */
80
81
  export type { AdwResponseAppearance } from '@gjsify/adwaita-core';
@@ -85,7 +86,7 @@ export type { AdwResponseAppearance } from '@gjsify/adwaita-core';
85
86
  * `appearance="suggested|destructive"` and `enabled="false"` mirror the
86
87
  * GtkBuildable `<response>` element attributes. Consumed at connect time.
87
88
  */
88
- export class AdwAlertResponse extends HTMLElement {
89
+ export class AdwAlertResponse extends WidgetElement {
89
90
  static get observedAttributes() {
90
91
  return ['id', 'appearance', 'enabled'];
91
92
  }
@@ -107,7 +108,7 @@ export interface AdwAlertDialogProps {
107
108
  preferWideLayout?: boolean;
108
109
  }
109
110
 
110
- export class AdwAlertDialog extends HTMLElement {
111
+ export class AdwAlertDialog extends WidgetElement {
111
112
  /** The GTK signals this element dispatches, each with the DOM event it arrives as (ADR 0093). */
112
113
  static readonly signals: DispatchedSignals = {
113
114
  response: 'response',
@@ -29,8 +29,9 @@ import {
29
29
  } from '@gjsify/adwaita-core';
30
30
 
31
31
  import { type GtkImage, createGtkImage } from './gtk-image.js';
32
+ import { WidgetElement } from '../widget-element.js';
32
33
 
33
- export class AdwAvatar extends HTMLElement {
34
+ export class AdwAvatar extends WidgetElement {
34
35
  private _textEl!: HTMLSpanElement;
35
36
  private _iconEl!: GtkImage;
36
37
  private _imageEl!: HTMLImageElement;
@@ -21,8 +21,9 @@ import {
21
21
  } from '@gjsify/adwaita-core';
22
22
 
23
23
  import { renderPangoMarkup } from '../pango-markup.js';
24
+ import { WidgetElement } from '../widget-element.js';
24
25
 
25
- export class AdwBanner extends HTMLElement {
26
+ export class AdwBanner extends WidgetElement {
26
27
  private _titleEl!: HTMLSpanElement;
27
28
  private _button!: HTMLButtonElement;
28
29
  private _initialized = false;
@@ -31,8 +31,9 @@
31
31
  // Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
32
32
 
33
33
  import { bindSlottedChildren } from '../slotted-children.js';
34
+ import { WidgetElement } from '../widget-element.js';
34
35
 
35
- export class AdwBin extends HTMLElement {
36
+ export class AdwBin extends WidgetElement {
36
37
  private _observer: MutationObserver | null = null;
37
38
 
38
39
  /** `Adw.Bin:child` — the one child, or `null`. The last one appended is the one that stays. */
@@ -66,17 +66,18 @@ import type {
66
66
  import { bindSlottedChildren, type AdwSlot } from '../slotted-children.js';
67
67
  import { installElementApi } from '../gobject-elements.js';
68
68
  import type { DispatchedSignals } from '../signals.js';
69
+ import { WidgetElement } from '../widget-element.js';
69
70
 
70
71
  /** The persistent content. Child of <adw-bottom-sheet>; consumed at connect time. */
71
- export class AdwBottomSheetContent extends HTMLElement {}
72
+ export class AdwBottomSheetContent extends WidgetElement {}
72
73
 
73
74
  /** The slide-up sheet. Child of <adw-bottom-sheet>; consumed at connect time. */
74
- export class AdwBottomSheetSheet extends HTMLElement {}
75
+ export class AdwBottomSheetSheet extends WidgetElement {}
75
76
 
76
77
  /** The collapsed bar the sheet morphs out of. Child of <adw-bottom-sheet>. */
77
- export class AdwBottomSheetBottomBar extends HTMLElement {}
78
+ export class AdwBottomSheetBottomBar extends WidgetElement {}
78
79
 
79
- export class AdwBottomSheet extends HTMLElement {
80
+ export class AdwBottomSheet extends WidgetElement {
80
81
  /** The GTK signals this element dispatches, each with the DOM event it arrives as (ADR 0093). */
81
82
  static readonly signals: DispatchedSignals = { 'notify::open': 'notify::open' };
82
83
 
@@ -68,6 +68,7 @@ import type { BreakpointSetter } from '@gjsify/adwaita-core';
68
68
 
69
69
  import { observeAdaptiveSize } from '../breakpoints.js';
70
70
  import { bindSlottedChildren } from '../slotted-children.js';
71
+ import { WidgetElement } from '../widget-element.js';
71
72
 
72
73
  /** One authored setter, as it reads in the `breakpoints` attribute. */
73
74
  interface AuthoredSetter {
@@ -104,7 +105,7 @@ function parseBreakpoints(raw: string | null): AuthoredBreakpoint[] {
104
105
  });
105
106
  }
106
107
 
107
- export class AdwBreakpointBin extends HTMLElement {
108
+ export class AdwBreakpointBin extends WidgetElement {
108
109
  /** The C's own structure: a list of breakpoints, and at most one picked. */
109
110
  private _state = new BreakpointBinState<Element>();
110
111
  private _dispose: (() => void) | undefined;
@@ -25,6 +25,7 @@
25
25
  import { BUTTON_CONTENT_STYLE_CLASS, buttonContentIconName, buttonContentLabelText } from '@gjsify/adwaita-core';
26
26
 
27
27
  import { type GtkImage, createGtkImage } from './gtk-image.js';
28
+ import { WidgetElement } from '../widget-element.js';
28
29
 
29
30
  /**
30
31
  * What `gtk_widget_get_ancestor (…, GTK_TYPE_BUTTON)` looks like in the DOM: a native
@@ -36,7 +37,7 @@ const BUTTON_SELECTOR = 'button, .adw-button';
36
37
  /** The split-button node the class is RETARGETED to. */
37
38
  const SPLIT_BUTTON_SELECTOR = 'adw-split-button, .adw-split-button';
38
39
 
39
- export class AdwButtonContent extends HTMLElement {
40
+ export class AdwButtonContent extends WidgetElement {
40
41
  private _boxEl!: HTMLDivElement;
41
42
  private _iconEl!: GtkImage;
42
43
  private _labelEl!: HTMLSpanElement;
@@ -27,8 +27,9 @@ import { BUTTON_ROW_ACTIVATABLE, ButtonRowState } from '@gjsify/adwaita-core';
27
27
  import { applyRowTooltip } from '../row-tooltip.js';
28
28
  import { type GtkImage, createGtkImage } from './gtk-image.js';
29
29
  import { attachRowActivation } from './row-activation.js';
30
+ import { TooltipElement } from '../widget-element.js';
30
31
 
31
- export class AdwButtonRow extends HTMLElement {
32
+ export class AdwButtonRow extends TooltipElement {
32
33
  private _contentsEl!: HTMLDivElement;
33
34
  private _startIconEl!: GtkImage;
34
35
  private _endIconEl!: GtkImage;
@@ -5,8 +5,9 @@
5
5
  // Reference: refs/adwaita-web/adwaita-web/scss/_card.scss
6
6
  // Copyright (c) GNOME contributors (libadwaita). LGPLv2.1+.
7
7
  // Modifications: Implemented as Web Component for @gjsify/adwaita-web.
8
+ import { WidgetElement } from '../widget-element.js';
8
9
 
9
- export class AdwCard extends HTMLElement {
10
+ export class AdwCard extends WidgetElement {
10
11
  connectedCallback() {
11
12
  this.classList.add('adw-card');
12
13
  }
@@ -36,9 +36,10 @@ import { CarouselState, carouselClosestSnapPoint, carouselPageAllocation } from
36
36
  import type { CarouselScrollRequest, CarouselScrollSource, CarouselStateChange } from '@gjsify/adwaita-core';
37
37
 
38
38
  import { attachSwipeDrag, type AdwSwipeDrag } from './swipe-drag.js';
39
+ import { WidgetElement } from '../widget-element.js';
39
40
 
40
41
  /** Common surface an indicator binds to. The concrete element is AdwCarousel. */
41
- interface CarouselHost extends HTMLElement {
42
+ interface CarouselHost extends WidgetElement {
42
43
  readonly nPages: number;
43
44
  readonly position: number;
44
45
  /** The page the current position settles on, `-1` when empty. */
@@ -70,7 +71,7 @@ function wheelSource(event: WheelEvent): CarouselScrollSource {
70
71
  return 'mouse';
71
72
  }
72
73
 
73
- export class AdwCarousel extends HTMLElement implements CarouselHost {
74
+ export class AdwCarousel extends WidgetElement implements CarouselHost {
74
75
  private readonly _state = new CarouselState({
75
76
  // The DOM owns the scroll animation: `scrollTo` only asks, and the
76
77
  // scroll handler feeds the ramp back through `setPosition`.
@@ -103,6 +104,8 @@ export class AdwCarousel extends HTMLElement implements CarouselHost {
103
104
  private _scrollTargetId: string | null = null;
104
105
  /** The pointer-drag gesture, asked whether it owns the strip. See `_onWheel`. */
105
106
  private _drag: AdwSwipeDrag | undefined;
107
+ /** A `scroll_to` issued before the pages were adopted, run once they are. */
108
+ private _pendingScrollPage: HTMLElement | null = null;
106
109
 
107
110
  static get observedAttributes() {
108
111
  return ['allow-scroll-wheel', 'allow-mouse-drag', 'allow-long-swipes', 'interactive', 'spacing', 'position'];
@@ -272,6 +275,14 @@ export class AdwCarousel extends HTMLElement implements CarouselHost {
272
275
  // delivers attributes BEFORE `connectedCallback`, so reading it here is the
273
276
  // only way `<adw-carousel position="2">` works at all.
274
277
  this._applyAttribute('position', this.getAttribute('position'));
278
+
279
+ // Upstream defers a `scroll_to` that arrives before the first allocation to an
280
+ // idle (adw-carousel.c:1580-1595); the pages existing is the earliest this port
281
+ // can resolve one, and it lands where a declared `position` would.
282
+ const pending = this._pendingScrollPage;
283
+ this._pendingScrollPage = null;
284
+ const id = pending ? this._idOf(pending) : null;
285
+ if (id !== null) this._positionWhenMeasurable(this._state.indexOf(id));
275
286
  }
276
287
 
277
288
  attributeChangedCallback(name: string, _oldValue: string | null, newValue: string | null) {
@@ -450,6 +461,45 @@ export class AdwCarousel extends HTMLElement implements CarouselHost {
450
461
  return this._state.navigate(direction);
451
462
  }
452
463
 
464
+ /**
465
+ * `adw_carousel_scroll_to` — scroll to `widget`, one of the pages. A widget that is
466
+ * not one is refused, which is C's precondition; `animate = false` lands at once.
467
+ */
468
+ scroll_to(widget: HTMLElement, animate: boolean): void {
469
+ if (!this._initialized) {
470
+ if (widget.parentElement === this) this._pendingScrollPage = widget;
471
+ return;
472
+ }
473
+ const id = this._idOf(widget);
474
+ if (id === null) return;
475
+ this._state.scrollTo(this._state.indexOf(id), { animate });
476
+ }
477
+
478
+ /**
479
+ * `adw_carousel_get_nth_page` — the page at `n`. Past the last page C's precondition
480
+ * fails and returns NULL, so this returns `null`.
481
+ */
482
+ get_nth_page(n: number): HTMLElement | null {
483
+ if (!this._initialized) {
484
+ const declared = this.children[n];
485
+ return Number.isInteger(n) && declared instanceof HTMLElement ? declared : null;
486
+ }
487
+ if (!Number.isInteger(n) || n < 0 || n >= this._state.nPages) return null;
488
+ const id = this._state.ids[n];
489
+ const page = id === undefined ? null : this._slots.get(id)?.firstElementChild;
490
+ return page instanceof HTMLElement ? page : null;
491
+ }
492
+
493
+ /** `adw_carousel_get_n_pages`. */
494
+ get_n_pages(): number {
495
+ return this._initialized ? this._state.nPages : this.children.length;
496
+ }
497
+
498
+ /** `adw_carousel_get_position` — the {@link position} property. */
499
+ get_position(): number {
500
+ return this._state.position;
501
+ }
502
+
453
503
  private _insert(page: HTMLElement, position: number): boolean {
454
504
  const id = `page-${this._nextPageId++}`;
455
505
  if (!this._state.insertPage(id, position)) return false;
@@ -601,6 +651,15 @@ export class AdwCarousel extends HTMLElement implements CarouselHost {
601
651
  if (!this._trackEl) return;
602
652
  const distance = this._distance();
603
653
  if (!(distance > 0)) return;
654
+ // The model is already there (`adw_animation_skip`), so the offset follows at once
655
+ // and nothing waits for an arrival; a smooth scroll would feed the frames in
656
+ // between back into `position`.
657
+ if (!request.animate) {
658
+ this._pendingInteractive = null;
659
+ this._scrollTargetId = null;
660
+ this._trackEl.scrollTo({ left: request.index * distance, behavior: 'instant' });
661
+ return;
662
+ }
604
663
  this._pendingInteractive = request.interactive;
605
664
  this._scrollTargetId = this._state.ids[request.index] ?? null;
606
665
  // `offset = distance * position`, NOT `slot.offsetLeft` — that is measured from
@@ -673,7 +732,7 @@ export class AdwCarousel extends HTMLElement implements CarouselHost {
673
732
  }
674
733
  }
675
734
 
676
- abstract class AdwCarouselIndicator extends HTMLElement {
735
+ abstract class AdwCarouselIndicator extends WidgetElement {
677
736
  protected _carousel: CarouselHost | null = null;
678
737
  protected _initialized = false;
679
738
 
@@ -53,6 +53,7 @@ import {
53
53
  } from '@gjsify/adwaita-core';
54
54
 
55
55
  import { bindSlottedChildren } from '../slotted-children.js';
56
+ import { WidgetElement } from '../widget-element.js';
56
57
 
57
58
  /** `Gtk.ScrollablePolicy`'s three nicks, in enum order. */
58
59
  export type ScrollPolicy = 'automatic' | 'always' | 'never';
@@ -64,7 +65,7 @@ const POLICY_OVERFLOW: Record<ScrollPolicy, string> = {
64
65
  never: 'hidden',
65
66
  };
66
67
 
67
- export class AdwClampScrollable extends HTMLElement {
68
+ export class AdwClampScrollable extends WidgetElement {
68
69
  private _resize: ResizeObserver | null = null;
69
70
  private _mutations: MutationObserver | null = null;
70
71
 
@@ -27,8 +27,9 @@
27
27
  import { ADW_CLAMP_DEFAULTS, ADW_CLAMP_SIZE_CLASSES, clampAllocate, normalizeClampSize } from '@gjsify/adwaita-core';
28
28
 
29
29
  import { bindSlottedChildren } from '../slotted-children.js';
30
+ import { WidgetElement } from '../widget-element.js';
30
31
 
31
- export class AdwClamp extends HTMLElement {
32
+ export class AdwClamp extends WidgetElement {
32
33
  private _resize: ResizeObserver | null = null;
33
34
  private _mutations: MutationObserver | null = null;
34
35
 
@@ -65,8 +65,9 @@ import { applyRowTooltip } from '../row-tooltip.js';
65
65
  import { bindSlottedChildren } from '../slotted-children.js';
66
66
  import { stringListSlot } from '../string-list-slot.js';
67
67
  import { applyRowLineClamp, parseRowLinesAttribute } from '../row-line-clamp.js';
68
+ import { TooltipElement } from '../widget-element.js';
68
69
 
69
- export class AdwComboRow extends HTMLElement {
70
+ export class AdwComboRow extends TooltipElement {
70
71
  private _select!: HTMLSelectElement;
71
72
  private _valueEl!: HTMLSpanElement;
72
73
  /** The label column — kept for `tooltip-text`, which the browser reads off a PART. */
@@ -92,6 +93,11 @@ export class AdwComboRow extends HTMLElement {
92
93
  this._state.setModel(normalizeComboOptions(value));
93
94
  }
94
95
 
96
+ /** `adw_combo_row_set_model`. */
97
+ set_model(model: AdwListModelInput | null): void {
98
+ this.model = model ?? [];
99
+ }
100
+
95
101
  /**
96
102
  * The selected index (Adw.ComboRow:selected). PERMISSIVE: an index past the end is
97
103
  * accepted and reads back with an empty {@link selectedValue}, mirroring the `guint`
@@ -107,6 +113,14 @@ export class AdwComboRow extends HTMLElement {
107
113
  this.setAttribute('selected', String(value));
108
114
  }
109
115
 
116
+ get_selected(): number {
117
+ return this.selected;
118
+ }
119
+
120
+ set_selected(position: number): void {
121
+ this.selected = position;
122
+ }
123
+
110
124
  /**
111
125
  * The selected option's `value`, or '' when nothing is selected (Adw.ComboRow:selected-item).
112
126
  *
@@ -72,6 +72,7 @@ import {
72
72
  normalizeDataGridVariant,
73
73
  } from '@gjsify/adwaita-core';
74
74
  import type { AdwDataGridColumn, AdwDataGridRow } from '@gjsify/adwaita-core';
75
+ import { WidgetElement } from '../widget-element.js';
75
76
 
76
77
  export type {
77
78
  AdwDataGridAlign,
@@ -81,7 +82,7 @@ export type {
81
82
  AdwDataGridRowVariant,
82
83
  } from '@gjsify/adwaita-core';
83
84
 
84
- export class AdwDataGrid extends HTMLElement {
85
+ export class AdwDataGrid extends WidgetElement {
85
86
  private _captionEl!: HTMLDivElement;
86
87
  private _scrollEl!: HTMLDivElement;
87
88
  private _tableEl!: HTMLDivElement;