Skip to content

Commit 231c0c3

Browse files
committed
feat(ui-kit): add button component and variants, update styles and utils, and optimize global styles and theme plugin
1 parent 95fcded commit 231c0c3

File tree

23 files changed

+2167
-25
lines changed

23 files changed

+2167
-25
lines changed

docs/app/globals.css

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,12 @@
11
@import "tailwindcss";
2+
@import "tw-animate-css";
23

3-
:root {
4-
--background: #ffffff;
5-
--foreground: #171717;
6-
}
7-
8-
@theme inline {
9-
--color-background: var(--background);
10-
--color-foreground: var(--foreground);
11-
--font-sans: var(--font-geist-sans);
12-
--font-mono: var(--font-geist-mono);
13-
}
4+
@plugin "tailwindcss-animate";
5+
@plugin "../plugins/tailwind-plugin";
146

15-
@media (prefers-color-scheme: dark) {
16-
:root {
17-
--background: #0a0a0a;
18-
--foreground: #ededed;
19-
}
7+
html {
8+
overflow-x: hidden;
209
}
21-
22-
body {
23-
background: var(--background);
24-
color: var(--foreground);
25-
font-family: Arial, Helvetica, sans-serif;
10+
html,body,#app {
11+
height: 100%;
2612
}

docs/app/page.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import Image from 'next/image';
22

3+
import { Button } from '@/components/button';
4+
35
export default function Home() {
46
return (
57
<div className="font-sans grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20">
@@ -12,6 +14,7 @@ export default function Home() {
1214
src="/next.svg"
1315
width={180}
1416
/>
17+
<Button className="flex-center">Click me</Button>
1518
<ol className="font-mono list-inside list-decimal text-sm/6 text-center sm:text-left">
1619
<li className="mb-2 tracking-[-.01em]">
1720
Get started by editing{' '}

docs/components.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"$schema": "https://ui.shadcn.com/schema.json",
3+
"aliases": {
4+
"components": "@/components",
5+
"hooks": "@/hooks",
6+
"lib": "@/lib",
7+
"ui": "@/components/ui",
8+
"utils": "@/lib/utils"
9+
},
10+
"iconLibrary": "lucide",
11+
"registries": {
12+
"@sr": "http://localhost:3001/r/{name}.json"
13+
},
14+
"rsc": true,
15+
"style": "new-york",
16+
"tailwind": {
17+
"baseColor": "neutral",
18+
"config": "",
19+
"css": "app/globals.css",
20+
"cssVariables": true,
21+
"prefix": ""
22+
},
23+
"tsx": true
24+
}

docs/components/button/Button.tsx

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { Slot } from '@radix-ui/react-slot';
2+
import { Loader2 } from 'lucide-react';
3+
import { forwardRef } from 'react';
4+
5+
import { cn } from '@/lib/utils';
6+
7+
import { buttonVariants } from './button-variants';
8+
import type { ButtonProps } from './types';
9+
10+
const Button = forwardRef<HTMLButtonElement, ButtonProps>((props, ref) => {
11+
const {
12+
asChild = false,
13+
children,
14+
className,
15+
color,
16+
disabled,
17+
fitContent,
18+
leading,
19+
loading,
20+
shadow,
21+
shape,
22+
size,
23+
trailing,
24+
variant,
25+
...rest
26+
} = props;
27+
28+
const isDisabled = loading || disabled;
29+
30+
const Comp = asChild ? Slot : 'button';
31+
32+
// eslint-disable-next-line sort/object-properties
33+
const mergedCls = cn(buttonVariants({ color, fitContent, shadow, size, shape, variant }), className);
34+
35+
if (asChild) {
36+
return (
37+
<Comp
38+
className={mergedCls}
39+
disabled={isDisabled}
40+
ref={ref}
41+
{...rest}
42+
>
43+
{children}
44+
</Comp>
45+
);
46+
}
47+
48+
return (
49+
<Comp
50+
className={mergedCls}
51+
disabled={isDisabled}
52+
ref={ref}
53+
{...rest}
54+
>
55+
{loading ? leading || <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : leading}
56+
{children}
57+
{trailing}
58+
</Comp>
59+
);
60+
});
61+
62+
Button.displayName = 'Button';
63+
64+
export default Button;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { forwardRef } from 'react';
2+
3+
import { cn } from '@/lib/utils';
4+
5+
import { buttonGroupVariants } from './button-group-variants';
6+
import type { ButtonGroupProps } from './types';
7+
8+
const ButtonGroup = forwardRef<HTMLDivElement, ButtonGroupProps>((props, ref) => {
9+
const { children, className, orientation, ...rest } = props;
10+
11+
const mergedCls = cn(buttonGroupVariants({ orientation }), className);
12+
13+
return (
14+
<div
15+
className={mergedCls}
16+
{...rest}
17+
ref={ref}
18+
>
19+
{children}
20+
</div>
21+
);
22+
});
23+
24+
ButtonGroup.displayName = 'ButtonGroup';
25+
26+
export default ButtonGroup;
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { forwardRef } from 'react';
2+
3+
import { Icon } from '../icon';
4+
5+
import Button from './Button';
6+
import type { ButtonIconProps } from './types';
7+
8+
const ButtonIcon = forwardRef<HTMLButtonElement, ButtonIconProps>((props, ref) => {
9+
const {
10+
children,
11+
color = 'accent',
12+
fitContent = true,
13+
icon,
14+
iconProps,
15+
shape = 'square',
16+
variant = 'ghost',
17+
...rest
18+
} = props;
19+
20+
return (
21+
<Button
22+
color={color}
23+
fitContent={fitContent}
24+
ref={ref}
25+
shape={shape}
26+
variant={variant}
27+
{...rest}
28+
>
29+
{children || (
30+
<Icon
31+
icon={String(icon)}
32+
{...iconProps}
33+
/>
34+
)}
35+
</Button>
36+
);
37+
});
38+
39+
ButtonIcon.displayName = 'ButtonIcon';
40+
41+
export default ButtonIcon;
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+
});

0 commit comments

Comments
 (0)