@lp-labs/ui-components 0.0.0-stage → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +41 -0
- package/LICENSE +21 -0
- package/README.md +256 -2
- package/dist/cjs/components/Accordion.d.ts +78 -0
- package/dist/cjs/components/Accordion.js +78 -0
- package/dist/cjs/components/AdvancedComponents.d.ts +353 -0
- package/dist/cjs/components/AdvancedComponents.js +353 -0
- package/dist/cjs/components/Alert.d.ts +102 -0
- package/dist/cjs/components/Alert.js +102 -0
- package/dist/cjs/components/Avatar.d.ts +89 -0
- package/dist/cjs/components/Avatar.js +89 -0
- package/dist/cjs/components/Badge.d.ts +57 -0
- package/dist/cjs/components/Badge.js +57 -0
- package/dist/cjs/components/Breadcrumb.d.ts +50 -0
- package/dist/cjs/components/Breadcrumb.js +50 -0
- package/dist/cjs/components/Button.d.ts +77 -0
- package/dist/cjs/components/Button.js +77 -0
- package/dist/cjs/components/ButtonVariants.d.ts +261 -0
- package/dist/cjs/components/ButtonVariants.js +261 -0
- package/dist/cjs/components/Card.d.ts +56 -0
- package/dist/cjs/components/Card.js +56 -0
- package/dist/cjs/components/CardVariants.d.ts +267 -0
- package/dist/cjs/components/CardVariants.js +267 -0
- package/dist/cjs/components/Checkbox.d.ts +50 -0
- package/dist/cjs/components/Checkbox.js +50 -0
- package/dist/cjs/components/Chip.d.ts +104 -0
- package/dist/cjs/components/Chip.js +104 -0
- package/dist/cjs/components/DataDisplayComponents.d.ts +275 -0
- package/dist/cjs/components/DataDisplayComponents.js +275 -0
- package/dist/cjs/components/Divider.d.ts +77 -0
- package/dist/cjs/components/Divider.js +77 -0
- package/dist/cjs/components/Drawer.d.ts +142 -0
- package/dist/cjs/components/Drawer.js +142 -0
- package/dist/cjs/components/Dropdown.d.ts +139 -0
- package/dist/cjs/components/Dropdown.js +139 -0
- package/dist/cjs/components/Form.d.ts +41 -0
- package/dist/cjs/components/Form.js +41 -0
- package/dist/cjs/components/FormGroup.d.ts +58 -0
- package/dist/cjs/components/FormGroup.js +58 -0
- package/dist/cjs/components/FormInputVariants.d.ts +298 -0
- package/dist/cjs/components/FormInputVariants.js +298 -0
- package/dist/cjs/components/Image.d.ts +106 -0
- package/dist/cjs/components/Image.js +106 -0
- package/dist/cjs/components/Input.d.ts +65 -0
- package/dist/cjs/components/Input.js +65 -0
- package/dist/cjs/components/LayoutComponents.d.ts +258 -0
- package/dist/cjs/components/LayoutComponents.js +258 -0
- package/dist/cjs/components/Link.d.ts +71 -0
- package/dist/cjs/components/Link.js +71 -0
- package/dist/cjs/components/LoadingFeedbackComponents.d.ts +230 -0
- package/dist/cjs/components/LoadingFeedbackComponents.js +230 -0
- package/dist/cjs/components/Menu.d.ts +167 -0
- package/dist/cjs/components/Menu.js +167 -0
- package/dist/cjs/components/Modal.d.ts +145 -0
- package/dist/cjs/components/Modal.js +145 -0
- package/dist/cjs/components/ModalTypes.d.ts +288 -0
- package/dist/cjs/components/ModalTypes.js +288 -0
- package/dist/cjs/components/Navbar.d.ts +181 -0
- package/dist/cjs/components/Navbar.js +181 -0
- package/dist/cjs/components/NavigationComponents.d.ts +276 -0
- package/dist/cjs/components/NavigationComponents.js +276 -0
- package/dist/cjs/components/Pagination.d.ts +94 -0
- package/dist/cjs/components/Pagination.js +94 -0
- package/dist/cjs/components/Popover.d.ts +108 -0
- package/dist/cjs/components/Popover.js +108 -0
- package/dist/cjs/components/Progress.d.ts +68 -0
- package/dist/cjs/components/Progress.js +68 -0
- package/dist/cjs/components/Radio.d.ts +93 -0
- package/dist/cjs/components/Radio.js +93 -0
- package/dist/cjs/components/Rating.d.ts +82 -0
- package/dist/cjs/components/Rating.js +82 -0
- package/dist/cjs/components/Select.d.ts +74 -0
- package/dist/cjs/components/Select.js +74 -0
- package/dist/cjs/components/Sidebar.d.ts +174 -0
- package/dist/cjs/components/Sidebar.js +174 -0
- package/dist/cjs/components/Skeleton.d.ts +57 -0
- package/dist/cjs/components/Skeleton.js +57 -0
- package/dist/cjs/components/Slider.d.ts +64 -0
- package/dist/cjs/components/Slider.js +64 -0
- package/dist/cjs/components/Spinner.d.ts +70 -0
- package/dist/cjs/components/Spinner.js +70 -0
- package/dist/cjs/components/Stack.d.ts +75 -0
- package/dist/cjs/components/Stack.js +75 -0
- package/dist/cjs/components/Stepper.d.ts +150 -0
- package/dist/cjs/components/Stepper.js +150 -0
- package/dist/cjs/components/Table.d.ts +173 -0
- package/dist/cjs/components/Table.js +173 -0
- package/dist/cjs/components/Tabs.d.ts +104 -0
- package/dist/cjs/components/Tabs.js +104 -0
- package/dist/cjs/components/Tag.d.ts +74 -0
- package/dist/cjs/components/Tag.js +74 -0
- package/dist/cjs/components/Textarea.d.ts +75 -0
- package/dist/cjs/components/Textarea.js +75 -0
- package/dist/cjs/components/Timeline.d.ts +124 -0
- package/dist/cjs/components/Timeline.js +124 -0
- package/dist/cjs/components/Toast.d.ts +155 -0
- package/dist/cjs/components/Toast.js +155 -0
- package/dist/cjs/components/Toggle.d.ts +75 -0
- package/dist/cjs/components/Toggle.js +75 -0
- package/dist/cjs/components/Tooltip.d.ts +80 -0
- package/dist/cjs/components/Tooltip.js +80 -0
- package/dist/cjs/components/TypographyComponents.d.ts +265 -0
- package/dist/cjs/components/TypographyComponents.js +265 -0
- package/dist/cjs/components/UtilityComponents.d.ts +345 -0
- package/dist/cjs/components/UtilityComponents.js +345 -0
- package/dist/cjs/components/Video.d.ts +82 -0
- package/dist/cjs/components/Video.js +82 -0
- package/dist/cjs/components/index.d.ts +311 -0
- package/dist/cjs/components/index.js +311 -0
- package/dist/cjs/index.d.ts +5 -0
- package/dist/cjs/index.js +5 -0
- package/dist/cjs/styles/main.css +493 -0
- package/dist/cjs/theme/ThemeProvider.d.ts +185 -0
- package/dist/cjs/theme/ThemeProvider.js +185 -0
- package/dist/cjs/theme/index.d.ts +2 -0
- package/dist/cjs/theme/index.js +2 -0
- package/dist/cjs/utilities/classNames.d.ts +200 -0
- package/dist/cjs/utilities/classNames.js +200 -0
- package/dist/cjs/utilities/index.d.ts +3 -0
- package/dist/cjs/utilities/index.js +3 -0
- package/dist/cjs/utilities/styles.d.ts +94 -0
- package/dist/cjs/utilities/styles.js +94 -0
- package/dist/esm/components/Accordion.d.ts +78 -0
- package/dist/esm/components/Accordion.js +78 -0
- package/dist/esm/components/AdvancedComponents.d.ts +353 -0
- package/dist/esm/components/AdvancedComponents.js +353 -0
- package/dist/esm/components/Alert.d.ts +102 -0
- package/dist/esm/components/Alert.js +102 -0
- package/dist/esm/components/Avatar.d.ts +89 -0
- package/dist/esm/components/Avatar.js +89 -0
- package/dist/esm/components/Badge.d.ts +57 -0
- package/dist/esm/components/Badge.js +57 -0
- package/dist/esm/components/Breadcrumb.d.ts +50 -0
- package/dist/esm/components/Breadcrumb.js +50 -0
- package/dist/esm/components/Button.d.ts +77 -0
- package/dist/esm/components/Button.js +77 -0
- package/dist/esm/components/ButtonVariants.d.ts +261 -0
- package/dist/esm/components/ButtonVariants.js +261 -0
- package/dist/esm/components/Card.d.ts +56 -0
- package/dist/esm/components/Card.js +56 -0
- package/dist/esm/components/CardVariants.d.ts +267 -0
- package/dist/esm/components/CardVariants.js +267 -0
- package/dist/esm/components/Checkbox.d.ts +50 -0
- package/dist/esm/components/Checkbox.js +50 -0
- package/dist/esm/components/Chip.d.ts +104 -0
- package/dist/esm/components/Chip.js +104 -0
- package/dist/esm/components/DataDisplayComponents.d.ts +275 -0
- package/dist/esm/components/DataDisplayComponents.js +275 -0
- package/dist/esm/components/Divider.d.ts +77 -0
- package/dist/esm/components/Divider.js +77 -0
- package/dist/esm/components/Drawer.d.ts +142 -0
- package/dist/esm/components/Drawer.js +142 -0
- package/dist/esm/components/Dropdown.d.ts +139 -0
- package/dist/esm/components/Dropdown.js +139 -0
- package/dist/esm/components/Form.d.ts +41 -0
- package/dist/esm/components/Form.js +41 -0
- package/dist/esm/components/FormGroup.d.ts +58 -0
- package/dist/esm/components/FormGroup.js +58 -0
- package/dist/esm/components/FormInputVariants.d.ts +298 -0
- package/dist/esm/components/FormInputVariants.js +298 -0
- package/dist/esm/components/Image.d.ts +106 -0
- package/dist/esm/components/Image.js +106 -0
- package/dist/esm/components/Input.d.ts +65 -0
- package/dist/esm/components/Input.js +65 -0
- package/dist/esm/components/LayoutComponents.d.ts +258 -0
- package/dist/esm/components/LayoutComponents.js +258 -0
- package/dist/esm/components/Link.d.ts +71 -0
- package/dist/esm/components/Link.js +71 -0
- package/dist/esm/components/LoadingFeedbackComponents.d.ts +230 -0
- package/dist/esm/components/LoadingFeedbackComponents.js +230 -0
- package/dist/esm/components/Menu.d.ts +167 -0
- package/dist/esm/components/Menu.js +167 -0
- package/dist/esm/components/Modal.d.ts +145 -0
- package/dist/esm/components/Modal.js +145 -0
- package/dist/esm/components/ModalTypes.d.ts +288 -0
- package/dist/esm/components/ModalTypes.js +288 -0
- package/dist/esm/components/Navbar.d.ts +181 -0
- package/dist/esm/components/Navbar.js +181 -0
- package/dist/esm/components/NavigationComponents.d.ts +276 -0
- package/dist/esm/components/NavigationComponents.js +276 -0
- package/dist/esm/components/Pagination.d.ts +94 -0
- package/dist/esm/components/Pagination.js +94 -0
- package/dist/esm/components/Popover.d.ts +108 -0
- package/dist/esm/components/Popover.js +108 -0
- package/dist/esm/components/Progress.d.ts +68 -0
- package/dist/esm/components/Progress.js +68 -0
- package/dist/esm/components/Radio.d.ts +93 -0
- package/dist/esm/components/Radio.js +93 -0
- package/dist/esm/components/Rating.d.ts +82 -0
- package/dist/esm/components/Rating.js +82 -0
- package/dist/esm/components/Select.d.ts +74 -0
- package/dist/esm/components/Select.js +74 -0
- package/dist/esm/components/Sidebar.d.ts +174 -0
- package/dist/esm/components/Sidebar.js +174 -0
- package/dist/esm/components/Skeleton.d.ts +57 -0
- package/dist/esm/components/Skeleton.js +57 -0
- package/dist/esm/components/Slider.d.ts +64 -0
- package/dist/esm/components/Slider.js +64 -0
- package/dist/esm/components/Spinner.d.ts +70 -0
- package/dist/esm/components/Spinner.js +70 -0
- package/dist/esm/components/Stack.d.ts +75 -0
- package/dist/esm/components/Stack.js +75 -0
- package/dist/esm/components/Stepper.d.ts +150 -0
- package/dist/esm/components/Stepper.js +150 -0
- package/dist/esm/components/Table.d.ts +173 -0
- package/dist/esm/components/Table.js +173 -0
- package/dist/esm/components/Tabs.d.ts +104 -0
- package/dist/esm/components/Tabs.js +104 -0
- package/dist/esm/components/Tag.d.ts +74 -0
- package/dist/esm/components/Tag.js +74 -0
- package/dist/esm/components/Textarea.d.ts +75 -0
- package/dist/esm/components/Textarea.js +75 -0
- package/dist/esm/components/Timeline.d.ts +124 -0
- package/dist/esm/components/Timeline.js +124 -0
- package/dist/esm/components/Toast.d.ts +155 -0
- package/dist/esm/components/Toast.js +155 -0
- package/dist/esm/components/Toggle.d.ts +75 -0
- package/dist/esm/components/Toggle.js +75 -0
- package/dist/esm/components/Tooltip.d.ts +80 -0
- package/dist/esm/components/Tooltip.js +80 -0
- package/dist/esm/components/TypographyComponents.d.ts +265 -0
- package/dist/esm/components/TypographyComponents.js +265 -0
- package/dist/esm/components/UtilityComponents.d.ts +345 -0
- package/dist/esm/components/UtilityComponents.js +345 -0
- package/dist/esm/components/Video.d.ts +82 -0
- package/dist/esm/components/Video.js +82 -0
- package/dist/esm/components/index.d.ts +311 -0
- package/dist/esm/components/index.js +311 -0
- package/dist/esm/index.d.ts +5 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/styles/main.css +493 -0
- package/dist/esm/theme/ThemeProvider.d.ts +185 -0
- package/dist/esm/theme/ThemeProvider.js +185 -0
- package/dist/esm/theme/index.d.ts +2 -0
- package/dist/esm/theme/index.js +2 -0
- package/dist/esm/utilities/classNames.d.ts +200 -0
- package/dist/esm/utilities/classNames.js +200 -0
- package/dist/esm/utilities/index.d.ts +3 -0
- package/dist/esm/utilities/index.js +3 -0
- package/dist/esm/utilities/styles.d.ts +94 -0
- package/dist/esm/utilities/styles.js +94 -0
- package/dist/styles/main.css +493 -0
- package/package.json +124 -6
- package/src/styles/main.css +493 -0
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
export interface ButtonVariantProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
4
|
+
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
5
|
+
state?: 'default' | 'hover' | 'focus' | 'active' | 'disabled';
|
|
6
|
+
icon?: React.ReactNode;
|
|
7
|
+
iconPosition?: 'left' | 'right';
|
|
8
|
+
children?: React.ReactNode;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const ButtonPrimary: React.FC<ButtonVariantProps> = ({
|
|
12
|
+
size = 'md',
|
|
13
|
+
state = 'default',
|
|
14
|
+
icon,
|
|
15
|
+
iconPosition = 'left',
|
|
16
|
+
children,
|
|
17
|
+
className = '',
|
|
18
|
+
...props
|
|
19
|
+
}) => {
|
|
20
|
+
const sizeClass = {
|
|
21
|
+
xs: 'px-2 py-1 text-xs',
|
|
22
|
+
sm: 'px-3 py-1.5 text-sm',
|
|
23
|
+
md: 'px-4 py-2 text-base',
|
|
24
|
+
lg: 'px-6 py-3 text-lg',
|
|
25
|
+
xl: 'px-8 py-4 text-xl',
|
|
26
|
+
}[size];
|
|
27
|
+
|
|
28
|
+
const stateClass = {
|
|
29
|
+
default: 'bg-blue-600 text-white',
|
|
30
|
+
hover: 'bg-blue-700 text-white',
|
|
31
|
+
focus: 'bg-blue-800 text-white outline outline-2 outline-offset-2 outline-blue-300',
|
|
32
|
+
active: 'bg-blue-900 text-white',
|
|
33
|
+
disabled: 'bg-gray-400 text-gray-600 cursor-not-allowed',
|
|
34
|
+
}[state];
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<button
|
|
38
|
+
className={`inline-flex items-center gap-2 rounded-lg font-medium transition-colors ${sizeClass} ${stateClass} ${className}`}
|
|
39
|
+
{...props}
|
|
40
|
+
>
|
|
41
|
+
{icon && iconPosition === 'left' && <span>{icon}</span>}
|
|
42
|
+
{children}
|
|
43
|
+
{icon && iconPosition === 'right' && <span>{icon}</span>}
|
|
44
|
+
</button>
|
|
45
|
+
);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export const ButtonSecondary: React.FC<ButtonVariantProps> = ({
|
|
49
|
+
size = 'md',
|
|
50
|
+
state = 'default',
|
|
51
|
+
icon,
|
|
52
|
+
iconPosition = 'left',
|
|
53
|
+
children,
|
|
54
|
+
className = '',
|
|
55
|
+
...props
|
|
56
|
+
}) => {
|
|
57
|
+
const sizeClass = {
|
|
58
|
+
xs: 'px-2 py-1 text-xs',
|
|
59
|
+
sm: 'px-3 py-1.5 text-sm',
|
|
60
|
+
md: 'px-4 py-2 text-base',
|
|
61
|
+
lg: 'px-6 py-3 text-lg',
|
|
62
|
+
xl: 'px-8 py-4 text-xl',
|
|
63
|
+
}[size];
|
|
64
|
+
|
|
65
|
+
const stateClass = {
|
|
66
|
+
default: 'bg-gray-200 text-gray-900',
|
|
67
|
+
hover: 'bg-gray-300 text-gray-900',
|
|
68
|
+
focus: 'bg-gray-400 text-gray-900 outline outline-2 outline-offset-2 outline-gray-300',
|
|
69
|
+
active: 'bg-gray-500 text-white',
|
|
70
|
+
disabled: 'bg-gray-100 text-gray-400 cursor-not-allowed',
|
|
71
|
+
}[state];
|
|
72
|
+
|
|
73
|
+
return (
|
|
74
|
+
<button
|
|
75
|
+
className={`inline-flex items-center gap-2 rounded-lg font-medium transition-colors ${sizeClass} ${stateClass} ${className}`}
|
|
76
|
+
{...props}
|
|
77
|
+
>
|
|
78
|
+
{icon && iconPosition === 'left' && <span>{icon}</span>}
|
|
79
|
+
{children}
|
|
80
|
+
{icon && iconPosition === 'right' && <span>{icon}</span>}
|
|
81
|
+
</button>
|
|
82
|
+
);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export const ButtonOutline: React.FC<ButtonVariantProps> = ({
|
|
86
|
+
size = 'md',
|
|
87
|
+
state = 'default',
|
|
88
|
+
icon,
|
|
89
|
+
iconPosition = 'left',
|
|
90
|
+
children,
|
|
91
|
+
className = '',
|
|
92
|
+
...props
|
|
93
|
+
}) => {
|
|
94
|
+
const sizeClass = {
|
|
95
|
+
xs: 'px-2 py-1 text-xs',
|
|
96
|
+
sm: 'px-3 py-1.5 text-sm',
|
|
97
|
+
md: 'px-4 py-2 text-base',
|
|
98
|
+
lg: 'px-6 py-3 text-lg',
|
|
99
|
+
xl: 'px-8 py-4 text-xl',
|
|
100
|
+
}[size];
|
|
101
|
+
|
|
102
|
+
const stateClass = {
|
|
103
|
+
default: 'border-2 border-blue-600 text-blue-600 bg-white',
|
|
104
|
+
hover: 'border-2 border-blue-700 text-blue-700 bg-blue-50',
|
|
105
|
+
focus: 'border-2 border-blue-800 text-blue-800 bg-blue-50 outline outline-2 outline-offset-2 outline-blue-300',
|
|
106
|
+
active: 'border-2 border-blue-900 text-white bg-blue-900',
|
|
107
|
+
disabled: 'border-2 border-gray-300 text-gray-400 bg-white cursor-not-allowed',
|
|
108
|
+
}[state];
|
|
109
|
+
|
|
110
|
+
return (
|
|
111
|
+
<button
|
|
112
|
+
className={`inline-flex items-center gap-2 rounded-lg font-medium transition-colors ${sizeClass} ${stateClass} ${className}`}
|
|
113
|
+
{...props}
|
|
114
|
+
>
|
|
115
|
+
{icon && iconPosition === 'left' && <span>{icon}</span>}
|
|
116
|
+
{children}
|
|
117
|
+
{icon && iconPosition === 'right' && <span>{icon}</span>}
|
|
118
|
+
</button>
|
|
119
|
+
);
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
export const ButtonGhost: React.FC<ButtonVariantProps> = ({
|
|
123
|
+
size = 'md',
|
|
124
|
+
state = 'default',
|
|
125
|
+
icon,
|
|
126
|
+
iconPosition = 'left',
|
|
127
|
+
children,
|
|
128
|
+
className = '',
|
|
129
|
+
...props
|
|
130
|
+
}) => {
|
|
131
|
+
const sizeClass = {
|
|
132
|
+
xs: 'px-2 py-1 text-xs',
|
|
133
|
+
sm: 'px-3 py-1.5 text-sm',
|
|
134
|
+
md: 'px-4 py-2 text-base',
|
|
135
|
+
lg: 'px-6 py-3 text-lg',
|
|
136
|
+
xl: 'px-8 py-4 text-xl',
|
|
137
|
+
}[size];
|
|
138
|
+
|
|
139
|
+
const stateClass = {
|
|
140
|
+
default: 'bg-transparent text-gray-700 hover:bg-gray-100',
|
|
141
|
+
hover: 'bg-gray-100 text-gray-900',
|
|
142
|
+
focus: 'bg-gray-200 text-gray-900 outline outline-2 outline-offset-2 outline-gray-300',
|
|
143
|
+
active: 'bg-gray-300 text-gray-900',
|
|
144
|
+
disabled: 'text-gray-400 cursor-not-allowed',
|
|
145
|
+
}[state];
|
|
146
|
+
|
|
147
|
+
return (
|
|
148
|
+
<button
|
|
149
|
+
className={`inline-flex items-center gap-2 rounded-lg font-medium transition-colors ${sizeClass} ${stateClass} ${className}`}
|
|
150
|
+
{...props}
|
|
151
|
+
>
|
|
152
|
+
{icon && iconPosition === 'left' && <span>{icon}</span>}
|
|
153
|
+
{children}
|
|
154
|
+
{icon && iconPosition === 'right' && <span>{icon}</span>}
|
|
155
|
+
</button>
|
|
156
|
+
);
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
export const ButtonLink: React.FC<ButtonVariantProps> = ({
|
|
160
|
+
size = 'md',
|
|
161
|
+
state = 'default',
|
|
162
|
+
icon,
|
|
163
|
+
iconPosition = 'left',
|
|
164
|
+
children,
|
|
165
|
+
className = '',
|
|
166
|
+
...props
|
|
167
|
+
}) => {
|
|
168
|
+
const sizeClass = {
|
|
169
|
+
xs: 'text-xs',
|
|
170
|
+
sm: 'text-sm',
|
|
171
|
+
md: 'text-base',
|
|
172
|
+
lg: 'text-lg',
|
|
173
|
+
xl: 'text-xl',
|
|
174
|
+
}[size];
|
|
175
|
+
|
|
176
|
+
const stateClass = {
|
|
177
|
+
default: 'bg-transparent text-blue-600 underline',
|
|
178
|
+
hover: 'bg-transparent text-blue-700 underline',
|
|
179
|
+
focus: 'bg-transparent text-blue-800 underline outline outline-2 outline-offset-2 outline-blue-300',
|
|
180
|
+
active: 'bg-transparent text-blue-900',
|
|
181
|
+
disabled: 'text-gray-400 cursor-not-allowed no-underline',
|
|
182
|
+
}[state];
|
|
183
|
+
|
|
184
|
+
return (
|
|
185
|
+
<button
|
|
186
|
+
className={`inline-flex items-center gap-2 font-medium transition-colors ${sizeClass} ${stateClass} ${className}`}
|
|
187
|
+
{...props}
|
|
188
|
+
>
|
|
189
|
+
{icon && iconPosition === 'left' && <span>{icon}</span>}
|
|
190
|
+
{children}
|
|
191
|
+
{icon && iconPosition === 'right' && <span>{icon}</span>}
|
|
192
|
+
</button>
|
|
193
|
+
);
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
export const ButtonIcon: React.FC<ButtonVariantProps> = ({
|
|
197
|
+
size = 'md',
|
|
198
|
+
state = 'default',
|
|
199
|
+
icon,
|
|
200
|
+
className = '',
|
|
201
|
+
...props
|
|
202
|
+
}) => {
|
|
203
|
+
const sizeClass = {
|
|
204
|
+
xs: 'p-1 text-xs',
|
|
205
|
+
sm: 'p-1.5 text-sm',
|
|
206
|
+
md: 'p-2 text-base',
|
|
207
|
+
lg: 'p-3 text-lg',
|
|
208
|
+
xl: 'p-4 text-xl',
|
|
209
|
+
}[size];
|
|
210
|
+
|
|
211
|
+
const stateClass = {
|
|
212
|
+
default: 'bg-white text-gray-700 border border-gray-300',
|
|
213
|
+
hover: 'bg-gray-100 text-gray-900 border border-gray-400',
|
|
214
|
+
focus: 'bg-white text-gray-900 border border-gray-500 outline outline-2 outline-offset-2 outline-blue-300',
|
|
215
|
+
active: 'bg-gray-200 text-gray-900',
|
|
216
|
+
disabled: 'bg-gray-50 text-gray-300 border border-gray-200 cursor-not-allowed',
|
|
217
|
+
}[state];
|
|
218
|
+
|
|
219
|
+
return (
|
|
220
|
+
<button
|
|
221
|
+
className={`inline-flex items-center justify-center rounded-lg transition-colors ${sizeClass} ${stateClass} ${className}`}
|
|
222
|
+
{...props}
|
|
223
|
+
>
|
|
224
|
+
{icon}
|
|
225
|
+
</button>
|
|
226
|
+
);
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
export const ButtonLoading: React.FC<ButtonVariantProps & { loading?: boolean }> = ({
|
|
230
|
+
size = 'md',
|
|
231
|
+
state = 'default',
|
|
232
|
+
icon,
|
|
233
|
+
loading = false,
|
|
234
|
+
children,
|
|
235
|
+
className = '',
|
|
236
|
+
...props
|
|
237
|
+
}) => {
|
|
238
|
+
const sizeClass = {
|
|
239
|
+
xs: 'px-2 py-1 text-xs',
|
|
240
|
+
sm: 'px-3 py-1.5 text-sm',
|
|
241
|
+
md: 'px-4 py-2 text-base',
|
|
242
|
+
lg: 'px-6 py-3 text-lg',
|
|
243
|
+
xl: 'px-8 py-4 text-xl',
|
|
244
|
+
}[size];
|
|
245
|
+
|
|
246
|
+
const baseClass = loading
|
|
247
|
+
? 'bg-blue-600 text-white cursor-wait opacity-75'
|
|
248
|
+
: 'bg-blue-600 text-white hover:bg-blue-700';
|
|
249
|
+
|
|
250
|
+
return (
|
|
251
|
+
<button
|
|
252
|
+
className={`inline-flex items-center gap-2 rounded-lg font-medium transition-colors ${sizeClass} ${baseClass} ${className}`}
|
|
253
|
+
disabled={loading}
|
|
254
|
+
{...props}
|
|
255
|
+
>
|
|
256
|
+
{loading && <span className="animate-spin">⌛</span>}
|
|
257
|
+
{!loading && icon && <span>{icon}</span>}
|
|
258
|
+
{children}
|
|
259
|
+
</button>
|
|
260
|
+
);
|
|
261
|
+
};
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
export interface ButtonVariantProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
4
|
+
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
5
|
+
state?: 'default' | 'hover' | 'focus' | 'active' | 'disabled';
|
|
6
|
+
icon?: React.ReactNode;
|
|
7
|
+
iconPosition?: 'left' | 'right';
|
|
8
|
+
children?: React.ReactNode;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const ButtonPrimary: React.FC<ButtonVariantProps> = ({
|
|
12
|
+
size = 'md',
|
|
13
|
+
state = 'default',
|
|
14
|
+
icon,
|
|
15
|
+
iconPosition = 'left',
|
|
16
|
+
children,
|
|
17
|
+
className = '',
|
|
18
|
+
...props
|
|
19
|
+
}) => {
|
|
20
|
+
const sizeClass = {
|
|
21
|
+
xs: 'px-2 py-1 text-xs',
|
|
22
|
+
sm: 'px-3 py-1.5 text-sm',
|
|
23
|
+
md: 'px-4 py-2 text-base',
|
|
24
|
+
lg: 'px-6 py-3 text-lg',
|
|
25
|
+
xl: 'px-8 py-4 text-xl',
|
|
26
|
+
}[size];
|
|
27
|
+
|
|
28
|
+
const stateClass = {
|
|
29
|
+
default: 'bg-blue-600 text-white',
|
|
30
|
+
hover: 'bg-blue-700 text-white',
|
|
31
|
+
focus: 'bg-blue-800 text-white outline outline-2 outline-offset-2 outline-blue-300',
|
|
32
|
+
active: 'bg-blue-900 text-white',
|
|
33
|
+
disabled: 'bg-gray-400 text-gray-600 cursor-not-allowed',
|
|
34
|
+
}[state];
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<button
|
|
38
|
+
className={`inline-flex items-center gap-2 rounded-lg font-medium transition-colors ${sizeClass} ${stateClass} ${className}`}
|
|
39
|
+
{...props}
|
|
40
|
+
>
|
|
41
|
+
{icon && iconPosition === 'left' && <span>{icon}</span>}
|
|
42
|
+
{children}
|
|
43
|
+
{icon && iconPosition === 'right' && <span>{icon}</span>}
|
|
44
|
+
</button>
|
|
45
|
+
);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export const ButtonSecondary: React.FC<ButtonVariantProps> = ({
|
|
49
|
+
size = 'md',
|
|
50
|
+
state = 'default',
|
|
51
|
+
icon,
|
|
52
|
+
iconPosition = 'left',
|
|
53
|
+
children,
|
|
54
|
+
className = '',
|
|
55
|
+
...props
|
|
56
|
+
}) => {
|
|
57
|
+
const sizeClass = {
|
|
58
|
+
xs: 'px-2 py-1 text-xs',
|
|
59
|
+
sm: 'px-3 py-1.5 text-sm',
|
|
60
|
+
md: 'px-4 py-2 text-base',
|
|
61
|
+
lg: 'px-6 py-3 text-lg',
|
|
62
|
+
xl: 'px-8 py-4 text-xl',
|
|
63
|
+
}[size];
|
|
64
|
+
|
|
65
|
+
const stateClass = {
|
|
66
|
+
default: 'bg-gray-200 text-gray-900',
|
|
67
|
+
hover: 'bg-gray-300 text-gray-900',
|
|
68
|
+
focus: 'bg-gray-400 text-gray-900 outline outline-2 outline-offset-2 outline-gray-300',
|
|
69
|
+
active: 'bg-gray-500 text-white',
|
|
70
|
+
disabled: 'bg-gray-100 text-gray-400 cursor-not-allowed',
|
|
71
|
+
}[state];
|
|
72
|
+
|
|
73
|
+
return (
|
|
74
|
+
<button
|
|
75
|
+
className={`inline-flex items-center gap-2 rounded-lg font-medium transition-colors ${sizeClass} ${stateClass} ${className}`}
|
|
76
|
+
{...props}
|
|
77
|
+
>
|
|
78
|
+
{icon && iconPosition === 'left' && <span>{icon}</span>}
|
|
79
|
+
{children}
|
|
80
|
+
{icon && iconPosition === 'right' && <span>{icon}</span>}
|
|
81
|
+
</button>
|
|
82
|
+
);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export const ButtonOutline: React.FC<ButtonVariantProps> = ({
|
|
86
|
+
size = 'md',
|
|
87
|
+
state = 'default',
|
|
88
|
+
icon,
|
|
89
|
+
iconPosition = 'left',
|
|
90
|
+
children,
|
|
91
|
+
className = '',
|
|
92
|
+
...props
|
|
93
|
+
}) => {
|
|
94
|
+
const sizeClass = {
|
|
95
|
+
xs: 'px-2 py-1 text-xs',
|
|
96
|
+
sm: 'px-3 py-1.5 text-sm',
|
|
97
|
+
md: 'px-4 py-2 text-base',
|
|
98
|
+
lg: 'px-6 py-3 text-lg',
|
|
99
|
+
xl: 'px-8 py-4 text-xl',
|
|
100
|
+
}[size];
|
|
101
|
+
|
|
102
|
+
const stateClass = {
|
|
103
|
+
default: 'border-2 border-blue-600 text-blue-600 bg-white',
|
|
104
|
+
hover: 'border-2 border-blue-700 text-blue-700 bg-blue-50',
|
|
105
|
+
focus: 'border-2 border-blue-800 text-blue-800 bg-blue-50 outline outline-2 outline-offset-2 outline-blue-300',
|
|
106
|
+
active: 'border-2 border-blue-900 text-white bg-blue-900',
|
|
107
|
+
disabled: 'border-2 border-gray-300 text-gray-400 bg-white cursor-not-allowed',
|
|
108
|
+
}[state];
|
|
109
|
+
|
|
110
|
+
return (
|
|
111
|
+
<button
|
|
112
|
+
className={`inline-flex items-center gap-2 rounded-lg font-medium transition-colors ${sizeClass} ${stateClass} ${className}`}
|
|
113
|
+
{...props}
|
|
114
|
+
>
|
|
115
|
+
{icon && iconPosition === 'left' && <span>{icon}</span>}
|
|
116
|
+
{children}
|
|
117
|
+
{icon && iconPosition === 'right' && <span>{icon}</span>}
|
|
118
|
+
</button>
|
|
119
|
+
);
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
export const ButtonGhost: React.FC<ButtonVariantProps> = ({
|
|
123
|
+
size = 'md',
|
|
124
|
+
state = 'default',
|
|
125
|
+
icon,
|
|
126
|
+
iconPosition = 'left',
|
|
127
|
+
children,
|
|
128
|
+
className = '',
|
|
129
|
+
...props
|
|
130
|
+
}) => {
|
|
131
|
+
const sizeClass = {
|
|
132
|
+
xs: 'px-2 py-1 text-xs',
|
|
133
|
+
sm: 'px-3 py-1.5 text-sm',
|
|
134
|
+
md: 'px-4 py-2 text-base',
|
|
135
|
+
lg: 'px-6 py-3 text-lg',
|
|
136
|
+
xl: 'px-8 py-4 text-xl',
|
|
137
|
+
}[size];
|
|
138
|
+
|
|
139
|
+
const stateClass = {
|
|
140
|
+
default: 'bg-transparent text-gray-700 hover:bg-gray-100',
|
|
141
|
+
hover: 'bg-gray-100 text-gray-900',
|
|
142
|
+
focus: 'bg-gray-200 text-gray-900 outline outline-2 outline-offset-2 outline-gray-300',
|
|
143
|
+
active: 'bg-gray-300 text-gray-900',
|
|
144
|
+
disabled: 'text-gray-400 cursor-not-allowed',
|
|
145
|
+
}[state];
|
|
146
|
+
|
|
147
|
+
return (
|
|
148
|
+
<button
|
|
149
|
+
className={`inline-flex items-center gap-2 rounded-lg font-medium transition-colors ${sizeClass} ${stateClass} ${className}`}
|
|
150
|
+
{...props}
|
|
151
|
+
>
|
|
152
|
+
{icon && iconPosition === 'left' && <span>{icon}</span>}
|
|
153
|
+
{children}
|
|
154
|
+
{icon && iconPosition === 'right' && <span>{icon}</span>}
|
|
155
|
+
</button>
|
|
156
|
+
);
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
export const ButtonLink: React.FC<ButtonVariantProps> = ({
|
|
160
|
+
size = 'md',
|
|
161
|
+
state = 'default',
|
|
162
|
+
icon,
|
|
163
|
+
iconPosition = 'left',
|
|
164
|
+
children,
|
|
165
|
+
className = '',
|
|
166
|
+
...props
|
|
167
|
+
}) => {
|
|
168
|
+
const sizeClass = {
|
|
169
|
+
xs: 'text-xs',
|
|
170
|
+
sm: 'text-sm',
|
|
171
|
+
md: 'text-base',
|
|
172
|
+
lg: 'text-lg',
|
|
173
|
+
xl: 'text-xl',
|
|
174
|
+
}[size];
|
|
175
|
+
|
|
176
|
+
const stateClass = {
|
|
177
|
+
default: 'bg-transparent text-blue-600 underline',
|
|
178
|
+
hover: 'bg-transparent text-blue-700 underline',
|
|
179
|
+
focus: 'bg-transparent text-blue-800 underline outline outline-2 outline-offset-2 outline-blue-300',
|
|
180
|
+
active: 'bg-transparent text-blue-900',
|
|
181
|
+
disabled: 'text-gray-400 cursor-not-allowed no-underline',
|
|
182
|
+
}[state];
|
|
183
|
+
|
|
184
|
+
return (
|
|
185
|
+
<button
|
|
186
|
+
className={`inline-flex items-center gap-2 font-medium transition-colors ${sizeClass} ${stateClass} ${className}`}
|
|
187
|
+
{...props}
|
|
188
|
+
>
|
|
189
|
+
{icon && iconPosition === 'left' && <span>{icon}</span>}
|
|
190
|
+
{children}
|
|
191
|
+
{icon && iconPosition === 'right' && <span>{icon}</span>}
|
|
192
|
+
</button>
|
|
193
|
+
);
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
export const ButtonIcon: React.FC<ButtonVariantProps> = ({
|
|
197
|
+
size = 'md',
|
|
198
|
+
state = 'default',
|
|
199
|
+
icon,
|
|
200
|
+
className = '',
|
|
201
|
+
...props
|
|
202
|
+
}) => {
|
|
203
|
+
const sizeClass = {
|
|
204
|
+
xs: 'p-1 text-xs',
|
|
205
|
+
sm: 'p-1.5 text-sm',
|
|
206
|
+
md: 'p-2 text-base',
|
|
207
|
+
lg: 'p-3 text-lg',
|
|
208
|
+
xl: 'p-4 text-xl',
|
|
209
|
+
}[size];
|
|
210
|
+
|
|
211
|
+
const stateClass = {
|
|
212
|
+
default: 'bg-white text-gray-700 border border-gray-300',
|
|
213
|
+
hover: 'bg-gray-100 text-gray-900 border border-gray-400',
|
|
214
|
+
focus: 'bg-white text-gray-900 border border-gray-500 outline outline-2 outline-offset-2 outline-blue-300',
|
|
215
|
+
active: 'bg-gray-200 text-gray-900',
|
|
216
|
+
disabled: 'bg-gray-50 text-gray-300 border border-gray-200 cursor-not-allowed',
|
|
217
|
+
}[state];
|
|
218
|
+
|
|
219
|
+
return (
|
|
220
|
+
<button
|
|
221
|
+
className={`inline-flex items-center justify-center rounded-lg transition-colors ${sizeClass} ${stateClass} ${className}`}
|
|
222
|
+
{...props}
|
|
223
|
+
>
|
|
224
|
+
{icon}
|
|
225
|
+
</button>
|
|
226
|
+
);
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
export const ButtonLoading: React.FC<ButtonVariantProps & { loading?: boolean }> = ({
|
|
230
|
+
size = 'md',
|
|
231
|
+
state = 'default',
|
|
232
|
+
icon,
|
|
233
|
+
loading = false,
|
|
234
|
+
children,
|
|
235
|
+
className = '',
|
|
236
|
+
...props
|
|
237
|
+
}) => {
|
|
238
|
+
const sizeClass = {
|
|
239
|
+
xs: 'px-2 py-1 text-xs',
|
|
240
|
+
sm: 'px-3 py-1.5 text-sm',
|
|
241
|
+
md: 'px-4 py-2 text-base',
|
|
242
|
+
lg: 'px-6 py-3 text-lg',
|
|
243
|
+
xl: 'px-8 py-4 text-xl',
|
|
244
|
+
}[size];
|
|
245
|
+
|
|
246
|
+
const baseClass = loading
|
|
247
|
+
? 'bg-blue-600 text-white cursor-wait opacity-75'
|
|
248
|
+
: 'bg-blue-600 text-white hover:bg-blue-700';
|
|
249
|
+
|
|
250
|
+
return (
|
|
251
|
+
<button
|
|
252
|
+
className={`inline-flex items-center gap-2 rounded-lg font-medium transition-colors ${sizeClass} ${baseClass} ${className}`}
|
|
253
|
+
disabled={loading}
|
|
254
|
+
{...props}
|
|
255
|
+
>
|
|
256
|
+
{loading && <span className="animate-spin">⌛</span>}
|
|
257
|
+
{!loading && icon && <span>{icon}</span>}
|
|
258
|
+
{children}
|
|
259
|
+
</button>
|
|
260
|
+
);
|
|
261
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { cn } from '../utilities/classNames';
|
|
3
|
+
|
|
4
|
+
export interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
5
|
+
elevation?: 'none' | 'sm' | 'md' | 'lg';
|
|
6
|
+
padding?: 'sm' | 'md' | 'lg';
|
|
7
|
+
border?: boolean;
|
|
8
|
+
interactive?: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const elevationStyles = {
|
|
12
|
+
none: '',
|
|
13
|
+
sm: 'shadow-sm',
|
|
14
|
+
md: 'shadow-md',
|
|
15
|
+
lg: 'shadow-lg',
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const paddingStyles = {
|
|
19
|
+
sm: 'p-3',
|
|
20
|
+
md: 'p-6',
|
|
21
|
+
lg: 'p-8',
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const Card = React.forwardRef<HTMLDivElement, CardProps>(
|
|
25
|
+
(
|
|
26
|
+
{
|
|
27
|
+
elevation = 'md',
|
|
28
|
+
padding = 'md',
|
|
29
|
+
border = false,
|
|
30
|
+
interactive = false,
|
|
31
|
+
className,
|
|
32
|
+
children,
|
|
33
|
+
...props
|
|
34
|
+
},
|
|
35
|
+
ref,
|
|
36
|
+
) => {
|
|
37
|
+
return (
|
|
38
|
+
<div
|
|
39
|
+
ref={ref}
|
|
40
|
+
className={cn(
|
|
41
|
+
'bg-white rounded-lg',
|
|
42
|
+
elevationStyles[elevation],
|
|
43
|
+
paddingStyles[padding],
|
|
44
|
+
border && 'border border-gray-200',
|
|
45
|
+
interactive && 'cursor-pointer hover:shadow-lg transition-shadow duration-200',
|
|
46
|
+
className,
|
|
47
|
+
)}
|
|
48
|
+
{...props}
|
|
49
|
+
>
|
|
50
|
+
{children}
|
|
51
|
+
</div>
|
|
52
|
+
);
|
|
53
|
+
},
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
Card.displayName = 'Card';
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { cn } from '../utilities/classNames';
|
|
3
|
+
|
|
4
|
+
export interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
5
|
+
elevation?: 'none' | 'sm' | 'md' | 'lg';
|
|
6
|
+
padding?: 'sm' | 'md' | 'lg';
|
|
7
|
+
border?: boolean;
|
|
8
|
+
interactive?: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const elevationStyles = {
|
|
12
|
+
none: '',
|
|
13
|
+
sm: 'shadow-sm',
|
|
14
|
+
md: 'shadow-md',
|
|
15
|
+
lg: 'shadow-lg',
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const paddingStyles = {
|
|
19
|
+
sm: 'p-3',
|
|
20
|
+
md: 'p-6',
|
|
21
|
+
lg: 'p-8',
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const Card = React.forwardRef<HTMLDivElement, CardProps>(
|
|
25
|
+
(
|
|
26
|
+
{
|
|
27
|
+
elevation = 'md',
|
|
28
|
+
padding = 'md',
|
|
29
|
+
border = false,
|
|
30
|
+
interactive = false,
|
|
31
|
+
className,
|
|
32
|
+
children,
|
|
33
|
+
...props
|
|
34
|
+
},
|
|
35
|
+
ref,
|
|
36
|
+
) => {
|
|
37
|
+
return (
|
|
38
|
+
<div
|
|
39
|
+
ref={ref}
|
|
40
|
+
className={cn(
|
|
41
|
+
'bg-white rounded-lg',
|
|
42
|
+
elevationStyles[elevation],
|
|
43
|
+
paddingStyles[padding],
|
|
44
|
+
border && 'border border-gray-200',
|
|
45
|
+
interactive && 'cursor-pointer hover:shadow-lg transition-shadow duration-200',
|
|
46
|
+
className,
|
|
47
|
+
)}
|
|
48
|
+
{...props}
|
|
49
|
+
>
|
|
50
|
+
{children}
|
|
51
|
+
</div>
|
|
52
|
+
);
|
|
53
|
+
},
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
Card.displayName = 'Card';
|