Skip to content

Commit

Permalink
Babel 6 / Flow compat
Browse files Browse the repository at this point in the history
  • Loading branch information
STRML committed Feb 10, 2016
1 parent 61f441b commit d778985
Show file tree
Hide file tree
Showing 14 changed files with 175 additions and 90 deletions.
13 changes: 5 additions & 8 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
{
"stage": 0,
"env": {
"test": {
"plugins": [
"typecheck"
]
}
}
"presets": [
"es2015",
"stage-1",
"react"
]
}
5 changes: 5 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,10 @@
env: {
"browser": true,
"node": true
},
globals: {
// For Flow
"ReactElement",
"ReactClass"
}
}
21 changes: 21 additions & 0 deletions .flowconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[ignore]
.*/node_modules/.*

[include]
lib/
index.js

[libs]

[options]
suppress_comment=\\(.\\|\n\\)*\\s*\\$FlowFixMe.*
suppress_comment=\\(.\\|\n\\)*\\s*\\$FlowBug.*
suppress_comment=\\(.\\|\n\\)*\\s*\\$FlowIgnore.*
suppress_comment=\\(.\\|\n\\)*\\s*\\$FlowNewLine.*
suppress_comment=\\(.\\|\n\\)*\\s*\\$FlowIssue
esproposal.class_instance_fields=ignore
esproposal.class_static_fields=ignore
module.file_ext=.js
module.file_ext=.jsx
module.file_ext=.es5
module.file_ext=.es6
4 changes: 2 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
module.exports = require('./lib/Draggable');
module.exports.DraggableCore = require('./lib/DraggableCore');
module.exports = require('./lib/Draggable').default;
module.exports.DraggableCore = require('./lib/DraggableCore').default;
3 changes: 0 additions & 3 deletions karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@ module.exports = function(config) {
loader: 'babel-loader',
query: {
cacheDirectory: true,
plugins: [
'typecheck'
]
},
exclude: /(node_modules)/
}
Expand Down
59 changes: 40 additions & 19 deletions lib/Draggable.es6
Original file line number Diff line number Diff line change
@@ -1,22 +1,36 @@
// @flow
import {default as React, PropTypes} from 'react';
import ReactDOM from 'react-dom';
// $FlowIgnore
import classNames from 'classnames';
import assign from 'object-assign';
import {createUIEvent, createTransform} from './utils/domFns';
import {createUIEvent, createCSSTransform, createSVGTransform} from './utils/domFns';
import {canDragX, canDragY, getBoundPosition} from './utils/positionFns';
import {dontSetMe} from './utils/shims';
import DraggableCore from './DraggableCore';
import log from './utils/log';

import type {CoreEvent} from './utils/domFns';
export type CoreEventHandler = (e: Event, coreEvent: CoreEvent) => void | false;
export type DraggableState = {
dragging: boolean,
dragged: boolean,
clientX: number, clientY: number,
slackX: number, slackY: number,
isElementSVG: boolean
};

//
// Define <Draggable>
//

