@farmzone/fz-react-ui 1.1.5 → 1.1.7

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.cts CHANGED
@@ -91,6 +91,8 @@ interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
91
91
  leftIcon?: ReactNode;
92
92
  rightIcon?: ReactNode;
93
93
  showPasswordToggle?: boolean;
94
+ clearable?: boolean;
95
+ onClear?: () => void;
94
96
  }
95
97
  declare function Input(props: InputProps): react.JSX.Element;
96
98
 
@@ -194,6 +196,9 @@ interface SelectOptionType {
194
196
  label: string | ReactNode;
195
197
  value: string;
196
198
  disabled?: boolean;
199
+ icon?: ReactNode;
200
+ avatarUrl?: string;
201
+ avatarAlt?: string;
197
202
  }
198
203
 
199
204
  interface SelectProps<T extends SelectOptionType = SelectOptionType> extends Omit<React.ComponentProps<typeof Select$1>, "onValueChange" | "value" | "defaultValue"> {
@@ -973,6 +978,8 @@ type InputOption<P> = BaseOption<P> & {
973
978
  placeholder?: string;
974
979
  /** 입력창 왼쪽에 돋보기 아이콘을 보여줄지 여부. 기본값 true. */
975
980
  leftIcon?: boolean;
981
+ /** 입력값이 있을 때 x(clear) 버튼을 보여줄지 여부. 기본값 true. */
982
+ canReset?: boolean;
976
983
  };
977
984
  type SelectOption<P> = BaseOption<P> & {
978
985
  type: "select";
@@ -1089,18 +1096,42 @@ interface MultiTabBarProps {
1089
1096
  * 전달하지 않으면(undefined) 기존과 완전히 동일한 평면(flat) 탭 목록으로 렌더링됩니다.
1090
1097
  *
1091
1098
  * 전달하면: 같은 key를 가진 탭들이 배열 안에서 서로 떨어져 있어도(다른 그룹 탭 사이에 끼어
1092
- * 있어도) 항상 그 그룹이 처음 등장한 위치의 칩 하나로 합쳐져서 색상 칩(그룹 헤더) + 그 아래
1093
- * 탭들로 렌더링됩니다 — 지금 fizza 프로젝트가 쓰던 커스텀 그룹 탭바와 동일한 형태이고, 이미
1099
+ * 있어도) 항상 그 그룹이 처음 등장한 위치의 칩 하나로 합쳐져서 Chrome 탭 그룹처럼 색상 칩(그룹
1100
+ * 라벨) + 그 옆 탭들 + 탭들 바닥을 잇는 그룹 색 하단선으로 렌더링됩니다. 이미
1094
1101
  * 열려 있는 그룹에 새 탭이 추가될 때 중복 칩이 생기지 않습니다.
1095
1102
  * 그룹 색상은 고정된 팔레트(파랑/주황/빨강/초록 + 보조 6색)에서 등장 순서대로 할당되고,
1096
- * 배경은 12% 투명도 틴트, 테두리는 40% 투명도로 렌더링됩니다 — fizza 프로젝트가 쓰던
1097
- * GroupedTabBar와 동일한 색상 스펙입니다.
1103
+ * 칩 배경·하단선·활성 탭 테두리에 같은 그룹 색이 쓰입니다.
1098
1104
  *
1099
1105
  * onTabsReorder를 같이 전달하면 그룹 모드에서도 드래그 앤 드롭 재정렬이 됩니다. 탭이 어느
1100
1106
  * 그룹에 속하는지는 getTabGroup이 반환하는 값으로만 정해지고 배열 위치와는 무관하므로,
1101
1107
  * 자유롭게 순서를 바꿔도 그룹 소속은 항상 그대로 유지됩니다.
1102
1108
  */
1103
1109
  getTabGroup?: (tab: MultiTab) => MultiTabGroupInfo | null | undefined;
1110
+ /**
1111
+ * 탭 라벨 왼쪽에 표시할 아이콘. null/undefined면 아이콘 없이 렌더링됩니다.
1112
+ */
1113
+ getTabIcon?: (tab: MultiTab) => ReactNode;
1114
+ /**
1115
+ * 탭의 더보기 메뉴 항목 — 더보기(⋯) 버튼을 줄지는 탭마다 이 함수의 반환값으로 정합니다.
1116
+ *
1117
+ * - 항목 배열을 반환한 탭: 아이콘에 마우스를 올리면 더보기 아이콘으로 바뀌고, 클릭하면 항목들이
1118
+ * Popover 메뉴로 열립니다(아이콘이 없는 탭이면 더보기 아이콘이 항상 보입니다).
1119
+ * - null/undefined/빈 배열을 반환한 탭: 더보기 버튼 없이 아이콘만 표시됩니다.
1120
+ *
1121
+ * 예) 특정 탭에만 메뉴 제공: `getTabMenuItems={(tab) => (tab.id === "settings" ? items : null)}`
1122
+ *
1123
+ * 아이콘·메뉴 영역의 클릭·포인터 이벤트는 탭 전환이나 드래그로 이어지지 않습니다.
1124
+ */
1125
+ getTabMenuItems?: (tab: MultiTab) => Array<MultiTabMenuItem> | null | undefined;
1126
+ }
1127
+ interface MultiTabMenuItem {
1128
+ key: string;
1129
+ label: ReactNode;
1130
+ /** 라벨 앞에 표시할 아이콘 (예: <Settings size={14} />) */
1131
+ icon?: ReactNode;
1132
+ /** 현재 화면에 해당하는 항목이면 true — 배경으로 강조됩니다 */
1133
+ selected?: boolean;
1134
+ onSelect: () => void;
1104
1135
  }
1105
1136
  declare function MultiTabBar(props: MultiTabBarProps): react.JSX.Element | null;
1106
1137
 
@@ -1602,4 +1633,4 @@ declare const Z_INDEX: {
1602
1633
  };
1603
1634
  type ZIndexKey = keyof typeof Z_INDEX;
1604
1635
 
1605
- export { ArrowIcon, Badge, type BadgeProps, type BaseParams, BaseUploader, type BaseUploaderProps, BreadCrumb, type BreadCrumbItem, type BreadCrumbMenuItem, type BreadCrumbProps, type BreadCrumbRoot, Button, type ButtonProps, type ButtonSize, type ButtonVariant, type CalendarYearRange, Carousel, type CarouselProps, type CarouselRef, Checkbox, type CheckboxProps, type Column, type ConfirmOptions, DatePicker, DebouncedButton, type DebouncedButtonProps, DetailContent, type DetailContentProps, type DetailField, type DetailFieldOrSection, DetailModalFrame, type DetailMode, DetailPageFrame, Empty, ExcelUploader, FilePreviewViewer, FileUploader, type FilterRow, type FormFieldConfig, Input, type InputProps, Loading, LoadingOverlay, type LoadingOverlayProps, type LoadingProps, type MentionItem, type MenuChild, type MenuGrandchild, type MenuItem, type MenuSection, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader, ModalIconHeader, type ModalIconHeaderProps, ModalOverlay, type ModalProps, type ModalType, MultiTabBar as MultiTab, type MultiTabGroupInfo, type MultiTab as MultiTabItem, PageFilter, type PageParams, Pagination, type PaginationProps, Popover, type PopoverAlign, PopoverAnchor, PopoverClose, PopoverContent, type PopoverContentProps, PopoverDescription, PopoverFooter, PopoverHeader, type PopoverPosition, PopoverTitle, PopoverTrigger, Radio, RadioGroup, type RadioGroupProps, type RadioOptionType, type RadioProps, RichEditor, RichEditorContent, type RichEditorContentProps, type RichEditorHeadingLevel, type RichEditorProps, type RichEditorThemeOverride, RichEditorToolbar, type RichEditorToolbarConfig, type RichEditorToolbarProps, ScrollArea, ScrollBar, SearchAddress, type SearchAddressProps, SearchBar, type SearchBarProps, Select, Select$1 as SelectBase, SelectContent, SelectGroup, SelectItem, SelectLabel, type SelectOptionType, type SelectProps, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Sidebar, type SidebarHeaderRenderProps, type SidebarProps, SimplePopover, type SimplePopoverProps, Skeleton, type SkeletonProps, Slider, type SliderProps, type SortOption, type SortOrder, type SortParams, Spinner, type SpinnerColor, type SpinnerProps, type SpinnerSize, SubmitForm, Switch, type SwitchProps, Tab, type TabItem, type TabProps, Table, Textarea, type TextareaProps, type ToastPosition, type ToastProps, ToastProvider, type ToastType, ToggleSwitch, Tooltip, type TooltipProps, type UseParams, type UseRichEditorOptions, type UseRichEditorReturn, type YmdDateString, type ZIndexKey, Z_INDEX, buildBreadCrumbItems, buttonVariants, cn, confirmModal, findParentMenuItem, findParentMenuName, formatDate, getFileLabel, getPreviewFileType, isCalendarDayAfterMax, isDateInRange, switchTrackSizes, textVariants, toast, useBlockModalConfirm, useBreadCrumbItems, useCustomBlocker, useDetailController, useFilePreviewViewer, useModal, useMultiTabStore, useParams, useRichEditor, useScrollToTop, useStableImageSrc, useToast, validateAndFormatInput };
1636
+ export { ArrowIcon, Badge, type BadgeProps, type BaseParams, BaseUploader, type BaseUploaderProps, BreadCrumb, type BreadCrumbItem, type BreadCrumbMenuItem, type BreadCrumbProps, type BreadCrumbRoot, Button, type ButtonProps, type ButtonSize, type ButtonVariant, type CalendarYearRange, Carousel, type CarouselProps, type CarouselRef, Checkbox, type CheckboxProps, type Column, type ConfirmOptions, DatePicker, DebouncedButton, type DebouncedButtonProps, DetailContent, type DetailContentProps, type DetailField, type DetailFieldOrSection, DetailModalFrame, type DetailMode, DetailPageFrame, Empty, ExcelUploader, FilePreviewViewer, FileUploader, type FilterRow, type FormFieldConfig, Input, type InputProps, Loading, LoadingOverlay, type LoadingOverlayProps, type LoadingProps, type MentionItem, type MenuChild, type MenuGrandchild, type MenuItem, type MenuSection, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader, ModalIconHeader, type ModalIconHeaderProps, ModalOverlay, type ModalProps, type ModalType, MultiTabBar as MultiTab, type MultiTabGroupInfo, type MultiTab as MultiTabItem, type MultiTabMenuItem, PageFilter, type PageParams, Pagination, type PaginationProps, Popover, type PopoverAlign, PopoverAnchor, PopoverClose, PopoverContent, type PopoverContentProps, PopoverDescription, PopoverFooter, PopoverHeader, type PopoverPosition, PopoverTitle, PopoverTrigger, Radio, RadioGroup, type RadioGroupProps, type RadioOptionType, type RadioProps, RichEditor, RichEditorContent, type RichEditorContentProps, type RichEditorHeadingLevel, type RichEditorProps, type RichEditorThemeOverride, RichEditorToolbar, type RichEditorToolbarConfig, type RichEditorToolbarProps, ScrollArea, ScrollBar, SearchAddress, type SearchAddressProps, SearchBar, type SearchBarProps, Select, Select$1 as SelectBase, SelectContent, SelectGroup, SelectItem, SelectLabel, type SelectOptionType, type SelectProps, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Sidebar, type SidebarHeaderRenderProps, type SidebarProps, SimplePopover, type SimplePopoverProps, Skeleton, type SkeletonProps, Slider, type SliderProps, type SortOption, type SortOrder, type SortParams, Spinner, type SpinnerColor, type SpinnerProps, type SpinnerSize, SubmitForm, Switch, type SwitchProps, Tab, type TabItem, type TabProps, Table, Textarea, type TextareaProps, type ToastPosition, type ToastProps, ToastProvider, type ToastType, ToggleSwitch, Tooltip, type TooltipProps, type UseParams, type UseRichEditorOptions, type UseRichEditorReturn, type YmdDateString, type ZIndexKey, Z_INDEX, buildBreadCrumbItems, buttonVariants, cn, confirmModal, findParentMenuItem, findParentMenuName, formatDate, getFileLabel, getPreviewFileType, isCalendarDayAfterMax, isDateInRange, switchTrackSizes, textVariants, toast, useBlockModalConfirm, useBreadCrumbItems, useCustomBlocker, useDetailController, useFilePreviewViewer, useModal, useMultiTabStore, useParams, useRichEditor, useScrollToTop, useStableImageSrc, useToast, validateAndFormatInput };
package/dist/index.d.ts CHANGED
@@ -91,6 +91,8 @@ interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
91
91
  leftIcon?: ReactNode;
92
92
  rightIcon?: ReactNode;
93
93
  showPasswordToggle?: boolean;
94
+ clearable?: boolean;
95
+ onClear?: () => void;
94
96
  }
95
97
  declare function Input(props: InputProps): react.JSX.Element;
96
98
 
@@ -194,6 +196,9 @@ interface SelectOptionType {
194
196
  label: string | ReactNode;
195
197
  value: string;
196
198
  disabled?: boolean;
199
+ icon?: ReactNode;
200
+ avatarUrl?: string;
201
+ avatarAlt?: string;
197
202
  }
198
203
 
199
204
  interface SelectProps<T extends SelectOptionType = SelectOptionType> extends Omit<React.ComponentProps<typeof Select$1>, "onValueChange" | "value" | "defaultValue"> {
@@ -973,6 +978,8 @@ type InputOption<P> = BaseOption<P> & {
973
978
  placeholder?: string;
974
979
  /** 입력창 왼쪽에 돋보기 아이콘을 보여줄지 여부. 기본값 true. */
975
980
  leftIcon?: boolean;
981
+ /** 입력값이 있을 때 x(clear) 버튼을 보여줄지 여부. 기본값 true. */
982
+ canReset?: boolean;
976
983
  };
977
984
  type SelectOption<P> = BaseOption<P> & {
978
985
  type: "select";
@@ -1089,18 +1096,42 @@ interface MultiTabBarProps {
1089
1096
  * 전달하지 않으면(undefined) 기존과 완전히 동일한 평면(flat) 탭 목록으로 렌더링됩니다.
1090
1097
  *
1091
1098
  * 전달하면: 같은 key를 가진 탭들이 배열 안에서 서로 떨어져 있어도(다른 그룹 탭 사이에 끼어
1092
- * 있어도) 항상 그 그룹이 처음 등장한 위치의 칩 하나로 합쳐져서 색상 칩(그룹 헤더) + 그 아래
1093
- * 탭들로 렌더링됩니다 — 지금 fizza 프로젝트가 쓰던 커스텀 그룹 탭바와 동일한 형태이고, 이미
1099
+ * 있어도) 항상 그 그룹이 처음 등장한 위치의 칩 하나로 합쳐져서 Chrome 탭 그룹처럼 색상 칩(그룹
1100
+ * 라벨) + 그 옆 탭들 + 탭들 바닥을 잇는 그룹 색 하단선으로 렌더링됩니다. 이미
1094
1101
  * 열려 있는 그룹에 새 탭이 추가될 때 중복 칩이 생기지 않습니다.
1095
1102
  * 그룹 색상은 고정된 팔레트(파랑/주황/빨강/초록 + 보조 6색)에서 등장 순서대로 할당되고,
1096
- * 배경은 12% 투명도 틴트, 테두리는 40% 투명도로 렌더링됩니다 — fizza 프로젝트가 쓰던
1097
- * GroupedTabBar와 동일한 색상 스펙입니다.
1103
+ * 칩 배경·하단선·활성 탭 테두리에 같은 그룹 색이 쓰입니다.
1098
1104
  *
1099
1105
  * onTabsReorder를 같이 전달하면 그룹 모드에서도 드래그 앤 드롭 재정렬이 됩니다. 탭이 어느
1100
1106
  * 그룹에 속하는지는 getTabGroup이 반환하는 값으로만 정해지고 배열 위치와는 무관하므로,
1101
1107
  * 자유롭게 순서를 바꿔도 그룹 소속은 항상 그대로 유지됩니다.
1102
1108
  */
1103
1109
  getTabGroup?: (tab: MultiTab) => MultiTabGroupInfo | null | undefined;
1110
+ /**
1111
+ * 탭 라벨 왼쪽에 표시할 아이콘. null/undefined면 아이콘 없이 렌더링됩니다.
1112
+ */
1113
+ getTabIcon?: (tab: MultiTab) => ReactNode;
1114
+ /**
1115
+ * 탭의 더보기 메뉴 항목 — 더보기(⋯) 버튼을 줄지는 탭마다 이 함수의 반환값으로 정합니다.
1116
+ *
1117
+ * - 항목 배열을 반환한 탭: 아이콘에 마우스를 올리면 더보기 아이콘으로 바뀌고, 클릭하면 항목들이
1118
+ * Popover 메뉴로 열립니다(아이콘이 없는 탭이면 더보기 아이콘이 항상 보입니다).
1119
+ * - null/undefined/빈 배열을 반환한 탭: 더보기 버튼 없이 아이콘만 표시됩니다.
1120
+ *
1121
+ * 예) 특정 탭에만 메뉴 제공: `getTabMenuItems={(tab) => (tab.id === "settings" ? items : null)}`
1122
+ *
1123
+ * 아이콘·메뉴 영역의 클릭·포인터 이벤트는 탭 전환이나 드래그로 이어지지 않습니다.
1124
+ */
1125
+ getTabMenuItems?: (tab: MultiTab) => Array<MultiTabMenuItem> | null | undefined;
1126
+ }
1127
+ interface MultiTabMenuItem {
1128
+ key: string;
1129
+ label: ReactNode;
1130
+ /** 라벨 앞에 표시할 아이콘 (예: <Settings size={14} />) */
1131
+ icon?: ReactNode;
1132
+ /** 현재 화면에 해당하는 항목이면 true — 배경으로 강조됩니다 */
1133
+ selected?: boolean;
1134
+ onSelect: () => void;
1104
1135
  }
1105
1136
  declare function MultiTabBar(props: MultiTabBarProps): react.JSX.Element | null;
1106
1137
 
@@ -1602,4 +1633,4 @@ declare const Z_INDEX: {
1602
1633
  };
1603
1634
  type ZIndexKey = keyof typeof Z_INDEX;
1604
1635
 
1605
- export { ArrowIcon, Badge, type BadgeProps, type BaseParams, BaseUploader, type BaseUploaderProps, BreadCrumb, type BreadCrumbItem, type BreadCrumbMenuItem, type BreadCrumbProps, type BreadCrumbRoot, Button, type ButtonProps, type ButtonSize, type ButtonVariant, type CalendarYearRange, Carousel, type CarouselProps, type CarouselRef, Checkbox, type CheckboxProps, type Column, type ConfirmOptions, DatePicker, DebouncedButton, type DebouncedButtonProps, DetailContent, type DetailContentProps, type DetailField, type DetailFieldOrSection, DetailModalFrame, type DetailMode, DetailPageFrame, Empty, ExcelUploader, FilePreviewViewer, FileUploader, type FilterRow, type FormFieldConfig, Input, type InputProps, Loading, LoadingOverlay, type LoadingOverlayProps, type LoadingProps, type MentionItem, type MenuChild, type MenuGrandchild, type MenuItem, type MenuSection, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader, ModalIconHeader, type ModalIconHeaderProps, ModalOverlay, type ModalProps, type ModalType, MultiTabBar as MultiTab, type MultiTabGroupInfo, type MultiTab as MultiTabItem, PageFilter, type PageParams, Pagination, type PaginationProps, Popover, type PopoverAlign, PopoverAnchor, PopoverClose, PopoverContent, type PopoverContentProps, PopoverDescription, PopoverFooter, PopoverHeader, type PopoverPosition, PopoverTitle, PopoverTrigger, Radio, RadioGroup, type RadioGroupProps, type RadioOptionType, type RadioProps, RichEditor, RichEditorContent, type RichEditorContentProps, type RichEditorHeadingLevel, type RichEditorProps, type RichEditorThemeOverride, RichEditorToolbar, type RichEditorToolbarConfig, type RichEditorToolbarProps, ScrollArea, ScrollBar, SearchAddress, type SearchAddressProps, SearchBar, type SearchBarProps, Select, Select$1 as SelectBase, SelectContent, SelectGroup, SelectItem, SelectLabel, type SelectOptionType, type SelectProps, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Sidebar, type SidebarHeaderRenderProps, type SidebarProps, SimplePopover, type SimplePopoverProps, Skeleton, type SkeletonProps, Slider, type SliderProps, type SortOption, type SortOrder, type SortParams, Spinner, type SpinnerColor, type SpinnerProps, type SpinnerSize, SubmitForm, Switch, type SwitchProps, Tab, type TabItem, type TabProps, Table, Textarea, type TextareaProps, type ToastPosition, type ToastProps, ToastProvider, type ToastType, ToggleSwitch, Tooltip, type TooltipProps, type UseParams, type UseRichEditorOptions, type UseRichEditorReturn, type YmdDateString, type ZIndexKey, Z_INDEX, buildBreadCrumbItems, buttonVariants, cn, confirmModal, findParentMenuItem, findParentMenuName, formatDate, getFileLabel, getPreviewFileType, isCalendarDayAfterMax, isDateInRange, switchTrackSizes, textVariants, toast, useBlockModalConfirm, useBreadCrumbItems, useCustomBlocker, useDetailController, useFilePreviewViewer, useModal, useMultiTabStore, useParams, useRichEditor, useScrollToTop, useStableImageSrc, useToast, validateAndFormatInput };
1636
+ export { ArrowIcon, Badge, type BadgeProps, type BaseParams, BaseUploader, type BaseUploaderProps, BreadCrumb, type BreadCrumbItem, type BreadCrumbMenuItem, type BreadCrumbProps, type BreadCrumbRoot, Button, type ButtonProps, type ButtonSize, type ButtonVariant, type CalendarYearRange, Carousel, type CarouselProps, type CarouselRef, Checkbox, type CheckboxProps, type Column, type ConfirmOptions, DatePicker, DebouncedButton, type DebouncedButtonProps, DetailContent, type DetailContentProps, type DetailField, type DetailFieldOrSection, DetailModalFrame, type DetailMode, DetailPageFrame, Empty, ExcelUploader, FilePreviewViewer, FileUploader, type FilterRow, type FormFieldConfig, Input, type InputProps, Loading, LoadingOverlay, type LoadingOverlayProps, type LoadingProps, type MentionItem, type MenuChild, type MenuGrandchild, type MenuItem, type MenuSection, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader, ModalIconHeader, type ModalIconHeaderProps, ModalOverlay, type ModalProps, type ModalType, MultiTabBar as MultiTab, type MultiTabGroupInfo, type MultiTab as MultiTabItem, type MultiTabMenuItem, PageFilter, type PageParams, Pagination, type PaginationProps, Popover, type PopoverAlign, PopoverAnchor, PopoverClose, PopoverContent, type PopoverContentProps, PopoverDescription, PopoverFooter, PopoverHeader, type PopoverPosition, PopoverTitle, PopoverTrigger, Radio, RadioGroup, type RadioGroupProps, type RadioOptionType, type RadioProps, RichEditor, RichEditorContent, type RichEditorContentProps, type RichEditorHeadingLevel, type RichEditorProps, type RichEditorThemeOverride, RichEditorToolbar, type RichEditorToolbarConfig, type RichEditorToolbarProps, ScrollArea, ScrollBar, SearchAddress, type SearchAddressProps, SearchBar, type SearchBarProps, Select, Select$1 as SelectBase, SelectContent, SelectGroup, SelectItem, SelectLabel, type SelectOptionType, type SelectProps, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Sidebar, type SidebarHeaderRenderProps, type SidebarProps, SimplePopover, type SimplePopoverProps, Skeleton, type SkeletonProps, Slider, type SliderProps, type SortOption, type SortOrder, type SortParams, Spinner, type SpinnerColor, type SpinnerProps, type SpinnerSize, SubmitForm, Switch, type SwitchProps, Tab, type TabItem, type TabProps, Table, Textarea, type TextareaProps, type ToastPosition, type ToastProps, ToastProvider, type ToastType, ToggleSwitch, Tooltip, type TooltipProps, type UseParams, type UseRichEditorOptions, type UseRichEditorReturn, type YmdDateString, type ZIndexKey, Z_INDEX, buildBreadCrumbItems, buttonVariants, cn, confirmModal, findParentMenuItem, findParentMenuName, formatDate, getFileLabel, getPreviewFileType, isCalendarDayAfterMax, isDateInRange, switchTrackSizes, textVariants, toast, useBlockModalConfirm, useBreadCrumbItems, useCustomBlocker, useDetailController, useFilePreviewViewer, useModal, useMultiTabStore, useParams, useRichEditor, useScrollToTop, useStableImageSrc, useToast, validateAndFormatInput };
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import * as React6 from 'react';
6
6
  import React6__default, { forwardRef, useState, useRef, useEffect, useImperativeHandle, useCallback, memo, createContext, useContext, useMemo, useId, useLayoutEffect, useDeferredValue, Fragment as Fragment$1 } from 'react';
7
7
  import { Slot } from '@radix-ui/react-slot';
8
8
  import * as TooltipPrimitive from '@radix-ui/react-tooltip';
9
- import { ChevronLeft, ChevronRight, FileText, ZoomIn, ZoomOut, RotateCcw, RotateCw, Download, X, Heading1, Heading2, Heading3, Heading4, Bold, Italic, Strikethrough, Code, AlignLeft, AlignCenter, AlignRight, List, ListOrdered, Quote, FileCode, Table as Table$1, Plus, Minus, Trash2, EyeOff, Eye, Check, CircleX, ChevronDown, Calendar, CircleIcon, ChevronUp, Search, TriangleAlert, Info, Pencil, BadgePlus, FileSearch2, Upload, FileUp, PanelRightClose, PanelLeftClose, ChevronFirst, ChevronLast } from 'lucide-react';
9
+ import { ChevronLeft, ChevronRight, FileText, ZoomIn, ZoomOut, RotateCcw, RotateCw, Download, X, Heading1, Heading2, Heading3, Heading4, Bold, Italic, Strikethrough, Code, AlignLeft, AlignCenter, AlignRight, List, ListOrdered, Quote, FileCode, Table as Table$1, Plus, Minus, Trash2, CircleX, EyeOff, Eye, Check, ChevronDown, Calendar, CircleIcon, ChevronUp, Search, TriangleAlert, Info, Pencil, BadgePlus, FileSearch2, Upload, FileUp, PanelRightClose, PanelLeftClose, ChevronFirst, ChevronLast, MoreHorizontal } from 'lucide-react';
10
10
  import * as SwitchPrimitive from '@radix-ui/react-switch';
11
11
  import * as RadixSlider from '@radix-ui/react-slider';
12
12
  import * as SelectPrimitive from '@radix-ui/react-select';
@@ -445,6 +445,8 @@ function Input2(props) {
445
445
  leftIcon,
446
446
  rightIcon,
447
447
  showPasswordToggle = true,
448
+ clearable = false,
449
+ onClear,
448
450
  onChange,
449
451
  ...rest
450
452
  } = props;
@@ -474,7 +476,16 @@ function Input2(props) {
474
476
  const shouldShowPasswordToggle = type === "password" && showPasswordToggle;
475
477
  const actualType = type === "password" && showPassword ? "text" : type;
476
478
  const handlePasswordToggle = () => setShowPassword((prev) => !prev);
477
- const finalRightIcon = rightIcon || (shouldShowPasswordToggle ? /* @__PURE__ */ jsx(
479
+ const handleClear = () => onClear?.();
480
+ const shouldShowClearButton = clearable && !disabled && typeof rest.value === "string" && rest.value.length > 0;
481
+ const finalRightIcon = rightIcon || (shouldShowClearButton ? /* @__PURE__ */ jsx(
482
+ "div",
483
+ {
484
+ onClick: handleClear,
485
+ className: "text-muted-foreground hover:text-foreground cursor-pointer transition-colors",
486
+ children: /* @__PURE__ */ jsx(CircleX, { className: "h-4 w-4" })
487
+ }
488
+ ) : null) || (shouldShowPasswordToggle ? /* @__PURE__ */ jsx(
478
489
  "div",
479
490
  {
480
491
  onClick: handlePasswordToggle,
@@ -940,6 +951,29 @@ function SelectScrollDownButton({
940
951
  }
941
952
  );
942
953
  }
954
+ function SelectOptionVisual(props) {
955
+ const { icon, avatarUrl, avatarAlt, fallbackLabel } = props;
956
+ const [hasAvatarError, setHasAvatarError] = useState(false);
957
+ const handleAvatarError = () => setHasAvatarError(true);
958
+ if (avatarUrl && !hasAvatarError) {
959
+ return /* @__PURE__ */ jsx(
960
+ "img",
961
+ {
962
+ src: avatarUrl,
963
+ alt: avatarAlt ?? "",
964
+ className: "size-5 shrink-0 rounded-full object-cover",
965
+ onError: handleAvatarError
966
+ }
967
+ );
968
+ }
969
+ if (avatarUrl && hasAvatarError) {
970
+ return /* @__PURE__ */ jsx("span", { className: "flex size-5 shrink-0 items-center justify-center rounded-full bg-gray-200 text-[10px] font-medium text-gray-500", children: fallbackLabel?.charAt(0).toUpperCase() ?? "?" });
971
+ }
972
+ if (icon) {
973
+ return /* @__PURE__ */ jsx("span", { className: "flex size-4 shrink-0 items-center justify-center text-gray-500", children: icon });
974
+ }
975
+ return null;
976
+ }
943
977
 
944
978
  // src/components/Select/config/default.ts
945
979
  var SELECT_BORDER_COLORS = {
@@ -1031,7 +1065,18 @@ function Select2(props) {
1031
1065
  itemClassName,
1032
1066
  option.disabled && cn("opacity-50 cursor-not-allowed text-gray-300 bg-white", disabledItemClassName)
1033
1067
  ),
1034
- children: option.label
1068
+ children: /* @__PURE__ */ jsxs("span", { className: "flex w-full min-w-0 items-center gap-2", children: [
1069
+ /* @__PURE__ */ jsx(
1070
+ SelectOptionVisual,
1071
+ {
1072
+ icon: option.icon,
1073
+ avatarUrl: option.avatarUrl,
1074
+ avatarAlt: option.avatarAlt,
1075
+ fallbackLabel: typeof option.label === "string" ? option.label : void 0
1076
+ }
1077
+ ),
1078
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: option.label })
1079
+ ] })
1035
1080
  },
1036
1081
  String(option.value)
1037
1082
  )) })
