AWS NorthstarでAWSっぽいReactアプリを作ってみる
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;
BrowserRouter
とNorthStarThemeProvider
の順番に指定はない様子で、逆にしても問題なく頁遷移などができることを確認しています。
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;
ここまでのコードでできたレイアウトがこちらです。
かなりそれっぽいのではないでしょうか。
サイドバーが畳めるところも実装済みです。
ヘルプバーを表示する
AppLayout
のhelpPanel
を使うことで、右側に出てくるパネルも作れます。
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>
)
なんとなく「ありそうな感じ」がでてきていませんか?
KeyValuePair
やStatusIndicator
が管理画面系で地味にありがたい要素だなぁと感じます。
スタイルのカスタマイズは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
でセットアップするのが無難そうです。
Discussion