react-native-molecules 0.5.0-beta.2 → 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.
Files changed (160) hide show
  1. package/README.md +1 -1
  2. package/components/Accordion/Accordion.tsx +2 -6
  3. package/components/Accordion/AccordionItem.tsx +16 -12
  4. package/components/Accordion/AccordionItemContent.tsx +6 -1
  5. package/components/Accordion/AccordionItemHeader.tsx +1 -1
  6. package/components/Accordion/utils.ts +6 -0
  7. package/components/ActivityIndicator/ActivityIndicator.tsx +6 -15
  8. package/components/Appbar/AppbarBase.tsx +18 -13
  9. package/components/Button/Button.tsx +209 -264
  10. package/components/Button/index.tsx +9 -3
  11. package/components/Button/types.ts +16 -2
  12. package/components/Button/utils.ts +230 -208
  13. package/components/Checkbox/CheckboxBase.ios.tsx +10 -14
  14. package/components/Checkbox/CheckboxBase.tsx +14 -121
  15. package/components/Checkbox/utils.ts +0 -25
  16. package/components/Chip/Chip.tsx +40 -52
  17. package/components/Chip/utils.ts +3 -7
  18. package/components/DateField/DateField.tsx +111 -0
  19. package/components/DateField/index.tsx +6 -0
  20. package/components/{DatePickerInput/inputUtils.ts → DateField/useDateFieldState.ts} +17 -49
  21. package/components/DatePicker/DateCalendar.tsx +83 -0
  22. package/components/DatePicker/DatePickerActions.tsx +73 -0
  23. package/components/DatePicker/DatePickerModal.tsx +245 -0
  24. package/components/DatePicker/DatePickerPopover.tsx +79 -0
  25. package/components/DatePicker/DatePickerProvider.tsx +158 -0
  26. package/components/DatePicker/DatePickerTrigger.tsx +23 -0
  27. package/components/DatePicker/context.tsx +83 -0
  28. package/components/DatePicker/index.tsx +45 -0
  29. package/components/DatePicker/utils.ts +293 -0
  30. package/components/DatePickerInline/DatePickerContext.tsx +1 -0
  31. package/components/DatePickerInline/DatePickerDockedHeader.tsx +117 -0
  32. package/components/DatePickerInline/DatePickerInline.tsx +16 -15
  33. package/components/DatePickerInline/DatePickerInlineBase.tsx +8 -2
  34. package/components/DatePickerInline/DatePickerInlineHeader.tsx +8 -4
  35. package/components/DatePickerInline/Day.tsx +25 -1
  36. package/components/DatePickerInline/DayNames.tsx +13 -10
  37. package/components/DatePickerInline/DayRange.tsx +2 -4
  38. package/components/DatePickerInline/HeaderItem.tsx +42 -27
  39. package/components/DatePickerInline/Month.tsx +48 -67
  40. package/components/DatePickerInline/MonthPicker.tsx +38 -44
  41. package/components/DatePickerInline/Swiper.native.tsx +21 -4
  42. package/components/DatePickerInline/Swiper.tsx +168 -13
  43. package/components/DatePickerInline/Week.tsx +6 -1
  44. package/components/DatePickerInline/YearPicker.tsx +206 -53
  45. package/components/DatePickerInline/dateUtils.tsx +17 -12
  46. package/components/DatePickerInline/types.ts +6 -2
  47. package/components/DatePickerInline/utils.ts +66 -29
  48. package/components/Drawer/Drawer.tsx +17 -6
  49. package/components/ElementGroup/ElementGroup.tsx +16 -14
  50. package/components/FilePicker/FilePicker.tsx +48 -78
  51. package/components/FilePicker/index.tsx +2 -1
  52. package/components/FilePicker/utils.ts +9 -0
  53. package/components/HelperText/HelperText.tsx +0 -35
  54. package/components/Icon/iconFactory.tsx +3 -3
  55. package/components/Icon/index.tsx +1 -1
  56. package/components/Icon/types.ts +17 -6
  57. package/components/IconButton/IconButton.tsx +42 -57
  58. package/components/IconButton/utils.ts +142 -33
  59. package/components/ListItem/ListItem.tsx +3 -1
  60. package/components/ListItem/utils.ts +1 -1
  61. package/components/LoadingIndicator/LoadingIndicator.tsx +253 -0
  62. package/components/LoadingIndicator/LoadingIndicator.web.tsx +136 -0
  63. package/components/LoadingIndicator/index.tsx +13 -0
  64. package/components/LoadingIndicator/utils.ts +117 -0
  65. package/components/Menu/Menu.tsx +3 -18
  66. package/components/NavigationRail/NavigationRail.tsx +15 -9
  67. package/components/Popover/Popover.tsx +122 -145
  68. package/components/Popover/PopoverRoot.tsx +74 -0
  69. package/components/Popover/common.ts +50 -34
  70. package/components/Popover/index.ts +18 -1
  71. package/components/Popover/usePlatformMeasure.native.ts +90 -0
  72. package/components/Popover/usePlatformMeasure.ts +118 -0
  73. package/components/Popover/utils.ts +34 -0
  74. package/components/Select/Select.tsx +368 -507
  75. package/components/Select/context.tsx +72 -0
  76. package/components/Select/index.ts +8 -14
  77. package/components/Select/types.ts +2 -4
  78. package/components/Select/utils.ts +144 -0
  79. package/components/Slot/Slot.tsx +244 -0
  80. package/components/Slot/compose-refs.tsx +62 -0
  81. package/components/Slot/index.tsx +8 -0
  82. package/components/Surface/Surface.android.tsx +34 -8
  83. package/components/Surface/Surface.ios.tsx +36 -29
  84. package/components/Surface/Surface.tsx +31 -4
  85. package/components/Surface/utils.ts +44 -30
  86. package/components/Switch/Switch.tsx +8 -2
  87. package/components/Tabs/TabItem.tsx +35 -58
  88. package/components/Tabs/TabLabel.tsx +5 -9
  89. package/components/Tabs/Tabs.tsx +154 -148
  90. package/components/Tabs/utils.ts +15 -2
  91. package/components/TextInput/TextInput.tsx +658 -575
  92. package/components/TextInput/index.tsx +19 -3
  93. package/components/TextInput/types.ts +76 -27
  94. package/components/TextInput/utils.ts +225 -145
  95. package/components/TimeField/TimeField.tsx +75 -0
  96. package/components/TimeField/index.tsx +6 -0
  97. package/components/TimeField/useTimeFieldState.ts +70 -0
  98. package/components/{TimePickerField/sanitizeTime.ts → TimeField/utils.ts} +77 -10
  99. package/components/TimePicker/TimeInput.tsx +87 -37
  100. package/components/TimePicker/TimeInputs.tsx +137 -49
  101. package/components/TimePicker/TimePicker.tsx +73 -10
  102. package/components/TimePicker/TimePickerModal.tsx +186 -0
  103. package/components/TimePicker/context.tsx +17 -0
  104. package/components/TimePicker/index.tsx +15 -3
  105. package/components/TimePicker/utils.ts +93 -0
  106. package/components/Tooltip/Tooltip.tsx +42 -67
  107. package/components/Tooltip/TooltipContent.tsx +32 -5
  108. package/components/Tooltip/TooltipTrigger.tsx +20 -20
  109. package/components/Tooltip/index.tsx +1 -1
  110. package/components/TouchableRipple/TouchableRipple.native.tsx +50 -14
  111. package/components/TouchableRipple/TouchableRipple.tsx +137 -47
  112. package/hocs/withPortal.tsx +1 -1
  113. package/hooks/index.tsx +0 -6
  114. package/hooks/useActionState.tsx +19 -8
  115. package/hooks/useControlledValue.tsx +20 -4
  116. package/hooks/useFilePicker.tsx +6 -16
  117. package/hooks/useWhatHasUpdated.tsx +48 -0
  118. package/package.json +17 -13
  119. package/shortcuts-manager/ShortcutsManager/ShortcutsManager.tsx +5 -2
  120. package/styles/shadow.ts +2 -1
  121. package/styles/themes/LightTheme.tsx +1 -1
  122. package/utils/DocumentPicker/documentPicker.ts +78 -27
  123. package/utils/DocumentPicker/types.ts +0 -1
  124. package/utils/extractPropertiesFromStyles.ts +25 -0
  125. package/utils/extractSubcomponents.ts +89 -0
  126. package/utils/lodash.ts +77 -5
  127. package/components/DatePickerDocked/DatePickerDocked.tsx +0 -30
  128. package/components/DatePickerDocked/DatePickerDockedHeader.tsx +0 -129
  129. package/components/DatePickerDocked/index.tsx +0 -17
  130. package/components/DatePickerDocked/types.ts +0 -11
  131. package/components/DatePickerDocked/utils.ts +0 -157
  132. package/components/DatePickerInput/DatePickerInput.tsx +0 -139
  133. package/components/DatePickerInput/DatePickerInputModal.tsx +0 -48
  134. package/components/DatePickerInput/DatePickerInputWithoutModal.tsx +0 -77
  135. package/components/DatePickerInput/DateRangeInput.tsx +0 -88
  136. package/components/DatePickerInput/index.tsx +0 -10
  137. package/components/DatePickerInput/types.ts +0 -28
  138. package/components/DatePickerInput/utils.ts +0 -15
  139. package/components/DatePickerModal/AnimatedCrossView.tsx +0 -94
  140. package/components/DatePickerModal/CalendarEdit.tsx +0 -139
  141. package/components/DatePickerModal/DatePickerModal.tsx +0 -85
  142. package/components/DatePickerModal/DatePickerModalContent.tsx +0 -155
  143. package/components/DatePickerModal/DatePickerModalContentHeader.tsx +0 -213
  144. package/components/DatePickerModal/DatePickerModalHeader.tsx +0 -74
  145. package/components/DatePickerModal/DatePickerModalHeaderBackground.tsx +0 -13
  146. package/components/DatePickerModal/index.tsx +0 -16
  147. package/components/DatePickerModal/types.ts +0 -92
  148. package/components/DatePickerModal/utils.ts +0 -122
  149. package/components/DateTimePicker/DateTimePicker.tsx +0 -172
  150. package/components/DateTimePicker/index.tsx +0 -10
  151. package/components/DateTimePicker/utils.ts +0 -12
  152. package/components/Popover/Popover.native.tsx +0 -185
  153. package/components/TimePickerField/TimePickerField.tsx +0 -152
  154. package/components/TimePickerField/index.tsx +0 -10
  155. package/components/TimePickerField/utils.ts +0 -94
  156. package/components/TimePickerModal/TimePickerModal.tsx +0 -115
  157. package/components/TimePickerModal/index.tsx +0 -10
  158. package/components/TimePickerModal/utils.ts +0 -47
  159. package/hooks/useSearchable.tsx +0 -74
  160. package/hooks/useSubcomponents.tsx +0 -59
