What is the supported method for dynamically creating elements.
Somethin akin to Solids <Dynamic> https://www.solidjs.com/docs/latest/api#dynamic
15 messages · Page 1 of 1 (latest)
What is the supported method for dynamically creating elements.
Somethin akin to Solids <Dynamic> https://www.solidjs.com/docs/latest/api#dynamic
After further investigation, this might be the answer: https://www.tzdesign.de/en/blog/qwik-component-polymorphism
Still welcoming any other input.
I used this pattern.
Hmm... even copy pasting the example doesn't work for me:
I'll try that
Actually, that won't work... I need to be able to define the name of a wrapping element.
here is another pattern that is now fixed https://github.com/BuilderIO/qwik/issues/4029
The real issue is at hand here is just the type and the linting error. What you're doing is functionally correct. I think if you just add a union type you should be good to go.
import type { FunctionComponent, 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 | FunctionComponent;
return (
<Component>
<Slot />
</Component>
);
}
);
export type ButtonProps<C extends keyof QwikIntrinsicElements> =
QwikIntrinsicElements[C] & {
as?: C;
};
note the | FunctionComponent after the as string. And also have to import the FunctionComponent type.
which is what that github issue was about, but the type was signal related.
Yeah, turns out if I limit the string type to something like "div", etc, then the issue goes away. Turns out it's actually correct, not all elements can take children.
Right, so if you have no idea, you have to type it so it could be either and trust the consumer of the component to pass in the right value.
the as string | FunctionComponent is really just getting rid of the linting error, not really making anything work.
I was also trying to see if I could make a mapped type that would just filter the keys down to allowed types.
This doesn't work:
type QwikIntrinsicElementsWithChildren = {[K in keyof QwikIntrinsicElements]: QwikIntrinsicElements[K] extends { children?: undefined; } ? never : QwikIntrinsicElements[K] };
This does:
type QwikIntrinsicElementsWithChildren = {[K in "div" | "span"]: QwikIntrinsicElements[K] extends { children?: undefined; } ? never : QwikIntrinsicElements[K] };
I thought filtering on children prop would be a nice generic way to go. But yeah, didn't work. I wonder what other than "children" needs to be there.
You can give it a default type in the component definition that exposes things specific to that html element. I haven't trying using a custom component as a default.
<C extends keyof QwikIntrinsicElements = 'button'>(props: ButtonProps<C>)