Skip to content

Commit f1b1d71

Browse files
feat: sheet component (#59)
1 parent 952c199 commit f1b1d71

File tree

8 files changed

+234
-1
lines changed

8 files changed

+234
-1
lines changed

.changeset/rich-garlics-tie.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@zenml-io/react-component-library": minor
3+
---
4+
5+
add sheet component

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
"dependencies": {
8787
"@radix-ui/react-avatar": "^1.0.4",
8888
"@radix-ui/react-collapsible": "^1.0.3",
89+
"@radix-ui/react-dialog": "^1.0.5",
8990
"@radix-ui/react-dropdown-menu": "^2.0.6",
9091
"@radix-ui/react-slot": "^1.0.2",
9192
"@radix-ui/react-tabs": "^1.0.4",
@@ -119,6 +120,7 @@
119120
"publint": "^0.2.7",
120121
"storybook": "^8.0.1",
121122
"tailwindcss": "^3.4.1",
123+
"tailwindcss-animate": "^1.0.7",
122124
"tsup": "^8.0.2",
123125
"typescript": "^5.4.2",
124126
"vitest": "^1.4.0"

pnpm-lock.yaml

Lines changed: 47 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { Meta } from "@storybook/react";
2+
import React from "react";
3+
import { Sheet, SheetTrigger, SheetContent, SheetClose } from "./index";
4+
import { Button } from "../Button";
5+
import { StoryObj } from "@storybook/react";
6+
7+
const meta = {
8+
title: "UI/Sheet",
9+
component: Sheet,
10+
argTypes: {},
11+
parameters: {
12+
layout: "centered"
13+
},
14+
15+
tags: ["autodocs"]
16+
} satisfies Meta<typeof Sheet>;
17+
18+
export default meta;
19+
20+
type Story = StoryObj<typeof meta>;
21+
22+
export const DefaultVariant: Story = {
23+
name: "Default",
24+
render: () => (
25+
<Sheet>
26+
<SheetTrigger asChild>
27+
<Button>Open</Button>
28+
</SheetTrigger>
29+
<SheetContent className="w-[1000px] overflow-y-auto">
30+
<div className="p-4">
31+
<SheetClose>
32+
<svg
33+
xmlns="http://www.w3.org/2000/svg"
34+
className="icon icon-tabler icon-tabler-x"
35+
width="24"
36+
height="24"
37+
viewBox="0 0 24 24"
38+
strokeWidth="1.5"
39+
stroke="#000000"
40+
fill="none"
41+
strokeLinecap="round"
42+
strokeLinejoin="round"
43+
>
44+
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
45+
<path d="M18 6l-12 12" />
46+
<path d="M6 6l12 12" />
47+
</svg>
48+
</SheetClose>
49+
<h1 className="text-2xl font-bold">Sheet</h1>
50+
<p className="text-lg">
51+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla condimentum, nisl non
52+
ultricies ultricies, mi nisl ornare est, nec ullamcorper mi libero eget nisl. Donec
53+
auctor, elit nec ultricies ultricies, mi nisl ornare est, nec ullamcorper mi libero eget
54+
nisl. Donec auctor, elit nec ultricies ultricies, mi nisl ornare est, nec ullamcorper mi
55+
libero eget nisl.
56+
</p>
57+
</div>
58+
</SheetContent>
59+
</Sheet>
60+
)
61+
};

src/components/Sheet/Sheet.tsx

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
"use client";
2+
3+
import * as SheetPrimitive from "@radix-ui/react-dialog";
4+
import { cn } from "../../utilities";
5+
import { cva, type VariantProps } from "class-variance-authority";
6+
import React from "react";
7+
8+
const Sheet = SheetPrimitive.Root;
9+
10+
const SheetTrigger = SheetPrimitive.Trigger;
11+
12+
const SheetClose = SheetPrimitive.Close;
13+
14+
const SheetPortal = SheetPrimitive.Portal;
15+
16+
const SheetOverlay = React.forwardRef<
17+
React.ElementRef<typeof SheetPrimitive.Overlay>,
18+
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>
19+
>(({ className, ...props }, ref) => (
20+
<SheetPrimitive.Overlay
21+
className={cn(
22+
"fixed inset-0 z-50 bg-black/10 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
23+
className
24+
)}
25+
{...props}
26+
ref={ref}
27+
/>
28+
));
29+
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName;
30+
31+
const sheetVariants = cva(
32+
"fixed z-50 gap-4 bg-theme-surface-secondary shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
33+
{
34+
variants: {
35+
side: {
36+
top: "inset-x-0 top-0 border-b border-theme-border-moderate data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
37+
bottom:
38+
"inset-x-0 bottom-0 border-t border-theme-border-moderate data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
39+
left: "inset-y-0 left-0 h-full w-3/4 border-theme-border-moderate border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left lg:max-w-[1000px] max-w-sm",
40+
right:
41+
"inset-y-0 right-0 h-full w-3/4 border-theme-border-moderate border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right lg:max-w-[1000px] max-w-sm"
42+
}
43+
},
44+
defaultVariants: {
45+
side: "right"
46+
}
47+
}
48+
);
49+
50+
interface SheetContentProps
51+
extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
52+
VariantProps<typeof sheetVariants> {}
53+
54+
const SheetContent = React.forwardRef<
55+
React.ElementRef<typeof SheetPrimitive.Content>,
56+
SheetContentProps
57+
>(({ side = "right", className, children, ...props }, ref) => (
58+
<SheetPortal>
59+
<SheetOverlay />
60+
<SheetPrimitive.Content ref={ref} className={cn(sheetVariants({ side }), className)} {...props}>
61+
{children}
62+
</SheetPrimitive.Content>
63+
</SheetPortal>
64+
));
65+
SheetContent.displayName = SheetPrimitive.Content.displayName;
66+
67+
const SheetHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
68+
<div className={cn("flex flex-col space-y-2 text-center sm:text-left", className)} {...props} />
69+
);
70+
SheetHeader.displayName = "SheetHeader";
71+
72+
const SheetFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
73+
<div
74+
className={cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className)}
75+
{...props}
76+
/>
77+
);
78+
SheetFooter.displayName = "SheetFooter";
79+
80+
const SheetTitle = React.forwardRef<
81+
React.ElementRef<typeof SheetPrimitive.Title>,
82+
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>
83+
>(({ className, ...props }, ref) => (
84+
<SheetPrimitive.Title
85+
ref={ref}
86+
className={cn("text-lg text-foreground font-semibold", className)}
87+
{...props}
88+
/>
89+
));
90+
SheetTitle.displayName = SheetPrimitive.Title.displayName;
91+
92+
const SheetDescription = React.forwardRef<
93+
React.ElementRef<typeof SheetPrimitive.Description>,
94+
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>
95+
>(({ className, ...props }, ref) => (
96+
<SheetPrimitive.Description
97+
ref={ref}
98+
className={cn("text-sm text-muted-foreground", className)}
99+
{...props}
100+
/>
101+
));
102+
SheetDescription.displayName = SheetPrimitive.Description.displayName;
103+
104+
export {
105+
Sheet,
106+
SheetClose,
107+
SheetContent,
108+
SheetDescription,
109+
SheetFooter,
110+
SheetHeader,
111+
SheetOverlay,
112+
SheetPortal,
113+
SheetTitle,
114+
SheetTrigger
115+
};

src/components/Sheet/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./Sheet";

src/components/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export * from "./Dropdown";
88
export * from "./Table";
99
export * from "./Tag";
1010
export * from "./Badge";
11+
export * from "./Sheet";
1112
export * from "./Spinner";
1213
export * from "./Tabs";
1314
export * from "./Collapsible";

tailwind.config.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ export default {
77
theme: {
88
extend: {}
99
},
10-
plugins: []
10+
// eslint-disable-next-line no-undef
11+
plugins: [require("tailwindcss-animate")]
1112
};

0 commit comments

Comments
 (0)