-=Camille=-
-=Camille=-
SSolidJS
Created by -=Camille=- on 5/10/2024 in #support
Component that can render a different tag depending on prop?
I want to make a title that renders a different component depending on the as props you give it. I've written the following component, using a Switch to render the correct component. I am not sure if this is the best way to accomplish what I want. What are your opinions on the way I should have done this? Is this good practice, or is there a cleaner way? Thank you very much for your help and your time! 🙏
import { JSXElement, Match, Switch } from 'solid-js';

import { TextColour } from './types/TextColour';

type TitleProps = {
/**
* The heading level of the title. Defaults to 'h1'.
*/
as?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
colour?: TextColour;
children: JSXElement;
variant?: 's' | 'm' | 'l' | 'xl';
};

/**
* Renders a title component based on the specified heading level.
* Defaults to 'h1' heading level, 'black' colour, and 'm' variant size.
*
* @example
* <Title as="h2" colour="dark-brown" variant="l">My Title</Title>
*/
const Title = (props: TitleProps) => {
const getClasslist = () => {
const classes: Record<string, boolean> = {};
classes[`title--${props.variant ?? 'm'}`] = true;
classes[`title--${props.colour ?? TextColour.BLACK}`] = true;
return classes;
};

return (
<Switch fallback={<h1 classList={getClasslist()}>{props.children}</h1>}>
<Match when={props.as === 'h2'}>
<h2 classList={getClasslist()}>{props.children}</h2>
</Match>
<Match when={props.as === 'h3'}>
<h3 classList={getClasslist()}>{props.children}</h3>
</Match>
<Match when={props.as === 'h4'}>
<h4 classList={getClasslist()}>{props.children}</h4>
</Match>
<Match when={props.as === 'h5'}>
<h5 classList={getClasslist()}>{props.children}</h5>
</Match>
<Match when={props.as === 'h6'}>
<h6 classList={getClasslist()}>{props.children}</h6>
</Match>
</Switch>
);
};

export default Title;
import { JSXElement, Match, Switch } from 'solid-js';

import { TextColour } from './types/TextColour';

type TitleProps = {
/**
* The heading level of the title. Defaults to 'h1'.
*/
as?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
colour?: TextColour;
children: JSXElement;
variant?: 's' | 'm' | 'l' | 'xl';
};

/**
* Renders a title component based on the specified heading level.
* Defaults to 'h1' heading level, 'black' colour, and 'm' variant size.
*
* @example
* <Title as="h2" colour="dark-brown" variant="l">My Title</Title>
*/
const Title = (props: TitleProps) => {
const getClasslist = () => {
const classes: Record<string, boolean> = {};
classes[`title--${props.variant ?? 'm'}`] = true;
classes[`title--${props.colour ?? TextColour.BLACK}`] = true;
return classes;
};

return (
<Switch fallback={<h1 classList={getClasslist()}>{props.children}</h1>}>
<Match when={props.as === 'h2'}>
<h2 classList={getClasslist()}>{props.children}</h2>
</Match>
<Match when={props.as === 'h3'}>
<h3 classList={getClasslist()}>{props.children}</h3>
</Match>
<Match when={props.as === 'h4'}>
<h4 classList={getClasslist()}>{props.children}</h4>
</Match>
<Match when={props.as === 'h5'}>
<h5 classList={getClasslist()}>{props.children}</h5>
</Match>
<Match when={props.as === 'h6'}>
<h6 classList={getClasslist()}>{props.children}</h6>
</Match>
</Switch>
);
};

export default Title;
14 replies