@@ -0,0 +1,45 @@
1
+ import { DateCalendar } from './DateCalendar';
2
+ import { DatePickerActions } from './DatePickerActions';
3
+ import { DatePickerModal } from './DatePickerModal';
4
+ import { DatePickerPopover } from './DatePickerPopover';
5
+ import { DatePickerProvider } from './DatePickerProvider';
6
+ import { DatePickerTrigger } from './DatePickerTrigger';
7
+
8
+ export const DatePicker = {
9
+ Provider: DatePickerProvider,
10
+ Trigger: DatePickerTrigger,
11
+ Actions: DatePickerActions,
12
+ Calendar: DateCalendar,
13
+ Modal: DatePickerModal,
14
+ Popover: DatePickerPopover,
15
+ };
16
+
17
+ export type {
18
+ DatePickerContextType,
19
+ DatePickerLocale,
20
+ DatePickerMode,
21
+ DatePickerValue,
22
+ DateValue,
23
+ RangeValue,
24
+ } from './context';
25
+ export { DatePickerContext, useDatePickerContext, useOptionalDatePickerContext } from './context';
26
+ export type { DateCalendarProps } from './DateCalendar';
27
+ export type { DatePickerActionsProps } from './DatePickerActions';
28
+ export { DatePickerActions } from './DatePickerActions';
29
+ export type { DatePickerModalProps } from './DatePickerModal';
30
+ export { DatePickerModal } from './DatePickerModal';
31
+ export type { DatePickerPopoverProps } from './DatePickerPopover';
32
+ export { DatePickerPopover } from './DatePickerPopover';
33
+ export type { DatePickerProviderProps } from './DatePickerProvider';
34
+ export { DatePickerProvider } from './DatePickerProvider';
35
+ export { DatePickerTrigger } from './DatePickerTrigger';
36
+ export {
37
+ datePickerHeaderItemStyles,
38
+ datePickerModalContentHeaderStyles,
39
+ datePickerModalEditStyles,
40
+ datePickerModalHeaderBackgroundStyles,
41
+ datePickerModalHeaderStyles,
42
+ datePickerModalStyles,
43
+ datePickerMonthItemStyles,
44
+ datePickerMonthPickerStyles,
45
+ } from './utils';
@@ -0,0 +1,293 @@
1
+ import { StyleSheet } from 'react-native-unistyles';
2
+
3
+ import { getRegisteredComponentStylesWithFallback } from '../../core';
4
+
5
+ const datePickerModalStylesDefault = StyleSheet.create(theme => ({
6
+ header: {
7
+ // backgroundColor: theme.colors.surfaceContainerHighest,
8
+ },
9
+ content: {
10
+ minWidth: 420,
11
+ width: 420,
12
+ maxWidth: undefined,
13
+ flex: undefined,
14
+ borderRadius: theme.shapes.corner.extraLarge,
15
+ overflow: 'hidden',
16
+ },
17
+ frame: {
18
+ // backgroundColor: theme.colors.surfaceContainerHighest,
19
+ width: '100%',
20
+ },
21
+ headlineContainer: {
22
+ // backgroundColor: theme.colors.surface,
23
+ paddingHorizontal: theme.spacings['5'],
24
+ paddingTop: theme.spacings['5'],
25
+ paddingBottom: theme.spacings['4'],
26
+ flexDirection: 'row',
27
+ alignItems: 'center',
28
+ },
29
+ headerCopy: {
30
+ flex: 1,
31
+ minWidth: 0,
32
+ },
33
+ headline: {
34
+ ...theme.typescale.labelLarge,
35
+ color: theme.colors.onSurfaceVariant,
36
+ },
37
+ supporting: {
38
+ fontSize: 44,
39
+ lineHeight: 52,
40
+ fontWeight: theme.typescale.displaySmall.fontWeight,
41
+ color: theme.colors.onSurface,
42
+ paddingTop: theme.spacings['2'],
43
+ flexShrink: 1,
44
+ },
45
+ modeToggle: {
46
+ color: theme.colors.onSurfaceVariant,
47
+ marginLeft: theme.spacings['3'],
48
+ },
49
+ body: {
50
+ // backgroundColor: theme.colors.surfaceContainerHighest,
51
+ borderTopWidth: StyleSheet.hairlineWidth,
52
+ borderTopColor: theme.colors.outlineVariant,
53
+ },
54
+ calendarContainer: {
55
+ minHeight: 320,
56
+ minWidth: undefined,
57
+ // backgroundColor: theme.colors.surfaceContainerHighest,
58
+ },
59
+ calendarRoot: {
60
+ // backgroundColor: theme.colors.surfaceContainerHighest,
61
+ },
62
+ inputContainer: {
63
+ padding: theme.spacings['6'],
64
+ paddingTop: theme.spacings['5'],
65
+ paddingBottom: theme.spacings['4'],
66
+ },
67
+ footer: {
68
+ // backgroundColor: theme.colors.surface,
69
+ flexDirection: 'row',
70
+ alignItems: 'center',
71
+ justifyContent: 'flex-end',
72
+ columnGap: theme.spacings['2'],
73
+ paddingHorizontal: theme.spacings['4'],
74
+ paddingTop: theme.spacings['0'],
75
+ paddingBottom: theme.spacings['2'],
76
+ },
77
+ }));
78
+
79
+ const datePickerModalHeaderStylesDefault = StyleSheet.create(theme => ({
80
+ root: {
81
+ color: theme.colors.onPrimary,
82
+ },
83
+ animated: {
84
+ paddingBottom: theme.spacings['0'],
85
+ elevation: 4,
86
+ },
87
+ safeContent: {
88
+ paddingBottom: theme.spacings['0'],
89
+
90
+ variants: {
91
+ state: {
92
+ disableSafeTop: {
93
+ paddingTop: 0,
94
+ },
95
+ },
96
+ },
97
+ },
98
+ safeContentNoTop: {
99
+ paddingTop: theme.spacings['0'],
100
+ },
101
+ appbarHeader: {
102
+ flexDirection: 'row',
103
+ alignItems: 'center',
104
+ justifyContent: 'space-between',
105
+ paddingHorizontal: theme.spacings['2'],
106
+ paddingVertical: theme.spacings['2'],
107
+ elevation: 0,
108
+ backgroundColor: 'transparent',
109
+ },
110
+ }));
111
+
112
+ const datePickerModalContentHeaderStylesDefault = StyleSheet.create(theme => ({
113
+ root: {
114
+ color: theme.colors.onPrimary,
115
+ },
116
+
117
+ fill: {
118
+ flex: 1,
119
+ },
120
+ header: {
121
+ height: 75,
122
+ alignItems: 'center',
123
+ flexDirection: 'row',
124
+ paddingLeft: theme.spacings['6'],
125
+ paddingRight: theme.spacings['3'],
126
+ },
127
+ headerContentContainer: {
128
+ marginTop: theme.spacings['1'],
129
+ flexDirection: 'row',
130
+ alignItems: 'center',
131
+ },
132
+ label: {
133
+ color: theme.colors.onPrimary,
134
+ letterSpacing: 1,
135
+ fontSize: theme.typescale.bodyMedium.fontSize,
136
+ },
137
+ headerText: {
138
+ fontSize: theme.typescale.bodyMedium.fontSize,
139
+ color: theme.colors.onPrimary,
140
+ },
141
+ headerSeparator: {
142
+ fontSize: theme.typescale.bodyMedium.fontSize,
143
+ paddingLeft: theme.spacings['2'],
144
+ paddingRight: theme.spacings['2'],
145
+ color: theme.colors.onPrimary,
146
+ },
147
+ icon: {
148
+ color: theme.colors.onPrimary,
149
+ },
150
+ }));
151
+
152
+ const datePickerModalHeaderBackgroundStylesDefault = StyleSheet.create(theme => ({
153
+ header: {
154
+ backgroundColor: theme.colors.primary,
155
+ paddingBottom: theme.spacings['0'],
156
+ elevation: 4,
157
+ },
158
+ safeContent: {
159
+ paddingBottom: theme.spacings['0'],
160
+ },
161
+ }));
162
+
163
+ const datePickerModalEditStylesDefault = StyleSheet.create(theme => ({
164
+ container: { padding: theme.spacings['3'] },
165
+ inner: { flexDirection: 'row' },
166
+ inputContainer: { flex: 1 },
167
+ input: { flex: 1 },
168
+ separator: { width: 12 },
169
+ }));
170
+
171
+ const datePickerPopoverHeaderStylesDefault = StyleSheet.create(theme => ({
172
+ buttonContainer: {
173
+ height: 46,
174
+ gap: theme.spacings['2'],
175
+ // width: '50%',
176
+ flexDirection: 'row',
177
+ alignItems: 'center',
178
+ },
179
+ buttonWrapper: {},
180
+ spacer: { flex: 1 },
181
+ labelStyle: {
182
+ ...theme.typescale.labelLarge,
183
+ color: theme.colors.onSurfaceVariant,
184
+ marginRight: theme.spacings['2'],
185
+ },
186
+ buttonStyle: {
187
+ alignSelf: 'center',
188
+ borderRadius: theme.shapes.corner.extraSmall,
189
+ },
190
+ innerStyle: {
191
+ paddingLeft: theme.spacings['0'],
192
+ flexDirection: 'row',
193
+ alignItems: 'center',
194
+ borderRadius: theme.shapes.corner.extraSmall,
195
+ },
196
+ emtpyView: {
197
+ width: 30,
198
+ },
199
+ }));
200
+
201
+ const datePickerPopoverMonthPickerStylesDefault = StyleSheet.create(theme => ({
202
+ root: {
203
+ backgroundColor: theme.colors.surface,
204
+ },
205
+ month: {
206
+ flex: 1,
207
+ justifyContent: 'center',
208
+ alignItems: 'flex-start',
209
+ },
210
+ selectedMonth: { color: theme.colors.onSurface },
211
+ monthButton: {
212
+ width: '100%',
213
+ overflow: 'hidden',
214
+ },
215
+ monthInner: {
216
+ height: 46,
217
+ alignItems: 'center',
218
+ justifyContent: 'flex-start',
219
+ flexDirection: 'row',
220
+ },
221
+ selectedMonthInner: { backgroundColor: theme.colors.surfaceVariant },
222
+ monthLabel: {
223
+ fontSize: 16,
224
+ },
225
+ }));
226
+
227
+ const datePickerPopoverMonthItemStylesDefault = StyleSheet.create(theme => ({
228
+ root: {
229
+ backgroundColor: theme.colors.surface,
230
+ },
231
+ monthButton: {
232
+ width: '100%',
233
+ overflow: 'hidden',
234
+ padding: theme.spacings['0'],
235
+ variants: {
236
+ state: {
237
+ selected: {
238
+ backgroundColor: theme.colors.surfaceVariant,
239
+ },
240
+ },
241
+ },
242
+ },
243
+ monthInner: {
244
+ height: 46,
245
+ alignItems: 'center',
246
+ justifyContent: 'flex-start',
247
+ flexDirection: 'row',
248
+ padding: theme.spacings['0'],
249
+ },
250
+ monthLabel: {
251
+ fontSize: 16,
252
+ variants: {
253
+ state: {
254
+ selected: {
255
+ color: theme.colors.onSurface,
256
+ },
257
+ },
258
+ },
259
+ },
260
+ }));
261
+
262
+ export const datePickerModalStyles = getRegisteredComponentStylesWithFallback(
263
+ 'DatePickerModal',
264
+ datePickerModalStylesDefault,
265
+ );
266
+ export const datePickerModalHeaderStyles = getRegisteredComponentStylesWithFallback(
267
+ 'DatePickerModal_Header',
268
+ datePickerModalHeaderStylesDefault,
269
+ );
270
+ export const datePickerModalContentHeaderStyles = getRegisteredComponentStylesWithFallback(
271
+ 'DatePickerModal_ContentHeader',
272
+ datePickerModalContentHeaderStylesDefault,
273
+ );
274
+ export const datePickerModalHeaderBackgroundStyles = getRegisteredComponentStylesWithFallback(
275
+ 'DatePickerModal_HeaderBackground',
276
+ datePickerModalHeaderBackgroundStylesDefault,
277
+ );
278
+ export const datePickerModalEditStyles = getRegisteredComponentStylesWithFallback(
279
+ 'DatePickerModal_Edit',
280
+ datePickerModalEditStylesDefault,
281
+ );
282
+ export const datePickerHeaderItemStyles = getRegisteredComponentStylesWithFallback(
283
+ 'DatePicker_HeaderItem',
284
+ datePickerPopoverHeaderStylesDefault,
285
+ );
286
+ export const datePickerMonthPickerStyles = getRegisteredComponentStylesWithFallback(
287
+ 'DatePickerPopover_MonthPicker',
288
+ datePickerPopoverMonthPickerStylesDefault,
289
+ );
290
+ export const datePickerMonthItemStyles = getRegisteredComponentStylesWithFallback(
291
+ 'DatePickerPopover_MonthItem',
292
+ datePickerPopoverMonthItemStylesDefault,
293
+ );
@@ -18,4 +18,5 @@ export const {
18
18
  Provider,
19
19
  useContext: useDatePickerStore,
20
20
  useContextValue: useDatePickerStoreValue,
21
+ useStoreRef: useDatePickerStoreRef,
21
22
  } = createFastContext<Store>();
