@hivcd-printshop/design-system 1.2.0 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +55 -3
- package/dist/index.d.ts +55 -3
- package/dist/index.js +471 -307
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +465 -307
- package/dist/index.mjs.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/dist/ChevronDown-XSALXCW4.svg +0 -3
- package/dist/Exclamation-IUYZYYC4.svg +0 -4
- package/dist/RadioSelected-DOLVV7ZM.svg +0 -4
- package/dist/RadioUnselected-QN74EU46.svg +0 -3
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/lib/cn.ts","../src/assets/svgs/Icons.tsx","../src/components/BackButton/BackButton.tsx","../src/components/CTA/CTA.tsx","../src/components/Column/MultiColumn.tsx","../src/components/Column/Column.tsx","../src/components/Column/ColumnContentContainer.tsx","../src/components/Column/ColumnLabel.tsx","../src/components/Column/ColumnText.tsx","../src/components/Column/ColumnSubTitle.tsx","../src/components/Form/BasicFormField.tsx","../src/components/Form/FormText.tsx","../src/components/Form/FormTextArea.tsx","../src/components/Form/FormNumber.tsx","../src/components/Form/FormPassword.tsx","../src/components/Form/FormTel.tsx","../src/components/Form/FormColor.tsx","../src/components/Form/FormFile.tsx","../src/components/Form/FormCheckBox.tsx","../src/components/Form/FormSelectBox.tsx","../src/components/Form/SelectBoxOption.tsx","../src/components/TextButton/TextButton.tsx","../src/components/Dropdown/Dropdown.tsx","../src/components/ListView/List.tsx","../src/components/Modal/Modal.tsx","../src/components/Modal/ModalText.tsx","../src/components/createPost/CategorySegment.tsx","../src/components/createPost/CategorySegmentedControl.tsx","../src/components/createPost/TitleInput.tsx","../src/components/notice/NoticeBadge.tsx","../src/components/notice/NoticeBar.tsx","../src/components/SearchBar/SearchBar.tsx","../src/components/SideRadioAccordion/SideRadioAccordion.tsx","../src/lib/useControllableState.ts","../src/components/Tag/Tag.tsx","../src/components/Timetable/Timetable.tsx","../src/components/Timetable/WeekNavigation.tsx","../src/components/Timetable/dateUtils.ts","../src/components/TNB/TNB.tsx","../src/components/Toast/Toast.tsx"],"sourcesContent":["export { BackButton, BackButtonProps } from \"./components/BackButton/BackButton\";\n\nexport { CTA, CTAProps } from \"./components/CTA/CTA\";\n\nexport { MultiColumn } from \"./components/Column/MultiColumn\";\nexport { Column, ColumnProps } from \"./components/Column/Column\";\nexport {\n ColumnContentContainer,\n ColumnContentContainerProps,\n} from \"./components/Column/ColumnContentContainer\";\nexport { ColumnLabel, ColumnLabelProps } from \"./components/Column/ColumnLabel\";\nexport {\n ColumnText,\n ColumnTextProps,\n ColumnTextStyle,\n ModalTextStyle,\n} from \"./components/Column/ColumnText\";\nexport { ColumnSubTitle, ColumnSubTitleProps } from \"./components/Column/ColumnSubTitle\";\n\nexport {\n BasicFormField,\n BasicFormFieldProps,\n getInputStyles,\n} from \"./components/Form/BasicFormField\";\nexport { FormText, FormTextProps } from \"./components/Form/FormText\";\nexport { FormTextArea, FormTextAreaProps } from \"./components/Form/FormTextArea\";\nexport { FormNumber, FormNumberProps } from \"./components/Form/FormNumber\";\nexport { FormPassword, FormPasswordProps } from \"./components/Form/FormPassword\";\nexport { FormTel, FormTelProps } from \"./components/Form/FormTel\";\nexport { FormColor, FormColorProps } from \"./components/Form/FormColor\";\nexport { FormFile, FormFileProps } from \"./components/Form/FormFile\";\nexport { FormCheckBox, FormCheckBoxProps } from \"./components/Form/FormCheckBox\";\nexport { FormSelectBox, FormSelectBoxProps } from \"./components/Form/FormSelectBox\";\nexport { SelectBoxOption, SelectBoxOptionProps } from \"./components/Form/SelectBoxOption\";\n\nexport { TextButton, TextButtonProps } from \"./components/TextButton/TextButton\";\n\nexport { Dropdown, DropdownProps } from \"./components/Dropdown/Dropdown\";\n\nexport { List, ListProps } from \"./components/ListView/List\";\n\nexport { Modal, ModalProps } from \"./components/Modal/Modal\";\nexport { ModalText, ModalTextProps } from \"./components/Modal/ModalText\";\n\nexport { IconInfo, IconCheck, IconChevronDownXS } from \"./assets/svgs/Icons\";\n\nexport { CategorySegment, CategorySegmentProps } from \"./components/createPost/CategorySegment\";\nexport {\n CategorySegmentedControl,\n CategorySegmentedControlProps,\n} from \"./components/createPost/CategorySegmentedControl\";\nexport { TitleInput, TitleInputProps } from \"./components/createPost/TitleInput\";\n\nexport {\n NoticeBadge,\n NoticeBadgeProps,\n NoticeBadgeVariable,\n} from \"./components/notice/NoticeBadge\";\nexport {\n NoticeBar,\n NoticeBarProps,\n NoticeBarVariable,\n NoticeBarBadgeVariable,\n} from \"./components/notice/NoticeBar\";\n\nexport { SearchBar, SearchBarProps } from \"./components/SearchBar/SearchBar\";\n\nexport {\n SideRadioAccordion,\n SideRadioAccordionProps,\n RadioToggle,\n PrintColor as SideRadioAccordionPrintColor,\n} from \"./components/SideRadioAccordion/SideRadioAccordion\";\n\nexport { Tag, TagProps } from \"./components/Tag/Tag\";\n\nexport {\n Timetable,\n TimetableProps,\n DayColumn,\n TimeSlot,\n TimeSlotState,\n PrintColor as TimetablePrintColor,\n} from \"./components/Timetable/Timetable\";\nexport { WeekNavigation, WeekNavigationProps, Week } from \"./components/Timetable/WeekNavigation\";\n\nexport {\n TNB,\n TNBProps,\n NavIcon,\n UpperPartItem,\n LowerPartItem,\n LinkComponent,\n} from \"./components/TNB/TNB\";\n\nexport { Toast, ToastProps } from \"./components/Toast/Toast\";\n","import { clsx, type ClassValue } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\n// text-head*/text-body*/text-caption* are custom typography utilities (src/styles.css),\n// not text-color utilities — tailwind-merge would otherwise treat them as the same\n// group as text-white/text-gray04 and silently drop one of them.\nconst twMerge = extendTailwindMerge<\"font-typography\">({\n extend: {\n classGroups: {\n \"font-typography\": [\n \"text-head1-medium\",\n \"text-head2-medium\",\n \"text-head3-medium\",\n \"text-head4-regular\",\n \"text-body1-medium\",\n \"text-body1-regular\",\n \"text-body2-regular\",\n \"text-body3-medium\",\n \"text-body3-regular\",\n \"text-body3-book\",\n \"text-caption-regular\",\n \"text-caption-book\",\n ],\n },\n },\n});\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","export const IconChevronDownXS = ({\n className,\n stroke,\n}: {\n className?: string;\n stroke?: string;\n}) => {\n return (\n <svg\n className={className}\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 20 20\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M5 8.3335L10 13.3335L15 8.3335\"\n stroke={stroke || \"#121212\"}\n strokeWidth=\"1.5\"\n strokeLinecap=\"square\"\n />\n </svg>\n );\n};\n\nexport const IconCheck = ({ className, stroke }: { className?: string; stroke?: string }) => {\n return (\n <svg\n className={className}\n width=\"13\"\n height=\"13\"\n viewBox=\"0 0 13 13\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M2.05566 7.0555L4.83344 9.8333L10.9446 3.72217\" stroke={stroke || \"#121212\"} />\n </svg>\n );\n};\n\nexport const IconSearch = ({ className, stroke }: { className?: string; stroke?: string }) => {\n return (\n <svg\n className={className}\n width=\"30\"\n height=\"30\"\n viewBox=\"0 0 30 30\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M20.1161 20.6888L24.1075 25.1791\"\n stroke={stroke || \"black\"}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M13.9289 23.0361C18.9587 23.0361 23.0361 18.9587 23.0361 13.9289C23.0361 8.89918 18.9587 4.82178 13.9289 4.82178C8.89918 4.82178 4.82178 8.89918 4.82178 13.9289C4.82178 18.9587 8.89918 23.0361 13.9289 23.0361Z\"\n stroke={stroke || \"black\"}\n strokeWidth=\"2\"\n />\n </svg>\n );\n};\n\nexport const IconInfo = ({ className, stroke }: { className?: string; stroke?: string }) => {\n return (\n <svg\n className={className}\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <circle cx=\"8\" cy=\"8\" r=\"6.25\" stroke={stroke || \"#8b94a1\"} strokeWidth=\"1.5\" />\n <path\n d=\"M8 7.25V11.25\"\n stroke={stroke || \"#8b94a1\"}\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n />\n <circle cx=\"8\" cy=\"5\" r=\"0.9\" fill={stroke || \"#8b94a1\"} />\n </svg>\n );\n};\n\nexport const IconGoBack = ({ className, stroke }: { className?: string; stroke?: string }) => {\n return (\n <svg\n className={className}\n width=\"32\"\n height=\"32\"\n viewBox=\"0 0 32 32\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M28 16.0001L4 16.0001\"\n stroke={stroke || \"black\"}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n <path d=\"M12 8L4 16L12 24\" stroke={stroke || \"black\"} strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n );\n};\n","import { cn } from \"../../lib/cn\";\nimport { IconGoBack } from \"../../assets/svgs/Icons\";\n\nexport interface BackButtonProps {\n onClick?: () => void;\n className?: string;\n}\n\nexport const BackButton = ({ onClick, className }: BackButtonProps) => {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className={cn(\n \"w-14 h-full py-3\",\n \"flex flex-col items-center\",\n \"box-border border-r border-gray02\",\n \"bg-white hover:bg-gray00 active:bg-gray01\",\n \"cursor-pointer\",\n className,\n )}\n >\n <IconGoBack />\n </button>\n );\n};\n","import { cn } from \"../../lib/cn\";\n\nexport interface CTAProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n primary?: boolean;\n alert?: boolean;\n disabled?: boolean;\n label: string;\n onClick?: () => void;\n className?: string;\n forModal?: boolean;\n}\n\nexport const CTA = ({\n primary = false,\n alert = false,\n disabled = false,\n label,\n onClick,\n className,\n forModal = false,\n ...props\n}: CTAProps) => {\n return (\n <button\n type=\"button\"\n disabled={disabled}\n className={cn(\n forModal ? \"h-14.5\" : \"h-12\",\n \"w-full max-w-360 px-4\",\n \"flex items-center justify-center\",\n \"border-t box-border border-gray02\",\n primary && \"border-none\",\n\n \"text-head3-medium text-strong\",\n primary && \"text-white\",\n alert && \"text-danger\",\n disabled && \"text-quaternary\",\n\n \"bg-white hover:bg-gray00 active:bg-gray01 disabled:bg-gray02\",\n primary && \"bg-black hover:bg-gray08 active:bg-gray09 disabled:bg-gray01\",\n\n \"cursor-pointer disabled:cursor-default\",\n\n className,\n )}\n onClick={onClick}\n {...props}\n >\n {label}\n </button>\n );\n};\n","//사용 예시\n//<MultiColumn>\n// <MultiColumn.Columns>\n// <Column title=\"첫번째\" />\n// <Column title=\"두번째\" />\n// <Column title=\"세번째\" />\n// </MultiColumn.Columns>\n//\n// <MultiColumn.CTAs>\n// <CTA label=\"저장하기\" variable=\"default\" />\n// </MultiColumn.CTAs>\n//</MultiColumn>\n\nimport React, { ReactNode } from \"react\";\nimport { cn } from \"../../lib/cn\"; // 사용 중인 유틸리티 경로에 맞게 수정\n\ninterface BaseProps {\n children: ReactNode;\n className?: string;\n}\n\n// 1. 메인 래퍼 컴포넌트 (전체 컨테이너)\nconst MultiColumnMain = ({ children, className }: BaseProps) => {\n return <div className={cn(\"flex flex-col w-full h-full\", className)}>{children}</div>;\n};\n\n// 2. 상단 Column 영역 컴포넌트 (2~3개 배치)\nconst Columns = ({ children, className }: BaseProps) => {\n return (\n // flex 래퍼를 사용하고 하위 Column들이 flex-1을 가지게 하거나,\n // grid를 사용하여 열을 나눌 수 있어. 여기서는 flex를 활용한 균등 분할 예시야.\n <div className={cn(\"flex w-full h-full divide-x divide-gray02\", className)}>{children}</div>\n );\n};\n\n// 3. 하단 CTA 영역 컴포넌트 (0~3개 배치)\nconst CTAs = ({ children, className }: BaseProps) => {\n // children이 없으면(CTA가 0개) 아예 렌더링하지 않음\n if (!children) return null;\n\n return (\n // CTA 버튼들을 중앙에 배치하는 예시 (우측 정렬이 필요하면 justify-end 사용)\n <div className={cn(\"flex flex-col w-full h-fit\", className)}>{children}</div>\n );\n};\n\n// 4. Object.assign을 통해 하나의 객체로 묶어주기\nexport const MultiColumn = Object.assign(MultiColumnMain, {\n Columns,\n CTAs,\n});\n","import { cn } from \"../../lib/cn\";\n\nexport interface ColumnProps {\n className?: string;\n children: React.ReactNode;\n /**\n * 컬럼 상단 제목. 생략하면 제목 영역을 렌더링하지 않으며,\n * 이 경우 children 안에서 `ColumnSubTitle`로 섹션 제목을 직접 배치할 수 있다.\n */\n header?: string;\n}\n\nexport const Column = ({ className, children, header }: ColumnProps) => {\n return (\n <div className={cn(\"flex flex-col gap-5\", \"h-full w-full px-5 pt-3 pb-8\", className)}>\n {header && <h1 className={cn(\"text-head3-medium text-primary font-bold\")}>{header}</h1>}\n {children}\n </div>\n );\n};\n","import { cn } from \"../../lib/cn\";\n\nexport interface ColumnContentContainerProps {\n className?: string;\n children: React.ReactNode;\n}\n\nexport const ColumnContentContainer = ({ className, children }: ColumnContentContainerProps) => {\n return <div className={cn(\"flex flex-col gap-1.5 w-full h-fit\", className)}>{children}</div>;\n};\n","import { cn } from \"../../lib/cn\";\n\nexport interface ColumnLabelProps {\n className?: string;\n children: string;\n subLabel?: string;\n htmlFor?: string;\n}\n\nexport const ColumnLabel = ({ className, children, subLabel, htmlFor }: ColumnLabelProps) => {\n return (\n <label htmlFor={htmlFor} className={cn(\"flex gap-1.5 items-end\", className)}>\n <span className={cn(\"text-body2-regular text-tertiary\")}>{children}</span>\n {subLabel && <span className={cn(\"text-caption-book text-quaternary\")}>{subLabel}</span>}\n </label>\n );\n};\n","import { cn } from \"../../lib/cn\";\n\nexport interface ColumnTextProps {\n className?: string;\n children?: string | React.ReactNode;\n onClick?: () => void;\n alert?: boolean;\n}\n\nexport const ColumnTextStyle = \"text-body3-book text-strong\";\nexport const ModalTextStyle = \"text-body1-regular text-primary\";\n\nexport const ColumnText = ({ className, alert = false, children, onClick }: ColumnTextProps) => {\n return (\n <div className={cn(ColumnTextStyle, alert && \"text-danger\", className)} onClick={onClick}>\n {children ? children : \"-\"}\n </div>\n );\n};\n","import { cn } from \"../../lib/cn\";\n\nexport interface ColumnSubTitleProps {\n className?: string;\n children: React.ReactNode;\n /** 우측에 부연 아이콘/버튼 등을 배치할 때 사용 (예: 도움말 아이콘) */\n action?: React.ReactNode;\n as?: \"h2\" | \"h3\" | \"h4\" | \"header\";\n}\n\n/**\n * Column 내부의 섹션 구분용 부제목.\n * 예: \"예약 정보\", \"예약자 정보\", \"예약 시 주의사항\"\n */\nexport const ColumnSubTitle = ({\n className,\n children,\n action,\n as: Tag = \"h2\",\n}: ColumnSubTitleProps) => {\n return (\n <Tag className={cn(\"flex items-center justify-between gap-1.5\", \"w-full\", className)}>\n <span className={cn(\"text-head3-medium text-strong\")}>{children}</span>\n {action && <span className=\"flex shrink-0 items-center\">{action}</span>}\n </Tag>\n );\n};\n","// src/components/.../FormField.tsx\n\nimport { cn } from \"../../lib/cn\";\nimport { ColumnTextStyle } from \"../Column/ColumnText\";\n\n// 1. 공통 Wrapper용 Props\nexport interface BasicFormFieldProps {\n children: React.ReactNode;\n isDanger?: boolean;\n dangerText?: string;\n className?: string; // 제일 바깥 div에 줄 클래스\n}\n\n// 2. 공통 에러 메시지 & 레이아웃 Wrapper 컴포넌트\nexport const BasicFormField = ({\n children,\n isDanger,\n dangerText,\n className,\n}: BasicFormFieldProps) => {\n return (\n <div className={cn(\"flex flex-col gap-1.5\", className)}>\n {children}\n {isDanger && dangerText && (\n <span className=\"text-caption-book text-danger\">{dangerText}</span>\n )}\n </div>\n );\n};\n\n// 3. 인풋 공통 스타일 생성 함수 (cn을 이용해 병합)\nexport const getInputStyles = (isDanger?: boolean, additionalClass?: string) => {\n return cn(\n \"w-full h-10 px-3\",\n \"box-border border border-gray02 focus:outline-none focus:border-black\",\n \"bg-white hover:bg-gray00 transition-colors focus:hover:bg-white\",\n ColumnTextStyle,\n \"text-primary placeholder:text-quaternary\",\n isDanger && \"border-danger\", // 에러 시 빨간 테두리\n additionalClass, // 각 인풋별 추가 스타일 (예: textarea의 h-30)\n );\n};\n","import { BasicFormField, getInputStyles } from \"./BasicFormField\";\n\nexport interface FormTextProps extends React.InputHTMLAttributes<HTMLInputElement> {\n isDanger?: boolean;\n dangerText?: string;\n}\n\nexport const FormText = ({ className, isDanger, dangerText, ...props }: FormTextProps) => {\n return (\n <BasicFormField isDanger={isDanger} dangerText={dangerText}>\n <input type=\"text\" className={getInputStyles(isDanger, className)} {...props} />\n </BasicFormField>\n );\n};\n","import { BasicFormField, getInputStyles } from \"./BasicFormField\";\n\nexport interface FormTextAreaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {\n isDanger?: boolean;\n dangerText?: string;\n}\n\nexport const FormTextArea = ({ className, isDanger, dangerText, ...props }: FormTextAreaProps) => {\n return (\n <BasicFormField isDanger={isDanger} dangerText={dangerText}>\n <textarea\n // 💡 cn() 유틸리티 덕분에 getInputStyles의 기본 h-10을 h-30이 깔끔하게 덮어씁니다!\n className={getInputStyles(isDanger, \"resize-none h-30 py-2.5 \" + (className || \"\"))}\n {...props}\n />\n </BasicFormField>\n );\n};\n","import { BasicFormField, getInputStyles } from \"./BasicFormField\";\n\nexport interface FormNumberProps extends React.InputHTMLAttributes<HTMLInputElement> {\n isDanger?: boolean;\n dangerText?: string;\n}\n\nexport const FormNumber = ({ className, isDanger, dangerText, ...props }: FormNumberProps) => {\n return (\n <BasicFormField isDanger={isDanger} dangerText={dangerText}>\n <input type=\"number\" className={getInputStyles(isDanger, className)} {...props} />\n </BasicFormField>\n );\n};\n","import { BasicFormField, getInputStyles } from \"./BasicFormField\";\n\nexport interface FormPasswordProps extends React.InputHTMLAttributes<HTMLInputElement> {\n isDanger?: boolean;\n dangerText?: string;\n}\n\nexport const FormPassword = ({ className, isDanger, dangerText, ...props }: FormPasswordProps) => {\n return (\n <BasicFormField isDanger={isDanger} dangerText={dangerText}>\n <input type=\"password\" className={getInputStyles(isDanger, className)} {...props} />\n </BasicFormField>\n );\n};\n","import { BasicFormField, getInputStyles } from \"./BasicFormField\";\n\nexport interface FormTelProps extends React.InputHTMLAttributes<HTMLInputElement> {\n isDanger?: boolean;\n dangerText?: string;\n}\n\nexport const FormTel = ({ className, isDanger, dangerText, onChange, ...props }: FormTelProps) => {\n const handlePhoneChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const rawValue = e.target.value.replace(/[^0-9]/g, \"\");\n let formattedValue = \"\";\n if (rawValue.length < 4) formattedValue = rawValue;\n else if (rawValue.length < 8) formattedValue = `${rawValue.slice(0, 3)}-${rawValue.slice(3)}`;\n else\n formattedValue = `${rawValue.slice(0, 3)}-${rawValue.slice(3, 7)}-${rawValue.slice(7, 11)}`;\n\n e.target.value = formattedValue;\n if (onChange) onChange(e);\n };\n\n return (\n <BasicFormField isDanger={isDanger} dangerText={dangerText}>\n <input\n type=\"tel\"\n className={getInputStyles(isDanger, className)}\n onChange={handlePhoneChange}\n maxLength={13}\n {...props}\n />\n </BasicFormField>\n );\n};\n","import { useState } from \"react\";\nimport { BasicFormField, getInputStyles } from \"./BasicFormField\";\n\nexport interface FormColorProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, \"type\"> {\n isDanger?: boolean;\n dangerText?: string;\n}\n\nexport const FormColor = ({\n className,\n isDanger,\n dangerText,\n value,\n defaultValue = \"#000000\",\n onChange,\n ...props\n}: FormColorProps) => {\n const [internalColor, setInternalColor] = useState<string>(\n (value as string) || (defaultValue as string) || \"#000000\",\n );\n\n // value가 주어지면(제어 컴포넌트) 항상 그 값을 사용하고, 아니면 내부 상태를 사용\n const color = value !== undefined ? (value as string) : internalColor;\n\n const handleColorChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n setInternalColor(e.target.value);\n onChange?.(e);\n };\n\n return (\n <BasicFormField isDanger={isDanger} dangerText={dangerText}>\n <label\n className={getInputStyles(\n isDanger,\n // 💡 focus-within을 통해 내부 <input>이 포커스될 때 부모(label)의 테두리와 배경 변경!\n \"flex items-center gap-2 relative \" +\n \"focus-within:border-black focus-within:hover:bg-white\" +\n (className || \"\"),\n )}\n >\n {/* 1. 좌측: 색상 스와치 (Color Swatch) */}\n <div className=\"w-6 h-6 shrink-0 overflow-hidden\" style={{ backgroundColor: color }}>\n <input\n type=\"color\"\n value={color}\n onChange={handleColorChange}\n className=\"absolute inset-0 w-full h-full opacity-0\"\n {...props}\n />\n </div>\n\n {/* 2. 중간: 색상 코드 텍스트 */}\n <span className=\"text-primary text-body3-regular uppercase flex-1 select-none\">\n {color}\n </span>\n\n {/* 3. 우측: 추후 아이콘 자리 */}\n </label>\n </BasicFormField>\n );\n};\n","import { useState } from \"react\";\nimport { BasicFormField, getInputStyles } from \"./BasicFormField\";\n\nexport interface FormFileProps extends Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n \"onChange\"\n> {\n isDanger?: boolean;\n dangerText?: string;\n fileUrl?: string; // 기존에 서버에 업로드된 파일 주소\n filename?: string; // 💡 변경할 파일 이름 prop (확장자는 자동 유지)\n onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;\n}\n\nexport const FormFile = ({\n className,\n isDanger,\n dangerText,\n placeholder = \"파일을 선택해주세요\",\n fileUrl,\n filename,\n onChange,\n ...props\n}: FormFileProps) => {\n const [selectedFile, setSelectedFile] = useState<File | null>(null);\n\n // 💡 파일 선택 및 파일명 변경 핸들러\n const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const originalFile = e.target.files?.[0];\n\n if (!originalFile) {\n setSelectedFile(null);\n onChange?.(e);\n return;\n }\n\n let finalFile = originalFile;\n\n // filename prop이 넘어왔을 경우 파일명 변경 로직\n if (filename) {\n const lastDotIndex = originalFile.name.lastIndexOf(\".\");\n const extension = lastDotIndex !== -1 ? originalFile.name.slice(lastDotIndex) : \"\";\n const newFileName = filename.endsWith(extension) ? filename : `${filename}${extension}`;\n\n finalFile = new File([originalFile], newFileName, {\n type: originalFile.type,\n lastModified: originalFile.lastModified,\n });\n\n try {\n const dataTransfer = new DataTransfer();\n dataTransfer.items.add(finalFile);\n e.target.files = dataTransfer.files;\n } catch (err) {\n console.warn(\"DataTransfer를 지원하지 않는 브라우저입니다.\", err);\n }\n }\n\n setSelectedFile(finalFile);\n onChange?.(e);\n };\n\n // 💡 파일 다운로드 통합 핸들러\n const handleDownload = (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n if (selectedFile) {\n const url = URL.createObjectURL(selectedFile);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = selectedFile.name;\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n URL.revokeObjectURL(url);\n } else if (fileUrl) {\n const a = document.createElement(\"a\");\n a.href = fileUrl;\n a.download = fileUrl.split(\"/\").pop() || \"download\";\n a.target = \"_blank\";\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n }\n };\n\n // 화면에 표시할 파일 이름 (변경된 로컬 파일명 또는 서버 파일명)\n const displayFileName = selectedFile?.name || (fileUrl ? fileUrl.split(\"/\").pop() : null);\n\n return (\n <BasicFormField isDanger={isDanger} dangerText={dangerText}>\n <div\n className={getInputStyles(\n isDanger,\n \"active:bg-gray00 flex items-center gap-2 justify-between \" + (className || \"\"),\n )}\n >\n {/* 좌측: 파일명 또는 Placeholder */}\n <div\n className={`truncate flex-1 max-w-50 w-full ${displayFileName ? \"text-primary\" : \"text-quaternary\"}`}\n >\n {displayFileName ? (\n <span\n onClick={handleDownload}\n className=\"w-full underline text-primary cursor-pointer hover:text-black transition-colors\"\n title={`${displayFileName} 다운로드`}\n >\n {displayFileName}\n </span>\n ) : (\n <span className=\"w-full\">{placeholder}</span>\n )}\n </div>\n\n {/* 우측: 파일 선택 버튼 */}\n <label className=\"px-1 -mx-1 cursor-pointer\">\n <div className=\"text-primary text-caption-regular underline\">파일 첨부</div>\n <input type=\"file\" className=\"hidden\" onChange={handleFileChange} {...props} />\n </label>\n </div>\n </BasicFormField>\n );\n};\n","import { cn } from \"../../lib/cn\";\nimport { IconCheck } from \"../../assets/svgs/Icons\";\nimport { ColumnTextStyle } from \"../Column/ColumnText\";\n\nexport interface FormCheckBoxProps extends Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n \"onChange\" | \"checked\"\n> {\n isChecked: boolean;\n setIsChecked: (checked: boolean) => void;\n children?: React.ReactNode; // 💡 string 대신 ReactNode로 확장성 증가\n className?: string;\n textStyle?: string;\n}\n\nexport const FormCheckBox = ({\n isChecked,\n setIsChecked,\n children,\n className,\n textStyle,\n ...props\n}: FormCheckBoxProps) => {\n return (\n <label\n className={cn(\n \"w-fit h-fit pr-1\",\n \"flex items-center gap-1\",\n \"hover:bg-gray00 active:bg-gray01 transition-colors\",\n \"cursor-pointer select-none\", // 💡 1. 텍스트 드래그 방지 추가\n className,\n )}\n >\n <input\n type=\"checkbox\"\n checked={isChecked}\n onChange={(e) => setIsChecked(e.target.checked)}\n className=\"sr-only peer\" // 💡 2. peer 추가 (키보드 포커스 감지용)\n {...props}\n />\n\n <div className=\"flex items-center justify-center w-5 h-5 shrink-0\">\n <div\n className={cn(\n \"w-[15px] h-[15px]\",\n \"box-border border\",\n \"flex items-center justify-center transition-colors duration-200\",\n\n // 💡 3. 키보드 Tab 이동 시 접근성 향상 (포커스 링 표시)\n \"peer-focus-visible:ring-2 peer-focus-visible:ring-black peer-focus-visible:ring-offset-1\",\n )}\n >\n {isChecked && <IconCheck />}\n </div>\n </div>\n\n {/* 💡 5. children이 전달되었을 때만 span을 렌더링하도록 조건부 처리 */}\n {children && <span className={cn(ColumnTextStyle, textStyle)}>{children}</span>}\n </label>\n );\n};\n","import { useEffect, useRef, useState } from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport { BasicFormField, getInputStyles } from \"./BasicFormField\";\nimport { SelectBoxOption } from \"./SelectBoxOption\";\nimport { IconChevronDownXS } from \"../../assets/svgs/Icons\";\n\nexport interface FormSelectBoxProps {\n options: string[];\n value: string;\n onChange: (option: string) => void;\n placeholder?: string;\n isDanger?: boolean;\n dangerText?: string;\n className?: string;\n}\n\nexport const FormSelectBox = ({\n options,\n value,\n onChange,\n placeholder = \"선택해주세요\",\n isDanger,\n dangerText,\n className,\n}: FormSelectBoxProps) => {\n const [isOpen, setIsOpen] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n\n // 외부 클릭 시 드롭다운 닫기\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(event.target as Node)) {\n setIsOpen(false);\n }\n };\n\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () => {\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, []);\n\n return (\n <BasicFormField isDanger={isDanger} dangerText={dangerText}>\n {/* 상대 위치(relative)의 기준점이 되는 컨테이너 */}\n <div ref={containerRef} className=\"relative w-full\">\n {/* 1. Select Box 트리거 (Input과 똑같이 생겨야 함!) */}\n <div\n tabIndex={0} // 💡 포커스를 받을 수 있게 설정\n className={getInputStyles(\n isDanger,\n cn(\n \"flex items-center justify-between cursor-pointer select-none\",\n isOpen && \"border-black\", // 💡 열려있을 때는 테두리를 검은색으로 고정 (포커스 효과)\n className,\n ),\n )}\n onClick={(e) => {\n if (isOpen) {\n e.currentTarget.blur(); // 💡 닫힐 때는 포커스(Focus)를 강제로 해제합니다!\n }\n setIsOpen((prev) => !prev);\n }}\n >\n {/* 선택값이 있으면 검은색(primary), 없으면 회색(quaternary) Placeholder 표시 */}\n <span className={value ? \"text-primary\" : \"text-quaternary\"}>{value || placeholder}</span>\n {/* 💡 보너스: 열려있을 때 아이콘 180도 회전 애니메이션 */}\n <IconChevronDownXS\n className={cn(\"text-gray06 transition-transform\", isOpen && \"rotate-180\")}\n stroke=\"currentColor\"\n />\n {/* <img\n src={chevronDown}\n alt=\"dropdown\"\n className={cn(\"transition-transform\", isOpen && \"rotate-180\")}\n /> */}\n </div>\n\n {/* 2. Dropdown 메뉴 리스트 */}\n {isOpen && (\n <ul\n className={cn(\n \"absolute top-full left-0 right-0 z-10\", // 💡 Input 바로 아래에 띄움\n \"box-border border border-gray02 bg-white flex flex-col\",\n \"max-h-50 overflow-y-auto shadow-sm\", // 💡 항목이 너무 많으면 스크롤 생성\n )}\n >\n {options.map((option) => (\n <SelectBoxOption\n key={option}\n label={option}\n // value={value}\n onClick={() => {\n onChange(option);\n setIsOpen(false); // 선택 후 자동으로 닫힘\n }}\n />\n ))}\n </ul>\n )}\n </div>\n </BasicFormField>\n );\n};\n","import { cn } from \"../../lib/cn\";\n\nexport interface SelectBoxOptionProps {\n label: string;\n onClick: () => void;\n // selectedLabel: string;\n className?: string;\n}\n\nexport const SelectBoxOption = ({\n label,\n onClick,\n // selectedLabel,\n className,\n}: SelectBoxOptionProps) => {\n // const isSelected = label === selectedLabel;\n return (\n <li\n onClick={onClick}\n className={cn(\n \"w-full h-11 px-3 shrink-0\",\n \"flex items-center justify-start\",\n // \"box-border border-b border-gray02\",\n \"text-body3-book text-primary\",\n \"bg-white hover:bg-gray00 active:bg-gray01\",\n // isSelected\n // ? \"bg-black text-white\"\n // : \"\",\n className,\n )}\n >\n {label}\n </li>\n );\n};\n","import { cn } from \"../../lib/cn\";\n\ntype CommonProps = {\n children: React.ReactNode;\n /** 텍스트 앞/뒤에 붙는 아이콘 (예: 도움말 ⓘ, 경고 아이콘) */\n icon?: React.ReactNode;\n iconPosition?: \"left\" | \"right\";\n /** 위험/경고 강조 색상 */\n alert?: boolean;\n /** 밑줄 표시 여부 (기본 true) */\n underline?: boolean;\n className?: string;\n};\n\nexport type TextButtonProps = CommonProps &\n (\n | ({ href: string } & Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, keyof CommonProps>)\n | ({ href?: undefined } & Omit<\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n keyof CommonProps\n >)\n );\n\n/**\n * 인라인 텍스트 버튼/링크.\n * 예: \"파일 제작 가이드\", \"파일 첨부\", \"더 보기\", \"다시 시도\"\n */\nexport const TextButton = ({\n children,\n icon,\n iconPosition = \"left\",\n alert = false,\n underline = true,\n className,\n ...props\n}: TextButtonProps) => {\n const content = (\n <>\n {icon && iconPosition === \"left\" && (\n <span className=\"flex shrink-0 items-center\">{icon}</span>\n )}\n <span className={cn(underline && \"underline underline-offset-2\")}>{children}</span>\n {icon && iconPosition === \"right\" && (\n <span className=\"flex shrink-0 items-center\">{icon}</span>\n )}\n </>\n );\n\n const classes = cn(\n \"inline-flex w-fit items-center gap-1 px-1 -mx-1\",\n \"text-caption-book\",\n alert ? \"text-danger\" : \"text-tertiary\",\n \"hover:bg-gray00 active:bg-gray01 transition-colors\",\n alert ? \"hover:text-danger\" : \"hover:text-primary\",\n \"cursor-pointer select-none\",\n \"disabled:cursor-default disabled:text-quaternary disabled:hover:bg-transparent\",\n \"aria-disabled:cursor-default aria-disabled:text-quaternary aria-disabled:hover:bg-transparent\",\n className,\n );\n\n if (props.href !== undefined) {\n const { href, ...rest } = props as React.AnchorHTMLAttributes<HTMLAnchorElement> & {\n href: string;\n };\n return (\n <a href={href} className={classes} {...rest}>\n {content}\n </a>\n );\n }\n\n const buttonProps = props as React.ButtonHTMLAttributes<HTMLButtonElement>;\n return (\n <button type=\"button\" className={classes} {...buttonProps}>\n {content}\n </button>\n );\n};\n","import { useEffect, useRef, useState } from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport { SelectBoxOption } from \"../Form/SelectBoxOption\";\nimport { IconChevronDownXS } from \"../../assets/svgs/Icons\";\n\nexport interface DropdownProps {\n selectedLabel: string;\n setSelectedLabel: (label: string) => void;\n labels: string[];\n className?: string;\n}\n\nexport const Dropdown = ({ selectedLabel, setSelectedLabel, labels, className }: DropdownProps) => {\n const [isOpen, setIsOpen] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(event.target as Node)) {\n setIsOpen(false);\n }\n };\n\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () => {\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, []);\n\n return (\n <div ref={containerRef} className=\"relative\">\n <div\n className={cn(\n \"w-fit h-fit px-2 py-1\",\n \"flex items-center justify-center gap-1.5\",\n \"text-body3-book text-strong\",\n \"bg-white hover:bg-gray00 active:bg-gray01\",\n \"cursor-pointer\",\n className,\n )}\n onClick={() => setIsOpen((prev) => !prev)}\n >\n <p>{selectedLabel}</p>\n <IconChevronDownXS\n className={cn(\"text-gray06 transition-transform\", isOpen && \"rotate-180\")}\n stroke=\"currentColor\"\n />\n </div>\n {isOpen && (\n <div className={cn(\"absolute top-full right-0 z-10\", \"box-border border border-gray02\")}>\n {labels.map((label) => (\n <SelectBoxOption\n key={label}\n label={label}\n // selectedLabel={selectedLabel}\n onClick={() => {\n setSelectedLabel(label);\n setIsOpen(false);\n }}\n className=\"w-44 h-11 justify-center\" // 💡 부모 Input의 가로 너비에 꽉 차도록 설정\n />\n ))}\n </div>\n )}\n </div>\n );\n};\n","import { cn } from \"../../lib/cn\";\n// 💡 TagProps를 꼭 같이 import 해주세요!\nimport type { TagProps } from \"../Tag/Tag\";\n\n// 1. 기본 HTMLAttributes에서 'children' 속성을 제외(Omit)합니다.\nexport interface ListProps extends Omit<React.HTMLAttributes<HTMLLIElement>, \"children\"> {\n className?: string;\n label1?: string;\n label2?: string;\n label2OnClick?: () => void;\n label3?: string;\n disabled?: boolean;\n selected?: boolean;\n onClick?: () => void;\n children?: React.ReactElement<TagProps> | React.ReactElement<TagProps>[];\n}\n\nexport function List({\n className,\n label1,\n label2,\n label2OnClick,\n label3,\n disabled = false,\n selected = false,\n onClick,\n children,\n ...props\n}: ListProps) {\n return (\n <li\n className={cn(\n \"w-full min-w-fit h-13 pl-4 pr-6\",\n \"grid grid-cols-[4fr_1fr_1fr] items-center gap-4\",\n \"bg-white hover:bg-gray00 hover:has-[.has-clickable:hover]:bg-white active:bg-gray01\",\n \"text-primary select-none [&_*]:cursor-pointer cursor-pointer\",\n disabled && \"opacity-40 [&_*]:cursor-pointer cursor-pointer\",\n selected &&\n \"bg-black text-white hover:bg-black active:bg-black hover:has-[.has-clickable:hover]:bg-black\",\n className,\n )}\n {...props}\n onClick={onClick}\n // onClickCapture={(e) => {\n // if (disabled) {\n // e.stopPropagation();\n // e.preventDefault();\n // }\n // }}\n >\n <section className={cn(\"flex items-center gap-4\")}>\n <label className={cn(\"text-body2-regular\")}>{label1 ? label1 : \"-\"}</label>\n <div className={cn(\"flex items-center gap-2\")}>\n {/* 3. 들어온 children을 그대로 렌더링합니다. */}\n {children}\n </div>\n </section>\n <label\n className={cn(\n \"text-body3-book truncate p-1 w-fit\",\n label2OnClick && \"underline has-clickable\",\n label2OnClick && !selected && \"hover:bg-gray00\",\n )}\n onClick={label2OnClick}\n >\n {label2 ? label2 : \"-\"}\n </label>\n <label className={cn(\"text-body3-regular text-right\")}>{label3 ? label3 : \"-\"}</label>\n </li>\n );\n}\n","import React from \"react\";\nimport { cn } from \"../../lib/cn\";\n\nexport interface ModalProps {\n isVisible: boolean;\n header: string;\n children: React.ReactNode;\n className?: string;\n}\n\ninterface BaseProps {\n children: React.ReactNode;\n className?: string;\n row?: boolean;\n}\n\nconst ModalBase = ({ isVisible, header, children, className }: ModalProps) => {\n if (!isVisible) return null;\n return (\n <div className={cn(\"fixed inset-0 z-50 pointer-events-auto\")}>\n <div\n className={cn(\"fixed inset-0 z-1001 flex items-center justify-center pointer-events-auto\")}\n >\n <main\n className={cn(\n \"w-110 pt-8 h-fit\",\n \"flex flex-col items-center\",\n \"border border-gray02\",\n \"bg-white shadow-[0 0 30px 0 rgba(0, 0, 0, 0.08);]\",\n className,\n )}\n >\n <h1 className={cn(\"text-strong font-[500] text-[24px] leading-[32px]\")}>{header}</h1>\n {children}\n </main>\n </div>\n </div>\n );\n};\n\nconst Contents = ({ children, className }: BaseProps) => {\n return (\n <div\n className={cn(\n \"flex flex-col items-center gap-8\",\n \"w-full h-fit\",\n \"px-14 pt-8 pb-9\",\n className,\n )}\n >\n {children}\n </div>\n );\n};\n\nconst CTAs = ({ children, className, row = false }: BaseProps) => {\n // children이 없으면(CTA가 0개) 아예 렌더링하지 않음\n if (!children) return null;\n\n return (\n // CTA 버튼들을 중앙에 배치하는 예시 (우측 정렬이 필요하면 justify-end 사용)\n <div\n className={cn(\n \"flex flex-col w-full h-fit\",\n row && \"flex-row divide-x divide-gray02\",\n className,\n )}\n >\n {children}\n </div>\n );\n};\n\nexport const Modal = Object.assign(ModalBase, {\n Contents,\n CTAs,\n});\n","import { cn } from \"../../lib/cn\";\nimport { ModalTextStyle } from \"../Column/ColumnText\";\n\nexport interface ModalTextProps {\n children: React.ReactNode;\n className?: string;\n}\n\nexport const ModalText = ({ children, className }: ModalTextProps) => {\n return (\n <div\n className={cn(\n \"flex flex-col items-center\",\n \"mt-[-20px] mb-[-4px]\",\n ModalTextStyle,\n \"text-tertiary text-center\",\n className,\n )}\n >\n {children}\n </div>\n );\n};\n","import { cn } from \"../../lib/cn\";\n\nexport interface CategorySegmentProps {\n selected?: boolean;\n label: string;\n className?: string;\n onClick?: () => void;\n}\n\nexport const CategorySegment = ({\n selected = false,\n label,\n className,\n onClick,\n}: CategorySegmentProps) => {\n return (\n <div\n className={cn(\n \"w-fit h-8 px-3.5\",\n \"flex items-center justify-center\",\n // 피그마랑 조금 다르게 적용하였음. 이게 더 효율적\n \"border-r border-gray02 cursor-pointer\",\n \"text-body3-book text-strong\",\n selected\n ? \"bg-black text-white\" // selected 상태\n : \"bg-white text-strong hover:bg-gray00 active:bg-gray01\", // default, hover, pressed 상태\n className,\n )}\n onClick={onClick}\n >\n {label}\n </div>\n );\n};\n","import { cn } from \"../../lib/cn\";\nimport { CategorySegment } from \"./CategorySegment\";\n\nexport interface CategorySegmentedControlProps {\n variable: \"info\" | \"archive\" | \"notice\" | \"infoTag\";\n setSelectedCategory: (label: string) => void;\n selectedCategory: string;\n className?: string;\n}\n\nconst categorySegments: Record<CategorySegmentedControlProps[\"variable\"], string[]> = {\n info: [\"공용 물품\", \"일반 기자재\", \"특수 기자재\"],\n archive: [\"프린트실\", \"홍익시디\"],\n notice: [\"일반 공지\", \"긴급 공지\"],\n infoTag: [\"가공\", \"제본\", \"출력\", \"스캔\", \"기타\"],\n};\n\nexport const CategorySegmentedControl = ({\n variable,\n setSelectedCategory,\n selectedCategory,\n className,\n}: CategorySegmentedControlProps) => {\n const segments = categorySegments[variable];\n\n return (\n <div className={cn(\"w-full h-fit flex items-center justify-start\", className)}>\n <div\n className={cn(\n \"w-fit h-8 px-3.5\",\n \"flex items-center justify-center\",\n // 피그마랑 조금 다르게 적용하였음. 이게 더 효율적\n \"border-r border-gray02\",\n \"text-body3-medium text-strong\",\n )}\n >\n {variable === \"infoTag\" ? \"태그 선택\" : \"카테고리 선택\"}\n </div>\n {segments.map((label) => (\n <CategorySegment\n key={label}\n label={label}\n selected={selectedCategory === label}\n onClick={() => setSelectedCategory(label)}\n />\n ))}\n </div>\n );\n};\n","import { cn } from \"../../lib/cn\";\n\nexport interface TitleInputProps {\n title?: string;\n onChange: (value: string) => void;\n className?: string;\n}\n\nexport const TitleInput = ({ title, onChange, className }: TitleInputProps) => {\n return (\n <input\n type=\"text\"\n value={title}\n onChange={(e) => onChange(e.target.value)}\n placeholder=\"제목을 입력하세요\"\n className={cn(\n \"w-full min-w-[200px] h-12 px-3\",\n // 피그마랑 매우 다름. focus되었을 때 테두리 중복 문제 등\n \"box-border border-b border-gray02 border-t border-t-white\",\n \"focus:border-black focus:border focus:outline-none\",\n \"text-head2-medium text-strong placeholder:text-gray03\",\n className,\n )}\n />\n );\n};\n","import { cn } from \"../../lib/cn\";\n\nexport interface NoticeBadgeProps {\n variable: NoticeBadgeVariable;\n className?: string;\n onClick?: () => void;\n}\n\nexport type NoticeBadgeVariable = \"urgent\" | \"common\";\n\nexport const NoticeBadge = ({ variable, className, onClick }: NoticeBadgeProps) => {\n return (\n <button\n type=\"button\"\n className={cn(\n // 너비 피그마에서는 fit으로 69px로 되어있는데, 69px로 하면 글자가 잘려서 72px로 잡음. 컨펌 필요\n \"w-18 h-8 box-border px-2 py-1 text-center text-body3-book cursor-pointer\",\n /** Urgent */ `${variable === \"urgent\" ? \"bg-black text-white\" : \"\"}`,\n /** Common */ `${variable === \"common\" ? \"border border-gray03 text-strong\" : \"\"}`, //이거 배경 없는 거 맞겠지...?\n className,\n )}\n onClick={onClick}\n >\n {variable === \"urgent\" ? \"긴급 공지\" : \"일반 공지\"}\n </button>\n );\n};\n","import { cn } from \"../../lib/cn\";\nimport { NoticeBadge } from \"./NoticeBadge\";\n\nexport interface NoticeBarProps {\n variable: NoticeBarVariable;\n badgeVariable: NoticeBarBadgeVariable;\n title: string;\n date: string;\n className?: string;\n onClick?: () => void;\n}\n\nexport type NoticeBarVariable = \"default\" | \"hover\" | \"pressed\";\nexport type NoticeBarBadgeVariable = \"urgent\" | \"common\";\n\nexport const NoticeBar = ({\n variable = \"default\",\n badgeVariable,\n title,\n date,\n className,\n onClick,\n}: NoticeBarProps) => {\n return (\n <div\n // 최소 너비 임시로 적어둠 -> 수정 요망!\n className={cn(\n \"w-full min-w-200 h-15 px-4 py-3.5 flex items-center justify-between box-border border-b border-gray02 cursor-pointer\",\n variable === \"default\" && \"bg-white hover:bg-gray00 active:bg-gray01\",\n variable === \"hover\" && \"bg-gray00\",\n variable === \"pressed\" && \"bg-gray01\",\n className,\n )}\n onClick={onClick}\n >\n <section className=\"flex items-center gap-3\">\n <NoticeBadge variable={badgeVariable} />\n <h1 className=\"text-head1-medium text-strong\">{title}</h1>\n </section>\n {/* 이거 나중에 수정해야함 */}\n <p className=\"text-body3-book text-tertiary\">{date}</p>\n </div>\n );\n};\n","import { cn } from \"../../lib/cn\";\nimport { IconSearch } from \"../../assets/svgs/Icons\";\n\nexport interface SearchBarProps {\n value?: string;\n onChange?: (value: string) => void;\n className?: string;\n}\n\nexport const SearchBar = ({ value, onChange, className }: SearchBarProps) => {\n return (\n <label\n className={cn(\n \"w-full h-12 pl-4 pr-3\",\n \"flex items-center gap-2\",\n \"box-border border-b border-gray02 border-t border-t-white\",\n \"focus-within:border-black focus-within:border focus-within:outline-none\",\n className,\n )}\n >\n <IconSearch />\n <input\n type=\"text\"\n placeholder=\"검색어를 입력해주세요\"\n value={value}\n onChange={(e) => onChange?.(e.target.value)}\n className={cn(\n \"w-full focus:outline-none\",\n \"text-body1-book text-strong placeholder:text-quaternary\",\n )}\n />\n </label>\n );\n};\n","import { forwardRef, type CSSProperties } from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport { useControllableState } from \"../../lib/useControllableState\";\nimport Exclamation from \"./Exclamation.svg\";\nimport ChevronDown from \"./ChevronDown.svg\";\nimport RadioSelectedIcon from \"./RadioSelected.svg\";\nimport RadioUnselectedIcon from \"./RadioUnselected.svg\";\n\nexport type PrintColor =\n \"Plotter\" | \"Printer\" | \"Riso\" | \"Fluorescent\" | \"UV\" | \"Seet Cutting\" | \"Laser Cutting\";\n\n// Tailwind는 클래스 이름을 정적 문자열로만 인식하므로 `bg-${...}` 같은 템플릿\n// 조합은 빌드 시 클래스가 생성되지 않는다(퍼지됨). 그래서 색상별 클래스를 전부 나열해둔다.\nconst printColorBgClass: Record<PrintColor, string> = {\n Plotter: \"bg-print-plotter\",\n Printer: \"bg-print-printer\",\n Riso: \"bg-print-riso\",\n Fluorescent: \"bg-print-fluorescent\",\n UV: \"bg-print-uv\",\n \"Seet Cutting\": \"bg-print-seet-cutting\",\n \"Laser Cutting\": \"bg-print-laser-cutting\",\n};\n\nexport type RadioToggle = {\n title: string;\n content: string;\n /**\n * 선택 상태를 식별할 값. 표시 텍스트(title)와 분리하고 싶을 때 사용한다.\n * 생략하면 title이 식별자로 쓰인다. onSelect도 이 값을 넘겨준다.\n */\n value?: string;\n badges?: string[];\n /** 선택됐을 때 라디오 행에 입힐 배경색(팔레트). `color`가 있으면 무시된다. */\n printColor?: PrintColor;\n /**\n * 선택됐을 때 라디오 행에 입힐 임의 배경색(hex/rgb/CSS 변수 등).\n * 고정 팔레트(printColor) 밖의 색이 필요할 때 사용한다.\n */\n color?: string;\n /** 라디오 행(button)에 덧붙일 클래스. 보더/그룹 구분 등 앱별 커스터마이징 훅. */\n className?: string;\n labelTextButton?: string;\n onClickTextButton?: () => void;\n};\n\nconst itemKey = (item: RadioToggle) => item.value ?? item.title;\n\nexport interface SideRadioAccordionProps {\n step: number;\n title: string;\n radioToggleList: RadioToggle[];\n /** controlled: 현재 선택된 항목의 value(없으면 title). `null`이면 미선택. */\n selected?: string | null;\n /** uncontrolled 초기 선택값. `selected`를 함께 주면 무시된다. */\n defaultSelected?: string;\n /** 선택이 바뀔 때 호출. 인자는 항목의 value(없으면 title). */\n onSelect?: (value: string) => void;\n /** 헤더(Stepper)를 스크롤 컨테이너 상단에 고정한다. */\n stickyHeader?: boolean;\n /** 헤더 클릭으로 접기/펼치기를 허용할지. false면 항상 펼쳐지고 chevron도 감춘다. 기본 true. */\n collapsible?: boolean;\n /** uncontrolled 펼침 초기값. 기본 true. */\n defaultOpen?: boolean;\n /** controlled 펼침 상태. */\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n quantityLimitLabel?: string;\n onClickQuantityLimit?: () => void;\n className?: string;\n}\n\nexport const SideRadioAccordion = forwardRef<HTMLDivElement, SideRadioAccordionProps>(\n function SideRadioAccordion(\n {\n step,\n title,\n radioToggleList,\n selected,\n defaultSelected,\n onSelect,\n stickyHeader = false,\n collapsible = true,\n defaultOpen = true,\n open,\n onOpenChange,\n quantityLimitLabel,\n onClickQuantityLimit,\n className,\n },\n ref,\n ) {\n const [selectedValue, setSelectedValue] = useControllableState<string | null>(\n selected,\n defaultSelected ?? null,\n );\n const [isOpen, setIsOpen] = useControllableState<boolean>(open, defaultOpen);\n const expanded = collapsible ? isOpen : true;\n\n const handleSelect = (value: string) => {\n setSelectedValue(value);\n onSelect?.(value);\n };\n\n const toggleOpen = () => {\n if (!collapsible) return;\n const next = !isOpen;\n setIsOpen(next);\n onOpenChange?.(next);\n };\n\n return (\n <div ref={ref} className={cn(\"w-full\", className)}>\n <Stepper\n step={step}\n title={title}\n isOpen={expanded}\n collapsible={collapsible}\n onClick={toggleOpen}\n className={cn(stickyHeader && \"sticky top-0 z-10\")}\n />\n {expanded && (\n <div className=\"flex flex-col\">\n {radioToggleList.map((item) => (\n <RadioToggleItem\n key={itemKey(item)}\n {...item}\n open={selectedValue === itemKey(item)}\n onSelect={() => handleSelect(itemKey(item))}\n />\n ))}\n {quantityLimitLabel && (\n <TextButton\n label={quantityLimitLabel}\n onClick={onClickQuantityLimit}\n className=\"mt-2\"\n />\n )}\n </div>\n )}\n </div>\n );\n },\n);\n\ninterface StepperProps {\n step: number;\n title: string;\n isOpen: boolean;\n collapsible: boolean;\n onClick: () => void;\n className?: string;\n}\nconst Stepper = ({ step, title, isOpen, collapsible, onClick, className }: StepperProps) => {\n const label = (\n <span>\n {step} | {title}\n </span>\n );\n const base =\n \"w-full flex items-center justify-between px-3 py-2.5 text-body1-medium text-strong text-left bg-white\";\n\n if (!collapsible) {\n return <div className={cn(base, className)}>{label}</div>;\n }\n\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className={cn(base, \"cursor-pointer hover:bg-gray00 active:bg-gray01\", className)}\n >\n {label}\n <img\n src={ChevronDown}\n alt=\"\"\n className={cn(\"transition-transform\", isOpen && \"rotate-180\")}\n />\n </button>\n );\n};\n\ninterface RadioToggleItemProps extends RadioToggle {\n open: boolean;\n onSelect: () => void;\n}\nconst RadioToggleItem = ({\n title,\n content,\n badges,\n printColor,\n color,\n className,\n labelTextButton,\n onClickTextButton,\n open,\n onSelect,\n}: RadioToggleItemProps) => {\n const rowBg = !open\n ? \"bg-white hover:bg-gray00\"\n : color\n ? undefined // 인라인 style이 배경을 담당\n : printColor\n ? printColorBgClass[printColor]\n : \"bg-gray00\";\n const style: CSSProperties | undefined = open && color ? { backgroundColor: color } : undefined;\n\n return (\n <div className=\"w-full\">\n <button\n type=\"button\"\n onClick={onSelect}\n style={style}\n className={cn(\n \"w-full flex items-center gap-1.5 px-3 py-2.5\",\n \"text-body2-regular text-primary text-left cursor-pointer\",\n rowBg,\n className,\n )}\n >\n <Radio selected={open} />\n <span>{title}</span>\n </button>\n {open && (\n <div className=\"flex flex-col gap-2 px-3 py-3 bg-white\">\n <p className=\"text-caption-regular text-secondary\">{content}</p>\n {badges && badges.length > 0 && (\n <div className=\"flex gap-1\">\n {badges.map((badge) => (\n <Badge key={badge} label={badge} />\n ))}\n </div>\n )}\n {labelTextButton && (\n <TextButton\n label={labelTextButton}\n onClick={onClickTextButton}\n showIcon\n className=\"self-end\"\n />\n )}\n </div>\n )}\n </div>\n );\n};\n\ninterface RadioProps {\n selected?: boolean;\n className?: string;\n}\nconst Radio = ({ selected = false, className }: RadioProps) => {\n return (\n <img\n src={selected ? RadioSelectedIcon : RadioUnselectedIcon}\n alt=\"\"\n className={cn(\"w-4 h-4\", className)}\n />\n );\n};\n\ninterface TextButtonProps {\n label: string;\n onClick?: () => void;\n showIcon?: boolean;\n className?: string;\n}\nconst TextButton = ({ label, onClick, showIcon = false, className }: TextButtonProps) => {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n disabled={!onClick}\n className={cn(\n \"w-fit h-fit px-1.5 py-0.5 flex items-center gap-1\",\n \"text-primary text-caption-regular underline\",\n onClick && \"cursor-pointer hover:bg-gray00 active:bg-gray01\",\n className,\n )}\n >\n {showIcon && <img src={Exclamation} alt=\"\" />}\n {label}\n </button>\n );\n};\n\ninterface BadgeProps {\n label?: string;\n className?: string;\n}\nconst Badge = ({ label, className }: BadgeProps) => {\n return (\n <div\n className={cn(\n \"w-fit h-fit px-2 py-0.5 border border-gray02\",\n \"text-tertiary text-caption-book\",\n className,\n )}\n >\n {label}\n </div>\n );\n};\n","import { useCallback, useState } from \"react\";\n\n/**\n * controlled/uncontrolled를 함께 지원하는 상태 훅.\n *\n * `controlled` 값이 `undefined`가 아니면(= `null` 포함) controlled로 간주하고\n * 내부 상태를 갱신하지 않는다. `undefined`면 uncontrolled로 동작한다.\n *\n * @returns `[value, setValue, isControlled]`\n */\nexport function useControllableState<T>(controlled: T | undefined, defaultValue: T) {\n const isControlled = controlled !== undefined;\n const [uncontrolled, setUncontrolled] = useState<T>(defaultValue);\n const value = isControlled ? (controlled as T) : uncontrolled;\n\n const setValue = useCallback(\n (next: T) => {\n if (!isControlled) setUncontrolled(next);\n },\n [isControlled],\n );\n\n return [value, setValue, isControlled] as const;\n}\n","import { cn } from \"../../lib/cn\";\n\nexport interface TagProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n className?: string;\n children: string | React.ReactNode;\n selected?: boolean;\n onClick?: () => void;\n bgColor?: string;\n}\n\nexport const Tag = ({\n className,\n children,\n selected = false,\n disabled = false,\n bgColor,\n onClick,\n ...props\n}: TagProps) => {\n return (\n <button\n className={cn(\n \"tag\",\n \"w-fit h-8 px-2.5\",\n \"text-primary text-body2-regular transition-colors\",\n \"box-border border border-gray02\",\n \"bg-white\",\n // bgColor && `bg-[${bgColor}] border-none`,\n onClick && \"cursor-pointer hover:bg-gray00 active:bg-gray01 cursor-pointer has-clickable\",\n selected && \"text-white bg-black border-black hover:bg-black active:bg-black\",\n \"disabled:text-gray04 disabled:bg-gray02 disabled:border-gray02 disabled:cursor-not-allowed\",\n className,\n )}\n onClick={onClick}\n disabled={disabled}\n style={bgColor ? { backgroundColor: bgColor, border: \"none\" } : undefined}\n {...props}\n >\n <span>{children}</span>\n </button>\n );\n};\n","import { forwardRef, type CSSProperties } from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport { WeekNavigation, type Week } from \"./WeekNavigation\";\nimport { formatDayLabel } from \"./dateUtils\";\n\nexport type PrintColor =\n \"Plotter\" | \"Printer\" | \"Riso\" | \"Fluorescent\" | \"UV\" | \"Seet Cutting\" | \"Laser Cutting\";\n\n// Tailwind는 클래스 이름을 정적 문자열로만 인식하므로 `hover:bg-${...}` 같은 템플릿\n// 조합은 빌드 시 클래스가 생성되지 않는다(퍼지됨). 그래서 색상별 클래스를 전부 나열해둔다.\nconst printColorHoverClass: Record<PrintColor, string> = {\n Plotter: \"hover:bg-print-plotter\",\n Printer: \"hover:bg-print-printer\",\n Riso: \"hover:bg-print-riso\",\n Fluorescent: \"hover:bg-print-fluorescent\",\n UV: \"hover:bg-print-uv\",\n \"Seet Cutting\": \"hover:bg-print-seet-cutting\",\n \"Laser Cutting\": \"hover:bg-print-laser-cutting\",\n};\n\nexport type TimeSlotState = \"none\" | \"default\" | \"disabled\" | \"selected\";\n\nexport interface TimeSlot {\n time: string;\n state: TimeSlotState;\n /** state가 \"default\"/\"selected\"일 때만 사용되는 hover 색상(팔레트). `color`가 있으면 무시. */\n printColor?: PrintColor;\n /** 고정 팔레트 밖의 임의 hover 색상(hex/rgb/CSS 변수 등). */\n color?: string;\n /** 셀(div)에 덧붙일 클래스. 보더/그룹 구분 등 앱별 커스터마이징 훅. */\n className?: string;\n}\n\nexport interface DayColumn {\n /** 해당 요일의 ISO 날짜(\"YYYY-MM-DD\") */\n date: string;\n slots: TimeSlot[];\n}\n\nexport interface TimetableProps {\n /** 표시 중인 주의 월요일(ISO \"YYYY-MM-DD\") */\n weekStart: string;\n week: Week;\n /** 월~금 5개, 왼쪽부터 순서대로 */\n days: DayColumn[];\n onPrevWeek?: () => void;\n onNextWeek?: () => void;\n onSelectSlot?: (date: string, time: string) => void;\n /**\n * true면 열 너비가 고정폭(72px) 대신 컨테이너 폭에 맞춰 균등하게 늘어난다.\n * 기존 고정폭 레이아웃이 필요하면 생략한다.\n */\n fluid?: boolean;\n /** 상단 주간 네비게이션을 숨긴다(외부에서 별도로 렌더링할 때). */\n hideWeekNavigation?: boolean;\n /** 주간 네비게이션의 이전/다음 버튼 노출을 명시적으로 제어(생략 시 week로 자동 판단). */\n canPrevWeek?: boolean;\n canNextWeek?: boolean;\n className?: string;\n}\n\nexport const Timetable = forwardRef<HTMLDivElement, TimetableProps>(function Timetable(\n {\n weekStart,\n week,\n days,\n onPrevWeek,\n onNextWeek,\n onSelectSlot,\n fluid = false,\n hideWeekNavigation = false,\n canPrevWeek,\n canNextWeek,\n className,\n },\n ref,\n) {\n return (\n <div ref={ref} className={cn(fluid && \"w-full\", className)}>\n {!hideWeekNavigation && (\n <WeekNavigation\n date={weekStart}\n week={week}\n canPrev={canPrevWeek}\n canNext={canNextWeek}\n onPrevWeek={onPrevWeek}\n onNextWeek={onNextWeek}\n />\n )}\n <div className={cn(\"flex\", fluid && \"w-full\")}>\n {days.map((day) => (\n <DailyTimetable\n key={day.date}\n date={day.date}\n slots={day.slots}\n fluid={fluid}\n onSelectTime={onSelectSlot ? (time) => onSelectSlot(day.date, time) : undefined}\n />\n ))}\n </div>\n </div>\n );\n});\n\ninterface DailyTimetableProps {\n date: string;\n slots: TimeSlot[];\n fluid?: boolean;\n onSelectTime?: (time: string) => void;\n className?: string;\n}\nconst DailyTimetable = ({ date, slots, fluid, onSelectTime, className }: DailyTimetableProps) => {\n return (\n <div className={cn(\"flex flex-col\", fluid ? \"flex-1 min-w-0\" : \"w-18\", className)}>\n <div className=\"h-13 flex items-center justify-center text-body3-medium text-secondary\">\n {formatDayLabel(date)}\n </div>\n {slots.map((slot) => (\n <TimeItem\n key={slot.time}\n state={slot.state}\n label={slot.time}\n printColor={slot.printColor}\n color={slot.color}\n fluid={fluid}\n className={slot.className}\n onClick={onSelectTime ? () => onSelectTime(slot.time) : undefined}\n />\n ))}\n </div>\n );\n};\n\ninterface TimeItemProps {\n state: TimeSlotState;\n label?: string;\n printColor?: PrintColor;\n color?: string;\n fluid?: boolean;\n onClick?: () => void;\n className?: string;\n}\nconst TimeItem = ({\n state,\n label,\n printColor,\n color,\n fluid,\n onClick,\n className,\n}: TimeItemProps) => {\n const clickable = (state === \"default\" || state === \"selected\") && !!onClick;\n const style: CSSProperties | undefined =\n state === \"default\" && color ? ({ \"--tt-hover\": color } as CSSProperties) : undefined;\n\n return (\n <div\n onClick={clickable ? onClick : undefined}\n style={style}\n className={cn(\n \"h-18 flex items-center justify-center\",\n fluid ? \"w-full\" : \"w-18\",\n \"text-body1-medium text-center bg-white text-primary\",\n state === \"none\" && \"bg-gray00 text-transparent\",\n state === \"selected\" && \"bg-black text-gray02 hover:cursor-pointer\",\n state === \"disabled\" && \"bg-gray00 text-gray03\",\n state === \"default\" && [\n \"hover:cursor-pointer\",\n color\n ? \"hover:bg-(--tt-hover)\"\n : printColor\n ? printColorHoverClass[printColor]\n : \"hover:bg-gray00\",\n ],\n className,\n )}\n >\n {label}\n </div>\n );\n};\n","import { forwardRef } from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport { IconChevronDownXS } from \"../../assets/svgs/Icons\";\nimport { formatWeekRange } from \"./dateUtils\";\n\nexport type Week = \"thisWeek\" | \"nextWeek\" | \"twoWeeksLater\";\n\nconst weekLabel: Record<Week, string> = {\n thisWeek: \"이번 주\",\n nextWeek: \"다음 주\",\n twoWeeksLater: \"다다음 주\",\n};\n\nexport interface WeekNavigationProps {\n /** 표시 중인 주의 월요일(ISO \"YYYY-MM-DD\"). 범위 라벨(~금요일)을 여기서 계산한다. */\n date: string;\n /** 3주 모델에 매핑되는 주차. `label`을 직접 주면 생략 가능. */\n week?: Week;\n /** 가운데 텍스트를 직접 지정(주어지면 week 기반 자동 라벨을 대체). */\n label?: string;\n /** 이전/다음 버튼 노출 여부를 명시적으로 제어. 생략 시 week로 자동 판단(thisWeek↔twoWeeksLater 경계). */\n canPrev?: boolean;\n canNext?: boolean;\n onPrevWeek?: () => void;\n onNextWeek?: () => void;\n className?: string;\n}\n\nexport const WeekNavigation = forwardRef<HTMLDivElement, WeekNavigationProps>(\n function WeekNavigation(\n { date, week, label, canPrev, canNext, onPrevWeek, onNextWeek, className },\n ref,\n ) {\n // \"이번 주\"보다 과거로는, \"다다음 주\"보다 미래로는 이동할 수 없다.\n const showPrev = canPrev ?? (week ? week !== \"thisWeek\" : true);\n const showNext = canNext ?? (week ? week !== \"twoWeeksLater\" : true);\n const text =\n label ?? (week ? `${weekLabel[week]} (${formatWeekRange(date)})` : formatWeekRange(date));\n\n return (\n <div\n ref={ref}\n className={cn(\n \"flex items-center justify-between\",\n \"w-full h-11 px-3\",\n \"bg-white border border-gray02\",\n \"text-body2-regular text-primary\",\n className,\n )}\n >\n <ArrowButton direction=\"left\" visible={showPrev} onClick={onPrevWeek} />\n <span>{text}</span>\n <ArrowButton direction=\"right\" visible={showNext} onClick={onNextWeek} />\n </div>\n );\n },\n);\n\ninterface ArrowButtonProps {\n direction: \"left\" | \"right\";\n visible: boolean;\n onClick?: () => void;\n}\n\nconst ArrowButton = ({ direction, visible, onClick }: ArrowButtonProps) => {\n if (!visible) {\n // 버튼이 없어도 가운데 라벨 위치가 흔들리지 않도록 자리만 유지한다.\n return <span className=\"w-6 h-6\" />;\n }\n\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className={cn(\n \"flex items-center justify-center w-6 h-6\",\n \"text-gray06 cursor-pointer\",\n \"hover:bg-gray00 active:bg-gray01\",\n )}\n >\n <IconChevronDownXS\n className={direction === \"left\" ? \"rotate-90\" : \"-rotate-90\"}\n stroke=\"currentColor\"\n />\n </button>\n );\n};\n","const KOREAN_WEEKDAYS = [\"일\", \"월\", \"화\", \"수\", \"목\", \"금\", \"토\"];\n\n// \"YYYY-MM-DD\" 문자열만 다루므로 로컬 타임존 파싱을 위해 new Date(date)(UTC 파싱) 대신 직접 분해한다.\nconst parseISODate = (date: string) => {\n const [year, month, day] = date.split(\"-\").map(Number);\n return new Date(year, month - 1, day);\n};\n\nconst toISODate = (d: Date) => {\n const year = d.getFullYear();\n const month = String(d.getMonth() + 1).padStart(2, \"0\");\n const day = String(d.getDate()).padStart(2, \"0\");\n return `${year}-${month}-${day}`;\n};\n\nexport const addDays = (date: string, amount: number) => {\n const d = parseISODate(date);\n d.setDate(d.getDate() + amount);\n return toISODate(d);\n};\n\n// \"5월 5일(월)\"\nexport const formatDayLabel = (date: string) => {\n const d = parseISODate(date);\n return `${d.getMonth() + 1}월 ${d.getDate()}일(${KOREAN_WEEKDAYS[d.getDay()]})`;\n};\n\n// \"05.05\"\nconst formatMMDD = (date: string) => {\n const d = parseISODate(date);\n return `${String(d.getMonth() + 1).padStart(2, \"0\")}.${String(d.getDate()).padStart(2, \"0\")}`;\n};\n\n// weekStart(월요일) 기준 5일(월~금) 범위: \"05.05 ~ 05.09\"\nexport const formatWeekRange = (weekStart: string) => {\n const weekEnd = addDays(weekStart, 4);\n return `${formatMMDD(weekStart)} ~ ${formatMMDD(weekEnd)}`;\n};\n","import {\n forwardRef,\n useCallback,\n useState,\n type AnchorHTMLAttributes,\n type ComponentType,\n type ReactNode,\n type Ref,\n} from \"react\";\nimport { cn } from \"../../lib/cn\";\n\n/**\n * href가 있는 항목을 실제 링크로 렌더링하기 위해 주입하는 컴포넌트.\n * Next.js라면 `next/link`를 그대로 넘기면 된다.\n * 주입하지 않으면 순수 `<a>`로 렌더링된다.\n */\nexport type LinkComponent = ComponentType<\n Pick<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n \"href\" | \"className\" | \"onClick\" | \"aria-current\"\n > & {\n children: ReactNode;\n ref?: Ref<HTMLAnchorElement>;\n }\n>;\n\nexport type NavIcon = {\n /** 아이콘 이미지 URL. `icon`(ReactNode)과 택일해서 사용한다. */\n src?: string;\n /** 인라인 SVG 등 커스텀 노드. `src` 대신 사용한다. 선택 상태 대비를 위해 `currentColor` 사용을 권장. */\n icon?: ReactNode;\n alt?: string;\n /** 아이콘 옆에 함께 노출할 텍스트 라벨(예: \"피드백\"). 아이콘 없이 라벨만도 가능. */\n label?: string;\n /** key/상태 식별용 안정적 id(권장). 없으면 `src` → `label` 순으로 대체한다. */\n id?: string;\n /** 지정하면 `<a>`(또는 주입된 LinkComponent)로 렌더링된다. */\n href?: string;\n onClick?: () => void;\n /** true면 아이콘 배경을 검게 채워 강조한다(예: 알림/마이페이지 진입 상태). */\n selected?: boolean;\n /** 알림 개수 등 우상단 뱃지. `true`면 점(dot)만 표시. */\n badge?: ReactNode;\n className?: string;\n /** 렌더링된 `<a>`/`<button>` 엘리먼트로 전달되는 ref(외부 클릭 감지 등에 사용). */\n ref?: Ref<HTMLElement>;\n};\n\nexport type LowerPartItem = {\n label: string;\n /** key/상태 식별용 안정적 id(권장). 없으면 `label`을 사용한다. */\n id?: string;\n /** 지정하면 `<a>`(또는 주입된 LinkComponent)로 렌더링된다. */\n href?: string;\n onClick?: () => void;\n};\n\nexport type UpperPartItem = {\n label: string;\n id?: string;\n href?: string;\n onClick?: () => void;\n /** 이 상단 탭이 선택됐을 때 아래에 노출할 하위 메뉴 */\n lowerPartItemList: LowerPartItem[];\n};\n\nexport interface TNBProps {\n logo: NavIcon;\n upperPartItemList: UpperPartItem[];\n /** 우측 알림/마이페이지 등 아이콘 목록(로고 제외) */\n upperPartIconList: NavIcon[];\n\n /**\n * controlled: 현재 선택된 상단 탭의 label.\n * `null`을 넘기면 \"선택된 탭 없음\"(홈 등)으로 표시된다.\n */\n selected?: string | null;\n /** uncontrolled 초기값. `selected`를 함께 넘기면 무시된다. 지정하지 않으면 선택된 탭이 없다. */\n defaultSelected?: string;\n onSelectedChange?: (label: string) => void;\n\n /** controlled: 현재 선택된 하위 메뉴 label. `null`이면 미선택. */\n selectedLower?: string | null;\n /** uncontrolled 초기값. */\n defaultSelectedLower?: string;\n onSelectedLowerChange?: (label: string) => void;\n\n /** @deprecated `onSelectedChange`를 사용하세요. 하위 호환용 별칭입니다. */\n onSelectItem?: (label: string) => void;\n\n /** href가 있는 항목을 렌더링할 링크 컴포넌트(Next.js면 `next/link`). */\n linkComponent?: LinkComponent;\n\n /** nav 랜드마크의 접근성 라벨. */\n \"aria-label\"?: string;\n className?: string;\n}\n\n/** controlled/uncontrolled를 함께 지원하는 상태 훅. `controlled`가 `undefined`가 아니면 controlled로 간주한다(`null` 포함). */\nfunction useControllableState<T>(controlled: T | undefined, defaultValue: T) {\n const isControlled = controlled !== undefined;\n const [uncontrolled, setUncontrolled] = useState<T>(defaultValue);\n const value = isControlled ? (controlled as T) : uncontrolled;\n const setValue = useCallback(\n (next: T) => {\n if (!isControlled) setUncontrolled(next);\n },\n [isControlled],\n );\n return [value, setValue, isControlled] as const;\n}\n\nexport const TNB = forwardRef<HTMLElement, TNBProps>(function TNB(\n {\n logo,\n upperPartItemList,\n upperPartIconList,\n selected,\n defaultSelected,\n onSelectedChange,\n selectedLower,\n defaultSelectedLower,\n onSelectedLowerChange,\n onSelectItem,\n linkComponent,\n \"aria-label\": ariaLabel = \"주요 메뉴\",\n className,\n },\n ref,\n) {\n const [upperValue, setUpperValue] = useControllableState<string | null>(\n selected,\n defaultSelected ?? null,\n );\n const [lowerValueRaw, setLowerValue, lowerIsControlled] = useControllableState<string | null>(\n selectedLower,\n defaultSelectedLower ?? null,\n );\n\n const currentUpper = upperPartItemList.find((item) => item.label === upperValue);\n const currentLowerItemList = currentUpper?.lowerPartItemList ?? [];\n\n // uncontrolled 하위 메뉴: 현재 목록에 없으면 첫 항목으로 자동 폴백(기존 동작 유지).\n const lowerValue = lowerIsControlled\n ? (lowerValueRaw ?? undefined)\n : currentLowerItemList.some((item) => item.label === lowerValueRaw)\n ? (lowerValueRaw as string)\n : (currentLowerItemList[0]?.label ?? undefined);\n\n const handleSelectUpper = (label: string) => {\n setUpperValue(label);\n if (!lowerIsControlled) {\n const nextLower =\n upperPartItemList.find((item) => item.label === label)?.lowerPartItemList[0]?.label ?? null;\n setLowerValue(nextLower);\n }\n onSelectedChange?.(label);\n onSelectItem?.(label);\n };\n\n const handleSelectLower = (label: string) => {\n setLowerValue(label);\n onSelectedLowerChange?.(label);\n };\n\n return (\n <nav ref={ref} aria-label={ariaLabel} className={cn(\"w-full bg-white\", className)}>\n <UpperPart\n logo={logo}\n upperPartItemList={upperPartItemList}\n upperPartIconList={upperPartIconList}\n selected={upperValue ?? undefined}\n onSelectItem={handleSelectUpper}\n linkComponent={linkComponent}\n />\n <LowerPart\n lowerPartItemList={currentLowerItemList}\n selected={lowerValue}\n onSelectItem={handleSelectLower}\n linkComponent={linkComponent}\n />\n </nav>\n );\n});\n\n/* -------------------------------------------------------------------------- */\n/* NavClickable — href 유무에 따라 <a>(또는 주입된 링크) / <button>을 렌더링 */\n/* -------------------------------------------------------------------------- */\n\ninterface NavClickableProps {\n href?: string;\n onClick?: () => void;\n linkComponent?: LinkComponent;\n /** 링크로 열더라도 현재 위치면 aria-current를 붙인다. */\n current?: boolean;\n disabled?: boolean;\n className?: string;\n children: ReactNode;\n}\n\nconst NavClickable = forwardRef<HTMLElement, NavClickableProps>(function NavClickable(\n { href, onClick, linkComponent: Link, current, disabled, className, children },\n ref,\n) {\n const ariaCurrent = current ? \"page\" : undefined;\n\n if (href && !disabled) {\n if (Link) {\n return (\n <Link\n href={href}\n onClick={onClick}\n aria-current={ariaCurrent}\n className={className}\n ref={ref as Ref<HTMLAnchorElement>}\n >\n {children}\n </Link>\n );\n }\n return (\n <a\n href={href}\n onClick={onClick}\n aria-current={ariaCurrent}\n className={className}\n ref={ref as Ref<HTMLAnchorElement>}\n >\n {children}\n </a>\n );\n }\n\n return (\n <button\n type=\"button\"\n onClick={onClick}\n disabled={disabled}\n aria-current={ariaCurrent}\n className={className}\n ref={ref as Ref<HTMLButtonElement>}\n >\n {children}\n </button>\n );\n});\n\n/* -------------------------------------------------------------------------- */\n\ninterface UpperPartProps {\n logo: NavIcon;\n upperPartItemList: UpperPartItem[];\n upperPartIconList: NavIcon[];\n selected?: string;\n onSelectItem: (label: string) => void;\n linkComponent?: LinkComponent;\n className?: string;\n}\nconst UpperPart = ({\n logo,\n upperPartItemList,\n upperPartIconList,\n selected,\n onSelectItem,\n linkComponent,\n className,\n}: UpperPartProps) => {\n return (\n <div className={cn(\"w-full h-13 px-4 flex items-center justify-between\", className)}>\n <div className=\"flex items-center gap-6\">\n <NavIconButton {...logo} linkComponent={linkComponent} />\n <div className=\"flex items-center gap-4\">\n {upperPartItemList.map((item) => (\n <UpperPartTab\n key={item.id ?? item.label}\n label={item.label}\n href={item.href}\n selected={item.label === selected}\n linkComponent={linkComponent}\n onClick={() => {\n item.onClick?.();\n onSelectItem(item.label);\n }}\n />\n ))}\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n {upperPartIconList.map((icon, index) => (\n <NavIconButton\n key={icon.id ?? icon.src ?? icon.label ?? index}\n {...icon}\n linkComponent={linkComponent}\n />\n ))}\n </div>\n </div>\n );\n};\n\ninterface UpperPartTabProps {\n label: string;\n href?: string;\n selected: boolean;\n onClick: () => void;\n linkComponent?: LinkComponent;\n className?: string;\n}\nconst UpperPartTab = ({\n label,\n href,\n selected,\n onClick,\n linkComponent,\n className,\n}: UpperPartTabProps) => {\n return (\n <NavClickable\n href={href}\n onClick={onClick}\n linkComponent={linkComponent}\n current={selected}\n className={cn(\n \"inline-flex px-1 py-1.5 text-body2-regular cursor-pointer no-underline\",\n selected\n ? \"text-strong font-medium underline underline-offset-4\"\n : \"text-quaternary hover:text-secondary\",\n className,\n )}\n >\n {label}\n </NavClickable>\n );\n};\n\nconst NavIconButton = forwardRef<HTMLElement, NavIcon & { linkComponent?: LinkComponent }>(\n function NavIconButton(\n { src, icon, alt, label, href, onClick, selected, badge, className, linkComponent },\n forwardedRef,\n ) {\n const interactive = Boolean(onClick || href);\n const showBadge = badge !== undefined && badge !== null && badge !== false;\n\n return (\n <NavClickable\n ref={forwardedRef}\n href={href}\n onClick={onClick}\n linkComponent={linkComponent}\n current={selected}\n disabled={!interactive}\n className={cn(\n \"relative inline-flex h-8 min-w-8 items-center justify-center gap-1.5 rounded-full px-1.5\",\n interactive && \"cursor-pointer\",\n selected ? \"bg-black text-white\" : \"bg-transparent hover:bg-gray00 active:bg-gray01\",\n className,\n )}\n >\n {icon ? (\n <span className=\"inline-flex h-5 w-5 items-center justify-center\">{icon}</span>\n ) : src ? (\n <img src={src} alt={alt ?? label ?? \"\"} className=\"h-5 w-5\" />\n ) : null}\n {label ? (\n <span className={cn(\"text-body2-regular\", selected ? \"text-white\" : \"text-secondary\")}>\n {label}\n </span>\n ) : null}\n {showBadge ? (\n <span\n aria-hidden={badge === true}\n className={cn(\n \"absolute -right-0.5 -top-0.5 flex items-center justify-center rounded-full bg-danger text-white\",\n badge === true ? \"h-2 w-2\" : \"h-4 min-w-4 px-1 text-caption-regular leading-none\",\n )}\n >\n {badge === true ? null : badge}\n </span>\n ) : null}\n </NavClickable>\n );\n },\n);\n\ninterface LowerPartProps {\n lowerPartItemList: LowerPartItem[];\n selected?: string;\n onSelectItem: (label: string) => void;\n linkComponent?: LinkComponent;\n className?: string;\n}\nconst LowerPart = ({\n lowerPartItemList,\n selected,\n onSelectItem,\n linkComponent,\n className,\n}: LowerPartProps) => {\n if (lowerPartItemList.length === 0) {\n return null;\n }\n\n return (\n <div\n className={cn(\"w-full h-9 px-4 flex items-center gap-4 border-t border-gray02\", className)}\n >\n {lowerPartItemList.map((item) => (\n <LowerPartItemButton\n key={item.id ?? item.label}\n label={item.label}\n href={item.href}\n selected={item.label === selected}\n linkComponent={linkComponent}\n onClick={() => {\n item.onClick?.();\n onSelectItem(item.label);\n }}\n />\n ))}\n </div>\n );\n};\n\ninterface LowerPartItemButtonProps {\n label: string;\n href?: string;\n selected: boolean;\n onClick: () => void;\n linkComponent?: LinkComponent;\n className?: string;\n}\nconst LowerPartItemButton = ({\n label,\n href,\n selected,\n onClick,\n linkComponent,\n className,\n}: LowerPartItemButtonProps) => {\n return (\n <NavClickable\n href={href}\n onClick={onClick}\n linkComponent={linkComponent}\n current={selected}\n className={cn(\n \"inline-flex px-1.5 py-1 text-caption-regular cursor-pointer no-underline\",\n \"hover:bg-gray00 active:bg-gray01\",\n selected ? \"text-strong font-medium\" : \"text-quaternary\",\n className,\n )}\n >\n {label}\n </NavClickable>\n );\n};\n","import { forwardRef, useEffect, useState } from \"react\";\nimport { cn } from \"../../lib/cn\";\n\nconst EXIT_MS = 300;\n\nexport interface ToastProps {\n message: string;\n /**\n * 표시 여부(controlled). 생략하면 항상 표시되는 순수 렌더 모드(하위 호환).\n * `true`/`false`를 넘기면 페이드 인/아웃 + 언마운트를 컴포넌트가 스스로 처리한다.\n */\n open?: boolean;\n /**\n * 자동 소멸까지의 시간(ms). `0`/`null`이면 자동 소멸하지 않는다. 기본 3000.\n * `open`이 `true`로 바뀔 때마다 타이머가 재시작된다.\n */\n duration?: number | null;\n /** 자동 소멸 시각 또는 (배너 클릭 시) 호출. controlled 모드에서 `open`을 false로 되돌리는 데 사용. */\n onClose?: () => void;\n /**\n * 화면 고정 위치. `\"none\"`이면 위치 스타일을 붙이지 않고 부모 레이아웃에 맡긴다(하위 호환 기본값).\n */\n position?: \"top\" | \"bottom\" | \"none\";\n className?: string;\n}\n\nexport const Toast = forwardRef<HTMLDivElement, ToastProps>(function Toast(\n { message, open, duration = 3000, onClose, position = \"none\", className },\n ref,\n) {\n const controlled = open !== undefined;\n const [mounted, setMounted] = useState(!controlled || open);\n const [visible, setVisible] = useState(!controlled || open);\n\n // 마운트/언마운트 + 다음 프레임 페이드\n useEffect(() => {\n if (!controlled) return;\n if (open) {\n setMounted(true);\n const raf = requestAnimationFrame(() => setVisible(true));\n return () => cancelAnimationFrame(raf);\n }\n setVisible(false);\n const timer = setTimeout(() => setMounted(false), EXIT_MS);\n return () => clearTimeout(timer);\n }, [controlled, open]);\n\n // 자동 소멸 타이머\n useEffect(() => {\n if (!controlled || !open || !duration) return;\n const timer = setTimeout(() => onClose?.(), duration);\n return () => clearTimeout(timer);\n }, [controlled, open, duration, onClose]);\n\n if (!mounted) return null;\n\n const banner = (\n <div\n ref={ref}\n role=\"status\"\n aria-live=\"polite\"\n className={cn(\n \"w-full h-fit py-2.5 bg-gray06\",\n \"font-pretendard text-white text-center font-semibold text-[17px]\",\n \"shadow-[0_2px_15px_rgba(0,0,0,0.18)]\",\n controlled && \"transition-opacity duration-300\",\n controlled && (visible ? \"opacity-100\" : \"opacity-0\"),\n className,\n )}\n >\n {message}\n </div>\n );\n\n if (position === \"none\") return banner;\n\n return (\n <div\n className={cn(\n \"fixed inset-x-0 z-5000 pointer-events-none\",\n position === \"top\" ? \"top-0\" : \"bottom-0\",\n )}\n >\n {banner}\n </div>\n );\n});\n"],"mappings":"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","names":["import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","Tag","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","CTAs","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","import_react","import_jsx_runtime","SideRadioAccordion","TextButton","import_jsx_runtime","import_react","import_react","import_jsx_runtime","WeekNavigation","import_jsx_runtime","Timetable","import_react","import_jsx_runtime","useControllableState","TNB","NavClickable","NavIconButton","import_react","import_jsx_runtime","Toast"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/lib/cn.ts","../src/assets/svgs/Icons.tsx","../src/components/BackButton/BackButton.tsx","../src/components/CTA/CTA.tsx","../src/components/Column/MultiColumn.tsx","../src/components/Column/Column.tsx","../src/components/Column/ColumnContentContainer.tsx","../src/components/Column/ColumnLabel.tsx","../src/components/Column/ColumnText.tsx","../src/components/Column/ColumnSubTitle.tsx","../src/components/Column/ColumnDescription.tsx","../src/components/Form/BasicFormField.tsx","../src/components/Form/FormText.tsx","../src/components/Form/FormTextArea.tsx","../src/components/Form/FormNumber.tsx","../src/components/Form/FormPassword.tsx","../src/components/Form/FormTel.tsx","../src/components/Form/FormColor.tsx","../src/components/Form/FormFile.tsx","../src/components/Form/FormCheckBox.tsx","../src/components/Form/FormSelectBox.tsx","../src/components/Form/SelectBoxOption.tsx","../src/components/TextButton/TextButton.tsx","../src/components/Dropdown/Dropdown.tsx","../src/components/ListView/List.tsx","../src/components/Modal/Modal.tsx","../src/components/Modal/ModalText.tsx","../src/components/createPost/CategorySegment.tsx","../src/components/createPost/CategorySegmentedControl.tsx","../src/components/createPost/TitleInput.tsx","../src/components/notice/NoticeBadge.tsx","../src/components/notice/NoticeBar.tsx","../src/components/SearchBar/SearchBar.tsx","../src/components/SideRadioAccordion/SideRadioAccordion.tsx","../src/lib/useControllableState.ts","../src/components/Tag/Tag.tsx","../src/components/Timetable/Timetable.tsx","../src/components/Timetable/WeekNavigation.tsx","../src/components/Timetable/dateUtils.ts","../src/components/TNB/TNB.tsx","../src/components/Toast/Toast.tsx"],"sourcesContent":["export { BackButton, BackButtonProps } from \"./components/BackButton/BackButton\";\n\nexport { CTA, CTAProps } from \"./components/CTA/CTA\";\n\nexport { MultiColumn } from \"./components/Column/MultiColumn\";\nexport { Column, ColumnProps } from \"./components/Column/Column\";\nexport {\n ColumnContentContainer,\n ColumnContentContainerProps,\n} from \"./components/Column/ColumnContentContainer\";\nexport { ColumnLabel, ColumnLabelProps } from \"./components/Column/ColumnLabel\";\nexport {\n ColumnText,\n ColumnTextProps,\n ColumnTextStyle,\n ModalTextStyle,\n} from \"./components/Column/ColumnText\";\nexport { ColumnSubTitle, ColumnSubTitleProps } from \"./components/Column/ColumnSubTitle\";\nexport {\n ColumnDescription,\n ColumnDescriptionProps,\n ColumnDescriptionList,\n ColumnDescriptionListProps,\n} from \"./components/Column/ColumnDescription\";\n\nexport {\n BasicFormField,\n BasicFormFieldProps,\n getInputStyles,\n} from \"./components/Form/BasicFormField\";\nexport { FormText, FormTextProps } from \"./components/Form/FormText\";\nexport { FormTextArea, FormTextAreaProps } from \"./components/Form/FormTextArea\";\nexport { FormNumber, FormNumberProps } from \"./components/Form/FormNumber\";\nexport { FormPassword, FormPasswordProps } from \"./components/Form/FormPassword\";\nexport { FormTel, FormTelProps } from \"./components/Form/FormTel\";\nexport { FormColor, FormColorProps } from \"./components/Form/FormColor\";\nexport { FormFile, FormFileProps } from \"./components/Form/FormFile\";\nexport { FormCheckBox, FormCheckBoxProps } from \"./components/Form/FormCheckBox\";\nexport { FormSelectBox, FormSelectBoxProps } from \"./components/Form/FormSelectBox\";\nexport { SelectBoxOption, SelectBoxOptionProps } from \"./components/Form/SelectBoxOption\";\n\nexport { TextButton, TextButtonProps } from \"./components/TextButton/TextButton\";\n\nexport { Dropdown, DropdownProps } from \"./components/Dropdown/Dropdown\";\n\nexport { List, ListProps } from \"./components/ListView/List\";\n\nexport { Modal, ModalProps } from \"./components/Modal/Modal\";\nexport { ModalText, ModalTextProps } from \"./components/Modal/ModalText\";\n\nexport {\n IconInfo,\n IconCheck,\n IconChevronDownXS,\n IconCompass,\n IconRadioSelected,\n IconRadioUnselected,\n IconExclamation,\n IconClose,\n} from \"./assets/svgs/Icons\";\n\nexport { CategorySegment, CategorySegmentProps } from \"./components/createPost/CategorySegment\";\nexport {\n CategorySegmentedControl,\n CategorySegmentedControlProps,\n} from \"./components/createPost/CategorySegmentedControl\";\nexport { TitleInput, TitleInputProps } from \"./components/createPost/TitleInput\";\n\nexport {\n NoticeBadge,\n NoticeBadgeProps,\n NoticeBadgeVariable,\n} from \"./components/notice/NoticeBadge\";\nexport {\n NoticeBar,\n NoticeBarProps,\n NoticeBarVariable,\n NoticeBarBadgeVariable,\n} from \"./components/notice/NoticeBar\";\n\nexport { SearchBar, SearchBarProps } from \"./components/SearchBar/SearchBar\";\n\nexport {\n SideRadioAccordion,\n SideRadioAccordionProps,\n RadioToggle,\n PrintColor as SideRadioAccordionPrintColor,\n} from \"./components/SideRadioAccordion/SideRadioAccordion\";\n\nexport { Tag, TagProps } from \"./components/Tag/Tag\";\n\nexport {\n Timetable,\n TimetableProps,\n DayColumn,\n TimeSlot,\n TimeSlotState,\n PrintColor as TimetablePrintColor,\n} from \"./components/Timetable/Timetable\";\nexport { WeekNavigation, WeekNavigationProps, Week } from \"./components/Timetable/WeekNavigation\";\n\nexport {\n TNB,\n TNBProps,\n NavIcon,\n UpperPartItem,\n LowerPartItem,\n LinkComponent,\n} from \"./components/TNB/TNB\";\n\nexport { Toast, ToastProps } from \"./components/Toast/Toast\";\n","import { clsx, type ClassValue } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\n// text-head*/text-body*/text-caption* are custom typography utilities (src/styles.css),\n// not text-color utilities — tailwind-merge would otherwise treat them as the same\n// group as text-white/text-gray04 and silently drop one of them.\nconst twMerge = extendTailwindMerge<\"font-typography\">({\n extend: {\n classGroups: {\n \"font-typography\": [\n \"text-head1-medium\",\n \"text-head2-medium\",\n \"text-head3-medium\",\n \"text-head4-regular\",\n \"text-body1-medium\",\n \"text-body1-regular\",\n \"text-body2-regular\",\n \"text-body3-medium\",\n \"text-body3-regular\",\n \"text-body3-book\",\n \"text-caption-regular\",\n \"text-caption-book\",\n ],\n },\n },\n});\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","export const IconChevronDownXS = ({\n className,\n stroke,\n}: {\n className?: string;\n stroke?: string;\n}) => {\n return (\n <svg\n className={className}\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 20 20\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M5 8.3335L10 13.3335L15 8.3335\"\n stroke={stroke || \"#121212\"}\n strokeWidth=\"1.5\"\n strokeLinecap=\"square\"\n />\n </svg>\n );\n};\n\nexport const IconCheck = ({ className, stroke }: { className?: string; stroke?: string }) => {\n return (\n <svg\n className={className}\n width=\"13\"\n height=\"13\"\n viewBox=\"0 0 13 13\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M2.05566 7.0555L4.83344 9.8333L10.9446 3.72217\" stroke={stroke || \"#121212\"} />\n </svg>\n );\n};\n\nexport const IconSearch = ({ className, stroke }: { className?: string; stroke?: string }) => {\n return (\n <svg\n className={className}\n width=\"30\"\n height=\"30\"\n viewBox=\"0 0 30 30\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M20.1161 20.6888L24.1075 25.1791\"\n stroke={stroke || \"black\"}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M13.9289 23.0361C18.9587 23.0361 23.0361 18.9587 23.0361 13.9289C23.0361 8.89918 18.9587 4.82178 13.9289 4.82178C8.89918 4.82178 4.82178 8.89918 4.82178 13.9289C4.82178 18.9587 8.89918 23.0361 13.9289 23.0361Z\"\n stroke={stroke || \"black\"}\n strokeWidth=\"2\"\n />\n </svg>\n );\n};\n\nexport const IconInfo = ({ className, stroke }: { className?: string; stroke?: string }) => {\n return (\n <svg\n className={className}\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <circle cx=\"8\" cy=\"8\" r=\"6.25\" stroke={stroke || \"#8b94a1\"} strokeWidth=\"1.5\" />\n <path\n d=\"M8 7.25V11.25\"\n stroke={stroke || \"#8b94a1\"}\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n />\n <circle cx=\"8\" cy=\"5\" r=\"0.9\" fill={stroke || \"#8b94a1\"} />\n </svg>\n );\n};\n\nexport const IconGoBack = ({ className, stroke }: { className?: string; stroke?: string }) => {\n return (\n <svg\n className={className}\n width=\"32\"\n height=\"32\"\n viewBox=\"0 0 32 32\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M28 16.0001L4 16.0001\"\n stroke={stroke || \"black\"}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n <path d=\"M12 8L4 16L12 24\" stroke={stroke || \"black\"} strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n );\n};\n\n/** HIVCD 컴퍼스 마크. 주의사항 리스트의 불릿 등으로 사용. */\nexport const IconCompass = ({ className, fill }: { className?: string; fill?: string }) => {\n return (\n <svg\n className={className}\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M12.5731 7.37945C12.2964 5.32806 10.668 3.70356 8.6166 3.42688V0H7.37945V3.42688C5.32806 3.70356 3.70356 5.32806 3.42688 7.37945H0V8.62055H3.42688C3.70356 10.6719 5.32806 12.2964 7.37945 12.5731V16H8.6166V12.5731C10.668 12.2964 12.2964 10.6719 12.5731 8.62055H16V7.37945H12.5731ZM7.37945 11.3241C6.01186 11.0672 4.93281 9.98814 4.67589 8.62055H7.37945V11.3241ZM7.4664 5.51383C7.41897 5.81423 7.39131 6.14229 7.37945 6.50988V7.37945H4.67589C4.89328 6.22925 5.68775 5.28458 6.75099 4.86166C6.9921 4.73122 7.07905 4.67589 7.19763 4.41502L7.67984 4.57312C7.58498 4.90119 7.51779 5.21344 7.4664 5.51383ZM9.24506 11.1383C9.00395 11.2727 8.917 11.3241 8.79842 11.5889L8.31621 11.4269C8.41107 11.1028 8.47826 10.7905 8.52965 10.4901C8.57312 10.2134 8.60474 9.91304 8.6166 9.58103V8.62055H11.3202C11.1067 9.77075 10.3083 10.7154 9.24506 11.1383ZM8.6166 7.37945V4.67984C9.98419 4.93281 11.0672 6.01186 11.3202 7.37945H8.6166Z\"\n fill={fill || \"#121212\"}\n />\n </svg>\n );\n};\n\n/** 선택된 라디오 버튼(채워진 점). SideRadioAccordion 등에서 사용. */\nexport const IconRadioSelected = ({\n className,\n stroke,\n fill,\n}: {\n className?: string;\n stroke?: string;\n fill?: string;\n}) => {\n return (\n <svg\n className={className}\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <circle cx=\"8\" cy=\"8\" r=\"7\" stroke={stroke || \"#121212\"} />\n <circle cx=\"8\" cy=\"8\" r=\"4\" fill={fill || \"#121212\"} />\n </svg>\n );\n};\n\n/** 선택되지 않은 라디오 버튼(빈 원). */\nexport const IconRadioUnselected = ({\n className,\n stroke,\n}: {\n className?: string;\n stroke?: string;\n}) => {\n return (\n <svg\n className={className}\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <circle cx=\"8\" cy=\"8\" r=\"7\" stroke={stroke || \"#B4B9C2\"} />\n </svg>\n );\n};\n\n/** 느낌표(원 안). 보조 안내 텍스트 버튼 등에서 사용. */\nexport const IconExclamation = ({ className, fill }: { className?: string; fill?: string }) => {\n return (\n <svg\n className={className}\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M6.41438 7.18735H5.57954L5.50175 3.10938H6.49218L6.41438 7.18735ZM5.40001 8.3313C5.39801 8.23061 5.42395 8.13738 5.47781 8.05161C5.53167 7.96583 5.60448 7.89777 5.69624 7.84743C5.79 7.79708 5.89174 7.77191 6.00145 7.77191C6.10718 7.77191 6.20592 7.79708 6.29768 7.84743C6.38945 7.89777 6.46226 7.96583 6.51612 8.05161C6.57197 8.13738 6.5999 8.23061 6.5999 8.3313C6.5999 8.43199 6.57197 8.52522 6.51612 8.611C6.46226 8.69677 6.38945 8.76483 6.29768 8.81518C6.20592 8.86552 6.10718 8.89069 6.00145 8.89069C5.89174 8.89069 5.79 8.86552 5.69624 8.81518C5.60448 8.76483 5.53167 8.69677 5.47781 8.611C5.42395 8.52522 5.39801 8.43199 5.40001 8.3313Z\"\n fill={fill || \"#505865\"}\n />\n <circle cx=\"6\" cy=\"6\" r=\"4.5\" stroke={fill || \"#505865\"} />\n </svg>\n );\n};\n\n/** 닫기(X) 아이콘. Modal 우상단 등에서 사용. */\nexport const IconClose = ({ className, stroke }: { className?: string; stroke?: string }) => {\n return (\n <svg\n className={className}\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M4 4L12 12M12 4L4 12\"\n stroke={stroke || \"#6d7683\"}\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n />\n </svg>\n );\n};\n","import { cn } from \"../../lib/cn\";\nimport { IconGoBack } from \"../../assets/svgs/Icons\";\n\nexport interface BackButtonProps {\n onClick?: () => void;\n className?: string;\n}\n\nexport const BackButton = ({ onClick, className }: BackButtonProps) => {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className={cn(\n \"w-14 h-full py-3\",\n \"flex flex-col items-center\",\n \"box-border border-r border-gray02\",\n \"bg-white hover:bg-gray00 active:bg-gray01\",\n \"cursor-pointer\",\n className,\n )}\n >\n <IconGoBack />\n </button>\n );\n};\n","import { cn } from \"../../lib/cn\";\n\nexport interface CTAProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n primary?: boolean;\n alert?: boolean;\n disabled?: boolean;\n label: string;\n onClick?: () => void;\n className?: string;\n forModal?: boolean;\n}\n\nexport const CTA = ({\n primary = false,\n alert = false,\n disabled = false,\n label,\n onClick,\n className,\n forModal = false,\n ...props\n}: CTAProps) => {\n return (\n <button\n type=\"button\"\n disabled={disabled}\n className={cn(\n forModal ? \"h-14.5\" : \"h-12\",\n \"w-full max-w-360 px-4\",\n \"flex items-center justify-center\",\n \"border-t box-border border-gray02\",\n primary && \"border-none\",\n\n \"text-head3-medium text-strong\",\n primary && \"text-white\",\n alert && \"text-danger\",\n disabled && \"text-quaternary\",\n\n \"bg-white hover:bg-gray00 active:bg-gray01 disabled:bg-gray02\",\n primary && \"bg-black hover:bg-gray08 active:bg-gray09 disabled:bg-gray01\",\n\n \"cursor-pointer disabled:cursor-default\",\n\n className,\n )}\n onClick={onClick}\n {...props}\n >\n {label}\n </button>\n );\n};\n","//사용 예시\n//<MultiColumn>\n// <MultiColumn.Columns>\n// <Column title=\"첫번째\" />\n// <Column title=\"두번째\" />\n// <Column title=\"세번째\" />\n// </MultiColumn.Columns>\n//\n// <MultiColumn.CTAs>\n// <CTA label=\"저장하기\" variable=\"default\" />\n// </MultiColumn.CTAs>\n//</MultiColumn>\n\nimport React, { ReactNode } from \"react\";\nimport { cn } from \"../../lib/cn\"; // 사용 중인 유틸리티 경로에 맞게 수정\n\ninterface BaseProps {\n children: ReactNode;\n className?: string;\n}\n\n// 1. 메인 래퍼 컴포넌트 (전체 컨테이너)\nconst MultiColumnMain = ({ children, className }: BaseProps) => {\n return <div className={cn(\"flex flex-col w-full h-full\", className)}>{children}</div>;\n};\n\n// 2. 상단 Column 영역 컴포넌트 (2~3개 배치)\nconst Columns = ({ children, className }: BaseProps) => {\n return (\n // flex 래퍼를 사용하고 하위 Column들이 flex-1을 가지게 하거나,\n // grid를 사용하여 열을 나눌 수 있어. 여기서는 flex를 활용한 균등 분할 예시야.\n <div className={cn(\"flex w-full h-full divide-x divide-gray02\", className)}>{children}</div>\n );\n};\n\n// 3. 하단 CTA 영역 컴포넌트 (0~3개 배치)\nconst CTAs = ({ children, className }: BaseProps) => {\n // children이 없으면(CTA가 0개) 아예 렌더링하지 않음\n if (!children) return null;\n\n return (\n // CTA 버튼들을 중앙에 배치하는 예시 (우측 정렬이 필요하면 justify-end 사용)\n <div className={cn(\"flex flex-col w-full h-fit\", className)}>{children}</div>\n );\n};\n\n// 4. Object.assign을 통해 하나의 객체로 묶어주기\nexport const MultiColumn = Object.assign(MultiColumnMain, {\n Columns,\n CTAs,\n});\n","import { cn } from \"../../lib/cn\";\n\nexport interface ColumnProps {\n className?: string;\n children: React.ReactNode;\n /**\n * 컬럼 상단 제목. 생략하면 제목 영역을 렌더링하지 않으며,\n * 이 경우 children 안에서 `ColumnSubTitle`로 섹션 제목을 직접 배치할 수 있다.\n */\n header?: string;\n}\n\nexport const Column = ({ className, children, header }: ColumnProps) => {\n return (\n <div className={cn(\"flex flex-col gap-5\", \"h-full w-full px-5 py-3\", className)}>\n {header && <h1 className={cn(\"text-body1-medium text-primary\")}>{header}</h1>}\n {children}\n </div>\n );\n};\n","import { cn } from \"../../lib/cn\";\n\nexport interface ColumnContentContainerProps {\n className?: string;\n children: React.ReactNode;\n}\n\nexport const ColumnContentContainer = ({ className, children }: ColumnContentContainerProps) => {\n return <div className={cn(\"flex flex-col gap-1.5 w-full h-fit\", className)}>{children}</div>;\n};\n","import { cn } from \"../../lib/cn\";\n\nexport interface ColumnLabelProps {\n className?: string;\n children: string;\n subLabel?: string;\n htmlFor?: string;\n}\n\nexport const ColumnLabel = ({ className, children, subLabel, htmlFor }: ColumnLabelProps) => {\n return (\n <label htmlFor={htmlFor} className={cn(\"flex gap-1.5 items-end\", className)}>\n <span className={cn(\"text-body2-regular text-tertiary\")}>{children}</span>\n {subLabel && <span className={cn(\"text-caption-book text-quaternary\")}>{subLabel}</span>}\n </label>\n );\n};\n","import { cn } from \"../../lib/cn\";\n\nexport interface ColumnTextProps {\n className?: string;\n children?: string | React.ReactNode;\n onClick?: () => void;\n alert?: boolean;\n}\n\nexport const ColumnTextStyle = \"text-body3-book text-strong\";\nexport const ModalTextStyle = \"text-body1-regular text-primary\";\n\nexport const ColumnText = ({ className, alert = false, children, onClick }: ColumnTextProps) => {\n return (\n <div className={cn(ColumnTextStyle, alert && \"text-danger\", className)} onClick={onClick}>\n {children ? children : \"-\"}\n </div>\n );\n};\n","import { cn } from \"../../lib/cn\";\n\nexport interface ColumnSubTitleProps {\n className?: string;\n children: React.ReactNode;\n /** 우측에 부연 아이콘/버튼 등을 배치할 때 사용 (예: 도움말 아이콘) */\n action?: React.ReactNode;\n as?: \"h2\" | \"h3\" | \"h4\" | \"header\";\n}\n\n/**\n * Column 내부의 섹션 구분용 부제목.\n * 예: \"예약 정보\", \"예약자 정보\", \"예약 시 주의사항\"\n */\nexport const ColumnSubTitle = ({\n className,\n children,\n action,\n as: Tag = \"h2\",\n}: ColumnSubTitleProps) => {\n return (\n <Tag className={cn(\"flex items-center justify-between gap-1.5\", \"w-full\", className)}>\n <span className={cn(\"text-body1-medium text-primary\")}>{children}</span>\n {action && <span className=\"flex shrink-0 items-center\">{action}</span>}\n </Tag>\n );\n};\n","import { cn } from \"../../lib/cn\";\nimport { IconCompass } from \"../../assets/svgs/Icons\";\n\nexport interface ColumnDescriptionProps {\n className?: string;\n children: React.ReactNode;\n /** 컴퍼스 마크 불릿 표시 여부. 기본 true. */\n bullet?: boolean;\n}\n\n/**\n * Column 내부의 안내/주의사항 항목 한 줄.\n * 컴퍼스 마크 불릿 + 본문(body3-book / text-primary)으로 구성되며,\n * 본문이 여러 줄이어도 줄바꿈된 텍스트가 아이콘 아래로 흐르지 않는다(행잉 인덴트).\n * 개행은 `\\n` 그대로 반영된다.\n * 예: \"예약 시 주의사항\" 목록의 각 항목.\n */\nexport const ColumnDescription = ({\n className,\n children,\n bullet = true,\n}: ColumnDescriptionProps) => {\n return (\n <div className={cn(\"flex items-start gap-3\", className)}>\n {bullet && (\n <span className=\"flex shrink-0 items-center py-1\">\n <IconCompass className=\"size-4\" />\n </span>\n )}\n <div className=\"min-w-0 flex-1 whitespace-pre-line text-body3-book text-primary\">\n {children}\n </div>\n </div>\n );\n};\n\nexport interface ColumnDescriptionListProps {\n className?: string;\n children: React.ReactNode;\n}\n\n/** `ColumnDescription` 항목들을 16px 간격으로 세로 배치하는 래퍼. */\nexport const ColumnDescriptionList = ({ className, children }: ColumnDescriptionListProps) => {\n return <div className={cn(\"flex flex-col gap-4\", className)}>{children}</div>;\n};\n","// src/components/.../FormField.tsx\n\nimport { cn } from \"../../lib/cn\";\nimport { ColumnTextStyle } from \"../Column/ColumnText\";\n\n// 1. 공통 Wrapper용 Props\nexport interface BasicFormFieldProps {\n children: React.ReactNode;\n isDanger?: boolean;\n dangerText?: string;\n className?: string; // 제일 바깥 div에 줄 클래스\n}\n\n// 2. 공통 에러 메시지 & 레이아웃 Wrapper 컴포넌트\nexport const BasicFormField = ({\n children,\n isDanger,\n dangerText,\n className,\n}: BasicFormFieldProps) => {\n return (\n <div className={cn(\"flex flex-col gap-1.5\", className)}>\n {children}\n {isDanger && dangerText && (\n <span className=\"text-caption-book text-danger\">{dangerText}</span>\n )}\n </div>\n );\n};\n\n// 3. 인풋 공통 스타일 생성 함수 (cn을 이용해 병합)\nexport const getInputStyles = (isDanger?: boolean, additionalClass?: string) => {\n return cn(\n // 디자인 스펙: 높이 41px, 좌우 12px / 상하 10px 패딩\n \"w-full h-[41px] px-3 py-2.5\",\n \"box-border border border-gray02 focus:outline-none focus:border-black\",\n \"bg-white transition-colors\",\n ColumnTextStyle,\n \"text-primary placeholder:text-quaternary\",\n isDanger && \"border-danger\", // 경고 시 빨간 테두리 (#E42939)\n additionalClass, // 각 인풋별 추가 스타일 (예: textarea의 h-30)\n );\n};\n","import { BasicFormField, getInputStyles } from \"./BasicFormField\";\n\nexport interface FormTextProps extends React.InputHTMLAttributes<HTMLInputElement> {\n isDanger?: boolean;\n dangerText?: string;\n}\n\nexport const FormText = ({ className, isDanger, dangerText, ...props }: FormTextProps) => {\n return (\n <BasicFormField isDanger={isDanger} dangerText={dangerText}>\n <input type=\"text\" className={getInputStyles(isDanger, className)} {...props} />\n </BasicFormField>\n );\n};\n","import { BasicFormField, getInputStyles } from \"./BasicFormField\";\n\nexport interface FormTextAreaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {\n isDanger?: boolean;\n dangerText?: string;\n}\n\nexport const FormTextArea = ({ className, isDanger, dangerText, ...props }: FormTextAreaProps) => {\n return (\n <BasicFormField isDanger={isDanger} dangerText={dangerText}>\n <textarea\n // 💡 cn() 유틸리티 덕분에 getInputStyles의 기본 h-10을 h-30이 깔끔하게 덮어씁니다!\n className={getInputStyles(isDanger, \"resize-none h-30 px-4 py-2.5 \" + (className || \"\"))}\n {...props}\n />\n </BasicFormField>\n );\n};\n","import { BasicFormField, getInputStyles } from \"./BasicFormField\";\n\nexport interface FormNumberProps extends React.InputHTMLAttributes<HTMLInputElement> {\n isDanger?: boolean;\n dangerText?: string;\n}\n\nexport const FormNumber = ({ className, isDanger, dangerText, ...props }: FormNumberProps) => {\n return (\n <BasicFormField isDanger={isDanger} dangerText={dangerText}>\n <input type=\"number\" className={getInputStyles(isDanger, className)} {...props} />\n </BasicFormField>\n );\n};\n","import { BasicFormField, getInputStyles } from \"./BasicFormField\";\n\nexport interface FormPasswordProps extends React.InputHTMLAttributes<HTMLInputElement> {\n isDanger?: boolean;\n dangerText?: string;\n}\n\nexport const FormPassword = ({ className, isDanger, dangerText, ...props }: FormPasswordProps) => {\n return (\n <BasicFormField isDanger={isDanger} dangerText={dangerText}>\n <input type=\"password\" className={getInputStyles(isDanger, className)} {...props} />\n </BasicFormField>\n );\n};\n","import { BasicFormField, getInputStyles } from \"./BasicFormField\";\n\nexport interface FormTelProps extends React.InputHTMLAttributes<HTMLInputElement> {\n isDanger?: boolean;\n dangerText?: string;\n}\n\nexport const FormTel = ({ className, isDanger, dangerText, onChange, ...props }: FormTelProps) => {\n const handlePhoneChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const rawValue = e.target.value.replace(/[^0-9]/g, \"\");\n let formattedValue = \"\";\n if (rawValue.length < 4) formattedValue = rawValue;\n else if (rawValue.length < 8) formattedValue = `${rawValue.slice(0, 3)}-${rawValue.slice(3)}`;\n else\n formattedValue = `${rawValue.slice(0, 3)}-${rawValue.slice(3, 7)}-${rawValue.slice(7, 11)}`;\n\n e.target.value = formattedValue;\n if (onChange) onChange(e);\n };\n\n return (\n <BasicFormField isDanger={isDanger} dangerText={dangerText}>\n <input\n type=\"tel\"\n className={getInputStyles(isDanger, className)}\n onChange={handlePhoneChange}\n maxLength={13}\n {...props}\n />\n </BasicFormField>\n );\n};\n","import { useState } from \"react\";\nimport { BasicFormField, getInputStyles } from \"./BasicFormField\";\n\nexport interface FormColorProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, \"type\"> {\n isDanger?: boolean;\n dangerText?: string;\n}\n\nexport const FormColor = ({\n className,\n isDanger,\n dangerText,\n value,\n defaultValue = \"#000000\",\n onChange,\n ...props\n}: FormColorProps) => {\n const [internalColor, setInternalColor] = useState<string>(\n (value as string) || (defaultValue as string) || \"#000000\",\n );\n\n // value가 주어지면(제어 컴포넌트) 항상 그 값을 사용하고, 아니면 내부 상태를 사용\n const color = value !== undefined ? (value as string) : internalColor;\n\n const handleColorChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n setInternalColor(e.target.value);\n onChange?.(e);\n };\n\n return (\n <BasicFormField isDanger={isDanger} dangerText={dangerText}>\n <label\n className={getInputStyles(\n isDanger,\n // 💡 focus-within을 통해 내부 <input>이 포커스될 때 부모(label)의 테두리와 배경 변경!\n \"flex items-center gap-2 relative \" +\n \"focus-within:border-black focus-within:hover:bg-white\" +\n (className || \"\"),\n )}\n >\n {/* 1. 좌측: 색상 스와치 (Color Swatch) */}\n <div className=\"w-6 h-6 shrink-0 overflow-hidden\" style={{ backgroundColor: color }}>\n <input\n type=\"color\"\n value={color}\n onChange={handleColorChange}\n className=\"absolute inset-0 w-full h-full opacity-0\"\n {...props}\n />\n </div>\n\n {/* 2. 중간: 색상 코드 텍스트 */}\n <span className=\"text-primary text-body3-regular uppercase flex-1 select-none\">\n {color}\n </span>\n\n {/* 3. 우측: 추후 아이콘 자리 */}\n </label>\n </BasicFormField>\n );\n};\n","import { useState } from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport { BasicFormField, getInputStyles } from \"./BasicFormField\";\n\nexport interface FormFileProps extends Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n \"onChange\"\n> {\n isDanger?: boolean;\n dangerText?: string;\n fileUrl?: string; // 기존에 서버에 업로드된 파일 주소\n filename?: string; // 💡 변경할 파일 이름 prop (확장자는 자동 유지)\n onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;\n}\n\nexport const FormFile = ({\n className,\n isDanger,\n dangerText,\n fileUrl,\n filename,\n onChange,\n ...props\n}: FormFileProps) => {\n const [selectedFile, setSelectedFile] = useState<File | null>(null);\n\n // 💡 파일 선택 및 파일명 변경 핸들러\n const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const originalFile = e.target.files?.[0];\n\n if (!originalFile) {\n setSelectedFile(null);\n onChange?.(e);\n return;\n }\n\n let finalFile = originalFile;\n\n // filename prop이 넘어왔을 경우 파일명 변경 로직\n if (filename) {\n const lastDotIndex = originalFile.name.lastIndexOf(\".\");\n const extension = lastDotIndex !== -1 ? originalFile.name.slice(lastDotIndex) : \"\";\n const newFileName = filename.endsWith(extension) ? filename : `${filename}${extension}`;\n\n finalFile = new File([originalFile], newFileName, {\n type: originalFile.type,\n lastModified: originalFile.lastModified,\n });\n\n try {\n const dataTransfer = new DataTransfer();\n dataTransfer.items.add(finalFile);\n e.target.files = dataTransfer.files;\n } catch (err) {\n console.warn(\"DataTransfer를 지원하지 않는 브라우저입니다.\", err);\n }\n }\n\n setSelectedFile(finalFile);\n onChange?.(e);\n };\n\n // 💡 파일 다운로드 통합 핸들러\n const handleDownload = (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n if (selectedFile) {\n const url = URL.createObjectURL(selectedFile);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = selectedFile.name;\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n URL.revokeObjectURL(url);\n } else if (fileUrl) {\n const a = document.createElement(\"a\");\n a.href = fileUrl;\n a.download = fileUrl.split(\"/\").pop() || \"download\";\n a.target = \"_blank\";\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n }\n };\n\n // 화면에 표시할 파일 이름 (변경된 로컬 파일명 또는 서버 파일명)\n const displayFileName = selectedFile?.name || (fileUrl ? fileUrl.split(\"/\").pop() : null);\n\n return (\n <BasicFormField isDanger={isDanger} dangerText={dangerText}>\n <div\n className={getInputStyles(\n isDanger,\n // 디자인 스펙: 파일 전 상태는 우측 정렬(\"파일 첨부\"만), 파일 후 상태는 좌우 배치\n cn(\n \"flex items-center gap-2\",\n displayFileName ? \"justify-between\" : \"justify-end\",\n className,\n ),\n )}\n >\n {/* 좌측: 파일명 (파일 첨부 후에만 노출, 밑줄 없는 본문 텍스트) */}\n {displayFileName && (\n <span\n onClick={handleDownload}\n className=\"text-body3-book text-primary truncate max-w-[200px] cursor-pointer\"\n title={`${displayFileName} 다운로드`}\n >\n {displayFileName}\n </span>\n )}\n\n {/* 우측: 파일 선택 / 다시 첨부 버튼 */}\n <label className=\"shrink-0 px-1 -mx-1 cursor-pointer\">\n <div className=\"text-primary text-caption-regular underline\">\n {displayFileName ? \"다시 첨부\" : \"파일 첨부\"}\n </div>\n <input type=\"file\" className=\"hidden\" onChange={handleFileChange} {...props} />\n </label>\n </div>\n </BasicFormField>\n );\n};\n","import { cn } from \"../../lib/cn\";\nimport { IconCheck } from \"../../assets/svgs/Icons\";\n\nexport interface FormCheckBoxProps extends Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n \"onChange\" | \"checked\"\n> {\n isChecked: boolean;\n setIsChecked: (checked: boolean) => void;\n children?: React.ReactNode; // 💡 string 대신 ReactNode로 확장성 증가\n className?: string;\n textStyle?: string;\n}\n\nexport const FormCheckBox = ({\n isChecked,\n setIsChecked,\n children,\n className,\n textStyle,\n ...props\n}: FormCheckBoxProps) => {\n return (\n <label\n className={cn(\n \"group w-fit h-fit\",\n \"flex items-center gap-1\",\n \"cursor-pointer select-none\", // 💡 1. 텍스트 드래그 방지 추가\n className,\n )}\n >\n <input\n type=\"checkbox\"\n checked={isChecked}\n onChange={(e) => setIsChecked(e.target.checked)}\n className=\"sr-only peer\" // 💡 2. peer 추가 (키보드 포커스 감지용)\n {...props}\n />\n\n {/* 디자인 스펙: hover/pressed 배경은 20px 박스에만 적용(radius 4px) */}\n <div\n className={cn(\n \"flex items-center justify-center w-5 h-5 shrink-0 rounded transition-colors\",\n \"group-hover:bg-gray00 group-active:bg-gray01\",\n )}\n >\n <div\n className={cn(\n \"w-[15px] h-[15px]\",\n \"box-border border border-black\",\n \"flex items-center justify-center transition-colors duration-200\",\n\n // 💡 3. 키보드 Tab 이동 시 접근성 향상 (포커스 링 표시)\n \"peer-focus-visible:ring-2 peer-focus-visible:ring-black peer-focus-visible:ring-offset-1\",\n )}\n >\n {isChecked && <IconCheck />}\n </div>\n </div>\n\n {/* 💡 5. children이 전달되었을 때만 span을 렌더링하도록 조건부 처리 */}\n {children && (\n <span className={cn(\"text-body3-book text-primary\", textStyle)}>{children}</span>\n )}\n </label>\n );\n};\n","import { useEffect, useRef, useState } from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport { BasicFormField, getInputStyles } from \"./BasicFormField\";\nimport { SelectBoxOption } from \"./SelectBoxOption\";\nimport { IconChevronDownXS } from \"../../assets/svgs/Icons\";\n\nexport interface FormSelectBoxProps {\n options: string[];\n value: string;\n onChange: (option: string) => void;\n placeholder?: string;\n isDanger?: boolean;\n dangerText?: string;\n className?: string;\n}\n\nexport const FormSelectBox = ({\n options,\n value,\n onChange,\n placeholder = \"선택해주세요\",\n isDanger,\n dangerText,\n className,\n}: FormSelectBoxProps) => {\n const [isOpen, setIsOpen] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n\n // 외부 클릭 시 드롭다운 닫기\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(event.target as Node)) {\n setIsOpen(false);\n }\n };\n\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () => {\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, []);\n\n return (\n <BasicFormField isDanger={isDanger} dangerText={dangerText}>\n {/* 상대 위치(relative)의 기준점이 되는 컨테이너 */}\n <div ref={containerRef} className=\"relative w-full\">\n {/* 1. Select Box 트리거 (Input과 똑같이 생겨야 함!) */}\n <div\n tabIndex={0} // 💡 포커스를 받을 수 있게 설정\n className={getInputStyles(\n isDanger,\n cn(\n \"flex items-center justify-between cursor-pointer select-none\",\n isOpen && \"border-gray08\", // 열려있을 때 테두리 #3A414C 고정 (디자인 스펙)\n className,\n ),\n )}\n onClick={(e) => {\n if (isOpen) {\n e.currentTarget.blur(); // 💡 닫힐 때는 포커스(Focus)를 강제로 해제합니다!\n }\n setIsOpen((prev) => !prev);\n }}\n >\n {/* 선택값이 있으면 검은색(primary), 없으면 회색(quaternary) Placeholder 표시 */}\n <span className={value ? \"text-primary\" : \"text-quaternary\"}>{value || placeholder}</span>\n {/* 💡 보너스: 열려있을 때 아이콘 180도 회전 애니메이션 */}\n <IconChevronDownXS\n className={cn(\"text-gray06 transition-transform\", isOpen && \"rotate-180\")}\n stroke=\"currentColor\"\n />\n {/* <img\n src={chevronDown}\n alt=\"dropdown\"\n className={cn(\"transition-transform\", isOpen && \"rotate-180\")}\n /> */}\n </div>\n\n {/* 2. Dropdown 메뉴 리스트 */}\n {isOpen && (\n <ul\n className={cn(\n \"absolute top-full left-0 right-0 z-10\", // 💡 Input 바로 아래에 띄움\n \"box-border border border-gray02 bg-white flex flex-col\",\n \"max-h-50 overflow-y-auto\", // 항목이 너무 많으면 스크롤 생성 (디자인 스펙: 그림자 없음)\n )}\n >\n {options.map((option) => (\n <SelectBoxOption\n key={option}\n label={option}\n // value={value}\n onClick={() => {\n onChange(option);\n setIsOpen(false); // 선택 후 자동으로 닫힘\n }}\n />\n ))}\n </ul>\n )}\n </div>\n </BasicFormField>\n );\n};\n","import { cn } from \"../../lib/cn\";\n\nexport interface SelectBoxOptionProps {\n label: string;\n onClick: () => void;\n // selectedLabel: string;\n className?: string;\n}\n\nexport const SelectBoxOption = ({\n label,\n onClick,\n // selectedLabel,\n className,\n}: SelectBoxOptionProps) => {\n // const isSelected = label === selectedLabel;\n return (\n <li\n onClick={onClick}\n className={cn(\n \"w-full p-3 shrink-0\", // 디자인 스펙: 12px 패딩\n \"flex items-center justify-start\",\n // \"box-border border-b border-gray02\",\n \"text-body3-book text-primary\",\n \"bg-white hover:bg-gray00 active:bg-gray01\",\n // isSelected\n // ? \"bg-black text-white\"\n // : \"\",\n className,\n )}\n >\n {label}\n </li>\n );\n};\n","import { cn } from \"../../lib/cn\";\n\ntype CommonProps = {\n children: React.ReactNode;\n /** 텍스트 앞/뒤에 붙는 아이콘 (예: 도움말 ⓘ, 경고 아이콘) */\n icon?: React.ReactNode;\n iconPosition?: \"left\" | \"right\";\n /** 위험/경고 강조 색상 */\n alert?: boolean;\n /** 밑줄 표시 여부 (기본 true) */\n underline?: boolean;\n className?: string;\n};\n\nexport type TextButtonProps = CommonProps &\n (\n | ({ href: string } & Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, keyof CommonProps>)\n | ({ href?: undefined } & Omit<\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n keyof CommonProps\n >)\n );\n\n/**\n * 인라인 텍스트 버튼/링크.\n * 예: \"파일 제작 가이드\", \"파일 첨부\", \"더 보기\", \"다시 시도\"\n */\nexport const TextButton = ({\n children,\n icon,\n iconPosition = \"left\",\n alert = false,\n underline = true,\n className,\n ...props\n}: TextButtonProps) => {\n const content = (\n <>\n {icon && iconPosition === \"left\" && (\n <span className=\"flex shrink-0 items-center\">{icon}</span>\n )}\n <span className={cn(underline && \"underline underline-offset-2\")}>{children}</span>\n {icon && iconPosition === \"right\" && (\n <span className=\"flex shrink-0 items-center\">{icon}</span>\n )}\n </>\n );\n\n const classes = cn(\n \"inline-flex w-fit items-center gap-1 px-1 -mx-1\",\n \"text-caption-book\",\n alert ? \"text-danger\" : \"text-secondary\",\n \"hover:bg-gray00 active:bg-gray01 transition-colors\",\n alert ? \"hover:text-danger\" : \"hover:text-primary\",\n \"cursor-pointer select-none\",\n \"disabled:cursor-default disabled:text-quaternary disabled:hover:bg-transparent\",\n \"aria-disabled:cursor-default aria-disabled:text-quaternary aria-disabled:hover:bg-transparent\",\n className,\n );\n\n if (props.href !== undefined) {\n const { href, ...rest } = props as React.AnchorHTMLAttributes<HTMLAnchorElement> & {\n href: string;\n };\n return (\n <a href={href} className={classes} {...rest}>\n {content}\n </a>\n );\n }\n\n const buttonProps = props as React.ButtonHTMLAttributes<HTMLButtonElement>;\n return (\n <button type=\"button\" className={classes} {...buttonProps}>\n {content}\n </button>\n );\n};\n","import { useEffect, useRef, useState } from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport { SelectBoxOption } from \"../Form/SelectBoxOption\";\nimport { IconChevronDownXS } from \"../../assets/svgs/Icons\";\n\nexport interface DropdownProps {\n selectedLabel: string;\n setSelectedLabel: (label: string) => void;\n labels: string[];\n className?: string;\n}\n\nexport const Dropdown = ({ selectedLabel, setSelectedLabel, labels, className }: DropdownProps) => {\n const [isOpen, setIsOpen] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(event.target as Node)) {\n setIsOpen(false);\n }\n };\n\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () => {\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, []);\n\n return (\n <div ref={containerRef} className=\"relative\">\n <div\n className={cn(\n \"w-fit h-fit px-2 py-1\",\n \"flex items-center justify-center gap-1.5\",\n \"text-body3-book text-strong\",\n \"bg-white hover:bg-gray00 active:bg-gray01\",\n \"cursor-pointer\",\n className,\n )}\n onClick={() => setIsOpen((prev) => !prev)}\n >\n <p>{selectedLabel}</p>\n <IconChevronDownXS\n className={cn(\"text-gray06 transition-transform\", isOpen && \"rotate-180\")}\n stroke=\"currentColor\"\n />\n </div>\n {isOpen && (\n <div className={cn(\"absolute top-full right-0 z-10\", \"box-border border border-gray02\")}>\n {labels.map((label) => (\n <SelectBoxOption\n key={label}\n label={label}\n // selectedLabel={selectedLabel}\n onClick={() => {\n setSelectedLabel(label);\n setIsOpen(false);\n }}\n className=\"w-44 h-11 justify-center\" // 💡 부모 Input의 가로 너비에 꽉 차도록 설정\n />\n ))}\n </div>\n )}\n </div>\n );\n};\n","import { cn } from \"../../lib/cn\";\n// 💡 TagProps를 꼭 같이 import 해주세요!\nimport type { TagProps } from \"../Tag/Tag\";\n\n// 1. 기본 HTMLAttributes에서 'children' 속성을 제외(Omit)합니다.\nexport interface ListProps extends Omit<React.HTMLAttributes<HTMLLIElement>, \"children\"> {\n className?: string;\n label1?: string;\n label2?: string;\n label2OnClick?: () => void;\n label3?: string;\n disabled?: boolean;\n selected?: boolean;\n onClick?: () => void;\n children?: React.ReactElement<TagProps> | React.ReactElement<TagProps>[];\n}\n\nexport function List({\n className,\n label1,\n label2,\n label2OnClick,\n label3,\n disabled = false,\n selected = false,\n onClick,\n children,\n ...props\n}: ListProps) {\n return (\n <li\n className={cn(\n \"w-full min-w-fit h-13 pl-4 pr-6\",\n \"grid grid-cols-[4fr_1fr_1fr] items-center gap-4\",\n \"bg-white hover:bg-gray00 hover:has-[.has-clickable:hover]:bg-white active:bg-gray01\",\n \"text-primary select-none [&_*]:cursor-pointer cursor-pointer\",\n disabled && \"opacity-40 [&_*]:cursor-pointer cursor-pointer\",\n selected &&\n \"bg-black text-white hover:bg-black active:bg-black hover:has-[.has-clickable:hover]:bg-black\",\n className,\n )}\n {...props}\n onClick={onClick}\n // onClickCapture={(e) => {\n // if (disabled) {\n // e.stopPropagation();\n // e.preventDefault();\n // }\n // }}\n >\n <section className={cn(\"flex items-center gap-4\")}>\n <label className={cn(\"text-body2-regular\")}>{label1 ? label1 : \"-\"}</label>\n <div className={cn(\"flex items-center gap-2\")}>\n {/* 3. 들어온 children을 그대로 렌더링합니다. */}\n {children}\n </div>\n </section>\n <label\n className={cn(\n \"text-body3-book truncate p-1 w-fit\",\n label2OnClick && \"underline has-clickable\",\n label2OnClick && !selected && \"hover:bg-gray00\",\n )}\n onClick={label2OnClick}\n >\n {label2 ? label2 : \"-\"}\n </label>\n <label className={cn(\"text-body3-regular text-right\")}>{label3 ? label3 : \"-\"}</label>\n </li>\n );\n}\n","import React from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport { IconClose } from \"../../assets/svgs/Icons\";\n\nexport interface ModalProps {\n isVisible: boolean;\n header: string;\n children: React.ReactNode;\n className?: string;\n /**\n * 지정하면 배경(백드롭) 클릭 시 호출되고, 카드 우상단에 닫기(X) 버튼이 노출된다.\n * 생략하면 배경은 딤 처리만 되고 클릭해도 닫히지 않는다.\n */\n onClose?: () => void;\n}\n\ninterface BaseProps {\n children: React.ReactNode;\n className?: string;\n row?: boolean;\n}\n\nconst ModalBase = ({ isVisible, header, children, className, onClose }: ModalProps) => {\n if (!isVisible) return null;\n return (\n <div className={cn(\"fixed inset-0 z-50\")}>\n {/* 배경 딤 레이어: outer(z-50)와 카드(z-1001) 사이 */}\n <div\n aria-hidden\n onClick={onClose}\n className={cn(\"fixed inset-0 z-1000 bg-black/10\", onClose && \"cursor-pointer\")}\n />\n {/* 카드 정렬용 레이어: 자신은 클릭을 받지 않고, 바깥 클릭은 뒤의 딤 레이어로 통과시킨다 */}\n <div className=\"fixed inset-0 z-1001 flex items-center justify-center pointer-events-none\">\n <main\n role=\"dialog\"\n aria-modal=\"true\"\n className={cn(\n \"relative w-110 pt-8 h-fit pointer-events-auto\",\n \"flex flex-col items-center\",\n \"border border-gray02\",\n \"bg-white shadow-[0px_0px_30px_0px_rgba(0,0,0,0.08)]\",\n className,\n )}\n >\n {onClose && (\n <button\n type=\"button\"\n onClick={onClose}\n aria-label=\"닫기\"\n className={cn(\n \"absolute right-3 top-3 flex size-8 items-center justify-center\",\n \"text-tertiary transition-colors hover:bg-gray00 active:bg-gray01 cursor-pointer\",\n )}\n >\n <IconClose />\n </button>\n )}\n <h1 className={cn(\"text-strong font-[500] text-[24px] leading-[32px]\")}>{header}</h1>\n {children}\n </main>\n </div>\n </div>\n );\n};\n\nconst Contents = ({ children, className }: BaseProps) => {\n return (\n <div\n className={cn(\n \"flex flex-col items-center gap-8\",\n \"w-full h-fit\",\n \"px-14 pt-8 pb-9\",\n className,\n )}\n >\n {children}\n </div>\n );\n};\n\nconst CTAs = ({ children, className, row = false }: BaseProps) => {\n // children이 없으면(CTA가 0개) 아예 렌더링하지 않음\n if (!children) return null;\n\n return (\n // CTA 버튼들을 중앙에 배치하는 예시 (우측 정렬이 필요하면 justify-end 사용)\n <div\n className={cn(\n \"flex flex-col w-full h-fit\",\n row && \"flex-row divide-x divide-gray02\",\n className,\n )}\n >\n {children}\n </div>\n );\n};\n\nexport const Modal = Object.assign(ModalBase, {\n Contents,\n CTAs,\n});\n","import { cn } from \"../../lib/cn\";\nimport { ModalTextStyle } from \"../Column/ColumnText\";\n\nexport interface ModalTextProps {\n children: React.ReactNode;\n className?: string;\n}\n\nexport const ModalText = ({ children, className }: ModalTextProps) => {\n return (\n <div\n className={cn(\n \"flex flex-col items-center\",\n \"mt-[-20px] mb-[-4px]\",\n ModalTextStyle,\n \"text-tertiary text-center\",\n className,\n )}\n >\n {children}\n </div>\n );\n};\n","import { cn } from \"../../lib/cn\";\n\nexport interface CategorySegmentProps {\n selected?: boolean;\n label: string;\n className?: string;\n onClick?: () => void;\n}\n\nexport const CategorySegment = ({\n selected = false,\n label,\n className,\n onClick,\n}: CategorySegmentProps) => {\n return (\n <div\n className={cn(\n \"w-fit h-8 px-3.5\",\n \"flex items-center justify-center\",\n // 피그마랑 조금 다르게 적용하였음. 이게 더 효율적\n \"border-r border-gray02 cursor-pointer\",\n \"text-body3-book text-strong\",\n selected\n ? \"bg-black text-white\" // selected 상태\n : \"bg-white text-strong hover:bg-gray00 active:bg-gray01\", // default, hover, pressed 상태\n className,\n )}\n onClick={onClick}\n >\n {label}\n </div>\n );\n};\n","import { cn } from \"../../lib/cn\";\nimport { CategorySegment } from \"./CategorySegment\";\n\nexport interface CategorySegmentedControlProps {\n variable: \"info\" | \"archive\" | \"notice\" | \"infoTag\";\n setSelectedCategory: (label: string) => void;\n selectedCategory: string;\n className?: string;\n}\n\nconst categorySegments: Record<CategorySegmentedControlProps[\"variable\"], string[]> = {\n info: [\"공용 물품\", \"일반 기자재\", \"특수 기자재\"],\n archive: [\"프린트실\", \"홍익시디\"],\n notice: [\"일반 공지\", \"긴급 공지\"],\n infoTag: [\"가공\", \"제본\", \"출력\", \"스캔\", \"기타\"],\n};\n\nexport const CategorySegmentedControl = ({\n variable,\n setSelectedCategory,\n selectedCategory,\n className,\n}: CategorySegmentedControlProps) => {\n const segments = categorySegments[variable];\n\n return (\n <div className={cn(\"w-full h-fit flex items-center justify-start\", className)}>\n <div\n className={cn(\n \"w-fit h-8 px-3.5\",\n \"flex items-center justify-center\",\n // 피그마랑 조금 다르게 적용하였음. 이게 더 효율적\n \"border-r border-gray02\",\n \"text-body3-medium text-strong\",\n )}\n >\n {variable === \"infoTag\" ? \"태그 선택\" : \"카테고리 선택\"}\n </div>\n {segments.map((label) => (\n <CategorySegment\n key={label}\n label={label}\n selected={selectedCategory === label}\n onClick={() => setSelectedCategory(label)}\n />\n ))}\n </div>\n );\n};\n","import { cn } from \"../../lib/cn\";\n\nexport interface TitleInputProps {\n title?: string;\n onChange: (value: string) => void;\n className?: string;\n}\n\nexport const TitleInput = ({ title, onChange, className }: TitleInputProps) => {\n return (\n <input\n type=\"text\"\n value={title}\n onChange={(e) => onChange(e.target.value)}\n placeholder=\"제목을 입력하세요\"\n className={cn(\n \"w-full min-w-[200px] h-12 px-3\",\n // 피그마랑 매우 다름. focus되었을 때 테두리 중복 문제 등\n \"box-border border-b border-gray02 border-t border-t-white\",\n \"focus:border-black focus:border focus:outline-none\",\n \"text-head2-medium text-strong placeholder:text-gray03\",\n className,\n )}\n />\n );\n};\n","import { cn } from \"../../lib/cn\";\n\nexport interface NoticeBadgeProps {\n variable: NoticeBadgeVariable;\n className?: string;\n onClick?: () => void;\n}\n\nexport type NoticeBadgeVariable = \"urgent\" | \"common\";\n\nexport const NoticeBadge = ({ variable, className, onClick }: NoticeBadgeProps) => {\n return (\n <button\n type=\"button\"\n className={cn(\n // 너비 피그마에서는 fit으로 69px로 되어있는데, 69px로 하면 글자가 잘려서 72px로 잡음. 컨펌 필요\n \"w-18 h-8 box-border px-2 py-1 text-center text-body3-book cursor-pointer\",\n /** Urgent */ `${variable === \"urgent\" ? \"bg-black text-white\" : \"\"}`,\n /** Common */ `${variable === \"common\" ? \"border border-gray03 text-strong\" : \"\"}`, //이거 배경 없는 거 맞겠지...?\n className,\n )}\n onClick={onClick}\n >\n {variable === \"urgent\" ? \"긴급 공지\" : \"일반 공지\"}\n </button>\n );\n};\n","import { cn } from \"../../lib/cn\";\nimport { NoticeBadge } from \"./NoticeBadge\";\n\nexport interface NoticeBarProps {\n variable: NoticeBarVariable;\n badgeVariable: NoticeBarBadgeVariable;\n title: string;\n date: string;\n className?: string;\n onClick?: () => void;\n}\n\nexport type NoticeBarVariable = \"default\" | \"hover\" | \"pressed\";\nexport type NoticeBarBadgeVariable = \"urgent\" | \"common\";\n\nexport const NoticeBar = ({\n variable = \"default\",\n badgeVariable,\n title,\n date,\n className,\n onClick,\n}: NoticeBarProps) => {\n return (\n <div\n // 최소 너비 임시로 적어둠 -> 수정 요망!\n className={cn(\n \"w-full min-w-200 h-15 px-4 py-3.5 flex items-center justify-between box-border border-b border-gray02 cursor-pointer\",\n variable === \"default\" && \"bg-white hover:bg-gray00 active:bg-gray01\",\n variable === \"hover\" && \"bg-gray00\",\n variable === \"pressed\" && \"bg-gray01\",\n className,\n )}\n onClick={onClick}\n >\n <section className=\"flex items-center gap-3\">\n <NoticeBadge variable={badgeVariable} />\n <h1 className=\"text-head1-medium text-strong\">{title}</h1>\n </section>\n {/* 이거 나중에 수정해야함 */}\n <p className=\"text-body3-book text-tertiary\">{date}</p>\n </div>\n );\n};\n","import { cn } from \"../../lib/cn\";\nimport { IconSearch } from \"../../assets/svgs/Icons\";\n\nexport interface SearchBarProps {\n value?: string;\n onChange?: (value: string) => void;\n className?: string;\n}\n\nexport const SearchBar = ({ value, onChange, className }: SearchBarProps) => {\n return (\n <label\n className={cn(\n \"w-full h-12 pl-4 pr-3\",\n \"flex items-center gap-2\",\n \"box-border border-b border-gray02 border-t border-t-white\",\n \"focus-within:border-black focus-within:border focus-within:outline-none\",\n className,\n )}\n >\n <IconSearch />\n <input\n type=\"text\"\n placeholder=\"검색어를 입력해주세요\"\n value={value}\n onChange={(e) => onChange?.(e.target.value)}\n className={cn(\n \"w-full focus:outline-none\",\n \"text-body1-book text-strong placeholder:text-quaternary\",\n )}\n />\n </label>\n );\n};\n","import { forwardRef, type CSSProperties } from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport { useControllableState } from \"../../lib/useControllableState\";\nimport {\n IconChevronDownXS,\n IconExclamation,\n IconRadioSelected,\n IconRadioUnselected,\n} from \"../../assets/svgs/Icons\";\n\nexport type PrintColor =\n \"Plotter\" | \"Printer\" | \"Riso\" | \"Fluorescent\" | \"UV\" | \"Seet Cutting\" | \"Laser Cutting\";\n\n// Tailwind는 클래스 이름을 정적 문자열로만 인식하므로 `bg-${...}` 같은 템플릿\n// 조합은 빌드 시 클래스가 생성되지 않는다(퍼지됨). 그래서 색상별 클래스를 전부 나열해둔다.\nconst printColorBgClass: Record<PrintColor, string> = {\n Plotter: \"bg-print-plotter\",\n Printer: \"bg-print-printer\",\n Riso: \"bg-print-riso\",\n Fluorescent: \"bg-print-fluorescent\",\n UV: \"bg-print-uv\",\n \"Seet Cutting\": \"bg-print-seet-cutting\",\n \"Laser Cutting\": \"bg-print-laser-cutting\",\n};\n\nexport type RadioToggle = {\n title: string;\n content: string;\n /**\n * 선택 상태를 식별할 값. 표시 텍스트(title)와 분리하고 싶을 때 사용한다.\n * 생략하면 title이 식별자로 쓰인다. onSelect도 이 값을 넘겨준다.\n */\n value?: string;\n badges?: string[];\n /** 선택됐을 때 라디오 행에 입힐 배경색(팔레트). `color`가 있으면 무시된다. */\n printColor?: PrintColor;\n /**\n * 선택됐을 때 라디오 행에 입힐 임의 배경색(hex/rgb/CSS 변수 등).\n * 고정 팔레트(printColor) 밖의 색이 필요할 때 사용한다.\n */\n color?: string;\n /** 라디오 행(button)에 덧붙일 클래스. 보더/그룹 구분 등 앱별 커스터마이징 훅. */\n className?: string;\n labelTextButton?: string;\n onClickTextButton?: () => void;\n};\n\nconst itemKey = (item: RadioToggle) => item.value ?? item.title;\n\nexport interface SideRadioAccordionProps {\n step: number;\n title: string;\n radioToggleList: RadioToggle[];\n /** controlled: 현재 선택된 항목의 value(없으면 title). `null`이면 미선택. */\n selected?: string | null;\n /** uncontrolled 초기 선택값. `selected`를 함께 주면 무시된다. */\n defaultSelected?: string;\n /** 선택이 바뀔 때 호출. 인자는 항목의 value(없으면 title). */\n onSelect?: (value: string) => void;\n /** 헤더(Stepper)를 스크롤 컨테이너 상단에 고정한다. */\n stickyHeader?: boolean;\n /** 헤더 클릭으로 접기/펼치기를 허용할지. false면 항상 펼쳐지고 chevron도 감춘다. 기본 true. */\n collapsible?: boolean;\n /** uncontrolled 펼침 초기값. 기본 true. */\n defaultOpen?: boolean;\n /** controlled 펼침 상태. */\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n quantityLimitLabel?: string;\n onClickQuantityLimit?: () => void;\n className?: string;\n}\n\nexport const SideRadioAccordion = forwardRef<HTMLDivElement, SideRadioAccordionProps>(\n function SideRadioAccordion(\n {\n step,\n title,\n radioToggleList,\n selected,\n defaultSelected,\n onSelect,\n stickyHeader = false,\n collapsible = true,\n defaultOpen = true,\n open,\n onOpenChange,\n quantityLimitLabel,\n onClickQuantityLimit,\n className,\n },\n ref,\n ) {\n const [selectedValue, setSelectedValue] = useControllableState<string | null>(\n selected,\n defaultSelected ?? null,\n );\n const [isOpen, setIsOpen] = useControllableState<boolean>(open, defaultOpen);\n const expanded = collapsible ? isOpen : true;\n\n const handleSelect = (value: string) => {\n setSelectedValue(value);\n onSelect?.(value);\n };\n\n const toggleOpen = () => {\n if (!collapsible) return;\n const next = !isOpen;\n setIsOpen(next);\n onOpenChange?.(next);\n };\n\n return (\n <div ref={ref} className={cn(\"w-full border-r border-gray02 bg-white\", className)}>\n <Stepper\n step={step}\n title={title}\n isOpen={expanded}\n collapsible={collapsible}\n onClick={toggleOpen}\n className={cn(stickyHeader && \"sticky top-0 z-10\")}\n />\n {expanded && (\n <div className=\"flex flex-col divide-y divide-gray02\">\n {radioToggleList.map((item) => (\n <RadioToggleItem\n key={itemKey(item)}\n {...item}\n open={selectedValue === itemKey(item)}\n onSelect={() => handleSelect(itemKey(item))}\n />\n ))}\n {quantityLimitLabel && (\n <div className=\"px-5 py-4\">\n <TextButton label={quantityLimitLabel} onClick={onClickQuantityLimit} />\n </div>\n )}\n </div>\n )}\n </div>\n );\n },\n);\n\ninterface StepperProps {\n step: number;\n title: string;\n isOpen: boolean;\n collapsible: boolean;\n onClick: () => void;\n className?: string;\n}\nconst Stepper = ({ step, title, isOpen, collapsible, onClick, className }: StepperProps) => {\n const label = (\n <span>\n {step} | {title}\n </span>\n );\n const base =\n \"w-full flex items-center justify-between px-5 py-2.5 text-head3-medium text-primary text-left bg-white border-b border-gray02\";\n\n if (!collapsible) {\n return <div className={cn(base, className)}>{label}</div>;\n }\n\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className={cn(base, \"cursor-pointer hover:bg-gray00 active:bg-gray01\", className)}\n >\n {label}\n <IconChevronDownXS className={cn(\"transition-transform\", isOpen && \"rotate-180\")} />\n </button>\n );\n};\n\ninterface RadioToggleItemProps extends RadioToggle {\n open: boolean;\n onSelect: () => void;\n}\nconst RadioToggleItem = ({\n title,\n content,\n badges,\n printColor,\n color,\n className,\n labelTextButton,\n onClickTextButton,\n open,\n onSelect,\n}: RadioToggleItemProps) => {\n const rowBg = !open\n ? \"bg-white hover:bg-gray00\"\n : color\n ? undefined // 인라인 style이 배경을 담당\n : printColor\n ? printColorBgClass[printColor]\n : \"bg-gray00\";\n const style: CSSProperties | undefined = open && color ? { backgroundColor: color } : undefined;\n\n return (\n <div className=\"w-full\">\n <button\n type=\"button\"\n onClick={onSelect}\n style={style}\n className={cn(\n \"w-full flex items-center gap-1.5 p-3\",\n \"text-body1-regular text-secondary text-left cursor-pointer\",\n rowBg,\n className,\n )}\n >\n <Radio selected={open} />\n <span>{title}</span>\n </button>\n {open && (\n <div className=\"flex flex-col gap-2 px-3 py-3 bg-white\">\n <p className=\"text-caption-regular text-secondary\">{content}</p>\n {badges && badges.length > 0 && (\n <div className=\"flex flex-wrap gap-1\">\n {badges.map((badge) => (\n <Badge key={badge} label={badge} />\n ))}\n </div>\n )}\n {labelTextButton && (\n <TextButton\n label={labelTextButton}\n onClick={onClickTextButton}\n showIcon\n className=\"self-end\"\n />\n )}\n </div>\n )}\n </div>\n );\n};\n\ninterface RadioProps {\n selected?: boolean;\n className?: string;\n}\nconst Radio = ({ selected = false, className }: RadioProps) => {\n const Icon = selected ? IconRadioSelected : IconRadioUnselected;\n return <Icon className={cn(\"w-6 h-6\", className)} />;\n};\n\ninterface TextButtonProps {\n label: string;\n onClick?: () => void;\n showIcon?: boolean;\n className?: string;\n}\nconst TextButton = ({ label, onClick, showIcon = false, className }: TextButtonProps) => {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n disabled={!onClick}\n className={cn(\n \"w-fit h-fit px-1.5 py-0.5 flex items-center gap-1\",\n \"text-primary text-caption-regular underline\",\n onClick && \"cursor-pointer hover:bg-gray00 active:bg-gray01\",\n className,\n )}\n >\n {showIcon && <IconExclamation />}\n {label}\n </button>\n );\n};\n\ninterface BadgeProps {\n label?: string;\n className?: string;\n}\nconst Badge = ({ label, className }: BadgeProps) => {\n return (\n <div\n className={cn(\n \"w-fit h-fit px-2 py-0.5 border border-gray02 shrink-0 whitespace-nowrap\",\n \"text-tertiary text-caption-book\",\n className,\n )}\n >\n {label}\n </div>\n );\n};\n","import { useCallback, useState } from \"react\";\n\n/**\n * controlled/uncontrolled를 함께 지원하는 상태 훅.\n *\n * `controlled` 값이 `undefined`가 아니면(= `null` 포함) controlled로 간주하고\n * 내부 상태를 갱신하지 않는다. `undefined`면 uncontrolled로 동작한다.\n *\n * @returns `[value, setValue, isControlled]`\n */\nexport function useControllableState<T>(controlled: T | undefined, defaultValue: T) {\n const isControlled = controlled !== undefined;\n const [uncontrolled, setUncontrolled] = useState<T>(defaultValue);\n const value = isControlled ? (controlled as T) : uncontrolled;\n\n const setValue = useCallback(\n (next: T) => {\n if (!isControlled) setUncontrolled(next);\n },\n [isControlled],\n );\n\n return [value, setValue, isControlled] as const;\n}\n","import { cn } from \"../../lib/cn\";\n\nexport interface TagProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n className?: string;\n children: string | React.ReactNode;\n selected?: boolean;\n onClick?: () => void;\n bgColor?: string;\n}\n\nexport const Tag = ({\n className,\n children,\n selected = false,\n disabled = false,\n bgColor,\n onClick,\n ...props\n}: TagProps) => {\n return (\n <button\n className={cn(\n \"tag\",\n \"w-fit h-8 px-2.5\",\n \"text-primary text-body2-regular transition-colors\",\n \"box-border border border-gray02\",\n \"bg-white\",\n // bgColor && `bg-[${bgColor}] border-none`,\n onClick && \"cursor-pointer hover:bg-gray00 active:bg-gray01 cursor-pointer has-clickable\",\n selected && \"text-white bg-black border-black hover:bg-black active:bg-black\",\n \"disabled:text-gray04 disabled:bg-gray02 disabled:border-gray02 disabled:cursor-not-allowed\",\n className,\n )}\n onClick={onClick}\n disabled={disabled}\n style={bgColor ? { backgroundColor: bgColor, border: \"none\" } : undefined}\n {...props}\n >\n <span>{children}</span>\n </button>\n );\n};\n","import { forwardRef, type CSSProperties } from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport { WeekNavigation, type Week } from \"./WeekNavigation\";\nimport { formatDayLabel } from \"./dateUtils\";\n\nexport type PrintColor =\n \"Plotter\" | \"Printer\" | \"Riso\" | \"Fluorescent\" | \"UV\" | \"Seet Cutting\" | \"Laser Cutting\";\n\n// Tailwind는 클래스 이름을 정적 문자열로만 인식하므로 `hover:bg-${...}` 같은 템플릿\n// 조합은 빌드 시 클래스가 생성되지 않는다(퍼지됨). 그래서 색상별 클래스를 전부 나열해둔다.\nconst printColorHoverClass: Record<PrintColor, string> = {\n Plotter: \"hover:bg-print-plotter\",\n Printer: \"hover:bg-print-printer\",\n Riso: \"hover:bg-print-riso\",\n Fluorescent: \"hover:bg-print-fluorescent\",\n UV: \"hover:bg-print-uv\",\n \"Seet Cutting\": \"hover:bg-print-seet-cutting\",\n \"Laser Cutting\": \"hover:bg-print-laser-cutting\",\n};\n\nexport type TimeSlotState = \"none\" | \"default\" | \"disabled\" | \"selected\";\n\nexport interface TimeSlot {\n time: string;\n state: TimeSlotState;\n /** state가 \"default\"/\"selected\"일 때만 사용되는 hover 색상(팔레트). `color`가 있으면 무시. */\n printColor?: PrintColor;\n /** 고정 팔레트 밖의 임의 hover 색상(hex/rgb/CSS 변수 등). */\n color?: string;\n /** 셀(div)에 덧붙일 클래스. 보더/그룹 구분 등 앱별 커스터마이징 훅. */\n className?: string;\n}\n\nexport interface DayColumn {\n /** 해당 요일의 ISO 날짜(\"YYYY-MM-DD\") */\n date: string;\n slots: TimeSlot[];\n}\n\nexport interface TimetableProps {\n /** 표시 중인 주의 월요일(ISO \"YYYY-MM-DD\") */\n weekStart: string;\n week: Week;\n /** 월~금 5개, 왼쪽부터 순서대로 */\n days: DayColumn[];\n onPrevWeek?: () => void;\n onNextWeek?: () => void;\n onSelectSlot?: (date: string, time: string) => void;\n /**\n * true면 열 너비가 고정폭(72px) 대신 컨테이너 폭에 맞춰 균등하게 늘어난다.\n * 기존 고정폭 레이아웃이 필요하면 생략한다.\n */\n fluid?: boolean;\n /** 상단 주간 네비게이션을 숨긴다(외부에서 별도로 렌더링할 때). */\n hideWeekNavigation?: boolean;\n /** 주간 네비게이션의 이전/다음 버튼 노출을 명시적으로 제어(생략 시 week로 자동 판단). */\n canPrevWeek?: boolean;\n canNextWeek?: boolean;\n className?: string;\n}\n\nexport const Timetable = forwardRef<HTMLDivElement, TimetableProps>(function Timetable(\n {\n weekStart,\n week,\n days,\n onPrevWeek,\n onNextWeek,\n onSelectSlot,\n fluid = false,\n hideWeekNavigation = false,\n canPrevWeek,\n canNextWeek,\n className,\n },\n ref,\n) {\n return (\n <div ref={ref} className={cn(fluid && \"w-full\", className)}>\n {!hideWeekNavigation && (\n <WeekNavigation\n date={weekStart}\n week={week}\n canPrev={canPrevWeek}\n canNext={canNextWeek}\n onPrevWeek={onPrevWeek}\n onNextWeek={onNextWeek}\n />\n )}\n <div className={cn(\"flex\", fluid && \"w-full\")}>\n {days.map((day) => (\n <DailyTimetable\n key={day.date}\n date={day.date}\n slots={day.slots}\n fluid={fluid}\n onSelectTime={onSelectSlot ? (time) => onSelectSlot(day.date, time) : undefined}\n />\n ))}\n </div>\n </div>\n );\n});\n\ninterface DailyTimetableProps {\n date: string;\n slots: TimeSlot[];\n fluid?: boolean;\n onSelectTime?: (time: string) => void;\n className?: string;\n}\nconst DailyTimetable = ({ date, slots, fluid, onSelectTime, className }: DailyTimetableProps) => {\n return (\n <div className={cn(\"flex flex-col\", fluid ? \"flex-1 min-w-0\" : \"w-18\", className)}>\n <div className=\"h-12 flex items-center justify-center border-b border-gray02 text-body1-regular text-secondary\">\n {formatDayLabel(date)}\n </div>\n {slots.map((slot) => (\n <TimeItem\n key={slot.time}\n state={slot.state}\n label={slot.time}\n printColor={slot.printColor}\n color={slot.color}\n fluid={fluid}\n className={slot.className}\n onClick={onSelectTime ? () => onSelectTime(slot.time) : undefined}\n />\n ))}\n </div>\n );\n};\n\ninterface TimeItemProps {\n state: TimeSlotState;\n label?: string;\n printColor?: PrintColor;\n color?: string;\n fluid?: boolean;\n onClick?: () => void;\n className?: string;\n}\nconst TimeItem = ({\n state,\n label,\n printColor,\n color,\n fluid,\n onClick,\n className,\n}: TimeItemProps) => {\n const clickable = (state === \"default\" || state === \"selected\") && !!onClick;\n const style: CSSProperties | undefined =\n state === \"default\" && color ? ({ \"--tt-hover\": color } as CSSProperties) : undefined;\n\n return (\n <div\n onClick={clickable ? onClick : undefined}\n style={style}\n className={cn(\n \"h-18 flex items-center justify-center border-b border-gray02\",\n fluid ? \"w-full\" : \"w-18\",\n \"text-body1-medium text-center bg-white text-primary\",\n state === \"none\" && \"bg-gray00 text-transparent\",\n state === \"selected\" && \"bg-black text-white hover:cursor-pointer\",\n state === \"disabled\" && \"bg-gray00 text-gray03\",\n state === \"default\" && [\n \"hover:cursor-pointer\",\n color\n ? \"hover:bg-(--tt-hover)\"\n : printColor\n ? printColorHoverClass[printColor]\n : \"hover:bg-gray00\",\n ],\n className,\n )}\n >\n {label}\n </div>\n );\n};\n","import { forwardRef } from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport { IconChevronDownXS } from \"../../assets/svgs/Icons\";\nimport { formatWeekRange } from \"./dateUtils\";\n\nexport type Week = \"thisWeek\" | \"nextWeek\" | \"twoWeeksLater\";\n\nconst weekLabel: Record<Week, string> = {\n thisWeek: \"이번 주\",\n nextWeek: \"다음 주\",\n twoWeeksLater: \"다다음 주\",\n};\n\nexport interface WeekNavigationProps {\n /** 표시 중인 주의 월요일(ISO \"YYYY-MM-DD\"). 범위 라벨(~금요일)을 여기서 계산한다. */\n date: string;\n /** 3주 모델에 매핑되는 주차. `label`을 직접 주면 생략 가능. */\n week?: Week;\n /** 가운데 텍스트를 직접 지정(주어지면 week 기반 자동 라벨을 대체). */\n label?: string;\n /** 이전/다음 버튼 노출 여부를 명시적으로 제어. 생략 시 week로 자동 판단(thisWeek↔twoWeeksLater 경계). */\n canPrev?: boolean;\n canNext?: boolean;\n onPrevWeek?: () => void;\n onNextWeek?: () => void;\n className?: string;\n}\n\nexport const WeekNavigation = forwardRef<HTMLDivElement, WeekNavigationProps>(\n function WeekNavigation(\n { date, week, label, canPrev, canNext, onPrevWeek, onNextWeek, className },\n ref,\n ) {\n // \"이번 주\"보다 과거로는, \"다다음 주\"보다 미래로는 이동할 수 없다.\n const showPrev = canPrev ?? (week ? week !== \"thisWeek\" : true);\n const showNext = canNext ?? (week ? week !== \"twoWeeksLater\" : true);\n const text =\n label ?? (week ? `${weekLabel[week]} (${formatWeekRange(date)})` : formatWeekRange(date));\n\n return (\n <div\n ref={ref}\n className={cn(\n \"flex items-stretch justify-between\",\n \"w-full h-12\",\n \"bg-white border-b border-gray02\",\n \"text-body1-medium text-secondary\",\n className,\n )}\n >\n <ArrowButton direction=\"left\" visible={showPrev} onClick={onPrevWeek} />\n <span className=\"flex flex-1 items-center justify-center text-center\">{text}</span>\n <ArrowButton direction=\"right\" visible={showNext} onClick={onNextWeek} />\n </div>\n );\n },\n);\n\ninterface ArrowButtonProps {\n direction: \"left\" | \"right\";\n visible: boolean;\n onClick?: () => void;\n}\n\nconst ArrowButton = ({ direction, visible, onClick }: ArrowButtonProps) => {\n // 화살표 안쪽(가운데 방향)에 1px 칸막이를 둔다. 디자인 스펙상 좌측은 [화살표][칸막이], 우측은 [칸막이][화살표].\n const divider = <span aria-hidden className=\"w-px self-stretch bg-gray02\" />;\n\n if (!visible) {\n // 버튼이 없어도 가운데 라벨 위치가 흔들리지 않도록 자리만 유지한다.\n return (\n <div className=\"flex items-stretch\">\n {direction === \"right\" && divider}\n <span className=\"w-[42px]\" />\n {direction === \"left\" && divider}\n </div>\n );\n }\n\n return (\n <div className=\"flex items-stretch\">\n {direction === \"right\" && divider}\n <button\n type=\"button\"\n onClick={onClick}\n className={cn(\n \"flex w-[42px] items-center justify-center\",\n \"text-gray06 cursor-pointer transition-colors\",\n \"hover:bg-gray00 active:bg-gray01\",\n )}\n >\n <IconChevronDownXS\n className={direction === \"left\" ? \"rotate-90\" : \"-rotate-90\"}\n stroke=\"currentColor\"\n />\n </button>\n {direction === \"left\" && divider}\n </div>\n );\n};\n","const KOREAN_WEEKDAYS = [\"일\", \"월\", \"화\", \"수\", \"목\", \"금\", \"토\"];\n\n// \"YYYY-MM-DD\" 문자열만 다루므로 로컬 타임존 파싱을 위해 new Date(date)(UTC 파싱) 대신 직접 분해한다.\nconst parseISODate = (date: string) => {\n const [year, month, day] = date.split(\"-\").map(Number);\n return new Date(year, month - 1, day);\n};\n\nconst toISODate = (d: Date) => {\n const year = d.getFullYear();\n const month = String(d.getMonth() + 1).padStart(2, \"0\");\n const day = String(d.getDate()).padStart(2, \"0\");\n return `${year}-${month}-${day}`;\n};\n\nexport const addDays = (date: string, amount: number) => {\n const d = parseISODate(date);\n d.setDate(d.getDate() + amount);\n return toISODate(d);\n};\n\n// \"5월 5일(월)\"\nexport const formatDayLabel = (date: string) => {\n const d = parseISODate(date);\n return `${d.getMonth() + 1}월 ${d.getDate()}일(${KOREAN_WEEKDAYS[d.getDay()]})`;\n};\n\n// \"05.05\"\nconst formatMMDD = (date: string) => {\n const d = parseISODate(date);\n return `${String(d.getMonth() + 1).padStart(2, \"0\")}.${String(d.getDate()).padStart(2, \"0\")}`;\n};\n\n// weekStart(월요일) 기준 5일(월~금) 범위: \"05.05 ~ 05.09\"\nexport const formatWeekRange = (weekStart: string) => {\n const weekEnd = addDays(weekStart, 4);\n return `${formatMMDD(weekStart)} ~ ${formatMMDD(weekEnd)}`;\n};\n","import {\n Fragment,\n forwardRef,\n useCallback,\n useState,\n type AnchorHTMLAttributes,\n type ComponentType,\n type ReactNode,\n type Ref,\n} from \"react\";\nimport { cn } from \"../../lib/cn\";\n\n/**\n * href가 있는 항목을 실제 링크로 렌더링하기 위해 주입하는 컴포넌트.\n * Next.js라면 `next/link`를 그대로 넘기면 된다.\n * 주입하지 않으면 순수 `<a>`로 렌더링된다.\n */\nexport type LinkComponent = ComponentType<\n Pick<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n \"href\" | \"className\" | \"onClick\" | \"aria-current\"\n > & {\n children: ReactNode;\n ref?: Ref<HTMLAnchorElement>;\n }\n>;\n\nexport type NavIcon = {\n /** 아이콘 이미지 URL. `icon`(ReactNode)과 택일해서 사용한다. */\n src?: string;\n /** 인라인 SVG 등 커스텀 노드. `src` 대신 사용한다. 선택 상태 대비를 위해 `currentColor` 사용을 권장. */\n icon?: ReactNode;\n alt?: string;\n /** 아이콘 옆에 함께 노출할 텍스트 라벨(예: \"피드백\"). 아이콘 없이 라벨만도 가능. */\n label?: string;\n /** key/상태 식별용 안정적 id(권장). 없으면 `src` → `label` 순으로 대체한다. */\n id?: string;\n /** 지정하면 `<a>`(또는 주입된 LinkComponent)로 렌더링된다. */\n href?: string;\n onClick?: () => void;\n /** true면 아이콘 배경을 검게 채워 강조한다(예: 알림/마이페이지 진입 상태). */\n selected?: boolean;\n /** 알림 개수 등 우상단 뱃지. `true`면 점(dot)만 표시. */\n badge?: ReactNode;\n className?: string;\n /** 렌더링된 `<a>`/`<button>` 엘리먼트로 전달되는 ref(외부 클릭 감지 등에 사용). */\n ref?: Ref<HTMLElement>;\n};\n\nexport type LowerPartItem = {\n label: string;\n /** key/상태 식별용 안정적 id(권장). 없으면 `label`을 사용한다. */\n id?: string;\n /** 지정하면 `<a>`(또는 주입된 LinkComponent)로 렌더링된다. */\n href?: string;\n onClick?: () => void;\n};\n\nexport type UpperPartItem = {\n label: string;\n id?: string;\n href?: string;\n onClick?: () => void;\n /** 이 상단 탭이 선택됐을 때 아래에 노출할 하위 메뉴 */\n lowerPartItemList: LowerPartItem[];\n};\n\nexport interface TNBProps {\n logo: NavIcon;\n upperPartItemList: UpperPartItem[];\n /** 우측 알림/마이페이지 등 아이콘 목록(로고 제외) */\n upperPartIconList: NavIcon[];\n\n /**\n * controlled: 현재 선택된 상단 탭의 label.\n * `null`을 넘기면 \"선택된 탭 없음\"(홈 등)으로 표시된다.\n */\n selected?: string | null;\n /** uncontrolled 초기값. `selected`를 함께 넘기면 무시된다. 지정하지 않으면 선택된 탭이 없다. */\n defaultSelected?: string;\n onSelectedChange?: (label: string) => void;\n\n /** controlled: 현재 선택된 하위 메뉴 label. `null`이면 미선택. */\n selectedLower?: string | null;\n /** uncontrolled 초기값. */\n defaultSelectedLower?: string;\n onSelectedLowerChange?: (label: string) => void;\n\n /** @deprecated `onSelectedChange`를 사용하세요. 하위 호환용 별칭입니다. */\n onSelectItem?: (label: string) => void;\n\n /** href가 있는 항목을 렌더링할 링크 컴포넌트(Next.js면 `next/link`). */\n linkComponent?: LinkComponent;\n\n /** nav 랜드마크의 접근성 라벨. */\n \"aria-label\"?: string;\n className?: string;\n}\n\n/** controlled/uncontrolled를 함께 지원하는 상태 훅. `controlled`가 `undefined`가 아니면 controlled로 간주한다(`null` 포함). */\nfunction useControllableState<T>(controlled: T | undefined, defaultValue: T) {\n const isControlled = controlled !== undefined;\n const [uncontrolled, setUncontrolled] = useState<T>(defaultValue);\n const value = isControlled ? (controlled as T) : uncontrolled;\n const setValue = useCallback(\n (next: T) => {\n if (!isControlled) setUncontrolled(next);\n },\n [isControlled],\n );\n return [value, setValue, isControlled] as const;\n}\n\nexport const TNB = forwardRef<HTMLElement, TNBProps>(function TNB(\n {\n logo,\n upperPartItemList,\n upperPartIconList,\n selected,\n defaultSelected,\n onSelectedChange,\n selectedLower,\n defaultSelectedLower,\n onSelectedLowerChange,\n onSelectItem,\n linkComponent,\n \"aria-label\": ariaLabel = \"주요 메뉴\",\n className,\n },\n ref,\n) {\n const [upperValue, setUpperValue] = useControllableState<string | null>(\n selected,\n defaultSelected ?? null,\n );\n const [lowerValueRaw, setLowerValue, lowerIsControlled] = useControllableState<string | null>(\n selectedLower,\n defaultSelectedLower ?? null,\n );\n\n const currentUpper = upperPartItemList.find((item) => item.label === upperValue);\n const currentLowerItemList = currentUpper?.lowerPartItemList ?? [];\n\n // uncontrolled 하위 메뉴: 현재 목록에 없으면 첫 항목으로 자동 폴백(기존 동작 유지).\n const lowerValue = lowerIsControlled\n ? (lowerValueRaw ?? undefined)\n : currentLowerItemList.some((item) => item.label === lowerValueRaw)\n ? (lowerValueRaw as string)\n : (currentLowerItemList[0]?.label ?? undefined);\n\n const handleSelectUpper = (label: string) => {\n setUpperValue(label);\n if (!lowerIsControlled) {\n const nextLower =\n upperPartItemList.find((item) => item.label === label)?.lowerPartItemList[0]?.label ?? null;\n setLowerValue(nextLower);\n }\n onSelectedChange?.(label);\n onSelectItem?.(label);\n };\n\n const handleSelectLower = (label: string) => {\n setLowerValue(label);\n onSelectedLowerChange?.(label);\n };\n\n return (\n <nav ref={ref} aria-label={ariaLabel} className={cn(\"w-full bg-white\", className)}>\n <UpperPart\n logo={logo}\n upperPartItemList={upperPartItemList}\n upperPartIconList={upperPartIconList}\n selected={upperValue ?? undefined}\n onSelectItem={handleSelectUpper}\n linkComponent={linkComponent}\n />\n <LowerPart\n lowerPartItemList={currentLowerItemList}\n selected={lowerValue}\n onSelectItem={handleSelectLower}\n linkComponent={linkComponent}\n />\n </nav>\n );\n});\n\n/* -------------------------------------------------------------------------- */\n/* NavClickable — href 유무에 따라 <a>(또는 주입된 링크) / <button>을 렌더링 */\n/* -------------------------------------------------------------------------- */\n\ninterface NavClickableProps {\n href?: string;\n onClick?: () => void;\n linkComponent?: LinkComponent;\n /** 링크로 열더라도 현재 위치면 aria-current를 붙인다. */\n current?: boolean;\n disabled?: boolean;\n className?: string;\n children: ReactNode;\n}\n\nconst NavClickable = forwardRef<HTMLElement, NavClickableProps>(function NavClickable(\n { href, onClick, linkComponent: Link, current, disabled, className, children },\n ref,\n) {\n const ariaCurrent = current ? \"page\" : undefined;\n\n if (href && !disabled) {\n if (Link) {\n return (\n <Link\n href={href}\n onClick={onClick}\n aria-current={ariaCurrent}\n className={className}\n ref={ref as Ref<HTMLAnchorElement>}\n >\n {children}\n </Link>\n );\n }\n return (\n <a\n href={href}\n onClick={onClick}\n aria-current={ariaCurrent}\n className={className}\n ref={ref as Ref<HTMLAnchorElement>}\n >\n {children}\n </a>\n );\n }\n\n return (\n <button\n type=\"button\"\n onClick={onClick}\n disabled={disabled}\n aria-current={ariaCurrent}\n className={className}\n ref={ref as Ref<HTMLButtonElement>}\n >\n {children}\n </button>\n );\n});\n\n/* -------------------------------------------------------------------------- */\n\ninterface UpperPartProps {\n logo: NavIcon;\n upperPartItemList: UpperPartItem[];\n upperPartIconList: NavIcon[];\n selected?: string;\n onSelectItem: (label: string) => void;\n linkComponent?: LinkComponent;\n className?: string;\n}\nconst UpperPart = ({\n logo,\n upperPartItemList,\n upperPartIconList,\n selected,\n onSelectItem,\n linkComponent,\n className,\n}: UpperPartProps) => {\n return (\n <div\n className={cn(\n \"w-full min-h-13 flex items-stretch justify-between border-b border-gray02\",\n className,\n )}\n >\n <div className=\"flex items-stretch\">\n <div className=\"flex w-14 shrink-0 items-center justify-center px-3\">\n <NavIconButton {...logo} linkComponent={linkComponent} />\n </div>\n <div className=\"flex items-stretch\">\n <span aria-hidden className=\"w-px self-stretch bg-gray02\" />\n {upperPartItemList.map((item) => (\n <Fragment key={item.id ?? item.label}>\n <UpperPartTab\n label={item.label}\n href={item.href}\n selected={item.label === selected}\n linkComponent={linkComponent}\n onClick={() => {\n item.onClick?.();\n onSelectItem(item.label);\n }}\n />\n <span aria-hidden className=\"w-px self-stretch bg-gray02\" />\n </Fragment>\n ))}\n </div>\n </div>\n <div className=\"flex items-stretch\">\n <span aria-hidden className=\"w-px self-stretch bg-gray02\" />\n {upperPartIconList.map((icon, index) => (\n <NavIconButton\n key={icon.id ?? icon.src ?? icon.label ?? index}\n {...icon}\n linkComponent={linkComponent}\n />\n ))}\n </div>\n </div>\n );\n};\n\ninterface UpperPartTabProps {\n label: string;\n href?: string;\n selected: boolean;\n onClick: () => void;\n linkComponent?: LinkComponent;\n className?: string;\n}\nconst UpperPartTab = ({\n label,\n href,\n selected,\n onClick,\n linkComponent,\n className,\n}: UpperPartTabProps) => {\n return (\n <NavClickable\n href={href}\n onClick={onClick}\n linkComponent={linkComponent}\n current={selected}\n className={cn(\n \"inline-flex min-h-13 flex-col items-center gap-2 pt-2.5 cursor-pointer no-underline\",\n \"transition-colors hover:bg-gray00 active:bg-gray01\",\n className,\n )}\n >\n <span className={cn(\"px-5 text-head1-medium\", selected ? \"text-strong\" : \"text-quaternary\")}>\n {label}\n </span>\n <span className={cn(\"h-0.5 w-full\", selected ? \"bg-black\" : \"bg-transparent\")} />\n </NavClickable>\n );\n};\n\nconst NavIconButton = forwardRef<HTMLElement, NavIcon & { linkComponent?: LinkComponent }>(\n function NavIconButton(\n { src, icon, alt, label, href, onClick, selected, badge, className, linkComponent },\n forwardedRef,\n ) {\n const interactive = Boolean(onClick || href);\n const showBadge = badge !== undefined && badge !== null && badge !== false;\n\n return (\n <NavClickable\n ref={forwardedRef}\n href={href}\n onClick={onClick}\n linkComponent={linkComponent}\n current={selected}\n disabled={!interactive}\n className={cn(\n \"relative inline-flex h-13 min-w-13 items-center justify-center gap-1.5 px-3 transition-colors\",\n interactive && \"cursor-pointer\",\n selected ? \"bg-black text-white\" : \"bg-transparent hover:bg-gray00 active:bg-gray01\",\n className,\n )}\n >\n {icon ? (\n <span className=\"inline-flex h-6 w-6 items-center justify-center\">{icon}</span>\n ) : src ? (\n <img src={src} alt={alt ?? label ?? \"\"} className=\"h-6 w-6\" />\n ) : null}\n {label ? (\n <span className={cn(\"text-body2-regular\", selected ? \"text-white\" : \"text-secondary\")}>\n {label}\n </span>\n ) : null}\n {showBadge ? (\n <span\n aria-hidden={badge === true}\n className={cn(\n \"absolute -right-0.5 -top-0.5 flex items-center justify-center rounded-full bg-danger text-white\",\n badge === true ? \"h-2 w-2\" : \"h-4 min-w-4 px-1 text-caption-regular leading-none\",\n )}\n >\n {badge === true ? null : badge}\n </span>\n ) : null}\n </NavClickable>\n );\n },\n);\n\ninterface LowerPartProps {\n lowerPartItemList: LowerPartItem[];\n selected?: string;\n onSelectItem: (label: string) => void;\n linkComponent?: LinkComponent;\n className?: string;\n}\nconst LowerPart = ({\n lowerPartItemList,\n selected,\n onSelectItem,\n linkComponent,\n className,\n}: LowerPartProps) => {\n if (lowerPartItemList.length === 0) {\n return null;\n }\n\n return (\n <div\n className={cn(\"w-full h-[42px] pl-14 flex items-stretch border-b border-gray02\", className)}\n >\n <span aria-hidden className=\"w-px self-stretch bg-gray02\" />\n {lowerPartItemList.map((item) => (\n <Fragment key={item.id ?? item.label}>\n <LowerPartItemButton\n label={item.label}\n href={item.href}\n selected={item.label === selected}\n linkComponent={linkComponent}\n onClick={() => {\n item.onClick?.();\n onSelectItem(item.label);\n }}\n />\n <span aria-hidden className=\"w-px self-stretch bg-gray02\" />\n </Fragment>\n ))}\n </div>\n );\n};\n\ninterface LowerPartItemButtonProps {\n label: string;\n href?: string;\n selected: boolean;\n onClick: () => void;\n linkComponent?: LinkComponent;\n className?: string;\n}\nconst LowerPartItemButton = ({\n label,\n href,\n selected,\n onClick,\n linkComponent,\n className,\n}: LowerPartItemButtonProps) => {\n return (\n <NavClickable\n href={href}\n onClick={onClick}\n linkComponent={linkComponent}\n current={selected}\n className={cn(\n \"inline-flex h-full items-center justify-center px-5 text-head3-medium cursor-pointer no-underline\",\n \"transition-colors hover:bg-gray00 active:bg-gray01\",\n selected ? \"text-strong\" : \"text-quaternary\",\n className,\n )}\n >\n {label}\n </NavClickable>\n );\n};\n","import { forwardRef, useEffect, useState } from \"react\";\nimport { cn } from \"../../lib/cn\";\n\nconst EXIT_MS = 300;\n\nexport interface ToastProps {\n message: string;\n /**\n * 표시 여부(controlled). 생략하면 항상 표시되는 순수 렌더 모드(하위 호환).\n * `true`/`false`를 넘기면 페이드 인/아웃 + 언마운트를 컴포넌트가 스스로 처리한다.\n */\n open?: boolean;\n /**\n * 자동 소멸까지의 시간(ms). `0`/`null`이면 자동 소멸하지 않는다. 기본 3000.\n * `open`이 `true`로 바뀔 때마다 타이머가 재시작된다.\n */\n duration?: number | null;\n /** 자동 소멸 시각 또는 (배너 클릭 시) 호출. controlled 모드에서 `open`을 false로 되돌리는 데 사용. */\n onClose?: () => void;\n /**\n * 화면 고정 위치. `\"none\"`이면 위치 스타일을 붙이지 않고 부모 레이아웃에 맡긴다(하위 호환 기본값).\n */\n position?: \"top\" | \"bottom\" | \"none\";\n className?: string;\n}\n\nexport const Toast = forwardRef<HTMLDivElement, ToastProps>(function Toast(\n { message, open, duration = 3000, onClose, position = \"none\", className },\n ref,\n) {\n const controlled = open !== undefined;\n const [mounted, setMounted] = useState(!controlled || open);\n const [visible, setVisible] = useState(!controlled || open);\n\n // 마운트/언마운트 + 다음 프레임 페이드\n useEffect(() => {\n if (!controlled) return;\n if (open) {\n setMounted(true);\n const raf = requestAnimationFrame(() => setVisible(true));\n return () => cancelAnimationFrame(raf);\n }\n setVisible(false);\n const timer = setTimeout(() => setMounted(false), EXIT_MS);\n return () => clearTimeout(timer);\n }, [controlled, open]);\n\n // 자동 소멸 타이머\n useEffect(() => {\n if (!controlled || !open || !duration) return;\n const timer = setTimeout(() => onClose?.(), duration);\n return () => clearTimeout(timer);\n }, [controlled, open, duration, onClose]);\n\n if (!mounted) return null;\n\n const banner = (\n <div\n ref={ref}\n role=\"status\"\n aria-live=\"polite\"\n className={cn(\n \"w-full h-fit py-2.5 bg-gray06\",\n \"font-pretendard text-white text-center font-semibold text-[17px] leading-[1.6]\",\n \"shadow-[0_2px_15px_rgba(0,0,0,0.18)]\",\n controlled && \"transition-opacity duration-300\",\n controlled && (visible ? \"opacity-100\" : \"opacity-0\"),\n className,\n )}\n >\n {message}\n </div>\n );\n\n if (position === \"none\") return banner;\n\n return (\n <div\n className={cn(\n \"fixed inset-x-0 z-5000 pointer-events-none\",\n position === \"top\" ? \"top-0\" : \"bottom-0\",\n )}\n >\n {banner}\n </div>\n );\n});\n"],"mappings":"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","names":["import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","Tag","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","CTAs","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","import_react","import_jsx_runtime","SideRadioAccordion","TextButton","import_jsx_runtime","import_react","import_react","import_jsx_runtime","WeekNavigation","import_jsx_runtime","Timetable","import_react","import_jsx_runtime","useControllableState","TNB","NavClickable","NavIconButton","import_react","import_jsx_runtime","Toast"]}
|