@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,128 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.Paragraph = void 0;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _Animation = require("./Animation");
9
+ var _propTypes = require("prop-types");
10
+ 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); }
11
+ 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); }
12
+ /**
13
+ * Paragraph - Accessible paragraph component with semantic HTML
14
+ *
15
+ * Features:
16
+ * - Semantic paragraph element with proper typography
17
+ * - Multiple size variants for design hierarchy
18
+ * - Screen reader accessible
19
+ * - Responsive typography
20
+ * - High contrast mode support
21
+ * - Customizable styling through CSS classes
22
+ *
23
+ * Accessibility:
24
+ * - Uses semantic <p> element
25
+ * - Proper text contrast ratios
26
+ * - Supports high contrast mode
27
+ * - Responsive and readable typography
28
+ *
29
+ * @component
30
+ * @example
31
+ * // Basic paragraph
32
+ * <Paragraph>
33
+ * This is a standard paragraph with default styling.
34
+ * </Paragraph>
35
+ *
36
+ * @example
37
+ * // Large paragraph for emphasis
38
+ * <Paragraph size="large">
39
+ * This is a larger paragraph for emphasis or lead text.
40
+ * </Paragraph>
41
+ *
42
+ * @example
43
+ * // Small paragraph for secondary content
44
+ * <Paragraph size="small">
45
+ * This is smaller text for captions or secondary information.
46
+ * </Paragraph>
47
+ */
48
+ const Paragraph = exports.Paragraph = /*#__PURE__*/(0, _react.forwardRef)(({
49
+ // Core props
50
+ children = null,
51
+ // Layout props
52
+ className = '',
53
+ size = 'medium',
54
+ // Accessibility props
55
+ id,
56
+ // Legacy props (for backward compatibility - internal use only)
57
+ additionalClassName = '',
58
+ componentName = 'paragraph',
59
+ testId,
60
+ ...restProps
61
+ }, ref) => {
62
+ // Handle legacy prop mapping
63
+ const finalClassName = className || additionalClassName;
64
+ const finalComponentName = componentName || 'paragraph';
65
+ const finalId = id || (testId ? `${testId}` : undefined);
66
+
67
+ // Build CSS classes: root class is componentName, then size, then className
68
+ const paragraphClasses = [finalComponentName, size !== 'medium' && `${finalComponentName}--${size}`, finalClassName].filter(Boolean).join(' ').trim();
69
+ return /*#__PURE__*/_react.default.createElement(_Animation.AnimatedDiv, {
70
+ fadingEntrances: "fadeIn",
71
+ duration: "faster"
72
+ }, /*#__PURE__*/_react.default.createElement("p", _extends({
73
+ ref: ref,
74
+ id: finalId,
75
+ className: paragraphClasses,
76
+ "data-testid": testId || 'paragraph'
77
+ }, restProps), children));
78
+ });
79
+
80
+ // Set display name for debugging
81
+ Paragraph.displayName = 'Paragraph';
82
+ Paragraph.propTypes = {
83
+ // ============================================================================
84
+ // CORE PROPS
85
+ // ============================================================================
86
+
87
+ /**
88
+ * Unique identifier for the paragraph
89
+ */
90
+ id: _propTypes.string,
91
+ /**
92
+ * Additional CSS classes to apply to the paragraph element
93
+ */
94
+ className: _propTypes.string,
95
+ // ============================================================================
96
+ // CONTENT PROPS
97
+ // ============================================================================
98
+
99
+ /**
100
+ * Content to display in the paragraph
101
+ * @required Essential for meaningful paragraph content
102
+ */
103
+ children: _propTypes.node.isRequired,
104
+ // ============================================================================
105
+ // APPEARANCE PROPS
106
+ // ============================================================================
107
+
108
+ /**
109
+ * Size variant for typography hierarchy
110
+ * - 'small': For captions, fine print, or secondary information
111
+ * - 'medium': Default paragraph size for body text
112
+ * - 'large': For emphasis, lead paragraphs, or important content
113
+ */
114
+ size: (0, _propTypes.oneOf)(['small', 'medium', 'large']),
115
+ /**
116
+ * Use 'className' instead. Additional CSS classes to apply
117
+ */
118
+ additionalClassName: _propTypes.string,
119
+ /**
120
+ * Use 'id' instead. Base CSS class name for the component
121
+ */
122
+ componentName: _propTypes.string,
123
+ /**
124
+ * Use 'id' instead. Test identifier for the paragraph
125
+ */
126
+ testId: _propTypes.string
127
+ };
128
+ var _default = exports.default = Paragraph;
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.Prompt = void 0;
7
+ var _react = _interopRequireDefault(require("react"));
8
+ require("../styles/prompt.scss");
9
+ var _propTypes = _interopRequireDefault(require("prop-types"));
10
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
+ /**
12
+ * Prompt Component
13
+ * A simple modal-like prompt for confirmations and notifications.
14
+ *
15
+ * @param {string} message - The prompt message to display
16
+ * @param {function} onConfirm - Called when user confirms (optional)
17
+ * @param {function} onCancel - Called when user cancels/dismisses (optional)
18
+ * @param {string} confirmText - Text for confirm button (default: 'Yes')
19
+ * @param {string} cancelText - Text for cancel button (default: 'Cancel')
20
+ * @param {boolean} showCancel - Whether to show cancel button (default: true)
21
+ * @param {boolean} open - Whether the prompt is visible
22
+ */
23
+ const Prompt = ({
24
+ message,
25
+ onConfirm,
26
+ onCancel,
27
+ confirmText = 'Yes',
28
+ cancelText = 'Cancel',
29
+ showCancel = true,
30
+ open = false
31
+ }) => {
32
+ if (!open) return null;
33
+ return /*#__PURE__*/_react.default.createElement("div", {
34
+ className: "prompt-overlay",
35
+ role: "dialog",
36
+ "aria-modal": "true",
37
+ "aria-label": message
38
+ }, /*#__PURE__*/_react.default.createElement("div", {
39
+ className: "prompt-box"
40
+ }, /*#__PURE__*/_react.default.createElement("p", null, message), /*#__PURE__*/_react.default.createElement("div", {
41
+ className: "prompt-actions"
42
+ }, onConfirm && /*#__PURE__*/_react.default.createElement("button", {
43
+ className: "prompt-confirm",
44
+ onClick: onConfirm,
45
+ autoFocus: true
46
+ }, confirmText), showCancel && /*#__PURE__*/_react.default.createElement("button", {
47
+ className: "prompt-cancel",
48
+ onClick: onCancel
49
+ }, cancelText))));
50
+ };
51
+ exports.Prompt = Prompt;
52
+ Prompt.propTypes = {
53
+ message: _propTypes.default.string.isRequired,
54
+ onConfirm: _propTypes.default.func,
55
+ onCancel: _propTypes.default.func,
56
+ confirmText: _propTypes.default.string,
57
+ cancelText: _propTypes.default.string,
58
+ showCancel: _propTypes.default.bool,
59
+ open: _propTypes.default.bool
60
+ };
61
+ var _default = exports.default = Prompt;
@@ -0,0 +1,254 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.Radio = void 0;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _propTypes = require("prop-types");
9
+ var _Label = require("./Label");
10
+ var _Error = require("./Error");
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); } /*eslint-disable no-unused-vars*/ // components
13
+ /**
14
+ * Radio Component
15
+ *
16
+ * A fully accessible, modern radio button component following WCAG 2.1 AA guidelines.
17
+ * Features proper keyboard navigation, screen reader support, and form integration.
18
+ *
19
+ * This is a stateless component - state management should be handled externally.
20
+ * Radio buttons should always be used in groups with the same name attribute.
21
+ *
22
+ * @component
23
+ * @example
24
+ * // Basic radio group (stateless)
25
+ * <Radio
26
+ * id="color-red"
27
+ * name="color"
28
+ * value="red"
29
+ * checked={selectedColor === 'red'}
30
+ * onChange={handleColorChange}
31
+ * required
32
+ * >
33
+ * Red
34
+ * </Radio>
35
+ *
36
+ * @example
37
+ * // Required radio with error state
38
+ * <Radio
39
+ * id="agreement-accept"
40
+ * name="agreement"
41
+ * value="accept"
42
+ * checked={agreement === 'accept'}
43
+ * onChange={handleAgreementChange}
44
+ * required
45
+ * error={hasError}
46
+ * errorText="You must accept the terms"
47
+ * >
48
+ * I accept the terms and conditions
49
+ * </Radio>
50
+ */
51
+ const Radio = exports.Radio = /*#__PURE__*/(0, _react.forwardRef)(({
52
+ // Core props
53
+ id,
54
+ name,
55
+ value,
56
+ checked = false,
57
+ onChange,
58
+ onFocus,
59
+ onBlur,
60
+ // Content props
61
+ children,
62
+ label,
63
+ // Validation props
64
+ required = false,
65
+ disabled = false,
66
+ error = false,
67
+ errorText = '',
68
+ // Layout props
69
+ className = '',
70
+ variant = 'default',
71
+ size = 'medium',
72
+ // Accessibility props
73
+ 'aria-label': ariaLabel,
74
+ 'aria-labelledby': ariaLabelledby,
75
+ 'aria-describedby': ariaDescribedby,
76
+ 'aria-invalid': ariaInvalid,
77
+ // Legacy props (for backward compatibility - internal use only)
78
+ componentName = 'radio',
79
+ additionalClassName = '',
80
+ labelText = '',
81
+ testId,
82
+ ...restProps
83
+ }, ref) => {
84
+ // Handle legacy prop mapping
85
+ const finalId = id || testId || `radio-${name}-${value}-${Math.random().toString(36).substr(2, 9)}`.replace(/\s+/g, '-').toLowerCase();
86
+ const finalLabel = children || label || labelText || value;
87
+ const finalClassName = className || additionalClassName;
88
+
89
+ // Generate unique IDs for accessibility
90
+ const radioId = finalId;
91
+ const errorId = `${radioId}-error`;
92
+
93
+ // Build aria-describedby
94
+ const describedByIds = [];
95
+ if (ariaDescribedby) describedByIds.push(ariaDescribedby);
96
+ if (error && errorText) describedByIds.push(errorId);
97
+ const finalAriaDescribedby = describedByIds.length > 0 ? describedByIds.join(' ') : undefined;
98
+
99
+ // Determine aria-invalid
100
+ const finalAriaInvalid = ariaInvalid || (error ? 'true' : undefined);
101
+
102
+ // Build CSS classes
103
+ const wrapperClasses = [`${componentName}-wrapper`, finalClassName, `${componentName}-wrapper--${variant}`, `${componentName}-wrapper--${size}`, error && `${componentName}-wrapper--error`, disabled && `${componentName}-wrapper--disabled`, required && `${componentName}-wrapper--required`].filter(Boolean).join(' ');
104
+ const radioClasses = [componentName, `${componentName}--${variant}`, `${componentName}--${size}`, error && `${componentName}--error`, disabled && `${componentName}--disabled`, checked && `${componentName}--checked`].filter(Boolean).join(' ');
105
+ return /*#__PURE__*/_react.default.createElement("div", {
106
+ className: wrapperClasses,
107
+ "data-testid": testId || `${componentName}-wrapper`
108
+ }, /*#__PURE__*/_react.default.createElement(_Label.Label, {
109
+ htmlFor: radioId,
110
+ required: required,
111
+ labelText: finalLabel,
112
+ className: `${componentName}__label`
113
+ }, /*#__PURE__*/_react.default.createElement("input", _extends({
114
+ ref: ref,
115
+ id: radioId,
116
+ name: name,
117
+ type: "radio",
118
+ value: value,
119
+ checked: checked,
120
+ onChange: onChange,
121
+ onFocus: onFocus,
122
+ onBlur: onBlur,
123
+ className: radioClasses,
124
+ disabled: disabled,
125
+ "data-testid": testId || `${componentName}-input`
126
+ // Accessibility attributes
127
+ ,
128
+ "aria-label": !finalLabel ? ariaLabel : undefined,
129
+ "aria-labelledby": !finalLabel ? ariaLabelledby : undefined,
130
+ "aria-describedby": finalAriaDescribedby,
131
+ "aria-invalid": finalAriaInvalid,
132
+ "aria-required": required || undefined
133
+ }, restProps)), /*#__PURE__*/_react.default.createElement("span", {
134
+ className: "custom-radio"
135
+ }), finalLabel && /*#__PURE__*/_react.default.createElement("span", {
136
+ className: `${componentName}__label-text`
137
+ }, finalLabel)), error && errorText && /*#__PURE__*/_react.default.createElement(_Error.Error, {
138
+ id: errorId,
139
+ className: `${componentName}__error`,
140
+ role: "alert",
141
+ "aria-live": "polite"
142
+ }, errorText));
143
+ });
144
+
145
+ // Set display name for debugging
146
+ Radio.displayName = 'Radio';
147
+ Radio.propTypes = {
148
+ // ===========================================
149
+ // Core Props
150
+ // ===========================================
151
+ /**
152
+ * Unique identifier for the radio button
153
+ */
154
+ id: _propTypes.string,
155
+ /**
156
+ * Additional CSS classes
157
+ */
158
+ className: _propTypes.string,
159
+ /**
160
+ * Name attribute for the radio group (required for proper grouping)
161
+ * All radios in the same group must have the same name
162
+ */
163
+ name: _propTypes.string.isRequired,
164
+ /**
165
+ * Value for this radio option (required)
166
+ * Should be unique within the radio group
167
+ */
168
+ value: _propTypes.string.isRequired,
169
+ // ===========================================
170
+ // Content Props
171
+ // ===========================================
172
+ /**
173
+ * Label content (can be string or JSX)
174
+ */
175
+ children: _propTypes.node,
176
+ /**
177
+ * Alternative label prop
178
+ */
179
+ label: _propTypes.string,
180
+ // ===========================================
181
+ // Appearance Props
182
+ // ===========================================
183
+ /**
184
+ * Visual style variant
185
+ */
186
+ variant: _propTypes.string,
187
+ /**
188
+ * Size of the radio button
189
+ */
190
+ size: _propTypes.string,
191
+ // ===========================================
192
+ // Behavior Props
193
+ // ===========================================
194
+ /**
195
+ * Whether this radio is currently selected
196
+ */
197
+ checked: _propTypes.bool,
198
+ /**
199
+ * Whether the radio is required
200
+ */
201
+ required: _propTypes.bool,
202
+ /**
203
+ * Whether the radio is disabled
204
+ */
205
+ disabled: _propTypes.bool,
206
+ // ===========================================
207
+ // Validation Props
208
+ // ===========================================
209
+ /**
210
+ * Whether the field has an error
211
+ */
212
+ error: _propTypes.bool,
213
+ /**
214
+ * Error message to display when error is true
215
+ */
216
+ errorText: _propTypes.string,
217
+ // ===========================================
218
+ // Event Props
219
+ // ===========================================
220
+ /**
221
+ * Change handler function - called when radio is selected
222
+ * @param {Event} event - The change event
223
+ */
224
+ onChange: _propTypes.func.isRequired,
225
+ /**
226
+ * Focus handler function
227
+ * @param {Event} event - The focus event
228
+ */
229
+ onFocus: _propTypes.func,
230
+ /**
231
+ * Blur handler function
232
+ * @param {Event} event - The blur event
233
+ */
234
+ onBlur: _propTypes.func,
235
+ // ===========================================
236
+ // Accessibility Props
237
+ // ===========================================
238
+ /**
239
+ * Accessible label (alternative to children/label prop)
240
+ */
241
+ 'aria-label': _propTypes.string,
242
+ /**
243
+ * ID of element that labels this radio
244
+ */
245
+ 'aria-labelledby': _propTypes.string,
246
+ /**
247
+ * ID(s) of elements that describe this radio
248
+ */
249
+ 'aria-describedby': _propTypes.string,
250
+ /**
251
+ * Whether the radio value is invalid
252
+ */
253
+ 'aria-invalid': _propTypes.string
254
+ };