@onewelcome/react-lib-components 1.4.0 → 1.5.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.
Files changed (39) hide show
  1. package/README.md +7 -0
  2. package/dist/Breadcrumbs/Breadcrumbs.d.ts +1 -1
  3. package/dist/ContextMenu/ContextMenu.d.ts +4 -1
  4. package/dist/DataGrid/DataGridActions/DataGridColumnsToggle.d.ts +1 -1
  5. package/dist/DataGrid/datagrid.interfaces.d.ts +4 -4
  6. package/dist/Form/FormControl/FormControl.d.ts +1 -1
  7. package/dist/Form/Input/Input.d.ts +1 -1
  8. package/dist/Form/Select/Select.d.ts +1 -1
  9. package/dist/Form/Select/Select.interfaces.d.ts +1 -1
  10. package/dist/Icon/Icon.d.ts +1 -1
  11. package/dist/Link/Link.d.ts +1 -1
  12. package/dist/Notifications/Snackbar/interfaces.d.ts +2 -2
  13. package/dist/Pagination/Pagination.d.ts +3 -3
  14. package/dist/Popover/Popover.d.ts +3 -1
  15. package/dist/Typography/Typography.d.ts +2 -2
  16. package/dist/Wizard/Wizard.d.ts +1 -1
  17. package/dist/Wizard/wizardStateReducer.d.ts +2 -2
  18. package/dist/_BaseStyling_/BaseStyling.d.ts +2 -0
  19. package/dist/hooks/usePosition.d.ts +6 -5
  20. package/dist/hooks/useSpacing.d.ts +3 -3
  21. package/dist/interfaces.d.ts +1 -1
  22. package/dist/react-lib-components.cjs.development.js +78 -56
  23. package/dist/react-lib-components.cjs.development.js.map +1 -1
  24. package/dist/react-lib-components.cjs.production.min.js +1 -1
  25. package/dist/react-lib-components.cjs.production.min.js.map +1 -1
  26. package/dist/react-lib-components.esm.js +79 -57
  27. package/dist/react-lib-components.esm.js.map +1 -1
  28. package/dist/util/helper.d.ts +1 -1
  29. package/package.json +36 -35
  30. package/src/ContextMenu/ContextMenu.tsx +18 -7
  31. package/src/Form/Input/Input.test.tsx +12 -0
  32. package/src/Form/Input/Input.tsx +1 -0
  33. package/src/Popover/Popover.test.tsx +4 -1
  34. package/src/Popover/Popover.tsx +40 -8
  35. package/src/Tooltip/Tooltip.test.tsx +5 -5
  36. package/src/_BaseStyling_/BaseStyling.tsx +4 -0
  37. package/src/hooks/usePosition.test.tsx +85 -85
  38. package/src/hooks/usePosition.ts +6 -3
  39. package/src/mixins.module.scss +5 -5
@@ -1,4 +1,4 @@
1
- declare type KeyValuePair = {
1
+ type KeyValuePair = {
2
2
  [key: string]: unknown;
3
3
  };
4
4
  export declare const generateID: (length?: number, stringToWeaveIn?: string) => string;
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
+ "homepage": "http://onewelcome.github.io/react-lib-components",
2
3
  "name": "@onewelcome/react-lib-components",
3
- "version": "1.4.0",
4
+ "version": "1.5.0",
4
5
  "license": "Apache-2.0",
5
6
  "author": "OneWelcome B.V.",
6
7
  "main": "dist/index.js",
@@ -51,60 +52,60 @@
51
52
  }
52
53
  ],
