Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: Add makeVariantStyles Function to Griffel #610

Open
dmytrokirpa opened this issue Oct 6, 2024 · 0 comments
Open

Proposal: Add makeVariantStyles Function to Griffel #610

dmytrokirpa opened this issue Oct 6, 2024 · 0 comments

Comments

@dmytrokirpa
Copy link

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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant