@gjsify/adwaita-web 0.54.0 → 0.56.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 (479) hide show
  1. package/README.md +8 -0
  2. package/dist/adwaita-web.css +8146 -3011
  3. package/dist/adwaita-web.css.map +1 -1
  4. package/lib/types/adw-application-window.spec.d.ts +1 -0
  5. package/lib/types/adw-bin.spec.d.ts +1 -0
  6. package/lib/types/adw-breakpoint-bin.spec.d.ts +1 -0
  7. package/lib/types/adw-clamp-scrollable.spec.d.ts +1 -0
  8. package/lib/types/adw-multi-layout-view.spec.d.ts +1 -0
  9. package/lib/types/adw-preferences-row.spec.d.ts +1 -0
  10. package/lib/types/adw-shortcuts.spec.d.ts +1 -0
  11. package/lib/types/adw-status-page.spec.d.ts +1 -0
  12. package/lib/types/adw-tab-bar.spec.d.ts +1 -0
  13. package/lib/types/adw-tab-button.spec.d.ts +1 -0
  14. package/lib/types/adw-tab-overview.spec.d.ts +1 -0
  15. package/lib/types/adw-view-switcher-sidebar.spec.d.ts +1 -0
  16. package/lib/types/adw-window.spec.d.ts +1 -0
  17. package/lib/types/attributes.d.ts +19 -0
  18. package/lib/types/breakpoints.d.ts +14 -3
  19. package/lib/types/construct-vectors.spec.d.ts +1 -0
  20. package/lib/types/elements/adw-action-row.d.ts +4 -0
  21. package/lib/types/elements/adw-application-window.d.ts +27 -0
  22. package/lib/types/elements/adw-bin.d.ts +17 -0
  23. package/lib/types/elements/adw-breakpoint-bin.d.ts +67 -0
  24. package/lib/types/elements/adw-clamp-scrollable.d.ts +38 -0
  25. package/lib/types/elements/adw-combo-row.d.ts +4 -0
  26. package/lib/types/elements/adw-dialog.d.ts +10 -0
  27. package/lib/types/elements/adw-entry-row.d.ts +6 -0
  28. package/lib/types/elements/adw-expander-row.d.ts +2 -0
  29. package/lib/types/elements/adw-header-bar.d.ts +6 -0
  30. package/lib/types/elements/adw-layout-slot.d.ts +19 -0
  31. package/lib/types/elements/adw-multi-layout-view.d.ts +101 -0
  32. package/lib/types/elements/adw-overlay-split-view.d.ts +13 -0
  33. package/lib/types/elements/adw-preferences-row.d.ts +31 -0
  34. package/lib/types/elements/adw-shortcuts-dialog.d.ts +13 -0
  35. package/lib/types/elements/adw-shortcuts-item.d.ts +36 -0
  36. package/lib/types/elements/adw-shortcuts-section.d.ts +14 -0
  37. package/lib/types/elements/adw-sidebar.d.ts +8 -2
  38. package/lib/types/elements/adw-spin-row.d.ts +6 -0
  39. package/lib/types/elements/adw-switch-row.d.ts +7 -0
  40. package/lib/types/elements/adw-tab-bar.d.ts +108 -0
  41. package/lib/types/elements/adw-tab-button.d.ts +32 -0
  42. package/lib/types/elements/adw-tab-overview.d.ts +199 -0
  43. package/lib/types/elements/adw-tab-view.d.ts +19 -23
  44. package/lib/types/elements/adw-toggle-group.d.ts +17 -0
  45. package/lib/types/elements/adw-view-switcher-sidebar.d.ts +84 -0
  46. package/lib/types/elements/adw-window.d.ts +40 -0
  47. package/lib/types/elements/gtk-about-dialog.d.ts +146 -0
  48. package/lib/types/elements/gtk-application-window.d.ts +34 -0
  49. package/lib/types/elements/gtk-aspect-frame.d.ts +27 -0
  50. package/lib/types/elements/gtk-button.d.ts +9 -0
  51. package/lib/types/elements/gtk-calendar.d.ts +159 -0
  52. package/lib/types/elements/gtk-center-box.d.ts +39 -0
  53. package/lib/types/elements/gtk-color-dialog-button.d.ts +69 -0
  54. package/lib/types/elements/gtk-column-view.d.ts +50 -0
  55. package/lib/types/elements/gtk-drag-icon.d.ts +78 -0
  56. package/lib/types/elements/gtk-drawing-area.d.ts +95 -0
  57. package/lib/types/elements/gtk-editable-label.d.ts +33 -0
  58. package/lib/types/elements/gtk-emoji-chooser.d.ts +84 -0
  59. package/lib/types/elements/gtk-entry.d.ts +20 -1
  60. package/lib/types/elements/gtk-expander.d.ts +49 -0
  61. package/lib/types/elements/gtk-fixed.d.ts +13 -0
  62. package/lib/types/elements/gtk-flow-box-child.d.ts +14 -0
  63. package/lib/types/elements/gtk-flow-box.d.ts +87 -0
  64. package/lib/types/elements/gtk-font-dialog-button.d.ts +83 -0
  65. package/lib/types/elements/gtk-frame.d.ts +24 -0
  66. package/lib/types/elements/gtk-gl-area.d.ts +136 -0
  67. package/lib/types/elements/gtk-graphics-offload.d.ts +24 -0
  68. package/lib/types/elements/gtk-grid-view.d.ts +39 -0
  69. package/lib/types/elements/gtk-grid.d.ts +27 -0
  70. package/lib/types/elements/gtk-header-bar.d.ts +60 -0
  71. package/lib/types/elements/gtk-inscription.d.ts +64 -0
  72. package/lib/types/elements/gtk-label.d.ts +3 -0
  73. package/lib/types/elements/gtk-level-bar.d.ts +59 -0
  74. package/lib/types/elements/gtk-link-button.d.ts +29 -0
  75. package/lib/types/elements/gtk-list-box-row.d.ts +54 -0
  76. package/lib/types/elements/gtk-list-box.d.ts +100 -0
  77. package/lib/types/elements/gtk-list-view.d.ts +73 -0
  78. package/lib/types/elements/gtk-media-controls.d.ts +142 -0
  79. package/lib/types/elements/gtk-notebook.d.ts +148 -0
  80. package/lib/types/elements/gtk-overlay.d.ts +22 -0
  81. package/lib/types/elements/gtk-page-setup-unix-dialog.d.ts +87 -0
  82. package/lib/types/elements/gtk-paned.d.ts +121 -0
  83. package/lib/types/elements/gtk-password-entry.d.ts +27 -0
  84. package/lib/types/elements/gtk-picture.d.ts +66 -0
  85. package/lib/types/elements/gtk-popover-bin.d.ts +82 -0
  86. package/lib/types/elements/gtk-popover-menu-bar.d.ts +66 -0
  87. package/lib/types/elements/gtk-popover-menu.d.ts +83 -0
  88. package/lib/types/elements/gtk-popover.d.ts +28 -3
  89. package/lib/types/elements/gtk-print-unix-dialog.d.ts +167 -0
  90. package/lib/types/elements/gtk-revealer.d.ts +55 -0
  91. package/lib/types/elements/gtk-scale-button.d.ts +59 -0
  92. package/lib/types/elements/gtk-scale.d.ts +98 -0
  93. package/lib/types/elements/gtk-scrollbar.d.ts +124 -0
  94. package/lib/types/elements/gtk-scrolled-window.d.ts +129 -0
  95. package/lib/types/elements/gtk-search-bar.d.ts +39 -0
  96. package/lib/types/elements/gtk-search-entry.d.ts +27 -0
  97. package/lib/types/elements/gtk-separator.d.ts +10 -0
  98. package/lib/types/elements/gtk-spin-button.d.ts +94 -0
  99. package/lib/types/elements/gtk-spinner.d.ts +14 -0
  100. package/lib/types/elements/gtk-stack-sidebar.d.ts +43 -0
  101. package/lib/types/elements/gtk-stack-switcher.d.ts +58 -0
  102. package/lib/types/elements/gtk-stack.d.ts +154 -0
  103. package/lib/types/elements/gtk-switch.d.ts +4 -1
  104. package/lib/types/elements/gtk-text-view.d.ts +62 -0
  105. package/lib/types/elements/gtk-text.d.ts +45 -0
  106. package/lib/types/elements/gtk-toggle-button.d.ts +45 -0
  107. package/lib/types/elements/gtk-tree-expander.d.ts +38 -0
  108. package/lib/types/elements/gtk-video.d.ts +97 -0
  109. package/lib/types/elements/gtk-viewport.d.ts +84 -0
  110. package/lib/types/elements/gtk-window-controls.d.ts +80 -0
  111. package/lib/types/elements/gtk-window-handle.d.ts +39 -0
  112. package/lib/types/elements/gtk-window.d.ts +103 -0
  113. package/lib/types/elements/justification.d.ts +2 -0
  114. package/lib/types/elements/popover-menu.d.ts +18 -0
  115. package/lib/types/elements/roving-focus.d.ts +29 -1
  116. package/lib/types/emoji-data.d.ts +38 -0
  117. package/lib/types/font-description.d.ts +96 -0
  118. package/lib/types/gtk-about-dialog.spec.d.ts +1 -0
  119. package/lib/types/gtk-action-bar.spec.d.ts +1 -0
  120. package/lib/types/gtk-application-window.spec.d.ts +1 -0
  121. package/lib/types/gtk-aspect-frame.spec.d.ts +1 -0
  122. package/lib/types/gtk-calendar.spec.d.ts +1 -0
  123. package/lib/types/gtk-center-box.spec.d.ts +1 -0
  124. package/lib/types/gtk-color-dialog-button.spec.d.ts +1 -0
  125. package/lib/types/gtk-column-view.spec.d.ts +1 -0
  126. package/lib/types/gtk-drag-icon.spec.d.ts +1 -0
  127. package/lib/types/gtk-drawing-area.spec.d.ts +1 -0
  128. package/lib/types/gtk-editable-label.spec.d.ts +1 -0
  129. package/lib/types/gtk-emoji-chooser.spec.d.ts +1 -0
  130. package/lib/types/gtk-expander.spec.d.ts +1 -0
  131. package/lib/types/gtk-fixed.spec.d.ts +1 -0
  132. package/lib/types/gtk-flow-box.spec.d.ts +1 -0
  133. package/lib/types/gtk-font-dialog-button.spec.d.ts +1 -0
  134. package/lib/types/gtk-frame.spec.d.ts +1 -0
  135. package/lib/types/gtk-gl-area.spec.d.ts +1 -0
  136. package/lib/types/gtk-graphics-offload.spec.d.ts +1 -0
  137. package/lib/types/gtk-grid-view.spec.d.ts +1 -0
  138. package/lib/types/gtk-grid.spec.d.ts +1 -0
  139. package/lib/types/gtk-header-bar.spec.d.ts +1 -0
  140. package/lib/types/gtk-inscription.spec.d.ts +1 -0
  141. package/lib/types/gtk-level-bar.spec.d.ts +1 -0
  142. package/lib/types/gtk-link-button.spec.d.ts +1 -0
  143. package/lib/types/gtk-list-box.spec.d.ts +1 -0
  144. package/lib/types/gtk-list-view.spec.d.ts +1 -0
  145. package/lib/types/gtk-media-controls.spec.d.ts +1 -0
  146. package/lib/types/gtk-notebook.spec.d.ts +1 -0
  147. package/lib/types/gtk-overlay.spec.d.ts +1 -0
  148. package/lib/types/gtk-paned.spec.d.ts +1 -0
  149. package/lib/types/gtk-password-entry.spec.d.ts +1 -0
  150. package/lib/types/gtk-picture.spec.d.ts +1 -0
  151. package/lib/types/gtk-popover-bin.spec.d.ts +1 -0
  152. package/lib/types/gtk-popover-menu-bar.spec.d.ts +1 -0
  153. package/lib/types/gtk-popover-menu.spec.d.ts +1 -0
  154. package/lib/types/gtk-popover-role.spec.d.ts +1 -0
  155. package/lib/types/gtk-popover.spec.d.ts +1 -0
  156. package/lib/types/gtk-print-dialogs.spec.d.ts +1 -0
  157. package/lib/types/gtk-revealer.spec.d.ts +1 -0
  158. package/lib/types/gtk-scale-button.spec.d.ts +1 -0
  159. package/lib/types/gtk-scale.spec.d.ts +1 -0
  160. package/lib/types/gtk-scrollbar.spec.d.ts +1 -0
  161. package/lib/types/gtk-scrolled-window.spec.d.ts +1 -0
  162. package/lib/types/gtk-search-bar.spec.d.ts +1 -0
  163. package/lib/types/gtk-search-entry.spec.d.ts +1 -0
  164. package/lib/types/gtk-separator.spec.d.ts +1 -0
  165. package/lib/types/gtk-spin-button.spec.d.ts +1 -0
  166. package/lib/types/gtk-spinner.spec.d.ts +1 -0
  167. package/lib/types/gtk-stack-sidebar.spec.d.ts +1 -0
  168. package/lib/types/gtk-stack-switcher.spec.d.ts +1 -0
  169. package/lib/types/gtk-stack.spec.d.ts +1 -0
  170. package/lib/types/gtk-text-view.spec.d.ts +1 -0
  171. package/lib/types/gtk-text.spec.d.ts +1 -0
  172. package/lib/types/gtk-toggle-button.spec.d.ts +1 -0
  173. package/lib/types/gtk-tree-expander.spec.d.ts +1 -0
  174. package/lib/types/gtk-video.spec.d.ts +1 -0
  175. package/lib/types/gtk-viewport.spec.d.ts +1 -0
  176. package/lib/types/gtk-window-controls.spec.d.ts +1 -0
  177. package/lib/types/gtk-window-handle.spec.d.ts +1 -0
  178. package/lib/types/gtk-window.spec.d.ts +1 -0
  179. package/lib/types/index.d.ts +4 -1
  180. package/lib/types/list-view-dom.d.ts +44 -0
  181. package/lib/types/namespace/adw.d.ts +12 -0
  182. package/lib/types/namespace/gtk.d.ts +61 -0
  183. package/lib/types/page-setup.d.ts +100 -0
  184. package/lib/types/row-line-clamp.d.ts +20 -0
  185. package/lib/types/row-tooltip.d.ts +8 -0
  186. package/lib/types/row-tooltip.spec.d.ts +1 -0
  187. package/lib/types/scroll-shading.d.ts +15 -1
  188. package/lib/types/shared-tree-builder.d.ts +75 -17
  189. package/lib/types/shared-tree-mount.spec.d.ts +1 -0
  190. package/lib/types/signals.d.ts +4 -0
  191. package/lib/types/styles.generated.d.ts +1 -1
  192. package/lib/types/tab-chip.d.ts +73 -0
  193. package/lib/types/template-classes.d.ts +11 -0
  194. package/lib/types/widget-size.spec.d.ts +1 -0
  195. package/package.json +12 -8
  196. package/scss/_action_row.scss +41 -17
  197. package/scss/_application_window.scss +26 -0
  198. package/scss/_aspect_frame.scss +25 -0
  199. package/scss/_bin.scss +26 -0
  200. package/scss/_button.scss +45 -0
  201. package/scss/_button_row.scss +5 -0
  202. package/scss/_calendar.scss +176 -0
  203. package/scss/_center_box.scss +25 -0
  204. package/scss/_checks.scss +6 -1
  205. package/scss/_clamp_scrollable.scss +28 -0
  206. package/scss/_color_button.scss +67 -0
  207. package/scss/_column_view.scss +126 -0
  208. package/scss/_drag_icon.scss +55 -0
  209. package/scss/_drawing.scss +85 -0
  210. package/scss/_emoji_chooser.scss +213 -0
  211. package/scss/_entry.scss +13 -5
  212. package/scss/_entry_row.scss +1 -1
  213. package/scss/_expander.scss +113 -0
  214. package/scss/_expander_row.scss +36 -3
  215. package/scss/_fixed.scss +29 -0
  216. package/scss/_flow_box.scss +94 -0
  217. package/scss/_font_button.scss +63 -0
  218. package/scss/_frame.scss +41 -0
  219. package/scss/_grid.scss +19 -0
  220. package/scss/_grid_view.scss +46 -0
  221. package/scss/_gtk_about_dialog.scss +186 -0
  222. package/scss/_headerbar.scss +134 -1
  223. package/scss/_icons.generated.scss +186 -0
  224. package/scss/_inscription.scss +125 -0
  225. package/scss/_level_bar.scss +190 -0
  226. package/scss/_link.scss +82 -0
  227. package/scss/_list_box.scss +88 -0
  228. package/scss/_list_view.scss +96 -0
  229. package/scss/_media_controls.scss +139 -0
  230. package/scss/_overlay.scss +68 -0
  231. package/scss/_paned.scss +130 -0
  232. package/scss/_password_entry.scss +83 -0
  233. package/scss/_picture.scss +80 -0
  234. package/scss/_popover_bin.scss +53 -0
  235. package/scss/_popover_menu_bar.scss +104 -0
  236. package/scss/_preferences_row.scss +60 -0
  237. package/scss/_print_dialogs.scss +328 -0
  238. package/scss/_reset.scss +21 -19
  239. package/scss/_revealer.scss +37 -0
  240. package/scss/_row.scss +36 -5
  241. package/scss/_scale.scss +298 -0
  242. package/scss/_scale_button.scss +167 -0
  243. package/scss/_scrollbar.scss +230 -0
  244. package/scss/_scrolled_window.scss +131 -0
  245. package/scss/_search_bar.scss +118 -0
  246. package/scss/_search_entry.scss +86 -0
  247. package/scss/_separator.scss +44 -0
  248. package/scss/_shortcuts_dialog.scss +100 -0
  249. package/scss/_spin_button.scss +172 -0
  250. package/scss/_spin_row.scss +56 -8
  251. package/scss/_spinner.scss +85 -4
  252. package/scss/_stack.scss +729 -0
  253. package/scss/_status_page.scss +1 -1
  254. package/scss/_switch.scss +13 -5
  255. package/scss/_switch_row.scss +10 -0
  256. package/scss/_tab_bar.scss +317 -0
  257. package/scss/_tab_button.scss +98 -0
  258. package/scss/_tab_overview.scss +483 -0
  259. package/scss/_text.scss +182 -0
  260. package/scss/_theme.scss +1 -1
  261. package/scss/_toggle_group.scss +28 -0
  262. package/scss/_tree_expander.scss +62 -0
  263. package/scss/_variables.scss +1 -1
  264. package/scss/_video.scss +146 -0
  265. package/scss/_view_switcher_sidebar.scss +112 -0
  266. package/scss/_viewport.scss +50 -0
  267. package/scss/_widget.scss +14 -3
  268. package/scss/_window.scss +131 -2
  269. package/scss/_window_handle.scss +20 -0
  270. package/scss/adwaita-skin.scss +109 -0
  271. package/src/adw-action-rows.spec.ts +331 -0
  272. package/src/adw-application-window.spec.ts +118 -0
  273. package/src/adw-bin.spec.ts +75 -0
  274. package/src/adw-breakpoint-bin.spec.ts +324 -0
  275. package/src/adw-clamp-scrollable.spec.ts +189 -0
  276. package/src/adw-header-bar.spec.ts +18 -0
  277. package/src/adw-multi-layout-view.spec.ts +243 -0
  278. package/src/adw-preferences-row.spec.ts +164 -0
  279. package/src/adw-row-state.spec.ts +142 -0
  280. package/src/adw-shortcuts.spec.ts +155 -0
  281. package/src/adw-status-page.spec.ts +124 -0
  282. package/src/adw-tab-bar.spec.ts +287 -0
  283. package/src/adw-tab-button.spec.ts +101 -0
  284. package/src/adw-tab-overview.spec.ts +443 -0
  285. package/src/adw-view-switcher-sidebar.spec.ts +281 -0
  286. package/src/adw-window.spec.ts +129 -0
  287. package/src/attributes.ts +52 -0
  288. package/src/breakpoints.ts +25 -8
  289. package/src/capabilities.d.mts +3 -0
  290. package/src/capabilities.mjs +21 -0
  291. package/src/connect-lifecycle.spec.ts +12 -0
  292. package/src/construct-vectors.spec.ts +175 -0
  293. package/src/elements/adw-action-row.ts +31 -2
  294. package/src/elements/adw-alert-dialog.ts +4 -1
  295. package/src/elements/adw-application-window.ts +154 -0
  296. package/src/elements/adw-bin.ts +101 -0
  297. package/src/elements/adw-breakpoint-bin.ts +287 -0
  298. package/src/elements/adw-button-row.ts +7 -1
  299. package/src/elements/adw-clamp-scrollable.ts +207 -0
  300. package/src/elements/adw-combo-row.ts +26 -1
  301. package/src/elements/adw-dialog.ts +19 -0
  302. package/src/elements/adw-entry-row.ts +22 -12
  303. package/src/elements/adw-expander-row.ts +34 -1
  304. package/src/elements/adw-header-bar.ts +18 -4
  305. package/src/elements/adw-layout-slot.ts +95 -0
  306. package/src/elements/adw-multi-layout-view.ts +326 -0
  307. package/src/elements/adw-overlay-split-view.ts +29 -6
  308. package/src/elements/adw-preferences-row.ts +153 -0
  309. package/src/elements/adw-shortcuts-dialog.ts +52 -0
  310. package/src/elements/adw-shortcuts-item.ts +171 -0
  311. package/src/elements/adw-shortcuts-section.ts +86 -0
  312. package/src/elements/adw-sidebar.ts +74 -7
  313. package/src/elements/adw-spin-row.ts +37 -2
  314. package/src/elements/adw-status-page.ts +10 -2
  315. package/src/elements/adw-switch-row.ts +53 -2
  316. package/src/elements/adw-tab-bar.ts +529 -0
  317. package/src/elements/adw-tab-button.ts +194 -0
  318. package/src/elements/adw-tab-overview.ts +1011 -0
  319. package/src/elements/adw-tab-view.ts +66 -145
  320. package/src/elements/adw-toggle-group.ts +138 -14
  321. package/src/elements/adw-view-stack.ts +18 -0
  322. package/src/elements/adw-view-switcher-sidebar.ts +332 -0
  323. package/src/elements/adw-window.ts +190 -11
  324. package/src/elements/checks.ts +35 -8
  325. package/src/elements/gtk-about-dialog.ts +811 -0
  326. package/src/elements/gtk-application-window.ts +108 -0
  327. package/src/elements/gtk-aspect-frame.ts +160 -0
  328. package/src/elements/gtk-button.ts +12 -0
  329. package/src/elements/gtk-calendar.ts +757 -0
  330. package/src/elements/gtk-center-box.ts +184 -0
  331. package/src/elements/gtk-color-dialog-button.ts +278 -0
  332. package/src/elements/gtk-column-view.ts +320 -0
  333. package/src/elements/gtk-drag-icon.ts +257 -0
  334. package/src/elements/gtk-drawing-area.ts +303 -0
  335. package/src/elements/gtk-editable-label.ts +204 -0
  336. package/src/elements/gtk-emoji-chooser.ts +542 -0
  337. package/src/elements/gtk-entry.ts +39 -5
  338. package/src/elements/gtk-expander.ts +301 -0
  339. package/src/elements/gtk-fixed.ts +99 -0
  340. package/src/elements/gtk-flow-box-child.ts +68 -0
  341. package/src/elements/gtk-flow-box.ts +480 -0
  342. package/src/elements/gtk-font-dialog-button.ts +432 -0
  343. package/src/elements/gtk-frame.ts +174 -0
  344. package/src/elements/gtk-gl-area.ts +476 -0
  345. package/src/elements/gtk-graphics-offload.ts +130 -0
  346. package/src/elements/gtk-grid-view.ts +168 -0
  347. package/src/elements/gtk-grid.ts +127 -0
  348. package/src/elements/gtk-header-bar.ts +273 -0
  349. package/src/elements/gtk-inscription.ts +387 -0
  350. package/src/elements/gtk-label.ts +19 -11
  351. package/src/elements/gtk-level-bar.ts +323 -0
  352. package/src/elements/gtk-link-button.ts +138 -0
  353. package/src/elements/gtk-list-box-row.ts +195 -0
  354. package/src/elements/gtk-list-box.ts +413 -0
  355. package/src/elements/gtk-list-view.ts +370 -0
  356. package/src/elements/gtk-media-controls.ts +509 -0
  357. package/src/elements/gtk-notebook.ts +664 -0
  358. package/src/elements/gtk-overlay.ts +149 -0
  359. package/src/elements/gtk-page-setup-unix-dialog.ts +420 -0
  360. package/src/elements/gtk-paned.ts +597 -0
  361. package/src/elements/gtk-password-entry.ts +170 -0
  362. package/src/elements/gtk-picture.ts +254 -0
  363. package/src/elements/gtk-popover-bin.ts +332 -0
  364. package/src/elements/gtk-popover-menu-bar.ts +355 -0
  365. package/src/elements/gtk-popover-menu.ts +339 -0
  366. package/src/elements/gtk-popover.ts +92 -10
  367. package/src/elements/gtk-print-unix-dialog.ts +989 -0
  368. package/src/elements/gtk-progress-bar.ts +24 -11
  369. package/src/elements/gtk-revealer.ts +406 -0
  370. package/src/elements/gtk-scale-button.ts +358 -0
  371. package/src/elements/gtk-scale.ts +492 -0
  372. package/src/elements/gtk-scrollbar.ts +528 -0
  373. package/src/elements/gtk-scrolled-window.ts +653 -0
  374. package/src/elements/gtk-search-bar.ts +200 -0
  375. package/src/elements/gtk-search-entry.ts +172 -0
  376. package/src/elements/gtk-separator.ts +52 -0
  377. package/src/elements/gtk-spin-button.ts +475 -0
  378. package/src/elements/gtk-spinner.ts +126 -0
  379. package/src/elements/gtk-stack-sidebar.ts +212 -0
  380. package/src/elements/gtk-stack-switcher.ts +279 -0
  381. package/src/elements/gtk-stack.ts +748 -0
  382. package/src/elements/gtk-switch.ts +52 -19
  383. package/src/elements/gtk-text-view.ts +290 -0
  384. package/src/elements/gtk-text.ts +219 -0
  385. package/src/elements/gtk-toggle-button.ts +239 -0
  386. package/src/elements/gtk-tree-expander.ts +243 -0
  387. package/src/elements/gtk-video.ts +423 -0
  388. package/src/elements/gtk-viewport.ts +277 -0
  389. package/src/elements/gtk-window-controls.ts +341 -0
  390. package/src/elements/gtk-window-handle.ts +221 -0
  391. package/src/elements/gtk-window.ts +372 -0
  392. package/src/elements/justification.ts +24 -0
  393. package/src/elements/popover-menu.ts +24 -0
  394. package/src/elements/roving-focus.ts +53 -21
  395. package/src/emoji-data.ts +577 -0
  396. package/src/entry-rows.spec.ts +31 -0
  397. package/src/font-description.ts +238 -0
  398. package/src/gtk-about-dialog.spec.ts +250 -0
  399. package/src/gtk-action-bar.spec.ts +89 -0
  400. package/src/gtk-application-window.spec.ts +107 -0
  401. package/src/gtk-aspect-frame.spec.ts +114 -0
  402. package/src/gtk-calendar.spec.ts +589 -0
  403. package/src/gtk-center-box.spec.ts +125 -0
  404. package/src/gtk-color-dialog-button.spec.ts +141 -0
  405. package/src/gtk-column-view.spec.ts +154 -0
  406. package/src/gtk-drag-icon.spec.ts +190 -0
  407. package/src/gtk-drawing-area.spec.ts +211 -0
  408. package/src/gtk-editable-label.spec.ts +190 -0
  409. package/src/gtk-emoji-chooser.spec.ts +173 -0
  410. package/src/gtk-entry.spec.ts +23 -0
  411. package/src/gtk-expander.spec.ts +170 -0
  412. package/src/gtk-fixed.spec.ts +97 -0
  413. package/src/gtk-flow-box.spec.ts +289 -0
  414. package/src/gtk-font-dialog-button.spec.ts +166 -0
  415. package/src/gtk-frame.spec.ts +119 -0
  416. package/src/gtk-gl-area.spec.ts +361 -0
  417. package/src/gtk-graphics-offload.spec.ts +119 -0
  418. package/src/gtk-grid-view.spec.ts +106 -0
  419. package/src/gtk-grid.spec.ts +122 -0
  420. package/src/gtk-header-bar.spec.ts +202 -0
  421. package/src/gtk-inscription.spec.ts +235 -0
  422. package/src/gtk-level-bar.spec.ts +199 -0
  423. package/src/gtk-link-button.spec.ts +117 -0
  424. package/src/gtk-list-box.spec.ts +422 -0
  425. package/src/gtk-list-view.spec.ts +203 -0
  426. package/src/gtk-media-controls.spec.ts +295 -0
  427. package/src/gtk-notebook.spec.ts +546 -0
  428. package/src/gtk-overlay.spec.ts +141 -0
  429. package/src/gtk-paned.spec.ts +267 -0
  430. package/src/gtk-password-entry.spec.ts +150 -0
  431. package/src/gtk-picture.spec.ts +172 -0
  432. package/src/gtk-popover-bin.spec.ts +229 -0
  433. package/src/gtk-popover-menu-bar.spec.ts +296 -0
  434. package/src/gtk-popover-menu.spec.ts +261 -0
  435. package/src/gtk-popover-role.spec.ts +138 -0
  436. package/src/gtk-popover.spec.ts +264 -0
  437. package/src/gtk-print-dialogs.spec.ts +251 -0
  438. package/src/gtk-revealer.spec.ts +164 -0
  439. package/src/gtk-scale-button.spec.ts +218 -0
  440. package/src/gtk-scale.spec.ts +213 -0
  441. package/src/gtk-scrollbar.spec.ts +244 -0
  442. package/src/gtk-scrolled-window.spec.ts +262 -0
  443. package/src/gtk-search-bar.spec.ts +179 -0
  444. package/src/gtk-search-entry.spec.ts +142 -0
  445. package/src/gtk-separator.spec.ts +74 -0
  446. package/src/gtk-spin-button.spec.ts +186 -0
  447. package/src/gtk-spinner.spec.ts +130 -0
  448. package/src/gtk-stack-sidebar.spec.ts +217 -0
  449. package/src/gtk-stack-switcher.spec.ts +249 -0
  450. package/src/gtk-stack.spec.ts +432 -0
  451. package/src/gtk-text-view.spec.ts +189 -0
  452. package/src/gtk-text.spec.ts +163 -0
  453. package/src/gtk-toggle-button.spec.ts +186 -0
  454. package/src/gtk-tree-expander.spec.ts +201 -0
  455. package/src/gtk-video.spec.ts +240 -0
  456. package/src/gtk-viewport.spec.ts +140 -0
  457. package/src/gtk-window-controls.spec.ts +232 -0
  458. package/src/gtk-window-handle.spec.ts +158 -0
  459. package/src/gtk-window.spec.ts +202 -0
  460. package/src/index.ts +9 -1
  461. package/src/keyboard-operable.spec.ts +77 -9
  462. package/src/list-view-dom.ts +121 -0
  463. package/src/namespace/adw.ts +12 -0
  464. package/src/namespace/gtk.ts +61 -0
  465. package/src/page-setup.ts +222 -0
  466. package/src/row-line-clamp.ts +74 -0
  467. package/src/row-tooltip.spec.ts +313 -0
  468. package/src/row-tooltip.ts +52 -0
  469. package/src/scroll-shading.ts +18 -1
  470. package/src/shared-tree-builder.ts +336 -41
  471. package/src/shared-tree-mount.spec.ts +130 -0
  472. package/src/shared-trees.spec.ts +15 -0
  473. package/src/signals.ts +15 -0
  474. package/src/style-classes.spec.ts +9 -8
  475. package/src/styles.generated.ts +1 -1
  476. package/src/tab-chip.ts +200 -0
  477. package/src/template-classes.ts +45 -0
  478. package/src/test.browser.mts +160 -0
  479. package/src/widget-size.spec.ts +117 -0
