Files
WRNexusJS/packages/ui/components/StatsBar.wrn
2026-08-01 01:09:58 +05:30

485 lines
14 KiB
Plaintext

component StatsBar {
props {
items: unknown[] = []
columns: number = 4
compact: boolean = true
dividers: boolean = true
icons: boolean = true
size: string = "default"
color: string = "primary"
variant: string = "raised"
maxWidth: string = "xl"
class: string = ""
}
view {
<section
{...attrs}
data-ui-component="StatsBar"
data-columns='{columns}'
data-compact='{compact ? "true" : "false"}'
data-dividers='{dividers ? "true" : "false"}'
data-icons='{icons ? "true" : "false"}'
data-size='{size}'
data-color='{color}'
data-variant='{variant}'
data-max-width='{maxWidth}'
class='wire-stats-bar {class}'
aria-label="Key statistics"
>
<div class="wire-stats-bar__inner">
<div class="wire-stats-bar__surface">
{#each items as item, itemIndex}
<article
class="wire-stats-bar__item"
data-color='{item.color || color}'
data-index='{itemIndex}'
>
<div class="wire-stats-bar__content">
{#if item.label}
<p class="wire-stats-bar__label">{item.label}</p>
{/if}
<div class="wire-stats-bar__value-row">
<strong class="wire-stats-bar__value">{item.value}</strong>
{#if item.suffix}
<span class="wire-stats-bar__suffix">{item.suffix}</span>
{/if}
</div>
{#if item.description}
<p class="wire-stats-bar__description">{item.description}</p>
{/if}
{#if item.trend || item.trendLabel}
<div
class="wire-stats-bar__trend"
data-direction='{item.trendDirection || "neutral"}'
>
{#if item.trendDirection === "up"}
<span
class="icon-[lucide--trending-up] wire-stats-bar__trend-icon"
aria-hidden="true"
></span>
{:else if item.trendDirection === "down"}
<span
class="icon-[lucide--trending-down] wire-stats-bar__trend-icon"
aria-hidden="true"
></span>
{:else}
<span
class="icon-[lucide--minus] wire-stats-bar__trend-icon"
aria-hidden="true"
></span>
{/if}
{#if item.trend}
<span class="wire-stats-bar__trend-value">{item.trend}</span>
{/if}
{#if item.trendLabel}
<span class="wire-stats-bar__trend-label">{item.trendLabel}</span>
{/if}
</div>
{/if}
</div>
{#if icons && item.icon}
<div class="wire-stats-bar__icon" aria-hidden="true">
<span class='{item.icon}'></span>
</div>
{/if}
</article>
{/each}
</div>
</div>
</section>
}
style {
.wire-stats-bar {
--stats-accent: var(--wire-color-primary);
--stats-contrast: var(--wire-color-primary-contrast);
--stats-soft: color-mix(in srgb, var(--stats-accent) 12%, transparent);
--stats-border: color-mix(in srgb, var(--stats-accent) 22%, var(--wire-color-border));
position: relative;
width: 100%;
color: var(--wire-color-text);
}
.wire-stats-bar[data-color="secondary"] {
--stats-accent: var(--wire-color-secondary);
--stats-contrast: var(--wire-color-secondary-contrast);
}
.wire-stats-bar[data-color="info"] {
--stats-accent: var(--wire-color-info);
--stats-contrast: var(--wire-color-info-contrast);
}
.wire-stats-bar[data-color="success"] {
--stats-accent: var(--wire-color-success);
--stats-contrast: var(--wire-color-success-contrast);
}
.wire-stats-bar[data-color="warning"] {
--stats-accent: var(--wire-color-warning);
--stats-contrast: var(--wire-color-warning-contrast);
}
.wire-stats-bar[data-color="danger"] {
--stats-accent: var(--wire-color-danger);
--stats-contrast: var(--wire-color-danger-contrast);
}
.wire-stats-bar__inner {
width: min(calc(100% - 2rem), 80rem);
margin-inline: auto;
}
.wire-stats-bar[data-max-width="compact"] .wire-stats-bar__inner {
width: min(calc(100% - 2rem), 64rem);
}
.wire-stats-bar[data-max-width="lg"] .wire-stats-bar__inner {
width: min(calc(100% - 2rem), 72rem);
}
.wire-stats-bar[data-max-width="wide"] .wire-stats-bar__inner,
.wire-stats-bar[data-max-width="2xl"] .wire-stats-bar__inner {
width: min(calc(100% - 2rem), 90rem);
}
.wire-stats-bar[data-max-width="full"] .wire-stats-bar__inner {
width: 100%;
max-width: none;
}
.wire-stats-bar__surface {
display: grid;
grid-template-columns: minmax(0, 1fr);
overflow: hidden;
background:
linear-gradient(
135deg,
color-mix(in srgb, var(--stats-accent) 7%, transparent),
transparent 42%
),
var(--wire-color-surface-raised);
border: 1px solid var(--stats-border);
border-radius: 1.25rem;
box-shadow:
0 1px 0 color-mix(in srgb, white 5%, transparent) inset,
0 18px 48px color-mix(in srgb, black 16%, transparent);
}
.wire-stats-bar[data-variant="default"] .wire-stats-bar__surface {
background: var(--wire-color-surface);
box-shadow: none;
}
.wire-stats-bar[data-variant="soft"] .wire-stats-bar__surface {
background:
linear-gradient(135deg, var(--stats-soft), transparent 58%),
var(--wire-color-surface-raised);
box-shadow: none;
}
.wire-stats-bar[data-variant="outline"] .wire-stats-bar__surface {
background: transparent;
box-shadow: none;
}
.wire-stats-bar[data-variant="minimal"] .wire-stats-bar__surface {
background: transparent;
border-color: transparent;
border-radius: 0;
box-shadow: none;
}
.wire-stats-bar[data-variant="solid"] .wire-stats-bar__surface {
color: var(--stats-contrast);
background:
linear-gradient(135deg, color-mix(in srgb, white 8%, transparent), transparent 52%),
var(--stats-accent);
border-color: color-mix(in srgb, white 24%, transparent);
box-shadow: 0 20px 56px color-mix(in srgb, var(--stats-accent) 28%, transparent);
}
.wire-stats-bar__item {
--item-accent: var(--stats-accent);
position: relative;
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
align-items: start;
gap: 1rem;
min-width: 0;
padding: 1.5rem;
transition:
background-color 180ms ease,
transform 180ms ease;
}
.wire-stats-bar[data-compact="true"] .wire-stats-bar__item {
padding: 1.15rem 1.25rem;
}
.wire-stats-bar[data-size="sm"] .wire-stats-bar__item {
padding: 1rem 1.1rem;
}
.wire-stats-bar[data-size="lg"] .wire-stats-bar__item {
padding: 1.8rem;
}
.wire-stats-bar__item[data-color="secondary"] {
--item-accent: var(--wire-color-secondary);
}
.wire-stats-bar__item[data-color="info"] {
--item-accent: var(--wire-color-info);
}
.wire-stats-bar__item[data-color="success"] {
--item-accent: var(--wire-color-success);
}
.wire-stats-bar__item[data-color="warning"] {
--item-accent: var(--wire-color-warning);
}
.wire-stats-bar__item[data-color="danger"] {
--item-accent: var(--wire-color-danger);
}
.wire-stats-bar__item:hover {
background: color-mix(in srgb, var(--item-accent) 6%, transparent);
}
.wire-stats-bar[data-variant="solid"] .wire-stats-bar__item:hover {
background: color-mix(in srgb, white 8%, transparent);
}
.wire-stats-bar__content {
min-width: 0;
}
.wire-stats-bar__label {
margin: 0;
color: var(--wire-color-text-muted);
font-size: 0.78rem;
font-weight: 600;
line-height: 1.4;
letter-spacing: 0.01em;
}
.wire-stats-bar__value-row {
display: flex;
align-items: baseline;
gap: 0.25rem;
margin-top: 0.45rem;
}
.wire-stats-bar__value {
margin: 0;
color: var(--wire-color-text);
font-size: clamp(1.75rem, 2.4vw, 2.35rem);
font-weight: 650;
line-height: 1;
letter-spacing: -0.035em;
}
.wire-stats-bar[data-compact="true"] .wire-stats-bar__value {
font-size: clamp(1.45rem, 2vw, 1.9rem);
}
.wire-stats-bar__suffix {
color: var(--item-accent);
font-size: 0.95rem;
font-weight: 700;
}
.wire-stats-bar__description {
max-width: 30rem;
margin: 0.7rem 0 0;
color: var(--wire-color-text-muted);
font-size: 0.78rem;
line-height: 1.55;
}
.wire-stats-bar[data-compact="true"] .wire-stats-bar__description {
margin-top: 0.55rem;
font-size: 0.73rem;
}
.wire-stats-bar__icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 2.65rem;
height: 2.65rem;
color: var(--item-accent);
background: color-mix(in srgb, var(--item-accent) 11%, transparent);
border-radius: 0.85rem;
}
.wire-stats-bar__icon > span {
width: 1.2rem;
height: 1.2rem;
}
.wire-stats-bar[data-compact="true"] .wire-stats-bar__icon {
width: 2.35rem;
height: 2.35rem;
border-radius: 0.75rem;
}
.wire-stats-bar__trend {
display: inline-flex;
align-items: center;
gap: 0.3rem;
width: fit-content;
margin-top: 0.7rem;
padding: 0.25rem 0.5rem;
color: var(--wire-color-text-muted);
font-size: 0.7rem;
line-height: 1;
background: color-mix(in srgb, var(--wire-color-text) 5%, transparent);
border-radius: 999px;
}
.wire-stats-bar__trend[data-direction="up"] {
color: var(--wire-color-success);
}
.wire-stats-bar__trend[data-direction="down"] {
color: var(--wire-color-danger);
}
.wire-stats-bar__trend-icon {
width: 0.8rem;
height: 0.8rem;
}
.wire-stats-bar__trend-value {
font-weight: 700;
}
.wire-stats-bar__trend-label {
opacity: 0.8;
}
.wire-stats-bar[data-variant="solid"] .wire-stats-bar__label,
.wire-stats-bar[data-variant="solid"] .wire-stats-bar__description,
.wire-stats-bar[data-variant="solid"] .wire-stats-bar__value,
.wire-stats-bar[data-variant="solid"] .wire-stats-bar__suffix {
color: var(--stats-contrast);
}
.wire-stats-bar[data-variant="solid"] .wire-stats-bar__label,
.wire-stats-bar[data-variant="solid"] .wire-stats-bar__description {
opacity: 0.78;
}
.wire-stats-bar[data-variant="solid"] .wire-stats-bar__icon {
color: var(--stats-contrast);
background: color-mix(in srgb, white 13%, transparent);
}
.wire-stats-bar[data-dividers="true"] .wire-stats-bar__item + .wire-stats-bar__item {
border-top: 1px solid var(--wire-color-border);
}
.wire-stats-bar[data-variant="solid"][data-dividers="true"]
.wire-stats-bar__item + .wire-stats-bar__item {
border-color: color-mix(in srgb, white 18%, transparent);
}
@media (min-width: 640px) {
.wire-stats-bar__surface {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.wire-stats-bar[data-columns="1"] .wire-stats-bar__surface {
grid-template-columns: minmax(0, 1fr);
}
.wire-stats-bar[data-dividers="true"] .wire-stats-bar__item {
border-top: 0;
}
.wire-stats-bar[data-dividers="true"] .wire-stats-bar__item:nth-child(even) {
border-left: 1px solid var(--wire-color-border);
}
.wire-stats-bar[data-dividers="true"] .wire-stats-bar__item:nth-child(n + 3) {
border-top: 1px solid var(--wire-color-border);
}
.wire-stats-bar[data-variant="solid"][data-dividers="true"]
.wire-stats-bar__item:nth-child(even),
.wire-stats-bar[data-variant="solid"][data-dividers="true"]
.wire-stats-bar__item:nth-child(n + 3) {
border-color: color-mix(in srgb, white 18%, transparent);
}
}
@media (min-width: 1024px) {
.wire-stats-bar[data-columns="1"] .wire-stats-bar__surface {
grid-template-columns: minmax(0, 1fr);
}
.wire-stats-bar[data-columns="2"] .wire-stats-bar__surface {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.wire-stats-bar[data-columns="3"] .wire-stats-bar__surface {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
.wire-stats-bar[data-columns="4"] .wire-stats-bar__surface {
grid-template-columns: repeat(4, minmax(0, 1fr));
}
.wire-stats-bar[data-columns="5"] .wire-stats-bar__surface {
grid-template-columns: repeat(5, minmax(0, 1fr));
}
.wire-stats-bar[data-columns="6"] .wire-stats-bar__surface {
grid-template-columns: repeat(6, minmax(0, 1fr));
}
.wire-stats-bar[data-dividers="true"] .wire-stats-bar__item,
.wire-stats-bar[data-dividers="true"] .wire-stats-bar__item:nth-child(even),
.wire-stats-bar[data-dividers="true"] .wire-stats-bar__item:nth-child(n + 3) {
border-top: 0;
border-left: 1px solid var(--wire-color-border);
}
.wire-stats-bar[data-dividers="true"] .wire-stats-bar__item:first-child {
border-left: 0;
}
.wire-stats-bar[data-variant="solid"][data-dividers="true"] .wire-stats-bar__item {
border-color: color-mix(in srgb, white 18%, transparent);
}
}
@media (max-width: 639px) {
.wire-stats-bar[data-max-width="full"] .wire-stats-bar__surface {
border-inline: 0;
border-radius: 0;
}
}
@media (prefers-reduced-motion: reduce) {
.wire-stats-bar__item {
transition: none;
}
}
}
}