@bitrise/bitkit 13.267.1-alpha.0 → 13.268.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 +13 -13
- package/src/Components/Dropdown/Dropdown.tsx +19 -31
- 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 +4 -5
- package/src/Components/Dropdown/isNodeMatch.ts +6 -15
- 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.
|
|
4
|
+
"version": "13.268.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+ssh://git@github.com/bitrise-io/bitkit.git"
|
|
@@ -38,10 +38,10 @@
|
|
|
38
38
|
"@floating-ui/react-dom-interactions": "^0.8.1",
|
|
39
39
|
"@fontsource/figtree": "^5.2.8",
|
|
40
40
|
"@fontsource/source-code-pro": "^5.2.6",
|
|
41
|
-
"framer-motion": "^12.
|
|
41
|
+
"framer-motion": "^12.23.0",
|
|
42
42
|
"luxon": "^3.6.1",
|
|
43
|
-
"react": "^
|
|
44
|
-
"react-dom": "^
|
|
43
|
+
"react": "^18.3.1",
|
|
44
|
+
"react-dom": "^18.3.1",
|
|
45
45
|
"react-focus-lock": "2.13.6",
|
|
46
46
|
"react-imask": "^7.6.1",
|
|
47
47
|
"react-markdown": "^10.1.0"
|
|
@@ -51,14 +51,13 @@
|
|
|
51
51
|
"react-dom": "^18.2.0"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
|
-
"@babel/core": "^7.
|
|
55
|
-
"@babel/preset-env": "^7.
|
|
54
|
+
"@babel/core": "^7.28.0",
|
|
55
|
+
"@babel/preset-env": "^7.28.0",
|
|
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-docs": "^9.0.15",
|
|
62
61
|
"@storybook/addon-links": "^9.0.15",
|
|
63
62
|
"@storybook/addon-webpack5-compiler-swc": "^3.0.0",
|
|
64
63
|
"@storybook/react-webpack5": "^9.0.15",
|
|
@@ -66,17 +65,17 @@
|
|
|
66
65
|
"@testing-library/jest-dom": "6.6.3",
|
|
67
66
|
"@testing-library/react": "16.3.0",
|
|
68
67
|
"@testing-library/user-event": "^14.6.1",
|
|
69
|
-
"@types/jest": "^
|
|
68
|
+
"@types/jest": "^29.5.14",
|
|
70
69
|
"@types/luxon": "^3.6.2",
|
|
71
|
-
"@types/react": "^
|
|
72
|
-
"@types/react-dom": "^
|
|
70
|
+
"@types/react": "^18.3.23",
|
|
71
|
+
"@types/react-dom": "^18.3.7",
|
|
73
72
|
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
|
74
73
|
"@typescript-eslint/parser": "^7.18.0",
|
|
75
74
|
"axios": "^1.10.0",
|
|
76
75
|
"eslint": "^8.57.1",
|
|
77
76
|
"glob": "^11.0.3",
|
|
78
|
-
"jest": "^
|
|
79
|
-
"jest-environment-jsdom": "^
|
|
77
|
+
"jest": "^29.7.0",
|
|
78
|
+
"jest-environment-jsdom": "^29.7.0",
|
|
80
79
|
"jsdom": "26.1.0",
|
|
81
80
|
"lodash": "^4.17.21",
|
|
82
81
|
"prettier": "^3.6.2",
|
|
@@ -84,7 +83,8 @@
|
|
|
84
83
|
"release-it": "^19.0.3",
|
|
85
84
|
"storybook": "^9.0.15",
|
|
86
85
|
"ts-jest": "^29.4.0",
|
|
87
|
-
"typescript": "^5.8.3"
|
|
86
|
+
"typescript": "^5.8.3",
|
|
87
|
+
"@storybook/addon-docs": "^9.0.15"
|
|
88
88
|
},
|
|
89
89
|
"files": [
|
|
90
90
|
"src",
|
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
import React, {
|
|
2
|
-
Children,
|
|
3
2
|
cloneElement,
|
|
4
3
|
createContext,
|
|
5
4
|
forwardRef,
|
|
6
|
-
ForwardRefExoticComponent,
|
|
7
|
-
isValidElement,
|
|
8
5
|
JSX,
|
|
9
6
|
ReactNode,
|
|
10
|
-
Ref,
|
|
11
|
-
RefAttributes,
|
|
12
|
-
RefObject,
|
|
13
7
|
useCallback,
|
|
14
8
|
useContext,
|
|
15
9
|
useEffect,
|
|
@@ -100,24 +94,23 @@ export { DropdownOption, DropdownGroup, DropdownSearch, NoResultsFound, Dropdown
|
|
|
100
94
|
|
|
101
95
|
function useOptionListWithIndexes({ children }: { children: ReactNode }) {
|
|
102
96
|
return useMemo(() => {
|
|
103
|
-
const childList = Children.toArray(children);
|
|
97
|
+
const childList = React.Children.toArray(children);
|
|
104
98
|
let idx = 0;
|
|
105
99
|
const transform = (ch: ReactNode): ReactNode => {
|
|
106
|
-
if (isValidElement(ch)) {
|
|
100
|
+
if (React.isValidElement(ch)) {
|
|
107
101
|
if (ch.type === DropdownOption || ch.type === DropdownDetailedOption) {
|
|
108
102
|
const index = idx;
|
|
109
103
|
idx += 1;
|
|
110
104
|
return cloneElement(ch, {
|
|
111
|
-
...
|
|
105
|
+
...ch.props,
|
|
112
106
|
index,
|
|
113
|
-
}
|
|
107
|
+
});
|
|
114
108
|
}
|
|
115
|
-
if ('children' in
|
|
109
|
+
if ('children' in ch.props) {
|
|
116
110
|
return cloneElement(ch, {
|
|
117
|
-
...
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
} as any);
|
|
111
|
+
...ch.props,
|
|
112
|
+
children: React.Children.toArray(ch.props.children).map(transform),
|
|
113
|
+
});
|
|
121
114
|
}
|
|
122
115
|
}
|
|
123
116
|
return ch;
|
|
@@ -127,29 +120,24 @@ function useOptionListWithIndexes({ children }: { children: ReactNode }) {
|
|
|
127
120
|
}
|
|
128
121
|
|
|
129
122
|
type UseDropdownProps = {
|
|
130
|
-
ref: Ref<Element>;
|
|
131
|
-
optionsRef: RefObject<HTMLDivElement
|
|
123
|
+
ref: React.Ref<Element>;
|
|
124
|
+
optionsRef: React.RefObject<HTMLDivElement>;
|
|
132
125
|
};
|
|
133
126
|
|
|
134
127
|
function findOption<T>(
|
|
135
128
|
children: ReactNode,
|
|
136
129
|
value: T,
|
|
137
130
|
): { label: ReactNode; index: number; avatar?: AvatarProps } | null {
|
|
138
|
-
const list = Children.toArray(children);
|
|
131
|
+
const list = React.Children.toArray(children);
|
|
139
132
|
for (let i = 0; i < list.length; i++) {
|
|
140
133
|
const elem = list[i];
|
|
141
|
-
if (isValidElement(elem) && !
|
|
142
|
-
const optValue = typeof
|
|
134
|
+
if (React.isValidElement(elem) && !elem.props.isDisabled) {
|
|
135
|
+
const optValue = typeof elem.props.value === 'undefined' ? null : elem.props.value;
|
|
143
136
|
if (elem.type === DropdownOption && optValue === value) {
|
|
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
|
+
return { index: elem.props.index, label: elem.props.children, avatar: elem.props.avatar };
|
|
149
138
|
}
|
|
150
139
|
const ch =
|
|
151
|
-
findOption(
|
|
152
|
-
(isSearchable(elem.type) && findOption(elem.type(elem.props), value));
|
|
140
|
+
findOption(elem.props.children, value) || (isSearchable(elem.type) && findOption(elem.type(elem.props), value));
|
|
153
141
|
if (ch) {
|
|
154
142
|
return ch;
|
|
155
143
|
}
|
|
@@ -207,7 +195,7 @@ function useDropdown<T>({
|
|
|
207
195
|
}
|
|
208
196
|
}, [activeIndex]);
|
|
209
197
|
const referenceKeyDown = useCallback(
|
|
210
|
-
(ev: React.KeyboardEvent
|
|
198
|
+
(ev: React.KeyboardEvent) => {
|
|
211
199
|
if (ev.key === 'Enter') {
|
|
212
200
|
ev.preventDefault();
|
|
213
201
|
searchOnSubmit();
|
|
@@ -221,7 +209,7 @@ function useDropdown<T>({
|
|
|
221
209
|
});
|
|
222
210
|
|
|
223
211
|
// this can just be a ref as it will always be updated when formValue is, which will cause a re-render
|
|
224
|
-
const labelMapRef = useRef<Map<T, ReactNode>>(
|
|
212
|
+
const labelMapRef = useRef<Map<T, ReactNode>>();
|
|
225
213
|
if (!labelMapRef.current) labelMapRef.current = new Map();
|
|
226
214
|
|
|
227
215
|
// clear map when value is changed from the outside
|
|
@@ -420,7 +408,7 @@ const Dropdown = forwardRef<Element, DropdownProps<string | null>>(
|
|
|
420
408
|
) => {
|
|
421
409
|
const dataAttributes = getDataAttributes(props);
|
|
422
410
|
|
|
423
|
-
const optionsRef = useRef
|
|
411
|
+
const optionsRef = useRef(null);
|
|
424
412
|
const {
|
|
425
413
|
avatar,
|
|
426
414
|
children,
|
|
@@ -566,7 +554,7 @@ const Dropdown = forwardRef<Element, DropdownProps<string | null>>(
|
|
|
566
554
|
|
|
567
555
|
export function typedDropdown<T>() {
|
|
568
556
|
return {
|
|
569
|
-
Dropdown: Dropdown as ForwardRefExoticComponent<DropdownProps<T> & RefAttributes<Element>>,
|
|
557
|
+
Dropdown: Dropdown as React.ForwardRefExoticComponent<DropdownProps<T> & React.RefAttributes<Element>>,
|
|
570
558
|
DropdownOption: DropdownOption as (p: DropdownOptionProps<T>) => JSX.Element,
|
|
571
559
|
};
|
|
572
560
|
}
|
|
@@ -7,13 +7,13 @@ const useAutoScroll = ({
|
|
|
7
7
|
optionsRef,
|
|
8
8
|
selectedIndex,
|
|
9
9
|
}: {
|
|
10
|
-
optionsRef: React.RefObject<HTMLDivElement
|
|
10
|
+
optionsRef: React.RefObject<HTMLDivElement>;
|
|
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>();
|
|
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>;
|
|
31
31
|
dropdownWidth: ChakraProps['width'] | 'match';
|
|
32
32
|
placement: UseFloatingProps['placement'] | undefined;
|
|
33
33
|
}) => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Children, cloneElement, isValidElement,
|
|
1
|
+
import { Children, cloneElement, isValidElement, 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,13 +25,12 @@ 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
|
|
29
|
-
const groupChildren = Children.toArray(element.props.children).map(transform).filter(Boolean);
|
|
28
|
+
const groupChildren = Children.toArray(node.props.children).map(transform).filter(Boolean);
|
|
30
29
|
if (groupChildren.length === 0) {
|
|
31
30
|
return null;
|
|
32
31
|
}
|
|
33
|
-
return cloneElement(
|
|
34
|
-
...
|
|
32
|
+
return cloneElement(node, {
|
|
33
|
+
...node.props,
|
|
35
34
|
children: groupChildren,
|
|
36
35
|
});
|
|
37
36
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import React, { 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 (
|
|
21
|
-
return isNodeMatch(
|
|
20
|
+
if ('children' in node) {
|
|
21
|
+
return isNodeMatch(node.children, filter);
|
|
22
22
|
}
|
|
23
|
-
if (isValidElement<any>(node)) {
|
|
23
|
+
if (React.isValidElement<any>(node)) {
|
|
24
24
|
if (node.type === 'svg') {
|
|
25
25
|
return false;
|
|
26
26
|
}
|
|
@@ -28,18 +28,9 @@ function isNodeMatch(node: ReactNode, filter: string): boolean {
|
|
|
28
28
|
if (isSearchable(ctor)) {
|
|
29
29
|
return isNodeMatch(ctor(node.props), filter);
|
|
30
30
|
}
|
|
31
|
-
|
|
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));
|
|
31
|
+
return isNodeMatch(node.props.children, filter);
|
|
41
32
|
}
|
|
42
|
-
return
|
|
33
|
+
return isNodeMatch(Array.from(node), filter);
|
|
43
34
|
}
|
|
44
35
|
|
|
45
36
|
export default isNodeMatch;
|
|
@@ -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,
|
|
20
|
+
titlePath: [...titlePath, child.props.title],
|
|
21
21
|
} as { level: number; indexPath: number[]; titlePath: string[] })
|
|
22
22
|
: child,
|
|
23
23
|
)}
|