Skip to content

Commit 7bc7398

Browse files
authored
feat(infiniteAgendaList): add the ability to set item height per item (#2515)
* feat(infiniteAgendaList): add the ability to set item height per item * Update infiniteAgendaList.tsx * add example * Fix PR comment * Rename itemType to itemCustomHeightType
1 parent 6b091db commit 7bc7398

File tree

7 files changed

+105
-9
lines changed

7 files changed

+105
-9
lines changed

example/src/mocks/agendaItems.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ function getPastDate(numberOfDays: number) {
2828
export const agendaItems = [
2929
{
3030
title: dates[0],
31-
data: [{hour: '12am', duration: '1h', title: 'First Yoga'}]
31+
data: [{hour: '12am', duration: '1h', title: 'First Yoga'}, {hour: '9am', duration: '1h', title: 'Long Yoga', itemCustomHeightType: 'LongEvent'}],
3232
},
3333
{
3434
title: dates[1],
@@ -63,13 +63,13 @@ export const agendaItems = [
6363
]
6464
},
6565
{
66-
title: dates[6],
66+
title: dates[6],
6767
data: [
6868
{hour: '12am', duration: '1h', title: 'Ashtanga Yoga'}
6969
]
7070
},
7171
{
72-
title: dates[7],
72+
title: dates[7],
7373
data: [{}]
7474
},
7575
{
@@ -90,7 +90,7 @@ export const agendaItems = [
9090
]
9191
},
9292
{
93-
title: dates[10],
93+
title: dates[10],
9494
data: [
9595
{hour: '12am', duration: '1h', title: 'Last Yoga'}
9696
]
@@ -104,13 +104,13 @@ export const agendaItems = [
104104
]
105105
},
106106
{
107-
title: dates[12],
107+
title: dates[12],
108108
data: [
109109
{hour: '12am', duration: '1h', title: 'Last Yoga'}
110110
]
111111
},
112112
{
113-
title: dates[13],
113+
title: dates[13],
114114
data: [
115115
{hour: '12am', duration: '1h', title: 'Last Yoga'}
116116
]
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import React, {useRef, useCallback} from 'react';
2+
import {StyleSheet, View} from 'react-native';
3+
import {ExpandableCalendar, AgendaList, CalendarProvider, WeekCalendar} from 'react-native-calendars';
4+
import testIDs from '../testIDs';
5+
import {agendaItems, getMarkedDates} from '../mocks/agendaItems';
6+
import AgendaItem from '../mocks/AgendaItem';
7+
import {getTheme, themeColor, lightThemeColor} from '../mocks/theme';
8+
9+
const leftArrowIcon = require('../img/previous.png');
10+
const rightArrowIcon = require('../img/next.png');
11+
const ITEMS: any[] = agendaItems;
12+
13+
interface Props {
14+
weekView?: boolean;
15+
}
16+
17+
const AgendaInfiniteListScreen = (props: Props) => {
18+
const {weekView} = props;
19+
const marked = useRef(getMarkedDates());
20+
const theme = useRef(getTheme());
21+
const todayBtnTheme = useRef({
22+
todayButtonTextColor: themeColor
23+
});
24+
25+
const renderItem = useCallback(({item}: any) => {
26+
const isLongItem = item.itemCustomHeightType === 'LongEvent';
27+
return <View style={{paddingTop: isLongItem ? 40 : 0}}><AgendaItem item={item}/></View>;
28+
}, []);
29+
30+
return (
31+
<CalendarProvider
32+
date={ITEMS[1]?.title}
33+
showTodayButton
34+
theme={todayBtnTheme.current}
35+
>
36+
{weekView ? (
37+
<WeekCalendar testID={testIDs.weekCalendar.CONTAINER} firstDay={1} markedDates={marked.current}/>
38+
) : (
39+
<ExpandableCalendar
40+
testID={testIDs.expandableCalendar.CONTAINER}
41+
theme={theme.current}
42+
firstDay={1}
43+
markedDates={marked.current}
44+
leftArrowImageSource={leftArrowIcon}
45+
rightArrowImageSource={rightArrowIcon}
46+
/>
47+
)}
48+
<AgendaList
49+
sections={ITEMS}
50+
renderItem={renderItem}
51+
sectionStyle={styles.section}
52+
infiniteListProps={
53+
{
54+
itemHeight: 80,
55+
titleHeight: 50,
56+
itemHeightByType: {
57+
LongEvent: 120,
58+
}
59+
}
60+
}
61+
/>
62+
</CalendarProvider>
63+
);
64+
};
65+
66+
export default AgendaInfiniteListScreen;
67+
68+
const styles = StyleSheet.create({
69+
calendar: {
70+
paddingLeft: 20,
71+
paddingRight: 20
72+
},
73+
header: {
74+
backgroundColor: 'lightgrey'
75+
},
76+
section: {
77+
backgroundColor: lightThemeColor,
78+
color: 'grey',
79+
textTransform: 'capitalize'
80+
}
81+
});

example/src/screens/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import MenuScreen from './menuScreen';
44
import CalendarScreen from './calendarScreen';
55
import CalendarPlaygroundScreen from './calendarPlaygroundScreen';
66
import AgendaScreen from './agendaScreen';
7+
import AgendaInfiniteListScreen from './agendaInfiniteListScreen';
78
import CalendarsListScreen from './calendarListScreen';
89
import NewCalendarsListScreen from './newCalendarListScreen';
910
import ExpandableCalendarScreen from './expandableCalendarScreen';
@@ -16,6 +17,7 @@ export function registerScreens() {
1617
Navigation.registerComponent('CalendarScreen', () => CalendarScreen);
1718
Navigation.registerComponent('CalendarPlaygroundScreen', () => CalendarPlaygroundScreen);
1819
Navigation.registerComponent('AgendaScreen', () => AgendaScreen);
20+
Navigation.registerComponent('AgendaInfiniteListScreen', () => AgendaInfiniteListScreen);
1921
Navigation.registerComponent('CalendarListScreen', () => CalendarsListScreen);
2022
Navigation.registerComponent('NewCalendarListScreen', () => NewCalendarsListScreen);
2123
Navigation.registerComponent('ExpandableCalendarScreen', () => ExpandableCalendarScreen);

example/src/screens/menuScreen.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ interface Props {
1414
const MenuScreen = (props: Props) => {
1515
const {componentId} = props;
1616
const [forceRTL, setForceRTL] = useState(false);
17-
17+
1818
const toggleRTL = (value) => {
1919
I18nManager.forceRTL(value);
2020
setForceRTL(value);
@@ -67,6 +67,7 @@ const MenuScreen = (props: Props) => {
6767
{renderEntry(testIDs.menu.HORIZONTAL_LIST, 'Horizontal Calendar List', 'CalendarListScreen', {horizontalView: true})}
6868
{renderEntry(testIDs.menu.HORIZONTAL_LIST, 'NEW Calendar List', 'NewCalendarListScreen')}
6969
{renderEntry(testIDs.menu.AGENDA, 'Agenda', 'AgendaScreen')}
70+
{renderEntry(testIDs.menu.AGENDA_INFINITE, 'Agenda Infinite List', 'AgendaInfiniteListScreen')}
7071
{renderEntry(testIDs.menu.EXPANDABLE_CALENDAR, 'Expandable Calendar', 'ExpandableCalendarScreen')}
7172
{renderEntry(testIDs.menu.TIMELINE_CALENDAR, 'Timeline Calendar', 'TimelineCalendarScreen')}
7273
{renderEntry(testIDs.menu.WEEK_CALENDAR, 'Week Calendar', 'ExpandableCalendarScreen', {weekView: true})}

example/src/testIDs.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export default {
55
CALENDAR_LIST: 'calendar_list_btn',
66
HORIZONTAL_LIST: 'horizontal_list_btn',
77
AGENDA: 'agenda_btn',
8+
AGENDA_INFINITE: 'agenda_infinite_btn',
89
EXPANDABLE_CALENDAR: 'expandable_calendar_btn',
910
WEEK_CALENDAR: 'week_calendar_btn',
1011
TIMELINE_CALENDAR: 'timeline_calendar_btn',

src/expandableCalendar/AgendaListsCommon.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ export interface AgendaListProps extends SectionListProps<any, DefaultSectionT>
3030
infiniteListProps?: {
3131
itemHeight?: number;
3232
titleHeight?: number;
33+
/** item height by type, require passing itemCustomHeightType in the elements you want to set custom height */
34+
itemHeightByType?: Record<string, number>;
3335
visibleIndicesChangedDebounce?: number;
3436
renderFooter?: () => React.ReactElement | null;
3537
};

src/expandableCalendar/infiniteAgendaList.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,19 @@ const InfiniteAgendaList = ({
149149

150150
const layoutProvider = useMemo(
151151
() => new LayoutProvider(
152-
(index) => dataRef.current[index]?.isTitle ? 'title': 'page',
152+
(index) => dataRef.current[index]?.isTitle ? 'title': dataRef.current[index]?.itemCustomHeightType ?? 'page',
153153
(type, dim) => {
154154
dim.width = constants.screenWidth;
155-
dim.height = type === 'title' ? infiniteListProps?.titleHeight ?? 60 : infiniteListProps?.itemHeight ?? 80;
155+
switch (type) {
156+
case 'title':
157+
dim.height = infiniteListProps?.titleHeight ?? 60;
158+
break;
159+
case 'page':
160+
dim.height = infiniteListProps?.itemHeight ?? 80;
161+
break;
162+
default:
163+
dim.height = infiniteListProps?.itemHeightByType?.[type] ?? infiniteListProps?.itemHeight ?? 80;
164+
}
156165
}
157166
),
158167
[]

0 commit comments

Comments
 (0)