@@ -4,19 +4,28 @@
4
4
  // The styles are the UNSCOPED `scss/_switch.scss`, so `.adw-switch` exists outside a
5
5
  // switch row and `<adw-expander-row>` can reuse it instead of copying the block.
6
6
  //
7
- // NO CORE STATE MACHINE. The state is one boolean with no derivation, no ordering and no
8
- // notify subtlety beyond "on change" — ADR 0004 is explicit that trivial behaviour gets
9
- // no core class, and the `active` ATTRIBUTE is the state (`toggleAttribute` is idempotent,
10
- // so "notify only on a real change" needs no guard). `GtkSwitch` does carry a two-phase
11
- // `active`/`state` pair for async toggles, but `refs/gtk` is an uninitialized submodule
12
- // here so that is unverifiable, and neither this port nor
13
- // `@gjsify/adwaita-nativescript` models it. The notify rule that IS derived from C lives
14
- // in the ROW's `SwitchRowState`.
7
+ // NO CORE STATE MACHINE. The state is two booleans with no derivation, no ordering and
8
+ // no notify subtlety beyond "on change" — ADR 0004 is explicit that trivial behaviour
9
+ // gets no core class — and each is the ATTRIBUTE, `toggleAttribute` being idempotent, so
10
+ // "notify only on a real change" needs no guard. The notify rule that IS derived from C
11
+ // lives in the ROW's `SwitchRowState`.
15
12
  //
