@threadlabs/looma 0.28.5 → 0.28.6

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 (429) hide show
  1. package/components/ui-editor-mention-menu-item/ui-editor-mention-menu-item.html +3 -2
  2. package/dist/index.js +1 -1
  3. package/package.json +3 -2
  4. package/styles/ui-action-bar.css +13 -6
  5. package/styles/ui-affordance-scope.css +12 -5
  6. package/styles/ui-avatar-group.css +17 -10
  7. package/styles/ui-avatar.css +23 -16
  8. package/styles/ui-badge.css +78 -71
  9. package/styles/ui-breadcrumb-item.css +12 -5
  10. package/styles/ui-breadcrumbs.css +10 -3
  11. package/styles/ui-button.css +79 -72
  12. package/styles/ui-callout.css +29 -22
  13. package/styles/ui-card.css +25 -18
  14. package/styles/ui-checkbox.css +45 -37
  15. package/styles/ui-cluster.css +34 -27
  16. package/styles/ui-combobox.css +46 -39
  17. package/styles/ui-container.css +20 -13
  18. package/styles/ui-context-menu.css +17 -10
  19. package/styles/ui-cover.css +12 -5
  20. package/styles/ui-description-item.css +10 -3
  21. package/styles/ui-description-list.css +20 -13
  22. package/styles/ui-dialog.css +44 -35
  23. package/styles/ui-disclosure.css +32 -25
  24. package/styles/ui-editable.css +15 -8
  25. package/styles/ui-editor-image-toolbar.css +1 -1
  26. package/styles/ui-editor-insert-table-grid.css +11 -4
  27. package/styles/ui-editor-mention-menu-item.css +17 -8
  28. package/styles/ui-editor-mention-menu.css +14 -7
  29. package/styles/ui-editor-slash-menu-group.css +10 -3
  30. package/styles/ui-editor-slash-menu-item.css +15 -8
  31. package/styles/ui-editor-slash-menu.css +15 -8
  32. package/styles/ui-editor-surface.css +10 -3
  33. package/styles/ui-editor-table-context-menu.css +17 -10
  34. package/styles/ui-editor-table-overlay.css +17 -10
  35. package/styles/ui-editor-table-toolbar.css +22 -15
  36. package/styles/ui-editor-toolbar.css +18 -11
  37. package/styles/ui-floating-action-button.css +21 -14
  38. package/styles/ui-form-field.css +20 -13
  39. package/styles/ui-grid.css +21 -14
  40. package/styles/ui-icon-button.css +80 -73
  41. package/styles/ui-icon.css +14 -7
  42. package/styles/ui-image.css +25 -18
  43. package/styles/ui-input-group.css +34 -27
  44. package/styles/ui-input.css +42 -35
  45. package/styles/ui-list-item.css +33 -26
  46. package/styles/ui-list.css +22 -15
  47. package/styles/ui-listbox.css +22 -14
  48. package/styles/ui-menu-group.css +10 -3
  49. package/styles/ui-menu-item.css +29 -22
  50. package/styles/ui-menu.css +25 -18
  51. package/styles/ui-meter.css +36 -29
  52. package/styles/ui-nav-item.css +26 -19
  53. package/styles/ui-page-header.css +12 -5
  54. package/styles/ui-popover.css +27 -20
  55. package/styles/ui-radio-group.css +14 -6
  56. package/styles/ui-radio.css +24 -17
  57. package/styles/ui-reel.css +28 -21
  58. package/styles/ui-scroll-area.css +22 -15
  59. package/styles/ui-search-result-row.css +28 -21
  60. package/styles/ui-search-shell.css +24 -17
  61. package/styles/ui-section.css +14 -7
  62. package/styles/ui-select.css +33 -26
  63. package/styles/ui-separator.css +17 -10
  64. package/styles/ui-sidebar.css +35 -28
  65. package/styles/ui-spinner.css +32 -23
  66. package/styles/ui-stack.css +29 -21
  67. package/styles/ui-status-message.css +14 -7
  68. package/styles/ui-switch.css +29 -22
  69. package/styles/ui-switcher.css +27 -20
  70. package/styles/ui-table.css +14 -7
  71. package/styles/ui-tabs.css +24 -17
  72. package/styles/ui-text.css +35 -28
  73. package/styles/ui-textarea.css +37 -30
  74. package/styles/ui-toast-region.css +74 -63
  75. package/styles/ui-toast.css +21 -14
  76. package/styles/ui-tooltip.css +38 -31
  77. package/styles/ui-top-bar.css +19 -12
  78. package/styles/ui-tree-item.css +79 -71
  79. package/styles/ui-tree.css +18 -11
  80. package/vanilla/UiActionBar.d.ts +1 -1
  81. package/vanilla/UiActionBar.js +1 -1
  82. package/vanilla/UiAffordanceScope.d.ts +1 -1
  83. package/vanilla/UiAffordanceScope.js +1 -1
  84. package/vanilla/UiAvatar.d.ts +1 -1
  85. package/vanilla/UiAvatar.js +1 -1
  86. package/vanilla/UiAvatarGroup.d.ts +1 -1
  87. package/vanilla/UiAvatarGroup.js +1 -1
  88. package/vanilla/UiBadge.d.ts +1 -1
  89. package/vanilla/UiBadge.js +1 -1
  90. package/vanilla/UiBreadcrumbItem.d.ts +1 -1
  91. package/vanilla/UiBreadcrumbItem.js +1 -1
  92. package/vanilla/UiBreadcrumbs.d.ts +1 -1
  93. package/vanilla/UiBreadcrumbs.js +1 -1
  94. package/vanilla/UiButton.d.ts +1 -1
  95. package/vanilla/UiButton.js +19 -57
  96. package/vanilla/UiCallout.d.ts +1 -1
  97. package/vanilla/UiCallout.js +25 -73
  98. package/vanilla/UiCard.d.ts +1 -1
  99. package/vanilla/UiCard.js +1 -1
  100. package/vanilla/UiCheckbox.d.ts +1 -1
  101. package/vanilla/UiCheckbox.js +1 -1
  102. package/vanilla/UiCluster.d.ts +1 -1
  103. package/vanilla/UiCluster.js +1 -1
  104. package/vanilla/UiCombobox.d.ts +1 -1
  105. package/vanilla/UiCombobox.js +60 -166
  106. package/vanilla/UiContainer.d.ts +1 -1
  107. package/vanilla/UiContainer.js +1 -1
  108. package/vanilla/UiContextMenu.d.ts +1 -1
  109. package/vanilla/UiContextMenu.js +1 -1
  110. package/vanilla/UiCover.d.ts +1 -1
  111. package/vanilla/UiCover.js +1 -1
  112. package/vanilla/UiDescriptionItem.d.ts +1 -1
  113. package/vanilla/UiDescriptionItem.js +1 -1
  114. package/vanilla/UiDescriptionList.d.ts +1 -1
  115. package/vanilla/UiDescriptionList.js +1 -1
  116. package/vanilla/UiDialog.d.ts +1 -1
  117. package/vanilla/UiDialog.js +4 -10
  118. package/vanilla/UiDisclosure.d.ts +1 -1
  119. package/vanilla/UiDisclosure.js +1 -1
  120. package/vanilla/UiEditable.d.ts +1 -1
  121. package/vanilla/UiEditable.js +7 -19
  122. package/vanilla/UiEditorImageToolbar.d.ts +1 -1
  123. package/vanilla/UiEditorImageToolbar.js +1 -1
  124. package/vanilla/UiEditorInsertTableGrid.d.ts +1 -1
  125. package/vanilla/UiEditorInsertTableGrid.js +1 -1
  126. package/vanilla/UiEditorMentionMenu.d.ts +1 -1
  127. package/vanilla/UiEditorMentionMenu.js +17 -37
  128. package/vanilla/UiEditorMentionMenuItem.d.ts +1 -1
  129. package/vanilla/UiEditorMentionMenuItem.js +4 -10
  130. package/vanilla/UiEditorSlashMenu.d.ts +1 -1
  131. package/vanilla/UiEditorSlashMenu.js +5 -4
  132. package/vanilla/UiEditorSlashMenuGroup.d.ts +1 -1
  133. package/vanilla/UiEditorSlashMenuGroup.js +1 -1
  134. package/vanilla/UiEditorSlashMenuItem.d.ts +1 -1
  135. package/vanilla/UiEditorSlashMenuItem.js +7 -19
  136. package/vanilla/UiEditorSurface.d.ts +1 -1
  137. package/vanilla/UiEditorSurface.js +1 -1
  138. package/vanilla/UiEditorTableContextMenu.d.ts +1 -1
  139. package/vanilla/UiEditorTableContextMenu.js +6 -14
  140. package/vanilla/UiEditorTableOverlay.d.ts +1 -1
  141. package/vanilla/UiEditorTableOverlay.js +9 -25
  142. package/vanilla/UiEditorTableToolbar.d.ts +1 -1
  143. package/vanilla/UiEditorTableToolbar.js +25 -77
  144. package/vanilla/UiEditorToolbar.d.ts +1 -1
  145. package/vanilla/UiEditorToolbar.js +1 -1
  146. package/vanilla/UiFloatingActionButton.d.ts +1 -1
  147. package/vanilla/UiFloatingActionButton.js +1 -1
  148. package/vanilla/UiFormField.d.ts +1 -1
  149. package/vanilla/UiFormField.js +1 -1
  150. package/vanilla/UiGrid.d.ts +1 -1
  151. package/vanilla/UiGrid.js +1 -1
  152. package/vanilla/UiIcon.d.ts +1 -1
  153. package/vanilla/UiIcon.js +15 -47
  154. package/vanilla/UiIconButton.d.ts +1 -1
  155. package/vanilla/UiIconButton.js +4 -10
  156. package/vanilla/UiImage.d.ts +1 -1
  157. package/vanilla/UiImage.js +1 -1
  158. package/vanilla/UiInput.d.ts +1 -1
  159. package/vanilla/UiInput.js +1 -1
  160. package/vanilla/UiInputGroup.d.ts +1 -1
  161. package/vanilla/UiInputGroup.js +1 -1
  162. package/vanilla/UiList.d.ts +1 -1
  163. package/vanilla/UiList.js +1 -1
  164. package/vanilla/UiListItem.d.ts +1 -1
  165. package/vanilla/UiListItem.js +1 -1
  166. package/vanilla/UiListbox.d.ts +1 -1
  167. package/vanilla/UiListbox.js +4 -10
  168. package/vanilla/UiMenu.d.ts +1 -1
  169. package/vanilla/UiMenu.js +1 -1
  170. package/vanilla/UiMenuGroup.d.ts +1 -1
  171. package/vanilla/UiMenuGroup.js +4 -10
  172. package/vanilla/UiMenuItem.d.ts +1 -1
  173. package/vanilla/UiMenuItem.js +4 -10
  174. package/vanilla/UiMeter.d.ts +1 -1
  175. package/vanilla/UiMeter.js +13 -33
  176. package/vanilla/UiNavItem.d.ts +1 -1
  177. package/vanilla/UiNavItem.js +1 -1
  178. package/vanilla/UiPageHeader.d.ts +1 -1
  179. package/vanilla/UiPageHeader.js +1 -1
  180. package/vanilla/UiPopover.d.ts +1 -1
  181. package/vanilla/UiPopover.js +1 -1
  182. package/vanilla/UiRadio.d.ts +1 -1
  183. package/vanilla/UiRadio.js +1 -1
  184. package/vanilla/UiRadioGroup.d.ts +1 -1
  185. package/vanilla/UiRadioGroup.js +1 -1
  186. package/vanilla/UiReel.d.ts +1 -1
  187. package/vanilla/UiReel.js +1 -1
  188. package/vanilla/UiScrollArea.d.ts +1 -1
  189. package/vanilla/UiScrollArea.js +1 -1
  190. package/vanilla/UiSearchResultRow.d.ts +1 -1
  191. package/vanilla/UiSearchResultRow.js +1 -1
  192. package/vanilla/UiSearchShell.d.ts +1 -1
  193. package/vanilla/UiSearchShell.js +1 -1
  194. package/vanilla/UiSection.d.ts +1 -1
  195. package/vanilla/UiSection.js +1 -1
  196. package/vanilla/UiSelect.d.ts +1 -1
  197. package/vanilla/UiSelect.js +1 -1
  198. package/vanilla/UiSeparator.d.ts +1 -1
  199. package/vanilla/UiSeparator.js +1 -1
  200. package/vanilla/UiSidebar.d.ts +1 -1
  201. package/vanilla/UiSidebar.js +1 -1
  202. package/vanilla/UiSpinner.d.ts +1 -1
  203. package/vanilla/UiSpinner.js +1 -1
  204. package/vanilla/UiStack.d.ts +1 -1
  205. package/vanilla/UiStack.js +1 -1
  206. package/vanilla/UiStatusMessage.d.ts +1 -1
  207. package/vanilla/UiStatusMessage.js +1 -1
  208. package/vanilla/UiSwitch.d.ts +1 -1
  209. package/vanilla/UiSwitch.js +1 -1
  210. package/vanilla/UiSwitcher.d.ts +1 -1
  211. package/vanilla/UiSwitcher.js +1 -1
  212. package/vanilla/UiTable.d.ts +1 -1
  213. package/vanilla/UiTable.js +1 -1
  214. package/vanilla/UiTabs.d.ts +1 -1
  215. package/vanilla/UiTabs.js +1 -1
  216. package/vanilla/UiText.d.ts +1 -1
  217. package/vanilla/UiText.js +1 -1
  218. package/vanilla/UiTextarea.d.ts +1 -1
  219. package/vanilla/UiTextarea.js +1 -1
  220. package/vanilla/UiToast.d.ts +1 -1
  221. package/vanilla/UiToast.js +1 -1
  222. package/vanilla/UiToastRegion.d.ts +1 -1
  223. package/vanilla/UiToastRegion.js +1 -1
  224. package/vanilla/UiTooltip.d.ts +1 -1
  225. package/vanilla/UiTooltip.js +1 -1
  226. package/vanilla/UiTopBar.d.ts +1 -1
  227. package/vanilla/UiTopBar.js +1 -1
  228. package/vanilla/UiTree.d.ts +1 -1
  229. package/vanilla/UiTree.js +1 -1
  230. package/vanilla/UiTreeItem.d.ts +1 -1
  231. package/vanilla/UiTreeItem.js +7 -19
  232. package/vue/UiActionBar.vue +46 -78
  233. package/vue/UiAffordanceScope.vue +27 -66
  234. package/vue/UiAvatar.d.ts +10 -7
  235. package/vue/UiAvatar.vue +100 -218
  236. package/vue/UiAvatarGroup.d.ts +10 -7
  237. package/vue/UiAvatarGroup.vue +78 -160
  238. package/vue/UiBadge.d.ts +1 -1
  239. package/vue/UiBadge.vue +483 -520
  240. package/vue/UiBreadcrumbItem.vue +52 -123
  241. package/vue/UiBreadcrumbs.vue +27 -70
  242. package/vue/UiButton.d.ts +2 -2
  243. package/vue/UiButton.vue +420 -471
  244. package/vue/UiCallout.vue +131 -175
  245. package/vue/UiCard.d.ts +1 -1
  246. package/vue/UiCard.vue +112 -151
  247. package/vue/UiCheckbox.d.ts +13 -10
  248. package/vue/UiCheckbox.vue +160 -221
  249. package/vue/UiCluster.d.ts +1 -1
  250. package/vue/UiCluster.vue +84 -128
  251. package/vue/UiCombobox.d.ts +71 -68
  252. package/vue/UiCombobox.vue +417 -743
  253. package/vue/UiContainer.vue +43 -87
  254. package/vue/UiContextMenu.d.ts +6 -6
  255. package/vue/UiContextMenu.vue +78 -117
  256. package/vue/UiCover.vue +29 -69
  257. package/vue/UiDescriptionItem.vue +39 -82
  258. package/vue/UiDescriptionList.vue +64 -107
  259. package/vue/UiDialog.d.ts +22 -19
  260. package/vue/UiDialog.vue +193 -246
  261. package/vue/UiDisclosure.d.ts +22 -19
  262. package/vue/UiDisclosure.vue +192 -283
  263. package/vue/UiEditable.d.ts +5 -5
  264. package/vue/UiEditable.vue +124 -207
  265. package/vue/UiEditorImageToolbar.d.ts +2 -2
  266. package/vue/UiEditorImageToolbar.vue +41 -251
  267. package/vue/UiEditorInsertTableGrid.d.ts +2 -2
  268. package/vue/UiEditorInsertTableGrid.vue +98 -266
  269. package/vue/UiEditorMentionMenu.d.ts +15 -12
  270. package/vue/UiEditorMentionMenu.vue +150 -239
  271. package/vue/UiEditorMentionMenuItem.vue +66 -110
  272. package/vue/UiEditorSlashMenu.d.ts +16 -13
  273. package/vue/UiEditorSlashMenu.vue +172 -253
  274. package/vue/UiEditorSlashMenuGroup.vue +25 -69
  275. package/vue/UiEditorSlashMenuItem.vue +67 -115
  276. package/vue/UiEditorSurface.vue +19 -63
  277. package/vue/UiEditorTableContextMenu.vue +135 -269
  278. package/vue/UiEditorTableOverlay.d.ts +2 -2
  279. package/vue/UiEditorTableOverlay.vue +310 -479
  280. package/vue/UiEditorTableToolbar.d.ts +2 -2
  281. package/vue/UiEditorTableToolbar.vue +182 -357
  282. package/vue/UiEditorToolbar.vue +143 -183
  283. package/vue/UiFloatingActionButton.vue +70 -114
  284. package/vue/UiFormField.d.ts +1 -1
  285. package/vue/UiFormField.vue +76 -117
  286. package/vue/UiGrid.d.ts +1 -1
  287. package/vue/UiGrid.vue +65 -103
  288. package/vue/UiIcon.vue +32 -106
  289. package/vue/UiIconButton.d.ts +2 -2
  290. package/vue/UiIconButton.vue +359 -411
  291. package/vue/UiImage.vue +145 -180
  292. package/vue/UiInput.vue +158 -190
  293. package/vue/UiInputGroup.vue +199 -239
  294. package/vue/UiList.vue +67 -109
  295. package/vue/UiListItem.vue +154 -201
  296. package/vue/UiListbox.d.ts +10 -7
  297. package/vue/UiListbox.vue +86 -260
  298. package/vue/UiMenu.d.ts +11 -11
  299. package/vue/UiMenu.vue +118 -152
  300. package/vue/UiMenuGroup.vue +21 -67
  301. package/vue/UiMenuItem.d.ts +19 -16
  302. package/vue/UiMenuItem.vue +169 -262
  303. package/vue/UiMeter.d.ts +4 -4
  304. package/vue/UiMeter.vue +166 -680
  305. package/vue/UiNavItem.vue +140 -213
  306. package/vue/UiPageHeader.vue +81 -127
  307. package/vue/UiPopover.d.ts +7 -7
  308. package/vue/UiPopover.vue +90 -129
  309. package/vue/UiRadio.d.ts +12 -9
  310. package/vue/UiRadio.vue +91 -149
  311. package/vue/UiRadioGroup.d.ts +2 -2
  312. package/vue/UiRadioGroup.vue +47 -85
  313. package/vue/UiReel.vue +89 -130
  314. package/vue/UiScrollArea.d.ts +1 -1
  315. package/vue/UiScrollArea.vue +78 -119
  316. package/vue/UiSearchResultRow.vue +96 -149
  317. package/vue/UiSearchShell.d.ts +2 -2
  318. package/vue/UiSearchShell.vue +159 -196
  319. package/vue/UiSection.vue +105 -149
  320. package/vue/UiSelect.d.ts +1 -1
  321. package/vue/UiSelect.vue +114 -146
  322. package/vue/UiSeparator.vue +42 -85
  323. package/vue/UiSidebar.d.ts +10 -7
  324. package/vue/UiSidebar.vue +193 -260
  325. package/vue/UiSpinner.vue +54 -130
  326. package/vue/UiStack.vue +66 -107
  327. package/vue/UiStatusMessage.d.ts +1 -1
  328. package/vue/UiStatusMessage.vue +61 -135
  329. package/vue/UiSwitch.d.ts +12 -9
  330. package/vue/UiSwitch.vue +136 -194
  331. package/vue/UiSwitcher.vue +69 -107
  332. package/vue/UiTable.vue +121 -156
  333. package/vue/UiTabs.d.ts +1 -1
  334. package/vue/UiTabs.vue +139 -267
  335. package/vue/UiText.d.ts +4 -4
  336. package/vue/UiText.vue +145 -184
  337. package/vue/UiTextarea.d.ts +2 -2
  338. package/vue/UiTextarea.vue +162 -194
  339. package/vue/UiToast.vue +70 -118
  340. package/vue/UiToastRegion.vue +157 -276
  341. package/vue/UiTooltip.d.ts +21 -18
  342. package/vue/UiTooltip.vue +174 -234
  343. package/vue/UiTopBar.vue +48 -76
  344. package/vue/UiTree.vue +46 -79
  345. package/vue/UiTreeItem.d.ts +18 -15
  346. package/vue/UiTreeItem.vue +526 -668
  347. package/vue/chunks/UiActionBar.js +5 -17
  348. package/vue/chunks/UiAffordanceScope.js +7 -26
  349. package/vue/chunks/UiAvatar.js +20 -74
  350. package/vue/chunks/UiAvatarGroup.js +14 -56
  351. package/vue/chunks/UiBadge.js +10 -28
  352. package/vue/chunks/UiBreadcrumbItem.js +11 -41
  353. package/vue/chunks/UiBreadcrumbs.js +7 -25
  354. package/vue/chunks/UiButton.js +80 -103
  355. package/vue/chunks/UiCallout.js +9 -27
  356. package/vue/chunks/UiCard.js +33 -53
  357. package/vue/chunks/UiCheckbox.js +14 -46
  358. package/vue/chunks/UiCluster.js +13 -31
  359. package/vue/chunks/UiCombobox.js +99 -237
  360. package/vue/chunks/UiContainer.js +9 -27
  361. package/vue/chunks/UiContextMenu.js +7 -26
  362. package/vue/chunks/UiCover.js +7 -25
  363. package/vue/chunks/UiDescriptionItem.js +6 -24
  364. package/vue/chunks/UiDescriptionList.js +9 -27
  365. package/vue/chunks/UiDialog.js +18 -47
  366. package/vue/chunks/UiDisclosure.js +19 -66
  367. package/vue/chunks/UiEditable.js +18 -60
  368. package/vue/chunks/UiEditorImageToolbar.js +34 -103
  369. package/vue/chunks/UiEditorInsertTableGrid.js +14 -112
  370. package/vue/chunks/UiEditorMentionMenu.js +16 -54
  371. package/vue/chunks/UiEditorMentionMenuItem.js +10 -28
  372. package/vue/chunks/UiEditorSlashMenu.js +17 -46
  373. package/vue/chunks/UiEditorSlashMenuGroup.js +7 -25
  374. package/vue/chunks/UiEditorSlashMenuItem.js +16 -31
  375. package/vue/chunks/UiEditorSurface.js +7 -25
  376. package/vue/chunks/UiEditorTableContextMenu.js +25 -102
  377. package/vue/chunks/UiEditorTableOverlay.js +41 -104
  378. package/vue/chunks/UiEditorTableToolbar.js +44 -122
  379. package/vue/chunks/UiEditorToolbar.js +7 -26
  380. package/vue/chunks/UiFloatingActionButton.js +10 -28
  381. package/vue/chunks/UiFormField.js +8 -27
  382. package/vue/chunks/UiGrid.js +10 -28
  383. package/vue/chunks/UiIcon.js +21 -74
  384. package/vue/chunks/UiIconButton.js +18 -50
  385. package/vue/chunks/UiImage.js +14 -33
  386. package/vue/chunks/UiInput.js +12 -31
  387. package/vue/chunks/UiInputGroup.js +10 -29
  388. package/vue/chunks/UiList.js +17 -37
  389. package/vue/chunks/UiListItem.js +12 -30
  390. package/vue/chunks/UiListbox.js +22 -124
  391. package/vue/chunks/UiMenu.js +13 -32
  392. package/vue/chunks/UiMenuGroup.js +8 -26
  393. package/vue/chunks/UiMenuItem.js +35 -80
  394. package/vue/chunks/UiMeter.js +17 -351
  395. package/vue/chunks/UiNavItem.js +23 -57
  396. package/vue/chunks/UiPageHeader.js +7 -25
  397. package/vue/chunks/UiPopover.js +9 -28
  398. package/vue/chunks/UiRadio.js +11 -43
  399. package/vue/chunks/UiRadioGroup.js +13 -32
  400. package/vue/chunks/UiReel.js +10 -28
  401. package/vue/chunks/UiScrollArea.js +10 -29
  402. package/vue/chunks/UiSearchResultRow.js +10 -28
  403. package/vue/chunks/UiSearchShell.js +9 -28
  404. package/vue/chunks/UiSection.js +9 -27
  405. package/vue/chunks/UiSelect.js +10 -29
  406. package/vue/chunks/UiSeparator.js +10 -28
  407. package/vue/chunks/UiSidebar.js +15 -47
  408. package/vue/chunks/UiSpinner.js +8 -44
  409. package/vue/chunks/UiStack.js +12 -30
  410. package/vue/chunks/UiStatusMessage.js +10 -42
  411. package/vue/chunks/UiSwitch.js +11 -43
  412. package/vue/chunks/UiSwitcher.js +9 -28
  413. package/vue/chunks/UiTable.js +7 -26
  414. package/vue/chunks/UiTabs.js +15 -91
  415. package/vue/chunks/UiText.js +148 -168
  416. package/vue/chunks/UiTextarea.js +16 -35
  417. package/vue/chunks/UiToast.js +13 -37
  418. package/vue/chunks/UiToastRegion.js +16 -88
  419. package/vue/chunks/UiTooltip.js +14 -46
  420. package/vue/chunks/UiTopBar.js +5 -17
  421. package/vue/chunks/UiTree.js +13 -32
  422. package/vue/chunks/UiTreeItem.js +34 -90
  423. package/vue/chunks/_plugin-vue_export-helper.js +904 -1
  424. package/vue/chunks/control.js +3 -0
  425. package/vue/chunks/props.js +1 -1
  426. package/vue/components.css +7606 -7534
  427. package/vue/editor/index.js +1 -1
  428. package/vue/host.ts +999 -14
  429. package/vue/chunks/host.js +0 -443
