@threadlabs/looma 0.33.1 → 0.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/shared/overlay.js +8 -2
- package/components/shared/surface-material.js +21 -0
- package/components/ui-button/ui-button.html +63 -47
- package/components/ui-card/ui-card.html +44 -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 +62 -1
- package/components/ui-dialog/ui-dialog.js +9 -1
- package/components/ui-icon-button/ui-icon-button.html +75 -23
- package/components/ui-menu/ui-menu.html +60 -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 +62 -0
- package/components/ui-number-input/ui-number-input.js +44 -0
- package/components/ui-popover/ui-popover.html +64 -1
- package/components/ui-popover/ui-popover.js +1 -1
- package/components/ui-slider/ui-slider.html +84 -0
- package/components/ui-slider/ui-slider.js +29 -0
- package/components/ui-tabs/ui-tabs.html +6 -1
- package/components/ui-text/ui-text.html +31 -6
- package/components/ui-tooltip/ui-tooltip.html +60 -0
- package/components/ui-tooltip/ui-tooltip.js +1 -1
- package/dist/index.js +46 -43
- package/docs/README.md +34 -4
- package/docs/card.html +16 -2
- package/docs/card.js +17 -2
- package/docs/catalog.json +1154 -144
- package/docs/customizer-render.mjs +35 -9
- package/docs/customizer.js +83 -20
- package/docs/documentation.css +9 -1
- package/docs/index.d.ts +4 -2
- package/docs/index.mjs +1 -1
- package/docs/preview.js +2 -0
- package/docs/render.mjs +15 -6
- package/docs/site.mjs +50 -9
- package/docs/theme-session.mjs +51 -0
- package/docs/theme.mjs +134 -15
- package/docs/value-editors.mjs +33 -0
- package/package.json +2 -2
- package/styles/ui-button.css +45 -45
- package/styles/ui-card.css +47 -0
- package/styles/ui-curve-editor.css +109 -0
- package/styles/ui-dialog.css +132 -0
- package/styles/ui-icon-button.css +63 -20
- package/styles/ui-menu.css +72 -0
- package/styles/ui-number-input.css +34 -0
- package/styles/ui-popover.css +74 -0
- package/styles/ui-slider.css +53 -0
- package/styles/ui-tabs.css +6 -1
- package/styles/ui-text.css +23 -1
- package/styles/ui-tooltip.css +72 -0
- package/theme-system.css +26 -10
- package/tokens.css +8 -2
- package/vanilla/UiButton.d.ts +1 -0
- package/vanilla/UiButton.js +195 -130
- package/vanilla/UiCard.d.ts +1 -1
- package/vanilla/UiCard.js +1 -1
- 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/UiNumberInput.d.ts +33 -0
- package/vanilla/UiNumberInput.js +79 -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 +3 -0
- package/vue/UiButton.d.ts +6 -0
- package/vue/UiButton.vue +155 -56
- package/vue/UiCard.d.ts +2 -2
- package/vue/UiCard.vue +55 -5
- package/vue/UiCurveEditor.d.ts +53 -0
- package/vue/UiCurveEditor.js +2 -0
- package/vue/UiCurveEditor.vue +427 -0
- package/vue/UiDialog.vue +177 -1
- package/vue/UiIconButton.d.ts +8 -2
- package/vue/UiIconButton.vue +164 -34
- package/vue/UiMenu.vue +89 -0
- package/vue/UiNumberInput.d.ts +83 -0
- package/vue/UiNumberInput.js +2 -0
- package/vue/UiNumberInput.vue +370 -0
- package/vue/UiPopover.vue +92 -1
- package/vue/UiSlider.d.ts +83 -0
- package/vue/UiSlider.js +2 -0
- package/vue/UiSlider.vue +412 -0
- package/vue/UiTabs.vue +6 -1
- package/vue/UiText.d.ts +7 -5
- package/vue/UiText.vue +104 -22
- 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 +2 -2
- 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 +6 -5
- package/vue/chunks/UiCheckbox.js +2 -2
- 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 +2 -2
- package/vue/chunks/UiInputGroup.js +2 -2
- 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 +390 -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 +2 -2
- 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 +2 -2
- 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 +2 -2
- 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 +2215 -1203
- package/vue/editor/index.js +623 -211
- package/vue/index.d.ts +3 -0
- package/vue/index.js +5 -2
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
<prop name="bare" type="boolean" default="false"
|
|
4
4
|
>Delegates the surface to its content, with no padding, border, background, shadow, or overflow clipping.</prop>
|
|
5
5
|
<prop name="size" type="keyword" values="content, sm, md, lg" default="content"
|
|
6
|
-
>Optional size preset. content keeps the existing intrinsic sizing; the other sizes constrain the surface for compact, medium, or large content
|
|
6
|
+
>Optional size preset. content keeps the existing intrinsic sizing; the other sizes constrain the surface for compact, medium, or large content. Shared
|
|
7
|
+
surface separation adapts to popover purpose and rendered size.</prop>
|
|
7
8
|
<prop name="open" type="boolean" default="false">Whether the popover is open initially or when set externally.</prop>
|
|
8
9
|
<prop name="for" type="string" default="">ID of the control that toggles and anchors the popover.</prop>
|
|
9
10
|
<prop
|
|
@@ -63,6 +64,7 @@
|
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
:host {
|
|
67
|
+
--_ui-material-scale: 0.55;
|
|
66
68
|
--_ui-popover-surface: var(--ui-popover-surface);
|
|
67
69
|
--_ui-popover-border: var(--ui-popover-border);
|
|
68
70
|
--_ui-popover-radius: var(--ui-popover-radius);
|
|
@@ -95,6 +97,65 @@
|
|
|
95
97
|
box-shadow: var(--_ui-popover-shadow, var(--ui-overlay-shadow, var(--ui-elevation-overlay, var(--ui-shadow-lg))));
|
|
96
98
|
}
|
|
97
99
|
|
|
100
|
+
/* Purpose and measured size shape one shared separation lever. The content plane stays opaque;
|
|
101
|
+
transparency, saturation and edge light belong to the surrounding decorative material. */
|
|
102
|
+
.surface {
|
|
103
|
+
--_ui-material-glassiness: clamp(0, var(--ui-glassiness, 0), 1);
|
|
104
|
+
--_ui-material-separation: clamp(0, var(--ui-surface-separation, 0), 1);
|
|
105
|
+
--_ui-material-active: clamp(0, calc((var(--_ui-material-glassiness) + var(--_ui-material-separation)) * 100000), 1);
|
|
106
|
+
--_ui-material-rim: calc((var(--_ui-material-separation) + var(--_ui-material-glassiness) * 0.25) * var(--_ui-material-scale, 0.55) * 8px);
|
|
107
|
+
--_ui-material-content-color: var(--_ui-popover-surface, var(--ui-material-content, var(--ui-overlay-surface, var(--ui-surface-elevated))));
|
|
108
|
+
--_ui-material-rim-color: color-mix(in srgb, var(--ui-material-glass, var(--ui-surface-elevated)) calc(var(--_ui-material-active) * 100%), transparent);
|
|
109
|
+
background:
|
|
110
|
+
linear-gradient(var(--_ui-material-content-color), var(--_ui-material-content-color)) padding-box,
|
|
111
|
+
linear-gradient(var(--_ui-material-rim-color), var(--_ui-material-rim-color)) border-box,
|
|
112
|
+
var(--_ui-material-content-color) padding-box;
|
|
113
|
+
border-width: calc(var(--ui-border-width) + var(--_ui-material-rim));
|
|
114
|
+
border-color: var(
|
|
115
|
+
--_ui-popover-border,
|
|
116
|
+
color-mix(in oklab, var(--ui-overlay-border, var(--ui-border-strong)) calc((1 - var(--_ui-material-active)) * 100%), transparent)
|
|
117
|
+
);
|
|
118
|
+
box-shadow: var(
|
|
119
|
+
--_ui-popover-shadow,
|
|
120
|
+
var(
|
|
121
|
+
--ui-overlay-shadow,
|
|
122
|
+
0 calc(var(--_ui-material-separation) * var(--_ui-material-scale, 0.55) * 8px) calc(
|
|
123
|
+
var(--_ui-material-separation) * var(--_ui-material-scale, 0.55) * 24px
|
|
124
|
+
) color-mix(in oklab, var(--ui-text-primary) 15%, transparent),
|
|
125
|
+
inset 0 0 0 calc(var(--_ui-material-active) * var(--ui-border-width)) var(--ui-material-edge, var(--ui-border-strong)),
|
|
126
|
+
var(--ui-elevation-overlay, var(--ui-shadow-lg))
|
|
127
|
+
)
|
|
128
|
+
);
|
|
129
|
+
backdrop-filter: blur(calc(var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.55) * 18px))
|
|
130
|
+
saturate(calc(1 + var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.55) * 0.18));
|
|
131
|
+
-webkit-backdrop-filter: blur(calc(var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.55) * 18px))
|
|
132
|
+
saturate(calc(1 + var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.55) * 0.18));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
|
|
136
|
+
.surface {
|
|
137
|
+
background: var(--_ui-material-content-color);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
@media (prefers-reduced-transparency: reduce) {
|
|
142
|
+
.surface {
|
|
143
|
+
background: var(--_ui-material-content-color);
|
|
144
|
+
backdrop-filter: none;
|
|
145
|
+
-webkit-backdrop-filter: none;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
@media (forced-colors: active) {
|
|
150
|
+
.surface {
|
|
151
|
+
background: Canvas;
|
|
152
|
+
border-color: CanvasText;
|
|
153
|
+
box-shadow: none;
|
|
154
|
+
backdrop-filter: none;
|
|
155
|
+
-webkit-backdrop-filter: none;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
98
159
|
/* A toolbar or card can supply its own surface, including an unclipped shadow. */
|
|
99
160
|
:host([bare]) .surface {
|
|
100
161
|
overflow: visible;
|
|
@@ -102,6 +163,8 @@
|
|
|
102
163
|
border: 0;
|
|
103
164
|
background: transparent;
|
|
104
165
|
box-shadow: none;
|
|
166
|
+
backdrop-filter: none;
|
|
167
|
+
-webkit-backdrop-filter: none;
|
|
105
168
|
}
|
|
106
169
|
|
|
107
170
|
:host(:not(:state(internalOpen))) {
|
|
@@ -59,7 +59,7 @@ export function connect(host) {
|
|
|
59
59
|
anchor = ids.get(nextFor);
|
|
60
60
|
if (anchor) anchorExpanded = anchor.getAttribute("aria-expanded");
|
|
61
61
|
anchor?.addEventListener("click", onAnchorClick);
|
|
62
|
-
surface = createAnchoredSurface(element, { anchor, placement: nextPlacement, gap: offset });
|
|
62
|
+
surface = createAnchoredSurface(element, { anchor, placement: nextPlacement, gap: offset, materialRole: "popover" });
|
|
63
63
|
};
|
|
64
64
|
const apply = () => {
|
|
65
65
|
const externalOpen = Boolean(host.props.open.value);
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
<link rel="component" href="../ui-number-input/ui-number-input.html">
|
|
2
|
+
<template component="ui-slider" module="./ui-slider.js">
|
|
3
|
+
<defs>
|
|
4
|
+
<state name="current" type="number" from="$value"></state>
|
|
5
|
+
<prop name="value" type="number" default="0">Current numeric value. Native range and exact entry share bounds.</prop>
|
|
6
|
+
<prop name="min" type="number" default="0">Inclusive lower bound for dragging, keyboard steps and exact entry.</prop>
|
|
7
|
+
<prop name="max" type="number" default="100">Inclusive upper bound for dragging, keyboard steps and exact entry.</prop>
|
|
8
|
+
<prop name="step" type="number" default="1">Positive native range and exact entry increment.</prop>
|
|
9
|
+
<prop name="unit" type="string" default="">Unit shown by the exact editor.</prop>
|
|
10
|
+
<prop name="name" type="string" default="">Optional numeric form field name.</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="number" required></prop></event>
|
|
15
|
+
<event name="change" type="object"><prop name="value" type="number" required></prop></event>
|
|
16
|
+
</defs>
|
|
17
|
+
<span>
|
|
18
|
+
<input
|
|
19
|
+
$ref="range"
|
|
20
|
+
type="range"
|
|
21
|
+
data-ui-field-control
|
|
22
|
+
from:aria-label="$label"
|
|
23
|
+
from:aria-valuetext="concat($current, $unit)"
|
|
24
|
+
from:value="$value"
|
|
25
|
+
from:min="$min"
|
|
26
|
+
from:max="$max"
|
|
27
|
+
from:step="$step"
|
|
28
|
+
from:disabled="$disabled"
|
|
29
|
+
from:name="$name"
|
|
30
|
+
>
|
|
31
|
+
<ui-number-input
|
|
32
|
+
data-slider-exact
|
|
33
|
+
from:value="concat($current, $unit)"
|
|
34
|
+
from:unit="$unit"
|
|
35
|
+
from:min="$min"
|
|
36
|
+
from:max="$max"
|
|
37
|
+
from:step="$step"
|
|
38
|
+
from:size="$size"
|
|
39
|
+
from:disabled="$disabled"
|
|
40
|
+
from:label="$label"
|
|
41
|
+
></ui-number-input>
|
|
42
|
+
</span>
|
|
43
|
+
<style>
|
|
44
|
+
:host {
|
|
45
|
+
display: grid !important;
|
|
46
|
+
grid-template-columns: minmax(4rem, 1fr) minmax(8rem, 1fr) !important;
|
|
47
|
+
align-items: center !important;
|
|
48
|
+
gap: var(--ui-space-2) !important;
|
|
49
|
+
margin: 0 !important;
|
|
50
|
+
padding: 0 !important;
|
|
51
|
+
min-inline-size: 0;
|
|
52
|
+
}
|
|
53
|
+
input {
|
|
54
|
+
inline-size: 100%;
|
|
55
|
+
min-inline-size: 0;
|
|
56
|
+
min-block-size: var(--ui-control-size-md);
|
|
57
|
+
margin: 0 !important;
|
|
58
|
+
accent-color: var(--ui-accent-solid);
|
|
59
|
+
cursor: pointer;
|
|
60
|
+
}
|
|
61
|
+
:host([size="sm"]) input {
|
|
62
|
+
min-block-size: var(--ui-control-size-sm);
|
|
63
|
+
}
|
|
64
|
+
:host([size="lg"]) input {
|
|
65
|
+
min-block-size: var(--ui-control-size-lg);
|
|
66
|
+
}
|
|
67
|
+
input:focus-visible {
|
|
68
|
+
outline: var(--ui-focus-width) solid var(--ui-control-focus, var(--ui-accent-solid));
|
|
69
|
+
outline-offset: var(--ui-space-1);
|
|
70
|
+
border-radius: var(--ui-radius-sm);
|
|
71
|
+
}
|
|
72
|
+
input:disabled {
|
|
73
|
+
cursor: not-allowed;
|
|
74
|
+
}
|
|
75
|
+
@media (pointer: coarse) {
|
|
76
|
+
input {
|
|
77
|
+
min-block-size: max(var(--ui-control-size-md), var(--ui-control-min-block-size));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
:host[hidden] {
|
|
81
|
+
display: none !important;
|
|
82
|
+
}
|
|
83
|
+
</style>
|
|
84
|
+
</template>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { boundedNumber, calculateValue } from "../ui-number-input/arithmetic.js";
|
|
2
|
+
import { afterFormReset } from "../shared/form-reset.js";
|
|
3
|
+
|
|
4
|
+
export function connect(host) {
|
|
5
|
+
const { range } = host.refs;
|
|
6
|
+
const exact = host.element.querySelector("[data-slider-exact]");
|
|
7
|
+
let external;
|
|
8
|
+
const paint = value => {
|
|
9
|
+
range.value = String(boundedNumber(value, host.props.min.value, host.props.max.value));
|
|
10
|
+
host.state.current = Number(range.value);
|
|
11
|
+
};
|
|
12
|
+
const edit = event => {
|
|
13
|
+
event.stopPropagation();
|
|
14
|
+
if (host.props.disabled.value) return;
|
|
15
|
+
const raw = event.currentTarget === range ? Number(range.value) : calculateValue(event.detail.value, host.props.unit.value || "");
|
|
16
|
+
paint(raw); host.dispatch(event.type, { value: Number(range.value) });
|
|
17
|
+
};
|
|
18
|
+
for (const field of [range, exact]) for (const type of ["input", "change"]) field.addEventListener(type, edit);
|
|
19
|
+
const stop = host.effect(() => {
|
|
20
|
+
const signature = JSON.stringify([host.props.value.value, host.props.min.value, host.props.max.value, host.props.step.value]);
|
|
21
|
+
if (external === signature) return; external = signature;
|
|
22
|
+
range.min = String(Math.min(Number(host.props.min.value), Number(host.props.max.value)));
|
|
23
|
+
range.max = String(Math.max(Number(host.props.min.value), Number(host.props.max.value)));
|
|
24
|
+
range.step = String(Math.abs(Number(host.props.step.value)) || 1);
|
|
25
|
+
range.defaultValue = String(host.props.value.value); paint(Number(host.props.value.value));
|
|
26
|
+
});
|
|
27
|
+
const reset = afterFormReset(range, () => paint(Number(range.defaultValue)));
|
|
28
|
+
return () => { stop(); reset(); for (const field of [range, exact]) for (const type of ["input", "change"]) field.removeEventListener(type, edit); };
|
|
29
|
+
}
|
|
@@ -59,6 +59,10 @@
|
|
|
59
59
|
syntax: "*";
|
|
60
60
|
inherits: false;
|
|
61
61
|
}
|
|
62
|
+
@property --ui-tabs-panel-padding {
|
|
63
|
+
syntax: "*";
|
|
64
|
+
inherits: false;
|
|
65
|
+
}
|
|
62
66
|
|
|
63
67
|
/* Density resolves into the tab row's own values; the public tokens still override them. */
|
|
64
68
|
:host {
|
|
@@ -66,6 +70,7 @@
|
|
|
66
70
|
--_ui-tabs-tab-min-block-size: var(--ui-tabs-tab-min-block-size);
|
|
67
71
|
--_ui-tabs-tab-padding-block: var(--ui-tabs-tab-padding-block);
|
|
68
72
|
--_ui-tabs-tab-padding-inline: var(--ui-tabs-tab-padding-inline);
|
|
73
|
+
--_ui-tabs-panel-padding: var(--ui-tabs-panel-padding);
|
|
69
74
|
|
|
70
75
|
--_tab-min-block-size: var(--ui-control-size);
|
|
71
76
|
--_tab-padding-block: var(--ui-space-2);
|
|
@@ -165,7 +170,7 @@
|
|
|
165
170
|
min-inline-size: 0;
|
|
166
171
|
}
|
|
167
172
|
.panels > :slotted(*) {
|
|
168
|
-
padding: var(--ui-space-4) !important;
|
|
173
|
+
padding: var(--_ui-tabs-panel-padding, var(--ui-space-4)) !important;
|
|
169
174
|
}
|
|
170
175
|
|
|
171
176
|
:host([orientation="vertical"]) {
|
|
@@ -17,14 +17,16 @@
|
|
|
17
17
|
does not carry the meaning, so the words must say it too.</prop>
|
|
18
18
|
<prop name="weight" type="keyword" values="inherit, normal, medium, semibold" default="inherit"
|
|
19
19
|
>The weight. inherit keeps the surrounding weight; medium and semibold emphasise a name or a figure.</prop>
|
|
20
|
-
<prop name="variant" type="keyword" values="body, eyebrow, code" default="body"
|
|
21
|
-
>body is running text.
|
|
22
|
-
|
|
20
|
+
<prop name="variant" type="keyword" values="body, display, heading, label, caption, eyebrow, code" default="body"
|
|
21
|
+
>body is running text. display is a page title, heading names a section, label identifies a control, and caption is supporting text. These roles set their
|
|
22
|
+
shared type scale, weight and leading; pair heading or display with an appropriate as heading element. eyebrow is a short, uppercase, tracked label that
|
|
23
|
+
names what follows, such as a group of links; code sets a value to copy or read exactly, such as an address, in the monospace face.</prop>
|
|
23
24
|
<prop name="truncate" type="boolean" default="false">Keeps the text on one line, ending in an ellipsis when it does not fit.</prop>
|
|
24
25
|
<prop name="align" type="keyword" values="start, center" default="start">Aligns the text within its line.</prop>
|
|
25
|
-
<prop name="as" type="keyword" values="p, span, div, small, strong, label, h2, h3, h4, h5, h6" default="p"
|
|
26
|
+
<prop name="as" type="keyword" values="p, span, div, small, strong, label, h1, h2, h3, h4, h5, h6" default="p"
|
|
26
27
|
>The native element the text renders: a paragraph by default, inline span, small, or strong within a line, a div for a block, a label for a control, or a
|
|
27
|
-
heading,
|
|
28
|
+
heading, h1 to h6. Choose its document level independently from its visual variant. The default body variant keeps the existing size and weight
|
|
29
|
+
behavior.</prop>
|
|
28
30
|
</defs>
|
|
29
31
|
<template $match>
|
|
30
32
|
<span $when="$as = 'span'"><slot></slot></span>
|
|
@@ -32,6 +34,7 @@
|
|
|
32
34
|
<small $when="$as = 'small'"><slot></slot></small>
|
|
33
35
|
<strong $when="$as = 'strong'"><slot></slot></strong>
|
|
34
36
|
<label $when="$as = 'label'"><slot></slot></label>
|
|
37
|
+
<h1 $when="$as = 'h1'"><slot></slot></h1>
|
|
35
38
|
<h2 $when="$as = 'h2'"><slot></slot></h2>
|
|
36
39
|
<h3 $when="$as = 'h3'"><slot></slot></h3>
|
|
37
40
|
<h4 $when="$as = 'h4'"><slot></slot></h4>
|
|
@@ -56,7 +59,7 @@
|
|
|
56
59
|
|
|
57
60
|
/* A heading drops the browser's heading size and weight, so size and weight set it as they set
|
|
58
61
|
any text, and inherit keeps the text around it. */
|
|
59
|
-
:host:is(h2, h3, h4, h5, h6) {
|
|
62
|
+
:host:is(h1, h2, h3, h4, h5, h6) {
|
|
60
63
|
font-family: var(--ui-font-display, inherit);
|
|
61
64
|
font-size: inherit;
|
|
62
65
|
font-weight: inherit;
|
|
@@ -119,10 +122,32 @@
|
|
|
119
122
|
font-weight: var(--ui-font-semibold);
|
|
120
123
|
}
|
|
121
124
|
|
|
125
|
+
:host([variant="display"]), :host([variant="heading"]) {
|
|
126
|
+
font-family: var(--ui-font-display, var(--ui-font-family-sans));
|
|
127
|
+
font-weight: var(--ui-font-semibold);
|
|
128
|
+
line-height: var(--ui-line-height-tight);
|
|
129
|
+
}
|
|
130
|
+
:host([variant="display"]) {
|
|
131
|
+
font-size: var(--ui-font-size-2xl);
|
|
132
|
+
}
|
|
133
|
+
:host([variant="heading"]) {
|
|
134
|
+
font-size: var(--ui-font-size-xl);
|
|
135
|
+
}
|
|
136
|
+
:host([variant="label"]) {
|
|
137
|
+
font-size: var(--ui-font-size-sm);
|
|
138
|
+
font-weight: var(--ui-font-medium);
|
|
139
|
+
line-height: var(--ui-line-height);
|
|
140
|
+
}
|
|
141
|
+
:host([variant="caption"]) {
|
|
142
|
+
font-size: var(--ui-font-size-sm);
|
|
143
|
+
line-height: var(--ui-line-height);
|
|
144
|
+
}
|
|
145
|
+
|
|
122
146
|
:host([variant="eyebrow"]) {
|
|
123
147
|
font-size: var(--ui-font-size-xs);
|
|
124
148
|
font-weight: var(--ui-font-semibold);
|
|
125
149
|
letter-spacing: 0.06em;
|
|
150
|
+
line-height: var(--ui-line-height);
|
|
126
151
|
text-transform: uppercase;
|
|
127
152
|
}
|
|
128
153
|
:host([variant="code"]) {
|
|
@@ -81,6 +81,7 @@
|
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
:host {
|
|
84
|
+
--_ui-material-scale: 0.08;
|
|
84
85
|
/* Hooks do not inherit, so the parts below read them from the root. */
|
|
85
86
|
--_ui-tooltip-border: var(--ui-tooltip-border);
|
|
86
87
|
--_ui-tooltip-max-inline-size: var(--ui-tooltip-max-inline-size);
|
|
@@ -133,6 +134,65 @@
|
|
|
133
134
|
box-shadow: var(--_ui-tooltip-shadow, var(--ui-overlay-shadow, var(--ui-elevation-tooltip, var(--ui-shadow-md))));
|
|
134
135
|
}
|
|
135
136
|
|
|
137
|
+
/* Purpose and measured size shape one shared separation lever. The content plane stays opaque;
|
|
138
|
+
transparency, saturation and edge light belong to the surrounding decorative material. */
|
|
139
|
+
.surface {
|
|
140
|
+
--_ui-material-glassiness: clamp(0, var(--ui-glassiness, 0), 1);
|
|
141
|
+
--_ui-material-separation: clamp(0, var(--ui-surface-separation, 0), 1);
|
|
142
|
+
--_ui-material-active: clamp(0, calc((var(--_ui-material-glassiness) + var(--_ui-material-separation)) * 100000), 1);
|
|
143
|
+
--_ui-material-rim: calc((var(--_ui-material-separation) + var(--_ui-material-glassiness) * 0.25) * var(--_ui-material-scale, 0.08) * 8px);
|
|
144
|
+
--_ui-material-content-color: var(--_ui-tooltip-surface, var(--ui-material-content, var(--ui-overlay-surface, var(--ui-surface-elevated))));
|
|
145
|
+
--_ui-material-rim-color: color-mix(in srgb, var(--ui-material-glass, var(--ui-surface-elevated)) calc(var(--_ui-material-active) * 100%), transparent);
|
|
146
|
+
background:
|
|
147
|
+
linear-gradient(var(--_ui-material-content-color), var(--_ui-material-content-color)) padding-box,
|
|
148
|
+
linear-gradient(var(--_ui-material-rim-color), var(--_ui-material-rim-color)) border-box,
|
|
149
|
+
var(--_ui-material-content-color) padding-box;
|
|
150
|
+
border-width: calc(var(--ui-border-width) + var(--_ui-material-rim));
|
|
151
|
+
border-color: var(
|
|
152
|
+
--_ui-tooltip-border,
|
|
153
|
+
color-mix(in oklab, var(--ui-overlay-border, var(--ui-border-strong)) calc((1 - var(--_ui-material-active)) * 100%), transparent)
|
|
154
|
+
);
|
|
155
|
+
box-shadow: var(
|
|
156
|
+
--_ui-tooltip-shadow,
|
|
157
|
+
var(
|
|
158
|
+
--ui-overlay-shadow,
|
|
159
|
+
0 calc(var(--_ui-material-separation) * var(--_ui-material-scale, 0.08) * 8px) calc(
|
|
160
|
+
var(--_ui-material-separation) * var(--_ui-material-scale, 0.08) * 24px
|
|
161
|
+
) color-mix(in oklab, var(--ui-text-primary) 15%, transparent),
|
|
162
|
+
inset 0 0 0 calc(var(--_ui-material-active) * var(--ui-border-width)) var(--ui-material-edge, var(--ui-border-strong)),
|
|
163
|
+
var(--ui-elevation-tooltip, var(--ui-shadow-md))
|
|
164
|
+
)
|
|
165
|
+
);
|
|
166
|
+
backdrop-filter: blur(calc(var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.08) * 18px))
|
|
167
|
+
saturate(calc(1 + var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.08) * 0.18));
|
|
168
|
+
-webkit-backdrop-filter: blur(calc(var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.08) * 18px))
|
|
169
|
+
saturate(calc(1 + var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.08) * 0.18));
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
|
|
173
|
+
.surface {
|
|
174
|
+
background: var(--_ui-material-content-color);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
@media (prefers-reduced-transparency: reduce) {
|
|
179
|
+
.surface {
|
|
180
|
+
background: var(--_ui-material-content-color);
|
|
181
|
+
backdrop-filter: none;
|
|
182
|
+
-webkit-backdrop-filter: none;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
@media (forced-colors: active) {
|
|
187
|
+
.surface {
|
|
188
|
+
background: Canvas;
|
|
189
|
+
border-color: CanvasText;
|
|
190
|
+
box-shadow: none;
|
|
191
|
+
backdrop-filter: none;
|
|
192
|
+
-webkit-backdrop-filter: none;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
136
196
|
/* A keyboard shortcut follows the label after a thin divider, smaller and quieter, as menus show
|
|
137
197
|
it. The label stays first in the description, so a screen reader hears the name, then the keys. */
|
|
138
198
|
.shortcut {
|
|
@@ -160,7 +160,7 @@ export function connect(host) {
|
|
|
160
160
|
attach();
|
|
161
161
|
}
|
|
162
162
|
surface?.destroy();
|
|
163
|
-
surface = createAnchoredSurface(element, { anchor: trigger, placement: nextPlacement, gap: offset });
|
|
163
|
+
surface = createAnchoredSurface(element, { anchor: trigger, placement: nextPlacement, gap: offset, materialRole: "tooltip" });
|
|
164
164
|
};
|
|
165
165
|
const close = (reason, input) => {
|
|
166
166
|
if (reason !== "escape" && reason !== "light-dismiss" && reason !== "programmatic") return;
|