@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.
- package/components/shared/overlay.js +8 -2
- package/components/shared/surface-material.js +21 -0
- package/components/ui-badge/ui-badge.html +11 -3
- package/components/ui-button/ui-button.html +92 -51
- package/components/ui-card/ui-card.html +50 -6
- package/components/ui-checkbox/ui-checkbox.html +4 -2
- package/components/ui-curve-editor/curve.js +10 -0
- package/components/ui-curve-editor/ui-curve-editor.html +181 -0
- package/components/ui-curve-editor/ui-curve-editor.js +51 -0
- package/components/ui-dialog/ui-dialog.html +64 -1
- package/components/ui-dialog/ui-dialog.js +9 -1
- package/components/ui-icon-button/ui-icon-button.html +97 -31
- 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 +62 -0
- package/components/ui-menu/ui-menu.js +1 -1
- package/components/ui-number-input/arithmetic.js +47 -0
- package/components/ui-number-input/ui-number-input.html +63 -0
- package/components/ui-number-input/ui-number-input.js +47 -0
- package/components/ui-popover/ui-popover.html +66 -1
- package/components/ui-popover/ui-popover.js +1 -1
- package/components/ui-select/ui-select.html +9 -7
- package/components/ui-slider/ui-slider.html +84 -0
- package/components/ui-slider/ui-slider.js +29 -0
- package/components/ui-switch/ui-switch.html +3 -0
- package/components/ui-tabs/ui-tabs.html +6 -1
- package/components/ui-text/ui-text.html +31 -6
- package/components/ui-textarea/ui-textarea.html +2 -1
- package/components/ui-tooltip/ui-tooltip.html +60 -0
- package/components/ui-tooltip/ui-tooltip.js +1 -1
- package/dist/index.js +47 -43
- package/docs/README.md +59 -5
- package/docs/card.html +16 -2
- package/docs/card.js +17 -2
- package/docs/catalog.json +1640 -108
- package/docs/customizer-render.mjs +50 -11
- package/docs/customizer.js +137 -24
- package/docs/documentation.css +9 -1
- package/docs/index.d.ts +8 -3
- package/docs/index.mjs +1 -1
- package/docs/preview.js +2 -0
- package/docs/render.mjs +16 -7
- package/docs/site.mjs +78 -27
- package/docs/theme-session.mjs +53 -0
- package/docs/theme.mjs +189 -18
- package/docs/value-editors.mjs +33 -0
- package/package.json +2 -2
- package/styles/ui-badge.css +11 -6
- package/styles/ui-button.css +74 -49
- package/styles/ui-card.css +51 -4
- package/styles/ui-checkbox.css +4 -2
- package/styles/ui-curve-editor.css +109 -0
- package/styles/ui-dialog.css +136 -0
- package/styles/ui-icon-button.css +85 -28
- 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 +74 -0
- package/styles/ui-number-input.css +34 -0
- package/styles/ui-popover.css +76 -0
- package/styles/ui-select.css +9 -7
- package/styles/ui-slider.css +53 -0
- package/styles/ui-switch.css +3 -0
- package/styles/ui-tabs.css +6 -1
- package/styles/ui-text.css +23 -1
- package/styles/ui-textarea.css +2 -1
- package/styles/ui-tooltip.css +72 -0
- package/theme-light.css +1 -0
- package/theme-system.css +69 -17
- package/tokens.css +12 -2
- package/vanilla/UiButton.d.ts +1 -0
- package/vanilla/UiButton.js +195 -130
- package/vanilla/UiCard.d.ts +1 -0
- package/vanilla/UiCard.js +12 -12
- package/vanilla/UiCurveEditor.d.ts +28 -0
- package/vanilla/UiCurveEditor.js +134 -0
- package/vanilla/UiIconButton.d.ts +2 -1
- package/vanilla/UiIconButton.js +58 -31
- package/vanilla/UiLightEditor.d.ts +29 -0
- package/vanilla/UiLightEditor.js +102 -0
- package/vanilla/UiNumberInput.d.ts +33 -0
- package/vanilla/UiNumberInput.js +86 -0
- package/vanilla/UiSlider.d.ts +33 -0
- package/vanilla/UiSlider.js +125 -0
- package/vanilla/UiText.d.ts +2 -2
- package/vanilla/UiText.js +45 -11
- package/vanilla/index.js +4 -0
- package/vue/UiBadge.vue +29 -4
- package/vue/UiButton.d.ts +6 -0
- package/vue/UiButton.vue +188 -60
- package/vue/UiCard.d.ts +6 -0
- package/vue/UiCard.vue +80 -6
- package/vue/UiCheckbox.vue +4 -2
- package/vue/UiCurveEditor.d.ts +53 -0
- package/vue/UiCurveEditor.js +2 -0
- package/vue/UiCurveEditor.vue +427 -0
- package/vue/UiDialog.vue +181 -1
- package/vue/UiIconButton.d.ts +8 -2
- package/vue/UiIconButton.vue +190 -45
- 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 +91 -0
- package/vue/UiNumberInput.d.ts +83 -0
- package/vue/UiNumberInput.js +2 -0
- package/vue/UiNumberInput.vue +399 -0
- package/vue/UiPopover.vue +94 -1
- package/vue/UiSelect.vue +16 -10
- package/vue/UiSlider.d.ts +83 -0
- package/vue/UiSlider.js +2 -0
- package/vue/UiSlider.vue +412 -0
- package/vue/UiSwitch.vue +3 -0
- package/vue/UiTabs.vue +6 -1
- package/vue/UiText.d.ts +7 -5
- package/vue/UiText.vue +104 -22
- package/vue/UiTextarea.vue +2 -1
- package/vue/UiTooltip.vue +89 -0
- package/vue/chunks/UiActionBar.js +1 -1
- package/vue/chunks/UiAffordanceScope.js +2 -2
- package/vue/chunks/UiAvatar.js +2 -2
- package/vue/chunks/UiAvatarGroup.js +2 -2
- package/vue/chunks/UiBadge.js +3 -3
- package/vue/chunks/UiBreadcrumbItem.js +2 -2
- package/vue/chunks/UiBreadcrumbs.js +2 -2
- package/vue/chunks/UiButton.js +94 -11
- package/vue/chunks/UiCallout.js +2 -2
- package/vue/chunks/UiCard.js +34 -5
- package/vue/chunks/UiCheckbox.js +3 -3
- package/vue/chunks/UiCluster.js +2 -2
- package/vue/chunks/UiColorPicker.js +2 -2
- package/vue/chunks/UiCombobox.js +2 -2
- package/vue/chunks/UiContainer.js +2 -2
- package/vue/chunks/UiContextMenu.js +2 -2
- package/vue/chunks/UiCover.js +2 -2
- package/vue/chunks/UiCurveEditor.js +413 -0
- package/vue/chunks/UiDescriptionItem.js +2 -2
- package/vue/chunks/UiDescriptionList.js +2 -2
- package/vue/chunks/UiDialog.js +4 -4
- package/vue/chunks/UiDisclosure.js +2 -2
- package/vue/chunks/UiEditable.js +2 -2
- package/vue/chunks/UiEditorBlockActions.js +2 -2
- package/vue/chunks/UiEditorChipEditor.js +2 -2
- package/vue/chunks/UiEditorCodeLanguage.js +2 -2
- package/vue/chunks/UiEditorFootnoteEditor.js +2 -2
- package/vue/chunks/UiEditorImageToolbar.js +3 -3
- package/vue/chunks/UiEditorInsertTableGrid.js +2 -2
- package/vue/chunks/UiEditorLinkCard.js +3 -3
- package/vue/chunks/UiEditorLinkForm.js +3 -3
- package/vue/chunks/UiEditorMentionMenu.js +2 -2
- package/vue/chunks/UiEditorMentionMenuItem.js +2 -2
- package/vue/chunks/UiEditorSlashMenu.js +2 -2
- package/vue/chunks/UiEditorSlashMenuGroup.js +2 -2
- package/vue/chunks/UiEditorSlashMenuItem.js +2 -2
- package/vue/chunks/UiEditorSurface.js +2 -2
- package/vue/chunks/UiEditorTableContextMenu.js +2 -2
- package/vue/chunks/UiEditorTableOverlay.js +2 -2
- package/vue/chunks/UiEditorTableToolbar.js +2 -2
- package/vue/chunks/UiEditorToolbar.js +2 -2
- package/vue/chunks/UiFloatingActionButton.js +2 -2
- package/vue/chunks/UiFormField.js +2 -2
- package/vue/chunks/UiGrid.js +2 -2
- package/vue/chunks/UiIcon.js +2 -2
- package/vue/chunks/UiIconButton.js +77 -11
- package/vue/chunks/UiImage.js +2 -2
- package/vue/chunks/UiInput.js +3 -3
- package/vue/chunks/UiInputGroup.js +3 -3
- package/vue/chunks/UiLightEditor.js +347 -0
- package/vue/chunks/UiList.js +2 -2
- package/vue/chunks/UiListItem.js +2 -2
- package/vue/chunks/UiListbox.js +2 -2
- package/vue/chunks/UiMenu.js +3 -3
- package/vue/chunks/UiMenuGroup.js +2 -2
- package/vue/chunks/UiMenuItem.js +2 -2
- package/vue/chunks/UiMeter.js +2 -2
- package/vue/chunks/UiNavItem.js +2 -2
- package/vue/chunks/UiNumberInput.js +403 -0
- package/vue/chunks/UiPageHeader.js +2 -2
- package/vue/chunks/UiPopover.js +4 -4
- package/vue/chunks/UiRadio.js +2 -2
- package/vue/chunks/UiRadioGroup.js +2 -2
- package/vue/chunks/UiReel.js +2 -2
- package/vue/chunks/UiScrollArea.js +2 -2
- package/vue/chunks/UiSearchResultRow.js +2 -2
- package/vue/chunks/UiSearchShell.js +2 -2
- package/vue/chunks/UiSection.js +2 -2
- package/vue/chunks/UiSelect.js +3 -3
- package/vue/chunks/UiSeparator.js +2 -2
- package/vue/chunks/UiSidebar.js +2 -2
- package/vue/chunks/UiSlider.js +396 -0
- package/vue/chunks/UiSpinner.js +2 -2
- package/vue/chunks/UiStack.js +2 -2
- package/vue/chunks/UiStatusMessage.js +2 -2
- package/vue/chunks/UiSwatch.js +2 -2
- package/vue/chunks/UiSwitch.js +3 -3
- package/vue/chunks/UiSwitcher.js +2 -2
- package/vue/chunks/UiTable.js +2 -2
- package/vue/chunks/UiTabs.js +3 -3
- package/vue/chunks/UiText.js +53 -12
- package/vue/chunks/UiTextarea.js +3 -3
- package/vue/chunks/UiToast.js +2 -2
- package/vue/chunks/UiToastRegion.js +2 -2
- package/vue/chunks/UiTooltip.js +3 -3
- package/vue/chunks/UiTopBar.js +1 -1
- package/vue/chunks/UiTree.js +2 -2
- package/vue/chunks/UiTreeItem.js +2 -2
- package/vue/chunks/_plugin-vue_export-helper.js +68 -2
- package/vue/chunks/props.js +24 -1
- package/vue/components.css +3391 -2139
- package/vue/editor/index.js +623 -211
- package/vue/index.d.ts +4 -0
- package/vue/index.js +6 -2
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
<link rel="component" href="../ui-number-input/ui-number-input.html">
|
|
2
|
+
<template component="ui-curve-editor" module="./ui-curve-editor.js">
|
|
3
|
+
<defs>
|
|
4
|
+
<state name="point0" type="string" value="0.25"></state>
|
|
5
|
+
<state name="point1" type="string" value="0.1"></state>
|
|
6
|
+
<state name="point2" type="string" value="0.25"></state>
|
|
7
|
+
<state name="point3" type="string" value="1"></state>
|
|
8
|
+
|
|
9
|
+
<prop name="value" type="string" default="cubic-bezier(0.25, 0.1, 0.25, 1)"
|
|
10
|
+
>CSS cubic-bezier or a standard easing keyword. X stays within 0–1; Y is bounded to -1–2 for a limited overshoot.</prop>
|
|
11
|
+
<prop name="label" type="string" default="Value">Accessible name for the editing control.</prop>
|
|
12
|
+
<prop name="size" type="keyword" values="sm, md, lg" default="md">Shared field and button height.</prop>
|
|
13
|
+
<prop name="disabled" type="boolean" default="false">Prevents typing, stepping and pointer or keyboard changes while keeping the value visible.</prop>
|
|
14
|
+
<event name="input" type="object"><prop name="value" type="string" required></prop></event>
|
|
15
|
+
<event name="change" type="object"><prop name="value" type="string" required></prop></event>
|
|
16
|
+
</defs>
|
|
17
|
+
<span>
|
|
18
|
+
<span class="plot-frame" from:aria-label="$label" role="group"><span class="plot" $ref="plot">
|
|
19
|
+
<svg viewBox="0 0 100 100" preserveAspectRatio="none" aria-hidden="true">
|
|
20
|
+
<path class="guide" d="M0 66.667 H100 M0 33.333 H100"></path>
|
|
21
|
+
<path $ref="firstLine" class="guide" d="M0 66.667 L25 63.333"></path>
|
|
22
|
+
<path $ref="secondLine" class="guide" d="M100 33.333 L25 33.333"></path>
|
|
23
|
+
<path $ref="curve" d="M0 66.667 C25 63.333 25 33.333 100 33.333"></path>
|
|
24
|
+
</svg>
|
|
25
|
+
<button $ref="first" class="handle" type="button" from:disabled="$disabled" aria-label="First curve handle. Arrow keys adjust; Shift moves faster.">
|
|
26
|
+
</button>
|
|
27
|
+
<button
|
|
28
|
+
$ref="second"
|
|
29
|
+
class="handle second"
|
|
30
|
+
type="button"
|
|
31
|
+
from:disabled="$disabled"
|
|
32
|
+
aria-label="Second curve handle. Arrow keys adjust; Shift moves faster."
|
|
33
|
+
>
|
|
34
|
+
</button>
|
|
35
|
+
</span></span>
|
|
36
|
+
<span class="coordinates">
|
|
37
|
+
<span class="coordinate"><span>X1</span><ui-number-input
|
|
38
|
+
data-curve-coordinate="0"
|
|
39
|
+
from:value="$point0"
|
|
40
|
+
min="0"
|
|
41
|
+
max="1"
|
|
42
|
+
step="0.01"
|
|
43
|
+
label="First handle X"
|
|
44
|
+
from:size="$size"
|
|
45
|
+
from:disabled="$disabled"
|
|
46
|
+
></ui-number-input></span>
|
|
47
|
+
<span class="coordinate"><span>Y1</span><ui-number-input
|
|
48
|
+
data-curve-coordinate="1"
|
|
49
|
+
from:value="$point1"
|
|
50
|
+
min="-1"
|
|
51
|
+
max="2"
|
|
52
|
+
step="0.01"
|
|
53
|
+
label="First handle Y"
|
|
54
|
+
from:size="$size"
|
|
55
|
+
from:disabled="$disabled"
|
|
56
|
+
></ui-number-input></span>
|
|
57
|
+
<span class="coordinate"><span>X2</span><ui-number-input
|
|
58
|
+
data-curve-coordinate="2"
|
|
59
|
+
from:value="$point2"
|
|
60
|
+
min="0"
|
|
61
|
+
max="1"
|
|
62
|
+
step="0.01"
|
|
63
|
+
label="Second handle X"
|
|
64
|
+
from:size="$size"
|
|
65
|
+
from:disabled="$disabled"
|
|
66
|
+
></ui-number-input></span>
|
|
67
|
+
<span class="coordinate"><span>Y2</span><ui-number-input
|
|
68
|
+
data-curve-coordinate="3"
|
|
69
|
+
from:value="$point3"
|
|
70
|
+
min="-1"
|
|
71
|
+
max="2"
|
|
72
|
+
step="0.01"
|
|
73
|
+
label="Second handle Y"
|
|
74
|
+
from:size="$size"
|
|
75
|
+
from:disabled="$disabled"
|
|
76
|
+
></ui-number-input></span>
|
|
77
|
+
</span>
|
|
78
|
+
<output $ref="result">{$value}</output>
|
|
79
|
+
</span>
|
|
80
|
+
<style>
|
|
81
|
+
:host {
|
|
82
|
+
display: grid !important;
|
|
83
|
+
gap: var(--ui-space-3) !important;
|
|
84
|
+
margin: 0 !important;
|
|
85
|
+
padding: 0 !important;
|
|
86
|
+
min-inline-size: 0;
|
|
87
|
+
}
|
|
88
|
+
.plot-frame {
|
|
89
|
+
box-sizing: border-box !important;
|
|
90
|
+
display: block !important;
|
|
91
|
+
block-size: 12rem;
|
|
92
|
+
padding: max(var(--ui-space-4), 0.75rem, calc(var(--ui-control-min-block-size) / 2)) !important;
|
|
93
|
+
margin: 0 !important;
|
|
94
|
+
border: var(--ui-border-width) solid var(--ui-control-border);
|
|
95
|
+
border-radius: var(--ui-field-radius, var(--ui-radius-md));
|
|
96
|
+
background: var(--ui-control-surface, var(--ui-surface));
|
|
97
|
+
}
|
|
98
|
+
.plot {
|
|
99
|
+
position: relative;
|
|
100
|
+
display: block !important;
|
|
101
|
+
inline-size: 100%;
|
|
102
|
+
block-size: 100%;
|
|
103
|
+
}
|
|
104
|
+
svg {
|
|
105
|
+
inline-size: 100%;
|
|
106
|
+
block-size: 100%;
|
|
107
|
+
overflow: visible;
|
|
108
|
+
}
|
|
109
|
+
path {
|
|
110
|
+
fill: none;
|
|
111
|
+
stroke: var(--ui-accent-solid);
|
|
112
|
+
stroke-width: 2;
|
|
113
|
+
vector-effect: non-scaling-stroke;
|
|
114
|
+
}
|
|
115
|
+
.guide {
|
|
116
|
+
stroke: var(--ui-control-border);
|
|
117
|
+
stroke-width: 1;
|
|
118
|
+
}
|
|
119
|
+
.handle {
|
|
120
|
+
position: absolute;
|
|
121
|
+
left: 25%;
|
|
122
|
+
top: 63.333%;
|
|
123
|
+
translate: -50% -50%;
|
|
124
|
+
inline-size: max(1.5rem, var(--ui-control-min-block-size));
|
|
125
|
+
block-size: max(1.5rem, var(--ui-control-min-block-size));
|
|
126
|
+
border: 0;
|
|
127
|
+
border-radius: 50%;
|
|
128
|
+
background: transparent;
|
|
129
|
+
color: var(--ui-text-primary);
|
|
130
|
+
touch-action: none;
|
|
131
|
+
cursor: grab;
|
|
132
|
+
padding: 0 !important;
|
|
133
|
+
margin: 0 !important;
|
|
134
|
+
}
|
|
135
|
+
.second {
|
|
136
|
+
top: 33.333%;
|
|
137
|
+
}
|
|
138
|
+
.handle::after {
|
|
139
|
+
content: "";
|
|
140
|
+
position: absolute;
|
|
141
|
+
inset: 25%;
|
|
142
|
+
border: var(--ui-border-width) solid var(--ui-accent-solid);
|
|
143
|
+
background: var(--ui-surface-raised);
|
|
144
|
+
border-radius: 50%;
|
|
145
|
+
box-shadow: var(--ui-shadow-xs);
|
|
146
|
+
}
|
|
147
|
+
.handle::before {
|
|
148
|
+
content: "";
|
|
149
|
+
position: absolute;
|
|
150
|
+
inset: 40%;
|
|
151
|
+
background: var(--ui-accent-solid);
|
|
152
|
+
border-radius: 50%;
|
|
153
|
+
z-index: 1;
|
|
154
|
+
}
|
|
155
|
+
.handle:focus-visible {
|
|
156
|
+
outline: var(--ui-focus-width) solid var(--ui-control-focus, var(--ui-accent-solid));
|
|
157
|
+
outline-offset: var(--ui-space-1);
|
|
158
|
+
}
|
|
159
|
+
.handle:disabled {
|
|
160
|
+
cursor: not-allowed;
|
|
161
|
+
}
|
|
162
|
+
.coordinates {
|
|
163
|
+
display: grid !important;
|
|
164
|
+
grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
|
|
165
|
+
gap: var(--ui-space-2) !important;
|
|
166
|
+
}
|
|
167
|
+
.coordinate {
|
|
168
|
+
display: grid !important;
|
|
169
|
+
gap: var(--ui-space-1) !important;
|
|
170
|
+
font-size: var(--ui-font-size-sm);
|
|
171
|
+
}
|
|
172
|
+
output {
|
|
173
|
+
overflow-wrap: anywhere;
|
|
174
|
+
font-family: var(--ui-font-mono, monospace);
|
|
175
|
+
font-size: var(--ui-font-size-sm);
|
|
176
|
+
}
|
|
177
|
+
:host[hidden] {
|
|
178
|
+
display: none !important;
|
|
179
|
+
}
|
|
180
|
+
</style>
|
|
181
|
+
</template>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { curvePoints, curveText } from "./curve.js";
|
|
2
|
+
|
|
3
|
+
export function connect(host) {
|
|
4
|
+
const { plot, first, second, firstLine, secondLine, curve, result } = host.refs;
|
|
5
|
+
const fields = [...host.element.querySelectorAll("[data-curve-coordinate]")];
|
|
6
|
+
let points = [.25, .1, .25, 1]; let external; let drag;
|
|
7
|
+
const limit = () => { points = curvePoints(curveText(points)); };
|
|
8
|
+
const paint = () => {
|
|
9
|
+
limit();
|
|
10
|
+
const x = index => points[index] * 100;
|
|
11
|
+
const y = index => (2 - points[index]) / 3 * 100;
|
|
12
|
+
for (const [index, handle] of [[0, first], [2, second]]) {
|
|
13
|
+
handle.style.left = `${x(index)}%`; handle.style.top = `${y(index + 1)}%`;
|
|
14
|
+
handle.setAttribute("aria-description", `X ${points[index]}, Y ${points[index + 1]}`);
|
|
15
|
+
}
|
|
16
|
+
firstLine.setAttribute("d", `M0 66.667 L${x(0)} ${y(1)}`);
|
|
17
|
+
secondLine.setAttribute("d", `M100 33.333 L${x(2)} ${y(3)}`);
|
|
18
|
+
curve.setAttribute("d", `M0 66.667 C${x(0)} ${y(1)} ${x(2)} ${y(3)} 100 33.333`);
|
|
19
|
+
fields.forEach((field, index) => { host.state[`point${index}`] = String(points[index]); });
|
|
20
|
+
result.value = curveText(points); result.textContent = curveText(points);
|
|
21
|
+
};
|
|
22
|
+
const emit = type => host.dispatch(type, { value: curveText(points) });
|
|
23
|
+
const move = event => {
|
|
24
|
+
if (!drag || event.pointerId !== drag.id || host.props.disabled.value) return;
|
|
25
|
+
const rect = plot.getBoundingClientRect();
|
|
26
|
+
if (!rect.width || !rect.height) return;
|
|
27
|
+
points[drag.index] = (event.clientX - rect.left) / rect.width;
|
|
28
|
+
points[drag.index + 1] = 2 - (event.clientY - rect.top) / rect.height * 3;
|
|
29
|
+
paint(); emit("input");
|
|
30
|
+
};
|
|
31
|
+
const finish = event => { if (drag?.id !== event.pointerId) return; drag = undefined; if (!host.props.disabled.value) emit("change"); };
|
|
32
|
+
const cleanups = [];
|
|
33
|
+
for (const [index, handle] of [[0, first], [2, second]]) {
|
|
34
|
+
const down = event => { if (host.props.disabled.value || event.button !== 0) return; event.preventDefault(); handle.focus(); drag = { id: event.pointerId, index }; handle.setPointerCapture(event.pointerId); };
|
|
35
|
+
const key = event => {
|
|
36
|
+
if (host.props.disabled.value || !["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown"].includes(event.key)) return;
|
|
37
|
+
event.preventDefault(); const step = event.shiftKey ? .1 : .01;
|
|
38
|
+
points[index + (event.key === "ArrowUp" || event.key === "ArrowDown" ? 1 : 0)] += (event.key === "ArrowLeft" || event.key === "ArrowDown" ? -step : step);
|
|
39
|
+
paint(); emit("input"); emit("change");
|
|
40
|
+
};
|
|
41
|
+
for (const [type, callback] of [["pointerdown", down], ["pointermove", move], ["pointerup", finish], ["pointercancel", finish], ["keydown", key]]) {
|
|
42
|
+
handle.addEventListener(type, callback); cleanups.push(() => handle.removeEventListener(type, callback));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
fields.forEach((field, index) => {
|
|
46
|
+
const edit = event => { event.stopPropagation(); if (host.props.disabled.value) return; points[index] = Number(event.detail.value); paint(); emit(event.type); };
|
|
47
|
+
for (const type of ["input", "change"]) { field.addEventListener(type, edit); cleanups.push(() => field.removeEventListener(type, edit)); }
|
|
48
|
+
});
|
|
49
|
+
const stop = host.effect(() => { const value = host.props.value.value; if (value === external) return; external = value; try { points = curvePoints(value); } catch { /* Keep the last valid curve. */ } paint(); });
|
|
50
|
+
return () => { stop(); cleanups.forEach(cleanup => cleanup()); };
|
|
51
|
+
}
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
closerequest when modal, none when not.</prop>
|
|
14
14
|
<prop name="alert" type="boolean" default="false"
|
|
15
15
|
>Use alert dialog semantics and require an explicit action instead of the header close button. An alert dialog is always modal.</prop>
|
|
16
|
-
<prop name="size" type="keyword" values="sm, md, lg, fullscreen" default="md"
|
|
16
|
+
<prop name="size" type="keyword" values="sm, md, lg, fullscreen" default="md"
|
|
17
|
+
>Choose a compact, standard, wide, or viewport-filling dialog. Shared surface separation adapts to dialog purpose and rendered size.</prop>
|
|
17
18
|
<prop name="label" type="string">Visible title in the dialog header; also its accessible name.</prop>
|
|
18
19
|
<prop name="for" type="string" default="">ID of the control that opens the dialog.</prop>
|
|
19
20
|
<state type="boolean" name="internalOpen" value="false"></state>
|
|
@@ -75,6 +76,7 @@
|
|
|
75
76
|
}
|
|
76
77
|
|
|
77
78
|
:host {
|
|
79
|
+
--_ui-material-scale: 1;
|
|
78
80
|
/* Hooks do not inherit, so the parts below read them from the root. */
|
|
79
81
|
--_ui-dialog-duration: var(--ui-dialog-duration);
|
|
80
82
|
|
|
@@ -107,6 +109,67 @@
|
|
|
107
109
|
overlay var(--ui-dialog-duration, var(--ui-motion-base)) var(--ui-motion-ease) allow-discrete;
|
|
108
110
|
}
|
|
109
111
|
|
|
112
|
+
/* Purpose and measured size shape one shared separation lever. The content plane stays opaque;
|
|
113
|
+
transparency, saturation and edge light belong to the surrounding decorative material. */
|
|
114
|
+
:host {
|
|
115
|
+
--_ui-material-glassiness: clamp(0, var(--ui-glassiness, 0), 1);
|
|
116
|
+
--_ui-material-separation: clamp(0, var(--ui-surface-separation, 0), 1);
|
|
117
|
+
--_ui-material-active: clamp(0, calc((var(--_ui-material-glassiness) + var(--_ui-material-separation)) * 100000), 1);
|
|
118
|
+
--_ui-material-rim: calc((var(--_ui-material-separation) + var(--_ui-material-glassiness) * 0.25) * var(--_ui-material-scale, 1) * 8px);
|
|
119
|
+
--_ui-material-content-color: var(--ui-dialog-surface, var(--ui-material-content, var(--ui-overlay-surface, var(--ui-surface-elevated))));
|
|
120
|
+
--_ui-material-rim-color: color-mix(in srgb, var(--ui-material-glass, var(--ui-surface-elevated)) calc(var(--_ui-material-active) * 100%), transparent);
|
|
121
|
+
background:
|
|
122
|
+
var(--ui-surface-highlight, linear-gradient(transparent, transparent)) padding-box,
|
|
123
|
+
linear-gradient(var(--_ui-material-content-color), var(--_ui-material-content-color)) padding-box,
|
|
124
|
+
linear-gradient(var(--_ui-material-rim-color), var(--_ui-material-rim-color)) border-box,
|
|
125
|
+
var(--_ui-material-content-color) padding-box;
|
|
126
|
+
border-width: calc(var(--ui-border-width) + var(--_ui-material-rim));
|
|
127
|
+
border-color: var(
|
|
128
|
+
--ui-dialog-border,
|
|
129
|
+
color-mix(in oklab, var(--ui-overlay-border, var(--ui-border-strong)) calc((1 - var(--_ui-material-active)) * 100%), transparent)
|
|
130
|
+
);
|
|
131
|
+
box-shadow: var(
|
|
132
|
+
--ui-dialog-shadow,
|
|
133
|
+
var(
|
|
134
|
+
--ui-overlay-shadow,
|
|
135
|
+
0 calc(var(--_ui-material-separation) * var(--_ui-material-scale, 1) * 8px) calc(
|
|
136
|
+
var(--_ui-material-separation) * var(--_ui-material-scale, 1) * 24px
|
|
137
|
+
) color-mix(in oklab, var(--ui-text-primary) 15%, transparent),
|
|
138
|
+
var(--ui-material-glow, 0 0 transparent),
|
|
139
|
+
inset 0 0 0 calc(var(--_ui-material-active) * var(--ui-border-width)) var(--ui-material-edge, var(--ui-border-strong)),
|
|
140
|
+
var(--ui-elevation-dialog, var(--ui-shadow-xl))
|
|
141
|
+
)
|
|
142
|
+
);
|
|
143
|
+
backdrop-filter: blur(calc(var(--_ui-material-glassiness) * var(--_ui-material-scale, 1) * 18px))
|
|
144
|
+
saturate(calc(1 + var(--_ui-material-glassiness) * var(--_ui-material-scale, 1) * 0.18));
|
|
145
|
+
-webkit-backdrop-filter: blur(calc(var(--_ui-material-glassiness) * var(--_ui-material-scale, 1) * 18px))
|
|
146
|
+
saturate(calc(1 + var(--_ui-material-glassiness) * var(--_ui-material-scale, 1) * 0.18));
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
|
|
150
|
+
:host {
|
|
151
|
+
background: var(--_ui-material-content-color);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
@media (prefers-reduced-transparency: reduce) {
|
|
156
|
+
:host {
|
|
157
|
+
background: var(--_ui-material-content-color);
|
|
158
|
+
backdrop-filter: none;
|
|
159
|
+
-webkit-backdrop-filter: none;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
@media (forced-colors: active) {
|
|
164
|
+
:host {
|
|
165
|
+
background: Canvas;
|
|
166
|
+
border-color: CanvasText;
|
|
167
|
+
box-shadow: none;
|
|
168
|
+
backdrop-filter: none;
|
|
169
|
+
-webkit-backdrop-filter: none;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
110
173
|
:host[open] {
|
|
111
174
|
display: flex !important;
|
|
112
175
|
visibility: visible;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { updateSurfaceMaterial } from "../shared/surface-material.js";
|
|
2
|
+
import { closeDialog, closeOverlay, createIdResolver, openOverlay, observeOverlayViewport, requestTopOverlayClose, showDialog } from "../shared/overlay.js";
|
|
2
3
|
|
|
3
4
|
function inferredLabel(element, explicit) {
|
|
4
5
|
if (String(explicit ?? "").trim()) return String(explicit).trim();
|
|
@@ -18,6 +19,7 @@ function observeContentHeight(dialog, refs) {
|
|
|
18
19
|
};
|
|
19
20
|
const observer = new owner.ResizeObserver(() => {
|
|
20
21
|
if (!dialog.open) { reset(); return; }
|
|
22
|
+
updateSurfaceMaterial(dialog, "dialog");
|
|
21
23
|
const previous = animation ? parseFloat(owner.getComputedStyle(dialog).height) : lastHeight;
|
|
22
24
|
animation?.cancel();
|
|
23
25
|
animation = null;
|
|
@@ -63,6 +65,7 @@ export function connect(host) {
|
|
|
63
65
|
let lastFor = "";
|
|
64
66
|
let lastExternalOpen = Boolean(host.props.open.value);
|
|
65
67
|
let lastOpen;
|
|
68
|
+
let stopMaterialViewport = null;
|
|
66
69
|
host.state.internalOpen = lastExternalOpen;
|
|
67
70
|
|
|
68
71
|
const requestClose = (reason, input) => {
|
|
@@ -126,9 +129,13 @@ export function connect(host) {
|
|
|
126
129
|
dialog.setAttribute("closedby", closedBy);
|
|
127
130
|
if (open) {
|
|
128
131
|
showDialog(dialog, modal);
|
|
132
|
+
updateSurfaceMaterial(dialog, "dialog");
|
|
133
|
+
stopMaterialViewport ??= observeOverlayViewport(document, () => updateSurfaceMaterial(dialog, "dialog"));
|
|
129
134
|
openOverlay({ id: overlayId, modal, element, modalElement: dialog, dismissible: true, canClose: (reason) => reason === "light-dismiss" ? closedBy === "any" : reason !== "escape" || closedBy !== "none", requestClose });
|
|
130
135
|
} else {
|
|
131
136
|
resize.reset();
|
|
137
|
+
stopMaterialViewport?.();
|
|
138
|
+
stopMaterialViewport = null;
|
|
132
139
|
closeDialog(dialog);
|
|
133
140
|
closeOverlay(document, overlayId);
|
|
134
141
|
}
|
|
@@ -176,6 +183,7 @@ export function connect(host) {
|
|
|
176
183
|
ids.stop();
|
|
177
184
|
observer.disconnect();
|
|
178
185
|
resize.destroy();
|
|
186
|
+
stopMaterialViewport?.();
|
|
179
187
|
dialog?.removeEventListener("close", onClose, true);
|
|
180
188
|
dialog?.removeEventListener("cancel", onCancel);
|
|
181
189
|
closeButton?.removeEventListener("click", onCloseClick);
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
<link rel="component" href="../ui-spinner/ui-spinner.html">
|
|
2
2
|
<template component="ui-icon-button" module="./ui-icon-button.js">
|
|
3
3
|
<defs>
|
|
4
|
+
<prop name="preset" type="keyword" values="none, primary, standard, quiet, destructive" default="none"
|
|
5
|
+
>The same shortcuts as Button: primary is solid accent, standard is solid neutral, quiet is ghost neutral, and destructive is solid danger. A named preset
|
|
6
|
+
wins over variant and tone; none preserves independent choices.</prop>
|
|
7
|
+
<!-- Computed maps read every member in HTML Next. auto keeps an omitted tone concrete so the preset map can resolve, while retaining the existing variant-dependent appearance. -->
|
|
8
|
+
<computed name="appearance" from="{ none: $variant, primary: 'solid', standard: 'solid', quiet: 'ghost', destructive: 'solid' }[$preset]"></computed>
|
|
9
|
+
<computed name="colorTone" from="{ none: $tone, primary: 'accent', standard: 'neutral', quiet: 'neutral', destructive: 'danger' }[$preset]"></computed>
|
|
4
10
|
<prop name="disabled" type="boolean" default="false"
|
|
5
11
|
>Disables the button, so it cannot be pressed or focused, and gives it a flat neutral surface and muted icon.</prop>
|
|
6
12
|
<prop name="loading" type="boolean" default="false"
|
|
@@ -17,9 +23,10 @@
|
|
|
17
23
|
<prop name="variant" type="keyword" values="ghost, outline, solid" default="ghost"
|
|
18
24
|
>Emphasis. ghost shows only the icon until it is hovered, for toolbars and dense rows; outline adds a border on the default surface; solid fills with the
|
|
19
25
|
accent colour, for the one primary action in a group.</prop>
|
|
20
|
-
<prop name="tone" type="keyword" values="accent, neutral"
|
|
21
|
-
>Colour for every variant. When omitted, ghost and outline keep their neutral appearance and solid
|
|
22
|
-
or neutral for a quiet one.
|
|
26
|
+
<prop name="tone" type="keyword" values="auto, accent, neutral, danger, success, warning, info" default="auto"
|
|
27
|
+
>Colour for every variant. auto preserves the existing variant-specific default. When omitted, ghost and outline keep their neutral appearance and solid
|
|
28
|
+
keeps its accent fill. Set accent for a coloured action or neutral for a quiet one. danger, success, warning and info share Button's intent colors. Native
|
|
29
|
+
aria-pressed="true" keeps an outline toggle visibly pressed; the consumer owns that state.</prop>
|
|
23
30
|
<prop name="anticipatory" type="boolean" default="false"
|
|
24
31
|
>Keeps the button out of sight until it is wanted: at rest a fine pointer sees only a small guide dot, and the button appears on hover, on focus, or when
|
|
25
32
|
the pointer comes near inside a ui-affordance-scope. Touch devices and the solid variant always show it.</prop>
|
|
@@ -32,6 +39,8 @@
|
|
|
32
39
|
<prop name="round" type="boolean" default="false">Use a fully circular shape.</prop>
|
|
33
40
|
</defs>
|
|
34
41
|
<button
|
|
42
|
+
from:data-appearance="$appearance"
|
|
43
|
+
from:data-tone="$colorTone"
|
|
35
44
|
from:disabled="$disabled"
|
|
36
45
|
type="button"
|
|
37
46
|
from:aria-label="$label"
|
|
@@ -124,7 +133,9 @@
|
|
|
124
133
|
:host {
|
|
125
134
|
/* Optional inherited action-group values keep text and icon actions under the same light.
|
|
126
135
|
One fine top/start highlight follows the bottom/end lowlight at a joined action seam.
|
|
127
|
-
|
|
136
|
+
The shared theme supplies reflections and glow independently of the resting lift. */
|
|
137
|
+
--_tone-highlight: var(--ui-accent-highlight, none);
|
|
138
|
+
--_tone-glow: var(--ui-accent-glow, 0 0 transparent);
|
|
128
139
|
--_ui-action-start: 1px;
|
|
129
140
|
--_ui-action-edge: var(
|
|
130
141
|
--ui-action-edge,
|
|
@@ -144,7 +155,9 @@
|
|
|
144
155
|
--_ui-action-start: -1px;
|
|
145
156
|
}
|
|
146
157
|
|
|
147
|
-
:host
|
|
158
|
+
:host[data-tone="accent"] {
|
|
159
|
+
--_tone-highlight: var(--ui-accent-highlight, none);
|
|
160
|
+
--_tone-glow: var(--ui-accent-glow, 0 0 transparent);
|
|
148
161
|
--_icon-button-border: var(--ui-accent-solid);
|
|
149
162
|
--_icon-button-hover-border: var(--ui-accent-hover);
|
|
150
163
|
--_icon-button-text: var(--ui-accent-subtle-text, var(--ui-accent-solid));
|
|
@@ -152,11 +165,65 @@
|
|
|
152
165
|
color: var(--_icon-button-text);
|
|
153
166
|
}
|
|
154
167
|
|
|
168
|
+
:host[data-tone="danger"] {
|
|
169
|
+
--_tone-highlight: var(--ui-danger-highlight, none);
|
|
170
|
+
--_tone-glow: var(--ui-danger-glow, 0 0 transparent);
|
|
171
|
+
--_icon-button-border: var(--ui-danger);
|
|
172
|
+
--_icon-button-hover-border: var(--ui-danger-hover);
|
|
173
|
+
--_icon-button-text: var(--ui-danger-subtle-text);
|
|
174
|
+
--_icon-button-outline-surface: color-mix(in srgb, var(--ui-danger) 5%, var(--ui-surface-default));
|
|
175
|
+
--_icon-button-solid-surface: var(--ui-danger);
|
|
176
|
+
--_icon-button-solid-hover-surface: var(--ui-danger-hover);
|
|
177
|
+
--_icon-button-solid-text: var(--ui-danger-on-strong);
|
|
178
|
+
color: var(--_icon-button-text);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
:host[data-tone="success"] {
|
|
182
|
+
--_tone-highlight: var(--ui-success-highlight, none);
|
|
183
|
+
--_tone-glow: var(--ui-success-glow, 0 0 transparent);
|
|
184
|
+
--_icon-button-border: var(--ui-success);
|
|
185
|
+
--_icon-button-hover-border: var(--ui-success-hover);
|
|
186
|
+
--_icon-button-text: var(--ui-success-subtle-text);
|
|
187
|
+
--_icon-button-outline-surface: color-mix(in srgb, var(--ui-success) 5%, var(--ui-surface-default));
|
|
188
|
+
--_icon-button-solid-surface: var(--ui-success);
|
|
189
|
+
--_icon-button-solid-hover-surface: var(--ui-success-hover);
|
|
190
|
+
--_icon-button-solid-text: var(--ui-success-on-strong);
|
|
191
|
+
color: var(--_icon-button-text);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
:host[data-tone="warning"] {
|
|
195
|
+
--_tone-highlight: var(--ui-warning-highlight, none);
|
|
196
|
+
--_tone-glow: var(--ui-warning-glow, 0 0 transparent);
|
|
197
|
+
--_icon-button-border: var(--ui-warning);
|
|
198
|
+
--_icon-button-hover-border: var(--ui-warning-hover);
|
|
199
|
+
--_icon-button-text: var(--ui-warning-subtle-text);
|
|
200
|
+
--_icon-button-outline-surface: color-mix(in srgb, var(--ui-warning) 5%, var(--ui-surface-default));
|
|
201
|
+
--_icon-button-solid-surface: var(--ui-warning);
|
|
202
|
+
--_icon-button-solid-hover-surface: var(--ui-warning-hover);
|
|
203
|
+
--_icon-button-solid-text: var(--ui-warning-on-strong);
|
|
204
|
+
color: var(--_icon-button-text);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
:host[data-tone="info"] {
|
|
208
|
+
--_tone-highlight: var(--ui-info-highlight, none);
|
|
209
|
+
--_tone-glow: var(--ui-info-glow, 0 0 transparent);
|
|
210
|
+
--_icon-button-border: var(--ui-info);
|
|
211
|
+
--_icon-button-hover-border: var(--ui-info-hover);
|
|
212
|
+
--_icon-button-text: var(--ui-info-subtle-text);
|
|
213
|
+
--_icon-button-outline-surface: color-mix(in srgb, var(--ui-info) 5%, var(--ui-surface-default));
|
|
214
|
+
--_icon-button-solid-surface: var(--ui-info);
|
|
215
|
+
--_icon-button-solid-hover-surface: var(--ui-info-hover);
|
|
216
|
+
--_icon-button-solid-text: var(--ui-info-on-strong);
|
|
217
|
+
color: var(--_icon-button-text);
|
|
218
|
+
}
|
|
219
|
+
|
|
155
220
|
/* Omitted tone retains the existing accent solid; explicit neutral is additive. */
|
|
156
|
-
:host
|
|
157
|
-
--
|
|
158
|
-
--
|
|
159
|
-
--_icon-button-solid-
|
|
221
|
+
:host[data-tone="neutral"] {
|
|
222
|
+
--_tone-highlight: var(--ui-neutral-highlight, none);
|
|
223
|
+
--_tone-glow: var(--ui-neutral-glow, 0 0 transparent);
|
|
224
|
+
--_icon-button-solid-surface: var(--ui-neutral-surface);
|
|
225
|
+
--_icon-button-solid-hover-surface: var(--ui-neutral-hover);
|
|
226
|
+
--_icon-button-solid-text: var(--ui-text);
|
|
160
227
|
}
|
|
161
228
|
|
|
162
229
|
:host([anticipatory]) {
|
|
@@ -198,13 +265,13 @@
|
|
|
198
265
|
}
|
|
199
266
|
|
|
200
267
|
@media (hover: hover) and (pointer: fine) {
|
|
201
|
-
:host([anticipatory]):not(:host([revealed]), :host
|
|
268
|
+
:host([anticipatory]):not(:host([revealed]), :host[data-appearance="solid"], :host([loading]), :host([pending]), :disabled, [aria-pressed="true"], [data-ui-proximity="near"], :hover, :focus-visible) {
|
|
202
269
|
border-color: transparent;
|
|
203
270
|
background-color: transparent;
|
|
204
271
|
box-shadow: none;
|
|
205
272
|
}
|
|
206
273
|
|
|
207
|
-
:host([anticipatory]):not(:host([revealed]), :host
|
|
274
|
+
:host([anticipatory]):not(:host([revealed]), :host[data-appearance="solid"], :host([loading]), :host([pending]), :disabled, [aria-pressed="true"], [data-ui-proximity="near"], :hover, :focus-visible)
|
|
208
275
|
.content {
|
|
209
276
|
opacity: 0;
|
|
210
277
|
transform: scale(0.65);
|
|
@@ -212,7 +279,7 @@
|
|
|
212
279
|
}
|
|
213
280
|
}
|
|
214
281
|
|
|
215
|
-
:host([anticipatory]):is(:host([revealed]), :host
|
|
282
|
+
:host([anticipatory]):is(:host([revealed]), :host[data-appearance="solid"], [aria-pressed="true"], [data-ui-proximity="near"], :hover, :focus-visible)::before {
|
|
216
283
|
opacity: 0;
|
|
217
284
|
}
|
|
218
285
|
|
|
@@ -321,19 +388,19 @@
|
|
|
321
388
|
border-radius: var(--ui-radius-round);
|
|
322
389
|
}
|
|
323
390
|
|
|
324
|
-
:host
|
|
391
|
+
:host[data-appearance="outline"] {
|
|
325
392
|
border-color: var(--ui-icon-button-border, var(--_icon-button-border, var(--ui-control-border, var(--ui-border-strong))));
|
|
326
393
|
background-color: var(--ui-icon-button-outline-surface, var(--_icon-button-outline-surface, var(--ui-surface-default)));
|
|
327
|
-
background-image: none;
|
|
394
|
+
background-image: var(--ui-surface-highlight, none);
|
|
328
395
|
color: var(--ui-icon-button-outline-text, var(--_icon-button-text, var(--ui-text-primary)));
|
|
329
|
-
box-shadow: var(--ui-action-shadow, var(--_ui-action-shadow));
|
|
396
|
+
box-shadow: var(--ui-action-shadow, var(--_ui-action-shadow)), var(--_tone-glow);
|
|
330
397
|
}
|
|
331
398
|
|
|
332
|
-
:host
|
|
399
|
+
:host[data-appearance="solid"] {
|
|
333
400
|
background-color: var(--ui-icon-button-solid-surface, var(--_icon-button-solid-surface, var(--ui-accent-solid)));
|
|
334
|
-
background-image:
|
|
401
|
+
background-image: var(--_tone-highlight);
|
|
335
402
|
color: var(--ui-icon-button-solid-text, var(--_icon-button-solid-text, var(--ui-text-on-accent)));
|
|
336
|
-
box-shadow: var(--ui-icon-button-solid-shadow, var(--ui-action-shadow, var(--_ui-action-shadow)));
|
|
403
|
+
box-shadow: var(--ui-icon-button-solid-shadow, var(--ui-action-shadow, var(--_ui-action-shadow))), var(--_tone-glow);
|
|
337
404
|
}
|
|
338
405
|
|
|
339
406
|
:host:hover:enabled:not([aria-disabled="true"]) {
|
|
@@ -342,27 +409,26 @@
|
|
|
342
409
|
color: var(--ui-icon-button-hover-text, var(--_icon-button-text, var(--ui-text-primary)));
|
|
343
410
|
}
|
|
344
411
|
|
|
345
|
-
:host
|
|
412
|
+
:host[data-appearance="outline"]:hover:enabled:not([aria-disabled="true"]) {
|
|
346
413
|
border-color: var(--ui-icon-button-hover-border, var(--_icon-button-hover-border, var(--ui-control-border-hover, var(--ui-control-border))));
|
|
347
414
|
}
|
|
348
415
|
|
|
349
|
-
:host
|
|
416
|
+
:host[data-appearance="solid"]:hover:enabled:not([aria-disabled="true"]) {
|
|
350
417
|
background-color: var(--ui-icon-button-solid-hover-surface, var(--_icon-button-solid-hover-surface, var(--ui-accent-hover)));
|
|
351
418
|
}
|
|
352
419
|
|
|
353
|
-
:host
|
|
354
|
-
:host([variant="solid"][tone="neutral"]):hover:enabled:not([aria-disabled="true"]) {
|
|
420
|
+
:host[data-appearance="solid"]:hover:enabled:not([aria-disabled="true"]) {
|
|
355
421
|
color: var(--ui-icon-button-solid-text, var(--_icon-button-solid-text, var(--ui-text-on-accent)));
|
|
356
422
|
}
|
|
357
423
|
|
|
358
|
-
:host
|
|
424
|
+
:host[data-appearance="ghost"][aria-expanded="true"]:enabled:not([aria-disabled="true"]) {
|
|
359
425
|
background-color: var(--ui-icon-button-active-surface, color-mix(in srgb, currentColor 16%, transparent));
|
|
360
426
|
color: var(--ui-icon-button-hover-text, var(--_icon-button-text, var(--ui-text-primary)));
|
|
361
427
|
box-shadow: var(--ui-pressed);
|
|
362
428
|
}
|
|
363
429
|
|
|
364
430
|
/* Native toggle state persists after pointer release, including during loading. */
|
|
365
|
-
:host
|
|
431
|
+
:host[data-appearance="outline"][aria-pressed="true"]:enabled {
|
|
366
432
|
background-color: var(--ui-icon-button-active-surface, color-mix(in srgb, currentColor 12%, var(--ui-surface-default)));
|
|
367
433
|
background-image: none;
|
|
368
434
|
box-shadow: var(--ui-pressed);
|
|
@@ -397,35 +463,35 @@
|
|
|
397
463
|
box-shadow: var(--ui-focus-halo);
|
|
398
464
|
}
|
|
399
465
|
|
|
400
|
-
:host
|
|
466
|
+
:host[data-appearance="outline"]:focus-visible {
|
|
401
467
|
box-shadow:
|
|
402
468
|
var(--ui-action-shadow, var(--_ui-action-shadow)),
|
|
403
469
|
var(--ui-focus-halo);
|
|
404
470
|
}
|
|
405
471
|
|
|
406
|
-
:host
|
|
472
|
+
:host[data-appearance="solid"]:focus-visible {
|
|
407
473
|
box-shadow:
|
|
408
474
|
var(--ui-icon-button-solid-shadow, var(--ui-action-shadow, var(--_ui-action-shadow))),
|
|
409
475
|
var(--ui-focus-halo);
|
|
410
476
|
}
|
|
411
477
|
|
|
412
|
-
:host:is(:host
|
|
478
|
+
:host:is(:host[data-appearance="outline"], :host[data-appearance="solid"]):active:enabled:not([aria-disabled="true"]) {
|
|
413
479
|
background-image: none;
|
|
414
480
|
box-shadow: var(--ui-pressed);
|
|
415
481
|
}
|
|
416
482
|
|
|
417
|
-
:host
|
|
483
|
+
:host[data-appearance="outline"][aria-pressed="true"]:enabled:focus-visible {
|
|
418
484
|
box-shadow:
|
|
419
485
|
var(--ui-pressed),
|
|
420
486
|
var(--ui-focus-halo);
|
|
421
487
|
}
|
|
422
488
|
|
|
423
489
|
@media (forced-colors: active) {
|
|
424
|
-
:host
|
|
490
|
+
:host[data-appearance="outline"][aria-pressed="true"]:enabled {
|
|
425
491
|
outline: var(--ui-focus-width) solid Highlight;
|
|
426
492
|
outline-offset: calc(-2 * var(--ui-focus-width));
|
|
427
493
|
}
|
|
428
|
-
:host
|
|
494
|
+
:host[data-appearance="outline"][aria-pressed="true"]:enabled:focus-visible {
|
|
429
495
|
outline-offset: var(--ui-focus-width);
|
|
430
496
|
}
|
|
431
497
|
}
|
|
@@ -442,7 +508,7 @@
|
|
|
442
508
|
background-image: none;
|
|
443
509
|
}
|
|
444
510
|
|
|
445
|
-
:host
|
|
511
|
+
:host[data-appearance="ghost"]:disabled {
|
|
446
512
|
border-color: transparent;
|
|
447
513
|
}
|
|
448
514
|
|
|
@@ -108,7 +108,8 @@
|
|
|
108
108
|
border: var(--ui-input-border-width, var(--_ui-default-input-border-width, var(--ui-border-width))) solid
|
|
109
109
|
var(--ui-input-border, var(--_ui-default-input-border, var(--ui-control-border, var(--ui-border-strong))));
|
|
110
110
|
border-radius: var(--ui-input-radius, var(--_ui-default-input-radius, var(--ui-field-radius, var(--ui-radius-md))));
|
|
111
|
-
background: var(--ui-input-surface, var(--_ui-default-input-surface, var(--ui-control-surface, var(--ui-surface-elevated))));
|
|
111
|
+
background-color: var(--ui-input-surface, var(--_ui-default-input-surface, var(--ui-control-surface, var(--ui-surface-elevated))));
|
|
112
|
+
background-image: var(--_ui-default-input-highlight, var(--ui-surface-highlight, none));
|
|
112
113
|
color: var(--ui-text-primary);
|
|
113
114
|
font: inherit;
|
|
114
115
|
line-height: var(--ui-line-height-tight);
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
--_ui-default-input-focus-outline: none;
|
|
54
54
|
--_ui-default-input-radius: 0;
|
|
55
55
|
--_ui-default-input-surface: transparent;
|
|
56
|
+
--_ui-default-input-highlight: none;
|
|
56
57
|
--_ui-default-textarea-border-width: 0;
|
|
57
58
|
--_ui-default-textarea-border: transparent;
|
|
58
59
|
--_ui-default-textarea-border-hover: transparent;
|
|
@@ -64,6 +65,7 @@
|
|
|
64
65
|
--_ui-default-textarea-focus-outline: none;
|
|
65
66
|
--_ui-default-textarea-radius: 0;
|
|
66
67
|
--_ui-default-textarea-surface: transparent;
|
|
68
|
+
--_ui-default-textarea-highlight: none;
|
|
67
69
|
|
|
68
70
|
display: flex !important;
|
|
69
71
|
align-items: stretch !important;
|
|
@@ -74,7 +76,8 @@
|
|
|
74
76
|
/* The frame reads the shared control tokens with a lone Input's fallbacks, so the two match. */
|
|
75
77
|
border: var(--ui-border-width) solid var(--ui-control-border, var(--ui-border-strong));
|
|
76
78
|
border-radius: var(--ui-input-group-radius, var(--ui-field-radius, var(--ui-radius-md)));
|
|
77
|
-
background: var(--ui-control-surface, var(--ui-surface-elevated));
|
|
79
|
+
background-color: var(--ui-control-surface, var(--ui-surface-elevated));
|
|
80
|
+
background-image: var(--ui-surface-highlight, none);
|
|
78
81
|
box-shadow: var(--ui-control-inset);
|
|
79
82
|
overflow: hidden;
|
|
80
83
|
/* A press anywhere in the frame focuses the input. */
|