@bitrise/bitkit 13.267.0 → 13.267.1-alpha.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 +22 -27
- package/src/Components/DatePicker/DatePickerDay.tsx +1 -1
- package/src/Components/DatePicker/DatePickerHeader.tsx +1 -1
- package/src/Components/DatePicker/DatePickerMonthSelector.tsx +1 -1
- package/src/Components/Dropdown/Dropdown.tsx +32 -19
- package/src/Components/Dropdown/hooks/useAutoScroll.ts +2 -2
- package/src/Components/Dropdown/hooks/useFloatingDropdown.ts +1 -1
- package/src/Components/Dropdown/hooks/useSimpleSearch.tsx +5 -4
- package/src/Components/Dropdown/isNodeMatch.ts +15 -6
- package/src/Components/LabeledData/LabeledData.tsx +1 -1
- package/src/Components/ProgressIndicator/ProgressIndicator.tsx +1 -1
- package/src/Components/Table/TablePagination.tsx +1 -1
- package/src/Components/TreeView/TreeViewGroup.tsx +1 -1
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.267.0",
|
|
4
|
+
"version": "13.267.1-alpha.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+ssh://git@github.com/bitrise-io/bitkit.git"
|
|
@@ -34,14 +34,14 @@
|
|
|
34
34
|
"@chakra-ui/theme-tools": "^2.2.8",
|
|
35
35
|
"@chakra-ui/utils": "^2.2.4",
|
|
36
36
|
"@emotion/react": "^11.14.0",
|
|
37
|
-
"@emotion/styled": "^11.14.
|
|
37
|
+
"@emotion/styled": "^11.14.1",
|
|
38
38
|
"@floating-ui/react-dom-interactions": "^0.8.1",
|
|
39
39
|
"@fontsource/figtree": "^5.2.8",
|
|
40
|
-
"@fontsource/source-code-pro": "^5.2.
|
|
41
|
-
"framer-motion": "^12.
|
|
40
|
+
"@fontsource/source-code-pro": "^5.2.6",
|
|
41
|
+
"framer-motion": "^12.20.4",
|
|
42
42
|
"luxon": "^3.6.1",
|
|
43
|
-
"react": "^
|
|
44
|
-
"react-dom": "^
|
|
43
|
+
"react": "^19.1.0",
|
|
44
|
+
"react-dom": "^19.1.0",
|
|
45
45
|
"react-focus-lock": "2.13.6",
|
|
46
46
|
"react-imask": "^7.6.1",
|
|
47
47
|
"react-markdown": "^10.1.0"
|
|
@@ -51,44 +51,39 @@
|
|
|
51
51
|
"react-dom": "^18.2.0"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
|
-
"@babel/core": "^7.27.
|
|
54
|
+
"@babel/core": "^7.27.7",
|
|
55
55
|
"@babel/preset-env": "^7.27.2",
|
|
56
56
|
"@babel/preset-react": "^7.27.1",
|
|
57
57
|
"@babel/preset-typescript": "^7.27.1",
|
|
58
58
|
"@bitrise/eslint-plugin": "^2.12.0",
|
|
59
59
|
"@chakra-ui/cli": "^2.5.8",
|
|
60
60
|
"@google-cloud/storage": "^7.16.0",
|
|
61
|
-
"@storybook/addon-
|
|
62
|
-
"@storybook/addon-
|
|
63
|
-
"@storybook/addon-interactions": "^8.6.14",
|
|
64
|
-
"@storybook/addon-links": "^8.6.14",
|
|
61
|
+
"@storybook/addon-docs": "^9.0.15",
|
|
62
|
+
"@storybook/addon-links": "^9.0.15",
|
|
65
63
|
"@storybook/addon-webpack5-compiler-swc": "^3.0.0",
|
|
66
|
-
"@storybook/
|
|
67
|
-
"@storybook/react": "^8.6.14",
|
|
68
|
-
"@storybook/react-webpack5": "^8.6.14",
|
|
69
|
-
"@storybook/theming": "^8.6.14",
|
|
64
|
+
"@storybook/react-webpack5": "^9.0.15",
|
|
70
65
|
"@testing-library/dom": "^10.4.0",
|
|
71
66
|
"@testing-library/jest-dom": "6.6.3",
|
|
72
67
|
"@testing-library/react": "16.3.0",
|
|
73
68
|
"@testing-library/user-event": "^14.6.1",
|
|
74
|
-
"@types/jest": "^
|
|
69
|
+
"@types/jest": "^30.0.0",
|
|
75
70
|
"@types/luxon": "^3.6.2",
|
|
76
|
-
"@types/react": "^
|
|
77
|
-
"@types/react-dom": "^
|
|
71
|
+
"@types/react": "^19.1.8",
|
|
72
|
+
"@types/react-dom": "^19.1.6",
|
|
78
73
|
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
|
79
74
|
"@typescript-eslint/parser": "^7.18.0",
|
|
80
|
-
"axios": "^1.
|
|
75
|
+
"axios": "^1.10.0",
|
|
81
76
|
"eslint": "^8.57.1",
|
|
82
|
-
"glob": "^11.0.
|
|
83
|
-
"jest": "^
|
|
84
|
-
"jest-environment-jsdom": "^
|
|
77
|
+
"glob": "^11.0.3",
|
|
78
|
+
"jest": "^30.0.3",
|
|
79
|
+
"jest-environment-jsdom": "^30.0.2",
|
|
85
80
|
"jsdom": "26.1.0",
|
|
86
81
|
"lodash": "^4.17.21",
|
|
87
|
-
"prettier": "^3.
|
|
88
|
-
"react-hook-form": "^7.
|
|
89
|
-
"release-it": "^19.0.
|
|
90
|
-
"storybook": "^
|
|
91
|
-
"ts-jest": "^29.
|
|
82
|
+
"prettier": "^3.6.2",
|
|
83
|
+
"react-hook-form": "^7.59.0",
|
|
84
|
+
"release-it": "^19.0.3",
|
|
85
|
+
"storybook": "^9.0.15",
|
|
86
|
+
"ts-jest": "^29.4.0",
|
|
92
87
|
"typescript": "^5.8.3"
|
|
93
88
|
},
|
|
94
89
|
"files": [
|
|
@@ -87,7 +87,7 @@ const DatePickerDayView = ({
|
|
|
87
87
|
const [DatePickerDayContext, useDatePickerDayContext] = createContext<Context>();
|
|
88
88
|
export { DatePickerDayContext };
|
|
89
89
|
|
|
90
|
-
const DatePickerDay = ({ n }: { n: number })
|
|
90
|
+
const DatePickerDay = ({ n }: { n: number }) => {
|
|
91
91
|
const {
|
|
92
92
|
onPreview,
|
|
93
93
|
onSelect,
|
|
@@ -62,7 +62,7 @@ const DatePickerMonthSelector = ({
|
|
|
62
62
|
}: {
|
|
63
63
|
viewDate: DateTime;
|
|
64
64
|
onMonthSelected: (month: number, year: number) => void;
|
|
65
|
-
})
|
|
65
|
+
}) => {
|
|
66
66
|
const [selectedYear, setSelectedYear] = useState(viewDate.year);
|
|
67
67
|
const onPreviousYear = useCallback(() => setSelectedYear((year) => year - 1), []);
|
|
68
68
|
const onNextYear = useCallback(() => setSelectedYear((year) => year + 1), []);
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import React, {
|
|
2
|
+
Children,
|
|
2
3
|
cloneElement,
|
|
3
4
|
createContext,
|
|
4
5
|
forwardRef,
|
|
6
|
+
ForwardRefExoticComponent,
|
|
7
|
+
isValidElement,
|
|
8
|
+
JSX,
|
|
5
9
|
ReactNode,
|
|
10
|
+
Ref,
|
|
11
|
+
RefAttributes,
|
|
12
|
+
RefObject,
|
|
6
13
|
useCallback,
|
|
7
14
|
useContext,
|
|
8
15
|
useEffect,
|
|
@@ -93,23 +100,24 @@ export { DropdownOption, DropdownGroup, DropdownSearch, NoResultsFound, Dropdown
|
|
|
93
100
|
|
|
94
101
|
function useOptionListWithIndexes({ children }: { children: ReactNode }) {
|
|
95
102
|
return useMemo(() => {
|
|
96
|
-
const childList =
|
|
103
|
+
const childList = Children.toArray(children);
|
|
97
104
|
let idx = 0;
|
|
98
105
|
const transform = (ch: ReactNode): ReactNode => {
|
|
99
|
-
if (
|
|
106
|
+
if (isValidElement(ch)) {
|
|
100
107
|
if (ch.type === DropdownOption || ch.type === DropdownDetailedOption) {
|
|
101
108
|
const index = idx;
|
|
102
109
|
idx += 1;
|
|
103
110
|
return cloneElement(ch, {
|
|
104
|
-
...ch.props,
|
|
111
|
+
...(ch.props || {}),
|
|
105
112
|
index,
|
|
106
|
-
});
|
|
113
|
+
} as any);
|
|
107
114
|
}
|
|
108
|
-
if ('children' in ch.props) {
|
|
115
|
+
if ('children' in (ch.props as any)) {
|
|
109
116
|
return cloneElement(ch, {
|
|
110
|
-
...ch.props,
|
|
111
|
-
children
|
|
112
|
-
|
|
117
|
+
...(ch.props || {}),
|
|
118
|
+
// Cast to any to allow children property
|
|
119
|
+
children: Children.toArray((ch.props as any).children).map(transform),
|
|
120
|
+
} as any);
|
|
113
121
|
}
|
|
114
122
|
}
|
|
115
123
|
return ch;
|
|
@@ -119,24 +127,29 @@ function useOptionListWithIndexes({ children }: { children: ReactNode }) {
|
|
|
119
127
|
}
|
|
120
128
|
|
|
121
129
|
type UseDropdownProps = {
|
|
122
|
-
ref:
|
|
123
|
-
optionsRef:
|
|
130
|
+
ref: Ref<Element>;
|
|
131
|
+
optionsRef: RefObject<HTMLDivElement | null>;
|
|
124
132
|
};
|
|
125
133
|
|
|
126
134
|
function findOption<T>(
|
|
127
135
|
children: ReactNode,
|
|
128
136
|
value: T,
|
|
129
137
|
): { label: ReactNode; index: number; avatar?: AvatarProps } | null {
|
|
130
|
-
const list =
|
|
138
|
+
const list = Children.toArray(children);
|
|
131
139
|
for (let i = 0; i < list.length; i++) {
|
|
132
140
|
const elem = list[i];
|
|
133
|
-
if (
|
|
134
|
-
const optValue = typeof elem.props.value === 'undefined' ? null : elem.props.value;
|
|
141
|
+
if (isValidElement(elem) && !(elem.props as any).isDisabled) {
|
|
142
|
+
const optValue = typeof (elem.props as any).value === 'undefined' ? null : (elem.props as any).value;
|
|
135
143
|
if (elem.type === DropdownOption && optValue === value) {
|
|
136
|
-
return {
|
|
144
|
+
return {
|
|
145
|
+
index: (elem.props as any).index,
|
|
146
|
+
label: (elem.props as any).children,
|
|
147
|
+
avatar: (elem.props as any).avatar,
|
|
148
|
+
};
|
|
137
149
|
}
|
|
138
150
|
const ch =
|
|
139
|
-
findOption(elem.props.children, value) ||
|
|
151
|
+
findOption((elem.props as any).children, value) ||
|
|
152
|
+
(isSearchable(elem.type) && findOption(elem.type(elem.props), value));
|
|
140
153
|
if (ch) {
|
|
141
154
|
return ch;
|
|
142
155
|
}
|
|
@@ -194,7 +207,7 @@ function useDropdown<T>({
|
|
|
194
207
|
}
|
|
195
208
|
}, [activeIndex]);
|
|
196
209
|
const referenceKeyDown = useCallback(
|
|
197
|
-
(ev: React.KeyboardEvent) => {
|
|
210
|
+
(ev: React.KeyboardEvent<Element>) => {
|
|
198
211
|
if (ev.key === 'Enter') {
|
|
199
212
|
ev.preventDefault();
|
|
200
213
|
searchOnSubmit();
|
|
@@ -208,7 +221,7 @@ function useDropdown<T>({
|
|
|
208
221
|
});
|
|
209
222
|
|
|
210
223
|
// this can just be a ref as it will always be updated when formValue is, which will cause a re-render
|
|
211
|
-
const labelMapRef = useRef<Map<T, ReactNode>>();
|
|
224
|
+
const labelMapRef = useRef<Map<T, ReactNode>>(new Map());
|
|
212
225
|
if (!labelMapRef.current) labelMapRef.current = new Map();
|
|
213
226
|
|
|
214
227
|
// clear map when value is changed from the outside
|
|
@@ -407,7 +420,7 @@ const Dropdown = forwardRef<Element, DropdownProps<string | null>>(
|
|
|
407
420
|
) => {
|
|
408
421
|
const dataAttributes = getDataAttributes(props);
|
|
409
422
|
|
|
410
|
-
const optionsRef = useRef(null);
|
|
423
|
+
const optionsRef = useRef<HTMLDivElement | null>(null);
|
|
411
424
|
const {
|
|
412
425
|
avatar,
|
|
413
426
|
children,
|
|
@@ -553,7 +566,7 @@ const Dropdown = forwardRef<Element, DropdownProps<string | null>>(
|
|
|
553
566
|
|
|
554
567
|
export function typedDropdown<T>() {
|
|
555
568
|
return {
|
|
556
|
-
Dropdown: Dropdown as
|
|
569
|
+
Dropdown: Dropdown as ForwardRefExoticComponent<DropdownProps<T> & RefAttributes<Element>>,
|
|
557
570
|
DropdownOption: DropdownOption as (p: DropdownOptionProps<T>) => JSX.Element,
|
|
558
571
|
};
|
|
559
572
|
}
|
|
@@ -7,13 +7,13 @@ const useAutoScroll = ({
|
|
|
7
7
|
optionsRef,
|
|
8
8
|
selectedIndex,
|
|
9
9
|
}: {
|
|
10
|
-
optionsRef: React.RefObject<HTMLDivElement>;
|
|
10
|
+
optionsRef: React.RefObject<HTMLDivElement | null>;
|
|
11
11
|
listRef: React.MutableRefObject<HTMLElement[]>;
|
|
12
12
|
activeIndex: number | null;
|
|
13
13
|
selectedIndex: number | null;
|
|
14
14
|
keyboardControlled: boolean;
|
|
15
15
|
}) => {
|
|
16
|
-
const prevActiveIndexRef = useRef<number | null>();
|
|
16
|
+
const prevActiveIndexRef = useRef<number | null>(null);
|
|
17
17
|
useLayoutEffect(() => {
|
|
18
18
|
prevActiveIndexRef.current = activeIndex;
|
|
19
19
|
}, [activeIndex]);
|
|
@@ -27,7 +27,7 @@ const useFloatingDropdown = ({
|
|
|
27
27
|
placement,
|
|
28
28
|
}: {
|
|
29
29
|
enabled: boolean;
|
|
30
|
-
optionsRef: RefObject<HTMLDivElement>;
|
|
30
|
+
optionsRef: RefObject<HTMLDivElement | null>;
|
|
31
31
|
dropdownWidth: ChakraProps['width'] | 'match';
|
|
32
32
|
placement: UseFloatingProps['placement'] | undefined;
|
|
33
33
|
}) => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Children, cloneElement, isValidElement, ReactNode, useMemo, useState } from 'react';
|
|
1
|
+
import { Children, cloneElement, isValidElement, ReactElement, ReactNode, useMemo, useState } from 'react';
|
|
2
2
|
import { chakra } from '@chakra-ui/react';
|
|
3
3
|
import { useDropdownStyles } from '../Dropdown.context';
|
|
4
4
|
import isNodeMatch from '../isNodeMatch';
|
|
@@ -25,12 +25,13 @@ function useSimpleSearch({ children, onSearch }: { children?: ReactNode; onSearc
|
|
|
25
25
|
|
|
26
26
|
const transform = (node: ReactNode): ReactNode => {
|
|
27
27
|
if (isValidElement(node) && node.type === DropdownGroup) {
|
|
28
|
-
const
|
|
28
|
+
const element = node as ReactElement<{ children?: ReactNode }>;
|
|
29
|
+
const groupChildren = Children.toArray(element.props.children).map(transform).filter(Boolean);
|
|
29
30
|
if (groupChildren.length === 0) {
|
|
30
31
|
return null;
|
|
31
32
|
}
|
|
32
|
-
return cloneElement(
|
|
33
|
-
...
|
|
33
|
+
return cloneElement(element, {
|
|
34
|
+
...element.props,
|
|
34
35
|
children: groupChildren,
|
|
35
36
|
});
|
|
36
37
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { isValidElement, JSXElementConstructor, ReactElement, ReactNode } from 'react';
|
|
2
2
|
|
|
3
3
|
type SearchableElement = JSXElementConstructor<any> & { searchable: true };
|
|
4
4
|
export function isSearchable(
|
|
@@ -17,10 +17,10 @@ function isNodeMatch(node: ReactNode, filter: string): boolean {
|
|
|
17
17
|
if (Array.isArray(node)) {
|
|
18
18
|
return Array.from(node).some((child) => isNodeMatch(child, filter));
|
|
19
19
|
}
|
|
20
|
-
if ('children' in node) {
|
|
21
|
-
return isNodeMatch(node.children, filter);
|
|
20
|
+
if (typeof node === 'object' && node !== null && 'children' in node) {
|
|
21
|
+
return isNodeMatch((node as any).children, filter);
|
|
22
22
|
}
|
|
23
|
-
if (
|
|
23
|
+
if (isValidElement<any>(node)) {
|
|
24
24
|
if (node.type === 'svg') {
|
|
25
25
|
return false;
|
|
26
26
|
}
|
|
@@ -28,9 +28,18 @@ function isNodeMatch(node: ReactNode, filter: string): boolean {
|
|
|
28
28
|
if (isSearchable(ctor)) {
|
|
29
29
|
return isNodeMatch(ctor(node.props), filter);
|
|
30
30
|
}
|
|
31
|
-
|
|
31
|
+
if (isValidElement(node)) {
|
|
32
|
+
return isNodeMatch((node as ReactElement<any>).props.children, filter);
|
|
33
|
+
}
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
if (
|
|
37
|
+
(typeof node === 'object' && node !== null && (Symbol.iterator in node || 'length' in node)) ||
|
|
38
|
+
Array.isArray(node)
|
|
39
|
+
) {
|
|
40
|
+
return Array.from(node as Iterable<ReactNode> | ArrayLike<ReactNode>).some((child) => isNodeMatch(child, filter));
|
|
32
41
|
}
|
|
33
|
-
return
|
|
42
|
+
return false;
|
|
34
43
|
}
|
|
35
44
|
|
|
36
45
|
export default isNodeMatch;
|
|
@@ -39,7 +39,7 @@ const LabeledData = ({
|
|
|
39
39
|
trendValue,
|
|
40
40
|
trendColorScheme,
|
|
41
41
|
...rest
|
|
42
|
-
}: LabeledDataProps)
|
|
42
|
+
}: LabeledDataProps) => {
|
|
43
43
|
const trendIconSize = size === 'sm' ? '16' : '24';
|
|
44
44
|
const labelColor = size === 'sm' ? 'text/primary' : 'text/secondary';
|
|
45
45
|
let trendSign;
|
|
@@ -166,7 +166,7 @@ const RealStage = ({
|
|
|
166
166
|
);
|
|
167
167
|
};
|
|
168
168
|
|
|
169
|
-
const ProgressIndicator = ({ activeStageIndex, stages, ...rest }: ProgressIndicatorProps)
|
|
169
|
+
const ProgressIndicator = ({ activeStageIndex, stages, ...rest }: ProgressIndicatorProps) => {
|
|
170
170
|
const style = useMultiStyleConfig('ProgressIndicator', { variant: rest.variant });
|
|
171
171
|
const extendLines = Boolean(rest.variant === 'horizontal' && rest.extendLines);
|
|
172
172
|
const activeSegmentIndex = extendLines ? activeStageIndex * 2 : activeStageIndex;
|
|
@@ -5,7 +5,7 @@ import Tr from './Tr';
|
|
|
5
5
|
|
|
6
6
|
export type TablePaginationProps = Omit<PaginationProps, 'variant'> & { colSpan: number };
|
|
7
7
|
|
|
8
|
-
const TablePagination = ({ colSpan, ...paginationProps }: TablePaginationProps)
|
|
8
|
+
const TablePagination = ({ colSpan, ...paginationProps }: TablePaginationProps) => {
|
|
9
9
|
return (
|
|
10
10
|
<Tfoot>
|
|
11
11
|
<Tr>
|
|
@@ -17,7 +17,7 @@ const TreeViewGroup = ({ label, role, level, indexPath, titlePath, children }: T
|
|
|
17
17
|
? cloneElement(child, {
|
|
18
18
|
level,
|
|
19
19
|
indexPath: [...indexPath, childIndex],
|
|
20
|
-
titlePath: [...titlePath, child.props.title],
|
|
20
|
+
titlePath: [...titlePath, (child.props as { title: string }).title],
|
|
21
21
|
} as { level: number; indexPath: number[]; titlePath: string[] })
|
|
22
22
|
: child,
|
|
23
23
|
)}
|