@scaffold-ui-kit/preview 0.0.0-stage → 2.3.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/LICENSE +21 -0
- package/README.md +1868 -2
- package/application/host/bootstrap.ts +43 -0
- package/application/host/main.ts +31 -0
- package/application/host/shell-host.ts +47 -0
- package/application/index.html +12 -0
- package/application/lib/base-url.ts +15 -0
- package/application/lib/no-code-block.ts +7 -0
- package/application/lib/no-setup.ts +3 -0
- package/application/lib/no-views.ts +6 -0
- package/application/preview/code/code.html +12 -0
- package/application/preview/code/main.ts +89 -0
- package/application/preview/globals.ts +254 -0
- package/application/preview/html/main.ts +93 -0
- package/application/preview/html/preview.html +12 -0
- package/application/preview/react/main.tsx +146 -0
- package/application/preview/react/preview.html +12 -0
- package/application/preview/svelte/Preview.svelte +104 -0
- package/application/preview/svelte/main.ts +13 -0
- package/application/preview/svelte/preview.html +12 -0
- package/application/preview/svelte/story-props.ts +172 -0
- package/application/preview/view/main.ts +124 -0
- package/application/preview/view/view.html +12 -0
- package/application/preview/vue/main.ts +145 -0
- package/application/preview/vue/preview.html +12 -0
- package/application/shells/charcell/components/Application/index.css +37 -0
- package/application/shells/charcell/components/Application/index.tsx +65 -0
- package/application/shells/charcell/components/Bar/index.css +68 -0
- package/application/shells/charcell/components/Bar/index.tsx +60 -0
- package/application/shells/charcell/components/CodePane/index.css +60 -0
- package/application/shells/charcell/components/CodePane/index.tsx +113 -0
- package/application/shells/charcell/components/ComponentStage/index.css +26 -0
- package/application/shells/charcell/components/ComponentStage/index.tsx +110 -0
- package/application/shells/charcell/components/Control/index.css +20 -0
- package/application/shells/charcell/components/Control/index.tsx +118 -0
- package/application/shells/charcell/components/CopyLink/index.tsx +35 -0
- package/application/shells/charcell/components/Description/index.css +6 -0
- package/application/shells/charcell/components/Description/index.tsx +24 -0
- package/application/shells/charcell/components/EditorAddDialog/index.css +9 -0
- package/application/shells/charcell/components/EditorAddDialog/index.tsx +158 -0
- package/application/shells/charcell/components/EditorPanel/index.css +48 -0
- package/application/shells/charcell/components/EditorPanel/index.tsx +496 -0
- package/application/shells/charcell/components/EventsRow/index.css +42 -0
- package/application/shells/charcell/components/EventsRow/index.tsx +68 -0
- package/application/shells/charcell/components/HeadingRow/index.css +11 -0
- package/application/shells/charcell/components/HeadingRow/index.tsx +16 -0
- package/application/shells/charcell/components/Hint/index.css +16 -0
- package/application/shells/charcell/components/Hint/index.tsx +81 -0
- package/application/shells/charcell/components/HtmlWarnings/index.tsx +45 -0
- package/application/shells/charcell/components/KeyHints/index.css +27 -0
- package/application/shells/charcell/components/KeyHints/index.tsx +106 -0
- package/application/shells/charcell/components/KitCodeBlock/index.css +55 -0
- package/application/shells/charcell/components/KitCodeBlock/index.tsx +18 -0
- package/application/shells/charcell/components/Markdown/index.tsx +16 -0
- package/application/shells/charcell/components/Navigation/index.css +13 -0
- package/application/shells/charcell/components/Navigation/index.tsx +98 -0
- package/application/shells/charcell/components/NavigationSplit/index.css +16 -0
- package/application/shells/charcell/components/NavigationSplit/index.tsx +82 -0
- package/application/shells/charcell/components/OptionControls/index.tsx +93 -0
- package/application/shells/charcell/components/PaneStatus/index.css +7 -0
- package/application/shells/charcell/components/PaneStatus/index.tsx +47 -0
- package/application/shells/charcell/components/PaneWidth/index.tsx +45 -0
- package/application/shells/charcell/components/PreviewGrid/index.css +39 -0
- package/application/shells/charcell/components/PreviewGrid/index.tsx +344 -0
- package/application/shells/charcell/components/PreviewPane/index.css +127 -0
- package/application/shells/charcell/components/PreviewPane/index.tsx +182 -0
- package/application/shells/charcell/components/PromptBar/index.tsx +133 -0
- package/application/shells/charcell/components/ScenarioRow/index.css +36 -0
- package/application/shells/charcell/components/ScenarioRow/index.tsx +71 -0
- package/application/shells/charcell/components/Select/index.tsx +48 -0
- package/application/shells/charcell/components/SlotOutlet/index.css +7 -0
- package/application/shells/charcell/components/SlotOutlet/index.tsx +25 -0
- package/application/shells/charcell/components/StageBar/index.css +7 -0
- package/application/shells/charcell/components/StageBar/index.tsx +109 -0
- package/application/shells/charcell/components/StageSplit/index.css +11 -0
- package/application/shells/charcell/components/StageSplit/index.tsx +99 -0
- package/application/shells/charcell/components/StatusBar/index.tsx +30 -0
- package/application/shells/charcell/components/ViewControls/index.css +15 -0
- package/application/shells/charcell/components/ViewControls/index.tsx +58 -0
- package/application/shells/charcell/components/ViewHeading/index.css +13 -0
- package/application/shells/charcell/components/ViewHeading/index.tsx +8 -0
- package/application/shells/charcell/components/ViewStage/index.css +9 -0
- package/application/shells/charcell/components/ViewStage/index.tsx +25 -0
- package/application/shells/charcell/components/WrapToggle/index.tsx +27 -0
- package/application/shells/charcell/configuration.ts +45 -0
- package/application/shells/charcell/controller-context.ts +27 -0
- package/application/shells/charcell/fit-labels.ts +42 -0
- package/application/shells/charcell/html-warnings.ts +18 -0
- package/application/shells/charcell/index.tsx +82 -0
- package/application/shells/charcell/page-loading.html +57 -0
- package/application/shells/charcell/placement.ts +24 -0
- package/application/shells/charcell/shell-options.ts +23 -0
- package/application/shells/charcell/shell.css +37 -0
- package/application/shells/charcell/shell.tsx +25 -0
- package/application/shells/charcell/split-reset.ts +47 -0
- package/application/shells/charcell/stacked-rows.ts +117 -0
- package/application/shells/charcell/stage-toggles.ts +93 -0
- package/application/types/manifest.d.ts +6 -0
- package/application/types/preview-configuration.d.ts +10 -0
- package/application/types/preview-shell.d.ts +7 -0
- package/application/types/react-registry.d.ts +15 -0
- package/application/types/vue-registry.d.ts +6 -0
- package/dist/build.d.ts +24 -0
- package/dist/build.js +34 -0
- package/dist/check.d.ts +48 -0
- package/dist/check.js +781 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +88 -0
- package/dist/context.d.ts +179 -0
- package/dist/context.js +783 -0
- package/dist/controller/catalog.d.ts +339 -0
- package/dist/controller/catalog.js +367 -0
- package/dist/controller/create-preview-controller.d.ts +532 -0
- package/dist/controller/create-preview-controller.js +1707 -0
- package/dist/controller/editor-tree.d.ts +161 -0
- package/dist/controller/editor-tree.js +373 -0
- package/dist/controller/html-source.d.ts +62 -0
- package/dist/controller/html-source.js +61 -0
- package/dist/controller/index.d.ts +9 -0
- package/dist/controller/index.js +12 -0
- package/dist/controller/persistence.d.ts +191 -0
- package/dist/controller/persistence.js +315 -0
- package/dist/controller/regeneration.d.ts +30 -0
- package/dist/controller/regeneration.js +27 -0
- package/dist/controller/source.d.ts +80 -0
- package/dist/controller/source.js +236 -0
- package/dist/controller/store.d.ts +27 -0
- package/dist/controller/store.js +40 -0
- package/dist/declarations/application/shells/charcell/components/Application/index.d.ts +2 -0
- package/dist/declarations/application/shells/charcell/components/Bar/index.d.ts +11 -0
- package/dist/declarations/application/shells/charcell/components/CodePane/index.d.ts +5 -0
- package/dist/declarations/application/shells/charcell/components/ComponentStage/index.d.ts +2 -0
- package/dist/declarations/application/shells/charcell/components/Control/index.d.ts +9 -0
- package/dist/declarations/application/shells/charcell/components/CopyLink/index.d.ts +1 -0
- package/dist/declarations/application/shells/charcell/components/Description/index.d.ts +5 -0
- package/dist/declarations/application/shells/charcell/components/EditorAddDialog/index.d.ts +6 -0
- package/dist/declarations/application/shells/charcell/components/EditorPanel/index.d.ts +2 -0
- package/dist/declarations/application/shells/charcell/components/EventsRow/index.d.ts +4 -0
- package/dist/declarations/application/shells/charcell/components/HeadingRow/index.d.ts +6 -0
- package/dist/declarations/application/shells/charcell/components/Hint/index.d.ts +11 -0
- package/dist/declarations/application/shells/charcell/components/HtmlWarnings/index.d.ts +5 -0
- package/dist/declarations/application/shells/charcell/components/KeyHints/index.d.ts +2 -0
- package/dist/declarations/application/shells/charcell/components/KitCodeBlock/index.d.ts +5 -0
- package/dist/declarations/application/shells/charcell/components/Markdown/index.d.ts +3 -0
- package/dist/declarations/application/shells/charcell/components/Navigation/index.d.ts +8 -0
- package/dist/declarations/application/shells/charcell/components/NavigationSplit/index.d.ts +7 -0
- package/dist/declarations/application/shells/charcell/components/OptionControls/index.d.ts +7 -0
- package/dist/declarations/application/shells/charcell/components/PaneStatus/index.d.ts +2 -0
- package/dist/declarations/application/shells/charcell/components/PaneWidth/index.d.ts +4 -0
- package/dist/declarations/application/shells/charcell/components/PreviewGrid/index.d.ts +7 -0
- package/dist/declarations/application/shells/charcell/components/PreviewPane/index.d.ts +9 -0
- package/dist/declarations/application/shells/charcell/components/PromptBar/index.d.ts +1 -0
- package/dist/declarations/application/shells/charcell/components/ScenarioRow/index.d.ts +2 -0
- package/dist/declarations/application/shells/charcell/components/Select/index.d.ts +16 -0
- package/dist/declarations/application/shells/charcell/components/SlotOutlet/index.d.ts +5 -0
- package/dist/declarations/application/shells/charcell/components/StageBar/index.d.ts +2 -0
- package/dist/declarations/application/shells/charcell/components/StageSplit/index.d.ts +17 -0
- package/dist/declarations/application/shells/charcell/components/StatusBar/index.d.ts +1 -0
- package/dist/declarations/application/shells/charcell/components/ViewControls/index.d.ts +9 -0
- package/dist/declarations/application/shells/charcell/components/ViewHeading/index.d.ts +4 -0
- package/dist/declarations/application/shells/charcell/components/ViewStage/index.d.ts +4 -0
- package/dist/declarations/application/shells/charcell/components/WrapToggle/index.d.ts +1 -0
- package/dist/declarations/application/shells/charcell/configuration.d.ts +31 -0
- package/dist/declarations/application/shells/charcell/controller-context.d.ts +9 -0
- package/dist/declarations/application/shells/charcell/fit-labels.d.ts +18 -0
- package/dist/declarations/application/shells/charcell/html-warnings.d.ts +5 -0
- package/dist/declarations/application/shells/charcell/index.d.ts +39 -0
- package/dist/declarations/application/shells/charcell/placement.d.ts +7 -0
- package/dist/declarations/application/shells/charcell/shell-options.d.ts +15 -0
- package/dist/declarations/application/shells/charcell/shell.d.ts +9 -0
- package/dist/declarations/application/shells/charcell/split-reset.d.ts +30 -0
- package/dist/declarations/application/shells/charcell/stacked-rows.d.ts +58 -0
- package/dist/declarations/application/shells/charcell/stage-toggles.d.ts +28 -0
- package/dist/declarations/src/controller/catalog.d.ts +339 -0
- package/dist/declarations/src/controller/create-preview-controller.d.ts +532 -0
- package/dist/declarations/src/controller/editor-tree.d.ts +161 -0
- package/dist/declarations/src/controller/html-source.d.ts +62 -0
- package/dist/declarations/src/controller/index.d.ts +9 -0
- package/dist/declarations/src/controller/persistence.d.ts +191 -0
- package/dist/declarations/src/controller/regeneration.d.ts +30 -0
- package/dist/declarations/src/controller/source.d.ts +80 -0
- package/dist/declarations/src/controller/store.d.ts +27 -0
- package/dist/declarations/src/emit/common.d.ts +103 -0
- package/dist/declarations/src/emit/manifest.d.ts +138 -0
- package/dist/declarations/src/emit/source.d.ts +87 -0
- package/dist/declarations/src/lib/jsx-roots.d.ts +22 -0
- package/dist/declarations/src/lib/module-of-source.d.ts +18 -0
- package/dist/declarations/src/lib/naming.d.ts +29 -0
- package/dist/declarations/src/lib/react-spelling.d.ts +68 -0
- package/dist/declarations/src/lib/scenario-story.d.ts +41 -0
- package/dist/declarations/src/lib/slot-fill.d.ts +15 -0
- package/dist/declarations/src/lib/types.d.ts +741 -0
- package/dist/declarations/src/options.d.ts +224 -0
- package/dist/declarations/src/protocol.d.ts +541 -0
- package/dist/declarations/src/react-view.d.ts +22 -0
- package/dist/declarations/src/react.d.ts +17 -0
- package/dist/declarations/src/shell.d.ts +99 -0
- package/dist/declarations/src/views.d.ts +152 -0
- package/dist/development-server.d.ts +121 -0
- package/dist/development-server.js +331 -0
- package/dist/emit/common.d.ts +103 -0
- package/dist/emit/common.js +170 -0
- package/dist/emit/html-source.d.ts +46 -0
- package/dist/emit/html-source.js +322 -0
- package/dist/emit/manifest.d.ts +138 -0
- package/dist/emit/manifest.js +74 -0
- package/dist/emit/react.d.ts +16 -0
- package/dist/emit/react.js +210 -0
- package/dist/emit/scratch.d.ts +40 -0
- package/dist/emit/scratch.js +116 -0
- package/dist/emit/source.d.ts +87 -0
- package/dist/emit/source.js +789 -0
- package/dist/emit/svelte.d.ts +9 -0
- package/dist/emit/svelte.js +177 -0
- package/dist/emit/vue.d.ts +2 -0
- package/dist/emit/vue.js +152 -0
- package/dist/enumerate.d.ts +2 -0
- package/dist/enumerate.js +162 -0
- package/dist/generate.d.ts +43 -0
- package/dist/generate.js +302 -0
- package/dist/html-stylesheet.d.ts +43 -0
- package/dist/html-stylesheet.js +145 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +21 -0
- package/dist/landing.d.ts +16 -0
- package/dist/landing.js +45 -0
- package/dist/lib/exported-types.d.ts +42 -0
- package/dist/lib/exported-types.js +86 -0
- package/dist/lib/html-attributes.d.ts +2 -0
- package/dist/lib/html-attributes.js +111 -0
- package/dist/lib/html-warnings.d.ts +19 -0
- package/dist/lib/html-warnings.js +79 -0
- package/dist/lib/jsx-roots.d.ts +22 -0
- package/dist/lib/jsx-roots.js +243 -0
- package/dist/lib/module-of-source.d.ts +18 -0
- package/dist/lib/module-of-source.js +24 -0
- package/dist/lib/naming.d.ts +29 -0
- package/dist/lib/naming.js +56 -0
- package/dist/lib/parse-type.d.ts +32 -0
- package/dist/lib/parse-type.js +103 -0
- package/dist/lib/react-spelling.d.ts +68 -0
- package/dist/lib/react-spelling.js +197 -0
- package/dist/lib/scenario-story.d.ts +41 -0
- package/dist/lib/scenario-story.js +84 -0
- package/dist/lib/slot-fill.d.ts +15 -0
- package/dist/lib/slot-fill.js +92 -0
- package/dist/lib/template-files.d.ts +14 -0
- package/dist/lib/template-files.js +25 -0
- package/dist/lib/types.d.ts +741 -0
- package/dist/lib/types.js +13 -0
- package/dist/lib/void-elements.d.ts +7 -0
- package/dist/lib/void-elements.js +13 -0
- package/dist/load.d.ts +37 -0
- package/dist/load.js +82 -0
- package/dist/model.d.ts +44 -0
- package/dist/model.js +464 -0
- package/dist/options.d.ts +224 -0
- package/dist/options.js +223 -0
- package/dist/prop-types.d.ts +26 -0
- package/dist/prop-types.js +102 -0
- package/dist/props-from.d.ts +84 -0
- package/dist/props-from.js +510 -0
- package/dist/protocol.d.ts +541 -0
- package/dist/protocol.js +819 -0
- package/dist/react-view.d.ts +22 -0
- package/dist/react-view.js +36 -0
- package/dist/react.d.ts +17 -0
- package/dist/react.js +23 -0
- package/dist/sass-importers.d.ts +26 -0
- package/dist/sass-importers.js +32 -0
- package/dist/shell-acceptance.d.ts +21 -0
- package/dist/shell-acceptance.js +37 -0
- package/dist/shell-page.d.ts +36 -0
- package/dist/shell-page.js +90 -0
- package/dist/shell-peers.d.ts +38 -0
- package/dist/shell-peers.js +61 -0
- package/dist/shell.d.ts +99 -0
- package/dist/shell.js +52 -0
- package/dist/shells/charcell/page.d.ts +8 -0
- package/dist/shells/charcell/page.js +69 -0
- package/dist/story-source.d.ts +113 -0
- package/dist/story-source.js +271 -0
- package/dist/story.d.ts +5 -0
- package/dist/story.js +28 -0
- package/dist/testing.d.ts +218 -0
- package/dist/testing.js +284 -0
- package/dist/views.d.ts +152 -0
- package/dist/views.js +7 -0
- package/dist/vite-configuration.d.ts +114 -0
- package/dist/vite-configuration.js +578 -0
- package/package.json +123 -3
- package/src/build.ts +51 -0
- package/src/check.ts +1062 -0
- package/src/cli.ts +123 -0
- package/src/context.ts +1168 -0
- package/src/controller/catalog.ts +719 -0
- package/src/controller/create-preview-controller.ts +2683 -0
- package/src/controller/editor-tree.ts +530 -0
- package/src/controller/html-source.ts +114 -0
- package/src/controller/index.ts +105 -0
- package/src/controller/persistence.ts +403 -0
- package/src/controller/regeneration.ts +55 -0
- package/src/controller/source.ts +333 -0
- package/src/controller/store.ts +55 -0
- package/src/development-server.ts +442 -0
- package/src/emit/common.ts +201 -0
- package/src/emit/html-source.ts +402 -0
- package/src/emit/manifest.ts +241 -0
- package/src/emit/react.ts +263 -0
- package/src/emit/scratch.ts +175 -0
- package/src/emit/source.ts +1094 -0
- package/src/emit/svelte.ts +230 -0
- package/src/emit/vue.ts +194 -0
- package/src/enumerate.ts +220 -0
- package/src/generate.ts +443 -0
- package/src/html-stylesheet.ts +173 -0
- package/src/index.ts +60 -0
- package/src/landing.ts +58 -0
- package/src/lib/exported-types.ts +114 -0
- package/src/lib/html-attributes.ts +113 -0
- package/src/lib/html-warnings.ts +81 -0
- package/src/lib/jsx-roots.ts +238 -0
- package/src/lib/module-of-source.ts +26 -0
- package/src/lib/naming.ts +65 -0
- package/src/lib/parse-type.ts +143 -0
- package/src/lib/react-spelling.ts +235 -0
- package/src/lib/scenario-story.ts +97 -0
- package/src/lib/slot-fill.ts +102 -0
- package/src/lib/template-files.ts +31 -0
- package/src/lib/types.ts +778 -0
- package/src/lib/void-elements.ts +15 -0
- package/src/load.ts +144 -0
- package/src/model.ts +568 -0
- package/src/options.ts +435 -0
- package/src/prop-types.ts +133 -0
- package/src/props-from.ts +678 -0
- package/src/protocol.ts +1135 -0
- package/src/react-view.ts +45 -0
- package/src/react.ts +34 -0
- package/src/sass-importers.ts +45 -0
- package/src/shell-acceptance.ts +45 -0
- package/src/shell-page.ts +133 -0
- package/src/shell-peers.ts +70 -0
- package/src/shell.ts +194 -0
- package/src/shells/charcell/page.ts +82 -0
- package/src/story-source.ts +391 -0
- package/src/story.ts +42 -0
- package/src/testing.ts +497 -0
- package/src/views.ts +183 -0
- package/src/vite-configuration.ts +675 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// The charcell shell's page: what the host page shows before the shell's
|
|
2
|
+
// script has loaded. charcell's dark ground paints from the first frame, the
|
|
3
|
+
// upright face is declared and its font preloaded, and the root holds the
|
|
4
|
+
// loading note the shell mounts over.
|
|
5
|
+
import { readFileSync } from 'node:fs';
|
|
6
|
+
import { createRequire } from 'node:module';
|
|
7
|
+
import { dirname, resolve } from 'node:path';
|
|
8
|
+
import { fileURLToPath } from 'node:url';
|
|
9
|
+
import { defineShellPage } from '../../shell.js';
|
|
10
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
/** The loading note and its styles, kept beside the shell. */
|
|
12
|
+
const loadingNote = resolve(here, '../../../application/shells/charcell/page-loading.html');
|
|
13
|
+
/**
|
|
14
|
+
* charcell's upright face, as its base stylesheet declares it.
|
|
15
|
+
*
|
|
16
|
+
* @returns The `@font-face` rule, the address it gives the font file, and
|
|
17
|
+
* the file's absolute path; or nothing when charcell or the rule cannot be
|
|
18
|
+
* found.
|
|
19
|
+
*/
|
|
20
|
+
function uprightFace() {
|
|
21
|
+
let stylesheet;
|
|
22
|
+
let source;
|
|
23
|
+
try {
|
|
24
|
+
stylesheet = createRequire(import.meta.url).resolve('charcell/css/base');
|
|
25
|
+
source = readFileSync(stylesheet, 'utf8');
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
const rule = (source.match(/@font-face\s*\{[^}]*\}/g) ?? []).find((face) => /font-style:\s*normal/.test(face));
|
|
31
|
+
const address = rule?.match(/url\((["']?)([^"')]+)\1\)/)?.[2];
|
|
32
|
+
// Only a font file beside the stylesheet: an address of another kind, a
|
|
33
|
+
// data address or one with a query, names no file to preload.
|
|
34
|
+
if (rule === undefined ||
|
|
35
|
+
address === undefined ||
|
|
36
|
+
!/^\.{0,2}\/?[\w./-]+\.woff2$/.test(address)) {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
return { rule, address, file: resolve(dirname(stylesheet), address) };
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The charcell shell's page: charcell's dark ground and its face in the
|
|
43
|
+
* head, the font preloaded, and the loading note in the root. A kit that
|
|
44
|
+
* names the charcell shell as it is gets it without naming it; a module of
|
|
45
|
+
* the kit's that configures the shell names it as `preview.shell.page`.
|
|
46
|
+
*/
|
|
47
|
+
export default defineShellPage({
|
|
48
|
+
head({ asset }) {
|
|
49
|
+
// The ground sits in the first, lowest cascade layer, so charcell's own
|
|
50
|
+
// page rule and a kit's overrides win once they load.
|
|
51
|
+
const ground = '<style>@layer { html { color-scheme: dark; background: #000000; } }</style>';
|
|
52
|
+
const face = uprightFace();
|
|
53
|
+
if (face === undefined)
|
|
54
|
+
return ground;
|
|
55
|
+
const font = asset(face.file);
|
|
56
|
+
// The face as charcell declares it, except that text waits for the font
|
|
57
|
+
// rather than showing in another face first: the loading note appears in
|
|
58
|
+
// the face the shell's text has, on the same cells.
|
|
59
|
+
const rule = face.rule
|
|
60
|
+
.replace(face.address, () => font)
|
|
61
|
+
.replace(/font-display:\s*[a-z]+/, 'font-display:block');
|
|
62
|
+
return [
|
|
63
|
+
ground,
|
|
64
|
+
`<link rel="preload" as="font" type="font/woff2" crossorigin href="${font}" />`,
|
|
65
|
+
`<style>${rule}</style>`,
|
|
66
|
+
].join('\n');
|
|
67
|
+
},
|
|
68
|
+
root: () => readFileSync(loadingNote, 'utf8'),
|
|
69
|
+
});
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import type { ConfigurationLookupOptions } from 'scaffold-ui-kit';
|
|
2
|
+
import { type PreviewContext } from './context.js';
|
|
3
|
+
import { type HtmlSourceResult } from './emit/html-source.js';
|
|
4
|
+
import type { EnumeratedComponent, JsonValue, Story, SlotFill, StoryAround, ResolvedStory, Target } from './lib/types.js';
|
|
5
|
+
/** What `storySource` prints: a framework's source, or the rendered markup. */
|
|
6
|
+
export type SourceTarget = Target | 'html';
|
|
7
|
+
/**
|
|
8
|
+
* What `storySource` returns: the source per target, and, when the `html`
|
|
9
|
+
* leaves something out, the warnings naming it.
|
|
10
|
+
*/
|
|
11
|
+
export type StorySource = Partial<Record<SourceTarget, string>> & {
|
|
12
|
+
/** What the `html` could not work out at rest and left out, such as an
|
|
13
|
+
* expression reading the component's script state; the markup shows that
|
|
14
|
+
* part at a default. Absent when there is nothing to name. */
|
|
15
|
+
htmlWarnings?: string[];
|
|
16
|
+
};
|
|
17
|
+
export interface StorySourceOptions extends ConfigurationLookupOptions {
|
|
18
|
+
/** A scenario id (curated or generated); its props apply over the story's. */
|
|
19
|
+
scenario?: string;
|
|
20
|
+
/** The targets to print. Defaults to every target the component renders
|
|
21
|
+
* into, and `html`. */
|
|
22
|
+
targets?: SourceTarget[];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Prints a component's story as the source a consumer would write per target:
|
|
26
|
+
* a React component, a Vue single-file component, a Svelte component. Imports
|
|
27
|
+
* name the kit's package entry for each target (`<package>/react`); props are
|
|
28
|
+
* those the story file sets (`defaultProps`, `fixed`) and the scenario's, leaving
|
|
29
|
+
* out values equal to the template's declared default. A default slot the
|
|
30
|
+
* story leaves unfilled prints no content. A two-way prop the story gives
|
|
31
|
+
* is bound to state of the source's own, as a consumer controls
|
|
32
|
+
* it: React's `useState` with the value and the change prop, Vue's `v-model`
|
|
33
|
+
* or `v-model:<prop>`, Svelte's `bind:<prop>` on `$state` in runes mode or a
|
|
34
|
+
* plain `let` in legacy mode, as the kit builds Svelte, its state typed by
|
|
35
|
+
* the prop's declared type where that names types the kit's package entry
|
|
36
|
+
* exports, imported from it. The prop its value starts from otherwise (its
|
|
37
|
+
* default prop) is left out, as is a prop the scenario gives `null`, unless
|
|
38
|
+
* it is a two-way prop the source binds. The `html` is the markup at the
|
|
39
|
+
* given value.
|
|
40
|
+
*
|
|
41
|
+
* `html` is the markup the story renders to, at rest: the template rendered
|
|
42
|
+
* once for those props and slot content, components it references rendered
|
|
43
|
+
* inline, and assumes the kit's stylesheet. A component written by hand
|
|
44
|
+
* renders as `handWrittenComponents` maps it - its content, or the template
|
|
45
|
+
* it renders - inside one comment saying its behavior is not included, and
|
|
46
|
+
* slot content written per framework renders its `html`. A story with any
|
|
47
|
+
* other part that has no markup gets no `html`, with a warning naming it.
|
|
48
|
+
* What the markup cannot work out at rest, such as an expression reading the
|
|
49
|
+
* component's script state, is left out, shows at a default, and is named
|
|
50
|
+
* once in `htmlWarnings` and a printed warning.
|
|
51
|
+
*
|
|
52
|
+
* @param kitRoot - The kit root (where its package.json lives)
|
|
53
|
+
* @param componentName - The component, by name
|
|
54
|
+
* @param options - The scenario and the targets to print, and the kit
|
|
55
|
+
* configuration file when it is not the one the kit root gives
|
|
56
|
+
* @returns The source per target, and the html's warnings
|
|
57
|
+
* @example
|
|
58
|
+
* ```ts
|
|
59
|
+
* const { react } = await storySource(kitRoot, 'Button', { scenario: 'variant-dense' });
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export declare function storySource(kitRoot: string, componentName: string, options?: StorySourceOptions): Promise<StorySource>;
|
|
63
|
+
/** A story as its source prints it: the props a consumer writes and its slot content. */
|
|
64
|
+
export interface SourceStoryContent {
|
|
65
|
+
props: Record<string, JsonValue>;
|
|
66
|
+
children?: SlotFill;
|
|
67
|
+
named: Record<string, SlotFill>;
|
|
68
|
+
/** The content beside the component, as its siblings. */
|
|
69
|
+
around?: StoryAround;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* What a story's source prints for a scenario's props: the props the story file
|
|
73
|
+
* sets (`defaultProps`, `fixed`) and the scenario's, less those equal to the
|
|
74
|
+
* component's declared default, and the story file's slot content, or its
|
|
75
|
+
* `children` text where it curates none. A default slot the story leaves
|
|
76
|
+
* unfilled prints no content: the component's name the preview shows there
|
|
77
|
+
* is the preview's own, which a consumer never writes, unless `placeholder`
|
|
78
|
+
* asks for it, as the html the panes render does.
|
|
79
|
+
*
|
|
80
|
+
* @param component - The component.
|
|
81
|
+
* @param story - Its story file, when it has one.
|
|
82
|
+
* @param model - Its resolved story.
|
|
83
|
+
* @param scenarioProps - The scenario's props.
|
|
84
|
+
* @param options - `placeholder` keeps the preview's text in an unfilled default slot.
|
|
85
|
+
* @returns The props and slot content to print.
|
|
86
|
+
*/
|
|
87
|
+
export declare function sourceStoryOf(component: EnumeratedComponent, story: Story | undefined, model: ResolvedStory, scenarioProps: Record<string, JsonValue>, options?: {
|
|
88
|
+
placeholder?: boolean;
|
|
89
|
+
}): SourceStoryContent;
|
|
90
|
+
/**
|
|
91
|
+
* The lines that report what a story's html leaves out, once per story: a
|
|
92
|
+
* heading, then each evaluation warning indented on a line of its own, a
|
|
93
|
+
* warning about the story's own component without its name, and the
|
|
94
|
+
* warnings one component gives for one reason as a single line counting
|
|
95
|
+
* them (see `summarizeHtmlWarnings`).
|
|
96
|
+
*
|
|
97
|
+
* @param componentName - The story's component.
|
|
98
|
+
* @param warnings - The expressions the html could not evaluate at rest.
|
|
99
|
+
* @returns The lines, joined, without a prefix.
|
|
100
|
+
*/
|
|
101
|
+
export declare function htmlWarningLine(componentName: string, warnings: readonly string[]): string;
|
|
102
|
+
/**
|
|
103
|
+
* Renders a story to the markup it shows at rest, with the kit's shared
|
|
104
|
+
* modules in scope and its styling, as `storySource`'s `html` does.
|
|
105
|
+
*
|
|
106
|
+
* @param context - The kit's preview context.
|
|
107
|
+
* @param components - Every component of the kit.
|
|
108
|
+
* @param story - The component, its props and its slot content.
|
|
109
|
+
* @returns The markup, or what the story holds that has none.
|
|
110
|
+
*/
|
|
111
|
+
export declare function printHtmlSource(context: PreviewContext, components: readonly EnumeratedComponent[], story: SourceStoryContent & {
|
|
112
|
+
component: EnumeratedComponent;
|
|
113
|
+
}): Promise<HtmlSourceResult>;
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
// A story as consumer source per target, for a kit's docs: the component,
|
|
2
|
+
// the props its story file curates (and a scenario's), and its slot content,
|
|
3
|
+
// importing from the kit's package entry for each target - and the markup the
|
|
4
|
+
// story renders to, as html. Read from the same story files the preview renders,
|
|
5
|
+
// so the snippets follow them.
|
|
6
|
+
import { REACT_ATTRIBUTE_NAMES } from '@js-template-engine/extension-react';
|
|
7
|
+
import { loadPreviewContext } from './context.js';
|
|
8
|
+
import { loadKit } from './load.js';
|
|
9
|
+
import { storyOnScenario } from './lib/scenario-story.js';
|
|
10
|
+
import { resolveStory } from './model.js';
|
|
11
|
+
import { declaredAttributes } from './lib/react-spelling.js';
|
|
12
|
+
import { moduleOfSource } from './lib/module-of-source.js';
|
|
13
|
+
import { htmlSource } from './emit/html-source.js';
|
|
14
|
+
import { inDeclarationOrder, SOURCE_PRINTERS, } from './emit/source.js';
|
|
15
|
+
import { exportedTypesOf } from './lib/exported-types.js';
|
|
16
|
+
import { summarizeHtmlWarnings } from './lib/html-warnings.js';
|
|
17
|
+
/**
|
|
18
|
+
* Prints a component's story as the source a consumer would write per target:
|
|
19
|
+
* a React component, a Vue single-file component, a Svelte component. Imports
|
|
20
|
+
* name the kit's package entry for each target (`<package>/react`); props are
|
|
21
|
+
* those the story file sets (`defaultProps`, `fixed`) and the scenario's, leaving
|
|
22
|
+
* out values equal to the template's declared default. A default slot the
|
|
23
|
+
* story leaves unfilled prints no content. A two-way prop the story gives
|
|
24
|
+
* is bound to state of the source's own, as a consumer controls
|
|
25
|
+
* it: React's `useState` with the value and the change prop, Vue's `v-model`
|
|
26
|
+
* or `v-model:<prop>`, Svelte's `bind:<prop>` on `$state` in runes mode or a
|
|
27
|
+
* plain `let` in legacy mode, as the kit builds Svelte, its state typed by
|
|
28
|
+
* the prop's declared type where that names types the kit's package entry
|
|
29
|
+
* exports, imported from it. The prop its value starts from otherwise (its
|
|
30
|
+
* default prop) is left out, as is a prop the scenario gives `null`, unless
|
|
31
|
+
* it is a two-way prop the source binds. The `html` is the markup at the
|
|
32
|
+
* given value.
|
|
33
|
+
*
|
|
34
|
+
* `html` is the markup the story renders to, at rest: the template rendered
|
|
35
|
+
* once for those props and slot content, components it references rendered
|
|
36
|
+
* inline, and assumes the kit's stylesheet. A component written by hand
|
|
37
|
+
* renders as `handWrittenComponents` maps it - its content, or the template
|
|
38
|
+
* it renders - inside one comment saying its behavior is not included, and
|
|
39
|
+
* slot content written per framework renders its `html`. A story with any
|
|
40
|
+
* other part that has no markup gets no `html`, with a warning naming it.
|
|
41
|
+
* What the markup cannot work out at rest, such as an expression reading the
|
|
42
|
+
* component's script state, is left out, shows at a default, and is named
|
|
43
|
+
* once in `htmlWarnings` and a printed warning.
|
|
44
|
+
*
|
|
45
|
+
* @param kitRoot - The kit root (where its package.json lives)
|
|
46
|
+
* @param componentName - The component, by name
|
|
47
|
+
* @param options - The scenario and the targets to print, and the kit
|
|
48
|
+
* configuration file when it is not the one the kit root gives
|
|
49
|
+
* @returns The source per target, and the html's warnings
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* const { react } = await storySource(kitRoot, 'Button', { scenario: 'variant-dense' });
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export async function storySource(kitRoot, componentName, options = {}) {
|
|
56
|
+
const context = loadPreviewContext(kitRoot, {
|
|
57
|
+
configuration: options.configuration,
|
|
58
|
+
workingDirectory: options.workingDirectory,
|
|
59
|
+
});
|
|
60
|
+
const { components } = await loadKit(context);
|
|
61
|
+
const loaded = components.find((entry) => entry.component.name === componentName);
|
|
62
|
+
if (!loaded) {
|
|
63
|
+
throw new Error(`[preview] no component named ${componentName} in ${kitRoot}`);
|
|
64
|
+
}
|
|
65
|
+
const { component, story } = loaded;
|
|
66
|
+
const model = resolveStory(component, story, context.configuration.controlHints ?? {}, context.configuration.labels, context.omitPattern, context.targets);
|
|
67
|
+
let scenarioProps = {};
|
|
68
|
+
let scenario;
|
|
69
|
+
if (options.scenario !== undefined) {
|
|
70
|
+
scenario = model.scenarios.find((entry) => entry.id === options.scenario);
|
|
71
|
+
if (!scenario) {
|
|
72
|
+
throw new Error(`[preview] ${componentName} has no scenario '${options.scenario}'; it has ${model.scenarios.map((entry) => `'${entry.id}'`).join(', ') || 'none'}`);
|
|
73
|
+
}
|
|
74
|
+
scenarioProps = scenario.props ?? {};
|
|
75
|
+
}
|
|
76
|
+
// A scenario with slot content of its own prints that over the story's.
|
|
77
|
+
const { props, children, named, around } = sourceStoryOf(component, story, storyOnScenario(model, scenario), scenarioProps);
|
|
78
|
+
// Each component imports from its source's package entry, as generation does.
|
|
79
|
+
const loadedByName = new Map(components.map((entry) => [entry.component.name, entry]));
|
|
80
|
+
const defaultModule = context.sources[0].moduleBase;
|
|
81
|
+
const importsFor = (target) => {
|
|
82
|
+
const imports = new Map();
|
|
83
|
+
for (const name of [model.name, ...model.slotComponents]) {
|
|
84
|
+
const entry = loadedByName.get(name);
|
|
85
|
+
imports.set(name, {
|
|
86
|
+
module: entry?.component.importModule?.[target] ??
|
|
87
|
+
moduleOfSource(entry?.source.moduleBase ?? defaultModule, target),
|
|
88
|
+
exported: entry?.component.exportName ?? name,
|
|
89
|
+
...(entry
|
|
90
|
+
? {
|
|
91
|
+
declaredAttributes: declaredAttributes(Object.keys(entry.component.props), REACT_ATTRIBUTE_NAMES),
|
|
92
|
+
}
|
|
93
|
+
: {}),
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
return imports;
|
|
97
|
+
};
|
|
98
|
+
// The types each component's module exports, which a bound prop's state
|
|
99
|
+
// is typed by where its declared type names them.
|
|
100
|
+
const exportedTypesFor = (target) => {
|
|
101
|
+
const types = new Map();
|
|
102
|
+
// A component's own name, or the name it is exported under, is a value.
|
|
103
|
+
const values = new Set(components.flatMap((entry) => [
|
|
104
|
+
entry.component.name,
|
|
105
|
+
entry.component.exportName ?? entry.component.name,
|
|
106
|
+
]));
|
|
107
|
+
// The story's own component first, so its type wins a name another
|
|
108
|
+
// component's module exports too.
|
|
109
|
+
const ordered = [
|
|
110
|
+
...components.filter((entry) => entry.component.name === componentName),
|
|
111
|
+
...components.filter((entry) => entry.component.name !== componentName),
|
|
112
|
+
];
|
|
113
|
+
for (const entry of ordered)
|
|
114
|
+
for (const type of exportedTypesOf(entry.component, [target])?.[target] ??
|
|
115
|
+
[])
|
|
116
|
+
if (!types.has(type) && !values.has(type))
|
|
117
|
+
types.set(type, entry.component.importModule?.[target] ??
|
|
118
|
+
moduleOfSource(entry.source.moduleBase ?? defaultModule, target));
|
|
119
|
+
return types;
|
|
120
|
+
};
|
|
121
|
+
// A two-way prop the story gives is controlled: its source binds it.
|
|
122
|
+
const declaredTypes = new Map(model.propTypes.map((propType) => [propType.name, propType.declaredType]));
|
|
123
|
+
const bindings = (model.bindings ?? [])
|
|
124
|
+
.filter((binding) => binding.prop in props)
|
|
125
|
+
.map((binding) => {
|
|
126
|
+
const declaredType = declaredTypes.get(binding.prop);
|
|
127
|
+
return { ...binding, ...(declaredType ? { declaredType } : {}) };
|
|
128
|
+
});
|
|
129
|
+
const requested = options.targets ?? [...model.targets, 'html'];
|
|
130
|
+
const sources = {};
|
|
131
|
+
for (const target of requested) {
|
|
132
|
+
if (target === 'html') {
|
|
133
|
+
const result = await printHtmlSource(context, components.map((entry) => entry.component), { component, props, children, named, around });
|
|
134
|
+
if (result.markup !== undefined) {
|
|
135
|
+
sources.html = result.markup;
|
|
136
|
+
if (result.warnings.length > 0) {
|
|
137
|
+
sources.htmlWarnings = result.warnings;
|
|
138
|
+
console.warn(`[preview] ${htmlWarningLine(componentName, result.warnings)}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
console.warn(`[preview] ${componentName} has no html source: it holds ${result.missing.join('; ')}`);
|
|
143
|
+
}
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
if (!model.targets.includes(target))
|
|
147
|
+
continue;
|
|
148
|
+
sources[target] = SOURCE_PRINTERS[target]({
|
|
149
|
+
component: model.name,
|
|
150
|
+
props,
|
|
151
|
+
children,
|
|
152
|
+
named,
|
|
153
|
+
...(around ? { around } : {}),
|
|
154
|
+
imports: importsFor(target),
|
|
155
|
+
...(bindings.length > 0 ? { bindings } : {}),
|
|
156
|
+
svelteMode: context.svelteMode,
|
|
157
|
+
reactAttributeNames: REACT_ATTRIBUTE_NAMES,
|
|
158
|
+
exportedTypes: exportedTypesFor(target),
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
return sources;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* What a story's source prints for a scenario's props: the props the story file
|
|
165
|
+
* sets (`defaultProps`, `fixed`) and the scenario's, less those equal to the
|
|
166
|
+
* component's declared default, and the story file's slot content, or its
|
|
167
|
+
* `children` text where it curates none. A default slot the story leaves
|
|
168
|
+
* unfilled prints no content: the component's name the preview shows there
|
|
169
|
+
* is the preview's own, which a consumer never writes, unless `placeholder`
|
|
170
|
+
* asks for it, as the html the panes render does.
|
|
171
|
+
*
|
|
172
|
+
* @param component - The component.
|
|
173
|
+
* @param story - Its story file, when it has one.
|
|
174
|
+
* @param model - Its resolved story.
|
|
175
|
+
* @param scenarioProps - The scenario's props.
|
|
176
|
+
* @param options - `placeholder` keeps the preview's text in an unfilled default slot.
|
|
177
|
+
* @returns The props and slot content to print.
|
|
178
|
+
*/
|
|
179
|
+
export function sourceStoryOf(component, story, model, scenarioProps, options = {}) {
|
|
180
|
+
// What the story file and scenario set, not the preview's own control defaults.
|
|
181
|
+
const props = {
|
|
182
|
+
...(story?.defaultProps ?? {}),
|
|
183
|
+
...(story?.fixed ?? {}),
|
|
184
|
+
...scenarioProps,
|
|
185
|
+
};
|
|
186
|
+
let children = model.slots?.default;
|
|
187
|
+
const childrenText = 'children' in props
|
|
188
|
+
? props.children
|
|
189
|
+
: options.placeholder
|
|
190
|
+
? model.defaultProps.children
|
|
191
|
+
: undefined;
|
|
192
|
+
delete props.children;
|
|
193
|
+
if (!children && typeof childrenText === 'string')
|
|
194
|
+
children = { kind: 'text', value: childrenText };
|
|
195
|
+
for (const [name, value] of Object.entries(props)) {
|
|
196
|
+
const declared = component.props[name]?.default;
|
|
197
|
+
if (value === undefined ||
|
|
198
|
+
(declared !== undefined &&
|
|
199
|
+
JSON.stringify(declared) === JSON.stringify(value))) {
|
|
200
|
+
delete props[name];
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return {
|
|
204
|
+
props: inDeclarationOrder(props, Object.keys(component.props)),
|
|
205
|
+
children,
|
|
206
|
+
named: model.slots?.named ?? {},
|
|
207
|
+
...(model.around ? { around: model.around } : {}),
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* The lines that report what a story's html leaves out, once per story: a
|
|
212
|
+
* heading, then each evaluation warning indented on a line of its own, a
|
|
213
|
+
* warning about the story's own component without its name, and the
|
|
214
|
+
* warnings one component gives for one reason as a single line counting
|
|
215
|
+
* them (see `summarizeHtmlWarnings`).
|
|
216
|
+
*
|
|
217
|
+
* @param componentName - The story's component.
|
|
218
|
+
* @param warnings - The expressions the html could not evaluate at rest.
|
|
219
|
+
* @returns The lines, joined, without a prefix.
|
|
220
|
+
*/
|
|
221
|
+
export function htmlWarningLine(componentName, warnings) {
|
|
222
|
+
const own = `${componentName}: `;
|
|
223
|
+
return [
|
|
224
|
+
`${componentName}'s html leaves out what it cannot evaluate at rest:`,
|
|
225
|
+
...summarizeHtmlWarnings(warnings).map((warning) => ` ${warning.startsWith(own) ? warning.slice(own.length) : warning}`),
|
|
226
|
+
].join('\n');
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Renders a story to the markup it shows at rest, with the kit's shared
|
|
230
|
+
* modules in scope and its styling, as `storySource`'s `html` does.
|
|
231
|
+
*
|
|
232
|
+
* @param context - The kit's preview context.
|
|
233
|
+
* @param components - Every component of the kit.
|
|
234
|
+
* @param story - The component, its props and its slot content.
|
|
235
|
+
* @returns The markup, or what the story holds that has none.
|
|
236
|
+
*/
|
|
237
|
+
export async function printHtmlSource(context, components, story) {
|
|
238
|
+
return htmlSource({
|
|
239
|
+
scope: await sharedScope(context),
|
|
240
|
+
component: story.component,
|
|
241
|
+
props: story.props,
|
|
242
|
+
children: story.children,
|
|
243
|
+
named: story.named,
|
|
244
|
+
...(story.around ? { around: story.around } : {}),
|
|
245
|
+
components,
|
|
246
|
+
styling: context.styling,
|
|
247
|
+
handWrittenComponents: context.configuration.handWrittenComponents ?? {},
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* The exports of `@scaffold-ui-kit/helpers`' framework-free entries and of
|
|
252
|
+
* the kit's shared modules - the helpers its templates import by specifier -
|
|
253
|
+
* under their names, later modules winning a clash, so a kit's own module
|
|
254
|
+
* wins over the package. A module that fails to load contributes nothing; an
|
|
255
|
+
* expression naming one of its exports is then a comment in the markup.
|
|
256
|
+
*/
|
|
257
|
+
async function sharedScope(context) {
|
|
258
|
+
const scope = {};
|
|
259
|
+
for (const modulePath of [
|
|
260
|
+
...context.helperModulesAbsolute,
|
|
261
|
+
...context.sharedModulesAbsolute,
|
|
262
|
+
]) {
|
|
263
|
+
try {
|
|
264
|
+
Object.assign(scope, (await context.importModule(modulePath)));
|
|
265
|
+
}
|
|
266
|
+
catch {
|
|
267
|
+
// Left out: the markup marks what depends on it.
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return scope;
|
|
271
|
+
}
|
package/dist/story.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Story } from './lib/types.js';
|
|
2
|
+
import type { ModuleImporter } from './lib/types.js';
|
|
3
|
+
/** Whether the kit's `omitPattern` leaves this component out by its name. */
|
|
4
|
+
export declare function isStructurallyOmitted(name: string, omitPattern?: RegExp): boolean;
|
|
5
|
+
export declare function loadStory(name: string, storiesDirectory: string | undefined, importModule: ModuleImporter): Promise<Story | undefined>;
|
package/dist/story.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Load a component's story file (stories/<Name>.story.ts, default export) if
|
|
2
|
+
// present. Also decides the omit by name: a kit whose naming marks a compound's
|
|
3
|
+
// parts declares the pattern (`preview.omitPattern`), and a matching
|
|
4
|
+
// component gets no story of its own.
|
|
5
|
+
import { existsSync } from 'node:fs';
|
|
6
|
+
import { resolve } from 'node:path';
|
|
7
|
+
/** Whether the kit's `omitPattern` leaves this component out by its name. */
|
|
8
|
+
export function isStructurallyOmitted(name, omitPattern) {
|
|
9
|
+
return omitPattern?.test(name) ?? false;
|
|
10
|
+
}
|
|
11
|
+
export async function loadStory(name, storiesDirectory, importModule) {
|
|
12
|
+
if (!storiesDirectory)
|
|
13
|
+
return undefined;
|
|
14
|
+
const file = resolve(storiesDirectory, `${name}.story.ts`);
|
|
15
|
+
if (!existsSync(file))
|
|
16
|
+
return undefined;
|
|
17
|
+
const mod = (await importModule(file));
|
|
18
|
+
// A story file that exports nothing would silently drop the component's
|
|
19
|
+
// curation (its defaults, slots and scenarios), so it is an error. The module
|
|
20
|
+
// importer's interop answers `default` even when none is exported, so the
|
|
21
|
+
// export is looked for among the module's own keys.
|
|
22
|
+
if (!Object.keys(mod).includes('default') ||
|
|
23
|
+
!mod.default ||
|
|
24
|
+
typeof mod.default !== 'object') {
|
|
25
|
+
throw new Error(`[preview] ${file} must default-export the ${name} story object`);
|
|
26
|
+
}
|
|
27
|
+
return mod.default;
|
|
28
|
+
}
|