@pyreon/elements 0.11.1 → 0.11.3

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 (52) hide show
  1. package/package.json +8 -7
  2. package/src/Element/component.tsx +211 -0
  3. package/src/Element/constants.ts +96 -0
  4. package/src/Element/index.ts +6 -0
  5. package/src/Element/types.ts +168 -0
  6. package/src/Element/utils.ts +15 -0
  7. package/src/List/component.tsx +57 -0
  8. package/src/List/index.ts +5 -0
  9. package/src/Overlay/component.tsx +131 -0
  10. package/src/Overlay/context.tsx +37 -0
  11. package/src/Overlay/index.ts +7 -0
  12. package/src/Overlay/useOverlay.tsx +616 -0
  13. package/src/Portal/component.tsx +41 -0
  14. package/src/Portal/index.ts +5 -0
  15. package/src/Text/component.tsx +65 -0
  16. package/src/Text/index.ts +5 -0
  17. package/src/Text/styled.ts +30 -0
  18. package/src/Util/component.tsx +43 -0
  19. package/src/Util/index.ts +5 -0
  20. package/src/__tests__/Content.test.tsx +115 -0
  21. package/src/__tests__/Element.test.ts +604 -0
  22. package/src/__tests__/Iterator.test.ts +483 -0
  23. package/src/__tests__/List.test.ts +199 -0
  24. package/src/__tests__/Overlay.test.ts +485 -0
  25. package/src/__tests__/Portal.test.ts +82 -0
  26. package/src/__tests__/Text.test.ts +274 -0
  27. package/src/__tests__/Util.test.ts +63 -0
  28. package/src/__tests__/Wrapper.test.tsx +152 -0
  29. package/src/__tests__/equalBeforeAfter.test.ts +122 -0
  30. package/src/__tests__/helpers.test.ts +65 -0
  31. package/src/__tests__/overlayContext.test.tsx +78 -0
  32. package/src/__tests__/responsiveProps.test.ts +298 -0
  33. package/src/__tests__/useOverlay.test.ts +1330 -0
  34. package/src/__tests__/utils.test.ts +69 -0
  35. package/src/constants.ts +1 -0
  36. package/src/helpers/Content/component.tsx +51 -0
  37. package/src/helpers/Content/index.ts +3 -0
  38. package/src/helpers/Content/styled.ts +105 -0
  39. package/src/helpers/Content/types.ts +49 -0
  40. package/src/helpers/Iterator/component.tsx +252 -0
  41. package/src/helpers/Iterator/index.ts +13 -0
  42. package/src/helpers/Iterator/types.ts +79 -0
  43. package/src/helpers/Wrapper/component.tsx +78 -0
  44. package/src/helpers/Wrapper/constants.ts +10 -0
  45. package/src/helpers/Wrapper/index.ts +3 -0
  46. package/src/helpers/Wrapper/styled.ts +69 -0
  47. package/src/helpers/Wrapper/types.ts +56 -0
  48. package/src/helpers/Wrapper/utils.ts +7 -0
  49. package/src/helpers/index.ts +4 -0
  50. package/src/index.ts +37 -0
  51. package/src/types.ts +81 -0
  52. package/src/utils.ts +1 -0
