Skip to content

Commit 2942753

Browse files
feat: select component (#72)
1 parent 71f804c commit 2942753

File tree

7 files changed

+222
-0
lines changed

7 files changed

+222
-0
lines changed

.changeset/tough-ghosts-promise.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@zenml-io/react-component-library": minor
3+
---
4+
5+
add select component

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
"@radix-ui/react-collapsible": "^1.0.3",
9090
"@radix-ui/react-dialog": "^1.0.5",
9191
"@radix-ui/react-dropdown-menu": "^2.0.6",
92+
"@radix-ui/react-select": "^2.0.0",
9293
"@radix-ui/react-slot": "^1.0.2",
9394
"@radix-ui/react-tabs": "^1.0.4",
9495
"@radix-ui/react-toast": "^1.1.5",

pnpm-lock.yaml

+49
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { Meta } from "@storybook/react";
2+
import React from "react";
3+
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./index";
4+
import { StoryObj } from "@storybook/react";
5+
6+
const meta = {
7+
title: "Elements/Select",
8+
component: Select,
9+
argTypes: {},
10+
parameters: {
11+
layout: "centered"
12+
},
13+
14+
tags: ["autodocs"]
15+
} satisfies Meta<typeof Select>;
16+
17+
export default meta;
18+
19+
type Story = StoryObj<typeof meta>;
20+
21+
export const DefaultVariant: Story = {
22+
name: "Default",
23+
render: () => (
24+
<Select>
25+
<SelectTrigger className="border border-theme-border-moderate bg-theme-surface-primary">
26+
<SelectValue placeholder="Select your Provider" />
27+
</SelectTrigger>
28+
<SelectContent className="">
29+
<SelectItem value="aws">Item 1</SelectItem>
30+
<SelectItem value="gcp">Item 2</SelectItem>
31+
<SelectItem value="azure">Item3</SelectItem>
32+
</SelectContent>
33+
</Select>
34+
)
35+
};

src/components/Select/Select.tsx

+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import * as React from "react";
2+
import * as SelectPrimitive from "@radix-ui/react-select";
3+
import { cn } from "../../utilities";
4+
5+
const Select = SelectPrimitive.Root;
6+
7+
const SelectGroup = SelectPrimitive.Group;
8+
9+
const SelectValue = SelectPrimitive.Value;
10+
11+
const SelectTrigger = React.forwardRef<
12+
React.ElementRef<typeof SelectPrimitive.Trigger>,
13+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
14+
>(({ className, children, ...props }, ref) => (
15+
<SelectPrimitive.Trigger
16+
ref={ref}
17+
className={cn(
18+
"ring-offset-background placeholder:text-secondary flex w-full items-center justify-between rounded-md bg-transparent px-2 py-1 text-text-sm focus:outline-none focus:ring-1 focus:ring-primary-500 disabled:cursor-not-allowed disabled:opacity-50",
19+
className
20+
)}
21+
{...props}
22+
>
23+
{children}
24+
<SelectPrimitive.Icon asChild>
25+
<svg
26+
className="h-4 w-4 shrink-0"
27+
viewBox="0 0 24 24"
28+
fill="black"
29+
xmlns="http://www.w3.org/2000/svg"
30+
>
31+
<path
32+
fillRule="evenodd"
33+
clipRule="evenodd"
34+
d="M5.29289 8.29289C5.68342 7.90237 6.31658 7.90237 6.70711 8.29289L12 13.5858L17.2929 8.29289C17.6834 7.90237 18.3166 7.90237 18.7071 8.29289C19.0976 8.68342 19.0976 9.31658 18.7071 9.70711L12.7071 15.7071C12.3166 16.0976 11.6834 16.0976 11.2929 15.7071L5.29289 9.70711C4.90237 9.31658 4.90237 8.68342 5.29289 8.29289Z"
35+
/>
36+
</svg>
37+
</SelectPrimitive.Icon>
38+
</SelectPrimitive.Trigger>
39+
));
40+
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
41+
42+
const SelectContent = React.forwardRef<
43+
React.ElementRef<typeof SelectPrimitive.Content>,
44+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
45+
>(({ className, children, position = "popper", ...props }, ref) => (
46+
<SelectPrimitive.Portal>
47+
<SelectPrimitive.Content
48+
ref={ref}
49+
className={cn(
50+
"relative z-50 min-w-[8rem] overflow-hidden rounded-md border bg-theme-surface-primary data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
51+
position === "popper" &&
52+
"data-[side=left]:-translate-x-1 data-[side=top]:-translate-y-1 data-[side=bottom]:translate-y-1 data-[side=right]:translate-x-1",
53+
className
54+
)}
55+
position={position}
56+
{...props}
57+
>
58+
<SelectPrimitive.Viewport
59+
className={cn(
60+
"p-1",
61+
position === "popper" &&
62+
"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
63+
)}
64+
>
65+
{children}
66+
</SelectPrimitive.Viewport>
67+
</SelectPrimitive.Content>
68+
</SelectPrimitive.Portal>
69+
));
70+
SelectContent.displayName = SelectPrimitive.Content.displayName;
71+
72+
const SelectLabel = React.forwardRef<
73+
React.ElementRef<typeof SelectPrimitive.Label>,
74+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
75+
>(({ className, ...props }, ref) => (
76+
<SelectPrimitive.Label
77+
ref={ref}
78+
className={cn("px-2 py-1 text-text-sm font-semibold", className)}
79+
{...props}
80+
/>
81+
));
82+
SelectLabel.displayName = SelectPrimitive.Label.displayName;
83+
84+
const SelectItem = React.forwardRef<
85+
React.ElementRef<typeof SelectPrimitive.Item>,
86+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item> & { description?: string }
87+
>(({ className, children, description, ...props }, ref) => (
88+
<SelectPrimitive.Item
89+
ref={ref}
90+
className={cn(
91+
"relative flex w-full cursor-default select-none items-center rounded-[4px] py-1 pl-2 pr-8 text-text-sm outline-none focus:bg-theme-surface-tertiary data-[disabled]:pointer-events-none data-[state=checked]:bg-primary-50 data-[disabled]:opacity-50",
92+
className
93+
)}
94+
{...props}
95+
>
96+
{/* <span className="absolute right-2 flex h-3 w-3 items-center justify-center">
97+
<SelectPrimitive.ItemIndicator>
98+
<CheckboxTick className="h-3 w-3 fill-primary-500" />
99+
</SelectPrimitive.ItemIndicator>
100+
</span> */}
101+
<div>
102+
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
103+
<p className="text-theme-text-secondary">{description}</p>
104+
</div>
105+
</SelectPrimitive.Item>
106+
));
107+
SelectItem.displayName = SelectPrimitive.Item.displayName;
108+
109+
const SelectSeparator = React.forwardRef<
110+
React.ElementRef<typeof SelectPrimitive.Separator>,
111+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
112+
>(({ className, ...props }, ref) => (
113+
<SelectPrimitive.Separator
114+
ref={ref}
115+
className={cn("-mx-1 my-1 h-[1px] bg-primary-500", className)}
116+
{...props}
117+
/>
118+
));
119+
SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
120+
121+
export {
122+
Select,
123+
SelectGroup,
124+
SelectValue,
125+
SelectTrigger,
126+
SelectContent,
127+
SelectLabel,
128+
SelectItem,
129+
SelectSeparator
130+
};

src/components/Select/index.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./Select";

src/components/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ export * from "./Checkbox";
1717
export * from "./Toast";
1818
export * from "./Dialog";
1919
export * from "./Progress";
20+
export * from "./Select";

0 commit comments

Comments
 (0)