Skip to content

Instantly share code, notes, and snippets.

@vojtaholik
Created June 26, 2023 07:53
Show Gist options
  • Save vojtaholik/4abf91150ccc1654dde705492e41859c to your computer and use it in GitHub Desktop.
Save vojtaholik/4abf91150ccc1654dde705492e41859c to your computer and use it in GitHub Desktop.
import {Button} from '@package/ui/button'
import {ThemeProvider} from '@package/ui/use-theme'
import {appUniqueTheme} from './theme'
const Page = () => {
return (
<ThemeProvider theme={appUniqueTheme} />
<Button />
</ThemeProvider>
)
}
export default Page
import {cva} from 'class-variance-authority'
export const appUniqueTheme = {
variants: {
button: cva(
'relative inline-flex items-center justify-center rounded-md text-base font-medium transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background',
{
variants: {
variant: {
default: 'bg-primary text-primary-foreground',
destructive:
'bg-destructive text-destructive-foreground hover:bg-destructive/90',
outline:
'border border-input hover:bg-accent hover:text-accent-foreground',
secondary:
'bg-secondary text-secondary-foreground hover:bg-secondary/80',
ghost: 'hover:bg-accent hover:text-accent-foreground',
link: 'underline-offset-4 hover:underline text-primary',
},
size: {
default: 'h-10 py-2 px-4',
sm: 'h-9 px-3 rounded-md',
lg: 'h-12 px-8 rounded-md',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
},
),
input: cva(''),
label: cva(''),
},
}
import * as React from 'react'
import {Slot} from '@radix-ui/react-slot'
import {cva, type VariantProps} from 'class-variance-authority'
import {cn} from './utils'
import {useTheme} from '../hooks/use-theme'
const defaultButtonVariants = cva(
'relative inline-flex items-center justify-center rounded-md text-base font-medium transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background',
{
variants: {
variant: {
default: 'bg-primary text-primary-foreground',
destructive:
'bg-destructive text-destructive-foreground hover:bg-destructive/90',
outline:
'border border-input hover:bg-accent hover:text-accent-foreground',
secondary:
'bg-secondary text-secondary-foreground hover:bg-secondary/80',
ghost: 'hover:bg-accent hover:text-accent-foreground',
link: 'underline-offset-4 hover:underline text-primary',
},
size: {
default: 'h-10 py-2 px-4',
sm: 'h-9 px-3 rounded-md',
lg: 'h-12 px-8 rounded-md',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
},
)
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof defaultButtonVariants> {
asChild?: boolean
}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({className, variant, size, asChild = false, ...props}, ref) => {
const Comp = asChild ? Slot : 'button'
const {variants} = useTheme()
return (
<Comp
data-sr-button=""
className={cn(
variants.button({variant, size, className}),
defaultButtonVariants({variant, size, className}),
)}
ref={ref}
{...props}
/>
)
},
)
Button.displayName = 'Button'
export {Button, defaultButtonVariants}
'use client'
import * as React from 'react'
import {type VariantProps, type CxReturn} from 'class-variance-authority'
import {type ClassProp} from 'class-variance-authority/dist/types'
import {defaultButtonVariants} from './button'
export const DEFAULT_THEME: ThemeContextType = {
variants: {
button: defaultButtonVariants,
// ...
},
}
type ThemeContextType = {
variants: {
button: (
props: VariantProps<typeof defaultButtonVariants> & ClassProp,
) => CxReturn
}
}
export const ThemeContext = React.createContext({} as ThemeContextType)
type ThemeProviderProps = {
theme: ThemeContextType
children: React.ReactNode
}
export const ThemeProvider: React.FC<ThemeProviderProps> = ({
theme,
children,
}) => {
const context = {
...theme,
}
return (
<ThemeContext.Provider value={context}>{children}</ThemeContext.Provider>
)
}
export const useTheme = () => {
const themeContext = React.useContext(ThemeContext)
return themeContext
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment