@onewelcome/react-lib-components 6.0.0 → 6.1.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/cjs/Button/Button.module.cjs.js +1 -1
- package/dist/cjs/Button/IconButton.module.cjs.js +1 -1
- package/dist/cjs/ContextMenu/ContextMenu.cjs.js +1 -1
- package/dist/cjs/ContextMenu/ContextMenu.cjs.js.map +1 -1
- package/dist/cjs/ContextMenu/ContextMenuItem.module.cjs.js +1 -1
- package/dist/cjs/ContextMenu/ContextMenuService.cjs.js +1 -1
- package/dist/cjs/ContextMenu/ContextMenuService.cjs.js.map +1 -1
- package/dist/cjs/DataGrid/DataGridActions/DataGridColumnsToggle.module.cjs.js +1 -1
- package/dist/cjs/Form/Input/Input.module.cjs.js +1 -1
- package/dist/cjs/Form/Select/Option.cjs.js +1 -1
- package/dist/cjs/Form/Select/Option.cjs.js.map +1 -1
- package/dist/cjs/Form/Select/Select.cjs.js +1 -1
- package/dist/cjs/Form/Select/Select.cjs.js.map +1 -1
- package/dist/cjs/Form/Select/Select.module.cjs.js +1 -1
- package/dist/cjs/Form/Select/SelectService.cjs.js +1 -1
- package/dist/cjs/Form/Select/SelectService.cjs.js.map +1 -1
- package/dist/cjs/Form/Textarea/Textarea.module.cjs.js +1 -1
- package/dist/cjs/Link/Link.module.cjs.js +1 -1
- package/dist/cjs/Notifications/BaseModal/BaseModal.module.cjs.js +1 -1
- package/dist/cjs/Notifications/SlideInModal/SlideInModal.module.cjs.js +1 -1
- package/dist/cjs/Notifications/Snackbar/SnackbarItem/SnackbarItem.module.cjs.js +1 -1
- package/dist/cjs/Popover/Popover.cjs.js +1 -1
- package/dist/cjs/Popover/Popover.cjs.js.map +1 -1
- package/dist/cjs/Popover/Popover.module.cjs.js +1 -1
- package/dist/cjs/Stepper/Step.cjs.js +1 -1
- package/dist/cjs/Stepper/Step.cjs.js.map +1 -1
- package/dist/cjs/Stepper/Step.module.cjs.js +1 -1
- package/dist/cjs/Stepper/Stepper.cjs.js +1 -1
- package/dist/cjs/Stepper/Stepper.cjs.js.map +1 -1
- package/dist/cjs/Tabs/TabButton.module.cjs.js +1 -1
- package/dist/cjs/TextEllipsis/TextEllipsis.module.cjs.js +1 -1
- package/dist/cjs/Tiles/Tile.module.cjs.js +1 -1
- package/dist/cjs/Tooltip/Tooltip.module.cjs.js +1 -1
- package/dist/cjs/Wizard/BaseWizardSteps/BaseWizardSteps.module.cjs.js +1 -1
- package/dist/cjs/src/.scope.d.ts +2 -0
- package/dist/cjs/src/components/ContextMenu/ContextMenu.d.ts +1 -1
- package/dist/cjs/src/components/ContextMenu/ContextMenuService.d.ts +4 -1
- package/dist/cjs/src/components/Form/Select/Option.d.ts +1 -0
- package/dist/cjs/src/components/Form/Select/Select.d.ts +20 -0
- package/dist/cjs/src/components/Form/Select/Select.interfaces.d.ts +3 -1
- package/dist/cjs/src/components/Form/Select/Select.test.d.ts +63 -1
- package/dist/cjs/src/components/Form/Select/SelectKeyboardNavigation.test.d.ts +1 -0
- package/dist/cjs/src/components/Form/Select/SelectService.d.ts +3 -2
- package/dist/cjs/src/components/Stepper/Stepper.d.ts +0 -1
- package/dist/cjs/src/hooks/usePosition.cjs.js.map +1 -1
- package/dist/cjs/src/hooks/usePosition.d.ts +1 -1
- package/dist/esm/Button/Button.module.esm.js +1 -1
- package/dist/esm/Button/IconButton.module.esm.js +1 -1
- package/dist/esm/ContextMenu/ContextMenu.esm.js +1 -1
- package/dist/esm/ContextMenu/ContextMenu.esm.js.map +1 -1
- package/dist/esm/ContextMenu/ContextMenuItem.module.esm.js +1 -1
- package/dist/esm/ContextMenu/ContextMenuService.esm.js +1 -1
- package/dist/esm/ContextMenu/ContextMenuService.esm.js.map +1 -1
- package/dist/esm/DataGrid/DataGridActions/DataGridColumnsToggle.module.esm.js +1 -1
- package/dist/esm/Form/Input/Input.module.esm.js +1 -1
- package/dist/esm/Form/Select/Option.esm.js +1 -1
- package/dist/esm/Form/Select/Option.esm.js.map +1 -1
- package/dist/esm/Form/Select/Select.esm.js +1 -1
- package/dist/esm/Form/Select/Select.esm.js.map +1 -1
- package/dist/esm/Form/Select/Select.module.esm.js +1 -1
- package/dist/esm/Form/Select/SelectService.esm.js +1 -1
- package/dist/esm/Form/Select/SelectService.esm.js.map +1 -1
- package/dist/esm/Form/Textarea/Textarea.module.esm.js +1 -1
- package/dist/esm/Link/Link.module.esm.js +1 -1
- package/dist/esm/Notifications/BaseModal/BaseModal.module.esm.js +1 -1
- package/dist/esm/Notifications/SlideInModal/SlideInModal.module.esm.js +1 -1
- package/dist/esm/Notifications/Snackbar/SnackbarItem/SnackbarItem.module.esm.js +1 -1
- package/dist/esm/Popover/Popover.esm.js +1 -1
- package/dist/esm/Popover/Popover.esm.js.map +1 -1
- package/dist/esm/Popover/Popover.module.esm.js +1 -1
- package/dist/esm/Stepper/Step.esm.js +1 -1
- package/dist/esm/Stepper/Step.esm.js.map +1 -1
- package/dist/esm/Stepper/Step.module.esm.js +1 -1
- package/dist/esm/Stepper/Stepper.esm.js +1 -1
- package/dist/esm/Stepper/Stepper.esm.js.map +1 -1
- package/dist/esm/Tabs/TabButton.module.esm.js +1 -1
- package/dist/esm/TextEllipsis/TextEllipsis.module.esm.js +1 -1
- package/dist/esm/Tiles/Tile.module.esm.js +1 -1
- package/dist/esm/Tooltip/Tooltip.module.esm.js +1 -1
- package/dist/esm/Wizard/BaseWizardSteps/BaseWizardSteps.module.esm.js +1 -1
- package/dist/esm/src/.scope.d.ts +2 -0
- package/dist/esm/src/components/ContextMenu/ContextMenu.d.ts +1 -1
- package/dist/esm/src/components/ContextMenu/ContextMenuService.d.ts +4 -1
- package/dist/esm/src/components/Form/Select/Option.d.ts +1 -0
- package/dist/esm/src/components/Form/Select/Select.d.ts +20 -0
- package/dist/esm/src/components/Form/Select/Select.interfaces.d.ts +3 -1
- package/dist/esm/src/components/Form/Select/Select.test.d.ts +63 -1
- package/dist/esm/src/components/Form/Select/SelectKeyboardNavigation.test.d.ts +1 -0
- package/dist/esm/src/components/Form/Select/SelectService.d.ts +3 -2
- package/dist/esm/src/components/Stepper/Stepper.d.ts +0 -1
- package/dist/esm/src/hooks/usePosition.d.ts +1 -1
- package/dist/esm/src/hooks/usePosition.esm.js.map +1 -1
- package/package.json +48 -45
- package/src/{hooks/useWrapper.test.ts → .scope.ts} +1 -12
- package/src/components/ContextMenu/ContextMenu.tsx +13 -23
- package/src/components/ContextMenu/ContextMenuService.ts +47 -1
- package/src/components/Form/Select/Option.tsx +3 -1
- package/src/components/Form/Select/Select.interfaces.ts +3 -1
- package/src/components/Form/Select/Select.module.scss +55 -34
- package/src/components/Form/Select/Select.tsx +74 -23
- package/src/components/Form/Select/SelectService.ts +26 -10
- package/src/components/Link/Link.module.scss +16 -0
- package/src/components/Popover/Popover.tsx +19 -2
- package/src/components/Stepper/Step.tsx +2 -1
- package/src/components/Stepper/Stepper.tsx +0 -2
- package/src/components/Tooltip/Tooltip.module.scss +1 -0
- package/src/hooks/usePosition.ts +1 -1
- package/src/interfaces.ts +2 -2
- package/src/mixins.module.scss +2 -4
- package/src/components/Breadcrumbs/Breadcrumbs.test.tsx +0 -64
- package/src/components/Button/BaseButton.test.tsx +0 -133
- package/src/components/Button/Button.test.tsx +0 -150
- package/src/components/Button/IconButton.test.tsx +0 -106
- package/src/components/ContextMenu/ContextMenu.test.tsx +0 -358
- package/src/components/DataGrid/DataGrid.test.tsx +0 -437
- package/src/components/DataGrid/DataGridActions/DataGridActions.test.tsx +0 -204
- package/src/components/DataGrid/DataGridActions/DataGridColumnsToggle.test.tsx +0 -99
- package/src/components/DataGrid/DataGridBody/DataGridBody.test.tsx +0 -140
- package/src/components/DataGrid/DataGridBody/DataGridCell.test.tsx +0 -90
- package/src/components/DataGrid/DataGridBody/DataGridRow.test.tsx +0 -117
- package/src/components/DataGrid/DataGridHeader/DataGridHeader.test.tsx +0 -276
- package/src/components/DataGrid/DataGridHeader/DataGridHeaderCell.test.tsx +0 -144
- package/src/components/Form/Checkbox/Checkbox.test.tsx +0 -308
- package/src/components/Form/Fieldset/Fieldset.test.tsx +0 -127
- package/src/components/Form/FileUpload/FileItem/FileItem.test.tsx +0 -103
- package/src/components/Form/FileUpload/FileUpload.test.tsx +0 -374
- package/src/components/Form/Form.test.tsx +0 -63
- package/src/components/Form/FormControl/FormControl.test.tsx +0 -98
- package/src/components/Form/FormGroup/FormGroup.test.tsx +0 -127
- package/src/components/Form/FormHelperText/FormHelperText.test.tsx +0 -84
- package/src/components/Form/FormSelectorWrapper/FormSelectorWrapper.test.tsx +0 -94
- package/src/components/Form/Input/Input.test.tsx +0 -267
- package/src/components/Form/Label/Label.test.tsx +0 -68
- package/src/components/Form/Radio/Radio.test.tsx +0 -130
- package/src/components/Form/Select/Option.test.tsx +0 -57
- package/src/components/Form/Select/Select.test.tsx +0 -564
- package/src/components/Form/Textarea/Textarea.test.tsx +0 -124
- package/src/components/Form/Toggle/Toggle.test.tsx +0 -200
- package/src/components/Form/Wrapper/CheckboxWrapper/CheckboxWrapper.test.tsx +0 -141
- package/src/components/Form/Wrapper/InputWrapper/InputWrapper.test.tsx +0 -211
- package/src/components/Form/Wrapper/RadioWrapper/RadioWrapper.test.tsx +0 -117
- package/src/components/Form/Wrapper/SelectWrapper/SelectWrapper.test.tsx +0 -186
- package/src/components/Form/Wrapper/TextareaWrapper/TextareaWrapper.test.tsx +0 -173
- package/src/components/Form/Wrapper/Wrapper/Wrapper.test.tsx +0 -59
- package/src/components/Icon/Icon.test.tsx +0 -83
- package/src/components/Link/Link.test.tsx +0 -203
- package/src/components/Notifications/Banner/Banner.test.tsx +0 -84
- package/src/components/Notifications/BaseModal/BaseModal.test.tsx +0 -194
- package/src/components/Notifications/BaseModal/BaseModalActions/BaseModalActions.test.tsx +0 -74
- package/src/components/Notifications/BaseModal/BaseModalContent/BaseModalContent.test.tsx +0 -71
- package/src/components/Notifications/BaseModal/BaseModalHeader/BaseModalHeader.test.tsx +0 -74
- package/src/components/Notifications/Dialog/Dialog.test.tsx +0 -118
- package/src/components/Notifications/Dialog/DialogActions/DialogActions.test.tsx +0 -61
- package/src/components/Notifications/Dialog/DialogTitle/DialogTitle.test.tsx +0 -87
- package/src/components/Notifications/DiscardChangesModal/DiscardChangesDialog/DiscardChangesDialog.test.tsx +0 -111
- package/src/components/Notifications/DiscardChangesModal/DiscardChangesModal.test.tsx +0 -175
- package/src/components/Notifications/Modal/Modal.test.tsx +0 -18
- package/src/components/Notifications/NotificationProvider/NotificationContext.test.tsx +0 -449
- package/src/components/Notifications/SlideInModal/SlideInModal.test.tsx +0 -90
- package/src/components/Notifications/Snackbar/SnackbarContainer/SnackbarContainer.test.tsx +0 -53
- package/src/components/Notifications/Snackbar/SnackbarItem/SnackbarItem.test.tsx +0 -77
- package/src/components/Notifications/Snackbar/SnackbarProvider/SnackbarProvider.test.tsx +0 -219
- package/src/components/Notifications/Snackbar/useSnackbar.test.tsx +0 -136
- package/src/components/Pagination/Pagination.test.tsx +0 -183
- package/src/components/Popover/Popover.test.tsx +0 -103
- package/src/components/ProgressBar/ProgressBar.test.tsx +0 -91
- package/src/components/Skeleton/Skeleton.test.tsx +0 -112
- package/src/components/StatusIndicator/StatusIndicator.test.tsx +0 -143
- package/src/components/Stepper/Stepper.test.tsx +0 -83
- package/src/components/Tabs/Tab.test.tsx +0 -49
- package/src/components/Tabs/TabButton.test.tsx +0 -65
- package/src/components/Tabs/Tabs.test.tsx +0 -291
- package/src/components/Tag/Tag.test.tsx +0 -89
- package/src/components/TextEllipsis/TextEllipsis.test.tsx +0 -96
- package/src/components/Tiles/Tile.test.tsx +0 -183
- package/src/components/Tiles/Tiles.test.tsx +0 -162
- package/src/components/Tooltip/Tooltip.test.tsx +0 -390
- package/src/components/Typography/Typography.test.tsx +0 -177
- package/src/components/Wizard/BaseWizardSteps/BaseWizardSteps.test.tsx +0 -90
- package/src/components/Wizard/Wizard.test.tsx +0 -218
- package/src/components/Wizard/WizardActions/WizardActions.test.tsx +0 -187
- package/src/components/Wizard/WizardSteps/WizardSteps.test.tsx +0 -125
- package/src/components/_BaseStyling_/BaseStyling.test.tsx +0 -55
- package/src/hooks/useAnimation.test.tsx +0 -65
- package/src/hooks/useBodyClick.test.tsx +0 -55
- package/src/hooks/useDebouncedCallback.test.ts +0 -150
- package/src/hooks/useDetermineStatusIcon.test.ts +0 -28
- package/src/hooks/useFormSelector.test.ts +0 -56
- package/src/hooks/usePosition.test.tsx +0 -510
- package/src/hooks/useRepeater.test.tsx +0 -156
- package/src/hooks/useScroll.test.tsx +0 -36
- package/src/hooks/useSpacing.test.ts +0 -86
- package/src/hooks/useUploadFile.test.ts +0 -211
- package/src/util/helper.test.tsx +0 -403
|
@@ -37,25 +37,41 @@ import { useDetermineStatusIcon } from "../../../hooks/useDetermineStatusIcon";
|
|
|
37
37
|
|
|
38
38
|
type PartialInputProps = Partial<InputProps>;
|
|
39
39
|
|
|
40
|
+
interface SearchProps {
|
|
41
|
+
enabled?: boolean;
|
|
42
|
+
renderThreshold?: number;
|
|
43
|
+
searchPlaceholder?: string;
|
|
44
|
+
searchInputProps?: PartialInputProps & { reset?: boolean };
|
|
45
|
+
}
|
|
46
|
+
|
|
40
47
|
export interface Props extends ComponentPropsWithRef<"select">, FormElement {
|
|
41
48
|
children: ReactElement[];
|
|
42
49
|
name?: string;
|
|
43
50
|
labeledBy?: string;
|
|
44
51
|
describedBy?: string;
|
|
45
52
|
placeholder?: string;
|
|
53
|
+
/**
|
|
54
|
+
* @deprecated
|
|
55
|
+
*/
|
|
46
56
|
searchPlaceholder?: string;
|
|
57
|
+
/**
|
|
58
|
+
* @deprecated
|
|
59
|
+
*/
|
|
47
60
|
searchInputProps?: PartialInputProps & { reset?: boolean };
|
|
48
61
|
selectButtonProps?: ComponentPropsWithRef<"button">;
|
|
62
|
+
search?: SearchProps;
|
|
49
63
|
className?: string;
|
|
50
64
|
value: string;
|
|
51
65
|
clearLabel?: string;
|
|
52
66
|
noResultsLabel?: string;
|
|
53
67
|
onChange?: (event: React.ChangeEvent<HTMLSelectElement>, child?: ReactElement) => void;
|
|
68
|
+
addNew?: {
|
|
69
|
+
label: string;
|
|
70
|
+
onAddNew: (value: string) => void;
|
|
71
|
+
btnProps?: React.ButtonHTMLAttributes<HTMLButtonElement>;
|
|
72
|
+
};
|
|
54
73
|
}
|
|
55
74
|
|
|
56
|
-
/** Amount of items to be rendered before a search input is rendered */
|
|
57
|
-
const renderSearchCondition = 10;
|
|
58
|
-
|
|
59
75
|
const SelectComponent: ForwardRefRenderFunction<HTMLSelectElement, Props> = (
|
|
60
76
|
{
|
|
61
77
|
children,
|
|
@@ -74,6 +90,8 @@ const SelectComponent: ForwardRefRenderFunction<HTMLSelectElement, Props> = (
|
|
|
74
90
|
clearLabel = "Clear selection",
|
|
75
91
|
noResultsLabel = "No results found",
|
|
76
92
|
onChange,
|
|
93
|
+
addNew,
|
|
94
|
+
search,
|
|
77
95
|
...rest
|
|
78
96
|
}: Props,
|
|
79
97
|
ref
|
|
@@ -85,14 +103,32 @@ const SelectComponent: ForwardRefRenderFunction<HTMLSelectElement, Props> = (
|
|
|
85
103
|
const optionListReference = useRef<HTMLDivElement>(null);
|
|
86
104
|
const [isSearching, setIsSearching] = useState(false);
|
|
87
105
|
const [focusedSelectItem, setFocusedSelectItem] = useState(-1);
|
|
88
|
-
const [shouldClick, setShouldClick] =
|
|
89
|
-
|
|
90
|
-
false
|
|
91
|
-
); /** 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. */
|
|
106
|
+
const [shouldClick, setShouldClick] = useState(false);
|
|
107
|
+
/** 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. */
|
|
92
108
|
const [shouldFocusButtonAfterClose, setShouldFocusButtonAfterClose] = useState(false);
|
|
93
109
|
|
|
110
|
+
const DEFAULT_RENDER_THRESHOLD = 10;
|
|
111
|
+
|
|
94
112
|
const nativeSelect = (ref as React.RefObject<HTMLSelectElement>) || createRef();
|
|
95
113
|
const searchInputRef = useRef<HTMLInputElement>(null);
|
|
114
|
+
const addBtnRef = useRef<HTMLButtonElement>(null);
|
|
115
|
+
|
|
116
|
+
const addNewLabel = addNew?.label ?? "Create new";
|
|
117
|
+
|
|
118
|
+
const getRenderThreshold = search?.renderThreshold ?? DEFAULT_RENDER_THRESHOLD;
|
|
119
|
+
const hasEnoughChildren = Array.isArray(children) && children.length > getRenderThreshold;
|
|
120
|
+
|
|
121
|
+
const shouldRenderSearch = () => {
|
|
122
|
+
if (search?.enabled) {
|
|
123
|
+
return hasEnoughChildren;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (search) {
|
|
127
|
+
return search.enabled as boolean;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return children.length > DEFAULT_RENDER_THRESHOLD;
|
|
131
|
+
};
|
|
96
132
|
|
|
97
133
|
const onOptionChangeHandler = (optionElement: HTMLElement | null) => {
|
|
98
134
|
if (nativeSelect.current && optionElement) {
|
|
@@ -114,11 +150,12 @@ const SelectComponent: ForwardRefRenderFunction<HTMLSelectElement, Props> = (
|
|
|
114
150
|
childrenCount: React.Children.count(children),
|
|
115
151
|
setShouldClick,
|
|
116
152
|
searchInputRef,
|
|
117
|
-
|
|
153
|
+
addBtnRef,
|
|
154
|
+
renderThreshold: getRenderThreshold
|
|
118
155
|
});
|
|
119
156
|
|
|
120
157
|
const { listPosition, opacity, optionsListMaxHeight, setListPosition, setOpacity } =
|
|
121
|
-
useSelectPositionList({ expanded, optionListReference, containerReference });
|
|
158
|
+
useSelectPositionList({ expanded, optionListReference, containerReference, addBtnRef });
|
|
122
159
|
|
|
123
160
|
const syncDisplayValue = (val: string) => {
|
|
124
161
|
React.Children.forEach(children, child => {
|
|
@@ -129,7 +166,7 @@ const SelectComponent: ForwardRefRenderFunction<HTMLSelectElement, Props> = (
|
|
|
129
166
|
};
|
|
130
167
|
|
|
131
168
|
/**
|
|
132
|
-
* @description We have to modify the children (Option component) to have
|
|
169
|
+
* @description We have to modify the children (Option component) to have an additional props that allows us to keep track of which one is selected and focused at all times and if a filter is active.
|
|
133
170
|
* The `children` prop can be either a single object (1 child) or an array of multiple children.
|
|
134
171
|
*/
|
|
135
172
|
const renderOptions = () => {
|
|
@@ -165,32 +202,32 @@ const SelectComponent: ForwardRefRenderFunction<HTMLSelectElement, Props> = (
|
|
|
165
202
|
selectOpened: expanded,
|
|
166
203
|
childIndex: index,
|
|
167
204
|
hasFocus: focusedSelectItem === index,
|
|
168
|
-
shouldClick: shouldClick
|
|
205
|
+
shouldClick: shouldClick,
|
|
206
|
+
isAddBtnFocused: addBtnRef.current === document.activeElement
|
|
169
207
|
});
|
|
170
208
|
});
|
|
171
209
|
}
|
|
172
210
|
};
|
|
173
211
|
|
|
174
|
-
const shouldRenderSearch =
|
|
175
|
-
expanded && Array.isArray(children) && children.length > renderSearchCondition;
|
|
176
|
-
|
|
177
212
|
const renderSearch = () => (
|
|
178
213
|
<Input
|
|
179
|
-
{...searchInputProps}
|
|
214
|
+
{...(search?.searchInputProps ?? searchInputProps)}
|
|
180
215
|
ref={searchInputRef}
|
|
181
216
|
onFocus={() => setIsSearching(true)}
|
|
182
217
|
onBlur={() => setIsSearching(false)}
|
|
183
218
|
onChange={filterResults}
|
|
184
219
|
className={classes["select-search"]}
|
|
185
220
|
wrapperProps={{
|
|
186
|
-
className:
|
|
221
|
+
className:
|
|
222
|
+
search?.searchInputProps?.wrapperProps?.className ??
|
|
223
|
+
searchInputProps?.wrapperProps?.className
|
|
187
224
|
}}
|
|
188
225
|
style={{
|
|
189
226
|
display: expanded ? "block" : "none"
|
|
190
227
|
}}
|
|
191
228
|
type="text"
|
|
192
229
|
name="search-option"
|
|
193
|
-
placeholder={searchPlaceholder}
|
|
230
|
+
placeholder={search?.searchPlaceholder ?? searchPlaceholder}
|
|
194
231
|
/>
|
|
195
232
|
);
|
|
196
233
|
|
|
@@ -245,8 +282,8 @@ const SelectComponent: ForwardRefRenderFunction<HTMLSelectElement, Props> = (
|
|
|
245
282
|
};
|
|
246
283
|
|
|
247
284
|
useEffect(() => {
|
|
248
|
-
searchInputProps?.reset && resetSearchState();
|
|
249
|
-
}, [searchInputProps?.reset]);
|
|
285
|
+
(search?.searchInputProps?.reset || searchInputProps?.reset) && resetSearchState();
|
|
286
|
+
}, [searchInputProps?.reset, search?.searchInputProps?.reset]);
|
|
250
287
|
|
|
251
288
|
const additionalClasses = [];
|
|
252
289
|
expanded && additionalClasses.push(classes.expanded);
|
|
@@ -280,7 +317,7 @@ const SelectComponent: ForwardRefRenderFunction<HTMLSelectElement, Props> = (
|
|
|
280
317
|
className ?? ""
|
|
281
318
|
}`}
|
|
282
319
|
>
|
|
283
|
-
{
|
|
320
|
+
{shouldRenderSearch() && renderSearch()}
|
|
284
321
|
<button
|
|
285
322
|
{...selectButtonProps}
|
|
286
323
|
onClick={() => {
|
|
@@ -290,7 +327,7 @@ const SelectComponent: ForwardRefRenderFunction<HTMLSelectElement, Props> = (
|
|
|
290
327
|
type="button"
|
|
291
328
|
name={name}
|
|
292
329
|
className={`${classes["custom-select"]} ${additionalClasses.join(" ")} `}
|
|
293
|
-
style={{ display: shouldRenderSearch ? "none" : "initial" }}
|
|
330
|
+
style={{ display: expanded && shouldRenderSearch() ? "none" : "initial" }}
|
|
294
331
|
disabled={disabled}
|
|
295
332
|
aria-disabled={disabled}
|
|
296
333
|
aria-invalid={error}
|
|
@@ -317,11 +354,25 @@ const SelectComponent: ForwardRefRenderFunction<HTMLSelectElement, Props> = (
|
|
|
317
354
|
...listPosition
|
|
318
355
|
}}
|
|
319
356
|
>
|
|
320
|
-
<ul role="listbox">
|
|
357
|
+
<ul className={addNew && classes["has-sibling"]} role="listbox">
|
|
358
|
+
{renderOptions()}
|
|
359
|
+
</ul>
|
|
360
|
+
{addNew && (
|
|
361
|
+
<button
|
|
362
|
+
data-testid={"select-action-button"}
|
|
363
|
+
className={classes["action-button"]}
|
|
364
|
+
onClick={() => addNew.onAddNew(filter)}
|
|
365
|
+
ref={addBtnRef}
|
|
366
|
+
{...addNew.btnProps}
|
|
367
|
+
>
|
|
368
|
+
{!filter && addNewLabel}
|
|
369
|
+
{filter && <span style={{ fontWeight: "700" }}>{`"${filter}"`}</span>}
|
|
370
|
+
{filter && ` (${addNewLabel.toLowerCase()})`}
|
|
371
|
+
</button>
|
|
372
|
+
)}
|
|
321
373
|
</div>
|
|
322
374
|
</div>
|
|
323
375
|
</Fragment>
|
|
324
376
|
);
|
|
325
377
|
};
|
|
326
|
-
|
|
327
378
|
export const Select = React.forwardRef(SelectComponent);
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
UseSelectPositionListParams
|
|
22
22
|
} from "./Select.interfaces";
|
|
23
23
|
|
|
24
|
+
/** @scope . */
|
|
24
25
|
export const useArrowNavigation = ({
|
|
25
26
|
expanded,
|
|
26
27
|
setExpanded,
|
|
@@ -31,7 +32,8 @@ export const useArrowNavigation = ({
|
|
|
31
32
|
childrenCount,
|
|
32
33
|
setShouldClick,
|
|
33
34
|
searchInputRef,
|
|
34
|
-
|
|
35
|
+
addBtnRef,
|
|
36
|
+
renderThreshold
|
|
35
37
|
}: UseArrowNavigationParams) => {
|
|
36
38
|
const onArrowNavigation = (event: React.KeyboardEvent) => {
|
|
37
39
|
const codesToPreventDefault = [
|
|
@@ -54,12 +56,16 @@ export const useArrowNavigation = ({
|
|
|
54
56
|
"MetaRight"
|
|
55
57
|
];
|
|
56
58
|
|
|
57
|
-
|
|
59
|
+
const isAddBtnFocused = addBtnRef?.current === document.activeElement;
|
|
60
|
+
|
|
58
61
|
if (expanded) {
|
|
59
62
|
codesToPreventDefault.push("Tab");
|
|
60
63
|
}
|
|
61
64
|
|
|
62
|
-
|
|
65
|
+
if (addBtnRef) {
|
|
66
|
+
codesToPreventDefaultWhenSearching.push("Tab");
|
|
67
|
+
}
|
|
68
|
+
|
|
63
69
|
if (codesToPreventDefault.includes(event.code) && !event.metaKey && !isSearching) {
|
|
64
70
|
event.preventDefault();
|
|
65
71
|
}
|
|
@@ -80,7 +86,14 @@ export const useArrowNavigation = ({
|
|
|
80
86
|
setFocusedSelectItem(childrenCount - 1);
|
|
81
87
|
return;
|
|
82
88
|
case "Escape":
|
|
89
|
+
setIsSearching(false);
|
|
90
|
+
setExpanded(false);
|
|
91
|
+
return;
|
|
83
92
|
case "Tab":
|
|
93
|
+
if (addBtnRef?.current) {
|
|
94
|
+
addBtnRef.current.focus();
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
84
97
|
setIsSearching(false);
|
|
85
98
|
setExpanded(false);
|
|
86
99
|
}
|
|
@@ -125,10 +138,13 @@ export const useArrowNavigation = ({
|
|
|
125
138
|
|
|
126
139
|
return;
|
|
127
140
|
case "Tab":
|
|
128
|
-
if (childrenCount >=
|
|
141
|
+
if (childrenCount >= renderThreshold && expanded && !isAddBtnFocused) {
|
|
129
142
|
setIsSearching(true);
|
|
130
143
|
searchInputRef.current?.focus();
|
|
131
144
|
return;
|
|
145
|
+
} else if (addBtnRef?.current && expanded && !isAddBtnFocused) {
|
|
146
|
+
addBtnRef.current.focus();
|
|
147
|
+
return;
|
|
132
148
|
}
|
|
133
149
|
setExpanded(false);
|
|
134
150
|
|
|
@@ -163,10 +179,11 @@ export const useArrowNavigation = ({
|
|
|
163
179
|
export const useSelectPositionList = ({
|
|
164
180
|
expanded,
|
|
165
181
|
optionListReference,
|
|
182
|
+
addBtnRef,
|
|
166
183
|
containerReference
|
|
167
184
|
}: UseSelectPositionListParams) => {
|
|
168
185
|
const [optionsListMaxHeight, setOptionsListMaxHeight] = useState("none");
|
|
169
|
-
const [opacity, setOpacity] = useState(0); // We set opacity because
|
|
186
|
+
const [opacity, setOpacity] = useState(0); // We set opacity because otherwise if we calculate the max height you see the list full height for a split second and then it shortens.
|
|
170
187
|
const [listPosition, setListPosition] = useState<Partial<Position>>({});
|
|
171
188
|
|
|
172
189
|
useEffect(() => {
|
|
@@ -203,6 +220,7 @@ export const useSelectPositionList = ({
|
|
|
203
220
|
const calculateOptionListMaxHeight = (position: Position) => {
|
|
204
221
|
// Calculate max height if there's more space below the select
|
|
205
222
|
const listHeight = optionListReference.current?.getBoundingClientRect().height;
|
|
223
|
+
const addNewButtonHeight = addBtnRef.current?.getBoundingClientRect().height ?? 0;
|
|
206
224
|
const transformOrigin = position.top !== "initial" ? "top" : "bottom";
|
|
207
225
|
|
|
208
226
|
if (!containerReference.current) {
|
|
@@ -214,12 +232,10 @@ export const useSelectPositionList = ({
|
|
|
214
232
|
|
|
215
233
|
const availableSpace =
|
|
216
234
|
transformOrigin === "top"
|
|
217
|
-
? window.innerHeight -
|
|
218
|
-
|
|
219
|
-
16
|
|
220
|
-
: containerReference.current.getBoundingClientRect()[transformOrigin] - 16;
|
|
235
|
+
? window.innerHeight - containerReference.current.getBoundingClientRect().bottom - 16
|
|
236
|
+
: containerReference.current.getBoundingClientRect().top - 16;
|
|
221
237
|
|
|
222
|
-
if (listHeight && availableSpace < listHeight) {
|
|
238
|
+
if (listHeight && availableSpace < listHeight + addNewButtonHeight) {
|
|
223
239
|
setOptionsListMaxHeight(`${availableSpace}px`);
|
|
224
240
|
setOpacity(100);
|
|
225
241
|
return;
|
|
@@ -39,6 +39,10 @@
|
|
|
39
39
|
&:focus-visible {
|
|
40
40
|
outline: 0.5px dashed var(--color-primary);
|
|
41
41
|
}
|
|
42
|
+
|
|
43
|
+
&:visited {
|
|
44
|
+
color: var(--button-primary-pressed-color);
|
|
45
|
+
}
|
|
42
46
|
}
|
|
43
47
|
|
|
44
48
|
&.success {
|
|
@@ -47,6 +51,10 @@
|
|
|
47
51
|
&:focus-visible {
|
|
48
52
|
outline: 0.5px dashed var(--color-primary);
|
|
49
53
|
}
|
|
54
|
+
|
|
55
|
+
&:visited {
|
|
56
|
+
color: var(--button-success-pressed-color);
|
|
57
|
+
}
|
|
50
58
|
}
|
|
51
59
|
|
|
52
60
|
&.danger {
|
|
@@ -55,6 +63,10 @@
|
|
|
55
63
|
&:focus-visible {
|
|
56
64
|
outline: 0.5px dashed var(--color-primary);
|
|
57
65
|
}
|
|
66
|
+
|
|
67
|
+
&:visited {
|
|
68
|
+
color: var(--button-danger-pressed-color);
|
|
69
|
+
}
|
|
58
70
|
}
|
|
59
71
|
|
|
60
72
|
&.warning {
|
|
@@ -63,6 +75,10 @@
|
|
|
63
75
|
&:focus-visible {
|
|
64
76
|
outline: 0.5px dashed var(--color-primary);
|
|
65
77
|
}
|
|
78
|
+
|
|
79
|
+
&:visited {
|
|
80
|
+
color: var(--button-warning-pressed-color);
|
|
81
|
+
}
|
|
66
82
|
}
|
|
67
83
|
|
|
68
84
|
&.disabled {
|
|
@@ -23,7 +23,7 @@ import React, {
|
|
|
23
23
|
useRef,
|
|
24
24
|
useState
|
|
25
25
|
} from "react";
|
|
26
|
-
import { Offset, Placement, usePosition } from "../../hooks/usePosition";
|
|
26
|
+
import { Offset, Placement, PositionType, usePosition } from "../../hooks/usePosition";
|
|
27
27
|
import classes from "./Popover.module.scss";
|
|
28
28
|
|
|
29
29
|
export interface Props extends ComponentPropsWithRef<"div"> {
|
|
@@ -63,6 +63,18 @@ const PopoverComponent: ForwardRefRenderFunction<HTMLDivElement, Props> = (
|
|
|
63
63
|
debounceAmount: debounceAmount ?? undefined
|
|
64
64
|
});
|
|
65
65
|
|
|
66
|
+
const normalizePosition = (value: PositionType) => {
|
|
67
|
+
if (value === "initial") {
|
|
68
|
+
return "initial";
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (isNaN(value)) {
|
|
72
|
+
return 0;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return Number(value);
|
|
76
|
+
};
|
|
77
|
+
|
|
66
78
|
useEffect(() => {
|
|
67
79
|
if (initialCalculationDone) {
|
|
68
80
|
setShowPopover(!!show);
|
|
@@ -114,7 +126,12 @@ const PopoverComponent: ForwardRefRenderFunction<HTMLDivElement, Props> = (
|
|
|
114
126
|
<div
|
|
115
127
|
ref={elToBePositioned}
|
|
116
128
|
className={`${classes.popover} ${className ?? ""} ${showPopover ? classes.show : ""}`}
|
|
117
|
-
style={{
|
|
129
|
+
style={{
|
|
130
|
+
top: normalizePosition(top),
|
|
131
|
+
left: normalizePosition(left),
|
|
132
|
+
right: normalizePosition(right),
|
|
133
|
+
bottom: normalizePosition(bottom)
|
|
134
|
+
}}
|
|
118
135
|
>
|
|
119
136
|
{children}
|
|
120
137
|
</div>
|
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
import React, { CSSProperties, ComponentPropsWithRef, ForwardRefRenderFunction } from "react";
|
|
18
18
|
import { Icon, Icons } from "../Icon/Icon";
|
|
19
19
|
import classes from "./Step.module.scss";
|
|
20
|
-
import { gapBetweenStepsInRem } from "./Stepper";
|
|
21
20
|
|
|
22
21
|
export type StepStatus = "waiting" | "current" | "done" | "error";
|
|
23
22
|
|
|
@@ -33,6 +32,8 @@ export interface Props extends Omit<ComponentPropsWithRef<"div">, "onClick"> {
|
|
|
33
32
|
onClick?: (event: React.MouseEvent<HTMLButtonElement | HTMLDivElement>) => void;
|
|
34
33
|
}
|
|
35
34
|
|
|
35
|
+
const gapBetweenStepsInRem = 0.5;
|
|
36
|
+
|
|
36
37
|
const getStepContent = (index: number, status: StepStatus) => {
|
|
37
38
|
switch (status) {
|
|
38
39
|
case "waiting":
|
package/src/hooks/usePosition.ts
CHANGED
package/src/interfaces.ts
CHANGED
|
@@ -32,6 +32,6 @@ export type DeepPartial<T> = {
|
|
|
32
32
|
[P in keyof T]?: T[P] extends (infer U)[]
|
|
33
33
|
? DeepPartial<U>[]
|
|
34
34
|
: T[P] extends ReadonlyArray<infer U>
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
? ReadonlyArray<DeepPartial<U>>
|
|
36
|
+
: DeepPartial<T[P]>;
|
|
37
37
|
};
|
package/src/mixins.module.scss
CHANGED
|
@@ -18,12 +18,12 @@
|
|
|
18
18
|
|
|
19
19
|
@mixin button($variant: "text", $type: "default") {
|
|
20
20
|
$disabledSelector: if($type == "link", ".disabled", ":disabled");
|
|
21
|
+
font-weight: 500;
|
|
21
22
|
|
|
22
23
|
@if $variant == "text" {
|
|
23
24
|
border-color: transparent;
|
|
24
25
|
background-color: transparent;
|
|
25
26
|
} @else if $variant == "fill" {
|
|
26
|
-
font-weight: 500;
|
|
27
27
|
&:not(#{$disabledSelector}) {
|
|
28
28
|
color: var(--button-fill-text-color);
|
|
29
29
|
@include buttonStyles(
|
|
@@ -37,7 +37,6 @@
|
|
|
37
37
|
}
|
|
38
38
|
} @else if $variant == "outline" {
|
|
39
39
|
background-color: var(--white);
|
|
40
|
-
font-weight: 500;
|
|
41
40
|
}
|
|
42
41
|
|
|
43
42
|
&.primary:not(#{$disabledSelector}) {
|
|
@@ -145,8 +144,7 @@
|
|
|
145
144
|
z-index: 2;
|
|
146
145
|
}
|
|
147
146
|
|
|
148
|
-
&:active:not(.disabled)
|
|
149
|
-
&:visited:not(.disabled) {
|
|
147
|
+
&:active:not(.disabled) {
|
|
150
148
|
@if $variant == "fill" {
|
|
151
149
|
background-color: $pressedColor;
|
|
152
150
|
border-color: $pressedColor;
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright 2022 OneWelcome B.V.
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
import React from "react";
|
|
18
|
-
import { Breadcrumbs, Props } from "./Breadcrumbs";
|
|
19
|
-
import { render } from "@testing-library/react";
|
|
20
|
-
import { Link } from "../Link/Link";
|
|
21
|
-
|
|
22
|
-
const defaultParams: Props = {
|
|
23
|
-
ariaLabel: "Breadcrumbs",
|
|
24
|
-
children: [
|
|
25
|
-
<Link key="0" to="#1" data-testid="link">
|
|
26
|
-
Test1
|
|
27
|
-
</Link>,
|
|
28
|
-
<Link key="1" to="#2" data-testid="link">
|
|
29
|
-
Test2
|
|
30
|
-
</Link>
|
|
31
|
-
]
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
const createBreadcrumbs = (params?: (defaultParams: Props) => Props) => {
|
|
35
|
-
let parameters: Props = defaultParams;
|
|
36
|
-
if (params) {
|
|
37
|
-
parameters = params(defaultParams);
|
|
38
|
-
}
|
|
39
|
-
const queries = render(<Breadcrumbs {...parameters} data-testid="breadcrumbs"></Breadcrumbs>);
|
|
40
|
-
const breadcrumbs = queries.getByTestId("breadcrumbs");
|
|
41
|
-
|
|
42
|
-
return {
|
|
43
|
-
...queries,
|
|
44
|
-
breadcrumbs
|
|
45
|
-
};
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
describe("Breadcrumbs should render", () => {
|
|
49
|
-
it("renders without crashing", () => {
|
|
50
|
-
const { breadcrumbs } = createBreadcrumbs();
|
|
51
|
-
|
|
52
|
-
expect(breadcrumbs).toBeDefined();
|
|
53
|
-
expect(breadcrumbs.firstChild).not.toHaveAttribute("aria-current");
|
|
54
|
-
if (breadcrumbs.firstChild) {
|
|
55
|
-
const homeIcon = (breadcrumbs.firstChild as HTMLElement).querySelector(
|
|
56
|
-
"[class*='icon-home-filled']"
|
|
57
|
-
);
|
|
58
|
-
expect(homeIcon).toBeInTheDocument();
|
|
59
|
-
}
|
|
60
|
-
expect((breadcrumbs.firstChild as HTMLElement).tagName).toEqual("A");
|
|
61
|
-
expect(breadcrumbs.lastChild).toHaveAttribute("aria-current", "page");
|
|
62
|
-
expect((breadcrumbs.lastChild as HTMLElement).tagName).toEqual("SPAN");
|
|
63
|
-
});
|
|
64
|
-
});
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright 2022 OneWelcome B.V.
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
import React, { useEffect, useRef } from "react";
|
|
18
|
-
import { BaseButton, Props } from "./BaseButton";
|
|
19
|
-
import { render } from "@testing-library/react";
|
|
20
|
-
import userEvent from "@testing-library/user-event";
|
|
21
|
-
|
|
22
|
-
const defaultParams: Props = {};
|
|
23
|
-
|
|
24
|
-
const createBaseButton = (params?: (defaultParams: Props) => Props) => {
|
|
25
|
-
let parameters: Props = defaultParams;
|
|
26
|
-
if (params) {
|
|
27
|
-
parameters = params(defaultParams);
|
|
28
|
-
}
|
|
29
|
-
const queries = render(
|
|
30
|
-
<BaseButton {...parameters} data-testid="baseButton">
|
|
31
|
-
baseButton content
|
|
32
|
-
</BaseButton>
|
|
33
|
-
);
|
|
34
|
-
const baseButton = queries.getByTestId("baseButton");
|
|
35
|
-
|
|
36
|
-
return {
|
|
37
|
-
...queries,
|
|
38
|
-
baseButton
|
|
39
|
-
};
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
describe("BaseButton should render", () => {
|
|
43
|
-
it("renders without crashing", () => {
|
|
44
|
-
const { baseButton } = createBaseButton();
|
|
45
|
-
|
|
46
|
-
expect(baseButton).toBeDefined();
|
|
47
|
-
expect(baseButton).toHaveTextContent("baseButton content");
|
|
48
|
-
});
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
describe("On click handler", () => {
|
|
52
|
-
it("executes the onclick handler", async () => {
|
|
53
|
-
const onClickHandler = jest.fn();
|
|
54
|
-
const { baseButton } = createBaseButton(defaultParams => ({
|
|
55
|
-
...defaultParams,
|
|
56
|
-
onClick: onClickHandler
|
|
57
|
-
}));
|
|
58
|
-
|
|
59
|
-
await userEvent.click(baseButton);
|
|
60
|
-
|
|
61
|
-
expect(onClickHandler).toBeCalled();
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
describe("Properties of the button", () => {
|
|
66
|
-
it("should be disabled, function should not have been called", async () => {
|
|
67
|
-
const onClickHandler = jest.fn();
|
|
68
|
-
const { baseButton } = createBaseButton(defaultParams => ({
|
|
69
|
-
...defaultParams,
|
|
70
|
-
disabled: true,
|
|
71
|
-
onClick: onClickHandler
|
|
72
|
-
}));
|
|
73
|
-
|
|
74
|
-
await userEvent.click(baseButton);
|
|
75
|
-
expect(onClickHandler).toHaveBeenCalledTimes(0);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it("when loading onClick function should not have been called", async () => {
|
|
79
|
-
const onClickHandler = jest.fn();
|
|
80
|
-
const { baseButton } = createBaseButton(defaultParams => ({
|
|
81
|
-
...defaultParams,
|
|
82
|
-
loading: true,
|
|
83
|
-
onClick: onClickHandler
|
|
84
|
-
}));
|
|
85
|
-
|
|
86
|
-
await userEvent.click(baseButton);
|
|
87
|
-
expect(onClickHandler).toHaveBeenCalledTimes(0);
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
it('should have the class "TESTING"', () => {
|
|
91
|
-
const { baseButton } = createBaseButton(defaultParams => ({
|
|
92
|
-
...defaultParams,
|
|
93
|
-
className: "TESTING"
|
|
94
|
-
}));
|
|
95
|
-
|
|
96
|
-
expect(baseButton).toHaveClass("TESTING");
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
it('should have a "name" property with the value "button"', () => {
|
|
100
|
-
const { baseButton } = createBaseButton(defaultParams => ({
|
|
101
|
-
...defaultParams,
|
|
102
|
-
name: "button"
|
|
103
|
-
}));
|
|
104
|
-
|
|
105
|
-
expect(baseButton).toHaveAttribute("name", "button");
|
|
106
|
-
});
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
describe("ref should work", () => {
|
|
110
|
-
it("should give back the proper data prop, this also checks if the component propagates ...rest properly", () => {
|
|
111
|
-
const ExampleComponent = ({
|
|
112
|
-
propagateRef
|
|
113
|
-
}: {
|
|
114
|
-
propagateRef?: (ref: React.RefObject<HTMLElement>) => void;
|
|
115
|
-
}) => {
|
|
116
|
-
const ref = useRef(null);
|
|
117
|
-
|
|
118
|
-
useEffect(() => {
|
|
119
|
-
if (ref.current) {
|
|
120
|
-
propagateRef && propagateRef(ref);
|
|
121
|
-
}
|
|
122
|
-
}, [ref]);
|
|
123
|
-
|
|
124
|
-
return <BaseButton {...defaultParams} data-ref="testing" ref={ref} />;
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
const refCheck = (ref: React.RefObject<HTMLElement>) => {
|
|
128
|
-
expect(ref.current).toHaveAttribute("data-ref", "testing");
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
render(<ExampleComponent propagateRef={refCheck} />);
|
|
132
|
-
});
|
|
133
|
-
});
|