Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "stage": 1 }
Copy link
Copy Markdown

@gabrielbull gabrielbull May 19, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why use Babel 5? Here's a config for Babel 6:

{
  "presets": [
    "es2015",
    "stage-1",
    "react"
  ],
  "plugins": [
    "transform-decorators-legacy"
  ]
}

Shouldn't we also have babel in the devDependencies:

    "babel-core": "^6.9.0",
    "babel-plugin-transform-decorators-legacy": "^1.3.4",
    "babel-preset-es2015": "^6.9.0",
    "babel-preset-react": "^6.5.0",
    "babel-preset-stage-1": "^6.5.0",

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops, you are right. I was using babel6, I think that babel6 is just backwards-compatible?

I was enabling stage:1 to turn on decorators.

Copy link
Copy Markdown

@gabrielbull gabrielbull May 19, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Umm, Babel 6 is not backwards compatible, you must have Babel 5 running somehow (?). Decorators have been removed from stage 1 and are now in the transform-decorators-legacy plugin. So I guess this could be the config:

{
  "presets": [
    "es2015",
    "react"
  ],
  "plugins": [
    "transform-decorators-legacy"
  ]
}
    "babel-core": "^6.9.0",
    "babel-plugin-transform-decorators-legacy": "^1.3.4",
    "babel-preset-es2015": "^6.9.0",
    "babel-preset-react": "^6.5.0",

Copy link
Copy Markdown
Author

@pconerly pconerly May 19, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I was confused. The repo is using babelify version 6.1.2, which uses babel-core version 5: https://github.com/babel/babelify/blob/v6.1.2/package.json

Anyway, upgrading to babel6 is something that we should do, but it's out-of-scope for this PR.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

babelify is only intended for demos that using ES6 syntax, the module itself (index.js) is written in pure ES5 so no transformation is needed.

But I guess it's been a long time since I released this repo initially, the tool chains changed a lot, maybe it worth upgrading to state of the art.

100 changes: 100 additions & 0 deletions decorator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/**
* react-menu-aim is a React Mixin heavily inspired by jQuery-menu-aim. All rights
* reserved by the original author.
*
* https://github.com/jasonslyvia/react-menu-aim
* https://github.com/kamens/jQuery-menu-aim
*/

import React from 'react';
// import {on, off, handleMouseMoveDocument, activate, getActivateDelay, mousemoveListener, mouseLocs} from './src/core.js';
import {on, off, handleMouseMoveDocument, activate, getActivateDelay, menuAimModel} from './src/core.js';


function possiblyActivate(rowIdentifier, handler, config) {
var delay = getActivateDelay.call(this, config);

if (delay) {
var self = this;
this.__reactMenuAimTimer = setTimeout(function(){
possiblyActivate.call(self, rowIdentifier, handler, config);
}, delay);
}
else {
handler(rowIdentifier);
}
}

/**
* @export
*/
export default function reactMenuAimDecorator(reactMenuAimConfig) {
return function (ComposedComponent) {
return class MenuAimDecorator extends React.Component {

__getMouseMoveDocumentHandler() {
if (!this.__mouseMoveDocumentHandler) {
this.__mouseMoveDocumentHandler = handleMouseMoveDocument.bind(this);
}

return this.__mouseMoveDocumentHandler;
}

componentDidMount() {
if (menuAimModel.mousemoveListener === 0) {
on(document, 'mousemove', this.__getMouseMoveDocumentHandler());
}

menuAimModel.mousemoveListener += 1;
}

componentWillUnmount() {
menuAimModel.mousemoveListener -= 1;

if (menuAimModel.mousemoveListener === 0) {
off(document, 'mousemove', this.__getMouseMoveDocumentHandler());
menuAimModel.mouseLocs = [];
}

clearTimeout(this.__reactMenuAimTimer);
this.__reactMenuAimTimer = null;
this.__mouseMoveDocumentHandler = null;
}

/**
* @param {function} handler The true event handler for your app
* @param {object} e React's synthetic event object
*/
handleMouseLeaveMenu(handler, e) {
if (this.__reactMenuAimTimer) {
clearTimeout(this.__reactMenuAimTimer);
}

if (typeof handler === 'function') {
handler.call(this, e);
}
}

/**
* @param {number} rowIdentifier The identifier of current row, ie. index or name
* @param {function} handler The true event handler for your app
* @param {object} e React's synthetic event object
*/
handleMouseEnterRow(rowIdentifier, handler) {
if (this.__reactMenuAimTimer) {
clearTimeout(this.__reactMenuAimTimer);
}

// possiblyActivate.call(this, rowIdentifier, handler, reactMenuAimConfig);
possiblyActivate.call(this, rowIdentifier, handler, reactMenuAimConfig);
}

render() {
return <ComposedComponent {...this.props}
handleMouseLeaveMenu={this.handleMouseLeaveMenu.bind(this)}
handleMouseEnterRow={this.handleMouseEnterRow.bind(this)}
></ComposedComponent>;
}
}
}
}
8 changes: 7 additions & 1 deletion demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,16 @@
<div class="demo" id="demo1">
<h4 class="title">Basic Demo</h4>
<div class="demo-container"></div>
</div> <div class="demo" id="demo3">
</div>
<div class="demo" id="demo3">
<h4 class="title">Submenu Appear below</h4>
<div class="demo-container"></div>
</div>

<div class="demo" id="demo4">
<h4 class="title">Decorated Basic Demo</h4>
<div class="demo-container"></div>
</div>
</div>
<script type="text/javascript" src="js/app.bundle.js"></script>
</body>
Expand Down
68 changes: 68 additions & 0 deletions demo/js/DecoratedMenu.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React from 'react';
import reactMenuAimDecorator from '../../decorator';


@reactMenuAimDecorator({
submenuDirection: 'right',
menuSelector: '.menu',
delay: 300,
tolerance: 75})
export default class Menu extends React.Component {

constructor(props) {
super();

this.state = {
activeMenuIndex: 0,
};
}

handleSwitchMenuIndex(index) {
this.setState({
activeMenuIndex: index
});
}

render() {
var containerClassName = 'menu-container ' + this.props.submenuDirection;

var subMenuStyle = {};
if (this.props.submenuDirection === 'below') {
subMenuStyle.left = this.state.activeMenuIndex * 140;
}

return (
<div className={containerClassName}>
<ul className="menu" onMouseLeave={this.props.handleMouseLeaveMenu}>
{this.props.menuData.map((menu, index) => {
var className = 'menu-item';
if (index === this.state.activeMenuIndex) {
className += ' active';
}

return (
<li className={className} key={index}
onMouseEnter={() =>{
this.props.handleMouseEnterRow(index, this.handleSwitchMenuIndex.bind(this));
}}>
{menu.name}
</li>
);
})}
</ul>
<ul className="sub-menu" style={subMenuStyle}>
{this.props.menuData[this.state.activeMenuIndex].subMenu.map(((subMenu, index) => {
return (
<li className="sub-menu-item" key={index}>{subMenu}</li>
);
}))}
</ul>
</div>
);
}
}

Menu.defaultProps = {
submenuDirection: 'right',
};

Loading