Button
Buttons are used to trigger actions.
'use client'
import { Button } from '@nerdfish/react/button'
export default function ButtonExample() {
return <Button>Button</Button>
}
Variants
'use client'
import { Button } from '@nerdfish/react/button'
export default function ButtonVariantsExample() {
return (
<div className="space-y-friends flex flex-col">
<Button variant="default">Default</Button>
<Button variant="accent">Nerdfish</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="destructive" onClick={() => {}}>
Danger
</Button>
<Button variant="success">Success</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="outline">Outline</Button>
<Button variant="link">Link</Button>
</div>
)
}
Disabled
'use client'
import { Button } from '@nerdfish/react/button'
export default function ButtonDisabledExample() {
return (
<div className="space-y-friends flex flex-col">
<Button disabled variant="default">
Default
</Button>
<Button disabled variant="accent">
Nerdfish
</Button>
<Button disabled variant="secondary">
Secondary
</Button>
<Button disabled variant="destructive">
Danger
</Button>
<Button disabled variant="success">
Success
</Button>
<Button disabled variant="ghost">
Ghost
</Button>
<Button disabled variant="outline">
Outline
</Button>
<Button disabled variant="link">
Link
</Button>
</div>
)
}
Sizes
'use client'
import { Button } from '@nerdfish/react/button'
import { ButtonGroup } from '@nerdfish/react/button-group'
import { Mail } from 'lucide-react'
export default function ButtonSizesExample() {
return (
<div className="gap-casual flex flex-col">
<div className="gap-best-friends flex flex-col">
<div>
<Button variant="accent" size="xs">
Extra Small
</Button>
</div>
<div>
<Button variant="accent" size="sm">
Small
</Button>
</div>
<div>
<Button variant="accent" size="md">
Medium
</Button>
</div>
<div>
<Button variant="accent" size="lg">
Large
</Button>
</div>
<div>
<Button variant="accent" size="xl">
Extra Large
</Button>
</div>
</div>
<div className="gap-best-friends flex flex-col">
<ButtonGroup>
<Button size="xs">Extra small</Button>
<Button size="xs" icon>
<Mail />
</Button>
</ButtonGroup>
<ButtonGroup>
<Button size="sm">Small</Button>
<Button size="sm" icon>
<Mail />
</Button>
</ButtonGroup>
<ButtonGroup>
<Button>Medium</Button>
<Button icon>
<Mail />
</Button>
</ButtonGroup>
<ButtonGroup>
<Button size="lg">Large</Button>
<Button size="lg" icon>
<Mail />
</Button>
</ButtonGroup>
<ButtonGroup>
<Button size="xl">Extra Large</Button>
<Button size="xl" icon>
<Mail />
</Button>
</ButtonGroup>
</div>
<div className="gap-best-friends flex flex-col">
<Button variant="accent" size="xs" icon>
<Mail />
</Button>
<Button variant="accent" size="sm" icon>
<Mail />
</Button>
<Button variant="accent" size="md" icon>
<Mail />
</Button>
<Button variant="accent" size="lg" icon>
<Mail />
</Button>
<Button variant="accent" size="xl" icon>
<Mail />
</Button>
</div>
</div>
)
}
With Icon
'use client'
import { Button } from '@nerdfish/react/button'
import { MailIcon } from 'lucide-react'
export default function ButtonWithIconExample() {
return (
<Button>
<MailIcon className="mr-best-friends size-4" /> Login with Email
</Button>
)
}
Loading
'use client'
import { Button } from '@nerdfish/react/button'
import { Loader2 } from 'lucide-react'
export default function ButtonLoadingExample() {
return (
<Button disabled>
<Loader2 className="mr-best-friends size-4 animate-spin" />
Please wait
</Button>
)
}
Icon only
'use client'
import { Button } from '@nerdfish/react/button'
import { Mail } from 'lucide-react'
export default function ButtonIconOnlyExample() {
return (
<Button icon>
<Mail className="size-4" />
<span className="sr-only">Mail</span>
</Button>
)
}
Render
'use client'
import { Button } from '@nerdfish/react/button'
export default function ButtonRenderExample() {
return <Button render={<a href="https://nerdfish.be">Nerdfish</a>} />
}
Button Group
'use client'
import { Button } from '@nerdfish/react/button'
import { ButtonGroup } from '@nerdfish/react/button-group'
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuRadioGroup,
DropdownMenuRadioItem,
DropdownMenuSeparator,
DropdownMenuSub,
DropdownMenuSubContent,
DropdownMenuSubTrigger,
DropdownMenuTrigger,
} from '@nerdfish/react/dropdown-menu'
import {
ArchiveIcon,
ArrowLeftIcon,
CalendarPlusIcon,
ClockIcon,
ListFilterPlusIcon,
MailCheckIcon,
MoreHorizontalIcon,
TagIcon,
Trash2Icon,
} from 'lucide-react'
import { useState } from 'react'
export default function ButtonGroupExample() {
const [label, setLabel] = useState('personal')
return (
<ButtonGroup className="gap-friends">
<ButtonGroup>
<Button variant="outline" icon aria-label="Go Back">
<ArrowLeftIcon />
</Button>
</ButtonGroup>
<ButtonGroup>
<Button variant="outline">Archive</Button>
<Button variant="outline">Report</Button>
</ButtonGroup>
<ButtonGroup>
<Button variant="outline">Snooze</Button>
<DropdownMenu>
<DropdownMenuTrigger
render={
<Button variant="outline" icon aria-label="More Options">
<MoreHorizontalIcon />
</Button>
}
/>
<DropdownMenuContent align="end" className="w-52">
<DropdownMenuGroup>
<DropdownMenuItem>
<MailCheckIcon />
Mark as Read
</DropdownMenuItem>
<DropdownMenuItem>
<ArchiveIcon />
Archive
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>
<ClockIcon />
Snooze
</DropdownMenuItem>
<DropdownMenuItem>
<CalendarPlusIcon />
Add to Calendar
</DropdownMenuItem>
<DropdownMenuItem>
<ListFilterPlusIcon />
Add to List
</DropdownMenuItem>
<DropdownMenuSub>
<DropdownMenuSubTrigger>
<TagIcon />
Label As...
</DropdownMenuSubTrigger>
<DropdownMenuSubContent>
<DropdownMenuRadioGroup
value={label}
onValueChange={setLabel}
>
<DropdownMenuRadioItem value="personal">
Personal
</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="work">
Work
</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="other">
Other
</DropdownMenuRadioItem>
</DropdownMenuRadioGroup>
</DropdownMenuSubContent>
</DropdownMenuSub>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem variant="destructive">
<Trash2Icon />
Trash
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
</ButtonGroup>
</ButtonGroup>
)
}
Button Group Use Case
'use client'
import { Button } from '@nerdfish/react/button'
import { ButtonGroup } from '@nerdfish/react/button-group'
import {
DropdownMenuGroup,
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@nerdfish/react/dropdown-menu'
import { ChevronDownIcon } from 'lucide-react'
import { useState } from 'react'
const descriptionsMap = {
merge:
'All commits from the source branch are added to the destination branch via a merge commit.',
squash:
'All commits from the source branch are added to the destination branch as a single commit.',
rebase:
'All commits from the source branch are added to the destination branch individually.',
}
const labelsMap = {
merge: 'Create a merge commit',
squash: 'Squash and merge',
rebase: 'Rebase and merge',
}
export default function ButtonGroupUseCase() {
const [selectedOption, setSelectedOption] =
useState<keyof typeof labelsMap>('merge')
return (
<ButtonGroup>
<Button variant="success">{labelsMap[selectedOption]}</Button>
<DropdownMenu>
<DropdownMenuTrigger
render={
<Button variant="success" icon>
<ChevronDownIcon className="size-4" />
</Button>
}
/>
<DropdownMenuContent className="max-w-75">
<DropdownMenuGroup>
{Object.entries(labelsMap).map(([key, label]) => {
const option = key as keyof typeof labelsMap
return (
<DropdownMenuItem
onSelect={() => setSelectedOption(option)}
key={key}
>
<div className="gap-best-friends flex flex-col">
<span className="font-bold">{label}</span>
<p className="text-sm">{descriptionsMap[option]}</p>
</div>
</DropdownMenuItem>
)
})}
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
</ButtonGroup>
)
}