@pyreon/ui-core 0.26.3 → 0.28.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 CHANGED
@@ -1,5 +1,5 @@
1
1
  import { StyledFunction, css, keyframes, styled } from "@pyreon/styler";
2
- import { ComponentFn, VNodeChild } from "@pyreon/core";
2
+ import { ComponentFn, VNodeChild, VNodeChildAtom } from "@pyreon/core";
3
3
  import { PyreonTheme } from "@pyreon/unistyle";
4
4
 
5
5
  //#region src/compose.d.ts
@@ -230,6 +230,74 @@ declare const isEmpty: IsEmpty;
230
230
  //#region src/isEqual.d.ts
231
231
  declare const isEqual: (a: unknown, b: unknown) => boolean;
232
232
  //#endregion
233
+ //#region src/isPyreonComponent.d.ts
234
+ /**
235
+ * Detect whether a function value is a component (framework-marked OR
236
+ * user-authored bare function), as opposed to a plain reactive-accessor
237
+ * function.
238
+ *
239
+ * Used by `resolveSlot` (and any other slot-resolver) to discriminate
240
+ * between
241
+ * `beforeContent={Header}` — component-reference shorthand, MUST mount
242
+ * as `h(Component, null)` so the framework's runWithHooks setup
243
+ * window is established (and any framework HOC's
244
+ * `removeUndefinedProps(props)` / `splitProps(props)` get the
245
+ * default-filled props object, not bare `undefined`).
246
+ * `beforeContent={() => <Header />}` — anonymous reactive accessor,
247
+ * called bare so its body's signal reads land inside the enclosing
248
+ * `mountReactive` effect.
249
+ *
250
+ * Both shapes are `typeof === 'function'`. The discriminator combines two
251
+ * checks (most-specific-first):
252
+ *
253
+ * **Tier 1 — framework markers** (load-bearing for HOC pipelines):
254
+ * - `IS_ROCKETSTYLE` — set by `@pyreon/rocketstyle`
255
+ * (`rocketstyle.ts:527`, `542`) on every `rocketstyle(...).config(...)`
256
+ * chain end-point.
257
+ * - `PYREON__COMPONENT` — set by every `@pyreon/elements` component
258
+ * factory (Element, Text, List, Portal, Overlay, Util, Content,
259
+ * Wrapper, …).
260
+ * - `pkgName` — same components also carry this; checked as a fallback
261
+ * in case a third-party package mirrors the elements convention.
262
+ *
263
+ * **Tier 2 — naming convention** (catches user-authored bare components
264
+ * without markers):
265
+ * - `displayName` is set → component. Authors set displayName
266
+ * deliberately for devtools / debug output; it's an explicit
267
+ * declaration of component intent.
268
+ * - `.name` starts with an uppercase letter → component. JSX already
269
+ * requires PascalCase for components (`<MyComp/>` is treated as a
270
+ * component; `<mycomp/>` is treated as a host tag); the discriminator
271
+ * mirrors that convention for slot-shorthand usage. Anonymous
272
+ * arrows (`name: ""`), default-export functions (`name: "default"`),
273
+ * and camelCase helpers fall through to the accessor path.
274
+ *
275
+ * Why Tier 2 matters — the bug class it closes: a bare-function component
276
+ * that internally uses lifecycle hooks (`useWindowResize`, `onMount`,
277
+ * `provide`, etc.) needs a `runWithHooks` setup window so the hook calls
278
+ * find `_current` non-null. Without Tier 2, `resolveSlot` would call the
279
+ * function bare → `_current === null` → `[Pyreon] onMount() called outside
280
+ * component setup` warning fires in dev-mode SSR. Routing the same
281
+ * function through `h(value, null)` mounts it as a proper component via
282
+ * the standard `runWithHooks`-based path; the hooks register correctly
283
+ * AND the warning never fires.
284
+ *
285
+ * Why the convention split is safe: a PascalCase function paired with
286
+ * the `beforeContent={Fn}` shorthand is canonically a component reference
287
+ * (matches every framework example in the docs). An anonymous arrow
288
+ * `() => signal() ? <A/> : <B/>` is canonically a reactive accessor
289
+ * (intent: re-evaluate on signal change). The naming convention is the
290
+ * same one JSX itself uses to differentiate component vs host element.
291
+ *
292
+ * Before this check, `resolveSlot` called any function-valued slot
293
+ * bare, crashing real consumers that used the
294
+ * `beforeContent={Component}` shorthand documented since the original
295
+ * Element API. The marker check (Tier 1) rescues framework-factory
296
+ * components; this Tier-2 convention check closes the residual gap
297
+ * for user-authored hook-using bare components.
298
+ */
299
+ declare function isPyreonComponent(value: unknown): boolean;
300
+ //#endregion
233
301
  //#region src/PyreonUI.d.ts
