@w5-ui/svelte 0.1.0 → 0.2.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.
Files changed (191) hide show
  1. package/package.json +4 -4
  2. package/src/lib/components/Accordion.svelte +9 -1
  3. package/src/lib/components/AccordionItem.svelte +11 -5
  4. package/src/lib/components/ActionMenu.svelte +19 -14
  5. package/src/lib/components/ActivityFeed.svelte +24 -11
  6. package/src/lib/components/Alert.svelte +9 -4
  7. package/src/lib/components/AnnotatedTimeSeries.svelte +40 -26
  8. package/src/lib/components/ArcDiagram.svelte +20 -8
  9. package/src/lib/components/AreaChart.svelte +26 -14
  10. package/src/lib/components/Avatar.svelte +20 -8
  11. package/src/lib/components/AvatarGroup.svelte +16 -7
  12. package/src/lib/components/Badge.svelte +24 -11
  13. package/src/lib/components/Banner.svelte +20 -9
  14. package/src/lib/components/BarChart.svelte +29 -17
  15. package/src/lib/components/BeeswarmChart.svelte +32 -18
  16. package/src/lib/components/BoxPlot.svelte +27 -15
  17. package/src/lib/components/Breadcrumb.svelte +12 -7
  18. package/src/lib/components/BubbleChart.svelte +39 -25
  19. package/src/lib/components/BulletChart.svelte +16 -9
  20. package/src/lib/components/BumpChart.svelte +15 -8
  21. package/src/lib/components/Button.svelte +32 -11
  22. package/src/lib/components/CIDRInput.svelte +27 -19
  23. package/src/lib/components/CalendarHeatmap.svelte +12 -5
  24. package/src/lib/components/Callout.svelte +9 -4
  25. package/src/lib/components/CandlestickChart.svelte +31 -16
  26. package/src/lib/components/Card.svelte +16 -6
  27. package/src/lib/components/Carousel.svelte +14 -11
  28. package/src/lib/components/Checkbox.svelte +37 -16
  29. package/src/lib/components/ChordDiagram.svelte +12 -5
  30. package/src/lib/components/CirclePacking.svelte +13 -6
  31. package/src/lib/components/CodeBlock.svelte +16 -7
  32. package/src/lib/components/ColorPicker.svelte +22 -11
  33. package/src/lib/components/ColumnToggle.svelte +18 -11
  34. package/src/lib/components/Combobox.svelte +44 -33
  35. package/src/lib/components/CommandPalette.svelte +41 -31
  36. package/src/lib/components/ConfirmDialog.svelte +66 -35
  37. package/src/lib/components/ContextMenu.svelte +46 -33
  38. package/src/lib/components/ContextualHelp.svelte +13 -9
  39. package/src/lib/components/ContourPlot.svelte +43 -28
  40. package/src/lib/components/CopyButton.svelte +8 -4
  41. package/src/lib/components/CorrelationMatrix.svelte +16 -7
  42. package/src/lib/components/CountUp.svelte +30 -13
  43. package/src/lib/components/CumulativeDistribution.svelte +32 -19
  44. package/src/lib/components/DatePicker.svelte +28 -21
  45. package/src/lib/components/DateRangePicker.svelte +39 -32
  46. package/src/lib/components/Dendrogram.svelte +18 -6
  47. package/src/lib/components/Donut.svelte +28 -14
  48. package/src/lib/components/DotPlot.svelte +31 -16
  49. package/src/lib/components/Drawer.svelte +28 -21
  50. package/src/lib/components/DualAxisChart.svelte +39 -26
  51. package/src/lib/components/DumbbellChart.svelte +24 -12
  52. package/src/lib/components/DurationInput.svelte +26 -17
  53. package/src/lib/components/EmptyState.svelte +16 -6
  54. package/src/lib/components/ErrorBandChart.svelte +28 -14
  55. package/src/lib/components/ExpandableRow.svelte +19 -6
  56. package/src/lib/components/Field.svelte +26 -12
  57. package/src/lib/components/FileUpload.svelte +29 -20
  58. package/src/lib/components/FilterBuilder.svelte +27 -17
  59. package/src/lib/components/FlameGraph.svelte +14 -7
  60. package/src/lib/components/ForceGraph.svelte +19 -7
  61. package/src/lib/components/FunnelChart.svelte +20 -13
  62. package/src/lib/components/GanttChart.svelte +14 -7
  63. package/src/lib/components/Gauge.svelte +26 -16
  64. package/src/lib/components/GroupedList.svelte +13 -6
  65. package/src/lib/components/HealthBar.svelte +14 -5
  66. package/src/lib/components/HeatMap.svelte +28 -17
  67. package/src/lib/components/HexbinChart.svelte +36 -22
  68. package/src/lib/components/Histogram.svelte +27 -14
  69. package/src/lib/components/HorizonChart.svelte +28 -16
  70. package/src/lib/components/HoverCard.svelte +24 -12
  71. package/src/lib/components/IPInput.svelte +24 -16
  72. package/src/lib/components/IcicleChart.svelte +14 -7
  73. package/src/lib/components/IconButton.svelte +27 -9
  74. package/src/lib/components/InlineEdit.svelte +22 -12
  75. package/src/lib/components/Input.svelte +67 -10
  76. package/src/lib/components/InputGroup.svelte +8 -3
  77. package/src/lib/components/JsonViewer.svelte +17 -6
  78. package/src/lib/components/JsonViewerNode.svelte +36 -18
  79. package/src/lib/components/KVTable.svelte +6 -2
  80. package/src/lib/components/KanbanBoard.svelte +24 -17
  81. package/src/lib/components/Kbd.svelte +8 -4
  82. package/src/lib/components/LineChart.svelte +29 -17
  83. package/src/lib/components/LogViewer.svelte +27 -12
  84. package/src/lib/components/LollipopChart.svelte +20 -8
  85. package/src/lib/components/MACInput.svelte +24 -16
  86. package/src/lib/components/MarimekkoChart.svelte +14 -7
  87. package/src/lib/components/MatrixChart.svelte +19 -9
  88. package/src/lib/components/Menubar.svelte +26 -19
  89. package/src/lib/components/MirroredBarChart.svelte +25 -10
  90. package/src/lib/components/Modal.svelte +46 -33
  91. package/src/lib/components/MultiSelect.svelte +49 -38
  92. package/src/lib/components/NightingaleChart.svelte +17 -10
  93. package/src/lib/components/NotificationPanel.svelte +48 -33
  94. package/src/lib/components/NumberInput.svelte +37 -23
  95. package/src/lib/components/OTPInput.svelte +28 -16
  96. package/src/lib/components/Pagination.svelte +16 -13
  97. package/src/lib/components/ParallelCoordinates.svelte +28 -16
  98. package/src/lib/components/ParetoChart.svelte +38 -24
  99. package/src/lib/components/PasswordInput.svelte +24 -14
  100. package/src/lib/components/PieChart.svelte +21 -13
  101. package/src/lib/components/Pill.svelte +17 -6
  102. package/src/lib/components/PolarHeatmap.svelte +32 -18
  103. package/src/lib/components/Popover.svelte +22 -11
  104. package/src/lib/components/ProgressBar.svelte +17 -8
  105. package/src/lib/components/PunchCard.svelte +31 -20
  106. package/src/lib/components/QuadrantChart.svelte +50 -30
  107. package/src/lib/components/RadarChart.svelte +30 -18
  108. package/src/lib/components/RadialBarChart.svelte +14 -7
  109. package/src/lib/components/RadioGroup.svelte +20 -8
  110. package/src/lib/components/RangeSlider.svelte +30 -18
  111. package/src/lib/components/RankedList.svelte +18 -6
  112. package/src/lib/components/ResizablePanel.svelte +33 -17
  113. package/src/lib/components/RidgelinePlot.svelte +33 -21
  114. package/src/lib/components/RowToggle.svelte +15 -5
  115. package/src/lib/components/SankeyDiagram.svelte +18 -6
  116. package/src/lib/components/ScatterPlot.svelte +34 -21
  117. package/src/lib/components/SearchBox.svelte +27 -5
  118. package/src/lib/components/SegmentedControl.svelte +11 -7
  119. package/src/lib/components/Select.svelte +37 -26
  120. package/src/lib/components/SelectionToolbar.svelte +25 -11
  121. package/src/lib/components/Sidebar.svelte +15 -9
  122. package/src/lib/components/Signal.svelte +6 -2
  123. package/src/lib/components/Skeleton.svelte +20 -10
  124. package/src/lib/components/SkipLink.svelte +9 -4
  125. package/src/lib/components/Slider.svelte +28 -14
  126. package/src/lib/components/SlopeChart.svelte +35 -21
  127. package/src/lib/components/SortHeader.svelte +20 -9
  128. package/src/lib/components/SortableList.svelte +20 -13
  129. package/src/lib/components/Sparkline.svelte +15 -6
  130. package/src/lib/components/SparklineMatrix.svelte +17 -10
  131. package/src/lib/components/Spinner.svelte +7 -3
  132. package/src/lib/components/SplitButton.svelte +28 -17
  133. package/src/lib/components/Spoiler.svelte +22 -11
  134. package/src/lib/components/StackedBarChart.svelte +35 -22
  135. package/src/lib/components/StackedProgress.svelte +21 -9
  136. package/src/lib/components/StarRating.svelte +22 -11
  137. package/src/lib/components/Stat.svelte +32 -10
  138. package/src/lib/components/StatusIndicator.svelte +7 -3
  139. package/src/lib/components/StepChart.svelte +27 -15
  140. package/src/lib/components/Stepper.svelte +10 -6
  141. package/src/lib/components/StreamGraph.svelte +19 -12
  142. package/src/lib/components/StripeChart.svelte +22 -12
  143. package/src/lib/components/SunburstChart.svelte +11 -4
  144. package/src/lib/components/SwitchPortGrid.svelte +13 -7
  145. package/src/lib/components/TabPanel.svelte +9 -4
  146. package/src/lib/components/Tabs.svelte +18 -10
  147. package/src/lib/components/Tag.svelte +9 -5
  148. package/src/lib/components/TagInput.svelte +28 -18
  149. package/src/lib/components/Textarea.svelte +37 -15
  150. package/src/lib/components/ThresholdAreaChart.svelte +34 -21
  151. package/src/lib/components/TimePicker.svelte +25 -17
  152. package/src/lib/components/TimeRange.svelte +19 -14
  153. package/src/lib/components/Timeline.svelte +8 -4
  154. package/src/lib/components/Toast.svelte +2 -2
  155. package/src/lib/components/Toggle.svelte +13 -7
  156. package/src/lib/components/ToggleGroup.svelte +19 -11
  157. package/src/lib/components/Tooltip.svelte +16 -6
  158. package/src/lib/components/Topbar.svelte +24 -10
  159. package/src/lib/components/TransferList.svelte +34 -27
  160. package/src/lib/components/TreeItem.svelte +23 -10
  161. package/src/lib/components/TreeMap.svelte +13 -6
  162. package/src/lib/components/TreeView.svelte +24 -12
  163. package/src/lib/components/UptimeTimeline.svelte +22 -15
  164. package/src/lib/components/VennDiagram.svelte +25 -13
  165. package/src/lib/components/ViolinPlot.svelte +31 -19
  166. package/src/lib/components/VirtualList.svelte +25 -13
  167. package/src/lib/components/WaffleChart.svelte +32 -18
  168. package/src/lib/components/WaterfallChart.svelte +33 -26
  169. package/src/lib/components/WordCloud.svelte +21 -14
  170. package/src/lib/icons/AlarmIcon.svelte +4 -1
  171. package/src/lib/icons/BellIcon.svelte +2 -1
  172. package/src/lib/icons/CaretIcon.svelte +5 -3
  173. package/src/lib/icons/ClientsIcon.svelte +4 -1
  174. package/src/lib/icons/CloseIcon.svelte +2 -1
  175. package/src/lib/icons/DashboardIcon.svelte +4 -1
  176. package/src/lib/icons/DevicesIcon.svelte +4 -1
  177. package/src/lib/icons/DownloadIcon.svelte +2 -1
  178. package/src/lib/icons/HelpIcon.svelte +2 -1
  179. package/src/lib/icons/InfraIcon.svelte +4 -1
  180. package/src/lib/icons/IntegrationsIcon.svelte +4 -1
  181. package/src/lib/icons/LogsIcon.svelte +4 -1
  182. package/src/lib/icons/PlusIcon.svelte +2 -1
  183. package/src/lib/icons/PortsIcon.svelte +4 -1
  184. package/src/lib/icons/SearchIcon.svelte +6 -4
  185. package/src/lib/icons/SecurityIcon.svelte +4 -1
  186. package/src/lib/icons/SettingsIcon.svelte +4 -1
  187. package/src/lib/icons/TopologyIcon.svelte +4 -1
  188. package/src/lib/icons/UpdatesIcon.svelte +2 -1
  189. package/src/lib/icons/VpnIcon.svelte +4 -1
  190. package/src/lib/icons/WifiIcon.svelte +4 -1
  191. package/src/lib/icons/WirelessIcon.svelte +4 -1
@@ -1,33 +1,47 @@
1
- <script lang="ts">
1
+ <script module lang="ts">
2
2
  export interface ParetoItem {
3
3
  label: string;
4
4
  value: number;
5
5
  color?: string;
6
6
  }
7
+ </script>
8
+
9
+ <script lang="ts">
10
+
11
+ interface Props {
12
+ items?: ParetoItem[];
13
+ height?: number;
14
+ ariaLabel?: string;
15
+ barColor?: string;
16
+ lineColor?: string;
17
+ threshold?: number;
18
+ }
7
19
 
8
- export let items: ParetoItem[] = [];
9
- export let height: number = 160;
10
- export let ariaLabel: string = 'Pareto chart';
11
- export let barColor: string = '#006FFF';
12
- export let lineColor: string = '#F5A623';
13
- export let threshold: number = 0.8;
20
+ let {
21
+ items = [],
22
+ height = 160,
23
+ ariaLabel = 'Pareto chart',
24
+ barColor = '#006FFF',
25
+ lineColor = '#F5A623',
26
+ threshold = 0.8
27
+ }: Props = $props();
14
28
 
15
29
  const VW = 400;
16
30
  const PAD = { t: 12, r: 40, b: 28, l: 8 };
17
31
 
18
- $: sorted = [...items].sort((a, b) => b.value - a.value);
19
- $: total = sorted.reduce((s, it) => s + it.value, 0) || 1;
20
- $: chartW = VW - PAD.l - PAD.r;
21
- $: chartH = height - PAD.t - PAD.b;
22
- $: bot = PAD.t + chartH;
23
- $: maxV = sorted[0]?.value || 1;
24
- $: barW = sorted.length > 0 ? chartW / sorted.length : chartW;
25
- $: gap = barW * 0.15;
26
- $: bw = Math.max(barW - gap * 2, 1);
32
+ let sorted = $derived([...items].sort((a, b) => b.value - a.value));
33
+ let total = $derived(sorted.reduce((s, it) => s + it.value, 0) || 1);
34
+ let chartW = $derived(VW - PAD.l - PAD.r);
35
+ let chartH = $derived(height - PAD.t - PAD.b);
36
+ let bot = $derived(PAD.t + chartH);
37
+ let maxV = $derived(sorted[0]?.value || 1);
38
+ let barW = $derived(sorted.length > 0 ? chartW / sorted.length : chartW);
39
+ let gap = $derived(barW * 0.15);
40
+ let bw = $derived(Math.max(barW - gap * 2, 1));
27
41
 
