Button
Displays a button or a component that looks like a button.
import Button from '@dinui/react/button'
export default function ButtonVariantDemo() { return ( <div className="flex flex-wrap gap-6 justify-center"> <Button variant="filled">Button</Button>
<Button variant="outline">Button</Button>
<Button variant="ghost">Button</Button> </div> )}Colors
import Button from '@dinui/react/button'
const variants = ['filled', 'outline', 'ghost'] as constconst colors = ['default', 'brand', 'danger'] as const
export default function ButtonColors() { return ( <div className="flex flex-col gap-6 justify-center"> {variants.map((v) => ( <div key={v} className="flex items-center gap-6 justify-center"> {colors.map((c) => ( <Button key={v + c} variant={v} color={c}> Button </Button> ))} </div> ))} </div> )}Size
import Button from '@dinui/react/button'import { IconUserCircle } from '@tabler/icons-react'
export default function ButtonSizeDemo() { return ( <div className="flex flex-wrap gap-6 items-center"> <Button size="sm"> <Button.LeftIcon> <IconUserCircle /> </Button.LeftIcon> Button <Button.RightIcon> <IconUserCircle /> </Button.RightIcon> </Button>
<Button size="md"> <Button.LeftIcon /> Button </Button>
<Button size="lg"> Button <Button.RightIcon /> </Button> </div> )}Icon
import Button from '@dinui/react/button'import { Icon12Hours, IconLoader } from '@tabler/icons-react'
export default function ButtonSizesDemo() { return ( <div className="flex flex-wrap gap-6 items-center"> <Button size="sm" icon> <Button.Icon /> </Button>
<Button size="md" icon> <Button.Icon className="animate-spin"> <IconLoader /> </Button.Icon> </Button>
<Button size="lg" icon> <Button.Icon> <Icon12Hours /> </Button.Icon> </Button> </div> )}Disabled
import Button from '@dinui/react/button'
export default function ButtonDisabledDemo() { return ( <div className="flex flex-wrap gap-6"> <Button disabled variant="filled"> Button </Button>
<Button disabled variant="outline"> Button </Button>
<Button disabled variant="ghost"> Button </Button> </div> )}Installation
-
Follow Installation Guide
To enable DinUI functionality in your project, you will need to properly set up Tailwind and install the necessary dependencies. -
All done
You now can start using this component in your project.
-
Follow Installation Guide
To enable DinUI functionality in your project, you will need to properly set up Tailwind and install the necessary dependencies. -
Run the following command in your project
Terminal window npx @dinui/cli@latest add buttonTerminal window yarn dlx @dinui/cli@latest add buttonTerminal window pnpm dlx @dinui/cli@latest add buttonTerminal window bunx @dinui/cli@latest add button -
Update the import paths to match your project setup
-
All done
You now can start using this component in your project.
-
Follow Installation Guide
To enable DinUI functionality in your project, you will need to properly set up Tailwind and install the necessary dependencies. -
Install dependencies
Terminal window npm install @radix-ui/react-slot @tabler/icons-react tailwind-variants type-festTerminal window yarn add @radix-ui/react-slot @tabler/icons-react tailwind-variants type-festTerminal window pnpm add @radix-ui/react-slot @tabler/icons-react tailwind-variants type-festTerminal window bun add @radix-ui/react-slot @tabler/icons-react tailwind-variants type-fest -
Copy and paste the following code into your project
import { Slot } from '@radix-ui/react-slot'import { IconCircle } from '@tabler/icons-react'import { createContext, forwardRef, useContext } from 'react'import { tv, type VariantProps } from 'tailwind-variants'import type { Merge } from 'type-fest'const button = tv({slots: {root: ['inline-flex items-center justify-center transition','whitespace-nowrap cursor-pointer','disabled:pointer-events-none disabled:opacity-50',],leftIcon: null,rightIcon: null,icon: null,},variants: {variant: {filled: {},outline: {},ghost: {},},color: {default: {},brand: {},danger: {},},size: {xs: {root: ['h-7 px-2 rounded-md', 'text-xs font-medium'],leftIcon: 'size-3.5 -ml-0.5 mr-1',rightIcon: 'size-3.5 ml-1 -mr-0.5',icon: 'size-3.5',},sm: {root: ['h-8 px-3 rounded-md', 'text-xs font-medium'],leftIcon: 'size-4 -ml-0.5 mr-1',rightIcon: 'size-4 ml-1 -mr-0.5',icon: 'size-4',},md: {root: ['h-9 px-4 rounded-md', 'text-sm font-medium'],leftIcon: 'size-[1.125rem] -ml-1 mr-1.5',rightIcon: 'size-[1.125rem] ml-1.5 -mr-1',icon: 'size-[1.125rem]',},lg: {root: ['h-10 px-5 rounded-md', 'text-sm font-medium'],leftIcon: 'size-5 -ml-1.5 mr-2',rightIcon: 'size-5 ml-2 -mr-1.5',icon: 'size-5',},},icon: {true: null,},},compoundVariants: [{variant: 'filled',color: 'default',className: {root: 'bg-brand hover:bg-bg--hover',},},{variant: 'filled',color: 'brand',className: {root: 'bg-brand hover:bg-bg--hover',},},{variant: 'filled',color: 'danger',className: {root: 'bg-danger hover:bg-bg--hover',},},{variant: 'outline',color: 'default',className: {root: 'bg-bg--contrast hover:bg-bg--hover border text-fg-weak hover:text-fg-weak--hover',},},{variant: 'outline',color: 'brand',className: {root: 'bg-bg--contrast hover:bg-bg--hover border border-fg-brand text-fg-brand',},},{variant: 'outline',color: 'danger',className: {root: 'bg-bg--contrast hover:bg-danger--hover border border-fg-danger text-fg-danger',},},{variant: 'ghost',color: 'default',className: {root: 'hover:bg-bg--hover text-fg-weak hover:text-fg-weak--hover',},},{variant: 'ghost',color: 'brand',className: {root: 'hover:bg-bg--hover text-fg-brand hover:text-fg-brand--hover',},},{variant: 'ghost',color: 'danger',className: {root: 'hover:bg-bg--hover text-fg-danger hover:text-fg-danger--hover',},},{size: 'xs',icon: true,className: {root: 'w-7 px-0',},},{size: 'sm',icon: true,className: {root: 'w-8 px-0',},},{size: 'md',icon: true,className: {root: 'w-9 px-0',},},{size: 'lg',icon: true,className: {root: 'w-10 px-0',},},],defaultVariants: {variant: 'filled',color: 'default',size: 'md',},})const ButtonContext = createContext<VariantProps<typeof button>>(button.defaultVariants)const ButtonRoot = forwardRef<HTMLButtonElement,Merge<Merge<React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof button>>,{asChild?: boolean}>>(({ variant, color, size, icon, asChild = false, ...props }, ref) => {const variantOpts = { variant, size, icon, color }const { root } = button(variantOpts)const Comp = asChild ? Slot : 'button'return (<ButtonContext.Provider value={variantOpts}><Comp {...props} ref={ref} className={root({ className: props.className })} /></ButtonContext.Provider>)})ButtonRoot.displayName = 'ButtonRoot'const LeftIcon = forwardRef<React.ElementRef<typeof IconCircle>,React.ComponentPropsWithoutRef<typeof IconCircle>>((props, ref) => {const variantOpts = useContext(ButtonContext)const { leftIcon } = button(variantOpts)return (<Slot{...(props as React.HTMLAttributes<HTMLElement>)}ref={ref as React.ForwardedRef<HTMLElement>}className={leftIcon({ className: props.className })}>{props.children ?? <IconCircle />}</Slot>)})LeftIcon.displayName = 'LeftIcon'const RightIcon = forwardRef<React.ElementRef<typeof IconCircle>,React.ComponentPropsWithoutRef<typeof IconCircle>>((props, ref) => {const variantOpts = useContext(ButtonContext)const { rightIcon } = button(variantOpts)return (<Slot{...(props as React.HTMLAttributes<HTMLElement>)}ref={ref as React.ForwardedRef<HTMLElement>}className={rightIcon({ className: props.className })}>{props.children ?? <IconCircle />}</Slot>)})RightIcon.displayName = 'RightIcon'const Icon = forwardRef<React.ElementRef<typeof IconCircle>,React.ComponentPropsWithoutRef<typeof IconCircle>>((props, ref) => {const variantOpts = useContext(ButtonContext)const { icon } = button(variantOpts)return (<Slot{...(props as React.HTMLAttributes<HTMLElement>)}ref={ref as React.ForwardedRef<HTMLElement>}className={icon({ className: props.className })}>{props.children ?? <IconCircle />}</Slot>)})Icon.displayName = 'Icon'const Button = Object.assign(ButtonRoot, {LeftIcon,RightIcon,Icon,})export default Buttonexport { button } -
Update the import paths to match your project setup
-
All done
You now can start using this component in your project.