From 69c16e787e496e9a973ea4ea8d5b567ecc23c1cd Mon Sep 17 00:00:00 2001 From: Alex Koehler Date: Fri, 11 May 2018 14:25:28 -0500 Subject: [PATCH 1/5] Added DnD support for custom DateCellWrapper and DayWrapper components --- src/addons/dragAndDrop/DropWrappers.js | 10 +++- src/addons/dragAndDrop/withDragAndDrop.js | 3 + stories/Calendar.js | 69 +++++++++++++++++++++++ 3 files changed, 79 insertions(+), 3 deletions(-) diff --git a/src/addons/dragAndDrop/DropWrappers.js b/src/addons/dragAndDrop/DropWrappers.js index 06b3cdf90..6285e6781 100644 --- a/src/addons/dragAndDrop/DropWrappers.js +++ b/src/addons/dragAndDrop/DropWrappers.js @@ -16,12 +16,12 @@ function getEventDropProps(start, end, dropDate, droppedInAllDay) { /* * If the event is dropped in a "Day" cell, preserve an event's start time by extracting the hours and minutes off * the original start date and add it to newDate.value - * + * * note: this behavior remains for backward compatibility, but might be counter-intuitive to some: * dragging an event from the grid to the day header might more commonly mean "make this an allDay event * on that day" - but the behavior here implements "keep the times of the event, but move it to the * new day". - * + * * To permit either interpretation, we embellish a new `allDay` parameter which determines whether the * event was dropped on the day header or not. */ @@ -46,6 +46,7 @@ class DropWrapper extends React.Component { static contextTypes = { onEventDrop: PropTypes.func, onEventResize: PropTypes.func, + components: PropTypes.object, dragDropManager: PropTypes.object, startAccessor: accessor, endAccessor: accessor, @@ -99,7 +100,10 @@ class DropWrapper extends React.Component { render() { const { connectDropTarget, children, type, isOver } = this.props - const BackgroundWrapper = BigCalendar.components[type] + + // Check if wrapper component of this type was passed in, otherwise use library default + const { components } = this.context + const BackgroundWrapper = components[type] || BigCalendar.components[type] let resultingChildren = children if (isOver) diff --git a/src/addons/dragAndDrop/withDragAndDrop.js b/src/addons/dragAndDrop/withDragAndDrop.js index fb576ca56..1d0f64ccf 100644 --- a/src/addons/dragAndDrop/withDragAndDrop.js +++ b/src/addons/dragAndDrop/withDragAndDrop.js @@ -78,6 +78,7 @@ export default function withDragAndDrop( static defaultProps = { // TODO: pick these up from Calendar.defaultProps + components: {}, startAccessor: 'start', endAccessor: 'end', allDayAccessor: 'allDay', @@ -92,6 +93,7 @@ export default function withDragAndDrop( static childContextTypes = { onEventDrop: PropTypes.func, onEventResize: PropTypes.func, + components: PropTypes.object, startAccessor: accessor, endAccessor: accessor, draggableAccessor: accessor, @@ -102,6 +104,7 @@ export default function withDragAndDrop( return { onEventDrop: this.props.onEventDrop, onEventResize: this.props.onEventResize, + components: this.props.components, startAccessor: this.props.startAccessor, endAccessor: this.props.endAccessor, step: this.props.step, diff --git a/stories/Calendar.js b/stories/Calendar.js index 4c8085005..5f8e08ed9 100644 --- a/stories/Calendar.js +++ b/stories/Calendar.js @@ -372,6 +372,38 @@ storiesOf('module.Calendar.week', module) ) }) + .add('add custom dateCellWrapper', () => { + const components = { + dateCellWrapper: props => { + const hasAlert = Math.random() <= 1 / 3 + const style = { + display: 'flex', + flex: 1, + borderLeft: '1px solid #DDD', + backgroundColor: hasAlert ? 'green' : '#fff', + } + return ( +
+ {hasAlert && ( + + Click me + + )} + {props.children} +
+ ) + }, + } + return ( +
+ +
+ ) + }) .add('no duration', () => { return (
@@ -561,3 +593,40 @@ storiesOf('module.Calendar.week', module)
) }) + .add('draggable and resizable with custom dateCellWrapper', () => { + const components = { + dateCellWrapper: props => { + const hasAlert = Math.random() <= 1 / 3 + const style = { + display: 'flex', + flex: 1, + borderLeft: '1px solid #DDD', + backgroundColor: hasAlert ? 'green' : '#fff', + } + return ( +
+ {hasAlert && ( + + Click me + + )} + {props.children} +
+ ) + }, + } + return ( +
+ +
+ ) + }) From 17cf099a97a0fb33ed817766fd9de422428c166b Mon Sep 17 00:00:00 2001 From: Alex Koehler Date: Mon, 14 May 2018 08:19:51 -0500 Subject: [PATCH 2/5] Code cleanup Fixed all hardcoded `defaultView` prop strings to use the Views constants --- examples/demos/customView.js | 2 +- examples/demos/dnd.js | 2 +- examples/demos/rendering.js | 2 +- examples/demos/resource.js | 2 +- examples/demos/selectable.js | 2 +- examples/demos/timeslots.js | 2 +- stories/Calendar.js | 24 ++++++++++++------------ 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/examples/demos/customView.js b/examples/demos/customView.js index 4a6aa4842..876a55073 100644 --- a/examples/demos/customView.js +++ b/examples/demos/customView.js @@ -49,7 +49,7 @@ MyWeek.title = date => { let CustomView = () => ( diff --git a/examples/demos/dnd.js b/examples/demos/dnd.js index 7d57749e8..0b139c66e 100644 --- a/examples/demos/dnd.js +++ b/examples/demos/dnd.js @@ -59,7 +59,7 @@ class Dnd extends React.Component { onEventDrop={this.moveEvent} resizable onEventResize={this.resizeEvent} - defaultView="week" + defaultView={BigCalendar.Views.WEEK} defaultDate={new Date(2015, 3, 12)} /> ) diff --git a/examples/demos/rendering.js b/examples/demos/rendering.js index 556f0dee3..a257f42df 100644 --- a/examples/demos/rendering.js +++ b/examples/demos/rendering.js @@ -43,7 +43,7 @@ let Rendering = () => ( ( ( alert(event.title)} diff --git a/examples/demos/timeslots.js b/examples/demos/timeslots.js index 0cad219b1..09c4a8b21 100644 --- a/examples/demos/timeslots.js +++ b/examples/demos/timeslots.js @@ -7,7 +7,7 @@ let Timeslots = () => ( events={events} step={15} timeslots={8} - defaultView="week" + defaultView={BigCalendar.Views.WEEK} defaultDate={new Date(2015, 3, 12)} /> ) diff --git a/stories/Calendar.js b/stories/Calendar.js index 5f8e08ed9..fea9d9d49 100644 --- a/stories/Calendar.js +++ b/stories/Calendar.js @@ -119,7 +119,7 @@ storiesOf('module.Calendar.week', module) return (
moment('9:30am', 'h:mma').toDate()} @@ -537,7 +537,7 @@ storiesOf('module.Calendar.week', module) return (
Date: Mon, 14 May 2018 10:30:17 -0500 Subject: [PATCH 3/5] Custom DropWrapper fixes - Pass through range and value props to match non-dnd component props - Added `customComponents` utility file for use with stories - Clarified comment in `withDragAndDrop` --- src/addons/dragAndDrop/DropWrappers.js | 25 +++++-- src/addons/dragAndDrop/withDragAndDrop.js | 5 +- stories/Calendar.js | 82 +++++++++++------------ stories/customComponents.js | 49 ++++++++++++++ 4 files changed, 111 insertions(+), 50 deletions(-) create mode 100644 stories/customComponents.js diff --git a/src/addons/dragAndDrop/DropWrappers.js b/src/addons/dragAndDrop/DropWrappers.js index 6285e6781..62533c3c1 100644 --- a/src/addons/dragAndDrop/DropWrappers.js +++ b/src/addons/dragAndDrop/DropWrappers.js @@ -39,8 +39,10 @@ function getEventDropProps(start, end, dropDate, droppedInAllDay) { class DropWrapper extends React.Component { static propTypes = { connectDropTarget: PropTypes.func.isRequired, - type: PropTypes.string, isOver: PropTypes.bool, + range: PropTypes.arrayOf(PropTypes.instanceOf(Date)), + type: PropTypes.string, + value: PropTypes.instanceOf(Date), } static contextTypes = { @@ -99,20 +101,35 @@ class DropWrapper extends React.Component { // }; render() { - const { connectDropTarget, children, type, isOver } = this.props + const { + connectDropTarget, + children, + isOver, + range, + type, + value, + } = this.props // Check if wrapper component of this type was passed in, otherwise use library default const { components } = this.context const BackgroundWrapper = components[type] || BigCalendar.components[type] + const backgroundWrapperProps = { + value, + } + + if (range) { + backgroundWrapperProps.range = range + } let resultingChildren = children - if (isOver) + if (isOver) { resultingChildren = React.cloneElement(children, { className: cn(children.props.className, 'rbc-addons-dnd-over'), }) + } return ( - + {connectDropTarget(resultingChildren)} ) diff --git a/src/addons/dragAndDrop/withDragAndDrop.js b/src/addons/dragAndDrop/withDragAndDrop.js index 1d0f64ccf..6a5f72a5e 100644 --- a/src/addons/dragAndDrop/withDragAndDrop.js +++ b/src/addons/dragAndDrop/withDragAndDrop.js @@ -52,8 +52,9 @@ try { * If you care about these corner cases, you can examine the `allDay` param suppled * in the callback to determine how the user dropped or resized the event. * - * Note: you cannot use custom `EventWrapper`, `DayWrapper` or `DateCellWrapper` - * components when using this HOC as they are overwritten here. + * Note: you cannot use custom `EventWrapper` components when using this HOC as it + * is overwritten here. + * * * @param {*} Calendar * @param {*} backend diff --git a/stories/Calendar.js b/stories/Calendar.js index fea9d9d49..505ecfbc0 100644 --- a/stories/Calendar.js +++ b/stories/Calendar.js @@ -8,6 +8,7 @@ import '../src/less/styles.less' import '../src/addons/dragAndDrop/styles.less' import demoEvents from '../examples/events' import createEvents from './createEvents' +import customComponents from './customComponents' import resources from './resourceEvents' import withDragAndDrop from '../src/addons/dragAndDrop' @@ -373,33 +374,27 @@ storiesOf('module.Calendar.week', module) ) }) .add('add custom dateCellWrapper', () => { - const components = { - dateCellWrapper: props => { - const hasAlert = Math.random() <= 1 / 3 - const style = { - display: 'flex', - flex: 1, - borderLeft: '1px solid #DDD', - backgroundColor: hasAlert ? 'green' : '#fff', - } - return ( -
- {hasAlert && ( - - Click me - - )} - {props.children} -
- ) - }, - } return (
+
+ ) + }) + .add('add custom dayWrapper', () => { + return ( +
+
) @@ -594,31 +589,12 @@ storiesOf('module.Calendar.week', module) ) }) .add('draggable and resizable with custom dateCellWrapper', () => { - const components = { - dateCellWrapper: props => { - const hasAlert = Math.random() <= 1 / 3 - const style = { - display: 'flex', - flex: 1, - borderLeft: '1px solid #DDD', - backgroundColor: hasAlert ? 'green' : '#fff', - } - return ( -
- {hasAlert && ( - - Click me - - )} - {props.children} -
- ) - }, - } return (
) }) + .add('draggable and resizable with custom dayWrapper', () => { + return ( +
+ +
+ ) + }) diff --git a/stories/customComponents.js b/stories/customComponents.js new file mode 100644 index 000000000..90f9508a5 --- /dev/null +++ b/stories/customComponents.js @@ -0,0 +1,49 @@ +import React from 'react' +import { action } from '@storybook/react' + +const customComponents = { + dateCellWrapper: dateCellWrapperProps => { + // Show 'click me' text in arbitrary places by using the range prop + const hasAlert = dateCellWrapperProps.range + ? dateCellWrapperProps.range.some(date => { + return date.getDate() % 12 === 0 + }) + : false + + const style = { + display: 'flex', + flex: 1, + borderLeft: '1px solid #DDD', + backgroundColor: hasAlert ? '#f5f5dc' : '#fff', + } + return ( +
+ {hasAlert && ( + + Click me + + )} + {dateCellWrapperProps.children} +
+ ) + }, + dayWrapper: dayWrapperProps => { + // Show different styles at arbitrary time + const hasCustomInfo = dayWrapperProps.value + ? dayWrapperProps.value.getHours() === 4 + : false + const style = { + display: 'flex', + flex: 1, + backgroundColor: hasCustomInfo ? '#f5f5dc' : '#fff', + } + return ( +
+ {hasCustomInfo && 'Custom Day Wrapper'} + {dayWrapperProps.children} +
+ ) + }, +} + +export default customComponents From a628acb1d460e19074c99b57aa09ba994b4d40ee Mon Sep 17 00:00:00 2001 From: Alex Koehler Date: Mon, 18 Jun 2018 13:58:58 -0500 Subject: [PATCH 4/5] Support for custom EventWrapper --- src/addons/dragAndDrop/DraggableEventWrapper.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/addons/dragAndDrop/DraggableEventWrapper.js b/src/addons/dragAndDrop/DraggableEventWrapper.js index afeb4ff99..9db78525a 100644 --- a/src/addons/dragAndDrop/DraggableEventWrapper.js +++ b/src/addons/dragAndDrop/DraggableEventWrapper.js @@ -8,10 +8,10 @@ import { accessor } from '../../utils/propTypes' import { accessor as get } from '../../utils/accessors' import BigCalendar from '../../index' -const EventWrapper = BigCalendar.components.eventWrapper class DraggableEventWrapper extends React.Component { static contextTypes = { + components: PropTypes.object, draggableAccessor: accessor, } @@ -50,6 +50,10 @@ class DraggableEventWrapper extends React.Component { } render() { + const { components } = this.context + const EventWrapper = + components.eventWrapper || BigCalendar.components.eventWrapper + let { connectDragSource, connectTopDragSource, From f16272c7fb9e179d96a2f6cdb61b1b24f2561cca Mon Sep 17 00:00:00 2001 From: Alex Koehler Date: Mon, 18 Jun 2018 14:14:56 -0500 Subject: [PATCH 5/5] Added examples to storybook --- src/addons/dragAndDrop/withDragAndDrop.js | 4 --- stories/Calendar.js | 31 +++++++++++++++++++++++ stories/customComponents.js | 9 +++++++ 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/addons/dragAndDrop/withDragAndDrop.js b/src/addons/dragAndDrop/withDragAndDrop.js index 4d8b6faa4..3771c7b5b 100644 --- a/src/addons/dragAndDrop/withDragAndDrop.js +++ b/src/addons/dragAndDrop/withDragAndDrop.js @@ -52,10 +52,6 @@ try { * If you care about these corner cases, you can examine the `allDay` param suppled * in the callback to determine how the user dropped or resized the event. * - * Note: you cannot use custom `EventWrapper` components when using this HOC as it - * is overwritten here. - * - * * @param {*} Calendar * @param {*} backend */ diff --git a/stories/Calendar.js b/stories/Calendar.js index 505ecfbc0..144c10fc0 100644 --- a/stories/Calendar.js +++ b/stories/Calendar.js @@ -399,6 +399,19 @@ storiesOf('module.Calendar.week', module)
) }) + .add('add custom eventWrapper', () => { + return ( +
+ +
+ ) + }) .add('no duration', () => { return (
@@ -624,3 +637,21 @@ storiesOf('module.Calendar.week', module)
) }) + .add('draggable and resizable with custom eventWrapper', () => { + return ( +
+ +
+ ) + }) diff --git a/stories/customComponents.js b/stories/customComponents.js index 90f9508a5..582443ffe 100644 --- a/stories/customComponents.js +++ b/stories/customComponents.js @@ -44,6 +44,15 @@ const customComponents = {
) }, + eventWrapper: eventWrapperProps => { + const style = { + border: '4px solid', + borderColor: + eventWrapperProps.event.start.getHours() % 2 === 0 ? 'green' : 'red', + padding: '5px', + } + return
{eventWrapperProps.children}
+ }, } export default customComponents