28
- $: gridLines = [0.25, 0.5, 0.75, 1].map((f) => PAD.t + (1 - f) * chartH);
42
+ let gridLines = $derived([0.25, 0.5, 0.75, 1].map((f) => PAD.t + (1 - f) * chartH));
29
43
 
30
- $: bars = sorted.map((item, i) => {
44
+ let bars = $derived(sorted.map((item, i) => {
31
45
  const bh = (item.value / maxV) * chartH;
32
46
  const x = PAD.l + i * barW + gap;
33
47
  return {
@@ -39,9 +53,9 @@
39
53
  color: item.color ?? barColor,
40
54
  key: `b${i}`,
41
55
  };
42
- });
56
+ }));
43
57
 
44
- $: linePoints = (() => {
58
+ let linePoints = $derived((() => {
45
59
  let cumSum = 0;
46
60
  const pts: string[] = [`${PAD.l},${bot}`];
47
61
  sorted.forEach((item, i) => {
@@ -52,14 +66,14 @@
52
66
  pts.push(`${x.toFixed(1)},${y.toFixed(1)}`);
53
67
  });
54
68
  return pts.join(' ');
55
- })();
69
+ })());
56
70
 
57
- $: thresholdY = threshold > 0 ? (PAD.t + (1 - threshold) * chartH).toFixed(1) : null;
71
+ let thresholdY = $derived(threshold > 0 ? (PAD.t + (1 - threshold) * chartH).toFixed(1) : null);
58
72
 
