react-native-molecules 0.5.0-beta.16 → 0.5.0-beta.18

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 (87) hide show
  1. package/components/DateField/DateField.tsx +110 -0
  2. package/components/DateField/index.tsx +6 -0
  3. package/components/{DatePickerInput/inputUtils.ts → DateField/useDateFieldState.ts} +17 -49
  4. package/components/DatePicker/DateCalendar.tsx +83 -0
  5. package/components/DatePicker/DatePickerActions.tsx +73 -0
  6. package/components/DatePicker/DatePickerModal.tsx +234 -0
  7. package/components/DatePicker/DatePickerPopover.tsx +79 -0
  8. package/components/DatePicker/DatePickerProvider.tsx +152 -0
  9. package/components/DatePicker/DatePickerTrigger.tsx +23 -0
  10. package/components/DatePicker/context.tsx +82 -0
  11. package/components/DatePicker/index.tsx +44 -0
  12. package/components/DatePicker/utils.ts +292 -0
  13. package/components/DatePickerInline/DatePickerContext.tsx +1 -0
  14. package/components/DatePickerInline/DatePickerDockedHeader.tsx +113 -0
  15. package/components/DatePickerInline/DatePickerInline.tsx +16 -15
  16. package/components/DatePickerInline/DatePickerInlineBase.tsx +7 -1
  17. package/components/DatePickerInline/Day.tsx +25 -1
  18. package/components/DatePickerInline/DayRange.tsx +2 -4
  19. package/components/DatePickerInline/HeaderItem.tsx +42 -27
  20. package/components/DatePickerInline/Month.tsx +45 -65
  21. package/components/DatePickerInline/MonthPicker.tsx +25 -41
  22. package/components/DatePickerInline/Swiper.native.tsx +21 -4
  23. package/components/DatePickerInline/Swiper.tsx +168 -13
  24. package/components/DatePickerInline/Week.tsx +6 -1
  25. package/components/DatePickerInline/YearPicker.tsx +206 -53
  26. package/components/DatePickerInline/dateUtils.tsx +17 -12
  27. package/components/DatePickerInline/types.ts +3 -0
  28. package/components/DatePickerInline/utils.ts +66 -29
  29. package/components/ListItem/ListItem.tsx +3 -1
  30. package/components/ListItem/utils.ts +1 -1
  31. package/components/LoadingIndicator/index.tsx +1 -1
  32. package/components/Menu/Menu.tsx +3 -18
  33. package/components/Popover/Popover.tsx +122 -145
  34. package/components/Popover/PopoverRoot.tsx +74 -0
  35. package/components/Popover/common.ts +50 -34
  36. package/components/Popover/index.ts +18 -1
  37. package/components/Popover/usePlatformMeasure.native.ts +90 -0
  38. package/components/Popover/usePlatformMeasure.ts +118 -0
  39. package/components/Popover/utils.ts +34 -0
  40. package/components/Select/Select.tsx +7 -8
  41. package/components/Select/context.tsx +72 -0
  42. package/components/Select/index.ts +1 -0
  43. package/components/Select/utils.ts +0 -71
  44. package/components/Slot/compose-refs.tsx +2 -0
  45. package/components/TimeField/TimeField.tsx +75 -0
  46. package/components/TimeField/index.tsx +6 -0
  47. package/components/TimeField/useTimeFieldState.ts +70 -0
  48. package/components/{TimePickerField/sanitizeTime.ts → TimeField/utils.ts} +77 -10
  49. package/components/TimePicker/TimePicker.tsx +53 -9
  50. package/components/TimePicker/TimePickerModal.tsx +186 -0
  51. package/components/TimePicker/context.tsx +17 -0
  52. package/components/TimePicker/index.tsx +15 -3
  53. package/components/TimePicker/utils.ts +50 -0
  54. package/hooks/useActionState.tsx +19 -8
  55. package/package.json +6 -1
  56. package/components/DatePickerDocked/DatePickerDocked.tsx +0 -30
  57. package/components/DatePickerDocked/DatePickerDockedHeader.tsx +0 -129
  58. package/components/DatePickerDocked/index.tsx +0 -17
  59. package/components/DatePickerDocked/types.ts +0 -11
  60. package/components/DatePickerDocked/utils.ts +0 -157
  61. package/components/DatePickerInput/DatePickerInput.tsx +0 -130
  62. package/components/DatePickerInput/DatePickerInputModal.tsx +0 -48
  63. package/components/DatePickerInput/DatePickerInputWithoutModal.tsx +0 -73
  64. package/components/DatePickerInput/DateRangeInput.tsx +0 -88
  65. package/components/DatePickerInput/index.tsx +0 -11
  66. package/components/DatePickerInput/types.ts +0 -26
  67. package/components/DatePickerInput/utils.ts +0 -24
  68. package/components/DatePickerModal/AnimatedCrossView.tsx +0 -94
  69. package/components/DatePickerModal/CalendarEdit.tsx +0 -140
  70. package/components/DatePickerModal/DatePickerModal.tsx +0 -85
  71. package/components/DatePickerModal/DatePickerModalContent.tsx +0 -155
  72. package/components/DatePickerModal/DatePickerModalContentHeader.tsx +0 -213
  73. package/components/DatePickerModal/DatePickerModalHeader.tsx +0 -74
  74. package/components/DatePickerModal/DatePickerModalHeaderBackground.tsx +0 -13
  75. package/components/DatePickerModal/index.tsx +0 -16
  76. package/components/DatePickerModal/types.ts +0 -92
  77. package/components/DatePickerModal/utils.ts +0 -122
  78. package/components/DateTimePicker/DateTimePicker.tsx +0 -172
  79. package/components/DateTimePicker/index.tsx +0 -10
  80. package/components/DateTimePicker/utils.ts +0 -12
  81. package/components/Popover/Popover.native.tsx +0 -185
  82. package/components/TimePickerField/TimePickerField.tsx +0 -154
  83. package/components/TimePickerField/index.tsx +0 -10
  84. package/components/TimePickerField/utils.ts +0 -94
  85. package/components/TimePickerModal/TimePickerModal.tsx +0 -119
  86. package/components/TimePickerModal/index.tsx +0 -10
  87. package/components/TimePickerModal/utils.ts +0 -47
