-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathindex.ts
More file actions
executable file
·83 lines (68 loc) · 2.48 KB
/
index.ts
File metadata and controls
executable file
·83 lines (68 loc) · 2.48 KB
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
import { createElement, forwardRef } from "react";
import {
CSSComponentConfig,
CSS,
PolymorphicComponent,
variantsType,
} from "./type";
import {
componentDisplayName,
findMatchingCompoundVariants,
flattenCss,
} from "./utils";
export { CSSComponentConfig, CSS, VariantProps } from "./type";
export const styled = <
V extends variantsType | object,
E extends React.ElementType
>(
element: E,
config?: CSSComponentConfig<V>
) => {
const styledComponent = forwardRef<E, { [key: string]: string }>(
(props, ref) => {
const mergedProps = { ...config?.defaultVariants, ...props } as {
[key: string]: string;
};
// Initialize variables to store the new props and styles
const componentProps: { [key: string]: unknown } = {};
const componentStyles: string[] = [];
// Pass through an existing className if it exists
if (mergedProps.className) componentStyles.push(mergedProps.className);
// Add the base style(s)
if (config?.css) componentStyles.push(flattenCss(config.css));
// Pass through the ref
if (ref) componentProps.ref = ref;
Object.keys(mergedProps).forEach((key) => {
// Apply any variant styles
if (config?.variants && config.variants.hasOwnProperty(key)) {
const variant = config.variants[key as keyof typeof config.variants];
if (variant && variant.hasOwnProperty(mergedProps[key])) {
const selector = variant[
mergedProps[key] as keyof typeof variant
] as CSS;
componentStyles.push(flattenCss(selector));
}
}
const isVariant =
config?.variants && config.variants.hasOwnProperty(key);
// Only pass through the prop if it's not a variant or been told to pass through
if (isVariant && !config?.passthrough?.includes(key as keyof V)) return;
componentProps[key] = mergedProps[key];
});
// Apply any compound variant styles
if (config?.compoundVariants) {
const matches = findMatchingCompoundVariants(
config.compoundVariants,
mergedProps
);
matches.forEach((match) => {
componentStyles.push(flattenCss(match.css as CSS));
});
}
componentProps.className = componentStyles.join(" ");
styledComponent.displayName = componentDisplayName(element);
return createElement(element, componentProps);
}
);
return styledComponent as PolymorphicComponent<E, V>;
};