59
- $: pctLabels = [0, 50, 100].map((pct) => ({
73
+ let pctLabels = $derived([0, 50, 100].map((pct) => ({
60
74
  label: `${pct}%`,
61
75
  y: (PAD.t + (1 - pct / 100) * chartH + 3).toFixed(1),
62
- }));
76
+ })));
63
77
  </script>
64
78
 
65
79
  <div role="img" aria-label={ariaLabel} style="width:100%;">
@@ -1,26 +1,36 @@
1
- <script context="module" lang="ts">
1
+ <script module lang="ts">
2
2
  let counter = 0;
3
3
  </script>
4
4
 
5
5
  <script lang="ts">
6
- import { createEventDispatcher } from 'svelte';
6
+
7
7
 
8
- export let label: string | undefined = undefined;
9
- export let value: string = '';
10
- export let placeholder: string | undefined = undefined;
11
- export let disabled: boolean = false;
12
- export let autocomplete: 'current-password' | 'new-password' | 'off' = 'current-password';
13
- let className = '';
14
- export { className as class };
8
+ interface Props {
9
+ label?: string | undefined;
10
+ value?: string;
11
+ placeholder?: string | undefined;
12
+ disabled?: boolean;
13
+ autocomplete?: 'current-password' | 'new-password' | 'off';
14
+ class?: string;
15
+ onchange?: (payload: string) => void;
16
+ }
15
17
 
16
- const dispatch = createEventDispatcher<{ change: string }>();
18
+ let {
19
+ label = undefined,
20
+ value = $bindable(''),
21
+ placeholder = undefined,
22
+ disabled = false,
23
+ autocomplete = 'current-password',
24
+ class: className = '',
25
+ onchange,
26
+ }: Props = $props();
17
27
  const uid = `dash-ui-pwd-${++counter}`;
18
28
 
19
- let shown = false;
29
+ let shown = $state(false);
20
30
 
21
31
  function handleInput(e: Event) {
22
32
  value = (e.target as HTMLInputElement).value;
23
- dispatch('change', value);
33
+ onchange?.(value);
24
34
  }
25
35
  </script>
26
36
 
@@ -37,7 +47,7 @@
37
47
  {placeholder}
38
48
  {disabled}
39
49
  {autocomplete}
40
- on:input={handleInput}
50
+ oninput={handleInput}
41
51
  />
42
52
  <button
43
53
  type="button"
@@ -45,7 +55,7 @@
45
55
  aria-pressed={shown}
46
56
  aria-label={shown ? 'Hide password' : 'Show password'}
47
57
  {disabled}
48
- on:click={() => (shown = !shown)}
58
+ onclick={() => (shown = !shown)}
49
59
  >
