@threadlabs/looma 0.37.0 → 0.37.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/shared/icons.js +3 -0
- package/components/ui-button/ui-button.html +3 -12
- package/components/ui-card/ui-card.html +5 -5
- package/components/ui-checkbox/ui-checkbox.html +1 -7
- package/components/ui-color-picker/ui-color-picker.html +0 -9
- package/components/ui-combobox/ui-combobox.html +2 -14
- package/components/ui-cycle-button/ui-cycle-button.html +41 -0
- package/components/ui-cycle-button/ui-cycle-button.js +19 -0
- package/components/ui-dialog/ui-dialog.html +1 -1
- package/components/ui-icon/ui-icon.html +3 -0
- package/components/ui-icon-button/ui-icon-button.html +10 -14
- package/components/ui-input/ui-input.html +4 -19
- package/components/ui-input-group/ui-input-group.html +0 -10
- package/components/ui-menu/ui-menu.html +1 -1
- package/components/ui-popover/ui-popover.html +1 -1
- package/components/ui-radio/ui-radio.html +1 -7
- package/components/ui-select/ui-select.html +4 -10
- package/components/ui-switch/ui-switch.html +1 -7
- package/components/ui-tooltip/ui-tooltip.html +1 -1
- package/dist/index.js +47 -46
- package/docs/README.md +48 -7
- package/docs/card.html +2 -1
- package/docs/catalog.json +224 -49
- package/docs/customizer-render.mjs +7 -6
- package/docs/customizer.js +13 -19
- package/docs/theme.mjs +3 -3
- package/editor/icons.d.ts +3 -0
- package/editor/index.js +4 -1
- package/package.json +2 -2
- package/styles/ui-button.css +2 -14
- package/styles/ui-card.css +1 -1
- package/styles/ui-checkbox.css +0 -9
- package/styles/ui-color-picker.css +0 -13
- package/styles/ui-combobox.css +2 -28
- package/styles/ui-cycle-button.css +36 -0
- package/styles/ui-dialog.css +2 -2
- package/styles/ui-icon-button.css +6 -13
- package/styles/ui-input-group.css +0 -13
- package/styles/ui-input.css +2 -18
- package/styles/ui-menu.css +1 -1
- package/styles/ui-popover.css +1 -1
- package/styles/ui-radio.css +0 -9
- package/styles/ui-select.css +3 -10
- package/styles/ui-switch.css +0 -9
- package/styles/ui-tooltip.css +1 -1
- package/theme-system.css +14 -14
- package/tokens.css +2 -10
- package/vanilla/UiCycleButton.d.ts +29 -0
- package/vanilla/UiCycleButton.js +85 -0
- package/vanilla/UiIcon.js +1 -1
- package/vanilla/index.js +1 -0
- package/vue/UiButton.vue +2 -11
- package/vue/UiCard.vue +5 -3
- package/vue/UiCheckbox.vue +1 -7
- package/vue/UiColorPicker.vue +0 -9
- package/vue/UiCombobox.vue +3 -27
- package/vue/UiCycleButton.d.ts +69 -0
- package/vue/UiCycleButton.js +2 -0
- package/vue/UiCycleButton.vue +403 -0
- package/vue/UiDialog.vue +6 -2
- package/vue/UiIcon.vue +22 -0
- package/vue/UiIconButton.vue +2 -16
- package/vue/UiInput.vue +2 -23
- package/vue/UiInputGroup.vue +0 -10
- package/vue/UiMenu.vue +3 -1
- package/vue/UiPopover.vue +3 -1
- package/vue/UiRadio.vue +1 -7
- package/vue/UiSelect.vue +3 -9
- package/vue/UiSwitch.vue +1 -7
- package/vue/UiTooltip.vue +3 -1
- package/vue/chunks/UiAffordanceScope.js +1 -1
- package/vue/chunks/UiAvatar.js +1 -1
- package/vue/chunks/UiAvatarGroup.js +1 -1
- package/vue/chunks/UiBadge.js +1 -1
- package/vue/chunks/UiBreadcrumbItem.js +1 -1
- package/vue/chunks/UiBreadcrumbs.js +1 -1
- package/vue/chunks/UiButton.js +3 -3
- package/vue/chunks/UiCallout.js +1 -1
- package/vue/chunks/UiCard.js +4 -4
- package/vue/chunks/UiCheckbox.js +3 -3
- package/vue/chunks/UiCluster.js +1 -1
- package/vue/chunks/UiColorPicker.js +2 -2
- package/vue/chunks/UiCombobox.js +3 -3
- package/vue/chunks/UiContainer.js +1 -1
- package/vue/chunks/UiContextMenu.js +1 -1
- package/vue/chunks/UiCover.js +1 -1
- package/vue/chunks/UiCurveEditor.js +1 -1
- package/vue/chunks/UiCycleButton.js +352 -0
- package/vue/chunks/UiDescriptionItem.js +1 -1
- package/vue/chunks/UiDescriptionList.js +1 -1
- package/vue/chunks/UiDialog.js +2 -2
- package/vue/chunks/UiDisclosure.js +1 -1
- package/vue/chunks/UiEditable.js +1 -1
- package/vue/chunks/UiEditorBlockActions.js +1 -1
- package/vue/chunks/UiEditorChipEditor.js +1 -1
- package/vue/chunks/UiEditorCodeLanguage.js +1 -1
- package/vue/chunks/UiEditorFootnoteEditor.js +1 -1
- package/vue/chunks/UiEditorImageToolbar.js +1 -1
- package/vue/chunks/UiEditorInsertTableGrid.js +1 -1
- package/vue/chunks/UiEditorLinkCard.js +1 -1
- package/vue/chunks/UiEditorLinkForm.js +1 -1
- package/vue/chunks/UiEditorMentionMenu.js +1 -1
- package/vue/chunks/UiEditorMentionMenuItem.js +1 -1
- package/vue/chunks/UiEditorSlashMenu.js +1 -1
- package/vue/chunks/UiEditorSlashMenuGroup.js +1 -1
- package/vue/chunks/UiEditorSlashMenuItem.js +1 -1
- package/vue/chunks/UiEditorSurface.js +1 -1
- package/vue/chunks/UiEditorTableContextMenu.js +1 -1
- package/vue/chunks/UiEditorTableOverlay.js +1 -1
- package/vue/chunks/UiEditorTableToolbar.js +1 -1
- package/vue/chunks/UiEditorToolbar.js +1 -1
- package/vue/chunks/UiFloatingActionButton.js +1 -1
- package/vue/chunks/UiFormField.js +1 -1
- package/vue/chunks/UiGrid.js +1 -1
- package/vue/chunks/UiIcon.js +70 -2
- package/vue/chunks/UiIconButton.js +4 -4
- package/vue/chunks/UiImage.js +1 -1
- package/vue/chunks/UiInput.js +3 -3
- package/vue/chunks/UiInputGroup.js +2 -2
- package/vue/chunks/UiLightEditor.js +1 -1
- package/vue/chunks/UiList.js +1 -1
- package/vue/chunks/UiListItem.js +1 -1
- package/vue/chunks/UiListbox.js +1 -1
- package/vue/chunks/UiMenu.js +2 -2
- package/vue/chunks/UiMenuGroup.js +1 -1
- package/vue/chunks/UiMenuItem.js +1 -1
- package/vue/chunks/UiMeter.js +1 -1
- package/vue/chunks/UiNavItem.js +1 -1
- package/vue/chunks/UiNumberInput.js +1 -1
- package/vue/chunks/UiPageHeader.js +1 -1
- package/vue/chunks/UiPopover.js +2 -2
- package/vue/chunks/UiRadio.js +3 -3
- package/vue/chunks/UiRadioGroup.js +1 -1
- package/vue/chunks/UiReel.js +1 -1
- package/vue/chunks/UiScrollArea.js +1 -1
- package/vue/chunks/UiSearchResultRow.js +1 -1
- package/vue/chunks/UiSearchShell.js +1 -1
- package/vue/chunks/UiSection.js +1 -1
- package/vue/chunks/UiSelect.js +3 -3
- package/vue/chunks/UiSeparator.js +1 -1
- package/vue/chunks/UiSidebar.js +1 -1
- package/vue/chunks/UiSlider.js +1 -1
- package/vue/chunks/UiSpinner.js +1 -1
- package/vue/chunks/UiStack.js +1 -1
- package/vue/chunks/UiStatusMessage.js +1 -1
- package/vue/chunks/UiSwatch.js +1 -1
- package/vue/chunks/UiSwitch.js +3 -3
- package/vue/chunks/UiSwitcher.js +1 -1
- package/vue/chunks/UiTable.js +1 -1
- package/vue/chunks/UiTabs.js +1 -1
- package/vue/chunks/UiText.js +1 -1
- package/vue/chunks/UiTextarea.js +1 -1
- package/vue/chunks/UiToast.js +1 -1
- package/vue/chunks/UiToastRegion.js +1 -1
- package/vue/chunks/UiTooltip.js +2 -2
- package/vue/chunks/UiTree.js +1 -1
- package/vue/chunks/UiTreeItem.js +1 -1
- package/vue/chunks/props.js +12 -1
- package/vue/components.css +74 -179
- package/vue/editor/index.js +68 -0
- package/vue/index.d.ts +1 -0
- package/vue/index.js +2 -1
|
@@ -0,0 +1,69 @@
|
|
|
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
|
+
index: {
|
|
8
|
+
type: PropType<number | null>;
|
|
9
|
+
};
|
|
10
|
+
items: {
|
|
11
|
+
type: PropType<readonly ({
|
|
12
|
+
readonly value: string;
|
|
13
|
+
readonly label: string;
|
|
14
|
+
readonly icon: string;
|
|
15
|
+
})[]>;
|
|
16
|
+
};
|
|
17
|
+
label: {
|
|
18
|
+
type: PropType<string | null>;
|
|
19
|
+
};
|
|
20
|
+
size: {
|
|
21
|
+
type: PropType<"sm" | "md" | "lg" | null>;
|
|
22
|
+
};
|
|
23
|
+
variant: {
|
|
24
|
+
type: PropType<"ghost" | "outline" | "solid" | null>;
|
|
25
|
+
};
|
|
26
|
+
"\0htmlNextInputStatus": {
|
|
27
|
+
type: PropType<InputBindings>;
|
|
28
|
+
};
|
|
29
|
+
}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
30
|
+
change: (event: CustomEvent<{
|
|
31
|
+
readonly value: string;
|
|
32
|
+
readonly index: number;
|
|
33
|
+
}>) => any;
|
|
34
|
+
"update:index": (value: number) => any;
|
|
35
|
+
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
36
|
+
disabled: {
|
|
37
|
+
type: PropType<boolean | null>;
|
|
38
|
+
};
|
|
39
|
+
index: {
|
|
40
|
+
type: PropType<number | null>;
|
|
41
|
+
};
|
|
42
|
+
items: {
|
|
43
|
+
type: PropType<readonly ({
|
|
44
|
+
readonly value: string;
|
|
45
|
+
readonly label: string;
|
|
46
|
+
readonly icon: string;
|
|
47
|
+
})[]>;
|
|
48
|
+
};
|
|
49
|
+
label: {
|
|
50
|
+
type: PropType<string | null>;
|
|
51
|
+
};
|
|
52
|
+
size: {
|
|
53
|
+
type: PropType<"sm" | "md" | "lg" | null>;
|
|
54
|
+
};
|
|
55
|
+
variant: {
|
|
56
|
+
type: PropType<"ghost" | "outline" | "solid" | null>;
|
|
57
|
+
};
|
|
58
|
+
"\0htmlNextInputStatus": {
|
|
59
|
+
type: PropType<InputBindings>;
|
|
60
|
+
};
|
|
61
|
+
}>> & Readonly<{
|
|
62
|
+
onChange?: ((event: CustomEvent<{
|
|
63
|
+
readonly value: string;
|
|
64
|
+
readonly index: number;
|
|
65
|
+
}>) => any) | undefined;
|
|
66
|
+
"onUpdate:index"?: ((value: number) => any) | undefined;
|
|
67
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
68
|
+
declare const _default: typeof __VLS_export;
|
|
69
|
+
export default _default;
|
|
@@ -0,0 +1,403 @@
|
|
|
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, watchSyncEffect } from 'vue'
|
|
4
|
+
import type { PropType } from 'vue'
|
|
5
|
+
import {
|
|
6
|
+
checkHydratedRoot,
|
|
7
|
+
concat,
|
|
8
|
+
createDispatch,
|
|
9
|
+
cycleCheckedComputed,
|
|
10
|
+
initializedState,
|
|
11
|
+
nativeAttrs,
|
|
12
|
+
useComponentHost,
|
|
13
|
+
useReflectedProp,
|
|
14
|
+
warnUnless,
|
|
15
|
+
} from './host'
|
|
16
|
+
import { acceptsControllerWrite } from './props'
|
|
17
|
+
import {
|
|
18
|
+
BINDING_INPUTS_PROP,
|
|
19
|
+
checkedProp,
|
|
20
|
+
checkPropInput,
|
|
21
|
+
copyStateSeed,
|
|
22
|
+
evaluateInput,
|
|
23
|
+
type InputBindings,
|
|
24
|
+
inputComputed,
|
|
25
|
+
inputDefault,
|
|
26
|
+
inputRead,
|
|
27
|
+
propValidityState,
|
|
28
|
+
READY_INPUT,
|
|
29
|
+
requireInputStatus,
|
|
30
|
+
UNRESOLVED_INPUT,
|
|
31
|
+
vPropValidity,
|
|
32
|
+
vuePropInputs,
|
|
33
|
+
} from './props'
|
|
34
|
+
import UiIcon from './UiIcon.vue'
|
|
35
|
+
import UiIconButton from './UiIconButton.vue'
|
|
36
|
+
|
|
37
|
+
defineOptions({ inheritAttrs: false })
|
|
38
|
+
|
|
39
|
+
const propValidityContract = {
|
|
40
|
+
props: {
|
|
41
|
+
disabled: {
|
|
42
|
+
type: { kind: 'terminal', name: 'boolean' },
|
|
43
|
+
required: false,
|
|
44
|
+
target: { attribute: 'disabled' },
|
|
45
|
+
description: 'Prevents cycling while keeping the selected state visible.',
|
|
46
|
+
default: false,
|
|
47
|
+
},
|
|
48
|
+
index: {
|
|
49
|
+
type: { kind: 'terminal', name: 'number' },
|
|
50
|
+
required: false,
|
|
51
|
+
target: { attribute: 'index' },
|
|
52
|
+
description:
|
|
53
|
+
'Initial or externally selected zero-based state. The first state is the default.',
|
|
54
|
+
default: 0,
|
|
55
|
+
},
|
|
56
|
+
items: {
|
|
57
|
+
type: {
|
|
58
|
+
kind: 'list',
|
|
59
|
+
item: {
|
|
60
|
+
kind: 'object',
|
|
61
|
+
fields: [{ name: 'value', type: { kind: 'terminal', name: 'string' }, optional: false }, {
|
|
62
|
+
name: 'label',
|
|
63
|
+
type: { kind: 'terminal', name: 'string' },
|
|
64
|
+
optional: false,
|
|
65
|
+
}, { name: 'icon', type: { kind: 'terminal', name: 'string' }, optional: false }],
|
|
66
|
+
open: false,
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
required: true,
|
|
70
|
+
target: { attribute: 'items' },
|
|
71
|
+
description:
|
|
72
|
+
'Ordered states with a value, readable label and Looma icon name. Activation advances to the next state and wraps.',
|
|
73
|
+
},
|
|
74
|
+
label: {
|
|
75
|
+
type: { kind: 'terminal', name: 'string' },
|
|
76
|
+
required: false,
|
|
77
|
+
target: { attribute: 'label' },
|
|
78
|
+
description:
|
|
79
|
+
'What the button changes, such as Appearance. The selected state is included in its accessible name.',
|
|
80
|
+
default: 'State',
|
|
81
|
+
},
|
|
82
|
+
size: {
|
|
83
|
+
type: { kind: 'terminal', name: 'keyword' },
|
|
84
|
+
required: false,
|
|
85
|
+
target: { attribute: 'size' },
|
|
86
|
+
description: 'Uses IconButton\'s compact visible sizes and adjustable invisible touch area.',
|
|
87
|
+
values: ['sm', 'md', 'lg'],
|
|
88
|
+
default: 'md',
|
|
89
|
+
},
|
|
90
|
+
variant: {
|
|
91
|
+
type: { kind: 'terminal', name: 'keyword' },
|
|
92
|
+
required: false,
|
|
93
|
+
target: { attribute: 'variant' },
|
|
94
|
+
description: 'Uses IconButton\'s standard emphasis.',
|
|
95
|
+
values: ['ghost', 'outline', 'solid'],
|
|
96
|
+
default: 'outline',
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
} as const
|
|
100
|
+
const props = defineProps({
|
|
101
|
+
disabled: { type: null as unknown as PropType<boolean | null> },
|
|
102
|
+
index: { type: null as unknown as PropType<number | null> },
|
|
103
|
+
items: {
|
|
104
|
+
type: null as unknown as PropType<
|
|
105
|
+
readonly ({ readonly value: string; readonly label: string; readonly icon: string })[]
|
|
106
|
+
>,
|
|
107
|
+
},
|
|
108
|
+
label: { type: null as unknown as PropType<string | null> },
|
|
109
|
+
size: { type: null as unknown as PropType<'sm' | 'md' | 'lg' | null> },
|
|
110
|
+
variant: { type: null as unknown as PropType<'ghost' | 'outline' | 'solid' | null> },
|
|
111
|
+
[BINDING_INPUTS_PROP]: { type: null as unknown as PropType<InputBindings> },
|
|
112
|
+
})
|
|
113
|
+
const acceptedProps: Record<string, unknown> = {
|
|
114
|
+
disabled: false,
|
|
115
|
+
index: 0,
|
|
116
|
+
items: null,
|
|
117
|
+
label: 'State',
|
|
118
|
+
size: 'md',
|
|
119
|
+
variant: 'outline',
|
|
120
|
+
}
|
|
121
|
+
const inputTracking = vuePropInputs(acceptedProps, {
|
|
122
|
+
disabled: false,
|
|
123
|
+
index: 0,
|
|
124
|
+
label: 'State',
|
|
125
|
+
size: 'md',
|
|
126
|
+
variant: 'outline',
|
|
127
|
+
}, (name, value, source, values) => {
|
|
128
|
+
switch (name) {
|
|
129
|
+
case 'disabled':
|
|
130
|
+
return checkPropInput(value, { kind: 'terminal', name: 'boolean' }, true, true)
|
|
131
|
+
case 'index':
|
|
132
|
+
return checkPropInput(value, { kind: 'terminal', name: 'number' }, true, true)
|
|
133
|
+
case 'items':
|
|
134
|
+
return checkPropInput(
|
|
135
|
+
value,
|
|
136
|
+
{
|
|
137
|
+
kind: 'list',
|
|
138
|
+
item: {
|
|
139
|
+
kind: 'object',
|
|
140
|
+
fields: [
|
|
141
|
+
{ name: 'value', type: { kind: 'terminal', name: 'string' }, optional: false },
|
|
142
|
+
{ name: 'label', type: { kind: 'terminal', name: 'string' }, optional: false },
|
|
143
|
+
{ name: 'icon', type: { kind: 'terminal', name: 'string' }, optional: false },
|
|
144
|
+
],
|
|
145
|
+
open: false,
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
true,
|
|
149
|
+
false,
|
|
150
|
+
)
|
|
151
|
+
case 'label':
|
|
152
|
+
return checkPropInput(value, { kind: 'terminal', name: 'string' }, true, true)
|
|
153
|
+
case 'size':
|
|
154
|
+
return checkPropInput(value, { kind: 'terminal', name: 'keyword' }, true, true)
|
|
155
|
+
case 'variant':
|
|
156
|
+
return checkPropInput(value, { kind: 'terminal', name: 'keyword' }, true, true)
|
|
157
|
+
default:
|
|
158
|
+
return { ok: false }
|
|
159
|
+
}
|
|
160
|
+
}, () => {
|
|
161
|
+
void checkedProps.value
|
|
162
|
+
})
|
|
163
|
+
const propInputs = inputTracking.inputs
|
|
164
|
+
const checkedProps = computed(() => {
|
|
165
|
+
void inputTracking.version.value
|
|
166
|
+
return ({
|
|
167
|
+
disabled: propInputs.value<boolean | null>(
|
|
168
|
+
'disabled',
|
|
169
|
+
props['disabled'],
|
|
170
|
+
props[BINDING_INPUTS_PROP],
|
|
171
|
+
) as boolean,
|
|
172
|
+
index: propInputs.value<number | null>(
|
|
173
|
+
'index',
|
|
174
|
+
props['index'],
|
|
175
|
+
props[BINDING_INPUTS_PROP],
|
|
176
|
+
) as number,
|
|
177
|
+
items: propInputs.value<
|
|
178
|
+
readonly ({ readonly value: string; readonly label: string; readonly icon: string })[]
|
|
179
|
+
>('items', props['items'], props[BINDING_INPUTS_PROP]),
|
|
180
|
+
label: propInputs.value<string | null>(
|
|
181
|
+
'label',
|
|
182
|
+
props['label'],
|
|
183
|
+
props[BINDING_INPUTS_PROP],
|
|
184
|
+
) as string,
|
|
185
|
+
size: propInputs.value<'sm' | 'md' | 'lg' | null>(
|
|
186
|
+
'size',
|
|
187
|
+
props['size'],
|
|
188
|
+
props[BINDING_INPUTS_PROP],
|
|
189
|
+
) as 'sm' | 'md' | 'lg',
|
|
190
|
+
variant: propInputs.value<'ghost' | 'outline' | 'solid' | null>(
|
|
191
|
+
'variant',
|
|
192
|
+
props['variant'],
|
|
193
|
+
props[BINDING_INPUTS_PROP],
|
|
194
|
+
) as 'ghost' | 'outline' | 'solid',
|
|
195
|
+
})
|
|
196
|
+
})
|
|
197
|
+
const inputStatus = (name: string, handlesError: boolean) => {
|
|
198
|
+
void checkedProps.value
|
|
199
|
+
void inputTracking.version.value
|
|
200
|
+
return requireInputStatus(propInputs.status(name), handlesError)
|
|
201
|
+
}
|
|
202
|
+
void checkedProps.value
|
|
203
|
+
watchSyncEffect(() => {
|
|
204
|
+
void checkedProps.value
|
|
205
|
+
})
|
|
206
|
+
const reflectedProp = useReflectedProp()
|
|
207
|
+
const hydrationInstance = getCurrentInstance()
|
|
208
|
+
const emit = defineEmits<{
|
|
209
|
+
'update:index': [value: number]
|
|
210
|
+
change: [event: CustomEvent<{ readonly value: string; readonly index: number }>]
|
|
211
|
+
}>()
|
|
212
|
+
|
|
213
|
+
const root = ref<HTMLElement | null>(null)
|
|
214
|
+
const current = initializedState<number>(
|
|
215
|
+
() =>
|
|
216
|
+
evaluateInput(() => {
|
|
217
|
+
return inputRead(checkedProps.value.index, propInputs.status('index'))
|
|
218
|
+
}),
|
|
219
|
+
(next: unknown) => (typeof next === 'number' && Number.isFinite(next)),
|
|
220
|
+
copyStateSeed,
|
|
221
|
+
() =>
|
|
222
|
+
warnUnless(false, 'initializer:current', 'State `current` does not satisfy its declared type.'),
|
|
223
|
+
)
|
|
224
|
+
let selectedPrevious: { value: string; label: string; icon: string } | null = null
|
|
225
|
+
const selected: ReturnType<
|
|
226
|
+
typeof inputComputed<{ value: string; label: string; icon: string } | null>
|
|
227
|
+
> = inputComputed<{ value: string; label: string; icon: string } | null>(
|
|
228
|
+
() => {
|
|
229
|
+
return inputDefault(() =>
|
|
230
|
+
((objectValue: any, indexValue: any) =>
|
|
231
|
+
objectValue === Symbol.for('html-next.invalid-result')
|
|
232
|
+
|| indexValue === Symbol.for('html-next.invalid-result')
|
|
233
|
+
? Symbol.for('html-next.invalid-result')
|
|
234
|
+
: objectValue[indexValue])(
|
|
235
|
+
inputRead(checkedProps.value.items, propInputs.status('items')),
|
|
236
|
+
inputDefault(() => inputRead(current.value, declarationStatus('current')), () => 0),
|
|
237
|
+
), () =>
|
|
238
|
+
inputRead(checkedProps.value.items, propInputs.status('items'))[0]) as any
|
|
239
|
+
},
|
|
240
|
+
(read) => {
|
|
241
|
+
const value = cycleCheckedComputed(read)
|
|
242
|
+
return { get: () => value.value }
|
|
243
|
+
},
|
|
244
|
+
next =>
|
|
245
|
+
(next as unknown) === Symbol.for('html-next.invalid-result')
|
|
246
|
+
? selectedPrevious
|
|
247
|
+
: (selectedPrevious = next),
|
|
248
|
+
)
|
|
249
|
+
let guardedPrevious: any = null
|
|
250
|
+
const guarded = computed(() => {
|
|
251
|
+
const candidate: any = concat(
|
|
252
|
+
checkedProps.value.label,
|
|
253
|
+
': ',
|
|
254
|
+
selected.get()?.label ?? 'No choices',
|
|
255
|
+
)
|
|
256
|
+
if (candidate === Symbol.for('html-next.invalid-result')) return guardedPrevious
|
|
257
|
+
return guardedPrevious = candidate
|
|
258
|
+
})
|
|
259
|
+
provide('html-next:ui-cycle-button:current', current)
|
|
260
|
+
const declarationStatuses = { current: () => current.status() } as Record<
|
|
261
|
+
string,
|
|
262
|
+
() => typeof READY_INPUT
|
|
263
|
+
>
|
|
264
|
+
const declarationStatus = (name: string) => declarationStatuses[name]!()
|
|
265
|
+
current.start()
|
|
266
|
+
checkHydratedRoot('span', 'ui-cycle-button')
|
|
267
|
+
|
|
268
|
+
const isChangeDetail = (
|
|
269
|
+
detail: unknown,
|
|
270
|
+
): boolean => (detail !== null && typeof detail === 'object' && !Array.isArray(detail)
|
|
271
|
+
&& typeof (detail as Record<string, unknown>)['value'] === 'string'
|
|
272
|
+
&& (typeof (detail as Record<string, unknown>)['index'] === 'number'
|
|
273
|
+
&& Number.isFinite((detail as Record<string, unknown>)['index']))
|
|
274
|
+
&& Object.keys(detail as object).every((key) => ['value', 'index'].includes(key)))
|
|
275
|
+
const dispatch = createDispatch(root, emit as (name: string, detail: unknown) => void, {
|
|
276
|
+
checks: {
|
|
277
|
+
change: isChangeDetail,
|
|
278
|
+
},
|
|
279
|
+
modeled: ['index'],
|
|
280
|
+
})
|
|
281
|
+
|
|
282
|
+
useComponentHost(() => import('../components/ui-cycle-button/ui-cycle-button.js'), {
|
|
283
|
+
root,
|
|
284
|
+
module: true,
|
|
285
|
+
dispatch,
|
|
286
|
+
acceptsState: (name: string, keys: readonly string[], value: unknown) =>
|
|
287
|
+
acceptsControllerWrite(
|
|
288
|
+
value,
|
|
289
|
+
({ current: { kind: 'terminal', name: 'number' } } as Record<string, any>)[name],
|
|
290
|
+
keys,
|
|
291
|
+
),
|
|
292
|
+
controllerSource: {
|
|
293
|
+
specifier: '../components/ui-cycle-button/ui-cycle-button.js',
|
|
294
|
+
definition: './components/ui-cycle-button/ui-cycle-button.html',
|
|
295
|
+
},
|
|
296
|
+
props: checkedProps,
|
|
297
|
+
inputs: propInputs,
|
|
298
|
+
inputTracking,
|
|
299
|
+
propInputs: (name: string) => {
|
|
300
|
+
const incoming = hydrationInstance?.vnode.props
|
|
301
|
+
const kebab = name.replace(/[A-Z]/g, (letter) => '-' + letter.toLowerCase())
|
|
302
|
+
return incoming !== null && incoming !== undefined
|
|
303
|
+
? (incoming[name] ?? incoming[kebab] ?? null)
|
|
304
|
+
: null
|
|
305
|
+
},
|
|
306
|
+
propNames: ['disabled', 'index', 'items', 'label', 'size', 'variant'],
|
|
307
|
+
propValidity: (name: string) =>
|
|
308
|
+
propValidityState({ contract: propValidityContract, values: { ...props } }, name),
|
|
309
|
+
state: { current },
|
|
310
|
+
computed: { selected },
|
|
311
|
+
availability: { current: () => declarationStatus('current'), selected: () => selected.status() },
|
|
312
|
+
})
|
|
313
|
+
</script>
|
|
314
|
+
|
|
315
|
+
<template>
|
|
316
|
+
<span
|
|
317
|
+
class="ui-cycle-button"
|
|
318
|
+
v-bind="nativeAttrs($attrs)"
|
|
319
|
+
data-hn
|
|
320
|
+
v-prop-validity="{ contract: propValidityContract, values: { ...props } }"
|
|
321
|
+
:data-ui-cycle-button-prop-disabled="reflectedProp('disabled', 'disabled', checkedProps.disabled, undefined, false)"
|
|
322
|
+
:data-ui-cycle-button-prop-index="reflectedProp('index', 'index', checkedProps.index, undefined, false)"
|
|
323
|
+
:data-ui-cycle-button-prop-items="reflectedProp('items', 'items', checkedProps.items, undefined, false)"
|
|
324
|
+
:data-ui-cycle-button-prop-label="reflectedProp('label', 'label', checkedProps.label, undefined, false)"
|
|
325
|
+
:data-ui-cycle-button-prop-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
|
|
326
|
+
:data-ui-cycle-button-prop-variant="reflectedProp('variant', 'variant', checkedProps.variant, undefined, false)"
|
|
327
|
+
ref="root"
|
|
328
|
+
><template
|
|
329
|
+
v-for="boundInput in [evaluateInput(
|
|
330
|
+
() =>
|
|
331
|
+
(concat(
|
|
332
|
+
inputRead(checkedProps.label, inputStatus('label', true)),
|
|
333
|
+
': ',
|
|
334
|
+
inputDefault(() => inputRead(selected.get(), selected.status())?.label, () => 'No choices'),
|
|
335
|
+
)) as any,
|
|
336
|
+
READY_INPUT,
|
|
337
|
+
)]"
|
|
338
|
+
><template
|
|
339
|
+
v-for="boundInputSnapshot in [evaluateInput(
|
|
340
|
+
() =>
|
|
341
|
+
(inputRead(checkedProps.disabled, inputStatus('disabled', true))
|
|
342
|
+
|| inputRead(checkedProps.items, inputStatus('items', true)).length < 2) as any,
|
|
343
|
+
READY_INPUT,
|
|
344
|
+
)]"
|
|
345
|
+
><UiIconButton
|
|
346
|
+
class="ui-icon-button"
|
|
347
|
+
tone="neutral"
|
|
348
|
+
aria-description="Activate to choose the next state."
|
|
349
|
+
:label="boundInput.value"
|
|
350
|
+
:title="guarded"
|
|
351
|
+
:size="checkedProps.size"
|
|
352
|
+
:variant="checkedProps.variant"
|
|
353
|
+
:disabled="boundInputSnapshot.value"
|
|
354
|
+
v-bind="{
|
|
355
|
+
[BINDING_INPUTS_PROP]: {
|
|
356
|
+
label: () => boundInput,
|
|
357
|
+
size: () => ({ value: checkedProps.size, status: inputStatus('size', true) }),
|
|
358
|
+
variant: () => ({ value: checkedProps.variant, status: inputStatus('variant', true) }),
|
|
359
|
+
disabled: () => boundInputSnapshot,
|
|
360
|
+
},
|
|
361
|
+
}"
|
|
362
|
+
><template
|
|
363
|
+
v-for="boundInputSnapshot2 in [evaluateInput(
|
|
364
|
+
() => (inputDefault(() => inputRead(selected.get(), selected.status())?.icon, () => '')) as any,
|
|
365
|
+
READY_INPUT,
|
|
366
|
+
)]"
|
|
367
|
+
><UiIcon
|
|
368
|
+
class="ui-icon"
|
|
369
|
+
:name="boundInputSnapshot2.value"
|
|
370
|
+
v-bind="{ [BINDING_INPUTS_PROP]: { name: () => boundInputSnapshot2 } }"
|
|
371
|
+
/></template></UiIconButton></template></template></span>
|
|
372
|
+
</template>
|
|
373
|
+
|
|
374
|
+
<style scoped>
|
|
375
|
+
@scope (.ui-cycle-button) to ([data-hn]) {
|
|
376
|
+
:global(:scope) {
|
|
377
|
+
display: inline-flex !important;
|
|
378
|
+
align-items: center !important;
|
|
379
|
+
justify-content: center !important;
|
|
380
|
+
gap: 0 !important;
|
|
381
|
+
margin: 0 !important;
|
|
382
|
+
padding: 0 !important;
|
|
383
|
+
vertical-align: middle;
|
|
384
|
+
}
|
|
385
|
+
:global(:scope[hidden]) {
|
|
386
|
+
display: none !important;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
@scope ([data-slotted~="ui-cycle-button"]:not([data-hn])) to ([data-hn], [data-slotted]) {
|
|
390
|
+
:global(:where(.ui-cycle-button):where(:scope, :not([data-hn], [data-slotted]:not([data-slotted~="ui-cycle-button"])))) {
|
|
391
|
+
display: inline-flex !important;
|
|
392
|
+
align-items: center !important;
|
|
393
|
+
justify-content: center !important;
|
|
394
|
+
gap: 0 !important;
|
|
395
|
+
margin: 0 !important;
|
|
396
|
+
padding: 0 !important;
|
|
397
|
+
vertical-align: middle;
|
|
398
|
+
}
|
|
399
|
+
:global(:where(.ui-cycle-button)[hidden]:where(:scope, :not([data-hn], [data-slotted]:not([data-slotted~="ui-cycle-button"])))) {
|
|
400
|
+
display: none !important;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
</style>
|
package/vue/UiDialog.vue
CHANGED
|
@@ -428,7 +428,9 @@ useComponentHost(() => import('../components/ui-dialog/ui-dialog.js'), {
|
|
|
428
428
|
overlay var(--ui-dialog-duration, var(--ui-motion-base)) var(--ui-motion-ease) allow-discrete;
|
|
429
429
|
}
|
|
430
430
|
:global(:scope:where([data-hn-ui-dialog])) {
|
|
431
|
-
--_ui-material-glassiness:
|
|
431
|
+
--_ui-material-glassiness: calc(
|
|
432
|
+
clamp(0, var(--ui-glassiness, 0), 1) + 2 * pow(clamp(0, var(--ui-glassiness, 0), 1), 4)
|
|
433
|
+
);
|
|
432
434
|
--_ui-material-separation: clamp(0, var(--ui-surface-separation, 0), 1);
|
|
433
435
|
--_ui-material-active: clamp(
|
|
434
436
|
0,
|
|
@@ -707,7 +709,9 @@ useComponentHost(() => import('../components/ui-dialog/ui-dialog.js'), {
|
|
|
707
709
|
overlay var(--ui-dialog-duration, var(--ui-motion-base)) var(--ui-motion-ease) allow-discrete;
|
|
708
710
|
}
|
|
709
711
|
:global(:where(.ui-dialog):where(:scope, :not([data-hn], [data-slotted]:not([data-slotted~="ui-dialog"]))):where([data-hn-ui-dialog])) {
|
|
710
|
-
--_ui-material-glassiness:
|
|
712
|
+
--_ui-material-glassiness: calc(
|
|
713
|
+
clamp(0, var(--ui-glassiness, 0), 1) + 2 * pow(clamp(0, var(--ui-glassiness, 0), 1), 4)
|
|
714
|
+
);
|
|
711
715
|
--_ui-material-separation: clamp(0, var(--ui-surface-separation, 0), 1);
|
|
712
716
|
--_ui-material-active: clamp(
|
|
713
717
|
0,
|
package/vue/UiIcon.vue
CHANGED
|
@@ -326,6 +326,17 @@ const shapes: ReturnType<typeof inputComputed<any>> = inputComputed<any>(
|
|
|
326
326
|
{ tag: 'path', d: 'M12 7v4' },
|
|
327
327
|
],
|
|
328
328
|
minus: [{ tag: 'path', d: 'M5 12h14' }],
|
|
329
|
+
monitor: [{ tag: 'rect', width: '20', height: '14', x: '2', y: '3', rx: '2' }, {
|
|
330
|
+
tag: 'line',
|
|
331
|
+
x1: '8',
|
|
332
|
+
x2: '16',
|
|
333
|
+
y1: '21',
|
|
334
|
+
y2: '21',
|
|
335
|
+
}, { tag: 'line', x1: '12', x2: '12', y1: '17', y2: '21' }],
|
|
336
|
+
moon: [{
|
|
337
|
+
tag: 'path',
|
|
338
|
+
d: 'M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401',
|
|
339
|
+
}],
|
|
329
340
|
'notebook-pen': [
|
|
330
341
|
{ tag: 'path', d: 'M13.4 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-7.4' },
|
|
331
342
|
{ tag: 'path', d: 'M2 6h4' },
|
|
@@ -413,6 +424,17 @@ const shapes: ReturnType<typeof inputComputed<any>> = inputComputed<any>(
|
|
|
413
424
|
tag: 'path',
|
|
414
425
|
d: 'M14 12a4 4 0 0 1 0 8H6',
|
|
415
426
|
}, { tag: 'line', x1: '4', x2: '20', y1: '12', y2: '12' }],
|
|
427
|
+
sun: [
|
|
428
|
+
{ tag: 'circle', cx: '12', cy: '12', r: '4' },
|
|
429
|
+
{ tag: 'path', d: 'M12 2v2' },
|
|
430
|
+
{ tag: 'path', d: 'M12 20v2' },
|
|
431
|
+
{ tag: 'path', d: 'm4.93 4.93 1.41 1.41' },
|
|
432
|
+
{ tag: 'path', d: 'm17.66 17.66 1.41 1.41' },
|
|
433
|
+
{ tag: 'path', d: 'M2 12h2' },
|
|
434
|
+
{ tag: 'path', d: 'M20 12h2' },
|
|
435
|
+
{ tag: 'path', d: 'm6.34 17.66-1.41 1.41' },
|
|
436
|
+
{ tag: 'path', d: 'm19.07 4.93-1.41 1.41' },
|
|
437
|
+
],
|
|
416
438
|
superscript: [{ tag: 'path', d: 'm4 19 8-8' }, { tag: 'path', d: 'm12 19-8-8' }, {
|
|
417
439
|
tag: 'path',
|
|
418
440
|
d: 'M20 12h-4c0-1.5.442-2 1.5-2.5S20 8.334 20 7.002c0-.472-.17-.93-.484-1.29a2.105 2.105 0 0 0-2.617-.436c-.42.239-.738.614-.899 1.06',
|
package/vue/UiIconButton.vue
CHANGED
|
@@ -77,7 +77,7 @@ const propValidityContract = {
|
|
|
77
77
|
required: false,
|
|
78
78
|
target: { attribute: 'data-match-button' },
|
|
79
79
|
description:
|
|
80
|
-
'Matches a boxed Button of the same size when the two share a flex row. Uses the control-size theme tokens and stretches to the row\'s height,
|
|
80
|
+
'Matches a boxed Button of the same size when the two share a flex row. Uses the control-size theme tokens and stretches to the row\'s height, on mouse and\n touch alike. Leave it off for compact toolbar and inline icon buttons.',
|
|
81
81
|
default: false,
|
|
82
82
|
},
|
|
83
83
|
pending: {
|
|
@@ -116,7 +116,7 @@ const propValidityContract = {
|
|
|
116
116
|
required: false,
|
|
117
117
|
target: { attribute: 'size' },
|
|
118
118
|
description:
|
|
119
|
-
'Button and icon size together: sm is 1.75rem with a small icon, md is 2rem, and lg is 2.5rem with a large icon.
|
|
119
|
+
'Button and icon size together: sm is 1.75rem with a small icon, md is 2rem, and lg is 2.5rem with a large icon. Touch can use an invisible hit area sized\n by the adjustable control target preference.',
|
|
120
120
|
values: ['sm', 'md', 'lg'],
|
|
121
121
|
default: 'md',
|
|
122
122
|
},
|
|
@@ -841,20 +841,6 @@ useComponentHost(() => import('../components/ui-icon-button/ui-icon-button.js'),
|
|
|
841
841
|
--_size: var(--ui-control-size-lg);
|
|
842
842
|
}
|
|
843
843
|
|
|
844
|
-
@media (pointer: coarse) {
|
|
845
|
-
:global(:scope[data-ui-icon-button-state~="matchButton"]:where([data-hn-ui-icon-button])) {
|
|
846
|
-
inline-size: max(var(--ui-icon-button-size, var(--_size)), var(--ui-control-min-block-size));
|
|
847
|
-
min-inline-size: max(
|
|
848
|
-
var(--ui-icon-button-size, var(--_size)),
|
|
849
|
-
var(--ui-control-min-block-size)
|
|
850
|
-
);
|
|
851
|
-
min-block-size: max(
|
|
852
|
-
var(--ui-icon-button-size, var(--_size)),
|
|
853
|
-
var(--ui-control-min-block-size)
|
|
854
|
-
);
|
|
855
|
-
}
|
|
856
|
-
}
|
|
857
|
-
|
|
858
844
|
:global(:scope[data-ui-icon-button-state~="round"]:where([data-hn-ui-icon-button])) {
|
|
859
845
|
border-radius: var(--ui-radius-round);
|
|
860
846
|
}
|
package/vue/UiInput.vue
CHANGED
|
@@ -81,7 +81,7 @@ const propValidityContract = {
|
|
|
81
81
|
required: false,
|
|
82
82
|
target: { attribute: 'size' },
|
|
83
83
|
description:
|
|
84
|
-
'Height, padding, and type size, matching Button\'s sizes so a field and a button of one size share a row. sm is the small control height (2rem by default)\n with smaller text, for compact rows such as a table row or a filter bar; md is the standard control height; lg is taller with roomier padding.
|
|
84
|
+
'Height, padding, and type size, matching Button\'s sizes so a field and a button of one size share a row. sm is the small control height (2rem by default)\n with smaller text, for compact rows such as a table row or a filter bar; md is the standard control height; lg is taller with roomier padding. Touch input\n keeps body-size field text without inflating the visible size ladder. Change it after render through this option; the element\'s size property is the\n native one.',
|
|
85
85
|
values: ['sm', 'md', 'lg'],
|
|
86
86
|
default: 'md',
|
|
87
87
|
},
|
|
@@ -540,8 +540,7 @@ useComponentHost(() => import('../components/ui-input/ui-input.js'), {
|
|
|
540
540
|
|
|
541
541
|
/* Each size reads the hook and then an Input Group's default first, so a group, which draws the frame, can zero it. */
|
|
542
542
|
|
|
543
|
-
/*
|
|
544
|
-
body-size text: below 16px, iOS zooms the page into the focused field. */
|
|
543
|
+
/* Touch may use body-size text in a small native field to avoid focus zoom; this does not impose a larger visible control height. */
|
|
545
544
|
|
|
546
545
|
/* Tabbing into a field selects its text; tint that selection softly instead of the page highlight. */
|
|
547
546
|
|
|
@@ -613,31 +612,11 @@ useComponentHost(() => import('../components/ui-input/ui-input.js'), {
|
|
|
613
612
|
font-size: var(--ui-font-size-md);
|
|
614
613
|
}
|
|
615
614
|
@media (pointer: coarse) {
|
|
616
|
-
:global(:scope) {
|
|
617
|
-
min-block-size: var(
|
|
618
|
-
--ui-input-min-block-size,
|
|
619
|
-
var(
|
|
620
|
-
--_ui-default-input-min-block-size,
|
|
621
|
-
max(var(--ui-control-size-md), var(--ui-control-min-block-size))
|
|
622
|
-
)
|
|
623
|
-
);
|
|
624
|
-
}
|
|
625
|
-
|
|
626
615
|
:global(:scope),
|
|
627
616
|
:global(:scope[data-ui-input-state~="size=sm"]),
|
|
628
617
|
:global(:scope[data-ui-input-state~="size=lg"]) {
|
|
629
618
|
font-size: var(--ui-font-size-md);
|
|
630
619
|
}
|
|
631
|
-
|
|
632
|
-
:global(:scope[data-ui-input-state~="size=sm"]) {
|
|
633
|
-
min-block-size: var(
|
|
634
|
-
--ui-input-min-block-size,
|
|
635
|
-
var(
|
|
636
|
-
--_ui-default-input-min-block-size,
|
|
637
|
-
max(var(--ui-control-size-sm), var(--ui-control-min-block-size))
|
|
638
|
-
)
|
|
639
|
-
);
|
|
640
|
-
}
|
|
641
620
|
}
|
|
642
621
|
:global(:scope::selection) {
|
|
643
622
|
background: color-mix(in srgb, var(--ui-accent-solid) 20%, transparent);
|
package/vue/UiInputGroup.vue
CHANGED
|
@@ -326,16 +326,6 @@ useComponentHost(() => import('../components/ui-input-group/ui-input-group.js'),
|
|
|
326
326
|
min-block-size: var(--ui-control-size-lg);
|
|
327
327
|
}
|
|
328
328
|
|
|
329
|
-
@media (pointer: coarse) {
|
|
330
|
-
:global(:scope:where([data-hn-ui-input-group])) {
|
|
331
|
-
min-block-size: max(var(--ui-control-size-md), var(--ui-control-min-block-size));
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
:global(:scope:has(.field [data-ui-input-state~="size=sm"]):where([data-hn-ui-input-group])) {
|
|
335
|
-
min-block-size: var(--ui-control-min-block-size);
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
|
|
339
329
|
:global(:scope:hover:not(:has(:is(input, textarea):focus, :is(input, textarea):disabled, :is(input, textarea):read-only, [aria-invalid="true"], :is(:user-invalid, [data-user-invalid]))):where([data-hn-ui-input-group])) {
|
|
340
330
|
border-color: var(--ui-control-border-hover, var(--ui-text-secondary));
|
|
341
331
|
}
|
package/vue/UiMenu.vue
CHANGED
|
@@ -427,7 +427,9 @@ useComponentHost(() => import('../components/ui-menu/ui-menu.js'), {
|
|
|
427
427
|
overflow: auto;
|
|
428
428
|
}
|
|
429
429
|
:global(:scope:not([inline]) .surface:where([data-hn-ui-menu])) {
|
|
430
|
-
--_ui-material-glassiness:
|
|
430
|
+
--_ui-material-glassiness: calc(
|
|
431
|
+
clamp(0, var(--ui-glassiness, 0), 1) + 2 * pow(clamp(0, var(--ui-glassiness, 0), 1), 4)
|
|
432
|
+
);
|
|
431
433
|
--_ui-material-separation: clamp(0, var(--ui-surface-separation, 0), 1);
|
|
432
434
|
--_ui-material-active: clamp(
|
|
433
435
|
0,
|
package/vue/UiPopover.vue
CHANGED
|
@@ -378,7 +378,9 @@ useComponentHost(() => import('../components/ui-popover/ui-popover.js'), {
|
|
|
378
378
|
);
|
|
379
379
|
}
|
|
380
380
|
:global(.surface:where([data-hn-ui-popover])) {
|
|
381
|
-
--_ui-material-glassiness:
|
|
381
|
+
--_ui-material-glassiness: calc(
|
|
382
|
+
clamp(0, var(--ui-glassiness, 0), 1) + 2 * pow(clamp(0, var(--ui-glassiness, 0), 1), 4)
|
|
383
|
+
);
|
|
382
384
|
--_ui-material-separation: clamp(0, var(--ui-surface-separation, 0), 1);
|
|
383
385
|
--_ui-material-active: clamp(
|
|
384
386
|
0,
|