@threadlabs/looma 0.33.1 → 0.34.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 (184) hide show
  1. package/components/shared/overlay.js +8 -2
  2. package/components/shared/surface-material.js +21 -0
  3. package/components/ui-button/ui-button.html +63 -47
  4. package/components/ui-card/ui-card.html +44 -2
  5. package/components/ui-curve-editor/curve.js +10 -0
  6. package/components/ui-curve-editor/ui-curve-editor.html +181 -0
  7. package/components/ui-curve-editor/ui-curve-editor.js +51 -0
  8. package/components/ui-dialog/ui-dialog.html +62 -1
  9. package/components/ui-dialog/ui-dialog.js +9 -1
  10. package/components/ui-icon-button/ui-icon-button.html +75 -23
  11. package/components/ui-menu/ui-menu.html +60 -0
  12. package/components/ui-menu/ui-menu.js +1 -1
  13. package/components/ui-number-input/arithmetic.js +47 -0
  14. package/components/ui-number-input/ui-number-input.html +62 -0
  15. package/components/ui-number-input/ui-number-input.js +44 -0
  16. package/components/ui-popover/ui-popover.html +64 -1
  17. package/components/ui-popover/ui-popover.js +1 -1
  18. package/components/ui-slider/ui-slider.html +84 -0
  19. package/components/ui-slider/ui-slider.js +29 -0
  20. package/components/ui-tabs/ui-tabs.html +6 -1
  21. package/components/ui-text/ui-text.html +31 -6
  22. package/components/ui-tooltip/ui-tooltip.html +60 -0
  23. package/components/ui-tooltip/ui-tooltip.js +1 -1
  24. package/dist/index.js +46 -43
  25. package/docs/README.md +34 -4
  26. package/docs/card.html +16 -2
  27. package/docs/card.js +17 -2
  28. package/docs/catalog.json +1154 -144
  29. package/docs/customizer-render.mjs +35 -9
  30. package/docs/customizer.js +83 -20
  31. package/docs/documentation.css +9 -1
  32. package/docs/index.d.ts +4 -2
  33. package/docs/index.mjs +1 -1
  34. package/docs/preview.js +2 -0
  35. package/docs/render.mjs +15 -6
  36. package/docs/site.mjs +50 -9
  37. package/docs/theme-session.mjs +51 -0
  38. package/docs/theme.mjs +134 -15
  39. package/docs/value-editors.mjs +33 -0
  40. package/package.json +2 -2
  41. package/styles/ui-button.css +45 -45
  42. package/styles/ui-card.css +47 -0
  43. package/styles/ui-curve-editor.css +109 -0
  44. package/styles/ui-dialog.css +132 -0
  45. package/styles/ui-icon-button.css +63 -20
  46. package/styles/ui-menu.css +72 -0
  47. package/styles/ui-number-input.css +34 -0
  48. package/styles/ui-popover.css +74 -0
  49. package/styles/ui-slider.css +53 -0
  50. package/styles/ui-tabs.css +6 -1
  51. package/styles/ui-text.css +23 -1
  52. package/styles/ui-tooltip.css +72 -0
  53. package/theme-system.css +26 -10
  54. package/tokens.css +8 -2
  55. package/vanilla/UiButton.d.ts +1 -0
  56. package/vanilla/UiButton.js +195 -130
  57. package/vanilla/UiCard.d.ts +1 -1
  58. package/vanilla/UiCard.js +1 -1
  59. package/vanilla/UiCurveEditor.d.ts +28 -0
  60. package/vanilla/UiCurveEditor.js +134 -0
  61. package/vanilla/UiIconButton.d.ts +2 -1
  62. package/vanilla/UiIconButton.js +58 -31
  63. package/vanilla/UiNumberInput.d.ts +33 -0
  64. package/vanilla/UiNumberInput.js +79 -0
  65. package/vanilla/UiSlider.d.ts +33 -0
  66. package/vanilla/UiSlider.js +125 -0
  67. package/vanilla/UiText.d.ts +2 -2
  68. package/vanilla/UiText.js +45 -11
  69. package/vanilla/index.js +3 -0
  70. package/vue/UiButton.d.ts +6 -0
  71. package/vue/UiButton.vue +155 -56
  72. package/vue/UiCard.d.ts +2 -2
  73. package/vue/UiCard.vue +55 -5
  74. package/vue/UiCurveEditor.d.ts +53 -0
  75. package/vue/UiCurveEditor.js +2 -0
  76. package/vue/UiCurveEditor.vue +427 -0
  77. package/vue/UiDialog.vue +177 -1
  78. package/vue/UiIconButton.d.ts +8 -2
  79. package/vue/UiIconButton.vue +164 -34
  80. package/vue/UiMenu.vue +89 -0
  81. package/vue/UiNumberInput.d.ts +83 -0
  82. package/vue/UiNumberInput.js +2 -0
  83. package/vue/UiNumberInput.vue +370 -0
  84. package/vue/UiPopover.vue +92 -1
  85. package/vue/UiSlider.d.ts +83 -0
  86. package/vue/UiSlider.js +2 -0
  87. package/vue/UiSlider.vue +412 -0
  88. package/vue/UiTabs.vue +6 -1
  89. package/vue/UiText.d.ts +7 -5
  90. package/vue/UiText.vue +104 -22
  91. package/vue/UiTooltip.vue +89 -0
  92. package/vue/chunks/UiActionBar.js +1 -1
  93. package/vue/chunks/UiAffordanceScope.js +2 -2
  94. package/vue/chunks/UiAvatar.js +2 -2
  95. package/vue/chunks/UiAvatarGroup.js +2 -2
  96. package/vue/chunks/UiBadge.js +2 -2
  97. package/vue/chunks/UiBreadcrumbItem.js +2 -2
  98. package/vue/chunks/UiBreadcrumbs.js +2 -2
  99. package/vue/chunks/UiButton.js +94 -11
  100. package/vue/chunks/UiCallout.js +2 -2
  101. package/vue/chunks/UiCard.js +6 -5
  102. package/vue/chunks/UiCheckbox.js +2 -2
  103. package/vue/chunks/UiCluster.js +2 -2
  104. package/vue/chunks/UiColorPicker.js +2 -2
  105. package/vue/chunks/UiCombobox.js +2 -2
  106. package/vue/chunks/UiContainer.js +2 -2
  107. package/vue/chunks/UiContextMenu.js +2 -2
  108. package/vue/chunks/UiCover.js +2 -2
  109. package/vue/chunks/UiCurveEditor.js +413 -0
  110. package/vue/chunks/UiDescriptionItem.js +2 -2
  111. package/vue/chunks/UiDescriptionList.js +2 -2
  112. package/vue/chunks/UiDialog.js +4 -4
  113. package/vue/chunks/UiDisclosure.js +2 -2
  114. package/vue/chunks/UiEditable.js +2 -2
  115. package/vue/chunks/UiEditorBlockActions.js +2 -2
  116. package/vue/chunks/UiEditorChipEditor.js +2 -2
  117. package/vue/chunks/UiEditorCodeLanguage.js +2 -2
  118. package/vue/chunks/UiEditorFootnoteEditor.js +2 -2
  119. package/vue/chunks/UiEditorImageToolbar.js +3 -3
  120. package/vue/chunks/UiEditorInsertTableGrid.js +2 -2
  121. package/vue/chunks/UiEditorLinkCard.js +3 -3
  122. package/vue/chunks/UiEditorLinkForm.js +3 -3
  123. package/vue/chunks/UiEditorMentionMenu.js +2 -2
  124. package/vue/chunks/UiEditorMentionMenuItem.js +2 -2
  125. package/vue/chunks/UiEditorSlashMenu.js +2 -2
  126. package/vue/chunks/UiEditorSlashMenuGroup.js +2 -2
  127. package/vue/chunks/UiEditorSlashMenuItem.js +2 -2
  128. package/vue/chunks/UiEditorSurface.js +2 -2
  129. package/vue/chunks/UiEditorTableContextMenu.js +2 -2
  130. package/vue/chunks/UiEditorTableOverlay.js +2 -2
  131. package/vue/chunks/UiEditorTableToolbar.js +2 -2
  132. package/vue/chunks/UiEditorToolbar.js +2 -2
  133. package/vue/chunks/UiFloatingActionButton.js +2 -2
  134. package/vue/chunks/UiFormField.js +2 -2
  135. package/vue/chunks/UiGrid.js +2 -2
  136. package/vue/chunks/UiIcon.js +2 -2
  137. package/vue/chunks/UiIconButton.js +77 -11
  138. package/vue/chunks/UiImage.js +2 -2
  139. package/vue/chunks/UiInput.js +2 -2
  140. package/vue/chunks/UiInputGroup.js +2 -2
  141. package/vue/chunks/UiList.js +2 -2
  142. package/vue/chunks/UiListItem.js +2 -2
  143. package/vue/chunks/UiListbox.js +2 -2
  144. package/vue/chunks/UiMenu.js +3 -3
  145. package/vue/chunks/UiMenuGroup.js +2 -2
  146. package/vue/chunks/UiMenuItem.js +2 -2
  147. package/vue/chunks/UiMeter.js +2 -2
  148. package/vue/chunks/UiNavItem.js +2 -2
  149. package/vue/chunks/UiNumberInput.js +390 -0
  150. package/vue/chunks/UiPageHeader.js +2 -2
  151. package/vue/chunks/UiPopover.js +4 -4
  152. package/vue/chunks/UiRadio.js +2 -2
  153. package/vue/chunks/UiRadioGroup.js +2 -2
  154. package/vue/chunks/UiReel.js +2 -2
  155. package/vue/chunks/UiScrollArea.js +2 -2
  156. package/vue/chunks/UiSearchResultRow.js +2 -2
  157. package/vue/chunks/UiSearchShell.js +2 -2
  158. package/vue/chunks/UiSection.js +2 -2
  159. package/vue/chunks/UiSelect.js +2 -2
  160. package/vue/chunks/UiSeparator.js +2 -2
  161. package/vue/chunks/UiSidebar.js +2 -2
  162. package/vue/chunks/UiSlider.js +396 -0
  163. package/vue/chunks/UiSpinner.js +2 -2
  164. package/vue/chunks/UiStack.js +2 -2
  165. package/vue/chunks/UiStatusMessage.js +2 -2
  166. package/vue/chunks/UiSwatch.js +2 -2
  167. package/vue/chunks/UiSwitch.js +2 -2
  168. package/vue/chunks/UiSwitcher.js +2 -2
  169. package/vue/chunks/UiTable.js +2 -2
  170. package/vue/chunks/UiTabs.js +3 -3
  171. package/vue/chunks/UiText.js +53 -12
  172. package/vue/chunks/UiTextarea.js +2 -2
  173. package/vue/chunks/UiToast.js +2 -2
  174. package/vue/chunks/UiToastRegion.js +2 -2
  175. package/vue/chunks/UiTooltip.js +3 -3
  176. package/vue/chunks/UiTopBar.js +1 -1
  177. package/vue/chunks/UiTree.js +2 -2
  178. package/vue/chunks/UiTreeItem.js +2 -2
  179. package/vue/chunks/_plugin-vue_export-helper.js +68 -2
  180. package/vue/chunks/props.js +24 -1
  181. package/vue/components.css +2215 -1203
  182. package/vue/editor/index.js +623 -211
  183. package/vue/index.d.ts +3 -0
  184. package/vue/index.js +5 -2
