@weasel-js/forge 1.10.1 → 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{FrameController-UeTY7ubF.d.ts → FrameController-BRhShqut.d.ts} +5 -0
- package/dist/{chunk-FL2MUPUL.js → chunk-2OJAV522.js} +2 -2
- package/dist/chunk-2OJAV522.js.map +1 -0
- package/dist/{chunk-DFKCLZKS.js → chunk-7BQPHMA2.js} +2 -2
- package/dist/chunk-7BQPHMA2.js.map +1 -0
- package/dist/{chunk-DKWHGSBZ.js → chunk-DPTECNYC.js} +3 -3
- package/dist/{chunk-DKWHGSBZ.js.map → chunk-DPTECNYC.js.map} +1 -1
- package/dist/{chunk-E2FHBDNQ.js → chunk-J3GYSNCK.js} +4 -4
- package/dist/{chunk-E2FHBDNQ.js.map → chunk-J3GYSNCK.js.map} +1 -1
- package/dist/{chunk-AP3DRQLI.js → chunk-NVNTQ4AT.js} +87 -9
- package/dist/chunk-NVNTQ4AT.js.map +1 -0
- package/dist/{chunk-BIAEGWGJ.js → chunk-R5F44ECM.js} +17 -7
- package/dist/chunk-R5F44ECM.js.map +1 -0
- package/dist/{chunk-GB6PRJET.js → chunk-SQ4KCIEH.js} +3 -3
- package/dist/{chunk-GB6PRJET.js.map → chunk-SQ4KCIEH.js.map} +1 -1
- package/dist/{config-Cz7ZyGF-.d.ts → config-BwScQukB.d.ts} +5 -4
- package/dist/csf/preview-api.js +2 -2
- package/dist/frame/index.d.ts +3 -2
- package/dist/frame/index.js +7 -8
- package/dist/frame/index.js.map +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.js +3 -3
- package/dist/shell/index.css +3 -0
- package/dist/shell/index.css.map +1 -1
- package/dist/shell/index.d.ts +4 -3
- package/dist/shell/index.js +140 -69
- package/dist/shell/index.js.map +1 -1
- package/dist/test/index.d.ts +2 -1
- package/dist/test/index.js +5 -5
- package/dist/vite/index.d.ts +1 -1
- package/dist/vite/index.js.map +1 -1
- package/package.json +8 -6
- package/dist/chunk-AP3DRQLI.js.map +0 -1
- package/dist/chunk-BIAEGWGJ.js.map +0 -1
- package/dist/chunk-DFKCLZKS.js.map +0 -1
- package/dist/chunk-FL2MUPUL.js.map +0 -1
package/dist/shell/index.js
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import { parseRoute, formatRoute, paramsToKnobs, knobPaths, sameKnob, knobsToParams, PLAYHEAD_PARAM, reservedParams } from '../chunk-
|
|
1
|
+
import { parseRoute, formatRoute, paramsToKnobs, knobPaths, sameKnob, knobsToParams, PLAYHEAD_PARAM, reservedParams } from '../chunk-DPTECNYC.js';
|
|
2
2
|
import { DEFAULT_TITLE } from '../chunk-5DXUNLV2.js';
|
|
3
|
-
import { TITLE_LIBRARIES, isIndexId, indexId, indexEntries, librariesFrom, LibrariesContext, schemaFromDescription, LibraryBadge, openChannel, IndexPage } from '../chunk-
|
|
3
|
+
import { TITLE_LIBRARIES, isIndexId, indexId, indexEntries, librariesFrom, LibrariesContext, createKitRoot, schemaFromDescription, LibraryBadge, openChannel, IndexPage } from '../chunk-R5F44ECM.js';
|
|
4
4
|
import { isGallery } from '../chunk-WEQSLPKT.js';
|
|
5
|
-
import { useTrialFrame, createTrialFrames, createTrialClocks, StoryGlobalsContext, TrialFramesContext, TrialClocksContext, StoryTrial, useCssOverrides, useTrialClock, TrialHost } from '../chunk-
|
|
6
|
-
export { StoryGlobalsContext, StoryTrial, TrialFramesContext, TrialHost, useTrialFrame } from '../chunk-
|
|
7
|
-
import { labGlobals, withGlobals, followApp, storyConfig, GLOBALS_KEY, effectiveGlobals, PLAYHEAD_KEY, labOptions, isGlobalsPath } from '../chunk-
|
|
8
|
-
import { loadStories, indexRenderOf, useNearViewport, IN_VIEW_MARGIN } from '../chunk-
|
|
5
|
+
import { useTrialFrame, createTrialFrames, createTrialClocks, StoryGlobalsContext, TrialFramesContext, TrialClocksContext, StoryTrial, useCssOverrides, useTrialClock, TrialHost } from '../chunk-J3GYSNCK.js';
|
|
6
|
+
export { StoryGlobalsContext, StoryTrial, TrialFramesContext, TrialHost, useTrialFrame } from '../chunk-J3GYSNCK.js';
|
|
7
|
+
import { labGlobals, withGlobals, followApp, storyConfig, GLOBALS_KEY, effectiveGlobals, PLAYHEAD_KEY, labOptions, isGlobalsPath } from '../chunk-7BQPHMA2.js';
|
|
8
|
+
import { loadStories, indexRenderOf, useNearViewport, IN_VIEW_MARGIN } from '../chunk-NVNTQ4AT.js';
|
|
9
9
|
import '../chunk-L5XM5VKB.js';
|
|
10
10
|
import '../chunk-ZAWXMUGZ.js';
|
|
11
|
-
import '../chunk-
|
|
12
|
-
import { stableStringify, PORT_HANDOFF, FRAME_HELLO, PROTOCOL_VERSION } from '../chunk-
|
|
13
|
-
import { useTrialId, Button, Lab, useLabContext, TrialIdContext, usePersistedState, Select, useTrialState,
|
|
11
|
+
import '../chunk-SQ4KCIEH.js';
|
|
12
|
+
import { stableStringify, PORT_HANDOFF, FRAME_HELLO, PROTOCOL_VERSION } from '../chunk-2OJAV522.js';
|
|
13
|
+
import { useTrialId, Button, Lab, useLabContext, TrialIdContext, usePersistedState, Select, useTrialState, ToggleBar as ToggleBar$1, Input, TokenPanel, inferTokenType, refitScale } from '@weasel-js/labkit';
|
|
14
14
|
import num from '@weasel-js/theme/numeric.module.css';
|
|
15
15
|
import { createContext, useState, useRef, useCallback, useEffect, useMemo, useLayoutEffect, useId, useContext, Fragment as Fragment$1, useSyncExternalStore } from 'react';
|
|
16
16
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
17
|
-
import { createRoot } from 'react-dom/client';
|
|
18
17
|
import { createEmitter } from '@weasel-js/registry';
|
|
19
18
|
import { f, valueAtPath, isConfigBranch } from '@weasel-js/labkit/config';
|
|
20
|
-
import {
|
|
21
|
-
import { themeAxes, weaselTheme,
|
|
19
|
+
import { formatShortcut, ToggleBar, Checkbox, Dialog, TOKEN_CATEGORIES, Icon, DisclosureMark, Button as Button$1, Callout, Slider, Transport } from '@weasel-js/ui';
|
|
20
|
+
import { TOKEN_MANIFEST, themeAxes, weaselTheme, THEME_SOURCES, resolveTheme, isColorModePreference, isByAxis } from '@weasel-js/theme';
|
|
22
21
|
import { scale, httpThemeApi } from '@weasel-js/theme/engine';
|
|
23
22
|
import { useLatest, historyKey, createHistory, swapOp, isPlainObject } from '@weasel-js/core';
|
|
24
23
|
import { useResolvedColorMode } from '@weasel-js/theme/react';
|
|
24
|
+
import { pref } from '@weasel-js/prefs';
|
|
25
25
|
|
|
26
26
|
function Finding({ finding }) {
|
|
27
27
|
return /* @__PURE__ */ jsxs("li", { className: "fg-a11y__finding", children: [
|
|
@@ -340,12 +340,30 @@ function missingInstrument(id, globals = {}) {
|
|
|
340
340
|
};
|
|
341
341
|
}
|
|
342
342
|
var ICONS = {
|
|
343
|
-
color:
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
343
|
+
color: (
|
|
344
|
+
/* @icon */
|
|
345
|
+
"ui:drop"
|
|
346
|
+
),
|
|
347
|
+
type: (
|
|
348
|
+
/* @icon */
|
|
349
|
+
"ui:type"
|
|
350
|
+
),
|
|
351
|
+
size: (
|
|
352
|
+
/* @icon */
|
|
353
|
+
"core:measure"
|
|
354
|
+
),
|
|
355
|
+
motion: (
|
|
356
|
+
/* @icon */
|
|
357
|
+
"ui:curveEaseInOut"
|
|
358
|
+
),
|
|
359
|
+
depth: (
|
|
360
|
+
/* @icon */
|
|
361
|
+
"ui:layers"
|
|
362
|
+
),
|
|
363
|
+
other: (
|
|
364
|
+
/* @icon */
|
|
365
|
+
"ui:more"
|
|
366
|
+
)
|
|
349
367
|
};
|
|
350
368
|
var PANEL = ".fg-css-vars";
|
|
351
369
|
var HOST = ".lk-sidebar-section, .lk-panel-tile";
|
|
@@ -636,6 +654,24 @@ function useThemeSave({ trialId, globals, themeApi, scales, overrides, history:
|
|
|
636
654
|
save
|
|
637
655
|
};
|
|
638
656
|
}
|
|
657
|
+
var MANIFEST = new Map(TOKEN_MANIFEST.map((token) => [token.name, token]));
|
|
658
|
+
function groupOf(name) {
|
|
659
|
+
const segments = name.replace(/^--/, "").split("-");
|
|
660
|
+
return segments.length > 1 ? segments.slice(0, -1).join("-") : name.replace(/^--/, "");
|
|
661
|
+
}
|
|
662
|
+
function useStoryTokens(vars) {
|
|
663
|
+
const [showUnused, setShowUnused] = usePersistedState("fg-css-vars-unused", false, { scope: "lab" });
|
|
664
|
+
const tokens = useMemo(
|
|
665
|
+
() => vars.flatMap(({ name, value, used }) => {
|
|
666
|
+
if (!used && !showUnused) return [];
|
|
667
|
+
const known = MANIFEST.get(name);
|
|
668
|
+
return [{ name, type: known?.type ?? inferTokenType(value), group: known?.group ?? groupOf(name), value }];
|
|
669
|
+
}),
|
|
670
|
+
[vars, showUnused]
|
|
671
|
+
);
|
|
672
|
+
const emptyText = vars.length > 0 && !showUnused ? "The story uses no variables." : "The story\u2019s frame has reported no variables.";
|
|
673
|
+
return { tokens, showUnused, setShowUnused, emptyText };
|
|
674
|
+
}
|
|
639
675
|
var AXES = themeAxes(weaselTheme);
|
|
640
676
|
function useThemeTokens(globals, vars) {
|
|
641
677
|
const selection = useTrialSelection(AXES, globals);
|
|
@@ -714,13 +750,13 @@ var TABS = [
|
|
|
714
750
|
{ value: "theme", label: "Theme" },
|
|
715
751
|
{ value: "story", label: "Story" }
|
|
716
752
|
];
|
|
717
|
-
var
|
|
753
|
+
var MANIFEST2 = new Map(TOKEN_MANIFEST.map((token) => [token.name, token]));
|
|
718
754
|
var literal = (v) => typeof v === "number";
|
|
719
755
|
var SCALE_SOURCES = Object.entries(THEME_SOURCES[THEME_NAME]?.scales ?? {}).flatMap(([name, def]) => {
|
|
720
756
|
if (!Array.isArray(def.steps)) return [];
|
|
721
757
|
const steps = def.steps;
|
|
722
758
|
const tokens = steps.map((step) => `${TOKEN_PREFIX}${name}-${step}`);
|
|
723
|
-
const group =
|
|
759
|
+
const group = MANIFEST2.get(tokens[0] ?? "")?.group;
|
|
724
760
|
if (!group) return [];
|
|
725
761
|
const factors = Array.isArray(def.factors) && def.factors.every(literal) ? def.factors : null;
|
|
726
762
|
const rule = def.factors !== void 0 ? factors ? { kind: "factors", factors } : "factors" : def.ratio !== void 0 ? literal(def.ratio) ? { kind: "ratio", ratio: def.ratio } : "ratio" : literal(def.step) ? { kind: "step", step: def.step } : "step";
|
|
@@ -750,10 +786,6 @@ function standingScale(source, amounts) {
|
|
|
750
786
|
const base = (amounts[at] ?? 0) / (rule.factors[at] ?? 1);
|
|
751
787
|
return { ...seed, base: Math.round(base * 100) / 100, rule };
|
|
752
788
|
}
|
|
753
|
-
function groupOf(name) {
|
|
754
|
-
const segments = name.replace(/^--/, "").split("-");
|
|
755
|
-
return segments.length > 1 ? segments.slice(0, -1).join("-") : name.replace(/^--/, "");
|
|
756
|
-
}
|
|
757
789
|
var NO_GLOBALS = {};
|
|
758
790
|
function CssVarsPanel({ globals = NO_GLOBALS, themeApi } = {}) {
|
|
759
791
|
const trialId = useTrialId();
|
|
@@ -768,13 +800,8 @@ function CssVarsPanel({ globals = NO_GLOBALS, themeApi } = {}) {
|
|
|
768
800
|
const [tab, setTab] = useState("theme");
|
|
769
801
|
const [filter, setFilter] = useState("");
|
|
770
802
|
const themeTokens = useThemeTokens(globals, frame.vars);
|
|
771
|
-
const
|
|
772
|
-
|
|
773
|
-
return frame.vars.map(({ name, value }) => {
|
|
774
|
-
const known = MANIFEST.get(name);
|
|
775
|
-
return { name, type: known?.type ?? inferTokenType(value), group: known?.group ?? groupOf(name), value };
|
|
776
|
-
});
|
|
777
|
-
}, [tab, frame.vars, themeTokens]);
|
|
803
|
+
const story = useStoryTokens(frame.vars);
|
|
804
|
+
const tokens = tab === "theme" ? themeTokens : story.tokens;
|
|
778
805
|
const query = filter.trim().toLowerCase();
|
|
779
806
|
const shown = tokens.map((token) => {
|
|
780
807
|
const override = overrides[token.name];
|
|
@@ -866,27 +893,27 @@ function CssVarsPanel({ globals = NO_GLOBALS, themeApi } = {}) {
|
|
|
866
893
|
placeholder: "Filter",
|
|
867
894
|
value: filter,
|
|
868
895
|
onChange: setFilter,
|
|
869
|
-
leadingAdornment: /* @__PURE__ */ jsx(
|
|
896
|
+
leadingAdornment: /* @__PURE__ */ jsx(Icon, { name: (
|
|
897
|
+
/* @icon */
|
|
898
|
+
"ui:search"
|
|
899
|
+
), size: 12 })
|
|
870
900
|
}
|
|
871
901
|
),
|
|
872
902
|
/* @__PURE__ */ jsxs("div", { className: "fg-css-vars__steps", role: "group", "aria-label": "History", children: [
|
|
873
|
-
/* @__PURE__ */ jsx(Button$1, { iconOnly: true, ariaLabel: "Undo", variant: "ghost", size: "sm", disabled: !history2.canUndo, onClick: () => history2.step("undo"), children: /* @__PURE__ */ jsx(Icon, { name:
|
|
874
|
-
|
|
903
|
+
/* @__PURE__ */ jsx(Button$1, { iconOnly: true, ariaLabel: "Undo", variant: "ghost", size: "sm", disabled: !history2.canUndo, onClick: () => history2.step("undo"), children: /* @__PURE__ */ jsx(Icon, { name: (
|
|
904
|
+
/* @icon */
|
|
905
|
+
"core:undo"
|
|
906
|
+
), size: 14 }) }),
|
|
907
|
+
/* @__PURE__ */ jsx(Button$1, { iconOnly: true, ariaLabel: "Redo", variant: "ghost", size: "sm", disabled: !history2.canRedo, onClick: () => history2.step("redo"), children: /* @__PURE__ */ jsx(Icon, { name: (
|
|
908
|
+
/* @icon */
|
|
909
|
+
"core:redo"
|
|
910
|
+
), size: 14 }) })
|
|
875
911
|
] })
|
|
876
912
|
] }),
|
|
877
|
-
tab === "
|
|
878
|
-
|
|
879
|
-
notice ? /* @__PURE__ */ jsx(
|
|
880
|
-
"p",
|
|
881
|
-
{
|
|
882
|
-
className: `fg-css-vars__notice fg-css-vars__notice--${notice.tone}`,
|
|
883
|
-
role: notice.tone === "error" ? "alert" : "status",
|
|
884
|
-
children: notice.text
|
|
885
|
-
}
|
|
886
|
-
) : null
|
|
887
|
-
] }) : null
|
|
913
|
+
tab === "story" ? /* @__PURE__ */ jsx(Checkbox, { className: "fg-css-vars__unused", isSelected: story.showUnused, onChange: story.setShowUnused, children: "Show variables the story doesn\u2019t use" }) : null,
|
|
914
|
+
tab === "theme" ? /* @__PURE__ */ jsx(SaveRow, { pending, saving, notice, onSave: () => void save() }) : null
|
|
888
915
|
] }),
|
|
889
|
-
shown.length === 0 ? /* @__PURE__ */ jsx("p", { className: "fg-css-vars__empty", children: tokens.length
|
|
916
|
+
shown.length === 0 ? /* @__PURE__ */ jsx("p", { className: "fg-css-vars__empty", children: tokens.length > 0 ? "No variables match." : tab === "story" ? story.emptyText : "The story\u2019s frame has reported no variables." }) : /* @__PURE__ */ jsx("div", { className: "fg-css-vars__list", children: /* @__PURE__ */ jsx(
|
|
890
917
|
TokenPanel,
|
|
891
918
|
{
|
|
892
919
|
tokens: shown,
|
|
@@ -903,6 +930,13 @@ function CssVarsPanel({ globals = NO_GLOBALS, themeApi } = {}) {
|
|
|
903
930
|
)
|
|
904
931
|
);
|
|
905
932
|
}
|
|
933
|
+
function SaveRow({ pending, saving, notice, onSave }) {
|
|
934
|
+
if (!pending && !notice) return null;
|
|
935
|
+
return /* @__PURE__ */ jsxs("div", { className: "fg-css-vars__save", children: [
|
|
936
|
+
pending ? /* @__PURE__ */ jsx(Button$1, { variant: "primary", size: "sm", loading: saving, disabled: saving, onClick: onSave, children: "Save to theme" }) : null,
|
|
937
|
+
notice ? /* @__PURE__ */ jsx("p", { className: `fg-css-vars__notice fg-css-vars__notice--${notice.tone}`, role: notice.tone === "error" ? "alert" : "status", children: notice.text }) : null
|
|
938
|
+
] });
|
|
939
|
+
}
|
|
906
940
|
function FocusedCssVars() {
|
|
907
941
|
const { focusedTrialId, trials, instruments } = useLabContext();
|
|
908
942
|
const labGlobals2 = useContext(StoryGlobalsContext);
|
|
@@ -920,6 +954,19 @@ var CSS_VARS_SECTION = {
|
|
|
920
954
|
region: "aside",
|
|
921
955
|
item: { title: "CSS Vars", actions: /* @__PURE__ */ jsx(SectionJump, {}), fill: true, body: /* @__PURE__ */ jsx(FocusedCssVars, {}) }
|
|
922
956
|
};
|
|
957
|
+
var KEYS = { kind: "key", key: "i", mods: { mod: true } };
|
|
958
|
+
function infoItem(open) {
|
|
959
|
+
return {
|
|
960
|
+
icon: (
|
|
961
|
+
/* @icon */
|
|
962
|
+
"ui:info"
|
|
963
|
+
),
|
|
964
|
+
label: "Info",
|
|
965
|
+
shortcut: formatShortcut({ key: KEYS.key, mod: KEYS.mods.mod }),
|
|
966
|
+
keys: KEYS,
|
|
967
|
+
onActivate: open
|
|
968
|
+
};
|
|
969
|
+
}
|
|
923
970
|
var GLOBALS = "$globals";
|
|
924
971
|
function leaves(shape, prefix = "") {
|
|
925
972
|
const out = [];
|
|
@@ -1193,7 +1240,8 @@ function GlobalsToolbar({ declarations }) {
|
|
|
1193
1240
|
NestedGlobals,
|
|
1194
1241
|
{
|
|
1195
1242
|
label: declaration.label,
|
|
1196
|
-
icon: declaration.icon ??
|
|
1243
|
+
icon: declaration.icon ?? /* @icon */
|
|
1244
|
+
"core:tune",
|
|
1197
1245
|
nested,
|
|
1198
1246
|
values,
|
|
1199
1247
|
set
|
|
@@ -1251,6 +1299,41 @@ function LabGlobals({
|
|
|
1251
1299
|
useEffect(() => onChange(resolved), [resolved, onChange]);
|
|
1252
1300
|
return null;
|
|
1253
1301
|
}
|
|
1302
|
+
var leafPath = (n) => `globals.d${n}.v`;
|
|
1303
|
+
function globalsMenu(declarations, values, set) {
|
|
1304
|
+
const entries = Object.entries(declarations);
|
|
1305
|
+
if (entries.length === 0) return void 0;
|
|
1306
|
+
const submenus = {};
|
|
1307
|
+
const current = {};
|
|
1308
|
+
const keys = /* @__PURE__ */ new Map();
|
|
1309
|
+
entries.forEach(([key, declaration], n) => {
|
|
1310
|
+
const options = labOptions(declaration, values);
|
|
1311
|
+
submenus[`d${n}`] = pref.group(
|
|
1312
|
+
declaration.label,
|
|
1313
|
+
{ v: pref.enum(declaration.label, declaration.default, options) },
|
|
1314
|
+
{ as: "menu" }
|
|
1315
|
+
);
|
|
1316
|
+
current[leafPath(n)] = values[key];
|
|
1317
|
+
keys.set(leafPath(n), key);
|
|
1318
|
+
});
|
|
1319
|
+
return {
|
|
1320
|
+
schema: pref.group("", { globals: pref.group("Globals", submenus, { as: "menu" }) }),
|
|
1321
|
+
values: current,
|
|
1322
|
+
onChange: (path, value) => {
|
|
1323
|
+
const key = keys.get(path);
|
|
1324
|
+
if (key !== void 0 && typeof value === "string") set(key, value);
|
|
1325
|
+
}
|
|
1326
|
+
};
|
|
1327
|
+
}
|
|
1328
|
+
function GlobalsMenus({
|
|
1329
|
+
declarations,
|
|
1330
|
+
onMenus
|
|
1331
|
+
}) {
|
|
1332
|
+
const [values, set] = useLabGlobals(declarations);
|
|
1333
|
+
const menus = useMemo(() => globalsMenu(declarations, values, set), [declarations, values, set]);
|
|
1334
|
+
useEffect(() => onMenus(menus), [menus, onMenus]);
|
|
1335
|
+
return null;
|
|
1336
|
+
}
|
|
1254
1337
|
function KnobSync({ schema, config }) {
|
|
1255
1338
|
const { setConfig } = useTrialState();
|
|
1256
1339
|
const reading = useRef(true);
|
|
@@ -2303,26 +2386,15 @@ function RouteOpener() {
|
|
|
2303
2386
|
}, [route, lab]);
|
|
2304
2387
|
return null;
|
|
2305
2388
|
}
|
|
2306
|
-
function
|
|
2389
|
+
function useDocumentTitle(title) {
|
|
2307
2390
|
useEffect(() => {
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
if (!(event.metaKey || event.ctrlKey) || event.altKey || event.shiftKey) return;
|
|
2311
|
-
const target = event.target;
|
|
2312
|
-
if (target?.isContentEditable || /^(input|textarea|select)$/i.test(target?.tagName ?? "")) return;
|
|
2313
|
-
event.preventDefault();
|
|
2314
|
-
open(true);
|
|
2315
|
-
};
|
|
2316
|
-
window.addEventListener("keydown", onKeyDown);
|
|
2317
|
-
return () => window.removeEventListener("keydown", onKeyDown);
|
|
2318
|
-
}, [open]);
|
|
2391
|
+
document.title = title;
|
|
2392
|
+
}, [title]);
|
|
2319
2393
|
}
|
|
2320
2394
|
function Workshop({ index, frameUrl, importers, setup, changes, config, stories = [], storageKey, storage, dependencies }) {
|
|
2321
2395
|
const declarations = config?.globals ?? NO_DECLARATIONS;
|
|
2322
2396
|
const title = config?.title ?? DEFAULT_TITLE;
|
|
2323
|
-
|
|
2324
|
-
document.title = title;
|
|
2325
|
-
}, [title]);
|
|
2397
|
+
useDocumentTitle(title);
|
|
2326
2398
|
const [frames] = useState(createTrialFrames);
|
|
2327
2399
|
const [clocks] = useState(createTrialClocks);
|
|
2328
2400
|
const [pool, setPool] = useState(null);
|
|
@@ -2358,15 +2430,11 @@ function Workshop({ index, frameUrl, importers, setup, changes, config, stories
|
|
|
2358
2430
|
const themeFor = config?.labTheme;
|
|
2359
2431
|
const labTheme = useMemo(() => themeFor?.(labValues), [themeFor, labValues]);
|
|
2360
2432
|
const [infoOpen, setInfoOpen] = useState(false);
|
|
2361
|
-
useInfoShortcut(setInfoOpen);
|
|
2362
2433
|
const reportLabValues = useCallback(
|
|
2363
2434
|
(next) => setLabValues((prev) => stableStringify(prev) === stableStringify(next) ? prev : next),
|
|
2364
2435
|
[]
|
|
2365
2436
|
);
|
|
2366
|
-
const infoCommand = useMemo(
|
|
2367
|
-
() => ({ icon: InfoIcon, label: "Info", shortcut: "\u2318I", onActivate: () => setInfoOpen(true) }),
|
|
2368
|
-
[]
|
|
2369
|
-
);
|
|
2437
|
+
const infoCommand = useMemo(() => infoItem(() => setInfoOpen(true)), []);
|
|
2370
2438
|
const labChrome = useMemo(
|
|
2371
2439
|
() => [
|
|
2372
2440
|
{ id: "fg-stories", region: "sidebar", render: (ctx) => /* @__PURE__ */ jsx(StoryTree, { ctx, index }) },
|
|
@@ -2378,6 +2446,7 @@ function Workshop({ index, frameUrl, importers, setup, changes, config, stories
|
|
|
2378
2446
|
],
|
|
2379
2447
|
[index, infoCommand, declarations, config?.cssVars, config?.labChrome]
|
|
2380
2448
|
);
|
|
2449
|
+
const [menus, setMenus] = useState();
|
|
2381
2450
|
const first = index[0];
|
|
2382
2451
|
if (!first) {
|
|
2383
2452
|
return /* @__PURE__ */ jsxs("div", { className: "fg-empty", children: [
|
|
@@ -2397,6 +2466,7 @@ function Workshop({ index, frameUrl, importers, setup, changes, config, stories
|
|
|
2397
2466
|
...storage ? { storage } : {},
|
|
2398
2467
|
labChrome,
|
|
2399
2468
|
addTrial: false,
|
|
2469
|
+
...menus ? { menus } : {},
|
|
2400
2470
|
...config?.controls ? { controls: config.controls } : {},
|
|
2401
2471
|
...config?.pages ? { pages: config.pages } : {},
|
|
2402
2472
|
...config?.path !== void 0 ? { path: config.path } : {},
|
|
@@ -2413,7 +2483,8 @@ function Workshop({ index, frameUrl, importers, setup, changes, config, stories
|
|
|
2413
2483
|
onOpenChange: setInfoOpen
|
|
2414
2484
|
}
|
|
2415
2485
|
),
|
|
2416
|
-
/* @__PURE__ */ jsx(LabGlobals, { declarations, onChange: reportLabValues })
|
|
2486
|
+
/* @__PURE__ */ jsx(LabGlobals, { declarations, onChange: reportLabValues }),
|
|
2487
|
+
/* @__PURE__ */ jsx(GlobalsMenus, { declarations, onMenus: setMenus })
|
|
2417
2488
|
]
|
|
2418
2489
|
}
|
|
2419
2490
|
) }) }) }) }) }) });
|
|
@@ -2421,7 +2492,7 @@ function Workshop({ index, frameUrl, importers, setup, changes, config, stories
|
|
|
2421
2492
|
function mountWorkshop({ container, ...props }) {
|
|
2422
2493
|
const target = container ?? document.getElementById("root");
|
|
2423
2494
|
if (!target) throw new Error("mountWorkshop: no container given and no #root element");
|
|
2424
|
-
const root =
|
|
2495
|
+
const root = createKitRoot(target, props.setup?.icons);
|
|
2425
2496
|
const changes = createStoryChanges();
|
|
2426
2497
|
let current = { ...props, changes };
|
|
2427
2498
|
root.render(/* @__PURE__ */ jsx(Workshop, { ...current }));
|