@weasel-js/forge 1.6.1 → 1.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -2
- package/dist/{FrameController-BspC9Zr5.d.ts → FrameController-RdGggdGA.d.ts} +34 -1
- package/dist/chunk-JNJGIUYU.js +77 -0
- package/dist/chunk-JNJGIUYU.js.map +1 -0
- package/dist/{chunk-CSAXZIMV.js → chunk-KIFCYY4F.js} +98 -11
- package/dist/chunk-KIFCYY4F.js.map +1 -0
- package/dist/{chunk-OLWZURU3.js → chunk-NYBMOSSR.js} +11 -12
- package/dist/chunk-NYBMOSSR.js.map +1 -0
- package/dist/{chunk-DIOLWCH7.js → chunk-SEK6EKHO.js} +38 -94
- package/dist/chunk-SEK6EKHO.js.map +1 -0
- package/dist/chunk-WEQSLPKT.js +9 -0
- package/dist/chunk-WEQSLPKT.js.map +1 -0
- package/dist/{chunk-2GXKNXTJ.js → chunk-Y3WZ2EWR.js} +2 -2
- package/dist/chunk-Y3WZ2EWR.js.map +1 -0
- package/dist/{chunk-JXIWZFD4.js → chunk-YKN3IAEX.js} +12 -10
- package/dist/chunk-YKN3IAEX.js.map +1 -0
- package/dist/{config-C5Vq5Kjj.d.ts → config-BJIgUhiI.d.ts} +16 -3
- package/dist/csf/preview-api.js +1 -1
- package/dist/frame/index.css +63 -7
- package/dist/frame/index.css.map +1 -1
- package/dist/frame/index.d.ts +7 -2
- package/dist/frame/index.js +11 -4
- package/dist/frame/index.js.map +1 -1
- package/dist/index.d.ts +14 -4
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/shell/index.css +165 -3
- package/dist/shell/index.css.map +1 -1
- package/dist/shell/index.d.ts +44 -31
- package/dist/shell/index.js +178 -202
- package/dist/shell/index.js.map +1 -1
- package/dist/test/index.d.ts +2 -1
- package/dist/test/index.js +5 -4
- package/dist/test/index.js.map +1 -1
- package/dist/vite/index.d.ts +7 -1
- package/dist/vite/index.js +367 -32
- package/dist/vite/index.js.map +1 -1
- package/package.json +10 -10
- package/dist/chunk-2GXKNXTJ.js.map +0 -1
- package/dist/chunk-CSAXZIMV.js.map +0 -1
- package/dist/chunk-DIOLWCH7.js.map +0 -1
- package/dist/chunk-JXIWZFD4.js.map +0 -1
- package/dist/chunk-OLWZURU3.js.map +0 -1
package/dist/shell/index.js
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
|
-
import { isIndexId, indexId, indexEntries, schemaFromDescription, openChannel, IndexPage } from '../chunk-
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import '../chunk-
|
|
1
|
+
import { isIndexId, indexId, libraryOf, indexEntries, schemaFromDescription, LibraryBadge, openChannel, IndexPage } from '../chunk-KIFCYY4F.js';
|
|
2
|
+
import { isGallery } from '../chunk-WEQSLPKT.js';
|
|
3
|
+
import { useTrialFrame, createTrialFrames, StoryGlobalsContext, TrialFramesContext, StoryTrial, useCssOverrides, TrialHost } from '../chunk-SEK6EKHO.js';
|
|
4
|
+
export { StoryGlobalsContext, StoryTrial, TrialFramesContext, TrialHost, useTrialFrame } from '../chunk-SEK6EKHO.js';
|
|
5
|
+
import { labGlobals, withGlobals, followApp, storyConfig, GLOBALS_KEY, effectiveGlobals, labOptions, isGlobalsPath } from '../chunk-JNJGIUYU.js';
|
|
6
|
+
import { loadStories, indexRenderOf } from '../chunk-NYBMOSSR.js';
|
|
7
|
+
import '../chunk-Y3WZ2EWR.js';
|
|
6
8
|
import '../chunk-HRGPFQBW.js';
|
|
7
|
-
import { stableStringify, PORT_HANDOFF, FRAME_HELLO, PROTOCOL_VERSION } from '../chunk-
|
|
9
|
+
import { stableStringify, PORT_HANDOFF, FRAME_HELLO, PROTOCOL_VERSION } from '../chunk-YKN3IAEX.js';
|
|
8
10
|
import { useTrialId, Button, Lab, useLabContext, TrialIdContext, usePersistedState, Select, inferTokenType, ToggleBar as ToggleBar$1, Input, TokenPanel, refitScale } from '@weasel-js/labkit';
|
|
9
11
|
import { createContext, useState, useRef, useEffect, useCallback, useMemo, useLayoutEffect, useId, useContext } from 'react';
|
|
10
12
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
11
13
|
import { createRoot } from 'react-dom/client';
|
|
12
|
-
import { InfoIcon, ToggleBar, Checkbox, Dialog,
|
|
14
|
+
import { InfoIcon, ToggleBar, Checkbox, Dialog, DisclosureMark, Button as Button$1, TuneIcon, Callout } from '@weasel-js/ui';
|
|
13
15
|
import { TOKEN_MANIFEST, THEME_SOURCES, isByAxis } from '@weasel-js/theme';
|
|
14
16
|
import { scale, httpThemeApi } from '@weasel-js/theme/engine';
|
|
15
17
|
import { f, valueAtPath, isConfigBranch } from '@weasel-js/labkit/config';
|
|
18
|
+
import { useLatest } from '@weasel-js/core';
|
|
16
19
|
|
|
17
20
|
function Finding({ finding }) {
|
|
18
21
|
return /* @__PURE__ */ jsxs("li", { className: "fg-a11y__finding", children: [
|
|
@@ -105,6 +108,7 @@ function createStoryChanges() {
|
|
|
105
108
|
}
|
|
106
109
|
};
|
|
107
110
|
}
|
|
111
|
+
var DependenciesContext = createContext(null);
|
|
108
112
|
var SEED_REF = /^\{seeds\.([^}]+)\}$/;
|
|
109
113
|
var RULE_KEYS = { factors: "factors", ratio: "ratio", step: "step" };
|
|
110
114
|
function selectionFor(axes, globals) {
|
|
@@ -445,113 +449,6 @@ function breadcrumb(title, name) {
|
|
|
445
449
|
const segments = [...title.split("/"), name].filter((segment, i) => i === 0 || segment.toLowerCase() !== "index");
|
|
446
450
|
return segments.join(" > ");
|
|
447
451
|
}
|
|
448
|
-
|
|
449
|
-
// src/shell/tree/buildComponents.ts
|
|
450
|
-
var LIBRARIES = [
|
|
451
|
-
["/packages/ui/", "ui"],
|
|
452
|
-
["/packages/labkit/", "labkit"],
|
|
453
|
-
["/packages/forge/", "forge"],
|
|
454
|
-
["/apps/draw/", "draw"],
|
|
455
|
-
["/apps/forge/", "forge"]
|
|
456
|
-
];
|
|
457
|
-
function libraryOf(entry) {
|
|
458
|
-
const file = entry.file.replaceAll("\\", "/");
|
|
459
|
-
for (const [marker, label] of LIBRARIES) {
|
|
460
|
-
if (file.includes(marker)) return label;
|
|
461
|
-
}
|
|
462
|
-
return entry.title.split("/")[0];
|
|
463
|
-
}
|
|
464
|
-
function buildComponents(index) {
|
|
465
|
-
const byTitle = /* @__PURE__ */ new Map();
|
|
466
|
-
for (const entry of index) {
|
|
467
|
-
let row = byTitle.get(entry.title);
|
|
468
|
-
if (!row) {
|
|
469
|
-
const segments = entry.title.split("/");
|
|
470
|
-
row = {
|
|
471
|
-
path: entry.title,
|
|
472
|
-
label: segments[segments.length - 1],
|
|
473
|
-
library: libraryOf(entry),
|
|
474
|
-
index: indexEntries([entry])[0],
|
|
475
|
-
entries: []
|
|
476
|
-
};
|
|
477
|
-
byTitle.set(entry.title, row);
|
|
478
|
-
}
|
|
479
|
-
row.entries.push(entry);
|
|
480
|
-
}
|
|
481
|
-
const rows = [...byTitle.values()];
|
|
482
|
-
disambiguate(rows);
|
|
483
|
-
return rows.sort(
|
|
484
|
-
(a, b) => a.label.localeCompare(b.label) || a.library.localeCompare(b.library) || a.path.localeCompare(b.path)
|
|
485
|
-
);
|
|
486
|
-
}
|
|
487
|
-
function disambiguate(rows) {
|
|
488
|
-
const byLabel = /* @__PURE__ */ new Map();
|
|
489
|
-
for (const row of rows) {
|
|
490
|
-
const key = `${row.library}\0${row.label}`;
|
|
491
|
-
const group = byLabel.get(key);
|
|
492
|
-
if (group) group.push(row);
|
|
493
|
-
else byLabel.set(key, [row]);
|
|
494
|
-
}
|
|
495
|
-
for (const group of byLabel.values()) {
|
|
496
|
-
if (group.length < 2) continue;
|
|
497
|
-
for (const row of group) {
|
|
498
|
-
const segments = row.path.split("/");
|
|
499
|
-
for (let take = 2; take <= segments.length; take++) {
|
|
500
|
-
row.label = segments.slice(-take).join("/");
|
|
501
|
-
if (group.every((other) => other === row || !other.path.endsWith(`/${row.label}`))) break;
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
function filterComponents(rows, query) {
|
|
507
|
-
const needle = query.trim().toLowerCase();
|
|
508
|
-
if (!needle) return [...rows];
|
|
509
|
-
const out = [];
|
|
510
|
-
for (const row of rows) {
|
|
511
|
-
if (`${row.path}/${row.library}`.toLowerCase().includes(needle)) {
|
|
512
|
-
out.push(row);
|
|
513
|
-
continue;
|
|
514
|
-
}
|
|
515
|
-
const entries = row.entries.filter((entry) => entry.name.toLowerCase().includes(needle));
|
|
516
|
-
if (entries.length > 0) out.push({ path: row.path, label: row.label, library: row.library, entries });
|
|
517
|
-
}
|
|
518
|
-
return out;
|
|
519
|
-
}
|
|
520
|
-
function componentNodes(rows) {
|
|
521
|
-
const root = [];
|
|
522
|
-
const folders = /* @__PURE__ */ new Map();
|
|
523
|
-
for (const row of rows) {
|
|
524
|
-
const labels = row.label.split("/");
|
|
525
|
-
const title = row.path.split("/");
|
|
526
|
-
let siblings = root;
|
|
527
|
-
let tag = row.library;
|
|
528
|
-
for (let i = 0; i < labels.length - 1; i++) {
|
|
529
|
-
const path = title.slice(0, title.length - labels.length + i + 1).join("/");
|
|
530
|
-
let folder = folders.get(path);
|
|
531
|
-
if (!folder) {
|
|
532
|
-
folder = { kind: "folder", label: labels[i], path, tag, children: [] };
|
|
533
|
-
folders.set(path, folder);
|
|
534
|
-
siblings.push(folder);
|
|
535
|
-
}
|
|
536
|
-
siblings = folder.children;
|
|
537
|
-
tag = void 0;
|
|
538
|
-
}
|
|
539
|
-
siblings.push({
|
|
540
|
-
kind: "folder",
|
|
541
|
-
label: labels[labels.length - 1],
|
|
542
|
-
path: row.path,
|
|
543
|
-
tag,
|
|
544
|
-
...row.index ? { index: row.index } : {},
|
|
545
|
-
children: row.entries.map((entry) => ({ kind: "story", entry }))
|
|
546
|
-
});
|
|
547
|
-
}
|
|
548
|
-
return root;
|
|
549
|
-
}
|
|
550
|
-
function librariesIn(index) {
|
|
551
|
-
return [...new Set(index.map(libraryOf))].sort((a, b) => a.localeCompare(b));
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
// src/shell/info/dossier.ts
|
|
555
452
|
var GLOBALS = "$globals";
|
|
556
453
|
function leaves(shape, prefix = "") {
|
|
557
454
|
const out = [];
|
|
@@ -745,20 +642,21 @@ function GlobalSelect({ name, declaration, values, set, labeled = false }) {
|
|
|
745
642
|
width: labeled ? "fill" : "fit",
|
|
746
643
|
selectedKey: String(values[name]),
|
|
747
644
|
onSelectionChange: (value) => set(name, value),
|
|
748
|
-
options:
|
|
645
|
+
options: labOptions(declaration, values)
|
|
749
646
|
}
|
|
750
647
|
);
|
|
751
648
|
}
|
|
752
649
|
function GlobalsToolbar({ declarations }) {
|
|
753
650
|
const [values, set] = useLabGlobals(declarations);
|
|
754
651
|
const entries = Object.entries(declarations);
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
nested
|
|
760
|
-
|
|
761
|
-
|
|
652
|
+
const top = entries.filter(([, declaration]) => declaration.under === void 0);
|
|
653
|
+
return /* @__PURE__ */ jsxs("div", { className: "fg-globals", role: "toolbar", "aria-label": "Globals", children: [
|
|
654
|
+
top.map(([key, declaration]) => /* @__PURE__ */ jsx("div", { className: "fg-globals__item", children: /* @__PURE__ */ jsx(GlobalSelect, { name: key, declaration, values, set }) }, key)),
|
|
655
|
+
top.map(([key, declaration]) => {
|
|
656
|
+
const nested = entries.filter(([, other]) => other.under === key);
|
|
657
|
+
return nested.length > 0 ? /* @__PURE__ */ jsx(NestedGlobals, { label: declaration.label, nested, values, set }, key) : null;
|
|
658
|
+
})
|
|
659
|
+
] });
|
|
762
660
|
}
|
|
763
661
|
function NestedGlobals({
|
|
764
662
|
label,
|
|
@@ -802,7 +700,9 @@ function LabGlobals({
|
|
|
802
700
|
onChange
|
|
803
701
|
}) {
|
|
804
702
|
const [values] = useLabGlobals(declarations);
|
|
805
|
-
|
|
703
|
+
const { mode } = useLabContext();
|
|
704
|
+
const resolved = useMemo(() => followApp(declarations, values, { mode }), [declarations, values, mode]);
|
|
705
|
+
useEffect(() => onChange(resolved), [resolved, onChange]);
|
|
806
706
|
return null;
|
|
807
707
|
}
|
|
808
708
|
|
|
@@ -872,6 +772,17 @@ function sortFolder(nodes) {
|
|
|
872
772
|
for (const folder of folders) folder.children = sortFolder(folder.children);
|
|
873
773
|
return [...folders, ...nodes.filter((n) => n.kind === "story")];
|
|
874
774
|
}
|
|
775
|
+
function foldGalleries(nodes) {
|
|
776
|
+
return nodes.map((node) => {
|
|
777
|
+
if (node.kind !== "folder") return node;
|
|
778
|
+
const children = foldGalleries(node.children);
|
|
779
|
+
const [only] = children;
|
|
780
|
+
if (!node.index && children.length === 1 && only?.kind === "folder" && only.path === `${node.path}/${only.label}` && only.index && isGallery(only.index)) {
|
|
781
|
+
return { ...only, label: node.label, tag: node.tag ?? only.tag };
|
|
782
|
+
}
|
|
783
|
+
return { ...node, children };
|
|
784
|
+
});
|
|
785
|
+
}
|
|
875
786
|
function buildTree(index) {
|
|
876
787
|
const root = [];
|
|
877
788
|
const folders = /* @__PURE__ */ new Map();
|
|
@@ -908,9 +819,102 @@ function filterTree(nodes, query) {
|
|
|
908
819
|
});
|
|
909
820
|
return walk(nodes);
|
|
910
821
|
}
|
|
822
|
+
|
|
823
|
+
// src/shell/tree/buildComponents.ts
|
|
824
|
+
function buildComponents(index) {
|
|
825
|
+
const byTitle = /* @__PURE__ */ new Map();
|
|
826
|
+
const pages = new Map(indexEntries(index).map((page) => [page.title, page]));
|
|
827
|
+
for (const entry of index) {
|
|
828
|
+
let row = byTitle.get(entry.title);
|
|
829
|
+
if (!row) {
|
|
830
|
+
const segments = entry.title.split("/");
|
|
831
|
+
row = {
|
|
832
|
+
path: entry.title,
|
|
833
|
+
label: segments[segments.length - 1],
|
|
834
|
+
library: libraryOf(entry),
|
|
835
|
+
index: pages.get(entry.title),
|
|
836
|
+
entries: []
|
|
837
|
+
};
|
|
838
|
+
byTitle.set(entry.title, row);
|
|
839
|
+
}
|
|
840
|
+
row.entries.push(entry);
|
|
841
|
+
}
|
|
842
|
+
const rows = [...byTitle.values()];
|
|
843
|
+
disambiguate(rows);
|
|
844
|
+
return rows.sort(
|
|
845
|
+
(a, b) => a.label.localeCompare(b.label) || a.library.localeCompare(b.library) || a.path.localeCompare(b.path)
|
|
846
|
+
);
|
|
847
|
+
}
|
|
848
|
+
function disambiguate(rows) {
|
|
849
|
+
const byLabel = /* @__PURE__ */ new Map();
|
|
850
|
+
for (const row of rows) {
|
|
851
|
+
const key = `${row.library}\0${row.label}`;
|
|
852
|
+
const group = byLabel.get(key);
|
|
853
|
+
if (group) group.push(row);
|
|
854
|
+
else byLabel.set(key, [row]);
|
|
855
|
+
}
|
|
856
|
+
for (const group of byLabel.values()) {
|
|
857
|
+
if (group.length < 2) continue;
|
|
858
|
+
for (const row of group) {
|
|
859
|
+
const segments = row.path.split("/");
|
|
860
|
+
for (let take = 2; take <= segments.length; take++) {
|
|
861
|
+
row.label = segments.slice(-take).join("/");
|
|
862
|
+
if (group.every((other) => other === row || !other.path.endsWith(`/${row.label}`))) break;
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
function filterComponents(rows, query) {
|
|
868
|
+
const needle = query.trim().toLowerCase();
|
|
869
|
+
if (!needle) return [...rows];
|
|
870
|
+
const out = [];
|
|
871
|
+
for (const row of rows) {
|
|
872
|
+
if (`${row.path}/${row.library}`.toLowerCase().includes(needle)) {
|
|
873
|
+
out.push(row);
|
|
874
|
+
continue;
|
|
875
|
+
}
|
|
876
|
+
const entries = row.entries.filter((entry) => entry.name.toLowerCase().includes(needle));
|
|
877
|
+
if (entries.length > 0) out.push({ path: row.path, label: row.label, library: row.library, entries });
|
|
878
|
+
}
|
|
879
|
+
return out;
|
|
880
|
+
}
|
|
881
|
+
function componentNodes(rows) {
|
|
882
|
+
const root = [];
|
|
883
|
+
const folders = /* @__PURE__ */ new Map();
|
|
884
|
+
for (const row of rows) {
|
|
885
|
+
const labels = row.label.split("/");
|
|
886
|
+
const title = row.path.split("/");
|
|
887
|
+
let siblings = root;
|
|
888
|
+
let tag = row.library;
|
|
889
|
+
for (let i = 0; i < labels.length - 1; i++) {
|
|
890
|
+
const path = title.slice(0, title.length - labels.length + i + 1).join("/");
|
|
891
|
+
let folder = folders.get(path);
|
|
892
|
+
if (!folder) {
|
|
893
|
+
folder = { kind: "folder", label: labels[i], path, tag, children: [] };
|
|
894
|
+
folders.set(path, folder);
|
|
895
|
+
siblings.push(folder);
|
|
896
|
+
}
|
|
897
|
+
siblings = folder.children;
|
|
898
|
+
tag = void 0;
|
|
899
|
+
}
|
|
900
|
+
siblings.push({
|
|
901
|
+
kind: "folder",
|
|
902
|
+
label: labels[labels.length - 1],
|
|
903
|
+
path: row.path,
|
|
904
|
+
tag,
|
|
905
|
+
...row.index ? { index: row.index } : {},
|
|
906
|
+
children: row.entries.map((entry) => ({ kind: "story", entry }))
|
|
907
|
+
});
|
|
908
|
+
}
|
|
909
|
+
return foldGalleries(root);
|
|
910
|
+
}
|
|
911
|
+
function librariesIn(index) {
|
|
912
|
+
return [...new Set(index.map(libraryOf))].sort((a, b) => a.localeCompare(b));
|
|
913
|
+
}
|
|
911
914
|
var VIEWS = [
|
|
912
915
|
{ value: "tree", label: "Tree" },
|
|
913
|
-
{ value: "components", label: "Components" }
|
|
916
|
+
{ value: "components", label: "Components" },
|
|
917
|
+
{ value: "gallery", label: "Gallery" }
|
|
914
918
|
];
|
|
915
919
|
var keyOf = (node) => node.kind === "folder" ? `folder:${node.path}` : `story:${node.entry.id}`;
|
|
916
920
|
function ancestorsOf(entry) {
|
|
@@ -923,14 +927,8 @@ function ancestorsOf(entry) {
|
|
|
923
927
|
}
|
|
924
928
|
return paths;
|
|
925
929
|
}
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
labkit: "color-mix(in oklab, var(--wzl-swatch-teal), var(--wzl-fg) 45%)",
|
|
929
|
-
forge: "color-mix(in oklab, var(--wzl-swatch-amber), var(--wzl-fg) 40%)",
|
|
930
|
-
draw: "color-mix(in oklab, var(--wzl-swatch-rose), var(--wzl-fg) 35%)"
|
|
931
|
-
};
|
|
932
|
-
function LibraryBadge({ library }) {
|
|
933
|
-
return /* @__PURE__ */ jsx(Badge, { status: "muted", tone: LIBRARY_TONES[library], variant: "subtle", size: "sm", className: "fg-tree__tag", children: library });
|
|
930
|
+
function LibraryBadge2({ library }) {
|
|
931
|
+
return /* @__PURE__ */ jsx(LibraryBadge, { library, className: "fg-tree__tag" });
|
|
934
932
|
}
|
|
935
933
|
function StoryTree({ ctx, index }) {
|
|
936
934
|
const headingId = useId();
|
|
@@ -943,11 +941,18 @@ function StoryTree({ ctx, index }) {
|
|
|
943
941
|
const items = useRef(/* @__PURE__ */ new Map());
|
|
944
942
|
const libraries = useMemo(() => librariesIn(index), [index]);
|
|
945
943
|
const kept = useMemo(() => index.filter((entry) => !hidden[libraryOf(entry)]), [index, hidden]);
|
|
946
|
-
const
|
|
947
|
-
|
|
944
|
+
const [galleryEntries, rest] = useMemo(() => {
|
|
945
|
+
const yes = [];
|
|
946
|
+
const no = [];
|
|
947
|
+
for (const entry of kept) (isGallery(entry) ? yes : no).push(entry);
|
|
948
|
+
return [yes, no];
|
|
949
|
+
}, [kept]);
|
|
950
|
+
const tree = useMemo(() => buildTree(rest), [rest]);
|
|
951
|
+
const components = useMemo(() => buildComponents(rest), [rest]);
|
|
952
|
+
const galleries = useMemo(() => buildComponents(galleryEntries), [galleryEntries]);
|
|
948
953
|
const shown = useMemo(
|
|
949
|
-
() => view === "
|
|
950
|
-
[view, components, tree, query]
|
|
954
|
+
() => view === "tree" ? filterTree(tree, query) : componentNodes(filterComponents(view === "gallery" ? galleries : components, query)),
|
|
955
|
+
[view, components, galleries, tree, query]
|
|
951
956
|
);
|
|
952
957
|
const routable = useMemo(() => [...kept, ...indexEntries(kept)], [kept]);
|
|
953
958
|
const routed = routable.find((entry) => entry.id === route);
|
|
@@ -989,7 +994,7 @@ function StoryTree({ ctx, index }) {
|
|
|
989
994
|
return;
|
|
990
995
|
}
|
|
991
996
|
if (folds[node.path] === false) {
|
|
992
|
-
setFolds(({ [node.path]: _dropped, ...
|
|
997
|
+
setFolds(({ [node.path]: _dropped, ...rest2 }) => rest2);
|
|
993
998
|
}
|
|
994
999
|
activate(node.index, another);
|
|
995
1000
|
};
|
|
@@ -1080,7 +1085,7 @@ function StoryTree({ ctx, index }) {
|
|
|
1080
1085
|
}
|
|
1081
1086
|
),
|
|
1082
1087
|
/* @__PURE__ */ jsx("span", { className: "fg-tree__label", children: node.label }),
|
|
1083
|
-
node.tag ? /* @__PURE__ */ jsx(
|
|
1088
|
+
node.tag ? /* @__PURE__ */ jsx(LibraryBadge2, { library: node.tag }) : null
|
|
1084
1089
|
]
|
|
1085
1090
|
}
|
|
1086
1091
|
),
|
|
@@ -1106,7 +1111,7 @@ function StoryTree({ ctx, index }) {
|
|
|
1106
1111
|
},
|
|
1107
1112
|
children: [
|
|
1108
1113
|
/* @__PURE__ */ jsx("span", { className: "fg-tree__label", children: node.label ?? entry.name }),
|
|
1109
|
-
node.tag ? /* @__PURE__ */ jsx(
|
|
1114
|
+
node.tag ? /* @__PURE__ */ jsx(LibraryBadge2, { library: node.tag }) : null
|
|
1110
1115
|
]
|
|
1111
1116
|
},
|
|
1112
1117
|
keyOf(node)
|
|
@@ -1137,7 +1142,7 @@ function StoryTree({ ctx, index }) {
|
|
|
1137
1142
|
{
|
|
1138
1143
|
isSelected: !hidden[library],
|
|
1139
1144
|
onChange: (on) => setHidden((prev) => ({ ...prev, [library]: !on })),
|
|
1140
|
-
children: /* @__PURE__ */ jsx(
|
|
1145
|
+
children: /* @__PURE__ */ jsx(LibraryBadge2, { library })
|
|
1141
1146
|
},
|
|
1142
1147
|
library
|
|
1143
1148
|
))
|
|
@@ -1202,6 +1207,9 @@ function createAnswerBook() {
|
|
|
1202
1207
|
function IndexTrial({ bundle, setup, config }) {
|
|
1203
1208
|
const lab = useLabContext();
|
|
1204
1209
|
const trialId = useContext(TrialIdContext);
|
|
1210
|
+
const graph = useContext(DependenciesContext);
|
|
1211
|
+
const gallery = isGallery(bundle);
|
|
1212
|
+
const dependencies = gallery ? void 0 : graph?.[bundle.title];
|
|
1205
1213
|
const open = (id) => {
|
|
1206
1214
|
if (!trialId || !lab.instruments.some((instrument) => instrument.name === id)) return;
|
|
1207
1215
|
lab.swapTrial(trialId, id);
|
|
@@ -1210,9 +1218,13 @@ function IndexTrial({ bundle, setup, config }) {
|
|
|
1210
1218
|
const render = (globals) => {
|
|
1211
1219
|
const env = {
|
|
1212
1220
|
title: bundle.title,
|
|
1221
|
+
library: bundle.library,
|
|
1213
1222
|
...bundle.description === void 0 ? {} : { description: bundle.description },
|
|
1214
1223
|
stories: bundle.stories,
|
|
1215
1224
|
descriptions: bundle.descriptions,
|
|
1225
|
+
gallery,
|
|
1226
|
+
galleries: bundle.galleries,
|
|
1227
|
+
...dependencies ? { dependencies } : {},
|
|
1216
1228
|
globals,
|
|
1217
1229
|
decorators: setup.decorators ?? [],
|
|
1218
1230
|
open,
|
|
@@ -1223,26 +1235,8 @@ function IndexTrial({ bundle, setup, config }) {
|
|
|
1223
1235
|
};
|
|
1224
1236
|
return /* @__PURE__ */ jsx(TrialHost, { layout: "fullscreen", setup, config, children: render });
|
|
1225
1237
|
}
|
|
1226
|
-
function annotationsOn(frames) {
|
|
1227
|
-
return {
|
|
1228
|
-
targets: (_state, _config, trial) => {
|
|
1229
|
-
const ref = frames.hostRef(trial.id);
|
|
1230
|
-
const frame = frames.get(trial.id);
|
|
1231
|
-
const box = frame.size ?? { width: ref.current?.clientWidth ?? 0, height: ref.current?.clientHeight ?? 0 };
|
|
1232
|
-
const capture = frame.capture;
|
|
1233
|
-
return [
|
|
1234
|
-
{
|
|
1235
|
-
id: "story",
|
|
1236
|
-
ref,
|
|
1237
|
-
content: { w: Math.max(1, box.width), h: Math.max(1, box.height) },
|
|
1238
|
-
...capture ? { base: () => capture() } : {}
|
|
1239
|
-
}
|
|
1240
|
-
];
|
|
1241
|
-
}
|
|
1242
|
-
};
|
|
1243
|
-
}
|
|
1244
1238
|
function documentInstrument(options) {
|
|
1245
|
-
const { entry, loaded, setup, globals = {}
|
|
1239
|
+
const { entry, loaded, setup, globals = {} } = options;
|
|
1246
1240
|
const schema = loaded.kind === "story" ? loaded.story.config : f.schema({});
|
|
1247
1241
|
const config = withGlobals(schema, globals);
|
|
1248
1242
|
const initialState = loaded.kind === "story" ? loaded.story.initialState : null;
|
|
@@ -1253,7 +1247,6 @@ function documentInstrument(options) {
|
|
|
1253
1247
|
defaultConfig: () => config.defaults(),
|
|
1254
1248
|
initialState: (c) => initialState?.(c) ?? null,
|
|
1255
1249
|
render: (ctx) => loaded.kind === "story" ? /* @__PURE__ */ jsx(StoryTrial, { story: loaded.story, setup, ctx }) : /* @__PURE__ */ jsx(IndexTrial, { bundle: loaded.bundle, setup, config: ctx.config }),
|
|
1256
|
-
...frames ? { annotations: annotationsOn(frames) } : {},
|
|
1257
1250
|
...loaded.kind === "story" && loaded.story.viewport ? { stage: { size: { width: loaded.story.viewport.width, height: loaded.story.viewport.height } } } : {}
|
|
1258
1251
|
};
|
|
1259
1252
|
}
|
|
@@ -1335,17 +1328,16 @@ function FrameView(props) {
|
|
|
1335
1328
|
const slotRef = useRef(null);
|
|
1336
1329
|
const inView = useInView(hostRef);
|
|
1337
1330
|
const link = useRef(null);
|
|
1338
|
-
const latest =
|
|
1339
|
-
latest.current = { ...props, globals, overrides, pool, lab, title };
|
|
1331
|
+
const latest = useLatest({ ...props, globals, overrides, pool, lab, title });
|
|
1340
1332
|
const [fault, setFault] = useState(null);
|
|
1341
1333
|
const [pending, setPending] = useState(true);
|
|
1342
|
-
const init = (current) => {
|
|
1334
|
+
const init = useCallback((current) => {
|
|
1343
1335
|
const { ctx: live, globals: liveGlobals } = latest.current;
|
|
1344
1336
|
current.awaiting = null;
|
|
1345
1337
|
current.sent = { config: storyConfig(live.config), state: live.state, globals: liveGlobals };
|
|
1346
1338
|
current.inputs += 1;
|
|
1347
1339
|
current.channel.send({ type: "init", ...current.sent });
|
|
1348
|
-
};
|
|
1340
|
+
}, [latest]);
|
|
1349
1341
|
const receive = (current, msg) => {
|
|
1350
1342
|
const { ctx: live, answers: answers2, onReady } = latest.current;
|
|
1351
1343
|
switch (msg.type) {
|
|
@@ -1466,8 +1458,7 @@ function FrameView(props) {
|
|
|
1466
1458
|
port2
|
|
1467
1459
|
]);
|
|
1468
1460
|
};
|
|
1469
|
-
const connectRef =
|
|
1470
|
-
connectRef.current = connect;
|
|
1461
|
+
const connectRef = useLatest(connect);
|
|
1471
1462
|
useEffect(() => {
|
|
1472
1463
|
const slot = slotRef.current;
|
|
1473
1464
|
if (!inView || !slot) return;
|
|
@@ -1502,7 +1493,7 @@ function FrameView(props) {
|
|
|
1502
1493
|
setPending(true);
|
|
1503
1494
|
setFault(null);
|
|
1504
1495
|
};
|
|
1505
|
-
}, [inView, src]);
|
|
1496
|
+
}, [inView, src, connectRef, latest]);
|
|
1506
1497
|
useEffect(() => {
|
|
1507
1498
|
iframeRef.current?.toggleAttribute("data-pending", pending && !fault);
|
|
1508
1499
|
}, [pending, fault, inView, src]);
|
|
@@ -1540,7 +1531,7 @@ function FrameView(props) {
|
|
|
1540
1531
|
input = true;
|
|
1541
1532
|
}
|
|
1542
1533
|
if (input) setFault((shown) => shown?.phase === "render" ? null : shown);
|
|
1543
|
-
}, [ctx.config, ctx.state, globals, descriptionKey]);
|
|
1534
|
+
}, [ctx.config, ctx.state, globals, descriptionKey, init]);
|
|
1544
1535
|
return /* @__PURE__ */ jsxs(
|
|
1545
1536
|
"div",
|
|
1546
1537
|
{
|
|
@@ -1559,26 +1550,8 @@ function FrameView(props) {
|
|
|
1559
1550
|
}
|
|
1560
1551
|
);
|
|
1561
1552
|
}
|
|
1562
|
-
function annotationsOn2(frames) {
|
|
1563
|
-
return {
|
|
1564
|
-
targets: (_state, _config, trial) => {
|
|
1565
|
-
const ref = frames.hostRef(trial.id);
|
|
1566
|
-
const frame = frames.get(trial.id);
|
|
1567
|
-
const box = frame.size ?? { width: ref.current?.clientWidth ?? 0, height: ref.current?.clientHeight ?? 0 };
|
|
1568
|
-
const capture = frame.capture;
|
|
1569
|
-
return [
|
|
1570
|
-
{
|
|
1571
|
-
id: "story",
|
|
1572
|
-
ref,
|
|
1573
|
-
content: { w: Math.max(1, box.width), h: Math.max(1, box.height) },
|
|
1574
|
-
...capture ? { base: () => capture() } : {}
|
|
1575
|
-
}
|
|
1576
|
-
];
|
|
1577
|
-
}
|
|
1578
|
-
};
|
|
1579
|
-
}
|
|
1580
1553
|
function storyInstrument(options) {
|
|
1581
|
-
const { entry, ready, answers, frameUrl, onReady, globals = {}
|
|
1554
|
+
const { entry, ready, answers, frameUrl, onReady, globals = {} } = options;
|
|
1582
1555
|
const config = withGlobals(
|
|
1583
1556
|
ready ? schemaFromDescription(ready.schema, answers) : f.schema({}),
|
|
1584
1557
|
globals
|
|
@@ -1601,7 +1574,6 @@ function storyInstrument(options) {
|
|
|
1601
1574
|
ctx
|
|
1602
1575
|
}
|
|
1603
1576
|
),
|
|
1604
|
-
...frames ? { annotations: annotationsOn2(frames) } : {},
|
|
1605
1577
|
...ready?.viewport ? { stage: { size: { width: ready.viewport.width, height: ready.viewport.height } } } : {}
|
|
1606
1578
|
};
|
|
1607
1579
|
}
|
|
@@ -1612,7 +1584,7 @@ var NO_SETUP = {};
|
|
|
1612
1584
|
var pruned = (map, ids) => [...map.keys()].every((id) => ids.has(id)) ? map : new Map([...map].filter(([id]) => ids.has(id)));
|
|
1613
1585
|
var toError = (error) => error instanceof Error ? error : new Error(String(error));
|
|
1614
1586
|
function useStoryRegistry(index, options) {
|
|
1615
|
-
const { frameUrl, globals = NO_GLOBALS2,
|
|
1587
|
+
const { frameUrl, globals = NO_GLOBALS2, importers, setup = NO_SETUP, load = loadStories } = options;
|
|
1616
1588
|
const [readies, setReadies] = useState(() => /* @__PURE__ */ new Map());
|
|
1617
1589
|
const [loaded, setLoaded] = useState(() => /* @__PURE__ */ new Map());
|
|
1618
1590
|
const [faults, setFaults] = useState(() => /* @__PURE__ */ new Map());
|
|
@@ -1633,8 +1605,7 @@ function useStoryRegistry(index, options) {
|
|
|
1633
1605
|
setRevisions((prev) => pruned(prev, ids));
|
|
1634
1606
|
}, [index]);
|
|
1635
1607
|
const imports = useRef(/* @__PURE__ */ new Map());
|
|
1636
|
-
const live =
|
|
1637
|
-
live.current = { index, importers, setup, load };
|
|
1608
|
+
const live = useLatest({ index, importers, setup, load });
|
|
1638
1609
|
const importOf = useCallback((file) => {
|
|
1639
1610
|
let loading = imports.current.get(file);
|
|
1640
1611
|
if (!loading) {
|
|
@@ -1643,7 +1614,7 @@ function useStoryRegistry(index, options) {
|
|
|
1643
1614
|
imports.current.set(file, loading);
|
|
1644
1615
|
}
|
|
1645
1616
|
return loading;
|
|
1646
|
-
}, []);
|
|
1617
|
+
}, [live]);
|
|
1647
1618
|
const request = useCallback(
|
|
1648
1619
|
(entry) => {
|
|
1649
1620
|
const { setup: current, load: loadModule } = live.current;
|
|
@@ -1677,7 +1648,10 @@ function useStoryRegistry(index, options) {
|
|
|
1677
1648
|
kind: "index",
|
|
1678
1649
|
bundle: {
|
|
1679
1650
|
title: entry.title,
|
|
1651
|
+
library: libraryOf(entry),
|
|
1680
1652
|
...entry.componentDescription === void 0 ? {} : { description: entry.componentDescription },
|
|
1653
|
+
...entry.tags === void 0 ? {} : { tags: entry.tags },
|
|
1654
|
+
galleries: entries.filter(isGallery).map((e) => e.id),
|
|
1681
1655
|
stories,
|
|
1682
1656
|
descriptions: Object.fromEntries(entries.flatMap((e) => e.description ? [[e.id, e.description]] : [])),
|
|
1683
1657
|
render: mods.map(indexRenderOf).find((render) => render !== null) ?? null
|
|
@@ -1702,7 +1676,7 @@ function useStoryRegistry(index, options) {
|
|
|
1702
1676
|
settle2(ids, result);
|
|
1703
1677
|
}).catch((error) => fail(ids, error));
|
|
1704
1678
|
},
|
|
1705
|
-
[importOf]
|
|
1679
|
+
[importOf, live]
|
|
1706
1680
|
);
|
|
1707
1681
|
const reload = useCallback(
|
|
1708
1682
|
(file) => {
|
|
@@ -1713,7 +1687,7 @@ function useStoryRegistry(index, options) {
|
|
|
1713
1687
|
setFaults((prev) => pruned(prev, new Set([...prev.keys()].filter((id) => !ids.has(id)))));
|
|
1714
1688
|
setGenerations((prev) => new Map(prev).set(file, (prev.get(file) ?? 0) + 1));
|
|
1715
1689
|
},
|
|
1716
|
-
[]
|
|
1690
|
+
[live]
|
|
1717
1691
|
);
|
|
1718
1692
|
const committed = useRef({ built: /* @__PURE__ */ new Map(), books: /* @__PURE__ */ new Map(), list: [] });
|
|
1719
1693
|
const cache = useMemo(() => {
|
|
@@ -1731,26 +1705,25 @@ function useStoryRegistry(index, options) {
|
|
|
1731
1705
|
const answers = previous.books.get(entry.id) ?? createAnswerBook();
|
|
1732
1706
|
books.set(entry.id, answers);
|
|
1733
1707
|
const held = previous.built.get(entry.id);
|
|
1734
|
-
const kept = held && held.entryKey === entryKey && held.ready === ready && held.loaded === had && held.fault === fault && held.frameUrl === frameUrl && held.globals === globals && held.
|
|
1708
|
+
const kept = held && held.entryKey === entryKey && held.ready === ready && held.loaded === had && held.fault === fault && held.frameUrl === frameUrl && held.globals === globals && held.setup === setup && held.inDocument === inDocument && held.generation === generation && held.revision === revision ? held : {
|
|
1735
1709
|
entryKey,
|
|
1736
1710
|
ready,
|
|
1737
1711
|
loaded: had,
|
|
1738
1712
|
fault,
|
|
1739
1713
|
frameUrl,
|
|
1740
1714
|
globals,
|
|
1741
|
-
frames,
|
|
1742
1715
|
setup,
|
|
1743
1716
|
inDocument,
|
|
1744
1717
|
generation,
|
|
1745
1718
|
revision,
|
|
1746
|
-
instrument: !inDocument ? storyInstrument({ entry, ready, answers, frameUrl, onReady, globals
|
|
1719
|
+
instrument: !inDocument ? storyInstrument({ entry, ready, answers, frameUrl, onReady, globals }) : had ? documentInstrument({ entry, loaded: had, setup, globals }) : pendingInstrument({ entry, globals, load: request, generation, ...fault ? { fault } : {} })
|
|
1747
1720
|
};
|
|
1748
1721
|
built.set(entry.id, kept);
|
|
1749
1722
|
return kept.instrument;
|
|
1750
1723
|
});
|
|
1751
1724
|
const unchanged = list.length === previous.list.length && list.every((i, n) => i === previous.list[n]);
|
|
1752
1725
|
return { built, books, list: unchanged ? previous.list : list };
|
|
1753
|
-
}, [index, readies, loaded, faults, generations, revisions, frameUrl, globals,
|
|
1726
|
+
}, [index, readies, loaded, faults, generations, revisions, frameUrl, globals, setup, importers, onReady, request]);
|
|
1754
1727
|
useLayoutEffect(() => {
|
|
1755
1728
|
committed.current = cache;
|
|
1756
1729
|
}, [cache]);
|
|
@@ -1802,7 +1775,7 @@ function useInfoShortcut(open) {
|
|
|
1802
1775
|
return () => window.removeEventListener("keydown", onKeyDown);
|
|
1803
1776
|
}, [open]);
|
|
1804
1777
|
}
|
|
1805
|
-
function Workshop({ index, frameUrl, importers, setup, changes, config, stories = [], storageKey, storage }) {
|
|
1778
|
+
function Workshop({ index, frameUrl, importers, setup, changes, config, stories = [], storageKey, storage, dependencies }) {
|
|
1806
1779
|
const declarations = config?.globals ?? NO_DECLARATIONS;
|
|
1807
1780
|
const [frames] = useState(createTrialFrames);
|
|
1808
1781
|
const [pool, setPool] = useState(null);
|
|
@@ -1820,7 +1793,6 @@ function Workshop({ index, frameUrl, importers, setup, changes, config, stories
|
|
|
1820
1793
|
const registry = useStoryRegistry(entries, {
|
|
1821
1794
|
frameUrl,
|
|
1822
1795
|
globals: declarations,
|
|
1823
|
-
frames,
|
|
1824
1796
|
...importers ? { importers } : {},
|
|
1825
1797
|
...setup ? { setup } : {}
|
|
1826
1798
|
});
|
|
@@ -1857,7 +1829,7 @@ function Workshop({ index, frameUrl, importers, setup, changes, config, stories
|
|
|
1857
1829
|
stories.length > 0 ? /* @__PURE__ */ jsx("ul", { className: "fg-empty__globs", "aria-label": "Story globs", children: stories.map((glob) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("code", { children: glob }) }, glob)) }) : null
|
|
1858
1830
|
] });
|
|
1859
1831
|
}
|
|
1860
|
-
return /* @__PURE__ */ jsx(StoryGlobalsContext.Provider, { value: labValues, children: /* @__PURE__ */ jsx(FramePoolContext.Provider, { value: pool, children: /* @__PURE__ */ jsx(TrialFramesContext.Provider, { value: frames, children: /* @__PURE__ */ jsxs(
|
|
1832
|
+
return /* @__PURE__ */ jsx(StoryGlobalsContext.Provider, { value: labValues, children: /* @__PURE__ */ jsx(DependenciesContext.Provider, { value: dependencies ?? null, children: /* @__PURE__ */ jsx(FramePoolContext.Provider, { value: pool, children: /* @__PURE__ */ jsx(TrialFramesContext.Provider, { value: frames, children: /* @__PURE__ */ jsxs(
|
|
1861
1833
|
Lab,
|
|
1862
1834
|
{
|
|
1863
1835
|
title: "weaselforge",
|
|
@@ -1886,7 +1858,7 @@ function Workshop({ index, frameUrl, importers, setup, changes, config, stories
|
|
|
1886
1858
|
/* @__PURE__ */ jsx(LabGlobals, { declarations, onChange: reportLabValues })
|
|
1887
1859
|
]
|
|
1888
1860
|
}
|
|
1889
|
-
) }) }) });
|
|
1861
|
+
) }) }) }) });
|
|
1890
1862
|
}
|
|
1891
1863
|
function mountWorkshop({ container, ...props }) {
|
|
1892
1864
|
const target = container ?? document.getElementById("root");
|
|
@@ -1905,6 +1877,10 @@ function mountWorkshop({ container, ...props }) {
|
|
|
1905
1877
|
root.render(/* @__PURE__ */ jsx(Workshop, { ...current }));
|
|
1906
1878
|
},
|
|
1907
1879
|
reloadStory: (file) => changes.emit(file),
|
|
1880
|
+
setDependencies(dependencies) {
|
|
1881
|
+
current = { ...current, dependencies };
|
|
1882
|
+
root.render(/* @__PURE__ */ jsx(Workshop, { ...current }));
|
|
1883
|
+
},
|
|
1908
1884
|
unmount: () => root.unmount()
|
|
1909
1885
|
};
|
|
1910
1886
|
}
|