53
54
  "devDependencies": {
54
- "@babel/core": "^7.19.3",
55
+ "@babel/core": "^7.20.12",
55
56
  "@mdx-js/react": "^1.6.22",
56
57
  "@onewelcome/eslint-config-shared-codestyle": "^9.0.3",
57
58
  "@size-limit/preset-small-lib": "^7.0.8",
58
- "@storybook/addon-a11y": "^6.5.12",
59
- "@storybook/addon-docs": "^6.5.12",
60
- "@storybook/addon-essentials": "^6.5.12",
61
- "@storybook/addon-links": "^6.5.12",
62
- "@storybook/addons": "^6.5.12",
63
- "@storybook/builder-webpack5": "^6.5.12",
64
- "@storybook/manager-webpack5": "^6.5.12",
59
+ "@storybook/addon-a11y": "^6.5.15",
60
+ "@storybook/addon-docs": "^6.5.15",
61
+ "@storybook/addon-essentials": "^6.5.15",
62
+ "@storybook/addon-links": "^6.5.15",
63
+ "@storybook/addons": "^6.5.15",
64
+ "@storybook/builder-webpack5": "^6.5.15",
65
+ "@storybook/manager-webpack5": "^6.5.15",
65
66
  "@storybook/preset-scss": "^1.0.3",
66
- "@storybook/react": "^6.5.12",
67
- "@storybook/theming": "^6.5.12",
68
- "@testing-library/dom": "^8.18.1",
67
+ "@storybook/react": "^6.5.15",
68
+ "@storybook/theming": "^6.5.15",
69
+ "@testing-library/dom": "^8.19.1",
69
70
  "@testing-library/jest-dom": "^5.16.5",
70
71
  "@testing-library/react": "^12.1.5",
71
- "@testing-library/react-hooks": "^7.0.2",
72
+ "@testing-library/react-hooks": "^8.0.1",
72
73
  "@testing-library/user-event": "^13.5.0",
73
- "@tsconfig/create-react-app": "^1.0.2",
74
+ "@tsconfig/create-react-app": "^1.0.3",
74
75
  "@tsconfig/recommended": "^1.0.1",
75
76
  "@types/color-convert": "^2.0.0",
76
- "@types/mdx": "^2.0.2",
77
- "@types/react": "^17.0.50",
78
- "@types/react-dom": "^17.0.17",
79
- "@types/react-router": "^5.1.19",
77
+ "@types/mdx": "^2.0.3",
78
+ "@types/react": "^17.0.52",
79
+ "@types/react-dom": "^17.0.18",
80
+ "@types/react-router": "^5.1.20",
80
81
  "@types/react-router-dom": "^5.3.3",
81
- "@typescript-eslint/eslint-plugin": "^5.39.0",
82
- "@typescript-eslint/parser": "^5.39.0",
83
- "babel-loader": "^8.2.5",
84
- "dts-cli": "^1.6.0",
85
- "eslint": "^8.24.0",
86
- "eslint-config-prettier": "^8.5.0",
82
+ "@typescript-eslint/eslint-plugin": "^5.48.1",
83
+ "@typescript-eslint/parser": "^5.48.1",
84
+ "babel-loader": "^9.1.0",
85
+ "dts-cli": "^1.6.3",
86
+ "eslint": "^8.31.0",
87
+ "eslint-config-prettier": "^8.6.0",
87
88
  "eslint-plugin-cypress": "^2.12.1",
88
- "eslint-plugin-jest": "^26.9.0",
89
+ "eslint-plugin-jest": "^27.2.1",
89
90
  "eslint-plugin-license-header": "^0.6.0",
90
91
  "eslint-plugin-prettier": "^4.2.1",
91
92
  "html-webpack-plugin": "^5.5.0",
92
- "husky": "^7.0.4",
93
+ "husky": "^8.0.3",
93
94
  "identity-obj-proxy": "^3.0.0",
94
- "jest-junit": "^13.2.0",
95
- "lint-staged": "^13.0.3",
95
+ "jest-junit": "^15.0.0",
96
+ "lint-staged": "^13.1.0",
96
97
  "npm-run-all": "^4.1.5",
97
- "prettier": "^2.7.1",
98
+ "prettier": "^2.8.2",
98
99
  "react": "^17.0.2",
99
100
  "react-dom": "^17.0.2",
100
- "react-is": "^17.0.2",
101
- "react-router": "^6.4.2",
102
- "react-router-dom": "^6.4.2",
101
+ "react-is": "^18.2.0",
102
+ "react-router": "^6.6.2",
103
+ "react-router-dom": "^6.6.2",
103
104
  "rollup-plugin-cleanup": "^3.2.1",
104
105
  "rollup-plugin-styles": "^4.0.0",
105
- "sass": "^1.55.0",
106
+ "sass": "^1.57.1",
106
107
  "size-limit": "^7.0.8",
107
- "tslib": "^2.4.0",
108
- "typescript": "^4.8.4"
108
+ "tslib": "^2.4.1",
109
+ "typescript": "^4.9.4"
109
110
  }
