Skip to content

Commit

Permalink
Implement button with vanilla-extract
Browse files Browse the repository at this point in the history
  • Loading branch information
majakomel committed Feb 28, 2024
1 parent 6754293 commit 2c18f8b
Show file tree
Hide file tree
Showing 7 changed files with 276 additions and 4 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"@styled-system/should-forward-prop": "^5.1.5",
"@vanilla-extract/css": "^1.14.1",
"@vanilla-extract/recipes": "^0.5.1",
"@vanilla-extract/sprinkles": "^1.6.1",
"react-select": "^5.8.0",
"styled-system": "^5.1.5"
},
Expand Down
142 changes: 142 additions & 0 deletions src/components/ButtonVE.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import { createGlobalTheme } from '@vanilla-extract/css'
import { recipe } from '@vanilla-extract/recipes'
import { sprinkles } from './ButtonVESprinkles.css'

export const vars = createGlobalTheme(':root', {
color: {
blue: {
'100': '#c9e8ff',
'200': '#8dd5f8',
'300': '#5db8fe',
'400': '#37a6ed',
'500': '#0588cb',
'600': '#0f77b8',
'700': '#056aa6',
'800': '#005f9c',
'900': '#005a99',
},
},
fontSize: {
sm: { fontSize: '0.875rem', lineHeight: '1.25rem' },
},
space: {
sm: '0.5rem',
},
})

export const button = recipe({
base: {
display: 'flex',
justifyItems: 'center',
alignItems: 'center',
borderRadius: 999,
cursor: 'pointer',
fontFamily: 'inherit',
// display: 'inline-block',
textTransform: 'capitalize',
// textAlign: 'center',
letterSpacing: '0.5px',
// verticalAlign: 'middle',
// Gets rid of tap active state
WebkitTapHighlightColor: 'transparent',
transition: '.2s ease-out',
outline: 0,
borderWidth: '2px',
borderStyle: 'solid',
':focus-visible': {
transition: 'none',
outline: '2px solid',
outlineColor: vars.color.blue[500],
outlineOffset: '1px',
},
},
variants: {
variant: {
primary: {
background: vars.color.blue[500],
color: 'white',
borderColor: vars.color.blue[500],
':hover': {
background: vars.color.blue[900],
borderColor: vars.color.blue[900],
},
},
dark: {
background: 'black',
borderColor: 'black',
color: 'white',
':hover': {
background: 'black',
borderColor: 'black',
},
},
},
size: {
s: [{ padding: '0.25rem 1rem' }, sprinkles({ textStyle: 'sm' })],
m: [{ padding: '0.5rem 1.5rem' }, sprinkles({ textStyle: 'md' })],
l: [{ padding: '0.5rem 2rem' }, sprinkles({ textStyle: 'xxl' })],
xl: [{ padding: '0.875rem 4rem' }, sprinkles({ textStyle: 'xxl' })],
},
hollow: {
true: { background: 'transparent' },
},
},
defaultVariants: {
size: 'm',
hollow: false,
variant: 'primary',
},
compoundVariants: [
{
variants: {
variant: 'primary',
hollow: true,
},
style: {
background: 'transparent',
color: vars.color.blue[500],
':hover': {
background: 'transparent',
borderColor: vars.color.blue[900],
color: vars.color.blue[900],
},
},
},
],
})

// export const storybookButton = style({
// fontFamily: 'Nunito Sans , Helvetica Neue , Helvetica , Arial , sans-serif',
// fontWeight: '700',
// border: '0',
// borderRadius: '3em',
// cursor: 'pointer',
// display: 'inline-block',
// lineHeight: '1',
// });

// export const storybookButtonLarge = style({
// fontSize: '16px',
// padding: '12px 24px',
// });

// export const storybookButtonMedium = style({
// fontSize: '14px',
// padding: '11px 20px',
// });

// export const storybookButtonPrimary = style({
// color: 'white',
// backgroundColor: '#1ea7fd',
// });

// export const storybookButtonSecondary = style({
// color: '#333',
// backgroundColor: 'transparent',
// boxShadow: 'rgba(0,0,0,0.15) 0px 0px 0px 1px inset',
// });

// export const storybookButtonSmall = style({
// fontSize: '12px',
// padding: '10px 16px',
// });
56 changes: 56 additions & 0 deletions src/components/ButtonVE.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React, { forwardRef } from 'react'
import { button } from './ButtonVE.css'
import { sprinkles } from './ButtonVESprinkles.css'