package/vue/UiButton.vue CHANGED
@@ -1,8 +1,17 @@
1
- <!-- Generated by HTML Next 1.0.0-alpha.35 for Vue 3.5. Do not edit. -->
1
+ <!-- Generated by HTML Next 1.0.0-alpha.51 for Vue 3.5. Do not edit. -->
2
2
  <script setup lang="ts">
3
3
  import { computed, getCurrentInstance, useTemplateRef, watchSyncEffect } from 'vue'
4
4
  import type { PropType } from 'vue'
5
- import { createDispatch, preserveRootFocus, useComponentHost } from './host'
5
+ import {
6
+ attribute,
7
+ checkHydratedRoot,
8
+ concat,
9
+ createDispatch,
10
+ nativeAttrs,
11
+ preserveRootFocus,
12
+ useComponentHost,
13
+ useReflectedProp,
14
+ } from './host'
6
15
  import { checkedProp, propValidityState, vPropValidity } from './props'
7
16
  import UiIcon from './UiIcon.vue'
8
17
  import UiSpinner from './UiSpinner.vue'
@@ -275,38 +284,7 @@ void checkedProps.value
275
284
  watchSyncEffect(() => {
276
285
  void checkedProps.value
277
286
  })
278
- function nativeAttrs(attrs: Record<string, unknown>): Record<string, unknown> {
279
- const names = Object.keys(attrs)
280
- if (!names.some((name) => Object.hasOwn(Object.prototype, name))) return attrs
281
- return Object.fromEntries(names.map((name) => [
282
- Object.hasOwn(Object.prototype, name)
283
- ? name === '__proto__' ? '__Proto__' : name[0]!.toUpperCase() + name.slice(1)
284
- : name,
285
- attrs[name],
286
- ]))
287
- }
288
- const componentInstance = getCurrentInstance()
289
- function reflectedProp(
290
- name: string,
291
- kebab: string,
292
- value: unknown,
293
- fallback: string | undefined,
294
- bound: boolean,
295
- separator?: string,
296
- ): string | undefined {
297
- const incoming = componentInstance?.vnode.props
298
- if (
299
- !bound
300
- && (incoming === null || incoming === undefined
301
- || (!Object.hasOwn(incoming, name) && !Object.hasOwn(incoming, kebab)))
302
- ) return fallback
303
- if (value === null || value === undefined) return undefined
304
- return Array.isArray(value) && separator !== undefined
305
- ? value.join(separator)
306
- : typeof value === 'object'
307
- ? JSON.stringify(value)
308
- : String(value)
309
- }
287
+ const reflectedProp = useReflectedProp()
310
288
  const hydrationInstance = getCurrentInstance()
