Qwik Polymorphism
Auch in Qwik braucht man machnmal komplexere Komponenten, die sowohl als Link als auch als Button oder welches Element auch immer gerendert werden müssen.
QwikIntrinsicElements#
Der Type QwikIntrinsicElements ist hier die Basis auf die du setzen solltest. Das Qwik-Team hat hier die HTMLAttributes erweitert.
Wie können jetzt deine Props aussehen? Wie der Titel schon vermuten lässt, kommen wir nicht um Generics herum.
Für meine Buttonkomponent sehen die Props so aus:
export type ButtonProps<C extends keyof QwikIntrinsicElements> =
QwikIntrinsicElements[C] & { as?: C;};
C ist dann die prop, die entscheiden, was für Props aus QwikIntrinsicElements verwendet werden.
Die Implementierung dafür ist dann insgesamt folgende:
import type { QwikIntrinsicElements } from '@builder.io/qwik';import { component$, Slot } from '@builder.io/qwik';
export default component$( <C extends keyof QwikIntrinsicElements>(props: ButtonProps<C>) => { const Component = (props.as ?? 'button') as string; return ( <Component> <Slot /> </Component> ); });
export type ButtonProps<C extends keyof QwikIntrinsicElements> = QwikIntrinsicElements[C] & { as?: C; };
Gern kannst du unter as?
einfach noch deine eigenen Props hinzufügen.
Casting als String#
const Component = (props.as ?? 'button') as string;
Leider scheint es noch kein sauberer Übertrag in JSX zu existieren. Ich habe relativ viel experimentiert und mit keyof QwikIntrinsicElements
etc. gearbeitet. Ich hatte erst mit any
gearbeitet, aber da viele von euch sicher Prettier und Lint nutzt, finde ich string hier etwas passender.
Viel einfacher als in React, wo man immer auch forwardRef
mit denken muss.
Viel Spaß mit Polymorphism