handoff-app 1.1.3 → 1.2.0-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/config.template.js +21 -14
- package/config/config.template.ts +54 -0
- package/config/docs/system.md +2 -0
- package/dist/app-builder/build.js +31 -12
- package/dist/app-builder/config-diff/index.d.ts +4 -0
- package/dist/app-builder/config-diff/index.js +12 -0
- package/dist/app-builder/config-diff/registry.d.ts +9 -0
- package/dist/app-builder/config-diff/registry.js +30 -0
- package/dist/app-builder/config-diff/snapshot.d.ts +13 -0
- package/dist/app-builder/config-diff/snapshot.js +43 -0
- package/dist/app-builder/config-diff/strategies/pattern.d.ts +2 -0
- package/dist/app-builder/config-diff/strategies/pattern.js +106 -0
- package/dist/app-builder/config-diff/types.d.ts +33 -0
- package/dist/app-builder/config-diff/types.js +2 -0
- package/dist/app-builder/watchers/component.d.ts +15 -0
- package/dist/app-builder/watchers/component.js +69 -0
- package/dist/app-builder/watchers/utils.d.ts +14 -0
- package/dist/app-builder/watchers/utils.js +44 -0
- package/dist/app-builder/watchers.d.ts +10 -19
- package/dist/app-builder/watchers.js +65 -79
- package/dist/app-builder/websocket.js +10 -4
- package/dist/cache/build-cache.js +14 -5
- package/dist/cli/create.js +67 -23
- package/dist/cli/eject.js +48 -7
- package/dist/cli/make.js +29 -4
- package/dist/cli/scaffold.js +60 -19
- package/dist/cli.js +1 -1
- package/dist/config/helpers.d.ts +7 -0
- package/dist/config/helpers.js +31 -0
- package/dist/config/index.d.ts +2 -1
- package/dist/config/index.js +5 -1
- package/dist/config/loader.d.ts +10 -1
- package/dist/config/loader.js +92 -28
- package/dist/config/normalizers/declaration.d.ts +11 -0
- package/dist/config/normalizers/declaration.js +119 -0
- package/dist/config/normalizers/pattern.d.ts +8 -0
- package/dist/config/normalizers/pattern.js +35 -0
- package/dist/config/runtime.d.ts +9 -3
- package/dist/config/runtime.js +260 -33
- package/dist/declarations/helpers.d.ts +6 -0
- package/dist/declarations/helpers.js +19 -0
- package/dist/declarations/index.d.ts +2 -0
- package/dist/declarations/index.js +9 -0
- package/dist/declarations/types.d.ts +60 -0
- package/dist/declarations/types.js +2 -0
- package/dist/index.d.ts +12 -1
- package/dist/index.js +34 -5
- package/dist/pipeline/index.d.ts +1 -0
- package/dist/pipeline/index.js +3 -1
- package/dist/pipeline/patterns.d.ts +8 -0
- package/dist/pipeline/patterns.js +21 -0
- package/dist/transformers/docgen/index.js +12 -2
- package/dist/transformers/plugins/csf-render.js +170 -34
- package/dist/transformers/plugins/ssr-render.js +18 -2
- package/dist/transformers/preview/component/api.js +16 -7
- package/dist/transformers/preview/component/builder.js +61 -8
- package/dist/transformers/preview/component/css.d.ts +8 -0
- package/dist/transformers/preview/component/css.js +6 -4
- package/dist/transformers/preview/component/html.js +14 -5
- package/dist/transformers/preview/component/javascript.d.ts +0 -1
- package/dist/transformers/preview/component/javascript.js +25 -14
- package/dist/transformers/preview/component/previews.d.ts +9 -0
- package/dist/transformers/preview/component/previews.js +10 -0
- package/dist/transformers/preview/pattern/api.d.ts +11 -0
- package/dist/transformers/preview/pattern/api.js +79 -0
- package/dist/transformers/preview/pattern/builder.d.ts +17 -0
- package/dist/transformers/preview/pattern/builder.js +167 -0
- package/dist/transformers/preview/pattern/html.d.ts +19 -0
- package/dist/transformers/preview/pattern/html.js +94 -0
- package/dist/transformers/preview/types.d.ts +54 -0
- package/dist/transformers/utils/csf.d.ts +16 -0
- package/dist/transformers/utils/csf.js +30 -0
- package/dist/transformers/utils/index.d.ts +1 -0
- package/dist/transformers/utils/index.js +2 -0
- package/dist/transformers/utils/module.d.ts +5 -0
- package/dist/transformers/utils/module.js +26 -13
- package/dist/transformers/utils/usage.d.ts +23 -0
- package/dist/transformers/utils/usage.js +294 -0
- package/dist/transformers/utils/vite-logger.js +4 -4
- package/dist/transformers/vite-config.js +2 -0
- package/dist/types/config.d.ts +32 -7
- package/dist/types/preview.d.ts +2 -0
- package/dist/utils/duration.d.ts +2 -0
- package/dist/utils/duration.js +6 -0
- package/dist/utils/logger.d.ts +42 -5
- package/dist/utils/logger.js +135 -15
- package/docs/cli.md +3 -3
- package/package.json +3 -1
- package/src/app/components/Component/PageSliceResolver.tsx +6 -6
- package/src/app/components/Component/Preview.tsx +17 -12
- package/src/app/components/Component/slices/ComponentDisplaySlice.tsx +16 -6
- package/src/app/components/Markdown/CodeHighlight.tsx +60 -11
- package/src/app/components/util/index.ts +71 -2
- package/src/app/pages/system/pattern/[pattern]/index.tsx +346 -0
- package/src/app/pages/system/pattern/index.tsx +14 -0
- package/src/app-builder/README.md +37 -9
- package/src/app-builder/build.ts +34 -12
- package/src/app-builder/config-diff/index.ts +4 -0
- package/src/app-builder/config-diff/registry.ts +23 -0
- package/src/app-builder/config-diff/snapshot.ts +51 -0
- package/src/app-builder/config-diff/strategies/pattern.ts +80 -0
- package/src/app-builder/config-diff/types.ts +36 -0
- package/src/app-builder/watchers/component.ts +72 -0
- package/src/app-builder/watchers/utils.ts +44 -0
- package/src/app-builder/watchers.ts +74 -80
- package/src/app-builder/websocket.ts +16 -5
- package/src/cache/build-cache.ts +14 -5
- package/src/cli/create.ts +86 -25
- package/src/cli/eject.ts +29 -7
- package/src/cli/make.ts +32 -5
- package/src/cli/scaffold.ts +68 -21
- package/src/cli.ts +1 -1
- package/src/config/README.md +10 -1
- package/src/config/helpers.ts +43 -0
- package/src/config/index.ts +4 -1
- package/src/config/loader.ts +110 -31
- package/src/config/normalizers/declaration.ts +176 -0
- package/src/config/normalizers/pattern.ts +56 -0
- package/src/config/runtime.ts +317 -35
- package/src/declarations/helpers.ts +36 -0
- package/src/declarations/index.ts +19 -0
- package/src/declarations/types.ts +70 -0
- package/src/index.ts +47 -6
- package/src/pipeline/index.ts +1 -0
- package/src/pipeline/patterns.ts +12 -0
- package/src/transformers/README.md +2 -2
- package/src/transformers/docgen/index.ts +13 -2
- package/src/transformers/plugins/csf-render.ts +216 -49
- package/src/transformers/plugins/ssr-render.ts +23 -7
- package/src/transformers/preview/component/api.ts +27 -7
- package/src/transformers/preview/component/builder.ts +82 -9
- package/src/transformers/preview/component/css.ts +6 -5
- package/src/transformers/preview/component/html.ts +18 -5
- package/src/transformers/preview/component/javascript.ts +29 -19
- package/src/transformers/preview/component/previews.ts +12 -0
- package/src/transformers/preview/pattern/api.ts +83 -0
- package/src/transformers/preview/pattern/builder.ts +192 -0
- package/src/transformers/preview/pattern/html.ts +107 -0
- package/src/transformers/preview/types.ts +58 -1
- package/src/transformers/utils/csf.ts +48 -0
- package/src/transformers/utils/index.ts +3 -0
- package/src/transformers/utils/module.ts +33 -18
- package/src/transformers/utils/usage.ts +319 -0
- package/src/transformers/utils/vite-logger.ts +4 -4
- package/src/transformers/vite-config.ts +2 -0
- package/src/types/README.md +1 -1
- package/src/types/config.ts +33 -7
- package/src/types/preview.ts +2 -0
- package/src/utils/duration.ts +3 -0
- package/src/utils/logger.ts +143 -16
- package/templates/default/components/button/Button.jsx.tpl +64 -0
- package/templates/default/components/button/button.react.handoff.js.tpl +31 -0
- package/templates/default/components/button/button.react.handoff.ts.tpl +31 -0
- package/templates/default/handoff.config.js.tpl +29 -16
- package/templates/default/handoff.config.ts.tpl +196 -0
- package/templates/default/handoff.config.with-examples.js.tpl +28 -17
- package/templates/default/handoff.config.with-examples.ts.tpl +195 -0
- package/templates/default/package.json.tpl +1 -3
- package/handoff.config.js +0 -90
- package/templates/default/components/button/button.js.tpl +0 -62
|
@@ -19,6 +19,16 @@ const logger_1 = require("../../../utils/logger");
|
|
|
19
19
|
const plugins_1 = require("../../plugins");
|
|
20
20
|
const vite_config_1 = __importDefault(require("../../vite-config"));
|
|
21
21
|
const component_1 = require("../component");
|
|
22
|
+
const resolveRenderer = (data) => {
|
|
23
|
+
var _a, _b, _c;
|
|
24
|
+
const templatePath = ((_a = data.entries) === null || _a === void 0 ? void 0 : _a.template) || '';
|
|
25
|
+
return (data.renderer ||
|
|
26
|
+
(((_b = data.entries) === null || _b === void 0 ? void 0 : _b.story) || templatePath.match(/\.stories\.(jsx|tsx|js|ts)$/) ? 'csf' : undefined) ||
|
|
27
|
+
(((_c = data.entries) === null || _c === void 0 ? void 0 : _c.component) || (templatePath.includes('.tsx') && !templatePath.match(/\.stories\.(jsx|tsx|js|ts)$/))
|
|
28
|
+
? 'react'
|
|
29
|
+
: undefined) ||
|
|
30
|
+
(templatePath.includes('.hbs') ? 'handlebars' : undefined));
|
|
31
|
+
};
|
|
22
32
|
/**
|
|
23
33
|
* Builds previews for components using Vite and Handlebars.
|
|
24
34
|
*
|
|
@@ -37,13 +47,12 @@ const buildPreviews = (data, handoff, components) => __awaiter(void 0, void 0, v
|
|
|
37
47
|
var _a, _b, _c;
|
|
38
48
|
if (!((_a = data.entries) === null || _a === void 0 ? void 0 : _a.template))
|
|
39
49
|
return data;
|
|
50
|
+
const resolvedRenderer = resolveRenderer(data);
|
|
40
51
|
const plugins = [
|
|
41
52
|
...(vite_config_1.default.plugins || []),
|
|
42
|
-
...(
|
|
43
|
-
...(
|
|
44
|
-
...(
|
|
45
|
-
? [(0, plugin_react_1.default)(), (0, plugins_1.ssrRenderPlugin)(data, components, handoff)]
|
|
46
|
-
: []),
|
|
53
|
+
...(resolvedRenderer === 'handlebars' ? [(0, plugins_1.handlebarsPreviewsPlugin)(data, components, handoff)] : []),
|
|
54
|
+
...(resolvedRenderer === 'csf' ? [(0, plugins_1.csfRenderPlugin)(data, components, handoff)] : []),
|
|
55
|
+
...(resolvedRenderer === 'react' ? [(0, plugin_react_1.default)(), (0, plugins_1.ssrRenderPlugin)(data, components, handoff)] : []),
|
|
47
56
|
];
|
|
48
57
|
// Store the current NODE_ENV value before vite build
|
|
49
58
|
// This is necessary because viteBuild forcibly sets NODE_ENV to 'production'
|
|
@@ -18,7 +18,6 @@ export declare const buildComponentJs: (data: TransformComponentTokensResult, ha
|
|
|
18
18
|
*
|
|
19
19
|
* @param handoff - The Handoff configuration object containing build settings
|
|
20
20
|
* @returns A Promise that resolves when the build process is complete
|
|
21
|
-
* @throws May throw an error if the build process fails
|
|
22
21
|
*/
|
|
23
22
|
export declare const buildMainJS: (handoff: Handoff) => Promise<void>;
|
|
24
23
|
export default buildComponentJs;
|
|
@@ -17,6 +17,7 @@ const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
|
17
17
|
const path_1 = __importDefault(require("path"));
|
|
18
18
|
const vite_1 = require("vite");
|
|
19
19
|
const config_1 = require("../../../config");
|
|
20
|
+
const duration_1 = require("../../../utils/duration");
|
|
20
21
|
const logger_1 = require("../../../utils/logger");
|
|
21
22
|
const vite_config_1 = __importDefault(require("../../vite-config"));
|
|
22
23
|
const component_1 = require("../component");
|
|
@@ -50,9 +51,6 @@ const buildJsBundle = (_a, handoff_1) => __awaiter(void 0, [_a, handoff_1], void
|
|
|
50
51
|
}
|
|
51
52
|
yield (0, vite_1.build)(viteConfig);
|
|
52
53
|
}
|
|
53
|
-
catch (e) {
|
|
54
|
-
logger_1.Logger.error(`Failed to build JS for "${outputFilename}":`, e);
|
|
55
|
-
}
|
|
56
54
|
finally {
|
|
57
55
|
// Restore the original NODE_ENV value after vite build completes
|
|
58
56
|
// This prevents interference with Next.js app building/running processes
|
|
@@ -83,11 +81,17 @@ const buildComponentJs = (data, handoff) => __awaiter(void 0, void 0, void 0, fu
|
|
|
83
81
|
const outputPath = (0, component_1.getComponentOutputPath)(handoff);
|
|
84
82
|
try {
|
|
85
83
|
const js = yield fs_extra_1.default.readFile(path_1.default.resolve(entry), 'utf8');
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
84
|
+
try {
|
|
85
|
+
yield buildJsBundle({
|
|
86
|
+
entry,
|
|
87
|
+
outputPath,
|
|
88
|
+
outputFilename: `${id}.js`,
|
|
89
|
+
}, handoff);
|
|
90
|
+
}
|
|
91
|
+
catch (e) {
|
|
92
|
+
logger_1.Logger.error(`Failed to bundle JS for component "${id}" (${id}.js):`, e);
|
|
93
|
+
return data;
|
|
94
|
+
}
|
|
91
95
|
data.js = js;
|
|
92
96
|
const compiled = yield fs_extra_1.default.readFile(path_1.default.resolve(outputPath, `${id}.js`), 'utf8');
|
|
93
97
|
data['jsCompiled'] = compiled;
|
|
@@ -106,17 +110,24 @@ exports.buildComponentJs = buildComponentJs;
|
|
|
106
110
|
*
|
|
107
111
|
* @param handoff - The Handoff configuration object containing build settings
|
|
108
112
|
* @returns A Promise that resolves when the build process is complete
|
|
109
|
-
* @throws May throw an error if the build process fails
|
|
110
113
|
*/
|
|
111
114
|
const buildMainJS = (handoff) => __awaiter(void 0, void 0, void 0, function* () {
|
|
112
115
|
const outputPath = (0, component_1.getComponentOutputPath)(handoff);
|
|
113
116
|
const runtimeConfig = (0, config_1.initRuntimeConfig)(handoff)[0];
|
|
114
117
|
if (runtimeConfig && runtimeConfig.entries.js && fs_extra_1.default.existsSync(path_1.default.resolve(runtimeConfig.entries.js))) {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
118
|
+
logger_1.Logger.info(`Building script for global entry (main.js)…`);
|
|
119
|
+
const startedAt = Date.now();
|
|
120
|
+
try {
|
|
121
|
+
yield buildJsBundle({
|
|
122
|
+
entry: runtimeConfig.entries.js,
|
|
123
|
+
outputPath,
|
|
124
|
+
outputFilename: 'main.js',
|
|
125
|
+
}, handoff);
|
|
126
|
+
logger_1.Logger.info(`Finished building script for global entry (main.js) in ${(0, duration_1.formatDurationMs)(Date.now() - startedAt)}`);
|
|
127
|
+
}
|
|
128
|
+
catch (e) {
|
|
129
|
+
logger_1.Logger.error(`Failed to build global script (main.js):`, e);
|
|
130
|
+
}
|
|
120
131
|
}
|
|
121
132
|
});
|
|
122
133
|
exports.buildMainJS = buildMainJS;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { OptionalPreviewRender } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Returns previews exposed in docs/API; synthetic pattern previews (`__pattern_*`) are omitted.
|
|
4
|
+
*/
|
|
5
|
+
export declare const getDocumentedPreviews: (previews?: {
|
|
6
|
+
[key: string]: OptionalPreviewRender;
|
|
7
|
+
}) => {
|
|
8
|
+
[key: string]: OptionalPreviewRender;
|
|
9
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getDocumentedPreviews = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Returns previews exposed in docs/API; synthetic pattern previews (`__pattern_*`) are omitted.
|
|
6
|
+
*/
|
|
7
|
+
const getDocumentedPreviews = (previews) => {
|
|
8
|
+
return Object.fromEntries(Object.entries(previews || {}).filter(([key]) => !key.startsWith('__pattern_')));
|
|
9
|
+
};
|
|
10
|
+
exports.getDocumentedPreviews = getDocumentedPreviews;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import Handoff from '../../../index';
|
|
2
|
+
import { PatternListObject, PatternObject } from '../types';
|
|
3
|
+
export declare const getPatternAPIPath: (handoff: Handoff) => string;
|
|
4
|
+
export declare const writePatternApi: (id: string, pattern: PatternObject, handoff: Handoff) => Promise<void>;
|
|
5
|
+
export declare const writePatternHtml: (id: string, html: string, handoff: Handoff) => Promise<void>;
|
|
6
|
+
export declare const writePatternSummaryApi: (handoff: Handoff, patterns: PatternListObject[]) => Promise<void>;
|
|
7
|
+
/**
|
|
8
|
+
* Reads the pattern list summary when present (used for partial pattern rebuilds).
|
|
9
|
+
*/
|
|
10
|
+
export declare const readPatternSummaryApi: (handoff: Handoff) => Promise<PatternListObject[] | null>;
|
|
11
|
+
export declare const syncPatternArtifacts: (handoff: Handoff, validIds: Iterable<string>) => Promise<void>;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.syncPatternArtifacts = exports.readPatternSummaryApi = exports.writePatternSummaryApi = exports.writePatternHtml = exports.writePatternApi = exports.getPatternAPIPath = void 0;
|
|
16
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
17
|
+
const path_1 = __importDefault(require("path"));
|
|
18
|
+
const getPatternAPIPath = (handoff) => {
|
|
19
|
+
const patternPath = path_1.default.resolve(handoff.workingPath, 'public/api/pattern');
|
|
20
|
+
if (!fs_extra_1.default.existsSync(patternPath)) {
|
|
21
|
+
fs_extra_1.default.mkdirSync(patternPath, { recursive: true });
|
|
22
|
+
}
|
|
23
|
+
return patternPath;
|
|
24
|
+
};
|
|
25
|
+
exports.getPatternAPIPath = getPatternAPIPath;
|
|
26
|
+
const writePatternApi = (id, pattern, handoff) => __awaiter(void 0, void 0, void 0, function* () {
|
|
27
|
+
const outputDir = (0, exports.getPatternAPIPath)(handoff);
|
|
28
|
+
const outputFilePath = path_1.default.resolve(outputDir, `${id}.json`);
|
|
29
|
+
yield fs_extra_1.default.writeFile(outputFilePath, JSON.stringify(pattern, null, 2));
|
|
30
|
+
});
|
|
31
|
+
exports.writePatternApi = writePatternApi;
|
|
32
|
+
const writePatternHtml = (id, html, handoff) => __awaiter(void 0, void 0, void 0, function* () {
|
|
33
|
+
const outputDir = (0, exports.getPatternAPIPath)(handoff);
|
|
34
|
+
const outputFilePath = path_1.default.resolve(outputDir, `${id}.html`);
|
|
35
|
+
yield fs_extra_1.default.writeFile(outputFilePath, html);
|
|
36
|
+
});
|
|
37
|
+
exports.writePatternHtml = writePatternHtml;
|
|
38
|
+
const writePatternSummaryApi = (handoff, patterns) => __awaiter(void 0, void 0, void 0, function* () {
|
|
39
|
+
const apiPath = path_1.default.resolve(handoff.workingPath, 'public/api');
|
|
40
|
+
if (!fs_extra_1.default.existsSync(apiPath)) {
|
|
41
|
+
fs_extra_1.default.mkdirSync(apiPath, { recursive: true });
|
|
42
|
+
}
|
|
43
|
+
patterns.sort((a, b) => a.title.localeCompare(b.title));
|
|
44
|
+
yield fs_extra_1.default.writeFile(path_1.default.resolve(apiPath, 'patterns.json'), JSON.stringify(patterns, null, 2));
|
|
45
|
+
});
|
|
46
|
+
exports.writePatternSummaryApi = writePatternSummaryApi;
|
|
47
|
+
/**
|
|
48
|
+
* Reads the pattern list summary when present (used for partial pattern rebuilds).
|
|
49
|
+
*/
|
|
50
|
+
const readPatternSummaryApi = (handoff) => __awaiter(void 0, void 0, void 0, function* () {
|
|
51
|
+
const summaryPath = path_1.default.resolve(handoff.workingPath, 'public/api/patterns.json');
|
|
52
|
+
if (!fs_extra_1.default.existsSync(summaryPath)) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
const raw = yield fs_extra_1.default.readFile(summaryPath, 'utf8');
|
|
57
|
+
const parsed = JSON.parse(raw);
|
|
58
|
+
return Array.isArray(parsed) ? parsed : null;
|
|
59
|
+
}
|
|
60
|
+
catch (_a) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
exports.readPatternSummaryApi = readPatternSummaryApi;
|
|
65
|
+
const syncPatternArtifacts = (handoff, validIds) => __awaiter(void 0, void 0, void 0, function* () {
|
|
66
|
+
const validIdSet = new Set(validIds);
|
|
67
|
+
const patternPath = (0, exports.getPatternAPIPath)(handoff);
|
|
68
|
+
const entries = yield fs_extra_1.default.readdir(patternPath);
|
|
69
|
+
for (const entry of entries) {
|
|
70
|
+
const parsed = path_1.default.parse(entry);
|
|
71
|
+
const isPatternArtifact = parsed.ext === '.json' || parsed.ext === '.html';
|
|
72
|
+
if (!isPatternArtifact)
|
|
73
|
+
continue;
|
|
74
|
+
if (!validIdSet.has(parsed.name)) {
|
|
75
|
+
yield fs_extra_1.default.remove(path_1.default.resolve(patternPath, entry));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
exports.syncPatternArtifacts = syncPatternArtifacts;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import Handoff from '../../../index';
|
|
2
|
+
import { PatternListObject } from '../types';
|
|
3
|
+
export type ProcessPatternsOptions = {
|
|
4
|
+
/** When set, only these pattern ids are recomposed; others keep existing artifacts. */
|
|
5
|
+
onlyPatternIds?: Set<string>;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Returns pattern ids whose declarations reference any of the given component ids.
|
|
9
|
+
*/
|
|
10
|
+
export declare const getPatternIdsReferencingComponents: (handoff: Handoff, componentIds: string[]) => string[];
|
|
11
|
+
/**
|
|
12
|
+
* Process all pattern declarations and compose their HTML from pre-built
|
|
13
|
+
* component preview files. This function must run AFTER buildComponents
|
|
14
|
+
* so that all component preview HTML files already exist on disk.
|
|
15
|
+
*/
|
|
16
|
+
export declare function processPatterns(handoff: Handoff, options?: ProcessPatternsOptions): Promise<PatternListObject[]>;
|
|
17
|
+
export default processPatterns;
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.getPatternIdsReferencingComponents = void 0;
|
|
16
|
+
exports.processPatterns = processPatterns;
|
|
17
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
18
|
+
const path_1 = __importDefault(require("path"));
|
|
19
|
+
const logger_1 = require("../../../utils/logger");
|
|
20
|
+
const api_1 = require("./api");
|
|
21
|
+
const html_1 = require("./html");
|
|
22
|
+
/**
|
|
23
|
+
* Returns pattern ids whose declarations reference any of the given component ids.
|
|
24
|
+
*/
|
|
25
|
+
const getPatternIdsReferencingComponents = (handoff, componentIds) => {
|
|
26
|
+
var _a, _b, _c, _d;
|
|
27
|
+
if (componentIds.length === 0) {
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
const idSet = new Set(componentIds);
|
|
31
|
+
const runtimePatterns = (_c = (_b = (_a = handoff.runtimeConfig) === null || _a === void 0 ? void 0 : _a.entries) === null || _b === void 0 ? void 0 : _b.patterns) !== null && _c !== void 0 ? _c : {};
|
|
32
|
+
const result = [];
|
|
33
|
+
for (const patternId of Object.keys(runtimePatterns)) {
|
|
34
|
+
const pattern = runtimePatterns[patternId];
|
|
35
|
+
if ((_d = pattern.components) === null || _d === void 0 ? void 0 : _d.some((ref) => idSet.has(ref.id))) {
|
|
36
|
+
result.push(patternId);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
exports.getPatternIdsReferencingComponents = getPatternIdsReferencingComponents;
|
|
42
|
+
function buildPattern(handoff, patternId, pattern, componentOutputDir, basePath) {
|
|
43
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
44
|
+
const fragments = [];
|
|
45
|
+
let hasErrors = false;
|
|
46
|
+
for (let i = 0; i < pattern.components.length; i++) {
|
|
47
|
+
const ref = pattern.components[i];
|
|
48
|
+
if (ref.resolved === false && !ref.resolvedPreview) {
|
|
49
|
+
hasErrors = true;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
const previewKey = ref.resolvedPreview || ref.preview;
|
|
53
|
+
if (!previewKey) {
|
|
54
|
+
const error = `Pattern "${patternId}" component[${i}] ("${ref.id}") has no resolved preview key. Skipping.`;
|
|
55
|
+
logger_1.Logger.warn(error);
|
|
56
|
+
ref.resolved = false;
|
|
57
|
+
hasErrors = true;
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
const htmlFileName = `${ref.id}-${previewKey}.html`;
|
|
61
|
+
const htmlFilePath = path_1.default.resolve(componentOutputDir, htmlFileName);
|
|
62
|
+
if (!fs_extra_1.default.existsSync(htmlFilePath)) {
|
|
63
|
+
const error = `Pattern "${patternId}" component[${i}] ("${ref.id}") preview file not found: ${htmlFileName}. ` +
|
|
64
|
+
`Ensure the component has a preview named "${previewKey}".`;
|
|
65
|
+
logger_1.Logger.warn(error);
|
|
66
|
+
ref.resolved = false;
|
|
67
|
+
hasErrors = true;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
ref.resolved = true;
|
|
71
|
+
const html = yield fs_extra_1.default.readFile(htmlFilePath, 'utf8');
|
|
72
|
+
fragments.push({ componentId: ref.id, html });
|
|
73
|
+
}
|
|
74
|
+
if (fragments.length === 0) {
|
|
75
|
+
logger_1.Logger.warn(`Pattern "${patternId}" produced no fragments. Skipping.`);
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
if (hasErrors) {
|
|
79
|
+
logger_1.Logger.warn(`Pattern "${patternId}" has missing components but will be composed from available fragments.`);
|
|
80
|
+
}
|
|
81
|
+
const composedHtml = (0, html_1.composePatternHtml)(patternId, pattern.title, fragments, basePath);
|
|
82
|
+
const patternUrl = `${patternId}.html`;
|
|
83
|
+
const patternData = Object.assign(Object.assign({}, pattern), { id: patternId, url: patternUrl, path: `${basePath}/api/pattern/${patternId}.json` });
|
|
84
|
+
yield (0, api_1.writePatternHtml)(patternId, composedHtml, handoff);
|
|
85
|
+
yield (0, api_1.writePatternApi)(patternId, patternData, handoff);
|
|
86
|
+
logger_1.Logger.debug(`Built pattern: ${patternId} (${fragments.length} component(s))`);
|
|
87
|
+
return patternData;
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Process all pattern declarations and compose their HTML from pre-built
|
|
92
|
+
* component preview files. This function must run AFTER buildComponents
|
|
93
|
+
* so that all component preview HTML files already exist on disk.
|
|
94
|
+
*/
|
|
95
|
+
function processPatterns(handoff, options) {
|
|
96
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
97
|
+
var _a, _b, _c, _d;
|
|
98
|
+
const runtimePatterns = (_c = (_b = (_a = handoff.runtimeConfig) === null || _a === void 0 ? void 0 : _a.entries) === null || _b === void 0 ? void 0 : _b.patterns) !== null && _c !== void 0 ? _c : {};
|
|
99
|
+
const patternIds = Object.keys(runtimePatterns);
|
|
100
|
+
const onlyPatternIds = options === null || options === void 0 ? void 0 : options.onlyPatternIds;
|
|
101
|
+
const isPartial = onlyPatternIds !== undefined;
|
|
102
|
+
if (patternIds.length === 0) {
|
|
103
|
+
yield (0, api_1.syncPatternArtifacts)(handoff, []);
|
|
104
|
+
yield (0, api_1.writePatternSummaryApi)(handoff, []);
|
|
105
|
+
return [];
|
|
106
|
+
}
|
|
107
|
+
const componentOutputDir = path_1.default.resolve(handoff.workingPath, 'public/api/component');
|
|
108
|
+
const basePath = (_d = process.env.HANDOFF_APP_BASE_PATH) !== null && _d !== void 0 ? _d : '';
|
|
109
|
+
if (!isPartial) {
|
|
110
|
+
logger_1.Logger.info(`Building ${patternIds.length} pattern(s)...`);
|
|
111
|
+
const result = [];
|
|
112
|
+
for (const patternId of patternIds) {
|
|
113
|
+
const pattern = runtimePatterns[patternId];
|
|
114
|
+
const built = yield buildPattern(handoff, patternId, pattern, componentOutputDir, basePath);
|
|
115
|
+
if (built) {
|
|
116
|
+
result.push(built);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
yield (0, api_1.syncPatternArtifacts)(handoff, result.map((p) => p.id));
|
|
120
|
+
yield (0, api_1.writePatternSummaryApi)(handoff, result);
|
|
121
|
+
logger_1.Logger.info(`Finished building ${result.length} pattern(s).`);
|
|
122
|
+
return result;
|
|
123
|
+
}
|
|
124
|
+
if (onlyPatternIds.size === 0) {
|
|
125
|
+
const existing = yield (0, api_1.readPatternSummaryApi)(handoff);
|
|
126
|
+
return existing !== null && existing !== void 0 ? existing : [];
|
|
127
|
+
}
|
|
128
|
+
const existingList = yield (0, api_1.readPatternSummaryApi)(handoff);
|
|
129
|
+
if (!existingList) {
|
|
130
|
+
logger_1.Logger.warn('Partial pattern rebuild requested but patterns.json is missing; rebuilding all patterns.');
|
|
131
|
+
return processPatterns(handoff);
|
|
132
|
+
}
|
|
133
|
+
const existingById = new Map(existingList.map((p) => [p.id, p]));
|
|
134
|
+
logger_1.Logger.info(`Rebuilding ${onlyPatternIds.size} of ${patternIds.length} pattern(s) (incremental)...`);
|
|
135
|
+
for (const patternId of patternIds) {
|
|
136
|
+
if (onlyPatternIds.has(patternId)) {
|
|
137
|
+
const pattern = runtimePatterns[patternId];
|
|
138
|
+
const built = yield buildPattern(handoff, patternId, pattern, componentOutputDir, basePath);
|
|
139
|
+
if (built) {
|
|
140
|
+
existingById.set(patternId, built);
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
existingById.delete(patternId);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
else if (!existingById.has(patternId)) {
|
|
147
|
+
const pattern = runtimePatterns[patternId];
|
|
148
|
+
const built = yield buildPattern(handoff, patternId, pattern, componentOutputDir, basePath);
|
|
149
|
+
if (built) {
|
|
150
|
+
existingById.set(patternId, built);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const merged = [];
|
|
155
|
+
for (const patternId of patternIds) {
|
|
156
|
+
const entry = existingById.get(patternId);
|
|
157
|
+
if (entry) {
|
|
158
|
+
merged.push(entry);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
yield (0, api_1.syncPatternArtifacts)(handoff, merged.map((p) => p.id));
|
|
162
|
+
yield (0, api_1.writePatternSummaryApi)(handoff, merged);
|
|
163
|
+
logger_1.Logger.info(`Finished incremental pattern build (${onlyPatternIds.size} recomposed).`);
|
|
164
|
+
return merged;
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
exports.default = processPatterns;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Composes multiple component preview HTML documents into a single-page HTML.
|
|
3
|
+
*
|
|
4
|
+
* Each component preview may be a React SSR document (with hydration scripts
|
|
5
|
+
* and a `#root` / `#__APP_PROPS__` pair) or a static Handlebars document.
|
|
6
|
+
*
|
|
7
|
+
* This function namespaces the element ids per-fragment so multiple React
|
|
8
|
+
* components can coexist and hydrate independently on the same page.
|
|
9
|
+
*
|
|
10
|
+
* Each hydration bundle gets its own `<script type="module">` tag for full
|
|
11
|
+
* module-level isolation. This is critical because esbuild bundles React
|
|
12
|
+
* into each script using module-scoped `var` declarations, and `hydrateRoot`
|
|
13
|
+
* is asynchronous — sharing a single module scope would cause later bundles
|
|
14
|
+
* to overwrite earlier React instances before hydration completes.
|
|
15
|
+
*/
|
|
16
|
+
export declare const composePatternHtml: (_patternId: string, patternTitle: string, fragments: {
|
|
17
|
+
componentId: string;
|
|
18
|
+
html: string;
|
|
19
|
+
}[], basePath: string) => string;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.composePatternHtml = void 0;
|
|
7
|
+
const escape_1 = __importDefault(require("lodash/escape"));
|
|
8
|
+
const node_html_parser_1 = require("node-html-parser");
|
|
9
|
+
/**
|
|
10
|
+
* Composes multiple component preview HTML documents into a single-page HTML.
|
|
11
|
+
*
|
|
12
|
+
* Each component preview may be a React SSR document (with hydration scripts
|
|
13
|
+
* and a `#root` / `#__APP_PROPS__` pair) or a static Handlebars document.
|
|
14
|
+
*
|
|
15
|
+
* This function namespaces the element ids per-fragment so multiple React
|
|
16
|
+
* components can coexist and hydrate independently on the same page.
|
|
17
|
+
*
|
|
18
|
+
* Each hydration bundle gets its own `<script type="module">` tag for full
|
|
19
|
+
* module-level isolation. This is critical because esbuild bundles React
|
|
20
|
+
* into each script using module-scoped `var` declarations, and `hydrateRoot`
|
|
21
|
+
* is asynchronous — sharing a single module scope would cause later bundles
|
|
22
|
+
* to overwrite earlier React instances before hydration completes.
|
|
23
|
+
*/
|
|
24
|
+
const composePatternHtml = (_patternId, patternTitle, fragments, basePath) => {
|
|
25
|
+
const cssHrefs = new Set();
|
|
26
|
+
const bodyParts = [];
|
|
27
|
+
const scriptTags = [];
|
|
28
|
+
cssHrefs.add(`${basePath}/api/component/main.css`);
|
|
29
|
+
cssHrefs.add(`${basePath}/assets/css/preview.css`);
|
|
30
|
+
const seenComponents = new Set();
|
|
31
|
+
for (let i = 0; i < fragments.length; i++) {
|
|
32
|
+
const { componentId, html } = fragments[i];
|
|
33
|
+
if (!seenComponents.has(componentId)) {
|
|
34
|
+
seenComponents.add(componentId);
|
|
35
|
+
cssHrefs.add(`${basePath}/api/component/${componentId}.css`);
|
|
36
|
+
}
|
|
37
|
+
const doc = (0, node_html_parser_1.parse)(html);
|
|
38
|
+
const suffix = `_p${i}`;
|
|
39
|
+
const namespacedRootId = `root${suffix}`;
|
|
40
|
+
const namespacedPropsId = `__APP_PROPS__${suffix}`;
|
|
41
|
+
// -- Extract props JSON (React SSR) ------------------------------------
|
|
42
|
+
const propsScript = doc.querySelector('#__APP_PROPS__');
|
|
43
|
+
let propsContent = '{}';
|
|
44
|
+
if (propsScript) {
|
|
45
|
+
propsContent = propsScript.textContent || '{}';
|
|
46
|
+
propsScript.remove();
|
|
47
|
+
}
|
|
48
|
+
// -- Extract and rewrite hydration scripts (React SSR) -----------------
|
|
49
|
+
// Each script becomes its own <script type="module"> for full isolation.
|
|
50
|
+
const moduleScripts = doc.querySelectorAll('script[type="module"]');
|
|
51
|
+
for (const script of moduleScripts) {
|
|
52
|
+
let code = script.textContent || '';
|
|
53
|
+
if (code.trim()) {
|
|
54
|
+
code = code
|
|
55
|
+
.replace(/__APP_PROPS__/g, namespacedPropsId)
|
|
56
|
+
.replace(/getElementById\(\s*["']root["']\s*\)/g, `getElementById("${namespacedRootId}")`);
|
|
57
|
+
scriptTags.push(` <script type="module">\n${code}\n </script>`);
|
|
58
|
+
}
|
|
59
|
+
script.remove();
|
|
60
|
+
}
|
|
61
|
+
// -- Namespace the root element (React SSR) ----------------------------
|
|
62
|
+
const rootEl = doc.querySelector('#root');
|
|
63
|
+
if (rootEl) {
|
|
64
|
+
rootEl.setAttribute('id', namespacedRootId);
|
|
65
|
+
}
|
|
66
|
+
// -- Extract body content ----------------------------------------------
|
|
67
|
+
const bodyEl = doc.querySelector('body');
|
|
68
|
+
const bodyContent = bodyEl
|
|
69
|
+
? bodyEl.innerHTML.trim()
|
|
70
|
+
: rootEl
|
|
71
|
+
? rootEl.outerHTML
|
|
72
|
+
: doc.innerHTML || '';
|
|
73
|
+
bodyParts.push(` <div class="handoff-pattern-block" data-component="${componentId}" data-fragment="${i}">\n` +
|
|
74
|
+
` <script id="${namespacedPropsId}" type="application/json">${propsContent}</script>\n` +
|
|
75
|
+
` ${bodyContent}\n` +
|
|
76
|
+
` </div>`);
|
|
77
|
+
}
|
|
78
|
+
const linkTags = Array.from(cssHrefs)
|
|
79
|
+
.map((href) => ` <link rel="stylesheet" href="${href}" />`)
|
|
80
|
+
.join('\n');
|
|
81
|
+
return `<!DOCTYPE html>
|
|
82
|
+
<html lang="en">
|
|
83
|
+
<head>
|
|
84
|
+
<meta charset="UTF-8" />
|
|
85
|
+
${linkTags}
|
|
86
|
+
<title>${(0, escape_1.default)(patternTitle)}</title>
|
|
87
|
+
</head>
|
|
88
|
+
<body>
|
|
89
|
+
${bodyParts.join('\n')}
|
|
90
|
+
${scriptTags.join('\n')}
|
|
91
|
+
</body>
|
|
92
|
+
</html>`;
|
|
93
|
+
};
|
|
94
|
+
exports.composePatternHtml = composePatternHtml;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { GeneratedDocs } from 'handoff-docgen';
|
|
2
2
|
import { Card } from '../../app/components/Component/Cards';
|
|
3
|
+
import type { RendererKind } from '../../declarations/types';
|
|
3
4
|
import { ValidationResult } from '../../types/preview';
|
|
4
5
|
import { Filter } from '../../utils/filter';
|
|
5
6
|
import { SlotMetadata } from './component';
|
|
@@ -93,7 +94,17 @@ export type ComponentObject = {
|
|
|
93
94
|
scss?: string;
|
|
94
95
|
/** Optional path to component template file (if available) */
|
|
95
96
|
template?: string;
|
|
97
|
+
/** Optional path to React component source for preview rendering */
|
|
98
|
+
component?: string;
|
|
99
|
+
/** Optional path to CSF story file */
|
|
100
|
+
story?: string;
|
|
101
|
+
/** Optional path to schema file (if available) */
|
|
102
|
+
schema?: string;
|
|
103
|
+
/** Optional path to templates directory */
|
|
104
|
+
templates?: string;
|
|
96
105
|
};
|
|
106
|
+
/** Optional explicit renderer id */
|
|
107
|
+
renderer?: RendererKind;
|
|
97
108
|
/** Schema describing the expected properties (props/slots) for the component */
|
|
98
109
|
properties: {
|
|
99
110
|
[key: string]: SlotMetadata;
|
|
@@ -102,10 +113,18 @@ export type ComponentObject = {
|
|
|
102
113
|
previews: {
|
|
103
114
|
[key: string]: OptionalPreviewRender;
|
|
104
115
|
};
|
|
116
|
+
/** Internal previews generated only for pattern composition, not public docs */
|
|
117
|
+
internalPatternPreviews?: {
|
|
118
|
+
[key: string]: OptionalPreviewRender;
|
|
119
|
+
};
|
|
105
120
|
/** Optional array of high-level categories for search/filtering */
|
|
106
121
|
categories?: string[];
|
|
107
122
|
/** Optional array of tags for search/filtering (e.g. "primary", "interactive") */
|
|
108
123
|
tags?: string[];
|
|
124
|
+
/** Optional markdown strings describing recommended usage patterns */
|
|
125
|
+
should_do?: string[];
|
|
126
|
+
/** Optional markdown strings describing anti-patterns to avoid */
|
|
127
|
+
should_not_do?: string[];
|
|
109
128
|
/** Optional source Figma file or node URL for the component */
|
|
110
129
|
figma?: string;
|
|
111
130
|
/** Optional canonical Figma component name or ID (used for matching back to design tokens) */
|
|
@@ -138,11 +157,15 @@ export type TransformComponentTokensResult = {
|
|
|
138
157
|
css?: string;
|
|
139
158
|
sass?: string;
|
|
140
159
|
sharedStyles?: string;
|
|
160
|
+
usage?: string;
|
|
141
161
|
title?: string;
|
|
142
162
|
description?: string;
|
|
143
163
|
previews?: {
|
|
144
164
|
[key: string]: OptionalPreviewRender;
|
|
145
165
|
};
|
|
166
|
+
internalPatternPreviews?: {
|
|
167
|
+
[key: string]: OptionalPreviewRender;
|
|
168
|
+
};
|
|
146
169
|
properties?: {
|
|
147
170
|
[key: string]: SlotMetadata;
|
|
148
171
|
};
|
|
@@ -151,8 +174,12 @@ export type TransformComponentTokensResult = {
|
|
|
151
174
|
js?: string;
|
|
152
175
|
scss?: string;
|
|
153
176
|
template?: string;
|
|
177
|
+
component?: string;
|
|
178
|
+
story?: string;
|
|
154
179
|
schema?: string;
|
|
180
|
+
templates?: string;
|
|
155
181
|
};
|
|
182
|
+
renderer?: RendererKind;
|
|
156
183
|
options?: {
|
|
157
184
|
preview?: {
|
|
158
185
|
groupBy?: string;
|
|
@@ -168,7 +195,34 @@ export type OptionalPreviewRender = {
|
|
|
168
195
|
[key: string]: string | string[] | any;
|
|
169
196
|
};
|
|
170
197
|
url: string;
|
|
198
|
+
usage?: string;
|
|
199
|
+
/** Optional source preview/story key used to derive this preview */
|
|
200
|
+
sourcePreview?: string;
|
|
171
201
|
};
|
|
172
202
|
export interface TransformedPreviewComponents {
|
|
173
203
|
[key: string]: TransformComponentTokensResult[];
|
|
174
204
|
}
|
|
205
|
+
export type PatternComponentEntry = {
|
|
206
|
+
/** Component id reference */
|
|
207
|
+
id: string;
|
|
208
|
+
/** Named preview variant to use (optional if args provided) */
|
|
209
|
+
preview?: string;
|
|
210
|
+
/** Arg overrides (optional if preview provided) */
|
|
211
|
+
args?: Record<string, any>;
|
|
212
|
+
/** Preview key resolved during injectPatternPreviews (set at build time) */
|
|
213
|
+
resolvedPreview?: string;
|
|
214
|
+
/** Whether the pattern entry resolved to a usable component preview */
|
|
215
|
+
resolved?: boolean;
|
|
216
|
+
};
|
|
217
|
+
export type PatternObject = {
|
|
218
|
+
title: string;
|
|
219
|
+
description?: string;
|
|
220
|
+
group?: string;
|
|
221
|
+
tags?: string[];
|
|
222
|
+
components: PatternComponentEntry[];
|
|
223
|
+
url?: string;
|
|
224
|
+
};
|
|
225
|
+
export type PatternListObject = {
|
|
226
|
+
id: string;
|
|
227
|
+
path: string;
|
|
228
|
+
} & PatternObject;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { OptionalPreviewRender } from '../preview/types';
|
|
2
|
+
export type StoryObject = {
|
|
3
|
+
name?: string;
|
|
4
|
+
args?: Record<string, any>;
|
|
5
|
+
argTypes?: Record<string, any>;
|
|
6
|
+
render?: (args: Record<string, any>) => any;
|
|
7
|
+
};
|
|
8
|
+
export type CsfMeta = {
|
|
9
|
+
title?: string;
|
|
10
|
+
component?: any;
|
|
11
|
+
args?: Record<string, any>;
|
|
12
|
+
argTypes?: Record<string, any>;
|
|
13
|
+
render?: (args: Record<string, any>) => any;
|
|
14
|
+
};
|
|
15
|
+
export declare function getCsfStoryEntries(moduleExports: Record<string, any>): Array<[string, StoryObject]>;
|
|
16
|
+
export declare function createCsfStoryPreviews(moduleExports: Record<string, any>): Record<string, OptionalPreviewRender>;
|