@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.
- package/LICENSE +21 -0
- package/README.md +708 -0
- package/dist/__tests__/Anchor.test.js +145 -0
- package/dist/__tests__/ArrowRight.test.js +91 -0
- package/dist/__tests__/Avatar.test.js +123 -0
- package/dist/__tests__/Button.test.js +82 -0
- package/dist/__tests__/Card.test.js +198 -0
- package/dist/__tests__/CheckCircle.test.js +98 -0
- package/dist/__tests__/Checkbox.test.js +161 -0
- package/dist/__tests__/ChevronDown.test.js +73 -0
- package/dist/__tests__/Close.test.js +98 -0
- package/dist/__tests__/EditSquare.test.js +99 -0
- package/dist/__tests__/Error.test.js +74 -0
- package/dist/__tests__/Footer.test.js +66 -0
- package/dist/__tests__/Heading.test.js +227 -0
- package/dist/__tests__/Hero.test.js +74 -0
- package/dist/__tests__/Label.test.js +123 -0
- package/dist/__tests__/Loader.test.js +115 -0
- package/dist/__tests__/MenuHover.test.js +137 -0
- package/dist/__tests__/Paragraph.test.js +93 -0
- package/dist/__tests__/PlusCircle.test.js +99 -0
- package/dist/__tests__/Radio.test.js +153 -0
- package/dist/__tests__/Select.test.js +187 -0
- package/dist/__tests__/Tabs.test.js +162 -0
- package/dist/__tests__/TextArea.test.js +127 -0
- package/dist/__tests__/TextInput.test.js +181 -0
- package/dist/__tests__/Toggle.test.js +120 -0
- package/dist/__tests__/TrashX.test.js +99 -0
- package/dist/__tests__/useHeadingAccessibility.test.js +144 -0
- package/dist/components/Anchor.js +131 -0
- package/dist/components/Animation.js +129 -0
- package/dist/components/AnimationGroup.js +207 -0
- package/dist/components/AnimationToggle.js +216 -0
- package/dist/components/Avatar.js +153 -0
- package/dist/components/Button.js +218 -0
- package/dist/components/Card.js +222 -0
- package/dist/components/Checkbox.js +305 -0
- package/dist/components/Crud.js +564 -0
- package/dist/components/DragAndDrop.js +337 -0
- package/dist/components/Error.js +206 -0
- package/dist/components/Footer.js +99 -0
- package/dist/components/Form.js +412 -0
- package/dist/components/Header.js +372 -0
- package/dist/components/Heading.js +134 -0
- package/dist/components/Hero.js +181 -0
- package/dist/components/Label.js +256 -0
- package/dist/components/Loader.js +302 -0
- package/dist/components/MenuHover.js +114 -0
- package/dist/components/Paragraph.js +128 -0
- package/dist/components/Prompt.js +61 -0
- package/dist/components/Radio.js +254 -0
- package/dist/components/Select.js +422 -0
- package/dist/components/SideMenu.js +313 -0
- package/dist/components/Tabs.js +297 -0
- package/dist/components/TextArea.js +370 -0
- package/dist/components/TextInput.js +286 -0
- package/dist/components/Toggle.js +186 -0
- package/dist/components/crudFiles/CrudEditBase.js +150 -0
- package/dist/components/crudFiles/CrudViewBase.js +39 -0
- package/dist/components/crudFiles/crudDevelopment.js +118 -0
- package/dist/components/crudFiles/crudEditHandlers.js +50 -0
- package/dist/constants/animation.js +30 -0
- package/dist/icons/ArrowIcon.js +32 -0
- package/dist/icons/ArrowRight.js +33 -0
- package/dist/icons/CheckCircle.js +33 -0
- package/dist/icons/ChevronDown.js +28 -0
- package/dist/icons/Close.js +33 -0
- package/dist/icons/EditSquare.js +33 -0
- package/dist/icons/Ellipses.js +34 -0
- package/dist/icons/Hamburger.js +39 -0
- package/dist/icons/LoadingSpinner.js +42 -0
- package/dist/icons/PlusCircle.js +33 -0
- package/dist/icons/SaveIcon.js +32 -0
- package/dist/icons/TrashX.js +33 -0
- package/dist/icons/__tests__/CheckCircle.test.js +9 -0
- package/dist/icons/__tests__/ChevronDown.test.js +9 -0
- package/dist/icons/__tests__/Close.test.js +9 -0
- package/dist/icons/__tests__/EditSquare.test.js +9 -0
- package/dist/icons/__tests__/PlusCircle.test.js +9 -0
- package/dist/icons/__tests__/TrashX.test.js +9 -0
- package/dist/icons/index.js +89 -0
- package/dist/index.js +332 -0
- package/dist/setupTests.js +3 -0
- package/dist/styles/_variables.scss +286 -0
- package/dist/styles/anchor.scss +40 -0
- package/dist/styles/animation-accessibility.scss +96 -0
- package/dist/styles/animation-toggle.scss +233 -0
- package/dist/styles/animation.scss +3781 -0
- package/dist/styles/avatar.scss +285 -0
- package/dist/styles/button.scss +430 -0
- package/dist/styles/card.scss +210 -0
- package/dist/styles/checkbox.scss +160 -0
- package/dist/styles/crud.scss +474 -0
- package/dist/styles/dragAndDrop.scss +312 -0
- package/dist/styles/error.scss +232 -0
- package/dist/styles/footer.scss +58 -0
- package/dist/styles/form.scss +420 -0
- package/dist/styles/grid.scss +29 -0
- package/dist/styles/header.scss +276 -0
- package/dist/styles/heading.scss +118 -0
- package/dist/styles/hero.scss +185 -0
- package/dist/styles/htmlElements.scss +20 -0
- package/dist/styles/image.scss +9 -0
- package/dist/styles/label.scss +340 -0
- package/dist/styles/list-item.scss +5 -0
- package/dist/styles/loader.scss +354 -0
- package/dist/styles/logo.scss +19 -0
- package/dist/styles/main.css +9056 -0
- package/dist/styles/main.css.map +1 -0
- package/dist/styles/main.scss +0 -0
- package/dist/styles/menu-hover.scss +30 -0
- package/dist/styles/paragraph.scss +88 -0
- package/dist/styles/prompt.scss +51 -0
- package/dist/styles/radio.scss +202 -0
- package/dist/styles/select.scss +363 -0
- package/dist/styles/side-menu.scss +334 -0
- package/dist/styles/tabs.scss +540 -0
- package/dist/styles/text-area.scss +388 -0
- package/dist/styles/text-input.scss +171 -0
- package/dist/styles/toggle.scss +0 -0
- package/dist/styles/unordered-list.scss +8 -0
- package/dist/utils/ScrollHandler.js +30 -0
- package/dist/utils/accessibility.js +128 -0
- package/dist/utils/heroUtils.js +316 -0
- package/dist/utils/index.js +104 -0
- package/dist/utils/inputValidation.js +29 -0
- package/dist/utils/keyboardNavigation.js +536 -0
- package/dist/utils/labelUtils.js +708 -0
- package/dist/utils/loaderUtils.js +387 -0
- package/dist/utils/menuUtils.js +575 -0
- package/dist/utils/useHeadingAccessibility.js +298 -0
- package/dist/utils/useRadioGroup.js +260 -0
- package/dist/utils/useSelectAccessibility.js +426 -0
- package/dist/utils/useTabsAccessibility.js +278 -0
- package/dist/utils/useTextAreaAccessibility.js +255 -0
- package/dist/utils/useTextInputAccessibility.js +295 -0
- package/dist/utils/useTypographyAccessibility.js +168 -0
- package/dist/utils/useWindowSize.js +32 -0
- package/dist/utils/utils/ScrollHandler.js +26 -0
- package/dist/utils/utils/accessibility.js +133 -0
- package/dist/utils/utils/heroUtils.js +348 -0
- package/dist/utils/utils/index.js +9 -0
- package/dist/utils/utils/inputValidation.js +22 -0
- package/dist/utils/utils/keyboardNavigation.js +664 -0
- package/dist/utils/utils/labelUtils.js +772 -0
- package/dist/utils/utils/loaderUtils.js +436 -0
- package/dist/utils/utils/menuUtils.js +651 -0
- package/dist/utils/utils/useHeadingAccessibility.js +334 -0
- package/dist/utils/utils/useRadioGroup.js +311 -0
- package/dist/utils/utils/useSelectAccessibility.js +498 -0
- package/dist/utils/utils/useTabsAccessibility.js +316 -0
- package/dist/utils/utils/useTextAreaAccessibility.js +303 -0
- package/dist/utils/utils/useTextInputAccessibility.js +338 -0
- package/dist/utils/utils/useTypographyAccessibility.js +180 -0
- package/dist/utils/utils/useWindowSize.js +26 -0
- package/dist/utils/utils/validation.js +131 -0
- package/dist/utils/validation.js +139 -0
- 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
|
+
};
|