Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: dropzone behavior #980

Merged
merged 37 commits into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
fa123c1
remove dropzone pacakge
juliusmarminge Sep 23, 2024
4534736
rm
juliusmarminge Sep 23, 2024
f2cc878
fix import in svelte pacakge
juliusmarminge Sep 23, 2024
306512f
fix react
juliusmarminge Sep 23, 2024
0306bc9
Merge branch 'main' into rm-dropzone-package
juliusmarminge Sep 24, 2024
97ffa01
fix lock
juliusmarminge Sep 24, 2024
ddda408
fix some peer dep issues
juliusmarminge Sep 24, 2024
ab8b377
Revert "fix some peer dep issues"
juliusmarminge Sep 24, 2024
2bddc54
fix react dropzone double click
juliusmarminge Sep 24, 2024
caafb87
add bundled tsup config to gitignore
juliusmarminge Sep 24, 2024
f0a60bb
fix vue
juliusmarminge Sep 24, 2024
1d23a77
make solid example runnable
juliusmarminge Sep 24, 2024
09e1161
Merge branch 'main' into rm-dropzone-package
juliusmarminge Sep 24, 2024
9c94f23
Merge branch 'rm-dropzone-package' into fix-dropzone-behavior
juliusmarminge Sep 24, 2024
3622c8b
fix solid
juliusmarminge Sep 24, 2024
f66ee53
rm comment
juliusmarminge Sep 24, 2024
ff29fc8
vue abort
juliusmarminge Sep 24, 2024
67382e4
rm unused
juliusmarminge Sep 24, 2024
6043557
rm log
juliusmarminge Sep 24, 2024
adf5d41
rm logs
juliusmarminge Sep 24, 2024
22c7322
start fixing svelte
juliusmarminge Sep 24, 2024
0fa93e0
fix linter
juliusmarminge Sep 24, 2024
204262b
button works now :)
juliusmarminge Sep 24, 2024
c058cf3
unification
juliusmarminge Sep 24, 2024
dbc2ef3
Merge branch 'main' into fix-dropzone-behavior
juliusmarminge Sep 24, 2024
dff4ec4
Merge branch 'main' into fix-dropzone-behavior
juliusmarminge Sep 25, 2024
f91e6ac
unifiy even more
juliusmarminge Sep 25, 2024
af3ebbe
fmt
juliusmarminge Sep 25, 2024
5271203
unify style
juliusmarminge Sep 30, 2024
bb77d70
fix svelte dropzone
juliusmarminge Sep 30, 2024
03ddd2b
fmt
juliusmarminge Sep 30, 2024
55ac13a
rev
juliusmarminge Sep 30, 2024
b3fc423
Update uploadthing.ts
juliusmarminge Oct 1, 2024
cbe4a94
Update uploadthing.ts
juliusmarminge Oct 1, 2024
fe30932
Merge branch 'main' into fix-dropzone-behavior
juliusmarminge Oct 1, 2024
0d385e3
cs
juliusmarminge Oct 1, 2024
3db2694
Merge branch 'main' into fix-dropzone-behavior
juliusmarminge Oct 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/honest-scissors-shave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@uploadthing/svelte": patch
"@uploadthing/react": patch
"@uploadthing/solid": patch
"@uploadthing/vue": patch
---

fix: file picker would open twice when clicking the input element on the dropzone
6 changes: 6 additions & 0 deletions examples/backend-adapters/client-vue/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ function alert(message: string) {
console.log('uploaded', file);
alert('Upload complete');
},
onUploadAborted: () => {
alert('Upload Aborted');
},
onUploadError: (error) => {
console.error(error, error.cause);
alert('Upload failed');
Expand All @@ -38,6 +41,9 @@ function alert(message: string) {
console.log('uploaded', file);
alert('Upload complete');
},
onUploadAborted: () => {
alert('Upload Aborted');
},
onUploadError: (error) => {
console.error(error, error.cause);
alert('Upload failed');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { withUt } from "uploadthing/tw";

/** @type {import('tailwindcss').Config} */
export default withUt({
content: ["./src/**/*.{js,jsx,ts,tsx}"],
theme: {
Expand Down
4 changes: 1 addition & 3 deletions examples/minimal-solidstart/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "bundler",
"module": "Preserve",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"jsx": "preserve",
"jsxImportSource": "solid-js",
"allowJs": true,
Expand Down
3 changes: 3 additions & 0 deletions examples/minimal-sveltekit/src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
import "@uploadthing/svelte/styles.css";

const uploader = createUploader("videoAndImage", {
onUploadAborted: () => {
alert("Upload Aborted");
},
onClientUploadComplete: (res) => {
console.log(`onClientUploadComplete`, res);
alert("Upload Completed");
Expand Down
76 changes: 38 additions & 38 deletions packages/react/src/components/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ export function UploadButton<
// since the ErrorMessage messes it up otherwise
const $props = props as unknown as UploadButtonProps<TRouter, TEndpoint> &
UploadThingInternalProps;
const fileRouteInput = "input" in $props ? $props.input : undefined;

const {
mode = "auto",
Expand All @@ -103,7 +102,6 @@ export function UploadButton<
const acRef = useRef(new AbortController());

const fileInputRef = useRef<HTMLInputElement>(null);
const labelRef = useRef<HTMLLabelElement>(null);
const [uploadProgress, setUploadProgress] = useState(
$props.__internal_upload_progress ?? 0,
);
Expand Down Expand Up @@ -132,21 +130,49 @@ export function UploadButton<
onBeforeUploadBegin: $props.onBeforeUploadBegin,
},
);
const { fileTypes, multiple } = generatePermittedFileTypes(routeConfig);

const disabled = !!($props.__internal_button_disabled ?? $props.disabled);
const state = (() => {
const ready = $props.__internal_state === "ready" || fileTypes.length > 0;

if ($props.__internal_state) return $props.__internal_state;
if (disabled) return "disabled";
if (!ready) return "readying";
if (ready && !isUploading) return "ready";
return "uploading";
})();

const uploadFiles = useCallback(
(files: File[]) => {
startUpload(files, fileRouteInput).catch((e) => {
const input = "input" in $props ? $props.input : undefined;
startUpload(files, input).catch((e) => {
if (e instanceof UploadAbortedError) {
void $props.onUploadAborted?.();
} else {
throw e;
}
});
},
[$props, startUpload, fileRouteInput],
[$props, startUpload],
);

const { fileTypes, multiple } = generatePermittedFileTypes(routeConfig);
const onUploadClick = (e: React.MouseEvent) => {
if (state === "uploading") {
e.preventDefault();
e.stopPropagation();

acRef.current.abort();
acRef.current = new AbortController();
return;
}
if (mode === "manual" && files.length > 0) {
e.preventDefault();
e.stopPropagation();

uploadFiles(files);
}
};

const inputProps = useMemo(
() => ({
Expand All @@ -165,24 +191,14 @@ export function UploadButton<
return;
}

void uploadFiles(selectedFiles);
uploadFiles(selectedFiles);
},
disabled: fileTypes.length === 0,
tabIndex: fileTypes.length === 0 ? -1 : 0,
disabled,
tabIndex: disabled ? -1 : 0,
}),
[$props, fileTypes, mode, multiple, uploadFiles],
[$props, disabled, fileTypes, mode, multiple, uploadFiles],
);

if ($props.__internal_button_disabled) inputProps.disabled = true;
if ($props.disabled) inputProps.disabled = true;

const state = (() => {
if ($props.__internal_state) return $props.__internal_state;
if (inputProps.disabled) return "disabled";
if (!inputProps.disabled && !isUploading) return "ready";
return "uploading";
})();

usePaste((event) => {
if (!appendOnPaste) return;
if (document.activeElement !== fileInputRef.current) return;
Expand All @@ -199,7 +215,7 @@ export function UploadButton<
return filesToUpload;
});

if (mode === "auto") void uploadFiles(files);
if (mode === "auto") uploadFiles(files);
});

const styleFieldArg = {
Expand All @@ -221,7 +237,7 @@ export function UploadButton<
return "Loading...";
}
case "uploading": {
if (uploadProgress === 100) return <Spinner />;
if (uploadProgress >= 100) return <Spinner />;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why can this go over 100 lol

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haha idk. Math is hard. Probably a bug in here somewhere but felt out of scope so this was a quick fix to get the UI to behave. Will look at the progress calculation later

https://github.com/pingdotgg/uploadthing/blob/main/packages/react/src/useUploadThing.ts#L84-L97
https://github.com/pingdotgg/uploadthing/blob/main/packages/uploadthing/src/internal/upload.browser.ts#L157-L168

return (
<span className="z-50">
<span className="block group-hover:hidden">{uploadProgress}%</span>
Expand Down Expand Up @@ -305,23 +321,7 @@ export function UploadButton<
style={styleFieldToCssObject($props.appearance?.button, styleFieldArg)}
data-state={state}
data-ut-element="button"
ref={labelRef}
onClick={(e) => {
if (state === "uploading") {
e.preventDefault();
e.stopPropagation();

acRef.current.abort();
acRef.current = new AbortController();
return;
}
if (mode === "manual" && files.length > 0) {
e.preventDefault();
e.stopPropagation();

uploadFiles(files);
}
}}
onClick={onUploadClick}
>
<input {...inputProps} className="sr-only" />
{renderButton()}
Expand Down
Loading
Loading