311
289
 
312
290
  const rootArmElement = useTemplateRef<HTMLElement>('@html-next/root')
@@ -590,25 +568,14 @@ const guardedBinding7 = computed(() => {
590
568
  concat(checkedProps.value.loading || checkedProps.value.pending),
591
569
  ))
592
570
  })
593
- const hydrationNode = hydrationInstance?.vnode.el
594
- if (
595
- typeof window !== 'undefined' && hydrationNode != null
596
- && (!(hydrationNode instanceof Element)
597
- || hydrationNode.localName
598
- !== ((checkedProps.value.variant === 'card' && checkedProps.value.as === 'a')
599
- ? 'a'
600
- : ((checkedProps.value.variant === 'card')
601
- ? 'button'
602
- : ((checkedProps.value.as === 'a') ? 'a' : ('button')))))
603
- ) {
604
- throw Object.assign(new Error('HR005: Server markup for <ui-button> has an incompatible root.'), {
605
- name: 'HtmlDiagnosticError',
606
- diagnostic: Object.freeze({
607
- code: 'HR005',
608
- message: 'Server markup for <ui-button> has an incompatible root.',
609
- }),
610
- })
611
- }
571
+ checkHydratedRoot(
572
+ (checkedProps.value.variant === 'card' && checkedProps.value.as === 'a')
573
+ ? 'a'
574
+ : ((checkedProps.value.variant === 'card')
575
+ ? 'button'
576
+ : ((checkedProps.value.as === 'a') ? 'a' : ('button'))),
577
+ 'ui-button',
578
+ )
612
579
 
