@uniweb/build 0.8.5 → 0.8.7
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 +4 -4
- package/src/prerender.js +18 -1
- package/src/schema.js +4 -4
- package/src/theme/css-generator.js +12 -4
- package/src/theme/processor.js +54 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uniweb/build",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.7",
|
|
4
4
|
"description": "Build tooling for the Uniweb Component Web Platform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -51,8 +51,8 @@
|
|
|
51
51
|
},
|
|
52
52
|
"optionalDependencies": {
|
|
53
53
|
"@uniweb/content-reader": "1.1.4",
|
|
54
|
-
"@uniweb/
|
|
55
|
-
"@uniweb/
|
|
54
|
+
"@uniweb/schemas": "0.2.1",
|
|
55
|
+
"@uniweb/runtime": "0.6.5"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
58
|
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"@tailwindcss/vite": "^4.0.0",
|
|
62
62
|
"@vitejs/plugin-react": "^4.0.0 || ^5.0.0",
|
|
63
63
|
"vite-plugin-svgr": "^4.0.0",
|
|
64
|
-
"@uniweb/core": "0.5.
|
|
64
|
+
"@uniweb/core": "0.5.6"
|
|
65
65
|
},
|
|
66
66
|
"peerDependenciesMeta": {
|
|
67
67
|
"vite": {
|
package/src/prerender.js
CHANGED
|
@@ -825,7 +825,24 @@ export async function prerenderSite(siteDir, options = {}) {
|
|
|
825
825
|
try {
|
|
826
826
|
renderedContent = renderToString(element)
|
|
827
827
|
} catch (err) {
|
|
828
|
-
|
|
828
|
+
const msg = err.message || ''
|
|
829
|
+
|
|
830
|
+
if (msg.includes('Invalid hook call') || msg.includes('useState') || msg.includes('useEffect')) {
|
|
831
|
+
console.warn(
|
|
832
|
+
` Skipped SSG for ${outputRoute} — contains components with React hooks ` +
|
|
833
|
+
`(useState/useEffect) that cannot render during pre-rendering. ` +
|
|
834
|
+
`The page will render correctly client-side.`
|
|
835
|
+
)
|
|
836
|
+
} else if (msg.includes('Element type is invalid') && msg.includes('null')) {
|
|
837
|
+
console.warn(
|
|
838
|
+
` Skipped SSG for ${outputRoute} — a component resolved to null during pre-rendering. ` +
|
|
839
|
+
`This often happens with components that use React hooks. ` +
|
|
840
|
+
`The page will render correctly client-side.`
|
|
841
|
+
)
|
|
842
|
+
} else {
|
|
843
|
+
console.warn(` Warning: Failed to render ${outputRoute}: ${msg}`)
|
|
844
|
+
}
|
|
845
|
+
|
|
829
846
|
if (process.env.DEBUG) {
|
|
830
847
|
console.error(err.stack)
|
|
831
848
|
}
|
package/src/schema.js
CHANGED
|
@@ -251,7 +251,7 @@ async function discoverSectionsInPath(srcDir, sectionsRelPath) {
|
|
|
251
251
|
|
|
252
252
|
if (result && result.meta) {
|
|
253
253
|
// Has meta.js — use explicit meta
|
|
254
|
-
if (result.meta.
|
|
254
|
+
if (result.meta.hidden) continue
|
|
255
255
|
components[entry.name] = buildComponentEntry(entry.name, relativePath, result.meta)
|
|
256
256
|
} else if (hasEntryFile(dirPath, entry.name)) {
|
|
257
257
|
// No meta.js but has entry file — implicit section type at root
|
|
@@ -338,7 +338,7 @@ export async function discoverLayoutsInPath(srcDir, layoutsRelPath = LAYOUTS_PAT
|
|
|
338
338
|
const result = await loadComponentMeta(dirPath)
|
|
339
339
|
|
|
340
340
|
if (result && result.meta) {
|
|
341
|
-
if (result.meta.
|
|
341
|
+
if (result.meta.hidden) continue
|
|
342
342
|
layouts[entry.name] = buildComponentEntry(entry.name, relativePath, result.meta)
|
|
343
343
|
} else if (hasEntryFile(dirPath, entry.name)) {
|
|
344
344
|
layouts[entry.name] = buildComponentEntry(entry.name, relativePath, createImplicitMeta(entry.name))
|
|
@@ -372,7 +372,7 @@ async function discoverNestedSections(srcDir, parentFullPath, parentRelPath, com
|
|
|
372
372
|
const result = await loadComponentMeta(dirPath)
|
|
373
373
|
|
|
374
374
|
if (result && result.meta) {
|
|
375
|
-
if (result.meta.
|
|
375
|
+
if (result.meta.hidden) continue
|
|
376
376
|
components[entry.name] = buildComponentEntry(entry.name, relativePath, result.meta)
|
|
377
377
|
}
|
|
378
378
|
|
|
@@ -406,7 +406,7 @@ async function discoverExplicitSectionsInPath(srcDir, relativePath) {
|
|
|
406
406
|
|
|
407
407
|
if (result && result.meta) {
|
|
408
408
|
// Check if explicitly hidden from discovery
|
|
409
|
-
if (result.meta.
|
|
409
|
+
if (result.meta.hidden) {
|
|
410
410
|
continue
|
|
411
411
|
}
|
|
412
412
|
|
|
@@ -29,9 +29,11 @@ const DEFAULT_CONTEXT_TOKENS = {
|
|
|
29
29
|
'primary': 'var(--primary-600)',
|
|
30
30
|
'primary-foreground': 'white',
|
|
31
31
|
'primary-hover': 'var(--primary-700)',
|
|
32
|
-
'
|
|
32
|
+
'primary-border': 'transparent',
|
|
33
|
+
'secondary': 'white',
|
|
33
34
|
'secondary-foreground': 'var(--neutral-900)',
|
|
34
|
-
'secondary-hover': 'var(--neutral-
|
|
35
|
+
'secondary-hover': 'var(--neutral-100)',
|
|
36
|
+
'secondary-border': 'var(--neutral-300)',
|
|
35
37
|
'success': '#16a34a',
|
|
36
38
|
'success-subtle': '#f0fdf4',
|
|
37
39
|
'warning': '#d97706',
|
|
@@ -55,9 +57,11 @@ const DEFAULT_CONTEXT_TOKENS = {
|
|
|
55
57
|
'primary': 'var(--primary-600)',
|
|
56
58
|
'primary-foreground': 'white',
|
|
57
59
|
'primary-hover': 'var(--primary-700)',
|
|
58
|
-
'
|
|
60
|
+
'primary-border': 'transparent',
|
|
61
|
+
'secondary': 'white',
|
|
59
62
|
'secondary-foreground': 'var(--neutral-900)',
|
|
60
|
-
'secondary-hover': 'var(--neutral-
|
|
63
|
+
'secondary-hover': 'var(--neutral-100)',
|
|
64
|
+
'secondary-border': 'var(--neutral-300)',
|
|
61
65
|
'success': '#16a34a',
|
|
62
66
|
'success-subtle': '#f0fdf4',
|
|
63
67
|
'warning': '#d97706',
|
|
@@ -81,9 +85,11 @@ const DEFAULT_CONTEXT_TOKENS = {
|
|
|
81
85
|
'primary': 'var(--primary-500)',
|
|
82
86
|
'primary-foreground': 'white',
|
|
83
87
|
'primary-hover': 'var(--primary-400)',
|
|
88
|
+
'primary-border': 'transparent',
|
|
84
89
|
'secondary': 'var(--neutral-800)',
|
|
85
90
|
'secondary-foreground': 'var(--neutral-100)',
|
|
86
91
|
'secondary-hover': 'var(--neutral-700)',
|
|
92
|
+
'secondary-border': 'var(--neutral-600)',
|
|
87
93
|
'success': '#4ade80',
|
|
88
94
|
'success-subtle': '#052e16',
|
|
89
95
|
'warning': '#fbbf24',
|
|
@@ -179,9 +185,11 @@ function generateDarkSchemeCSS(config = {}) {
|
|
|
179
185
|
'primary': 'var(--primary-500)',
|
|
180
186
|
'primary-foreground': 'white',
|
|
181
187
|
'primary-hover': 'var(--primary-400)',
|
|
188
|
+
'primary-border': 'transparent',
|
|
182
189
|
'secondary': 'var(--neutral-800)',
|
|
183
190
|
'secondary-foreground': 'var(--neutral-100)',
|
|
184
191
|
'secondary-hover': 'var(--neutral-700)',
|
|
192
|
+
'secondary-border': 'var(--neutral-600)',
|
|
185
193
|
'success': '#4ade80',
|
|
186
194
|
'success-subtle': '#052e16',
|
|
187
195
|
'warning': '#fbbf24',
|
package/src/theme/processor.js
CHANGED
|
@@ -23,11 +23,11 @@ const NEUTRAL_PRESETS = {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
|
-
* Default inline text styles (content-author markdown: [text]{
|
|
26
|
+
* Default inline text styles (content-author markdown: [text]{accent})
|
|
27
27
|
* These reference semantic tokens so they adapt to context automatically
|
|
28
28
|
*/
|
|
29
29
|
const DEFAULT_INLINE = {
|
|
30
|
-
|
|
30
|
+
accent: {
|
|
31
31
|
color: 'var(--link)',
|
|
32
32
|
'font-weight': '600',
|
|
33
33
|
},
|
|
@@ -85,6 +85,45 @@ const DEFAULT_CODE_THEME = {
|
|
|
85
85
|
selection: '#45475a', // Selection background
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
/**
|
|
89
|
+
* Valid shade levels for palette references
|
|
90
|
+
*/
|
|
91
|
+
const SHADE_LEVELS = new Set([50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950])
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Resolve context token values to valid CSS.
|
|
95
|
+
*
|
|
96
|
+
* Content authors write palette references as bare names: `primary-500`,
|
|
97
|
+
* `neutral-200`. This is the natural syntax in theme.yml. The processor
|
|
98
|
+
* resolves these to `var(--primary-500)` etc. Plain CSS values (hex, var(),
|
|
99
|
+
* named colors) pass through as-is — that's the escape hatch.
|
|
100
|
+
*
|
|
101
|
+
* @param {string} value - The token value from theme.yml
|
|
102
|
+
* @returns {string} Valid CSS value
|
|
103
|
+
*/
|
|
104
|
+
function normalizePaletteRef(value) {
|
|
105
|
+
if (typeof value !== 'string') return value
|
|
106
|
+
|
|
107
|
+
// Already a CSS function (var(), rgb(), etc.) — pass through
|
|
108
|
+
if (value.includes('(')) return value
|
|
109
|
+
|
|
110
|
+
// Hex color — pass through
|
|
111
|
+
if (value.startsWith('#')) return value
|
|
112
|
+
|
|
113
|
+
// Bare palette reference: "primary-500", "--primary-500"
|
|
114
|
+
const bare = value.replace(/^-{0,2}/, '')
|
|
115
|
+
const match = bare.match(/^([a-z][a-z0-9]*)-(\d+)$/)
|
|
116
|
+
|
|
117
|
+
if (match) {
|
|
118
|
+
const shade = parseInt(match[2], 10)
|
|
119
|
+
if (SHADE_LEVELS.has(shade)) {
|
|
120
|
+
return `var(--${bare})`
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return value
|
|
125
|
+
}
|
|
126
|
+
|
|
88
127
|
/**
|
|
89
128
|
* Validate color configuration
|
|
90
129
|
*
|
|
@@ -420,12 +459,20 @@ export function processTheme(rawConfig = {}, options = {}) {
|
|
|
420
459
|
warnings.push('No neutral color specified, using default stone (#78716c)')
|
|
421
460
|
}
|
|
422
461
|
|
|
423
|
-
// Process contexts
|
|
462
|
+
// Process contexts (resolve bare palette refs like "primary-500" to var())
|
|
424
463
|
const defaultContexts = getDefaultContextTokens()
|
|
425
|
-
const
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
464
|
+
const rawContexts = rawConfig.contexts || {}
|
|
465
|
+
const contexts = {}
|
|
466
|
+
|
|
467
|
+
for (const name of ['light', 'medium', 'dark']) {
|
|
468
|
+
const overrides = rawContexts[name] || {}
|
|
469
|
+
const normalized = {}
|
|
470
|
+
|
|
471
|
+
for (const [token, value] of Object.entries(overrides)) {
|
|
472
|
+
normalized[token] = normalizePaletteRef(value)
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
contexts[name] = { ...defaultContexts[name], ...normalized }
|
|
429
476
|
}
|
|
430
477
|
|
|
431
478
|
// Process fonts
|