Giter Site home page Giter Site logo

react-typestyle's Introduction

React integration of TypeStyle

wercker status

React-TypeStyle provides a higher-order component to easily use TypeStyle to style your React components. It automatically handles dynamic style updates, caching and deduping across all components.

Install

using yarn

yarn add react-typestyle

or npm

npm install --save react-typestyle

Usage

Just add a static styles field to your React component and wrap it in the withStyles higher-order component. You can now access generated class names via props.classNames.

Example

TypeScript

import withStyles, { InjectedProps, InputSheet } from 'react-typestyle';

interface Props {
  name: string;
  pos: { x: number, y: number };
  theme: { color: string };
}

class Component extends React.PureComponent<Props & InjectedProps> {
  public static styles: InputSheet<Props> = {
    button: {
      background: 'transparent',
      border: 'none',
    },
    root: (props) => ({
      color: props.theme.color,
      position: 'absolute',
      transform: `translate(${props.pos.x}px,${props.pos.y}px)`,
    }),
  };

  public render() {
    const { classNames, name } = this.props;
    return (
      <div className={classNames.root}>
        <button className={classNames.button}>{name}</button>
      </div>
    );
  }
}

export default withStyles()<Props>(Component);

JavaScript

import withStyles from 'react-typestyle';

class Component extends React.PureComponent {
  static styles = {
    button: {
      background: 'transparent',
      border: 'none',
    },
    root: (props) => ({
      color: props.theme.color,
      position: 'absolute',
      transform: `translate(${props.pos.x}px,${props.pos.y}px)`,
    }),
  };

  render() {
    const { classNames, name } = this.props;
    return (
      <div className={classNames.root}>
        <button className={classNames.button}>{name}</button>
      </div>
    );
  }
}

export default withStyles()(Component);

Stateless Components

TypeScript

import withStyles, { InjectedProps, StyledStatelessComponent } from 'react-typestyle';

interface Props {
  name: string;
  pos: { x: number, y: number };
  theme: { color: string };
}

const Component: StyledStatelessComponent<Props> = ({ classNames, name }) => (
  <div className={classNames.root}>
    <button className={classNames.button}>{name}</button>
  </div>
);

Component.styles = {
  button: {
    background: 'transparent',
    border: 'none',
  },
  root: (props) => ({
    color: props.theme.color,
    position: 'absolute',
    transform: `translate(${props.pos.x}px,${props.pos.y}px)`,
  }),
};

export default withStyles()<Props>(Component);

JavaScript

import withStyles from 'react-typestyle';

const Component = ({ classNames, name }) => (
  <div className={classNames.root}>
    <button className={classNames.button}>{name}</button>
  </div>
);

Component.styles = {
  button: {
    background: 'transparent',
    border: 'none',
  },
  root: (props) => ({
    color: props.theme.color,
    position: 'absolute',
    transform: `translate(${props.pos.x}px,${props.pos.y}px)`,
  }),
};

export default withStyles()(Component);

Options

You can pass in general options and options specific to the wrapped component.

withStyles(options)(Component, componentOptions)

options

  • plugins?: Array<(style: { [property: string]: any }, type: string, renderer: any, props?: { [key: string]: any }) => { [property: string]: any }>
    Plugins for further style transformations. The plugin API is compatible with most Fela plugins, e.g. fela-plugin-prefixer

  • renderer: Registry
    A registry instance the component's styles will be mounted to. Defaults to a global Renderer instance

  • shouldStylesUpdate: <Props>(props: Props, nextProps: Props) => boolean
    Used to check whether styles should to be rerendered. Defaults to a shallow comparison of next and current props

componentOptions

  • styles: InputSheet<Props>
    Alternative style sheet, overwrites styles field of wrapped component

Server Side Rendering

Just like TypeStyle itself, React-TypeStyle can easily be used for server side rendering.

import { getStyles } from 'react-typestyle';

// Render the react app...

// Render to CSS style tag
const styleTag = `<style>${getStyles()}</style>`
// ^ send this as a part of your HTML response

Note: As React-TypeStyle uses a custom renderer under the hood, you can not use TypeStyle's getStyles() function.

Utilities

Dynamic Extend

If you are using dynamic styles (your stylesheet includes functions), TypeStyle's standard extend won't work for you.
If you want to compose dynamic styles, use React-TypeStyle's dynamic extend instead.

import { extend } from 'react-typestyle';

// Compose styles
const styles = extend(
  ({ background }) => ({ background }),
  { color: '#fff' },
  () => ({}),
);

// Use them in the higher-order component
class Component extends React.PureComponent {
  static styles = {
    root: styles,
  };

  render() {/* ... */}
}

Developing

This is what you do after you have cloned the repository:

yarn / npm install
npm run build

(Install dependencies & build the project.)

Linting

Execute TSLint

npm run lint

Try to automatically fix linting errors

npm run lint:fix

Testing

Execute Jest unit tests using

npm test

npm run test:coverage

Tests are defined in the same directory the module lives in. They are specified in '[module].test.js' files.

Building

To build the project, execute

npm run build

This saves the production ready code into 'dist/'.

react-typestyle's People

Contributors

paulbrachmann avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

hyunseob

react-typestyle's Issues

this.props.classNames doesn't expose styles with static typing...?

First off, I love what you're working on, I think it's a natural extension to typestyle for react!

I have a component I've created to test react-typestyle:

class TestComponent extends React.PureComponent<Props & InjectedProps, RootState> {

  public static styles: InputSheet<Props> = {
    bg: {
      background: 'red'
    }
  };

  render() {
    return (
      <div className={this.props.classNames.bg}>
      </div>
    );
  }
}

When assigning the className on the div I realised that this.props.classNames offers no autocomplete, and is simply the 'ClassNames' type.

Which means, I can also write this.props.classNames.garbage and TS offers no complaints.

Compare that to regular typestyle, where if I declare styles, I can do styles. and I get completion & compile-time checking that all my styles actually exist.

Have I done something wrong, or is this a limitation of react-typestyle?

Dynamic styles overriding static styles?

I've been looking for a CSS in JS solution and your project looks very promising.

In dynamicExtend in utils.ts, I noticed that dynamic styles take precedence over static styles:

return extend(
    ...staticStyles,
    ...((dynamicStyles as StyleGenerator<P>[]).map((style) => style(props))),
);

Is there a reason styles are not applied in the order they were given?

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.