PluginProbe
Code Snippets / 4.0.0-beta.2
Code Snippets v4.0.0-beta.2
4.0.0-beta.2 3.10.2 3.10.1 3.10.0 3.10.0-beta.2 3.10.0-beta.1 4.0.0-beta.1 3.9.6 trunk 2.10.0 2.10.1 2.12.0 2.12.1 2.13.0 2.13.1 2.13.2 2.13.3 2.14.0 2.14.1 2.14.2 2.14.3 2.14.4 2.14.5 2.14.6 3.0.0 All 65 releases
code-snippets / js / components / ImportMenu / UploadForm / SelectFiles / DragDropUploadArea.tsx

DragDropUploadArea.tsx in Code Snippets 4.0.0-beta.2, at js/components/ImportMenu/UploadForm/SelectFiles/DragDropUploadArea.tsx

83 lines 2.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import React, { useId, useState } from 'react'
2 import classnames from 'classnames'
3 import { __ } from '@wordpress/i18n'
4 import type { DragEventHandler, RefObject } from 'react'
5
6 export interface DragDropUploadAreaProps {
7 fileInputRef: RefObject<HTMLInputElement>
8 onFileSelect: (files: FileList | undefined) => void
9 disabled?: boolean
10 }
11
12 const useDragDropZone = (
13 disabled: boolean | undefined,
14 onFileSelect: (files: FileList | undefined) => void
15 ) => {
16 const [dragOver, setDragOver] = useState(false)
17
18 const handleDragOver: DragEventHandler<HTMLElement> = event => {
19 if (disabled) {
20 return
21 }
22
23 event.preventDefault()
24 setDragOver(true)
25 }
26
27 const handleDragLeave: DragEventHandler<HTMLElement> = event => {
28 if (disabled) {
29 return
30 }
31
32 event.preventDefault()
33 setDragOver(false)
34 }
35
36 const handleDrop: DragEventHandler<HTMLElement> = event => {
37 if (disabled) {
38 return
39 }
40
41 handleDragLeave(event)
42 if (0 < event.dataTransfer.files.length) {
43 onFileSelect(event.dataTransfer.files)
44 }
45 }
46
47 return { dragOver, handleDragOver, handleDragLeave, handleDrop }
48 }
49
50 export const DragDropUploadArea: React.FC<DragDropUploadAreaProps> = ({ fileInputRef, onFileSelect, disabled }) => {
51 const fileInputId = useId()
52 const { dragOver, handleDragOver, handleDragLeave, handleDrop } = useDragDropZone(disabled, onFileSelect)
53
54 return (
55 <div
56 className="upload-drop-zone-wrapper"
57 onDragOver={handleDragOver}
58 onDragLeave={handleDragLeave}
59 onDrop={handleDrop}
60 >
61 <label
62 htmlFor={fileInputId}
63 className={classnames('upload-drop-zone', { 'drag-over': dragOver, 'disabled': disabled })}
64 >
65 <div className="drop-zone-icon" aria-hidden="true">📁</div>
66 <p>{__('Drag and drop files here, or click to browse', 'code-snippets')}</p>
67 <p>{__('Supports JSON and XML files', 'code-snippets')}</p>
68 </label>
69 <input
70 ref={fileInputRef}
71 id={fileInputId}
72 className="upload-drop-zone-file-input"
73 type="file"
74 accept="application/json,.json,text/xml"
75 multiple
76 onChange={event => onFileSelect(event.target.files ?? undefined)}
77 disabled={disabled}
78 aria-label={__('Select files to import', 'code-snippets')}
79 />
80 </div>
81 )
82 }
83