사용 원칙
코어 컴포넌트는 화면의 톤을 맞추기 위한 기준입니다. 관리자 설정, 회원, 게시판, 댓글처럼 반복되는 업무 화면에서는 임의의 button, input, fixed layer를 새로 만들기보다 이 컴포넌트를 먼저 사용합니다.
src/core/components/button/Button.tsxsrc/core/components/form/InputField.tsxsrc/core/components/form/SelectField.tsxsrc/core/components/tab/Tab.tsxsrc/core/components/modal/Modal.tsxsrc/core/components/panel/Bottom.tsxsrc/core/components/accordion/Accordion.tsxsrc/core/components/dropdown/Dropdown.tsxTab
`Tab`은 서로 관련된 화면을 같은 맥락 안에서 전환할 때 사용합니다. 회원 목록/회원 추가/그룹 관리, 설정 카테고리, 알림 필터처럼 현재 페이지 안에서 뷰만 바뀌는 구조에 적합합니다.
itemsvalue / defaultValuevariantrenderPanelkeepMountedimport Tab from "@components/tab/Tab";
<Tab
defaultValue="members"
variant="line"
items={[
{ value: "members", label: "회원 목록", content: <MemberList /> },
{ value: "create", label: "회원 추가", content: <MemberCreate /> },
]}
/>
<Tab
value="list"
variant="pill"
renderPanel={false}
items={[
{ value: "list", label: "회원 목록", href: "/admin/user/list" },
{ value: "group", label: "그룹 관리", href: "/admin/user/groupList" },
]}
/>Form Fields
`InputField`와 `SelectField`는 label, focus, disabled, error 상태를 같은 구조로 보여줍니다. 서버 액션에서 받은 `fieldErrors`는 Alert로 올리지 말고 해당 input의 `error`에 연결하는 것을 기본 규칙으로 둡니다.
inputTitlename / idiconerrorgetData<InputField
inputTitle="이메일"
name="email"
placeholder="hello@example.com"
icon={<Mail size={16} />}
error={fieldErrors?.email?.[0]}
/>
<SelectField
inputTitle="게시판 타입"
name="boardType"
options={[
{ id: "default", title: "기본 게시판" },
{ id: "issue", title: "이슈 트래커" },
]}
/>Modal
`Modal`은 삭제 확인, 그룹 추가, 첨부파일 선택처럼 페이지 맥락을 유지한 채 짧은 결정을 받아야 할 때 사용합니다. 긴 문서나 화면 전환성 콘텐츠에는 `Bottom`이 더 적합합니다.
state / closesizepositionescClose / overlayCloseconst [open, setOpen] = useState(false);
<Button onClick={() => setOpen(true)}>Modal 열기</Button>
<Modal state={open} close={setOpen} size="md" position="center">
<ModalContent />
</Modal>Bottom
`Bottom`은 아래에서 올라오는 보조 화면입니다. 모바일 선택 UI, 긴 보조 작업, 임시 문서 패널처럼 현재 화면의 맥락을 유지한 채 별도 흐름을 열어야 할 때 사용합니다.
실제 컴포넌트는 portal로 렌더링되며, 닫을 때 `closeHref`가 있으면 해당 주소로 이동합니다.
closeHrefdrag downanimationimport Bottom from "@components/panel/Bottom";
const HelperPanel = ({ children }: { children: React.ReactNode }) => {
return <Bottom closeHref="/">{children}</Bottom>;
};Accordion / Dropdown
`Accordion`은 정보를 접어 읽기 부담을 줄일 때 사용합니다. `Dropdown`은 계정 메뉴, 빠른 액션, 필터 메뉴처럼 버튼 주변에 짧은 선택지를 띄울 때 사용합니다.
<Accordion items={items} allowMultiple />
<div className="relative">
<Button onClick={() => setOpen((prev) => !prev)}>메뉴</Button>
<Dropdown state={open} close={setOpen} className="left-0 top-full mt-2">
<div className="rounded-lg border bg-white p-2 shadow-xl">
...
</div>
</Dropdown>
</div>Feedback
`Alert`는 반드시 필요한 전역성 안내에만 씁니다. 입력값 오류는 `InputField`의 `error`로 내려보내고, 작업 전체가 실패했거나 권한/시스템 문제처럼 특정 필드에 붙일 수 없는 경우에 Alert를 사용합니다.
<Alert type="success" message="저장되었습니다." />
<Alert type="warning" message="일부 설정은 서버 재시작 후 반영됩니다." />
<Alert type="error" message="권한이 없거나 요청을 처리할 수 없습니다." />