sek-consulting / solid-ui

Beautifully designed components. Built with Kobalte & corvu. Styled with Tailwind CSS.
https://www.solid-ui.com
MIT License
674 stars 25 forks source link

A helper function you might find useful: `withProps` #107

Open jsimonrichard opened 3 weeks ago

jsimonrichard commented 3 weeks ago

This is not a PR because I don't know how I would integrate this into your project. But you might find this useful (I put it into my utils.tsx file):

import { Polymorphic } from '@kobalte/core/polymorphic';
import {
  Component,
  ComponentProps,
  ValidComponent,
  mergeProps,
} from 'solid-js';

export function withProps<T extends ValidComponent, ExtraProps extends {} = {}>(
  Comp: T,
  extra_props: ExtraProps,
) {
  return <U extends ValidComponent>(
    props: Omit<ComponentProps<T>, keyof ExtraProps> &
      Partial<ComponentProps<T>> & {
        as?: Component<ComponentProps<T> & ComponentProps<U>>;
      } & ComponentProps<U>,
  ) => {
    if (
      props.class &&
      'class' in extra_props &&
      typeof extra_props.class === 'string'
    ) {
      props.class = cn(props.class, extra_props.class);
    }
    const totalProps = mergeProps(props, extra_props);
    return <Polymorphic as={props.as ?? Comp} {...totalProps} />;
  };
}

Usage:

export const Root = withProps('div', {
  class: 'flex items-stretch text-left border rounded-md',
});

When using the CLI to copy in new components, it's definitely more important for the components to be extensible rather than succinct. But your users might appreciate a utility like this when trying to define their own components.

Edit: this might go better in @kobalte/utils, but the cn function is useful here.

sek-consulting commented 2 weeks ago

Thanks for the contribution :) I'm not sure how and if I want to include it but for now I'll save it for later.