@pyreon/elements 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.
Files changed (53) hide show
  1. package/README.md +38 -35
  2. package/lib/index.d.ts +15 -15
  3. package/package.json +24 -24
  4. package/src/Element/component.tsx +14 -14
  5. package/src/Element/constants.ts +25 -25
  6. package/src/Element/index.ts +2 -2
  7. package/src/Element/types.ts +3 -3
  8. package/src/Element/utils.ts +1 -1
  9. package/src/List/component.tsx +7 -7
  10. package/src/List/index.ts +2 -2
  11. package/src/Overlay/component.tsx +22 -22
  12. package/src/Overlay/context.tsx +2 -2
  13. package/src/Overlay/index.ts +3 -3
  14. package/src/Overlay/useOverlay.tsx +97 -97
  15. package/src/Portal/component.tsx +6 -6
  16. package/src/Portal/index.ts +2 -2
  17. package/src/Text/component.tsx +6 -6
  18. package/src/Text/index.ts +2 -2
  19. package/src/Text/styled.ts +4 -4
  20. package/src/Util/component.tsx +5 -5
  21. package/src/Util/index.ts +2 -2
  22. package/src/__tests__/Content.test.tsx +46 -46
  23. package/src/__tests__/Element.test.ts +251 -251
  24. package/src/__tests__/Iterator.test.ts +142 -142
  25. package/src/__tests__/List.test.ts +61 -61
  26. package/src/__tests__/Overlay.test.ts +125 -125
  27. package/src/__tests__/Portal.test.ts +33 -33
  28. package/src/__tests__/Text.test.ts +128 -128
  29. package/src/__tests__/Util.test.ts +31 -31
  30. package/src/__tests__/Wrapper.test.tsx +60 -60
  31. package/src/__tests__/equalBeforeAfter.test.ts +41 -41
  32. package/src/__tests__/helpers.test.ts +29 -29
  33. package/src/__tests__/overlayContext.test.tsx +14 -14
  34. package/src/__tests__/responsiveProps.test.ts +116 -116
  35. package/src/__tests__/useOverlay.test.ts +283 -283
  36. package/src/__tests__/utils.test.ts +43 -43
  37. package/src/constants.ts +1 -1
  38. package/src/helpers/Content/component.tsx +5 -5
  39. package/src/helpers/Content/index.ts +1 -1
  40. package/src/helpers/Content/styled.ts +16 -16
  41. package/src/helpers/Content/types.ts +7 -7
  42. package/src/helpers/Iterator/component.tsx +28 -28
  43. package/src/helpers/Iterator/index.ts +2 -2
  44. package/src/helpers/Iterator/types.ts +3 -3
  45. package/src/helpers/Wrapper/component.tsx +6 -6
  46. package/src/helpers/Wrapper/index.ts +1 -1
  47. package/src/helpers/Wrapper/styled.ts +8 -8
  48. package/src/helpers/Wrapper/types.ts +3 -3
  49. package/src/helpers/Wrapper/utils.ts +1 -1
  50. package/src/helpers/index.ts +2 -2
  51. package/src/index.ts +16 -16
  52. package/src/types.ts +7 -7
  53. package/src/utils.ts +1 -1
@@ -1,9 +1,9 @@
1
- import type { VNode } from "@pyreon/core"
2
- import { h } from "@pyreon/core"
3
- import { describe, expect, it } from "vitest"
4
- import { Element } from "../Element"
5
- import Content from "../helpers/Content/component"
6
- import Wrapper from "../helpers/Wrapper/component"
1
+ import type { VNode } from '@pyreon/core'
2
+ import { h } from '@pyreon/core'
3
+ import { describe, expect, it } from 'vitest'
4
+ import { Element } from '../Element'
5
+ import Content from '../helpers/Content/component'
6
+ import Wrapper from '../helpers/Wrapper/component'
7
7
 
8
8
  const asVNode = (v: unknown) => v as VNode
9
9
 
@@ -16,142 +16,142 @@ const getContentSlots = (result: VNode): VNode[] => {
16
16
  if (!Array.isArray(children)) return []
17
17
  return children.filter(
18
18
  (c: unknown) =>
19
- c != null && typeof c === "object" && "type" in (c as VNode) && (c as VNode).type === Content,
19
+ c != null && typeof c === 'object' && 'type' in (c as VNode) && (c as VNode).type === Content,
20
20
  ) as VNode[]
21
21
  }
22
22
 
