@threadlabs/looma 0.33.1 → 0.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. package/components/shared/overlay.js +8 -2
  2. package/components/shared/surface-material.js +21 -0
  3. package/components/ui-badge/ui-badge.html +11 -3
  4. package/components/ui-button/ui-button.html +92 -51
  5. package/components/ui-card/ui-card.html +50 -6
  6. package/components/ui-checkbox/ui-checkbox.html +4 -2
  7. package/components/ui-curve-editor/curve.js +10 -0
  8. package/components/ui-curve-editor/ui-curve-editor.html +181 -0
  9. package/components/ui-curve-editor/ui-curve-editor.js +51 -0
  10. package/components/ui-dialog/ui-dialog.html +64 -1
  11. package/components/ui-dialog/ui-dialog.js +9 -1
  12. package/components/ui-icon-button/ui-icon-button.html +97 -31
  13. package/components/ui-input/ui-input.html +2 -1
  14. package/components/ui-input-group/ui-input-group.html +4 -1
  15. package/components/ui-light-editor/ui-light-editor.html +45 -0
  16. package/components/ui-light-editor/ui-light-editor.js +53 -0
  17. package/components/ui-menu/ui-menu.html +62 -0
  18. package/components/ui-menu/ui-menu.js +1 -1
  19. package/components/ui-number-input/arithmetic.js +47 -0
  20. package/components/ui-number-input/ui-number-input.html +63 -0
  21. package/components/ui-number-input/ui-number-input.js +47 -0
  22. package/components/ui-popover/ui-popover.html +66 -1
  23. package/components/ui-popover/ui-popover.js +1 -1
  24. package/components/ui-select/ui-select.html +9 -7
  25. package/components/ui-slider/ui-slider.html +84 -0
  26. package/components/ui-slider/ui-slider.js +29 -0
  27. package/components/ui-switch/ui-switch.html +3 -0
  28. package/components/ui-tabs/ui-tabs.html +6 -1
  29. package/components/ui-text/ui-text.html +31 -6
  30. package/components/ui-textarea/ui-textarea.html +2 -1
  31. package/components/ui-tooltip/ui-tooltip.html +60 -0
  32. package/components/ui-tooltip/ui-tooltip.js +1 -1
  33. package/dist/index.js +47 -43
  34. package/docs/README.md +59 -5
  35. package/docs/card.html +16 -2
  36. package/docs/card.js +17 -2
  37. package/docs/catalog.json +1640 -108
  38. package/docs/customizer-render.mjs +50 -11
  39. package/docs/customizer.js +137 -24
  40. package/docs/documentation.css +9 -1
  41. package/docs/index.d.ts +8 -3
  42. package/docs/index.mjs +1 -1
  43. package/docs/preview.js +2 -0
  44. package/docs/render.mjs +16 -7
  45. package/docs/site.mjs +78 -27
  46. package/docs/theme-session.mjs +53 -0
  47. package/docs/theme.mjs +189 -18
  48. package/docs/value-editors.mjs +33 -0
  49. package/package.json +2 -2
  50. package/styles/ui-badge.css +11 -6
  51. package/styles/ui-button.css +74 -49
  52. package/styles/ui-card.css +51 -4
  53. package/styles/ui-checkbox.css +4 -2
  54. package/styles/ui-curve-editor.css +109 -0
  55. package/styles/ui-dialog.css +136 -0
  56. package/styles/ui-icon-button.css +85 -28
  57. package/styles/ui-input-group.css +4 -1
  58. package/styles/ui-input.css +2 -1
  59. package/styles/ui-light-editor.css +28 -0
  60. package/styles/ui-menu.css +74 -0
  61. package/styles/ui-number-input.css +34 -0
  62. package/styles/ui-popover.css +76 -0
  63. package/styles/ui-select.css +9 -7
  64. package/styles/ui-slider.css +53 -0
  65. package/styles/ui-switch.css +3 -0
  66. package/styles/ui-tabs.css +6 -1
  67. package/styles/ui-text.css +23 -1
  68. package/styles/ui-textarea.css +2 -1
  69. package/styles/ui-tooltip.css +72 -0
  70. package/theme-light.css +1 -0
  71. package/theme-system.css +69 -17
  72. package/tokens.css +12 -2
  73. package/vanilla/UiButton.d.ts +1 -0
  74. package/vanilla/UiButton.js +195 -130
  75. package/vanilla/UiCard.d.ts +1 -0
  76. package/vanilla/UiCard.js +12 -12
  77. package/vanilla/UiCurveEditor.d.ts +28 -0
  78. package/vanilla/UiCurveEditor.js +134 -0
  79. package/vanilla/UiIconButton.d.ts +2 -1
  80. package/vanilla/UiIconButton.js +58 -31
  81. package/vanilla/UiLightEditor.d.ts +29 -0
  82. package/vanilla/UiLightEditor.js +102 -0
  83. package/vanilla/UiNumberInput.d.ts +33 -0
  84. package/vanilla/UiNumberInput.js +86 -0
  85. package/vanilla/UiSlider.d.ts +33 -0
  86. package/vanilla/UiSlider.js +125 -0
  87. package/vanilla/UiText.d.ts +2 -2
  88. package/vanilla/UiText.js +45 -11
  89. package/vanilla/index.js +4 -0
  90. package/vue/UiBadge.vue +29 -4
  91. package/vue/UiButton.d.ts +6 -0
  92. package/vue/UiButton.vue +188 -60
  93. package/vue/UiCard.d.ts +6 -0
  94. package/vue/UiCard.vue +80 -6
  95. package/vue/UiCheckbox.vue +4 -2
  96. package/vue/UiCurveEditor.d.ts +53 -0
  97. package/vue/UiCurveEditor.js +2 -0
  98. package/vue/UiCurveEditor.vue +427 -0
  99. package/vue/UiDialog.vue +181 -1
  100. package/vue/UiIconButton.d.ts +8 -2
  101. package/vue/UiIconButton.vue +190 -45
  102. package/vue/UiInput.vue +2 -1
  103. package/vue/UiInputGroup.vue +4 -1
  104. package/vue/UiLightEditor.d.ts +75 -0
  105. package/vue/UiLightEditor.js +2 -0
  106. package/vue/UiLightEditor.vue +402 -0
  107. package/vue/UiMenu.vue +91 -0
  108. package/vue/UiNumberInput.d.ts +83 -0
  109. package/vue/UiNumberInput.js +2 -0
  110. package/vue/UiNumberInput.vue +399 -0
  111. package/vue/UiPopover.vue +94 -1
  112. package/vue/UiSelect.vue +16 -10
  113. package/vue/UiSlider.d.ts +83 -0
  114. package/vue/UiSlider.js +2 -0
  115. package/vue/UiSlider.vue +412 -0
  116. package/vue/UiSwitch.vue +3 -0
  117. package/vue/UiTabs.vue +6 -1
  118. package/vue/UiText.d.ts +7 -5
  119. package/vue/UiText.vue +104 -22
  120. package/vue/UiTextarea.vue +2 -1
  121. package/vue/UiTooltip.vue +89 -0
  122. package/vue/chunks/UiActionBar.js +1 -1
  123. package/vue/chunks/UiAffordanceScope.js +2 -2
  124. package/vue/chunks/UiAvatar.js +2 -2
  125. package/vue/chunks/UiAvatarGroup.js +2 -2
  126. package/vue/chunks/UiBadge.js +3 -3
  127. package/vue/chunks/UiBreadcrumbItem.js +2 -2
  128. package/vue/chunks/UiBreadcrumbs.js +2 -2
  129. package/vue/chunks/UiButton.js +94 -11
  130. package/vue/chunks/UiCallout.js +2 -2
  131. package/vue/chunks/UiCard.js +34 -5
  132. package/vue/chunks/UiCheckbox.js +3 -3
  133. package/vue/chunks/UiCluster.js +2 -2
  134. package/vue/chunks/UiColorPicker.js +2 -2
  135. package/vue/chunks/UiCombobox.js +2 -2
  136. package/vue/chunks/UiContainer.js +2 -2
  137. package/vue/chunks/UiContextMenu.js +2 -2
  138. package/vue/chunks/UiCover.js +2 -2
  139. package/vue/chunks/UiCurveEditor.js +413 -0
  140. package/vue/chunks/UiDescriptionItem.js +2 -2
  141. package/vue/chunks/UiDescriptionList.js +2 -2
  142. package/vue/chunks/UiDialog.js +4 -4
  143. package/vue/chunks/UiDisclosure.js +2 -2
  144. package/vue/chunks/UiEditable.js +2 -2
  145. package/vue/chunks/UiEditorBlockActions.js +2 -2
  146. package/vue/chunks/UiEditorChipEditor.js +2 -2
  147. package/vue/chunks/UiEditorCodeLanguage.js +2 -2
  148. package/vue/chunks/UiEditorFootnoteEditor.js +2 -2
  149. package/vue/chunks/UiEditorImageToolbar.js +3 -3
  150. package/vue/chunks/UiEditorInsertTableGrid.js +2 -2
  151. package/vue/chunks/UiEditorLinkCard.js +3 -3
  152. package/vue/chunks/UiEditorLinkForm.js +3 -3
  153. package/vue/chunks/UiEditorMentionMenu.js +2 -2
  154. package/vue/chunks/UiEditorMentionMenuItem.js +2 -2
  155. package/vue/chunks/UiEditorSlashMenu.js +2 -2
  156. package/vue/chunks/UiEditorSlashMenuGroup.js +2 -2
  157. package/vue/chunks/UiEditorSlashMenuItem.js +2 -2
  158. package/vue/chunks/UiEditorSurface.js +2 -2
  159. package/vue/chunks/UiEditorTableContextMenu.js +2 -2
  160. package/vue/chunks/UiEditorTableOverlay.js +2 -2
  161. package/vue/chunks/UiEditorTableToolbar.js +2 -2
  162. package/vue/chunks/UiEditorToolbar.js +2 -2
  163. package/vue/chunks/UiFloatingActionButton.js +2 -2
  164. package/vue/chunks/UiFormField.js +2 -2
  165. package/vue/chunks/UiGrid.js +2 -2
  166. package/vue/chunks/UiIcon.js +2 -2
  167. package/vue/chunks/UiIconButton.js +77 -11
  168. package/vue/chunks/UiImage.js +2 -2
  169. package/vue/chunks/UiInput.js +3 -3
  170. package/vue/chunks/UiInputGroup.js +3 -3
  171. package/vue/chunks/UiLightEditor.js +347 -0
  172. package/vue/chunks/UiList.js +2 -2
  173. package/vue/chunks/UiListItem.js +2 -2
  174. package/vue/chunks/UiListbox.js +2 -2
  175. package/vue/chunks/UiMenu.js +3 -3
  176. package/vue/chunks/UiMenuGroup.js +2 -2
  177. package/vue/chunks/UiMenuItem.js +2 -2
  178. package/vue/chunks/UiMeter.js +2 -2
  179. package/vue/chunks/UiNavItem.js +2 -2
  180. package/vue/chunks/UiNumberInput.js +403 -0
  181. package/vue/chunks/UiPageHeader.js +2 -2
  182. package/vue/chunks/UiPopover.js +4 -4
  183. package/vue/chunks/UiRadio.js +2 -2
  184. package/vue/chunks/UiRadioGroup.js +2 -2
  185. package/vue/chunks/UiReel.js +2 -2
  186. package/vue/chunks/UiScrollArea.js +2 -2
  187. package/vue/chunks/UiSearchResultRow.js +2 -2
  188. package/vue/chunks/UiSearchShell.js +2 -2
  189. package/vue/chunks/UiSection.js +2 -2
  190. package/vue/chunks/UiSelect.js +3 -3
  191. package/vue/chunks/UiSeparator.js +2 -2
  192. package/vue/chunks/UiSidebar.js +2 -2
  193. package/vue/chunks/UiSlider.js +396 -0
  194. package/vue/chunks/UiSpinner.js +2 -2
  195. package/vue/chunks/UiStack.js +2 -2
  196. package/vue/chunks/UiStatusMessage.js +2 -2
  197. package/vue/chunks/UiSwatch.js +2 -2
  198. package/vue/chunks/UiSwitch.js +3 -3
  199. package/vue/chunks/UiSwitcher.js +2 -2
  200. package/vue/chunks/UiTable.js +2 -2
  201. package/vue/chunks/UiTabs.js +3 -3
  202. package/vue/chunks/UiText.js +53 -12
  203. package/vue/chunks/UiTextarea.js +3 -3
  204. package/vue/chunks/UiToast.js +2 -2
  205. package/vue/chunks/UiToastRegion.js +2 -2
  206. package/vue/chunks/UiTooltip.js +3 -3
  207. package/vue/chunks/UiTopBar.js +1 -1
  208. package/vue/chunks/UiTree.js +2 -2
  209. package/vue/chunks/UiTreeItem.js +2 -2
  210. package/vue/chunks/_plugin-vue_export-helper.js +68 -2
  211. package/vue/chunks/props.js +24 -1
  212. package/vue/components.css +3391 -2139
  213. package/vue/editor/index.js +623 -211
  214. package/vue/index.d.ts +4 -0
  215. package/vue/index.js +6 -2
