Skip to content

Instantly share code, notes, and snippets.

@SanderSpies
Last active August 29, 2015 14:09
Show Gist options
  • Save SanderSpies/8ded0da686c70ec59086 to your computer and use it in GitHub Desktop.
Save SanderSpies/8ded0da686c70ec59086 to your computer and use it in GitHub Desktop.

So this is my current solution for "fixing" the implicit nature of CSS. It basically replaces CSS selectors, classNames, etc. with the ability to directly reference to a style from JavaScript.

/**
 * @jsx React.DOM
 */
'use strict';

var React = require('react');
var ReactStyle = require('react-style');

var ButtonStyles = {

  normalStyle: ReactStyle({
    display: 'inline-block',
    zoom: 1,
    lineHeight: 'normal',
    whiteSpace: 'nowrap',
    verticalAlign: 'baseline',
    textAlign: 'center',
    cursor: 'pointer',
    userSelect: 'none',
    fontFamily: 'inherit',
    outline: 'none',
    fontSize: '100%',
    padding: '0.5em 1em',
    color: 'rgba(0, 0, 0, 0.70)',
    border: 'none rgba(0, 0, 0, 0)',
    backgroundColor: '#E6E6E6',
    textDecoration: 'none',
    borderRadius: '3px'
  }, 'Button_baseStyle'),

  activeStyle: ReactStyle({
    boxShadow: '0 0 0 1px rgba(0,0,0, 0.15) inset, 0 0 6px rgba(0,0,0, 0.20) inset'
  }, 'Button_activeStyle'),

  hoverStyle: ReactStyle({
    color: '#000',
    backgroundImage: 'linear-gradient(transparent, rgba(0,0,0, 0.05) 40%, rgba(0,0,0, 0.10))'
  }, 'Button_hoverStyle'),

  focusStyle: ReactStyle({
    backgroundImage: 'linear-gradient(transparent, rgba(0,0,0, 0.05) 40%, rgba(0,0,0, 0.10))',
    outline: 'none'
  }, 'Button_focusStyle')
};

class Button {

  getInitialState() {
    return {
      focus: false,
      hover: false
    }
  }

  render() {
    var props = this.props;
    var state = this.state;
    var styles = [
        ButtonStyles.normalStyle,
        props.active ? ButtonStyles.activeStyle : null,
        state.hover ? ButtonStyles.hoverStyle : null,
        state.focus ? ButtonStyles.focusStyle : null
    ].concat(props.styles);

    return (
      <button {...props} styles={styles}
        onMouseEnter={this.onMouseEnter}
        onMouseLeave={this.onMouseLeave}
        onFocus={this.onFocus}
        onBlur={this.onBlur}>
        {props.children}
      </button>
    );
  }

  onMouseEnter() {
    this.setState({hover: true});
  }

  onMouseLeave() {
    this.setState({hover: false});
  }

  onFocus() {
    this.setState({focus: true});
  }

  onBlur() {
    this.setState({focus: false})
  }
}

module.exports = React.createClass(Button.prototype);
@bkardell
Copy link

What do you mean exactly by "implicit nature"?

What you are doing - you can already do that through CSSOM (admittedly terrible) API though, and it is actually using CSS, you're just not expressing it in CSS or using many of the features -- I think you are kind of proving that if this is your current solution? What do you think is 'missing'?

@SanderSpies
Copy link
Author

The way how CSS and HTML/JS are connected is implicit. classNames easily break quietly, leaving tons of unknown code inside most code repositories. CSS selectors refer implicit to DOM elements, which makes it harder to refactor code.

@SanderSpies
Copy link
Author

(will add more when I have the time)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment