Skip to content

๐Ÿ‘ฉโ€๐ŸŽค ๋””์ž์ธ ์‹œ์Šคํ…œ ๊ตฌ์ถ•์„ ์œ„ํ•œ ๊ณ„์ธต ๊ตฌ๋ถ„ ์›๋ฆฌ

Notifications You must be signed in to change notification settings

with-key/design-system-layers

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

2 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๋””์ž์ธ ์‹œ์Šคํ…œ ๊ณ„์ธต

image

design system component

  • ์ถ”์ƒํ™” ์ˆ˜์ค€์ด ๋†’์Œ
  • ํ™•์žฅ์„ฑ >> ์‚ฌ์šฉ์„ฑ
  • ํ˜•ํƒœ ์—†์ด, ๊ธฐ๋Šฅ๋งŒ ์ œ๊ณต
// radio-group.tsx
export { Indicator, Item, Root } from "@radix-ui/react-radio-group";

product system component

  • 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,
});

domain component

  • ๋„๋ฉ”์ธ์˜ ๋งฅ๋ฝ์„ ๋‹ด๊ณ  ์žˆ๋Š” ์˜์—ญ
  • ๋„๋ฉ”์ธ์˜ ์„ธ๋ถ€ ํ˜•ํƒœ์™€ ์„ธ๋ถ€ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€์ ์œผ๋กœ ๋‹ด๊ณ  ์žˆ์Œ
  • ๋„๋ฉ”์ธ์˜ ๋งฅ๋ฝ์„ ๋‹ด๊ณ  ์žˆ์ง€๋งŒ, ์žฌ์‚ฌ์šฉ ๋  ์ˆœ ์žˆ์Œ
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>
  );
};

theme (color tokens)

// 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

About

๐Ÿ‘ฉโ€๐ŸŽค ๋””์ž์ธ ์‹œ์Šคํ…œ ๊ตฌ์ถ•์„ ์œ„ํ•œ ๊ณ„์ธต ๊ตฌ๋ถ„ ์›๋ฆฌ

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published