CSS弱者なので、tailwindだけで画面を作るのは厳しいです。React コンポーネントライブラリのMantineを使って画面を作成します。
https://mantine.dev/
Mantineを使うのはudemyでちょうど講座がセールしてたというだけの理由です。
https://www.udemy.com/course/mantine-react-complete-guide-nextjs/
内容は非常にわかりやすくで実践的だったのでお勧めです。
ただし、udemyは普段の値段と、セールの値段が違いすぎるのでセールを待つのがめんどくさいですが。
mantineを追加
npm install @mantine/core @mantine/hooks @mantine/form @mantine/next tabler-icons-react
mantineの設定
https://mantine.dev/guides/next/
を参考に、src/pages/_app.tsxにMantineの設定を追加します。
return (
<SessionProvider session={session}>
+ <MantineProvider
+ withGlobalStyles
+ withNormalizeCSS
+ theme={{ colorScheme: "dark" }}
+ >
<Component {...pageProps} />
+ </MantineProvider>
</SessionProvider>
);
};
Layoutを作成
src/components/Layout.tsxを作成します
https://github.com/GomaGoma676/mantine-lesson/blob/main/components/Layout.tsx
udemy
からコピペしただけです。
import Head from "next/head";
import type { FC, ReactNode } from "react";
type Props = {
title: string;
children: ReactNode;
};
export const Layout: FC<Props> = ({ children, title = "T3 Todo Example" }) => {
return (
<div>
<Head>
<title>{title}</title>
</Head>
<header></header>
<main className="flex flex-1 flex-col items-center justify-center p-4">
{children}
</main>
<footer></footer>
</div>
);
};
Webアプリの開発していたころはまだflexは使えなかったため
https://www.webcreatorbox.com/tech/css-flexbox-cheat-sheet
のチートシートを見て勉強しました。
flex-colが子要素を上から下に配置する指定。
flex-1クラスを使用すると、初期サイズを無視して、必要に応じてフレックスアイテムを拡大および縮小する指定。
justify-centerが主軸(flex-colなら縦)方向で中央に配置
items-centerがクロス軸(flex-colなら縦)方向で中央に配置
だそうです。
Todo画面を更新
import { ActionIcon, Card, Group, Text } from "@mantine/core";
import { type NextPage } from "next";
import { Trash } from "tabler-icons-react";
import { Layout } from "../components/Layout";
import { trpc } from "../utils/trpc";
const Todo: NextPage = () => {
const todos = trpc.todo.getAll.useQuery();
const utils = trpc.useContext();
const deleteTodo = trpc.todo.delete.useMutation({
onSettled: () => {
utils.todo.getAll.invalidate();
},
});
return (
<Layout title="Todo">
<h1 className="">Todo</h1>
<div>
{todos.data?.map((todo) => (
<Card withBorder key={todo.id} mt={"sm"}>
<Group position={"apart"}>
<Text>{todo.name}</Text>
<ActionIcon
onClick={() => {
deleteTodo.mutate({ id: todo.id });
}}
color={"red"}
variant={"transparent"}
>
<Trash />
</ActionIcon>
</Group>
</Card>
))}
</div>
</Layout>
);
};
export default Todo;
Groupは要素を縦に並べるFlex Boxで、position={"apart"}を指定すると、要素同士ができるだけ離れるように配置します。
今回の変更は以下の通りです。