@bitrise/bitkit 13.273.0 → 13.274.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 +1 -1
- package/src/Components/Breadcrumb/Breadcrumb.theme.ts +3 -1
- package/src/Components/Filter/Filter.storyData.ts +1 -0
- package/src/Components/Filter/Filter.types.ts +8 -0
- package/src/Components/Filter/FilterDate/FilterDate.tsx +9 -3
- package/src/Components/Filter/FilterSwitch/FilterSwitch.theme.ts +18 -17
- package/src/Components/Filter/FilterSwitch/FilterSwitch.tsx +51 -5
- package/src/Components/Filter/FilterSwitch/FilterSwitchGroup.tsx +13 -3
- package/src/Components/Filter/FilterSwitchAdapter/FilterSwitchAdapter.tsx +16 -5
- package/src/Components/Pagination/Pagination.tsx +2 -2
- package/src/Components/Tag/Tag.theme.ts +3 -2
package/package.json
CHANGED
|
@@ -12,7 +12,8 @@ const BreadcrumbTheme: SystemStyleObject = {
|
|
|
12
12
|
_hover: {
|
|
13
13
|
textDecoration: 'none',
|
|
14
14
|
},
|
|
15
|
-
color: '
|
|
15
|
+
color: 'text/body',
|
|
16
|
+
textStyle: 'body/md/semibold',
|
|
16
17
|
},
|
|
17
18
|
_hover: {
|
|
18
19
|
textDecoration: 'underline',
|
|
@@ -29,6 +30,7 @@ const BreadcrumbTheme: SystemStyleObject = {
|
|
|
29
30
|
separator: {
|
|
30
31
|
color: 'neutral.80',
|
|
31
32
|
display: 'flex',
|
|
33
|
+
marginInline: '4',
|
|
32
34
|
},
|
|
33
35
|
},
|
|
34
36
|
};
|
|
@@ -36,11 +36,19 @@ export type FilterCategoryProps = {
|
|
|
36
36
|
dayTooltip?: DatePickerProps['dayTooltip'];
|
|
37
37
|
isMultiple: true;
|
|
38
38
|
}
|
|
39
|
+
| {
|
|
40
|
+
type: 'switch';
|
|
41
|
+
allOptionLabel?: string;
|
|
42
|
+
}
|
|
39
43
|
| {
|
|
40
44
|
type?: Exclude<FilterType, 'dateRange'>;
|
|
41
45
|
selectable?: never;
|
|
42
46
|
dayTooltip?: never;
|
|
43
47
|
}
|
|
48
|
+
| {
|
|
49
|
+
type?: Exclude<FilterType, 'switch'>;
|
|
50
|
+
allOptionLabel?: never;
|
|
51
|
+
}
|
|
44
52
|
);
|
|
45
53
|
|
|
46
54
|
export type FilterData = Record<string, FilterCategoryProps>;
|
|
@@ -3,11 +3,12 @@ import { useEffect } from 'react';
|
|
|
3
3
|
import { useDisclosure, useMultiStyleConfig } from '@chakra-ui/react';
|
|
4
4
|
import { DateTime } from 'luxon';
|
|
5
5
|
import Box from '../../Box/Box';
|
|
6
|
-
import DatePicker, { DateRange, useDateRange } from '../../DatePicker/DatePicker';
|
|
6
|
+
import DatePicker, { DatePickerProps, DateRange, useDateRange } from '../../DatePicker/DatePicker';
|
|
7
7
|
import Icon from '../../Icon/Icon';
|
|
8
8
|
import Text from '../../Text/Text';
|
|
9
9
|
import { useFilterContext } from '../Filter.context';
|
|
10
10
|
import { FilterStyle } from '../Filter.theme';
|
|
11
|
+
import { FilterCategoryProps } from '../Filter.types';
|
|
11
12
|
|
|
12
13
|
export type FilterDateProps = {
|
|
13
14
|
category: string;
|
|
@@ -19,6 +20,11 @@ const FilterDate = (props: FilterDateProps) => {
|
|
|
19
20
|
|
|
20
21
|
const { isLoading, onFilterChange, onFilterClear, setPopoverOpen, state, data } = useFilterContext();
|
|
21
22
|
|
|
23
|
+
const dateRangeData = data.date_range as FilterCategoryProps & {
|
|
24
|
+
dayTooltip?: DatePickerProps['dayTooltip'];
|
|
25
|
+
selectable?: DateRange;
|
|
26
|
+
};
|
|
27
|
+
|
|
22
28
|
const { isOpen, onClose, onToggle } = useDisclosure();
|
|
23
29
|
|
|
24
30
|
const value = state[category];
|
|
@@ -54,11 +60,11 @@ const FilterDate = (props: FilterDateProps) => {
|
|
|
54
60
|
|
|
55
61
|
return (
|
|
56
62
|
<DatePicker
|
|
57
|
-
selectable={
|
|
63
|
+
selectable={dateRangeData.selectable || selectable}
|
|
58
64
|
onApply={onDateRangeApply}
|
|
59
65
|
onClear={value?.length ? onClearClick : undefined}
|
|
60
66
|
onClose={onClose}
|
|
61
|
-
dayTooltip={
|
|
67
|
+
dayTooltip={dateRangeData.dayTooltip}
|
|
62
68
|
selected={selectedRange}
|
|
63
69
|
visible={isOpen}
|
|
64
70
|
mode="range"
|
|
@@ -1,43 +1,44 @@
|
|
|
1
1
|
import { rem } from '../../../utils/utils';
|
|
2
2
|
|
|
3
3
|
const FilterSwitch = {
|
|
4
|
-
baseStyle: () => {
|
|
4
|
+
baseStyle: ({ isChecked }: { isChecked: boolean }) => {
|
|
5
5
|
return {
|
|
6
6
|
container: {
|
|
7
7
|
background: 'neutral.95',
|
|
8
|
-
border: '1px solid',
|
|
9
|
-
borderColor: 'neutral.80',
|
|
10
8
|
borderRadius: '4',
|
|
11
9
|
color: 'neutral.40',
|
|
12
10
|
display: 'flex',
|
|
13
11
|
},
|
|
12
|
+
icon: {
|
|
13
|
+
color: isChecked ? 'icon/secondary' : 'icon/tertiary',
|
|
14
|
+
},
|
|
14
15
|
item: {
|
|
16
|
+
borderRadius: '4',
|
|
17
|
+
maxW: '20rem',
|
|
18
|
+
borderColor: isChecked ? 'border/strong' : 'transparent',
|
|
19
|
+
borderWidth: '1px',
|
|
20
|
+
borderStyle: 'solid',
|
|
21
|
+
_hover: {
|
|
22
|
+
background: 'background/hover',
|
|
23
|
+
color: 'text/primary',
|
|
24
|
+
|
|
25
|
+
'> svg': {
|
|
26
|
+
color: 'icon/secondary',
|
|
27
|
+
},
|
|
28
|
+
},
|
|
15
29
|
_active: {
|
|
16
|
-
background: '
|
|
17
|
-
color: 'purple.10',
|
|
30
|
+
background: 'background/active',
|
|
18
31
|
},
|
|
19
32
|
_checked: {
|
|
20
33
|
background: 'neutral.100',
|
|
21
34
|
color: 'purple.10',
|
|
22
35
|
cursor: 'default',
|
|
23
36
|
},
|
|
24
|
-
_first: {
|
|
25
|
-
borderLeft: 'none',
|
|
26
|
-
borderLeftRadius: '4',
|
|
27
|
-
},
|
|
28
37
|
_focusVisible: {
|
|
29
38
|
boxShadow: 'outline',
|
|
30
39
|
zIndex: 1,
|
|
31
40
|
},
|
|
32
|
-
_hover: {
|
|
33
|
-
background: 'neutral.100',
|
|
34
|
-
},
|
|
35
|
-
_last: {
|
|
36
|
-
borderRightRadius: '4',
|
|
37
|
-
},
|
|
38
41
|
alignItems: 'center',
|
|
39
|
-
borderLeft: '1px solid',
|
|
40
|
-
borderLeftColor: 'neutral.80',
|
|
41
42
|
cursor: 'pointer',
|
|
42
43
|
display: 'flex',
|
|
43
44
|
fontSize: rem(14),
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
1
2
|
import {
|
|
2
3
|
chakra,
|
|
3
4
|
forwardRef,
|
|
@@ -7,33 +8,47 @@ import {
|
|
|
7
8
|
useRadioGroupContext,
|
|
8
9
|
} from '@chakra-ui/react';
|
|
9
10
|
import { omitThemingProps } from '@chakra-ui/styled-system';
|
|
11
|
+
import { createContext } from '@chakra-ui/react-utils';
|
|
12
|
+
import Divider from '../../Divider/Divider';
|
|
13
|
+
import Text from '../../Text/Text';
|
|
14
|
+
import Box from '../../Box/Box';
|
|
15
|
+
import Icon, { TypeIconName } from '../../Icon/Icon';
|
|
10
16
|
|
|
11
17
|
type RadioInputProps = ChakraRadioProps['inputProps'] & {
|
|
12
18
|
'data-testid'?: string;
|
|
13
19
|
};
|
|
14
20
|
|
|
15
21
|
export interface FilterSwitchProps extends Omit<ChakraRadioProps, 'inputProps'> {
|
|
22
|
+
iconName?: TypeIconName;
|
|
16
23
|
inputProps?: RadioInputProps;
|
|
17
24
|
}
|
|
18
25
|
|
|
26
|
+
type FilterSwicthContext = {
|
|
27
|
+
selectedOption: string;
|
|
28
|
+
options: string[];
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const [FilterSwitchContextProvider, useFilterSwitchContext] = createContext<FilterSwicthContext>();
|
|
32
|
+
|
|
19
33
|
const FilterSwitch = forwardRef<FilterSwitchProps, 'input'>((props, ref) => {
|
|
20
34
|
const group = useRadioGroupContext();
|
|
21
35
|
const { value: valueProp } = props;
|
|
22
36
|
|
|
23
|
-
const
|
|
37
|
+
const isChecked = group.value === valueProp;
|
|
38
|
+
|
|
39
|
+
const styles = useMultiStyleConfig('FilterSwitch', { isChecked });
|
|
24
40
|
|
|
25
41
|
const ownProps = omitThemingProps(props);
|
|
26
42
|
|
|
27
43
|
const {
|
|
28
44
|
children,
|
|
45
|
+
iconName,
|
|
29
46
|
inputProps: htmlInputProps,
|
|
30
47
|
isDisabled = group?.isDisabled,
|
|
31
48
|
isFocusable = group?.isFocusable,
|
|
32
49
|
...rest
|
|
33
50
|
} = ownProps;
|
|
34
51
|
|
|
35
|
-
const isChecked = group.value === valueProp;
|
|
36
|
-
|
|
37
52
|
const { name } = group;
|
|
38
53
|
|
|
39
54
|
const { getRadioProps, getInputProps, getLabelProps } = useRadio({
|
|
@@ -45,12 +60,43 @@ const FilterSwitch = forwardRef<FilterSwitchProps, 'input'>((props, ref) => {
|
|
|
45
60
|
onChange: group.onChange,
|
|
46
61
|
});
|
|
47
62
|
|
|
48
|
-
|
|
63
|
+
const { options, selectedOption } = useFilterSwitchContext();
|
|
64
|
+
|
|
65
|
+
const showDivider = useMemo(() => {
|
|
66
|
+
const optionCount = options.length;
|
|
67
|
+
const index = options.indexOf(valueProp || '');
|
|
68
|
+
|
|
69
|
+
const selectedIndex = options.indexOf(selectedOption);
|
|
70
|
+
|
|
71
|
+
return index < optionCount - 1 && selectedIndex !== index && selectedIndex !== index + 1;
|
|
72
|
+
}, [options, selectedOption, valueProp]);
|
|
73
|
+
|
|
74
|
+
const component = (
|
|
49
75
|
<chakra.label {...getLabelProps()} {...getRadioProps()} __css={styles.item}>
|
|
50
76
|
<chakra.input {...getInputProps(htmlInputProps, ref)} />
|
|
51
|
-
{
|
|
77
|
+
{iconName && <Icon __css={styles.icon} name={iconName} size="16" />}
|
|
78
|
+
<Text as="span" display="block" overflow="hidden" textOverflow="ellipsis">
|
|
79
|
+
{children}
|
|
80
|
+
</Text>
|
|
52
81
|
</chakra.label>
|
|
53
82
|
);
|
|
83
|
+
|
|
84
|
+
return (
|
|
85
|
+
<Box height="fit-content" width="fit-content" position="relative">
|
|
86
|
+
{component}
|
|
87
|
+
{showDivider && (
|
|
88
|
+
<Divider
|
|
89
|
+
background="boder/regular"
|
|
90
|
+
height="16"
|
|
91
|
+
orientation="vertical"
|
|
92
|
+
marginTop="8"
|
|
93
|
+
position="absolute"
|
|
94
|
+
right="0"
|
|
95
|
+
top="0"
|
|
96
|
+
/>
|
|
97
|
+
)}
|
|
98
|
+
</Box>
|
|
99
|
+
);
|
|
54
100
|
});
|
|
55
101
|
|
|
56
102
|
export default FilterSwitch;
|
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
import { RadioGroup as ChakraRadioGroup, RadioGroupProps, useMultiStyleConfig } from '@chakra-ui/react';
|
|
2
|
+
import { FilterSwitchContextProvider } from './FilterSwitch';
|
|
2
3
|
|
|
3
|
-
export type {
|
|
4
|
+
export type FilterSwitchGroupProps = { options: string[] } & RadioGroupProps;
|
|
4
5
|
|
|
5
|
-
const FilterSwitchGroup = (
|
|
6
|
+
const FilterSwitchGroup = ({ options, value, ...rest }: FilterSwitchGroupProps) => {
|
|
6
7
|
const { container } = useMultiStyleConfig('FilterSwitch');
|
|
7
8
|
|
|
8
|
-
return
|
|
9
|
+
return (
|
|
10
|
+
<FilterSwitchContextProvider
|
|
11
|
+
value={{
|
|
12
|
+
options,
|
|
13
|
+
selectedOption: value || '',
|
|
14
|
+
}}
|
|
15
|
+
>
|
|
16
|
+
<ChakraRadioGroup sx={container} {...rest} value={value} />
|
|
17
|
+
</FilterSwitchContextProvider>
|
|
18
|
+
);
|
|
9
19
|
};
|
|
10
20
|
|
|
11
21
|
export default FilterSwitchGroup;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
1
2
|
import { useFilterContext } from '../Filter.context';
|
|
2
3
|
import { getOptionLabel } from '../Filter.utils';
|
|
3
|
-
import Icon from '../../Icon/Icon';
|
|
4
4
|
import FilterSwitch from '../FilterSwitch/FilterSwitch';
|
|
5
5
|
import FilterSwitchGroup from '../FilterSwitch/FilterSwitchGroup';
|
|
6
|
+
import { FilterCategoryProps } from '../Filter.types';
|
|
6
7
|
|
|
7
8
|
type FilterSwitchAdapterProps = {
|
|
8
9
|
category: string;
|
|
@@ -11,7 +12,11 @@ type FilterSwitchAdapterProps = {
|
|
|
11
12
|
const FilterSwitchAdapter = (props: FilterSwitchAdapterProps) => {
|
|
12
13
|
const { category } = props;
|
|
13
14
|
const { data, onFilterChange, state } = useFilterContext();
|
|
14
|
-
const { iconsMap, options, optionsMap } = data[category]
|
|
15
|
+
const { allOptionLabel, iconsMap, options, optionsMap } = data[category] as FilterCategoryProps & {
|
|
16
|
+
allOptionLabel?: string;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const optionsWithAll = useMemo(() => ['all', ...(options || [])], [options]);
|
|
15
20
|
|
|
16
21
|
if (!options?.length) {
|
|
17
22
|
return null;
|
|
@@ -20,10 +25,16 @@ const FilterSwitchAdapter = (props: FilterSwitchAdapterProps) => {
|
|
|
20
25
|
const value = state[category]?.[0] || '';
|
|
21
26
|
|
|
22
27
|
return (
|
|
23
|
-
<FilterSwitchGroup
|
|
28
|
+
<FilterSwitchGroup
|
|
29
|
+
onChange={(newValue) => onFilterChange(category, [newValue])}
|
|
30
|
+
options={optionsWithAll}
|
|
31
|
+
value={value}
|
|
32
|
+
>
|
|
33
|
+
<FilterSwitch key="all" value="all">
|
|
34
|
+
{allOptionLabel || 'All items'}
|
|
35
|
+
</FilterSwitch>
|
|
24
36
|
{options.map((opt) => (
|
|
25
|
-
<FilterSwitch key={opt} value={opt}>
|
|
26
|
-
{iconsMap && iconsMap[opt] && <Icon color="icon/tertiary" name={iconsMap[opt]} size="16" />}
|
|
37
|
+
<FilterSwitch key={opt} value={opt} iconName={iconsMap && iconsMap[opt]}>
|
|
27
38
|
{getOptionLabel(opt, optionsMap)}
|
|
28
39
|
</FilterSwitch>
|
|
29
40
|
))}
|
|
@@ -60,13 +60,13 @@ const Pagination = ({
|
|
|
60
60
|
))}
|
|
61
61
|
</Dropdown>
|
|
62
62
|
</Box>
|
|
63
|
-
<Divider color="pal.neutral.90" height="
|
|
63
|
+
<Divider color="pal.neutral.90" height="2.5rem" orientation="vertical" />
|
|
64
64
|
</>
|
|
65
65
|
)}
|
|
66
66
|
<Text as="span" color={textColor} marginRight="auto" textStyle="body/md/regular">
|
|
67
67
|
{itemsStartIndex}-{itemsEndIndex} of {totalCount} items
|
|
68
68
|
</Text>
|
|
69
|
-
<Divider color="pal.neutral.90" height="
|
|
69
|
+
<Divider color="pal.neutral.90" height="2.5rem" orientation="vertical" />
|
|
70
70
|
<Box alignItems="center" display="flex" gap="0.5rem">
|
|
71
71
|
<Dropdown
|
|
72
72
|
onChange={({ target }) => setPage(Number(target.value))}
|
|
@@ -66,9 +66,9 @@ const schemeMap: Record<TagColors, MappedColor> = {
|
|
|
66
66
|
};
|
|
67
67
|
|
|
68
68
|
const baseStyle = definePartsStyle((props) => {
|
|
69
|
-
const { colorScheme = 'neutral' } = props;
|
|
69
|
+
const { colorScheme = 'neutral', isDisabled, isLoading } = props;
|
|
70
70
|
const { color, isFilled } = schemeMap[colorScheme as TagColors];
|
|
71
|
-
const normalTextColor = color === 'neutral' ? 'text.
|
|
71
|
+
const normalTextColor = color === 'neutral' ? 'text.body' : `sys.${color}.strong`;
|
|
72
72
|
const scheme = {
|
|
73
73
|
backgroundColor: `sys.${color}.${isFilled ? 'bold' : 'subtle'}`,
|
|
74
74
|
borderColor: `sys.${color}.${isFilled ? 'bold' : 'muted'}`,
|
|
@@ -108,6 +108,7 @@ const baseStyle = definePartsStyle((props) => {
|
|
|
108
108
|
},
|
|
109
109
|
},
|
|
110
110
|
icon: {
|
|
111
|
+
color: colorScheme === 'neutral' && !isDisabled && !isLoading ? 'icon.secondary' : undefined,
|
|
111
112
|
marginInlineEnd: '4',
|
|
112
113
|
},
|
|
113
114
|
label: {
|