-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
89 lines (71 loc) · 2.25 KB
/
index.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
import type { ImageStyle, TextStyle, ViewStyle } from 'react-native';
export type StringToBoolean<T> = T extends 'true' | 'false' ? boolean : T;
export type Style = ViewStyle | TextStyle | ImageStyle;
export type VariantProps<Component extends (...args: any) => any> =
Parameters<Component>[0];
type CompoundVariant<V extends VariantShape> = {
[Variant in keyof V]?: StringToBoolean<keyof V[Variant]> | undefined;
} & {
style: Style;
};
type VariantShape = Record<string, Record<string, Style>>;
type VariantSchema<V extends VariantShape> = {
[Variant in keyof V]?: StringToBoolean<keyof V[Variant]> | undefined;
};
export type Config<V extends VariantShape = VariantShape> = {
base?: Style;
variants?: V;
defaultVariants?: VariantSchema<V>;
compoundVariants?: Array<CompoundVariant<V>>;
};
type Props<V> = V extends VariantShape
? VariantSchema<V> & {
style?: Style;
}
: never;
export const sv =
<V extends VariantShape = VariantShape>({
base,
defaultVariants,
variants,
compoundVariants = [],
}: Config<V>) =>
(_options?: Props<V>) => {
const styles: Style = {};
const options = _options || ({} as Props<V>);
if (base) {
Object.assign(styles, base);
}
if (defaultVariants) {
Object.keys(defaultVariants).forEach((key) => {
if (!options.hasOwnProperty(key) || options[key] === undefined) {
Object.assign(options, {
[key]: defaultVariants[key],
});
}
});
}
Object.entries(options || {}).forEach(([category, variantSelected]) => {
if (variants?.hasOwnProperty(category)) {
const categoryVariants = variants[category];
if (categoryVariants?.hasOwnProperty(String(variantSelected))) {
Object.assign(styles, categoryVariants[String(variantSelected)]);
}
}
});
compoundVariants.forEach((compound) => {
const { style, ...compoundVariantOptions } = compound;
if (
Object.entries(compoundVariantOptions).every(
([key, value]) => options[key] === value
)
) {
Object.assign(styles, style);
}
});
if (options.hasOwnProperty('style')) {
Object.assign(styles, options.style);
}
return styles;
};
export default sv;