@@ -0,0 +1,117 @@
1
+ import { add, setYear } from 'date-fns';
2
+ import { memo, useCallback, useMemo } from 'react';
3
+ import { View, type ViewStyle } from 'react-native';
4
+ import { StyleSheet } from 'react-native-unistyles';
5
+
6
+ import type { DatePickerLocale } from '../DatePicker/context';
7
+ import { useDatePickerStoreRef, useDatePickerStoreValue } from './DatePickerContext';
8
+ import type { DisableWeekDaysType } from './dateUtils';
9
+ import DayNames from './DayNames';
10
+ import HeaderItem from './HeaderItem';
11
+ import { datePickerHeaderStyles } from './utils';
12
+
13
+ export type DockedHeaderProps = {
14
+ locale?: DatePickerLocale;
15
+ scrollMode: 'horizontal' | 'vertical';
16
+ disableWeekDays?: DisableWeekDaysType;
17
+ style?: ViewStyle;
18
+ };
19
+
20
+ function DatePickerDockedHeader({
21
+ locale = 'en',
22
+ scrollMode,
23
+ disableWeekDays,
24
+ style: styleProp,
25
+ }: DockedHeaderProps) {
26
+ const setStore = useDatePickerStoreRef().set;
27
+ const { localDate, pickerType } = useDatePickerStoreValue(state => ({
28
+ localDate: state.localDate,
29
+ pickerType: state.pickerType,
30
+ }));
31
+ const isHorizontal = scrollMode === 'horizontal';
32
+
33
+ const { monthName, year } = useMemo(
34
+ () => ({
35
+ monthName: new Intl.DateTimeFormat(locale, { month: 'short' }).format(localDate),
36
+ year: localDate.getFullYear(),
37
+ }),
38
+ [localDate, locale],
39
+ );
40
+
41
+ const handleMonthDropdown = useCallback(() => {
42
+ setStore(prev => ({ pickerType: prev.pickerType === 'month' ? undefined : 'month' }));
43
+ }, [setStore]);
44
+
45
+ const handleYearDropdown = useCallback(() => {
46
+ setStore(prev => ({ pickerType: prev.pickerType === 'year' ? undefined : 'year' }));
47
+ }, [setStore]);
48
+
49
+ const handleMonthPrev = useCallback(() => {
50
+ setStore(prev => ({ localDate: add(prev.localDate, { months: -1 }) }));
51
+ }, [setStore]);
52
+
53
+ const handleMonthNext = useCallback(() => {
54
+ setStore(prev => ({ localDate: add(prev.localDate, { months: 1 }) }));
55
+ }, [setStore]);
56
+
57
+ const handleYearPrev = useCallback(() => {
58
+ setStore(prev => ({
59
+ localDate: setYear(prev.localDate, prev.localDate.getFullYear() - 1),
60
+ }));
61
+ }, [setStore]);
62
+
63
+ const handleYearNext = useCallback(() => {
64
+ setStore(prev => ({
65
+ localDate: setYear(prev.localDate, prev.localDate.getFullYear() + 1),
66
+ }));
67
+ }, [setStore]);
68
+
69
+ const pickerOpen = pickerType === 'month' || pickerType === 'year';
70
+
71
+ return (
72
+ <View pointerEvents="box-none">
73
+ {isHorizontal && (
74
+ <View
75
+ style={[
76
+ datePickerHeaderStyles.datePickerHeader,
77
+ styles.row,
78
+ pickerOpen && styles.rowPickerOpen,
79
+ styleProp,
80
+ ]}>
81
+ <HeaderItem
82
+ onPrev={handleMonthPrev}
83
+ onNext={handleMonthNext}
84
+ onPressDropdown={handleMonthDropdown}
85
+ type="month"
86
+ value={monthName}
87
+ pickerType={pickerType}
88
+ selecting={pickerType === 'month'}
89
+ />
90
+ <HeaderItem
91
+ onPrev={handleYearPrev}
92
+ onNext={handleYearNext}
93
+ onPressDropdown={handleYearDropdown}
94
+ type="year"
95
+ value={year}
96
+ pickerType={pickerType}
97
+ selecting={pickerType === 'year'}
98
+ />
99
+ </View>
100
+ )}
101
+ <DayNames disableWeekDays={disableWeekDays} locale={locale} />
102
+ </View>
103
+ );
104
+ }
105
+
106
+ const styles = StyleSheet.create(theme => ({
107
+ row: {
108
+ flexDirection: 'row',
109
+ alignItems: 'center',
110
+ },
111
+ rowPickerOpen: {
112
+ borderBottomWidth: StyleSheet.hairlineWidth,
113
+ borderBottomColor: theme.colors.outlineVariant,
114
+ },
115
+ }));
116
+
117
+ export default memo(DatePickerDockedHeader);
@@ -1,18 +1,18 @@
1
- import { memo, useCallback, useMemo } from 'react';
1
+ import { memo, useCallback } from 'react';
2
2
  import { View, type ViewStyle } from 'react-native';
3
3
 
4
4
  import { useControlledValue } from '../../hooks';
5
- import type {
6
- LocalState,
7
- LocalStateMultiple,
8
- LocalStateRange,
9
- LocalStateSingle,
10
- } from '../DatePickerModal/types';
5
+ import DatePickerDockedHeader from './DatePickerDockedHeader';
11
6
  import DatePickerInlineBase from './DatePickerInlineBase';
12
7
  import DatePickerInlineHeader from './DatePickerInlineHeader';
13
- import type { DatePickerInlineBaseProps } from './types';
8
+ import type { CalendarDate, CalendarDates, DatePickerInlineBaseProps } from './types';
14
9
  import { datePickerStyles } from './utils';
15
10
 
11
+ type LocalState = LocalStateSingle | LocalStateMultiple | LocalStateRange;
12
+ type LocalStateSingle = { date: CalendarDate };
13
+ type LocalStateMultiple = { dates: CalendarDates };
14
+ type LocalStateRange = { startDate: CalendarDate; endDate: CalendarDate };
15
+
16
16
  export type DatePickerInlineProps = DatePickerInlineBaseProps & {
17
17
  containerStyle?: ViewStyle;
18
18
  };
@@ -25,6 +25,8 @@ const DatePickerInline = ({
25
25
  onChange,
26
26
  locale = 'en',
27
27
  mode = 'single',
28
+ headerLayout = 'inline',
29
+ HeaderComponent,
28
30
  containerStyle: containerStyleProp,
29
31
  ...rest
30
32
  }: DatePickerInlineProps) => {
@@ -40,16 +42,15 @@ const DatePickerInline = ({
40
42
  onChange: onInnerChange,
41
43
  });
42
44
 
43
- const { containerStyle } = useMemo(() => {
44
- return {
45
- containerStyle: [datePickerStyles.container, datePickerStyles.root, containerStyleProp],
46
- };
47
- }, [containerStyleProp]);
45
+ const resolvedHeader =
46
+ HeaderComponent ??
47
+ (headerLayout === 'docked' ? DatePickerDockedHeader : DatePickerInlineHeader);
48
48
 
49
49
  return (
50
- <View style={containerStyle}>
50
+ <View style={[datePickerStyles.container, datePickerStyles.root, containerStyleProp]}>
51
51
  <DatePickerInlineBase
52
52
  {...rest}
53
+ headerLayout={headerLayout}
53
54
  locale={locale}
54
55
  mode={mode}
55
56
  startDate={(state as LocalStateRange)?.startDate}
@@ -59,7 +60,7 @@ const DatePickerInline = ({
59
60
  dates={(state as LocalStateMultiple)?.dates}
60
61
  // TODO - fix ts issues
61
62
  // @ts-ignore
62
- HeaderComponent={DatePickerInlineHeader}
63
+ HeaderComponent={resolvedHeader}
63
64
  />
64
65
  </View>
65
66
  );
@@ -43,6 +43,8 @@ function DatePickerInlineBaseChild(props: DatePickerInlineBaseProps) {
43
43
  HeaderComponent,
44
44
  onToggle,
45
45
  monthStyle,
46
+ showOutsideDays,
47
+ headerLayout,
46
48
  } = props;
47
49
  const [pickerType, setStore] = useDatePickerStore(state => state.pickerType);
48
50
 
@@ -125,6 +127,7 @@ function DatePickerInlineBaseChild(props: DatePickerInlineBaseProps) {
125
127
  scrollMode={scrollMode}
126
128
  disableWeekDays={disableWeekDays}
127
129
  customMonthStyles={monthStyle}
130
+ showOutsideDays={showOutsideDays}
128
131
  />
129
132
  );
130
133
  },
@@ -140,6 +143,7 @@ function DatePickerInlineBaseChild(props: DatePickerInlineBaseProps) {
140
143
  scrollMode,
141
144
  disableWeekDays,
142
145
  monthStyle,
146
+ showOutsideDays,
143
147
  ],
144
148
  );
145
149
 
@@ -166,8 +170,10 @@ function DatePickerInlineBaseChild(props: DatePickerInlineBaseProps) {
166
170
  renderItem={renderMonthComponent}
167
171
  renderHeader={renderCalenderHeader}
168
172
  />
169
- {isHorizontal && pickerType === 'year' && <YearPicker />}
170
- {isHorizontal && pickerType === 'month' && <MonthPicker />}
173
+ {isHorizontal && pickerType === 'year' && (
174
+ <YearPicker layout={headerLayout === 'docked' ? 'list' : 'grid'} />
175
+ )}
176
+ {isHorizontal && pickerType === 'month' && <MonthPicker locale={locale} />}
171
177
  </View>
172
178
  );
173
179
  }
@@ -1,7 +1,8 @@
1
- import { add, format } from 'date-fns';
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?: string;
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 { monthName: format(localDate, 'LLLL'), year: y };
39
- }, [localDate]);
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,11 +1,17 @@
1
1
  import { memo, useCallback, useMemo } from 'react';
2
2
  import { type StyleProp, View, type ViewStyle } from 'react-native';
3
3
 
4
+ import { useActionState } from '../../hooks/useActionState';
4
5
  import { resolveStateVariant } from '../../utils';
6
+ import { StateLayer } from '../StateLayer';
5
7
  import { Text } from '../Text';
6
8
  import { TouchableRipple } from '../TouchableRipple';
7
9
  import DayRange from './DayRange';
8
- import { datePickerDayEmptyStyles, datePickerDayStyles } from './utils';
10
+ import {
11
+ datePickerDayEmptyStyles,
12
+ datePickerDayStateLayerStyles,
13
+ datePickerDayStyles,
14
+ } from './utils';
9
15
 
10
16
  function EmptyDayPure() {
11
17
  return <View style={datePickerDayEmptyStyles.root} />;
@@ -23,6 +29,7 @@ function Day(props: {
23
29
  rightCrop: boolean;
24
30
  isToday: boolean;
25
31
  disabled: boolean;
32
+ outside?: boolean;
26
33
  onPressDate: (date: Date) => any;
27
34
  }) {
28
35
  const {
@@ -36,17 +43,32 @@ function Day(props: {
36
43
  onPressDate,
37
44
  isToday,
38
45
  disabled,
46
+ outside,
39
47
  } = props;
48
+
49
+ const { hovered, actionsRef } = useActionState({ actionsToListen: ['hover'] });
50
+
40
51
  const state = resolveStateVariant({
41
52
  disabled,
42
53
  selected,
43
54
  inRange,
44
55
  today: isToday,
56
+ outside: !!outside,
45
57
  });
46
58
  datePickerDayStyles.useVariants({
47
59
  state: state as any,
48
60
  });
49
61
 
62
+ datePickerDayStateLayerStyles.useVariants({
63
+ state: resolveStateVariant({
64
+ hovered: hovered,
65
+ outsideAndHovered: !!outside && !selected && !inRange && hovered,
66
+ selectedAndHovered: selected && hovered,
67
+ inRangeAndHovered: inRange && hovered,
68
+ todayAndHovered: isToday && hovered,
69
+ }) as any,
70
+ });
71
+
50
72
  const onPress = useCallback(() => {
51
73
  onPressDate(new Date(year, month, day));
52
74
  }, [onPressDate, year, month, day]);
@@ -69,6 +91,7 @@ function Day(props: {
69
91
  <DayRange inRange={inRange} leftCrop={leftCrop} rightCrop={rightCrop} />
70
92
 
71
93
  <TouchableRipple
94
+ ref={actionsRef}
72
95
  testID={`day-${year}-${month}-${day}`}
73
96
  disabled={disabled}
74
97
  borderless={true}
@@ -80,6 +103,7 @@ function Day(props: {
80
103
  {day}
81
104
  </Text>
82
105
  </View>
106
+ <StateLayer style={datePickerDayStateLayerStyles.stateLayer} />
83
107
  </TouchableRipple>
84
108
  </View>
85
109
  );