@pyreon/ui-core 0.33.0 → 0.35.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/lib/index.d.ts +10 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +21 -4
- package/lib/index.js.map +1 -1
- package/package.json +7 -7
package/lib/index.d.ts
CHANGED
|
@@ -167,6 +167,7 @@ interface ResolvedCssVariablesConfig {
|
|
|
167
167
|
}
|
|
168
168
|
type InitConfig = Partial<CSSEngineConnector & PlatformConfig & {
|
|
169
169
|
cssVariables: boolean | CssVariablesConfig;
|
|
170
|
+
styleExtraction: boolean;
|
|
170
171
|
}>;
|
|
171
172
|
/**
|
|
172
173
|
* Configuration singleton that bridges the UI system with the CSS engine.
|
|
@@ -199,11 +200,20 @@ declare class Configuration {
|
|
|
199
200
|
* assume the flag does not flip mid-session.
|
|
200
201
|
*/
|
|
201
202
|
cssVariables: boolean | CssVariablesConfig;
|
|
203
|
+
/**
|
|
204
|
+
* Opt-in Custom-Property Style Extraction for the default styled/Element
|
|
205
|
+
* pipeline. When true, `PyreonUI` wires `@pyreon/styler`'s `setStyleExtraction`
|
|
206
|
+
* (injecting unistyle's `cpseRewrite`) so non-reactive styled components emit a
|
|
207
|
+
* value-agnostic CSS rule + per-instance inline custom properties (O(1) rules).
|
|
208
|
+
* Off (default) = byte-identical classic path. Set BEFORE first render.
|
|
209
|
+
*/
|
|
210
|
+
styleExtraction: boolean;
|
|
202
211
|
init: (props: InitConfig) => void;
|
|
203
212
|
}
|
|
204
213
|
declare const config: Configuration;
|
|
205
214
|
declare const init: (props: Partial<CSSEngineConnector & PlatformConfig & {
|
|
206
215
|
cssVariables: boolean | CssVariablesConfig;
|
|
216
|
+
styleExtraction: boolean;
|
|
207
217
|
}>) => void;
|
|
208
218
|
/**
|
|
209
219
|
* Resolved view of `config.cssVariables` with defaults applied — the one
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index2.d.ts","names":[],"sources":["../../src/compose.ts","../../src/html/htmlElementAttrs.ts","../../src/html/htmlTags.ts","../../src/html/index.ts","../../src/config.ts","../../src/types.ts","../../src/context.tsx","../../src/hoistNonReactStatics.ts","../../src/isEmpty.ts","../../src/isEqual.ts","../../src/isPyreonComponent.ts","../../src/PyreonUI.tsx","../../src/render.tsx","../../src/resolveSlot.ts","../../src/useStableValue.ts","../../src/utils.ts","../../src/cssVariablesPrePaint.ts"],"mappings":";;;;;KAAK,UAAA,IAAc,GAAQ;AAAA,KACtB,eAAA,oBAAmC,CAAC,aAAa,IAAA,YAAgB,IAAA,aAAiB,CAAA;AAAA,KAClF,oBAAA,oBAAwC,UAAA,CAAW,eAAA,CAAgB,CAAA;AAAA,KACnE,gBAAA,oBAAoC,UAAU,CAAC,CAAA;AAAA,cAE9C,OAAA,aACO,UAAA,OAAiB,GAAA,EAAK,CAAA,MAChC,CAAA,EAAG,oBAAA,CAAqB,CAAA,MAAK,gBAAA,CAAiB,CAAA;;;KCP5C,IAAA,GAAO,WAAW;AAAA,UAEN,gBAAA;EACf,CAAA,EAAG,iBAAA;EACH,IAAA,EAAM,IAAA;EACN,OAAA,EAAS,IAAA;EACT,IAAA,EAAM,eAAA;EACN,OAAA,EAAS,IAAA;EACT,KAAA,EAAO,IAAA;EACP,KAAA,EAAO,gBAAA;EACP,CAAA,EAAG,IAAA;EACH,GAAA,EAAK,IAAA;EACL,GAAA,EAAK,IAAA;EACL,GAAA,EAAK,IAAA;EACL,UAAA,EAAY,gBAAA;EACZ,IAAA,EAAM,eAAA;EACN,EAAA,EAAI,aAAA;EACJ,MAAA,EAAQ,iBAAA;EACR,MAAA,EAAQ,iBAAA;EACR,OAAA,EAAS,IAAA;EACT,IAAA,EAAM,gBAAA;EACN,IAAA,EAAM,IAAA;EACN,GAAA,EAAK,mBAAA;EACL,QAAA,EAAU,mBAAA;EACV,IAAA,EAAM,eAAA;EACN,QAAA,EAAU,mBAAA;EACV,EAAA,EAAI,IAAA;EACJ,GAAA,EAAK,cAAA;EACL,OAAA,EAAS,kBAAA;EACT,GAAA,EAAK,IAAA;EACL,MAAA,EAAQ,iBAAA;EACR,GAAA,EAAK,cAAA;EACL,EAAA,EAAI,gBAAA;EACJ,EAAA,EAAI,IAAA;EACJ,EAAA,EAAI,IAAA;EACJ,KAAA,EAAO,gBAAA;EACP,QAAA,EAAU,mBAAA;EACV,UAAA,EAAY,IAAA;EACZ,MAAA,EAAQ,IAAA;EACR,MAAA,EAAQ,IAAA;EACR,IAAA,EAAM,eAAA;EACN,EAAA,EAAI,kBAAA;EACJ,EAAA,EAAI,kBAAA;EACJ,EAAA,EAAI,kBAAA;EACJ,EAAA,EAAI,kBAAA;EACJ,EAAA,EAAI,kBAAA;EACJ,EAAA,EAAI,kBAAA;EACJ,MAAA,EAAQ,IAAA;EACR,EAAA,EAAI,aAAA;EACJ,IAAA,EAAM,eAAA;EACN,CAAA,EAAG,IAAA;EACH,MAAA,EAAQ,iBAAA;EACR,GAAA,EAAK,gBAAA;EACL,KAAA,EAAO,gBAAA;EACP,GAAA,EAAK,cAAA;EACL,GAAA,EAAK,IAAA;EACL,KAAA,EAAO,gBAAA;EACP,MAAA,EAAQ,iBAAA;EACR,EAAA,EAAI,aAAA;EACJ,IAAA,EAAM,IAAA;EACN,GAAA,EAAK,cAAA;EACL,IAAA,EAAM,IAAA;EACN,KAAA,EAAO,gBAAA;EACP,GAAA,EAAK,IAAA;EACL,MAAA,EAAQ,iBAAA;EACR,EAAA,EAAI,gBAAA;EACJ,QAAA,EAAU,mBAAA;EACV,MAAA,EAAQ,iBAAA;EACR,MAAA,EAAQ,iBAAA;EACR,CAAA,EAAG,oBAAA;EACH,OAAA,EAAS,IAAA;EACT,GAAA,EAAK,cAAA;EACL,QAAA,EAAU,mBAAA;EACV,CAAA,EAAG,gBAAA;EACH,EAAA,EAAI,IAAA;EACJ,EAAA,EAAI,IAAA;EACJ,IAAA,EAAM,IAAA;EACN,CAAA,EAAG,IAAA;EACH,IAAA,EAAM,IAAA;EACN,OAAA,EAAS,IAAA;EACT,MAAA,EAAQ,iBAAA;EACR,KAAA,EAAO,IAAA;EACP,MAAA,EAAQ,iBAAA;EACR,IAAA,EAAM,eAAA;EACN,MAAA,EAAQ,IAAA;EACR,GAAA,EAAK,IAAA;EACL,OAAA,EAAS,IAAA;EACT,GAAA,EAAK,IAAA;EACL,GAAA,EAAK,aAAA;EACL,KAAA,EAAO,gBAAA;EACP,KAAA,EAAO,uBAAA;EACP,EAAA,EAAI,oBAAA;EACJ,QAAA,EAAU,mBAAA;EACV,QAAA,EAAU,mBAAA;EACV,KAAA,EAAO,uBAAA;EACP,EAAA,EAAI,oBAAA;EACJ,KAAA,EAAO,uBAAA;EACP,IAAA,EAAM,eAAA;EACN,EAAA,EAAI,mBAAA;EACJ,KAAA,EAAO,gBAAA;EACP,CAAA,EAAG,IAAA;EACH,EAAA,EAAI,gBAAA;EACJ,GAAA,EAAK,IAAA;EACL,KAAA,EAAO,gBAAA;EACP,GAAA,EAAK,IAAA;AAAA;;;cCxGD,SAAA;AAAA,cAyGA,cAAA;AAAA,KA2CM,QAAA,WAAmB,SAAS;AAAA,KAC5B,YAAA,WAAuB,cAAc;;;KCjJ5C,iBAAA,WAA4B,QAAA,IAAY,CAAA,SAAU,QAAA,GACnD,gBAAA,CAAiB,CAAA,IACjB,MAAA;;;;;;;;UCGa,kBAAA;EACf,GAAA,SAAY,GAAA;EACZ,MAAA,SAAe,MAAA;EACf,SAAA,SAAkB,SAAA;AAAA;AAAA,UAGV,cAAA;EACR,SAAA,WAAoB,QAAA;EACpB,aAAA,WAAwB,QAAA;EACxB,kBAAA,IAAsB,KAAA;IACpB,WAAA,EAAa,MAAA;IACb,QAAA;IACA,GAAA,EAAK,kBAAA;EAAA,MACD,MAAA,aAAmB,IAAA;AAAA;AJrB6D;AAAA;;;AAAA,UI4BvE,kBAAA;EJ3BuC;EI6BtD,MAAA;EJ7BqD;;;;;EImCrD,SAAS;AAAA;AJnC8D;AAAA,UIuCxD,0BAAA;EACf,OAAA;EACA,MAAA;EACA,SAAA;AAAA;AAAA,KAGG,UAAA,GAAa,OAAA,CAChB,kBAAA,
|
|
1
|
+
{"version":3,"file":"index2.d.ts","names":[],"sources":["../../src/compose.ts","../../src/html/htmlElementAttrs.ts","../../src/html/htmlTags.ts","../../src/html/index.ts","../../src/config.ts","../../src/types.ts","../../src/context.tsx","../../src/hoistNonReactStatics.ts","../../src/isEmpty.ts","../../src/isEqual.ts","../../src/isPyreonComponent.ts","../../src/PyreonUI.tsx","../../src/render.tsx","../../src/resolveSlot.ts","../../src/useStableValue.ts","../../src/utils.ts","../../src/cssVariablesPrePaint.ts"],"mappings":"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"}
|
package/lib/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { computed, effect, isClient, registerSingleton, signal } from "@pyreon/reactivity";
|
|
2
|
-
import { ThemeContext, css, keyframes, sheet, styled } from "@pyreon/styler";
|
|
2
|
+
import { ThemeContext, css, keyframes, setStyleExtraction, sheet, styled } from "@pyreon/styler";
|
|
3
3
|
import { createContext, createReactiveContext, h, nativeCompat, provide, useContext } from "@pyreon/core";
|
|
4
|
-
import { enrichTheme, themeToCssVars } from "@pyreon/unistyle";
|
|
4
|
+
import { cpseRewrite, enrichTheme, themeToCssVars } from "@pyreon/unistyle";
|
|
5
5
|
|
|
6
6
|
//#region package.json
|
|
7
7
|
var name = "@pyreon/ui-core";
|
|
8
|
-
var version = "0.
|
|
8
|
+
var version = "0.35.0";
|
|
9
9
|
|
|
10
10
|
//#endregion
|
|
11
11
|
//#region src/compose.ts
|
|
@@ -41,6 +41,14 @@ var Configuration = class {
|
|
|
41
41
|
* assume the flag does not flip mid-session.
|
|
42
42
|
*/
|
|
43
43
|
cssVariables = false;
|
|
44
|
+
/**
|
|
45
|
+
* Opt-in Custom-Property Style Extraction for the default styled/Element
|
|
46
|
+
* pipeline. When true, `PyreonUI` wires `@pyreon/styler`'s `setStyleExtraction`
|
|
47
|
+
* (injecting unistyle's `cpseRewrite`) so non-reactive styled components emit a
|
|
48
|
+
* value-agnostic CSS rule + per-instance inline custom properties (O(1) rules).
|
|
49
|
+
* Off (default) = byte-identical classic path. Set BEFORE first render.
|
|
50
|
+
*/
|
|
51
|
+
styleExtraction = false;
|
|
44
52
|
init = (props) => {
|
|
45
53
|
if (props.css) this.css = props.css;
|
|
46
54
|
if (props.styled) this.styled = props.styled;
|
|
@@ -49,6 +57,7 @@ var Configuration = class {
|
|
|
49
57
|
if (props.textComponent) this.textComponent = props.textComponent;
|
|
50
58
|
if (props.createMediaQueries) this.createMediaQueries = props.createMediaQueries;
|
|
51
59
|
if (props.cssVariables !== void 0) this.cssVariables = props.cssVariables;
|
|
60
|
+
if (props.styleExtraction !== void 0) this.styleExtraction = props.styleExtraction;
|
|
52
61
|
};
|
|
53
62
|
};
|
|
54
63
|
const config = new Configuration();
|
|
@@ -72,6 +81,11 @@ function resolveCssVariables() {
|
|
|
72
81
|
attribute: opts.attribute ?? "data-theme"
|
|
73
82
|
};
|
|
74
83
|
}
|
|
84
|
+
/** Resolved view of `config.styleExtraction` — read by `PyreonUI` to wire
|
|
85
|
+
* styler's CPSE hook. Defaulting lives in one place. */
|
|
86
|
+
function resolveStyleExtraction() {
|
|
87
|
+
return config.styleExtraction === true;
|
|
88
|
+
}
|
|
75
89
|
|
|
76
90
|
//#endregion
|
|
77
91
|
//#region src/isEmpty.ts
|
|
@@ -483,6 +497,7 @@ function PyreonUI(props) {
|
|
|
483
497
|
};
|
|
484
498
|
const modeComputed = computed(resolveMode);
|
|
485
499
|
const cssVars = resolveCssVariables();
|
|
500
|
+
if (resolveStyleExtraction()) setStyleExtraction(true, cpseRewrite);
|
|
486
501
|
const enrichedTheme = computed(() => {
|
|
487
502
|
const t = props.theme;
|
|
488
503
|
if (t === void 0 || t === null) return parentThemeAccessor();
|
|
@@ -538,9 +553,10 @@ const render = (content, attachProps) => {
|
|
|
538
553
|
}
|
|
539
554
|
return h(content, attachProps ?? {});
|
|
540
555
|
}
|
|
541
|
-
/* v8 ignore
|
|
556
|
+
/* v8 ignore start */
|
|
542
557
|
if (typeof content === "object") return content;
|
|
543
558
|
return content;
|
|
559
|
+
/* v8 ignore stop */
|
|
544
560
|
};
|
|
545
561
|
|
|
546
562
|
//#endregion
|
|
@@ -691,6 +707,7 @@ const throttle = (fn, wait = 0, options) => {
|
|
|
691
707
|
if (timeoutId !== void 0) return;
|
|
692
708
|
timeoutId = setTimeout(() => {
|
|
693
709
|
timeoutId = void 0;
|
|
710
|
+
/* v8 ignore else */
|
|
694
711
|
if (lastArgs) {
|
|
695
712
|
invoke(lastArgs);
|
|
696
713
|
lastArgs = void 0;
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["coreContext","__pkgName","__pkgVersion"],"sources":["../package.json","../src/compose.ts","../src/config.ts","../src/isEmpty.ts","../src/context.tsx","../src/hoistNonReactStatics.ts","../src/html/htmlTags.ts","../src/isEqual.ts","../src/isPyreonComponent.ts","../src/PyreonUI.tsx","../src/render.tsx","../src/resolveSlot.ts","../src/useStableValue.ts","../src/utils.ts","../src/cssVariablesPrePaint.ts","../src/index.ts"],"sourcesContent":["","type ArityOneFn = (arg: any) => any\ntype PickLastInTuple<T extends any[]> = T extends [...rest: infer _U, argn: infer L] ? L : any\ntype FirstFnParameterType<T extends any[]> = Parameters<PickLastInTuple<T>>[any]\ntype LastFnReturnType<T extends any[]> = ReturnType<T[0]>\n\nconst compose =\n <T extends ArityOneFn[]>(...fns: T) =>\n (p: FirstFnParameterType<T>): LastFnReturnType<T> =>\n fns.reduceRight((acc: any, cur: any) => cur(acc), p)\n\nexport default compose\n","import type { StyledFunction } from '@pyreon/styler'\nimport { css, keyframes, styled } from '@pyreon/styler'\nimport type { HTMLTags } from './html'\n\n/**\n * Describes the shape of the CSS-in-JS engine.\n * Pyreon uses @pyreon/styler directly — no connector abstraction needed.\n * This type is kept for API compatibility with downstream packages.\n */\nexport interface CSSEngineConnector {\n css: typeof css\n styled: typeof styled\n keyframes: typeof keyframes\n}\n\ninterface PlatformConfig {\n component: string | HTMLTags\n textComponent: string | HTMLTags\n createMediaQueries?: (props: {\n breakpoints: Record<string, number>\n rootSize: number\n css: CSSEngineConnector['css']\n }) => Record<string, (...args: any[]) => any>\n}\n\n/**\n * Options for the opt-in CSS-variables theming mode.\n * `init({ cssVariables: true })` enables it with the defaults.\n */\nexport interface CssVariablesConfig {\n /** Custom-property prefix: `--<prefix>-<path>`. Default `'px'`. */\n prefix?: string\n /**\n * Attribute carrying the active mode (set on `<html>` by the root\n * `PyreonUI`, and on the `display: contents` wrapper of nested\n * inversed / explicit-mode providers). Default `'data-theme'`.\n */\n attribute?: string\n}\n\n/** Resolved (defaulted) view of the cssVariables config. */\nexport interface ResolvedCssVariablesConfig {\n enabled: boolean\n prefix: string\n attribute: string\n}\n\ntype InitConfig = Partial<\n CSSEngineConnector & PlatformConfig & { cssVariables: boolean | CssVariablesConfig }\n>\n\n/**\n * Configuration singleton that bridges the UI system with the CSS engine.\n * All packages reference config.css, config.styled, etc.\n *\n * In Pyreon, the engine is @pyreon/styler and is available immediately —\n * no lazy initialization or connector pattern needed.\n */\nclass Configuration {\n css = css\n styled: StyledFunction = styled\n keyframes = keyframes\n component: string | HTMLTags = 'div'\n textComponent: string | HTMLTags = 'span'\n createMediaQueries: PlatformConfig['createMediaQueries'] = undefined\n /**\n * Opt-in CSS-variables theming mode (the ui-system-wide switch).\n *\n * When enabled: `PyreonUI` autogenerates custom properties from the\n * theme JSON (unistyle's `themeToCssVars`) and injects the `:root`\n * block once; rocketstyle's `mode(a, b)` pairs become hashed var pairs\n * resolved by the `data-theme` attribute; theme resolution turns\n * mode-FREE and a dark/light flip is a single attribute write — no\n * re-resolution, no className churn.\n *\n * Set BEFORE the first render (app boot) — theme-resolution caches\n * assume the flag does not flip mid-session.\n */\n cssVariables: boolean | CssVariablesConfig = false\n\n init = (props: InitConfig) => {\n if (props.css) this.css = props.css\n if (props.styled) this.styled = props.styled\n if (props.keyframes) this.keyframes = props.keyframes\n if (props.component) this.component = props.component\n if (props.textComponent) this.textComponent = props.textComponent\n if (props.createMediaQueries) this.createMediaQueries = props.createMediaQueries\n if (props.cssVariables !== undefined) this.cssVariables = props.cssVariables\n }\n}\n\nconst config = new Configuration()\nconst { init } = config\n\n/**\n * Resolved view of `config.cssVariables` with defaults applied — the one\n * accessor every var-mode consumer (`PyreonUI`, rocketstyle's mode-pair\n * factory) reads, so defaulting lives in exactly one place.\n */\nexport function resolveCssVariables(): ResolvedCssVariablesConfig {\n const raw = config.cssVariables\n if (raw === false) return { enabled: false, prefix: 'px', attribute: 'data-theme' }\n const opts = raw === true ? {} : raw\n return {\n enabled: true,\n prefix: opts.prefix ?? 'px',\n attribute: opts.attribute ?? 'data-theme',\n }\n}\n\nexport default config\nexport { init }\n","export type IsEmpty = <T extends Record<number | string, any> | any[] | null | undefined>(\n param: T,\n) => T extends null | undefined\n ? true\n : keyof T extends never\n ? true\n : T extends T[]\n ? T[number] extends never\n ? true\n : false\n : false\n\nconst isEmpty = (<T extends Record<number | string, any> | any[] | null | undefined>(param: T) => {\n if (!param) return true\n if (typeof param !== 'object') return true\n if (Array.isArray(param)) return param.length === 0\n return Object.keys(param).length === 0\n}) as IsEmpty\n\nexport default isEmpty\n","import type { VNodeChild } from '@pyreon/core'\nimport { createReactiveContext, nativeCompat, provide } from '@pyreon/core'\nimport isEmpty from './isEmpty'\nimport type { Breakpoints } from './types'\n\n/**\n * Core context value shared across all @pyreon UI packages.\n */\nexport interface CoreContextValue {\n theme: Record<string, unknown>\n mode: 'light' | 'dark'\n isDark: boolean\n isLight: boolean\n}\n\n/**\n * Internal reactive context shared across all @pyreon packages.\n * Carries the theme object, mode, and derived dark/light flags.\n *\n * ReactiveContext means useContext() returns `() => CoreContextValue`.\n */\nconst context = createReactiveContext<CoreContextValue>({\n theme: {},\n mode: 'light',\n isDark: false,\n isLight: true,\n})\n\ntype Theme = Partial<\n {\n rootSize: number\n breakpoints: Breakpoints\n } & Record<string, any>\n>\n\ntype ProviderType = Partial<\n {\n theme: Theme\n children: VNodeChild\n } & Record<string, any>\n>\n\n/**\n * @internal Low-level provider — use `PyreonUI` from `@pyreon/ui-core` instead.\n *\n * Provider that feeds the internal Pyreon context with the theme.\n * When no theme is supplied, renders children directly.\n *\n * @deprecated Prefer `<PyreonUI theme={theme}>` which handles all context layers.\n */\nfunction Provider({ theme, children, ...props }: ProviderType): VNodeChild {\n /* v8 ignore next 5 — dev-only warning gate; production NODE_ENV branch not exercised in tests */\n if (process.env.NODE_ENV !== 'production') {\n // oxlint-disable-next-line no-console\n console.warn(\n '[Pyreon] CoreProvider is internal. Use <PyreonUI theme={theme}> instead — it handles all context layers (styler, core, mode) in one component.',\n )\n }\n if (isEmpty(theme) || !theme) return children ?? null\n\n provide(context, () => ({\n theme: theme as Record<string, unknown>,\n mode: (props.mode as 'light' | 'dark') ?? 'light',\n isDark: props.isDark as boolean ?? false,\n isLight: props.isLight as boolean ?? true,\n ...props,\n }))\n\n return children ?? null\n}\n\n// Mark as native — even though @internal, PyreonUI invokes this internally\n// AND the JSX inside PyreonUI's body still routes through the active jsx()\n// runtime (which is the compat one in compat-mode apps). Without the marker,\n// CoreProvider's body runs inside the compat wrapper's runUntracked and its\n// provide() call is swallowed.\nnativeCompat(Provider)\n\nexport { context }\n\nexport default Provider\n","const KNOWN_STATICS: Record<string, true> = {\n name: true,\n length: true,\n prototype: true,\n caller: true,\n callee: true,\n arguments: true,\n arity: true,\n}\n\nconst COMPONENT_STATICS: Record<string, true> = {\n displayName: true,\n defaultProps: true,\n}\n\n/**\n * Copies non-framework static properties from a source component to a target.\n *\n * Pyreon equivalent of hoistNonReactStatics — simplified since Pyreon\n * components are plain functions without React-specific statics like\n * contextType, propTypes, getDerivedStateFromProps, etc.\n */\nconst hoistNonReactStatics = <T, S>(\n target: T,\n source: S,\n excludeList?: Record<string, true>,\n): T => {\n if (typeof source === 'string') return target\n\n const proto = Object.getPrototypeOf(source)\n if (proto && proto !== Object.prototype) {\n hoistNonReactStatics(target, proto, excludeList)\n }\n\n const keys: (string | symbol)[] = [\n ...Object.getOwnPropertyNames(source),\n ...Object.getOwnPropertySymbols(source),\n ]\n\n for (const key of keys) {\n const k = key as string\n if (KNOWN_STATICS[k] || excludeList?.[k] || COMPONENT_STATICS[k]) {\n continue\n }\n\n const descriptor = Object.getOwnPropertyDescriptor(source, key)\n /* v8 ignore next — descriptor is always defined: key came from getOwnPropertyNames(source) */\n if (descriptor) {\n try {\n Object.defineProperty(target, key, descriptor)\n } catch {\n // Silently skip non-configurable properties\n }\n }\n }\n\n return target\n}\n\nexport default hoistNonReactStatics\n","const HTML_TAGS = [\n 'a',\n 'abbr',\n 'address',\n 'area',\n 'article',\n 'aside',\n 'audio',\n 'b',\n 'bdi',\n 'bdo',\n 'big',\n 'blockquote',\n 'body',\n 'br',\n 'button',\n 'canvas',\n 'caption',\n 'cite',\n 'code',\n 'col',\n 'colgroup',\n 'data',\n 'datalist',\n 'dd',\n 'del',\n 'details',\n 'dfn',\n 'dialog',\n 'div',\n 'dl',\n 'dt',\n 'em',\n 'embed',\n 'fieldset',\n 'figcaption',\n 'figure',\n 'footer',\n 'form',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'header',\n 'hr',\n 'html',\n 'i',\n 'iframe',\n 'img',\n 'input',\n 'ins',\n 'kbd',\n 'label',\n 'legend',\n 'li',\n 'main',\n 'map',\n 'mark',\n 'meter',\n 'nav',\n 'object',\n 'ol',\n 'optgroup',\n 'option',\n 'output',\n 'p',\n 'picture',\n 'pre',\n 'progress',\n 'q',\n 'rp',\n 'rt',\n 'ruby',\n 's',\n 'samp',\n 'section',\n 'select',\n 'small',\n 'source',\n 'span',\n 'strong',\n 'sub',\n 'summary',\n 'sup',\n 'svg',\n 'table',\n 'tbody',\n 'td',\n 'template',\n 'textarea',\n 'tfoot',\n 'th',\n 'thead',\n 'time',\n 'tr',\n 'track',\n 'u',\n 'ul',\n 'var',\n 'video',\n 'wbr',\n] as const\n\nconst HTML_TEXT_TAGS = [\n 'abbr',\n 'b',\n 'bdi',\n 'bdo',\n 'big',\n 'blockquote',\n 'cite',\n 'code',\n 'del',\n 'div',\n 'dl',\n 'dt',\n 'em',\n 'figcaption',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'i',\n 'ins',\n 'kbd',\n 'label',\n 'legend',\n 'li',\n 'p',\n 'pre',\n 'q',\n 'rp',\n 'rt',\n 's',\n 'small',\n 'span',\n 'strong',\n 'sub',\n 'summary',\n 'sup',\n 'time',\n 'u',\n] as const\n\nexport type HTMLTags = (typeof HTML_TAGS)[number]\nexport type HTMLTextTags = (typeof HTML_TEXT_TAGS)[number]\nexport { HTML_TAGS, HTML_TEXT_TAGS }\n","const isArrayEqual = (a: unknown[], b: unknown[]): boolean => {\n if (a.length !== b.length) return false\n for (let i = 0; i < a.length; i++) {\n if (!isEqual(a[i], b[i])) return false\n }\n return true\n}\n\nconst isObjectEqual = (a: Record<string, unknown>, b: Record<string, unknown>): boolean => {\n const aKeys = Object.keys(a)\n if (aKeys.length !== Object.keys(b).length) return false\n for (const key of aKeys) {\n if (!Object.hasOwn(b, key)) return false\n if (!isEqual(a[key], b[key])) return false\n }\n return true\n}\n\nconst isEqual = (a: unknown, b: unknown): boolean => {\n if (Object.is(a, b)) return true\n if (typeof a !== typeof b || a == null || b == null || typeof a !== 'object') return false\n if (Array.isArray(a)) return Array.isArray(b) && isArrayEqual(a, b)\n if (Array.isArray(b)) return false\n return isObjectEqual(a as Record<string, unknown>, b as Record<string, unknown>)\n}\n\nexport default isEqual\n","/**\n * Detect whether a function value is a component (framework-marked OR\n * user-authored bare function), as opposed to a plain reactive-accessor\n * function.\n *\n * Used by `resolveSlot` (and any other slot-resolver) to discriminate\n * between\n * `beforeContent={Header}` — component-reference shorthand, MUST mount\n * as `h(Component, null)` so the framework's runWithHooks setup\n * window is established (and any framework HOC's\n * `removeUndefinedProps(props)` / `splitProps(props)` get the\n * default-filled props object, not bare `undefined`).\n * `beforeContent={() => <Header />}` — anonymous reactive accessor,\n * called bare so its body's signal reads land inside the enclosing\n * `mountReactive` effect.\n *\n * Both shapes are `typeof === 'function'`. The discriminator combines two\n * checks (most-specific-first):\n *\n * **Tier 1 — framework markers** (load-bearing for HOC pipelines):\n * - `IS_ROCKETSTYLE` — set by `@pyreon/rocketstyle`\n * (`rocketstyle.ts:527`, `542`) on every `rocketstyle(...).config(...)`\n * chain end-point.\n * - `PYREON__COMPONENT` — set by every `@pyreon/elements` component\n * factory (Element, Text, List, Portal, Overlay, Util, Content,\n * Wrapper, …).\n * - `pkgName` — same components also carry this; checked as a fallback\n * in case a third-party package mirrors the elements convention.\n *\n * **Tier 2 — naming convention** (catches user-authored bare components\n * without markers):\n * - `displayName` is set → component. Authors set displayName\n * deliberately for devtools / debug output; it's an explicit\n * declaration of component intent.\n * - `.name` starts with an uppercase letter → component. JSX already\n * requires PascalCase for components (`<MyComp/>` is treated as a\n * component; `<mycomp/>` is treated as a host tag); the discriminator\n * mirrors that convention for slot-shorthand usage. Anonymous\n * arrows (`name: \"\"`), default-export functions (`name: \"default\"`),\n * and camelCase helpers fall through to the accessor path.\n *\n * Why Tier 2 matters — the bug class it closes: a bare-function component\n * that internally uses lifecycle hooks (`useWindowResize`, `onMount`,\n * `provide`, etc.) needs a `runWithHooks` setup window so the hook calls\n * find `_current` non-null. Without Tier 2, `resolveSlot` would call the\n * function bare → `_current === null` → `[Pyreon] onMount() called outside\n * component setup` warning fires in dev-mode SSR. Routing the same\n * function through `h(value, null)` mounts it as a proper component via\n * the standard `runWithHooks`-based path; the hooks register correctly\n * AND the warning never fires.\n *\n * Why the convention split is safe: a PascalCase function paired with\n * the `beforeContent={Fn}` shorthand is canonically a component reference\n * (matches every framework example in the docs). An anonymous arrow\n * `() => signal() ? <A/> : <B/>` is canonically a reactive accessor\n * (intent: re-evaluate on signal change). The naming convention is the\n * same one JSX itself uses to differentiate component vs host element.\n *\n * Before this check, `resolveSlot` called any function-valued slot\n * bare, crashing real consumers that used the\n * `beforeContent={Component}` shorthand documented since the original\n * Element API. The marker check (Tier 1) rescues framework-factory\n * components; this Tier-2 convention check closes the residual gap\n * for user-authored hook-using bare components.\n */\nexport function isPyreonComponent(value: unknown): boolean {\n if (typeof value !== 'function') return false\n // ── Tier 1 — framework markers ──────────────────────────────────────\n // `Object.hasOwn` (not `in`) so a marker on a parent prototype doesn't\n // count — the marker is always an own-property in the factories.\n if (\n Object.hasOwn(value, 'IS_ROCKETSTYLE') ||\n Object.hasOwn(value, 'PYREON__COMPONENT') ||\n Object.hasOwn(value, 'pkgName')\n ) {\n return true\n }\n // ── Tier 2 — naming convention ──────────────────────────────────────\n const fn = value as { displayName?: unknown; name?: unknown }\n // displayName: explicit author intent. Any non-empty string counts.\n if (typeof fn.displayName === 'string' && fn.displayName.length > 0) {\n return true\n }\n // .name: inferred function name (`const Header = () => …` → \"Header\";\n // `function Header()` → \"Header\"; anonymous arrow → \"\"). PascalCase\n // first letter matches JSX's own component-vs-host discriminator.\n const name = fn.name\n if (typeof name === 'string' && name.length > 0) {\n const first = name.charCodeAt(0)\n // Uppercase A-Z range (65-90). Avoids unicode-letter false-positives\n // and skips `name === \"default\"` from `export default () => …`.\n if (first >= 65 && first <= 90) return true\n }\n return false\n}\n","import type { VNodeChild } from '@pyreon/core'\nimport {\n createContext,\n createReactiveContext,\n h,\n nativeCompat,\n provide,\n useContext,\n} from '@pyreon/core'\nimport { computed, effect, isClient, signal } from '@pyreon/reactivity'\nimport { sheet, ThemeContext } from '@pyreon/styler'\nimport type { PyreonTheme } from '@pyreon/unistyle'\nimport { enrichTheme, themeToCssVars } from '@pyreon/unistyle'\nimport { resolveCssVariables } from './config'\nimport { context as coreContext } from './context'\n\n// Structural flag distinguishing the ROOT PyreonUI from a NESTED one (a\n// plain context, not reactive — nesting is fixed at mount). In cssVariables\n// mode the root writes the mode attribute to `document.documentElement`\n// (so it sits at `:root`, where the pre-paint FOUC script also writes and\n// where the var rules cascade from), while nested / `inversed` providers\n// render a `display: contents` wrapper that scopes an override to their\n// subtree. Putting the root on a wrapper instead would let the wrapper —\n// a closer ancestor than `<html>` — defeat a pre-paint script that can\n// only reach `document.documentElement` before the in-body wrapper parses.\nconst PyreonUINestedContext = createContext(false)\n\n// ─── Types ──────────────────────────────────────────────────────────────────\n\nexport type ThemeMode = 'light' | 'dark'\nexport type ThemeModeInput = ThemeMode | 'system'\n\nexport interface PyreonUIProps {\n /**\n * Theme object with breakpoints, rootSize, and custom keys.\n *\n * Optional — when omitted, the theme is INHERITED from the nearest\n * ancestor PyreonUI. This makes nested `<PyreonUI inversed>` work\n * without re-passing the theme:\n *\n * ```tsx\n * <PyreonUI theme={appTheme}>\n * <Header />\n * <PyreonUI inversed> // inherits appTheme, just flips mode\n * <DarkSidebar />\n * </PyreonUI>\n * </PyreonUI>\n * ```\n *\n * At the OUTERMOST PyreonUI with no ancestor, the provided ThemeContext\n * value falls back to the default `{}` (styled components see fields as\n * undefined; no crash). Pass a real theme at the outermost PyreonUI to\n * avoid that.\n */\n theme?: PyreonTheme | undefined\n /**\n * Color mode: \"light\", \"dark\", or \"system\" (follows OS preference).\n * Can be a signal or getter for reactive mode switching.\n *\n * When omitted, mode is INHERITED from the nearest ancestor PyreonUI\n * (or `'light'` at the root).\n */\n mode?: ThemeModeInput | (() => ThemeModeInput) | undefined\n /**\n * Flip mode for a nested section (e.g. dark sidebar in light app).\n * Scoped — only affects DESCENDANTS of this PyreonUI; ancestors and\n * siblings see the original mode unchanged.\n */\n inversed?: boolean | undefined\n children?: VNodeChild\n}\n\n// ─── System mode detection ──────────────────────────────────────────────────\n\n// `isClient` is the canonical DOM-present guard; `matchMedia` is an extra\n// FEATURE check (system color-scheme needs it), kept rather than folded in.\nconst _isBrowser = isClient && typeof matchMedia === 'function'\n\n/** Reactive signal tracking the OS dark mode preference. Lazy-initialized on first use. */\nlet _systemMode: ReturnType<typeof signal<ThemeMode>> | undefined\n\nfunction getSystemMode(): ReturnType<typeof signal<ThemeMode>> {\n if (_systemMode) return _systemMode\n\n // Ternary (not `&&`) so the typeof-derived `_isBrowser` guard is\n // statically verifiable as protecting the `matchMedia` access — same\n // runtime value (`false` on the server), SSR-safe + analyzer-clear.\n /* v8 ignore next 3 — `_isBrowser` is always true in tests (happy-dom + matchMedia); SSR branch covered by typeof guard */\n const prefersDark = _isBrowser\n ? matchMedia('(prefers-color-scheme: dark)').matches\n : false\n _systemMode = signal<ThemeMode>(prefersDark ? 'dark' : 'light')\n\n /* v8 ignore next 5 — same SSR/typeof gate as above */\n if (_isBrowser) {\n matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {\n _systemMode?.set(e.matches ? 'dark' : 'light')\n })\n }\n\n return _systemMode\n}\n\n// ─── Mode context ───────────────────────────────────────────────────────────\n\n/** Reactive context — useContext(ModeContext) returns () => ThemeMode. */\nconst ModeContext = createReactiveContext<ThemeMode>('light')\n\nconst INVERSED: Record<ThemeMode, ThemeMode> = { light: 'dark', dark: 'light' }\n\n/**\n * Read the resolved color mode (\"light\" | \"dark\") from the nearest PyreonUI.\n * Reactive — updates when the mode prop changes or when OS preference changes\n * (if mode=\"system\").\n *\n * @example\n * const mode = useMode() // \"light\" | \"dark\"\n */\nexport function useMode(): ThemeMode {\n return useContext(ModeContext)()\n}\n\n// ─── Auto-init ──────────────────────────────────────────────────────────────\n\nlet _autoInitDone = false\n\nfunction autoInit(): void {\n if (_autoInitDone) return\n _autoInitDone = true\n}\n\n// ─── PyreonUI ───────────────────────────────────────────────────────────────\n\n/**\n * Unified provider for the Pyreon UI system.\n *\n * Replaces the need for separate UnistyleProvider, RocketstyleProvider,\n * and ThemeProvider — one component, zero init.\n *\n * Mode can be a static string OR a signal/getter for reactive switching:\n * ```tsx\n * // Static\n * <PyreonUI theme={theme} mode=\"dark\">\n *\n * // Reactive signal\n * const mode = signal<ThemeModeInput>(\"light\")\n * <PyreonUI theme={theme} mode={mode}>\n *\n * // System (follows OS preference)\n * <PyreonUI theme={theme} mode=\"system\">\n * ```\n */\nexport function PyreonUI(props: PyreonUIProps): VNodeChild {\n autoInit()\n\n // IMPORTANT: do NOT destructure props. Components run once in Pyreon, and\n // destructuring captures values at setup time — losing reactivity. Reading\n // `props.mode` / `props.inversed` lazily inside `resolveMode()` lets the\n // computed re-evaluate when the underlying reactive props change (parent\n // re-renders with a different value, or signal-driven mode toggling).\n //\n // Previously this destructured `{ theme, mode = 'light', inversed, children }`\n // which made `inversed` permanently static — toggling inversed in a parent\n // had no effect because the local boolean was captured once. See\n // `.claude/rules/anti-patterns.md` \"Destructuring props\" entry.\n\n // Create a reactive mode getter that resolves \"system\" and applies inversion.\n // This getter is provided via context — consumers read it lazily in their\n // own reactive scopes, so mode changes propagate automatically.\n //\n // When `inversed` is set without an explicit `mode`, inherit the parent's\n // mode and flip it. This makes nested `<PyreonUI inversed>` work reactively:\n // outer light → inner dark, outer dark → inner light.\n //\n // useContext(ModeContext) returns the reactive accessor from the nearest\n // parent PyreonUI. At root level (no parent), the ReactiveContext default\n // returns 'light'. This read is TRACKED inside the computed below, so when\n // the parent's mode changes, this child's computed re-evaluates.\n const parentModeAccessor = useContext(ModeContext)\n // Same shape for theme — useContext(ThemeContext) is a reactive accessor.\n // When `props.theme` is omitted, we provide the parent's theme through\n // verbatim (already enriched at the level it was provided). Re-enriching\n // would be idempotent but wasteful, AND would replace the parent's exact\n // `__PYREON__` reference, which downstream identity-keyed caches (styler's\n // class cache, rocketstyle's per-definition WeakMaps) rely on for hits.\n // Pass-through preserves identity.\n const parentThemeAccessor = useContext(ThemeContext)\n const resolveMode = (): ThemeMode => {\n const mode = props.mode\n let resolved: ThemeMode\n if (mode === undefined || mode === null) {\n // No explicit mode — inherit from parent context\n resolved = parentModeAccessor()\n } else {\n const raw = typeof mode === 'function' ? mode() : mode\n resolved = raw === 'system' ? getSystemMode()() : raw\n }\n return props.inversed ? INVERSED[resolved] : resolved\n }\n\n // Wrap in computed for memoization\n const modeComputed = computed(resolveMode)\n\n // Enrich theme — wrapped in computed so user-preference theme swaps\n // propagate. The enrichment itself is cheap (builds a __PYREON__ block).\n //\n // When `props.theme` is omitted, return the parent's theme verbatim\n // (already enriched). Without this, `enrichTheme(undefined)` would\n // destructure undefined and throw — but the throw happens LAZILY (the\n // computed is only read when a child consumes ThemeContext), so the\n // failure mode is the cryptic dev-mode warning\n // `[pyreon] Unhandled effect error: TypeError: Cannot destructure property\n // 'breakpoints' of 'theme' as it is undefined`\n // followed by every styled descendant rendering with an empty theme.\n // That's what made the user's nested `<PyreonUI inversed>` \"look like\n // inversed wasn't working\" — the whole subtree was broken.\n // Resolved once at setup — the cssVariables switch is a boot-time contract\n // (set via init() before the first render); theme-resolution caches across\n // the ui-system assume it does not flip mid-session.\n const cssVars = resolveCssVariables()\n\n const enrichedTheme = computed(() => {\n const t = props.theme\n if (t === undefined || t === null) return parentThemeAccessor()\n const enriched = enrichTheme(t)\n if (!cssVars.enabled) return enriched\n // CSS-variables mode: every eligible theme leaf becomes a 'var(--px-…)'\n // string and the :root block is injected ONCE per theme identity\n // (injectRules is idempotent by key and SSR-aware — on the server the\n // block lands in the ssrBuffer that getStyleTag()/the stream flush emit).\n // Downstream consumers (styler templates, rocketstyle callbacks, the\n // unistyle value pipeline) read the var references verbatim, so a mode\n // flip never re-resolves any of them.\n const { vars, css: varsCss } = themeToCssVars(enriched, { prefix: cssVars.prefix })\n if (varsCss) sheet.injectRules([varsCss], varsCss)\n // Same tree shape; leaves are var() reference strings — every theme\n // value position accepts strings, so the widened leaf type is safe.\n return vars as unknown as ReturnType<typeof enrichTheme>\n })\n\n // Provide to all three context layers:\n\n // 1. Styler ThemeContext — reactive accessor. DynamicStyled reads this\n // inside its computed() to re-resolve CSS on theme swap.\n provide(ThemeContext, () => enrichedTheme())\n\n // 2. Core context — provide a reactive getter function.\n // coreContext is a ReactiveContext, so provide(() => value).\n // Rocketstyle reads mode/isDark/isLight by calling the getter.\n //\n // LAZY getters (not eager fields) are load-bearing: reading `.theme`\n // must NOT transitively subscribe to `modeComputed`. With eager fields\n // (`{ theme: enrichedTheme(), mode: modeComputed() }`) the object\n // construction reads modeComputed(), so ANY consumer touching `.theme`\n // re-runs on every mode flip — even under cssVariables, where component\n // resolution is supposed to be mode-free (the flip is an attribute write,\n // the cascade does the rest). Getters defer each read: a component that\n // reads only `.theme` subscribes only to `enrichedTheme` (stable on flip\n // → no re-run); classic-mode resolution that reads `.mode` still\n // subscribes to `modeComputed` (re-runs on flip → correct).\n provide(coreContext, () => ({\n get theme() {\n return enrichedTheme()\n },\n get mode() {\n return modeComputed()\n },\n get isDark() {\n return modeComputed() === 'dark'\n },\n get isLight() {\n return modeComputed() === 'light'\n },\n }))\n\n // 3. Mode context — getter function for useMode()\n provide(ModeContext, () => modeComputed())\n\n if (!cssVars.enabled) return props.children ?? null\n\n // Is this the ROOT PyreonUI (no PyreonUI ancestor) or a NESTED one?\n const isNested = useContext(PyreonUINestedContext)\n // Descendants are nested under us regardless.\n provide(PyreonUINestedContext, true)\n\n if (!isNested) {\n // ROOT, cssVariables mode: drive the mode attribute on\n // `document.documentElement` so it lives at `:root` — where the var\n // rules cascade from AND where a pre-paint FOUC script writes before\n // first paint. The effect keeps it in sync with reactive mode changes\n // (toggles, system-pref flips) after hydration; the flip is one\n // attribute write, zero re-resolution, zero className churn. SSR can't\n // touch `document` — there, first-paint correctness comes from the\n // pre-paint script (system/persisted) or an explicit `<html>` stamp;\n // see `cssVariablesPrePaintScript`. No wrapper at the root: a wrapper\n // would be a closer ancestor than `<html>` and defeat that script.\n if (isClient) {\n // Intentional reactive DOM sync: this MUST re-run whenever modeComputed\n // changes (toggle / system-pref flip), so onMount (runs once) cannot do\n // it — same shape as the framework's own renderEffect/_bind DOM writes.\n // It's a one-line attribute write, not the fetch/timer imperative-work\n // the rule guards against.\n // pyreon-lint-disable-next-line pyreon/no-imperative-effect-on-create\n effect(() => {\n document.documentElement.setAttribute(cssVars.attribute, modeComputed())\n })\n }\n return props.children ?? null\n }\n\n // NESTED / `inversed` cssVariables provider: render a layout-neutral\n // wrapper carrying the mode attribute. The cascade does the rest —\n // `[data-theme=\"dark\"]` re-resolves every mode-pair var for THIS subtree\n // only, so a scoped dark/light section is one attribute write with zero\n // re-resolution and zero className churn. Server-rendered too.\n return h(\n 'div',\n {\n style: 'display: contents',\n [cssVars.attribute]: () => modeComputed(),\n },\n props.children ?? null,\n )\n}\n\n// Mark as native — compat-mode jsx() runtimes skip wrapCompatComponent so\n// PyreonUI's three provide() calls + useContext(ModeContext) read run inside\n// Pyreon's setup frame. Critical for compat-mode apps that wrap their tree\n// with <PyreonUI> at the top level — without the marker, theme/mode never\n// propagate to descendants.\nnativeCompat(PyreonUI)\n","import type { ComponentFn, Props, VNodeChild } from '@pyreon/core'\nimport { h } from '@pyreon/core'\n\ntype RenderProps<T extends Record<string, unknown> | undefined> = (props: Partial<T>) => VNodeChild\n\n/**\n * Flexible element renderer that handles multiple content types:\n * - Primitives (string, number) — returned as-is\n * - Arrays — returned as-is\n * - Component functions — created via h()\n * - VNode objects — returned as-is (with props merged if provided)\n * - Render props (functions) — called with attachProps\n * - Falsy values — return null\n */\nexport type Render = <T extends Record<string, any> | undefined>(\n content?: ComponentFn | string | VNodeChild | VNodeChild[] | RenderProps<T>,\n attachProps?: T,\n) => VNodeChild\n\nconst render: Render = (content, attachProps) => {\n if (!content) return null\n\n const t = typeof content\n if (t === 'string' || t === 'number' || t === 'boolean' || t === 'bigint') {\n return content as VNodeChild\n }\n\n if (Array.isArray(content)) {\n return content as VNodeChild\n }\n\n if (typeof content === 'function') {\n // Extract key from props — it's a VNode concept, not a component prop.\n // Passing key inside props causes JSX runtime warnings.\n if (attachProps && 'key' in attachProps) {\n const { key: _key, ...rest } = attachProps\n return h(content as string | ComponentFn, rest as Props)\n }\n return h(content as string | ComponentFn, (attachProps ?? {}) as Props)\n }\n\n // VNode object — return directly\n /* v8 ignore next 4 — fallthrough after typeof guards above; the trailing return is structurally unreachable */\n if (typeof content === 'object') {\n return content as VNodeChild\n }\n\n return content as VNodeChild\n}\n\nexport default render\n","import { h } from '@pyreon/core'\nimport type { ComponentFn, VNodeChildAtom } from '@pyreon/core'\nimport { isPyreonComponent } from './isPyreonComponent'\nimport render from './render'\n\n/**\n * Resolve a slot value INSIDE a reactive accessor. If the consumer passed\n * a function-returning-VNode (e.g. `content={() => <Icon name={signal()} />}`),\n * unwrap it by calling — its body's signal reads are then tracked by the\n * enclosing mountReactive effect, and the slot re-renders on signal change.\n * Static VNodes / strings / null pass through unchanged to `render()`.\n *\n * **Component vs accessor discriminator** —\n * `beforeContent={Header}` (component-reference shorthand) and\n * `content={() => <X />}` (reactive accessor) are BOTH `typeof === 'function'`.\n * Calling both bare crashes component shorthands the moment a\n * rocketstyle / attrs HOC runs `removeUndefinedProps(undefined)` on the\n * un-supplied props (`TypeError: Cannot convert undefined or null to object`).\n *\n * Discriminator: framework components carry one of two markers attached by\n * their factory:\n * - `IS_ROCKETSTYLE` — anything `rocketstyle()` produces\n * - `PYREON__COMPONENT` / `pkgName` — `@pyreon/elements` components\n * (Element, Text, List, Portal, Overlay, Util)\n * Marked function → mount as `h(Component, null)` (no props, defaults\n * fill in via the HOC pipeline). Unmarked function → reactive accessor,\n * called bare so its return value (a VNode) renders. Bare-function\n * components without HOC wrapping (e.g. `const MyComp = () => <div />`)\n * also work via the accessor path — they're called with no args and\n * their VNode return goes through `render()` correctly. The marker\n * check ONLY rescues components that REQUIRE props to be defined.\n * Tier 2 of `isPyreonComponent` (PascalCase `.name` / explicit\n * `displayName`) additionally catches user-authored bare components\n * that use lifecycle hooks — see `isPyreonComponent` JSDoc.\n *\n * Return type is the RESOLVED atom (VNodeChildAtom | VNodeChildAtom[]) —\n * never a nested accessor — so the enclosing `() => resolveSlot(...)` IS\n * a valid VNodeChildAccessor in the JSX child position.\n */\nexport const resolveSlot = (value: unknown): VNodeChildAtom | VNodeChildAtom[] => {\n if (typeof value === 'function') {\n if (isPyreonComponent(value)) {\n return h(value as ComponentFn, null) as VNodeChildAtom\n }\n return (value as () => VNodeChildAtom | VNodeChildAtom[])()\n }\n return render(value as Parameters<typeof render>[0]) as VNodeChildAtom | VNodeChildAtom[]\n}\n\nexport default resolveSlot\n","import { signal } from '@pyreon/reactivity'\nimport isEqual from './isEqual'\n\n/**\n * Returns a referentially stable version of `value`. The returned reference\n * only changes when the value is no longer deeply equal to the previous one.\n *\n * Pyreon equivalent of the React useStableValue hook — uses a signal\n * internally to hold the stable reference.\n */\nconst useStableValue = <T>(value: T): T => {\n const ref = signal(value)\n\n /* v8 ignore next 3 — defensive: ref was just initialized with `value`, isEqual is always true */\n if (!isEqual(ref.peek(), value)) {\n ref.set(value)\n }\n\n return ref.peek()\n}\n\nexport default useStableValue\n","/**\n * Returns a copy of `obj` without the specified keys.\n *\n * Accepts either an array of keys (builds a Set internally) or a\n * pre-built `Set<string>` for hot paths where the same key list is\n * reused across many calls (avoids per-call Set allocation).\n *\n * Copies own property DESCRIPTORS (not values) so that getter-shaped\n * properties — produced by `makeReactiveProps` in `@pyreon/core` for\n * compiler-emitted `<Comp prop={signal()}>` — survive the copy with\n * their reactive subscription intact. For data properties the\n * behaviour is identical to value-copying.\n */\nexport const omit = <T extends Record<string, any>>(\n obj: T | null | undefined,\n keys?: readonly (string | keyof T)[] | Set<string>,\n): Partial<T> => {\n if (obj == null) return {} as Partial<T>\n const descriptors = Object.getOwnPropertyDescriptors(obj)\n if (!keys || (keys instanceof Set ? keys.size === 0 : keys.length === 0)) {\n return Object.defineProperties({} as Partial<T>, descriptors)\n }\n const keysSet = keys instanceof Set ? keys : new Set(keys as readonly string[])\n const result: Record<string, any> = {}\n for (const key of Object.keys(descriptors)) {\n if (!keysSet.has(key)) {\n Object.defineProperty(result, key, descriptors[key]!)\n }\n }\n return result as Partial<T>\n}\n\n/**\n * Returns a copy of `obj` containing only the specified keys.\n *\n * See `omit` above — same descriptor-preserving semantics: getter-\n * shaped properties survive the copy with reactive subscription\n * intact. For data properties the behaviour is identical to\n * value-copying.\n */\nexport const pick = <T extends Record<string, any>>(\n obj: T | null | undefined,\n keys?: readonly (string | keyof T)[],\n): Partial<T> => {\n if (obj == null) return {} as Partial<T>\n if (!keys || keys.length === 0) {\n return Object.defineProperties(\n {} as Partial<T>,\n Object.getOwnPropertyDescriptors(obj),\n )\n }\n const result: Record<string, any> = {}\n for (const key of keys) {\n const k = key as string\n const descriptor = Object.getOwnPropertyDescriptor(obj, k)\n if (descriptor) {\n Object.defineProperty(result, k, descriptor)\n }\n }\n return result as Partial<T>\n}\n\nconst PATH_RE = /[^.[\\]]+/g\n\nconst parsePath = (path: string | string[]): string[] => {\n if (Array.isArray(path)) return path\n const parts = path.match(PATH_RE)\n return parts ?? []\n}\n\nconst isUnsafeKey = (key: string): boolean =>\n key === '__proto__' || key === 'prototype' || key === 'constructor'\n\nexport const get = (obj: any, path: string | string[], defaultValue?: any): any => {\n const keys = parsePath(path)\n let result = obj\n for (const key of keys) {\n if (result == null || isUnsafeKey(key)) return defaultValue\n result = result[key]\n }\n return result === undefined ? defaultValue : result\n}\n\nexport const set = (\n obj: Record<string, any>,\n path: string | string[],\n value: any,\n): Record<string, any> => {\n const keys = parsePath(path)\n let current = obj\n for (let i = 0; i < keys.length - 1; i++) {\n const key = keys[i] as string\n if (isUnsafeKey(key)) return obj\n const nextKey = keys[i + 1] as string\n if (isUnsafeKey(nextKey)) return obj\n if (current[key] == null) {\n current[key] = /^\\d+$/.test(nextKey) ? [] : {}\n }\n current = current[key]\n }\n const lastKey = keys[keys.length - 1]\n if (lastKey != null && !isUnsafeKey(lastKey)) {\n current[lastKey] = value\n }\n return obj\n}\n\nexport const throttle = <T extends (...args: any[]) => any>(\n fn: T,\n wait: number = 0,\n options?: { leading?: boolean; trailing?: boolean },\n): T & { cancel: () => void } => {\n const leading = options?.leading !== false\n const trailing = options?.trailing !== false\n let lastCallTime: number | undefined\n let timeoutId: ReturnType<typeof setTimeout> | undefined\n let lastArgs: any[] | undefined\n\n const invoke = (args: any[]) => {\n lastCallTime = Date.now()\n fn(...args)\n }\n\n const startTrailingTimer = (args: any[], delay: number) => {\n lastArgs = args\n if (timeoutId !== undefined) return\n timeoutId = setTimeout(() => {\n timeoutId = undefined\n if (lastArgs) {\n invoke(lastArgs)\n lastArgs = undefined\n }\n }, delay)\n }\n\n const throttled = (...args: any[]) => {\n const now = Date.now()\n const elapsed = lastCallTime === undefined ? wait : now - lastCallTime\n if (elapsed >= wait) {\n if (leading) {\n invoke(args)\n } else {\n lastCallTime = now\n if (trailing) startTrailingTimer(args, wait)\n }\n } else if (trailing) {\n startTrailingTimer(args, wait - elapsed)\n }\n }\n\n throttled.cancel = () => {\n if (timeoutId !== undefined) {\n clearTimeout(timeoutId)\n timeoutId = undefined\n }\n lastArgs = undefined\n lastCallTime = undefined\n }\n\n return throttled as T & { cancel: () => void }\n}\n\nconst isPlainObject = (value: unknown): value is Record<string, any> =>\n value !== null &&\n typeof value === 'object' &&\n !Array.isArray(value) &&\n Object.getPrototypeOf(value) === Object.prototype\n\nexport const merge = <T extends Record<string, any>>(\n target: T,\n ...sources: Record<string, any>[]\n): T => {\n for (const source of sources) {\n if (source == null) continue\n for (const key of Object.keys(source)) {\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') continue\n const targetVal = (target as Record<string, unknown>)[key]\n const sourceVal = source[key]\n if (isPlainObject(targetVal) && isPlainObject(sourceVal)) {\n ;(target as Record<string, unknown>)[key] = merge({ ...targetVal }, sourceVal)\n } else {\n ;(target as Record<string, unknown>)[key] = sourceVal\n }\n }\n }\n return target\n}\n","import { resolveCssVariables } from './config'\n\nexport interface CssVariablesPrePaintOptions {\n /**\n * Mode attribute to set on `document.documentElement`. Defaults to the\n * resolved `init({ cssVariables })` attribute (`'data-theme'`).\n */\n attribute?: string\n /**\n * localStorage key a persisted user toggle is stored under. Defaults to\n * `'zero-theme'` (the `@pyreon/zero` convention). Values `'light'` /\n * `'dark'` win; anything else falls back to the system preference.\n */\n storageKey?: string\n /**\n * Mode to use when there is no stored preference AND the system query is\n * unavailable. Defaults to `'light'`.\n */\n fallback?: 'light' | 'dark'\n}\n\n/**\n * Build the blocking pre-paint script that sets the CSS-variables mode\n * attribute on `document.documentElement` BEFORE first paint — the standard\n * dark-mode FOUC fix.\n *\n * Inject the returned string as a synchronous `<script>` in `<head>` (it\n * must run before the body paints). It reads a persisted toggle from\n * localStorage, else the OS `prefers-color-scheme`, else `fallback`, and\n * writes the attribute at `:root` — exactly where the var rules cascade\n * from and where the ROOT `PyreonUI` writes after hydration, so the two\n * agree and there is no flash for `mode=\"system\"` or a persisted toggle.\n *\n * (Explicit hardcoded `mode=\"dark\"` with SSR and NO stored preference is the\n * one case this can't cover — the mode lives only in the app's JSX, unknown\n * to a pre-paint script; stamp `<html data-theme=\"dark\">` server-side for\n * that, or store the preference.)\n *\n * Self-contained, dependency-free, try/catch-wrapped (a storage/matchMedia\n * throw must never block paint). Safe to inline verbatim.\n *\n * @example\n * // zero injects this automatically when init({ cssVariables: true }).\n * const script = cssVariablesPrePaintScript()\n * // <script>{script}</script> in <head>\n */\nexport function cssVariablesPrePaintScript(options: CssVariablesPrePaintOptions = {}): string {\n const attribute = options.attribute ?? resolveCssVariables().attribute\n const storageKey = options.storageKey ?? 'zero-theme'\n const fallback = options.fallback ?? 'light'\n // JSON.stringify keeps the embedded strings safe inside the inline script.\n const attr = JSON.stringify(attribute)\n const key = JSON.stringify(storageKey)\n const fb = JSON.stringify(fallback)\n return (\n `(function(){try{` +\n `var s=localStorage.getItem(${key});` +\n `var m=s===\"light\"||s===\"dark\"?s:` +\n `(window.matchMedia&&window.matchMedia(\"(prefers-color-scheme:dark)\").matches?\"dark\":${fb});` +\n `document.documentElement.setAttribute(${attr},m)` +\n `}catch(e){}})()`\n )\n}\n","import { name as __pkgName, version as __pkgVersion } from '../package.json' with { type: 'json' }\nimport { registerSingleton } from '@pyreon/reactivity'\n\n// Singleton sentinel — fail-loud detection of duplicate @pyreon/ui-core\n// instances in the same heap. See @pyreon/reactivity/singleton-sentinel for\n// full rationale. Hardcoded version is acceptable here — it's a diagnostic\n// aid, not a load-bearing identity check.\nregisterSingleton(__pkgName, __pkgVersion, import.meta.url)\n\nimport compose from './compose'\nimport config, { init } from './config'\nimport type { CoreContextValue } from './context'\nimport Provider, { context } from './context'\nimport hoistNonReactStatics from './hoistNonReactStatics'\nimport type { HTMLElementAttrs, HTMLTagAttrsByTag, HTMLTags, HTMLTextTags } from './html'\nimport { HTML_TAGS, HTML_TEXT_TAGS } from './html'\nimport type { IsEmpty } from './isEmpty'\nimport isEmpty from './isEmpty'\nimport isEqual from './isEqual'\nimport { isPyreonComponent } from './isPyreonComponent'\nimport type { PyreonUIProps, ThemeMode, ThemeModeInput } from './PyreonUI'\nimport { PyreonUI, useMode } from './PyreonUI'\nimport type { Render } from './render'\nimport render from './render'\nimport { resolveSlot } from './resolveSlot'\nimport type { BreakpointKeys, Breakpoints } from './types'\nimport useStableValue from './useStableValue'\nimport { get, merge, omit, pick, set, throttle } from './utils'\n\nexport type { CSSEngineConnector, CssVariablesConfig, ResolvedCssVariablesConfig } from './config'\nexport { resolveCssVariables } from './config'\nexport type { CssVariablesPrePaintOptions } from './cssVariablesPrePaint'\nexport { cssVariablesPrePaintScript } from './cssVariablesPrePaint'\n\nexport type {\n BreakpointKeys,\n Breakpoints,\n CoreContextValue,\n HTMLElementAttrs,\n HTMLTagAttrsByTag,\n HTMLTags,\n HTMLTextTags,\n IsEmpty,\n PyreonUIProps,\n Render,\n ThemeMode,\n ThemeModeInput,\n}\n\nexport {\n compose,\n config,\n context,\n get,\n HTML_TAGS,\n HTML_TEXT_TAGS,\n hoistNonReactStatics,\n init,\n isEmpty,\n isEqual,\n isPyreonComponent,\n merge,\n omit,\n Provider,\n PyreonUI,\n pick,\n render,\n resolveSlot,\n set,\n throttle,\n useMode,\n useStableValue,\n}\n"],"mappings":";;;;;;;;;;;ACKA,MAAM,WACqB,GAAG,SAC3B,MACC,IAAI,aAAa,KAAU,QAAa,IAAI,GAAG,GAAG,CAAC;;;;;;;;;;;ACkDvD,IAAM,gBAAN,MAAoB;CAClB,MAAM;CACN,SAAyB;CACzB,YAAY;CACZ,YAA+B;CAC/B,gBAAmC;CACnC,qBAA2D;;;;;;;;;;;;;;CAc3D,eAA6C;CAE7C,QAAQ,UAAsB;EAC5B,IAAI,MAAM,KAAK,KAAK,MAAM,MAAM;EAChC,IAAI,MAAM,QAAQ,KAAK,SAAS,MAAM;EACtC,IAAI,MAAM,WAAW,KAAK,YAAY,MAAM;EAC5C,IAAI,MAAM,WAAW,KAAK,YAAY,MAAM;EAC5C,IAAI,MAAM,eAAe,KAAK,gBAAgB,MAAM;EACpD,IAAI,MAAM,oBAAoB,KAAK,qBAAqB,MAAM;EAC9D,IAAI,MAAM,iBAAiB,QAAW,KAAK,eAAe,MAAM;CAClE;AACF;AAEA,MAAM,SAAS,IAAI,cAAc;AACjC,MAAM,EAAE,SAAS;;;;;;AAOjB,SAAgB,sBAAkD;CAChE,MAAM,MAAM,OAAO;CACnB,IAAI,QAAQ,OAAO,OAAO;EAAE,SAAS;EAAO,QAAQ;EAAM,WAAW;CAAa;CAClF,MAAM,OAAO,QAAQ,OAAO,CAAC,IAAI;CACjC,OAAO;EACL,SAAS;EACT,QAAQ,KAAK,UAAU;EACvB,WAAW,KAAK,aAAa;CAC/B;AACF;;;;AChGA,MAAM,YAA+E,UAAa;CAChG,IAAI,CAAC,OAAO,OAAO;CACnB,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,IAAI,MAAM,QAAQ,KAAK,GAAG,OAAO,MAAM,WAAW;CAClD,OAAO,OAAO,KAAK,KAAK,EAAE,WAAW;AACvC;;;;;;;;;;ACIA,MAAM,UAAU,sBAAwC;CACtD,OAAO,CAAC;CACR,MAAM;CACN,QAAQ;CACR,SAAS;AACX,CAAC;;;;;;;;;AAwBD,SAAS,SAAS,EAAE,OAAO,UAAU,GAAG,SAAmC;;CAEzE,IAAI,QAAQ,IAAI,aAAa,cAE3B,QAAQ,KACN,gJACF;CAEF,IAAI,QAAQ,KAAK,KAAK,CAAC,OAAO,OAAO,YAAY;CAEjD,QAAQ,gBAAgB;EACf;EACP,MAAO,MAAM,QAA6B;EAC1C,QAAQ,MAAM,UAAqB;EACnC,SAAS,MAAM,WAAsB;EACrC,GAAG;CACL,EAAE;CAEF,OAAO,YAAY;AACrB;AAOA,aAAa,QAAQ;;;;AC5ErB,MAAM,gBAAsC;CAC1C,MAAM;CACN,QAAQ;CACR,WAAW;CACX,QAAQ;CACR,QAAQ;CACR,WAAW;CACX,OAAO;AACT;AAEA,MAAM,oBAA0C;CAC9C,aAAa;CACb,cAAc;AAChB;;;;;;;;AASA,MAAM,wBACJ,QACA,QACA,gBACM;CACN,IAAI,OAAO,WAAW,UAAU,OAAO;CAEvC,MAAM,QAAQ,OAAO,eAAe,MAAM;CAC1C,IAAI,SAAS,UAAU,OAAO,WAC5B,qBAAqB,QAAQ,OAAO,WAAW;CAGjD,MAAM,OAA4B,CAChC,GAAG,OAAO,oBAAoB,MAAM,GACpC,GAAG,OAAO,sBAAsB,MAAM,CACxC;CAEA,KAAK,MAAM,OAAO,MAAM;EACtB,MAAM,IAAI;EACV,IAAI,cAAc,MAAM,cAAc,MAAM,kBAAkB,IAC5D;EAGF,MAAM,aAAa,OAAO,yBAAyB,QAAQ,GAAG;;EAE9D,IAAI,YACF,IAAI;GACF,OAAO,eAAe,QAAQ,KAAK,UAAU;EAC/C,QAAQ,CAER;CAEJ;CAEA,OAAO;AACT;;;;ACzDA,MAAM,YAAY;CAChB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,MAAM,iBAAiB;CACrB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;;;AClJA,MAAM,gBAAgB,GAAc,MAA0B;CAC5D,IAAI,EAAE,WAAW,EAAE,QAAQ,OAAO;CAClC,KAAK,IAAI,IAAI,GAAG,IAAI,EAAE,QAAQ,KAC5B,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,GAAG,OAAO;CAEnC,OAAO;AACT;AAEA,MAAM,iBAAiB,GAA4B,MAAwC;CACzF,MAAM,QAAQ,OAAO,KAAK,CAAC;CAC3B,IAAI,MAAM,WAAW,OAAO,KAAK,CAAC,EAAE,QAAQ,OAAO;CACnD,KAAK,MAAM,OAAO,OAAO;EACvB,IAAI,CAAC,OAAO,OAAO,GAAG,GAAG,GAAG,OAAO;EACnC,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAG,OAAO;CACvC;CACA,OAAO;AACT;AAEA,MAAM,WAAW,GAAY,MAAwB;CACnD,IAAI,OAAO,GAAG,GAAG,CAAC,GAAG,OAAO;CAC5B,IAAI,OAAO,MAAM,OAAO,KAAK,KAAK,QAAQ,KAAK,QAAQ,OAAO,MAAM,UAAU,OAAO;CACrF,IAAI,MAAM,QAAQ,CAAC,GAAG,OAAO,MAAM,QAAQ,CAAC,KAAK,aAAa,GAAG,CAAC;CAClE,IAAI,MAAM,QAAQ,CAAC,GAAG,OAAO;CAC7B,OAAO,cAAc,GAA8B,CAA4B;AACjF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACyCA,SAAgB,kBAAkB,OAAyB;CACzD,IAAI,OAAO,UAAU,YAAY,OAAO;CAIxC,IACE,OAAO,OAAO,OAAO,gBAAgB,KACrC,OAAO,OAAO,OAAO,mBAAmB,KACxC,OAAO,OAAO,OAAO,SAAS,GAE9B,OAAO;CAGT,MAAM,KAAK;CAEX,IAAI,OAAO,GAAG,gBAAgB,YAAY,GAAG,YAAY,SAAS,GAChE,OAAO;CAKT,MAAM,OAAO,GAAG;CAChB,IAAI,OAAO,SAAS,YAAY,KAAK,SAAS,GAAG;EAC/C,MAAM,QAAQ,KAAK,WAAW,CAAC;EAG/B,IAAI,SAAS,MAAM,SAAS,IAAI,OAAO;CACzC;CACA,OAAO;AACT;;;;ACrEA,MAAM,wBAAwB,cAAc,KAAK;AAmDjD,MAAM,aAAa,YAAY,OAAO,eAAe;;AAGrD,IAAI;AAEJ,SAAS,gBAAsD;CAC7D,IAAI,aAAa,OAAO;CASxB,cAAc,QAHM,aAChB,WAAW,8BAA8B,EAAE,UAC3C,SAC0C,SAAS,OAAO;;CAG9D,IAAI,YACF,WAAW,8BAA8B,EAAE,iBAAiB,WAAW,MAAM;EAC3E,aAAa,IAAI,EAAE,UAAU,SAAS,OAAO;CAC/C,CAAC;CAGH,OAAO;AACT;;AAKA,MAAM,cAAc,sBAAiC,OAAO;AAE5D,MAAM,WAAyC;CAAE,OAAO;CAAQ,MAAM;AAAQ;;;;;;;;;AAU9E,SAAgB,UAAqB;CACnC,OAAO,WAAW,WAAW,EAAE;AACjC;AAIA,IAAI,gBAAgB;AAEpB,SAAS,WAAiB;CACxB,IAAI,eAAe;CACnB,gBAAgB;AAClB;;;;;;;;;;;;;;;;;;;;AAuBA,SAAgB,SAAS,OAAkC;CACzD,SAAS;CAyBT,MAAM,qBAAqB,WAAW,WAAW;CAQjD,MAAM,sBAAsB,WAAW,YAAY;CACnD,MAAM,oBAA+B;EACnC,MAAM,OAAO,MAAM;EACnB,IAAI;EACJ,IAAI,SAAS,UAAa,SAAS,MAEjC,WAAW,mBAAmB;OACzB;GACL,MAAM,MAAM,OAAO,SAAS,aAAa,KAAK,IAAI;GAClD,WAAW,QAAQ,WAAW,cAAc,EAAE,IAAI;EACpD;EACA,OAAO,MAAM,WAAW,SAAS,YAAY;CAC/C;CAGA,MAAM,eAAe,SAAS,WAAW;CAkBzC,MAAM,UAAU,oBAAoB;CAEpC,MAAM,gBAAgB,eAAe;EACnC,MAAM,IAAI,MAAM;EAChB,IAAI,MAAM,UAAa,MAAM,MAAM,OAAO,oBAAoB;EAC9D,MAAM,WAAW,YAAY,CAAC;EAC9B,IAAI,CAAC,QAAQ,SAAS,OAAO;EAQ7B,MAAM,EAAE,MAAM,KAAK,YAAY,eAAe,UAAU,EAAE,QAAQ,QAAQ,OAAO,CAAC;EAClF,IAAI,SAAS,MAAM,YAAY,CAAC,OAAO,GAAG,OAAO;EAGjD,OAAO;CACT,CAAC;CAMD,QAAQ,oBAAoB,cAAc,CAAC;CAgB3C,QAAQA,gBAAoB;EAC1B,IAAI,QAAQ;GACV,OAAO,cAAc;EACvB;EACA,IAAI,OAAO;GACT,OAAO,aAAa;EACtB;EACA,IAAI,SAAS;GACX,OAAO,aAAa,MAAM;EAC5B;EACA,IAAI,UAAU;GACZ,OAAO,aAAa,MAAM;EAC5B;CACF,EAAE;CAGF,QAAQ,mBAAmB,aAAa,CAAC;CAEzC,IAAI,CAAC,QAAQ,SAAS,OAAO,MAAM,YAAY;CAG/C,MAAM,WAAW,WAAW,qBAAqB;CAEjD,QAAQ,uBAAuB,IAAI;CAEnC,IAAI,CAAC,UAAU;EAWb,IAAI,UAOF,aAAa;GACX,SAAS,gBAAgB,aAAa,QAAQ,WAAW,aAAa,CAAC;EACzE,CAAC;EAEH,OAAO,MAAM,YAAY;CAC3B;CAOA,OAAO,EACL,OACA;EACE,OAAO;GACN,QAAQ,kBAAkB,aAAa;CAC1C,GACA,MAAM,YAAY,IACpB;AACF;AAOA,aAAa,QAAQ;;;;ACvTrB,MAAM,UAAkB,SAAS,gBAAgB;CAC/C,IAAI,CAAC,SAAS,OAAO;CAErB,MAAM,IAAI,OAAO;CACjB,IAAI,MAAM,YAAY,MAAM,YAAY,MAAM,aAAa,MAAM,UAC/D,OAAO;CAGT,IAAI,MAAM,QAAQ,OAAO,GACvB,OAAO;CAGT,IAAI,OAAO,YAAY,YAAY;EAGjC,IAAI,eAAe,SAAS,aAAa;GACvC,MAAM,EAAE,KAAK,MAAM,GAAG,SAAS;GAC/B,OAAO,EAAE,SAAiC,IAAa;EACzD;EACA,OAAO,EAAE,SAAkC,eAAe,CAAC,CAAW;CACxE;;CAIA,IAAI,OAAO,YAAY,UACrB,OAAO;CAGT,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACTA,MAAa,eAAe,UAAsD;CAChF,IAAI,OAAO,UAAU,YAAY;EAC/B,IAAI,kBAAkB,KAAK,GACzB,OAAO,EAAE,OAAsB,IAAI;EAErC,OAAQ,MAAkD;CAC5D;CACA,OAAO,OAAO,KAAqC;AACrD;;;;;;;;;;;ACrCA,MAAM,kBAAqB,UAAgB;CACzC,MAAM,MAAM,OAAO,KAAK;;CAGxB,IAAI,CAAC,QAAQ,IAAI,KAAK,GAAG,KAAK,GAC5B,IAAI,IAAI,KAAK;CAGf,OAAO,IAAI,KAAK;AAClB;;;;;;;;;;;;;;;;;ACNA,MAAa,QACX,KACA,SACe;CACf,IAAI,OAAO,MAAM,OAAO,CAAC;CACzB,MAAM,cAAc,OAAO,0BAA0B,GAAG;CACxD,IAAI,CAAC,SAAS,gBAAgB,MAAM,KAAK,SAAS,IAAI,KAAK,WAAW,IACpE,OAAO,OAAO,iBAAiB,CAAC,GAAiB,WAAW;CAE9D,MAAM,UAAU,gBAAgB,MAAM,OAAO,IAAI,IAAI,IAAyB;CAC9E,MAAM,SAA8B,CAAC;CACrC,KAAK,MAAM,OAAO,OAAO,KAAK,WAAW,GACvC,IAAI,CAAC,QAAQ,IAAI,GAAG,GAClB,OAAO,eAAe,QAAQ,KAAK,YAAY,IAAK;CAGxD,OAAO;AACT;;;;;;;;;AAUA,MAAa,QACX,KACA,SACe;CACf,IAAI,OAAO,MAAM,OAAO,CAAC;CACzB,IAAI,CAAC,QAAQ,KAAK,WAAW,GAC3B,OAAO,OAAO,iBACZ,CAAC,GACD,OAAO,0BAA0B,GAAG,CACtC;CAEF,MAAM,SAA8B,CAAC;CACrC,KAAK,MAAM,OAAO,MAAM;EACtB,MAAM,IAAI;EACV,MAAM,aAAa,OAAO,yBAAyB,KAAK,CAAC;EACzD,IAAI,YACF,OAAO,eAAe,QAAQ,GAAG,UAAU;CAE/C;CACA,OAAO;AACT;AAEA,MAAM,UAAU;AAEhB,MAAM,aAAa,SAAsC;CACvD,IAAI,MAAM,QAAQ,IAAI,GAAG,OAAO;CAEhC,OADc,KAAK,MAAM,OACd,KAAK,CAAC;AACnB;AAEA,MAAM,eAAe,QACnB,QAAQ,eAAe,QAAQ,eAAe,QAAQ;AAExD,MAAa,OAAO,KAAU,MAAyB,iBAA4B;CACjF,MAAM,OAAO,UAAU,IAAI;CAC3B,IAAI,SAAS;CACb,KAAK,MAAM,OAAO,MAAM;EACtB,IAAI,UAAU,QAAQ,YAAY,GAAG,GAAG,OAAO;EAC/C,SAAS,OAAO;CAClB;CACA,OAAO,WAAW,SAAY,eAAe;AAC/C;AAEA,MAAa,OACX,KACA,MACA,UACwB;CACxB,MAAM,OAAO,UAAU,IAAI;CAC3B,IAAI,UAAU;CACd,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,SAAS,GAAG,KAAK;EACxC,MAAM,MAAM,KAAK;EACjB,IAAI,YAAY,GAAG,GAAG,OAAO;EAC7B,MAAM,UAAU,KAAK,IAAI;EACzB,IAAI,YAAY,OAAO,GAAG,OAAO;EACjC,IAAI,QAAQ,QAAQ,MAClB,QAAQ,OAAO,QAAQ,KAAK,OAAO,IAAI,CAAC,IAAI,CAAC;EAE/C,UAAU,QAAQ;CACpB;CACA,MAAM,UAAU,KAAK,KAAK,SAAS;CACnC,IAAI,WAAW,QAAQ,CAAC,YAAY,OAAO,GACzC,QAAQ,WAAW;CAErB,OAAO;AACT;AAEA,MAAa,YACX,IACA,OAAe,GACf,YAC+B;CAC/B,MAAM,UAAU,SAAS,YAAY;CACrC,MAAM,WAAW,SAAS,aAAa;CACvC,IAAI;CACJ,IAAI;CACJ,IAAI;CAEJ,MAAM,UAAU,SAAgB;EAC9B,eAAe,KAAK,IAAI;EACxB,GAAG,GAAG,IAAI;CACZ;CAEA,MAAM,sBAAsB,MAAa,UAAkB;EACzD,WAAW;EACX,IAAI,cAAc,QAAW;EAC7B,YAAY,iBAAiB;GAC3B,YAAY;GACZ,IAAI,UAAU;IACZ,OAAO,QAAQ;IACf,WAAW;GACb;EACF,GAAG,KAAK;CACV;CAEA,MAAM,aAAa,GAAG,SAAgB;EACpC,MAAM,MAAM,KAAK,IAAI;EACrB,MAAM,UAAU,iBAAiB,SAAY,OAAO,MAAM;EAC1D,IAAI,WAAW,MACb,IAAI,SACF,OAAO,IAAI;OACN;GACL,eAAe;GACf,IAAI,UAAU,mBAAmB,MAAM,IAAI;EAC7C;OACK,IAAI,UACT,mBAAmB,MAAM,OAAO,OAAO;CAE3C;CAEA,UAAU,eAAe;EACvB,IAAI,cAAc,QAAW;GAC3B,aAAa,SAAS;GACtB,YAAY;EACd;EACA,WAAW;EACX,eAAe;CACjB;CAEA,OAAO;AACT;AAEA,MAAM,iBAAiB,UACrB,UAAU,QACV,OAAO,UAAU,YACjB,CAAC,MAAM,QAAQ,KAAK,KACpB,OAAO,eAAe,KAAK,MAAM,OAAO;AAE1C,MAAa,SACX,QACA,GAAG,YACG;CACN,KAAK,MAAM,UAAU,SAAS;EAC5B,IAAI,UAAU,MAAM;EACpB,KAAK,MAAM,OAAO,OAAO,KAAK,MAAM,GAAG;GACrC,IAAI,QAAQ,eAAe,QAAQ,iBAAiB,QAAQ,aAAa;GACzE,MAAM,YAAa,OAAmC;GACtD,MAAM,YAAY,OAAO;GACzB,IAAI,cAAc,SAAS,KAAK,cAAc,SAAS,GACpD,AAAC,OAAmC,OAAO,MAAM,EAAE,GAAG,UAAU,GAAG,SAAS;QAE5E,AAAC,OAAmC,OAAO;EAEhD;CACF;CACA,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC5IA,SAAgB,2BAA2B,UAAuC,CAAC,GAAW;CAC5F,MAAM,YAAY,QAAQ,aAAa,oBAAoB,EAAE;CAC7D,MAAM,aAAa,QAAQ,cAAc;CACzC,MAAM,WAAW,QAAQ,YAAY;CAErC,MAAM,OAAO,KAAK,UAAU,SAAS;CAGrC,OACE,8CAHU,KAAK,UAAU,UAIO,EAAE,wHAHzB,KAAK,UAAU,QAKgE,EAAE,0CACjD,KAAK;AAGlD;;;;ACvDA,kBAAkBC,MAAWC,SAAc,OAAO,KAAK,GAAG"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["coreContext","__pkgName","__pkgVersion"],"sources":["../package.json","../src/compose.ts","../src/config.ts","../src/isEmpty.ts","../src/context.tsx","../src/hoistNonReactStatics.ts","../src/html/htmlTags.ts","../src/isEqual.ts","../src/isPyreonComponent.ts","../src/PyreonUI.tsx","../src/render.tsx","../src/resolveSlot.ts","../src/useStableValue.ts","../src/utils.ts","../src/cssVariablesPrePaint.ts","../src/index.ts"],"sourcesContent":["","type ArityOneFn = (arg: any) => any\ntype PickLastInTuple<T extends any[]> = T extends [...rest: infer _U, argn: infer L] ? L : any\ntype FirstFnParameterType<T extends any[]> = Parameters<PickLastInTuple<T>>[any]\ntype LastFnReturnType<T extends any[]> = ReturnType<T[0]>\n\nconst compose =\n <T extends ArityOneFn[]>(...fns: T) =>\n (p: FirstFnParameterType<T>): LastFnReturnType<T> =>\n fns.reduceRight((acc: any, cur: any) => cur(acc), p)\n\nexport default compose\n","import type { StyledFunction } from '@pyreon/styler'\nimport { css, keyframes, styled } from '@pyreon/styler'\nimport type { HTMLTags } from './html'\n\n/**\n * Describes the shape of the CSS-in-JS engine.\n * Pyreon uses @pyreon/styler directly — no connector abstraction needed.\n * This type is kept for API compatibility with downstream packages.\n */\nexport interface CSSEngineConnector {\n css: typeof css\n styled: typeof styled\n keyframes: typeof keyframes\n}\n\ninterface PlatformConfig {\n component: string | HTMLTags\n textComponent: string | HTMLTags\n createMediaQueries?: (props: {\n breakpoints: Record<string, number>\n rootSize: number\n css: CSSEngineConnector['css']\n }) => Record<string, (...args: any[]) => any>\n}\n\n/**\n * Options for the opt-in CSS-variables theming mode.\n * `init({ cssVariables: true })` enables it with the defaults.\n */\nexport interface CssVariablesConfig {\n /** Custom-property prefix: `--<prefix>-<path>`. Default `'px'`. */\n prefix?: string\n /**\n * Attribute carrying the active mode (set on `<html>` by the root\n * `PyreonUI`, and on the `display: contents` wrapper of nested\n * inversed / explicit-mode providers). Default `'data-theme'`.\n */\n attribute?: string\n}\n\n/** Resolved (defaulted) view of the cssVariables config. */\nexport interface ResolvedCssVariablesConfig {\n enabled: boolean\n prefix: string\n attribute: string\n}\n\ntype InitConfig = Partial<\n CSSEngineConnector &\n PlatformConfig & { cssVariables: boolean | CssVariablesConfig; styleExtraction: boolean }\n>\n\n/**\n * Configuration singleton that bridges the UI system with the CSS engine.\n * All packages reference config.css, config.styled, etc.\n *\n * In Pyreon, the engine is @pyreon/styler and is available immediately —\n * no lazy initialization or connector pattern needed.\n */\nclass Configuration {\n css = css\n styled: StyledFunction = styled\n keyframes = keyframes\n component: string | HTMLTags = 'div'\n textComponent: string | HTMLTags = 'span'\n createMediaQueries: PlatformConfig['createMediaQueries'] = undefined\n /**\n * Opt-in CSS-variables theming mode (the ui-system-wide switch).\n *\n * When enabled: `PyreonUI` autogenerates custom properties from the\n * theme JSON (unistyle's `themeToCssVars`) and injects the `:root`\n * block once; rocketstyle's `mode(a, b)` pairs become hashed var pairs\n * resolved by the `data-theme` attribute; theme resolution turns\n * mode-FREE and a dark/light flip is a single attribute write — no\n * re-resolution, no className churn.\n *\n * Set BEFORE the first render (app boot) — theme-resolution caches\n * assume the flag does not flip mid-session.\n */\n cssVariables: boolean | CssVariablesConfig = false\n\n /**\n * Opt-in Custom-Property Style Extraction for the default styled/Element\n * pipeline. When true, `PyreonUI` wires `@pyreon/styler`'s `setStyleExtraction`\n * (injecting unistyle's `cpseRewrite`) so non-reactive styled components emit a\n * value-agnostic CSS rule + per-instance inline custom properties (O(1) rules).\n * Off (default) = byte-identical classic path. Set BEFORE first render.\n */\n styleExtraction = false\n\n init = (props: InitConfig) => {\n if (props.css) this.css = props.css\n if (props.styled) this.styled = props.styled\n if (props.keyframes) this.keyframes = props.keyframes\n if (props.component) this.component = props.component\n if (props.textComponent) this.textComponent = props.textComponent\n if (props.createMediaQueries) this.createMediaQueries = props.createMediaQueries\n if (props.cssVariables !== undefined) this.cssVariables = props.cssVariables\n if (props.styleExtraction !== undefined) this.styleExtraction = props.styleExtraction\n }\n}\n\nconst config = new Configuration()\nconst { init } = config\n\n/**\n * Resolved view of `config.cssVariables` with defaults applied — the one\n * accessor every var-mode consumer (`PyreonUI`, rocketstyle's mode-pair\n * factory) reads, so defaulting lives in exactly one place.\n */\nexport function resolveCssVariables(): ResolvedCssVariablesConfig {\n const raw = config.cssVariables\n if (raw === false) return { enabled: false, prefix: 'px', attribute: 'data-theme' }\n const opts = raw === true ? {} : raw\n return {\n enabled: true,\n prefix: opts.prefix ?? 'px',\n attribute: opts.attribute ?? 'data-theme',\n }\n}\n\n/** Resolved view of `config.styleExtraction` — read by `PyreonUI` to wire\n * styler's CPSE hook. Defaulting lives in one place. */\nexport function resolveStyleExtraction(): boolean {\n return config.styleExtraction === true\n}\n\nexport default config\nexport { init }\n","export type IsEmpty = <T extends Record<number | string, any> | any[] | null | undefined>(\n param: T,\n) => T extends null | undefined\n ? true\n : keyof T extends never\n ? true\n : T extends T[]\n ? T[number] extends never\n ? true\n : false\n : false\n\nconst isEmpty = (<T extends Record<number | string, any> | any[] | null | undefined>(param: T) => {\n if (!param) return true\n if (typeof param !== 'object') return true\n if (Array.isArray(param)) return param.length === 0\n return Object.keys(param).length === 0\n}) as IsEmpty\n\nexport default isEmpty\n","import type { VNodeChild } from '@pyreon/core'\nimport { createReactiveContext, nativeCompat, provide } from '@pyreon/core'\nimport isEmpty from './isEmpty'\nimport type { Breakpoints } from './types'\n\n/**\n * Core context value shared across all @pyreon UI packages.\n */\nexport interface CoreContextValue {\n theme: Record<string, unknown>\n mode: 'light' | 'dark'\n isDark: boolean\n isLight: boolean\n}\n\n/**\n * Internal reactive context shared across all @pyreon packages.\n * Carries the theme object, mode, and derived dark/light flags.\n *\n * ReactiveContext means useContext() returns `() => CoreContextValue`.\n */\nconst context = createReactiveContext<CoreContextValue>({\n theme: {},\n mode: 'light',\n isDark: false,\n isLight: true,\n})\n\ntype Theme = Partial<\n {\n rootSize: number\n breakpoints: Breakpoints\n } & Record<string, any>\n>\n\ntype ProviderType = Partial<\n {\n theme: Theme\n children: VNodeChild\n } & Record<string, any>\n>\n\n/**\n * @internal Low-level provider — use `PyreonUI` from `@pyreon/ui-core` instead.\n *\n * Provider that feeds the internal Pyreon context with the theme.\n * When no theme is supplied, renders children directly.\n *\n * @deprecated Prefer `<PyreonUI theme={theme}>` which handles all context layers.\n */\nfunction Provider({ theme, children, ...props }: ProviderType): VNodeChild {\n /* v8 ignore next 5 — dev-only warning gate; production NODE_ENV branch not exercised in tests */\n if (process.env.NODE_ENV !== 'production') {\n // oxlint-disable-next-line no-console\n console.warn(\n '[Pyreon] CoreProvider is internal. Use <PyreonUI theme={theme}> instead — it handles all context layers (styler, core, mode) in one component.',\n )\n }\n if (isEmpty(theme) || !theme) return children ?? null\n\n provide(context, () => ({\n theme: theme as Record<string, unknown>,\n mode: (props.mode as 'light' | 'dark') ?? 'light',\n isDark: props.isDark as boolean ?? false,\n isLight: props.isLight as boolean ?? true,\n ...props,\n }))\n\n return children ?? null\n}\n\n// Mark as native — even though @internal, PyreonUI invokes this internally\n// AND the JSX inside PyreonUI's body still routes through the active jsx()\n// runtime (which is the compat one in compat-mode apps). Without the marker,\n// CoreProvider's body runs inside the compat wrapper's runUntracked and its\n// provide() call is swallowed.\nnativeCompat(Provider)\n\nexport { context }\n\nexport default Provider\n","const KNOWN_STATICS: Record<string, true> = {\n name: true,\n length: true,\n prototype: true,\n caller: true,\n callee: true,\n arguments: true,\n arity: true,\n}\n\nconst COMPONENT_STATICS: Record<string, true> = {\n displayName: true,\n defaultProps: true,\n}\n\n/**\n * Copies non-framework static properties from a source component to a target.\n *\n * Pyreon equivalent of hoistNonReactStatics — simplified since Pyreon\n * components are plain functions without React-specific statics like\n * contextType, propTypes, getDerivedStateFromProps, etc.\n */\nconst hoistNonReactStatics = <T, S>(\n target: T,\n source: S,\n excludeList?: Record<string, true>,\n): T => {\n if (typeof source === 'string') return target\n\n const proto = Object.getPrototypeOf(source)\n if (proto && proto !== Object.prototype) {\n hoistNonReactStatics(target, proto, excludeList)\n }\n\n const keys: (string | symbol)[] = [\n ...Object.getOwnPropertyNames(source),\n ...Object.getOwnPropertySymbols(source),\n ]\n\n for (const key of keys) {\n const k = key as string\n if (KNOWN_STATICS[k] || excludeList?.[k] || COMPONENT_STATICS[k]) {\n continue\n }\n\n const descriptor = Object.getOwnPropertyDescriptor(source, key)\n /* v8 ignore next — descriptor is always defined: key came from getOwnPropertyNames(source) */\n if (descriptor) {\n try {\n Object.defineProperty(target, key, descriptor)\n } catch {\n // Silently skip non-configurable properties\n }\n }\n }\n\n return target\n}\n\nexport default hoistNonReactStatics\n","const HTML_TAGS = [\n 'a',\n 'abbr',\n 'address',\n 'area',\n 'article',\n 'aside',\n 'audio',\n 'b',\n 'bdi',\n 'bdo',\n 'big',\n 'blockquote',\n 'body',\n 'br',\n 'button',\n 'canvas',\n 'caption',\n 'cite',\n 'code',\n 'col',\n 'colgroup',\n 'data',\n 'datalist',\n 'dd',\n 'del',\n 'details',\n 'dfn',\n 'dialog',\n 'div',\n 'dl',\n 'dt',\n 'em',\n 'embed',\n 'fieldset',\n 'figcaption',\n 'figure',\n 'footer',\n 'form',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'header',\n 'hr',\n 'html',\n 'i',\n 'iframe',\n 'img',\n 'input',\n 'ins',\n 'kbd',\n 'label',\n 'legend',\n 'li',\n 'main',\n 'map',\n 'mark',\n 'meter',\n 'nav',\n 'object',\n 'ol',\n 'optgroup',\n 'option',\n 'output',\n 'p',\n 'picture',\n 'pre',\n 'progress',\n 'q',\n 'rp',\n 'rt',\n 'ruby',\n 's',\n 'samp',\n 'section',\n 'select',\n 'small',\n 'source',\n 'span',\n 'strong',\n 'sub',\n 'summary',\n 'sup',\n 'svg',\n 'table',\n 'tbody',\n 'td',\n 'template',\n 'textarea',\n 'tfoot',\n 'th',\n 'thead',\n 'time',\n 'tr',\n 'track',\n 'u',\n 'ul',\n 'var',\n 'video',\n 'wbr',\n] as const\n\nconst HTML_TEXT_TAGS = [\n 'abbr',\n 'b',\n 'bdi',\n 'bdo',\n 'big',\n 'blockquote',\n 'cite',\n 'code',\n 'del',\n 'div',\n 'dl',\n 'dt',\n 'em',\n 'figcaption',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'i',\n 'ins',\n 'kbd',\n 'label',\n 'legend',\n 'li',\n 'p',\n 'pre',\n 'q',\n 'rp',\n 'rt',\n 's',\n 'small',\n 'span',\n 'strong',\n 'sub',\n 'summary',\n 'sup',\n 'time',\n 'u',\n] as const\n\nexport type HTMLTags = (typeof HTML_TAGS)[number]\nexport type HTMLTextTags = (typeof HTML_TEXT_TAGS)[number]\nexport { HTML_TAGS, HTML_TEXT_TAGS }\n","const isArrayEqual = (a: unknown[], b: unknown[]): boolean => {\n if (a.length !== b.length) return false\n for (let i = 0; i < a.length; i++) {\n if (!isEqual(a[i], b[i])) return false\n }\n return true\n}\n\nconst isObjectEqual = (a: Record<string, unknown>, b: Record<string, unknown>): boolean => {\n const aKeys = Object.keys(a)\n if (aKeys.length !== Object.keys(b).length) return false\n for (const key of aKeys) {\n if (!Object.hasOwn(b, key)) return false\n if (!isEqual(a[key], b[key])) return false\n }\n return true\n}\n\nconst isEqual = (a: unknown, b: unknown): boolean => {\n if (Object.is(a, b)) return true\n if (typeof a !== typeof b || a == null || b == null || typeof a !== 'object') return false\n if (Array.isArray(a)) return Array.isArray(b) && isArrayEqual(a, b)\n if (Array.isArray(b)) return false\n return isObjectEqual(a as Record<string, unknown>, b as Record<string, unknown>)\n}\n\nexport default isEqual\n","/**\n * Detect whether a function value is a component (framework-marked OR\n * user-authored bare function), as opposed to a plain reactive-accessor\n * function.\n *\n * Used by `resolveSlot` (and any other slot-resolver) to discriminate\n * between\n * `beforeContent={Header}` — component-reference shorthand, MUST mount\n * as `h(Component, null)` so the framework's runWithHooks setup\n * window is established (and any framework HOC's\n * `removeUndefinedProps(props)` / `splitProps(props)` get the\n * default-filled props object, not bare `undefined`).\n * `beforeContent={() => <Header />}` — anonymous reactive accessor,\n * called bare so its body's signal reads land inside the enclosing\n * `mountReactive` effect.\n *\n * Both shapes are `typeof === 'function'`. The discriminator combines two\n * checks (most-specific-first):\n *\n * **Tier 1 — framework markers** (load-bearing for HOC pipelines):\n * - `IS_ROCKETSTYLE` — set by `@pyreon/rocketstyle`\n * (`rocketstyle.ts:527`, `542`) on every `rocketstyle(...).config(...)`\n * chain end-point.\n * - `PYREON__COMPONENT` — set by every `@pyreon/elements` component\n * factory (Element, Text, List, Portal, Overlay, Util, Content,\n * Wrapper, …).\n * - `pkgName` — same components also carry this; checked as a fallback\n * in case a third-party package mirrors the elements convention.\n *\n * **Tier 2 — naming convention** (catches user-authored bare components\n * without markers):\n * - `displayName` is set → component. Authors set displayName\n * deliberately for devtools / debug output; it's an explicit\n * declaration of component intent.\n * - `.name` starts with an uppercase letter → component. JSX already\n * requires PascalCase for components (`<MyComp/>` is treated as a\n * component; `<mycomp/>` is treated as a host tag); the discriminator\n * mirrors that convention for slot-shorthand usage. Anonymous\n * arrows (`name: \"\"`), default-export functions (`name: \"default\"`),\n * and camelCase helpers fall through to the accessor path.\n *\n * Why Tier 2 matters — the bug class it closes: a bare-function component\n * that internally uses lifecycle hooks (`useWindowResize`, `onMount`,\n * `provide`, etc.) needs a `runWithHooks` setup window so the hook calls\n * find `_current` non-null. Without Tier 2, `resolveSlot` would call the\n * function bare → `_current === null` → `[Pyreon] onMount() called outside\n * component setup` warning fires in dev-mode SSR. Routing the same\n * function through `h(value, null)` mounts it as a proper component via\n * the standard `runWithHooks`-based path; the hooks register correctly\n * AND the warning never fires.\n *\n * Why the convention split is safe: a PascalCase function paired with\n * the `beforeContent={Fn}` shorthand is canonically a component reference\n * (matches every framework example in the docs). An anonymous arrow\n * `() => signal() ? <A/> : <B/>` is canonically a reactive accessor\n * (intent: re-evaluate on signal change). The naming convention is the\n * same one JSX itself uses to differentiate component vs host element.\n *\n * Before this check, `resolveSlot` called any function-valued slot\n * bare, crashing real consumers that used the\n * `beforeContent={Component}` shorthand documented since the original\n * Element API. The marker check (Tier 1) rescues framework-factory\n * components; this Tier-2 convention check closes the residual gap\n * for user-authored hook-using bare components.\n */\nexport function isPyreonComponent(value: unknown): boolean {\n if (typeof value !== 'function') return false\n // ── Tier 1 — framework markers ──────────────────────────────────────\n // `Object.hasOwn` (not `in`) so a marker on a parent prototype doesn't\n // count — the marker is always an own-property in the factories.\n if (\n Object.hasOwn(value, 'IS_ROCKETSTYLE') ||\n Object.hasOwn(value, 'PYREON__COMPONENT') ||\n Object.hasOwn(value, 'pkgName')\n ) {\n return true\n }\n // ── Tier 2 — naming convention ──────────────────────────────────────\n const fn = value as { displayName?: unknown; name?: unknown }\n // displayName: explicit author intent. Any non-empty string counts.\n if (typeof fn.displayName === 'string' && fn.displayName.length > 0) {\n return true\n }\n // .name: inferred function name (`const Header = () => …` → \"Header\";\n // `function Header()` → \"Header\"; anonymous arrow → \"\"). PascalCase\n // first letter matches JSX's own component-vs-host discriminator.\n const name = fn.name\n if (typeof name === 'string' && name.length > 0) {\n const first = name.charCodeAt(0)\n // Uppercase A-Z range (65-90). Avoids unicode-letter false-positives\n // and skips `name === \"default\"` from `export default () => …`.\n if (first >= 65 && first <= 90) return true\n }\n return false\n}\n","import type { VNodeChild } from '@pyreon/core'\nimport {\n createContext,\n createReactiveContext,\n h,\n nativeCompat,\n provide,\n useContext,\n} from '@pyreon/core'\nimport { computed, effect, isClient, signal } from '@pyreon/reactivity'\nimport { setStyleExtraction, sheet, ThemeContext } from '@pyreon/styler'\nimport type { PyreonTheme } from '@pyreon/unistyle'\nimport { cpseRewrite, enrichTheme, themeToCssVars } from '@pyreon/unistyle'\nimport { resolveCssVariables, resolveStyleExtraction } from './config'\nimport { context as coreContext } from './context'\n\n// Structural flag distinguishing the ROOT PyreonUI from a NESTED one (a\n// plain context, not reactive — nesting is fixed at mount). In cssVariables\n// mode the root writes the mode attribute to `document.documentElement`\n// (so it sits at `:root`, where the pre-paint FOUC script also writes and\n// where the var rules cascade from), while nested / `inversed` providers\n// render a `display: contents` wrapper that scopes an override to their\n// subtree. Putting the root on a wrapper instead would let the wrapper —\n// a closer ancestor than `<html>` — defeat a pre-paint script that can\n// only reach `document.documentElement` before the in-body wrapper parses.\nconst PyreonUINestedContext = createContext(false)\n\n// ─── Types ──────────────────────────────────────────────────────────────────\n\nexport type ThemeMode = 'light' | 'dark'\nexport type ThemeModeInput = ThemeMode | 'system'\n\nexport interface PyreonUIProps {\n /**\n * Theme object with breakpoints, rootSize, and custom keys.\n *\n * Optional — when omitted, the theme is INHERITED from the nearest\n * ancestor PyreonUI. This makes nested `<PyreonUI inversed>` work\n * without re-passing the theme:\n *\n * ```tsx\n * <PyreonUI theme={appTheme}>\n * <Header />\n * <PyreonUI inversed> // inherits appTheme, just flips mode\n * <DarkSidebar />\n * </PyreonUI>\n * </PyreonUI>\n * ```\n *\n * At the OUTERMOST PyreonUI with no ancestor, the provided ThemeContext\n * value falls back to the default `{}` (styled components see fields as\n * undefined; no crash). Pass a real theme at the outermost PyreonUI to\n * avoid that.\n */\n theme?: PyreonTheme | undefined\n /**\n * Color mode: \"light\", \"dark\", or \"system\" (follows OS preference).\n * Can be a signal or getter for reactive mode switching.\n *\n * When omitted, mode is INHERITED from the nearest ancestor PyreonUI\n * (or `'light'` at the root).\n */\n mode?: ThemeModeInput | (() => ThemeModeInput) | undefined\n /**\n * Flip mode for a nested section (e.g. dark sidebar in light app).\n * Scoped — only affects DESCENDANTS of this PyreonUI; ancestors and\n * siblings see the original mode unchanged.\n */\n inversed?: boolean | undefined\n children?: VNodeChild\n}\n\n// ─── System mode detection ──────────────────────────────────────────────────\n\n// `isClient` is the canonical DOM-present guard; `matchMedia` is an extra\n// FEATURE check (system color-scheme needs it), kept rather than folded in.\nconst _isBrowser = isClient && typeof matchMedia === 'function'\n\n/** Reactive signal tracking the OS dark mode preference. Lazy-initialized on first use. */\nlet _systemMode: ReturnType<typeof signal<ThemeMode>> | undefined\n\nfunction getSystemMode(): ReturnType<typeof signal<ThemeMode>> {\n if (_systemMode) return _systemMode\n\n // Ternary (not `&&`) so the typeof-derived `_isBrowser` guard is\n // statically verifiable as protecting the `matchMedia` access — same\n // runtime value (`false` on the server), SSR-safe + analyzer-clear.\n /* v8 ignore next 3 — `_isBrowser` is always true in tests (happy-dom + matchMedia); SSR branch covered by typeof guard */\n const prefersDark = _isBrowser\n ? matchMedia('(prefers-color-scheme: dark)').matches\n : false\n _systemMode = signal<ThemeMode>(prefersDark ? 'dark' : 'light')\n\n /* v8 ignore next 5 — same SSR/typeof gate as above */\n if (_isBrowser) {\n matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {\n _systemMode?.set(e.matches ? 'dark' : 'light')\n })\n }\n\n return _systemMode\n}\n\n// ─── Mode context ───────────────────────────────────────────────────────────\n\n/** Reactive context — useContext(ModeContext) returns () => ThemeMode. */\nconst ModeContext = createReactiveContext<ThemeMode>('light')\n\nconst INVERSED: Record<ThemeMode, ThemeMode> = { light: 'dark', dark: 'light' }\n\n/**\n * Read the resolved color mode (\"light\" | \"dark\") from the nearest PyreonUI.\n * Reactive — updates when the mode prop changes or when OS preference changes\n * (if mode=\"system\").\n *\n * @example\n * const mode = useMode() // \"light\" | \"dark\"\n */\nexport function useMode(): ThemeMode {\n return useContext(ModeContext)()\n}\n\n// ─── Auto-init ──────────────────────────────────────────────────────────────\n\nlet _autoInitDone = false\n\nfunction autoInit(): void {\n if (_autoInitDone) return\n _autoInitDone = true\n}\n\n// ─── PyreonUI ───────────────────────────────────────────────────────────────\n\n/**\n * Unified provider for the Pyreon UI system.\n *\n * Replaces the need for separate UnistyleProvider, RocketstyleProvider,\n * and ThemeProvider — one component, zero init.\n *\n * Mode can be a static string OR a signal/getter for reactive switching:\n * ```tsx\n * // Static\n * <PyreonUI theme={theme} mode=\"dark\">\n *\n * // Reactive signal\n * const mode = signal<ThemeModeInput>(\"light\")\n * <PyreonUI theme={theme} mode={mode}>\n *\n * // System (follows OS preference)\n * <PyreonUI theme={theme} mode=\"system\">\n * ```\n */\nexport function PyreonUI(props: PyreonUIProps): VNodeChild {\n autoInit()\n\n // IMPORTANT: do NOT destructure props. Components run once in Pyreon, and\n // destructuring captures values at setup time — losing reactivity. Reading\n // `props.mode` / `props.inversed` lazily inside `resolveMode()` lets the\n // computed re-evaluate when the underlying reactive props change (parent\n // re-renders with a different value, or signal-driven mode toggling).\n //\n // Previously this destructured `{ theme, mode = 'light', inversed, children }`\n // which made `inversed` permanently static — toggling inversed in a parent\n // had no effect because the local boolean was captured once. See\n // `.claude/rules/anti-patterns.md` \"Destructuring props\" entry.\n\n // Create a reactive mode getter that resolves \"system\" and applies inversion.\n // This getter is provided via context — consumers read it lazily in their\n // own reactive scopes, so mode changes propagate automatically.\n //\n // When `inversed` is set without an explicit `mode`, inherit the parent's\n // mode and flip it. This makes nested `<PyreonUI inversed>` work reactively:\n // outer light → inner dark, outer dark → inner light.\n //\n // useContext(ModeContext) returns the reactive accessor from the nearest\n // parent PyreonUI. At root level (no parent), the ReactiveContext default\n // returns 'light'. This read is TRACKED inside the computed below, so when\n // the parent's mode changes, this child's computed re-evaluates.\n const parentModeAccessor = useContext(ModeContext)\n // Same shape for theme — useContext(ThemeContext) is a reactive accessor.\n // When `props.theme` is omitted, we provide the parent's theme through\n // verbatim (already enriched at the level it was provided). Re-enriching\n // would be idempotent but wasteful, AND would replace the parent's exact\n // `__PYREON__` reference, which downstream identity-keyed caches (styler's\n // class cache, rocketstyle's per-definition WeakMaps) rely on for hits.\n // Pass-through preserves identity.\n const parentThemeAccessor = useContext(ThemeContext)\n const resolveMode = (): ThemeMode => {\n const mode = props.mode\n let resolved: ThemeMode\n if (mode === undefined || mode === null) {\n // No explicit mode — inherit from parent context\n resolved = parentModeAccessor()\n } else {\n const raw = typeof mode === 'function' ? mode() : mode\n resolved = raw === 'system' ? getSystemMode()() : raw\n }\n return props.inversed ? INVERSED[resolved] : resolved\n }\n\n // Wrap in computed for memoization\n const modeComputed = computed(resolveMode)\n\n // Enrich theme — wrapped in computed so user-preference theme swaps\n // propagate. The enrichment itself is cheap (builds a __PYREON__ block).\n //\n // When `props.theme` is omitted, return the parent's theme verbatim\n // (already enriched). Without this, `enrichTheme(undefined)` would\n // destructure undefined and throw — but the throw happens LAZILY (the\n // computed is only read when a child consumes ThemeContext), so the\n // failure mode is the cryptic dev-mode warning\n // `[pyreon] Unhandled effect error: TypeError: Cannot destructure property\n // 'breakpoints' of 'theme' as it is undefined`\n // followed by every styled descendant rendering with an empty theme.\n // That's what made the user's nested `<PyreonUI inversed>` \"look like\n // inversed wasn't working\" — the whole subtree was broken.\n // Resolved once at setup — the cssVariables switch is a boot-time contract\n // (set via init() before the first render); theme-resolution caches across\n // the ui-system assume it does not flip mid-session.\n const cssVars = resolveCssVariables()\n\n // Wire CPSE into styler's default pipeline when opted in\n // (`init({ styleExtraction: true })`). styler can't import unistyle (dep\n // direction), so the root provider injects `cpseRewrite` here. Boot-time\n // contract; flag-off (default) leaves the classic path byte-identical.\n if (resolveStyleExtraction()) setStyleExtraction(true, cpseRewrite)\n\n const enrichedTheme = computed(() => {\n const t = props.theme\n if (t === undefined || t === null) return parentThemeAccessor()\n const enriched = enrichTheme(t)\n if (!cssVars.enabled) return enriched\n // CSS-variables mode: every eligible theme leaf becomes a 'var(--px-…)'\n // string and the :root block is injected ONCE per theme identity\n // (injectRules is idempotent by key and SSR-aware — on the server the\n // block lands in the ssrBuffer that getStyleTag()/the stream flush emit).\n // Downstream consumers (styler templates, rocketstyle callbacks, the\n // unistyle value pipeline) read the var references verbatim, so a mode\n // flip never re-resolves any of them.\n const { vars, css: varsCss } = themeToCssVars(enriched, { prefix: cssVars.prefix })\n if (varsCss) sheet.injectRules([varsCss], varsCss)\n // Same tree shape; leaves are var() reference strings — every theme\n // value position accepts strings, so the widened leaf type is safe.\n return vars as unknown as ReturnType<typeof enrichTheme>\n })\n\n // Provide to all three context layers:\n\n // 1. Styler ThemeContext — reactive accessor. DynamicStyled reads this\n // inside its computed() to re-resolve CSS on theme swap.\n provide(ThemeContext, () => enrichedTheme())\n\n // 2. Core context — provide a reactive getter function.\n // coreContext is a ReactiveContext, so provide(() => value).\n // Rocketstyle reads mode/isDark/isLight by calling the getter.\n //\n // LAZY getters (not eager fields) are load-bearing: reading `.theme`\n // must NOT transitively subscribe to `modeComputed`. With eager fields\n // (`{ theme: enrichedTheme(), mode: modeComputed() }`) the object\n // construction reads modeComputed(), so ANY consumer touching `.theme`\n // re-runs on every mode flip — even under cssVariables, where component\n // resolution is supposed to be mode-free (the flip is an attribute write,\n // the cascade does the rest). Getters defer each read: a component that\n // reads only `.theme` subscribes only to `enrichedTheme` (stable on flip\n // → no re-run); classic-mode resolution that reads `.mode` still\n // subscribes to `modeComputed` (re-runs on flip → correct).\n provide(coreContext, () => ({\n get theme() {\n return enrichedTheme()\n },\n get mode() {\n return modeComputed()\n },\n get isDark() {\n return modeComputed() === 'dark'\n },\n get isLight() {\n return modeComputed() === 'light'\n },\n }))\n\n // 3. Mode context — getter function for useMode()\n provide(ModeContext, () => modeComputed())\n\n if (!cssVars.enabled) return props.children ?? null\n\n // Is this the ROOT PyreonUI (no PyreonUI ancestor) or a NESTED one?\n const isNested = useContext(PyreonUINestedContext)\n // Descendants are nested under us regardless.\n provide(PyreonUINestedContext, true)\n\n if (!isNested) {\n // ROOT, cssVariables mode: drive the mode attribute on\n // `document.documentElement` so it lives at `:root` — where the var\n // rules cascade from AND where a pre-paint FOUC script writes before\n // first paint. The effect keeps it in sync with reactive mode changes\n // (toggles, system-pref flips) after hydration; the flip is one\n // attribute write, zero re-resolution, zero className churn. SSR can't\n // touch `document` — there, first-paint correctness comes from the\n // pre-paint script (system/persisted) or an explicit `<html>` stamp;\n // see `cssVariablesPrePaintScript`. No wrapper at the root: a wrapper\n // would be a closer ancestor than `<html>` and defeat that script.\n if (isClient) {\n // Intentional reactive DOM sync: this MUST re-run whenever modeComputed\n // changes (toggle / system-pref flip), so onMount (runs once) cannot do\n // it — same shape as the framework's own renderEffect/_bind DOM writes.\n // It's a one-line attribute write, not the fetch/timer imperative-work\n // the rule guards against.\n // pyreon-lint-disable-next-line pyreon/no-imperative-effect-on-create\n effect(() => {\n document.documentElement.setAttribute(cssVars.attribute, modeComputed())\n })\n }\n return props.children ?? null\n }\n\n // NESTED / `inversed` cssVariables provider: render a layout-neutral\n // wrapper carrying the mode attribute. The cascade does the rest —\n // `[data-theme=\"dark\"]` re-resolves every mode-pair var for THIS subtree\n // only, so a scoped dark/light section is one attribute write with zero\n // re-resolution and zero className churn. Server-rendered too.\n return h(\n 'div',\n {\n style: 'display: contents',\n [cssVars.attribute]: () => modeComputed(),\n },\n props.children ?? null,\n )\n}\n\n// Mark as native — compat-mode jsx() runtimes skip wrapCompatComponent so\n// PyreonUI's three provide() calls + useContext(ModeContext) read run inside\n// Pyreon's setup frame. Critical for compat-mode apps that wrap their tree\n// with <PyreonUI> at the top level — without the marker, theme/mode never\n// propagate to descendants.\nnativeCompat(PyreonUI)\n","import type { ComponentFn, Props, VNodeChild } from '@pyreon/core'\nimport { h } from '@pyreon/core'\n\ntype RenderProps<T extends Record<string, unknown> | undefined> = (props: Partial<T>) => VNodeChild\n\n/**\n * Flexible element renderer that handles multiple content types:\n * - Primitives (string, number) — returned as-is\n * - Arrays — returned as-is\n * - Component functions — created via h()\n * - VNode objects — returned as-is (with props merged if provided)\n * - Render props (functions) — called with attachProps\n * - Falsy values — return null\n */\nexport type Render = <T extends Record<string, any> | undefined>(\n content?: ComponentFn | string | VNodeChild | VNodeChild[] | RenderProps<T>,\n attachProps?: T,\n) => VNodeChild\n\nconst render: Render = (content, attachProps) => {\n if (!content) return null\n\n const t = typeof content\n if (t === 'string' || t === 'number' || t === 'boolean' || t === 'bigint') {\n return content as VNodeChild\n }\n\n if (Array.isArray(content)) {\n return content as VNodeChild\n }\n\n if (typeof content === 'function') {\n // Extract key from props — it's a VNode concept, not a component prop.\n // Passing key inside props causes JSX runtime warnings.\n if (attachProps && 'key' in attachProps) {\n const { key: _key, ...rest } = attachProps\n return h(content as string | ComponentFn, rest as Props)\n }\n return h(content as string | ComponentFn, (attachProps ?? {}) as Props)\n }\n\n // VNode object — return directly. Fallthrough after the typeof guards above;\n // both the object branch and the trailing return are structurally\n // unreachable (content is already narrowed to an object here).\n /* v8 ignore start */\n if (typeof content === 'object') {\n return content as VNodeChild\n }\n\n return content as VNodeChild\n /* v8 ignore stop */\n}\n\nexport default render\n","import { h } from '@pyreon/core'\nimport type { ComponentFn, VNodeChildAtom } from '@pyreon/core'\nimport { isPyreonComponent } from './isPyreonComponent'\nimport render from './render'\n\n/**\n * Resolve a slot value INSIDE a reactive accessor. If the consumer passed\n * a function-returning-VNode (e.g. `content={() => <Icon name={signal()} />}`),\n * unwrap it by calling — its body's signal reads are then tracked by the\n * enclosing mountReactive effect, and the slot re-renders on signal change.\n * Static VNodes / strings / null pass through unchanged to `render()`.\n *\n * **Component vs accessor discriminator** —\n * `beforeContent={Header}` (component-reference shorthand) and\n * `content={() => <X />}` (reactive accessor) are BOTH `typeof === 'function'`.\n * Calling both bare crashes component shorthands the moment a\n * rocketstyle / attrs HOC runs `removeUndefinedProps(undefined)` on the\n * un-supplied props (`TypeError: Cannot convert undefined or null to object`).\n *\n * Discriminator: framework components carry one of two markers attached by\n * their factory:\n * - `IS_ROCKETSTYLE` — anything `rocketstyle()` produces\n * - `PYREON__COMPONENT` / `pkgName` — `@pyreon/elements` components\n * (Element, Text, List, Portal, Overlay, Util)\n * Marked function → mount as `h(Component, null)` (no props, defaults\n * fill in via the HOC pipeline). Unmarked function → reactive accessor,\n * called bare so its return value (a VNode) renders. Bare-function\n * components without HOC wrapping (e.g. `const MyComp = () => <div />`)\n * also work via the accessor path — they're called with no args and\n * their VNode return goes through `render()` correctly. The marker\n * check ONLY rescues components that REQUIRE props to be defined.\n * Tier 2 of `isPyreonComponent` (PascalCase `.name` / explicit\n * `displayName`) additionally catches user-authored bare components\n * that use lifecycle hooks — see `isPyreonComponent` JSDoc.\n *\n * Return type is the RESOLVED atom (VNodeChildAtom | VNodeChildAtom[]) —\n * never a nested accessor — so the enclosing `() => resolveSlot(...)` IS\n * a valid VNodeChildAccessor in the JSX child position.\n */\nexport const resolveSlot = (value: unknown): VNodeChildAtom | VNodeChildAtom[] => {\n if (typeof value === 'function') {\n if (isPyreonComponent(value)) {\n return h(value as ComponentFn, null) as VNodeChildAtom\n }\n return (value as () => VNodeChildAtom | VNodeChildAtom[])()\n }\n return render(value as Parameters<typeof render>[0]) as VNodeChildAtom | VNodeChildAtom[]\n}\n\nexport default resolveSlot\n","import { signal } from '@pyreon/reactivity'\nimport isEqual from './isEqual'\n\n/**\n * Returns a referentially stable version of `value`. The returned reference\n * only changes when the value is no longer deeply equal to the previous one.\n *\n * Pyreon equivalent of the React useStableValue hook — uses a signal\n * internally to hold the stable reference.\n */\nconst useStableValue = <T>(value: T): T => {\n const ref = signal(value)\n\n /* v8 ignore next 3 — defensive: ref was just initialized with `value`, isEqual is always true */\n if (!isEqual(ref.peek(), value)) {\n ref.set(value)\n }\n\n return ref.peek()\n}\n\nexport default useStableValue\n","/**\n * Returns a copy of `obj` without the specified keys.\n *\n * Accepts either an array of keys (builds a Set internally) or a\n * pre-built `Set<string>` for hot paths where the same key list is\n * reused across many calls (avoids per-call Set allocation).\n *\n * Copies own property DESCRIPTORS (not values) so that getter-shaped\n * properties — produced by `makeReactiveProps` in `@pyreon/core` for\n * compiler-emitted `<Comp prop={signal()}>` — survive the copy with\n * their reactive subscription intact. For data properties the\n * behaviour is identical to value-copying.\n */\nexport const omit = <T extends Record<string, any>>(\n obj: T | null | undefined,\n keys?: readonly (string | keyof T)[] | Set<string>,\n): Partial<T> => {\n if (obj == null) return {} as Partial<T>\n const descriptors = Object.getOwnPropertyDescriptors(obj)\n if (!keys || (keys instanceof Set ? keys.size === 0 : keys.length === 0)) {\n return Object.defineProperties({} as Partial<T>, descriptors)\n }\n const keysSet = keys instanceof Set ? keys : new Set(keys as readonly string[])\n const result: Record<string, any> = {}\n for (const key of Object.keys(descriptors)) {\n if (!keysSet.has(key)) {\n Object.defineProperty(result, key, descriptors[key]!)\n }\n }\n return result as Partial<T>\n}\n\n/**\n * Returns a copy of `obj` containing only the specified keys.\n *\n * See `omit` above — same descriptor-preserving semantics: getter-\n * shaped properties survive the copy with reactive subscription\n * intact. For data properties the behaviour is identical to\n * value-copying.\n */\nexport const pick = <T extends Record<string, any>>(\n obj: T | null | undefined,\n keys?: readonly (string | keyof T)[],\n): Partial<T> => {\n if (obj == null) return {} as Partial<T>\n if (!keys || keys.length === 0) {\n return Object.defineProperties(\n {} as Partial<T>,\n Object.getOwnPropertyDescriptors(obj),\n )\n }\n const result: Record<string, any> = {}\n for (const key of keys) {\n const k = key as string\n const descriptor = Object.getOwnPropertyDescriptor(obj, k)\n if (descriptor) {\n Object.defineProperty(result, k, descriptor)\n }\n }\n return result as Partial<T>\n}\n\nconst PATH_RE = /[^.[\\]]+/g\n\nconst parsePath = (path: string | string[]): string[] => {\n if (Array.isArray(path)) return path\n const parts = path.match(PATH_RE)\n return parts ?? []\n}\n\nconst isUnsafeKey = (key: string): boolean =>\n key === '__proto__' || key === 'prototype' || key === 'constructor'\n\nexport const get = (obj: any, path: string | string[], defaultValue?: any): any => {\n const keys = parsePath(path)\n let result = obj\n for (const key of keys) {\n if (result == null || isUnsafeKey(key)) return defaultValue\n result = result[key]\n }\n return result === undefined ? defaultValue : result\n}\n\nexport const set = (\n obj: Record<string, any>,\n path: string | string[],\n value: any,\n): Record<string, any> => {\n const keys = parsePath(path)\n let current = obj\n for (let i = 0; i < keys.length - 1; i++) {\n const key = keys[i] as string\n if (isUnsafeKey(key)) return obj\n const nextKey = keys[i + 1] as string\n if (isUnsafeKey(nextKey)) return obj\n if (current[key] == null) {\n current[key] = /^\\d+$/.test(nextKey) ? [] : {}\n }\n current = current[key]\n }\n const lastKey = keys[keys.length - 1]\n if (lastKey != null && !isUnsafeKey(lastKey)) {\n current[lastKey] = value\n }\n return obj\n}\n\nexport const throttle = <T extends (...args: any[]) => any>(\n fn: T,\n wait: number = 0,\n options?: { leading?: boolean; trailing?: boolean },\n): T & { cancel: () => void } => {\n const leading = options?.leading !== false\n const trailing = options?.trailing !== false\n let lastCallTime: number | undefined\n let timeoutId: ReturnType<typeof setTimeout> | undefined\n let lastArgs: any[] | undefined\n\n const invoke = (args: any[]) => {\n lastCallTime = Date.now()\n fn(...args)\n }\n\n const startTrailingTimer = (args: any[], delay: number) => {\n lastArgs = args\n if (timeoutId !== undefined) return\n timeoutId = setTimeout(() => {\n timeoutId = undefined\n // `lastArgs` is always set by `startTrailingTimer` immediately before\n // scheduling this timer, and `cancel()` clears the timer alongside\n // `lastArgs` — so the falsy branch is a defensive guard that the normal\n // schedule/fire/cancel flow never reaches.\n /* v8 ignore else */\n if (lastArgs) {\n invoke(lastArgs)\n lastArgs = undefined\n }\n }, delay)\n }\n\n const throttled = (...args: any[]) => {\n const now = Date.now()\n const elapsed = lastCallTime === undefined ? wait : now - lastCallTime\n if (elapsed >= wait) {\n if (leading) {\n invoke(args)\n } else {\n lastCallTime = now\n if (trailing) startTrailingTimer(args, wait)\n }\n } else if (trailing) {\n startTrailingTimer(args, wait - elapsed)\n }\n }\n\n throttled.cancel = () => {\n if (timeoutId !== undefined) {\n clearTimeout(timeoutId)\n timeoutId = undefined\n }\n lastArgs = undefined\n lastCallTime = undefined\n }\n\n return throttled as T & { cancel: () => void }\n}\n\nconst isPlainObject = (value: unknown): value is Record<string, any> =>\n value !== null &&\n typeof value === 'object' &&\n !Array.isArray(value) &&\n Object.getPrototypeOf(value) === Object.prototype\n\nexport const merge = <T extends Record<string, any>>(\n target: T,\n ...sources: Record<string, any>[]\n): T => {\n for (const source of sources) {\n if (source == null) continue\n for (const key of Object.keys(source)) {\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') continue\n const targetVal = (target as Record<string, unknown>)[key]\n const sourceVal = source[key]\n if (isPlainObject(targetVal) && isPlainObject(sourceVal)) {\n ;(target as Record<string, unknown>)[key] = merge({ ...targetVal }, sourceVal)\n } else {\n ;(target as Record<string, unknown>)[key] = sourceVal\n }\n }\n }\n return target\n}\n","import { resolveCssVariables } from './config'\n\nexport interface CssVariablesPrePaintOptions {\n /**\n * Mode attribute to set on `document.documentElement`. Defaults to the\n * resolved `init({ cssVariables })` attribute (`'data-theme'`).\n */\n attribute?: string\n /**\n * localStorage key a persisted user toggle is stored under. Defaults to\n * `'zero-theme'` (the `@pyreon/zero` convention). Values `'light'` /\n * `'dark'` win; anything else falls back to the system preference.\n */\n storageKey?: string\n /**\n * Mode to use when there is no stored preference AND the system query is\n * unavailable. Defaults to `'light'`.\n */\n fallback?: 'light' | 'dark'\n}\n\n/**\n * Build the blocking pre-paint script that sets the CSS-variables mode\n * attribute on `document.documentElement` BEFORE first paint — the standard\n * dark-mode FOUC fix.\n *\n * Inject the returned string as a synchronous `<script>` in `<head>` (it\n * must run before the body paints). It reads a persisted toggle from\n * localStorage, else the OS `prefers-color-scheme`, else `fallback`, and\n * writes the attribute at `:root` — exactly where the var rules cascade\n * from and where the ROOT `PyreonUI` writes after hydration, so the two\n * agree and there is no flash for `mode=\"system\"` or a persisted toggle.\n *\n * (Explicit hardcoded `mode=\"dark\"` with SSR and NO stored preference is the\n * one case this can't cover — the mode lives only in the app's JSX, unknown\n * to a pre-paint script; stamp `<html data-theme=\"dark\">` server-side for\n * that, or store the preference.)\n *\n * Self-contained, dependency-free, try/catch-wrapped (a storage/matchMedia\n * throw must never block paint). Safe to inline verbatim.\n *\n * @example\n * // zero injects this automatically when init({ cssVariables: true }).\n * const script = cssVariablesPrePaintScript()\n * // <script>{script}</script> in <head>\n */\nexport function cssVariablesPrePaintScript(options: CssVariablesPrePaintOptions = {}): string {\n const attribute = options.attribute ?? resolveCssVariables().attribute\n const storageKey = options.storageKey ?? 'zero-theme'\n const fallback = options.fallback ?? 'light'\n // JSON.stringify keeps the embedded strings safe inside the inline script.\n const attr = JSON.stringify(attribute)\n const key = JSON.stringify(storageKey)\n const fb = JSON.stringify(fallback)\n return (\n `(function(){try{` +\n `var s=localStorage.getItem(${key});` +\n `var m=s===\"light\"||s===\"dark\"?s:` +\n `(window.matchMedia&&window.matchMedia(\"(prefers-color-scheme:dark)\").matches?\"dark\":${fb});` +\n `document.documentElement.setAttribute(${attr},m)` +\n `}catch(e){}})()`\n )\n}\n","import { name as __pkgName, version as __pkgVersion } from '../package.json' with { type: 'json' }\nimport { registerSingleton } from '@pyreon/reactivity'\n\n// Singleton sentinel — fail-loud detection of duplicate @pyreon/ui-core\n// instances in the same heap. See @pyreon/reactivity/singleton-sentinel for\n// full rationale. Hardcoded version is acceptable here — it's a diagnostic\n// aid, not a load-bearing identity check.\nregisterSingleton(__pkgName, __pkgVersion, import.meta.url)\n\nimport compose from './compose'\nimport config, { init } from './config'\nimport type { CoreContextValue } from './context'\nimport Provider, { context } from './context'\nimport hoistNonReactStatics from './hoistNonReactStatics'\nimport type { HTMLElementAttrs, HTMLTagAttrsByTag, HTMLTags, HTMLTextTags } from './html'\nimport { HTML_TAGS, HTML_TEXT_TAGS } from './html'\nimport type { IsEmpty } from './isEmpty'\nimport isEmpty from './isEmpty'\nimport isEqual from './isEqual'\nimport { isPyreonComponent } from './isPyreonComponent'\nimport type { PyreonUIProps, ThemeMode, ThemeModeInput } from './PyreonUI'\nimport { PyreonUI, useMode } from './PyreonUI'\nimport type { Render } from './render'\nimport render from './render'\nimport { resolveSlot } from './resolveSlot'\nimport type { BreakpointKeys, Breakpoints } from './types'\nimport useStableValue from './useStableValue'\nimport { get, merge, omit, pick, set, throttle } from './utils'\n\nexport type { CSSEngineConnector, CssVariablesConfig, ResolvedCssVariablesConfig } from './config'\nexport { resolveCssVariables } from './config'\nexport type { CssVariablesPrePaintOptions } from './cssVariablesPrePaint'\nexport { cssVariablesPrePaintScript } from './cssVariablesPrePaint'\n\nexport type {\n BreakpointKeys,\n Breakpoints,\n CoreContextValue,\n HTMLElementAttrs,\n HTMLTagAttrsByTag,\n HTMLTags,\n HTMLTextTags,\n IsEmpty,\n PyreonUIProps,\n Render,\n ThemeMode,\n ThemeModeInput,\n}\n\nexport {\n compose,\n config,\n context,\n get,\n HTML_TAGS,\n HTML_TEXT_TAGS,\n hoistNonReactStatics,\n init,\n isEmpty,\n isEqual,\n isPyreonComponent,\n merge,\n omit,\n Provider,\n PyreonUI,\n pick,\n render,\n resolveSlot,\n set,\n throttle,\n useMode,\n useStableValue,\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pyreon/ui-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.35.0",
|
|
4
4
|
"description": "Core utilities, config, and context for Pyreon UI System",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/pyreon/pyreon/tree/main/packages/ui-system/ui-core#readme",
|
|
@@ -35,17 +35,17 @@
|
|
|
35
35
|
"typecheck": "tsc --noEmit"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
|
-
"@pyreon/core": "^0.
|
|
39
|
-
"@pyreon/reactivity": "^0.
|
|
38
|
+
"@pyreon/core": "^0.35.0",
|
|
39
|
+
"@pyreon/reactivity": "^0.35.0"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@pyreon/styler": "^0.
|
|
43
|
-
"@pyreon/unistyle": "^0.
|
|
42
|
+
"@pyreon/styler": "^0.35.0",
|
|
43
|
+
"@pyreon/unistyle": "^0.35.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@pyreon/manifest": "0.13.2",
|
|
47
|
-
"@pyreon/runtime-server": "^0.
|
|
48
|
-
"@pyreon/typescript": "^0.
|
|
47
|
+
"@pyreon/runtime-server": "^0.35.0",
|
|
48
|
+
"@pyreon/typescript": "^0.35.0",
|
|
49
49
|
"@pyreon/vitest-config": "0.13.3",
|
|
50
50
|
"@vitus-labs/tools-rolldown": "^2.5.0"
|
|
51
51
|
},
|