@webdevarif/dashui 0.2.2 → 0.2.4

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.mjs CHANGED
@@ -1894,7 +1894,6 @@ function MediaPickerDialog({
1894
1894
  folders = [],
1895
1895
  loading = false,
1896
1896
  total,
1897
- uploads = [],
1898
1897
  typeFilter = "all",
1899
1898
  onTypeChange,
1900
1899
  search = "",
@@ -1905,14 +1904,56 @@ function MediaPickerDialog({
1905
1904
  onLoadMore,
1906
1905
  hasMore = false,
1907
1906
  multiple = false,
1907
+ initialSelected = [],
1908
1908
  accept = "all",
1909
1909
  onSelect
1910
1910
  }) {
1911
- const [localSelected, setLocalSelected] = React20.useState(/* @__PURE__ */ new Set());
1911
+ const [localSelected, setLocalSelected] = React20.useState(new Set(initialSelected));
1912
+ const [isDragging, setIsDragging] = React20.useState(false);
1912
1913
  const fileInputRef = React20.useRef(null);
1914
+ const dragCounterRef = React20.useRef(0);
1913
1915
  React20.useEffect(() => {
1914
- if (!open) setLocalSelected(/* @__PURE__ */ new Set());
1916
+ if (open) {
1917
+ setLocalSelected(new Set(initialSelected));
1918
+ } else {
1919
+ setLocalSelected(/* @__PURE__ */ new Set());
1920
+ setIsDragging(false);
1921
+ dragCounterRef.current = 0;
1922
+ }
1915
1923
  }, [open]);
1924
+ const handleDragEnter = (e) => {
1925
+ e.preventDefault();
1926
+ e.stopPropagation();
1927
+ if (e.dataTransfer.types.includes("Files")) {
1928
+ dragCounterRef.current++;
1929
+ setIsDragging(true);
1930
+ }
1931
+ };
1932
+ const handleDragLeave = (e) => {
1933
+ e.preventDefault();
1934
+ e.stopPropagation();
1935
+ dragCounterRef.current--;
1936
+ if (dragCounterRef.current <= 0) {
1937
+ dragCounterRef.current = 0;
1938
+ setIsDragging(false);
1939
+ }
1940
+ };
1941
+ const handleDragOver = (e) => {
1942
+ e.preventDefault();
1943
+ e.stopPropagation();
1944
+ };
1945
+ const handleDrop = (e) => {
1946
+ e.preventDefault();
1947
+ e.stopPropagation();
1948
+ dragCounterRef.current = 0;
1949
+ setIsDragging(false);
1950
+ if (!onUpload || !e.dataTransfer.files.length) return;
1951
+ const accepted = accept === "images" ? Array.from(e.dataTransfer.files).filter((f) => f.type.startsWith("image/")) : Array.from(e.dataTransfer.files);
1952
+ if (!accepted.length) return;
1953
+ const dt = new DataTransfer();
1954
+ accepted.forEach((f) => dt.items.add(f));
1955
+ onUpload(dt.files);
1956
+ };
1916
1957
  const typeOptions = ALL_TYPE_OPTIONS.filter(
1917
1958
  (o) => accept === "images" ? o.value === "all" || o.value === "images" : true
1918
1959
  );
@@ -1936,7 +1977,6 @@ function MediaPickerDialog({
1936
1977
  onUpload(e.target.files);
1937
1978
  }
1938
1979
  };
1939
- const activeUploads = uploads.filter((u) => u.status === "uploading");
1940
1980
  const firstSelected = files.find((f) => localSelected.has(f.id));
1941
1981
  return /* @__PURE__ */ jsx34(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs20(
1942
1982
  DialogContent,
@@ -2042,41 +2082,49 @@ function MediaPickerDialog({
2042
2082
  )
2043
2083
  ] })
2044
2084
  ] }),
