@uniweb/runtime 0.6.38 → 0.7.0
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/components/Layout.jsx +15 -3
- package/src/components/PageRenderer.jsx +14 -0
- package/src/hooks/useLinkInterceptor.js +12 -1
- package/src/setup.js +94 -2
- package/dist/app/_importmap/@uniweb-core.js +0 -2
- package/dist/app/_importmap/@uniweb-core.js.map +0 -1
- package/dist/app/_importmap/react-dom.js +0 -2
- package/dist/app/_importmap/react-dom.js.map +0 -1
- package/dist/app/_importmap/react-jsx-dev-runtime.js +0 -2
- package/dist/app/_importmap/react-jsx-dev-runtime.js.map +0 -1
- package/dist/app/_importmap/react-jsx-runtime.js +0 -2
- package/dist/app/_importmap/react-jsx-runtime.js.map +0 -1
- package/dist/app/_importmap/react.js +0 -2
- package/dist/app/_importmap/react.js.map +0 -1
- package/dist/app/assets/_commonjsHelpers-CqkleIqs.js +0 -2
- package/dist/app/assets/_commonjsHelpers-CqkleIqs.js.map +0 -1
- package/dist/app/assets/_importmap_react-dWoQamCw.js +0 -2
- package/dist/app/assets/_importmap_react-dWoQamCw.js.map +0 -1
- package/dist/app/assets/index-C0udIITE.js +0 -9
- package/dist/app/assets/index-C0udIITE.js.map +0 -1
- package/dist/app/assets/index-C6TPxGbh.js +0 -133
- package/dist/app/assets/index-C6TPxGbh.js.map +0 -1
- package/dist/app/assets/index-CsyMBO9p.js +0 -8
- package/dist/app/assets/index-CsyMBO9p.js.map +0 -1
- package/dist/app/assets/index-kA4PVysc.js +0 -2
- package/dist/app/assets/index-kA4PVysc.js.map +0 -1
- package/dist/app/assets/jsx-runtime-C3x2e0aW.js +0 -2
- package/dist/app/assets/jsx-runtime-C3x2e0aW.js.map +0 -1
- package/dist/app/index.html +0 -31
- package/dist/app/manifest.json +0 -19
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uniweb/runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Minimal runtime for loading Uniweb foundations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -35,13 +35,13 @@
|
|
|
35
35
|
"node": ">=20.19"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@uniweb/
|
|
39
|
-
"@uniweb/
|
|
38
|
+
"@uniweb/theming": "0.1.3",
|
|
39
|
+
"@uniweb/core": "0.6.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@vitejs/plugin-react": "^4.5.2",
|
|
43
43
|
"vite": "^7.3.1",
|
|
44
|
-
"@uniweb/build": "0.8.
|
|
44
|
+
"@uniweb/build": "0.8.42"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"react": "^18.0.0 || ^19.0.0",
|
|
@@ -90,11 +90,23 @@ export default function Layout({ page, website }) {
|
|
|
90
90
|
const allBlockGroups = [bodyBlocks, ...Object.values(areas)]
|
|
91
91
|
initializeAllBlocks(...allBlockGroups)
|
|
92
92
|
|
|
93
|
-
// Pre-render each area as React elements
|
|
94
|
-
|
|
93
|
+
// Pre-render each area as React elements.
|
|
94
|
+
// When the foundation enables view transitions, wrap areas in thin divs
|
|
95
|
+
// with view-transition-name so the browser can animate them independently.
|
|
96
|
+
const transitions = website.viewTransitions ? layoutMeta?.transitions : null
|
|
97
|
+
|
|
98
|
+
const bodyElement = bodyBlocks ? (
|
|
99
|
+
transitions?.body
|
|
100
|
+
? <div style={{ viewTransitionName: transitions.body }}><Blocks blocks={bodyBlocks} /></div>
|
|
101
|
+
: <Blocks blocks={bodyBlocks} />
|
|
102
|
+
) : null
|
|
103
|
+
|
|
95
104
|
const areaElements = {}
|
|
96
105
|
for (const [name, blocks] of Object.entries(areas)) {
|
|
97
|
-
|
|
106
|
+
const transitionName = transitions?.[name]
|
|
107
|
+
areaElements[name] = transitionName
|
|
108
|
+
? <div style={{ viewTransitionName: transitionName }}><Blocks blocks={blocks} /></div>
|
|
109
|
+
: <Blocks blocks={blocks} />
|
|
98
110
|
}
|
|
99
111
|
|
|
100
112
|
// Use foundation's custom Layout if provided
|
|
@@ -127,6 +127,16 @@ export default function PageRenderer() {
|
|
|
127
127
|
let page = website?.getPage(location.pathname)
|
|
128
128
|
if (page && website) website.setActivePage(location.pathname)
|
|
129
129
|
|
|
130
|
+
// ─── Content loading (split page content) ───
|
|
131
|
+
// On first load, the current page's sections are pre-embedded → contentReady = true.
|
|
132
|
+
// On SPA navigation to an unvisited page → contentReady = false → fetch → re-render.
|
|
133
|
+
const contentReady = !page || !page.hasContent() || page.isContentLoaded()
|
|
134
|
+
|
|
135
|
+
useEffect(() => {
|
|
136
|
+
if (contentReady) return
|
|
137
|
+
page.loadContent().then(() => forceUpdate())
|
|
138
|
+
}, [page, contentReady])
|
|
139
|
+
|
|
130
140
|
// ─── Compute navigation targets (before hooks, no early returns) ───
|
|
131
141
|
|
|
132
142
|
// Explicit redirect: in page.yml
|
|
@@ -213,6 +223,10 @@ export default function PageRenderer() {
|
|
|
213
223
|
)
|
|
214
224
|
}
|
|
215
225
|
|
|
226
|
+
// Wait for content before rendering blocks (split page content).
|
|
227
|
+
// The prerendered HTML is already visible while we load.
|
|
228
|
+
if (!contentReady) return null
|
|
229
|
+
|
|
216
230
|
const appearance = website?.themeData?.appearance
|
|
217
231
|
|
|
218
232
|
// Use Layout component for proper orchestration
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
import { useEffect, useCallback } from 'react'
|
|
16
16
|
import { useNavigate, useLocation } from 'react-router-dom'
|
|
17
|
+
import { prefetchContent, prefersReducedMotion } from '../setup.js'
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
20
|
* Check if a URL is internal (same origin, no external protocol)
|
|
@@ -193,7 +194,17 @@ export function useLinkInterceptor(options = {}) {
|
|
|
193
194
|
// Use React Router navigation (with router-relative path)
|
|
194
195
|
// React Router will handle the path, and our useEffect above
|
|
195
196
|
// will handle scrolling to hash after navigation completes
|
|
196
|
-
|
|
197
|
+
const useTransition = website?.viewTransitions && document.startViewTransition
|
|
198
|
+
&& !prefersReducedMotion
|
|
199
|
+
|
|
200
|
+
if (useTransition) {
|
|
201
|
+
document.startViewTransition(async () => {
|
|
202
|
+
await prefetchContent(routeHref)
|
|
203
|
+
navigate(routeHref)
|
|
204
|
+
})
|
|
205
|
+
} else {
|
|
206
|
+
navigate(routeHref)
|
|
207
|
+
}
|
|
197
208
|
}
|
|
198
209
|
|
|
199
210
|
// Add click listener to document
|
package/src/setup.js
CHANGED
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
* with routing components, icon resolver, data fetcher, etc.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
import React from 'react'
|
|
8
9
|
import { createUniweb, Website } from '@uniweb/core'
|
|
9
10
|
import {
|
|
10
11
|
Link as RouterLink,
|
|
11
|
-
useNavigate,
|
|
12
|
+
useNavigate as useRouterNavigate,
|
|
12
13
|
useParams,
|
|
13
14
|
useLocation
|
|
14
15
|
} from 'react-router-dom'
|
|
@@ -16,6 +17,97 @@ import {
|
|
|
16
17
|
import { ChildBlocks } from './components/PageRenderer.jsx'
|
|
17
18
|
import { executeFetchClient } from './data-fetcher-client.js'
|
|
18
19
|
|
|
20
|
+
// ─── View Transition Wrappers ───────────────────────────────────────────────
|
|
21
|
+
//
|
|
22
|
+
// When the foundation enables viewTransitions, navigation is wrapped in
|
|
23
|
+
// document.startViewTransition() to animate page changes. Split content
|
|
24
|
+
// is prefetched inside the transition callback so the user never sees
|
|
25
|
+
// a blank or loading state.
|
|
26
|
+
//
|
|
27
|
+
// These wrappers are registered as routing components, so Kit's <Link>
|
|
28
|
+
// and useRouting().useNavigate() automatically get view transition support.
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Prefetch split page content with a timeout.
|
|
32
|
+
* Resolves when content is loaded or the timeout expires — whichever
|
|
33
|
+
* comes first. This keeps the old-page screenshot from freezing too
|
|
34
|
+
* long on slow connections. If the timeout wins, navigation proceeds
|
|
35
|
+
* and the PageRenderer loading gate handles the rest.
|
|
36
|
+
*/
|
|
37
|
+
const CONTENT_PREFETCH_TIMEOUT = 1000
|
|
38
|
+
export const prefersReducedMotion = typeof window !== 'undefined'
|
|
39
|
+
&& window.matchMedia('(prefers-reduced-motion: reduce)').matches
|
|
40
|
+
|
|
41
|
+
export function prefetchContent(route) {
|
|
42
|
+
const website = globalThis.uniweb?.activeWebsite
|
|
43
|
+
if (!route || !website) return
|
|
44
|
+
|
|
45
|
+
const targetPage = website.getPage(route)
|
|
46
|
+
if (!targetPage?.hasContent?.() || targetPage.isContentLoaded?.()) return
|
|
47
|
+
|
|
48
|
+
return Promise.race([
|
|
49
|
+
targetPage.loadContent(),
|
|
50
|
+
new Promise(resolve => setTimeout(resolve, CONTENT_PREFETCH_TIMEOUT))
|
|
51
|
+
])
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Prefetch split content and navigate inside a view transition.
|
|
56
|
+
* Falls back to plain navigation when transitions are not available.
|
|
57
|
+
*/
|
|
58
|
+
function navigateWithTransition(navigate, to, options) {
|
|
59
|
+
const vt = globalThis.uniweb?.foundationConfig?.viewTransitions
|
|
60
|
+
if (vt && document.startViewTransition && !prefersReducedMotion) {
|
|
61
|
+
document.startViewTransition(async () => {
|
|
62
|
+
const route = typeof to === 'string' ? to : to?.pathname
|
|
63
|
+
await prefetchContent(route)
|
|
64
|
+
navigate(to, options)
|
|
65
|
+
})
|
|
66
|
+
} else {
|
|
67
|
+
navigate(to, options)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* View-transition-aware Link component.
|
|
73
|
+
* Intercepts clicks to wrap navigation in startViewTransition() when enabled.
|
|
74
|
+
* Falls through to RouterLink's normal behavior otherwise.
|
|
75
|
+
* Preserves all React Router Link props (replace, state, preventScrollReset).
|
|
76
|
+
*/
|
|
77
|
+
const ViewTransitionLink = React.forwardRef(function ViewTransitionLink(
|
|
78
|
+
{ onClick, replace, state, preventScrollReset, ...props },
|
|
79
|
+
ref
|
|
80
|
+
) {
|
|
81
|
+
const navigate = useRouterNavigate()
|
|
82
|
+
|
|
83
|
+
const handleClick = (e) => {
|
|
84
|
+
if (onClick) onClick(e)
|
|
85
|
+
if (e.defaultPrevented) return
|
|
86
|
+
if (e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) return
|
|
87
|
+
if (e.button !== 0) return
|
|
88
|
+
|
|
89
|
+
const vt = globalThis.uniweb?.foundationConfig?.viewTransitions
|
|
90
|
+
if (!vt || !document.startViewTransition || prefersReducedMotion) return
|
|
91
|
+
|
|
92
|
+
e.preventDefault()
|
|
93
|
+
navigateWithTransition(navigate, props.to, { replace, state, preventScrollReset })
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return React.createElement(RouterLink, {
|
|
97
|
+
ref, ...props, onClick: handleClick,
|
|
98
|
+
replace, state, preventScrollReset
|
|
99
|
+
})
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* View-transition-aware useNavigate hook.
|
|
104
|
+
* The returned function wraps navigation in startViewTransition() when enabled.
|
|
105
|
+
*/
|
|
106
|
+
function useNavigate() {
|
|
107
|
+
const navigate = useRouterNavigate()
|
|
108
|
+
return (to, options) => navigateWithTransition(navigate, to, options)
|
|
109
|
+
}
|
|
110
|
+
|
|
19
111
|
/**
|
|
20
112
|
* Map friendly family names to react-icons codes
|
|
21
113
|
* The existing CDN uses react-icons structure: /{familyCode}/{familyCode}-{name}.svg
|
|
@@ -139,7 +231,7 @@ export function setupUniweb(configData) {
|
|
|
139
231
|
// This enables the bridge pattern: components access routing via
|
|
140
232
|
// website.getRoutingComponents() instead of direct imports
|
|
141
233
|
uniwebInstance.routingComponents = {
|
|
142
|
-
Link:
|
|
234
|
+
Link: ViewTransitionLink,
|
|
143
235
|
useNavigate,
|
|
144
236
|
useParams,
|
|
145
237
|
useLocation
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{B as h,P as g,U as p,W as _,c as f,g as d}from"../assets/index-C6TPxGbh.js";const a=[50,100,200,300,400,500,600,700,800,900,950],r=["light","medium","dark"],n={light:{bg:"var(--neutral-50)",text:"var(--neutral-950)",heading:"var(--neutral-900)",link:"var(--primary-600)"},medium:{bg:"var(--neutral-100)",text:"var(--neutral-950)",heading:"var(--neutral-900)",link:"var(--primary-600)"},dark:{bg:"var(--neutral-900)",text:"var(--neutral-50)",heading:"white",link:"var(--primary-400)"}};class i{constructor(t={}){this._data=t,this._palettes=t.palettes||t.colors||{},this._rawColors=t.colors||{},this._contexts=t.contexts||{},this._fonts=t.fonts||{},this._appearance=t.appearance||{default:"light"},this._foundationVars=t.foundationVars||{},this._css=t.css||null,Object.seal(this)}get css(){return this._css}get data(){return this._data}getColor(t,e=500){const s=this._palettes[t];return s&&s[e]||null}getPalette(t){return this._palettes[t]||null}getPaletteNames(){return Object.keys(this._palettes)}hasPalette(t){return t in this._palettes}getColorVar(t,e=500){return`var(--${t}-${e})`}getContextToken(t,e){const s=this._contexts[t];return s&&s[e]?s[e]:n[t]?.[e]||null}getContextTokens(t){const e=n[t]||{},s=this._contexts[t]||{};return{...e,...s}}getContextClass(t){return r.includes(t)?`context-${t}`:(console.warn(`Invalid context: ${t}. Using 'light'.`),"context-light")}isValidContext(t){return r.includes(t)}getValidContexts(){return[...r]}getAppearance(){return{default:this._appearance.default||"light",allowToggle:this._appearance.allowToggle||!1,respectSystemPreference:this._appearance.respectSystemPreference??!0,schemes:this._appearance.schemes||["light"]}}getDefaultScheme(){return this._appearance.default||"light"}supportsScheme(t){return(this._appearance.schemes||["light"]).includes(t)}hasSchemeToggle(){return this._appearance.allowToggle===!0}getSchemeClass(t){return`scheme-${t}`}getFonts(){return{...this._fonts}}getFont(t){return this._fonts[t]||null}getFontVar(t){return`var(--font-${t})`}getFoundationVar(t){const e=this._foundationVars[t];return e?typeof e=="object"?e.default:e:null}getFoundationVars(){const t={};for(const[e,s]of Object.entries(this._foundationVars))t[e]=typeof s=="object"?s.default:s;return t}getFoundationVarRef(t){return`var(--${t})`}getShadeLevels(){return[...a]}hasCustomization(){return Object.keys(this._palettes).length>0||Object.keys(this._contexts).length>0||Object.keys(this._fonts).length>0}toJSON(){return{palettes:this._palettes,colors:this._rawColors,contexts:this._contexts,fonts:this._fonts,appearance:this._appearance,foundationVars:this._foundationVars}}}export{h as Block,g as Page,i as Theme,p as Uniweb,_ as Website,f as createUniweb,d as getUniweb};
|
|
2
|
-
//# sourceMappingURL=@uniweb-core.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"@uniweb-core.js","sources":["../../../../core/src/theme.js"],"sourcesContent":["/**\n * Theme Class\n *\n * Runtime representation of a site's theme configuration.\n * Provides access to colors, semantic tokens, and appearance settings.\n *\n * @module @uniweb/core/theme\n */\n\n// Standard shade levels\nconst SHADE_LEVELS = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950]\n\n// Valid color contexts\nconst VALID_CONTEXTS = ['light', 'medium', 'dark']\n\n// Default semantic tokens by context\nconst DEFAULT_CONTEXT_TOKENS = {\n light: {\n bg: 'var(--neutral-50)',\n text: 'var(--neutral-950)',\n heading: 'var(--neutral-900)',\n link: 'var(--primary-600)',\n },\n medium: {\n bg: 'var(--neutral-100)',\n text: 'var(--neutral-950)',\n heading: 'var(--neutral-900)',\n link: 'var(--primary-600)',\n },\n dark: {\n bg: 'var(--neutral-900)',\n text: 'var(--neutral-50)',\n heading: 'white',\n link: 'var(--primary-400)',\n },\n}\n\n/**\n * Theme class for runtime theme access\n */\nexport default class Theme {\n /**\n * Create a Theme instance\n *\n * @param {Object} themeData - Processed theme data from build\n * @param {Object} themeData.palettes - Generated color palettes (name → { shade → value })\n * @param {Object} themeData.colors - Raw colors (for reference)\n * @param {Object} themeData.contexts - Context token overrides\n * @param {Object} themeData.fonts - Font configuration\n * @param {Object} themeData.appearance - Appearance settings\n * @param {Object} themeData.foundationVars - Foundation variables\n * @param {string} themeData.css - Pre-generated CSS (optional)\n */\n constructor(themeData = {}) {\n this._data = themeData\n // Use palettes if available, fall back to colors for backwards compatibility\n this._palettes = themeData.palettes || themeData.colors || {}\n this._rawColors = themeData.colors || {}\n this._contexts = themeData.contexts || {}\n this._fonts = themeData.fonts || {}\n this._appearance = themeData.appearance || { default: 'light' }\n this._foundationVars = themeData.foundationVars || {}\n this._css = themeData.css || null\n\n Object.seal(this)\n }\n\n /**\n * Get the pre-generated CSS string\n * @returns {string|null}\n */\n get css() {\n return this._css\n }\n\n /**\n * Get the raw theme data\n * @returns {Object}\n */\n get data() {\n return this._data\n }\n\n // ============================================================\n // Color Access\n // ============================================================\n\n /**\n * Get a color value from a palette\n *\n * @param {string} name - Palette name (e.g., 'primary', 'neutral')\n * @param {number} shade - Shade level (50-950), defaults to 500\n * @returns {string|null} Color value (oklch string) or null if not found\n *\n * @example\n * theme.getColor('primary', 500) // → \"oklch(55.0% 0.2000 260.0)\"\n * theme.getColor('primary') // → same as above (500 is default)\n */\n getColor(name, shade = 500) {\n const palette = this._palettes[name]\n if (!palette) return null\n\n return palette[shade] || null\n }\n\n /**\n * Get all shades for a color palette\n *\n * @param {string} name - Palette name\n * @returns {Object|null} Object with shade levels as keys, or null\n *\n * @example\n * theme.getPalette('primary')\n * // → { 50: \"oklch(...)\", 100: \"oklch(...)\", ... }\n */\n getPalette(name) {\n return this._palettes[name] || null\n }\n\n /**\n * Get all available palette names\n *\n * @returns {string[]} Array of palette names\n */\n getPaletteNames() {\n return Object.keys(this._palettes)\n }\n\n /**\n * Check if a palette exists\n *\n * @param {string} name - Palette name\n * @returns {boolean}\n */\n hasPalette(name) {\n return name in this._palettes\n }\n\n /**\n * Get a CSS variable reference for a color\n *\n * @param {string} name - Palette name\n * @param {number} shade - Shade level\n * @returns {string} CSS var() reference\n *\n * @example\n * theme.getColorVar('primary', 600) // → \"var(--primary-600)\"\n */\n getColorVar(name, shade = 500) {\n return `var(--${name}-${shade})`\n }\n\n // ============================================================\n // Context Access\n // ============================================================\n\n /**\n * Get a semantic token value for a context\n *\n * @param {string} context - Context name ('light', 'medium', 'dark')\n * @param {string} token - Token name (e.g., 'bg', 'text', 'link')\n * @returns {string|null} Token value or null\n *\n * @example\n * theme.getContextToken('light', 'bg') // → \"var(--neutral-50)\"\n * theme.getContextToken('dark', 'text') // → \"var(--neutral-50)\"\n */\n getContextToken(context, token) {\n // Check custom context tokens first\n const customContext = this._contexts[context]\n if (customContext && customContext[token]) {\n return customContext[token]\n }\n\n // Fall back to defaults\n const defaults = DEFAULT_CONTEXT_TOKENS[context]\n return defaults?.[token] || null\n }\n\n /**\n * Get all tokens for a context\n *\n * @param {string} context - Context name\n * @returns {Object} Token name → value mapping\n */\n getContextTokens(context) {\n const defaults = DEFAULT_CONTEXT_TOKENS[context] || {}\n const custom = this._contexts[context] || {}\n return { ...defaults, ...custom }\n }\n\n /**\n * Get the CSS class name for a context\n *\n * @param {string} context - Context name\n * @returns {string} CSS class name\n *\n * @example\n * theme.getContextClass('dark') // → \"context-dark\"\n */\n getContextClass(context) {\n if (!VALID_CONTEXTS.includes(context)) {\n console.warn(`Invalid context: ${context}. Using 'light'.`)\n return 'context-light'\n }\n return `context-${context}`\n }\n\n /**\n * Check if a context is valid\n *\n * @param {string} context - Context name\n * @returns {boolean}\n */\n isValidContext(context) {\n return VALID_CONTEXTS.includes(context)\n }\n\n /**\n * Get all valid context names\n *\n * @returns {string[]}\n */\n getValidContexts() {\n return [...VALID_CONTEXTS]\n }\n\n // ============================================================\n // Appearance (Color Scheme)\n // ============================================================\n\n /**\n * Get appearance configuration\n *\n * @returns {Object} Appearance settings\n * @property {string} default - Default scheme ('light', 'dark', 'system')\n * @property {boolean} allowToggle - Whether scheme toggle is enabled\n * @property {boolean} respectSystemPreference - Honor prefers-color-scheme\n * @property {string[]} schemes - Available schemes\n */\n getAppearance() {\n return {\n default: this._appearance.default || 'light',\n allowToggle: this._appearance.allowToggle || false,\n respectSystemPreference: this._appearance.respectSystemPreference ?? true,\n schemes: this._appearance.schemes || ['light'],\n }\n }\n\n /**\n * Get the default color scheme\n *\n * @returns {string} 'light', 'dark', or 'system'\n */\n getDefaultScheme() {\n return this._appearance.default || 'light'\n }\n\n /**\n * Check if a color scheme is supported\n *\n * @param {string} scheme - Scheme name\n * @returns {boolean}\n */\n supportsScheme(scheme) {\n const schemes = this._appearance.schemes || ['light']\n return schemes.includes(scheme)\n }\n\n /**\n * Check if scheme toggle is enabled\n *\n * @returns {boolean}\n */\n hasSchemeToggle() {\n return this._appearance.allowToggle === true\n }\n\n /**\n * Get the CSS class for a scheme\n *\n * @param {string} scheme - Scheme name\n * @returns {string} CSS class name\n *\n * @example\n * theme.getSchemeClass('dark') // → \"scheme-dark\"\n */\n getSchemeClass(scheme) {\n return `scheme-${scheme}`\n }\n\n // ============================================================\n // Fonts\n // ============================================================\n\n /**\n * Get font configuration\n *\n * @returns {Object} Font settings\n */\n getFonts() {\n return { ...this._fonts }\n }\n\n /**\n * Get a specific font family\n *\n * @param {string} type - Font type ('body', 'heading', 'mono')\n * @returns {string|null} Font family string or null\n */\n getFont(type) {\n return this._fonts[type] || null\n }\n\n /**\n * Get CSS variable reference for a font\n *\n * @param {string} type - Font type\n * @returns {string} CSS var() reference\n */\n getFontVar(type) {\n return `var(--font-${type})`\n }\n\n // ============================================================\n // Foundation Variables\n // ============================================================\n\n /**\n * Get a foundation variable value\n *\n * @param {string} name - Variable name\n * @returns {string|null} Variable value or null\n */\n getFoundationVar(name) {\n const config = this._foundationVars[name]\n if (!config) return null\n return typeof config === 'object' ? config.default : config\n }\n\n /**\n * Get all foundation variables\n *\n * @returns {Object} Variable name → value mapping\n */\n getFoundationVars() {\n const vars = {}\n for (const [name, config] of Object.entries(this._foundationVars)) {\n vars[name] = typeof config === 'object' ? config.default : config\n }\n return vars\n }\n\n /**\n * Get CSS variable reference for a foundation variable\n *\n * @param {string} name - Variable name\n * @returns {string} CSS var() reference\n */\n getFoundationVarRef(name) {\n return `var(--${name})`\n }\n\n // ============================================================\n // Utility Methods\n // ============================================================\n\n /**\n * Get all shade levels\n *\n * @returns {number[]}\n */\n getShadeLevels() {\n return [...SHADE_LEVELS]\n }\n\n /**\n * Check if theme has any custom configuration\n *\n * @returns {boolean}\n */\n hasCustomization() {\n return (\n Object.keys(this._palettes).length > 0 ||\n Object.keys(this._contexts).length > 0 ||\n Object.keys(this._fonts).length > 0\n )\n }\n\n /**\n * Convert theme to a plain object (for serialization)\n *\n * @returns {Object}\n */\n toJSON() {\n return {\n palettes: this._palettes,\n colors: this._rawColors,\n contexts: this._contexts,\n fonts: this._fonts,\n appearance: this._appearance,\n foundationVars: this._foundationVars,\n }\n }\n}\n"],"names":["SHADE_LEVELS","VALID_CONTEXTS","DEFAULT_CONTEXT_TOKENS","Theme","themeData","name","shade","palette","context","token","customContext","defaults","custom","scheme","type","config","vars"],"mappings":"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"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{g as e}from"../assets/_commonjsHelpers-CqkleIqs.js";import{r as o}from"../assets/index-C0udIITE.js";import"../assets/index-kA4PVysc.js";var t=o();const s=e(t),_=t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,c=t.createPortal,d=t.createRoot,u=t.findDOMNode,E=t.flushSync,R=t.hydrate,m=t.hydrateRoot,i=t.render,l=t.unmountComponentAtNode,p=t.unstable_batchedUpdates,N=t.unstable_renderSubtreeIntoContainer,O=t.version;export{_ as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,c as createPortal,d as createRoot,s as default,u as findDOMNode,E as flushSync,R as hydrate,m as hydrateRoot,i as render,l as unmountComponentAtNode,p as unstable_batchedUpdates,N as unstable_renderSubtreeIntoContainer,O as version};
|
|
2
|
-
//# sourceMappingURL=react-dom.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"react-dom.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{g as s}from"../assets/_commonjsHelpers-CqkleIqs.js";var r={exports:{}},e={};var n;function u(){if(n)return e;n=1;var o=Symbol.for("react.fragment");return e.Fragment=o,e.jsxDEV=void 0,e}var i;function a(){return i||(i=1,r.exports=u()),r.exports}var t=a();const x=s(t),v=t.Fragment,c=t.jsxDEV;export{v as Fragment,x as default,c as jsxDEV};
|
|
2
|
-
//# sourceMappingURL=react-jsx-dev-runtime.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"react-jsx-dev-runtime.js","sources":["../../../../../node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react-jsx-dev-runtime.production.min.js","../../../../../node_modules/.pnpm/react@18.3.1/node_modules/react/jsx-dev-runtime.js"],"sourcesContent":["/**\n * @license React\n * react-jsx-dev-runtime.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n'use strict';var a=Symbol.for(\"react.fragment\");exports.Fragment=a;exports.jsxDEV=void 0;\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react-jsx-dev-runtime.production.min.js');\n} else {\n module.exports = require('./cjs/react-jsx-dev-runtime.development.js');\n}\n"],"names":["a","reactJsxDevRuntime_production_min","jsxDevRuntimeModule","require$$0"],"mappings":"wHASa,IAAIA,EAAE,OAAO,IAAI,gBAAgB,EAAE,OAAAC,WAAiBD,EAAEC,EAAA,OAAe,2CCNhFC,EAAA,QAAiBC,EAAA","x_google_ignoreList":[0,1]}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{j as s}from"../assets/jsx-runtime-C3x2e0aW.js";import{a as n}from"../assets/jsx-runtime-C3x2e0aW.js";import"../assets/_commonjsHelpers-CqkleIqs.js";import"../assets/index-kA4PVysc.js";const m=s.Fragment,x=s.jsx,a=s.jsxs;export{m as Fragment,n as default,x as jsx,a as jsxs};
|
|
2
|
-
//# sourceMappingURL=react-jsx-runtime.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"react-jsx-runtime.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{r as e}from"../assets/_importmap_react-dWoQamCw.js";import{R as H}from"../assets/_importmap_react-dWoQamCw.js";import"../assets/_commonjsHelpers-CqkleIqs.js";import"../assets/index-kA4PVysc.js";const o=e.Children,c=e.Component,r=e.Fragment,a=e.Profiler,u=e.PureComponent,l=e.StrictMode,f=e.Suspense,i=e.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,E=e.act,m=e.cloneElement,_=e.createContext,d=e.createElement,R=e.createFactory,S=e.createRef,p=e.forwardRef,C=e.isValidElement,I=e.lazy,T=e.memo,x=e.startTransition,y=e.unstable_act,D=e.useCallback,L=e.useContext,O=e.useDebugValue,b=e.useDeferredValue,F=e.useEffect,N=e.useId,V=e.useImperativeHandle,g=e.useInsertionEffect,v=e.useLayoutEffect,M=e.useMemo,P=e.useReducer,U=e.useRef,h=e.useState,k=e.useSyncExternalStore,w=e.useTransition,z=e.version;export{o as Children,c as Component,r as Fragment,a as Profiler,u as PureComponent,l as StrictMode,f as Suspense,i as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,E as act,m as cloneElement,_ as createContext,d as createElement,R as createFactory,S as createRef,H as default,p as forwardRef,C as isValidElement,I as lazy,T as memo,x as startTransition,y as unstable_act,D as useCallback,L as useContext,O as useDebugValue,b as useDeferredValue,F as useEffect,N as useId,V as useImperativeHandle,g as useInsertionEffect,v as useLayoutEffect,M as useMemo,P as useReducer,U as useRef,h as useState,k as useSyncExternalStore,w as useTransition,z as version};
|
|
2
|
-
//# sourceMappingURL=react.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"react.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_commonjsHelpers-CqkleIqs.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_importmap_react-dWoQamCw.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|