110
111
  }
@@ -19,13 +19,14 @@ import React, {
19
19
  ForwardRefRenderFunction,
20
20
  ReactElement,
21
21
  ReactNode,
22
+ useCallback,
22
23
  useEffect,
23
24
  useRef,
24
25
  useState
25
26
  } from "react";
26
27
  import { Props as ButtonProps } from "../Button/Button";
27
28
  import { Props as IconButtonProps } from "../Button/IconButton";
28
- import { Popover } from "../Popover/Popover";
29
+ import { Popover, Props as PopoverProps } from "../Popover/Popover";
29
30
  import { Placement, Offset } from "../hooks/usePosition";
30
31
  import classes from "./ContextMenu.module.scss";
31
32
  import { useBodyClick } from "../hooks/useBodyClick";
@@ -38,11 +39,13 @@ export interface Props extends ComponentPropsWithRef<"div"> {
38
39
  placement?: Placement;
39
40
  transformOrigin?: Placement;
40
41
  offset?: Offset;
42
+ debounceAmount?: number;
41
43
  id: string;
42
44
  show?: boolean;
43
45
  domRoot?: HTMLElement;
44
46
  onShow?: () => void;
45
47
  onClose?: () => void;
48
+ popoverProps?: PopoverProps;
46
49
  }
47
50
 
48
51
  const ContextMenuComponent: ForwardRefRenderFunction<HTMLDivElement, Props> = (
@@ -57,7 +60,9 @@ const ContextMenuComponent: ForwardRefRenderFunction<HTMLDivElement, Props> = (
57
60
  placement = { horizontal: "right", vertical: "top" },
58
61
  offset = { top: 0, bottom: 0, left: 0, right: 0 },
59
62
  transformOrigin = { horizontal: "left", vertical: "top" },
63
+ debounceAmount,
60
64
  domRoot = document.body,
65
+ popoverProps,
61
66
  ...rest
62
67
  }: Props,
63
68
  ref
@@ -173,9 +178,9 @@ const ContextMenuComponent: ForwardRefRenderFunction<HTMLDivElement, Props> = (
173
178
  ref: anchorEl
174
179
  });
175
180
 
