Cat components

Styles

Components

Decorators

How to use

Install package

yarn add react react-dom cat-components
//or
npm install react react-dom cat-components

Install other packages

Some components need other packages. You should install those packages by yourself.

Use it

Then you can use those components with import [component name] from 'cat-components/lib/[component name]';. You can see code to learn how to use those components.

Most components can be used like normal component. As a result, you can use like style, onClick and so on. However, remember to add radium-normalize or include normalize.css to your project.

Utils

Here are some functions you can use. Use them with import [util name] from 'cat-components/lib/utils/[util name]';.

  • toggleStyle(status, styles) [func]

    This will give a style with radium.keyframes. If the status is true, it will make an animtion from the first style to ths least style.

    • status [bool, default: true]

      Use to determine give a showing style or hiding style.

    • styles [array, default: []]

      The styles in this array must be [hideStyle, ..., showStyle]. This array must have at least two elements.

  • loadAnimation(styles) [func]

    This will return an array of <StyleRoot />. Owing to some problems with radium.keyframes, you can use this to load some keyframes which you add after the components are mounted.

    • styles [array, default: []]

      Add style to this array.

Multiple components

Because those components are build with radium, this is difficult that users can control all the styles if the component is complex. As a result, those components are as simpler as possible. However, I have write some examples to show how to use those components to make some complex components.

color

This is the style of the color from material design.

Example

import red from 'components/lib/color/red';

console.log(red); // #F44336
// or
import * as red from 'components/lib/color/red';

