feat(ui): component redesign pass and fixes, release ui 0.8.87
Redesign - Shared field foundation rules (duplicated across 15 form components and emitted globally) are now identical everywhere, so later copies no longer silently override earlier redesigns. - Drawn checkbox and radio controls, white switch thumbs (the thumb was the text colour, a black blob in light mode), recessed field wells, keycap actions in Modal, Drawer, Popover, Toaster, Pagination, Stepper, DataTable. - Menus (Dropdown, ContextMenu, Popover, Select dropdown, Navbar panels) share one flat raised panel with neutral hover rows and mono section labels. - Alerts with an accent rail and icon chip; card headers without the grey band; accordion, collapse, list, list group, timeline, stats, metrics, chat, skeleton, avatar group, clipboard, splitter, section, sidebar, navbar and upload progress restyled. - Chart rebuilt: nice y-axis ticks, gridlines, rounded bars, line and area modes, hover tooltips, hidden series leave the scale. Fixes - Checkbox and radio labels toggle their input again (empty for="" broke it). - TimePicker kept every clicked time pressed; only the chosen hour and minute are pressed now, and nothing is pressed before a value exists. - ColorPicker hex readout now follows the picked colour. - Disabled FileInput no longer shows the native file-input text. - Date and time panels float instead of pushing content. - ContextMenu opened at the pointer closes on scroll. - Drawer left/top/bottom placements slide from their own edge again. - Image-only Card no longer renders an empty body strip. - Timeline supports item.time, current/upcoming states, sizes and compact/alternate variants; showcase demos use distinct variants. - ChatBubble: delivery receipts (sending/sent/delivered/read/failed/error) and meta aligned to its bubble. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
5eae6f3b3c
commit
1bed8e4b74
93 files changed
+4439
-1915
No files matched your search
@@ -26,16 +26,86 @@ component Chart {
|
||||
|
||||
functions {
|
||||
shared function chartData() { return data.length ? data : items }
|
||||
shared function linePoints() { return chartData().map(function (item, index) { return (barX(index) + barWidth() / 2) + "," + barY(item) }).join(" ") }
|
||||
shared function chartKind() { var kind = type || variant; return kind === "line" || kind === "area" ? kind : "bar" }
|
||||
shared function numericValue(item) { return Math.max(0, Number(item[valueKey]) || 0) }
|
||||
shared function maximumValue() {
|
||||
return Math.max(1, ...chartData().map(function (item) { return numericValue(item) }))
|
||||
}
|
||||
shared function isHidden(index) { return hiddenIndexes.includes(index) }
|
||||
shared function barWidth() { return chartData().length ? Math.max(4, 400 / chartData().length) : 400 }
|
||||
shared function barX(index) { return 50 + index * (500 / Math.max(1, chartData().length)) }
|
||||
shared function barHeight(item) { return numericValue(item) / maximumValue() * 160 }
|
||||
shared function barY(item) { return 200 - barHeight(item) }
|
||||
|
||||
// Visible points keep their original index so events report the source item.
|
||||
shared function points() {
|
||||
var source = chartData()
|
||||
var visible = []
|
||||
for (var index = 0; index < source.length; index++) {
|
||||
if (!hiddenIndexes.includes(index)) { visible.push({ item: source[index], index: index }) }
|
||||
}
|
||||
return visible
|
||||
}
|
||||
|
||||
// Plot geometry in viewBox units: 600 wide, height tall.
|
||||
shared function plotLeft() { return 44 }
|
||||
shared function plotRight() { return 588 }
|
||||
shared function plotTop() { return 14 }
|
||||
shared function plotBottom() { return Math.max(120, height) - 30 }
|
||||
|
||||
// Round the scale up to a readable value so the ticks land on clean numbers.
|
||||
shared function niceMax() {
|
||||
var max = 0
|
||||
var visible = points()
|
||||
for (var index = 0; index < visible.length; index++) { max = Math.max(max, numericValue(visible[index].item)) }
|
||||
if (max <= 0) { return 1 }
|
||||
var magnitude = Math.pow(10, Math.floor(Math.log10(max)))
|
||||
var steps = [1, 2, 2.5, 5, 10]
|
||||
var chosen = 10 * magnitude
|
||||
for (var step = steps.length - 1; step >= 0; step--) {
|
||||
if (steps[step] * magnitude >= max) { chosen = steps[step] * magnitude }
|
||||
}
|
||||
return chosen
|
||||
}
|
||||
shared function ticks() {
|
||||
var top = niceMax()
|
||||
return [0, top * 0.25, top * 0.5, top * 0.75, top]
|
||||
}
|
||||
shared function tickLabel(value) {
|
||||
if (value >= 1000000) { return (value / 1000000).toFixed(value % 1000000 ? 1 : 0) + "M" }
|
||||
if (value >= 1000) { return (value / 1000).toFixed(value % 1000 ? 1 : 0) + "k" }
|
||||
return String(Math.round(value * 100) / 100)
|
||||
}
|
||||
shared function yFor(value) { return plotTop() + (1 - value / niceMax()) * (plotBottom() - plotTop()) }
|
||||
|
||||
shared function band() { return (plotRight() - plotLeft()) / Math.max(1, points().length) }
|
||||
shared function barWidth() { return Math.min(band() * 0.62, 56) }
|
||||
shared function centerX(position) { return plotLeft() + position * band() + band() / 2 }
|
||||
|
||||
// Bars: 4px rounded data end, square at the baseline.
|
||||
shared function barPath(point, position) {
|
||||
var width = barWidth()
|
||||
var x = centerX(position) - width / 2
|
||||
var y = yFor(numericValue(point.item))
|
||||
var base = plotBottom()
|
||||
var radius = Math.min(4, (base - y) / 2, width / 2)
|
||||
if (base - y < 1) { return "M" + x + "," + (base - 1) + "h" + width + "v1h-" + width + "Z" }
|
||||
return "M" + x + "," + base + "V" + (y + radius) + "Q" + x + "," + y + " " + (x + radius) + "," + y + "H" + (x + width - radius) + "Q" + (x + width) + "," + y + " " + (x + width) + "," + (y + radius) + "V" + base + "Z"
|
||||
}
|
||||
shared function linePath() {
|
||||
var visible = points()
|
||||
var path = ""
|
||||
for (var position = 0; position < visible.length; position++) {
|
||||
path = path + (position ? "L" : "M") + centerX(position) + "," + yFor(numericValue(visible[position].item))
|
||||
}
|
||||
return path
|
||||
}
|
||||
shared function areaPath() {
|
||||
var visible = points()
|
||||
if (!visible.length) { return "" }
|
||||
return linePath() + "L" + centerX(visible.length - 1) + "," + plotBottom() + "L" + centerX(0) + "," + plotBottom() + "Z"
|
||||
}
|
||||
|
||||
// Hit targets and tooltips are HTML laid over the SVG, positioned in %.
|
||||
shared function hitStyle(position) {
|
||||
return "left:" + ((plotLeft() + position * band()) / 600 * 100) + "%;width:" + (band() / 600 * 100) + "%;top:" + (plotTop() / Math.max(120, height) * 100) + "%;height:" + ((plotBottom() - plotTop()) / Math.max(120, height) * 100) + "%"
|
||||
}
|
||||
shared function tipStyle(point) {
|
||||
return "top:" + ((yFor(numericValue(point.item)) - plotTop()) / (plotBottom() - plotTop()) * 100) + "%"
|
||||
}
|
||||
|
||||
client function selectPoint(item, index, sourceEvent) {
|
||||
output.dataPointClick({ item: item, index: index, sourceEvent: sourceEvent })
|
||||
@@ -43,39 +113,63 @@ component Chart {
|
||||
}
|
||||
|
||||
client function toggleLegend(item, index, sourceEvent, next) {
|
||||
next = hiddenIndexes.slice()
|
||||
if (next.includes(index)) {
|
||||
next = next.filter(function (value) { return value !== index })
|
||||
} else {
|
||||
next.push(index)
|
||||
next = []
|
||||
for (var position = 0; position < hiddenIndexes.length; position++) {
|
||||
if (hiddenIndexes[position] !== index) { next.push(hiddenIndexes[position]) }
|
||||
}
|
||||
if (next.length === hiddenIndexes.length) { next.push(index) }
|
||||
hiddenIndexes = next
|
||||
output.legendToggle({ item: item, index: index, hidden: next.includes(index), sourceEvent: sourceEvent })
|
||||
}
|
||||
}
|
||||
|
||||
view {
|
||||
<figure {...attrs} data-ui-component="Chart" data-variant='{variant}' class='wrn-chart {class}'>
|
||||
<figure {...attrs} data-ui-component="Chart" data-variant='{chartKind()}' data-size='{size}' data-color='{color}' class='wrn-chart {class}'>
|
||||
{#if title || description}
|
||||
<figcaption class="wrn-chart__header">
|
||||
{#if title}<strong>{title}</strong>{/if}
|
||||
{#if description}<span>{description}</span>{/if}
|
||||
</figcaption>
|
||||
{/if}
|
||||
{#if (type || variant) === "line"}
|
||||
<svg class="wrn-chart__line" viewBox="0 0 600 240" role="img" aria-label="{title}" style="height:{height}px"><polyline points="{linePoints()}" fill="none" stroke="var(--wrn-color-primary)" stroke-width="3" /></svg>
|
||||
<div class="wrn-chart__point-labels">{#each chartData() as item, index}<button type="button" @click="selectPoint(item, index, event)">{item[labelKey]} · {numericValue(item)}</button>{/each}</div>
|
||||
{:else}
|
||||
<div class="wrn-chart__columns" style="height:{height}px" role="group" aria-label="{title}">
|
||||
{#each chartData() as item, index}<button type="button" class="wrn-chart__column" data-hidden="{hiddenIndexes.includes(index)}" aria-label="{item[labelKey] + ': ' + numericValue(item)}" @click="selectPoint(item, index, event)">
|
||||
{#if showValues}<span>{numericValue(item)}</span>{/if}
|
||||
<svg viewBox="0 0 60 160" preserveAspectRatio="none" aria-hidden="true" style="height:{numericValue(item) / maximumValue() * Math.max(60, height - 60)}px"><rect x="0" y="0" width="60" height="160" rx="3" fill="var(--wrn-color-primary)" /></svg>
|
||||
<small>{item[labelKey]}</small>
|
||||
</button>{/each}
|
||||
|
||||
<div class="wrn-chart__stage" style="aspect-ratio: 600 / {Math.max(120, height)}">
|
||||
<svg class="wrn-chart__plot" viewBox="0 0 600 {Math.max(120, height)}" preserveAspectRatio="none" role="img" aria-label="{title}">
|
||||
{#each ticks() as tick}
|
||||
<line class="wrn-chart__grid" x1="{plotLeft()}" x2="{plotRight()}" y1="{yFor(tick)}" y2="{yFor(tick)}" data-baseline="{tick === 0}"></line>
|
||||
{/each}
|
||||
{#if chartKind() === "bar"}
|
||||
{#each points() as point, position}
|
||||
<path class="wrn-chart__bar" d="{barPath(point, position)}"></path>
|
||||
{/each}
|
||||
{:else}
|
||||
{#if chartKind() === "area"}<path class="wrn-chart__area" d="{areaPath()}"></path>{/if}
|
||||
<path class="wrn-chart__line" d="{linePath()}"></path>
|
||||
{/if}
|
||||
</svg>
|
||||
|
||||
<div class="wrn-chart__ticks" aria-hidden="true">
|
||||
{#each ticks() as tick}<span style="top:{yFor(tick) / Math.max(120, height) * 100}%">{tickLabel(tick)}</span>{/each}
|
||||
</div>
|
||||
{/if}
|
||||
{#if showLegend}
|
||||
<div class="wrn-chart__legend" aria-label="Chart legend">
|
||||
|
||||
<div class="wrn-chart__labels" aria-hidden="true">
|
||||
{#each points() as point, position}<span style="left:{centerX(position) / 600 * 100}%">{point.item[labelKey]}</span>{/each}
|
||||
</div>
|
||||
|
||||
<div class="wrn-chart__hits">
|
||||
{#each points() as point, position}
|
||||
<button type="button" class="wrn-chart__hit" style="{hitStyle(position)}" aria-label="{point.item[labelKey] + ': ' + numericValue(point.item)}" @click="selectPoint(point.item, point.index, event)">
|
||||
{#if chartKind() !== "bar"}<i class="wrn-chart__dot" style="{tipStyle(point)}" aria-hidden="true"></i>{/if}
|
||||
{#if showValues && chartKind() === "bar"}<b class="wrn-chart__value" style="{tipStyle(point)}" aria-hidden="true">{tickLabel(numericValue(point.item))}</b>{/if}
|
||||
<span class="wrn-chart__tip" style="{tipStyle(point)}" aria-hidden="true"><small>{point.item[labelKey]}</small><strong>{numericValue(point.item)}</strong></span>
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
{#if !points().length}<p class="wrn-chart__empty">No data to show</p>{/if}
|
||||
</div>
|
||||
|
||||
{#if showLegend && chartData().length}
|
||||
<div class="wrn-chart__legend" role="group" aria-label="Show or hide data">
|
||||
{#each chartData() as item, index}
|
||||
<button type="button" aria-pressed='{isHidden(index) ? "false" : "true"}' @click='toggleLegend(item, index, event)'>
|
||||
<span aria-hidden="true"></span>{item[labelKey]}
|
||||
@@ -88,29 +182,159 @@ component Chart {
|
||||
}
|
||||
|
||||
style {
|
||||
.wrn-chart__columns { display:flex; align-items:flex-end; gap:clamp(.5rem,2vw,1.5rem); padding:.5rem; border-bottom:1px solid var(--wrn-color-border); }
|
||||
.wrn-chart__column { display:flex; flex:1; min-width:0; flex-direction:column; align-items:center; gap:.6rem; padding:0; border:0; background:transparent; color:var(--wrn-color-text); font:inherit; font-size:.8rem; cursor:pointer; }
|
||||
.wrn-chart__column svg { width:100%; max-width:5rem; min-height:1px; }
|
||||
.wrn-chart__column small { max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--wrn-color-muted); }
|
||||
.wrn-chart__column[data-hidden="true"] { opacity:.2; }
|
||||
.wrn-chart__line { width:100%; display:block; }
|
||||
.wrn-chart__point-labels { display:flex; justify-content:space-around; gap:.5rem; flex-wrap:wrap; }
|
||||
.wrn-chart__point-labels button { border:0; background:transparent; color:var(--wrn-color-muted); font:inherit; font-size:.8rem; cursor:pointer; }
|
||||
.wrn-chart {
|
||||
--wrn-chart-color: var(--wrn-color-primary);
|
||||
display: grid;
|
||||
gap: 0.875rem;
|
||||
min-width: 0;
|
||||
margin: 0;
|
||||
padding: 1rem 1.125rem;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius);
|
||||
color: var(--wrn-color-text);
|
||||
background: var(--wrn-color-surface);
|
||||
box-shadow: var(--wrn-shadow-1);
|
||||
}
|
||||
.wrn-chart[data-color="secondary"] { --wrn-chart-color: var(--wrn-color-secondary); }
|
||||
.wrn-chart[data-color="success"] { --wrn-chart-color: var(--wrn-color-success); }
|
||||
.wrn-chart[data-color="info"] { --wrn-chart-color: var(--wrn-color-info); }
|
||||
.wrn-chart[data-color="warning"] { --wrn-chart-color: var(--wrn-color-warning); }
|
||||
.wrn-chart[data-color="danger"] { --wrn-chart-color: var(--wrn-color-danger); }
|
||||
|
||||
.wrn-chart { display: grid; gap: 1rem; min-width: 0; margin: 0; padding: 1rem; border: 1px solid var(--wrn-color-border); border-radius: var(--wrn-radius); color: var(--wrn-color-text); background: var(--wrn-color-surface); box-shadow: var(--wrn-shadow-1); }
|
||||
.wrn-chart__header { display: grid; gap: 0.2rem; }
|
||||
.wrn-chart__header > span { color: var(--wrn-color-muted); font-size: 0.8rem; }
|
||||
.wrn-chart__plot { display: block; width: 100%; min-height: 12rem; overflow: visible; }
|
||||
.wrn-chart__axis { stroke: var(--wrn-color-border); stroke-width: 0.5; }
|
||||
.wrn-chart__bar { fill: var(--wrn-color-primary); cursor: pointer; transition: opacity var(--wrn-motion-fast), transform var(--wrn-motion-fast); transform-box: fill-box; transform-origin: bottom; }
|
||||
.wrn-chart__bar:hover { opacity: 0.82; transform: scaleY(1.02); }
|
||||
.wrn-chart__bar:focus-visible { outline: 1.5px solid var(--wrn-color-focus); outline-offset: 1px; }
|
||||
.wrn-chart__plot g[data-hidden="true"] { opacity: 0.18; pointer-events: none; }
|
||||
.wrn-chart__value, .wrn-chart__label { fill: var(--wrn-color-text); font-size: 11px; text-anchor: middle; }
|
||||
.wrn-chart__label { fill: var(--wrn-color-muted); }
|
||||
.wrn-chart__legend { display: flex; flex-wrap: wrap; gap: 0.5rem; }
|
||||
.wrn-chart__legend button { display: inline-flex; align-items: center; gap: 0.35rem; padding: 0.3rem 0.5rem; border: 1px solid var(--wrn-color-border); border-radius: 999px; color: var(--wrn-color-text); background: transparent; font: inherit; font-size: 0.75rem; cursor: pointer; }
|
||||
.wrn-chart__legend button > span { width: 0.65rem; height: 0.65rem; border-radius: 0.2rem; background: var(--wrn-color-primary); }
|
||||
.wrn-chart__legend button[aria-pressed="false"] { opacity: 0.5; }
|
||||
.wrn-chart__header > strong { font-size: 0.9375rem; font-weight: 620; letter-spacing: -0.01em; }
|
||||
.wrn-chart__header > span { color: var(--wrn-color-text-muted, var(--wrn-color-muted)); font-size: 0.8125rem; }
|
||||
|
||||
/* The stage reserves the SVG box; ticks, labels and hit targets sit over
|
||||
it in percentages so text never scales with the plot. */
|
||||
.wrn-chart__stage { position: relative; width: 100%; min-width: 0; }
|
||||
.wrn-chart__plot { position: absolute; inset: 0; display: block; width: 100%; height: 100%; overflow: visible; }
|
||||
|
||||
.wrn-chart__grid { stroke: var(--wrn-color-border); stroke-width: 1; vector-effect: non-scaling-stroke; stroke-dasharray: 2 4; }
|
||||
.wrn-chart__grid[data-baseline="true"] { stroke: var(--wrn-color-border-strong, var(--wrn-color-border)); stroke-dasharray: none; }
|
||||
|
||||
.wrn-chart__bar { fill: var(--wrn-chart-color); transition: opacity var(--wrn-motion-fast); }
|
||||
.wrn-chart__line { fill: none; stroke: var(--wrn-chart-color); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke; }
|
||||
.wrn-chart__area { fill: color-mix(in srgb, var(--wrn-chart-color) 14%, transparent); stroke: none; }
|
||||
|
||||
.wrn-chart__ticks > span,
|
||||
.wrn-chart__labels > span {
|
||||
position: absolute;
|
||||
color: var(--wrn-color-text-subtle, var(--wrn-color-muted));
|
||||
font-family: var(--wrn-font-mono, monospace);
|
||||
font-size: 0.65rem;
|
||||
font-variant-numeric: tabular-nums;
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
pointer-events: none;
|
||||
}
|
||||
.wrn-chart__ticks > span { left: 0; width: calc(44 / 600 * 100% - 0.4rem); text-align: right; transform: translateY(-50%); }
|
||||
.wrn-chart__labels > span {
|
||||
bottom: 0;
|
||||
max-width: 5.5rem;
|
||||
overflow: hidden;
|
||||
font-family: var(--wrn-font-sans, inherit);
|
||||
font-size: 0.72rem;
|
||||
text-overflow: ellipsis;
|
||||
transform: translate(-50%, -0.35rem);
|
||||
}
|
||||
|
||||
.wrn-chart__hits { position: absolute; inset: 0; }
|
||||
.wrn-chart__hit {
|
||||
position: absolute;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
border-radius: calc(var(--wrn-radius-sm) - 2px);
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
}
|
||||
.wrn-chart__hit:hover,
|
||||
.wrn-chart__hit:focus-visible { background: color-mix(in srgb, var(--wrn-color-text) 4%, transparent); outline: none; }
|
||||
.wrn-chart__hit:focus-visible { box-shadow: inset 0 0 0 1.5px var(--wrn-color-focus, var(--wrn-chart-color)); }
|
||||
|
||||
.wrn-chart__dot {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
width: 0.5rem;
|
||||
height: 0.5rem;
|
||||
border-radius: 999px;
|
||||
background: var(--wrn-chart-color);
|
||||
box-shadow: 0 0 0 2px var(--wrn-color-surface);
|
||||
transform: translate(-50%, -50%);
|
||||
transition: transform var(--wrn-motion-fast);
|
||||
}
|
||||
.wrn-chart__hit:is(:hover, :focus-visible) .wrn-chart__dot { transform: translate(-50%, -50%) scale(1.4); }
|
||||
|
||||
.wrn-chart__value {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
color: var(--wrn-color-text-muted, var(--wrn-color-text));
|
||||
font-family: var(--wrn-font-mono, monospace);
|
||||
font-size: 0.68rem;
|
||||
font-weight: 600;
|
||||
font-variant-numeric: tabular-nums;
|
||||
transform: translate(-50%, calc(-100% - 0.3rem));
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.wrn-chart__tip {
|
||||
position: absolute;
|
||||
z-index: 3;
|
||||
left: 50%;
|
||||
display: grid;
|
||||
gap: 0.1rem;
|
||||
width: max-content;
|
||||
padding: 0.375rem 0.55rem;
|
||||
border: 1px solid rgb(255 255 255 / 0.08);
|
||||
border-radius: var(--wrn-radius-sm, 0.5rem);
|
||||
color: #f4f5f7;
|
||||
background: #16181d;
|
||||
box-shadow: 0 8px 24px -4px rgb(0 0 0 / 0.35);
|
||||
text-align: left;
|
||||
opacity: 0;
|
||||
transform: translate(-50%, calc(-100% - 0.75rem));
|
||||
transition: opacity var(--wrn-motion-fast);
|
||||
pointer-events: none;
|
||||
}
|
||||
.wrn-chart__tip small { color: rgb(244 245 247 / 0.7); font-size: 0.68rem; }
|
||||
.wrn-chart__tip strong { font-family: var(--wrn-font-mono, monospace); font-size: 0.8125rem; font-variant-numeric: tabular-nums; }
|
||||
.wrn-chart__hit:is(:hover, :focus-visible) .wrn-chart__tip { opacity: 1; }
|
||||
.wrn-chart__hit:is(:hover, :focus-visible) .wrn-chart__value { opacity: 0; }
|
||||
|
||||
.wrn-chart__empty {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
margin: 0;
|
||||
color: var(--wrn-color-text-muted, var(--wrn-color-muted));
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
|
||||
.wrn-chart__legend { display: flex; flex-wrap: wrap; gap: 0.375rem; }
|
||||
.wrn-chart__legend button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.375rem;
|
||||
min-height: 1.75rem;
|
||||
padding: 0 0.6rem;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: 999px;
|
||||
color: var(--wrn-color-text);
|
||||
background: var(--wrn-color-surface);
|
||||
font: inherit;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 550;
|
||||
cursor: pointer;
|
||||
transition: opacity 120ms ease, background-color 120ms ease;
|
||||
}
|
||||
.wrn-chart__legend button:hover { background: var(--wrn-color-surface-soft); }
|
||||
.wrn-chart__legend button > span { width: 0.5rem; height: 0.5rem; border-radius: 2px; background: var(--wrn-chart-color); }
|
||||
.wrn-chart__legend button[aria-pressed="false"] { color: var(--wrn-color-text-subtle, var(--wrn-color-muted)); text-decoration: line-through; }
|
||||
.wrn-chart__legend button[aria-pressed="false"] > span { background: var(--wrn-color-border-strong, var(--wrn-color-border)); }
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.wrn-chart__dot, .wrn-chart__tip, .wrn-chart__bar { transition: none; }
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user