@@ -1,24 +0,0 @@
1
- import { createContext } from 'react';
2
- import { StyleSheet } from 'react-native-unistyles';
3
-
4
- import { getRegisteredComponentStylesWithFallback } from '../../core';
5
-
6
- export type DatePickerInputContextType = {
7
- onPressTrigger: () => void;
8
- };
9
-
10
- export const DatePickerInputContext = createContext<DatePickerInputContextType>({
11
- onPressTrigger: () => {},
12
- });
13
-
14
- const datePickerInputStylesDefault = StyleSheet.create({
15
- root: {
16
- minWidth: 150,
17
- justifyContent: 'center',
18
- },
19
- });
20
-
21
- export const datePickerInputStyles = getRegisteredComponentStylesWithFallback(
22
- 'DatePickerInput',
23
- datePickerInputStylesDefault,
24
- );
@@ -1,94 +0,0 @@
1
- import { useEffect, useMemo, useRef } from 'react';
2
- import { Animated, View } from 'react-native';
3
- import { StyleSheet } from 'react-native-unistyles';
4
-
5
- export default function AnimatedCrossView({
6
- // visible,
7
- collapsed,
8
- calendar,
9
- calendarEdit,
10
- }: {
11
- calendar: any;
12
- calendarEdit: any;
13
- // visible: boolean
14
- collapsed: boolean;
15
- }) {
16
- const calendarOpacity = useRef<Animated.Value>(new Animated.Value(collapsed ? 1 : 0));
17
- useEffect(() => {
18
- // if (visible) {
19
- Animated.timing(calendarOpacity.current, {
20
- toValue: collapsed ? 1 : 0,
21
- duration: 250,
22
- useNativeDriver: true,
23
- }).start();
24
- // }
25
- }, [collapsed]);
26
-
27
- const { calendarStyle, calendarEditStyle } = useMemo(() => {
28
- return {
29
- calendarStyle: [
30
- styles.calendar,
31
- {
32
- opacity: calendarOpacity.current,
33
- transform: [
34
- {
35
- scaleY: calendarOpacity.current.interpolate({
36
- inputRange: [0, 1],
37
- outputRange: [0.85, 1],
38
- }),
39
- },
40
- {
41
- scaleX: calendarOpacity.current.interpolate({
42
- inputRange: [0, 1],
43
- outputRange: [0.95, 1],
44
- }),
45
- },
46
- ],
47
- },
48
- ],
49
- calendarEditStyle: [
50
- styles.calendarEdit,
51
- {
52
- opacity: calendarOpacity.current.interpolate({
53
- inputRange: [0, 1],
54
- outputRange: [1, 0],
55
- }),
56
- transform: [
57
- {
58
- scale: calendarOpacity.current.interpolate({
59
- inputRange: [0, 1],
60
- outputRange: [1, 0.95],
61
- }),
62
- },
63
- ],
64
- },
65
- ],
66
- };
67
- }, []);
68
-
69
- // TODO Create AnimatedCrossView Component
70
- return (
71
- <View style={styles.root}>
72
- <Animated.View pointerEvents={collapsed ? 'auto' : 'none'} style={calendarStyle}>
73
- {calendar}
74
- </Animated.View>
75
- <Animated.View pointerEvents={collapsed ? 'none' : 'auto'} style={calendarEditStyle}>
76
- {calendarEdit}
77
- </Animated.View>
78
- </View>
79
- );
80
- }
81
-
82
- const styles = StyleSheet.create(theme => ({
83
- root: { flex: 1 },
84
- calendarEdit: {
85
- position: 'absolute',
86
-
87
- left: 0,
88
- right: 0,
89
- backgroundColor: theme.colors.surface,
90
- },
91
- calendar: {
92
- flex: 1,
93
- },
94
- }));
@@ -1,140 +0,0 @@
1
- import { memo, useCallback, useEffect, useRef } from 'react';
2
- import { Keyboard, TextInput as TextInputNative, View } from 'react-native';
3
-
4
- import type { ModeType, ValidRangeType } from '../DatePickerInline';
5
- import DatePickerInputWithoutModal from '../DatePickerInput/DatePickerInputWithoutModal';
6
- import { TextInput } from '../TextInput';
7
- import type { LocalState, LocalStateRange, LocalStateSingle } from './types';
8
- import { datePickerModalEditStyles } from './utils';
9
-
10
- type Props = {
11
- mode: ModeType;
12
- label?: string;
13
- startLabel?: string;
14
- endLabel?: string;
15
- state: LocalState;
16
- collapsed: boolean;
17
- onChange: (s: LocalState) => any;
18
- validRange: ValidRangeType | undefined;
19
- // locale: string;
20
- };
21
-
22
- function CalendarEdit({
23
- mode,
24
- state,
25
- label = '',
26
- startLabel = 'Start',
27
- endLabel = 'End',
28
- collapsed,
29
- onChange,
30
- validRange,
31
- }: // locale,
32
- Props) {
33
- const dateInput = useRef<TextInputNative | null>(null);
34
- const startInput = useRef<TextInputNative | null>(null);
35
- const endInput = useRef<TextInputNative | null>(null);
36
-
37
- // when switching views focus, or un-focus text input
38
- useEffect(() => {
39
- // hide open keyboard
40
- if (collapsed) {
41
- Keyboard.dismiss();
42
- }
43
-
44
- const inputsToFocus = [dateInput.current, startInput.current].filter(
45
- n => n,
46
- ) as TextInputNative[];
47
-
48
- const inputsToBlur = [dateInput.current, startInput.current, endInput.current].filter(
49
- n => n,
50
- ) as TextInputNative[];
51
-
52
- if (collapsed) {
53
- inputsToBlur.forEach(ip => ip.blur());
54
- } else {
55
- inputsToFocus.forEach(ip => ip.focus());
56
- }
57
- }, [mode, startInput, endInput, dateInput, collapsed]);
58
-
59
- const onSubmitStartInput = useCallback(() => {
60
- if (endInput.current) {
61
- endInput.current.focus();
62
- }
63
- }, [endInput]);
64
-
65
- const onSubmitEndInput = useCallback(() => {
66
- // TODO: close modal and persist range
67
- }, []);
68
-
69
- const onSubmitInput = useCallback(() => {
70
- // TODO: close modal and persist range
71
- }, []);
72
-
73
- const onSingleInputChange = useCallback(
74
- (date: Date | null) => onChange({ ...state, date }),
75
- [onChange, state],
76
- );
77
-
78
- const onStartDateChange = useCallback(
79
- (startDate: Date | null) => onChange({ ...state, startDate }),
80
- [onChange, state],
81
- );
82
-
83
- const onEndDateChange = useCallback(
84
- (endDate: Date | null) => onChange({ ...state, endDate }),
85
- [onChange, state],
86
- );
87
-
88
- return (
89
- <View style={datePickerModalEditStyles.container}>
90
- <>
91
- {mode === 'single' ? (
92
- <DatePickerInputWithoutModal
93
- inputMode="start"
94
- ref={dateInput}
95
- value={(state as LocalStateSingle).date}
96
- onChange={onSingleInputChange}
97
- onSubmitEditing={onSubmitInput}
98
- validRange={validRange}
99
- // locale={locale}
100
- autoComplete={'off'}>
101
- <TextInput.Label>{label}</TextInput.Label>
102
- </DatePickerInputWithoutModal>
103
- ) : null}
104
- </>
105
-
106
- <>
107
- {mode === 'range' ? (
108
- <View style={datePickerModalEditStyles.inner}>
109
- <DatePickerInputWithoutModal
110
- inputMode="start"
111
- ref={startInput}
112
- value={(state as LocalStateRange).startDate}
113
- onChange={onStartDateChange}
114
- returnKeyType={'next'}
115
- onSubmitEditing={onSubmitStartInput}
116
- validRange={validRange}
117
- // locale={locale}
118
- autoComplete={'off'}>
119
- <TextInput.Label>{startLabel}</TextInput.Label>
120
- </DatePickerInputWithoutModal>
121
- <View style={datePickerModalEditStyles.separator} />
122
- <DatePickerInputWithoutModal
123
- inputMode="end"
124
- ref={endInput}
125
- value={(state as LocalStateRange).endDate}
126
- onChange={onEndDateChange}
127
- onSubmitEditing={onSubmitEndInput}
128
- validRange={validRange}
129
- // locale={locale}
130
- autoComplete="off">
131
- <TextInput.Label>{endLabel}</TextInput.Label>
132
- </DatePickerInputWithoutModal>
133
- </View>
134
- ) : null}
135
- </>
136
- </View>
137
- );
138
- }
139
-
140
- export default memo(CalendarEdit);
@@ -1,85 +0,0 @@
1
- import color from 'color';
2
- import { memo, useMemo } from 'react';
3
- import {
4
- Platform,
5
- StatusBar,
6
- type StatusBarStyle,
7
- StyleSheet,
8
- useWindowDimensions,
9
- View,
10
- } from 'react-native';
11
-
12
- import { Modal } from '../Modal';
13
- import { Portal } from '../Portal';
14
- import { DatePickerModalContent } from './DatePickerModalContent';
15
- import type { DatePickerModalProps } from './types';
16
- import { datePickerModalStyles } from './utils';
17
-
18
- export function DatePickerModal(props: DatePickerModalProps) {
19
- const dimensions = useWindowDimensions();
20
-
21
- const {
22
- isOpen,
23
- disableStatusBar,
24
- disableStatusBarPadding,
25
- mode = 'single',
26
- style: styleProp,
27
- ...rest
28
- } = props;
29
-
30
- const { containerStyle, headerStyle, barStyle, modalContentStyle } = useMemo(() => {
31
- let isHeaderBackgroundLight = true;
32
- try {
33
- isHeaderBackgroundLight = color(
34
- datePickerModalStyles.header?.backgroundColor,
35
- ).isLight();
36
- } catch (e) {}
37
-
38
- return {
39
- containerStyle: [StyleSheet.absoluteFill, styleProp],
40
- headerStyle: [
41
- datePickerModalStyles.header,
42
- {
43
- height: Platform.OS === 'android' ? StatusBar.currentHeight : 0, // on IOS StatusBar.currentHeight isn't available
44
- },
45
- ],
46
- barStyle: (isHeaderBackgroundLight
47
- ? 'dark-content'
48
- : 'light-content') as StatusBarStyle,
49
- modalContentStyle:
50
- dimensions.width > 650
51
- ? { flex: 1, maxHeight: 600 }
52
- : { flex: 1, maxWidth: undefined, borderRadius: 0 },
53
- };
54
- }, [dimensions.width, styleProp]);
55
-
56
- return (
57
- <View style={containerStyle} pointerEvents="box-none">
58
- <Portal>
59
- <Modal
60
- isOpen={isOpen}
61
- onClose={rest.onClose}
62
- style={modalContentStyle}
63
- elevation={0}>
64
- <>
65
- <>
66
- {disableStatusBar ? null : (
67
- <StatusBar translucent={true} barStyle={barStyle} />
68
- )}
69
- </>
70
-
71
- <>{disableStatusBarPadding ? null : <View style={headerStyle} />}</>
72
-
73
- <DatePickerModalContent
74
- {...rest}
75
- mode={mode as any}
76
- disableSafeTop={disableStatusBar}
77
- />
78
- </>
79
- </Modal>
80
- </Portal>
81
- </View>
82
- );
83
- }
84
-
85
- export default memo(DatePickerModal);
@@ -1,155 +0,0 @@
1
- import { memo, useCallback, useState } from 'react';
2
-
3
- import { useControlledValue } from '../../hooks';
4
- import { DatePickerInlineBase, getStateValue } from '../DatePickerInline';
5
- import DatePickerInlineHeader from '../DatePickerInline/DatePickerInlineHeader';
6
- import AnimatedCrossView from './AnimatedCrossView';
7
- import CalendarEdit from './CalendarEdit';
8
- import DatePickerModalContentHeader from './DatePickerModalContentHeader';
9
- import DatePickerModalHeader from './DatePickerModalHeader';
10
- import DatePickerModalHeaderBackground from './DatePickerModalHeaderBackground';
11
- import type {
12
- DatePickerModalContentMultiProps,
13
- DatePickerModalContentRangeProps,
14
- DatePickerModalContentSingleProps,
15
- LocalState,
16
- LocalStateMultiple,
17
- LocalStateRange,
18
- LocalStateSingle,
19
- } from './types';
20
-
21
- type Props =
22
- | DatePickerModalContentSingleProps
23
- | DatePickerModalContentRangeProps
24
- | DatePickerModalContentMultiProps;
25
-
26
- export function DatePickerModalContent(props: Props) {
27
- const {
28
- mode = 'single',
29
- onChange,
30
- onConfirm,
31
- onClose,
32
- disableSafeTop,
33
- disableWeekDays,
34
- // locale = 'en',
35
- validRange,
36
- dateMode,
37
- startYear,
38
- endYear,
39
- date,
40
- startDate,
41
- endDate,
42
- dates,
43
- } = props;
44
- const [collapsed, setCollapsed] = useState<boolean>(true);
45
-
46
- const onInnerChange = useCallback(
47
- (params: any) => {
48
- onChange?.(params);
49
- },
50
- [onChange],
51
- );
52
-
53
- const [state, onStateChange] = useControlledValue<LocalState>({
54
- value: getStateValue(
55
- {
56
- date,
57
- dates,
58
- startDate,
59
- endDate,
60
- },
61
- mode,
62
- ),
63
- onChange: onInnerChange,
64
- });
65
-
66
- const onInnerConfirm = useCallback(() => {
67
- if (mode === 'single') {
68
- (onConfirm as DatePickerModalContentSingleProps['onConfirm'])?.({
69
- date: (state as LocalStateSingle)?.date,
70
- });
71
- } else if (mode === 'range') {
72
- (onConfirm as DatePickerModalContentRangeProps['onConfirm'])?.({
73
- startDate: (state as LocalStateRange)?.startDate,
74
- endDate: (state as LocalStateRange)?.endDate,
75
- });
76
- } else if (mode === 'multiple') {
77
- (onConfirm as DatePickerModalContentMultiProps['onConfirm'])?.({
78
- dates: (state as LocalStateMultiple)?.dates || [],
79
- });
80
- }
81
- }, [state, mode, onConfirm]);
82
-
83
- const onToggleCollapse = useCallback(() => {
84
- setCollapsed(prev => !prev);
85
- }, [setCollapsed]);
86
-
87
- return (
88
- <>
89
- <DatePickerModalHeaderBackground>
90
- <DatePickerModalHeader
91
- onSave={onInnerConfirm}
92
- onClose={onClose}
93
- saveLabel={props.saveLabel}
94
- saveLabelDisabled={props.saveLabelDisabled || false}
95
- disableSafeTop={disableSafeTop}
96
- closeIcon={props.closeIcon}
97
- />
98
- <DatePickerModalContentHeader
99
- state={state || { startDate, dates, date, endDate }}
100
- mode={mode}
101
- collapsed={collapsed}
102
- onToggle={onToggleCollapse}
103
- headerSeparator={props.headerSeparator}
104
- emptyLabel={props.emptyLabel}
105
- label={props.label}
106
- moreLabel={props.moreLabel}
107
- startLabel={props.startLabel}
108
- endLabel={props.endLabel}
109
- uppercase={props.uppercase || true}
110
- // locale={locale}
111
- editIcon={props.editIcon}
112
- calendarIcon={props.calendarIcon}
113
- />
114
- </DatePickerModalHeaderBackground>
115
-
116
- <AnimatedCrossView
117
- collapsed={collapsed}
118
- calendar={
119
- <DatePickerInlineBase
120
- // locale={locale}
121
- mode={mode}
122
- startDate={(state as LocalStateRange)?.startDate}
123
- endDate={(state as LocalStateRange)?.endDate}
124
- date={(state as LocalStateSingle)?.date}
125
- onChange={onStateChange as typeof onInnerChange}
126
- disableWeekDays={disableWeekDays}
127
- dates={(state as LocalStateMultiple)?.dates}
128
- validRange={validRange}
129
- dateMode={dateMode}
130
- startYear={startYear}
131
- endYear={endYear}
132
- // TODO - fix ts issues
133
- // @ts-ignore
134
- HeaderComponent={DatePickerInlineHeader}
135
- />
136
- }
137
- calendarEdit={
138
- <CalendarEdit
139
- mode={mode}
140
- state={state || { startDate, dates, date, endDate }}
141
- label={props.label}
142
- startLabel={props.startLabel}
143
- endLabel={props.endLabel}
144
- collapsed={collapsed}
145
- onChange={onStateChange}
146
- validRange={validRange}
147
- // locale={locale}
148
- />
149
- }
150
- />
151
- </>
152
- );
153
- }
154
-
155
- export default memo(DatePickerModalContent);