Skip to content

Commit 1f369f3

Browse files
committed
add documentation + demo on select
1 parent 65dc423 commit 1f369f3

File tree

5 files changed

+345
-476
lines changed

5 files changed

+345
-476
lines changed

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ The exact viewport of the calendar. When these are specified, scrolling in the c
142142

143143
## selected
144144

145-
An array with id's corresponding to id's in items (`item.id`). If this prop is set you have to manage the selected items yourself within the `onItemSelect` handler to update the property with new id's. This overwrites the default behaviour of selecting one item on click.
145+
An array with id's corresponding to id's in items (`item.id`). If this prop is set you have to manage the selected items yourself within the `onItemSelect` handler to update the property with new id's and use `onItemDeselect` handler to clear selection. This overwrites the default behaviour of selecting one item on click.
146146

147147
## keys
148148

@@ -280,6 +280,10 @@ Callback when an item is resized. Returns 1) the item's ID, 2) the new start or
280280

281281
Called when an item is selected. This is sent on the first click on an item. `time` is the time that corresponds to where you click/select on the item in the timeline.
282282

283+
## onItemDeselect(e)
284+
285+
Called when deselecting an item. Used to clear controlled selected prop.
286+
283287
## onItemClick(itemId, e, time)
284288

285289
Called when an item is clicked. Note: the item must be selected before it's clicked... except if it's a touch event and `itemTouchSendsClick` is enabled. `time` is the time that corresponds to where you click on the item in the timeline.
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
/* eslint-disable no-console */
2+
import React, { Component } from 'react'
3+
import moment from 'moment'
4+
5+
import Timeline, {
6+
TimelineMarkers,
7+
TimelineHeaders,
8+
TodayMarker,
9+
CustomMarker,
10+
CursorMarker,
11+
CustomHeader,
12+
SidebarHeader,
13+
DateHeader
14+
} from 'react-calendar-timeline'
15+
16+
import generateFakeData from '../generate-fake-data'
17+
18+
var minTime = moment()
19+
.add(-6, 'months')
20+
.valueOf()
21+
var maxTime = moment()
22+
.add(6, 'months')
23+
.valueOf()
24+
25+
var keys = {
26+
groupIdKey: 'id',
27+
groupTitleKey: 'title',
28+
groupRightTitleKey: 'rightTitle',
29+
itemIdKey: 'id',
30+
itemTitleKey: 'title',
31+
itemDivTitleKey: 'title',
32+
itemGroupKey: 'group',
33+
itemTimeStartKey: 'start',
34+
itemTimeEndKey: 'end'
35+
}
36+
37+
export default class App extends Component {
38+
constructor(props) {
39+
super(props)
40+
41+
const { groups, items } = generateFakeData()
42+
const defaultTimeStart = moment()
43+
.startOf('day')
44+
.toDate()
45+
const defaultTimeEnd = moment()
46+
.startOf('day')
47+
.add(1, 'day')
48+
.toDate()
49+
50+
this.state = {
51+
groups,
52+
items,
53+
defaultTimeStart,
54+
defaultTimeEnd,
55+
selected: undefined,
56+
}
57+
}
58+
59+
handleCanvasClick = (groupId, time) => {
60+
console.log('Canvas clicked', groupId, moment(time).format())
61+
}
62+
63+
handleCanvasDoubleClick = (groupId, time) => {
64+
console.log('Canvas double clicked', groupId, moment(time).format())
65+
}
66+
67+
handleCanvasContextMenu = (group, time) => {
68+
console.log('Canvas context menu', group, moment(time).format())
69+
}
70+
71+
handleItemClick = (itemId, _, time) => {
72+
console.log('Clicked: ' + itemId, moment(time).format())
73+
}
74+
75+
handleItemSelect = (itemId, _, time) => {
76+
this.setState({
77+
selected: [itemId]
78+
})
79+
console.log('Selected: ' + itemId, moment(time).format())
80+
}
81+
82+
handleItemDeselect = () => {
83+
this.setState({selected: undefined})
84+
}
85+
86+
handleItemDoubleClick = (itemId, _, time) => {
87+
console.log('Double Click: ' + itemId, moment(time).format())
88+
}
89+
90+
handleItemContextMenu = (itemId, _, time) => {
91+
console.log('Context Menu: ' + itemId, moment(time).format())
92+
}
93+
94+
handleItemMove = (itemId, dragTime, newGroupOrder) => {
95+
const { items, groups } = this.state
96+
97+
const group = groups[newGroupOrder]
98+
99+
this.setState({
100+
items: items.map(
101+
item =>
102+
item.id === itemId
103+
? Object.assign({}, item, {
104+
start: dragTime,
105+
end: dragTime + (item.end - item.start),
106+
group: group.id
107+
})
108+
: item
109+
)
110+
})
111+
112+
console.log('Moved', itemId, dragTime, newGroupOrder)
113+
}
114+
115+
handleItemResize = (itemId, time, edge) => {
116+
const { items } = this.state
117+
118+
this.setState({
119+
items: items.map(
120+
item =>
121+
item.id === itemId
122+
? Object.assign({}, item, {
123+
start: edge === 'left' ? time : item.start,
124+
end: edge === 'left' ? item.end : time
125+
})
126+
: item
127+
)
128+
})
129+
130+
console.log('Resized', itemId, time, edge)
131+
}
132+
133+
// this limits the timeline to -6 months ... +6 months
134+
handleTimeChange = (visibleTimeStart, visibleTimeEnd, updateScrollCanvas) => {
135+
if (visibleTimeStart < minTime && visibleTimeEnd > maxTime) {
136+
updateScrollCanvas(minTime, maxTime)
137+
} else if (visibleTimeStart < minTime) {
138+
updateScrollCanvas(minTime, minTime + (visibleTimeEnd - visibleTimeStart))
139+
} else if (visibleTimeEnd > maxTime) {
140+
updateScrollCanvas(maxTime - (visibleTimeEnd - visibleTimeStart), maxTime)
141+
} else {
142+
updateScrollCanvas(visibleTimeStart, visibleTimeEnd)
143+
}
144+
}
145+
146+
moveResizeValidator = (action, item, time) => {
147+
if (time < new Date().getTime()) {
148+
var newTime =
149+
Math.ceil(new Date().getTime() / (15 * 60 * 1000)) * (15 * 60 * 1000)
150+
return newTime
151+
}
152+
153+
return time
154+
}
155+
156+
render() {
157+
const { groups, items, defaultTimeStart, defaultTimeEnd } = this.state
158+
159+
return (
160+
<Timeline
161+
groups={groups}
162+
items={items}
163+
keys={keys}
164+
sidebarWidth={150}
165+
sidebarContent={<div>Above The Left</div>}
166+
canMove
167+
canResize="right"
168+
canSelect
169+
itemsSorted
170+
itemTouchSendsClick={false}
171+
stackItems
172+
itemHeightRatio={0.75}
173+
defaultTimeStart={defaultTimeStart}
174+
defaultTimeEnd={defaultTimeEnd}
175+
onCanvasClick={this.handleCanvasClick}
176+
onCanvasDoubleClick={this.handleCanvasDoubleClick}
177+
onCanvasContextMenu={this.handleCanvasContextMenu}
178+
onItemClick={this.handleItemClick}
179+
onItemSelect={this.handleItemSelect}
180+
onItemContextMenu={this.handleItemContextMenu}
181+
onItemMove={this.handleItemMove}
182+
onItemResize={this.handleItemResize}
183+
onItemDoubleClick={this.handleItemDoubleClick}
184+
onTimeChange={this.handleTimeChange}
185+
moveResizeValidator={this.moveResizeValidator}
186+
selected={this.state.selected}
187+
onItemDeselect={this.handleItemDeselect}
188+
>
189+
<TimelineMarkers>
190+
<TodayMarker />
191+
<CustomMarker
192+
date={
193+
moment()
194+
.startOf('day')
195+
.valueOf() +
196+
1000 * 60 * 60 * 2
197+
}
198+
/>
199+
<CustomMarker
200+
date={moment()
201+
.add(3, 'day')
202+
.valueOf()}
203+
>
204+
{({ styles }) => {
205+
const newStyles = { ...styles, backgroundColor: 'blue' }
206+
return <div style={newStyles} />
207+
}}
208+
</CustomMarker>
209+
<CursorMarker />
210+
</TimelineMarkers>
211+
</Timeline>
212+
)
213+
}
214+
}

