--- 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'` | | `ChecklistOutlineIcon` | `import { ChecklistOutlineIcon } 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'` | | `Heading1OutlineIcon` | `import { Heading1OutlineIcon } from '@vapor-ui/icons'` | | `Heading2OutlineIcon` | `import { Heading2OutlineIcon } from '@vapor-ui/icons'` | | `Heading3OutlineIcon` | `import { Heading3OutlineIcon } from '@vapor-ui/icons'` | | `Heading4OutlineIcon` | `import { Heading4OutlineIcon } 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'` | | `StrikeOutlineIcon` | `import { StrikeOutlineIcon } 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는 프로필 이미지 또는 대체 텍스트를 표시합니다. *** title: 'Avatar' site\_name: 'Avatar - Vapor Core' description: 'Avatar는 프로필 이미지 또는 대체 텍스트를 표시합니다.' ------------------------------------------------ ```json doc-gen:file { "file": "./src/components/demo/examples/avatar/default-avatar.tsx", "codeblock": true } ``` ## Property *** ### Size 크기를 지정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/avatar/avatar-size.tsx", "codeblock": true } ``` ### Shape 모양을 지정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/avatar/avatar-shape.tsx", "codeblock": true } ``` ## Examples *** ### Composition Pattern 하위 컴포넌트를 조합하여 이미지와 대체 콘텐츠를 커스터마이징합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/avatar/flexible.tsx", "codeblock": true } ``` ### Fallback Only 이미지 없이 대체 콘텐츠만 표시합니다. `delay` prop으로 대체 콘텐츠의 표시 지연 시간을 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/avatar/avatar-fallback-only.tsx", "codeblock": true } ``` ## Props Table *** ### Avatar.Root > ⚠️ Spec file not found: `avatar-root.json` #### Avatar.ImagePrimitive > ⚠️ Spec file not found: `avatar-image-primitive.json` #### Avatar.FallbackPrimitive > ⚠️ Spec file not found: `avatar-fallback-primitive.json` --- 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 > ⚠️ Spec file not found: `badge.json` --- 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 > ⚠️ Spec file not found: `breadcrumb-root.json` #### Breadcrumb.RootPrimitive > ⚠️ Spec file not found: `breadcrumb-root-primitive.json` #### Breadcrumb.ListPrimitive > ⚠️ Spec file not found: `breadcrumb-list-primitive.json` ### Breadcrumb.Item > ⚠️ Spec file not found: `breadcrumb-item.json` #### Breadcrumb.ItemPrimitive > ⚠️ Spec file not found: `breadcrumb-item-primitive.json` #### Breadcrumb.LinkPrimitive > ⚠️ Spec file not found: `breadcrumb-link-primitive.json` ### Breadcrumb.Separator > ⚠️ Spec file not found: `breadcrumb-separator.json` ### Breadcrumb.Ellipsis > ⚠️ Spec file not found: `breadcrumb-ellipsis.json` #### Breadcrumb.EllipsisPrimitive > ⚠️ Spec file not found: `breadcrumb-ellipsis-primitive.json` --- 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 > ⚠️ Spec file not found: `button.json` --- 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 > ⚠️ Spec file not found: `callout-root.json` ### Callout.Icon > ⚠️ Spec file not found: `callout-icon.json` --- 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 > ⚠️ Spec file not found: `card-root.json` ### Card.Header > ⚠️ Spec file not found: `card-header.json` ### Card.Body > ⚠️ Spec file not found: `card-body.json` ### Card.Footer > ⚠️ Spec file not found: `card-footer.json` --- 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 > ⚠️ Spec file not found: `checkbox-root.json` ### Checkbox.IndicatorPrimitive > ⚠️ Spec file not found: `checkbox-indicator-primitive.json` --- 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 > ⚠️ Spec file not found: `collapsible-root.json` ### Collapsible.Trigger > ⚠️ Spec file not found: `collapsible-trigger.json` ### Collapsible.Panel > ⚠️ Spec file not found: `collapsible-panel.json` --- 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 > ⚠️ Spec file not found: `dialog-root.json` ### Dialog.Popup > ⚠️ Spec file not found: `dialog-popup.json` #### Dialog.PortalPrimitive > ⚠️ Spec file not found: `dialog-portal-primitive.json` #### Dialog.OverlayPrimitive > ⚠️ Spec file not found: `dialog-overlay-primitive.json` #### Dialog.PopupPrimitive > ⚠️ Spec file not found: `dialog-popup-primitive.json` ### Dialog.Trigger > ⚠️ Spec file not found: `dialog-trigger.json` ### Dialog.Close > ⚠️ Spec file not found: `dialog-close.json` ### Dialog.Title > ⚠️ Spec file not found: `dialog-title.json` ### Dialog.Description > ⚠️ Spec file not found: `dialog-description.json` ### Dialog.Header > ⚠️ Spec file not found: `dialog-header.json` ### Dialog.Body > ⚠️ Spec file not found: `dialog-body.json` ### Dialog.Footer > ⚠️ Spec file not found: `dialog-footer.json` --- 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 > ⚠️ Spec file not found: `field-root.json` ### Field.Label > ⚠️ Spec file not found: `field-label.json` ### Field.Description > ⚠️ Spec file not found: `field-description.json` ### Field.Error > ⚠️ Spec file not found: `field-error.json` ### Field.Success > ⚠️ Spec file not found: `field-success.json` --- version: 1.0.0-beta.6 --- # FloatingBar URL: /docs/components/floating-bar Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/components/floating-bar.mdx FloatingBar는 하단에 고정되어 주요 액션을 포함하는 컴포넌트입니다. *** title: 'FloatingBar' site\_name: 'FloatingBar - Vapor Core' description: 'FloatingBar는 하단에 고정되어 주요 액션을 포함하는 컴포넌트입니다.' --------------------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/floating-bar/default.tsx", "codeblock": true } ``` ## Examples *** ### Actions FloatingBar는 다양한 액션 요소를 담을 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/floating-bar/with-actions.tsx", "codeblock": true } ``` ### Controlled FloatingBar는 제어 형태로 사용되어, 여러 상태를 동시에 관리할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/floating-bar/controlled.tsx", "codeblock": true } ``` ## Props Table *** ### FloatingBar.Root FloatingBar의 루트 컨테이너로, 전체 FloatingBar 컴포넌트의 상태와 동작을 관리합니다. ### FloatingBar.Trigger FloatingBar를 여는 트리거 요소입니다. ### FloatingBar.Close FloatingBar를 닫는 버튼 컴포넌트입니다. ### FloatingBar.Popup FloatingBar의 실제 콘텐츠를 담는 컨테이너입니다. Portal과 Positioner를 조합하여 구성됩니다. ### FloatingBar.PortalPrimitive FloatingBar를 DOM의 다른 위치에 렌더링하는 포털 컴포넌트입니다. ### FloatingBar.PositionerPrimitive FloatingBar의 위치를 설정하는 컴포넌트입니다. ### FloatingBar.PopupPrimitive FloatingBar의 실제 팝업 콘텐츠 영역입니다. --- 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 > ⚠️ Spec file not found: `icon-button.json` --- 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 > ⚠️ Spec file not found: `input-group-root.json` ### InputGroup.Counter > ⚠️ Spec file not found: `input-group-counter.json` --- 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 > ⚠️ Spec file not found: `menu-root.json` ### Menu.Trigger > ⚠️ Spec file not found: `menu-trigger.json` ### Menu.PositionerPrimitive > ⚠️ Spec file not found: `menu-popup.json` #### Menu.PortalPrimitive > ⚠️ Spec file not found: `menu-portal-primitive.json` #### Menu.PositionerPrimitive > ⚠️ Spec file not found: `menu-positioner-primitive.json` #### Menu.PopupPrimitive > ⚠️ Spec file not found: `menu-popup-primitive.json` ### Menu.CheckboxItemIndicatorPrimitive > ⚠️ Spec file not found: `menu-item.json` ### Menu.RadioItemIndicatorPrimitive > ⚠️ Spec file not found: `menu-separator.json` ### Menu.Group > ⚠️ Spec file not found: `menu-group.json` ### Menu.GroupLabel > ⚠️ Spec file not found: `menu-group-label.json` ### Menu.SubmenuRoot > ⚠️ Spec file not found: `menu-submenu-root.json` ### Menu.SubmenuTriggerItem > ⚠️ Spec file not found: `menu-submenu-trigger-item.json` ### Menu.SubmenuPopup > ⚠️ Spec file not found: `menu-submenu-popup.json` #### Menu.SubmenuPopupPrimitive > ⚠️ Spec file not found: `menu-submenu-popup-primitive.json` ### Menu.CheckboxItem > ⚠️ Spec file not found: `menu-checkbox-item.json` #### Menu.CheckboxItemPrimitive > ⚠️ Spec file not found: `menu-checkbox-item-primitive.json` #### Menu.CheckboxItemIndicatorPrimitive > ⚠️ Spec file not found: `menu-checkbox-item-indicator-primitive.json` ### Menu.RadioGroup > ⚠️ Spec file not found: `menu-radio-group.json` ### Menu.RadioItem > ⚠️ Spec file not found: `menu-radio-item.json` #### Menu.RadioItemPrimitive > ⚠️ Spec file not found: `menu-radio-item-primitive.json` #### Menu.RadioItemIndicatorPrimitive > ⚠️ Spec file not found: `menu-radio-item-indicator-primitive.json` --- version: 1.0.0-beta.6 --- # MultiSelect URL: /docs/components/multi-select Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/components/multi-select.mdx MultiSelect는 사용자가 여러 옵션 중에서 다중 선택할 수 있는 드롭다운 컴포넌트입니다. 선택된 값들은 배지 형태로 표시되며, 태그 선택, 필터링, 카테고리 선택 등에 사용됩니다. *** title: 'MultiSelect' site\_name: 'MultiSelect - Vapor Core' description: 'MultiSelect는 사용자가 여러 옵션 중에서 다중 선택할 수 있는 드롭다운 컴포넌트입니다. 선택된 값들은 배지 형태로 표시되며, 태그 선택, 필터링, 카테고리 선택 등에 사용됩니다.' ----------------------------------------------------------------------------------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/multi-select/default-multi-select.tsx", "codeblock": true } ``` ## Property *** ### Size MultiSelect의 크기를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/multi-select/multi-select-size.tsx", "codeblock": true } ``` ### Controlled State MultiSelect의 선택 상태를 제어합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/multi-select/multi-select-controlled.tsx", "codeblock": true } ``` ### States MultiSelect의 다양한 상태를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/multi-select/multi-select-states.tsx", "codeblock": true } ``` ## Examples *** ### Items Configuration 다양한 형태의 아이템 데이터를 사용합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/multi-select/multi-select-items.tsx", "codeblock": true } ``` ### Grouping Options 옵션을 그룹으로 묶어 구조화합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/multi-select/multi-select-grouping.tsx", "codeblock": true } ``` ### Custom Value Display MultiSelect.Value에 함수형 children을 제공하여 선택된 값들의 표시 방법을 커스터마이징할 수 있습니다. 기본적으로는 배지 형태로 표시되지만, 문자열이나 커스텀 컴포넌트로 변경할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/multi-select/multi-select-custom-value.tsx", "codeblock": true } ``` ## Props Table *** ### MultiSelect.Root > ⚠️ Spec file not found: `multi-select-root.json` ### MultiSelect.Trigger > ⚠️ Spec file not found: `multi-select-trigger.json` #### MultiSelect.TriggerPrimitive > ⚠️ Spec file not found: `multi-select-trigger-primitive.json` #### MultiSelect.TriggerIconPrimitive > ⚠️ Spec file not found: `multi-select-trigger-icon-primitive.json` #### MultiSelect.ValuePrimitive > ⚠️ Spec file not found: `multi-select-value-primitive.json` #### MultiSelect.PlaceholderPrimitive > ⚠️ Spec file not found: `multi-select-placeholder-primitive.json` ### MultiSelect.Popup > ⚠️ Spec file not found: `multi-select-popup.json` #### MultiSelect.PortalPrimitive > ⚠️ Spec file not found: `multi-select-portal-primitive.json` #### MultiSelect.PositionerPrimitive > ⚠️ Spec file not found: `multi-select-positioner-primitive.json` #### MultiSelect.PopupPrimitive > ⚠️ Spec file not found: `multi-select-popup-primitive.json` ### MultiSelect.Item > ⚠️ Spec file not found: `multi-select-item.json` #### MultiSelect.ItemPrimitive > ⚠️ Spec file not found: `multi-select-item-primitive.json` #### MultiSelect.ItemIndicatorPrimitive > ⚠️ Spec file not found: `multi-select-item-indicator-primitive.json` ### MultiSelect.Separator > ⚠️ Spec file not found: `multi-select-separator.json` ### MultiSelect.Group > ⚠️ Spec file not found: `multi-select-group.json` ### MultiSelect.GroupLabel > ⚠️ Spec file not found: `multi-select-group-label.json` --- version: 1.0.0-beta.6 --- # NavigationMenu URL: /docs/components/navigation-menu Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/components/navigation-menu.mdx 여러 콘텐츠 섹션 간에 전환할 수 있도록 돕는 요소로 클릭 시 페이지가 이동합니다. *** title: 'NavigationMenu' site\_name: 'NavigationMenu - Vapor Core' description: '여러 콘텐츠 섹션 간에 전환할 수 있도록 돕는 요소로 클릭 시 페이지가 이동합니다.' ------------------------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/navigation-menu/default-navigation-menu.tsx", "codeblock": true } ``` ## Property *** ### Size NavigationMenu의 크기를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/navigation-menu/navigation-menu-size.tsx", "codeblock": true } ``` ### Direction NavigationMenu의 방향을 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/navigation-menu/navigation-menu-direction.tsx", "codeblock": true } ``` ### Disabled NavigationMenu의 비활성화 상태를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/navigation-menu/navigation-menu-disabled.tsx", "codeblock": true } ``` ### Selected NavigationMenu의 선택된 상태를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/navigation-menu/navigation-menu-selected.tsx", "codeblock": true } ``` ## Examples *** ### With Icons 아이콘과 함께 사용합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/navigation-menu/navigation-menu-with-icon.tsx", "codeblock": true } ``` ### With Popup 팝오버 형태로 사용합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/navigation-menu/with-popup.tsx", "codeblock": true } ``` ### Flexible Usage NavigationMenu의 모든 프리셋 컴포넌트를 분리하여 사용합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/navigation-menu/flexible.tsx", "codeblock": true } ``` ## Props Table *** ### NavigationMenu.Root > ⚠️ Spec file not found: `navigation-menu-root.json` ### NavigationMenu.List > ⚠️ Spec file not found: `navigation-menu-list.json` ### NavigationMenu.Item > ⚠️ Spec file not found: `navigation-menu-item.json` ### NavigationMenu.Link > ⚠️ Spec file not found: `navigation-menu-link.json` ### NavigationMenu.Trigger > ⚠️ Spec file not found: `navigation-menu-trigger.json` #### NavigationMenu.TriggerPrimitive > ⚠️ Spec file not found: `navigation-menu-trigger-primitive.json` #### NavigationMenu.TriggerIndicatorPrimitive > ⚠️ Spec file not found: `navigation-menu-trigger-indicator-primitive.json` ### NavigationMenu.Content > ⚠️ Spec file not found: `navigation-menu-content.json` #### NavigationMenu.PortalPrimitive > ⚠️ Spec file not found: `navigation-menu-portal-primitive.json` #### NavigationMenu.PositionerPrimitive > ⚠️ Spec file not found: `navigation-menu-positioner-primitive.json` #### NavigationMenu.PopupPrimitive > ⚠️ Spec file not found: `navigation-menu-popup-primitive.json` ### NavigationMenu.Viewport > ⚠️ Spec file not found: `navigation-menu-viewport.json` #### NavigationMenu.ViewportPrimitive > ⚠️ Spec file not found: `navigation-menu-viewport-primitive.json` --- version: 1.0.0-beta.6 --- # Pagination URL: /docs/components/pagination Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/components/pagination.mdx Pagination은 중요한 정보를 시각적으로 강조하여 사용자에게 전달하는 메시지 컴포넌트입니다. *** title: 'Pagination' site\_name: 'Pagination - Vapor Core' description: 'Pagination은 중요한 정보를 시각적으로 강조하여 사용자에게 전달하는 메시지 컴포넌트입니다.' --------------------------------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/pagination/default.tsx", "codeblock": true } ``` ## Property ### Sibling Count Pagination에서 현재 페이지 주변에 표시할 페이지 번호의 개수를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/pagination/sibling-count.tsx", "codeblock": true } ``` ### Boundary Count Pagination의 시작과 끝에 항상 표시할 페이지 번호의 개수를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/pagination/boundary-count.tsx", "codeblock": true } ``` ### Size Pagination의 사이즈는 sm, md, lg, xl로 제공합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/pagination/size.tsx", "codeblock": true } ``` ### Disabled Pagination 버튼들의 비활성화 여부를 결정하는 옵션입니다. ```json doc-gen:file { "file": "./src/components/demo/examples/pagination/disabled.tsx", "codeblock": true } ``` ### Disabled Pagination 버튼들의 비활성화 여부를 결정하는 옵션입니다. ```json doc-gen:file { "file": "./src/components/demo/examples/pagination/disabled.tsx", "codeblock": true } ``` ### Controlled Pagination 컴포넌트를 제어 컴포넌트로 사용하는 예시입니다. ```json doc-gen:file { "file": "./src/components/demo/examples/pagination/controlled.tsx", "codeblock": true } ``` *** ### Pagination.Root 이 컴포넌트는 `div` 요소를 기반으로, 표준 HTML 속성(`className`, `style` 등)을 지원합니다. ### Pagination.Icon Pagination 내에서 아이콘을 표시하는 데 사용되는 컴포넌트입니다. 아이콘의 크기와 위치를 적절히 조정하여 일관된 시각적 경험을 제공합니다. 이 컴포넌트는 `div` 요소를 기반으로, 표준 HTML 속성을 지원합니다. --- version: 1.0.0-beta.6 --- # Popover URL: /docs/components/popover Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/components/popover.mdx Popover는 트리거 요소 근처에 부가 정보나 상호작용 콘텐츠를 표시하는 오버레이 컴포넌트입니다. 툴팁, 메뉴, 폼, 상세 정보 등을 표시할 때 사용합니다. *** title: 'Popover' site\_name: 'Popover - Vapor Core' description: 'Popover는 트리거 요소 근처에 부가 정보나 상호작용 콘텐츠를 표시하는 오버레이 컴포넌트입니다. 툴팁, 메뉴, 폼, 상세 정보 등을 표시할 때 사용합니다.' ------------------------------------------------------------------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/popover/default-popover.tsx", "codeblock": true } ``` ## Property *** ### PositionerProps Popover가 나타날 위치와 정렬을 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/popover/popover-positioning.tsx", "codeblock": true } ``` ### Offset Popover와 트리거 간의 거리를 조정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/popover/popover-offset.tsx", "codeblock": true } ``` ## Examples *** ### Content Variations 간단한 텍스트부터 복잡한 상호작용 요소까지 다양한 콘텐츠를 표시합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/popover/popover-content.tsx", "codeblock": true } ``` ## Props Table *** ### Popover.Root > ⚠️ Spec file not found: `popover-root.json` ### Popover.Trigger > ⚠️ Spec file not found: `popover-trigger.json` ### Popover.Popup > ⚠️ Spec file not found: `popover-popup.json` #### Popover.PortalPrimitive > ⚠️ Spec file not found: `popover-portal-primitive.json` #### Popover.PositionerPrimitive > ⚠️ Spec file not found: `popover-positioner-primitive.json` #### Popover.PopupPrimitive > ⚠️ Spec file not found: `popover-popup-primitive.json` ### Popover.Title > ⚠️ Spec file not found: `popover-title.json` ### Popover.Description > ⚠️ Spec file not found: `popover-description.json` ### Popover.Close > ⚠️ Spec file not found: `popover-close.json` --- version: 1.0.0-beta.6 --- # RadioCard URL: /docs/components/radio-card Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/components/radio-card.mdx RadioCard는 RadioGroup과 함께 사용하는 카드 형태의 라디오 버튼 컴포넌트입니다. 선택 가능한 옵션을 카드 UI로 표현하여 더 직관적인 사용자 경험을 제공합니다. *** title: 'RadioCard' site\_name: 'RadioCard - Vapor Core' description: 'RadioCard는 RadioGroup과 함께 사용하는 카드 형태의 라디오 버튼 컴포넌트입니다. 선택 가능한 옵션을 카드 UI로 표현하여 더 직관적인 사용자 경험을 제공합니다.' ----------------------------------------------------------------------------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/radio-card/default-radio-card.tsx", "codeblock": true } ``` ## Property *** ### Size RadioCard의 크기를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/radio-card/radio-card-size.tsx", "codeblock": true } ``` ### Disabled 사용자가 상호작용할 수 없는 상태입니다. 액션을 수행하기 위한 특정 조건을 충족하지 않았거나 일시적으로 기능을 제한하려는 상황에서 사용합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/radio-card/radio-card-disabled.tsx", "codeblock": true } ``` ### Read Only 읽기 전용 상태로, 사용자가 값을 변경할 수 없지만 현재 선택된 상태를 확인할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/radio-card/radio-card-readonly.tsx", "codeblock": true } ``` ## Examples *** ### Simple Usage RadioGroup.Root와 함께 사용합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/radio-card/radio-card-simple.tsx", "codeblock": true } ``` ### Direction VStack과 HStack을 사용하여 세로 및 가로 방향으로 배치합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/radio-card/radio-card-direction.tsx", "codeblock": true } ``` ## Props Table *** ### RadioCard > ⚠️ Spec file not found: `radio-card.json` --- version: 1.0.0-beta.6 --- # Radio URL: /docs/components/radio Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/components/radio.mdx Radio는 여러 옵션 중 하나만 선택할 수 있는 입력 컴포넌트입니다. RadioGroup과 함께 사용하여 라디오 버튼 그룹을 구성할 수 있습니다. *** title: 'Radio' site\_name: 'Radio - Vapor Core' description: 'Radio는 여러 옵션 중 하나만 선택할 수 있는 입력 컴포넌트입니다. RadioGroup과 함께 사용하여 라디오 버튼 그룹을 구성할 수 있습니다.' ------------------------------------------------------------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/radio-group/default-radio-group.tsx", "codeblock": true } ``` ## Property *** ### Size RadioGroup의 크기를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/radio-group/radio-group-size.tsx", "codeblock": true } ``` ### Disabled RadioGroup의 비활성화 상태를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/radio-group/radio-group-disabled.tsx", "codeblock": true } ``` ### Read Only RadioGroup의 읽기 전용 상태입니다. 사용자가 값을 변경할 수 없지만 현재 선택된 상태를 확인할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/radio-group/radio-readonly.tsx", "codeblock": true } ``` ## Examples *** ### Direction Radio 그룹의 방향을 조절할 수 있습니다. VStack과 HStack을 사용하여 세로 및 가로 방향으로 배치할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/radio-group/radio-direction.tsx", "codeblock": true } ``` ### Flexible Radio의 유연한 사용예시입니다. ```json doc-gen:file { "file": "./src/components/demo/examples/radio-group/flexible.tsx", "codeblock": true } ``` ## Props Table *** ### RadioGroup.Root > ⚠️ Spec file not found: `radio-group-root.json` ### RadioGroup.Label > ⚠️ Spec file not found: `radio-group-label.json` ### Radio.Root > ⚠️ Spec file not found: `radio-root.json` ### Radio.IndicatorPrimitive > ⚠️ Spec file not found: `radio-indicator-primitive.json` --- version: 1.0.0-beta.6 --- # Select URL: /docs/components/select Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/components/select.mdx Select는 사용자가 여러 옵션 중에서 하나를 선택할 수 있는 드롭다운 컴포넌트입니다. 폼 입력, 설정 선택, 필터링 등에 사용되며, 키보드 내비게이션과 접근성을 완벽하게 지원합니다. *** title: 'Select' site\_name: 'Select - Vapor Core' description: 'Select는 사용자가 여러 옵션 중에서 하나를 선택할 수 있는 드롭다운 컴포넌트입니다. 폼 입력, 설정 선택, 필터링 등에 사용되며, 키보드 내비게이션과 접근성을 완벽하게 지원합니다.' ---------------------------------------------------------------------------------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/select/default-select.tsx", "codeblock": true } ``` ## Property *** ### Size Select의 크기를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/select/select-size.tsx", "codeblock": true } ``` ### Positioning Select 드롭다운이 나타날 위치를 설정합니다. 기본값은 'bottom'입니다. ```json doc-gen:file { "file": "./src/components/demo/examples/select/select-positioning.tsx", "codeblock": true } ``` ### Controlled State Select의 선택 상태를 외부에서 제어합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/select/select-controlled.tsx", "codeblock": true } ``` ### States Select의 다양한 상태(비활성화, 읽기 전용, 오류)를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/select/select-states.tsx", "codeblock": true } ``` ## Examples *** ### Items Configuration 배열 형태와 객체 형태의 아이템 데이터를 모두 지원합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/select/select-items.tsx", "codeblock": true } ``` ### Grouping Options 관련된 옵션들을 그룹으로 묶어 구조화할 수 있습니다. Group과 GroupLabel, Separator를 사용하여 명확한 구조를 만들 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/select/select-grouping.tsx", "codeblock": true } ``` ### Custom Value Display Select.Value에 함수형 children을 제공하여 선택된 값을 커스터마이징할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/select/select-custom-value.tsx", "codeblock": true } ``` ## Props Table *** ### Select.Root > ⚠️ Spec file not found: `select-root.json` ### Select.Trigger > ⚠️ Spec file not found: `select-trigger.json` #### Select.ValuePrimitive > ⚠️ Spec file not found: `select-value-primitive.json` #### Select.PlaceholderPrimitive > ⚠️ Spec file not found: `select-placeholder-primitive.json` #### Select.TriggerIconPrimitive > ⚠️ Spec file not found: `select-trigger-icon-primitive.json` ### Select.Popup > ⚠️ Spec file not found: `select-popup.json` #### Select.PositionerPrimitive > ⚠️ Spec file not found: `select-positioner-primitive.json` #### Select.PopupPrimitive > ⚠️ Spec file not found: `select-popup-primitive.json` ### Select.Item > ⚠️ Spec file not found: `select-item.json` #### Select.ItemPrimitive > ⚠️ Spec file not found: `select-item-primitive.json` #### Select.ItemIndicatorPrimitive > ⚠️ Spec file not found: `select-item-indicator-primitive.json` ### Select.Group > ⚠️ Spec file not found: `select-group.json` ### Select.GroupLabel > ⚠️ Spec file not found: `select-group-label.json` ### Select.Separator > ⚠️ Spec file not found: `select-separator.json` --- version: 1.0.0-beta.6 --- # Sheet URL: /docs/components/sheet Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/components/sheet.mdx Sheet는 화면의 가장자리에서 슬라이드되어 나타나는 오버레이 컴포넌트입니다. 사이드바, 메뉴, 폼, 상세 정보 등을 표시할 때 사용합니다. *** title: 'Sheet' site\_name: 'Sheet - Vapor Core' description: 'Sheet는 화면의 가장자리에서 슬라이드되어 나타나는 오버레이 컴포넌트입니다. 사이드바, 메뉴, 폼, 상세 정보 등을 표시할 때 사용합니다.' --------------------------------------------------------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/sheet/default-sheet.tsx", "codeblock": true } ``` ## Property *** ### Side Sheet가 나타날 위치를 설정합니다. 기본값은 'right'입니다. ```json doc-gen:file { "file": "./src/components/demo/examples/sheet/sheet-side.tsx", "codeblock": true } ``` ### Controlled State Sheet의 열림/닫힘 상태를 외부에서 제어합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/sheet/sheet-controlled.tsx", "codeblock": true } ``` ### Keep Mounted Sheet가 닫혀도 DOM에서 제거되지 않고 유지되도록 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/sheet/sheet-keep-mounted.tsx", "codeblock": true } ``` ## Examples *** ### Custom Usage 유연하게 Sheet를 사용합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/sheet/flexible.tsx", "codeblock": true } ``` ## Props Table *** ### Sheet.Root > ⚠️ Spec file not found: `sheet-root.json` ### Sheet.Trigger > ⚠️ Spec file not found: `sheet-trigger.json` ### Sheet.Popup > ⚠️ Spec file not found: `sheet-popup.json` #### Sheet.PortalPrimitive > ⚠️ Spec file not found: `sheet-portal-primitive.json` #### Sheet.OverlayPrimitive > ⚠️ Spec file not found: `sheet-overlay-primitive.json` #### Sheet.PopupPrimitive > ⚠️ Spec file not found: `sheet-popup-primitive.json` #### Sheet.PositionerPrimitive > ⚠️ Spec file not found: `sheet-positioner-primitive.json` ### Sheet.Header > ⚠️ Spec file not found: `sheet-header.json` ### Sheet.Body > ⚠️ Spec file not found: `sheet-body.json` ### Sheet.Footer > ⚠️ Spec file not found: `sheet-footer.json` ### Sheet.Title > ⚠️ Spec file not found: `sheet-title.json` ### Sheet.Description > ⚠️ Spec file not found: `sheet-description.json` ### Sheet.Close > ⚠️ Spec file not found: `sheet-close.json` --- version: 1.0.0-beta.6 --- # Switch URL: /docs/components/switch Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/components/switch.mdx Switch는 사용자가 설정을 on/off로 전환할 수 있게 돕는 토글 컴포넌트입니다. *** title: 'Switch' site\_name: 'Switch - Vapor Core' description: 'Switch는 사용자가 설정을 on/off로 전환할 수 있게 돕는 토글 컴포넌트입니다.' --------------------------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/switch/default-switch.tsx", "codeblock": true } ``` ## Property *** ### Size Switch의 크기를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/switch/switch-size.tsx", "codeblock": true } ``` ### Checked Switch의 체크 상태를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/switch/switch-checked.tsx", "codeblock": true } ``` ### Disabled Switch의 비활성화 상태를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/switch/switch-disabled.tsx", "codeblock": true } ``` ### Read Only 사용자는 스위치 상태를 변경할 수 없지만, 현재 상태를 확인할 수 있도록 허용하는 상태입니다. ```json doc-gen:file { "file": "./src/components/demo/examples/switch/switch-readonly.tsx", "codeblock": true } ``` ## Examples *** ### Controlled 제어되는 Switch 컴포넌트의 사용 예시입니다. ```json doc-gen:file { "file": "./src/components/demo/examples/switch/switch-controlled.tsx", "codeblock": true } ``` ## Props Table *** ### Switch.Root > ⚠️ Spec file not found: `switch-root.json` #### Switch.ThumbPrimitive > ⚠️ Spec file not found: `switch-thumb-primitive.json` --- version: 1.0.0-beta.6 --- # Table URL: /docs/components/table Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/components/table.mdx Table는 데이터를 행과 열로 구성하여 구조화된 방식으로 표시하는 컴포넌트입니다. *** title: 'Table' site\_name: Table - Vapor Core description: 'Table는 데이터를 행과 열로 구성하여 구조화된 방식으로 표시하는 컴포넌트입니다.' ------------------------------------------------------------- Table 컴포넌트는 순수한 뷰(View) 역할에 집중하여 기본적인 구조와 스타일만을 제공합니다. 복잡한 상태 관리와 로직을 바탕으로 대량의 데이터를 다루는 Data Table을 구현하려면 [Table Block 문서](/blocks/table)를 참고해주세요.
```json doc-gen:file { "file": "./src/components/demo/examples/table/basic.tsx", "codeblock": true } ``` ## Props Table *** ### Table.Root > ⚠️ Spec file not found: `table-root.json` ### Table.Header > ⚠️ Spec file not found: `table-header.json` ### Table.Body > ⚠️ Spec file not found: `table-body.json` ### Table.Footer > ⚠️ Spec file not found: `table-footer.json` ### Table.Row > ⚠️ Spec file not found: `table-row.json` ### Table.Heading > ⚠️ Spec file not found: `table-heading.json` ### Table.Cell > ⚠️ Spec file not found: `table-cell.json` ### Table.ColumnGroup > ⚠️ Spec file not found: `table-column-group.json` ### Table.Column > ⚠️ Spec file not found: `table-column.json` --- version: 1.0.0-beta.6 --- # Tabs URL: /docs/components/tabs Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/components/tabs.mdx Tabs는 관련된 콘텐츠를 탭 형태로 구성하여 사용자가 쉽게 전환할 수 있도록 하는 컴포넌트입니다. 키보드 내비게이션, 접근성, 다양한 스타일 변형을 지원합니다. *** title: 'Tabs' site\_name: 'Tabs - Vapor Core' description: 'Tabs는 관련된 콘텐츠를 탭 형태로 구성하여 사용자가 쉽게 전환할 수 있도록 하는 컴포넌트입니다. 키보드 내비게이션, 접근성, 다양한 스타일 변형을 지원합니다.' --------------------------------------------------------------------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/tabs/default-tabs.tsx", "codeblock": true } ``` ## Property *** ### Size Tabs의 크기를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/tabs/tabs-size.tsx", "codeblock": true } ``` ### Variant line과 fill 두 가지 스타일을 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/tabs/tabs-variant.tsx", "codeblock": true } ``` ### Orientation 수평(horizontal)과 수직(vertical) 방향을 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/tabs/tabs-orientation.tsx", "codeblock": true } ``` ### Controlled State Tabs의 활성 상태를 외부에서 제어합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/tabs/tabs-controlled.tsx", "codeblock": true } ``` ### States Tabs의 다양한 상태(개별 탭 비활성화, 전체 탭 그룹 비활성화)를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/tabs/tabs-states.tsx", "codeblock": true } ``` ## Examples *** ### Keyboard Navigation Tabs는 완전한 키보드 내비게이션을 지원합니다. 포커스 동작과 순환 내비게이션을 세밀하게 제어할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/tabs/tabs-keyboard.tsx", "codeblock": true } ``` ## Props Table *** ### Tabs.Root > ⚠️ Spec file not found: `tabs-root.json` ### Tabs.List > ⚠️ Spec file not found: `tabs-list.json` ### Tabs.Trigger > ⚠️ Spec file not found: `tabs-trigger.json` ### Tabs.Indicator > ⚠️ Spec file not found: `tabs-indicator.json` ### Tabs.Panel > ⚠️ Spec file not found: `tabs-panel.json` --- version: 1.0.0-beta.6 --- # TextInput URL: /docs/components/text-input Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/components/text-input.mdx TextInput은 사용자가 데이터를 입력할 수 있도록 텍스트, 숫자 등 다양한 형식의 입력 필드를 제공합니다. *** title: 'TextInput' site\_name: 'TextInput - Vapor Core' description: 'TextInput은 사용자가 데이터를 입력할 수 있도록 텍스트, 숫자 등 다양한 형식의 입력 필드를 제공합니다.' ----------------------------------------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/text-input/default-text-input.tsx", "codeblock": true } ``` ## Property *** ### Size TextInput의 크기를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/text-input/text-input-size.tsx", "codeblock": true } ``` ### Type TextInput의 타입을 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/text-input/text-input-type.tsx", "codeblock": true } ``` ### Disabled 사용자가 상호작용할 수 없는 상태입니다. 액션을 수행하기 위한 특정 조건을 충족하지 않았거나 일시적으로 기능을 제한하려는 상황에서 사용합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/text-input/text-input-disabled.tsx", "codeblock": true } ``` ### Invalid 유효하지 않은 상태(필수 항목 누락, 잘못된 입력 등)를 표시하여 올바른 입력을 유도합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/text-input/text-input-invalid.tsx", "codeblock": true } ``` ### Read Only 값을 수정할 수 없지만, 텍스트를 복사하거나 읽을 수 있는 상태입니다. ```json doc-gen:file { "file": "./src/components/demo/examples/text-input/text-input-readonly.tsx", "codeblock": true } ``` ## Examples *** ### States TextInput의 다양한 상태를 보여줍니다. ```json doc-gen:file { "file": "./src/components/demo/examples/text-input/text-input-states.tsx", "codeblock": true } ``` ## Props Table *** ### TextInput > ⚠️ Spec file not found: `text-input.json` --- version: 1.0.0-beta.6 --- # Text URL: /docs/components/text Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/components/text.mdx Text 컴포넌트는 시멘틱 태그와 타이포그래피·색상 토큰을 조합하여 텍스트 스타일을 설정합니다. *** title: 'Text' site\_name: 'Text - Vapor Core' description: 'Text 컴포넌트는 시멘틱 태그와 타이포그래피·색상 토큰을 조합하여 텍스트 스타일을 설정합니다.' -------------------------------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/text/default-text.tsx", "codeblock": true } ``` ## Property *** ### Typography 텍스트의 타이포그래피 스타일을 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/text/text-typography.tsx", "codeblock": true } ``` ### Foreground 텍스트의 색상을 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/text/text-foreground.tsx", "codeblock": true } ``` ## Props Table *** ### Text > ⚠️ Spec file not found: `text.json` --- version: 1.0.0-beta.6 --- # Textarea URL: /docs/components/textarea Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/components/textarea.mdx Textarea는 사용자가 여러 줄의 텍스트를 입력할 수 있도록 하는 텍스트 입력 필드를 제공합니다. *** title: 'Textarea' site\_name: 'Textarea - Vapor Core' description: 'Textarea는 사용자가 여러 줄의 텍스트를 입력할 수 있도록 하는 텍스트 입력 필드를 제공합니다.' ----------------------------------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/textarea/default-textarea.tsx", "codeblock": true } ``` ## Property *** ### Size Textarea의 크기를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/textarea/textarea-size.tsx", "codeblock": true } ``` ### Auto Resize 텍스트 내용에 따라 높이가 자동 조절됩니다. ```json doc-gen:file { "file": "./src/components/demo/examples/textarea/textarea-auto-resize.tsx", "codeblock": true } ``` ### States Textarea의 다양한 상태를 보여줍니다. ```json doc-gen:file { "file": "./src/components/demo/examples/textarea/textarea-states.tsx", "codeblock": true } ``` ## Examples *** ### maxLength Textarea에 `maxLength` 속성을 추가하여 입력 가능한 최대 문자 수를 제한하는 기능을 제공합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/textarea/textarea-character-count.tsx", "codeblock": true } ``` ## Props Table *** ### Textarea > ⚠️ Spec file not found: `textarea.json` --- version: 1.0.0-beta.6 --- # Toast URL: /docs/components/toast Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/components/toast.mdx Toast는 일시적인 알림 메시지를 사용자에게 표시하는 컴포넌트입니다. *** title: 'Toast' site\_name: 'Toast - Vapor Core' description: 'Toast는 일시적인 알림 메시지를 사용자에게 표시하는 컴포넌트입니다.' ------------------------------------------------------ Toast 컴포넌트는 화면의 모서리에 일시적인 알림 메시지를 표시하는 데 사용됩니다. 사용자의 작업에 대한 피드백을 제공하고, 피드백을 하나의 리스트로 관리하기 때문에 다른 컴포넌트와 사용 방식이 다릅니다. ```json doc-gen:file { "file": "./src/components/demo/examples/toast/default.tsx", "codeblock": true } ``` ## Property ### Methods Toast를 추가, 업데이트 및 제거할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/toast/method.tsx", "codeblock": true } ``` ### ColorPalette Toast의 색상 팔레트를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/toast/color-palette.tsx", "codeblock": true } ``` ## Examples ### Action Action 버튼과 함께 사용할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/toast/action.tsx", "codeblock": true } ``` ### Close Close 버튼을 제거할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/toast/close.tsx", "codeblock": true } ``` ### Icon Icon을 커스텀 할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/toast/icon.tsx", "codeblock": true } ``` ### Custom Toast 아이템을 완전히 커스텀할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/toast/custom.tsx", "codeblock": true } ``` ## Props ### Toast.Provider > ⚠️ Spec file not found: `toast-provider.json` ### Toast.ProviderPrimitive > ⚠️ Spec file not found: `toast-provider-primitive.json` ### Toast.PortalPrimitive > ⚠️ Spec file not found: `toast-portal-primitive.json` ### Toast.ViewportPrimitive > ⚠️ Spec file not found: `toast-viewport-primitive.json` ### Toast.RootPrimitive > ⚠️ Spec file not found: `toast-root-primitive.json` ### Toast.ContentPrimitive > ⚠️ Spec file not found: `toast-content-primitive.json` ### Toast.TitlePrimitive > ⚠️ Spec file not found: `toast-title-primitive.json` ### Toast.DescriptionPrimitive > ⚠️ Spec file not found: `toast-description-primitive.json` ### Toast.ActionPrimitive > ⚠️ Spec file not found: `toast-action-primitive.json` ### Toast.ClosePrimitive > ⚠️ Spec file not found: `toast-close-primitive.json` ### Toast.IconPrimitive > ⚠️ Spec file not found: `toast-icon-primitive.json` ### useToastManager > ⚠️ Spec file not found: `toast-object.json` --- version: 1.0.0-beta.6 --- # Tooltip URL: /docs/components/tooltip Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/components/tooltip.mdx 요소에 대한 추가 정보를 제공하는 툴팁 컴포넌트입니다 *** title: 'Tooltip' site\_name: 'Tooltip - Vapor Core' description: '요소에 대한 추가 정보를 제공하는 툴팁 컴포넌트입니다' -------------------------------------------- ```json doc-gen:file { "file": "./src/components/demo/examples/tooltip/default-tooltip.tsx", "codeblock": true } ``` ## Property *** ### Positioning Tooltip의 표시 위치를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/tooltip/tooltip-positioning.tsx", "codeblock": true } ``` ### Alignment Tooltip의 정렬 위치를 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/tooltip/tooltip-alignment.tsx", "codeblock": true } ``` ### Delay Tooltip의 지연 시간을 설정합니다. ```json doc-gen:file { "file": "./src/components/demo/examples/tooltip/tooltip-delay.tsx", "codeblock": true } ``` ### Offset Tooltip의 거리와 정렬 오프셋을 조정할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/tooltip/tooltip-offset.tsx", "codeblock": true } ``` ## Examples *** ### Content Variations 다양한 형태의 툴팁 내용을 표시할 수 있습니다. ```json doc-gen:file { "file": "./src/components/demo/examples/tooltip/tooltip-content.tsx", "codeblock": true } ``` ## Props Table *** ### Tooltip.Root > ⚠️ Spec file not found: `tooltip-root.json` ### Tooltip.Trigger > ⚠️ Spec file not found: `tooltip-trigger.json` ### Tooltip.Popup > ⚠️ Spec file not found: `tooltip-popup.json` #### Tooltip.PortalPrimitive > ⚠️ Spec file not found: `tooltip-portal-primitive.json` #### Tooltip.PositionerPrimitive > ⚠️ Spec file not found: `tooltip-positioner-primitive.json` #### Tooltip.PopupPrimitive > ⚠️ Spec file not found: `tooltip-popup-primitive.json` --- version: 1.0.0-beta.6 --- # Next.js - App Router URL: /docs/frameworks/next-js-app Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/frameworks/next-js-app.mdx Vapor UI 컴포넌트를 Nextjs app router와 사용하는 방법 *** title: 'Next.js - App Router' description: 'Vapor UI 컴포넌트를 Nextjs app router와 사용하는 방법' -------------------------------------------------------- ## Next.js - App Router Next.js 13의 app/ 디렉토리는 기본적으로 서버 컴포넌트를 사용합니다. Vapor UI 컴포넌트는 빌드 시점에 `use client`를 추가하므로 서버 컴포넌트에서 사용할 수 있습니다. ### 프로젝트 생성 먼저, Next.js 프로젝트를 생성합니다. 설치 과정에서 **App Router** 사용을 선택해 주세요. ```bash npx create-next-app@latest ``` ### 라이브러리 설치 프로젝트 디렉토리로 이동하여 VaporUI를 설치합니다. ```bash cd your-project-name ``` ```package-install npm install @vapor-ui/core @vapor-ui/icons ``` ### `next.config.ts` 설정 프로젝트의 루트 디렉토리에 있는 `next.config.ts` 파일을 열고, [`optimizePackageImports`](https://nextjs.org/docs/app/api-reference/config/next-config-js/optimizePackageImports) 옵션을 추가합니다. 이 설정은 `@vapor-ui/core` 라이브러리에서 사용하는 부분만 빌드에 포함시켜 **최종 번들 사이즈를 줄여줍니다.** ```typescript title="next.config.ts" import type { NextConfig } from 'next'; const nextConfig: NextConfig = { // Vapor UI 번들 최적화 설정 experimental: { optimizePackageImports: ['@vapor-ui/core', '@vapor-ui/icons'], }, }; export default nextConfig; ``` ### 컴포넌트 사용 예시 이제 페이지에서 Vapor UI 컴포넌트와 테마 전환 기능을 사용할 수 있습니다. ```tsx title="src/app/page.tsx" import { Card, Text } from '@vapor-ui/core'; export default function HomePage() { return (

