@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.
Files changed (244) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/LICENSE +21 -0
  3. package/README.md +256 -2
  4. package/dist/cjs/components/Accordion.d.ts +78 -0
  5. package/dist/cjs/components/Accordion.js +78 -0
  6. package/dist/cjs/components/AdvancedComponents.d.ts +353 -0
  7. package/dist/cjs/components/AdvancedComponents.js +353 -0
  8. package/dist/cjs/components/Alert.d.ts +102 -0
  9. package/dist/cjs/components/Alert.js +102 -0
  10. package/dist/cjs/components/Avatar.d.ts +89 -0
  11. package/dist/cjs/components/Avatar.js +89 -0
  12. package/dist/cjs/components/Badge.d.ts +57 -0
  13. package/dist/cjs/components/Badge.js +57 -0
  14. package/dist/cjs/components/Breadcrumb.d.ts +50 -0
  15. package/dist/cjs/components/Breadcrumb.js +50 -0
  16. package/dist/cjs/components/Button.d.ts +77 -0
  17. package/dist/cjs/components/Button.js +77 -0
  18. package/dist/cjs/components/ButtonVariants.d.ts +261 -0
  19. package/dist/cjs/components/ButtonVariants.js +261 -0
  20. package/dist/cjs/components/Card.d.ts +56 -0
  21. package/dist/cjs/components/Card.js +56 -0
  22. package/dist/cjs/components/CardVariants.d.ts +267 -0
  23. package/dist/cjs/components/CardVariants.js +267 -0
  24. package/dist/cjs/components/Checkbox.d.ts +50 -0
  25. package/dist/cjs/components/Checkbox.js +50 -0
  26. package/dist/cjs/components/Chip.d.ts +104 -0
  27. package/dist/cjs/components/Chip.js +104 -0
  28. package/dist/cjs/components/DataDisplayComponents.d.ts +275 -0
  29. package/dist/cjs/components/DataDisplayComponents.js +275 -0
  30. package/dist/cjs/components/Divider.d.ts +77 -0
  31. package/dist/cjs/components/Divider.js +77 -0
  32. package/dist/cjs/components/Drawer.d.ts +142 -0
  33. package/dist/cjs/components/Drawer.js +142 -0
  34. package/dist/cjs/components/Dropdown.d.ts +139 -0
  35. package/dist/cjs/components/Dropdown.js +139 -0
  36. package/dist/cjs/components/Form.d.ts +41 -0
  37. package/dist/cjs/components/Form.js +41 -0
  38. package/dist/cjs/components/FormGroup.d.ts +58 -0
  39. package/dist/cjs/components/FormGroup.js +58 -0
  40. package/dist/cjs/components/FormInputVariants.d.ts +298 -0
  41. package/dist/cjs/components/FormInputVariants.js +298 -0
  42. package/dist/cjs/components/Image.d.ts +106 -0
  43. package/dist/cjs/components/Image.js +106 -0
  44. package/dist/cjs/components/Input.d.ts +65 -0
  45. package/dist/cjs/components/Input.js +65 -0
  46. package/dist/cjs/components/LayoutComponents.d.ts +258 -0
  47. package/dist/cjs/components/LayoutComponents.js +258 -0
  48. package/dist/cjs/components/Link.d.ts +71 -0
  49. package/dist/cjs/components/Link.js +71 -0
  50. package/dist/cjs/components/LoadingFeedbackComponents.d.ts +230 -0
  51. package/dist/cjs/components/LoadingFeedbackComponents.js +230 -0
  52. package/dist/cjs/components/Menu.d.ts +167 -0
  53. package/dist/cjs/components/Menu.js +167 -0
  54. package/dist/cjs/components/Modal.d.ts +145 -0
  55. package/dist/cjs/components/Modal.js +145 -0
  56. package/dist/cjs/components/ModalTypes.d.ts +288 -0
  57. package/dist/cjs/components/ModalTypes.js +288 -0
  58. package/dist/cjs/components/Navbar.d.ts +181 -0
  59. package/dist/cjs/components/Navbar.js +181 -0
  60. package/dist/cjs/components/NavigationComponents.d.ts +276 -0
  61. package/dist/cjs/components/NavigationComponents.js +276 -0
  62. package/dist/cjs/components/Pagination.d.ts +94 -0
  63. package/dist/cjs/components/Pagination.js +94 -0
  64. package/dist/cjs/components/Popover.d.ts +108 -0
  65. package/dist/cjs/components/Popover.js +108 -0
  66. package/dist/cjs/components/Progress.d.ts +68 -0
  67. package/dist/cjs/components/Progress.js +68 -0
  68. package/dist/cjs/components/Radio.d.ts +93 -0
  69. package/dist/cjs/components/Radio.js +93 -0
  70. package/dist/cjs/components/Rating.d.ts +82 -0
  71. package/dist/cjs/components/Rating.js +82 -0
  72. package/dist/cjs/components/Select.d.ts +74 -0
  73. package/dist/cjs/components/Select.js +74 -0
  74. package/dist/cjs/components/Sidebar.d.ts +174 -0
  75. package/dist/cjs/components/Sidebar.js +174 -0
  76. package/dist/cjs/components/Skeleton.d.ts +57 -0
  77. package/dist/cjs/components/Skeleton.js +57 -0
  78. package/dist/cjs/components/Slider.d.ts +64 -0
  79. package/dist/cjs/components/Slider.js +64 -0
  80. package/dist/cjs/components/Spinner.d.ts +70 -0
  81. package/dist/cjs/components/Spinner.js +70 -0
  82. package/dist/cjs/components/Stack.d.ts +75 -0
  83. package/dist/cjs/components/Stack.js +75 -0
  84. package/dist/cjs/components/Stepper.d.ts +150 -0
  85. package/dist/cjs/components/Stepper.js +150 -0
  86. package/dist/cjs/components/Table.d.ts +173 -0
  87. package/dist/cjs/components/Table.js +173 -0
  88. package/dist/cjs/components/Tabs.d.ts +104 -0
  89. package/dist/cjs/components/Tabs.js +104 -0
  90. package/dist/cjs/components/Tag.d.ts +74 -0
  91. package/dist/cjs/components/Tag.js +74 -0
  92. package/dist/cjs/components/Textarea.d.ts +75 -0
  93. package/dist/cjs/components/Textarea.js +75 -0
  94. package/dist/cjs/components/Timeline.d.ts +124 -0
  95. package/dist/cjs/components/Timeline.js +124 -0
  96. package/dist/cjs/components/Toast.d.ts +155 -0
  97. package/dist/cjs/components/Toast.js +155 -0
  98. package/dist/cjs/components/Toggle.d.ts +75 -0
  99. package/dist/cjs/components/Toggle.js +75 -0
  100. package/dist/cjs/components/Tooltip.d.ts +80 -0
  101. package/dist/cjs/components/Tooltip.js +80 -0
  102. package/dist/cjs/components/TypographyComponents.d.ts +265 -0
  103. package/dist/cjs/components/TypographyComponents.js +265 -0
  104. package/dist/cjs/components/UtilityComponents.d.ts +345 -0
  105. package/dist/cjs/components/UtilityComponents.js +345 -0
  106. package/dist/cjs/components/Video.d.ts +82 -0
  107. package/dist/cjs/components/Video.js +82 -0
  108. package/dist/cjs/components/index.d.ts +311 -0
  109. package/dist/cjs/components/index.js +311 -0
  110. package/dist/cjs/index.d.ts +5 -0
  111. package/dist/cjs/index.js +5 -0
  112. package/dist/cjs/styles/main.css +493 -0
  113. package/dist/cjs/theme/ThemeProvider.d.ts +185 -0
  114. package/dist/cjs/theme/ThemeProvider.js +185 -0
  115. package/dist/cjs/theme/index.d.ts +2 -0
  116. package/dist/cjs/theme/index.js +2 -0
  117. package/dist/cjs/utilities/classNames.d.ts +200 -0
  118. package/dist/cjs/utilities/classNames.js +200 -0
  119. package/dist/cjs/utilities/index.d.ts +3 -0
  120. package/dist/cjs/utilities/index.js +3 -0
  121. package/dist/cjs/utilities/styles.d.ts +94 -0
  122. package/dist/cjs/utilities/styles.js +94 -0
  123. package/dist/esm/components/Accordion.d.ts +78 -0
  124. package/dist/esm/components/Accordion.js +78 -0
  125. package/dist/esm/components/AdvancedComponents.d.ts +353 -0
  126. package/dist/esm/components/AdvancedComponents.js +353 -0
  127. package/dist/esm/components/Alert.d.ts +102 -0
  128. package/dist/esm/components/Alert.js +102 -0
  129. package/dist/esm/components/Avatar.d.ts +89 -0
  130. package/dist/esm/components/Avatar.js +89 -0
  131. package/dist/esm/components/Badge.d.ts +57 -0
  132. package/dist/esm/components/Badge.js +57 -0
  133. package/dist/esm/components/Breadcrumb.d.ts +50 -0
  134. package/dist/esm/components/Breadcrumb.js +50 -0
  135. package/dist/esm/components/Button.d.ts +77 -0
  136. package/dist/esm/components/Button.js +77 -0
  137. package/dist/esm/components/ButtonVariants.d.ts +261 -0
  138. package/dist/esm/components/ButtonVariants.js +261 -0
  139. package/dist/esm/components/Card.d.ts +56 -0
  140. package/dist/esm/components/Card.js +56 -0
  141. package/dist/esm/components/CardVariants.d.ts +267 -0
  142. package/dist/esm/components/CardVariants.js +267 -0
  143. package/dist/esm/components/Checkbox.d.ts +50 -0
  144. package/dist/esm/components/Checkbox.js +50 -0
  145. package/dist/esm/components/Chip.d.ts +104 -0
  146. package/dist/esm/components/Chip.js +104 -0
  147. package/dist/esm/components/DataDisplayComponents.d.ts +275 -0
  148. package/dist/esm/components/DataDisplayComponents.js +275 -0
  149. package/dist/esm/components/Divider.d.ts +77 -0
  150. package/dist/esm/components/Divider.js +77 -0
  151. package/dist/esm/components/Drawer.d.ts +142 -0
  152. package/dist/esm/components/Drawer.js +142 -0
  153. package/dist/esm/components/Dropdown.d.ts +139 -0
  154. package/dist/esm/components/Dropdown.js +139 -0
  155. package/dist/esm/components/Form.d.ts +41 -0
  156. package/dist/esm/components/Form.js +41 -0
  157. package/dist/esm/components/FormGroup.d.ts +58 -0
  158. package/dist/esm/components/FormGroup.js +58 -0
  159. package/dist/esm/components/FormInputVariants.d.ts +298 -0
  160. package/dist/esm/components/FormInputVariants.js +298 -0
  161. package/dist/esm/components/Image.d.ts +106 -0
  162. package/dist/esm/components/Image.js +106 -0
  163. package/dist/esm/components/Input.d.ts +65 -0
  164. package/dist/esm/components/Input.js +65 -0
  165. package/dist/esm/components/LayoutComponents.d.ts +258 -0
  166. package/dist/esm/components/LayoutComponents.js +258 -0
  167. package/dist/esm/components/Link.d.ts +71 -0
  168. package/dist/esm/components/Link.js +71 -0
  169. package/dist/esm/components/LoadingFeedbackComponents.d.ts +230 -0
  170. package/dist/esm/components/LoadingFeedbackComponents.js +230 -0
  171. package/dist/esm/components/Menu.d.ts +167 -0
  172. package/dist/esm/components/Menu.js +167 -0
  173. package/dist/esm/components/Modal.d.ts +145 -0
  174. package/dist/esm/components/Modal.js +145 -0
  175. package/dist/esm/components/ModalTypes.d.ts +288 -0
  176. package/dist/esm/components/ModalTypes.js +288 -0
  177. package/dist/esm/components/Navbar.d.ts +181 -0
  178. package/dist/esm/components/Navbar.js +181 -0
  179. package/dist/esm/components/NavigationComponents.d.ts +276 -0
  180. package/dist/esm/components/NavigationComponents.js +276 -0
  181. package/dist/esm/components/Pagination.d.ts +94 -0
  182. package/dist/esm/components/Pagination.js +94 -0
  183. package/dist/esm/components/Popover.d.ts +108 -0
  184. package/dist/esm/components/Popover.js +108 -0
  185. package/dist/esm/components/Progress.d.ts +68 -0
  186. package/dist/esm/components/Progress.js +68 -0
  187. package/dist/esm/components/Radio.d.ts +93 -0
  188. package/dist/esm/components/Radio.js +93 -0
  189. package/dist/esm/components/Rating.d.ts +82 -0
  190. package/dist/esm/components/Rating.js +82 -0
  191. package/dist/esm/components/Select.d.ts +74 -0
  192. package/dist/esm/components/Select.js +74 -0
  193. package/dist/esm/components/Sidebar.d.ts +174 -0
  194. package/dist/esm/components/Sidebar.js +174 -0
  195. package/dist/esm/components/Skeleton.d.ts +57 -0
  196. package/dist/esm/components/Skeleton.js +57 -0
  197. package/dist/esm/components/Slider.d.ts +64 -0
  198. package/dist/esm/components/Slider.js +64 -0
  199. package/dist/esm/components/Spinner.d.ts +70 -0
  200. package/dist/esm/components/Spinner.js +70 -0
  201. package/dist/esm/components/Stack.d.ts +75 -0
  202. package/dist/esm/components/Stack.js +75 -0
  203. package/dist/esm/components/Stepper.d.ts +150 -0
  204. package/dist/esm/components/Stepper.js +150 -0
  205. package/dist/esm/components/Table.d.ts +173 -0
  206. package/dist/esm/components/Table.js +173 -0
  207. package/dist/esm/components/Tabs.d.ts +104 -0
  208. package/dist/esm/components/Tabs.js +104 -0
  209. package/dist/esm/components/Tag.d.ts +74 -0
  210. package/dist/esm/components/Tag.js +74 -0
  211. package/dist/esm/components/Textarea.d.ts +75 -0
  212. package/dist/esm/components/Textarea.js +75 -0
  213. package/dist/esm/components/Timeline.d.ts +124 -0
  214. package/dist/esm/components/Timeline.js +124 -0
  215. package/dist/esm/components/Toast.d.ts +155 -0
  216. package/dist/esm/components/Toast.js +155 -0
  217. package/dist/esm/components/Toggle.d.ts +75 -0
  218. package/dist/esm/components/Toggle.js +75 -0
  219. package/dist/esm/components/Tooltip.d.ts +80 -0
  220. package/dist/esm/components/Tooltip.js +80 -0
  221. package/dist/esm/components/TypographyComponents.d.ts +265 -0
  222. package/dist/esm/components/TypographyComponents.js +265 -0
  223. package/dist/esm/components/UtilityComponents.d.ts +345 -0
  224. package/dist/esm/components/UtilityComponents.js +345 -0
  225. package/dist/esm/components/Video.d.ts +82 -0
  226. package/dist/esm/components/Video.js +82 -0
  227. package/dist/esm/components/index.d.ts +311 -0
  228. package/dist/esm/components/index.js +311 -0
  229. package/dist/esm/index.d.ts +5 -0
  230. package/dist/esm/index.js +5 -0
  231. package/dist/esm/styles/main.css +493 -0
  232. package/dist/esm/theme/ThemeProvider.d.ts +185 -0
  233. package/dist/esm/theme/ThemeProvider.js +185 -0
  234. package/dist/esm/theme/index.d.ts +2 -0
  235. package/dist/esm/theme/index.js +2 -0
  236. package/dist/esm/utilities/classNames.d.ts +200 -0
  237. package/dist/esm/utilities/classNames.js +200 -0
  238. package/dist/esm/utilities/index.d.ts +3 -0
  239. package/dist/esm/utilities/index.js +3 -0
  240. package/dist/esm/utilities/styles.d.ts +94 -0
  241. package/dist/esm/utilities/styles.js +94 -0
  242. package/dist/styles/main.css +493 -0
  243. package/package.json +124 -6
  244. 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';