Skip to content

Commit 09abccd

Browse files
committed
feat: add button-group component
1 parent 9d1114b commit 09abccd

File tree

5 files changed

+103
-1
lines changed

5 files changed

+103
-1
lines changed

packages/ui-variants/src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@ export * from './shared';
33
export * from './types';
44

55
export * from './variants/button';
6-
6+
export * from './variants/button-group';
77
export * from './variants/card';
8+
export * from './variants/tabs';
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { tv } from 'tailwind-variants';
2+
3+
export const buttonGroupVariants = tv({
4+
base: `*:relative focus-visible:*:z-2 *:not-first:not-last:rounded-none`,
5+
6+
// eslint-disable-next-line sort/object-properties
7+
variants: {
8+
orientation: {
9+
horizontal: `inline-flex *:not-last:border-r-0 *:first:rounded-r-none *:last:rounded-l-none`,
10+
vertical: `flex flex-col *:not-last:border-b-0 *:first:rounded-b-none *:last:rounded-t-none`
11+
}
12+
},
13+
defaultVariants: {
14+
orientation: 'horizontal'
15+
}
16+
});
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export * from './source/Button';
2+
export * from './source/ButtonGroup';
3+
4+
export * from './type';
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { Slot } from '@radix-ui/react-slot';
2+
import { buttonVariants, cn } from '@skyroc-ui/variants';
3+
import { Loader2 } from 'lucide-react';
4+
import { forwardRef } from 'react';
5+
6+
import type { ButtonProps } from '../type';
7+
8+
export const Button = forwardRef<HTMLButtonElement, ButtonProps>((props, ref) => {
9+
const {
10+
asChild = false,
11+
asIconButton,
12+
children,
13+
className,
14+
color = asIconButton ? 'carbon' : 'primary',
15+
disabled,
16+
fitContent,
17+
leading,
18+
loading,
19+
shadow,
20+
shape = asIconButton ? 'square' : 'auto',
21+
size,
22+
trailing,
23+
variant = asIconButton ? 'ghost' : 'solid',
24+
...rest
25+
} = props;
26+
27+
const isDisabled = loading || disabled;
28+
29+
const Comp = asChild ? Slot : 'button';
30+
31+
const mergedCls = cn(buttonVariants({ color, fitContent, shadow, shape, size, variant }), className);
32+
33+
if (asChild) {
34+
return (
35+
<Comp
36+
className={mergedCls}
37+
disabled={isDisabled}
38+
ref={ref}
39+
{...rest}
40+
>
41+
{children}
42+
</Comp>
43+
);
44+
}
45+
46+
return (
47+
<Comp
48+
className={mergedCls}
49+
disabled={isDisabled}
50+
ref={ref}
51+
{...rest}
52+
>
53+
{loading ? leading || <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : leading}
54+
{children}
55+
{trailing}
56+
</Comp>
57+
);
58+
});
59+
Button.displayName = 'Button';
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { buttonGroupVariants, cn } from '@skyroc-ui/variants';
2+
import { forwardRef } from 'react';
3+
4+
import type { ButtonGroupProps } from '../type';
5+
6+
export const ButtonGroup = forwardRef<HTMLDivElement, ButtonGroupProps>((props, ref) => {
7+
const { children, className, orientation, ...rest } = props;
8+
9+
const mergedCls = cn(buttonGroupVariants({ orientation }), className);
10+
11+
return (
12+
<div
13+
className={mergedCls}
14+
{...rest}
15+
ref={ref}
16+
>
17+
{children}
18+
</div>
19+
);
20+
});
21+
22+
ButtonGroup.displayName = 'ButtonGroup';

0 commit comments

Comments
 (0)