elementdrawing 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 (78) hide show
  1. package/LICENSE +21 -0
  2. package/dist/elementdrawing.min.js +3 -0
  3. package/dist/elementdrawing.min.js.LICENSE.txt +8 -0
  4. package/dist/elementdrawing.min.js.map +1 -0
  5. package/dist/index.html +1 -0
  6. package/package.json +127 -0
  7. package/src/core/bridge.h +855 -0
  8. package/src/core/diff.c +900 -0
  9. package/src/core/element.c +1078 -0
  10. package/src/core/event.c +813 -0
  11. package/src/core/fiber.c +1027 -0
  12. package/src/core/hooks.c +919 -0
  13. package/src/core/renderer.c +963 -0
  14. package/src/core/scheduler.c +702 -0
  15. package/src/core/state.c +803 -0
  16. package/src/css/animations.css +779 -0
  17. package/src/css/base.css +615 -0
  18. package/src/css/components.css +1311 -0
  19. package/src/css/tailwind.css +370 -0
  20. package/src/css/themes.css +517 -0
  21. package/src/css/utilities.css +475 -0
  22. package/src/index.js +746 -0
  23. package/src/js/animation.js +655 -0
  24. package/src/js/dom.js +665 -0
  25. package/src/js/events.js +585 -0
  26. package/src/js/http.js +446 -0
  27. package/src/js/index.js +26 -0
  28. package/src/js/router.js +483 -0
  29. package/src/js/store.js +539 -0
  30. package/src/js/utils.js +593 -0
  31. package/src/js/validator.js +529 -0
  32. package/src/jsx/components/Accordion.jsx +210 -0
  33. package/src/jsx/components/Alert.jsx +169 -0
  34. package/src/jsx/components/Avatar.jsx +214 -0
  35. package/src/jsx/components/Badge.jsx +136 -0
  36. package/src/jsx/components/Breadcrumb.jsx +200 -0
  37. package/src/jsx/components/Button.jsx +188 -0
  38. package/src/jsx/components/Card.jsx +192 -0
  39. package/src/jsx/components/Carousel.jsx +278 -0
  40. package/src/jsx/components/Checkbox.jsx +215 -0
  41. package/src/jsx/components/Dialog.jsx +242 -0
  42. package/src/jsx/components/Drawer.jsx +190 -0
  43. package/src/jsx/components/Dropdown.jsx +268 -0
  44. package/src/jsx/components/Form.jsx +274 -0
  45. package/src/jsx/components/Input.jsx +285 -0
  46. package/src/jsx/components/Menu.jsx +276 -0
  47. package/src/jsx/components/Modal.jsx +274 -0
  48. package/src/jsx/components/Navbar.jsx +292 -0
  49. package/src/jsx/components/Pagination.jsx +268 -0
  50. package/src/jsx/components/Progress.jsx +252 -0
  51. package/src/jsx/components/Radio.jsx +208 -0
  52. package/src/jsx/components/Select.jsx +397 -0
  53. package/src/jsx/components/Sidebar.jsx +250 -0
  54. package/src/jsx/components/Slider.jsx +310 -0
  55. package/src/jsx/components/Spinner.jsx +198 -0
  56. package/src/jsx/components/Switch.jsx +201 -0
  57. package/src/jsx/components/Table.jsx +332 -0
  58. package/src/jsx/components/Tabs.jsx +227 -0
  59. package/src/jsx/components/Textarea.jsx +212 -0
  60. package/src/jsx/components/Toast.jsx +270 -0
  61. package/src/jsx/components/Tooltip.jsx +178 -0
  62. package/src/jsx/components/Typography.jsx +299 -0
  63. package/src/jsx/components/index.jsx +70 -0
  64. package/src/jsx/core/element.js +3 -0
  65. package/src/jsx/hooks/index.js +356 -0
  66. package/src/jsx/hooks/useCallback.js +472 -0
  67. package/src/jsx/hooks/useContext.js +586 -0
  68. package/src/jsx/hooks/useEffect.js +704 -0
  69. package/src/jsx/hooks/useLayoutEffect.js +508 -0
  70. package/src/jsx/hooks/useMemo.js +689 -0
  71. package/src/jsx/hooks/useReducer.js +729 -0
  72. package/src/jsx/hooks/useRef.js +542 -0
  73. package/src/jsx/hooks/useState.js +854 -0
  74. package/src/jsx/runtime/commit.js +903 -0
  75. package/src/jsx/runtime/createElement.js +860 -0
  76. package/src/jsx/runtime/index.js +356 -0
  77. package/src/jsx/runtime/reconcile.js +687 -0
  78. package/src/jsx/runtime/render.js +914 -0