16
- // `notify::active` (CustomEvent, bubbles, detail `{ active }`) fires on every change,
17
- // programmatic included. A widget that COMPOSES this one and publishes its own
18
- // `notify::active` (`<adw-switch-row>`) stops this one at the switch, so the row stays
19
- // the single public event surface.
13
+ // THE TWO BOOLEANS ARE NOT THE SAME THING, and that is the whole of `GtkSwitch`:
14
+ // `active` is where the USER put the switch, `state` is what the thing being switched
15
+ // currently IS (gtkswitch.c:39-43). `set_active` emits `::state-set` with the new value
16
+ // and the DEFAULT HANDLER sets `state` to it (:800, :558), so by default the two track
17
+ // each other — that is why a declarative `active` still paints the trough. An
18
+ // application that changes the backend separately connects to `::state-set`, returns
19
+ // TRUE to stop the default handler and calls `set_state` when the real change lands
20
+ // (:637-654); then `active` moves and `state` does not, which is exactly the delayed
21
+ // case. So the handler is not modelled as a cancellable signal — it is modelled as its
22
+ // DEFAULT, plus the attribute an application writes, which is the one half a custom
23
+ // element can express.
24
+ //
25
+ // WHICH ONE IS PAINTED: libadwaita's `switch:checked` (refs/libadwaita/src/stylesheet/
26
+ // widgets/_switch.scss:41-55), and GTK sets that state flag from `state`, not from
27
+ // `active` (gtkswitch.c:853-856). So the trough colour follows `state` and the knob
28
+ // position follows `active`, which is the two-phase picture the C describes.
20
29
  //