176
- const renderChildren = () => {
177
- return React.Children.map(children, (child, index) => {
178
- return React.cloneElement(child as ReactElement, {
181
+ const renderChildren = () =>
182
+ React.Children.map(children, (child, index) =>
183
+ React.cloneElement(child as ReactElement, {
179
184
  onFocusChange: (childIndex: number) => setFocusedContextMenuItem(childIndex),
180
185
  onSelectedChange: (childIndex: number) => {
181
186
  setSelectedContextMenuItem(childIndex);
@@ -186,20 +191,26 @@ const ContextMenuComponent: ForwardRefRenderFunction<HTMLDivElement, Props> = (
186
191
  isSelected: selectedContextMenuItem === index,
187
192
  contextMenuOpened: showContextMenu,
188
193
  shouldClick: shouldClick
189
- });
190
- });
191
- };
194
+ })
195
+ );
196
+
197
+ const onOutOfViewHandler = useCallback(() => {
198
+ setShowContextMenu(false);
199
+ }, []);
192
200
 
193
201
  return (
194
202
  <div {...rest} ref={ref} onKeyDown={onArrowNavigation} className={classes["context-menu"]}>
195
203
  {renderTrigger()}
196
204
  {createPortal(
197
205
  <Popover
206
+ {...popoverProps}
198
207
  placement={placement}
199
208
  transformOrigin={transformOrigin}
200
209
  offset={offset}
201
210
  anchorEl={anchorEl}
211
+ debounceAmount={debounceAmount}
202
212
  show={showContextMenu}
213
+ onAnchorOutOfView={onOutOfViewHandler}
203
214
  >
204
215
  {decorativeElement && (
205
216
  <div className={classes["decorative-element"]}>{decorativeElement}</div>
@@ -112,6 +112,18 @@ describe("Should have the appropriate attributes", () => {
112
112
  expect(input).toHaveAttribute("disabled");
113
113
  expect(input).toHaveClass("classname");
114
114
  });
115
+
116
+ it("should render an input with spellcheck enabled", () => {
117
+ const { input } = createInput(defaultParams => ({ ...defaultParams, spellCheck: true }));
118
+
119
+ expect(input).toHaveAttribute("spellcheck", "true");
120
+ });
121
+
122
+ it("should render an input with spellcheck disabled by default", () => {
123
+ const { input } = createInput(defaultParams => ({ ...defaultParams }));
124
+
125
+ expect(input).toHaveAttribute("spellcheck", "false");
126
+ });
115
127
  });
116
128
 
117
129
  describe("Should render all different types of inputs", () => {
@@ -124,6 +124,7 @@ const InputComponent: ForwardRefRenderFunction<HTMLInputElement, Props> = (
124
124
  name={name}
125
125
  disabled={disabled}
126
126
  className={inputClassNames.join(" ")}
127
+ spellCheck={rest.spellCheck || false}
127
128
  />
128
129
  {suffix && (
129
130
  <div ref={suffixRef} data-suffix className={classes["suffix"]}>
@@ -32,7 +32,7 @@ const createPopover = (params?: (defaultParams: Props) => Props) => {
32
32
  <li>Test</li>
33
33
  </ul>
34
34
  ),
35
- show: false,
35
+ show: true,
36
36
  placement: { vertical: "top", horizontal: "left" }
37
37
  };
38
38
  let parameters: Props = defaultParams;
@@ -95,6 +95,9 @@ describe("Popover should render", () => {
95
95
  it("renders without crashing and has default left and top attributes", () => {
96
96
  const { popover } = createPopover();
97
97
 
98
+ window.dispatchEvent(new Event("resize"));
99
+ window.dispatchEvent(new Event("scroll"));
100
+
98
101
  expect(popover).toBeTruthy();
99
102
  });
100
103
  });
@@ -31,37 +31,69 @@ export interface Props extends ComponentPropsWithRef<"div"> {
31
31
  anchorEl?: RefObject<HTMLOrSVGElement>; //eslint-disable-line no-undef
32
32
  placement?: Placement;
33
33
  offset?: Offset;
34
+ debounceAmount?: number;
34
35
  transformOrigin?: Placement;
36
+ onAnchorOutOfView?: () => void;
35
37
  }
36
38
 
37
39
  const PopoverComponent: ForwardRefRenderFunction<HTMLDivElement, Props> = (
38
- { children, className, show, placement, offset, transformOrigin, anchorEl, ...rest },
40
+ {
41
+ children,
42
+ className,
43
+ show,
44
+ placement,
45
+ offset,
46
+ debounceAmount,
47
+ transformOrigin,
48
+ anchorEl,
49
+ onAnchorOutOfView,
50
+ ...rest
51
+ },
39
52
  ref
40
53
  ) => {
41
54
  const elToBePositioned = useRef<HTMLDivElement>(null);
42
55
 
43
- if (show === undefined) {
44
- throw new Error('Please make sure to define the "show" property on your Popover component');
45
- }
46
-
47
56
  const { top, left, right, bottom, calculatePosition } = usePosition({
48
57
  elementToBePositioned: elToBePositioned,
49
58
  relativeElement: anchorEl,
50
59
  offset: offset,
51
60
  placement: placement,
52
- transformOrigin: transformOrigin
61
+ transformOrigin: transformOrigin,
62
+ debounceAmount: debounceAmount || undefined
53
63
  });
54
64
 
55
65
  useEffect(() => {
66
+ if (!show) {
67
+ return;
68
+ }
69
+
56
70
  window.addEventListener("resize", calculatePosition);
71
+ window.addEventListener("scroll", calculatePosition);
57
72
 
58
- return () => window.removeEventListener("resize", calculatePosition);
59
- }, []);
73
+ return () => {
74
+ window.removeEventListener("resize", calculatePosition);
75
+ window.removeEventListener("scroll", calculatePosition);
76
+ };
77
+ }, [show]);
60
78
 
61
79
  useEffect(() => {
62
80
  calculatePosition();
63
81
  }, [show]);
64
82
 
83
+ useEffect(() => {
84
+ const isAnchorOffscreen =
85
+ show &&
86
+ (top === 0 ||
87
+ left === 0 ||
88
+ right === 0 ||
89
+ bottom === 0 ||
90
+ window.innerHeight - (elToBePositioned.current as HTMLElement).offsetHeight === top);
91
+
92
+ if (isAnchorOffscreen) {
93
+ onAnchorOutOfView && onAnchorOutOfView();
94
+ }
95
+ }, [top, left, right, bottom]);
96
+
65
97
  return (
66
98
  <div ref={ref} {...rest}>
67
99
  <div
@@ -16,7 +16,7 @@
16
16
 
17
17
  import React, { useEffect, useRef } from "react";
18
18
  import { Tooltip, Props } from "./Tooltip";
19
- import { render } from "@testing-library/react";
19
+ import { render, waitFor } from "@testing-library/react";
20
20
  import userEvent from "@testing-library/user-event";
21
21
 
22
22
  const defaultParams: Props = {
@@ -39,7 +39,7 @@ const createTooltip = (params?: (defaultParams: Props) => Props) => {
39
39
  };
40
40
 
41
41
  describe("Tooltip should render", () => {
42
- it("renders without crashing", () => {
42
+ it("renders without crashing", async () => {
43
43
  const { tooltip, getByText } = createTooltip(defaultParams => ({
44
44
  ...defaultParams,
45
45
  className: "testing"
@@ -49,7 +49,7 @@ describe("Tooltip should render", () => {
49
49
  const label = getByText("Label");
50
50
 
51
51
  expect(tooltip).toHaveClass("testing");
52
- expect(tooltipText).toHaveStyle({ top: "0px", left: "16px" });
52
+ await waitFor(() => expect(tooltipText).toHaveStyle({ top: "0px", left: "16px" }));
53
53
  expect(label).toBeTruthy();
54
54
  expect(tooltipText).toBeTruthy();
55
55
  expect(tooltip).toBeTruthy();
@@ -65,7 +65,7 @@ describe("Tooltip should render", () => {
65
65
  expect(getByText(labelText)).toBeDefined();
66
66
  });
67
67
 
68
- it("should override the default placement and offset values", () => {
68
+ it("should override the default placement and offset values", async () => {
69
69
  const { tooltip, getByText } = createTooltip(defaultParams => ({
70
70
  ...defaultParams,
71
71
  placement: { horizontal: "center", vertical: "center" },
@@ -74,7 +74,7 @@ describe("Tooltip should render", () => {
74
74
  }));
75
75
 
76
76
  const tooltipText = getByText("This is a test message");
77
- expect(tooltipText).toHaveStyle({ right: "1024px", bottom: "768px" });
77
+ await waitFor(() => expect(tooltipText).toHaveStyle({ right: "1024px", bottom: "768px" }));
78
78
  expect(tooltip).toBeTruthy();
79
79
  });
80
80
  });
@@ -42,6 +42,8 @@ interface CSSProperties {
42
42
  modalShadowColor?: string;
43
43
  modalBackgroundColor?: string;
44
44
  modalHeaderBackgroundColor?: string;
45
+ skeletonBackgroundColor?: string;
46
+ skeletonAnimationColorRgb?: string;
45
47
  snackbarTextColor?: string;
46
48
  snackbarInfoBackgroundColor?: string;
47
49
  snackbarSuccessBackgroundColor?: string;
@@ -103,6 +105,8 @@ export const BaseStyling = ({ children, properties = {} }: Props) => {
103
105
  modalShadowColor: "rgba(0, 0, 0, 0.16)",
104
106
  modalBackgroundColor: "#f5f8f8",
105
107
  modalHeaderBackgroundColor: "var(--light)",
108
+ skeletonBackgroundColor: "var(--disabled)",
109
+ skeletonAnimationColorRgb: "255, 255, 255",
106
110
  snackbarTextColor: "var(--light)",
107
111
  snackbarInfoBackgroundColor: "#003b5e",
108
112
  snackbarSuccessBackgroundColor: "#008a28",