234
302
  type ThemeMode = 'light' | 'dark';
235
303
  type ThemeModeInput = ThemeMode | 'system';
@@ -316,6 +384,43 @@ type RenderProps<T extends Record<string, unknown> | undefined> = (props: Partia
316
384
  type Render = <T extends Record<string, any> | undefined>(content?: ComponentFn | string | VNodeChild | VNodeChild[] | RenderProps<T>, attachProps?: T) => VNodeChild;
317
385
  declare const render: Render;
318
386
  //#endregion
387
+ //#region src/resolveSlot.d.ts
388
+ /**
389
+ * Resolve a slot value INSIDE a reactive accessor. If the consumer passed
390
+ * a function-returning-VNode (e.g. `content={() => <Icon name={signal()} />}`),
391
+ * unwrap it by calling — its body's signal reads are then tracked by the
392
+ * enclosing mountReactive effect, and the slot re-renders on signal change.
393
+ * Static VNodes / strings / null pass through unchanged to `render()`.
394
+ *
395
+ * **Component vs accessor discriminator** —
396
+ * `beforeContent={Header}` (component-reference shorthand) and
397
+ * `content={() => <X />}` (reactive accessor) are BOTH `typeof === 'function'`.
398
+ * Calling both bare crashes component shorthands the moment a
399
+ * rocketstyle / attrs HOC runs `removeUndefinedProps(undefined)` on the
400
+ * un-supplied props (`TypeError: Cannot convert undefined or null to object`).
401
+ *
402
+ * Discriminator: framework components carry one of two markers attached by
403
+ * their factory:
404
+ * - `IS_ROCKETSTYLE` — anything `rocketstyle()` produces
405
+ * - `PYREON__COMPONENT` / `pkgName` — `@pyreon/elements` components
406
+ * (Element, Text, List, Portal, Overlay, Util)
407
+ * Marked function → mount as `h(Component, null)` (no props, defaults
408
+ * fill in via the HOC pipeline). Unmarked function → reactive accessor,
409
+ * called bare so its return value (a VNode) renders. Bare-function
410
+ * components without HOC wrapping (e.g. `const MyComp = () => <div />`)
411
+ * also work via the accessor path — they're called with no args and
412
+ * their VNode return goes through `render()` correctly. The marker
413
+ * check ONLY rescues components that REQUIRE props to be defined.
414
+ * Tier 2 of `isPyreonComponent` (PascalCase `.name` / explicit
415
+ * `displayName`) additionally catches user-authored bare components
416
+ * that use lifecycle hooks — see `isPyreonComponent` JSDoc.
417
+ *
418
+ * Return type is the RESOLVED atom (VNodeChildAtom | VNodeChildAtom[]) —
419
+ * never a nested accessor — so the enclosing `() => resolveSlot(...)` IS
420
+ * a valid VNodeChildAccessor in the JSX child position.
421
+ */
422
+ declare const resolveSlot: (value: unknown) => VNodeChildAtom | VNodeChildAtom[];
423
+ //#endregion
319
424
  //#region src/useStableValue.d.ts
320
425
  /**
321
426
  * Returns a referentially stable version of `value`. The returned reference
@@ -360,5 +465,5 @@ declare const throttle: <T extends (...args: any[]) => any>(fn: T, wait?: number
360
465
  };
361
466
  declare const merge: <T extends Record<string, any>>(target: T, ...sources: Record<string, any>[]) => T;
362
467
  //#endregion
363
- export { type BreakpointKeys, type Breakpoints, type CSSEngineConnector, type CoreContextValue, type HTMLElementAttrs, type HTMLTagAttrsByTag, type HTMLTags, type HTMLTextTags, HTML_TAGS, HTML_TEXT_TAGS, type IsEmpty, Provider, PyreonUI, type PyreonUIProps, type Render, type ThemeMode, type ThemeModeInput, compose, config, context, get, hoistNonReactStatics, init, isEmpty, isEqual, merge, omit, pick, render, set, throttle, useMode, useStableValue };
468
+ export { type BreakpointKeys, type Breakpoints, type CSSEngineConnector, type CoreContextValue, type HTMLElementAttrs, type HTMLTagAttrsByTag, type HTMLTags, type HTMLTextTags, HTML_TAGS, HTML_TEXT_TAGS, type IsEmpty, Provider, PyreonUI, type PyreonUIProps, type Render, type ThemeMode, type ThemeModeInput, compose, config, context, get, hoistNonReactStatics, init, isEmpty, isEqual, isPyreonComponent, merge, omit, pick, render, resolveSlot, set, throttle, useMode, useStableValue };
364
469
  //# sourceMappingURL=index2.d.ts.map
@@ -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/PyreonUI.tsx","../../src/render.tsx","../../src/useStableValue.ts","../../src/utils.ts"],"mappings":"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"}
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"],"mappings":"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"}
package/lib/index.js CHANGED
@@ -290,6 +290,86 @@ const isEqual = (a, b) => {
290
290
  return isObjectEqual(a, b);
291
291
  };
292
292
 
293
+ //#endregion
294
+ //#region src/isPyreonComponent.ts
295
+ /**
296
+ * Detect whether a function value is a component (framework-marked OR
297
+ * user-authored bare function), as opposed to a plain reactive-accessor
298
+ * function.
299
+ *
300
+ * Used by `resolveSlot` (and any other slot-resolver) to discriminate
301
+ * between
302
+ * `beforeContent={Header}` — component-reference shorthand, MUST mount
303
+ * as `h(Component, null)` so the framework's runWithHooks setup
304
+ * window is established (and any framework HOC's
305
+ * `removeUndefinedProps(props)` / `splitProps(props)` get the
306
+ * default-filled props object, not bare `undefined`).
307
+ * `beforeContent={() => <Header />}` — anonymous reactive accessor,
308
+ * called bare so its body's signal reads land inside the enclosing
309
+ * `mountReactive` effect.
310
+ *
311
+ * Both shapes are `typeof === 'function'`. The discriminator combines two
312
+ * checks (most-specific-first):
313
+ *
314
+ * **Tier 1 — framework markers** (load-bearing for HOC pipelines):
315
+ * - `IS_ROCKETSTYLE` — set by `@pyreon/rocketstyle`
316
+ * (`rocketstyle.ts:527`, `542`) on every `rocketstyle(...).config(...)`
317
+ * chain end-point.
318
+ * - `PYREON__COMPONENT` — set by every `@pyreon/elements` component
319
+ * factory (Element, Text, List, Portal, Overlay, Util, Content,
320
+ * Wrapper, …).
321
+ * - `pkgName` — same components also carry this; checked as a fallback
322
+ * in case a third-party package mirrors the elements convention.
323
+ *
324
+ * **Tier 2 — naming convention** (catches user-authored bare components
325
+ * without markers):
326
+ * - `displayName` is set → component. Authors set displayName
327
+ * deliberately for devtools / debug output; it's an explicit
328
+ * declaration of component intent.
329
+ * - `.name` starts with an uppercase letter → component. JSX already
330
+ * requires PascalCase for components (`<MyComp/>` is treated as a
331
+ * component; `<mycomp/>` is treated as a host tag); the discriminator
332
+ * mirrors that convention for slot-shorthand usage. Anonymous
333
+ * arrows (`name: ""`), default-export functions (`name: "default"`),
334
+ * and camelCase helpers fall through to the accessor path.
335
+ *
336
+ * Why Tier 2 matters — the bug class it closes: a bare-function component
337
+ * that internally uses lifecycle hooks (`useWindowResize`, `onMount`,
338
+ * `provide`, etc.) needs a `runWithHooks` setup window so the hook calls
339
+ * find `_current` non-null. Without Tier 2, `resolveSlot` would call the
340
+ * function bare → `_current === null` → `[Pyreon] onMount() called outside
341
+ * component setup` warning fires in dev-mode SSR. Routing the same
342
+ * function through `h(value, null)` mounts it as a proper component via
343
+ * the standard `runWithHooks`-based path; the hooks register correctly
344
+ * AND the warning never fires.
345
+ *
346
+ * Why the convention split is safe: a PascalCase function paired with
347
+ * the `beforeContent={Fn}` shorthand is canonically a component reference
348
+ * (matches every framework example in the docs). An anonymous arrow
349
+ * `() => signal() ? <A/> : <B/>` is canonically a reactive accessor
350
+ * (intent: re-evaluate on signal change). The naming convention is the
351
+ * same one JSX itself uses to differentiate component vs host element.
352
+ *
353
+ * Before this check, `resolveSlot` called any function-valued slot
354
+ * bare, crashing real consumers that used the
355
+ * `beforeContent={Component}` shorthand documented since the original
356
+ * Element API. The marker check (Tier 1) rescues framework-factory
357
+ * components; this Tier-2 convention check closes the residual gap
358
+ * for user-authored hook-using bare components.
359
+ */
360
+ function isPyreonComponent(value) {
361
+ if (typeof value !== "function") return false;
362
+ if (Object.hasOwn(value, "IS_ROCKETSTYLE") || Object.hasOwn(value, "PYREON__COMPONENT") || Object.hasOwn(value, "pkgName")) return true;
363
+ const fn = value;
364
+ if (typeof fn.displayName === "string" && fn.displayName.length > 0) return true;
365
+ const name = fn.name;
366
+ if (typeof name === "string" && name.length > 0) {
367
+ const first = name.charCodeAt(0);
368
+ if (first >= 65 && first <= 90) return true;
369
+ }
370
+ return false;
371
+ }
372
+
293
373
  //#endregion
294
374
  //#region src/PyreonUI.tsx
295
375
  const _isBrowser = typeof window !== "undefined" && typeof matchMedia === "function";
@@ -394,6 +474,50 @@ const render = (content, attachProps) => {
394
474
  return content;
395
475
  };
396
476
 
477
+ //#endregion
478
+ //#region src/resolveSlot.ts
479
+ /**
480
+ * Resolve a slot value INSIDE a reactive accessor. If the consumer passed
481
+ * a function-returning-VNode (e.g. `content={() => <Icon name={signal()} />}`),
482
+ * unwrap it by calling — its body's signal reads are then tracked by the
483
+ * enclosing mountReactive effect, and the slot re-renders on signal change.
484
+ * Static VNodes / strings / null pass through unchanged to `render()`.
485
+ *
486
+ * **Component vs accessor discriminator** —
487
+ * `beforeContent={Header}` (component-reference shorthand) and
488
+ * `content={() => <X />}` (reactive accessor) are BOTH `typeof === 'function'`.
489
+ * Calling both bare crashes component shorthands the moment a
490
+ * rocketstyle / attrs HOC runs `removeUndefinedProps(undefined)` on the
491
+ * un-supplied props (`TypeError: Cannot convert undefined or null to object`).
492
+ *
493
+ * Discriminator: framework components carry one of two markers attached by
494
+ * their factory:
495
+ * - `IS_ROCKETSTYLE` — anything `rocketstyle()` produces
496
+ * - `PYREON__COMPONENT` / `pkgName` — `@pyreon/elements` components
497
+ * (Element, Text, List, Portal, Overlay, Util)
498
+ * Marked function → mount as `h(Component, null)` (no props, defaults
499
+ * fill in via the HOC pipeline). Unmarked function → reactive accessor,
500
+ * called bare so its return value (a VNode) renders. Bare-function
501
+ * components without HOC wrapping (e.g. `const MyComp = () => <div />`)
502
+ * also work via the accessor path — they're called with no args and
503
+ * their VNode return goes through `render()` correctly. The marker
504
+ * check ONLY rescues components that REQUIRE props to be defined.
505
+ * Tier 2 of `isPyreonComponent` (PascalCase `.name` / explicit
506
+ * `displayName`) additionally catches user-authored bare components
507
+ * that use lifecycle hooks — see `isPyreonComponent` JSDoc.
508
+ *
509
+ * Return type is the RESOLVED atom (VNodeChildAtom | VNodeChildAtom[]) —
510
+ * never a nested accessor — so the enclosing `() => resolveSlot(...)` IS
511
+ * a valid VNodeChildAccessor in the JSX child position.
512
+ */
513
+ const resolveSlot = (value) => {
514
+ if (typeof value === "function") {
515
+ if (isPyreonComponent(value)) return h(value, null);
516
+ return value();
517
+ }
518
+ return render(value);
519
+ };
520
+
397
521
  //#endregion
398
522
  //#region src/useStableValue.ts
399
523
  /**
@@ -543,5 +667,5 @@ const merge = (target, ...sources) => {
543
667
  registerSingleton("@pyreon/ui-core", "0.24.6", import.meta.url);
544
668
 
545
669
  //#endregion
546
- export { HTML_TAGS, HTML_TEXT_TAGS, Provider, PyreonUI, compose, config, context, get, hoistNonReactStatics, init, isEmpty, isEqual, merge, omit, pick, render, set, throttle, useMode, useStableValue };
670
+ export { HTML_TAGS, HTML_TEXT_TAGS, Provider, PyreonUI, compose, config, context, get, hoistNonReactStatics, init, isEmpty, isEqual, isPyreonComponent, merge, omit, pick, render, resolveSlot, set, throttle, useMode, useStableValue };
547
671
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["coreContext"],"sources":["../src/compose.ts","../src/config.ts","../src/isEmpty.ts","../src/context.tsx","../src/hoistNonReactStatics.ts","../src/html/htmlTags.ts","../src/isEqual.ts","../src/PyreonUI.tsx","../src/render.tsx","../src/useStableValue.ts","../src/utils.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\ntype InitConfig = Partial<CSSEngineConnector & PlatformConfig>\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 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 }\n}\n\nconst config = new Configuration()\nconst { init } = config\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 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 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","import type { VNodeChild } from '@pyreon/core'\nimport { createReactiveContext, nativeCompat, provide, useContext } from '@pyreon/core'\nimport { computed, signal } from '@pyreon/reactivity'\nimport { ThemeContext } from '@pyreon/styler'\nimport type { PyreonTheme } from '@pyreon/unistyle'\nimport { enrichTheme } from '@pyreon/unistyle'\nimport { context as coreContext } from './context'\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\nconst _isBrowser = typeof window !== 'undefined' && 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 const prefersDark = _isBrowser\n ? matchMedia('(prefers-color-scheme: dark)').matches\n : false\n _systemMode = signal<ThemeMode>(prefersDark ? 'dark' : 'light')\n\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 const enrichedTheme = computed(() => {\n const t = props.theme\n if (t === undefined || t === null) return parentThemeAccessor()\n return enrichTheme(t)\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 provide(coreContext, () => ({\n theme: enrichedTheme(),\n mode: modeComputed(),\n isDark: modeComputed() === 'dark',\n isLight: modeComputed() === 'light',\n }))\n\n // 3. Mode context — getter function for useMode()\n provide(ModeContext, () => modeComputed())\n\n return props.children ?? null\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 if (typeof content === 'object') {\n return content as VNodeChild\n }\n\n return content as VNodeChild\n}\n\nexport default render\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 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 { 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('@pyreon/ui-core', '0.24.6', 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 type { PyreonUIProps, ThemeMode, ThemeModeInput } from './PyreonUI'\nimport { PyreonUI, useMode } from './PyreonUI'\nimport type { Render } from './render'\nimport render from './render'\nimport type { BreakpointKeys, Breakpoints } from './types'\nimport useStableValue from './useStableValue'\nimport { get, merge, omit, pick, set, throttle } from './utils'\n\nexport type { CSSEngineConnector } from './config'\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 merge,\n omit,\n Provider,\n PyreonUI,\n pick,\n render,\n set,\n throttle,\n useMode,\n useStableValue,\n}\n"],"mappings":";;;;;;AAKA,MAAM,WACqB,GAAG,SAC3B,MACC,IAAI,aAAa,KAAU,QAAa,IAAI,GAAG,GAAG,CAAC;;;;;;;;;;;AC0BvD,IAAM,gBAAN,MAAoB;CAClB,MAAM;CACN,SAAyB;CACzB,YAAY;CACZ,YAA+B;CAC/B,gBAAmC;CACnC,qBAA2D;CAE3D,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;CAChE;AACF;AAEA,MAAM,SAAS,IAAI,cAAc;AACjC,MAAM,EAAE,SAAS;;;;ACzCjB,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;CACzE,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;;;;AC3ErB,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;EAC9D,IAAI,YACF,IAAI;GACF,OAAO,eAAe,QAAQ,KAAK,UAAU;EAC/C,QAAQ,CAER;CAEJ;CAEA,OAAO;AACT;;;;ACxDA,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;CAC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"}
1
+ {"version":3,"file":"index.js","names":["coreContext"],"sources":["../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/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\ntype InitConfig = Partial<CSSEngineConnector & PlatformConfig>\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 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 }\n}\n\nconst config = new Configuration()\nconst { init } = config\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 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 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 { createReactiveContext, nativeCompat, provide, useContext } from '@pyreon/core'\nimport { computed, signal } from '@pyreon/reactivity'\nimport { ThemeContext } from '@pyreon/styler'\nimport type { PyreonTheme } from '@pyreon/unistyle'\nimport { enrichTheme } from '@pyreon/unistyle'\nimport { context as coreContext } from './context'\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\nconst _isBrowser = typeof window !== 'undefined' && 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 const prefersDark = _isBrowser\n ? matchMedia('(prefers-color-scheme: dark)').matches\n : false\n _systemMode = signal<ThemeMode>(prefersDark ? 'dark' : 'light')\n\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 const enrichedTheme = computed(() => {\n const t = props.theme\n if (t === undefined || t === null) return parentThemeAccessor()\n return enrichTheme(t)\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 provide(coreContext, () => ({\n theme: enrichedTheme(),\n mode: modeComputed(),\n isDark: modeComputed() === 'dark',\n isLight: modeComputed() === 'light',\n }))\n\n // 3. Mode context — getter function for useMode()\n provide(ModeContext, () => modeComputed())\n\n return props.children ?? null\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 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 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 { 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('@pyreon/ui-core', '0.24.6', 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 } from './config'\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":";;;;;;AAKA,MAAM,WACqB,GAAG,SAC3B,MACC,IAAI,aAAa,KAAU,QAAa,IAAI,GAAG,GAAG,CAAC;;;;;;;;;;;AC0BvD,IAAM,gBAAN,MAAoB;CAClB,MAAM;CACN,SAAyB;CACzB,YAAY;CACZ,YAA+B;CAC/B,gBAAmC;CACnC,qBAA2D;CAE3D,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;CAChE;AACF;AAEA,MAAM,SAAS,IAAI,cAAc;AACjC,MAAM,EAAE,SAAS;;;;ACzCjB,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;CACzE,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;;;;AC3ErB,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;EAC9D,IAAI,YACF,IAAI;GACF,OAAO,eAAe,QAAQ,KAAK,UAAU;EAC/C,QAAQ,CAER;CAEJ;CAEA,OAAO;AACT;;;;ACxDA,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;CAC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"}
package/package.json CHANGED
@@ -1,19 +1,17 @@
1
1
  {
2
2
  "name": "@pyreon/ui-core",
3
- "version": "0.26.3",
3
+ "version": "0.28.0",
4
4
  "description": "Core utilities, config, and context for Pyreon UI System",
5
5
  "license": "MIT",
6
+ "homepage": "https://github.com/pyreon/pyreon/tree/main/packages/ui-system/ui-core#readme",
7
+ "bugs": {
8
+ "url": "https://github.com/pyreon/pyreon/issues"
9
+ },
6
10
  "repository": {
7
11
  "type": "git",
8
- "url": "https://github.com/pyreon/pyreon",
12
+ "url": "https://github.com/pyreon/pyreon.git",
9
13
  "directory": "packages/ui-system/ui-core"
10
14
  },
11
- "files": [
12
- "lib",
13
- "!lib/analysis",
14
- "README.md",
15
- "LICENSE"
16
- ],
17
15
  "type": "module",
18
16
  "sideEffects": false,
19
17
  "main": "./lib/index.js",
@@ -24,30 +22,36 @@
24
22
  "types": "./lib/index.d.ts"
25
23
  }
26
24
  },
27
- "publishConfig": {
28
- "access": "public"
29
- },
25
+ "files": [
26
+ "lib",
27
+ "!lib/analysis",
28
+ "README.md",
29
+ "LICENSE"
30
+ ],
30
31
  "scripts": {
31
32
  "build": "bun run vl_rolldown_build",
32
33
  "lint": "oxlint .",
33
34
  "test": "vitest run",
34
35
  "typecheck": "tsc --noEmit"
35
36
  },
37
+ "peerDependencies": {
38
+ "@pyreon/core": "^0.28.0",
39
+ "@pyreon/reactivity": "^0.28.0"
40
+ },
41
+ "dependencies": {
42
+ "@pyreon/styler": "^0.28.0",
43
+ "@pyreon/unistyle": "^0.28.0"
44
+ },
36
45
  "devDependencies": {
37
46
  "@pyreon/manifest": "0.13.1",
38
- "@pyreon/typescript": "^0.26.3",
47
+ "@pyreon/typescript": "^0.28.0",
39
48
  "@pyreon/vitest-config": "0.13.1",
40
49
  "@vitus-labs/tools-rolldown": "^2.5.0"
41
50
  },
42
51
  "engines": {
43
52
  "node": ">= 22"
44
53
  },
45
- "dependencies": {
46
- "@pyreon/styler": "^0.26.3",
47
- "@pyreon/unistyle": "^0.26.3"
48
- },
49
- "peerDependencies": {
50
- "@pyreon/core": "^0.26.3",
51
- "@pyreon/reactivity": "^0.26.3"
54
+ "publishConfig": {
55
+ "access": "public"
52
56
  }
53
57
  }