@underverse-ui/underverse 0.2.5 → 0.2.8
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 +139 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -1
- package/dist/index.d.ts +11 -1
- package/dist/index.js +143 -54
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.d.cts
CHANGED
|
@@ -343,11 +343,16 @@ interface ModalProps {
|
|
|
343
343
|
title?: string;
|
|
344
344
|
description?: string;
|
|
345
345
|
className?: string;
|
|
346
|
+
contentClassName?: string;
|
|
346
347
|
overlayClassName?: string;
|
|
347
348
|
showCloseButton?: boolean;
|
|
348
349
|
closeOnOverlayClick?: boolean;
|
|
349
350
|
closeOnEsc?: boolean;
|
|
350
351
|
size?: "sm" | "md" | "lg" | "xl" | "full";
|
|
352
|
+
noPadding?: boolean;
|
|
353
|
+
fullWidth?: boolean;
|
|
354
|
+
width?: string | number;
|
|
355
|
+
height?: string | number;
|
|
351
356
|
}
|
|
352
357
|
declare const Modal: React$1.FC<ModalProps>;
|
|
353
358
|
|
|
@@ -828,6 +833,8 @@ interface ComboboxProps {
|
|
|
828
833
|
label?: string;
|
|
829
834
|
required?: boolean;
|
|
830
835
|
fontBold?: boolean;
|
|
836
|
+
loading?: boolean;
|
|
837
|
+
loadingText?: string;
|
|
831
838
|
}
|
|
832
839
|
declare const Combobox: React$1.FC<ComboboxProps>;
|
|
833
840
|
|
|
@@ -847,11 +854,14 @@ interface MultiComboboxProps {
|
|
|
847
854
|
showClear?: boolean;
|
|
848
855
|
className?: string;
|
|
849
856
|
disabled?: boolean;
|
|
850
|
-
size?:
|
|
857
|
+
size?: "sm" | "md" | "lg";
|
|
851
858
|
label?: string;
|
|
852
859
|
title?: string;
|
|
853
860
|
required?: boolean;
|
|
854
861
|
displayFormat?: (option: MultiComboboxOption) => string;
|
|
862
|
+
loading?: boolean;
|
|
863
|
+
loadingText?: string;
|
|
864
|
+
emptyText?: string;
|
|
855
865
|
}
|
|
856
866
|
declare const MultiCombobox: React$1.FC<MultiComboboxProps>;
|
|
857
867
|
|
package/dist/index.d.ts
CHANGED
|
@@ -343,11 +343,16 @@ interface ModalProps {
|
|
|
343
343
|
title?: string;
|
|
344
344
|
description?: string;
|
|
345
345
|
className?: string;
|
|
346
|
+
contentClassName?: string;
|
|
346
347
|
overlayClassName?: string;
|
|
347
348
|
showCloseButton?: boolean;
|
|
348
349
|
closeOnOverlayClick?: boolean;
|
|
349
350
|
closeOnEsc?: boolean;
|
|
350
351
|
size?: "sm" | "md" | "lg" | "xl" | "full";
|
|
352
|
+
noPadding?: boolean;
|
|
353
|
+
fullWidth?: boolean;
|
|
354
|
+
width?: string | number;
|
|
355
|
+
height?: string | number;
|
|
351
356
|
}
|
|
352
357
|
declare const Modal: React$1.FC<ModalProps>;
|
|
353
358
|
|
|
@@ -828,6 +833,8 @@ interface ComboboxProps {
|
|
|
828
833
|
label?: string;
|
|
829
834
|
required?: boolean;
|
|
830
835
|
fontBold?: boolean;
|
|
836
|
+
loading?: boolean;
|
|
837
|
+
loadingText?: string;
|
|
831
838
|
}
|
|
832
839
|
declare const Combobox: React$1.FC<ComboboxProps>;
|
|
833
840
|
|
|
@@ -847,11 +854,14 @@ interface MultiComboboxProps {
|
|
|
847
854
|
showClear?: boolean;
|
|
848
855
|
className?: string;
|
|
849
856
|
disabled?: boolean;
|
|
850
|
-
size?:
|
|
857
|
+
size?: "sm" | "md" | "lg";
|
|
851
858
|
label?: string;
|
|
852
859
|
title?: string;
|
|
853
860
|
required?: boolean;
|
|
854
861
|
displayFormat?: (option: MultiComboboxOption) => string;
|
|
862
|
+
loading?: boolean;
|
|
863
|
+
loadingText?: string;
|
|
864
|
+
emptyText?: string;
|
|
855
865
|
}
|
|
856
866
|
declare const MultiCombobox: React$1.FC<MultiComboboxProps>;
|
|
857
867
|
|
package/dist/index.js
CHANGED
|
@@ -2107,7 +2107,7 @@ var sizeStyles3 = {
|
|
|
2107
2107
|
md: "max-w-md",
|
|
2108
2108
|
lg: "max-w-lg",
|
|
2109
2109
|
xl: "max-w-xl",
|
|
2110
|
-
full: "max-w-full
|
|
2110
|
+
full: "max-w-full"
|
|
2111
2111
|
};
|
|
2112
2112
|
var Modal = ({
|
|
2113
2113
|
isOpen,
|
|
@@ -2116,11 +2116,16 @@ var Modal = ({
|
|
|
2116
2116
|
title,
|
|
2117
2117
|
description,
|
|
2118
2118
|
className,
|
|
2119
|
+
contentClassName,
|
|
2119
2120
|
overlayClassName,
|
|
2120
2121
|
showCloseButton = true,
|
|
2121
2122
|
closeOnOverlayClick = true,
|
|
2122
2123
|
closeOnEsc = true,
|
|
2123
|
-
size = "md"
|
|
2124
|
+
size = "md",
|
|
2125
|
+
noPadding = false,
|
|
2126
|
+
fullWidth = false,
|
|
2127
|
+
width,
|
|
2128
|
+
height
|
|
2124
2129
|
}) => {
|
|
2125
2130
|
const [isMounted, setIsMounted] = React9.useState(false);
|
|
2126
2131
|
const [isVisible, setIsVisible] = React9.useState(false);
|
|
@@ -2188,14 +2193,17 @@ var Modal = ({
|
|
|
2188
2193
|
className: cn(
|
|
2189
2194
|
"relative w-full rounded-lg bg-card text-card-foreground shadow-xl",
|
|
2190
2195
|
"transition-all duration-200 ease-out",
|
|
2191
|
-
sizeStyles3[size],
|
|
2196
|
+
fullWidth ? "max-w-full" : sizeStyles3[size],
|
|
2197
|
+
fullWidth && "mx-0",
|
|
2192
2198
|
className
|
|
2193
2199
|
),
|
|
2194
2200
|
style: {
|
|
2195
2201
|
opacity: isOpen && !isAnimating ? 1 : 0,
|
|
2196
2202
|
transform: isOpen && !isAnimating ? "scale(1)" : "scale(0.9)",
|
|
2197
2203
|
// Thêm dòng này để tạo hiệu ứng nảy
|
|
2198
|
-
transition: "all 300ms cubic-bezier(0.34, 1.76, 0.64, 1)"
|
|
2204
|
+
transition: "all 300ms cubic-bezier(0.34, 1.76, 0.64, 1)",
|
|
2205
|
+
width,
|
|
2206
|
+
height
|
|
2199
2207
|
},
|
|
2200
2208
|
onClick: (e) => e.stopPropagation(),
|
|
2201
2209
|
children: [
|
|
@@ -2217,7 +2225,7 @@ var Modal = ({
|
|
|
2217
2225
|
}
|
|
2218
2226
|
)
|
|
2219
2227
|
] }),
|
|
2220
|
-
/* @__PURE__ */ jsx13("div", { className: "p-6", children })
|
|
2228
|
+
/* @__PURE__ */ jsx13("div", { className: cn("p-6", noPadding && "p-0", contentClassName), children })
|
|
2221
2229
|
]
|
|
2222
2230
|
}
|
|
2223
2231
|
)
|
|
@@ -3846,7 +3854,7 @@ import { ChevronLeft, ChevronRight as ChevronRight2, MoreHorizontal as MoreHoriz
|
|
|
3846
3854
|
import * as React18 from "react";
|
|
3847
3855
|
import { useId as useId2 } from "react";
|
|
3848
3856
|
import { createPortal as createPortal6 } from "react-dom";
|
|
3849
|
-
import { ChevronDown, Search as Search2, Check as Check3, X as X7 } from "lucide-react";
|
|
3857
|
+
import { ChevronDown, Search as Search2, SearchX, Check as Check3, X as X7, Loader2 as Loader22 } from "lucide-react";
|
|
3850
3858
|
import { jsx as jsx24, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
3851
3859
|
var getOptionLabel = (option) => {
|
|
3852
3860
|
return typeof option === "string" ? option : option.label;
|
|
@@ -3872,7 +3880,9 @@ var Combobox = ({
|
|
|
3872
3880
|
usePortal = true,
|
|
3873
3881
|
label,
|
|
3874
3882
|
required,
|
|
3875
|
-
fontBold = false
|
|
3883
|
+
fontBold = false,
|
|
3884
|
+
loading: loading2 = false,
|
|
3885
|
+
loadingText = "Loading..."
|
|
3876
3886
|
}) => {
|
|
3877
3887
|
const [open, setOpen] = React18.useState(false);
|
|
3878
3888
|
const [query, setQuery] = React18.useState("");
|
|
@@ -3890,6 +3900,7 @@ var Combobox = ({
|
|
|
3890
3900
|
);
|
|
3891
3901
|
const [dropdownPosition, setDropdownPosition] = React18.useState(null);
|
|
3892
3902
|
const triggerRef = React18.useRef(null);
|
|
3903
|
+
const dropdownRef = React18.useRef(null);
|
|
3893
3904
|
const calculatePosition = React18.useCallback(() => {
|
|
3894
3905
|
if (!triggerRef.current) return null;
|
|
3895
3906
|
const rect = triggerRef.current.getBoundingClientRect();
|
|
@@ -3918,11 +3929,10 @@ var Combobox = ({
|
|
|
3918
3929
|
if (!open) return;
|
|
3919
3930
|
const handleClickOutside = (event) => {
|
|
3920
3931
|
const target = event.target;
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
}
|
|
3932
|
+
const triggerEl = triggerRef.current;
|
|
3933
|
+
const dropdownEl = dropdownRef.current;
|
|
3934
|
+
if (triggerEl && !triggerEl.contains(target) && dropdownEl && !dropdownEl.contains(target)) {
|
|
3935
|
+
setOpen(false);
|
|
3926
3936
|
}
|
|
3927
3937
|
};
|
|
3928
3938
|
const handleEscape = (event) => {
|
|
@@ -3966,6 +3976,7 @@ var Combobox = ({
|
|
|
3966
3976
|
"div",
|
|
3967
3977
|
{
|
|
3968
3978
|
"data-combobox-dropdown": true,
|
|
3979
|
+
ref: dropdownRef,
|
|
3969
3980
|
style: {
|
|
3970
3981
|
position: "absolute",
|
|
3971
3982
|
top: dropdownPosition?.top || 0,
|
|
@@ -4023,7 +4034,10 @@ var Combobox = ({
|
|
|
4023
4034
|
}
|
|
4024
4035
|
)
|
|
4025
4036
|
] }),
|
|
4026
|
-
/* @__PURE__ */ jsx24("div", { className: "max-h-64 overflow-y-auto overscroll-contain", children: /* @__PURE__ */ jsx24("ul", { className: "p-1 space-y-1", children:
|
|
4037
|
+
/* @__PURE__ */ jsx24("div", { className: "max-h-64 overflow-y-auto overscroll-contain", children: /* @__PURE__ */ jsx24("ul", { className: "p-1 space-y-1", children: loading2 ? /* @__PURE__ */ jsx24("li", { className: "px-3 py-8 text-center", children: /* @__PURE__ */ jsxs21("div", { className: "flex flex-col items-center gap-2 animate-in fade-in-0 zoom-in-95 duration-300", children: [
|
|
4038
|
+
/* @__PURE__ */ jsx24(Loader22, { className: "h-6 w-6 animate-spin text-primary" }),
|
|
4039
|
+
/* @__PURE__ */ jsx24("span", { className: "text-sm text-muted-foreground", children: loadingText || "Loading..." })
|
|
4040
|
+
] }) }) : filteredOptions.length > 0 ? filteredOptions.map((item, index) => {
|
|
4027
4041
|
const itemValue = getOptionValue(item);
|
|
4028
4042
|
const itemLabel = getOptionLabel(item);
|
|
4029
4043
|
const isSelected = itemValue === value;
|
|
@@ -4057,9 +4071,18 @@ var Combobox = ({
|
|
|
4057
4071
|
},
|
|
4058
4072
|
`${itemValue}-${index}`
|
|
4059
4073
|
);
|
|
4060
|
-
}) : /* @__PURE__ */ jsx24("li", { className: "px-3 py-8 text-center text-muted-foreground text-sm", children: /* @__PURE__ */ jsxs21("div", { className: "flex flex-col items-center gap-2", children: [
|
|
4061
|
-
/* @__PURE__ */ jsx24(
|
|
4062
|
-
/* @__PURE__ */ jsx24("span", { children: emptyText })
|
|
4074
|
+
}) : /* @__PURE__ */ jsx24("li", { className: "px-3 py-8 text-center text-muted-foreground text-sm", children: /* @__PURE__ */ jsxs21("div", { className: "flex flex-col items-center gap-2 animate-in fade-in-0 zoom-in-95 duration-300", children: [
|
|
4075
|
+
/* @__PURE__ */ jsx24(SearchX, { className: "h-8 w-8 opacity-40 text-muted-foreground" }),
|
|
4076
|
+
/* @__PURE__ */ jsx24("span", { className: "text-sm", children: emptyText }),
|
|
4077
|
+
query && /* @__PURE__ */ jsx24(
|
|
4078
|
+
"button",
|
|
4079
|
+
{
|
|
4080
|
+
type: "button",
|
|
4081
|
+
onClick: () => setQuery(""),
|
|
4082
|
+
className: "text-xs text-primary hover:underline",
|
|
4083
|
+
children: "Clear search"
|
|
4084
|
+
}
|
|
4085
|
+
)
|
|
4063
4086
|
] }) }) }) })
|
|
4064
4087
|
] })
|
|
4065
4088
|
}
|
|
@@ -4135,7 +4158,15 @@ var Combobox = ({
|
|
|
4135
4158
|
children: /* @__PURE__ */ jsx24(X7, { className: "h-3 w-3" })
|
|
4136
4159
|
}
|
|
4137
4160
|
),
|
|
4138
|
-
/* @__PURE__ */ jsx24(
|
|
4161
|
+
/* @__PURE__ */ jsx24(
|
|
4162
|
+
ChevronDown,
|
|
4163
|
+
{
|
|
4164
|
+
className: cn(
|
|
4165
|
+
"h-4 w-4 text-muted-foreground transition-all duration-200",
|
|
4166
|
+
open && "rotate-180 scale-110 text-primary"
|
|
4167
|
+
)
|
|
4168
|
+
}
|
|
4169
|
+
)
|
|
4139
4170
|
] })
|
|
4140
4171
|
]
|
|
4141
4172
|
}
|
|
@@ -6044,7 +6075,7 @@ function Calendar2({
|
|
|
6044
6075
|
import * as React24 from "react";
|
|
6045
6076
|
import { useId as useId4 } from "react";
|
|
6046
6077
|
import { createPortal as createPortal8 } from "react-dom";
|
|
6047
|
-
import { ChevronDown as ChevronDown2, Search as Search3, Check as Check5 } from "lucide-react";
|
|
6078
|
+
import { ChevronDown as ChevronDown2, Search as Search3, Check as Check5, SearchX as SearchX2, Loader2 as Loader23 } from "lucide-react";
|
|
6048
6079
|
import { jsx as jsx31, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
6049
6080
|
var MultiCombobox = ({
|
|
6050
6081
|
id,
|
|
@@ -6062,7 +6093,10 @@ var MultiCombobox = ({
|
|
|
6062
6093
|
label,
|
|
6063
6094
|
title,
|
|
6064
6095
|
required,
|
|
6065
|
-
displayFormat = (option) => option.label
|
|
6096
|
+
displayFormat = (option) => option.label,
|
|
6097
|
+
loading: loading2 = false,
|
|
6098
|
+
loadingText = "Loading...",
|
|
6099
|
+
emptyText = "No results found"
|
|
6066
6100
|
}) => {
|
|
6067
6101
|
const [query, setQuery] = React24.useState("");
|
|
6068
6102
|
const [open, setOpen] = React24.useState(false);
|
|
@@ -6071,6 +6105,7 @@ var MultiCombobox = ({
|
|
|
6071
6105
|
const listRef = React24.useRef([]);
|
|
6072
6106
|
const [dropdownPosition, setDropdownPosition] = React24.useState(null);
|
|
6073
6107
|
const triggerRef = React24.useRef(null);
|
|
6108
|
+
const dropdownRef = React24.useRef(null);
|
|
6074
6109
|
useShadCNAnimations();
|
|
6075
6110
|
const calculatePosition = React24.useCallback(() => {
|
|
6076
6111
|
if (!triggerRef.current) return null;
|
|
@@ -6100,11 +6135,10 @@ var MultiCombobox = ({
|
|
|
6100
6135
|
if (!open) return;
|
|
6101
6136
|
const handleClickOutside = (event) => {
|
|
6102
6137
|
const target = event.target;
|
|
6103
|
-
|
|
6104
|
-
|
|
6105
|
-
|
|
6106
|
-
|
|
6107
|
-
}
|
|
6138
|
+
const triggerEl = triggerRef.current;
|
|
6139
|
+
const dropdownEl = dropdownRef.current;
|
|
6140
|
+
if (triggerEl && !triggerEl.contains(target) && dropdownEl && !dropdownEl.contains(target)) {
|
|
6141
|
+
setOpen(false);
|
|
6108
6142
|
}
|
|
6109
6143
|
};
|
|
6110
6144
|
const handleEscape = (event) => {
|
|
@@ -6273,7 +6307,12 @@ var MultiCombobox = ({
|
|
|
6273
6307
|
value.length,
|
|
6274
6308
|
" selected"
|
|
6275
6309
|
] }) : /* @__PURE__ */ jsx31("span", { className: "text-muted-foreground", children: placeholder || "Select..." }) }),
|
|
6276
|
-
/* @__PURE__ */ jsx31(
|
|
6310
|
+
/* @__PURE__ */ jsx31(
|
|
6311
|
+
ChevronDown2,
|
|
6312
|
+
{
|
|
6313
|
+
className: cn("opacity-50 transition-all duration-200", sizeStyles8[size].icon, open && "rotate-180 scale-110 text-primary opacity-100")
|
|
6314
|
+
}
|
|
6315
|
+
)
|
|
6277
6316
|
]
|
|
6278
6317
|
}
|
|
6279
6318
|
),
|
|
@@ -6281,6 +6320,7 @@ var MultiCombobox = ({
|
|
|
6281
6320
|
/* @__PURE__ */ jsx31(
|
|
6282
6321
|
"div",
|
|
6283
6322
|
{
|
|
6323
|
+
ref: dropdownRef,
|
|
6284
6324
|
"data-dropdown": "multicombobox",
|
|
6285
6325
|
style: {
|
|
6286
6326
|
position: "absolute",
|
|
@@ -6298,10 +6338,7 @@ var MultiCombobox = ({
|
|
|
6298
6338
|
children: /* @__PURE__ */ jsxs26(
|
|
6299
6339
|
"div",
|
|
6300
6340
|
{
|
|
6301
|
-
className: cn(
|
|
6302
|
-
"rounded-md border bg-popover text-popover-foreground shadow-md",
|
|
6303
|
-
"backdrop-blur-sm bg-popover/95 border-border/60"
|
|
6304
|
-
),
|
|
6341
|
+
className: cn("rounded-md border bg-popover text-popover-foreground shadow-md", "backdrop-blur-sm bg-popover/95 border-border/60"),
|
|
6305
6342
|
children: [
|
|
6306
6343
|
showClear && value.length > 0 && /* @__PURE__ */ jsx31("div", { className: "px-3 py-2 border-b border-border/60 flex justify-end", children: /* @__PURE__ */ jsx31(
|
|
6307
6344
|
"button",
|
|
@@ -6333,7 +6370,10 @@ var MultiCombobox = ({
|
|
|
6333
6370
|
}
|
|
6334
6371
|
)
|
|
6335
6372
|
] }),
|
|
6336
|
-
/* @__PURE__ */ jsx31("ul", { className: cn("max-h-60 overflow-y-auto p-1", size === "lg" ? "text-base" : size === "sm" ? "text-xs" : "text-sm"), children:
|
|
6373
|
+
/* @__PURE__ */ jsx31("ul", { className: cn("max-h-60 overflow-y-auto p-1", size === "lg" ? "text-base" : size === "sm" ? "text-xs" : "text-sm"), children: loading2 ? /* @__PURE__ */ jsx31("li", { className: "px-3 py-8 text-center", children: /* @__PURE__ */ jsxs26("div", { className: "flex flex-col items-center gap-2 animate-in fade-in-0 zoom-in-95 duration-300", children: [
|
|
6374
|
+
/* @__PURE__ */ jsx31(Loader23, { className: "h-6 w-6 animate-spin text-primary" }),
|
|
6375
|
+
/* @__PURE__ */ jsx31("span", { className: "text-muted-foreground", children: loadingText })
|
|
6376
|
+
] }) }) : filtered.length ? filtered.map((item, index) => {
|
|
6337
6377
|
const isSelected = value.includes(item.value);
|
|
6338
6378
|
const isDisabled = disabledOptions.includes(item.value);
|
|
6339
6379
|
return /* @__PURE__ */ jsxs26(
|
|
@@ -6365,7 +6405,20 @@ var MultiCombobox = ({
|
|
|
6365
6405
|
},
|
|
6366
6406
|
item.value
|
|
6367
6407
|
);
|
|
6368
|
-
}) : /* @__PURE__ */ jsx31(
|
|
6408
|
+
}) : /* @__PURE__ */ jsx31(
|
|
6409
|
+
"li",
|
|
6410
|
+
{
|
|
6411
|
+
className: cn(
|
|
6412
|
+
"px-3 py-8 text-center text-muted-foreground",
|
|
6413
|
+
size === "lg" ? "text-base" : size === "sm" ? "text-xs" : "text-sm"
|
|
6414
|
+
),
|
|
6415
|
+
children: /* @__PURE__ */ jsxs26("div", { className: "flex flex-col items-center gap-2 animate-in fade-in-0 zoom-in-95 duration-300", children: [
|
|
6416
|
+
/* @__PURE__ */ jsx31(SearchX2, { className: "h-8 w-8 opacity-40 text-muted-foreground" }),
|
|
6417
|
+
/* @__PURE__ */ jsx31("span", { children: emptyText }),
|
|
6418
|
+
query && /* @__PURE__ */ jsx31("button", { type: "button", onClick: () => setQuery(""), className: "text-xs text-primary hover:underline", children: "Clear search" })
|
|
6419
|
+
] })
|
|
6420
|
+
}
|
|
6421
|
+
) })
|
|
6369
6422
|
]
|
|
6370
6423
|
}
|
|
6371
6424
|
)
|
|
@@ -7393,7 +7446,7 @@ function CategoryTreeSelect({ categories, value, onChange, placeholder = "Ch\u1E
|
|
|
7393
7446
|
|
|
7394
7447
|
// ../../components/ui/ImageUpload.tsx
|
|
7395
7448
|
import { useState as useState25, useRef as useRef10, useCallback as useCallback9 } from "react";
|
|
7396
|
-
import { Upload, X as X9, Image as ImageIcon, Loader2 as
|
|
7449
|
+
import { Upload, X as X9, Image as ImageIcon, Loader2 as Loader24, Check as Check7 } from "lucide-react";
|
|
7397
7450
|
import { useTranslations as useTranslations6 } from "next-intl";
|
|
7398
7451
|
import { jsx as jsx36, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
7399
7452
|
function ImageUpload({
|
|
@@ -7532,7 +7585,7 @@ function ImageUpload({
|
|
|
7532
7585
|
onDrop: handleDrop,
|
|
7533
7586
|
children: [
|
|
7534
7587
|
uploading && /* @__PURE__ */ jsx36("div", { className: "absolute inset-0 bg-background/80 flex items-center justify-center rounded-lg", children: /* @__PURE__ */ jsxs31("div", { className: "flex items-center gap-3", children: [
|
|
7535
|
-
/* @__PURE__ */ jsx36(
|
|
7588
|
+
/* @__PURE__ */ jsx36(Loader24, { className: "w-6 h-6 animate-spin text-primary" }),
|
|
7536
7589
|
/* @__PURE__ */ jsx36("span", { className: "text-sm font-medium", children: "Uploading..." })
|
|
7537
7590
|
] }) }),
|
|
7538
7591
|
/* @__PURE__ */ jsxs31("div", { className: "space-y-4", children: [
|
|
@@ -10035,11 +10088,44 @@ function DataTable({
|
|
|
10035
10088
|
col.key
|
|
10036
10089
|
)) });
|
|
10037
10090
|
const isServerMode = Boolean(onQueryChange);
|
|
10091
|
+
const processedData = React37.useMemo(() => {
|
|
10092
|
+
if (isServerMode) return data;
|
|
10093
|
+
let result = [...data];
|
|
10094
|
+
if (Object.keys(filters).length > 0) {
|
|
10095
|
+
result = result.filter((row) => {
|
|
10096
|
+
return Object.entries(filters).every(([key, value]) => {
|
|
10097
|
+
if (value === void 0 || value === null || value === "") return true;
|
|
10098
|
+
const col = columns.find((c) => c.key === key);
|
|
10099
|
+
const rowValue = col?.dataIndex ? row[col.dataIndex] : row[key];
|
|
10100
|
+
if (col?.filter?.type === "date" && value instanceof Date) {
|
|
10101
|
+
return new Date(rowValue).toDateString() === value.toDateString();
|
|
10102
|
+
}
|
|
10103
|
+
return String(rowValue ?? "").toLowerCase().includes(String(value).toLowerCase());
|
|
10104
|
+
});
|
|
10105
|
+
});
|
|
10106
|
+
}
|
|
10107
|
+
if (sort) {
|
|
10108
|
+
result.sort((a, b) => {
|
|
10109
|
+
const col = columns.find((c) => c.key === sort.key);
|
|
10110
|
+
const aValue = col?.dataIndex ? a[col.dataIndex] : a[sort.key];
|
|
10111
|
+
const bValue = col?.dataIndex ? b[col.dataIndex] : b[sort.key];
|
|
10112
|
+
if (aValue === bValue) return 0;
|
|
10113
|
+
if (typeof aValue === "number" && typeof bValue === "number") {
|
|
10114
|
+
return sort.order === "asc" ? aValue - bValue : bValue - aValue;
|
|
10115
|
+
}
|
|
10116
|
+
const compare = String(aValue).localeCompare(String(bValue));
|
|
10117
|
+
return sort.order === "asc" ? compare : -compare;
|
|
10118
|
+
});
|
|
10119
|
+
}
|
|
10120
|
+
return result;
|
|
10121
|
+
}, [data, isServerMode, filters, sort, columns]);
|
|
10122
|
+
const totalItems = isServerMode ? total : processedData.length;
|
|
10038
10123
|
const displayedData = isServerMode ? data : React37.useMemo(() => {
|
|
10039
10124
|
const start = (curPage - 1) * curPageSize;
|
|
10040
|
-
|
|
10041
|
-
|
|
10042
|
-
|
|
10125
|
+
if (start >= processedData.length && curPage > 1) {
|
|
10126
|
+
}
|
|
10127
|
+
return processedData.slice(start, start + curPageSize);
|
|
10128
|
+
}, [processedData, curPage, curPageSize]);
|
|
10043
10129
|
return /* @__PURE__ */ jsxs41("div", { className: cn("space-y-2", className), children: [
|
|
10044
10130
|
/* @__PURE__ */ jsxs41("div", { className: "flex items-center justify-between gap-4 mb-1", children: [
|
|
10045
10131
|
/* @__PURE__ */ jsx47("div", { className: "text-sm text-muted-foreground", children: caption }),
|
|
@@ -10111,24 +10197,27 @@ function DataTable({
|
|
|
10111
10197
|
)
|
|
10112
10198
|
] }),
|
|
10113
10199
|
/* @__PURE__ */ jsx47("span", { className: "text-sm", children: "Loading..." })
|
|
10114
|
-
] }) }) }) : !displayedData || displayedData.length === 0 ? /* @__PURE__ */ jsx47(TableRow, { children: /* @__PURE__ */ jsx47(TableCell, { colSpan: visibleColumns.length, className: "text-center py-6 text-muted-foreground", children: "No data" }) }) : displayedData.map((row, idx) =>
|
|
10115
|
-
const
|
|
10116
|
-
return /* @__PURE__ */ jsx47(
|
|
10117
|
-
|
|
10118
|
-
|
|
10119
|
-
|
|
10120
|
-
|
|
10121
|
-
|
|
10122
|
-
|
|
10123
|
-
|
|
10124
|
-
|
|
10125
|
-
|
|
10126
|
-
|
|
10127
|
-
|
|
10128
|
-
|
|
10129
|
-
|
|
10130
|
-
|
|
10131
|
-
|
|
10200
|
+
] }) }) }) : !displayedData || displayedData.length === 0 ? /* @__PURE__ */ jsx47(TableRow, { children: /* @__PURE__ */ jsx47(TableCell, { colSpan: visibleColumns.length, className: "text-center py-6 text-muted-foreground", children: "No data" }) }) : displayedData.map((row, idx) => {
|
|
10201
|
+
const isLastRow = idx === displayedData.length - 1;
|
|
10202
|
+
return /* @__PURE__ */ jsx47(TableRow, { className: cn(densityRowClass, striped && idx % 2 === 0 && "bg-muted/30"), children: visibleColumns.map((col, colIdx) => {
|
|
10203
|
+
const value = col.dataIndex ? row[col.dataIndex] : void 0;
|
|
10204
|
+
return /* @__PURE__ */ jsx47(
|
|
10205
|
+
TableCell,
|
|
10206
|
+
{
|
|
10207
|
+
className: cn(
|
|
10208
|
+
cellPadding,
|
|
10209
|
+
col.align === "right" && "text-right",
|
|
10210
|
+
col.align === "center" && "text-center",
|
|
10211
|
+
columnDividers && colIdx > 0 && "border-l border-border/60",
|
|
10212
|
+
isLastRow && col === visibleColumns[0] && "rounded-bl-md",
|
|
10213
|
+
isLastRow && col === visibleColumns[visibleColumns.length - 1] && "rounded-br-md"
|
|
10214
|
+
),
|
|
10215
|
+
children: col.render ? col.render(value, row, idx) : String(value ?? "")
|
|
10216
|
+
},
|
|
10217
|
+
col.key
|
|
10218
|
+
);
|
|
10219
|
+
}) }, getRowKey(row, idx));
|
|
10220
|
+
}) })
|
|
10132
10221
|
]
|
|
10133
10222
|
}
|
|
10134
10223
|
) }),
|