Skip to content

Commit 8ad4ee7

Browse files
committed
[changed] selection bound to Calendar container, respects overlays
1 parent 98b3dad commit 8ad4ee7

File tree

7 files changed

+82
-12
lines changed

7 files changed

+82
-12
lines changed

examples/App.js

+59-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import React from 'react';
2+
import Modal from 'react-overlays/lib/Modal';
3+
24
import { render } from 'react-dom';
35

46
import globalizeLocalizer from 'react-big-calendar/globalize-localizer';
@@ -28,8 +30,44 @@ function EventAgenda(props) {
2830
return <em>{props.event.title}</em>
2931
}
3032

31-
const Example = React.createClass({
3233

34+
let rand = ()=> (Math.floor(Math.random() * 20) - 10);
35+
36+
const modalStyle = {
37+
position: 'fixed',
38+
zIndex: 1040,
39+
top: 0, bottom: 0, left: 0, right: 0
40+
};
41+
42+
const backdropStyle = {
43+
...modalStyle,
44+
zIndex: 'auto',
45+
backgroundColor: '#000',
46+
opacity: 0.5
47+
};
48+
49+
const dialogStyle = function() {
50+
// we use some psuedo random coords so modals
51+
// don't sit right on top of each other.
52+
let top = 50 + rand();
53+
let left = 50 + rand();
54+
55+
return {
56+
position: 'absolute',
57+
width: 400,
58+
top: top + '%', left: left + '%',
59+
transform: `translate(-${top}%, -${left}%)`,
60+
border: '1px solid #e5e5e5',
61+
backgroundColor: 'white',
62+
boxShadow: '0 5px 15px rgba(0,0,0,.5)',
63+
padding: 20
64+
};
65+
};
66+
67+
const Example = React.createClass({
68+
getInitialState(){
69+
return { showModal: false };
70+
},
3371
render() {
3472

3573
return (
@@ -39,6 +77,7 @@ const Example = React.createClass({
3977
selectable
4078
popup
4179
events={events}
80+
onSelectEvent={this.open}
4281
defaultDate={new Date(2015, 3, 1)}
4382
eventPropGetter={e => ({ className: 'hi-event'})}
4483
components={{
@@ -49,8 +88,27 @@ const Example = React.createClass({
4988
}}
5089
/>
5190
</main>
91+
<Modal
92+
aria-labelledby='modal-label'
93+
style={modalStyle}
94+
backdropStyle={backdropStyle}
95+
show={this.state.showModal}
96+
onHide={this.close}
97+
>
98+
<div style={dialogStyle()} >
99+
<h4 id='modal-label'>Text in a modal</h4>
100+
<p>Duis mollis, est non commodo luctus, nisi erat porttitor ligula.</p>
101+
</div>
102+
</Modal>
52103
</div>
53104
);
105+
},
106+
close(){
107+
this.setState({ showModal: false });
108+
},
109+
110+
open(){
111+
this.setState({ showModal: true });
54112
}
55113
});
56114

src/BackgroundCells.jsx

+6-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React from 'react';
22
import { findDOMNode } from 'react-dom';
33
import cn from 'classnames';
44
import { segStyle } from './utils/eventLevels';
5+
import { notify } from './utils/helpers';
56
import { dateCellSelection, slotWidth, getCellAtX, pointInBox } from './utils/selection';
67
import Selection, { getBoundsForNode } from './Selection';
78

@@ -58,17 +59,18 @@ class DisplayCells extends React.Component {
5859

5960
_selectable(){
6061
let node = findDOMNode(this);
61-
let selector = this._selector = new Selection()
62+
let selector = this._selector = new Selection(this.props.container)
6263

6364
selector.on('selecting', box => {
6465
let { slots } = this.props;
6566

6667
let startIdx = -1;
6768
let endIdx = -1;
6869

69-
if (!this.state.selecting)
70+
if (!this.state.selecting) {
71+
notify(this.props.onSelectStart, [box]);
7072
this._initial = { x: box.x, y: box.y };
71-
73+
}
7274
if (selector.isSelected(node)) {
7375
let nodeBox = getBoundsForNode(node);
7476

@@ -108,6 +110,7 @@ class DisplayCells extends React.Component {
108110
this._selectSlot(this.state)
109111
this._initial = {}
110112
this.setState({ selecting: false })
113+
notify(this.props.onSelectEnd, [this.state]);
111114
})
112115
}
113116

src/DaySlot.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ let DaySlot = React.createClass({
178178

179179
_selectable(){
180180
let node = findDOMNode(this);
181-
let selector = this._selector = new Selection(node)
181+
let selector = this._selector = new Selection(()=> findDOMNode(this))
182182

183183
selector.on('selecting', ({ x, y }) => {
184184
let { date, step, min } = this.props;

src/Month.jsx

+1
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ let MonthView = React.createClass({
195195

196196
return (
197197
<BackgroundCells
198+
container={() => findDOMNode(this)}
198199
selectable={this.props.selectable}
199200
slots={7}
200201
ref={r => this._bgRows[idx] = r}

src/Selection.js

+8-4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ function addEventListener(type, handler) {
88
}
99
}
1010

11+
function isOverContainer(container, x, y){
12+
return !container || contains(container, document.elementFromPoint(x, y))
13+
}
14+
1115
class Selection {
1216

1317
constructor(node, global = false){
@@ -72,14 +76,14 @@ class Selection {
7276
}
7377

7478
_mouseDown (e) {
75-
var node = this.container
79+
var node = this.container()
7680
, collides, offsetData;
7781

7882
// Right clicks
79-
if (e.which === 3 || e.button === 2)
83+
if (e.which === 3 || e.button === 2 || !isOverContainer(node, e.pageX, e.pageY))
8084
return;
8185

82-
if (node && !contains(node, e.target) && !this.globalMouse) {
86+
if (!this.globalMouse && node && !contains(node, e.target)) {
8387

8488
let { top, left, bottom, right } = normalizeDistance(0);
8589

@@ -119,7 +123,7 @@ class Selection {
119123
let clickTolerance = 5;
120124

121125
var { x, y } = this._mouseDownData;
122-
var inRoot = !this.container || contains(this.container, e.target);
126+
var inRoot = !this.container || contains(this.container(), e.target);
123127
var bounds = this._selectRect;
124128
var click = (
125129
Math.abs(e.pageX - x) <= clickTolerance &&

src/TimeGrid.jsx

+6-2
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,12 @@ let TimeGrid = React.createClass({
103103
<div ref={addGutterRef(1)} className='rbc-gutter-cell'>
104104
{ message(messages).allDay }
105105
</div>
106-
<div className='rbc-allday-cell'>
107-
<BackgroundCells slots={range.length}/>
106+
<div ref='allDay' className='rbc-allday-cell'>
107+
<BackgroundCells
108+
slots={range.length}
109+
container={()=> this.refs.allDay}
110+
selectable={this.props.selectable}
111+
/>
108112
<div style={{ zIndex: 1, position: 'relative' }}>
109113
{ this.renderAllDayEvents(range, levels) }
110114
</div>

src/utils/eventLevels.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export function eventSegments(event, first, last, { startAccessor, endAccessor,
88

99
let span = dates.diff(start, end, 'day');
1010

11-
span = Math.min(Math.max(span, 1), slots);
11+
span = Math.max(Math.min(span, slots), 1);
1212

1313
let padding = dates.diff(first, start, 'day');
1414

0 commit comments

Comments
 (0)