@pyreon/ui-core 0.11.5 → 0.11.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/config.ts CHANGED
@@ -1,6 +1,6 @@
1
- import type { StyledFunction } from "@pyreon/styler"
2
- import { css, keyframes, styled } from "@pyreon/styler"
3
- import type { HTMLTags } from "./html"
1
+ import type { StyledFunction } from '@pyreon/styler'
2
+ import { css, keyframes, styled } from '@pyreon/styler'
3
+ import type { HTMLTags } from './html'
4
4
 
5
5
  /**
6
6
  * Describes the shape of the CSS-in-JS engine.
@@ -19,7 +19,7 @@ interface PlatformConfig {
19
19
  createMediaQueries?: (props: {
20
20
  breakpoints: Record<string, number>
21
21
  rootSize: number
22
- css: CSSEngineConnector["css"]
22
+ css: CSSEngineConnector['css']
23
23
  }) => Record<string, (...args: any[]) => any>
24
24
  }
25
25
 
@@ -36,9 +36,9 @@ class Configuration {
36
36
  css = css
37
37
  styled: StyledFunction = styled
38
38
  keyframes = keyframes
39
- component: string | HTMLTags = "div"
40
- textComponent: string | HTMLTags = "span"
41
- createMediaQueries: PlatformConfig["createMediaQueries"] = undefined
39
+ component: string | HTMLTags = 'div'
40
+ textComponent: string | HTMLTags = 'span'
41
+ createMediaQueries: PlatformConfig['createMediaQueries'] = undefined
42
42
 
43
43
  init = (props: InitConfig) => {
44
44
  if (props.css) this.css = props.css
package/src/context.tsx CHANGED
@@ -1,13 +1,30 @@
1
- import type { VNodeChild } from "@pyreon/core"
2
- import { createContext, provide } from "@pyreon/core"
3
- import isEmpty from "./isEmpty"
4
- import type { Breakpoints } from "./types"
1
+ import type { VNodeChild } from '@pyreon/core'
2
+ import { createReactiveContext, provide } from '@pyreon/core'
3
+ import isEmpty from './isEmpty'
4
+ import type { Breakpoints } from './types'
5
5
 
6
6
  /**
7
- * Internal context shared across all @pyreon packages.
8
- * Carries the theme object plus any extra provider props.
7
+ * Core context value shared across all @pyreon UI packages.
9
8
  */
10
- const context = createContext<any>({})
9
+ export interface CoreContextValue {
10
+ theme: Record<string, unknown>
11
+ mode: 'light' | 'dark'
12
+ isDark: boolean
13
+ isLight: boolean
14
+ }
15
+
16
+ /**
17
+ * Internal reactive context shared across all @pyreon packages.
18
+ * Carries the theme object, mode, and derived dark/light flags.
19
+ *
20
+ * ReactiveContext means useContext() returns `() => CoreContextValue`.
21
+ */
22
+ const context = createReactiveContext<CoreContextValue>({
23
+ theme: {},
24
+ mode: 'light',
25
+ isDark: false,
26
+ isLight: true,
27
+ })
11
28
 
12
29
  type Theme = Partial<
