@uniweb/build 0.14.12 → 0.14.13

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uniweb/build",
3
- "version": "0.14.12",
3
+ "version": "0.14.13",
4
4
  "description": "Build tooling for the Uniweb Component Web Platform",
5
5
  "type": "module",
6
6
  "exports": {
@@ -59,22 +59,22 @@
59
59
  "js-yaml": "^4.1.0",
60
60
  "sharp": "^0.33.2",
61
61
  "yaml": "^2.5.0",
62
- "@uniweb/theming": "0.1.3",
63
- "@uniweb/content-writer": "0.2.5"
62
+ "@uniweb/content-writer": "0.2.5",
63
+ "@uniweb/theming": "0.1.4"
64
64
  },
65
65
  "optionalDependencies": {
66
+ "@uniweb/runtime": "0.8.18",
66
67
  "@uniweb/content-reader": "1.1.12",
67
- "@uniweb/schemas": "0.2.3",
68
- "@uniweb/runtime": "0.8.17"
68
+ "@uniweb/schemas": "0.2.3"
69
69
  },
70
70
  "peerDependencies": {
71
71
  "vite": "^5.0.0 || ^6.0.0 || ^7.0.0",
72
- "react": "^18.0.0 || ^19.0.0",
73
- "react-dom": "^18.0.0 || ^19.0.0",
72
+ "react": "^19.0.0",
73
+ "react-dom": "^19.0.0",
74
74
  "@tailwindcss/vite": "^4.0.0",
75
75
  "@vitejs/plugin-react": "^4.0.0 || ^5.0.0",
76
76
  "vite-plugin-svgr": "^4.0.0",
77
- "@uniweb/core": "0.7.12"
77
+ "@uniweb/core": "0.7.13"
78
78
  },
79
79
  "peerDependenciesMeta": {
80
80
  "vite": {
@@ -99,6 +99,7 @@ const INFO_TO_SITE_YML = {
99
99
  search: 'search',
100
100
  paths: 'paths',
101
101
  data: 'data',
102
+ template: 'template',
102
103
  }
103
104
 
104
105
  /**
package/src/uwx/site.js CHANGED
@@ -554,6 +554,10 @@ export async function siteProjectToDocument(siteRoot, opts = {}) {
554
554
  setIf(info, 'search', siteYml.search)
555
555
  setIf(info, 'paths', siteYml.paths)
556
556
  setIf(info, 'data', siteYml.data ?? siteYml.fetch)
557
+ // `template: true` designates this site as a clonable SITE-TEMPLATE: on push the
558
+ // backend applies a clonability designation to this site-content entity (it is
559
+ // NOT a registry artifact). Verbatim; absent → a normal (non-template) site.
560
+ setIf(info, 'template', siteYml.template)
557
561
 
558
562
  const ctx = { siteRoot, siteIndex: siteYml.index, sourceLocale, translations }
559
563
  const pagesPath = siteYml.paths?.pages
@@ -13,6 +13,7 @@ import { join, resolve } from 'node:path'
13
13
  import { buildSchema } from './schema.js'
14
14
  import { generateEntryPoint, shouldRegenerateForFile } from './generate-entry.js'
15
15
  import { processAllPreviews } from './images.js'
16
+ import { generateFoundationVars } from './theme/index.js'
16
17
 
17
18
  /**
18
19
  * Build schema.json with preview image references
@@ -300,6 +301,45 @@ async function buildSSRBundle(outDir) {
300
301
  }
301
302
  }
302
303
 
304
+ /**
305
+ * Append the foundation's theme-variable DEFAULTS as a `:root{}` baseline to the
306
+ * built CSS (`assets/style.css`), so a runtime-loaded foundation carries its own
307
+ * var defaults wherever it loads (registry ref / URL — where the site build can't
308
+ * read them). Context-aware vars (color/gradient) are excluded: those are applied
309
+ * per light/dark context by the site theme, not as a flat default. Idempotent
310
+ * (marker-guarded), and a no-op when the foundation declares no vars or ships no
311
+ * stylesheet to carry them.
312
+ */
313
+ async function emitFoundationVarsCss(outDir, schema) {
314
+ const rawVars = schema?._self?.vars
315
+ if (!rawVars || Object.keys(rawVars).length === 0) return
316
+
317
+ const CONTEXT_AWARE = new Set(['color', 'gradient'])
318
+ const flatVars = Object.fromEntries(
319
+ Object.entries(rawVars).filter(
320
+ ([, cfg]) => !(cfg && typeof cfg === 'object' && CONTEXT_AWARE.has(cfg.type))
321
+ )
322
+ )
323
+
324
+ const rootCss = generateFoundationVars(flatVars)
325
+ if (!rootCss) return
326
+
327
+ const cssPath = join(outDir, 'assets', 'style.css')
328
+ if (!existsSync(cssPath)) {
329
+ console.warn(
330
+ `Foundation declares ${Object.keys(flatVars).length} theme var(s) but has no assets/style.css to carry their defaults — skipped.`
331
+ )
332
+ return
333
+ }
334
+
335
+ const marker = '/* uniweb:foundation-var-defaults */'
336
+ const existing = await readFile(cssPath, 'utf-8')
337
+ if (existing.includes(marker)) return
338
+
339
+ await writeFile(cssPath, `${existing.trimEnd()}\n\n${marker}\n${rootCss}\n`, 'utf-8')
340
+ console.log(`Emitted ${Object.keys(flatVars).length} foundation theme-var default(s) to assets/style.css`)
341
+ }
342
+
303
343
  /**
304
344
  * Vite plugin for foundation builds
305
345
  */
@@ -359,6 +399,18 @@ export function foundationBuildPlugin(options = {}) {
359
399
 
360
400
  console.log(`Generated meta/schema.json with ${Object.keys(schema).length - 1} components`)
361
401
 
402
+ // Emit the foundation's theme-variable DEFAULTS as a :root{} baseline into
403
+ // the delivered CSS. A runtime-loaded foundation (registry ref / URL) is
404
+ // loaded with only its dist/ — the site build can't read these defaults
405
+ // (they live in schema._self.vars, which the site never sees), so without
406
+ // this the foundation renders with its theme vars undefined (e.g. collapsed
407
+ // section spacing where components use py-[var(--section-padding-y)]).
408
+ // Shipping the defaults in the foundation's own CSS makes it self-sufficient
409
+ // in every load mode; a site's theme.yml overrides still win (the site theme
410
+ // loads after the foundation CSS). Bundled sites already get these via the
411
+ // site build's theme.css — this is harmless redundancy there.
412
+ await emitFoundationVarsCss(outDir, schema)
413
+
362
414
  // Emit runtime-pin.json so the edge isolate (under Strategy S) can
363
415
  // side-load the matching runtime/{ver}/ssr.js. Lands silently before
364
416
  // the dual-mode resolver ships; foundations published in the dual-mode