Skip to content

Instantly share code, notes, and snippets.

@goldhand
Last active March 23, 2017 19:48
Show Gist options
  • Save goldhand/56509526435a90315bb7f1bfee0dc26e to your computer and use it in GitHub Desktop.
Save goldhand/56509526435a90315bb7f1bfee0dc26e to your computer and use it in GitHub Desktop.
Format pseudo styles for a react component
/**
* Pseudo styles
* @param {Object} pseudoStates - state object with keys matching pseudo attributes
* @returns {Object} use(styles)
*
* @example
* const styles = {color: '#000', hover: {color: 'red'}, active: {color: 'green'}};
* const state = {hover: true, active: true};
* pseudoStyles(state)
* .use(styles.button)
* .set('hover')
* .set('active')
* .styles(); // {color: 'green'}
*/
const pseudoStyles = pseudoStates => {
const setStyles = style => attr => {
const attrActive = (
Object.prototype.hasOwnProperty.call(style, attr) &&
Object.prototype.hasOwnProperty.call(pseudoStates, attr) &&
pseudoStates[attr]
);
const nextStyles = attrActive
? {...style, ...style[attr]}
: {...style};
return {
set: setStyles(nextStyles),
styles: () => nextStyles,
};
};
return {
use: style => setStyles(style)(),
};
};
/**
* generic/components/Button.js
*/
import React, {PropTypes} from 'react';
import Pseudo from '../../components/Pseudo';
import * as styles from '../../styles/buttons';
/**
*
* @returns {object} <Button />
*/
export const Button = ({
active,
children,
focus,
hover,
onClick,
onMouseEnter,
onMouseLeave,
onMouseDown,
onMouseUp,
onFocus,
onBlur,
}) => {
const getStyles = use => Pseudo.pseudoStyles({
hover,
active,
focus,
}).use(use)
.set('hover')
.set('active')
.set('focus')
.styles();
return (
<button
style={getStyles(styles.button)}
onClick={onClick}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
onMouseDown={onMouseDown}
onMouseUp={onMouseUp}
onFocus={onFocus}
onBlur={onBlur}
>
<span style={getStyles(styles.inner)}>
<span style={styles.text}>
{children}
</span>
</span>
</button>
);
};
Button.propTypes = {
active: PropTypes.bool.isRequired,
children: PropTypes.node.isRequired,
focus: PropTypes.bool.isRequired,
hover: PropTypes.bool.isRequired,
onClick: PropTypes.func,
onMouseEnter: PropTypes.func,
onMouseLeave: PropTypes.func,
onMouseDown: PropTypes.func,
onMouseUp: PropTypes.func,
onFocus: PropTypes.func,
onBlur: PropTypes.func,
};
Button.defaultProps = {
onClick: null,
onMouseEnter: null,
onMouseLeave: null,
onMouseDown: null,
onMouseUp: null,
onFocus: null,
onBlur: null,
};
export default Pseudo(Button);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment