@threadlabs/looma 0.17.0 → 0.17.2

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 (229) hide show
  1. package/components/ui-avatar-group/ui-avatar-group.html +8 -5
  2. package/components/ui-avatar-group/ui-avatar-group.js +3 -3
  3. package/components/ui-badge/ui-badge.html +10 -5
  4. package/components/ui-breadcrumb-item/ui-breadcrumb-item.html +2 -1
  5. package/components/ui-button/ui-button.html +33 -26
  6. package/components/ui-button/ui-button.js +2 -2
  7. package/components/ui-callout/ui-callout.html +3 -1
  8. package/components/ui-card/ui-card.html +5 -3
  9. package/components/ui-checkbox/ui-checkbox.html +36 -8
  10. package/components/ui-combobox/ui-combobox.html +72 -45
  11. package/components/ui-combobox/ui-combobox.js +7 -2
  12. package/components/ui-context-menu/ui-context-menu.html +2 -2
  13. package/components/ui-description-item/ui-description-item.html +1 -1
  14. package/components/ui-description-list/ui-description-list.html +2 -0
  15. package/components/ui-dialog/ui-dialog.html +3 -23
  16. package/components/ui-disclosure/ui-disclosure.html +2 -2
  17. package/components/ui-editor-insert-table-grid/ui-editor-insert-table-grid.html +2 -2
  18. package/components/ui-editor-mention-menu/ui-editor-mention-menu.html +3 -3
  19. package/components/ui-editor-slash-menu/ui-editor-slash-menu.html +4 -4
  20. package/components/ui-editor-slash-menu-item/ui-editor-slash-menu-item.html +6 -1
  21. package/components/ui-editor-table-context-menu/ui-editor-table-context-menu.html +2 -2
  22. package/components/ui-editor-table-toolbar/ui-editor-table-toolbar.html +4 -4
  23. package/components/ui-editor-toolbar/ui-editor-toolbar.html +5 -5
  24. package/components/ui-floating-action-button/ui-floating-action-button.html +4 -2
  25. package/components/ui-icon-button/ui-icon-button.html +57 -17
  26. package/components/ui-icon-button/ui-icon-button.js +1 -1
  27. package/components/ui-list/ui-list.html +46 -6
  28. package/components/ui-list-item/ui-list-item.html +1 -1
  29. package/components/ui-menu/ui-menu.html +4 -3
  30. package/components/ui-menu/ui-menu.js +9 -3
  31. package/components/ui-menu-item/ui-menu-item.html +43 -6
  32. package/components/ui-meter/ui-meter.html +4 -1
  33. package/components/ui-nav-item/ui-nav-item.html +0 -1
  34. package/components/ui-page-header/ui-page-header.html +1 -0
  35. package/components/ui-popover/ui-popover.html +1 -1
  36. package/components/ui-radio/ui-radio.html +5 -2
  37. package/components/ui-scroll-area/ui-scroll-area.html +9 -14
  38. package/components/ui-scroll-area/ui-scroll-area.js +32 -0
  39. package/components/ui-search-result-row/ui-search-result-row.html +5 -3
  40. package/components/ui-search-shell/ui-search-shell.html +8 -8
  41. package/components/ui-section/ui-section.html +5 -3
  42. package/components/ui-separator/ui-separator.html +2 -2
  43. package/components/ui-sidebar/ui-sidebar.html +2 -2
  44. package/components/ui-spinner/ui-spinner.html +28 -8
  45. package/components/ui-status-message/ui-status-message.html +1 -1
  46. package/components/ui-switch/ui-switch.html +17 -8
  47. package/components/ui-table/ui-table.html +1 -1
  48. package/components/ui-tabs/ui-tabs.html +21 -12
  49. package/components/ui-toast/ui-toast.html +1 -1
  50. package/components/ui-toast-region/ui-toast-region.html +1 -1
  51. package/components/ui-tooltip/ui-tooltip.html +12 -12
  52. package/components/ui-tooltip/ui-tooltip.js +1 -1
  53. package/components/ui-top-bar/ui-top-bar.html +1 -1
  54. package/components/ui-tree/ui-tree.js +4 -1
  55. package/components/ui-tree-item/ui-tree-item.html +2 -1
  56. package/dist/index.js +15 -14
  57. package/editor/chunks/extensions.js +12 -2
  58. package/editor/extensions/preset.d.ts +6 -1
  59. package/package.json +1 -1
  60. package/styles/ui-avatar-group.css +8 -5
  61. package/styles/ui-badge.css +10 -5
  62. package/styles/ui-breadcrumb-item.css +2 -1
  63. package/styles/ui-button.css +19 -25
  64. package/styles/ui-callout.css +3 -1
  65. package/styles/ui-card.css +4 -2
  66. package/styles/ui-checkbox.css +38 -8
  67. package/styles/ui-combobox.css +27 -8
  68. package/styles/ui-context-menu.css +2 -2
  69. package/styles/ui-description-item.css +1 -1
  70. package/styles/ui-description-list.css +2 -0
  71. package/styles/ui-dialog.css +1 -22
  72. package/styles/ui-disclosure.css +2 -2
  73. package/styles/ui-editor-insert-table-grid.css +2 -2
  74. package/styles/ui-editor-mention-menu.css +3 -3
  75. package/styles/ui-editor-slash-menu-item.css +6 -1
  76. package/styles/ui-editor-slash-menu.css +4 -4
  77. package/styles/ui-editor-table-context-menu.css +2 -2
  78. package/styles/ui-editor-table-toolbar.css +4 -4
  79. package/styles/ui-editor-toolbar.css +5 -5
  80. package/styles/ui-floating-action-button.css +3 -1
  81. package/styles/ui-icon-button.css +53 -18
  82. package/styles/ui-list-item.css +1 -1
  83. package/styles/ui-list.css +41 -6
  84. package/styles/ui-menu-item.css +43 -5
  85. package/styles/ui-menu.css +3 -3
  86. package/styles/ui-meter.css +4 -1
  87. package/styles/ui-nav-item.css +0 -1
  88. package/styles/ui-page-header.css +1 -0
  89. package/styles/ui-popover.css +1 -1
  90. package/styles/ui-radio.css +5 -2
  91. package/styles/ui-scroll-area.css +10 -16
  92. package/styles/ui-search-result-row.css +3 -2
  93. package/styles/ui-search-shell.css +7 -7
  94. package/styles/ui-section.css +5 -3
  95. package/styles/ui-separator.css +2 -2
  96. package/styles/ui-sidebar.css +2 -2
  97. package/styles/ui-spinner.css +27 -6
  98. package/styles/ui-status-message.css +1 -1
  99. package/styles/ui-switch.css +17 -8
  100. package/styles/ui-table.css +1 -1
  101. package/styles/ui-tabs.css +60 -51
  102. package/styles/ui-toast-region.css +1 -1
  103. package/styles/ui-toast.css +1 -1
  104. package/styles/ui-tooltip.css +12 -12
  105. package/styles/ui-top-bar.css +1 -1
  106. package/styles/ui-tree-item.css +2 -1
  107. package/theme-dark.css +4 -4
  108. package/theme-light.css +3 -3
  109. package/tokens.css +9 -6
  110. package/vanilla/UiButton.d.ts +1 -0
  111. package/vanilla/UiButton.js +17 -19
  112. package/vanilla/UiCombobox.js +162 -159
  113. package/vanilla/UiDialog.js +2 -2
  114. package/vanilla/UiIconButton.d.ts +1 -0
  115. package/vanilla/UiIconButton.js +1 -4
  116. package/vanilla/UiList.d.ts +3 -1
  117. package/vanilla/UiList.js +36 -19
  118. package/vanilla/UiMenu.d.ts +1 -0
  119. package/vanilla/UiMenu.js +1 -1
  120. package/vanilla/UiMenuItem.js +10 -13
  121. package/vanilla/UiScrollArea.js +11 -6
  122. package/vanilla/UiSearchShell.js +2 -2
  123. package/vanilla/UiSpinner.js +2 -4
  124. package/vue/UiAvatarGroup.vue +8 -5
  125. package/vue/UiBadge.vue +10 -5
  126. package/vue/UiBreadcrumbItem.vue +2 -1
  127. package/vue/UiButton.d.ts +2 -0
  128. package/vue/UiButton.vue +31 -28
  129. package/vue/UiCallout.vue +3 -2
  130. package/vue/UiCard.vue +4 -2
  131. package/vue/UiCheckbox.vue +36 -8
  132. package/vue/UiCombobox.d.ts +1 -1
  133. package/vue/UiCombobox.vue +55 -35
  134. package/vue/UiContextMenu.vue +2 -2
  135. package/vue/UiDescriptionItem.vue +1 -1
  136. package/vue/UiDescriptionList.vue +2 -0
  137. package/vue/UiDialog.d.ts +3 -3
  138. package/vue/UiDialog.vue +3 -27
  139. package/vue/UiDisclosure.vue +2 -2
  140. package/vue/UiEditorInsertTableGrid.vue +2 -2
  141. package/vue/UiEditorMentionMenu.d.ts +1 -1
  142. package/vue/UiEditorMentionMenu.vue +4 -3
  143. package/vue/UiEditorSlashMenu.vue +6 -4
  144. package/vue/UiEditorSlashMenuItem.vue +6 -1
  145. package/vue/UiEditorTableContextMenu.vue +2 -2
  146. package/vue/UiEditorTableToolbar.vue +4 -4
  147. package/vue/UiEditorToolbar.vue +5 -5
  148. package/vue/UiFloatingActionButton.vue +3 -1
  149. package/vue/UiIconButton.d.ts +2 -0
  150. package/vue/UiIconButton.vue +61 -19
  151. package/vue/UiList.d.ts +7 -1
  152. package/vue/UiList.vue +57 -6
  153. package/vue/UiListItem.vue +1 -1
  154. package/vue/UiMenu.d.ts +2 -0
  155. package/vue/UiMenu.vue +6 -3
  156. package/vue/UiMenuItem.d.ts +3 -3
  157. package/vue/UiMenuItem.vue +47 -7
  158. package/vue/UiMeter.vue +4 -1
  159. package/vue/UiNavItem.vue +0 -1
  160. package/vue/UiPageHeader.vue +1 -0
  161. package/vue/UiPopover.vue +1 -1
  162. package/vue/UiRadio.vue +5 -2
  163. package/vue/UiScrollArea.vue +24 -18
  164. package/vue/UiSearchResultRow.vue +3 -2
  165. package/vue/UiSearchShell.vue +8 -8
  166. package/vue/UiSection.vue +5 -3
  167. package/vue/UiSeparator.vue +2 -2
  168. package/vue/UiSidebar.vue +2 -2
  169. package/vue/UiSpinner.vue +28 -7
  170. package/vue/UiStatusMessage.vue +1 -1
  171. package/vue/UiSwitch.vue +20 -9
  172. package/vue/UiTable.vue +1 -1
  173. package/vue/UiTabs.vue +25 -12
  174. package/vue/UiToast.vue +1 -1
  175. package/vue/UiToastRegion.vue +1 -1
  176. package/vue/UiTooltip.vue +12 -12
  177. package/vue/UiTopBar.vue +1 -1
  178. package/vue/UiTreeItem.vue +2 -1
  179. package/vue/chunks/UiAvatarGroup.js +1 -1
  180. package/vue/chunks/UiBadge.js +1 -1
  181. package/vue/chunks/UiBreadcrumbItem.js +1 -1
  182. package/vue/chunks/UiButton.js +28 -23
  183. package/vue/chunks/UiCallout.js +1 -1
  184. package/vue/chunks/UiCard.js +1 -1
  185. package/vue/chunks/UiCheckbox.js +1 -1
  186. package/vue/chunks/UiCombobox.js +80 -77
  187. package/vue/chunks/UiContextMenu.js +1 -1
  188. package/vue/chunks/UiDescriptionItem.js +1 -1
  189. package/vue/chunks/UiDescriptionList.js +1 -1
  190. package/vue/chunks/UiDialog.js +7 -4
  191. package/vue/chunks/UiDisclosure.js +1 -1
  192. package/vue/chunks/UiEditorInsertTableGrid.js +1 -1
  193. package/vue/chunks/UiEditorMentionMenu.js +1 -1
  194. package/vue/chunks/UiEditorSlashMenu.js +1 -1
  195. package/vue/chunks/UiEditorSlashMenuItem.js +1 -1
  196. package/vue/chunks/UiEditorTableContextMenu.js +1 -1
  197. package/vue/chunks/UiEditorTableToolbar.js +1 -1
  198. package/vue/chunks/UiEditorToolbar.js +1 -1
  199. package/vue/chunks/UiFloatingActionButton.js +1 -1
  200. package/vue/chunks/UiIconButton.js +13 -8
  201. package/vue/chunks/UiList.js +17 -5
  202. package/vue/chunks/UiListItem.js +1 -1
  203. package/vue/chunks/UiMenu.js +10 -2
  204. package/vue/chunks/UiMenuItem.js +1 -4
  205. package/vue/chunks/UiMeter.js +1 -1
  206. package/vue/chunks/UiNavItem.js +1 -1
  207. package/vue/chunks/UiPageHeader.js +1 -1
  208. package/vue/chunks/UiPopover.js +1 -1
  209. package/vue/chunks/UiRadio.js +1 -1
  210. package/vue/chunks/UiScrollArea.js +22 -3
  211. package/vue/chunks/UiSearchResultRow.js +1 -1
  212. package/vue/chunks/UiSearchShell.js +2 -2
  213. package/vue/chunks/UiSection.js +1 -1
  214. package/vue/chunks/UiSeparator.js +1 -1
  215. package/vue/chunks/UiSidebar.js +1 -1
  216. package/vue/chunks/UiSpinner.js +7 -5
  217. package/vue/chunks/UiStatusMessage.js +1 -1
  218. package/vue/chunks/UiSwitch.js +1 -1
  219. package/vue/chunks/UiTable.js +1 -1
  220. package/vue/chunks/UiTabs.js +1 -1
  221. package/vue/chunks/UiToast.js +1 -1
  222. package/vue/chunks/UiToastRegion.js +1 -1
  223. package/vue/chunks/UiTooltip.js +1 -1
  224. package/vue/chunks/UiTopBar.js +1 -1
  225. package/vue/chunks/UiTreeItem.js +1 -1
  226. package/vue/components.css +1231 -1032
  227. package/vue/editor/code-block-view.d.ts +29 -0
  228. package/vue/editor/index.js +70 -4
  229. package/vue/index.js +1 -1
