You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

78 lines
2.4 KiB
Svelte

<script>import { afterUpdate } from "svelte";
import { tailwindDefaultColors } from "./settings.js";
export let stops = [{ color: ["neutral", 500], start: 0, end: 100 }];
export let legend = false;
export let spin = false;
export let width = "w-24";
export let hover = "bg-primary-hover-token";
export let digits = 0;
export let regionCaption = "";
export let regionCone = "";
export let regionLegend = "";
let cone;
let generatedLegendList;
const cBase = "flex flex-col items-center space-y-4 w-";
const cCaption = "text-center";
const cCone = "block aspect-square rounded-full";
const cLegend = "text-sm w-full";
const cSwatch = "block aspect-square bg-black w-5 rounded-full mr-2";
function setColorValue(color) {
if (typeof color === "string")
return color;
const colorSet = tailwindDefaultColors.find((c) => c.label === color[0]);
return colorSet?.shades[color[1]].hex;
}
function genConicGradient() {
let d = stops.map((v) => `${setColorValue(v.color)} ${v.start}% ${v.end}%`);
cone = `conic-gradient(${d.join(", ")})`;
}
function genLegend() {
if (!legend)
return;
generatedLegendList = stops.map((v) => {
return {
label: v.label,
color: setColorValue(v.color),
value: (v.end - v.start).toFixed(digits)
};
});
}
afterUpdate(() => {
genConicGradient();
genLegend();
});
$:
classesBase = `${cBase} ${$$props.class ?? ""}`;
$:
classesCaption = `${cCaption} ${regionCaption}`;
$:
classesCone = `${cCone} ${width} ${regionCone}`;
$:
classesLegend = `${cLegend} ${regionLegend}`;
</script>
<figure class="conic-gradient {classesBase}" data-testid="conic-gradient">
<!-- Label -->
{#if $$slots.default}
<figcaption class="conic-caption {classesCaption}"><slot /></figcaption>
{/if}
<!-- Conic Gradient -->
{#if cone}
<div class="conic-cone {classesCone}" class:animate-spin={spin} style:background={cone} />
{/if}
<!-- Legend -->
{#if legend && generatedLegendList}
<ul class="conic-list list {classesLegend}">
{#each generatedLegendList as { color, label, value }}
<!-- FIXME: resolve a11y warnings -->
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
<li class="conic-item {hover}" on:click on:keydown on:keyup on:keypress>
<span class="conic-swatch {cSwatch}" style:background={color} />
<span class="conic-label flex-auto">{label}</span>
<strong class="conic-value">{value}%</strong>
</li>
{/each}
</ul>
{/if}
</figure>