@pyreon/elements 0.14.0 → 0.16.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 +113 -56
- package/lib/index.js +200 -180
- package/package.json +14 -13
- package/src/Element/component.tsx +16 -4
- package/src/List/component.tsx +65 -15
- package/src/Overlay/component.tsx +6 -1
- package/src/Overlay/context.tsx +5 -1
- package/src/Portal/component.tsx +23 -10
- package/src/__tests__/Element.test.ts +157 -0
- package/src/__tests__/Iterator.test.ts +12 -3
- package/src/__tests__/Iterator.types.test.ts +237 -0
- package/src/__tests__/Overlay.test.ts +8 -1
- package/src/__tests__/Portal.test.ts +122 -48
- package/src/__tests__/Wrapper-innerhtml.test.tsx +178 -0
- package/src/__tests__/Wrapper.test.tsx +44 -0
- package/src/__tests__/elements.browser.test.tsx +77 -4
- package/src/__tests__/internElementBundle.test.ts +102 -0
- package/src/__tests__/native-markers.test.ts +13 -0
- package/src/__tests__/useOverlay.test.ts +7 -1
- package/src/__tests__/wrapper-block-cascade.test.ts +121 -0
- package/src/env.d.ts +6 -0
- package/src/helpers/Iterator/component.tsx +55 -4
- package/src/helpers/Iterator/index.ts +17 -1
- package/src/helpers/Iterator/types.ts +97 -38
- package/src/helpers/Wrapper/component.tsx +67 -30
- package/src/helpers/Wrapper/styled.ts +12 -18
- package/src/helpers/internElementBundle.ts +37 -0
- package/src/index.ts +4 -0
- package/src/types.ts +33 -2
- package/src/utils.ts +1 -4
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js.map +0 -1
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import { styles } from '../helpers/Wrapper/styled'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Regression test for the responsive `block` cascade bug (mirrors vitus-labs's
|
|
6
|
+
* "couple of fixes" PR #121).
|
|
7
|
+
*
|
|
8
|
+
* Scenario: a responsive theme like `block: [true, false, true]` runs the
|
|
9
|
+
* styles callback once per breakpoint with a single-value `t.block`. The bug
|
|
10
|
+
* was that `align-self`, `flex`/`width` etc. were emitted ONLY when
|
|
11
|
+
* `t.block` was truthy — so the breakpoint where `t.block` is false emitted
|
|
12
|
+
* nothing, leaving the previous breakpoint's `align-self: stretch` cascading
|
|
13
|
+
* through the mobile-first @media query.
|
|
14
|
+
*
|
|
15
|
+
* Fix: always emit a value for these properties (truthy → stretch/100%,
|
|
16
|
+
* falsy → auto/auto). The mobile-first @media cascade then resets cleanly
|
|
17
|
+
* when `block` flips false at a later breakpoint.
|
|
18
|
+
*
|
|
19
|
+
* The styles callback is called per-breakpoint with the per-breakpoint theme
|
|
20
|
+
* already resolved to a single value — so testing it directly with two
|
|
21
|
+
* scalar themes is enough to lock in the always-emit contract.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
const identityCss = (strings: TemplateStringsArray, ...vals: unknown[]) => {
|
|
25
|
+
let r = ''
|
|
26
|
+
for (let i = 0; i < strings.length; i++) {
|
|
27
|
+
r += strings[i]
|
|
28
|
+
if (i < vals.length) {
|
|
29
|
+
const v = vals[i]
|
|
30
|
+
// Mirror styled-components / styler interpolation: drop falsy
|
|
31
|
+
// interpolations, stringify the rest. CSSResult instances (from the
|
|
32
|
+
// alignContent / extendCss helpers) coerce via their toString.
|
|
33
|
+
if (v === false || v == null) continue
|
|
34
|
+
r += String(v)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return r
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const renderAt = (theme: Record<string, unknown>): string =>
|
|
41
|
+
String(styles({ theme, css: identityCss }))
|
|
42
|
+
|
|
43
|
+
describe('Wrapper styles — responsive block cascade reset', () => {
|
|
44
|
+
it('emits stretch/100%/flex when block is true', () => {
|
|
45
|
+
const out = renderAt({
|
|
46
|
+
block: true,
|
|
47
|
+
direction: 'inline',
|
|
48
|
+
alignX: 'left',
|
|
49
|
+
alignY: 'center',
|
|
50
|
+
})
|
|
51
|
+
expect(out).toContain('align-self: stretch')
|
|
52
|
+
expect(out).toContain('width: 100%')
|
|
53
|
+
expect(out).toContain('display: flex')
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
it('emits auto/auto/inline-flex reset when block is false (key fix)', () => {
|
|
57
|
+
const out = renderAt({
|
|
58
|
+
block: false,
|
|
59
|
+
direction: 'inline',
|
|
60
|
+
alignX: 'left',
|
|
61
|
+
alignY: 'center',
|
|
62
|
+
})
|
|
63
|
+
// The fix: these properties MUST be emitted with reset values so the
|
|
64
|
+
// mobile-first @media cascade doesn't leak `align-self: stretch` from a
|
|
65
|
+
// smaller breakpoint where block was true.
|
|
66
|
+
expect(out).toContain('align-self: auto')
|
|
67
|
+
expect(out).toContain('width: auto')
|
|
68
|
+
expect(out).toContain('display: inline-flex')
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
it('emits height: 100% when alignY is "block", auto otherwise', () => {
|
|
72
|
+
const blockY = renderAt({
|
|
73
|
+
block: false,
|
|
74
|
+
direction: 'inline',
|
|
75
|
+
alignX: 'left',
|
|
76
|
+
alignY: 'block',
|
|
77
|
+
})
|
|
78
|
+
expect(blockY).toContain('height: 100%')
|
|
79
|
+
|
|
80
|
+
const nonBlockY = renderAt({
|
|
81
|
+
block: false,
|
|
82
|
+
direction: 'inline',
|
|
83
|
+
alignX: 'left',
|
|
84
|
+
alignY: 'center',
|
|
85
|
+
})
|
|
86
|
+
expect(nonBlockY).toContain('height: auto')
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
it('does not emit display when childFix is set (parent split)', () => {
|
|
90
|
+
const out = renderAt({
|
|
91
|
+
block: true,
|
|
92
|
+
childFix: true,
|
|
93
|
+
direction: 'inline',
|
|
94
|
+
alignX: 'left',
|
|
95
|
+
alignY: 'center',
|
|
96
|
+
})
|
|
97
|
+
// childFix branch handles its own display rules outside the responsive
|
|
98
|
+
// styles callback.
|
|
99
|
+
expect(out).not.toContain('display: flex;')
|
|
100
|
+
expect(out).not.toContain('display: inline-flex;')
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
it('emits parentFix flex-direction: column only when parentFix is set', () => {
|
|
104
|
+
const withParentFix = renderAt({
|
|
105
|
+
block: true,
|
|
106
|
+
parentFix: true,
|
|
107
|
+
direction: 'inline',
|
|
108
|
+
alignX: 'left',
|
|
109
|
+
alignY: 'center',
|
|
110
|
+
})
|
|
111
|
+
expect(withParentFix).toContain('flex-direction: column')
|
|
112
|
+
|
|
113
|
+
const withoutParentFix = renderAt({
|
|
114
|
+
block: true,
|
|
115
|
+
direction: 'inline',
|
|
116
|
+
alignX: 'left',
|
|
117
|
+
alignY: 'center',
|
|
118
|
+
})
|
|
119
|
+
expect(withoutParentFix).not.toContain('flex-direction: column')
|
|
120
|
+
})
|
|
121
|
+
})
|
package/src/env.d.ts
ADDED
|
@@ -10,7 +10,15 @@
|
|
|
10
10
|
import type { VNode, VNodeChild } from '@pyreon/core'
|
|
11
11
|
import { Fragment } from '@pyreon/core'
|
|
12
12
|
import { isEmpty, render } from '@pyreon/ui-core'
|
|
13
|
-
import type {
|
|
13
|
+
import type {
|
|
14
|
+
ChildrenProps,
|
|
15
|
+
ExtendedProps,
|
|
16
|
+
LooseProps,
|
|
17
|
+
ObjectProps,
|
|
18
|
+
ObjectValue,
|
|
19
|
+
SimpleProps,
|
|
20
|
+
SimpleValue,
|
|
21
|
+
} from './types'
|
|
14
22
|
|
|
15
23
|
type ClassifiedData =
|
|
16
24
|
| { type: 'simple'; data: SimpleValue[] }
|
|
@@ -70,7 +78,7 @@ const attachItemProps: AttachItemProps = ({ i, length }: { i: number; length: nu
|
|
|
70
78
|
}
|
|
71
79
|
}
|
|
72
80
|
|
|
73
|
-
const Component = (props:
|
|
81
|
+
const Component = (props: LooseProps) => {
|
|
74
82
|
const {
|
|
75
83
|
itemKey,
|
|
76
84
|
valueName,
|
|
@@ -246,7 +254,50 @@ const Component = (props: Props) => {
|
|
|
246
254
|
return renderItems()
|
|
247
255
|
}
|
|
248
256
|
|
|
249
|
-
|
|
257
|
+
// ---------------------------------------------------------------------------
|
|
258
|
+
// Public callable type — overloads expose the generic `<T>` API at the JSX
|
|
259
|
+
// boundary while the impl stays loose-typed. TS picks the matching overload
|
|
260
|
+
// based on the props object passed:
|
|
261
|
+
//
|
|
262
|
+
// <Iterator data={['a','b']} valueName="text" component={Item} />
|
|
263
|
+
// ^ T inferred as string → SimpleProps<string> overload selected
|
|
264
|
+
//
|
|
265
|
+
// <Iterator data={users} component={UserCard} />
|
|
266
|
+
// ^ T inferred as User → ObjectProps<User> overload selected
|
|
267
|
+
//
|
|
268
|
+
// <Iterator>{...}</Iterator> → ChildrenProps overload selected
|
|
269
|
+
// ---------------------------------------------------------------------------
|
|
270
|
+
export interface IteratorComponent {
|
|
271
|
+
// T is inferred from the `data` prop at the JSX site — no explicit
|
|
272
|
+
// generic argument needed. Order matters: SimpleProps first (matches
|
|
273
|
+
// `data: SimpleValue[]`), then ObjectProps (object[]), then ChildrenProps,
|
|
274
|
+
// then a LooseProps fallback.
|
|
275
|
+
//
|
|
276
|
+
// The narrow overloads (Simple / Object / Children) drive per-mode T
|
|
277
|
+
// inference and stricter compile-time errors for direct callers (e.g.
|
|
278
|
+
// `valueName` required for primitive arrays, forbidden for object arrays).
|
|
279
|
+
// The LooseProps fallback exists for forwarding patterns where the props
|
|
280
|
+
// type is a wide union that doesn't bind to any single narrow overload —
|
|
281
|
+
// notably `Partial<(typeof Wrapper)['$$types']>` spread back into the JSX
|
|
282
|
+
// site after `@pyreon/rocketstyle`'s 4-overload-aware `ExtractProps`
|
|
283
|
+
// distributes the union across all of Iterator's call signatures. Without
|
|
284
|
+
// the loose binding home, the wide union has nowhere to land and TS
|
|
285
|
+
// reports "no overload matches this call" at every forwarding site.
|
|
286
|
+
//
|
|
287
|
+
// Direct callers still see the strict per-mode errors — the loose fallback
|
|
288
|
+
// only fires when none of the three narrow overloads match.
|
|
289
|
+
<T extends SimpleValue>(props: SimpleProps<T>): VNodeChild
|
|
290
|
+
<T extends ObjectValue>(props: ObjectProps<T>): VNodeChild
|
|
291
|
+
(props: ChildrenProps): VNodeChild
|
|
292
|
+
(props: LooseProps): VNodeChild
|
|
293
|
+
isIterator: true
|
|
294
|
+
RESERVED_PROPS: typeof RESERVED_PROPS
|
|
295
|
+
displayName?: string
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
const Iterator = Object.assign(Component, {
|
|
250
299
|
isIterator: true as const,
|
|
251
300
|
RESERVED_PROPS,
|
|
252
|
-
})
|
|
301
|
+
}) as unknown as IteratorComponent
|
|
302
|
+
|
|
303
|
+
export default Iterator
|
|
@@ -1,14 +1,30 @@
|
|
|
1
1
|
import component from './component'
|
|
2
2
|
import type {
|
|
3
|
+
ChildrenProps,
|
|
3
4
|
ElementType,
|
|
4
5
|
ExtendedProps,
|
|
6
|
+
LooseProps,
|
|
5
7
|
MaybeNull,
|
|
8
|
+
ObjectProps,
|
|
6
9
|
ObjectValue,
|
|
7
10
|
Props,
|
|
8
11
|
PropsCallback,
|
|
12
|
+
SimpleProps,
|
|
9
13
|
SimpleValue,
|
|
10
14
|
} from './types'
|
|
11
15
|
|
|
12
|
-
export type {
|
|
16
|
+
export type {
|
|
17
|
+
ChildrenProps,
|
|
18
|
+
ElementType,
|
|
19
|
+
ExtendedProps,
|
|
20
|
+
LooseProps,
|
|
21
|
+
MaybeNull,
|
|
22
|
+
ObjectProps,
|
|
23
|
+
ObjectValue,
|
|
24
|
+
Props,
|
|
25
|
+
PropsCallback,
|
|
26
|
+
SimpleProps,
|
|
27
|
+
SimpleValue,
|
|
28
|
+
}
|
|
13
29
|
|
|
14
30
|
export default component
|
|
@@ -23,6 +23,80 @@ export type ExtendedProps = {
|
|
|
23
23
|
position: number
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// Per-mode prop shapes — narrowed via the `T` data-element type
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Iterator over an array of strings/numbers. Each item is wrapped in
|
|
32
|
+
* `{ [valueName]: item }` and that object is what callbacks see + what's
|
|
33
|
+
* spread onto the rendered component.
|
|
34
|
+
*/
|
|
35
|
+
export type SimpleProps<T extends SimpleValue> = {
|
|
36
|
+
data: Array<T | MaybeNull>
|
|
37
|
+
/** A component to be rendered per item. */
|
|
38
|
+
component: ElementType
|
|
39
|
+
/**
|
|
40
|
+
* Key under which each primitive value is exposed to `component` and
|
|
41
|
+
* callbacks. Defaults to `'children'` at runtime — i.e. the value is
|
|
42
|
+
* passed to the component as its children.
|
|
43
|
+
*/
|
|
44
|
+
valueName?: string
|
|
45
|
+
/** Optional wrapper around each item. */
|
|
46
|
+
wrapComponent?: ElementType
|
|
47
|
+
/** Stable key per item (defaults to index). */
|
|
48
|
+
itemKey?: (item: T, index: number) => SimpleValue
|
|
49
|
+
/** Extra props merged onto the rendered component, optionally per-item. */
|
|
50
|
+
itemProps?: TObj | ((item: { [k: string]: T }, ext: ExtendedProps) => TObj)
|
|
51
|
+
/** Extra props merged onto the wrapper, optionally per-item. */
|
|
52
|
+
wrapProps?: TObj | ((item: { [k: string]: T }, ext: ExtendedProps) => TObj)
|
|
53
|
+
children?: never
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Iterator over an array of objects. Each item is spread onto the rendered
|
|
58
|
+
* component as props. Per-item `component` overrides also work — when an
|
|
59
|
+
* item carries its own `component` field, the wrapper is bypassed.
|
|
60
|
+
*/
|
|
61
|
+
export type ObjectProps<T extends ObjectValue> = {
|
|
62
|
+
data: Array<T | MaybeNull>
|
|
63
|
+
/** Default component to be rendered per item (item-level `component` overrides). */
|
|
64
|
+
component: ElementType
|
|
65
|
+
/** `valueName` is meaningless when iterating objects — TS forbids it. */
|
|
66
|
+
valueName?: never
|
|
67
|
+
/** Optional wrapper around each item. */
|
|
68
|
+
wrapComponent?: ElementType
|
|
69
|
+
/** Stable key per item — pick a key from the item, or compute it. */
|
|
70
|
+
itemKey?: keyof T | ((item: T, index: number) => SimpleValue)
|
|
71
|
+
/** Extra props merged onto the rendered component, optionally per-item. */
|
|
72
|
+
itemProps?: TObj | ((item: T, ext: ExtendedProps) => TObj)
|
|
73
|
+
/** Extra props merged onto the wrapper, optionally per-item. */
|
|
74
|
+
wrapProps?: TObj | ((item: T, ext: ExtendedProps) => TObj)
|
|
75
|
+
children?: never
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Iterator over `children` — no `data`/`component`. Each child gets
|
|
80
|
+
* positional metadata via `itemProps` and an optional `wrapComponent`.
|
|
81
|
+
*/
|
|
82
|
+
export type ChildrenProps = {
|
|
83
|
+
children: VNodeChild
|
|
84
|
+
data?: never
|
|
85
|
+
component?: never
|
|
86
|
+
valueName?: never
|
|
87
|
+
itemKey?: never
|
|
88
|
+
wrapComponent?: ElementType
|
|
89
|
+
itemProps?: TObj | ((_: Record<string, never>, ext: ExtendedProps) => TObj)
|
|
90
|
+
wrapProps?: TObj | ((_: Record<string, never>, ext: ExtendedProps) => TObj)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// ---------------------------------------------------------------------------
|
|
94
|
+
// Loose backward-compatible fallback shape (today's behavior)
|
|
95
|
+
//
|
|
96
|
+
// Used when callers don't (or can't) parameterize `Props<T>` — keeps the
|
|
97
|
+
// existing call surface intact so this refactor lands non-breaking.
|
|
98
|
+
// ---------------------------------------------------------------------------
|
|
99
|
+
|
|
26
100
|
export type PropsCallback =
|
|
27
101
|
| TObj
|
|
28
102
|
| ((
|
|
@@ -30,50 +104,35 @@ export type PropsCallback =
|
|
|
30
104
|
extendedProps: ExtendedProps,
|
|
31
105
|
) => TObj)
|
|
32
106
|
|
|
33
|
-
export type
|
|
34
|
-
/**
|
|
35
|
-
* Valid children
|
|
36
|
-
*/
|
|
107
|
+
export type LooseProps = Partial<{
|
|
37
108
|
children: VNodeChild
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Array of data passed to `component` prop
|
|
41
|
-
*/
|
|
42
109
|
data: Array<SimpleValue | ObjectValue | MaybeNull>
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* A component to be rendered within list
|
|
46
|
-
*/
|
|
47
110
|
component: ElementType
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Defines name of the prop to be passed to the iteration component
|
|
51
|
-
* when **data** prop is type of `string[]`, `number[]` or combination
|
|
52
|
-
* of both. Otherwise ignored.
|
|
53
|
-
*/
|
|
54
111
|
valueName: string
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* A component to be rendered within list. `wrapComponent`
|
|
58
|
-
* wraps `component`. Therefore it can be used to enhance the behavior
|
|
59
|
-
* of the list component
|
|
60
|
-
*/
|
|
61
112
|
wrapComponent: ElementType
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Extension of **item** `component` props to be passed
|
|
65
|
-
*/
|
|
66
113
|
itemProps: PropsCallback
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
* Extension of **item** `wrapComponent` props to be passed
|
|
70
|
-
*/
|
|
71
|
-
wrapProps?: PropsCallback
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Extension of **item** `wrapComponent` props to be passed
|
|
75
|
-
*/
|
|
76
|
-
itemKey?:
|
|
114
|
+
wrapProps: PropsCallback
|
|
115
|
+
itemKey:
|
|
77
116
|
| keyof ObjectValue
|
|
78
117
|
| ((item: SimpleValue | Omit<ObjectValue, 'component'>, index: number) => SimpleValue)
|
|
79
118
|
}>
|
|
119
|
+
|
|
120
|
+
// ---------------------------------------------------------------------------
|
|
121
|
+
// Public, generic-aware Props<T>
|
|
122
|
+
//
|
|
123
|
+
// Props<string> → SimpleProps<string> (valueName REQUIRED)
|
|
124
|
+
// Props<{ id; name }> → ObjectProps<{...}> (valueName FORBIDDEN)
|
|
125
|
+
// Props<unknown> / Props → LooseProps (today's behavior)
|
|
126
|
+
//
|
|
127
|
+
// `unknown extends T` is the canonical "did the caller actually narrow T?"
|
|
128
|
+
// check — true only when T is left as `unknown`, false for any concrete
|
|
129
|
+
// narrowing. Fallback to LooseProps preserves existing call sites.
|
|
130
|
+
// ---------------------------------------------------------------------------
|
|
131
|
+
|
|
132
|
+
export type Props<T = unknown> = unknown extends T
|
|
133
|
+
? LooseProps
|
|
134
|
+
: T extends SimpleValue
|
|
135
|
+
? SimpleProps<T>
|
|
136
|
+
: T extends ObjectValue
|
|
137
|
+
? ObjectProps<T>
|
|
138
|
+
: ChildrenProps
|
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
* support `display: flex` consistently across browsers.
|
|
6
6
|
*/
|
|
7
7
|
import { splitProps } from '@pyreon/core'
|
|
8
|
+
import { getShouldBeEmpty } from '../../Element/utils'
|
|
8
9
|
import { IS_DEVELOPMENT } from '../../utils'
|
|
10
|
+
import { internElementBundle } from '../internElementBundle'
|
|
9
11
|
import Styled from './styled'
|
|
10
12
|
import type { Props } from './types'
|
|
11
13
|
import { isWebFixNeeded } from './utils'
|
|
@@ -41,46 +43,81 @@ const Component = (props: Partial<Props> & { ref?: unknown }) => {
|
|
|
41
43
|
|
|
42
44
|
const needsFix = !own.dangerouslySetInnerHTML && isWebFixNeeded(own.tag)
|
|
43
45
|
|
|
46
|
+
// Void HTML elements (hr, input, img, br, …) cannot have children. Even
|
|
47
|
+
// a falsy `{own.children}` slot becomes `[undefined]` in the vnode and
|
|
48
|
+
// trips runtime-dom's void-element warning. Element already skips passing
|
|
49
|
+
// children to Wrapper for void tags; this guard makes sure the empty
|
|
50
|
+
// slot is dropped here too instead of leaking into the JSX.
|
|
51
|
+
const isVoidTag = !own.dangerouslySetInnerHTML && getShouldBeEmpty(own.tag)
|
|
52
|
+
|
|
53
|
+
// dangerouslySetInnerHTML and children are mutually exclusive — both
|
|
54
|
+
// become inner content (per `runtime-server/src/index.ts:228` and
|
|
55
|
+
// `runtime-dom/src/props.ts:289`). Pre-fix the prop was in OWN_KEYS,
|
|
56
|
+
// moved into `own` by splitProps, and never re-attached to the rendered
|
|
57
|
+
// vnode — so `<Logo dangerouslySetInnerHTML={...} />` rendered an empty
|
|
58
|
+
// <div></div>. Forward the prop to the styled vnode and drop the
|
|
59
|
+
// children slot when innerHTML is set.
|
|
60
|
+
const innerHTML = own.dangerouslySetInnerHTML
|
|
61
|
+
|
|
44
62
|
if (!needsFix) {
|
|
63
|
+
const bundle = internElementBundle({
|
|
64
|
+
block: own.block,
|
|
65
|
+
direction: own.direction,
|
|
66
|
+
alignX: own.alignX,
|
|
67
|
+
alignY: own.alignY,
|
|
68
|
+
equalCols: own.equalCols,
|
|
69
|
+
extraStyles: own.extendCss,
|
|
70
|
+
})
|
|
71
|
+
if (isVoidTag) {
|
|
72
|
+
return <Styled {...commonProps} $element={bundle} />
|
|
73
|
+
}
|
|
74
|
+
if (innerHTML) {
|
|
75
|
+
return <Styled {...commonProps} $element={bundle} dangerouslySetInnerHTML={innerHTML} />
|
|
76
|
+
}
|
|
45
77
|
return (
|
|
46
|
-
<Styled
|
|
47
|
-
{...commonProps}
|
|
48
|
-
$element={{
|
|
49
|
-
block: own.block,
|
|
50
|
-
direction: own.direction,
|
|
51
|
-
alignX: own.alignX,
|
|
52
|
-
alignY: own.alignY,
|
|
53
|
-
equalCols: own.equalCols,
|
|
54
|
-
extraStyles: own.extendCss,
|
|
55
|
-
}}
|
|
56
|
-
>
|
|
78
|
+
<Styled {...commonProps} $element={bundle}>
|
|
57
79
|
{own.children}
|
|
58
80
|
</Styled>
|
|
59
81
|
)
|
|
60
82
|
}
|
|
61
83
|
|
|
62
84
|
const asTag = own.isInline ? 'span' : 'div'
|
|
85
|
+
const parentBundle = internElementBundle({
|
|
86
|
+
parentFix: true as const,
|
|
87
|
+
block: own.block,
|
|
88
|
+
extraStyles: own.extendCss,
|
|
89
|
+
})
|
|
90
|
+
const childBundle = internElementBundle({
|
|
91
|
+
childFix: true as const,
|
|
92
|
+
direction: own.direction,
|
|
93
|
+
alignX: own.alignX,
|
|
94
|
+
alignY: own.alignY,
|
|
95
|
+
equalCols: own.equalCols,
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
// needsFix path: innerHTML belongs on the INNER styled node (where the
|
|
99
|
+
// actual content lives), NOT on the outer flex-fix wrapper. The
|
|
100
|
+
// `needsFix` computation already excludes the innerHTML case
|
|
101
|
+
// (`!own.dangerouslySetInnerHTML && isWebFixNeeded(own.tag)`), so this
|
|
102
|
+
// branch normally won't execute when innerHTML is set — but we keep
|
|
103
|
+
// the defensive forwarding so the contract is robust against future
|
|
104
|
+
// refactors of the needsFix gate.
|
|
105
|
+
if (innerHTML) {
|
|
106
|
+
return (
|
|
107
|
+
<Styled {...commonProps} $element={parentBundle}>
|
|
108
|
+
<Styled
|
|
109
|
+
as={asTag}
|
|
110
|
+
$childFix
|
|
111
|
+
$element={childBundle}
|
|
112
|
+
dangerouslySetInnerHTML={innerHTML}
|
|
113
|
+
/>
|
|
114
|
+
</Styled>
|
|
115
|
+
)
|
|
116
|
+
}
|
|
63
117
|
|
|
64
118
|
return (
|
|
65
|
-
<Styled
|
|
66
|
-
{
|
|
67
|
-
$element={{
|
|
68
|
-
parentFix: true as const,
|
|
69
|
-
block: own.block,
|
|
70
|
-
extraStyles: own.extendCss,
|
|
71
|
-
}}
|
|
72
|
-
>
|
|
73
|
-
<Styled
|
|
74
|
-
as={asTag}
|
|
75
|
-
$childFix
|
|
76
|
-
$element={{
|
|
77
|
-
childFix: true as const,
|
|
78
|
-
direction: own.direction,
|
|
79
|
-
alignX: own.alignX,
|
|
80
|
-
alignY: own.alignY,
|
|
81
|
-
equalCols: own.equalCols,
|
|
82
|
-
}}
|
|
83
|
-
>
|
|
119
|
+
<Styled {...commonProps} $element={parentBundle}>
|
|
120
|
+
<Styled as={asTag} $childFix $element={childBundle}>
|
|
84
121
|
{own.children}
|
|
85
122
|
</Styled>
|
|
86
123
|
</Styled>
|
|
@@ -23,31 +23,25 @@ const parentFixCSS = `
|
|
|
23
23
|
flex-direction: column;
|
|
24
24
|
`
|
|
25
25
|
|
|
26
|
-
const
|
|
27
|
-
height: 100%;
|
|
28
|
-
`
|
|
29
|
-
|
|
30
|
-
const blockCSS = `
|
|
31
|
-
align-self: stretch;
|
|
32
|
-
flex: 1;
|
|
33
|
-
min-width: 0;
|
|
34
|
-
`
|
|
35
|
-
|
|
36
|
-
const childFixPosition = (isBlock?: boolean) => `display: ${isBlock ? 'flex' : 'inline-flex'};`
|
|
37
|
-
|
|
38
|
-
const styles: ResponsiveStylesCallback = ({ theme: t, css: cssFn }) => cssFn`
|
|
39
|
-
${t.alignY === 'block' && fullHeightCSS};
|
|
40
|
-
|
|
26
|
+
export const styles: ResponsiveStylesCallback = ({ theme: t, css: cssFn }) => cssFn`
|
|
41
27
|
${alignContent({
|
|
42
28
|
direction: t.direction,
|
|
43
29
|
alignX: t.alignX,
|
|
44
30
|
alignY: t.alignY,
|
|
45
31
|
})};
|
|
46
32
|
|
|
47
|
-
|
|
48
|
-
|
|
33
|
+
/*
|
|
34
|
+
* Always emit a value for the block-related properties so a responsive
|
|
35
|
+
* theme that flips from \`block: true\` at one breakpoint to \`block: false\`
|
|
36
|
+
* at another resets cleanly. Previously \`align-self\` / \`width\` / \`height\`
|
|
37
|
+
* were only set when the truthy branch matched, which left the prior
|
|
38
|
+
* breakpoint's values cascading through.
|
|
39
|
+
*/
|
|
40
|
+
${`align-self: ${t.block ? 'stretch' : 'auto'};
|
|
41
|
+
width: ${t.block ? '100%' : 'auto'};
|
|
42
|
+
height: ${t.alignY === 'block' ? '100%' : 'auto'};`};
|
|
49
43
|
|
|
50
|
-
${!t.childFix &&
|
|
44
|
+
${!t.childFix && `display: ${t.block ? 'flex' : 'inline-flex'};`};
|
|
51
45
|
${t.parentFix && parentFixCSS};
|
|
52
46
|
|
|
53
47
|
${t.extraStyles && extendCss(t.extraStyles as Parameters<typeof extendCss>[0])};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module-scope intern cache for `$element` bundles passed to Wrapper's styled
|
|
3
|
+
* component. Same primitive prop tuple → same object identity, so the styler's
|
|
4
|
+
* `elClassCache` (added 2026-Q2 alongside this) hits and skips the resolve
|
|
5
|
+
* pipeline. Analogous to `@pyreon/rocketstyle`'s dimension-prop memo (PR #344)
|
|
6
|
+
* but at the layer below — covers non-rocketstyle Element / Wrapper / Text usage
|
|
7
|
+
* AND the residual styled wrappers under any rocketstyle component.
|
|
8
|
+
*
|
|
9
|
+
* Cache key is a JSON-stringified shallow snapshot of the bundle. LRU-bound at
|
|
10
|
+
* 256 entries; oldest-first eviction. Bail (return the input as-is, no cache)
|
|
11
|
+
* when any value is a function (signal accessor) or a non-string object (CSS
|
|
12
|
+
* callback / CSSResult / nested object) — those cannot be safely round-tripped
|
|
13
|
+
* through JSON without losing identity guarantees.
|
|
14
|
+
*/
|
|
15
|
+
const _bundleCache = new Map<string, Record<string, unknown>>()
|
|
16
|
+
const BUNDLE_CAP = 256
|
|
17
|
+
|
|
18
|
+
export const internElementBundle = <T extends Record<string, unknown>>(bundle: T): T => {
|
|
19
|
+
for (const k in bundle) {
|
|
20
|
+
const v = bundle[k]
|
|
21
|
+
if (typeof v === 'function') return bundle
|
|
22
|
+
if (v != null && typeof v === 'object') return bundle
|
|
23
|
+
}
|
|
24
|
+
const key = JSON.stringify(bundle)
|
|
25
|
+
const existing = _bundleCache.get(key)
|
|
26
|
+
if (existing) {
|
|
27
|
+
_bundleCache.delete(key)
|
|
28
|
+
_bundleCache.set(key, existing)
|
|
29
|
+
return existing as T
|
|
30
|
+
}
|
|
31
|
+
if (_bundleCache.size >= BUNDLE_CAP) {
|
|
32
|
+
const oldest = _bundleCache.keys().next().value
|
|
33
|
+
if (oldest !== undefined) _bundleCache.delete(oldest)
|
|
34
|
+
}
|
|
35
|
+
_bundleCache.set(key, bundle)
|
|
36
|
+
return bundle
|
|
37
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -3,12 +3,16 @@ import { Provider } from '@pyreon/unistyle'
|
|
|
3
3
|
export type { ElementProps, PyreonElement } from './Element'
|
|
4
4
|
export { Element } from './Element'
|
|
5
5
|
export type {
|
|
6
|
+
ChildrenProps as IteratorChildrenProps,
|
|
6
7
|
ElementType,
|
|
7
8
|
ExtendedProps,
|
|
9
|
+
LooseProps as IteratorLooseProps,
|
|
8
10
|
MaybeNull,
|
|
11
|
+
ObjectProps as IteratorObjectProps,
|
|
9
12
|
ObjectValue,
|
|
10
13
|
Props as IteratorProps,
|
|
11
14
|
PropsCallback,
|
|
15
|
+
SimpleProps as IteratorSimpleProps,
|
|
12
16
|
SimpleValue,
|
|
13
17
|
} from './helpers/Iterator'
|
|
14
18
|
export { default as Iterator } from './helpers/Iterator'
|
package/src/types.ts
CHANGED
|
@@ -69,8 +69,39 @@ export type Responsive =
|
|
|
69
69
|
|
|
70
70
|
export type ExtendCss = Css | Css[] | Partial<Record<BreakpointKeys, Css>>
|
|
71
71
|
|
|
72
|
-
|
|
73
|
-
|
|
72
|
+
/**
|
|
73
|
+
* Extracts the props type from a Pyreon component function — multi-overload
|
|
74
|
+
* aware. Matches up to 4 call signatures and produces the UNION of their
|
|
75
|
+
* first-argument types. Iterator / List ship 3-overload primitives whose
|
|
76
|
+
* LAST overload is `ChildrenProps` (the loosest); without overload-aware
|
|
77
|
+
* extraction, `ExtractProps<Iterator>` returned just `ChildrenProps` and
|
|
78
|
+
* lost `SimpleProps<T>` / `ObjectProps<T>` shapes. Mirrors vitus-labs
|
|
79
|
+
* PR #222.
|
|
80
|
+
*
|
|
81
|
+
* Kept in sync with the copies in `@pyreon/core` / `@pyreon/attrs` /
|
|
82
|
+
* `@pyreon/rocketstyle`.
|
|
83
|
+
*/
|
|
84
|
+
export type ExtractProps<TComponentOrTProps> = TComponentOrTProps extends {
|
|
85
|
+
(props: infer P1, ...args: any): any
|
|
86
|
+
(props: infer P2, ...args: any): any
|
|
87
|
+
(props: infer P3, ...args: any): any
|
|
88
|
+
(props: infer P4, ...args: any): any
|
|
89
|
+
}
|
|
90
|
+
? P1 | P2 | P3 | P4
|
|
91
|
+
: TComponentOrTProps extends {
|
|
92
|
+
(props: infer P1, ...args: any): any
|
|
93
|
+
(props: infer P2, ...args: any): any
|
|
94
|
+
(props: infer P3, ...args: any): any
|
|
95
|
+
}
|
|
96
|
+
? P1 | P2 | P3
|
|
97
|
+
: TComponentOrTProps extends {
|
|
98
|
+
(props: infer P1, ...args: any): any
|
|
99
|
+
(props: infer P2, ...args: any): any
|
|
100
|
+
}
|
|
101
|
+
? P1 | P2
|
|
102
|
+
: TComponentOrTProps extends ComponentFn<infer TProps>
|
|
103
|
+
? TProps
|
|
104
|
+
: TComponentOrTProps
|
|
74
105
|
|
|
75
106
|
export type PyreonComponent<P extends Record<string, any> = {}> = ComponentFn<P> & PyreonStatic
|
|
76
107
|
|
package/src/utils.ts
CHANGED
|
@@ -2,7 +2,4 @@
|
|
|
2
2
|
// literal-replaced so prod bundles tree-shake the dev branch to zero bytes.
|
|
3
3
|
// Typed through a narrowing interface so downstream packages don't need
|
|
4
4
|
// `vite/client` in their tsconfigs to type-check this file transitively.
|
|
5
|
-
|
|
6
|
-
readonly env?: { readonly DEV?: boolean }
|
|
7
|
-
}
|
|
8
|
-
export const IS_DEVELOPMENT: boolean = (import.meta as ViteMeta).env?.DEV === true
|
|
5
|
+
export const IS_DEVELOPMENT: boolean = process.env.NODE_ENV !== 'production'
|
package/lib/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index2.d.ts","names":[],"sources":["../../src/types.ts","../../src/Element/types.ts","../../src/Element/component.tsx","../../src/helpers/Iterator/types.ts","../../src/helpers/Iterator/component.tsx","../../src/List/component.tsx","../../src/Overlay/context.tsx","../../src/Overlay/positioning.ts","../../src/Overlay/useOverlay.tsx","../../src/Overlay/component.tsx","../../src/Portal/component.tsx","../../src/Text/component.tsx","../../src/Util/component.tsx"],"mappings":"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"}
|