type Size = 's' | 'm' | 'l' | 'xl'
type Variant = 'primary' | 'dark'

console.log(' sprinkles', sprinkles({ textStyle: 'sm' }))

export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
disabled?: boolean
inverted?: boolean
hollow?: boolean
variant?: Variant
size?: Size
startIcon?: React.ReactNode
endIcon?: React.ReactNode
}

const Button = forwardRef(
(
{
hollow = false,
inverted = false,
disabled = false,
variant = 'primary',
size = 'm',
type = 'button',
children,
startIcon,
endIcon,
...rest
}: ButtonProps,
ref,
) => {
return (
<button
className={button({
variant,
size,
hollow,
})}
type={type}
{...ref}
{...rest}
>
{startIcon && <span className="icon">{startIcon}</span>}
{children}
{endIcon && <span className="icon">{endIcon}</span>}
</button>
)
},
)

export default Button
17 changes: 17 additions & 0 deletions src/components/ButtonVESprinkles.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { createSprinkles, defineProperties } from '@vanilla-extract/sprinkles'

const properties = defineProperties({
properties: {
textStyle: {
sm: { fontSize: '0.875rem', lineHeight: '1.25rem' },
md: { fontSize: '1rem', lineHeight: '1.5rem' },
lg: { fontSize: '1.125rem', lineHeight: '1.75rem' },
xl: { fontSize: '1.25rem', lineHeight: '1.75rem' },
xxl: { fontSize: '1.5rem', lineHeight: '2rem' },
},
},
})

export const sprinkles = createSprinkles(properties)

export type Sprinkles = Parameters<typeof sprinkles>[0]
51 changes: 51 additions & 0 deletions stories/ButtonVE.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Meta, StoryObj } from '@storybook/react'
import React from 'react'
import { BsTwitter } from 'react-icons/bs'
import Box from '../src/components/Box'
import Button from '../src/components/ButtonVE'

const meta = {
title: 'Components/ButtonVE',
component: Button,
tags: ['autodocs'],
argTypes: {
onClick: { action: 'clicked' },
hollow: { control: 'boolean' },
disabled: { control: 'boolean' },
inverted: { control: 'boolean' },
},
} satisfies Meta<typeof Button>

export default meta
type Story = StoryObj<typeof meta>

export const Primary: Story = {
args: {
children: 'Button',
},
}

export const ColorVariant: Story = {
args: {
variant: 'dark',
children: 'Button',
size: 's',
endIcon: <BsTwitter />,
},
}

export const Hollow: Story = {
args: {
hollow: true,
size: 'l',
children: 'Button',
},
}

export const LongButton = () => {
return (
<Box width="300px">
<Button>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</Button>
</Box>
)
}
8 changes: 4 additions & 4 deletions vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin';
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';
import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin'
import react from '@vitejs/plugin-react'
import { defineConfig } from 'vite'

// https://vitejs.dev/config/
export default defineConfig({
plugins: [react(), vanillaExtractPlugin()],
});
})
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3811,6 +3811,11 @@
resolved "https://registry.yarnpkg.com/@vanilla-extract/recipes/-/recipes-0.5.1.tgz#617d1a0375af60835341770397810317d2f61998"
integrity sha512-7dCuBgPQQ/89siQ0w2lkfjgkmToPUUDzFlHf5DRmt9ykiiycfA52tmPJ2RI/mr7jXi7U/vEN2aGP9QJSXEpGlA==

"@vanilla-extract/sprinkles@^1.6.1":
version "1.6.1"
resolved "https://registry.yarnpkg.com/@vanilla-extract/sprinkles/-/sprinkles-1.6.1.tgz#2c8a832757a0d8104dc6bd5d961db2c70d1dbdcb"
integrity sha512-N/RGKwGAAidBupZ436RpuweRQHEFGU+mvAqBo8PRMAjJEmHoPDttV8RObaMLrJHWLqvX+XUMinHUnD0hFRQISw==

"@vanilla-extract/vite-plugin@^4.0.4":
version "4.0.4"
resolved "https://registry.yarnpkg.com/@vanilla-extract/vite-plugin/-/vite-plugin-4.0.4.tgz#8975d1e584e7bb8bbc241d31d49db3b134328627"
Expand Down

0 comments on commit 2c18f8b

Please sign in to comment.