@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.cjs +213 -82
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +36 -5
- package/dist/index.d.ts +36 -5
- package/dist/index.js +214 -83
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +2 -2
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
|
-
*
|
|
1099
|
+
* 있어도) 항상 그 그룹이 처음 등장한 위치의 칩 하나로 합쳐져서 Chrome 탭 그룹처럼 색상 칩(그룹
|
|
1100
|
+
* 라벨) + 그 옆 탭들 + 탭들 바닥을 잇는 그룹 색 하단선으로 렌더링됩니다. 이미
|
|
1094
1101
|
* 열려 있는 그룹에 새 탭이 추가될 때 중복 칩이 생기지 않습니다.
|
|
1095
1102
|
* 그룹 색상은 고정된 팔레트(파랑/주황/빨강/초록 + 보조 6색)에서 등장 순서대로 할당되고,
|
|
1096
|
-
*
|
|
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
|
-
*
|
|
1099
|
+
* 있어도) 항상 그 그룹이 처음 등장한 위치의 칩 하나로 합쳐져서 Chrome 탭 그룹처럼 색상 칩(그룹
|
|
1100
|
+
* 라벨) + 그 옆 탭들 + 탭들 바닥을 잇는 그룹 색 하단선으로 렌더링됩니다. 이미
|
|
1094
1101
|
* 열려 있는 그룹에 새 탭이 추가될 때 중복 칩이 생기지 않습니다.
|
|
1095
1102
|
* 그룹 색상은 고정된 팔레트(파랑/주황/빨강/초록 + 보조 6색)에서 등장 순서대로 할당되고,
|
|
1096
|
-
*
|
|
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,
|
|
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
|
|
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:
|
|
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-
|
|
7990
|
-
closeBtnSize:
|
|
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
|
-
|
|
7995
|
-
tabPx: "px-
|
|
7996
|
-
tabTextSize: "text-
|
|
7997
|
-
scrollPadding: "px-3 pt-
|
|
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-
|
|
8009
|
-
closeBtnSize:
|
|
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
|
-
|
|
8014
|
-
tabPx: "px-
|
|
8015
|
-
tabTextSize: "text-
|
|
8016
|
-
scrollPadding: "px-3 pt-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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]).
|
|
8453
|
-
border: (draggingGroupColor ?? TAB_PALETTE[0]).
|
|
8454
|
-
color:
|
|
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:
|
|
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__ */
|
|
8524
|
-
|
|
8525
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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: "
|
|
8583
|
-
style: { backgroundColor: color.base
|
|
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-
|
|
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,
|