@@ -7847,6 +7892,9 @@ function PageFilter(props) {
7847
7892
  const handleInputChange = (key) => (e) => {
7848
7893
  onChange({ [key]: e.target.value });
7849
7894
  };
7895
+ const handleInputClear = (key) => () => {
7896
+ onChange({ [key]: "" });
7897
+ };
7850
7898
  const handleSelectChange = (key, autoSubmit) => (value) => {
7851
7899
  onChange({ [key]: value });
7852
7900
  if (autoSubmit) pendingAutoSubmitRef.current = { key, value };
@@ -7891,6 +7939,8 @@ function PageFilter(props) {
7891
7939
  if (e.key === "Enter") handleSubmit();
7892
7940
  },
7893
7941
  leftIcon: option.leftIcon !== false ? /* @__PURE__ */ jsx(Search, { size: 16 }) : void 0,
7942
+ clearable: option.canReset ?? true,
7943
+ onClear: handleInputClear(optionKey),
7894
7944
  className: option.className
7895
7945
  }
7896
7946
  ) }, String(optionKey));
@@ -7986,15 +8036,15 @@ var VARIANT_STYLES = {
7986
8036
  inactiveText: "font-normal",
7987
8037
  indicator: "bg-blue-500",
7988
8038
  closeBtn: "rounded hover:bg-gray-300/60",
7989
- closeBtnWH: "w-3.5 h-3.5",
7990
- closeBtnSize: 10,
8039
+ closeBtnWH: "w-4 h-4",
8040
+ closeBtnSize: 12,
7991
8041
  plusBtnArea: "border-l border-gray-100 bg-white",
7992
8042
  plusBtn: "text-gray-400 hover:text-gray-600 hover:bg-gray-100",
7993
8043
  fadeOpacity: 0.12,
7994
- tabPy: "py-1.5",
7995
- tabPx: "px-3",
7996
- tabTextSize: "text-xs",
7997
- scrollPadding: "px-3 pt-1.5",
8044
+ tabHeight: "h-[38px]",
8045
+ tabPx: "px-4",
8046
+ tabTextSize: "text-sm",
8047
+ scrollPadding: "px-3 pt-2",
7998
8048
  rounded: "rounded-t-md"
7999
8049
  },
