@mondrianai/runyourai-design-system 0.0.14 → 0.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -309,28 +309,35 @@ interface ComboboxProps {
309
309
  declare function Combobox({ options, value, onValueChange, placeholder, searchPlaceholder, showSearch, footer, className, disabled, }: ComboboxProps): react_jsx_runtime.JSX.Element;
310
310
 
311
311
  type DatePickerLocale = 'ko' | 'en' | 'jp';
312
- type DatePickerMode = 'date' | 'offset';
312
+ type DatePickerMode = 'date' | 'offset' | 'range';
313
+ type DateRange = {
314
+ start?: Date;
315
+ end?: Date;
316
+ };
313
317
  interface DatePickerProps {
314
- /** Controlled value */
318
+ /** Controlled value (date / offset modes) */
315
319
  value?: Date;
316
- /** Uncontrolled default value */
320
+ /** Uncontrolled default value (date / offset modes) */
317
321
  defaultValue?: Date;
318
- /** Called when user selects a date */
322
+ /** Called when user selects a date (date / offset modes) */
319
323
  onChange?: (date: Date | undefined) => void;
320
324
  /**
321
- * 'date' — trigger shows formatted date (e.g. "June 01, 2025")
325
+ * 'date' — trigger shows formatted date (e.g. "June 01, 2025")
322
326
  * 'offset' — trigger shows days-from-today (e.g. "In 2 days")
327
+ * 'range' — user interactively picks start + end; use range / onRangeChange
323
328
  */
324
329
  mode?: DatePickerMode;
330
+ /** Controlled range value. Used when mode='range'. */
331
+ range?: DateRange;
332
+ /** Uncontrolled default range. Used when mode='range'. */
333
+ defaultRange?: DateRange;
334
+ /** Called when the selected range changes. Used when mode='range'. */
335
+ onRangeChange?: (range: DateRange) => void;
325
336
  /** When true, dates before today cannot be selected and prev-month nav is blocked at current month */
326
337
  disablePast?: boolean;
327
338
  locale?: DatePickerLocale;
328
339
  /** Override the placeholder shown when no date is selected */
329
340
  placeholder?: string;
330
- /**
331
- * Receives the selected date and returns a helper string rendered below the trigger.
332
- * Only shown when mode='offset' and a date is selected.
333
- */
334
341
  className?: string;
335
342
  /**
336
343
  * [minYear, maxYear] for the year dropdown.
@@ -341,7 +348,7 @@ interface DatePickerProps {
341
348
  showTodayLabel?: boolean;
342
349
  disabled?: boolean;
343
350
  }
344
- declare function DatePicker({ value, defaultValue, onChange, mode, disablePast, locale, placeholder, className, yearRange, showTodayLabel, disabled, }: DatePickerProps): react_jsx_runtime.JSX.Element;
351
+ declare function DatePicker({ value, defaultValue, onChange, mode, range, defaultRange, onRangeChange, disablePast, locale, placeholder, className, yearRange, showTodayLabel, disabled, }: DatePickerProps): react_jsx_runtime.JSX.Element;
345
352
 
346
353
  interface FieldProps {
347
354
  /** 필드 레이블 */
@@ -707,6 +714,8 @@ type SidebarSubMenuItem = {
707
714
  titleBadge?: string | number;
708
715
  onClick?: () => void;
709
716
  isExternal?: boolean;
717
+ /** 아이템 행 우측에 렌더링되는 커스텀 콘텐츠. 링크 외부에 위치하므로 버튼 등 인터랙티브 요소를 포함할 수 있습니다. */
718
+ rightContent?: React$1.ReactNode;
710
719
  };
711
720
  type SidebarMainMenuItem = {
712
721
  type?: 'item';
@@ -744,7 +753,7 @@ declare function SidebarLink({ href, className, style, onClick, children, }: {
744
753
  onClick?: () => void;
745
754
  children: React$1.ReactNode;
746
755
  }): React$1.ReactElement<unknown, string | React$1.JSXElementConstructor<any>>;
747
- declare function Sidebar({ logo, menus, avatar, utilities, panelTopContent, panelCenterContent, panelBottomContent, className, LinkComponent, }: {
756
+ declare function Sidebar({ logo, menus, avatar, utilities, panelTopContent, panelCenterContent, panelBottomContent, className, LinkComponent, isPanelOpen: isPanelOpenProp, onPanelOpenChange, mainMenuIconSize, }: {
748
757
  logo: React$1.ReactNode;
749
758
  menus: SidebarMainMenuItem[];
750
759
  avatar: React$1.ReactNode;
@@ -754,6 +763,20 @@ declare function Sidebar({ logo, menus, avatar, utilities, panelTopContent, pane
754
763
  panelBottomContent?: React$1.ReactNode;
755
764
  className?: string;
756
765
  LinkComponent: SidebarLinkComponent;
766
+ /**
767
+ * 서브메뉴 패널의 열림 상태를 외부에서 제어합니다.
768
+ * - `true` / `false`: controlled 모드 — subMenus 배열 길이와 관계없이 이 값을 따릅니다.
769
+ * - `undefined` (기본값): uncontrolled 모드 — activeMenu의 subMenus가 있을 때 자동으로 열립니다.
770
+ */
771
+ isPanelOpen?: boolean;
772
+ /** 패널 열림 상태가 변경될 때 호출됩니다. controlled / uncontrolled 모두 동작합니다. */
773
+ onPanelOpenChange?: (isOpen: boolean) => void;
774
+ /**
775
+ * 좌측 메인 메뉴(내비게이터) 아이콘 컨테이너 크기.
776
+ * - `'md'` (기본값): 32px
777
+ * - `'lg'`: 40px
778
+ */
779
+ mainMenuIconSize?: 'md' | 'lg';
757
780
  }): react_jsx_runtime.JSX.Element;
758
781
 
759
782
  interface SkeletonProps extends React$1.HTMLAttributes<HTMLDivElement> {
@@ -1525,4 +1548,4 @@ declare function WordFileIcon({ className }: {
1525
1548
  className?: string;
1526
1549
  }): react_jsx_runtime.JSX.Element;
1527
1550
 
1528
- export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, AgentBlogIcon, AgentCsIcon, AgentDataIcon, AgentHrIcon, AgentMailIcon, AgentTrendIcon, AiAgentIcon, AiBuilderIcon, AiCloudIcon, AiDatacenterIcon, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AlignJustifyIcon, AlignLeftIcon, ArrowDownIcon, Avatar, AvatarGroup, type AvatarGroupItem, type AvatarGroupProps, type AvatarProps, type AvatarSize, BADGE_VARIANT_STYLES, Badge, type BadgeProps, type BadgeVariant, BlockquoteIcon, BoldIcon, BookOpenIcon, BookUpIcon, Breadcrumb, Button, type ButtonProps, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, CheckboxCard, type CheckboxCardProps, type CheckboxProps, ChevronsUpDownIcon, ChoiceCardGroup, type ChoiceCardGroupProps, ChoiceCardItem, type ChoiceCardItemProps, CircleCheckFillIcon, CircleHelpIcon, CircleIndicator, type CircleIndicatorProps, CircleOutlineIcon, ClaudeIcon, CodeIcon, CodeSquareIcon, Collapsible, CollapsibleContent, type CollapsibleProps, CollapsibleRoot, CollapsibleTrigger, type CollapsibleWorkspace, Combobox, type ComboboxOption, type ComboboxProps, CreditIcon, DataSection, type DataSectionProps, DatePicker, type DatePickerLocale, type DatePickerMode, type DatePickerProps, DeepSeekIcon, DownloadIcon, Drawer, type DrawerProps, DriveIcon, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Empty, EmptyTrayIcon, Field, FieldDivider, type FieldProps, FieldRow, type FieldRowProps, FieldSection, type FieldSectionProps, FileCodeIcon, FileSearchIcon, FileTypeCornerIcon, FolderAmberIcon, FolderBlueIcon, FolderClosedIcon, FolderGreenIcon, FolderVioletIcon, GeminiIcon, GoogleIcon, HangulFileIcon, Header, type HeaderNavItem, type HeaderProps, HeadingIcon, HtmlFileIcon, ICON_NODES, Icon, type IconProps, ImageIcon, ImportIcon, IndentIcon, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, ItalicIcon, KbCard, type KbCardMetadataItem, type KbCardProps, KeyRoundIcon, type LanguageItem, LayersIcon, LayoutGridIcon, LineChartIcon, LinkIcon, ListIcon, ListOrderedIcon, MarkdownFileIcon, MarkdownMessage, Menubar, MenubarContent, MenubarGroup, MenubarItem, MenubarMenu, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, MessageCircleIcon, MessageFooter, type MessageFooterProps, MessagesSquareIcon, Modal, type ModalProps, MyPageIcon, type NavDropdownItem, type NotificationItem, NumberBadge, type NumberBadgeProps, OpenAiIcon, OutdentIcon, Pagination, PanelLeftIcon, PdfFileIcon, PenLineIcon, PencilLineIcon, PresentationIcon, Progress, type ProgressProps, type ProgressThreshold, Providers, RefreshCwIcon, RyaiLogoIcon, SearchInput, type SearchInputProps, SegmentedControl, Select, type SelectGroup, type SelectOption, type SelectProps, Sheet, SheetFileIcon, ShoppingBagIcon, Sidebar, SidebarLink, type SidebarMainMenuItem, type SidebarSubMenuItem, type SidebarUtilityItem, Skeleton, type SkeletonProps, SlideFileIcon, Slider, SmileIcon, type SortDirection, SortIcon, SparklesIcon, SquareCheckIcon, SquareCheckOutlineIcon, StarIcon, Stepper, type StepperProps, StrikethroughIcon, Switch, SwitchField, type SwitchFieldProps, type TabItem, Table, type TableColumn, type TablePaginationConfig, TablePropertiesIcon, type TableProps, type TableSortingItem, Tabs, type TabsProps, Toggle, ToggleGroup, type ToggleGroupItemData, type ToggleGroupProps, type ToggleProps, Tooltip, type TooltipProps, TooltipProvider, TooltipWithIcon, type TooltipWithIconProps, TrashIcon, UpstageIcon, type UserMenuSection, type UserMenuSectionItem, UserMessageBubble, WandSparklesIcon, WordFileIcon, buttonVariants, toggleBaseClasses, toggleSizeClasses };
1551
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, AgentBlogIcon, AgentCsIcon, AgentDataIcon, AgentHrIcon, AgentMailIcon, AgentTrendIcon, AiAgentIcon, AiBuilderIcon, AiCloudIcon, AiDatacenterIcon, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AlignJustifyIcon, AlignLeftIcon, ArrowDownIcon, Avatar, AvatarGroup, type AvatarGroupItem, type AvatarGroupProps, type AvatarProps, type AvatarSize, BADGE_VARIANT_STYLES, Badge, type BadgeProps, type BadgeVariant, BlockquoteIcon, BoldIcon, BookOpenIcon, BookUpIcon, Breadcrumb, Button, type ButtonProps, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, CheckboxCard, type CheckboxCardProps, type CheckboxProps, ChevronsUpDownIcon, ChoiceCardGroup, type ChoiceCardGroupProps, ChoiceCardItem, type ChoiceCardItemProps, CircleCheckFillIcon, CircleHelpIcon, CircleIndicator, type CircleIndicatorProps, CircleOutlineIcon, ClaudeIcon, CodeIcon, CodeSquareIcon, Collapsible, CollapsibleContent, type CollapsibleProps, CollapsibleRoot, CollapsibleTrigger, type CollapsibleWorkspace, Combobox, type ComboboxOption, type ComboboxProps, CreditIcon, DataSection, type DataSectionProps, DatePicker, type DatePickerLocale, type DatePickerMode, type DatePickerProps, type DateRange, DeepSeekIcon, DownloadIcon, Drawer, type DrawerProps, DriveIcon, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Empty, EmptyTrayIcon, Field, FieldDivider, type FieldProps, FieldRow, type FieldRowProps, FieldSection, type FieldSectionProps, FileCodeIcon, FileSearchIcon, FileTypeCornerIcon, FolderAmberIcon, FolderBlueIcon, FolderClosedIcon, FolderGreenIcon, FolderVioletIcon, GeminiIcon, GoogleIcon, HangulFileIcon, Header, type HeaderNavItem, type HeaderProps, HeadingIcon, HtmlFileIcon, ICON_NODES, Icon, type IconProps, ImageIcon, ImportIcon, IndentIcon, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, ItalicIcon, KbCard, type KbCardMetadataItem, type KbCardProps, KeyRoundIcon, type LanguageItem, LayersIcon, LayoutGridIcon, LineChartIcon, LinkIcon, ListIcon, ListOrderedIcon, MarkdownFileIcon, MarkdownMessage, Menubar, MenubarContent, MenubarGroup, MenubarItem, MenubarMenu, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, MessageCircleIcon, MessageFooter, type MessageFooterProps, MessagesSquareIcon, Modal, type ModalProps, MyPageIcon, type NavDropdownItem, type NotificationItem, NumberBadge, type NumberBadgeProps, OpenAiIcon, OutdentIcon, Pagination, PanelLeftIcon, PdfFileIcon, PenLineIcon, PencilLineIcon, PresentationIcon, Progress, type ProgressProps, type ProgressThreshold, Providers, RefreshCwIcon, RyaiLogoIcon, SearchInput, type SearchInputProps, SegmentedControl, Select, type SelectGroup, type SelectOption, type SelectProps, Sheet, SheetFileIcon, ShoppingBagIcon, Sidebar, SidebarLink, type SidebarMainMenuItem, type SidebarSubMenuItem, type SidebarUtilityItem, Skeleton, type SkeletonProps, SlideFileIcon, Slider, SmileIcon, type SortDirection, SortIcon, SparklesIcon, SquareCheckIcon, SquareCheckOutlineIcon, StarIcon, Stepper, type StepperProps, StrikethroughIcon, Switch, SwitchField, type SwitchFieldProps, type TabItem, Table, type TableColumn, type TablePaginationConfig, TablePropertiesIcon, type TableProps, type TableSortingItem, Tabs, type TabsProps, Toggle, ToggleGroup, type ToggleGroupItemData, type ToggleGroupProps, type ToggleProps, Tooltip, type TooltipProps, TooltipProvider, TooltipWithIcon, type TooltipWithIconProps, TrashIcon, UpstageIcon, type UserMenuSection, type UserMenuSectionItem, UserMessageBubble, WandSparklesIcon, WordFileIcon, buttonVariants, toggleBaseClasses, toggleSizeClasses };
package/dist/index.d.ts CHANGED
@@ -309,28 +309,35 @@ interface ComboboxProps {
309
309
  declare function Combobox({ options, value, onValueChange, placeholder, searchPlaceholder, showSearch, footer, className, disabled, }: ComboboxProps): react_jsx_runtime.JSX.Element;
310
310
 
311
311
  type DatePickerLocale = 'ko' | 'en' | 'jp';
312
- type DatePickerMode = 'date' | 'offset';
312
+ type DatePickerMode = 'date' | 'offset' | 'range';
313
+ type DateRange = {
314
+ start?: Date;
315
+ end?: Date;
316
+ };
313
317
  interface DatePickerProps {
314
- /** Controlled value */
318
+ /** Controlled value (date / offset modes) */
315
319
  value?: Date;
316
- /** Uncontrolled default value */
320
+ /** Uncontrolled default value (date / offset modes) */
317
321
  defaultValue?: Date;
318
- /** Called when user selects a date */
322
+ /** Called when user selects a date (date / offset modes) */
319
323
  onChange?: (date: Date | undefined) => void;
320
324
  /**
321
- * 'date' — trigger shows formatted date (e.g. "June 01, 2025")
325
+ * 'date' — trigger shows formatted date (e.g. "June 01, 2025")
322
326
  * 'offset' — trigger shows days-from-today (e.g. "In 2 days")
327
+ * 'range' — user interactively picks start + end; use range / onRangeChange
323
328
  */
324
329
  mode?: DatePickerMode;
330
+ /** Controlled range value. Used when mode='range'. */
331
+ range?: DateRange;
332
+ /** Uncontrolled default range. Used when mode='range'. */
333
+ defaultRange?: DateRange;
334
+ /** Called when the selected range changes. Used when mode='range'. */
335
+ onRangeChange?: (range: DateRange) => void;
325
336
  /** When true, dates before today cannot be selected and prev-month nav is blocked at current month */
326
337
  disablePast?: boolean;
327
338
  locale?: DatePickerLocale;
328
339
  /** Override the placeholder shown when no date is selected */
329
340
  placeholder?: string;
330
- /**
331
- * Receives the selected date and returns a helper string rendered below the trigger.
332
- * Only shown when mode='offset' and a date is selected.
333
- */
334
341
  className?: string;
335
342
  /**
336
343
  * [minYear, maxYear] for the year dropdown.
@@ -341,7 +348,7 @@ interface DatePickerProps {
341
348
  showTodayLabel?: boolean;
342
349
  disabled?: boolean;
343
350
  }
344
- declare function DatePicker({ value, defaultValue, onChange, mode, disablePast, locale, placeholder, className, yearRange, showTodayLabel, disabled, }: DatePickerProps): react_jsx_runtime.JSX.Element;
351
+ declare function DatePicker({ value, defaultValue, onChange, mode, range, defaultRange, onRangeChange, disablePast, locale, placeholder, className, yearRange, showTodayLabel, disabled, }: DatePickerProps): react_jsx_runtime.JSX.Element;
345
352
 
346
353
  interface FieldProps {
347
354
  /** 필드 레이블 */
@@ -707,6 +714,8 @@ type SidebarSubMenuItem = {
707
714
  titleBadge?: string | number;
708
715
  onClick?: () => void;
709
716
  isExternal?: boolean;
717
+ /** 아이템 행 우측에 렌더링되는 커스텀 콘텐츠. 링크 외부에 위치하므로 버튼 등 인터랙티브 요소를 포함할 수 있습니다. */
718
+ rightContent?: React$1.ReactNode;
710
719
  };
711
720
  type SidebarMainMenuItem = {
712
721
  type?: 'item';
@@ -744,7 +753,7 @@ declare function SidebarLink({ href, className, style, onClick, children, }: {
744
753
  onClick?: () => void;
745
754
  children: React$1.ReactNode;
746
755
  }): React$1.ReactElement<unknown, string | React$1.JSXElementConstructor<any>>;
747
- declare function Sidebar({ logo, menus, avatar, utilities, panelTopContent, panelCenterContent, panelBottomContent, className, LinkComponent, }: {
756
+ declare function Sidebar({ logo, menus, avatar, utilities, panelTopContent, panelCenterContent, panelBottomContent, className, LinkComponent, isPanelOpen: isPanelOpenProp, onPanelOpenChange, mainMenuIconSize, }: {
748
757
  logo: React$1.ReactNode;
749
758
  menus: SidebarMainMenuItem[];
750
759
  avatar: React$1.ReactNode;
@@ -754,6 +763,20 @@ declare function Sidebar({ logo, menus, avatar, utilities, panelTopContent, pane
754
763
  panelBottomContent?: React$1.ReactNode;
755
764
  className?: string;
756
765
  LinkComponent: SidebarLinkComponent;
766
+ /**
767
+ * 서브메뉴 패널의 열림 상태를 외부에서 제어합니다.
768
+ * - `true` / `false`: controlled 모드 — subMenus 배열 길이와 관계없이 이 값을 따릅니다.
769
+ * - `undefined` (기본값): uncontrolled 모드 — activeMenu의 subMenus가 있을 때 자동으로 열립니다.
770
+ */
771
+ isPanelOpen?: boolean;
772
+ /** 패널 열림 상태가 변경될 때 호출됩니다. controlled / uncontrolled 모두 동작합니다. */
773
+ onPanelOpenChange?: (isOpen: boolean) => void;
774
+ /**
775
+ * 좌측 메인 메뉴(내비게이터) 아이콘 컨테이너 크기.
776
+ * - `'md'` (기본값): 32px
777
+ * - `'lg'`: 40px
778
+ */
779
+ mainMenuIconSize?: 'md' | 'lg';
757
780
  }): react_jsx_runtime.JSX.Element;
758
781
 
759
782
  interface SkeletonProps extends React$1.HTMLAttributes<HTMLDivElement> {
@@ -1525,4 +1548,4 @@ declare function WordFileIcon({ className }: {
1525
1548
  className?: string;
1526
1549
  }): react_jsx_runtime.JSX.Element;
1527
1550
 
1528
- export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, AgentBlogIcon, AgentCsIcon, AgentDataIcon, AgentHrIcon, AgentMailIcon, AgentTrendIcon, AiAgentIcon, AiBuilderIcon, AiCloudIcon, AiDatacenterIcon, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AlignJustifyIcon, AlignLeftIcon, ArrowDownIcon, Avatar, AvatarGroup, type AvatarGroupItem, type AvatarGroupProps, type AvatarProps, type AvatarSize, BADGE_VARIANT_STYLES, Badge, type BadgeProps, type BadgeVariant, BlockquoteIcon, BoldIcon, BookOpenIcon, BookUpIcon, Breadcrumb, Button, type ButtonProps, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, CheckboxCard, type CheckboxCardProps, type CheckboxProps, ChevronsUpDownIcon, ChoiceCardGroup, type ChoiceCardGroupProps, ChoiceCardItem, type ChoiceCardItemProps, CircleCheckFillIcon, CircleHelpIcon, CircleIndicator, type CircleIndicatorProps, CircleOutlineIcon, ClaudeIcon, CodeIcon, CodeSquareIcon, Collapsible, CollapsibleContent, type CollapsibleProps, CollapsibleRoot, CollapsibleTrigger, type CollapsibleWorkspace, Combobox, type ComboboxOption, type ComboboxProps, CreditIcon, DataSection, type DataSectionProps, DatePicker, type DatePickerLocale, type DatePickerMode, type DatePickerProps, DeepSeekIcon, DownloadIcon, Drawer, type DrawerProps, DriveIcon, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Empty, EmptyTrayIcon, Field, FieldDivider, type FieldProps, FieldRow, type FieldRowProps, FieldSection, type FieldSectionProps, FileCodeIcon, FileSearchIcon, FileTypeCornerIcon, FolderAmberIcon, FolderBlueIcon, FolderClosedIcon, FolderGreenIcon, FolderVioletIcon, GeminiIcon, GoogleIcon, HangulFileIcon, Header, type HeaderNavItem, type HeaderProps, HeadingIcon, HtmlFileIcon, ICON_NODES, Icon, type IconProps, ImageIcon, ImportIcon, IndentIcon, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, ItalicIcon, KbCard, type KbCardMetadataItem, type KbCardProps, KeyRoundIcon, type LanguageItem, LayersIcon, LayoutGridIcon, LineChartIcon, LinkIcon, ListIcon, ListOrderedIcon, MarkdownFileIcon, MarkdownMessage, Menubar, MenubarContent, MenubarGroup, MenubarItem, MenubarMenu, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, MessageCircleIcon, MessageFooter, type MessageFooterProps, MessagesSquareIcon, Modal, type ModalProps, MyPageIcon, type NavDropdownItem, type NotificationItem, NumberBadge, type NumberBadgeProps, OpenAiIcon, OutdentIcon, Pagination, PanelLeftIcon, PdfFileIcon, PenLineIcon, PencilLineIcon, PresentationIcon, Progress, type ProgressProps, type ProgressThreshold, Providers, RefreshCwIcon, RyaiLogoIcon, SearchInput, type SearchInputProps, SegmentedControl, Select, type SelectGroup, type SelectOption, type SelectProps, Sheet, SheetFileIcon, ShoppingBagIcon, Sidebar, SidebarLink, type SidebarMainMenuItem, type SidebarSubMenuItem, type SidebarUtilityItem, Skeleton, type SkeletonProps, SlideFileIcon, Slider, SmileIcon, type SortDirection, SortIcon, SparklesIcon, SquareCheckIcon, SquareCheckOutlineIcon, StarIcon, Stepper, type StepperProps, StrikethroughIcon, Switch, SwitchField, type SwitchFieldProps, type TabItem, Table, type TableColumn, type TablePaginationConfig, TablePropertiesIcon, type TableProps, type TableSortingItem, Tabs, type TabsProps, Toggle, ToggleGroup, type ToggleGroupItemData, type ToggleGroupProps, type ToggleProps, Tooltip, type TooltipProps, TooltipProvider, TooltipWithIcon, type TooltipWithIconProps, TrashIcon, UpstageIcon, type UserMenuSection, type UserMenuSectionItem, UserMessageBubble, WandSparklesIcon, WordFileIcon, buttonVariants, toggleBaseClasses, toggleSizeClasses };
1551
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, AgentBlogIcon, AgentCsIcon, AgentDataIcon, AgentHrIcon, AgentMailIcon, AgentTrendIcon, AiAgentIcon, AiBuilderIcon, AiCloudIcon, AiDatacenterIcon, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AlignJustifyIcon, AlignLeftIcon, ArrowDownIcon, Avatar, AvatarGroup, type AvatarGroupItem, type AvatarGroupProps, type AvatarProps, type AvatarSize, BADGE_VARIANT_STYLES, Badge, type BadgeProps, type BadgeVariant, BlockquoteIcon, BoldIcon, BookOpenIcon, BookUpIcon, Breadcrumb, Button, type ButtonProps, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, CheckboxCard, type CheckboxCardProps, type CheckboxProps, ChevronsUpDownIcon, ChoiceCardGroup, type ChoiceCardGroupProps, ChoiceCardItem, type ChoiceCardItemProps, CircleCheckFillIcon, CircleHelpIcon, CircleIndicator, type CircleIndicatorProps, CircleOutlineIcon, ClaudeIcon, CodeIcon, CodeSquareIcon, Collapsible, CollapsibleContent, type CollapsibleProps, CollapsibleRoot, CollapsibleTrigger, type CollapsibleWorkspace, Combobox, type ComboboxOption, type ComboboxProps, CreditIcon, DataSection, type DataSectionProps, DatePicker, type DatePickerLocale, type DatePickerMode, type DatePickerProps, type DateRange, DeepSeekIcon, DownloadIcon, Drawer, type DrawerProps, DriveIcon, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Empty, EmptyTrayIcon, Field, FieldDivider, type FieldProps, FieldRow, type FieldRowProps, FieldSection, type FieldSectionProps, FileCodeIcon, FileSearchIcon, FileTypeCornerIcon, FolderAmberIcon, FolderBlueIcon, FolderClosedIcon, FolderGreenIcon, FolderVioletIcon, GeminiIcon, GoogleIcon, HangulFileIcon, Header, type HeaderNavItem, type HeaderProps, HeadingIcon, HtmlFileIcon, ICON_NODES, Icon, type IconProps, ImageIcon, ImportIcon, IndentIcon, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, ItalicIcon, KbCard, type KbCardMetadataItem, type KbCardProps, KeyRoundIcon, type LanguageItem, LayersIcon, LayoutGridIcon, LineChartIcon, LinkIcon, ListIcon, ListOrderedIcon, MarkdownFileIcon, MarkdownMessage, Menubar, MenubarContent, MenubarGroup, MenubarItem, MenubarMenu, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, MessageCircleIcon, MessageFooter, type MessageFooterProps, MessagesSquareIcon, Modal, type ModalProps, MyPageIcon, type NavDropdownItem, type NotificationItem, NumberBadge, type NumberBadgeProps, OpenAiIcon, OutdentIcon, Pagination, PanelLeftIcon, PdfFileIcon, PenLineIcon, PencilLineIcon, PresentationIcon, Progress, type ProgressProps, type ProgressThreshold, Providers, RefreshCwIcon, RyaiLogoIcon, SearchInput, type SearchInputProps, SegmentedControl, Select, type SelectGroup, type SelectOption, type SelectProps, Sheet, SheetFileIcon, ShoppingBagIcon, Sidebar, SidebarLink, type SidebarMainMenuItem, type SidebarSubMenuItem, type SidebarUtilityItem, Skeleton, type SkeletonProps, SlideFileIcon, Slider, SmileIcon, type SortDirection, SortIcon, SparklesIcon, SquareCheckIcon, SquareCheckOutlineIcon, StarIcon, Stepper, type StepperProps, StrikethroughIcon, Switch, SwitchField, type SwitchFieldProps, type TabItem, Table, type TableColumn, type TablePaginationConfig, TablePropertiesIcon, type TableProps, type TableSortingItem, Tabs, type TabsProps, Toggle, ToggleGroup, type ToggleGroupItemData, type ToggleGroupProps, type ToggleProps, Tooltip, type TooltipProps, TooltipProvider, TooltipWithIcon, type TooltipWithIconProps, TrashIcon, UpstageIcon, type UserMenuSection, type UserMenuSectionItem, UserMessageBubble, WandSparklesIcon, WordFileIcon, buttonVariants, toggleBaseClasses, toggleSizeClasses };
package/dist/index.js CHANGED
@@ -2322,7 +2322,8 @@ var LOCALE_CONFIG = {
2322
2322
  if (days === 1) return "In 1 day";
2323
2323
  return `In ${days} days`;
2324
2324
  },
2325
- defaultPlaceholder: "Select a date"
2325
+ defaultPlaceholder: "Select a date",
2326
+ defaultRangePlaceholder: "Select date range"
2326
2327
  },
2327
2328
  ko: {
2328
2329
  dayHeaders: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"],
@@ -2333,7 +2334,8 @@ var LOCALE_CONFIG = {
2333
2334
  if (days === 0) return "\uC624\uB298";
2334
2335
  return `${days}\uC77C \uD6C4`;
2335
2336
  },
2336
- defaultPlaceholder: "\uB0A0\uC9DC \uC120\uD0DD"
2337
+ defaultPlaceholder: "\uB0A0\uC9DC \uC120\uD0DD",
2338
+ defaultRangePlaceholder: "\uB0A0\uC9DC \uBC94\uC704 \uC120\uD0DD"
2337
2339
  },
2338
2340
  jp: {
2339
2341
  dayHeaders: ["\u65E5", "\u6708", "\u706B", "\u6C34", "\u6728", "\u91D1", "\u571F"],
@@ -2344,7 +2346,8 @@ var LOCALE_CONFIG = {
2344
2346
  if (days === 0) return "\u4ECA\u65E5";
2345
2347
  return `${days}\u65E5\u5F8C`;
2346
2348
  },
2347
- defaultPlaceholder: "\u65E5\u4ED8\u3092\u9078\u629E"
2349
+ defaultPlaceholder: "\u65E5\u4ED8\u3092\u9078\u629E",
2350
+ defaultRangePlaceholder: "\u671F\u9593\u3092\u9078\u629E"
2348
2351
  }
2349
2352
  };
2350
2353
  function startOfDay(d) {
@@ -2365,7 +2368,12 @@ function CalendarGrid({
2365
2368
  onYearChange,
2366
2369
  onMonthChange,
2367
2370
  locale,
2368
- yearRange
2371
+ yearRange,
2372
+ isRangeMode = false,
2373
+ rangeStart,
2374
+ rangeEnd,
2375
+ hoverDate,
2376
+ onHover
2369
2377
  }) {
2370
2378
  const config = LOCALE_CONFIG[locale];
2371
2379
  const todayStart = startOfDay(today);
@@ -2411,6 +2419,9 @@ function CalendarGrid({
2411
2419
  const prevYear = month === 0 ? year - 1 : year;
2412
2420
  const prevMon = month === 0 ? 11 : month - 1;
2413
2421
  const isPrevDisabled = disablePast && (prevYear < today.getFullYear() || prevYear === today.getFullYear() && prevMon < today.getMonth());
2422
+ const rangeStartTime = rangeStart ? startOfDay(rangeStart).getTime() : null;
2423
+ const rangeEndTime = rangeEnd ? startOfDay(rangeEnd).getTime() : null;
2424
+ const visualEndTime = rangeEndTime != null ? rangeEndTime : rangeStartTime !== null && hoverDate ? startOfDay(hoverDate).getTime() : null;
2414
2425
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "px-5 pt-3 pb-4", children: [
2415
2426
  /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "mb-4 flex items-center justify-between", children: [
2416
2427
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
@@ -2482,28 +2493,40 @@ function CalendarGrid({
2482
2493
  },
2483
2494
  d
2484
2495
  )) }),
2485
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "grid grid-cols-7 gap-1", children: cells.map(({ day, currentMonth, date }) => {
2486
- const dateStart = startOfDay(date);
2487
- const isSelected = (selectedStart == null ? void 0 : selectedStart.getTime()) === dateStart.getTime();
2488
- const isToday = todayStart.getTime() === dateStart.getTime();
2489
- const isPast = dateStart < todayStart;
2490
- const isDisabled = disablePast && isPast;
2491
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2492
- "button",
2493
- {
2494
- type: "button",
2495
- disabled: isDisabled,
2496
- onClick: () => onSelect(date),
2497
- className: cn(
2498
- "flex aspect-square w-full items-center justify-center rounded-lg text-sm leading-xs transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
2499
- isSelected ? "bg-foreground font-normal text-background hover:bg-foreground active:bg-foreground" : isDisabled ? "cursor-not-allowed text-foreground opacity-50" : !currentMonth ? "cursor-pointer text-foreground opacity-50 hover:bg-accent active:bg-accent" : "cursor-pointer text-foreground hover:bg-accent active:bg-accent",
2500
- isToday && !isSelected && "border border-border"
2501
- ),
2502
- children: day
2503
- },
2504
- date.toISOString()
2505
- );
2506
- }) })
2496
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2497
+ "div",
2498
+ {
2499
+ className: "grid grid-cols-7 gap-1",
2500
+ onMouseLeave: () => onHover == null ? void 0 : onHover(void 0),
2501
+ children: cells.map(({ day, currentMonth, date }) => {
2502
+ const dateStart = startOfDay(date);
2503
+ const t = dateStart.getTime();
2504
+ const isToday = todayStart.getTime() === t;
2505
+ const isPast = dateStart < todayStart;
2506
+ const isDisabled = disablePast && isPast;
2507
+ const isRangeStart = isRangeMode && rangeStartTime !== null && t === rangeStartTime;
2508
+ const isRangeEnd = isRangeMode && rangeEndTime !== null && t === rangeEndTime;
2509
+ const isInRange = isRangeMode && rangeStartTime !== null && visualEndTime !== null && !isRangeStart && !isRangeEnd && t > Math.min(rangeStartTime, visualEndTime) && t < Math.max(rangeStartTime, visualEndTime);
2510
+ const isSelected = isRangeMode ? isRangeStart || isRangeEnd : (selectedStart == null ? void 0 : selectedStart.getTime()) === t;
2511
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2512
+ "button",
2513
+ {
2514
+ type: "button",
2515
+ disabled: isDisabled,
2516
+ onClick: () => onSelect(date),
2517
+ onMouseEnter: () => onHover == null ? void 0 : onHover(date),
2518
+ className: cn(
2519
+ "flex aspect-square w-full items-center justify-center rounded-lg text-sm leading-xs transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
2520
+ isSelected ? "bg-foreground font-normal text-background hover:bg-foreground active:bg-foreground cursor-pointer" : isDisabled ? "cursor-not-allowed text-foreground opacity-50" : isInRange ? "bg-accent cursor-pointer text-foreground" : !currentMonth ? "cursor-pointer text-foreground opacity-50 hover:bg-accent active:bg-accent" : "cursor-pointer text-foreground hover:bg-accent active:bg-accent",
2521
+ isToday && !isSelected && !isInRange && "border border-border"
2522
+ ),
2523
+ children: day
2524
+ },
2525
+ date.toISOString()
2526
+ );
2527
+ })
2528
+ }
2529
+ )
2507
2530
  ] });
2508
2531
  }
2509
2532
  function DatePicker({
@@ -2511,6 +2534,9 @@ function DatePicker({
2511
2534
  defaultValue,
2512
2535
  onChange,
2513
2536
  mode = "date",
2537
+ range,
2538
+ defaultRange,
2539
+ onRangeChange,
2514
2540
  disablePast = false,
2515
2541
  locale = "en",
2516
2542
  placeholder,
@@ -2519,43 +2545,90 @@ function DatePicker({
2519
2545
  showTodayLabel = false,
2520
2546
  disabled = false
2521
2547
  }) {
2548
+ var _a;
2522
2549
  const today = React11.useMemo(() => /* @__PURE__ */ new Date(), []);
2523
2550
  const config = LOCALE_CONFIG[locale];
2524
2551
  const [open, setOpen] = React11.useState(false);
2525
- const [selected, setSelected] = React11.useState(
2526
- defaultValue
2527
- );
2552
+ const [selected, setSelected] = React11.useState(defaultValue);
2528
2553
  const activeDate = value !== void 0 ? value : selected;
2529
- const [viewYear, setViewYear] = React11.useState(
2530
- () => (activeDate != null ? activeDate : today).getFullYear()
2531
- );
2532
- const [viewMonth, setViewMonth] = React11.useState(
2533
- () => (activeDate != null ? activeDate : today).getMonth()
2534
- );
2554
+ const [internalRange, setInternalRange] = React11.useState(
2555
+ defaultRange != null ? defaultRange : {}
2556
+ );
2557
+ const activeRange = range !== void 0 ? range : internalRange;
2558
+ const [pickingStage, setPickingStage] = React11.useState("start");
2559
+ const [hoverDate, setHoverDate] = React11.useState();
2560
+ const initialViewDate = mode === "range" ? (_a = activeRange.start) != null ? _a : today : activeDate != null ? activeDate : today;
2561
+ const [viewYear, setViewYear] = React11.useState(() => initialViewDate.getFullYear());
2562
+ const [viewMonth, setViewMonth] = React11.useState(() => initialViewDate.getMonth());
2535
2563
  const activeDateRef = React11.useRef(activeDate);
2536
2564
  activeDateRef.current = activeDate;
2565
+ const activeRangeRef = React11.useRef(activeRange);
2566
+ activeRangeRef.current = activeRange;
2537
2567
  const todayRef = React11.useRef(today);
2538
2568
  todayRef.current = today;
2569
+ const modeRef = React11.useRef(mode);
2570
+ modeRef.current = mode;
2539
2571
  React11.useEffect(() => {
2540
- var _a;
2541
- if (open) {
2542
- const d = (_a = activeDateRef.current) != null ? _a : todayRef.current;
2543
- setViewYear(d.getFullYear());
2544
- setViewMonth(d.getMonth());
2572
+ var _a2, _b;
2573
+ if (!open) {
2574
+ setHoverDate(void 0);
2575
+ setPickingStage("start");
2576
+ return;
2545
2577
  }
2578
+ const currentMode = modeRef.current;
2579
+ const d = currentMode === "range" ? (_a2 = activeRangeRef.current.start) != null ? _a2 : todayRef.current : (_b = activeDateRef.current) != null ? _b : todayRef.current;
2580
+ setViewYear(d.getFullYear());
2581
+ setViewMonth(d.getMonth());
2546
2582
  }, [open]);
2547
2583
  const effectiveYearRange = React11.useMemo(
2548
2584
  () => yearRange != null ? yearRange : [today.getFullYear() - 10, today.getFullYear() + 10],
2549
2585
  [yearRange, today]
2550
2586
  );
2551
2587
  function handleSelect(date) {
2552
- if (value === void 0) setSelected(date);
2553
- onChange == null ? void 0 : onChange(date);
2554
- setOpen(false);
2588
+ if (mode === "range") {
2589
+ if (pickingStage === "start") {
2590
+ const newRange = { start: date, end: void 0 };
2591
+ if (range === void 0) setInternalRange(newRange);
2592
+ onRangeChange == null ? void 0 : onRangeChange(newRange);
2593
+ setPickingStage("end");
2594
+ } else {
2595
+ const existingStart = activeRange.start;
2596
+ let start;
2597
+ let end;
2598
+ if (existingStart && startOfDay(date) < startOfDay(existingStart)) {
2599
+ start = date;
2600
+ end = existingStart;
2601
+ } else {
2602
+ start = existingStart;
2603
+ end = date;
2604
+ }
2605
+ const newRange = { start, end };
2606
+ if (range === void 0) setInternalRange(newRange);
2607
+ onRangeChange == null ? void 0 : onRangeChange(newRange);
2608
+ setPickingStage("start");
2609
+ setOpen(false);
2610
+ }
2611
+ } else {
2612
+ if (value === void 0) setSelected(date);
2613
+ onChange == null ? void 0 : onChange(date);
2614
+ setOpen(false);
2615
+ }
2555
2616
  }
2556
2617
  let triggerText;
2557
2618
  let showCalendarIcon;
2558
- if (!activeDate) {
2619
+ if (mode === "range") {
2620
+ const { start, end } = activeRange;
2621
+ if (!start) {
2622
+ triggerText = placeholder != null ? placeholder : config.defaultRangePlaceholder;
2623
+ showCalendarIcon = false;
2624
+ } else if (!end) {
2625
+ triggerText = `${config.formatTriggerDate(start)} \u2192`;
2626
+ showCalendarIcon = true;
2627
+ } else {
2628
+ triggerText = `${config.formatTriggerDate(start)} \u2192 ${config.formatTriggerDate(end)}`;
2629
+ showCalendarIcon = true;
2630
+ }
2631
+ } else if (!activeDate) {
2559
2632
  triggerText = placeholder != null ? placeholder : config.defaultPlaceholder;
2560
2633
  showCalendarIcon = false;
2561
2634
  } else if (mode === "offset") {
@@ -2583,7 +2656,7 @@ function DatePicker({
2583
2656
  "flex h-9 w-full items-center justify-between rounded-xl border border-border bg-background px-4",
2584
2657
  "text-sm transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
2585
2658
  disabled ? "bg-muted opacity-60 cursor-not-allowed" : "hover:bg-accent cursor-pointer",
2586
- !activeDate && "text-muted-foreground"
2659
+ mode === "range" ? !activeRange.start && "text-muted-foreground" : !activeDate && "text-muted-foreground"
2587
2660
  ),
2588
2661
  children: [
2589
2662
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "truncate text-left", children: triggerText }),
@@ -2611,7 +2684,6 @@ function DatePicker({
2611
2684
  {
2612
2685
  align: "start",
2613
2686
  sideOffset: 4,
2614
- style: { minWidth: "var(--radix-popover-trigger-width)" },
2615
2687
  className: cn(
2616
2688
  "z-50 w-64 rounded-2xl border border-border bg-background",
2617
2689
  "shadow-dropdown",
@@ -2632,7 +2704,12 @@ function DatePicker({
2632
2704
  onYearChange: setViewYear,
2633
2705
  onMonthChange: setViewMonth,
2634
2706
  locale,
2635
- yearRange: effectiveYearRange
2707
+ yearRange: effectiveYearRange,
2708
+ isRangeMode: mode === "range",
2709
+ rangeStart: activeRange.start,
2710
+ rangeEnd: activeRange.end,
2711
+ hoverDate: mode === "range" && pickingStage === "end" ? hoverDate : void 0,
2712
+ onHover: mode === "range" ? setHoverDate : void 0
2636
2713
  }
2637
2714
  )
2638
2715
  }
@@ -4983,10 +5060,15 @@ function Sidebar({
4983
5060
  panelCenterContent,
4984
5061
  panelBottomContent,
4985
5062
  className,
4986
- LinkComponent
5063
+ LinkComponent,
5064
+ isPanelOpen: isPanelOpenProp,
5065
+ onPanelOpenChange,
5066
+ mainMenuIconSize = "md"
4987
5067
  }) {
4988
5068
  var _a, _b, _c;
4989
- const [isPanelOpen, setIsPanelOpen] = React22.useState(true);
5069
+ const isControlled = isPanelOpenProp !== void 0;
5070
+ const [internalIsPanelOpen, setInternalIsPanelOpen] = React22.useState(true);
5071
+ const resolvedIsPanelOpen = isControlled ? isPanelOpenProp : internalIsPanelOpen;
4990
5072
  const activeMenu = React22.useMemo(
4991
5073
  () => {
4992
5074
  var _a2;
@@ -4995,12 +5077,28 @@ function Sidebar({
4995
5077
  [menus]
4996
5078
  );
4997
5079
  const subMenus = (_a = activeMenu == null ? void 0 : activeMenu.subMenus) != null ? _a : [];
5080
+ const panelVisible = isControlled ? resolvedIsPanelOpen : resolvedIsPanelOpen && subMenus.length > 0;
5081
+ const handleSetPanelOpen = React22.useCallback(
5082
+ (open) => {
5083
+ if (!isControlled) setInternalIsPanelOpen(open);
5084
+ onPanelOpenChange == null ? void 0 : onPanelOpenChange(open);
5085
+ },
5086
+ [isControlled, onPanelOpenChange]
5087
+ );
5088
+ const prevPanelVisibleRef = React22.useRef(null);
5089
+ React22.useEffect(() => {
5090
+ if (prevPanelVisibleRef.current !== panelVisible) {
5091
+ prevPanelVisibleRef.current = panelVisible;
5092
+ onPanelOpenChange == null ? void 0 : onPanelOpenChange(panelVisible);
5093
+ }
5094
+ }, [panelVisible, onPanelOpenChange]);
5095
+ const iconContainerClass = mainMenuIconSize === "lg" ? "size-10" : "size-8";
4998
5096
  return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(SidebarLinkProvider, { LinkComponent, children: /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
4999
5097
  "aside",
5000
5098
  {
5001
5099
  className: cn(
5002
5100
  "flex h-full bg-background shrink-0 transition-[width]",
5003
- isPanelOpen && subMenus.length > 0 ? "w-70" : "w-17",
5101
+ panelVisible ? "w-70" : "w-17",
5004
5102
  className
5005
5103
  ),
5006
5104
  children: [
@@ -5040,8 +5138,13 @@ function Sidebar({
5040
5138
  href: item.href,
5041
5139
  onClick: () => {
5042
5140
  var _a2;
5043
- const hasSubMenus = item.subMenus && item.subMenus.length > 0;
5044
- if (hasSubMenus && !isPanelOpen) setIsPanelOpen(true);
5141
+ if (!isControlled) {
5142
+ const hasSubMenus = item.subMenus && item.subMenus.length > 0;
5143
+ if (hasSubMenus && !internalIsPanelOpen) {
5144
+ setInternalIsPanelOpen(true);
5145
+ onPanelOpenChange == null ? void 0 : onPanelOpenChange(true);
5146
+ }
5147
+ }
5045
5148
  (_a2 = item.onClick) == null ? void 0 : _a2.call(item);
5046
5149
  },
5047
5150
  className: "flex flex-col items-center cursor-pointer",
@@ -5051,7 +5154,8 @@ function Sidebar({
5051
5154
  "div",
5052
5155
  {
5053
5156
  className: cn(
5054
- "relative flex items-center justify-center rounded-md size-8 transition-colors",
5157
+ "relative flex items-center justify-center rounded-md transition-colors",
5158
+ iconContainerClass,
5055
5159
  item.isActive ? "bg-accent" : "hover:bg-sidebar-accent"
5056
5160
  ),
5057
5161
  children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "flex items-center justify-center size-5 shrink-0 [&_svg]:size-full", children: item.icon })
@@ -5125,7 +5229,7 @@ function Sidebar({
5125
5229
  {
5126
5230
  className: cn(
5127
5231
  "flex flex-col flex-1 h-full min-h-0 min-w-0",
5128
- (!isPanelOpen || !subMenus.length) && "hidden"
5232
+ !panelVisible && "hidden"
5129
5233
  ),
5130
5234
  children: [
5131
5235
  /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "flex flex-col shrink-0 w-full", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "flex flex-col items-start justify-center p-2", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
@@ -5140,7 +5244,7 @@ function Sidebar({
5140
5244
  {
5141
5245
  type: "button",
5142
5246
  "aria-label": "\uD328\uB110 \uB2EB\uAE30",
5143
- onClick: () => setIsPanelOpen(false),
5247
+ onClick: () => handleSetPanelOpen(false),
5144
5248
  className: "flex items-center justify-center p-2 rounded-lg text-sidebar-foreground hover:bg-sidebar-accent transition-colors cursor-pointer",
5145
5249
  children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(PanelLeftIcon, { className: "size-4" })
5146
5250
  }
@@ -5149,23 +5253,29 @@ function Sidebar({
5149
5253
  }
5150
5254
  ) }) }),
5151
5255
  /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex flex-col flex-1 min-h-0", children: [
5152
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "flex flex-col p-2 shrink-0 w-full", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "flex flex-col gap-0.5", children: subMenus.map((item) => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
5256
+ subMenus.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "flex flex-col p-2 shrink-0 w-full", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "flex flex-col gap-0.5", children: subMenus.map((item) => /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
5153
5257
  "div",
5154
5258
  {
5155
- className: cn("rounded-md", item.isActive && "bg-accent"),
5156
- children: /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
5157
- SidebarLink,
5158
- {
5159
- href: item.href,
5160
- onClick: item.onClick,
5161
- className: "flex gap-2 h-8 items-center p-2 rounded-md hover:bg-sidebar-accent transition-colors",
5162
- children: [
5163
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "flex items-center justify-center size-4 shrink-0 [&_svg]:size-full", children: item.icon }),
5164
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "flex-1 min-w-0 text-sm font-normal leading-5 tracking-tight overflow-hidden text-ellipsis whitespace-nowrap text-foreground", children: item.title }),
5165
- item.isExternal && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "flex items-center justify-center shrink-0 text-[#8C8C8C]", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_lucide_react4.ArrowUpRight, { size: 12, strokeWidth: 1.5 }) })
5166
- ]
5167
- }
5168
- )
5259
+ className: cn(
5260
+ "group flex items-center rounded-md transition-colors",
5261
+ item.isActive ? "bg-accent" : "hover:bg-sidebar-accent"
5262
+ ),
5263
+ children: [
5264
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
5265
+ SidebarLink,
5266
+ {
5267
+ href: item.href,
5268
+ onClick: item.onClick,
5269
+ className: "flex gap-2 flex-1 h-8 items-center px-2 min-w-0",
5270
+ children: [
5271
+ item.icon && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "flex items-center justify-center size-4 shrink-0 [&_svg]:size-full", children: item.icon }),
5272
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "flex-1 min-w-0 text-sm font-normal leading-5 tracking-tight overflow-hidden text-ellipsis whitespace-nowrap text-foreground", children: item.title }),
5273
+ item.isExternal && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "flex items-center justify-center shrink-0 text-[#8C8C8C]", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_lucide_react4.ArrowUpRight, { size: 12, strokeWidth: 1.5 }) })
5274
+ ]
5275
+ }
5276
+ ),
5277
+ item.rightContent && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "shrink-0 pr-1", children: item.rightContent })
5278
+ ]
5169
5279
  },
5170
5280
  item.id
5171
5281
  )) }) }),