@pyreon/elements 0.24.4 → 0.24.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/package.json +10 -12
- package/src/Element/component.tsx +0 -315
- package/src/Element/constants.ts +0 -96
- package/src/Element/index.ts +0 -6
- package/src/Element/types.ts +0 -168
- package/src/Element/utils.ts +0 -15
- package/src/List/component.tsx +0 -105
- package/src/List/index.ts +0 -5
- package/src/Overlay/component.tsx +0 -140
- package/src/Overlay/context.tsx +0 -36
- package/src/Overlay/index.ts +0 -7
- package/src/Overlay/positioning.ts +0 -191
- package/src/Overlay/useOverlay.tsx +0 -461
- package/src/Portal/component.tsx +0 -54
- package/src/Portal/index.ts +0 -5
- package/src/Text/component.tsx +0 -67
- package/src/Text/index.ts +0 -5
- package/src/Text/styled.ts +0 -30
- package/src/Util/component.tsx +0 -43
- package/src/Util/index.ts +0 -5
- package/src/__tests__/Content.test.tsx +0 -123
- package/src/__tests__/Element-slot-reactivity.browser.test.tsx +0 -152
- package/src/__tests__/Element.test.ts +0 -819
- package/src/__tests__/Iterator.test.ts +0 -492
- package/src/__tests__/Iterator.types.test.ts +0 -237
- package/src/__tests__/List.test.ts +0 -199
- package/src/__tests__/Overlay.test.ts +0 -492
- package/src/__tests__/Portal.test.ts +0 -156
- package/src/__tests__/Text.test.ts +0 -274
- package/src/__tests__/Util.test.ts +0 -63
- package/src/__tests__/Wrapper-innerhtml.test.tsx +0 -178
- package/src/__tests__/Wrapper.test.tsx +0 -196
- package/src/__tests__/elements.browser.test.tsx +0 -132
- package/src/__tests__/equalBeforeAfter.test.ts +0 -122
- package/src/__tests__/helpers.test.ts +0 -65
- package/src/__tests__/integration.test.tsx +0 -118
- package/src/__tests__/internElementBundle.test.ts +0 -102
- package/src/__tests__/iterator-function-children.test.tsx +0 -120
- package/src/__tests__/native-markers.test.ts +0 -13
- package/src/__tests__/overlayContext.test.tsx +0 -78
- package/src/__tests__/perf-stress.browser.test.tsx +0 -119
- package/src/__tests__/positioning.test.ts +0 -90
- package/src/__tests__/responsiveProps.test.ts +0 -328
- package/src/__tests__/slot-component-reference.test.tsx +0 -157
- package/src/__tests__/useOverlay.test.ts +0 -1336
- package/src/__tests__/utils.test.ts +0 -69
- package/src/__tests__/wrapper-block-cascade.test.ts +0 -121
- package/src/constants.ts +0 -1
- package/src/env.d.ts +0 -6
- package/src/helpers/Content/component.tsx +0 -75
- package/src/helpers/Content/index.ts +0 -3
- package/src/helpers/Content/styled.ts +0 -105
- package/src/helpers/Content/types.ts +0 -49
- package/src/helpers/Iterator/component.tsx +0 -316
- package/src/helpers/Iterator/index.ts +0 -30
- package/src/helpers/Iterator/types.ts +0 -138
- package/src/helpers/Wrapper/component.tsx +0 -180
- package/src/helpers/Wrapper/constants.ts +0 -10
- package/src/helpers/Wrapper/index.ts +0 -3
- package/src/helpers/Wrapper/styled.ts +0 -64
- package/src/helpers/Wrapper/types.ts +0 -56
- package/src/helpers/Wrapper/utils.ts +0 -7
- package/src/helpers/index.ts +0 -4
- package/src/helpers/internElementBundle.ts +0 -37
- package/src/helpers/isPyreonComponent.ts +0 -46
- package/src/index.ts +0 -42
- package/src/manifest.ts +0 -190
- package/src/tests/manifest-snapshot.test.ts +0 -45
- package/src/types.ts +0 -112
- package/src/utils.ts +0 -5
|
@@ -1,237 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Compile-time type tests for Iterator + List overloads.
|
|
3
|
-
*
|
|
4
|
-
* The public callable interface ships FOUR overloads in priority order:
|
|
5
|
-
*
|
|
6
|
-
* 1. SimpleProps<T extends SimpleValue> — `valueName` allowed, no `children`
|
|
7
|
-
* 2. ObjectProps<T extends ObjectValue> — `valueName` FORBIDDEN, no `children`
|
|
8
|
-
* 3. ChildrenProps — `children` required, no `data`/`component`
|
|
9
|
-
* 4. LooseProps — fallback for forwarding patterns
|
|
10
|
-
*
|
|
11
|
-
* The first three drive per-mode T inference and stricter constraints for
|
|
12
|
-
* direct callers. The 4th (LooseProps — added in PR #229's mirror) exists
|
|
13
|
-
* so that wide-union props produced by `@pyreon/rocketstyle`'s 4-overload-
|
|
14
|
-
* aware `ExtractProps` (PR #222 mirror) have a binding home. Pre-fallback
|
|
15
|
-
* the wide union failed to bind to any narrow overload and TS reported
|
|
16
|
-
* "no overload matches this call" at every forwarding site.
|
|
17
|
-
*
|
|
18
|
-
* Trade-off: adding the loose fallback intentionally weakens the strict
|
|
19
|
-
* per-mode constraints for DIRECT callers too — a call that doesn't match
|
|
20
|
-
* Simple / Object / Children will now match LooseProps and compile. This
|
|
21
|
-
* matches vitus-labs's design choice (PR #229): forwarding-pattern support
|
|
22
|
-
* is more valuable than mixed-shape rejection at the type level. Runtime
|
|
23
|
-
* still picks the right mode based on the data shape.
|
|
24
|
-
*
|
|
25
|
-
* Regression: pre-PR-5 (4-overload `ExtractProps`), Pyreon's Iterator type
|
|
26
|
-
* collapsed all three narrow modes when wrapped through `rocketstyle()` /
|
|
27
|
-
* `attrs()` — only the LAST overload's props survived. PR #5 + PR #7
|
|
28
|
-
* together restore the full union AND give it a binding home.
|
|
29
|
-
*/
|
|
30
|
-
|
|
31
|
-
import { describe, expectTypeOf, it } from 'vitest'
|
|
32
|
-
import { h } from '@pyreon/core'
|
|
33
|
-
import Iterator from '../helpers/Iterator/component'
|
|
34
|
-
import List from '../List/component'
|
|
35
|
-
import type {
|
|
36
|
-
ChildrenProps,
|
|
37
|
-
LooseProps,
|
|
38
|
-
ObjectProps,
|
|
39
|
-
Props,
|
|
40
|
-
SimpleProps,
|
|
41
|
-
} from '../helpers/Iterator/types'
|
|
42
|
-
|
|
43
|
-
describe('Iterator — Props<T> generic dispatch', () => {
|
|
44
|
-
it('Props<string> narrows to SimpleProps<string>', () => {
|
|
45
|
-
expectTypeOf<Props<string>>().toEqualTypeOf<SimpleProps<string>>()
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
it('Props<{ id: number; name: string }> narrows to ObjectProps<...>', () => {
|
|
49
|
-
type User = { id: number; name: string }
|
|
50
|
-
expectTypeOf<Props<User>>().toEqualTypeOf<ObjectProps<User>>()
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
it('Props<unknown> (default) falls back to loose props', () => {
|
|
54
|
-
// The default Props (no T) MUST accept the legacy untyped call surface.
|
|
55
|
-
// Smoke check: `data: any[]` shape continues to typecheck without
|
|
56
|
-
// narrowing.
|
|
57
|
-
type Default = Props
|
|
58
|
-
const _ok: Default = { data: ['a', 1, null], component: 'div' }
|
|
59
|
-
void _ok
|
|
60
|
-
})
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
describe('Iterator — happy-path overload selection', () => {
|
|
64
|
-
const Item = (p: { children?: unknown }) => h('span', null, p.children as never)
|
|
65
|
-
|
|
66
|
-
it('SimpleProps mode: valueName allowed', () => {
|
|
67
|
-
// Direct call with primitive data + valueName → SimpleProps overload
|
|
68
|
-
Iterator({
|
|
69
|
-
data: ['a', 'b'] as string[],
|
|
70
|
-
component: Item,
|
|
71
|
-
valueName: 'text',
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
// Mixed shape (children + data) now falls through to LooseProps — by
|
|
75
|
-
// design after PR #229's mirror. Strict per-mode rejection is no longer
|
|
76
|
-
// enforced at the type level; runtime picks the right path based on
|
|
77
|
-
// which props are present. This compiles and that's intentional.
|
|
78
|
-
Iterator({
|
|
79
|
-
data: ['a', 'b'] as string[],
|
|
80
|
-
component: Item,
|
|
81
|
-
children: h('span', null, 'leaked'),
|
|
82
|
-
})
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
it('ObjectProps mode: valueName FORBIDDEN by Object overload but accepted by Loose', () => {
|
|
86
|
-
type Row = { id: number; label: string }
|
|
87
|
-
Iterator({
|
|
88
|
-
data: [{ id: 1, label: 'a' }] as Row[],
|
|
89
|
-
component: Item,
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
// `valueName: 'row'` doesn't match ObjectProps' `valueName?: never`, but
|
|
93
|
-
// the LooseProps fallback accepts it. Pre-PR-7 this errored; now it's a
|
|
94
|
-
// legal forwarding shape.
|
|
95
|
-
Iterator({
|
|
96
|
-
data: [{ id: 1, label: 'a' }] as Row[],
|
|
97
|
-
component: Item,
|
|
98
|
-
valueName: 'row',
|
|
99
|
-
})
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
it('ChildrenProps mode: clean form picked when only children supplied', () => {
|
|
103
|
-
Iterator({ children: h('span', null, 'hi') })
|
|
104
|
-
|
|
105
|
-
// Mixing children with data / component used to be a hard error.
|
|
106
|
-
// Post-PR-7 the LooseProps fallback accepts these — runtime decides
|
|
107
|
-
// which mode fires based on which fields are populated.
|
|
108
|
-
Iterator({
|
|
109
|
-
children: h('span', null, 'hi'),
|
|
110
|
-
data: [1, 2, 3],
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
Iterator({
|
|
114
|
-
children: h('span', null, 'hi'),
|
|
115
|
-
component: Item,
|
|
116
|
-
})
|
|
117
|
-
})
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
describe('Iterator + List — LooseProps fallback for forwarding patterns (PR #7)', () => {
|
|
121
|
-
const Item = (p: { children?: unknown }) => h('span', null, p.children as never)
|
|
122
|
-
|
|
123
|
-
it('LooseProps shape binds via the 4th overload (no overload-mismatch error)', () => {
|
|
124
|
-
// The motivating shape: a wide-union props object produced by
|
|
125
|
-
// `Partial<(typeof Wrapper)['$$types']>` (rocketstyle's $$types after
|
|
126
|
-
// PR #5's 4-overload ExtractProps distributes the union). Without the
|
|
127
|
-
// loose fallback overload, this fails at every forwarding call site
|
|
128
|
-
// with "no overload matches this call" — the wide union doesn't bind
|
|
129
|
-
// to SimpleProps<T> / ObjectProps<T> / ChildrenProps individually.
|
|
130
|
-
const looseForwarded: LooseProps = {
|
|
131
|
-
data: ['a', 'b'],
|
|
132
|
-
component: Item,
|
|
133
|
-
valueName: 'text',
|
|
134
|
-
}
|
|
135
|
-
Iterator(looseForwarded)
|
|
136
|
-
// Cast preserves the LooseProps binding (the conditional Props<T>
|
|
137
|
-
// exposes LooseProps when T defaults to unknown).
|
|
138
|
-
Iterator(looseForwarded as Props)
|
|
139
|
-
})
|
|
140
|
-
|
|
141
|
-
it('partial / empty shapes are accepted via LooseProps', () => {
|
|
142
|
-
// Empty object — no narrow overload matches (data missing for Simple/
|
|
143
|
-
// Object, children missing for Children) but LooseProps' fields are
|
|
144
|
-
// all optional. This is the genuine forwarding shape from props spread.
|
|
145
|
-
const empty: LooseProps = {}
|
|
146
|
-
Iterator(empty)
|
|
147
|
-
|
|
148
|
-
// Object with just `data` (no component) — falls through to LooseProps.
|
|
149
|
-
Iterator({ data: ['a'] as string[] } as LooseProps)
|
|
150
|
-
})
|
|
151
|
-
|
|
152
|
-
it('List inherits the LooseProps fallback overload', () => {
|
|
153
|
-
const looseForwarded: LooseProps = {
|
|
154
|
-
data: [{ id: 1, name: 'A' }],
|
|
155
|
-
component: Item,
|
|
156
|
-
}
|
|
157
|
-
// List's 4th overload mirrors Iterator's — wide unions bind here too.
|
|
158
|
-
List({ ...looseForwarded, rootElement: true })
|
|
159
|
-
})
|
|
160
|
-
|
|
161
|
-
it('the loose fallback is the 4th overload (order matters for inference)', () => {
|
|
162
|
-
// Direct callers that DO match SimpleProps shape should still drive
|
|
163
|
-
// T inference from `data` — i.e. the overload picked at the call site
|
|
164
|
-
// is the FIRST one matching, not LooseProps. This is what preserves
|
|
165
|
-
// the strict per-mode constraints for the direct-caller happy path.
|
|
166
|
-
//
|
|
167
|
-
// We can't introspect "which overload TS picked" directly, but we CAN
|
|
168
|
-
// prove SimpleProps<T>'s `valueName?: string` survives — a LooseProps
|
|
169
|
-
// pick would lose the per-mode field constraints. The fact that the
|
|
170
|
-
// existing `expectTypeOf<Props<string>>().toEqualTypeOf<SimpleProps<string>>()`
|
|
171
|
-
// in the first describe block passes is the structural anchor.
|
|
172
|
-
type Props_string = Props<string>
|
|
173
|
-
expectTypeOf<Props_string>().toEqualTypeOf<SimpleProps<string>>()
|
|
174
|
-
// Negative: when T is unparameterized, Props falls back to LooseProps
|
|
175
|
-
// by design (the `unknown extends T` clause in Props<T>'s definition).
|
|
176
|
-
expectTypeOf<Props>().toEqualTypeOf<LooseProps>()
|
|
177
|
-
})
|
|
178
|
-
})
|
|
179
|
-
|
|
180
|
-
describe('List — generic flow + Element prop forwarding', () => {
|
|
181
|
-
const Card = (p: { children?: unknown }) => h('div', null, p.children as never)
|
|
182
|
-
|
|
183
|
-
it('inherits Iterator overload constraints', () => {
|
|
184
|
-
type User = { id: number; name: string }
|
|
185
|
-
List({
|
|
186
|
-
data: [{ id: 1, name: 'Alice' }] as User[],
|
|
187
|
-
component: Card,
|
|
188
|
-
rootElement: true,
|
|
189
|
-
})
|
|
190
|
-
|
|
191
|
-
// ObjectProps mode forbids `valueName`, but the LooseProps fallback
|
|
192
|
-
// accepts it — same trade-off as Iterator (see top-of-file comment).
|
|
193
|
-
List({
|
|
194
|
-
data: [{ id: 1, name: 'Alice' }] as User[],
|
|
195
|
-
component: Card,
|
|
196
|
-
valueName: 'user',
|
|
197
|
-
})
|
|
198
|
-
})
|
|
199
|
-
|
|
200
|
-
it('forwards Element layout props (tag, direction, alignX, …)', () => {
|
|
201
|
-
List({
|
|
202
|
-
data: ['a', 'b'] as string[],
|
|
203
|
-
component: Card,
|
|
204
|
-
valueName: 'text',
|
|
205
|
-
rootElement: true,
|
|
206
|
-
tag: 'ul',
|
|
207
|
-
direction: 'rows',
|
|
208
|
-
alignX: 'center',
|
|
209
|
-
})
|
|
210
|
-
})
|
|
211
|
-
|
|
212
|
-
it('rejects Element label/content (List-specific blacklist)', () => {
|
|
213
|
-
List({
|
|
214
|
-
children: h('span', null, 'hi'),
|
|
215
|
-
// @ts-expect-error — List forbids `label` (ListOnly: label?: never)
|
|
216
|
-
label: 'oops',
|
|
217
|
-
})
|
|
218
|
-
|
|
219
|
-
List({
|
|
220
|
-
children: h('span', null, 'hi'),
|
|
221
|
-
// @ts-expect-error — List forbids `content` (ListOnly: content?: never)
|
|
222
|
-
content: 'oops',
|
|
223
|
-
})
|
|
224
|
-
})
|
|
225
|
-
})
|
|
226
|
-
|
|
227
|
-
describe('Children-vs-data type discrimination', () => {
|
|
228
|
-
it('ChildrenProps and SimpleProps are mutually exclusive', () => {
|
|
229
|
-
// The strict overloads pick exactly one mode. ChildrenProps' `data: never`
|
|
230
|
-
// and SimpleProps' `children: never` ensure they can't be unified into
|
|
231
|
-
// one shape — verified at the type level here.
|
|
232
|
-
type C = ChildrenProps
|
|
233
|
-
type S = SimpleProps<string>
|
|
234
|
-
expectTypeOf<C['data']>().toEqualTypeOf<undefined>()
|
|
235
|
-
expectTypeOf<S['children']>().toEqualTypeOf<undefined>()
|
|
236
|
-
})
|
|
237
|
-
})
|
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
import type { ComponentFn, VNode } from '@pyreon/core'
|
|
2
|
-
import { h } from '@pyreon/core'
|
|
3
|
-
import { describe, expect, it } from 'vitest'
|
|
4
|
-
import { Element } from '../Element'
|
|
5
|
-
import Iterator from '../helpers/Iterator'
|
|
6
|
-
import { List } from '../List'
|
|
7
|
-
|
|
8
|
-
const asVNode = (v: unknown) => v as VNode
|
|
9
|
-
|
|
10
|
-
describe('List', () => {
|
|
11
|
-
describe('statics', () => {
|
|
12
|
-
it('has correct displayName', () => {
|
|
13
|
-
expect(List.displayName).toBe('@pyreon/elements/List')
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
it('has correct pkgName', () => {
|
|
17
|
-
expect(List.pkgName).toBe('@pyreon/elements')
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
it('has correct PYREON__COMPONENT', () => {
|
|
21
|
-
expect(List.PYREON__COMPONENT).toBe('@pyreon/elements/List')
|
|
22
|
-
})
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
describe('rootElement = false (default)', () => {
|
|
26
|
-
it('returns a VNode whose type is Iterator', () => {
|
|
27
|
-
const Comp: ComponentFn = (props: any) => h('span', null, props.children)
|
|
28
|
-
const result = asVNode(
|
|
29
|
-
List({
|
|
30
|
-
data: ['a', 'b'],
|
|
31
|
-
component: Comp,
|
|
32
|
-
}),
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
expect(result.type).toBe(Iterator)
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
it('passes iterator-related props to the Iterator VNode', () => {
|
|
39
|
-
const Comp: ComponentFn = (props: any) => h('span', null, props.children)
|
|
40
|
-
const data = ['a', 'b', 'c']
|
|
41
|
-
const itemKeyFn = (_item: unknown, i: number) => i
|
|
42
|
-
const itemPropsFn = () => ({})
|
|
43
|
-
const WrapComp: ComponentFn = (props: any) => h('div', null, ...props.children)
|
|
44
|
-
|
|
45
|
-
const result = asVNode(
|
|
46
|
-
List({
|
|
47
|
-
data,
|
|
48
|
-
component: Comp,
|
|
49
|
-
itemKey: itemKeyFn,
|
|
50
|
-
itemProps: itemPropsFn,
|
|
51
|
-
valueName: 'label',
|
|
52
|
-
wrapComponent: WrapComp,
|
|
53
|
-
wrapProps: { className: 'wrap' },
|
|
54
|
-
}),
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
expect(result.type).toBe(Iterator)
|
|
58
|
-
expect(result.props.data).toBe(data)
|
|
59
|
-
expect(result.props.component).toBe(Comp)
|
|
60
|
-
expect(result.props.itemKey).toBe(itemKeyFn)
|
|
61
|
-
expect(result.props.itemProps).toBe(itemPropsFn)
|
|
62
|
-
expect(result.props.valueName).toBe('label')
|
|
63
|
-
expect(result.props.wrapComponent).toBe(WrapComp)
|
|
64
|
-
expect(result.props.wrapProps).toEqual({ className: 'wrap' })
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
it('does not pass non-iterator props to Iterator', () => {
|
|
68
|
-
const Comp: ComponentFn = (props: any) => h('span', null, props.children)
|
|
69
|
-
const result = asVNode(
|
|
70
|
-
List({
|
|
71
|
-
data: ['a'],
|
|
72
|
-
component: Comp,
|
|
73
|
-
block: true,
|
|
74
|
-
gap: 8,
|
|
75
|
-
direction: 'rows',
|
|
76
|
-
} as any),
|
|
77
|
-
)
|
|
78
|
-
|
|
79
|
-
expect(result.type).toBe(Iterator)
|
|
80
|
-
expect(result.props.block).toBeUndefined()
|
|
81
|
-
expect(result.props.gap).toBeUndefined()
|
|
82
|
-
expect(result.props.direction).toBeUndefined()
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
it('forwards children prop to Iterator', () => {
|
|
86
|
-
const child = h('span', null, 'hello')
|
|
87
|
-
const result = asVNode(List({ children: child }))
|
|
88
|
-
|
|
89
|
-
expect(result.type).toBe(Iterator)
|
|
90
|
-
expect(result.props.children).toBe(child)
|
|
91
|
-
})
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
describe('rootElement = true', () => {
|
|
95
|
-
it('returns a VNode whose type is Element', () => {
|
|
96
|
-
const Comp: ComponentFn = (props: any) => h('span', null, props.children)
|
|
97
|
-
const result = asVNode(
|
|
98
|
-
List({
|
|
99
|
-
data: ['a'],
|
|
100
|
-
component: Comp,
|
|
101
|
-
rootElement: true,
|
|
102
|
-
}),
|
|
103
|
-
)
|
|
104
|
-
|
|
105
|
-
expect(result.type).toBe(Element)
|
|
106
|
-
})
|
|
107
|
-
|
|
108
|
-
it('passes layout props to the Element VNode', () => {
|
|
109
|
-
const Comp: ComponentFn = (props: any) => h('span', null, props.children)
|
|
110
|
-
const result = asVNode(
|
|
111
|
-
List({
|
|
112
|
-
data: ['a'],
|
|
113
|
-
component: Comp,
|
|
114
|
-
rootElement: true,
|
|
115
|
-
block: true,
|
|
116
|
-
gap: 8,
|
|
117
|
-
direction: 'rows',
|
|
118
|
-
} as any),
|
|
119
|
-
)
|
|
120
|
-
|
|
121
|
-
expect(result.type).toBe(Element)
|
|
122
|
-
expect(result.props.block).toBe(true)
|
|
123
|
-
expect(result.props.gap).toBe(8)
|
|
124
|
-
expect(result.props.direction).toBe('rows')
|
|
125
|
-
})
|
|
126
|
-
|
|
127
|
-
it('does not pass iterator-reserved props to Element', () => {
|
|
128
|
-
const Comp: ComponentFn = (props: any) => h('span', null, props.children)
|
|
129
|
-
const result = asVNode(
|
|
130
|
-
List({
|
|
131
|
-
data: ['x'],
|
|
132
|
-
component: Comp,
|
|
133
|
-
rootElement: true,
|
|
134
|
-
valueName: 'label',
|
|
135
|
-
}),
|
|
136
|
-
)
|
|
137
|
-
|
|
138
|
-
expect(result.type).toBe(Element)
|
|
139
|
-
// Iterator-reserved props should not leak to Element
|
|
140
|
-
expect(result.props.data).toBeUndefined()
|
|
141
|
-
expect(result.props.component).toBeUndefined()
|
|
142
|
-
expect(result.props.valueName).toBeUndefined()
|
|
143
|
-
})
|
|
144
|
-
|
|
145
|
-
it('nests an Iterator VNode as children of Element', () => {
|
|
146
|
-
const Comp: ComponentFn = (props: any) => h('span', null, props.children)
|
|
147
|
-
const data = ['a', 'b']
|
|
148
|
-
const result = asVNode(
|
|
149
|
-
List({
|
|
150
|
-
data,
|
|
151
|
-
component: Comp,
|
|
152
|
-
rootElement: true,
|
|
153
|
-
}),
|
|
154
|
-
)
|
|
155
|
-
|
|
156
|
-
expect(result.type).toBe(Element)
|
|
157
|
-
|
|
158
|
-
// The children of Element should contain the Iterator VNode
|
|
159
|
-
const children = result.props.children as unknown
|
|
160
|
-
const iteratorNode = asVNode(Array.isArray(children) ? children[0] : children)
|
|
161
|
-
expect(iteratorNode.type).toBe(Iterator)
|
|
162
|
-
expect(iteratorNode.props.data).toBe(data)
|
|
163
|
-
expect(iteratorNode.props.component).toBe(Comp)
|
|
164
|
-
})
|
|
165
|
-
|
|
166
|
-
it('forwards ref to Element', () => {
|
|
167
|
-
const Comp: ComponentFn = (props: any) => h('span', null, props.children)
|
|
168
|
-
const refFn = (_node: unknown) => {
|
|
169
|
-
/* noop */
|
|
170
|
-
}
|
|
171
|
-
const result = asVNode(
|
|
172
|
-
List({
|
|
173
|
-
data: ['a'],
|
|
174
|
-
component: Comp,
|
|
175
|
-
rootElement: true,
|
|
176
|
-
ref: refFn,
|
|
177
|
-
} as any),
|
|
178
|
-
)
|
|
179
|
-
|
|
180
|
-
expect(result.type).toBe(Element)
|
|
181
|
-
expect(result.props.ref).toBe(refFn)
|
|
182
|
-
})
|
|
183
|
-
})
|
|
184
|
-
|
|
185
|
-
describe('Iterator.RESERVED_PROPS', () => {
|
|
186
|
-
it('contains the expected prop names', () => {
|
|
187
|
-
expect(Iterator.RESERVED_PROPS).toEqual([
|
|
188
|
-
'children',
|
|
189
|
-
'component',
|
|
190
|
-
'wrapComponent',
|
|
191
|
-
'data',
|
|
192
|
-
'itemKey',
|
|
193
|
-
'valueName',
|
|
194
|
-
'itemProps',
|
|
195
|
-
'wrapProps',
|
|
196
|
-
])
|
|
197
|
-
})
|
|
198
|
-
})
|
|
199
|
-
})
|