@w5-ui/svelte 0.1.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/README.md +8 -0
- package/package.json +57 -0
- package/src/lib/components/Accordion.svelte +3 -0
- package/src/lib/components/AccordionItem.svelte +40 -0
- package/src/lib/components/ActionMenu.svelte +96 -0
- package/src/lib/components/ActivityFeed.svelte +60 -0
- package/src/lib/components/Alert.svelte +19 -0
- package/src/lib/components/AnnotatedTimeSeries.svelte +90 -0
- package/src/lib/components/ArcDiagram.svelte +74 -0
- package/src/lib/components/AreaChart.svelte +64 -0
- package/src/lib/components/Avatar.svelte +30 -0
- package/src/lib/components/AvatarGroup.svelte +35 -0
- package/src/lib/components/Badge.svelte +25 -0
- package/src/lib/components/Banner.svelte +37 -0
- package/src/lib/components/BarChart.svelte +52 -0
- package/src/lib/components/BeeswarmChart.svelte +88 -0
- package/src/lib/components/BoxPlot.svelte +66 -0
- package/src/lib/components/Breadcrumb.svelte +31 -0
- package/src/lib/components/BubbleChart.svelte +69 -0
- package/src/lib/components/BulletChart.svelte +70 -0
- package/src/lib/components/BumpChart.svelte +109 -0
- package/src/lib/components/Button.svelte +25 -0
- package/src/lib/components/CIDRInput.svelte +142 -0
- package/src/lib/components/CalendarHeatmap.svelte +86 -0
- package/src/lib/components/Callout.svelte +38 -0
- package/src/lib/components/CandlestickChart.svelte +66 -0
- package/src/lib/components/Card.svelte +11 -0
- package/src/lib/components/Carousel.svelte +64 -0
- package/src/lib/components/Checkbox.svelte +45 -0
- package/src/lib/components/ChordDiagram.svelte +90 -0
- package/src/lib/components/CirclePacking.svelte +119 -0
- package/src/lib/components/CodeBlock.svelte +49 -0
- package/src/lib/components/ColorPicker.svelte +91 -0
- package/src/lib/components/ColumnToggle.svelte +96 -0
- package/src/lib/components/Combobox.svelte +138 -0
- package/src/lib/components/CommandPalette.svelte +152 -0
- package/src/lib/components/ConfirmDialog.svelte +84 -0
- package/src/lib/components/ContextMenu.svelte +107 -0
- package/src/lib/components/ContextualHelp.svelte +73 -0
- package/src/lib/components/ContourPlot.svelte +164 -0
- package/src/lib/components/CopyButton.svelte +33 -0
- package/src/lib/components/CorrelationMatrix.svelte +90 -0
- package/src/lib/components/CountUp.svelte +49 -0
- package/src/lib/components/CumulativeDistribution.svelte +67 -0
- package/src/lib/components/DatePicker.svelte +201 -0
- package/src/lib/components/DateRangePicker.svelte +249 -0
- package/src/lib/components/Dendrogram.svelte +128 -0
- package/src/lib/components/Donut.svelte +49 -0
- package/src/lib/components/DotPlot.svelte +121 -0
- package/src/lib/components/Drawer.svelte +60 -0
- package/src/lib/components/DualAxisChart.svelte +80 -0
- package/src/lib/components/DumbbellChart.svelte +56 -0
- package/src/lib/components/DurationInput.svelte +118 -0
- package/src/lib/components/EmptyState.svelte +21 -0
- package/src/lib/components/ErrorBandChart.svelte +69 -0
- package/src/lib/components/ExpandableRow.svelte +42 -0
- package/src/lib/components/Field.svelte +40 -0
- package/src/lib/components/FileUpload.svelte +96 -0
- package/src/lib/components/FilterBuilder.svelte +160 -0
- package/src/lib/components/FlameGraph.svelte +88 -0
- package/src/lib/components/ForceGraph.svelte +104 -0
- package/src/lib/components/FunnelChart.svelte +50 -0
- package/src/lib/components/GanttChart.svelte +49 -0
- package/src/lib/components/Gauge.svelte +53 -0
- package/src/lib/components/GroupedList.svelte +87 -0
- package/src/lib/components/HealthBar.svelte +19 -0
- package/src/lib/components/HeatMap.svelte +64 -0
- package/src/lib/components/HexbinChart.svelte +100 -0
- package/src/lib/components/Histogram.svelte +93 -0
- package/src/lib/components/HorizonChart.svelte +71 -0
- package/src/lib/components/HoverCard.svelte +45 -0
- package/src/lib/components/IPInput.svelte +103 -0
- package/src/lib/components/IcicleChart.svelte +87 -0
- package/src/lib/components/IconButton.svelte +19 -0
- package/src/lib/components/InlineEdit.svelte +72 -0
- package/src/lib/components/Input.svelte +18 -0
- package/src/lib/components/InputGroup.svelte +14 -0
- package/src/lib/components/JsonViewer.svelte +15 -0
- package/src/lib/components/JsonViewerNode.svelte +59 -0
- package/src/lib/components/KVTable.svelte +18 -0
- package/src/lib/components/KanbanBoard.svelte +141 -0
- package/src/lib/components/Kbd.svelte +16 -0
- package/src/lib/components/LineChart.svelte +67 -0
- package/src/lib/components/LogViewer.svelte +84 -0
- package/src/lib/components/LollipopChart.svelte +79 -0
- package/src/lib/components/MACInput.svelte +98 -0
- package/src/lib/components/MarimekkoChart.svelte +108 -0
- package/src/lib/components/MatrixChart.svelte +55 -0
- package/src/lib/components/Menubar.svelte +131 -0
- package/src/lib/components/MirroredBarChart.svelte +120 -0
- package/src/lib/components/Modal.svelte +90 -0
- package/src/lib/components/MultiSelect.svelte +165 -0
- package/src/lib/components/NightingaleChart.svelte +63 -0
- package/src/lib/components/NotificationPanel.svelte +170 -0
- package/src/lib/components/NumberInput.svelte +93 -0
- package/src/lib/components/OTPInput.svelte +94 -0
- package/src/lib/components/Pagination.svelte +58 -0
- package/src/lib/components/ParallelCoordinates.svelte +98 -0
- package/src/lib/components/ParetoChart.svelte +88 -0
- package/src/lib/components/PasswordInput.svelte +62 -0
- package/src/lib/components/PieChart.svelte +91 -0
- package/src/lib/components/Pill.svelte +12 -0
- package/src/lib/components/PolarHeatmap.svelte +85 -0
- package/src/lib/components/Popover.svelte +89 -0
- package/src/lib/components/ProgressBar.svelte +29 -0
- package/src/lib/components/PunchCard.svelte +73 -0
- package/src/lib/components/QuadrantChart.svelte +122 -0
- package/src/lib/components/RadarChart.svelte +71 -0
- package/src/lib/components/RadialBarChart.svelte +76 -0
- package/src/lib/components/RadioGroup.svelte +48 -0
- package/src/lib/components/RangeSlider.svelte +68 -0
- package/src/lib/components/RankedList.svelte +49 -0
- package/src/lib/components/ResizablePanel.svelte +77 -0
- package/src/lib/components/RidgelinePlot.svelte +103 -0
- package/src/lib/components/RowToggle.svelte +19 -0
- package/src/lib/components/SankeyDiagram.svelte +100 -0
- package/src/lib/components/ScatterPlot.svelte +54 -0
- package/src/lib/components/SearchBox.svelte +11 -0
- package/src/lib/components/SegmentedControl.svelte +51 -0
- package/src/lib/components/Select.svelte +110 -0
- package/src/lib/components/SelectionToolbar.svelte +42 -0
- package/src/lib/components/Sidebar.svelte +44 -0
- package/src/lib/components/Signal.svelte +12 -0
- package/src/lib/components/Skeleton.svelte +23 -0
- package/src/lib/components/SkipLink.svelte +9 -0
- package/src/lib/components/Slider.svelte +48 -0
- package/src/lib/components/SlopeChart.svelte +91 -0
- package/src/lib/components/SortHeader.svelte +19 -0
- package/src/lib/components/SortableList.svelte +87 -0
- package/src/lib/components/Sparkline.svelte +32 -0
- package/src/lib/components/SparklineMatrix.svelte +84 -0
- package/src/lib/components/Spinner.svelte +6 -0
- package/src/lib/components/SplitButton.svelte +102 -0
- package/src/lib/components/Spoiler.svelte +41 -0
- package/src/lib/components/StackedBarChart.svelte +83 -0
- package/src/lib/components/StackedProgress.svelte +32 -0
- package/src/lib/components/StarRating.svelte +64 -0
- package/src/lib/components/Stat.svelte +24 -0
- package/src/lib/components/StatusIndicator.svelte +10 -0
- package/src/lib/components/StepChart.svelte +74 -0
- package/src/lib/components/Stepper.svelte +40 -0
- package/src/lib/components/StreamGraph.svelte +93 -0
- package/src/lib/components/StripeChart.svelte +52 -0
- package/src/lib/components/SunburstChart.svelte +80 -0
- package/src/lib/components/SwitchPortGrid.svelte +45 -0
- package/src/lib/components/TabPanel.svelte +17 -0
- package/src/lib/components/Tabs.svelte +45 -0
- package/src/lib/components/Tag.svelte +19 -0
- package/src/lib/components/TagInput.svelte +92 -0
- package/src/lib/components/Textarea.svelte +31 -0
- package/src/lib/components/ThresholdAreaChart.svelte +72 -0
- package/src/lib/components/TimePicker.svelte +116 -0
- package/src/lib/components/TimeRange.svelte +104 -0
- package/src/lib/components/Timeline.svelte +32 -0
- package/src/lib/components/Toast.svelte +52 -0
- package/src/lib/components/Toggle.svelte +23 -0
- package/src/lib/components/ToggleGroup.svelte +32 -0
- package/src/lib/components/Tooltip.svelte +16 -0
- package/src/lib/components/Topbar.svelte +63 -0
- package/src/lib/components/TransferList.svelte +184 -0
- package/src/lib/components/TreeItem.svelte +61 -0
- package/src/lib/components/TreeMap.svelte +90 -0
- package/src/lib/components/TreeView.svelte +130 -0
- package/src/lib/components/UptimeTimeline.svelte +86 -0
- package/src/lib/components/VennDiagram.svelte +91 -0
- package/src/lib/components/ViolinPlot.svelte +114 -0
- package/src/lib/components/VirtualList.svelte +38 -0
- package/src/lib/components/WaffleChart.svelte +68 -0
- package/src/lib/components/WaterfallChart.svelte +96 -0
- package/src/lib/components/WordCloud.svelte +103 -0
- package/src/lib/icons/AlarmIcon.svelte +5 -0
- package/src/lib/icons/BellIcon.svelte +6 -0
- package/src/lib/icons/CaretIcon.svelte +8 -0
- package/src/lib/icons/ClientsIcon.svelte +5 -0
- package/src/lib/icons/CloseIcon.svelte +6 -0
- package/src/lib/icons/DashboardIcon.svelte +7 -0
- package/src/lib/icons/DevicesIcon.svelte +5 -0
- package/src/lib/icons/DownloadIcon.svelte +6 -0
- package/src/lib/icons/HelpIcon.svelte +7 -0
- package/src/lib/icons/InfraIcon.svelte +7 -0
- package/src/lib/icons/IntegrationsIcon.svelte +5 -0
- package/src/lib/icons/LogsIcon.svelte +6 -0
- package/src/lib/icons/PlusIcon.svelte +6 -0
- package/src/lib/icons/PortsIcon.svelte +6 -0
- package/src/lib/icons/SearchIcon.svelte +10 -0
- package/src/lib/icons/SecurityIcon.svelte +4 -0
- package/src/lib/icons/SettingsIcon.svelte +5 -0
- package/src/lib/icons/TopologyIcon.svelte +7 -0
- package/src/lib/icons/UpdatesIcon.svelte +6 -0
- package/src/lib/icons/VpnIcon.svelte +5 -0
- package/src/lib/icons/WifiIcon.svelte +5 -0
- package/src/lib/icons/WirelessIcon.svelte +4 -0
- package/src/lib/icons.ts +22 -0
- package/src/lib/index.ts +275 -0
- package/src/lib/styles.css +2 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
export type UptimeStatus = 'up' | 'degraded' | 'down';
|
|
3
|
+
|
|
4
|
+
export interface UptimeSegment {
|
|
5
|
+
from: number;
|
|
6
|
+
to: number;
|
|
7
|
+
status: UptimeStatus;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface UptimeSeries {
|
|
11
|
+
label: string;
|
|
12
|
+
segments: UptimeSegment[];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export let series: UptimeSeries[] = [];
|
|
16
|
+
export let xLabels: string[] = [];
|
|
17
|
+
export let ariaLabel: string = 'Uptime timeline';
|
|
18
|
+
|
|
19
|
+
const VW = 400;
|
|
20
|
+
const LABEL_W = 88;
|
|
21
|
+
const PAD_R = 10;
|
|
22
|
+
const PAD_T = 6;
|
|
23
|
+
const ROW_H = 14;
|
|
24
|
+
const ROW_GAP = 8;
|
|
25
|
+
const XLBL_H = 16;
|
|
26
|
+
const LEG_H = 16;
|
|
27
|
+
const PAD_B = XLBL_H + LEG_H + 4;
|
|
28
|
+
|
|
29
|
+
const STATUS_COLOR: Record<UptimeStatus, string> = {
|
|
30
|
+
up: '#00C875',
|
|
31
|
+
degraded: '#F5A623',
|
|
32
|
+
down: '#F03E3E',
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const LEGEND: { status: UptimeStatus; label: string }[] = [
|
|
36
|
+
{ status: 'up', label: 'Up' },
|
|
37
|
+
{ status: 'degraded', label: 'Degraded' },
|
|
38
|
+
{ status: 'down', label: 'Down' },
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
$: trackW = VW - LABEL_W - PAD_R;
|
|
42
|
+
$: rowsH = series.length * (ROW_H + ROW_GAP) - ROW_GAP;
|
|
43
|
+
$: totalH = PAD_T + rowsH + PAD_B;
|
|
44
|
+
$: xlblY = PAD_T + rowsH + XLBL_H;
|
|
45
|
+
$: legY = xlblY + LEG_H;
|
|
46
|
+
|
|
47
|
+
$: rows = series.map((s, si) => ({
|
|
48
|
+
label: s.label,
|
|
49
|
+
y: PAD_T + si * (ROW_H + ROW_GAP),
|
|
50
|
+
midY: PAD_T + si * (ROW_H + ROW_GAP) + ROW_H / 2 + 4,
|
|
51
|
+
segs: s.segments.map((seg) => ({
|
|
52
|
+
x: LABEL_W + seg.from * trackW,
|
|
53
|
+
w: (seg.to - seg.from) * trackW,
|
|
54
|
+
color: STATUS_COLOR[seg.status],
|
|
55
|
+
})),
|
|
56
|
+
}));
|
|
57
|
+
|
|
58
|
+
$: xlbls = xLabels.map((lbl, i) => ({
|
|
59
|
+
lbl,
|
|
60
|
+
x: LABEL_W + (xLabels.length > 1 ? i / (xLabels.length - 1) : 0) * trackW,
|
|
61
|
+
anchor: i === 0 ? 'start' : i === xLabels.length - 1 ? 'end' : 'middle',
|
|
62
|
+
}));
|
|
63
|
+
</script>
|
|
64
|
+
|
|
65
|
+
<div role="img" aria-label={ariaLabel} style="width:100%;">
|
|
66
|
+
<svg viewBox="0 0 {VW} {totalH}" style="width:100%;height:auto;display:block;" aria-hidden="true" focusable="false">
|
|
67
|
+
{#each rows as row}
|
|
68
|
+
<text x={LABEL_W - 8} y={row.midY} text-anchor="end" fill="#A4A7B5" font-size="11" font-family="inherit">
|
|
69
|
+
{row.label}
|
|
70
|
+
</text>
|
|
71
|
+
<rect x={LABEL_W} y={row.y} width={trackW} height={ROW_H} fill="rgba(255,255,255,0.04)" rx="3" />
|
|
72
|
+
{#each row.segs as seg}
|
|
73
|
+
<rect x={seg.x} y={row.y} width={seg.w} height={ROW_H} fill={seg.color} rx="2" fill-opacity="0.85" />
|
|
74
|
+
{/each}
|
|
75
|
+
{/each}
|
|
76
|
+
|
|
77
|
+
{#each xlbls as { lbl, x, anchor }}
|
|
78
|
+
<text {x} y={xlblY} text-anchor={anchor} fill="#6E7079" font-size="10" font-family="inherit">{lbl}</text>
|
|
79
|
+
{/each}
|
|
80
|
+
|
|
81
|
+
{#each LEGEND as { status, label }, i}
|
|
82
|
+
<rect x={LABEL_W + i * 80} y={legY - 8} width="12" height="8" fill={STATUS_COLOR[status]} rx="2" fill-opacity="0.85" />
|
|
83
|
+
<text x={LABEL_W + i * 80 + 16} y={legY} fill="#6E7079" font-size="10" font-family="inherit">{label}</text>
|
|
84
|
+
{/each}
|
|
85
|
+
</svg>
|
|
86
|
+
</div>
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
export interface VennSet {
|
|
3
|
+
id: string;
|
|
4
|
+
label: string;
|
|
5
|
+
value: number;
|
|
6
|
+
color?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface VennIntersection {
|
|
9
|
+
sets: string[];
|
|
10
|
+
value: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export let sets: VennSet[] = [];
|
|
14
|
+
export let intersections: VennIntersection[] = [];
|
|
15
|
+
export let height = 240;
|
|
16
|
+
export let ariaLabel = 'Venn diagram';
|
|
17
|
+
|
|
18
|
+
const PALETTE = ['#006FFF', '#00C875', '#A78BFA'];
|
|
19
|
+
const VW = 340;
|
|
20
|
+
|
|
21
|
+
function fmt(n: number): string {
|
|
22
|
+
return n >= 1000 ? `${(n / 1000).toFixed(1)}k` : String(n);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
$: valid = sets.length >= 2 && sets.length <= 3;
|
|
26
|
+
$: is3 = sets.length === 3;
|
|
27
|
+
$: cx = VW / 2;
|
|
28
|
+
$: cy = height / 2;
|
|
29
|
+
|
|
30
|
+
$: circles = is3
|
|
31
|
+
? [
|
|
32
|
+
{ x: cx, y: cy - 40, r: 75 },
|
|
33
|
+
{ x: cx - 65, y: cy + 50, r: 75 },
|
|
34
|
+
{ x: cx + 65, y: cy + 50, r: 75 },
|
|
35
|
+
]
|
|
36
|
+
: [
|
|
37
|
+
{ x: cx - 58, y: cy, r: 85 },
|
|
38
|
+
{ x: cx + 58, y: cy, r: 85 },
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
$: exclusiveValues = sets.map((s) =>
|
|
42
|
+
Math.max(
|
|
43
|
+
0,
|
|
44
|
+
s.value -
|
|
45
|
+
intersections
|
|
46
|
+
.filter((i) => i.sets.includes(s.id))
|
|
47
|
+
.reduce((sum, i) => sum + i.value, 0),
|
|
48
|
+
),
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
function getPt(inter: VennIntersection): { x: number; y: number } | null {
|
|
52
|
+
const idxById: Record<string, number> = {};
|
|
53
|
+
sets.forEach((s, i) => { idxById[s.id] = i; });
|
|
54
|
+
const idxs = inter.sets
|
|
55
|
+
.map((id) => idxById[id])
|
|
56
|
+
.filter((v) => v !== undefined)
|
|
57
|
+
.sort((a, b) => a - b);
|
|
58
|
+
if (!is3) return { x: cx, y: cy };
|
|
59
|
+
if (idxs.length >= 3) return { x: cx, y: cy + 18 };
|
|
60
|
+
if (idxs[0] === 0 && idxs[1] === 1) return { x: cx - 33, y: cy + 4 };
|
|
61
|
+
if (idxs[0] === 0 && idxs[1] === 2) return { x: cx + 33, y: cy + 4 };
|
|
62
|
+
if (idxs[0] === 1 && idxs[1] === 2) return { x: cx, y: cy + 50 };
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
</script>
|
|
66
|
+
|
|
67
|
+
{#if valid}
|
|
68
|
+
<div role="img" aria-label={ariaLabel} style="width:100%;">
|
|
69
|
+
<svg viewBox="0 0 {VW} {height}" style="width:100%;height:auto;display:block;" aria-hidden="true" focusable="false">
|
|
70
|
+
{#each sets as s, i}
|
|
71
|
+
{@const c = circles[i]}
|
|
72
|
+
{@const color = s.color ?? PALETTE[i % PALETTE.length]}
|
|
73
|
+
<circle cx={c.x} cy={c.y} r={c.r} fill={color} fill-opacity="0.15" stroke={color} stroke-opacity="0.55" stroke-width="1.5" />
|
|
74
|
+
{/each}
|
|
75
|
+
|
|
76
|
+
{#each sets as s, i}
|
|
77
|
+
{@const c = circles[i]}
|
|
78
|
+
{@const color = s.color ?? PALETTE[i % PALETTE.length]}
|
|
79
|
+
<text x={c.x} y={c.y - 8} fill={color} font-size="11" text-anchor="middle" font-family="inherit" font-weight="600">{s.label}</text>
|
|
80
|
+
<text x={c.x} y={c.y + 8} fill="#A4A7B5" font-size="10" text-anchor="middle" font-family="inherit">{fmt(exclusiveValues[i])}</text>
|
|
81
|
+
{/each}
|
|
82
|
+
|
|
83
|
+
{#each intersections as inter}
|
|
84
|
+
{@const pt = getPt(inter)}
|
|
85
|
+
{#if pt}
|
|
86
|
+
<text x={pt.x} y={pt.y} fill="rgba(255,255,255,0.65)" font-size="10" text-anchor="middle" font-family="inherit">{fmt(inter.value)}</text>
|
|
87
|
+
{/if}
|
|
88
|
+
{/each}
|
|
89
|
+
</svg>
|
|
90
|
+
</div>
|
|
91
|
+
{/if}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
export interface ViolinSeries {
|
|
3
|
+
label: string;
|
|
4
|
+
values: number[];
|
|
5
|
+
color?: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export let series: ViolinSeries[] = [];
|
|
9
|
+
export let yRange: [number, number] | undefined = undefined;
|
|
10
|
+
export let height: number = 160;
|
|
11
|
+
export let ariaLabel: string = 'Violin plot';
|
|
12
|
+
|
|
13
|
+
const COLORS = ['#006FFF', '#00C8C8', '#F5A623', '#7FB6FF', '#A878F5', '#F56342'];
|
|
14
|
+
const SQRT_TWO_PI = Math.sqrt(2 * Math.PI);
|
|
15
|
+
const NUM_PTS = 60;
|
|
16
|
+
|
|
17
|
+
function bw(vals: number[]): number {
|
|
18
|
+
const n = vals.length;
|
|
19
|
+
const m = vals.reduce((a, b) => a + b, 0) / n;
|
|
20
|
+
const s = Math.sqrt(vals.reduce((a, b) => a + (b - m) ** 2, 0) / n);
|
|
21
|
+
return Math.max(0.9 * s * Math.pow(n, -0.2), 0.5);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function kde(vals: number[], h: number, pts: number[]): number[] {
|
|
25
|
+
const n = vals.length;
|
|
26
|
+
const c = 1 / (n * h * SQRT_TWO_PI);
|
|
27
|
+
return pts.map(y => c * vals.reduce((acc, x) => {
|
|
28
|
+
const z = (y - x) / h;
|
|
29
|
+
return acc + Math.exp(-0.5 * z * z);
|
|
30
|
+
}, 0));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function med(vals: number[]): number {
|
|
34
|
+
const s = [...vals].sort((a, b) => a - b);
|
|
35
|
+
const m = Math.floor(s.length / 2);
|
|
36
|
+
return s.length % 2 ? s[m] : (s[m - 1] + s[m]) / 2;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const VW = 380;
|
|
40
|
+
$: VH = height;
|
|
41
|
+
const PAD_L = 28;
|
|
42
|
+
const PAD_R = 8;
|
|
43
|
+
const PAD_T = 8;
|
|
44
|
+
const PAD_B = 20;
|
|
45
|
+
|
|
46
|
+
$: allVals = series.flatMap(s => s.values);
|
|
47
|
+
$: yMin = yRange ? yRange[0] : Math.min(...allVals);
|
|
48
|
+
$: yMax = yRange ? yRange[1] : Math.max(...allVals);
|
|
49
|
+
|
|
50
|
+
$: TRACK_W = VW - PAD_L - PAD_R;
|
|
51
|
+
$: TRACK_H = VH - PAD_T - PAD_B;
|
|
52
|
+
$: slotW = TRACK_W / series.length;
|
|
53
|
+
$: maxHalfW = slotW * 0.38;
|
|
54
|
+
|
|
55
|
+
$: evalPts = Array.from({ length: NUM_PTS }, (_, i) =>
|
|
56
|
+
yMin + (i / (NUM_PTS - 1)) * (yMax - yMin)
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
function ySvg(v: number): number {
|
|
60
|
+
return PAD_T + ((yMax - v) / (yMax - yMin)) * TRACK_H;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
$: violins = series.map((s, si) => {
|
|
64
|
+
const h = bw(s.values);
|
|
65
|
+
const dens = kde(s.values, h, evalPts);
|
|
66
|
+
const maxD = Math.max(...dens, 1e-9);
|
|
67
|
+
const cx = PAD_L + si * slotW + slotW / 2;
|
|
68
|
+
const pts = evalPts.map((v, i) => ({ x: (dens[i] / maxD) * maxHalfW, y: ySvg(v) }));
|
|
69
|
+
const right = pts.map(p => `${(cx + p.x).toFixed(1)},${p.y.toFixed(1)}`);
|
|
70
|
+
const left = [...pts].reverse().map(p => `${(cx - p.x).toFixed(1)},${p.y.toFixed(1)}`);
|
|
71
|
+
const d = `M${cx},${ySvg(yMin)} L${right.join(' L')} L${left.join(' L')} Z`;
|
|
72
|
+
const median = med(s.values);
|
|
73
|
+
return {
|
|
74
|
+
d,
|
|
75
|
+
cx,
|
|
76
|
+
medY: ySvg(median),
|
|
77
|
+
maxHalfW,
|
|
78
|
+
color: s.color ?? COLORS[si % COLORS.length],
|
|
79
|
+
label: s.label,
|
|
80
|
+
};
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
$: ticks = [0, 0.25, 0.5, 0.75, 1].map(t => {
|
|
84
|
+
const v = yMin + t * (yMax - yMin);
|
|
85
|
+
return { v, y: ySvg(v) };
|
|
86
|
+
});
|
|
87
|
+
</script>
|
|
88
|
+
|
|
89
|
+
<div role="img" aria-label={ariaLabel} style="width:100%;">
|
|
90
|
+
<svg
|
|
91
|
+
viewBox="0 0 {VW} {VH}"
|
|
92
|
+
style="width:100%;height:auto;display:block;"
|
|
93
|
+
aria-hidden="true"
|
|
94
|
+
focusable="false"
|
|
95
|
+
>
|
|
96
|
+
{#each ticks as tick (tick.v)}
|
|
97
|
+
<line x1={PAD_L} y1={tick.y} x2={VW - PAD_R} y2={tick.y} stroke="rgba(255,255,255,0.06)" stroke-width="1" />
|
|
98
|
+
<text x={PAD_L - 3} y={tick.y + 3} fill="#6E7079" font-size="8" text-anchor="end" font-family="inherit">{tick.v.toFixed(0)}</text>
|
|
99
|
+
{/each}
|
|
100
|
+
{#each violins as v, si (si)}
|
|
101
|
+
<path d={v.d} fill={v.color} opacity="0.72" />
|
|
102
|
+
<line
|
|
103
|
+
x1={v.cx - v.maxHalfW * 0.45}
|
|
104
|
+
y1={v.medY}
|
|
105
|
+
x2={v.cx + v.maxHalfW * 0.45}
|
|
106
|
+
y2={v.medY}
|
|
107
|
+
stroke="#fff"
|
|
108
|
+
stroke-width="1.5"
|
|
109
|
+
stroke-linecap="round"
|
|
110
|
+
/>
|
|
111
|
+
<text x={v.cx} y={VH - 5} fill="#6E7079" font-size="8" text-anchor="middle" font-family="inherit">{v.label}</text>
|
|
112
|
+
{/each}
|
|
113
|
+
</svg>
|
|
114
|
+
</div>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
export let items: unknown[] = [];
|
|
3
|
+
export let itemHeight: number = 48;
|
|
4
|
+
export let height: number = 400;
|
|
5
|
+
export let label: string | undefined = undefined;
|
|
6
|
+
export let overscan: number = 3;
|
|
7
|
+
|
|
8
|
+
let scrollTop = 0;
|
|
9
|
+
|
|
10
|
+
$: totalHeight = items.length * itemHeight;
|
|
11
|
+
$: firstVisible = Math.floor(scrollTop / itemHeight);
|
|
12
|
+
$: startIndex = Math.max(0, firstVisible - overscan);
|
|
13
|
+
$: endIndex = Math.min(items.length, firstVisible + Math.ceil(height / itemHeight) + overscan + 1);
|
|
14
|
+
$: visible = items.slice(startIndex, endIndex).map((item, i) => ({ item, index: startIndex + i }));
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<div
|
|
18
|
+
role="list"
|
|
19
|
+
aria-label={label}
|
|
20
|
+
class="vl"
|
|
21
|
+
style:height="{height}px"
|
|
22
|
+
style:overflow-y="auto"
|
|
23
|
+
on:scroll={(e) => (scrollTop = e.currentTarget.scrollTop)}
|
|
24
|
+
>
|
|
25
|
+
<div style:height="{totalHeight}px" style:position="relative">
|
|
26
|
+
<div style:position="absolute" style:top="{startIndex * itemHeight}px" style:width="100%">
|
|
27
|
+
{#each visible as { item, index } (index)}
|
|
28
|
+
<div
|
|
29
|
+
role="listitem"
|
|
30
|
+
style:height="{itemHeight}px"
|
|
31
|
+
style:overflow="hidden"
|
|
32
|
+
>
|
|
33
|
+
<slot {item} {index} />
|
|
34
|
+
</div>
|
|
35
|
+
{/each}
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
export interface WaffleSegment {
|
|
3
|
+
label: string;
|
|
4
|
+
value: number;
|
|
5
|
+
color?: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export let segments: WaffleSegment[] = [];
|
|
9
|
+
export let total: number | undefined = undefined;
|
|
10
|
+
export let cols: number = 10;
|
|
11
|
+
export let rows: number = 10;
|
|
12
|
+
export let gap: number = 2;
|
|
13
|
+
export let ariaLabel: string = 'Waffle chart';
|
|
14
|
+
|
|
15
|
+
const COLORS = ['#006FFF', '#00C7A8', '#F5A623', '#FF6B6B', '#A78BFA'];
|
|
16
|
+
const VW = 280;
|
|
17
|
+
const LEGEND_H = 24;
|
|
18
|
+
|
|
19
|
+
$: sum = total ?? segments.reduce((s, seg) => s + seg.value, 0);
|
|
20
|
+
$: cellSize = (VW - gap * (cols - 1)) / cols;
|
|
21
|
+
$: gridH = rows * cellSize + gap * (rows - 1);
|
|
22
|
+
$: svgH = gridH + LEGEND_H + 6;
|
|
23
|
+
$: totalCells = cols * rows;
|
|
24
|
+
|
|
25
|
+
$: cellMap = (() => {
|
|
26
|
+
const map: number[] = new Array(totalCells).fill(-1);
|
|
27
|
+
let cursor = 0;
|
|
28
|
+
segments.forEach((seg, si) => {
|
|
29
|
+
const count = Math.round((seg.value / sum) * totalCells);
|
|
30
|
+
for (let j = 0; j < count && cursor < totalCells; j++, cursor++) {
|
|
31
|
+
map[cursor] = si;
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
return map;
|
|
35
|
+
})();
|
|
36
|
+
|
|
37
|
+
$: cells = Array.from({ length: totalCells }, (_, i) => {
|
|
38
|
+
const col = i % cols;
|
|
39
|
+
const row = Math.floor(i / cols);
|
|
40
|
+
const x = col * (cellSize + gap);
|
|
41
|
+
const y = row * (cellSize + gap);
|
|
42
|
+
const si = cellMap[i];
|
|
43
|
+
const fill = si >= 0 ? (segments[si].color ?? COLORS[si % COLORS.length]) : 'rgba(255,255,255,0.06)';
|
|
44
|
+
return { x, y, fill, width: cellSize, height: cellSize };
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
$: legendItems = segments.map((seg, si) => ({
|
|
48
|
+
color: seg.color ?? COLORS[si % COLORS.length],
|
|
49
|
+
pct: Math.round((seg.value / sum) * 100),
|
|
50
|
+
label: seg.label,
|
|
51
|
+
lx: si * (VW / segments.length),
|
|
52
|
+
ly: gridH + 8,
|
|
53
|
+
}));
|
|
54
|
+
</script>
|
|
55
|
+
|
|
56
|
+
<div role="img" aria-label={ariaLabel} style="width:100%;">
|
|
57
|
+
<svg viewBox="0 0 {VW} {svgH}" style="width:100%;height:auto;display:block;" aria-hidden="true" focusable="false">
|
|
58
|
+
{#each cells as cell}
|
|
59
|
+
<rect x={cell.x} y={cell.y} width={cell.width} height={cell.height} fill={cell.fill} rx="1" />
|
|
60
|
+
{/each}
|
|
61
|
+
{#each legendItems as item}
|
|
62
|
+
<rect x={item.lx} y={item.ly} width="8" height="8" fill={item.color} rx="1" />
|
|
63
|
+
<text x={item.lx + 11} y={item.ly + 7.5} fill="#A4A7B5" font-size="9" font-family="inherit">
|
|
64
|
+
{item.label} {item.pct}%
|
|
65
|
+
</text>
|
|
66
|
+
{/each}
|
|
67
|
+
</svg>
|
|
68
|
+
</div>
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
export interface WaterfallBar {
|
|
3
|
+
label: string;
|
|
4
|
+
value: number;
|
|
5
|
+
type?: 'start' | 'delta' | 'total';
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export let bars: WaterfallBar[] = [];
|
|
9
|
+
export let height: number = 160;
|
|
10
|
+
export let ariaLabel: string = 'Waterfall chart';
|
|
11
|
+
|
|
12
|
+
const VW = 320;
|
|
13
|
+
const PAD = { t: 12, r: 8, b: 24, l: 8 };
|
|
14
|
+
const COLOR_START = '#006FFF';
|
|
15
|
+
const COLOR_POS = '#00C875';
|
|
16
|
+
const COLOR_NEG = '#F04949';
|
|
17
|
+
const COLOR_TOTAL = '#A78BFA';
|
|
18
|
+
|
|
19
|
+
$: chartH = height - PAD.t - PAD.b;
|
|
20
|
+
$: chartW = VW - PAD.l - PAD.r;
|
|
21
|
+
$: n = bars.length;
|
|
22
|
+
$: colW = n > 0 ? chartW / n : chartW;
|
|
23
|
+
$: gap = colW * 0.15;
|
|
24
|
+
$: barW = colW - gap * 2;
|
|
25
|
+
|
|
26
|
+
$: cumBases = (() => {
|
|
27
|
+
const result: number[] = [];
|
|
28
|
+
let acc = 0;
|
|
29
|
+
for (const b of bars) {
|
|
30
|
+
if (b.type === 'start' || b.type === 'total') {
|
|
31
|
+
result.push(0);
|
|
32
|
+
acc = b.value;
|
|
33
|
+
} else {
|
|
34
|
+
result.push(acc);
|
|
35
|
+
acc += b.value;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return result;
|
|
39
|
+
})();
|
|
40
|
+
|
|
41
|
+
$: tops = bars.map((b, i) => {
|
|
42
|
+
if (b.type === 'start' || b.type === 'total') return b.value;
|
|
43
|
+
return cumBases[i] + b.value;
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
$: allVals = [0, ...cumBases, ...tops];
|
|
47
|
+
$: minV = allVals.length ? Math.min(...allVals) : 0;
|
|
48
|
+
$: maxV = allVals.length ? Math.max(...allVals) : 1;
|
|
49
|
+
$: range = maxV - minV || 1;
|
|
50
|
+
|
|
51
|
+
function toY(v: number): number {
|
|
52
|
+
return PAD.t + (1 - (v - minV) / range) * chartH;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
$: bot = PAD.t + chartH;
|
|
56
|
+
|
|
57
|
+
$: rects = bars.map((b, i) => {
|
|
58
|
+
const base = cumBases[i];
|
|
59
|
+
const top = b.type === 'start' || b.type === 'total' ? b.value : base + b.value;
|
|
60
|
+
const y0 = toY(Math.max(base, top));
|
|
61
|
+
const y1 = toY(Math.min(base, top));
|
|
62
|
+
const x = PAD.l + i * colW + gap;
|
|
63
|
+
const color = b.type === 'start' ? COLOR_START : b.type === 'total' ? COLOR_TOTAL : b.value >= 0 ? COLOR_POS : COLOR_NEG;
|
|
64
|
+
return { x: x.toFixed(1), y: y0.toFixed(1), w: barW.toFixed(1), h: Math.max(y1 - y0, 1).toFixed(1), color };
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
$: connectors = rects.slice(0, -1).map((r, i) => {
|
|
68
|
+
const nextX = PAD.l + (i + 1) * colW + gap;
|
|
69
|
+
return { x1: parseFloat(r.x), x2: nextX + barW + gap, y: parseFloat(r.y) };
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
$: labels = bars.map((b, i) => ({
|
|
73
|
+
x: (PAD.l + (i + 0.5) * colW).toFixed(1),
|
|
74
|
+
y: (bot + 10).toFixed(1),
|
|
75
|
+
label: b.label,
|
|
76
|
+
}));
|
|
77
|
+
|
|
78
|
+
$: gridLines = [0.25, 0.5, 0.75, 1].map((f) => (PAD.t + (1 - f) * chartH).toFixed(1));
|
|
79
|
+
</script>
|
|
80
|
+
|
|
81
|
+
<div role="img" aria-label={ariaLabel} style="width:100%;">
|
|
82
|
+
<svg viewBox="0 0 {VW} {height}" style="width:100%;height:auto;display:block;" aria-hidden="true" focusable="false">
|
|
83
|
+
{#each gridLines as y}
|
|
84
|
+
<line x1={PAD.l} y1={y} x2={VW - PAD.r} y2={y} stroke="rgba(255,255,255,0.06)" stroke-width="1" />
|
|
85
|
+
{/each}
|
|
86
|
+
{#each connectors as c}
|
|
87
|
+
<line x1={c.x1} y1={c.y} x2={c.x2} y2={c.y} stroke="rgba(255,255,255,0.2)" stroke-width="1" stroke-dasharray="2 2" />
|
|
88
|
+
{/each}
|
|
89
|
+
{#each rects as r, i}
|
|
90
|
+
<rect x={r.x} y={r.y} width={r.w} height={r.h} fill={r.color} fill-opacity="0.85" rx="2" />
|
|
91
|
+
{/each}
|
|
92
|
+
{#each labels as l}
|
|
93
|
+
<text x={l.x} y={l.y} text-anchor="middle" fill="#6E7079" font-size="9" font-family="inherit">{l.label}</text>
|
|
94
|
+
{/each}
|
|
95
|
+
</svg>
|
|
96
|
+
</div>
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
export interface WordCloudItem {
|
|
3
|
+
word: string;
|
|
4
|
+
weight: number;
|
|
5
|
+
color?: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export let items: WordCloudItem[] = [];
|
|
9
|
+
export let height: number = 160;
|
|
10
|
+
export let ariaLabel: string = 'Word cloud';
|
|
11
|
+
|
|
12
|
+
const VW = 380;
|
|
13
|
+
const PAD = 14;
|
|
14
|
+
const MIN_FONT = 9;
|
|
15
|
+
const MAX_FONT = 28;
|
|
16
|
+
const GAP = 6;
|
|
17
|
+
const COLORS = ['#006FFF', '#00C8C8', '#F5A623', '#7FB6FF', '#A878F5', '#F56342', '#00C875', '#FF7BB1'];
|
|
18
|
+
|
|
19
|
+
$: sorted = [...items].sort((a, b) => b.weight - a.weight);
|
|
20
|
+
$: maxW = sorted[0]?.weight ?? 1;
|
|
21
|
+
$: minW = sorted[sorted.length - 1]?.weight ?? 0;
|
|
22
|
+
$: range = maxW - minW || 1;
|
|
23
|
+
|
|
24
|
+
$: words = sorted.map((item, i) => {
|
|
25
|
+
const t = (item.weight - minW) / range;
|
|
26
|
+
const fontSize = MIN_FONT + t * (MAX_FONT - MIN_FONT);
|
|
27
|
+
const approxW = item.word.length * fontSize * 0.56 + GAP * 2;
|
|
28
|
+
return {
|
|
29
|
+
word: item.word,
|
|
30
|
+
weight: item.weight,
|
|
31
|
+
fontSize,
|
|
32
|
+
approxW,
|
|
33
|
+
color: item.color ?? COLORS[i % COLORS.length],
|
|
34
|
+
bold: fontSize >= 16,
|
|
35
|
+
};
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
$: placed = (() => {
|
|
39
|
+
const usableW = VW - PAD * 2;
|
|
40
|
+
const rows: (typeof words)[] = [];
|
|
41
|
+
let row: typeof words = [];
|
|
42
|
+
let rowW = 0;
|
|
43
|
+
for (const w of words) {
|
|
44
|
+
if (rowW + w.approxW > usableW && row.length > 0) {
|
|
45
|
+
rows.push(row);
|
|
46
|
+
row = [w];
|
|
47
|
+
rowW = w.approxW;
|
|
48
|
+
} else {
|
|
49
|
+
row.push(w);
|
|
50
|
+
rowW += w.approxW;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (row.length) rows.push(row);
|
|
54
|
+
|
|
55
|
+
const ROW_H = 32;
|
|
56
|
+
const totalH = rows.length * ROW_H + PAD * 2;
|
|
57
|
+
const svgH = Math.max(height, totalH);
|
|
58
|
+
const offsetY = PAD + (svgH - totalH) / 2;
|
|
59
|
+
|
|
60
|
+
return rows.flatMap((r, ri) => {
|
|
61
|
+
const rowUsed = r.reduce((s, w) => s + w.approxW, 0);
|
|
62
|
+
let x = PAD + (usableW - rowUsed) / 2;
|
|
63
|
+
const baseY = offsetY + ri * ROW_H;
|
|
64
|
+
return r.map((w) => {
|
|
65
|
+
const cx = x + w.approxW / 2;
|
|
66
|
+
x += w.approxW;
|
|
67
|
+
return { ...w, cx, cy: baseY + w.fontSize };
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
})();
|
|
71
|
+
|
|
72
|
+
$: svgH = (() => {
|
|
73
|
+
const ROW_H = 32;
|
|
74
|
+
const usableW = VW - PAD * 2;
|
|
75
|
+
let rows = 1; let rowW = 0;
|
|
76
|
+
for (const w of words) {
|
|
77
|
+
if (rowW + w.approxW > usableW && rowW > 0) { rows++; rowW = w.approxW; }
|
|
78
|
+
else rowW += w.approxW;
|
|
79
|
+
}
|
|
80
|
+
return Math.max(height, rows * ROW_H + PAD * 2);
|
|
81
|
+
})();
|
|
82
|
+
</script>
|
|
83
|
+
|
|
84
|
+
<div role="img" aria-label={ariaLabel} style="width:100%;">
|
|
85
|
+
<svg
|
|
86
|
+
viewBox="0 0 {VW} {svgH}"
|
|
87
|
+
style="width:100%;height:auto;display:block;"
|
|
88
|
+
aria-hidden="true"
|
|
89
|
+
focusable="false"
|
|
90
|
+
>
|
|
91
|
+
{#each placed as w (w.word)}
|
|
92
|
+
<text
|
|
93
|
+
x={w.cx}
|
|
94
|
+
y={w.cy}
|
|
95
|
+
text-anchor="middle"
|
|
96
|
+
fill={w.color}
|
|
97
|
+
font-size={w.fontSize}
|
|
98
|
+
font-weight={w.bold ? 600 : 400}
|
|
99
|
+
font-family="inherit"
|
|
100
|
+
>{w.word}</text>
|
|
101
|
+
{/each}
|
|
102
|
+
</svg>
|
|
103
|
+
</div>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<script lang="ts">export let size: number = 16;</script>
|
|
2
|
+
<svg width={size} height={size} viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false">
|
|
3
|
+
<path d="m8 2 6 11H2L8 2Z" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round" />
|
|
4
|
+
<path d="M8 7v3M8 11.5h.01" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" />
|
|
5
|
+
</svg>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
export let size: number = 16;
|
|
3
|
+
</script>
|
|
4
|
+
<svg width={size} height={size} viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false">
|
|
5
|
+
<path d="M4 6.5a4 4 0 0 1 8 0V9l1.2 2H2.8L4 9V6.5ZM6.5 12.5a1.5 1.5 0 0 0 3 0" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
|
|
6
|
+
</svg>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
let className = '';
|
|
3
|
+
export { className as class };
|
|
4
|
+
export let size: number = 14;
|
|
5
|
+
</script>
|
|
6
|
+
<svg width={size} height={size} viewBox="0 0 20 20" fill="none" aria-hidden="true" focusable="false" class={className}>
|
|
7
|
+
<path d="M5.5 8 10 12.5 14.5 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
|
|
8
|
+
</svg>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<script lang="ts">export let size: number = 16;</script>
|
|
2
|
+
<svg width={size} height={size} viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false">
|
|
3
|
+
<circle cx="8" cy="6" r="2.5" stroke="currentColor" stroke-width="1.5" />
|
|
4
|
+
<path d="M3 13c0-2.5 2.2-4.5 5-4.5s5 2 5 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" />
|
|
5
|
+
</svg>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
export let size: number = 14;
|
|
3
|
+
</script>
|
|
4
|
+
<svg width={size} height={size} viewBox="0 0 14 14" fill="none" aria-hidden="true" focusable="false">
|
|
5
|
+
<path d="M3 3l8 8M11 3l-8 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" />
|
|
6
|
+
</svg>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<script lang="ts">export let size: number = 16;</script>
|
|
2
|
+
<svg width={size} height={size} viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false">
|
|
3
|
+
<rect x="2" y="2" width="5" height="5" rx="1" stroke="currentColor" stroke-width="1.5" />
|
|
4
|
+
<rect x="9" y="2" width="5" height="5" rx="1" stroke="currentColor" stroke-width="1.5" />
|
|
5
|
+
<rect x="2" y="9" width="5" height="5" rx="1" stroke="currentColor" stroke-width="1.5" />
|
|
6
|
+
<rect x="9" y="9" width="5" height="5" rx="1" stroke="currentColor" stroke-width="1.5" />
|
|
7
|
+
</svg>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<script lang="ts">export let size: number = 16;</script>
|
|
2
|
+
<svg width={size} height={size} viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false">
|
|
3
|
+
<rect x="2.5" y="3.5" width="11" height="9" rx="1.5" stroke="currentColor" stroke-width="1.5" />
|
|
4
|
+
<line x1="2.5" y1="6.5" x2="13.5" y2="6.5" stroke="currentColor" stroke-width="1.5" />
|
|
5
|
+
</svg>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
export let size: number = 14;
|
|
3
|
+
</script>
|
|
4
|
+
<svg width={size} height={size} viewBox="0 0 14 14" fill="none" aria-hidden="true" focusable="false">
|
|
5
|
+
<path d="M7 1.5v7m0 0L4.5 6m2.5 2.5L9.5 6M2 11h10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
|
|
6
|
+
</svg>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
export let size: number = 16;
|
|
3
|
+
</script>
|
|
4
|
+
<svg width={size} height={size} viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false">
|
|
5
|
+
<circle cx="8" cy="8" r="6" stroke="currentColor" stroke-width="1.5" />
|
|
6
|
+
<path d="M6.4 6.2c.2-1 1-1.5 1.9-1.5 1.1 0 1.9.7 1.9 1.7s-.6 1.4-1.4 1.8c-.6.3-1 .6-1 1.2v.3M8 11.6h0" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" />
|
|
7
|
+
</svg>
|