@@ -7,6 +7,7 @@ import {
7
7
  checkHydratedRoot,
8
8
  concat,
9
9
  createDispatch,
10
+ cycleCheckedComputed,
10
11
  nativeAttrs,
11
12
  useComponentHost,
12
13
  useReflectedProp,
@@ -16,6 +17,9 @@ import {
16
17
  checkedProp,
17
18
  checkPropInput,
18
19
  type InputBindings,
20
+ inputComputed,
21
+ inputDefault,
22
+ inputRead,
19
23
  propValidityState,
20
24
  READY_INPUT,
21
25
  requireInputStatus,
@@ -83,6 +87,15 @@ const propValidityContract = {
83
87
  description: 'Deprecated alias for loading.',
84
88
  default: false,
85
89
  },
90
+ preset: {
91
+ type: { kind: 'terminal', name: 'keyword' },
92
+ required: false,
93
+ target: { attribute: 'preset' },
94
+ description:
95
+ 'The same shortcuts as Button: primary is solid accent, standard is solid neutral, quiet is ghost neutral, and destructive is solid danger. A named preset\n wins over variant and tone; none preserves independent choices.',
96
+ values: ['none', 'primary', 'standard', 'quiet', 'destructive'],
97
+ default: 'none',
98
+ },
86
99
  revealed: {
87
100
  type: { kind: 'terminal', name: 'boolean' },
88
101
  required: false,
@@ -112,8 +125,9 @@ const propValidityContract = {
112
125
  required: false,
113
126
  target: { attribute: 'tone' },
114
127
  description:
115
- 'Colour for every variant. When omitted, ghost and outline keep their neutral appearance and solid keeps its accent fill. Set accent for a coloured action\n or neutral for a quiet one. Native aria-pressed="true" keeps an outline toggle visibly pressed; the consumer owns that state.',
116
- values: ['accent', 'neutral'],
128
+ 'Colour for every variant. auto preserves the existing variant-specific default. When omitted, ghost and outline keep their neutral appearance and solid\n keeps its accent fill. Set accent for a coloured action or neutral for a quiet one. danger, success, warning and info share Button\'s intent colors. Native\n aria-pressed="true" keeps an outline toggle visibly pressed; the consumer owns that state.',
129
+ values: ['auto', 'accent', 'neutral', 'danger', 'success', 'warning', 'info'],
130
+ default: 'auto',
117
131
  },
118
132
  variant: {
119
133
  type: { kind: 'terminal', name: 'keyword' },
@@ -134,10 +148,19 @@ const props = defineProps({
134
148
  loading: { type: null as unknown as PropType<boolean | null> },
135
149
  matchButton: { type: null as unknown as PropType<boolean | null> },
136
150
  pending: { type: null as unknown as PropType<boolean | null> },
151
+ preset: {
152
+ type: null as unknown as PropType<
153
+ 'none' | 'primary' | 'standard' | 'quiet' | 'destructive' | null
154
+ >,
155
+ },
137
156
  revealed: { type: null as unknown as PropType<boolean | null> },
138
157
  round: { type: null as unknown as PropType<boolean | null> },
139
158
  size: { type: null as unknown as PropType<'sm' | 'md' | 'lg' | null> },
140
- tone: { type: null as unknown as PropType<'accent' | 'neutral' | null> },
159
+ tone: {
160
+ type: null as unknown as PropType<
161
+ 'auto' | 'accent' | 'neutral' | 'danger' | 'success' | 'warning' | 'info' | null
162
+ >,
163
+ },
141
164
  variant: { type: null as unknown as PropType<'ghost' | 'outline' | 'solid' | null> },
142
165
  [BINDING_INPUTS_PROP]: { type: null as unknown as PropType<InputBindings> },
143
166
  })
@@ -149,10 +172,11 @@ const acceptedProps: Record<string, unknown> = {
149
172
  loading: false,
150
173
  matchButton: false,
151
174
  pending: false,
175
+ preset: 'none',
152
176
  revealed: false,
153
177
  round: false,
154
178
  size: 'md',
155
- tone: null,
179
+ tone: 'auto',
156
180
  variant: 'ghost',
157
181
  }
158
182
  const inputTracking = vuePropInputs(acceptedProps, {
@@ -162,9 +186,11 @@ const inputTracking = vuePropInputs(acceptedProps, {
162
186
  loading: false,
163
187
  matchButton: false,
164
188
  pending: false,
189
+ preset: 'none',
165
190
  revealed: false,
166
191
  round: false,
167
192
  size: 'md',
193
+ tone: 'auto',
168
194
  variant: 'ghost',
169
195
  }, (name, value, source, values) => {
170
196
  switch (name) {
@@ -182,6 +208,8 @@ const inputTracking = vuePropInputs(acceptedProps, {
182
208
  return checkPropInput(value, { kind: 'terminal', name: 'boolean' }, true, true)
183
209
  case 'pending':
184
210
  return checkPropInput(value, { kind: 'terminal', name: 'boolean' }, true, true)
211
+ case 'preset':
212
+ return checkPropInput(value, { kind: 'terminal', name: 'keyword' }, true, true)
185
213
  case 'revealed':
186
214
  return checkPropInput(value, { kind: 'terminal', name: 'boolean' }, true, true)
187
215
  case 'round':
@@ -233,6 +261,11 @@ const checkedProps = computed(() => {
233
261
  props['pending'],
234
262
  props[BINDING_INPUTS_PROP],
235
263
  ) as boolean,
264
+ preset: propInputs.value<'none' | 'primary' | 'standard' | 'quiet' | 'destructive' | null>(
265
+ 'preset',
266
+ props['preset'],
267
+ props[BINDING_INPUTS_PROP],
268
+ ) as 'none' | 'primary' | 'standard' | 'quiet' | 'destructive',
236
269
  revealed: propInputs.value<boolean | null>(
237
270
  'revealed',
238
271
  props['revealed'],
@@ -248,11 +281,16 @@ const checkedProps = computed(() => {
248
281
  props['size'],
249
282
  props[BINDING_INPUTS_PROP],
250
283
  ) as 'sm' | 'md' | 'lg',
251
- tone: propInputs.value<'accent' | 'neutral' | null>(
252
- 'tone',
253
- props['tone'],
254
- props[BINDING_INPUTS_PROP],
255
- ),
284
+ tone: propInputs.value<
285
+ 'auto' | 'accent' | 'neutral' | 'danger' | 'success' | 'warning' | 'info' | null
286
+ >('tone', props['tone'], props[BINDING_INPUTS_PROP]) as
287
+ | 'auto'
288
+ | 'accent'
289
+ | 'neutral'
290
+ | 'danger'
291
+ | 'success'
292
+ | 'warning'
293
+ | 'info',
256
294
  variant: propInputs.value<'ghost' | 'outline' | 'solid' | null>(
257
295
  'variant',
258
296
  props['variant'],
@@ -273,6 +311,38 @@ const reflectedProp = useReflectedProp()
273
311
  const hydrationInstance = getCurrentInstance()
274
312
 
275
313
  const root = ref<HTMLElement | null>(null)
314
+ const appearance: ReturnType<typeof inputComputed<any>> = inputComputed<any>(
315
+ () =>
316
+ (({
317
+ none: inputRead(checkedProps.value.variant, propInputs.status('variant')),
318
+ primary: 'solid',
319
+ standard: 'solid',
320
+ quiet: 'ghost',
321
+ destructive: 'solid',
322
+ }) as Record<string, any>)[
323
+ inputRead(checkedProps.value.preset, propInputs.status('preset'))
324
+ ] as any,
325
+ (read) => {
326
+ const value = cycleCheckedComputed(read)
327
+ return { get: () => value.value }
328
+ },
329
+ )
330
+ const colorTone: ReturnType<typeof inputComputed<any>> = inputComputed<any>(
331
+ () =>
332
+ (({
333
+ none: inputRead(checkedProps.value.tone, propInputs.status('tone')),
334
+ primary: 'accent',
335
+ standard: 'neutral',
336
+ quiet: 'neutral',
337
+ destructive: 'danger',
338
+ }) as Record<string, any>)[
339
+ inputRead(checkedProps.value.preset, propInputs.status('preset'))
340
+ ] as any,
341
+ (read) => {
342
+ const value = cycleCheckedComputed(read)
343
+ return { get: () => value.value }
344
+ },
345
+ )
276
346
  let guardedPrevious: any = null
277
347
  const guarded = computed(() => {
278
348
  const candidate: any = ((objectValue: any, indexValue: any) =>
@@ -316,15 +386,10 @@ checkHydratedRoot('button', 'ui-icon-button')
316
386
  /** The values the styles' :host() and :state() rules test. */
317
387
  const hostState = computed(() =>
318
388
  [
319
- checkedProps.value.tone && 'tone',
320
- checkedProps.value.tone != null && `tone=${encodeURIComponent(checkedProps.value.tone)}`,
321
389
  checkedProps.value.anticipatory && 'anticipatory',
322
390
  checkedProps.value.guide && 'guide',
323
391
  checkedProps.value.guide != null && `guide=${encodeURIComponent(checkedProps.value.guide)}`,
324
392
  checkedProps.value.revealed && 'revealed',
325
- checkedProps.value.variant && 'variant',
326
- checkedProps.value.variant != null
327
- && `variant=${encodeURIComponent(checkedProps.value.variant)}`,
328
393
  checkedProps.value.loading && 'loading',
329
394
  checkedProps.value.pending && 'pending',
330
395
  checkedProps.value.size && 'size',
@@ -362,6 +427,7 @@ useComponentHost(() => import('../components/ui-icon-button/ui-icon-button.js'),
362
427
  'loading',
363
428
  'matchButton',
364
429
  'pending',
430
+ 'preset',
365
431
  'revealed',
366
432
  'round',
367
433
  'size',
@@ -370,6 +436,8 @@ useComponentHost(() => import('../components/ui-icon-button/ui-icon-button.js'),
370
436
  ],
371
437
  propValidity: (name: string) =>
372
438
  propValidityState({ contract: propValidityContract, values: { ...props } }, name),
439
+ computed: { appearance, colorTone },
440
+ availability: { appearance: () => appearance.status(), colorTone: () => colorTone.status() },
373
441
  })
374
442
  </script>
375
443
 
@@ -380,6 +448,8 @@ useComponentHost(() => import('../components/ui-icon-button/ui-icon-button.js'),
380
448
  v-bind="nativeAttrs($attrs)"
381
449
  data-hn
382
450
  data-hn-ui-icon-button
451
+ :data-appearance="attribute(appearance.get())"
452
+ :data-tone="attribute(colorTone.get())"
383
453
  :disabled="checkedProps.disabled ?? undefined"
384
454
  :aria-label="checkedProps.label ?? undefined"
385
455
  :data-match-button="checkedProps.matchButton ? '' : undefined"
@@ -393,6 +463,7 @@ useComponentHost(() => import('../components/ui-icon-button/ui-icon-button.js'),
393
463
  :data-ui-icon-button-prop-loading="reflectedProp('loading', 'loading', checkedProps.loading, undefined, false)"
394
464
  :data-ui-icon-button-prop-match-button="reflectedProp('matchButton', 'match-button', checkedProps.matchButton, undefined, false)"
395
465
  :data-ui-icon-button-prop-pending="reflectedProp('pending', 'pending', checkedProps.pending, undefined, false)"
466
+ :data-ui-icon-button-prop-preset="reflectedProp('preset', 'preset', checkedProps.preset, undefined, false)"
396
467
  :data-ui-icon-button-prop-revealed="reflectedProp('revealed', 'revealed', checkedProps.revealed, undefined, false)"
397
468
  :data-ui-icon-button-prop-round="reflectedProp('round', 'round', checkedProps.round, undefined, false)"
398
469
  :data-ui-icon-button-prop-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
@@ -506,7 +577,9 @@ useComponentHost(() => import('../components/ui-icon-button/ui-icon-button.js'),
506
577
  :global(:scope:where([data-hn-ui-icon-button])) {
507
578
  /* Optional inherited action-group values keep text and icon actions under the same light.
508
579
  One fine top/start highlight follows the bottom/end lowlight at a joined action seam.
509
- A single ambient lift avoids stacking a face gradient or another inset bevel. */
580
+ The shared theme supplies reflections and glow independently of the resting lift. */
581
+ --_tone-highlight: var(--ui-accent-highlight, none);
582
+ --_tone-glow: var(--ui-accent-glow, 0 0 transparent);
510
583
  --_ui-action-start: 1px;
511
584
  --_ui-action-edge: var(
512
585
  --ui-action-edge,
@@ -534,7 +607,9 @@ useComponentHost(() => import('../components/ui-icon-button/ui-icon-button.js'),
534
607
  --_ui-action-start: -1px;
535
608
  }
536
609
 
537
- :global(:scope[data-ui-icon-button-state~="tone=accent"]:where([data-hn-ui-icon-button])) {
610
+ :global(:scope[data-tone="accent"]:where([data-hn-ui-icon-button])) {
611
+ --_tone-highlight: var(--ui-accent-highlight, none);
612
+ --_tone-glow: var(--ui-accent-glow, 0 0 transparent);
538
613
  --_icon-button-border: var(--ui-accent-solid);
539
614
  --_icon-button-hover-border: var(--ui-accent-hover);
540
615
  --_icon-button-text: var(--ui-accent-subtle-text, var(--ui-accent-solid));
@@ -545,10 +620,80 @@ useComponentHost(() => import('../components/ui-icon-button/ui-icon-button.js'),
545
620
  );
546
621
  color: var(--_icon-button-text);
547
622
  }
548
- :global(:scope[data-ui-icon-button-state~="tone=neutral"]:where([data-hn-ui-icon-button])) {
549
- --_icon-button-solid-surface: var(--ui-text-primary);
550
- --_icon-button-solid-hover-surface: var(--ui-text-primary);
551
- --_icon-button-solid-text: var(--ui-surface-default);
623
+
624
+ :global(:scope[data-tone="danger"]:where([data-hn-ui-icon-button])) {
625
+ --_tone-highlight: var(--ui-danger-highlight, none);
626
+ --_tone-glow: var(--ui-danger-glow, 0 0 transparent);
627
+ --_icon-button-border: var(--ui-danger);
628
+ --_icon-button-hover-border: var(--ui-danger-hover);
629
+ --_icon-button-text: var(--ui-danger-subtle-text);
630
+ --_icon-button-outline-surface: color-mix(
631
+ in srgb,
632
+ var(--ui-danger) 5%,
633
+ var(--ui-surface-default)
634
+ );
635
+ --_icon-button-solid-surface: var(--ui-danger);
636
+ --_icon-button-solid-hover-surface: var(--ui-danger-hover);
637
+ --_icon-button-solid-text: var(--ui-danger-on-strong);
638
+ color: var(--_icon-button-text);
639
+ }
640
+
641
+ :global(:scope[data-tone="success"]:where([data-hn-ui-icon-button])) {
642
+ --_tone-highlight: var(--ui-success-highlight, none);
643
+ --_tone-glow: var(--ui-success-glow, 0 0 transparent);
644
+ --_icon-button-border: var(--ui-success);
645
+ --_icon-button-hover-border: var(--ui-success-hover);
646
+ --_icon-button-text: var(--ui-success-subtle-text);
647
+ --_icon-button-outline-surface: color-mix(
648
+ in srgb,
649
+ var(--ui-success) 5%,
650
+ var(--ui-surface-default)
651
+ );
652
+ --_icon-button-solid-surface: var(--ui-success);
653
+ --_icon-button-solid-hover-surface: var(--ui-success-hover);
654
+ --_icon-button-solid-text: var(--ui-success-on-strong);
655
+ color: var(--_icon-button-text);
656
+ }
657
+
658
+ :global(:scope[data-tone="warning"]:where([data-hn-ui-icon-button])) {
659
+ --_tone-highlight: var(--ui-warning-highlight, none);
660
+ --_tone-glow: var(--ui-warning-glow, 0 0 transparent);
661
+ --_icon-button-border: var(--ui-warning);
662
+ --_icon-button-hover-border: var(--ui-warning-hover);
663
+ --_icon-button-text: var(--ui-warning-subtle-text);
664
+ --_icon-button-outline-surface: color-mix(
665
+ in srgb,
666
+ var(--ui-warning) 5%,
667
+ var(--ui-surface-default)
668
+ );
669
+ --_icon-button-solid-surface: var(--ui-warning);
670
+ --_icon-button-solid-hover-surface: var(--ui-warning-hover);
671
+ --_icon-button-solid-text: var(--ui-warning-on-strong);
672
+ color: var(--_icon-button-text);
673
+ }
674
+
675
+ :global(:scope[data-tone="info"]:where([data-hn-ui-icon-button])) {
676
+ --_tone-highlight: var(--ui-info-highlight, none);
677
+ --_tone-glow: var(--ui-info-glow, 0 0 transparent);
678
+ --_icon-button-border: var(--ui-info);
679
+ --_icon-button-hover-border: var(--ui-info-hover);
680
+ --_icon-button-text: var(--ui-info-subtle-text);
681
+ --_icon-button-outline-surface: color-mix(
682
+ in srgb,
683
+ var(--ui-info) 5%,
684
+ var(--ui-surface-default)
685
+ );
686
+ --_icon-button-solid-surface: var(--ui-info);
687
+ --_icon-button-solid-hover-surface: var(--ui-info-hover);
688
+ --_icon-button-solid-text: var(--ui-info-on-strong);
689
+ color: var(--_icon-button-text);
690
+ }
691
+ :global(:scope[data-tone="neutral"]:where([data-hn-ui-icon-button])) {
692
+ --_tone-highlight: var(--ui-neutral-highlight, none);
693
+ --_tone-glow: var(--ui-neutral-glow, 0 0 transparent);
694
+ --_icon-button-solid-surface: var(--ui-neutral-surface);
695
+ --_icon-button-solid-hover-surface: var(--ui-neutral-hover);
696
+ --_icon-button-solid-text: var(--ui-text);
552
697
  }
553
698
 
554
699
  :global(:scope[data-ui-icon-button-state~="anticipatory"]:where([data-hn-ui-icon-button])) {
@@ -590,13 +735,13 @@ useComponentHost(() => import('../components/ui-icon-button/ui-icon-button.js'),
590
735
  }
591
736
 
592
737
  @media (hover: hover) and (pointer: fine) {
593
- :global(:scope[data-ui-icon-button-state~="anticipatory"]:not(:scope[data-ui-icon-button-state~="revealed"], :scope[data-ui-icon-button-state~="variant=solid"], :scope[data-ui-icon-button-state~="loading"], :scope[data-ui-icon-button-state~="pending"], :disabled, [aria-pressed="true"], [data-ui-proximity="near"], :hover, :focus-visible):where([data-hn-ui-icon-button])) {
738
+ :global(:scope[data-ui-icon-button-state~="anticipatory"]:not(:scope[data-ui-icon-button-state~="revealed"], :scope[data-appearance="solid"], :scope[data-ui-icon-button-state~="loading"], :scope[data-ui-icon-button-state~="pending"], :disabled, [aria-pressed="true"], [data-ui-proximity="near"], :hover, :focus-visible):where([data-hn-ui-icon-button])) {
594
739
  border-color: transparent;
595
740
  background-color: transparent;
596
741
  box-shadow: none;
597
742
  }
598
743
 
599
- :global(:scope[data-ui-icon-button-state~="anticipatory"]:not(:scope[data-ui-icon-button-state~="revealed"], :scope[data-ui-icon-button-state~="variant=solid"], :scope[data-ui-icon-button-state~="loading"], :scope[data-ui-icon-button-state~="pending"], :disabled, [aria-pressed="true"], [data-ui-proximity="near"], :hover, :focus-visible)
744
+ :global(:scope[data-ui-icon-button-state~="anticipatory"]:not(:scope[data-ui-icon-button-state~="revealed"], :scope[data-appearance="solid"], :scope[data-ui-icon-button-state~="loading"], :scope[data-ui-icon-button-state~="pending"], :disabled, [aria-pressed="true"], [data-ui-proximity="near"], :hover, :focus-visible)
600
745
  .content:where([data-hn-ui-icon-button])) {
601
746
  opacity: 0;
602
747
  transform: scale(0.65);
@@ -604,7 +749,7 @@ useComponentHost(() => import('../components/ui-icon-button/ui-icon-button.js'),
604
749
  }
605
750
  }
606
751
 
607
- :global(:scope[data-ui-icon-button-state~="anticipatory"]:is(:scope[data-ui-icon-button-state~="revealed"], :scope[data-ui-icon-button-state~="variant=solid"], [aria-pressed="true"], [data-ui-proximity="near"], :hover, :focus-visible):where([data-hn-ui-icon-button])::before) {
752
+ :global(:scope[data-ui-icon-button-state~="anticipatory"]:is(:scope[data-ui-icon-button-state~="revealed"], :scope[data-appearance="solid"], [aria-pressed="true"], [data-ui-proximity="near"], :hover, :focus-visible):where([data-hn-ui-icon-button])::before) {
608
753
  opacity: 0;
609
754
  }
610
755
 
@@ -714,7 +859,7 @@ useComponentHost(() => import('../components/ui-icon-button/ui-icon-button.js'),
714
859
  border-radius: var(--ui-radius-round);
715
860
  }
716
861
 
717
- :global(:scope[data-ui-icon-button-state~="variant=outline"]:where([data-hn-ui-icon-button])) {
862
+ :global(:scope[data-appearance="outline"]:where([data-hn-ui-icon-button])) {
718
863
  border-color: var(
719
864
  --ui-icon-button-border,
720
865
  var(--_icon-button-border, var(--ui-control-border, var(--ui-border-strong)))
@@ -723,25 +868,26 @@ useComponentHost(() => import('../components/ui-icon-button/ui-icon-button.js'),
723
868
  --ui-icon-button-outline-surface,
724
869
  var(--_icon-button-outline-surface, var(--ui-surface-default))
725
870
  );
726
- background-image: none;
871
+ background-image: var(--ui-surface-highlight, none);
727
872
  color: var(--ui-icon-button-outline-text, var(--_icon-button-text, var(--ui-text-primary)));
728
- box-shadow: var(--ui-action-shadow, var(--_ui-action-shadow));
873
+ box-shadow:
874
+ var(--ui-action-shadow, var(--_ui-action-shadow)),
875
+ var(--_tone-glow);
729
876
  }
730
877
 
731
- :global(:scope[data-ui-icon-button-state~="variant=solid"]:where([data-hn-ui-icon-button])) {
878
+ :global(:scope[data-appearance="solid"]:where([data-hn-ui-icon-button])) {
732
879
  background-color: var(
733
880
  --ui-icon-button-solid-surface,
734
881
  var(--_icon-button-solid-surface, var(--ui-accent-solid))
735
882
  );
736
- background-image: none;
883
+ background-image: var(--_tone-highlight);
737
884
  color: var(
738
885
  --ui-icon-button-solid-text,
739
886
  var(--_icon-button-solid-text, var(--ui-text-on-accent))
740
887
  );
741
- box-shadow: var(
742
- --ui-icon-button-solid-shadow,
743
- var(--ui-action-shadow, var(--_ui-action-shadow))
744
- );
888
+ box-shadow:
889
+ var(--ui-icon-button-solid-shadow, var(--ui-action-shadow, var(--_ui-action-shadow))),
890
+ var(--_tone-glow);
745
891
  }
746
892
 
747
893
  :global(:scope:hover:enabled:not([aria-disabled="true"]):where([data-hn-ui-icon-button])) {
@@ -753,29 +899,28 @@ useComponentHost(() => import('../components/ui-icon-button/ui-icon-button.js'),
753
899
  color: var(--ui-icon-button-hover-text, var(--_icon-button-text, var(--ui-text-primary)));
754
900
  }
755
901
 
756
- :global(:scope[data-ui-icon-button-state~="variant=outline"]:hover:enabled:not([aria-disabled="true"]):where([data-hn-ui-icon-button])) {
902
+ :global(:scope[data-appearance="outline"]:hover:enabled:not([aria-disabled="true"]):where([data-hn-ui-icon-button])) {
757
903
  border-color: var(
758
904
  --ui-icon-button-hover-border,
759
905
  var(--_icon-button-hover-border, var(--ui-control-border-hover, var(--ui-control-border)))
760
906
  );
761
907
  }
762
908
 
763
- :global(:scope[data-ui-icon-button-state~="variant=solid"]:hover:enabled:not([aria-disabled="true"]):where([data-hn-ui-icon-button])) {
909
+ :global(:scope[data-appearance="solid"]:hover:enabled:not([aria-disabled="true"]):where([data-hn-ui-icon-button])) {
764
910
  background-color: var(
765
911
  --ui-icon-button-solid-hover-surface,
766
912
  var(--_icon-button-solid-hover-surface, var(--ui-accent-hover))
767
913
  );
768
914
  }
769
915
 
770
- :global(:scope[data-ui-icon-button-state~="variant=solid"][data-ui-icon-button-state~="tone=accent"]:hover:enabled:not([aria-disabled="true"]):where([data-hn-ui-icon-button])),
771
- :global(:scope[data-ui-icon-button-state~="variant=solid"][data-ui-icon-button-state~="tone=neutral"]:hover:enabled:not([aria-disabled="true"]):where([data-hn-ui-icon-button])) {
916
+ :global(:scope[data-appearance="solid"]:hover:enabled:not([aria-disabled="true"]):where([data-hn-ui-icon-button])) {
772
917
  color: var(
773
918
  --ui-icon-button-solid-text,
774
919
  var(--_icon-button-solid-text, var(--ui-text-on-accent))
775
920
  );
776
921
  }
777
922
 
778
- :global(:scope[data-ui-icon-button-state~="variant=ghost"][aria-expanded="true"]:enabled:not([aria-disabled="true"]):where([data-hn-ui-icon-button])) {
923
+ :global(:scope[data-appearance="ghost"][aria-expanded="true"]:enabled:not([aria-disabled="true"]):where([data-hn-ui-icon-button])) {
779
924
  background-color: var(
780
925
  --ui-icon-button-active-surface,
781
926
  color-mix(in srgb, currentColor 16%, transparent)
@@ -783,7 +928,7 @@ useComponentHost(() => import('../components/ui-icon-button/ui-icon-button.js'),
783
928
  color: var(--ui-icon-button-hover-text, var(--_icon-button-text, var(--ui-text-primary)));
784
929
  box-shadow: var(--ui-pressed);
785
930
  }
786
- :global(:scope[data-ui-icon-button-state~="variant=outline"][aria-pressed="true"]:enabled:where([data-hn-ui-icon-button])) {
931
+ :global(:scope[data-appearance="outline"][aria-pressed="true"]:enabled:where([data-hn-ui-icon-button])) {
787
932
  background-color: var(
788
933
  --ui-icon-button-active-surface,
789
934
  color-mix(in srgb, currentColor 12%, var(--ui-surface-default))
@@ -823,35 +968,35 @@ useComponentHost(() => import('../components/ui-icon-button/ui-icon-button.js'),
823
968
  box-shadow: var(--ui-focus-halo);
824
969
  }
825
970
 
826
- :global(:scope[data-ui-icon-button-state~="variant=outline"]:focus-visible:where([data-hn-ui-icon-button])) {
971
+ :global(:scope[data-appearance="outline"]:focus-visible:where([data-hn-ui-icon-button])) {
827
972
  box-shadow:
828
973
  var(--ui-action-shadow, var(--_ui-action-shadow)),
829
974
  var(--ui-focus-halo);
830
975
  }
831
976
 
832
- :global(:scope[data-ui-icon-button-state~="variant=solid"]:focus-visible:where([data-hn-ui-icon-button])) {
977
+ :global(:scope[data-appearance="solid"]:focus-visible:where([data-hn-ui-icon-button])) {
833
978
  box-shadow:
834
979
  var(--ui-icon-button-solid-shadow, var(--ui-action-shadow, var(--_ui-action-shadow))),
835
980
  var(--ui-focus-halo);
836
981
  }
837
982
 
838
- :global(:scope:is(:scope[data-ui-icon-button-state~="variant=outline"], :scope[data-ui-icon-button-state~="variant=solid"]):active:enabled:not([aria-disabled="true"]):where([data-hn-ui-icon-button])) {
983
+ :global(:scope:is(:scope[data-appearance="outline"], :scope[data-appearance="solid"]):active:enabled:not([aria-disabled="true"]):where([data-hn-ui-icon-button])) {
839
984
  background-image: none;
840
985
  box-shadow: var(--ui-pressed);
841
986
  }
842
987
 
843
- :global(:scope[data-ui-icon-button-state~="variant=outline"][aria-pressed="true"]:enabled:focus-visible:where([data-hn-ui-icon-button])) {
988
+ :global(:scope[data-appearance="outline"][aria-pressed="true"]:enabled:focus-visible:where([data-hn-ui-icon-button])) {
844
989
  box-shadow:
845
990
  var(--ui-pressed),
846
991
  var(--ui-focus-halo);
847
992
  }
848
993
 
849
994
  @media (forced-colors: active) {
850
- :global(:scope[data-ui-icon-button-state~="variant=outline"][aria-pressed="true"]:enabled:where([data-hn-ui-icon-button])) {
995
+ :global(:scope[data-appearance="outline"][aria-pressed="true"]:enabled:where([data-hn-ui-icon-button])) {
851
996
  outline: var(--ui-focus-width) solid Highlight;
852
997
  outline-offset: calc(-2 * var(--ui-focus-width));
853
998
  }
854
- :global(:scope[data-ui-icon-button-state~="variant=outline"][aria-pressed="true"]:enabled:focus-visible:where([data-hn-ui-icon-button])) {
999
+ :global(:scope[data-appearance="outline"][aria-pressed="true"]:enabled:focus-visible:where([data-hn-ui-icon-button])) {
855
1000
  outline-offset: var(--ui-focus-width);
856
1001
  }
857
1002
  }
@@ -866,7 +1011,7 @@ useComponentHost(() => import('../components/ui-icon-button/ui-icon-button.js'),
866
1011
  background-image: none;
867
1012
  }
868
1013
 
869
- :global(:scope[data-ui-icon-button-state~="variant=ghost"]:disabled:where([data-hn-ui-icon-button])) {
1014
+ :global(:scope[data-appearance="ghost"]:disabled:where([data-hn-ui-icon-button])) {
870
1015
  border-color: transparent;
871
1016
  }
872
1017
 
package/vue/UiInput.vue CHANGED
@@ -581,10 +581,11 @@ useComponentHost(() => import('../components/ui-input/ui-input.js'), {
581
581
  --ui-input-radius,
582
582
  var(--_ui-default-input-radius, var(--ui-field-radius, var(--ui-radius-md)))
583
583
  );
584
- background: var(
584
+ background-color: var(
585
585
  --ui-input-surface,
586
586
  var(--_ui-default-input-surface, var(--ui-control-surface, var(--ui-surface-elevated)))
587
587
  );
588
+ background-image: var(--_ui-default-input-highlight, var(--ui-surface-highlight, none));
588
589
  color: var(--ui-text-primary);
589
590
  font: inherit;
590
591
  line-height: var(--ui-line-height-tight);
@@ -279,6 +279,7 @@ useComponentHost(() => import('../components/ui-input-group/ui-input-group.js'),
279
279
  --_ui-default-input-focus-outline: none;
280
280
  --_ui-default-input-radius: 0;
281
281
  --_ui-default-input-surface: transparent;
282
+ --_ui-default-input-highlight: none;
282
283
  --_ui-default-textarea-border-width: 0;
283
284
  --_ui-default-textarea-border: transparent;
284
285
  --_ui-default-textarea-border-hover: transparent;
@@ -290,6 +291,7 @@ useComponentHost(() => import('../components/ui-input-group/ui-input-group.js'),
290
291
  --_ui-default-textarea-focus-outline: none;
291
292
  --_ui-default-textarea-radius: 0;
292
293
  --_ui-default-textarea-surface: transparent;
294
+ --_ui-default-textarea-highlight: none;
293
295
 
294
296
  display: flex !important;
295
297
  align-items: stretch !important;
@@ -300,7 +302,8 @@ useComponentHost(() => import('../components/ui-input-group/ui-input-group.js'),
300
302
  /* The frame reads the shared control tokens with a lone Input's fallbacks, so the two match. */
301
303
  border: var(--ui-border-width) solid var(--ui-control-border, var(--ui-border-strong));
302
304
  border-radius: var(--ui-input-group-radius, var(--ui-field-radius, var(--ui-radius-md)));
303
- background: var(--ui-control-surface, var(--ui-surface-elevated));
305
+ background-color: var(--ui-control-surface, var(--ui-surface-elevated));
306
+ background-image: var(--ui-surface-highlight, none);
304
307
  box-shadow: var(--ui-control-inset);
305
308
  overflow: hidden;
306
309
  /* A press anywhere in the frame focuses the input. */
@@ -0,0 +1,75 @@
1
+ import type { PropType } from 'vue';
2
+ import { type InputBindings } from './props.js';
3
+ declare var __VLS_1: {};
4
+ type __VLS_Slots = {} & {
5
+ default?: (props: typeof __VLS_1) => any;
6
+ };
7
+ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
8
+ disabled: {
9
+ type: PropType<boolean | null>;
10
+ };
11
+ label: {
12
+ type: PropType<string | null>;
13
+ };
14
+ size: {
15
+ type: PropType<"sm" | "md" | "lg" | null>;
16
+ };
17
+ x: {
18
+ type: PropType<number | null>;
19
+ };
20
+ y: {
21
+ type: PropType<number | null>;
22
+ };
23
+ "\0htmlNextInputStatus": {
24
+ type: PropType<InputBindings>;
25
+ };
26
+ }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
27
+ input: (event: CustomEvent<{
28
+ readonly x: number;
29
+ readonly y: number;
30
+ }>) => any;
31
+ change: (event: CustomEvent<{
32
+ readonly x: number;
33
+ readonly y: number;
34
+ }>) => any;
35
+ "update:x": (value: number) => any;
36
+ "update:y": (value: number) => any;
37
+ }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
38
+ disabled: {
39
+ type: PropType<boolean | null>;
40
+ };
41
+ label: {
42
+ type: PropType<string | null>;
43
+ };
44
+ size: {
45
+ type: PropType<"sm" | "md" | "lg" | null>;
46
+ };
47
+ x: {
48
+ type: PropType<number | null>;
49
+ };
50
+ y: {
51
+ type: PropType<number | null>;
52
+ };
53
+ "\0htmlNextInputStatus": {
54
+ type: PropType<InputBindings>;
55
+ };
56
+ }>> & Readonly<{
57
+ onInput?: ((event: CustomEvent<{
58
+ readonly x: number;
59
+ readonly y: number;
60
+ }>) => any) | undefined;
61
+ onChange?: ((event: CustomEvent<{
62
+ readonly x: number;
63
+ readonly y: number;
64
+ }>) => any) | undefined;
65
+ "onUpdate:x"?: ((value: number) => any) | undefined;
66
+ "onUpdate:y"?: ((value: number) => any) | undefined;
67
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
68
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
69
+ declare const _default: typeof __VLS_export;
70
+ export default _default;
71
+ type __VLS_WithSlots<T, S> = T & {
72
+ new (): {
73
+ $slots: S;
74
+ };
75
+ };
@@ -0,0 +1,2 @@
1
+ import { t as UiLightEditor_default } from "./chunks/UiLightEditor.js";
2
+ export { UiLightEditor_default as default };