Skip to content

Proposal: Add makeVariantStyles Function to Griffel #610

Open

Description

Overview

I'd like to propose adding a new utility function makeVariantStyles to Griffel. This function would enable a variant-based styling approach similar to libraries like vanilla-extract and Panda CSS, allowing for more flexible and maintainable component styling.

Features

  • Create variant-based styles with a simple, declarative API
  • Support for compound variants
  • Default variants
  • Type-safe usage with TypeScript, including automatic prop type inference

Benefits

  1. Improved Developer Experience: Simplifies the process of creating and managing component variants.
  2. Type Safety: Leverages TypeScript for type-safe styling and prop usage.
  3. Performance: Utilizes memoization to minimize unnecessary style recalculations.
  4. Flexibility: Supports complex styling scenarios with compound variants and default variants.
  5. Familiarity: API design inspired by popular libraries, reducing learning curve for developers.

Example Usage

const useVariantStyles = makeVariantStyles({
  base: {
    borderRadius: '6px'
  },
  variants: {
    color: {
      neutral: { backgroundColor: 'whitesmoke' },
      brand: { backgroundColor: 'blueviolet' },
      accent: { backgroundColor: 'slateblue' }
    },
    size: {
      small: { padding: '12px' },
      medium: { padding: '16px' },
      large: { padding: '24px' }
    },
    rounded: {
      true: { borderRadius: '999px' }
    }
  },
  compoundVariants: [
    {
      variants: { color: 'neutral', size: 'large' },
      style: { backgroundColor: 'ghostwhite' }
    }
  ],
  defaultVariants: {
    color: 'accent',
    size: 'medium'
  }
});

type ButtonProps = VariantProps<typeof useVariantStyles>;

const Button: React.FC<ButtonProps> = (props) => {
  const variants = useVariantStyles();
  return <button className={variants(props)}>Click me</button>;
};

Demo

A working demo of this proposed functionality can be found on StackBlitz:

View makeVariantStyles Demo on StackBlitz

Similar Implementations in Other Libraries

To provide context and allow for comparison, here are links to similar implementations in other popular styling libraries:

The proposed implementation takes inspiration from these approaches while adapting to Griffel's unique architecture and capabilities. And it does not rely on Griffel's internal APIs, utilizing public API such as makeStyles and mergeClasses. Which allows multiple ways for integration - bake in directly into core, or create a standalone extension package.

I would greatly appreciate any feedback, suggestions, or concerns you might have about this proposal. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions