Material-UI v1.0をTypeScriptで使うを試す


以下で解説頂いている件を試しました。（スペシャルサンクス）
[Material-UI v1.0をTypeScriptで使う - Qiita](https://qiita.com/gcoka/items/5ac6716a5e92b2aa506d)


[Material-UI](https://material-ui.com/)本家ページ

今回のソースは以下に起きました。
[sugasaki/mui-ts-sample](https://github.com/sugasaki/mui-ts-sample)


## 環境
・Visual Studio Code
・TSLint


## create-react-app

create-react-appは導入済みという前提で進みます。
未導入の場合はGetting Startに添って導入を
[material-ui/Button.d.ts at master · mui-org/material-ui](https://github.com/mui-org/material-ui/blob/master/packages/material-ui/src/Button/Button.d.ts)

create-react-appコマンドでプロジェクトの雛形を作成します。

```
# create-react-app-typescriptを使ってreactテンプレートを作成
create-react-app mui-ts-sample --scripts-version=react-scripts-ts

cd mui-ts-sample

# 動作確認
yarn start
```

## Material-UIのインストール

公式ページではnpm で説明があったのでnpm で進めました。
[Installation - Material-UI](https://material-ui.com/getting-started/installation/)

```
# material-uiインストール
npm install @material-ui/core
# SVGアイコンもインストール
npm install @material-ui/icons
```



## Material-UIを使う

[Material-UI v1.0をTypeScriptで使う - Qiita](https://qiita.com/gcoka/items/5ac6716a5e92b2aa506d)のサンプルコードを使うに添って進めましたが私の環境が悪いのかうまく動作させる事ができなかったので、ファイルを分割しながら進めました。

## 手順
* componentsフォルダ作成
* components/FlatButtonsSample.tsx 作成
* components/RaisedButtonsSample.tsx 作成
* components/Styles.tsx 作成
* App.tsx変更


## 手順

結果だけ列挙していきます。
TSLingに怒られたのでimportの順番等は変更しています。

### FlatButtonsSample.tsx 作成

```js:FlatButtonsSample.tsx

import { WithStyles, withStyles } from '@material-ui/core/styles';
import DeleteIcon from 'material-ui-icons/Delete';
import Button from 'material-ui/Button';
import * as React from 'react';
import { ClassNames, styles } from './Styles';


interface IFlatButtonsProps {
    onClick: () => void;
}

// Stateless Function Componentsの場合
const FlatButtonsSample = withStyles(styles)<IFlatButtonsProps>(
    (props: IFlatButtonsProps & WithStyles<ClassNames>) => {
        const classes = props.classes;
        return (
            <div className={classes.box}>
                {/* クリックイベントの処理はこんな感じ */}
                <Button onClick={props.onClick} className={classes.button}>Default</Button>
                <Button color="primary" className={classes.buttonWithHover}>Primary</Button>
                <Button color="secondary"><DeleteIcon />削除</Button>
            </div>
        );
    }
);


export default FlatButtonsSample;

```


### RaisedButtonsSample.tsx 作成

```js:RaisedButtonsSample.tsx
import { WithStyles, withStyles } from '@material-ui/core/styles';
import DeleteIcon from 'material-ui-icons/Delete';
import Button from 'material-ui/Button';
import * as React from 'react';
import { ClassNames, styles } from './Styles';


interface IRaisedButtonsProps {
    onClick: () => void;
}

// Componentクラスの場合
class RaisedButtonsSample extends React.Component<IRaisedButtonsProps & WithStyles<ClassNames>, {}> {
    public render() {
        const classes = this.props.classes;
        return (
            <div className={classes.box}>
                <Button onClick={this.props.onClick} className={classes.buttonWithHover}>Default</Button>
                <Button color="primary" className={classes.button}>Primary</Button>
                <Button color="secondary" className={classes.button}><DeleteIcon />削除</Button>
            </div>
        );
    }
}


// withStylesに型注釈が必要な場合は、以下のようにする
export default withStyles<{} & ClassNames>(styles)<IRaisedButtonsProps>(RaisedButtonsSample);


```

### Styles.tsx 作成


```js:Styles.tsx


export const styles = {
    box: {
        border: 'solid 1px gray',
        margin: 10,
        padding: 10,
    },
    button: {
        margin: 10,
    },
    buttonWithHover: {
        // hoverも記述できる
        '&:hover': {
            backgroundColor: '#ff0000',
        },
        margin: 10,
    },
};


export type ClassNames = keyof typeof styles;



```


### App.tsx
```js:App.tsx
import * as React from 'react';
import FlatButtonsSample from './components/FlatButtonsSample';
import RaisedButtonsSample from './components/RaisedButtonsSample';

class App extends React.Component {
  public handleClick = () => {
    alert('Clicked!');
  }

  public render() {
    return (
      <div>
        <RaisedButtonsSample onClick={this.handleClick} />
        <FlatButtonsSample onClick={this.handleClick} />
      </div>
    );
  }
}

export default App;
```


## 結果

以下のような感じで動作しました。

![image](https://qiita-image-store.s3.amazonaws.com/0/49910/b15c8d0b-31e0-08bb-00f7-b70f28e25961.png)

IE11でも動作しました。
![image](https://qiita-image-store.s3.amazonaws.com/0/49910/069ae214-87dc-024e-4839-c702af175dbb.png)