diff --git a/README.md b/README.md
index 8b57a85..3eafb76 100644
--- a/README.md
+++ b/README.md
@@ -13,17 +13,17 @@ npm install react-popover-control
```javascript
import Popover from 'react-popover-control';
-actions = [
+const actions = [
{
title: 'Edit',
- func: () => {
- ...
+ func() {
+ // some action here
}
},
{
title: 'Delete',
- func: () => {
- ...
+ func() {
+ // some action here
}
}
];
@@ -31,23 +31,21 @@ actions = [
class Page extends React.Component {
render() {
return (
-
- Click Here
-
+
)
}
-}
+};
```
## Styling
-Default styles are included in `css/ReactPopoverControl.scss`.
-
-If you are using webpack with sass-loader, you can load the style in like this:
-
-```javascript
-require('react-popover-control/css/ReactPopoverControl.scss')
-```
+Default styles are included as jss, but you can opt out by... (TODO)
## A good popover...
@@ -61,4 +59,4 @@ require('react-popover-control/css/ReactPopoverControl.scss')
- Arrow key control
- Scrolling when there are too many items
- Using keyboard letters as shortcuts to certain fields
-- Filtering items with an input field
\ No newline at end of file
+- Filtering items with an input field
diff --git a/css/ReactPopoverControl.scss b/css/ReactPopoverControl.scss
deleted file mode 100644
index a5a7a04..0000000
--- a/css/ReactPopoverControl.scss
+++ /dev/null
@@ -1,21 +0,0 @@
-.ReactPopoverList {
- background-color: white;
- min-width: 150px;
- overflow: hidden;
- box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.25);
- border-radius: 5px;
-
- a {
- display: block;
- height: 40px;
- line-height: 40px;
- padding: 0 10px;
- color: #1A2D36;
-
- &:hover {
- text-decoration: none;
- color: #1A2D36;
- background-color: #e1f0f7;
- }
- }
-}
\ No newline at end of file
diff --git a/package.json b/package.json
index 028d57c..79d7ecd 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "react-popover-control",
- "version": "0.1.1",
+ "version": "0.1.4",
"description": "A popover control for React",
"repository": {
"type": "git",
@@ -15,8 +15,15 @@
],
"main": "lib/index.js",
"dependencies": {
+ "classnames": "^2.1.3",
+ "jss": "^2.1.2",
+ "jss-camel-case": "^0.1.2",
+ "jss-nested": "^0.1.8",
+ "jss-px": "^0.1.3",
+ "jss-vendor-prefixer": "^0.2.2",
"keycode": "^2.1.0",
- "lodash": "^3.8.0"
+ "lodash": "^3.8.0",
+ "react-jss": "^1.0.4"
},
"peerDependencies": {
"react": "^0.13.2",
diff --git a/site/package.json b/site/package.json
index 8bd0360..463b4a9 100644
--- a/site/package.json
+++ b/site/package.json
@@ -2,13 +2,15 @@
"description": "A simple, idiomatic popover control for React",
"scripts": {
"start": "NODE_ENV=development webpack-dev-server --progress",
+ "build-dev": "NODE_ENV=development webpack --progress",
"build-prod": "NODE_ENV=production webpack -p --progress"
},
"dependencies": {
"active-event-stack": "^1.0.0",
"react": "^0.13.3",
- "react-popover-control": "^0.1.0",
- "react-router": "^0.13.3"
+ "react-popover-control": "^0.1.1",
+ "react-router": "^0.13.3",
+ "source-map-support": "^0.3.2"
},
"devDependencies": {
"autoprefixer-core": "^5.2.1",
diff --git a/site/src/js/index.js b/site/src/js/index.js
index c0bb26a..1233270 100644
--- a/site/src/js/index.js
+++ b/site/src/js/index.js
@@ -5,6 +5,8 @@ import routes from './routes';
require('../css/reset.scss');
export default function(path, props, done) {
+ console.log(typeof global);
+
Router.run(routes, path, Handler => {
done(
'' +
@@ -17,4 +19,4 @@ if (typeof document != 'undefined') {
Router.run(routes, Router.HashLocation, Handler => {
React.render(, document);
});
-}
\ No newline at end of file
+}
diff --git a/site/src/js/pages/HomePage.js b/site/src/js/pages/HomePage.js
index 0f34d7d..ac86fb5 100644
--- a/site/src/js/pages/HomePage.js
+++ b/site/src/js/pages/HomePage.js
@@ -6,7 +6,7 @@ import marked from 'marked';
import customMarkedRenderer from '../customMarkedRenderer';
import Popover from 'react-popover-control';
-require('react-popover-control/css/ReactPopoverControl.scss');
+
require('../../css/HomePage.scss')
const HomePageMarkdown = require('../markdown/HomePage.md');
@@ -30,7 +30,7 @@ export default class HomePage extends React.Component {
render() {
return (
-
@@ -57,4 +57,4 @@ export default class HomePage extends React.Component {
)
}
-}
\ No newline at end of file
+}
diff --git a/site/webpack.config.js b/site/webpack.config.js
index fd3ea92..97a31d8 100644
--- a/site/webpack.config.js
+++ b/site/webpack.config.js
@@ -1,3 +1,5 @@
+var path = require('path');
+
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var StaticRenderWebpackPlugin = require('static-render-webpack-plugin');
var webpack = require('webpack');
@@ -27,15 +29,23 @@ module.exports = {
{test: /\.md$/, loader: 'raw'}
]
},
+ resolveLoader: {
+ alias: {
+ babel: __dirname + '/node_modules/babel-loader'
+ }
+ },
resolve: {
alias: {
+ 'react-popover-control$': path.join(__dirname, '../src/index.js'),
react: __dirname + '/node_modules/react'
}
},
devServer: {
- port: 9000
+ port: 9000,
+ contentBase: './build'
},
- devtool: IS_DEV ? 'cheap-module-source-map' : undefined,
+ devtool: 'sourcemap',
+ // devtool: IS_DEV ? 'cheap-module-source-map' : undefined,
postcss: function() {
return [autoprefixer];
},
@@ -44,4 +54,4 @@ module.exports = {
new ExtractTextPlugin('style.css'),
new StaticRenderWebpackPlugin('bundle.js', routes)
]
-}
\ No newline at end of file
+}
diff --git a/src/index.js b/src/index.js
index 091f006..e22008d 100644
--- a/src/index.js
+++ b/src/index.js
@@ -2,6 +2,14 @@ import React, {PropTypes} from 'react';
import {debounce, map} from 'lodash';
import keycode from 'keycode';
import EventStack from 'active-event-stack';
+import classNames from 'classnames';
+
+let useSheet;
+if (typeof window === 'undefined') {
+ useSheet = x => x => x;
+} else {
+ useSheet = require('./useSheet');
+}
const PopoverActionsType = PropTypes.arrayOf(PropTypes.shape({
title: PropTypes.string.isRequired,
@@ -11,7 +19,8 @@ const PopoverActionsType = PropTypes.arrayOf(PropTypes.shape({
export default class PopoverControl extends React.Component {
static propTypes = {
actions: PopoverActionsType.isRequired,
- className: PropTypes.string
+ className: PropTypes.string,
+ sheet: PropTypes.object
}
state = {
isPopped: false
@@ -45,29 +54,23 @@ export default class PopoverControl extends React.Component {
}
}, 100);
- document.addEventListener('scroll', this._debouncedScroll, true);
+ document.addEventListener('scroll', this._debouncedScroll);
window.addEventListener('resize', this._debouncedScroll);
}
componentWillUnmount = () => {
- document.removeEventListener('scroll', this._debouncedScroll, true);
+ document.removeEventListener('scroll', this._debouncedScroll);
window.removeEventListener('resize', this._debouncedScroll);
}
render = () => {
const {top, left, width, height} = this.state;
- let popoverControlStyle = {
- position: 'relative'
- }
-
return (
-
-
+
+
{this.props.children}
{this.state.isPopped ?
-
)
}
-}
+};
+const PopoverListStyles = {
+ base: {
+ backgroundColor: 'white',
+ minWidth: 150,
+ overflow: 'hidden',
+ boxShadow: '0px 1px 4px rgba(0, 0, 0, 0.25)',
+ borderRadius: 5
+ },
+ item: {
+ display: 'block',
+ height: 40,
+ lineHeight: 40,
+ padding: '0 10px',
+ color: '#1A2D36',
+ '&:hover': {
+ textDecoration: 'none',
+ color: '#1A2D36',
+ backgroundColor: '#e1f0f7',
+ }
+ }
+};
+
+@useSheet(PopoverListStyles)
class PopoverList extends React.Component {
static propTypes = {
actions: PopoverActionsType.isRequired,
@@ -86,13 +112,19 @@ class PopoverList extends React.Component {
getPopoverReferenceFrame: PropTypes.func.isRequired
}).isRequired,
windowMargin: PropTypes.number.isRequired,
- launcherMargin: PropTypes.number.isRequired
+ launcherMargin: PropTypes.number.isRequired,
+ zIndex: PropTypes.number.isRequired
}
static defaultProps = {
+ zIndex: 10,
windowMargin: 20,
launcherMargin: 10
}
state = {
+ top: null,
+ left: null,
+ width: null,
+ height: null,
offsetX: 0,
isFlipped: false, // usually bottom facing, but if true, then the popover should appear above
}
@@ -103,8 +135,8 @@ class PopoverList extends React.Component {
]);
// Once the element is in the dom, we can measure its height
- const {width, height} = React.findDOMNode(this).getBoundingClientRect();
- this.setState({width, height});
+ const {top, left, width, height} = React.findDOMNode(this).getBoundingClientRect();
+ this.setState({top, left, width, height});
}
componentWillUnmount() {
EventStack.removeListenable(this.eventToken);
@@ -119,6 +151,7 @@ class PopoverList extends React.Component {
this.props.delegate.shouldHidePopover();
}
render() {
+ const {props: {sheet: {classes}}} = this;
const {windowMargin, launcherMargin, parentFrame, actions} = this.props;
const {width, height} = this.state;
@@ -128,7 +161,7 @@ class PopoverList extends React.Component {
};
// State
- let offsetY = parentFrame.height + launcherMargin,
+ let offsetY = parentFrame.height + launcherMargin,
offsetX = 0;
// Flipping
@@ -144,18 +177,20 @@ class PopoverList extends React.Component {
position: 'absolute',
top: 0,
left: 0,
- transform: `translate(${offsetX}px, ${offsetY}px)`
+ transform: `translate(${offsetX}px, ${offsetY}px)`,
+ zIndex: this.props.zIndex
};
return (
-
+
)
}
-}
\ No newline at end of file
+};
diff --git a/src/useSheet.js b/src/useSheet.js
new file mode 100644
index 0000000..6364583
--- /dev/null
+++ b/src/useSheet.js
@@ -0,0 +1,17 @@
+import {Jss} from 'jss';
+import reactJss from 'react-jss';
+import jssPx from 'jss-px';
+import jssCamelCase from 'jss-camel-case';
+import jssNested from 'jss-nested';
+
+const jss = new Jss();
+
+if (typeof window !== 'undefined') {
+ const vendorPrefixer = require('jss-vendor-prefixer');
+ jss.use(vendorPrefixer);
+}
+jss.use(jssPx);
+jss.use(jssCamelCase);
+jss.use(jssNested);
+
+export default reactJss(jss);