@@ -0,0 +1,370 @@
1
+ <!-- Generated by HTML Next 1.0.0-alpha.69 for Vue 3.5. Do not edit. -->
2
+ <script setup lang="ts">
3
+ import { computed, getCurrentInstance, ref, watchSyncEffect } from 'vue'
4
+ import type { PropType } from 'vue'
5
+ import {
6
+ checkHydratedRoot,
7
+ concat,
8
+ createDispatch,
9
+ nativeAttrs,
10
+ useComponentHost,
11
+ useReflectedProp,
12
+ } from './host'
13
+ import {
14
+ BINDING_INPUTS_PROP,
15
+ checkedProp,
16
+ checkPropInput,
17
+ evaluateInput,
18
+ type InputBindings,
19
+ inputDefault,
20
+ inputRead,
21
+ propValidityState,
22
+ READY_INPUT,
23
+ requireInputStatus,
24
+ UNRESOLVED_INPUT,
25
+ vPropValidity,
26
+ vuePropInputs,
27
+ } from './props'
28
+ import UiIcon from './UiIcon.vue'
29
+ import UiIconButton from './UiIconButton.vue'
30
+ import UiInput from './UiInput.vue'
31
+
32
+ defineOptions({ inheritAttrs: false })
33
+
34
+ const propValidityContract = {
35
+ props: {
36
+ disabled: {
37
+ type: { kind: 'terminal', name: 'boolean' },
38
+ required: false,
39
+ target: { attribute: 'disabled' },
40
+ description:
41
+ 'Prevents typing, stepping and pointer or keyboard changes while keeping the value visible.',
42
+ default: false,
43
+ },
44
+ label: {
45
+ type: { kind: 'terminal', name: 'string' },
46
+ required: false,
47
+ target: { attribute: 'aria-label' },
48
+ description: 'Accessible name for the editing control.',
49
+ default: 'Value',
50
+ },
51
+ max: {
52
+ type: { kind: 'terminal', name: 'number' },
53
+ required: false,
54
+ target: { attribute: 'max' },
55
+ description: 'Inclusive upper bound applied to every editing path.',
56
+ default: 1000000,
57
+ },
58
+ min: {
59
+ type: { kind: 'terminal', name: 'number' },
60
+ required: false,
61
+ target: { attribute: 'min' },
62
+ description:
63
+ 'Inclusive lower bound applied to typing, arithmetic, stepping and external values.',
64
+ default: -1000000,
65
+ },
66
+ name: {
67
+ type: { kind: 'terminal', name: 'string' },
68
+ required: false,
69
+ target: { attribute: 'name' },
70
+ description: 'Optional form field name.',
71
+ default: '',
72
+ },
73
+ size: {
74
+ type: { kind: 'terminal', name: 'keyword' },
75
+ required: false,
76
+ target: { attribute: 'size' },
77
+ description: 'Shared field and button height.',
78
+ values: ['sm', 'md', 'lg'],
79
+ default: 'md',
80
+ },
81
+ step: {
82
+ type: { kind: 'terminal', name: 'number' },
83
+ required: false,
84
+ target: { attribute: 'step' },
85
+ description:
86
+ 'Positive increment used by arrows and step buttons; Shift multiplies it by ten.',
87
+ default: 1,
88
+ },
89
+ unit: {
90
+ type: { kind: 'terminal', name: 'string' },
91
+ required: false,
92
+ target: { attribute: 'unit' },
93
+ description:
94
+ 'One accepted unit, such as px, rem, ms or %. Bare numbers use this unit. No automatic unit conversion.',
95
+ default: '',
96
+ },
97
+ value: {
98
+ type: { kind: 'terminal', name: 'string' },
99
+ required: false,
100
+ target: { attribute: 'value' },
101
+ description:
102
+ 'Exact value. Arithmetic is calculated on Enter or blur; the resulting value includes unit. Invalid expressions stay visible and expose invalid\n state.',
103
+ default: '0',
104
+ },
105
+ },
106
+ } as const
107
+ const props = defineProps({
108
+ disabled: { type: null as unknown as PropType<boolean | null> },
109
+ label: { type: null as unknown as PropType<string | null> },
110
+ max: { type: null as unknown as PropType<number | null> },
111
+ min: { type: null as unknown as PropType<number | null> },
112
+ name: { type: null as unknown as PropType<string | null> },
113
+ size: { type: null as unknown as PropType<'sm' | 'md' | 'lg' | null> },
114
+ step: { type: null as unknown as PropType<number | null> },
115
+ unit: { type: null as unknown as PropType<string | null> },
116
+ value: { type: null as unknown as PropType<string | null> },
117
+ [BINDING_INPUTS_PROP]: { type: null as unknown as PropType<InputBindings> },
118
+ })
119
+ const acceptedProps: Record<string, unknown> = {
120
+ disabled: false,
121
+ label: 'Value',
122
+ max: 1000000,
123
+ min: -1000000,
124
+ name: '',
125
+ size: 'md',
126
+ step: 1,
127
+ unit: '',
128
+ value: '0',
129
+ }
130
+ const inputTracking = vuePropInputs(acceptedProps, {
131
+ disabled: false,
132
+ label: 'Value',
133
+ max: 1000000,
134
+ min: -1000000,
135
+ name: '',
136
+ size: 'md',
137
+ step: 1,
138
+ unit: '',
139
+ value: '0',
140
+ }, (name, value, source, values) => {
141
+ switch (name) {
142
+ case 'disabled':
143
+ return checkPropInput(value, { kind: 'terminal', name: 'boolean' }, true, true)
144
+ case 'label':
145
+ return checkPropInput(value, { kind: 'terminal', name: 'string' }, true, true)
146
+ case 'max':
147
+ return checkPropInput(value, { kind: 'terminal', name: 'number' }, true, true)
148
+ case 'min':
149
+ return checkPropInput(value, { kind: 'terminal', name: 'number' }, true, true)
150
+ case 'name':
151
+ return checkPropInput(value, { kind: 'terminal', name: 'string' }, true, true)
152
+ case 'size':
153
+ return checkPropInput(value, { kind: 'terminal', name: 'keyword' }, true, true)
154
+ case 'step':
155
+ return checkPropInput(value, { kind: 'terminal', name: 'number' }, true, true)
156
+ case 'unit':
157
+ return checkPropInput(value, { kind: 'terminal', name: 'string' }, true, true)
158
+ case 'value':
159
+ return checkPropInput(value, { kind: 'terminal', name: 'string' }, true, true)
160
+ default:
161
+ return { ok: false }
162
+ }
163
+ }, () => {
164
+ void checkedProps.value
165
+ })
166
+ const propInputs = inputTracking.inputs
167
+ const checkedProps = computed(() => {
168
+ void inputTracking.version.value
169
+ return ({
170
+ disabled: propInputs.value<boolean | null>(
171
+ 'disabled',
172
+ props['disabled'],
173
+ props[BINDING_INPUTS_PROP],
174
+ ) as boolean,
175
+ label: propInputs.value<string | null>(
176
+ 'label',
177
+ props['label'],
178
+ props[BINDING_INPUTS_PROP],
179
+ ) as string,
180
+ max: propInputs.value<number | null>('max', props['max'], props[BINDING_INPUTS_PROP]) as number,
181
+ min: propInputs.value<number | null>('min', props['min'], props[BINDING_INPUTS_PROP]) as number,
182
+ name: propInputs.value<string | null>(
183
+ 'name',
184
+ props['name'],
185
+ props[BINDING_INPUTS_PROP],
186
+ ) as string,
187
+ size: propInputs.value<'sm' | 'md' | 'lg' | null>(
188
+ 'size',
189
+ props['size'],
190
+ props[BINDING_INPUTS_PROP],
191
+ ) as 'sm' | 'md' | 'lg',
192
+ step: propInputs.value<number | null>(
193
+ 'step',
194
+ props['step'],
195
+ props[BINDING_INPUTS_PROP],
196
+ ) as number,
197
+ unit: propInputs.value<string | null>(
198
+ 'unit',
199
+ props['unit'],
200
+ props[BINDING_INPUTS_PROP],
201
+ ) as string,
202
+ value: propInputs.value<string | null>(
203
+ 'value',
204
+ props['value'],
205
+ props[BINDING_INPUTS_PROP],
206
+ ) as string,
207
+ })
208
+ })
209
+ const inputStatus = (name: string, handlesError: boolean) => {
210
+ void checkedProps.value
211
+ void inputTracking.version.value
212
+ return requireInputStatus(propInputs.status(name), handlesError)
213
+ }
214
+ void checkedProps.value
215
+ watchSyncEffect(() => {
216
+ void checkedProps.value
217
+ })
218
+ const reflectedProp = useReflectedProp()
219
+ const hydrationInstance = getCurrentInstance()
220
+ const emit = defineEmits<{
221
+ 'update:value': [value: string]
222
+ input: [event: CustomEvent<{ readonly value: string }>]
223
+ change: [event: CustomEvent<{ readonly value: string }>]
224
+ }>()
225
+
226
+ const root = ref<HTMLElement | null>(null)
227
+ checkHydratedRoot('span', 'ui-number-input')
228
+
229
+ const isInputDetail = (
230
+ detail: unknown,
231
+ ): boolean => (detail !== null && typeof detail === 'object' && !Array.isArray(detail)
232
+ && typeof (detail as Record<string, unknown>)['value'] === 'string'
233
+ && Object.keys(detail as object).every((key) => ['value'].includes(key)))
234
+ const dispatch = createDispatch(root, emit as (name: string, detail: unknown) => void, {
235
+ checks: {
236
+ input: isInputDetail,
237
+ change: isInputDetail,
238
+ },
239
+ modeled: ['value'],
240
+ })
241
+
242
+ useComponentHost(() => import('../components/ui-number-input/ui-number-input.js'), {
243
+ root,
244
+ module: true,
245
+ dispatch,
246
+ controllerSource: {
247
+ specifier: '../components/ui-number-input/ui-number-input.js',
248
+ definition: './components/ui-number-input/ui-number-input.html',
249
+ },
250
+ props: checkedProps,
251
+ inputs: propInputs,
252
+ inputTracking,
253
+ propInputs: (name: string) => {
254
+ const incoming = hydrationInstance?.vnode.props
255
+ const kebab = name.replace(/[A-Z]/g, (letter) => '-' + letter.toLowerCase())
256
+ return incoming !== null && incoming !== undefined
257
+ ? (incoming[name] ?? incoming[kebab] ?? null)
258
+ : null
259
+ },
260
+ propNames: ['disabled', 'label', 'max', 'min', 'name', 'size', 'step', 'unit', 'value'],
261
+ propValidity: (name: string) =>
262
+ propValidityState({ contract: propValidityContract, values: { ...props } }, name),
263
+ })
264
+ </script>
265
+
266
+ <template>
267
+ <span
268
+ class="ui-number-input"
269
+ v-bind="nativeAttrs($attrs)"
270
+ data-hn
271
+ v-prop-validity="{ contract: propValidityContract, values: { ...props } }"
272
+ :data-ui-number-input-prop-disabled="reflectedProp('disabled', 'disabled', checkedProps.disabled, undefined, false)"
273
+ :data-ui-number-input-prop-label="reflectedProp('label', 'label', checkedProps.label, undefined, false)"
274
+ :data-ui-number-input-prop-max="reflectedProp('max', 'max', checkedProps.max, undefined, false)"
275
+ :data-ui-number-input-prop-min="reflectedProp('min', 'min', checkedProps.min, undefined, false)"
276
+ :data-ui-number-input-prop-name="reflectedProp('name', 'name', checkedProps.name, undefined, false)"
277
+ :data-ui-number-input-prop-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
278
+ :data-ui-number-input-prop-step="reflectedProp('step', 'step', checkedProps.step, undefined, false)"
279
+ :data-ui-number-input-prop-unit="reflectedProp('unit', 'unit', checkedProps.unit, undefined, false)"
280
+ :data-ui-number-input-prop-value="reflectedProp('value', 'value', checkedProps.value, undefined, false)"
281
+ ref="root"
282
+ ><template
283
+ v-for="boundInput in [evaluateInput(
284
+ () => (concat('Decrease ', inputRead(checkedProps.label, inputStatus('label', true)))) as any,
285
+ READY_INPUT,
286
+ )]"
287
+ ><UiIconButton
288
+ class="ui-icon-button"
289
+ data-number-step="decrease"
290
+ :match-button="true"
291
+ type="button"
292
+ :size="checkedProps.size"
293
+ :disabled="checkedProps.disabled"
294
+ :label="boundInput.value"
295
+ v-bind="{
296
+ [BINDING_INPUTS_PROP]: {
297
+ size: () => ({ value: checkedProps.size, status: inputStatus('size', true) }),
298
+ disabled: () => ({ value: checkedProps.disabled, status: inputStatus('disabled', true) }),
299
+ label: () => boundInput,
300
+ },
301
+ }"
302
+ ><UiIcon class="ui-icon" name="minus" /></UiIconButton></template>{{ ' ' }}<UiInput
303
+ class="ui-input"
304
+ data-ui-field-control=""
305
+ inputmode="decimal"
306
+ spellcheck="false"
307
+ aria-description="Enter calculates arithmetic. Arrow keys step; Shift changes ten steps."
308
+ :size="checkedProps.size"
309
+ :disabled="checkedProps.disabled"
310
+ :value="checkedProps.value"
311
+ :aria-label="checkedProps.label"
312
+ :name="checkedProps.name"
313
+ v-bind="{
314
+ [BINDING_INPUTS_PROP]: {
315
+ size: () => ({ value: checkedProps.size, status: inputStatus('size', true) }),
316
+ disabled: () => ({ value: checkedProps.disabled, status: inputStatus('disabled', true) }),
317
+ value: () => ({ value: checkedProps.value, status: inputStatus('value', true) }),
318
+ },
319
+ }"
320
+ />{{ ' ' }}<template
321
+ v-for="boundInputSnapshot in [evaluateInput(
322
+ () => (concat('Increase ', inputRead(checkedProps.label, inputStatus('label', true)))) as any,
323
+ READY_INPUT,
324
+ )]"
325
+ ><UiIconButton
326
+ class="ui-icon-button"
327
+ data-number-step="increase"
328
+ :match-button="true"
329
+ type="button"
330
+ :size="checkedProps.size"
331
+ :disabled="checkedProps.disabled"
332
+ :label="boundInputSnapshot.value"
333
+ v-bind="{
334
+ [BINDING_INPUTS_PROP]: {
335
+ size: () => ({ value: checkedProps.size, status: inputStatus('size', true) }),
336
+ disabled: () => ({ value: checkedProps.disabled, status: inputStatus('disabled', true) }),
337
+ label: () => boundInputSnapshot,
338
+ },
339
+ }"
340
+ ><UiIcon class="ui-icon" name="plus" /></UiIconButton></template></span>
341
+ </template>
342
+
343
+ <style scoped>
344
+ @scope (.ui-number-input) to ([data-hn]) {
345
+ :global(:scope) {
346
+ display: flex !important;
347
+ align-items: center !important;
348
+ gap: var(--ui-space-1) !important;
349
+ margin: 0 !important;
350
+ padding: 0 !important;
351
+ min-inline-size: 0;
352
+ }
353
+ :global(:scope[hidden]) {
354
+ display: none !important;
355
+ }
356
+ }
357
+ @scope ([data-slotted~="ui-number-input"]:not([data-hn])) to ([data-hn], [data-slotted]) {
358
+ :global(:where(.ui-number-input):where(:scope, :not([data-hn], [data-slotted]:not([data-slotted~="ui-number-input"])))) {
359
+ display: flex !important;
360
+ align-items: center !important;
361
+ gap: var(--ui-space-1) !important;
362
+ margin: 0 !important;
363
+ padding: 0 !important;
364
+ min-inline-size: 0;
365
+ }
366
+ :global(:where(.ui-number-input)[hidden]:where(:scope, :not([data-hn], [data-slotted]:not([data-slotted~="ui-number-input"])))) {
367
+ display: none !important;
368
+ }
369
+ }
370
+ </style>
package/vue/UiPopover.vue CHANGED
@@ -76,7 +76,7 @@ const propValidityContract = {
76
76
  required: false,
77
77
  target: { attribute: 'size' },
78
78
  description:
79
- 'Optional size preset. content keeps the existing intrinsic sizing; the other sizes constrain the surface for compact, medium, or large content.',
79
+ 'Optional size preset. content keeps the existing intrinsic sizing; the other sizes constrain the surface for compact, medium, or large content. Shared\n surface separation adapts to popover purpose and rendered size.',
80
80
  values: ['content', 'sm', 'md', 'lg'],
81
81
  default: 'content',
82
82
  },