@@ -0,0 +1,10 @@
1
+ /**
2
+ * HTML elements that need a two-layer DOM workaround because browsers do not
3
+ * fully support flexbox layout on button, fieldset, and legend elements.
4
+ * @see https://stackoverflow.com/questions/35464067/flexbox-not-working-on-button-or-fieldset-elements
5
+ */
6
+ export const INLINE_ELEMENTS_FLEX_FIX = {
7
+ button: true,
8
+ fieldset: true,
9
+ legend: true,
10
+ }
@@ -0,0 +1,3 @@
1
+ import component from "./component"
2
+
3
+ export default component
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Styled component for the Element wrapper layer. Handles responsive
3
+ * block/inline-flex display, direction, alignment, and custom CSS injection.
4
+ * Includes special handling for the `parentFix` / `childFix` flags that
5
+ * split flex behavior across two DOM nodes for button/fieldset/legend
6
+ * elements where a single flex container is insufficient.
7
+ */
8
+ import { config } from "@pyreon/ui-core"
9
+ import { alignContent, extendCss, makeItResponsive } from "@pyreon/unistyle"
10
+ import type { ResponsiveStylesCallback } from "../../types"
11
+ import type { StyledProps } from "./types"
12
+
13
+ const { styled, css, component } = config
14
+
15
+ const childFixCSS = `
16
+ display: flex;
17
+ flex: 1;
18
+ width: 100%;
19
+ height: 100%;
20
+ `
21
+
22
+ const parentFixCSS = `
23
+ flex-direction: column;
24
+ `
25
+
26
+ const fullHeightCSS = `
27
+ height: 100%;
28
+ `
29
+
30
+ const blockCSS = `
31
+ align-self: stretch;
32
+ width: 100%;
33
+ `
34
+
35
+ const childFixPosition = (isBlock?: boolean) => `display: ${isBlock ? "flex" : "inline-flex"};`
36
+
37
+ const styles: ResponsiveStylesCallback = ({ theme: t, css: cssFn }) => cssFn`
38
+ ${t.alignY === "block" && fullHeightCSS};
39
+
40
+ ${alignContent({
41
+ direction: t.direction,
42
+ alignX: t.alignX,
43
+ alignY: t.alignY,
44
+ })};
45
+
46
+ ${t.block && blockCSS};
47
+ ${t.alignY === "block" && t.block && fullHeightCSS};
48
+
49
+ ${!t.childFix && childFixPosition(t.block)};
50
+ ${t.parentFix && parentFixCSS};
51
+
52
+ ${t.extraStyles && extendCss(t.extraStyles as Parameters<typeof extendCss>[0])};
53
+ `
54
+
55
+ const platformCSS = `box-sizing: border-box;`
56
+
57
+ export default styled(component)`
58
+ position: relative;
59
+ ${platformCSS};
60
+
61
+ ${(({ $childFix }: StyledProps) => $childFix && childFixCSS) as any};
62
+
63
+ ${makeItResponsive({
64
+ key: "$element",
65
+ styles,
66
+ css,
67
+ normalize: true,
68
+ })};
69
+ `
@@ -0,0 +1,56 @@
1
+ import type { VNodeChild } from "@pyreon/core"
2
+ import type { HTMLTags } from "@pyreon/ui-core"
3
+ import type {
4
+ AlignX,
5
+ AlignY,
6
+ ContentAlignX,
7
+ ContentAlignY,
8
+ ContentBoolean,
9
+ ContentDirection,
10
+ Css,
11
+ Direction,
12
+ ExtendCss,
13
+ ResponsiveBoolType,
14
+ } from "../../types"
15
+
16
+ export type Reference = unknown
17
+
18
+ export interface Props {
19
+ children: VNodeChild | VNodeChild[]
20
+ tag: HTMLTags | undefined
21
+ block: ResponsiveBoolType | undefined
22
+ isInline: boolean | undefined
23
+ direction: Direction | undefined
24
+ alignX: AlignX | undefined
25
+ alignY: AlignY | undefined
26
+ equalCols: ResponsiveBoolType | undefined
27
+ extendCss: ExtendCss | undefined
28
+ dangerouslySetInnerHTML: { __html: string } | undefined
29
+ }
30
+
31
+ export interface StyledProps {
32
+ $element: {
33
+ direction: Direction
34
+ alignX: AlignX
35
+ alignY: AlignY
36
+ equalCols: ResponsiveBoolType
37
+ } & Partial<{
38
+ block: ResponsiveBoolType
39
+ extraStyles: ExtendCss
40
+ childFix: true
41
+ parentFix: true
42
+ }>
43
+ $childFix?: true
44
+ }
45
+
46
+ export type ThemeProps = {
47
+ direction: ContentDirection
48
+ alignX: ContentAlignX
49
+ alignY: ContentAlignY
50
+ equalCols: ContentBoolean
51
+ } & Partial<{
52
+ block: ContentBoolean
53
+ extraStyles: Css
54
+ childFix: true
55
+ parentFix: true
56
+ }>
@@ -0,0 +1,7 @@
1
+ import { INLINE_ELEMENTS_FLEX_FIX } from "./constants"
2
+
3
+ type IsWebFixNeeded = (tag?: string) => boolean
4
+ export const isWebFixNeeded: IsWebFixNeeded = (tag) => {
5
+ if (tag && tag in INLINE_ELEMENTS_FLEX_FIX) return true
6
+ return false
7
+ }
@@ -0,0 +1,4 @@
1
+ import Content from "./Content"
2
+ import Wrapper from "./Wrapper"
3
+
4
+ export { Content, Wrapper }
package/src/index.ts ADDED
@@ -0,0 +1,37 @@
1
+ import { Provider } from "@pyreon/unistyle"
2
+
3
+ export type { ElementProps, PyreonElement } from "./Element"
4
+ export { Element } from "./Element"
5
+ export type {
6
+ ElementType,
7
+ ExtendedProps,
8
+ ObjectValue,
9
+ Props as IteratorProps,
10
+ PropsCallback,
11
+ SimpleValue,
12
+ } from "./helpers/Iterator"
13
+ export { default as Iterator } from "./helpers/Iterator"
14
+ export type { ListProps } from "./List"
15
+ export { List } from "./List"
16
+ export type { OverlayProps, UseOverlayProps } from "./Overlay"
17
+ export { Overlay, OverlayProvider, useOverlay } from "./Overlay"
18
+ export type { PortalProps } from "./Portal"
19
+ export { Portal } from "./Portal"
20
+ export type { TextProps } from "./Text"
21
+ export { Text } from "./Text"
22
+ export type {
23
+ AlignX,
24
+ AlignY,
25
+ Content,
26
+ ContentBoolean,
27
+ Direction,
28
+ ExtendCss,
29
+ InnerRef,
30
+ PyreonStatic,
31
+ Responsive,
32
+ ResponsiveBoolType,
33
+ } from "./types"
34
+ export type { UtilProps } from "./Util"
35
+ export { Util } from "./Util"
36
+
37
+ export { Provider }
package/src/types.ts ADDED
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Shared type definitions for the elements package. Provides responsive
3
+ * value types (single | array | breakpoint-map) for layout props like
4
+ * alignment and direction, plus utility types for merging prop objects.
5
+ */
6
+ import type { ComponentFn } from "@pyreon/core"
7
+ import type { BreakpointKeys, config, render } from "@pyreon/ui-core"
8
+ import type { MakeItResponsiveStyles } from "@pyreon/unistyle"
9
+
10
+ export type ResponsiveStylesCallback = MakeItResponsiveStyles
11
+
12
+ type ExtractNullableKeys<T> = {
13
+ [P in keyof T as T[P] extends null | undefined ? never : P]: T[P]
14
+ }
15
+
16
+ type Id<T> = T extends infer U ? { [K in keyof U]: U[K] } : never
17
+
18
+ type SpreadTwo<L, R> = Id<Pick<L, Exclude<keyof L, keyof R>> & R>
19
+
20
+ type Spread<A extends readonly [...any]> = A extends [infer L, ...infer R]
21
+ ? SpreadTwo<L, Spread<R>>
22
+ : unknown
23
+
24
+ export type MergeTypes<A extends readonly [...any]> = ExtractNullableKeys<Spread<A>>
25
+
26
+ export type InnerRef = HTMLElement | ((el: HTMLElement | null) => void) | null
27
+
28
+ export type CssCallback = (css: typeof config.css) => ReturnType<typeof css>
29
+
30
+ export type Css = CssCallback | ReturnType<typeof config.css> | string
31
+
32
+ export type Content = Parameters<typeof render>["0"]
33
+
34
+ export type ContentAlignX = "left" | "center" | "right" | "spaceBetween" | "spaceAround" | "block"
35
+
36
+ export type ContentAlignY = "top" | "center" | "bottom" | "spaceBetween" | "spaceAround" | "block"
37
+
38
+ export type ContentDirection = "inline" | "rows" | "reverseInline" | "reverseRows"
39
+
40
+ export type ContentBoolean = boolean
41
+ export type ContentSimpleValue = string | number
42
+
43
+ export type Ref = HTMLElement
44
+
45
+ export type AlignY =
46
+ | ContentAlignY
47
+ | ContentAlignY[]
48
+ | Partial<Record<BreakpointKeys, ContentAlignY>>
49
+
50
+ export type AlignX =
51
+ | ContentAlignX
52
+ | ContentAlignX[]
53
+ | Partial<Record<BreakpointKeys, ContentAlignX>>
54
+
55
+ export type Direction =
56
+ | ContentDirection
57
+ | ContentDirection[]
58
+ | Partial<Record<BreakpointKeys, ContentDirection>>
59
+
60
+ export type ResponsiveBoolType =
61
+ | ContentBoolean
62
+ | ContentBoolean[]
63
+ | Partial<Record<BreakpointKeys, ContentBoolean>>
64
+
65
+ export type Responsive =
66
+ | ContentSimpleValue
67
+ | ContentSimpleValue[]
68
+ | Partial<Record<BreakpointKeys, number | string>>
69
+
70
+ export type ExtendCss = Css | Css[] | Partial<Record<BreakpointKeys, Css>>
71
+
72
+ export type ExtractProps<TComponentOrTProps> =
73
+ TComponentOrTProps extends ComponentFn<infer TProps> ? TProps : TComponentOrTProps
74
+
75
+ export type PyreonComponent<P extends Record<string, any> = {}> = ComponentFn<P> & PyreonStatic
76
+
77
+ export interface PyreonStatic {
78
+ displayName?: string | undefined
79
+ pkgName?: string
80
+ PYREON__COMPONENT?: `@pyreon/${string}`
81
+ }
package/src/utils.ts ADDED
@@ -0,0 +1 @@
1
+ export const IS_DEVELOPMENT = process.env.NODE_ENV !== "production"