50
60
  {#if shown}
51
61
  <svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false">
@@ -1,17 +1,25 @@
1
- <script lang="ts">
1
+ <script module lang="ts">
2
2
  export interface PieSlice {
3
3
  label: string;
4
4
  value: number;
5
5
  color?: string;
6
6
  }
7
+ </script>
8
+
9
+ <script lang="ts">
10
+
11
+ interface Props {
12
+ slices?: PieSlice[];
13
+ size?: number;
14
+ ariaLabel?: string;
15
+ }
7
16
 
8
- export let slices: PieSlice[] = [];
9
- export let size: number = 140;
10
- export let ariaLabel: string = 'Pie chart';
17
+ let { slices = [], size = 140, ariaLabel = 'Pie chart' }: Props = $props();
11
18
 
12
19
  const COLORS = ['#006FFF', '#00C8C8', '#F5A623', '#A878F5', '#FF6B6B', '#00C875', '#7FB6FF', '#6E7079'];
13
20
  const TAU = 2 * Math.PI;
14
21
  const START = -Math.PI / 2;
22
+ const LEGEND_ROW = 18;
15
23
 
16
24
  function arcPath(cx: number, cy: number, r: number, a0: number, a1: number): string {
17
25
  const x0 = cx + r * Math.cos(a0);
@@ -22,15 +30,15 @@
22
30
  return `M ${cx} ${cy} L ${x0.toFixed(2)} ${y0.toFixed(2)} A ${r} ${r} 0 ${large} 1 ${x1.toFixed(2)} ${y1.toFixed(2)} Z`;
23
31
  }
24
32
 
25
- $: total = slices.reduce((s, sl) => s + sl.value, 0) || 1;
26
- $: cx = size / 2;
27
- $: cy = size / 2;
28
- $: r = (size / 2) * 0.82;
29
- $: LEGEND_ROW = 18;
30
- $: legendH = Math.ceil(slices.length / 2) * LEGEND_ROW + 6;
31
- $: VH = size + legendH;
33
+ let total = $derived(slices.reduce((s, sl) => s + sl.value, 0) || 1);
34
+ let cx = $derived(size / 2);
35
+ let cy = $derived(size / 2);
36
+ let r = $derived((size / 2) * 0.82);
37
+
38
+ let legendH = $derived(Math.ceil(slices.length / 2) * LEGEND_ROW + 6);
39
+ let VH = $derived(size + legendH);
32
40
 
33
- $: segments = (() => {
41
+ let segments = $derived((() => {
34
42
  const result: { path: string; color: string; mid: number }[] = [];
35
43
  let angle = START;
36
44
  for (let i = 0; i < slices.length; i++) {
@@ -41,7 +49,7 @@
41
49
  angle += span;
42
50
  }
43
51
  return result;
44
- })();
52
+ })());
45
53
  </script>
46
54
 
47
55
  <div role="img" aria-label={ariaLabel} style="width:100%;">
@@ -1,12 +1,23 @@
1
1
  <script lang="ts">
2
- export let variant: 'success' | 'warn' | 'danger' | 'info' | 'neutral' = 'neutral';
3
- export let showDot: boolean = true;
4
- let className = '';
5
- export { className as class };
6
- export let style: string = '';
2
+
3
+ interface Props {
4
+ variant?: 'success' | 'warn' | 'danger' | 'info' | 'neutral';
5
+ showDot?: boolean;
6
+ class?: string;
7
+ style?: string;
8
+ children?: import('svelte').Snippet;
9
+ }
10
+
11
+ let {
12
+ variant = 'neutral',
13
+ showDot = true,
14
+ class: className = '',
15
+ style = '',
16
+ children
17
+ }: Props = $props();
7
18
  </script>
8
19
 
9
20
  <span class="pill pill-{variant} {className}" {style}>
10
21
  {#if showDot}<span class="dot" aria-hidden="true"></span>{/if}
11
- <slot />
22
+ {@render children?.()}
12
23
  </span>
@@ -1,16 +1,30 @@
1
- <script lang="ts">
1
+ <script module lang="ts">
2
2
  export interface PolarCell {
3
3
  row: number;
4
4
  col: number;
5
5
  value: number;
6
6
  }
7
+ </script>
8
+
9
+ <script lang="ts">
10
+
11
+ interface Props {
12
+ data?: PolarCell[];
13
+ rows?: number;
14
+ cols?: number;
15
+ colLabels?: string[];
16
+ color?: string;
17
+ ariaLabel?: string;
18
+ }
7
19
 
8
- export let data: PolarCell[] = [];
9
- export let rows: number = 7;
10
- export let cols: number = 24;
11
- export let colLabels: string[] = [];
12
- export let color: string = '#006FFF';
13
- export let ariaLabel: string = 'Polar heatmap';
20
+ let {
21
+ data = [],
22
+ rows = 7,
23
+ cols = 24,
24
+ colLabels = [],
25
+ color = '#006FFF',
26
+ ariaLabel = 'Polar heatmap'
27
+ }: Props = $props();
14
28
 
15
29
  const SIZE = 280;
16
30
  const CX = SIZE / 2;
@@ -36,14 +50,14 @@
36
50
  ].join(' ');
37
51
  }
