Skip to content

Commit

Permalink
Add beginAgendaAt and endAgendaAt props (#183)
Browse files Browse the repository at this point in the history
  • Loading branch information
pdpino authored Apr 18, 2022
1 parent 795a222 commit 78159e8
Showing 5 changed files with 66 additions and 29 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -70,11 +70,13 @@ const MyComponent = () => (
| `onDayPress` | _Function:_ `(date, formattedDate) => {}` | `null` | Callback when a day from the header is pressed. |
| `onMonthPress` | _Function:_ `(date, formattedDate) => {}` | `null` | Callback when the month at the top left (title) is pressed. |
|**_Week-view <br> customizations_**|
| `startHour` | _Number_ | `8` (8 am) | Vertical position of the week-view in the first render (vertically in the agenda). |
| `startHour` | _Number_, in hours | `8` (8 am) | Vertical position of the week-view in the first render (vertically in the agenda). |
| `weekStartsOn` | _Number_ | `1` (Monday) | First day of the week, i.e. day to show at the left of the week-view (0 is Sunday, 1 is Monday, and so on). Only useful when `numberOfDays === 7` or `fixedHorizontally` is true. |
| `showTitle` | _Boolean_ | `true` | Show or hide the selected month and year in the top-left corner (a.k.a the title). |
| `hoursInDisplay` | _Number_ | `6` | Amount of hours to display vertically in the agenda. Increasing this number will make the events look smaller. |
| `timeStep` | _Number_ | `60` (minutes) | Number of minutes to use as step in the time labels at the left. Increasing this number will increase the vertical space between grid lines. |
| `hoursInDisplay` | _Number_, in hours | `6` | Amount of hours to display vertically in the agenda. Increasing this number will make the events look smaller. |
| `beginAgendaAt` | _Number_, in minutes | `0` (0h) | Time of day to start the agenda at the top (grid above is left out). For example, for 8 am set `beginAgendaAt={8*60}`. |
| `endAgendaAt` | _Number_, in minutes | `24 * 60` (24h) | Time of day to end the agenda at the bottom (grid below is left out). For example, for 10pm set `engAgendaAt={22*60}`. |
| `timeStep` | _Number_, in minutes | `60` | Number of minutes to use as step in the time labels at the left. Increasing this number will increase the vertical space between grid lines. |
| `formatDateHeader` | _String_ | `"MMM D"` (e.g. "Apr 3") | Formatter for dates in the header. See [all formatters in momentjs](https://momentjs.com/docs/#/displaying/format/). |
| `formatTimeLabel` | _String_ | `"H:mm"` (24 hours) | Formatter for the time labels at the left. Other examples, AM/PM: `"h:mm A"` or `"h:mm a"` for lowercase. See [all formatters in momentjs](https://momentjs.com/docs/#/displaying/format/). |
| `EventComponent` | _ReactComponent_ | `Text` | Custom component rendered inside an event. By default, is a `Text` with the `event.description`. See [sub-section below](#custom-eventcomponent) for details on the component. |
2 changes: 2 additions & 0 deletions example/App.js
Original file line number Diff line number Diff line change
@@ -145,6 +145,8 @@ class App extends React.Component {
formatDateHeader={showFixedComponent ? 'ddd' : 'ddd DD'}
hoursInDisplay={12}
timeStep={60}
beginAgendaAt={5 * 60}
endAgendaAt={23 * 60}
startHour={8}
fixedHorizontally={showFixedComponent}
showTitle={!showFixedComponent}
27 changes: 19 additions & 8 deletions src/Events/Events.js
Original file line number Diff line number Diff line change
@@ -31,12 +31,14 @@ const areEventsOverlapped = (event1EndDate, event2StartDate) => {
return endDate.isSameOrAfter(event2StartDate);
};

const getStyleForEvent = (event, regularItemWidth, hoursInDisplay) => {
const getStyleForEvent = (event, regularItemWidth, hoursInDisplay, beginAgendaAt) => {
const startDate = moment(event.startDate);
const startHours = startDate.hours();
const startMinutes = startDate.minutes();
const totalStartMinutes = startHours * MINUTES_IN_HOUR + startMinutes;
const top = minutesToYDimension(hoursInDisplay, totalStartMinutes);
const verticalOffset = minutesToYDimension(hoursInDisplay, beginAgendaAt);
const top = minutesToYDimension(hoursInDisplay, totalStartMinutes) - verticalOffset;

const deltaMinutes = moment(event.endDate).diff(event.startDate, 'minutes');
const height = minutesToYDimension(hoursInDisplay, deltaMinutes);

@@ -115,12 +117,14 @@ const addOverlappedToArray = (baseArr, overlappedArr, itemWidth) => {
});
};

const getEventsWithPosition = (totalEvents, regularItemWidth, hoursInDisplay) => {
const getEventsWithPosition = (
totalEvents, regularItemWidth, hoursInDisplay, beginAgendaAt,
) => {
return totalEvents.map((events) => {
let overlappedSoFar = []; // Store events overlapped until now
let lastDate = null;
const eventsWithStyle = events.reduce((eventsAcc, event) => {
const style = getStyleForEvent(event, regularItemWidth, hoursInDisplay);
const style = getStyleForEvent(event, regularItemWidth, hoursInDisplay, beginAgendaAt);
const eventWithStyle = {
data: event,
style,
@@ -152,9 +156,10 @@ const getEventsWithPosition = (totalEvents, regularItemWidth, hoursInDisplay) =>

class Events extends PureComponent {
yToHour = (y) => {
const { hoursInDisplay } = this.props;
const hour = (y * hoursInDisplay) / CONTAINER_HEIGHT;
return hour;
const { hoursInDisplay, beginAgendaAt } = this.props;
const hour = (y * hoursInDisplay) / CONTAINER_HEIGHT; // yDimensionToHours()
const agendaOffset = beginAgendaAt / 60; // in hours
return hour + agendaOffset;
};

getEventItemWidth = (padded = true) => {
@@ -164,7 +169,9 @@ class Events extends PureComponent {
};

processEvents = memoizeOne(
(eventsByDate, initialDate, numberOfDays, hoursInDisplay, rightToLeft) => {
(eventsByDate, initialDate, numberOfDays, hoursInDisplay, rightToLeft,
beginAgendaAt,
) => {
// totalEvents stores events in each day of numberOfDays
// example: [[event1, event2], [event3, event4], [event5]], each child array
// is events for specific day in range
@@ -180,6 +187,7 @@ class Events extends PureComponent {
totalEvents,
regularItemWidth,
hoursInDisplay,
beginAgendaAt,
);
return totalEventsWithPosition;
},
@@ -256,6 +264,7 @@ class Events extends PureComponent {
rightToLeft,
hoursInDisplay,
timeStep,
beginAgendaAt,
showNowLine,
nowLineColor,
onDragEvent,
@@ -266,6 +275,7 @@ class Events extends PureComponent {
numberOfDays,
hoursInDisplay,
rightToLeft,
beginAgendaAt,
);
const timeSlotHeight = getTimeLabelHeight(hoursInDisplay, timeStep);

@@ -294,6 +304,7 @@ class Events extends PureComponent {
color={nowLineColor}
hoursInDisplay={hoursInDisplay}
width={this.getEventItemWidth(false)}
beginAgendaAt={beginAgendaAt}
/>
)}
{eventsInSection.map((item) => (
14 changes: 10 additions & 4 deletions src/NowLine/NowLine.js
Original file line number Diff line number Diff line change
@@ -7,17 +7,21 @@ import styles from './NowLine.styles';

const UPDATE_EVERY_MILLISECONDS = 60 * 1000; // 1 minute

const getCurrentTop = (hoursInDisplay) => {
const getCurrentTop = (hoursInDisplay, beginAgendaAt) => {
const now = new Date();
const minutes = now.getHours() * 60 + now.getMinutes();
return minutesToYDimension(hoursInDisplay, minutes) + CONTENT_OFFSET;
const position = minutesToYDimension(hoursInDisplay, minutes);
const agendaOffset = minutesToYDimension(hoursInDisplay, beginAgendaAt);
return position - agendaOffset + CONTENT_OFFSET;
};

class NowLine extends React.Component {
constructor(props) {
super(props);

this.initialTop = getCurrentTop(this.props.hoursInDisplay);
const { hoursInDisplay, beginAgendaAt } = this.props;

this.initialTop = getCurrentTop(hoursInDisplay, beginAgendaAt);

this.state = {
currentTranslateY: new Animated.Value(0),
@@ -45,7 +49,9 @@ class NowLine extends React.Component {
}

updateLinePosition = (animationDuration) => {
const newTop = getCurrentTop(this.props.hoursInDisplay);
const { hoursInDisplay, beginAgendaAt } = this.props;

const newTop = getCurrentTop(hoursInDisplay, beginAgendaAt);
Animated.timing(this.state.currentTranslateY, {
toValue: newTop - this.initialTop,
duration: animationDuration,
44 changes: 30 additions & 14 deletions src/WeekView/WeekView.js
Original file line number Diff line number Diff line change
@@ -18,14 +18,30 @@ import Title from '../Title/Title';
import Times from '../Times/Times';
import styles from './WeekView.styles';
import {
CONTAINER_HEIGHT,
DATE_STR_FORMAT,
availableNumberOfDays,
setLocale,
CONTAINER_WIDTH,
minutesToYDimension,
} from '../utils';

const MINUTES_IN_DAY = 60 * 24;
const calculateTimesArray = (
minutesStep, formatTimeLabel, beginAt = 0, endAt = MINUTES_IN_DAY,
) => {
const times = [];
const startOfDay = moment().startOf('day');
for (
let timer = (0 <= beginAt && beginAt < MINUTES_IN_DAY) ? beginAt : 0;
timer < endAt && timer < MINUTES_IN_DAY;
timer += minutesStep
) {
const time = startOfDay.clone().minutes(timer);
times.push(time.format(formatTimeLabel));
}

return times;
};

export default class WeekView extends Component {
constructor(props) {
@@ -93,21 +109,14 @@ export default class WeekView extends Component {
this.eventsGridScrollX.removeAllListeners();
}

calculateTimes = memoizeOne((minutesStep, formatTimeLabel) => {
const times = [];
const startOfDay = moment().startOf('day');
for (let timer = 0; timer < MINUTES_IN_DAY; timer += minutesStep) {
const time = startOfDay.clone().minutes(timer);
times.push(time.format(formatTimeLabel));
}
return times;
});
calculateTimes = memoizeOne(calculateTimesArray);

scrollToVerticalStart = () => {
if (this.verticalAgenda) {
const { startHour, hoursInDisplay } = this.props;
const startHeight = (startHour * CONTAINER_HEIGHT) / hoursInDisplay;
this.verticalAgenda.scrollTo({ y: startHeight, x: 0, animated: false });
const { startHour, hoursInDisplay, beginAgendaAt } = this.props;
const startHeight = minutesToYDimension(hoursInDisplay, startHour * 60);
const agendaOffset = minutesToYDimension(hoursInDisplay, beginAgendaAt);
this.verticalAgenda.scrollTo({ y: startHeight - agendaOffset, x: 0, animated: false });
}
};

@@ -381,6 +390,8 @@ export default class WeekView extends Component {
events,
hoursInDisplay,
timeStep,
beginAgendaAt,
endAgendaAt,
formatTimeLabel,
onGridClick,
onGridLongPress,
@@ -397,7 +408,7 @@ export default class WeekView extends Component {
RefreshComponent,
} = this.props;
const { currentMoment, initialDates } = this.state;
const times = this.calculateTimes(timeStep, formatTimeLabel);
const times = this.calculateTimes(timeStep, formatTimeLabel, beginAgendaAt, endAgendaAt);
const eventsByDate = this.sortEventsByDate(events);
const horizontalInverted =
(prependMostRecent && !rightToLeft) ||
@@ -485,6 +496,7 @@ export default class WeekView extends Component {
onGridLongPress={onGridLongPress}
hoursInDisplay={hoursInDisplay}
timeStep={timeStep}
beginAgendaAt={beginAgendaAt}
EventComponent={EventComponent}
eventContainerStyle={eventContainerStyle}
gridRowStyle={gridRowStyle}
@@ -544,6 +556,8 @@ WeekView.propTypes = {
locale: PropTypes.string,
hoursInDisplay: PropTypes.number,
timeStep: PropTypes.number,
beginAgendaAt: PropTypes.number,
endAgendaAt: PropTypes.number,
formatTimeLabel: PropTypes.string,
startHour: PropTypes.number,
EventComponent: PropTypes.elementType,
@@ -568,6 +582,8 @@ WeekView.defaultProps = {
hoursInDisplay: 6,
weekStartsOn: 1,
timeStep: 60,
beginAgendaAt: 0,
endAgendaAt: MINUTES_IN_DAY,
formatTimeLabel: 'H:mm',
startHour: 8,
showTitle: true,

0 comments on commit 78159e8

Please sign in to comment.