--- version: 1.0.0-beta.6 --- # Icons URL: /docs/icons Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/icons.mdx @vapor-ui/icons 라이브러리에서 제공하는 아이콘입니다. 아이콘을 클릭해 import 문을 복사할 수 있습니다. *** title: Icons description: | @vapor-ui/icons 라이브러리에서 제공하는 아이콘입니다. 아이콘을 클릭해 import 문을 복사할 수 있습니다. ------------------------------ ## Basic Icons | Icon Name | Import Statement | | --------------------------- | ------------------------------------------------------------- | | `AchievementIcon` | `import { AchievementIcon } from '@vapor-ui/icons'` | | `AddUserIcon` | `import { AddUserIcon } from '@vapor-ui/icons'` | | `AiGoormeeIcon` | `import { AiGoormeeIcon } from '@vapor-ui/icons'` | | `AiSmartieIcon` | `import { AiSmartieIcon } from '@vapor-ui/icons'` | | `AirplayIcon` | `import { AirplayIcon } from '@vapor-ui/icons'` | | `AlgorithmIcon` | `import { AlgorithmIcon } from '@vapor-ui/icons'` | | `AppleIcon` | `import { AppleIcon } from '@vapor-ui/icons'` | | `ArrowDownCircleIcon` | `import { ArrowDownCircleIcon } from '@vapor-ui/icons'` | | `AssignmentIcon` | `import { AssignmentIcon } from '@vapor-ui/icons'` | | `AwsIcon` | `import { AwsIcon } from '@vapor-ui/icons'` | | `AzureIcon` | `import { AzureIcon } from '@vapor-ui/icons'` | | `BedIcon` | `import { BedIcon } from '@vapor-ui/icons'` | | `BellOffIcon` | `import { BellOffIcon } from '@vapor-ui/icons'` | | `BellOnIcon` | `import { BellOnIcon } from '@vapor-ui/icons'` | | `BitbucketIcon` | `import { BitbucketIcon } from '@vapor-ui/icons'` | | `BlogColorIcon` | `import { BlogColorIcon } from '@vapor-ui/icons'` | | `BlogIcon` | `import { BlogIcon } from '@vapor-ui/icons'` | | `BookIcon` | `import { BookIcon } from '@vapor-ui/icons'` | | `BookmarkIcon` | `import { BookmarkIcon } from '@vapor-ui/icons'` | | `BottomPlayerIcon` | `import { BottomPlayerIcon } from '@vapor-ui/icons'` | | `BranchIcon` | `import { BranchIcon } from '@vapor-ui/icons'` | | `BreakpointIcon` | `import { BreakpointIcon } from '@vapor-ui/icons'` | | `BuildIcon` | `import { BuildIcon } from '@vapor-ui/icons'` | | `CafeIcon` | `import { CafeIcon } from '@vapor-ui/icons'` | | `CakeIcon` | `import { CakeIcon } from '@vapor-ui/icons'` | | `CalculatorIcon` | `import { CalculatorIcon } from '@vapor-ui/icons'` | | `CalendarIcon` | `import { CalendarIcon } from '@vapor-ui/icons'` | | `CallIcon` | `import { CallIcon } from '@vapor-ui/icons'` | | `CameraIcon` | `import { CameraIcon } from '@vapor-ui/icons'` | | `CampIcon` | `import { CampIcon } from '@vapor-ui/icons'` | | `CaptionIcon` | `import { CaptionIcon } from '@vapor-ui/icons'` | | `CarIcon` | `import { CarIcon } from '@vapor-ui/icons'` | | `CardsIcon` | `import { CardsIcon } from '@vapor-ui/icons'` | | `CaretDownIcon` | `import { CaretDownIcon } from '@vapor-ui/icons'` | | `CaretLeftIcon` | `import { CaretLeftIcon } from '@vapor-ui/icons'` | | `CaretRightIcon` | `import { CaretRightIcon } from '@vapor-ui/icons'` | | `CaretUpIcon` | `import { CaretUpIcon } from '@vapor-ui/icons'` | | `CertificateIcon` | `import { CertificateIcon } from '@vapor-ui/icons'` | | `ChapterIcon` | `import { ChapterIcon } from '@vapor-ui/icons'` | | `ChartPieIcon` | `import { ChartPieIcon } from '@vapor-ui/icons'` | | `ChatgptIcon` | `import { ChatgptIcon } from '@vapor-ui/icons'` | | `CheckCircleIcon` | `import { CheckCircleIcon } from '@vapor-ui/icons'` | | `CheckboxIcon` | `import { CheckboxIcon } from '@vapor-ui/icons'` | | `ChromeColorIcon` | `import { ChromeColorIcon } from '@vapor-ui/icons'` | | `ChromeIcon` | `import { ChromeIcon } from '@vapor-ui/icons'` | | `ClassIcon` | `import { ClassIcon } from '@vapor-ui/icons'` | | `CodeBlockIcon` | `import { CodeBlockIcon } from '@vapor-ui/icons'` | | `CodevisorIcon` | `import { CodevisorIcon } from '@vapor-ui/icons'` | | `CollaborationIcon` | `import { CollaborationIcon } from '@vapor-ui/icons'` | | `ComponentIcon` | `import { ComponentIcon } from '@vapor-ui/icons'` | | `ContainerIcon` | `import { ContainerIcon } from '@vapor-ui/icons'` | | `ContainerRunIcon` | `import { ContainerRunIcon } from '@vapor-ui/icons'` | | `ContainerShareIcon` | `import { ContainerShareIcon } from '@vapor-ui/icons'` | | `ContainerStopIcon` | `import { ContainerStopIcon } from '@vapor-ui/icons'` | | `ContainerToImageIcon` | `import { ContainerToImageIcon } from '@vapor-ui/icons'` | | `ControlCommonIcon` | `import { ControlCommonIcon } from '@vapor-ui/icons'` | | `CopyIcon` | `import { CopyIcon } from '@vapor-ui/icons'` | | `CouponIcon` | `import { CouponIcon } from '@vapor-ui/icons'` | | `CourseHistoryIcon` | `import { CourseHistoryIcon } from '@vapor-ui/icons'` | | `CourseIcon` | `import { CourseIcon } from '@vapor-ui/icons'` | | `CpuIcon` | `import { CpuIcon } from '@vapor-ui/icons'` | | `CreditCardIcon` | `import { CreditCardIcon } from '@vapor-ui/icons'` | | `CursorshareoffIcon` | `import { CursorshareoffIcon } from '@vapor-ui/icons'` | | `CursorshareonIcon` | `import { CursorshareonIcon } from '@vapor-ui/icons'` | | `DarkIcon` | `import { DarkIcon } from '@vapor-ui/icons'` | | `DashboardIcon` | `import { DashboardIcon } from '@vapor-ui/icons'` | | `DatabaseIcon` | `import { DatabaseIcon } from '@vapor-ui/icons'` | | `DebugContinueIcon` | `import { DebugContinueIcon } from '@vapor-ui/icons'` | | `DebugIcon` | `import { DebugIcon } from '@vapor-ui/icons'` | | `DeployPushIcon` | `import { DeployPushIcon } from '@vapor-ui/icons'` | | `DetailViewIcon` | `import { DetailViewIcon } from '@vapor-ui/icons'` | | `DiscIcon` | `import { DiscIcon } from '@vapor-ui/icons'` | | `DiscordColorIcon` | `import { DiscordColorIcon } from '@vapor-ui/icons'` | | `DiscordIcon` | `import { DiscordIcon } from '@vapor-ui/icons'` | | `DiscussionIcon` | `import { DiscussionIcon } from '@vapor-ui/icons'` | | `DiskIcon` | `import { DiskIcon } from '@vapor-ui/icons'` | | `DislikeIcon` | `import { DislikeIcon } from '@vapor-ui/icons'` | | `DislikeThumbIcon` | `import { DislikeThumbIcon } from '@vapor-ui/icons'` | | `DividerIcon` | `import { DividerIcon } from '@vapor-ui/icons'` | | `DockerIcon` | `import { DockerIcon } from '@vapor-ui/icons'` | | `DocktoBottomIcon` | `import { DocktoBottomIcon } from '@vapor-ui/icons'` | | `DocumentViewerIcon` | `import { DocumentViewerIcon } from '@vapor-ui/icons'` | | `DotIcon` | `import { DotIcon } from '@vapor-ui/icons'` | | `DownloadIcon` | `import { DownloadIcon } from '@vapor-ui/icons'` | | `DragIndicatorIcon` | `import { DragIndicatorIcon } from '@vapor-ui/icons'` | | `EditIcon` | `import { EditIcon } from '@vapor-ui/icons'` | | `EraserIcon` | `import { EraserIcon } from '@vapor-ui/icons'` | | `ErrorCircleIcon` | `import { ErrorCircleIcon } from '@vapor-ui/icons'` | | `ExamIcon` | `import { ExamIcon } from '@vapor-ui/icons'` | | `ExamListIcon` | `import { ExamListIcon } from '@vapor-ui/icons'` | | `ExamReportIcon` | `import { ExamReportIcon } from '@vapor-ui/icons'` | | `ExploreIcon` | `import { ExploreIcon } from '@vapor-ui/icons'` | | `ExportIcon` | `import { ExportIcon } from '@vapor-ui/icons'` | | `ExportImageIcon` | `import { ExportImageIcon } from '@vapor-ui/icons'` | | `FacebookColorIcon` | `import { FacebookColorIcon } from '@vapor-ui/icons'` | | `FacebookIcon` | `import { FacebookIcon } from '@vapor-ui/icons'` | | `FigmaColorIcon` | `import { FigmaColorIcon } from '@vapor-ui/icons'` | | `FigmaIcon` | `import { FigmaIcon } from '@vapor-ui/icons'` | | `FileAddIcon` | `import { FileAddIcon } from '@vapor-ui/icons'` | | `FileDeleteIcon` | `import { FileDeleteIcon } from '@vapor-ui/icons'` | | `FileIcon` | `import { FileIcon } from '@vapor-ui/icons'` | | `FilenewIcon` | `import { FilenewIcon } from '@vapor-ui/icons'` | | `FilterIcon` | `import { FilterIcon } from '@vapor-ui/icons'` | | `FirefoxColorIcon` | `import { FirefoxColorIcon } from '@vapor-ui/icons'` | | `FlagIcon` | `import { FlagIcon } from '@vapor-ui/icons'` | | `FlaskIcon` | `import { FlaskIcon } from '@vapor-ui/icons'` | | `FlightIcon` | `import { FlightIcon } from '@vapor-ui/icons'` | | `FoldIcon` | `import { FoldIcon } from '@vapor-ui/icons'` | | `FolderIcon` | `import { FolderIcon } from '@vapor-ui/icons'` | | `FolderNewIcon` | `import { FolderNewIcon } from '@vapor-ui/icons'` | | `FolderSearchIcon` | `import { FolderSearchIcon } from '@vapor-ui/icons'` | | `ForkIcon` | `import { ForkIcon } from '@vapor-ui/icons'` | | `FunctionIcon` | `import { FunctionIcon } from '@vapor-ui/icons'` | | `GameIcon` | `import { GameIcon } from '@vapor-ui/icons'` | | `GcpIcon` | `import { GcpIcon } from '@vapor-ui/icons'` | | `GitIcon` | `import { GitIcon } from '@vapor-ui/icons'` | | `GithubColorIcon` | `import { GithubColorIcon } from '@vapor-ui/icons'` | | `GithubIcon` | `import { GithubIcon } from '@vapor-ui/icons'` | | `GitlabIcon` | `import { GitlabIcon } from '@vapor-ui/icons'` | | `GoogleCalendarIcon` | `import { GoogleCalendarIcon } from '@vapor-ui/icons'` | | `GoogleColorIcon` | `import { GoogleColorIcon } from '@vapor-ui/icons'` | | `GoogleDrawingIcon` | `import { GoogleDrawingIcon } from '@vapor-ui/icons'` | | `GoogleIcon` | `import { GoogleIcon } from '@vapor-ui/icons'` | | `GooglePresentationIcon` | `import { GooglePresentationIcon } from '@vapor-ui/icons'` | | `GoogleSpreadsheetIcon` | `import { GoogleSpreadsheetIcon } from '@vapor-ui/icons'` | | `GoormduinoIcon` | `import { GoormduinoIcon } from '@vapor-ui/icons'` | | `GpuIcon` | `import { GpuIcon } from '@vapor-ui/icons'` | | `GroupIcon` | `import { GroupIcon } from '@vapor-ui/icons'` | | `GuestIcon` | `import { GuestIcon } from '@vapor-ui/icons'` | | `HeartIcon` | `import { HeartIcon } from '@vapor-ui/icons'` | | `HelpCircleIcon` | `import { HelpCircleIcon } from '@vapor-ui/icons'` | | `HelpIcon` | `import { HelpIcon } from '@vapor-ui/icons'` | | `HighlightViewIcon` | `import { HighlightViewIcon } from '@vapor-ui/icons'` | | `HomeIcon` | `import { HomeIcon } from '@vapor-ui/icons'` | | `HourglassIcon` | `import { HourglassIcon } from '@vapor-ui/icons'` | | `IdCardIcon` | `import { IdCardIcon } from '@vapor-ui/icons'` | | `IdeShareIcon` | `import { IdeShareIcon } from '@vapor-ui/icons'` | | `ImageIcon` | `import { ImageIcon } from '@vapor-ui/icons'` | | `ImagePackIcon` | `import { ImagePackIcon } from '@vapor-ui/icons'` | | `ImageToContainerIcon` | `import { ImageToContainerIcon } from '@vapor-ui/icons'` | | `ImportIcon` | `import { ImportIcon } from '@vapor-ui/icons'` | | `InfoCircleIcon` | `import { InfoCircleIcon } from '@vapor-ui/icons'` | | `InstagramColorIcon` | `import { InstagramColorIcon } from '@vapor-ui/icons'` | | `InstagramIcon` | `import { InstagramIcon } from '@vapor-ui/icons'` | | `IntelliSenseClassIcon` | `import { IntelliSenseClassIcon } from '@vapor-ui/icons'` | | `IntelliSenseColorIcon` | `import { IntelliSenseColorIcon } from '@vapor-ui/icons'` | | `IntelliSenseConstantIcon` | `import { IntelliSenseConstantIcon } from '@vapor-ui/icons'` | | `IntelliSenseEnumIcon` | `import { IntelliSenseEnumIcon } from '@vapor-ui/icons'` | | `IntelliSenseEventIcon` | `import { IntelliSenseEventIcon } from '@vapor-ui/icons'` | | `IntelliSenseFunctionIcon` | `import { IntelliSenseFunctionIcon } from '@vapor-ui/icons'` | | `IntelliSenseInterfaceIcon` | `import { IntelliSenseInterfaceIcon } from '@vapor-ui/icons'` | | `IntelliSenseModuleIcon` | `import { IntelliSenseModuleIcon } from '@vapor-ui/icons'` | | `IntelliSenseNullIcon` | `import { IntelliSenseNullIcon } from '@vapor-ui/icons'` | | `IntelliSenseOperatorIcon` | `import { IntelliSenseOperatorIcon } from '@vapor-ui/icons'` | | `IntelliSensePropertyIcon` | `import { IntelliSensePropertyIcon } from '@vapor-ui/icons'` | | `IntelliSenseSnippetIcon` | `import { IntelliSenseSnippetIcon } from '@vapor-ui/icons'` | | `IntelliSenseStructureIcon` | `import { IntelliSenseStructureIcon } from '@vapor-ui/icons'` | | `IntelliSenseTextIcon` | `import { IntelliSenseTextIcon } from '@vapor-ui/icons'` | | `IntelliSenseUnitIcon` | `import { IntelliSenseUnitIcon } from '@vapor-ui/icons'` | | `IntelliSenseValueIcon` | `import { IntelliSenseValueIcon } from '@vapor-ui/icons'` | | `IntellijColorIcon` | `import { IntellijColorIcon } from '@vapor-ui/icons'` | | `ItalicIcon` | `import { ItalicIcon } from '@vapor-ui/icons'` | | `JiraIcon` | `import { JiraIcon } from '@vapor-ui/icons'` | | `JupyterColorIcon` | `import { JupyterColorIcon } from '@vapor-ui/icons'` | | `JupyterlabColorIcon` | `import { JupyterlabColorIcon } from '@vapor-ui/icons'` | | `JupyterlabIcon` | `import { JupyterlabIcon } from '@vapor-ui/icons'` | | `KakaoIcon` | `import { KakaoIcon } from '@vapor-ui/icons'` | | `KeyboardIcon` | `import { KeyboardIcon } from '@vapor-ui/icons'` | | `KeyboardTabIcon` | `import { KeyboardTabIcon } from '@vapor-ui/icons'` | | `KidIcon` | `import { KidIcon } from '@vapor-ui/icons'` | | `KrampolineIcon` | `import { KrampolineIcon } from '@vapor-ui/icons'` | | `KubernatesIcon` | `import { KubernatesIcon } from '@vapor-ui/icons'` | | `LightIcon` | `import { LightIcon } from '@vapor-ui/icons'` | | `LightbulbIcon` | `import { LightbulbIcon } from '@vapor-ui/icons'` | | `LightningIcon` | `import { LightningIcon } from '@vapor-ui/icons'` | | `LikeIcon` | `import { LikeIcon } from '@vapor-ui/icons'` | | `LikeThumbIcon` | `import { LikeThumbIcon } from '@vapor-ui/icons'` | | `LinkedinIcon` | `import { LinkedinIcon } from '@vapor-ui/icons'` | | `ListIcon` | `import { ListIcon } from '@vapor-ui/icons'` | | `ListNumberedIcon` | `import { ListNumberedIcon } from '@vapor-ui/icons'` | | `LiveLessonIcon` | `import { LiveLessonIcon } from '@vapor-ui/icons'` | | `LocationIcon` | `import { LocationIcon } from '@vapor-ui/icons'` | | `LockIcon` | `import { LockIcon } from '@vapor-ui/icons'` | | `MagicWandIcon` | `import { MagicWandIcon } from '@vapor-ui/icons'` | | `MailIcon` | `import { MailIcon } from '@vapor-ui/icons'` | | `MarkModeIcon` | `import { MarkModeIcon } from '@vapor-ui/icons'` | | `MarkdownIcon` | `import { MarkdownIcon } from '@vapor-ui/icons'` | | `MediumIcon` | `import { MediumIcon } from '@vapor-ui/icons'` | | `MemoIcon` | `import { MemoIcon } from '@vapor-ui/icons'` | | `MemoryIcon` | `import { MemoryIcon } from '@vapor-ui/icons'` | | `MessageIcon` | `import { MessageIcon } from '@vapor-ui/icons'` | | `MethodIcon` | `import { MethodIcon } from '@vapor-ui/icons'` | | `MicOffIcon` | `import { MicOffIcon } from '@vapor-ui/icons'` | | `MicOnIcon` | `import { MicOnIcon } from '@vapor-ui/icons'` | | `MinusBoxIcon` | `import { MinusBoxIcon } from '@vapor-ui/icons'` | | `MovieIcon` | `import { MovieIcon } from '@vapor-ui/icons'` | | `MysqlColorIcon` | `import { MysqlColorIcon } from '@vapor-ui/icons'` | | `MysqlIcon` | `import { MysqlIcon } from '@vapor-ui/icons'` | | `NaverIcon` | `import { NaverIcon } from '@vapor-ui/icons'` | | `NaverblogColorIcon` | `import { NaverblogColorIcon } from '@vapor-ui/icons'` | | `NaverblogIcon` | `import { NaverblogIcon } from '@vapor-ui/icons'` | | `NetworkIcon` | `import { NetworkIcon } from '@vapor-ui/icons'` | | `NextIcon` | `import { NextIcon } from '@vapor-ui/icons'` | | `NoImageIcon` | `import { NoImageIcon } from '@vapor-ui/icons'` | | `NoUserIcon` | `import { NoUserIcon } from '@vapor-ui/icons'` | | `NoticeBoardIcon` | `import { NoticeBoardIcon } from '@vapor-ui/icons'` | | `NoticeCircleIcon` | `import { NoticeCircleIcon } from '@vapor-ui/icons'` | | `NotionIcon` | `import { NotionIcon } from '@vapor-ui/icons'` | | `ObjectIcon` | `import { ObjectIcon } from '@vapor-ui/icons'` | | `OpenFileIcon` | `import { OpenFileIcon } from '@vapor-ui/icons'` | | `OpenFolderIcon` | `import { OpenFolderIcon } from '@vapor-ui/icons'` | | `OperaColorIcon` | `import { OperaColorIcon } from '@vapor-ui/icons'` | | `OrganizationIcon` | `import { OrganizationIcon } from '@vapor-ui/icons'` | | `PanelOpenIcon` | `import { PanelOpenIcon } from '@vapor-ui/icons'` | | `ParentsIcon` | `import { ParentsIcon } from '@vapor-ui/icons'` | | `PauseIcon` | `import { PauseIcon } from '@vapor-ui/icons'` | | `PaycoIcon` | `import { PaycoIcon } from '@vapor-ui/icons'` | | `PaypalColorIcon` | `import { PaypalColorIcon } from '@vapor-ui/icons'` | | `PcIcon` | `import { PcIcon } from '@vapor-ui/icons'` | | `PdfIcon` | `import { PdfIcon } from '@vapor-ui/icons'` | | `PhoneIcon` | `import { PhoneIcon } from '@vapor-ui/icons'` | | `PinSetIcon` | `import { PinSetIcon } from '@vapor-ui/icons'` | | `PipetteIcon` | `import { PipetteIcon } from '@vapor-ui/icons'` | | `PlansIcon` | `import { PlansIcon } from '@vapor-ui/icons'` | | `PlayIcon` | `import { PlayIcon } from '@vapor-ui/icons'` | | `PlugInIcon` | `import { PlugInIcon } from '@vapor-ui/icons'` | | `PlugOutIcon` | `import { PlugOutIcon } from '@vapor-ui/icons'` | | `PlusBoxIcon` | `import { PlusBoxIcon } from '@vapor-ui/icons'` | | `PortforwardingIcon` | `import { PortforwardingIcon } from '@vapor-ui/icons'` | | `PowerIcon` | `import { PowerIcon } from '@vapor-ui/icons'` | | `PreIcon` | `import { PreIcon } from '@vapor-ui/icons'` | | `PresentScreenIcon` | `import { PresentScreenIcon } from '@vapor-ui/icons'` | | `PreviewIcon` | `import { PreviewIcon } from '@vapor-ui/icons'` | | `PrintIcon` | `import { PrintIcon } from '@vapor-ui/icons'` | | `ProductHuntColorIcon` | `import { ProductHuntColorIcon } from '@vapor-ui/icons'` | | `ProgrammingIcon` | `import { ProgrammingIcon } from '@vapor-ui/icons'` | | `ProjectIcon` | `import { ProjectIcon } from '@vapor-ui/icons'` | | `ProjectOpenIcon` | `import { ProjectOpenIcon } from '@vapor-ui/icons'` | | `ProjectSettingIcon` | `import { ProjectSettingIcon } from '@vapor-ui/icons'` | | `PropertyIcon` | `import { PropertyIcon } from '@vapor-ui/icons'` | | `PsychologyIcon` | `import { PsychologyIcon } from '@vapor-ui/icons'` | | `PublishIcon` | `import { PublishIcon } from '@vapor-ui/icons'` | | `QnAIcon` | `import { QnAIcon } from '@vapor-ui/icons'` | | `QuoteIcon` | `import { QuoteIcon } from '@vapor-ui/icons'` | | `ReferenceIcon` | `import { ReferenceIcon } from '@vapor-ui/icons'` | | `RemoteIcon` | `import { RemoteIcon } from '@vapor-ui/icons'` | | `RemoteOffIcon` | `import { RemoteOffIcon } from '@vapor-ui/icons'` | | `ReplaceIcon` | `import { ReplaceIcon } from '@vapor-ui/icons'` | | `ResultManagementIcon` | `import { ResultManagementIcon } from '@vapor-ui/icons'` | | `RouteIcon` | `import { RouteIcon } from '@vapor-ui/icons'` | | `RstudioColorIcon` | `import { RstudioColorIcon } from '@vapor-ui/icons'` | | `RunIcon` | `import { RunIcon } from '@vapor-ui/icons'` | | `SaveAsIcon` | `import { SaveAsIcon } from '@vapor-ui/icons'` | | `SaveIcon` | `import { SaveIcon } from '@vapor-ui/icons'` | | `SavingIcon` | `import { SavingIcon } from '@vapor-ui/icons'` | | `SbomIcon` | `import { SbomIcon } from '@vapor-ui/icons'` | | `SchoolIcon` | `import { SchoolIcon } from '@vapor-ui/icons'` | | `SendIcon` | `import { SendIcon } from '@vapor-ui/icons'` | | `SentryIcon` | `import { SentryIcon } from '@vapor-ui/icons'` | | `SettingIcon` | `import { SettingIcon } from '@vapor-ui/icons'` | | `ShareIcon` | `import { ShareIcon } from '@vapor-ui/icons'` | | `ShoppingCartIcon` | `import { ShoppingCartIcon } from '@vapor-ui/icons'` | | `SideNavIcon` | `import { SideNavIcon } from '@vapor-ui/icons'` | | `SlackColorIcon` | `import { SlackColorIcon } from '@vapor-ui/icons'` | | `SlackIcon` | `import { SlackIcon } from '@vapor-ui/icons'` | | `SlotIcon` | `import { SlotIcon } from '@vapor-ui/icons'` | | `SoundOffIcon` | `import { SoundOffIcon } from '@vapor-ui/icons'` | | `SoundOnIcon` | `import { SoundOnIcon } from '@vapor-ui/icons'` | | `SourcecodeIcon` | `import { SourcecodeIcon } from '@vapor-ui/icons'` | | `SplitIcon` | `import { SplitIcon } from '@vapor-ui/icons'` | | `SshIcon` | `import { SshIcon } from '@vapor-ui/icons'` | | `StarIcon` | `import { StarIcon } from '@vapor-ui/icons'` | | `StopIcon` | `import { StopIcon } from '@vapor-ui/icons'` | | `StorageIcon` | `import { StorageIcon } from '@vapor-ui/icons'` | | `StorybookColorIcon` | `import { StorybookColorIcon } from '@vapor-ui/icons'` | | `StorybookIcon` | `import { StorybookIcon } from '@vapor-ui/icons'` | | `StripeColorIcon` | `import { StripeColorIcon } from '@vapor-ui/icons'` | | `StripeIcon` | `import { StripeIcon } from '@vapor-ui/icons'` | | `StruckIcon` | `import { StruckIcon } from '@vapor-ui/icons'` | | `StudentManagementIcon` | `import { StudentManagementIcon } from '@vapor-ui/icons'` | | `SyllabusIcon` | `import { SyllabusIcon } from '@vapor-ui/icons'` | | `TabletIcon` | `import { TabletIcon } from '@vapor-ui/icons'` | | `TaegukColorIcon` | `import { TaegukColorIcon } from '@vapor-ui/icons'` | | `TaegukIcon` | `import { TaegukIcon } from '@vapor-ui/icons'` | | `TakeoffIcon` | `import { TakeoffIcon } from '@vapor-ui/icons'` | | `TestIcon` | `import { TestIcon } from '@vapor-ui/icons'` | | `TimeIcon` | `import { TimeIcon } from '@vapor-ui/icons'` | | `TrashIcon` | `import { TrashIcon } from '@vapor-ui/icons'` | | `TreeCollapseIcon` | `import { TreeCollapseIcon } from '@vapor-ui/icons'` | | `TrelloIcon` | `import { TrelloIcon } from '@vapor-ui/icons'` | | `TwoFileIcon` | `import { TwoFileIcon } from '@vapor-ui/icons'` | | `UnlockIcon` | `import { UnlockIcon } from '@vapor-ui/icons'` | | `UploadIcon` | `import { UploadIcon } from '@vapor-ui/icons'` | | `UppercaseIcon` | `import { UppercaseIcon } from '@vapor-ui/icons'` | | `UserCheckIcon` | `import { UserCheckIcon } from '@vapor-ui/icons'` | | `UserIcon` | `import { UserIcon } from '@vapor-ui/icons'` | | `UserMoveIcon` | `import { UserMoveIcon } from '@vapor-ui/icons'` | | `UserSearchIcon` | `import { UserSearchIcon } from '@vapor-ui/icons'` | | `VariableIcon` | `import { VariableIcon } from '@vapor-ui/icons'` | | `VideocamOffIcon` | `import { VideocamOffIcon } from '@vapor-ui/icons'` | | `VideocamOnIcon` | `import { VideocamOnIcon } from '@vapor-ui/icons'` | | `ViewModuleIcon` | `import { ViewModuleIcon } from '@vapor-ui/icons'` | | `ViewOffIcon` | `import { ViewOffIcon } from '@vapor-ui/icons'` | | `ViewOnIcon` | `import { ViewOnIcon } from '@vapor-ui/icons'` | | `VscodeColorIcon` | `import { VscodeColorIcon } from '@vapor-ui/icons'` | | `VscodeIcon` | `import { VscodeIcon } from '@vapor-ui/icons'` | | `WarningIcon` | `import { WarningIcon } from '@vapor-ui/icons'` | | `WordMatchIcon` | `import { WordMatchIcon } from '@vapor-ui/icons'` | | `XIcon` | `import { XIcon } from '@vapor-ui/icons'` | | `YoutubeColorIcon` | `import { YoutubeColorIcon } from '@vapor-ui/icons'` | | `YoutubeIcon` | `import { YoutubeIcon } from '@vapor-ui/icons'` | ## Outline Icons | Icon Name | Import Statement | | -------------------------------------- | ------------------------------------------------------------------------ | | `AccessibilityOutlineIcon` | `import { AccessibilityOutlineIcon } from '@vapor-ui/icons'` | | `AchievementOutlineIcon` | `import { AchievementOutlineIcon } from '@vapor-ui/icons'` | | `AddCartOutlineIcon` | `import { AddCartOutlineIcon } from '@vapor-ui/icons'` | | `AddUserOutlineIcon` | `import { AddUserOutlineIcon } from '@vapor-ui/icons'` | | `AiGoormeeOutlineIcon` | `import { AiGoormeeOutlineIcon } from '@vapor-ui/icons'` | | `AiSmartieOutlineIcon` | `import { AiSmartieOutlineIcon } from '@vapor-ui/icons'` | | `AichatOutlineIcon` | `import { AichatOutlineIcon } from '@vapor-ui/icons'` | | `AirplayOutlineIcon` | `import { AirplayOutlineIcon } from '@vapor-ui/icons'` | | `AlgorithmOutlineIcon` | `import { AlgorithmOutlineIcon } from '@vapor-ui/icons'` | | `AlignCenterOutlineIcon` | `import { AlignCenterOutlineIcon } from '@vapor-ui/icons'` | | `AlignJustifyOutlineIcon` | `import { AlignJustifyOutlineIcon } from '@vapor-ui/icons'` | | `AlignLeftOutlineIcon` | `import { AlignLeftOutlineIcon } from '@vapor-ui/icons'` | | `AlignRightOutlineIcon` | `import { AlignRightOutlineIcon } from '@vapor-ui/icons'` | | `AnalysisOutlineIcon` | `import { AnalysisOutlineIcon } from '@vapor-ui/icons'` | | `ArrowDownOutlineIcon` | `import { ArrowDownOutlineIcon } from '@vapor-ui/icons'` | | `ArrowUpOutlineIcon` | `import { ArrowUpOutlineIcon } from '@vapor-ui/icons'` | | `AssignmentOutlineIcon` | `import { AssignmentOutlineIcon } from '@vapor-ui/icons'` | | `AttachFileOutlineIcon` | `import { AttachFileOutlineIcon } from '@vapor-ui/icons'` | | `AttemptOutlineIcon` | `import { AttemptOutlineIcon } from '@vapor-ui/icons'` | | `AutoCodeOutlineIcon` | `import { AutoCodeOutlineIcon } from '@vapor-ui/icons'` | | `BackPageOutlineIcon` | `import { BackPageOutlineIcon } from '@vapor-ui/icons'` | | `BackUpOutlineIcon` | `import { BackUpOutlineIcon } from '@vapor-ui/icons'` | | `BedOutlineIcon` | `import { BedOutlineIcon } from '@vapor-ui/icons'` | | `BellOffOutlineIcon` | `import { BellOffOutlineIcon } from '@vapor-ui/icons'` | | `BellOnOutlineIcon` | `import { BellOnOutlineIcon } from '@vapor-ui/icons'` | | `BlankOutlineIcon` | `import { BlankOutlineIcon } from '@vapor-ui/icons'` | | `BlockOutlineIcon` | `import { BlockOutlineIcon } from '@vapor-ui/icons'` | | `BoldOutlineIcon` | `import { BoldOutlineIcon } from '@vapor-ui/icons'` | | `BookOutlineIcon` | `import { BookOutlineIcon } from '@vapor-ui/icons'` | | `BookmarkOutlineIcon` | `import { BookmarkOutlineIcon } from '@vapor-ui/icons'` | | `BottomPlayerOutlineIcon` | `import { BottomPlayerOutlineIcon } from '@vapor-ui/icons'` | | `BranchOutlineIcon` | `import { BranchOutlineIcon } from '@vapor-ui/icons'` | | `BuildOutlineIcon` | `import { BuildOutlineIcon } from '@vapor-ui/icons'` | | `BulletlistOutlineIcon` | `import { BulletlistOutlineIcon } from '@vapor-ui/icons'` | | `CafeOutlineIcon` | `import { CafeOutlineIcon } from '@vapor-ui/icons'` | | `CakeOutlineIcon` | `import { CakeOutlineIcon } from '@vapor-ui/icons'` | | `CalculatorOutlineIcon` | `import { CalculatorOutlineIcon } from '@vapor-ui/icons'` | | `CalendarOutlineIcon` | `import { CalendarOutlineIcon } from '@vapor-ui/icons'` | | `CallOutlineIcon` | `import { CallOutlineIcon } from '@vapor-ui/icons'` | | `CameraOutlineIcon` | `import { CameraOutlineIcon } from '@vapor-ui/icons'` | | `CampOutlineIcon` | `import { CampOutlineIcon } from '@vapor-ui/icons'` | | `CaptionOutlineIcon` | `import { CaptionOutlineIcon } from '@vapor-ui/icons'` | | `CarOutlineIcon` | `import { CarOutlineIcon } from '@vapor-ui/icons'` | | `CardsOutlineIcon` | `import { CardsOutlineIcon } from '@vapor-ui/icons'` | | `CertificateOutlineIcon` | `import { CertificateOutlineIcon } from '@vapor-ui/icons'` | | `ChapterOutlineIcon` | `import { ChapterOutlineIcon } from '@vapor-ui/icons'` | | `ChartOutlineIcon` | `import { ChartOutlineIcon } from '@vapor-ui/icons'` | | `ChartPieOutlineIcon` | `import { ChartPieOutlineIcon } from '@vapor-ui/icons'` | | `CheckCartOutlineIcon` | `import { CheckCartOutlineIcon } from '@vapor-ui/icons'` | | `CheckCircleOutlineIcon` | `import { CheckCircleOutlineIcon } from '@vapor-ui/icons'` | | `ChevronDoubleLeftOutlineIcon` | `import { ChevronDoubleLeftOutlineIcon } from '@vapor-ui/icons'` | | `ChevronDoubleRightOutlineIcon` | `import { ChevronDoubleRightOutlineIcon } from '@vapor-ui/icons'` | | `ChevronDownOutlineIcon` | `import { ChevronDownOutlineIcon } from '@vapor-ui/icons'` | | `ChevronLeftOutlineIcon` | `import { ChevronLeftOutlineIcon } from '@vapor-ui/icons'` | | `ChevronRightOutlineIcon` | `import { ChevronRightOutlineIcon } from '@vapor-ui/icons'` | | `ChevronUpOutlineIcon` | `import { ChevronUpOutlineIcon } from '@vapor-ui/icons'` | | `CloseOutlineIcon` | `import { CloseOutlineIcon } from '@vapor-ui/icons'` | | `CodeBlockOutlineIcon` | `import { CodeBlockOutlineIcon } from '@vapor-ui/icons'` | | `CollaborationOutlineIcon` | `import { CollaborationOutlineIcon } from '@vapor-ui/icons'` | | `CollapseOutlineIcon` | `import { CollapseOutlineIcon } from '@vapor-ui/icons'` | | `CommitOutlineIcon` | `import { CommitOutlineIcon } from '@vapor-ui/icons'` | | `ConfirmOutlineIcon` | `import { ConfirmOutlineIcon } from '@vapor-ui/icons'` | | `ContainerOutlineIcon` | `import { ContainerOutlineIcon } from '@vapor-ui/icons'` | | `ContainerRunOutlineIcon` | `import { ContainerRunOutlineIcon } from '@vapor-ui/icons'` | | `ContainerShareOutlineIcon` | `import { ContainerShareOutlineIcon } from '@vapor-ui/icons'` | | `ContainerStopOutlineIcon` | `import { ContainerStopOutlineIcon } from '@vapor-ui/icons'` | | `ControlCommonOutlineIcon` | `import { ControlCommonOutlineIcon } from '@vapor-ui/icons'` | | `CopyAsMarkdownOutlineIcon` | `import { CopyAsMarkdownOutlineIcon } from '@vapor-ui/icons'` | | `CopyOutlineIcon` | `import { CopyOutlineIcon } from '@vapor-ui/icons'` | | `CorrectOutlineIcon` | `import { CorrectOutlineIcon } from '@vapor-ui/icons'` | | `CouponOutlineIcon` | `import { CouponOutlineIcon } from '@vapor-ui/icons'` | | `CourseOutlineIcon` | `import { CourseOutlineIcon } from '@vapor-ui/icons'` | | `CpuOutlineIcon` | `import { CpuOutlineIcon } from '@vapor-ui/icons'` | | `CreateBranchOutlineIcon` | `import { CreateBranchOutlineIcon } from '@vapor-ui/icons'` | | `CreditCardOutlineIcon` | `import { CreditCardOutlineIcon } from '@vapor-ui/icons'` | | `DarkOutlineIcon` | `import { DarkOutlineIcon } from '@vapor-ui/icons'` | | `DashboardOutlineIcon` | `import { DashboardOutlineIcon } from '@vapor-ui/icons'` | | `DatabaseOutlineIcon` | `import { DatabaseOutlineIcon } from '@vapor-ui/icons'` | | `DebugOutlineIcon` | `import { DebugOutlineIcon } from '@vapor-ui/icons'` | | `DeployOutlineIcon` | `import { DeployOutlineIcon } from '@vapor-ui/icons'` | | `DeployPushOutlineIcon` | `import { DeployPushOutlineIcon } from '@vapor-ui/icons'` | | `DetailViewOutlineIcon` | `import { DetailViewOutlineIcon } from '@vapor-ui/icons'` | | `DiscOutlineIcon` | `import { DiscOutlineIcon } from '@vapor-ui/icons'` | | `DiscardOutlineIcon` | `import { DiscardOutlineIcon } from '@vapor-ui/icons'` | | `DiscussionOutlineIcon` | `import { DiscussionOutlineIcon } from '@vapor-ui/icons'` | | `DislikeOutlineIcon` | `import { DislikeOutlineIcon } from '@vapor-ui/icons'` | | `DislikeThumbOutlineIcon` | `import { DislikeThumbOutlineIcon } from '@vapor-ui/icons'` | | `DividerOutlineIcon` | `import { DividerOutlineIcon } from '@vapor-ui/icons'` | | `DocktoBottomOutlineIcon` | `import { DocktoBottomOutlineIcon } from '@vapor-ui/icons'` | | `DocumentViewerOutlineIcon` | `import { DocumentViewerOutlineIcon } from '@vapor-ui/icons'` | | `DollarOutlineIcon` | `import { DollarOutlineIcon } from '@vapor-ui/icons'` | | `DownloadOutlineIcon` | `import { DownloadOutlineIcon } from '@vapor-ui/icons'` | | `EditOutlineIcon` | `import { EditOutlineIcon } from '@vapor-ui/icons'` | | `EnterOutlineIcon` | `import { EnterOutlineIcon } from '@vapor-ui/icons'` | | `EqualOutlineIcon` | `import { EqualOutlineIcon } from '@vapor-ui/icons'` | | `EraserOutlineIcon` | `import { EraserOutlineIcon } from '@vapor-ui/icons'` | | `ErrorCircleOutlineIcon` | `import { ErrorCircleOutlineIcon } from '@vapor-ui/icons'` | | `ExamListOutlineIcon` | `import { ExamListOutlineIcon } from '@vapor-ui/icons'` | | `ExamOutlineIcon` | `import { ExamOutlineIcon } from '@vapor-ui/icons'` | | `ExamReportOutlineIcon` | `import { ExamReportOutlineIcon } from '@vapor-ui/icons'` | | `ExpandOutlineIcon` | `import { ExpandOutlineIcon } from '@vapor-ui/icons'` | | `ExploreOutlineIcon` | `import { ExploreOutlineIcon } from '@vapor-ui/icons'` | | `ExportOutlineIcon` | `import { ExportOutlineIcon } from '@vapor-ui/icons'` | | `FileAddOutlineIcon` | `import { FileAddOutlineIcon } from '@vapor-ui/icons'` | | `FileDeleteOutlineIcon` | `import { FileDeleteOutlineIcon } from '@vapor-ui/icons'` | | `FileEditOutlineIcon` | `import { FileEditOutlineIcon } from '@vapor-ui/icons'` | | `FileNewOutlineIcon` | `import { FileNewOutlineIcon } from '@vapor-ui/icons'` | | `FileOutlineIcon` | `import { FileOutlineIcon } from '@vapor-ui/icons'` | | `FilterOutlineIcon` | `import { FilterOutlineIcon } from '@vapor-ui/icons'` | | `FlagOutlineIcon` | `import { FlagOutlineIcon } from '@vapor-ui/icons'` | | `FoldOutlineIcon` | `import { FoldOutlineIcon } from '@vapor-ui/icons'` | | `FolderNewOutlineIcon` | `import { FolderNewOutlineIcon } from '@vapor-ui/icons'` | | `FolderOutlineIcon` | `import { FolderOutlineIcon } from '@vapor-ui/icons'` | | `FolderSearchOutlineIcon` | `import { FolderSearchOutlineIcon } from '@vapor-ui/icons'` | | `ForkOutlineIcon` | `import { ForkOutlineIcon } from '@vapor-ui/icons'` | | `FormatColorTextOutlineIcon` | `import { FormatColorTextOutlineIcon } from '@vapor-ui/icons'` | | `ForwardPageOutlineIcon` | `import { ForwardPageOutlineIcon } from '@vapor-ui/icons'` | | `FunctionOutlineIcon` | `import { FunctionOutlineIcon } from '@vapor-ui/icons'` | | `FunctionsOutlineIcon` | `import { FunctionsOutlineIcon } from '@vapor-ui/icons'` | | `GameOutlineIcon` | `import { GameOutlineIcon } from '@vapor-ui/icons'` | | `GiftOutlineIcon` | `import { GiftOutlineIcon } from '@vapor-ui/icons'` | | `GitMergeOutlineIcon` | `import { GitMergeOutlineIcon } from '@vapor-ui/icons'` | | `GlobalOutlineIcon` | `import { GlobalOutlineIcon } from '@vapor-ui/icons'` | | `GoogleDrawingOutlineIcon` | `import { GoogleDrawingOutlineIcon } from '@vapor-ui/icons'` | | `GooglePresentationOutlineIcon` | `import { GooglePresentationOutlineIcon } from '@vapor-ui/icons'` | | `GoogleSpreadsheetOutlineIcon` | `import { GoogleSpreadsheetOutlineIcon } from '@vapor-ui/icons'` | | `GroupOutlineIcon` | `import { GroupOutlineIcon } from '@vapor-ui/icons'` | | `HardBreakOutlineIcon` | `import { HardBreakOutlineIcon } from '@vapor-ui/icons'` | | `HeadingOutlineIcon` | `import { HeadingOutlineIcon } from '@vapor-ui/icons'` | | `HeartOutlineIcon` | `import { HeartOutlineIcon } from '@vapor-ui/icons'` | | `HelpCircleOutlineIcon` | `import { HelpCircleOutlineIcon } from '@vapor-ui/icons'` | | `HighlightViewOutlineIcon` | `import { HighlightViewOutlineIcon } from '@vapor-ui/icons'` | | `HistoryOutlineIcon` | `import { HistoryOutlineIcon } from '@vapor-ui/icons'` | | `HomeOutlineIcon` | `import { HomeOutlineIcon } from '@vapor-ui/icons'` | | `IdCardOutlineIcon` | `import { IdCardOutlineIcon } from '@vapor-ui/icons'` | | `ImageOutlineIcon` | `import { ImageOutlineIcon } from '@vapor-ui/icons'` | | `ImagePackOutlineIcon` | `import { ImagePackOutlineIcon } from '@vapor-ui/icons'` | | `ImageToContainerOutlineIcon` | `import { ImageToContainerOutlineIcon } from '@vapor-ui/icons'` | | `ImportOutlineIcon` | `import { ImportOutlineIcon } from '@vapor-ui/icons'` | | `InOutlineIcon` | `import { InOutlineIcon } from '@vapor-ui/icons'` | | `IndentDecreaseOutlineIcon` | `import { IndentDecreaseOutlineIcon } from '@vapor-ui/icons'` | | `IndentIncreaseOutlineIcon` | `import { IndentIncreaseOutlineIcon } from '@vapor-ui/icons'` | | `InfiniteOutlineIcon` | `import { InfiniteOutlineIcon } from '@vapor-ui/icons'` | | `InfoCircleOutlineIcon` | `import { InfoCircleOutlineIcon } from '@vapor-ui/icons'` | | `InputSettingOutlineIcon` | `import { InputSettingOutlineIcon } from '@vapor-ui/icons'` | | `IntelliSenseEnumOutlineIcon` | `import { IntelliSenseEnumOutlineIcon } from '@vapor-ui/icons'` | | `IntelliSenseEventOutlineIcon` | `import { IntelliSenseEventOutlineIcon } from '@vapor-ui/icons'` | | `IntelliSenseFieldOutlineIcon` | `import { IntelliSenseFieldOutlineIcon } from '@vapor-ui/icons'` | | `IntelliSenseModuleOutlineIcon` | `import { IntelliSenseModuleOutlineIcon } from '@vapor-ui/icons'` | | `IntelliSensePropertyOutlineIcon` | `import { IntelliSensePropertyOutlineIcon } from '@vapor-ui/icons'` | | `IntelliSenseReferenceOutlineIcon` | `import { IntelliSenseReferenceOutlineIcon } from '@vapor-ui/icons'` | | `IntelliSenseSnippetOutlineIcon` | `import { IntelliSenseSnippetOutlineIcon } from '@vapor-ui/icons'` | | `IntelliSenseTypeParameterOutlineIcon` | `import { IntelliSenseTypeParameterOutlineIcon } from '@vapor-ui/icons'` | | `IntelliSenseUnitOutlineIcon` | `import { IntelliSenseUnitOutlineIcon } from '@vapor-ui/icons'` | | `IntelliSenseVariableOutlineIcon` | `import { IntelliSenseVariableOutlineIcon } from '@vapor-ui/icons'` | | `KeyboardOutlineIcon` | `import { KeyboardOutlineIcon } from '@vapor-ui/icons'` | | `KidOutlineIcon` | `import { KidOutlineIcon } from '@vapor-ui/icons'` | | `LightOutlineIcon` | `import { LightOutlineIcon } from '@vapor-ui/icons'` | | `LightbulbOutlineIcon` | `import { LightbulbOutlineIcon } from '@vapor-ui/icons'` | | `LightningOutlineIcon` | `import { LightningOutlineIcon } from '@vapor-ui/icons'` | | `LikeOutlineIcon` | `import { LikeOutlineIcon } from '@vapor-ui/icons'` | | `LikeThumbOutlineIcon` | `import { LikeThumbOutlineIcon } from '@vapor-ui/icons'` | | `LineSpacingOutlineIcon` | `import { LineSpacingOutlineIcon } from '@vapor-ui/icons'` | | `LineStyleOutlineIcon` | `import { LineStyleOutlineIcon } from '@vapor-ui/icons'` | | `LinearScaleOutlineIcon` | `import { LinearScaleOutlineIcon } from '@vapor-ui/icons'` | | `LinkOffOutlineIcon` | `import { LinkOffOutlineIcon } from '@vapor-ui/icons'` | | `LinkOutlineIcon` | `import { LinkOutlineIcon } from '@vapor-ui/icons'` | | `LiveLessonOutlineIcon` | `import { LiveLessonOutlineIcon } from '@vapor-ui/icons'` | | `LocationOutlineIcon` | `import { LocationOutlineIcon } from '@vapor-ui/icons'` | | `LockOutlineIcon` | `import { LockOutlineIcon } from '@vapor-ui/icons'` | | `LongTextOutlineIcon` | `import { LongTextOutlineIcon } from '@vapor-ui/icons'` | | `MagicWandOutlineIcon` | `import { MagicWandOutlineIcon } from '@vapor-ui/icons'` | | `MailOutlineIcon` | `import { MailOutlineIcon } from '@vapor-ui/icons'` | | `ManagementOutlineIcon` | `import { ManagementOutlineIcon } from '@vapor-ui/icons'` | | `MarkModeOutlineIcon` | `import { MarkModeOutlineIcon } from '@vapor-ui/icons'` | | `MarkdownOutlineIcon` | `import { MarkdownOutlineIcon } from '@vapor-ui/icons'` | | `MemoOutlineIcon` | `import { MemoOutlineIcon } from '@vapor-ui/icons'` | | `MenuOutlineIcon` | `import { MenuOutlineIcon } from '@vapor-ui/icons'` | | `MergeUpOutlineIcon` | `import { MergeUpOutlineIcon } from '@vapor-ui/icons'` | | `MessageOutlineIcon` | `import { MessageOutlineIcon } from '@vapor-ui/icons'` | | `MethodOutlineIcon` | `import { MethodOutlineIcon } from '@vapor-ui/icons'` | | `MicOffOutlineIcon` | `import { MicOffOutlineIcon } from '@vapor-ui/icons'` | | `MicOnOutlineIcon` | `import { MicOnOutlineIcon } from '@vapor-ui/icons'` | | `MinusBoxOutlineIcon` | `import { MinusBoxOutlineIcon } from '@vapor-ui/icons'` | | `MinusOutlineIcon` | `import { MinusOutlineIcon } from '@vapor-ui/icons'` | | `MoreCommonOutlineIcon` | `import { MoreCommonOutlineIcon } from '@vapor-ui/icons'` | | `MovieOutlineIcon` | `import { MovieOutlineIcon } from '@vapor-ui/icons'` | | `NetfficeOutlineIcon` | `import { NetfficeOutlineIcon } from '@vapor-ui/icons'` | | `NetworkOutlineIcon` | `import { NetworkOutlineIcon } from '@vapor-ui/icons'` | | `NextOutlineIcon` | `import { NextOutlineIcon } from '@vapor-ui/icons'` | | `NoImageOutlineIcon` | `import { NoImageOutlineIcon } from '@vapor-ui/icons'` | | `NoUserOutlineIcon` | `import { NoUserOutlineIcon } from '@vapor-ui/icons'` | | `NoticeBoardOutlineIcon` | `import { NoticeBoardOutlineIcon } from '@vapor-ui/icons'` | | `NoticeCircleOutlineIcon` | `import { NoticeCircleOutlineIcon } from '@vapor-ui/icons'` | | `NumberlistOutlineIcon` | `import { NumberlistOutlineIcon } from '@vapor-ui/icons'` | | `OpenFileOutlineIcon` | `import { OpenFileOutlineIcon } from '@vapor-ui/icons'` | | `OpenFolderOutlineIcon` | `import { OpenFolderOutlineIcon } from '@vapor-ui/icons'` | | `OpenInNewOutlineIcon` | `import { OpenInNewOutlineIcon } from '@vapor-ui/icons'` | | `OutOutlineIcon` | `import { OutOutlineIcon } from '@vapor-ui/icons'` | | `PandasOutlineIcon` | `import { PandasOutlineIcon } from '@vapor-ui/icons'` | | `PanelOpenOutlineIcon` | `import { PanelOpenOutlineIcon } from '@vapor-ui/icons'` | | `PauseOutlineIcon` | `import { PauseOutlineIcon } from '@vapor-ui/icons'` | | `PcOutlineIcon` | `import { PcOutlineIcon } from '@vapor-ui/icons'` | | `PdfOutlineIcon` | `import { PdfOutlineIcon } from '@vapor-ui/icons'` | | `PhoneOutlineIcon` | `import { PhoneOutlineIcon } from '@vapor-ui/icons'` | | `PinSetOutlineIcon` | `import { PinSetOutlineIcon } from '@vapor-ui/icons'` | | `PlansOutlineIcon` | `import { PlansOutlineIcon } from '@vapor-ui/icons'` | | `PlayOutlineIcon` | `import { PlayOutlineIcon } from '@vapor-ui/icons'` | | `PlaylistOutlineIcon` | `import { PlaylistOutlineIcon } from '@vapor-ui/icons'` | | `PlusBoxOutlineIcon` | `import { PlusBoxOutlineIcon } from '@vapor-ui/icons'` | | `PlusOutlineIcon` | `import { PlusOutlineIcon } from '@vapor-ui/icons'` | | `PortforwardingOutlineIcon` | `import { PortforwardingOutlineIcon } from '@vapor-ui/icons'` | | `PreOutlineIcon` | `import { PreOutlineIcon } from '@vapor-ui/icons'` | | `PresentScreenOutlineIcon` | `import { PresentScreenOutlineIcon } from '@vapor-ui/icons'` | | `PresetOutlineIcon` | `import { PresetOutlineIcon } from '@vapor-ui/icons'` | | `PreviewOutlineIcon` | `import { PreviewOutlineIcon } from '@vapor-ui/icons'` | | `PriceOutlineIcon` | `import { PriceOutlineIcon } from '@vapor-ui/icons'` | | `PrintOutlineIcon` | `import { PrintOutlineIcon } from '@vapor-ui/icons'` | | `ProgrammingOutlineIcon` | `import { ProgrammingOutlineIcon } from '@vapor-ui/icons'` | | `ProjectOutlineIcon` | `import { ProjectOutlineIcon } from '@vapor-ui/icons'` | | `ProjectSettingOutlineIcon` | `import { ProjectSettingOutlineIcon } from '@vapor-ui/icons'` | | `PsychologyOutlineIcon` | `import { PsychologyOutlineIcon } from '@vapor-ui/icons'` | | `PublishOutlineIcon` | `import { PublishOutlineIcon } from '@vapor-ui/icons'` | | `PullOutlineIcon` | `import { PullOutlineIcon } from '@vapor-ui/icons'` | | `QnAOutlineIcon` | `import { QnAOutlineIcon } from '@vapor-ui/icons'` | | `QrcodeOutlineIcon` | `import { QrcodeOutlineIcon } from '@vapor-ui/icons'` | | `QuoteOutlineIcon` | `import { QuoteOutlineIcon } from '@vapor-ui/icons'` | | `ReferenceOutlineIcon` | `import { ReferenceOutlineIcon } from '@vapor-ui/icons'` | | `RefreshOutlineIcon` | `import { RefreshOutlineIcon } from '@vapor-ui/icons'` | | `RegexOutlineIcon` | `import { RegexOutlineIcon } from '@vapor-ui/icons'` | | `ReloadOutlineIcon` | `import { ReloadOutlineIcon } from '@vapor-ui/icons'` | | `RemoteOffOutlineIcon` | `import { RemoteOffOutlineIcon } from '@vapor-ui/icons'` | | `RemoteOutlineIcon` | `import { RemoteOutlineIcon } from '@vapor-ui/icons'` | | `ReplyOutlineIcon` | `import { ReplyOutlineIcon } from '@vapor-ui/icons'` | | `RestaurantOutlineIcon` | `import { RestaurantOutlineIcon } from '@vapor-ui/icons'` | | `ResultManagementOutlineIcon` | `import { ResultManagementOutlineIcon } from '@vapor-ui/icons'` | | `RouteOutlineIcon` | `import { RouteOutlineIcon } from '@vapor-ui/icons'` | | `RunOutlineIcon` | `import { RunOutlineIcon } from '@vapor-ui/icons'` | | `SaveAsOutlineIcon` | `import { SaveAsOutlineIcon } from '@vapor-ui/icons'` | | `SaveOutlineIcon` | `import { SaveOutlineIcon } from '@vapor-ui/icons'` | | `SavingOutlineIcon` | `import { SavingOutlineIcon } from '@vapor-ui/icons'` | | `SchoolOutlineIcon` | `import { SchoolOutlineIcon } from '@vapor-ui/icons'` | | `SearchOutlineIcon` | `import { SearchOutlineIcon } from '@vapor-ui/icons'` | | `SendOutlineIcon` | `import { SendOutlineIcon } from '@vapor-ui/icons'` | | `SettingOutlineIcon` | `import { SettingOutlineIcon } from '@vapor-ui/icons'` | | `ShareOutlineIcon` | `import { ShareOutlineIcon } from '@vapor-ui/icons'` | | `ShoppingCartOutlineIcon` | `import { ShoppingCartOutlineIcon } from '@vapor-ui/icons'` | | `ShortTextOutlineIcon` | `import { ShortTextOutlineIcon } from '@vapor-ui/icons'` | | `ShortcutOutlineIcon` | `import { ShortcutOutlineIcon } from '@vapor-ui/icons'` | | `SideNavOutlineIcon` | `import { SideNavOutlineIcon } from '@vapor-ui/icons'` | | `SignalPowerOutlineIcon` | `import { SignalPowerOutlineIcon } from '@vapor-ui/icons'` | | `SlashOutlineIcon` | `import { SlashOutlineIcon } from '@vapor-ui/icons'` | | `SoundOffOutlineIcon` | `import { SoundOffOutlineIcon } from '@vapor-ui/icons'` | | `SoundOnOutlineIcon` | `import { SoundOnOutlineIcon } from '@vapor-ui/icons'` | | `SpinnerOutlineIcon` | `import { SpinnerOutlineIcon } from '@vapor-ui/icons'` | | `SplitHorizontalOutlineIcon` | `import { SplitHorizontalOutlineIcon } from '@vapor-ui/icons'` | | `SplitVerticalOutlineIcon` | `import { SplitVerticalOutlineIcon } from '@vapor-ui/icons'` | | `StarOutlineIcon` | `import { StarOutlineIcon } from '@vapor-ui/icons'` | | `StepInOutlineIcon` | `import { StepInOutlineIcon } from '@vapor-ui/icons'` | | `StepOutOutlineIcon` | `import { StepOutOutlineIcon } from '@vapor-ui/icons'` | | `StepOverOutlineIcon` | `import { StepOverOutlineIcon } from '@vapor-ui/icons'` | | `StopOutlineIcon` | `import { StopOutlineIcon } from '@vapor-ui/icons'` | | `StruckOutlineIcon` | `import { StruckOutlineIcon } from '@vapor-ui/icons'` | | `StudentManagementOutlineIcon` | `import { StudentManagementOutlineIcon } from '@vapor-ui/icons'` | | `SyllabusOutlineIcon` | `import { SyllabusOutlineIcon } from '@vapor-ui/icons'` | | `TableFilterOutlineIcon` | `import { TableFilterOutlineIcon } from '@vapor-ui/icons'` | | `TableOutlineIcon` | `import { TableOutlineIcon } from '@vapor-ui/icons'` | | `TabletOutlineIcon` | `import { TabletOutlineIcon } from '@vapor-ui/icons'` | | `TerminalConnectOutlineIcon` | `import { TerminalConnectOutlineIcon } from '@vapor-ui/icons'` | | `TerminalOutlineIcon` | `import { TerminalOutlineIcon } from '@vapor-ui/icons'` | | `TerminalWindowOutlineIcon` | `import { TerminalWindowOutlineIcon } from '@vapor-ui/icons'` | | `TestOutlineIcon` | `import { TestOutlineIcon } from '@vapor-ui/icons'` | | `TextColorOutlineIcon` | `import { TextColorOutlineIcon } from '@vapor-ui/icons'` | | `TextOutlineIcon` | `import { TextOutlineIcon } from '@vapor-ui/icons'` | | `TextScanOutlineIcon` | `import { TextScanOutlineIcon } from '@vapor-ui/icons'` | | `TimeOutlineIcon` | `import { TimeOutlineIcon } from '@vapor-ui/icons'` | | `TransferOutlineIcon` | `import { TransferOutlineIcon } from '@vapor-ui/icons'` | | `TranslateOutlineIcon` | `import { TranslateOutlineIcon } from '@vapor-ui/icons'` | | `TrashOutlineIcon` | `import { TrashOutlineIcon } from '@vapor-ui/icons'` | | `UnderlineOutlineIcon` | `import { UnderlineOutlineIcon } from '@vapor-ui/icons'` | | `UndoOutlineIcon` | `import { UndoOutlineIcon } from '@vapor-ui/icons'` | | `UnlockOutlineIcon` | `import { UnlockOutlineIcon } from '@vapor-ui/icons'` | | `UploadOutlineIcon` | `import { UploadOutlineIcon } from '@vapor-ui/icons'` | | `UserCheckOutlineIcon` | `import { UserCheckOutlineIcon } from '@vapor-ui/icons'` | | `UserMoveOutlineIcon` | `import { UserMoveOutlineIcon } from '@vapor-ui/icons'` | | `UserOutlineIcon` | `import { UserOutlineIcon } from '@vapor-ui/icons'` | | `UserSearchOutlineIcon` | `import { UserSearchOutlineIcon } from '@vapor-ui/icons'` | | `VideocamOffOutlineIcon` | `import { VideocamOffOutlineIcon } from '@vapor-ui/icons'` | | `VideocamOnOutlineIcon` | `import { VideocamOnOutlineIcon } from '@vapor-ui/icons'` | | `ViewExpandOutlineIcon` | `import { ViewExpandOutlineIcon } from '@vapor-ui/icons'` | | `ViewModuleOutlineIcon` | `import { ViewModuleOutlineIcon } from '@vapor-ui/icons'` | | `ViewOffOutlineIcon` | `import { ViewOffOutlineIcon } from '@vapor-ui/icons'` | | `ViewOnOutlineIcon` | `import { ViewOnOutlineIcon } from '@vapor-ui/icons'` | | `ViewShrinkOutlineIcon` | `import { ViewShrinkOutlineIcon } from '@vapor-ui/icons'` | | `WarningOutlineIcon` | `import { WarningOutlineIcon } from '@vapor-ui/icons'` | | `WordSearchOutlineIcon` | `import { WordSearchOutlineIcon } from '@vapor-ui/icons'` | | `ZoomInOutlineIcon` | `import { ZoomInOutlineIcon } from '@vapor-ui/icons'` | | `ZoomOutOutlineIcon` | `import { ZoomOutOutlineIcon } from '@vapor-ui/icons'` | --- version: 1.0.0-beta.6 --- # Welcome, Vapor UI URL: /docs Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/index.mdx Vapor는 구름의 세 번째 디자인 시스템으로, 다양한 서브 패키지들로 구성되어 있습니다. 각 서브 패키지는 다음과 같은 역할을 수행합니다. *** title: Welcome, Vapor UI description: Vapor는 구름의 세 번째 디자인 시스템으로, 다양한 서브 패키지들로 구성되어 있습니다. 각 서브 패키지는 다음과 같은 역할을 수행합니다. ------------------------------------------------------------------------------------------- --- version: 1.0.0-beta.6 --- # Avatar URL: /docs/components/avatar Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/components/avatar.mdx Avatar는 사용자가 설정한 프로필 이미지 혹은 텍스트를 UI상에 나타냅니다. *** title: 'Avatar' site\_name: 'Avatar - Vapor Core' description: 'Avatar는 사용자가 설정한 프로필 이미지 혹은 텍스트를 UI상에 나타냅니다.' ----------------------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/avatar/default-avatar.tsx", "codeblock": true } ``` ## Property *** ### Size Avatar의 크기를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/avatar/avatar-size.tsx", "codeblock": true } ``` ### Shape Avatar의 모양을 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/avatar/avatar-shape.tsx", "codeblock": true } ``` ## Examples *** ### Composition Pattern Avatar 컴포넌트의 다양한 구성 패턴입니다. ```json doc-gen:file { "file": "./src/components/demo/examples/avatar/flexible.tsx", "codeblock": true } ``` ### Fallback Only 이미지 없이 대체 텍스트만 표시합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/avatar/avatar-fallback-only.tsx", "codeblock": true } ``` ## Props Table *** ### Avatar.Root | Prop | Type | Default | Description | | ----------- | ------------------------------------ | -------- | ---------------------------------------------------------------------------------------------- | | `size` | `sm`, `md`, `lg`, `xl` | `md` | 아바타 크기 | | `className` | `string`, `(state: State) => string` | - | 요소에 적용된 CSS 클래스 또는 컴포넌트의 상태에 따라 클래스를 반환하는 함수. | | **alt** | `string` | - | 대체 텍스트, 폴백 이니셜 생성에도 사용 | | `shape` | `circle`, `square` | `square` | 아바타 모서리 형태 | | `src` | `string` | - | 이미지 소스 URL | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | | `delay` | `number` | - | 폴백 표시 전 지연 시간 (밀리초) | #### Avatar.ImagePrimitive | Prop | Type | Default | Description | | ----------------------- | -------------------------------------- | ------- | ---------------------------------------------------------------------------------------------- | | `className` | `string`, `(state: State) => string` | - | 요소에 적용된 CSS 클래스 또는 컴포넌트의 상태에 따라 클래스를 반환하는 함수. | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | | `onLoadingStatusChange` | `(status: ImageLoadingStatus) => void` | - | 로딩 상태가 변경될 때 호출되는 콜백 | #### Avatar.FallbackPrimitive | Prop | Type | Default | Description | | ----------- | ------------------------------------ | ------- | ---------------------------------------------------------------------------------------------- | | `className` | `string`, `(state: State) => string` | - | 요소에 적용된 CSS 클래스 또는 컴포넌트의 상태에 따라 클래스를 반환하는 함수. | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | --- version: 1.0.0-beta.6 --- # Badge URL: /docs/components/badge Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/components/badge.mdx Badge는 이미지, 컨텐츠 등의 상태 또는 분류를 시각적으로 표시합니다. *** title: 'Badge' site\_name: 'Badge - Vapor Core' description: 'Badge는 이미지, 컨텐츠 등의 상태 또는 분류를 시각적으로 표시합니다.' -------------------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/badge/default-badge.tsx", "codeblock": true } ``` ## Property *** ### ColorPalette Badge의 색상을 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/badge/badge-color.tsx", "codeblock": true } ``` ### Shape Badge의 모양을 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/badge/badge-shape.tsx", "codeblock": true } ``` ### Size Badge의 크기를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/badge/badge-size.tsx", "codeblock": true } ``` ## Props Table *** ### Badge | Prop | Type | Default | Description | | -------------- | ------------------------------------------------------------- | --------- | ---------------------------------------------------------------------------------------------- | | `size` | `sm`, `md`, `lg` | `md` | 뱃지 크기 | | `shape` | `square`, `pill` | `square` | 뱃지 모서리 형태 | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | | `colorPalette` | `primary`, `success`, `warning`, `danger`, `hint`, `contrast` | `primary` | 뱃지 색상 | --- version: 1.0.0-beta.6 --- # Breadcrumb URL: /docs/components/breadcrumb Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/components/breadcrumb.mdx 사용자가 현재 페이지의 위치를 파악하고 이전 페이지로 쉽게 이동할 수 있도록 도와주는 네비게이션 컴포넌트입니다. *** title: 'Breadcrumb' site\_name: 'Breadcrumb - Vapor Core' description: '사용자가 현재 페이지의 위치를 파악하고 이전 페이지로 쉽게 이동할 수 있도록 도와주는 네비게이션 컴포넌트입니다.' ----------------------------------------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/breadcrumb/default-breadcrumb.tsx", "codeblock": true } ``` ## Property *** ### Size Breadcrumb 사이즈는 sm, md, lg, xl 로 제공합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/breadcrumb/breadcrumb-size.tsx", "codeblock": true } ``` ### Current 현재 페이지를 나타내는 링크의 상태를 설정할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/breadcrumb/breadcrumb-current.tsx", "codeblock": true } ``` ## Examples *** ### With Ellipsis 긴 네비게이션 경로에서 중간 단계를 생략 표시로 나타낸 패턴입니다. ```json doc-gen:file { "file": "./src/components/demo/examples/breadcrumb/breadcrumb-ellipsis.tsx", "codeblock": true } ``` ### Composition Pattern Breadcrumb 컴포넌트의 다양한 구성 패턴입니다. ```json doc-gen:file { "file": "./src/components/demo/examples/breadcrumb/breadcrumb-composition.tsx", "codeblock": true } ``` ## Props Table *** ### Breadcrumb.Root | Prop | Type | Default | Description | | -------- | ---------------------- | ------- | ---------------------------------------------------------------------------------------------- | | `size` | `sm`, `md`, `lg`, `xl` | `md` | 브레드크럼 크기 | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | #### Breadcrumb.RootPrimitive | Prop | Type | Default | Description | | -------- | ---------------------- | ------- | ---------------------------------------------------------------------------------------------- | | `size` | `sm`, `md`, `lg`, `xl` | `md` | 브레드크럼 크기 | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | #### Breadcrumb.ListPrimitive | Prop | Type | Default | Description | | -------- | -------------- | ------- | ---------------------------------------------------------------------------------------------- | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | ### Breadcrumb.Item | Prop | Type | Default | Description | | --------- | --------------- | ------- | ---------------------------------------------------------------------------------------------- | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | | `current` | `false`, `true` | - | 현재 페이지 여부 | #### Breadcrumb.ItemPrimitive | Prop | Type | Default | Description | | -------- | -------------- | ------- | ---------------------------------------------------------------------------------------------- | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | #### Breadcrumb.LinkPrimitive | Prop | Type | Default | Description | | --------- | --------------- | ------- | ---------------------------------------------------------------------------------------------- | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | | `current` | `false`, `true` | `false` | 현재 페이지 여부 | ### Breadcrumb.Separator | Prop | Type | Default | Description | | -------- | -------------- | ------- | ---------------------------------------------------------------------------------------------- | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | ### Breadcrumb.Ellipsis | Prop | Type | Default | Description | | -------- | -------------- | ------- | ---------------------------------------------------------------------------------------------- | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | #### Breadcrumb.EllipsisPrimitive | Prop | Type | Default | Description | | -------- | -------------- | ------- | ---------------------------------------------------------------------------------------------- | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | --- version: 1.0.0-beta.6 --- # Button URL: /docs/components/button Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/components/button.mdx Button은 사용자가 주요 작업을 수행하도록 돕는 핵심 상호작용 요소입니다. *** title: 'Button' site\_name: 'Button - Vapor Core' description: 'Button은 사용자가 주요 작업을 수행하도록 돕는 핵심 상호작용 요소입니다.' ---------------------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/button/default-button.tsx", "codeblock": true } ``` ## Property *** ### ColorPalette Button의 역할에 따른 색상을 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/button/button-color.tsx", "codeblock": true } ``` ### Size Button의 크기를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/button/button-size.tsx", "codeblock": true } ``` ### Variant Button의 시각적 다양성을 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/button/button-variant.tsx", "codeblock": true } ``` ### Disabled Button의 비활성화 상태를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/button/button-disabled.tsx", "codeblock": true } ``` ## Examples *** ### Button with Icon Button의 역할을 직관적으로 표현하기 위해 아이콘과 함께 사용합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/button/button-with-icon.tsx", "codeblock": true } ``` ## Props Table *** ### Button | Prop | Type | Default | Description | | -------------- | ------------------------------------------------------------------ | --------- | ---------------------------------------------------------------------------------------------- | | `size` | `sm`, `md`, `lg`, `xl` | `md` | 버튼 크기 | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | | `colorPalette` | `primary`, `secondary`, `success`, `warning`, `danger`, `contrast` | `primary` | 버튼 색상 | | `variant` | `outline`, `fill`, `ghost` | `fill` | 버튼 스타일 (fill: 채움, outline: 테두리, ghost: 투명) | --- version: 1.0.0-beta.6 --- # Callout URL: /docs/components/callout Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/components/callout.mdx Callout은 중요한 정보를 시각적으로 강조하여 사용자에게 전달하는 메시지 컴포넌트입니다. *** title: 'Callout' site\_name: 'Callout - Vapor Core' description: 'Callout은 중요한 정보를 시각적으로 강조하여 사용자에게 전달하는 메시지 컴포넌트입니다.' ------------------------------------------------------------------ ```json doc-gen:file { "file": "./src/components/demo/examples/callout/default-callout.tsx", "codeblock": true } ``` ## Property *** ### ColorPalette Callout의 역할에 따른 색상을 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/callout/callout-color.tsx", "codeblock": true } ``` ## Examples *** ### Callout with Icon Callout의 역할을 직관적으로 표현하기 위해 아이콘과 함께 사용합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/callout/callout-with-icon.tsx", "codeblock": true } ``` ## Props Table *** ### Callout.Root | Prop | Type | Default | Description | | -------------- | ------------------------------------------------------------- | --------- | --------------------------------------------------------------------------------------------------------- | | `render` | `ReactElement` | - | 컴포넌트의 HTML 엘리먼트를 다른 태그로 교체하거나 다른 컴포넌트와 조합할 수 있습니다.

