@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,303 @@
1
+ // <gtk-drawing-area> — a blank widget you draw on. It owns no painting of its own: it
2
+ // carries a SIZE, a CALLBACK and a resize notification, and everything you can see is
3
+ // what the callback painted.
4
+ //
5
+ // WHAT THE C ACTUALLY DOES, IN FOUR PLACES (gtkdrawingarea.c):
6
+ //
7
+ // · `gtk_drawing_area_measure` (:210-231) returns `content_width` / `content_height`
8
+ // as BOTH the minimum and the natural size of the matching orientation. A zero — the
9
+ // default — means the widget has no intrinsic size on that axis at all, so the parent
10
+ // decides; a non-zero one is a floor the parent cannot allocate below, not a fixed
11
+ // size. `_drawing.scss` spells that pair as `width`/`min-width`.
12
+ // · `gtk_drawing_area_size_allocate` (:233-238) does nothing but emit `::resize` with
13
+ // the new width and height. That is the whole allocation path: no re-measure, no
14
+ // re-layout, one signal.
15
+ // · `gtk_drawing_area_snapshot` (:240-267) returns early WITHOUT calling the draw
16
+ // function when none is set, appends a cairo region the size of the allocation and
17
+ // calls it with `width`/`height` from the allocation, not from the properties.
18
+ // · `gtk_drawing_area_set_draw_func` (:474-491) runs the previous `destroy` notifier,
19
+ // stores the triple and calls `gtk_widget_queue_draw`, so installing a function
20
+ // repaints. `set_draw_func(NULL)` is therefore a documented way to blank the widget.
21
+ //
22
+ // THE CALLBACK. GTK's is `(area, cr, width, height, user_data)`. The `user_data` /
23
+ // `destroy` pair is what this renderer has no use for — a JS closure holds its own
24
+ // captures and the garbage collector is the notifier — so the browser signature drops
25
+ // both and the element keeps the first four in the C's order. Replacing a function is a
26
+ // plain assignment; there is no second copy to leak, which is the only thing the
27
+ // `destroy` notifier is for.
28
+ //
29
+ // LOGICAL PIXELS, ONCE. The cairo region GTK hands the callback is in the widget's LOGICAL
30
+ // size (`:248-262` — the allocation, unscaled), and GTK scales the surface at composite
31
+ // time. A `<canvas>` is a PIXEL buffer whose `width`/`height` attributes are its backing
32
+ // store, so the element multiplies that by the device pixel ratio and scales the 2D
33
+ // context by the same factor before calling in. The callback still draws in logical
34
+ // pixels, which is the property an application port depends on.
35
+ //
36
+ // EACH FRAME STARTS EMPTY. GTK's renderer builds every frame into a fresh surface, so a
37
+ // draw function that paints a background covers what was there; a canvas keeps its pixels
38
+ // between frames, so the element clears the allocation before calling in. Without that a
39
+ // second frame would composite over the first — the one difference a naive port shows and
40
+ // the reason this is written down rather than left to the reader.
41
+ //
42
+ // A11Y: no role, and none invented. GtkDrawingArea is a blank widget with no accessible
43
+ // role of its own, so naming one would add an interface GTK does not have. A drawing
44
+ // area that shows text owes the screen reader a label from the application, which an
45
+ // ordinary `aria-label` on the element already does.
46
+ //
47
+ // Events: `resize` (CustomEvent, bubbles, detail `{ width, height }` — GtkDrawingArea's
48
+ // own signal, gtkdrawingarea.c:311-328) on the first allocation and every change of one,
49
+ // and `notify::<prop>` (CustomEvent, bubbles, detail `{ <prop>: value }`) on a real change.
50
+ //
51
+ // Reference: refs/gtk/gtk/gtkdrawingarea.c
52
+ // Copyright (c) The GTK Team. LGPLv2.1+.
53
+ // Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
54
+
55
+ import { glibClamp } from '@gjsify/adwaita-core';
56
+
57
+ /**
58
+ * `GtkDrawingAreaDrawFunc` with the `user_data` / `destroy` pair dropped — see the header.
59
+ *
60
+ * @param area the drawing area being painted, as the C's first argument
61
+ * @param cr a 2D context over the whole allocation, in logical pixels
62
+ * @param width the width of the allocation — NOT of `content-width`
63
+ * @param height the height of the allocation — NOT of `content-height`
64
+ */
65
+ export type GtkDrawingAreaDrawFunc = (
66
+ area: GtkDrawingArea,
67
+ cr: CanvasRenderingContext2D,
68
+ width: number,
69
+ height: number,
70
+ ) => void;
71
+
72
+ /** `G_MAXINT`, the top of `g_param_spec_int`'s range (:288-304). */
73
+ const MAX_INT = 2147483647;
74
+
75
+ /** A missing or unparseable attribute is `0`, which is also the GIR default. */
76
+ function intAttribute(element: HTMLElement, name: string): number {
77
+ const raw = Number.parseInt(element.getAttribute(name) ?? '', 10);
78
+ return Number.isFinite(raw) ? raw : 0;
79
+ }
80
+
81
+ export class GtkDrawingArea extends HTMLElement {
82
+ private _canvas!: HTMLCanvasElement;
83
+ private _context: CanvasRenderingContext2D | null = null;
84
+ private _initialized = false;
85
+ private _drawFunc: GtkDrawingAreaDrawFunc | null = null;
86
+ /** The last allocation the draw function was called with, as `::resize` sees it. */
87
+ private _width = -1;
88
+ private _height = -1;
89
+ /** The last device pixel ratio the backing store was built for. */
90
+ private _scale = 1;
91
+ private _resize: ResizeObserver | null = null;
92
+ private _frame: number | null = null;
93
+
94
+ static get observedAttributes() {
95
+ return ['content-width', 'content-height'];
96
+ }
97
+
98
+ /** `Gtk.DrawingArea:content-width` — the minimum AND natural width. Defaults to 0. */
99
+ get contentWidth(): number {
100
+ return intAttribute(this, 'content-width');
101
+ }
102
+
103
+ set contentWidth(v: number) {
104
+ // The pspec range is 0…G_MAXINT (:290-294), so a write outside it is clamped
105
+ // rather than refused — which is what `set_property` does with the value.
106
+ this._write('content-width', String(glibClamp(Math.trunc(v) || 0, 0, MAX_INT)));
107
+ }
108
+
109
+ /** `Gtk.DrawingArea:content-height` — the minimum AND natural height. Defaults to 0. */
110
+ get contentHeight(): number {
111
+ return intAttribute(this, 'content-height');
112
+ }
113
+
114
+ set contentHeight(v: number) {
115
+ this._write('content-height', String(glibClamp(Math.trunc(v) || 0, 0, MAX_INT)));
116
+ }
117
+
118
+ /**
119
+ * Every GObject setter here returns early when the value is already right
120
+ * (gtkdrawingarea.c:373, :423), while `setAttribute` runs the reaction for a write
121
+ * that changes nothing — so the guard that makes "notify only on a real change" true
122
+ * for the numeric half is the same one `<gtk-level-bar>` uses.
123
+ */
124
+ private _write(name: string, value: string): void {
125
+ if (this.getAttribute(name) !== value) this.setAttribute(name, value);
126
+ }
127
+
128
+ /** `GtkDrawingAreaDrawFunc`, or `null` — GTK's default, which paints nothing (:251). */
129
+ get drawFunc(): GtkDrawingAreaDrawFunc | null {
130
+ return this._drawFunc;
131
+ }
132
+
133
+ set drawFunc(fn: GtkDrawingAreaDrawFunc | null) {
134
+ this.setDrawFunc(fn);
135
+ }
136
+
137
+ /**
138
+ * `gtk_drawing_area_set_draw_func` (gtkdrawingarea.c:474-491): store the function and
139
+ * `queue_draw`, which is what repaints. Passing `null` clears it, and the next
140
+ * snapshot leaves the widget blank — the C's early return at :251.
141
+ */
142
+ setDrawFunc(fn: GtkDrawingAreaDrawFunc | null): void {
143
+ this._drawFunc = fn;
144
+ this.queueDraw();
145
+ }
146
+
147
+ /**
148
+ * `gtk_widget_queue_draw` on this widget: the documented way to ask for the draw
149
+ * function to be called again (gtkdrawingarea.c:127-129).
150
+ *
151
+ * AND WHY IT IS NOT IMMEDIATE. `queue_draw` marks the window dirty and the frame clock
152
+ * draws it on the next frame, so a draw function that calls `queue_draw` keeps
153
+ * ANIMATING rather than recursing — and a 2D canvas drawn synchronously would turn the
154
+ * same application into a stack overflow. One animation frame is the browser's frame
155
+ * clock, and coalescing through it is what makes "paint from the function" a loop and
156
+ * not a crash. Several requests before the frame are one frame, as in the C.
157
+ */
158
+ queueDraw(): void {
159
+ if (!this._initialized || this._frame !== null) return;
160
+ this._frame = requestAnimationFrame(() => {
161
+ this._frame = null;
162
+ this._draw();
163
+ });
164
+ }
165
+
166
+ connectedCallback() {
167
+ if (this._initialized) {
168
+ // The teardown below released the observer on the way out, so a re-parent has
169
+ // to arm it again — see `scripts/check-adwaita-connect-rebind.mjs`.
170
+ this._observe();
171
+ return;
172
+ }
173
+ this._initialized = true;
174
+
175
+ this._canvas = document.createElement('canvas');
176
+ this._canvas.className = 'adw-drawing-area-canvas';
177
+ this._context = this._canvas.getContext('2d');
178
+ this.replaceChildren(this._canvas);
179
+ this._publishSize();
180
+ this._observe();
181
+ }
182
+
183
+ disconnectedCallback() {
184
+ this._resize?.disconnect();
185
+ this._resize = null;
186
+ if (this._frame !== null) cancelAnimationFrame(this._frame);
187
+ this._frame = null;
188
+ }
189
+
190
+ attributeChangedCallback(name: string) {
191
+ if (!this._initialized) return;
192
+ // A size property is a REQUEST, not a repaint: it changes the element's own box,
193
+ // the observer hears the allocation that follows, and the paint is redone then.
194
+ // `notify` fires either way, and the custom property the partial reads is
195
+ // republished first so the CSS floor moves with the property.
196
+ if (name === 'content-width' || name === 'content-height') this._publishSize();
197
+ this._notify(name);
198
+ if (name === 'content-width' || name === 'content-height') this.queueDraw();
199
+ }
200
+
201
+ /**
202
+ * `measure` returns one number per axis as the minimum AND the natural size
203
+ * (gtkdrawingarea.c:210-231), and CSS has a property for each half — so the element
204
+ * publishes the number once and `_drawing.scss` reads it twice. A zero removes the
205
+ * property rather than declaring `0px`, because `var(--adw-drawing-width, auto)` is
206
+ * how "no intrinsic size" is spelled.
207
+ */
208
+ private _publishSize(): void {
209
+ const size: [string, number][] = [
210
+ ['--adw-drawing-width', this.contentWidth],
211
+ ['--adw-drawing-height', this.contentHeight],
212
+ ];
213
+ for (const [property, value] of size) {
214
+ if (value > 0) this.style.setProperty(property, `${value}px`);
215
+ else this.style.removeProperty(property);
216
+ }
217
+ }
218
+
219
+ private _observe(): void {
220
+ if (this._resize) return;
221
+ // ResizeObserver delivers an initial observation on observe(), so the first draw
222
+ // lands without a separate seeding pass — the `::resize` signal GTK emits "once
223
+ // when the widget is realized" (:312-313).
224
+ this._resize = new ResizeObserver((entries) => {
225
+ for (const entry of entries) {
226
+ const box = entry.borderBoxSize?.[0];
227
+ this._allocated(
228
+ box ? box.inlineSize : entry.contentRect.width,
229
+ box ? box.blockSize : entry.contentRect.height,
230
+ );
231
+ }
232
+ });
233
+ this._resize.observe(this);
234
+ }
235
+
236
+ /**
237
+ * `gtk_drawing_area_size_allocate` (:233-238) emits `::resize` and does nothing else —
238
+ * the signal IS the allocation path. The browser learns the allocation from the
239
+ * observer instead, so the signal is emitted from here, and only when the allocation
240
+ * really changed: GTK reaches `size_allocate` on every layout pass, and the signal
241
+ * is documented as firing "each time the widget is changed" (:312-314).
242
+ */
243
+ private _allocated(width: number, height: number): void {
244
+ const changed = width !== this._width || height !== this._height;
245
+ this._width = width;
246
+ this._height = height;
247
+ if (changed) {
248
+ this.dispatchEvent(new CustomEvent('resize', { bubbles: true, detail: { width, height } }));
249
+ }
250
+ this._draw();
251
+ }
252
+
253
+ /**
254
+ * One frame. `gtk_drawing_area_snapshot` (:240-267) measures the ALLOCATION, not the
255
+ * properties, and calls the function with it; the browser gets the allocation from the
256
+ * observer instead of from the snapshot, and the drawing itself is the 2D context the
257
+ * canvas already owns.
258
+ */
259
+ private _draw(): void {
260
+ if (!this._canvas || this._width < 0) return;
261
+ const width = this._width;
262
+ const height = this._height;
263
+ // The cairo region is the allocation unscaled (:248-262); the backing store is the
264
+ // same size in device pixels, and the context carries the ratio.
265
+ const scale = this._devicePixelRatio();
266
+ const pixelWidth = Math.round(width * scale);
267
+ const pixelHeight = Math.round(height * scale);
268
+ if (this._canvas.width !== pixelWidth) this._canvas.width = pixelWidth;
269
+ if (this._canvas.height !== pixelHeight) this._canvas.height = pixelHeight;
270
+ this._scale = scale;
271
+
272
+ const context = this._context;
273
+ if (!context) return;
274
+ // `setTransform` rather than `scale`, so a second frame does not compound the ratio.
275
+ context.setTransform(scale, 0, 0, scale, 0, 0);
276
+ // A fresh surface per frame, as GTK's renderer gives the callback.
277
+ context.clearRect(0, 0, width, height);
278
+
279
+ if (this._drawFunc) this._drawFunc(this, context, width, height);
280
+ }
281
+
282
+ /** The backing store is rebuilt when the display's ratio changes, not every frame. */
283
+ private _devicePixelRatio(): number {
284
+ return typeof window === 'undefined' ? 1 : window.devicePixelRatio || 1;
285
+ }
286
+
287
+ /** The `notify::` detail for `name`: the PROPERTY, parsed, not the raw attribute. */
288
+ private _notify(name: string): void {
289
+ const value = name === 'content-width' ? this.contentWidth : this.contentHeight;
290
+ this.dispatchEvent(new CustomEvent(`notify::${name}`, { bubbles: true, detail: { [name]: value } }));
291
+ }
292
+
293
+ /** The last allocation, as `::resize` reported it — the spec reads it back. */
294
+ get allocation(): { width: number; height: number } {
295
+ return { width: this._width, height: this._height };
296
+ }
297
+
298
+ /** The ratio the backing store was built at, as the header describes. */
299
+ get pixelScale(): number {
300
+ return this._scale;
301
+ }
302
+ }
303
+ customElements.define('gtk-drawing-area', GtkDrawingArea);
@@ -0,0 +1,204 @@
1
+ // <gtk-editable-label> — `GtkEditableLabel`, a label you click and edit in place.
2
+ //
3
+ // IT IS A STACK, NOT A FIELD. The C builds `stack > { label, entry }`, puts a
4
+ // `Gtk.Text` in the entry slot, and `editing` IS "the entry is the stack's visible child"
5
+ // (gtkeditablelabel.c:319-331,595-599). Two elements therefore stand for one widget, and
6
+ // which of them shows is the whole of its state — `.editing` on the host is the class the
7
+ // C adds and removes around every transition (gtkeditablelabel.c:609-663), and it is what
8
+ // libadwaita's `editablelabel > stack > text` selector keys on.
9
+ //
10
+ // THE KEYS ARE THE BEHAVIOUR. Enter on the label starts editing; Enter in the entry COMMITS
11
+ // (the drafted text becomes the label's); Escape in the entry DISCARDS it (the entry is
12
+ // reset to what the label says, gtkeditablelabel.c:637-656). A click on the label starts
13
+ // editing — the gesture is on the LABEL, not on the widget (gtkeditablelabel.c:193-215,
14
+ // 351-353) — and focus leaving the widget commits after the C's 100 ms grace period, which
15
+ // exists so a focus move INSIDE the widget is not read as leaving
16
+ // (gtkeditablelabel.c:293-318). `editable` FALSE stops editing without committing and
17
+ // refuses to start it (gtkeditablelabel.c:414-427).
18
+ //
19
+ // `text` is `Gtk.Editable:text`, what the label shows. While the entry is visible it holds a
20
+ // DRAFT, which is why the C syncs the label from `notify::text` only while it is not
21
+ // editing (gtkeditablelabel.c:237-248) and why a discarded edit resets the entry rather
22
+ // than the label.
23
+ //
24
+ // A11y: GTK declares no role for this widget (`gtkeditablelabel.c` calls no
25
+ // `set_accessible_role`) and makes it focusable (gtkeditablelabel.c:320), so the host owns
26
+ // the tab stop while it shows the label and the entry holds it while it edits.
27
+ //
28
+ // NOT PORTED, one line each, declared in `check-adwaita-element-properties.mjs`: the
29
+ // drag-and-drop target and source (GTK drops a string onto the label and drags its text out,
30
+ // gtkeditablelabel.c:250-291), the context menu (a `Gtk.PopoverMenu` over a right click,
31
+ // gtkeditablelabel.c:145-190) and `Gtk.Editable`'s undo stack (`enable-undo`, which no
32
+ // attribute can carry and a native input does not expose).
33
+ //
34
+ // Reference: refs/gtk/gtk/gtkeditablelabel.c:40-95 (the node tree and the keys),
35
+ // 193-215,237-248,293-331,414-427,609-663 (gesture, text sync, focus grace, editable,
36
+ // start/stop editing)
37
+ // Reference: refs/libadwaita/src/stylesheet/widgets/_labels.scss:1-11,90-97
38
+ // (`label {}`, `editablelabel > stack > text`)
39
+ // Copyright (c) The GTK Team, GNOME contributors. LGPLv2.1+.
40
+ // Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
41
+
42
+ /** The C's grace period between a focus leaving the widget and the commit it triggers. */
43
+ const FOCUS_OUT_GRACE_MS = 100;
44
+
45
+ export class GtkEditableLabel extends HTMLElement {
46
+ private _label!: HTMLSpanElement;
47
+ private _entry!: HTMLInputElement;
48
+ private _initialized = false;
49
+ private _grace: ReturnType<typeof setTimeout> | null = null;
50
+
51
+ static get observedAttributes() {
52
+ return ['text', 'editable', 'editing'];
53
+ }
54
+
55
+ /** `Gtk.Editable:text` — what the label shows, which is the committed draft. */
56
+ get text(): string {
57
+ return this.getAttribute('text') ?? '';
58
+ }
59
+
60
+ set text(value: string) {
61
+ this.setAttribute('text', value ?? '');
62
+ }
63
+
64
+ /** `Gtk.Editable:editable` — defaults TRUE. FALSE refuses to start editing. */
65
+ get editable(): boolean {
66
+ const raw = this.getAttribute('editable');
67
+ return raw === null ? true : raw !== 'false';
68
+ }
69
+
70
+ set editable(value: boolean) {
71
+ if (value) this.removeAttribute('editable');
72
+ else this.setAttribute('editable', 'false');
73
+ }
74
+
75
+ /**
76
+ * `GtkEditableLabel:editing` — TRUE while the entry is the stack's visible child, so it
77
+ * is the ATTRIBUTE as on every other boolean here. Setting it is what starts or stops
78
+ * editing, because the C's property setter does exactly that (gtkeditablelabel.c:406-411).
79
+ */
80
+ get editing(): boolean {
81
+ return this.hasAttribute('editing');
82
+ }
83
+
84
+ set editing(value: boolean) {
85
+ this.toggleAttribute('editing', !!value);
86
+ }
87
+
88
+ /** `gtk_editable_label_start_editing` — refused while `editable` is FALSE, as in the C. */
89
+ startEditing(): void {
90
+ if (!this.editable) return;
91
+ this.editing = true;
92
+ }
93
+
94
+ /**
95
+ * `gtk_editable_label_stop_editing` — `commit` decides whether the drafted text becomes
96
+ * the label's; FALSE resets the entry to the label instead (gtkeditablelabel.c:637-656).
97
+ */
98
+ stopEditing(commit = false): void {
99
+ if (!this.editing) return;
100
+ if (commit) this.setAttribute('text', this._entry.value);
101
+ this.editing = false;
102
+ }
103
+
104
+ /** The inner native entry, for focus and selection. */
105
+ get entry(): HTMLInputElement {
106
+ return this._entry;
107
+ }
108
+
109
+ connectedCallback() {
110
+ if (this._initialized) return;
111
+ this._initialized = true;
112
+
113
+ this._label = document.createElement('span');
114
+ this._label.className = 'adw-editable-label-label';
115
+ this._label.addEventListener('click', () => this.startEditing());
116
+
117
+ this._entry = document.createElement('input');
118
+ this._entry.className = 'adw-editable-label-entry';
119
+ this._entry.type = 'text';
120
+ // The C moves focus onto the entry to start editing and back onto the widget to stop
121
+ // (gtkeditablelabel.c:614,652), so the host is the tab stop only while it shows the
122
+ // label — otherwise a Tab would walk through two controls for one widget.
123
+ this._entry.tabIndex = -1;
124
+ this._entry.addEventListener('keydown', (event) => {
125
+ if (event.key === 'Enter') {
126
+ event.preventDefault();
127
+ // Consumed here: Enter in the entry is its `activate` signal
128
+ // (gtkeditablelabel.c:232-234), and letting it reach the widget would start
129
+ // editing again the moment the commit stopped it.
130
+ event.stopPropagation();
131
+ this.stopEditing(true);
132
+ } else if (event.key === 'Escape') {
133
+ event.preventDefault();
134
+ event.stopPropagation();
135
+ this.stopEditing(false);
136
+ }
137
+ });
138
+
139
+ this.replaceChildren(this._label, this._entry);
140
+ // Enter and Space start editing as a KEY BINDING of the WIDGET, not of the label node
141
+ // inside it (gtkeditablelabel.c:54-63), so the listener is on the host.
142
+ this.addEventListener('keydown', (event) => {
143
+ if (this.editing || (event.key !== 'Enter' && event.key !== ' ')) return;
144
+ event.preventDefault();
145
+ this.startEditing();
146
+ });
147
+ // Leaving the WIDGET is what commits, not leaving the entry, and the C waits out its
148
+ // grace period first so a focus move WITHIN the widget is not read as leaving it.
149
+ this.addEventListener('focusout', (event) => {
150
+ const next = event.relatedTarget;
151
+ if (next instanceof Node && this.contains(next)) return;
152
+ if (this._grace !== null) clearTimeout(this._grace);
153
+ this._grace = setTimeout(() => {
154
+ this._grace = null;
155
+ if (this.editing) this.stopEditing(true);
156
+ }, FOCUS_OUT_GRACE_MS);
157
+ });
158
+
159
+ this._render();
160
+ }
161
+
162
+ disconnectedCallback() {
163
+ if (this._grace !== null) clearTimeout(this._grace);
164
+ this._grace = null;
165
+ }
166
+
167
+ attributeChangedCallback(name: string, _old: string | null, value: string | null) {
168
+ if (!this._initialized) return;
169
+ switch (name) {
170
+ case 'text':
171
+ // The label's text only follows the property while nothing is being drafted,
172
+ // which is the condition `text_changed` tests in the C.
173
+ if (!this.editing) this._render();
174
+ break;
175
+ case 'editable':
176
+ if (value === 'false') this.stopEditing(false);
177
+ break;
178
+ case 'editing':
179
+ this._render();
180
+ if (this.editing) this._entry.focus();
181
+ else this.focus();
182
+ this.dispatchEvent(
183
+ new CustomEvent('notify::editing', { bubbles: true, detail: { editing: this.editing } }),
184
+ );
185
+ break;
186
+ }
187
+ }
188
+
189
+ private _render(): void {
190
+ const editing = this.editing;
191
+ this.classList.toggle('editing', editing);
192
+ this._label.hidden = editing;
193
+ this._entry.hidden = !editing;
194
+ this._label.textContent = this.text;
195
+ this._entry.value = this.text;
196
+ // The tab stop FOLLOWS the state: the widget is focusable while it shows the label
197
+ // and hands the focus to the entry while it edits (gtkeditablelabel.c:614,652), so
198
+ // a Tab never reaches a control the user cannot see.
199
+ if (editing) this.removeAttribute('tabindex');
200
+ else this.setAttribute('tabindex', '0');
201
+ }
202
+ }
203
+
204
+ customElements.define('gtk-editable-label', GtkEditableLabel);