@sentropic/design-system-svelte 0.15.0 → 0.16.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.
@@ -249,6 +249,30 @@
249
249
  * null when the hover/focus ends. Intended for syncing an external panel.
250
250
  */
251
251
  onNodeHover?: (node: ForceGraphNode | null) => void;
252
+ /**
253
+ * Reconciliation merge animation (CLIENT-ONLY — driven by `$effect`, which
254
+ * never runs during SSR, so no merge is animated or resolved server-side).
255
+ *
256
+ * Pass a `{ id, from, into }` where both `from` and `into` exist in `nodes`:
257
+ * the `from` node animates toward the position of `into` while fading out
258
+ * (the node and its incident edges), then `onMergeComplete(pair)` fires
259
+ * exactly ONCE for that `id`. Purely visual — the component never mutates the
260
+ * data; the consumer removes `from` from `nodes` after the callback.
261
+ *
262
+ * Idempotent on `id`: re-passing the SAME `id` (even with a new identity for
263
+ * the object) is a no-op — the animation/callback are not replayed. Passing a
264
+ * NEW `id` (re)plays the merge, even for the same `from`/`into` pair. After
265
+ * completion the `from` node stays MASKED (hidden) until the consumer removes
266
+ * it or a new `mergePair` is supplied, so it does not flash back when the
267
+ * prop returns to null. Pass null (the default) for no merge in flight.
268
+ */
269
+ mergePair?: { id: string; from: string; into: string } | null;
270
+ /**
271
+ * Fired once the merge animation for the current `mergePair` completes (or
272
+ * immediately, on a microtask, under reduced motion). Fires at most ONCE per
273
+ * `id`. Receives the same pair so the consumer can drop `from` from the data.
274
+ */
275
+ onMergeComplete?: (pair: { id: string; from: string; into: string }) => void;
252
276
  class?: string;
253
277
  };
254
278
 
@@ -270,6 +294,8 @@
270
294
  edgeCurve = 0.15,
271
295
  repulsion = 1,
272
296
  onNodeHover,
297
+ mergePair = null,
298
+ onMergeComplete,
273
299
  class: className
274
300
  }: ForceGraphProps = $props();
275
301
 
@@ -320,6 +346,26 @@
320
346
  };
321
347
  }
322
348
 
