Commit graph

94 commits

Author SHA1 Message Date
Prakash
1427add64a
@uppy/upgrade-devdeps-v1 (#6317)
Part of the dev-dependency major-version upgrades. These required code
changes so they're split out from the no-code-change batch (#6315).

**AI Disclaimer** : AI Used

- **glob 8 → 13** — `@uppy/locales` scripts: the callback API was
removed, so `getPaths()` uses the promise form and `test.mjs` uses the
named `globSync`.
- **npm-packlist 5 → 11** — `upload-to-cdn.js`: v7+ takes an
`@npmcli/arborist` tree instead of `{ path }`; loads the tree and passes
it to `packlist()`. Adds `@npmcli/arborist` as a devDependency.
- **nock 13 → 14** (`@uppy/companion`) — the v14 @mswjs/interceptors
rewrite crashed the SSRF tests in `http-agent.test.ts`; nock
interception is now kept off by default and only activated for the one
test that mocks a host.
- **@types/use-sync-external-store 0 → 1** — `@uppy/react`: v1's exports
map only exposes extensionless subpaths, so imports use
`use-sync-external-store/shim` and `/with-selector` (runtime supports
both).
2026-06-03 14:38:14 +05:30
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
Prakash
79e6460a6c
Make Generics Optional in uppy.getPlugin (#6057)
fixes #6024.

### Problem
- `getPlugin()` defaults to `UnknownPlugin`, so methods like `openModal`
are not visible , since core is not aware of that plugin type

### Proposed change
- Introduce a types-only registry in core:
- `export interface PluginTypeRegistry<M extends Meta, B extends Body>
{}`
- Overload `getPlugin` to return a precise type when the id is a known
key of the registry.
- add `Dashboard` to  PluginTypeRegistry through module augmentation:
  - `'Dashboard': Dashboard<M, B>`.
- When a project imports from `@uppy/dashboard`, its module augmentation
extends PluginTypeRegistry, adding the correct type into it
- I've added Tests , kept them in a separate file so it's easier to
review , once this approach gets approved I'll add them to
`Uppy.test.ts`

Once this PR gets a positive review I'll add this for other plugins ,
currently only added for `@uppy/dashboard`

**Build with Local tarball can be checked here** 


https://stackblitz.com/~/github.com/qxprakash/uppy-type-test?file=type_test.ts
2025-11-17 18:18:54 +05:30
Merlijn Vos
16aa6fe941
@uppy/react: export useUppyContext (#6044)
Fixes #6043
2025-10-30 09:59:13 +01:00
Prakash
86f353d2fe
@uppy/react: remove dashboard export (#6036)
No need to export it from index.ts, since it’s already exported through
the export maps. Also, it’s an optional peer dependency, we probably
missed this in #5830 , though this might count as a breaking change now
☹️
2025-10-27 09:33:29 +01:00
Prakash
92a0a0d2b8
add back framework wrappers for @uppy/status-bar (#5948)
- added `react` `vue` `svelte` `angular` framwork wrappers for
`@uppy/status-bar`
- `git add -f
packages/@uppy/angular/projects/uppy/angular/src/lib/components/status-bar/`
because
https://transloadit.slack.com/archives/C0FMW9PSB/p1755632185831369?thread_ts=1755526948.473969&cid=C0FMW9PSB
2025-09-17 10:40:57 +02:00
Mikael Finstad
075636a3b3
remove react h (#5938)
it was added in #5935 but no explanation of why.

if you look at the build output of for example
`packages/@uppy/react/lib/headless/generated/Dropzone.js`:

```js
import { jsx as _jsx } from "react/jsx-runtime";
// This file was generated by build-components.mjs
// ANY EDITS WILL BE OVERWRITTEN!
import { Dropzone as PreactDropzone, } from '@uppy/components';
import { h as preactH, render as preactRender } from 'preact';
// biome-ignore lint/correctness/noUnusedImports: it's needed
import { createElement as h, useContext, useEffect, useRef } from 'react';
import { UppyContext } from '../UppyContextProvider.js';
export default function Dropzone(props) {
    const ref = useRef(null);
    const ctx = useContext(UppyContext);
    useEffect(() => {
        if (ref.current) {
            preactRender(preactH(PreactDropzone, {
                ...props,
                ctx,
            }), ref.current);
        }
    }, [ctx, props]);
    return _jsx("div", { ref: ref });
}
```

as can be seen there is no usage of `h`. `import { jsx as _jsx } from
"react/jsx-runtime";` is being injected for React JSX. see also
https://github.com/transloadit/uppy/pull/5896#issuecomment-3169210799
2025-08-29 16:24:16 +02:00
Merlijn Vos
49522ec5cb
Remove preact/compat (#5935)
We drag it in unneccesarily in the bundle and it can cause JSX clashes
in React apps with `"jsx": "preserve"` in their `tsconfig.json`
(https://github.com/preactjs/preact/issues/4908)

- Remove `@types/react` from companion (unused)
- Fix tsconfig's for @uppy/utils (build was fine, but editor diagnostics
weren't)
2025-08-28 16:57:07 +02:00
Prakash
6a33652458 Merge branch 'main' of https://github.com/transloadit/uppy into 5.0 2025-08-20 16:17:08 +05:30
Prakash
d301c01d6a
@uppy/utils: update export maps (#5900)
- cleanup `@uppy/utils ` removed unused / redundant modules .
- migrated modules and tests from `.js` to `.ts`
- removed all the nested export paths
- updated `@uppy/utils` import paths for all packages
- `@uppy/angular` is still failing while running`yarn build` , I'm
looking into it.

---------

Co-authored-by: Merlijn Vos <merlijn@soverin.net>
2025-08-19 12:25:27 +02:00
Mikael Finstad
d31c90e443
Run biome check on main (#5896)
this time on main
closes #5891

also: fix a11y tabIndex (key event handler)
2025-08-11 10:06:21 +02:00
Prakash
e8692434d6
Merge @uppy/status-bar into @uppy/dashboard (#5825)
This pull request removes the `@uppy/status-bar` plugin and integrates
it directly into the `@uppy/dashboard` plugin.

### Breakdown of the merge

- The `StatusBar` class was refactored from a `UIPlugin` into a Preact
Class component.
- The `locale` strings from status-bar were merged into dashboard's
locale file.
- The Dashboard plugin now integrates the `StatusBar` component
directly, controlling its visibility and passing down all props ( i.e.
options that were specific to StatusBar (like showProgressDetails).
- The standalone StatusBar wrappers for React , Vue , svelte , Angular
were removed.
- every reference to the @uppy/status-bar package from the monorepo
(including in package.json and tsconfig.json files).
- fixed failing tests and removed redundant tests.

---------

Co-authored-by: Mikael Finstad <finstaden@gmail.com>
Co-authored-by: Merlijn Vos <merlijn@soverin.net>
2025-08-05 13:17:29 +02:00
Prakash
cb9673bc1e
uppy 5.0: remove stale plugins (#5834)
This PR removes `@uppy/store-redux` , `@uppy/redux-dev-tools` ,
`@uppy/progress-bar` , `@uppy/drag-drop` , `@uppy/file-input` ,
`@uppy/aws-s3-multipart`

- **Source Removal**  
Removed source Dirs of packages, including all source code, styles,
documentation, and build configurations.

- **Bundle & Exports**  
Removed related exports from `packages/uppy/src/bundle.ts` and
`index.ts`. Cleaned up dependencies from `uppy/package.json`.

- **Framework Cleanup**  
  Removed components and exports from:
  - `@uppy/react`
  - `@uppy/vue`
  - `@uppy/svelte`
  - `@uppy/angular`

- **Dependency Cleanup**  
Removed references across all `package.json`, `peerDependencies`,
`tsconfig.*.json`, and `turbo.json` files.

- **Example Updates**  
  - Updated Angular example and `private/dev/DragDrop.js`
  - Removed deprecated plugin usage
  - Cleaned example dependencies

- **Style Cleanup**  
Removed CSS imports from `packages/uppy/src/style.scss` and
`examples/angular/src/styles.css`. Fixed TypeScript project references.

- **Migration Guide**  
  Updated `.github/MIGRATION.md`
2025-07-28 10:30:50 +02:00
Merlijn Vos
78299475ae
Migrate from Eslint/Prettier/Stylelint to Biome (#5794) 2025-07-01 14:55:41 +02:00
Merlijn Vos
d408570373
From Babel to TS (#5792) 2025-06-30 16:12:26 +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
Merlijn Vos
229902eb17
@uppy/core: fix locale type for plugins (#5700)
Co-authored-by: Mikael Finstad <finstaden@gmail.com>
2025-03-31 12:04:29 +02:00
Merlijn Vos
568aa9143b
@uppy/react: pass getServerSnapshot to useSyncExternalStoreWithSelector (#5685) 2025-03-13 09:45:33 +01:00
Merlijn Vos
6e65cd8c51
Import types consistently from @uppy/core (#5589)
* Import types consistently from @uppy/core

* Add new eslint rule

* Clean up exports
2025-01-09 11:03:43 +01:00
Merlijn Vos
3e2aa9f3c8
Use .js(x) for all imports instead .ts(x) (#5573) 2025-01-06 13:29:55 +01:00
Merlijn Vos
13581742e5
@uppy/react: fix use-sync-external-store import (#5426) 2024-08-23 10:32:03 +02:00
Mikael Finstad
cd2d39ee05
@uppy/dashboard: propagate setOptions to StatusBar (#5260) 2024-07-15 12:02:37 +02:00
Antoine du Hamel
473e164e03
meta: fix React linter rules (#5317) 2024-07-09 15:24:20 +02:00
Merlijn Vos
903d435299
@uppy/react: introduce useUppyEvent (#5264) 2024-07-08 10:45:22 +02:00
Merlijn Vos
88d508f7bf
TS strict mode (#5258)
Co-authored-by: Antoine du Hamel <antoine@transloadit.com>
2024-06-20 16:54:10 +02:00
Merlijn Vos
f72aed7470
@uppy/react: remove react: prefix from id & allow id as a prop (#5228) 2024-06-10 15:43:25 +02:00
Murderlon
82a5999260
Merge branch 'main' into 4.x
* main: (22 commits)
  @uppy/xhr-upload: refactor to use `fetcher` (#5074)
  docs: use StackBlitz for all examples/issue template (#5125)
  Update yarn.lock
  Add svelte 5 as peer dep (#5122)
  Bump docker/setup-buildx-action from 2 to 3 (#5124)
  Bump actions/checkout from 3 to 4 (#5123)
  Remove JSX global type everywhere (#5117)
  Revert "@uppy/core: reference updated i18n in Restricter"
  @uppy/core: reference updated i18n in Restricter
  @uppy/utils: improve return type of `dataURItoFile` (#5112)
  @uppy/drop-target: change drop event type to DragEvent (#5107)
  @uppy/image-editor: fix label definitions (#5111)
  meta: bump Prettier version (#5114)
  @uppy/provider-views: bring back "loaded X files..." (#5097)
  @uppy/dashboard: fix type of trigger option (#5106)
  meta: fix linter
  @uppy/form: fix `submitOnSuccess` and `triggerUploadOnSubmit` combination (#5058)
  Bump docker/build-push-action from 3 to 5 (#5105)
  Bump akhileshns/heroku-deploy from 3.12.12 to 3.13.15 (#5102)
  Bump docker/login-action from 2 to 3 (#5101)
  ...
2024-04-29 15:56:33 +02:00
Merlijn Vos
57b5909611
Remove JSX global type everywhere (#5117)
* Remove JSX global type everywhere

* Add JSX to restricted globals

* Fix last instances of JSX global
2024-04-25 16:20:28 +02:00
Merlijn Vos
915a563da9
@uppy/react: remove useUppy & reintroduce useUppyState (#5059) 2024-04-17 12:05:48 +02:00
Antoine du Hamel
4be043a306
@uppy/react: remove prop-types dependency (#5031) 2024-03-27 13:18:11 +01:00
Antoine du Hamel
619f8ae4e8
@uppy/react: remove Wrapper.ts (#5032) 2024-03-27 11:20:08 +01:00
Antoine du Hamel
462e8c61bd
@uppy/react: refactor to TS (#5012) 2024-03-27 11:03:34 +01:00
Chris Grigg
01f2428b41
@uppy/dashboard: add new autoOpen option (#5001)
* Add autoOpenView option that defaults to meta

* <Dashboard/> - deprecate `autoOpenFileEditor`, use `autoOpen` instead

* tests - account for the case where `opts` are undefined

* Update packages/@uppy/dashboard/src/Dashboard.jsx

Co-authored-by: Merlijn Vos <merlijn@soverin.net>

* types - properly deprecate option `autoOpenFileEditor`

* everywhere - rename "fileEditor" => "imageEditor"

* <DashboardModal/> - refactor `props` passing

* types - copypaste types

* Dashboard.tsx - autoOpen: `false` => `null`

* change the default value too

---------

Co-authored-by: Evgenia Karunus <lakesare@gmail.com>
Co-authored-by: Merlijn Vos <merlijn@soverin.net>
2024-03-25 21:31:09 +04:00
Antoine du Hamel
89a2fc5d24
remove unnecessary 'use strict' directives (#4943) 2024-02-21 10:49:45 +01:00
Artur Paikin
440b8a9f9a
Revert "@uppy/react: add useUppyState (#4711)" (#4789)
This reverts commit 12e08ada02.
2023-11-12 02:03:55 +01:00
Merlijn Vos
12e08ada02
@uppy/react: add useUppyState (#4711) 2023-10-24 08:58:58 +02:00
Antoine du Hamel
34c78e9093
meta: run Prettier on existing files (#4713) 2023-09-29 11:11:28 +02:00
Merlijn Vos
f71df146fa
@uppy/react: allow id from props (#4570)
Fixes: https://github.com/transloadit/uppy/issues/4482
2023-07-13 12:14:16 +02:00
Antoine du Hamel
0a7eceac21
meta: fix all ESLint warnings and turn them into errors (#4398) 2023-04-04 15:54:13 +02:00
Merlijn Vos
81d482fdc9
@uppy/react: deprecate useUppy (#4223)
Co-authored-by: Mikael Finstad <finstaden@gmail.com>
2022-12-23 14:45:20 +01:00
Matt Jesuele
8a3665d28b
@uppy/react: useUppy: fix unmount on NextJS dev mode (#4062) 2022-08-30 15:44:23 +02:00
Merlijn Vos
9a213b59da
Fix all breaking todo comments for 3.0 (#3907)
- `@uppy/aws/s3-multipart`: remove `client` getter and setter.
  - reason: internal usage only
  - migrate: use exposed options only
- `@uppy/core`: remove `AggregateError` polyfill
  - reason: [should be polyfilled by the user](https://github.com/transloadit/uppy/pull/3532#discussion_r818602636)
  - migrate: install `AggregateError` polyfill or use `core-js`
- `@uppy/core`: remove `reset()` method
  - reason: it's a duplicate of `cancelAll`, but with a less intention revealing name
  - migrate: use `cancelAll`
- `@uppy/core`: remove backwards compatible exports (static properties on `Uppy`)
  - reason: transition to ESM
  - migrate: import the `Uppy` class by default and/or use named exports for everything else.
- `@uppy/react`: don't expose `validProps`
  - reason: internal only
  - migrate: do not depend on this
- `@uppy/store-redux`: remove backwards compatible exports (static properties on `ReduxStore`)
  - reason: transition to ESM
  - migrate: use named imports
- `@uppy/thumbnail-generator`: remove `rotateImage`, `protect`, and `canvasToBlob` from prototype.
  - reason: internal only
  - migrate: don't depend on this
2022-08-03 20:07:24 +02:00
Antoine du Hamel
dc7ad4b916
@uppy/status-bar: rename internal modules (#3929)
* rename `StatusBar` -> `StatusBarUI`

* rename `_StatusBar.jsx` -> `StatusBar.jsx`
2022-08-02 14:53:49 +02:00
Murderlon
d31cae30aa
Fix exports in propTypes.js to fix website build 2022-07-27 18:32:28 +02:00
Antoine du Hamel
a6029d0304 Merge stable branch 2022-06-09 21:15:10 +02:00
Tomasz Pęksa
2c05d51794
Reset uppy instance when React component is unmounted (#3814) 2022-06-07 18:14:37 +02:00