@weasel-js/forge 1.11.1 → 1.13.0-rc.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/README.md +110 -5
- package/dist/{FrameController-Cj_i-Rdk.d.ts → FrameController-Tv3jrHyT.d.ts} +3 -3
- package/dist/{chunk-JTCUIJPZ.js → chunk-35DOPXHZ.js} +119 -10
- package/dist/chunk-35DOPXHZ.js.map +1 -0
- package/dist/{chunk-7BQPHMA2.js → chunk-3BAM6M26.js} +2 -2
- package/dist/chunk-3BAM6M26.js.map +1 -0
- package/dist/{chunk-ZAWXMUGZ.js → chunk-5WS67HMU.js} +8 -3
- package/dist/chunk-5WS67HMU.js.map +1 -0
- package/dist/{chunk-BKPDKUDN.js → chunk-BUXUWAI4.js} +45 -60
- package/dist/chunk-BUXUWAI4.js.map +1 -0
- package/dist/chunk-ORMMZ5PV.js +59 -0
- package/dist/chunk-ORMMZ5PV.js.map +1 -0
- package/dist/chunk-RKQ277P5.js +501 -0
- package/dist/chunk-RKQ277P5.js.map +1 -0
- package/dist/chunk-STF6NQ5N.js +60 -0
- package/dist/chunk-STF6NQ5N.js.map +1 -0
- package/dist/chunk-VUPN73JP.js +16 -0
- package/dist/chunk-VUPN73JP.js.map +1 -0
- package/dist/{config-DN6IaNf6.d.ts → config-Bd6FVlh7.d.ts} +22 -5
- package/dist/frame/index.css +37 -0
- package/dist/frame/index.css.map +1 -1
- package/dist/frame/index.d.ts +62 -29
- package/dist/frame/index.js +138 -8
- package/dist/frame/index.js.map +1 -1
- package/dist/index.d.ts +28 -5
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/mountFrame-FdJDb3TB.d.ts +35 -0
- package/dist/shell/index.css +147 -2
- package/dist/shell/index.css.map +1 -1
- package/dist/shell/index.d.ts +44 -8
- package/dist/shell/index.js +1614 -277
- package/dist/shell/index.js.map +1 -1
- package/dist/test/index.css +58 -0
- package/dist/test/index.css.map +1 -0
- package/dist/test/index.d.ts +1 -1
- package/dist/test/index.js +4 -4
- package/dist/vite/index.js +571 -121
- package/dist/vite/index.js.map +1 -1
- package/package.json +13 -8
- package/dist/chunk-5DXUNLV2.js +0 -6
- package/dist/chunk-5DXUNLV2.js.map +0 -1
- package/dist/chunk-7BQPHMA2.js.map +0 -1
- package/dist/chunk-BKPDKUDN.js.map +0 -1
- package/dist/chunk-FZNABWJC.js +0 -282
- package/dist/chunk-FZNABWJC.js.map +0 -1
- package/dist/chunk-JTCUIJPZ.js.map +0 -1
- package/dist/chunk-WEQSLPKT.js +0 -9
- package/dist/chunk-WEQSLPKT.js.map +0 -1
- package/dist/chunk-ZAWXMUGZ.js.map +0 -1
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { sanitize } from './chunk-5WS67HMU.js';
|
|
2
|
+
|
|
3
|
+
// src/story/indexPages.ts
|
|
4
|
+
var SUFFIX = ":index";
|
|
5
|
+
var INDEX_NAME = "Index";
|
|
6
|
+
function indexId(title) {
|
|
7
|
+
return `${sanitize(title)}${SUFFIX}`;
|
|
8
|
+
}
|
|
9
|
+
function isIndexId(id) {
|
|
10
|
+
return id.endsWith(SUFFIX);
|
|
11
|
+
}
|
|
12
|
+
function stemOf(file) {
|
|
13
|
+
const name = file.replaceAll("\\", "/").split("/").pop() ?? file;
|
|
14
|
+
return name.replace(/(?:\.(?:story|stories))?\.[^.]+$/i, "");
|
|
15
|
+
}
|
|
16
|
+
function primaryFile(title, files) {
|
|
17
|
+
const name = (title.split("/").pop() ?? title).toLowerCase();
|
|
18
|
+
return files.find((file) => stemOf(file).toLowerCase() === name) ?? files[0];
|
|
19
|
+
}
|
|
20
|
+
function byComponent(stories) {
|
|
21
|
+
const byTitle = /* @__PURE__ */ new Map();
|
|
22
|
+
for (const entry of stories) {
|
|
23
|
+
const group = byTitle.get(entry.title);
|
|
24
|
+
if (group) group.push(entry);
|
|
25
|
+
else byTitle.set(entry.title, [entry]);
|
|
26
|
+
}
|
|
27
|
+
return [...byTitle].flatMap(([title, group]) => {
|
|
28
|
+
const primary = primaryFile(title, [...new Set(group.map((entry) => entry.file))]);
|
|
29
|
+
return [...group.filter((entry) => entry.file === primary), ...group.filter((entry) => entry.file !== primary)];
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
function indexEntries(stories) {
|
|
33
|
+
const byTitle = /* @__PURE__ */ new Map();
|
|
34
|
+
for (const entry of byComponent(stories)) {
|
|
35
|
+
const page = byTitle.get(entry.title);
|
|
36
|
+
if (page) {
|
|
37
|
+
if (page.tags) {
|
|
38
|
+
const common = page.tags.filter((tag) => entry.tags?.includes(tag));
|
|
39
|
+
if (common.length > 0) page.tags = common;
|
|
40
|
+
else delete page.tags;
|
|
41
|
+
}
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
byTitle.set(entry.title, {
|
|
45
|
+
id: indexId(entry.title),
|
|
46
|
+
title: entry.title,
|
|
47
|
+
name: INDEX_NAME,
|
|
48
|
+
exportName: "",
|
|
49
|
+
file: entry.file,
|
|
50
|
+
...entry.componentDescription === void 0 ? {} : { componentDescription: entry.componentDescription },
|
|
51
|
+
...entry.componentName === void 0 ? {} : { componentName: entry.componentName },
|
|
52
|
+
...entry.tags === void 0 ? {} : { tags: entry.tags }
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
return [...byTitle.values()];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export { byComponent, indexEntries, indexId, isIndexId };
|
|
59
|
+
//# sourceMappingURL=chunk-STF6NQ5N.js.map
|
|
60
|
+
//# sourceMappingURL=chunk-STF6NQ5N.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/story/indexPages.ts"],"names":[],"mappings":"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","file":"chunk-STF6NQ5N.js","sourcesContent":["import { sanitize } from './ids';\nimport type { IndexEntry } from './types';\n\nconst SUFFIX = ':index';\n\n/** The name an index page goes by in the sidebar and in its trial's title. */\nexport const INDEX_NAME = 'Index';\n\n/** The id of `title`'s index page. A colon never survives `sanitize`, so no story id can collide with it. */\nexport function indexId(title: string): string {\n return `${sanitize(title)}${SUFFIX}`;\n}\n\nexport function isIndexId(id: string): boolean {\n return id.endsWith(SUFFIX);\n}\n\n/** A story file's name with its `.stories.tsx`-style suffix removed: `Bar` for `/x/Bar.stories.tsx`. */\nfunction stemOf(file: string): string {\n const name = file.replaceAll('\\\\', '/').split('/').pop() ?? file;\n return name.replace(/(?:\\.(?:story|stories))?\\.[^.]+$/i, '');\n}\n\n/**\n * The file that speaks for a title several story files share: the one named for the title's last segment, so\n * `Bar.stories.tsx` over `lab/BarArc.stories.tsx` for `ui/Bar`, else the first. Its meta describes the component.\n */\nexport function primaryFile(title: string, files: readonly string[]): string | undefined {\n const name = (title.split('/').pop() ?? title).toLowerCase();\n return files.find((file) => stemOf(file).toLowerCase() === name) ?? files[0];\n}\n\n/** `stories` grouped by title, in the order titles first appear, each title's primary file's stories first. */\nexport function byComponent(stories: readonly IndexEntry[]): IndexEntry[] {\n const byTitle = new Map<string, IndexEntry[]>();\n for (const entry of stories) {\n const group = byTitle.get(entry.title);\n if (group) group.push(entry);\n else byTitle.set(entry.title, [entry]);\n }\n return [...byTitle].flatMap(([title, group]) => {\n const primary = primaryFile(title, [...new Set(group.map((entry) => entry.file))]);\n return [...group.filter((entry) => entry.file === primary), ...group.filter((entry) => entry.file !== primary)];\n });\n}\n\n/**\n * One index-page entry per title in `stories`, in the order titles first appear. It routes and runs like a story:\n * its `file` is the title's primary file, its descriptions are that file's, and its tags are those every story\n * of the title carries.\n */\nexport function indexEntries(stories: readonly IndexEntry[]): IndexEntry[] {\n const byTitle = new Map<string, IndexEntry>();\n for (const entry of byComponent(stories)) {\n const page = byTitle.get(entry.title);\n if (page) {\n if (page.tags) {\n const common = page.tags.filter((tag) => entry.tags?.includes(tag));\n if (common.length > 0) page.tags = common;\n else delete page.tags;\n }\n continue;\n }\n byTitle.set(entry.title, {\n id: indexId(entry.title),\n title: entry.title,\n name: INDEX_NAME,\n exportName: '',\n file: entry.file,\n ...(entry.componentDescription === undefined ? {} : { componentDescription: entry.componentDescription }),\n ...(entry.componentName === undefined ? {} : { componentName: entry.componentName }),\n ...(entry.tags === undefined ? {} : { tags: entry.tags }),\n });\n }\n return [...byTitle.values()];\n}\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// src/story/tags.ts
|
|
2
|
+
var GALLERY_TAG = "gallery";
|
|
3
|
+
function isGallery(entry) {
|
|
4
|
+
return entry.tags?.includes(GALLERY_TAG) ?? false;
|
|
5
|
+
}
|
|
6
|
+
var LAB_TAG = "lab";
|
|
7
|
+
function isLab(entry) {
|
|
8
|
+
return entry.tags?.includes(LAB_TAG) ?? false;
|
|
9
|
+
}
|
|
10
|
+
function taggedIds(entries) {
|
|
11
|
+
return { galleries: entries.filter(isGallery).map((e) => e.id), labs: entries.filter(isLab).map((e) => e.id) };
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export { GALLERY_TAG, LAB_TAG, isGallery, isLab, taggedIds };
|
|
15
|
+
//# sourceMappingURL=chunk-VUPN73JP.js.map
|
|
16
|
+
//# sourceMappingURL=chunk-VUPN73JP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/story/tags.ts"],"names":[],"mappings":";AACO,IAAM,WAAA,GAAc;AAEpB,SAAS,UAAU,KAAA,EAA8C;AACtE,EAAA,OAAO,KAAA,CAAM,IAAA,EAAM,QAAA,CAAS,WAAW,CAAA,IAAK,KAAA;AAC9C;AAGO,IAAM,OAAA,GAAU;AAEhB,SAAS,MAAM,KAAA,EAA8C;AAClE,EAAA,OAAO,KAAA,CAAM,IAAA,EAAM,QAAA,CAAS,OAAO,CAAA,IAAK,KAAA;AAC1C;AAGO,SAAS,UAAU,OAAA,EAGxB;AACA,EAAA,OAAO,EAAE,WAAW,OAAA,CAAQ,MAAA,CAAO,SAAS,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,EAAE,GAAG,IAAA,EAAM,OAAA,CAAQ,OAAO,KAAK,CAAA,CAAE,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,EAAE,CAAA,EAAE;AAC/G","file":"chunk-VUPN73JP.js","sourcesContent":["/** The meta tag marking a story file as a gallery: a catalog of many components, or of every permutation of one. */\nexport const GALLERY_TAG = 'gallery';\n\nexport function isGallery(entry: { tags?: readonly string[] }): boolean {\n return entry.tags?.includes(GALLERY_TAG) ?? false;\n}\n\n/** The meta tag marking a story file as a lab: a whole screen for exercising a component, not a specimen of it. */\nexport const LAB_TAG = 'lab';\n\nexport function isLab(entry: { tags?: readonly string[] }): boolean {\n return entry.tags?.includes(LAB_TAG) ?? false;\n}\n\n/** The ids among `entries` tagged as galleries and as labs, as an index page is handed them. */\nexport function taggedIds(entries: readonly { id: string; tags?: readonly string[] }[]): {\n galleries: string[];\n labs: string[];\n} {\n return { galleries: entries.filter(isGallery).map((e) => e.id), labs: entries.filter(isLab).map((e) => e.id) };\n}\n"]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { LabMode, LabContribution, LabPage } from '@weasel-js/labkit';
|
|
2
2
|
import { Theme } from '@weasel-js/theme';
|
|
3
3
|
import { ControlRenderer } from '@weasel-js/labkit/config';
|
|
4
|
-
import { G as Globals, F as FrameSetup } from './FrameController-
|
|
4
|
+
import { G as Globals, F as FrameSetup } from './FrameController-Tv3jrHyT.js';
|
|
5
5
|
import { IconRef } from '@weasel-js/icons';
|
|
6
|
-
import {
|
|
6
|
+
import { AppearanceProps } from '@weasel-js/ui/appearance';
|
|
7
7
|
|
|
8
8
|
/** One global the workshop's toolbar sets for every story, and a trial may pin for its own. */
|
|
9
9
|
interface GlobalDeclaration {
|
|
@@ -28,6 +28,12 @@ interface GlobalDeclaration {
|
|
|
28
28
|
* pin follows the lab or names a value; it cannot follow the app on its own.
|
|
29
29
|
*/
|
|
30
30
|
follows?: (chrome: LabChrome) => string;
|
|
31
|
+
/**
|
|
32
|
+
* The value opposite `value`, for the global a lens's opposite-mode comparison flips (`ShellConfig.loupe`'s
|
|
33
|
+
* `modeGlobal`); undefined when it has none. `App` and `auto` are resolved to the mode they show before this is
|
|
34
|
+
* asked. Absent, the lens swaps `light` and `dark`.
|
|
35
|
+
*/
|
|
36
|
+
opposite?: (value: string, globals: Globals) => string | undefined;
|
|
31
37
|
}
|
|
32
38
|
/** The lab chrome's own settings a global can follow. */
|
|
33
39
|
interface LabChrome {
|
|
@@ -43,8 +49,8 @@ interface Library {
|
|
|
43
49
|
/** A stretch of path every story file of the library has, with forward slashes: `/packages/ui/`. */
|
|
44
50
|
path: string;
|
|
45
51
|
label: string;
|
|
46
|
-
/** The
|
|
47
|
-
|
|
52
|
+
/** The tint of the library's badge, as a `<Badge>` takes one. Default: the badge's own low emphasis. */
|
|
53
|
+
tint?: AppearanceProps['tint'];
|
|
48
54
|
}
|
|
49
55
|
/** A project's libraries, as the tree's package filter, the index page header, and Get Info ask about them. */
|
|
50
56
|
interface Libraries {
|
|
@@ -53,7 +59,7 @@ interface Libraries {
|
|
|
53
59
|
file: string;
|
|
54
60
|
title: string;
|
|
55
61
|
}): string;
|
|
56
|
-
|
|
62
|
+
tintOf(label: string): AppearanceProps['tint'];
|
|
57
63
|
}
|
|
58
64
|
|
|
59
65
|
/** A shell config module: what the workshop adds to the lab. Only the workshop page imports it. */
|
|
@@ -78,6 +84,17 @@ interface ShellConfig {
|
|
|
78
84
|
pages?: readonly LabPage[];
|
|
79
85
|
/** Which of `pages` the workshop is, when the URL alone cannot say, as across dev servers on different ports. */
|
|
80
86
|
path?: string;
|
|
87
|
+
/** What a Pixels capture may load besides the dev server's own pages, such as the origins of a web-font service
|
|
88
|
+
* the stories' fonts come from. Every other request a capture makes is refused. The dev server reads the list
|
|
89
|
+
* from this module's source, as it does `title`, so write each origin as a string. */
|
|
90
|
+
capture?: {
|
|
91
|
+
allowOrigins?: readonly string[];
|
|
92
|
+
};
|
|
93
|
+
/** The workshop's lenses. `modeGlobal` names the global holding the color mode, which a lens's opposite-mode
|
|
94
|
+
* comparison flips through its declaration's `opposite`. Default `mode`. */
|
|
95
|
+
loupe?: {
|
|
96
|
+
modeGlobal?: string;
|
|
97
|
+
};
|
|
81
98
|
}
|
|
82
99
|
/** A frame config module's default export. The workshop page imports it as well as every frame document, so CSS it imports reaches both; the plugin's `frameStyles` is for CSS meant for frames alone. */
|
|
83
100
|
declare function defineFrameConfig(config: FrameSetup): FrameSetup;
|
package/dist/frame/index.css
CHANGED
|
@@ -73,6 +73,24 @@ body {
|
|
|
73
73
|
margin-top: calc(var(--wzl-space-lg) * 1.5);
|
|
74
74
|
border-top: var(--wzl-border-w) solid var(--wzl-border);
|
|
75
75
|
}
|
|
76
|
+
.fg-index-story__main {
|
|
77
|
+
display: flex;
|
|
78
|
+
flex-wrap: wrap;
|
|
79
|
+
align-items: flex-start;
|
|
80
|
+
gap: var(--wzl-space-8) calc(var(--wzl-space-lg) * 1.5);
|
|
81
|
+
}
|
|
82
|
+
.fg-index-story__text {
|
|
83
|
+
flex: 1 1 20rem;
|
|
84
|
+
min-width: 0;
|
|
85
|
+
}
|
|
86
|
+
.fg-index-story__main > .fg-index-cell {
|
|
87
|
+
flex: 0 1 auto;
|
|
88
|
+
margin: 0;
|
|
89
|
+
}
|
|
90
|
+
.fg-index-story__main > .fg-index-cell--padded,
|
|
91
|
+
.fg-index-story__main > .fg-index-cell--fullscreen {
|
|
92
|
+
flex: 2 1 28rem;
|
|
93
|
+
}
|
|
76
94
|
.fg-index-story__head {
|
|
77
95
|
display: flex;
|
|
78
96
|
align-items: center;
|
|
@@ -87,6 +105,14 @@ body {
|
|
|
87
105
|
text-transform: var(--wzl-panel-title-case);
|
|
88
106
|
color: var(--wzl-panel-title-color);
|
|
89
107
|
}
|
|
108
|
+
.fg-index-story__link {
|
|
109
|
+
color: inherit;
|
|
110
|
+
text-decoration: none;
|
|
111
|
+
}
|
|
112
|
+
.fg-index-story__link:hover {
|
|
113
|
+
color: var(--wzl-accent-fg);
|
|
114
|
+
text-decoration: underline;
|
|
115
|
+
}
|
|
90
116
|
.fg-index-cell {
|
|
91
117
|
margin: var(--wzl-space-8) 0 0;
|
|
92
118
|
width: fit-content;
|
|
@@ -213,4 +239,15 @@ body {
|
|
|
213
239
|
margin: var(--wzl-space-8) 0 0;
|
|
214
240
|
font-size: var(--wzl-font-size-sm);
|
|
215
241
|
}
|
|
242
|
+
|
|
243
|
+
/* src/frame/capture/capture.css */
|
|
244
|
+
.fg-story[data-fg-capture] {
|
|
245
|
+
position: relative;
|
|
246
|
+
box-sizing: border-box;
|
|
247
|
+
width: var(--fg-capture-w);
|
|
248
|
+
height: var(--fg-capture-h);
|
|
249
|
+
overflow: hidden;
|
|
250
|
+
contain: paint;
|
|
251
|
+
container-type: size;
|
|
252
|
+
}
|
|
216
253
|
/*# sourceMappingURL=index.css.map */
|
package/dist/frame/index.css.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/frame/frame.css","../../src/frame/index/index.css"],"sourcesContent":["html,\nbody {\n margin: 0;\n}\n\n.fg-frame {\n box-sizing: border-box;\n}\n\n.fg-frame--centered {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 100vh;\n}\n\n.fg-frame--padded {\n padding: var(--wzl-space-8);\n}\n\n.fg-frame--fullscreen {\n height: 100vh;\n padding: 0;\n}\n\n.fg-frame__fault {\n margin: 0;\n padding: var(--wzl-space-8);\n white-space: pre-wrap;\n border: 1px solid #f2b8b5;\n border-radius: 4px;\n background: #fdecea;\n color: #8c1d18;\n font: 13px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace;\n}\n",".fg-index {\n box-sizing: border-box;\n max-width: 1200px;\n margin: 0 auto;\n padding: var(--wzl-space-lg);\n font-family: var(--wzl-font-ui);\n font-size: var(--wzl-font-size);\n color: var(--wzl-fg);\n}\n\n.fg-index__head {\n margin-bottom: calc(var(--wzl-space-lg) * 2);\n}\n\n.fg-index__path {\n margin: 0 0 var(--wzl-space-2);\n font-size: var(--wzl-font-size-lg);\n color: var(--wzl-fg-muted);\n}\n\n.fg-index__title {\n margin: 0;\n font-family: var(--wzl-panel-title-font);\n font-size: calc(var(--wzl-font-size-xl) * 1.6);\n font-weight: var(--wzl-font-weight-medium);\n letter-spacing: var(--wzl-panel-title-tracking);\n text-transform: var(--wzl-panel-title-case);\n}\n\n.fg-index__description,\n.fg-index-story__description {\n max-width: 72ch;\n margin: var(--wzl-space-4) 0 0;\n font-family: var(--wzl-font-body);\n line-height: 1.5;\n color: var(--wzl-fg-muted);\n}\n\n.fg-index-story {\n padding-top: calc(var(--wzl-space-lg) * 1.5);\n margin-top: calc(var(--wzl-space-lg) * 1.5);\n border-top: var(--wzl-border-w) solid var(--wzl-border);\n}\n\n.fg-index-story__head {\n display: flex;\n align-items: center;\n gap: var(--wzl-space-6);\n}\n\n.fg-index-story__name {\n margin: 0;\n font-family: var(--wzl-panel-title-font);\n font-size: var(--wzl-font-size-xl);\n font-weight: var(--wzl-panel-title-weight);\n letter-spacing: var(--wzl-panel-title-tracking);\n text-transform: var(--wzl-panel-title-case);\n color: var(--wzl-panel-title-color);\n}\n\n.fg-index-cell {\n margin: var(--wzl-space-8) 0 0;\n width: fit-content;\n /* A fluid specimen (a slider, a tiled workspace) has no width of its own,\n so hugging it alone collapses the cell to its padding. */\n min-width: min(100%, 20rem);\n max-width: 100%;\n}\n\n.fg-index-cell__stage {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 96px;\n padding: var(--wzl-space-2);\n border: var(--wzl-border-w) solid var(--wzl-border);\n border-radius: var(--wzl-radius-md);\n background: var(--wzl-surface);\n overflow: auto;\n}\n\n/* A padded story sits top-left as it would on a page: the column's width, and\n none of the minimum height that gives a centered one presence. */\n.fg-index-cell--padded {\n width: auto;\n}\n\n.fg-index-cell--padded > .fg-index-cell__stage {\n display: block;\n min-height: 0;\n}\n\n.fg-index-cell--fullscreen {\n width: auto;\n}\n\n.fg-index-cell--fullscreen > .fg-index-cell__stage {\n display: block;\n height: 360px;\n padding: 0;\n}\n\n.fg-index-cell__label {\n margin-top: var(--wzl-space-3);\n font-family: var(--wzl-font-mono);\n font-size: var(--wzl-font-size-sm);\n color: var(--wzl-fg-muted);\n}\n\n.fg-index-variants__row {\n margin-top: calc(var(--wzl-space-lg) * 1.25);\n}\n\n/* Set as the kit's panel titles are, at the small size. */\n.fg-index-variants__label {\n margin: 0;\n font-family: var(--wzl-panel-title-font);\n font-size: var(--wzl-font-size-sm);\n font-weight: var(--wzl-panel-title-weight);\n letter-spacing: 0.06em;\n text-transform: uppercase;\n color: var(--wzl-fg-muted);\n}\n\n.fg-index-variants__cells {\n display: flex;\n flex-wrap: wrap;\n align-items: flex-start;\n gap: var(--wzl-space-6);\n}\n\n.fg-index-variants__cells > .fg-index-cell {\n margin-top: var(--wzl-space-4);\n}\n\n.fg-index__library {\n margin-inline-end: var(--wzl-space-4);\n vertical-align: middle;\n}\n\n.fg-index__title-row {\n display: flex;\n align-items: center;\n gap: var(--wzl-space-6);\n}\n\n.fg-index-history {\n display: flex;\n flex-wrap: wrap;\n gap: var(--wzl-space-2) var(--wzl-space-8);\n margin: var(--wzl-space-8) 0 0;\n font-size: var(--wzl-font-size-sm);\n}\n\n.fg-index-history__item {\n display: flex;\n gap: var(--wzl-space-3);\n}\n\n.fg-index-history__label {\n color: var(--wzl-fg-muted);\n}\n\n.fg-index-history__value {\n margin: 0;\n}\n\n.fg-index-deps {\n display: grid;\n grid-template-columns: max-content 1fr;\n gap: var(--wzl-space-3) var(--wzl-space-8);\n margin: var(--wzl-space-8) 0 0;\n font-size: var(--wzl-font-size-sm);\n}\n\n.fg-index-deps__row {\n display: contents;\n}\n\n.fg-index-deps__label {\n color: var(--wzl-fg-muted);\n}\n\n.fg-index-deps__value {\n margin: 0;\n}\n\n.fg-index-deps__list {\n display: flex;\n flex-wrap: wrap;\n gap: var(--wzl-space-2) var(--wzl-space-6);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.fg-index-deps__link {\n color: var(--wzl-accent-fg);\n text-decoration: none;\n}\n\n.fg-index-deps__link:hover {\n text-decoration: underline;\n}\n\n.fg-index-deps__prefix,\n.fg-index-deps__empty,\n.fg-index-deps__none {\n color: var(--wzl-fg-muted);\n}\n\n.fg-index-deps__none {\n max-width: 72ch;\n margin: var(--wzl-space-8) 0 0;\n font-size: var(--wzl-font-size-sm);\n}\n"],"mappings":";AAAA;AACA;AACE,UAAQ;AACV;AAEA,CAAC;AACC,cAAY;AACd;AAEA,CAAC;AACC,WAAS;AACT,eAAa;AACb,mBAAiB;AACjB,cAAY;AACd;AAEA,CAAC;AACC,WAAS,IAAI;AACf;AAEA,CAAC;AACC,UAAQ;AACR,WAAS;AACX;AAEA,CAAC;AACC,UAAQ;AACR,WAAS,IAAI;AACb,eAAa;AACb,UAAQ,IAAI,MAAM;AAClB,iBAAe;AACf,cAAY;AACZ,SAAO;AACP;AAAA,IAAM,IAAI,CAAC,IAAI,YAAY;AAAA,IAAE,cAAc;AAAA,IAAE,KAAK;AAAA,IAAE;AACtD;;;AClCA,CAAC;AACC,cAAY;AACZ,aAAW;AACX,UAAQ,EAAE;AACV,WAAS,IAAI;AACb,eAAa,IAAI;AACjB,aAAW,IAAI;AACf,SAAO,IAAI;AACb;AAEA,CAAC;AACC,iBAAe,KAAK,IAAI,gBAAgB,EAAE;AAC5C;AAEA,CAAC;AACC,UAAQ,EAAE,EAAE,IAAI;AAChB,aAAW,IAAI;AACf,SAAO,IAAI;AACb;AAEA,CAAC;AACC,UAAQ;AACR,eAAa,IAAI;AACjB,aAAW,KAAK,IAAI,oBAAoB,EAAE;AAC1C,eAAa,IAAI;AACjB,kBAAgB,IAAI;AACpB,kBAAgB,IAAI;AACtB;AAEA,CAAC;AACD,CAAC;AACC,aAAW;AACX,UAAQ,IAAI,eAAe,EAAE;AAC7B,eAAa,IAAI;AACjB,eAAa;AACb,SAAO,IAAI;AACb;AAEA,CAAC;AACC,eAAa,KAAK,IAAI,gBAAgB,EAAE;AACxC,cAAY,KAAK,IAAI,gBAAgB,EAAE;AACvC,cAAY,IAAI,gBAAgB,MAAM,IAAI;AAC5C;AAEA,CAAC;AACC,WAAS;AACT,eAAa;AACb,OAAK,IAAI;AACX;AAEA,CAAC;AACC,UAAQ;AACR,eAAa,IAAI;AACjB,aAAW,IAAI;AACf,eAAa,IAAI;AACjB,kBAAgB,IAAI;AACpB,kBAAgB,IAAI;AACpB,SAAO,IAAI;AACb;AAEA,CAAC;AACC,UAAQ,IAAI,eAAe,EAAE;AAC7B,SAAO;AAGP,aAAW,IAAI,IAAI,EAAE;AACrB,aAAW;AACb;AAEA,CAAC;AACC,WAAS;AACT,eAAa;AACb,mBAAiB;AACjB,cAAY;AACZ,WAAS,IAAI;AACb,UAAQ,IAAI,gBAAgB,MAAM,IAAI;AACtC,iBAAe,IAAI;AACnB,cAAY,IAAI;AAChB,YAAU;AACZ;AAIA,
|
|
1
|
+
{"version":3,"sources":["../../src/frame/frame.css","../../src/frame/index/index.css","../../src/frame/capture/capture.css"],"sourcesContent":["html,\nbody {\n margin: 0;\n}\n\n.fg-frame {\n box-sizing: border-box;\n}\n\n.fg-frame--centered {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 100vh;\n}\n\n.fg-frame--padded {\n padding: var(--wzl-space-8);\n}\n\n.fg-frame--fullscreen {\n height: 100vh;\n padding: 0;\n}\n\n.fg-frame__fault {\n margin: 0;\n padding: var(--wzl-space-8);\n white-space: pre-wrap;\n border: 1px solid #f2b8b5;\n border-radius: 4px;\n background: #fdecea;\n color: #8c1d18;\n font: 13px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace;\n}\n",".fg-index {\n box-sizing: border-box;\n max-width: 1200px;\n margin: 0 auto;\n padding: var(--wzl-space-lg);\n font-family: var(--wzl-font-ui);\n font-size: var(--wzl-font-size);\n color: var(--wzl-fg);\n}\n\n.fg-index__head {\n margin-bottom: calc(var(--wzl-space-lg) * 2);\n}\n\n.fg-index__path {\n margin: 0 0 var(--wzl-space-2);\n font-size: var(--wzl-font-size-lg);\n color: var(--wzl-fg-muted);\n}\n\n.fg-index__title {\n margin: 0;\n font-family: var(--wzl-panel-title-font);\n font-size: calc(var(--wzl-font-size-xl) * 1.6);\n font-weight: var(--wzl-font-weight-medium);\n letter-spacing: var(--wzl-panel-title-tracking);\n text-transform: var(--wzl-panel-title-case);\n}\n\n.fg-index__description,\n.fg-index-story__description {\n max-width: 72ch;\n margin: var(--wzl-space-4) 0 0;\n font-family: var(--wzl-font-body);\n line-height: 1.5;\n color: var(--wzl-fg-muted);\n}\n\n.fg-index-story {\n padding-top: calc(var(--wzl-space-lg) * 1.5);\n margin-top: calc(var(--wzl-space-lg) * 1.5);\n border-top: var(--wzl-border-w) solid var(--wzl-border);\n}\n\n/* Text and example share a row while both fit, and the example wraps under the text rather than squeezing it. */\n.fg-index-story__main {\n display: flex;\n flex-wrap: wrap;\n align-items: flex-start;\n gap: var(--wzl-space-8) calc(var(--wzl-space-lg) * 1.5);\n}\n\n.fg-index-story__text {\n flex: 1 1 20rem;\n min-width: 0;\n}\n\n.fg-index-story__main > .fg-index-cell {\n flex: 0 1 auto;\n margin: 0;\n}\n\n.fg-index-story__main > .fg-index-cell--padded,\n.fg-index-story__main > .fg-index-cell--fullscreen {\n flex: 2 1 28rem;\n}\n\n.fg-index-story__head {\n display: flex;\n align-items: center;\n gap: var(--wzl-space-6);\n}\n\n.fg-index-story__name {\n margin: 0;\n font-family: var(--wzl-panel-title-font);\n font-size: var(--wzl-font-size-xl);\n font-weight: var(--wzl-panel-title-weight);\n letter-spacing: var(--wzl-panel-title-tracking);\n text-transform: var(--wzl-panel-title-case);\n color: var(--wzl-panel-title-color);\n}\n\n.fg-index-story__link {\n color: inherit;\n text-decoration: none;\n}\n\n.fg-index-story__link:hover {\n color: var(--wzl-accent-fg);\n text-decoration: underline;\n}\n\n.fg-index-cell {\n margin: var(--wzl-space-8) 0 0;\n width: fit-content;\n /* A fluid specimen (a slider, a tiled workspace) has no width of its own,\n so hugging it alone collapses the cell to its padding. */\n min-width: min(100%, 20rem);\n max-width: 100%;\n}\n\n.fg-index-cell__stage {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 96px;\n padding: var(--wzl-space-2);\n border: var(--wzl-border-w) solid var(--wzl-border);\n border-radius: var(--wzl-radius-md);\n background: var(--wzl-surface);\n overflow: auto;\n}\n\n/* A padded story sits top-left as it would on a page: the column's width, and\n none of the minimum height that gives a centered one presence. */\n.fg-index-cell--padded {\n width: auto;\n}\n\n.fg-index-cell--padded > .fg-index-cell__stage {\n display: block;\n min-height: 0;\n}\n\n.fg-index-cell--fullscreen {\n width: auto;\n}\n\n.fg-index-cell--fullscreen > .fg-index-cell__stage {\n display: block;\n height: 360px;\n padding: 0;\n}\n\n.fg-index-cell__label {\n margin-top: var(--wzl-space-3);\n font-family: var(--wzl-font-mono);\n font-size: var(--wzl-font-size-sm);\n color: var(--wzl-fg-muted);\n}\n\n.fg-index-variants__row {\n margin-top: calc(var(--wzl-space-lg) * 1.25);\n}\n\n/* Set as the kit's panel titles are, at the small size. */\n.fg-index-variants__label {\n margin: 0;\n font-family: var(--wzl-panel-title-font);\n font-size: var(--wzl-font-size-sm);\n font-weight: var(--wzl-panel-title-weight);\n letter-spacing: 0.06em;\n text-transform: uppercase;\n color: var(--wzl-fg-muted);\n}\n\n.fg-index-variants__cells {\n display: flex;\n flex-wrap: wrap;\n align-items: flex-start;\n gap: var(--wzl-space-6);\n}\n\n.fg-index-variants__cells > .fg-index-cell {\n margin-top: var(--wzl-space-4);\n}\n\n.fg-index__library {\n margin-inline-end: var(--wzl-space-4);\n vertical-align: middle;\n}\n\n.fg-index__title-row {\n display: flex;\n align-items: center;\n gap: var(--wzl-space-6);\n}\n\n.fg-index-history {\n display: flex;\n flex-wrap: wrap;\n gap: var(--wzl-space-2) var(--wzl-space-8);\n margin: var(--wzl-space-8) 0 0;\n font-size: var(--wzl-font-size-sm);\n}\n\n.fg-index-history__item {\n display: flex;\n gap: var(--wzl-space-3);\n}\n\n.fg-index-history__label {\n color: var(--wzl-fg-muted);\n}\n\n.fg-index-history__value {\n margin: 0;\n}\n\n.fg-index-deps {\n display: grid;\n grid-template-columns: max-content 1fr;\n gap: var(--wzl-space-3) var(--wzl-space-8);\n margin: var(--wzl-space-8) 0 0;\n font-size: var(--wzl-font-size-sm);\n}\n\n.fg-index-deps__row {\n display: contents;\n}\n\n.fg-index-deps__label {\n color: var(--wzl-fg-muted);\n}\n\n.fg-index-deps__value {\n margin: 0;\n}\n\n.fg-index-deps__list {\n display: flex;\n flex-wrap: wrap;\n gap: var(--wzl-space-2) var(--wzl-space-6);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.fg-index-deps__link {\n color: var(--wzl-accent-fg);\n text-decoration: none;\n}\n\n.fg-index-deps__link:hover {\n text-decoration: underline;\n}\n\n.fg-index-deps__prefix,\n.fg-index-deps__empty,\n.fg-index-deps__none {\n color: var(--wzl-fg-muted);\n}\n\n.fg-index-deps__none {\n max-width: 72ch;\n margin: var(--wzl-space-8) 0 0;\n font-size: var(--wzl-font-size-sm);\n}\n","/* The capture box is the host's size exactly, whatever else styles a `.fg-story`. An isolated story's frame wrapper\n measures `100vh` against the page, which the capture sizes to the box. */\n.fg-story[data-fg-capture] {\n position: relative;\n box-sizing: border-box;\n width: var(--fg-capture-w);\n height: var(--fg-capture-h);\n overflow: hidden;\n contain: paint;\n container-type: size;\n}\n"],"mappings":"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","names":[]}
|
package/dist/frame/index.d.ts
CHANGED
|
@@ -1,39 +1,72 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { G as Globals, L as Layout, I as IndexEntry, F as FrameSetup } from '../FrameController-Tv3jrHyT.js';
|
|
2
|
+
export { C as Channel, a as ConfigAnswers, b as FaultPhase, c as FromFrame, S as StartFrameOptions, T as ToFrame, r as reportImportFault, s as startFrame } from '../FrameController-Tv3jrHyT.js';
|
|
3
|
+
import { F as FrameImporters } from '../mountFrame-FdJDb3TB.js';
|
|
4
|
+
export { a as FrameIndexEntry, M as MountFrameOptions, m as mountFrame } from '../mountFrame-FdJDb3TB.js';
|
|
5
|
+
import { Theme } from '@weasel-js/theme';
|
|
3
6
|
import '@weasel-js/icons';
|
|
4
7
|
import '@weasel-js/labkit/config';
|
|
5
8
|
import 'react';
|
|
6
9
|
|
|
7
|
-
/**
|
|
8
|
-
interface
|
|
9
|
-
|
|
10
|
+
/** Everything the screen renders a story from, as the capture endpoint takes it. */
|
|
11
|
+
interface CapturePayload {
|
|
12
|
+
/** The story's index id. */
|
|
13
|
+
story: string;
|
|
14
|
+
/** Picks the document: an isolated story renders under frame styles, any other under shell styles. */
|
|
15
|
+
isolate: boolean;
|
|
16
|
+
/** The story's config, with forge's `$` keys stripped and a comparison's args laid over. */
|
|
17
|
+
config: unknown;
|
|
18
|
+
/** Must survive JSON. */
|
|
19
|
+
state: unknown;
|
|
20
|
+
globals: Globals;
|
|
21
|
+
/** CSS variable overrides, by property name. */
|
|
22
|
+
overrides: Readonly<Record<string, string>>;
|
|
23
|
+
/** Null for a story with no timeline, and for an isolated story. */
|
|
24
|
+
playhead: number | null;
|
|
25
|
+
/** The host's size in CSS pixels. */
|
|
26
|
+
box: {
|
|
27
|
+
width: number;
|
|
28
|
+
height: number;
|
|
29
|
+
};
|
|
30
|
+
layout: Layout;
|
|
31
|
+
/** Device pixel ratio, in [1, 3]. */
|
|
32
|
+
dpr: number;
|
|
33
|
+
/** Where the story's scroller stands in its host, in CSS pixels, so the capture shows the patch the screen does. */
|
|
34
|
+
scroll: {
|
|
35
|
+
left: number;
|
|
36
|
+
top: number;
|
|
37
|
+
};
|
|
38
|
+
/** The workshop lab's theme as the screen shows it: the lab's globals, which the shell config's `labTheme` reads,
|
|
39
|
+
* and its resolved color mode. An isolated story's document has no lab, and ignores it. */
|
|
40
|
+
lab: {
|
|
41
|
+
globals: Globals;
|
|
42
|
+
mode: 'light' | 'dark';
|
|
43
|
+
};
|
|
44
|
+
/** The OS color scheme the screen sees, which the capture page emulates: a story or a lab in `auto` mode follows
|
|
45
|
+
* `prefers-color-scheme`, and headless Chromium would otherwise answer light. */
|
|
46
|
+
colorScheme: 'light' | 'dark';
|
|
10
47
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
title: string;
|
|
16
|
-
file: string;
|
|
17
|
-
exportName: string;
|
|
18
|
-
/** The JSDoc above the story's export, which its index page shows. */
|
|
19
|
-
description?: string;
|
|
20
|
-
/** The JSDoc above the file's meta, which heads the index page. */
|
|
21
|
-
componentDescription?: string;
|
|
22
|
-
/** The meta's `tags`. */
|
|
23
|
-
tags?: readonly string[];
|
|
24
|
-
}
|
|
25
|
-
/** Inputs to `mountFrame`. `load` replaces the default module loader, `loadStories`. */
|
|
26
|
-
interface MountFrameOptions {
|
|
27
|
-
index: readonly FrameIndexEntry[];
|
|
48
|
+
|
|
49
|
+
/** Inputs to `mountCapture`, as a capture page's entry module passes them. */
|
|
50
|
+
interface MountCaptureOptions {
|
|
51
|
+
index: readonly IndexEntry[];
|
|
28
52
|
importers: FrameImporters;
|
|
29
|
-
setup
|
|
30
|
-
|
|
53
|
+
setup: FrameSetup;
|
|
54
|
+
/** The shell config's `labTheme`; only the shell's capture page has one. */
|
|
55
|
+
labTheme?: ((globals: Globals) => Theme) | undefined;
|
|
56
|
+
}
|
|
57
|
+
declare global {
|
|
58
|
+
interface Window {
|
|
59
|
+
/** Set by `mountCapture`: renders one payload and resolves once it has painted. */
|
|
60
|
+
__forgeCapture?: {
|
|
61
|
+
render(payload: CapturePayload): Promise<void>;
|
|
62
|
+
};
|
|
63
|
+
}
|
|
31
64
|
}
|
|
32
|
-
|
|
33
65
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
66
|
+
* A capture page's entry: exposes `window.__forgeCapture.render(payload)`, which loads the payload's story, renders
|
|
67
|
+
* it afresh into `#root`, and resolves once it has painted. Rejects for a story the index does not hold, and with
|
|
68
|
+
* whatever throws outside the story's own error boundary.
|
|
36
69
|
*/
|
|
37
|
-
declare function
|
|
70
|
+
declare function mountCapture({ index, importers, setup, labTheme }: MountCaptureOptions): void;
|
|
38
71
|
|
|
39
|
-
export {
|
|
72
|
+
export { FrameImporters, FrameSetup, type MountCaptureOptions, mountCapture };
|
package/dist/frame/index.js
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
|
-
import { describeSchema, createKitRoot, openChannel,
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import '../chunk-
|
|
5
|
-
import '../chunk-
|
|
1
|
+
import { describeSchema, createKitRoot, openChannel, TITLE_LIBRARIES, LAB_DENSITY, answerSchema, IndexPage } from '../chunk-BUXUWAI4.js';
|
|
2
|
+
import { isIndexId, indexId } from '../chunk-STF6NQ5N.js';
|
|
3
|
+
import { taggedIds, isGallery } from '../chunk-VUPN73JP.js';
|
|
4
|
+
import { createOverrides, createGlobalsTarget, createA11yHighlighter, loadStories, indexRenderOf, scanCssVars, auditElement, runAxe, useHostConditions, useStoryClock, StoryHost, resolveCssVar } from '../chunk-35DOPXHZ.js';
|
|
5
|
+
import { ClockContext } from '../chunk-L5XM5VKB.js';
|
|
6
|
+
import '../chunk-5WS67HMU.js';
|
|
6
7
|
import '../chunk-KEQBGDUZ.js';
|
|
7
8
|
import { FRAME_HELLO, stableStringify, PORT_HANDOFF } from '../chunk-GH5RE5X5.js';
|
|
8
9
|
import { flushSync } from 'react-dom';
|
|
9
10
|
import { jsx } from 'react/jsx-runtime';
|
|
10
11
|
import { f } from '@weasel-js/labkit/config';
|
|
11
|
-
import { Component } from 'react';
|
|
12
|
+
import { Component, useState, useMemo, useLayoutEffect, useRef, useEffect } from 'react';
|
|
13
|
+
import { useLatest, useVisibleRaf } from '@weasel-js/core';
|
|
14
|
+
import { interstellarTheme, LabRoot } from '@weasel-js/labkit';
|
|
15
|
+
import { ThemeProvider } from '@weasel-js/theme/react';
|
|
16
|
+
import { OverlayPortalProvider } from '@weasel-js/ui/portal-host';
|
|
12
17
|
|
|
13
18
|
var VARS_SETTLE_MS = 100;
|
|
14
19
|
function fault(phase, error, seq) {
|
|
@@ -207,6 +212,7 @@ function startIndex(options) {
|
|
|
207
212
|
descriptions: options.descriptions,
|
|
208
213
|
gallery: options.gallery ?? false,
|
|
209
214
|
galleries: options.galleries ?? [],
|
|
215
|
+
labs: options.labs ?? [],
|
|
210
216
|
globals,
|
|
211
217
|
decorators: setup.decorators ?? [],
|
|
212
218
|
open: (id) => send({ type: "open", id }),
|
|
@@ -312,7 +318,7 @@ async function mountFrame(options) {
|
|
|
312
318
|
// The project's library table is the shell config's, which a frame document does not load.
|
|
313
319
|
library: TITLE_LIBRARIES.of({ file: entries[0]?.file ?? "", title }),
|
|
314
320
|
gallery: entries.every(isGallery),
|
|
315
|
-
|
|
321
|
+
...taggedIds(entries),
|
|
316
322
|
stories: stories2,
|
|
317
323
|
descriptions: Object.fromEntries(entries.flatMap((e) => e.description ? [[e.id, e.description]] : [])),
|
|
318
324
|
render: mods.map(indexRenderOf).find((render) => render !== null) ?? null,
|
|
@@ -334,7 +340,131 @@ async function mountFrame(options) {
|
|
|
334
340
|
reportImportFault(channel, error);
|
|
335
341
|
}
|
|
336
342
|
}
|
|
343
|
+
var HOST_ID = "capture";
|
|
344
|
+
var NO_WRITE = () => {
|
|
345
|
+
};
|
|
346
|
+
var boxStyle = ({ width, height }) => ({ ["--fg-capture-w"]: `${width}px`, ["--fg-capture-h"]: `${height}px` });
|
|
347
|
+
function scrollTo(host, { left, top }) {
|
|
348
|
+
const scroller = host?.querySelector(":scope > .fg-story__scroll");
|
|
349
|
+
if (!scroller) return;
|
|
350
|
+
scroller.scrollLeft = left;
|
|
351
|
+
scroller.scrollTop = top;
|
|
352
|
+
}
|
|
353
|
+
function CaptureView({ story, payload, setup, labTheme, onRendered }) {
|
|
354
|
+
const [host, setHost] = useState(null);
|
|
355
|
+
useHostConditions(host, { hostId: HOST_ID, globals: payload.globals, overrides: payload.overrides, setup });
|
|
356
|
+
const spec = useMemo(() => story.timeline?.(payload.config) ?? null, [story, payload.config]);
|
|
357
|
+
const clock = useStoryClock(spec, () => payload.playhead);
|
|
358
|
+
const state = useMemo(
|
|
359
|
+
() => payload.state === null && story.initialState ? story.initialState(payload.config) : payload.state,
|
|
360
|
+
[payload.state, payload.config, story]
|
|
361
|
+
);
|
|
362
|
+
const ctx = {
|
|
363
|
+
config: payload.config,
|
|
364
|
+
setConfig: NO_WRITE,
|
|
365
|
+
state,
|
|
366
|
+
setState: NO_WRITE,
|
|
367
|
+
globals: payload.globals,
|
|
368
|
+
title: story.title,
|
|
369
|
+
name: story.name
|
|
370
|
+
};
|
|
371
|
+
const latest = useLatest({ onRendered, host, scroll: payload.scroll });
|
|
372
|
+
useLayoutEffect(() => scrollTo(host, payload.scroll), [host, payload.scroll]);
|
|
373
|
+
const ticks = useRef(0);
|
|
374
|
+
const raf = useVisibleRaf(
|
|
375
|
+
(_now, loop) => {
|
|
376
|
+
ticks.current += 1;
|
|
377
|
+
scrollTo(latest.current.host, latest.current.scroll);
|
|
378
|
+
if (ticks.current < 2) loop.request();
|
|
379
|
+
else latest.current.onRendered();
|
|
380
|
+
},
|
|
381
|
+
{ dangerouslyRunWhenHidden: true }
|
|
382
|
+
);
|
|
383
|
+
useEffect(() => {
|
|
384
|
+
if (!host) return;
|
|
385
|
+
let canceled = false;
|
|
386
|
+
const start = () => {
|
|
387
|
+
if (!canceled) raf.request();
|
|
388
|
+
};
|
|
389
|
+
const { fonts } = host.ownerDocument;
|
|
390
|
+
if (fonts) void fonts.ready.then(start, start);
|
|
391
|
+
else start();
|
|
392
|
+
return () => {
|
|
393
|
+
canceled = true;
|
|
394
|
+
raf.cancel();
|
|
395
|
+
};
|
|
396
|
+
}, [host, raf]);
|
|
397
|
+
const content = host ? /* @__PURE__ */ jsx(ClockContext.Provider, { value: clock, children: /* @__PURE__ */ jsx(StoryHost, { story, ctx, decorators: setup.decorators ?? [], resetKey: 0, onError: NO_WRITE }) }) : null;
|
|
398
|
+
const box = /* @__PURE__ */ jsx(
|
|
399
|
+
"div",
|
|
400
|
+
{
|
|
401
|
+
ref: setHost,
|
|
402
|
+
className: "fg-story",
|
|
403
|
+
"data-fg-host": HOST_ID,
|
|
404
|
+
"data-fg-capture": "",
|
|
405
|
+
"data-fg-layout": payload.layout,
|
|
406
|
+
style: boxStyle(payload.box),
|
|
407
|
+
children: payload.isolate ? /* @__PURE__ */ jsx("div", { className: `fg-frame fg-frame--${payload.layout}`, children: content }) : /* @__PURE__ */ jsx("div", { className: "fg-story__scroll", children: host ? /* @__PURE__ */ jsx(OverlayPortalProvider, { container: host, contained: true, children: content }) : null })
|
|
408
|
+
}
|
|
409
|
+
);
|
|
410
|
+
if (payload.isolate) return box;
|
|
411
|
+
return /* @__PURE__ */ jsx(
|
|
412
|
+
ThemeProvider,
|
|
413
|
+
{
|
|
414
|
+
theme: labTheme?.(payload.lab.globals) ?? interstellarTheme,
|
|
415
|
+
selection: { mode: payload.lab.mode, density: LAB_DENSITY },
|
|
416
|
+
children: /* @__PURE__ */ jsx(LabRoot, { children: box })
|
|
417
|
+
}
|
|
418
|
+
);
|
|
419
|
+
}
|
|
420
|
+
var CaptureBoundary = class extends Component {
|
|
421
|
+
state = { failed: false };
|
|
422
|
+
static getDerivedStateFromError() {
|
|
423
|
+
return { failed: true };
|
|
424
|
+
}
|
|
425
|
+
componentDidCatch(error) {
|
|
426
|
+
this.props.onError(error);
|
|
427
|
+
}
|
|
428
|
+
render() {
|
|
429
|
+
return this.state.failed ? null : this.props.children;
|
|
430
|
+
}
|
|
431
|
+
};
|
|
432
|
+
function mountCapture({ index, importers, setup, labTheme }) {
|
|
433
|
+
const container = document.getElementById("root") ?? document.body;
|
|
434
|
+
const root = createKitRoot(container, setup.icons);
|
|
435
|
+
const prepared = /* @__PURE__ */ new Map();
|
|
436
|
+
let renders = 0;
|
|
437
|
+
const storyOf = (id) => {
|
|
438
|
+
let loading = prepared.get(id);
|
|
439
|
+
if (!loading) {
|
|
440
|
+
loading = (async () => {
|
|
441
|
+
const entry = index.find((e) => e.id === id);
|
|
442
|
+
if (!entry) throw new Error(`No story with id "${id}"`);
|
|
443
|
+
const importer = importers[entry.file];
|
|
444
|
+
if (!importer) throw new Error(`No importer for ${entry.file}`);
|
|
445
|
+
const story = loadStories(await importer(), entry.title, setup.parameters).find((s) => s.exportName === entry.exportName);
|
|
446
|
+
if (!story) throw new Error(`${entry.file} has no story export "${entry.exportName}"`);
|
|
447
|
+
await setup.prepare?.(story);
|
|
448
|
+
return story;
|
|
449
|
+
})();
|
|
450
|
+
prepared.set(id, loading);
|
|
451
|
+
loading.catch(() => prepared.delete(id));
|
|
452
|
+
}
|
|
453
|
+
return loading;
|
|
454
|
+
};
|
|
455
|
+
window.__forgeCapture = {
|
|
456
|
+
async render(payload) {
|
|
457
|
+
const story = await storyOf(payload.story);
|
|
458
|
+
renders += 1;
|
|
459
|
+
await new Promise((resolve, reject) => {
|
|
460
|
+
root.render(
|
|
461
|
+
/* @__PURE__ */ jsx(CaptureBoundary, { onError: reject, children: /* @__PURE__ */ jsx(CaptureView, { story, payload, setup, labTheme, onRendered: resolve }) }, renders)
|
|
462
|
+
);
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
};
|
|
466
|
+
}
|
|
337
467
|
|
|
338
|
-
export { mountFrame, reportImportFault, startFrame };
|
|
468
|
+
export { mountCapture, mountFrame, reportImportFault, startFrame };
|
|
339
469
|
//# sourceMappingURL=index.js.map
|
|
340
470
|
//# sourceMappingURL=index.js.map
|