613
580
  /** The values the styles' :host-state() rules test. */
614
581
  const hostState = computed(() =>
@@ -666,43 +633,12 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
666
633
  propValidity: (name: string) =>
667
634
  propValidityState({ contract: propValidityContract, values: { ...props } }, name),
668
635
  })
669
-
670
- function text(value: unknown): string {
671
- if (Array.isArray(value)) return value.map(text).join(' ')
672
- return value === null || value === undefined || typeof value === 'object' ? '' : String(value)
673
- }
674
-
675
- function attribute(value: unknown): any {
676
- if (
677
- value === null || value === undefined || value === false
678
- || (typeof value === 'object' && !Array.isArray(value))
679
- ) return undefined
680
- return value === true ? '' : text(value)
681
- }
682
-
683
- // A nonempty scalar call cannot produce the invalid-result sentinel.
684
- type ConcatResult<T extends unknown[]> = T extends
685
- [
686
- string | number | boolean | null | undefined,
687
- ...(string | number | boolean | null | undefined)[],
688
- ] ? string | undefined
689
- : string | symbol | undefined
690
- function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
691
- if (values.some(value => value === Symbol.for('html-next.invalid-result'))) {
692
- return Symbol.for('html-next.invalid-result') as ConcatResult<T>
693
- }
694
- if (values.some(value => value === undefined)) return undefined as ConcatResult<T>
695
- if (values.length === 0 || values.some(value => typeof value === 'object' && value !== null)) {
696
- return Symbol.for('html-next.invalid-result') as ConcatResult<T>
697
- }
698
- return values.map(value => value === null ? '' : String(value)).join('') as ConcatResult<T>
699
- }
700
636
  </script>
701
637
 
702
638
  <template>
703
639
  <a
704
640
  v-if="checkedProps.variant === 'card' && checkedProps.as === 'a'"
705
- data-component="ui-button"
641
+ class="ui-button"
706
642
  v-bind="nativeAttrs($attrs)"
707
643
  :href="guarded"
708
644
  :target="checkedProps.target ?? undefined"
@@ -729,6 +665,7 @@ function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
729
665
  ref="@html-next/root"
730
666
  ><span class="card-icon"><UiSpinner
731
667
  v-if="checkedProps.loading || checkedProps.pending"
668
+ class="ui-spinner"
732
669
  size="sm"
733
670
  />
734
671
  <template v-if="!(checkedProps.loading || checkedProps.pending)"><slot
@@ -736,12 +673,13 @@ function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
736
673
  /></template></span>
737
674
  <span class="card-content"><slot /></span>
738
675
  <span class="card-action"><slot name="action"><UiIcon
676
+ class="ui-icon"
739
677
  name="chevron-right"
740
678
  aria-hidden="true"
741
679
  /></slot></span></a>
742
680
  <button
743
681
  v-else-if="checkedProps.variant === 'card'"
744
- data-component="ui-button"
682
+ class="ui-button"
745
683
  v-bind="nativeAttrs($attrs)"
746
684
  :type="checkedProps.type ?? undefined"
747
685
  :disabled="checkedProps.disabled ?? undefined"
@@ -767,6 +705,7 @@ function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
767
705
  >
768
706
  <span class="card-icon"><UiSpinner
769
707
  v-if="checkedProps.loading || checkedProps.pending"
708
+ class="ui-spinner"
770
709
  size="sm"
771
710
  />
772
711
  <template v-if="!(checkedProps.loading || checkedProps.pending)"><slot
@@ -774,13 +713,14 @@ function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
774
713
  /></template></span>
775
714
  <span class="card-content"><slot /></span>
776
715
  <span class="card-action"><slot name="action"><UiIcon
716
+ class="ui-icon"
777
717
  name="chevron-right"
778
718
  aria-hidden="true"
779
719
  /></slot></span>
780
720
  </button>
781
721
  <a
782
722
  v-else-if="checkedProps.as === 'a'"
783
- data-component="ui-button"
723
+ class="ui-button"
784
724
  v-bind="nativeAttrs($attrs)"
785
725
  :href="guardedBinding4"
786
726
  :target="checkedProps.target ?? undefined"
@@ -806,13 +746,14 @@ function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
806
746
  :data-ui-button-state="hostState || undefined"
807
747
  ref="@html-next/root"
808
748
  ><span v-if="checkedProps.loading || checkedProps.pending" class="spinner-wrap"><UiSpinner
749
+ class="ui-spinner"
809
750
  size="sm"
810
751
  /></span>
811
752
  <slot />
812
753
  <span class="badge"><slot name="badge" /></span></a>
813
754
  <button
814
755
  v-else
815
- data-component="ui-button"
756
+ class="ui-button"
816
757
  v-bind="nativeAttrs($attrs)"
817
758
  :type="checkedProps.type ?? undefined"
818
759
  :disabled="checkedProps.disabled ?? undefined"
@@ -837,6 +778,7 @@ function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
837
778
  ref="@html-next/root"
838
779
  >
839
780
  <span v-if="checkedProps.loading || checkedProps.pending" class="spinner-wrap"><UiSpinner
781
+ class="ui-spinner"
840
782
  size="sm"
841
783
  /></span>
842
784
  <slot />
@@ -919,440 +861,447 @@ function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
919
861
  inherits: false;
920
862
  }
921
863
 
922
- [data-component~="ui-button"] {
923
- /* Optional inherited action-group values keep text and icon actions under the same light.
924
- One fine top/start highlight follows the bottom/end lowlight at a joined action seam.
925
- A single ambient lift avoids stacking a face gradient or another inset bevel. */
926
- --_ui-action-start: 1px;
927
- --_ui-action-edge: var(
928
- --ui-action-edge,
929
- inset var(--_ui-action-start) 1px 0 light-dark(
930
- rgb(255 255 255 / 0.08),
931
- rgb(255 255 255 / 0.06)
932
- ),
933
- inset calc(-1 * var(--_ui-action-start)) -1px 0 light-dark(rgb(0 0 0 / 0.08), rgb(0 0 0 / 0.08))
934
- );
935
- --_ui-action-shadow:
936
- var(--_ui-action-edge),
937
- 0 1px 2px light-dark(rgb(0 0 0 / 0.10), rgb(0 0 0 / 0.20));
938
- --_hue: var(--ui-accent);
939
- --_hue-hover: var(--ui-accent-hover);
940
- --_hue-active: var(--ui-accent-active);
941
- --_hue-text: var(--ui-accent-active);
942
- --_on-hue: var(--ui-on-accent);
864
+ /* An anchor keeps the boxed button look even when an app styles ordinary links. */
943
865
 
944
- --_tone: var(--_hue);
945
- --_tone-hover: var(--_hue-hover);
946
- --_tone-active: var(--_hue-active);
947
- --_tone-text: var(--_hue-text);
948
- --_on-tone: var(--_on-hue);
866
+ /* A count is an adornment, not another line of label text. Keep the standard control height
867
+ with enough inset for a 24px mark; large content can still grow the button naturally. */
949
868
 
950
- display: inline-flex;
951
- align-items: center;
952
- justify-content: center;
953
- column-gap: var(--ui-space-2);
954
- vertical-align: middle;
955
- color: var(--_tone-text);
956
- }
869
+ /* Card actions inherit Button's palette and behavior; only their shared layout changes.
870
+ The icon may contain any decorative composition. Empty icons remove their column. */
957
871
 
958
- [data-component~="ui-button"]:dir(rtl) {
959
- --_ui-action-start: -1px;
960
- }
872
+ /* A link is never :enabled, so interactive states test "not unavailable" instead: for a button that
873
+ is exactly :enabled, at the same specificity, and it also matches a link that can be followed. */
961
874
 
962
- [data-component~="ui-button"][data-ui-button-state~="align=start"] {
963
- justify-content: flex-start;
964
- text-align: start;
965
- }
875
+ /* A neutral card encloses content quietly; ordinary outlines keep their action-tone edge. */
966
876
 
967
- [data-component~="ui-button"][data-ui-button-state~="stretch"] {
968
- display: flex;
969
- inline-size: 100%;
970
- }
877
+ /* Pressed reads as pressed in: the highlight goes, and the shadow moves inside. */
971
878
 
972
- [data-component~="ui-button"] {
973
- appearance: none;
974
- min-block-size: var(--ui-button-min-block-size, var(--ui-control-size-md));
975
- border-style: solid;
976
- border-width: var(--ui-border-width);
977
- border-color: var(--ui-button-border, var(--_tone));
978
- border-radius: var(--ui-button-radius, var(--ui-action-radius, var(--ui-radius-md)));
979
- background-color: var(--ui-button-surface, oklch(from var(--_tone) l c h / 5%));
980
- color: var(--ui-button-text, var(--_tone-text));
981
- font: inherit;
982
- font-weight: var(--ui-font-medium);
983
- text-decoration: none;
984
- /* Unset, a button wraps as its container does. */
985
- white-space: var(--ui-button-white-space, inherit);
986
- line-height: var(--ui-line-height-tight);
987
- padding: var(--ui-space-2) var(--ui-space-3);
988
- background-image: none;
989
- box-shadow: var(--ui-button-shadow, var(--ui-action-shadow, var(--_ui-action-shadow)));
990
- cursor: pointer;
991
- transition:
992
- background-color var(--ui-motion-fast) var(--ui-motion-ease),
993
- border-color var(--ui-motion-fast) var(--ui-motion-ease),
994
- color var(--ui-motion-fast) var(--ui-motion-ease),
995
- box-shadow var(--ui-motion-base) var(--ui-motion-ease);
996
- margin: 0;
997
- }
879
+ /* Tone is the colour, variant is the volume. Every pairing works: a danger outline is a
880
+ destructive secondary action, not a special case. */
998
881
 
