AWS NorthstarでAWSっぽいReactアプリを作ってみる

6 min read読了の目安(約5800字

AWSが突如としてリリースしたOSSが「AWS Northstar」です。

Aboutをざっと読む限り、「社内でのプロトタイピングなどを目的に作られたデザインシステム兼FWをオープンにしました」というところかなという感じですね。

せっかくなので触ってみます。

セットアップ

実際の実装ではTypeScriptを使っていますが、説明が面倒なのでこちらでは省きます。

$ npx create-react-app northstar
$ cd northstar
$ yarn add aws-northstar react-router react-router-dom 

Providerの設定

Material UIなどと同じくTheme Providerを利用する必要があります。

import React from 'react'
import { BrowserRouter } from 'react-router-dom';
import NorthStarThemeProvider from 'aws-northstar/components/NorthStarThemeProvider';


function App() {
  return (
    <BrowserRouter>
      <NorthStarThemeProvider>
        <h1>hello world</h1>
      </NorthStarThemeProvider>
    </BrowserRouter>
  );
}

export default App;

BrowserRouterNorthStarThemeProviderの順番に指定はない様子で、逆にしても問題なく頁遷移などができることを確認しています。

AWSっぽいレイアウトを作る

準備ができましたので、早速それっぽいレイアウトを作ります。
必要な要素はほぼ間違いなくComponent化されていますので、ドキュメントをみながら必要なものを探すと良いでしょう。

import React from 'react'
import { BrowserRouter } from 'react-router-dom';
import NorthStarThemeProvider from 'aws-northstar/components/NorthStarThemeProvider';
import AppLayout from 'aws-northstar/layouts/AppLayout';
import Header from 'aws-northstar/components/Header';
import SideNavigation, { SideNavigationItemType } from 'aws-northstar/components/SideNavigation';

function App() {

  return (
    <BrowserRouter>
      <NorthStarThemeProvider>
        <AppLayout
            header={<Header title="Hello Northstar" />}
            navigation={(
              <SideNavigation
                header={{
                  href: "/",
                  text: 'App Home'
                }}
                items={[{
                  type: SideNavigationItemType.LINK,
                  text: 'Item 1',
                  href: "/page1"
                }, {
                  type: SideNavigationItemType.LINK,
                  text: 'Item 2',
                  href: "/page2"
                }, {
                  type: SideNavigationItemType.DIVIDER,
                }, {
                  type: SideNavigationItemType.LINK,
                  text: 'Item 10',
                  href: "/page10"
                }]}
              />
            )}
        >
          <h1>Hello</h1>
        </AppLayout>
      </NorthStarThemeProvider>
    </BrowserRouter>
  );
}

export default App;

ここまでのコードでできたレイアウトがこちらです。
かなりそれっぽいのではないでしょうか。

サイドバーが畳めるところも実装済みです。

ヘルプバーを表示する

AppLayouthelpPanelを使うことで、右側に出てくるパネルも作れます。


import HelpPanel from 'aws-northstar/components/HelpPanel';
import Link from 'aws-northstar/components/Link';
import Text from 'aws-northstar/components/Text';
import Heading from 'aws-northstar/components/Heading';

const HelpPanelContent =  () => (
  <HelpPanel
    header="Help panel"
    learnMoreFooter={[
      <Link href="/item1">Link to internal</Link>,
      <Link href="https://zenn.dev">Go to external</Link>
    ]}
  >
    <Heading variant="h2">Header</Heading>
    <Text variant="p">
      This is paragraph text
    </Text>
    <Heading variant="h5">Header</Heading>
    <Text variant="p">
      This is paragraph
      {' '}
      <Text variant="small">
        small
      </Text>
      {' '}
      text
    </Text>
  </HelpPanel>
)

AWSっぽいコンテンツを追加する

最後にそれっぽい中身も1つ追加してみます。

AppLayoutの子要素として配置しましょう。

import { Column, ColumnLayout, Container, KeyValuePair, Stack, StatusIndicator } from 'aws-northstar';
const Content = () => (
          <Container headingVariant="h4" title="Column container">
            <ColumnLayout>
                <Column key="col1">
                  <Stack>
                    <KeyValuePair label="Site id" value="xxx-xxx-xxx" />
                    <KeyValuePair label="Owner" value="John doe" />
                  </Stack>
                </Column>
                <Column key="col2">
                  <Stack>
                    <KeyValuePair label="Created at" value={new Date().toLocaleDateString()} />
                    <KeyValuePair label="Status" value={<StatusIndicator statusType="positive">Running</StatusIndicator>} />
                  </Stack>
                </Column>
            </ColumnLayout>
          </Container>
)

なんとなく「ありそうな感じ」がでてきていませんか?
KeyValuePairStatusIndicatorが管理画面系で地味にありがたい要素だなぁと感じます。

スタイルのカスタマイズはMaterial UI準拠

AWS NorthstarはMaterial UIを拡張して作られています。
NorthStarThemeProviderの型を見ようとしたら、思いっきりThemeOptionsをMaterial UIからimportしていました。

なので以下のようにcreateMuiThemeに渡す値をうまく上書きしてやれば、自社サービスっぽいけどAWSみたいな使い勝手のUIが作れそうです。

import { createMuiTheme } from '@material-ui/core/styles';
import { getTheme } from 'aws-northstar/themes/default';

const theme = createMuiTheme({
  ...getTheme(),
  palette: {
    primary: {
      light: '#757ce8',
      main: '#3f50b5',
      dark: '#002884',
      contrastText: '#fff',
    },
    secondary: {
      light: '#ff7961',
      main: '#f44336',
      dark: '#ba000d',
      contrastText: '#000',
    },
  },
})

function App() {
  return (
    <NorthStarThemeProvider theme={theme}>

余談: Next.js / Gatsbyで動かすにはちょっと苦労しそう

内部でreact-routerを使っているらしく、それ以外のRouterを使っているアプリに入れると事故ります。

Next.jsやGatsbyなどは独自またはreact-router以外のRouterを利用していますので、create-react-appでセットアップするのが無難そうです。