@abstraks-dev/ui-library 1.0.1

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 (158) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +708 -0
  3. package/dist/__tests__/Anchor.test.js +145 -0
  4. package/dist/__tests__/ArrowRight.test.js +91 -0
  5. package/dist/__tests__/Avatar.test.js +123 -0
  6. package/dist/__tests__/Button.test.js +82 -0
  7. package/dist/__tests__/Card.test.js +198 -0
  8. package/dist/__tests__/CheckCircle.test.js +98 -0
  9. package/dist/__tests__/Checkbox.test.js +161 -0
  10. package/dist/__tests__/ChevronDown.test.js +73 -0
  11. package/dist/__tests__/Close.test.js +98 -0
  12. package/dist/__tests__/EditSquare.test.js +99 -0
  13. package/dist/__tests__/Error.test.js +74 -0
  14. package/dist/__tests__/Footer.test.js +66 -0
  15. package/dist/__tests__/Heading.test.js +227 -0
  16. package/dist/__tests__/Hero.test.js +74 -0
  17. package/dist/__tests__/Label.test.js +123 -0
  18. package/dist/__tests__/Loader.test.js +115 -0
  19. package/dist/__tests__/MenuHover.test.js +137 -0
  20. package/dist/__tests__/Paragraph.test.js +93 -0
  21. package/dist/__tests__/PlusCircle.test.js +99 -0
  22. package/dist/__tests__/Radio.test.js +153 -0
  23. package/dist/__tests__/Select.test.js +187 -0
  24. package/dist/__tests__/Tabs.test.js +162 -0
  25. package/dist/__tests__/TextArea.test.js +127 -0
  26. package/dist/__tests__/TextInput.test.js +181 -0
  27. package/dist/__tests__/Toggle.test.js +120 -0
  28. package/dist/__tests__/TrashX.test.js +99 -0
  29. package/dist/__tests__/useHeadingAccessibility.test.js +144 -0
  30. package/dist/components/Anchor.js +131 -0
  31. package/dist/components/Animation.js +129 -0
  32. package/dist/components/AnimationGroup.js +207 -0
  33. package/dist/components/AnimationToggle.js +216 -0
  34. package/dist/components/Avatar.js +153 -0
  35. package/dist/components/Button.js +218 -0
  36. package/dist/components/Card.js +222 -0
  37. package/dist/components/Checkbox.js +305 -0
  38. package/dist/components/Crud.js +564 -0
  39. package/dist/components/DragAndDrop.js +337 -0
  40. package/dist/components/Error.js +206 -0
  41. package/dist/components/Footer.js +99 -0
  42. package/dist/components/Form.js +412 -0
  43. package/dist/components/Header.js +372 -0
  44. package/dist/components/Heading.js +134 -0
  45. package/dist/components/Hero.js +181 -0
  46. package/dist/components/Label.js +256 -0
  47. package/dist/components/Loader.js +302 -0
  48. package/dist/components/MenuHover.js +114 -0
  49. package/dist/components/Paragraph.js +128 -0
  50. package/dist/components/Prompt.js +61 -0
  51. package/dist/components/Radio.js +254 -0
  52. package/dist/components/Select.js +422 -0
  53. package/dist/components/SideMenu.js +313 -0
  54. package/dist/components/Tabs.js +297 -0
  55. package/dist/components/TextArea.js +370 -0
  56. package/dist/components/TextInput.js +286 -0
  57. package/dist/components/Toggle.js +186 -0
  58. package/dist/components/crudFiles/CrudEditBase.js +150 -0
  59. package/dist/components/crudFiles/CrudViewBase.js +39 -0
  60. package/dist/components/crudFiles/crudDevelopment.js +118 -0
  61. package/dist/components/crudFiles/crudEditHandlers.js +50 -0
  62. package/dist/constants/animation.js +30 -0
  63. package/dist/icons/ArrowIcon.js +32 -0
  64. package/dist/icons/ArrowRight.js +33 -0
  65. package/dist/icons/CheckCircle.js +33 -0
  66. package/dist/icons/ChevronDown.js +28 -0
  67. package/dist/icons/Close.js +33 -0
  68. package/dist/icons/EditSquare.js +33 -0
  69. package/dist/icons/Ellipses.js +34 -0
  70. package/dist/icons/Hamburger.js +39 -0
  71. package/dist/icons/LoadingSpinner.js +42 -0
  72. package/dist/icons/PlusCircle.js +33 -0
  73. package/dist/icons/SaveIcon.js +32 -0
  74. package/dist/icons/TrashX.js +33 -0
  75. package/dist/icons/__tests__/CheckCircle.test.js +9 -0
  76. package/dist/icons/__tests__/ChevronDown.test.js +9 -0
  77. package/dist/icons/__tests__/Close.test.js +9 -0
  78. package/dist/icons/__tests__/EditSquare.test.js +9 -0
  79. package/dist/icons/__tests__/PlusCircle.test.js +9 -0
  80. package/dist/icons/__tests__/TrashX.test.js +9 -0
  81. package/dist/icons/index.js +89 -0
  82. package/dist/index.js +332 -0
  83. package/dist/setupTests.js +3 -0
  84. package/dist/styles/_variables.scss +286 -0
  85. package/dist/styles/anchor.scss +40 -0
  86. package/dist/styles/animation-accessibility.scss +96 -0
  87. package/dist/styles/animation-toggle.scss +233 -0
  88. package/dist/styles/animation.scss +3781 -0
  89. package/dist/styles/avatar.scss +285 -0
  90. package/dist/styles/button.scss +430 -0
  91. package/dist/styles/card.scss +210 -0
  92. package/dist/styles/checkbox.scss +160 -0
  93. package/dist/styles/crud.scss +474 -0
  94. package/dist/styles/dragAndDrop.scss +312 -0
  95. package/dist/styles/error.scss +232 -0
  96. package/dist/styles/footer.scss +58 -0
  97. package/dist/styles/form.scss +420 -0
  98. package/dist/styles/grid.scss +29 -0
  99. package/dist/styles/header.scss +276 -0
  100. package/dist/styles/heading.scss +118 -0
  101. package/dist/styles/hero.scss +185 -0
  102. package/dist/styles/htmlElements.scss +20 -0
  103. package/dist/styles/image.scss +9 -0
  104. package/dist/styles/label.scss +340 -0
  105. package/dist/styles/list-item.scss +5 -0
  106. package/dist/styles/loader.scss +354 -0
  107. package/dist/styles/logo.scss +19 -0
  108. package/dist/styles/main.css +9056 -0
  109. package/dist/styles/main.css.map +1 -0
  110. package/dist/styles/main.scss +0 -0
  111. package/dist/styles/menu-hover.scss +30 -0
  112. package/dist/styles/paragraph.scss +88 -0
  113. package/dist/styles/prompt.scss +51 -0
  114. package/dist/styles/radio.scss +202 -0
  115. package/dist/styles/select.scss +363 -0
  116. package/dist/styles/side-menu.scss +334 -0
  117. package/dist/styles/tabs.scss +540 -0
  118. package/dist/styles/text-area.scss +388 -0
  119. package/dist/styles/text-input.scss +171 -0
  120. package/dist/styles/toggle.scss +0 -0
  121. package/dist/styles/unordered-list.scss +8 -0
  122. package/dist/utils/ScrollHandler.js +30 -0
  123. package/dist/utils/accessibility.js +128 -0
  124. package/dist/utils/heroUtils.js +316 -0
  125. package/dist/utils/index.js +104 -0
  126. package/dist/utils/inputValidation.js +29 -0
  127. package/dist/utils/keyboardNavigation.js +536 -0
  128. package/dist/utils/labelUtils.js +708 -0
  129. package/dist/utils/loaderUtils.js +387 -0
  130. package/dist/utils/menuUtils.js +575 -0
  131. package/dist/utils/useHeadingAccessibility.js +298 -0
  132. package/dist/utils/useRadioGroup.js +260 -0
  133. package/dist/utils/useSelectAccessibility.js +426 -0
  134. package/dist/utils/useTabsAccessibility.js +278 -0
  135. package/dist/utils/useTextAreaAccessibility.js +255 -0
  136. package/dist/utils/useTextInputAccessibility.js +295 -0
  137. package/dist/utils/useTypographyAccessibility.js +168 -0
  138. package/dist/utils/useWindowSize.js +32 -0
  139. package/dist/utils/utils/ScrollHandler.js +26 -0
  140. package/dist/utils/utils/accessibility.js +133 -0
  141. package/dist/utils/utils/heroUtils.js +348 -0
  142. package/dist/utils/utils/index.js +9 -0
  143. package/dist/utils/utils/inputValidation.js +22 -0
  144. package/dist/utils/utils/keyboardNavigation.js +664 -0
  145. package/dist/utils/utils/labelUtils.js +772 -0
  146. package/dist/utils/utils/loaderUtils.js +436 -0
  147. package/dist/utils/utils/menuUtils.js +651 -0
  148. package/dist/utils/utils/useHeadingAccessibility.js +334 -0
  149. package/dist/utils/utils/useRadioGroup.js +311 -0
  150. package/dist/utils/utils/useSelectAccessibility.js +498 -0
  151. package/dist/utils/utils/useTabsAccessibility.js +316 -0
  152. package/dist/utils/utils/useTextAreaAccessibility.js +303 -0
  153. package/dist/utils/utils/useTextInputAccessibility.js +338 -0
  154. package/dist/utils/utils/useTypographyAccessibility.js +180 -0
  155. package/dist/utils/utils/useWindowSize.js +26 -0
  156. package/dist/utils/utils/validation.js +131 -0
  157. package/dist/utils/validation.js +139 -0
  158. package/package.json +90 -0
