uppy/packages/@uppy
Merlijn Vos fa23832f6a
@uppy/vue: support kebab-case props in generated components (#6125)
## Summary

- Fix Vue components to work with kebab-case props (`:edit-file` instead
of `:editFile`)
- Update `migrate.mjs` to parse prop names from TypeScript source files
and generate explicit `props` arrays

## Problem

The generated Vue components didn't work correctly with Vue's standard
kebab-case prop convention:

```vue
<!-- This didn't work -->
<FilesList :edit-file="handleEdit" />

<!-- Only this worked (non-standard) -->
<FilesList :editFile="handleEdit" />
```

## Root Cause

The original Vue template used `attrs` to pass props to Preact:

```ts
setup(props, { attrs }) {
  preactRender(preactH(PreactComponent, {
    ...(attrs as Props),  // attrs preserves kebab-case!
    ctx,
  }), container)
}
```

When using `:edit-file` in a Vue template, Vue passes
`attrs['edit-file']` (kebab-case preserved), but Preact expects
`editFile` (camelCase).

## Solution

Generate Vue components with explicit `props` declarations:

```ts
defineComponent({
  props: ['editFile', 'columns', 'imageThumbnail'],
  setup(props) {
    preactRender(preactH(PreactComponent, {
      ...props,  // Vue already converted kebab → camelCase
      ctx,
    }), container)
  }
})
```

When Vue components declare their props, Vue automatically converts
kebab-case template usage to camelCase in the `props` object. This is
standard Vue behavior.

## Why Simpler Alternatives Don't Work

### "Just use `props` instead of `attrs`"

Without a `props` declaration, Vue doesn't know which attributes are
props. The `props` object will be empty and everything goes to `attrs`:

```ts
// Without props declaration
defineComponent({
  setup(props, { attrs }) {
    // props = {}  (empty!)
    // attrs = { 'edit-file': fn }  (kebab-case preserved)
  }
})
```

### "Accept all props dynamically"

Vue doesn't have a "accept all props and convert casing" option. You
must explicitly declare which props you expect for Vue to handle the
conversion.

### "Just document to use camelCase"

This works but violates Vue conventions. Every Vue developer expects
`:edit-file` to work.

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Prakash <qxprakash@gmail.com>
2026-01-19 09:59:42 +01:00
..
angular
audio
aws-s3
box
companion
companion-client
components @uppy/vue: support kebab-case props in generated components (#6125) 2026-01-19 09:59:42 +01:00
compressor
core
dashboard
drag-drop
drop-target
dropbox
facebook
form
golden-retriever
google-drive
google-drive-picker
google-photos-picker
image-editor
image-generator
instagram
locales Update the cs dropPaste translation keys to match en locale (#6135) 2026-01-16 10:53:26 +01:00
onedrive
provider-views
react
remote-sources
screen-capture
status-bar
store-default
svelte build(deps-dev): bump @sveltejs/kit from 2.20.7 to 2.49.5 (#6143) 2026-01-16 10:46:30 +01:00
thumbnail-generator
transloadit
tus
unsplash
url
utils
vue @uppy/vue: support kebab-case props in generated components (#6125) 2026-01-19 09:59:42 +01:00
webcam
webdav
xhr-upload
zoom