@onewelcome/react-lib-components 7.1.0 → 8.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.
Files changed (146) hide show
  1. package/dist/cjs/DataGrid/DataGrid.cjs.js +1 -1
  2. package/dist/cjs/DataGrid/DataGrid.cjs.js.map +1 -1
  3. package/dist/cjs/DataGrid/DataGridBody/DataGridBody.cjs.js +1 -1
  4. package/dist/cjs/DataGrid/DataGridBody/DataGridBody.cjs.js.map +1 -1
  5. package/dist/cjs/DataGrid/DataGridBody/DataGridCell/DataGridCell.cjs.js +1 -1
  6. package/dist/cjs/DataGrid/DataGridBody/DataGridCell/DataGridCell.cjs.js.map +1 -1
  7. package/dist/cjs/DataGrid/DataGridBody/DataGridRow/DataGridRow.cjs.js +1 -1
  8. package/dist/cjs/DataGrid/DataGridBody/DataGridRow/DataGridRow.cjs.js.map +1 -1
  9. package/dist/cjs/DataGrid/DataGridFilters/DataGridFilter.cjs.js +1 -1
  10. package/dist/cjs/DataGrid/DataGridFilters/DataGridFilter.cjs.js.map +1 -1
  11. package/dist/cjs/DataGrid/DataGridFilters/DataGridFilter.module.scss.cjs.js +1 -1
  12. package/dist/cjs/DataGrid/DataGridFilters/DataGridFilterPopover.cjs.js +1 -1
  13. package/dist/cjs/DataGrid/DataGridFilters/DataGridFilterPopover.cjs.js.map +1 -1
  14. package/dist/cjs/DataGrid/DataGridFilters/DataGridFilterTag.cjs.js +1 -1
  15. package/dist/cjs/DataGrid/DataGridFilters/DataGridFilterTag.cjs.js.map +1 -1
  16. package/dist/cjs/DataGrid/DataGridFilters/DataGridSearchbar.cjs.js +2 -0
  17. package/dist/cjs/DataGrid/DataGridFilters/DataGridSearchbar.cjs.js.map +1 -0
  18. package/dist/cjs/DataGrid/DataGridFilters/DataGridToolbar.cjs.js +1 -1
  19. package/dist/cjs/DataGrid/DataGridFilters/DataGridToolbar.cjs.js.map +1 -1
  20. package/dist/cjs/DataGrid/DataGridFilters/DataGridToolbar.module.scss.cjs.js +1 -1
  21. package/dist/cjs/DataGrid/DataGridFilters/DataGridToolbarWrapper.cjs.js +2 -0
  22. package/dist/cjs/DataGrid/DataGridFilters/DataGridToolbarWrapper.cjs.js.map +1 -0
  23. package/dist/cjs/DataGrid/DataGridFilters/useFiltersReducer.cjs.js +2 -0
  24. package/dist/cjs/DataGrid/DataGridFilters/useFiltersReducer.cjs.js.map +1 -0
  25. package/dist/cjs/DataGrid/DataGridHeader/DataGridHeaderCell.cjs.js +1 -1
  26. package/dist/cjs/DataGrid/DataGridHeader/DataGridHeaderCell.cjs.js.map +1 -1
  27. package/dist/cjs/DataGrid/DataGridHeader/DataGridHeaderCell.module.scss.cjs.js +1 -1
  28. package/dist/cjs/Form/FileUpload/FileUpload.module.scss.cjs.js +1 -1
  29. package/dist/cjs/Form/Select/MultiSelect/MultiSelect.cjs.js +1 -1
  30. package/dist/cjs/Form/Select/MultiSelect/MultiSelect.cjs.js.map +1 -1
  31. package/dist/cjs/Form/Select/SingleSelect/Select.cjs.js +1 -1
  32. package/dist/cjs/Form/Select/SingleSelect/Select.cjs.js.map +1 -1
  33. package/dist/cjs/Icon/Icon.cjs.js +1 -1
  34. package/dist/cjs/Icon/Icon.cjs.js.map +1 -1
  35. package/dist/cjs/Icon/Icon.module.scss.cjs.js +1 -1
  36. package/dist/cjs/Notifications/BaseModal/BaseModal.cjs.js +1 -1
  37. package/dist/cjs/Notifications/BaseModal/BaseModal.cjs.js.map +1 -1
  38. package/dist/cjs/src/components/DataGrid/DataGrid.d.ts +8 -5
  39. package/dist/cjs/src/components/DataGrid/DataGridBody/DataGridBody.d.ts +1 -0
  40. package/dist/cjs/src/components/DataGrid/DataGridBody/DataGridCell/DataGridCell.d.ts +1 -0
  41. package/dist/cjs/src/components/DataGrid/DataGridBody/DataGridRow/DataGridRow.d.ts +1 -0
  42. package/dist/cjs/src/components/DataGrid/DataGridFilters/DataGridFilter.d.ts +3 -3
  43. package/dist/cjs/src/components/DataGrid/DataGridFilters/DataGridFilterPopover.d.ts +3 -2
  44. package/dist/cjs/src/components/DataGrid/DataGridFilters/DataGridFilterTag.d.ts +2 -1
  45. package/dist/cjs/src/components/DataGrid/DataGridFilters/DataGridSearchbar.d.ts +10 -0
  46. package/dist/cjs/src/components/DataGrid/DataGridFilters/DataGridToolbar.d.ts +4 -4
  47. package/dist/cjs/src/components/DataGrid/DataGridFilters/DataGridToolbarWrapper.d.ts +10 -0
  48. package/dist/cjs/src/components/DataGrid/DataGridFilters/useFiltersReducer.d.ts +8 -0
  49. package/dist/cjs/src/components/DataGrid/DataGridFilters/useFiltersReducer.test.d.ts +1 -0
  50. package/dist/cjs/src/components/DataGrid/testUtils.d.ts +1 -0
  51. package/dist/cjs/src/components/Icon/Icon.d.ts +2 -1
  52. package/dist/cjs/src/hooks/useRepeatFocus.cjs.js +2 -0
  53. package/dist/cjs/src/hooks/useRepeatFocus.cjs.js.map +1 -0
  54. package/dist/cjs/src/index.cjs.js +1 -1
  55. package/dist/cjs/src/index.d.ts +1 -0
  56. package/dist/esm/DataGrid/DataGrid.esm.js +8 -4
  57. package/dist/esm/DataGrid/DataGrid.esm.js.map +1 -1
  58. package/dist/esm/DataGrid/DataGridBody/DataGridBody.esm.js +2 -1
  59. package/dist/esm/DataGrid/DataGridBody/DataGridBody.esm.js.map +1 -1
  60. package/dist/esm/DataGrid/DataGridBody/DataGridCell/DataGridCell.esm.js +22 -3
  61. package/dist/esm/DataGrid/DataGridBody/DataGridCell/DataGridCell.esm.js.map +1 -1
  62. package/dist/esm/DataGrid/DataGridBody/DataGridRow/DataGridRow.esm.js +2 -1
  63. package/dist/esm/DataGrid/DataGridBody/DataGridRow/DataGridRow.esm.js.map +1 -1
  64. package/dist/esm/DataGrid/DataGridFilters/DataGridFilter.esm.js +7 -14
  65. package/dist/esm/DataGrid/DataGridFilters/DataGridFilter.esm.js.map +1 -1
  66. package/dist/esm/DataGrid/DataGridFilters/DataGridFilter.module.scss.esm.js +2 -2
  67. package/dist/esm/DataGrid/DataGridFilters/DataGridFilterPopover.esm.js +11 -3
  68. package/dist/esm/DataGrid/DataGridFilters/DataGridFilterPopover.esm.js.map +1 -1
  69. package/dist/esm/DataGrid/DataGridFilters/DataGridFilterTag.esm.js +5 -7
  70. package/dist/esm/DataGrid/DataGridFilters/DataGridFilterTag.esm.js.map +1 -1
  71. package/dist/esm/DataGrid/DataGridFilters/DataGridSearchbar.esm.js +43 -0
  72. package/dist/esm/DataGrid/DataGridFilters/DataGridSearchbar.esm.js.map +1 -0
  73. package/dist/esm/DataGrid/DataGridFilters/DataGridToolbar.esm.js +18 -34
  74. package/dist/esm/DataGrid/DataGridFilters/DataGridToolbar.esm.js.map +1 -1
  75. package/dist/esm/DataGrid/DataGridFilters/DataGridToolbar.module.scss.esm.js +2 -2
  76. package/dist/esm/DataGrid/DataGridFilters/DataGridToolbarWrapper.esm.js +27 -0
  77. package/dist/esm/DataGrid/DataGridFilters/DataGridToolbarWrapper.esm.js.map +1 -0
  78. package/dist/esm/DataGrid/DataGridFilters/useFiltersReducer.esm.js +59 -0
  79. package/dist/esm/DataGrid/DataGridFilters/useFiltersReducer.esm.js.map +1 -0
  80. package/dist/esm/DataGrid/DataGridHeader/DataGridHeaderCell.esm.js +3 -5
  81. package/dist/esm/DataGrid/DataGridHeader/DataGridHeaderCell.esm.js.map +1 -1
  82. package/dist/esm/DataGrid/DataGridHeader/DataGridHeaderCell.module.scss.esm.js +2 -2
  83. package/dist/esm/Form/FileUpload/FileUpload.module.scss.esm.js +1 -1
  84. package/dist/esm/Form/Select/MultiSelect/MultiSelect.esm.js +1 -1
  85. package/dist/esm/Form/Select/MultiSelect/MultiSelect.esm.js.map +1 -1
  86. package/dist/esm/Form/Select/SingleSelect/Select.esm.js +1 -1
  87. package/dist/esm/Form/Select/SingleSelect/Select.esm.js.map +1 -1
  88. package/dist/esm/Icon/Icon.esm.js +1 -0
  89. package/dist/esm/Icon/Icon.esm.js.map +1 -1
  90. package/dist/esm/Icon/Icon.module.scss.esm.js +2 -2
  91. package/dist/esm/Notifications/BaseModal/BaseModal.esm.js +1 -1
  92. package/dist/esm/Notifications/BaseModal/BaseModal.esm.js.map +1 -1
  93. package/dist/esm/src/components/DataGrid/DataGrid.d.ts +8 -5
  94. package/dist/esm/src/components/DataGrid/DataGridBody/DataGridBody.d.ts +1 -0
  95. package/dist/esm/src/components/DataGrid/DataGridBody/DataGridCell/DataGridCell.d.ts +1 -0
  96. package/dist/esm/src/components/DataGrid/DataGridBody/DataGridRow/DataGridRow.d.ts +1 -0
  97. package/dist/esm/src/components/DataGrid/DataGridFilters/DataGridFilter.d.ts +3 -3
  98. package/dist/esm/src/components/DataGrid/DataGridFilters/DataGridFilterPopover.d.ts +3 -2
  99. package/dist/esm/src/components/DataGrid/DataGridFilters/DataGridFilterTag.d.ts +2 -1
  100. package/dist/esm/src/components/DataGrid/DataGridFilters/DataGridSearchbar.d.ts +10 -0
  101. package/dist/esm/src/components/DataGrid/DataGridFilters/DataGridToolbar.d.ts +4 -4
  102. package/dist/esm/src/components/DataGrid/DataGridFilters/DataGridToolbarWrapper.d.ts +10 -0
  103. package/dist/esm/src/components/DataGrid/DataGridFilters/useFiltersReducer.d.ts +8 -0
  104. package/dist/esm/src/components/DataGrid/DataGridFilters/useFiltersReducer.test.d.ts +1 -0
  105. package/dist/esm/src/components/DataGrid/testUtils.d.ts +1 -0
  106. package/dist/esm/src/components/Icon/Icon.d.ts +2 -1
  107. package/dist/esm/{Notifications/BaseModal → src/hooks}/useRepeatFocus.esm.js +12 -1
  108. package/dist/esm/src/hooks/useRepeatFocus.esm.js.map +1 -0
  109. package/dist/esm/src/index.d.ts +1 -0
  110. package/dist/esm/src/index.esm.js +1 -0
  111. package/dist/esm/src/index.esm.js.map +1 -1
  112. package/package.json +1 -1
  113. package/src/components/DataGrid/DataGrid.tsx +32 -8
  114. package/src/components/DataGrid/DataGridBody/DataGridBody.tsx +3 -0
  115. package/src/components/DataGrid/DataGridBody/DataGridCell/DataGridCell.tsx +34 -2
  116. package/src/components/DataGrid/DataGridBody/DataGridRow/DataGridRow.tsx +3 -0
  117. package/src/components/DataGrid/DataGridFilters/DataGridFilter.module.scss +21 -11
  118. package/src/components/DataGrid/DataGridFilters/DataGridFilter.tsx +15 -19
  119. package/src/components/DataGrid/DataGridFilters/DataGridFilterPopover.tsx +15 -2
  120. package/src/components/DataGrid/DataGridFilters/DataGridFilterTag.tsx +18 -7
  121. package/src/components/DataGrid/DataGridFilters/DataGridSearchbar.tsx +68 -0
  122. package/src/components/DataGrid/DataGridFilters/DataGridToolbar.module.scss +40 -18
  123. package/src/components/DataGrid/DataGridFilters/DataGridToolbar.tsx +34 -62
  124. package/src/components/DataGrid/DataGridFilters/DataGridToolbarWrapper.tsx +38 -0
  125. package/src/components/DataGrid/DataGridFilters/useFiltersReducer.tsx +66 -0
  126. package/src/components/DataGrid/DataGridHeader/DataGridHeaderCell.module.scss +8 -1
  127. package/src/components/DataGrid/DataGridHeader/DataGridHeaderCell.tsx +3 -8
  128. package/src/components/DataGrid/testUtils.ts +14 -16
  129. package/src/components/Form/FileUpload/FileUpload.module.scss +1 -2
  130. package/src/components/Form/Select/MultiSelect/MultiSelect.tsx +1 -3
  131. package/src/components/Form/Select/SingleSelect/Select.tsx +1 -3
  132. package/src/components/Icon/Icon.module.scss +5 -0
  133. package/src/components/Icon/Icon.tsx +2 -1
  134. package/src/components/Notifications/BaseModal/BaseModal.tsx +1 -1
  135. package/src/font/icomoon.eot +0 -0
  136. package/src/font/icomoon.svg +1 -0
  137. package/src/font/icomoon.ttf +0 -0
  138. package/src/font/icomoon.woff +0 -0
  139. package/src/font/selection.json +1 -1
  140. package/src/{components/Notifications/BaseModal → hooks}/useRepeatFocus.tsx +12 -2
  141. package/src/index.ts +1 -0
  142. package/dist/cjs/Notifications/BaseModal/useRepeatFocus.cjs.js +0 -2
  143. package/dist/cjs/Notifications/BaseModal/useRepeatFocus.cjs.js.map +0 -1
  144. package/dist/esm/Notifications/BaseModal/useRepeatFocus.esm.js.map +0 -1
  145. /package/dist/cjs/src/{components/Notifications/BaseModal → hooks}/useRepeatFocus.d.ts +0 -0
  146. /package/dist/esm/src/{components/Notifications/BaseModal → hooks}/useRepeatFocus.d.ts +0 -0
