vuejs / babel-plugin-jsx

JSX for Vue 3
https://vue-jsx-explorer.netlify.app
MIT License
1.73k stars 141 forks source link

[Question] How to pass any attribute to the component #663

Open MellKam opened 1 year ago

MellKam commented 1 year ago

How can I pass any attribute to the component? Maybe something is wrong with my typescript configuratin, but I can't pass anything other then props that are provided by the component and a few common attributes like "style" as "key".

For example, if I try to pass the "src" value to a component, typescript gives the following error:

Type '{ class: string; src: string; }' is not assignable to type 'IntrinsicAttributes & { as?: AsTag | undefined; class?: unknown; readonly asChild?: boolean | undefined; key?: string | number | symbol | undefined; ref?: VNodeRef | undefined; ... 8 more ...; style?: unknown; }'.
  Property 'src' does not exist on type 'IntrinsicAttributes & { as?: AsTag | undefined; class?: unknown; readonly asChild?: boolean | undefined; key?: string | number | symbol | undefined; ref?: VNodeRef | undefined; ... 8 more 

When I use sfc template I can pass anything to the component, but with jsx I can't do that.

Here is my tsconfig.

{
    "compilerOptions": {
        "target": "ES2020",
        "useDefineForClassFields": true,
        "module": "ESNext",
        "lib": ["ES2020", "DOM", "DOM.Iterable"],
        "skipLibCheck": true,

        /* Bundler mode */
        "moduleResolution": "bundler",
        "allowImportingTsExtensions": true,
        "resolveJsonModule": true,
        "isolatedModules": true,
        "noEmit": true,
        "jsx": "preserve",
        "jsxImportSource": "vue",

        /* Linting */
        "strict": true,
        "noUnusedLocals": true,
        "noUnusedParameters": true,
        "noImplicitReturns": true,
        "noFallthroughCasesInSwitch": true,
        "noUncheckedIndexedAccess": true,
        "allowUnreachableCode": false,
        "noImplicitThis": true,
        "forceConsistentCasingInFileNames": true,
        "noImplicitAny": true,
        "paths": {
            "#/*": ["./src/*"],
            "#generated/*": ["./generated/*"]
        }
    },
    "include": [
        "src/**/*.ts",
        "src/**/*.d.ts",
        "src/**/*.tsx",
        "src/**/*.vue",
        "generated/**/*.ts",
        "generated/**/*.d.ts"
    ],
    "references": [{ "path": "./tsconfig.node.json" }]
}

Would appreciate any help 😄!

funny-family commented 1 year ago

@MellKam Code example to pass attrs to component: https://github.com/funny-family/vue3-ts-playground/blob/master/src/app/shared/components/text-field/text-field.component.ts#L24 https://github.com/funny-family/vue3-ts-playground/blob/master/src/app/components/not-found/not-found.component.tsx#L190

MellKam commented 1 year ago

@MellKam Code example to pass attrs to component: funny-family/vue3-ts-playground@master/src/app/shared/components/text-field/text-field.component.ts#L24 funny-family/vue3-ts-playground@master/src/app/components/not-found/not-found.component.tsx#L190

Thanks for the example, but in my case I have no control over the component.

I think I need to clarify the situation. I'm using the radix-vue library, which creates a component using Vue SFC. Since they are non-styled, I want to create a stylized wrapper, like shadcn-ui does. I decided to use JSX to do this, but I'm running into a situation where I can't pass the component anything other than the properties shown in the screenshot above. Basically no attributes.

Using the h() function, I can specify anything I want, since the type RawProps = VNodeProps & { .... } & Record<string, any>. So that's one I'm using for now.