349
+ // Stable seed from the SET of node ids (sorted), not from ns.length/es.length.
350
+ // A length-based seed reshuffled the whole layout whenever a node was added or
351
+ // removed (notably after a reconciliation merge), making the graph "jump". A
352
+ // hash over the sorted ids keeps the same topology → same layout, so removing
353
+ // one node leaves the rest essentially in place. (FNV-1a 32-bit over the joined
354
+ // sorted ids; deterministic and order-independent.)
355
+ function stableSeed(ns: ForceGraphNode[]): number {
356
+ const ids = ns.map((n) => n.id).sort();
357
+ let h = 0x811c9dc5; // FNV offset basis
358
+ const joined = ids.join("|");
359
+ for (let i = 0; i < joined.length; i++) {
360
+ h ^= joined.charCodeAt(i);
361
+ h = Math.imul(h, 0x01000193); // FNV prime
362
+ }
363
+ // Fold in the count too so wholly different graphs of equal id-hash still
364
+ // differ, but the dominant term is the (order-independent) id hash.
365
+ h ^= ns.length;
366
+ return h >>> 0;
367
+ }
368
+
323
369
  function runSimulation(
324
370
  ns: ForceGraphNode[],
325
371
  es: ForceGraphEdge[],
@@ -330,7 +376,9 @@
330
376
  ): Map<string, { x: number; y: number }> {
331
377
  const cx = w / 2;
332
378
  const cy = h / 2;
333
- const rand = mulberry32(ns.length * 2654435761 + es.length);
379
+ // Seed from the stable id-set hash so adding/removing a node does not
380
+ // reshuffle the whole layout (same topology → same layout).
381
+ const rand = mulberry32(stableSeed(ns));
334
382
  const idIndex = new Map<string, number>();
335
383
  const sim: SimNode[] = ns.map((n, i) => {
336
384
  idIndex.set(n.id, i);
@@ -549,6 +597,176 @@
549
597
  .filter((e): e is NonNullable<typeof e> => e !== null);
550
598
  });
551
599
 
600
+ // ---------------------------------------------------------------------------
601
+ // Merge animation (reconciliation): when `mergePair` becomes a new valid pair,
602
+ // the `from` node slides toward `into` while fading out (node + incident
603
+ // edges), then `onMergeComplete` fires. Purely visual — never mutates props.
604
+ // Driven by a single $state holding per-merge progress (0→1). Under reduced
605
+ // motion / SSR we skip straight to completion on a microtask.
606
+ // ---------------------------------------------------------------------------
607
+ const MERGE_DURATION_MS = 450;
608
+ // ease-in-out (cubic) for a smooth glide.
609
+ const easeInOut = (t: number) =>
610
+ t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
611
+
612
+ type MergeState = {
613
+ id: string;
614
+ from: string;
615
+ into: string;
616
+ /** Animation progress, 0..1. */
617
+ progress: number;
618
+ /** Pixel delta from the `from` start position to `into`, captured at start. */
619
+ dx: number;
620
+ dy: number;
621
+ } | null;
622
+
623
+ let mergeState = $state<MergeState>(null);
624
+ let mergeRaf: number | null = null;
625
+ // The id currently being (or already) handled, so the $effect only reacts to a
626
+ // genuinely NEW id. Re-passing the same id (even a fresh object) is a no-op.
627
+ let handledMergeId: string | null = null;
628
+ // The id of the `from` node to keep MASKED after a completed merge, until the
629
+ // consumer drops it from `nodes` (or a new pair arrives). Decouples the mask
630
+ // from `mergePair` returning to null (otherwise the node would flash back).
631
+ let maskedFromId = $state<string | null>(null);
632
+ // Set true on the component's own teardown so no queued microtask/frame fires a
633
+ // callback or touches reactive state after unmount.
634
+ let disposed = false;
635
+
636
+ function cancelMergeRaf() {
637
+ if (mergeRaf != null && typeof cancelAnimationFrame === "function") {
638
+ cancelAnimationFrame(mergeRaf);
639
+ }
640
+ mergeRaf = null;
641
+ }
642
+
643
+ // Component-lifetime teardown guard (separate from the per-pair effect below):
644
+ // marks the instance disposed and cancels any in-flight frame on unmount.
645
+ $effect(() => {
646
+ return () => {
647
+ disposed = true;
648
+ cancelMergeRaf();
649
+ };
650
+ });
651
+
652
+ $effect(() => {
653
+ const pair = mergePair;
654
+ const id = pair ? pair.id : null;
655
+
656
+ // Idempotent on id: same id (or still null) means nothing to (re)start. A new
657
+ // id always (re)plays, even for the same from/into pair.
658
+ if (id === handledMergeId) return;
659
+ handledMergeId = id;
660
+
661
+ // Tear down any in-flight animation for a previous pair.
662
+ cancelMergeRaf();
663
+ mergeState = null;
664
+
665
+ if (!pair) return;
666
+
667
+ // A genuinely new pair supersedes any lingering mask from a prior merge.
668
+ maskedFromId = null;
669
+
670
+ // Validate: both endpoints must currently exist.
671
+ const fromPos = layout.get(pair.from);
672
+ const intoPos = layout.get(pair.into);
673
+ if (!fromPos || !intoPos) return; // invalid pair: no-op, no crash, no callback
674
+
675
+ const captured = { id: pair.id, from: pair.from, into: pair.into };
676
+
677
+ const complete = () => {
678
+ // Keep `from` hidden until the consumer removes it (or a new pair arrives).
679
+ maskedFromId = captured.from;
680
+ onMergeComplete?.(captured);
681
+ };
682
+
683
+ // Reduced motion: no animation, resolve on a microtask. Guarded so a late
684
+ // microtask after unmount or after a newer id took over is a no-op.
685
+ if (prefersReducedMotion || typeof requestAnimationFrame !== "function") {
686
+ queueMicrotask(() => {
687
+ if (disposed || handledMergeId !== id) return;
688
+ complete();
689
+ });
690
+ return;
691
+ }
692
+
693
+ const dx = intoPos.x - fromPos.x;
694
+ const dy = intoPos.y - fromPos.y;
695
+ mergeState = { id: captured.id, from: captured.from, into: captured.into, progress: 0, dx, dy };
696
+
697
+ // Anchor the clock to the FIRST frame's own timestamp. rAF timestamps and
698
+ // performance.now() can use different time origins (notably under jsdom), so
699
+ // mixing them yields a negative/garbage elapsed time. Using the frame clock
700
+ // for both start and elapsed keeps the easing monotonic everywhere.
701
+ let start: number | null = null;
702
+ const tick = (now: number) => {
703
+ // Bail cleanly if the instance went away or a newer id superseded us — no
704
+ // callback, no dangling state.
705
+ if (disposed || handledMergeId !== id) {
706
+ mergeRaf = null;
707
+ return;
708
+ }
709
+ // Re-validate both endpoints every frame: if either disappears mid-flight
710
+ // (e.g. the consumer removed a node), cancel the glide WITHOUT firing
711
+ // onMergeComplete (no double-tir) and without a dangling frame.
712
+ if (!layout.has(captured.from) || !layout.has(captured.into)) {
713
+ cancelMergeRaf();
714
+ mergeState = null;
715
+ return;
716
+ }
717
+ if (start === null) start = now;
718
+ const t = Math.min(1, Math.max(0, (now - start) / MERGE_DURATION_MS));
719
+ if (mergeState) mergeState = { ...mergeState, progress: t };
720
+ if (t < 1) {
721
+ mergeRaf = requestAnimationFrame(tick);
722
+ } else {
723
+ mergeRaf = null;
724
+ mergeState = null;
725
+ complete();
726
+ }
727
+ };
728
+ mergeRaf = requestAnimationFrame(tick);
729
+
730
+ return () => cancelMergeRaf();
731
+ });
732
+
733
+ // ---------------------------------------------------------------------------
734
+ // The `from` node is hidden while it is the active merge source AND while it
735
+ // remains masked post-completion (until the consumer removes it). Both feed the
736
+ // same opacity helpers below.
737
+ // ---------------------------------------------------------------------------
738
+ const mergeFromId = $derived(mergeState?.from ?? null);
739
+ const mergeEased = $derived(mergeState ? easeInOut(mergeState.progress) : 0);
740
+
741
+ /** True when this id is the (post-merge) masked node — render it fully hidden. */
742
+ function isMasked(id: string): boolean {
743
+ return maskedFromId === id;
744
+ }
745
+
746
+ /** Extra translation applied to the merging node so it glides toward `into`. */
747
+ function mergeOffset(id: string): { x: number; y: number } {
748
+ if (!mergeState || mergeState.from !== id) return { x: 0, y: 0 };
749
+ return { x: mergeState.dx * mergeEased, y: mergeState.dy * mergeEased };
750
+ }
751
+
752
+ /**
753
+ * Opacity for a node during/after a merge. The animating `from` fades 1->0; a
754
+ * masked `from` (merge done, awaiting removal) stays at 0. Others unaffected.
755
+ */
756
+ function mergeNodeOpacity(id: string): number | null {
757
+ if (isMasked(id)) return 0;
758
+ if (mergeFromId !== id) return null;
759
+ return 1 - mergeEased;
760
+ }
761
+
762
+ /** Opacity for an edge incident to the merging/masked `from` node (fades too). */
763
+ function mergeEdgeOpacity(e: ForceGraphEdge): number | null {
764
+ const fromId = mergeFromId ?? maskedFromId;
765
+ if (fromId == null) return null;
766
+ if (e.source !== fromId && e.target !== fromId) return null;
767
+ return isMasked(fromId) ? 0 : 1 - mergeEased;
768
+ }
769
+
552
770
  let hoveredNodeIndex: number | null = $state(null);
553
771
  let hoveredEdgeIndex: number | null = $state(null);
554
772
 
@@ -779,6 +997,7 @@
779
997
  onmouseleave={() => { hoveredEdgeIndex = null; }}
780
998
  />
781
999
  {/if}
1000
+ {@const mEdgeOpacity = mergeEdgeOpacity(e.edge)}
782
1001
  {#if e.path}
783
1002
  <path
784
1003
  class="st-forceGraph__edge"
@@ -786,10 +1005,12 @@
786
1005
  class:st-forceGraph__edge--emphasis={e.edge.emphasis}
787
1006
  class:st-forceGraph__edge--hovered={hoveredEdgeIndex === e.i}
788
1007
  class:st-forceGraph__edge--dim={isEdgeSelectionDimmed(e.edge) || isHoverDimmedEdge(e.edge)}
1008
+ class:st-forceGraph__edge--merging={mEdgeOpacity !== null}
789
1009
  d={e.path}
790
1010
  fill="none"
791
1011
  stroke-dasharray={e.dashArray}
792
1012
  stroke-width={e.strokeWidth}
1013
+ opacity={mEdgeOpacity}
793
1014
  pointer-events="none"
794
1015
  />
795
1016
  {:else}
@@ -799,12 +1020,14 @@
799
1020
  class:st-forceGraph__edge--emphasis={e.edge.emphasis}
800
1021
  class:st-forceGraph__edge--hovered={hoveredEdgeIndex === e.i}
801
1022
  class:st-forceGraph__edge--dim={isEdgeSelectionDimmed(e.edge) || isHoverDimmedEdge(e.edge)}
1023
+ class:st-forceGraph__edge--merging={mEdgeOpacity !== null}
802
1024
  x1={e.x1}
803
1025
  y1={e.y1}
804
1026
  x2={e.x2}
805
1027
  y2={e.y2}
806
1028
  stroke-dasharray={e.dashArray}
807
1029
  stroke-width={e.strokeWidth}
1030
+ opacity={mEdgeOpacity}
808
1031
  pointer-events="none"
809
1032
  />
810
1033
  {/if}
@@ -813,12 +1036,18 @@
813
1036
 
814
1037
  <g class="st-forceGraph__nodes">
815
1038
  {#each positionedNodes as p (p.node.id)}
1039
+ {@const mOff = mergeOffset(p.node.id)}
1040
+ {@const mOpacity = mergeNodeOpacity(p.node.id)}
1041
+ {@const mMasked = isMasked(p.node.id)}
816
1042
  <g
817
1043
  class="st-forceGraph__node st-forceGraph__node--{p.tone}"
818
1044
  class:st-forceGraph__node--dim={isHoverDimmedNode(p.node.id) || isSelectionDimmed(p.node.id)}
819
1045
  class:st-forceGraph__node--selected={selectedSet.has(p.node.id)}
820
1046
  class:st-forceGraph__node--focus={focusId === p.node.id}
821
- transform="translate({p.x} {p.y})"
1047
+ class:st-forceGraph__node--merging={mergeFromId === p.node.id || mMasked}
1048
+ aria-hidden={mMasked ? "true" : undefined}
1049
+ opacity={mOpacity}
1050
+ transform="translate({p.x + mOff.x} {p.y + mOff.y})"
822
1051
  >
823
1052
  {#if p.shapePath}
824
1053
  <path
@@ -1022,6 +1251,14 @@
1022
1251
  .st-forceGraph__node { transition: opacity 120ms ease; }
1023
1252
  .st-forceGraph__node--dim { opacity: 0.3; }
1024
1253
 
1254
+ /* During a merge the opacity/transform are driven per-frame via rAF, so the
1255
+ CSS transitions are disabled to avoid a lag that would smear the glide. The
1256
+ fading/masked `from` node is also taken out of hit-testing so the invisible
1257
+ node cannot be hovered, focused or clicked. */
1258
+ .st-forceGraph__node--merging,
1259
+ .st-forceGraph__edge--merging { transition: none; }
1260
+ .st-forceGraph__node--merging { pointer-events: none; }
1261
+
1025
1262
  .st-forceGraph__dot {
1026
1263
  cursor: pointer;
1027
1264
  fill-opacity: 0.9;
@@ -138,6 +138,38 @@ type ForceGraphProps = {
138
138
  * null when the hover/focus ends. Intended for syncing an external panel.
139
139
  */
140
140
  onNodeHover?: (node: ForceGraphNode | null) => void;
141
+ /**
142
+ * Reconciliation merge animation (CLIENT-ONLY — driven by `$effect`, which
143
+ * never runs during SSR, so no merge is animated or resolved server-side).
144
+ *
145
+ * Pass a `{ id, from, into }` where both `from` and `into` exist in `nodes`:
146
+ * the `from` node animates toward the position of `into` while fading out
147
+ * (the node and its incident edges), then `onMergeComplete(pair)` fires
148
+ * exactly ONCE for that `id`. Purely visual — the component never mutates the
149
+ * data; the consumer removes `from` from `nodes` after the callback.
150
+ *
151
+ * Idempotent on `id`: re-passing the SAME `id` (even with a new identity for
152
+ * the object) is a no-op — the animation/callback are not replayed. Passing a
153
+ * NEW `id` (re)plays the merge, even for the same `from`/`into` pair. After
154
+ * completion the `from` node stays MASKED (hidden) until the consumer removes
155
+ * it or a new `mergePair` is supplied, so it does not flash back when the
156
+ * prop returns to null. Pass null (the default) for no merge in flight.
157
+ */
158
+ mergePair?: {
159
+ id: string;
160
+ from: string;
161
+ into: string;
162
+ } | null;
163
+ /**
164
+ * Fired once the merge animation for the current `mergePair` completes (or
165
+ * immediately, on a microtask, under reduced motion). Fires at most ONCE per
166
+ * `id`. Receives the same pair so the consumer can drop `from` from the data.
167
+ */
168
+ onMergeComplete?: (pair: {
169
+ id: string;
170
+ from: string;
171
+ into: string;
172
+ }) => void;
141
173
  class?: string;
142
174
  };
143
175
  declare const ForceGraph: import("svelte").Component<ForceGraphProps, {}, "">;
@@ -1 +1 @@
1
- {"version":3,"file":"ForceGraph.svelte.d.ts","sourceRoot":"","sources":["../src/lib/ForceGraph.svelte.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ForceGraph.svelte.d.ts","sourceRoot":"","sources":["../src/lib/ForceGraph.svelte.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,186 @@
1
+ <script lang="ts" module>
2
+ import type { Snippet } from "svelte";
3
+
4
+ export type SelectableListProps = {
5
+ /** Accessible name for the listbox (required for SR users). */
6
+ label?: string;
7
+ /** References the id of an external visible label (alternative to `label`). */
8
+ labelledby?: string;
9
+ /**
10
+ * Allow more than one selected row. Adds aria-multiselectable and toggles
11
+ * each row independently. Defaults to false (single-select).
12
+ */
13
+ multiple?: boolean;
14
+ /**
15
+ * Selected value(s). Controlled when provided. For single-select pass a
16
+ * string (or null); for multiple pass a string[]. When omitted the list is
17
+ * uncontrolled and keeps its own internal selection.
18
+ */
19
+ value?: string | string[] | null;
20
+ /**
21
+ * Fired with the new selection on every change. Receives a string|null for
22
+ * single-select and a string[] for multiple. Required for the controlled
23
+ * pattern; also fires for uncontrolled lists.
24
+ */
25
+ onchange?: (value: string | string[] | null) => void;
26
+ class?: string;
27
+ children?: Snippet;
28
+ };
29
+ </script>
30
+
31
+ <script lang="ts">
32
+ import { setContext, untrack } from "svelte";
33
+ import {
34
+ SELECTABLE_LIST_KEY,
35
+ type SelectableListContext
36
+ } from "./SelectableRow.svelte";
37
+
38
+ let {
39
+ label,
40
+ labelledby,
41
+ multiple = false,
42
+ value,
43
+ onchange,
44
+ class: className,
45
+ children
46
+ }: SelectableListProps = $props();
47
+
48
+ // Controlled when the consumer passes `value` (including null). Otherwise the
49
+ // list owns an internal selection set.
50
+ const controlled = $derived(value !== undefined);
51
+
52
+ function toSet(v: string | string[] | null | undefined): Set<string> {
53
+ if (v == null) return new Set();
54
+ return new Set(Array.isArray(v) ? v : [v]);
55
+ }
56
+
57
+ // Internal selection for the uncontrolled case.
58
+ let internal = $state<Set<string>>(new Set());
59
+ const selectedValues = $derived(controlled ? toSet(value) : internal);
60
+
61
+ // --- Row registry: ordered by DOM position so arrow nav matches the visual
62
+ // order regardless of registration timing. -------------------------------
63
+ type Entry = { el: HTMLElement; value: string | undefined };
64
+ let entries = $state<Entry[]>([]);
65
+
66
+ // The element that currently holds the roving tab stop (tabindex 0). Null until
67
+ // a row is focused; until then the FIRST enabled row is the default stop.
68
+ let tabStopEl = $state<HTMLElement | null>(null);
69
+
70
+ function sortByDom(list: Entry[]): Entry[] {
71
+ return [...list].sort((a, b) => {
72
+ const pos = a.el.compareDocumentPosition(b.el);
73
+ if (pos & Node.DOCUMENT_POSITION_FOLLOWING) return -1;
74
+ if (pos & Node.DOCUMENT_POSITION_PRECEDING) return 1;
75
+ return 0;
76
+ });
77
+ }
78
+
79
+ // register/unregister are called from each row's $effect. They read AND write
80
+ // `entries`, so the read must be untracked — otherwise the calling effect would
81
+ // subscribe to `entries`, and writing it would re-run the effect forever.
82
+ function register(el: HTMLElement, rowValue: string | undefined): () => void {
83
+ untrack(() => {
84
+ entries = sortByDom([...entries.filter((e) => e.el !== el), { el, value: rowValue }]);
85
+ });
86
+ return () => {
87
+ untrack(() => {
88
+ entries = entries.filter((e) => e.el !== el);
89
+ if (tabStopEl === el) tabStopEl = null;
90
+ });
91
+ };
92
+ }
93
+
94
+ // Default roving stop = first registered (DOM-ordered) row when none focused.
95
+ const effectiveTabStop = $derived(tabStopEl ?? entries[0]?.el ?? null);
96
+
97
+ function valueOf(el: HTMLElement): string | undefined {
98
+ return entries.find((e) => e.el === el)?.value;
99
+ }
100
+
101
+ function isSelected(el: HTMLElement): boolean {
102
+ const v = valueOf(el);
103
+ return v !== undefined && selectedValues.has(v);
104
+ }
105
+
106
+ function isTabStop(el: HTMLElement): boolean {
107
+ return el === effectiveTabStop;
108
+ }
109
+
110
+ function emit(next: Set<string>) {
111
+ if (!controlled) internal = next;
112
+ if (multiple) onchange?.([...next]);
113
+ else onchange?.(next.size ? [...next][0] : null);
114
+ }
115
+
116
+ function activate(el: HTMLElement) {
117
+ const v = valueOf(el);
118
+ if (v === undefined) return;
119
+ const current = selectedValues;
120
+ let next: Set<string>;
121
+ if (multiple) {
122
+ next = new Set(current);
123
+ if (next.has(v)) next.delete(v);
124
+ else next.add(v);
125
+ } else {
126
+ // Single-select toggles off when re-activating the selected row.
127
+ next = current.has(v) && current.size === 1 ? new Set() : new Set([v]);
128
+ }
129
+ emit(next);
130
+ }
131
+
132
+ function focusRow(el: HTMLElement) {
133
+ tabStopEl = el;
134
+ }
135
+
136
+ function navigate(el: HTMLElement, key: string) {
137
+ if (entries.length === 0) return;
138
+ const idx = entries.findIndex((e) => e.el === el);
139
+ if (idx === -1) return;
140
+ let targetIdx = idx;
141
+ if (key === "ArrowDown" || key === "ArrowRight") targetIdx = idx + 1;
142
+ else if (key === "ArrowUp" || key === "ArrowLeft") targetIdx = idx - 1;
143
+ else if (key === "Home") targetIdx = 0;
144
+ else if (key === "End") targetIdx = entries.length - 1;
145
+ // Clamp (no wrap) so Home/End and arrows stay within bounds.
146
+ targetIdx = Math.max(0, Math.min(entries.length - 1, targetIdx));
147
+ const target = entries[targetIdx]?.el;
148
+ if (target) {
149
+ tabStopEl = target;
150
+ target.focus();
151
+ }
152
+ }
153
+
154
+ const context: SelectableListContext = {
155
+ managed: true,
156
+ itemRole: "option",
157
+ register,
158
+ isSelected,
159
+ isTabStop,
160
+ activate,
161
+ focusRow,
162
+ navigate
163
+ };
164
+ setContext(SELECTABLE_LIST_KEY, context);
165
+
166
+ const classes = $derived(["st-selectableList", className].filter(Boolean).join(" "));
167
+ </script>
168
+
169
+ <div
170
+ class={classes}
171
+ role="listbox"
172
+ aria-label={labelledby ? undefined : label}
173
+ aria-labelledby={labelledby}
174
+ aria-multiselectable={multiple ? "true" : undefined}
175
+ >
176
+ {@render children?.()}
177
+ </div>
178
+
179
+ <style>
180
+ .st-selectableList {
181
+ display: flex;
182
+ flex-direction: column;
183
+ gap: var(--st-spacing-1, 0.25rem);
184
+ width: 100%;
185
+ }
186
+ </style>
@@ -0,0 +1,30 @@
1
+ import type { Snippet } from "svelte";
2
+ export type SelectableListProps = {
3
+ /** Accessible name for the listbox (required for SR users). */
4
+ label?: string;
5
+ /** References the id of an external visible label (alternative to `label`). */
6
+ labelledby?: string;
7
+ /**
8
+ * Allow more than one selected row. Adds aria-multiselectable and toggles
9
+ * each row independently. Defaults to false (single-select).
10
+ */
11
+ multiple?: boolean;
12
+ /**
13
+ * Selected value(s). Controlled when provided. For single-select pass a
14
+ * string (or null); for multiple pass a string[]. When omitted the list is
15
+ * uncontrolled and keeps its own internal selection.
16
+ */
17
+ value?: string | string[] | null;
18
+ /**
19
+ * Fired with the new selection on every change. Receives a string|null for
20
+ * single-select and a string[] for multiple. Required for the controlled
21
+ * pattern; also fires for uncontrolled lists.
22
+ */
23
+ onchange?: (value: string | string[] | null) => void;
24
+ class?: string;
25
+ children?: Snippet;
26
+ };
27
+ declare const SelectableList: import("svelte").Component<SelectableListProps, {}, "">;
28
+ type SelectableList = ReturnType<typeof SelectableList>;
29
+ export default SelectableList;
30
+ //# sourceMappingURL=SelectableList.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectableList.svelte.d.ts","sourceRoot":"","sources":["../src/lib/SelectableList.svelte.ts"],"names":[],"mappings":"AAGE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,MAAM,MAAM,mBAAmB,GAAG;IAChC,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC;IACjC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,KAAK,IAAI,CAAC;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AA0JJ,QAAA,MAAM,cAAc,yDAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
@@ -0,0 +1,291 @@
1
+ <script lang="ts" module>
2
+ import type { Snippet } from "svelte";
3
+
4
+ /**
5
+ * Shared context contract between {@link SelectableList} and its slotted
6
+ * {@link SelectableRow} children. The list owns selection + roving tabindex and
7
+ * exposes reactive getters the rows read to derive their own `role` / `tabindex`
8
+ * / `aria-selected`, plus callbacks for registration and activation. When a row
9
+ * is used STANDALONE (no list) `getContext` returns undefined and the row falls
10
+ * back to its own `role` / `tabindex` / selection state.
11
+ */
12
+ export const SELECTABLE_LIST_KEY = Symbol("st-selectable-list");
13
+
14
+ export type SelectableListContext = {
15
+ /** True when the list manages selection/roving for its rows. */
16
+ readonly managed: true;
17
+ /** listbox role for the wrapper → rows are "option". */
18
+ readonly itemRole: "option";
19
+ /** Register a row element; returns an unregister callback. */
20
+ register: (el: HTMLElement, value: string | undefined) => () => void;
21
+ /** Is the row with this element currently selected? */
22
+ isSelected: (el: HTMLElement) => boolean;
23
+ /** Should the row with this element be the roving-tabindex stop (tabindex 0)? */
24
+ isTabStop: (el: HTMLElement) => boolean;
25
+ /** Row was activated (click / Space / Enter). The list toggles selection. */
26
+ activate: (el: HTMLElement) => void;
27
+ /** Row received focus → becomes the roving tab stop. */
28
+ focusRow: (el: HTMLElement) => void;
29
+ /** Arrow / Home / End navigation from a row. */
30
+ navigate: (el: HTMLElement, key: string) => void;
31
+ };
32
+
33
+ export type SelectableRowProps = {
34
+ /**
35
+ * Selected state (bindable). Honoured when the row is used STANDALONE; inside
36
+ * a {@link SelectableList} the list is the source of truth and drives the
37
+ * selected styling, so this prop is ignored for managed rows.
38
+ */
39
+ selected?: boolean;
40
+ /** Notified on every toggle with the new selected state (standalone rows). */
41
+ onselect?: (selected: boolean) => void;
42
+ /** Non-interactive when true. */
43
+ disabled?: boolean;
44
+ /** Stable value, surfaced as `data-value` and used by the list for `value`. */
45
+ value?: string;
46
+ /**
47
+ * ARIA role for the standalone row. Defaults to "option" so a lone row still
48
+ * reads as a selectable item. Inside a list the role is forced to "option".
49
+ */
50
+ role?: string;
51
+ /**
52
+ * Opt-in left accent bar on the selected state. Off by default so the
53
+ * selected item is a calm tinted surface + accented text (two signals only).
54
+ */
55
+ accentBar?: boolean;
56
+ /** Leading slot (icon / avatar). */
57
+ leading?: Snippet;
58
+ /** Trailing slot (meta / icon). */
59
+ trailing?: Snippet;
60
+ /** Main content. */
61
+ children?: Snippet;
62
+ class?: string;
63
+ };
64
+ </script>
65
+
66
+ <script lang="ts">
67
+ import { getContext } from "svelte";
68
+
69
+ let {
70
+ selected = $bindable(false),
71
+ onselect,
72
+ disabled = false,
73
+ value,
74
+ role = "option",
75
+ accentBar = false,
76
+ leading,
77
+ trailing,
78
+ children,
79
+ class: className
80
+ }: SelectableRowProps = $props();
81
+
82
+ // When rendered inside a SelectableList, the list (via context) owns selection
83
+ // and the roving tabindex. Standalone rows manage their own state.
84
+ const list = getContext<SelectableListContext | undefined>(SELECTABLE_LIST_KEY);
85
+
86
+ let el: HTMLElement | null = $state(null);
87
+
88
+ // Register with the parent list (if any) so it can order rows for arrow nav
89
+ // and compute the roving tab stop. The effect re-registers if value changes.
90
+ $effect(() => {
91
+ if (!list || !el || disabled) return;
92
+ return list.register(el, value);
93
+ });
94
+
95
+ // Effective selected state: list-managed rows read the list; standalone rows
96
+ // use their own bindable prop.
97
+ const isSelected = $derived(list && el ? list.isSelected(el) : selected);
98
+
99
+ // Effective role: a managed row is always an "option" inside the listbox.
100
+ const effectiveRole = $derived(list ? list.itemRole : role);
101
+
102
+ // Roving tabindex: in a list, exactly one enabled row is the tab stop (0), the
103
+ // rest are -1. Standalone enabled rows are always tabbable (0). Disabled = -1.
104
+ const tabindex = $derived(
105
+ disabled ? -1 : list && el ? (list.isTabStop(el) ? 0 : -1) : 0
106
+ );
107
+
108
+ const classes = $derived(
109
+ [
110
+ "st-selectableRow",
111
+ isSelected ? "st-selectableRow--selected" : null,
112
+ disabled ? "st-selectableRow--disabled" : null,
113
+ accentBar ? "st-selectableRow--accentBar" : null,
114
+ className
115
+ ]
116
+ .filter(Boolean)
117
+ .join(" ")
118
+ );
119
+
120
+ function activate() {
121
+ if (disabled) return;
122
+ if (list && el) {
123
+ list.activate(el);
124
+ return;
125
+ }
126
+ selected = !selected;
127
+ onselect?.(selected);
128
+ }
129
+
130
+ function handleKeydown(e: KeyboardEvent) {
131
+ if (disabled) return;
132
+ if (e.key === "Enter" || e.key === " ") {
133
+ e.preventDefault();
134
+ activate();
135
+ return;
136
+ }
137
+ // Roving navigation is owned by the list; forward the relevant keys.
138
+ if (
139
+ list &&
140
+ el &&
141
+ (e.key === "ArrowDown" ||
142
+ e.key === "ArrowUp" ||
143
+ e.key === "ArrowLeft" ||
144
+ e.key === "ArrowRight" ||
145
+ e.key === "Home" ||
146
+ e.key === "End")
147
+ ) {
148
+ e.preventDefault();
149
+ list.navigate(el, e.key);
150
+ }
151
+ }
152
+
153
+ function handleFocus() {
154
+ if (disabled) return;
155
+ if (list && el) list.focusRow(el);
156
+ }
157
+ </script>
158
+
159
+ <!-- The row carries an interactive ARIA role (option/listbox item) so a roving
160
+ tabindex is correct; the role is dynamic, which the static a11y check cannot
161
+ verify, hence the targeted ignore. -->
162
+ <!-- svelte-ignore a11y_no_noninteractive_tabindex -->
163
+ <div
164
+ bind:this={el}
165
+ class={classes}
166
+ role={effectiveRole}
167
+ aria-selected={effectiveRole === "option" ? isSelected : undefined}
168
+ aria-disabled={disabled ? "true" : undefined}
169
+ data-value={value}
170
+ {tabindex}
171
+ onclick={activate}
172
+ onkeydown={handleKeydown}
173
+ onfocus={handleFocus}
174
+ >
175
+ {#if leading}
176
+ <span class="st-selectableRow__leading">{@render leading()}</span>
177
+ {/if}
178
+ <span class="st-selectableRow__content">{@render children?.()}</span>
179
+ {#if trailing}
180
+ <span class="st-selectableRow__trailing">{@render trailing()}</span>
181
+ {/if}
182
+ </div>
183
+
184
+ <style>
185
+ /* Compact, full-width selectable list/rail row. By DEFAULT the selected state
186
+ is just two calm signals — a tinted surface + accented text — deliberately
187
+ NOT the off-theme "boudin box" (inset box-shadow + heavy rounded border) it
188
+ replaces, and NOT a reflow-causing font-weight bump. The fine left accent
189
+ bar is OPT-IN via the `accentBar` prop. */
190
+ .st-selectableRow {
191
+ align-items: center;
192
+ background: transparent;
193
+ border-radius: var(--st-radius-sm, 0.25rem);
194
+ box-sizing: border-box;
195
+ color: var(--st-semantic-text-secondary, #475569);
196
+ cursor: pointer;
197
+ display: flex;
198
+ gap: var(--st-spacing-2, 0.5rem);
199
+ padding: 0.5rem 0.75rem;
200
+ position: relative;
201
+ text-align: left;
202
+ transition:
203
+ background-color var(--st-motion-fast, 120ms) var(--st-motion-easing, ease),
204
+ color var(--st-motion-fast, 120ms) var(--st-motion-easing, ease);
205
+ user-select: none;
206
+ width: 100%;
207
+ }
208
+
209
+ /* Opt-in accent bar: reserve the 2px gutter only when enabled so text never
210
+ shifts on selection. */
211
+ .st-selectableRow--accentBar {
212
+ padding-left: calc(0.75rem - 2px);
213
+ border-left: 2px solid transparent;
214
+ }
215
+
216
+ .st-selectableRow:hover:not(.st-selectableRow--disabled):not(.st-selectableRow--selected) {
217
+ background: var(
218
+ --st-component-control-hoverBackground,
219
+ var(--st-semantic-surface-subtle, #f8fafc)
220
+ );
221
+ color: var(--st-semantic-text-primary, #0f172a);
222
+ }
223
+
224
+ /* Focus ring as an EXTERNAL offset (not inset) so it reads as a focus
225
+ affordance around the row rather than an inner stroke. */
226
+ .st-selectableRow:focus-visible {
227
+ outline: 2px solid var(--st-semantic-border-interactive, var(--st-semantic-action-primary));
228
+ outline-offset: 2px;
229
+ }
230
+
231
+ /* Selected: two signals by default — tinted surface + accented (contrast-safe)
232
+ text. The token values carry a flat fallback; the inline color-mix is only a
233
+ last-resort default when the token is unset. */
234
+ .st-selectableRow--selected {
235
+ background: var(
236
+ --st-component-selectableRow-selectedBackground,
237
+ color-mix(in oklch, var(--st-semantic-action-primary, #2563eb) 12%, transparent)
238
+ );
239
+ color: var(
240
+ --st-component-selectableRow-selectedText,
241
+ color-mix(in oklch, var(--st-semantic-action-primary, #2563eb) 78%, black)
242
+ );
243
+ }
244
+
245
+ /* The left accent bar paints only when opt-in AND selected. */
246
+ .st-selectableRow--accentBar.st-selectableRow--selected {
247
+ border-left-color: var(
248
+ --st-component-selectableRow-selectedAccent,
249
+ var(--st-semantic-action-primary, #2563eb)
250
+ );
251
+ }
252
+
253
+ /* color-mix fallback: engines without color-mix() get a flat tinted surface +
254
+ a solid accent text from the resolved tokens' plain values. */
255
+ @supports not (color: color-mix(in oklch, red, blue)) {
256
+ .st-selectableRow--selected {
257
+ background: var(
258
+ --st-component-selectableRow-selectedBackground,
259
+ var(--st-semantic-surface-subtle, #eef2ff)
260
+ );
261
+ color: var(
262
+ --st-component-selectableRow-selectedText,
263
+ var(--st-semantic-action-primary, #1d4ed8)
264
+ );
265
+ }
266
+ }
267
+
268
+ .st-selectableRow--disabled {
269
+ cursor: not-allowed;
270
+ opacity: 0.55;
271
+ }
272
+
273
+ .st-selectableRow__leading,
274
+ .st-selectableRow__trailing {
275
+ align-items: center;
276
+ display: inline-flex;
277
+ flex: 0 0 auto;
278
+ }
279
+
280
+ .st-selectableRow__content {
281
+ flex: 1 1 auto;
282
+ min-width: 0;
283
+ overflow: hidden;
284
+ text-overflow: ellipsis;
285
+ white-space: nowrap;
286
+ }
287
+
288
+ @media (prefers-reduced-motion: reduce) {
289
+ .st-selectableRow { transition: none; }
290
+ }
291
+ </style>
@@ -0,0 +1,63 @@
1
+ import type { Snippet } from "svelte";
2
+ /**
3
+ * Shared context contract between {@link SelectableList} and its slotted
4
+ * {@link SelectableRow} children. The list owns selection + roving tabindex and
5
+ * exposes reactive getters the rows read to derive their own `role` / `tabindex`
6
+ * / `aria-selected`, plus callbacks for registration and activation. When a row
7
+ * is used STANDALONE (no list) `getContext` returns undefined and the row falls
8
+ * back to its own `role` / `tabindex` / selection state.
9
+ */
10
+ export declare const SELECTABLE_LIST_KEY: unique symbol;
11
+ export type SelectableListContext = {
12
+ /** True when the list manages selection/roving for its rows. */
13
+ readonly managed: true;
14
+ /** listbox role for the wrapper → rows are "option". */
15
+ readonly itemRole: "option";
16
+ /** Register a row element; returns an unregister callback. */
17
+ register: (el: HTMLElement, value: string | undefined) => () => void;
18
+ /** Is the row with this element currently selected? */
19
+ isSelected: (el: HTMLElement) => boolean;
20
+ /** Should the row with this element be the roving-tabindex stop (tabindex 0)? */
21
+ isTabStop: (el: HTMLElement) => boolean;
22
+ /** Row was activated (click / Space / Enter). The list toggles selection. */
23
+ activate: (el: HTMLElement) => void;
24
+ /** Row received focus → becomes the roving tab stop. */
25
+ focusRow: (el: HTMLElement) => void;
26
+ /** Arrow / Home / End navigation from a row. */
27
+ navigate: (el: HTMLElement, key: string) => void;
28
+ };
29
+ export type SelectableRowProps = {
30
+ /**
31
+ * Selected state (bindable). Honoured when the row is used STANDALONE; inside
32
+ * a {@link SelectableList} the list is the source of truth and drives the
33
+ * selected styling, so this prop is ignored for managed rows.
34
+ */
35
+ selected?: boolean;
36
+ /** Notified on every toggle with the new selected state (standalone rows). */
37
+ onselect?: (selected: boolean) => void;
38
+ /** Non-interactive when true. */
39
+ disabled?: boolean;
40
+ /** Stable value, surfaced as `data-value` and used by the list for `value`. */
41
+ value?: string;
42
+ /**
43
+ * ARIA role for the standalone row. Defaults to "option" so a lone row still
44
+ * reads as a selectable item. Inside a list the role is forced to "option".
45
+ */
46
+ role?: string;
47
+ /**
48
+ * Opt-in left accent bar on the selected state. Off by default so the
49
+ * selected item is a calm tinted surface + accented text (two signals only).
50
+ */
51
+ accentBar?: boolean;
52
+ /** Leading slot (icon / avatar). */
53
+ leading?: Snippet;
54
+ /** Trailing slot (meta / icon). */
55
+ trailing?: Snippet;
56
+ /** Main content. */
57
+ children?: Snippet;
58
+ class?: string;
59
+ };
60
+ declare const SelectableRow: import("svelte").Component<SelectableRowProps, {}, "selected">;
61
+ type SelectableRow = ReturnType<typeof SelectableRow>;
62
+ export default SelectableRow;
63
+ //# sourceMappingURL=SelectableRow.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectableRow.svelte.d.ts","sourceRoot":"","sources":["../src/lib/SelectableRow.svelte.ts"],"names":[],"mappings":"AAGE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,eAA+B,CAAC;AAEhE,MAAM,MAAM,qBAAqB,GAAG;IAClC,gEAAgE;IAChE,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC;IACvB,wDAAwD;IACxD,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,8DAA8D;IAC9D,QAAQ,EAAE,CAAC,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,KAAK,MAAM,IAAI,CAAC;IACrE,uDAAuD;IACvD,UAAU,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,OAAO,CAAC;IACzC,iFAAiF;IACjF,SAAS,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,OAAO,CAAC;IACxC,6EAA6E;IAC7E,QAAQ,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,IAAI,CAAC;IACpC,wDAAwD;IACxD,QAAQ,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,IAAI,CAAC;IACpC,gDAAgD;IAChD,QAAQ,EAAE,CAAC,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAClD,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,iCAAiC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,+EAA+E;IAC/E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oCAAoC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,mCAAmC;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,oBAAoB;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAoHJ,QAAA,MAAM,aAAa,gEAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
package/dist/index.d.ts CHANGED
@@ -81,6 +81,8 @@ export { default as Row } from "./Row.svelte";
81
81
  export { default as ScatterPlot } from "./ScatterPlot.svelte";
82
82
  export { default as Search } from "./Search.svelte";
83
83
  export { default as Select } from "./Select.svelte";
84
+ export { default as SelectableRow } from "./SelectableRow.svelte";
85
+ export { default as SelectableList } from "./SelectableList.svelte";
84
86
  export { default as SideNav } from "./SideNav.svelte";
85
87
  export { default as SkeletonText } from "./SkeletonText.svelte";
86
88
  export { default as SkipLink } from "./SkipLink.svelte";
@@ -138,6 +140,8 @@ export type { MultiSelectOption } from "./MultiSelect.svelte";
138
140
  export type { OverflowMenuItem } from "./OverflowMenu.svelte";
139
141
  export type { ProgressIndicatorItem, ProgressIndicatorStatus } from "./ProgressIndicator.svelte";
140
142
  export type { SideNavItem } from "./SideNav.svelte";
143
+ export type { SelectableRowProps } from "./SelectableRow.svelte";
144
+ export type { SelectableListProps } from "./SelectableList.svelte";
141
145
  export type { StructuredListItem } from "./StructuredList.svelte";
142
146
  export type { DisplayFontScale, DisplayContrast, DisplayLineSpacing, DisplaySettingsState } from "./DisplaySettings.svelte";
143
147
  export type { TranscriptionSegment } from "./Transcription.svelte";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/lib/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/lib/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -81,6 +81,8 @@ export { default as Row } from "./Row.svelte";
81
81
  export { default as ScatterPlot } from "./ScatterPlot.svelte";
82
82
  export { default as Search } from "./Search.svelte";
83
83
  export { default as Select } from "./Select.svelte";
84
+ export { default as SelectableRow } from "./SelectableRow.svelte";
85
+ export { default as SelectableList } from "./SelectableList.svelte";
84
86
  export { default as SideNav } from "./SideNav.svelte";
85
87
  export { default as SkeletonText } from "./SkeletonText.svelte";
86
88
  export { default as SkipLink } from "./SkipLink.svelte";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentropic/design-system-svelte",
3
- "version": "0.15.0",
3
+ "version": "0.16.0",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"