8000
8050
  dark: {
@@ -8005,15 +8055,15 @@ var VARIANT_STYLES = {
8005
8055
  inactiveText: "font-normal",
8006
8056
  indicator: "bg-indigo-400",
8007
8057
  closeBtn: "rounded hover:bg-gray-600/60",
8008
- closeBtnWH: "w-3.5 h-3.5",
8009
- closeBtnSize: 10,
8058
+ closeBtnWH: "w-4 h-4",
8059
+ closeBtnSize: 12,
8010
8060
  plusBtnArea: "border-l border-gray-700 bg-gray-900",
8011
8061
  plusBtn: "text-gray-500 hover:text-gray-300 hover:bg-gray-700",
8012
8062
  fadeOpacity: 0.4,
8013
- tabPy: "py-1.5",
8014
- tabPx: "px-3",
8015
- tabTextSize: "text-xs",
8016
- scrollPadding: "px-3 pt-1.5",
8063
+ tabHeight: "h-[38px]",
8064
+ tabPx: "px-4",
8065
+ tabTextSize: "text-sm",
8066
+ scrollPadding: "px-3 pt-2",
8017
8067
  rounded: "rounded-t-md"
8018
8068
  },
8019
8069
  "system-light": {
@@ -8029,7 +8079,7 @@ var VARIANT_STYLES = {
8029
8079
  plusBtnArea: "border-l border-gray-300 bg-gray-200",
8030
8080
  plusBtn: "text-slate-400 hover:text-slate-600 hover:bg-gray-300",
8031
8081
  fadeOpacity: 0.15,
8032
- tabPy: "py-2.5",
8082
+ tabHeight: "h-[38px]",
8033
8083
  tabPx: "px-5",
8034
8084
  tabTextSize: "text-sm",
8035
8085
  scrollPadding: "px-3 pt-2",
@@ -8048,7 +8098,7 @@ var VARIANT_STYLES = {
8048
8098
  plusBtnArea: "border-l border-slate-700 bg-slate-900",
8049
8099
  plusBtn: "text-slate-400 hover:text-slate-200 hover:bg-slate-700",
8050
8100
  fadeOpacity: 0.45,
8051
- tabPy: "py-2.5",
8101
+ tabHeight: "h-[38px]",
8052
8102
  tabPx: "px-5",
8053
8103
  tabTextSize: "text-sm",
8054
8104
  scrollPadding: "px-4 pt-2",
@@ -8060,6 +8110,65 @@ function easedFade(dir, opacity) {
8060
8110
  const c = (t) => `rgba(0,0,0,${(opacity * t).toFixed(3)})`;
8061
8111
  return `linear-gradient(${dir}, ${c(1)} 0%, ${c(0.72)} 20%, ${c(0.38)} 45%, ${c(0.1)} 70%, transparent 100%)`;
8062
8112
  }
8113
+ var MENU_ITEM_CLASSNAME = "flex w-full cursor-pointer items-center gap-2 rounded-md border-none bg-transparent px-2 py-1.5 text-left text-[13px] whitespace-nowrap text-gray-900 hover:bg-gray-100";
8114
+ function TabIconMenu(props) {
8115
+ const { icon, items, label } = props;
8116
+ const [open, setOpen] = useState(false);
8117
+ if (items.length === 0) {
8118
+ return /* @__PURE__ */ jsx("span", { className: "flex h-4.5 w-4.5 items-center justify-center", children: icon });
8119
+ }
8120
+ const showMore = (base) => open ? "flex" : base;
8121
+ return /* @__PURE__ */ jsx(
8122
+ SimplePopover,
8123
+ {
8124
+ open,
8125
+ onOpenChange: setOpen,
8126
+ align: "start",
8127
+ contentClassName: "w-auto min-w-28 p-1",
8128
+ trigger: /* @__PURE__ */ jsxs(
8129
+ "button",
8130
+ {
8131
+ type: "button",
8132
+ "aria-label": `${label} \uBA54\uB274`,
8133
+ className: "group/tab-menu relative flex h-4.5 w-4.5 cursor-pointer items-center justify-center rounded border-none bg-transparent p-0",
8134
+ children: [
8135
+ icon != null && /* @__PURE__ */ jsx(
8136
+ "span",
8137
+ {
8138
+ className: `flex items-center justify-center ${open ? "invisible" : "group-hover/tab-menu:invisible"}`,
8139
+ children: icon
8140
+ }
8141
+ ),
8142
+ /* @__PURE__ */ jsx(
8143
+ "span",
8144
+ {
8145
+ className: `absolute inset-0 items-center justify-center rounded bg-gray-200 text-gray-700 ${icon != null ? showMore("hidden group-hover/tab-menu:flex") : "flex"}`,
8146
+ children: /* @__PURE__ */ jsx(MoreHorizontal, { size: 14 })
8147
+ }
8148
+ )
8149
+ ]
8150
+ }
8151
+ ),
8152
+ children: items.map((item) => /* @__PURE__ */ jsxs(
8153
+ "button",
8154
+ {
8155
+ type: "button",
8156
+ onClick: () => {
8157
+ setOpen(false);
8158
+ item.onSelect();
8159
+ },
8160
+ className: MENU_ITEM_CLASSNAME,
8161
+ style: item.selected ? { backgroundColor: "#F3F4F6" } : void 0,
8162
+ children: [
8163
+ item.icon != null && /* @__PURE__ */ jsx("span", { className: "flex shrink-0 items-center text-gray-500", children: item.icon }),
8164
+ item.label
8165
+ ]
8166
+ },
8167
+ item.key
8168
+ ))
8169
+ }
8170
+ );
8171
+ }
8063
8172
  function clusterTabs(tabs, getTabGroup) {
8064
8173
  const clusters = [];
8065
8174
  const clusterByGroupKey = /* @__PURE__ */ new Map();
@@ -8127,8 +8236,13 @@ function MultiTabPill(props) {
8127
8236
  draggable = false,
8128
8237
  onPointerDown,
8129
8238
  dropIndicator = null,
8130
- isDraggingThis = false
8239
+ isDraggingThis = false,
8240
+ icon,
8241
+ menuItems,
8242
+ groupColor
8131
8243
  } = props;
8244
+ const hasPrefix = icon != null || (menuItems?.length ?? 0) > 0;
8245
+ const outlinedByGroup = isActive && !!groupColor;
8132
8246
  return /* @__PURE__ */ jsxs(
8133
8247
  "div",
8134
8248
  {
@@ -8138,7 +8252,7 @@ function MultiTabPill(props) {
8138
8252
  if (!isActive) onClick();
8139
8253
  },
8140
8254
  className: `
8141
- group relative flex items-center gap-1.5 ${s.tabPx} ${s.tabPy} flex-shrink-0
8255
+ group relative flex items-center gap-1.5 ${s.tabPx} ${s.tabHeight} flex-shrink-0
8142
8256
  ${s.rounded} border border-b-0 select-none
8143
8257
  transition-colors duration-100
8144
8258
  ${isActive ? s.activeTab : s.inactiveTab}
@@ -8146,7 +8260,9 @@ function MultiTabPill(props) {
8146
8260
  ${isDraggingThis ? "opacity-40" : ""}
8147
8261
  ${dropIndicator === "before" ? "[box-shadow:inset_2px_0_0_0_#3b82f6]" : ""}
8148
8262
  ${dropIndicator === "after" ? "[box-shadow:inset_-2px_0_0_0_#3b82f6]" : ""}
8263
+ ${outlinedByGroup ? "z-[2]" : ""}
8149
8264
  `,
8265
+ style: outlinedByGroup ? { borderColor: groupColor } : void 0,
8150
8266
  children: [
8151
8267
  isActive && /* @__PURE__ */ jsx(
8152
8268
  "div",
@@ -8155,6 +8271,15 @@ function MultiTabPill(props) {
8155
8271
  style: accentColor ? { backgroundColor: accentColor } : void 0
8156
8272
  }
8157
8273
  ),
8274
+ hasPrefix && /* @__PURE__ */ jsx(
8275
+ "span",
8276
+ {
8277
+ className: "flex flex-shrink-0 items-center",
8278
+ onPointerDown: (e) => e.stopPropagation(),
8279
+ onClick: (e) => e.stopPropagation(),
8280
+ children: /* @__PURE__ */ jsx(TabIconMenu, { icon, items: menuItems ?? [], label: tab.label })
8281
+ }
8282
+ ),
8158
8283
  /* @__PURE__ */ jsx("span", { className: `${s.tabTextSize} max-w-35 truncate leading-none ${isActive ? s.activeText : s.inactiveText}`, children: tab.label }),
8159
8284
  showClose && /* @__PURE__ */ jsx(
8160
8285
  "button",
@@ -8186,7 +8311,9 @@ function MultiTabBar(props) {
8186
8311
  onTabsReorder,
8187
8312
  variant = "light",
8188
8313
  primaryColor,
8189
- getTabGroup
8314
+ getTabGroup,
8315
+ getTabIcon,
8316
+ getTabMenuItems
8190
8317
  } = props;
8191
8318
  const s = VARIANT_STYLES[variant];
8192
8319
  const scrollRef = useRef(null);
@@ -8449,9 +8576,9 @@ function MultiTabBar(props) {
8449
8576
  const draggingGroupColor = draggingGroupKey ? groupColors.get(draggingGroupKey) : void 0;
8450
8577
  const ghost = draggingGroupKey && draggingGroupCluster?.group ? {
8451
8578
  label: draggingGroupCluster.group.label,
8452
- bg: (draggingGroupColor ?? TAB_PALETTE[0]).bg,
8453
- border: (draggingGroupColor ?? TAB_PALETTE[0]).border,
8454
- color: (draggingGroupColor ?? TAB_PALETTE[0]).base
8579
+ bg: (draggingGroupColor ?? TAB_PALETTE[0]).base,
8580
+ border: (draggingGroupColor ?? TAB_PALETTE[0]).base,
8581
+ color: "white"
8455
8582
  } : draggingTab ? { label: draggingTab.label, bg: "white", border: draggingColor ?? "#e5e7eb", color: "#111827" } : null;
8456
8583
  if (tabs.length === 0) return null;
8457
8584
  return /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -8502,7 +8629,9 @@ function MultiTabBar(props) {
8502
8629
  draggable: reorderEnabled,
8503
8630
  isDraggingThis: tab.id === draggingId,
8504
8631
  dropIndicator: isDropTarget ? dropSide : isGroupDropTarget2 ? groupDropSide : null,
8505
- onPointerDown: (e) => handlePointerDown(e, tab.id)
8632
+ onPointerDown: (e) => handlePointerDown(e, tab.id),
8633
+ icon: getTabIcon?.(tab),
8634
+ menuItems: getTabMenuItems?.(tab)
8506
8635
  },
8507
8636
  tab.id
8508
8637
  );
@@ -8511,76 +8640,76 @@ function MultiTabBar(props) {
8511
8640
  const { key, label } = cluster.group;
8512
8641
  const color = groupColors.get(key) ?? TAB_PALETTE[0];
8513
8642
  const collapsed = collapsedGroups.has(key);
8514
- const groupHasActiveTab = cluster.tabs.some((t) => t.id === activeTabId);
8515
8643
  const isGroupDropTarget = groupDropTargetKey === `group:${key}`;
8516
8644
  const isDraggingThisGroup = draggingGroupKey === key;
8517
8645
  return /* @__PURE__ */ jsxs(
8518
8646
  "div",
8519
8647
  {
8520
8648
  ref: (el) => registerGroupRef(key, el),
8521
- className: "flex shrink-0 flex-col items-stretch",
8649
+ className: `relative flex shrink-0 items-end gap-0.5 ${isDraggingThisGroup ? "opacity-40" : ""} ${isGroupDropTarget && groupDropSide === "before" ? "[box-shadow:inset_2px_0_0_0_#3b82f6]" : ""} ${isGroupDropTarget && groupDropSide === "after" ? "[box-shadow:inset_-2px_0_0_0_#3b82f6]" : ""}`,
8522
8650
  children: [
8523
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
8524
- /* @__PURE__ */ jsxs(
8525
- "button",
8651
+ /* @__PURE__ */ jsx("div", { className: `flex ${s.tabHeight} shrink-0 items-center px-1`, children: /* @__PURE__ */ jsxs(
8652
+ "button",
8653
+ {
8654
+ type: "button",
8655
+ onClick: () => {
8656
+ if (suppressClickRef.current) return;
8657
+ toggleGroupCollapsed(key);
8658
+ },
8659
+ onPointerDown: reorderEnabled ? (e) => handleGroupPointerDown(e, key) : void 0,
8660
+ "aria-expanded": !collapsed,
8661
+ title: collapsed ? "\uD558\uC704 \uD0ED \uD3BC\uCE58\uAE30" : "\uD558\uC704 \uD0ED \uC811\uAE30",
8662
+ className: `flex h-6.5 items-center gap-1 rounded-lg px-2.5 text-sm font-semibold whitespace-nowrap text-white select-none ${reorderEnabled ? isDraggingThisGroup ? "cursor-grabbing" : "cursor-grab" : "cursor-pointer"}`,
8663
+ style: { backgroundColor: color.base },
8664
+ children: [
8665
+ collapsed ? /* @__PURE__ */ jsx(ChevronRight, { size: 14 }) : /* @__PURE__ */ jsx(ChevronDown, { size: 14 }),
8666
+ label,
8667
+ canClose && /* @__PURE__ */ jsx(
8668
+ X,
8669
+ {
8670
+ size: 14,
8671
+ onClick: (e) => {
8672
+ e.stopPropagation();
8673
+ cluster.tabs.forEach((t) => onTabClose(t.id));
8674
+ }
8675
+ }
8676
+ )
8677
+ ]
8678
+ }
8679
+ ) }),
8680
+ !collapsed && cluster.tabs.map((tab) => {
8681
+ const isDropTarget = dropTargetId === tab.id;
8682
+ const isTabGroupDropTarget = groupDropTargetKey === `tab:${tab.id}`;
8683
+ return /* @__PURE__ */ jsx(
8684
+ MultiTabPill,
8526
8685
  {
8527
- type: "button",
8686
+ tab,
8687
+ isActive: tab.id === activeTabId,
8688
+ showClose: canClose,
8689
+ accentColor: color.base,
8690
+ style: s,
8528
8691
  onClick: () => {
8529
8692
  if (suppressClickRef.current) return;
8530
- toggleGroupCollapsed(key);
8531
- },
8532
- onPointerDown: reorderEnabled ? (e) => handleGroupPointerDown(e, key) : void 0,
8533
- "aria-expanded": !collapsed,
8534
- title: collapsed ? "\uD558\uC704 \uD0ED \uD3BC\uCE58\uAE30" : "\uD558\uC704 \uD0ED \uC811\uAE30",
8535
- className: `flex items-center gap-1 rounded-md border px-2.5 py-1 text-xs font-bold whitespace-nowrap select-none ${reorderEnabled ? isDraggingThisGroup ? "cursor-grabbing" : "cursor-grab" : "cursor-pointer"} ${isDraggingThisGroup ? "opacity-40" : ""} ${isGroupDropTarget && groupDropSide === "before" ? "[box-shadow:inset_2px_0_0_0_#3b82f6]" : ""} ${isGroupDropTarget && groupDropSide === "after" ? "[box-shadow:inset_-2px_0_0_0_#3b82f6]" : ""}`,
8536
- style: { backgroundColor: color.bg, borderColor: color.border, color: color.base },
8537
- children: [
8538
- collapsed ? /* @__PURE__ */ jsx(ChevronRight, { size: 12 }) : /* @__PURE__ */ jsx(ChevronDown, { size: 12 }),
8539
- label,
8540
- canClose && /* @__PURE__ */ jsx(
8541
- X,
8542
- {
8543
- size: 12,
8544
- onClick: (e) => {
8545
- e.stopPropagation();
8546
- cluster.tabs.forEach((t) => onTabClose(t.id));
8547
- }
8548
- }
8549
- )
8550
- ]
8551
- }
8552
- ),
8553
- !collapsed && cluster.tabs.map((tab) => {
8554
- const isDropTarget = dropTargetId === tab.id;
8555
- const isTabGroupDropTarget = groupDropTargetKey === `tab:${tab.id}`;
8556
- return /* @__PURE__ */ jsx(
8557
- MultiTabPill,
8558
- {
8559
- tab,
8560
- isActive: tab.id === activeTabId,
8561
- showClose: canClose,
8562
- accentColor: color.base,
8563
- style: s,
8564
- onClick: () => {
8565
- if (suppressClickRef.current) return;
8566
- onTabClick(tab.id);
8567
- },
8568
- onClose: () => onTabClose(tab.id),
8569
- registerRef: registerTabRef,
8570
- draggable: reorderEnabled,
8571
- isDraggingThis: tab.id === draggingId,
8572
- dropIndicator: isDropTarget ? dropSide : isTabGroupDropTarget ? groupDropSide : null,
8573
- onPointerDown: (e) => handlePointerDown(e, tab.id)
8693
+ onTabClick(tab.id);
8574
8694
  },
8575
- tab.id
8576
- );
8577
- })
8578
- ] }),
8579
- /* @__PURE__ */ jsx(
8695
+ onClose: () => onTabClose(tab.id),
8696
+ registerRef: registerTabRef,
8697
+ draggable: reorderEnabled,
8698
+ isDraggingThis: tab.id === draggingId,
8699
+ dropIndicator: isDropTarget ? dropSide : isTabGroupDropTarget ? groupDropSide : null,
8700
+ onPointerDown: (e) => handlePointerDown(e, tab.id),
8701
+ icon: getTabIcon?.(tab),
8702
+ menuItems: getTabMenuItems?.(tab),
8703
+ groupColor: color.base
8704
+ },
8705
+ tab.id
8706
+ );
8707
+ }),
8708
+ !collapsed && /* @__PURE__ */ jsx(
8580
8709
  "div",
8581
8710
  {
8582
- className: "mt-1 h-0.75 rounded-full",
8583
- style: { backgroundColor: color.base, opacity: groupHasActiveTab ? 1 : 0.35 }
8711
+ className: "pointer-events-none absolute right-0 bottom-0 left-1 z-[1] h-0.5 rounded-l-full",
8712
+ style: { backgroundColor: color.base }
8584
8713
  }
8585
8714
  )
8586
8715
  ]
@@ -8606,7 +8735,9 @@ function MultiTabBar(props) {
8606
8735
  draggable: reorderEnabled,
8607
8736
  isDraggingThis: tab.id === draggingId,
8608
8737
  dropIndicator: isDropTarget ? dropSide : null,
8609
- onPointerDown: (e) => handlePointerDown(e, tab.id)
8738
+ onPointerDown: (e) => handlePointerDown(e, tab.id),
8739
+ icon: getTabIcon?.(tab),
8740
+ menuItems: getTabMenuItems?.(tab)
8610
8741
  },
8611
8742
  tab.id
8612
8743
  );
@@ -8634,7 +8765,7 @@ function MultiTabBar(props) {
8634
8765
  /* @__PURE__ */ jsx(
8635
8766
  "div",
8636
8767
  {
8637
- className: "pointer-events-none fixed z-50 flex items-center gap-1.5 rounded-md border px-2.5 py-1 text-xs font-bold whitespace-nowrap shadow-lg",
8768
+ className: "pointer-events-none fixed z-50 flex items-center gap-1.5 rounded-md border px-3 py-1.5 text-sm font-bold whitespace-nowrap shadow-lg",
8638
8769
  style: {
8639
8770
  left: dragPos.x + 12,
8640
8771
  top: dragPos.y + 12,