Refresh UI components and showcase; release updated framework packages
This commit is contained in:
1 parent
d800228585
commit
c77f5e1cec
293 files changed
+22544
-35778
No files matched your search
@@ -9,6 +9,8 @@ component Chart {
|
||||
title: string = "Chart"
|
||||
description: string = ""
|
||||
items: unknown[] = []
|
||||
data: unknown[] = []
|
||||
type: string = ""
|
||||
valueKey: string = "value"
|
||||
labelKey: string = "label"
|
||||
height: number = 240
|
||||
@@ -23,15 +25,17 @@ component Chart {
|
||||
state hiddenIndexes = []
|
||||
|
||||
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 numericValue(item) { return Math.max(0, Number(item[valueKey]) || 0) }
|
||||
shared function maximumValue() {
|
||||
return Math.max(1, ...items.map(function (item) { return numericValue(item) }))
|
||||
return Math.max(1, ...chartData().map(function (item) { return numericValue(item) }))
|
||||
}
|
||||
shared function isHidden(index) { return hiddenIndexes.includes(index) }
|
||||
shared function barWidth() { return items.length ? Math.max(4, 80 / items.length) : 80 }
|
||||
shared function barX(index) { return 10 + index * (80 / Math.max(1, items.length)) }
|
||||
shared function barHeight(item) { return numericValue(item) / maximumValue() * 72 }
|
||||
shared function barY(item) { return 84 - barHeight(item) }
|
||||
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) }
|
||||
|
||||
client function selectPoint(item, index, sourceEvent) {
|
||||
output.dataPointClick({ item: item, index: index, sourceEvent: sourceEvent })
|
||||
@@ -58,25 +62,21 @@ component Chart {
|
||||
{#if description}<span>{description}</span>{/if}
|
||||
</figcaption>
|
||||
{/if}
|
||||
<svg class="wrn-chart__plot" viewBox="0 0 100 100" role="img" aria-label='{title}' style='height:{height}px'>
|
||||
<line x1="8" y1="84" x2="96" y2="84" class="wrn-chart__axis" />
|
||||
{#each items as item, index}
|
||||
<g data-hidden='{isHidden(index) ? "true" : "false"}'>
|
||||
<rect
|
||||
x='{barX(index)}' y='{barY(item)}' width='{barWidth()}' height='{barHeight(item)}'
|
||||
rx="1.5" class="wrn-chart__bar" role="button" tabindex="0"
|
||||
aria-label='{item[labelKey] + ": " + numericValue(item)}'
|
||||
@click='selectPoint(item, index, event)'
|
||||
@keydown='if (event.key === "Enter" || event.key === " ") { event.preventDefault(); selectPoint(item, index, event) }'
|
||||
/>
|
||||
{#if showValues}<text x='{barX(index) + barWidth() / 2}' y='{barY(item) - 3}' class="wrn-chart__value">{numericValue(item)}</text>{/if}
|
||||
<text x='{barX(index) + barWidth() / 2}' y="94" class="wrn-chart__label">{item[labelKey]}</text>
|
||||
</g>
|
||||
{/each}
|
||||
</svg>
|
||||
{#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>
|
||||
{/if}
|
||||
{#if showLegend}
|
||||
<div class="wrn-chart__legend" aria-label="Chart legend">
|
||||
{#each items as item, index}
|
||||
{#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]}
|
||||
</button>
|
||||
@@ -88,6 +88,15 @@ 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 { 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; }
|
||||
@@ -97,7 +106,7 @@ component Chart {
|
||||
.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: 3.5px; text-anchor: middle; }
|
||||
.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; }
|
||||
|
||||
Reference in new issue
Block a user