@pyreon/elements 0.24.5 → 0.25.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.
Files changed (71) hide show
  1. package/lib/index.js +5 -1
  2. package/package.json +11 -13
  3. package/src/Element/component.tsx +0 -315
  4. package/src/Element/constants.ts +0 -96
  5. package/src/Element/index.ts +0 -6
  6. package/src/Element/types.ts +0 -168
  7. package/src/Element/utils.ts +0 -15
  8. package/src/List/component.tsx +0 -105
  9. package/src/List/index.ts +0 -5
  10. package/src/Overlay/component.tsx +0 -140
  11. package/src/Overlay/context.tsx +0 -36
  12. package/src/Overlay/index.ts +0 -7
  13. package/src/Overlay/positioning.ts +0 -191
  14. package/src/Overlay/useOverlay.tsx +0 -461
  15. package/src/Portal/component.tsx +0 -54
  16. package/src/Portal/index.ts +0 -5
  17. package/src/Text/component.tsx +0 -67
  18. package/src/Text/index.ts +0 -5
  19. package/src/Text/styled.ts +0 -30
  20. package/src/Util/component.tsx +0 -43
  21. package/src/Util/index.ts +0 -5
  22. package/src/__tests__/Content.test.tsx +0 -123
  23. package/src/__tests__/Element-slot-reactivity.browser.test.tsx +0 -152
  24. package/src/__tests__/Element.test.ts +0 -819
  25. package/src/__tests__/Iterator.test.ts +0 -492
  26. package/src/__tests__/Iterator.types.test.ts +0 -237
  27. package/src/__tests__/List.test.ts +0 -199
  28. package/src/__tests__/Overlay.test.ts +0 -492
  29. package/src/__tests__/Portal.test.ts +0 -156
  30. package/src/__tests__/Text.test.ts +0 -274
  31. package/src/__tests__/Util.test.ts +0 -63
  32. package/src/__tests__/Wrapper-innerhtml.test.tsx +0 -178
  33. package/src/__tests__/Wrapper.test.tsx +0 -196
  34. package/src/__tests__/elements.browser.test.tsx +0 -132
  35. package/src/__tests__/equalBeforeAfter.test.ts +0 -122
  36. package/src/__tests__/helpers.test.ts +0 -65
  37. package/src/__tests__/integration.test.tsx +0 -118
  38. package/src/__tests__/internElementBundle.test.ts +0 -102
  39. package/src/__tests__/iterator-function-children.test.tsx +0 -120
  40. package/src/__tests__/native-markers.test.ts +0 -13
  41. package/src/__tests__/overlayContext.test.tsx +0 -78
  42. package/src/__tests__/perf-stress.browser.test.tsx +0 -119
  43. package/src/__tests__/positioning.test.ts +0 -90
  44. package/src/__tests__/responsiveProps.test.ts +0 -328
  45. package/src/__tests__/slot-component-reference.test.tsx +0 -157
  46. package/src/__tests__/useOverlay.test.ts +0 -1336
  47. package/src/__tests__/utils.test.ts +0 -69
  48. package/src/__tests__/wrapper-block-cascade.test.ts +0 -121
  49. package/src/constants.ts +0 -1
  50. package/src/env.d.ts +0 -6
  51. package/src/helpers/Content/component.tsx +0 -75
  52. package/src/helpers/Content/index.ts +0 -3
  53. package/src/helpers/Content/styled.ts +0 -105
  54. package/src/helpers/Content/types.ts +0 -49
  55. package/src/helpers/Iterator/component.tsx +0 -316
  56. package/src/helpers/Iterator/index.ts +0 -30
  57. package/src/helpers/Iterator/types.ts +0 -138
  58. package/src/helpers/Wrapper/component.tsx +0 -180
  59. package/src/helpers/Wrapper/constants.ts +0 -10
  60. package/src/helpers/Wrapper/index.ts +0 -3
  61. package/src/helpers/Wrapper/styled.ts +0 -64
  62. package/src/helpers/Wrapper/types.ts +0 -56
  63. package/src/helpers/Wrapper/utils.ts +0 -7
  64. package/src/helpers/index.ts +0 -4
  65. package/src/helpers/internElementBundle.ts +0 -37
  66. package/src/helpers/isPyreonComponent.ts +0 -46
  67. package/src/index.ts +0 -42
  68. package/src/manifest.ts +0 -190
  69. package/src/tests/manifest-snapshot.test.ts +0 -45
  70. package/src/types.ts +0 -112
  71. package/src/utils.ts +0 -5
