Skip to content

Instantly share code, notes, and snippets.

@mattmccray
Last active January 27, 2022 03:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mattmccray/a2c3e02c8219d12dcf471231993cef29 to your computer and use it in GitHub Desktop.
Save mattmccray/a2c3e02c8219d12dcf471231993cef29 to your computer and use it in GitHub Desktop.
Simple Component wrapper for use with SolidJS and ./css.ts
import { createMemo, JSX, splitProps } from "solid-js"
import { Dynamic } from 'solid-js/web'
type CssComponent<T extends keyof JSX.IntrinsicElements> = (props: JSX.IntrinsicElements[T]) => JSX.Element
export function component(styles: string): (props: JSX.IntrinsicElements['div']) => JSX.Element
export function component<T extends keyof JSX.IntrinsicElements>(tag: T | string | CssComponent<any>, styles: string): (props: JSX.IntrinsicElements[T]) => JSX.Element
export function component<T extends keyof JSX.IntrinsicElements>(tag?: string | T | CssComponent<any>, styles?: string): CssComponent<any> {
let extraClassNames = ''
if (!styles) {
if (typeof tag !== 'string') throw new Error("No styles provided")
styles = tag
tag = 'div'
}
if (typeof tag === 'string' && tag.includes('.')) {
const parts = tag.split('.')
tag = parts.shift()
extraClassNames = parts.join(' ')
}
return (props: any) => {
const [localProps, forwardProps] = splitProps(props, ["className", "children"]);
const dynamicClassname = createMemo(() => `${extraClassNames} ${styles} ${localProps.className ?? ''}`)
return <Dynamic component={tag} {...forwardProps} className={dynamicClassname()}>{localProps.children}</Dynamic>
}
}
const Simple = component(css`
& { color: green; }
`)
const Other = component('article', css`
& { color: black; }
`)
const MiniButton = component('button.btn-mini', css`
& { color: red; }
`)
const LargeButon = component(MiniButton, css`
& { color: dodgerblue; }
`)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment