- ์ถ์ํ ์์ค์ด ๋์
- ํ์ฅ์ฑ >> ์ฌ์ฉ์ฑ
- ํํ ์์ด, ๊ธฐ๋ฅ๋ง ์ ๊ณต
// radio-group.tsx
export { Indicator, Item, Root } from "@radix-ui/react-radio-group";
Core
์ ์ถ์ํ ์์ค์ ํ๋จ๊ณ ๋ฎ์ถฐ์ ์ ๊ณต- ํ์ฅ์ฑ > ์ฌ์ฉ์ฑ
- ๊ธฐ๋ณธ
theme
์ด ์ ์ฉ๋์ด ์์ (ํ ๋ง ์ธ์ ๋์์ธ์ ์ ์ฉํ๊ธฐ ์ํ headless ํํ๋ก๋ ์ ๊ณตํจ)
// radio-group.tsx
import { ReactNode, useId } from "react";
import * as Primitive from "../../core/radio-group/radio-group";
import css from "./radio-group.module.scss";
type RootProps = React.ComponentPropsWithoutRef<typeof Primitive.Root> & {};
const Root = (props: RootProps) => {
return <Primitive.Root className={css.container} {...props} />;
};
type ItemProps = React.ComponentPropsWithoutRef<typeof Primitive.Item> & {};
const Item = (props: ItemProps) => {
return <Primitive.Item className={css.item} {...props} />;
};
type IndicatorProps = React.ComponentPropsWithoutRef<
typeof Primitive.Indicator
> & {};
const Indicator = (props: IndicatorProps) => {
return <Primitive.Indicator className={css.indicator} {...props} />;
};
type LabelProps = Omit<React.ComponentPropsWithoutRef<"label">, "children"> & {
children: ReactNode | ((id: string) => ReactNode);
};
// design system ๋ ๋ฒจ์์๋ ์ ๊ณต๋์ง ์์ง๋ง, ์ฌ์ฉ์ฑ์ ๋์ด๊ธฐ ์ํด ์๋ธ ์ปดํฌ๋ํธ ์ถ๊ฐํจ
const Label = ({ children, ...props }: LabelProps) => {
const id = useId();
return (
<label {...props} className={css.label || props.className}>
{typeof children === "function" ? children(id) : children}
</label>
);
};
export const RadioGroup = Object.assign(Root, {
Item,
Indicator,
Label,
});
- ๋๋ฉ์ธ์ ๋งฅ๋ฝ์ ๋ด๊ณ ์๋ ์์ญ
- ๋๋ฉ์ธ์ ์ธ๋ถ ํํ์ ์ธ๋ถ ๊ธฐ๋ฅ์ ์ถ๊ฐ์ ์ผ๋ก ๋ด๊ณ ์์
- ๋๋ฉ์ธ์ ๋งฅ๋ฝ์ ๋ด๊ณ ์์ง๋ง, ์ฌ์ฌ์ฉ ๋ ์ ์์
import { useState } from "react";
import { RadioGroup } from "../../product/radio-group/radio-group";
import css from "./radio-image.module.scss";
export const RadioImage = () => {
const [value, setValue] = useState<"yes" | "no">("yes");
return (
<RadioGroup
defaultValue="yes"
value={value}
onValueChange={(val) => {
if (val === "yes" || val === "no") {
setValue(val);
}
}}
>
<div style={{ display: "flex" }}>
<div style={{ display: "flex", flexDirection: "column" }}>
<RadioGroup.Label
data-state={value === "yes" ? "checked" : "unchecked"}
className={css.label}
>
<div className={css.image}></div>
<div style={{ display: "flex", alignItems: "center" }}>
<RadioGroup.Item value="yes">
<RadioGroup.Indicator />
</RadioGroup.Item>
<div>์ฌ์ง</div>
</div>
</RadioGroup.Label>
</div>
<div style={{ display: "flex", flexDirection: "column" }}>
<RadioGroup.Label
data-state={value === "no" ? "checked" : "unchecked"}
className={css.label}
>
<div className={css.image}></div>
<div style={{ display: "flex", alignItems: "center" }}>
<RadioGroup.Item value="no">
<RadioGroup.Indicator />
</RadioGroup.Item>
<div>์ฌ์ง 2</div>
</div>
</RadioGroup.Label>
</div>
</div>
</RadioGroup>
);
};
// main.tsx
import { createRoot } from "react-dom/client";
import App from "./App.tsx";
import Theme from "./styles/utils/theme.tsx";
createRoot(document.getElementById("root")!).render(
// Theme์ `accentColor`์ ๋ฐ๋ผ --accent-color๊ฐ ๋ณ๊ฒฝ๋จ
<Theme accentColor="blue">
<App />
</Theme>
);
@import "./primitive-colors.scss";
[data-accent-color="red"] {
--accent-01: var(--red01);
--accent-02: var(--red02);
--accent-03: var(--red03);
--accent-04: var(--red04);
--accent-05: var(--red05);
--accent-06: var(--red06);
--accent-07: var(--red07);
--accent-08: var(--red08);
--accent-09: var(--red09);
--accent-10: var(--red10);
}
[data-accent-color="blue"] {
--accent-01: var(--blue01);
--accent-02: var(--blue02);
--accent-03: var(--blue03);
--accent-04: var(--blue04);
--accent-05: var(--blue05);
--accent-06: var(--blue06);
--accent-07: var(--blue07);
--accent-08: var(--blue08);
--accent-09: var(--blue09);
--accent-10: var(--blue10);
}
[data-accent-color="green"] {
--accent-01: var(--green01);
--accent-02: var(--green02);
--accent-03: var(--green03);
--accent-04: var(--green04);
--accent-05: var(--green05);
--accent-06: var(--green06);
--accent-07: var(--green07);
--accent-08: var(--green08);
--accent-09: var(--green09);
--accent-10: var(--green10);
}
so-so.dev ๋์์ธ ์์คํ ์ฝ๋๋ฅผ ๋์ด์ radix-theme