@@ -14,14 +14,13 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import React, { Fragment, createRef, useState } from "react";
17
+ import React, { Fragment, useRef, useState } from "react";
18
18
  import { createPortal } from "react-dom";
19
19
  import { useGetDomRoot } from "../../../hooks/useGetDomRoot";
20
20
  import {
21
21
  DataGridColumnMetadata,
22
22
  Filter,
23
23
  FilterEditorMode,
24
- FiltersAction,
25
24
  PopoverTranslations,
26
25
  TagTranslations
27
26
  } from "./DataGridFilters.interfaces";
@@ -35,12 +34,12 @@ export type Props = {
35
34
  domRoot?: HTMLElement;
36
35
  filter?: Filter;
37
36
  columnsMetadata: DataGridColumnMetadata[];
38
- dispatch: React.Dispatch<FiltersAction>;
39
37
  onFilterAdd?: (filter: Filter) => void;
40
38
  onFilterEdit?: (filter: Filter) => void;
41
39
  onFilterDelete?: (id: string) => void;
42
40
  tagTranslations?: TagTranslations;
43
41
  popoverTranslations?: PopoverTranslations;
42
+ customEditTagContent?: React.ReactElement;
44
43
  };
45
44
 
46
45
  export const DataGridFilter = ({
@@ -48,14 +47,17 @@ export const DataGridFilter = ({
48
47
  filter,
49
48
  domRoot,
50
49
  columnsMetadata,
51
- dispatch,
52
50
  onFilterAdd,
53
51
  onFilterEdit,
54
52
  onFilterDelete,
55
53
  tagTranslations,
56
- popoverTranslations
54
+ popoverTranslations,
55
+ customEditTagContent
57
56
  }: Props) => {
58
- const wrappingDivRef = createRef<HTMLDivElement>();
57
+ const wrappingDivRef = useRef<HTMLDivElement>(null);
58
+ const triggerRef = useRef<HTMLButtonElement>(null);
59
+ const popoverRef = useRef<HTMLDivElement>(null);
60
+
59
61
  const [filterOpen, setFilterOpen] = useState(false);
60
62
  const { root } = useGetDomRoot(domRoot, wrappingDivRef);
61
63
  const {
@@ -76,19 +78,9 @@ export const DataGridFilter = ({
76
78
  const onFilterSubmit = () => {
77
79
  if (mode === "ADD") {
78
80
  const id = generateID();
79
-
80
- dispatch({
81
- type: "add",
82
- payload: { id, column, operator, value: pickedValues }
83
- });
84
81
  onFilterAdd && onFilterAdd({ id, column, operator, value: pickedValues });
85
82
  } else if (mode === "EDIT" && filter) {
86
83
  const { id } = filter;
87
-
88
- dispatch({
89
- type: "edit",
90
- payload: { id, column, operator, value: pickedValues }
91
- });
92
84
  onFilterEdit && onFilterEdit({ id, column, operator, value: pickedValues });
93
85
  }
94
86
 
@@ -100,9 +92,8 @@ export const DataGridFilter = ({
100
92
  if (!filter) {
101
93
  return;
102
94
  }
103
- const { id } = filter;
104
95
 
105
- dispatch({ type: "remove", payload: { id } });
96
+ const { id } = filter;
106
97
  onFilterDelete && onFilterDelete(id);
107
98
 
108
99
  resetFields();
@@ -121,13 +112,18 @@ export const DataGridFilter = ({
121
112
  mode={mode}
122
113
  onFilterOpen={onFilterOpen}
123
114
  onFilterRemove={onFilterRemove}
124
- triggerRef={wrappingDivRef}
115
+ triggerRef={triggerRef}
116
+ ref={wrappingDivRef}
125
117
  filter={filter}
118
+ translations={tagTranslations}
119
+ customEditTagContent={customEditTagContent}
126
120
  />
127
121
  {createPortal(
128
122
  <DataGridFilterPopover
123
+ popoverRef={popoverRef}
129
124
  anchorRef={wrappingDivRef}
130
125
  isOpen={filterOpen}
126
+ translations={popoverTranslations}
131
127
  column={column}
132
128
  columnsMetadata={columnsMetadata}
133
129
  values={values}
@@ -14,7 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import React from "react";
17
+ import React, { useEffect } from "react";
18
18
  import classes from "./DataGridFilter.module.scss";
19
19
  import { Button } from "../../Button/Button";
20
20
  import { Option } from "../../Form/Select/SingleSelect/Option";
@@ -27,9 +27,11 @@ import {
27
27
  DefaultOperators,
28
28
  PopoverTranslations
29
29
  } from "./DataGridFilters.interfaces";
30
+ import { useRepeatFocus } from "../../../hooks/useRepeatFocus";
30
31
 
31
32
  export type Props = {
32
- anchorRef?: React.RefObject<HTMLOrSVGElement>;
33
+ popoverRef: React.RefObject<HTMLDivElement>;
34
+ anchorRef?: React.RefObject<HTMLDivElement>;
33
35
  isOpen: boolean;
34
36
  column: string;
35
37
  columnsMetadata: DataGridColumnMetadata[];
@@ -49,6 +51,7 @@ export type Props = {
49
51
  };
50
52
 
51
53
  export const DataGridFilterPopover = ({
54
+ popoverRef,
52
55
  anchorRef,
53
56
  isOpen,
54
57
  column,
@@ -76,9 +79,19 @@ export const DataGridFilterPopover = ({
76
79
  submitButtonTitle = "Apply",
77
80
  cancelButtonTitle = "Cancel"
78
81
  } = translations || {};
82
+ useRepeatFocus(popoverRef);
83
+
84
+ useEffect(() => {
85
+ if (isOpen) {
86
+ popoverRef.current?.focus();
87
+ }
88
+ }, [isOpen]);
89
+
79
90
  return (
80
91
  <Popover
92
+ tabIndex={-1}
81
93
  anchorEl={anchorRef}
94
+ ref={popoverRef}
82
95
  show={isOpen}
83
96
  placement={{ horizontal: "left", vertical: "bottom" }}
84
97
  transformOrigin={{ horizontal: "left", vertical: "top" }}
@@ -22,7 +22,8 @@ import classes from "./DataGridFilter.module.scss";
22
22
  import { Filter, FilterEditorMode, TagTranslations } from "./DataGridFilters.interfaces";
23
23
 
24
24
  export interface DataGridFilterTagProps extends ComponentPropsWithRef<"div"> {
25
- triggerRef: React.Ref<HTMLDivElement>;
25
+ customEditTagContent?: React.ReactElement;
26
+ triggerRef: React.Ref<HTMLButtonElement>;
26
27
  filter?: Filter;
27
28
  mode: FilterEditorMode;
28
29
  onFilterRemove: () => void;
@@ -38,7 +39,6 @@ const EditTagContent = ({ filter }: { filter: Filter }) => {
38
39
  {column} {operator} {value.length > 0 && <b>{value[0]}</b>}
39
40
  {value.length >= 2 && (
40
41
  <>
41
- {" "}
42
42
  or <b> {value.length - 1} other</b>
43
43
  </>
44
44
  )}
@@ -57,7 +57,7 @@ export const DataGridFilterTagComponent: ForwardRefRenderFunction<
57
57
  onFilterRemove,
58
58
  onFilterOpen,
59
59
  translations,
60
-
60
+ customEditTagContent,
61
61
  ...rest
62
62
  }: DataGridFilterTagProps,
63
63
  ref
@@ -67,8 +67,13 @@ export const DataGridFilterTagComponent: ForwardRefRenderFunction<
67
67
  const shouldRenderEditTag = mode === "EDIT" && filter;
68
68
 
69
69
  return (
70
- <div {...rest} ref={triggerRef} className={classes["filter-wrapper"]}>
71
- <button type="button" className={classes["filter-button"]} onClick={onFilterOpen}>
70
+ <div {...rest} ref={ref} className={classes["filter-wrapper"]}>
71
+ <button
72
+ ref={triggerRef}
73
+ type="button"
74
+ className={classes["filter-button"]}
75
+ onClick={onFilterOpen}
76
+ >
72
77
  {shouldRenderAddTag && (
73
78
  <Fragment>
74
79
  <Icon icon={Icons.AddCircle} />
@@ -79,11 +84,17 @@ export const DataGridFilterTagComponent: ForwardRefRenderFunction<
79
84
  )}
80
85
  {shouldRenderEditTag && (
81
86
  <Typography variant="body" className={classes["caption"]}>
82
- <EditTagContent filter={filter} />
87
+ {customEditTagContent ? (
88
+ React.cloneElement(customEditTagContent, { filter })
89
+ ) : (
90
+ <EditTagContent filter={filter} />
91
+ )}
83
92
  </Typography>
84
93
  )}
85
94
  </button>
86
- {shouldRenderEditTag && <RemoveButton onRemove={onFilterRemove} />}
95
+ {shouldRenderEditTag && (
96
+ <RemoveButton className={classes["remove-button"]} onRemove={onFilterRemove} />
97
+ )}
87
98
  </div>
88
99
  );
89
100
  };
@@ -0,0 +1,68 @@
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, { useState, useEffect } from "react";
18
+ import { InputWrapper } from "../../Form/Wrapper/InputWrapper/InputWrapper";
19
+ import { Icon, Icons } from "../../Icon/Icon";
20
+ import classes from "./DataGridToolbar.module.scss";
21
+ import { InputWrapperProps, useDebouncedCallback } from "../../..";
22
+
23
+ export interface DataGridSearchbarProps {
24
+ onSearch: (value: string) => void;
25
+ initialSearchValue?: string;
26
+ debounceTime?: number;
27
+ placeholder?: string;
28
+ inputWrapperProps?: InputWrapperProps;
29
+ }
30
+
31
+ export const DataGridSearchbar = ({
32
+ onSearch,
33
+ initialSearchValue,
34
+ debounceTime,
35
+ inputWrapperProps,
36
+ placeholder
37
+ }: DataGridSearchbarProps) => {
38
+ const [search, setSearch] = useState(initialSearchValue ?? "");
39
+ const debouncedCallback = useDebouncedCallback(onSearch, debounceTime ?? 500);
40
+ const onSearchCallback = debounceTime ? debouncedCallback : onSearch;
41
+
42
+ const onChange = (event: React.ChangeEvent<HTMLInputElement>) => {
43
+ onSearchCallback(event.target.value);
44
+ setSearch(event.target.value);
45
+ };
46
+
47
+ useEffect(() => {
48
+ initialSearchValue && setSearch(initialSearchValue);
49
+ }, [initialSearchValue]);
50
+
51
+ return (
52
+ <InputWrapper
53
+ {...inputWrapperProps}
54
+ className={`${classes["searchbar"]} ${inputWrapperProps?.className ?? ""}`}
55
+ label={inputWrapperProps?.label ?? ""}
56
+ onChange={onChange}
57
+ type="search"
58
+ name={inputWrapperProps?.name ?? "searchbar"}
59
+ value={search}
60
+ inputProps={{
61
+ ...inputWrapperProps?.inputProps,
62
+ type: "search",
63
+ prefix: <Icon icon={Icons.Search} />,
64
+ placeholder: placeholder ?? "Search items"
65
+ }}
66
+ ></InputWrapper>
67
+ );
68
+ };
@@ -16,34 +16,56 @@
16
16
 
17
17
  @use "../../../mixins.module.scss";
18
18
 
19
- .toolbar {
19
+ .wrapper {
20
20
  display: flex;
21
- align-items: center;
22
- justify-content: flex-start;
23
- flex-wrap: wrap;
21
+ align-items: flex-start;
22
+ justify-content: space-between;
24
23
  gap: 0.5rem;
25
24
  width: 100%;
26
25
  padding-bottom: 1rem;
27
26
 
28
- .actions-wrapper {
27
+ .filter-section {
29
28
  display: flex;
30
29
  align-items: center;
31
30
  justify-content: flex-start;
31
+ flex-wrap: wrap;
32
32
  gap: 0.5rem;
33
- }
33
+ width: 100%;
34
+ flex-grow: 1;
35
+
36
+ .searchbar {
37
+ min-width: 7rem;
38
+ flex-basis: 15rem;
39
+ }
40
+
41
+ .actions-wrapper {
42
+ display: flex;
43
+ align-items: center;
44
+ justify-content: flex-start;
45
+ gap: 0.5rem;
46
+ }
47
+
48
+ .clear-button {
49
+ background: none;
50
+ border: none;
51
+ cursor: pointer;
52
+ @include mixins.focusVisibleOutline($outlineOffset: 0);
34
53
 
35
- .clear-button {
36
- background: none;
37
- border: none;
38
- cursor: pointer;
39
- @include mixins.focusVisibleOutline($outlineOffset: 0);
40
-
41
- .caption {
42
- margin: 0;
43
- font-size: var(--font-size-data-grid);
44
- line-height: var(--data-grid-line-height);
45
- text-decoration: underline;
46
- color: var(--color-primary500);
54
+ .caption {
55
+ margin: 0;
56
+ font-size: var(--font-size-data-grid);
57
+ line-height: var(--data-grid-line-height);
58
+ text-decoration: underline;
59
+ color: var(--color-primary500);
60
+ }
47
61
  }
48
62
  }
63
+
64
+ .button-section {
65
+ flex-shrink: 0;
66
+ display: flex;
67
+ justify-content: center;
68
+ align-items: center;
69
+ gap: 0.5rem;
70
+ }
49
71
  }
@@ -14,20 +14,16 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import React, { ComponentPropsWithRef, ForwardRefRenderFunction, useReducer } from "react";
17
+ import React, { Fragment } from "react";
18
18
  import { DataGridFilter } from "./DataGridFilter";
19
19
  import classes from "./DataGridToolbar.module.scss";
20
- import {
21
- DataGridColumnMetadata,
22
- Filter,
23
- FiltersAction,
24
- FiltersState,
25
- FiltersTranslations
26
- } from "./DataGridFilters.interfaces";
20
+ import { DataGridColumnMetadata, Filter, FiltersTranslations } from "./DataGridFilters.interfaces";
27
21
  import { Typography } from "../../Typography/Typography";
22
+ import { useFiltersReducer } from "./useFiltersReducer";
28
23
 
29
- export interface DataGridToolbarProps extends ComponentPropsWithRef<"div"> {
24
+ export interface DataGridToolbarProps {
30
25
  columnsMetadata: DataGridColumnMetadata[];
26
+ customEditTagContent?: React.ReactElement;
31
27
  filterValues?: Filter[];
32
28
  translations?: FiltersTranslations;
33
29
  onFilterAdd?: (filter: Filter) => void;
@@ -36,71 +32,49 @@ export interface DataGridToolbarProps extends ComponentPropsWithRef<"div"> {
36
32
  onFiltersClear?: () => void;
37
33
  }
38
34
 
39
- const filtersReducer = (state: FiltersState, action: FiltersAction): FiltersState => {
40
- switch (action.type) {
41
- case "add":
42
- return { ...state, filters: [...state.filters, { ...action.payload }] };
43
- case "edit":
44
- return {
45
- ...state,
46
- filters: [
47
- ...state.filters.map(value => {
48
- if (value.id === action.payload.id) {
49
- return action.payload;
50
- }
51
- return value;
52
- })
53
- ]
54
- };
55
- case "remove":
56
- return {
57
- ...state,
58
- filters: [...state.filters.filter(value => value.id !== action.payload.id)]
59
- };
60
- case "clear":
61
- return { ...state, filters: [] };
62
- }
63
- };
64
-
65
- export const DataGridToolbarComponent: ForwardRefRenderFunction<
66
- HTMLDivElement,
67
- DataGridToolbarProps
68
- > = (
69
- {
70
- columnsMetadata,
71
- filterValues,
72
- translations,
73
- onFilterAdd,
74
- onFilterEdit,
75
- onFilterDelete,
76
- onFiltersClear,
77
- ...rest
78
- },
79
- ref
80
- ) => {
81
- const [state, dispatch] = useReducer(filtersReducer, { filters: filterValues || [] });
35
+ export const DataGridToolbar = ({
36
+ columnsMetadata,
37
+ filterValues,
38
+ translations,
39
+ onFilterAdd,
40
+ onFilterEdit,
41
+ onFilterDelete,
42
+ onFiltersClear,
43
+ customEditTagContent
44
+ }: DataGridToolbarProps) => {
45
+ const { state, addFilter, editFilter, deleteFilter, clearFilters } =
46
+ useFiltersReducer(filterValues);
82
47
  const { clearButtonCaption = "Clear all filters" } = translations?.toolbar || {};
83
48
  return (
84
- <div {...rest} ref={ref} className={classes["toolbar"]}>
49
+ <Fragment>
85
50
  {state.filters.map(filter => (
86
51
  <DataGridFilter
87
52
  mode="EDIT"
88
53
  key={filter.id}
89
54
  filter={filter}
90
55
  columnsMetadata={columnsMetadata}
91
- dispatch={dispatch}
92
- onFilterEdit={onFilterEdit}
93
- onFilterDelete={onFilterDelete}
56
+ onFilterEdit={filter => {
57
+ editFilter(filter);
58
+ onFilterEdit && onFilterEdit(filter);
59
+ }}
60
+ onFilterDelete={id => {
61
+ deleteFilter(id);
62
+ onFilterDelete && onFilterDelete(id);
63
+ }}
94
64
  tagTranslations={translations?.tag}
95
65
  popoverTranslations={translations?.popover}
66
+ customEditTagContent={customEditTagContent}
96
67
  />
97
68
  ))}
98
69
  <div className={classes["actions-wrapper"]}>
99
70
  <DataGridFilter
100
71
  mode="ADD"
72
+ customEditTagContent={customEditTagContent}
101
73
  columnsMetadata={columnsMetadata}
102
- dispatch={dispatch}
103
- onFilterAdd={onFilterAdd}
74
+ onFilterAdd={filter => {
75
+ addFilter(filter);
76
+ onFilterAdd && onFilterAdd(filter);
77
+ }}
104
78
  tagTranslations={translations?.tag}
105
79
  popoverTranslations={translations?.popover}
106
80
  />
@@ -109,7 +83,7 @@ export const DataGridToolbarComponent: ForwardRefRenderFunction<
109
83
  type="button"
110
84
  className={classes["clear-button"]}
111
85
  onClick={() => {
112
- dispatch({ type: "clear" });
86
+ clearFilters();
113
87
  onFiltersClear && onFiltersClear();
114
88
  }}
115
89
  >
@@ -119,8 +93,6 @@ export const DataGridToolbarComponent: ForwardRefRenderFunction<
119
93
  </button>
120
94
  )}
121
95
  </div>
122
- </div>
96
+ </Fragment>
123
97
  );
124
98
  };
125
-
126
- export const DataGridToolbar = React.forwardRef(DataGridToolbarComponent);
@@ -0,0 +1,38 @@
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, { ComponentPropsWithRef, ForwardRefRenderFunction, ReactElement } from "react";
18
+ import classes from "./DataGridToolbar.module.scss";
19
+ import { Button } from "../../Button/Button";
20
+ import { ButtonProps } from "../../..";
21
+ interface Props extends ComponentPropsWithRef<"div"> {
22
+ filters?: React.JSX.Element;
23
+ buttons?: ReactElement<ButtonProps, typeof Button> | ReactElement<ButtonProps, typeof Button>[];
24
+ }
25
+
26
+ export const DataGridToolbarWrapperComponent: ForwardRefRenderFunction<HTMLDivElement, Props> = (
27
+ { children, filters, buttons, ...rest },
28
+ ref
29
+ ) => {
30
+ return (
31
+ <div ref={ref} className={classes["wrapper"]} {...rest}>
32
+ <div className={classes["filter-section"]}>{filters}</div>
33
+ <div className={classes["button-section"]}>{buttons}</div>
34
+ </div>
35
+ );
36
+ };
37
+
38
+ export const DataGridToolbarWrapper = React.forwardRef(DataGridToolbarWrapperComponent);
@@ -0,0 +1,66 @@
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 { useReducer } from "react";
18
+ import { Filter, FiltersAction, FiltersState } from "./DataGridFilters.interfaces";
19
+
20
+ export const useFiltersReducer = (filterValues: Filter[] | undefined) => {
21
+ const filtersReducer = (state: FiltersState, action: FiltersAction): FiltersState => {
22
+ switch (action.type) {
23
+ case "add":
24
+ return { ...state, filters: [...state.filters, { ...action.payload }] };
25
+ case "edit":
26
+ return {
27
+ ...state,
28
+ filters: [
29
+ ...state.filters.map(value => {
30
+ if (value.id === action.payload.id) {
31
+ return action.payload;
32
+ }
33
+ return value;
34
+ })
35
+ ]
36
+ };
37
+ case "remove":
38
+ return {
39
+ ...state,
40
+ filters: [...state.filters.filter(value => value.id !== action.payload.id)]
41
+ };
42
+ case "clear":
43
+ return { ...state, filters: [] };
44
+ }
45
+ };
46
+
47
+ const [state, dispatch] = useReducer(filtersReducer, { filters: filterValues || [] });
48
+
49
+ const addFilter = (filter: Filter) =>
50
+ dispatch({
51
+ type: "add",
52
+ payload: filter
53
+ });
54
+
55
+ const editFilter = (filter: Filter) =>
56
+ dispatch({
57
+ type: "edit",
58
+ payload: filter
59
+ });
60
+
61
+ const deleteFilter = (id: string) => dispatch({ type: "remove", payload: { id } });
62
+
63
+ const clearFilters = () => dispatch({ type: "clear" });
64
+
65
+ return { state, addFilter, deleteFilter, editFilter, clearFilters };
66
+ };
@@ -62,11 +62,18 @@
62
62
 
63
63
  .indicator {
64
64
  color: var(--greyed-out);
65
+ transition: transform 0.2s ease-in-out;
66
+ transform: rotate(0deg);
65
67
 
66
- &.active {
68
+ &.ascending {
67
69
  color: var(--color-primary);
68
70
  }
69
71
 
72
+ &.descending {
73
+ color: var(--color-primary);
74
+ transform: rotate(180deg);
75
+ }
76
+
70
77
  &.hidden {
71
78
  visibility: hidden;
72
79
  }
@@ -41,21 +41,16 @@ const DataGridHeaderCellComponent: ForwardRefRenderFunction<HTMLTableCellElement
41
41
  };
42
42
 
43
43
  const sortingIndicator = () => {
44
- const getSortingIndicatorClasses = (direction: Direction) => {
44
+ const getSortingIndicatorClasses = () => {
45
45
  const sortingIndicatorClasses = [classes["indicator"]];
46
46
  activeSortDirection &&
47
47
  sortingIndicatorClasses.push(
48
- activeSortDirection === direction ? classes["active"] : classes["hidden"]
48
+ activeSortDirection === "ASC" ? classes["ascending"] : classes["descending"]
49
49
  );
50
50
  return sortingIndicatorClasses;
51
51
  };
52
52
 
53
- return (
54
- <Fragment>
55
- <Icon className={getSortingIndicatorClasses("ASC").join(" ")} icon={Icons.TriangleUp} />
56
- <Icon className={getSortingIndicatorClasses("DESC").join(" ")} icon={Icons.TriangleDown} />
57
- </Fragment>
58
- );
53
+ return <Icon className={getSortingIndicatorClasses().join(" ")} icon={Icons.ArrowUp} />;
59
54
  };
60
55
 
61
56
  const innerContent = (