13
30
  {
@@ -24,13 +41,31 @@ type ProviderType = Partial<
24
41
  >
25
42
 
26
43
  /**
44
+ * @internal Low-level provider — use `PyreonUI` from `@pyreon/ui-core` instead.
45
+ *
27
46
  * Provider that feeds the internal Pyreon context with the theme.
28
47
  * When no theme is supplied, renders children directly.
48
+ *
49
+ * @deprecated Prefer `<PyreonUI theme={theme}>` which handles all context layers.
29
50
  */
51
+ const __DEV__ = typeof process !== 'undefined' && process?.env?.NODE_ENV !== 'production'
52
+
30
53
  function Provider({ theme, children, ...props }: ProviderType): VNodeChild {
54
+ if (__DEV__) {
55
+ // eslint-disable-next-line no-console
56
+ console.warn(
57
+ '[Pyreon] CoreProvider is internal. Use <PyreonUI theme={theme}> instead — it handles all context layers (styler, core, mode) in one component.',
58
+ )
59
+ }
31
60
  if (isEmpty(theme) || !theme) return children ?? null
32
61
 
33
- provide(context, { theme, ...props })
62
+ provide(context, () => ({
63
+ theme: theme as Record<string, unknown>,
64
+ mode: (props.mode as 'light' | 'dark') ?? 'light',
65
+ isDark: props.isDark as boolean ?? false,
66
+ isLight: props.isLight as boolean ?? true,
67
+ ...props,
68
+ }))
34
69
 
35
70
  return children ?? null
36
71
  }
@@ -25,7 +25,7 @@ const hoistNonReactStatics = <T, S>(
25
25
  source: S,
26
26
  excludeList?: Record<string, true>,
27
27
  ): T => {
28
- if (typeof source === "string") return target
28
+ if (typeof source === 'string') return target
29
29
 
30
30
  const proto = Object.getPrototypeOf(source)
31
31
  if (proto && proto !== Object.prototype) {
@@ -1,149 +1,149 @@
1
1
  const HTML_TAGS = [
2
- "a",
3
- "abbr",
4
- "address",
5
- "area",
6
- "article",
7
- "aside",
8
- "audio",
9
- "b",
10
- "bdi",
11
- "bdo",
12
- "big",
13
- "blockquote",
14
- "body",
15
- "br",
16
- "button",
17
- "canvas",
18
- "caption",
19
- "cite",
20
- "code",
21
- "col",
22
- "colgroup",
23
- "data",
24
- "datalist",
25
- "dd",
26
- "del",
27
- "details",
28
- "dfn",
29
- "dialog",
30
- "div",
31
- "dl",
32
- "dt",
33
- "em",
34
- "embed",
35
- "fieldset",
36
- "figcaption",
37
- "figure",
38
- "footer",
39
- "form",
40
- "h1",
41
- "h2",
42
- "h3",
43
- "h4",
44
- "h5",
45
- "h6",
46
- "header",
47
- "hr",
48
- "html",
49
- "i",
50
- "iframe",
51
- "img",
52
- "input",
53
- "ins",
54
- "kbd",
55
- "label",
56
- "legend",
57
- "li",
58
- "main",
59
- "map",
60
- "mark",
61
- "meter",
62
- "nav",
63
- "object",
64
- "ol",
65
- "optgroup",
66
- "option",
67
- "output",
68
- "p",
69
- "picture",
70
- "pre",
71
- "progress",
72
- "q",
73
- "rp",
74
- "rt",
75
- "ruby",
76
- "s",
77
- "samp",
78
- "section",
79
- "select",
80
- "small",
81
- "source",
82
- "span",
83
- "strong",
84
- "sub",
85
- "summary",
86
- "sup",
87
- "svg",
88
- "table",
89
- "tbody",
90
- "td",
91
- "template",
92
- "textarea",
93
- "tfoot",
94
- "th",
95
- "thead",
96
- "time",
97
- "tr",
98
- "track",
99
- "u",
100
- "ul",
101
- "var",
102
- "video",
103
- "wbr",
2
+ 'a',
3
+ 'abbr',
4
+ 'address',
5
+ 'area',
6
+ 'article',
7
+ 'aside',
8
+ 'audio',
9
+ 'b',
10
+ 'bdi',
11
+ 'bdo',
12
+ 'big',
13
+ 'blockquote',
14
+ 'body',
15
+ 'br',
16
+ 'button',
17
+ 'canvas',
18
+ 'caption',
19
+ 'cite',
20
+ 'code',
21
+ 'col',
22
+ 'colgroup',
23
+ 'data',
24
+ 'datalist',
25
+ 'dd',
26
+ 'del',
27
+ 'details',
28
+ 'dfn',
29
+ 'dialog',
30
+ 'div',
31
+ 'dl',
32
+ 'dt',
33
+ 'em',
34
+ 'embed',
35
+ 'fieldset',
36
+ 'figcaption',
37
+ 'figure',
38
+ 'footer',
39
+ 'form',
40
+ 'h1',
41
+ 'h2',
42
+ 'h3',
43
+ 'h4',
44
+ 'h5',
45
+ 'h6',
46
+ 'header',
47
+ 'hr',
48
+ 'html',
49
+ 'i',
50
+ 'iframe',
51
+ 'img',
52
+ 'input',
53
+ 'ins',
54
+ 'kbd',
55
+ 'label',
56
+ 'legend',
57
+ 'li',
58
+ 'main',
59
+ 'map',
60
+ 'mark',
61
+ 'meter',
62
+ 'nav',
63
+ 'object',
64
+ 'ol',
65
+ 'optgroup',
66
+ 'option',
67
+ 'output',
68
+ 'p',
69
+ 'picture',
70
+ 'pre',
71
+ 'progress',
72
+ 'q',
73
+ 'rp',
74
+ 'rt',
75
+ 'ruby',
76
+ 's',
77
+ 'samp',
78
+ 'section',
79
+ 'select',
80
+ 'small',
81
+ 'source',
82
+ 'span',
83
+ 'strong',
84
+ 'sub',
85
+ 'summary',
86
+ 'sup',
87
+ 'svg',
88
+ 'table',
89
+ 'tbody',
90
+ 'td',
91
+ 'template',
92
+ 'textarea',
93
+ 'tfoot',
94
+ 'th',
95
+ 'thead',
96
+ 'time',
97
+ 'tr',
98
+ 'track',
99
+ 'u',
100
+ 'ul',
101
+ 'var',
102
+ 'video',
103
+ 'wbr',
104
104
  ] as const
105
105
 
106
106
  const HTML_TEXT_TAGS = [
107
- "abbr",
108
- "b",
109
- "bdi",
110
- "bdo",
111
- "big",
112
- "blockquote",
113
- "cite",
114
- "code",
115
- "del",
116
- "div",
117
- "dl",
118
- "dt",
119
- "em",
120
- "figcaption",
121
- "h1",
122
- "h2",
123
- "h3",
124
- "h4",
125
- "h5",
126
- "h6",
127
- "i",
128
- "ins",
129
- "kbd",
130
- "label",
131
- "legend",
132
- "li",
133
- "p",
134
- "pre",
135
- "q",
136
- "rp",
137
- "rt",
138
- "s",
139
- "small",
140
- "span",
141
- "strong",
142
- "sub",
143
- "summary",
144
- "sup",
145
- "time",
146
- "u",
107
+ 'abbr',
108
+ 'b',
109
+ 'bdi',
110
+ 'bdo',
111
+ 'big',
112
+ 'blockquote',
113
+ 'cite',
114
+ 'code',
115
+ 'del',
116
+ 'div',
117
+ 'dl',
118
+ 'dt',
119
+ 'em',
120
+ 'figcaption',
121
+ 'h1',
122
+ 'h2',
123
+ 'h3',
124
+ 'h4',
125
+ 'h5',
126
+ 'h6',
127
+ 'i',
128
+ 'ins',
129
+ 'kbd',
130
+ 'label',
131
+ 'legend',
132
+ 'li',
133
+ 'p',
134
+ 'pre',
135
+ 'q',
136
+ 'rp',
137
+ 'rt',
138
+ 's',
139
+ 'small',
140
+ 'span',
141
+ 'strong',
142
+ 'sub',
143
+ 'summary',
144
+ 'sup',
145
+ 'time',
146
+ 'u',
147
147
  ] as const
148
148
 
149
149
  export type HTMLTags = (typeof HTML_TAGS)[number]
package/src/html/index.ts CHANGED
@@ -1,6 +1,6 @@
1
- import type { HTMLElementAttrs } from "./htmlElementAttrs"
2
- import type { HTMLTags, HTMLTextTags } from "./htmlTags"
3
- import { HTML_TAGS, HTML_TEXT_TAGS } from "./htmlTags"
1
+ import type { HTMLElementAttrs } from './htmlElementAttrs'
2
+ import type { HTMLTags, HTMLTextTags } from './htmlTags'
3
+ import { HTML_TAGS, HTML_TEXT_TAGS } from './htmlTags'
4
4
 
5
5
  type HTMLTagAttrsByTag<T extends HTMLTags> = T extends HTMLTags
6
6
  ? HTMLElementAttrs[T]
package/src/index.ts CHANGED
@@ -1,25 +1,27 @@
1
- import compose from "./compose"
2
- import config, { init } from "./config"
3
- import Provider, { context } from "./context"
4
- import hoistNonReactStatics from "./hoistNonReactStatics"
5
- import type { HTMLElementAttrs, HTMLTagAttrsByTag, HTMLTags, HTMLTextTags } from "./html"
6
- import { HTML_TAGS, HTML_TEXT_TAGS } from "./html"
7
- import type { IsEmpty } from "./isEmpty"
8
- import isEmpty from "./isEmpty"
9
- import isEqual from "./isEqual"
10
- import type { PyreonUIProps, ThemeMode, ThemeModeInput } from "./PyreonUI"
11
- import { PyreonUI, useMode } from "./PyreonUI"
12
- import type { Render } from "./render"
13
- import render from "./render"
14
- import type { BreakpointKeys, Breakpoints } from "./types"
15
- import useStableValue from "./useStableValue"
16
- import { get, merge, omit, pick, set, throttle } from "./utils"
1
+ import compose from './compose'
2
+ import config, { init } from './config'
3
+ import type { CoreContextValue } from './context'
4
+ import Provider, { context } from './context'
5
+ import hoistNonReactStatics from './hoistNonReactStatics'
6
+ import type { HTMLElementAttrs, HTMLTagAttrsByTag, HTMLTags, HTMLTextTags } from './html'
7
+ import { HTML_TAGS, HTML_TEXT_TAGS } from './html'
8
+ import type { IsEmpty } from './isEmpty'
9
+ import isEmpty from './isEmpty'
10
+ import isEqual from './isEqual'
11
+ import type { PyreonUIProps, ThemeMode, ThemeModeInput } from './PyreonUI'
12
+ import { PyreonUI, useMode } from './PyreonUI'
13
+ import type { Render } from './render'
14
+ import render from './render'
15
+ import type { BreakpointKeys, Breakpoints } from './types'
16
+ import useStableValue from './useStableValue'
17
+ import { get, merge, omit, pick, set, throttle } from './utils'
17
18
 
18
- export type { CSSEngineConnector } from "./config"
19
+ export type { CSSEngineConnector } from './config'
19
20
 
20
21
  export type {
21
22
  BreakpointKeys,
22
23
  Breakpoints,
24
+ CoreContextValue,
23
25
  HTMLElementAttrs,
24
26
  HTMLTagAttrsByTag,
25
27
  HTMLTags,
package/src/isEmpty.ts CHANGED
@@ -12,7 +12,7 @@ export type IsEmpty = <T extends Record<number | string, any> | any[] | null | u
12
12
 
13
13
  const isEmpty = (<T extends Record<number | string, any> | any[] | null | undefined>(param: T) => {
14
14
  if (!param) return true
15
- if (typeof param !== "object") return true
15
+ if (typeof param !== 'object') return true
16
16
  if (Array.isArray(param)) return param.length === 0
17
17
  return Object.keys(param).length === 0
18
18
  }) as IsEmpty
package/src/isEqual.ts CHANGED
@@ -18,7 +18,7 @@ const isObjectEqual = (a: Record<string, unknown>, b: Record<string, unknown>):
18
18
 
19
19
  const isEqual = (a: unknown, b: unknown): boolean => {
20
20
  if (Object.is(a, b)) return true
21
- if (typeof a !== typeof b || a == null || b == null || typeof a !== "object") return false
21
+ if (typeof a !== typeof b || a == null || b == null || typeof a !== 'object') return false
22
22
  if (Array.isArray(a)) return Array.isArray(b) && isArrayEqual(a, b)
23
23
  if (Array.isArray(b)) return false
24
24
  return isObjectEqual(a as Record<string, unknown>, b as Record<string, unknown>)
package/src/render.tsx CHANGED
@@ -1,5 +1,5 @@
1
- import type { ComponentFn, Props, VNodeChild } from "@pyreon/core"
2
- import { h } from "@pyreon/core"
1
+ import type { ComponentFn, Props, VNodeChild } from '@pyreon/core'
2
+ import { h } from '@pyreon/core'
3
3
 
4
4
  type RenderProps<T extends Record<string, unknown> | undefined> = (props: Partial<T>) => VNodeChild
5
5
 
@@ -21,7 +21,7 @@ const render: Render = (content, attachProps) => {
21
21
  if (!content) return null
22
22
 
23
23
  const t = typeof content
24
- if (t === "string" || t === "number" || t === "boolean" || t === "bigint") {
24
+ if (t === 'string' || t === 'number' || t === 'boolean' || t === 'bigint') {
25
25
  return content as VNodeChild
26
26
  }
27
27
 
@@ -29,10 +29,10 @@ const render: Render = (content, attachProps) => {
29
29
  return content as VNodeChild
30
30
  }
31
31
 
32
- if (typeof content === "function") {
32
+ if (typeof content === 'function') {
33
33
  // Extract key from props — it's a VNode concept, not a component prop.
34
34
  // Passing key inside props causes JSX runtime warnings.
35
- if (attachProps && "key" in attachProps) {
35
+ if (attachProps && 'key' in attachProps) {
36
36
  const { key, ...rest } = attachProps
37
37
  return h(content as string | ComponentFn, rest as Props)
38
38
  }
@@ -40,7 +40,7 @@ const render: Render = (content, attachProps) => {
40
40
  }
41
41
 
42
42
  // VNode object — return directly
43
- if (typeof content === "object") {
43
+ if (typeof content === 'object') {
44
44
  return content as VNodeChild
45
45
  }
46
46
 
@@ -1,5 +1,5 @@
1
- import { signal } from "@pyreon/reactivity"
2
- import isEqual from "./isEqual"
1
+ import { signal } from '@pyreon/reactivity'
2
+ import isEqual from './isEqual'
3
3
 
4
4
  /**
5
5
  * Returns a referentially stable version of `value`. The returned reference
package/src/utils.ts CHANGED
@@ -39,7 +39,7 @@ const parsePath = (path: string | string[]): string[] => {
39
39
  }
40
40
 
41
41
  const isUnsafeKey = (key: string): boolean =>
42
- key === "__proto__" || key === "prototype" || key === "constructor"
42
+ key === '__proto__' || key === 'prototype' || key === 'constructor'
43
43
 
44
44
  export const get = (obj: any, path: string | string[], defaultValue?: any): any => {
45
45
  const keys = parsePath(path)
@@ -132,7 +132,7 @@ export const throttle = <T extends (...args: any[]) => any>(
132
132
 
133
133
  const isPlainObject = (value: unknown): value is Record<string, any> =>
134
134
  value !== null &&
135
- typeof value === "object" &&
135
+ typeof value === 'object' &&
136
136
  !Array.isArray(value) &&
137
137
  Object.getPrototypeOf(value) === Object.prototype
138
138
 
@@ -143,7 +143,7 @@ export const merge = <T extends Record<string, any>>(
143
143
  for (const source of sources) {
144
144
  if (source == null) continue
145
145
  for (const key of Object.keys(source)) {
146
- if (key === "__proto__" || key === "constructor" || key === "prototype") continue
146
+ if (key === '__proto__' || key === 'constructor' || key === 'prototype') continue
147
147
  const targetVal = (target as Record<string, unknown>)[key]
148
148
  const sourceVal = source[key]
149
149
  if (isPlainObject(targetVal) && isPlainObject(sourceVal)) {