react-native-molecules 0.5.0-beta.20 → 0.5.0-beta.21
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/Checkbox/CheckboxBase.ios.tsx +10 -14
- package/components/Checkbox/CheckboxBase.tsx +13 -15
- package/components/DateField/DateField.tsx +4 -3
- package/components/DatePicker/DatePickerModal.tsx +33 -22
- package/components/DatePicker/DatePickerProvider.tsx +8 -2
- package/components/DatePicker/context.tsx +2 -1
- package/components/DatePicker/index.tsx +1 -0
- package/components/DatePickerInline/DatePickerDockedHeader.tsx +8 -4
- package/components/DatePickerInline/DatePickerInlineBase.tsx +1 -1
- package/components/DatePickerInline/DatePickerInlineHeader.tsx +8 -4
- package/components/DatePickerInline/DayNames.tsx +13 -10
- package/components/DatePickerInline/Month.tsx +4 -3
- package/components/DatePickerInline/MonthPicker.tsx +14 -4
- package/components/DatePickerInline/types.ts +3 -2
- package/components/TimeField/TimeField.tsx +1 -1
- package/components/TimePicker/TimePickerModal.tsx +15 -15
- package/package.json +1 -1
|
@@ -37,20 +37,16 @@ const CheckboxIOS = (
|
|
|
37
37
|
state: state as States,
|
|
38
38
|
size,
|
|
39
39
|
});
|
|
40
|
+
const checkedColor = colorProp;
|
|
40
41
|
|
|
41
|
-
const {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
rippleContainerStyles: [styles.root, style],
|
|
50
|
-
iconContainerStyles: { opacity: indeterminate || checked ? 1 : 0 },
|
|
51
|
-
};
|
|
52
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
53
|
-
}, [checked, colorProp, indeterminate, style, state, size]);
|
|
42
|
+
const { rippleColor, rippleContainerStyles, iconContainerStyles } = useMemo(() => {
|
|
43
|
+
return {
|
|
44
|
+
rippleColor: setColor(checkedColor).fade(0.32).rgb().string(),
|
|
45
|
+
rippleContainerStyles: [styles.root, style],
|
|
46
|
+
iconContainerStyles: { opacity: indeterminate || checked ? 1 : 0 },
|
|
47
|
+
};
|
|
48
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
49
|
+
}, [checked, colorProp, indeterminate, style, state, size, checkedColor]);
|
|
54
50
|
|
|
55
51
|
const onChange = useCallback(() => {
|
|
56
52
|
onChangeProp?.(!checked);
|
|
@@ -76,7 +72,7 @@ const CheckboxIOS = (
|
|
|
76
72
|
allowFontScaling={false}
|
|
77
73
|
type="material-community"
|
|
78
74
|
name={icon}
|
|
79
|
-
size={
|
|
75
|
+
size={iconSizeMap[size]}
|
|
80
76
|
color={checkedColor}
|
|
81
77
|
/>
|
|
82
78
|
</View>
|
|
@@ -51,20 +51,18 @@ const CheckboxAndroid = (
|
|
|
51
51
|
size,
|
|
52
52
|
});
|
|
53
53
|
|
|
54
|
-
const {
|
|
55
|
-
|
|
56
|
-
const _color = tokenStylesParser.getColor(checked ? colorProp : uncheckedColorProp);
|
|
54
|
+
const { rippleColor, rippleContainerStyles, iconStyle } = useMemo(() => {
|
|
55
|
+
const _color = tokenStylesParser.getColor(checked ? colorProp : uncheckedColorProp);
|
|
57
56
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}, [checked, colorProp, uncheckedColorProp, size, style, stateLayerProps?.style]);
|
|
57
|
+
return {
|
|
58
|
+
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
|
+
rippleContainerStyles: [styles.root, style],
|
|
63
|
+
};
|
|
64
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
65
|
+
}, [checked, colorProp, uncheckedColorProp, style, size, state]);
|
|
68
66
|
|
|
69
67
|
const onChange = useCallback(() => {
|
|
70
68
|
onChangeProp?.(!checked);
|
|
@@ -96,13 +94,13 @@ const CheckboxAndroid = (
|
|
|
96
94
|
allowFontScaling={false}
|
|
97
95
|
type="material-community"
|
|
98
96
|
name={icon}
|
|
99
|
-
size={
|
|
97
|
+
size={iconSizeMap[size]}
|
|
100
98
|
style={iconStyle}
|
|
101
99
|
/>
|
|
102
100
|
<StateLayer
|
|
103
101
|
testID={testID ? `${testID}-stateLayer` : ''}
|
|
104
102
|
{...stateLayerProps}
|
|
105
|
-
style={
|
|
103
|
+
style={[styles.stateLayer, stateLayerProps?.style]}
|
|
106
104
|
/>
|
|
107
105
|
</>
|
|
108
106
|
</TouchableRipple>
|
|
@@ -14,6 +14,7 @@ export type DateFieldProps = Omit<
|
|
|
14
14
|
> & {
|
|
15
15
|
inputMode?: DateFieldInputMode;
|
|
16
16
|
dateFormat?: string;
|
|
17
|
+
mask?: string;
|
|
17
18
|
};
|
|
18
19
|
|
|
19
20
|
const DEFAULT_DATE_FORMAT = 'dd/MM/yyyy';
|
|
@@ -93,13 +94,13 @@ function DateField({
|
|
|
93
94
|
|
|
94
95
|
return (
|
|
95
96
|
<TextInputWithMask
|
|
97
|
+
placeholder={dateFormat}
|
|
98
|
+
keyboardType="number-pad"
|
|
99
|
+
mask={dateFormat}
|
|
96
100
|
{...rest}
|
|
97
101
|
ref={ref}
|
|
98
102
|
disabled={disabled}
|
|
99
103
|
value={formattedValue}
|
|
100
|
-
placeholder={dateFormat}
|
|
101
|
-
keyboardType="number-pad"
|
|
102
|
-
mask={dateFormat}
|
|
103
104
|
onChangeText={onChangeText}
|
|
104
105
|
onBlur={onInnerBlur}
|
|
105
106
|
onFocus={onInnerFocus}
|
|
@@ -10,14 +10,13 @@ import {
|
|
|
10
10
|
} from 'react-native';
|
|
11
11
|
|
|
12
12
|
import { getRegisteredComponentWithFallback } from '../../core';
|
|
13
|
-
import { format } from '../../utils/date-fns';
|
|
14
13
|
import { DateField } from '../DateField';
|
|
15
14
|
import { IconButton } from '../IconButton';
|
|
16
15
|
import { Modal, type ModalProps } from '../Modal';
|
|
17
16
|
import { Portal } from '../Portal';
|
|
18
17
|
import { Text } from '../Text';
|
|
19
18
|
import { TextInput } from '../TextInput';
|
|
20
|
-
import type { DatePickerContextType, DatePickerValue } from './context';
|
|
19
|
+
import type { DatePickerContextType, DatePickerLocale, DatePickerValue } from './context';
|
|
21
20
|
import {
|
|
22
21
|
DatePickerContext,
|
|
23
22
|
useDatePickerContext,
|
|
@@ -42,6 +41,12 @@ export type DatePickerModalProps = Omit<ModalProps, 'children' | 'isOpen' | 'onC
|
|
|
42
41
|
cancelLabel?: string;
|
|
43
42
|
editIcon?: string;
|
|
44
43
|
calendarIcon?: string;
|
|
44
|
+
emptySummaryLabel?: string;
|
|
45
|
+
editingSummaryLabel?: string;
|
|
46
|
+
dateInputLabel?: string;
|
|
47
|
+
showCalendarAccessibilityLabel?: string;
|
|
48
|
+
enterDateManuallyAccessibilityLabel?: string;
|
|
49
|
+
locale?: DatePickerLocale;
|
|
45
50
|
headerLayout?: 'inline' | 'docked';
|
|
46
51
|
/** Override the surface default draft mode. Modal defaults to `true` (staged commit). */
|
|
47
52
|
draft?: boolean;
|
|
@@ -59,6 +64,11 @@ function DatePickerModalBody({
|
|
|
59
64
|
cancelLabel = 'Cancel',
|
|
60
65
|
editIcon = 'pencil',
|
|
61
66
|
calendarIcon = 'calendar',
|
|
67
|
+
emptySummaryLabel = 'Select date',
|
|
68
|
+
editingSummaryLabel = 'Enter dates',
|
|
69
|
+
dateInputLabel = 'Date',
|
|
70
|
+
showCalendarAccessibilityLabel = 'Show calendar',
|
|
71
|
+
enterDateManuallyAccessibilityLabel = 'Enter date manually',
|
|
62
72
|
headerLayout,
|
|
63
73
|
...rest
|
|
64
74
|
}: BodyProps) {
|
|
@@ -97,15 +107,19 @@ function DatePickerModalBody({
|
|
|
97
107
|
: ctx.draftValue;
|
|
98
108
|
|
|
99
109
|
const summaryLabel = useMemo(() => {
|
|
100
|
-
if (editing) return
|
|
101
|
-
if (!draft) return
|
|
102
|
-
return
|
|
103
|
-
|
|
110
|
+
if (editing) return editingSummaryLabel;
|
|
111
|
+
if (!draft) return emptySummaryLabel;
|
|
112
|
+
return new Intl.DateTimeFormat(ctx.locale, {
|
|
113
|
+
weekday: 'short',
|
|
114
|
+
month: 'short',
|
|
115
|
+
day: 'numeric',
|
|
116
|
+
}).format(draft);
|
|
117
|
+
}, [ctx.locale, draft, editing, editingSummaryLabel, emptySummaryLabel]);
|
|
104
118
|
|
|
105
119
|
const body = editing ? (
|
|
106
120
|
<View style={datePickerModalStyles.inputContainer}>
|
|
107
121
|
<DateField autoFocus>
|
|
108
|
-
<TextInput.Label>
|
|
122
|
+
<TextInput.Label>{dateInputLabel}</TextInput.Label>
|
|
109
123
|
</DateField>
|
|
110
124
|
</View>
|
|
111
125
|
) : (
|
|
@@ -139,7 +153,9 @@ function DatePickerModalBody({
|
|
|
139
153
|
<IconButton
|
|
140
154
|
name={editing ? calendarIcon : editIcon}
|
|
141
155
|
accessibilityLabel={
|
|
142
|
-
editing
|
|
156
|
+
editing
|
|
157
|
+
? showCalendarAccessibilityLabel
|
|
158
|
+
: enterDateManuallyAccessibilityLabel
|
|
143
159
|
}
|
|
144
160
|
onPress={() => setEditing(prev => !prev)}
|
|
145
161
|
style={datePickerModalStyles.modeToggle}
|
|
@@ -161,31 +177,24 @@ function DatePickerModalBody({
|
|
|
161
177
|
function DatePickerModalLayer({
|
|
162
178
|
base,
|
|
163
179
|
draft: draftProp,
|
|
164
|
-
|
|
165
|
-
}: {
|
|
180
|
+
...rest
|
|
181
|
+
}: BodyProps & {
|
|
166
182
|
base: DatePickerContextType;
|
|
167
183
|
draft: boolean | undefined;
|
|
168
|
-
bodyProps: BodyProps;
|
|
169
184
|
}) {
|
|
170
185
|
const effectiveDraft = draftProp ?? base.providerDraft ?? true;
|
|
171
186
|
const ctx = useMemo(() => withDraftLayer(base, effectiveDraft), [base, effectiveDraft]);
|
|
172
187
|
if (!base.open) return null;
|
|
173
188
|
return (
|
|
174
189
|
<DatePickerContext value={ctx}>
|
|
175
|
-
<DatePickerModalBody {...
|
|
190
|
+
<DatePickerModalBody {...rest} />
|
|
176
191
|
</DatePickerContext>
|
|
177
192
|
);
|
|
178
193
|
}
|
|
179
194
|
|
|
180
|
-
function DatePickerModalAdapter({
|
|
181
|
-
draft,
|
|
182
|
-
bodyProps,
|
|
183
|
-
}: {
|
|
184
|
-
draft: boolean | undefined;
|
|
185
|
-
bodyProps: BodyProps;
|
|
186
|
-
}) {
|
|
195
|
+
function DatePickerModalAdapter({ draft, ...rest }: BodyProps & { draft: boolean | undefined }) {
|
|
187
196
|
const base = useDatePickerContext();
|
|
188
|
-
return <DatePickerModalLayer base={base} draft={draft}
|
|
197
|
+
return <DatePickerModalLayer base={base} draft={draft} {...rest} />;
|
|
189
198
|
}
|
|
190
199
|
|
|
191
200
|
function DatePickerModalInner({
|
|
@@ -193,6 +202,7 @@ function DatePickerModalInner({
|
|
|
193
202
|
onClose: onCloseProp,
|
|
194
203
|
value: valueProp,
|
|
195
204
|
onChange: onChangeProp,
|
|
205
|
+
locale,
|
|
196
206
|
draft: draftProp,
|
|
197
207
|
...rest
|
|
198
208
|
}: DatePickerModalProps) {
|
|
@@ -206,7 +216,7 @@ function DatePickerModalInner({
|
|
|
206
216
|
);
|
|
207
217
|
|
|
208
218
|
if (outer) {
|
|
209
|
-
return <DatePickerModalLayer base={outer} draft={draftProp}
|
|
219
|
+
return <DatePickerModalLayer base={outer} draft={draftProp} {...rest} />;
|
|
210
220
|
}
|
|
211
221
|
|
|
212
222
|
return (
|
|
@@ -214,8 +224,9 @@ function DatePickerModalInner({
|
|
|
214
224
|
value={valueProp}
|
|
215
225
|
onChange={onChangeProp}
|
|
216
226
|
open={isOpenProp}
|
|
227
|
+
locale={locale}
|
|
217
228
|
onOpenChange={onOpenChange}>
|
|
218
|
-
<DatePickerModalAdapter draft={draftProp}
|
|
229
|
+
<DatePickerModalAdapter draft={draftProp} {...rest} />
|
|
219
230
|
</DatePickerProvider>
|
|
220
231
|
);
|
|
221
232
|
}
|
|
@@ -4,7 +4,13 @@ import { memo, useCallback, useMemo, useRef, useState } from 'react';
|
|
|
4
4
|
import { getRegisteredComponentWithFallback } from '../../core';
|
|
5
5
|
import { useControlledValue } from '../../hooks';
|
|
6
6
|
import type { ValidRangeType } from '../DatePickerInline';
|
|
7
|
-
import type {
|
|
7
|
+
import type {
|
|
8
|
+
DatePickerContextType,
|
|
9
|
+
DatePickerLocale,
|
|
10
|
+
DatePickerMode,
|
|
11
|
+
DatePickerValue,
|
|
12
|
+
RangeValue,
|
|
13
|
+
} from './context';
|
|
8
14
|
import { DatePickerContext, withDraftLayer } from './context';
|
|
9
15
|
|
|
10
16
|
const DATE_FORMAT_BY_MODE: Record<DatePickerMode, string> = {
|
|
@@ -30,7 +36,7 @@ export type DatePickerProviderProps = {
|
|
|
30
36
|
defaultOpen?: boolean;
|
|
31
37
|
onOpenChange?: (open: boolean) => void;
|
|
32
38
|
|
|
33
|
-
locale?:
|
|
39
|
+
locale?: DatePickerLocale;
|
|
34
40
|
validRange?: ValidRangeType;
|
|
35
41
|
is24Hour?: boolean;
|
|
36
42
|
dateFormat?: string;
|
|
@@ -5,6 +5,7 @@ import type { ValidRangeType } from '../DatePickerInline';
|
|
|
5
5
|
import { registerPortalContext } from '../Portal';
|
|
6
6
|
|
|
7
7
|
export type DatePickerMode = 'date' | 'time' | 'datetime' | 'range';
|
|
8
|
+
export type DatePickerLocale = Intl.LocalesArgument;
|
|
8
9
|
|
|
9
10
|
export type DateValue = Date | null;
|
|
10
11
|
export type RangeValue = { start: Date | null; end: Date | null };
|
|
@@ -35,7 +36,7 @@ export type DatePickerContextType = {
|
|
|
35
36
|
open: boolean;
|
|
36
37
|
setOpen: (open: boolean) => void;
|
|
37
38
|
triggerRef: RefObject<any>;
|
|
38
|
-
locale?:
|
|
39
|
+
locale?: DatePickerLocale;
|
|
39
40
|
validRange?: ValidRangeType;
|
|
40
41
|
is24Hour: boolean;
|
|
41
42
|
dateFormat: string;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { add,
|
|
1
|
+
import { add, setYear } from 'date-fns';
|
|
2
2
|
import { memo, useCallback, useMemo } from 'react';
|
|
3
3
|
import { View, type ViewStyle } from 'react-native';
|
|
4
4
|
import { StyleSheet } from 'react-native-unistyles';
|
|
5
5
|
|
|
6
|
+
import type { DatePickerLocale } from '../DatePicker/context';
|
|
6
7
|
import { useDatePickerStoreRef, useDatePickerStoreValue } from './DatePickerContext';
|
|
7
8
|
import type { DisableWeekDaysType } from './dateUtils';
|
|
8
9
|
import DayNames from './DayNames';
|
|
@@ -10,7 +11,7 @@ import HeaderItem from './HeaderItem';
|
|
|
10
11
|
import { datePickerHeaderStyles } from './utils';
|
|
11
12
|
|
|
12
13
|
export type DockedHeaderProps = {
|
|
13
|
-
locale?:
|
|
14
|
+
locale?: DatePickerLocale;
|
|
14
15
|
scrollMode: 'horizontal' | 'vertical';
|
|
15
16
|
disableWeekDays?: DisableWeekDaysType;
|
|
16
17
|
style?: ViewStyle;
|
|
@@ -30,8 +31,11 @@ function DatePickerDockedHeader({
|
|
|
30
31
|
const isHorizontal = scrollMode === 'horizontal';
|
|
31
32
|
|
|
32
33
|
const { monthName, year } = useMemo(
|
|
33
|
-
() => ({
|
|
34
|
-
|
|
34
|
+
() => ({
|
|
35
|
+
monthName: new Intl.DateTimeFormat(locale, { month: 'short' }).format(localDate),
|
|
36
|
+
year: localDate.getFullYear(),
|
|
37
|
+
}),
|
|
38
|
+
[localDate, locale],
|
|
35
39
|
);
|
|
36
40
|
|
|
37
41
|
const handleMonthDropdown = useCallback(() => {
|
|
@@ -173,7 +173,7 @@ function DatePickerInlineBaseChild(props: DatePickerInlineBaseProps) {
|
|
|
173
173
|
{isHorizontal && pickerType === 'year' && (
|
|
174
174
|
<YearPicker layout={headerLayout === 'docked' ? 'list' : 'grid'} />
|
|
175
175
|
)}
|
|
176
|
-
{isHorizontal && pickerType === 'month' && <MonthPicker />}
|
|
176
|
+
{isHorizontal && pickerType === 'month' && <MonthPicker locale={locale} />}
|
|
177
177
|
</View>
|
|
178
178
|
);
|
|
179
179
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { add
|
|
1
|
+
import { add } 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
|
+
import type { DatePickerLocale } from '../DatePicker/context';
|
|
5
6
|
import { useDatePickerStore, useDatePickerStoreValue } from './DatePickerContext';
|
|
6
7
|
import type { DisableWeekDaysType } from './dateUtils';
|
|
7
8
|
import DayNames from './DayNames';
|
|
@@ -13,7 +14,7 @@ const buttonContainerMarginTop = 4;
|
|
|
13
14
|
const buttonContainerMarginBottom = 8;
|
|
14
15
|
|
|
15
16
|
export type CalendarHeaderProps = {
|
|
16
|
-
locale?:
|
|
17
|
+
locale?: DatePickerLocale;
|
|
17
18
|
scrollMode: 'horizontal' | 'vertical';
|
|
18
19
|
disableWeekDays?: DisableWeekDaysType;
|
|
19
20
|
style?: ViewStyle;
|
|
@@ -35,8 +36,11 @@ function DatePickerInlineHeader({
|
|
|
35
36
|
const { monthName, year } = useMemo(() => {
|
|
36
37
|
const y = localDate.getFullYear();
|
|
37
38
|
|
|
38
|
-
return {
|
|
39
|
-
|
|
39
|
+
return {
|
|
40
|
+
monthName: new Intl.DateTimeFormat(locale, { month: 'long' }).format(localDate),
|
|
41
|
+
year: y,
|
|
42
|
+
};
|
|
43
|
+
}, [localDate, locale]);
|
|
40
44
|
|
|
41
45
|
const { containerStyle } = useMemo(() => {
|
|
42
46
|
// const { datePickerHeader, buttonContainer, buttonWrapper, spacer, ...rest } =
|
|
@@ -1,23 +1,26 @@
|
|
|
1
|
-
import { memo } from 'react';
|
|
1
|
+
import { memo, useMemo } from 'react';
|
|
2
2
|
import { View } from 'react-native';
|
|
3
3
|
|
|
4
|
-
import { addDays,
|
|
4
|
+
import { addDays, startOfWeek } from '../../utils/date-fns';
|
|
5
|
+
import type { DatePickerLocale } from '../DatePicker/context';
|
|
5
6
|
import { type DisableWeekDaysType, showWeekDay } from './dateUtils';
|
|
6
7
|
import DayName from './DayName';
|
|
7
8
|
import { dateDayNameStyles } from './utils';
|
|
8
9
|
|
|
9
|
-
const shortDayNames = (() => {
|
|
10
|
-
const firstDOW = startOfWeek(new Date());
|
|
11
|
-
return Array.from(Array(7)).map((_, i) => format(addDays(firstDOW, i), 'EEEEE'));
|
|
12
|
-
})();
|
|
13
|
-
|
|
14
10
|
function DayNames({
|
|
15
11
|
disableWeekDays,
|
|
16
|
-
|
|
17
|
-
{
|
|
12
|
+
locale,
|
|
13
|
+
}: {
|
|
18
14
|
disableWeekDays?: DisableWeekDaysType;
|
|
19
|
-
locale?:
|
|
15
|
+
locale?: DatePickerLocale;
|
|
20
16
|
}) {
|
|
17
|
+
const shortDayNames = useMemo(() => {
|
|
18
|
+
const firstDOW = startOfWeek(new Date());
|
|
19
|
+
return Array.from(Array(7)).map((_, i) =>
|
|
20
|
+
new Intl.DateTimeFormat(locale, { weekday: 'narrow' }).format(addDays(firstDOW, i)),
|
|
21
|
+
);
|
|
22
|
+
}, [locale]);
|
|
23
|
+
|
|
21
24
|
return (
|
|
22
25
|
<View style={dateDayNameStyles.container} pointerEvents={'none'}>
|
|
23
26
|
{shortDayNames
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { memo, useMemo } from 'react';
|
|
2
2
|
import { View } from 'react-native';
|
|
3
3
|
|
|
4
|
-
import { format } from '../../utils/date-fns';
|
|
5
4
|
import { Text } from '../Text';
|
|
6
5
|
import { getCalendarHeaderHeight } from './DatePickerInlineHeader';
|
|
7
6
|
import {
|
|
@@ -43,6 +42,7 @@ function Month(props: MonthSingleProps | MonthRangeProps | MonthMultiProps) {
|
|
|
43
42
|
disableWeekDays,
|
|
44
43
|
validRange,
|
|
45
44
|
showOutsideDays,
|
|
45
|
+
locale,
|
|
46
46
|
// customMonthStyles,
|
|
47
47
|
} = props;
|
|
48
48
|
const isHorizontal = scrollMode === 'horizontal';
|
|
@@ -54,9 +54,10 @@ function Month(props: MonthSingleProps | MonthRangeProps | MonthMultiProps) {
|
|
|
54
54
|
const md = addMonths(new Date(), realIndex);
|
|
55
55
|
const y = md.getFullYear();
|
|
56
56
|
const m = md.getMonth();
|
|
57
|
+
const name = new Intl.DateTimeFormat(locale, { month: 'long' }).format(md);
|
|
57
58
|
|
|
58
|
-
return { monthName:
|
|
59
|
-
}, [index]);
|
|
59
|
+
return { monthName: name, month: m, year: y };
|
|
60
|
+
}, [index, locale]);
|
|
60
61
|
|
|
61
62
|
const grid = useMemo(
|
|
62
63
|
() =>
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { setMonth } from 'date-fns';
|
|
2
2
|
import { memo, useCallback, useMemo, useRef } from 'react';
|
|
3
3
|
import { FlatList, View, type ViewStyle } from 'react-native';
|
|
4
4
|
import { StyleSheet } from 'react-native-unistyles';
|
|
5
5
|
|
|
6
6
|
import { resolveStateVariant } from '../../utils';
|
|
7
7
|
import { range } from '../../utils/dateTimePicker';
|
|
8
|
+
import type { DatePickerLocale } from '../DatePicker/context';
|
|
8
9
|
import { datePickerMonthItemStyles, datePickerMonthPickerStyles } from '../DatePicker/utils';
|
|
9
10
|
import { HorizontalDivider } from '../HorizontalDivider';
|
|
10
11
|
import { Icon } from '../Icon';
|
|
@@ -12,7 +13,7 @@ import { ListItem } from '../ListItem/';
|
|
|
12
13
|
import { Text } from '../Text';
|
|
13
14
|
import { useDatePickerStore, useDatePickerStoreValue } from './DatePickerContext';
|
|
14
15
|
|
|
15
|
-
export default function MonthPicker() {
|
|
16
|
+
export default function MonthPicker({ locale }: { locale?: DatePickerLocale }) {
|
|
16
17
|
const [_, setStore] = useDatePickerStore(state => state);
|
|
17
18
|
const { localDate, selectingMonth } = useDatePickerStoreValue(state => ({
|
|
18
19
|
localDate: state.localDate,
|
|
@@ -40,10 +41,11 @@ export default function MonthPicker() {
|
|
|
40
41
|
selected={localDate.getMonth() === item}
|
|
41
42
|
onPressMonth={handleOnChange}
|
|
42
43
|
monthStyles={datePickerMonthPickerStyles.root}
|
|
44
|
+
locale={locale}
|
|
43
45
|
/>
|
|
44
46
|
);
|
|
45
47
|
},
|
|
46
|
-
[localDate, handleOnChange],
|
|
48
|
+
[localDate, handleOnChange, locale],
|
|
47
49
|
);
|
|
48
50
|
|
|
49
51
|
if (!selectingMonth) {
|
|
@@ -76,11 +78,13 @@ function MonthPure({
|
|
|
76
78
|
selected,
|
|
77
79
|
onPressMonth,
|
|
78
80
|
monthStyles,
|
|
81
|
+
locale,
|
|
79
82
|
}: {
|
|
80
83
|
month: number;
|
|
81
84
|
selected: boolean;
|
|
82
85
|
onPressMonth: (newMonth: number) => any;
|
|
83
86
|
monthStyles: ViewStyle;
|
|
87
|
+
locale?: DatePickerLocale;
|
|
84
88
|
}) {
|
|
85
89
|
const state = resolveStateVariant({
|
|
86
90
|
selected,
|
|
@@ -100,6 +104,12 @@ function MonthPure({
|
|
|
100
104
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
101
105
|
}, [selected, monthStyles, state]);
|
|
102
106
|
|
|
107
|
+
const monthLabel = useMemo(
|
|
108
|
+
() =>
|
|
109
|
+
new Intl.DateTimeFormat(locale, { month: 'long' }).format(new Date(2000, month, 1)),
|
|
110
|
+
[locale, month],
|
|
111
|
+
);
|
|
112
|
+
|
|
103
113
|
const handleMonthPress = useCallback(() => {
|
|
104
114
|
onPressMonth(month);
|
|
105
115
|
}, [onPressMonth, month]);
|
|
@@ -123,7 +133,7 @@ function MonthPure({
|
|
|
123
133
|
}>
|
|
124
134
|
<View style={datePickerMonthItemStyles.monthInner}>
|
|
125
135
|
<Text style={datePickerMonthItemStyles.monthLabel} selectable={false}>
|
|
126
|
-
{
|
|
136
|
+
{monthLabel}
|
|
127
137
|
</Text>
|
|
128
138
|
</View>
|
|
129
139
|
</ListItem>
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import type { MemoExoticComponent } from 'react';
|
|
2
2
|
import type { ViewStyle } from 'react-native';
|
|
3
3
|
|
|
4
|
+
import type { DatePickerLocale } from '../DatePicker/context';
|
|
4
5
|
import type { CalendarHeaderProps } from './DatePickerInlineHeader';
|
|
5
6
|
import type { DisableWeekDaysType } from './dateUtils';
|
|
6
7
|
|
|
7
8
|
export interface BaseMonthProps {
|
|
8
|
-
locale:
|
|
9
|
+
locale: DatePickerLocale | undefined;
|
|
9
10
|
scrollMode: 'horizontal' | 'vertical';
|
|
10
11
|
disableWeekDays?: DisableWeekDaysType;
|
|
11
12
|
mode: ModeType;
|
|
@@ -47,7 +48,7 @@ export type ValidRangeType = {
|
|
|
47
48
|
};
|
|
48
49
|
|
|
49
50
|
export type BaseDatePickerProps = {
|
|
50
|
-
locale?:
|
|
51
|
+
locale?: DatePickerLocale;
|
|
51
52
|
disableWeekDays?: DisableWeekDaysType;
|
|
52
53
|
validRange?: ValidRangeType;
|
|
53
54
|
startYear?: number;
|
|
@@ -60,11 +60,11 @@ function TimeField({ ref, disabled: disabledProp, onBlur, onFocus, ...rest }: Ti
|
|
|
60
60
|
|
|
61
61
|
return (
|
|
62
62
|
<TextInput
|
|
63
|
+
placeholder={timeFormat[is24Hour ? '24' : '12'].format}
|
|
63
64
|
{...rest}
|
|
64
65
|
ref={ref}
|
|
65
66
|
disabled={disabled}
|
|
66
67
|
value={formatted}
|
|
67
|
-
placeholder={timeFormat[is24Hour ? '24' : '12'].format}
|
|
68
68
|
onChangeText={onChangeText}
|
|
69
69
|
onBlur={onInnerBlur}
|
|
70
70
|
onFocus={onInnerFocus}
|
|
@@ -5,7 +5,11 @@ import { KeyboardAvoidingView, Platform, View } from 'react-native';
|
|
|
5
5
|
import { getRegisteredComponentWithFallback } from '../../core';
|
|
6
6
|
import { useControlledValue } from '../../hooks';
|
|
7
7
|
import { DatePickerActions, DatePickerProvider } from '../DatePicker';
|
|
8
|
-
import type {
|
|
8
|
+
import type {
|
|
9
|
+
DatePickerContextType,
|
|
10
|
+
DatePickerLocale,
|
|
11
|
+
DatePickerValue,
|
|
12
|
+
} from '../DatePicker/context';
|
|
9
13
|
import {
|
|
10
14
|
DatePickerContext,
|
|
11
15
|
useDatePickerContext,
|
|
@@ -32,6 +36,7 @@ export type TimePickerModalProps = Omit<ModalProps, 'children' | 'isOpen' | 'onC
|
|
|
32
36
|
onClose?: () => void;
|
|
33
37
|
value?: DatePickerValue;
|
|
34
38
|
onChange?: (value: DatePickerValue) => void;
|
|
39
|
+
locale?: DatePickerLocale;
|
|
35
40
|
is24Hour?: boolean;
|
|
36
41
|
inputType?: PossibleInputTypes;
|
|
37
42
|
defaultInputType?: PossibleInputTypes;
|
|
@@ -119,31 +124,24 @@ function TimePickerModalBody({
|
|
|
119
124
|
function TimePickerModalLayer({
|
|
120
125
|
base,
|
|
121
126
|
draft: draftProp,
|
|
122
|
-
|
|
123
|
-
}: {
|
|
127
|
+
...rest
|
|
128
|
+
}: BodyProps & {
|
|
124
129
|
base: DatePickerContextType;
|
|
125
130
|
draft: boolean | undefined;
|
|
126
|
-
bodyProps: BodyProps;
|
|
127
131
|
}) {
|
|
128
132
|
const effectiveDraft = draftProp ?? base.providerDraft ?? true;
|
|
129
133
|
const ctx = useMemo(() => withDraftLayer(base, effectiveDraft), [base, effectiveDraft]);
|
|
130
134
|
if (!base.open) return null;
|
|
131
135
|
return (
|
|
132
136
|
<DatePickerContext value={ctx}>
|
|
133
|
-
<TimePickerModalBody {...
|
|
137
|
+
<TimePickerModalBody {...rest} />
|
|
134
138
|
</DatePickerContext>
|
|
135
139
|
);
|
|
136
140
|
}
|
|
137
141
|
|
|
138
|
-
function TimePickerModalAdapter({
|
|
139
|
-
draft,
|
|
140
|
-
bodyProps,
|
|
141
|
-
}: {
|
|
142
|
-
draft: boolean | undefined;
|
|
143
|
-
bodyProps: BodyProps;
|
|
144
|
-
}) {
|
|
142
|
+
function TimePickerModalAdapter({ draft, ...rest }: BodyProps & { draft: boolean | undefined }) {
|
|
145
143
|
const base = useDatePickerContext();
|
|
146
|
-
return <TimePickerModalLayer base={base} draft={draft}
|
|
144
|
+
return <TimePickerModalLayer base={base} draft={draft} {...rest} />;
|
|
147
145
|
}
|
|
148
146
|
|
|
149
147
|
const TimePickerModalDefault = memo(
|
|
@@ -152,6 +150,7 @@ const TimePickerModalDefault = memo(
|
|
|
152
150
|
onClose: onCloseProp,
|
|
153
151
|
value: valueProp,
|
|
154
152
|
onChange: onChangeProp,
|
|
153
|
+
locale,
|
|
155
154
|
is24Hour,
|
|
156
155
|
draft: draftProp,
|
|
157
156
|
...rest
|
|
@@ -159,7 +158,7 @@ const TimePickerModalDefault = memo(
|
|
|
159
158
|
const outer = useOptionalDatePickerContext();
|
|
160
159
|
|
|
161
160
|
if (outer) {
|
|
162
|
-
return <TimePickerModalLayer base={outer} draft={draftProp}
|
|
161
|
+
return <TimePickerModalLayer base={outer} draft={draftProp} {...rest} />;
|
|
163
162
|
}
|
|
164
163
|
|
|
165
164
|
return (
|
|
@@ -168,11 +167,12 @@ const TimePickerModalDefault = memo(
|
|
|
168
167
|
value={valueProp}
|
|
169
168
|
onChange={onChangeProp}
|
|
170
169
|
open={isOpenProp}
|
|
170
|
+
locale={locale}
|
|
171
171
|
onOpenChange={next => {
|
|
172
172
|
if (!next) onCloseProp?.();
|
|
173
173
|
}}
|
|
174
174
|
is24Hour={is24Hour}>
|
|
175
|
-
<TimePickerModalAdapter draft={draftProp}
|
|
175
|
+
<TimePickerModalAdapter draft={draftProp} {...rest} />
|
|
176
176
|
</DatePickerProvider>
|
|
177
177
|
);
|
|
178
178
|
},
|