Replies: 2 comments 3 replies
-
you need to mix type, like this: import { JSX } from 'preact'
type ComponentProps = { /* your custom prop */ } & JSX.HTMLAttributes<HTMLButtonElement>
const MyComponent = (props: ComponentProps) => {
return <button {...props}>Hello World</button>
} |
Beta Was this translation helpful? Give feedback.
2 replies
-
Did the same thing using the source code from the Kobalte library (Solid.js), which is fantastic btw. There are some gotchas, like Preact's https://github.com/kobaltedev/kobalte/blob/main/packages/core/src/polymorphic/polymorphic.tsx // credits: https://github.com/kobaltedev/kobalte/blob/main/packages/utils/src/props.ts
import { ComponentProps, JSX } from 'preact';
/**
* Allows for extending a set of props (`Source`) by an overriding set of props (`Override`),
* ensuring that any duplicates are overridden by the overriding set of props.
*/
export type OverrideProps<Source = {}, Override = {}> = Omit<Source, keyof Override> & Override;
/**
* Allows for extending a set of `ComponentProps` by an overriding set of props,
* ensuring that any duplicates are overridden by the overriding set of props.
*/
export type OverrideComponentProps<T extends JSX.ElementType, P> = OverrideProps<ComponentProps<T>, P>; // credits: https://github.com/kobaltedev/kobalte/blob/main/packages/core/src/polymorphic/polymorphic.tsx
import { ComponentProps, JSX } from 'preact';
import { ForwardedRef, forwardRef } from 'preact/compat';
import { OverrideProps } from '~/utils/props.ts';
import { forwardRefType } from './utils.ts';
export type ElementOf<T> = T extends HTMLElement ? T : T extends keyof HTMLElementTagNameMap ? HTMLElementTagNameMap[T] : any;
/**
* Polymorphic attribute.
*/
export interface PolymorphicAttributes<T extends JSX.ElementType> {
as?: T | keyof JSX.IntrinsicElements;
}
/**
* Props used by a polymorphic component.
*/
export type PolymorphicProps<T extends JSX.ElementType, Props extends {} = {}> = OverrideProps<
ComponentProps<T>,
Props & PolymorphicAttributes<T>
>;
/**
* Helper type to get the exact props in Polymnorphic `as` callback.
*/
export type PolymorphicCallbackProps<CustomProps extends {}, Options extends {}, RenderProps extends {}> =
& Omit<CustomProps, keyof Options | keyof RenderProps>
& RenderProps;
/**
* A utility component that render its `as` prop.
*/
function Polymorphic<RenderProps>(
props: RenderProps & PolymorphicAttributes<JSX.ElementType>,
ref: ForwardedRef<HTMLElement>,
): JSX.Element {
const { as: Component, ...rest } = props;
if (!Component) {
throw new Error('Polymorphic is missing the required `as` prop.');
}
return <Component ref={ref} {...rest} />;
}
const _Polymorphic = (forwardRef as forwardRefType)(Polymorphic);
export { _Polymorphic as Polymorphic }; // Override forwardRef types so generics work.
declare function forwardRef<T, P = {}>(
render: (props: P, ref: React.Ref<T>) => React.ReactElement | null,
): (props: P & React.RefAttributes<T>) => React.ReactElement | null;
export type forwardRefType = typeof forwardRef; |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Hi,
I'm struggling to properly type a component in Preact. I want to pass the HTML tag the component should be rendered with as a string.
Here's some code to explain myself (and here's a playground on Stackblitz: https://stackblitz.com/edit/preact-tsx-starter-hbjjaq?file=App.tsx):
Beta Was this translation helpful? Give feedback.
All reactions