@@ -0,0 +1,276 @@
1
+ /**
2
+ * Menu Component for ElementDrawing Framework
3
+ * Supports items, submenus, icons, shortcuts, dividers, groups, selectable, active, compact
4
+ */
5
+ const ED = require('../core/element');
6
+
7
+ function MenuItem(props) {
8
+ const {
9
+ children,
10
+ label,
11
+ icon,
12
+ shortcut,
13
+ disabled = false,
14
+ active = false,
15
+ selected = false,
16
+ danger = false,
17
+ href,
18
+ onClick,
19
+ className = '',
20
+ style = {},
21
+ indent = 0,
22
+ compact = false,
23
+ level = 0,
24
+ } = props;
25
+
26
+ const itemClasses = [
27
+ 'ed-flex ed-items-center ed-w-full ed-px-3 ed-text-sm ed-transition-colors ed-duration-150 ed-gap-2',
28
+ compact ? 'ed-py-1' : 'ed-py-2',
29
+ disabled
30
+ ? 'ed-text-gray-400 ed-cursor-not-allowed'
31
+ : danger
32
+ ? 'ed-text-red-600 hover:ed-bg-red-50 ed-cursor-pointer'
33
+ : active || selected
34
+ ? 'ed-bg-blue-50 ed-text-blue-700 ed-font-medium ed-cursor-pointer'
35
+ : 'ed-text-gray-700 hover:ed-bg-gray-50 ed-cursor-pointer',
36
+ 'ed-rounded-md',
37
+ className,
38
+ ].filter(Boolean).join(' ');
39
+
40
+ const iconElement = icon
41
+ ? ED.createElement('span', {
42
+ className: 'ed-w-4 ed-h-4 ed-flex ed-items-center ed-justify-center ed-flex-shrink-0',
43
+ children: typeof icon === 'string' ? ED.createElement('i', { className: icon }) : icon,
44
+ })
45
+ : null;
46
+
47
+ const shortcutElement = shortcut
48
+ ? ED.createElement('span', {
49
+ className: 'ed-ml-auto ed-text-xs ed-text-gray-400 ed-font-mono',
50
+ }, shortcut)
51
+ : null;
52
+
53
+ const labelContent = label || children;
54
+
55
+ if (href && !disabled) {
56
+ return ED.createElement('a', {
57
+ href,
58
+ className: itemClasses,
59
+ style: { paddingLeft: `${indent + 12}px`, ...style },
60
+ onClick: disabled ? undefined : onClick,
61
+ role: 'menuitem',
62
+ tabIndex: disabled ? -1 : 0,
63
+ children: [iconElement, ED.createElement('span', { key: 'label', className: 'ed-flex-1' }, labelContent), shortcutElement].filter(Boolean),
64
+ });
65
+ }
66
+
67
+ return ED.createElement('div', {
68
+ className: itemClasses,
69
+ style: { paddingLeft: `${indent + 12}px`, ...style },
70
+ onClick: disabled ? undefined : onClick,
71
+ role: 'menuitem',
72
+ tabIndex: disabled ? -1 : 0,
73
+ 'aria-disabled': disabled,
74
+ onKeyDown: (e) => {
75
+ if (e.key === 'Enter' && !disabled) onClick?.(e);
76
+ },
77
+ children: [iconElement, ED.createElement('span', { key: 'label', className: 'ed-flex-1' }, labelContent), shortcutElement].filter(Boolean),
78
+ });
79
+ }
80
+
81
+ MenuItem.displayName = 'MenuItem';
82
+
83
+ function MenuGroup(props) {
84
+ const {
85
+ children,
86
+ title,
87
+ className = '',
88
+ style = {},
89
+ } = props;
90
+
91
+ return ED.createElement('div', {
92
+ className: `ed-py-1 ${className}`,
93
+ style,
94
+ role: 'group',
95
+ 'aria-label': title,
96
+ children: [
97
+ title
98
+ ? ED.createElement('div', {
99
+ key: 'title',
100
+ className: 'ed-px-3 ed-py-1.5 ed-text-xs ed-font-semibold ed-text-gray-400 ed-uppercase ed-tracking-wider',
101
+ }, title)
102
+ : null,
103
+ children,
104
+ ].filter(Boolean),
105
+ });
106
+ }
107
+
108
+ MenuGroup.displayName = 'MenuGroup';
109
+
110
+ function MenuDivider() {
111
+ return ED.createElement('div', {
112
+ className: 'ed-my-1 ed-border-t ed-border-gray-100',
113
+ role: 'separator',
114
+ });
115
+ }
116
+
117
+ MenuDivider.displayName = 'MenuDivider';
118
+
119
+ function SubMenu(props) {
120
+ const {
121
+ children,
122
+ label,
123
+ icon,
124
+ disabled = false,
125
+ expanded = false,
126
+ onToggle,
127
+ className = '',
128
+ style = {},
129
+ level = 0,
130
+ compact = false,
131
+ } = props;
132
+
133
+ const itemClasses = [
134
+ 'ed-flex ed-items-center ed-w-full ed-px-3 ed-text-sm ed-transition-colors ed-duration-150 ed-gap-2',
135
+ compact ? 'ed-py-1' : 'ed-py-2',
136
+ disabled
137
+ ? 'ed-text-gray-400 ed-cursor-not-allowed'
138
+ : 'ed-text-gray-700 hover:ed-bg-gray-50 ed-cursor-pointer',
139
+ 'ed-rounded-md',
140
+ className,
141
+ ].filter(Boolean).join(' ');
142
+
143
+ return ED.createElement('div', null, [
144
+ ED.createElement('div', {
145
+ key: 'header',
146
+ className: itemClasses,
147
+ style: { paddingLeft: `${level * 16 + 12}px`, ...style },
148
+ onClick: disabled ? undefined : onToggle,
149
+ 'aria-expanded': expanded,
150
+ role: 'menuitem',
151
+ 'aria-haspopup': 'true',
152
+ tabIndex: disabled ? -1 : 0,
153
+ children: [
154
+ icon
155
+ ? ED.createElement('span', {
156
+ key: 'icon',
157
+ className: 'ed-w-4 ed-h-4 ed-flex ed-items-center ed-justify-center ed-flex-shrink-0',
158
+ children: typeof icon === 'string' ? ED.createElement('i', { className: icon }) : icon,
159
+ })
160
+ : null,
161
+ ED.createElement('span', { key: 'label', className: 'ed-flex-1' }, label),
162
+ ED.createElement('svg', {
163
+ key: 'arrow',
164
+ className: `ed-w-4 ed-h-4 ed-text-gray-400 ed-transition-transform ed-duration-200 ${expanded ? 'ed-rotate-90' : ''}`,
165
+ fill: 'none', viewBox: '0 0 24 24', stroke: 'currentColor',
166
+ children: ED.createElement('path', { strokeLinecap: 'round', strokeLinejoin: 'round', strokeWidth: 2, d: 'M9 5l7 7-7 7' }),
167
+ }),
168
+ ],
169
+ }),
170
+ expanded
171
+ ? ED.createElement('div', {
172
+ key: 'content',
173
+ className: 'ed-overflow-hidden',
174
+ role: 'menu',
175
+ children,
176
+ })
177
+ : null,
178
+ ]);
179
+ }
180
+
181
+ SubMenu.displayName = 'SubMenu';
182
+
183
+ function Menu(props) {
184
+ const {
185
+ children,
186
+ items = [],
187
+ mode = 'vertical',
188
+ selectedKey,
189
+ onSelect,
190
+ expandedKeys = [],
191
+ onExpand,
192
+ compact = false,
193
+ className = '',
194
+ style = {},
195
+ theme = 'light',
196
+ bordered = true,
197
+ width = 256,
198
+ inlineCollapsed = false,
199
+ selectable = true,
200
+ multiple = false,
201
+ defaultSelectedKey,
202
+ defaultOpenKeys = [],
203
+ onClick,
204
+ } = props;
205
+
206
+ const isDark = theme === 'dark';
207
+
208
+ const menuClasses = [
209
+ 'ed-py-1 ed-min-w-0',
210
+ isDark ? 'ed-bg-gray-900 ed-text-gray-100' : 'ed-bg-white ed-text-gray-800',
211
+ bordered ? 'ed-border ed-border-gray-200 ed-rounded-lg' : '',
212
+ mode === 'horizontal' ? 'ed-flex ed-items-center' : '',
213
+ className,
214
+ ].filter(Boolean).join(' ');
215
+
216
+ const renderItems = (menuItems, level = 0) =>
217
+ menuItems.map((item, idx) => {
218
+ if (item.divider) return ED.createElement(MenuDivider, { key: item.key || idx });
219
+
220
+ if (item.group) {
221
+ return ED.createElement(MenuGroup, {
222
+ key: item.key || idx,
223
+ title: item.title || item.label,
224
+ children: renderItems(item.children || [], level),
225
+ });
226
+ }
227
+
228
+ if (item.children && item.children.length > 0) {
229
+ return ED.createElement(SubMenu, {
230
+ key: item.key || idx,
231
+ label: item.label,
232
+ icon: item.icon,
233
+ disabled: item.disabled,
234
+ expanded: expandedKeys.includes(item.key),
235
+ onToggle: () => onExpand?.(item.key),
236
+ level,
237
+ compact,
238
+ children: renderItems(item.children, level + 1),
239
+ });
240
+ }
241
+
242
+ return ED.createElement(MenuItem, {
243
+ key: item.key || idx,
244
+ label: item.label,
245
+ icon: item.icon,
246
+ shortcut: item.shortcut,
247
+ disabled: item.disabled,
248
+ active: selectable && selectedKey === item.key,
249
+ selected: selectable && selectedKey === item.key,
250
+ danger: item.danger,
251
+ href: item.href,
252
+ indent: level * 16,
253
+ compact,
254
+ level,
255
+ onClick: () => {
256
+ onSelect?.(item);
257
+ onClick?.(item);
258
+ },
259
+ });
260
+ });
261
+
262
+ return ED.createElement('div', {
263
+ className: menuClasses,
264
+ style: { width, ...style },
265
+ role: 'menu',
266
+ children: items.length > 0 ? renderItems(items) : children,
267
+ });
268
+ }
269
+
270
+ Menu.displayName = 'Menu';
271
+ Menu.Item = MenuItem;
272
+ Menu.Group = MenuGroup;
273
+ Menu.Divider = MenuDivider;
274
+ Menu.SubMenu = SubMenu;
275
+
276
+ module.exports = Menu;
@@ -0,0 +1,274 @@
1
+ /**
2
+ * Modal Component for ElementDrawing Framework
3
+ * Supports backdrop, sizes, animations, close button, sections, confirmation, scrollable, portal
4
+ */
5
+ const ED = require('../core/element');
6
+
7
+ const MODAL_SIZES = {
8
+ sm: 'ed-max-w-sm',
9
+ md: 'ed-max-w-md',
10
+ lg: 'ed-max-w-lg',
11
+ xl: 'ed-max-w-xl',
12
+ full: 'ed-max-w-full ed-mx-4 ed-h-full ed-flex ed-items-stretch',
13
+ };
14
+
15
+ const ANIMATIONS = {
16
+ fade: { enter: 'ed-animate-fade-in', leave: 'ed-animate-fade-out' },
17
+ zoom: { enter: 'ed-animate-zoom-in', leave: 'ed-animate-zoom-out' },
18
+ slideUp: { enter: 'ed-animate-slide-up', leave: 'ed-animate-slide-down' },
19
+ slideDown: { enter: 'ed-animate-slide-down', leave: 'ed-animate-slide-up' },
20
+ slideLeft: { enter: 'ed-animate-slide-left', leave: 'ed-animate-slide-right' },
21
+ slideRight: { enter: 'ed-animate-slide-right', leave: 'ed-animate-slide-left' },
22
+ };
23
+
24
+ function ModalHeader(props) {
25
+ const {
26
+ children,
27
+ title,
28
+ onClose,
29
+ closable = true,
30
+ className = '',
31
+ style = {},
32
+ } = props;
33
+
34
+ return ED.createElement('div', {
35
+ className: [
36
+ 'ed-flex ed-items-center ed-justify-between ed-px-6 ed-py-4 ed-border-b ed-border-gray-200',
37
+ 'ed-modal-header',
38
+ className,
39
+ ].filter(Boolean).join(' '),
40
+ style,
41
+ children: [
42
+ title
43
+ ? ED.createElement('h3', {
44
+ key: 'title',
45
+ className: 'ed-text-lg ed-font-semibold ed-text-gray-900',
46
+ }, title)
47
+ : ED.createElement('div', { key: 'title-content' }, children),
48
+ closable
49
+ ? ED.createElement('button', {
50
+ key: 'close',
51
+ className: 'ed-ml-4 ed-p-1 ed-rounded-md ed-text-gray-400 hover:ed-text-gray-600 hover:ed-bg-gray-100 ed-transition-colors ed-focus:outline-none',
52
+ onClick: onClose,
53
+ 'aria-label': 'Close modal',
54
+ type: 'button',
55
+ children: ED.createElement('svg', {
56
+ className: 'ed-w-5 ed-h-5',
57
+ fill: 'none',
58
+ viewBox: '0 0 24 24',
59
+ stroke: 'currentColor',
60
+ strokeWidth: 2,
61
+ children: ED.createElement('path', {
62
+ strokeLinecap: 'round',
63
+ strokeLinejoin: 'round',
64
+ d: 'M6 18L18 6M6 6l12 12',
65
+ }),
66
+ }),
67
+ })
68
+ : null,
69
+ ].filter(Boolean),
70
+ });
71
+ }
72
+
73
+ ModalHeader.displayName = 'ModalHeader';
74
+
75
+ function ModalBody(props) {
76
+ const {
77
+ children,
78
+ className = '',
79
+ style = {},
80
+ scrollable = false,
81
+ } = props;
82
+
83
+ return ED.createElement('div', {
84
+ className: [
85
+ 'ed-px-6 ed-py-4',
86
+ scrollable ? 'ed-overflow-y-auto ed-max-h-[60vh]' : '',
87
+ 'ed-modal-body',
88
+ className,
89
+ ].filter(Boolean).join(' '),
90
+ style,
91
+ children,
92
+ });
93
+ }
94
+
95
+ ModalBody.displayName = 'ModalBody';
96
+
97
+ function ModalFooter(props) {
98
+ const {
99
+ children,
100
+ className = '',
101
+ style = {},
102
+ align = 'right',
103
+ bordered = true,
104
+ } = props;
105
+
106
+ const alignClass = {
107
+ left: 'ed-justify-start',
108
+ center: 'ed-justify-center',
109
+ right: 'ed-justify-end',
110
+ between: 'ed-justify-between',
111
+ }[align] || 'ed-justify-end';
112
+
113
+ return ED.createElement('div', {
114
+ className: [
115
+ 'ed-px-6 ed-py-3 ed-flex ed-items-center ed-gap-3',
116
+ bordered ? 'ed-border-t ed-border-gray-200' : '',
117
+ alignClass,
118
+ 'ed-modal-footer',
119
+ className,
120
+ ].filter(Boolean).join(' '),
121
+ style,
122
+ children,
123
+ });
124
+ }
125
+
126
+ ModalFooter.displayName = 'ModalFooter';
127
+
128
+ function Modal(props) {
129
+ const {
130
+ children,
131
+ visible = false,
132
+ onClose,
133
+ title,
134
+ size = 'md',
135
+ animation = 'zoom',
136
+ closable = true,
137
+ closeOnBackdrop = true,
138
+ closeOnEscape = true,
139
+ backdrop = true,
140
+ backdropClassName = '',
141
+ className = '',
142
+ style = {},
143
+ footer,
144
+ header,
145
+ centered = true,
146
+ scrollable = false,
147
+ destroyOnClose = false,
148
+ portal = false,
149
+ portalTarget,
150
+ confirmLoading = false,
151
+ okText = 'OK',
152
+ cancelText = 'Cancel',
153
+ onOk,
154
+ onCancel,
155
+ showCancel = true,
156
+ width,
157
+ zIndex = 1000,
158
+ afterClose,
159
+ maskStyle,
160
+ } = props;
161
+
162
+ if (!visible && destroyOnClose) return null;
163
+ if (!visible) return null;
164
+
165
+ const sizeClass = MODAL_SIZES[size] || MODAL_SIZES.md;
166
+ const anim = ANIMATIONS[animation] || ANIMATIONS.zoom;
167
+
168
+ const backdropClasses = [
169
+ 'ed-fixed ed-inset-0 ed-z-50 ed-flex',
170
+ centered ? 'ed-items-center ed-justify-center' : 'ed-items-start ed-justify-center ed-pt-16',
171
+ backdrop ? 'ed-bg-black ed-bg-opacity-50' : '',
172
+ anim.enter,
173
+ 'ed-modal-backdrop',
174
+ backdropClassName,
175
+ ].filter(Boolean).join(' ');
176
+
177
+ const modalClasses = [
178
+ 'ed-bg-white ed-rounded-lg ed-shadow-xl ed-w-full',
179
+ sizeClass,
180
+ 'ed-relative ed-flex ed-flex-col',
181
+ 'ed-modal-content',
182
+ anim.enter,
183
+ className,
184
+ ].filter(Boolean).join(' ');
185
+
186
+ const handleBackdropClick = (e) => {
187
+ if (closeOnBackdrop && e.target === e.currentTarget) {
188
+ onClose?.();
189
+ }
190
+ };
191
+
192
+ const handleKeyDown = (e) => {
193
+ if (closeOnEscape && e.key === 'Escape') {
194
+ onClose?.();
195
+ }
196
+ };
197
+
198
+ const headerElement = header !== undefined ? header
199
+ : (title || closable)
200
+ ? ED.createElement(ModalHeader, {
201
+ title,
202
+ closable,
203
+ onClose,
204
+ })
205
+ : null;
206
+
207
+ const bodyElement = ED.createElement(ModalBody, {
208
+ scrollable,
209
+ children,
210
+ });
211
+
212
+ const footerElement = footer !== undefined ? footer
213
+ : (onOk || onCancel)
214
+ ? ED.createElement(ModalFooter, null,
215
+ showCancel
216
+ ? ED.createElement('button', {
217
+ key: 'cancel',
218
+ className: 'ed-px-4 ed-py-2 ed-text-sm ed-font-medium ed-text-gray-700 ed-bg-white ed-border ed-border-gray-300 ed-rounded-md hover:ed-bg-gray-50 ed-transition-colors',
219
+ onClick: onCancel || onClose,
220
+ children: cancelText,
221
+ })
222
+ : null,
223
+ ED.createElement('button', {
224
+ key: 'ok',
225
+ className: [
226
+ 'ed-px-4 ed-py-2 ed-text-sm ed-font-medium ed-text-white ed-bg-blue-600 ed-rounded-md',
227
+ 'hover:ed-bg-blue-700 ed-transition-colors',
228
+ confirmLoading ? 'ed-opacity-70 ed-cursor-not-allowed' : '',
229
+ ].filter(Boolean).join(' '),
230
+ onClick: onOk,
231
+ disabled: confirmLoading,
232
+ children: confirmLoading
233
+ ? ED.createElement('span', { className: 'ed-flex ed-items-center ed-gap-2' },
234
+ ED.createElement('span', { className: 'ed-w-4 ed-h-4 ed-border-2 ed-border-white ed-border-t-transparent ed-rounded-full ed-animate-spin' }),
235
+ okText
236
+ )
237
+ : okText,
238
+ })
239
+ )
240
+ : null;
241
+
242
+ const modalContent = ED.createElement('div', {
243
+ className: backdropClasses,
244
+ style: { zIndex, ...maskStyle },
245
+ onClick: handleBackdropClick,
246
+ onKeyDown: handleKeyDown,
247
+ tabIndex: -1,
248
+ role: 'dialog',
249
+ 'aria-modal': 'true',
250
+ 'aria-labelledby': title ? 'modal-title' : undefined,
251
+ children: ED.createElement('div', {
252
+ className: modalClasses,
253
+ style: width ? { maxWidth: width, ...style } : style,
254
+ role: 'document',
255
+ children: [headerElement, bodyElement, footerElement].filter(Boolean),
256
+ }),
257
+ });
258
+
259
+ if (portal && typeof document !== 'undefined') {
260
+ const target = portalTarget || document.body;
261
+ return ED.createElement('portal', { target, children: modalContent });
262
+ }
263
+
264
+ return modalContent;
265
+ }
266
+
267
+ Modal.displayName = 'Modal';
268
+ Modal.Header = ModalHeader;
269
+ Modal.Body = ModalBody;
270
+ Modal.Footer = ModalFooter;
271
+ Modal.SIZES = MODAL_SIZES;
272
+ Modal.ANIMATIONS = ANIMATIONS;
273
+
274
+ module.exports = Modal;