Welcome to Vapor UI!

이것은 Next.js App Router와 함께 Vapor UI 컴포넌트를 사용하는 예시입니다.
); } ```
--- version: 1.0.0-beta.6 --- # Next.js - Pages Router URL: /docs/frameworks/next-js-pages Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/frameworks/next-js-pages.mdx Vapor UI 컴포넌트를 Nextjs Pages Router와 사용하는 방법 *** title: 'Next.js - Pages Router' description: 'Vapor UI 컴포넌트를 Nextjs Pages Router와 사용하는 방법' ---------------------------------------------------------- ## Next.js - Pages Router Next.js Pages Router는 전통적인 파일 시스템 기반 라우팅을 사용합니다. Vapor UI 컴포넌트는 Pages Router 환경에서도 완벽하게 작동합니다. ### 프로젝트 생성 먼저, Next.js 프로젝트를 생성합니다. Pages Router를 사용하도록 설정해주세요. ```bash npx create-next-app@latest ``` ### 라이브러리 설치 프로젝트 디렉토리로 이동하여 Vapor UI를 설치합니다. ```bash cd your-project-name ``` ```package-install npm install @vapor-ui/core @vapor-ui/icons ``` ### `next.config.ts` 설정 Pages Router에서는 `transpilePackages` 옵션을 사용하여 라이브러리를 트랜스파일합니다. ```typescript title="next.config.ts" import type { NextConfig } from 'next'; const nextConfig: NextConfig = { reactStrictMode: true, transpilePackages: ['@vapor-ui/core', '@vapor-ui/icons'], }; export default nextConfig; ``` ### 컴포넌트 사용 예시 이제 페이지에서 Vapor UI 컴포넌트와 테마 전환 기능을 사용할 수 있습니다. ```tsx title="pages/index.tsx" import { Card, Text } from '@vapor-ui/core'; export default function HomePage() { return (

Welcome to Vapor UI!

이것은 Next.js Pages Router와 함께 Vapor UI 컴포넌트를 사용하는 예시입니다.
); } ```
--- version: 1.0.0-beta.6 --- # React Router URL: /docs/frameworks/react-router Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/frameworks/react-router.mdx Vapor UI 컴포넌트를 React Router와 함께 사용하는 방법 *** title: 'React Router' description: 'Vapor UI 컴포넌트를 React Router와 함께 사용하는 방법' ------------------------------------------------------ ## React Router React Router는 React 애플리케이션에서 선언적 라우팅을 위한 표준 라이브러리입니다. SPA(Single Page Application)를 구축할 때 필수적인 도구입니다. ### 프로젝트 생성 Vite를 사용하여 React 프로젝트를 생성하고 React Router를 설치합니다. ```bash # 프로젝트 생성 npx create-react-router@latest my-react-router-app cd my-react-router-app ``` ### 라이브러리 설치 Vapor UI 패키지를 설치합니다. ```package-install npm install @vapor-ui/core @vapor-ui/icons ``` ### Vite 설정 Vite 설정 파일에서 Vapor UI 패키지가 SSR에서 올바르게 작동하도록 구성합니다. ```typescript title="vite.config.ts" import react from '@vitejs/plugin-react'; import { defineConfig } from 'vite'; export default defineConfig({ plugins: [react()], ssr: { noExternal: ['@vapor-ui/core', '@vapor-ui/icons'], }, }); ``` ### 컴포넌트 사용 예시 ```tsx title="pages/index.tsx" import { Card, Text } from '@vapor-ui/core'; export default function HomePage() { return (