2045
- activeUploads.length > 0 && /* @__PURE__ */ jsx34("div", { className: "border-b px-4 py-2 space-y-1.5 shrink-0", children: activeUploads.map((u, i) => /* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-2", children: [
2046
- /* @__PURE__ */ jsx34("span", { className: "flex-1 truncate text-xs text-muted-foreground", children: u.name }),
2047
- /* @__PURE__ */ jsx34("div", { className: "h-1.5 w-24 overflow-hidden rounded-full bg-muted", children: /* @__PURE__ */ jsx34(
2048
- "div",
2049
- {
2050
- className: "h-full rounded-full bg-primary transition-all duration-200",
2051
- style: { width: `${u.progress}%` }
2052
- }
2053
- ) }),
2054
- /* @__PURE__ */ jsxs20("span", { className: "text-[10px] text-muted-foreground w-6 text-right", children: [
2055
- u.progress,
2056
- "%"
2057
- ] })
2058
- ] }, i)) }),
2059
- /* @__PURE__ */ jsxs20("div", { className: "flex-1 overflow-y-auto p-4", children: [
2060
- /* @__PURE__ */ jsx34(
2061
- MediaGrid,
2062
- {
2063
- files,
2064
- selected: localSelected,
2065
- onSelect: handleFileSelect,
2066
- loading,
2067
- columns: 5,
2068
- onUploadClick: onUpload ? () => fileInputRef.current?.click() : void 0
2069
- }
2070
- ),
2071
- hasMore && /* @__PURE__ */ jsx34("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsx34(
2072
- "button",
2073
- {
2074
- onClick: onLoadMore,
2075
- className: "rounded-lg border px-4 py-2 text-xs text-muted-foreground transition-colors hover:bg-accent",
2076
- children: "Load more"
2077
- }
2078
- ) })
2079
- ] })
2085
+ /* @__PURE__ */ jsxs20(
2086
+ "div",
2087
+ {
2088
+ className: "relative flex-1 overflow-y-auto p-4",
2089
+ onDragEnter: handleDragEnter,
2090
+ onDragLeave: handleDragLeave,
2091
+ onDragOver: handleDragOver,
2092
+ onDrop: handleDrop,
2093
+ children: [
2094
+ isDragging && onUpload && /* @__PURE__ */ jsxs20("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: [
2095
+ /* @__PURE__ */ jsxs20("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: [
2096
+ /* @__PURE__ */ jsx34("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
2097
+ /* @__PURE__ */ jsx34("polyline", { points: "17 8 12 3 7 8" }),
2098
+ /* @__PURE__ */ jsx34("line", { x1: "12", y1: "3", x2: "12", y2: "15" })
2099
+ ] }),
2100
+ /* @__PURE__ */ jsxs20("p", { className: "text-sm font-medium text-primary", children: [
2101
+ "Drop ",
2102
+ accept === "images" ? "images" : "files",
2103
+ " to upload"
2104
+ ] })
2105
+ ] }),
2106
+ /* @__PURE__ */ jsx34(
2107
+ MediaGrid,
2108
+ {
2109
+ files,
2110
+ selected: localSelected,
2111
+ onSelect: handleFileSelect,
2112
+ loading,
2113
+ columns: 5,
2114
+ onUploadClick: onUpload ? () => fileInputRef.current?.click() : void 0
2115
+ }
2116
+ ),
2117
+ hasMore && /* @__PURE__ */ jsx34("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsx34(
2118
+ "button",
2119
+ {
2120
+ onClick: onLoadMore,
2121
+ className: "rounded-lg border px-4 py-2 text-xs text-muted-foreground transition-colors hover:bg-accent",
2122
+ children: "Load more"
2123
+ }
2124
+ ) })
2125
+ ]
2126
+ }
2127
+ )
2080
2128
  ] })
2081
2129
  ] }),
2082
2130
  localSelected.size > 0 && /* @__PURE__ */ jsxs20("div", { className: "flex items-center justify-between gap-4 border-t px-5 py-3 shrink-0 bg-muted/20", children: [