@webdevarif/dashui 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +226 -151
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +226 -151
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -378,6 +378,7 @@ interface MediaPickerDialogProps {
|
|
|
378
378
|
onLoadMore?: () => void;
|
|
379
379
|
hasMore?: boolean;
|
|
380
380
|
multiple?: boolean;
|
|
381
|
+
/** "images" = only show image type tabs; "all" = show all type tabs */
|
|
381
382
|
accept?: "images" | "all";
|
|
382
383
|
onSelect: (files: MediaCardFile[]) => void;
|
|
383
384
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -378,6 +378,7 @@ interface MediaPickerDialogProps {
|
|
|
378
378
|
onLoadMore?: () => void;
|
|
379
379
|
hasMore?: boolean;
|
|
380
380
|
multiple?: boolean;
|
|
381
|
+
/** "images" = only show image type tabs; "all" = show all type tabs */
|
|
381
382
|
accept?: "images" | "all";
|
|
382
383
|
onSelect: (files: MediaCardFile[]) => void;
|
|
383
384
|
}
|
package/dist/index.js
CHANGED
|
@@ -2016,11 +2016,10 @@ function MediaGrid({
|
|
|
2016
2016
|
// src/components/media/media-picker-dialog.tsx
|
|
2017
2017
|
var React20 = __toESM(require("react"));
|
|
2018
2018
|
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
2019
|
-
var
|
|
2019
|
+
var ALL_TYPE_OPTIONS = [
|
|
2020
2020
|
{ value: "all", label: "All" },
|
|
2021
2021
|
{ value: "images", label: "Images" },
|
|
2022
2022
|
{ value: "videos", label: "Videos" },
|
|
2023
|
-
{ value: "audio", label: "Audio" },
|
|
2024
2023
|
{ value: "documents", label: "Docs" }
|
|
2025
2024
|
];
|
|
2026
2025
|
function MediaPickerDialog({
|
|
@@ -2046,23 +2045,61 @@ function MediaPickerDialog({
|
|
|
2046
2045
|
onSelect
|
|
2047
2046
|
}) {
|
|
2048
2047
|
const [localSelected, setLocalSelected] = React20.useState(/* @__PURE__ */ new Set());
|
|
2048
|
+
const [isDragging, setIsDragging] = React20.useState(false);
|
|
2049
2049
|
const fileInputRef = React20.useRef(null);
|
|
2050
|
+
const dragCounterRef = React20.useRef(0);
|
|
2051
|
+
React20.useEffect(() => {
|
|
2052
|
+
if (!open) {
|
|
2053
|
+
setLocalSelected(/* @__PURE__ */ new Set());
|
|
2054
|
+
setIsDragging(false);
|
|
2055
|
+
dragCounterRef.current = 0;
|
|
2056
|
+
}
|
|
2057
|
+
}, [open]);
|
|
2058
|
+
const handleDragEnter = (e) => {
|
|
2059
|
+
e.preventDefault();
|
|
2060
|
+
e.stopPropagation();
|
|
2061
|
+
if (e.dataTransfer.types.includes("Files")) {
|
|
2062
|
+
dragCounterRef.current++;
|
|
2063
|
+
setIsDragging(true);
|
|
2064
|
+
}
|
|
2065
|
+
};
|
|
2066
|
+
const handleDragLeave = (e) => {
|
|
2067
|
+
e.preventDefault();
|
|
2068
|
+
e.stopPropagation();
|
|
2069
|
+
dragCounterRef.current--;
|
|
2070
|
+
if (dragCounterRef.current <= 0) {
|
|
2071
|
+
dragCounterRef.current = 0;
|
|
2072
|
+
setIsDragging(false);
|
|
2073
|
+
}
|
|
2074
|
+
};
|
|
2075
|
+
const handleDragOver = (e) => {
|
|
2076
|
+
e.preventDefault();
|
|
2077
|
+
e.stopPropagation();
|
|
2078
|
+
};
|
|
2079
|
+
const handleDrop = (e) => {
|
|
2080
|
+
e.preventDefault();
|
|
2081
|
+
e.stopPropagation();
|
|
2082
|
+
dragCounterRef.current = 0;
|
|
2083
|
+
setIsDragging(false);
|
|
2084
|
+
if (!onUpload || !e.dataTransfer.files.length) return;
|
|
2085
|
+
const accepted = accept === "images" ? Array.from(e.dataTransfer.files).filter((f) => f.type.startsWith("image/")) : Array.from(e.dataTransfer.files);
|
|
2086
|
+
if (!accepted.length) return;
|
|
2087
|
+
const dt = new DataTransfer();
|
|
2088
|
+
accepted.forEach((f) => dt.items.add(f));
|
|
2089
|
+
onUpload(dt.files);
|
|
2090
|
+
};
|
|
2091
|
+
const typeOptions = ALL_TYPE_OPTIONS.filter(
|
|
2092
|
+
(o) => accept === "images" ? o.value === "all" || o.value === "images" : true
|
|
2093
|
+
);
|
|
2050
2094
|
const handleFileSelect = (file) => {
|
|
2051
|
-
|
|
2052
|
-
|
|
2095
|
+
setLocalSelected((prev) => {
|
|
2096
|
+
if (multiple) {
|
|
2053
2097
|
const next = new Set(prev);
|
|
2054
|
-
|
|
2055
|
-
next.delete(file.id);
|
|
2056
|
-
} else {
|
|
2057
|
-
next.add(file.id);
|
|
2058
|
-
}
|
|
2098
|
+
next.has(file.id) ? next.delete(file.id) : next.add(file.id);
|
|
2059
2099
|
return next;
|
|
2060
|
-
}
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
onSelect(selected);
|
|
2064
|
-
onOpenChange(false);
|
|
2065
|
-
}
|
|
2100
|
+
}
|
|
2101
|
+
return prev.has(file.id) ? /* @__PURE__ */ new Set() : /* @__PURE__ */ new Set([file.id]);
|
|
2102
|
+
});
|
|
2066
2103
|
};
|
|
2067
2104
|
const handleConfirm = () => {
|
|
2068
2105
|
const selected = files.filter((f) => localSelected.has(f.id));
|
|
@@ -2075,163 +2112,201 @@ function MediaPickerDialog({
|
|
|
2075
2112
|
}
|
|
2076
2113
|
};
|
|
2077
2114
|
const activeUploads = uploads.filter((u) => u.status === "uploading");
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2088
|
-
"input",
|
|
2089
|
-
{
|
|
2090
|
-
ref: fileInputRef,
|
|
2091
|
-
type: "file",
|
|
2092
|
-
className: "hidden",
|
|
2093
|
-
multiple: true,
|
|
2094
|
-
accept: accept === "images" ? "image/*" : void 0,
|
|
2095
|
-
onChange: handleUploadChange
|
|
2096
|
-
}
|
|
2097
|
-
),
|
|
2098
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
2099
|
-
"button",
|
|
2100
|
-
{
|
|
2101
|
-
onClick: () => fileInputRef.current?.click(),
|
|
2102
|
-
className: "flex items-center gap-1.5 rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground transition-opacity hover:opacity-90",
|
|
2103
|
-
children: [
|
|
2104
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("svg", { className: "h-3.5 w-3.5", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2105
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
|
|
2106
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("polyline", { points: "17 8 12 3 7 8" }),
|
|
2107
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("line", { x1: "12", y1: "3", x2: "12", y2: "15" })
|
|
2108
|
-
] }),
|
|
2109
|
-
"Upload"
|
|
2110
|
-
]
|
|
2111
|
-
}
|
|
2112
|
-
)
|
|
2113
|
-
] })
|
|
2114
|
-
] })
|
|
2115
|
-
] }),
|
|
2116
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex flex-1 overflow-hidden", children: [
|
|
2117
|
-
folders.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("aside", { className: "flex w-44 shrink-0 flex-col gap-0.5 overflow-y-auto border-r p-2", children: [
|
|
2118
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
2119
|
-
"button",
|
|
2120
|
-
{
|
|
2121
|
-
onClick: () => onFolderChange?.(""),
|
|
2122
|
-
className: cn(
|
|
2123
|
-
"flex w-full items-center gap-2 rounded-md px-2.5 py-1.5 text-sm transition-colors",
|
|
2124
|
-
!activeFolderId ? "bg-primary/10 font-medium text-primary" : "text-muted-foreground hover:bg-accent"
|
|
2125
|
-
),
|
|
2126
|
-
children: [
|
|
2127
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("svg", { className: "h-3.5 w-3.5", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("path", { d: "M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" }) }),
|
|
2128
|
-
"All files"
|
|
2129
|
-
]
|
|
2130
|
-
}
|
|
2131
|
-
),
|
|
2132
|
-
folders.map((folder) => /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
2133
|
-
"button",
|
|
2134
|
-
{
|
|
2135
|
-
onClick: () => onFolderChange?.(folder.id),
|
|
2136
|
-
className: cn(
|
|
2137
|
-
"flex w-full items-center gap-2 rounded-md px-2.5 py-1.5 text-sm transition-colors",
|
|
2138
|
-
activeFolderId === folder.id ? "bg-primary/10 font-medium text-primary" : "text-muted-foreground hover:bg-accent"
|
|
2139
|
-
),
|
|
2140
|
-
children: [
|
|
2141
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "text-base leading-none", children: folder.icon ?? "\u{1F4C1}" }),
|
|
2142
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "truncate", children: folder.name })
|
|
2143
|
-
]
|
|
2144
|
-
},
|
|
2145
|
-
folder.id
|
|
2146
|
-
))
|
|
2147
|
-
] }),
|
|
2148
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
|
|
2149
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex items-center gap-2 border-b px-4 py-2", children: [
|
|
2150
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "relative flex-1", children: [
|
|
2151
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("svg", { className: "pointer-events-none absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2152
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("circle", { cx: "11", cy: "11", r: "8" }),
|
|
2153
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("path", { d: "m21 21-4.35-4.35" })
|
|
2154
|
-
] }),
|
|
2115
|
+
const firstSelected = files.find((f) => localSelected.has(f.id));
|
|
2116
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Dialog, { open, onOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
2117
|
+
DialogContent,
|
|
2118
|
+
{
|
|
2119
|
+
"aria-describedby": void 0,
|
|
2120
|
+
className: "flex h-[85vh] max-h-[700px] max-w-4xl flex-col gap-0 p-0",
|
|
2121
|
+
children: [
|
|
2122
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(DialogHeader, { className: "flex-row items-center gap-3 border-b px-5 py-3 pr-12 space-y-0 shrink-0", children: [
|
|
2123
|
+
onUpload && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_jsx_runtime34.Fragment, { children: [
|
|
2155
2124
|
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2156
2125
|
"input",
|
|
2157
2126
|
{
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2127
|
+
ref: fileInputRef,
|
|
2128
|
+
type: "file",
|
|
2129
|
+
className: "hidden",
|
|
2130
|
+
multiple: true,
|
|
2131
|
+
accept: accept === "images" ? "image/*" : void 0,
|
|
2132
|
+
onChange: handleUploadChange
|
|
2133
|
+
}
|
|
2134
|
+
),
|
|
2135
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
2136
|
+
"button",
|
|
2137
|
+
{
|
|
2138
|
+
onClick: () => fileInputRef.current?.click(),
|
|
2139
|
+
className: "flex shrink-0 items-center gap-1.5 rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground transition-opacity hover:opacity-90",
|
|
2140
|
+
children: [
|
|
2141
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("svg", { className: "h-3.5 w-3.5", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2142
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
|
|
2143
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("polyline", { points: "17 8 12 3 7 8" }),
|
|
2144
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("line", { x1: "12", y1: "3", x2: "12", y2: "15" })
|
|
2145
|
+
] }),
|
|
2146
|
+
"Upload"
|
|
2147
|
+
]
|
|
2163
2148
|
}
|
|
2164
2149
|
)
|
|
2165
2150
|
] }),
|
|
2166
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
"rounded px-2 py-1 text-xs transition-colors",
|
|
2172
|
-
typeFilter === opt.value ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:bg-accent"
|
|
2173
|
-
),
|
|
2174
|
-
children: opt.label
|
|
2175
|
-
},
|
|
2176
|
-
opt.value
|
|
2177
|
-
)) })
|
|
2151
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(DialogTitle, { className: "text-sm font-semibold flex-1", children: title }),
|
|
2152
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("span", { className: "text-xs text-muted-foreground shrink-0", children: [
|
|
2153
|
+
total,
|
|
2154
|
+
" files"
|
|
2155
|
+
] })
|
|
2178
2156
|
] }),
|
|
2179
|
-
|
|
2180
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2157
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex flex-1 overflow-hidden min-h-0", children: [
|
|
2158
|
+
folders.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("aside", { className: "flex w-44 shrink-0 flex-col gap-0.5 overflow-y-auto border-r p-2", children: [
|
|
2159
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
2160
|
+
"button",
|
|
2161
|
+
{
|
|
2162
|
+
onClick: () => onFolderChange?.(""),
|
|
2163
|
+
className: cn(
|
|
2164
|
+
"flex w-full items-center gap-2 rounded-md px-2.5 py-1.5 text-sm transition-colors",
|
|
2165
|
+
!activeFolderId ? "bg-primary/10 font-medium text-primary" : "text-muted-foreground hover:bg-accent"
|
|
2166
|
+
),
|
|
2167
|
+
children: [
|
|
2168
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("svg", { className: "h-3.5 w-3.5 shrink-0", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("path", { d: "M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z" }) }),
|
|
2169
|
+
"All files"
|
|
2170
|
+
]
|
|
2171
|
+
}
|
|
2172
|
+
),
|
|
2173
|
+
folders.map((folder) => /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
2174
|
+
"button",
|
|
2175
|
+
{
|
|
2176
|
+
onClick: () => onFolderChange?.(folder.id),
|
|
2177
|
+
className: cn(
|
|
2178
|
+
"flex w-full items-center gap-2 rounded-md px-2.5 py-1.5 text-sm transition-colors",
|
|
2179
|
+
activeFolderId === folder.id ? "bg-primary/10 font-medium text-primary" : "text-muted-foreground hover:bg-accent"
|
|
2180
|
+
),
|
|
2181
|
+
children: [
|
|
2182
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "text-base leading-none", children: folder.icon ?? "\u{1F4C1}" }),
|
|
2183
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "truncate", children: folder.name })
|
|
2184
|
+
]
|
|
2185
|
+
},
|
|
2186
|
+
folder.id
|
|
2187
|
+
))
|
|
2188
|
+
] }),
|
|
2189
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex flex-1 flex-col overflow-hidden min-w-0", children: [
|
|
2190
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex items-center gap-2 border-b px-4 py-2 shrink-0", children: [
|
|
2191
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "flex items-center gap-0.5 rounded-lg border border-input bg-muted/50 p-0.5", children: typeOptions.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2192
|
+
"button",
|
|
2193
|
+
{
|
|
2194
|
+
onClick: () => onTypeChange?.(opt.value),
|
|
2195
|
+
className: cn(
|
|
2196
|
+
"rounded-md px-2.5 py-1 text-xs font-medium transition-colors",
|
|
2197
|
+
typeFilter === opt.value ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"
|
|
2198
|
+
),
|
|
2199
|
+
children: opt.label
|
|
2200
|
+
},
|
|
2201
|
+
opt.value
|
|
2202
|
+
)) }),
|
|
2203
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "relative flex-1 max-w-xs ml-auto", children: [
|
|
2204
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("svg", { className: "pointer-events-none absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2205
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("circle", { cx: "11", cy: "11", r: "8" }),
|
|
2206
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("path", { d: "m21 21-4.35-4.35" })
|
|
2207
|
+
] }),
|
|
2208
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2209
|
+
"input",
|
|
2210
|
+
{
|
|
2211
|
+
type: "search",
|
|
2212
|
+
value: search,
|
|
2213
|
+
onChange: (e) => onSearch?.(e.target.value),
|
|
2214
|
+
placeholder: "Search\u2026",
|
|
2215
|
+
className: "h-8 w-full rounded-lg border border-input bg-background pl-8 pr-3 text-xs outline-none focus:border-primary focus:ring-1 focus:ring-primary/30"
|
|
2216
|
+
}
|
|
2217
|
+
)
|
|
2218
|
+
] })
|
|
2219
|
+
] }),
|
|
2220
|
+
activeUploads.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "border-b px-4 py-2 space-y-1.5 shrink-0", children: activeUploads.map((u, i) => /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
2221
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "flex-1 truncate text-xs text-muted-foreground", children: u.name }),
|
|
2222
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "h-1.5 w-24 overflow-hidden rounded-full bg-muted", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2223
|
+
"div",
|
|
2224
|
+
{
|
|
2225
|
+
className: "h-full rounded-full bg-primary transition-all duration-200",
|
|
2226
|
+
style: { width: `${u.progress}%` }
|
|
2227
|
+
}
|
|
2228
|
+
) }),
|
|
2229
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("span", { className: "text-[10px] text-muted-foreground w-6 text-right", children: [
|
|
2230
|
+
u.progress,
|
|
2231
|
+
"%"
|
|
2232
|
+
] })
|
|
2233
|
+
] }, i)) }),
|
|
2234
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
2235
|
+
"div",
|
|
2236
|
+
{
|
|
2237
|
+
className: "relative flex-1 overflow-y-auto p-4",
|
|
2238
|
+
onDragEnter: handleDragEnter,
|
|
2239
|
+
onDragLeave: handleDragLeave,
|
|
2240
|
+
onDragOver: handleDragOver,
|
|
2241
|
+
onDrop: handleDrop,
|
|
2242
|
+
children: [
|
|
2243
|
+
isDragging && onUpload && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "pointer-events-none absolute inset-0 z-10 flex flex-col items-center justify-center gap-3 rounded-lg border-2 border-dashed border-primary bg-primary/5 backdrop-blur-[1px]", children: [
|
|
2244
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("svg", { className: "h-10 w-10 text-primary opacity-70", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2245
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
|
|
2246
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("polyline", { points: "17 8 12 3 7 8" }),
|
|
2247
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("line", { x1: "12", y1: "3", x2: "12", y2: "15" })
|
|
2248
|
+
] }),
|
|
2249
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("p", { className: "text-sm font-medium text-primary", children: [
|
|
2250
|
+
"Drop ",
|
|
2251
|
+
accept === "images" ? "images" : "files",
|
|
2252
|
+
" to upload"
|
|
2253
|
+
] })
|
|
2254
|
+
] }),
|
|
2255
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2256
|
+
MediaGrid,
|
|
2257
|
+
{
|
|
2258
|
+
files,
|
|
2259
|
+
selected: localSelected,
|
|
2260
|
+
onSelect: handleFileSelect,
|
|
2261
|
+
loading,
|
|
2262
|
+
columns: 5,
|
|
2263
|
+
onUploadClick: onUpload ? () => fileInputRef.current?.click() : void 0
|
|
2264
|
+
}
|
|
2265
|
+
),
|
|
2266
|
+
hasMore && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2267
|
+
"button",
|
|
2268
|
+
{
|
|
2269
|
+
onClick: onLoadMore,
|
|
2270
|
+
className: "rounded-lg border px-4 py-2 text-xs text-muted-foreground transition-colors hover:bg-accent",
|
|
2271
|
+
children: "Load more"
|
|
2272
|
+
}
|
|
2273
|
+
) })
|
|
2274
|
+
]
|
|
2275
|
+
}
|
|
2276
|
+
)
|
|
2191
2277
|
] })
|
|
2192
|
-
] }, i)) }),
|
|
2193
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex-1 overflow-y-auto p-4", children: [
|
|
2194
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2195
|
-
MediaGrid,
|
|
2196
|
-
{
|
|
2197
|
-
files,
|
|
2198
|
-
selected: localSelected,
|
|
2199
|
-
onSelect: handleFileSelect,
|
|
2200
|
-
loading,
|
|
2201
|
-
columns: 5,
|
|
2202
|
-
onUploadClick: onUpload ? () => fileInputRef.current?.click() : void 0
|
|
2203
|
-
}
|
|
2204
|
-
),
|
|
2205
|
-
hasMore && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2206
|
-
"button",
|
|
2207
|
-
{
|
|
2208
|
-
onClick: onLoadMore,
|
|
2209
|
-
className: "rounded-md border px-4 py-2 text-sm text-muted-foreground transition-colors hover:bg-accent",
|
|
2210
|
-
children: "Load more"
|
|
2211
|
-
}
|
|
2212
|
-
) })
|
|
2213
2278
|
] }),
|
|
2214
|
-
|
|
2279
|
+
localSelected.size > 0 && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex items-center justify-between gap-4 border-t px-5 py-3 shrink-0 bg-muted/20", children: [
|
|
2215
2280
|
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("span", { className: "text-sm text-muted-foreground", children: [
|
|
2216
2281
|
localSelected.size,
|
|
2282
|
+
" file",
|
|
2283
|
+
localSelected.size !== 1 ? "s" : "",
|
|
2217
2284
|
" selected"
|
|
2218
2285
|
] }),
|
|
2219
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.
|
|
2286
|
+
firstSelected && firstSelected.mimeType.startsWith("image/") && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2287
|
+
"img",
|
|
2288
|
+
{
|
|
2289
|
+
src: firstSelected.url,
|
|
2290
|
+
alt: firstSelected.name,
|
|
2291
|
+
className: "h-9 w-9 rounded-lg border border-border object-cover shadow-sm"
|
|
2292
|
+
}
|
|
2293
|
+
),
|
|
2294
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
2220
2295
|
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2221
2296
|
"button",
|
|
2222
2297
|
{
|
|
2223
2298
|
onClick: () => setLocalSelected(/* @__PURE__ */ new Set()),
|
|
2224
|
-
className: "rounded-
|
|
2225
|
-
children: "
|
|
2299
|
+
className: "rounded-lg px-3 py-1.5 text-sm text-muted-foreground transition-colors hover:bg-accent",
|
|
2300
|
+
children: "Cancel"
|
|
2226
2301
|
}
|
|
2227
2302
|
),
|
|
2228
2303
|
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
2229
2304
|
"button",
|
|
2230
2305
|
{
|
|
2231
2306
|
onClick: handleConfirm,
|
|
2232
|
-
className: "rounded-
|
|
2307
|
+
className: "rounded-lg bg-primary px-4 py-1.5 text-sm font-medium text-primary-foreground transition-opacity hover:opacity-90",
|
|
2233
2308
|
children: [
|
|
2234
|
-
"
|
|
2309
|
+
"Use ",
|
|
2235
2310
|
localSelected.size,
|
|
2236
2311
|
" file",
|
|
2237
2312
|
localSelected.size !== 1 ? "s" : ""
|
|
@@ -2240,9 +2315,9 @@ function MediaPickerDialog({
|
|
|
2240
2315
|
)
|
|
2241
2316
|
] })
|
|
2242
2317
|
] })
|
|
2243
|
-
]
|
|
2244
|
-
|
|
2245
|
-
|
|
2318
|
+
]
|
|
2319
|
+
}
|
|
2320
|
+
) });
|
|
2246
2321
|
}
|
|
2247
2322
|
|
|
2248
2323
|
// src/components/media/image-picker-field.tsx
|