@bitrise/bitkit 13.318.0 → 13.320.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/package.json +19 -19
- package/src/Components/DatePicker/DatePicker.tsx +59 -54
- package/src/Components/Dialog/DialogProps.ts +1 -2
- package/src/Components/Drawer/Drawer.tsx +23 -7
- package/src/Components/ExpandableCard/ExpandableCard.tsx +23 -24
- package/src/Components/Filter/Desktop/Filter.tsx +92 -0
- package/src/Components/Filter/Desktop/FilterAdd/FilterAdd.tsx +89 -0
- package/src/Components/Filter/{FilterDate → Desktop/FilterDate}/FilterDate.tsx +21 -10
- package/src/Components/Filter/{FilterForm → Desktop}/FilterForm.tsx +24 -115
- package/src/Components/Filter/{FilterItem → Desktop}/FilterItem.tsx +1 -1
- package/src/Components/Filter/{FilterSwitch → Desktop/FilterSwitch}/FilterSwitch.theme.ts +1 -1
- package/src/Components/Filter/{FilterSwitch → Desktop/FilterSwitch}/FilterSwitch.tsx +4 -4
- package/src/Components/Filter/{FilterSwitchAdapter → Desktop/FilterSwitch}/FilterSwitchAdapter.tsx +5 -5
- package/src/Components/Filter/Filter.storyData.ts +14 -1
- package/src/Components/Filter/Filter.tsx +16 -106
- package/src/Components/Filter/Filter.types.ts +34 -1
- package/src/Components/Filter/Filter.utils.ts +13 -0
- package/src/Components/Filter/Mobile/DateSelectOption.tsx +53 -0
- package/src/Components/Filter/Mobile/Filter.tsx +57 -0
- package/src/Components/Filter/Mobile/FilterAdd.tsx +97 -0
- package/src/Components/Filter/Mobile/FilterDrawer.tsx +96 -0
- package/src/Components/Filter/Mobile/FilterForm.tsx +236 -0
- package/src/Components/Filter/Mobile/FilterItem.tsx +95 -0
- package/src/Components/Filter/Mobile/MultiSelectOptions.tsx +69 -0
- package/src/Components/Filter/Mobile/SingleSelectOptions.tsx +136 -0
- package/src/Components/Filter/hooks/useFilterAdd.ts +68 -0
- package/src/Components/Filter/hooks/useFilterForm.ts +131 -0
- package/src/Components/Filter/hooks/useIsScrollable.ts +35 -0
- package/src/Components/Filter/hooks/useListBox.ts +66 -0
- package/src/Components/Form/Checkbox/Checkbox.tsx +4 -2
- package/src/Components/Form/Input/Input.theme.ts +27 -11
- package/src/Components/Form/Input/Input.tsx +4 -1
- package/src/Components/Form/Radio/Radio.tsx +4 -2
- package/src/Components/SearchInput/SearchInput.tsx +3 -2
- package/src/Components/components.theme.ts +1 -1
- package/src/index.ts +3 -4
- package/src/Components/Filter/FilterAdd/FilterAdd.tsx +0 -111
- /package/src/Components/Filter/{FilterSearch → Desktop}/FilterSearch.tsx +0 -0
- /package/src/Components/Filter/{FilterSwitch → Desktop/FilterSwitch}/FilterSwitchGroup.tsx +0 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bitrise/bitkit",
|
|
3
3
|
"description": "Bitrise React component library",
|
|
4
|
-
"version": "13.
|
|
4
|
+
"version": "13.320.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+ssh://git@github.com/bitrise-io/bitkit.git"
|
|
@@ -38,11 +38,11 @@
|
|
|
38
38
|
"chakra-ui-2--theme": "npm:@chakra-ui/theme@3.4.9",
|
|
39
39
|
"chakra-ui-2--theme-tools": "npm:@chakra-ui/theme-tools@2.2.9",
|
|
40
40
|
"clsx": "^2.1.1",
|
|
41
|
-
"framer-motion": "^12.23.
|
|
41
|
+
"framer-motion": "^12.23.24",
|
|
42
42
|
"luxon": "^3.7.2",
|
|
43
43
|
"react": "^18.3.1",
|
|
44
44
|
"react-dom": "^18.3.1",
|
|
45
|
-
"react-focus-lock": "2.13.
|
|
45
|
+
"react-focus-lock": "2.13.7",
|
|
46
46
|
"react-imask": "^7.6.1",
|
|
47
47
|
"react-markdown": "^10.1.0"
|
|
48
48
|
},
|
|
@@ -51,39 +51,39 @@
|
|
|
51
51
|
"react-dom": "^18.2.0"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
|
-
"@babel/core": "^7.28.
|
|
55
|
-
"@babel/preset-env": "^7.28.
|
|
56
|
-
"@babel/preset-react": "^7.
|
|
57
|
-
"@babel/preset-typescript": "^7.
|
|
54
|
+
"@babel/core": "^7.28.5",
|
|
55
|
+
"@babel/preset-env": "^7.28.5",
|
|
56
|
+
"@babel/preset-react": "^7.28.5",
|
|
57
|
+
"@babel/preset-typescript": "^7.28.5",
|
|
58
58
|
"@bitrise/eslint-plugin": "^2.12.0",
|
|
59
|
-
"@google-cloud/storage": "^7.17.
|
|
60
|
-
"@storybook/addon-docs": "^9.1.
|
|
61
|
-
"@storybook/addon-links": "^9.1.
|
|
59
|
+
"@google-cloud/storage": "^7.17.3",
|
|
60
|
+
"@storybook/addon-docs": "^9.1.16",
|
|
61
|
+
"@storybook/addon-links": "^9.1.16",
|
|
62
62
|
"@storybook/addon-webpack5-compiler-swc": "^3.0.0",
|
|
63
|
-
"@storybook/react-webpack5": "^9.1.
|
|
63
|
+
"@storybook/react-webpack5": "^9.1.16",
|
|
64
64
|
"@testing-library/dom": "^10.4.1",
|
|
65
65
|
"@testing-library/jest-dom": "6.9.1",
|
|
66
66
|
"@testing-library/react": "16.3.0",
|
|
67
67
|
"@testing-library/user-event": "^14.6.1",
|
|
68
68
|
"@types/jest": "^29.5.14",
|
|
69
69
|
"@types/luxon": "^3.7.1",
|
|
70
|
-
"@types/react": "^18.3.
|
|
70
|
+
"@types/react": "^18.3.27",
|
|
71
71
|
"@types/react-dom": "^18.3.7",
|
|
72
72
|
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
|
73
73
|
"@typescript-eslint/parser": "^7.18.0",
|
|
74
|
-
"axios": "^1.
|
|
74
|
+
"axios": "^1.13.2",
|
|
75
75
|
"chakra-ui-2--cli": "npm:@chakra-ui/cli@2.5.8",
|
|
76
76
|
"eslint": "^8.57.1",
|
|
77
|
-
"glob": "^11.0
|
|
77
|
+
"glob": "^11.1.0",
|
|
78
78
|
"jest": "^29.7.0",
|
|
79
79
|
"jest-environment-jsdom": "^29.7.0",
|
|
80
80
|
"jsdom": "26.1.0",
|
|
81
81
|
"lodash": "^4.17.21",
|
|
82
|
-
"prettier": "^3.
|
|
83
|
-
"react-hook-form": "^7.
|
|
84
|
-
"release-it": "^19.0.
|
|
85
|
-
"storybook": "^9.1.
|
|
86
|
-
"ts-jest": "^29.4.
|
|
82
|
+
"prettier": "^3.7.3",
|
|
83
|
+
"react-hook-form": "^7.67.0",
|
|
84
|
+
"release-it": "^19.0.6",
|
|
85
|
+
"storybook": "^9.1.16",
|
|
86
|
+
"ts-jest": "^29.4.5",
|
|
87
87
|
"typescript": "^5.9.3"
|
|
88
88
|
},
|
|
89
89
|
"files": [
|
|
@@ -19,13 +19,13 @@ import { DatePickerDayViewProps } from './DatePickerDay';
|
|
|
19
19
|
export { useDateRange, DateRange };
|
|
20
20
|
|
|
21
21
|
export type DatePickerProps = {
|
|
22
|
-
children
|
|
22
|
+
children?: React.ReactNode;
|
|
23
|
+
onClose?: () => void;
|
|
23
24
|
dayTooltip?: DatePickerDayViewProps['tooltip'];
|
|
24
25
|
selectable?: DateRange;
|
|
25
|
-
onClose: () => void;
|
|
26
26
|
onClear?: () => void;
|
|
27
27
|
visible: boolean;
|
|
28
|
-
variant?: 'default' | 'filter';
|
|
28
|
+
variant?: 'default' | 'filter' | 'inline';
|
|
29
29
|
} & (
|
|
30
30
|
| {
|
|
31
31
|
selected?: DateRange;
|
|
@@ -88,7 +88,7 @@ const DatePicker = (props: DatePickerProps) => {
|
|
|
88
88
|
}, [initialRange]);
|
|
89
89
|
|
|
90
90
|
const handleClose = () => {
|
|
91
|
-
onClose();
|
|
91
|
+
onClose?.();
|
|
92
92
|
setDateTo(undefined);
|
|
93
93
|
setDateFrom(undefined);
|
|
94
94
|
};
|
|
@@ -158,7 +158,7 @@ const DatePicker = (props: DatePickerProps) => {
|
|
|
158
158
|
setDateFrom(dateFromNew);
|
|
159
159
|
setDateTo(dateToNew);
|
|
160
160
|
|
|
161
|
-
if (variant === 'default') {
|
|
161
|
+
if (variant === 'default' || variant === 'inline') {
|
|
162
162
|
if (!dateFromNew || previewNew) {
|
|
163
163
|
return;
|
|
164
164
|
}
|
|
@@ -200,58 +200,63 @@ const DatePicker = (props: DatePickerProps) => {
|
|
|
200
200
|
[isMonthSelector],
|
|
201
201
|
);
|
|
202
202
|
|
|
203
|
-
|
|
204
|
-
<
|
|
205
|
-
<
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
onMonthClick={onMonthClickLeft}
|
|
221
|
-
onViewDateChange={updateLeftViewDate}
|
|
222
|
-
viewDate={leftViewDate}
|
|
223
|
-
/>
|
|
203
|
+
const datePicker = (
|
|
204
|
+
<DatePickerContext value={ctx}>
|
|
205
|
+
<Box padding={variant === 'inline' ? '0' : '24'}>
|
|
206
|
+
{isMonthSelector ? (
|
|
207
|
+
<DatePickerMonthSelector
|
|
208
|
+
onMonthSelected={onMonthSelected}
|
|
209
|
+
viewDate={isMonthSelector === 'left' ? leftViewDate : rightViewDate}
|
|
210
|
+
/>
|
|
211
|
+
) : (
|
|
212
|
+
<>
|
|
213
|
+
<Box display="flex" gap="32" marginBottom="24">
|
|
214
|
+
<DatePickerMonth
|
|
215
|
+
controls={isSingleMonthView ? 'both' : 'left'}
|
|
216
|
+
onMonthClick={onMonthClickLeft}
|
|
217
|
+
onViewDateChange={updateLeftViewDate}
|
|
218
|
+
viewDate={leftViewDate}
|
|
219
|
+
/>
|
|
224
220
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
)}
|
|
233
|
-
</Box>
|
|
234
|
-
{variant === 'filter' && (
|
|
235
|
-
<DatePickerFooter
|
|
236
|
-
mode={mode || 'range'}
|
|
237
|
-
onApply={() => handleApply(dateFrom, dateTo)}
|
|
238
|
-
onClear={onClear}
|
|
239
|
-
onClose={handleClose}
|
|
240
|
-
selected={currentSelected}
|
|
241
|
-
/>
|
|
242
|
-
)}
|
|
243
|
-
{variant === 'default' && mode === 'day' && (
|
|
244
|
-
<Box display="flex" justifyContent="space-around">
|
|
245
|
-
<Button onClick={() => handleSelect(DateTime.now())} variant="tertiary">
|
|
246
|
-
Today
|
|
247
|
-
</Button>
|
|
248
|
-
</Box>
|
|
249
|
-
)}
|
|
250
|
-
</>
|
|
221
|
+
{!isSingleMonthView && (
|
|
222
|
+
<DatePickerMonth
|
|
223
|
+
controls="right"
|
|
224
|
+
onMonthClick={onMonthClickRight}
|
|
225
|
+
onViewDateChange={updateRightViewDate}
|
|
226
|
+
viewDate={rightViewDate}
|
|
227
|
+
/>
|
|
251
228
|
)}
|
|
252
229
|
</Box>
|
|
253
|
-
|
|
254
|
-
|
|
230
|
+
{variant === 'filter' && (
|
|
231
|
+
<DatePickerFooter
|
|
232
|
+
mode={mode || 'range'}
|
|
233
|
+
onApply={() => handleApply(dateFrom, dateTo)}
|
|
234
|
+
onClear={onClear}
|
|
235
|
+
onClose={handleClose}
|
|
236
|
+
selected={currentSelected}
|
|
237
|
+
/>
|
|
238
|
+
)}
|
|
239
|
+
{variant === 'default' && mode === 'day' && (
|
|
240
|
+
<Box display="flex" justifyContent="space-around">
|
|
241
|
+
<Button onClick={() => handleSelect(DateTime.now())} variant="tertiary">
|
|
242
|
+
Today
|
|
243
|
+
</Button>
|
|
244
|
+
</Box>
|
|
245
|
+
)}
|
|
246
|
+
</>
|
|
247
|
+
)}
|
|
248
|
+
</Box>
|
|
249
|
+
</DatePickerContext>
|
|
250
|
+
);
|
|
251
|
+
|
|
252
|
+
return variant === 'inline' ? (
|
|
253
|
+
datePicker
|
|
254
|
+
) : (
|
|
255
|
+
<Popover isLazy isOpen={visible} lazyBehavior="unmount" modifiers={[]} onClose={onClose}>
|
|
256
|
+
<PopoverAnchor>{children}</PopoverAnchor>
|
|
257
|
+
<PopoverContent aria-label="select date range">
|
|
258
|
+
<FocusLock returnFocus />
|
|
259
|
+
{datePicker}
|
|
255
260
|
</PopoverContent>
|
|
256
261
|
</Popover>
|
|
257
262
|
);
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { HTMLChakraProps, ModalProps } from 'chakra-ui-2--react';
|
|
2
2
|
|
|
3
3
|
export interface DialogProps
|
|
4
|
-
extends Omit<HTMLChakraProps<'section'>, 'scrollBehavior'>,
|
|
5
|
-
Pick<ModalProps, 'returnFocusOnClose'> {
|
|
4
|
+
extends Omit<HTMLChakraProps<'section'>, 'scrollBehavior'>, Pick<ModalProps, 'returnFocusOnClose'> {
|
|
6
5
|
isClosable?: boolean;
|
|
7
6
|
isOpen: boolean;
|
|
8
7
|
onClose(): void;
|
|
@@ -17,8 +17,12 @@ import {
|
|
|
17
17
|
} from 'chakra-ui-2--react';
|
|
18
18
|
import Icon from '../Icon/Icon';
|
|
19
19
|
|
|
20
|
-
export interface DrawerProps
|
|
21
|
-
|
|
20
|
+
export interface DrawerProps extends Pick<
|
|
21
|
+
ChakraDrawerProps,
|
|
22
|
+
'finalFocusRef' | 'initialFocusRef' | 'isOpen' | 'onClose' | 'onCloseComplete'
|
|
23
|
+
> {
|
|
24
|
+
blockScrollOnMount?: boolean;
|
|
25
|
+
bodyRef?: React.RefObject<HTMLDivElement>;
|
|
22
26
|
children: DrawerContentProps['children'];
|
|
23
27
|
footer?: ReactNode;
|
|
24
28
|
maxWidth?: BoxProps['maxWidth'];
|
|
@@ -26,6 +30,7 @@ export interface DrawerProps
|
|
|
26
30
|
padding?: BoxProps['padding'];
|
|
27
31
|
margin?: BoxProps['margin'];
|
|
28
32
|
headerPadding?: BoxProps['padding'];
|
|
33
|
+
hideCloseButton?: boolean;
|
|
29
34
|
bodyPadding?: BoxProps['padding'];
|
|
30
35
|
overlayProps?: ModalOverlayProps;
|
|
31
36
|
contentProps?: DrawerContentProps;
|
|
@@ -34,12 +39,21 @@ export interface DrawerProps
|
|
|
34
39
|
footerProps?: ModalFooterProps;
|
|
35
40
|
}
|
|
36
41
|
|
|
37
|
-
const Drawer = ({
|
|
42
|
+
const Drawer = ({
|
|
43
|
+
bodyRef,
|
|
44
|
+
overlayProps,
|
|
45
|
+
contentProps,
|
|
46
|
+
headerProps,
|
|
47
|
+
bodyProps,
|
|
48
|
+
footerProps,
|
|
49
|
+
...props
|
|
50
|
+
}: DrawerProps) => {
|
|
38
51
|
const {
|
|
39
52
|
bodyPadding,
|
|
40
53
|
children,
|
|
41
54
|
footer,
|
|
42
55
|
headerPadding,
|
|
56
|
+
hideCloseButton,
|
|
43
57
|
maxWidth = '20rem',
|
|
44
58
|
padding,
|
|
45
59
|
margin,
|
|
@@ -51,13 +65,15 @@ const Drawer = ({ overlayProps, contentProps, headerProps, bodyProps, footerProp
|
|
|
51
65
|
<ChakraDrawer {...drawerProps}>
|
|
52
66
|
<DrawerOverlay {...overlayProps} />
|
|
53
67
|
<DrawerContent maxWidth={maxWidth} padding={padding} margin={margin} {...contentProps}>
|
|
54
|
-
|
|
55
|
-
<
|
|
56
|
-
|
|
68
|
+
{!hideCloseButton && (
|
|
69
|
+
<DrawerCloseButton size="md">
|
|
70
|
+
<Icon name="Cross" />
|
|
71
|
+
</DrawerCloseButton>
|
|
72
|
+
)}
|
|
57
73
|
<DrawerHeader as="h3" padding={headerPadding} {...headerProps}>
|
|
58
74
|
{title}
|
|
59
75
|
</DrawerHeader>
|
|
60
|
-
<DrawerBody padding={bodyPadding} {...bodyProps}>
|
|
76
|
+
<DrawerBody padding={bodyPadding} {...bodyProps} ref={bodyRef}>
|
|
61
77
|
{children}
|
|
62
78
|
</DrawerBody>
|
|
63
79
|
{footer && <DrawerFooter {...footerProps}>{footer}</DrawerFooter>}
|
|
@@ -5,30 +5,29 @@ import Collapse from '../Collapse/Collapse';
|
|
|
5
5
|
import Card, { CardProps } from '../Card/Card';
|
|
6
6
|
import Icon from '../Icon/Icon';
|
|
7
7
|
|
|
8
|
-
export interface ExpandableCardProps
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
> {
|
|
8
|
+
export interface ExpandableCardProps extends Omit<
|
|
9
|
+
CardProps,
|
|
10
|
+
| 'p'
|
|
11
|
+
| 'pt'
|
|
12
|
+
| 'paddingTop'
|
|
13
|
+
| 'pr'
|
|
14
|
+
| 'paddingRight'
|
|
15
|
+
| 'pe'
|
|
16
|
+
| 'paddingEnd'
|
|
17
|
+
| 'pb'
|
|
18
|
+
| 'paddingBottom'
|
|
19
|
+
| 'pl'
|
|
20
|
+
| 'paddingLeft'
|
|
21
|
+
| 'ps'
|
|
22
|
+
| 'paddingStart'
|
|
23
|
+
| 'px'
|
|
24
|
+
| 'paddingX'
|
|
25
|
+
| 'py'
|
|
26
|
+
| 'paddingY'
|
|
27
|
+
| 'paddingInlineStart'
|
|
28
|
+
| 'paddingInlineEnd'
|
|
29
|
+
| 'onChange'
|
|
30
|
+
> {
|
|
32
31
|
buttonContent: ReactNode;
|
|
33
32
|
buttonPadding?: BoxProps['padding'];
|
|
34
33
|
isExpanded?: boolean;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { Modal, ModalOverlay, useMultiStyleConfig } from 'chakra-ui-2--react';
|
|
2
|
+
import Box from '../../Box/Box';
|
|
3
|
+
import Icon from '../../Icon/Icon';
|
|
4
|
+
import Button from '../../Button/Button';
|
|
5
|
+
import Divider from '../../Divider/Divider';
|
|
6
|
+
import { FilterProps } from '../Filter.types';
|
|
7
|
+
import { useFilterContext } from '../Filter.context';
|
|
8
|
+
import FilterAdd from './FilterAdd/FilterAdd';
|
|
9
|
+
import FilterDate from './FilterDate/FilterDate';
|
|
10
|
+
import FilterItem from './FilterItem';
|
|
11
|
+
import FilterSearch from './FilterSearch';
|
|
12
|
+
import FilterSwitchAdapter from './FilterSwitch/FilterSwitchAdapter';
|
|
13
|
+
|
|
14
|
+
const Filter = (props: FilterProps) => {
|
|
15
|
+
const {
|
|
16
|
+
data,
|
|
17
|
+
defaultState,
|
|
18
|
+
filtersDependOn,
|
|
19
|
+
isLoading,
|
|
20
|
+
isMobile,
|
|
21
|
+
onChange,
|
|
22
|
+
searchTooltip,
|
|
23
|
+
showAdd = true,
|
|
24
|
+
showFilterIcon = true,
|
|
25
|
+
showClearFilters = true,
|
|
26
|
+
showSearch,
|
|
27
|
+
...rest
|
|
28
|
+
} = props;
|
|
29
|
+
|
|
30
|
+
const filterStyle = useMultiStyleConfig('Filter');
|
|
31
|
+
|
|
32
|
+
const { filters, isPopoverOpen, onClearFilters, onFilterChange, showClearButton, state } = useFilterContext();
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<Box sx={filterStyle.container} {...rest}>
|
|
36
|
+
<Modal isOpen={isPopoverOpen} onClose={() => {}}>
|
|
37
|
+
{isPopoverOpen && <ModalOverlay />}
|
|
38
|
+
</Modal>
|
|
39
|
+
<Box sx={filterStyle.content}>
|
|
40
|
+
{showFilterIcon && <Icon name="Filter" sx={filterStyle.icon} />}
|
|
41
|
+
|
|
42
|
+
{Object.keys(filters.switch).map((category) => (
|
|
43
|
+
<FilterSwitchAdapter key={category} category={category} />
|
|
44
|
+
))}
|
|
45
|
+
|
|
46
|
+
{Object.keys(filters.dateRange).map((category) => (
|
|
47
|
+
<FilterDate category={category} isMobile={Boolean(isMobile)} key={category} />
|
|
48
|
+
))}
|
|
49
|
+
|
|
50
|
+
{Object.keys(filters.select).map((category) => (
|
|
51
|
+
<FilterItem key={category} category={category} />
|
|
52
|
+
))}
|
|
53
|
+
{Object.keys(filters.tag).map((category) => {
|
|
54
|
+
if (!state[category]) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
return <FilterItem key={category} category={category} />;
|
|
58
|
+
})}
|
|
59
|
+
|
|
60
|
+
{showAdd && <FilterAdd />}
|
|
61
|
+
</Box>
|
|
62
|
+
{(showClearButton || showSearch) && (
|
|
63
|
+
<Box sx={filterStyle.rightContent}>
|
|
64
|
+
{showClearButton && (
|
|
65
|
+
<Button
|
|
66
|
+
isDisabled={isLoading}
|
|
67
|
+
leftIconName="Cross"
|
|
68
|
+
minWidth="7.5rem"
|
|
69
|
+
onClick={onClearFilters}
|
|
70
|
+
size="sm"
|
|
71
|
+
variant="tertiary"
|
|
72
|
+
>
|
|
73
|
+
Clear filters
|
|
74
|
+
</Button>
|
|
75
|
+
)}
|
|
76
|
+
{showSearch && (
|
|
77
|
+
<>
|
|
78
|
+
<Divider flexShrink="0" orientation="vertical" size="1" variant="solid" />
|
|
79
|
+
<FilterSearch
|
|
80
|
+
onChange={onFilterChange}
|
|
81
|
+
value={state.search?.length ? state.search[0] : ''}
|
|
82
|
+
searchTooltip={searchTooltip}
|
|
83
|
+
/>
|
|
84
|
+
</>
|
|
85
|
+
)}
|
|
86
|
+
</Box>
|
|
87
|
+
)}
|
|
88
|
+
</Box>
|
|
89
|
+
);
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export default Filter;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { Menu, MenuButton, MenuList, Portal } from 'chakra-ui-2--react';
|
|
2
|
+
import Button from '../../../Button/Button';
|
|
3
|
+
import MenuItem from '../../../Menu/MenuItem';
|
|
4
|
+
import Tooltip from '../../../Tooltip/Tooltip';
|
|
5
|
+
import { useFilterContext } from '../../Filter.context';
|
|
6
|
+
import FilterForm from '../FilterForm';
|
|
7
|
+
import { FilterValue } from '../../Filter.types';
|
|
8
|
+
import { getMissingDependencies } from '../../Filter.utils';
|
|
9
|
+
import useFilterAdd from '../../hooks/useFilterAdd';
|
|
10
|
+
|
|
11
|
+
export interface FilterAddProps {
|
|
12
|
+
onChange: (category: string, selected: FilterValue) => void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const FilterAdd = () => {
|
|
16
|
+
const { data, isLoading } = useFilterContext();
|
|
17
|
+
|
|
18
|
+
const {
|
|
19
|
+
categoryList,
|
|
20
|
+
isDisabled,
|
|
21
|
+
isMenuOpen,
|
|
22
|
+
onCategorySelect,
|
|
23
|
+
onChange,
|
|
24
|
+
onClose,
|
|
25
|
+
onOpen,
|
|
26
|
+
selectedCategory,
|
|
27
|
+
stateKeys,
|
|
28
|
+
} = useFilterAdd({ isMobile: false });
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<Menu closeOnSelect={false} isOpen={isMenuOpen} onClose={onClose} onOpen={onOpen}>
|
|
32
|
+
<MenuButton
|
|
33
|
+
as={Button}
|
|
34
|
+
isDisabled={isDisabled}
|
|
35
|
+
isLoading={isLoading}
|
|
36
|
+
leftIconName="Plus"
|
|
37
|
+
position={isMenuOpen ? 'relative' : undefined}
|
|
38
|
+
size="sm"
|
|
39
|
+
variant="tertiary"
|
|
40
|
+
zIndex={isMenuOpen ? 'dialog' : undefined}
|
|
41
|
+
>
|
|
42
|
+
Add filter {isMenuOpen}
|
|
43
|
+
</MenuButton>
|
|
44
|
+
<Portal>
|
|
45
|
+
<MenuList
|
|
46
|
+
paddingY={selectedCategory ? 0 : '12'}
|
|
47
|
+
position={isMenuOpen ? 'relative' : undefined}
|
|
48
|
+
zIndex={isMenuOpen ? 'dialog' : undefined}
|
|
49
|
+
>
|
|
50
|
+
{selectedCategory ? (
|
|
51
|
+
<FilterForm
|
|
52
|
+
category={selectedCategory}
|
|
53
|
+
categoryName={data[selectedCategory].categoryName}
|
|
54
|
+
categoryNamePlural={data[selectedCategory].categoryNamePlural}
|
|
55
|
+
loadingText={data[selectedCategory].loadingText}
|
|
56
|
+
onCancel={onClose}
|
|
57
|
+
onChange={onChange}
|
|
58
|
+
/>
|
|
59
|
+
) : (
|
|
60
|
+
categoryList.map((category) => {
|
|
61
|
+
const { categoryName, dependsOn } = data[category];
|
|
62
|
+
const missingDependencies = getMissingDependencies(stateKeys, Object.keys(dependsOn || []));
|
|
63
|
+
const isCategoryDisabled = missingDependencies.length > 0 || !data[category]?.options?.length;
|
|
64
|
+
return (
|
|
65
|
+
<Tooltip
|
|
66
|
+
key={category}
|
|
67
|
+
isDisabled={!isCategoryDisabled}
|
|
68
|
+
label={dependsOn?.[missingDependencies[0]] || 'There is no options for this category.'}
|
|
69
|
+
placement="right"
|
|
70
|
+
>
|
|
71
|
+
<MenuItem
|
|
72
|
+
isDisabled={isCategoryDisabled}
|
|
73
|
+
onClick={() => onCategorySelect(category)}
|
|
74
|
+
pointerEvents="all"
|
|
75
|
+
rightIconName="ChevronRight"
|
|
76
|
+
>
|
|
77
|
+
{categoryName || category}
|
|
78
|
+
</MenuItem>
|
|
79
|
+
</Tooltip>
|
|
80
|
+
);
|
|
81
|
+
})
|
|
82
|
+
)}
|
|
83
|
+
</MenuList>
|
|
84
|
+
</Portal>
|
|
85
|
+
</Menu>
|
|
86
|
+
);
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export default FilterAdd;
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
// import { useEffect } from 'react';
|
|
2
1
|
import { useEffect } from 'react';
|
|
3
2
|
import { useDisclosure, useMultiStyleConfig } from 'chakra-ui-2--react';
|
|
4
3
|
import { DateTime } from 'luxon';
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import
|
|
4
|
+
import DatePicker, { DatePickerProps, DateRange, useDateRange } from '../../../DatePicker/DatePicker';
|
|
5
|
+
import { useFilterContext } from '../../Filter.context';
|
|
6
|
+
import { FilterStyle } from '../../Filter.theme';
|
|
7
|
+
import { FilterCategoryProps } from '../../Filter.types';
|
|
8
|
+
import Box from '../../../Box/Box';
|
|
9
|
+
import Text from '../../../Text/Text';
|
|
10
|
+
import Icon from '../../../Icon/Icon';
|
|
12
11
|
|
|
13
12
|
export type FilterDateProps = {
|
|
14
13
|
category: string;
|
|
14
|
+
isMobile: boolean;
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
const FilterDate = (props: FilterDateProps) => {
|
|
18
|
-
const { category } = props;
|
|
18
|
+
const { category, isMobile } = props;
|
|
19
19
|
const filterStyle = useMultiStyleConfig('Filter') as FilterStyle;
|
|
20
20
|
|
|
21
21
|
const { isLoading, onFilterChange, onFilterClear, setPopoverOpen, state, data } = useFilterContext();
|
|
@@ -58,7 +58,18 @@ const FilterDate = (props: FilterDateProps) => {
|
|
|
58
58
|
? `${selectedRange.from?.toFormat('LLL dd')} - ${selectedRange.to?.toFormat('LLL dd')}`
|
|
59
59
|
: 'All dates';
|
|
60
60
|
|
|
61
|
-
return (
|
|
61
|
+
return isMobile ? (
|
|
62
|
+
<DatePicker
|
|
63
|
+
selectable={dateRangeData.selectable || selectable}
|
|
64
|
+
onApply={onDateRangeApply}
|
|
65
|
+
onClear={value?.length ? onClearClick : undefined}
|
|
66
|
+
dayTooltip={dateRangeData.dayTooltip}
|
|
67
|
+
selected={selectedRange}
|
|
68
|
+
visible={isOpen}
|
|
69
|
+
variant="inline"
|
|
70
|
+
mode="range"
|
|
71
|
+
/>
|
|
72
|
+
) : (
|
|
62
73
|
<DatePicker
|
|
63
74
|
selectable={dateRangeData.selectable || selectable}
|
|
64
75
|
onApply={onDateRangeApply}
|