feat: open multi-part packages in browser
This commit is contained in:
@@ -2,25 +2,25 @@ import { useRef, useState, type ChangeEvent, type DragEvent } from 'react';
|
||||
|
||||
interface FileDropZoneProps {
|
||||
disabled?: boolean;
|
||||
onFile(file: File): void;
|
||||
onFiles(files: File[]): void;
|
||||
}
|
||||
|
||||
export function FileDropZone({ disabled = false, onFile }: FileDropZoneProps) {
|
||||
export function FileDropZone({ disabled = false, onFiles }: FileDropZoneProps) {
|
||||
const input = useRef<HTMLInputElement>(null);
|
||||
const [dragging, setDragging] = useState(false);
|
||||
|
||||
const selectFile = (event: ChangeEvent<HTMLInputElement>) => {
|
||||
const file = event.target.files?.[0];
|
||||
const selectFiles = (event: ChangeEvent<HTMLInputElement>) => {
|
||||
const files = [...(event.target.files ?? [])];
|
||||
event.target.value = '';
|
||||
if (file) onFile(file);
|
||||
if (files.length > 0) onFiles(files);
|
||||
};
|
||||
|
||||
const dropFile = (event: DragEvent<HTMLDivElement>) => {
|
||||
const dropFiles = (event: DragEvent<HTMLDivElement>) => {
|
||||
event.preventDefault();
|
||||
setDragging(false);
|
||||
if (disabled) return;
|
||||
const file = event.dataTransfer.files[0];
|
||||
if (file) onFile(file);
|
||||
const files = [...event.dataTransfer.files];
|
||||
if (files.length > 0) onFiles(files);
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -36,23 +36,24 @@ export function FileDropZone({ disabled = false, onFile }: FileDropZoneProps) {
|
||||
setDragging(false);
|
||||
}
|
||||
}}
|
||||
onDrop={dropFile}
|
||||
onDrop={dropFiles}
|
||||
data-testid="file-drop-zone"
|
||||
>
|
||||
<p className="drop-zone__eyebrow">Private, local-first reader</p>
|
||||
<h2>Open a OneNote file</h2>
|
||||
<p>
|
||||
Inspect a <code>.one</code> section or <code>.onepkg</code> notebook
|
||||
package without sending it to a server.
|
||||
Inspect a <code>.one</code> section, or a <code>.onepkg</code> notebook
|
||||
with any linked <code>.cab</code> parts, without sending it to a server.
|
||||
</p>
|
||||
<input
|
||||
ref={input}
|
||||
className="visually-hidden"
|
||||
type="file"
|
||||
accept=".one,.onepkg"
|
||||
accept=".one,.onepkg,.cab"
|
||||
multiple
|
||||
disabled={disabled}
|
||||
onChange={selectFile}
|
||||
aria-label="Choose a OneNote file"
|
||||
onChange={selectFiles}
|
||||
aria-label="Choose OneNote files"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
@@ -60,10 +61,10 @@ export function FileDropZone({ disabled = false, onFile }: FileDropZoneProps) {
|
||||
disabled={disabled}
|
||||
onClick={() => input.current?.click()}
|
||||
>
|
||||
Choose OneNote file
|
||||
Choose OneNote files
|
||||
</button>
|
||||
<span className="drop-zone__hint">
|
||||
or drop one .one or .onepkg file here
|
||||
or drop one .one, or one .onepkg with its .cab parts, here
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user