HelpLogin
© 2022-2025 Spice AI, Inc.
SQL Query ReferenceDocsFAQSupport
PrivacyTerms
Status
Home
Datasets
Models
trunk
Edit on GitHub
Fork
/docs/website/src/components/atoms/button/button.tsx
1import * as React from 'react';
2import { Link, LinkProps } from '../link/link';
3import { cva, type VariantProps } from 'class-variance-authority';
4
5import { classNames } from '../../../lib/utils';
6
7type ButtonAnchorProps = Omit<
8 React.AnchorHTMLAttributes<HTMLAnchorElement>,
9 keyof React.ButtonHTMLAttributes<HTMLButtonElement>
10>;
11
12const buttonVariants = cva(
13 'rounded-xl font-semibold transition-all outline-none',
14 {
15 variants: {
16 variant: {
17 brand: 'bg-primary hover:bg-primary-600',
18 brandOutline:
19 'bg-primary hover:bg-neutral hover:text-neutral-foreground active:bg-neutral-400 active:shadow-none hover:shadow-button-hover',
20 primary: 'bg-alpha-900 hover:bg-primary',
21 secondary:
22 'bg-transparent hover:bg-alpha-150 hover:text-neutral-foreground active:bg-alpha-300 border border-alpha-150',
23 negative: 'bg-neutral hover:bg-primary',
24 tag: 'px-4 py-3 md:hover:bg-alpha-50 md:active:bg-alpha-100',
25 tagSmall:
26 'bg-alpha-100 rounded-sm md:hover:bg-alpha-150 active:bg-alpha-200 text-xs leading-6 text-alpha-700',
27 },
28 size: {
29 sm: 'px-3 py-2 text-base',
30 md: 'px-4 py-3 text-base',
31 lg: 'px-8 py-4 text-lg',
32 },
33 },
34 defaultVariants: {
35 variant: 'primary',
36 size: 'md',
37 },
38 compoundVariants: [
39 {
40 variant: ['brand', 'primary', 'negative'],
41 className:
42 'active:bg-red-700 hover:text-primary-foreground hover:shadow-button-hover active:shadow-none',
43 },
44 {
45 variant: ['brand', 'brandOutline', 'primary'],
46 className: 'text-primary-foreground',
47 },
48 {
49 variant: ['secondary', 'negative'],
50 className: 'text-neutral-foreground',
51 },
52 {
53 variant: ['tagSmall'],
54 className: 'text-sm px-2 py-0.5',
55 },
56 ],
57 }
58);
59
60export interface ButtonProps
61 extends Omit<
62 React.ButtonHTMLAttributes<HTMLButtonElement>,
63 keyof ButtonAnchorProps
64 >,
65 ButtonAnchorProps,
66 VariantProps<typeof buttonVariants> {
67 href?: string;
68 ref?: React.Ref<HTMLButtonElement & HTMLAnchorElement>;
69}
70
71
72const Button =
73React.forwardRef<HTMLButtonElement, ButtonProps>(
74({
75 className,
76 variant,
77 size,
78 href,
79 ...props
80}, ref) => {
81 const classes = classNames(
82 'inline-block',
83 buttonVariants({ variant, size, className })
84 );
85
86 if (href) {
87 return (
88 <Link className={classes} {...props as any} href={href}>
89 {props.children}
90 </Link>
91 );
92 }
93
94 return <button className={classes} {...props} {...(ref ? { ref } : {})} />;
95});
96
97Button.displayName = 'Button';
98
99export { Button, buttonVariants };
100
1import * as React from 'react';
2import { Link, LinkProps } from '../link/link';
3import { cva, type VariantProps } from 'class-variance-authority';
4
5import { classNames } from '../../../lib/utils';
6
7type ButtonAnchorProps = Omit<
8 React.AnchorHTMLAttributes<HTMLAnchorElement>,
9 keyof React.ButtonHTMLAttributes<HTMLButtonElement>
10>;
11
12const buttonVariants = cva(
13 'rounded-xl font-semibold transition-all outline-none',
14 {
15 variants: {
16 variant: {
17 brand: 'bg-primary hover:bg-primary-600',
18 brandOutline:
19 'bg-primary hover:bg-neutral hover:text-neutral-foreground active:bg-neutral-400 active:shadow-none hover:shadow-button-hover',
20 primary: 'bg-alpha-900 hover:bg-primary',
21 secondary:
22 'bg-transparent hover:bg-alpha-150 hover:text-neutral-foreground active:bg-alpha-300 border border-alpha-150',
23 negative: 'bg-neutral hover:bg-primary',
24 tag: 'px-4 py-3 md:hover:bg-alpha-50 md:active:bg-alpha-100',
25 tagSmall:
26 'bg-alpha-100 rounded-sm md:hover:bg-alpha-150 active:bg-alpha-200 text-xs leading-6 text-alpha-700',
27 },
28 size: {
29 sm: 'px-3 py-2 text-base',
30 md: 'px-4 py-3 text-base',
31 lg: 'px-8 py-4 text-lg',
32 },
33 },
34 defaultVariants: {
35 variant: 'primary',
36 size: 'md',
37 },
38 compoundVariants: [
39 {
40 variant: ['brand', 'primary', 'negative'],
41 className:
42 'active:bg-red-700 hover:text-primary-foreground hover:shadow-button-hover active:shadow-none',
43 },
44 {
45 variant: ['brand', 'brandOutline', 'primary'],
46 className: 'text-primary-foreground',
47 },
48 {
49 variant: ['secondary', 'negative'],
50 className: 'text-neutral-foreground',
51 },
52 {
53 variant: ['tagSmall'],
54 className: 'text-sm px-2 py-0.5',
55 },
56 ],
57 }
58);
59
60export interface ButtonProps
61 extends Omit<
62 React.ButtonHTMLAttributes<HTMLButtonElement>,
63 keyof ButtonAnchorProps
64 >,
65 ButtonAnchorProps,
66 VariantProps<typeof buttonVariants> {
67 href?: string;
68 ref?: React.Ref<HTMLButtonElement & HTMLAnchorElement>;
69}
70
71
72const Button =
73React.forwardRef<HTMLButtonElement, ButtonProps>(
74({
75 className,
76 variant,
77 size,
78 href,
79 ...props
80}, ref) => {
81 const classes = classNames(
82 'inline-block',
83 buttonVariants({ variant, size, className })
84 );
85
86 if (href) {
87 return (
88 <Link className={classes} {...props as any} href={href}>
89 {props.children}
90 </Link>
91 );
92 }
93
94 return <button className={classes} {...props} {...(ref ? { ref } : {})} />;
95});
96
97Button.displayName = 'Button';
98
99export { Button, buttonVariants };
100