@onewelcome/react-lib-components 0.2.5 → 0.3.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/ContextMenu/ContextMenu.d.ts +2 -1
- package/dist/react-lib-components.cjs.development.js +27 -17
- 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 +27 -17
- package/dist/react-lib-components.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/ContextMenu/ContextMenu.module.scss +8 -0
- package/src/ContextMenu/ContextMenu.test.tsx +43 -0
- package/src/ContextMenu/ContextMenu.tsx +11 -1
- package/src/Form/Input/Input.module.scss +1 -0
- package/src/Form/Wrapper/InputWrapper/InputWrapper.module.scss +18 -11
- package/src/Form/Wrapper/InputWrapper/InputWrapper.test.tsx +20 -0
- package/src/Form/Wrapper/InputWrapper/InputWrapper.tsx +10 -4
- package/src/Form/Wrapper/Wrapper/Wrapper.module.scss +4 -0
- package/src/Form/Wrapper/Wrapper/Wrapper.tsx +2 -1
package/package.json
CHANGED
|
@@ -88,6 +88,16 @@ describe("ContextMenu should render", () => {
|
|
|
88
88
|
expect(child.parentElement).toHaveClass("custom");
|
|
89
89
|
});
|
|
90
90
|
|
|
91
|
+
it("renders the decorative element", () => {
|
|
92
|
+
const { getByText } = createContextMenu(defaultParams => ({
|
|
93
|
+
...defaultParams,
|
|
94
|
+
show: true,
|
|
95
|
+
decorativeElement: <div>test</div>
|
|
96
|
+
}));
|
|
97
|
+
|
|
98
|
+
expect(getByText("test")).toBeInTheDocument();
|
|
99
|
+
});
|
|
100
|
+
|
|
91
101
|
it("should throw an error", () => {
|
|
92
102
|
// Prevent throwing an error in the console when this test is executed. We fix this and the end of this test.
|
|
93
103
|
const err = console.error;
|
|
@@ -252,4 +262,37 @@ describe("accessibility controls", () => {
|
|
|
252
262
|
|
|
253
263
|
expect(thirdContextMenuItem).toHaveFocus();
|
|
254
264
|
});
|
|
265
|
+
|
|
266
|
+
it("opens correctly with enter, navigate with arrow keys skipping the decorative element", () => {
|
|
267
|
+
onClick.mockImplementation(e => {
|
|
268
|
+
expect(e.target.getAttribute("data-testid")).toBe("contextmenuitem3");
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
const { trigger, getByTestId, getByText } = createContextMenu(defaultParams => ({
|
|
272
|
+
...defaultParams,
|
|
273
|
+
decorativeElement: <div>test</div>
|
|
274
|
+
}));
|
|
275
|
+
const thirdContextMenuItem = getByTestId("contextmenuitem3");
|
|
276
|
+
|
|
277
|
+
userEvent.tab();
|
|
278
|
+
userEvent.keyboard("{enter}");
|
|
279
|
+
|
|
280
|
+
expect(getByText("test")).toBeInTheDocument();
|
|
281
|
+
|
|
282
|
+
expect(trigger).toHaveAttribute("aria-expanded", "true");
|
|
283
|
+
|
|
284
|
+
userEvent.keyboard("{arrowdown}");
|
|
285
|
+
userEvent.keyboard("{arrowdown}");
|
|
286
|
+
userEvent.keyboard("{arrowdown}");
|
|
287
|
+
|
|
288
|
+
expect(thirdContextMenuItem).toHaveFocus();
|
|
289
|
+
|
|
290
|
+
userEvent.keyboard("{space}");
|
|
291
|
+
|
|
292
|
+
expect(onClick).toHaveBeenCalled();
|
|
293
|
+
|
|
294
|
+
userEvent.keyboard("{space}");
|
|
295
|
+
|
|
296
|
+
expect(thirdContextMenuItem).toHaveFocus();
|
|
297
|
+
});
|
|
255
298
|
});
|
|
@@ -16,6 +16,7 @@ import { createPortal } from "react-dom";
|
|
|
16
16
|
|
|
17
17
|
export interface Props extends ComponentPropsWithRef<"div"> {
|
|
18
18
|
trigger: ReactElement<ButtonProps> | ReactElement<IconButtonProps>;
|
|
19
|
+
decorativeElement?: ReactNode;
|
|
19
20
|
children: ReactNode;
|
|
20
21
|
placement?: Placement;
|
|
21
22
|
transformOrigin?: Placement;
|
|
@@ -32,6 +33,7 @@ export const ContextMenu = React.forwardRef<HTMLDivElement, Props>(
|
|
|
32
33
|
{
|
|
33
34
|
trigger,
|
|
34
35
|
children,
|
|
36
|
+
decorativeElement,
|
|
35
37
|
id,
|
|
36
38
|
show = false,
|
|
37
39
|
onShow,
|
|
@@ -183,7 +185,15 @@ export const ContextMenu = React.forwardRef<HTMLDivElement, Props>(
|
|
|
183
185
|
anchorEl={anchorEl}
|
|
184
186
|
show={showContextMenu}
|
|
185
187
|
>
|
|
186
|
-
|
|
188
|
+
{decorativeElement && (
|
|
189
|
+
<div className={classes["decorative-element"]}>{decorativeElement}</div>
|
|
190
|
+
)}
|
|
191
|
+
<ul
|
|
192
|
+
className={`${classes["menu"]} ${decorativeElement ? classes["no-margin-top"] : ""}`}
|
|
193
|
+
id={`${id}-menu`}
|
|
194
|
+
aria-describedby={id}
|
|
195
|
+
role="menu"
|
|
196
|
+
>
|
|
187
197
|
{renderChildren()}
|
|
188
198
|
</ul>
|
|
189
199
|
</Popover>,
|
|
@@ -12,19 +12,26 @@ input {
|
|
|
12
12
|
margin-top: 0.25rem;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
.input-wrapper
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
.input-wrapper {
|
|
16
|
+
[data-icon]:before {
|
|
17
|
+
transition: 0.2s ease-in-out;
|
|
18
|
+
transform: translateY(0px);
|
|
19
|
+
font-size: 1.125rem;
|
|
20
|
+
}
|
|
20
21
|
|
|
21
|
-
.
|
|
22
|
-
|
|
23
|
-
}
|
|
22
|
+
.floating-label-active [data-icon]:before {
|
|
23
|
+
transform: translateY(5px);
|
|
24
|
+
}
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
[data-prefix],
|
|
27
|
+
[data-suffix] {
|
|
28
|
+
transform: translateY(-0.125rem);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.disabled {
|
|
32
|
+
background-color: var(--disabled);
|
|
33
|
+
cursor: not-allowed;
|
|
34
|
+
}
|
|
28
35
|
}
|
|
29
36
|
|
|
30
37
|
.floating-label-active [data-prefix],
|
|
@@ -58,6 +58,26 @@ describe("InputWrapper should render", () => {
|
|
|
58
58
|
|
|
59
59
|
expect(input).toHaveAttribute("aria-describedby", helperId);
|
|
60
60
|
});
|
|
61
|
+
|
|
62
|
+
it("disabled input", () => {
|
|
63
|
+
const { getByLabelText } = createInputWrapper(defaultParams => ({
|
|
64
|
+
...defaultParams,
|
|
65
|
+
disabled: true
|
|
66
|
+
}));
|
|
67
|
+
|
|
68
|
+
const input = getByLabelText("Example label");
|
|
69
|
+
|
|
70
|
+
expect(input).toBeDisabled();
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it("consume wrapper props classname", () => {
|
|
74
|
+
const { container } = createInputWrapper(defaultParams => ({
|
|
75
|
+
...defaultParams,
|
|
76
|
+
inputProps: { wrapperProps: { className: "testClass" } }
|
|
77
|
+
}));
|
|
78
|
+
|
|
79
|
+
expect(container.querySelector(".testClass")).toBeDefined();
|
|
80
|
+
});
|
|
61
81
|
});
|
|
62
82
|
|
|
63
83
|
describe("ref should work", () => {
|
|
@@ -56,6 +56,7 @@ export const InputWrapper = React.forwardRef<HTMLDivElement, Props>(
|
|
|
56
56
|
onChange,
|
|
57
57
|
onBlur,
|
|
58
58
|
onFocus,
|
|
59
|
+
disabled,
|
|
59
60
|
...rest
|
|
60
61
|
}: Props,
|
|
61
62
|
ref
|
|
@@ -72,15 +73,21 @@ export const InputWrapper = React.forwardRef<HTMLDivElement, Props>(
|
|
|
72
73
|
const { prefix, suffix } = inputProps || {};
|
|
73
74
|
const input = useRef<HTMLInputElement>(null);
|
|
74
75
|
const hasValueOrActiveFloatingLabel = !!value || floatingLabelActive;
|
|
75
|
-
const labelClasses = [classes["input-label"]];
|
|
76
76
|
const { labelOffset } = useLabelOffset(
|
|
77
77
|
(inputProps && (inputProps.ref as React.RefObject<HTMLInputElement>)) || input,
|
|
78
78
|
floatingLabelActive,
|
|
79
79
|
prefix
|
|
80
80
|
);
|
|
81
81
|
|
|
82
|
+
const labelClasses = [classes["input-label"]];
|
|
82
83
|
hasFocus && labelClasses.push(classes["focus"]);
|
|
83
84
|
|
|
85
|
+
const inputWrapperClasses = [];
|
|
86
|
+
floatingLabelActive && inputWrapperClasses.push(classes["floating-label-active"]);
|
|
87
|
+
inputProps?.wrapperProps?.className &&
|
|
88
|
+
inputWrapperClasses.push(inputProps?.wrapperProps?.className);
|
|
89
|
+
disabled && inputWrapperClasses.push(classes["disabled"]);
|
|
90
|
+
|
|
84
91
|
return (
|
|
85
92
|
<Wrapper
|
|
86
93
|
{...rest}
|
|
@@ -102,15 +109,14 @@ export const InputWrapper = React.forwardRef<HTMLDivElement, Props>(
|
|
|
102
109
|
className: `${classes["input-wrapper-helper"]} ${helperProps?.className ?? ""} `
|
|
103
110
|
}}
|
|
104
111
|
helperIndent={20}
|
|
112
|
+
disabled={disabled}
|
|
105
113
|
>
|
|
106
114
|
<Input
|
|
107
115
|
{...inputProps}
|
|
108
116
|
prefix={hasValueOrActiveFloatingLabel ? prefix : ""}
|
|
109
117
|
suffix={hasValueOrActiveFloatingLabel ? suffix : ""}
|
|
110
118
|
wrapperProps={{
|
|
111
|
-
className:
|
|
112
|
-
inputProps?.wrapperProps?.className ?? ""
|
|
113
|
-
}`
|
|
119
|
+
className: inputWrapperClasses.join(" ")
|
|
114
120
|
}}
|
|
115
121
|
ref={(inputProps && inputProps.ref) || input}
|
|
116
122
|
aria-labelledby={labelId}
|
|
@@ -69,9 +69,10 @@ export const Wrapper = React.forwardRef<HTMLDivElement, Props>(
|
|
|
69
69
|
labelProps?.className && labelClasses.push(labelProps.className);
|
|
70
70
|
required && labelClasses.push(classes["required"]);
|
|
71
71
|
error && labelClasses.push(classes["error"]);
|
|
72
|
+
disabled && labelClasses.push(classes["disabled"]);
|
|
72
73
|
|
|
73
74
|
return (
|
|
74
|
-
<div {...rest} ref={ref} className={`${classes.wrapper} ${className
|
|
75
|
+
<div {...rest} ref={ref} className={`${classes.wrapper} ${className ?? ""}`}>
|
|
75
76
|
<FormGroup
|
|
76
77
|
error={error}
|
|
77
78
|
errorMessage={errorMessage}
|