uppy/packages/@uppy/components
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
..
src Fix various deps and peer deps in packages (#6030) 2025-10-28 09:55:21 +01:00
CHANGELOG.md [ci] release (#6029) 2025-10-28 10:15:14 +01:00
migrate.mjs @uppy/vue: support kebab-case props in generated components (#6125) 2026-01-19 09:59:42 +01:00
package.json build(deps): bump preact from 10.26.9 to 10.26.10 (#6123) 2026-01-08 12:00:59 +01:00
tsconfig.build.json
tsconfig.json
turbo.json Fix various deps and peer deps in packages (#6030) 2025-10-28 09:55:21 +01:00