Skip to content

Commit 502a372

Browse files
committed
fix: revert deepmerge and fix wheelpicker
1 parent 77aef0e commit 502a372

11 files changed

Lines changed: 82 additions & 75 deletions

File tree

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
],
3636
"license": "MIT",
3737
"dependencies": {
38+
"deepmerge": "4.0.0",
3839
"exenv": "1.2.2",
3940
"focus-trap": "5.0.1",
4041
"react-icons": "3.7.0",

src/components/Layout/LayoutProvider.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
import deepMerge from 'deepmerge';
12
import * as React from 'react';
23
import { Dimensions } from 'react-native';
34

4-
import { deepMerge } from '../../utils/deepMerge';
55
import {
66
defaultLayout,
77
DESC_ORDER_SCREEN_SIZES,

src/components/WheelPicker/WheelPicker.mdx

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { Box, State, WheelPicker, Icon, TextInput } from '..';
1313
{({ state, setState }) => (
1414
<Box flexDirection="row">
1515
<WheelPicker
16-
value="May"
16+
value={state.month}
1717
options={[
1818
{ label: 'January', value: 'January' },
1919
{ label: 'February', value: 'February' },
@@ -28,19 +28,30 @@ import { Box, State, WheelPicker, Icon, TextInput } from '..';
2828
{ label: 'November', value: 'November' },
2929
{ label: 'December', value: 'December' },
3030
]}
31-
onValueChange={value => console.log(value)}
31+
onValueChange={value => {
32+
console.log(value);
33+
setState({ month: value });
34+
}}
3235
/>
3336
<WheelPicker
37+
value={state.day}
3438
options={new Array(31)
3539
.fill(0)
3640
.map((v, i) => ({ label: `${i + 1}`, value: `${i + 1}` }))}
37-
onValueChange={value => console.log(value)}
41+
onValueChange={value => {
42+
console.log(value);
43+
setState({ day: value });
44+
}}
3845
/>
3946
<WheelPicker
47+
value={state.year}
4048
options={new Array(50)
4149
.fill(0)
4250
.map((v, i) => ({ label: `${2000 + i}`, value: `${2000 + i}` }))}
43-
onValueChange={value => console.log(value)}
51+
onValueChange={value => {
52+
console.log(value);
53+
setState({ year: value });
54+
}}
4455
/>
4556
</Box>
4657
)}

src/components/WheelPicker/WheelPicker.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ const WheelPickerBase = (
5353
handlePressDown,
5454
handlePressUp,
5555
handleEndDrag,
56-
initialScrollIndex,
5756
} = useWheelPicker({
5857
onValueChange,
5958
options,
@@ -65,6 +64,7 @@ const WheelPickerBase = (
6564
value,
6665
});
6766

67+
const initialScrollIndex = options.findIndex(o => o.value === value);
6868
const theme = useTheme();
6969

7070
const {
@@ -95,7 +95,7 @@ const WheelPickerBase = (
9595
length: ITEM_HEIGHT,
9696
offset: ITEM_HEIGHT * index,
9797
})}
98-
initialScrollIndex={initialScrollIndex}
98+
initialScrollIndex={initialScrollIndex < 0 ? 0 : initialScrollIndex}
9999
keyExtractor={item => item.value}
100100
renderItem={({ item }) => <WheelPickerItem option={item} />}
101101
showsHorizontalScrollIndicator={false}

src/components/WheelPicker/WheelPicker.web.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@ export const WheelPicker = React.forwardRef(
2121
} = props;
2222

2323
const theme = useTheme();
24-
2524
const listRef = React.useRef<HTMLDivElement>(null);
2625

2726
const {
2827
optionsWithClones,
2928
handlePressDown,
3029
handlePressUp,
3130
handleScroll,
31+
scrollToValue,
3232
} = useWheelPicker({
3333
onValueChange,
3434
options,
@@ -57,6 +57,12 @@ export const WheelPicker = React.forwardRef(
5757
theme.components.getWheelPickerStyles,
5858
)(props, theme);
5959

60+
React.useLayoutEffect(() => {
61+
setTimeout(() => {
62+
if (listRef.current && value) scrollToValue(value, false);
63+
}, 50);
64+
}, [value]);
65+
6066
return (
6167
<View style={containerStyle}>
6268
<TouchableOpacity style={arrowWrapperStyle} onPress={handlePressUp}>

src/components/WheelPicker/useWheelPicker.ts

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import * as React from 'react';
22

3+
import { useDebouncedCallback } from '../../hooks/useDebouncedCallback';
34
import { WheelPicker } from './WheelPicker';
45
import { ITEM_HEIGHT } from './WheelPicker.constants';
56
import { WheelPickerOption } from './WheelPickerItem';
67

8+
const DEBOUNCE_TIME = 300;
9+
710
export const makePaddedOptions = (options: WheelPickerOption[]) => {
811
return [
912
{ value: 'emptyStart', label: '' },
@@ -64,18 +67,15 @@ export const useWheelPicker = (props: UseWheelPickerProps) => {
6467
onValueChange = () => {
6568
return;
6669
},
67-
value: initialValue,
70+
value: initialValue = options[0].value,
6871
scrollContainer,
6972
ref,
7073
} = props;
7174
const optionsWithClones = makePaddedOptions(options);
72-
const [currentValue, setCurrentValue] = React.useState(initialValue);
75+
const [value, setValue] = React.useState<string>(initialValue);
7376
const getOption = React.useMemo(() => getOptionFromOptions(options), [
7477
options,
7578
]);
76-
const initialScrollIndex = options.findIndex(
77-
o => o.value === (initialValue || options[0].value),
78-
);
7979

8080
const scrollToValue = React.useCallback(
8181
(toValue: string, animated = true) => {
@@ -87,30 +87,30 @@ export const useWheelPicker = (props: UseWheelPickerProps) => {
8787
animated,
8888
offset: index * ITEM_HEIGHT - ITEM_HEIGHT,
8989
});
90-
91-
setCurrentValue(toValue);
9290
},
9391
[scrollContainer, options],
9492
);
9593

96-
React.useLayoutEffect(() => {
97-
if (initialValue) {
98-
scrollToValue(initialValue, false);
99-
} else {
100-
scrollToValue(options[0].value, false);
101-
}
102-
}, [options]);
94+
const handleChange = React.useCallback(
95+
(newValue: string) => {
96+
if (newValue !== value) {
97+
onValueChange(newValue);
98+
setValue(newValue);
99+
}
100+
},
101+
[onValueChange, value],
102+
);
103103

104-
const handleScroll = React.useCallback(
104+
const handleScroll = useDebouncedCallback(
105105
(offset: number) => {
106106
if (!scrollContainer) return;
107107

108108
const selectedOption = getOption(offset);
109109

110-
onValueChange(selectedOption.value);
111-
setCurrentValue(selectedOption.value);
110+
handleChange(selectedOption.value);
112111
},
113-
[scrollContainer, options],
112+
DEBOUNCE_TIME,
113+
[scrollContainer, options, handleChange],
114114
);
115115

116116
const handleEndDrag = React.useCallback(
@@ -125,43 +125,41 @@ export const useWheelPicker = (props: UseWheelPickerProps) => {
125125

126126
const selectedOption = getOption(scrollPosition);
127127

128-
onValueChange(selectedOption.value);
129-
setCurrentValue(selectedOption.value);
128+
handleChange(selectedOption.value);
130129
},
131-
[scrollContainer, options],
130+
[scrollContainer, options, handleChange],
132131
);
133132

134133
React.useImperativeHandle(
135134
ref,
136135
() => ({
137-
selectValue: (value: string) => scrollToValue(value),
136+
selectValue: (newValue: string) => scrollToValue(newValue),
138137
}),
139138
[scrollContainer, options],
140139
);
141140

142141
const handlePressUp = React.useCallback(() => {
143142
if (!scrollContainer) return;
144-
const currentIndex = options.findIndex(o => o.value === currentValue);
143+
const currentIndex = options.findIndex(o => o.value === value);
145144

146145
if (currentIndex <= 0) return;
147146
scrollToValue(options[currentIndex - 1].value);
148-
}, [scrollContainer, currentValue]);
147+
}, [scrollContainer, value]);
149148

150149
const handlePressDown = React.useCallback(() => {
151150
if (!scrollContainer) return;
152151

153-
const currentIndex = options.findIndex(o => o.value === currentValue);
152+
const currentIndex = options.findIndex(o => o.value === value);
154153

155154
if (currentIndex >= options.length - 1) return;
156155
scrollToValue(options[currentIndex + 1].value);
157-
}, [scrollContainer, currentValue]);
156+
}, [scrollContainer, value]);
158157

159158
return {
160159
handleEndDrag,
161160
handlePressDown,
162161
handlePressUp,
163162
handleScroll,
164-
initialScrollIndex,
165163
optionsWithClones,
166164
scrollToValue,
167165
};

src/hooks/useDebouncedCallback.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import React from 'react';
2+
3+
export const useDebouncedCallback = <T extends (...args: any[]) => void>(
4+
callback: T,
5+
delay: number,
6+
deps: readonly any[],
7+
): T => {
8+
const timeout = React.useRef<number | null>(null);
9+
10+
return React.useCallback(
11+
// @ts-ignore
12+
(...args) => {
13+
if (timeout.current) clearTimeout(timeout.current);
14+
15+
// @ts-ignore
16+
timeout.current = setTimeout(() => callback(...args), delay);
17+
},
18+
[callback, delay, ...deps],
19+
);
20+
};

src/theme/Theme.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import deepMerge from 'deepmerge';
12
import React from 'react';
23
import { TextStyle, ViewStyle } from 'react-native';
34
import { DeepPartial } from 'ts-essentials';
@@ -34,7 +35,6 @@ import { GetLabelStyles } from '../components/Typography/Label.styles';
3435
import { GetParagraphStyles } from '../components/Typography/Paragraph.styles';
3536
import { GetTextStyles } from '../components/Typography/Text.styles';
3637
import { GetWheelPickerStyles } from '../components/WheelPicker/WheelPicker.styles';
37-
import { deepMerge } from '../utils/deepMerge';
3838
import { defaultTheme } from './defaultTheme';
3939

4040
export interface TextSizes {
@@ -304,7 +304,8 @@ export interface ThemeProviderProps {
304304
value?: DeepPartial<Theme>;
305305
}
306306

307-
export const createTheme = (theme?: DeepPartial<Theme>): Theme => {
307+
const createTheme = (theme?: DeepPartial<Theme>): Theme => {
308+
// @ts-ignore
308309
return theme ? deepMerge(defaultTheme, theme) : defaultTheme;
309310
};
310311

src/utils/deepMerge.ts

Lines changed: 0 additions & 36 deletions
This file was deleted.

src/utils/mergeStyles.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
import deepMerge from 'deepmerge';
12
import { DeepPartial } from 'ts-essentials';
23

34
import { Theme } from '../theme';
4-
import { deepMerge } from './deepMerge';
55

66
export type GetStyles<TStyles = any, TStyleProps = any> = (
77
props: TStyleProps,
@@ -32,5 +32,6 @@ export const mergeStyles = <TStyles = any, TStyleProps = any>(
3232
styles.push(getOverridingStyles(props, theme) as Partial<TStyles>);
3333
}
3434

35-
return deepMerge<TStyles>(defaultStyles, ...styles);
35+
// @ts-ignore
36+
return deepMerge.all<TStyles>([defaultStyles, ...styles]);
3637
};

0 commit comments

Comments
 (0)