Welcome to Vapor UI!

이것은 React Router와 함께 Vapor UI 컴포넌트를 사용하는 예시입니다.
); } ```
--- version: 1.0.0-beta.6 --- # Vite URL: /docs/frameworks/vite-react Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/frameworks/vite-react.mdx Vapor UI 컴포넌트를 Vite와 React에서 사용하는 방법 *** title: 'Vite' description: 'Vapor UI 컴포넌트를 Vite와 React에서 사용하는 방법' --------------------------------------------------- ## Vite + React Vite는 빠른 개발 서버와 최적화된 빌드를 제공하는 모던 프론트엔드 빌드 도구입니다. React와 함께 사용하면 뛰어난 개발자 경험을 제공합니다. ### 프로젝트 생성 Vite React 프로젝트를 생성하고 기본 의존성을 설치합니다. ```bash # Vite React 프로젝트 생성 (TypeScript 템플릿) npm create vite@latest # 프로젝트 폴더로 이동 cd my-vapor-vite-app # 기본 의존성 설치 npm install ``` ### 라이브러리 설치 Vapor UI 패키지를 설치합니다. ```package-install npm install @vapor-ui/core @vapor-ui/icons ``` ### Vite 설정 Vite 설정을 구성합니다. ```typescript title="vite.config.ts" import react from '@vitejs/plugin-react'; import { defineConfig } from 'vite'; // https://vite.dev/config/ export default defineConfig({ plugins: [react()], }); ``` ### 컴포넌트 사용 예시 ```tsx title="src/App.tsx" import { Card, Text } from '@vapor-ui/core'; export default function HomePage() { return (