21
30
  // A11Y: the checkbox is left bare — no `role="switch"` — because the widgets that host
22
31
  // one claim that role themselves (`adw_switch_row_init` sets
@@ -25,6 +34,7 @@
25
34
  //
26
35
  // Reference: refs/adwaita-web/adwaita-web/scss/_switch.scss
27
36
  // Reference: refs/libadwaita/src/stylesheet/widgets/_switch.scss
37
+ // Reference: refs/gtk/gtk/gtkswitch.c:26-72,558,637-654,779-810,840-859
28
38
  // Copyright (c) GNOME contributors (libadwaita). LGPLv2.1+.
29
39
  // Copyright (c) 2025 csm (adwaita-web). MIT License.
30
40
  // Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
@@ -35,7 +45,7 @@ export class GtkSwitch extends HTMLElement {
35
45
  private _initialized = false;
36
46
 
37
47
  static get observedAttributes() {
38
- return ['active', 'disabled', 'unfocusable'];
48
+ return ['active', 'state', 'disabled', 'unfocusable'];
39
49
  }
40
50
 
41
51
  /**
@@ -54,17 +64,26 @@ export class GtkSwitch extends HTMLElement {
54
64
  this.toggleAttribute('unfocusable', !!value);
55
65
  }
56
66
 
57
- /** Whether the switch is on. */
67
+ /** Whether the user put the switch ON. Drives the knob. */
58
68
  get active(): boolean {
59
69
  return this.hasAttribute('active');
60
70
  }
61
71
 
62
72
  set active(value: boolean) {
63
- // `toggleAttribute` with a force flag is a no-op when the attribute already holds
64
- // the wanted state, so re-setting the current value never runs
65
- // `attributeChangedCallback` and never notifies. That idempotence is what a state
66
- // class would otherwise hold.
73
+ // `gtk_switch_set_active` emits `::state-set` and the DEFAULT handler runs
74
+ // `set_state` (gtkswitch.c:800, :558), so writing one writes the other. That is
75
+ // what keeps a declarative `active` painting the accent trough.
67
76
  this.toggleAttribute('active', !!value);
77
+ this.state = this.active;
78
+ }
79
+
80
+ /** `Gtk.Switch:state` — what the switched thing currently is. Drives the trough. */
81
+ get state(): boolean {
82
+ return this.hasAttribute('state');
83
+ }
84
+
85
+ set state(value: boolean) {
86
+ this.toggleAttribute('state', !!value);
68
87
  }
69
88
 
70
89
  /** Whether the switch is inert. */
@@ -77,7 +96,10 @@ export class GtkSwitch extends HTMLElement {
77
96
  }
78
97
 
79
98
  connectedCallback() {
80
- if (this._initialized) return;
99
+ if (this._initialized) {
100
+ this._render();
101
+ return;
102
+ }
81
103
  this._initialized = true;
82
104
 
83
105
  this.classList.add('adw-switch');
@@ -88,6 +110,12 @@ export class GtkSwitch extends HTMLElement {
88
110
  this._slider.className = 'adw-switch-slider';
89
111
  this.replaceChildren(this._input, this._slider);
90
112
 
113
+ // An `active` written before the element was connected is the same write GTK
114
+ // sees at construction time, so the default `::state-set` handler has already
115
+ // run by the time anyone looks: catch `state` up here (gtkswitch.c:682-757 gives
116
+ // `state` and `is_active` the same FALSE default and no attribute to reconcile).
117
+ if (this.active) this.state = true;
118
+
91
119
  // Keyboard (Space on the focused checkbox) and a programmatic `input.click()` both
92
120
  // arrive here; the attribute is the state, so this writes it and lets
93
121
  // attributeChangedCallback do the rest.
@@ -112,6 +140,8 @@ export class GtkSwitch extends HTMLElement {
112
140
  this._render();
113
141
  if (name === 'active') {
114
142
  this.dispatchEvent(new CustomEvent('notify::active', { bubbles: true, detail: { active: this.active } }));
143
+ } else if (name === 'state') {
144
+ this.dispatchEvent(new CustomEvent('notify::state', { bubbles: true, detail: { state: this.state } }));
115
145
  }
116
146
  }
117
147
 
@@ -121,6 +151,9 @@ export class GtkSwitch extends HTMLElement {
121
151
  this._input.disabled = disabled;
122
152
  if (this.unfocusable) this._input.tabIndex = -1;
123
153
  else this._input.removeAttribute('tabindex');
154
+ // The `:checked` state flag GTK raises from `state` (gtkswitch.c:853-856), which
155
+ // is the selector libadwaita paints the accent trough from.
156
+ this.classList.toggle('checked', this.state);
124
157
  this.classList.toggle('disabled', disabled);
125
158
  }
126
159
  }
@@ -0,0 +1,290 @@
1
+ // <gtk-text-view> — `Gtk.TextView`, GTK's multi-line editable text widget.
2
+ //
3
+ // THE TEXT IS THE BUFFER, AND A BUFFER IS NOT AN ATTRIBUTE. `Gtk.TextView` has no `text`
4
+ // property of its own: the text lives in a `Gtk.TextBuffer` handed over by `set_buffer`
5
+ // (gtktextview.c), which is why an authored tree cannot carry one and the gallery block
6
+ // for this widget is refused a static tree. Here the buffer's text is the light-DOM text of
7
+ // the element, read once when it connects, plus a `text` attribute for the programmatic
8
+ // door — the same shape `<gtk-entry>` has with `value`.
9
+ //
10
+ // `wrap-mode` and `justification` are Pango's, so they reach real CSS mechanisms rather
11
+ // than being declared unreachable: `JUSTIFY_TEXT_ALIGN` answers the justification through
12
+ // Pango's switch, which `<gtk-label>` reads for the same enum
13
+ // (`Gtk.TextView:justification` and `Gtk.Label:justify` are one), and `wrap-mode` becomes
14
+ // `white-space` plus the break CSS offers. `monospace` is libadwaita's own `.monospace`
15
+ // class rather than a font stack written here again.
16
+ //
17
+ // THE FOUR PARAGRAPH SPACINGS ARE NOT PORTED, one reason: `indent`, `pixels-above-lines`,
18
+ // `pixels-below-lines` and `pixels-inside-wrap` are Pango's PARAGRAPH model — a document
19
+ // with paragraph breaks this widget does not have. CSS has one `line-height` for every
20
+ // line, so there is no value of it that spaces paragraphs apart from the lines inside
21
+ // them, and a `<textarea>` has no paragraphs to tell apart. They are declared in
22
+ // `check-adwaita-element-properties.mjs` rather than silently dropped. The four MARGINS
23
+ // are the other half of that pspec family and DO have a CSS mechanism: GTK's own property
24
+ // doc says it — "this property is confusingly named. In CSS terms, the value set here is
25
+ // padding" (gtktextview.c:1050-1057) — so they are `padding` here.
26
+ //
27
+ // `accepts-tab` is GTK's default (TRUE: Tab inserts a tab character,
28
+ // gtktextview.c:1147-1151), which is the opposite of a browser's — so this element
29
+ // intercepts Tab and inserts one rather than letting the UA move focus, and
30
+ // `accepts-tab="false"` gives the UA its default back.
31
+ //
32
+ // A11y: GTK gives the widget `AccessibleRole.text_box` (gtktextview.c:1949), and the
33
+ // native `<textarea>` this element builds already carries exactly that role — the host
34
+ // does not repeat it, because a `role="textbox"` wrapping another textbox is worse for a
35
+ // screen reader than no role at all.
36
+ //
37
+ // NOT PORTED, one line each: `im-module`, `input-hints` and `input-purpose` (the input
38
+ // method and the on-screen keyboard it steers — a browser owns its own), and `overwrite`
39
+ // (a mode that draws a block cursor and makes every keystroke replace the next character,
40
+ // where a native text control overwrites an existing selection and exposes no mode
41
+ // besides).
42
+ //
43
+ // Reference: refs/gtk/gtk/gtktextview.c:983-1201 (the pspecs and their defaults),
44
+ // 1050-1057 (margins ARE padding), 1147-1151 (`accepts-tab` defaults TRUE),
45
+ // 1949 (the `textbox` role), 3540-3600 (justification)
46
+ // Reference: refs/libadwaita/src/stylesheet/widgets/_views.scss:1-45 (`%view`, `textview`)
47
+ // Copyright (c) The GTK Team, GNOME contributors. LGPLv2.1+.
48
+ // Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
49
+
50
+ import { normalizeLabelJustify, type LabelJustification } from '@gjsify/adwaita-core';
51
+
52
+ import { JUSTIFY_TEXT_ALIGN } from './justification.js';
53
+
54
+ /** `Gtk.WrapMode`'s four nicks, in enum order — Pango's enum, and the DEFAULT is `none`. */
55
+ const WRAP_MODES = ['none', 'char', 'word', 'word-char'] as const;
56
+
57
+ type TextViewWrapMode = (typeof WRAP_MODES)[number];
58
+
59
+ /**
60
+ * `Gtk.TextView:wrap-mode` from its nick, at Pango's own default of `none`.
61
+ *
62
+ * NOT `normalizeLabelWrapMode`, which reads the same enum but for `Gtk.Label`, whose
63
+ * pspec default is `word` and which has no `none` member to hold: reusing it here would
64
+ * wrap a text view that was asked not to, on every unknown value.
65
+ */
66
+ function normalizeWrapMode(value: string | null): TextViewWrapMode {
67
+ return (WRAP_MODES as readonly string[]).includes(value ?? '') ? (value as TextViewWrapMode) : 'none';
68
+ }
69
+
70
+ /** `Gtk.TextView:wrap-mode` as the two CSS mechanisms it maps onto. */
71
+ const WRAP_WHITE_SPACE: Record<TextViewWrapMode, string> = {
72
+ none: 'pre',
73
+ word: 'pre-wrap',
74
+ 'word-char': 'pre-wrap',
75
+ char: 'pre-wrap',
76
+ };
77
+
78
+ export class GtkTextView extends HTMLElement {
79
+ private _area!: HTMLTextAreaElement;
80
+ private _initialized = false;
81
+
82
+ static get observedAttributes() {
83
+ return [
84
+ 'text',
85
+ 'editable',
86
+ 'wrap-mode',
87
+ 'justification',
88
+ 'monospace',
89
+ 'accepts-tab',
90
+ 'cursor-visible',
91
+ 'top-margin',
92
+ 'bottom-margin',
93
+ 'left-margin',
94
+ 'right-margin',
95
+ ];
96
+ }
97
+
98
+ /** The buffer's text — the light-DOM text of the element, then whatever is typed. */
99
+ get text(): string {
100
+ return this._area ? this._area.value : (this.getAttribute('text') ?? this._seedText());
101
+ }
102
+
103
+ set text(value: string) {
104
+ if (this._area) this._area.value = value ?? '';
105
+ else this.setAttribute('text', value ?? '');
106
+ }
107
+
108
+ /** `Gtk.TextView:editable` — defaults TRUE, so the attribute carries a VALUE. */
109
+ get editable(): boolean {
110
+ return this._bool('editable', true);
111
+ }
112
+
113
+ set editable(value: boolean) {
114
+ this._setBool('editable', value, true);
115
+ }
116
+
117
+ /** `Gtk.TextView:wrap-mode` — where a line may break. Defaults to `none`, no wrapping. */
118
+ get wrapMode(): TextViewWrapMode {
119
+ return normalizeWrapMode(this.getAttribute('wrap-mode'));
120
+ }
121
+
122
+ set wrapMode(value: TextViewWrapMode) {
123
+ this.setAttribute('wrap-mode', value);
124
+ }
125
+
126
+ /** `Gtk.TextView:justification` — how the lines align with each other. Defaults `left`. */
127
+ get justification(): LabelJustification {
128
+ return normalizeLabelJustify(this.getAttribute('justification'));
129
+ }
130
+
131
+ set justification(value: LabelJustification) {
132
+ this.setAttribute('justification', value);
133
+ }
134
+
135
+ /** `Gtk.TextView:monospace` — whether the text is drawn in a monospace font. */
136
+ get monospace(): boolean {
137
+ return this._bool('monospace', false);
138
+ }
139
+
140
+ set monospace(value: boolean) {
141
+ this._setBool('monospace', value, false);
142
+ }
143
+
144
+ /** `Gtk.TextView:accepts-tab` — whether Tab inserts a tab character. Defaults TRUE. */
145
+ get acceptsTab(): boolean {
146
+ return this._bool('accepts-tab', true);
147
+ }
148
+
149
+ set acceptsTab(value: boolean) {
150
+ this._setBool('accepts-tab', value, true);
151
+ }
152
+
153
+ /** `Gtk.TextView:cursor-visible` — whether the insertion cursor is drawn. Defaults TRUE. */
154
+ get cursorVisible(): boolean {
155
+ return this._bool('cursor-visible', true);
156
+ }
157
+
158
+ set cursorVisible(value: boolean) {
159
+ this._setBool('cursor-visible', value, true);
160
+ }
161
+
162
+ /** `Gtk.TextView:top-margin` — pixels of blank space above the text, in `padding`. */
163
+ get topMargin(): number {
164
+ return this._margin('top-margin');
165
+ }
166
+
167
+ set topMargin(value: number) {
168
+ this.setAttribute('top-margin', String(value));
169
+ }
170
+
171
+ /** `Gtk.TextView:bottom-margin` — pixels of blank space below the text. */
172
+ get bottomMargin(): number {
173
+ return this._margin('bottom-margin');
174
+ }
175
+
176
+ set bottomMargin(value: number) {
177
+ this.setAttribute('bottom-margin', String(value));
178
+ }
179
+
180
+ /** `Gtk.TextView:left-margin` — pixels of blank space to the left of the text. */
181
+ get leftMargin(): number {
182
+ return this._margin('left-margin');
183
+ }
184
+
185
+ set leftMargin(value: number) {
186
+ this.setAttribute('left-margin', String(value));
187
+ }
188
+
189
+ /** `Gtk.TextView:right-margin` — pixels of blank space to the right of the text. */
190
+ get rightMargin(): number {
191
+ return this._margin('right-margin');
192
+ }
193
+
194
+ set rightMargin(value: number) {
195
+ this.setAttribute('right-margin', String(value));
196
+ }
197
+
198
+ /** The inner native textarea, for focus and selection. */
199
+ get textarea(): HTMLTextAreaElement {
200
+ return this._area;
201
+ }
202
+
203
+ connectedCallback() {
204
+ if (this._initialized) return;
205
+ this._initialized = true;
206
+
207
+ const area = document.createElement('textarea');
208
+ area.className = 'adw-text-view';
209
+ // The `text` attribute wins over the light-DOM text, because an attribute is the
210
+ // explicit write and the light text is only what the author put where the buffer goes.
211
+ area.value = this.getAttribute('text') ?? this._seedText();
212
+ area.spellcheck = false;
213
+ area.addEventListener('input', () => this._emitChanged());
214
+ area.addEventListener('keydown', (event) => {
215
+ if (event.key !== 'Tab' || !this.acceptsTab) return;
216
+ event.preventDefault();
217
+ const start = area.selectionStart ?? area.value.length;
218
+ const end = area.selectionEnd ?? start;
219
+ // `setRangeText` does not fire `input`, so the insertion GTK reports through the
220
+ // buffer's `changed` is dispatched here instead.
221
+ area.setRangeText('\t', start, end, 'end');
222
+ this._emitChanged();
223
+ });
224
+
225
+ this._area = area;
226
+ this.replaceChildren(area);
227
+ this._render();
228
+ }
229
+
230
+ attributeChangedCallback(name: string, _old: string | null, value: string | null) {
231
+ if (!this._initialized) return;
232
+ if (name === 'text') this._area.value = value ?? '';
233
+ else if (name === 'editable') this._area.readOnly = !this.editable;
234
+ this._render();
235
+ }
236
+
237
+ private _render(): void {
238
+ const wrapMode = this.wrapMode;
239
+ const area = this._area;
240
+ area.style.whiteSpace = WRAP_WHITE_SPACE[wrapMode];
241
+ // `word-char` falls back to a CHARACTER break only where a word will not fit, which
242
+ // is what `overflow-wrap: anywhere` means; `char` breaks anywhere, `word-break`.
243
+ area.style.wordBreak = wrapMode === 'char' ? 'break-all' : 'normal';
244
+ area.style.overflowWrap = wrapMode === 'word-char' ? 'anywhere' : 'normal';
245
+ area.style.textAlign = JUSTIFY_TEXT_ALIGN[this.justification];
246
+ area.style.caretColor = this.cursorVisible ? '' : 'transparent';
247
+ this.classList.toggle('monospace', this.monospace);
248
+ // The margins are custom properties the stylesheet ADDS to its own padding, because
249
+ // GTK's doc says they are applied in addition to the theme's padding
250
+ // (gtktextview.c:1050-1057) — writing `padding` from here would replace it.
251
+ area.style.setProperty('--adw-text-view-margin-top', `${this.topMargin}px`);
252
+ area.style.setProperty('--adw-text-view-margin-end', `${this.rightMargin}px`);
253
+ area.style.setProperty('--adw-text-view-margin-bottom', `${this.bottomMargin}px`);
254
+ area.style.setProperty('--adw-text-view-margin-start', `${this.leftMargin}px`);
255
+ }
256
+
257
+ /** The buffer's text before the inner control exists: the light-DOM text, or the attribute. */
258
+ private _seedText(): string {
259
+ return this.textContent;
260
+ }
261
+
262
+ /**
263
+ * `Gtk.TextBuffer:changed`, the signal a text view's edits travel on. The buffer is a
264
+ * separate GObject here (its text is the element's), so its `changed` is the one event
265
+ * this widget has to re-emit.
266
+ */
267
+ private _emitChanged(): void {
268
+ this.dispatchEvent(new CustomEvent('changed', { bubbles: true, detail: { text: this._area.value } }));
269
+ }
270
+
271
+ /** A boolean pspec read the way its default decides an attribute can spell it. */
272
+ private _bool(name: string, fallback: boolean): boolean {
273
+ const raw = this.getAttribute(name);
274
+ return raw === null ? fallback : raw !== 'false';
275
+ }
276
+
277
+ /** {@link _bool}'s writer: the pspec default is left unwritten, anything else is written. */
278
+ private _setBool(name: string, value: boolean, fallback: boolean): void {
279
+ if (value === fallback) this.removeAttribute(name);
280
+ else this.setAttribute(name, value ? 'true' : 'false');
281
+ }
282
+
283
+ /** A pixel margin, floored at 0 like every `g_param_spec_int` with a zero minimum. */
284
+ private _margin(name: string): number {
285
+ const parsed = Number.parseInt(this.getAttribute(name) ?? '', 10);
286
+ return Number.isFinite(parsed) ? Math.max(0, parsed) : 0;
287
+ }
288
+ }
289
+
290
+ customElements.define('gtk-text-view', GtkTextView);
@@ -0,0 +1,219 @@
1
+ // <gtk-text> — `Gtk.Text`, the single-line text widget GTK builds every entry out of.
2
+ //
3
+ // WHY IT EXISTS ALONGSIDE <gtk-entry>. `Gtk.Text` is "the common implementation of
4
+ // single-line text editing that is shared between Gtk.Entry, Gtk.PasswordEntry,
5
+ // Gtk.SpinButton" (gtktext.c:78-91), and its own `<gtk-text>` surface is what an author
6
+ // reaches when there is no entry AROUND it — a bare single-line field with a placeholder
7
+ // and a length limit. GTK gives that widget `AccessibleRole.none`, "which causes it to be
8
+ // skipped for accessibility … expected to be used as a delegate for a GtkEditable
9
+ // implementation" (gtktext.c:199-205); standing alone it IS the field, so the inner
10
+ // native input carries the textbox role here. That is a DECLARED divergence, and it is
11
+ // the only one about accessibility.
12
+ //
13
+ // THE LENGTH ARITHMETIC IS HEADLESS and lives in `@gjsify/adwaita-core` (ADR 0004):
14
+ // `clampEntryText` truncates on CODE POINTS, the same helper `<gtk-entry>` uses. The
15
+ // native `maxlength` attribute would not have closed the gap, because the browser counts
16
+ // UTF-16 code units — `'🔒é'` is 2 characters to GTK and 3 to `input.maxLength`.
17
+ //
18
+ // `visibility` IS A VALUE, NOT A PRESENCE: its pspec default is TRUE (gtktext.c:1778),
19
+ // so a bare `visibility` attribute would mean the same thing as leaving it off, and
20
+ // `editable` has the same default. `readBooleanAttribute` below reads both the HTML way
21
+ // (absent → the pspec default, an explicit `="false"` → off) and is what decides which
22
+ // spelling a boolean of this widget can carry.
23
+ //
24
+ // NOT PORTED, one line each, and declared in `check-adwaita-element-properties.mjs`:
25
+ // `activates-default` (GTK additionally activates the toplevel's default widget, and a
26
+ // document has none — `activate`, the signal Return is bound to at gtktext.c:1517-1520,
27
+ // fires either way), `enable-emoji-completion` (an Emoji chooser a browser has none of),
28
+ // `im-module` / `input-hints` / `input-purpose` (the input method and the on-screen
29
+ // keyboard it steers), `invisible-char` / `invisible-char-set` (GTK picks the masking
30
+ // glyph — `'*'`, the pspec default `42`, or a blank when only the flag is set,
31
+ // gtktext.c:2318-2322 — where a masked native input draws U+2022 and exposes no choice),
32
+ // `overwrite-mode` (a mode that draws a block cursor and makes every keystroke replace
33
+ // the next character; a native input overwrites an existing selection and no mode
34
+ // besides), and `truncate-multiline` (a single-line input drops every newline from a
35
+ // paste, so the property has nothing left to switch).
36
+ //
37
+ // Reference: refs/gtk/gtk/gtktext.c:78-91,1517-1520,155-167,2270-2322,2588-2611,
38
+ // 3605-3607,5742-5767,7400-7420
39
+ // Reference: refs/libadwaita/src/stylesheet/widgets/_views.scss:1-18,20-45 (`%view`, `text`)
40
+ // Reference: refs/libadwaita/src/stylesheet/widgets/_entries.scss:19-28 (placeholder, block cursor)
41
+ // Copyright (c) The GTK Team, GNOME contributors. LGPLv2.1+.
42
+ // Modifications: Implemented as a Web Component for @gjsify/adwaita-web; the length
43
+ // arithmetic composed from @gjsify/adwaita-core.
44
+
45
+ import { ENTRY_ROW_MAX_LENGTH_LIMIT, clampEntryText, entryTextLength } from '@gjsify/adwaita-core';
46
+
47
+ export class GtkText extends HTMLElement {
48
+ private _input!: HTMLInputElement;
49
+ private _initialized = false;
50
+ private _maxLength = 0;
51
+
52
+ static get observedAttributes() {
53
+ return ['text', 'editable', 'placeholder-text', 'max-length', 'visibility', 'propagate-text-width'];
54
+ }
55
+
56
+ /** `Gtk.Editable:text` — the buffer's contents, which is what the field shows. */
57
+ get text(): string {
58
+ return this._input ? this._input.value : (this.getAttribute('text') ?? '');
59
+ }
60
+
61
+ set text(value: string) {
62
+ const clamped = clampEntryText(value ?? '', this._maxLength);
63
+ if (this._input) this._input.value = clamped;
64
+ else this.setAttribute('text', clamped);
65
+ this._resizeToText();
66
+ }
67
+
68
+ /** `Gtk.Editable:editable` — defaults TRUE, so the attribute carries a VALUE. */
69
+ get editable(): boolean {
70
+ return readBooleanAttribute(this, 'editable', true);
71
+ }
72
+
73
+ set editable(value: boolean) {
74
+ writeBooleanAttribute(this, 'editable', value, true);
75
+ }
76
+
77
+ /** `Gtk.Text:placeholder-text` — shown while the field is empty and unfocused. */
78
+ get placeholderText(): string {
79
+ return this.getAttribute('placeholder-text') ?? '';
80
+ }
81
+
82
+ set placeholderText(value: string) {
83
+ this.setAttribute('placeholder-text', value ?? '');
84
+ }
85
+
86
+ /** `Gtk.Text:max-length` — 0 means unlimited. Counted in CODE POINTS. */
87
+ get maxLength(): number {
88
+ return this._maxLength;
89
+ }
90
+
91
+ set maxLength(value: number) {
92
+ this._maxLength = Number.isFinite(value)
93
+ ? Math.min(ENTRY_ROW_MAX_LENGTH_LIMIT, Math.max(0, Math.trunc(value)))
94
+ : 0;
95
+ if (this._input) this._input.value = clampEntryText(this._input.value, this._maxLength);
96
+ }
97
+
98
+ /** `Gtk.Text:visibility` — FALSE masks the contents (the "password mode"). Defaults TRUE. */
99
+ get visibility(): boolean {
100
+ return readBooleanAttribute(this, 'visibility', true);
101
+ }
102
+
103
+ set visibility(value: boolean) {
104
+ writeBooleanAttribute(this, 'visibility', value, true);
105
+ }
106
+
107
+ /**
108
+ * `Gtk.Text:propagate-text-width` — whether the widget grows and shrinks with its
109
+ * content. GTK re-measures the Pango layout on every insertion and deletion while it
110
+ * is set (gtktext.c:2588-2600,3605-3607,3639-3640); a native input has the same
111
+ * mechanism, its `size`, which is why this is a real mapping and not a measurement.
112
+ */
113
+ get propagateTextWidth(): boolean {
114
+ return readBooleanAttribute(this, 'propagate-text-width', false);
115
+ }
116
+
117
+ set propagateTextWidth(value: boolean) {
118
+ writeBooleanAttribute(this, 'propagate-text-width', value, false);
119
+ }
120
+
121
+ /** `gtk_text_get_text_length` — code points, not UTF-16 units. */
122
+ get textLength(): number {
123
+ return entryTextLength(this.text);
124
+ }
125
+
126
+ /** The inner native input, for focus and selection. */
127
+ get input(): HTMLInputElement {
128
+ return this._input;
129
+ }
130
+
131
+ connectedCallback() {
132
+ if (this._initialized) return;
133
+ this._initialized = true;
134
+
135
+ this._maxLength = Number(this.getAttribute('max-length') ?? 0);
136
+ const input = document.createElement('input');
137
+ input.className = 'adw-text';
138
+ input.type = this.visibility ? 'text' : 'password';
139
+ input.value = clampEntryText(this.getAttribute('text') ?? '', this._maxLength);
140
+ input.placeholder = this.placeholderText;
141
+ input.readOnly = !this.editable;
142
+ // Typing past the limit is clamped here, on the way in, so the field and the
143
+ // buffer agree — the same place `<gtk-entry>` clamps.
144
+ input.addEventListener('input', () => {
145
+ const clamped = clampEntryText(input.value, this._maxLength);
146
+ if (clamped !== input.value) input.value = clamped;
147
+ this._resizeToText();
148
+ });
149
+ input.addEventListener('keydown', (event) => {
150
+ if (event.key !== 'Enter') return;
151
+ this.dispatchEvent(new CustomEvent('activate', { bubbles: true, detail: { text: input.value } }));
152
+ });
153
+
154
+ this._input = input;
155
+ this.replaceChildren(input);
156
+ this._render();
157
+ }
158
+
159
+ attributeChangedCallback(name: string, _old: string | null, value: string | null) {
160
+ if (!this._initialized) {
161
+ // Before the inner input exists `max-length` is still read: it decides what the
162
+ // input is built with, so `_initialized` alone would drop a limit set in markup.
163
+ if (name === 'max-length') this._maxLength = Number(value ?? 0);
164
+ return;
165
+ }
166
+ if (name === 'text') this._input.value = clampEntryText(value ?? '', this._maxLength);
167
+ else if (name === 'placeholder-text') this._input.placeholder = value ?? '';
168
+ else if (name === 'max-length') {
169
+ this._maxLength = Number(value ?? 0);
170
+ this._input.value = clampEntryText(this._input.value, this._maxLength);
171
+ } else if (name === 'editable') this._input.readOnly = !this.editable;
172
+ else if (name === 'visibility') this._input.type = this.visibility ? 'text' : 'password';
173
+ this._resizeToText();
174
+ this._reflectReadOnly();
175
+ }
176
+
177
+ private _render(): void {
178
+ this._resizeToText();
179
+ this._reflectReadOnly();
180
+ }
181
+
182
+ /**
183
+ * `text[.read-only]` (gtktext.c:155-167) is the node class a read-only text carries,
184
+ * and libadwaita never styles it — it is a selector hook. GTK's own `set_editable`
185
+ * adds the class on the way TO editable (gtktext.c:5762-5767), which is the inverse of
186
+ * what the node documentation above it describes; the DOCUMENTED rule is what a node
187
+ * author can rely on, so that is the one applied here.
188
+ */
189
+ private _reflectReadOnly(): void {
190
+ this.classList.toggle('read-only', !this.editable);
191
+ }
192
+
193
+ private _resizeToText(): void {
194
+ const propagate = this.propagateTextWidth;
195
+ this.classList.toggle('propagate-text-width', propagate);
196
+ // Only ever RAISED: `size` is a limited-to-positive-range IDL attribute, so
197
+ // restoring it to the UA default means leaving it alone.
198
+ if (this._input && propagate) this._input.size = Math.max(1, entryTextLength(this._input.value));
199
+ }
200
+ }
201
+
202
+ /**
203
+ * A boolean GObject property, read the way its pspec default decides an attribute can
204
+ * spell it: absent is the default, a bare attribute is TRUE, and `="false"` is the opt-out.
205
+ * `Gtk.Text:visibility` and `Gtk.Editable:editable` both default TRUE, so neither can be
206
+ * carried by presence alone.
207
+ */
208
+ function readBooleanAttribute(element: HTMLElement, name: string, fallback: boolean): boolean {
209
+ const value = element.getAttribute(name);
210
+ return value === null ? fallback : value !== 'false';
211
+ }
212
+
213
+ /** {@link readBooleanAttribute}'s writer: the default is left unwritten, anything else is. */
214
+ function writeBooleanAttribute(element: HTMLElement, name: string, value: boolean, fallback: boolean): void {
215
+ if (value === fallback) element.removeAttribute(name);
216
+ else element.setAttribute(name, value ? 'true' : 'false');
217
+ }
218
+
219
+ customElements.define('gtk-text', GtkText);