najm-kit 2.1.47 → 2.1.49
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/CHANGELOG.md +42 -0
- package/README.md +140 -6
- package/dist/index.d.ts +104 -5
- package/dist/index.mjs +625 -180
- package/dist/theme.css +60 -2
- package/package.json +4 -2
package/dist/index.mjs
CHANGED
|
@@ -7274,7 +7274,7 @@ function NSkeleton({ className, ...props }) {
|
|
|
7274
7274
|
return /* @__PURE__ */ jsx(
|
|
7275
7275
|
"div",
|
|
7276
7276
|
{
|
|
7277
|
-
className: cn("animate-pulse rounded-md bg-accent", className),
|
|
7277
|
+
className: cn("animate-pulse rounded-md bg-accent motion-reduce:animate-none", className),
|
|
7278
7278
|
"aria-hidden": "true",
|
|
7279
7279
|
...props
|
|
7280
7280
|
}
|
|
@@ -9850,12 +9850,74 @@ function UploaderRow({ item, onCancel, onRemove }) {
|
|
|
9850
9850
|
}
|
|
9851
9851
|
);
|
|
9852
9852
|
}
|
|
9853
|
+
|
|
9854
|
+
// src/components/inputs/imagePreview.ts
|
|
9855
|
+
var NON_APPENDABLE_PREFIXES = ["data:", "blob:", "javascript:", "file:"];
|
|
9856
|
+
function isNonAppendable(src) {
|
|
9857
|
+
const lower = src.toLowerCase();
|
|
9858
|
+
return NON_APPENDABLE_PREFIXES.some((prefix) => lower.startsWith(prefix));
|
|
9859
|
+
}
|
|
9860
|
+
function isMeaningful(src) {
|
|
9861
|
+
return typeof src === "string" && src.length > 0;
|
|
9862
|
+
}
|
|
9863
|
+
function appendImageVersion(src, version) {
|
|
9864
|
+
if (!isMeaningful(src)) return src;
|
|
9865
|
+
if (version == null || version === "") return src;
|
|
9866
|
+
if (isNonAppendable(src)) return src;
|
|
9867
|
+
const fragmentIndex = src.indexOf("#");
|
|
9868
|
+
const beforeFragment = fragmentIndex === -1 ? src : src.slice(0, fragmentIndex);
|
|
9869
|
+
const fragment = fragmentIndex === -1 ? "" : src.slice(fragmentIndex);
|
|
9870
|
+
const queryIndex = beforeFragment.indexOf("?");
|
|
9871
|
+
const base = queryIndex === -1 ? beforeFragment : beforeFragment.slice(0, queryIndex);
|
|
9872
|
+
const existingQuery = queryIndex === -1 ? "" : beforeFragment.slice(queryIndex);
|
|
9873
|
+
const separator = existingQuery ? "&" : "?";
|
|
9874
|
+
const versionString = `${separator}v=${encodeURIComponent(String(version))}`;
|
|
9875
|
+
if (!existingQuery && !fragment) {
|
|
9876
|
+
return `${base}${versionString}`;
|
|
9877
|
+
}
|
|
9878
|
+
if (!existingQuery) {
|
|
9879
|
+
return `${base}${versionString}${fragment}`;
|
|
9880
|
+
}
|
|
9881
|
+
if (!fragment) {
|
|
9882
|
+
return `${base}${existingQuery}${versionString}`;
|
|
9883
|
+
}
|
|
9884
|
+
return `${base}${existingQuery}${versionString}${fragment}`;
|
|
9885
|
+
}
|
|
9886
|
+
function appendVersionToCandidate(src, version) {
|
|
9887
|
+
if (version == null || version === "") return src;
|
|
9888
|
+
if (isNonAppendable(src)) return src;
|
|
9889
|
+
return appendImageVersion(src, version);
|
|
9890
|
+
}
|
|
9891
|
+
function buildPreviewCandidates(options) {
|
|
9892
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9893
|
+
const result = [];
|
|
9894
|
+
const push = (src, source) => {
|
|
9895
|
+
if (!isMeaningful(src)) return;
|
|
9896
|
+
if (seen.has(src)) return;
|
|
9897
|
+
seen.add(src);
|
|
9898
|
+
result.push({ src, source });
|
|
9899
|
+
};
|
|
9900
|
+
push(options.value ?? null, "value");
|
|
9901
|
+
push(options.fallback ?? null, "fallback");
|
|
9902
|
+
push(options.defaultImage ?? null, "default");
|
|
9903
|
+
const version = options.imageVersion;
|
|
9904
|
+
if (version == null || version === "") return result;
|
|
9905
|
+
return result.map((candidate) => ({
|
|
9906
|
+
src: appendVersionToCandidate(candidate.src, version),
|
|
9907
|
+
source: candidate.source
|
|
9908
|
+
}));
|
|
9909
|
+
}
|
|
9910
|
+
function candidatesKey(candidates) {
|
|
9911
|
+
return candidates.map((candidate) => `${candidate.source}:${candidate.src}`).join("|");
|
|
9912
|
+
}
|
|
9853
9913
|
var IMAGE_SIZE_MAP = {
|
|
9854
9914
|
sm: "w-16 h-16",
|
|
9855
9915
|
md: "w-24 h-24",
|
|
9856
9916
|
lg: "w-32 h-32",
|
|
9857
9917
|
xl: "w-40 h-40"
|
|
9858
9918
|
};
|
|
9919
|
+
var CONTROL_VISIBILITY = "nimage-input-control";
|
|
9920
|
+
var COMPACT_OVERLAY_VISIBILITY = "nimage-input-compact-overlay";
|
|
9859
9921
|
function ImageInput({
|
|
9860
9922
|
value,
|
|
9861
9923
|
onChange,
|
|
@@ -9863,11 +9925,19 @@ function ImageInput({
|
|
|
9863
9925
|
previewClassName,
|
|
9864
9926
|
previewStyle,
|
|
9865
9927
|
contentClassName,
|
|
9928
|
+
imageClassName,
|
|
9866
9929
|
showPreview = true,
|
|
9867
9930
|
previewPosition = "top",
|
|
9868
9931
|
allowClear = true,
|
|
9869
9932
|
accept = "image/*",
|
|
9870
9933
|
defaultImage,
|
|
9934
|
+
fallbackImage,
|
|
9935
|
+
previewAlt,
|
|
9936
|
+
fallbackAlt,
|
|
9937
|
+
unavailableContent,
|
|
9938
|
+
onPreviewError,
|
|
9939
|
+
replaceAriaLabel,
|
|
9940
|
+
clearAriaLabel,
|
|
9871
9941
|
imageSize = "md",
|
|
9872
9942
|
imageVersion,
|
|
9873
9943
|
disabled = false,
|
|
@@ -9882,117 +9952,242 @@ function ImageInput({
|
|
|
9882
9952
|
buttonLabel = "Upload"
|
|
9883
9953
|
}) {
|
|
9884
9954
|
const fileInputRef = useRef(null);
|
|
9885
|
-
const [
|
|
9955
|
+
const [localFilePreview, setLocalFilePreview] = useState(null);
|
|
9956
|
+
const [failedSources, setFailedSources] = useState(() => /* @__PURE__ */ new Set());
|
|
9957
|
+
const readerTokenRef = useRef(0);
|
|
9958
|
+
const previewCandidates = useMemo(() => {
|
|
9959
|
+
if (value instanceof File) return [];
|
|
9960
|
+
if (typeof value === "string" && value) {
|
|
9961
|
+
return buildPreviewCandidates({
|
|
9962
|
+
value,
|
|
9963
|
+
fallback: fallbackImage ?? null,
|
|
9964
|
+
defaultImage: defaultImage ?? null,
|
|
9965
|
+
imageVersion
|
|
9966
|
+
});
|
|
9967
|
+
}
|
|
9968
|
+
return buildPreviewCandidates({
|
|
9969
|
+
value: null,
|
|
9970
|
+
fallback: null,
|
|
9971
|
+
defaultImage: defaultImage ?? null,
|
|
9972
|
+
imageVersion
|
|
9973
|
+
});
|
|
9974
|
+
}, [value, fallbackImage, defaultImage, imageVersion]);
|
|
9975
|
+
const candidateKeyValue = useMemo(
|
|
9976
|
+
() => candidatesKey(previewCandidates),
|
|
9977
|
+
[previewCandidates]
|
|
9978
|
+
);
|
|
9979
|
+
const [trackedKey, setTrackedKey] = useState(candidateKeyValue);
|
|
9980
|
+
if (trackedKey !== candidateKeyValue) {
|
|
9981
|
+
setTrackedKey(candidateKeyValue);
|
|
9982
|
+
setFailedSources(/* @__PURE__ */ new Set());
|
|
9983
|
+
}
|
|
9886
9984
|
useEffect(() => {
|
|
9887
|
-
if (value instanceof File) {
|
|
9888
|
-
|
|
9889
|
-
|
|
9890
|
-
|
|
9891
|
-
|
|
9892
|
-
|
|
9893
|
-
|
|
9894
|
-
|
|
9895
|
-
|
|
9985
|
+
if (!(value instanceof File)) {
|
|
9986
|
+
setLocalFilePreview(null);
|
|
9987
|
+
return void 0;
|
|
9988
|
+
}
|
|
9989
|
+
const token = ++readerTokenRef.current;
|
|
9990
|
+
const reader = new FileReader();
|
|
9991
|
+
reader.onloadend = () => {
|
|
9992
|
+
if (token !== readerTokenRef.current) return;
|
|
9993
|
+
if (typeof reader.result === "string") {
|
|
9994
|
+
setLocalFilePreview(reader.result);
|
|
9995
|
+
}
|
|
9996
|
+
};
|
|
9997
|
+
reader.onerror = () => {
|
|
9998
|
+
if (token !== readerTokenRef.current) return;
|
|
9999
|
+
setLocalFilePreview(null);
|
|
10000
|
+
};
|
|
10001
|
+
reader.readAsDataURL(value);
|
|
10002
|
+
return () => {
|
|
10003
|
+
if (token === readerTokenRef.current) {
|
|
10004
|
+
readerTokenRef.current = token - 1;
|
|
10005
|
+
}
|
|
10006
|
+
};
|
|
10007
|
+
}, [value]);
|
|
10008
|
+
const activeCandidate = useMemo(() => {
|
|
10009
|
+
if (value instanceof File) return null;
|
|
10010
|
+
for (const candidate of previewCandidates) {
|
|
10011
|
+
if (!failedSources.has(candidate.src)) return candidate;
|
|
9896
10012
|
}
|
|
9897
|
-
|
|
10013
|
+
return null;
|
|
10014
|
+
}, [previewCandidates, failedSources, value]);
|
|
10015
|
+
const handleCandidateError = (candidate) => {
|
|
10016
|
+
setFailedSources((prev) => {
|
|
10017
|
+
if (prev.has(candidate.src)) return prev;
|
|
10018
|
+
const next = new Set(prev);
|
|
10019
|
+
next.add(candidate.src);
|
|
10020
|
+
return next;
|
|
10021
|
+
});
|
|
10022
|
+
onPreviewError?.({ source: candidate.source, src: candidate.src });
|
|
10023
|
+
};
|
|
9898
10024
|
const handleClick = () => {
|
|
9899
|
-
if (
|
|
10025
|
+
if (disabled) return;
|
|
10026
|
+
fileInputRef.current?.click();
|
|
9900
10027
|
};
|
|
9901
10028
|
const handleChange = (e) => {
|
|
9902
10029
|
const file = e.target.files?.[0] || null;
|
|
9903
10030
|
if (file) onChange(file);
|
|
10031
|
+
e.target.value = "";
|
|
9904
10032
|
};
|
|
9905
10033
|
const handleClear = (e) => {
|
|
9906
10034
|
e.stopPropagation();
|
|
10035
|
+
if (disabled) return;
|
|
9907
10036
|
onChange(null);
|
|
9908
|
-
|
|
10037
|
+
setLocalFilePreview(null);
|
|
9909
10038
|
if (fileInputRef.current) fileInputRef.current.value = "";
|
|
9910
10039
|
};
|
|
10040
|
+
const handleImgError = () => {
|
|
10041
|
+
if (value instanceof File) return;
|
|
10042
|
+
if (activeCandidate) handleCandidateError(activeCandidate);
|
|
10043
|
+
};
|
|
9911
10044
|
const effectiveSize = previewClassName || IMAGE_SIZE_MAP[imageSize];
|
|
9912
10045
|
const isDropzone = !!previewClassName;
|
|
9913
10046
|
const effectiveReplaceSubtitle = replaceSubtitle ?? subtitle;
|
|
10047
|
+
const primaryAlt = previewAlt ?? replaceTitle ?? "Preview";
|
|
10048
|
+
const secondaryAlt = fallbackAlt ?? previewAlt ?? replaceTitle ?? "Preview";
|
|
10049
|
+
const replaceAccessibleName = replaceAriaLabel ?? replaceTitle;
|
|
10050
|
+
const clearAccessibleName = clearAriaLabel ?? "Remove image";
|
|
10051
|
+
let dataState = "empty";
|
|
10052
|
+
let previewSrc = null;
|
|
10053
|
+
let previewAltText = primaryAlt;
|
|
10054
|
+
if (value instanceof File) {
|
|
10055
|
+
dataState = localFilePreview ? "preview" : "empty";
|
|
10056
|
+
previewSrc = localFilePreview;
|
|
10057
|
+
previewAltText = primaryAlt;
|
|
10058
|
+
} else if (activeCandidate) {
|
|
10059
|
+
dataState = activeCandidate.source === "value" ? "preview" : "fallback";
|
|
10060
|
+
previewSrc = activeCandidate.src;
|
|
10061
|
+
previewAltText = activeCandidate.source === "value" ? primaryAlt : secondaryAlt;
|
|
10062
|
+
} else if (previewCandidates.length > 0) {
|
|
10063
|
+
dataState = "unavailable";
|
|
10064
|
+
}
|
|
10065
|
+
const renderUnavailableContent = () => unavailableContent ?? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
10066
|
+
/* @__PURE__ */ jsx(Image, { className: "h-10 w-10 text-muted-foreground/50", "aria-hidden": true }),
|
|
10067
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "Image unavailable" })
|
|
10068
|
+
] });
|
|
10069
|
+
const renderClearButton = (compact) => {
|
|
10070
|
+
if (!allowClear) return null;
|
|
10071
|
+
return /* @__PURE__ */ jsx(
|
|
10072
|
+
"button",
|
|
10073
|
+
{
|
|
10074
|
+
type: "button",
|
|
10075
|
+
onClick: handleClear,
|
|
10076
|
+
disabled,
|
|
10077
|
+
"aria-label": clearAccessibleName,
|
|
10078
|
+
className: cn(
|
|
10079
|
+
"absolute top-2 end-2 z-10 flex items-center justify-center rounded-full bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
10080
|
+
compact ? "p-1.5" : "h-6 w-6",
|
|
10081
|
+
CONTROL_VISIBILITY
|
|
10082
|
+
),
|
|
10083
|
+
children: /* @__PURE__ */ jsx(X, { className: compact ? "h-4 w-4" : "h-3.5 w-3.5" })
|
|
10084
|
+
}
|
|
10085
|
+
);
|
|
10086
|
+
};
|
|
9914
10087
|
const renderPreview = () => /* @__PURE__ */ jsx(
|
|
9915
10088
|
"div",
|
|
9916
10089
|
{
|
|
9917
10090
|
style: previewStyle,
|
|
10091
|
+
"data-image-input-state": dataState,
|
|
9918
10092
|
className: cn(
|
|
9919
|
-
"flex relative
|
|
10093
|
+
"group/image flex relative rounded-lg overflow-hidden border-2 border-dashed border-muted-foreground/60 hover:border-primary transition-colors",
|
|
9920
10094
|
effectiveSize
|
|
9921
10095
|
),
|
|
9922
|
-
children:
|
|
9923
|
-
/* @__PURE__ */ jsx("img", { src: preview, alt: "Preview", className: "absolute inset-0 w-full h-full object-cover" }),
|
|
9924
|
-
/* @__PURE__ */ jsxs("div", { className: cn("relative w-full h-full flex flex-col items-center justify-center gap-1.5 bg-black/40 text-white px-6 py-8 text-center", contentClassName), children: [
|
|
9925
|
-
/* @__PURE__ */ jsx("span", { className: cn("text-sm font-medium", titleClassName), children: replaceTitle }),
|
|
9926
|
-
effectiveReplaceSubtitle ? /* @__PURE__ */ jsx("span", { className: cn("text-xs opacity-80", subtitleClassName), children: effectiveReplaceSubtitle }) : null,
|
|
9927
|
-
allowClear && /* @__PURE__ */ jsx(
|
|
9928
|
-
"button",
|
|
9929
|
-
{
|
|
9930
|
-
type: "button",
|
|
9931
|
-
onClick: handleClear,
|
|
9932
|
-
disabled,
|
|
9933
|
-
className: "absolute top-2 right-2 flex h-6 w-6 items-center justify-center rounded-full bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
|
|
9934
|
-
"aria-label": "Remove image",
|
|
9935
|
-
children: /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5" })
|
|
9936
|
-
}
|
|
9937
|
-
)
|
|
9938
|
-
] })
|
|
9939
|
-
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
9940
|
-
/* @__PURE__ */ jsx("img", { src: preview, alt: "Preview", className: "w-full h-full object-cover" }),
|
|
10096
|
+
children: previewSrc ? isDropzone ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
9941
10097
|
/* @__PURE__ */ jsx(
|
|
9942
|
-
"
|
|
10098
|
+
"img",
|
|
9943
10099
|
{
|
|
9944
|
-
|
|
9945
|
-
|
|
9946
|
-
|
|
10100
|
+
src: previewSrc,
|
|
10101
|
+
alt: previewAltText,
|
|
10102
|
+
onError: handleImgError,
|
|
10103
|
+
className: cn(
|
|
10104
|
+
"absolute inset-0 w-full h-full object-cover",
|
|
10105
|
+
imageClassName
|
|
10106
|
+
)
|
|
9947
10107
|
}
|
|
9948
10108
|
),
|
|
9949
|
-
|
|
10109
|
+
/* @__PURE__ */ jsxs(
|
|
9950
10110
|
"button",
|
|
9951
10111
|
{
|
|
9952
10112
|
type: "button",
|
|
9953
|
-
onClick:
|
|
10113
|
+
onClick: handleClick,
|
|
9954
10114
|
disabled,
|
|
9955
|
-
|
|
9956
|
-
|
|
10115
|
+
"aria-label": replaceAccessibleName,
|
|
10116
|
+
className: cn(
|
|
10117
|
+
"relative w-full h-full flex flex-col items-center justify-center gap-1.5 bg-black/40 text-white px-6 py-8 text-center cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
10118
|
+
contentClassName
|
|
10119
|
+
),
|
|
10120
|
+
children: [
|
|
10121
|
+
/* @__PURE__ */ jsx("span", { className: cn("text-sm font-medium", titleClassName), children: replaceTitle }),
|
|
10122
|
+
effectiveReplaceSubtitle ? /* @__PURE__ */ jsx("span", { className: cn("text-xs opacity-80", subtitleClassName), children: effectiveReplaceSubtitle }) : null
|
|
10123
|
+
]
|
|
9957
10124
|
}
|
|
9958
|
-
)
|
|
9959
|
-
|
|
9960
|
-
|
|
10125
|
+
),
|
|
10126
|
+
renderClearButton(false)
|
|
10127
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
9961
10128
|
/* @__PURE__ */ jsx(
|
|
9962
|
-
"
|
|
10129
|
+
"img",
|
|
10130
|
+
{
|
|
10131
|
+
src: previewSrc,
|
|
10132
|
+
alt: previewAltText,
|
|
10133
|
+
onError: handleImgError,
|
|
10134
|
+
className: cn("w-full h-full", imageClassName ?? "object-cover")
|
|
10135
|
+
}
|
|
10136
|
+
),
|
|
10137
|
+
/* @__PURE__ */ jsx(
|
|
10138
|
+
"button",
|
|
9963
10139
|
{
|
|
10140
|
+
type: "button",
|
|
9964
10141
|
onClick: handleClick,
|
|
9965
|
-
|
|
9966
|
-
|
|
10142
|
+
disabled,
|
|
10143
|
+
"aria-label": replaceAccessibleName,
|
|
10144
|
+
className: cn(
|
|
10145
|
+
"absolute inset-0 bg-black/50 flex items-center justify-center cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
10146
|
+
COMPACT_OVERLAY_VISIBILITY
|
|
10147
|
+
),
|
|
10148
|
+
children: /* @__PURE__ */ jsx(Upload, { className: "h-8 w-8 text-white", "aria-hidden": true })
|
|
9967
10149
|
}
|
|
9968
|
-
)
|
|
9969
|
-
|
|
10150
|
+
),
|
|
10151
|
+
renderClearButton(true)
|
|
10152
|
+
] }) : dataState === "unavailable" ? /* @__PURE__ */ jsx(
|
|
9970
10153
|
"div",
|
|
9971
10154
|
{
|
|
10155
|
+
"data-image-input-unavailable": true,
|
|
10156
|
+
className: cn(
|
|
10157
|
+
"w-full h-full flex flex-col items-center justify-center gap-2 bg-muted/30 text-muted-foreground px-6 py-8 text-center",
|
|
10158
|
+
contentClassName
|
|
10159
|
+
),
|
|
10160
|
+
children: renderUnavailableContent()
|
|
10161
|
+
}
|
|
10162
|
+
) : isDropzone ? /* @__PURE__ */ jsxs(
|
|
10163
|
+
"button",
|
|
10164
|
+
{
|
|
10165
|
+
type: "button",
|
|
9972
10166
|
onClick: handleClick,
|
|
9973
|
-
|
|
10167
|
+
disabled,
|
|
10168
|
+
"aria-label": replaceAriaLabel ?? title,
|
|
10169
|
+
className: cn(
|
|
10170
|
+
"w-full h-full flex flex-col items-center justify-center gap-2 cursor-pointer bg-muted/30 hover:bg-muted/50 transition-colors px-6 py-8 text-center focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
10171
|
+
contentClassName
|
|
10172
|
+
),
|
|
9974
10173
|
children: [
|
|
9975
10174
|
(trigger === "icon" || trigger === "both") && /* @__PURE__ */ jsx("div", { className: "text-primary", children: uploadIcon ?? /* @__PURE__ */ jsx(Plus, { className: "h-8 w-8" }) }),
|
|
9976
|
-
(trigger === "button" || trigger === "both") && /* @__PURE__ */ jsx(
|
|
9977
|
-
"span",
|
|
9978
|
-
{
|
|
9979
|
-
role: "button",
|
|
9980
|
-
className: "inline-flex items-center justify-center rounded-md border border-input bg-background px-3 py-1.5 text-xs font-medium text-foreground shadow-sm hover:bg-accent hover:text-accent-foreground",
|
|
9981
|
-
children: buttonLabel
|
|
9982
|
-
}
|
|
9983
|
-
),
|
|
10175
|
+
(trigger === "button" || trigger === "both") && /* @__PURE__ */ jsx("span", { className: "inline-flex items-center justify-center rounded-md border border-input bg-background px-3 py-1.5 text-xs font-medium text-foreground shadow-sm hover:bg-accent hover:text-accent-foreground", children: buttonLabel }),
|
|
9984
10176
|
/* @__PURE__ */ jsx("span", { className: cn("text-sm font-medium text-foreground", titleClassName), children: title }),
|
|
9985
10177
|
subtitle ? /* @__PURE__ */ jsx("span", { className: cn("text-xs text-muted-foreground", subtitleClassName), children: subtitle }) : null
|
|
9986
10178
|
]
|
|
9987
10179
|
}
|
|
9988
10180
|
) : /* @__PURE__ */ jsxs(
|
|
9989
|
-
"
|
|
10181
|
+
"button",
|
|
9990
10182
|
{
|
|
10183
|
+
type: "button",
|
|
9991
10184
|
onClick: handleClick,
|
|
9992
|
-
|
|
10185
|
+
disabled,
|
|
10186
|
+
"aria-label": replaceAriaLabel ?? title,
|
|
10187
|
+
className: "w-full h-full flex flex-col items-center justify-center cursor-pointer bg-muted/30 hover:bg-muted/50 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
9993
10188
|
children: [
|
|
9994
|
-
/* @__PURE__ */ jsx(Image, { className: "h-12 w-12 text-muted-foreground/50 mb-2" }),
|
|
9995
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground text-center px-2", children:
|
|
10189
|
+
/* @__PURE__ */ jsx(Image, { className: "h-12 w-12 text-muted-foreground/50 mb-2", "aria-hidden": true }),
|
|
10190
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground text-center px-2", children: title })
|
|
9996
10191
|
]
|
|
9997
10192
|
}
|
|
9998
10193
|
)
|
|
@@ -10006,20 +10201,42 @@ function ImageInput({
|
|
|
10006
10201
|
onChange: handleChange,
|
|
10007
10202
|
className: "hidden",
|
|
10008
10203
|
accept,
|
|
10009
|
-
disabled
|
|
10204
|
+
disabled,
|
|
10205
|
+
"aria-hidden": true,
|
|
10206
|
+
tabIndex: -1
|
|
10010
10207
|
}
|
|
10011
10208
|
);
|
|
10012
10209
|
if (!showPreview) return renderFileInput();
|
|
10013
10210
|
if (previewPosition === "left" || previewPosition === "right") {
|
|
10014
|
-
return /* @__PURE__ */ jsxs(
|
|
10015
|
-
|
|
10016
|
-
|
|
10017
|
-
|
|
10211
|
+
return /* @__PURE__ */ jsxs(
|
|
10212
|
+
"div",
|
|
10213
|
+
{
|
|
10214
|
+
className: cn(
|
|
10215
|
+
"flex items-center gap-4",
|
|
10216
|
+
previewPosition === "right" && "flex-row-reverse",
|
|
10217
|
+
containerClassName
|
|
10218
|
+
),
|
|
10219
|
+
children: [
|
|
10220
|
+
renderPreview(),
|
|
10221
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1", children: renderFileInput() })
|
|
10222
|
+
]
|
|
10223
|
+
}
|
|
10224
|
+
);
|
|
10018
10225
|
}
|
|
10019
|
-
return /* @__PURE__ */ jsxs(
|
|
10020
|
-
|
|
10021
|
-
|
|
10022
|
-
|
|
10226
|
+
return /* @__PURE__ */ jsxs(
|
|
10227
|
+
"div",
|
|
10228
|
+
{
|
|
10229
|
+
className: cn(
|
|
10230
|
+
"flex flex-col gap-3",
|
|
10231
|
+
previewPosition === "bottom" && "flex-col-reverse",
|
|
10232
|
+
containerClassName
|
|
10233
|
+
),
|
|
10234
|
+
children: [
|
|
10235
|
+
renderPreview(),
|
|
10236
|
+
renderFileInput()
|
|
10237
|
+
]
|
|
10238
|
+
}
|
|
10239
|
+
);
|
|
10023
10240
|
}
|
|
10024
10241
|
var AVATAR_SIZE_MAP = {
|
|
10025
10242
|
sm: "size-16",
|
|
@@ -11629,7 +11846,14 @@ var createTableStore = () => {
|
|
|
11629
11846
|
addButtonText: "",
|
|
11630
11847
|
pageSizeOptions: [10, 20, 30, 40, 50],
|
|
11631
11848
|
calculatedPageSize: 10,
|
|
11849
|
+
skeletonRowCount: 6,
|
|
11632
11850
|
maxHeight: null,
|
|
11851
|
+
bodyWidth: 0,
|
|
11852
|
+
bodyHeight: 0,
|
|
11853
|
+
tableHeaderHeight: 48,
|
|
11854
|
+
cardColumnCount: 1,
|
|
11855
|
+
cardRowHeight: 0,
|
|
11856
|
+
cardGap: 12,
|
|
11633
11857
|
// JSON mode
|
|
11634
11858
|
jsonValue: void 0,
|
|
11635
11859
|
jsonColors: null,
|
|
@@ -11699,6 +11923,8 @@ var createTableStore = () => {
|
|
|
11699
11923
|
// Responsive cards
|
|
11700
11924
|
responsiveCards: true,
|
|
11701
11925
|
isMobile: false,
|
|
11926
|
+
effectiveViewMode: "table",
|
|
11927
|
+
cardPagination: { mode: "paged" },
|
|
11702
11928
|
// Empty states
|
|
11703
11929
|
isEmpty: void 0,
|
|
11704
11930
|
isFilteredEmpty: false,
|
|
@@ -11774,6 +12000,8 @@ function filterResponsiveColumns(columns) {
|
|
|
11774
12000
|
// src/components/table/hooks.ts
|
|
11775
12001
|
var ROW_HEIGHT = 56;
|
|
11776
12002
|
var DEFAULT_TABLE_HEADER_HEIGHT = 48;
|
|
12003
|
+
var DEFAULT_CARD_HEIGHT = 176;
|
|
12004
|
+
var DEFAULT_CARD_GAP = 12;
|
|
11777
12005
|
var ROOT_SECTION_GAP_COUNT = 2;
|
|
11778
12006
|
function useStoreSync(props) {
|
|
11779
12007
|
const storeRef = useRef(null);
|
|
@@ -11854,23 +12082,43 @@ function calculateDynamicPageSize(input) {
|
|
|
11854
12082
|
if (availableRowsHeight <= 0) return 1;
|
|
11855
12083
|
return Math.max(1, Math.floor(availableRowsHeight / rowHeight));
|
|
11856
12084
|
}
|
|
11857
|
-
function
|
|
12085
|
+
function calculateCardSkeletonCount(input) {
|
|
12086
|
+
const columns = Math.max(1, Math.floor(input.columnCount));
|
|
12087
|
+
const cardHeight = Math.max(1, input.cardHeight ?? DEFAULT_CARD_HEIGHT);
|
|
12088
|
+
const gap = Math.max(0, input.gap ?? DEFAULT_CARD_GAP);
|
|
12089
|
+
if (input.bodyHeight <= 0) return columns;
|
|
12090
|
+
const rows = Math.max(1, Math.ceil((input.bodyHeight + gap) / (cardHeight + gap)));
|
|
12091
|
+
return rows * columns;
|
|
12092
|
+
}
|
|
12093
|
+
function fallbackCardColumns(width) {
|
|
12094
|
+
if (width >= 1280) return 4;
|
|
12095
|
+
if (width >= 1024) return 3;
|
|
12096
|
+
if (width >= 640) return 2;
|
|
12097
|
+
return 1;
|
|
12098
|
+
}
|
|
12099
|
+
function useDynamicPageSize(containerRef, effectiveViewMode) {
|
|
11858
12100
|
const dynamicHeight = useTableStore.use.dynamicHeight();
|
|
11859
|
-
const viewMode = useTableStore.use.
|
|
12101
|
+
const viewMode = useTableStore.use.effectiveViewMode();
|
|
11860
12102
|
const manualPagination = useTableStore.use.manualPagination();
|
|
11861
12103
|
const isLoading = useTableStore.use.isLoading();
|
|
11862
12104
|
const error = useTableStore.use.error();
|
|
11863
12105
|
const hasNoData = useTableStore.use.hasNoData();
|
|
11864
12106
|
const isFilteredEmpty = useTableStore.use.isFilteredEmpty();
|
|
11865
12107
|
const syncWithProps = useTableStore.use.syncWithProps();
|
|
12108
|
+
const lastMeasurementRef = useRef("");
|
|
11866
12109
|
useLayoutEffect(() => {
|
|
11867
|
-
if (!dynamicHeight || !containerRef.current
|
|
12110
|
+
if (!dynamicHeight || !containerRef.current) return;
|
|
11868
12111
|
const calculatePageSize = () => {
|
|
11869
12112
|
const container2 = containerRef.current;
|
|
11870
12113
|
if (!container2) return;
|
|
11871
12114
|
const bodyEl = container2.querySelector("[data-ntable-body]");
|
|
11872
12115
|
const tableHeaderEl = container2.querySelector("[data-ntable-table-header]");
|
|
12116
|
+
const loadingHeaderEl = container2.querySelector("[data-ntable-loading-header]");
|
|
12117
|
+
const cardsGridEl = container2.querySelector(
|
|
12118
|
+
"[data-ntable-loading-cards-grid], [data-ntable-cards-grid]"
|
|
12119
|
+
);
|
|
11873
12120
|
let bodyHeight = bodyEl?.clientHeight ?? 0;
|
|
12121
|
+
const bodyWidth = bodyEl?.clientWidth ?? container2.clientWidth ?? 0;
|
|
11874
12122
|
if (!bodyHeight) {
|
|
11875
12123
|
const rootHeight = container2.clientHeight;
|
|
11876
12124
|
const headerHeight = container2.querySelector("[data-ntable-header]")?.offsetHeight ?? 0;
|
|
@@ -11879,10 +12127,36 @@ function useDynamicPageSize(containerRef) {
|
|
|
11879
12127
|
const gap = Number.parseFloat(rootStyles.rowGap || rootStyles.gap || "0") || 0;
|
|
11880
12128
|
bodyHeight = rootHeight - headerHeight - paginationHeight - gap * ROOT_SECTION_GAP_COUNT;
|
|
11881
12129
|
}
|
|
12130
|
+
if (loadingHeaderEl && bodyEl) {
|
|
12131
|
+
const bodyStyles = window.getComputedStyle(bodyEl);
|
|
12132
|
+
const bodyGap = Number.parseFloat(bodyStyles.rowGap || bodyStyles.gap || "0") || 0;
|
|
12133
|
+
bodyHeight = Math.max(0, bodyHeight - loadingHeaderEl.offsetHeight - bodyGap);
|
|
12134
|
+
}
|
|
11882
12135
|
const tableHeaderHeight = tableHeaderEl?.offsetHeight ?? DEFAULT_TABLE_HEADER_HEIGHT;
|
|
11883
12136
|
const newPageSize = calculateDynamicPageSize({ bodyHeight, tableHeaderHeight });
|
|
11884
12137
|
const calculatedMaxHeight = tableHeaderHeight + newPageSize * ROW_HEIGHT;
|
|
11885
|
-
|
|
12138
|
+
const gridStyles = cardsGridEl ? window.getComputedStyle(cardsGridEl) : null;
|
|
12139
|
+
const gridTemplateColumns = gridStyles?.gridTemplateColumns;
|
|
12140
|
+
const gridColumns = gridTemplateColumns && gridTemplateColumns !== "none" ? gridTemplateColumns.split(" ").filter(Boolean).length : 0;
|
|
12141
|
+
const cardColumnCount = gridColumns || fallbackCardColumns(bodyWidth);
|
|
12142
|
+
const cardGap = Number.parseFloat(gridStyles?.rowGap || gridStyles?.gap || "") || DEFAULT_CARD_GAP;
|
|
12143
|
+
const firstCard = cardsGridEl?.querySelector("[data-ntable-loading-card], [data-row]");
|
|
12144
|
+
const cardRowHeight = firstCard?.offsetHeight || firstCard?.getBoundingClientRect().height || DEFAULT_CARD_HEIGHT;
|
|
12145
|
+
const updates = {
|
|
12146
|
+
...!manualPagination ? { calculatedPageSize: newPageSize, maxHeight: calculatedMaxHeight } : {},
|
|
12147
|
+
skeletonRowCount: newPageSize,
|
|
12148
|
+
bodyWidth,
|
|
12149
|
+
bodyHeight,
|
|
12150
|
+
tableHeaderHeight,
|
|
12151
|
+
cardColumnCount,
|
|
12152
|
+
cardRowHeight,
|
|
12153
|
+
cardGap
|
|
12154
|
+
};
|
|
12155
|
+
const fingerprint = JSON.stringify(updates);
|
|
12156
|
+
if (fingerprint !== lastMeasurementRef.current) {
|
|
12157
|
+
lastMeasurementRef.current = fingerprint;
|
|
12158
|
+
syncWithProps(updates);
|
|
12159
|
+
}
|
|
11886
12160
|
};
|
|
11887
12161
|
calculatePageSize();
|
|
11888
12162
|
const resizeObserver = new ResizeObserver(calculatePageSize);
|
|
@@ -11891,11 +12165,14 @@ function useDynamicPageSize(containerRef) {
|
|
|
11891
12165
|
container.querySelectorAll(
|
|
11892
12166
|
"[data-ntable-header], [data-ntable-body], [data-ntable-pagination], [data-ntable-table-header]"
|
|
11893
12167
|
).forEach((el) => resizeObserver.observe(el));
|
|
12168
|
+
container.querySelectorAll(
|
|
12169
|
+
"[data-ntable-loading-header], [data-ntable-loading-cards-grid], [data-ntable-loading-card], [data-ntable-cards-grid]"
|
|
12170
|
+
).forEach((el) => resizeObserver.observe(el));
|
|
11894
12171
|
if (container.parentElement) resizeObserver.observe(container.parentElement);
|
|
11895
12172
|
return () => resizeObserver.disconnect();
|
|
11896
|
-
}, [dynamicHeight, viewMode, containerRef, syncWithProps, manualPagination, isLoading, error, hasNoData, isFilteredEmpty]);
|
|
12173
|
+
}, [dynamicHeight, effectiveViewMode, viewMode, containerRef, syncWithProps, manualPagination, isLoading, error, hasNoData, isFilteredEmpty]);
|
|
11897
12174
|
}
|
|
11898
|
-
function useTable() {
|
|
12175
|
+
function useTable(effectiveViewModeOverride) {
|
|
11899
12176
|
const [sorting, setSorting] = useState([]);
|
|
11900
12177
|
const [columnFilters, setColumnFilters] = useState([]);
|
|
11901
12178
|
const [columnVisibility, setColumnVisibility] = useState({});
|
|
@@ -11912,6 +12189,8 @@ function useTable() {
|
|
|
11912
12189
|
const CardComponent = useTableStore.use.CardComponent();
|
|
11913
12190
|
const dynamicHeight = useTableStore.use.dynamicHeight();
|
|
11914
12191
|
const viewMode = useTableStore.use.viewMode();
|
|
12192
|
+
const effectiveViewMode = useTableStore.use.effectiveViewMode();
|
|
12193
|
+
const cardPagination = useTableStore.use.cardPagination();
|
|
11915
12194
|
const calculatedPageSize = useTableStore.use.calculatedPageSize();
|
|
11916
12195
|
const syncWithProps = useTableStore.use.syncWithProps();
|
|
11917
12196
|
const onStateChange = useTableStore.use.onStateChange();
|
|
@@ -12002,6 +12281,8 @@ function useTable() {
|
|
|
12002
12281
|
notifyStateChange({ sorting, columnFilters, columnVisibility, rowSelection: storeRowSelection, globalFilter });
|
|
12003
12282
|
}, [storePagination, storeRowSelection, setPagination, sorting, columnFilters, columnVisibility, globalFilter, notifyStateChange]);
|
|
12004
12283
|
const hasExpansion = Boolean(renderSubRow || userGetRowCanExpand);
|
|
12284
|
+
const renderedMode = effectiveViewModeOverride ?? effectiveViewMode ?? viewMode;
|
|
12285
|
+
const renderAllSuppliedRows = renderedMode === "cards" && cardPagination.mode !== "paged";
|
|
12005
12286
|
const tableConfig = {
|
|
12006
12287
|
data,
|
|
12007
12288
|
columns: finalColumns,
|
|
@@ -12018,7 +12299,7 @@ function useTable() {
|
|
|
12018
12299
|
getPaginationRowModel: getPaginationRowModel(),
|
|
12019
12300
|
getSortedRowModel: getSortedRowModel(),
|
|
12020
12301
|
getExpandedRowModel: getExpandedRowModel(),
|
|
12021
|
-
manualPagination,
|
|
12302
|
+
manualPagination: manualPagination || renderAllSuppliedRows,
|
|
12022
12303
|
pageCount,
|
|
12023
12304
|
rowCount
|
|
12024
12305
|
};
|
|
@@ -12032,9 +12313,11 @@ function useTable() {
|
|
|
12032
12313
|
}, [table]);
|
|
12033
12314
|
useLayoutEffect(() => {
|
|
12034
12315
|
if (manualPagination) return;
|
|
12035
|
-
if (dynamicHeight &&
|
|
12036
|
-
if (viewMode === "cards"
|
|
12037
|
-
|
|
12316
|
+
if (dynamicHeight && renderedMode === "table") table.setPageSize(calculatedPageSize);
|
|
12317
|
+
if (viewMode === "cards" && cardPagination.mode === "paged") {
|
|
12318
|
+
table.setPageSize(data.length || 9999);
|
|
12319
|
+
}
|
|
12320
|
+
}, [calculatedPageSize, dynamicHeight, renderedMode, viewMode, cardPagination.mode, table, data.length, manualPagination]);
|
|
12038
12321
|
return { table, finalColumns, sorting, setSorting, columnFilters, setColumnFilters, columnVisibility, setColumnVisibility, globalFilter, setGlobalFilter };
|
|
12039
12322
|
}
|
|
12040
12323
|
function useTableKeyboard(options = {}) {
|
|
@@ -12128,6 +12411,26 @@ function resolveTableColor(value, fallback) {
|
|
|
12128
12411
|
}
|
|
12129
12412
|
return color;
|
|
12130
12413
|
}
|
|
12414
|
+
|
|
12415
|
+
// src/components/table/tableSurface.ts
|
|
12416
|
+
function useTableSurfaceAppearance(bordered, borderColor) {
|
|
12417
|
+
const recipe = useNajmComponentStyle("table");
|
|
12418
|
+
const recipeRadius = resolveRadiusValue(recipe?.radius);
|
|
12419
|
+
const resolvedBorderColor = resolveTableColor(borderColor, DEFAULT_TABLE_BORDER_COLOR);
|
|
12420
|
+
const style = recipeRadius || bordered !== false && (recipe?.borderWidth || borderColor) ? {
|
|
12421
|
+
...recipeRadius ? { borderRadius: recipeRadius } : {},
|
|
12422
|
+
...bordered !== false && recipe?.borderWidth ? { borderWidth: recipe.borderWidth } : {},
|
|
12423
|
+
...bordered !== false && borderColor ? { borderColor: resolvedBorderColor } : {}
|
|
12424
|
+
} : void 0;
|
|
12425
|
+
return {
|
|
12426
|
+
bordered,
|
|
12427
|
+
style,
|
|
12428
|
+
className: cn(
|
|
12429
|
+
"bg-card",
|
|
12430
|
+
bordered === true ? surfaceBorderClasses(true) : "border-0 shadow-sm"
|
|
12431
|
+
)
|
|
12432
|
+
};
|
|
12433
|
+
}
|
|
12131
12434
|
var ROW_CONTEXT_HANDLED = "__ntableRowContextHandled";
|
|
12132
12435
|
function EditableCell({ cell, onCellEdit }) {
|
|
12133
12436
|
const columnDef = cell.column.columnDef;
|
|
@@ -12182,12 +12485,6 @@ function EditableCell({ cell, onCellEdit }) {
|
|
|
12182
12485
|
] });
|
|
12183
12486
|
}
|
|
12184
12487
|
function NTableContent({ effectiveMode }) {
|
|
12185
|
-
const recipe = useNajmComponentStyle("table");
|
|
12186
|
-
const recipeRadius = resolveRadiusValue(recipe?.radius);
|
|
12187
|
-
const recipeStyle = recipeRadius || recipe?.borderWidth ? {
|
|
12188
|
-
...recipeRadius ? { borderRadius: recipeRadius } : {},
|
|
12189
|
-
...recipe?.borderWidth ? { borderWidth: recipe.borderWidth } : {}
|
|
12190
|
-
} : void 0;
|
|
12191
12488
|
const table = useTableStore.use.table();
|
|
12192
12489
|
const storeIsTableView = useTableStore.use.isTableView();
|
|
12193
12490
|
const columns = useTableStore.use.columns();
|
|
@@ -12204,10 +12501,6 @@ function NTableContent({ effectiveMode }) {
|
|
|
12204
12501
|
backgroundColor: resolvedHeaderColor,
|
|
12205
12502
|
color: resolvedHeaderTextColor
|
|
12206
12503
|
};
|
|
12207
|
-
const contentStyle = recipeStyle || tableBorderColor ? {
|
|
12208
|
-
...recipeStyle ?? {},
|
|
12209
|
-
...tableBorderColor ? { borderColor: resolvedBorderColor } : {}
|
|
12210
|
-
} : void 0;
|
|
12211
12504
|
const rowBorderStyle = tableBorderColor ? { borderColor: resolvedBorderColor } : void 0;
|
|
12212
12505
|
const onRowClick = useTableStore.use.onRowClick();
|
|
12213
12506
|
const onRowContextMenu = useTableStore.use.onRowContextMenu();
|
|
@@ -12220,6 +12513,7 @@ function NTableContent({ effectiveMode }) {
|
|
|
12220
12513
|
const showContent = useTableStore.use.showContent();
|
|
12221
12514
|
const classNames = useTableStore.use.classNames();
|
|
12222
12515
|
const bordered = useTableStore.use.bordered();
|
|
12516
|
+
const surface = useTableSurfaceAppearance(bordered, tableBorderColor);
|
|
12223
12517
|
const showCheckbox = useTableStore.use.showCheckbox();
|
|
12224
12518
|
const selectedRowId = useTableStore.use.selectedRowId();
|
|
12225
12519
|
const renderSubRow = useTableStore.use.renderSubRow();
|
|
@@ -12248,11 +12542,11 @@ function NTableContent({ effectiveMode }) {
|
|
|
12248
12542
|
axis: "both",
|
|
12249
12543
|
"data-bordered": bordered === false ? "false" : bordered ? "true" : void 0,
|
|
12250
12544
|
className: cn(
|
|
12251
|
-
"min-h-0 flex-1 overflow-hidden rounded-md
|
|
12252
|
-
|
|
12545
|
+
"min-h-0 flex-1 overflow-hidden rounded-md",
|
|
12546
|
+
surface.className,
|
|
12253
12547
|
classNames?.content
|
|
12254
12548
|
),
|
|
12255
|
-
style:
|
|
12549
|
+
style: surface.style,
|
|
12256
12550
|
onContextMenu: handleBackgroundContextMenu,
|
|
12257
12551
|
children: /* @__PURE__ */ jsxs(Table, { children: [
|
|
12258
12552
|
/* @__PURE__ */ jsx(TableHeader, { "data-ntable-table-header": true, className: cn("bg-card sticky top-0 z-10", headerClassName, bordered === true && "[&_tr]:border-border", classNames?.tableHeader), children: table.getHeaderGroups().map((hg) => /* @__PURE__ */ jsxs(TableRow, { style: rowBorderStyle, className: cn("hover:bg-transparent", bordered === true && "border-border"), children: [
|
|
@@ -12361,13 +12655,8 @@ function NTableContent({ effectiveMode }) {
|
|
|
12361
12655
|
}
|
|
12362
12656
|
);
|
|
12363
12657
|
}
|
|
12364
|
-
function NDataCardShell({ row, onClick, onContextMenu, actions, children, className, showCheckbox = true, selectedRowId, openRowMenu, menuButton, bordered }) {
|
|
12365
|
-
const
|
|
12366
|
-
const recipeRadius = resolveRadiusValue(recipe?.radius);
|
|
12367
|
-
const recipeStyle = recipeRadius || recipe?.borderWidth ? {
|
|
12368
|
-
...recipeRadius ? { borderRadius: recipeRadius } : {},
|
|
12369
|
-
...recipe?.borderWidth ? { borderWidth: recipe.borderWidth } : {}
|
|
12370
|
-
} : void 0;
|
|
12658
|
+
function NDataCardShell({ row, onClick, onContextMenu, actions, children, className, showCheckbox = true, selectedRowId, openRowMenu, menuButton, bordered, borderColor }) {
|
|
12659
|
+
const surface = useTableSurfaceAppearance(bordered, borderColor);
|
|
12371
12660
|
const canExpand = row.getCanExpand();
|
|
12372
12661
|
const isExpanded = canExpand && row.getIsExpanded();
|
|
12373
12662
|
const isSelected = row.getIsSelected();
|
|
@@ -12382,10 +12671,10 @@ function NDataCardShell({ row, onClick, onContextMenu, actions, children, classN
|
|
|
12382
12671
|
"data-bordered": bordered === false ? "false" : bordered ? "true" : void 0,
|
|
12383
12672
|
onClick,
|
|
12384
12673
|
onContextMenu,
|
|
12385
|
-
style:
|
|
12674
|
+
style: surface.style,
|
|
12386
12675
|
className: cn(
|
|
12387
12676
|
"relative group w-full rounded-lg bg-card text-card-foreground overflow-hidden",
|
|
12388
|
-
|
|
12677
|
+
surface.className,
|
|
12389
12678
|
isActive && (bordered ? "border-primary" : "ring-2 ring-primary ring-offset-1 ring-offset-background"),
|
|
12390
12679
|
onClick && "cursor-pointer",
|
|
12391
12680
|
className
|
|
@@ -12402,7 +12691,7 @@ function NDataCardShell({ row, onClick, onContextMenu, actions, children, classN
|
|
|
12402
12691
|
className: "h-4 w-4"
|
|
12403
12692
|
}
|
|
12404
12693
|
) }),
|
|
12405
|
-
useMenuButton ? /* @__PURE__ */ jsx("div", { className: "absolute
|
|
12694
|
+
useMenuButton ? /* @__PURE__ */ jsx("div", { "data-ntable-card-action": true, className: "ntable-card-action absolute end-2 top-2 z-10 h-auto transition-opacity duration-200", children: /* @__PURE__ */ jsx(
|
|
12406
12695
|
"button",
|
|
12407
12696
|
{
|
|
12408
12697
|
type: "button",
|
|
@@ -12411,10 +12700,10 @@ function NDataCardShell({ row, onClick, onContextMenu, actions, children, classN
|
|
|
12411
12700
|
e.stopPropagation();
|
|
12412
12701
|
openRowMenu(e, row.original);
|
|
12413
12702
|
},
|
|
12414
|
-
className: "flex h-7 w-7
|
|
12703
|
+
className: "flex h-7 w-7 cursor-pointer items-center justify-center rounded-md p-0 text-muted-foreground transition-colors hover:bg-muted/50 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
12415
12704
|
children: /* @__PURE__ */ jsx(MoreVertical, { className: "h-4 w-4" })
|
|
12416
12705
|
}
|
|
12417
|
-
) }) : actions && (actions.onView || actions.onEdit || actions.onDelete) ? /* @__PURE__ */ jsx("div", { className: "absolute
|
|
12706
|
+
) }) : actions && (actions.onView || actions.onEdit || actions.onDelete) ? /* @__PURE__ */ jsx("div", { "data-ntable-card-action": true, className: "ntable-card-action absolute end-2 top-2 z-10 h-auto transition-opacity duration-200", children: /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
12418
12707
|
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
12419
12708
|
"div",
|
|
12420
12709
|
{
|
|
@@ -12519,6 +12808,7 @@ function NTableCards({ effectiveMode }) {
|
|
|
12519
12808
|
const showContent = useTableStore.use.showContent();
|
|
12520
12809
|
const classNames = useTableStore.use.classNames();
|
|
12521
12810
|
const bordered = useTableStore.use.bordered();
|
|
12811
|
+
const borderColor = useTableStore.use.borderColor();
|
|
12522
12812
|
const renderSubRow = useTableStore.use.renderSubRow();
|
|
12523
12813
|
const userGetRowCanExpand = useTableStore.use.getRowCanExpand();
|
|
12524
12814
|
const handleContainerContextMenu = useCallback((e) => {
|
|
@@ -12556,7 +12846,7 @@ function NTableCards({ effectiveMode }) {
|
|
|
12556
12846
|
const defaultContainerClass = "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-3";
|
|
12557
12847
|
const containerClass = classNames?.cards ?? defaultContainerClass;
|
|
12558
12848
|
const actions = !menuButton && (onView || onEdit || onDelete) ? { onView, onEdit, onDelete } : void 0;
|
|
12559
|
-
return /* @__PURE__ */ jsx(NajmScroll, { axis: "y", className: "min-h-0 flex-1 overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: cn(containerClass), onContextMenu: handleContainerContextMenu, children: rows.map((row) => {
|
|
12849
|
+
return /* @__PURE__ */ jsx(NajmScroll, { axis: "y", className: "min-h-0 flex-1 overflow-hidden", children: /* @__PURE__ */ jsx("div", { "data-ntable-cards-grid": true, className: cn(containerClass), onContextMenu: handleContainerContextMenu, children: rows.map((row) => {
|
|
12560
12850
|
const noShell = Boolean(row.original?.__smsNoShell);
|
|
12561
12851
|
const hasExpansion = Boolean(renderSubRow || userGetRowCanExpand);
|
|
12562
12852
|
const canExpand = hasExpansion && row.getCanExpand();
|
|
@@ -12586,7 +12876,8 @@ function NTableCards({ effectiveMode }) {
|
|
|
12586
12876
|
e.stopPropagation();
|
|
12587
12877
|
openRowMenu(e, row.original);
|
|
12588
12878
|
},
|
|
12589
|
-
|
|
12879
|
+
"data-ntable-card-action": true,
|
|
12880
|
+
className: "ntable-card-action absolute end-2 top-2 z-10 flex h-7 w-7 cursor-pointer items-center justify-center rounded-md p-0 text-muted-foreground transition-all duration-200 hover:bg-muted/50 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
12590
12881
|
children: /* @__PURE__ */ jsx(MoreVertical, { className: "h-4 w-4" })
|
|
12591
12882
|
}
|
|
12592
12883
|
),
|
|
@@ -12622,6 +12913,7 @@ function NTableCards({ effectiveMode }) {
|
|
|
12622
12913
|
openRowMenu,
|
|
12623
12914
|
menuButton,
|
|
12624
12915
|
bordered,
|
|
12916
|
+
borderColor,
|
|
12625
12917
|
className: rowClassName || void 0,
|
|
12626
12918
|
children: /* @__PURE__ */ jsx(
|
|
12627
12919
|
CardComponent,
|
|
@@ -12639,13 +12931,108 @@ function NTableCards({ effectiveMode }) {
|
|
|
12639
12931
|
);
|
|
12640
12932
|
}) }) });
|
|
12641
12933
|
}
|
|
12934
|
+
function CardLoadMorePagination({
|
|
12935
|
+
config,
|
|
12936
|
+
rowCount,
|
|
12937
|
+
bordered,
|
|
12938
|
+
className
|
|
12939
|
+
}) {
|
|
12940
|
+
const [internalPending, setInternalPending] = React__default.useState(false);
|
|
12941
|
+
const [internalError, setInternalError] = React__default.useState(null);
|
|
12942
|
+
const [announcement, setAnnouncement] = React__default.useState("");
|
|
12943
|
+
const buttonRef = React__default.useRef(null);
|
|
12944
|
+
const pendingRef = React__default.useRef(false);
|
|
12945
|
+
const restoreFocusRef = React__default.useRef(false);
|
|
12946
|
+
const previousRowCountRef = React__default.useRef(rowCount);
|
|
12947
|
+
const errorId = React__default.useId();
|
|
12948
|
+
const pending = Boolean(config.loadingMore || internalPending);
|
|
12949
|
+
const error = config.loadMoreError ?? internalError;
|
|
12950
|
+
React__default.useEffect(() => {
|
|
12951
|
+
const previous = previousRowCountRef.current;
|
|
12952
|
+
if (rowCount > previous) {
|
|
12953
|
+
const appended = rowCount - previous;
|
|
12954
|
+
setAnnouncement(
|
|
12955
|
+
config.itemsLoadedLabel?.(appended) ?? `${appended} more ${appended === 1 ? "item" : "items"} loaded.`
|
|
12956
|
+
);
|
|
12957
|
+
}
|
|
12958
|
+
previousRowCountRef.current = rowCount;
|
|
12959
|
+
}, [config.itemsLoadedLabel, rowCount]);
|
|
12960
|
+
React__default.useEffect(() => {
|
|
12961
|
+
if (pending || !restoreFocusRef.current) return;
|
|
12962
|
+
restoreFocusRef.current = false;
|
|
12963
|
+
const frame = requestAnimationFrame(() => buttonRef.current?.focus());
|
|
12964
|
+
return () => cancelAnimationFrame(frame);
|
|
12965
|
+
}, [pending]);
|
|
12966
|
+
const loadMore = async () => {
|
|
12967
|
+
if (pendingRef.current || pending || !config.hasNextPage && !error) return;
|
|
12968
|
+
pendingRef.current = true;
|
|
12969
|
+
restoreFocusRef.current = document.activeElement === buttonRef.current;
|
|
12970
|
+
setInternalPending(true);
|
|
12971
|
+
setInternalError(null);
|
|
12972
|
+
const loadingAnnouncement = config.loadingMoreLabel ?? "Loading more items...";
|
|
12973
|
+
setAnnouncement(loadingAnnouncement);
|
|
12974
|
+
try {
|
|
12975
|
+
await config.onLoadMore();
|
|
12976
|
+
} catch {
|
|
12977
|
+
setInternalError(config.loadMoreErrorLabel ?? "Couldn't load more items.");
|
|
12978
|
+
setAnnouncement("");
|
|
12979
|
+
} finally {
|
|
12980
|
+
pendingRef.current = false;
|
|
12981
|
+
setInternalPending(false);
|
|
12982
|
+
setAnnouncement((current) => current === loadingAnnouncement ? "" : current);
|
|
12983
|
+
}
|
|
12984
|
+
};
|
|
12985
|
+
if (!config.hasNextPage && !pending && !error) {
|
|
12986
|
+
return /* @__PURE__ */ jsx(
|
|
12987
|
+
"div",
|
|
12988
|
+
{
|
|
12989
|
+
"data-ntable-load-more-end": true,
|
|
12990
|
+
role: "status",
|
|
12991
|
+
"aria-live": "polite",
|
|
12992
|
+
className: cn("py-2 text-center text-sm text-muted-foreground", className),
|
|
12993
|
+
children: config.endLabel ?? "No more items."
|
|
12994
|
+
}
|
|
12995
|
+
);
|
|
12996
|
+
}
|
|
12997
|
+
return /* @__PURE__ */ jsxs(
|
|
12998
|
+
"div",
|
|
12999
|
+
{
|
|
13000
|
+
"data-ntable-load-more": true,
|
|
13001
|
+
className: cn("flex min-w-0 flex-col items-center gap-2 py-2", className),
|
|
13002
|
+
children: [
|
|
13003
|
+
error ? /* @__PURE__ */ jsx("div", { id: errorId, role: "alert", className: "text-center text-sm text-destructive", children: error === true ? config.loadMoreErrorLabel ?? "Couldn't load more items." : error }) : null,
|
|
13004
|
+
/* @__PURE__ */ jsxs(
|
|
13005
|
+
Button,
|
|
13006
|
+
{
|
|
13007
|
+
ref: buttonRef,
|
|
13008
|
+
type: "button",
|
|
13009
|
+
bordered,
|
|
13010
|
+
variant: "outline",
|
|
13011
|
+
autoLoading: false,
|
|
13012
|
+
disabled: pending,
|
|
13013
|
+
"aria-describedby": error ? errorId : void 0,
|
|
13014
|
+
"aria-busy": pending ? "true" : void 0,
|
|
13015
|
+
onClick: loadMore,
|
|
13016
|
+
children: [
|
|
13017
|
+
pending ? /* @__PURE__ */ jsx(Loader2, { "aria-hidden": "true", className: "h-4 w-4 animate-spin motion-reduce:animate-none" }) : null,
|
|
13018
|
+
pending ? config.loadingMoreLabel ?? "Loading more..." : error ? config.retryLabel ?? "Retry" : config.loadMoreLabel ?? "Load more"
|
|
13019
|
+
]
|
|
13020
|
+
}
|
|
13021
|
+
),
|
|
13022
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", role: "status", "aria-live": "polite", "aria-atomic": "true", children: announcement })
|
|
13023
|
+
]
|
|
13024
|
+
}
|
|
13025
|
+
);
|
|
13026
|
+
}
|
|
12642
13027
|
function NTablePagination() {
|
|
12643
13028
|
const table = useTableStore.use.table();
|
|
12644
13029
|
const showPagination = useTableStore.use.showPagination();
|
|
12645
13030
|
const showContent = useTableStore.use.showContent();
|
|
12646
13031
|
const pageSizeOptions = useTableStore.use.pageSizeOptions();
|
|
12647
13032
|
const classNames = useTableStore.use.classNames();
|
|
12648
|
-
const
|
|
13033
|
+
const effectiveViewMode = useTableStore.use.effectiveViewMode();
|
|
13034
|
+
const cardPagination = useTableStore.use.cardPagination();
|
|
13035
|
+
const data = useTableStore.use.data();
|
|
12649
13036
|
const pagination = useTableStore.use.pagination();
|
|
12650
13037
|
const manualPagination = useTableStore.use.manualPagination();
|
|
12651
13038
|
const pageCount = useTableStore.use.pageCount();
|
|
@@ -12653,7 +13040,19 @@ function NTablePagination() {
|
|
|
12653
13040
|
const setPagination = useTableStore.use.setPagination();
|
|
12654
13041
|
const isPaginationControlled = useTableStore.use.isPaginationControlled();
|
|
12655
13042
|
const bordered = useTableStore.use.bordered();
|
|
12656
|
-
if (!table || !showContent || !showPagination ||
|
|
13043
|
+
if (!table || !showContent || !showPagination || effectiveViewMode === "json" || effectiveViewMode === "files") return null;
|
|
13044
|
+
if (effectiveViewMode === "cards" && cardPagination.mode === "all") return null;
|
|
13045
|
+
if (effectiveViewMode === "cards" && cardPagination.mode === "load-more") {
|
|
13046
|
+
return /* @__PURE__ */ jsx(
|
|
13047
|
+
CardLoadMorePagination,
|
|
13048
|
+
{
|
|
13049
|
+
config: cardPagination,
|
|
13050
|
+
rowCount: data.length,
|
|
13051
|
+
bordered,
|
|
13052
|
+
className: classNames?.pagination
|
|
13053
|
+
}
|
|
13054
|
+
);
|
|
13055
|
+
}
|
|
12657
13056
|
const filteredRows = table.getFilteredRowModel().rows;
|
|
12658
13057
|
const selectedRows = table.getFilteredSelectedRowModel().rows;
|
|
12659
13058
|
const { pageIndex, pageSize } = table.getState().pagination;
|
|
@@ -13091,7 +13490,7 @@ function NTableHeaderSkeleton() {
|
|
|
13091
13490
|
}
|
|
13092
13491
|
);
|
|
13093
13492
|
}
|
|
13094
|
-
function NTableLoadingSkeleton({ rows
|
|
13493
|
+
function NTableLoadingSkeleton({ rows }) {
|
|
13095
13494
|
const rawColumns = useTableStore.use.columns();
|
|
13096
13495
|
const responsiveColumns = React__default.useMemo(() => filterResponsiveColumns(rawColumns), [rawColumns]);
|
|
13097
13496
|
const columns = responsiveColumns;
|
|
@@ -13099,24 +13498,34 @@ function NTableLoadingSkeleton({ rows = DEFAULT_ROWS2 }) {
|
|
|
13099
13498
|
const headerClassName = useTableStore.use.headerClassName();
|
|
13100
13499
|
const classNames = useTableStore.use.classNames();
|
|
13101
13500
|
const dynamicHeight = useTableStore.use.dynamicHeight();
|
|
13501
|
+
const bordered = useTableStore.use.bordered();
|
|
13502
|
+
const borderColor = useTableStore.use.borderColor();
|
|
13503
|
+
const surface = useTableSurfaceAppearance(bordered, borderColor);
|
|
13504
|
+
const bodyHeight = useTableStore.use.bodyHeight();
|
|
13505
|
+
const skeletonRowCount = useTableStore.use.skeletonRowCount();
|
|
13102
13506
|
const renderSubRow = useTableStore.use.renderSubRow();
|
|
13103
13507
|
const userGetRowCanExpand = useTableStore.use.getRowCanExpand();
|
|
13104
13508
|
const hasExpansion = Boolean(renderSubRow || userGetRowCanExpand);
|
|
13105
13509
|
const loadingText = useTableStore.use.loadingText();
|
|
13510
|
+
const rowCount = rows ?? (dynamicHeight && bodyHeight > 0 ? skeletonRowCount : DEFAULT_ROWS2);
|
|
13106
13511
|
const renderHeaderLabel = (header) => typeof header === "string" ? header : null;
|
|
13107
13512
|
return /* @__PURE__ */ jsxs("div", { className: "flex min-h-0 flex-1 flex-col gap-2", children: [
|
|
13108
13513
|
/* @__PURE__ */ jsx(NTableHeaderSkeleton, {}),
|
|
13109
13514
|
/* @__PURE__ */ jsxs(
|
|
13110
|
-
|
|
13515
|
+
"div",
|
|
13111
13516
|
{
|
|
13112
13517
|
"data-testid": "ntable-loading-skeleton",
|
|
13518
|
+
"data-ntable-loading-row-count": rowCount,
|
|
13519
|
+
"data-bordered": surface.bordered === false ? "false" : surface.bordered ? "true" : void 0,
|
|
13113
13520
|
"aria-busy": "true",
|
|
13114
13521
|
"aria-label": loadingText,
|
|
13115
|
-
|
|
13522
|
+
role: "status",
|
|
13523
|
+
style: surface.style,
|
|
13524
|
+
className: cn("min-h-0 flex-1 rounded-md p-0", surface.className, dynamicHeight ? "overflow-hidden" : "najm-overlay-scroll", classNames?.content),
|
|
13116
13525
|
children: [
|
|
13117
13526
|
/* @__PURE__ */ jsx("span", { className: "sr-only", children: loadingText }),
|
|
13118
|
-
/* @__PURE__ */ jsx("div", { className: dynamicHeight ? "najm-overlay-scroll" : void 0, children: /* @__PURE__ */ jsxs(Table, { children: [
|
|
13119
|
-
/* @__PURE__ */ jsx(TableHeader, { className: cn(headerClassName,
|
|
13527
|
+
/* @__PURE__ */ jsx("div", { "aria-hidden": "true", className: dynamicHeight ? "najm-overlay-scroll h-full" : void 0, children: /* @__PURE__ */ jsxs(Table, { children: [
|
|
13528
|
+
/* @__PURE__ */ jsx(TableHeader, { "data-ntable-table-header": true, className: cn(headerClassName, "sticky top-0 z-10", classNames?.tableHeader), children: /* @__PURE__ */ jsxs(TableRow, { className: "hover:bg-muted/30", children: [
|
|
13120
13529
|
showCheckbox && /* @__PURE__ */ jsx(TableHead, { "aria-label": "Select column", className: "w-10 text-foreground h-12" }),
|
|
13121
13530
|
hasExpansion && /* @__PURE__ */ jsx(TableHead, { "aria-label": "Expand column", className: "w-10 text-foreground h-12" }),
|
|
13122
13531
|
columns.map((col, i) => /* @__PURE__ */ jsx(
|
|
@@ -13129,7 +13538,7 @@ function NTableLoadingSkeleton({ rows = DEFAULT_ROWS2 }) {
|
|
|
13129
13538
|
col?.id ?? col?.accessorKey ?? i
|
|
13130
13539
|
))
|
|
13131
13540
|
] }) }),
|
|
13132
|
-
/* @__PURE__ */ jsx(TableBody, { children: Array.from({ length:
|
|
13541
|
+
/* @__PURE__ */ jsx(TableBody, { children: Array.from({ length: rowCount }).map((_, r) => /* @__PURE__ */ jsxs(TableRow, { children: [
|
|
13133
13542
|
showCheckbox && /* @__PURE__ */ jsx(TableCell, { className: "h-14 w-10", children: /* @__PURE__ */ jsx(NSkeleton, { className: "h-4 w-4" }) }),
|
|
13134
13543
|
hasExpansion && /* @__PURE__ */ jsx(TableCell, { className: "h-14 w-10", children: /* @__PURE__ */ jsx(NSkeleton, { className: "h-4 w-4" }) }),
|
|
13135
13544
|
columns.map((col, c) => /* @__PURE__ */ jsx(
|
|
@@ -13160,74 +13569,105 @@ function NTableCardsLoadingSkeleton({ rows }) {
|
|
|
13160
13569
|
);
|
|
13161
13570
|
const classNames = useTableStore.use.classNames();
|
|
13162
13571
|
const bordered = useTableStore.use.bordered();
|
|
13163
|
-
const
|
|
13164
|
-
const
|
|
13165
|
-
const
|
|
13572
|
+
const borderColor = useTableStore.use.borderColor();
|
|
13573
|
+
const surface = useTableSurfaceAppearance(bordered, borderColor);
|
|
13574
|
+
const dynamicHeight = useTableStore.use.dynamicHeight();
|
|
13575
|
+
const bodyHeight = useTableStore.use.bodyHeight();
|
|
13576
|
+
const cardColumnCount = useTableStore.use.cardColumnCount();
|
|
13577
|
+
const cardRowHeight = useTableStore.use.cardRowHeight();
|
|
13578
|
+
const cardGap = useTableStore.use.cardGap();
|
|
13579
|
+
const loadingText = useTableStore.use.loadingText();
|
|
13580
|
+
const cardCount = rows ?? (dynamicHeight && bodyHeight > 0 ? calculateCardSkeletonCount({
|
|
13581
|
+
bodyHeight,
|
|
13582
|
+
columnCount: cardColumnCount,
|
|
13583
|
+
cardHeight: cardRowHeight,
|
|
13584
|
+
gap: cardGap
|
|
13585
|
+
}) : DEFAULT_CARD_COUNT);
|
|
13586
|
+
const defaultContainerClass = "grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4";
|
|
13587
|
+
const containerClass = classNames?.cards ?? defaultContainerClass;
|
|
13166
13588
|
return /* @__PURE__ */ jsxs("div", { className: "flex min-h-0 flex-1 flex-col gap-2", children: [
|
|
13167
13589
|
hasHeaderSkeleton && /* @__PURE__ */ jsx(NTableHeaderSkeleton, {}),
|
|
13168
|
-
/* @__PURE__ */
|
|
13169
|
-
|
|
13590
|
+
/* @__PURE__ */ jsxs(
|
|
13591
|
+
NajmScroll,
|
|
13170
13592
|
{
|
|
13171
|
-
|
|
13593
|
+
axis: "y",
|
|
13172
13594
|
"aria-busy": "true",
|
|
13173
|
-
|
|
13174
|
-
|
|
13175
|
-
|
|
13176
|
-
|
|
13177
|
-
|
|
13178
|
-
|
|
13179
|
-
|
|
13180
|
-
|
|
13181
|
-
|
|
13182
|
-
|
|
13183
|
-
|
|
13184
|
-
|
|
13185
|
-
|
|
13186
|
-
|
|
13187
|
-
|
|
13188
|
-
|
|
13189
|
-
|
|
13190
|
-
|
|
13191
|
-
|
|
13192
|
-
|
|
13193
|
-
|
|
13194
|
-
/* @__PURE__ */ jsx(NSkeleton, { className: "hidden h-3 w-16 sm:block" })
|
|
13195
|
-
] }),
|
|
13196
|
-
/* @__PURE__ */ jsx(
|
|
13197
|
-
NSkeleton,
|
|
13198
|
-
{
|
|
13199
|
-
"data-ntable-loading-card-status": true,
|
|
13200
|
-
className: "hidden h-6 w-14 shrink-0 rounded-full sm:block"
|
|
13201
|
-
}
|
|
13202
|
-
)
|
|
13203
|
-
] }),
|
|
13204
|
-
/* @__PURE__ */ jsx(
|
|
13595
|
+
"aria-label": loadingText,
|
|
13596
|
+
role: "status",
|
|
13597
|
+
className: "min-h-0 flex-1 overflow-hidden",
|
|
13598
|
+
children: [
|
|
13599
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: loadingText }),
|
|
13600
|
+
/* @__PURE__ */ jsx(
|
|
13601
|
+
"div",
|
|
13602
|
+
{
|
|
13603
|
+
"data-testid": "ntable-cards-loading-skeleton",
|
|
13604
|
+
"data-ntable-loading-cards-grid": true,
|
|
13605
|
+
"data-ntable-loading-card-count": cardCount,
|
|
13606
|
+
"aria-hidden": "true",
|
|
13607
|
+
className: cn(containerClass),
|
|
13608
|
+
children: Array.from({ length: cardCount }).map((_, index) => /* @__PURE__ */ jsx(
|
|
13609
|
+
"div",
|
|
13610
|
+
{
|
|
13611
|
+
"data-ntable-loading-card": true,
|
|
13612
|
+
"data-bordered": surface.bordered === false ? "false" : surface.bordered ? "true" : void 0,
|
|
13613
|
+
style: surface.style,
|
|
13614
|
+
className: cn("rounded-lg p-3 sm:p-4", surface.className),
|
|
13615
|
+
children: /* @__PURE__ */ jsxs(
|
|
13205
13616
|
"div",
|
|
13206
13617
|
{
|
|
13207
|
-
"data-ntable-loading-card-
|
|
13208
|
-
className: "
|
|
13209
|
-
children:
|
|
13210
|
-
/* @__PURE__ */ jsx(
|
|
13211
|
-
/* @__PURE__ */ jsx(
|
|
13618
|
+
"data-ntable-loading-card-layout": "responsive-avatar",
|
|
13619
|
+
className: "grid grid-cols-[80px_minmax(0,1fr)] gap-3 sm:grid-cols-[72px_minmax(0,1fr)]",
|
|
13620
|
+
children: [
|
|
13621
|
+
/* @__PURE__ */ jsx("div", { className: "col-start-1 row-start-1 flex items-start justify-center sm:justify-start", children: /* @__PURE__ */ jsx(
|
|
13212
13622
|
NSkeleton,
|
|
13213
13623
|
{
|
|
13214
|
-
|
|
13215
|
-
|
|
13216
|
-
|
|
13217
|
-
|
|
13624
|
+
"data-ntable-loading-card-avatar": true,
|
|
13625
|
+
className: "size-20 shrink-0 rounded-full sm:size-16"
|
|
13626
|
+
}
|
|
13627
|
+
) }),
|
|
13628
|
+
/* @__PURE__ */ jsxs("div", { className: "col-start-2 row-start-1 flex min-w-0 items-start justify-between gap-3", children: [
|
|
13629
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1 space-y-2", children: [
|
|
13630
|
+
/* @__PURE__ */ jsx(NSkeleton, { className: "h-5 w-36 max-w-full" }),
|
|
13631
|
+
/* @__PURE__ */ jsx(NSkeleton, { className: "hidden h-3 w-16 sm:block" })
|
|
13632
|
+
] }),
|
|
13633
|
+
/* @__PURE__ */ jsx(
|
|
13634
|
+
NSkeleton,
|
|
13635
|
+
{
|
|
13636
|
+
"data-ntable-loading-card-status": true,
|
|
13637
|
+
className: "hidden h-6 w-14 shrink-0 rounded-full sm:block"
|
|
13638
|
+
}
|
|
13639
|
+
)
|
|
13640
|
+
] }),
|
|
13641
|
+
/* @__PURE__ */ jsx(
|
|
13642
|
+
"div",
|
|
13643
|
+
{
|
|
13644
|
+
"data-ntable-loading-card-details": true,
|
|
13645
|
+
className: "col-start-2 row-start-2 space-y-1 sm:col-span-full sm:col-start-1 sm:space-y-2 sm:rounded-lg sm:bg-muted/50 sm:p-3",
|
|
13646
|
+
children: Array.from({ length: 3 }).map((_2, detailIndex) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 sm:gap-2", children: [
|
|
13647
|
+
/* @__PURE__ */ jsx(NSkeleton, { className: "size-3.5 shrink-0 rounded-sm sm:size-4" }),
|
|
13648
|
+
/* @__PURE__ */ jsx(
|
|
13649
|
+
NSkeleton,
|
|
13650
|
+
{
|
|
13651
|
+
className: cn(
|
|
13652
|
+
"h-3 max-w-full sm:h-4",
|
|
13653
|
+
detailIndex === 0 ? "w-full" : detailIndex === 1 ? "w-4/5" : "w-3/4"
|
|
13654
|
+
)
|
|
13655
|
+
}
|
|
13656
|
+
)
|
|
13657
|
+
] }, detailIndex))
|
|
13218
13658
|
}
|
|
13219
13659
|
)
|
|
13220
|
-
]
|
|
13660
|
+
]
|
|
13221
13661
|
}
|
|
13222
13662
|
)
|
|
13223
|
-
|
|
13224
|
-
|
|
13225
|
-
|
|
13226
|
-
|
|
13227
|
-
|
|
13228
|
-
|
|
13663
|
+
},
|
|
13664
|
+
index
|
|
13665
|
+
))
|
|
13666
|
+
}
|
|
13667
|
+
)
|
|
13668
|
+
]
|
|
13229
13669
|
}
|
|
13230
|
-
)
|
|
13670
|
+
)
|
|
13231
13671
|
] });
|
|
13232
13672
|
}
|
|
13233
13673
|
function TableStateSlot({ children }) {
|
|
@@ -13278,7 +13718,7 @@ function TableLayout(props) {
|
|
|
13278
13718
|
const responsiveCards = useTableStore.use.responsiveCards();
|
|
13279
13719
|
const isCustomMode = useTableStore.use.isCustomMode();
|
|
13280
13720
|
const renderCustomMode = useTableStore.use.renderCustomMode();
|
|
13281
|
-
const [isMobile, setIsMobile] = useState(false);
|
|
13721
|
+
const [isMobile, setIsMobile] = useState(() => typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia("(max-width: 639px)").matches : false);
|
|
13282
13722
|
useEffect(() => {
|
|
13283
13723
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
13284
13724
|
const mql = window.matchMedia("(max-width: 639px)");
|
|
@@ -13287,18 +13727,22 @@ function TableLayout(props) {
|
|
|
13287
13727
|
mql.addEventListener("change", handler2);
|
|
13288
13728
|
return () => mql.removeEventListener("change", handler2);
|
|
13289
13729
|
}, []);
|
|
13290
|
-
useDynamicPageSize(containerRef);
|
|
13291
|
-
useTable();
|
|
13292
|
-
useTableKeyboard({
|
|
13293
|
-
scopeRef: containerRef,
|
|
13294
|
-
contextMenuClose: props.contextMenuClose,
|
|
13295
|
-
contextMenuOpen: props.contextMenuOpen
|
|
13296
|
-
});
|
|
13297
13730
|
const effectiveMode = (() => {
|
|
13298
13731
|
if (viewMode === "json") return "json";
|
|
13299
13732
|
if (isMobile && responsiveCards && CardComponent) return "cards";
|
|
13300
13733
|
return viewMode;
|
|
13301
13734
|
})();
|
|
13735
|
+
const syncWithProps = useTableStore.use.syncWithProps();
|
|
13736
|
+
useLayoutEffect(() => {
|
|
13737
|
+
syncWithProps({ isMobile, effectiveViewMode: effectiveMode });
|
|
13738
|
+
}, [effectiveMode, isMobile, syncWithProps]);
|
|
13739
|
+
useDynamicPageSize(containerRef, effectiveMode);
|
|
13740
|
+
useTable(effectiveMode);
|
|
13741
|
+
useTableKeyboard({
|
|
13742
|
+
scopeRef: containerRef,
|
|
13743
|
+
contextMenuClose: props.contextMenuClose,
|
|
13744
|
+
contextMenuOpen: props.contextMenuOpen
|
|
13745
|
+
});
|
|
13302
13746
|
const showFilteredEmpty = isFilteredEmpty && !isLoading && !error;
|
|
13303
13747
|
const showEmpty = hasNoData && !isLoading && !error && !showFilteredEmpty;
|
|
13304
13748
|
const customRenderer = isCustomMode ? renderCustomMode?.[viewMode] : void 0;
|
|
@@ -13458,6 +13902,7 @@ function NTable(props) {
|
|
|
13458
13902
|
pagination: props.pagination,
|
|
13459
13903
|
defaultPagination: props.defaultPagination,
|
|
13460
13904
|
onPaginationChange: props.onPaginationChange ?? null,
|
|
13905
|
+
cardPagination: props.cardPagination ?? { mode: "paged" },
|
|
13461
13906
|
// Row selection
|
|
13462
13907
|
rowSelection: props.rowSelection,
|
|
13463
13908
|
defaultRowSelection: props.defaultRowSelection,
|