`ReactElement` 또는 렌더링할 엘리먼트를 반환하는 함수를 받습니다. | | `colorPalette` | `primary`, `success`, `warning`, `danger`, `hint`, `contrast` | `primary` | 색상 스킴을 제어합니다 | ### Callout.Icon | Prop | Type | Default | Description | | -------- | -------------- | ------- | --------------------------------------------------------------------------------------------------------- | | `render` | `ReactElement` | - | 컴포넌트의 HTML 엘리먼트를 다른 태그로 교체하거나 다른 컴포넌트와 조합할 수 있습니다.

`ReactElement` 또는 렌더링할 엘리먼트를 반환하는 함수를 받습니다. | --- version: 1.0.0-beta.6 --- # Card URL: /docs/components/card Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/components/card.mdx Card는 이미지와 텍스트, 일부 기능 버튼을 포함한 컨테이너로 콘텐츠를 제공합니다. *** title: 'Card' site\_name: 'Card - Vapor Core' description: 'Card는 이미지와 텍스트, 일부 기능 버튼을 포함한 컨테이너로 콘텐츠를 제공합니다.' -------------------------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/card/default-card.tsx", "codeblock": true } ``` ## Examples *** ### Layout 상황에 따라, 일부 영역을 생략하여 Card를 구성할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/card/card-layout.tsx", "codeblock": true } ``` ### Within Form `
` 컴포넌트와 함께 사용하여 관련된 필드를 그룹화할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/card/card-basic.tsx", "codeblock": true } ``` ## Props Table *** ### Card.Root | Prop | Type | Default | Description | | -------- | -------------- | ------- | ---------------------------------------------------------------------------------------------- | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | ### Card.Header | Prop | Type | Default | Description | | -------- | -------------- | ------- | ---------------------------------------------------------------------------------------------- | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | ### Card.Body | Prop | Type | Default | Description | | -------- | -------------- | ------- | ---------------------------------------------------------------------------------------------- | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | ### Card.Footer | Prop | Type | Default | Description | | -------- | -------------- | ------- | ---------------------------------------------------------------------------------------------- | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | --- version: 1.0.0-beta.6 --- # Checkbox URL: /docs/components/checkbox Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/components/checkbox.mdx Checkbox는 여러 항목 중 복수 선택을 가능하게 하는 입력 컴포넌트입니다. *** title: 'Checkbox' site\_name: 'Checkbox - Vapor Core' description: 'Checkbox는 여러 항목 중 복수 선택을 가능하게 하는 입력 컴포넌트입니다.' ----------------------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/checkbox/default-checkbox.tsx", "codeblock": true } ``` ## Property *** ### Size Checkbox의 크기를 결정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/checkbox/checkbox-size.tsx", "codeblock": true } ``` ### Disabled Checkbox의 비활성화 상태를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/checkbox/checkbox-disabled.tsx", "codeblock": true } ``` ### Invalid Checkbox의 유효하지 않음 상태를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/checkbox/checkbox-invalid.tsx", "codeblock": true } ``` ### Indeterminate Checkbox의 혼합 상태 여부를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/checkbox/checkbox-indeterminate.tsx", "codeblock": true } ``` ### Read Only Checkbox의 읽기 전용 상태를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/checkbox/checkbox-readonly.tsx", "codeblock": true } ``` ## Props Table *** ### Checkbox.Root | Prop | Type | Default | Description | | ----------------- | ------------------------------------------------------------------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------- | | `size` | `md`, `lg` | `md` | 체크박스 크기 | | `className` | `string`, `(state: State) => string` | - | 요소에 적용된 CSS 클래스 또는 컴포넌트의 상태에 따라 클래스를 반환하는 함수. | | `id` | `string` | - | input 요소의 고유 식별자 | | `name` | `string` | `undefined` | 폼 제출 시 필드를 식별하는 이름 | | `defaultChecked` | `false`, `true` | `false` | 초기 상태에서 체크박스가 선택되었는지 여부