demo/app/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ const demos = {
1515
verticalClasses: require('./demo-vertical-classes').default,
1616
customItems: require('./demo-custom-items').default,
1717
customHeaders: require('./demo-headers').default,
18-
customInfoLabel: require('./demo-custom-info-label').default
18+
customInfoLabel: require('./demo-custom-info-label').default,
19+
controledSelect: require('./demo-controlled-select').default
1920
}
2021

2122
// A simple component that shows the pathname of the current location

package.json

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,19 @@
55
"main": "lib/index.js",
66
"scripts": {
77
"build": "npm run build:lib",
8-
"build:demo":
9-
"echo '!!! Building Demo' && cross-env NODE_ENV=production webpack --progress",
10-
"build:lib":
11-
"echo '!!! Building Library' && rimraf lib && cross-env NODE_ENV=production babel src --out-dir lib && node-sass src/lib/Timeline.scss lib/Timeline.css && sed -i'.bak' 's/Timeline\\.scss/Timeline\\.css/g' lib/lib/Timeline.js && rm lib/lib/Timeline.js.bak",
8+
"build:demo": "echo '!!! Building Demo' && cross-env NODE_ENV=production webpack --progress",
9+
"build:lib": "echo '!!! Building Library' && rimraf lib && cross-env NODE_ENV=production babel src --out-dir lib && node-sass src/lib/Timeline.scss lib/Timeline.css && sed -i'.bak' 's/Timeline\\.scss/Timeline\\.css/g' lib/lib/Timeline.js && rm lib/lib/Timeline.js.bak",
1210
"lint": "eslint --ext .js --ext .jsx ./src",
1311
"lint:fix": "prettier-eslint --parser babylon --write \"src/**/*.js\"",
1412
"prepublish": "npm run build:lib",
1513
"start": "webpack-dev-server --hot --host 0.0.0.0 --display-modules",
1614
"test": "jest",
1715
"test:watch": "jest --watch"
1816
},
19-
"files": ["lib", "src"],
17+
"files": [
18+
"lib",
19+
"src"
20+
],
2021
"homepage": "https://github.com/namespace-ee/react-calendar-timeline",
2122
"repository": {
2223
"type": "git",
@@ -57,7 +58,12 @@
5758
}
5859
],
5960
"license": "MIT",
60-
"keywords": ["react", "reactjs", "react-component", "timeline"],
61+
"keywords": [
62+
"react",
63+
"reactjs",
64+
"react-component",
65+
"timeline"
66+
],
6167
"standard": {
6268
"parser": "babel-eslint"
6369
},
@@ -128,7 +134,7 @@
128134
"jest-watch-typeahead": "^0.3.1",
129135
"jsdom": "^11.5.1",
130136
"moment": "^2.11.1",
131-
"node-sass": "^4.9.2",
137+
"node-sass": "^4.12.0",
132138
"prettier": "^1.10.2",
133139
"prettier-eslint-cli": "^4.7.0",
134140
"prop-types": "^15.6.2",

0 commit comments

Comments
 (0)