@@ -334,10 +334,14 @@ useComponentHost(() => import('../components/ui-popover/ui-popover.js'), {
334
334
  inherits: false;
335
335
  }
336
336
 
337
+ /* Purpose and measured size shape one shared separation lever. The content plane stays opaque;
338
+ transparency, saturation and edge light belong to the surrounding decorative material. */
339
+
337
340
  /* A toolbar or card can supply its own surface, including an unclipped shadow. */
338
341
 
339
342
  @scope (.ui-popover) to ([data-hn]) {
340
343
  :global(:scope:where([data-hn-ui-popover])) {
344
+ --_ui-material-scale: 0.55;
341
345
  --_ui-popover-surface: var(--ui-popover-surface);
342
346
  --_ui-popover-border: var(--ui-popover-border);
343
347
  --_ui-popover-radius: var(--ui-popover-radius);
@@ -373,12 +377,99 @@ useComponentHost(() => import('../components/ui-popover/ui-popover.js'), {
373
377
  var(--ui-overlay-shadow, var(--ui-elevation-overlay, var(--ui-shadow-lg)))
374
378
  );
375
379
  }
380
+ :global(.surface:where([data-hn-ui-popover])) {
381
+ --_ui-material-glassiness: clamp(0, var(--ui-glassiness, 0), 1);
382
+ --_ui-material-separation: clamp(0, var(--ui-surface-separation, 0), 1);
383
+ --_ui-material-active: clamp(
384
+ 0,
385
+ calc((var(--_ui-material-glassiness) + var(--_ui-material-separation)) * 100000),
386
+ 1
387
+ );
388
+ --_ui-material-rim: calc(
389
+ (
390
+ var(--_ui-material-separation) + var(--_ui-material-glassiness) * 0.25
391
+ ) *
392
+ var(--_ui-material-scale, 0.55) *
393
+ 8px
394
+ );
395
+ --_ui-material-content-color: var(
396
+ --_ui-popover-surface,
397
+ var(--ui-material-content, var(--ui-overlay-surface, var(--ui-surface-elevated)))
398
+ );
399
+ --_ui-material-rim-color: color-mix(
400
+ in srgb,
401
+ var(--ui-material-glass, var(--ui-surface-elevated)) calc(var(--_ui-material-active) * 100%),
402
+ transparent
403
+ );
404
+ background:
405
+ linear-gradient(var(--_ui-material-content-color), var(--_ui-material-content-color))
406
+ padding-box,
407
+ linear-gradient(var(--_ui-material-rim-color), var(--_ui-material-rim-color)) border-box,
408
+ var(--_ui-material-content-color) padding-box;
409
+ border-width: calc(var(--ui-border-width) + var(--_ui-material-rim));
410
+ border-color: var(
411
+ --_ui-popover-border,
412
+ color-mix(
413
+ in oklab,
414
+ var(--ui-overlay-border, var(--ui-border-strong)) calc(
415
+ (1 - var(--_ui-material-active)) * 100%
416
+ ),
417
+ transparent
418
+ )
419
+ );
420
+ box-shadow: var(
421
+ --_ui-popover-shadow,
422
+ var(
423
+ --ui-overlay-shadow,
424
+ 0 calc(var(--_ui-material-separation) * var(--_ui-material-scale, 0.55) * 8px) calc(
425
+ var(--_ui-material-separation) * var(--_ui-material-scale, 0.55) * 24px
426
+ ) color-mix(in oklab, var(--ui-text-primary) 15%, transparent),
427
+ inset 0 0 0 calc(var(--_ui-material-active) * var(--ui-border-width)) var(
428
+ --ui-material-edge,
429
+ var(--ui-border-strong)
430
+ ),
431
+ var(--ui-elevation-overlay, var(--ui-shadow-lg))
432
+ )
433
+ );
434
+ backdrop-filter: blur(
435
+ calc(var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.55) * 18px)
436
+ ) saturate(calc(1 + var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.55) * 0.18));
437
+ -webkit-backdrop-filter: blur(
438
+ calc(var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.55) * 18px)
439
+ ) saturate(calc(1 + var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.55) * 0.18));
440
+ }
441
+
442
+ @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
443
+ :global(.surface:where([data-hn-ui-popover])) {
444
+ background: var(--_ui-material-content-color);
445
+ }
446
+ }
447
+
448
+ @media (prefers-reduced-transparency: reduce) {
449
+ :global(.surface:where([data-hn-ui-popover])) {
450
+ background: var(--_ui-material-content-color);
451
+ backdrop-filter: none;
452
+ -webkit-backdrop-filter: none;
453
+ }
454
+ }
455
+
456
+ @media (forced-colors: active) {
457
+ :global(.surface:where([data-hn-ui-popover])) {
458
+ background: Canvas;
459
+ border-color: CanvasText;
460
+ box-shadow: none;
461
+ backdrop-filter: none;
462
+ -webkit-backdrop-filter: none;
463
+ }
464
+ }
376
465
  :global(:scope[data-ui-popover-state~="bare"] .surface:where([data-hn-ui-popover])) {
377
466
  overflow: visible;
378
467
  padding: 0 !important;
379
468
  border: 0;
380
469
  background: transparent;
381
470
  box-shadow: none;
471
+ backdrop-filter: none;
472
+ -webkit-backdrop-filter: none;
382
473
  }