제어되는 체크박스를 렌더링하려면 대신 `checked` 속성을 사용하십시오. | | `disabled` | `false`, `true` | `false` | 사용자 상호작용을 비활성화할지 여부 | | `value` | `string` | - | 폼 제출 시 체크박스의 값 | | `checked` | `false`, `true` | `undefined` | 체크박스가 현재 선택되었는지 여부

제어되지 않는 체크박스를 렌더링하려면 대신 `defaultChecked` 프로퍼티를 사용하십시오. | | `readOnly` | `false`, `true` | `false` | 사용자가 체크박스를 선택하거나 선택 해제하지 못하도록 할지 여부 | | `required` | `false`, `true` | `false` | 사용자가 폼을 제출하기 전에 체크박스를 선택해야 하는지 여부 | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | | `onCheckedChange` | `(checked: boolean, eventDetails: Checkbox.Root.ChangeEventDetails) => void` | - | 체크박스가 선택되거나 해제될 때 호출되는 이벤트 핸들러 | | `indeterminate` | `false`, `true` | `false` | 체크박스가 indeterminate 상태인지 여부: 선택되었거나 선택되지 않음. | | `inputRef` | `null`, `(instance: HTMLInputElement \| null) => void`, `RefObject` | - | 숨겨진 `<input>` 요소에 접근하기 위한 ref | | `parent` | `false`, `true` | `false` | 체크박스가 하위 체크박스 그룹을 제어하는지 여부

[Checkbox Group](https://base-ui.com/react/components/checkbox-group)에서 사용해야 합니다. | | `nativeButton` | `false`, `true` | `true` | render prop으로 교체할 때 네이티브 `<button>` 요소를 렌더링할지 여부
렌더링되는 요소가 버튼이 아닌 경우(예: `<div>`) `false`로 설정하세요. | | `invalid` | `false`, `true` | `false` | 유효성 검사 실패 상태 | ### Checkbox.IndicatorPrimitive | Prop | Type | Default | Description | | ------------- | ------------------------------------ | ------- | ---------------------------------------------------------------------------------------------- | | `className` | `string`, `(state: State) => string` | - | 요소에 적용된 CSS 클래스 또는 컴포넌트의 상태에 따라 클래스를 반환하는 함수. | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | | `keepMounted` | `false`, `true` | `false` | 체크박스가 선택되지 않은 경우에도 Indicator를 DOM에 유지할지 여부 | --- version: 1.0.0-beta.6 --- # Collapsible URL: /docs/components/collapsible Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/components/collapsible.mdx Collapsible은 콘텐츠를 접었다 펼칠 수 있는 대화형 컴포넌트입니다. 아코디언이나 확장 가능한 섹션을 구현할 때 사용합니다. *** title: 'Collapsible' site\_name: 'Collapsible - Vapor Core' description: 'Collapsible은 콘텐츠를 접었다 펼칠 수 있는 대화형 컴포넌트입니다. 아코디언이나 확장 가능한 섹션을 구현할 때 사용합니다.' ---------------------------------------------------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/collapsible/default-collapsible.tsx", "codeblock": true } ``` ## Property *** ### Open State Collapsible의 열림/닫힘 상태를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/collapsible/collapsible-open-state.tsx", "codeblock": true } ``` ### Keep Mounted 패널이 닫힌 상태에서도 DOM에 유지합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/collapsible/collapsible-keep-mounted.tsx", "codeblock": true } ``` ### Disabled Collapsible의 비활성화 상태를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/collapsible/collapsible-disabled.tsx", "codeblock": true } ``` ## Props Table *** ### Collapsible.Root | Prop | Type | Default | Description | | -------------- | ---------------------------------------------------------------------------- | ------- | ---------------------------------------------------------------------------------------------- | | `className` | `string`, `(state: State) => string` | - | 요소에 적용된 CSS 클래스 또는 컴포넌트의 상태에 따라 클래스를 반환하는 함수. | | `disabled` | `false`, `true` | `false` | 사용자 상호작용을 비활성화할지 여부 | | `open` | `false`, `true` | - | collapsible 패널의 현재 열림 상태

비제어 컴포넌트로 사용하려면 `defaultOpen` prop을 사용하세요. | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | | `defaultOpen` | `false`, `true` | `false` | collapsible 패널의 초기 열림 상태 (비제어 컴포넌트)

제어 컴포넌트로 사용하려면 `open` prop을 사용하세요. | | `onOpenChange` | `(open: boolean, eventDetails: Collapsible.Root.ChangeEventDetails) => void` | - | 패널이 열리거나 닫힐 때 호출되는 이벤트 핸들러 | ### Collapsible.Trigger | Prop | Type | Default | Description | | -------------- | ------------------------------------ | ------- | ----------------------------------------------------------------------------------------------------------------- | | `className` | `string`, `(state: State) => string` | - | 요소에 적용된 CSS 클래스 또는 컴포넌트의 상태에 따라 클래스를 반환하는 함수. | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | | `nativeButton` | `false`, `true` | `true` | render prop으로 교체할 때 네이티브 `<button>` 요소를 렌더링할지 여부
렌더링되는 요소가 버튼이 아닌 경우(예: `<div>`) `false`로 설정하세요. | ### Collapsible.Panel | Prop | Type | Default | Description | | ------------------ | ------------------------------------ | ------- | ---------------------------------------------------------------------------------------------- | | `className` | `string`, `(state: State) => string` | - | 요소에 적용된 CSS 클래스 또는 컴포넌트의 상태에 따라 클래스를 반환하는 함수. | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | | `hiddenUntilFound` | `false`, `true` | `false` | 체크박스가 현재 선택되었는지 여부

제어되지 않는 체크박스를 렌더링하려면 대신 `defaultChecked` 프로퍼티를 사용하십시오 | | `keepMounted` | `false`, `true` | `false` | 요소가 숨겨져 있는 동안 DOM에 유지할지 여부입니다.
이 속성은 `hiddenUntilFound`가 사용될 때 무시됩니다. | --- version: 1.0.0-beta.6 --- # Dialog URL: /docs/components/dialog Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/components/dialog.mdx Dialog는 페이지 위에 모달 형태로 정보를 표시하거나 작업을 수행하도록 하는 컴포넌트입니다. *** title: 'Dialog' site\_name: 'Dialog - Vapor Core' description: 'Dialog는 페이지 위에 모달 형태로 정보를 표시하거나 작업을 수행하도록 하는 컴포넌트입니다.' -------------------------------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/dialog/default-dialog.tsx", "codeblock": true } ``` ## Property *** ### Size Dialog의 크기를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/dialog/dialog-size.tsx", "codeblock": true } ``` ### Modal Behavior Dialog의 모달 동작을 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/dialog/dialog-modal.tsx", "codeblock": true } ``` ## Examples *** ### Custom Usage Dialog 컴포넌트의 다양한 구성 패턴입니다. ```json doc-gen:file { "file": "./src/components/demo/examples/dialog/flexible.tsx", "codeblock": true } ``` ## Props Table *** ### Dialog.Root | Prop | Type | Default | Description | | ---------------------- | ------------------------------------------------------------------------------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `children` | `null`, `string`, `number`, `false`, `true`, `ReactElement`, `Iterable`, `ReactPortal` | - | | | `open` | `false`, `true` | - | Dialog가 현재 열려 있는지 여부. | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | | `defaultOpen` | `false`, `true` | `false` | Dialog가 처음에 열려 있는지 여부입니다.

제어되는 Dialog를 렌더링하려면 대신 `open` prop을 사용하세요. | | `modal` | `false`, `true`, `trap-focus` | `true` | 대화 상자를 열었을 때 모드 상태로 전환되는지 여부를 결정합니다.
- 'true': 사용자 상호작용은 대화 상자에만 제한됩니다: 포커스가 갇히고, 문서 페이지 스크롤이 잠기고, 외부 요소의 포인터 상호작용이 비활성화됩니다.
- 'false': 문서의 나머지 부분과의 사용자 상호작용이 허용됩니다.
- 'trap 포커스': 포커스는 대화 상자 안에 갇혀 있지만, 문서 페이지 스크롤은 잠겨 있지 않고 외부의 포인터 상호작용은 활성화된 상태로 유지됩니다. | | `onOpenChange` | `(open: boolean, eventDetails: Dialog.Root.ChangeEventDetails) => void` | - | 대화 상자를 열거나 닫을 때 호출되는 이벤트 핸들러입니다. | | `onOpenChangeComplete` | `(open: boolean) => void` | - | 대화 상자가 열리거나 닫힐 때 애니메이션이 완료된 후 호출되는 이벤트 핸들러입니다. | | `actionsRef` | `RefObject` | - | 명령적 행동에 대한 참조.
- '언마운트': 지정하면 대화 상자를 닫았을 때 언마운트되지 않습니다.
대신, '언마운트' 기능을 호출하여 수동으로 대화 상자를 언마운트해야 합니다.
대화 상자의 애니메이션이 외부 라이브러리에 의해 제어될 때 유용합니다. | | `size` | `md`, `lg`, `xl` | `md` | Dialog 크기 | ### Dialog.Popup | Prop | Type | Default | Description | | ---------------- | --------------------------------------------------------------------------------------------------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `className` | `string`, `(state: State) => string` | - | 요소에 적용된 CSS 클래스 또는 컴포넌트의 상태에 따라 클래스를 반환하는 함수. | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | | `initialFocus` | `false`, `true`, `RefObject`, `(openType: InteractionType) => boolean \| void \| HTMLElement \| null` | - | 대화 상자를 열 때 집중할 요소를 결정합니다.
- 'false': 초점을 움직이지 마세요.
- 'true': 기본 동작(첫 번째 탭 가능 요소 또는 팝업)에 따라 초점을 이동합니다.
- 'RefObject': 초점을 참조 요소로 이동합니다.
- 'function': 상호작용 유형('마우스', '터치', '펜' 또는 '키보드')으로 호출됩니다.
요소를 초점 맞추기 위해 'true'을, 기본 동작을 사용하기 위해 'true'을, 아무것도 하지 않기 위해 'false'/'undefined'을 반환합니다. | | `finalFocus` | `false`, `true`, `RefObject`, `(closeType: InteractionType) => boolean \| void \| HTMLElement \| null` | - | 대화 상자를 닫을 때 집중할 요소를 결정합니다.
- 'false': 초점을 움직이지 마세요.
- 'true': 기본 동작(트리거 또는 이전에 집중된 요소)에 따라 초점을 이동합니다.
- 'RefObject': 초점을 참조 요소로 이동합니다.
- 'function': 상호작용 유형('마우스', '터치', '펜' 또는 '키보드')으로 호출됩니다.
요소를 초점 맞추기 위해 'true'을, 기본 동작을 사용하기 위해 'true'을, 아무것도 하지 않기 위해 'false'/'undefined'을 반환합니다. | | `portalElement` | `ReactElement` | - | | | `overlayElement` | `ReactElement` | - | | #### Dialog.PortalPrimitive | Prop | Type | Default | Description | | ------------- | ------------------------------------------------------------------------------------------------- | ------- | ---------------------------------------------------------------------------------------------- | | `children` | `null`, `string`, `number`, `false`, `true`, `ReactElement`, `Iterable`, `ReactPortal` | - | | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | | `container` | `null`, `HTMLElement`, `ShadowRoot`, `RefObject` | - | 포털 요소를 렌더링할 상위 요소입니다. | | `keepMounted` | `false`, `true` | `false` | 포털이 숨겨져 있는 동안 DOM에 유지할지 여부입니다. | #### Dialog.OverlayPrimitive | Prop | Type | Default | Description | | ------------- | ------------------------------------ | ------- | ---------------------------------------------------------------------------------------------- | | `className` | `string`, `(state: State) => string` | - | 요소에 적용된 CSS 클래스 또는 컴포넌트의 상태에 따라 클래스를 반환하는 함수. | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | | `forceRender` | `false`, `true` | `false` | 중첩되어 있을 때도 백드롭이 강제로 렌더링되는지 여부입니다. | #### Dialog.PopupPrimitive | Prop | Type | Default | Description | | -------------- | --------------------------------------------------------------------------------------------------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `className` | `string`, `(state: State) => string` | - | 요소에 적용된 CSS 클래스 또는 컴포넌트의 상태에 따라 클래스를 반환하는 함수. | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | | `initialFocus` | `false`, `true`, `RefObject`, `(openType: InteractionType) => boolean \| void \| HTMLElement \| null` | - | 대화 상자를 열 때 집중할 요소를 결정합니다.
- 'false': 초점을 움직이지 마세요.
- 'true': 기본 동작(첫 번째 탭 가능 요소 또는 팝업)에 따라 초점을 이동합니다.
- 'RefObject': 초점을 참조 요소로 이동합니다.
- 'function': 상호작용 유형('마우스', '터치', '펜' 또는 '키보드')으로 호출됩니다.
요소를 초점 맞추기 위해 'true'을, 기본 동작을 사용하기 위해 'true'을, 아무것도 하지 않기 위해 'false'/'undefined'을 반환합니다. | | `finalFocus` | `false`, `true`, `RefObject`, `(closeType: InteractionType) => boolean \| void \| HTMLElement \| null` | - | 대화 상자를 닫을 때 집중할 요소를 결정합니다.
- 'false': 초점을 움직이지 마세요.
- 'true': 기본 동작(트리거 또는 이전에 집중된 요소)에 따라 초점을 이동합니다.
- 'RefObject': 초점을 참조 요소로 이동합니다.
- 'function': 상호작용 유형('마우스', '터치', '펜' 또는 '키보드')으로 호출됩니다.
요소를 초점 맞추기 위해 'true'을, 기본 동작을 사용하기 위해 'true'을, 아무것도 하지 않기 위해 'false'/'undefined'을 반환합니다. | ### Dialog.Trigger | Prop | Type | Default | Description | | -------------- | ------------------------------------ | ------- | ---------------------------------------------------------------------------------------------------------------------------- | | `className` | `string`, `(state: State) => string` | - | 요소에 적용된 CSS 클래스 또는 컴포넌트의 상태에 따라 클래스를 반환하는 함수. | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | | `nativeButton` | `false`, `true` | `true` | 컴포넌트가 `render` 속성을 통해 대체될 때 네이티브 `<button>` 요소를 렌더링할지 여부입니다.
렌더링된 요소가 버튼이 아닌 경우(예: `<div>`) `false`로 설정하세요. | ### Dialog.Close | Prop | Type | Default | Description | | -------------- | ------------------------------------ | ------- | ---------------------------------------------------------------------------------------------------------------------------- | | `className` | `string`, `(state: State) => string` | - | 요소에 적용된 CSS 클래스 또는 컴포넌트의 상태에 따라 클래스를 반환하는 함수. | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | | `nativeButton` | `false`, `true` | `true` | 컴포넌트가 `render` 속성을 통해 대체될 때 네이티브 `<button>` 요소를 렌더링할지 여부입니다.
렌더링된 요소가 버튼이 아닌 경우(예: `<div>`) `false`로 설정하세요. | ### Dialog.Title | Prop | Type | Default | Description | | ----------- | ------------------------------------ | ------- | ---------------------------------------------------------------------------------------------- | | `className` | `string`, `(state: State) => string` | - | 요소에 적용된 CSS 클래스 또는 컴포넌트의 상태에 따라 클래스를 반환하는 함수. | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | ### Dialog.Description | Prop | Type | Default | Description | | ----------- | ------------------------------------ | ------- | ---------------------------------------------------------------------------------------------- | | `className` | `string`, `(state: State) => string` | - | 요소에 적용된 CSS 클래스 또는 컴포넌트의 상태에 따라 클래스를 반환하는 함수. | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | ### Dialog.Header | Prop | Type | Default | Description | | -------- | -------------- | ------- | ---------------------------------------------------------------------------------------------- | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | ### Dialog.Body | Prop | Type | Default | Description | | -------- | -------------- | ------- | ---------------------------------------------------------------------------------------------- | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | ### Dialog.Footer | Prop | Type | Default | Description | | -------- | -------------- | ------- | ---------------------------------------------------------------------------------------------- | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | --- version: 1.0.0-beta.6 --- # Field URL: /docs/components/field Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/components/field.mdx Field는 폼 요소들을 감싸는 컨테이너 컴포넌트로, 라벨, 설명, 에러 메시지, 성공 메시지 등을 제공합니다. *** title: Field site\_name: Field - Vapor Core description: Field는 폼 요소들을 감싸는 컨테이너 컴포넌트로, 라벨, 설명, 에러 메시지, 성공 메시지 등을 제공합니다. --------------------------------------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/field/default-field.tsx", "codeblock": true } ``` ## Property *** ### Invalid State Field의 유효하지 않은 상태를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/field/field-invalid.tsx", "codeblock": true } ``` ### Validation Mode 유효성 검사 타이밍을 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/field/field-validation-mode.tsx", "codeblock": true } ``` ## Examples *** ### With Description Field에 대한 추가 설명을 표시합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/field/field-description.tsx", "codeblock": true } ``` ### Validation 입력된 값에 대한 유효성을 검사합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/field/field-validation.tsx", "codeblock": true } ``` ### Required 필수 Field와 선택 Field를 구분하여 표시합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/field/field-required.tsx", "codeblock": true } ``` ### Disabled disabled 속성을 사용하여 비활성화된 Field를 만들 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/field/field-disabled.tsx", "codeblock": true } ``` ### With RadioGroup RadioGroup과 Field를 함께 사용합니다. ```tsx 'use client'; import { Field, Radio, RadioGroup } from '@vapor-ui/core'; export default function FieldRadioGroup() { return ( 성별
남성
여성
기타
개인정보 보호를 위해 선택사항입니다.
); } ```
### With Form Elements 다양한 폼 요소(TextInput, Checkbox, Switch, Select 등)와 Field를 함께 사용합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/field/field-with-inputs.tsx", "codeblock": true } ``` ### Controlled 제어 컴포넌트로 Field를 관리하고 실시간으로 상태를 표시합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/field/field-controlled.tsx", "codeblock": true } ``` ## Props Table *** ### Field.Root | Prop | Type | Default | Description | | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------- | | `className` | `string`, `(state: State) => string` | - | 요소에 적용된 CSS 클래스 또는 컴포넌트의 상태에 따라 클래스를 반환하는 함수. | | `name` | `string` | - | 폼 제출 시 필드를 식별하는 이름
`<Field.Control>` 컴포넌트의 `name` prop보다 우선합니다. | | `disabled` | `false`, `true` | `false` | 사용자 상호작용을 무시할지 여부
`<Field.Control>` 컴포넌트의 `disabled` prop보다 우선합니다. | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | | `validate` | `(value: unknown, formValues: Record) => string \| string[] \| Promise \| null` | - | 커스텀 유효성 검사 함수
값이 유효하지 않으면 에러 메시지 문자열 또는 문자열 배열을 반환하고, 유효하면 `null`을 반환합니다. | | `validationMode` | `onBlur`, `onChange` | `onBlur` | 필드 유효성 검사 시점

- **onBlur**: 컨트롤이 포커스를 잃을 때 검사
- **onChange**: 컨트롤 값이 변경될 때마다 검사 | | `validationDebounceTime` | `number` | `0` | `validationMode="onChange"` 사용 시 `validate` 콜백 사이의 대기 시간 (밀리초) | | `invalid` | `false`, `true` | - | 필드를 강제로 유효하지 않은 상태로 표시할지 여부 | ### Field.Label | Prop | Type | Default | Description | | ----------- | ------------------------------------ | ------- | ---------------------------------------------------------------------------------------------- | | `className` | `string`, `(state: State) => string` | - | 요소에 적용된 CSS 클래스 또는 컴포넌트의 상태에 따라 클래스를 반환하는 함수. | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | ### Field.Description | Prop | Type | Default | Description | | ----------- | ------------------------------------ | ------- | ---------------------------------------------------------------------------------------------- | | `className` | `string`, `(state: State) => string` | - | 요소에 적용된 CSS 클래스 또는 컴포넌트의 상태에 따라 클래스를 반환하는 함수. | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | ### Field.Error | Prop | Type | Default | Description | | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | | `match` | `false`, `true`, `badInput`, `customError`, `patternMismatch`, `rangeOverflow`, `rangeUnderflow`, `stepMismatch`, `tooLong`, `tooShort`, `typeMismatch`, `valueMissing` | - | 특정 유효성 검사 상태에 대한 오류 메시지를 표시할지 여부

- **false**: 모든 오류 메시지를 표시
- **true**: 모든 오류 메시지를 숨김
- **기타 문자열**: 해당 유효성 검사 상태에 대한 오류 메시지만 표시 | | `className` | `string`, `(state: State) => string` | - | 요소에 적용된 CSS 클래스 또는 컴포넌트의 상태에 따라 클래스를 반환하는 함수. | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | ### Field.Success | Prop | Type | Default | Description | | ----------- | ------------------------------------ | ------- | -------------------------------------------------------------------------------------------------------------------------------- | | `match` | `false`, `true`, `valid` | - | 성공 메시지를 표시할지 여부

- **false**: 모든 성공 메시지를 표시
- **true**: 모든 성공 메시지를 숨김
- **valid**: 필드가 유효한 상태일 때만 성공 메시지를 표시 | | `className` | `string`, `(state: State) => string` | - | 요소에 적용된 CSS 클래스 또는 컴포넌트의 상태에 따라 클래스를 반환하는 함수. | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | --- version: 1.0.0-beta.6 --- # IconButton URL: /docs/components/icon-button Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/components/icon-button.mdx IconButton은 특정 작업이나 기능을 나타내며, 텍스트 없이 아이콘만으로 명령을 전달하는 버튼입니다. *** title: 'IconButton' site\_name: 'IconButton - Vapor Core' description: 'IconButton은 특정 작업이나 기능을 나타내며, 텍스트 없이 아이콘만으로 명령을 전달하는 버튼입니다.' -------------------------------------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/icon-button/default-icon-button.tsx", "codeblock": true } ``` ## Property *** ### Size IconButton의 크기를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/icon-button/icon-button-size.tsx", "codeblock": true } ``` ### ColorPalette IconButton의 색상을 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/icon-button/icon-button-color.tsx", "codeblock": true } ``` ### Variant IconButton의 시각적 변형을 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/icon-button/icon-button-variant.tsx", "codeblock": true } ``` ### Shape IconButton의 모양을 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/icon-button/icon-button-shape.tsx", "codeblock": true } ``` ### Disabled IconButton의 비활성화 상태를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/icon-button/icon-button-disabled.tsx", "codeblock": true } ``` ## Props Table *** ### IconButton | Prop | Type | Default | Description | | -------------- | ------------------------------------------------------------------ | --------- | ---------------------------------------------------------------------------------------------- | | `size` | `sm`, `md`, `lg`, `xl` | `md` | 버튼 크기 | | `shape` | `circle`, `square` | `square` | 버튼 모양 | | **aria-label** | `string` | - | 현재 요소의 레이블을 정의하는 문자열 값 | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | | `colorPalette` | `primary`, `secondary`, `success`, `warning`, `danger`, `contrast` | `primary` | 버튼 색상 | | `variant` | `outline`, `fill`, `ghost` | `fill` | 버튼 스타일 (fill: 채움, outline: 테두리, ghost: 투명) | --- version: 1.0.0-beta.6 --- # InputGroup URL: /docs/components/input-group Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/components/input-group.mdx InputGroup은 입력 필드(TextInput, Textarea)와 관련 요소들을 그룹화하여 문자 수 카운터와 같은 추가 기능을 제공합니다. *** title: 'InputGroup' site\_name: 'InputGroup - Vapor Core' description: 'InputGroup은 입력 필드(TextInput, Textarea)와 관련 요소들을 그룹화하여 문자 수 카운터와 같은 추가 기능을 제공합니다.' ----------------------------------------------------------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/input-group/default-input-group.tsx", "codeblock": true } ``` ## Examples *** ### Custom Counter 커스텀 카운터 UI를 구현합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/input-group/input-group-custom-counter.tsx", "codeblock": true } ``` ## Props Table *** ### InputGroup.Root | Prop | Type | Default | Description | | -------- | -------------- | ------- | ---------------------------------------------------------------------------------------------- | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | ### InputGroup.Counter | Prop | Type | Default | Description | | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ---------------------------------------------------------------------------------------------- | | `children` | `null`, `string`, `number`, `false`, `true`, `ReactElement`, `Iterable`, `ReactPortal`, `(props: CounterRenderProps) => ReactNode` | - | | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | --- version: 1.0.0-beta.6 --- # Menu URL: /docs/components/menu Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/components/menu.mdx 드롭다운 Menu와 컨텍스트 Menu를 제공하는 컴포넌트입니다 *** title: 'Menu' site\_name: 'Menu - Vapor Core' description: '드롭다운 Menu와 컨텍스트 Menu를 제공하는 컴포넌트입니다' ------------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/menu/default-menu.tsx", "codeblock": true } ``` ## Property *** ### Disabled Menu의 비활성화 상태를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/menu/menu-disabled.tsx", "codeblock": true } ``` ## Examples *** ### Positioning Menu의 표시 위치를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/menu/menu-positioning.tsx", "codeblock": true } ``` ### Groups Menu 아이템을 그룹화합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/menu/menu-groups.tsx", "codeblock": true } ``` ### With Checkbox Items Checkbox Item을 사용합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/menu/menu-checkbox.tsx", "codeblock": true } ``` ### With Radio Items Radio Item을 사용합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/menu/menu-radio.tsx", "codeblock": true } ``` ### With Submenu Submenu를 구성할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/menu/menu-submenu.tsx", "codeblock": true } ``` ## Props Table *** ### Menu.Root | Prop | Type | Default | Description | | ---------------------- | -------------------------------------------------------------------------------------------------------------- | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `orientation` | `horizontal`, `vertical` | `vertical` | 메뉴의 시각적 방향입니다.
로빙 포커스가 위/아래 또는 왼쪽/오른쪽 화살표 키를 사용하는지 제어합니다. | | **children** | `undefined`, `null`, `string`, `number`, `false`, `true`, `ReactElement`, `Iterable`, `ReactPortal` | - | | | `loop` | `false`, `true` | `true` | 키보드 포커스를 첫 번째 항목으로 다시 루프할지 여부
화살표 키를 사용할 때 목록 끝에 도달하면. | | `disabled` | `false`, `true` | `false` | 컴포넌트가 사용자 상호작용을 무시해야 하는지 여부입니다. | | `open` | `false`, `true` | - | 메뉴가 현재 열려 있는지 여부입니다. | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | | `defaultOpen` | `false`, `true` | `false` | 메뉴가 처음에 열려 있는지 여부입니다.

제어되는 메뉴를 렌더링하려면 대신 `open` 속성을 사용하세요. | | `modal` | `false`, `true` | `true` | 메뉴가 열려 있을 때 모달 상태에 들어가는지 여부를 결정합니다.
- `true`: 사용자 상호작용이 메뉴로 제한됩니다: 문서 페이지 스크롤이 잠기고 외부 요소에 대한 포인터 상호작용이 비활성화됩니다.
- `false`: 문서의 나머지 부분과의 사용자 상호작용이 허용됩니다. | | `onOpenChange` | `(open: boolean, eventDetails: ChangeEventDetails) => void` | - | 메뉴가 열리거나 닫힐 때 호출되는 이벤트 핸들러입니다. | | `onOpenChangeComplete` | `(open: boolean) => void` | - | 메뉴가 닫힐 때 애니메이션이 완료된 후 호출되는 이벤트 핸들러입니다. | | `closeParentOnEsc` | `false`, `true` | `true` | 하위 메뉴에 있을 때, Escape 키를 눌렀을 때 전체 메뉴를 닫을지
현재 하위 메뉴만 닫을지 결정합니다. | | `delay` | `number` | `100` | 메뉴가 열리기 전에 기다리는 시간입니다.
지연 시간은 밀리초 단위로 지정됩니다.

`openOnHover` 속성이 필요합니다. | | `closeDelay` | `number` | `0` | 마우스를 올려놓아 열린 메뉴를 닫기 전에 기다리는 시간입니다.
지연 시간은 밀리초 단위로 지정됩니다.

`openOnHover` 속성이 필요합니다. | | `openOnHover` | `false`, `true` | - | 트리거에 마우스를 올려놓았을 때 메뉴도 열려야 하는지 여부입니다. | | `actionsRef` | `RefObject` | - | 명령형 작업에 대한 ref입니다.
- `unmount`: 지정된 경우, 메뉴가 닫힐 때 마운트 해제되지 않습니다.
대신, `unmount` 함수를 호출하여 메뉴를 수동으로 마운트 해제해야 합니다.
메뉴의 애니메이션이 외부 라이브러리에 의해 제어되는 경우에 유용합니다. | ### Menu.Trigger | Prop | Type | Default | Description | | -------------- | ------------------------------------------------------------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------- | | `className` | `string`, `(state: State) => string` | - | 요소에 적용된 CSS 클래스 또는 컴포넌트의 상태에 따라 클래스를 반환하는 함수. | | `children` | `null`, `string`, `number`, `false`, `true`, `ReactElement`, `Iterable`, `ReactPortal` | - | | | `disabled` | `false`, `true` | `false` | 구성 요소가 사용자 상호작용을 무시해야 하는지 여부. | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | | `nativeButton` | `false`, `true` | `true` | 구성 요소가 교체할 때 네이티브 '\ 상태 // 합성 컴포넌트 프로젝트 상태 현재 개발 진행상황 섹션 1 섹션 2 섹션 3 ``` ## 4. 예측 가능한 명명 규칙 컴포넌트의 속성은 최대한의 예측 가능성을 위해 **시각적 옵션**과 **논리적 상태**를 기반으로 한 체계적 규칙을 따릅니다. ### 시각적 옵션 ```tsx // 크기 변형은 일관된 스케일을 따름 ... // After ... ``` **Why this change:** * Maintains Figma-React design system parity (SSOT principle) * Follows "React Props = Figma Variants" architectural principle * Aligns with Vapor UI's 4-layer component architecture (Container, Interaction, Contents, Slot) * Layout concerns should be handled by parent containers, not component props #### Patch Changes * 1fd7efc: Updated Menu.Item paddingRight from 6px to 12px to match Figma design specification * ed63947: Correct MenuPositionerPrimitive sideOffset from 8px to 4px to match Figma spec ### @vapor-ui/css-generator #### Patch Changes * 174d004: add color-border-normal semantic token that dynamically adapts to background color customization (light: 100 step, dark: 300 step) * Updated dependencies \[174d004] * @vapor-ui/color-generator\@1.0.0-beta.7 *** ## 1.0.0-beta.6 ### @vapor-ui/codemod #### Minor Changes * b2d053c: add checkbox, collapsible, dialog transform * 939c845: add avatar, breadcrumb, card transform * eb3fdc7: add codemod cli packages ### @vapor-ui/color-generator #### Patch Changes * bd523c7: feat: update color generator & color palette ### @vapor-ui/core #### Patch Changes * bd523c7: feat: update color generator & color palette ### @vapor-ui/css-generator #### Patch Changes * bd523c7: feat: update color generator & color palette * Updated dependencies \[bd523c7] * @vapor-ui/color-generator\@1.0.0 *** ## 1.0.0-beta.5 ### @vapor-ui/codemod #### Minor Changes * a8de0b0: Add codemod for icon packages name import ### @vapor-ui/color-generator #### Minor Changes * caf13a1: feat: create @vapor-ui/color-generator & @vapor-ui/css-generator #### Patch Changes * 707f705: feat: update color tokens ### @vapor-ui/core #### Minor Changes * 27c0ba9: export component with namespace * f8af6e2: feat: remove ThemeScript & simplify ThemeProvider * c9e4b68: migrate to base-ui beta v4 * 220cda2: change components interface * 216866e: feat: add new component `RadioCard` * 6c02d6f: unreflected content revisions * f17650a: add uilitiy props * b581b9f: add `Form` component * 7928a67: add subcomponent props to `Content` * e12f4c4: split label into vertical/horizontal * 5357a54: feat(theme): Add ThemeScope component and migrate to data-attribute based theming * 98170c1: Add white foreground variant to foreground recipe #### Patch Changes * abeac6d: Unified the Cascade Layer into a single layer `vapor` * 3819233: Fix checkbox borderRadius sync error * ee61a32: Synchronize the aria-labelledby with the recieved id prop * df5cb78: separate `readonly` from `disabled` * 707f705: feat: update color tokens * f0f643b: feat: Remove Font Loading from CSS Build * 43cfefb: feat: add font banner * 74dc538: ### Features * **Enabled CSS Tree-shaking:** Component CSS is now imported by its corresponding JS file instead of being in the global `styles.css`. This significantly reduces your production bundle size by only including the CSS for components you actually use. ### Bug Fixes * Fixed a CSS dependency order issue where `IconButton` styles loaded before `Button` styles, causing incorrect style inheritance. * 6f8de5b: correct padding-inline for sm size from 4px(050) to 8px(100) * 4df6bcf: resolved interactions layer's color in dark mode * 25c235e: adjust indicator size to account for border * 716c1d6: restore reset css * 9a3c4f6: fix(RadioGroup): Resolving orientation style errors * d68304a: fix(text-input): add component layer * Updated dependencies \[8217749] * Updated dependencies \[402284e] * Updated dependencies \[fd4acaa] * Updated dependencies \[f2950ee] * @vapor-ui/icons\@0.5.0 ### @vapor-ui/css-generator #### Minor Changes * caf13a1: feat: create @vapor-ui/color-generator & @vapor-ui/css-generator * 5357a54: feat(theme): Add ThemeScope component and migrate to data-attribute based theming #### Patch Changes * 707f705: feat: update color tokens * Updated dependencies \[caf13a1] * Updated dependencies \[707f705] * @vapor-ui/color-generator\@0.1.0 ### @vapor-ui/hooks #### Minor Changes * 68b001c: create avatar , badge , box , button , card , dialog , flex , grid , h-stack , icon-button, nav , text-input , text , theme-provider , v-stack ### @vapor-ui/icons #### Minor Changes * 8217749: Add new icons from Figma **New Basic Icons:** `DocktoBottomIcon`, `SideNavIcon`, `SideNavOutlineIcon`, `DocktoBottomOutlineIcon` **Also Updated:** * Basic Icons: `PanelOpenIcon`, `PanelOpenOutlineIcon` * 402284e: Add new icons from Figma **New Basic Icons:** `DocktoBottomIcon`, `SideNavIcon`, `DocktoBottomOutlineIcon`, `SideNavOutlineIcon` **Also Updated:** * Basic Icons: `PanelOpenIcon`, `PanelOpenOutlineIcon` * fd4acaa: Add new icons from Figma **New Basic Icons:** `SideNavIcon`, `DocktoBottomIcon`, `SideNavOutlineIcon`, `DocktoBottomOutlineIcon` **Also Updated:** * Basic Icons: `PanelOpenIcon`, `PanelOpenOutlineIcon` #### Patch Changes * f2950ee: Update icons from Figma **Updated Basic Icons:** `TreeCollapseIcon` *** ## 0.6.0 ### @vapor-ui/core #### Minor Changes * 4d7eb69: Add new Textarea component with auto-resize functionality * 4026b68: add field components * 4a9bad5: add new `MultiSelect` component * e64e867: change the overlay component interface * 3fff33e: add new `Select` component * d294454: remove label components' * b92cff1: add new `Collapsible` component * b78f3e1: add new `Tabs` component * 98dee18: Migrate `Nav` to `NavigationMenu` * 0880cf7: add new `Sheet` component * 1d2f506: migrate to `Base UI` * e1bf119: add inputgroup component * b4509b1: add new `Popover` component #### Patch Changes * 2651ee2: eidt tooltip offset * 6de8824: edit spacing style implementation * 1ea54c0: fix(Callout): add flex layout for icons and text alignment * Add display: 'flex' to align icons and text horizontally * Add alignItems: 'center' for vertical centering * Add gap spacing between icon and text content * Ensures consistent layout behavior with Button component * 1ba360b: add readonly props * 2b756c5: fix svg rendering issue on safari * 6d1a2e3: remove active style when provided readonly * 1f4ba60: prioritize focus style over hover * Updated dependencies \[450b324] * Updated dependencies \[2b756c5] * Updated dependencies \[e381247] * Updated dependencies \[3bfda49] * @vapor-ui/icons\@0.4.0 *** ## 0.5.0 ### @vapor-ui/core #### Minor Changes * df2dbc4: add new `Tooltip` component * fdbf49d: enhance token structure * 263874c: add new `Menu` component * 66a0032: add new `Breadcrumb` component #### Patch Changes * b498ae2: Fix RadioGroup indicator color to use white background instead of theme-dependent background normal * fe0d153: Align CSS variable naming with new build identifiers config * 7b1b889: remove hover state when used touchscreen * 74b7c97: add VComponentProps * 3611d89: style(Button): add no-wrap * 9188b0e: Enhance vanillaExtractPlugin identifiers for better debugging * 96c0f7a: add box-shadow tokens * Updated dependencies \[c4d0e8e] * Updated dependencies \[a156f82] * @vapor-ui/icons\@0.3.0 *** ## 0.4.0 ### @vapor-ui/core #### Minor Changes * 2ce16a6: refactor(build): Improve DX by Overhauling CSS Bundling Strategy * 482e447: feat: The CSS layer names have been changed to “theme,” “reset,” “components,” and “utilities.” * f5e6651: feat: Add Tailwind CSS v4 Preset #### Patch Changes * 0c6d39c: fix(RadioGroup): remove incorrectly injected props * a813633: fix(Text): Add foreground mixin to style entry point * 242d1e8: style(Badge): add center alignment * Updated dependencies \[30ebcde] * @vapor-ui/icons\@0.2.0 ### @vapor-ui/icons #### Minor Changes * e381247: Add new icons from Figma **New Symbol Icons:** `MediumIcon` **Also Updated:** * Symbol Icons: `FirefoxColorIcon` #### Patch Changes * 450b324: conditionally add CSS variables only when isCssVariable is true * 2b756c5: fix icon size * 3bfda49: Update icons from Figma **Updated Basic Icons:** `TerminalWindowOutlineIcon` *** ## 0.3.1 ### @vapor-ui/core #### Patch Changes * ca267e9: feat: Added primary color custom functionality *** ## 0.3.0 ### @vapor-ui/core #### Minor Changes * e139a7f: remove sprinkles on each components #### Patch Changes * 03655b1: fix(tsup): Correct CSS Layer Priority for vapor-components * 488c614: refactor: replace text sprinkles into mixins ### @vapor-ui/icons #### Minor Changes * c4d0e8e: Add new icons from Figma **New Basic Icons:** `LinearScaleOutlineIcon` **Also Updated:** * Basic Icons: `PlayIcon`, `ReplaceIcon`, `ClassIcon`, `ArrowUpOutlineIcon`, `ArrowDownOutlineIcon`, `TerminalOutlineIcon`, `ViewShrinkOutlineIcon`, `FolderSearchIcon`, `StarOutlineIcon`, `PriceOutlineIcon`, `HistoryOutlineIcon`, `CardsOutlineIcon`, `ZoomOutOutlineIcon`, `IntelliSensePropertyOutlineIcon`, `CorrectOutlineIcon`, `ChevronDoubleRightOutlineIcon`, `AutoCodeOutlineIcon`, `ChapterOutlineIcon` * Symbol Icons: `RstudioColorIcon` * a156f82: Add new icons from Figma **New Basic Icons:** `SidenavIcon` *** ## 0.2.1 ### @vapor-ui/core #### Patch Changes * 6749d80: fix(createThemeConfig): support RSC *** ## 0.2.0 ### @vapor-ui/core #### Minor Changes * 55f2f42: Callout: added new callout component * 4725a73: RadioGroup: add new component * 9f96e2c: Checkbox: Add New `Checkbox` Component * b59dd77: Switch: add new Switch component * 267a998: IconButton: remove @vapor-ui/icons for resolving storybook build error * d7c2714: fix: resolve circular dependency in vanilla-extract and improve tsup build #### Patch Changes * c5cd0fc: edit dialog & interaction animation functions * a0c1ff0: chore: tsup spliting disable * d7c2714: build(tsup): Optimize build system with per-component bundling ### @vapor-ui/icons #### Minor Changes * 30ebcde: feat: Add new icons and update existing icon components ## New Icons Added * `AlignJustifyOutlineIcon`, `CopyAsMarkdownOutlineIcon`, `IndentDecreaseOutlineIcon`, `SlotIcon`, `TextScanOutlineIcon` ## Updated Icons * Updated approximately 190 existing icons with refined SVG paths and improved rendering * Minor coordinate adjustments for better visual consistency * Enhanced clipPath definitions where needed *** ## 0.1.0 ### @vapor-ui/core #### Minor Changes * 68b001c: create avatar , badge , box , button , card , dialog , flex , grid , h-stack , icon-button, nav , text-input , text , theme-provider , v-stack #### Patch Changes * Updated dependencies \[68b001c] * @vapor-ui/hooks\@0.1.0 * @vapor-ui/icons\@0.1.0 ### @vapor-ui/icons #### Minor Changes * 68b001c: create avatar , badge , box , button , card , dialog , flex , grid , h-stack , icon-button, nav , text-input , text , theme-provider , v-stack *** --- version: 1.0.0-beta.6 --- # Tailwind CSS v4 URL: /docs/getting-started/tailwindcss-v4 Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/getting-started/tailwindcss-v4.mdx Vapor UI와 함께 Tailwind CSS v4를 사용하세요. *** title: Tailwind CSS v4 description: Vapor UI와 함께 Tailwind CSS v4를 사용하세요. ------------------------------------------------- Vapor UI는 Tailwind CSS v4와 완벽하게 호환됩니다. **기본적으로 아름다운 컴포넌트**와 **무한한 커스터마이징**이라는 두 가지 장점을 모두 얻을 수 있습니다. ## 시작하기 메인 CSS 파일(예: `global.css`)에 아래 코드를 복사하면 바로 사용할 수 있습니다: ```css /* global.css */ /* 1. 스타일 우선순위 정의 */ @layer tw-theme, vapor, tw-utilities; @import '@vapor-ui/core/tailwind.css'; /* 2. Tailwind CSS 연결 */ @import 'tailwindcss/theme.css' layer(tw-theme); @import 'tailwindcss/utilities.css' layer(tw-utilities); ``` 이제 Vapor UI 컴포넌트와 Tailwind 유틸리티를 자유롭게 조합할 수 있습니다. ## Vapor 유틸리티로 스타일링하기 이제 `v-` 접두사가 붙은 **Vapor 전용 유틸리티 클래스**를 사용할 수 있습니다. Vapor UI의 디자인 시스템이 Tailwind와 완벽하게 통합됩니다. ### 디자인 토큰 클래스 Vapor의 모든 색상, 간격, 둥근 모서리를 **Tailwind 방식**으로 사용할 수 있습니다. `v-` 접두사를 추가하여 Tailwind의 익숙한 문법으로 Vapor 디자인을 적용할 수 있습니다. * **색상**: `bg-v-blue-500`, `text-v-red-300`, `border-v-gray-900` * **간격**: `p-v-100`, `m-v-200`, `gap-v-400`, `w-v-400` * **둥근 모서리**: `rounded-v-200`, `rounded-t-v-400` * **폰트 굵기**: `font-v-400`, `font-v-700` > 💡 팁: Tailwind의 모든 [유틸리티 클래스](https://tailwindcss.com/docs/theme#theme-variable-namespaces)와 조합할 수 있습니다. ### 시맨틱 유틸리티 클래스 **의미 기반 클래스**를 제공합니다. Primary, Success, Warning 등의 역할에 맞는 색상을 쉽게 적용할 수 있습니다. * **배경색**: `bg-v-primary`, `bg-v-secondary`, `bg-v-success`, `bg-v-warning`, `bg-v-danger`, ... * **텍스트색**: `text-v-primary`, `text-v-success`, `text-v-warning`, `text-v-danger`, `text-v-accent`, ... * **테두리색**: `border-v-primary`, `border-v-success`, `border-v-warning`, `border-v-danger`, ... ## 더 깊이 알아보기 ### 스타일 우선순위 이해하기 **왜 Tailwind 클래스가 항상 적용될까요?** CSS `@layer` 규칙 덕분입니다. 위에서 설정한 코드는 스마트한 우선순위 계층을 만듭니다. 1. Vapor 컴포넌트 기본 스타일 2. Vapor 유틸리티 클래스 3. **Tailwind 유틸리티** ← 가장 높은 우선순위 **결과**: `className="bg-blue-500"`와 같은 Tailwind 유틸리티로 Vapor 컴포넌트를 직접 커스터마이징할 수 있습니다. ### CSS Reset: 충돌 없는 설정 Vapor UI가 이미 필요한 스타일 초기화를 처리합니다. 따라서 Tailwind의 `preflight.css`는 사용하지 않는 것을 권장합니다. `preflight.css`를 꼭 써야 한다면, 레이어 순서를 조정해서 충돌을 방지할 수 있습니다: ```css /* preflight를 사용해야 하는 경우 */ @layer tw-theme, vapor.theme, tw-base, vapor.reset, vapor.components, vapor.utilities, tw-utilities; @import '@vapor-ui/core/tailwind.css'; @import 'tailwindcss/theme.css' layer(tw-theme); @import 'tailwindcss/preflight.css' layer(tw-base); @import 'tailwindcss/utilities.css' layer(tw-utilities); ``` > ⚠️ **주의**: 이 방법은 스타일 충돌 가능성이 있으므로 꼭 필요한 경우에만 사용하세요. --- version: 1.0.0-beta.6 --- # Theming URL: /docs/getting-started/theming Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/getting-started/theming.mdx 라이트, 다크, 시스템 테마를 자동으로 지원하는 Vapor UI 테마 시스템을 설정하세요. *** title: Theming description: 라이트, 다크, 시스템 테마를 자동으로 지원하는 Vapor UI 테마 시스템을 설정하세요. --------------------------------------------------------------- Vapor UI는 **라이트 모드, 다크 모드, 시스템 동기화**를 자동으로 지원합니다. `ThemeProvider` 하나로 완전한 테마 관리 시스템을 구축할 수 있습니다. ## 빠른 설정 ### 패키지 설치 ```package-install npm install @vapor-ui/core@beta ``` ### ThemeProvider 설정 애플리케이션 최상위를 `ThemeProvider`로 감싸면 테마 시스템이 활성화됩니다: ```tsx title="app/layout.tsx" import { ThemeProvider } from '@vapor-ui/core'; export default function RootLayout({ children }: { children: React.ReactNode }) { return ( {children} ); } ``` > **SSR 팁**: `suppressHydrationWarning`을 `` 태그에 추가하면 서버-클라이언트 테마 차이로 인한 하이드레이션 경고를 방지할 수 있습니다. ## 테마 제어하기 `useTheme` 훅으로 테마를 읽고 변경할 수 있습니다. 다음 예제는 테마 토글 버튼 구현 방법입니다: ```tsx title="components/theme-toggle.tsx" 'use client'; import { Button } from '@vapor-ui/components/ui/button'; import { useTheme } from '@vapor-ui/core'; export function ThemeToggle() { const { resolvedTheme, setTheme, mounted } = useTheme(); // SSR 환경에서 hydration 완료 전까지 로딩 상태 표시 if (!mounted) { return null; } return ( ); } ``` ## useTheme 훅 레퍼런스 테마 관리에 필요한 모든 기능을 제공합니다: | Key | Type | Description | | :------------ | :--------------------------------------------------------------------------- | :------------------------------------------------------------------ | | theme | `'light' \| 'dark' \| 'system' \| undefined` | 현재 설정된 테마. SSR 환경에서 mounted가 `false`일 때는 `undefined`. | | setTheme | `(theme: 'light' \| 'dark' \| 'system' \| ((prev: Theme) => Theme)) => void` | 테마를 변경하는 함수. 함수형 업데이트도 지원하며 localStorage에 자동 저장됩니다. | | themes | `('light' \| 'dark' \| 'system')[]` | 사용 가능한 테마 목록. 항상 `['light', 'dark', 'system']`을 포함합니다. | | resolvedTheme | `'light' \| 'dark' \| undefined` | 실제로 적용된 테마. theme가 `'system'`일 때 현재 시스템 테마를 반영합니다. | | systemTheme | `'light' \| 'dark' \| undefined` | 현재 사용자의 시스템 테마. theme가 `'system'`일 때만 제공됩니다. | | forcedTheme | `'light' \| 'dark' \| 'system' \| undefined` | 강제로 적용된 테마. 설정되지 않았을 때는 `undefined`. | | resetTheme | `() => void` | 테마 설정을 기본값으로 초기화하고 localStorage에서 저장된 값을 제거합니다. | | mounted | `boolean` | ThemeProvider가 클라이언트에서 마운트되었는지 여부. SSR 환경에서 hydration 이슈 방지를 위해 사용. | ## ThemeProvider 설정 옵션 | Prop | Type | Default | Description | | :------------------------ | :------------------------------ | :----------------- | :----------------------------------------------------------------------- | | defaultTheme | `'light' \| 'dark' \| 'system'` | `'system'` | 테마 동작을 결정합니다. `'light'`, `'dark'`는 고정 테마, `'system'`은 시스템 테마에 자동 동기화됩니다. | | storageKey | `string` | `'vapor-ui-theme'` | localStorage에 테마를 저장할 때 사용될 키. | | forcedTheme\` | `'light' \| 'dark' \| 'system'` | `undefined` | 특정 테마를 강제로 적용합니다. 이 값이 설정되면 다른 모든 테마 관련 설정을 무시합니다. | | disableTransitionOnChange | `boolean` | `false` | `true`일 경우, 테마 변경 시 발생하는 CSS 트랜지션을 비활성화합니다. | | enableColorScheme | `boolean` | `true` | `true`일 경우, `color-scheme` CSS 속성을 자동으로 설정하여 브라우저 UI(스크롤바 등)의 테마를 조정합니다. | | nonce | `string \| undefined` | `undefined` | CSP(Content Security Policy) nonce 값. 보안 정책이 적용된 환경에서 사용. | ## 부분 테마 적용 (ThemeScope) 특정 영역에만 다른 테마를 적용하고 싶을 때 `ThemeScope`를 사용합니다: ```tsx title="components/theme-scope-example.tsx" import { Card } from '@vapor-ui/components/ui/card'; import { ThemeScope } from '@vapor-ui/core'; export function ThemeScopeExample() { return (
전역 테마가 적용된 카드 다크 테마가 강제 적용된 카드 라이트 테마가 강제 적용된 카드
); } ``` ### Portal 컴포넌트와 함께 사용 Dialog, Popover 같은 Portal 컴포넌트가 `ThemeScope`의 테마를 상속받으려면 컨테이너를 지정하세요: ```tsx
{' '} {/* 어떤 요소든 가능 */} {/* 이 Portal은 다크 테마를 상속받음 */}
``` ### ThemeScope 옵션 | Prop | Type | Description | | :---------- | :--------------------------- | :--------------------------- | | forcedTheme | `'light' \| 'dark'` | 해당 영역에 강제로 적용할 테마 | | children | `React.ReactNode` | 테마가 적용될 자식 컴포넌트들 | | style | `CSSProperties \| undefined` | 추가 스타일 (`colorScheme` 자동 설정) | ## 고급 기능 ### SSR 자동 처리 서버-클라이언트 테마 차이로 인한 hydration 오류를 자동으로 방지합니다: * **`mounted` 상태 추적**: 클라이언트 마운트 완료 여부 확인 * **안전한 기본값**: 마운트 전까지 충돌 없는 값 사용 * **자동 동기화**: 마운트 완료 후 실제 테마로 업데이트 ### 테마 동작 모드 **고정 테마** (`'light'` 또는 `'dark'`): * 지정된 테마로 고정 * 시스템 테마 변경 무시 * 사용자가 수동으로 변경 가능 **시스템 동기화** (`'system'`): * 운영체제 테마 설정 자동 감지 * `prefers-color-scheme` 미디어 쿼리로 실시간 추적 * 시스템 변경 시 자동 업데이트 ### 우선순위 시스템 1. **`forcedTheme`** - 강제 테마 (최우선) 2. **`localStorage`** - 사용자 선택 (사용자 존중) 3. **`defaultTheme`** - 기본 설정 (초기값) ### 다중 탭 동기화 여러 브라우저 탭 간 테마 설정을 자동으로 동기화합니다. 한 탭에서 테마를 변경하면 같은 도메인의 다른 탭들도 즉시 업데이트됩니다. ### TypeScript 지원 ```tsx import type { ThemeConfig, ThemeScopeProps, UseThemeProps } from '@vapor-ui/core'; // 시스템 테마에 자동 동기화 const systemConfig: ThemeConfig = { defaultTheme: 'system', }; // 라이트 테마로 고정 const lightConfig: ThemeConfig = { defaultTheme: 'light', }; const MyComponent = () => { const themeData: UseThemeProps = useTheme(); // ... }; ``` --- version: 1.0.0-beta.6 --- # Box URL: /docs/layout/box Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/layout/box.mdx 레이아웃과 스타일링을 위한 기본 컨테이너 컴포넌트입니다. 디자인 토큰을 활용한 간격, 색상, 크기 등의 속성을 제공합니다. *** title: 'Box' site\_name: 'Box - Vapor Core' description: '레이아웃과 스타일링을 위한 기본 컨테이너 컴포넌트입니다. 디자인 토큰을 활용한 간격, 색상, 크기 등의 속성을 제공합니다.' ----------------------------------------------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/box/default-box.tsx", "codeblock": true } ``` ## Property *** ### Display Types Box 컴포넌트는 다양한 디스플레이 타입을 지원하여 레이아웃을 유연하게 구성할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/box/box-display.tsx", "codeblock": true } ``` ### Background Color Box 컴포넌트는 시맨틱 색상과 팔레트 색상을 모두 지원합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/box/box-background.tsx", "codeblock": true } ``` ### Spacing 패딩과 마진 속성을 사용하여 요소의 내부 및 외부 여백을 조절할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/box/box-spacing.tsx", "codeblock": true } ``` ### Layout 플렉스박스 속성을 활용하여 다양한 레이아웃을 구성할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/box/box-layout.tsx", "codeblock": true } ``` ### Dimensions 너비와 높이를 설정하거나 최소/최대 크기 제약을 적용할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/box/box-dimensions.tsx", "codeblock": true } ``` ### Visual Styles 테두리 둥글기, 투명도, 텍스트 정렬 등의 시각적 속성을 제어할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/box/box-visual.tsx", "codeblock": true } ``` ## Props Table *** ### Box | Prop | Type | Default | Description | | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ---------------------------------------------------------------------------------------------- | | `alignContent` | `center`, `end`, `flex-end`, `flex-start`, `start`, `baseline`, `normal`, `stretch`, `space-around`, `space-between`, `space-evenly` | - | | | `alignItems` | `center`, `end`, `flex-end`, `flex-start`, `self-end`, `self-start`, `start`, `baseline`, `normal`, `stretch` | - | | | `backgroundColor` | `$black`, `$white`, `$primary-100`, `$primary-200`, `$secondary-100`, `$success-100`, `$success-200`, `$warning-100`, `$warning-200`, `$danger-100`, `$danger-200`, `$hint-100`, `$hint-200`, `$contrast-100`, `$contrast-200`, `$canvas-100`, `$canvas-200`, `$overlay-100`, `$blue-050`, `$blue-100`, `$blue-200`, `$blue-300`, `$blue-400`, `$blue-500`, `$blue-600`, `$blue-700`, `$blue-800`, `$blue-900`, `$cyan-050`, `$cyan-100`, `$cyan-200`, `$cyan-300`, `$cyan-400`, `$cyan-500`, `$cyan-600`, `$cyan-700`, `$cyan-800`, `$cyan-900`, `$grape-050`, `$grape-100`, `$grape-200`, `$grape-300`, `$grape-400`, `$grape-500`, `$grape-600`, `$grape-700`, `$grape-800`, `$grape-900`, `$gray-050`, `$gray-100`, `$gray-200`, `$gray-300`, `$gray-400`, `$gray-500`, `$gray-600`, `$gray-700`, `$gray-800`, `$gray-900`, `$green-050`, `$green-100`, `$green-200`, `$green-300`, `$green-400`, `$green-500`, `$green-600`, `$green-700`, `$green-800`, `$green-900`, `$lime-050`, `$lime-100`, `$lime-200`, `$lime-300`, `$lime-400`, `$lime-500`, `$lime-600`, `$lime-700`, `$lime-800`, `$lime-900`, `$orange-050`, `$orange-100`, `$orange-200`, `$orange-300`, `$orange-400`, `$orange-500`, `$orange-600`, `$orange-700`, `$orange-800`, `$orange-900`, `$pink-050`, `$pink-100`, `$pink-200`, `$pink-300`, `$pink-400`, `$pink-500`, `$pink-600`, `$pink-700`, `$pink-800`, `$pink-900`, `$red-050`, `$red-100`, `$red-200`, `$red-300`, `$red-400`, `$red-500`, `$red-600`, `$red-700`, `$red-800`, `$red-900`, `$violet-050`, `$violet-100`, `$violet-200`, `$violet-300`, `$violet-400`, `$violet-500`, `$violet-600`, `$violet-700`, `$violet-800`, `$violet-900`, `$yellow-050`, `$yellow-100`, `$yellow-200`, `$yellow-300`, `$yellow-400`, `$yellow-500`, `$yellow-600`, `$yellow-700`, `$yellow-800`, `$yellow-900` | - | | | `color` | `$primary-100`, `$primary-200`, `$secondary-100`, `$success-100`, `$success-200`, `$warning-100`, `$warning-200`, `$danger-100`, `$danger-200`, `$hint-100`, `$hint-200`, `$contrast-100`, `$contrast-200`, `$secondary-200`, `$normal-100`, `$normal-200`, `$button-primary` | - | | | `display` | `flex`, `grid`, `block`, `inline`, `run-in`, `flow`, `flow-root`, `ruby`, `table`, `ruby-base`, `ruby-base-container`, `ruby-text`, `ruby-text-container`, `table-caption`, `table-cell`, `table-column`, `table-column-group`, `table-footer-group`, `table-header-group`, `table-row`, `table-row-group`, `inline-block`, `inline-flex`, `inline-grid`, `inline-list-item`, `inline-table`, `contents`, `list-item`, `none` | - | | | `flexDirection` | `null`, `column`, `column-reverse`, `row`, `row-reverse` | - | | | `height` | `number`, `stretch`, `auto`, `fit-content`, `max-content`, `min-content`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800` | - | | | `justifyContent` | `left`, `right`, `center`, `end`, `flex-end`, `flex-start`, `start`, `normal`, `stretch`, `space-around`, `space-between`, `space-evenly` | - | | | `marginBottom` | `auto`, `$000`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900`, `-$000`, `-$025`, `-$050`, `-$075`, `-$100`, `-$150`, `-$175`, `-$200`, `-$225`, `-$250`, `-$300`, `-$400`, `-$500`, `-$600`, `-$700`, `-$800`, `-$900` | - | | | `marginLeft` | `auto`, `$000`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900`, `-$000`, `-$025`, `-$050`, `-$075`, `-$100`, `-$150`, `-$175`, `-$200`, `-$225`, `-$250`, `-$300`, `-$400`, `-$500`, `-$600`, `-$700`, `-$800`, `-$900` | - | | | `marginRight` | `auto`, `$000`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900`, `-$000`, `-$025`, `-$050`, `-$075`, `-$100`, `-$150`, `-$175`, `-$200`, `-$225`, `-$250`, `-$300`, `-$400`, `-$500`, `-$600`, `-$700`, `-$800`, `-$900` | - | | | `marginTop` | `auto`, `$000`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900`, `-$000`, `-$025`, `-$050`, `-$075`, `-$100`, `-$150`, `-$175`, `-$200`, `-$225`, `-$250`, `-$300`, `-$400`, `-$500`, `-$600`, `-$700`, `-$800`, `-$900` | - | | | `maxHeight` | `number`, `none`, `stretch`, `fit-content`, `intrinsic`, `max-content`, `min-content`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800` | - | | | `maxWidth` | `number`, `none`, `stretch`, `fit-content`, `intrinsic`, `max-content`, `min-content`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800` | - | | | `minHeight` | `number`, `stretch`, `auto`, `fit-content`, `intrinsic`, `max-content`, `min-content`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800` | - | | | `minWidth` | `number`, `stretch`, `auto`, `fit-content`, `intrinsic`, `max-content`, `min-content`, `min-intrinsic`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800` | - | | | `opacity` | `null`, `string`, `number` | - | | | `paddingBottom` | `$000`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900` | - | | | `paddingLeft` | `$000`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900` | - | | | `paddingRight` | `$000`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900` | - | | | `paddingTop` | `$000`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900` | - | | | `pointerEvents` | `all`, `fill`, `stroke`, `none`, `auto`, `inherit`, `painted`, `visible`, `visibleFill`, `visiblePainted`, `visibleStroke` | - | | | `position` | `null`, `absolute`, `fixed`, `relative`, `static`, `sticky` | - | | | `textAlign` | `null`, `left`, `right`, `center`, `end`, `start`, `justify`, `match-parent` | - | | | `width` | `number`, `stretch`, `auto`, `fit-content`, `intrinsic`, `max-content`, `min-content`, `min-intrinsic`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800` | - | | | `border` | `width \| style \| color` | - | | | `borderColor` | `$normal`, `$primary`, `$secondary`, `$success`, `$warning`, `$danger`, `$hint`, `$contrast` | - | | | `borderRadius` | `$000`, `$050`, `$100`, `$200`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900` | - | | | `gap` | `normal`, `$000`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900` | - | | | `margin` | `string`, `number`, `auto`, `$000`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900`, `-$000`, `-$025`, `-$050`, `-$075`, `-$100`, `-$150`, `-$175`, `-$200`, `-$225`, `-$250`, `-$300`, `-$400`, `-$500`, `-$600`, `-$700`, `-$800`, `-$900` | - | | | `overflow` | `null`, `clip`, `auto`, `hidden`, `visible`, `scroll` | - | | | `padding` | `$000`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900` | - | | | `paddingX` | `$000`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900` | - | | | `paddingY` | `$000`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900` | - | | | `marginX` | `string`, `number`, `auto`, `$000`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900`, `-$000`, `-$025`, `-$050`, `-$075`, `-$100`, `-$150`, `-$175`, `-$200`, `-$225`, `-$250`, `-$300`, `-$400`, `-$500`, `-$600`, `-$700`, `-$800`, `-$900` | - | | | `marginY` | `string`, `number`, `auto`, `$000`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900`, `-$000`, `-$025`, `-$050`, `-$075`, `-$100`, `-$150`, `-$175`, `-$200`, `-$225`, `-$250`, `-$300`, `-$400`, `-$500`, `-$600`, `-$700`, `-$800`, `-$900` | - | | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | --- version: 1.0.0-beta.6 --- # Flex URL: /docs/layout/flex Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/layout/flex.mdx 플렉스박스 레이아웃을 쉽게 구현할 수 있는 컨테이너 컴포넌트입니다. Box 컴포넌트를 확장하여 플렉스 관련 기능을 제공합니다. *** title: 'Flex' site\_name: 'Flex - Vapor Core' description: '플렉스박스 레이아웃을 쉽게 구현할 수 있는 컨테이너 컴포넌트입니다. Box 컴포넌트를 확장하여 플렉스 관련 기능을 제공합니다.' ------------------------------------------------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/flex/default-flex.tsx", "codeblock": true } ``` ## Examples *** ### Direction 플렉스 컨테이너의 주축 방향을 설정하여 항목들의 배치 방향을 제어할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/flex/flex-direction.tsx", "codeblock": true } ``` ## Props Table *** ### Flex | Prop | Type | Default | Description | | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ---------------------------------------------------------------------------------------------- | | `alignContent` | `null`, `OnlyString`, `center`, `end`, `flex-end`, `flex-start`, `start`, `baseline`, `normal`, `stretch`, `space-around`, `space-between`, `space-evenly`, `Partial>` | - | | | `alignItems` | `null`, `OnlyString`, `center`, `end`, `flex-end`, `flex-start`, `self-end`, `self-start`, `start`, `baseline`, `normal`, `stretch`, `Partial>` | - | | | `backgroundColor` | `null`, `OnlyString`, `AliceBlue`, `AntiqueWhite`, `Aqua`, `Aquamarine`, `Azure`, `Beige`, `Bisque`, `Black`, `BlanchedAlmond`, `Blue`, `BlueViolet`, `Brown`, `BurlyWood`, `CadetBlue`, `Chartreuse`, `Chocolate`, `Coral`, `CornflowerBlue`, `Cornsilk`, `Crimson`, `Cyan`, `DarkBlue`, `DarkCyan`, `DarkGoldenRod`, `DarkGray`, `DarkGreen`, `DarkGrey`, `DarkKhaki`, `DarkMagenta`, `DarkOliveGreen`, `DarkOrange`, `DarkOrchid`, `DarkRed`, `DarkSalmon`, `DarkSeaGreen`, `DarkSlateBlue`, `DarkSlateGray`, `DarkSlateGrey`, `DarkTurquoise`, `DarkViolet`, `DeepPink`, `DeepSkyBlue`, `DimGray`, `DimGrey`, `DodgerBlue`, `FireBrick`, `FloralWhite`, `ForestGreen`, `Fuchsia`, `Gainsboro`, `GhostWhite`, `Gold`, `GoldenRod`, `Gray`, `Green`, `GreenYellow`, `Grey`, `HoneyDew`, `HotPink`, `IndianRed`, `Indigo`, `Ivory`, `Khaki`, `Lavender`, `LavenderBlush`, `LawnGreen`, `LemonChiffon`, `LightBlue`, `LightCoral`, `LightCyan`, `LightGoldenRodYellow`, `LightGray`, `LightGreen`, `LightGrey`, `LightPink`, `LightSalmon`, `LightSeaGreen`, `LightSkyBlue`, `LightSlateGray`, `LightSlateGrey`, `LightSteelBlue`, `LightYellow`, `Lime`, `LimeGreen`, `Linen`, `Magenta`, `Maroon`, `MediumAquaMarine`, `MediumBlue`, `MediumOrchid`, `MediumPurple`, `MediumSeaGreen`, `MediumSlateBlue`, `MediumSpringGreen`, `MediumTurquoise`, `MediumVioletRed`, `MidnightBlue`, `MintCream`, `MistyRose`, `Moccasin`, `NavajoWhite`, `Navy`, `OldLace`, `Olive`, `OliveDrab`, `Orange`, `OrangeRed`, `Orchid`, `PaleGoldenRod`, `PaleGreen`, `PaleTurquoise`, `PaleVioletRed`, `PapayaWhip`, `PeachPuff`, `Peru`, `Pink`, `Plum`, `PowderBlue`, `Purple`, `RebeccaPurple`, `Red`, `RosyBrown`, `RoyalBlue`, `SaddleBrown`, `Salmon`, `SandyBrown`, `SeaGreen`, `SeaShell`, `Sienna`, `Silver`, `SkyBlue`, `SlateBlue`, `SlateGray`, `SlateGrey`, `Snow`, `SpringGreen`, `SteelBlue`, `Tan`, `Teal`, `Thistle`, `Tomato`, `transparent`, `Turquoise`, `Violet`, `Wheat`, `White`, `WhiteSmoke`, `Yellow`, `YellowGreen`, `CurrentColor`, `hsl(`, `lab(`, `rgb(`, `$primary-100`, `$primary-200`, `$secondary-100`, `$success-100`, `$success-200`, `$warning-100`, `$warning-200`, `$danger-100`, `$danger-200`, `$hint-100`, `$hint-200`, `$contrast-100`, `$contrast-200`, `$black`, `$white`, `$canvas-100`, `$canvas-200`, `$overlay-100`, `$blue-050`, `$blue-100`, `$blue-200`, `$blue-300`, `$blue-400`, `$blue-500`, `$blue-600`, `$blue-700`, `$blue-800`, `$blue-900`, `$cyan-050`, `$cyan-100`, `$cyan-200`, `$cyan-300`, `$cyan-400`, `$cyan-500`, `$cyan-600`, `$cyan-700`, `$cyan-800`, `$cyan-900`, `$grape-050`, `$grape-100`, `$grape-200`, `$grape-300`, `$grape-400`, `$grape-500`, `$grape-600`, `$grape-700`, `$grape-800`, `$grape-900`, `$gray-050`, `$gray-100`, `$gray-200`, `$gray-300`, `$gray-400`, `$gray-500`, `$gray-600`, `$gray-700`, `$gray-800`, `$gray-900`, `$green-050`, `$green-100`, `$green-200`, `$green-300`, `$green-400`, `$green-500`, `$green-600`, `$green-700`, `$green-800`, `$green-900`, `$lime-050`, `$lime-100`, `$lime-200`, `$lime-300`, `$lime-400`, `$lime-500`, `$lime-600`, `$lime-700`, `$lime-800`, `$lime-900`, `$orange-050`, `$orange-100`, `$orange-200`, `$orange-300`, `$orange-400`, `$orange-500`, `$orange-600`, `$orange-700`, `$orange-800`, `$orange-900`, `$pink-050`, `$pink-100`, `$pink-200`, `$pink-300`, `$pink-400`, `$pink-500`, `$pink-600`, `$pink-700`, `$pink-800`, `$pink-900`, `$red-050`, `$red-100`, `$red-200`, `$red-300`, `$red-400`, `$red-500`, `$red-600`, `$red-700`, `$red-800`, `$red-900`, `$violet-050`, `$violet-100`, `$violet-200`, `$violet-300`, `$violet-400`, `$violet-500`, `$violet-600`, `$violet-700`, `$violet-800`, `$violet-900`, `$yellow-050`, `$yellow-100`, `$yellow-200`, `$yellow-300`, `$yellow-400`, `$yellow-500`, `$yellow-600`, `$yellow-700`, `$yellow-800`, `$yellow-900`, `Partial>` | - | | | `color` | `null`, `OnlyString`, `AliceBlue`, `AntiqueWhite`, `Aqua`, `Aquamarine`, `Azure`, `Beige`, `Bisque`, `Black`, `BlanchedAlmond`, `Blue`, `BlueViolet`, `Brown`, `BurlyWood`, `CadetBlue`, `Chartreuse`, `Chocolate`, `Coral`, `CornflowerBlue`, `Cornsilk`, `Crimson`, `Cyan`, `DarkBlue`, `DarkCyan`, `DarkGoldenRod`, `DarkGray`, `DarkGreen`, `DarkGrey`, `DarkKhaki`, `DarkMagenta`, `DarkOliveGreen`, `DarkOrange`, `DarkOrchid`, `DarkRed`, `DarkSalmon`, `DarkSeaGreen`, `DarkSlateBlue`, `DarkSlateGray`, `DarkSlateGrey`, `DarkTurquoise`, `DarkViolet`, `DeepPink`, `DeepSkyBlue`, `DimGray`, `DimGrey`, `DodgerBlue`, `FireBrick`, `FloralWhite`, `ForestGreen`, `Fuchsia`, `Gainsboro`, `GhostWhite`, `Gold`, `GoldenRod`, `Gray`, `Green`, `GreenYellow`, `Grey`, `HoneyDew`, `HotPink`, `IndianRed`, `Indigo`, `Ivory`, `Khaki`, `Lavender`, `LavenderBlush`, `LawnGreen`, `LemonChiffon`, `LightBlue`, `LightCoral`, `LightCyan`, `LightGoldenRodYellow`, `LightGray`, `LightGreen`, `LightGrey`, `LightPink`, `LightSalmon`, `LightSeaGreen`, `LightSkyBlue`, `LightSlateGray`, `LightSlateGrey`, `LightSteelBlue`, `LightYellow`, `Lime`, `LimeGreen`, `Linen`, `Magenta`, `Maroon`, `MediumAquaMarine`, `MediumBlue`, `MediumOrchid`, `MediumPurple`, `MediumSeaGreen`, `MediumSlateBlue`, `MediumSpringGreen`, `MediumTurquoise`, `MediumVioletRed`, `MidnightBlue`, `MintCream`, `MistyRose`, `Moccasin`, `NavajoWhite`, `Navy`, `OldLace`, `Olive`, `OliveDrab`, `Orange`, `OrangeRed`, `Orchid`, `PaleGoldenRod`, `PaleGreen`, `PaleTurquoise`, `PaleVioletRed`, `PapayaWhip`, `PeachPuff`, `Peru`, `Pink`, `Plum`, `PowderBlue`, `Purple`, `RebeccaPurple`, `Red`, `RosyBrown`, `RoyalBlue`, `SaddleBrown`, `Salmon`, `SandyBrown`, `SeaGreen`, `SeaShell`, `Sienna`, `Silver`, `SkyBlue`, `SlateBlue`, `SlateGray`, `SlateGrey`, `Snow`, `SpringGreen`, `SteelBlue`, `Tan`, `Teal`, `Thistle`, `Tomato`, `transparent`, `Turquoise`, `Violet`, `Wheat`, `White`, `WhiteSmoke`, `Yellow`, `YellowGreen`, `CurrentColor`, `hsl(`, `lab(`, `rgb(`, `$primary-100`, `$primary-200`, `$secondary-100`, `$success-100`, `$success-200`, `$warning-100`, `$warning-200`, `$danger-100`, `$danger-200`, `$hint-100`, `$hint-200`, `$contrast-100`, `$contrast-200`, `$secondary-200`, `$normal-100`, `$normal-200`, `$button-primary`, `Partial>` | - | | | `display` | `null`, `flex`, `grid`, `block`, `inline`, `run-in`, `flow`, `flow-root`, `ruby`, `table`, `ruby-base`, `ruby-base-container`, `ruby-text`, `ruby-text-container`, `table-caption`, `table-cell`, `table-column`, `table-column-group`, `table-footer-group`, `table-header-group`, `table-row`, `table-row-group`, `inline-block`, `inline-flex`, `inline-grid`, `inline-list-item`, `inline-table`, `contents`, `list-item`, `none`, `OnlyString`, `Partial>` | - | | | `flexDirection` | `null`, `column`, `column-reverse`, `row`, `row-reverse`, `Partial>` | - | | | `height` | `null`, `number`, `OnlyString`, `stretch`, `auto`, `fit-content`, `max-content`, `min-content`, `Partial>`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800` | - | | | `justifyContent` | `null`, `left`, `right`, `OnlyString`, `center`, `end`, `flex-end`, `flex-start`, `start`, `normal`, `stretch`, `space-around`, `space-between`, `space-evenly`, `Partial>` | - | | | `marginBottom` | `null`, `string & OnlyObject`, `number & OnlyObject`, `auto`, `Partial>`, `$000`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900`, `-$000`, `-$025`, `-$050`, `-$075`, `-$100`, `-$150`, `-$175`, `-$200`, `-$225`, `-$250`, `-$300`, `-$400`, `-$500`, `-$600`, `-$700`, `-$800`, `-$900` | - | | | `marginLeft` | `null`, `string & OnlyObject`, `number & OnlyObject`, `auto`, `Partial>`, `$000`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900`, `-$000`, `-$025`, `-$050`, `-$075`, `-$100`, `-$150`, `-$175`, `-$200`, `-$225`, `-$250`, `-$300`, `-$400`, `-$500`, `-$600`, `-$700`, `-$800`, `-$900` | - | | | `marginRight` | `null`, `string & OnlyObject`, `number & OnlyObject`, `auto`, `Partial>`, `$000`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900`, `-$000`, `-$025`, `-$050`, `-$075`, `-$100`, `-$150`, `-$175`, `-$200`, `-$225`, `-$250`, `-$300`, `-$400`, `-$500`, `-$600`, `-$700`, `-$800`, `-$900` | - | | | `marginTop` | `null`, `string & OnlyObject`, `number & OnlyObject`, `auto`, `Partial>`, `$000`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900`, `-$000`, `-$025`, `-$050`, `-$075`, `-$100`, `-$150`, `-$175`, `-$200`, `-$225`, `-$250`, `-$300`, `-$400`, `-$500`, `-$600`, `-$700`, `-$800`, `-$900` | - | | | `maxHeight` | `null`, `number`, `none`, `OnlyString`, `stretch`, `fit-content`, `intrinsic`, `max-content`, `min-content`, `Partial>`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800` | - | | | `maxWidth` | `null`, `number`, `none`, `OnlyString`, `stretch`, `fit-content`, `intrinsic`, `max-content`, `min-content`, `Partial>`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800` | - | | | `minHeight` | `null`, `number`, `OnlyString`, `stretch`, `auto`, `fit-content`, `intrinsic`, `max-content`, `min-content`, `Partial>`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800` | - | | | `minWidth` | `null`, `number`, `OnlyString`, `stretch`, `auto`, `fit-content`, `intrinsic`, `max-content`, `min-content`, `min-intrinsic`, `Partial>`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800` | - | | | `opacity` | `null`, `string & OnlyObject`, `number & OnlyObject`, `Partial>` | - | | | `paddingBottom` | `null`, `string & OnlyObject`, `number & OnlyObject`, `Partial>`, `$000`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900` | - | | | `paddingLeft` | `null`, `string & OnlyObject`, `number & OnlyObject`, `Partial>`, `$000`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900` | - | | | `paddingRight` | `null`, `string & OnlyObject`, `number & OnlyObject`, `Partial>`, `$000`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900` | - | | | `paddingTop` | `null`, `string & OnlyObject`, `number & OnlyObject`, `Partial>`, `$000`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900` | - | | | `pointerEvents` | `null`, `all`, `fill`, `stroke`, `none`, `auto`, `inherit`, `painted`, `visible`, `visibleFill`, `visiblePainted`, `visibleStroke`, `Partial>` | - | | | `position` | `null`, `absolute`, `fixed`, `relative`, `static`, `sticky`, `Partial>` | - | | | `textAlign` | `null`, `left`, `right`, `center`, `end`, `start`, `justify`, `match-parent`, `Partial>` | - | | | `width` | `null`, `number`, `OnlyString`, `stretch`, `auto`, `fit-content`, `intrinsic`, `max-content`, `min-content`, `min-intrinsic`, `Partial>`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800` | - | | | `border` | `null`, `number`, `inset`, `none`, `OnlyString`, `medium`, `thick`, `thin`, `dashed`, `dotted`, `double`, `groove`, `hidden`, `outset`, `ridge`, `solid`, `AliceBlue`, `AntiqueWhite`, `Aqua`, `Aquamarine`, `Azure`, `Beige`, `Bisque`, `Black`, `BlanchedAlmond`, `Blue`, `BlueViolet`, `Brown`, `BurlyWood`, `CadetBlue`, `Chartreuse`, `Chocolate`, `Coral`, `CornflowerBlue`, `Cornsilk`, `Crimson`, `Cyan`, `DarkBlue`, `DarkCyan`, `DarkGoldenRod`, `DarkGray`, `DarkGreen`, `DarkGrey`, `DarkKhaki`, `DarkMagenta`, `DarkOliveGreen`, `DarkOrange`, `DarkOrchid`, `DarkRed`, `DarkSalmon`, `DarkSeaGreen`, `DarkSlateBlue`, `DarkSlateGray`, `DarkSlateGrey`, `DarkTurquoise`, `DarkViolet`, `DeepPink`, `DeepSkyBlue`, `DimGray`, `DimGrey`, `DodgerBlue`, `FireBrick`, `FloralWhite`, `ForestGreen`, `Fuchsia`, `Gainsboro`, `GhostWhite`, `Gold`, `GoldenRod`, `Gray`, `Green`, `GreenYellow`, `Grey`, `HoneyDew`, `HotPink`, `IndianRed`, `Indigo`, `Ivory`, `Khaki`, `Lavender`, `LavenderBlush`, `LawnGreen`, `LemonChiffon`, `LightBlue`, `LightCoral`, `LightCyan`, `LightGoldenRodYellow`, `LightGray`, `LightGreen`, `LightGrey`, `LightPink`, `LightSalmon`, `LightSeaGreen`, `LightSkyBlue`, `LightSlateGray`, `LightSlateGrey`, `LightSteelBlue`, `LightYellow`, `Lime`, `LimeGreen`, `Linen`, `Magenta`, `Maroon`, `MediumAquaMarine`, `MediumBlue`, `MediumOrchid`, `MediumPurple`, `MediumSeaGreen`, `MediumSlateBlue`, `MediumSpringGreen`, `MediumTurquoise`, `MediumVioletRed`, `MidnightBlue`, `MintCream`, `MistyRose`, `Moccasin`, `NavajoWhite`, `Navy`, `OldLace`, `Olive`, `OliveDrab`, `Orange`, `OrangeRed`, `Orchid`, `PaleGoldenRod`, `PaleGreen`, `PaleTurquoise`, `PaleVioletRed`, `PapayaWhip`, `PeachPuff`, `Peru`, `Pink`, `Plum`, `PowderBlue`, `Purple`, `RebeccaPurple`, `Red`, `RosyBrown`, `RoyalBlue`, `SaddleBrown`, `Salmon`, `SandyBrown`, `SeaGreen`, `SeaShell`, `Sienna`, `Silver`, `SkyBlue`, `SlateBlue`, `SlateGray`, `SlateGrey`, `Snow`, `SpringGreen`, `SteelBlue`, `Tan`, `Teal`, `Thistle`, `Tomato`, `transparent`, `Turquoise`, `Violet`, `Wheat`, `White`, `WhiteSmoke`, `Yellow`, `YellowGreen`, `CurrentColor`, `hsl(`, `lab(`, `rgb(`, `Partial>` | - | | | `borderColor` | `null`, `OnlyString`, `AliceBlue`, `AntiqueWhite`, `Aqua`, `Aquamarine`, `Azure`, `Beige`, `Bisque`, `Black`, `BlanchedAlmond`, `Blue`, `BlueViolet`, `Brown`, `BurlyWood`, `CadetBlue`, `Chartreuse`, `Chocolate`, `Coral`, `CornflowerBlue`, `Cornsilk`, `Crimson`, `Cyan`, `DarkBlue`, `DarkCyan`, `DarkGoldenRod`, `DarkGray`, `DarkGreen`, `DarkGrey`, `DarkKhaki`, `DarkMagenta`, `DarkOliveGreen`, `DarkOrange`, `DarkOrchid`, `DarkRed`, `DarkSalmon`, `DarkSeaGreen`, `DarkSlateBlue`, `DarkSlateGray`, `DarkSlateGrey`, `DarkTurquoise`, `DarkViolet`, `DeepPink`, `DeepSkyBlue`, `DimGray`, `DimGrey`, `DodgerBlue`, `FireBrick`, `FloralWhite`, `ForestGreen`, `Fuchsia`, `Gainsboro`, `GhostWhite`, `Gold`, `GoldenRod`, `Gray`, `Green`, `GreenYellow`, `Grey`, `HoneyDew`, `HotPink`, `IndianRed`, `Indigo`, `Ivory`, `Khaki`, `Lavender`, `LavenderBlush`, `LawnGreen`, `LemonChiffon`, `LightBlue`, `LightCoral`, `LightCyan`, `LightGoldenRodYellow`, `LightGray`, `LightGreen`, `LightGrey`, `LightPink`, `LightSalmon`, `LightSeaGreen`, `LightSkyBlue`, `LightSlateGray`, `LightSlateGrey`, `LightSteelBlue`, `LightYellow`, `Lime`, `LimeGreen`, `Linen`, `Magenta`, `Maroon`, `MediumAquaMarine`, `MediumBlue`, `MediumOrchid`, `MediumPurple`, `MediumSeaGreen`, `MediumSlateBlue`, `MediumSpringGreen`, `MediumTurquoise`, `MediumVioletRed`, `MidnightBlue`, `MintCream`, `MistyRose`, `Moccasin`, `NavajoWhite`, `Navy`, `OldLace`, `Olive`, `OliveDrab`, `Orange`, `OrangeRed`, `Orchid`, `PaleGoldenRod`, `PaleGreen`, `PaleTurquoise`, `PaleVioletRed`, `PapayaWhip`, `PeachPuff`, `Peru`, `Pink`, `Plum`, `PowderBlue`, `Purple`, `RebeccaPurple`, `Red`, `RosyBrown`, `RoyalBlue`, `SaddleBrown`, `Salmon`, `SandyBrown`, `SeaGreen`, `SeaShell`, `Sienna`, `Silver`, `SkyBlue`, `SlateBlue`, `SlateGray`, `SlateGrey`, `Snow`, `SpringGreen`, `SteelBlue`, `Tan`, `Teal`, `Thistle`, `Tomato`, `transparent`, `Turquoise`, `Violet`, `Wheat`, `White`, `WhiteSmoke`, `Yellow`, `YellowGreen`, `CurrentColor`, `hsl(`, `lab(`, `rgb(`, `$normal`, `$primary`, `$secondary`, `$success`, `$warning`, `$danger`, `$hint`, `$contrast`, `Partial>` | - | | | `borderRadius` | `null`, `string & OnlyObject`, `number & OnlyObject`, `Partial>`, `$000`, `$050`, `$100`, `$200`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900` | - | | | `gap` | `null`, `normal`, `string & OnlyObject`, `number & OnlyObject`, `Partial>`, `$000`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900` | - | | | `margin` | `null`, `string & OnlyObject`, `number & OnlyObject`, `auto`, `Partial>`, `$000`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900`, `-$000`, `-$025`, `-$050`, `-$075`, `-$100`, `-$150`, `-$175`, `-$200`, `-$225`, `-$250`, `-$300`, `-$400`, `-$500`, `-$600`, `-$700`, `-$800`, `-$900` | - | | | `overflow` | `null`, `clip`, `OnlyString`, `auto`, `hidden`, `visible`, `scroll`, `Partial>` | - | | | `padding` | `null`, `string & OnlyObject`, `number & OnlyObject`, `Partial>`, `$000`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900` | - | | | `inline` | `false`, `true` | - | 인라인 플렉스 여부 | | `paddingX` | `null`, `string & OnlyObject`, `number & OnlyObject`, `Partial>`, `$000`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900` | - | | | `paddingY` | `null`, `string & OnlyObject`, `number & OnlyObject`, `Partial>`, `$000`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900` | - | | | `marginX` | `null`, `string & OnlyObject`, `number & OnlyObject`, `auto`, `Partial>`, `Partial>`, `$000`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900`, `-$000`, `-$025`, `-$050`, `-$075`, `-$100`, `-$150`, `-$175`, `-$200`, `-$225`, `-$250`, `-$300`, `-$400`, `-$500`, `-$600`, `-$700`, `-$800`, `-$900` | - | | | `marginY` | `null`, `string & OnlyObject`, `number & OnlyObject`, `auto`, `Partial>`, `Partial>`, `$000`, `$025`, `$050`, `$075`, `$100`, `$150`, `$175`, `$200`, `$225`, `$250`, `$300`, `$400`, `$500`, `$600`, `$700`, `$800`, `$900`, `-$000`, `-$025`, `-$050`, `-$075`, `-$100`, `-$150`, `-$175`, `-$200`, `-$225`, `-$250`, `-$300`, `-$400`, `-$500`, `-$600`, `-$700`, `-$800`, `-$900` | - | | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | --- version: 1.0.0-beta.6 --- # Grid URL: /docs/layout/grid Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/layout/grid.mdx 유연하고 강력한 CSS Grid 기반의 레이아웃 컴포넌트입니다 *** title: 'Grid' site\_name: 'Grid - Vapor Core' description: '유연하고 강력한 CSS Grid 기반의 레이아웃 컴포넌트입니다' ------------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/grid/default-grid.tsx", "codeblock": true } ``` ## Property *** ### Template Grid의 행과 열 템플릿을 설정하여 레이아웃 구조를 정의할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/grid/grid-template.tsx", "codeblock": true } ``` ### Flow Grid 아이템들의 자동 배치 방향을 설정할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/grid/grid-flow.tsx", "codeblock": true } ``` ### Inline Grid를 인라인 요소로 표시할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/grid/grid-inline.tsx", "codeblock": true } ``` ### Span Grid 아이템이 차지할 행이나 열의 개수를 설정할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/grid/grid-span.tsx", "codeblock": true } ``` ## Examples *** ### Layout Patterns 일반적인 레이아웃 패턴들을 Grid로 구현할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/grid/grid-layout.tsx", "codeblock": true } ``` ## Props Table *** ### Grid.Root | Prop | Type | Default | Description | | ----------------- | -------------------------------------------- | ------- | ---------------------------------------------------------------------------------------------- | | `inline` | `false`, `true` | - | 인라인 그리드 여부 | | `flow` | `column`, `row`, `row-dense`, `column-dense` | `row` | 그리드 아이템 배치 방향 | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | | `templateRows` | `string` | - | 그리드 행 템플릿 | | `templateColumns` | `string` | - | 그리드 열 템플릿 | ### Grid.Item | Prop | Type | Default | Description | | --------- | -------------- | ------- | ---------------------------------------------------------------------------------------------- | | `colSpan` | `string` | - | 열 범위 지정 | | `rowSpan` | `string` | - | 행 범위 지정 | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | --- version: 1.0.0-beta.6 --- # HStack URL: /docs/layout/h-stack Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/layout/h-stack.mdx 수평으로 아이템들을 배치하는 레이아웃 컴포넌트입니다 *** title: 'HStack' site\_name: 'HStack - Vapor Core' description: '수평으로 아이템들을 배치하는 레이아웃 컴포넌트입니다' ------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/h-stack/default-h-stack.tsx", "codeblock": true } ``` ## Property *** ### Reverse HStack의 아이템 순서를 역순으로 배치할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/h-stack/h-stack-reverse.tsx", "codeblock": true } ``` ### Spacing HStack 아이템 간의 간격을 조정할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/h-stack/h-stack-spacing.tsx", "codeblock": true } ``` ## Props Table *** ### HStack | Prop | Type | Default | Description | | --------- | --------------- | ------- | ---------------------------------------------------------------------------------------------- | | `inline` | `false`, `true` | - | 인라인 플렉스 여부 | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | | `reverse` | `false`, `true` | - | 역방향 배치 여부 | --- version: 1.0.0-beta.6 --- # VStack URL: /docs/layout/v-stack Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/layout/v-stack.mdx 수직으로 아이템들을 배치하는 레이아웃 컴포넌트입니다 *** title: 'VStack' site\_name: 'VStack - Vapor Core' description: '수직으로 아이템들을 배치하는 레이아웃 컴포넌트입니다' ------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/v-stack/default-v-stack.tsx", "codeblock": true } ``` ## Property *** ### Reverse VStack의 아이템 순서를 역순으로 배치할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/v-stack/v-stack-reverse.tsx", "codeblock": true } ``` ### Spacing VStack 아이템 간의 간격을 조정할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/v-stack/v-stack-spacing.tsx", "codeblock": true } ``` ### Alignment VStack 아이템들의 수평 정렬을 조정할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/v-stack/v-stack-alignment.tsx", "codeblock": true } ``` ### Justify Content VStack 아이템들의 수직 분산을 조정할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/v-stack/v-stack-justify.tsx", "codeblock": true } ``` ## Props Table *** ### VStack | Prop | Type | Default | Description | | --------- | --------------- | ------- | ---------------------------------------------------------------------------------------------- | | `inline` | `false`, `true` | - | 인라인 플렉스 여부 | | `render` | `ReactElement` | - | 컴포넌트의 HTML 요소를 다른 태그로 대체하거나 다른 컴포넌트와 조합할 수 있습니다. 렌더링할 요소를 반환하는 `ReactElement` 또는 함수를 인수로 받습니다. | | `reverse` | `false`, `true` | - | 자식 요소의 쌓이는 순서를 반대로 할지 여부 | --- version: 1.0.0-beta.6 --- # Color URL: /docs/tokens/color Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/tokens/color.mdx 컬러 토큰은 브랜드의 정체성과 사용자 경험을 지원하는 다양한 색상을 정의합니다. *** title: Color description: 컬러 토큰은 브랜드의 정체성과 사용자 경험을 지원하는 다양한 색상을 정의합니다. --------------------------------------------------------- }, { value: 'semantic', trigger: 'Semantic Colors', panel: }, ]} /> --- version: 1.0.0-beta.6 --- # Size URL: /docs/tokens/size Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/tokens/size.mdx 요소의 크기,여백과 관련된 값을 정의하여 일관된 디자인을 유지하는 데 도움을 줍니다. *** title: Size description: 요소의 크기,여백과 관련된 값을 정의하여 일관된 디자인을 유지하는 데 도움을 줍니다. ------------------------------------------------------------ | token | value | | ----------------------------- | -------- | | --vapor-size-borderRadius-000 | 0rem | | --vapor-size-borderRadius-050 | 0.125rem | | --vapor-size-borderRadius-100 | 0.25rem | | --vapor-size-borderRadius-200 | 0.375rem | | --vapor-size-borderRadius-300 | 0.5rem | | --vapor-size-borderRadius-400 | 0.75rem | | --vapor-size-borderRadius-500 | 1rem | | --vapor-size-borderRadius-600 | 1.25rem | | --vapor-size-borderRadius-700 | 1.5rem | | --vapor-size-borderRadius-800 | 2rem | | --vapor-size-borderRadius-900 | 2.5rem | | --vapor-size-space-000 | 0rem | | --vapor-size-space-025 | 0.125rem | | --vapor-size-space-050 | 0.25rem | | --vapor-size-space-075 | 0.375rem | | --vapor-size-space-100 | 0.5rem | | --vapor-size-space-150 | 0.75rem | | --vapor-size-space-175 | 0.875rem | | --vapor-size-space-200 | 1rem | | --vapor-size-space-225 | 1.125rem | | --vapor-size-space-250 | 1.25rem | | --vapor-size-space-300 | 1.5rem | | --vapor-size-space-400 | 2rem | | --vapor-size-space-500 | 2.5rem | | --vapor-size-space-600 | 3rem | | --vapor-size-space-700 | 3.5rem | | --vapor-size-space-800 | 4rem | | --vapor-size-space-900 | 4.5rem | | --vapor-size-dimension-025 | 0.125rem | | --vapor-size-dimension-050 | 0.25rem | | --vapor-size-dimension-075 | 0.375rem | | --vapor-size-dimension-100 | 0.5rem | | --vapor-size-dimension-150 | 0.75rem | | --vapor-size-dimension-175 | 0.875rem | | --vapor-size-dimension-200 | 1rem | | --vapor-size-dimension-225 | 1.125rem | | --vapor-size-dimension-250 | 1.25rem | | --vapor-size-dimension-300 | 1.5rem | | --vapor-size-dimension-400 | 2rem | | --vapor-size-dimension-500 | 2.5rem | | --vapor-size-dimension-600 | 3rem | | --vapor-size-dimension-700 | 3.5rem | | --vapor-size-dimension-800 | 4rem | --- version: 1.0.0-beta.6 --- # Typography URL: /docs/tokens/typography Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/tokens/typography.mdx 텍스트의 스타일과 형식을 정의하여 일관된 글꼴 사용과 가독성을 보장합니다. *** title: Typography description: 텍스트의 스타일과 형식을 정의하여 일관된 글꼴 사용과 가독성을 보장합니다. ------------------------------------------------------ | token | value | | ------------------------------------ | ---------- | | --vapor-typography-fontFamily-sans | Pretendard | | --vapor-typography-fontFamily-code | FiraCode | | --vapor-typography-fontSize-025 | 10px | | --vapor-typography-fontSize-050 | 12px | | --vapor-typography-fontSize-075 | 14px | | --vapor-typography-fontSize-100 | 16px | | --vapor-typography-fontSize-200 | 18px | | --vapor-typography-fontSize-300 | 20px | | --vapor-typography-fontSize-400 | 24px | | --vapor-typography-fontSize-500 | 32px | | --vapor-typography-fontSize-600 | 38px | | --vapor-typography-fontSize-700 | 48px | | --vapor-typography-fontSize-800 | 64px | | --vapor-typography-fontSize-900 | 80px | | --vapor-typography-fontSize-1000 | 120px | | --vapor-typography-fontWeight-400 | regular | | --vapor-typography-fontWeight-500 | medium | | --vapor-typography-fontWeight-700 | bold | | --vapor-typography-fontWeight-800 | extra-bold | | --vapor-typography-letterSpacing-000 | 0 | | --vapor-typography-letterSpacing-100 | -0.1px | | --vapor-typography-letterSpacing-200 | -0.2px | | --vapor-typography-letterSpacing-300 | -0.3px | | --vapor-typography-letterSpacing-400 | -0.4px | | --vapor-typography-lineHeight-025 | 14px | | --vapor-typography-lineHeight-050 | 18px | | --vapor-typography-lineHeight-075 | 22px | | --vapor-typography-lineHeight-100 | 24px | | --vapor-typography-lineHeight-200 | 26px | | --vapor-typography-lineHeight-300 | 30px | | --vapor-typography-lineHeight-400 | 36px | | --vapor-typography-lineHeight-500 | 48px | | --vapor-typography-lineHeight-600 | 56px | | --vapor-typography-lineHeight-700 | 62px | | --vapor-typography-lineHeight-800 | 84px | | --vapor-typography-lineHeight-900 | 104px | | --vapor-typography-lineHeight-1000 | 156px | --- version: 1.0.0-beta.6 --- # Form URL: /blocks/form Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/blocks/form.mdx 여러 개의 입력 단위를 하나로 묶어 사용자로부터 정보를 수집하는 폼 영역 *** title: Form description: 여러 개의 입력 단위를 하나로 묶어 사용자로부터 정보를 수집하는 폼 영역 previewImageUrl: /images/form-preview\.svg ------------------------------------------ ### Type: Login ```tsx import './login-form.css'; import { Box, Button, Checkbox, Field, Form, HStack, Text, TextInput, VStack, } from '@vapor-ui/core'; export default function LoginForm() { return ( event.preventDefault()} />} > } flexDirection="column" justifyContent="space-between" > 이메일 이메일을 입력해주세요. 유효한 이메일 형식이 아닙니다. } flexDirection="column" justifyContent="space-between" > 비밀번호 8~16자, 대소문자 영문, 특수문자 포함 비밀번호를 입력해주세요. 유효한 비밀번호 형식이 아닙니다. } alignItems="center"> 자동 로그인 ); } ``` ```css .input-label { color: var(--vapor-color-foreground-normal-100, #525463); font-size: var(--vapor-typography-fontSize-050, 0.75rem); font-weight: var(--vapor-typography-fontWeight-500); line-height: var(--vapor-typography-lineHeight-050, 1.125rem); /* 150% */ letter-spacing: var(--vapor-typography-letterSpacing-000, 0); } .checkbox-label { color: var(--vapor-color-foreground-normal-100, #2b2d36); font-size: var(--vapor-typography-fontSize-075, 0.875rem); font-weight: var(--vapor-typography-fontWeight-400); line-height: var(--vapor-typography-lineHeight-075, 1.375rem); /* 157.143% */ letter-spacing: var(--vapor-typography-letterSpacing-100, -0.00625rem); } .helper-text { color: var(--vapor-color-foreground-hint, #6c6e7e); font-size: var(--vapor-typography-fontSize-075, 0.875rem); font-weight: var(--vapor-typography-fontWeight-400); line-height: var(--vapor-typography-lineHeight-075, 1.375rem); /* 157.143% */ letter-spacing: var(--vapor-typography-letterSpacing-100, -0.00625rem); } ``` ### Type: SignUp ```tsx import './signup-form.css'; import { useState } from 'react'; import { Box, Button, Checkbox, Field, Form, HStack, IconButton, Select, Text, TextInput, VStack, } from '@vapor-ui/core'; import { ChevronRightOutlineIcon } from '@vapor-ui/icons'; const jobs = [ { label: '개발자', value: 'developer' }, { label: '디자이너', value: 'designer' }, { label: '프로덕트 매니저', value: 'product-manager' }, { label: '기타', value: 'etc' }, ]; export default function SignupForm() { const [passwordCheck, setPasswordCheck] = useState(''); // const passwordCheck = useRef(''); return ( event.preventDefault()} />} > } flexDirection="column" className="input-label" > 이메일 이메일을 입력해주세요. 유효한 이메일 형식이 아닙니다. } flexDirection="column" className="input-label" > 비밀번호 setPasswordCheck(value)} required pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[\W_]).{8,16}" /> 8~16자, 대소문자 영문, 숫자, 특수문자 포함 비밀번호를 입력해주세요. 유효한 비밀번호 형식이 아닙니다. } flexDirection="column" className="input-label" > 비밀번호 확인 8~16자, 대소문자 영문, 특수문자 포함 비밀번호를 입력해주세요. 비밀번호를 다시 확인해주세요. } flexDirection="column" className="input-label" > 이름 이름을 입력해주세요. } flexDirection="column" className="input-label" > 직업 {jobs.map((job) => ( {job.label} ))} } alignItems="center" className="checkbox-label" > 필수 약관에 모두 동의 } alignItems="center" className="checkbox-label" > 이용 약관 동의 } alignItems="center" className="checkbox-label" > 개인 정보 수집 이용 동의 이미 계정이 있으세요? ); } ``` ```css .input-label { color: var(--vapor-color-foreground-normal-100, #525463); font-size: var(--vapor-typography-fontSize-050, 0.75rem); font-weight: var(--vapor-typography-fontWeight-500); line-height: var(--vapor-typography-lineHeight-050, 1.125rem); /* 150% */ letter-spacing: var(--vapor-typography-letterSpacing-000, 0); } .checkbox-label { color: var(--vapor-color-foreground-normal-100, #2b2d36); font-size: var(--vapor-typography-fontSize-075, 0.875rem); font-weight: var(--vapor-typography-fontWeight-400); line-height: var(--vapor-typography-lineHeight-075, 1.375rem); /* 157.143% */ letter-spacing: var(--vapor-typography-letterSpacing-100, -0.00625rem); } .helper-text { color: var(--vapor-color-foreground-hint, #6c6e7e); font-size: var(--vapor-typography-fontSize-075, 0.875rem); font-weight: var(--vapor-typography-fontWeight-400); line-height: var(--vapor-typography-lineHeight-075, 1.375rem); /* 157.143% */ letter-spacing: var(--vapor-typography-letterSpacing-100, -0.00625rem); } ``` ### Type: Authentication ```tsx import { Children, cloneElement, isValidElement, useState } from 'react'; import './authentication-form.css'; import { Box, Button, Field, Form, Select, Text, TextInput, VStack } from '@vapor-ui/core'; const codes = { '+82': '🇰🇷 +82', '+1': '🇺🇸 +1', '+34': '🇪🇸 +34', '+33': '🇫🇷 +33', '+39': '🇮🇹 +39', '+44': '🇬🇧 +44', '+81': '🇯🇵 +81', '+86': '🇨🇳 +86', '+7': '🇷🇺 +7', }; export default function AuthenticationForm() { const [phoneNumber, setPhoneNumber] = useState(''); const handleChange = (e: React.ChangeEvent) => { setPhoneNumber(e.target.value); }; const regex = /^[0-9\s-()]{6,20}$/; return ( e.preventDefault()} />} > } flexDirection="column"> 핸드폰 번호 {Object.entries(codes).map(([value, label]) => ( {label} ))} 핸드폰 번호를 입력해주세요. 올바른 핸드폰 번호를 입력해주세요. } flexDirection="column"> 인증번호 인증번호를 입력해주세요. ); } interface GroupProps { attached?: boolean; children?: React.ReactNode; } const Group = ({ attached = false, children: childrenProp }: GroupProps) => { const children = Children.map(childrenProp, (child, index) => { if (!isValidElement(child)) return; return cloneElement(child as React.ReactElement, { style: { '--group-index': index, ...child.props.style }, ...(index === 0 ? { 'data-first-item': '' } : {}), ...(index === Children.count(childrenProp) - 1 ? { 'data-last-item': '' } : {}), }); }); return (
{children}
); }; ``` ```css .input-label { color: var(--vapor-color-foreground-normal-100, #525463); font-size: var(--vapor-typography-fontSize-050, 0.75rem); font-weight: var(--vapor-typography-fontWeight-500); line-height: var(--vapor-typography-lineHeight-050, 1.125rem); /* 150% */ letter-spacing: var(--vapor-typography-letterSpacing-000, 0); } .group { display: flex; align-items: center; gap: 0; &.attached { & > [data-first-item] { border-right: none; border-top-right-radius: 0; border-bottom-right-radius: 0; } & > [data-last-item] { border: 1px solid var(--vapor-color-border-normal, #d1d2d8); border-top-left-radius: 0; border-bottom-left-radius: 0; } & > *:not([data-first-item]):not([data-last-item]) { border: 1px solid var(--vapor-color-border-normal, #d1d2d8); border-right: none; border-radius: 0; } } } ```
### Type: Research ```tsx import './research-form.css'; import { Box, Button, Checkbox, Field, Form, HStack, MultiSelect, Radio, RadioGroup, Select, Switch, Text, TextInput, VStack, } from '@vapor-ui/core'; const jobs = [ { label: '프론트엔드 개발자', value: 'frontend-engineer' }, { label: '백엔드 개발자', value: 'backend-engineer' }, { label: '풀스택 개발자', value: 'fullstack-engineer' }, { label: '모바일 앱 개발자', value: 'app-engineer' }, { label: 'DevOps/클라우드 엔지니어', value: 'devops-engineer' }, ]; const stacks = [ { label: 'HTML/CSS', value: 'html-css' }, { label: 'JavaScript', value: 'javascript' }, { label: 'React', value: 'react' }, { label: 'Vue.js', value: 'vue' }, { label: 'Next.js', value: 'nextjs' }, ]; export default function ResearchForm() { return ( event.preventDefault()} />} > 기본 정보를 입력해주세요. } flexDirection="column"> 이름 이름을 입력해주세요. } flexDirection="column"> 직업 {jobs.map((job) => ( {job.label} ))} } flexDirection="column"> 스택 {stacks.map((stack) => ( {stack.label} ))} 만족도를 선택해주세요. } alignItems="center"> 매우 만족 } alignItems="center"> 보통 } alignItems="center"> 불만족 좋았던 강의는 무엇인가요? 중복 선택 가능 } alignItems="center"> 멘토님 강연 능력 } alignItems="center"> 주제(협업 및 커뮤니케이션 스킬) } alignItems="center"> 전반적인 강의 내용 } alignItems="center"> 세미나 자료 } alignItems="center"> 기타 개인 정보 수신 동의 }> 서비스 메일 수신 동의 }> 이벤트성 광고 수신 동의 ); } ``` ```css .input-label { color: var(--vapor-color-foreground-normal-100, #525463); font-size: var(--vapor-typography-fontSize-050, 0.75rem); font-weight: var(--vapor-typography-fontWeight-500); line-height: var(--vapor-typography-lineHeight-050, 1.125rem); /* 150% */ letter-spacing: var(--vapor-typography-letterSpacing-000, 0); } .checkbox-label { color: var(--vapor-color-foreground-normal-100, #2b2d36); font-size: var(--vapor-typography-fontSize-075, 0.875rem); font-weight: var(--vapor-typography-fontWeight-400); line-height: var(--vapor-typography-lineHeight-075, 1.375rem); /* 157.143% */ letter-spacing: var(--vapor-typography-letterSpacing-100, -0.00625rem); } .radio-label { color: var(--vapor-color-foreground-normal-100, #2b2d36); font-size: var(--vapor-typography-fontSize-075, 0.875rem); font-weight: var(--vapor-typography-fontWeight-400); line-height: var(--vapor-typography-lineHeight-075, 1.375rem); /* 157.143% */ letter-spacing: var(--vapor-typography-letterSpacing-100, -0.00625rem); } ``` ### Type: Filter ```tsx import './filter-form.css'; import type { FormEvent } from 'react'; import { useCallback, useRef, useState } from 'react'; import { Box, Button, Checkbox, Collapsible, Field, Form, HStack, Radio, RadioGroup, Text, VStack, } from '@vapor-ui/core'; import { ChevronDownOutlineIcon, RefreshOutlineIcon } from '@vapor-ui/icons'; // 초기값 정의 type FormData = typeof FORM_SCHEME; const FORM_SCHEME = { view: 'recent', sort: { feedback: false, buttons: false, 'data-display': false, overlay: false, inputs: false, navigation: false, utils: false, }, packs: { 'goorm-dev/vapor-core': false, 'goorm-dev/vapor-component': false, 'vapor-ui/core': false, }, status: { active: false, inactive: false, draft: false }, tag: { ui: false, 'open-source': false, performance: false }, }; export default function FilterForm() { const formRef = useRef(null); const [formData, setFormData] = useState({ view: FORM_SCHEME.view, sort: { ...FORM_SCHEME.sort }, packs: { ...FORM_SCHEME.packs }, status: { ...FORM_SCHEME.status }, tag: { ...FORM_SCHEME.tag }, }); const getFieldValues = useCallback( (fieldName: T): FormData[T] => formData[fieldName], [formData], ); const updateFormData = useCallback( (fieldName: keyof FormData, key: string, checked: boolean) => { setFormData((prev) => { const field = prev[fieldName]; if (typeof field !== 'object') return prev; return { ...prev, [fieldName]: { ...field, [key]: checked } }; }); }, [], ); // 라디오 버튼 변경 핸들러 const handleRadioChange = useCallback((fieldName: keyof FormData, value: string) => { setFormData((prev) => ({ ...prev, [fieldName]: value })); }, []); // 체크박스 변경 핸들러 const handleCheckboxChange = useCallback( (fieldName: keyof FormData, key: string) => (checked: boolean) => { updateFormData(fieldName, key, checked); }, [updateFormData], ); const selectedSortCount = Object.values(getFieldValues('sort')).filter(Boolean).length; const handleReset = (event: FormEvent) => { event.preventDefault(); setFormData({ view: FORM_SCHEME.view, sort: { ...FORM_SCHEME.sort }, packs: { ...FORM_SCHEME.packs }, status: { ...FORM_SCHEME.status }, tag: { ...FORM_SCHEME.tag }, }); }; return ( }> Filter } border="none" marginY="$150" height="1px" width="100%" backgroundColor="$gray-300" /> View }> handleRadioChange('view', value as string) } > } alignItems="center"> Recent } alignItems="center"> Most Popular Sort {selectedSortCount} }> } alignItems="center"> Feedback } alignItems="center"> Buttons } alignItems="center"> Data Display } alignItems="center"> Overlay } alignItems="center"> Inputs } alignItems="center"> Navigation } alignItems="center"> Utils Package }> } alignItems="center"> goorm-dev/vapor-core } alignItems="center"> goorm-dev/vapor-component } alignItems="center"> vapor-ui/core Status }> } alignItems="center"> Active } alignItems="center"> Inactive } alignItems="center"> Draft Tag }> } alignItems="center"> UI } alignItems="center"> Open Source } alignItems="center"> Performance ); } ``` ```css .checkbox-label { color: var(--vapor-color-foreground-normal-100, #2b2d36); font-size: var(--vapor-typography-fontSize-075, 0.875rem); font-weight: var(--vapor-typography-fontWeight-400); line-height: var(--vapor-typography-lineHeight-075, 1.375rem); /* 157.143% */ letter-spacing: var(--vapor-typography-letterSpacing-100, -0.00625rem); } .radio-label { color: var(--vapor-color-foreground-normal-100, #2b2d36); font-size: var(--vapor-typography-fontSize-075, 0.875rem); font-weight: var(--vapor-typography-fontWeight-400); line-height: var(--vapor-typography-lineHeight-075, 1.375rem); /* 157.143% */ letter-spacing: var(--vapor-typography-letterSpacing-100, -0.00625rem); } .collapsible-trigger { width: 100%; display: flex; align-items: center; justify-content: space-between; transition: transform 150ms ease; } .trigger-icon { transition: transform 150ms ease; &:where([data-open] &) { transform: rotate(180deg); } &:where([data-closed] &) { transform: rotate(0); } } ``` ### Type: BottomSheetFilter ```tsx import './sheet-form.css'; import type { FormEvent } from 'react'; import { useCallback, useState } from 'react'; import { Box, Button, Checkbox, Field, Form, Sheet, Tabs, VStack } from '@vapor-ui/core'; import { RefreshOutlineIcon } from '@vapor-ui/icons'; type FormData = typeof FORM_SCHEME; const FORM_SCHEME = { sort: { feedback: false, buttons: true, 'data-display': false, overlay: false, inputs: true, navigation: false, utils: false, }, packs: { 'goorm-dev/vapor-core': true, 'goorm-dev/vapor-component': false, 'vapor-ui/core': false, }, status: { active: true, inactive: false, draft: false, }, tag: { ui: true, 'open-source': false, performance: false, }, }; export default function SheetForm() { const [formData, setFormData] = useState(() => { return { sort: { ...FORM_SCHEME.sort }, packs: { ...FORM_SCHEME.packs }, status: { ...FORM_SCHEME.status }, tag: { ...FORM_SCHEME.tag }, }; }); const getFieldValues = useCallback( (fieldName: T): FormData[T] => formData[fieldName], [formData], ); const updateFormData = useCallback( (fieldName: keyof FormData, key: string, checked: boolean) => { setFormData((prev) => { const field = prev[fieldName]; if (typeof field !== 'object') return prev; return { ...prev, [fieldName]: { ...field, [key]: checked } }; }); }, [], ); const handleCheckboxChange = useCallback( (fieldName: keyof FormData, key: string) => (checked: boolean) => { updateFormData(fieldName, key, checked); }, [updateFormData], ); const handleReset = useCallback((event: FormEvent) => { event.preventDefault(); setFormData({ sort: { ...FORM_SCHEME.sort }, packs: { ...FORM_SCHEME.packs }, status: { ...FORM_SCHEME.status }, tag: { ...FORM_SCHEME.tag }, }); }, []); return ( } > }>Open Filter } className={'popup'} > Filter Sort Package Status Tag {/* Sort */} } alignItems="center"> Feedback } alignItems="center"> Buttons } alignItems="center"> Data Display } alignItems="center"> Overlay } alignItems="center"> Inputs } alignItems="center"> Navigation } alignItems="center"> Utils {/* Package */} } alignItems="center"> goorm-dev/vapor-core } alignItems="center"> goorm-dev/vapor-component } alignItems="center"> vapor-ui/core {/* Status */} } alignItems="center"> Active } alignItems="center"> Inactive } alignItems="center"> Draft {/* Tag */} } alignItems="center"> UI } alignItems="center"> Open Source } alignItems="center"> Performance }> Apply ); } ``` ```css .checkbox-label { color: var(--vapor-color-foreground-normal-100, #2b2d36); font-size: var(--vapor-typography-fontSize-075, 0.875rem); font-weight: var(--vapor-typography-fontWeight-400); line-height: var(--vapor-typography-lineHeight-075, 1.375rem); /* 157.143% */ letter-spacing: var(--vapor-typography-letterSpacing-100, -0.00625rem); } .popup { border-top-left-radius: var(--vapor-size-borderRadius-300); border-top-right-radius: var(--vapor-size-borderRadius-300); } .tabs { height: 100%; } .tabs-list { padding-inline: 0; } .tabs-panel { padding-block: var(--vapor-size-space-200); } .header { padding: var(--vapor-size-space-250) var(--vapor-size-space-200) 0; } .body { padding-inline: var(--vapor-size-space-200); } .footer { gap: var(--vapor-size-space-100); padding-top: var(--vapor-size-space-100); } .refresh-button { flex-shrink: 0; } .apply-button { flex-shrink: 0; flex-grow: 1; } ``` --- version: 1.0.0-beta.6 --- # Navbar URL: /blocks/nav-bar Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/blocks/nav-bar.mdx 사용자의 액션에 대한 피드백 혹은 서비스에 대한 메시지를 제공할 때 사용할 수 있습니다. 상황에 따라 컬러와 좌측 아이콘, 닫기 버튼을 적절히 사용합니다. *** title: Navbar description: 사용자의 액션에 대한 피드백 혹은 서비스에 대한 메시지를 제공할 때 사용할 수 있습니다. 상황에 따라 컬러와 좌측 아이콘, 닫기 버튼을 적절히 사용합니다. previewImageUrl: /images/nav-bar-preview\.svg --------------------------------------------- ### Left Aligned Navbar ```tsx import './block.css'; import type { ComponentProps } from 'react'; import { Avatar, Collapsible, HStack, IconButton, NavigationMenu, Sheet } from '@vapor-ui/core'; import { BellOnIcon, ChevronDownOutlineIcon, CloseOutlineIcon, MenuOutlineIcon, } from '@vapor-ui/icons'; export default function Block1() { return ( Features Pricing Templates }> } > }> }> } > } > Features Container SBOM Pricing Templates ); } const LogoSvg = (props: ComponentProps<'svg'>) => { return ( ); }; ``` ```css .navbar-desktop { display: inherit; @media (max-width: 767px) { display: none; } } .navbar-mobile { display: none; @media (max-width: 767px) { display: inherit; } } .logo { flex-shrink: 0; } .vertical-navigation-menu { width: 100%; } .collapsible-trigger { width: 100%; justify-content: space-between; } .link-item { justify-content: flex-start; } .nested-link-item { justify-content: flex-start; padding-left: var(--vapor-size-space-250); } ``` ### Center Aligned Navbar ```tsx import './block.css'; import type { ComponentProps } from 'react'; import { Avatar, Collapsible, HStack, IconButton, NavigationMenu, Sheet } from '@vapor-ui/core'; import { BellOnIcon, ChevronDownOutlineIcon, CloseOutlineIcon, MenuOutlineIcon, } from '@vapor-ui/icons'; export default function Block2() { return ( Features Pricing Templates }> } > }> }> } > } > Features Container SBOM Pricing Templates ); } const LogoSvg = (props: ComponentProps<'svg'>) => { return ( ); }; ``` ```css .navbar-desktop { display: inherit; @media (max-width: 767px) { display: none; } } .navbar-mobile { display: none; @media (max-width: 767px) { display: inherit; } } .logo { flex-shrink: 0; } .vertical-navigation-menu { width: 100%; } .collapsible-trigger { width: 100%; justify-content: space-between; } .link-item { justify-content: flex-start; } .nested-link-item { justify-content: flex-start; padding-left: var(--vapor-size-space-250); } ``` ### Right Aligned Navbar ```tsx import './block.css'; import type { ComponentProps } from 'react'; import { Avatar, Collapsible, HStack, IconButton, NavigationMenu, Sheet } from '@vapor-ui/core'; import { BellOnIcon, ChevronDownOutlineIcon, CloseOutlineIcon, MenuOutlineIcon, } from '@vapor-ui/icons'; export default function Block3() { return ( Features Pricing Templates }> } > } > }> } > } > Features Container SBOM Pricing Templates ); } const LogoSvg = (props: ComponentProps<'svg'>) => { return ( ); }; ``` ```css .navbar-desktop { display: inherit; @media (max-width: 767px) { display: none; } } .navbar-mobile { display: none; @media (max-width: 767px) { display: inherit; } } .logo { flex-shrink: 0; } .vertical-navigation-menu { width: 100%; } .collapsible-trigger { width: 100%; justify-content: space-between; } .link-item { justify-content: flex-start; } .nested-link-item { justify-content: flex-start; padding-left: var(--vapor-size-space-250); } ``` ### Navbar with Login Button ```tsx import './block.css'; import type { ComponentProps } from 'react'; import { Button, Collapsible, HStack, IconButton, NavigationMenu, Sheet } from '@vapor-ui/core'; import { ChevronDownOutlineIcon, CloseOutlineIcon, MenuOutlineIcon } from '@vapor-ui/icons'; export default function Block4() { return ( Features Pricing Templates } > }> } > } > Features Container SBOM Pricing Templates ); } const LogoSvg = (props: ComponentProps<'svg'>) => { return ( ); }; ``` ```css .navbar-desktop { display: inherit; @media (max-width: 767px) { display: none; } } .navbar-mobile { display: none; @media (max-width: 767px) { display: inherit; } } .logo { flex-shrink: 0; } .vertical-navigation-menu { width: 100%; } .collapsible-trigger { width: 100%; justify-content: space-between; } .link-item { justify-content: flex-start; } .nested-link-item { justify-content: flex-start; padding-left: var(--vapor-size-space-250); } ``` ### Logo Centered Navbar ```tsx import './logo.css'; import type { ComponentProps } from 'react'; import { Button, HStack } from '@vapor-ui/core'; export default function Block5() { return ( ); } const LogoSvg = (props: ComponentProps<'svg'>) => { return ( ); }; ``` ```css .logo { flex-shrink: 0; } ``` ### Page Navigation Navbar ```tsx import './logo.css'; import type { ComponentProps } from 'react'; import { HStack, IconButton } from '@vapor-ui/core'; import { BackPageOutlineIcon, ForwardPageOutlineIcon } from '@vapor-ui/icons'; export default function Block6() { return ( ); } const LogoSvg = (props: ComponentProps<'svg'>) => { return ( ); }; ``` ```css .logo { flex-shrink: 0; } ``` --- version: 1.0.0-beta.6 --- # Table URL: /blocks/table Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/blocks/table.mdx 데이터의 구조화된 표현을 제공하는 데 사용됩니다. *** title: Table description: 데이터의 구조화된 표현을 제공하는 데 사용됩니다. previewImageUrl: /images/table-preview\.svg ------------------------------------------- 이 문서는 대량의 데이터를 다루는 Data Table의 구현 예시를 안내합니다. Data Table은 데이터를 효율적으로 시각화하고 관리하는 강력한 도구이지만, 내부적으로 복잡한 상태 관리와 로직을 필요로 합니다. 이러한 기능을 컴포넌트 내부에 강결합하면 유지보수가 어렵고 확장성이 떨어지는 문제가 발생할 수 있습니다. 이에 따라 Vapor UI의 Table 컴포넌트는 순수한 뷰(View) 역할에 집중하여 기본적인 구조와 스타일을 제공합니다. 이 문서에서는 `@tanstack/react-table`과 같은 Headless UI 라이브러리를 활용하여 다양한 기능을 유연하게 구현하는 방법을 예시로 제공합니다. ### Basic ```tsx import { Badge, Card, Table } from '@vapor-ui/core'; const datas = [ { name: 'Olivia Park', status: 'active', role: 'designer', 'last-active': '2 hours ago' }, { name: 'Ethan Kim', status: 'active', role: 'developer', 'last-active': '3 days ago' }, { name: 'Mia Choi', status: 'inactive', role: 'developer', 'last-active': '10 minutes ago' }, { name: 'Noah Lee', status: 'active', role: 'designer', 'last-active': '1 day ago' }, { name: 'Ava Jung', status: 'active', role: 'developer', 'last-active': '5 days ago' }, { name: 'Liam Han', status: 'inactive', role: 'developer', 'last-active': '5 days ago' }, { name: 'Emma Seo', status: 'active', role: 'designer', 'last-active': '7 days ago' }, { name: 'Mason Yoo', status: 'active', role: 'designer', 'last-active': '30 minutes ago' }, { name: 'Sophia Lim', status: 'inactive', role: 'designer', 'last-active': '4 hours ago' }, { name: 'Lucas Park', status: 'active', role: 'developer', 'last-active': '1 hour ago' }, ]; const activeness: Record = { active: 'success', inactive: 'hint', }; export default function Basic() { return ( Name Status Role Last Active {datas.map((data, index) => ( {data.name} {data.status.toUpperCase()} {data.role} {data['last-active']} ))} ); } ``` ### Checkbox ```tsx import { useMemo, useState } from 'react'; import { type ColumnDef, flexRender, getCoreRowModel, useReactTable } from '@tanstack/react-table'; import { Badge, Card, Checkbox, Table } from '@vapor-ui/core'; export default function Basic() { const [rowSelection, setRowSelection] = useState({}); const columns = useMemo[]>( () => [ { id: 'select', header: ({ table }) => ( table.toggleAllRowsSelected(value)} style={{ justifySelf: 'center' }} /> ), cell: ({ row }) => ( row.toggleSelected(value)} style={{ justifySelf: 'center' }} /> ), }, { header: 'Name', accessorKey: 'name', }, { header: 'Status', accessorKey: 'status', cell: ({ getValue }) => { const status = getValue(); return ( {status.toUpperCase()} ); }, }, { header: 'Role', accessorKey: 'role', }, { header: 'Last Active', accessorKey: 'last-active', }, ], [], ); const table = useReactTable({ data: datas, columns, state: { rowSelection }, enableRowSelection: true, onRowSelectionChange: setRowSelection, getCoreRowModel: getCoreRowModel(), }); return ( {table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( {flexRender( header.column.columnDef.header, header.getContext(), )} ))} ))} {table.getRowModel().rows.map((row) => { return ( {row.getVisibleCells().map((cell) => { return ( {flexRender( cell.column.columnDef.cell, cell.getContext(), )} ); })} ); })} ); } type Data = { name: string; status: 'active' | 'inactive'; role: string; 'last-active': string; }; const datas: Data[] = [ { name: 'Olivia Park', status: 'active', role: 'designer', 'last-active': '2 hours ago' }, { name: 'Ethan Kim', status: 'active', role: 'developer', 'last-active': '3 days ago' }, { name: 'Mia Choi', status: 'inactive', role: 'developer', 'last-active': '10 minutes ago' }, { name: 'Noah Lee', status: 'active', role: 'designer', 'last-active': '1 day ago' }, { name: 'Ava Jung', status: 'active', role: 'developer', 'last-active': '5 days ago' }, { name: 'Liam Han', status: 'inactive', role: 'developer', 'last-active': '5 days ago' }, { name: 'Emma Seo', status: 'active', role: 'designer', 'last-active': '7 days ago' }, { name: 'Mason Yoo', status: 'active', role: 'designer', 'last-active': '30 minutes ago' }, { name: 'Sophia Lim', status: 'inactive', role: 'designer', 'last-active': '4 hours ago' }, { name: 'Lucas Park', status: 'active', role: 'developer', 'last-active': '1 hour ago' }, ]; const activeness: Record = { active: 'success', inactive: 'hint', }; ``` ### Ordering ```tsx import { useMemo, useState } from 'react'; import { type ColumnDef, flexRender, getCoreRowModel, useReactTable } from '@tanstack/react-table'; import { Badge, Box, Card, Table } from '@vapor-ui/core'; export default function Ordering() { const [rowSelection, setRowSelection] = useState({}); const columns = useMemo[]>( () => [ { id: 'select', header: () => ID, cell: ({ row }) => {row.index + 1}, }, { header: 'Name', accessorKey: 'name', }, { header: 'Status', accessorKey: 'status', cell: ({ getValue }) => { const status = getValue(); return ( {status.toUpperCase()} ); }, }, { header: 'Role', accessorKey: 'role', }, { header: 'Last Active', accessorKey: 'last-active', }, ], [], ); const table = useReactTable({ data: datas, columns, state: { rowSelection }, enableRowSelection: true, onRowSelectionChange: setRowSelection, getCoreRowModel: getCoreRowModel(), }); return ( {table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( {flexRender( header.column.columnDef.header, header.getContext(), )} ))} ))} {table.getRowModel().rows.map((row) => { return ( {row.getVisibleCells().map((cell) => ( {flexRender( cell.column.columnDef.cell, cell.getContext(), )} ))} ); })} ); } type Data = { name: string; status: 'active' | 'inactive'; role: string; 'last-active': string; }; const datas: Data[] = [ { name: 'Olivia Park', status: 'active', role: 'designer', 'last-active': '2 hours ago' }, { name: 'Ethan Kim', status: 'active', role: 'developer', 'last-active': '3 days ago' }, { name: 'Mia Choi', status: 'inactive', role: 'developer', 'last-active': '10 minutes ago' }, { name: 'Noah Lee', status: 'active', role: 'designer', 'last-active': '1 day ago' }, { name: 'Ava Jung', status: 'active', role: 'developer', 'last-active': '5 days ago' }, { name: 'Liam Han', status: 'inactive', role: 'developer', 'last-active': '5 days ago' }, { name: 'Emma Seo', status: 'active', role: 'designer', 'last-active': '7 days ago' }, { name: 'Mason Yoo', status: 'active', role: 'designer', 'last-active': '30 minutes ago' }, { name: 'Sophia Lim', status: 'inactive', role: 'designer', 'last-active': '4 hours ago' }, { name: 'Lucas Park', status: 'active', role: 'developer', 'last-active': '1 hour ago' }, ]; const activeness: Record = { active: 'success', inactive: 'hint', }; ``` ### Sticky ```tsx import type { CSSProperties } from 'react'; import { useMemo, useState } from 'react'; import type { Column, Table as TanstackTable } from '@tanstack/react-table'; import { type ColumnDef, flexRender, getCoreRowModel, useReactTable } from '@tanstack/react-table'; import { Badge, Box, Card, Table } from '@vapor-ui/core'; export default function Basic() { const [rowSelection, setRowSelection] = useState({}); const columns = useMemo[]>( () => [ { header: () => ID, accessorKey: 'id', cell: ({ row }) => {row.index + 1}, }, { header: 'Name', accessorKey: 'name', cell: ({ row }) => {row.getValue('name')}, }, { header: 'Status', accessorKey: 'status', cell: ({ row }) => { const status = row.getValue('status'); return ( {status.toUpperCase()} ); }, }, { header: 'Role', accessorKey: 'role', }, { header: 'Last Active', accessorKey: 'last-active', }, ], [], ); const table = useReactTable({ data: datas, columns, state: { rowSelection, columnPinning: { left: ['id', 'name'] } }, enableRowSelection: true, onRowSelectionChange: setRowSelection, getCoreRowModel: getCoreRowModel(), }); return ( {table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( columnSizingHandler(thElem, table, header.column) } backgroundColor="$white" style={{ ...getCommonPinningStyles(header.column) }} > {flexRender( header.column.columnDef.header, header.getContext(), )} ))} ))} {table.getRowModel().rows.map((row) => { return ( {row.getVisibleCells().map((cell) => ( {flexRender( cell.column.columnDef.cell, cell.getContext(), )} ))} ); })} ); } type Data = { name: string; status: 'active' | 'inactive'; role: string; 'last-active': string; }; const datas: Data[] = [ { name: 'Olivia Park', status: 'active', role: 'designer', 'last-active': '2 hours ago' }, { name: 'Ethan Kim', status: 'active', role: 'developer', 'last-active': '3 days ago' }, { name: 'Mia Choi', status: 'inactive', role: 'developer', 'last-active': '10 minutes ago' }, { name: 'Noah Lee', status: 'active', role: 'designer', 'last-active': '1 day ago' }, { name: 'Ava Jung', status: 'active', role: 'developer', 'last-active': '5 days ago' }, { name: 'Liam Han', status: 'inactive', role: 'developer', 'last-active': '5 days ago' }, { name: 'Emma Seo', status: 'active', role: 'designer', 'last-active': '7 days ago' }, { name: 'Mason Yoo', status: 'active', role: 'designer', 'last-active': '30 minutes ago' }, { name: 'Sophia Lim', status: 'inactive', role: 'designer', 'last-active': '4 hours ago' }, { name: 'Lucas Park', status: 'active', role: 'developer', 'last-active': '1 hour ago' }, ]; const getCommonPinningStyles = (column: Column): CSSProperties => { const isPinned = column.getIsPinned(); const lastPinnedColumn = isPinned === 'left' && column.getIsLastColumn('left'); return { boxShadow: lastPinnedColumn ? '-3px 0 0 0 rgba(0, 0, 0, 0.06) inset' : undefined, left: isPinned === 'left' ? `${column.getStart('left')}px` : undefined, position: isPinned ? 'sticky' : 'unset', zIndex: isPinned ? 1 : undefined, }; }; const activeness: Record = { active: 'success', inactive: 'hint', }; const columnSizingHandler = ( thElem: HTMLTableCellElement | null, table: TanstackTable, column: Column, ) => { if (!thElem) return; if (table.getState().columnSizing[column.id] !== undefined) return; if (table.getState().columnSizing[column.id] === thElem.getBoundingClientRect().width) return; table.setColumnSizing((prevSizes) => ({ ...prevSizes, [column.id]: thElem.getBoundingClientRect().width, })); }; ``` ### Collapsed ```tsx import type { CSSProperties } from 'react'; import { useMemo, useState } from 'react'; import { makeStateUpdater } from '@tanstack/react-table'; import type { Column, ColumnDef, OnChangeFn, RowData, TableFeature, Table as TanstackTable, Updater, } from '@tanstack/react-table'; import { flexRender, getCoreRowModel, useReactTable } from '@tanstack/react-table'; import { Badge, Box, Card, HStack, IconButton, Table } from '@vapor-ui/core'; import { ChevronDoubleLeftOutlineIcon, ChevronDoubleRightOutlineIcon } from '@vapor-ui/icons'; export default function Collapsed() { const columns = useMemo[]>( () => [ { header: () => ID, accessorKey: 'id', cell: ({ row }) => {row.index + 1}, }, { header: ({ column }) => { const isCollapsed = column.getIsCollapsed(); const IconElement = isCollapsed ? ChevronDoubleRightOutlineIcon : ChevronDoubleLeftOutlineIcon; return ( {isCollapsed ? '' : 'Name'} column.toggleCollapsed()} > ); }, accessorKey: 'name', cell: ({ row, column }) => { const isCollapsed = column.getIsCollapsed(); return ( {row.getValue('name')} ); }, }, { header: 'Status', accessorKey: 'status', cell: ({ row }) => { const status = row.getValue('status'); return ( {status.toUpperCase()} ); }, }, { header: () => Role, accessorKey: 'role', }, { header: () => Last Active, accessorKey: 'last-active', }, ], [], ); const [columnCollapsed, setColumnCollapsed] = useState(['name']); // 초기에 접힐 컬럼들 const table = useReactTable({ _features: [ColumnCollapsedFeature], data: datas, columns, state: { columnPinning: { left: ['id', 'name'] }, columnCollapsed, }, enableRowSelection: true, getCoreRowModel: getCoreRowModel(), onColumnCollapsedChange: setColumnCollapsed, }); return ( {table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( columnSizingHandler(thElem, table, header.column) } backgroundColor="$gray-050" style={{ ...getCommonPinningStyles(header.column) }} > {flexRender( header.column.columnDef.header, header.getContext(), )} ))} ))} {table.getRowModel().rows.map((row) => { return ( {row.getVisibleCells().map((cell) => ( {flexRender( cell.column.columnDef.cell, cell.getContext(), )} ))} ); })} ); } /* -----------------------------------------------------------------------------------------------*/ type Data = { name: string; status: 'active' | 'inactive'; role: string; 'last-active': string; }; const datas: Data[] = [ { name: 'Olivia Park', status: 'active', role: 'designer', 'last-active': '2 hours ago' }, { name: 'Ethan Kim', status: 'active', role: 'developer', 'last-active': '3 days ago' }, { name: 'Mia Choi', status: 'inactive', role: 'developer', 'last-active': '10 minutes ago' }, { name: 'Noah Lee', status: 'active', role: 'designer', 'last-active': '1 day ago' }, { name: 'Ava Jung', status: 'active', role: 'developer', 'last-active': '5 days ago' }, { name: 'Liam Han', status: 'inactive', role: 'developer', 'last-active': '5 days ago' }, { name: 'Emma Seo', status: 'active', role: 'designer', 'last-active': '7 days ago' }, { name: 'Mason Yoo', status: 'active', role: 'designer', 'last-active': '30 minutes ago' }, { name: 'Sophia Lim', status: 'inactive', role: 'designer', 'last-active': '4 hours ago' }, { name: 'Lucas Park', status: 'active', role: 'developer', 'last-active': '1 hour ago' }, ]; const getCommonPinningStyles = (column: Column): CSSProperties => { const isPinned = column.getIsPinned(); const lastPinnedColumn = isPinned === 'left' && column.getIsLastColumn('left'); return { boxShadow: lastPinnedColumn ? '-3px 0 0 0 rgba(0, 0, 0, 0.06) inset' : undefined, left: isPinned === 'left' ? `${column.getStart('left')}px` : undefined, position: isPinned ? 'sticky' : 'unset', zIndex: isPinned ? 1 : undefined, }; }; const activeness: Record = { active: 'success', inactive: 'hint', }; const columnSizingHandler = ( thElem: HTMLTableCellElement | null, table: TanstackTable, column: Column, ) => { if (!thElem) return; const currentSize = table.getState().columnSizing[column.id]; const elementWidth = thElem.getBoundingClientRect().width; if (currentSize === elementWidth) return; table.setColumnSizing((prevSizes) => ({ ...prevSizes, [column.id]: elementWidth, })); }; /* -----------------------------------------------------------------------------------------------*/ export type ColumnCollapsedState = string[]; export interface ColumnCollapsedTableState { columnCollapsed: ColumnCollapsedState; } export interface ColumnCollapsedOptions { enableColumnCollapsed?: boolean; onColumnCollapsedChange?: OnChangeFn; } export interface ColumnCollapsedColumnInstance { getIsCollapsed: () => boolean; toggleCollapsed: () => void; } declare module '@tanstack/react-table' { interface TableState extends ColumnCollapsedTableState {} // eslint-disable-next-line @typescript-eslint/no-unused-vars interface TableOptionsResolved extends ColumnCollapsedOptions {} // eslint-disable-next-line @typescript-eslint/no-unused-vars interface Column extends ColumnCollapsedColumnInstance {} } export const ColumnCollapsedFeature: TableFeature = { getInitialState: (state): ColumnCollapsedTableState => { return { columnCollapsed: [], ...state, }; }, getDefaultOptions: ( table: TanstackTable, ): ColumnCollapsedOptions => { return { enableColumnCollapsed: true, onColumnCollapsedChange: makeStateUpdater('columnCollapsed', table), }; }, createColumn: ( column: Column, table: TanstackTable, ): void => { column.getIsCollapsed = () => { return table.getState().columnCollapsed?.includes(column.id) ?? false; }; column.toggleCollapsed = () => { const currentState = column.getIsCollapsed(); const updater: Updater = (old) => { if (currentState) return old.filter((id) => id !== column.id); return [...old, column.id]; }; table.options.onColumnCollapsedChange?.(updater); }; }, }; ``` ### Sort ```tsx import { useMemo, useState } from 'react'; import type { SortingState } from '@tanstack/react-table'; import { type ColumnDef, flexRender, getCoreRowModel, getSortedRowModel, useReactTable, } from '@tanstack/react-table'; import { Badge, Box, Card, HStack, IconButton, Table } from '@vapor-ui/core'; import { ControlCommonIcon } from '@vapor-ui/icons'; export default function Sort() { const columns = useMemo[]>( () => [ { id: 'index', header: 'ID', accessorFn: (_, index) => index + 1, cell: ({ getValue }) => {String(getValue() ?? '.')}, }, { header: 'Name', accessorKey: 'name', cell: (info) => info.getValue(), }, { accessorKey: 'status', cell: ({ getValue }) => { const status = getValue(); return ( {status.toUpperCase()} ); }, }, { accessorKey: 'role', cell: (info) => info.getValue(), }, { accessorKey: 'last-active', cell: (info) => info.getValue(), sortingFn: 'datetime', }, ], [], ); const [sorting, setSorting] = useState([]); const table = useReactTable({ data: datas, columns, state: { sorting }, enableRowSelection: true, getCoreRowModel: getCoreRowModel(), getSortedRowModel: getSortedRowModel(), onSortingChange: setSorting, }); return ( {table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( {flexRender( header.column.columnDef.header, header.getContext(), )} ))} ))} {table.getRowModel().rows.map((row) => { return ( {row.getVisibleCells().map((cell) => { return ( {flexRender( cell.column.columnDef.cell, cell.getContext(), )} ); })} ); })} ); } type Data = { name: string; status: 'active' | 'inactive'; role: string; 'last-active': string; }; const datas: Data[] = [ { name: 'Olivia Park', status: 'active', role: 'designer', 'last-active': '2 hours ago' }, { name: 'Ethan Kim', status: 'active', role: 'developer', 'last-active': '3 days ago' }, { name: 'Mia Choi', status: 'inactive', role: 'developer', 'last-active': '10 minutes ago' }, { name: 'Noah Lee', status: 'active', role: 'designer', 'last-active': '1 day ago' }, { name: 'Ava Jung', status: 'active', role: 'developer', 'last-active': '5 days ago' }, { name: 'Liam Han', status: 'inactive', role: 'developer', 'last-active': '5 days ago' }, { name: 'Emma Seo', status: 'active', role: 'designer', 'last-active': '7 days ago' }, { name: 'Mason Yoo', status: 'active', role: 'designer', 'last-active': '30 minutes ago' }, { name: 'Sophia Lim', status: 'inactive', role: 'designer', 'last-active': '4 hours ago' }, { name: 'Lucas Park', status: 'active', role: 'developer', 'last-active': '1 hour ago' }, ]; const activeness: Record = { active: 'success', inactive: 'hint', }; ``` ### Scroll ```tsx import { useMemo, useState } from 'react'; import { type ColumnDef, flexRender, getCoreRowModel, useReactTable } from '@tanstack/react-table'; import { Badge, Box, Card, Table } from '@vapor-ui/core'; export default function Scroll() { const [rowSelection, setRowSelection] = useState({}); const columns = useMemo[]>( () => [ { accessorKey: 'id', header: () => ID, cell: ({ row }) => {row.index + 1}, }, { header: 'Name', accessorKey: 'name', cell: ({ row }) => {row.getValue('name')}, }, { header: 'Status', accessorKey: 'status', cell: ({ row }) => { const status = row.getValue('status'); return ( {status.toUpperCase()} ); }, }, { header: () => 'Role', accessorKey: 'role', }, { header: () => 'Last Active', accessorKey: 'last-active', }, ], [], ); const table = useReactTable({ data: datas, columns, state: { rowSelection, columnPinning: { left: ['id', 'name'] } }, enableRowSelection: true, onRowSelectionChange: setRowSelection, getCoreRowModel: getCoreRowModel(), }); return ( {table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( {flexRender( header.column.columnDef.header, header.getContext(), )} ))} ))} {table.getRowModel().rows.map((row) => { return ( {row.getVisibleCells().map((cell) => ( {flexRender( cell.column.columnDef.cell, cell.getContext(), )} ))} ); })} ); } type Data = { name: string; status: 'active' | 'inactive'; role: string; 'last-active': string; }; const datas: Data[] = [ { name: 'Olivia Park', status: 'active', role: 'designer', 'last-active': '2 hours ago' }, { name: 'Ethan Kim', status: 'active', role: 'developer', 'last-active': '3 days ago' }, { name: 'Mia Choi', status: 'inactive', role: 'developer', 'last-active': '10 minutes ago' }, { name: 'Noah Lee', status: 'active', role: 'designer', 'last-active': '1 day ago' }, { name: 'Ava Jung', status: 'active', role: 'developer', 'last-active': '5 days ago' }, { name: 'Liam Han', status: 'inactive', role: 'developer', 'last-active': '5 days ago' }, { name: 'Emma Seo', status: 'active', role: 'designer', 'last-active': '7 days ago' }, { name: 'Mason Yoo', status: 'active', role: 'designer', 'last-active': '30 minutes ago' }, { name: 'Sophia Lim', status: 'inactive', role: 'designer', 'last-active': '4 hours ago' }, { name: 'Lucas Park', status: 'active', role: 'developer', 'last-active': '1 hour ago' }, ]; const activeness: Record = { active: 'success', inactive: 'hint', }; ``` ### Filter ```tsx import { useMemo, useState } from 'react'; import type { ColumnFiltersState, Row } from '@tanstack/react-table'; import { type ColumnDef, flexRender, getCoreRowModel, getFilteredRowModel, getPaginationRowModel, useReactTable, } from '@tanstack/react-table'; import { Badge, Box, Button, Card, HStack, MultiSelect, Select, Table, Text, TextInput, } from '@vapor-ui/core'; import { PlusOutlineIcon, SearchOutlineIcon } from '@vapor-ui/icons'; // eslint-disable-next-line @typescript-eslint/no-explicit-any const customFilterFn = (row: Row, columnId: string, filterValue: any) => { if (!filterValue || filterValue.length === 0) return true; const cellValue = row.getValue(columnId) as string; return filterValue.includes(cellValue); }; export default function Scroll() { const columns = useMemo[]>( () => [ { header: () => ID, accessorKey: 'id', size: 0, // prevent cumulative layout shift cell: ({ row }) => {row.index + 1}, }, { header: 'Name', accessorKey: 'name', size: 0, // prevent cumulative layout shift cell: ({ row }) =>
{row.getValue('name')}
, }, { header: 'Status', accessorKey: 'status', cell: ({ row }) => { const status = row.getValue('status'); return ( {status.toUpperCase()} ); }, filterFn: customFilterFn, }, { header: 'Role', accessorKey: 'role', filterFn: customFilterFn, }, { header: 'Last Active', accessorKey: 'last-active', }, ], [], ); const [columnFilters, setColumnFilters] = useState([]); const table = useReactTable({ data: datas, columns, state: { columnFilters }, enableRowSelection: true, getCoreRowModel: getCoreRowModel(), getFilteredRowModel: getFilteredRowModel(), getPaginationRowModel: getPaginationRowModel(), onColumnFiltersChange: setColumnFilters, }); return ( 출석부 table.getColumn('name')?.setFilterValue(value) } /> { table.getColumn('status')?.setFilterValue(value); }} content={ <> Active Inactive } /> table.getColumn('role')?.setFilterValue(value) } content={ <> Designer Developer } /> col.getIsVisible()) .map((col) => col.id)} content={table .getAllColumns() .filter((column) => column.getCanHide()) .map((column) => ( column.toggleVisibility()} > {column.id} ))} /> {table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( {flexRender( header.column.columnDef.header, header.getContext(), )} ))} ))} {table.getRowModel().rows.length ? ( table.getRowModel().rows.map((row) => { return ( {row.getVisibleCells().map((cell) => ( {flexRender( cell.column.columnDef.cell, cell.getContext(), )} ))} ); }) ) : ( 검색 결과가 없습니다. )} table.setPageSize(Number(value))} > {(value) => `${value}개씩 보기`} {[5, 10, 20, 30, 40, 50].map((pageSize) => ( {pageSize} ))} ); } type Data = { name: string; status: 'active' | 'inactive'; role: string; 'last-active': string; }; const datas: Data[] = [ { name: 'Olivia Park', status: 'active', role: 'designer', 'last-active': '2 hours ago' }, { name: 'Ethan Kim', status: 'active', role: 'developer', 'last-active': '3 days ago' }, { name: 'Mia Choi', status: 'inactive', role: 'developer', 'last-active': '10 minutes ago' }, { name: 'Noah Lee', status: 'active', role: 'designer', 'last-active': '1 day ago' }, { name: 'Ava Jung', status: 'active', role: 'developer', 'last-active': '5 days ago' }, { name: 'Liam Han', status: 'inactive', role: 'developer', 'last-active': '5 days ago' }, { name: 'Emma Seo', status: 'active', role: 'designer', 'last-active': '7 days ago' }, { name: 'Mason Yoo', status: 'active', role: 'designer', 'last-active': '30 minutes ago' }, { name: 'Sophia Lim', status: 'inactive', role: 'designer', 'last-active': '4 hours ago' }, { name: 'Lucas Park', status: 'active', role: 'developer', 'last-active': '1 hour ago' }, ]; const activeness: Record = { active: 'success', inactive: 'hint', }; /* -----------------------------------------------------------------------------------------------*/ interface FilterSelectProps extends React.ComponentProps { triggerLabel: string; content: React.ReactNode; } const FilterSelect = ({ content, triggerLabel, ...props }: FilterSelectProps) => { return ( } style={{ width: 'unset' }} > {triggerLabel} }> {content} ); }; ```
### Pagination ```tsx import { useMemo, useState } from 'react'; import type { ColumnFiltersState, Row } from '@tanstack/react-table'; import { type ColumnDef, flexRender, getCoreRowModel, getFilteredRowModel, getPaginationRowModel, useReactTable, } from '@tanstack/react-table'; import { Badge, Button, Card, HStack, MultiSelect, Pagination, Select, Table, Text, TextInput, } from '@vapor-ui/core'; import { PlusOutlineIcon, SearchOutlineIcon } from '@vapor-ui/icons'; // eslint-disable-next-line @typescript-eslint/no-explicit-any const customFilterFn = (row: Row, columnId: string, filterValue: any) => { if (!filterValue || filterValue.length === 0) return true; const cellValue = row.getValue(columnId) as string; return filterValue.includes(cellValue); }; export default function WithPagination() { const columns = useMemo[]>( () => [ { header: () =>
ID
, accessorKey: 'id', size: 0, // prevent cumulative layout shift cell: ({ row }) =>
{row.index + 1}
, }, { header: 'Name', accessorKey: 'name', size: 0, // prevent cumulative layout shift cell: ({ row }) =>
{row.getValue('name')}
, }, { header: 'Status', accessorKey: 'status', cell: ({ row }) => { const status = row.getValue('status'); return ( {status.toUpperCase()} ); }, filterFn: customFilterFn, }, { header: 'Role', accessorKey: 'role', filterFn: customFilterFn, }, { header: 'Last Active', accessorKey: 'last-active', }, ], [], ); const [columnFilters, setColumnFilters] = useState([]); const table = useReactTable({ data: datas, columns, state: { columnFilters }, enableRowSelection: true, getCoreRowModel: getCoreRowModel(), getFilteredRowModel: getFilteredRowModel(), getPaginationRowModel: getPaginationRowModel(), onColumnFiltersChange: setColumnFilters, }); return ( 출석부 table.getColumn('name')?.setFilterValue(value) } /> { table.getColumn('status')?.setFilterValue(value); }} content={ <> Active Inactive } /> table.getColumn('role')?.setFilterValue(value) } content={ <> Designer Developer } /> col.getIsVisible()) .map((col) => col.id)} content={table .getAllColumns() .filter((column) => column.getCanHide()) .map((column) => ( column.toggleVisibility()} > {column.id} ))} /> {table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( {flexRender( header.column.columnDef.header, header.getContext(), )} ))} ))} {table.getRowModel().rows.length ? ( table.getRowModel().rows.map((row) => { return ( {row.getVisibleCells().map((cell) => ( {flexRender( cell.column.columnDef.cell, cell.getContext(), )} ))} ); }) ) : ( 검색 결과가 없습니다. )} table.setPageIndex(page - 1)} > table.setPageSize(Number(value))} > {(value) => `${value}개씩 보기`} {[5, 10, 20, 30, 40, 50].map((pageSize) => ( {pageSize} ))} ); } type Data = { name: string; status: 'active' | 'inactive'; role: string; 'last-active': string; }; const datas: Data[] = [ { name: 'Olivia Park', status: 'active', role: 'designer', 'last-active': '2 hours ago' }, { name: 'Ethan Kim', status: 'active', role: 'developer', 'last-active': '3 days ago' }, { name: 'Mia Choi', status: 'inactive', role: 'developer', 'last-active': '10 minutes ago' }, { name: 'Noah Lee', status: 'active', role: 'designer', 'last-active': '1 day ago' }, { name: 'Ava Jung', status: 'active', role: 'developer', 'last-active': '5 days ago' }, { name: 'Liam Han', status: 'inactive', role: 'developer', 'last-active': '5 days ago' }, { name: 'Emma Seo', status: 'active', role: 'designer', 'last-active': '7 days ago' }, { name: 'Mason Yoo', status: 'active', role: 'designer', 'last-active': '30 minutes ago' }, { name: 'Sophia Lim', status: 'inactive', role: 'designer', 'last-active': '4 hours ago' }, { name: 'Lucas Park', status: 'active', role: 'developer', 'last-active': '1 hour ago' }, { name: 'Olivia Park', status: 'active', role: 'designer', 'last-active': '2 hours ago' }, { name: 'Ethan Kim', status: 'active', role: 'developer', 'last-active': '3 days ago' }, { name: 'Mia Choi', status: 'inactive', role: 'developer', 'last-active': '10 minutes ago' }, { name: 'Noah Lee', status: 'active', role: 'designer', 'last-active': '1 day ago' }, { name: 'Ava Jung', status: 'active', role: 'developer', 'last-active': '5 days ago' }, { name: 'Liam Han', status: 'inactive', role: 'developer', 'last-active': '5 days ago' }, { name: 'Emma Seo', status: 'active', role: 'designer', 'last-active': '7 days ago' }, { name: 'Mason Yoo', status: 'active', role: 'designer', 'last-active': '30 minutes ago' }, { name: 'Sophia Lim', status: 'inactive', role: 'designer', 'last-active': '4 hours ago' }, { name: 'Lucas Park', status: 'active', role: 'developer', 'last-active': '1 hour ago' }, ]; const activeness: Record = { active: 'success', inactive: 'hint', }; /* -----------------------------------------------------------------------------------------------*/ interface FilterSelectProps extends React.ComponentProps { triggerLabel: string; content: React.ReactNode; } const FilterSelect = ({ content, triggerLabel, ...props }: FilterSelectProps) => { return ( } style={{ width: 'unset' }} > {triggerLabel} }> {content} ); }; ```