handoff-app 2.0.0-8 → 2.0.0-9

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.
Files changed (34) hide show
  1. package/README.md +19 -3
  2. package/dist/catalog/normalize.js +3 -0
  3. package/dist/catalog/previews.js +5 -4
  4. package/dist/catalog/types.d.ts +8 -0
  5. package/dist/config/loader.js +2 -0
  6. package/dist/config/runtime.js +8 -10
  7. package/dist/handlebars.d.ts +10 -2
  8. package/dist/transformers/plugins/ssr-render.js +40 -15
  9. package/dist/transformers/preview/component/css.d.ts +1 -0
  10. package/dist/transformers/preview/component/css.js +85 -47
  11. package/dist/transformers/preview/pattern/html.js +3 -1
  12. package/dist/transformers/preview/types.d.ts +13 -0
  13. package/dist/transformers/utils/build.d.ts +19 -0
  14. package/dist/transformers/utils/build.js +83 -1
  15. package/dist/transformers/utils/module.js +2 -1
  16. package/dist/types/config.d.ts +6 -0
  17. package/package.json +1 -1
  18. package/src/app/components/Component/PageSliceResolver.tsx +1 -0
  19. package/src/app/components/Component/Preview.tsx +380 -189
  20. package/src/app/components/Component/slices/ComponentDisplaySlice.tsx +4 -0
  21. package/src/catalog/README.md +3 -0
  22. package/src/catalog/normalize.ts +2 -0
  23. package/src/catalog/previews.ts +6 -3
  24. package/src/catalog/types.ts +8 -0
  25. package/src/config/loader.ts +2 -0
  26. package/src/config/runtime.ts +9 -4
  27. package/src/handlebars.ts +8 -2
  28. package/src/transformers/plugins/ssr-render.ts +53 -16
  29. package/src/transformers/preview/component/css.ts +93 -50
  30. package/src/transformers/preview/pattern/html.ts +3 -1
  31. package/src/transformers/preview/types.ts +14 -0
  32. package/src/transformers/utils/build.ts +80 -0
  33. package/src/transformers/utils/module.ts +4 -2
  34. package/src/types/config.ts +6 -0
@@ -1,12 +1,35 @@
1
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
+ };
2
11
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
13
  };
5
14
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.DEFAULT_CLIENT_BUILD_CONFIG = exports.DEFAULT_SSR_BUILD_CONFIG = void 0;
15
+ exports.DEFAULT_CLIENT_BUILD_CONFIG = exports.DEFAULT_SSR_BUILD_CONFIG = exports.STYLE_IMPORT_LOADERS = void 0;
16
+ exports.withStyleLoaders = withStyleLoaders;
17
+ exports.collectStyleImports = collectStyleImports;
7
18
  exports.resolveModule = resolveModule;
8
19
  exports.createReactResolvePlugin = createReactResolvePlugin;
20
+ const esbuild_1 = __importDefault(require("esbuild"));
9
21
  const path_1 = __importDefault(require("path"));
22
+ const STYLE_EXTENSIONS = ['.css', '.scss', '.sass'];
23
+ /**
24
+ * Keeps co-located stylesheet imports out of the JavaScript graph; the CSS pipeline compiles them.
25
+ *
26
+ * esbuild has no `.scss` loader, and a `.css` import fails too because these builds run with
27
+ * `write: false` and no output path. `empty` rather than a plugin: `esbuild.buildSync` rejects
28
+ * plugins, and the declaration and config loaders are synchronous.
29
+ *
30
+ * CSS Modules are not covered — the empty module leaves the class map undefined.
31
+ */
32
+ exports.STYLE_IMPORT_LOADERS = Object.fromEntries(STYLE_EXTENSIONS.map((extension) => [extension, 'empty']));
10
33
  /**
11
34
  * Default esbuild configuration for SSR builds
12
35
  */
@@ -17,6 +40,7 @@ exports.DEFAULT_SSR_BUILD_CONFIG = {
17
40
  platform: 'node',
18
41
  jsx: 'automatic',
19
42
  external: ['react', 'react-dom', '@opentelemetry/api'],
43
+ loader: exports.STYLE_IMPORT_LOADERS,
20
44
  };