999
- /* An anchor keeps the boxed button look even when an app styles ordinary links. */
1000
- [data-component~="ui-button"]:is(a) {
1001
- text-decoration: none;
1002
- }
882
+ /* A value picker is a field, with Select's quiet edge and resting lift. */
1003
883
 
1004
- .spinner-wrap {
1005
- display: inline-flex;
1006
- flex: none;
1007
- vertical-align: middle;
1008
- }
884
+ /* Tints derive from the text colour, not a surface token, so hover and press show on any background. */
1009
885
 
1010
- /* A count is an adornment, not another line of label text. Keep the standard control height
1011
- with enough inset for a 24px mark; large content can still grow the button naturally. */
1012
- [data-component~="ui-button"]:not([variant="link"]):has(.badge:not(:empty)) {
1013
- padding-block: var(--ui-space-0-5);
1014
- }
886
+ /* Pressed, or holding its menu open, a ghost button sinks slightly: a light surface with a faint
887
+ edge and a soft inner shadow. Lighter than hover, so an open menu's trigger never reads as heavy. */
1015
888
 
1016
- .badge {
1017
- display: inline-flex;
1018
- align-items: center;
1019
- flex: none;
1020
- }
889
+ /* A soft halo that transitions in with the other box-shadow changes, layered on the raised shadow. */
1021
890
 
1022
- .badge:empty {
1023
- display: none;
1024
- }
891
+ /* A loading action stays visually active; only an explicitly disabled action takes the
892
+ neutral disabled palette. Its flat surface and muted ink make the state unambiguous. */
1025
893
 
1026
- @supports (text-box-trim: trim-both) {
1027
- [data-component~="ui-button"] {
1028
- text-box-trim: trim-both;
1029
- text-box-edge: cap alphabetic;
1030
- }
1031
- }
894
+ /* Ghost keeps no border, but gains the same neutral surface as other disabled buttons. */
1032
895
 
1033
- [data-component~="ui-button"][data-ui-button-state~="size=xs"] {
1034
- min-block-size: 1.5rem;
1035
- padding: calc(var(--ui-space-0-5) * 1.5) calc(var(--ui-space-1) * 1.25);
1036
- font-size: var(--ui-font-size-xs);
1037
- }
896
+ /* The size states outrank :host, so sm is named too, or a small button would stay small. */
1038
897
 
1039
- [data-component~="ui-button"][data-ui-button-state~="shape=pill"] {
1040
- border-radius: var(--ui-button-radius, var(--ui-radius-round));
1041
- }
898
+ /* Under touch, a link-style button's press lands within the control minimum: an invisible hit
899
+ area, centred on it, like IconButton's. A boxed button grows to the minimum itself (below);
900
+ a link-style one keeps its text size, so a standalone one ("See all" under a list) needs the
901
+ area. xs sits inside a line of text the same way, so it keeps its size and gains the area too.
902
+ Only these need it: a hit area on every button would reach over its neighbours. */
1042
903
 
1043
- [data-component~="ui-button"][data-ui-button-state~="size=sm"] {
1044
- min-block-size: var(--ui-control-size-sm);
1045
- padding: var(--ui-space-1) var(--ui-space-2);
1046
- font-size: var(--ui-font-size-sm);
1047
- }
904
+ /* Link: an inline text action. No box, padding, or minimum height (inline targets are exempt under
905
+ WCAG 2.5.8); the inherited font; an underline that strengthens on hover; a visible focus ring. */
1048
906
 
1049
- [data-component~="ui-button"][data-ui-button-state~="size=lg"] {
1050
- min-block-size: var(--ui-control-size-lg);
1051
- padding: var(--ui-space-3) var(--ui-space-4);
1052
- font-size: var(--ui-font-size-md);
1053
- }
907
+ /* A component that sets its display still honours the hidden attribute on its root. */
1054
908
 
