@threadlabs/looma 0.34.0 → 0.35.1
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.
- package/components/ui-badge/ui-badge.html +11 -3
- package/components/ui-button/ui-button.html +29 -4
- package/components/ui-card/ui-card.html +15 -13
- package/components/ui-checkbox/ui-checkbox.html +4 -2
- package/components/ui-dialog/ui-dialog.html +2 -0
- package/components/ui-icon-button/ui-icon-button.html +22 -8
- package/components/ui-input/ui-input.html +2 -1
- package/components/ui-input-group/ui-input-group.html +4 -1
- package/components/ui-light-editor/ui-light-editor.html +45 -0
- package/components/ui-light-editor/ui-light-editor.js +53 -0
- package/components/ui-menu/ui-menu.html +2 -0
- package/components/ui-number-input/ui-number-input.html +2 -1
- package/components/ui-number-input/ui-number-input.js +6 -3
- package/components/ui-popover/ui-popover.html +2 -0
- package/components/ui-reel/ui-reel.html +2 -1
- package/components/ui-select/ui-select.html +9 -7
- package/components/ui-switch/ui-switch.html +3 -0
- package/components/ui-tabs/ui-tabs.html +2 -3
- package/components/ui-tabs/ui-tabs.js +0 -9
- package/components/ui-textarea/ui-textarea.html +2 -1
- package/components/ui-tooltip/ui-tooltip.html +2 -1
- package/dist/index.js +24 -23
- package/docs/README.md +29 -3
- package/docs/card.html +7 -6
- package/docs/catalog-view.mjs +2 -1
- package/docs/catalog.json +575 -53
- package/docs/customizer-render.mjs +31 -16
- package/docs/customizer.js +72 -19
- package/docs/index.d.ts +4 -1
- package/docs/index.mjs +1 -1
- package/docs/render.mjs +1 -1
- package/docs/site.mjs +33 -22
- package/docs/theme-session.mjs +4 -2
- package/docs/theme.mjs +61 -7
- package/package.json +2 -2
- package/styles/ui-badge.css +11 -6
- package/styles/ui-button.css +29 -4
- package/styles/ui-card.css +9 -9
- package/styles/ui-checkbox.css +4 -2
- package/styles/ui-dialog.css +4 -0
- package/styles/ui-icon-button.css +22 -8
- package/styles/ui-input-group.css +4 -1
- package/styles/ui-input.css +2 -1
- package/styles/ui-light-editor.css +28 -0
- package/styles/ui-menu.css +2 -0
- package/styles/ui-popover.css +2 -0
- package/styles/ui-select.css +9 -7
- package/styles/ui-switch.css +3 -0
- package/styles/ui-tabs.css +2 -3
- package/styles/ui-textarea.css +2 -1
- package/styles/ui-tooltip.css +2 -1
- package/theme-light.css +1 -0
- package/theme-system.css +43 -7
- package/tokens.css +5 -1
- package/vanilla/UiCard.d.ts +2 -1
- package/vanilla/UiCard.js +12 -12
- package/vanilla/UiLightEditor.d.ts +29 -0
- package/vanilla/UiLightEditor.js +102 -0
- package/vanilla/UiNumberInput.js +27 -20
- package/vanilla/index.js +1 -0
- package/vue/UiBadge.vue +29 -4
- package/vue/UiButton.vue +33 -4
- package/vue/UiCard.d.ts +8 -2
- package/vue/UiCard.vue +41 -17
- package/vue/UiCheckbox.vue +4 -2
- package/vue/UiDialog.vue +4 -0
- package/vue/UiIconButton.vue +26 -11
- package/vue/UiInput.vue +2 -1
- package/vue/UiInputGroup.vue +4 -1
- package/vue/UiLightEditor.d.ts +75 -0
- package/vue/UiLightEditor.js +2 -0
- package/vue/UiLightEditor.vue +402 -0
- package/vue/UiMenu.vue +2 -0
- package/vue/UiNumberInput.vue +32 -3
- package/vue/UiPopover.vue +2 -0
- package/vue/UiReel.vue +1 -1
- package/vue/UiSelect.vue +16 -10
- package/vue/UiSwitch.vue +3 -0
- package/vue/UiTabs.vue +2 -3
- package/vue/UiTextarea.vue +2 -1
- package/vue/UiTooltip.vue +2 -1
- package/vue/chunks/UiBadge.js +1 -1
- package/vue/chunks/UiButton.js +1 -1
- package/vue/chunks/UiCard.js +33 -5
- package/vue/chunks/UiCheckbox.js +1 -1
- package/vue/chunks/UiDialog.js +1 -1
- package/vue/chunks/UiIconButton.js +1 -1
- package/vue/chunks/UiInput.js +1 -1
- package/vue/chunks/UiInputGroup.js +1 -1
- package/vue/chunks/UiLightEditor.js +347 -0
- package/vue/chunks/UiMenu.js +1 -1
- package/vue/chunks/UiNumberInput.js +21 -8
- package/vue/chunks/UiPopover.js +1 -1
- package/vue/chunks/UiReel.js +2 -2
- package/vue/chunks/UiSelect.js +1 -1
- package/vue/chunks/UiSwitch.js +1 -1
- package/vue/chunks/UiTabs.js +1 -1
- package/vue/chunks/UiTextarea.js +1 -1
- package/vue/chunks/UiTooltip.js +1 -1
- package/vue/components.css +312 -71
- package/vue/index.d.ts +1 -0
- package/vue/index.js +2 -1
|
@@ -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
|
@@ -451,6 +451,7 @@ useComponentHost(() => import('../components/ui-menu/ui-menu.js'), {
|
|
|
451
451
|
transparent
|
|
452
452
|
);
|
|
453
453
|
background:
|
|
454
|
+
var(--ui-surface-highlight, linear-gradient(transparent, transparent)) padding-box,
|
|
454
455
|
linear-gradient(var(--_ui-material-content-color), var(--_ui-material-content-color))
|
|
455
456
|
padding-box,
|
|
456
457
|
linear-gradient(var(--_ui-material-rim-color), var(--_ui-material-rim-color)) border-box,
|
|
@@ -473,6 +474,7 @@ useComponentHost(() => import('../components/ui-menu/ui-menu.js'), {
|
|
|
473
474
|
0 calc(var(--_ui-material-separation) * var(--_ui-material-scale, 0.28) * 8px) calc(
|
|
474
475
|
var(--_ui-material-separation) * var(--_ui-material-scale, 0.28) * 24px
|
|
475
476
|
) color-mix(in oklab, var(--ui-text-primary) 15%, transparent),
|
|
477
|
+
var(--ui-material-glow, 0 0 transparent),
|
|
476
478
|
inset 0 0 0 calc(var(--_ui-material-active) * var(--ui-border-width)) var(
|
|
477
479
|
--ui-material-edge,
|
|
478
480
|
var(--ui-border-strong)
|
package/vue/UiNumberInput.vue
CHANGED
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
<!-- Generated by HTML Next 1.0.0-alpha.69 for Vue 3.5. Do not edit. -->
|
|
2
2
|
<script setup lang="ts">
|
|
3
|
-
import { computed, getCurrentInstance, ref, watchSyncEffect } from 'vue'
|
|
3
|
+
import { computed, getCurrentInstance, provide, ref, watchSyncEffect } from 'vue'
|
|
4
4
|
import type { PropType } from 'vue'
|
|
5
5
|
import {
|
|
6
6
|
checkHydratedRoot,
|
|
7
7
|
concat,
|
|
8
8
|
createDispatch,
|
|
9
|
+
initializedState,
|
|
9
10
|
nativeAttrs,
|
|
10
11
|
useComponentHost,
|
|
11
12
|
useReflectedProp,
|
|
13
|
+
warnUnless,
|
|
12
14
|
} from './host'
|
|
15
|
+
import { acceptsControllerWrite } from './props'
|
|
13
16
|
import {
|
|
14
17
|
BINDING_INPUTS_PROP,
|
|
15
18
|
checkedProp,
|
|
16
19
|
checkPropInput,
|
|
20
|
+
copyStateSeed,
|
|
17
21
|
evaluateInput,
|
|
18
22
|
type InputBindings,
|
|
19
23
|
inputDefault,
|
|
@@ -224,6 +228,23 @@ const emit = defineEmits<{
|
|
|
224
228
|
}>()
|
|
225
229
|
|
|
226
230
|
const root = ref<HTMLElement | null>(null)
|
|
231
|
+
const display = initializedState<string>(
|
|
232
|
+
() =>
|
|
233
|
+
evaluateInput(() => {
|
|
234
|
+
return inputRead(checkedProps.value.value, propInputs.status('value'))
|
|
235
|
+
}),
|
|
236
|
+
(next: unknown) => typeof next === 'string',
|
|
237
|
+
copyStateSeed,
|
|
238
|
+
() =>
|
|
239
|
+
warnUnless(false, 'initializer:display', 'State `display` does not satisfy its declared type.'),
|
|
240
|
+
)
|
|
241
|
+
provide('html-next:ui-number-input:display', display)
|
|
242
|
+
const declarationStatuses = { display: () => display.status() } as Record<
|
|
243
|
+
string,
|
|
244
|
+
() => typeof READY_INPUT
|
|
245
|
+
>
|
|
246
|
+
const declarationStatus = (name: string) => declarationStatuses[name]!()
|
|
247
|
+
display.start()
|
|
227
248
|
checkHydratedRoot('span', 'ui-number-input')
|
|
228
249
|
|
|
229
250
|
const isInputDetail = (
|
|
@@ -243,6 +264,12 @@ useComponentHost(() => import('../components/ui-number-input/ui-number-input.js'
|
|
|
243
264
|
root,
|
|
244
265
|
module: true,
|
|
245
266
|
dispatch,
|
|
267
|
+
acceptsState: (name: string, keys: readonly string[], value: unknown) =>
|
|
268
|
+
acceptsControllerWrite(
|
|
269
|
+
value,
|
|
270
|
+
({ display: { kind: 'terminal', name: 'string' } } as Record<string, any>)[name],
|
|
271
|
+
keys,
|
|
272
|
+
),
|
|
246
273
|
controllerSource: {
|
|
247
274
|
specifier: '../components/ui-number-input/ui-number-input.js',
|
|
248
275
|
definition: './components/ui-number-input/ui-number-input.html',
|
|
@@ -260,6 +287,8 @@ useComponentHost(() => import('../components/ui-number-input/ui-number-input.js'
|
|
|
260
287
|
propNames: ['disabled', 'label', 'max', 'min', 'name', 'size', 'step', 'unit', 'value'],
|
|
261
288
|
propValidity: (name: string) =>
|
|
262
289
|
propValidityState({ contract: propValidityContract, values: { ...props } }, name),
|
|
290
|
+
state: { display },
|
|
291
|
+
availability: { display: () => declarationStatus('display') },
|
|
263
292
|
})
|
|
264
293
|
</script>
|
|
265
294
|
|
|
@@ -307,14 +336,14 @@ useComponentHost(() => import('../components/ui-number-input/ui-number-input.js'
|
|
|
307
336
|
aria-description="Enter calculates arithmetic. Arrow keys step; Shift changes ten steps."
|
|
308
337
|
:size="checkedProps.size"
|
|
309
338
|
:disabled="checkedProps.disabled"
|
|
310
|
-
:value="
|
|
339
|
+
:value="display"
|
|
311
340
|
:aria-label="checkedProps.label"
|
|
312
341
|
:name="checkedProps.name"
|
|
313
342
|
v-bind="{
|
|
314
343
|
[BINDING_INPUTS_PROP]: {
|
|
315
344
|
size: () => ({ value: checkedProps.size, status: inputStatus('size', true) }),
|
|
316
345
|
disabled: () => ({ value: checkedProps.disabled, status: inputStatus('disabled', true) }),
|
|
317
|
-
value: () => ({ value:
|
|
346
|
+
value: () => ({ value: display, status: declarationStatus('display') }),
|
|
318
347
|
},
|
|
319
348
|
}"
|
|
320
349
|
/>{{ ' ' }}<template
|
package/vue/UiPopover.vue
CHANGED
|
@@ -402,6 +402,7 @@ useComponentHost(() => import('../components/ui-popover/ui-popover.js'), {
|
|
|
402
402
|
transparent
|
|
403
403
|
);
|
|
404
404
|
background:
|
|
405
|
+
var(--ui-surface-highlight, linear-gradient(transparent, transparent)) padding-box,
|
|
405
406
|
linear-gradient(var(--_ui-material-content-color), var(--_ui-material-content-color))
|
|
406
407
|
padding-box,
|
|
407
408
|
linear-gradient(var(--_ui-material-rim-color), var(--_ui-material-rim-color)) border-box,
|
|
@@ -424,6 +425,7 @@ useComponentHost(() => import('../components/ui-popover/ui-popover.js'), {
|
|
|
424
425
|
0 calc(var(--_ui-material-separation) * var(--_ui-material-scale, 0.55) * 8px) calc(
|
|
425
426
|
var(--_ui-material-separation) * var(--_ui-material-scale, 0.55) * 24px
|
|
426
427
|
) color-mix(in oklab, var(--ui-text-primary) 15%, transparent),
|
|
428
|
+
var(--ui-material-glow, 0 0 transparent),
|
|
427
429
|
inset 0 0 0 calc(var(--_ui-material-active) * var(--ui-border-width)) var(
|
|
428
430
|
--ui-material-edge,
|
|
429
431
|
var(--ui-border-strong)
|
package/vue/UiReel.vue
CHANGED
|
@@ -40,7 +40,7 @@ const propValidityContract = {
|
|
|
40
40
|
required: false,
|
|
41
41
|
target: { attribute: 'snap' },
|
|
42
42
|
description:
|
|
43
|
-
'Snaps scrolling to items: start comes to rest with an item\'s start edge at the reel\'s start, and center with an item centred in the reel. Unset, the reel\n scrolls freely.',
|
|
43
|
+
'Snaps scrolling to items: start comes to rest with an item\'s start edge at the reel\'s start, and center with an item centred in the reel. Unset, the reel\n scrolls freely. Wrap a component item in a plain element when snapping: the wrapper receives snap alignment while the component keeps ownership of its\n root styles.',
|
|
44
44
|
values: ['start', 'center'],
|
|
45
45
|
},
|
|
46
46
|
},
|
package/vue/UiSelect.vue
CHANGED
|
@@ -296,7 +296,7 @@ useComponentHost(() => import('../components/ui-select/ui-select.js'), {
|
|
|
296
296
|
var(--ui-control-surface, var(--ui-surface-elevated))
|
|
297
297
|
);
|
|
298
298
|
color: var(--ui-text-primary);
|
|
299
|
-
color-scheme:
|
|
299
|
+
color-scheme: inherit;
|
|
300
300
|
font: inherit;
|
|
301
301
|
line-height: var(--ui-line-height-tight);
|
|
302
302
|
box-shadow: var(--ui-select-shadow, var(--ui-shadow-sm));
|
|
@@ -306,15 +306,18 @@ useComponentHost(() => import('../components/ui-select/ui-select.js'), {
|
|
|
306
306
|
background-color var(--ui-motion-fast) var(--ui-motion-ease);
|
|
307
307
|
}
|
|
308
308
|
:global(:scope:where([data-hn-ui-select])) {
|
|
309
|
+
--_ui-select-highlight: var(--ui-surface-highlight, linear-gradient(transparent, transparent));
|
|
309
310
|
appearance: none;
|
|
310
311
|
padding-inline-end: calc(var(--ui-space-3) + 1.5rem) !important;
|
|
311
|
-
background-image:
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
312
|
+
background-image:
|
|
313
|
+
var(
|
|
314
|
+
--ui-select-chevron,
|
|
315
|
+
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235c5c58' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E")
|
|
316
|
+
),
|
|
317
|
+
var(--_ui-select-highlight);
|
|
315
318
|
background-repeat: no-repeat;
|
|
316
|
-
background-position: right var(--ui-space-3) center;
|
|
317
|
-
background-size: 1.125rem 1.125rem
|
|
319
|
+
background-position: right var(--ui-space-3) center, center;
|
|
320
|
+
background-size: 1.125rem 1.125rem, 100% 100%;
|
|
318
321
|
}
|
|
319
322
|
|
|
320
323
|
:global(:scope:hover:not(:focus):not(:disabled):not([aria-invalid="true"]):not(:is(:user-invalid, [data-user-invalid])):where([data-hn-ui-select])) {
|
|
@@ -351,6 +354,7 @@ useComponentHost(() => import('../components/ui-select/ui-select.js'), {
|
|
|
351
354
|
}
|
|
352
355
|
|
|
353
356
|
:global(:scope:disabled:where([data-hn-ui-select])) {
|
|
357
|
+
--_ui-select-highlight: none;
|
|
354
358
|
background-color: var(--ui-control-surface-disabled, var(--ui-surface-muted));
|
|
355
359
|
color: var(--ui-disabled-text);
|
|
356
360
|
box-shadow: none;
|
|
@@ -362,8 +366,10 @@ useComponentHost(() => import('../components/ui-select/ui-select.js'), {
|
|
|
362
366
|
padding: var(--ui-control-inset-block-sm, var(--ui-space-1)) var(--ui-space-2) !important;
|
|
363
367
|
padding-inline-end: calc(var(--ui-space-2) + var(--ui-icon-size-sm) + var(--ui-space-1))
|
|
364
368
|
!important;
|
|
365
|
-
background-position: right var(--ui-space-2) center;
|
|
366
|
-
background-size:
|
|
369
|
+
background-position: right var(--ui-space-2) center, center;
|
|
370
|
+
background-size:
|
|
371
|
+
var(--ui-icon-size-sm) var(--ui-icon-size-sm),
|
|
372
|
+
100% 100%;
|
|
367
373
|
font-size: var(--ui-font-size-sm);
|
|
368
374
|
}
|
|
369
375
|
|
|
@@ -371,7 +377,7 @@ useComponentHost(() => import('../components/ui-select/ui-select.js'), {
|
|
|
371
377
|
min-block-size: var(--ui-control-size-lg);
|
|
372
378
|
padding: var(--ui-control-inset-block-lg, var(--ui-space-3)) var(--ui-space-4) !important;
|
|
373
379
|
padding-inline-end: calc(var(--ui-space-4) + 1.5rem) !important;
|
|
374
|
-
background-position: right var(--ui-space-4) center;
|
|
380
|
+
background-position: right var(--ui-space-4) center, center;
|
|
375
381
|
font-size: var(--ui-font-size-md);
|
|
376
382
|
}
|
|
377
383
|
@media (pointer: coarse) {
|
package/vue/UiSwitch.vue
CHANGED
|
@@ -375,6 +375,7 @@ useComponentHost(() => import('../components/ui-switch/ui-switch.js'), {
|
|
|
375
375
|
border: var(--ui-border-width) solid var(--ui-control-border, var(--ui-border-strong));
|
|
376
376
|
border-radius: var(--ui-radius-round);
|
|
377
377
|
background-color: var(--ui-control-surface, var(--ui-surface-default));
|
|
378
|
+
background-image: var(--ui-surface-highlight, none);
|
|
378
379
|
box-shadow: var(--ui-control-inset);
|
|
379
380
|
cursor: pointer;
|
|
380
381
|
transition:
|
|
@@ -400,6 +401,7 @@ useComponentHost(() => import('../components/ui-switch/ui-switch.js'), {
|
|
|
400
401
|
|
|
401
402
|
:global(input:checked:where([data-hn-ui-switch])) {
|
|
402
403
|
background-color: var(--ui-accent-solid);
|
|
404
|
+
background-image: var(--ui-accent-highlight, none);
|
|
403
405
|
border-color: var(--ui-accent-solid);
|
|
404
406
|
}
|
|
405
407
|
|
|
@@ -423,6 +425,7 @@ useComponentHost(() => import('../components/ui-switch/ui-switch.js'), {
|
|
|
423
425
|
:global(:scope[data-ui-switch-state~="disabled"] input:where([data-hn-ui-switch])) {
|
|
424
426
|
border-color: var(--ui-disabled-border);
|
|
425
427
|
background-color: var(--ui-disabled-surface);
|
|
428
|
+
background-image: none;
|
|
426
429
|
box-shadow: none;
|
|
427
430
|
cursor: not-allowed;
|
|
428
431
|
}
|
package/vue/UiTabs.vue
CHANGED
|
@@ -395,10 +395,9 @@ useComponentHost(() => import('../components/ui-tabs/ui-tabs.js'), {
|
|
|
395
395
|
max-inline-size: 100%;
|
|
396
396
|
/* Tabs that do not fit scroll sideways rather than wrapping or squeezing. */
|
|
397
397
|
overflow-x: auto;
|
|
398
|
-
/*
|
|
399
|
-
strip or the page vertically. */
|
|
398
|
+
/* Contain sideways overscroll without trapping vertical page scrolling. */
|
|
400
399
|
overflow-y: hidden;
|
|
401
|
-
overscroll-behavior: contain;
|
|
400
|
+
overscroll-behavior-inline: contain;
|
|
402
401
|
scrollbar-width: thin;
|
|
403
402
|
border-block-end: var(--ui-border-width) solid var(--ui-border-divider);
|
|
404
403
|
}
|
package/vue/UiTextarea.vue
CHANGED
|
@@ -393,10 +393,11 @@ useComponentHost(() => import('../components/ui-textarea/ui-textarea.js'), {
|
|
|
393
393
|
--ui-textarea-radius,
|
|
394
394
|
var(--_ui-default-textarea-radius, var(--ui-field-radius, var(--ui-radius-md)))
|
|
395
395
|
);
|
|
396
|
-
background: var(
|
|
396
|
+
background-color: var(
|
|
397
397
|
--ui-textarea-surface,
|
|
398
398
|
var(--_ui-default-textarea-surface, var(--ui-control-surface, var(--ui-surface-elevated)))
|
|
399
399
|
);
|
|
400
|
+
background-image: var(--_ui-default-textarea-highlight, var(--ui-surface-highlight, none));
|
|
400
401
|
color: var(--ui-text-primary);
|
|
401
402
|
font: inherit;
|
|
402
403
|
line-height: var(--ui-line-height-md);
|
package/vue/UiTooltip.vue
CHANGED
|
@@ -580,7 +580,8 @@ useComponentHost(() => import('../components/ui-tooltip/ui-tooltip.js'), {
|
|
|
580
580
|
border-inline-end-width: var(--ui-border-width);
|
|
581
581
|
border-block-end-width: var(--ui-border-width);
|
|
582
582
|
border-end-end-radius: var(--ui-border-width);
|
|
583
|
-
|
|
583
|
+
/* Stretch in screen axes after rotation so both arrow shoulders stay level. */
|
|
584
|
+
transform: scale(1.25, 0.85) rotate(45deg);
|
|
584
585
|
}
|
|
585
586
|
|
|
586
587
|
:global(:scope[data-ui-actual-placement="bottom"] .surface:where([data-hn-ui-tooltip])::after) {
|
package/vue/chunks/UiBadge.js
CHANGED
package/vue/chunks/UiButton.js
CHANGED