Gambaran Umum
Resep slot berguna ketika Anda perlu menerapkan variasi gaya ke beberapa bagian dari sebuah komponen.
Resep slot terdiri dari properti berikut:
className: Awalan className untuk dilampirkan ke slot komponenslots: Kumpulan bagian komponen yang akan diberi gayabase: Gaya dasar per slotvariants: Gaya visual yang berbeda untuk setiap slotdefaultVariants: Varian default untuk komponencompoundVariants: Kombinasi varian gabungan dan penggantian gaya untuk setiap slot.
Mendefinisikan Resep
Gunakan fungsi identitas defineSlotRecipe untuk membuat resep slot.
recipe\n\nimport { defineSlotRecipe } from "@chakra-ui/react"\n\nexport const checkboxSlotRecipe = defineSlotRecipe({\n slots: ["root", "control", "label"],\n base: {\n root: { display: "flex", alignItems: "center", gap: "2" },\n control: { borderWidth: "1px", borderRadius: "sm" },\n label: { marginStart: "2" },\n },\n variants: {\n size: {\n sm: {\n control: { width: "8", height: "8" },\n label: { fontSize: "sm" },\n },\n md: {\n control: { width: "10", height: "10" },\n label: { fontSize: "md" },\n },\n },\n },\n})Menggunakan Resep
Ada dua cara menggunakan resep dalam komponen:
- Langsung di komponen dengan
useSlotRecipe - Sebagai komponen gabungan (disarankan) dengan
createSlotRecipeContext
Informasi: Menambahkan arahan"use client"diperlukan untuk menggunakan hookuseSlotRecipeatau fungsicreateSlotRecipeContext. Ini karena mereka bergantung pada hook react sepertiuseContextdanuseInsertionEffectdi balik layar.
Langsung di Komponen
Gunakan hook useSlotRecipe untuk mendapatkan resep bagi sebuah komponen. Kemudian, panggil resep dengan props varian untuk mendapatkan gaya.
checkbox\n\n"use client"\n\nimport { chakra, useSlotRecipe } from "@chakra-ui/react"\nimport { checkboxSlotRecipe } from "./checkbox"\n\nexport const Checkbox = (props) => {\n const { size, ...restProps } = props\n\n const recipe = useSlotRecipe({ recipe: checkboxSlotRecipe })\n const styles = recipe({ size })\n\n return (\n <chakra css={styles}>\n <chakra type="checkbox" css={stylesl} {...restProps} />\n <chakra css={styles}>Checkbox Label</chakra>\n </chakra>\n )\n}splitVariantProps
Perhatikan bagaimana prop size di-destruktur dari props untuk diteruskan ke resep. Pendekatan yang lebih cerdas adalah secara otomatis memisahkan props resep dari props komponen.
Untuk melakukannya, gunakan fungsi recipeariantProps untuk memisahkan props resep dari props komponen.
checkbox\n\n"use client"\n\nimport { chakra, useSlotRecipe } from "@chakra-ui/react"\nimport { checkboxSlotRecipe } from "./checkbox"\n\nexport const Checkbox = (props) => {\n const recipe = useSlotRecipe({ recipe: checkboxSlotRecipe })\n const [recipeProps, restProps] = recipeariantProps(props)\n const styles = recipe(recipeProps)\n\n //...\n}TypeScript
Untuk menyimpulkan tipe props varian resep, gunakan pembantu tipe RecipeVariantProps.
checkbox\n\nimport type { RecipeVariantProps } from "@chakra-ui/react"\nimport { checkboxSlotRecipe } from "./checkbox"\n\ntype CheckboxVariantProps = RecipeVariantProps<typeof checkboxSlotRecipe>\n\nexport interface CheckboxProps extends ReactithChildren<CheckboxVariantProps> {}Membuat Komponen Gabungan
Teruskan resep ke fungsi createSlotRecipeContext untuk membuat konteks resep slot.
Kemudian, gunakan fungsi withProvider dan withContext untuk membuat komponen gabungan yang berbagi konteks yang sama.
Informasi: Anda perlu mengetik secara manual generics untukwithProviderdanwithContext. Pendekatan ini dirancang untuk mengoptimalkan performa TypeScript. Inferensi otomatis, meskipun nyaman, akan memperlambat kompilasi TypeScript karena kompleksitas tipe yang terlibat.
checkbox\n\n"use client"\n\nimport { createSlotRecipeContext } from "@chakra-ui/react"\nimport { checkboxSlotRecipe } from "./checkbox"\n\nconst { withProvider, withContext } = createSlotRecipeContext({\n recipe: checkboxSlotRecipe,\n})\n\ninterface CheckboxRootProps extends HTMLChakraProps<\n "label",\n RecipeVariantProps<typeof checkboxSlotRecipe>\n> {}\nexport const CheckboxRoot = withProvider<HTMLLabelElement, CheckboxRootProps>(\n "label",\n "root",\n)\n\ninterface CheckboxControlProps extends HTMLChakraProps<"input"> {}\nexport const CheckboxControl = withContext<\n HTMLInputElement,\n CheckboxControlProps\n>("input", "control")\n\ninterface CheckboxLabelProps extends HTMLChakraProps<"span"> {}\nexport const CheckboxLabel = withContext<HTMLSpanElement, CheckboxLabelProps>(\n "span",\n "label",\n)Teruskan props varian ke komponen "root" untuk menerapkan gaya.
Catatan: Komponen root adalah yang menggunakan fungsi withProvider.
app\n\nconst App = () => {\n return (\n <CheckboxRoot size="md">\n <CheckboxControl />\n <CheckboxLabel />\n </CheckboxRoot>\n )\n}Prop unstyled
Pendekatan ini mendukung penggunaan prop unstyled untuk menghapus gaya yang diterapkan oleh resep.
checkbox\n\n<CheckboxRoot unstyled>\n <CheckboxControl />\n <CheckboxLabel />\n</CheckboxRoot>TypeScript
Untuk menyimpulkan tipe props varian resep, gunakan pembantu tipe RecipeVariantProps.
import type { RecipeVariantProps, UnstyledProp } from "@chakra-ui/react"\nimport { checkboxSlotRecipe } from "./checkbox"\n\ntype CheckboxVariantProps = RecipeVariantProps<typeof checkboxSlotRecipe>\n\nexport interface CheckboxProps\n extends ReactithChildren<CheckboxVariantProps>, UnstyledProp {}Varian Gabungan
Gunakan properti compoundVariants untuk mendefinisikan sekumpulan varian yang diterapkan berdasarkan kombinasi varian lainnya.
recipe\n\nimport { defineSlotRecipe } from "@chakra-ui/react"\n\nexport const checkboxRecipe = defineSlotRecipe({\n slots: ["root", "control", "label"],\n base: {},\n variants: {\n size: {\n sm: {},\n md: {},\n },\n visual: {\n contained: {},\n outline: {},\n },\n },\n compoundVariants: [\n {\n size: "sm",\n visual: "outline",\n css: {\n control: { borderWidth: "1px" },\n label: { color: "green.500" },\n },\n },\n ],\n})Menargetkan Slot
Dalam beberapa kasus, menargetkan slot dengan className mungkin diperlukan.
- Setel properti
classNamedalam konfigurasi - Konvensi penamaan adalah
${className}__${slot}
recipe\n\nimport { defineSlotRecipe } from "@chakra-ui/react"\n\nexport const checkboxRecipe = defineSlotRecipe({\n className: "checkbox",\n slots: ["root", "control", "label"],\n base: {\n root: {\n bg: "blue.500",\n _hover: {\n "& .checkbox__label": { color: "white" },\n },\n },\n },\n})Penggunaan Tema
Untuk menggunakan resep secara dapat digunakan kembali, pindahkan ke tema sistem dan tambahkan ke properti themecipes.
Tidak perlu menambahkan arahan "use client" saat menggunakan resep dalam tema.
theme\n\nimport { createSystem, defaultConfig, defineConfig } from "@chakra-ui/react"\nimport { checkboxSlotRecipe } from "./checkbox"\n\nconst config = defineConfig({\n theme: {\n slotRecipes: {\n checkbox: checkboxSlotRecipe,\n },\n },\n})\n\nexport default createSystem(defaultConfig, config)TypeScript
Gunakan CLI untuk menghasilkan tipe untuk resep, lalu impor di komponen Anda. Lihat dokumentasi CLI tentang cara menjalankan typegen di postinstall, CI, dan monorepos.
npx @chakra-ui/cli typegen ./theme
Kemudian, impor tipe yang dihasilkan di komponen Anda.
checkbox\n\nimport type { SlotRecipeProps, UnstyledProp } from "@chakra-ui/react"\n\nexport interface CheckboxProps\n extends SlotRecipeProps<"checkbox">, UnstyledProp {}Perbarui Kode
Jika Anda menggunakan resep langsung di komponen, perbarui useRecipe untuk menggunakan properti key untuk mendapatkan resep dari tema.
checkbox\n\nconst Checkbox = () => {\n- const recipe = useRecipe({ recipe: checkboxRecipe })\n+ const recipe = useRecipe({ key: "checkbox" })\n // ...\n}Jika Anda membuat komponen gabungan, perbarui createSlotRecipeContext untuk menggunakan properti key.
checkbox\n\nconst { withProvider, withContext } = createSlotRecipeContext({\n- recipe: checkboxRecipe,\n+ key: "checkbox",\n})