اجزای مشابه با سبک های مختلف در ui Chakra

هنگام ساخت قطعات با Chakra UI V3 ، ممکن است نیاز به ایجاد اجزای مشابه با تغییرات جزئی در سبک ها مانند رنگ های مختلف پس زمینه ایجاد کنید. چگونه می توانید این تغییرات را به طور کارآمد مدیریت کنید؟
بیایید در نظر بگیریم ServerStatus
مؤلفه ای که نشان دهنده وضعیت در حال اجرا یک سرور است. یک نسخه ساده از این مؤلفه ممکن است مانند موارد زیر باشد:
import { Box } from "@chakra-ui/react";
export const ServerRunningStatus = () => {
return (
<Box
w="200px"
p={2}
textAlign="center"
borderRadius="md"
bg="green.600"
color="white"
>
Running
Box>
);
};
با این حال ، یک سرور نه تنها وضعیت در حال اجرا دارد بلکه می تواند متوقف شود یا در حالت ناشناخته باشد. از آنجا که محتوای نمایشگر اکثراً یکسان است ، می توانیم از یک مؤلفه واحد با غرفه ها برای کنترل تغییرات آن استفاده کنیم.
import { Box } from "@chakra-ui/react";
type Status = "running" | "stopped" | "unknown";
interface Props {
status: Status;
}
export const ServerStatus = ({ status }: Props) => {
const bgColor = {
running: "green.600",
stopped: "red.600",
unknown: "gray.600",
}[status];
return (
<Box
w="200px"
p={2}
textAlign="center"
borderRadius="md"
textTransform="capitalize"
bg={bgColor}
color="white"
>
{status}
Box>
);
};
برای تمایز بصری حالتها ، ما a را تعریف می کنیم bgColor
خاصیت این رویکرد در بسیاری موارد خوب کار می کند و هنگامی که به حالت های جدید اضافه می شود Status
اگر به درستی رسیدگی نشود ، خطای نوع رخ می دهد. با این حال ، با افزایش تعداد سبک هایی که نیاز به تمایز دارند ، مدیریت آنها به صورت دستی می تواند برای مدیریت سخت تر شود.
مدیریت چند سبک
حال ، بیایید با اضافه کردن یک ویژگی دیگر ، رنگ متن را به همراه رنگ پس زمینه نیز مدیریت کنیم:
import { Box } from "@chakra-ui/react";
type Status = "running" | "stopped" | "unknown";
interface Props {
status: Status;
}
export const ServerStatus = ({ status }: Props) => {
const styles = {
running: { bg: "green.600", color: "white" },
stopped: { bg: "red.600", color: "white" },
unknown: { bg: "gray.200", color: "gray.600" },
}[status];
return (
<Box
w="200px"
p={2}
textAlign="center"
borderRadius="md"
textTransform="capitalize"
bg={styles.bg}
color="white"
>
{status}
Box>
);
};
در حالی که این کار می کند ، چند موضوع وجود دارد. بزرگترین اشکال این است که سبک ها از نوع ایمنی برخوردار نیستندبشر اگر یک مقدار نادرست باشد ، TypeScript آن را به دست نمی آورد و تکمیل خودکار در دسترس نخواهد بود.
با استفاده از Record
برای نوع ایمنی
ما می توانیم این کار را با استفاده از یک نوع ضبط بهبود بخشیم:
import { Box, type BoxProps } from "@chakra-ui/react";
type Status = "running" | "stopped" | "unknown";
interface Props {
status: Status;
}
const styles: Record<Status, Required<Pick<BoxProps, "bg" | "color">>> = {
running: { bg: "green.600", color: "white" },
stopped: { bg: "red.600", color: "white" },
unknown: { bg: "gray.200", color: "gray.600" },
};
export const ServerStatus = ({ status }: Props) => {
return (
<Box
w="200px"
p={2}
textAlign="center"
borderRadius="md"
textTransform="capitalize"
{...styles[status]}
>
{status}
Box>
);
};
با استفاده از Record
، ما اطمینان حاصل می کنیم که همه Status
تعریف سبک مربوطه با استفاده از Required
اختیاری است ، اما هر دو را تضمین می کند bg
وت color
برای هر Status
بشر علاوه بر این ، از آنجا که ما اهرم می کنیم BoxProps
، ما از تکمیل خودکار TypeScript بهره مند می شویم.
اگر وضعیت های مختلف به تعداد مختلفی از خصوصیات سبک نیاز داشته باشند ، می توانیم نقشه برداری را به صورت انعطاف پذیر ساختار دهیم:
const styles: Record<Status, BoxProps> = {
running: { bg: "green.600", color: "white" },
stopped: { bg: "red.600", color: "white" },
unknown: { bg: "gray.200", borderColor: "gray.800" },
};
این رویکرد ممکن است در بسیاری موارد کافی باشد. با این حال ، اگر ما نیاز به تعریف سبک های پیچیده تر داشته باشیم ، چه می شود؟ نوشتن تعداد زیادی از سبک ها به طور مستقیم در مؤلفه می تواند خوانایی را کاهش دهد.
جدا کردن سبک ها با ui چاکرا Recipe
UI Chakra ویژگی دستور العمل را ارائه می دهد ، که به ما امکان می دهد سبک ها را از منطق مؤلفه جدا کنیم. بیایید مثالی را ببینیم:
import { Box, defineRecipe, useRecipe } from "@chakra-ui/react";
type Status = "running" | "stopped" | "unknown";
interface Props {
status: Status;
}
const serverStatusRecipe = defineRecipe({
base: {
textAlign: "center",
w: "200px",
p: 2,
borderRadius: "md",
textTransform: "capitalize",
},
variants: {
status: {
running: { bg: "green.200", color: "white" },
stopped: { bg: "red.600", color: "white" },
unknown: { bg: "gray.200", color: "gray.600" },
},
},
});
export const ServerStatus = ({ status }: Props) => {
const recipe = useRecipe({ recipe: serverStatusRecipe });
const styles = recipe({ status });
return <Box css={styles}>{status}Box>;
};
با استفاده از defineRecipe
، ما می توانیم سبک هایی را با نوع ایمنی و ساخت خودکار بنویسیم. ترکیبی از base
وت variants
به ما اجازه می دهد تا به طور طبیعی سبک های مشترک و تغییرات آنها را تعریف کنیم. این جدایی باعث بهبود خوانایی و حفظ آن می شود.
علاوه بر این ، serverStatusRecipe
می توان در یک فایل جداگانه یا حتی در پیکربندی موضوع Chakra قرار داد ، و آن را در سراسر برنامه بسیار قابل استفاده مجدد می کند.
پایان
بسته به پیچیدگی سبک ها و نیاز به قابلیت استفاده مجدد ، می توانید بهترین روش را برای مورد استفاده خود انتخاب کنید. آیا با استفاده از یک ظاهر طراحی شده مبتنی بر غرفه ، a Record
نقشه برداری ، یا چاکرا UI Recipe
، هر روش از نظر حفظ و مقیاس پذیری مزایای مختلفی را ارائه می دهد.