38
52
 
39
- $: maxVal = data.length ? Math.max(...data.map((d) => d.value), 1) : 1;
40
- $: ringH = (MAX_R - MIN_R) / rows;
41
- $: segA = (2 * Math.PI) / cols;
42
- $: [rC, gC, bC] = hexToRgb(color);
43
- $: LABEL_R = MAX_R + 14;
44
- $: labelEvery = cols <= 12 ? 1 : cols <= 24 ? 3 : Math.round(cols / 8);
45
- $: rings = Array.from({ length: rows + 1 }, (_, i) => +(MIN_R + i * ringH).toFixed(2));
46
- $: cells = data.map((cell) => {
53
+ let maxVal = $derived(data.length ? Math.max(...data.map((d) => d.value), 1) : 1);
54
+ let ringH = $derived((MAX_R - MIN_R) / rows);
55
+ let segA = $derived((2 * Math.PI) / cols);
56
+ let [rC, gC, bC] = $derived(hexToRgb(color));
57
+ let LABEL_R = $derived(MAX_R + 14);
58
+ let labelEvery = $derived(cols <= 12 ? 1 : cols <= 24 ? 3 : Math.round(cols / 8));
59
+ let rings = $derived(Array.from({ length: rows + 1 }, (_, i) => +(MIN_R + i * ringH).toFixed(2)));
60
+ let cells = $derived(data.map((cell) => {
47
61
  const ir = MIN_R + cell.row * ringH;
48
62
  const or = ir + ringH - 0.5;
49
63
  const sa = BASE + cell.col * segA + 0.01;
@@ -53,8 +67,8 @@
53
67
  d: annularSector(ir, or, sa, ea),
54
68
  fill: `rgba(${rC},${gC},${bC},${(0.08 + 0.92 * norm).toFixed(3)})`,
55
69
  };
56
- });
57
- $: visibleColLabels = colLabels
70
+ }));
71
+ let visibleColLabels = $derived(colLabels
58
72
  .map((label, i) => {
59
73
  if (i % labelEvery !== 0) return null;
60
74
  const a = BASE + (i + 0.5) * segA;
@@ -64,7 +78,7 @@
64
78
  label,
65
79
  };
66
80
  })
67
- .filter(Boolean) as { x: string; y: string; label: string }[];
81
+ .filter(Boolean) as { x: string; y: string; label: string }[]);
68
82
  </script>
69
83
 
