Skip to content

Variants API #5

@Arilas

Description

@Arilas

For most use-cases, people are using function interpolation to make it possible to design components based on props.

This can be transformed into declarative API as Variants.

What we should consider:

  • It should be possible to make some variants as required, without specifying the default value
  • It should be possible to make some variants optional and the developer should not write style for default value (e.g. type="flat" in the example doesn't have specified value)
  • It should work with boolean types (e.g. active: { true: 'classes', false: 'classes' } )
  • Should be easy to work with
  • Should support comments and Primitive Interpolations

The possible ways to implement this can be:

  1. Options object:
export interface ButtonProps {
  type?: 'rounded' | 'flat'
  variant?: 'filled' | 'outlined'
  // ...
}
export const Button = stail<ButtonProps>("button", {
  variants: {
    type: {
      rounded: 'rounded-full',
    },
    variant: {
      filled: 'bg-gray-400 text-white hover:bg-gray-300 active:bg-gray-200',
      outlined: 'bg-white border-gray-400 text-gray-400 hover:border-gray-300 active:border-gray-200'
    }
  },
  defaultProps: {
    type: 'rounded',
    variant: 'filled'
  }
})`px-4 py-2 text-xl font-bold`

<Button>Rounded filled</Button>
<Button variant="outlined">Rounded outlined</Button>
<Button type="flat" variant="outlined">Flat outlined</Button>
  1. Variant helper:
export interface ButtonProps {
  type?: 'rounded' | 'flat'
  variant?: 'filled' | 'outlined'
  // ...
}
export const Button = stail.button<ButtonProps>`
px-4 py-2 text-xl font-bold

${variant(
  "type",
  {
    rounded: 'rounded-full',
  },
  "rounded"
)}

${variant(
  "variant",
  {
    filled: 'bg-gray-400 text-white hover:bg-gray-300 active:bg-gray-200',
    outlined: 'bg-white border-gray-400 text-gray-400 hover:border-gray-300 active:border-gray-200'
  },
  "filled"
)}`

<Button>Rounded filled</Button>
<Button variant="outlined">Rounded outlined</Button>
<Button type="flat" variant="outlined">Flat outlined</Button>

As I can see the second option is more native and gives developers more freedom to design component

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions