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
Uh oh!
There was an error while loading. Please reload this page.
-
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