@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,4 +1,4 @@
1
- <script context="module" lang="ts">
1
+ <script module lang="ts">
2
2
  export interface SegmentOption {
3
3
  value: string;
4
4
  label: string;
@@ -9,11 +9,15 @@
9
9
  <script lang="ts">
10
10
  import { tick } from 'svelte';
11
11
 
12
- export let label: string;
13
- export let options: SegmentOption[] = [];
14
- export let value: string = options[0]?.value ?? '';
12
+ interface Props {
13
+ label: string;
14
+ options?: SegmentOption[];
15
+ value?: string;
16
+ }
17
+
18
+ let { label, options = [], value = $bindable(options[0]?.value ?? '') }: Props = $props();
15
19
 
16
- let root: HTMLDivElement;
20
+ let root = $state<HTMLDivElement | undefined>(undefined);
17
21
 
18
22
  async function handleKeyDown(e: KeyboardEvent) {
19
23
  const enabled = options.filter((o) => !o.disabled);
@@ -34,7 +38,7 @@
34
38
  }
35
39
  </script>
36
40
 
37
- <div bind:this={root} role="radiogroup" aria-label={label} class="seg-ctrl" tabindex="-1" on:keydown={handleKeyDown}>
41
+ <div bind:this={root} role="radiogroup" aria-label={label} class="seg-ctrl" tabindex="-1" onkeydown={handleKeyDown}>
38
42
  {#each options as opt (opt.value)}
39
43
  <button
40
44
  type="button"
@@ -43,7 +47,7 @@
43
47
  disabled={opt.disabled}
44
48
  tabindex={value === opt.value ? 0 : -1}
45
49
  class="seg-ctrl__btn{value === opt.value ? ' seg-ctrl__btn--active' : ''}"
46
- on:click={() => { value = opt.value; }}
50
+ onclick={() => { value = opt.value; }}
47
51
  >
48
52
  {opt.label}
49
53
  </button>
@@ -1,33 +1,44 @@
1
- <script context="module" lang="ts">
1
+ <script module lang="ts">
2
2
  let counter = 0;
3
3
  export interface SelectOption { value: string; label: string; }
4
4
  </script>
5
5
 
6
6
  <script lang="ts">
7
- import { createEventDispatcher, onMount, onDestroy } from 'svelte';
7
+ import { onMount, onDestroy } from 'svelte';
8
8
 
9
- export let options: SelectOption[] = [];
10
- export let value: string | undefined = undefined;
11
- export let label: string | undefined = undefined;
12
- export let placeholder: string = 'Select…';
13
- export let id: string | undefined = undefined;
14
- export let disabled: boolean = false;
15
- let className = '';
16
- export { className as class };
17
-
18
- const uid = `dash-ui-sel-${++counter}`;
19
- $: triggerId = id ?? uid;
20
- $: listboxId = `${triggerId}-lb`;
9
+ interface Props {
10
+ options?: SelectOption[];
11
+ value?: string | undefined;
12
+ label?: string | undefined;
13
+ placeholder?: string;
14
+ id?: string | undefined;
15
+ disabled?: boolean;
16
+ class?: string;
17
+ onchange?: (payload: string) => void;
18
+ }
21
19
 
22
- const dispatch = createEventDispatcher<{ change: string }>();
20
+ let {
21
+ options = [],
22
+ value = undefined,
23
+ label = undefined,
24
+ placeholder = 'Select…',
25
+ id = undefined,
26
+ disabled = false,
27
+ class: className = '',
28
+ onchange,
29
+ }: Props = $props();
30
+
23
31
 
24
- let open = false;
25
- let activeIdx = -1;
26
- let triggerEl: HTMLButtonElement;
27
- let wrapperEl: HTMLDivElement;
32
+ const uid = `dash-ui-sel-${++counter}`;
33
+ let triggerId = $derived(id ?? uid);
34
+ let listboxId = $derived(`${triggerId}-lb`);
35
+ let open = $state(false);
36
+ let activeIdx = $state(-1);
37
+ let triggerEl = $state<HTMLButtonElement | undefined>(undefined);
38
+ let wrapperEl = $state<HTMLDivElement | undefined>(undefined);
28
39
 
29
- $: selected = options.find((o) => o.value === value);
30
- $: displayLabel = selected?.label ?? placeholder;
40
+ let selected = $derived(options.find((o) => o.value === value));
41
+ let displayLabel = $derived(selected?.label ?? placeholder);
31
42
 
32
43
  function toggle() {
33
44
  if (disabled) return;
@@ -39,7 +50,7 @@
39
50
  }
40
51
 
41
52
  function pick(val: string) {
42
- dispatch('change', val);
53
+ onchange?.(val);
43
54
  open = false;
44
55
  triggerEl?.focus();
45
56
  }
@@ -84,8 +95,8 @@
84
95
  aria-label={label}
85
96
  {disabled}
86
97
  class="select-trigger"
87
- on:click={toggle}
88
- on:keydown={onKeyDown}
98
+ onclick={toggle}
99
+ onkeydown={onKeyDown}
89
100
  type="button"
90
101
  >
91
102
  <span>{displayLabel}</span>
@@ -101,8 +112,8 @@
101
112
  aria-selected={opt.value === value}
102
113
  data-active={idx === activeIdx ? 'true' : undefined}
103
114
  class="select-option"
104
- on:mousedown|preventDefault={() => pick(opt.value)}
105
- on:mouseenter={() => { activeIdx = idx; }}
115
+ onmousedown={(e) => { e.preventDefault(); (() => pick(opt.value))(); }}
116
+ onmouseenter={() => { activeIdx = idx; }}
106
117
  >{opt.label}</li>
107
118
  {/each}
108
119
  </ul>
@@ -1,16 +1,30 @@
1
- <script lang="ts">
2
- import CloseIcon from '../icons/CloseIcon.svelte';
3
-
1
+ <script module lang="ts">
4
2
  export interface SelectionToolbarAction {
5
3
  label: string;
6
4
  onClick: () => void;
7
5
  variant?: 'default' | 'danger';
8
6
  }
7
+ </script>
8
+
9
+ <script lang="ts">
10
+ import CloseIcon from '../icons/CloseIcon.svelte';
11
+
12
+
13
+ interface Props {
14
+ count: number;
15
+ actions?: SelectionToolbarAction[];
16
+ onClear: () => void;
17
+ ariaLabel?: string;
18
+ children?: import('svelte').Snippet;
19
+ }
9
20
 
10
- export let count: number;
11
- export let actions: SelectionToolbarAction[] = [];
12
- export let onClear: () => void;
13
- export let ariaLabel: string = 'Selection actions';
21
+ let {
22
+ count,
23
+ actions = [],
24
+ onClear,
25
+ ariaLabel = 'Selection actions',
26
+ children
27
+ }: Props = $props();
14
28
  </script>
15
29
 
16
30
  {#if count > 0}
@@ -23,20 +37,20 @@
23
37
  <button
24
38
  type="button"
25
39
  class="sel-toolbar__btn{action.variant === 'danger' ? ' sel-toolbar__btn--danger' : ''}"
26
- on:click={action.onClick}
40
+ onclick={action.onClick}
27
41
  >
28
42
  {action.label}
29
43
  </button>
30
44
  {/each}
31
- <slot />
45
+ {@render children?.()}
32
46
  </div>
33
47
  <button
34
48
  type="button"
35
49
  class="sel-toolbar__clear icon-btn"
36
- on:click={onClear}
50
+ onclick={onClear}
37
51
  aria-label="Clear selection"
38
52
  >
39
- <CloseIcon aria-hidden="true" />
53
+ <CloseIcon />
40
54
  </button>
41
55
  </div>
42
56
  {/if}
@@ -1,9 +1,9 @@
1
- <script lang="ts" context="module">
2
- import type { ComponentType } from 'svelte';
1
+ <script lang="ts" module>
2
+ import type { Component } from 'svelte';
3
3
  export interface SidebarItemDef {
4
4
  id: string;
5
5
  label: string;
6
- icon: ComponentType;
6
+ icon: Component<Record<string, unknown>>;
7
7
  count?: number;
8
8
  pill?: number;
9
9
  }
@@ -14,10 +14,16 @@
14
14
  </script>
15
15
 
16
16
  <script lang="ts">
17
- import { createEventDispatcher } from 'svelte';
18
- export let sections: SidebarSectionDef[] = [];
19
- export let activeId: string;
20
- const dispatch = createEventDispatcher<{ change: string }>();
17
+
18
+ interface Props {
19
+ sections?: SidebarSectionDef[];
20
+ activeId: string;
21
+ onchange?: (payload: string) => void;
22
+ }
23
+
24
+ let { sections = [], activeId = $bindable(),
25
+ onchange,
26
+ }: Props = $props();
21
27
  </script>
22
28
 
23
29
  <nav class="sidebar" aria-label="Primary">
@@ -30,9 +36,9 @@
30
36
  type="button"
31
37
  class="sb-item {it.id === activeId ? 'active' : ''}"
32
38
  aria-current={it.id === activeId ? 'page' : undefined}
33
- on:click={() => { activeId = it.id; dispatch('change', it.id); }}
39
+ onclick={() => { activeId = it.id; onchange?.(it.id); }}
34
40
  >
35
- <span class="sb-ico"><svelte:component this={it.icon} /></span>
41
+ <span class="sb-ico"><it.icon /></span>
36
42
  {it.label}
37
43
  {#if it.count !== undefined}<span class="sb-count">{it.count}</span>{/if}
38
44
  {#if it.pill !== undefined}<span class="sb-pill">{it.pill}<span class="sr-only"> alert{it.pill !== 1 ? 's' : ''}</span></span>{/if}
@@ -1,6 +1,10 @@
1
1
  <script lang="ts">
2
- export let weak: boolean = false;
3
- export let label: string | undefined = undefined;
2
+ interface Props {
3
+ weak?: boolean;
4
+ label?: string | undefined;
5
+ }
6
+
7
+ let { weak = false, label = undefined }: Props = $props();
4
8
  </script>
5
9
 
6
10
  <span
@@ -1,17 +1,27 @@
1
1
  <script lang="ts">
2
- export let variant: 'text' | 'title' | 'stat' | 'circle' | 'block' = 'text';
3
- export let width: string | number | undefined = undefined;
4
- export let height: string | number | undefined = undefined;
5
- let className = '';
6
- export { className as class };
7
- export let ariaLabel: string = 'Loading';
2
+
3
+ interface Props {
4
+ variant?: 'text' | 'title' | 'stat' | 'circle' | 'block';
5
+ width?: string | number | undefined;
6
+ height?: string | number | undefined;
7
+ class?: string;
8
+ ariaLabel?: string;
9
+ }
8
10
 
9
- $: variantClass = variant === 'block' ? '' : variant;
10
- $: w = width ?? (variant === 'circle' ? height : undefined);
11
- $: style = [
11
+ let {
12
+ variant = 'text',
13
+ width = undefined,
14
+ height = undefined,
15
+ class: className = '',
16
+ ariaLabel = 'Loading'
17
+ }: Props = $props();
18
+
19
+ let variantClass = $derived(variant === 'block' ? '' : variant);
20
+ let w = $derived(width ?? (variant === 'circle' ? height : undefined));
21
+ let style = $derived([
12
22
  w !== undefined ? `width:${typeof w === 'number' ? w + 'px' : w}` : '',
13
23
  height !== undefined ? `height:${typeof height === 'number' ? height + 'px' : height}` : '',
14
- ].filter(Boolean).join(';');
24
+ ].filter(Boolean).join(';'));
15
25
  </script>
16
26
 
17
27
  <span
@@ -1,9 +1,14 @@
1
1
  <script lang="ts">
2
- export let href: string = '#main-content';
3
- let className = '';
4
- export { className as class };
2
+ interface Props {
3
+ href?: string;
4
+ class?: string;
5
+ children?: import('svelte').Snippet;
6
+ }
7
+
8
+ let { href = '#main-content', class: className = '', children }: Props = $props();
9
+
5
10
  </script>
6
11
 
7
12
  <a class="skip-link {className}" {href}>
8
- <slot>Skip to main content</slot>
13
+ {#if children}{@render children()}{:else}Skip to main content{/if}
9
14
  </a>
@@ -1,24 +1,38 @@
1
1
  <script lang="ts">
2
- import { createEventDispatcher } from 'svelte';
2
+
3
3
 
4
- export let label: string | undefined = undefined;
5
- export let value: number = 0;
6
- export let min: number = 0;
7
- export let max: number = 100;
8
- export let step: number = 1;
9
- export let suffix: string | undefined = undefined;
10
- export let disabled: boolean = false;
11
- export let id: string | undefined = undefined;
4
+ interface Props {
5
+ label?: string | undefined;
6
+ value?: number;
7
+ min?: number;
8
+ max?: number;
9
+ step?: number;
10
+ suffix?: string | undefined;
11
+ disabled?: boolean;
12
+ id?: string | undefined;
13
+ onchange?: (payload: number) => void;
14
+ }
15
+
16
+ let {
17
+ label = undefined,
18
+ value = $bindable(0),
19
+ min = 0,
20
+ max = 100,
21
+ step = 1,
22
+ suffix = undefined,
23
+ disabled = false,
24
+ id = undefined,
25
+ onchange,
26
+ }: Props = $props();
12
27
 
13
28
  let counter = 0;
29
+ // svelte-ignore state_referenced_locally
14
30
  const inputId = id ?? `slider-${counter++}`;
15
- const dispatch = createEventDispatcher<{ change: number }>();
16
-
17
- $: pct = max === min ? 0 : ((value - min) / (max - min)) * 100;
31
+ let pct = $derived(max === min ? 0 : ((value - min) / (max - min)) * 100);
18
32
 
19
33
  function handleChange(e: Event) {
20
34
  value = Number((e.target as HTMLInputElement).value);
21
- dispatch('change', value);
35
+ onchange?.(value);
22
36
  }
23
37
  </script>
24
38
 
@@ -43,6 +57,6 @@
43
57
  style="--slider-fill:{pct}%"
44
58
  aria-label={label}
45
59
  aria-valuetext={suffix ? `${value} ${suffix}` : undefined}
46
- on:input={handleChange}
60
+ oninput={handleChange}
47
61
  />
48
62
  </div>
@@ -1,16 +1,30 @@
1
- <script lang="ts">
1
+ <script module lang="ts">
2
2
  export interface SlopeItem {
3
3
  label: string;
4
4
  before: number;
5
5
  after: number;
6
6
  }
7
+ </script>
8
+
9
+ <script lang="ts">
10
+
11
+ interface Props {
12
+ items?: SlopeItem[];
13
+ labelBefore?: string;
14
+ labelAfter?: string;
15
+ unit?: string;
16
+ ariaLabel?: string;
17
+ positiveIsGood?: boolean;
18
+ }
7
19
 
8
- export let items: SlopeItem[] = [];
9
- export let labelBefore: string = 'Before';
10
- export let labelAfter: string = 'After';
11
- export let unit: string = '';
12
- export let ariaLabel: string = 'Slope chart';
13
- export let positiveIsGood: boolean = false;
20
+ let {
21
+ items = [],
22
+ labelBefore = 'Before',
23
+ labelAfter = 'After',
24
+ unit = '',
25
+ ariaLabel = 'Slope chart',
26
+ positiveIsGood = false
27
+ }: Props = $props();
14
28
 
15
29
  const VW = 340;
16
30
  const COL_L = 108;
@@ -36,18 +50,18 @@
36
50
  return res;
37
51
  }
38
52
 
39
- $: allVals = items.flatMap((it) => [it.before, it.after]);
40
- $: minV = allVals.length ? Math.min(...allVals) : 0;
41
- $: maxV = allVals.length ? Math.max(...allVals) : 1;
42
- $: range = maxV - minV || 1;
43
- $: ty = (v: number) => PAD_T + (1 - (v - minV) / range) * CHART_H;
53
+ let allVals = $derived(items.flatMap((it) => [it.before, it.after]));
54
+ let minV = $derived(allVals.length ? Math.min(...allVals) : 0);
55
+ let maxV = $derived(allVals.length ? Math.max(...allVals) : 1);
56
+ let range = $derived(maxV - minV || 1);
57
+ let ty = $derived((v: number) => PAD_T + (1 - (v - minV) / range) * CHART_H);
44
58
 
45
- $: leftDotY = items.map((it) => ty(it.before));
46
- $: rightDotY = items.map((it) => ty(it.after));
47
- $: leftLabelY = nudge(leftDotY, LABEL_GAP);
48
- $: rightLabelY = nudge(rightDotY, LABEL_GAP);
59
+ let leftDotY = $derived(items.map((it) => ty(it.before)));
60
+ let rightDotY = $derived(items.map((it) => ty(it.after)));
61
+ let leftLabelY = $derived(nudge(leftDotY, LABEL_GAP));
62
+ let rightLabelY = $derived(nudge(rightDotY, LABEL_GAP));
49
63
 
50
- $: colored = items.map((it, i) => {
64
+ let colored = $derived(items.map((it, i) => {
51
65
  const diff = it.after - it.before;
52
66
  const c =
53
67
  diff === 0 ? '#A4A7B5' : diff > 0 === positiveIsGood ? '#00C875' : '#FF7B7B';
@@ -60,7 +74,7 @@
60
74
  rly: rightLabelY[i],
61
75
  delta: it.after - it.before,
62
76
  };
63
- });
77
+ }));
64
78
  </script>
65
79
 
66
80
  {#if items.length}
@@ -82,9 +96,9 @@
82
96
  <circle cx={COL_L} cy={it.ly} r={DOT_R} fill={it.c} />
83
97
  <circle cx={COL_R} cy={it.ry} r={DOT_R} fill={it.c} />
84
98
  <text x={COL_L - 10} y={it.lly + 4} fill="#A4A7B5" font-size="9" text-anchor="end" font-family="inherit">{it.label}</text>
85
- <text x={COL_L - 10} y={it.lly + 15} fill="#6E7079" font-size="9" text-anchor="end" font-family="inherit" font-variant-numeric="tabular-nums">{it.before}{unit}</text>
86
- <text x={COL_R + 10} y={it.rly + 4} fill="#A4A7B5" font-size="9" text-anchor="start" font-family="inherit" font-variant-numeric="tabular-nums">{it.after}{unit}</text>
87
- <text x={COL_R + 10} y={it.rly + 15} fill={it.c} font-size="9" text-anchor="start" font-family="inherit" font-variant-numeric="tabular-nums">{it.delta > 0 ? '+' : ''}{it.delta}{unit}</text>
99
+ <text x={COL_L - 10} y={it.lly + 15} fill="#6E7079" font-size="9" text-anchor="end" font-family="inherit" style="font-variant-numeric: tabular-nums">{it.before}{unit}</text>
100
+ <text x={COL_R + 10} y={it.rly + 4} fill="#A4A7B5" font-size="9" text-anchor="start" font-family="inherit" style="font-variant-numeric: tabular-nums">{it.after}{unit}</text>
101
+ <text x={COL_R + 10} y={it.rly + 15} fill={it.c} font-size="9" text-anchor="start" font-family="inherit" style="font-variant-numeric: tabular-nums">{it.delta > 0 ? '+' : ''}{it.delta}{unit}</text>
88
102
  {/each}
89
103
  </svg>
90
104
  </div>
@@ -1,16 +1,27 @@
1
1
  <script lang="ts">
2
- import { createEventDispatcher } from 'svelte';
3
- export let sortKey: string;
4
- export let activeKey: string | null = null;
5
- export let dir: 'asc' | 'desc' = 'asc';
6
- const dispatch = createEventDispatcher<{ sort: string }>();
7
- $: active = activeKey === sortKey;
8
- $: ariaSort = active ? (dir === 'asc' ? 'ascending' : 'descending') : 'none';
2
+
3
+ interface Props {
4
+ sortKey: string;
5
+ activeKey?: string | null;
6
+ dir?: 'asc' | 'desc';
7
+ children?: import('svelte').Snippet;
8
+ onsort?: (payload: string) => void;
9
+ }
10
+
11
+ let {
12
+ sortKey,
13
+ activeKey = null,
14
+ dir = 'asc',
15
+ children,
16
+ onsort,
17
+ }: Props = $props();
18
+ let active = $derived(activeKey === sortKey);
19
+ let ariaSort = $derived((active ? (dir === 'asc' ? 'ascending' : 'descending') : 'none') as 'ascending' | 'descending' | 'none');
9
20
  </script>
10
21
 
11
22
  <th scope="col" aria-sort={ariaSort}>
12
- <button type="button" class="sort-header-btn" on:click={() => dispatch('sort', sortKey)}>
13
- <slot />
23
+ <button type="button" class="sort-header-btn" onclick={() => onsort?.(sortKey)}>
24
+ {@render children?.()}
14
25
  <svg class="sort-icon" viewBox="0 0 8 11" aria-hidden="true" fill="currentColor">
15
26
  <path d="M4 0L7 4H1Z" opacity={active && dir === 'asc' ? 1 : 0.3} />
16
27
  <path d="M4 11L1 7H7Z" opacity={active && dir === 'desc' ? 1 : 0.3} />
@@ -1,17 +1,24 @@
1
- <script lang="ts">
1
+ <script module lang="ts">
2
2
  export interface SortableItem {
3
3
  id: string;
4
4
  label: string;
5
5
  meta?: string;
6
6
  }
7
+ </script>
8
+
9
+ <script lang="ts">
10
+
11
+ interface Props {
12
+ items?: SortableItem[];
13
+ onChange?: (items: SortableItem[]) => void;
14
+ ariaLabel?: string | undefined;
15
+ }
7
16
 
8
- export let items: SortableItem[] = [];
9
- export let onChange: (items: SortableItem[]) => void = () => {};
10
- export let ariaLabel: string | undefined = undefined;
17
+ let { items = $bindable([]), onChange = () => {}, ariaLabel = undefined }: Props = $props();
11
18
 
12
- let grabbed: string | null = null;
13
- let dragSrc: string | null = null;
14
- let dragOver: string | null = null;
19
+ let grabbed: string | null = $state(null);
20
+ let dragSrc: string | null = $state(null);
21
+ let dragOver: string | null = $state(null);
15
22
 
16
23
  function reorder(fromId: string, toId: string) {
17
24
  if (fromId === toId) return;
@@ -53,18 +60,18 @@
53
60
  class:is-grabbed={grabbed === item.id}
54
61
  class:is-drag-over={dragOver === item.id}
55
62
  draggable="true"
56
- on:dragstart={e => { e.dataTransfer?.setData('text/plain', item.id); if (e.dataTransfer) e.dataTransfer.effectAllowed = 'move'; dragSrc = item.id; }}
57
- on:dragend={() => { dragSrc = null; dragOver = null; }}
58
- on:dragover={e => { e.preventDefault(); if (e.dataTransfer) e.dataTransfer.dropEffect = 'move'; dragOver = item.id; }}
59
- on:dragleave={() => { dragOver = null; }}
60
- on:drop={e => { e.preventDefault(); if (dragSrc) reorder(dragSrc, item.id); dragSrc = null; dragOver = null; }}
63
+ ondragstart={e => { e.dataTransfer?.setData('text/plain', item.id); if (e.dataTransfer) e.dataTransfer.effectAllowed = 'move'; dragSrc = item.id; }}
64
+ ondragend={() => { dragSrc = null; dragOver = null; }}
65
+ ondragover={e => { e.preventDefault(); if (e.dataTransfer) e.dataTransfer.dropEffect = 'move'; dragOver = item.id; }}
66
+ ondragleave={() => { dragOver = null; }}
67
+ ondrop={e => { e.preventDefault(); if (dragSrc) reorder(dragSrc, item.id); dragSrc = null; dragOver = null; }}
61
68
  >
62
69
  <button
63
70
  type="button"
64
71
  class="sortable-list__handle"
65
72
  aria-label="{grabbed === item.id ? 'Release' : 'Grab'} {item.label}. Use arrow keys to reorder."
66
73
  aria-pressed={grabbed === item.id}
67
- on:keydown={e => handleKeyDown(e, item.id)}
74
+ onkeydown={e => handleKeyDown(e, item.id)}
68
75
  >
69
76
  <svg width="14" height="14" viewBox="0 0 14 14" fill="currentColor" aria-hidden="true" focusable="false">
70
77
  <rect x="3" y="2" width="2" height="2" rx="1" />
@@ -1,8 +1,17 @@
1
1
  <script lang="ts">
2
- export let bars: number = 36;
3
- export let active: boolean = false;
4
- export let seed: number = 1;
5
- export let ariaLabel: string = 'Activity sparkline';
2
+ interface Props {
3
+ bars?: number;
4
+ active?: boolean;
5
+ seed?: number;
6
+ ariaLabel?: string;
7
+ }
8
+
9
+ let {
10
+ bars = 36,
11
+ active = false,
12
+ seed = 1,
13
+ ariaLabel = 'Activity sparkline'
14
+ }: Props = $props();
6
15
 
7
16
  function rng(s0: number) {
8
17
  let s = s0;
@@ -12,7 +21,7 @@
12
21
  };
13
22
  }
14
23
 
15
- $: heights = (() => {
24
+ let heights = $derived((() => {
16
25
  const r = rng(seed);
17
26
  const out: number[] = [];
18
27
  let prev = 12;
@@ -22,7 +31,7 @@
22
31
  out.push(v);
23
32
  }
24
33
  return out;
25
- })();
34
+ })());
26
35
  </script>
27
36
 
28
37
  <div class="spark" role="img" aria-label={ariaLabel}>
@@ -1,14 +1,21 @@
1
- <script lang="ts">
1
+ <script module lang="ts">
2
2
  export interface SparklineMatrixRow {
3
3
  label: string;
4
4
  values: number[];
5
5
  unit?: string;
6
6
  color?: string;
7
7
  }
8
+ </script>
9
+
10
+ <script lang="ts">
11
+
12
+ interface Props {
13
+ rows?: SparklineMatrixRow[];
14
+ height?: number;
15
+ ariaLabel?: string;
16
+ }
8
17
 
9
- export let rows: SparklineMatrixRow[] = [];
10
- export let height: number = 160;
11
- export let ariaLabel: string = 'Sparkline matrix';
18
+ let { rows = [], height = 160, ariaLabel = 'Sparkline matrix' }: Props = $props();
12
19
 
13
20
  const VW = 380;
14
21
  const PAD_L = 76;
@@ -17,12 +24,12 @@
17
24
  const SPARK_PAD_Y = 5;
18
25
  const PALETTE = ['#006FFF', '#00C875', '#7FB6FF', '#F5A623', '#FF7B7B', '#A78BFA'];
19
26
 
20
- $: rowH = height / (rows.length || 1);
21
- $: sparkX0 = PAD_L + SPARK_PAD_X;
22
- $: sparkW = VW - PAD_L - PAD_R - SPARK_PAD_X * 2;
23
- $: sparkH = rowH - SPARK_PAD_Y * 2;
27
+ let rowH = $derived(height / (rows.length || 1));
28
+ let sparkX0 = $derived(PAD_L + SPARK_PAD_X);
29
+ let sparkW = $derived(VW - PAD_L - PAD_R - SPARK_PAD_X * 2);
30
+ let sparkH = $derived(rowH - SPARK_PAD_Y * 2);
24
31
 
25
- $: computed = rows.map((row, i) => {
32
+ let computed = $derived(rows.map((row, i) => {
26
33
  const y0 = i * rowH + SPARK_PAD_Y;
27
34
  const color = row.color ?? PALETTE[i % PALETTE.length];
28
35
  const min = Math.min(...row.values);
@@ -43,7 +50,7 @@
43
50
 
44
51
  const dotY = y0 + sparkH - ((lastVal - min) / range) * sparkH;
45
52
  return { color, lastVal, d, dotX: sparkX0 + sparkW, dotY, midY: i * rowH + rowH / 2 };
46
- });
53
+ }));
47
54
  </script>
48
55
 
49
56
  {#if rows.length}