@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
@@ -0,0 +1,402 @@
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, provide, ref, useTemplateRef, 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 { acceptsControllerWrite } from './props'
14
+ import {
15
+ BINDING_INPUTS_PROP,
16
+ checkedProp,
17
+ checkPropInput,
18
+ type InputBindings,
19
+ propValidityState,
20
+ READY_INPUT,
21
+ requireInputStatus,
22
+ UNRESOLVED_INPUT,
23
+ vPropValidity,
24
+ vuePropInputs,
25
+ } from './props'
26
+ import UiNumberInput from './UiNumberInput.vue'
27
+
28
+ defineOptions({ inheritAttrs: false })
29
+
30
+ const propValidityContract = {
31
+ props: {
32
+ disabled: {
33
+ type: { kind: 'terminal', name: 'boolean' },
34
+ required: false,
35
+ target: { attribute: 'disabled' },
36
+ description: 'Prevents pointer, keyboard and exact edits.',
37
+ default: false,
38
+ },
39
+ label: {
40
+ type: { kind: 'terminal', name: 'string' },
41
+ required: false,
42
+ target: { attribute: 'aria-label' },
43
+ description: 'Accessible name for the position editor.',
44
+ default: 'Light position',
45
+ },
46
+ size: {
47
+ type: { kind: 'terminal', name: 'keyword' },
48
+ required: false,
49
+ target: { attribute: 'size' },
50
+ description:
51
+ 'Sets both coordinate fields to the shared small, medium or large control height.',
52
+ values: ['sm', 'md', 'lg'],
53
+ default: 'md',
54
+ },
55
+ x: {
56
+ type: { kind: 'terminal', name: 'number' },
57
+ required: false,
58
+ target: { attribute: 'x' },
59
+ description:
60
+ 'Horizontal source position from 0 (left) to 1 (right), relative to every surface.',
61
+ default: 0.5,
62
+ },
63
+ y: {
64
+ type: { kind: 'terminal', name: 'number' },
65
+ required: false,
66
+ target: { attribute: 'y' },
67
+ description:
68
+ 'Vertical source position from 0 (top) to 1 (bottom), relative to every surface.',
69
+ default: 0,
70
+ },
71
+ },
72
+ } as const
73
+ const props = defineProps({
74
+ disabled: { type: null as unknown as PropType<boolean | null> },
75
+ label: { type: null as unknown as PropType<string | null> },
76
+ size: { type: null as unknown as PropType<'sm' | 'md' | 'lg' | null> },
77
+ x: { type: null as unknown as PropType<number | null> },
78
+ y: { type: null as unknown as PropType<number | null> },
79
+ [BINDING_INPUTS_PROP]: { type: null as unknown as PropType<InputBindings> },
80
+ })
81
+ const acceptedProps: Record<string, unknown> = {
82
+ disabled: false,
83
+ label: 'Light position',
84
+ size: 'md',
85
+ x: 0.5,
86
+ y: 0,
87
+ }
88
+ const inputTracking = vuePropInputs(acceptedProps, {
89
+ disabled: false,
90
+ label: 'Light position',
91
+ size: 'md',
92
+ x: 0.5,
93
+ y: 0,
94
+ }, (name, value, source, values) => {
95
+ switch (name) {
96
+ case 'disabled':
97
+ return checkPropInput(value, { kind: 'terminal', name: 'boolean' }, true, true)
98
+ case 'label':
99
+ return checkPropInput(value, { kind: 'terminal', name: 'string' }, true, true)
100
+ case 'size':
101
+ return checkPropInput(value, { kind: 'terminal', name: 'keyword' }, true, true)
102
+ case 'x':
103
+ return checkPropInput(value, { kind: 'terminal', name: 'number' }, true, true)
104
+ case 'y':
105
+ return checkPropInput(value, { kind: 'terminal', name: 'number' }, true, true)
106
+ default:
107
+ return { ok: false }
108
+ }
109
+ }, () => {
110
+ void checkedProps.value
111
+ })
112
+ const propInputs = inputTracking.inputs
113
+ const checkedProps = computed(() => {
114
+ void inputTracking.version.value
115
+ return ({
116
+ disabled: propInputs.value<boolean | null>(
117
+ 'disabled',
118
+ props['disabled'],
119
+ props[BINDING_INPUTS_PROP],
120
+ ) as boolean,
121
+ label: propInputs.value<string | null>(
122
+ 'label',
123
+ props['label'],
124
+ props[BINDING_INPUTS_PROP],
125
+ ) as string,
126
+ size: propInputs.value<'sm' | 'md' | 'lg' | null>(
127
+ 'size',
128
+ props['size'],
129
+ props[BINDING_INPUTS_PROP],
130
+ ) as 'sm' | 'md' | 'lg',
131
+ x: propInputs.value<number | null>('x', props['x'], props[BINDING_INPUTS_PROP]) as number,
132
+ y: propInputs.value<number | null>('y', props['y'], props[BINDING_INPUTS_PROP]) as number,
133
+ })
134
+ })
135
+ const inputStatus = (name: string, handlesError: boolean) => {
136
+ void checkedProps.value
137
+ void inputTracking.version.value
138
+ return requireInputStatus(propInputs.status(name), handlesError)
139
+ }
140
+ void checkedProps.value
141
+ watchSyncEffect(() => {
142
+ void checkedProps.value
143
+ })
144
+ const reflectedProp = useReflectedProp()
145
+ const hydrationInstance = getCurrentInstance()
146
+ const emit = defineEmits<{
147
+ 'update:x': [value: number]
148
+ 'update:y': [value: number]
149
+ input: [event: CustomEvent<{ readonly x: number; readonly y: number }>]
150
+ change: [event: CustomEvent<{ readonly x: number; readonly y: number }>]
151
+ }>()
152
+
153
+ const root = ref<HTMLElement | null>(null)
154
+ const planeElement = useTemplateRef<HTMLElement>('planeElement')
155
+ const sourceElement = useTemplateRef<HTMLElement>('sourceElement')
156
+ const horizontal = ref('50')
157
+ const vertical = ref('0')
158
+ let guardedPrevious: any = null
159
+ const guarded = computed(() => {
160
+ const candidate: any = concat(
161
+ checkedProps.value.label,
162
+ '. Arrow keys move the source; Shift moves faster.',
163
+ )
164
+ if (candidate === Symbol.for('html-next.invalid-result')) return guardedPrevious
165
+ return guardedPrevious = candidate
166
+ })
167
+ provide('html-next:ui-light-editor:horizontal', horizontal)
168
+ provide('html-next:ui-light-editor:vertical', vertical)
169
+ checkHydratedRoot('span', 'ui-light-editor')
170
+
171
+ const isInputDetail = (
172
+ detail: unknown,
173
+ ): boolean => (detail !== null && typeof detail === 'object' && !Array.isArray(detail)
174
+ && (typeof (detail as Record<string, unknown>)['x'] === 'number'
175
+ && Number.isFinite((detail as Record<string, unknown>)['x']))
176
+ && (typeof (detail as Record<string, unknown>)['y'] === 'number'
177
+ && Number.isFinite((detail as Record<string, unknown>)['y']))
178
+ && Object.keys(detail as object).every((key) => ['x', 'y'].includes(key)))
179
+ const dispatch = createDispatch(root, emit as (name: string, detail: unknown) => void, {
180
+ checks: {
181
+ input: isInputDetail,
182
+ change: isInputDetail,
183
+ },
184
+ modeled: ['x', 'y'],
185
+ })
186
+
187
+ useComponentHost(() => import('../components/ui-light-editor/ui-light-editor.js'), {
188
+ root,
189
+ module: true,
190
+ dispatch,
191
+ acceptsState: (name: string, keys: readonly string[], value: unknown) =>
192
+ acceptsControllerWrite(
193
+ value,
194
+ ({
195
+ horizontal: { kind: 'terminal', name: 'string' },
196
+ vertical: { kind: 'terminal', name: 'string' },
197
+ } as Record<string, any>)[name],
198
+ keys,
199
+ ),
200
+ initials: { horizontal: '50', vertical: '0' },
201
+ controllerSource: {
202
+ specifier: '../components/ui-light-editor/ui-light-editor.js',
203
+ definition: './components/ui-light-editor/ui-light-editor.html',
204
+ },
205
+ props: checkedProps,
206
+ inputs: propInputs,
207
+ inputTracking,
208
+ propInputs: (name: string) => {
209
+ const incoming = hydrationInstance?.vnode.props
210
+ const kebab = name.replace(/[A-Z]/g, (letter) => '-' + letter.toLowerCase())
211
+ return incoming !== null && incoming !== undefined
212
+ ? (incoming[name] ?? incoming[kebab] ?? null)
213
+ : null
214
+ },
215
+ propNames: ['disabled', 'label', 'size', 'x', 'y'],
216
+ propValidity: (name: string) =>
217
+ propValidityState({ contract: propValidityContract, values: { ...props } }, name),
218
+ refs: { plane: planeElement, source: sourceElement },
219
+ state: { horizontal, vertical },
220
+ })
221
+ </script>
222
+
223
+ <template>
224
+ <span
225
+ class="ui-light-editor"
226
+ v-bind="nativeAttrs($attrs)"
227
+ data-hn
228
+ data-hn-ui-light-editor
229
+ v-prop-validity="{ contract: propValidityContract, values: { ...props } }"
230
+ :data-ui-light-editor-prop-disabled="reflectedProp('disabled', 'disabled', checkedProps.disabled, undefined, false)"
231
+ :data-ui-light-editor-prop-label="reflectedProp('label', 'label', checkedProps.label, undefined, false)"
232
+ :data-ui-light-editor-prop-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
233
+ :data-ui-light-editor-prop-x="reflectedProp('x', 'x', checkedProps.x, undefined, false)"
234
+ :data-ui-light-editor-prop-y="reflectedProp('y', 'y', checkedProps.y, undefined, false)"
235
+ ref="root"
236
+ ><span
237
+ class="stage"
238
+ role="group"
239
+ data-hn-ui-light-editor
240
+ :aria-label="checkedProps.label ?? undefined"
241
+ ><span class="plane" data-hn-ui-light-editor ref="planeElement"><svg
242
+ viewBox="0 0 100 60"
243
+ preserveAspectRatio="none"
244
+ aria-hidden="true"
245
+ data-hn-ui-light-editor
246
+ >
247
+ <path d="M0 30 H100 M50 0 V60" data-hn-ui-light-editor></path>
248
+ </svg>{{ ' ' }}<span class="specimen" data-hn-ui-light-editor><slot /></span>{{
249
+ ' '
250
+ }}<button
251
+ type="button"
252
+ class="source"
253
+ data-hn-ui-light-editor
254
+ :disabled="checkedProps.disabled ?? undefined"
255
+ :aria-label="guarded"
256
+ ref="sourceElement"
257
+ >
258
+ </button></span></span>{{ ' ' }}<span
259
+ class="coordinates"
260
+ data-hn-ui-light-editor
261
+ ><UiNumberInput
262
+ class="ui-number-input"
263
+ data-coordinate="x"
264
+ :min="0"
265
+ :max="100"
266
+ :step="1"
267
+ unit="%"
268
+ label="Light horizontal position"
269
+ :value="horizontal"
270
+ :size="checkedProps.size"
271
+ :disabled="checkedProps.disabled"
272
+ v-bind="{
273
+ [BINDING_INPUTS_PROP]: {
274
+ size: () => ({ value: checkedProps.size, status: inputStatus('size', true) }),
275
+ disabled: () => ({ value: checkedProps.disabled, status: inputStatus('disabled', true) }),
276
+ },
277
+ }"
278
+ />{{ ' ' }}<UiNumberInput
279
+ class="ui-number-input"
280
+ data-coordinate="y"
281
+ :min="0"
282
+ :max="100"
283
+ :step="1"
284
+ unit="%"
285
+ label="Light vertical position"
286
+ :value="vertical"
287
+ :size="checkedProps.size"
288
+ :disabled="checkedProps.disabled"
289
+ v-bind="{
290
+ [BINDING_INPUTS_PROP]: {
291
+ size: () => ({ value: checkedProps.size, status: inputStatus('size', true) }),
292
+ disabled: () => ({ value: checkedProps.disabled, status: inputStatus('disabled', true) }),
293
+ },
294
+ }"
295
+ /></span>{{ ' ' }}<span class="hint" data-hn-ui-light-editor
296
+ >Drag the light, use arrow keys, or enter its position. Top centre is 50%, 0%.</span></span>
297
+ </template>
298
+
299
+ <style scoped>
300
+ @scope (.ui-light-editor) to ([data-hn]) {
301
+ :global(:scope:where([data-hn-ui-light-editor])) {
302
+ display: grid !important;
303
+ gap: var(--ui-space-3) !important;
304
+ min-inline-size: 0;
305
+ padding: 0 !important;
306
+ margin: 0 !important;
307
+ }
308
+ :global(.stage:where([data-hn-ui-light-editor])) {
309
+ box-sizing: border-box !important;
310
+ display: block !important;
311
+ block-size: 13rem;
312
+ padding: calc(var(--ui-control-min-block-size) / 2) !important;
313
+ border: var(--ui-border-width) solid var(--ui-control-border);
314
+ border-radius: var(--ui-field-radius, var(--ui-radius-md));
315
+ background: var(--ui-neutral-surface, var(--ui-surface));
316
+ }
317
+ :global(.plane:where([data-hn-ui-light-editor])) {
318
+ position: relative;
319
+ display: block !important;
320
+ inline-size: 100%;
321
+ block-size: 100%;
322
+ }
323
+ :global(svg:where([data-hn-ui-light-editor])) {
324
+ inline-size: 100%;
325
+ block-size: 100%;
326
+ overflow: visible;
327
+ }
328
+ :global(path:where([data-hn-ui-light-editor])) {
329
+ fill: none;
330
+ stroke: var(--ui-border);
331
+ stroke-width: 1;
332
+ vector-effect: non-scaling-stroke;
333
+ }
334
+ :global(.specimen:where([data-hn-ui-light-editor])) {
335
+ position: absolute;
336
+ inset: 0;
337
+ display: grid !important;
338
+ place-items: center !important;
339
+ }
340
+ :global(.source:where([data-hn-ui-light-editor])) {
341
+ position: absolute;
342
+ left: 50%;
343
+ top: 0;
344
+ translate: -50% -50%;
345
+ display: grid !important;
346
+ place-items: center !important;
347
+ inline-size: max(2rem, var(--ui-control-min-block-size));
348
+ block-size: max(2rem, var(--ui-control-min-block-size));
349
+ padding: 0 !important;
350
+ margin: 0 !important;
351
+ border: 0;
352
+ border-radius: 50%;
353
+ background: transparent;
354
+ cursor: grab;
355
+ touch-action: none;
356
+ }
357
+ :global(.source:where([data-hn-ui-light-editor])::after) {
358
+ content: "";
359
+ inline-size: 1rem;
360
+ block-size: 1rem;
361
+ border: var(--ui-border-width) solid var(--ui-accent);
362
+ border-radius: 50%;
363
+ background: var(--ui-surface-raised);
364
+ box-shadow:
365
+ 0 0 0 var(--ui-space-2) color-mix(in srgb, var(--ui-accent) 12%, transparent),
366
+ var(--ui-shadow-sm);
367
+ }
368
+ :global(.source:active:where([data-hn-ui-light-editor])) {
369
+ cursor: grabbing;
370
+ }
371
+ :global(.source:focus-visible:where([data-hn-ui-light-editor])) {
372
+ outline: var(--ui-focus-width) solid var(--ui-focus-ring);
373
+ outline-offset: var(--ui-space-1);
374
+ }
375
+ :global(.source:disabled:where([data-hn-ui-light-editor])) {
376
+ cursor: not-allowed;
377
+ }
378
+ :global(.source:disabled:where([data-hn-ui-light-editor])::after) {
379
+ background: var(--ui-disabled-surface);
380
+ border-color: var(--ui-disabled-border);
381
+ box-shadow: none;
382
+ }
383
+ :global(.coordinates:where([data-hn-ui-light-editor])) {
384
+ display: grid !important;
385
+ grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
386
+ gap: var(--ui-space-2) !important;
387
+ }
388
+ :global(.hint:where([data-hn-ui-light-editor])) {
389
+ font-size: var(--ui-font-size-sm);
390
+ color: var(--ui-text-secondary);
391
+ }
392
+ @media (forced-colors: active) {
393
+ :global(.source:where([data-hn-ui-light-editor])::after) {
394
+ background: Canvas;
395
+ border-color: CanvasText;
396
+ }
397
+ :global(.source:focus-visible:where([data-hn-ui-light-editor])) {
398
+ outline-color: Highlight;
399
+ }
400
+ }
401
+ }
402
+ </style>
package/vue/UiMenu.vue CHANGED
@@ -352,6 +352,9 @@ useComponentHost(() => import('../components/ui-menu/ui-menu.js'), {
352
352
 
353
353
  /* Small follows its trigger down: an item's own hooks still win. */
354
354
 
355
+ /* Purpose and measured size shape one shared separation lever. The content plane stays opaque;
356
+ transparency, saturation and edge light belong to the surrounding decorative material. */
357
+
355
358
  @scope (.ui-menu) to ([data-hn]) {
356
359
  :global(:scope[data-ui-menu-state~="density=compact"]:where([data-hn-ui-menu])) {
357
360
  --_ui-default-menu-item-padding-block: var(--ui-space-1);
@@ -378,6 +381,7 @@ useComponentHost(() => import('../components/ui-menu/ui-menu.js'), {
378
381
  }
379
382
 
380
383
  :global(:scope:where([data-hn-ui-menu])) {
384
+ --_ui-material-scale: 0.28;
381
385
  --_ui-menu-surface: var(--ui-menu-surface);
382
386
  --_ui-menu-border: var(--ui-menu-border);
383
387
  --_ui-menu-radius: var(--ui-menu-radius);
@@ -422,6 +426,93 @@ useComponentHost(() => import('../components/ui-menu/ui-menu.js'), {
422
426
  max-block-size: inherit;
423
427
  overflow: auto;
424
428
  }
429
+ :global(:scope:not([inline]) .surface:where([data-hn-ui-menu])) {
430
+ --_ui-material-glassiness: clamp(0, var(--ui-glassiness, 0), 1);
431
+ --_ui-material-separation: clamp(0, var(--ui-surface-separation, 0), 1);
432
+ --_ui-material-active: clamp(
433
+ 0,
434
+ calc((var(--_ui-material-glassiness) + var(--_ui-material-separation)) * 100000),
435
+ 1
436
+ );
437
+ --_ui-material-rim: calc(
438
+ (
439
+ var(--_ui-material-separation) + var(--_ui-material-glassiness) * 0.25
440
+ ) *
441
+ var(--_ui-material-scale, 0.28) *
442
+ 8px
443
+ );
444
+ --_ui-material-content-color: var(
445
+ --_ui-menu-surface,
446
+ var(--ui-material-content, var(--ui-overlay-surface, var(--ui-surface-elevated)))
447
+ );
448
+ --_ui-material-rim-color: color-mix(
449
+ in srgb,
450
+ var(--ui-material-glass, var(--ui-surface-elevated)) calc(var(--_ui-material-active) * 100%),
451
+ transparent
452
+ );
453
+ background:
454
+ var(--ui-surface-highlight, linear-gradient(transparent, transparent)) padding-box,
455
+ linear-gradient(var(--_ui-material-content-color), var(--_ui-material-content-color))
456
+ padding-box,
457
+ linear-gradient(var(--_ui-material-rim-color), var(--_ui-material-rim-color)) border-box,
458
+ var(--_ui-material-content-color) padding-box;
459
+ border-width: calc(var(--ui-border-width) + var(--_ui-material-rim));
460
+ border-color: var(
461
+ --_ui-menu-border,
462
+ color-mix(
463
+ in oklab,
464
+ var(--ui-overlay-border, var(--ui-border-strong)) calc(
465
+ (1 - var(--_ui-material-active)) * 100%
466
+ ),
467
+ transparent
468
+ )
469
+ );
470
+ box-shadow: var(
471
+ --_ui-menu-shadow,
472
+ var(
473
+ --ui-overlay-shadow,
474
+ 0 calc(var(--_ui-material-separation) * var(--_ui-material-scale, 0.28) * 8px) calc(
475
+ var(--_ui-material-separation) * var(--_ui-material-scale, 0.28) * 24px
476
+ ) color-mix(in oklab, var(--ui-text-primary) 15%, transparent),
477
+ var(--ui-material-glow, 0 0 transparent),
478
+ inset 0 0 0 calc(var(--_ui-material-active) * var(--ui-border-width)) var(
479
+ --ui-material-edge,
480
+ var(--ui-border-strong)
481
+ ),
482
+ var(--ui-elevation-overlay, var(--ui-shadow-lg))
483
+ )
484
+ );
485
+ backdrop-filter: blur(
486
+ calc(var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.28) * 18px)
487
+ ) saturate(calc(1 + var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.28) * 0.18));
488
+ -webkit-backdrop-filter: blur(
489
+ calc(var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.28) * 18px)
490
+ ) saturate(calc(1 + var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.28) * 0.18));
491
+ }
492
+
493
+ @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
494
+ :global(:scope:not([inline]) .surface:where([data-hn-ui-menu])) {
495
+ background: var(--_ui-material-content-color);
496
+ }
497
+ }
498
+
499
+ @media (prefers-reduced-transparency: reduce) {
500
+ :global(:scope:not([inline]) .surface:where([data-hn-ui-menu])) {
501
+ background: var(--_ui-material-content-color);
502
+ backdrop-filter: none;
503
+ -webkit-backdrop-filter: none;
504
+ }
505
+ }
506
+
507
+ @media (forced-colors: active) {
508
+ :global(:scope:not([inline]) .surface:where([data-hn-ui-menu])) {
509
+ background: Canvas;
510
+ border-color: CanvasText;
511
+ box-shadow: none;
512
+ backdrop-filter: none;
513
+ -webkit-backdrop-filter: none;
514
+ }
515
+ }
425
516
 
426
517
  :global(.surface hr:where([data-hn-ui-menu])) {
427
518
  align-self: stretch;
@@ -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<string | null>;
30
+ };
31
+ "\0htmlNextInputStatus": {
32
+ type: PropType<InputBindings>;
33
+ };
34
+ }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
35
+ input: (event: CustomEvent<{
36
+ readonly value: string;
37
+ }>) => any;
38
+ change: (event: CustomEvent<{
39
+ readonly value: string;
40
+ }>) => any;
41
+ "update:value": (value: string) => 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<string | null>;
69
+ };
70
+ "\0htmlNextInputStatus": {
71
+ type: PropType<InputBindings>;
72
+ };
73
+ }>> & Readonly<{
74
+ onInput?: ((event: CustomEvent<{
75
+ readonly value: string;
76
+ }>) => any) | undefined;
77
+ onChange?: ((event: CustomEvent<{
78
+ readonly value: string;
79
+ }>) => any) | undefined;
80
+ "onUpdate:value"?: ((value: string) => 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 UiNumberInput_default } from "./chunks/UiNumberInput.js";
2
+ export { UiNumberInput_default as default };