@pyreon/elements 0.11.1 → 0.11.2
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 +8 -7
- package/src/Element/component.tsx +211 -0
- package/src/Element/constants.ts +96 -0
- package/src/Element/index.ts +6 -0
- package/src/Element/types.ts +168 -0
- package/src/Element/utils.ts +15 -0
- package/src/List/component.tsx +57 -0
- package/src/List/index.ts +5 -0
- package/src/Overlay/component.tsx +131 -0
- package/src/Overlay/context.tsx +37 -0
- package/src/Overlay/index.ts +7 -0
- package/src/Overlay/useOverlay.tsx +616 -0
- package/src/Portal/component.tsx +41 -0
- package/src/Portal/index.ts +5 -0
- package/src/Text/component.tsx +65 -0
- package/src/Text/index.ts +5 -0
- package/src/Text/styled.ts +30 -0
- package/src/Util/component.tsx +43 -0
- package/src/Util/index.ts +5 -0
- package/src/__tests__/Content.test.tsx +115 -0
- package/src/__tests__/Element.test.ts +604 -0
- package/src/__tests__/Iterator.test.ts +483 -0
- package/src/__tests__/List.test.ts +199 -0
- package/src/__tests__/Overlay.test.ts +485 -0
- package/src/__tests__/Portal.test.ts +82 -0
- package/src/__tests__/Text.test.ts +274 -0
- package/src/__tests__/Util.test.ts +63 -0
- package/src/__tests__/Wrapper.test.tsx +152 -0
- package/src/__tests__/equalBeforeAfter.test.ts +122 -0
- package/src/__tests__/helpers.test.ts +65 -0
- package/src/__tests__/overlayContext.test.tsx +78 -0
- package/src/__tests__/responsiveProps.test.ts +298 -0
- package/src/__tests__/useOverlay.test.ts +1330 -0
- package/src/__tests__/utils.test.ts +69 -0
- package/src/constants.ts +1 -0
- package/src/helpers/Content/component.tsx +51 -0
- package/src/helpers/Content/index.ts +3 -0
- package/src/helpers/Content/styled.ts +105 -0
- package/src/helpers/Content/types.ts +49 -0
- package/src/helpers/Iterator/component.tsx +252 -0
- package/src/helpers/Iterator/index.ts +13 -0
- package/src/helpers/Iterator/types.ts +79 -0
- package/src/helpers/Wrapper/component.tsx +78 -0
- package/src/helpers/Wrapper/constants.ts +10 -0
- package/src/helpers/Wrapper/index.ts +3 -0
- package/src/helpers/Wrapper/styled.ts +69 -0
- package/src/helpers/Wrapper/types.ts +56 -0
- package/src/helpers/Wrapper/utils.ts +7 -0
- package/src/helpers/index.ts +4 -0
- package/src/index.ts +37 -0
- package/src/types.ts +81 -0
- package/src/utils.ts +1 -0
|
@@ -0,0 +1,65 @@
|
|
|
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 type { PyreonHTMLAttributes, VNodeChild } from "@pyreon/core"
|
|
9
|
+
import type { HTMLTextTags } from "@pyreon/ui-core"
|
|
10
|
+
import { PKG_NAME } from "../constants"
|
|
11
|
+
import type { ExtendCss, PyreonComponent } from "../types"
|
|
12
|
+
import Styled from "./styled"
|
|
13
|
+
|
|
14
|
+
export type Props = Partial<{
|
|
15
|
+
/**
|
|
16
|
+
* Label can be used instead of children for inline syntax. But **children** prop takes a precedence
|
|
17
|
+
*/
|
|
18
|
+
label: VNodeChild
|
|
19
|
+
/**
|
|
20
|
+
* Children to be rendered within **Text** component.
|
|
21
|
+
*/
|
|
22
|
+
children: VNodeChild
|
|
23
|
+
/**
|
|
24
|
+
* Defines whether should behave as a block text element. Automatically adds **p** HTML tag
|
|
25
|
+
*/
|
|
26
|
+
paragraph: boolean
|
|
27
|
+
/**
|
|
28
|
+
* Defines what kind of HTML tag should be rendered
|
|
29
|
+
*/
|
|
30
|
+
tag: HTMLTextTags
|
|
31
|
+
/**
|
|
32
|
+
* If an additional styling needs to be added, it can be do so via injecting styles using this property.
|
|
33
|
+
*/
|
|
34
|
+
css: ExtendCss
|
|
35
|
+
}> &
|
|
36
|
+
PyreonHTMLAttributes
|
|
37
|
+
|
|
38
|
+
const Component: PyreonComponent<Props> & {
|
|
39
|
+
isText?: true
|
|
40
|
+
} = ({ paragraph, label, children, tag, css, ref, ...props }) => {
|
|
41
|
+
let finalTag: string | undefined
|
|
42
|
+
|
|
43
|
+
if (paragraph) finalTag = "p"
|
|
44
|
+
else {
|
|
45
|
+
finalTag = tag
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<Styled ref={ref} as={finalTag} $text={{ extraStyles: css }} {...props}>
|
|
50
|
+
{children ?? label}
|
|
51
|
+
</Styled>
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// ----------------------------------------------
|
|
56
|
+
// DEFINE STATICS
|
|
57
|
+
// ----------------------------------------------
|
|
58
|
+
const name = `${PKG_NAME}/Text` as const
|
|
59
|
+
|
|
60
|
+
Component.displayName = name
|
|
61
|
+
Component.pkgName = PKG_NAME
|
|
62
|
+
Component.PYREON__COMPONENT = name
|
|
63
|
+
Component.isText = true
|
|
64
|
+
|
|
65
|
+
export default Component
|
|
@@ -0,0 +1,30 @@
|
|
|
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)`
|
|
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
|
+
`
|
|
@@ -0,0 +1,43 @@
|
|
|
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
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import type { VNode } from "@pyreon/core"
|
|
2
|
+
import { beforeEach, describe, expect, it, vi } from "vitest"
|
|
3
|
+
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
// Mocks
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
const mocks = vi.hoisted(() => ({
|
|
8
|
+
render: vi.fn((children: unknown) => children),
|
|
9
|
+
}))
|
|
10
|
+
|
|
11
|
+
vi.mock("@pyreon/ui-core", async (importOriginal) => {
|
|
12
|
+
const actual = (await importOriginal()) as Record<string, unknown>
|
|
13
|
+
return {
|
|
14
|
+
...actual,
|
|
15
|
+
render: mocks.render,
|
|
16
|
+
}
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
vi.mock("~/utils", () => ({
|
|
20
|
+
IS_DEVELOPMENT: true,
|
|
21
|
+
}))
|
|
22
|
+
|
|
23
|
+
import Content from "../helpers/Content/component"
|
|
24
|
+
import Styled from "../helpers/Content/styled"
|
|
25
|
+
|
|
26
|
+
const asVNode = (v: unknown) => v as VNode
|
|
27
|
+
|
|
28
|
+
describe("Content component", () => {
|
|
29
|
+
beforeEach(() => {
|
|
30
|
+
vi.clearAllMocks()
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
it("returns a VNode whose type is the Styled component", () => {
|
|
34
|
+
const result = asVNode(Content({ contentType: "content" }))
|
|
35
|
+
expect(result.type).toBe(Styled)
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
it("passes tag as the 'as' prop to Styled", () => {
|
|
39
|
+
const result = asVNode(Content({ tag: "span" }))
|
|
40
|
+
expect(result.props.as).toBe("span")
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
it("passes contentType as $contentType prop", () => {
|
|
44
|
+
const result = asVNode(Content({ contentType: "before" }))
|
|
45
|
+
expect(result.props.$contentType).toBe("before")
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
it("passes styling props bundled as $element prop", () => {
|
|
49
|
+
const result = asVNode(
|
|
50
|
+
Content({
|
|
51
|
+
contentType: "content",
|
|
52
|
+
parentDirection: "inline",
|
|
53
|
+
direction: "rows",
|
|
54
|
+
alignX: "center",
|
|
55
|
+
alignY: "top",
|
|
56
|
+
equalCols: true,
|
|
57
|
+
gap: 8,
|
|
58
|
+
extendCss: "color: red;",
|
|
59
|
+
}),
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
expect(result.props.$element).toEqual({
|
|
63
|
+
contentType: "content",
|
|
64
|
+
parentDirection: "inline",
|
|
65
|
+
direction: "rows",
|
|
66
|
+
alignX: "center",
|
|
67
|
+
alignY: "top",
|
|
68
|
+
equalCols: true,
|
|
69
|
+
gap: 8,
|
|
70
|
+
extraStyles: "color: red;",
|
|
71
|
+
})
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
it("adds data-pyr-element attribute in development mode", () => {
|
|
75
|
+
const result = asVNode(Content({ contentType: "after" }))
|
|
76
|
+
expect(result.props["data-pyr-element"]).toBe("after")
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
it("passes children through render()", () => {
|
|
80
|
+
const children = "Some text"
|
|
81
|
+
Content({ children })
|
|
82
|
+
expect(mocks.render).toHaveBeenCalledWith(children)
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
it("spreads remaining props to Styled", () => {
|
|
86
|
+
const result = asVNode(Content({ id: "test-id", className: "custom" } as any))
|
|
87
|
+
expect(result.props.id).toBe("test-id")
|
|
88
|
+
expect(result.props.className).toBe("custom")
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
it("maps extendCss to extraStyles in $element", () => {
|
|
92
|
+
const result = asVNode(Content({ extendCss: "font-size: 14px;" }))
|
|
93
|
+
expect((result.props.$element as any).extraStyles).toBe("font-size: 14px;")
|
|
94
|
+
})
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
describe("Content component (production mode)", () => {
|
|
98
|
+
it("does not add data-pyr-element when IS_DEVELOPMENT is false", async () => {
|
|
99
|
+
// Reset module registry so the new mock takes effect
|
|
100
|
+
vi.resetModules()
|
|
101
|
+
vi.doMock("../utils", () => ({
|
|
102
|
+
IS_DEVELOPMENT: false,
|
|
103
|
+
}))
|
|
104
|
+
// Re-mock @pyreon/ui-core after resetModules
|
|
105
|
+
vi.doMock("@pyreon/ui-core", async (importOriginal) => {
|
|
106
|
+
const actual = (await importOriginal()) as Record<string, unknown>
|
|
107
|
+
return { ...actual, render: (children: unknown) => children }
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
const { default: ContentProd } = await import("../helpers/Content/component")
|
|
111
|
+
const result = asVNode(ContentProd({ contentType: "before" }))
|
|
112
|
+
|
|
113
|
+
expect(result.props["data-pyr-element"]).toBeUndefined()
|
|
114
|
+
})
|
|
115
|
+
})
|