Giter VIP home page Giter VIP logo

react-styleable's Introduction

react-styleable

Consistent, easy overrides for CSS Modules in React Components

Install

npm install react-styleable --save-dev

Usage

Styles in Props

react-styleable makes your styles from your CSS modules available on props.css.

Write your stylesheet with all the perks of css modules. For example:

.list {
  list-style: none;
  padding-left: 0;
  margin: 10px;
}
.item {
  outline: 1px solid red;
  padding: 10px;
}

Then in your reusable component, wrap your React.Component in react-styleable's higher-order component.

import styleable from 'react-styleable'

import css from './my-list.css'

class MyList extends React.Component {
  renderItem(item, i) {
    return (
      <li key={i} className={this.props.css.item}>{item}</li>
    )
  }
  renderList(items) {
    return items.map(this.renderItem)
  }
  render() {
    return (
      <ul className={this.props.css.list}>
        {this.renderList(this.props.items)}
      </ul>
    )
  }
}

export default styleable(css)(MyList)

Usage as a decorator is also nice:

@styleable(css)
class MyList extends React.Component { /* ... */ }

Your MyList component is now styled and ready to display!

Overriding Component Styles

This is the big payoff.

If you want to override this component's styles as the consumer, you can easily do so, through the same, consistent interface. First, define a new stylesheet:

.item {
  outline: 1px solid blue;
}

And use it to render MyList again, passing your new stylesheet via the props.css prop:

import MyList from './my-list'

import css from './client.css'

React.render(<MyList css={css} />, document.getElementById('app'))

Now the .items outline will be blue instead of the original red.

Composing Component Styles

If instead of just overriding the styles, you wanted to add to them with style composition, you can do that as well.

One method is via CSS modules' composes keyword. In your new stylesheet:

.item {
  composes: item from "./my-list.css";
  background: pink;
}

Now the original red outline will remain and a pink background will be present as well. This is the most surefire way to compose styles because it allows you to guarantee the order of the cascade.

But it has the downside of having to locate the original stylesheet location.

If you have enough assurances on the cascade order and selector specificity, all potential concerns, you can use the compose api via the react-styleable to accomplish the same thing (in [email protected]):

import MyList from './my-list'

import css from './client.css'

React.render(<MyList css={{ compose: css }} />, document.getElementById('app'))

Styled. Portable. Easily overridden. So, so good.

react-styleable's People

Contributors

bressain avatar dependabot[bot] avatar jaketrent avatar landonwilkins avatar rafaelcardoso avatar twclark0 avatar vyorkin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-styleable's Issues

PropTypes.isRequired flag lost after decoration

Found that components that have been decorated by styleable lose propTypes. This is manifested whenever a parent component renders a child component with an isRequired propType that has been styled by Styleable and the parent forgot to provide the prop. Normally this would result in a console warning but noticed that they have been missing. Here's an example that would produce the issue:

@styleable(childCss)
export default class Child extends React.Component {
  static propTypes = {
    required: React.PropTypes.string.isRequired
  };
  render () {
    return (
      <div>Required content: {this.props.required}</div>
    )
  }
}

...

@styleable(css)
export default class Parent extends React.Component {
  // note that we're forgetting the required propType
  render () {
    return (
      <div><Child /></div>
    )
  }
}

When rendering, we should see a warning.

Can't get it working with defaultProps

I've just tried to use defaultProps + stateless components and it seems this is the only way to make it work:

import React, { PropTypes } from 'react';
import styleable from 'react-styleable';
import cn from 'classnames';

import Icon from '../Icon';
import styles from './styles';

const { bool, string, object, node } = PropTypes;

export const Button = (props) => {
  // ......... skipped ...........
  return (
    <button className={rootClass} disabled={disabled} {...other}>
      {icon && <Icon className={cn(iconClassName, css.icon)} value={icon} />}
      {label && <span className={cn(labelClassName, css.label)}>{label}</span>}
      {children}
    </button>
  );
};

const StyledButton = styleable(styles)(Button);

StyledButton.defaultProps = {
  disabled: false,
  neutral: true,
  rounded: false,
  small: false,
  big: false
};
export default StyledButton;

if I do it as usual, e.g.:

Button.defaultProps = {
  disabled: false,
  neutral: true,
  rounded: false,
  small: false,
  big: false
};
export default styleable(styles)(Button);

then I won't have my defaults set.

Combine with react-css-modules

Do you think there is an easy way to combine this with react-css-modules?

Btw; this package is awesome. Hope that more big react component projects will adopt this pattern.

Question: Class name with dash

Hello - excellent framework! ๐Ÿ‘

I tend to use dashes (-) in my class names, like product-image. Can I still do so when using styleable? My naive approach was to do what I've been doing with the className attribute, that is passing in productImage, but it didn't work for me.

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.