Welcome to Vapor UI!

이것은 Vite와 React와 함께 Vapor UI 컴포넌트를 사용하는 예시입니다.
); } ```
--- version: 1.0.0-beta.6 --- # Installation URL: /docs/getting-started/installation Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/getting-started/installation.mdx Vapor UI를 프로젝트에 설치하고 첫 컴포넌트를 사용해보세요. *** title: Installation description: Vapor UI를 프로젝트에 설치하고 첫 컴포넌트를 사용해보세요. ------------------------------------------------- Vapor UI를 설치하고 **2분 안에** 첫 번째 컴포넌트를 사용할 수 있습니다. ## 시스템 요구사항 * **React**: 17 이상 * **Node.js**: 16 이상 ## 패키지 설치 원하는 패키지 매니저로 Vapor UI를 설치하세요: ```package-install npm install @vapor-ui/core @vapor-ui/icons ``` ## 첫 번째 컴포넌트 사용하기 설치가 완료되었습니다! 이제 컴포넌트를 import해서 사용해보세요: ```json doc-gen:file { "file": "./src/components/demo/examples/assemble-component.tsx", "codeblock": true } ``` ## 다음 단계 * [테마 설정하기](./theming) - 라이트/다크 모드 및 커스텀 테마 설정 방법 * [컴포넌트 살펴보기](./overview#components) - 다양한 UI 컴포넌트 사용법 --- version: 1.0.0-beta.6 --- # LLMs.txt URL: /docs/getting-started/llms-txt Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/getting-started/llms-txt.mdx Cursor 등 AI 도구에서 Vapor Design System 문서를 활용하는 방법 *** title: LLMs.txt description: Cursor 등 AI 도구에서 Vapor Design System 문서를 활용하는 방법 ------------------------------------------------------------- ## LLMs.txt란 무엇인가? Vapor Design System의 문서를 LLM(Large Language Model)이 잘 이해하도록 구조화한 텍스트 파일입니다. 컨텍스트 창(context window)이 제한된 AI 도구에서 핵심 정보를 빠르게 파악할 수 있게 돕습니다. *** ## 제공 파일 구성 | 파일명 | 설명 | | ------------- | ---------------------------------------------------------- | | llms.txt | 전체 라우트 및 카테고리 개요를 포함한 메인 인덱스 파일 | | llms-full.txt | Vapor Design System의 모든 문서(컴포넌트, 가이드, API 등)를 포함한 전체 문서 세트 | ### 메인 인덱스 * [llms.txt](/llms.txt) : 각 문서에 대한 요약과 링크가 포함되어 있으며, AI가 필요한 자료를 따라갈 수 있도록 구성됩니다 * [llms-full.txt](/llms-full.txt) : 모든 내용을 담아 큰 컨텍스트를 사용하는 워크플로우에 적합합니다 ### 세부 문서 * 가이드: [\`/docs/getting-started/installation.mdx](/docs/getting-started/installation.mdx): Vapor UI 설치를 위한 가이드. * 디자인 토큰 * [/docs/tokens/color.mdx](/docs/tokens/color.mdx): 디자인 토큰에 대한 상세 문서로, 색상 시스템을 정의합니다. * [/docs/tokens/size.mdx](/docs/tokens/size.mdx): 디자인 토큰에 대한 상세 문서로, 크기 및 여백을 정의합니다. * [/docs/tokens/typography.mdx](/docs/tokens/typography.mdx): 디자인 토큰에 대한 상세 문서로, 타이포그래피 시스템을 * 테마 변경: * [/docs/getting-started/theming.mdx](/docs/getting-started/theming.mdx): Next.js 앱에서 테마를 변경하는 방법에 대한 가이드. * 컴포넌트 * [/docs/components/\[component-name\].mdx](/docs/components/avatar.mdx): 컴포넌트별 상세 문서로, 각 컴포넌트의 사용법과 API를 포함합니다. (예: Avatar) *** ## AI 도구와 함께 사용하기 Cursor 등 LLM 기반 코드 도구에서 LLMs 텍스트 파일을 활용하려면 `@Docs` 기능을 사용하세요. [Cursor @Docs](https://docs.cursor.com/context/@-symbols/@-docs) --- version: 1.0.0-beta.6 --- # Overview URL: /docs/getting-started/overview Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/getting-started/overview.mdx 빠른 개발과 일관된 디자인을 위한 Vapor UI 디자인 시스템을 살펴보세요. *** title: Overview description: 빠른 개발과 일관된 디자인을 위한 Vapor UI 디자인 시스템을 살펴보세요. -------------------------------------------------------- Vapor UI는 **개발자 경험과 디자인 일관성**을 모두 만족시키는 React 컴포넌트 라이브러리입니다. 구름에서 개발한 세 번째 디자인 시스템으로, 실제 프로덕션에서 검증된 컴포넌트들을 제공합니다. ### 특징 * **모듈화된 구조**: 필요한 패키지만 선택적으로 사용 가능 * **완전한 TypeScript 지원**: 타입 안전성과 개발자 경험 최적화 * **접근성 기본 내장**: WCAG 2.1 AA 수준의 웹 접근성 자동 지원 * **Tailwind CSS 통합**: 익숙한 유틸리티 클래스로 빠른 커스터마이징 * **다크 모드**: 라이트/다크 테마 자동 전환 시스템 ### 이런 프로젝트에 적합합니다: * **빠른 프로토타이핑이 필요한** 스타트업과 신규 프로젝트 * **일관된 디자인 시스템을 구축하려는** 중대형 팀 * **접근성을 중요시하는** 공공 서비스나 글로벌 서비스 * **TypeScript 환경에서 개발하는** 모던 React 프로젝트 * **디자인과 개발 간 협업이 중요한** 조직 *** ## Components --- version: 1.0.0-beta.6 --- # Design Principles URL: /docs/getting-started/principles Source: https://raw.githubusercontent.com/goorm-dev/vapor-ui/refs/heads/main/apps/website/content/docs/getting-started/principles.mdx Vapor UI의 컴포넌트 아키텍처와 개발 철학을 이끄는 핵심 디자인 원칙 *** title: Design Principles description: Vapor UI의 컴포넌트 아키텍처와 개발 철학을 이끄는 핵심 디자인 원칙 ------------------------------------------------------ Vapor UI는 합성, 접근성, 일관성, 개발자 경험을 우선시하는 6가지 기본 디자인 원칙을 따르면서 유연한 커스터마이징 기능을 유지합니다. ## 1. Preset 기반의 컴파운드 패턴 Vapor UI는 편의성과 유연성을 모두 제공하는 **합성 컴포넌트 패턴**을 채택합니다. 빠른 구현을 위한 **Preset 컴포넌트**와 완전한 커스터마이징 제어를 위한 **Primitive 컴포넌트**를 함께 제공합니다. ```tsx // Preset 패턴 (빠르고 간편) Trigger Contents // Primitive 패턴 (완전한 제어) Trigger Contents ``` 이러한 이중 접근법을 통해 개발자는 다음과 같은 이점을 얻을 수 있습니다: * **빠른 시작** - 바로 사용 가능한 preset 컴포넌트로 즉시 구현 * **깊은 확장** - 커스텀 동작이 필요할 때 primitive 컴포넌트 활용 * **혼합 사용** - 동일한 애플리케이션 내에서 두 패턴을 모두 사용 ## 2. 접근성 포괄적인 [WCAG 2.2](https://www.w3.org/TR/WCAG22/) AA 준수와 [키보드 네비게이션](https://www.w3.org/TR/WCAG22/#keyboard-accessible), [포커스 형태](https://www.w3.org/WAI/WCAG22/Understanding/focus-appearance) 등의 접근성 향상을 위해 [Base UI](https://base-ui.com/react/overview/quick-start)를 기반으로 구축되었습니다. ### 포괄적인 접근성 기능 * **Base UI 통합** — 자동 ARIA 속성, 키보드 내비게이션, 스크린 리더 지원 * **색상 대비 준수** — 자체 개발한 Color Generator가 WCAG AA/AAA 대비 비율을 보장 * **수학적 디자인 토큰** — 일관된 시각적 위계를 위해 수학적 비율로 생성된 디자인 토큰 ```tsx // 적절한 ARIA 속성과 키보드 처리가 자동으로 포함됨 설정 열기 {/* 포커스 관리와 ESC 키 처리가 내장됨 */} ``` ### Color Generator 시스템 내부 Color Generator가 지각적 색상 모델을 사용하여 접근성 있는 색상 팔레트를 생성합니다: ```tsx // 색상이 자동으로 대비 요구사항을 충족함 Primary Success Warning ``` ## 3. 일관된 네이밍 규칙 모든 컴포넌트는 예측 가능하고 직관적인 사용 경험을 제공하기 위해 일관된 네이밍 규칙을 따릅니다. * 독립 컴포넌트: 단일 이름 * 합성 컴포넌트: Dot Notation 표기법 ```tsx // 단일 컴포넌트 상태 // 합성 컴포넌트 프로젝트 상태 현재 개발 진행상황 섹션 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 > ⚠️ Spec file not found: `box.json` --- 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 > ⚠️ Spec file not found: `flex.json` --- 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 > ⚠️ Spec file not found: `grid-root.json` ### Grid.Item > ⚠️ Spec file not found: `grid-item.json` --- 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 > ⚠️ Spec file not found: `h-stack.json` --- 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 > ⚠️ Spec file not found: `v-stack.json` --- 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, 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="$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; 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} ); }; ```