-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtypes.ts
97 lines (78 loc) · 3.2 KB
/
types.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
export type DefaultTraverseChildren = TraverseChildren<React.ReactNode | undefined>
/**
* Converts specified groups into camelCase props. Use in combination with your component
* props like:
* ```
* const Header: React.FC<React.PropsWithChildren> = ({ children }) => {
* return <div>{children}</div>;
* };
*
* const childGroups = {
* Header,
* Footer: null,
* } as const;
*
* const MyComponentInternal: React.FC<MyComponentProps & GroupedChildrenProps<typeof childGroups>> = ({
* header,
* footer,
* ...
* }) => ...
* ```
*/
export type GroupedChildrenProps<S extends ChildrenSpec, T = ReturnType<DefaultTraverseChildren>> = {
[key in Uncapitalize<keyof S & string>]: Array<null extends S[key] ? T | undefined : React.ReactNode>
}
export type ToArray = (children: React.ReactNode | React.ReactNode[]) => Array<Exclude<React.ReactNode, boolean | null | undefined>>
export type ChildrenSpec = Record<string, React.ComponentType<object> | null>
export type SwapNullWithComponent<S extends ChildrenSpec> = {
[K in keyof S]: S[K] extends NonNullable<S[K]>
? S[K]
: React.ComponentType<React.PropsWithChildren> & GeneratedGroupingComponent
}
export type WithGroupedChildrenComponent<S extends ChildrenSpec, PROPS extends object> = React.FC<
React.PropsWithChildren<PROPS>
> &
SwapNullWithComponent<S>
export type OmitGroupedChildren<P extends object, S extends ChildrenSpec> = Omit<P, Uncapitalize<keyof S & string>>
export type ArrayElement<T extends readonly unknown[]> = T extends readonly (infer ElementType)[] ? ElementType : never
export type TrueReactChild = ArrayElement<ReturnType<ToArray>>
type ReactChildOrNull = TrueReactChild | null
export type OptimizedReactChild = ReturnType<ToArray>
export type TraverseChildren<R> = (component: ReactChildOrNull) => R
export type ChildMatcher = (component: TrueReactChild, key: PropertyKey, type: string | React.ComponentType) => boolean
export type ComponentFactory = (key: string) => React.ComponentType<React.PropsWithChildren>
export interface ExtractionConfig<T> {
/**
* A custom method to convert React component initial children to array on preprocessing stage.
* Use when you want to flatten children.
* The function must always return a cloned array of children as it will be mutated.
* If not defined standard React.Children.toArray is used.
*/
childrenToArray?: ToArray
/**
* A custom component matcher
* @param component Child Component
*/
componentMatcher?: ChildMatcher
/**
* Function to transform children of generated groups (those defined by `null` in the provided spec)
*/
traverseChildren?: TraverseChildren<T>
}
export interface Config<S extends ChildrenSpec, T = ReturnType<DefaultTraverseChildren>> extends ExtractionConfig<T> {
childrenSpec: S
/**
* A custom HOC name generation factory.
* @returns Custom component name which will be displayed in React Dev Tools.
*/
getComponentName?: () => string
/**
* A factory which returns a custom implementation of Proxy component
* @param key Current key of specification object
* @returns A React component
*/
proxyComponentFactory?: ComponentFactory
}
export type GeneratedGroupingComponent = {
_groupGenerated?: true
}