@thecb/components 10.12.1 → 10.12.2-beta.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/index.cjs.js +222 -110
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.esm.js +221 -111
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/atoms/checkbox/Checkbox.js +14 -8
- package/src/components/atoms/icons/CheckboxCheckmarkIcon.js +45 -0
- package/src/components/atoms/icons/PaymentStatusIcon.d.ts +1 -0
- package/src/components/atoms/icons/PaymentStatusIcon.js +28 -0
- package/src/components/atoms/icons/PersonIcon.d.ts +1 -0
- package/src/components/atoms/icons/PersonIcon.js +28 -0
- package/src/components/atoms/icons/icons.stories.js +5 -1
- package/src/components/atoms/icons/index.js +5 -1
- package/src/components/molecules/multiple-select-filter/MultipleSelectFilter.js +22 -20
- package/src/components/molecules/multiple-select-filter/MultipleSelectFilter.stories.js +2 -4
- package/src/components/molecules/multiple-select-filter/MultipleSelectFilter.styled.js +2 -2
- package/src/components/molecules/multiple-select-filter/__private__/ActionLinkButton.js +16 -13
- package/src/components/molecules/multiple-select-filter/__private__/FilterButton.js +13 -9
- package/src/components/molecules/multiple-select-filter/__private__/FilterDropdown.js +22 -18
- package/src/components/molecules/multiple-select-filter/__private__/FilterableList.js +43 -41
- package/src/components/molecules/multiple-select-filter/__private__/FilterableListItem.js +53 -41
- package/src/components/molecules/multiple-select-filter/__private__/SearchBox.js +10 -7
- package/src/components/molecules/multiple-select-filter/index.d.ts +2 -2
package/package.json
CHANGED
|
@@ -106,6 +106,8 @@ const Checkbox = forwardRef(
|
|
|
106
106
|
labelledById,
|
|
107
107
|
dataQa = null,
|
|
108
108
|
checkboxExtraStyles,
|
|
109
|
+
hasIconOverride = false,
|
|
110
|
+
icon: Icon,
|
|
109
111
|
...rest
|
|
110
112
|
},
|
|
111
113
|
ref
|
|
@@ -164,14 +166,18 @@ const Checkbox = forwardRef(
|
|
|
164
166
|
focusedStyles={themeValues.focusedStyles}
|
|
165
167
|
checkboxExtraStyles={checkboxExtraStyles}
|
|
166
168
|
>
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
169
|
+
{hasIconOverride ? (
|
|
170
|
+
<Icon />
|
|
171
|
+
) : (
|
|
172
|
+
<CheckboxIcon
|
|
173
|
+
viewBox="0 0 24 24"
|
|
174
|
+
disabled={disabled}
|
|
175
|
+
disabledCheckColor={themeValues.disabledCheckColor}
|
|
176
|
+
checkColor={themeValues.checkColor}
|
|
177
|
+
>
|
|
178
|
+
<polyline points="20 6 9 17 4 12" />
|
|
179
|
+
</CheckboxIcon>
|
|
180
|
+
)}
|
|
175
181
|
</StyledCheckbox>
|
|
176
182
|
</CheckboxContainer>
|
|
177
183
|
{title && (
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
const CheckboxCheckmarkIcon = ({
|
|
4
|
+
width = "18",
|
|
5
|
+
height = "18",
|
|
6
|
+
color = "#FEFEFE",
|
|
7
|
+
...props
|
|
8
|
+
}) => (
|
|
9
|
+
<svg
|
|
10
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
11
|
+
width={width}
|
|
12
|
+
height={height}
|
|
13
|
+
viewBox={`0 0 ${width} ${height}`}
|
|
14
|
+
fill="none"
|
|
15
|
+
{...props}
|
|
16
|
+
>
|
|
17
|
+
<path
|
|
18
|
+
fillRule="evenodd"
|
|
19
|
+
clipRule="evenodd"
|
|
20
|
+
d="M13.7503 5.35354C13.555 5.15828 13.2385 5.15828 13.0432 5.35354L7.52373 10.873L5.52808 8.87735C5.33282 8.68209 5.01624 8.68209 4.82097 8.87735L4.35348 9.34484C4.15822 9.54011 4.15822 9.85669 4.35348 10.052L6.70268 12.4012L7.17018 12.8687C7.36544 13.0639 7.68203 13.0639 7.87729 12.8687L8.34478 12.4012L14.2178 6.52814C14.4131 6.33288 14.4131 6.0163 14.2178 5.82104L13.7503 5.35354Z"
|
|
21
|
+
fill="#FEFEFE"
|
|
22
|
+
/>
|
|
23
|
+
<mask
|
|
24
|
+
id="mask0_3361_1486"
|
|
25
|
+
style={{ maskType: "luminance" }}
|
|
26
|
+
maskUnits="userSpaceOnUse"
|
|
27
|
+
x="4"
|
|
28
|
+
y="5"
|
|
29
|
+
width="11"
|
|
30
|
+
height="9"
|
|
31
|
+
>
|
|
32
|
+
<path
|
|
33
|
+
fillRule="evenodd"
|
|
34
|
+
clipRule="evenodd"
|
|
35
|
+
d="M13.7503 5.35354C13.555 5.15828 13.2385 5.15828 13.0432 5.35354L7.52373 10.873L5.52808 8.87735C5.33282 8.68209 5.01624 8.68209 4.82097 8.87735L4.35348 9.34484C4.15822 9.54011 4.15822 9.85669 4.35348 10.052L6.70268 12.4012L7.17018 12.8687C7.36544 13.0639 7.68203 13.0639 7.87729 12.8687L8.34478 12.4012L14.2178 6.52814C14.4131 6.33288 14.4131 6.0163 14.2178 5.82104L13.7503 5.35354Z"
|
|
36
|
+
fill="white"
|
|
37
|
+
/>
|
|
38
|
+
</mask>
|
|
39
|
+
<g mask="url(#mask0_3361_1486)">
|
|
40
|
+
<rect width={width} height={height} fill={color} />
|
|
41
|
+
</g>
|
|
42
|
+
</svg>
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
export default CheckboxCheckmarkIcon;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const PaymentStatusIcon: JSX.Element;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { CHARADE_GREY } from "../../../constants/colors";
|
|
3
|
+
|
|
4
|
+
const PaymentStatusIcon = ({
|
|
5
|
+
width = "20",
|
|
6
|
+
height = "21",
|
|
7
|
+
color = CHARADE_GREY,
|
|
8
|
+
...props
|
|
9
|
+
}) => {
|
|
10
|
+
return (
|
|
11
|
+
<svg
|
|
12
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
13
|
+
width={width}
|
|
14
|
+
height={height}
|
|
15
|
+
viewBox={`0 0 ${width} ${height}`}
|
|
16
|
+
fill="none"
|
|
17
|
+
{...props}
|
|
18
|
+
>
|
|
19
|
+
<path
|
|
20
|
+
fillRule="evenodd"
|
|
21
|
+
clipRule="evenodd"
|
|
22
|
+
d="M10.875 4.375C10.875 3.89175 11.2668 3.5 11.75 3.5H16.125C16.6082 3.5 17 3.89175 17 4.375V8.75C17 9.23325 16.6082 9.625 16.125 9.625H15.25V15.75C15.25 16.7165 14.4665 17.5 13.5 17.5H4.75C3.7835 17.5 3 16.7165 3 15.75V7C3 6.0335 3.7835 5.25 4.75 5.25H10.875V4.375ZM10.875 8.75V6.5625H4.75C4.50838 6.5625 4.3125 6.75838 4.3125 7V15.75C4.3125 15.9916 4.50838 16.1875 4.75 16.1875H13.5C13.7416 16.1875 13.9375 15.9916 13.9375 15.75V9.625H11.75C11.2668 9.625 10.875 9.23325 10.875 8.75ZM13.9375 7.875C14.6624 7.875 15.25 7.28737 15.25 6.5625C15.25 5.83763 14.6624 5.25 13.9375 5.25C13.2126 5.25 12.625 5.83763 12.625 6.5625C12.625 7.28737 13.2126 7.875 13.9375 7.875Z"
|
|
23
|
+
fill={color}
|
|
24
|
+
/>
|
|
25
|
+
</svg>
|
|
26
|
+
);
|
|
27
|
+
};
|
|
28
|
+
export default PaymentStatusIcon;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const PersonIcon: JSX.Element;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { CHARADE_GREY } from "../../../constants/colors";
|
|
3
|
+
|
|
4
|
+
const PersonIcon = ({
|
|
5
|
+
width = "14",
|
|
6
|
+
height = "15",
|
|
7
|
+
color = CHARADE_GREY,
|
|
8
|
+
...props
|
|
9
|
+
}) => {
|
|
10
|
+
return (
|
|
11
|
+
<svg
|
|
12
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
13
|
+
width={width}
|
|
14
|
+
height={height}
|
|
15
|
+
viewBox={`0 0 ${width} ${height}`}
|
|
16
|
+
fill="none"
|
|
17
|
+
{...props}
|
|
18
|
+
>
|
|
19
|
+
<path
|
|
20
|
+
fillRule="evenodd"
|
|
21
|
+
clipRule="evenodd"
|
|
22
|
+
d="M12.25 1.8125H1.75C1.50838 1.8125 1.3125 2.00838 1.3125 2.25V12.75C1.3125 12.9916 1.50838 13.1875 1.75 13.1875H2.625V11.7778C2.625 9.89848 4.02411 8.375 5.75 8.375H8.25C9.97589 8.375 11.375 9.89848 11.375 11.7778V13.1875H12.25C12.4916 13.1875 12.6875 12.9916 12.6875 12.75V2.25C12.6875 2.00838 12.4916 1.8125 12.25 1.8125ZM1.75 14.5H2.625H11.375H12.25C13.2165 14.5 14 13.7165 14 12.75V2.25C14 1.2835 13.2165 0.5 12.25 0.5H1.75C0.783502 0.5 0 1.2835 0 2.25V12.75C0 13.7165 0.783502 14.5 1.75 14.5ZM7 7.5C8.20812 7.5 9.1875 6.52062 9.1875 5.3125C9.1875 4.10438 8.20812 3.125 7 3.125C5.79188 3.125 4.8125 4.10438 4.8125 5.3125C4.8125 6.52062 5.79188 7.5 7 7.5Z"
|
|
23
|
+
fill={color}
|
|
24
|
+
/>
|
|
25
|
+
</svg>
|
|
26
|
+
);
|
|
27
|
+
};
|
|
28
|
+
export default PersonIcon;
|
|
@@ -52,7 +52,9 @@ import {
|
|
|
52
52
|
DisabledPaymentMethodsAddIcon,
|
|
53
53
|
ReversalNeededIcon,
|
|
54
54
|
OverageIcon,
|
|
55
|
-
ShortageIcon
|
|
55
|
+
ShortageIcon,
|
|
56
|
+
PersonIcon,
|
|
57
|
+
PaymentStatusIcon
|
|
56
58
|
} from "./index";
|
|
57
59
|
|
|
58
60
|
const story = page({
|
|
@@ -114,3 +116,5 @@ export const successfulIcon = () => <SuccessfulIcon />;
|
|
|
114
116
|
export const trashIconV2 = () => <TrashIconV2 />;
|
|
115
117
|
export const verifiedEmailIcon = () => <VerifiedEmailIcon />;
|
|
116
118
|
export const voidedIcon = () => <VoidedIcon />;
|
|
119
|
+
export const personIcon = () => <PersonIcon />;
|
|
120
|
+
export const paymentStatusIcon = () => <PaymentStatusIcon />;
|
|
@@ -99,6 +99,8 @@ import OverageIcon from "./OverageIcon";
|
|
|
99
99
|
import ShortageIcon from "./ShortageIcon";
|
|
100
100
|
import NoResultsIcon from "./NoResultsIcon";
|
|
101
101
|
import AgencyIcon from "./AgencyIcon";
|
|
102
|
+
import PersonIcon from "./PersonIcon";
|
|
103
|
+
import PaymentStatusIcon from "./PaymentStatusIcon";
|
|
102
104
|
|
|
103
105
|
export {
|
|
104
106
|
AccountsIcon,
|
|
@@ -201,5 +203,7 @@ export {
|
|
|
201
203
|
OverageIcon,
|
|
202
204
|
ShortageIcon,
|
|
203
205
|
NoResultsIcon,
|
|
204
|
-
AgencyIcon
|
|
206
|
+
AgencyIcon,
|
|
207
|
+
PersonIcon,
|
|
208
|
+
PaymentStatusIcon
|
|
205
209
|
};
|
|
@@ -16,7 +16,9 @@ const MultipleSelectFilter = ({
|
|
|
16
16
|
actions,
|
|
17
17
|
autocompleteValue,
|
|
18
18
|
btnContentOverride,
|
|
19
|
+
btnExtraStyles,
|
|
19
20
|
disabled,
|
|
21
|
+
dropdownExtraStyles,
|
|
20
22
|
extraStyles,
|
|
21
23
|
fields,
|
|
22
24
|
filterLabel,
|
|
@@ -29,27 +31,29 @@ const MultipleSelectFilter = ({
|
|
|
29
31
|
options,
|
|
30
32
|
placeholder = "Search",
|
|
31
33
|
searchable = true,
|
|
32
|
-
selectedOptions,
|
|
33
|
-
setSelectedOptions,
|
|
34
34
|
themeValues,
|
|
35
35
|
truncateBtnTextWidth = "15rem"
|
|
36
36
|
}) => {
|
|
37
37
|
const [opened, setOpened] = useState(false);
|
|
38
|
+
const [selectedOptions, setSelectedOptions] = useState([]);
|
|
38
39
|
const [appliedOptions, setAppliedOptions] = useState([]);
|
|
40
|
+
const openedRef = useRef(opened);
|
|
39
41
|
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
const handleOnClose = () => {
|
|
43
|
+
if (openedRef.current) {
|
|
44
|
+
setOpened(false);
|
|
45
|
+
actions.fields.searchTerm.set("");
|
|
46
|
+
}
|
|
44
47
|
};
|
|
45
|
-
const containerRef = useOutsideClickHook(() =>
|
|
48
|
+
const containerRef = useOutsideClickHook(() => handleOnClose());
|
|
46
49
|
const dropdownRef = useRef(null);
|
|
47
50
|
const filterButtonRef = useRef(null);
|
|
48
51
|
const applyFilterButtonRef = useRef(null);
|
|
49
52
|
const filterDropdownID = `${name}-filter-dropdown`;
|
|
50
|
-
const
|
|
53
|
+
const listGroupID = `${name}-list-group`;
|
|
51
54
|
|
|
52
55
|
useEffect(() => {
|
|
56
|
+
openedRef.current = opened;
|
|
53
57
|
if (!opened) {
|
|
54
58
|
onApply(selectedOptions);
|
|
55
59
|
setAppliedOptions(selectedOptions);
|
|
@@ -77,9 +81,7 @@ const MultipleSelectFilter = ({
|
|
|
77
81
|
filterButtonRef.current &&
|
|
78
82
|
filterButtonRef.current.contains(event.target))
|
|
79
83
|
) {
|
|
80
|
-
|
|
81
|
-
actions.fields.searchTerm.set("");
|
|
82
|
-
onApply(selectedOptions);
|
|
84
|
+
handleOnClose();
|
|
83
85
|
}
|
|
84
86
|
};
|
|
85
87
|
document.addEventListener("keydown", handleKeyDown);
|
|
@@ -113,12 +115,15 @@ const MultipleSelectFilter = ({
|
|
|
113
115
|
truncateBtnTextWidth={truncateBtnTextWidth}
|
|
114
116
|
filterLabel={filterLabel}
|
|
115
117
|
selectedOptions={selectedOptions}
|
|
118
|
+
extraStyles={btnExtraStyles}
|
|
116
119
|
></FilterButton>
|
|
117
120
|
<FilterDropdown
|
|
118
121
|
id={filterDropdownID}
|
|
119
122
|
ref={dropdownRef}
|
|
120
|
-
ariaOwns={
|
|
123
|
+
ariaOwns={listGroupID}
|
|
124
|
+
ariaControls={listGroupID}
|
|
121
125
|
opened={opened}
|
|
126
|
+
extraStyles={dropdownExtraStyles}
|
|
122
127
|
>
|
|
123
128
|
<SearchBox
|
|
124
129
|
showSearchBox={searchable && options?.length > 8}
|
|
@@ -129,7 +134,7 @@ const MultipleSelectFilter = ({
|
|
|
129
134
|
disabled={disabled}
|
|
130
135
|
></SearchBox>
|
|
131
136
|
<FilterableList
|
|
132
|
-
id={
|
|
137
|
+
id={listGroupID}
|
|
133
138
|
options={options}
|
|
134
139
|
appliedOptions={appliedOptions}
|
|
135
140
|
themeValues={themeValues}
|
|
@@ -151,23 +156,20 @@ const MultipleSelectFilter = ({
|
|
|
151
156
|
>
|
|
152
157
|
<ActionLinkButton
|
|
153
158
|
action={() => {
|
|
154
|
-
setOpened(false);
|
|
155
159
|
setSelectedOptions([]);
|
|
156
|
-
|
|
160
|
+
handleOnClose();
|
|
157
161
|
onClear();
|
|
158
162
|
}}
|
|
159
163
|
text="Clear"
|
|
160
164
|
dataQa={`${name}-clear-filters`}
|
|
165
|
+
ariaLabel={"Clear all filters"}
|
|
161
166
|
></ActionLinkButton>
|
|
162
167
|
<ActionLinkButton
|
|
163
168
|
ref={applyFilterButtonRef}
|
|
164
|
-
action={() =>
|
|
165
|
-
setOpened(false);
|
|
166
|
-
actions.fields.searchTerm.set("");
|
|
167
|
-
onApply(selectedOptions);
|
|
168
|
-
}}
|
|
169
|
+
action={() => handleOnClose()}
|
|
169
170
|
text="Apply"
|
|
170
171
|
dataQa={`${name}-apply-filters`}
|
|
172
|
+
ariaLabel={"Apply all filters"}
|
|
171
173
|
></ActionLinkButton>
|
|
172
174
|
</Box>
|
|
173
175
|
</FilterDropdown>
|
|
@@ -41,8 +41,6 @@ const items = [
|
|
|
41
41
|
];
|
|
42
42
|
|
|
43
43
|
const FormWrapper = props => {
|
|
44
|
-
const [selectedItems, setSelectedItems] = useState([]);
|
|
45
|
-
|
|
46
44
|
return (
|
|
47
45
|
<MultipleSelectFilter
|
|
48
46
|
autocompleteValue={props.autocompleteValue}
|
|
@@ -55,8 +53,8 @@ const FormWrapper = props => {
|
|
|
55
53
|
placeholder={"Find an agency"}
|
|
56
54
|
fields={props.fields}
|
|
57
55
|
actions={props.actions}
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
btnExtraStyles={props.btnExtraStyles}
|
|
57
|
+
dropdownExtraStyles={props.dropdownExtraStyles}
|
|
60
58
|
/>
|
|
61
59
|
);
|
|
62
60
|
};
|
|
@@ -5,9 +5,9 @@ import ButtonWithAction from "../../atoms/button-with-action";
|
|
|
5
5
|
|
|
6
6
|
const StyledFilterContainer = styled(Box)`
|
|
7
7
|
position: relative;
|
|
8
|
+
overflow: visible;
|
|
8
9
|
box-sizing: border-box;
|
|
9
10
|
padding: 0;
|
|
10
|
-
${({ extraStyles }) => extraStyles}
|
|
11
11
|
`;
|
|
12
12
|
|
|
13
13
|
export const FilterContainer = forwardRef((props, ref) => (
|
|
@@ -18,7 +18,7 @@ const StyledFilterDropdown = styled(Box)`
|
|
|
18
18
|
position: absolute;
|
|
19
19
|
top: calc(100% + 0.5rem);
|
|
20
20
|
left: 0;
|
|
21
|
-
width:
|
|
21
|
+
width: 18.4rem;
|
|
22
22
|
background-color: white;
|
|
23
23
|
z-index: 1000;
|
|
24
24
|
border-radius: 0.25rem;
|
|
@@ -2,23 +2,26 @@ import React, { forwardRef } from "react";
|
|
|
2
2
|
import { ButtonWithAction } from "../../../atoms";
|
|
3
3
|
import { FONT_WEIGHT_REGULAR } from "../../../../constants/style_constants";
|
|
4
4
|
|
|
5
|
-
const ActionLinkButton = forwardRef(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
const ActionLinkButton = forwardRef(
|
|
6
|
+
({ action, text, dataQa, ariaLabel }, ref) => {
|
|
7
|
+
return (
|
|
8
|
+
<ButtonWithAction
|
|
9
|
+
ref={ref}
|
|
10
|
+
action={action}
|
|
11
|
+
variant="tertiary"
|
|
12
|
+
extraStyles={`
|
|
12
13
|
padding: 0.2rem;
|
|
13
14
|
margin: 0.5rem;
|
|
14
15
|
min-height: auto;
|
|
15
16
|
min-width: auto;
|
|
16
17
|
`}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
textExtraStyles={`font-weight: ${FONT_WEIGHT_REGULAR};`}
|
|
19
|
+
text={text}
|
|
20
|
+
dataQa={dataQa}
|
|
21
|
+
aria-label={ariaLabel}
|
|
22
|
+
></ButtonWithAction>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
);
|
|
23
26
|
|
|
24
27
|
export default ActionLinkButton;
|
|
@@ -18,10 +18,18 @@ const FilterButton = forwardRef(
|
|
|
18
18
|
icon: Icon,
|
|
19
19
|
truncateBtnTextWidth,
|
|
20
20
|
filterLabel,
|
|
21
|
-
selectedOptions
|
|
21
|
+
selectedOptions,
|
|
22
|
+
extraStyles
|
|
22
23
|
},
|
|
23
24
|
ref
|
|
24
25
|
) => {
|
|
26
|
+
const btnTextFilterDescription = selectedOptions?.length
|
|
27
|
+
? `${filterLabel ? `${filterLabel}: ` : ""}${selectedOptions[0].name}`
|
|
28
|
+
: `${filterLabel ? filterLabel : ""}`;
|
|
29
|
+
const btnTextItemsDescription =
|
|
30
|
+
selectedOptions?.length && selectedOptions?.length > 1
|
|
31
|
+
? `, +${selectedOptions?.length - 1} More`
|
|
32
|
+
: "";
|
|
25
33
|
return (
|
|
26
34
|
<StyledFilterButton
|
|
27
35
|
ref={ref}
|
|
@@ -32,6 +40,8 @@ const FilterButton = forwardRef(
|
|
|
32
40
|
aria-controls={filterDropdownID}
|
|
33
41
|
backgroundColor={backgroundColor}
|
|
34
42
|
dataQa={`${name}-filter-button`}
|
|
43
|
+
extraStyles={extraStyles}
|
|
44
|
+
aria-label={`${filterLabel} Filter: ${btnTextFilterDescription} ${btnTextItemsDescription}`}
|
|
35
45
|
contentOverride
|
|
36
46
|
>
|
|
37
47
|
{btnContentOverride ? (
|
|
@@ -62,16 +72,10 @@ const FilterButton = forwardRef(
|
|
|
62
72
|
${truncateBtnTextWidth && `max-width:` + truncateBtnTextWidth}
|
|
63
73
|
`}
|
|
64
74
|
>
|
|
65
|
-
{
|
|
66
|
-
? `${filterLabel ? filterLabel + ": " : ""}${
|
|
67
|
-
selectedOptions[0].name
|
|
68
|
-
}`
|
|
69
|
-
: `${filterLabel ? filterLabel : ""}`}
|
|
75
|
+
{btnTextFilterDescription}
|
|
70
76
|
</Text>
|
|
71
77
|
<Text color={contentColor} variant="pS">
|
|
72
|
-
{
|
|
73
|
-
? `, +${selectedOptions?.length - 1} More`
|
|
74
|
-
: ""}
|
|
78
|
+
{btnTextItemsDescription}
|
|
75
79
|
</Text>
|
|
76
80
|
</Center>
|
|
77
81
|
<DropdownIconV2 color={contentColor} />
|
|
@@ -1,23 +1,27 @@
|
|
|
1
1
|
import React, { forwardRef } from "react";
|
|
2
2
|
import { FilterDropdownContainer } from "../MultipleSelectFilter.styled";
|
|
3
3
|
|
|
4
|
-
const FilterDropdown = forwardRef(
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
4
|
+
const FilterDropdown = forwardRef(
|
|
5
|
+
({ id, ariaOwns, ariaControls, opened, extraStyles, children }, ref) => {
|
|
6
|
+
return (
|
|
7
|
+
<>
|
|
8
|
+
{opened && (
|
|
9
|
+
<FilterDropdownContainer
|
|
10
|
+
ref={ref}
|
|
11
|
+
id={id}
|
|
12
|
+
role="combobox"
|
|
13
|
+
aria-expanded={opened}
|
|
14
|
+
aria-haspopup="listbox"
|
|
15
|
+
aria-owns={ariaOwns}
|
|
16
|
+
aria-controls={ariaControls}
|
|
17
|
+
extraStyles={extraStyles}
|
|
18
|
+
>
|
|
19
|
+
{children}
|
|
20
|
+
</FilterDropdownContainer>
|
|
21
|
+
)}
|
|
22
|
+
</>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
);
|
|
22
26
|
|
|
23
27
|
export default FilterDropdown;
|
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
isChecked,
|
|
10
10
|
isMaxSelectionReached
|
|
11
11
|
} from "./util";
|
|
12
|
-
import { GHOST_GREY } from "../../../../constants/colors";
|
|
13
12
|
|
|
14
13
|
const FilterableList = ({
|
|
15
14
|
id,
|
|
@@ -68,23 +67,20 @@ const FilterableList = ({
|
|
|
68
67
|
return (
|
|
69
68
|
<Box
|
|
70
69
|
id={id}
|
|
71
|
-
role="listbox"
|
|
72
70
|
padding="0"
|
|
71
|
+
role="listbox"
|
|
72
|
+
aria-label="Filter options container"
|
|
73
|
+
onKeyDown={handleKeyDown}
|
|
73
74
|
extraStyles={`
|
|
74
75
|
overflow-y: auto;
|
|
75
76
|
max-height: 250px;
|
|
76
77
|
display: flex;
|
|
77
78
|
flex-flow: column;
|
|
78
|
-
|
|
79
|
-
|
|
79
|
+
padding-bottom: 0.5rem;
|
|
80
|
+
`}
|
|
80
81
|
>
|
|
81
82
|
{sortedAppliedOptions?.length > 0 && (
|
|
82
|
-
|
|
83
|
-
padding="0"
|
|
84
|
-
extraStyles={
|
|
85
|
-
sortedOptions.length > 0 && `border-bottom: 1px solid ${GHOST_GREY}`
|
|
86
|
-
}
|
|
87
|
-
>
|
|
83
|
+
<>
|
|
88
84
|
{sortedAppliedOptions.map((option, index) => {
|
|
89
85
|
const checked = isChecked(option, selectedOptions);
|
|
90
86
|
const tabIndex =
|
|
@@ -102,41 +98,47 @@ const FilterableList = ({
|
|
|
102
98
|
tabIndex={tabIndex}
|
|
103
99
|
name={name}
|
|
104
100
|
themeValues={themeValues}
|
|
101
|
+
showDivider={
|
|
102
|
+
sortedOptions.length > 0 &&
|
|
103
|
+
index === sortedAppliedOptions.length - 1
|
|
104
|
+
}
|
|
105
105
|
></FilterableListItem>
|
|
106
106
|
);
|
|
107
107
|
})}
|
|
108
|
-
|
|
108
|
+
</>
|
|
109
109
|
)}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
110
|
+
<>
|
|
111
|
+
{sortedOptions.map((option, index) => {
|
|
112
|
+
const checked = isChecked(option, selectedOptions);
|
|
113
|
+
const isDisabled =
|
|
114
|
+
isMaxSelectionReached(maxSelections, selectedOptions) && !checked;
|
|
115
|
+
const indexOffset = sortedAppliedOptions?.length
|
|
116
|
+
? sortedAppliedOptions?.length
|
|
117
|
+
: 0;
|
|
118
|
+
const currentIndex = index === 0 ? indexOffset : index + indexOffset;
|
|
119
|
+
const tabIndex =
|
|
120
|
+
currentIndex === focusedIndex ||
|
|
121
|
+
(indexOffset === 0 &&
|
|
122
|
+
currentIndex === indexOffset &&
|
|
123
|
+
focusedIndex === -1)
|
|
124
|
+
? "0"
|
|
125
|
+
: "-1";
|
|
126
|
+
return (
|
|
127
|
+
<FilterableListItem
|
|
128
|
+
key={currentIndex}
|
|
129
|
+
ref={el => (itemRefs.current[currentIndex] = el)}
|
|
130
|
+
index={currentIndex}
|
|
131
|
+
option={option}
|
|
132
|
+
checked={checked}
|
|
133
|
+
selectOption={isDisabled ? noop : handleSelectOption}
|
|
134
|
+
disabled={isDisabled}
|
|
135
|
+
tabIndex={tabIndex}
|
|
136
|
+
name={name}
|
|
137
|
+
themeValues={themeValues}
|
|
138
|
+
></FilterableListItem>
|
|
139
|
+
);
|
|
140
|
+
})}
|
|
141
|
+
</>
|
|
140
142
|
</Box>
|
|
141
143
|
);
|
|
142
144
|
};
|