@@ -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
5058const 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 = "초기화"
0 commit comments