70
84
  {#if data.length}
@@ -1,14 +1,25 @@
1
- <script context="module" lang="ts">
1
+ <script module lang="ts">
2
2
  let counter = 0;
3
3
  </script>
4
4
 
5
5
  <script lang="ts">
6
6
  import { onMount, onDestroy, tick } from 'svelte';
7
7
 
8
- export let label: string;
9
- export let variant: 'ghost' | 'primary' = 'ghost';
10
- export let title: string | undefined = undefined;
11
- export let placement: 'bottom-start' | 'bottom-end' | 'bottom' = 'bottom-start';
8
+ interface Props {
9
+ label: string;
10
+ variant?: 'ghost' | 'primary';
11
+ title?: string | undefined;
12
+ placement?: 'bottom-start' | 'bottom-end' | 'bottom';
13
+ children?: import('svelte').Snippet;
14
+ }
15
+
16
+ let {
17
+ label,
18
+ variant = 'ghost',
19
+ title = undefined,
20
+ placement = 'bottom-start',
21
+ children
22
+ }: Props = $props();
12
23
 
13
24
  const uid = `dash-ui-pop-${++counter}`;
14
25
  const titleId = `${uid}-title`;
@@ -16,10 +27,10 @@
16
27
  const FOCUSABLE =
17
28
  'a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])';
18
29
 
19
- let open = false;
20
- let rootEl: HTMLDivElement;
21
- let triggerEl: HTMLButtonElement;
22
- let panelEl: HTMLDivElement;
30
+ let open = $state(false);
31
+ let rootEl = $state<HTMLDivElement | undefined>(undefined);
32
+ let triggerEl = $state<HTMLButtonElement | undefined>(undefined);
33
+ let panelEl = $state<HTMLDivElement | undefined>(undefined);
23
34
 
24
35
  async function toggle() {
25
36
  if (!open) {
@@ -72,7 +83,7 @@
72
83
  class="btn btn-{variant}"
73
84
  aria-haspopup="dialog"
74
85
  aria-expanded={open}
75
- on:click={toggle}
86
+ onclick={toggle}
76
87
  >{label}</button>
77
88
  {#if open}
78
89
  <div
@@ -83,7 +94,7 @@
83
94
  tabindex="-1"
84
95
  >
85
96
  {#if title}<div id={titleId} class="popover-h">{title}</div>{/if}
86
- <div class="popover-b"><slot /></div>
97
+ <div class="popover-b">{@render children?.()}</div>
87
98
  </div>
88
99
  {/if}
89
100
  </div>
@@ -1,11 +1,20 @@
1
1
  <script lang="ts">
2
- export let value: number;
3
- export let label: string | undefined = undefined;
4
- export let valueText: string | undefined = undefined;
5
- export let color: string = '#006FFF';
6
- $: clamped = Math.max(0, Math.min(100, value));
7
- $: displayed = valueText ?? `${Math.round(clamped)}%`;
8
- $: hasHeader = label !== undefined || valueText !== undefined;
2
+ interface Props {
3
+ value: number;
4
+ label?: string | undefined;
5
+ valueText?: string | undefined;
6
+ color?: string;
7
+ }
8
+
9
+ let {
10
+ value,
11
+ label = undefined,
12
+ valueText = undefined,
13
+ color = '#006FFF'
14
+ }: Props = $props();
15
+ let clamped = $derived(Math.max(0, Math.min(100, value)));
16
+ let displayed = $derived(valueText ?? `${Math.round(clamped)}%`);
17
+ let hasHeader = $derived(label !== undefined || valueText !== undefined);
9
18
  </script>
10
19
 
11
20
  <div class="pb">
@@ -24,6 +33,6 @@
24
33
  aria-label={label}
25
34
  aria-valuetext={displayed}
26
35
  >
27
- <div class="pb-fill" style="width:{clamped}%;background:{color};" />
36
+ <div class="pb-fill" style="width:{clamped}%;background:{color};"></div>
28
37
  </div>
29
38
  </div>
@@ -1,40 +1,51 @@
1
- <script context="module">
1
+ <script module>
2
2
  let _n = 0;
3
3
  </script>
4
4
  <script lang="ts">
5
5
  const _uid = `pc${_n++}`;
6
6
 
7
- export let data: number[][];
8
- export let rowLabels: string[] | undefined = undefined;
9
- export let colLabels: string[] | undefined = undefined;
10
- export let color: string = '#006FFF';
11
- export let height: number = 180;
12
- export let ariaLabel: string = 'Punch card chart';
7
+ interface Props {
8
+ data: number[][];
9
+ rowLabels?: string[] | undefined;
10
+ colLabels?: string[] | undefined;
11
+ color?: string;
12
+ height?: number;
13
+ ariaLabel?: string;
14
+ }
15
+
16
+ let {
17
+ data,
18
+ rowLabels = undefined,
19
+ colLabels = undefined,
20
+ color = '#006FFF',
21
+ height = 180,
22
+ ariaLabel = 'Punch card chart'
23
+ }: Props = $props();
13
24
 
14
25
  const VW = 400;
15
26
  const PAD = { t: 16, r: 8, b: 28, l: 28 };
16
27
  const DEFAULT_ROWS = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
17
28
 
18
- $: rows = data.length;
19
- $: cols = data[0]?.length ?? 0;
20
- $: chartW = VW - PAD.l - PAD.r;
21
- $: chartH = height - PAD.t - PAD.b;
22
- $: cellW = chartW / (cols || 1);
23
- $: cellH = chartH / (rows || 1);
24
- $: maxR = Math.min(cellW, cellH) / 2 * 0.85;
25
- $: maxVal = Math.max(...data.flat(), 1);
26
- $: rLabels = rowLabels ?? DEFAULT_ROWS.slice(0, rows);
27
- $: cLabels = colLabels ?? Array.from({ length: cols }, (_, i) =>
29
+ let rows = $derived(data.length);
30
+ let cols = $derived(data[0]?.length ?? 0);
31
+ let chartW = $derived(VW - PAD.l - PAD.r);
32
+ let chartH = $derived(height - PAD.t - PAD.b);
33
+ let cellW = $derived(chartW / (cols || 1));
34
+ let cellH = $derived(chartH / (rows || 1));
35
+ let maxR = $derived(Math.min(cellW, cellH) / 2 * 0.85);
36
+ let maxVal = $derived(Math.max(...data.flat(), 1));
37
+ let rLabels = $derived(rowLabels ?? DEFAULT_ROWS.slice(0, rows));
38
+ let cLabels = $derived(colLabels ?? Array.from({ length: cols }, (_, i) =>
28
39
  i % 6 === 0 ? String(i).padStart(2, '0') : ''
29
- );
30
- $: dots = data.flatMap((row, ri) =>
40
+ ));
41
+ let dots = $derived(data.flatMap((row, ri) =>
31
42
  row.map((val, ci) => ({
32
43
  ri, ci,
33
44
  r: Math.sqrt(val / maxVal) * maxR,
34
45
  cx: PAD.l + (ci + 0.5) * cellW,
35
46
  cy: PAD.t + (ri + 0.5) * cellH,
36
47
  }))
37
- ).filter(d => d.r >= 0.4);
48
+ ).filter(d => d.r >= 0.4));
38
49
  </script>
39
50
 
40
51
  <div role="img" aria-label={ariaLabel} style="width:100%">
@@ -1,57 +1,77 @@
1
- <script lang="ts">
1
+ <script module lang="ts">
2
2
  export interface QuadrantPoint {
3
3
  x: number;
4
4
  y: number;
5
5
  label?: string;
6
6
  color?: string;
7
7
  }
8
+ </script>
9
+
10
+ <script lang="ts">
11
+
12
+
13
+ interface Props {
14
+ points?: QuadrantPoint[];
15
+ xThreshold: number;
16
+ yThreshold: number;
17
+ xRange?: [number, number] | undefined;
18
+ yRange?: [number, number] | undefined;
19
+ /** Labels: [top-left, top-right, bottom-left, bottom-right] */
20
+ quadrantLabels?: [string, string, string, string];
21
+ quadrantColors?: [string, string, string, string];
22
+ xLabel?: string | undefined;
23
+ yLabel?: string | undefined;
24
+ height?: number;
25
+ ariaLabel?: string;
26
+ }
8
27
 
9
- export let points: QuadrantPoint[] = [];
10
- export let xThreshold: number;
11
- export let yThreshold: number;
12
- export let xRange: [number, number] | undefined = undefined;
13
- export let yRange: [number, number] | undefined = undefined;
14
- /** Labels: [top-left, top-right, bottom-left, bottom-right] */
15
- export let quadrantLabels: [string, string, string, string] = ['', '', '', ''];
16
- export let quadrantColors: [string, string, string, string] = [
28
+ let {
29
+ points = [],
30
+ xThreshold,
31
+ yThreshold,
32
+ xRange = undefined,
33
+ yRange = undefined,
34
+ quadrantLabels = ['', '', '', ''],
35
+ quadrantColors = [
17
36
  'rgba(0,200,117,0.06)',
18
37
  'rgba(245,166,35,0.07)',
19
38
  'rgba(0,111,255,0.06)',
20
39
  'rgba(255,123,123,0.09)',
21
- ];
22
- export let xLabel: string | undefined = undefined;
23
- export let yLabel: string | undefined = undefined;
24
- export let height = 200;
25
- export let ariaLabel = 'Quadrant chart';
40
+ ],
41
+ xLabel = undefined,
42
+ yLabel = undefined,
43
+ height = 200,
44
+ ariaLabel = 'Quadrant chart'
45
+ }: Props = $props();
26
46
 
27
47
  const VW = 360;
28
48
  const PAD = { t: 8, r: 8, b: 28, l: 36 };
29
49
 
30
- $: xs = points.map((p) => p.x);
31
- $: ys = points.map((p) => p.y);
32
- $: x0 = xRange ? xRange[0] : Math.min(...xs, xThreshold - 1);
33
- $: x1 = xRange ? xRange[1] : Math.max(...xs, xThreshold + 1);
34
- $: y0 = yRange ? yRange[0] : Math.min(...ys, yThreshold - 1);
35
- $: y1 = yRange ? yRange[1] : Math.max(...ys, yThreshold + 1);
36
- $: xSpan = x1 - x0 || 1;
37
- $: ySpan = y1 - y0 || 1;
38
- $: cw = VW - PAD.l - PAD.r;
39
- $: ch = height - PAD.t - PAD.b;
50
+ let xs = $derived(points.map((p) => p.x));
51
+ let ys = $derived(points.map((p) => p.y));
52
+ let x0 = $derived(xRange ? xRange[0] : Math.min(...xs, xThreshold - 1));
53
+ let x1 = $derived(xRange ? xRange[1] : Math.max(...xs, xThreshold + 1));
54
+ let y0 = $derived(yRange ? yRange[0] : Math.min(...ys, yThreshold - 1));
55
+ let y1 = $derived(yRange ? yRange[1] : Math.max(...ys, yThreshold + 1));
56
+ let xSpan = $derived(x1 - x0 || 1);
57
+ let ySpan = $derived(y1 - y0 || 1);
58
+ let cw = $derived(VW - PAD.l - PAD.r);
59
+ let ch = $derived(height - PAD.t - PAD.b);
40
60
 
41
61
  function toX(x: number) { return PAD.l + ((x - x0) / xSpan) * cw; }
42
62
  function toY(y: number) { return PAD.t + ch - ((y - y0) / ySpan) * ch; }
43
63
 
44
- $: tx = toX(xThreshold);
45
- $: ty = toY(yThreshold);
46
- $: xTicks = [x0, xThreshold, x1];
47
- $: yTicks = [y0, yThreshold, y1];
64
+ let tx = $derived(toX(xThreshold));
65
+ let ty = $derived(toY(yThreshold));
66
+ let xTicks = $derived([x0, xThreshold, x1]);
67
+ let yTicks = $derived([y0, yThreshold, y1]);
48
68
 
49
- $: dots = points.map((p) => ({
69
+ let dots = $derived(points.map((p) => ({
50
70
  cx: toX(p.x),
51
71
  cy: toY(p.y),
52
72
  color: p.color ?? '#006FFF',
53
73
  label: p.label,
54
- }));
74
+ })));
55
75
  </script>
56
76
 
57
77
  {#if points.length > 0}