@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,422 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = exports.Select = void 0;
|
|
7
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
9
|
+
var _Label = require("./Label");
|
|
10
|
+
var _Error = require("./Error");
|
|
11
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
|
+
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); }
|
|
13
|
+
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); }
|
|
14
|
+
const {
|
|
15
|
+
string,
|
|
16
|
+
number,
|
|
17
|
+
bool,
|
|
18
|
+
arrayOf,
|
|
19
|
+
oneOfType,
|
|
20
|
+
shape,
|
|
21
|
+
element,
|
|
22
|
+
func,
|
|
23
|
+
object
|
|
24
|
+
} = _propTypes.default;
|
|
25
|
+
// components
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Select - Accessible dropdown selection component with comprehensive form support
|
|
29
|
+
*
|
|
30
|
+
* Features:
|
|
31
|
+
* - Full keyboard navigation (Tab, Space, Enter, Arrow keys, Escape)
|
|
32
|
+
* - Screen reader support with proper ARIA labeling
|
|
33
|
+
* - Form validation integration with error states
|
|
34
|
+
* - Multiple option formats (string, object, React elements)
|
|
35
|
+
* - Responsive design with consistent styling
|
|
36
|
+
* - High contrast mode support
|
|
37
|
+
* - Disabled and required state handling
|
|
38
|
+
* - Help text and error message support
|
|
39
|
+
*
|
|
40
|
+
* Accessibility:
|
|
41
|
+
* - Uses semantic <select> element with proper labeling
|
|
42
|
+
* - ARIA attributes for screen reader compatibility
|
|
43
|
+
* - Keyboard navigation following web standards
|
|
44
|
+
* - Error announcements with aria-live regions
|
|
45
|
+
* - Proper form association and validation
|
|
46
|
+
* - Focus management and tab order support
|
|
47
|
+
*
|
|
48
|
+
* @component
|
|
49
|
+
* @example
|
|
50
|
+
* // Basic usage with object options
|
|
51
|
+
* <Select
|
|
52
|
+
* name="country"
|
|
53
|
+
* label="Select Country"
|
|
54
|
+
* value={selectedCountry}
|
|
55
|
+
* onChange={handleCountryChange}
|
|
56
|
+
* options={[
|
|
57
|
+
* { value: 'us', label: 'United States' },
|
|
58
|
+
* { value: 'ca', label: 'Canada' }
|
|
59
|
+
* ]}
|
|
60
|
+
* />
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* // With validation and help text
|
|
64
|
+
* <Select
|
|
65
|
+
* name="size"
|
|
66
|
+
* label="Size"
|
|
67
|
+
* value={size}
|
|
68
|
+
* onChange={handleSizeChange}
|
|
69
|
+
* options={sizeOptions}
|
|
70
|
+
* required
|
|
71
|
+
* error={hasError}
|
|
72
|
+
* errorText="Please select a size"
|
|
73
|
+
* helpText="Choose the size that fits best"
|
|
74
|
+
* />
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* // Multiple selection with custom styling
|
|
78
|
+
* <Select
|
|
79
|
+
* name="tags"
|
|
80
|
+
* label="Select Tags"
|
|
81
|
+
* value={selectedTags}
|
|
82
|
+
* onChange={handleTagsChange}
|
|
83
|
+
* options={tagOptions}
|
|
84
|
+
* multiple
|
|
85
|
+
* className="custom-select"
|
|
86
|
+
* />
|
|
87
|
+
*/
|
|
88
|
+
const Select = exports.Select = /*#__PURE__*/(0, _react.forwardRef)(({
|
|
89
|
+
// Core props (required)
|
|
90
|
+
name,
|
|
91
|
+
label,
|
|
92
|
+
onChange = () => {},
|
|
93
|
+
// Provide default no-op function to prevent React warnings // Content props
|
|
94
|
+
value = '',
|
|
95
|
+
options = [],
|
|
96
|
+
placeholder = 'Select an option',
|
|
97
|
+
helpText = '',
|
|
98
|
+
// Legacy compatibility - handle old prop names
|
|
99
|
+
additionalClassName,
|
|
100
|
+
componentName = 'Select',
|
|
101
|
+
setName,
|
|
102
|
+
// legacy name prop
|
|
103
|
+
selectOptions,
|
|
104
|
+
// legacy options prop
|
|
105
|
+
defaultValue,
|
|
106
|
+
// legacy placeholder prop
|
|
107
|
+
noLabel,
|
|
108
|
+
// legacy hideLabel prop
|
|
109
|
+
|
|
110
|
+
// Layout props
|
|
111
|
+
className: classNameProp = '',
|
|
112
|
+
hideLabel = false,
|
|
113
|
+
multiple = false,
|
|
114
|
+
size,
|
|
115
|
+
// Validation props
|
|
116
|
+
required = false,
|
|
117
|
+
disabled = false,
|
|
118
|
+
error = false,
|
|
119
|
+
errorText = '',
|
|
120
|
+
// Accessibility props
|
|
121
|
+
id,
|
|
122
|
+
ariaLabel,
|
|
123
|
+
ariaDescribedBy,
|
|
124
|
+
ariaRequired,
|
|
125
|
+
tabIndex,
|
|
126
|
+
// Event handlers
|
|
127
|
+
onFocus,
|
|
128
|
+
onBlur,
|
|
129
|
+
onKeyDown,
|
|
130
|
+
// Styling props
|
|
131
|
+
style = {},
|
|
132
|
+
// Testing props
|
|
133
|
+
'data-testid': dataTestId,
|
|
134
|
+
'data-cy': dataCy,
|
|
135
|
+
...restProps
|
|
136
|
+
}, ref) => {
|
|
137
|
+
// Handle legacy prop mapping for backward compatibility
|
|
138
|
+
const finalName = name || setName;
|
|
139
|
+
const finalLabel = label || (setName && !noLabel ? setName : '');
|
|
140
|
+
const finalOptions = options.length > 0 ? options : selectOptions || [];
|
|
141
|
+
const finalPlaceholder = placeholder !== 'Select an option' ? placeholder : defaultValue || placeholder;
|
|
142
|
+
const finalHideLabel = hideLabel || noLabel || false;
|
|
143
|
+
const className = classNameProp || additionalClassName || '';
|
|
144
|
+
|
|
145
|
+
// Log deprecation warnings for legacy props (development only)
|
|
146
|
+
if (process.env.NODE_ENV === 'development') {
|
|
147
|
+
if (additionalClassName) {
|
|
148
|
+
console.warn(`${componentName}: 'additionalClassName' prop is deprecated. Use 'className' instead.`);
|
|
149
|
+
}
|
|
150
|
+
if (setName) {
|
|
151
|
+
console.warn(`${componentName}: 'setName' prop is deprecated. Use 'name' instead.`);
|
|
152
|
+
}
|
|
153
|
+
if (selectOptions) {
|
|
154
|
+
console.warn(`${componentName}: 'selectOptions' prop is deprecated. Use 'options' instead.`);
|
|
155
|
+
}
|
|
156
|
+
if (defaultValue) {
|
|
157
|
+
console.warn(`${componentName}: 'defaultValue' prop is deprecated. Use 'placeholder' instead.`);
|
|
158
|
+
}
|
|
159
|
+
if (noLabel !== undefined) {
|
|
160
|
+
console.warn(`${componentName}: 'noLabel' prop is deprecated. Use 'hideLabel' instead.`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
// Generate unique ID if not provided
|
|
164
|
+
const selectId = id || `select-${finalName}`;
|
|
165
|
+
const errorId = `${selectId}-error`;
|
|
166
|
+
const helpTextId = `${selectId}-help`;
|
|
167
|
+
|
|
168
|
+
// Calculate aria-describedby
|
|
169
|
+
const describedBy = [ariaDescribedBy, helpText ? helpTextId : null, error && errorText ? errorId : null].filter(Boolean).join(' ') || undefined;
|
|
170
|
+
|
|
171
|
+
// Handle keyboard navigation
|
|
172
|
+
const handleKeyDown = event => {
|
|
173
|
+
// Let native select handle most keyboard interactions
|
|
174
|
+
// Custom logic can be added here if needed
|
|
175
|
+
onKeyDown?.(event);
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
// Render options from array format
|
|
179
|
+
const renderOptions = () => {
|
|
180
|
+
if (!finalOptions || finalOptions.length === 0) return null;
|
|
181
|
+
return finalOptions.map((option, index) => {
|
|
182
|
+
// Support both object format { value, label } and string format
|
|
183
|
+
if (typeof option === 'string') {
|
|
184
|
+
return /*#__PURE__*/_react.default.createElement("option", {
|
|
185
|
+
key: `${option}-${index}`,
|
|
186
|
+
value: option
|
|
187
|
+
}, option);
|
|
188
|
+
}
|
|
189
|
+
if (typeof option === 'object' && option.value !== undefined) {
|
|
190
|
+
return /*#__PURE__*/_react.default.createElement("option", {
|
|
191
|
+
key: `${option.value}-${index}`,
|
|
192
|
+
value: option.value,
|
|
193
|
+
disabled: option.disabled
|
|
194
|
+
}, option.label || option.value);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Support React element options (backward compatibility)
|
|
198
|
+
return option;
|
|
199
|
+
});
|
|
200
|
+
};
|
|
201
|
+
const selectElement = /*#__PURE__*/_react.default.createElement("select", _extends({
|
|
202
|
+
ref: ref,
|
|
203
|
+
id: selectId,
|
|
204
|
+
name: finalName,
|
|
205
|
+
value: value,
|
|
206
|
+
onChange: onChange,
|
|
207
|
+
onFocus: onFocus,
|
|
208
|
+
onBlur: onBlur,
|
|
209
|
+
onKeyDown: handleKeyDown,
|
|
210
|
+
disabled: disabled,
|
|
211
|
+
required: required || ariaRequired,
|
|
212
|
+
multiple: multiple,
|
|
213
|
+
size: size,
|
|
214
|
+
className: `select ${error ? 'select--error' : ''} ${disabled ? 'select--disabled' : ''}`,
|
|
215
|
+
style: style,
|
|
216
|
+
"aria-label": finalHideLabel ? ariaLabel || finalLabel : ariaLabel,
|
|
217
|
+
"aria-describedby": describedBy,
|
|
218
|
+
"aria-invalid": error,
|
|
219
|
+
"aria-required": required || ariaRequired,
|
|
220
|
+
tabIndex: tabIndex,
|
|
221
|
+
"data-testid": dataTestId || `select-${finalName}`,
|
|
222
|
+
"data-cy": dataCy
|
|
223
|
+
}, restProps), !multiple && finalPlaceholder && /*#__PURE__*/_react.default.createElement("option", {
|
|
224
|
+
value: "",
|
|
225
|
+
disabled: true
|
|
226
|
+
}, finalPlaceholder), renderOptions());
|
|
227
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
228
|
+
className: `${componentName.toLowerCase()}-wrapper ${finalHideLabel ? `${componentName.toLowerCase()}--no-label` : `${componentName.toLowerCase()}--with-label`} ${className}`,
|
|
229
|
+
"data-testid": `${componentName ? componentName.toLowerCase() : 'select'}-wrapper`
|
|
230
|
+
}, !finalHideLabel && finalLabel && /*#__PURE__*/_react.default.createElement(_Label.Label, {
|
|
231
|
+
htmlFor: selectId,
|
|
232
|
+
required: required,
|
|
233
|
+
labelText: finalLabel,
|
|
234
|
+
className: "select__label"
|
|
235
|
+
}), helpText && /*#__PURE__*/_react.default.createElement("div", {
|
|
236
|
+
id: helpTextId,
|
|
237
|
+
className: "select__help-text"
|
|
238
|
+
}, helpText), selectElement, error && errorText && /*#__PURE__*/_react.default.createElement(_Error.Error, {
|
|
239
|
+
id: errorId,
|
|
240
|
+
className: "select__error",
|
|
241
|
+
role: "alert",
|
|
242
|
+
"aria-live": "polite"
|
|
243
|
+
}, errorText));
|
|
244
|
+
});
|
|
245
|
+
/**
|
|
246
|
+
* PropTypes for Select component
|
|
247
|
+
* Organized by categories for better maintainability and documentation
|
|
248
|
+
*/
|
|
249
|
+
Select.propTypes = {
|
|
250
|
+
// =====================
|
|
251
|
+
// Core Props (Required)
|
|
252
|
+
// =====================
|
|
253
|
+
/**
|
|
254
|
+
* The name attribute for the select input (required for form submission)
|
|
255
|
+
* Used to identify the field in form data and for accessibility
|
|
256
|
+
*/
|
|
257
|
+
name: string.isRequired,
|
|
258
|
+
/**
|
|
259
|
+
* The label text displayed above the select (required for accessibility)
|
|
260
|
+
* Should clearly describe what the user is selecting
|
|
261
|
+
*/
|
|
262
|
+
label: string.isRequired,
|
|
263
|
+
/**
|
|
264
|
+
* Function called when selection changes (required)
|
|
265
|
+
* Receives the change event as parameter
|
|
266
|
+
* @param {Event} event - The change event from the select
|
|
267
|
+
*/
|
|
268
|
+
onChange: func.isRequired,
|
|
269
|
+
// ==============
|
|
270
|
+
// Content Props
|
|
271
|
+
// ==============
|
|
272
|
+
/**
|
|
273
|
+
* Current selected value(s) - string for single select, array for multiple
|
|
274
|
+
* Controls the select input (controlled component)
|
|
275
|
+
*/
|
|
276
|
+
value: oneOfType([string, number, arrayOf(string)]),
|
|
277
|
+
/**
|
|
278
|
+
* Array of options for the select dropdown
|
|
279
|
+
* Can be strings, objects with {value, label}, or React elements
|
|
280
|
+
* @example
|
|
281
|
+
* // String array
|
|
282
|
+
* ['Option 1', 'Option 2']
|
|
283
|
+
*
|
|
284
|
+
* // Object array (recommended)
|
|
285
|
+
* [
|
|
286
|
+
* { value: 'us', label: 'United States' },
|
|
287
|
+
* { value: 'ca', label: 'Canada', disabled: true }
|
|
288
|
+
* ]
|
|
289
|
+
*/
|
|
290
|
+
options: arrayOf(oneOfType([string, shape({
|
|
291
|
+
value: oneOfType([string, number]).isRequired,
|
|
292
|
+
label: string,
|
|
293
|
+
disabled: bool
|
|
294
|
+
}), element])),
|
|
295
|
+
/**
|
|
296
|
+
* Placeholder text shown when no option is selected
|
|
297
|
+
* Not applicable for multiple selects
|
|
298
|
+
*/
|
|
299
|
+
placeholder: string,
|
|
300
|
+
/**
|
|
301
|
+
* Additional help text displayed below the label
|
|
302
|
+
* Provides context or instructions for the user
|
|
303
|
+
*/
|
|
304
|
+
helpText: string,
|
|
305
|
+
// =============
|
|
306
|
+
// Layout Props
|
|
307
|
+
// =============
|
|
308
|
+
/**
|
|
309
|
+
* Whether to hide the label visually (but keep it for screen readers)
|
|
310
|
+
* Use when layout constraints require hidden labels
|
|
311
|
+
*/
|
|
312
|
+
hideLabel: bool,
|
|
313
|
+
/**
|
|
314
|
+
* Whether multiple options can be selected
|
|
315
|
+
* Changes the select behavior and value type
|
|
316
|
+
*/
|
|
317
|
+
multiple: bool,
|
|
318
|
+
/**
|
|
319
|
+
* Number of visible options (for multiple selects)
|
|
320
|
+
* Controls the height of the select box
|
|
321
|
+
*/
|
|
322
|
+
size: number,
|
|
323
|
+
// ==================
|
|
324
|
+
// Validation Props
|
|
325
|
+
// ==================
|
|
326
|
+
/**
|
|
327
|
+
* Whether selection is required for form validation
|
|
328
|
+
* Adds visual indicator and accessibility attributes
|
|
329
|
+
*/
|
|
330
|
+
required: bool,
|
|
331
|
+
/**
|
|
332
|
+
* Whether the select is in an error state
|
|
333
|
+
* Shows error styling and sets aria-invalid
|
|
334
|
+
*/
|
|
335
|
+
error: bool,
|
|
336
|
+
/**
|
|
337
|
+
* Error message to display when error is true
|
|
338
|
+
* Announced by screen readers for accessibility
|
|
339
|
+
*/
|
|
340
|
+
errorText: string,
|
|
341
|
+
/**
|
|
342
|
+
* Whether the select is disabled
|
|
343
|
+
* Prevents user interaction and excludes from form submission
|
|
344
|
+
*/
|
|
345
|
+
disabled: bool,
|
|
346
|
+
// ====================
|
|
347
|
+
// Accessibility Props
|
|
348
|
+
// ====================
|
|
349
|
+
/**
|
|
350
|
+
* Unique identifier for the select element
|
|
351
|
+
* Generated automatically if not provided
|
|
352
|
+
*/
|
|
353
|
+
id: string,
|
|
354
|
+
/**
|
|
355
|
+
* Accessible label for screen readers when hideLabel is true
|
|
356
|
+
* Should be provided when label is hidden visually
|
|
357
|
+
*/
|
|
358
|
+
ariaLabel: string,
|
|
359
|
+
/**
|
|
360
|
+
* Space-separated IDs of elements that describe this select
|
|
361
|
+
* Used for additional context or instructions
|
|
362
|
+
*/
|
|
363
|
+
ariaDescribedBy: string,
|
|
364
|
+
/**
|
|
365
|
+
* Explicitly set aria-required (usually handled by required prop)
|
|
366
|
+
* Override for custom validation scenarios
|
|
367
|
+
*/
|
|
368
|
+
ariaRequired: bool,
|
|
369
|
+
/**
|
|
370
|
+
* Tab order position for keyboard navigation
|
|
371
|
+
* Usually managed automatically by DOM order
|
|
372
|
+
*/
|
|
373
|
+
tabIndex: number,
|
|
374
|
+
// ================
|
|
375
|
+
// Event Handlers
|
|
376
|
+
// ================
|
|
377
|
+
/**
|
|
378
|
+
* Function called when select receives focus
|
|
379
|
+
* @param {Event} event - The focus event
|
|
380
|
+
*/
|
|
381
|
+
onFocus: func,
|
|
382
|
+
/**
|
|
383
|
+
* Function called when select loses focus
|
|
384
|
+
* @param {Event} event - The blur event
|
|
385
|
+
*/
|
|
386
|
+
onBlur: func,
|
|
387
|
+
/**
|
|
388
|
+
* Function called on keydown events
|
|
389
|
+
* @param {KeyboardEvent} event - The keyboard event
|
|
390
|
+
*/
|
|
391
|
+
onKeyDown: func,
|
|
392
|
+
// ==============
|
|
393
|
+
// Styling Props
|
|
394
|
+
// ==============
|
|
395
|
+
/**
|
|
396
|
+
* Additional CSS classes to apply to the wrapper
|
|
397
|
+
* Merged with default component classes
|
|
398
|
+
*/
|
|
399
|
+
className: string,
|
|
400
|
+
/**
|
|
401
|
+
* Inline styles for the select element
|
|
402
|
+
* Use sparingly - prefer CSS classes
|
|
403
|
+
*/
|
|
404
|
+
style: object,
|
|
405
|
+
// ==============
|
|
406
|
+
// Testing Props
|
|
407
|
+
// ==============
|
|
408
|
+
/**
|
|
409
|
+
* Test ID for automated testing frameworks
|
|
410
|
+
* Applied as data-testid attribute
|
|
411
|
+
*/
|
|
412
|
+
'data-testid': string,
|
|
413
|
+
/**
|
|
414
|
+
* Cypress test selector
|
|
415
|
+
* Applied as data-cy attribute
|
|
416
|
+
*/
|
|
417
|
+
'data-cy': string
|
|
418
|
+
};
|
|
419
|
+
|
|
420
|
+
// Set display name for better debugging and dev tools
|
|
421
|
+
Select.displayName = 'Select';
|
|
422
|
+
var _default = exports.default = Select;
|