react-native-molecules 0.5.0-beta.21 → 0.5.0-beta.23
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/components/Button/Button.tsx +3 -1
- package/components/Card/Card.tsx +1 -1
- package/components/Checkbox/CheckboxBase.ios.tsx +1 -4
- package/components/Checkbox/CheckboxBase.tsx +2 -7
- package/components/DatePicker/DateCalendar.tsx +4 -4
- package/components/DatePicker/DatePickerModal.tsx +2 -1
- package/components/DatePicker/utils.ts +2 -0
- package/components/DatePickerInline/DatePickerDockedHeader.tsx +3 -3
- package/components/DatePickerInline/DatePickerInline.tsx +1 -1
- package/components/DatePickerInline/DatePickerInlineBase.tsx +2 -2
- package/components/DatePickerInline/DatePickerInlineHeader.tsx +43 -17
- package/components/DatePickerInline/HeaderItem.tsx +2 -2
- package/components/DatePickerInline/MonthPicker.tsx +58 -64
- package/components/DatePickerInline/Swiper.native.tsx +2 -2
- package/components/DatePickerInline/Swiper.tsx +3 -3
- package/components/DatePickerInline/YearPicker.tsx +108 -119
- package/components/DatePickerInline/{DatePickerContext.tsx → store.tsx} +7 -3
- package/components/DatePickerInline/types.ts +1 -1
- package/components/Divider/Divider.tsx +192 -0
- package/components/Divider/index.tsx +11 -0
- package/components/Drawer/DrawerItemGroup.tsx +3 -7
- package/components/IconButton/IconButton.tsx +2 -12
- package/components/List/List.tsx +275 -0
- package/components/List/context.tsx +26 -0
- package/components/List/index.ts +8 -0
- package/components/List/types.ts +117 -0
- package/components/List/utils.ts +79 -0
- package/components/Menu/Menu.tsx +146 -19
- package/components/Menu/index.tsx +9 -7
- package/components/Menu/utils.ts +21 -70
- package/components/Popover/Popover.tsx +7 -10
- package/components/Popover/PopoverRoot.tsx +6 -20
- package/components/Popover/common.ts +4 -0
- package/components/Popover/index.ts +2 -8
- package/components/Popover/usePlatformMeasure.ts +4 -2
- package/components/RadioButton/RadioButtonAndroid.tsx +38 -54
- package/components/RadioButton/RadioButtonIOS.tsx +2 -16
- package/components/Select/Select.tsx +307 -501
- package/components/Select/context.tsx +39 -32
- package/components/Select/types.ts +63 -56
- package/components/Select/utils.ts +19 -44
- package/components/Text/textFactory.tsx +17 -5
- package/components/TimePicker/TimeInput.tsx +2 -7
- package/components/TimePicker/utils.ts +0 -4
- package/components/TouchableRipple/TouchableRipple.native.tsx +36 -5
- package/components/TouchableRipple/TouchableRipple.tsx +121 -163
- package/components/TouchableRipple/rippleFromForegroundColor.ts +21 -0
- package/package.json +6 -3
- package/components/HorizontalDivider/HorizontalDivider.tsx +0 -103
- package/components/HorizontalDivider/index.tsx +0 -9
- package/components/ListItem/ListItem.tsx +0 -138
- package/components/ListItem/ListItemDescription.tsx +0 -25
- package/components/ListItem/ListItemTitle.tsx +0 -25
- package/components/ListItem/index.tsx +0 -14
- package/components/ListItem/utils.ts +0 -115
- package/components/Menu/MenuDivider.tsx +0 -13
- package/components/Menu/MenuItem.tsx +0 -128
- package/components/VerticalDivider/VerticalDivider.tsx +0 -100
- package/components/VerticalDivider/index.tsx +0 -9
|
@@ -81,6 +81,8 @@ export type Props = Omit<SurfaceProps, 'style'> &
|
|
|
81
81
|
disabledPress?: boolean;
|
|
82
82
|
};
|
|
83
83
|
|
|
84
|
+
const emptyObj = {};
|
|
85
|
+
|
|
84
86
|
const Button = (
|
|
85
87
|
{
|
|
86
88
|
disabled = false,
|
|
@@ -97,7 +99,7 @@ const Button = (
|
|
|
97
99
|
style: styleProp,
|
|
98
100
|
testID,
|
|
99
101
|
accessible,
|
|
100
|
-
stateLayerProps =
|
|
102
|
+
stateLayerProps = emptyObj,
|
|
101
103
|
elevation: elevationProp,
|
|
102
104
|
textRelatedStyle,
|
|
103
105
|
disabledPress,
|
package/components/Card/Card.tsx
CHANGED
|
@@ -51,7 +51,7 @@ const Card = (
|
|
|
51
51
|
container: [cardStyles.container, cardStyles.root, style],
|
|
52
52
|
innerContainer: [cardStyles.innerContainer, touchableContainerStyle],
|
|
53
53
|
};
|
|
54
|
-
// eslint-disable-next-line
|
|
54
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
55
55
|
}, [variant, state, style, touchableContainerStyle]);
|
|
56
56
|
|
|
57
57
|
const elevation = elevationProp === undefined ? elevationLevel ?? 0 : elevationProp;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import setColor from 'color';
|
|
2
1
|
import { forwardRef, memo, useCallback, useMemo } from 'react';
|
|
3
2
|
import { View } from 'react-native';
|
|
4
3
|
|
|
@@ -39,9 +38,8 @@ const CheckboxIOS = (
|
|
|
39
38
|
});
|
|
40
39
|
const checkedColor = colorProp;
|
|
41
40
|
|
|
42
|
-
const {
|
|
41
|
+
const { rippleContainerStyles, iconContainerStyles } = useMemo(() => {
|
|
43
42
|
return {
|
|
44
|
-
rippleColor: setColor(checkedColor).fade(0.32).rgb().string(),
|
|
45
43
|
rippleContainerStyles: [styles.root, style],
|
|
46
44
|
iconContainerStyles: { opacity: indeterminate || checked ? 1 : 0 },
|
|
47
45
|
};
|
|
@@ -58,7 +56,6 @@ const CheckboxIOS = (
|
|
|
58
56
|
<TouchableRipple
|
|
59
57
|
{...rest}
|
|
60
58
|
borderless
|
|
61
|
-
rippleColor={rippleColor}
|
|
62
59
|
onPress={onChange}
|
|
63
60
|
disabled={disabled}
|
|
64
61
|
accessibilityRole="checkbox"
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import setColor from 'color';
|
|
2
1
|
import { forwardRef, memo, type PropsWithoutRef, useCallback, useMemo } from 'react';
|
|
3
|
-
import {
|
|
2
|
+
import { type ViewProps } from 'react-native';
|
|
4
3
|
|
|
5
4
|
import { useActionState } from '../../hooks';
|
|
6
5
|
import { resolveStateVariant } from '../../utils';
|
|
@@ -51,14 +50,11 @@ const CheckboxAndroid = (
|
|
|
51
50
|
size,
|
|
52
51
|
});
|
|
53
52
|
|
|
54
|
-
const {
|
|
53
|
+
const { rippleContainerStyles, iconStyle } = useMemo(() => {
|
|
55
54
|
const _color = tokenStylesParser.getColor(checked ? colorProp : uncheckedColorProp);
|
|
56
55
|
|
|
57
56
|
return {
|
|
58
57
|
iconStyle: [styles.icon, _color],
|
|
59
|
-
// TODO - fix this on web
|
|
60
|
-
rippleColor:
|
|
61
|
-
Platform.OS === 'web' ? undefined : setColor(_color).fade(0.32).rgb().string(),
|
|
62
58
|
rippleContainerStyles: [styles.root, style],
|
|
63
59
|
};
|
|
64
60
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
@@ -80,7 +76,6 @@ const CheckboxAndroid = (
|
|
|
80
76
|
<TouchableRipple
|
|
81
77
|
{...rest}
|
|
82
78
|
borderless
|
|
83
|
-
rippleColor={rippleColor}
|
|
84
79
|
onPress={onChange}
|
|
85
80
|
disabled={disabled}
|
|
86
81
|
accessibilityRole="checkbox"
|
|
@@ -11,7 +11,7 @@ import { useOptionalDatePickerContext } from './context';
|
|
|
11
11
|
|
|
12
12
|
export type DateCalendarProps = DatePickerInlineProps;
|
|
13
13
|
|
|
14
|
-
const DateCalendarDefault = memo((props: DateCalendarProps) => {
|
|
14
|
+
const DateCalendarDefault = memo(({ headerLayout = 'default', ...props }: DateCalendarProps) => {
|
|
15
15
|
const ctx = useOptionalDatePickerContext();
|
|
16
16
|
|
|
17
17
|
const hasExplicitState =
|
|
@@ -22,7 +22,7 @@ const DateCalendarDefault = memo((props: DateCalendarProps) => {
|
|
|
22
22
|
props.onChange !== undefined;
|
|
23
23
|
|
|
24
24
|
const isRange = props.mode === 'range' || ctx?.mode === 'range';
|
|
25
|
-
const effectiveHeaderLayout =
|
|
25
|
+
const effectiveHeaderLayout = headerLayout ?? (ctx ? 'docked' : 'inline');
|
|
26
26
|
const showOutsideDays =
|
|
27
27
|
props.showOutsideDays ?? (effectiveHeaderLayout === 'docked' && !isRange);
|
|
28
28
|
|
|
@@ -50,7 +50,7 @@ const DateCalendarDefault = memo((props: DateCalendarProps) => {
|
|
|
50
50
|
onChange={onChange}
|
|
51
51
|
locale={locale}
|
|
52
52
|
validRange={validRange}
|
|
53
|
-
headerLayout={
|
|
53
|
+
headerLayout={headerLayout}
|
|
54
54
|
showOutsideDays={showOutsideDays}
|
|
55
55
|
/>
|
|
56
56
|
);
|
|
@@ -72,7 +72,7 @@ const DateCalendarDefault = memo((props: DateCalendarProps) => {
|
|
|
72
72
|
onChange={onChange}
|
|
73
73
|
locale={locale}
|
|
74
74
|
validRange={validRange}
|
|
75
|
-
headerLayout={
|
|
75
|
+
headerLayout={headerLayout}
|
|
76
76
|
showOutsideDays={showOutsideDays}
|
|
77
77
|
/>
|
|
78
78
|
);
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
|
|
12
12
|
import { getRegisteredComponentWithFallback } from '../../core';
|
|
13
13
|
import { DateField } from '../DateField';
|
|
14
|
+
import type { DatePickerInlineProps } from '../DatePickerInline/DatePickerInline';
|
|
14
15
|
import { IconButton } from '../IconButton';
|
|
15
16
|
import { Modal, type ModalProps } from '../Modal';
|
|
16
17
|
import { Portal } from '../Portal';
|
|
@@ -47,7 +48,7 @@ export type DatePickerModalProps = Omit<ModalProps, 'children' | 'isOpen' | 'onC
|
|
|
47
48
|
showCalendarAccessibilityLabel?: string;
|
|
48
49
|
enterDateManuallyAccessibilityLabel?: string;
|
|
49
50
|
locale?: DatePickerLocale;
|
|
50
|
-
headerLayout?: '
|
|
51
|
+
headerLayout?: DatePickerInlineProps['headerLayout'];
|
|
51
52
|
/** Override the surface default draft mode. Modal defaults to `true` (staged commit). */
|
|
52
53
|
draft?: boolean;
|
|
53
54
|
};
|
|
@@ -4,10 +4,10 @@ import { View, type ViewStyle } from 'react-native';
|
|
|
4
4
|
import { StyleSheet } from 'react-native-unistyles';
|
|
5
5
|
|
|
6
6
|
import type { DatePickerLocale } from '../DatePicker/context';
|
|
7
|
-
import { useDatePickerStoreRef, useDatePickerStoreValue } from './DatePickerContext';
|
|
8
7
|
import type { DisableWeekDaysType } from './dateUtils';
|
|
9
8
|
import DayNames from './DayNames';
|
|
10
9
|
import HeaderItem from './HeaderItem';
|
|
10
|
+
import { useDatePickerInlineStoreRef, useDatePickerInlineStoreValue } from './store';
|
|
11
11
|
import { datePickerHeaderStyles } from './utils';
|
|
12
12
|
|
|
13
13
|
export type DockedHeaderProps = {
|
|
@@ -23,8 +23,8 @@ function DatePickerDockedHeader({
|
|
|
23
23
|
disableWeekDays,
|
|
24
24
|
style: styleProp,
|
|
25
25
|
}: DockedHeaderProps) {
|
|
26
|
-
const setStore =
|
|
27
|
-
const { localDate, pickerType } =
|
|
26
|
+
const setStore = useDatePickerInlineStoreRef().set;
|
|
27
|
+
const { localDate, pickerType } = useDatePickerInlineStoreValue(state => ({
|
|
28
28
|
localDate: state.localDate,
|
|
29
29
|
pickerType: state.pickerType,
|
|
30
30
|
}));
|
|
@@ -2,10 +2,10 @@ import { memo, useCallback, useEffect, useMemo } from 'react';
|
|
|
2
2
|
import { StyleSheet, View } from 'react-native';
|
|
3
3
|
|
|
4
4
|
import { useLatest } from '../../hooks';
|
|
5
|
-
import { defaultValue, Provider, useDatePickerStore } from './DatePickerContext';
|
|
6
5
|
import { areDatesOnSameDay, dateToUnix, getEndOfDay, getInitialIndex } from './dateUtils';
|
|
7
6
|
import Month from './Month';
|
|
8
7
|
import MonthPicker from './MonthPicker';
|
|
8
|
+
import { defaultValue, Provider, useDatePickerInlineStore } from './store';
|
|
9
9
|
import Swiper from './Swiper';
|
|
10
10
|
import type {
|
|
11
11
|
CalendarDate,
|
|
@@ -46,7 +46,7 @@ function DatePickerInlineBaseChild(props: DatePickerInlineBaseProps) {
|
|
|
46
46
|
showOutsideDays,
|
|
47
47
|
headerLayout,
|
|
48
48
|
} = props;
|
|
49
|
-
const [pickerType, setStore] =
|
|
49
|
+
const [pickerType, setStore] = useDatePickerInlineStore(state => state.pickerType);
|
|
50
50
|
|
|
51
51
|
const scrollMode = mode === 'range' || mode === 'multiple' ? 'vertical' : 'horizontal';
|
|
52
52
|
const isHorizontal = scrollMode === 'horizontal';
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { add } from 'date-fns';
|
|
1
|
+
import { add, setYear } from 'date-fns';
|
|
2
2
|
import { memo, useCallback, useMemo } from 'react';
|
|
3
3
|
import { type StyleProp, View, type ViewStyle } from 'react-native';
|
|
4
4
|
|
|
5
5
|
import type { DatePickerLocale } from '../DatePicker/context';
|
|
6
|
-
import { useDatePickerStore, useDatePickerStoreValue } from './DatePickerContext';
|
|
7
6
|
import type { DisableWeekDaysType } from './dateUtils';
|
|
8
7
|
import DayNames from './DayNames';
|
|
9
8
|
import HeaderItem from './HeaderItem';
|
|
9
|
+
import { useDatePickerInlineStore, useDatePickerInlineStoreValue } from './store';
|
|
10
10
|
import { datePickerHeaderStyles, dayNamesHeight } from './utils';
|
|
11
11
|
|
|
12
12
|
const buttonContainerHeight = 56;
|
|
@@ -26,10 +26,10 @@ function DatePickerInlineHeader({
|
|
|
26
26
|
disableWeekDays,
|
|
27
27
|
style: styleProp,
|
|
28
28
|
}: CalendarHeaderProps) {
|
|
29
|
-
const [_, setStore] =
|
|
30
|
-
const { localDate,
|
|
29
|
+
const [_, setStore] = useDatePickerInlineStore(state => state);
|
|
30
|
+
const { localDate, pickerType } = useDatePickerInlineStoreValue(state => ({
|
|
31
31
|
localDate: state.localDate,
|
|
32
|
-
|
|
32
|
+
pickerType: state.pickerType,
|
|
33
33
|
}));
|
|
34
34
|
const isHorizontal = scrollMode === 'horizontal';
|
|
35
35
|
|
|
@@ -58,36 +58,62 @@ function DatePickerInlineHeader({
|
|
|
58
58
|
};
|
|
59
59
|
}, [styleProp]);
|
|
60
60
|
|
|
61
|
+
const handleOnMonthPress = useCallback(() => {
|
|
62
|
+
isHorizontal &&
|
|
63
|
+
setStore(prev => ({
|
|
64
|
+
pickerType: prev.pickerType === 'month' ? undefined : 'month',
|
|
65
|
+
}));
|
|
66
|
+
}, [isHorizontal, setStore]);
|
|
67
|
+
|
|
61
68
|
const handleOnYearPress = useCallback(() => {
|
|
62
|
-
isHorizontal &&
|
|
69
|
+
isHorizontal &&
|
|
70
|
+
setStore(prev => ({
|
|
71
|
+
pickerType: prev.pickerType === 'year' ? undefined : 'year',
|
|
72
|
+
}));
|
|
63
73
|
}, [isHorizontal, setStore]);
|
|
64
74
|
|
|
65
|
-
const
|
|
75
|
+
const handleMonthPrev = useCallback(() => {
|
|
66
76
|
setStore(prev => ({ localDate: add(prev.localDate, { months: -1 }) }));
|
|
67
77
|
}, [setStore]);
|
|
68
78
|
|
|
69
|
-
const
|
|
79
|
+
const handleMonthNext = useCallback(() => {
|
|
70
80
|
setStore(prev => ({ localDate: add(prev.localDate, { months: 1 }) }));
|
|
71
81
|
}, [setStore]);
|
|
72
82
|
|
|
83
|
+
const handleYearPrev = useCallback(() => {
|
|
84
|
+
setStore(prev => ({
|
|
85
|
+
localDate: setYear(prev.localDate, prev.localDate.getFullYear() - 1),
|
|
86
|
+
}));
|
|
87
|
+
}, [setStore]);
|
|
88
|
+
|
|
89
|
+
const handleYearNext = useCallback(() => {
|
|
90
|
+
setStore(prev => ({
|
|
91
|
+
localDate: setYear(prev.localDate, prev.localDate.getFullYear() + 1),
|
|
92
|
+
}));
|
|
93
|
+
}, [setStore]);
|
|
94
|
+
|
|
73
95
|
return (
|
|
74
96
|
<View pointerEvents={'box-none'}>
|
|
75
97
|
<>
|
|
76
98
|
{isHorizontal && (
|
|
77
99
|
<View style={containerStyle}>
|
|
78
100
|
<HeaderItem
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
101
|
+
onPrev={handleMonthPrev}
|
|
102
|
+
onNext={handleMonthNext}
|
|
103
|
+
onPressDropdown={handleOnMonthPress}
|
|
104
|
+
type="month"
|
|
105
|
+
value={monthName}
|
|
106
|
+
pickerType={pickerType}
|
|
107
|
+
selecting={pickerType === 'month'}
|
|
84
108
|
/>
|
|
85
109
|
<HeaderItem
|
|
86
|
-
onNext={
|
|
87
|
-
onPrev={
|
|
88
|
-
|
|
110
|
+
onNext={handleYearNext}
|
|
111
|
+
onPrev={handleYearPrev}
|
|
112
|
+
onPressDropdown={handleOnYearPress}
|
|
113
|
+
type="year"
|
|
114
|
+
selecting={pickerType === 'year'}
|
|
89
115
|
value={year}
|
|
90
|
-
pickerType=
|
|
116
|
+
pickerType={pickerType}
|
|
91
117
|
/>
|
|
92
118
|
</View>
|
|
93
119
|
)}
|
|
@@ -6,7 +6,7 @@ import { Icon } from '../Icon';
|
|
|
6
6
|
import { IconButton } from '../IconButton';
|
|
7
7
|
import { Text } from '../Text';
|
|
8
8
|
import { TouchableRipple } from '../TouchableRipple';
|
|
9
|
-
import {
|
|
9
|
+
import { useDatePickerInlineStoreValue } from './store';
|
|
10
10
|
|
|
11
11
|
function HeaderItem({
|
|
12
12
|
value,
|
|
@@ -25,7 +25,7 @@ function HeaderItem({
|
|
|
25
25
|
onNext?: (type: 'month' | 'year' | undefined) => void;
|
|
26
26
|
onPrev?: (type: 'month' | 'year' | undefined) => void;
|
|
27
27
|
}) {
|
|
28
|
-
const { startDateYear, endDateYear } =
|
|
28
|
+
const { startDateYear, endDateYear } = useDatePickerInlineStoreValue(state => ({
|
|
29
29
|
startDateYear: state.startDateYear,
|
|
30
30
|
endDateYear: state.endDateYear,
|
|
31
31
|
}));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { setMonth } from 'date-fns';
|
|
2
|
-
import { memo, useCallback, useMemo
|
|
2
|
+
import { memo, useCallback, useMemo } from 'react';
|
|
3
3
|
import { FlatList, View, type ViewStyle } from 'react-native';
|
|
4
4
|
import { StyleSheet } from 'react-native-unistyles';
|
|
5
5
|
|
|
@@ -7,87 +7,84 @@ import { resolveStateVariant } from '../../utils';
|
|
|
7
7
|
import { range } from '../../utils/dateTimePicker';
|
|
8
8
|
import type { DatePickerLocale } from '../DatePicker/context';
|
|
9
9
|
import { datePickerMonthItemStyles, datePickerMonthPickerStyles } from '../DatePicker/utils';
|
|
10
|
-
import {
|
|
10
|
+
import { Divider } from '../Divider';
|
|
11
11
|
import { Icon } from '../Icon';
|
|
12
|
-
import {
|
|
12
|
+
import { List, type ListItemId, useListContextValue } from '../List';
|
|
13
13
|
import { Text } from '../Text';
|
|
14
|
-
import {
|
|
14
|
+
import { useDatePickerInlineStore, useDatePickerInlineStoreValue } from './store';
|
|
15
|
+
|
|
16
|
+
type MonthListItem = { id: number; label: string };
|
|
15
17
|
|
|
16
18
|
export default function MonthPicker({ locale }: { locale?: DatePickerLocale }) {
|
|
17
|
-
const [_, setStore] =
|
|
18
|
-
const { localDate, selectingMonth } =
|
|
19
|
+
const [_, setStore] = useDatePickerInlineStore(state => state);
|
|
20
|
+
const { localDate, selectingMonth } = useDatePickerInlineStoreValue(state => ({
|
|
19
21
|
localDate: state.localDate,
|
|
20
22
|
selectingMonth: state.pickerType === 'month',
|
|
21
23
|
}));
|
|
22
|
-
// const monthPickerStyles = useComponentStyles('DatePickerDocked_MonthPicker');
|
|
23
|
-
const flatList = useRef<FlatList<number> | null>(null);
|
|
24
24
|
const months = range(0, 11);
|
|
25
|
+
const monthItems = useMemo<MonthListItem[]>(
|
|
26
|
+
() => months.map(month => ({ id: month, label: String(month) })),
|
|
27
|
+
[months],
|
|
28
|
+
);
|
|
25
29
|
|
|
26
30
|
const handleOnChange = useCallback(
|
|
27
|
-
(
|
|
31
|
+
(value: ListItemId | null) => {
|
|
32
|
+
if (typeof value !== 'number') return;
|
|
28
33
|
setStore(prev => ({
|
|
29
|
-
localDate: setMonth(prev.localDate,
|
|
34
|
+
localDate: setMonth(prev.localDate, value),
|
|
30
35
|
pickerType: undefined,
|
|
31
36
|
}));
|
|
32
37
|
},
|
|
33
38
|
[setStore],
|
|
34
39
|
);
|
|
35
40
|
|
|
36
|
-
const renderItem = useCallback(
|
|
37
|
-
({ item }: { item: number }) => {
|
|
38
|
-
return (
|
|
39
|
-
<Month
|
|
40
|
-
month={item}
|
|
41
|
-
selected={localDate.getMonth() === item}
|
|
42
|
-
onPressMonth={handleOnChange}
|
|
43
|
-
monthStyles={datePickerMonthPickerStyles.root}
|
|
44
|
-
locale={locale}
|
|
45
|
-
/>
|
|
46
|
-
);
|
|
47
|
-
},
|
|
48
|
-
[localDate, handleOnChange, locale],
|
|
49
|
-
);
|
|
50
|
-
|
|
51
41
|
if (!selectingMonth) {
|
|
52
42
|
return null;
|
|
53
43
|
}
|
|
54
44
|
|
|
55
45
|
return (
|
|
56
|
-
<
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
46
|
+
<List multiple={false} value={localDate.getMonth()} onChange={handleOnChange}>
|
|
47
|
+
<View
|
|
48
|
+
style={[
|
|
49
|
+
StyleSheet.absoluteFill,
|
|
50
|
+
styles.root,
|
|
51
|
+
selectingMonth ? styles.opacity1 : styles.opacity0,
|
|
52
|
+
]}
|
|
53
|
+
pointerEvents={selectingMonth ? 'auto' : 'none'}>
|
|
54
|
+
<Divider />
|
|
55
|
+
<FlatList<MonthListItem>
|
|
56
|
+
style={styles.list}
|
|
57
|
+
data={monthItems}
|
|
58
|
+
renderItem={({ item }) => (
|
|
59
|
+
<Month
|
|
60
|
+
month={item.id}
|
|
61
|
+
monthStyles={datePickerMonthPickerStyles.root}
|
|
62
|
+
locale={locale}
|
|
63
|
+
/>
|
|
64
|
+
)}
|
|
65
|
+
keyExtractor={item => `${item.id}`}
|
|
66
|
+
/>
|
|
67
|
+
</View>
|
|
68
|
+
</List>
|
|
73
69
|
);
|
|
74
70
|
}
|
|
75
71
|
|
|
76
72
|
function MonthPure({
|
|
77
73
|
month,
|
|
78
|
-
selected,
|
|
79
|
-
onPressMonth,
|
|
80
74
|
monthStyles,
|
|
81
75
|
locale,
|
|
82
76
|
}: {
|
|
83
77
|
month: number;
|
|
84
|
-
selected: boolean;
|
|
85
|
-
onPressMonth: (newMonth: number) => any;
|
|
86
78
|
monthStyles: ViewStyle;
|
|
87
79
|
locale?: DatePickerLocale;
|
|
88
80
|
}) {
|
|
81
|
+
const isSelected = useListContextValue(state => {
|
|
82
|
+
const selectedValue = state.value as any;
|
|
83
|
+
return (selectedValue?.id ?? selectedValue) === month;
|
|
84
|
+
});
|
|
85
|
+
|
|
89
86
|
const state = resolveStateVariant({
|
|
90
|
-
selected,
|
|
87
|
+
selected: isSelected,
|
|
91
88
|
});
|
|
92
89
|
|
|
93
90
|
datePickerMonthItemStyles.useVariants({
|
|
@@ -99,44 +96,38 @@ function MonthPure({
|
|
|
99
96
|
|
|
100
97
|
return {
|
|
101
98
|
monthButtonStyle: [monthButton, monthStyles],
|
|
102
|
-
accessibilityState: { selected },
|
|
99
|
+
accessibilityState: { selected: isSelected },
|
|
103
100
|
};
|
|
104
|
-
|
|
105
|
-
}, [selected, monthStyles, state]);
|
|
101
|
+
}, [isSelected, monthStyles]);
|
|
106
102
|
|
|
107
103
|
const monthLabel = useMemo(
|
|
108
|
-
() =>
|
|
109
|
-
new Intl.DateTimeFormat(locale, { month: 'long' }).format(new Date(2000, month, 1)),
|
|
104
|
+
() => new Intl.DateTimeFormat(locale, { month: 'long' }).format(new Date(2000, month, 1)),
|
|
110
105
|
[locale, month],
|
|
111
106
|
);
|
|
112
107
|
|
|
113
|
-
const handleMonthPress = useCallback(() => {
|
|
114
|
-
onPressMonth(month);
|
|
115
|
-
}, [onPressMonth, month]);
|
|
116
|
-
|
|
117
108
|
return (
|
|
118
|
-
<
|
|
119
|
-
|
|
109
|
+
<List.Item
|
|
110
|
+
value={month}
|
|
120
111
|
accessibilityRole="button"
|
|
121
112
|
accessibilityLabel={String(month)}
|
|
122
113
|
accessibilityState={accessibilityState}
|
|
123
114
|
style={monthButtonStyle}
|
|
124
|
-
testID={`pick-month-${month}`}
|
|
125
|
-
|
|
126
|
-
|
|
115
|
+
testID={`pick-month-${month}`}>
|
|
116
|
+
<View style={styles.left}>
|
|
117
|
+
{isSelected ? (
|
|
127
118
|
<View style={styles.checkIconView}>
|
|
128
119
|
<Icon name="check" size={24} />
|
|
129
120
|
</View>
|
|
130
121
|
) : (
|
|
131
122
|
<View style={styles.spacer} />
|
|
132
|
-
)
|
|
133
|
-
|
|
123
|
+
)}
|
|
124
|
+
</View>
|
|
134
125
|
<View style={datePickerMonthItemStyles.monthInner}>
|
|
135
126
|
<Text style={datePickerMonthItemStyles.monthLabel} selectable={false}>
|
|
136
127
|
{monthLabel}
|
|
137
128
|
</Text>
|
|
138
129
|
</View>
|
|
139
|
-
</
|
|
130
|
+
</List.Item>
|
|
140
131
|
);
|
|
141
132
|
}
|
|
142
133
|
const Month = memo(MonthPure);
|
|
@@ -155,6 +146,9 @@ const styles = StyleSheet.create(theme => ({
|
|
|
155
146
|
spacer: {
|
|
156
147
|
width: 44,
|
|
157
148
|
},
|
|
149
|
+
left: {
|
|
150
|
+
marginRight: theme.spacings['2'],
|
|
151
|
+
},
|
|
158
152
|
|
|
159
153
|
list: {
|
|
160
154
|
flex: 1,
|
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
} from 'react-native';
|
|
10
10
|
|
|
11
11
|
import AutoSizer from './AutoSizer';
|
|
12
|
-
import { useDatePickerStore } from './DatePickerContext';
|
|
13
12
|
import { beginOffset, estimatedMonthHeight, getInitialIndex, totalMonths } from './dateUtils';
|
|
14
13
|
import { addMonths, getRealIndex } from './dateUtils';
|
|
15
14
|
import {
|
|
@@ -18,6 +17,7 @@ import {
|
|
|
18
17
|
getMonthHeight,
|
|
19
18
|
getVerticalMonthsOffset,
|
|
20
19
|
} from './Month';
|
|
20
|
+
import { useDatePickerInlineStore } from './store';
|
|
21
21
|
import type { SwiperProps } from './SwiperUtils';
|
|
22
22
|
import { montHeaderHeight } from './utils';
|
|
23
23
|
|
|
@@ -56,7 +56,7 @@ function SwiperInner({
|
|
|
56
56
|
);
|
|
57
57
|
|
|
58
58
|
const parentRef = useRef<ScrollView | null>(null);
|
|
59
|
-
const [{ localDate }, setStore] =
|
|
59
|
+
const [{ localDate }, setStore] = useDatePickerInlineStore(state => state);
|
|
60
60
|
|
|
61
61
|
const scrollTo = useCallback(
|
|
62
62
|
(index: number, animated: boolean) => {
|
|
@@ -12,10 +12,10 @@ import {
|
|
|
12
12
|
|
|
13
13
|
import { useLatest } from '../../hooks';
|
|
14
14
|
import AutoSizer from './AutoSizer';
|
|
15
|
-
import { useDatePickerStore } from './DatePickerContext';
|
|
16
15
|
import { beginOffset, estimatedMonthHeight, getInitialIndex, totalMonths } from './dateUtils';
|
|
17
16
|
import { addMonths, getRealIndex } from './dateUtils';
|
|
18
17
|
import { getIndexFromVerticalOffset, getMonthHeight, getVerticalMonthsOffset } from './Month';
|
|
18
|
+
import { useDatePickerInlineStore } from './store';
|
|
19
19
|
import type { SwiperProps } from './SwiperUtils';
|
|
20
20
|
import { montHeaderHeight } from './utils';
|
|
21
21
|
|
|
@@ -73,7 +73,7 @@ function HorizontalScroller({
|
|
|
73
73
|
visibleHorizontalArray(initialIndex),
|
|
74
74
|
);
|
|
75
75
|
const parentRef = useRef<HTMLDivElement | null>(null);
|
|
76
|
-
const [{ localDate }, setStore] =
|
|
76
|
+
const [{ localDate }, setStore] = useDatePickerInlineStore(state => state);
|
|
77
77
|
const settleTimerRef = useRef<number | null>(null);
|
|
78
78
|
const isRecenteringRef = useRef(false);
|
|
79
79
|
|
|
@@ -209,7 +209,7 @@ function VerticalScroller({
|
|
|
209
209
|
const [visibleIndexes, setVisibleIndexes] = useState<number[]>(visibleArray(initialIndex));
|
|
210
210
|
|
|
211
211
|
const parentRef = useRef<HTMLDivElement | null>(null);
|
|
212
|
-
const [{ localDate }, setStore] =
|
|
212
|
+
const [{ localDate }, setStore] = useDatePickerInlineStore(state => state);
|
|
213
213
|
|
|
214
214
|
useIsomorphicLayoutEffect(() => {
|
|
215
215
|
const element = parentRef.current;
|