export default class Draggable extends DraggableCore {
export default class Draggable extends React.Component {

static displayName = 'Draggable';

static propTypes = assign({}, DraggableCore.propTypes, {
static propTypes = {
// Accepts all props <DraggableCore> accepts.
...DraggableCore.propTypes,

/**
* `axis` determines which axis the draggable can move.
*
Expand Down Expand Up @@ -116,19 +130,23 @@ export default class Draggable extends DraggableCore {
className: dontSetMe,
style: dontSetMe,
transform: dontSetMe
});
};

static defaultProps = assign({}, DraggableCore.defaultProps, {
static defaultProps = {
...DraggableCore.defaultProps,
axis: 'both',
bounds: false,
start: {x: 0, y: 0},
zIndex: NaN
});
};

state = {
state: DraggableState = {
// Whether or not we are currently dragging.
dragging: false,

// Whether or not we have been dragged before.
dragged: false,

// Current transform x and y.
clientX: this.props.start.x, clientY: this.props.start.y,

Expand All @@ -150,18 +168,18 @@ export default class Draggable extends DraggableCore {
this.setState({dragging: false}); // prevents invariant if unmounted while dragging
}

onDragStart = (e, coreEvent) => {
onDragStart: CoreEventHandler = (e, coreEvent) => {
log('Draggable: onDragStart: %j', coreEvent.position);

// Short-circuit if user's callback killed it.
let shouldStart = this.props.onStart(e, createUIEvent(this, coreEvent));
// Kills start event on core as well, so move handlers are never bound.
if (shouldStart === false) return false;

this.setState({dragging: true});
this.setState({dragging: true, dragged: true});
};

onDrag = (e, coreEvent) => {
onDrag: CoreEventHandler = (e, coreEvent) => {
if (!this.state.dragging) return false;
log('Draggable: onDrag: %j', coreEvent.position);

Expand Down Expand Up @@ -202,7 +220,7 @@ export default class Draggable extends DraggableCore {
this.setState(newState);
};

onDragStop = (e, coreEvent) => {
onDragStop: CoreEventHandler = (e, coreEvent) => {
if (!this.state.dragging) return false;

// Short-circuit if user's callback killed it.
Expand All @@ -218,13 +236,14 @@ export default class Draggable extends DraggableCore {
});
};

render() {
let style, svgTransform = null;
render(): ReactElement {
let style = {}, svgTransform = null;

// Add a CSS transform to move the element around. This allows us to move the element around
// without worrying about whether or not it is relatively or absolutely positioned.
// If the item you are dragging already has a transform set, wrap it in a <span> so <Draggable>
// has a clean slate.
style = createTransform({
const transformOpts = {
// Set left if horizontal drag is enabled
x: canDragX(this) ?
this.state.clientX :
Expand All @@ -234,12 +253,13 @@ export default class Draggable extends DraggableCore {
y: canDragY(this) ?
this.state.clientY :
this.props.start.y
}, this.state.isElementSVG);
};

// If this element was SVG, we use the `transform` attribute.
if (this.state.isElementSVG) {
svgTransform = style;
style = {};
svgTransform = createSVGTransform(transformOpts);
} else {
style = createCSSTransform(transformOpts);
}

// zIndex option
Expand All @@ -259,10 +279,11 @@ export default class Draggable extends DraggableCore {
<DraggableCore {...this.props} onStart={this.onDragStart} onDrag={this.onDrag} onStop={this.onDragStop}>
{React.cloneElement(React.Children.only(this.props.children), {
className: className,
style: assign({}, this.props.children.props.style, style),
style: {...this.props.children.props.style, ...style},
transform: svgTransform
})}
</DraggableCore>
);
}
}

34 changes: 21 additions & 13 deletions lib/DraggableCore.es6
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @flow
import {default as React, PropTypes} from 'react';
import {matchesSelector, createCoreEvent, addEvent, removeEvent, addUserSelectStyles,
removeUserSelectStyles, styleHacks} from './utils/domFns';
Expand All @@ -6,7 +7,7 @@ import {dontSetMe} from './utils/shims';
import log from './utils/log';

// Simple abstraction for dragging events names.
let eventsFor = {
const eventsFor = {
touch: {
start: 'touchstart',
move: 'touchmove',
Expand All @@ -22,6 +23,13 @@ let eventsFor = {
// Default to mouse events.
let dragEventFor = eventsFor.mouse;

type EventHandler = (e: Event) => void;
type CoreState = {
dragging: boolean,
lastX: ?number,
lastY: ?number
};

//
// Define <DraggableCore>.
//
Expand Down Expand Up @@ -222,7 +230,7 @@ export default class DraggableCore extends React.Component {
onMouseDown: function(){}
};

state = {
state: CoreState = {
dragging: false,
// Used while dragging to determine deltas.
lastX: null, lastY: null
Expand All @@ -239,7 +247,7 @@ export default class DraggableCore extends React.Component {
if (this.props.enableUserSelectHack) removeUserSelectStyles();
}

handleDragStart = (e) => {
handleDragStart: EventHandler = (e) => {
// Make it possible to attach event handlers on top of this one.
this.props.onMouseDown(e);

Expand Down Expand Up @@ -300,7 +308,7 @@ export default class DraggableCore extends React.Component {
addEvent(document, dragEventFor.stop, this.handleDragStop);
};

handleDrag = (e) => {
handleDrag: EventHandler = (e) => {
// Return if this is a touch event, but not the correct one for this element
if (e.targetTouches && (e.targetTouches[0].identifier !== this.state.touchIdentifier)) return;

Expand All @@ -314,13 +322,13 @@ export default class DraggableCore extends React.Component {
clientX = this.state.lastX + deltaX, clientY = this.state.lastY + deltaY;
}

let coreEvent = createCoreEvent(this, clientX, clientY);
const coreEvent = createCoreEvent(this, clientX, clientY);

log('DraggableCore: handleDrag: %j', coreEvent.position);


// Call event handler. If it returns explicit false, trigger end.
let shouldUpdate = this.props.onDrag(e, coreEvent);
const shouldUpdate = this.props.onDrag(e, coreEvent);
if (shouldUpdate === false) {
this.handleDragStop({});
return;
Expand All @@ -332,7 +340,7 @@ export default class DraggableCore extends React.Component {
});
};

handleDragStop = (e) => {
handleDragStop: EventHandler = (e) => {
if (!this.state.dragging) return;

// Short circuit if this is not the correct touch event. `changedTouches` contains all
Expand All @@ -343,7 +351,7 @@ export default class DraggableCore extends React.Component {
if (this.props.enableUserSelectHack) removeUserSelectStyles();

let {clientX, clientY} = getControlPosition(e);
let coreEvent = createCoreEvent(this, clientX, clientY);
const coreEvent = createCoreEvent(this, clientX, clientY);

log('DraggableCore: handleDragStop: %j', coreEvent.position);

Expand All @@ -366,8 +374,8 @@ export default class DraggableCore extends React.Component {

// When the user scrolls, adjust internal state so the draggable moves along the page properly.
// This only fires when a drag is active.
handleScroll = (e) => {
let s = this.state, x = document.body.scrollLeft, y = document.body.scrollTop;
handleScroll: EventHandler = (e) => {
const s = this.state, x = document.body.scrollLeft, y = document.body.scrollTop;

// Create the usual event, but make the scroll offset our deltas.
let coreEvent = createCoreEvent(this);
Expand All @@ -383,7 +391,7 @@ export default class DraggableCore extends React.Component {
};

// On mousedown, consider the drag started.
onMouseDown = (e) => {
onMouseDown: EventHandler = (e) => {
// HACK: Prevent 'ghost click' which happens 300ms after touchstart if the event isn't cancelled.
// We don't cancel the event on touchstart because of #37; we might want to make a scrollable item draggable.
// More on ghost clicks: http://ariatemplates.com/blog/2014/05/ghost-clicks-in-mobile-browsers/
Expand All @@ -395,14 +403,14 @@ export default class DraggableCore extends React.Component {
};

// Same as onMouseDown (start drag), but now consider this a touch device.
onTouchStart = (e) => {
onTouchStart: EventHandler = (e) => {
// We're on a touch device now, so change the event handlers
dragEventFor = eventsFor.touch;

return this.handleDragStart(e);
};

render() {
render(): ReactElement {
// Reuse the child provided
// This makes it flexible to use whatever element is wanted (div, ul, etc)
return React.cloneElement(React.Children.only(this.props.children), {
Expand Down
Loading

0 comments on commit d778985

Please sign in to comment.