383
474
 
384
475
  :global(:scope:not([data-ui-popover-state~="internalOpen"]):where([data-hn-ui-popover])) {
@@ -0,0 +1,83 @@
1
+ import type { PropType } from 'vue';
2
+ import { type InputBindings } from './props.js';
3
+ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
4
+ disabled: {
5
+ type: PropType<boolean | null>;
6
+ };
7
+ label: {
8
+ type: PropType<string | null>;
9
+ };
10
+ max: {
11
+ type: PropType<number | null>;
12
+ };
13
+ min: {
14
+ type: PropType<number | null>;
15
+ };
16
+ name: {
17
+ type: PropType<string | null>;
18
+ };
19
+ size: {
20
+ type: PropType<"sm" | "md" | "lg" | null>;
21
+ };
22
+ step: {
23
+ type: PropType<number | null>;
24
+ };
25
+ unit: {
26
+ type: PropType<string | null>;
27
+ };
28
+ value: {
29
+ type: PropType<number | null>;
30
+ };
31
+ "\0htmlNextInputStatus": {
32
+ type: PropType<InputBindings>;
33
+ };
34
+ }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
35
+ input: (event: CustomEvent<{
36
+ readonly value: number;
37
+ }>) => any;
38
+ change: (event: CustomEvent<{
39
+ readonly value: number;
40
+ }>) => any;
41
+ "update:value": (value: number) => any;
42
+ }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
43
+ disabled: {
44
+ type: PropType<boolean | null>;
45
+ };
46
+ label: {
47
+ type: PropType<string | null>;
48
+ };
49
+ max: {
50
+ type: PropType<number | null>;
51
+ };
52
+ min: {
53
+ type: PropType<number | null>;
54
+ };
55
+ name: {
56
+ type: PropType<string | null>;
57
+ };
58
+ size: {
59
+ type: PropType<"sm" | "md" | "lg" | null>;
60
+ };
61
+ step: {
62
+ type: PropType<number | null>;
63
+ };
64
+ unit: {
65
+ type: PropType<string | null>;
66
+ };
67
+ value: {
68
+ type: PropType<number | null>;
69
+ };
70
+ "\0htmlNextInputStatus": {
71
+ type: PropType<InputBindings>;
72
+ };
73
+ }>> & Readonly<{
74
+ onInput?: ((event: CustomEvent<{
75
+ readonly value: number;
76
+ }>) => any) | undefined;
77
+ onChange?: ((event: CustomEvent<{
78
+ readonly value: number;
79
+ }>) => any) | undefined;
80
+ "onUpdate:value"?: ((value: number) => any) | undefined;
81
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
82
+ declare const _default: typeof __VLS_export;
83
+ export default _default;
@@ -0,0 +1,2 @@
1
+ import { t as UiSlider_default } from "./chunks/UiSlider.js";
2
+ export { UiSlider_default as default };