Skip to content

Commit

Permalink
feat(time-grid): allow consumer to set allDayMaxRows (jquense#2386)
Browse files Browse the repository at this point in the history
* Add support for displaying Show more text in TimeGrid views via allDayMaxRows prop.
* Prevent Background cells from capturing click on show more button.
  • Loading branch information
Arturo Fornes committed Jun 2, 2023
1 parent 0b27f58 commit 1805b74
Show file tree
Hide file tree
Showing 10 changed files with 128 additions and 9 deletions.
4 changes: 2 additions & 2 deletions src/BackgroundCells.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import clsx from 'clsx'

import { notify } from './utils/helpers'
import { dateCellSelection, getSlotAtX, pointInBox } from './utils/selection'
import Selection, { getBoundsForNode, isEvent } from './Selection'
import Selection, { getBoundsForNode, isEvent, isShowMore } from './Selection'

class BackgroundCells extends React.Component {
constructor(props, context) {
Expand Down Expand Up @@ -77,7 +77,7 @@ class BackgroundCells extends React.Component {
}))

let selectorClicksHandler = (point, actionType) => {
if (!isEvent(node, point)) {
if (!isEvent(node, point) && !isShowMore(node, point)) {
let rowBox = getBoundsForNode(node)
let { range, rtl } = this.props

Expand Down
10 changes: 10 additions & 0 deletions src/Calendar.js
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,15 @@ class Calendar extends React.Component {
*/
showMultiDayTimes: PropTypes.bool,

/**
* Determines a maximum amount of rows of events to display in the all day
* section for Week and Day views, will display `showMore` button if
* events excede this number.
*
* Defaults to `Infinity`
*/
allDayMaxRows: PropTypes.number,

/**
* Constrains the minimum _time_ of the Day and Week views.
*/
Expand Down Expand Up @@ -865,6 +874,7 @@ class Calendar extends React.Component {
views: [views.MONTH, views.WEEK, views.DAY, views.AGENDA],
step: 30,
length: 30,
allDayMaxRows: Infinity,

doShowMoreDrillDown: true,
drilldownView: views.DAY,
Expand Down
2 changes: 1 addition & 1 deletion src/EventEndingRow.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class EventEndingRow extends React.Component {
type="button"
key={'sm_' + slot}
className={clsx('rbc-button-link', 'rbc-show-more')}
onClick={e => this.showMore(slot, e)}
onClick={(e) => this.showMore(slot, e)}
>
{localizer.messages.showMore(count)}
</button>
Expand Down
23 changes: 17 additions & 6 deletions src/Selection.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,19 @@ export function getEventNodeFromPoint(node, { clientX, clientY }) {
return closest(target, '.rbc-event', node)
}

export function getShowMoreNodeFromPoint(node, { clientX, clientY }) {
let target = document.elementFromPoint(clientX, clientY)
return closest(target, '.rbc-show-more', node)
}

export function isEvent(node, bounds) {
return !!getEventNodeFromPoint(node, bounds)
}

export function isShowMore(node, bounds) {
return !!getShowMoreNodeFromPoint(node, bounds)
}

function getEventCoordinates(e) {
let target = e

Expand All @@ -38,7 +47,10 @@ const clickTolerance = 5
const clickInterval = 250

class Selection {
constructor(node, { global = false, longPressThreshold = 250, validContainers = [] } = {}) {
constructor(
node,
{ global = false, longPressThreshold = 250, validContainers = [] } = {}
) {
this.isDetached = false
this.container = node
this.globalMouse = !node || global
Expand Down Expand Up @@ -307,15 +319,14 @@ class Selection {
// Check whether provided event target element
// - is contained within a valid container
_isWithinValidContainer(e) {
const eventTarget = e.target;
const containers = this.validContainers;
const eventTarget = e.target
const containers = this.validContainers

if (!containers || !containers.length || !eventTarget) {
return true;
return true
}

return containers.some(
(target) => !!eventTarget.closest(target));
return containers.some((target) => !!eventTarget.closest(target))
}

_handleTerminatingEvent(e) {
Expand Down
10 changes: 10 additions & 0 deletions src/TimeGrid.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ export default class TimeGrid extends Component {
notify(this.props.onSelectEvent, args)
}

handleShowMore = (...args) => {
this.clearSelection()
notify(this.props.onShowMore, args)
}

handleSelectAllDaySlot = (slots, slotInfo) => {
const { onSelectSlot } = this.props

Expand Down Expand Up @@ -211,6 +216,7 @@ export default class TimeGrid extends Component {
getNow={getNow}
localizer={localizer}
selected={selected}
allDayMaxRows={this.props.allDayMaxRows}
resources={this.memoizedResources(resources, accessors)}
selectable={this.props.selectable}
accessors={accessors}
Expand All @@ -221,6 +227,7 @@ export default class TimeGrid extends Component {
longPressThreshold={longPressThreshold}
onSelectSlot={this.handleSelectAllDaySlot}
onSelectEvent={this.handleSelectAlldayEvent}
onShowMore={this.handleShowMore}
onDoubleClickEvent={this.props.onDoubleClickEvent}
onKeyPressEvent={this.props.onKeyPressEvent}
onDrillDown={this.props.onDrillDown}
Expand Down Expand Up @@ -341,6 +348,8 @@ TimeGrid.propTypes = {
getters: PropTypes.object.isRequired,
localizer: PropTypes.object.isRequired,

allDayMaxRows: PropTypes.number,

selected: PropTypes.object,
selectable: PropTypes.oneOf([true, false, 'ignoreEvents']),
longPressThreshold: PropTypes.number,
Expand All @@ -350,6 +359,7 @@ TimeGrid.propTypes = {
onSelectEnd: PropTypes.func,
onSelectStart: PropTypes.func,
onSelectEvent: PropTypes.func,
onShowMore: PropTypes.func,
onDoubleClickEvent: PropTypes.func,
onKeyPressEvent: PropTypes.func,
onDrillDown: PropTypes.func,
Expand Down
7 changes: 7 additions & 0 deletions src/TimeGridHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class TimeGridHeader extends React.Component {
rtl={rtl}
getNow={getNow}
minRows={2}
maxRows={this.props.allDayMaxRows}
range={range}
events={eventsToDisplay}
resourceId={resourceId}
Expand All @@ -96,6 +97,7 @@ class TimeGridHeader extends React.Component {
getters={getters}
localizer={localizer}
onSelect={this.props.onSelectEvent}
onShowMore={this.props.onShowMore}
onDoubleClick={this.props.onDoubleClickEvent}
onKeyPress={this.props.onKeyPressEvent}
onSelectSlot={this.props.onSelectSlot}
Expand Down Expand Up @@ -172,6 +174,7 @@ class TimeGridHeader extends React.Component {
rtl={rtl}
getNow={getNow}
minRows={2}
maxRows={this.props.allDayMaxRows}
range={range}
events={groupedEvents.get(id) || []}
resourceId={resource && id}
Expand All @@ -183,6 +186,7 @@ class TimeGridHeader extends React.Component {
getters={getters}
localizer={localizer}
onSelect={this.props.onSelectEvent}
onShowMore={this.props.onShowMore}
onDoubleClick={this.props.onDoubleClickEvent}
onKeyPress={this.props.onKeyPressEvent}
onSelectSlot={this.props.onSelectSlot}
Expand Down Expand Up @@ -216,11 +220,14 @@ TimeGridHeader.propTypes = {
selectable: PropTypes.oneOf([true, false, 'ignoreEvents']),
longPressThreshold: PropTypes.number,

allDayMaxRows: PropTypes.number,

onSelectSlot: PropTypes.func,
onSelectEvent: PropTypes.func,
onDoubleClickEvent: PropTypes.func,
onKeyPressEvent: PropTypes.func,
onDrillDown: PropTypes.func,
onShowMore: PropTypes.func,
getDrilldownView: PropTypes.func.isRequired,
scrollRef: PropTypes.any,
}
Expand Down
10 changes: 10 additions & 0 deletions stories/props/API.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,16 @@ The end date/time of the event. Must resolve to a JavaScript `Date` object.

Determines whether the event should be considered an "all day" event and ignore time. Must resolve to a `boolean` value.

### allDayMaxRows

- type: `number`
- default: `Infinity`
- <LinkTo kind="props" story="all-day-max-rows">
Example
</LinkTo>

Determines a maximum amount of rows of events to display in the all day section for Week and Day views, will display `showMore` button if events excede this number.

### resources

- type: `arrayOf(Resource)`
Expand Down
10 changes: 10 additions & 0 deletions stories/props/allDayMaxRows.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Canvas, Story } from '@storybook/addon-docs'

# allDayMaxRows

- type: `number`
- default: `Infinity`

Determines a maximum amount of rows of events to display in the all day section for Week and Day views, will display `showMore` button if events excede this number.

<Story id="props--all-day-max-rows" />
38 changes: 38 additions & 0 deletions stories/props/allDayMaxRows.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react'
import moment from 'moment'
import { Calendar, Views, momentLocalizer } from '../../src'
import allDayEvents from '../resources/allDayEvents'
import mdx from './allDayMaxRows.mdx'

const mLocalizer = momentLocalizer(moment)

export default {
title: 'props',
component: Calendar,
argTypes: {
localizer: { control: { type: null } },
events: { control: { type: null } },
defaultDate: { control: { type: null } },
},
parameters: {
docs: {
page: mdx,
},
},
}

const Template = (args) => (
<div className="height600">
<Calendar {...args} />
</div>
)

export const AllDayMaxRows = Template.bind({})
AllDayMaxRows.storyName = 'allDayMaxRows'
AllDayMaxRows.args = {
defaultDate: new Date(2015, 3, 1),
defaultView: Views.WEEK,
events: allDayEvents,
localizer: mLocalizer,
allDayMaxRows: 2,
}
23 changes: 23 additions & 0 deletions stories/resources/allDayEvents.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export default [
{
id: 0,
title: 'All Day Event very long title',
allDay: true,
start: new Date(2015, 3, 0),
end: new Date(2015, 3, 1),
},
{
id: 1,
title: '#2 All Day Event very long title',
allDay: true,
start: new Date(2015, 3, 0),
end: new Date(2015, 3, 2),
},
{
id: 2,
title: '#3 All Day Event very long title',
allDay: true,
start: new Date(2015, 3, 0),
end: new Date(2015, 3, 1),
},
]

0 comments on commit 1805b74

Please sign in to comment.