@uniweb/build 0.8.5 → 0.8.6

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.8.5",
3
+ "version": "0.8.6",
4
4
  "description": "Build tooling for the Uniweb Component Web Platform",
5
5
  "type": "module",
6
6
  "exports": {
@@ -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.4"
64
+ "@uniweb/core": "0.5.5"
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
- console.warn(`Warning: Failed to render ${outputRoute}: ${err.message}`)
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
  }
@@ -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
- 'secondary': 'var(--neutral-100)',
32
+ 'primary-border': 'transparent',
33
+ 'secondary': 'white',
33
34
  'secondary-foreground': 'var(--neutral-900)',
34
- 'secondary-hover': 'var(--neutral-200)',
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
- 'secondary': 'var(--neutral-200)',
60
+ 'primary-border': 'transparent',
61
+ 'secondary': 'white',
59
62
  'secondary-foreground': 'var(--neutral-900)',
60
- 'secondary-hover': 'var(--neutral-300)',
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',
@@ -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 contexts = {
426
- light: { ...defaultContexts.light, ...(rawConfig.contexts?.light || {}) },
427
- medium: { ...defaultContexts.medium, ...(rawConfig.contexts?.medium || {}) },
428
- dark: { ...defaultContexts.dark, ...(rawConfig.contexts?.dark || {}) },
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