Mantine 入門1 セットアップとリンクの貼り方、テーマの概要
ゴールはNextjsをフレームワークとして、Mantineを使ってブログサイトをつくることです。
ただし、Mantineに焦点を当てるため、寄り道をいっぱいしようと思っております。
インストール
公式ページの初っ端にフレームワークを選択させるところがありますので、Nextjsをクリックします。typescript前提なので、下記で新しいプロジェクトを作って移動しておきます。
npx create-next-app@latest --ts mantine-sample
cd mantine-sample
そうすると、必要なパッケージを選択させる画面がありますので、今回は全部入りにします。
あとは画面に出てきたコマンドをコピペしてターミナルに貼り付け実行します。
npm install @mantine/core @mantine/hooks @mantine/form @mantine/dates dayjs @mantine/notifications @mantine/prism @mantine/rte @mantine/dropzone @mantine/carousel embla-carousel-react @mantine/spotlight @mantine/modals @mantine/nprogress @mantine/next @emotion/server @emotion/react
次に、pageフォルダに_document.tsxを生成します。また、最初からある_app.tsxを編集します。ざっくりいうと、_document.tsxはNextjsが生成するHTMLの構成をrendarに記載し、HTML生成時に最初に呼び出す初期化処理をその上に記載します。_app.tsxは、ユーザがコンポーネントを作成していくわけですが、全てのコンポーネントに記載される内容を書いておくと、_app.tsxは全てのコンポーネントの上からラップしてくれます。たとえば使用するUIのimportを全コンポーネントで実行するのは大変なので、_app.tsxに記載したりします。
公式ページに従い、_document.tsxは下記を貼り付けます。
import { createGetInitialProps } from '@mantine/next';
import Document, { Head, Html, Main, NextScript } from 'next/document';
const getInitialProps = createGetInitialProps();
export default class _Document extends Document {
static getInitialProps = getInitialProps;
render() {
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
_app .tsxは下記で上書きします。
import { AppProps } from 'next/app';
import Head from 'next/head';
import { MantineProvider } from '@mantine/core';
export default function App(props: AppProps) {
const { Component, pageProps } = props;
return (
<>
<Head>
<title>Page title</title>
<meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width" />
</Head>
<MantineProvider
withGlobalStyles
withNormalizeCSS
theme={{
/** Put your mantine theme override here */
colorScheme: 'light',
}}
>
<Component {...pageProps} />
</MantineProvider>
</>
);
}
この状態で npm run dev すると、http://localhost:3000/にいつもの画面が出てきます。
リンクの貼り方
今、下記のページを作成し、ページ間でリンクを貼るとします。
// pages/index.tsx
import type { NextPage } from 'next'
import Head from 'next/head'
const Home: NextPage = () => {
return (
<>
<Head><title>Home</title></Head>
<p>ホームのページ</p>
</>
)
}
export default Home
// pages/page1.tsx
import type { NextPage } from 'next'
import Head from 'next/head'
const Page1: NextPage = () => {
return (
<>
<Head><title>Page1</title></Head>
<p>Page1のページ</p>
</>
)
}
export default Page1
Mantineが提供するButton, ActionIcon, Anchorなどの要素でnextjsのLINKを使う場合は下記のようにします。
・要素のcomponentパラメータに”a”を設定
・その要素を<Link>で囲う
// pages/index.tsx
import { Button } from '@mantine/core'
import type { NextPage } from 'next'
import Head from 'next/head'
import Link from 'next/link'
const Home: NextPage = () => {
return (
<>
<Head><title>Home</title></Head>
<p>ホームのページ</p>
<Link href="/page1">
<Button component="a">page1へ移動</Button>
</Link>
</>
)
}
export default Home
マウスホバーなどでアクションするTooltipコンポーネントを使っていると、上記のやり方ではエラーが出ますので、下記のようにNextLinkを使います。
// pages/page1.tsx
import { Button } from '@mantine/core'
import { NextLink } from '@mantine/next'
import type { NextPage } from 'next'
import Head from 'next/head'
const Page1: NextPage = () => {
return (
<>
<Head><title>Page1</title></Head>
<p>Page1のページ</p>
<Button component={NextLink} href="/">ホームへ</Button>
</>
)
}
export default Page1
テーマ設定の概要
裏で動いているテーマオブジェクトがあります。これは色やフォント、ボックシャドウなど様々な設定をプロパティとして持っています。テーマを設定するためには、MantineProviderを使ってテーマオブジェクトを一部上書きして利用できます。
先ほどのindex.tsx,page1.tsxに、下記のコンポーネントを追加します。
pagesの下に作らないように注意してください。
// components/somepart.tsx
import { Container, Grid } from '@mantine/core';
import { Radio,Text,Button } from '@mantine/core';
export type SomePartProps = {
label:string;
name: string;
}
const SomePart:React.FC<SomePartProps> = ({label,name}) =>{
return(
<Container>
<Grid>
<Grid.Col span={4}>
<Radio label={label} value="false"/>
</Grid.Col>
<Grid.Col span={4}>
<Text>Font</Text>
</Grid.Col>
<Grid.Col span={4}>
<Button variant="gradient">{name}</Button>
</Grid.Col>
</Grid>
</Container>
)
}
export default SomePart
index.tsxは単に上記を読み込みます。
// pages/index.tsx
import { Button } from '@mantine/core'
import type { NextPage } from 'next'
import Head from 'next/head'
import Link from 'next/link'
import SomePart from '../components/somepart'
const Home: NextPage = () => {
return (
<>
<Head><title>Home</title></Head>
<p>ホームのページ</p>
<Link href="/page1">
<Button>page1へ移動</Button>
</Link>
<SomePart label="hello" name='default'/>
</>
)
}
export default Home
page1.tsxでは、MantineProviderにより、一部テーマオブジェクトを上書きします。フォントをRobotoに、ボタンの配色プロパティのGradientをオレンジ系統にしています。
// pages/page1.tsx
import { Button } from '@mantine/core'
import { NextLink } from '@mantine/next'
import type { NextPage } from 'next'
import Head from 'next/head'
import SomePart from '../components/somepart'
import { MantineProvider } from '@mantine/core';
const Page1theme = {
fontFamily: 'Roboto',
defaultGradient: {
from: 'orange',
to: 'red',
deg: 45,
},
}
const Page1: NextPage = () => {
return (
<>
<Head><title>Page1</title></Head>
<p>Page1のページ</p>
<Button component={NextLink} href="/">ホームへ</Button>
<MantineProvider theme={Page1theme}>
<SomePart label="hello" name='type'/>
</MantineProvider>
</>
)
}
export default Page1
全てのMantineコンポーネントはライトモードとダークモードをサポートします。ダークモードは下記のように{colorScheme: 'dark'}を設定するだけです。
// pages/page1.tsx
import { Button } from '@mantine/core'
import { NextLink } from '@mantine/next'
import type { NextPage } from 'next'
import Head from 'next/head'
import SomePart from '../components/somepart'
import { MantineProvider } from '@mantine/core';
const Page1: NextPage = () => {
return (
<>
<Head><title>Page1</title></Head>
<p>Page1のページ</p>
<Button component={NextLink} href="/">ホームへ</Button>
<MantineProvider theme={{colorScheme: 'dark'} }>
<SomePart label="hello" name='darkmode'/>
</MantineProvider>
</>
)
}
export default Page1