🍳
【Panda CSS】Atomic Recipe記法を使ってVueコンポーネントを実装する
はじめに
前回の記事ではcss()
を利用しましたが例的にはcva()
でもいけそうでした。前回記事は下記によりご覧ください。
本記事では Atomic Recipe 記法を利用して Vue コンポーネントを実装してみます。
Panda CSS の Atomic Recipe とは
Atomic Recipe はClass Variance Authorityにインスパイアされた実装方法です。
実際に使ってみる
共通スキーマ
/schemas/stickyNote.ts
import { z } from "zod";
export const stickyNoteSchema = z.enum(["alert", "warning", "success", "info"]);
export const dummyStickyNotes: z.infer<typeof stickyNoteSchema>[] = [
"alert",
"warning",
"success",
"info",
];
コンポーネント(/components)
/components/stickyNote.vue
<script setup lang="ts">
import { cva } from "styled-system/css";
import { stickyNoteSchema } from "@/schemas/stickyNote";
const { color } = defineProps<{
color: z.infer<typeof stickyNoteSchema>;
}>();
const stickyNoteRecipe = cva({
/** 共通スタイル */
base: {
width: "200px",
height: "200px",
textDecoration: "none",
padding: "0.5rem",
boxShadow: "5px 5px 5px rgba(0, 0, 0, 0.22)",
zIndex: 5,
},
/** 可変させるスタイル */
variants: {
color: {
alert: {
color: "red.500",
bgColor: "red.100",
},
warning: {
color: "yellow.500",
bgColor: "yellow.100",
},
success: {
color: "green.500",
bgColor: "green.100",
},
info: {
color: "sky.500",
bgColor: "sky.100",
},
},
},
});
</script>
<template>
<div :class="stickyNoteRecipe({ color })">
<slot></slot>
</div>
</template>
呼び出し元(/pages)
/pages/index.vue
<script setup lang="ts">
import { grid } from "styled-system/patterns/grid";
import { stickyNoteSchema, dummyStickyNotes } from "@/schemas/stickyNote";
</script>
<template>
<div :class="grid({ columns: '4', gap: '1' })">
<!-- NOTE: Nuxt3のAuto-imports利用 -->
<StickyNote v-for="sn in dummyStickyNotes" :key="sn" :color="sn">
This is {{ sn }} sticky note.
</StickyNote>
</div>
</template>
表示結果
npm run dev
コマンドを実行し表示した結果は以下の通りです。grid()
もきちんと効いています。
おわりに
今回はcva()
(defineRecipe
)を利用しましたが、より複雑になる場合はsva()
(defineSlotRecipe
)を利用した方が便利です。
Panda CSS は今回紹介したcva()
、前回紹介したcss()
、今回紹介していないsva()
など、様々な形で実装できます。
実装者に合った形で実装できるのはありがたい限りです。
Discussion