-
-
Notifications
You must be signed in to change notification settings - Fork 449
/
Copy pathButton.tsx
111 lines (98 loc) · 2.99 KB
/
Button.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
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
"use client";
import type { ElementType } from "react";
import { forwardRef } from "react";
import type { PolymorphicComponentPropWithRef, PolymorphicRef } from "../../helpers/generic-as-prop";
import { get } from "../../helpers/get";
import { resolveProps } from "../../helpers/resolve-props";
import { useResolveTheme } from "../../helpers/resolve-theme";
import { twMerge } from "../../helpers/tailwind-merge";
import { useThemeProvider } from "../../theme/provider";
import type {
DynamicStringEnumKeysOf,
FlowbiteColors,
FlowbiteSizes,
FlowbiteStateColors,
ThemingProps,
} from "../../types";
import { ButtonBase } from "./ButtonBase";
import { useButtonGroupContext } from "./ButtonGroupContext";
import { buttonTheme } from "./theme";
export interface ButtonTheme {
base: string;
disabled: string;
fullSized: string;
grouped: string;
pill: string;
size: ButtonSizes;
// colors
color: ButtonColors;
outlineColor: ButtonOutlineColors;
}
export interface ButtonColors extends Omit<FlowbiteColors, keyof FlowbiteStateColors> {
[key: string]: string;
default: string;
alternative: string;
}
export interface ButtonOutlineColors extends Omit<ButtonColors, "alternative" | "light"> {
[key: string]: string;
}
export interface ButtonSizes extends Pick<FlowbiteSizes, "xs" | "sm" | "lg" | "xl"> {
[key: string]: string;
}
export type ButtonProps<T extends ElementType = "button"> = PolymorphicComponentPropWithRef<
T,
{
href?: string;
color?: DynamicStringEnumKeysOf<ButtonColors>;
fullSized?: boolean;
outline?: boolean;
pill?: boolean;
size?: DynamicStringEnumKeysOf<ButtonSizes>;
}
> &
ThemingProps<ButtonTheme>;
type ButtonComponentType = (<C extends ElementType = "button">(props: ButtonProps<C>) => JSX.Element) & {
displayName?: string;
};
export const Button = forwardRef(<T extends ElementType = "button">(props: ButtonProps<T>, ref: PolymorphicRef<T>) => {
const provider = useThemeProvider();
const theme = useResolveTheme(
[buttonTheme, provider.theme?.button, props.theme],
[get(provider.clearTheme, "button"), props.clearTheme],
[get(provider.applyTheme, "button"), props.applyTheme],
);
const {
children,
className,
color = "default",
disabled,
fullSized,
outline: _outline,
pill: _pill,
size = "md",
...restProps
} = resolveProps(props, provider.props?.button);
const buttonGroup = useButtonGroupContext();
const outline = buttonGroup?.outline ?? _outline;
const pill = buttonGroup?.pill ?? _pill;
return (
<ButtonBase
ref={ref}
disabled={disabled}
className={twMerge(
theme.base,
theme.size[size],
pill && theme.pill,
disabled && theme.disabled,
fullSized && theme.fullSized,
outline ? theme.outlineColor[color] : theme.color[color],
buttonGroup && theme.grouped,
className,
)}
{...restProps}
>
{children}
</ButtonBase>
);
}) as ButtonComponentType;
Button.displayName = "Button";