@@ -108,7 +108,7 @@ useComponentHost(controllerModule.default, {
108
108
 
109
109
  [data-component~="ui-editor-slash-menu"] {
110
110
  background: var(--ui-surface);
111
- border: 1px solid var(--ui-border);
111
+ border: 1px solid var(--ui-border-strong);
112
112
  border-radius: var(--ui-radius-dialog);
113
113
  box-shadow: var(--ui-shadow-lg, 0 8px 24px rgb(0 0 0 / 0.12));
114
114
  overflow: hidden;
@@ -128,7 +128,7 @@ useComponentHost(controllerModule.default, {
128
128
  align-items: center;
129
129
  gap: var(--ui-space-2);
130
130
  padding: var(--ui-space-3) var(--ui-space-4);
131
- border-bottom: 1px solid var(--ui-border);
131
+ border-bottom: 1px solid var(--ui-border-divider);
132
132
  font-size: var(--ui-font-size-xs);
133
133
  color: var(--ui-text-muted);
134
134
  font-weight: var(--ui-font-semibold);
@@ -136,7 +136,9 @@ useComponentHost(controllerModule.default, {
136
136
  letter-spacing: 0.05em;
137
137
  }
138
138
 
139
- .header:not(:has(> *)), .footer:not(:has(> *)), .empty:not(:has(> *)) {
139
+ [data-component~="ui-editor-slash-menu"] > .header:empty,
140
+ [data-component~="ui-editor-slash-menu"] > .footer:empty,
141
+ [data-component~="ui-editor-slash-menu"] > .empty:empty {
140
142
  display: none;
141
143
  }
142
144
 
@@ -257,7 +259,7 @@ useComponentHost(controllerModule.default, {
257
259
 
258
260
  .footer {
259
261
  padding: var(--ui-space-2) var(--ui-space-3);
260
- border-top: 1px solid var(--ui-border);
262
+ border-top: 1px solid var(--ui-border-divider);
261
263
  font-size: var(--ui-font-size-xs);
262
264
  color: var(--ui-text-muted);
263
265
  }
@@ -53,9 +53,14 @@ withDefaults(
53
53
  background: var(--ui-accent-subtle);
54
54
  }
55
55
  [data-component~="ui-editor-slash-menu-item"][aria-disabled="true"] {
56
- opacity: 0.6;
56
+ background: var(--ui-disabled-surface);
57
57
  cursor: not-allowed;
58
58
  }
59
+ [data-component~="ui-editor-slash-menu-item"][aria-disabled="true"] .title,
60
+ [data-component~="ui-editor-slash-menu-item"][aria-disabled="true"] .description,
61
+ [data-component~="ui-editor-slash-menu-item"][aria-disabled="true"] .icon {
62
+ color: var(--ui-disabled-text);
63
+ }
59
64
 
60
65
  .icon {
61
66
  display: flex;
@@ -217,7 +217,7 @@ function attribute(value: unknown): any {
217
217
  max-height: min(28rem, calc(100vh - 24px));
218
218
  padding: var(--ui-space-2);
219
219
  background: var(--ui-surface);
220
- border: 1px solid var(--ui-border);
220
+ border: 1px solid var(--ui-border-strong);
221
221
  border-radius: var(--ui-radius-lg);
222
222
  box-shadow: var(--ui-shadow-lg, 0 10px 15px -3px rgb(0 0 0 / 0.1));
223
223
  display: flex;
@@ -319,7 +319,7 @@ function attribute(value: unknown): any {
319
319
 
320
320
  .sep {
321
321
  height: 1px;
322
- background: var(--ui-border);
322
+ background: var(--ui-border-divider);
323
323
  margin: var(--ui-space-1) 0;
324
324
  }
325
325
 
@@ -298,7 +298,7 @@ function attribute(value: unknown): any {
298
298
  gap: var(--ui-space-1);
299
299
  padding: var(--ui-space-1);
300
300
  background: color-mix(in srgb, var(--ui-surface) 94%, transparent);
301
- border: 1px solid var(--ui-border);
301
+ border: 1px solid var(--ui-border-strong);
302
302
  border-radius: calc(var(--ui-radius-md) + 2px);
303
303
  box-shadow: var(--ui-shadow-lg, 0 10px 15px -3px rgb(0 0 0 / 0.1));
304
304
  backdrop-filter: blur(10px);
@@ -314,7 +314,7 @@ function attribute(value: unknown): any {
314
314
  .sep {
315
315
  width: 1px;
316
316
  align-self: stretch;
317
- background: var(--ui-border);
317
+ background: var(--ui-border-divider);
318
318
  }
319
319
 
320
320
  .overflow {
@@ -387,7 +387,7 @@ function attribute(value: unknown): any {
387
387
  min-width: 12rem;
388
388
  padding: var(--ui-space-1);
389
389
  background: var(--ui-surface);
390
- border: 1px solid var(--ui-border);
390
+ border: 1px solid var(--ui-border-strong);
391
391
  border-radius: var(--ui-radius-md);
392
392
  box-shadow: var(--ui-shadow-lg, 0 10px 15px -3px rgb(0 0 0 / 0.1));
393
393
  display: flex;
@@ -399,7 +399,7 @@ function attribute(value: unknown): any {
399
399
  .menu-section + .menu-section {
400
400
  margin-top: var(--ui-space-1);
401
401
  padding-top: var(--ui-space-1);
402
- border-top: 1px solid color-mix(in srgb, var(--ui-border) 80%, transparent);
402
+ border-top: 1px solid var(--ui-border-divider);
403
403
  }
404
404
 
405
405
  .menu-heading {
@@ -59,7 +59,7 @@ useComponentHost(controllerModule.default, {
59
59
  var(--ui-editor-toolbar-padding-inline, 12px);
60
60
  min-height: var(--ui-editor-toolbar-min-height, 48px);
61
61
  background: var(--ui-editor-toolbar-surface, var(--ui-surface));
62
- border-bottom: 1px solid var(--ui-editor-toolbar-border, var(--ui-border));
62
+ border-bottom: 1px solid var(--ui-editor-toolbar-border, var(--ui-border-divider));
63
63
  }
64
64
 
65
65
  /* One row, always. When the controls outgrow the space, the row scrolls sideways rather than
@@ -117,7 +117,7 @@ useComponentHost(controllerModule.default, {
117
117
  :slotted(.divider) {
118
118
  width: 1px;
119
119
  height: 20px;
120
- background: var(--ui-editor-toolbar-divider, var(--ui-border));
120
+ background: var(--ui-editor-toolbar-divider, var(--ui-border-divider));
121
121
  flex-shrink: 0;
122
122
  margin: 0 var(--ui-editor-toolbar-divider-margin, 4px);
123
123
  }
@@ -134,7 +134,7 @@ useComponentHost(controllerModule.default, {
134
134
  var(--ui-editor-toolbar-surface, var(--ui-surface)) 96%,
135
135
  transparent
136
136
  );
137
- border: 1px solid var(--ui-editor-toolbar-border, var(--ui-border));
137
+ border: 1px solid var(--ui-editor-toolbar-border, var(--ui-border-strong));
138
138
  border-radius: var(--ui-editor-toolbar-floating-radius, var(--ui-radius-lg));
139
139
  box-shadow: var(
140
140
  --ui-editor-toolbar-floating-shadow,
@@ -151,7 +151,7 @@ useComponentHost(controllerModule.default, {
151
151
  left: 0;
152
152
  right: 0;
153
153
  min-height: var(--ui-editor-toolbar-mobile-min-height, 56px);
154
- border-top: 1px solid var(--ui-editor-toolbar-border, var(--ui-border));
154
+ border-top: 1px solid var(--ui-editor-toolbar-border, var(--ui-border-divider));
155
155
  border-bottom: none;
156
156
  box-shadow: var(--ui-editor-toolbar-mobile-shadow, 0 -2px 8px rgb(0 0 0 / 0.06));
157
157
  }
@@ -160,7 +160,7 @@ useComponentHost(controllerModule.default, {
160
160
  position: relative;
161
161
  inset: auto;
162
162
  min-height: auto;
163
- border: 1px solid var(--ui-editor-toolbar-border, var(--ui-border));
163
+ border: 1px solid var(--ui-editor-toolbar-border, var(--ui-border-strong));
164
164
  border-radius: var(--ui-editor-toolbar-floating-radius, var(--ui-radius-lg));
165
165
  box-shadow: var(
166
166
  --ui-editor-toolbar-floating-shadow,
@@ -103,7 +103,9 @@ const hostState = computed(() =>
103
103
  }
104
104
 
105
105
  [data-component~="ui-floating-action-button"]:disabled {
106
- opacity: 0.6;
106
+ background: var(--ui-disabled-surface);
107
+ color: var(--ui-disabled-text);
108
+ box-shadow: none;
107
109
  cursor: not-allowed;
108
110
  }
109
111
 
@@ -2,6 +2,7 @@ type __VLS_Props = {
2
2
  anticipatory?: boolean;
3
3
  disabled?: boolean;
4
4
  label?: string;
5
+ loading?: boolean;
5
6
  pending?: boolean;
6
7
  round?: boolean;
7
8
  size?: 'sm' | 'md' | 'lg';
@@ -16,6 +17,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
16
17
  size: "sm" | "md" | "lg";
17
18
  variant: "ghost" | "outline" | "solid";
18
19
  disabled: boolean;
20
+ loading: boolean;
19
21
  pending: boolean;
20
22
  anticipatory: boolean;
21
23
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -12,6 +12,7 @@ const props = withDefaults(
12
12
  anticipatory?: boolean
13
13
  disabled?: boolean
14
14
  label?: string
15
+ loading?: boolean
15
16
  pending?: boolean
16
17
  round?: boolean
17
18
  size?: 'sm' | 'md' | 'lg'
@@ -20,6 +21,7 @@ const props = withDefaults(
20
21
  {
21
22
  anticipatory: false,
22
23
  disabled: false,
24
+ loading: false,
23
25
  pending: false,
24
26
  round: false,
25
27
  size: 'md',
@@ -34,9 +36,10 @@ const hostState = computed(() =>
34
36
  [
35
37
  props.anticipatory && 'anticipatory',
36
38
  props.variant && `variant variant=${props.variant}`,
39
+ props.loading && 'loading',
40
+ props.pending && 'pending',
37
41
  props.size && `size size=${props.size}`,
38
42
  props.round && 'round',
39
- props.pending && 'pending',
40
43
  ].filter(Boolean).join(' ')
41
44
  )
42
45
 
@@ -69,14 +72,14 @@ function attribute(value: unknown): any {
69
72
  v-bind="$attrs"
70
73
  :disabled="disabled"
71
74
  :aria-label="label"
72
- :aria-disabled="typeof (({ true: 'true', false: null })[`${pending}`]) === 'boolean'
73
- ? String(({ true: 'true', false: null })[`${pending}`])
74
- : attribute(({ true: 'true', false: null })[`${pending}`])"
75
- :aria-busy="pending"
75
+ :aria-disabled="typeof (({ true: 'true', false: null })[`${loading || pending}`]) === 'boolean'
76
+ ? String(({ true: 'true', false: null })[`${loading || pending}`])
77
+ : attribute(({ true: 'true', false: null })[`${loading || pending}`])"
78
+ :aria-busy="loading || pending"
76
79
  :data-ui-icon-button-state="hostState || undefined"
77
80
  ref="root"
78
81
  >
79
- <UiSpinner v-if="pending" size="sm" />
82
+ <UiSpinner v-if="loading || pending" size="sm" />
80
83
  <span class="content"><slot /></span>
81
84
  </button>
82
85
  </template>
@@ -184,15 +187,32 @@ function attribute(value: unknown): any {
184
187
  pointer-events: none;
185
188
  }
186
189
 
187
- /* At rest an anticipatory button shows only its guide dot; proximity, hover, or focus reveals the
188
- * surface and icon. The root is the native button, so hiding it outright would hide the dot
189
- * too, and slotted icons sit outside this scope; `color: transparent` hides currentColor icons. */
190
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"]:disabled::before {
191
+ opacity: 0;
192
+ }
193
+
194
+ /* At rest an anticipatory button shows only its guide dot. The icon grows into place when
195
+ proximity, hover, or focus reveals it; the button's hit area and guide remain stable. */
196
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"] .content {
197
+ opacity: 1;
198
+ transform: scale(1);
199
+ transition:
200
+ opacity var(--ui-motion-fast) var(--ui-motion-ease),
201
+ transform calc(var(--ui-motion-fast) * 2) cubic-bezier(0.2, 1.4, 0.35, 1);
202
+ }
203
+
190
204
  @media (hover: hover) and (pointer: fine) {
191
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"]:not([data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"], [data-ui-proximity="near"], :hover, :focus-visible) {
205
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"]:not([data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"], [data-component~="ui-icon-button"][data-ui-icon-button-state~="loading"], [data-component~="ui-icon-button"][data-ui-icon-button-state~="pending"], :disabled, [data-ui-proximity="near"], :hover, :focus-visible) {
192
206
  border-color: transparent;
193
207
  background: transparent;
194
208
  box-shadow: none;
195
- color: transparent;
209
+ }
210
+
211
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"]:not([data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"], [data-component~="ui-icon-button"][data-ui-icon-button-state~="loading"], [data-component~="ui-icon-button"][data-ui-icon-button-state~="pending"], :disabled, [data-ui-proximity="near"], :hover, :focus-visible)
212
+ .content {
213
+ opacity: 0;
214
+ transform: scale(0.65);
215
+ transition-duration: var(--ui-motion-fast);
196
216
  }
197
217
  }
198
218
 
@@ -222,7 +242,7 @@ function attribute(value: unknown): any {
222
242
  background-color var(--ui-motion-fast) var(--ui-motion-ease),
223
243
  border-color var(--ui-motion-fast) var(--ui-motion-ease),
224
244
  color var(--ui-motion-fast) var(--ui-motion-ease),
225
- box-shadow var(--ui-motion-fast) var(--ui-motion-ease),
245
+ box-shadow var(--ui-motion-base) var(--ui-motion-ease),
226
246
  transform var(--ui-motion-fast) var(--ui-motion-ease);
227
247
  }
228
248
 
@@ -283,13 +303,16 @@ html[data-ui-input-modality="touch"] [data-component~="ui-icon-button"]::after {
283
303
  }
284
304
 
285
305
  [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=outline"] {
286
- border-color: var(--ui-icon-button-border, var(--ui-border-default));
306
+ border-color: var(--ui-icon-button-border, var(--ui-control-border, var(--ui-border-strong)));
287
307
  background: var(--ui-icon-button-outline-surface, var(--ui-surface-default));
308
+ background-image: var(--ui-raised-highlight);
288
309
  color: var(--ui-icon-button-outline-text, var(--ui-text-primary));
310
+ box-shadow: var(--ui-raised);
289
311
  }
290
312
 
291
313
  [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"] {
292
314
  background: var(--ui-icon-button-solid-surface, var(--ui-accent-solid));
315
+ background-image: var(--ui-raised-highlight);
293
316
  color: var(--ui-icon-button-solid-text, var(--ui-text-on-accent));
294
317
  box-shadow: var(
295
318
  --ui-icon-button-solid-shadow,
@@ -304,7 +327,10 @@ html[data-ui-input-modality="touch"] [data-component~="ui-icon-button"]::after {
304
327
  }
305
328
 
306
329
  [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=outline"]:hover:enabled:not([aria-disabled="true"]) {
307
- border-color: var(--ui-icon-button-hover-border, var(--ui-border-strong));
330
+ border-color: var(
331
+ --ui-icon-button-hover-border,
332
+ var(--ui-control-border-hover, var(--ui-control-border))
333
+ );
308
334
  }
309
335
 
310
336
  [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"]:hover:enabled:not([aria-disabled="true"]) {
@@ -315,30 +341,46 @@ html[data-ui-input-modality="touch"] [data-component~="ui-icon-button"]::after {
315
341
  transform: scale(var(--ui-icon-button-active-scale, 0.96));
316
342
  }
317
343
 
318
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="pending"] {
344
+ :is([data-component~="ui-icon-button"][data-ui-icon-button-state~="loading"], [data-component~="ui-icon-button"][data-ui-icon-button-state~="pending"]) {
319
345
  cursor: progress;
320
346
  }
321
347
 
322
348
  .content {
323
- display: contents;
349
+ display: inline-flex;
350
+ align-items: center;
351
+ justify-content: center;
324
352
  }
325
353
 
326
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="pending"] .content {
354
+ :is([data-component~="ui-icon-button"][data-ui-icon-button-state~="loading"], [data-component~="ui-icon-button"][data-ui-icon-button-state~="pending"])
355
+ .content {
327
356
  display: none;
328
357
  }
329
358
 
359
+ @media (prefers-reduced-motion: reduce) {
360
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"] .content {
361
+ transition: none;
362
+ }
363
+ }
364
+
330
365
  [data-component~="ui-icon-button"]:focus-visible {
331
366
  outline: none;
332
367
  box-shadow: var(--ui-focus-halo);
333
368
  }
334
369
 
335
- /* Disabled colours fall back to each variant's own; ghost takes only the icon colour. */
336
- /* Disabled washes the button out the way Button does: the same shape, one filter. */
370
+ /* Disabled is a flat neutral control, independent of the active variant's tone. */
337
371
  [data-component~="ui-icon-button"]:disabled {
372
+ border-color: var(--ui-disabled-border);
373
+ background: var(--ui-disabled-surface);
374
+ color: var(--ui-disabled-text);
338
375
  filter: var(--ui-icon-button-disabled-filter, var(--ui-disabled-filter));
339
376
  opacity: var(--ui-icon-button-disabled-opacity, 1);
340
377
  cursor: not-allowed;
341
378
  box-shadow: none;
379
+ background-image: none;
380
+ }
381
+
382
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=ghost"]:disabled {
383
+ border-color: transparent;
342
384
  }
343
385
 
344
386
  [data-component~="ui-icon-button"] {
package/vue/UiList.d.ts CHANGED
@@ -1,14 +1,20 @@
1
1
  type __VLS_Props = {
2
+ as?: 'ul' | 'ol';
2
3
  density?: 'comfortable' | 'compact';
3
4
  layout?: 'rows' | 'grid';
5
+ markers?: 'none' | 'disc';
4
6
  };
5
- declare var __VLS_1: {};
7
+ declare var __VLS_1: {}, __VLS_3: {};
6
8
  type __VLS_Slots = {} & {
7
9
  default?: (props: typeof __VLS_1) => any;
10
+ } & {
11
+ default?: (props: typeof __VLS_3) => any;
8
12
  };
9
13
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
14
+ as: "ul" | "ol";
10
15
  density: "comfortable" | "compact";
11
16
  layout: "rows" | "grid";
17
+ markers: "none" | "disc";
12
18
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
13
19
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
14
20
  declare const _default: typeof __VLS_export;
package/vue/UiList.vue CHANGED
@@ -6,18 +6,24 @@ defineOptions({ inheritAttrs: false })
6
6
 
7
7
  const props = withDefaults(
8
8
  defineProps<{
9
+ as?: 'ul' | 'ol'
9
10
  density?: 'comfortable' | 'compact'
10
11
  layout?: 'rows' | 'grid'
12
+ markers?: 'none' | 'disc'
11
13
  }>(),
12
14
  {
15
+ as: 'ul',
13
16
  density: 'comfortable',
14
17
  layout: 'rows',
18
+ markers: 'none',
15
19
  },
16
20
  )
17
21
 
18
22
  /** The values the styles' :host-state() rules test. */
19
23
  const hostState = computed(() =>
20
24
  [
25
+ props.as && `as as=${props.as}`,
26
+ props.markers && `markers markers=${props.markers}`,
21
27
  props.density && `density density=${props.density}`,
22
28
  props.layout && `layout layout=${props.layout}`,
23
29
  ].filter(Boolean).join(' ')
@@ -25,7 +31,16 @@ const hostState = computed(() =>
25
31
  </script>
26
32
 
27
33
  <template>
34
+ <ol
35
+ v-if="as === 'ol'"
36
+ data-component="ui-list"
37
+ v-bind="$attrs"
38
+ :data-ui-list-state="hostState || undefined"
39
+ >
40
+ <slot />
41
+ </ol>
28
42
  <ul
43
+ v-else
29
44
  data-component="ui-list"
30
45
  role="list"
31
46
  v-bind="$attrs"
@@ -46,33 +61,69 @@ const hostState = computed(() =>
46
61
  inherits: false;
47
62
  }
48
63
 
49
- /* A list of items (ui-list-item). It owns the spacing between them, so a view never sets it. The
64
+ /* A list of native li elements or structured ui-list-item components. It owns the spacing between them, so a view never sets it. The
50
65
  explicit list role keeps the list announced as one: some browsers drop it from a list with no
51
66
  markers. */
52
67
  [data-component~="ui-list"] {
68
+ --_list-gap: var(--ui-list-gap, var(--ui-space-1));
69
+ --_list-min-item-width: var(--ui-list-min-item-width, 14rem);
53
70
  display: flex;
54
71
  flex-direction: column;
55
- gap: var(--ui-list-gap, var(--ui-space-1));
72
+ inline-size: 100%;
73
+ gap: var(--_list-gap);
56
74
  min-inline-size: 0;
57
75
  margin: 0;
58
76
  padding: 0;
59
77
  list-style: none;
60
78
  }
61
79
 
80
+ [data-component~="ui-list"][data-ui-list-state~="as=ol"],
81
+ [data-component~="ui-list"][data-ui-list-state~="markers=disc"] {
82
+ padding-inline-start: var(--ui-space-5);
83
+ }
84
+
85
+ [data-component~="ui-list"][data-ui-list-state~="as=ol"] {
86
+ list-style: decimal;
87
+ }
88
+
89
+ [data-component~="ui-list"][data-ui-list-state~="markers=disc"] {
90
+ list-style: disc;
91
+ }
92
+
93
+ [data-component~="ui-list"] > :slotted(li) {
94
+ box-sizing: border-box;
95
+ min-inline-size: 0;
96
+ padding: var(--_ui-list-native-padding-block, var(--ui-space-2))
97
+ var(--_ui-list-native-padding-inline, var(--ui-space-3));
98
+ border-radius: var(--ui-radius-md);
99
+ color: var(--ui-text-primary);
100
+ list-style: inherit;
101
+ }
102
+
103
+ [data-component~="ui-list"] > :slotted(li.card) {
104
+ padding: var(--_ui-list-native-padding-block, var(--ui-space-3))
105
+ var(--_ui-list-native-padding-inline, var(--ui-space-4));
106
+ border: 1px solid var(--ui-border-strong);
107
+ border-radius: var(--ui-radius-lg);
108
+ background: var(--ui-surface-raised);
109
+ list-style: none;
110
+ }
111
+
62
112
  /* Compact passes its size to the items through private properties, which cross into each item. */
63
113
  [data-component~="ui-list"][data-ui-list-state~="density=compact"] {
114
+ --_list-gap: var(--ui-list-gap, var(--ui-space-2));
64
115
  --_ui-list-item-min-size: 0;
65
116
  --_ui-list-item-padding-block: 0;
66
117
  --_ui-list-item-padding-inline: 0;
67
118
  --_ui-list-item-title-weight: var(--ui-font-normal);
68
- gap: var(--ui-list-gap, var(--ui-space-2));
119
+ --_ui-list-native-padding-block: 0;
120
+ --_ui-list-native-padding-inline: 0;
69
121
  }
70
122
 
71
123
  [data-component~="ui-list"][data-ui-list-state~="layout=grid"] {
124
+ --_list-gap: var(--ui-list-gap, var(--ui-space-3));
72
125
  display: grid;
73
- grid-template-columns:
74
- repeat(auto-fill, minmax(min(100%, var(--ui-list-min-item-width, 14rem)), 1fr));
75
- gap: var(--ui-list-gap, var(--ui-space-3));
126
+ grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--_list-min-item-width)), 1fr));
76
127
  }
77
128
 
78
129
  /* A component that sets its display still honours the hidden attribute on its root. */
@@ -95,7 +95,7 @@ const hostState = computed(() =>
95
95
  [data-component~="ui-list-item"][data-ui-list-item-state~="variant=card"] {
96
96
  padding-block: var(--ui-list-item-padding-block, var(--ui-space-3));
97
97
  padding-inline: var(--ui-list-item-padding-inline, var(--ui-space-4));
98
- border: 1px solid var(--ui-border-default);
98
+ border: 1px solid var(--ui-border-strong);
99
99
  border-radius: var(--ui-radius-lg);
100
100
  background: var(--ui-surface-raised);
101
101
  }
package/vue/UiMenu.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  type __VLS_Props = {
2
2
  density?: 'comfortable' | 'compact';
3
3
  for?: string;
4
+ inline?: boolean;
4
5
  open?: boolean;
5
6
  placement?: string;
6
7
  };
@@ -46,6 +47,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
46
47
  for: string;
47
48
  open: boolean;
48
49
  placement: string;
50
+ inline: boolean;
49
51
  density: "comfortable" | "compact";
50
52
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
51
53
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
package/vue/UiMenu.vue CHANGED
@@ -10,12 +10,14 @@ const props = withDefaults(
10
10
  defineProps<{
11
11
  density?: 'comfortable' | 'compact'
12
12
  for?: string
13
+ inline?: boolean
13
14
  open?: boolean
14
15
  placement?: string
15
16
  }>(),
16
17
  {
17
18
  density: 'comfortable',
18
19
  for: '',
20
+ inline: false,
19
21
  open: false,
20
22
  placement: 'bottom-start',
21
23
  },
@@ -53,6 +55,7 @@ const hostState = computed(() =>
53
55
  [
54
56
  props.density && `density density=${props.density}`,
55
57
  internalOpen.value && 'internalOpen',
58
+ props.inline && 'inline',
56
59
  ].filter(Boolean).join(' ')
57
60
  )
58
61
 
@@ -181,7 +184,7 @@ useComponentHost(controllerModule.default, {
181
184
  max-inline-size: inherit;
182
185
  padding: var(--ui-space-1);
183
186
  background: var(--_ui-menu-surface, var(--ui-overlay-surface, var(--ui-surface-elevated)));
184
- border: 1px solid var(--_ui-menu-border, var(--ui-overlay-border, var(--ui-border-default)));
187
+ border: 1px solid var(--_ui-menu-border, var(--ui-overlay-border, var(--ui-border-strong)));
185
188
  border-radius: var(--_ui-menu-radius, var(--ui-overlay-radius, var(--ui-radius-lg)));
186
189
  box-shadow: var(
187
190
  --_ui-menu-shadow,
@@ -196,10 +199,10 @@ useComponentHost(controllerModule.default, {
196
199
  block-size: 0;
197
200
  margin: var(--ui-space-1) 0;
198
201
  border: 0;
199
- border-block-start: 1px solid var(--ui-border-default);
202
+ border-block-start: 1px solid var(--ui-border-divider);
200
203
  }
201
204
 
202
- [data-component~="ui-menu"]:not([data-component~="ui-menu"][data-ui-menu-state~="internalOpen"]) {
205
+ [data-component~="ui-menu"]:not([data-component~="ui-menu"][data-ui-menu-state~="internalOpen"]):not([data-component~="ui-menu"][data-ui-menu-state~="inline"]) {
203
206
  display: none;
204
207
  }
205
208
 
@@ -5,15 +5,15 @@ type __VLS_Props = {
5
5
  type?: 'action' | 'checkbox' | 'radio';
6
6
  value?: string;
7
7
  };
8
- declare var __VLS_1: {}, __VLS_3: {}, __VLS_15: {}, __VLS_17: {};
8
+ declare var __VLS_1: {}, __VLS_3: {}, __VLS_10: {}, __VLS_12: {};
9
9
  type __VLS_Slots = {} & {
10
10
  default?: (props: typeof __VLS_1) => any;
11
11
  } & {
12
12
  shortcut?: (props: typeof __VLS_3) => any;
13
13
  } & {
14
- default?: (props: typeof __VLS_15) => any;
14
+ default?: (props: typeof __VLS_10) => any;
15
15
  } & {
16
- shortcut?: (props: typeof __VLS_17) => any;
16
+ shortcut?: (props: typeof __VLS_12) => any;
17
17
  };
18
18
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
19
19
  change: (detail: {