@unicitylabs/sphere-ui 0.1.27 → 0.1.28
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.ts +0 -3
- package/dist/index.js +50 -37
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -314,9 +314,6 @@ interface MediaUploaderProps {
|
|
|
314
314
|
* locally, render a blob-URL preview, and call onFileSelected(file). The
|
|
315
315
|
* consumer is responsible for uploading later (e.g. after creating the
|
|
316
316
|
* parent entity to get a real ownerId).
|
|
317
|
-
*
|
|
318
|
-
* In this mode the URL paste fallback is hidden — the parent entity does
|
|
319
|
-
* not yet exist, so an external URL can't be persisted to it anyway.
|
|
320
317
|
*/
|
|
321
318
|
deferUpload?: boolean;
|
|
322
319
|
onFileSelected?: (file: File | null) => void;
|
package/dist/index.js
CHANGED
|
@@ -1478,6 +1478,7 @@ function MediaUploader({
|
|
|
1478
1478
|
const limit = MEDIA_LIMITS[kind];
|
|
1479
1479
|
const [state, setState] = useState7({ phase: "idle" });
|
|
1480
1480
|
const [urlInput, setUrlInput] = useState7(value && !value.startsWith("blob:") ? value : "");
|
|
1481
|
+
const [source, setSource] = useState7("upload");
|
|
1481
1482
|
const previewRef = useRef3(null);
|
|
1482
1483
|
const fileInputRef = useRef3(null);
|
|
1483
1484
|
const isPlaceholder = value?.includes("placehold.co") ?? false;
|
|
@@ -1506,6 +1507,7 @@ function MediaUploader({
|
|
|
1506
1507
|
});
|
|
1507
1508
|
return;
|
|
1508
1509
|
}
|
|
1510
|
+
setUrlInput("");
|
|
1509
1511
|
const fitted = await fitImage(file, limit);
|
|
1510
1512
|
if (fitted.type !== "image/svg+xml") {
|
|
1511
1513
|
const size = await readImageSize(fitted);
|
|
@@ -1609,9 +1611,26 @@ function MediaUploader({
|
|
|
1609
1611
|
setUrlInput("");
|
|
1610
1612
|
if (deferUpload) onFileSelected?.(null);
|
|
1611
1613
|
};
|
|
1614
|
+
const commitUrl = () => {
|
|
1615
|
+
const url = urlInput.trim();
|
|
1616
|
+
onChange(url || null);
|
|
1617
|
+
if (url) {
|
|
1618
|
+
if (previewRef.current) {
|
|
1619
|
+
URL.revokeObjectURL(previewRef.current);
|
|
1620
|
+
previewRef.current = null;
|
|
1621
|
+
}
|
|
1622
|
+
setState({ phase: "idle" });
|
|
1623
|
+
if (deferUpload) onFileSelected?.(null);
|
|
1624
|
+
}
|
|
1625
|
+
};
|
|
1626
|
+
const tabClass = (active) => `px-3 py-1 rounded-md transition-colors ${active ? "bg-white dark:bg-white/10 text-neutral-900 dark:text-white shadow-sm" : "text-neutral-500 dark:text-white/45 hover:text-neutral-700 dark:hover:text-white/70"}`;
|
|
1612
1627
|
return /* @__PURE__ */ jsxs18("div", { className: "space-y-2", children: [
|
|
1613
1628
|
label && /* @__PURE__ */ jsx23("div", { className: "text-sm text-neutral-700 dark:text-white/70", children: label }),
|
|
1614
|
-
/* @__PURE__ */ jsxs18(
|
|
1629
|
+
/* @__PURE__ */ jsxs18("div", { className: "inline-flex gap-0.5 rounded-lg p-0.5 bg-neutral-100 dark:bg-white/5 text-xs w-fit", children: [
|
|
1630
|
+
/* @__PURE__ */ jsx23("button", { type: "button", onClick: () => setSource("upload"), className: tabClass(source === "upload"), children: "Upload" }),
|
|
1631
|
+
/* @__PURE__ */ jsx23("button", { type: "button", onClick: () => setSource("url"), className: tabClass(source === "url"), children: "URL" })
|
|
1632
|
+
] }),
|
|
1633
|
+
source === "upload" && /* @__PURE__ */ jsxs18(
|
|
1615
1634
|
"div",
|
|
1616
1635
|
{
|
|
1617
1636
|
...getRootProps(),
|
|
@@ -1717,19 +1736,16 @@ function MediaUploader({
|
|
|
1717
1736
|
]
|
|
1718
1737
|
}
|
|
1719
1738
|
),
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
}
|
|
1731
|
-
)
|
|
1732
|
-
] })
|
|
1739
|
+
source === "url" && /* @__PURE__ */ jsx23(
|
|
1740
|
+
Input,
|
|
1741
|
+
{
|
|
1742
|
+
type: "url",
|
|
1743
|
+
placeholder: "https://...",
|
|
1744
|
+
value: urlInput,
|
|
1745
|
+
onChange: (e) => setUrlInput(e.target.value),
|
|
1746
|
+
onBlur: commitUrl
|
|
1747
|
+
}
|
|
1748
|
+
)
|
|
1733
1749
|
] });
|
|
1734
1750
|
}
|
|
1735
1751
|
|
|
@@ -1784,18 +1800,18 @@ function MediaGallery({ ownerType, ownerId, items, onChange, uploadFn, max = 10,
|
|
|
1784
1800
|
};
|
|
1785
1801
|
function handleDragEnd(e) {
|
|
1786
1802
|
if (!e.over || e.active.id === e.over.id) return;
|
|
1787
|
-
if (
|
|
1788
|
-
const oldIndex = pending.findIndex((p) => p.preview === e.active.id);
|
|
1789
|
-
const newIndex = pending.findIndex((p) => p.preview === e.over.id);
|
|
1790
|
-
emitPending(arrayMove(pending, oldIndex, newIndex));
|
|
1791
|
-
} else {
|
|
1803
|
+
if (items.some((i) => i.url === e.active.id)) {
|
|
1792
1804
|
const oldIndex = items.findIndex((i) => i.url === e.active.id);
|
|
1793
1805
|
const newIndex = items.findIndex((i) => i.url === e.over.id);
|
|
1794
|
-
onChange(arrayMove(items, oldIndex, newIndex));
|
|
1806
|
+
if (newIndex >= 0) onChange(arrayMove(items, oldIndex, newIndex));
|
|
1807
|
+
} else if (deferUpload) {
|
|
1808
|
+
const oldIndex = pending.findIndex((p) => p.preview === e.active.id);
|
|
1809
|
+
const newIndex = pending.findIndex((p) => p.preview === e.over.id);
|
|
1810
|
+
if (newIndex >= 0) emitPending(arrayMove(pending, oldIndex, newIndex));
|
|
1795
1811
|
}
|
|
1796
1812
|
}
|
|
1797
|
-
const count = deferUpload ? pending.length :
|
|
1798
|
-
const tileIds =
|
|
1813
|
+
const count = items.length + (deferUpload ? pending.length : 0);
|
|
1814
|
+
const tileIds = [...items.map((i) => i.url), ...deferUpload ? pending.map((p) => p.preview) : []];
|
|
1799
1815
|
return /* @__PURE__ */ jsxs19(
|
|
1800
1816
|
"div",
|
|
1801
1817
|
{
|
|
@@ -1811,7 +1827,15 @@ function MediaGallery({ ownerType, ownerId, items, onChange, uploadFn, max = 10,
|
|
|
1811
1827
|
")"
|
|
1812
1828
|
] }),
|
|
1813
1829
|
/* @__PURE__ */ jsx24(DndContext, { collisionDetection: closestCenter, onDragEnd: handleDragEnd, children: /* @__PURE__ */ jsx24(SortableContext, { items: tileIds, strategy: horizontalListSortingStrategy, children: /* @__PURE__ */ jsxs19("div", { className: "flex flex-wrap gap-2", children: [
|
|
1814
|
-
|
|
1830
|
+
items.map((item, i) => /* @__PURE__ */ jsx24(
|
|
1831
|
+
SortableTile,
|
|
1832
|
+
{
|
|
1833
|
+
item,
|
|
1834
|
+
onRemove: () => onChange(items.filter((_, j) => j !== i))
|
|
1835
|
+
},
|
|
1836
|
+
item.url
|
|
1837
|
+
)),
|
|
1838
|
+
deferUpload && pending.map((p, i) => /* @__PURE__ */ jsx24(
|
|
1815
1839
|
SortableTile,
|
|
1816
1840
|
{
|
|
1817
1841
|
item: { type: "screenshot", url: p.preview },
|
|
@@ -1821,13 +1845,6 @@ function MediaGallery({ ownerType, ownerId, items, onChange, uploadFn, max = 10,
|
|
|
1821
1845
|
}
|
|
1822
1846
|
},
|
|
1823
1847
|
p.preview
|
|
1824
|
-
)) : items.map((item, i) => /* @__PURE__ */ jsx24(
|
|
1825
|
-
SortableTile,
|
|
1826
|
-
{
|
|
1827
|
-
item,
|
|
1828
|
-
onRemove: () => onChange(items.filter((_, j) => j !== i))
|
|
1829
|
-
},
|
|
1830
|
-
item.url
|
|
1831
1848
|
)),
|
|
1832
1849
|
count < max && !adding && /* @__PURE__ */ jsx24(
|
|
1833
1850
|
"button",
|
|
@@ -1856,13 +1873,9 @@ function MediaGallery({ ownerType, ownerId, items, onChange, uploadFn, max = 10,
|
|
|
1856
1873
|
}
|
|
1857
1874
|
setAdding(false);
|
|
1858
1875
|
} : void 0,
|
|
1859
|
-
onChange:
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
const isDuplicate = items.some((i) => i.url === url);
|
|
1863
|
-
if (!isDuplicate) {
|
|
1864
|
-
onChange([...items, { type: "screenshot", url }]);
|
|
1865
|
-
}
|
|
1876
|
+
onChange: (url) => {
|
|
1877
|
+
if (url && !items.some((i) => i.url === url)) {
|
|
1878
|
+
onChange([...items, { type: "screenshot", url }]);
|
|
1866
1879
|
}
|
|
1867
1880
|
setAdding(false);
|
|
1868
1881
|
},
|