console.log(red);
/*
 * {
 *   "_50_": "#FFEBEE",
 *   "_100_": "#FFCDD2",
 *   "_200_": "#EF9A9A",
 *   "_300_": "#E57373",
 *   "_400_": "#EF5350",
 *   "_500_": "#F44336",
 *   "_600_": "#E53935",
 *   "_700_": "#D32F2F",
 *   "_800_": "#C62828",
 *   "_900_": "#B71C1C",
 *   "default": "#F44336"
 * }
 * /

layout

This is the style of layout.

  • tablet(style) [func]

    Add style to tablet size (480px ~ 839px).

  • phone(style) [func]

    Add style to phone size (0px ~ 479px).

    • style [object]

Example

'use strict';

import React from 'react';
import radium, {StyleRoot} from 'radium';
import * as layoutStyle from 'cat-components/lib/layout';

import * as style from './style/useLayout';

@radium
export default class UseLayout extends React.Component {
  render() {
    return (
      <StyleRoot style={[style.root, layoutStyle.tablet(style.tablet), layoutStyle.phone(style.phone)]} />
    );
  }
}

Alert

You need to add Alert before you use alertBuilder.

Props

  • animationStyles [array]

    Use to modify the animation of showing or hiding the alert. It must be an array like [hideStyle, ..., showStyle]. You can use many styles in this array.

Decorators

  • alertBuilder
    • Props
      • alert(component) [func]

        This is the function to build alert.

        • component({hide, Icon}) [func, required]

          This is uesd to build the children of the alert.

          • hide() [func]

            You can give this function to your component as props and use this to hide the component.

          • Icon [component]

            You can add Icon to your Alert.

      • hideAlert() [func]

        This is the function to hide alert.

      • alertIsShown [bool]

Example

'use strict';

import React from 'react';
import PropTypes from 'prop-types';
import radium from 'radium';
import Button from 'cat-components/lib/button';
import Alert, {alertBuilder} from 'cat-components/lib/alert';

@radium
@alertBuilder
class UseAlert extends React.Component {
  static propTypes = {
    alert: PropTypes.func.isRequired
  }

  render() {
    const {alert} = this.props;

    return (
      <div>
        <Button onClick={() => alert()}
        >Default Alert</Button>

        <Button
          onClick={() => alert(({hide, Icon}) => (
            <div>
              <Icon />

              Alert
            </div>
          ))}
        >Custom Alert</Button>
      </div>
    );
  }
}

export default () => ( // eslint-disable-line react/display-name
  <Alert>
    <UseAlert />
  </Alert>
);

Button

Combine a tag and button tag in one component with custom style.

Props

  • link [string]

    If you do not give a link, it will render a normal button.

  • target [string]

    This is used for a tag.

Example

'use strict';

import React from 'react';
import radium from 'radium';
import Button from 'cat-components/lib/button';

@radium
export default class UseButton extends React.Component {
  render() {
    return (
      <div>
        <Button>button</Button>

        <Button link='https://github.com/HsuTing/cat-components'
        >button with a link</Button>

        <Button link='https://github.com/HsuTing/cat-components'
          target='_blank'
        >button with a link(target: _blank)</Button>
      </div>
    );
  }
}

Bundle

Make a component with bundle loader. This aslo can use server side rendering. You must set a variable like TYPE to make the different between client and server side.

Example

'use strict';
import Bundle, {load} from 'cat-components/lib/bundle';

<Bundle load={
  process.env.TYPE === 'client' ?
    require('bundle-loader?lazy&name=simple!./Component') :
    load(require('./Component'))
}
>
  {Component => <Component />}
</Bundle>

Calendar

Because this component uses moment, the month which you give and you get is equal to the real month minus one.

Other packages

Props

  • start [int, default: 1999]

    This is the start of the year.

  • end [int, default: 2030]

    This is the end of the year.

  • format [string, default: 'MMM D YYYY']

    You can use this to modify the format of the text. See here to learn more information.

  • isChosenStyle [object]

    Use to modify style when date is chosen.

  • getDate(date) [func]

    Use to get date.

    • date [object]

      This is the date which is choosen, like {year: 1990, month: 1, date: 1}.

  • defaultDate [object]

    Give a default date to Calendar. For example, it can be {year: 2017}.

  • date [object]

    Give a date when you want to change the date which is chosen. For example, it can be {year: 2017}.

Example

'use strict';

import React from 'react';
import radium from 'radium';
import Calendar from 'cat-components/lib/calendar';

@radium
export default class UseCalendar extends React.Component {
  render() {
    return (
      <Calendar />
    );
  }
}

Dec 18 2017
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

CalendarTable

Other packages

Props

  • year [int, default: this year]

    This is the year of the calendar.

  • month [int, required]

    This is the month of the calendar. If you want to set July, you need to set 6, not 7.

  • date [int, today]

    This is the date today.

  • children [component, required]

    Use to render the calendar. This will be given year, month, date, isBefore, isAfter and sameMonth as props.

    • year, month, date [int]

      This is the date of this children.

    • isBefore, isAfter [boolean]

      Use to show the date of this children is before or after today.

    • sameMonth [boolean]

      Use to show if the month of this children is same as this month of the calendar.

Example

'use strict';

import React from 'react';
import radium, {StyleRoot} from 'radium';
import moment from 'moment';
import CalendarTable from 'cat-components/lib/calendar-table';

import * as style from './style/useCalendarTable';

const now = moment();

const Cell = ({year, month, date, isBefore, isAfter, sameMonth, ...props}) => {
  const addStyle = [
    style.root
  ];

  if(!sameMonth)
    addStyle.push(style.notThisMonth);

  return (
    <StyleRoot {...props}
      style={addStyle}
    >
      <font style={!isBefore && !isAfter ? style.today : {}}>
        {`
          ${date === 1 ? `${moment({year, month, date}).format('MMM')} ` : ''}
          ${date}
        `}
      </font>
    </StyleRoot>
  );
};

@radium
export default class UseCalendarTable extends React.Component {
  render() {
    return (
      <CalendarTable month={now.month()}>
        <Cell />
      </CalendarTable>
    );
  }
}

26
27
28
29
30
Dec 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Jan 1
2
3
4
5
6

Loading

Other packages

Props

  • innerRadius [int, default: 10]

    This is the radius of the inner circle.

  • outerRadius [int, default: 13]

    This is the radius of the outer circle.

  • sec [int, default 0.5]

    This is the duration of the animation.

  • fps [int, default: 60]

    This is the fps of the animation.

  • diff [int, default: 0.8]

    This is the max value between the start angle and the end angle.

  • animation [string | func, default: 'quartInOut']

    This is the function of the animation. It can be a name of eases or a function.

Example

'use strict';

import React from 'react';
import radium from 'radium';
import Loading from 'cat-components/lib/loading';

@radium
export default class UseLoading extends React.Component {
  render() {
    return (
      <Loading />
    );
  }
}

I18n

This uses to build several languages in website with fetch. This will try to get new json file when you change language.

Other packages

Props

  • lang [string, required]

    This is the default language which will be used at first.

  • defaultData [object, required]

    The data of the language is used at first. For example, it can be {hello: "Hello world"}.

  • basename [string, default: '/public/i18n/']

    This is the basename of the url which has those files, like en-us.json, zh-tw.json.

Decorators

  • language
    • Props
      • translate [object]

        This is the object of the language data from your json file.

      • changeLanguage(lang) [func]

        This is a function which can be used to change the language. Use like onClick={changeLanguage('en-us')}.

        • lang [string, required]

Example

// en-us.json
{
  hello: "Hello world"
}

// component
'use strict';

import React from 'react';
import PropTypes from 'prop-types';
import radium from 'radium';
import Button from 'cat-components/lib/button';
import {language} from 'cat-components/lib/i18n';

@radium
@language
export default class UseI18n extends React.Component {
  static propTypes = {
    translate: PropTypes.object.isRequired,
    changeLanguage: PropTypes.func.isRequired
  }

  render() {
    const {translate, changeLanguage} = this.props;

    return (
      <div>
        {[{
          title: '中文',
          value: 'zh-tw'
        }, {
          title: 'English',
          value: 'en-us'
        }].map((item, itemIndex) => (
          <Button key={itemIndex}
            onClick={changeLanguage(item.value)}
          >{item.title}</Button>
        ))}

        <div>{translate.hello}</div>
      </div>
    );
  }
}


// root comopnent
export default () => (
  <I18n lang='en-us'
    defaultData={defaultData}
  >
    <UseI18n />
  </I18n>
);
Hello world

Icon

Make an icon of this website.

Example

'use strict';

import React from 'react';
import radium from 'radium';
import Icon from 'cat-components/lib/icon';

@radium
export default class UseIcon extends React.Component {
  render() {
    return (
      <Icon />
    );
  }
}

Hsu Ting

Img

Combine a tag and img tag in one component. This component will not render the img immediately. This component will render img after the img is loaded.

Props

  • type [string, default: 'img']

    Use to set the type of the img.

  • link [string]

    If you do not give a link, it will render a normal img.

  • target [string]

    This is used for a tag.

  • src [string, required]

    This is the link of the img.

Example

'use strict';

import React from 'react';
import radium from 'radium';
import Img from 'cat-components/lib/img';

import * as style from './style/useImg';

@radium
export default class UseImg extends React.Component {
  render() {
    return (
      <div>
        <Img src='https://hsuting.github.io/public/img/icon.svg'
          link='https://github.com/HsuTing/cat-components'
        />

        <Img style={style.div}
          src='https://hsuting.github.io/public/img/icon.svg'
          link='https://github.com/HsuTing/cat-components'
          type='div'
        />
      </div>
    );
  }
}

ImgZoom

Other packages

Props

  • rootStyle(isZoom) [func]

    Use to modify the root style of the background.

    • isZoom [bool]

      This will be true when the img is zoomed in.

  • imgBackgroundStyle [object]

    Use to modify the style of the img`s background. Here is a transparent div which control the size of the img.

  • imgStyle [object]

    Use to modify the style of the img.

Decorators

  • addZoom
    • Props
      • zoomIn(src, e) [func]

        Show the image.

        • src [string, required]

          Give the link of the img.

        • e [object, required]

          Give the event to the img. You can see the example.

      • zoomOut() [func]

        Hide the image.

Example

'use strict';

import React from 'react';
import PropTypes from 'prop-types';
import radium from 'radium';
import ImgZoom, {addZoom} from 'cat-components/lib/img-zoom';
import Img from 'cat-components/lib/img';

@addZoom
@radium
class UseImgZoom extends React.Component {
  static propTypes = {
    zoomIn: PropTypes.func.isRequired
  }

  render() {
    const {zoomIn} = this.props;

    return (
      <Img src='https://hsuting.github.io/public/img/icon.svg'
        onClick={e => zoomIn('https://hsuting.github.io/public/img/icon.svg', e)}
      />
    );
  }
}

export default () => ( // eslint-disable-line react/display-name
  <ImgZoom>
    <UseImgZoom />
  </ImgZoom>
);

Input

This is input tag with using validator to check value. For checking value in the server, you can use import {inputCheck} from 'cat-components/lib/input'; and give this function value and rules.

If you want to use input with redux, you just need to change input to input-redux. You can see the example to know how to use it.

Other packages

Props

  • type [string, default: text]

    This can be the all type of input tag, and it can be textarea.

  • rules [array, required]

    This will give to inputCheck to check if value is correct.

    • validator(value, event) [func | string, required)

      Use to check value. You can use function from validator with giving a name or write a function to check value. You just need to return true or false to show if value is correct.

      • value

        This is the value of the input.

      • event

        This is the event of the input.

    • message [func | string, required]

      This message will be pushed to error when value is incorrect.

    • options [object]

      You can add other options for validator.

    • not [bool]

      Use to reverse the result.

  • value [string, required]

    Give the input a value.

  • onChange(data, event) [func, required]

  • onBlur(data, event) [func]

    onChange will be called when the value of the input is changed. onBlur will be called when user is not focus on the input. Those functions can return an object like data and it will be added to the input.

    • data [object]

      This is the result of the inputCheck when a value give to the input.

      • value [string]

        This is a value of this input.

      • isError [bool]

        This is the result of the rules.

      • error [array]

        Here are the error messages when value does not pass the rules.

    • event [object]

      This is the event of the input.

Decorators

  • inputConnect

    This is like connect in react-redux. It will return connect when you give a formName. So you can give the arguments to inputConnect, like inputConnect('test_form')(mapStateToProps, mapDispatchToProps, mergeProps, options).

    Remeber to add formReducer in your combineReducers. Use import {formReducer} from 'cat-components/lib/input-redux'; to import this reducer.

    • Other packages

    • Arguments

      • formName [string, required]

        Use to determine the form which should be used.

    • Props

      • form [object]

        This is the data of the form.

      • isSubmited [bool]

        Check if form is submited.

      • inputDispatch(inputName, value) [func]

        Use this function in the onChange function.

        • inputName [string]

          This is the name of the input. It will be used for redux to add value to form.

        • value [object]

          The value of the input is used to redux, and it will be like the result of the inputCheck which has value, isError and error.

      • submitDispatch(callback) [func]

        Owing to isSubmited in the form, you will not get the real isError. As a result, this is recommended that you should use this when you want to send the data to a server.

        • callback(form) [func]

          This will be called after isSubmited is changed in the form. This will get the real data of the form.

          • form [object]
      • resetDispatch(callback) [func]

        Use to reset form.

        • callback(data) [func]

          • data [object]

            This is the data of the form. Use to determine how to reset form.

Example

// component
'use strict';

import React from 'react';
import PropTypes from 'prop-types';
import radium from 'radium';
import Button from 'cat-components/lib/button';
import Input, {inputConnect, inputCheck} from 'cat-components/lib/input-redux';

import * as style from './style/useInput';

const rules = [{
  validator: 'isEmpty',
  message: 'It can not be empty.'
}, {
  validator: 'isEmail',
  not: true,
  message: 'It must be a email.'
}, {
  validator: value => value !== 'hsuting0106@gmail.com',
  message: 'This email must be "hsuting0106@gmail.com".'
}];

const errorMessage = (isError, error) => (
  !isError ?
    null :
    error.map((err, index) => (
      <p key={index}
        style={style.error}
      >{err}</p>
    ))
);

@radium
class UseDefaultValue extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: 'test@gmail.com',
      isError: false,
      error: []
    };

    this.onChange = this.onChange.bind(this);
  }

  render() {
    const {value, isError, error} = this.state;

    return (
      <div>
        <Input style={isError ? style.inputError : {}}
          rules={rules}
          value={value}
          onChange={this.onChange}
          type='textarea'
        />

        {errorMessage(isError, error)}
      </div>
    );
  }

  onChange(data) {
    this.setState(data);
  }
}

@radium
@inputConnect('test_form')()
class UseRedux extends React.Component {
  static propTypes = {
    form: PropTypes.object.isRequired,
    inputDispatch: PropTypes.func.isRequired
  }

  render() {
    const {form, inputDispatch} = this.props;
    const {value, isError, error} = form.test_input || {};

    return (
      <div>
        <Input style={isError ? style.inputError : {}}
          rules={rules}
          value={value === undefined ? 'test@gmail.com' : value}
          onChange={data => inputDispatch('test_input', data)}
        />

        {errorMessage(isError, error)}
      </div>
    );
  }
}

@radium
@inputConnect('test_form')()
class UseReduxWithNoDefaultValue extends React.Component {
  static propTypes = {
    form: PropTypes.object.isRequired,
    inputDispatch: PropTypes.func.isRequired,
    submitDispatch: PropTypes.func.isRequired,
    resetDispatch: PropTypes.func.isRequired
  }

  constructor(props) {
    super(props);
    this.submit = this.submit.bind(this);
  }

  render() {
    const {form, inputDispatch, submitDispatch, resetDispatch} = this.props;
    const {value, isError, error} = form.test_input_no_default_value || {};

    return (
      <div>
        <Input style={isError ? style.inputError : {}}
          rules={rules}
          value={value === undefined ? '' : value}
          onChange={data => inputDispatch('test_input_no_default_value', data)}
        />

        {errorMessage(isError, error)}

        <Button onClick={() => submitDispatch(this.submit)}
        >Submit</Button>

        <Button
          onClick={() => resetDispatch(data => {
            Object.keys(data)
              .forEach(key => {
                data[key] = inputCheck('', rules);
              });
          })}
        >Reset</Button>
      </div>
    );
  }

  submit(form) {
    alert(JSON.stringify(form, null, 2));
  }
}

export default () => ( // eslint-disable-line react/display-name
  <div>
    <h5>Use default value</h5>
    <UseDefaultValue />

    <h5>Use redux</h5>
    <UseRedux />

    <h5>Use redux with no default value</h5>
    <UseReduxWithNoDefaultValue />
  </div>
);


// root component
import {combineReducers} from 'redux';
import {formReducer} from 'cat-components/lib/input-redux';

const reducers = combineReducers(formReducer);
// or
const reducers = combineReducers({
  yourReducer,
  ...formReducer
});
// Then, use to create store.
Use default value
Use redux
Use redux with no default value

PictureSlideshow

Use to make a picture slideshow.

Other packages

Props

  • index [int, required]

    This is the index of slideshow. Use this to control which image should be shown.

  • imgs [array, required]

    This is an array of image. It should have src to give a link of the image and other attributes will be given to image as props.

  • type [string, default: 'div']

    Choose the type of image. If type is img, this component will use img tag as image. If it is not, this component will use div tag as image.

  • position [object]

    • left [object]
    • center [object]
    • right [object]

    Those are the position of the image. This is recommended to use transform: 'translateX(x)' to set the position of the image.

Example

'use strict';

import React from 'react';
import radium from 'radium';
import PictureSlideshow from 'cat-components/lib/picture-slideshow';
import Button from 'cat-components/lib/button';

import * as style from './style/usePictureSlideshow';

const imgs = [{
  src: 'https://scontent-tpe1-1.cdninstagram.com/t51.2885-15/e35/17493450_397169997321386_4423519579884486656_n.jpg'
}, {
  src: 'https://scontent-tpe1-1.cdninstagram.com/t51.2885-15/e35/16465237_160262967811059_8777509647905980416_n.jpg'
}, {
  src: 'https://scontent-tpe1-1.cdninstagram.com/t51.2885-15/e35/16906239_1371447262875968_9128363095364730880_n.jpg'
}];

@radium
export default class UsePictureSlideshow extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      index: 0
    };

    this.onClick = this.onClick.bind(this);
  }

  render() {
    const {index} = this.state;

    return (
      <div>
        <h5>Type: img</h5>
        <PictureSlideshow index={index}
          imgs={imgs}
          type='img'
        />

        <h5>Type: div</h5>
        <PictureSlideshow index={index}
          imgs={imgs}
        />

        {imgs.map((img, imgIndex) => (
          <Button key={imgIndex}
            style={imgIndex === index ? style.isClicked : {}}
            onClick={this.onClick(imgIndex)}
          >{imgIndex}</Button>
        ))}
      </div>
    );
  }

  onClick(index) {
    return e => {
      this.setState({index});
    };
  }
}

Type: img
Type: div

Slider

Props

  • onChange(value) [func]

    Use to get value.

    • value [int]
  • value [int]

    This is the value of this component.

  • max [int, default: 100]

    This is the max of the value.

  • min [int, default: 0]

    This is the min of the value.

  • buttonStyle(percentage) [func]

  • barStyle(percentage) [func]

    Use to modify the style of the button and use to modify the style of the bar. You need to return an object of the style to modify the style.

    • percentage [float]

      If you modify the size of the button, this percentage is important to help you modify left. For example, it will be percentage => ({left: 'calc(' + percentage * 100 + '% - 10px)'}).

Example

'use strict';

import React from 'react';
import radium from 'radium';
import Slider from 'cat-components/lib/slider';

@radium
export default class UseSlider extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: 20
    };

    this.change = this.change.bind(this);
  }

  render() {
    const {value} = this.state;

    return (
      <div>
        <Slider onChange={this.change}
          value={value}
        />

        <h5>{value}</h5>
      </div>
    );
  }

change(value) {
    this.setState({value});
  }
}

20

Square

Make a square DOM. Remember that you do not set height of children DOM. If you set height, it will overwrite the height of Square.

Other packages

Props

  • children [component, required]

Example

'use strict';

import React from 'react';
import radium from 'radium';
import Square from 'cat-components/lib/square';

import * as style from './style/useSquare';

@radium
export default class UseSquare extends React.Component {
  render() {
    return (
      <Square>
        <div style={style.root} />
      </Square>
    );
  }
}

Table

Example

'use strict';

import React from 'react';
import radium from 'radium';
import {Table, Thead, Tbody, Tr, Td, Th} from 'cat-components/lib/table';

@radium
export default class UseTable extends React.Component {
  render() {
    return (
      <Table>
        <Thead>
          <Tr>
            {['list1', 'list2', 'list3'].map((data, index) => (
              <Th key={index}>{data}</Th>
            ))}
          </Tr>
        </Thead>
        <Tbody>
          {[
            ['item1-1', 'item2-1', 'item3-1'],
            ['item1-2', 'item2-2', 'item3-2']
          ].map((list, listIndex) => (
            <Tr key={listIndex}>
              {list.map((item, itemIndex) => (
                <Td key={itemIndex}>{item}</Td>
              ))}
            </Tr>
          ))}
        </Tbody>
      </Table>
    );
  }
}

list1list2list3
item1-1item2-1item3-1
item1-2item2-2item3-2

Timeline

Props

  • time [array, required]

    • date [string, required]

      The date of the time is shown.

    • content [component, required]

      The content of the time is shown.

  • color [string, default: '#2196f3']

    Change the color of the bar.

  • dateStyle [object]

    Modify the style of the date.

Example

'use strict';

import React from 'react';
import radium from 'radium';
import moment from 'moment';
import Timeline from 'cat-components/lib/timeline';

const format = 'MMMM Do YYYY';
const time = [{
  date: moment().format(format),
  content: <div>Content 1</div>
}, {
  date: moment().subtract(1, 'days').format(format),
  content: <div>Content 2</div>
}, {
  date: moment().subtract(2, 'days').format(format),
  content: <div>Content 3</div>
}];

@radium
export default class UseTimeline extends React.Component {
  render() {
    return (
      <Timeline time={time} />
    );
  }
}

December 18th 2017
Content 1
Content 2
December 17th 2017
December 16th 2017
Content 3

Toggle

Other packages

Props

  • rootStyle(isClicked) [func]

    Use to modify the style of the toggle. You need to return an object to modify the style.

    • isClicked [bool]

      This will be true when the toggle is clicked.

  • checked [bool]

    Use to set default clicked.

  • icons [object]

    You can use this to change icons. For example, it will be {default: IconOne, clicked: IconTwo}.

  • type [string, default: 'checkbox']

    Use to choose the type of the component. It can be checkbox, radio and switch.

    • radio

      • Props
        • clicked [bool, required]
    • switch

      • Props
        • buttonStyle [object]

          Use to modify the style of the button.

Example

'use strict';

import React from 'react';
import radium from 'radium';
import CheckCircleIcon from 'react-icons/lib/md/check-circle';
import LensIcon from 'react-icons/lib/md/lens';
import Toggle from 'cat-components/lib/toggle';

const icons = {
  default: LensIcon,
  clicked: CheckCircleIcon
};

@radium
export default class UseToggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: '1'
    };

    this.click = this.click.bind(this);
  }

  render() {
    const {value} = this.state;

    return (
      <div>
        <h5>Type: radio</h5>
        <div>
          <Toggle type='radio'
            clicked={value === '1'}
            onClick={this.click('1')}
          />
          <Toggle type='radio'
            clicked={value === '2'}
            onClick={this.click('2')}
          />
        </div>

        <h5>Type: checkbox</h5>
        <div>
          <Toggle checked />
          <Toggle />
        </div>

        <h5>Type: switch</h5>
        <div>
          <Toggle type='switch'
            checked
          />
        </div>
        <div>
          <Toggle type='switch' />
        </div>

        <h5>Type: custom</h5>
        <div>
          <Toggle icons={icons}
            checked
          />
          <Toggle icons={icons} />
        </div>
      </div>
    );
  }

  click(value) {
    return isClicked => {
      if(isClicked)
        this.setState({value});
      else
        this.setState({value: ''});
    };
  }
}

Type: radio
Type: checkbox
Type: switch
Type: custom

Wrapper

This is a component for using server side rendering with radium. It can alos render react-redux and react-router-dom. Use this component as the root component.

Props

  • modules [object]

    Add the modules here. If you install other packages, you must add packages here because this Wrapper does not include those modules. The reason why this component does not include those modules is that the not using modules will not be added in javascript.

  • redux [object]

    You can give reducer(required), preloadedState and enhancer. This is used like createStore in redux. Howerver, if you need to use multiple middlewares in enhancer, you need to use an array of the middlewares.

    You need to install redux, react-redux and include in modules.

  • router [object]

    You can give isServer to choose StaticRouter or BrowserRouter. When isServer is true. you need to give an object like {location: '/', context: {}}.

    You need to install react-router-dom and include in modules.

Example

// Example.js
'use strict';

import React from 'react';
import * as redux fomr 'redux';
import * as reactRedux from 'react-redux';
import * as reactRouterDom from 'react-router-dom';
import Wrapper from 'cat-components/lib/Wrapper';

class Example extends React.Component {
  render() {
    return (
      <div>example</div>
    );
  }
}

// just add the modules which you use in modules.
export default (props) => (
  <Wrapper {...props}
    modules={{
      redux,
      reactRedux,
      reactRouterDom
    }}
  >
    <Example />
  </Wrapper>
);


// # normal
// client
ReactDOM.render(
  <Example />,
  document.getElementById('root')
);
// server
renderToStaticMarkup(
  <Example radiumConfig={{userAgent: ctx.request.headers['user-agent']}}
  />
);


// # redux
import {combineReducers} from 'redux';
import {createLogger} from 'redux-logger';

import Example from './Example';
import reducer from './reducer';

const reducer = combineReducers({form});
const enhancer = createLogger({collapsed: true});

// client
ReactDOM.render(
  <Example redux={{reducer, enhancer}}/>,
  document.getElementById('root')
);
// server
renderToStaticMarkup(
  <Example radiumConfig={{userAgent: ctx.request.headers['user-agent']}}
    redux={{reducer, enhancer}}
  />
);


// # router
// client
ReactDOM.render(
  <Example router={{isServer: false}} />,
  document.getElementById('root')
);
// server
cosnt context = {};

renderToStaticMarkup(
  <Example radiumConfig={{userAgent: ctx.request.headers['user-agent']}}
    router={{
      isServer: true,
      location={ctx.request.url}
      context={context}
    }}
  />
);

VideoSubtitle

Other packages

Props

  • subtitle [object, required]

    This is the subtitle of the video.

    • hour [number]

    • minute [number]

    • second [number]

    • millisecond [number]

    • content(now) [func, required]

      This function should return a react component.

      • now [boolean]

        If this content should be shown, this will be true.

  • now [object, required]

    • hour [number]
    • minute [number]
    • second [number]

Example

'use strict';

import React from 'react';
import radium from 'radium';
import moment from 'moment';
import VideoSubtitle from 'cat-components/lib/video-subtitle';

import * as style from './style/useVideoSubtitle';

const subtitle = [{
  minute: 11,
  second: 22
}, {
  minute: 10,
  second: 55
}, {
  minute: 11,
  second: 44
}, {
  hour: 1
}].map(({hour, minute, second}) => ({
  hour,
  minute,
  second,
  content: now => (
    <div style={now ? style.now : {}}>
      {moment({
        hour,
        minute,
        second
      }).format('HH : mm : ss')}
    </div>
  )
}));

@radium
export default class UseVideoSubtitle extends React.Component {
  render() {
    return (
      <VideoSubtitle subtitle={subtitle}
        now={{
          minute: 11,
          second: 30
        }}
      />
    );
  }
}

00 : 10 : 55
00 : 11 : 22
00 : 11 : 44
01 : 00 : 00

checkAPI

Use to check if some api library can be used like FB, gapi.

Arguments

  • name [string, required]

    Use to identify api.

  • func() [func, required]

    This must be a function which will return the global variable. For example, it will be like () => FB

  • getData(callback) [func, default: callback => callback({})]

    This will be called when this library can be used.

    • callback() [func]

      If you want to add some data as props, you can give the data to callback. Here is the example:

      @checkAPI('FB', () => FB,
        callback => {
          FB.login(response => {
            callback(response);
          });
        }
      )
      class ...
      
  • defaultData [object, default: {}]

    This will be added to props in order to avoid the error with propTypes when you use callback in getData.

Props

  • [name]CanUse [bool]

    Show if this library can be used.

Example

'use strict';

import React from 'react';
import PropTypes from 'prop-types';
import checkAPI from 'cat-components/lib/checkAPI';

@checkAPI('FB', () => FB)
export default class UsecheckAPI extends React.Component {
  static propTypes = {
    FBCanUse: PropTypes.bool.isRequired
  }

  render() {
    const {FBCanUse} = this.props;

    return (
      <div>
        {
          FBCanUse ?
            'Can use "FB.api".' :
            'Can not use "FB.api".'
        }
      </div>
    );
  }
}

Can not use "FB.api".

goToAnimation

Use to scroll main DOM to target DOM or top of window.

Other packages

Arguments

  • main [string, required]

    This is main DOM which is controlled. This is used to querySelector to find the DOM. As a result, you can use like #main.

  • options [object, default = {sec: 2, fps: 60, animation: 'quartInOut'}]

    You can add sec, fps and animation. sec is the duration of this animation. fps is the fps of this animation. animation can be a name of eases or a function.

Props

  • goTo(target) [func]

    This is the function to srcoll the main DOM.

    • target [string, required]

      This is alse used to querySelector to find the target DOM. If target is not set, this function will scroll to the top of the main DOM.

Example

'use strict';

import React from 'react';
import PropTypes from 'prop-types';
import radium from 'radium';
import Button from 'cat-components/lib/button';
import goToAnimation from 'cat-components/lib/goToAnimation';

@radium
@goToAnimation('#body')
export default class UseGoTo extends React.Component {
  static propTypes = {
    goTo: PropTypes.func.isRequired
  }

  render() {
    const {goTo} = this.props;

    return (
      <div>
        <Button onClick={() => goTo()}>Go Top</Button>
        <Button onClick={() => goTo('#Input')}>Go To Input</Button>
      </div>
    );
  }
}

timer

Other packages

Arguments

  • fps [int, default: 120]

    Use to set the fps of the timer.

Props

  • isRunning [bool]

    Show if the timer is running.

  • timer [object]

    This is the data of the timer.

    • hours [int]
    • minutes [int]
    • seconds [int]
    • milliseconds [int]
  • timerStart(timer) [func]

    Run the timer.

    • time [moment, default: moment()]

      This is the start of the timer.

  • timerStop() [func]

    Stop the timer.

  • timerReset() [func]

    Reset the timer.

Example

'use strict';

import React from 'react';
import PropTypes from 'prop-types';
import radium from 'radium';
import timer from 'cat-components/lib/timer';
import Button from 'cat-components/lib/button';

@radium
@timer()
export default class UseTimer extends React.Component {
  static propTypes = {
    timer: PropTypes.object.isRequired,
    timerStart: PropTypes.func.isRequired,
    timerStop: PropTypes.func.isRequired,
    timerReset: PropTypes.func.isRequired
  }

  render() {
    const {timer, timerStart, timerStop, timerReset} = this.props;
    const {hours, minutes, seconds, milliseconds} = timer;

    return (
      <div>
        <div>
          <Button onClick={() => timerStart()}>start</Button>
          <Button onClick={() => timerStop()}>stop</Button>
          <Button onClick={() => timerReset()}>reset</Button>
        </div>

        {`${hours} hr ${minutes} min ${seconds} sec ${milliseconds} ms`}
      </div>
    );
  }
}

0 hr 0 min 0 sec 0 ms