こんにちは。エンジニアの本山です。
現在開発中の「addcari」では、UIライブラリにMantineを使用して開発を行っています。
そこで自身のキャッチアップも兼ねて、コーポレートサイトを作ってみたいと思います!
ただし、今回だけでコーポレートサイト完成までを書いてしまうと、内容がとてつもない分量になってしまうので、
数回に分けて公開していこうと思います?
主な使用技術
- Mantine v5.5.5
- Next.js v12.2.4
- TypeScript v4.7.4
はじめに
さっそく作っていきたいのですが、コーポレートサイトのデザインが必要ですね。
デザインも作成となると、余計に時間がかかってしまうので、他社様のコーポレートサイトを参考にさせていただきます。
参考にさせていただくのは、和菓子屋 とらやさんのコーポレートサイトです。
シンプルでありながらも、とても上品さが伺えるコーポレートサイトだなと感じました。
なにより和菓子が繊細で美味しそう?
次に、どんな事業会社のコーポレートサイトにするかですが、自分はエンジニアになる前は建設業に携わっていたので、
建設会社のコーポレートサイトを作ってみようと思います。
Mantineとは
Mantineは、ReactのUIライブラリになります。多彩なコンポーネント、50種類以上のhooksを提供しています。
特徴
TypeScriptをサポート
TypeScriptとはJavaScriptの上位互換です。
静的型付のため、大規模案件でも採用されるようです。
addcariでもライブラリを導入する際は、TypeScriptをサポートしているか否かは必ず見るポイントです。
使いやすいhooksの提供
use-debounced-value,use-clipboardなど実装の際に役に立つhooksが多数提供されています。
個人的にuse-disclosureを、モーダルやポップオーバーの開閉によく使用します。
基本的なレイアウト用コンポーネント、トランジションを持つコンポーネントまで多様なコンポーネントが用意されている
Center,Spaceなどのレイアウト系、Text,Titleなどの表示系、Modal,Carouselトランジションを持つコンポーネントなど多様なコンポーネントが用意されています。
Next.js + TypeScript導入
まずはNext.jsを導入します。
私の過去記事でも触れているため、割愛させていただきます。
Mantine導入
Mantine公式ドキュメントを見ながら、パッケージを導入していきます。
core,hooks,carouselを入れます。
yarn add @mantine/core @mantine/hooks @mantine/carousel embla-carousel-react @mantine/next @emotion/server @emotion/react
pages直下に_document.tsxを作成します。
import { createGetInitialProps } from '@mantine/next'
import Document, { Head, Html, NextScript, Main } from 'next/document'
const getInitialProps = createGetInitialProps()
export default class _Document extends Document {
static getInitialProps = getInitialProps
render() {
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
pages直下に_app.tsxを作成します。
import { AppProps } from 'next/app'
import { MantineProvider } from '@mantine/core'
import Head from 'next/head'
const App = ({ Component, pageProps }: AppProps) => {
return (
<>
<Head>
<title>コーポレートサイト</title>
<meta name='viewport' content='minimum-scale=1, initial-scale=1, width=device-width' />
</Head>
<MantineProvider
withGlobalStyles
withNormalizeCSS
theme={{
colorScheme: 'light',
}}
>
<Component {...pageProps} />
</MantineProvider>
</>
)
}
export default App
これでNext.jsで、Mantineのコンポーネント等を扱えます。
スライダーの実装
とらやさんのトップページのようなスライダーを実装します。
Mantineでは、フェードアウト的なスライドアニメーションでは無く、単にスライドしていくスライドアニメーションになります。
まずは、自動スライドを実現するために、ライブラリを導入します。
yarn add embla-carousel-autoplay
MantineのCarouselは、embla-carousel に依存します。
ですので、autoplay、scale等行いたい場合は、プラグインを追加します。
プラグインを追加したので、次にスライダーコンポーネントを作成していきます。
src/components/BackgroundimageSlider.tsx
import { Carousel, CarouselProps } from '@mantine/carousel'
import { AspectRatio, BackgroundImage, Box, Image } from '@mantine/core'
import Autoplay, { AutoplayOptionsType } from 'embla-carousel-autoplay'
import { useMemo, useRef } from 'react'
type BackgroundImageSliderProps = {
isControls?: CarouselProps['withControls']
isAutoPlay?: boolean
delay?: AutoplayOptionsType['delay']
images: string[]
}
export const BackgroundImageSlider = ({
isControls = false,
isAutoPlay = true,
delay = 5000,
images,
}: BackgroundImageSliderProps) => {
const autoplay = useRef(Autoplay({ delay }))
const plugins = useMemo(() => {
return [isAutoPlay && autoplay.current]
}, [])
return (
<Carousel withControls={isControls} plugins={plugins}>
{images.map((src, index) => (
<Carousel.Slide key={`BackgroundImageSlider-${index}`}>
<BackgroundImage
src={src}
sx={{ backgroundSize: 'cover', paddingTop: 'min(100vh, 75%)' }}
/>
</Carousel.Slide>
))}
</Carousel>
)
}
コンポーネントのprops typeを説明していきます。
images以外はオプショナルにして、コンポーネント側で指定するしないを決めれるようにしております。
(imagesは割愛します)
isControls
CarouselPropsのwithControlsになっております。
右左ボタンを表示・非表示を設定します。
デフォルトでfalseを設定しております。
isAutoPlay
自動スクロールを行うか行わないかを設定します。
memo化をしており、trueだった場合は、autoplayプラグインを使用するようにしております。
デフォルトでtrueを設定しております。
delay
スライド遷移間の時間を設定します。
デフォルトで5000ミリ秒を設定しております。
今回は画面いっぱいに画像を表示して、スライドさせていきたいので、
BackgroundImageコンポーネントを使用しています。
<BackgroundImage
src={src}
sx={{ backgroundSize: 'cover', paddingTop: 'min(100vh, 75%)' }}
/>
pathpida導入
静的画像ファイルを使用するため、内部パスを型安全に取得したいですよね。
そんなときに便利なpathpidaというライブラリを導入します。
yarn add pathpida npm-run-all --dev
実行後、package.jsonを編集します。
今回public/images配下の画像パスを、型安全に取得したいので、
下記のように編集します。
"dev": "run-p dev:*", "dev:next": "next dev", "dev:path": "pathpida --enableStatic --watch", "build": "pathpida --enableStatic && next build"
そして、yarn devを実行すると、src/lib/$path.tsが自動生成されます。
src/lib/$path.ts
export const pagesPath = {
$url: (url?: { hash?: string }) => ({ pathname: '/' as const, hash: url?.hash }),
}
export type PagesPath = typeof pagesPath
export const staticPath = {
image: {
image_slider_1_jpg: '/image/image_slider_1.jpg',
image_slider_2_jpg: '/image/image_slider_2.jpg',
image_slider_3_jpg: '/image/image_slider_3.jpg',
image_slider_4_jpg: '/image/image_slider_4.jpg',
image_slider_5_jpg: '/image/image_slider_5.jpg',
},
} as const
export type StaticPath = typeof staticPath
スライダーの表示
スライダーを表示する準備は整ったので、src/pages/index.tsxを編集していきます。
src/pages/index.tsx
import { BackgroundImageSlider } from '@/components/ImageSlider'
import { staticPath } from '@/lib/$path'
const images = [
staticPath.image.image_slider_1_jpg,
staticPath.image.image_slider_2_jpg,
staticPath.image.image_slider_3_jpg,
staticPath.image.image_slider_4_jpg,
staticPath.image.image_slider_5_jpg,
]
const AppPage = () => {
return <BackgroundImageSlider images={images} />
}
export default AppPage
pathpidaを使用することで、
staticPath.{ディレクトリ名}.{ファイル名}のように、型安全にファイル取得ができます。
トップページスライダー

想定通り画像がスライドして表示されてますね!!
まとめ
今回は以上となります。
環境構築、Mantineの説明、pathpida、トップページのスライダー実装を行いました。
実際にMantineを使用してみて、とても使いやすいUIライブラリだなと再確認しました。
また、個人的にドキュメントが分かりやすいと感じており、開発者には感謝しかありません。
次回以降どんどん実装していき、コーポレートサイトの完成を目指していきます。
次回はヘッダー、フッターを実装していきます。
お楽しみに!!