-
Notifications
You must be signed in to change notification settings - Fork 112
/
Copy pathColor.tsx
52 lines (50 loc) · 1.6 KB
/
Color.tsx
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
'use client';
import {
Children,
ComponentProps,
PropsWithChildren,
cloneElement,
isValidElement,
} from 'react';
import { useTheme } from 'styled-components';
import { appTheme } from '../AppTheme/appTheme';
type ColorProps<
TColorCategory extends keyof (typeof appTheme)['colors'],
TColorVariant extends keyof (typeof appTheme)['colors'][TColorCategory],
> = PropsWithChildren<{
/** If this component should inject the style value directly into the child component */
asChild?: boolean;
/** The color category */
colorCategory: TColorCategory;
/** The color variant, based on chosen `colorCategory` */
colorVariant: TColorVariant;
/** The color name, based on chosen `colorCategory` and `colorVariant` */
colorName: keyof (typeof appTheme)['colors'][TColorCategory][TColorVariant];
}>;
/**
* Component to wrap an element in order to change its text color.
*
* Sets the `color` style value to the chosen color
*/
export function Color<
TColorCategory extends keyof (typeof appTheme)['colors'],
TColorVariant extends keyof (typeof appTheme)['colors'][TColorCategory],
>({
colorCategory,
colorVariant,
colorName,
children,
asChild = true,
}: ColorProps<TColorCategory, TColorVariant>) {
const theme = useTheme();
const colorValue = theme.colors[colorCategory][colorVariant][
colorName
] as string;
const childElement = Children.only(children);
if (asChild && isValidElement<ComponentProps<any>>(childElement)) {
return cloneElement(childElement as any, {
style: { color: colorValue },
});
}
return <span style={{ color: colorValue }}>{children}</span>;
}