23
- describe("Element", () => {
24
- describe("basic rendering", () => {
25
- it("returns a VNode whose type is the Wrapper component (a function)", () => {
26
- const result = asVNode(Element({ children: "hello" }))
27
- expect(typeof result.type).toBe("function")
23
+ describe('Element', () => {
24
+ describe('basic rendering', () => {
25
+ it('returns a VNode whose type is the Wrapper component (a function)', () => {
26
+ const result = asVNode(Element({ children: 'hello' }))
27
+ expect(typeof result.type).toBe('function')
28
28
  expect(result.type).toBe(Wrapper)
29
29
  })
30
30
 
31
- it("passes tag as the tag prop to Wrapper", () => {
32
- const result = asVNode(Element({ tag: "section", children: "content" }))
33
- expect(result.props.tag).toBe("section")
31
+ it('passes tag as the tag prop to Wrapper', () => {
32
+ const result = asVNode(Element({ tag: 'section', children: 'content' }))
33
+ expect(result.props.tag).toBe('section')
34
34
  })
35
35
 
36
- it("defaults tag to undefined when not specified", () => {
37
- const result = asVNode(Element({ children: "hello" }))
36
+ it('defaults tag to undefined when not specified', () => {
37
+ const result = asVNode(Element({ children: 'hello' }))
38
38
  expect(result.props.tag).toBeUndefined()
39
39
  })
40
40
 
41
- it("renders with no children", () => {
41
+ it('renders with no children', () => {
42
42
  const result = asVNode(Element({}))
43
43
  expect(result.type).toBe(Wrapper)
44
44
  })
45
45
  })
46
46
 
47
- describe("simple element (no beforeContent/afterContent)", () => {
48
- it("uses contentDirection as wrapper direction (defaults to rows)", () => {
49
- const result = asVNode(Element({ children: "test" }))
50
- expect(result.props.direction).toBe("rows")
47
+ describe('simple element (no beforeContent/afterContent)', () => {
48
+ it('uses contentDirection as wrapper direction (defaults to rows)', () => {
49
+ const result = asVNode(Element({ children: 'test' }))
50
+ expect(result.props.direction).toBe('rows')
51
51
  })
52
52
 
53
- it("uses contentAlignX as wrapper alignX (defaults to left)", () => {
54
- const result = asVNode(Element({ children: "test" }))
55
- expect(result.props.alignX).toBe("left")
53
+ it('uses contentAlignX as wrapper alignX (defaults to left)', () => {
54
+ const result = asVNode(Element({ children: 'test' }))
55
+ expect(result.props.alignX).toBe('left')
56
56
  })
57
57
 
58
- it("uses contentAlignY as wrapper alignY (defaults to center)", () => {
59
- const result = asVNode(Element({ children: "test" }))
60
- expect(result.props.alignY).toBe("center")
58
+ it('uses contentAlignY as wrapper alignY (defaults to center)', () => {
59
+ const result = asVNode(Element({ children: 'test' }))
60
+ expect(result.props.alignY).toBe('center')
61
61
  })
62
62
 
63
- it("overrides direction with contentDirection when simple", () => {
64
- const result = asVNode(Element({ contentDirection: "inline", children: "test" }))
65
- expect(result.props.direction).toBe("inline")
63
+ it('overrides direction with contentDirection when simple', () => {
64
+ const result = asVNode(Element({ contentDirection: 'inline', children: 'test' }))
65
+ expect(result.props.direction).toBe('inline')
66
66
  })
67
67
 
68
- it("overrides alignX with contentAlignX when simple", () => {
69
- const result = asVNode(Element({ contentAlignX: "center", children: "test" }))
70
- expect(result.props.alignX).toBe("center")
68
+ it('overrides alignX with contentAlignX when simple', () => {
69
+ const result = asVNode(Element({ contentAlignX: 'center', children: 'test' }))
70
+ expect(result.props.alignX).toBe('center')
71
71
  })
72
72
 
73
- it("overrides alignY with contentAlignY when simple", () => {
74
- const result = asVNode(Element({ contentAlignY: "top", children: "test" }))
75
- expect(result.props.alignY).toBe("top")
73
+ it('overrides alignY with contentAlignY when simple', () => {
74
+ const result = asVNode(Element({ contentAlignY: 'top', children: 'test' }))
75
+ expect(result.props.alignY).toBe('top')
76
76
  })
77
77
 
78
- it("renders children directly via render() without Content wrappers", () => {
79
- const result = asVNode(Element({ children: h("span", null, "inner") }))
78
+ it('renders children directly via render() without Content wrappers', () => {
79
+ const result = asVNode(Element({ children: h('span', null, 'inner') }))
80
80
  const slots = getContentSlots(result)
81
81
  expect(slots).toHaveLength(0)
82
82
  })
83
83
 
84
- it("renders string children in props.children array", () => {
85
- const result = asVNode(Element({ children: "hello" }))
84
+ it('renders string children in props.children array', () => {
85
+ const result = asVNode(Element({ children: 'hello' }))
86
86
  const children = result.props.children as unknown[]
87
87
  // Simple element renders: [falsy beforeContent, render(CHILDREN), falsy afterContent]
88
88
  expect(children).toBeDefined()
89
89
  expect(Array.isArray(children)).toBe(true)
90
90
  })
91
91
 
92
- it("passes block prop to Wrapper", () => {
93
- const result = asVNode(Element({ block: true, children: "test" }))
92
+ it('passes block prop to Wrapper', () => {
93
+ const result = asVNode(Element({ block: true, children: 'test' }))
94
94
  expect(result.props.block).toBe(true)
95
95
  })
96
96
  })
97
97
 
98
- describe("three-section layout (with beforeContent/afterContent)", () => {
99
- it("defaults wrapper direction to inline", () => {
98
+ describe('three-section layout (with beforeContent/afterContent)', () => {
99
+ it('defaults wrapper direction to inline', () => {
100
100
  const result = asVNode(
101
101
  Element({
102
- beforeContent: h("span", null, "B"),
103
- children: "test",
104
- afterContent: h("span", null, "A"),
102
+ beforeContent: h('span', null, 'B'),
103
+ children: 'test',
104
+ afterContent: h('span', null, 'A'),
105
105
  }),
106
106
  )
107
- expect(result.props.direction).toBe("inline")
107
+ expect(result.props.direction).toBe('inline')
108
108
  })
109
109
 
110
- it("uses explicit direction when provided", () => {
110
+ it('uses explicit direction when provided', () => {
111
111
  const result = asVNode(
112
112
  Element({
113
- direction: "rows",
114
- beforeContent: h("span", null, "B"),
115
- children: "test",
116
- afterContent: h("span", null, "A"),
113
+ direction: 'rows',
114
+ beforeContent: h('span', null, 'B'),
115
+ children: 'test',
116
+ afterContent: h('span', null, 'A'),
117
117
  }),
118
118
  )
119
- expect(result.props.direction).toBe("rows")
119
+ expect(result.props.direction).toBe('rows')
120
120
  })
121
121
 
122
- it("uses default alignX (left) and alignY (center)", () => {
122
+ it('uses default alignX (left) and alignY (center)', () => {
123
123
  const result = asVNode(
124
124
  Element({
125
- beforeContent: "B",
126
- children: "test",
127
- afterContent: "A",
125
+ beforeContent: 'B',
126
+ children: 'test',
127
+ afterContent: 'A',
128
128
  }),
129
129
  )
130
- expect(result.props.alignX).toBe("left")
131
- expect(result.props.alignY).toBe("center")
130
+ expect(result.props.alignX).toBe('left')
131
+ expect(result.props.alignY).toBe('center')
132
132
  })
133
133
 
134
- it("uses explicit alignX and alignY", () => {
134
+ it('uses explicit alignX and alignY', () => {
135
135
  const result = asVNode(
136
136
  Element({
137
- alignX: "center",
138
- alignY: "top",
139
- beforeContent: "B",
140
- children: "test",
141
- afterContent: "A",
137
+ alignX: 'center',
138
+ alignY: 'top',
139
+ beforeContent: 'B',
140
+ children: 'test',
141
+ afterContent: 'A',
142
142
  }),
143
143
  )
144
- expect(result.props.alignX).toBe("center")
145
- expect(result.props.alignY).toBe("top")
144
+ expect(result.props.alignX).toBe('center')
145
+ expect(result.props.alignY).toBe('top')
146
146
  })
147
147
 
148
- it("renders three Content children when both before and after exist", () => {
149
- const before = h("span", null, "Before")
150
- const after = h("span", null, "After")
148
+ it('renders three Content children when both before and after exist', () => {
149
+ const before = h('span', null, 'Before')
150
+ const after = h('span', null, 'After')
151
151
  const result = asVNode(
152
152
  Element({
153
153
  beforeContent: before,
154
- children: "Main",
154
+ children: 'Main',
155
155
  afterContent: after,
156
156
  }),
157
157
  )
@@ -160,46 +160,46 @@ describe("Element", () => {
160
160
  expect(slots).toHaveLength(3)
161
161
  })
162
162
 
163
- it("sets correct contentType on each Content slot", () => {
164
- const before = h("span", null, "Before")
165
- const after = h("span", null, "After")
163
+ it('sets correct contentType on each Content slot', () => {
164
+ const before = h('span', null, 'Before')
165
+ const after = h('span', null, 'After')
166
166
  const result = asVNode(
167
167
  Element({
168
168
  beforeContent: before,
169
- children: "Main",
169
+ children: 'Main',
170
170
  afterContent: after,
171
171
  }),
172
172
  )
173
173
 
174
174
  const slots = getContentSlots(result)
175
175
  const [slot0, slot1, slot2] = slots as [VNode, VNode, VNode]
176
- expect(slot0.props.contentType).toBe("before")
177
- expect(slot1.props.contentType).toBe("content")
178
- expect(slot2.props.contentType).toBe("after")
176
+ expect(slot0.props.contentType).toBe('before')
177
+ expect(slot1.props.contentType).toBe('content')
178
+ expect(slot2.props.contentType).toBe('after')
179
179
  })
180
180
 
181
- it("passes parentDirection to Content slots", () => {
181
+ it('passes parentDirection to Content slots', () => {
182
182
  const result = asVNode(
183
183
  Element({
184
- direction: "rows",
185
- beforeContent: "B",
186
- children: "M",
187
- afterContent: "A",
184
+ direction: 'rows',
185
+ beforeContent: 'B',
186
+ children: 'M',
187
+ afterContent: 'A',
188
188
  }),
189
189
  )
190
190
 
191
191
  const slots = getContentSlots(result)
192
192
  for (const slot of slots) {
193
- expect(slot.props.parentDirection).toBe("rows")
193
+ expect(slot.props.parentDirection).toBe('rows')
194
194
  }
195
195
  })
196
196
 
197
- it("renders before and content Content slots when no afterContent", () => {
198
- const before = h("span", null, "Before")
197
+ it('renders before and content Content slots when no afterContent', () => {
198
+ const before = h('span', null, 'Before')
199
199
  const result = asVNode(
200
200
  Element({
201
201
  beforeContent: before,
202
- children: "Main",
202
+ children: 'Main',
203
203
  }),
204
204
  )
205
205
 
@@ -207,15 +207,15 @@ describe("Element", () => {
207
207
  // beforeContent makes isSimpleElement false, so content also gets a Content wrapper
208
208
  expect(slots).toHaveLength(2)
209
209
  const [s0, s1] = slots as [VNode, VNode]
210
- expect(s0.props.contentType).toBe("before")
211
- expect(s1.props.contentType).toBe("content")
210
+ expect(s0.props.contentType).toBe('before')
211
+ expect(s1.props.contentType).toBe('content')
212
212
  })
213
213
 
214
- it("renders content and after Content slots when no beforeContent", () => {
215
- const after = h("span", null, "After")
214
+ it('renders content and after Content slots when no beforeContent', () => {
215
+ const after = h('span', null, 'After')
216
216
  const result = asVNode(
217
217
  Element({
218
- children: "Main",
218
+ children: 'Main',
219
219
  afterContent: after,
220
220
  }),
221
221
  )
@@ -224,33 +224,33 @@ describe("Element", () => {
224
224
  // content slot + after slot (both are Content wrappers since afterContent makes it non-simple)
225
225
  expect(slots).toHaveLength(2)
226
226
  const [c0, c1] = slots as [VNode, VNode]
227
- expect(c0.props.contentType).toBe("content")
228
- expect(c1.props.contentType).toBe("after")
227
+ expect(c0.props.contentType).toBe('content')
228
+ expect(c1.props.contentType).toBe('after')
229
229
  })
230
230
 
231
- it("uses span sub-tag for inline parent elements (like span)", () => {
231
+ it('uses span sub-tag for inline parent elements (like span)', () => {
232
232
  const result = asVNode(
233
233
  Element({
234
- tag: "span",
235
- beforeContent: "B",
236
- children: "M",
237
- afterContent: "A",
234
+ tag: 'span',
235
+ beforeContent: 'B',
236
+ children: 'M',
237
+ afterContent: 'A',
238
238
  }),
239
239
  )
240
240
 
241
241
  const slots = getContentSlots(result)
242
242
  for (const slot of slots) {
243
- expect(slot.props.tag).toBe("span")
243
+ expect(slot.props.tag).toBe('span')
244
244
  }
245
245
  })
246
246
 
247
- it("uses undefined sub-tag for block parent elements (like div)", () => {
247
+ it('uses undefined sub-tag for block parent elements (like div)', () => {
248
248
  const result = asVNode(
249
249
  Element({
250
- tag: "div",
251
- beforeContent: "B",
252
- children: "M",
253
- afterContent: "A",
250
+ tag: 'div',
251
+ beforeContent: 'B',
252
+ children: 'M',
253
+ afterContent: 'A',
254
254
  }),
255
255
  )
256
256
 
@@ -260,13 +260,13 @@ describe("Element", () => {
260
260
  }
261
261
  })
262
262
 
263
- it("passes equalCols to Content slots", () => {
263
+ it('passes equalCols to Content slots', () => {
264
264
  const result = asVNode(
265
265
  Element({
266
266
  equalCols: true,
267
- beforeContent: "B",
268
- children: "M",
269
- afterContent: "A",
267
+ beforeContent: 'B',
268
+ children: 'M',
269
+ afterContent: 'A',
270
270
  }),
271
271
  )
272
272
 
@@ -276,155 +276,155 @@ describe("Element", () => {
276
276
  }
277
277
  })
278
278
 
279
- it("passes gap to before and after Content slots but not content slot", () => {
279
+ it('passes gap to before and after Content slots but not content slot', () => {
280
280
  const result = asVNode(
281
281
  Element({
282
282
  gap: 16,
283
- beforeContent: "B",
284
- children: "M",
285
- afterContent: "A",
283
+ beforeContent: 'B',
284
+ children: 'M',
285
+ afterContent: 'A',
286
286
  }),
287
287
  )
288
288
 
289
289
  const slots = getContentSlots(result)
290
- const beforeSlot = slots.find((v) => v.props.contentType === "before")
291
- const contentSlot = slots.find((v) => v.props.contentType === "content")
292
- const afterSlot = slots.find((v) => v.props.contentType === "after")
290
+ const beforeSlot = slots.find((v) => v.props.contentType === 'before')
291
+ const contentSlot = slots.find((v) => v.props.contentType === 'content')
292
+ const afterSlot = slots.find((v) => v.props.contentType === 'after')
293
293
 
294
294
  expect(beforeSlot?.props.gap).toBe(16)
295
295
  expect(contentSlot?.props.gap).toBeUndefined()
296
296
  expect(afterSlot?.props.gap).toBe(16)
297
297
  })
298
298
 
299
- it("passes content-level alignment to the content Content slot", () => {
299
+ it('passes content-level alignment to the content Content slot', () => {
300
300
  const result = asVNode(
301
301
  Element({
302
- contentDirection: "inline",
303
- contentAlignX: "center",
304
- contentAlignY: "top",
305
- beforeContent: "B",
306
- children: "M",
307
- afterContent: "A",
302
+ contentDirection: 'inline',
303
+ contentAlignX: 'center',
304
+ contentAlignY: 'top',
305
+ beforeContent: 'B',
306
+ children: 'M',
307
+ afterContent: 'A',
308
308
  }),
309
309
  )
310
310
 
311
311
  const slots = getContentSlots(result)
312
- const contentSlot = slots.find((v) => v.props.contentType === "content")
313
- expect(contentSlot?.props.direction).toBe("inline")
314
- expect(contentSlot?.props.alignX).toBe("center")
315
- expect(contentSlot?.props.alignY).toBe("top")
312
+ const contentSlot = slots.find((v) => v.props.contentType === 'content')
313
+ expect(contentSlot?.props.direction).toBe('inline')
314
+ expect(contentSlot?.props.alignX).toBe('center')
315
+ expect(contentSlot?.props.alignY).toBe('top')
316
316
  })
317
317
 
318
- it("passes before-level alignment to the before Content slot", () => {
318
+ it('passes before-level alignment to the before Content slot', () => {
319
319
  const result = asVNode(
320
320
  Element({
321
- beforeContentDirection: "rows",
322
- beforeContentAlignX: "right",
323
- beforeContentAlignY: "bottom",
324
- beforeContent: "B",
325
- children: "M",
326
- afterContent: "A",
321
+ beforeContentDirection: 'rows',
322
+ beforeContentAlignX: 'right',
323
+ beforeContentAlignY: 'bottom',
324
+ beforeContent: 'B',
325
+ children: 'M',
326
+ afterContent: 'A',
327
327
  }),
328
328
  )
329
329
 
330
330
  const slots = getContentSlots(result)
331
- const beforeSlot = slots.find((v) => v.props.contentType === "before")
332
- expect(beforeSlot?.props.direction).toBe("rows")
333
- expect(beforeSlot?.props.alignX).toBe("right")
334
- expect(beforeSlot?.props.alignY).toBe("bottom")
331
+ const beforeSlot = slots.find((v) => v.props.contentType === 'before')
332
+ expect(beforeSlot?.props.direction).toBe('rows')
333
+ expect(beforeSlot?.props.alignX).toBe('right')
334
+ expect(beforeSlot?.props.alignY).toBe('bottom')
335
335
  })
336
336
 
337
- it("passes after-level alignment to the after Content slot", () => {
337
+ it('passes after-level alignment to the after Content slot', () => {
338
338
  const result = asVNode(
339
339
  Element({
340
- afterContentDirection: "rows",
341
- afterContentAlignX: "center",
342
- afterContentAlignY: "top",
343
- beforeContent: "B",
344
- children: "M",
345
- afterContent: "A",
340
+ afterContentDirection: 'rows',
341
+ afterContentAlignX: 'center',
342
+ afterContentAlignY: 'top',
343
+ beforeContent: 'B',
344
+ children: 'M',
345
+ afterContent: 'A',
346
346
  }),
347
347
  )
348
348
 
349
349
  const slots = getContentSlots(result)
350
- const afterSlot = slots.find((v) => v.props.contentType === "after")
351
- expect(afterSlot?.props.direction).toBe("rows")
352
- expect(afterSlot?.props.alignX).toBe("center")
353
- expect(afterSlot?.props.alignY).toBe("top")
350
+ const afterSlot = slots.find((v) => v.props.contentType === 'after')
351
+ expect(afterSlot?.props.direction).toBe('rows')
352
+ expect(afterSlot?.props.alignX).toBe('center')
353
+ expect(afterSlot?.props.alignY).toBe('top')
354
354
  })
355
355
  })
356
356
 
357
- describe("HTML attribute filtering", () => {
358
- it("passes through id", () => {
359
- const result = asVNode(Element({ id: "my-el", children: "test" }))
360
- expect(result.props.id).toBe("my-el")
357
+ describe('HTML attribute filtering', () => {
358
+ it('passes through id', () => {
359
+ const result = asVNode(Element({ id: 'my-el', children: 'test' }))
360
+ expect(result.props.id).toBe('my-el')
361
361
  })
362
362
 
363
- it("passes through role", () => {
364
- const result = asVNode(Element({ role: "button", children: "test" }))
365
- expect(result.props.role).toBe("button")
363
+ it('passes through role', () => {
364
+ const result = asVNode(Element({ role: 'button', children: 'test' }))
365
+ expect(result.props.role).toBe('button')
366
366
  })
367
367
 
368
- it("passes through data- attributes", () => {
369
- const result = asVNode(Element({ "data-testid": "el", children: "test" }))
370
- expect(result.props["data-testid"]).toBe("el")
368
+ it('passes through data- attributes', () => {
369
+ const result = asVNode(Element({ 'data-testid': 'el', children: 'test' }))
370
+ expect(result.props['data-testid']).toBe('el')
371
371
  })
372
372
 
373
- it("passes through aria- attributes", () => {
374
- const result = asVNode(Element({ "aria-label": "label", children: "test" }))
375
- expect(result.props["aria-label"]).toBe("label")
373
+ it('passes through aria- attributes', () => {
374
+ const result = asVNode(Element({ 'aria-label': 'label', children: 'test' }))
375
+ expect(result.props['aria-label']).toBe('label')
376
376
  })
377
377
 
378
- it("passes through on-prefixed event handlers", () => {
378
+ it('passes through on-prefixed event handlers', () => {
379
379
  const handler = () => {
380
380
  /* noop */
381
381
  }
382
- const result = asVNode(Element({ onClick: handler, children: "test" }))
382
+ const result = asVNode(Element({ onClick: handler, children: 'test' }))
383
383
  expect(result.props.onClick).toBe(handler)
384
384
  })
385
385
 
386
- it("passes through tabindex", () => {
386
+ it('passes through tabindex', () => {
387
387
  // @ts-expect-error — testing element-specific attr forwarding
388
- const result = asVNode(Element({ tabindex: 0, children: "test" }))
388
+ const result = asVNode(Element({ tabindex: 0, children: 'test' }))
389
389
  expect(result.props.tabindex).toBe(0)
390
390
  })
391
391
 
392
- it("passes through title", () => {
393
- const result = asVNode(Element({ title: "tooltip", children: "test" }))
394
- expect(result.props.title).toBe("tooltip")
392
+ it('passes through title', () => {
393
+ const result = asVNode(Element({ title: 'tooltip', children: 'test' }))
394
+ expect(result.props.title).toBe('tooltip')
395
395
  })
396
396
 
397
- it("passes through href for anchor tag", () => {
397
+ it('passes through href for anchor tag', () => {
398
398
  // @ts-expect-error — testing element-specific attr forwarding
399
- const result = asVNode(Element({ tag: "a", href: "/link", children: "test" }))
400
- expect(result.props.href).toBe("/link")
399
+ const result = asVNode(Element({ tag: 'a', href: '/link', children: 'test' }))
400
+ expect(result.props.href).toBe('/link')
401
401
  })
402
402
 
403
- it("passes through disabled for button tag", () => {
403
+ it('passes through disabled for button tag', () => {
404
404
  // @ts-expect-error — testing element-specific attr forwarding
405
- const result = asVNode(Element({ tag: "button", disabled: true, children: "test" }))
405
+ const result = asVNode(Element({ tag: 'button', disabled: true, children: 'test' }))
406
406
  expect(result.props.disabled).toBe(true)
407
407
  })
408
408
 
409
- it("passes through class", () => {
410
- const result = asVNode(Element({ class: "my-class", children: "test" }))
411
- expect(result.props.class).toBe("my-class")
409
+ it('passes through class', () => {
410
+ const result = asVNode(Element({ class: 'my-class', children: 'test' }))
411
+ expect(result.props.class).toBe('my-class')
412
412
  })
413
413
 
414
- it("does not set class when not provided", () => {
415
- const result = asVNode(Element({ children: "test" }))
414
+ it('does not set class when not provided', () => {
415
+ const result = asVNode(Element({ children: 'test' }))
416
416
  expect(result.props.class).toBeUndefined()
417
417
  })
418
418
 
419
- it("filters out reserved props (gap, beforeContent, afterContent, css, etc.)", () => {
419
+ it('filters out reserved props (gap, beforeContent, afterContent, css, etc.)', () => {
420
420
  const result = asVNode(
421
421
  Element({
422
- beforeContent: h("span", null, "x"),
423
- afterContent: h("span", null, "y"),
424
- children: "test",
425
- direction: "inline",
426
- alignX: "center",
427
- alignY: "center",
422
+ beforeContent: h('span', null, 'x'),
423
+ afterContent: h('span', null, 'y'),
424
+ children: 'test',
425
+ direction: 'inline',
426
+ alignX: 'center',
427
+ alignY: 'center',
428
428
  gap: 8,
429
429
  block: true,
430
430
  equalCols: true,
@@ -442,162 +442,162 @@ describe("Element", () => {
442
442
  })
443
443
  })
444
444
 
445
- describe("ref handling", () => {
446
- it("passes a merged ref function to Wrapper", () => {
447
- const result = asVNode(Element({ children: "test" }))
448
- expect(typeof result.props.ref).toBe("function")
445
+ describe('ref handling', () => {
446
+ it('passes a merged ref function to Wrapper', () => {
447
+ const result = asVNode(Element({ children: 'test' }))
448
+ expect(typeof result.props.ref).toBe('function')
449
449
  })
450
450
 
451
- it("wraps function ref in mergedRef", () => {
451
+ it('wraps function ref in mergedRef', () => {
452
452
  let captured: HTMLElement | null = null
453
453
  const ref = (node: HTMLElement | null) => {
454
454
  captured = node
455
455
  }
456
- const result = asVNode(Element({ ref, children: "test" }))
457
- expect(typeof result.props.ref).toBe("function")
456
+ const result = asVNode(Element({ ref, children: 'test' }))
457
+ expect(typeof result.props.ref).toBe('function')
458
458
  const fakeNode = {} as HTMLElement
459
459
  ;(result.props.ref as (node: HTMLElement | null) => void)(fakeNode)
460
460
  expect(captured).toBe(fakeNode)
461
461
  })
462
462
 
463
- it("wraps object ref in mergedRef", () => {
463
+ it('wraps object ref in mergedRef', () => {
464
464
  const ref = { current: null as HTMLElement | null }
465
- const result = asVNode(Element({ ref, children: "test" }))
466
- expect(typeof result.props.ref).toBe("function")
465
+ const result = asVNode(Element({ ref, children: 'test' }))
466
+ expect(typeof result.props.ref).toBe('function')
467
467
  const fakeNode = {} as HTMLElement
468
468
  ;(result.props.ref as (node: HTMLElement | null) => void)(fakeNode)
469
469
  expect(ref.current).toBe(fakeNode)
470
470
  })
471
471
  })
472
472
 
473
- describe("void / empty elements", () => {
474
- it("renders img with no children", () => {
473
+ describe('void / empty elements', () => {
474
+ it('renders img with no children', () => {
475
475
  // @ts-expect-error — testing element-specific attr forwarding
476
- const result = asVNode(Element({ tag: "img", src: "/pic.png" }))
476
+ const result = asVNode(Element({ tag: 'img', src: '/pic.png' }))
477
477
  expect(result.type).toBe(Wrapper)
478
- expect(result.props.tag).toBe("img")
479
- expect(result.props.src).toBe("/pic.png")
478
+ expect(result.props.tag).toBe('img')
479
+ expect(result.props.src).toBe('/pic.png')
480
480
  expect(result.props.children).toBeUndefined()
481
481
  })
482
482
 
483
- it("renders input with no children", () => {
483
+ it('renders input with no children', () => {
484
484
  // @ts-expect-error — testing element-specific attr forwarding
485
- const result = asVNode(Element({ tag: "input", type: "text" }))
485
+ const result = asVNode(Element({ tag: 'input', type: 'text' }))
486
486
  expect(result.type).toBe(Wrapper)
487
- expect(result.props.tag).toBe("input")
488
- expect(result.props.type).toBe("text")
487
+ expect(result.props.tag).toBe('input')
488
+ expect(result.props.type).toBe('text')
489
489
  expect(result.props.children).toBeUndefined()
490
490
  })
491
491
 
492
- it("renders with dangerouslySetInnerHTML (treated as empty)", () => {
493
- const result = asVNode(Element({ dangerouslySetInnerHTML: { __html: "<b>hi</b>" } }))
492
+ it('renders with dangerouslySetInnerHTML (treated as empty)', () => {
493
+ const result = asVNode(Element({ dangerouslySetInnerHTML: { __html: '<b>hi</b>' } }))
494
494
  expect(result.type).toBe(Wrapper)
495
- expect(result.props.dangerouslySetInnerHTML).toEqual({ __html: "<b>hi</b>" })
495
+ expect(result.props.dangerouslySetInnerHTML).toEqual({ __html: '<b>hi</b>' })
496
496
  expect(result.props.children).toBeUndefined()
497
497
  })
498
498
 
499
- it("renders br with no children", () => {
500
- const result = asVNode(Element({ tag: "br" }))
499
+ it('renders br with no children', () => {
500
+ const result = asVNode(Element({ tag: 'br' }))
501
501
  expect(result.type).toBe(Wrapper)
502
502
  expect(result.props.children).toBeUndefined()
503
503
  })
504
504
 
505
- it("renders hr with no children", () => {
506
- const result = asVNode(Element({ tag: "hr" }))
505
+ it('renders hr with no children', () => {
506
+ const result = asVNode(Element({ tag: 'hr' }))
507
507
  expect(result.type).toBe(Wrapper)
508
508
  expect(result.props.children).toBeUndefined()
509
509
  })
510
510
  })
511
511
 
512
- describe("isInline flag for Wrapper", () => {
513
- it("passes isInline=true for inline tags like span", () => {
514
- const result = asVNode(Element({ tag: "span", children: "text" }))
512
+ describe('isInline flag for Wrapper', () => {
513
+ it('passes isInline=true for inline tags like span', () => {
514
+ const result = asVNode(Element({ tag: 'span', children: 'text' }))
515
515
  expect(result.props.isInline).toBe(true)
516
516
  })
517
517
 
518
- it("passes isInline=true for anchor tag", () => {
518
+ it('passes isInline=true for anchor tag', () => {
519
519
  // @ts-expect-error — testing element-specific attr forwarding
520
- const result = asVNode(Element({ tag: "a", href: "#", children: "link" }))
520
+ const result = asVNode(Element({ tag: 'a', href: '#', children: 'link' }))
521
521
  expect(result.props.isInline).toBe(true)
522
522
  })
523
523
 
524
- it("passes isInline=false for block tags like section", () => {
525
- const result = asVNode(Element({ tag: "section", children: "text" }))
524
+ it('passes isInline=false for block tags like section', () => {
525
+ const result = asVNode(Element({ tag: 'section', children: 'text' }))
526
526
  expect(result.props.isInline).toBe(false)
527
527
  })
528
528
 
529
- it("passes isInline=false when tag is undefined (default)", () => {
530
- const result = asVNode(Element({ children: "text" }))
529
+ it('passes isInline=false when tag is undefined (default)', () => {
530
+ const result = asVNode(Element({ children: 'text' }))
531
531
  expect(result.props.isInline).toBe(false)
532
532
  })
533
533
  })
534
534
 
535
- describe("extendCss prop", () => {
536
- it("passes css prop as extendCss to Wrapper", () => {
537
- const customCss = "color: red;"
538
- const result = asVNode(Element({ css: customCss, children: "test" }))
535
+ describe('extendCss prop', () => {
536
+ it('passes css prop as extendCss to Wrapper', () => {
537
+ const customCss = 'color: red;'
538
+ const result = asVNode(Element({ css: customCss, children: 'test' }))
539
539
  expect(result.props.extendCss).toBe(customCss)
540
540
  })
541
541
 
542
- it("does not pass extendCss when css not provided", () => {
543
- const result = asVNode(Element({ children: "test" }))
542
+ it('does not pass extendCss when css not provided', () => {
543
+ const result = asVNode(Element({ children: 'test' }))
544
544
  expect(result.props.extendCss).toBeUndefined()
545
545
  })
546
546
  })
547
547
 
548
- describe("content fallback chain", () => {
549
- it("prefers children over content", () => {
550
- const result = asVNode(Element({ children: "child", content: "alt" }))
548
+ describe('content fallback chain', () => {
549
+ it('prefers children over content', () => {
550
+ const result = asVNode(Element({ children: 'child', content: 'alt' }))
551
551
  const children = result.props.children as unknown[]
552
552
  expect(children).toBeDefined()
553
553
  expect(Array.isArray(children)).toBe(true)
554
554
  })
555
555
 
556
- it("falls back to content when no children", () => {
557
- const result = asVNode(Element({ content: "alt content" }))
556
+ it('falls back to content when no children', () => {
557
+ const result = asVNode(Element({ content: 'alt content' }))
558
558
  const children = result.props.children as unknown[]
559
559
  expect(children).toBeDefined()
560
560
  })
561
561
 
562
- it("falls back to label when no children or content", () => {
563
- const result = asVNode(Element({ label: "label text" }))
562
+ it('falls back to label when no children or content', () => {
563
+ const result = asVNode(Element({ label: 'label text' }))
564
564
  const children = result.props.children as unknown[]
565
565
  expect(children).toBeDefined()
566
566
  })
567
567
  })
568
568
 
569
- describe("Wrapper as prop reset", () => {
570
- it("resets the as prop to undefined on Wrapper", () => {
571
- const result = asVNode(Element({ children: "test" }))
569
+ describe('Wrapper as prop reset', () => {
570
+ it('resets the as prop to undefined on Wrapper', () => {
571
+ const result = asVNode(Element({ children: 'test' }))
572
572
  expect(result.props.as).toBeUndefined()
573
573
  })
574
574
  })
575
575
 
576
- describe("button tag (flex fix needed)", () => {
577
- it("passes tag as button to Wrapper", () => {
578
- const result = asVNode(Element({ tag: "button", children: "click" }))
576
+ describe('button tag (flex fix needed)', () => {
577
+ it('passes tag as button to Wrapper', () => {
578
+ const result = asVNode(Element({ tag: 'button', children: 'click' }))
579
579
  expect(result.type).toBe(Wrapper)
580
- expect(result.props.tag).toBe("button")
580
+ expect(result.props.tag).toBe('button')
581
581
  })
582
582
 
583
- it("passes isInline=true for button (inline element)", () => {
584
- const result = asVNode(Element({ tag: "button", children: "click" }))
583
+ it('passes isInline=true for button (inline element)', () => {
584
+ const result = asVNode(Element({ tag: 'button', children: 'click' }))
585
585
  expect(result.props.isInline).toBe(true)
586
586
  })
587
587
  })
588
588
 
589
- describe("component metadata", () => {
590
- it("has displayName set", () => {
589
+ describe('component metadata', () => {
590
+ it('has displayName set', () => {
591
591
  expect(Element.displayName).toBeDefined()
592
- expect(Element.displayName).toContain("Element")
592
+ expect(Element.displayName).toContain('Element')
593
593
  })
594
594
 
595
- it("has PYREON__COMPONENT set", () => {
595
+ it('has PYREON__COMPONENT set', () => {
596
596
  expect(Element.PYREON__COMPONENT).toBeDefined()
597
- expect(Element.PYREON__COMPONENT).toContain("Element")
597
+ expect(Element.PYREON__COMPONENT).toContain('Element')
598
598
  })
599
599
 
600
- it("has pkgName set", () => {
600
+ it('has pkgName set', () => {
601
601
  expect(Element.pkgName).toBeDefined()
602
602
  })
603
603
  })