@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,145 @@
1
+ import React, { useEffect, useRef } from 'react';
2
+ import { cn } from '../utilities/classNames';
3
+ import { Button } from './Button';
4
+
5
+ export interface ModalProps {
6
+ open: boolean;
7
+ onClose: () => void;
8
+ title?: string;
9
+ size?: 'sm' | 'md' | 'lg';
10
+ closeButton?: boolean;
11
+ children: React.ReactNode;
12
+ }
13
+
14
+ export const Modal = React.forwardRef<HTMLDivElement, ModalProps>(
15
+ (
16
+ {
17
+ open,
18
+ onClose,
19
+ title,
20
+ size = 'md',
21
+ closeButton = true,
22
+ children,
23
+ },
24
+ ref,
25
+ ) => {
26
+ const dialogRef = useRef<HTMLDivElement>(null);
27
+
28
+ useEffect(() => {
29
+ if (open) {
30
+ document.body.style.overflow = 'hidden';
31
+ } else {
32
+ document.body.style.overflow = 'unset';
33
+ }
34
+
35
+ return () => {
36
+ document.body.style.overflow = 'unset';
37
+ };
38
+ }, [open]);
39
+
40
+ const handleBackdropClick = (e: React.MouseEvent) => {
41
+ if (e.target === e.currentTarget) {
42
+ onClose();
43
+ }
44
+ };
45
+
46
+ if (!open) return null;
47
+
48
+ const sizeStyles = {
49
+ sm: 'max-w-sm',
50
+ md: 'max-w-md',
51
+ lg: 'max-w-lg',
52
+ };
53
+
54
+ return (
55
+ <div
56
+ className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"
57
+ onClick={handleBackdropClick}
58
+ >
59
+ <div
60
+ ref={ref || dialogRef}
61
+ className={cn(
62
+ 'bg-white rounded-lg shadow-xl w-full mx-4',
63
+ sizeStyles[size],
64
+ )}
65
+ >
66
+ {(title || closeButton) && (
67
+ <div className="flex items-center justify-between p-6 border-b border-gray-200">
68
+ {title && <h2 className="text-xl font-semibold text-gray-900">{title}</h2>}
69
+ {closeButton && (
70
+ <button
71
+ onClick={onClose}
72
+ className="ml-auto text-gray-400 hover:text-gray-600 transition-colors"
73
+ aria-label="Close modal"
74
+ >
75
+ <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
76
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
77
+ </svg>
78
+ </button>
79
+ )}
80
+ </div>
81
+ )}
82
+ <div className="p-6">
83
+ {children}
84
+ </div>
85
+ </div>
86
+ </div>
87
+ );
88
+ },
89
+ );
90
+
91
+ Modal.displayName = 'Modal';
92
+
93
+ export interface ModalHeaderProps extends React.HTMLAttributes<HTMLDivElement> {
94
+ children: React.ReactNode;
95
+ }
96
+
97
+ export const ModalHeader = React.forwardRef<HTMLDivElement, ModalHeaderProps>(
98
+ ({ children, className, ...props }, ref) => (
99
+ <div
100
+ ref={ref}
101
+ className={cn('px-6 py-4 border-b border-gray-200', className)}
102
+ {...props}
103
+ >
104
+ {children}
105
+ </div>
106
+ ),
107
+ );
108
+
109
+ ModalHeader.displayName = 'ModalHeader';
110
+
111
+ export interface ModalBodyProps extends React.HTMLAttributes<HTMLDivElement> {
112
+ children: React.ReactNode;
113
+ }
114
+
115
+ export const ModalBody = React.forwardRef<HTMLDivElement, ModalBodyProps>(
116
+ ({ children, className, ...props }, ref) => (
117
+ <div
118
+ ref={ref}
119
+ className={cn('px-6 py-4', className)}
120
+ {...props}
121
+ >
122
+ {children}
123
+ </div>
124
+ ),
125
+ );
126
+
127
+ ModalBody.displayName = 'ModalBody';
128
+
129
+ export interface ModalFooterProps extends React.HTMLAttributes<HTMLDivElement> {
130
+ children: React.ReactNode;
131
+ }
132
+
133
+ export const ModalFooter = React.forwardRef<HTMLDivElement, ModalFooterProps>(
134
+ ({ children, className, ...props }, ref) => (
135
+ <div
136
+ ref={ref}
137
+ className={cn('px-6 py-4 border-t border-gray-200 flex justify-end gap-3', className)}
138
+ {...props}
139
+ >
140
+ {children}
141
+ </div>
142
+ ),
143
+ );
144
+
145
+ ModalFooter.displayName = 'ModalFooter';
@@ -0,0 +1,288 @@
1
+ import React from 'react';
2
+
3
+ export interface ModalTypeProps extends React.HTMLAttributes<HTMLDivElement> {
4
+ isOpen: boolean;
5
+ onClose: () => void;
6
+ size?: 'sm' | 'md' | 'lg' | 'fullscreen';
7
+ animation?: 'fade' | 'slideUp' | 'slideDown' | 'zoom' | 'none';
8
+ closeOnBackdrop?: boolean;
9
+ children?: React.ReactNode;
10
+ }
11
+
12
+ const sizeClass = {
13
+ sm: 'max-w-sm',
14
+ md: 'max-w-md',
15
+ lg: 'max-w-2xl',
16
+ fullscreen: 'max-w-full h-screen',
17
+ };
18
+
19
+ const animationClass = {
20
+ fade: 'animate-fade',
21
+ slideUp: 'animate-slideUp',
22
+ slideDown: 'animate-slideDown',
23
+ zoom: 'animate-zoom',
24
+ none: '',
25
+ };
26
+
27
+ export const ModalStandard: React.FC<ModalTypeProps> = ({
28
+ isOpen,
29
+ onClose,
30
+ size = 'md',
31
+ animation = 'fade',
32
+ closeOnBackdrop = true,
33
+ className = '',
34
+ children,
35
+ ...props
36
+ }) => {
37
+ if (!isOpen) return null;
38
+
39
+ return (
40
+ <div
41
+ className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50"
42
+ onClick={closeOnBackdrop ? onClose : undefined}
43
+ >
44
+ <div
45
+ className={`bg-white rounded-lg shadow-2xl ${sizeClass[size]} ${animationClass[animation]} ${className}`}
46
+ onClick={(e) => e.stopPropagation()}
47
+ {...props}
48
+ >
49
+ {children}
50
+ </div>
51
+ </div>
52
+ );
53
+ };
54
+
55
+ export const ModalAlert: React.FC<
56
+ ModalTypeProps & {
57
+ title?: string;
58
+ message?: string;
59
+ icon?: React.ReactNode;
60
+ }
61
+ > = ({
62
+ isOpen,
63
+ onClose,
64
+ size = 'sm',
65
+ animation = 'zoom',
66
+ closeOnBackdrop = true,
67
+ title,
68
+ message,
69
+ icon,
70
+ className = '',
71
+ children,
72
+ ...props
73
+ }) => {
74
+ if (!isOpen) return null;
75
+
76
+ return (
77
+ <div
78
+ className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50"
79
+ onClick={closeOnBackdrop ? onClose : undefined}
80
+ >
81
+ <div
82
+ className={`bg-white rounded-lg shadow-2xl ${sizeClass[size]} ${animationClass[animation]} p-6 text-center ${className}`}
83
+ onClick={(e) => e.stopPropagation()}
84
+ {...props}
85
+ >
86
+ {icon && <div className="mb-4 text-4xl">{icon}</div>}
87
+ {title && <h2 className="text-xl font-bold mb-2">{title}</h2>}
88
+ {message && <p className="text-gray-600 mb-6">{message}</p>}
89
+ {children}
90
+ <button
91
+ onClick={onClose}
92
+ className="mt-4 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700"
93
+ >
94
+ OK
95
+ </button>
96
+ </div>
97
+ </div>
98
+ );
99
+ };
100
+
101
+ export const ModalConfirm: React.FC<
102
+ ModalTypeProps & {
103
+ title?: string;
104
+ message?: string;
105
+ confirmText?: string;
106
+ cancelText?: string;
107
+ onConfirm?: () => void;
108
+ isDangerous?: boolean;
109
+ }
110
+ > = ({
111
+ isOpen,
112
+ onClose,
113
+ size = 'sm',
114
+ animation = 'zoom',
115
+ title,
116
+ message,
117
+ confirmText = 'Confirm',
118
+ cancelText = 'Cancel',
119
+ onConfirm,
120
+ isDangerous = false,
121
+ className = '',
122
+ children,
123
+ ...props
124
+ }) => {
125
+ if (!isOpen) return null;
126
+
127
+ return (
128
+ <div
129
+ className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50"
130
+ onClick={onClose}
131
+ >
132
+ <div
133
+ className={`bg-white rounded-lg shadow-2xl ${sizeClass[size]} ${animationClass[animation]} p-6 ${className}`}
134
+ onClick={(e) => e.stopPropagation()}
135
+ {...props}
136
+ >
137
+ {title && <h2 className="text-xl font-bold mb-2">{title}</h2>}
138
+ {message && <p className="text-gray-600 mb-6">{message}</p>}
139
+ {children}
140
+ <div className="mt-6 flex gap-3 justify-end">
141
+ <button
142
+ onClick={onClose}
143
+ className="px-4 py-2 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50"
144
+ >
145
+ {cancelText}
146
+ </button>
147
+ <button
148
+ onClick={() => {
149
+ onConfirm?.();
150
+ onClose();
151
+ }}
152
+ className={`px-4 py-2 text-white rounded-lg ${isDangerous ? 'bg-red-600 hover:bg-red-700' : 'bg-blue-600 hover:bg-blue-700'}`}
153
+ >
154
+ {confirmText}
155
+ </button>
156
+ </div>
157
+ </div>
158
+ </div>
159
+ );
160
+ };
161
+
162
+ export const ModalSidebar: React.FC<
163
+ ModalTypeProps & {
164
+ position?: 'left' | 'right';
165
+ }
166
+ > = ({
167
+ isOpen,
168
+ onClose,
169
+ position = 'right',
170
+ animation = 'slideUp',
171
+ closeOnBackdrop = true,
172
+ className = '',
173
+ children,
174
+ ...props
175
+ }) => {
176
+ if (!isOpen) return null;
177
+
178
+ const positionClass = position === 'left' ? 'left-0' : 'right-0';
179
+
180
+ return (
181
+ <div
182
+ className="fixed inset-0 z-50 bg-black bg-opacity-50"
183
+ onClick={closeOnBackdrop ? onClose : undefined}
184
+ >
185
+ <div
186
+ className={`fixed ${positionClass} top-0 bottom-0 w-64 bg-white shadow-2xl ${animationClass[animation]} overflow-y-auto ${className}`}
187
+ onClick={(e) => e.stopPropagation()}
188
+ {...props}
189
+ >
190
+ <div className="p-6">
191
+ <button
192
+ onClick={onClose}
193
+ className="absolute top-4 right-4 text-gray-500 hover:text-gray-700"
194
+ >
195
+ ✕
196
+ </button>
197
+ {children}
198
+ </div>
199
+ </div>
200
+ </div>
201
+ );
202
+ };
203
+
204
+ export const ModalFullscreen: React.FC<
205
+ ModalTypeProps & {
206
+ title?: string;
207
+ }
208
+ > = ({
209
+ isOpen,
210
+ onClose,
211
+ animation = 'fade',
212
+ title,
213
+ className = '',
214
+ children,
215
+ ...props
216
+ }) => {
217
+ if (!isOpen) return null;
218
+
219
+ return (
220
+ <div
221
+ className={`fixed inset-0 z-50 bg-white ${animationClass[animation]} overflow-y-auto ${className}`}
222
+ {...props}
223
+ >
224
+ <div className="flex items-center justify-between p-6 border-b border-gray-200">
225
+ {title && <h2 className="text-2xl font-bold">{title}</h2>}
226
+ <button
227
+ onClick={onClose}
228
+ className="text-gray-500 hover:text-gray-700 text-2xl"
229
+ >
230
+ ✕
231
+ </button>
232
+ </div>
233
+ <div className="p-6">{children}</div>
234
+ </div>
235
+ );
236
+ };
237
+
238
+ export const ModalCentered: React.FC<ModalTypeProps> = ({
239
+ isOpen,
240
+ onClose,
241
+ size = 'md',
242
+ className = '',
243
+ children,
244
+ ...props
245
+ }) => {
246
+ if (!isOpen) return null;
247
+
248
+ return (
249
+ <div
250
+ className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50"
251
+ onClick={onClose}
252
+ >
253
+ <div
254
+ className={`bg-white rounded-lg shadow-2xl ${sizeClass[size]} p-6 ${className}`}
255
+ onClick={(e) => e.stopPropagation()}
256
+ {...props}
257
+ >
258
+ {children}
259
+ </div>
260
+ </div>
261
+ );
262
+ };
263
+
264
+ export const ModalScrollable: React.FC<ModalTypeProps> = ({
265
+ isOpen,
266
+ onClose,
267
+ size = 'md',
268
+ className = '',
269
+ children,
270
+ ...props
271
+ }) => {
272
+ if (!isOpen) return null;
273
+
274
+ return (
275
+ <div
276
+ className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50"
277
+ onClick={onClose}
278
+ >
279
+ <div
280
+ className={`bg-white rounded-lg shadow-2xl ${sizeClass[size]} max-h-screen overflow-y-auto ${className}`}
281
+ onClick={(e) => e.stopPropagation()}
282
+ {...props}
283
+ >
284
+ {children}
285
+ </div>
286
+ </div>
287
+ );
288
+ };
@@ -0,0 +1,288 @@
1
+ import React from 'react';
2
+
3
+ export interface ModalTypeProps extends React.HTMLAttributes<HTMLDivElement> {
4
+ isOpen: boolean;
5
+ onClose: () => void;
6
+ size?: 'sm' | 'md' | 'lg' | 'fullscreen';
7
+ animation?: 'fade' | 'slideUp' | 'slideDown' | 'zoom' | 'none';
8
+ closeOnBackdrop?: boolean;
9
+ children?: React.ReactNode;
10
+ }
11
+
12
+ const sizeClass = {
13
+ sm: 'max-w-sm',
14
+ md: 'max-w-md',
15
+ lg: 'max-w-2xl',
16
+ fullscreen: 'max-w-full h-screen',
17
+ };
18
+
19
+ const animationClass = {
20
+ fade: 'animate-fade',
21
+ slideUp: 'animate-slideUp',
22
+ slideDown: 'animate-slideDown',
23
+ zoom: 'animate-zoom',
24
+ none: '',
25
+ };
26
+
27
+ export const ModalStandard: React.FC<ModalTypeProps> = ({
28
+ isOpen,
29
+ onClose,
30
+ size = 'md',
31
+ animation = 'fade',
32
+ closeOnBackdrop = true,
33
+ className = '',
34
+ children,
35
+ ...props
36
+ }) => {
37
+ if (!isOpen) return null;
38
+
39
+ return (
40
+ <div
41
+ className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50"
42
+ onClick={closeOnBackdrop ? onClose : undefined}
43
+ >
44
+ <div
45
+ className={`bg-white rounded-lg shadow-2xl ${sizeClass[size]} ${animationClass[animation]} ${className}`}
46
+ onClick={(e) => e.stopPropagation()}
47
+ {...props}
48
+ >
49
+ {children}
50
+ </div>
51
+ </div>
52
+ );
53
+ };
54
+
55
+ export const ModalAlert: React.FC<
56
+ ModalTypeProps & {
57
+ title?: string;
58
+ message?: string;
59
+ icon?: React.ReactNode;
60
+ }
61
+ > = ({
62
+ isOpen,
63
+ onClose,
64
+ size = 'sm',
65
+ animation = 'zoom',
66
+ closeOnBackdrop = true,
67
+ title,
68
+ message,
69
+ icon,
70
+ className = '',
71
+ children,
72
+ ...props
73
+ }) => {
74
+ if (!isOpen) return null;
75
+
76
+ return (
77
+ <div
78
+ className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50"
79
+ onClick={closeOnBackdrop ? onClose : undefined}
80
+ >
81
+ <div
82
+ className={`bg-white rounded-lg shadow-2xl ${sizeClass[size]} ${animationClass[animation]} p-6 text-center ${className}`}
83
+ onClick={(e) => e.stopPropagation()}
84
+ {...props}
85
+ >
86
+ {icon && <div className="mb-4 text-4xl">{icon}</div>}
87
+ {title && <h2 className="text-xl font-bold mb-2">{title}</h2>}
88
+ {message && <p className="text-gray-600 mb-6">{message}</p>}
89
+ {children}
90
+ <button
91
+ onClick={onClose}
92
+ className="mt-4 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700"
93
+ >
94
+ OK
95
+ </button>
96
+ </div>
97
+ </div>
98
+ );
99
+ };
100
+
101
+ export const ModalConfirm: React.FC<
102
+ ModalTypeProps & {
103
+ title?: string;
104
+ message?: string;
105
+ confirmText?: string;
106
+ cancelText?: string;
107
+ onConfirm?: () => void;
108
+ isDangerous?: boolean;
109
+ }
110
+ > = ({
111
+ isOpen,
112
+ onClose,
113
+ size = 'sm',
114
+ animation = 'zoom',
115
+ title,
116
+ message,
117
+ confirmText = 'Confirm',
118
+ cancelText = 'Cancel',
119
+ onConfirm,
120
+ isDangerous = false,
121
+ className = '',
122
+ children,
123
+ ...props
124
+ }) => {
125
+ if (!isOpen) return null;
126
+
127
+ return (
128
+ <div
129
+ className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50"
130
+ onClick={onClose}
131
+ >
132
+ <div
133
+ className={`bg-white rounded-lg shadow-2xl ${sizeClass[size]} ${animationClass[animation]} p-6 ${className}`}
134
+ onClick={(e) => e.stopPropagation()}
135
+ {...props}
136
+ >
137
+ {title && <h2 className="text-xl font-bold mb-2">{title}</h2>}
138
+ {message && <p className="text-gray-600 mb-6">{message}</p>}
139
+ {children}
140
+ <div className="mt-6 flex gap-3 justify-end">
141
+ <button
142
+ onClick={onClose}
143
+ className="px-4 py-2 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50"
144
+ >
145
+ {cancelText}
146
+ </button>
147
+ <button
148
+ onClick={() => {
149
+ onConfirm?.();
150
+ onClose();
151
+ }}
152
+ className={`px-4 py-2 text-white rounded-lg ${isDangerous ? 'bg-red-600 hover:bg-red-700' : 'bg-blue-600 hover:bg-blue-700'}`}
153
+ >
154
+ {confirmText}
155
+ </button>
156
+ </div>
157
+ </div>
158
+ </div>
159
+ );
160
+ };
161
+
162
+ export const ModalSidebar: React.FC<
163
+ ModalTypeProps & {
164
+ position?: 'left' | 'right';
165
+ }
166
+ > = ({
167
+ isOpen,
168
+ onClose,
169
+ position = 'right',
170
+ animation = 'slideUp',
171
+ closeOnBackdrop = true,
172
+ className = '',
173
+ children,
174
+ ...props
175
+ }) => {
176
+ if (!isOpen) return null;
177
+
178
+ const positionClass = position === 'left' ? 'left-0' : 'right-0';
179
+
180
+ return (
181
+ <div
182
+ className="fixed inset-0 z-50 bg-black bg-opacity-50"
183
+ onClick={closeOnBackdrop ? onClose : undefined}
184
+ >
185
+ <div
186
+ className={`fixed ${positionClass} top-0 bottom-0 w-64 bg-white shadow-2xl ${animationClass[animation]} overflow-y-auto ${className}`}
187
+ onClick={(e) => e.stopPropagation()}
188
+ {...props}
189
+ >
190
+ <div className="p-6">
191
+ <button
192
+ onClick={onClose}
193
+ className="absolute top-4 right-4 text-gray-500 hover:text-gray-700"
194
+ >
195
+ ✕
196
+ </button>
197
+ {children}
198
+ </div>
199
+ </div>
200
+ </div>
201
+ );
202
+ };
203
+
204
+ export const ModalFullscreen: React.FC<
205
+ ModalTypeProps & {
206
+ title?: string;
207
+ }
208
+ > = ({
209
+ isOpen,
210
+ onClose,
211
+ animation = 'fade',
212
+ title,
213
+ className = '',
214
+ children,
215
+ ...props
216
+ }) => {
217
+ if (!isOpen) return null;
218
+
219
+ return (
220
+ <div
221
+ className={`fixed inset-0 z-50 bg-white ${animationClass[animation]} overflow-y-auto ${className}`}
222
+ {...props}
223
+ >
224
+ <div className="flex items-center justify-between p-6 border-b border-gray-200">
225
+ {title && <h2 className="text-2xl font-bold">{title}</h2>}
226
+ <button
227
+ onClick={onClose}
228
+ className="text-gray-500 hover:text-gray-700 text-2xl"
229
+ >
230
+ ✕
231
+ </button>
232
+ </div>
233
+ <div className="p-6">{children}</div>
234
+ </div>
235
+ );
236
+ };
237
+
238
+ export const ModalCentered: React.FC<ModalTypeProps> = ({
239
+ isOpen,
240
+ onClose,
241
+ size = 'md',
242
+ className = '',
243
+ children,
244
+ ...props
245
+ }) => {
246
+ if (!isOpen) return null;
247
+
248
+ return (
249
+ <div
250
+ className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50"
251
+ onClick={onClose}
252
+ >
253
+ <div
254
+ className={`bg-white rounded-lg shadow-2xl ${sizeClass[size]} p-6 ${className}`}
255
+ onClick={(e) => e.stopPropagation()}
256
+ {...props}
257
+ >
258
+ {children}
259
+ </div>
260
+ </div>
261
+ );
262
+ };
263
+
264
+ export const ModalScrollable: React.FC<ModalTypeProps> = ({
265
+ isOpen,
266
+ onClose,
267
+ size = 'md',
268
+ className = '',
269
+ children,
270
+ ...props
271
+ }) => {
272
+ if (!isOpen) return null;
273
+
274
+ return (
275
+ <div
276
+ className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50"
277
+ onClick={onClose}
278
+ >
279
+ <div
280
+ className={`bg-white rounded-lg shadow-2xl ${sizeClass[size]} max-h-screen overflow-y-auto ${className}`}
281
+ onClick={(e) => e.stopPropagation()}
282
+ {...props}
283
+ >
284
+ {children}
285
+ </div>
286
+ </div>
287
+ );
288
+ };