@@ -0,0 +1,412 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.Form = void 0;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _propTypes = require("prop-types");
9
+ var _accessibility = require("../utils/accessibility.js");
10
+ require("../styles/form.scss");
11
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
12
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
13
+ /**
14
+ * Form - A stateless, accessible form component with validation and error handling
15
+ *
16
+ return (
17
+ <Animation fadingEntrances="fadeIn" duration="faster">
18
+ <form
19
+ ref={ref}
20
+ className={`${componentName}-wrapper ${additionalClassName}`.trim()}
21
+ aria-label={ariaLabel}
22
+ aria-labelledby={ariaLabelledBy}
23
+ aria-describedby={ariaDescribedBy}
24
+ noValidate={noValidate}
25
+ autoComplete={autoComplete}
26
+ method={method}
27
+ action={action}
28
+ encType={encType}
29
+ target={target}
30
+ acceptCharset={acceptCharset}
31
+ role={role}
32
+ id={id}
33
+ onSubmit={handleSubmit}
34
+ {...props}
35
+ >
36
+ {children}
37
+ </form>
38
+ </Animation>
39
+ );
40
+ * }
41
+ * }}
42
+ * validationMode="onBlur"
43
+ * ariaLabel="User registration form"
44
+ * >
45
+ * <FormField name="email" required>
46
+ * <TextInput />
47
+ * </FormField>
48
+ * <Button type="submit">Submit</Button>
49
+ * </Form>
50
+ */
51
+ const Form = exports.Form = /*#__PURE__*/(0, _react.forwardRef)(({
52
+ componentName = 'form',
53
+ additionalClassName = '',
54
+ children = null,
55
+ onSubmit,
56
+ onChange,
57
+ onValidate,
58
+ validationMode = 'onSubmit',
59
+ noValidate = true,
60
+ autoComplete = 'on',
61
+ method = 'post',
62
+ action = '',
63
+ encType = 'application/x-www-form-urlencoded',
64
+ target = '_self',
65
+ acceptCharset = 'UTF-8',
66
+ ariaLabel = '',
67
+ ariaDescribedBy = '',
68
+ ariaLabelledBy = '',
69
+ disabled = false,
70
+ isSubmitting = false,
71
+ errors = {},
72
+ resetOnSubmit = false,
73
+ announceErrors = true,
74
+ announceSuccess = true,
75
+ id = '',
76
+ role = 'form',
77
+ ...props
78
+ }, ref) => {
79
+ const [formData, setFormData] = (0, _react.useState)({});
80
+ const [touched, setTouched] = (0, _react.useState)({});
81
+ const [localErrors, setLocalErrors] = (0, _react.useState)({});
82
+ const [submissionCount, setSubmissionCount] = (0, _react.useState)(0);
83
+
84
+ // Merge external errors with local errors
85
+ const allErrors = {
86
+ ...localErrors,
87
+ ...errors
88
+ };
89
+ const hasErrors = Object.keys(allErrors).length > 0;
90
+
91
+ /**
92
+ * Validates a single field
93
+ * @param {string} fieldName - Name of the field to validate
94
+ * @param {*} value - Value to validate
95
+ * @returns {string|null} Error message or null if valid
96
+ */
97
+ const validateField = (0, _react.useCallback)((fieldName, value) => {
98
+ if (!onValidate) return null;
99
+ return onValidate(fieldName, value, formData);
100
+ }, [onValidate, formData]);
101
+
102
+ /**
103
+ * Updates form data and handles validation based on mode
104
+ */
105
+ const updateFormData = (0, _react.useCallback)((fieldName, value) => {
106
+ const newFormData = {
107
+ ...formData,
108
+ [fieldName]: value
109
+ };
110
+ setFormData(newFormData);
111
+
112
+ // Real-time validation for onChange mode
113
+ if (validationMode === 'onChange' || touched[fieldName]) {
114
+ const error = validateField(fieldName, value);
115
+ setLocalErrors(prev => ({
116
+ ...prev,
117
+ [fieldName]: error
118
+ }));
119
+ }
120
+ onChange?.(newFormData, fieldName, value);
121
+ }, [formData, validationMode, touched, validateField, onChange]);
122
+
123
+ /**
124
+ * Handles field blur events for onBlur validation
125
+ */
126
+ const handleFieldBlur = (0, _react.useCallback)((fieldName, value) => {
127
+ setTouched(prev => ({
128
+ ...prev,
129
+ [fieldName]: true
130
+ }));
131
+ if (validationMode === 'onBlur' || validationMode === 'onChange') {
132
+ const error = validateField(fieldName, value);
133
+ setLocalErrors(prev => ({
134
+ ...prev,
135
+ [fieldName]: error
136
+ }));
137
+
138
+ // Announce validation errors
139
+ if (error && announceErrors) {
140
+ (0, _accessibility.announceToScreenReader)(`${fieldName}: ${error}`, 'assertive');
141
+ }
142
+ }
143
+ }, [validationMode, validateField, announceErrors]);
144
+
145
+ /**
146
+ * Validates all form fields
147
+ * @returns {Object} Object containing all field errors
148
+ */
149
+ const validateAllFields = (0, _react.useCallback)(() => {
150
+ if (!onValidate) return {};
151
+ const newErrors = {};
152
+ Object.keys(formData).forEach(fieldName => {
153
+ const error = validateField(fieldName, formData[fieldName]);
154
+ if (error) {
155
+ newErrors[fieldName] = error;
156
+ }
157
+ });
158
+ return newErrors;
159
+ }, [formData, validateField, onValidate]);
160
+
161
+ /**
162
+ * Handles form submission
163
+ */
164
+ const handleSubmit = (0, _react.useCallback)(async event => {
165
+ event.preventDefault();
166
+ if (disabled || isSubmitting) return;
167
+ setSubmissionCount(prev => prev + 1);
168
+
169
+ // Validate all fields on submit
170
+ const validationErrors = validateAllFields();
171
+ setLocalErrors(validationErrors);
172
+ const hasValidationErrors = Object.keys(validationErrors).length > 0;
173
+ if (hasValidationErrors) {
174
+ // Focus first error field
175
+ const firstErrorField = Object.keys(validationErrors)[0];
176
+ const errorElement = document.querySelector(`[name="${firstErrorField}"]`);
177
+ if (errorElement) {
178
+ (0, _accessibility.safeFocus)(errorElement);
179
+ }
180
+
181
+ // Announce validation failure
182
+ if (announceErrors) {
183
+ const errorCount = Object.keys(validationErrors).length;
184
+ (0, _accessibility.announceToScreenReader)(`Form submission failed. ${errorCount} field${errorCount !== 1 ? 's' : ''} ${errorCount !== 1 ? 'have' : 'has'} validation errors.`, 'assertive');
185
+ }
186
+ return;
187
+ }
188
+ try {
189
+ // Provide form utilities to onSubmit callback
190
+ const formUtils = {
191
+ setErrors: setLocalErrors,
192
+ setFormData,
193
+ resetForm: () => {
194
+ setFormData({});
195
+ setLocalErrors({});
196
+ setTouched({});
197
+ },
198
+ updateField: updateFormData
199
+ };
200
+ await onSubmit?.(formData, formUtils, event);
201
+
202
+ // Reset form if requested
203
+ if (resetOnSubmit) {
204
+ formUtils.resetForm();
205
+ }
206
+
207
+ // Announce success
208
+ if (announceSuccess) {
209
+ (0, _accessibility.announceToScreenReader)('Form submitted successfully', 'polite');
210
+ }
211
+ } catch (error) {
212
+ // Let the onSubmit handler manage errors, but provide fallback
213
+ logError('Form submission error:', error);
214
+ if (announceErrors) {
215
+ (0, _accessibility.announceToScreenReader)('Form submission failed', 'assertive');
216
+ }
217
+ }
218
+ }, [disabled, isSubmitting, validateAllFields, onSubmit, formData, resetOnSubmit, announceSuccess, announceErrors, updateFormData]);
219
+
220
+ // Generate comprehensive class names
221
+ const classNames = [componentName, additionalClassName, disabled && `${componentName}--disabled`, isSubmitting && `${componentName}--submitting`, hasErrors && `${componentName}--has-errors`].filter(Boolean).join(' ');
222
+
223
+ // Enhanced children with form context
224
+ const enhancedChildren = _react.default.Children.map(children, child => {
225
+ if (/*#__PURE__*/_react.default.isValidElement(child)) {
226
+ // Check if this is a form field that needs form context
227
+ const fieldName = child.props?.name || child.props?.setName;
228
+ if (fieldName) {
229
+ return /*#__PURE__*/_react.default.cloneElement(child, {
230
+ error: allErrors[fieldName],
231
+ errorText: allErrors[fieldName],
232
+ value: formData[fieldName] || child.props.value || '',
233
+ inputValue: formData[fieldName] || child.props.inputValue || '',
234
+ onChangeFunc: event => {
235
+ const value = event.target?.value !== undefined ? event.target.value : event;
236
+ updateFormData(fieldName, value);
237
+ child.props?.onChangeFunc?.(event);
238
+ },
239
+ onChange: event => {
240
+ const value = event.target?.value !== undefined ? event.target.value : event;
241
+ updateFormData(fieldName, value);
242
+ child.props?.onChange?.(event);
243
+ },
244
+ onBlur: event => {
245
+ const value = event.target?.value !== undefined ? event.target.value : formData[fieldName];
246
+ handleFieldBlur(fieldName, value);
247
+ child.props?.onBlur?.(event);
248
+ },
249
+ blur: event => {
250
+ const value = event.target?.value !== undefined ? event.target.value : formData[fieldName];
251
+ handleFieldBlur(fieldName, value);
252
+ child.props?.blur?.(event);
253
+ },
254
+ disabled: disabled || child.props?.disabled,
255
+ 'aria-invalid': !!allErrors[fieldName],
256
+ 'aria-describedby': allErrors[fieldName] ? `${fieldName}-error` : child.props?.['aria-describedby'],
257
+ ...child.props
258
+ });
259
+ }
260
+ }
261
+ return child;
262
+ });
263
+ return /*#__PURE__*/_react.default.createElement("form", _extends({
264
+ ref: ref,
265
+ className: classNames,
266
+ "data-testid": componentName,
267
+ onSubmit: handleSubmit,
268
+ noValidate: noValidate,
269
+ autoComplete: autoComplete,
270
+ method: method,
271
+ action: action,
272
+ encType: encType,
273
+ target: target,
274
+ acceptCharset: acceptCharset,
275
+ "aria-label": ariaLabel || undefined,
276
+ "aria-labelledby": ariaLabelledBy || undefined,
277
+ "aria-describedby": ariaDescribedBy || undefined,
278
+ role: role,
279
+ "aria-invalid": hasErrors,
280
+ id: id || undefined
281
+ }, props), /*#__PURE__*/_react.default.createElement("div", {
282
+ className: "sr-only",
283
+ "aria-live": "polite",
284
+ "aria-atomic": "true"
285
+ }), enhancedChildren, isSubmitting && /*#__PURE__*/_react.default.createElement("div", {
286
+ className: "sr-only",
287
+ "aria-live": "polite"
288
+ }, "Form is being submitted, please wait..."), hasErrors && /*#__PURE__*/_react.default.createElement("div", {
289
+ className: `${componentName}__errors-summary`,
290
+ role: "alert"
291
+ }, /*#__PURE__*/_react.default.createElement("p", {
292
+ className: `${componentName}__errors-title`
293
+ }, "Please correct the following errors:"), /*#__PURE__*/_react.default.createElement("ul", {
294
+ className: `${componentName}__errors-list`
295
+ }, Object.entries(allErrors).map(([fieldName, error]) => /*#__PURE__*/_react.default.createElement("li", {
296
+ key: fieldName,
297
+ className: `${componentName}__error-item`
298
+ }, /*#__PURE__*/_react.default.createElement("strong", null, fieldName, ":"), " ", error)))));
299
+ });
300
+ Form.propTypes = {
301
+ /**
302
+ * Base CSS class name for the component
303
+ */
304
+ componentName: _propTypes.string,
305
+ /**
306
+ * Additional CSS class names to apply to the form
307
+ */
308
+ additionalClassName: _propTypes.string,
309
+ /**
310
+ * Form content and fields
311
+ */
312
+ children: _propTypes.node.isRequired,
313
+ /**
314
+ * Form submission handler
315
+ * @param {Object} formData - Current form data
316
+ * @param {Object} formUtils - Utilities for form management
317
+ * @param {Event} event - Submit event
318
+ */
319
+ onSubmit: _propTypes.func,
320
+ /**
321
+ * Form change handler called when any field changes
322
+ * @param {Object} formData - Current form data
323
+ * @param {string} fieldName - Name of changed field
324
+ * @param {*} value - New field value
325
+ */
326
+ onChange: _propTypes.func,
327
+ /**
328
+ * Field validation function
329
+ * @param {string} fieldName - Name of field to validate
330
+ * @param {*} value - Field value
331
+ * @param {Object} formData - Complete form data
332
+ * @returns {string|null} Error message or null if valid
333
+ */
334
+ onValidate: _propTypes.func,
335
+ /**
336
+ * When to perform validation
337
+ */
338
+ validationMode: (0, _propTypes.oneOf)(['onSubmit', 'onBlur', 'onChange']),
339
+ /**
340
+ * HTML form noValidate attribute
341
+ */
342
+ noValidate: _propTypes.bool,
343
+ /**
344
+ * HTML form autoComplete attribute
345
+ */
346
+ autoComplete: _propTypes.string,
347
+ /**
348
+ * HTML form method attribute
349
+ */
350
+ method: (0, _propTypes.oneOf)(['get', 'post', 'dialog']),
351
+ /**
352
+ * HTML form action attribute
353
+ */
354
+ action: _propTypes.string,
355
+ /**
356
+ * HTML form encType attribute
357
+ */
358
+ encType: (0, _propTypes.oneOf)(['application/x-www-form-urlencoded', 'multipart/form-data', 'text/plain']),
359
+ /**
360
+ * HTML form target attribute
361
+ */
362
+ target: (0, _propTypes.oneOf)(['_self', '_blank', '_parent', '_top']),
363
+ /**
364
+ * HTML form acceptCharset attribute
365
+ */
366
+ acceptCharset: _propTypes.string,
367
+ /**
368
+ * Accessible label for the form
369
+ */
370
+ ariaLabel: _propTypes.string,
371
+ /**
372
+ * ID of element that describes the form
373
+ */
374
+ ariaDescribedBy: _propTypes.string,
375
+ /**
376
+ * ID of element that labels the form
377
+ */
378
+ ariaLabelledBy: _propTypes.string,
379
+ /**
380
+ * Whether the entire form is disabled
381
+ */
382
+ disabled: _propTypes.bool,
383
+ /**
384
+ * Whether the form is currently being submitted
385
+ */
386
+ isSubmitting: _propTypes.bool,
387
+ /**
388
+ * External errors object (field name: error message)
389
+ */
390
+ errors: _propTypes.object,
391
+ /**
392
+ * Whether to reset form data after successful submission
393
+ */
394
+ resetOnSubmit: _propTypes.bool,
395
+ /**
396
+ * Whether to announce errors to screen readers
397
+ */
398
+ announceErrors: _propTypes.bool,
399
+ /**
400
+ * Whether to announce successful submissions to screen readers
401
+ */
402
+ announceSuccess: _propTypes.bool,
403
+ /**
404
+ * HTML id attribute for the form
405
+ */
406
+ id: _propTypes.string,
407
+ /**
408
+ * ARIA role for the form
409
+ */
410
+ role: _propTypes.string
411
+ };
412
+ var _default = exports.default = Form;