@@ -1,461 +0,0 @@
1
- /**
2
- * Core hook powering the Overlay component. Manages open/close state, DOM
3
- * event listeners (click, hover, scroll, resize, ESC key), and dynamic
4
- * positioning of overlay content relative to its trigger. Supports dropdown,
5
- * tooltip, popover, and modal types with automatic edge-of-viewport flipping.
6
- * Event handlers are throttled for performance, and nested overlay blocking
7
- * is coordinated through the overlay context.
8
- */
9
-
10
- import { signal } from '@pyreon/reactivity'
11
- import { throttle } from '@pyreon/ui-core'
12
- import { value } from '@pyreon/unistyle'
13
- import { IS_DEVELOPMENT } from '../utils'
14
- import Provider, { useOverlayContext } from './context'
15
- import {
16
- adjustForAncestor,
17
- calcDropdownHorizontal,
18
- calcDropdownVertical,
19
- calcModalPos,
20
- type Align,
21
- type AlignX,
22
- type AlignY,
23
- type OverlayPosition,
24
- } from './positioning'
25
-
26
- export type UseOverlayProps = Partial<{
27
- isOpen: boolean
28
- openOn: 'click' | 'hover' | 'manual'
29
- closeOn: 'click' | 'clickOnTrigger' | 'clickOutsideContent' | 'hover' | 'manual'
30
- type: 'dropdown' | 'tooltip' | 'popover' | 'modal' | 'custom'
31
- position: 'absolute' | 'fixed' | 'relative' | 'static'
32
- align: Align
33
- alignX: AlignX
34
- alignY: AlignY
35
- offsetX: number
36
- offsetY: number
37
- throttleDelay: number
38
- parentContainer: HTMLElement | null
39
- closeOnEsc: boolean
40
- hoverDelay: number
41
- disabled: boolean
42
- onOpen: () => void
43
- onClose: () => void
44
- }>
45
-
46
- // Reference counter for nested modals sharing document.body overflow lock.
47
- let modalOverflowCount = 0
48
-
49
- // Hoisted: closeOn values that count as "click-driven close". Inlined
50
- // previously, allocating a fresh 3-element array on each click-listener
51
- // setupListeners re-run. Ported from vitus-labs `804dd0e2`.
52
- const CLICK_CLOSE_KINDS: ReadonlySet<string> = new Set([
53
- 'click',
54
- 'clickOnTrigger',
55
- 'clickOutsideContent',
56
- ])
57
-
58
- const devWarn = (msg: string) => {
59
- if (!IS_DEVELOPMENT) return
60
- // oxlint-disable-next-line no-console
61
- console.warn(msg)
62
- }
63
-
64
-
65
- type ComputeResult = {
66
- pos: OverlayPosition
67
- resolvedAlignX?: AlignX
68
- resolvedAlignY?: AlignY
69
- }
70
-
71
- const computePosition = (
72
- type: string,
73
- align: Align,
74
- alignX: AlignX,
75
- alignY: AlignY,
76
- offsetX: number,
77
- offsetY: number,
78
- triggerEl: HTMLElement | null,
79
- contentEl: HTMLElement | null,
80
- ancestorOffset: { top: number; left: number },
81
- ): ComputeResult => {
82
- const isDropdown = ['dropdown', 'tooltip', 'popover'].includes(type)
83
-
84
- if (isDropdown && (!triggerEl || !contentEl)) {
85
- devWarn(
86
- `[@pyreon/elements] Overlay (${type}): ` +
87
- `${triggerEl ? 'contentRef' : 'triggerRef'} is not attached. ` +
88
- 'Position cannot be calculated without both refs.',
89
- )
90
- return { pos: {} }
91
- }
92
-
93
- if (isDropdown && triggerEl && contentEl) {
94
- const c = contentEl.getBoundingClientRect()
95
- const t = triggerEl.getBoundingClientRect()
96
- const result =
97
- align === 'top' || align === 'bottom'
98
- ? calcDropdownVertical(c, t, align, alignX, offsetX, offsetY)
99
- : calcDropdownHorizontal(c, t, align as 'left' | 'right', alignY, offsetX, offsetY)
100
-
101
- return {
102
- pos: adjustForAncestor(result.pos, ancestorOffset),
103
- resolvedAlignX: result.resolvedAlignX,
104
- resolvedAlignY: result.resolvedAlignY,
105
- }
106
- }
107
-
108
- if (type === 'modal') {
109
- if (!contentEl) {
110
- devWarn(
111
- '[@pyreon/elements] Overlay (modal): contentRef is not attached. ' +
112
- 'Modal position cannot be calculated without a content element.',
113
- )
114
- return { pos: {} }
115
- }
116
- const c = contentEl.getBoundingClientRect()
117
- return {
118
- pos: adjustForAncestor(calcModalPos(c, alignX, alignY, offsetX, offsetY), ancestorOffset),
119
- }
120
- }
121
-
122
- return { pos: {} }
123
- }
124
-
125
- const processVisibilityEvent = (
126
- e: Event,
127
- active: boolean,
128
- openOn: string,
129
- closeOn: string,
130
- isTrigger: (evt: Event) => boolean,
131
- isContent: (evt: Event) => boolean,
132
- showContent: () => void,
133
- hideContent: () => void,
134
- ) => {
135
- if (!active && openOn === 'click' && e.type === 'click' && isTrigger(e)) {
136
- showContent()
137
- return
138
- }
139
-
140
- if (!active) return
141
-
142
- if (closeOn === 'hover' && e.type === 'scroll') {
143
- hideContent()
144
- return
145
- }
146
-
147
- if (e.type !== 'click') return
148
-
149
- if (closeOn === 'click') {
150
- hideContent()
151
- } else if (closeOn === 'clickOnTrigger' && isTrigger(e)) {
152
- hideContent()
153
- } else if (closeOn === 'clickOutsideContent' && !isContent(e)) {
154
- hideContent()
155
- }
156
- }
157
-
158
- const useOverlay = ({
159
- isOpen = false,
160
- openOn = 'click',
161
- closeOn = 'click',
162
- type = 'dropdown',
163
- position = 'fixed',
164
- align = 'bottom',
165
- alignX: propAlignX = 'left',
166
- alignY: propAlignY = 'bottom',
167
- offsetX = 0,
168
- offsetY = 0,
169
- throttleDelay = 200,
170
- parentContainer,
171
- closeOnEsc = true,
172
- hoverDelay = 100,
173
- disabled,
174
- onOpen,
175
- onClose,
176
- }: Partial<UseOverlayProps> = {}) => {
177
- const ctx = useOverlayContext()
178
-
179
- // Signal-based state
180
- const active = signal(isOpen)
181
- const isContentLoaded = signal(false)
182
- const innerAlignX = signal(propAlignX)
183
- const innerAlignY = signal(propAlignY)
184
- const blockedCount = signal(0)
185
-
186
- const blocked = () => blockedCount() > 0
187
-
188
- // DOM refs (plain variables, component runs once)
189
- let triggerEl: HTMLElement | null = null
190
- let contentEl: HTMLElement | null = null
191
- const _prevFocusEl: HTMLElement | null = null
192
- let hoverTimeout: ReturnType<typeof setTimeout> | null = null
193
-
194
- const triggerRef = (node: HTMLElement | null) => {
195
- triggerEl = node
196
- }
197
-
198
- const contentRefCallback = (node: HTMLElement | null) => {
199
- contentEl = node
200
- isContentLoaded.set(!!node)
201
- }
202
-
203
- const setBlocked = () => blockedCount.update((c) => c + 1)
204
- const setUnblocked = () => blockedCount.update((c) => Math.max(0, c - 1))
205
-
206
- const showContent = () => {
207
- active.set(true)
208
- onOpen?.()
209
- ctx.setBlocked?.()
210
- }
211
-
212
- const hideContent = () => {
213
- active.set(false)
214
- isContentLoaded.set(false)
215
- onClose?.()
216
- ctx.setUnblocked?.()
217
- }
218
-
219
- // Position calculation helpers
220
- const getAncestorOffset = () => {
221
- if (typeof document === 'undefined') return { top: 0, left: 0 }
222
- if (position !== 'absolute' || !contentEl) {
223
- return { top: 0, left: 0 }
224
- }
225
-
226
- const offsetParent = contentEl.offsetParent as HTMLElement | null
227
- if (!offsetParent || offsetParent === document.body) {
228
- return { top: 0, left: 0 }
229
- }
230
-
231
- const rect = offsetParent.getBoundingClientRect()
232
- return { top: rect.top, left: rect.left }
233
- }
234
-
235
- const calculateContentPosition = () => {
236
- if (!active() || !isContentLoaded()) return {}
237
-
238
- const result = computePosition(
239
- type,
240
- align,
241
- propAlignX,
242
- propAlignY,
243
- offsetX,
244
- offsetY,
245
- triggerEl,
246
- contentEl,
247
- getAncestorOffset(),
248
- )
249
-
250
- if (result.resolvedAlignX) innerAlignX.set(result.resolvedAlignX)
251
- if (result.resolvedAlignY) innerAlignY.set(result.resolvedAlignY)
252
-
253
- return result.pos
254
- }
255
-
256
- const assignContentPosition = (values: OverlayPosition = {}) => {
257
- if (!contentEl) return
258
-
259
- const el = contentEl
260
- const setValue = (param?: string | number) => value(param, 16) as string
261
-
262
- el.style.position = position
263
-
264
- el.style.top = values.top != null ? setValue(values.top) : ''
265
- el.style.bottom = values.bottom != null ? setValue(values.bottom) : ''
266
- el.style.left = values.left != null ? setValue(values.left) : ''
267
- el.style.right = values.right != null ? setValue(values.right) : ''
268
- }
269
-
270
- const setContentPosition = () => {
271
- const currentPosition = calculateContentPosition()
272
- assignContentPosition(currentPosition)
273
- }
274
-
275
- const isNodeOrChild = (getRef: () => HTMLElement | null) => (e: Event) => {
276
- const ref = getRef()
277
- if (e?.target && ref) {
278
- return ref.contains(e.target as Element) || e.target === ref
279
- }
280
- return false
281
- }
282
-
283
- const handleVisibilityByEventType = (e: Event) => {
284
- if (blocked() || disabled) return
285
-
286
- processVisibilityEvent(
287
- e,
288
- active(),
289
- openOn,
290
- closeOn,
291
- isNodeOrChild(() => triggerEl),
292
- isNodeOrChild(() => contentEl),
293
- showContent,
294
- hideContent,
295
- )
296
- }
297
-
298
- const handleContentPosition = throttle(() => setContentPosition(), throttleDelay)
299
-
300
- const handleClick = (e: Event) => handleVisibilityByEventType(e)
301
-
302
- const handleVisibility = throttle((e: Event) => handleVisibilityByEventType(e), throttleDelay)
303
-
304
- // --------------------------------------------------------------------------
305
- // Set up all event listeners on mount, clean up on unmount
306
- // --------------------------------------------------------------------------
307
- const setupListeners = () => {
308
- if (typeof window === 'undefined') return () => {}
309
- const cleanups: (() => void)[] = []
310
-
311
- // Click-based open/close
312
- const enabledClick = openOn === 'click' || CLICK_CLOSE_KINDS.has(closeOn)
313
-
314
- if (enabledClick) {
315
- window.addEventListener('click', handleClick)
316
- cleanups.push(() => window.removeEventListener('click', handleClick))
317
- }
318
-
319
- // ESC key
320
- if (closeOnEsc) {
321
- const handleEscKey = (e: KeyboardEvent) => {
322
- if (e.key === 'Escape' && active() && !blocked()) {
323
- hideContent()
324
- }
325
- }
326
- window.addEventListener('keydown', handleEscKey)
327
- cleanups.push(() => window.removeEventListener('keydown', handleEscKey))
328
- }
329
-
330
- // Hover-based open/close
331
- const enabledHover = openOn === 'hover' || closeOn === 'hover'
332
- if (enabledHover) {
333
- const clearHoverTimeout = () => {
334
- if (hoverTimeout != null) {
335
- clearTimeout(hoverTimeout)
336
- hoverTimeout = null
337
- }
338
- }
339
-
340
- const scheduleHide = () => {
341
- clearHoverTimeout()
342
- hoverTimeout = setTimeout(hideContent, hoverDelay)
343
- }
344
-
345
- const onTriggerEnter = () => {
346
- clearHoverTimeout()
347
- if (openOn === 'hover' && !active()) showContent()
348
- }
349
-
350
- const onTriggerLeave = () => {
351
- if (closeOn === 'hover' && active()) scheduleHide()
352
- }
353
-
354
- const onContentEnter = () => {
355
- clearHoverTimeout()
356
- }
357
-
358
- const onContentLeave = () => {
359
- if (closeOn === 'hover' && active()) scheduleHide()
360
- }
361
-
362
- // We need to defer listener attachment until refs are available
363
- const attachHoverListeners = () => {
364
- if (triggerEl) {
365
- triggerEl.addEventListener('mouseenter', onTriggerEnter)
366
- triggerEl.addEventListener('mouseleave', onTriggerLeave)
367
- }
368
- if (contentEl) {
369
- contentEl.addEventListener('mouseenter', onContentEnter)
370
- contentEl.addEventListener('mouseleave', onContentLeave)
371
- }
372
- }
373
-
374
- attachHoverListeners()
375
-
376
- cleanups.push(() => {
377
- clearHoverTimeout()
378
- if (triggerEl) {
379
- triggerEl.removeEventListener('mouseenter', onTriggerEnter)
380
- triggerEl.removeEventListener('mouseleave', onTriggerLeave)
381
- }
382
- if (contentEl) {
383
- contentEl.removeEventListener('mouseenter', onContentEnter)
384
- contentEl.removeEventListener('mouseleave', onContentLeave)
385
- }
386
- })
387
- }
388
-
389
- // Resize/scroll repositioning
390
- const shouldSetOverflow = type === 'modal'
391
-
392
- const onScroll = (e: Event) => {
393
- handleContentPosition()
394
- handleVisibility(e)
395
- }
396
-
397
- if (shouldSetOverflow) {
398
- modalOverflowCount++
399
- if (modalOverflowCount === 1) document.body.style.overflow = 'hidden'
400
- }
401
-
402
- window.addEventListener('resize', handleContentPosition)
403
- window.addEventListener('scroll', onScroll, { passive: true })
404
- cleanups.push(() => {
405
- handleContentPosition.cancel()
406
- handleVisibility.cancel()
407
- if (shouldSetOverflow) {
408
- modalOverflowCount--
409
- if (modalOverflowCount === 0) document.body.style.overflow = ''
410
- }
411
- window.removeEventListener('resize', handleContentPosition)
412
- window.removeEventListener('scroll', onScroll)
413
- })
414
-
415
- // Parent container scroll
416
- if (parentContainer) {
417
- if (closeOn !== 'hover') parentContainer.style.overflow = 'hidden'
418
-
419
- const onParentScroll = (e: Event) => {
420
- handleContentPosition()
421
- handleVisibility(e)
422
- }
423
-
424
- parentContainer.addEventListener('scroll', onParentScroll, {
425
- passive: true,
426
- })
427
- cleanups.push(() => {
428
- parentContainer.style.overflow = ''
429
- parentContainer.removeEventListener('scroll', onParentScroll)
430
- })
431
- }
432
-
433
- // Cleanup function
434
- return () => {
435
- for (const cleanup of cleanups) cleanup()
436
- }
437
- }
438
-
439
- // Handle disabled state
440
- if (disabled) {
441
- active.set(false)
442
- }
443
-
444
- return {
445
- triggerRef,
446
- contentRef: contentRefCallback,
447
- active,
448
- align,
449
- alignX: innerAlignX,
450
- alignY: innerAlignY,
451
- showContent,
452
- hideContent,
453
- blocked,
454
- setBlocked,
455
- setUnblocked,
456
- setupListeners,
457
- Provider,
458
- }
459
- }
460
-
461
- export default useOverlay
@@ -1,54 +0,0 @@
1
- /**
2
- * Portal — renders children into a per-instance wrapper element appended to
3
- * `DOMLocation` (defaults to `document.body`). Mirrors vitus-labs's Portal:
4
- * a fresh wrapper is created per Portal mount, children render INSIDE it
5
- * (not directly into DOMLocation), and the wrapper is removed on unmount.
6
- *
7
- * Per-instance wrapper isolation matters when multiple Portals share a
8
- * DOMLocation (e.g. several modals on `document.body`) — without the wrapper
9
- * their children would intermingle, defeating CSS scoping and making
10
- * cleanup brittle.
11
- */
12
-
13
- import type { VNodeChild } from '@pyreon/core'
14
- import { Portal as CorePortal, onUnmount } from '@pyreon/core'
15
- import { PKG_NAME } from '../constants'
16
- import type { PyreonComponent } from '../types'
17
-
18
- export interface Props {
19
- /**
20
- * DOM element to mount the wrapper into. Defaults to `document.body`.
21
- */
22
- DOMLocation?: HTMLElement
23
- /**
24
- * Children rendered inside the wrapper.
25
- */
26
- children: VNodeChild
27
- /**
28
- * HTML tag for the per-instance wrapper element. Defaults to `'div'`.
29
- */
30
- tag?: string
31
- }
32
-
33
- const Component: PyreonComponent<Props> = (props) => {
34
- if (typeof document === 'undefined') return null
35
-
36
- const tag = props.tag ?? 'div'
37
- const target = props.DOMLocation ?? document.body
38
- const wrapper = document.createElement(tag)
39
- target.appendChild(wrapper)
40
-
41
- onUnmount(() => {
42
- wrapper.remove()
43
- })
44
-
45
- return <CorePortal target={wrapper}>{props.children}</CorePortal>
46
- }
47
-
48
- const name = `${PKG_NAME}/Portal` as const
49
-
50
- Component.displayName = name
51
- Component.pkgName = PKG_NAME
52
- Component.PYREON__COMPONENT = name
53
-
54
- export default Component
@@ -1,5 +0,0 @@
1
- import type { Props } from './component'
2
- import component from './component'
3
-
4
- export type { Props as PortalProps }
5
- export { component as Portal }
@@ -1,67 +0,0 @@
1
- /**
2
- * Text component for rendering inline or block-level text. Supports a
3
- * `paragraph` shorthand that automatically renders as a `<p>` tag, or
4
- * a custom `tag` for semantic HTML (h1-h6, span, etc.). Marked with
5
- * a static `isText` flag so other components can detect text children.
6
- */
7
-
8
- import { splitProps } from '@pyreon/core'
9
- import type { PyreonHTMLAttributes, VNodeChild } from '@pyreon/core'
10
- import type { HTMLTextTags } from '@pyreon/ui-core'
11
- import { PKG_NAME } from '../constants'
12
- import type { ExtendCss, PyreonComponent } from '../types'
13
- import Styled from './styled'
14
-
15
- export type Props = Partial<{
16
- /**
17
- * Label can be used instead of children for inline syntax. But **children** prop takes a precedence
18
- */
19
- label: VNodeChild
20
- /**
21
- * Children to be rendered within **Text** component.
22
- */
23
- children: VNodeChild
24
- /**
25
- * Defines whether should behave as a block text element. Automatically adds **p** HTML tag
26
- */
27
- paragraph: boolean
28
- /**
29
- * Defines what kind of HTML tag should be rendered
30
- */
31
- tag: HTMLTextTags
32
- /**
33
- * If an additional styling needs to be added, it can be do so via injecting styles using this property.
34
- */
35
- css: ExtendCss
36
- }> &
37
- PyreonHTMLAttributes
38
-
39
- const Component: PyreonComponent<Props> & {
40
- isText?: true
41
- } = (props) => {
42
- const [own, rest] = splitProps(props, ['paragraph', 'label', 'children', 'tag', 'css', 'ref'])
43
-
44
- // `paragraph` shorthand maps to <p>; otherwise pass through `tag`. Ternary
45
- // form replaces the prior `let finalTag` + if/else block — V8 prefers the
46
- // single-assignment shape for inline-cache stability. Ported from
47
- // vitus-labs `804dd0e2`.
48
- const finalTag = own.paragraph ? 'p' : own.tag
49
-
50
- return (
51
- <Styled ref={own.ref} as={finalTag} $text={{ extraStyles: own.css }} {...rest}>
52
- {own.children ?? own.label}
53
- </Styled>
54
- )
55
- }
56
-
57
- // ----------------------------------------------
58
- // DEFINE STATICS
59
- // ----------------------------------------------
60
- const name = `${PKG_NAME}/Text` as const
61
-
62
- Component.displayName = name
63
- Component.pkgName = PKG_NAME
64
- Component.PYREON__COMPONENT = name
65
- Component.isText = true
66
-
67
- export default Component
package/src/Text/index.ts DELETED
@@ -1,5 +0,0 @@
1
- import type { Props } from './component'
2
- import component from './component'
3
-
4
- export type { Props as TextProps }
5
- export { component as Text }
@@ -1,30 +0,0 @@
1
- /**
2
- * Styled text primitive that inherits color, font-weight, and line-height
3
- * from its parent so it blends seamlessly into any context. Additional
4
- * styles can be injected via the responsive `extraStyles` prop processed
5
- * through makeItResponsive.
6
- */
7
- import { config } from '@pyreon/ui-core'
8
- import { extendCss, makeItResponsive } from '@pyreon/unistyle'
9
- import type { ResponsiveStylesCallback } from '../types'
10
-
11
- const { styled, css, textComponent } = config
12
-
13
- const styles: ResponsiveStylesCallback = ({ css: cssFn, theme: t }) => cssFn`
14
- ${t.extraStyles && extendCss(t.extraStyles)};
15
- `
16
-
17
- export default styled(textComponent, { layer: 'elements' })`
18
- ${css`
19
- color: inherit;
20
- font-weight: inherit;
21
- line-height: 1;
22
- `};
23
-
24
- ${makeItResponsive({
25
- key: '$text',
26
- styles,
27
- css,
28
- normalize: false,
29
- })};
30
- `
@@ -1,43 +0,0 @@
1
- /**
2
- * Utility wrapper that injects className and/or style props into its
3
- * children without adding any DOM nodes of its own. Uses the core `render`
4
- * helper to clone children with the merged props.
5
- */
6
-
7
- import type { VNode, VNodeChild } from '@pyreon/core'
8
- import { render } from '@pyreon/ui-core'
9
- import { PKG_NAME } from '../constants'
10
- import type { PyreonComponent } from '../types'
11
-
12
- export interface Props {
13
- /**
14
- * Children to be rendered within **Util** component.
15
- */
16
- children: VNodeChild
17
- /**
18
- * Class name(s) to be added to children component.
19
- */
20
- className?: string | string[] | undefined
21
- /**
22
- * Style property to extend children component inline styles
23
- */
24
- style?: Record<string, unknown> | undefined
25
- }
26
-
27
- const Component: PyreonComponent<Props> = (({ children, className, style }: Props) => {
28
- const mergedClasses = Array.isArray(className) ? className.join(' ') : className
29
-
30
- const finalProps: Record<string, any> = {}
31
- if (style) finalProps.style = style
32
- if (mergedClasses) finalProps.className = mergedClasses
33
-
34
- return render(children, finalProps) as VNode | null
35
- }) as PyreonComponent<Props>
36
-
37
- const name = `${PKG_NAME}/Util` as const
38
-
39
- Component.displayName = name
40
- Component.pkgName = PKG_NAME
41
- Component.PYREON__COMPONENT = name
42
-
43
- export default Component
package/src/Util/index.ts DELETED
@@ -1,5 +0,0 @@
1
- import type { Props } from './component'
2
- import component from './component'
3
-
4
- export type { Props as UtilProps }
5
- export { component as Util }