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,274 @@
1
+ /**
2
+ * Form Component for ElementDrawing Framework
3
+ * Supports validation, field groups, inline/stacked layouts, form items, labels, errors, help text, disabled, loading
4
+ */
5
+ const ED = require('../core/element');
6
+
7
+ function FormItem(props) {
8
+ const {
9
+ children,
10
+ label,
11
+ labelFor,
12
+ labelAlign = 'left',
13
+ labelWidth,
14
+ required = false,
15
+ error,
16
+ warning,
17
+ success,
18
+ helpText,
19
+ className = '',
20
+ style = {},
21
+ layout = 'vertical',
22
+ colon = false,
23
+ tooltip,
24
+ extra,
25
+ noStyle = false,
26
+ hidden = false,
27
+ } = props;
28
+
29
+ if (hidden) return children;
30
+
31
+ const validationState = error ? 'error' : warning ? 'warning' : success ? 'success' : 'default';
32
+
33
+ const labelClasses = [
34
+ 'ed-block ed-text-sm ed-font-medium ed-mb-1',
35
+ labelAlign === 'right' ? 'ed-text-right' : labelAlign === 'center' ? 'ed-text-center' : '',
36
+ required ? "ed-after:content-['*'] ed-after:ed-text-red-500 ed-after:ed-ml-0.5" : '',
37
+ error ? 'ed-text-red-600' : 'ed-text-gray-700',
38
+ layout === 'horizontal' ? 'ed-mb-0 ed-flex ed-items-center' : '',
39
+ ].filter(Boolean).join(' ');
40
+
41
+ const labelElement = label
42
+ ? ED.createElement('label', {
43
+ htmlFor: labelFor,
44
+ className: labelClasses,
45
+ style: layout === 'horizontal' ? { width: labelWidth || 120, flexShrink: 0 } : {},
46
+ children: [
47
+ ED.createElement('span', null, label),
48
+ colon ? ED.createElement('span', { key: 'colon' }, ':') : null,
49
+ tooltip
50
+ ? ED.createElement('span', {
51
+ key: 'tooltip',
52
+ className: 'ed-ml-1 ed-inline-flex ed-items-center',
53
+ title: typeof tooltip === 'string' ? tooltip : undefined,
54
+ children: ED.createElement('svg', {
55
+ className: 'ed-w-4 ed-h-4 ed-text-gray-400',
56
+ fill: 'none', viewBox: '0 0 24 24', stroke: 'currentColor',
57
+ children: ED.createElement('path', { strokeLinecap: 'round', strokeLinejoin: 'round', strokeWidth: 2, d: 'M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z' }),
58
+ }),
59
+ })
60
+ : null,
61
+ ],
62
+ })
63
+ : null;
64
+
65
+ const messageElement = error
66
+ ? ED.createElement('p', { className: 'ed-text-xs ed-text-red-500 ed-mt-1 ed-flex ed-items-center ed-gap-1' },
67
+ ED.createElement('svg', { className: 'ed-w-3.5 ed-h-3.5 ed-flex-shrink-0', fill: 'none', viewBox: '0 0 24 24', stroke: 'currentColor' },
68
+ ED.createElement('path', { strokeLinecap: 'round', strokeLinejoin: 'round', strokeWidth: 2, d: 'M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z' })
69
+ ),
70
+ error
71
+ )
72
+ : warning
73
+ ? ED.createElement('p', { className: 'ed-text-xs ed-text-yellow-500 ed-mt-1' }, warning)
74
+ : success
75
+ ? ED.createElement('p', { className: 'ed-text-xs ed-text-green-500 ed-mt-1' }, success)
76
+ : helpText
77
+ ? ED.createElement('p', { className: 'ed-text-xs ed-text-gray-500 ed-mt-1' }, helpText)
78
+ : null;
79
+
80
+ const extraElement = extra
81
+ ? ED.createElement('div', { className: 'ed-text-xs ed-text-gray-400 ed-mt-1' }, extra)
82
+ : null;
83
+
84
+ if (noStyle) {
85
+ return ED.createElement('div', { className, style, children });
86
+ }
87
+
88
+ if (layout === 'horizontal') {
89
+ return ED.createElement('div', {
90
+ className: `ed-flex ed-gap-4 ed-mb-4 ${className}`,
91
+ style,
92
+ children: [
93
+ labelElement,
94
+ ED.createElement('div', { className: 'ed-flex-1 ed-min-w-0', key: 'control' },
95
+ children,
96
+ messageElement,
97
+ extraElement,
98
+ ),
99
+ ],
100
+ });
101
+ }
102
+
103
+ if (layout === 'inline') {
104
+ return ED.createElement('div', {
105
+ className: `ed-inline-flex ed-items-center ed-gap-2 ed-mr-4 ${className}`,
106
+ style,
107
+ children: [labelElement, children, messageElement].filter(Boolean),
108
+ });
109
+ }
110
+
111
+ return ED.createElement('div', {
112
+ className: `ed-mb-4 ${className}`,
113
+ style,
114
+ children: [labelElement, children, messageElement, extraElement].filter(Boolean),
115
+ });
116
+ }
117
+
118
+ FormItem.displayName = 'FormItem';
119
+
120
+ function FormGroup(props) {
121
+ const {
122
+ children,
123
+ title,
124
+ description,
125
+ collapsible = false,
126
+ collapsed: defaultCollapsed = false,
127
+ className = '',
128
+ style = {},
129
+ bordered = true,
130
+ } = props;
131
+
132
+ const groupClasses = [
133
+ bordered ? 'ed-border ed-border-gray-200 ed-rounded-lg ed-p-4' : '',
134
+ 'ed-mb-6',
135
+ className,
136
+ ].filter(Boolean).join(' ');
137
+
138
+ return ED.createElement('fieldset', {
139
+ className: groupClasses,
140
+ style,
141
+ children: [
142
+ title
143
+ ? ED.createElement('legend', {
144
+ className: 'ed-text-sm ed-font-semibold ed-text-gray-700 ed-px-2',
145
+ }, title)
146
+ : null,
147
+ description
148
+ ? ED.createElement('p', { className: 'ed-text-xs ed-text-gray-500 ed-mb-3' }, description)
149
+ : null,
150
+ children,
151
+ ].filter(Boolean),
152
+ });
153
+ }
154
+
155
+ FormGroup.displayName = 'FormGroup';
156
+
157
+ function Form(props) {
158
+ const {
159
+ children,
160
+ layout = 'vertical',
161
+ labelAlign = 'left',
162
+ labelWidth = 120,
163
+ colon = false,
164
+ requiredMark = true,
165
+ disabled = false,
166
+ loading = false,
167
+ className = '',
168
+ style = {},
169
+ onSubmit,
170
+ onValuesChange,
171
+ initialValues,
172
+ validateMessages,
173
+ size = 'md',
174
+ bordered = false,
175
+ name,
176
+ action,
177
+ method,
178
+ footer,
179
+ showReset = false,
180
+ resetText = 'Reset',
181
+ submitText = 'Submit',
182
+ onReset,
183
+ } = props;
184
+
185
+ const handleSubmit = (e) => {
186
+ e.preventDefault();
187
+ onSubmit?.(e);
188
+ };
189
+
190
+ const handleReset = (e) => {
191
+ e.preventDefault();
192
+ onReset?.(e);
193
+ };
194
+
195
+ const sizeClasses = {
196
+ sm: 'ed-text-sm',
197
+ md: 'ed-text-sm',
198
+ lg: 'ed-text-base',
199
+ };
200
+
201
+ const formClasses = [
202
+ sizeClasses[size] || sizeClasses.md,
203
+ layout === 'inline' ? 'ed-flex ed-flex-wrap ed-items-end ed-gap-4' : '',
204
+ layout === 'horizontal' ? 'ed-space-y-0' : 'ed-space-y-0',
205
+ bordered ? 'ed-border ed-border-gray-200 ed-rounded-lg ed-p-6' : '',
206
+ disabled ? 'ed-opacity-60 ed-pointer-events-none' : '',
207
+ 'ed-form',
208
+ className,
209
+ ].filter(Boolean).join(' ');
210
+
211
+ const loadingOverlay = loading
212
+ ? ED.createElement('div', {
213
+ className: 'ed-absolute ed-inset-0 ed-bg-white ed-bg-opacity-70 ed-flex ed-items-center ed-justify-center ed-z-10 ed-rounded-lg',
214
+ children: ED.createElement('div', {
215
+ className: 'ed-flex ed-items-center ed-gap-2 ed-text-gray-500',
216
+ children: [
217
+ ED.createElement('div', {
218
+ key: 'spinner',
219
+ className: 'ed-w-5 ed-h-5 ed-border-2 ed-border-blue-500 ed-border-t-transparent ed-rounded-full ed-animate-spin',
220
+ }),
221
+ ED.createElement('span', { key: 'text' }, 'Submitting...'),
222
+ ],
223
+ }),
224
+ })
225
+ : null;
226
+
227
+ const footerElement = footer !== undefined ? footer
228
+ : (onSubmit || action)
229
+ ? ED.createElement('div', {
230
+ className: `ed-flex ed-items-center ed-gap-3 ${layout === 'inline' ? '' : 'ed-mt-6'}`,
231
+ children: [
232
+ ED.createElement('button', {
233
+ key: 'submit',
234
+ type: 'submit',
235
+ className: [
236
+ 'ed-px-5 ed-py-2 ed-text-sm ed-font-medium ed-text-white ed-bg-blue-600 ed-rounded-md',
237
+ 'hover:ed-bg-blue-700 focus:ed-ring-2 focus:ed-ring-blue-500 focus:ed-ring-offset-2',
238
+ 'ed-transition-colors ed-duration-200',
239
+ loading ? 'ed-opacity-70 ed-cursor-not-allowed' : '',
240
+ ].filter(Boolean).join(' '),
241
+ disabled: loading,
242
+ }, submitText),
243
+ showReset
244
+ ? ED.createElement('button', {
245
+ key: 'reset',
246
+ type: 'button',
247
+ className: 'ed-px-5 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',
248
+ onClick: handleReset,
249
+ }, resetText)
250
+ : null,
251
+ ].filter(Boolean),
252
+ })
253
+ : null;
254
+
255
+ return ED.createElement('form', {
256
+ name,
257
+ action,
258
+ method,
259
+ className: formClasses,
260
+ style: { position: 'relative', ...style },
261
+ onSubmit: handleSubmit,
262
+ children: [
263
+ children,
264
+ footerElement,
265
+ loadingOverlay,
266
+ ].filter(Boolean),
267
+ });
268
+ }
269
+
270
+ Form.displayName = 'Form';
271
+ Form.Item = FormItem;
272
+ Form.Group = FormGroup;
273
+
274
+ module.exports = Form;
@@ -0,0 +1,285 @@
1
+ /**
2
+ * Input Component for ElementDrawing Framework
3
+ * Supports types, sizes, validation, prefix/suffix icons, clearable, disabled, readonly, floating label
4
+ */
5
+ const ED = require('../core/element');
6
+
7
+ const INPUT_SIZES = {
8
+ xs: 'ed-text-xs ed-px-2 ed-py-1',
9
+ sm: 'ed-text-sm ed-px-3 ed-py-1.5',
10
+ md: 'ed-text-sm ed-px-3 ed-py-2',
11
+ lg: 'ed-text-base ed-px-4 ed-py-2.5',
12
+ xl: 'ed-text-lg ed-px-4 ed-py-3',
13
+ };
14
+
15
+ const VALIDATION_STATES = {
16
+ default: 'ed-border-gray-300 focus:ed-border-blue-500 focus:ed-ring-blue-500',
17
+ success: 'ed-border-green-500 focus:ed-border-green-600 focus:ed-ring-green-500',
18
+ warning: 'ed-border-yellow-500 focus:ed-border-yellow-600 focus:ed-ring-yellow-500',
19
+ error: 'ed-border-red-500 focus:ed-border-red-600 focus:ed-ring-red-500',
20
+ };
21
+
22
+ const VALIDATION_ICONS = {
23
+ success: ED.createElement('svg', {
24
+ className: 'ed-w-5 ed-h-5 ed-text-green-500',
25
+ fill: 'none', viewBox: '0 0 24 24', stroke: 'currentColor',
26
+ children: ED.createElement('path', {
27
+ strokeLinecap: 'round', strokeLinejoin: 'round', strokeWidth: 2,
28
+ d: 'M5 13l4 4L19 7',
29
+ }),
30
+ }),
31
+ warning: ED.createElement('svg', {
32
+ className: 'ed-w-5 ed-h-5 ed-text-yellow-500',
33
+ fill: 'none', viewBox: '0 0 24 24', stroke: 'currentColor',
34
+ children: ED.createElement('path', {
35
+ strokeLinecap: 'round', strokeLinejoin: 'round', strokeWidth: 2,
36
+ d: 'M12 9v2m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z',
37
+ }),
38
+ }),
39
+ error: ED.createElement('svg', {
40
+ className: 'ed-w-5 ed-h-5 ed-text-red-500',
41
+ fill: 'none', viewBox: '0 0 24 24', stroke: 'currentColor',
42
+ children: ED.createElement('path', {
43
+ strokeLinecap: 'round', strokeLinejoin: 'round', strokeWidth: 2,
44
+ d: 'M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z',
45
+ }),
46
+ }),
47
+ };
48
+
49
+ function Input(props) {
50
+ const {
51
+ type = 'text',
52
+ size = 'md',
53
+ variant = 'default',
54
+ state = 'default',
55
+ validationState,
56
+ value,
57
+ defaultValue,
58
+ placeholder,
59
+ prefix,
60
+ suffix,
61
+ prefixIcon,
62
+ suffixIcon,
63
+ clearable = false,
64
+ disabled = false,
65
+ readonly = false,
66
+ floatingLabel,
67
+ label,
68
+ helperText,
69
+ errorMessage,
70
+ successMessage,
71
+ warningMessage,
72
+ maxLength,
73
+ showCount = false,
74
+ allowClear,
75
+ onClear,
76
+ onChange,
77
+ onFocus,
78
+ onBlur,
79
+ onInput,
80
+ onKeyDown,
81
+ onKeyUp,
82
+ onKeyPress,
83
+ onEnter,
84
+ className = '',
85
+ style = {},
86
+ inputClassName = '',
87
+ inputStyle = {},
88
+ id,
89
+ name,
90
+ autoComplete,
91
+ autoFocus = false,
92
+ tabIndex,
93
+ required = false,
94
+ pattern,
95
+ min,
96
+ max,
97
+ step,
98
+ rows,
99
+ size: sizeProp,
100
+ width,
101
+ borderRadius,
102
+ bordered = true,
103
+ status,
104
+ } = props;
105
+
106
+ const currentState = status || state || validationState || 'default';
107
+ const sizeClass = INPUT_SIZES[size] || INPUT_SIZES.md;
108
+ const stateClass = VALIDATION_STATES[currentState] || VALIDATION_STATES.default;
109
+ const hasPrefix = prefix || prefixIcon;
110
+ const hasSuffix = suffix || suffixIcon || clearable || VALIDATION_ICONS[currentState];
111
+
112
+ const clearButton = clearable && value && !disabled && !readonly
113
+ ? ED.createElement('button', {
114
+ key: 'clear',
115
+ className: 'ed-flex ed-items-center ed-justify-center ed-text-gray-400 hover:ed-text-gray-600 ed-transition-colors ed-ml-1',
116
+ onClick: (e) => {
117
+ e.stopPropagation();
118
+ onClear?.();
119
+ onChange?.({ target: { value: '' } });
120
+ },
121
+ tabIndex: -1,
122
+ type: 'button',
123
+ 'aria-label': 'Clear input',
124
+ children: ED.createElement('svg', {
125
+ className: 'ed-w-4 ed-h-4',
126
+ fill: 'none', viewBox: '0 0 24 24', stroke: 'currentColor',
127
+ children: ED.createElement('path', {
128
+ strokeLinecap: 'round', strokeLinejoin: 'round', strokeWidth: 2,
129
+ d: 'M6 18L18 6M6 6l12 12',
130
+ }),
131
+ }),
132
+ })
133
+ : null;
134
+
135
+ const prefixElement = hasPrefix
136
+ ? ED.createElement('span', {
137
+ className: 'ed-flex ed-items-center ed-pl-3 ed-text-gray-500 ed-pointer-events-none ed-input-prefix',
138
+ children: prefixIcon
139
+ ? (typeof prefixIcon === 'string'
140
+ ? ED.createElement('i', { className: prefixIcon })
141
+ : prefixIcon)
142
+ : prefix,
143
+ })
144
+ : null;
145
+
146
+ const suffixElement = hasSuffix
147
+ ? ED.createElement('span', {
148
+ className: 'ed-flex ed-items-center ed-pr-3 ed-text-gray-500 ed-gap-1 ed-input-suffix',
149
+ children: [
150
+ VALIDATION_ICONS[currentState] || null,
151
+ suffixIcon
152
+ ? (typeof suffixIcon === 'string'
153
+ ? ED.createElement('i', { className: suffixIcon })
154
+ : suffixIcon)
155
+ : null,
156
+ suffix || null,
157
+ clearButton,
158
+ ].filter(Boolean),
159
+ })
160
+ : null;
161
+
162
+ const charCount = showCount && maxLength
163
+ ? ED.createElement('span', {
164
+ className: `ed-text-xs ed-mt-1 ed-text-right ${value?.length > maxLength ? 'ed-text-red-500' : 'ed-text-gray-400'}`,
165
+ }, `${value?.length || 0} / ${maxLength}`)
166
+ : null;
167
+
168
+ const messageElement = errorMessage && currentState === 'error'
169
+ ? ED.createElement('p', { className: 'ed-text-xs ed-text-red-500 ed-mt-1' }, errorMessage)
170
+ : successMessage && currentState === 'success'
171
+ ? ED.createElement('p', { className: 'ed-text-xs ed-text-green-500 ed-mt-1' }, successMessage)
172
+ : warningMessage && currentState === 'warning'
173
+ ? ED.createElement('p', { className: 'ed-text-xs ed-text-yellow-500 ed-mt-1' }, warningMessage)
174
+ : helperText
175
+ ? ED.createElement('p', { className: 'ed-text-xs ed-text-gray-500 ed-mt-1' }, helperText)
176
+ : null;
177
+
178
+ const inputElement = ED.createElement('input', {
179
+ id,
180
+ name,
181
+ type,
182
+ value,
183
+ defaultValue,
184
+ placeholder: floatingLabel ? ' ' : placeholder,
185
+ disabled,
186
+ readOnly: readonly,
187
+ maxLength,
188
+ autoComplete,
189
+ autoFocus,
190
+ tabIndex,
191
+ required,
192
+ pattern,
193
+ min,
194
+ max,
195
+ step,
196
+ className: [
197
+ 'ed-w-full ed-outline-none ed-transition-all ed-duration-200',
198
+ 'ed-bg-transparent',
199
+ sizeClass,
200
+ bordered ? stateClass : 'ed-border-none',
201
+ !hasPrefix ? 'ed-pl-3' : '',
202
+ !hasSuffix ? 'ed-pr-3' : '',
203
+ disabled ? 'ed-bg-gray-100 ed-cursor-not-allowed ed-text-gray-400' : '',
204
+ readonly ? 'ed-bg-gray-50 ed-cursor-default' : '',
205
+ 'focus:ed-ring-2 focus:ed-ring-offset-0',
206
+ borderRadius ? `ed-rounded-${borderRadius}` : 'ed-rounded-md',
207
+ floatingLabel ? 'ed-peer ed-placeholder-shown:ed-pt-4 ed-placeholder-shown:ed-pb-1' : '',
208
+ inputClassName,
209
+ ].filter(Boolean).join(' '),
210
+ style: inputStyle,
211
+ onChange,
212
+ onFocus,
213
+ onBlur,
214
+ onInput,
215
+ onKeyDown: onEnter
216
+ ? (e) => { if (e.key === 'Enter') onEnter(e); onKeyDown?.(e); }
217
+ : onKeyDown,
218
+ onKeyUp,
219
+ onKeyPress,
220
+ 'aria-invalid': currentState === 'error',
221
+ 'aria-describedby': errorMessage ? `${id}-error` : undefined,
222
+ });
223
+
224
+ const floatingLabelElement = floatingLabel
225
+ ? ED.createElement('label', {
226
+ htmlFor: id,
227
+ className: [
228
+ 'ed-absolute ed-left-3 ed-transition-all ed-duration-200',
229
+ 'ed-text-gray-500 ed-pointer-events-none',
230
+ 'peer-placeholder-shown:ed-top-2.5 peer-placeholder-shown:ed-text-sm',
231
+ 'peer-focus:ed-top-0.5 peer-focus:ed-text-xs peer-focus:ed-text-blue-500',
232
+ '-ed-top-0.5 ed-text-xs',
233
+ 'ed-bg-white ed-px-1',
234
+ ].join(' '),
235
+ }, floatingLabel)
236
+ : null;
237
+
238
+ const wrapperClasses = [
239
+ 'ed-relative ed-flex ed-items-center',
240
+ bordered ? 'ed-border ed-rounded-md' : '',
241
+ disabled ? 'ed-bg-gray-100' : 'ed-bg-white',
242
+ currentState === 'error' ? 'ed-border-red-500' : currentState === 'success' ? 'ed-border-green-500' : 'ed-border-gray-300',
243
+ disabled ? 'ed-opacity-60' : '',
244
+ 'hover:ed-border-gray-400',
245
+ 'focus-within:ed-ring-2 focus-within:ed-ring-blue-500 focus-within:ed-border-blue-500',
246
+ 'ed-transition-all ed-duration-200',
247
+ className,
248
+ ].filter(Boolean).join(' ');
249
+
250
+ return ED.createElement('div', {
251
+ className: `ed-inline-flex ed-flex-col ${width ? '' : 'ed-w-full'}`,
252
+ style: { width, ...style },
253
+ children: [
254
+ label && !floatingLabel
255
+ ? ED.createElement('label', {
256
+ key: 'label',
257
+ htmlFor: id,
258
+ className: `ed-block ed-text-sm ed-font-medium ed-mb-1 ${required ? "ed-after:content-['*'] ed-after:ed-text-red-500 ed-after:ed-ml-0.5" : ''} ${disabled ? 'ed-text-gray-400' : 'ed-text-gray-700'}`,
259
+ }, label)
260
+ : null,
261
+ ED.createElement('div', {
262
+ key: 'input-wrapper',
263
+ className: wrapperClasses,
264
+ style: { position: 'relative' },
265
+ children: [
266
+ prefixElement,
267
+ inputElement,
268
+ floatingLabelElement,
269
+ suffixElement,
270
+ ].filter(Boolean),
271
+ }),
272
+ ED.createElement('div', {
273
+ key: 'messages',
274
+ className: 'ed-flex ed-justify-between',
275
+ children: [messageElement, charCount].filter(Boolean),
276
+ }),
277
+ ].filter(Boolean),
278
+ });
279
+ }
280
+
281
+ Input.displayName = 'Input';
282
+ Input.SIZES = INPUT_SIZES;
283
+ Input.STATES = VALIDATION_STATES;
284
+
285
+ module.exports = Input;