Skip to content

Commit c6ed03c

Browse files
authored
Move 'TodayButton' to a separate component (#1999)
* ContextProvider - move TodayButton to a separate component * Adding context
1 parent 9b52caf commit c6ed03c

File tree

5 files changed

+173
-287
lines changed

5 files changed

+173
-287
lines changed

example/src/screens/expandableCalendarScreen.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ const ExpandableCalendarScreen = (props: Props) => {
4040
// onDateChanged={onDateChanged}
4141
// onMonthChange={onMonthChange}
4242
showTodayButton
43-
disabledOpacity={0.6}
43+
disabledOpacity={0.5}
4444
theme={todayBtnTheme.current}
4545
// todayBottomMargin={16}
4646
>

src/expandableCalendar/Context/Presenter.spec.js

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

src/expandableCalendar/Context/Presenter.ts

Lines changed: 0 additions & 64 deletions
This file was deleted.
Lines changed: 17 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import XDate from 'xdate';
22

3-
import React, {useEffect, useRef, useState, useCallback, useMemo} from 'react';
4-
import {Animated, TouchableOpacity, View, ViewStyle, ViewProps, StyleProp} from 'react-native';
3+
import React, {useRef, useState, useCallback, useMemo} from 'react';
4+
import {View, ViewStyle, ViewProps, StyleProp} from 'react-native';
55

66
import {sameMonth} from '../../dateutils';
77
import {xdateToData} from '../../interface';
@@ -10,17 +10,7 @@ import {Theme, DateData} from '../../types';
1010
import {UpdateSources} from '../commons';
1111
import styleConstructor from '../style';
1212
import CalendarContext from './index';
13-
import {
14-
shouldAnimateTodayButton,
15-
shouldAnimateOpacity,
16-
getButtonIcon,
17-
getPositionAnimation,
18-
getOpacityAnimation,
19-
getTodayDate,
20-
getTodayFormatted
21-
} from './Presenter';
22-
23-
const TOP_POSITION = 65;
13+
import TodayButton, {TodayButtonImperativeMethods} from './todayButton';
2414

2515
export interface CalendarContextProviderProps extends ViewProps {
2616
/** Initial date in 'yyyy-MM-dd' format. Default = now */
@@ -33,6 +23,7 @@ export interface CalendarContextProviderProps extends ViewProps {
3323
onDateChanged?: (date: string, updateSource: UpdateSources) => void;
3424
/** Callback for month change event */
3525
onMonthChange?: (date: DateData, updateSource: UpdateSources) => void;
26+
3627
/** Whether to show the today button */
3728
showTodayButton?: boolean;
3829
/** Today button's top position */
@@ -41,6 +32,7 @@ export interface CalendarContextProviderProps extends ViewProps {
4132
todayButtonStyle?: ViewStyle;
4233
/** The opacity for the disabled today button (0-1) */
4334
disabledOpacity?: number;
35+
4436
/** The number of days to present in the timeline calendar */
4537
numberOfDays?: number;
4638
/** The left inset of the timeline calendar (sidebar width), default is 72 */
@@ -58,6 +50,7 @@ const CalendarProvider = (props: CalendarContextProviderProps) => {
5850
onDateChanged,
5951
onMonthChange,
6052
showTodayButton = false,
53+
disabledOpacity,
6154
todayBottomMargin,
6255
todayButtonStyle,
6356
style: propsStyle,
@@ -66,15 +59,11 @@ const CalendarProvider = (props: CalendarContextProviderProps) => {
6659
children
6760
} = props;
6861
const style = useRef(styleConstructor(theme));
69-
const buttonY = useRef(new Animated.Value(todayBottomMargin ? -todayBottomMargin : -TOP_POSITION));
70-
const opacity = useRef(new Animated.Value(1));
71-
const today = useRef(getTodayFormatted());
62+
const todayButton = useRef<TodayButtonImperativeMethods>();
7263
const prevDate = useRef(date);
7364
const currDate = useRef(date); // for setDate only to keep prevDate up to date
7465
const [currentDate, setCurrentDate] = useState(date);
7566
const [updateSource, setUpdateSource] = useState(UpdateSources.CALENDAR_INIT);
76-
const [isDisabled, setIsDisabled] = useState(false);
77-
const [buttonIcon, setButtonIcon] = useState(getButtonIcon(date, showTodayButton));
7867

7968
const wrapperStyle = useMemo(() => {
8069
return [style.current.contextWrapper, propsStyle];
@@ -86,18 +75,11 @@ const CalendarProvider = (props: CalendarContextProviderProps) => {
8675
}
8776
}, [date]);
8877

89-
useEffect(() => {
90-
animateTodayButton(currentDate);
91-
}, [todayBottomMargin, currentDate]);
92-
93-
/** Context */
94-
9578
const _setDate = useCallback((date: string, updateSource: UpdateSources) => {
9679
prevDate.current = currDate.current;
9780
currDate.current = date;
9881
setCurrentDate(date);
9982
setUpdateSource(updateSource);
100-
setButtonIcon(getButtonIcon(date, showTodayButton));
10183

10284
onDateChanged?.(date, updateSource);
10385

@@ -107,12 +89,10 @@ const CalendarProvider = (props: CalendarContextProviderProps) => {
10789
}, [onDateChanged, onMonthChange]);
10890

10991
const _setDisabled = useCallback((disabled: boolean) => {
110-
if (!showTodayButton || disabled === isDisabled) {
111-
return;
92+
if (showTodayButton) {
93+
todayButton.current?.disable(disabled);
11294
}
113-
setIsDisabled(disabled);
114-
animateOpacity(disabled);
115-
}, [showTodayButton, isDisabled]);
95+
}, [showTodayButton]);
11696

11797
const contextValue = useMemo(() => {
11898
return {
@@ -126,50 +106,15 @@ const CalendarProvider = (props: CalendarContextProviderProps) => {
126106
};
127107
}, [currentDate, updateSource, numberOfDays, _setDisabled]);
128108

129-
/** Animations */
130-
131-
const animateTodayButton = (date: string) => {
132-
if (shouldAnimateTodayButton(props)) {
133-
const animationData = getPositionAnimation(date, todayBottomMargin);
134-
135-
Animated.spring(buttonY.current, {
136-
...animationData
137-
}).start();
138-
}
139-
};
140-
141-
const animateOpacity = (disabled: boolean) => {
142-
if (shouldAnimateOpacity(props)) {
143-
const animationData = getOpacityAnimation(props, disabled);
144-
145-
Animated.timing(opacity.current, {
146-
...animationData
147-
}).start();
148-
}
149-
};
150-
151-
/** Events */
152-
153-
const onTodayPress = useCallback(() => {
154-
_setDate(getTodayDate(), UpdateSources.TODAY_PRESS);
155-
}, [_setDate]);
156-
157-
/** Renders */
158-
159109
const renderTodayButton = () => {
160110
return (
161-
<Animated.View style={[style.current.todayButtonContainer, {transform: [{translateY: buttonY.current}]}]}>
162-
<TouchableOpacity
163-
style={[style.current.todayButton, todayButtonStyle]}
164-
onPress={onTodayPress}
165-
disabled={isDisabled}
166-
>
167-
<Animated.Image style={[style.current.todayButtonImage, {opacity: opacity.current}]} source={buttonIcon}/>
168-
<Animated.Text allowFontScaling={false} style={[style.current.todayButtonText, {opacity: opacity.current}]}>
169-
{today.current}
170-
</Animated.Text>
171-
</TouchableOpacity>
172-
</Animated.View>
111+
<TodayButton
112+
ref={todayButton}
113+
disabledOpacity={disabledOpacity}
114+
margin={todayBottomMargin}
115+
style={todayButtonStyle}
116+
theme={theme}
117+
/>
173118
);
174119
};
175120

@@ -182,5 +127,4 @@ const CalendarProvider = (props: CalendarContextProviderProps) => {
182127
};
183128

184129
export default CalendarProvider;
185-
186130
CalendarProvider.displayName = 'CalendarProvider';

0 commit comments

Comments
 (0)