Skip to content

Commit 9345ad8

Browse files
committed
feat: MediaUpload 기존 이미지가 있는 경우 대응
1 parent bf3281c commit 9345ad8

File tree

4 files changed

+35
-7
lines changed

4 files changed

+35
-7
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ddingdong-design-system",
3-
"version": "1.0.1",
3+
"version": "1.0.2",
44
"type": "module",
55
"keywords": [
66
"react",

src/shared/ui/MediaUpload/MediaUpload.stories.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,13 @@ export const MultipleMode: Story = {
4242
multiple: true,
4343
},
4444
};
45+
46+
export const EditMode: Story = {
47+
args: {
48+
multiple: true,
49+
initialPreviewUrls: [
50+
'https://images.unsplash.com/photo-1500530855697-b586d89ba3ee?q=80&w=1200&auto=format&fit=crop',
51+
],
52+
initialFiles: [new File([], 'test.jpg')],
53+
},
54+
};

src/shared/ui/MediaUpload/MediaUpload.tsx

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@ export type Props = {
4545
* @default false
4646
*/
4747
multiple?: boolean;
48+
/**
49+
* initial preview urls for edit mode (e.g., existing uploaded image urls)
50+
*/
51+
initialPreviewUrls?: string[];
52+
/**
53+
* initial files for edit mode (if available).
54+
*/
55+
initialFiles?: File[];
4856
} & Omit<ComponentProps<'input'>, 'id'>;
4957

5058
const GB = 1024 * 1024 * 1024;
@@ -58,17 +66,21 @@ export function MediaUpload({
5866
maxSize = 5,
5967
acceptedFormats = ['image/*'],
6068
multiple = false,
69+
initialPreviewUrls,
70+
initialFiles,
6171
...props
6272
}: Props) {
6373
const generatedId = useId();
6474
const inputId = id || generatedId;
6575

66-
const [selectedFiles, setSelectedFiles] = useState<File[]>([]);
67-
const [previewUrls, setPreviewUrls] = useState<string[]>([]);
76+
const [selectedFiles, setSelectedFiles] = useState<File[]>(initialFiles || []);
77+
const [previewUrls, setPreviewUrls] = useState<string[]>(initialPreviewUrls || []);
6878
const isSelected = selectedFiles.length > 0;
6979

7080
const handleReset = () => {
71-
previewUrls.forEach((url) => URL.revokeObjectURL(url));
81+
previewUrls.forEach((url) => {
82+
if (url.startsWith('blob:')) URL.revokeObjectURL(url);
83+
});
7284
setSelectedFiles([]);
7385
setPreviewUrls([]);
7486
onFileUpload?.(null);
@@ -92,7 +104,10 @@ export function MediaUpload({
92104
};
93105

94106
const handleRemoveFile = (index: number) => {
95-
URL.revokeObjectURL(previewUrls[index]);
107+
const urlToRemove = previewUrls[index];
108+
if (urlToRemove?.startsWith('blob:')) {
109+
URL.revokeObjectURL(urlToRemove);
110+
}
96111
const newFiles = selectedFiles.filter((_, i) => i !== index);
97112
const newUrls = previewUrls.filter((_, i) => i !== index);
98113

@@ -162,7 +177,10 @@ function RefreshButton({ handleReset, isSelected }: RefreshButtonProp) {
162177
return (
163178
<Flex
164179
as="button"
165-
onClick={isSelected ? handleReset : undefined}
180+
onClick={(e) => {
181+
e.stopPropagation();
182+
if (isSelected) handleReset();
183+
}}
166184
alignItems="center"
167185
className={`text-primary-300 justify-end ${isSelected ? 'cursor-pointer' : 'cursor-not-allowed opacity-50'}`}
168186
aria-label="초기화"

src/shared/ui/MediaUpload/MediaUploadPreview.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export function MediaPreview({ files, previewUrls, onRemoveFile, multiple }: Pro
2020
<button
2121
type="button"
2222
onClick={() => onRemoveFile(index)}
23-
className="absolute top-2 right-2 rounded-full bg-white/75 p-1"
23+
className="absolute top-2 right-2 cursor-pointer rounded-full bg-white/75 p-1"
2424
>
2525
<Icon name="close" size={14} />
2626
</button>

0 commit comments

Comments
 (0)