Diary

@ssig33

16 Jan 2019 Wed 18:36

material-ui でカレンダーな UI を作る

こんにちは、金をよこせ死ね。こういう素晴しい書き出しでアメブロを書いている異常者がいたんですがとっくの昔に消えました。アプリ開発をやっているとカレンダーっぽい UI が必要になることはそれなりにあるかと思います。従来 Web だとそういうの非常にだるかったものですが、 material-ui という React Component 集だとそれが簡単にできます。

material-ui 。それにしても酷い名前ですね、何様のつもりなのか。 material-ui にはいわゆる Grid システムをやっていくための Grid という機能があるのですが、それとは別に GridList というコンポーネントをもっています。これはデモをみると

img

みたいな感じであきらかに汎用的なレイアウトを作ることは想定していないと思うのですが、実際 UI のレイアウトをこれで組むと話が早い。

img

こんな感じのカレンダーが以下のようなコードで実現できます。

const uuid = require('uuid');

const weekdays = ['Sun.', 'Mon.', 'Tue.', 'Wed.', 'Thu.', 'Fri.', 'Sat.'];
const cardStyle = { margin: 1 }

const Calendar = (props)=>{
  const begining = new Date(2019, 0, 1);

  const calendar = []
  Array.apply(null, {length: begining.getDay()}).map(Number.call, Number).forEach((e)=>{
    calendar.push(<GridListTile key={uuid()}><Card /></GridListTile>);
  });
  Array.apply(null, {length: 32}).map(Number.call, Number).forEach((i)=>{
    const day = new Date(begining.getFullYear(), begining.getMonth(), 1+i);
    if(day.getMonth() === begining.getMonth()){
      calendar.push(
        <GridListTile>
          <Card style={cardStyle}><CardContent><Typography>{day.toLocaleDateString()}</Typography></CardContent></Card>
        </GridListTile>
      );
    }
  });

  return <Paper>
    <GridList cols={7} cellHeight='auto'>
      {
        weekdays.map((w)=>{
          const styles = {};
          if(w == 'Sun.'){styles.color = 'red'}
          if(w == 'Sat.'){styles.color = 'blue'}
          return <GridListTile key={w}>
            <Card style={cardStyle}>
              <CardContent><Typography style={styles}>{w}</Typography></CardContent>
            </Card>
          </GridListTile>
        })
      }
      {calendar}
    </GridList>
  </Paper>
}

記述短くしようとしたらかえって分かりづらくなった気しますね。まあいいや。なんかそれっぽい感じでいろいろ一瞬で書けるので material-ui いいと思う。名前が酷いが、、、