Merlijn Vos
850c1cb1c5
Add useImageEditor ( #6122 )
...
- Create image editor abstraction in `@uppy/components`
- Refactor `Editor` (Preact) and `ImageEditor` (Uppy plugin) to put all
methods in the Uppy plugin class so they can be reused by the headless
abstraction
- Create framework hooks for React, Vue, Svelte
- Update all examples to showcase the new hook
- Symlink the `cropper.scss` (just regular CSS) from
`@uppy/image-editor` into `@uppy/components`, update `build:css` in all
framework packages to copy that file too into their own `dist/` output.
- cropper-js needs basic CSS to do the rotations and stuff which would
be very tedious to write yourself so we ship that CSS file to consumers
too so they can just import it.
- Fix memory leak where we created the image on each render inside the
original Preact plugin UI
```ts
import type { UppyFile } from '@uppy/core'
import { useImageEditor } from '@uppy/react'
interface ImageEditorProps {
file: UppyFile<any, any>
close: () => void
}
export function ImageEditor({ file, close }: ImageEditorProps) {
const {
state,
getImageProps,
getSaveButtonProps,
getCancelButtonProps,
getRotateButtonProps,
getFlipHorizontalButtonProps,
getZoomButtonProps,
getCropSquareButtonProps,
getCropLandscapeButtonProps,
getCropPortraitButtonProps,
getResetButtonProps,
getRotationSliderProps,
} = useImageEditor({ file })
return (
<div className="p-4 max-w-2xl w-full">
<div className="flex justify-between items-center mb-4">
<h2 className="text-xl font-bold">Edit Image</h2>
<button
type="button"
onClick={close}
className="text-gray-500 hover:text-gray-700"
>
✕
</button>
</div>
<div className="mb-4">
{/* biome-ignore lint/a11y/useAltText: alt is provided by getImageProps() */}
<img
className="w-full max-h-[400px] rounded-lg border-2"
{...getImageProps()}
/>
</div>
<div className="mb-4">
<label className="block text-sm font-medium mb-2">
Fine Rotation: {state.angle}°
<input className="w-full mt-1" {...getRotationSliderProps()} />
</label>
</div>
<div className="flex gap-2 flex-wrap mb-4">
<button
className="bg-gray-200 px-3 py-1 rounded disabled:opacity-50"
{...getRotateButtonProps(-90)}
>
↶ -90°
</button>
<button
className="bg-gray-200 px-3 py-1 rounded disabled:opacity-50"
{...getRotateButtonProps(90)}
>
↷ +90°
</button>
<button
className="bg-gray-200 px-3 py-1 rounded disabled:opacity-50"
{...getFlipHorizontalButtonProps()}
>
⇆ Flip
</button>
<button
className="bg-gray-200 px-3 py-1 rounded disabled:opacity-50"
{...getZoomButtonProps(0.1)}
>
+ Zoom
</button>
<button
className="bg-gray-200 px-3 py-1 rounded disabled:opacity-50"
{...getZoomButtonProps(-0.1)}
>
- Zoom
</button>
</div>
<div className="flex gap-2 flex-wrap mb-4">
<button
className="bg-gray-200 px-3 py-1 rounded disabled:opacity-50"
{...getCropSquareButtonProps()}
>
1:1
</button>
<button
className="bg-gray-200 px-3 py-1 rounded disabled:opacity-50"
{...getCropLandscapeButtonProps()}
>
16:9
</button>
<button
className="bg-gray-200 px-3 py-1 rounded disabled:opacity-50"
{...getCropPortraitButtonProps()}
>
9:16
</button>
<button
className="bg-gray-200 px-3 py-1 rounded disabled:opacity-50"
{...getResetButtonProps()}
>
Reset
</button>
</div>
<div className="flex gap-4 justify-end">
<button
className="bg-gray-500 text-white px-4 py-2 rounded-md"
{...getCancelButtonProps({ onClick: close })}
>
Cancel
</button>
<button
className="bg-green-500 text-white px-4 py-2 rounded-md disabled:opacity-50 disabled:bg-green-300"
{...getSaveButtonProps({ onClick: close })}
>
Save
</button>
</div>
</div>
)
}
export default ImageEditor
```
https://github.com/user-attachments/assets/4b0a99cc-8489-41a2-aa3b-ce88110025bf
---------
Co-authored-by: Prakash <qxprakash@gmail.com>
2026-01-29 11:13:12 +01:00
Merlijn Vos
da754b7fa4
@uppy/svelte: fix props reactivity ( #5991 )
...
The fix in #5872 was not enough
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> Fix props reactivity in Svelte components by updating plugin options
reactively and add example + tests validating Dashboard/StatusBar prop
changes.
>
> - **Svelte components (@uppy/svelte)**:
> - **Reactivity fix**: In `components/Dashboard.svelte`,
`DashboardModal.svelte`, and `StatusBar.svelte`, switch reactive updates
from `uppy.setOptions(...)` to `plugin?.setOptions(...)` to ensure
`props` changes are applied.
> - **Examples/Tests**:
> - Add `examples/sveltekit/src/components/test/props-reactivity.svelte`
demonstrating toggling `props` for `Dashboard` and `StatusBar`.
> - Extend `examples/sveltekit/test/index.test.ts` with tests verifying
Dashboard `ariaDisabled` toggles and StatusBar `hideUploadButton`
reactivity.
> - **Changeset**:
> - Patch release for `"@uppy/svelte"` noting props reactivity fix.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot ) for commit
5a9c4ef00f . This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot ).</sup>
<!-- /CURSOR_SUMMARY -->
2025-10-01 16:16:47 +02:00
Prakash
c5b51f6158
Add Export Maps ( #5830 )
...
- added export maps to all the @uppy packages .
- imports remain unaffected except for peerDep packages in `@uppy/react`
`@uppy/svelte` and `@uppy/vue3`.
- export maps added for index files , css , and package.json.
- Added side effects for all the packages.
---------
Co-authored-by: Mikael Finstad <finstaden@gmail.com>
Co-authored-by: Merlijn Vos <merlijn@soverin.net>
2025-07-31 17:22:57 +02:00
Prakash
455abb32af
Headless Hooks: add error component in examples ( #5810 )
...
Add error components in headless hooks examples for `useWebcam` and
`useScreenCapture`
2025-07-09 10:44:47 +02:00
Merlijn Vos
78299475ae
Migrate from Eslint/Prettier/Stylelint to Biome ( #5794 )
2025-07-01 14:55:41 +02:00
Merlijn Vos
cb2999926b
Add useRemoteSource ( #5778 )
2025-06-24 11:00:37 +02:00
Prakash
b0e69cf7ce
Headless Hooks: Add useScreenCapture ( #5784 )
2025-06-19 12:42:01 +02:00
Merlijn Vos
7d807e6d5e
Add useWebcam ( #5741 )
...
Co-authored-by: Mikael Finstad <finstaden@gmail.com>
2025-06-12 11:03:57 +02:00
Merlijn Vos
5c0c831937
Add useDropzone & useFileInput ( #5735 )
...
Co-authored-by: Mikael Finstad <finstaden@gmail.com>
2025-06-09 10:54:28 +02:00
Merlijn Vos
0259b09d73
Headless components ( #5727 )
...
Co-authored-by: Mikael Finstad <finstaden@gmail.com>
2025-05-22 09:59:43 +02:00