1055
- /* Card actions inherit Button's palette and behavior; only their shared layout changes.
1056
- The icon may contain any decorative composition. Empty icons remove their column. */
1057
- [data-component~="ui-button"][data-ui-button-state~="variant=card"] {
1058
- display: grid;
1059
- grid-template-columns: auto minmax(0, 1fr) auto;
1060
- align-content: center;
1061
- align-items: start;
1062
- gap: var(--ui-space-3);
1063
- inline-size: 100%;
1064
- min-block-size: max(var(--ui-control-min-block-size), var(--ui-control-size-md));
1065
- text-align: start;
1066
- white-space: normal;
1067
- box-shadow: none;
1068
- background-image: none;
1069
- }
1070
- [data-component~="ui-button"][data-ui-button-state~="variant=card"][data-ui-button-state~="size=lg"] {
1071
- min-block-size: max(var(--ui-control-min-block-size), var(--ui-control-size-lg));
1072
- }
1073
- [data-component~="ui-button"][data-ui-button-state~="variant=card"]:has(.card-icon:empty) {
1074
- grid-template-columns: minmax(0, 1fr) auto;
1075
- }
1076
- .card-icon {
1077
- display: flex;
1078
- align-items: flex-start;
1079
- }
1080
- .card-icon:empty {
1081
- display: none;
1082
- }
1083
- .card-content {
1084
- min-inline-size: 0;
1085
- }
1086
- .card-action {
1087
- display: flex;
1088
- align-items: center;
1089
- align-self: center;
1090
- }
909
+ @scope (.ui-button) to (.ui-spinner, .ui-icon) {
910
+ :scope:where(:scope) {
911
+ /* Optional inherited action-group values keep text and icon actions under the same light.
912
+ One fine top/start highlight follows the bottom/end lowlight at a joined action seam.
913
+ A single ambient lift avoids stacking a face gradient or another inset bevel. */
914
+ --_ui-action-start: 1px;
915
+ --_ui-action-edge: var(
916
+ --ui-action-edge,
917
+ inset var(--_ui-action-start) 1px 0 light-dark(
918
+ rgb(255 255 255 / 0.08),
919
+ rgb(255 255 255 / 0.06)
920
+ ),
921
+ inset calc(-1 * var(--_ui-action-start)) -1px 0 light-dark(
922
+ rgb(0 0 0 / 0.08),
923
+ rgb(0 0 0 / 0.08)
924
+ )
925
+ );
926
+ --_ui-action-shadow:
927
+ var(--_ui-action-edge),
928
+ 0 1px 2px light-dark(rgb(0 0 0 / 0.10), rgb(0 0 0 / 0.20));
929
+ --_hue: var(--ui-accent);
930
+ --_hue-hover: var(--ui-accent-hover);
931
+ --_hue-active: var(--ui-accent-active);
932
+ --_hue-text: var(--ui-accent-active);
933
+ --_on-hue: var(--ui-on-accent);
1091
934
 
1092
- /* A link is never :enabled, so interactive states test "not unavailable" instead: for a button that
1093
- is exactly :enabled, at the same specificity, and it also matches a link that can be followed. */
1094
- [data-component~="ui-button"]:hover:not(:disabled, [aria-disabled="true"]) {
1095
- border-color: var(--ui-button-hover-border, var(--_tone-hover));
1096
- background-color: var(--ui-button-hover-surface, oklch(from var(--_tone) l c h / 12%));
1097
- }
935
+ --_tone: var(--_hue);
936
+ --_tone-hover: var(--_hue-hover);
937
+ --_tone-active: var(--_hue-active);
938
+ --_tone-text: var(--_hue-text);
939
+ --_on-tone: var(--_on-hue);
1098
940
 
1099
- /* A neutral card encloses content quietly; ordinary outlines keep their action-tone edge. */
1100
- [data-component~="ui-button"][data-ui-button-state~="variant=card"][data-ui-button-state~="tone=neutral"] {
1101
- border-color: var(--ui-button-border, var(--ui-border));
1102
- }
941
+ display: inline-flex;
942
+ align-items: center;
943
+ justify-content: center;
944
+ column-gap: var(--ui-space-2);
945
+ vertical-align: middle;
946
+ color: var(--_tone-text);
947
+ }
1103
948
 
1104
- [data-component~="ui-button"][data-ui-button-state~="variant=card"][data-ui-button-state~="tone=neutral"]:hover:not(:disabled, [aria-disabled="true"]) {
1105
- border-color: var(--ui-button-hover-border, var(--ui-border-strong));
1106
- }
949
+ :scope:where(:scope):is(:dir(rtl)) {
950
+ --_ui-action-start: -1px;
951
+ }
1107
952
 
1108
- /* Pressed reads as pressed in: the highlight goes, and the shadow moves inside. */
1109
- [data-component~="ui-button"]:active:not(:disabled, [aria-disabled="true"]) {
1110
- background-color: var(--ui-button-active-surface, oklch(from var(--_tone) l c h / 18%));
1111
- background-image: none;
1112
- box-shadow: var(--ui-pressed);
1113
- }
953
+ :scope:where(:scope):is([data-ui-button-state~="align=start"]) {
954
+ justify-content: flex-start;
955
+ text-align: start;
956
+ }
1114
957
 
1115
- [data-component~="ui-button"][data-ui-button-state~="variant=solid"],
1116
- [data-component~="ui-button"][data-ui-button-state~="variant=danger"] {
1117
- border-color: var(--_tone);
1118
- background-color: var(--_tone);
1119
- color: var(--_on-tone);
1120
- box-shadow: var(--ui-button-solid-shadow, var(--ui-action-shadow, var(--_ui-action-shadow)));
1121
- }
958
+ :scope:where(:scope):is([data-ui-button-state~="stretch"]) {
959
+ display: flex;
960
+ inline-size: 100%;
961
+ }
1122
962
 
1123
- :is([data-component~="ui-button"][data-ui-button-state~="variant=solid"], [data-component~="ui-button"][data-ui-button-state~="variant=danger"]):hover:not(:disabled, [aria-disabled="true"]) {
1124
- background-color: var(--_tone-hover);
1125
- border-color: var(--_tone-hover);
1126
- }
963
+ :scope:where(:scope) {
964
+ appearance: none;
965
+ min-block-size: var(--ui-button-min-block-size, var(--ui-control-size-md));
966
+ border-style: solid;
967
+ border-width: var(--ui-border-width);
968
+ border-color: var(--ui-button-border, var(--_tone));
969
+ border-radius: var(--ui-button-radius, var(--ui-action-radius, var(--ui-radius-md)));
970
+ background-color: var(--ui-button-surface, oklch(from var(--_tone) l c h / 5%));
971
+ color: var(--ui-button-text, var(--_tone-text));
972
+ font: inherit;
973
+ font-weight: var(--ui-font-medium);
974
+ text-decoration: none;
975
+ /* Unset, a button wraps as its container does. */
976
+ white-space: var(--ui-button-white-space, inherit);
977
+ line-height: var(--ui-line-height-tight);
978
+ padding: var(--ui-space-2) var(--ui-space-3);
979
+ background-image: none;
980
+ box-shadow: var(--ui-button-shadow, var(--ui-action-shadow, var(--_ui-action-shadow)));
981
+ cursor: pointer;
982
+ transition:
983
+ background-color var(--ui-motion-fast) var(--ui-motion-ease),
984
+ border-color var(--ui-motion-fast) var(--ui-motion-ease),
985
+ color var(--ui-motion-fast) var(--ui-motion-ease),
986
+ box-shadow var(--ui-motion-base) var(--ui-motion-ease);
987
+ margin: 0;
988
+ }
989
+ :scope:where(:scope):is(:is(a)) {
990
+ text-decoration: none;
991
+ }
1127
992
 
1128
- :is([data-component~="ui-button"][data-ui-button-state~="variant=solid"], [data-component~="ui-button"][data-ui-button-state~="variant=danger"]):active:not(:disabled, [aria-disabled="true"]) {
1129
- background-color: var(--_tone-active);
1130
- border-color: var(--_tone-active);
1131
- background-image: none;
1132
- box-shadow: var(--ui-pressed);
1133
- }
993
+ .spinner-wrap {
994
+ display: inline-flex;
995
+ flex: none;
996
+ vertical-align: middle;
997
+ }
998
+ :scope:where(:scope):is(:not([variant="link"]):has(.badge:not(:empty))) {
999
+ padding-block: var(--ui-space-0-5);
1000
+ }
1134
1001
 
1135
- /* Tone is the colour, variant is the volume. Every pairing works: a danger outline is a
1136
- destructive secondary action, not a special case. */
1137
- [data-component~="ui-button"][data-ui-button-state~="tone=neutral"] {
1138
- --_hue: var(--ui-text);
1139
- --_hue-hover: var(--ui-text);
1140
- --_hue-active: var(--ui-text);
1141
- --_hue-text: var(--ui-text);
1142
- --_on-hue: var(--ui-surface);
1143
- }
1002
+ .badge {
1003
+ display: inline-flex;
1004
+ align-items: center;
1005
+ flex: none;
1006
+ }
1144
1007
 
1145
- [data-component~="ui-button"][data-ui-button-state~="tone=danger"],
1146
- [data-component~="ui-button"][data-ui-button-state~="variant=danger"] {
1147
- --_hue: var(--ui-danger);
1148
- --_hue-hover: var(--ui-danger-hover);
1149
- --_hue-active: var(--ui-danger-hover);
1150
- --_hue-text: var(--ui-danger-hover);
1151
- --_on-hue: var(--ui-on-danger);
1152
- }
1008
+ .badge:empty {
1009
+ display: none;
1010
+ }
1153
1011
 
1154
- [data-component~="ui-button"][data-ui-button-state~="tone=success"] {
1155
- --_hue: var(--ui-success);
1156
- --_hue-hover: color-mix(in srgb, var(--ui-success) 85%, #000);
1157
- --_hue-active: color-mix(in srgb, var(--ui-success) 75%, #000);
1158
- --_hue-text: color-mix(in srgb, var(--ui-success) 85%, #000);
1159
- --_on-hue: var(--ui-surface);
1160
- }
1012
+ @supports (text-box-trim: trim-both) {
1013
+ :scope:where(:scope) {
1014
+ text-box-trim: trim-both;
1015
+ text-box-edge: cap alphabetic;
1016
+ }
1017
+ }
1161
1018
 
1162
- [data-component~="ui-button"][data-ui-button-state~="tone=warning"] {
1163
- --_hue: var(--ui-warning);
1164
- --_hue-hover: color-mix(in srgb, var(--ui-warning) 85%, #000);
1165
- --_hue-active: color-mix(in srgb, var(--ui-warning) 75%, #000);
1166
- --_hue-text: color-mix(in srgb, var(--ui-warning) 85%, #000);
1167
- --_on-hue: var(--ui-surface);
1168
- }
1019
+ :scope:where(:scope):is([data-ui-button-state~="size=xs"]) {
1020
+ min-block-size: 1.5rem;
1021
+ padding: calc(var(--ui-space-0-5) * 1.5) calc(var(--ui-space-1) * 1.25);
1022
+ font-size: var(--ui-font-size-xs);
1023
+ }
1169
1024
 
1170
- [data-component~="ui-button"][data-ui-button-state~="tone=info"] {
1171
- --_hue: var(--ui-info);
1172
- --_hue-hover: color-mix(in srgb, var(--ui-info) 85%, #000);
1173
- --_hue-active: color-mix(in srgb, var(--ui-info) 75%, #000);
1174
- --_hue-text: color-mix(in srgb, var(--ui-info) 85%, #000);
1175
- --_on-hue: var(--ui-surface);
1176
- }
1025
+ :scope:where(:scope):is([data-ui-button-state~="shape=pill"]) {
1026
+ border-radius: var(--ui-button-radius, var(--ui-radius-round));
1027
+ }
1177
1028
 
1178
- /* A value picker is a field, with Select's quiet edge and resting lift. */
1179
- [data-component~="ui-button"][data-ui-button-state~="variant=field"] {
1180
- --_ui-field-shadow: var(--ui-shadow-sm);
1181
- border-color: var(--ui-button-border, var(--ui-control-border, var(--ui-border-strong)));
1182
- border-radius: var(--ui-button-radius, var(--ui-field-radius, var(--ui-radius-md)));
1183
- background-color: var(--ui-button-surface, var(--ui-control-surface, var(--ui-surface-elevated)));
1184
- color: var(--ui-button-text, var(--ui-text-primary));
1185
- font-weight: var(--ui-font-normal);
1186
- box-shadow: var(--ui-button-shadow, var(--_ui-field-shadow));
1187
- }
1029
+ :scope:where(:scope):is([data-ui-button-state~="size=sm"]) {
1030
+ min-block-size: var(--ui-control-size-sm);
1031
+ padding: var(--ui-space-1) var(--ui-space-2);
1032
+ font-size: var(--ui-font-size-sm);
1033
+ }
1188
1034
 
1189
- [data-component~="ui-button"][data-ui-button-state~="variant=field"]:hover:not(:disabled, [aria-disabled="true"]) {
1190
- border-color: var(
1191
- --ui-button-hover-border,
1192
- var(--ui-control-border-hover, var(--ui-text-secondary))
1193
- );
1194
- background-color: var(
1195
- --ui-button-hover-surface,
1196
- var(--ui-control-surface, var(--ui-surface-elevated))
1197
- );
1198
- }
1035
+ :scope:where(:scope):is([data-ui-button-state~="size=lg"]) {
1036
+ min-block-size: var(--ui-control-size-lg);
1037
+ padding: var(--ui-space-3) var(--ui-space-4);
1038
+ font-size: var(--ui-font-size-md);
1039
+ }
1040
+ :scope:where(:scope):is([data-ui-button-state~="variant=card"]) {
1041
+ display: grid;
1042
+ grid-template-columns: auto minmax(0, 1fr) auto;
1043
+ align-content: center;
1044
+ align-items: start;
1045
+ gap: var(--ui-space-3);
1046
+ inline-size: 100%;
1047
+ min-block-size: max(var(--ui-control-min-block-size), var(--ui-control-size-md));
1048
+ text-align: start;
1049
+ white-space: normal;
1050
+ box-shadow: none;
1051
+ background-image: none;
1052
+ }
1053
+ :scope:where(:scope):is([data-ui-button-state~="variant=card"][data-ui-button-state~="size=lg"]) {
1054
+ min-block-size: max(var(--ui-control-min-block-size), var(--ui-control-size-lg));
1055
+ }
1056
+ :scope:where(:scope):is([data-ui-button-state~="variant=card"]:has(.card-icon:empty)) {
1057
+ grid-template-columns: minmax(0, 1fr) auto;
1058
+ }
1059
+ .card-icon {
1060
+ display: flex;
1061
+ align-items: flex-start;
1062
+ }
1063
+ .card-icon:empty {
1064
+ display: none;
1065
+ }
1066
+ .card-content {
1067
+ min-inline-size: 0;
1068
+ }
1069
+ .card-action {
1070
+ display: flex;
1071
+ align-items: center;
1072
+ align-self: center;
1073
+ }
1074
+ :scope:where(:scope):is(:hover:not(:disabled, [aria-disabled="true"])) {
1075
+ border-color: var(--ui-button-hover-border, var(--_tone-hover));
1076
+ background-color: var(--ui-button-hover-surface, oklch(from var(--_tone) l c h / 12%));
1077
+ }
1078
+ :scope:where(:scope):is([data-ui-button-state~="variant=card"][data-ui-button-state~="tone=neutral"]) {
1079
+ border-color: var(--ui-button-border, var(--ui-border));
1080
+ }
1199
1081
 
1200
- [data-component~="ui-button"][data-ui-button-state~="variant=field"]:is(:active, [aria-expanded="true"]):not(:disabled, [aria-disabled="true"]) {
1201
- --_ui-field-shadow: var(--ui-pressed);
1202
- }
1082
+ :scope:where(:scope):is([data-ui-button-state~="variant=card"][data-ui-button-state~="tone=neutral"]:hover:not(:disabled, [aria-disabled="true"])) {
1083
+ border-color: var(--ui-button-hover-border, var(--ui-border-strong));
1084
+ }
1085
+ :scope:where(:scope):is(:active:not(:disabled, [aria-disabled="true"])) {
1086
+ background-color: var(--ui-button-active-surface, oklch(from var(--_tone) l c h / 18%));
1087
+ background-image: none;
1088
+ box-shadow: var(--ui-pressed);
1089
+ }
1203
1090
 
1204
- [data-component~="ui-button"][data-ui-button-state~="variant=field"]:focus-visible {
1205
- border-color: var(--ui-control-focus, var(--ui-accent-solid));
1206
- box-shadow:
1207
- var(--ui-button-shadow, var(--_ui-field-shadow)),
1208
- var(--ui-control-focus-halo-shadow);
1209
- }
1091
+ :scope:where(:scope):is([data-ui-button-state~="variant=solid"]),
1092
+ :scope:where(:scope):is([data-ui-button-state~="variant=danger"]) {
1093
+ border-color: var(--_tone);
1094
+ background-color: var(--_tone);
1095
+ color: var(--_on-tone);
1096
+ box-shadow: var(--ui-button-solid-shadow, var(--ui-action-shadow, var(--_ui-action-shadow)));
1097
+ }
1210
1098
 
1211
- [data-component~="ui-button"][data-ui-button-state~="variant=ghost"] {
1212
- border-color: transparent;
1213
- background: transparent;
1214
- box-shadow: none;
1215
- color: var(--ui-button-ghost-text, var(--_tone-text));
1216
- }
1099
+ :is(:scope[data-ui-button-state~="variant=solid"], :scope[data-ui-button-state~="variant=danger"]):hover:not(:disabled, [aria-disabled="true"]) {
1100
+ background-color: var(--_tone-hover);
1101
+ border-color: var(--_tone-hover);
1102
+ }
1217
1103
 
1218
- /* Tints derive from the text colour, not a surface token, so hover and press show on any background. */
1219
- [data-component~="ui-button"][data-ui-button-state~="variant=ghost"]:hover:not(:disabled, [aria-disabled="true"]) {
1220
- background-color: var(--ui-button-ghost-hover-surface, oklch(from var(--_tone) l c h / 10%));
1221
- border-color: transparent;
1222
- }
1104
+ :is(:scope[data-ui-button-state~="variant=solid"], :scope[data-ui-button-state~="variant=danger"]):active:not(:disabled, [aria-disabled="true"]) {
1105
+ background-color: var(--_tone-active);
1106
+ border-color: var(--_tone-active);
1107
+ background-image: none;
1108
+ box-shadow: var(--ui-pressed);
1109
+ }
1110
+ :scope:where(:scope):is([data-ui-button-state~="tone=neutral"]) {
1111
+ --_hue: var(--ui-text);
1112
+ --_hue-hover: var(--ui-text);
1113
+ --_hue-active: var(--ui-text);
1114
+ --_hue-text: var(--ui-text);
1115
+ --_on-hue: var(--ui-surface);
1116
+ }
1223
1117
 
1224
- /* Pressed, or holding its menu open, a ghost button sinks slightly: a light surface with a faint
1225
- edge and a soft inner shadow. Lighter than hover, so an open menu's trigger never reads as heavy. */
1226
- [data-component~="ui-button"][data-ui-button-state~="variant=ghost"]:is(:active, [aria-expanded="true"]):not(:disabled, [aria-disabled="true"]) {
1227
- background-color: var(
1228
- --ui-button-ghost-active-surface,
1229
- color-mix(in oklch, var(--ui-surface), var(--_tone) 3%)
1230
- );
1231
- border-color: transparent;
1232
- box-shadow:
1233
- inset 0 0 0 1px oklch(from var(--_tone) l c h / 10%),
1234
- inset 0 1px 2px oklch(from var(--_tone) l c h / 8%);
1235
- }
1118
+ :scope:where(:scope):is([data-ui-button-state~="tone=danger"]),
1119
+ :scope:where(:scope):is([data-ui-button-state~="variant=danger"]) {
1120
+ --_hue: var(--ui-danger);
1121
+ --_hue-hover: var(--ui-danger-hover);
1122
+ --_hue-active: var(--ui-danger-hover);
1123
+ --_hue-text: var(--ui-danger-hover);
1124
+ --_on-hue: var(--ui-on-danger);
1125
+ }
1236
1126
 
1237
- /* A soft halo that transitions in with the other box-shadow changes, layered on the raised shadow. */
1238
- [data-component~="ui-button"]:focus-visible {
1239
- outline: none;
1240
- box-shadow:
1241
- var(--ui-button-shadow, var(--ui-action-shadow, var(--_ui-action-shadow))),
1242
- var(--ui-focus-halo);
1243
- }
1127
+ :scope:where(:scope):is([data-ui-button-state~="tone=success"]) {
1128
+ --_hue: var(--ui-success);
1129
+ --_hue-hover: color-mix(in srgb, var(--ui-success) 85%, #000);
1130
+ --_hue-active: color-mix(in srgb, var(--ui-success) 75%, #000);
1131
+ --_hue-text: color-mix(in srgb, var(--ui-success) 85%, #000);
1132
+ --_on-hue: var(--ui-surface);
1133
+ }
1244
1134
 
1245
- [data-component~="ui-button"][data-ui-button-state~="variant=solid"]:focus-visible {
1246
- box-shadow:
1247
- var(--ui-button-solid-shadow, var(--ui-action-shadow, var(--_ui-action-shadow))),
1248
- var(--ui-focus-halo);
1249
- }
1135
+ :scope:where(:scope):is([data-ui-button-state~="tone=warning"]) {
1136
+ --_hue: var(--ui-warning);
1137
+ --_hue-hover: color-mix(in srgb, var(--ui-warning) 85%, #000);
1138
+ --_hue-active: color-mix(in srgb, var(--ui-warning) 75%, #000);
1139
+ --_hue-text: color-mix(in srgb, var(--ui-warning) 85%, #000);
1140
+ --_on-hue: var(--ui-surface);
1141
+ }
1250
1142
 
1251
- :is([data-component~="ui-button"][data-ui-button-state~="variant=ghost"], [data-component~="ui-button"][data-ui-button-state~="variant=link"], [data-component~="ui-button"][data-ui-button-state~="variant=card"]):focus-visible {
1252
- box-shadow: var(--ui-focus-halo);
1253
- }
1143
+ :scope:where(:scope):is([data-ui-button-state~="tone=info"]) {
1144
+ --_hue: var(--ui-info);
1145
+ --_hue-hover: color-mix(in srgb, var(--ui-info) 85%, #000);
1146
+ --_hue-active: color-mix(in srgb, var(--ui-info) 75%, #000);
1147
+ --_hue-text: color-mix(in srgb, var(--ui-info) 85%, #000);
1148
+ --_on-hue: var(--ui-surface);
1149
+ }
1150
+ :scope:where(:scope):is([data-ui-button-state~="variant=field"]) {
1151
+ --_ui-field-shadow: var(--ui-shadow-sm);
1152
+ border-color: var(--ui-button-border, var(--ui-control-border, var(--ui-border-strong)));
1153
+ border-radius: var(--ui-button-radius, var(--ui-field-radius, var(--ui-radius-md)));
1154
+ background-color: var(
1155
+ --ui-button-surface,
1156
+ var(--ui-control-surface, var(--ui-surface-elevated))
1157
+ );
1158
+ color: var(--ui-button-text, var(--ui-text-primary));
1159
+ font-weight: var(--ui-font-normal);
1160
+ box-shadow: var(--ui-button-shadow, var(--_ui-field-shadow));
1161
+ }
1254
1162
 
1255
- /* A loading action stays visually active; only an explicitly disabled action takes the
1256
- neutral disabled palette. Its flat surface and muted ink make the state unambiguous. */
1257
- [data-component~="ui-button"]:is(:disabled, [aria-disabled="true"]:not([aria-busy="true"])) {
1258
- border-color: var(--ui-disabled-border);
1259
- background-color: var(--ui-disabled-surface);
1260
- color: var(--ui-disabled-text);
1261
- filter: var(--ui-button-disabled-filter, var(--ui-disabled-filter));
1262
- opacity: var(--ui-button-disabled-opacity, 1);
1263
- cursor: not-allowed;
1264
- background-image: none;
1265
- box-shadow: none;
1266
- }
1163
+ :scope:where(:scope):is([data-ui-button-state~="variant=field"]:hover:not(:disabled, [aria-disabled="true"])) {
1164
+ border-color: var(
1165
+ --ui-button-hover-border,
1166
+ var(--ui-control-border-hover, var(--ui-text-secondary))
1167
+ );
1168
+ background-color: var(
1169
+ --ui-button-hover-surface,
1170
+ var(--ui-control-surface, var(--ui-surface-elevated))
1171
+ );
1172
+ }
1267
1173
 
1268
- :is([data-component~="ui-button"][data-ui-button-state~="loading"], [data-component~="ui-button"][data-ui-button-state~="pending"]):focus-visible {
1269
- box-shadow: var(--ui-focus-halo);
1270
- }
1174
+ :scope:where(:scope):is([data-ui-button-state~="variant=field"]:is(:active, [aria-expanded="true"]):not(:disabled, [aria-disabled="true"])) {
1175
+ --_ui-field-shadow: var(--ui-pressed);
1176
+ }
1271
1177
 
1272
- /* Ghost keeps no border, but gains the same neutral surface as other disabled buttons. */
1273
- [data-component~="ui-button"][data-ui-button-state~="variant=ghost"]:is(:disabled, [aria-disabled="true"]:not([aria-busy="true"])) {
1274
- background-color: var(--ui-disabled-surface);
1275
- border-color: transparent;
1276
- }
1178
+ :scope:where(:scope):is([data-ui-button-state~="variant=field"]:focus-visible) {
1179
+ border-color: var(--ui-control-focus, var(--ui-accent-solid));
1180
+ box-shadow:
1181
+ var(--ui-button-shadow, var(--_ui-field-shadow)),
1182
+ var(--ui-control-focus-halo-shadow);
1183
+ }
1277
1184
 
1278
- /* The size states outrank :host, so sm is named too, or a small button would stay small. */
1279
- @media (pointer: coarse) {
1280
- [data-component~="ui-button"], [data-component~="ui-button"][data-ui-button-state~="size=sm"] {
1281
- min-block-size: var(--ui-control-min-block-size);
1185
+ :scope:where(:scope):is([data-ui-button-state~="variant=ghost"]) {
1186
+ border-color: transparent;
1187
+ background: transparent;
1188
+ box-shadow: none;
1189
+ color: var(--ui-button-ghost-text, var(--_tone-text));
1190
+ }
1191
+ :scope:where(:scope):is([data-ui-button-state~="variant=ghost"]:hover:not(:disabled, [aria-disabled="true"])) {
1192
+ background-color: var(--ui-button-ghost-hover-surface, oklch(from var(--_tone) l c h / 10%));
1193
+ border-color: transparent;
1194
+ }
1195
+ :scope:where(:scope):is([data-ui-button-state~="variant=ghost"]:is(:active, [aria-expanded="true"]):not(:disabled, [aria-disabled="true"])) {
1196
+ background-color: var(
1197
+ --ui-button-ghost-active-surface,
1198
+ color-mix(in oklch, var(--ui-surface), var(--_tone) 3%)
1199
+ );
1200
+ border-color: transparent;
1201
+ box-shadow:
1202
+ inset 0 0 0 1px oklch(from var(--_tone) l c h / 10%),
1203
+ inset 0 1px 2px oklch(from var(--_tone) l c h / 8%);
1204
+ }
1205
+ :scope:where(:scope):is(:focus-visible) {
1206
+ outline: none;
1207
+ box-shadow:
1208
+ var(--ui-button-shadow, var(--ui-action-shadow, var(--_ui-action-shadow))),
1209
+ var(--ui-focus-halo);
1282
1210
  }
1283
- }
1284
1211
 
1285
- /* Under touch, a link-style button's press lands within the control minimum: an invisible hit
1286
- area, centred on it, like IconButton's. A boxed button grows to the minimum itself (below);
1287
- a link-style one keeps its text size, so a standalone one ("See all" under a list) needs the
1288
- area. xs sits inside a line of text the same way, so it keeps its size and gains the area too.
1289
- Only these need it: a hit area on every button would reach over its neighbours. */
1290
- html[data-ui-input-modality="touch"]
1291
- [data-component~="ui-button"][data-ui-button-state~="variant=link"],
1292
- html[data-ui-input-modality="touch"]
1293
- [data-component~="ui-button"][data-ui-button-state~="size=xs"] {
1294
- position: relative;
1295
- }
1212
+ :scope:where(:scope):is([data-ui-button-state~="variant=solid"]:focus-visible) {
1213
+ box-shadow:
1214
+ var(--ui-button-solid-shadow, var(--ui-action-shadow, var(--_ui-action-shadow))),
1215
+ var(--ui-focus-halo);
1216
+ }
1296
1217
 
1297
- html[data-ui-input-modality="touch"]
1298
- [data-component~="ui-button"][data-ui-button-state~="variant=link"]::after,
1299
- html[data-ui-input-modality="touch"]
1300
- [data-component~="ui-button"][data-ui-button-state~="size=xs"]::after {
1301
- position: absolute;
1302
- inset: 50% auto auto 50%;
1303
- inline-size: max(100%, var(--ui-control-min-block-size));
1304
- block-size: max(100%, var(--ui-control-min-block-size));
1305
- transform: translate(-50%, -50%);
1306
- content: "";
1307
- }
1218
+ :is(:scope[data-ui-button-state~="variant=ghost"], :scope[data-ui-button-state~="variant=link"], :scope[data-ui-button-state~="variant=card"]):focus-visible {
1219
+ box-shadow: var(--ui-focus-halo);
1220
+ }
1221
+ :scope:where(:scope):is(:is(:disabled, [aria-disabled="true"]:not([aria-busy="true"]))) {
1222
+ border-color: var(--ui-disabled-border);
1223
+ background-color: var(--ui-disabled-surface);
1224
+ color: var(--ui-disabled-text);
1225
+ filter: var(--ui-button-disabled-filter, var(--ui-disabled-filter));
1226
+ opacity: var(--ui-button-disabled-opacity, 1);
1227
+ cursor: not-allowed;
1228
+ background-image: none;
1229
+ box-shadow: none;
1230
+ }
1308
1231
 
1309
- /* Link: an inline text action. No box, padding, or minimum height (inline targets are exempt under
1310
- WCAG 2.5.8); the inherited font; an underline that strengthens on hover; a visible focus ring. */
1311
- [data-component~="ui-button"][data-ui-button-state~="variant=link"] {
1312
- display: inline;
1313
- min-block-size: 0;
1314
- padding: 0;
1315
- border: 0;
1316
- border-radius: var(--ui-radius-sm);
1317
- background: none;
1318
- box-shadow: none;
1319
- font: inherit;
1320
- color: var(--ui-button-link-text, var(--ui-text-secondary));
1321
- text-decoration-line: underline;
1322
- text-decoration-thickness: 1px;
1323
- text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);
1324
- text-underline-offset: 0.2em;
1325
- transition:
1326
- color var(--ui-motion-fast) var(--ui-motion-ease),
1327
- text-decoration-color var(--ui-motion-fast) var(--ui-motion-ease);
1328
- }
1232
+ :is(:scope[data-ui-button-state~="loading"], :scope[data-ui-button-state~="pending"]):focus-visible {
1233
+ box-shadow: var(--ui-focus-halo);
1234
+ }
1235
+ :scope:where(:scope):is([data-ui-button-state~="variant=ghost"]:is(:disabled, [aria-disabled="true"]:not([aria-busy="true"]))) {
1236
+ background-color: var(--ui-disabled-surface);
1237
+ border-color: transparent;
1238
+ }
1239
+ @media (pointer: coarse) {
1240
+ :scope:where(:scope), :scope:where(:scope):is([data-ui-button-state~="size=sm"]) {
1241
+ min-block-size: var(--ui-control-min-block-size);
1242
+ }
1243
+ }
1244
+ :scope:where(:scope):is(html[data-ui-input-modality="touch"]
1245
+ [data-ui-button-state~="variant=link"]),
1246
+ :scope:where(:scope):is(html[data-ui-input-modality="touch"] [data-ui-button-state~="size=xs"]) {
1247
+ position: relative;
1248
+ }
1329
1249
 
1330
- [data-component~="ui-button"][data-ui-button-state~="variant=link"]:hover:not(:disabled, [aria-disabled="true"]) {
1331
- color: var(--ui-button-link-hover-text, var(--ui-text-primary));
1332
- text-decoration-color: currentColor;
1333
- background: none;
1334
- transform: none;
1335
- }
1250
+ :scope:where(:scope):is(html[data-ui-input-modality="touch"]
1251
+ [data-ui-button-state~="variant=link"])::after,
1252
+ :scope:where(:scope):is(html[data-ui-input-modality="touch"]
1253
+ [data-ui-button-state~="size=xs"])::after {
1254
+ position: absolute;
1255
+ inset: 50% auto auto 50%;
1256
+ inline-size: max(100%, var(--ui-control-min-block-size));
1257
+ block-size: max(100%, var(--ui-control-min-block-size));
1258
+ transform: translate(-50%, -50%);
1259
+ content: "";
1260
+ }
1261
+ :scope:where(:scope):is([data-ui-button-state~="variant=link"]) {
1262
+ display: inline;
1263
+ min-block-size: 0;
1264
+ padding: 0;
1265
+ border: 0;
1266
+ border-radius: var(--ui-radius-sm);
1267
+ background: none;
1268
+ box-shadow: none;
1269
+ font: inherit;
1270
+ color: var(--ui-button-link-text, var(--ui-text-secondary));
1271
+ text-decoration-line: underline;
1272
+ text-decoration-thickness: 1px;
1273
+ text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);
1274
+ text-underline-offset: 0.2em;
1275
+ transition:
1276
+ color var(--ui-motion-fast) var(--ui-motion-ease),
1277
+ text-decoration-color var(--ui-motion-fast) var(--ui-motion-ease);
1278
+ }
1336
1279
 
1337
- [data-component~="ui-button"][data-ui-button-state~="variant=link"]:active:not(:disabled, [aria-disabled="true"]) {
1338
- background: none;
1339
- transform: none;
1340
- }
1280
+ :scope:where(:scope):is([data-ui-button-state~="variant=link"]:hover:not(:disabled, [aria-disabled="true"])) {
1281
+ color: var(--ui-button-link-hover-text, var(--ui-text-primary));
1282
+ text-decoration-color: currentColor;
1283
+ background: none;
1284
+ transform: none;
1285
+ }
1341
1286
 
1342
- [data-component~="ui-button"][data-ui-button-state~="variant=link"]:is(:disabled, [aria-disabled="true"]:not([aria-busy="true"])) {
1343
- background: none;
1344
- border-color: transparent;
1345
- }
1287
+ :scope:where(:scope):is([data-ui-button-state~="variant=link"]:active:not(:disabled, [aria-disabled="true"])) {
1288
+ background: none;
1289
+ transform: none;
1290
+ }
1346
1291
 
1347
- [data-component~="ui-button"][data-ui-button-state~="variant=link"]:focus-visible {
1348
- box-shadow: none;
1349
- /* Fallback keeps the ring if the token is missing: an unresolved var() would void the outline. */
1350
- outline: var(--ui-focus-width) solid var(--ui-focus-ring);
1351
- outline-offset: var(--ui-focus-width);
1352
- }
1292
+ :scope:where(:scope):is([data-ui-button-state~="variant=link"]:is(:disabled, [aria-disabled="true"]:not([aria-busy="true"]))) {
1293
+ background: none;
1294
+ border-color: transparent;
1295
+ }
1353
1296
 
1354
- /* A component that sets its display still honours the hidden attribute on its root. */
1355
- [data-component~="ui-button"][hidden] {
1356
- display: none;
1297
+ :scope:where(:scope):is([data-ui-button-state~="variant=link"]:focus-visible) {
1298
+ box-shadow: none;
1299
+ /* Fallback keeps the ring if the token is missing: an unresolved var() would void the outline. */
1300
+ outline: var(--ui-focus-width) solid var(--ui-focus-ring);
1301
+ outline-offset: var(--ui-focus-width);
1302
+ }
1303
+ :scope:where(:scope):is([hidden]) {
1304
+ display: none;
1305
+ }
1357
1306
  }
1358
1307
  </style>