21
45
  /**
22
46
  * Default esbuild configuration for client builds
@@ -29,7 +53,65 @@ exports.DEFAULT_CLIENT_BUILD_CONFIG = {
29
53
  jsx: 'automatic',
30
54
  sourcemap: false,
31
55
  minify: false,
56
+ loader: exports.STYLE_IMPORT_LOADERS,
32
57
  };
58
+ /** Apply after a consumer hook: a hook that replaces `loader` would otherwise drop these. */
59
+ function withStyleLoaders(config) {
60
+ return Object.assign(Object.assign({}, config), { loader: Object.assign(Object.assign({}, config.loader), exports.STYLE_IMPORT_LOADERS) });
61
+ }
62
+ /**
63
+ * Stylesheets of the module graph in cascade order: every import of a module before the module
64
+ * itself, siblings in source order.
65
+ *
66
+ * This is the order a bundler emits CSS in, and the cascade depends on it. A component that
67
+ * overrides a rule of a component it imports ties that rule on specificity, so the later of the
68
+ * two wins. esbuild's `onLoad` callbacks do not give this order: they fire roughly breadth-first,
69
+ * which puts a component's own stylesheet ahead of the ones it imports and reverses every such
70
+ * override.
71
+ */
72
+ function orderStyleImports(metafile, entryPath) {
73
+ const entryKey = Object.keys(metafile.inputs).find((key) => path_1.default.resolve(key) === entryPath);
74
+ if (!entryKey)
75
+ return [];
76
+ const ordered = [];
77
+ const visited = new Set();
78
+ const visit = (key) => {
79
+ var _a, _b;
80
+ if (visited.has(key))
81
+ return;
82
+ visited.add(key);
83
+ for (const imported of (_b = (_a = metafile.inputs[key]) === null || _a === void 0 ? void 0 : _a.imports) !== null && _b !== void 0 ? _b : []) {
84
+ if (!imported.external && metafile.inputs[imported.path])
85
+ visit(imported.path);
86
+ }
87
+ if (STYLE_EXTENSIONS.includes(path_1.default.extname(key)))
88
+ ordered.push(path_1.default.resolve(key));
89
+ };
90
+ visit(entryKey);
91
+ return ordered;
92
+ }
93
+ /**
94
+ * Stylesheet paths imported anywhere in a component's module graph, in cascade order.
95
+ *
96
+ * An unbuildable graph yields an empty list rather than throwing, leaving the CSS step with the
97
+ * declared entry.
98
+ */
99
+ function collectStyleImports(entryPath, handoff) {
100
+ return __awaiter(this, void 0, void 0, function* () {
101
+ var _a, _b;
102
+ const baseConfig = Object.assign(Object.assign({}, exports.DEFAULT_SSR_BUILD_CONFIG), { entryPoints: [entryPath], logLevel: 'silent' });
103
+ const hookedConfig = ((_b = (_a = handoff === null || handoff === void 0 ? void 0 : handoff.config) === null || _a === void 0 ? void 0 : _a.hooks) === null || _b === void 0 ? void 0 : _b.ssrBuildConfig) ? handoff.config.hooks.ssrBuildConfig(baseConfig) : baseConfig;
104
+ try {
105
+ // The `empty` loader keeps stylesheets out of the JavaScript, and the metafile still records
106
+ // them as inputs, so the graph carries the order.
107
+ const result = yield esbuild_1.default.build(Object.assign(Object.assign({}, withStyleLoaders(hookedConfig)), { metafile: true }));
108
+ return result.metafile ? orderStyleImports(result.metafile, entryPath) : [];
109
+ }
110
+ catch (_c) {
111
+ return [];
112
+ }
113
+ });
114
+ }
33
115
  /**
34
116
  * Resolves a module from multiple search directories
35
117
  * @param id - Module ID to resolve
@@ -19,9 +19,10 @@ const build_1 = require("./build");
19
19
  function createModuleBuildConfig(entryPath, handoff) {
20
20
  var _a, _b;
21
21
  const defaultBuildConfig = Object.assign(Object.assign({}, build_1.DEFAULT_SSR_BUILD_CONFIG), { entryPoints: [entryPath] });
22
- return ((_b = (_a = handoff.config) === null || _a === void 0 ? void 0 : _a.hooks) === null || _b === void 0 ? void 0 : _b.ssrBuildConfig)
22
+ const hookedBuildConfig = ((_b = (_a = handoff.config) === null || _a === void 0 ? void 0 : _a.hooks) === null || _b === void 0 ? void 0 : _b.ssrBuildConfig)
23
23
  ? handoff.config.hooks.ssrBuildConfig(defaultBuildConfig)
24
24
  : defaultBuildConfig;
25
+ return (0, build_1.withStyleLoaders)(hookedBuildConfig);
25
26
  }
26
27
  function evaluateBuiltModule(code) {
27
28
  const mod = { exports: {} };
@@ -273,6 +273,9 @@ export interface Config {
273
273
  validateComponent?: (component: TransformComponentTokensResult) => Promise<Record<string, ValidationResult>>;
274
274
  /**
275
275
  * Optional hook to override the SSR build configuration used in the ssrRenderPlugin
276
+ *
277
+ * Stylesheet loaders are re-applied after this hook, so a `.css`/`.scss`/`.sass` import stays out
278
+ * of the JavaScript graph whatever the hook returns.
276
279
  * @param config - The default esbuild configuration
277
280
  * @returns Modified esbuild configuration
278
281
  * @example
@@ -286,6 +289,9 @@ export interface Config {
286
289
  ssrBuildConfig?: (config: BuildOptions) => BuildOptions;
287
290
  /**
288
291
  * Optional hook to override the client-side build configuration used in the ssrRenderPlugin
292
+ *
293
+ * Stylesheet loaders are re-applied after this hook, so a `.css`/`.scss`/`.sass` import stays out
294
+ * of the JavaScript graph whatever the hook returns.
289
295
  * @param config - The default esbuild configuration
290
296
  * @returns Modified esbuild configuration
291
297
  * @example
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "handoff-app",
3
- "version": "2.0.0-8",
3
+ "version": "2.0.0-9",
4
4
  "description": "Automated documentation toolchain for building client side documentation from figma",
5
5
  "author ": {
6
6
  "name": "Convertiv",
@@ -44,6 +44,7 @@ export const PageSliceResolver: React.FC<PageSliceResolverProps> = ({
44
44
  showPreview={slice.showPreview}
45
45
  showCodeHighlight={slice.showCodeHighlight}
46
46
  defaultHeight={slice.defaultHeight}
47
+ defaultWidth={slice.defaultWidth}
47
48
  filterBy={slice.filterBy}
48
49
  codeHighlight={codeHighlight}
49
50
  />