@onewelcome/react-lib-components 1.2.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Button/IconButton.d.ts +2 -1
- package/dist/DataGrid/DataGrid.d.ts +1 -0
- package/dist/DataGrid/DataGridActions/DataGridActions.d.ts +2 -1
- package/dist/Form/Form.d.ts +3 -3
- package/dist/Notifications/SlideInModal/SlideInModal.d.ts +1 -1
- package/dist/Tabs/Tab.d.ts +5 -9
- package/dist/Tabs/TabButton.d.ts +3 -6
- package/dist/Tabs/Tabs.d.ts +1 -2
- package/dist/hooks/useDebouncedCallback.d.ts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/react-lib-components.cjs.development.js +472 -395
- package/dist/react-lib-components.cjs.development.js.map +1 -1
- package/dist/react-lib-components.cjs.production.min.js +1 -1
- package/dist/react-lib-components.cjs.production.min.js.map +1 -1
- package/dist/react-lib-components.esm.js +473 -397
- package/dist/react-lib-components.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/Breadcrumbs/Breadcrumbs.tsx +46 -38
- package/src/Button/BaseButton.tsx +23 -20
- package/src/Button/Button.module.scss +9 -0
- package/src/Button/Button.tsx +40 -40
- package/src/Button/IconButton.tsx +28 -28
- package/src/ContextMenu/ContextMenu.tsx +161 -160
- package/src/ContextMenu/ContextMenuItem.tsx +55 -49
- package/src/DataGrid/DataGrid.tsx +1 -0
- package/src/DataGrid/DataGridActions/DataGridActions.module.scss +1 -1
- package/src/DataGrid/DataGridActions/DataGridActions.test.tsx +4 -2
- package/src/DataGrid/DataGridActions/DataGridActions.tsx +95 -87
- package/src/DataGrid/DataGridActions/DataGridColumnsToggle.tsx +64 -64
- package/src/DataGrid/DataGridBody/DataGridCell.tsx +42 -44
- package/src/DataGrid/DataGridBody/DataGridRow.tsx +29 -29
- package/src/DataGrid/DataGridHeader/DataGridHeader.tsx +78 -78
- package/src/DataGrid/DataGridHeader/DataGridHeaderCell.tsx +48 -48
- package/src/Form/Checkbox/Checkbox.tsx +134 -130
- package/src/Form/Fieldset/Fieldset.tsx +81 -78
- package/src/Form/Form.tsx +9 -4
- package/src/Form/FormControl/FormControl.module.scss +1 -20
- package/src/Form/FormControl/FormControl.tsx +36 -35
- package/src/Form/FormGroup/FormGroup.tsx +62 -62
- package/src/Form/FormHelperText/FormHelperText.tsx +19 -18
- package/src/Form/FormSelectorWrapper/FormSelectorWrapper.tsx +58 -53
- package/src/Form/Input/Input.tsx +90 -87
- package/src/Form/Label/Label.tsx +17 -16
- package/src/Form/Radio/Radio.tsx +91 -91
- package/src/Form/Select/Option.tsx +66 -60
- package/src/Form/Select/Select.tsx +207 -209
- package/src/Form/Textarea/Textarea.tsx +51 -53
- package/src/Form/Toggle/Toggle.tsx +26 -23
- package/src/Form/Wrapper/CheckboxWrapper/CheckboxWrapper.tsx +51 -43
- package/src/Form/Wrapper/InputWrapper/InputWrapper.tsx +112 -106
- package/src/Form/Wrapper/RadioWrapper/RadioWrapper.tsx +67 -62
- package/src/Form/Wrapper/SelectWrapper/SelectWrapper.tsx +42 -37
- package/src/Form/Wrapper/TextareaWrapper/TextareaWrapper.tsx +94 -94
- package/src/Form/Wrapper/Wrapper/Wrapper.tsx +73 -73
- package/src/Icon/Icon.module.scss +1 -0
- package/src/Icon/Icon.tsx +19 -16
- package/src/Link/Link.tsx +68 -63
- package/src/Notifications/BaseModal/BaseModal.tsx +68 -68
- package/src/Notifications/BaseModal/BaseModalActions/BaseModalActions.tsx +13 -10
- package/src/Notifications/BaseModal/BaseModalContent/BaseModalContent.tsx +33 -25
- package/src/Notifications/BaseModal/BaseModalHeader/BaseModalHeader.tsx +20 -17
- package/src/Notifications/Dialog/Dialog.tsx +83 -83
- package/src/Notifications/Dialog/DialogActions/DialogActions.tsx +17 -14
- package/src/Notifications/Dialog/DialogTitle/DialogTitle.tsx +15 -12
- package/src/Notifications/DiscardChangesModal/DiscardChangesDialog/DiscardChangesDialog.tsx +40 -40
- package/src/Notifications/SlideInModal/SlideInModal.module.scss +5 -5
- package/src/Notifications/SlideInModal/SlideInModal.test.tsx +7 -2
- package/src/Notifications/SlideInModal/SlideInModal.tsx +47 -27
- package/src/Pagination/Pagination.tsx +169 -169
- package/src/Popover/Popover.module.scss +1 -0
- package/src/Popover/Popover.tsx +43 -33
- package/src/ProgressBar/ProgressBar.tsx +17 -14
- package/src/Skeleton/Skeleton.tsx +23 -20
- package/src/StatusIndicator/StatusIndicator.tsx +18 -15
- package/src/Tabs/{TabPanel.module.scss → Tab.module.scss} +1 -1
- package/src/Tabs/Tab.test.tsx +1 -39
- package/src/Tabs/Tab.tsx +16 -10
- package/src/Tabs/TabButton.module.scss +0 -4
- package/src/Tabs/TabButton.test.tsx +3 -31
- package/src/Tabs/TabButton.tsx +35 -49
- package/src/Tabs/Tabs.test.tsx +40 -33
- package/src/Tabs/Tabs.tsx +107 -101
- package/src/TextEllipsis/TextEllipsis.tsx +50 -41
- package/src/Tiles/Tile.tsx +58 -56
- package/src/Tiles/Tiles.tsx +44 -41
- package/src/Tooltip/Tooltip.tsx +101 -100
- package/src/Typography/Typography.tsx +47 -44
- package/src/Wizard/BaseWizardSteps/BaseWizardSteps.tsx +55 -52
- package/src/Wizard/WizardSteps/WizardSteps.tsx +25 -22
- package/src/hooks/useDebouncedCallback.test.ts +140 -0
- package/src/hooks/useDebouncedCallback.tsx +32 -0
- package/src/index.ts +1 -0
- package/src/mixins.module.scss +2 -2
- package/src/util/helper.test.tsx +0 -28
- package/dist/Tabs/TabPanel.d.ts +0 -8
- package/src/Tabs/TabPanel.test.tsx +0 -92
- package/src/Tabs/TabPanel.tsx +0 -43
|
@@ -19,6 +19,7 @@ import classes from "./Select.module.scss";
|
|
|
19
19
|
import React, {
|
|
20
20
|
ComponentPropsWithRef,
|
|
21
21
|
createRef,
|
|
22
|
+
ForwardRefRenderFunction,
|
|
22
23
|
Fragment,
|
|
23
24
|
ReactElement,
|
|
24
25
|
useEffect,
|
|
@@ -53,238 +54,235 @@ export interface Props extends ComponentPropsWithRef<"select">, FormElement {
|
|
|
53
54
|
/** Amount of items to be rendered before a search input is rendered */
|
|
54
55
|
const renderSearchCondition = 10;
|
|
55
56
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const [childrenCount] = useState(React.Children.count(children));
|
|
57
|
+
const SelectComponent: ForwardRefRenderFunction<HTMLSelectElement, Props> = (
|
|
58
|
+
{
|
|
59
|
+
children,
|
|
60
|
+
name,
|
|
61
|
+
disabled = false,
|
|
62
|
+
labeledBy,
|
|
63
|
+
placeholder,
|
|
64
|
+
describedBy,
|
|
65
|
+
searchPlaceholder = "Search item",
|
|
66
|
+
searchInputProps,
|
|
67
|
+
selectButtonProps,
|
|
68
|
+
className,
|
|
69
|
+
error = false,
|
|
70
|
+
value,
|
|
71
|
+
clearLabel = "Clear selection",
|
|
72
|
+
onChange,
|
|
73
|
+
...rest
|
|
74
|
+
}: Props,
|
|
75
|
+
ref
|
|
76
|
+
) => {
|
|
77
|
+
const [expanded, setExpanded] = useState(false);
|
|
78
|
+
const [filter, setFilter] = useState("");
|
|
79
|
+
const [display, setDisplay] = useState("");
|
|
80
|
+
const containerReference = useRef<HTMLDivElement>(null);
|
|
81
|
+
const optionListReference = useRef<HTMLDivElement>(null);
|
|
82
|
+
const [isSearching, setIsSearching] = useState(false);
|
|
83
|
+
const [focusedSelectItem, setFocusedSelectItem] = useState(-1);
|
|
84
|
+
const [shouldClick, setShouldClick] =
|
|
85
|
+
useState(
|
|
86
|
+
false
|
|
87
|
+
); /** We need this, because whenever we use the arrow keys to select the select item, and we focus the currently selected item it fires the "click" listener in Option component. Instead, we only want this to fire if we press "enter" or "spacebar" so we set this to true whenever that is the case, and back to false when it has been executed. */
|
|
88
|
+
const [childrenCount] = useState(React.Children.count(children));
|
|
89
89
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
90
|
+
const nativeSelect = (ref as React.RefObject<HTMLSelectElement>) || createRef();
|
|
91
|
+
const searchInputRef = useRef<HTMLInputElement>(null);
|
|
92
|
+
const customSelectButtonRef = useRef<HTMLButtonElement>(null);
|
|
93
93
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
const { listPosition, opacity, optionsListMaxHeight, setListPosition, setOpacity } =
|
|
108
|
-
useSelectPositionList({ expanded, optionListReference, containerReference });
|
|
94
|
+
const { onArrowNavigation } = useArrowNavigation({
|
|
95
|
+
expanded,
|
|
96
|
+
setExpanded,
|
|
97
|
+
isSearching,
|
|
98
|
+
setIsSearching,
|
|
99
|
+
setFocusedSelectItem,
|
|
100
|
+
childrenCount,
|
|
101
|
+
customSelectButtonRef,
|
|
102
|
+
setShouldClick,
|
|
103
|
+
searchInputRef,
|
|
104
|
+
renderSearchCondition
|
|
105
|
+
});
|
|
109
106
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
if (child.props.value === val) {
|
|
113
|
-
setDisplay(child.props.children);
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
};
|
|
107
|
+
const { listPosition, opacity, optionsListMaxHeight, setListPosition, setOpacity } =
|
|
108
|
+
useSelectPositionList({ expanded, optionListReference, containerReference });
|
|
117
109
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
110
|
+
const syncDisplayValue = (val: string) => {
|
|
111
|
+
React.Children.forEach(children, child => {
|
|
112
|
+
if (child.props.value === val) {
|
|
113
|
+
setDisplay(child.props.children);
|
|
122
114
|
}
|
|
115
|
+
});
|
|
116
|
+
};
|
|
123
117
|
|
|
124
|
-
|
|
118
|
+
const onOptionChangeHandler = (optionRef: React.RefObject<HTMLLIElement>) => {
|
|
119
|
+
if (nativeSelect.current && optionRef.current) {
|
|
120
|
+
nativeSelect.current.value = optionRef.current.getAttribute("data-value")!;
|
|
121
|
+
nativeSelect.current.dispatchEvent(new Event("change", { bubbles: true }));
|
|
122
|
+
}
|
|
125
123
|
|
|
126
|
-
|
|
127
|
-
};
|
|
124
|
+
setExpanded(false);
|
|
128
125
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
* The `children` prop can be either a single object (1 child) or an array of multiple children.
|
|
132
|
-
*/
|
|
133
|
-
const renderOptions = () => {
|
|
134
|
-
if (isSearching || filter !== "") {
|
|
135
|
-
const filteredChildren = React.Children.toArray(children).filter(
|
|
136
|
-
child =>
|
|
137
|
-
(child as ReactElement).props.children.toLowerCase().match(filter.toLowerCase()) !==
|
|
138
|
-
null
|
|
139
|
-
);
|
|
126
|
+
customSelectButtonRef.current && customSelectButtonRef.current.focus();
|
|
127
|
+
};
|
|
140
128
|
|
|
141
|
-
|
|
142
|
-
|
|
129
|
+
/**
|
|
130
|
+
* @description We have to modify the children (Option component) to have a additional props that allows us to keep track of which one is selected and focused at all times and if a filter is active.
|
|
131
|
+
* The `children` prop can be either a single object (1 child) or an array of multiple children.
|
|
132
|
+
*/
|
|
133
|
+
const renderOptions = () => {
|
|
134
|
+
if (isSearching || filter !== "") {
|
|
135
|
+
const filteredChildren = React.Children.toArray(children).filter(
|
|
136
|
+
child =>
|
|
137
|
+
(child as ReactElement).props.children.toLowerCase().match(filter.toLowerCase()) !== null
|
|
138
|
+
);
|
|
143
139
|
|
|
144
|
-
return _internalRenderChildren(
|
|
140
|
+
return _internalRenderChildren(filteredChildren as ReactElement[]);
|
|
141
|
+
}
|
|
145
142
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
143
|
+
return _internalRenderChildren(children);
|
|
144
|
+
|
|
145
|
+
function _internalRenderChildren(internalChildren: ReactElement[]) {
|
|
146
|
+
return React.Children.map(internalChildren, (child, index) => {
|
|
147
|
+
return React.cloneElement(child, {
|
|
148
|
+
onFocusChange: (childIndex: number) => setFocusedSelectItem(childIndex),
|
|
149
|
+
onOptionSelect: (optionRef: React.RefObject<HTMLLIElement>) => {
|
|
150
|
+
onOptionChangeHandler(optionRef);
|
|
151
|
+
setShouldClick(false);
|
|
152
|
+
},
|
|
153
|
+
isSelected: child.props.value === value,
|
|
154
|
+
isSearching: isSearching,
|
|
155
|
+
selectOpened: expanded,
|
|
156
|
+
childIndex: index,
|
|
157
|
+
hasFocus: focusedSelectItem === index,
|
|
158
|
+
shouldClick: shouldClick
|
|
161
159
|
});
|
|
162
|
-
}
|
|
163
|
-
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
};
|
|
164
163
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
164
|
+
const renderSearch = () => (
|
|
165
|
+
<Input
|
|
166
|
+
{...searchInputProps}
|
|
167
|
+
autoFocus
|
|
168
|
+
ref={searchInputRef}
|
|
169
|
+
onFocus={() => setIsSearching(true)}
|
|
170
|
+
onBlur={() => setIsSearching(false)}
|
|
171
|
+
onChange={filterResults}
|
|
172
|
+
className={classes["select-search"]}
|
|
173
|
+
wrapperProps={{
|
|
174
|
+
className: `${classes["select-search-wrapper"]} ${searchInputProps?.wrapperProps?.className}`
|
|
175
|
+
}}
|
|
176
|
+
type="text"
|
|
177
|
+
name="search-option"
|
|
178
|
+
placeholder={searchPlaceholder}
|
|
179
|
+
/>
|
|
180
|
+
);
|
|
182
181
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
182
|
+
const filterResults = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
183
|
+
setFilter(event.currentTarget.value);
|
|
184
|
+
};
|
|
186
185
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
186
|
+
const statusIcon = () => {
|
|
187
|
+
if (error) {
|
|
188
|
+
return <Icon className={classes["warning"]} icon={Icons.Warning} />;
|
|
189
|
+
}
|
|
191
190
|
|
|
192
|
-
|
|
193
|
-
|
|
191
|
+
return null;
|
|
192
|
+
};
|
|
194
193
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
194
|
+
const nativeOnChangeHandler = (event: React.ChangeEvent<HTMLSelectElement>) => {
|
|
195
|
+
onChange && onChange(event);
|
|
196
|
+
};
|
|
198
197
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
198
|
+
useEffect(() => {
|
|
199
|
+
syncDisplayValue(value);
|
|
200
|
+
}, [value]);
|
|
202
201
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
202
|
+
useBodyClick(
|
|
203
|
+
(event: MouseEvent) => !(event.target as Element).closest(".custom-select") && expanded,
|
|
204
|
+
() => {
|
|
205
|
+
setExpanded(false);
|
|
206
|
+
setListPosition({ top: 0, bottom: "initial" });
|
|
207
|
+
setOpacity(0);
|
|
208
|
+
},
|
|
209
|
+
expanded
|
|
210
|
+
);
|
|
212
211
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
212
|
+
const additionalClasses = [];
|
|
213
|
+
expanded && additionalClasses.push(classes.expanded);
|
|
214
|
+
error && additionalClasses.push(classes.error);
|
|
215
|
+
disabled && additionalClasses.push(classes.disabled);
|
|
216
|
+
className && additionalClasses.push(className);
|
|
218
217
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
218
|
+
/** The native select is purely for external form libraries. We use it to emit an onChange with native select event object so they know exactly what's happening. */
|
|
219
|
+
return (
|
|
220
|
+
<Fragment>
|
|
221
|
+
<select
|
|
222
|
+
{...filterProps(rest, /^data-/, false)}
|
|
223
|
+
tabIndex={-1}
|
|
224
|
+
aria-hidden="true"
|
|
225
|
+
ref={nativeSelect}
|
|
226
|
+
name={name}
|
|
227
|
+
onChange={nativeOnChangeHandler}
|
|
228
|
+
className={readyclasses["sr-only"]}
|
|
229
|
+
>
|
|
230
|
+
<option value=""></option>
|
|
231
|
+
{React.Children.map(children, child => (
|
|
232
|
+
<option value={child.props.value}></option>
|
|
233
|
+
))}
|
|
234
|
+
</select>
|
|
235
|
+
<div
|
|
236
|
+
{...filterProps(rest, /^data-/)}
|
|
237
|
+
ref={containerReference}
|
|
238
|
+
onKeyDown={onArrowNavigation}
|
|
239
|
+
className={`custom-select ${classes.select} ${additionalClasses.join(" ")} ${
|
|
240
|
+
className ?? ""
|
|
241
|
+
}`}
|
|
242
|
+
>
|
|
243
|
+
<button
|
|
244
|
+
{...selectButtonProps}
|
|
245
|
+
onClick={() => {
|
|
246
|
+
setExpanded(!expanded);
|
|
247
|
+
}}
|
|
248
|
+
ref={customSelectButtonRef}
|
|
249
|
+
type="button"
|
|
227
250
|
name={name}
|
|
228
|
-
|
|
229
|
-
|
|
251
|
+
className={`${classes["custom-select"]} ${additionalClasses.join(" ")} `}
|
|
252
|
+
disabled={disabled}
|
|
253
|
+
aria-disabled={disabled}
|
|
254
|
+
aria-invalid={error}
|
|
255
|
+
aria-expanded={expanded}
|
|
256
|
+
aria-haspopup="listbox"
|
|
257
|
+
aria-labelledby={labeledBy}
|
|
258
|
+
aria-describedby={describedBy}
|
|
230
259
|
>
|
|
231
|
-
<
|
|
232
|
-
|
|
233
|
-
<
|
|
234
|
-
|
|
235
|
-
|
|
260
|
+
<div data-display className={classes["selected"]}>
|
|
261
|
+
{!value && placeholder && <span className={classes["placeholder"]}>{placeholder}</span>}
|
|
262
|
+
{value?.length > 0 && <span data-display-inner>{display}</span>}
|
|
263
|
+
</div>
|
|
264
|
+
<div className={classes["status"]}>
|
|
265
|
+
{statusIcon()}
|
|
266
|
+
<Icon className={classes["triangle-down"]} icon={Icons.TriangleDown} />
|
|
267
|
+
</div>
|
|
268
|
+
</button>
|
|
236
269
|
<div
|
|
237
|
-
{
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
270
|
+
ref={optionListReference}
|
|
271
|
+
className={`list-wrapper ${classes["list-wrapper"]}`}
|
|
272
|
+
style={{
|
|
273
|
+
display: expanded ? "block" : "none",
|
|
274
|
+
opacity: opacity,
|
|
275
|
+
maxHeight: optionsListMaxHeight,
|
|
276
|
+
pointerEvents: expanded ? "auto" : "none",
|
|
277
|
+
...listPosition
|
|
278
|
+
}}
|
|
243
279
|
>
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
onClick={() => {
|
|
247
|
-
setExpanded(!expanded);
|
|
248
|
-
}}
|
|
249
|
-
ref={customSelectButtonRef}
|
|
250
|
-
type="button"
|
|
251
|
-
name={name}
|
|
252
|
-
className={`${classes["custom-select"]} ${additionalClasses.join(" ")} `}
|
|
253
|
-
disabled={disabled}
|
|
254
|
-
aria-disabled={disabled}
|
|
255
|
-
aria-invalid={error}
|
|
256
|
-
aria-expanded={expanded}
|
|
257
|
-
aria-haspopup="listbox"
|
|
258
|
-
aria-labelledby={labeledBy}
|
|
259
|
-
aria-describedby={describedBy}
|
|
260
|
-
>
|
|
261
|
-
<div data-display className={classes["selected"]}>
|
|
262
|
-
{!value && placeholder && (
|
|
263
|
-
<span className={classes["placeholder"]}>{placeholder}</span>
|
|
264
|
-
)}
|
|
265
|
-
{value?.length > 0 && <span data-display-inner>{display}</span>}
|
|
266
|
-
</div>
|
|
267
|
-
<div className={classes["status"]}>
|
|
268
|
-
{statusIcon()}
|
|
269
|
-
<Icon className={classes["triangle-down"]} icon={Icons.TriangleDown} />
|
|
270
|
-
</div>
|
|
271
|
-
</button>
|
|
272
|
-
<div
|
|
273
|
-
ref={optionListReference}
|
|
274
|
-
className={`list-wrapper ${classes["list-wrapper"]}`}
|
|
275
|
-
style={{
|
|
276
|
-
display: expanded ? "block" : "none",
|
|
277
|
-
opacity: opacity,
|
|
278
|
-
maxHeight: optionsListMaxHeight,
|
|
279
|
-
pointerEvents: expanded ? "auto" : "none",
|
|
280
|
-
...listPosition
|
|
281
|
-
}}
|
|
282
|
-
>
|
|
283
|
-
{Array.isArray(children) && children.length > renderSearchCondition && renderSearch()}
|
|
284
|
-
<ul role="listbox">{renderOptions()}</ul>
|
|
285
|
-
</div>
|
|
280
|
+
{Array.isArray(children) && children.length > renderSearchCondition && renderSearch()}
|
|
281
|
+
<ul role="listbox">{renderOptions()}</ul>
|
|
286
282
|
</div>
|
|
287
|
-
</
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
283
|
+
</div>
|
|
284
|
+
</Fragment>
|
|
285
|
+
);
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
export const Select = React.forwardRef(SelectComponent);
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import React, { ComponentPropsWithRef, useState } from "react";
|
|
17
|
+
import React, { ForwardRefRenderFunction, ComponentPropsWithRef, useState } from "react";
|
|
18
18
|
import { Icon, Props as IconProps, Icons } from "../../Icon/Icon";
|
|
19
19
|
import classes from "./Textarea.module.scss";
|
|
20
20
|
import { FormElement } from "../form.interfaces";
|
|
@@ -26,59 +26,57 @@ export interface Props extends ComponentPropsWithRef<"textarea">, FormElement {
|
|
|
26
26
|
errorProps?: IconPropsPartial;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const [focus, setFocus] = useState(false);
|
|
29
|
+
const TextareaComponent: ForwardRefRenderFunction<HTMLTextAreaElement, Props> = (
|
|
30
|
+
{
|
|
31
|
+
error = false,
|
|
32
|
+
disabled = false,
|
|
33
|
+
className,
|
|
34
|
+
rows = 4,
|
|
35
|
+
wrapperProps,
|
|
36
|
+
errorProps,
|
|
37
|
+
onFocus,
|
|
38
|
+
onBlur,
|
|
39
|
+
...rest
|
|
40
|
+
}: Props,
|
|
41
|
+
ref
|
|
42
|
+
) => {
|
|
43
|
+
const [focus, setFocus] = useState(false);
|
|
45
44
|
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
const wrapperClasses = [classes["textarea-wrapper"]];
|
|
46
|
+
const outlineClasses = [classes["outline"]];
|
|
48
47
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
error && wrapperClasses.push(classes["error"]) && outlineClasses.push(classes["error"]);
|
|
54
|
-
focus && wrapperClasses.push(classes["focus"]) && outlineClasses.push(classes["focus"]);
|
|
48
|
+
wrapperProps?.className && wrapperClasses.push(wrapperProps.className);
|
|
49
|
+
disabled && wrapperClasses.push(classes["disabled"]) && outlineClasses.push(classes["disabled"]);
|
|
50
|
+
error && wrapperClasses.push(classes["error"]) && outlineClasses.push(classes["error"]);
|
|
51
|
+
focus && wrapperClasses.push(classes["focus"]) && outlineClasses.push(classes["focus"]);
|
|
55
52
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
53
|
+
return (
|
|
54
|
+
<div {...wrapperProps} className={wrapperClasses.join(" ")}>
|
|
55
|
+
<textarea
|
|
56
|
+
{...rest}
|
|
57
|
+
ref={ref}
|
|
58
|
+
rows={rows}
|
|
59
|
+
className={`${error ? classes["error"] : ""} ${classes["textarea"]} ${className ?? ""}`}
|
|
60
|
+
disabled={disabled}
|
|
61
|
+
onFocus={event => {
|
|
62
|
+
setFocus(true);
|
|
63
|
+
onFocus && onFocus(event);
|
|
64
|
+
}}
|
|
65
|
+
onBlur={event => {
|
|
66
|
+
setFocus(false);
|
|
67
|
+
onBlur && onBlur(event);
|
|
68
|
+
}}
|
|
69
|
+
/>
|
|
70
|
+
{error && (
|
|
71
|
+
<Icon
|
|
72
|
+
{...errorProps}
|
|
73
|
+
className={`${classes["warning"]} ${errorProps?.className ?? ""}`}
|
|
74
|
+
icon={Icons.Error}
|
|
72
75
|
/>
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
<span className={outlineClasses.join(" ")}></span>
|
|
81
|
-
</div>
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
);
|
|
76
|
+
)}
|
|
77
|
+
<span className={outlineClasses.join(" ")}></span>
|
|
78
|
+
</div>
|
|
79
|
+
);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export const Textarea = React.forwardRef(TextareaComponent);
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import React, { ComponentPropsWithRef } from "react";
|
|
17
|
+
import React, { ForwardRefRenderFunction, ComponentPropsWithRef } from "react";
|
|
18
18
|
import { Checkbox, Props as CheckboxProps } from "../Checkbox/Checkbox";
|
|
19
19
|
import classes from "./Toggle.module.scss";
|
|
20
20
|
|
|
@@ -24,26 +24,29 @@ export interface Props
|
|
|
24
24
|
children: string;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
27
|
+
const ToggleComponent: ForwardRefRenderFunction<HTMLInputElement, Props> = (
|
|
28
|
+
{ children, checked, disabled, helperProps, ...rest }: Props,
|
|
29
|
+
ref
|
|
30
|
+
) => (
|
|
31
|
+
<div className={classes["toggle-wrapper"]}>
|
|
32
|
+
<Checkbox
|
|
33
|
+
{...rest}
|
|
34
|
+
ref={ref}
|
|
35
|
+
checked={checked}
|
|
36
|
+
className={classes["checkbox"]}
|
|
37
|
+
helperProps={{ className: classes["toggle-helper"], ...helperProps }}
|
|
38
|
+
disabled={disabled}
|
|
39
|
+
label={children}
|
|
40
|
+
>
|
|
41
|
+
<span
|
|
42
|
+
data-toggle
|
|
43
|
+
aria-hidden="true"
|
|
44
|
+
className={`${classes["toggle"]} ${checked ? classes["checked"] : ""} ${
|
|
45
|
+
disabled ? classes["disabled"] : ""
|
|
46
|
+
} `}
|
|
47
|
+
></span>
|
|
48
|
+
</Checkbox>
|
|
49
|
+
</div>
|
|
49
50
|
);
|
|
51
|
+
|
|
52
|
+
export const Toggle = React.forwardRef(ToggleComponent);
|