@a2v2ai/uikit 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Alert/Alert.stories.tsx +121 -0
- package/Alert/Alert.tsx +71 -0
- package/AlertDialog/AlertDialog.stories.tsx +665 -0
- package/AlertDialog/AlertDialog.tsx +241 -0
- package/Avatar/Avatar.stories.tsx +128 -0
- package/Avatar/Avatar.tsx +71 -0
- package/Badge/Badge.stories.tsx +76 -0
- package/Badge/Badge.tsx +39 -0
- package/Breadcrumb/Breadcrumb.stories.tsx +231 -0
- package/Breadcrumb/Breadcrumb.tsx +114 -0
- package/Button/Button.stories.tsx +684 -0
- package/Button/Button.tsx +90 -0
- package/Calendar/Calendar.stories.tsx +207 -0
- package/Calendar/Calendar.tsx +232 -0
- package/Card/Card.stories.tsx +136 -0
- package/Card/Card.tsx +96 -0
- package/ChatBubble/ChatBubble.stories.tsx +307 -0
- package/ChatBubble/ChatBubble.tsx +167 -0
- package/Checkbox/Checkbox.stories.tsx +137 -0
- package/Checkbox/Checkbox.tsx +53 -0
- package/Drawer/Drawer.stories.tsx +721 -0
- package/Drawer/Drawer.tsx +201 -0
- package/DropdownMenu/DropdownMenu.stories.tsx +251 -0
- package/DropdownMenu/DropdownMenu.tsx +199 -0
- package/ErrorMessage/ErrorMessage.stories.tsx +159 -0
- package/ErrorMessage/ErrorMessage.tsx +55 -0
- package/Flex/Flex.tsx +102 -0
- package/IconButton/IconButton.stories.tsx +566 -0
- package/IconButton/IconButton.tsx +95 -0
- package/Input/Input.stories.tsx +456 -0
- package/Input/Input.tsx +129 -0
- package/InputOTP/InputOTP.stories.tsx +246 -0
- package/InputOTP/InputOTP.tsx +127 -0
- package/Label/Label.stories.tsx +105 -0
- package/Label/Label.tsx +43 -0
- package/Loader/Loader.stories.tsx +170 -0
- package/Loader/Loader.tsx +62 -0
- package/Popover/Popover.stories.tsx +133 -0
- package/Popover/Popover.tsx +31 -0
- package/Progress/Progress.stories.tsx +146 -0
- package/Progress/Progress.tsx +67 -0
- package/README.md +12 -12
- package/RadioGroup/RadioGroup.stories.tsx +159 -0
- package/RadioGroup/RadioGroup.tsx +68 -0
- package/ScrollArea/ScrollArea.stories.tsx +136 -0
- package/ScrollArea/ScrollArea.tsx +46 -0
- package/Select/Select.stories.tsx +242 -0
- package/Select/Select.tsx +180 -0
- package/Separator/Separator.stories.tsx +110 -0
- package/Separator/Separator.tsx +29 -0
- package/Skeleton/Skeleton.stories.tsx +117 -0
- package/Skeleton/Skeleton.tsx +16 -0
- package/Spinner/Spinner.stories.tsx +210 -0
- package/Spinner/Spinner.tsx +78 -0
- package/Switch/Switch.stories.tsx +146 -0
- package/Switch/Switch.tsx +59 -0
- package/Tabs/Tabs.stories.tsx +197 -0
- package/Tabs/Tabs.tsx +74 -0
- package/Textarea/Textarea.stories.tsx +170 -0
- package/Textarea/Textarea.tsx +51 -0
- package/Toast/Toast.stories.tsx +285 -0
- package/Toast/Toast.tsx +59 -0
- package/Tooltip/Tooltip.stories.tsx +463 -0
- package/Tooltip/Tooltip.tsx +96 -0
- package/Typography/Typography.stories.tsx +235 -0
- package/Typography/Typography.tsx +171 -0
- package/helpers.ts +5 -0
- package/icons.ts +2 -0
- package/index.ts +136 -0
- package/lib/utils.ts +15 -0
- package/package.json +4 -1
- package/tsconfig.json +24 -0
- package/Alert/Alert.d.ts +0 -11
- package/Alert/Alert.js +0 -64
- package/AlertDialog/AlertDialog.d.ts +0 -35
- package/AlertDialog/AlertDialog.js +0 -121
- package/Avatar/Avatar.d.ts +0 -12
- package/Avatar/Avatar.js +0 -64
- package/Badge/Badge.d.ts +0 -9
- package/Badge/Badge.js +0 -26
- package/Breadcrumb/Breadcrumb.d.ts +0 -19
- package/Breadcrumb/Breadcrumb.js +0 -65
- package/Button/Button.d.ts +0 -14
- package/Button/Button.js +0 -75
- package/Calendar/Calendar.d.ts +0 -16
- package/Calendar/Calendar.js +0 -113
- package/Card/Card.d.ts +0 -14
- package/Card/Card.js +0 -70
- package/ChatBubble/ChatBubble.d.ts +0 -29
- package/ChatBubble/ChatBubble.js +0 -133
- package/Checkbox/Checkbox.d.ts +0 -10
- package/Checkbox/Checkbox.js +0 -57
- package/Dialog/Dialog.d.ts +0 -35
- package/Dialog/Dialog.js +0 -130
- package/Drawer/Drawer.d.ts +0 -31
- package/Drawer/Drawer.js +0 -69
- package/DropdownMenu/DropdownMenu.d.ts +0 -27
- package/DropdownMenu/DropdownMenu.js +0 -85
- package/ErrorMessage/ErrorMessage.d.ts +0 -27
- package/ErrorMessage/ErrorMessage.js +0 -15
- package/Flex/Flex.d.ts +0 -23
- package/Flex/Flex.js +0 -101
- package/IconButton/IconButton.d.ts +0 -17
- package/IconButton/IconButton.js +0 -85
- package/Input/Input.d.ts +0 -16
- package/Input/Input.js +0 -75
- package/InputOTP/InputOTP.d.ts +0 -18
- package/InputOTP/InputOTP.js +0 -85
- package/Label/Label.d.ts +0 -10
- package/Label/Label.js +0 -57
- package/Loader/Loader.d.ts +0 -18
- package/Loader/Loader.js +0 -67
- package/Popover/Popover.d.ts +0 -7
- package/Popover/Popover.js +0 -49
- package/Progress/Progress.d.ts +0 -13
- package/Progress/Progress.js +0 -71
- package/RadioGroup/RadioGroup.d.ts +0 -11
- package/RadioGroup/RadioGroup.js +0 -64
- package/ScrollArea/ScrollArea.d.ts +0 -5
- package/ScrollArea/ScrollArea.js +0 -48
- package/Select/Select.d.ts +0 -19
- package/Select/Select.js +0 -85
- package/Separator/Separator.d.ts +0 -4
- package/Separator/Separator.js +0 -43
- package/Skeleton/Skeleton.d.ts +0 -4
- package/Skeleton/Skeleton.js +0 -8
- package/Spinner/Spinner.d.ts +0 -15
- package/Spinner/Spinner.js +0 -68
- package/Switch/Switch.d.ts +0 -10
- package/Switch/Switch.js +0 -67
- package/Tabs/Tabs.d.ts +0 -13
- package/Tabs/Tabs.js +0 -64
- package/Textarea/Textarea.d.ts +0 -10
- package/Textarea/Textarea.js +0 -64
- package/Toast/Toast.d.ts +0 -10
- package/Toast/Toast.js +0 -29
- package/Tooltip/Tooltip.d.ts +0 -15
- package/Tooltip/Tooltip.js +0 -68
- package/Typography/Typography.d.ts +0 -15
- package/Typography/Typography.js +0 -125
- package/helpers.d.ts +0 -4
- package/helpers.js +0 -13
- package/icons.d.ts +0 -1
- package/icons.js +0 -18
- package/index.d.ts +0 -35
- package/index.js +0 -183
- package/lib/utils.d.ts +0 -3
- package/lib/utils.js +0 -18
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import * as RadioGroupPrimitive from "@radix-ui/react-radio-group"
|
|
3
|
+
import { Circle } from "lucide-react"
|
|
4
|
+
import { cva } from "class-variance-authority"
|
|
5
|
+
|
|
6
|
+
import { cn } from "../lib/utils"
|
|
7
|
+
|
|
8
|
+
type RadioGroupItemSize = "small" | "regular"
|
|
9
|
+
|
|
10
|
+
const RadioGroup = React.forwardRef<
|
|
11
|
+
React.ElementRef<typeof RadioGroupPrimitive.Root>,
|
|
12
|
+
React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root>
|
|
13
|
+
>(({ className, ...props }, ref) => {
|
|
14
|
+
return (
|
|
15
|
+
<RadioGroupPrimitive.Root
|
|
16
|
+
className={cn("grid gap-2", className)}
|
|
17
|
+
{...props}
|
|
18
|
+
ref={ref}
|
|
19
|
+
/>
|
|
20
|
+
)
|
|
21
|
+
})
|
|
22
|
+
RadioGroup.displayName = RadioGroupPrimitive.Root.displayName
|
|
23
|
+
|
|
24
|
+
const radioGroupItemVariants = cva(
|
|
25
|
+
"aspect-square rounded-full border border-grey-300 bg-white text-main-950 ring-offset-white focus:outline-none focus-visible:ring-2 focus-visible:ring-main-950 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:border-main-950",
|
|
26
|
+
{
|
|
27
|
+
variants: {
|
|
28
|
+
size: {
|
|
29
|
+
small: "size-4",
|
|
30
|
+
regular: "size-5",
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
defaultVariants: {
|
|
34
|
+
size: "regular",
|
|
35
|
+
},
|
|
36
|
+
}
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
export interface RadioGroupItemProps
|
|
40
|
+
extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item> {
|
|
41
|
+
size?: RadioGroupItemSize
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const RadioGroupItem = React.forwardRef<
|
|
45
|
+
React.ElementRef<typeof RadioGroupPrimitive.Item>,
|
|
46
|
+
RadioGroupItemProps
|
|
47
|
+
>(({ className, size, ...props }, ref) => {
|
|
48
|
+
return (
|
|
49
|
+
<RadioGroupPrimitive.Item
|
|
50
|
+
ref={ref}
|
|
51
|
+
className={cn(radioGroupItemVariants({ size }), className)}
|
|
52
|
+
{...props}
|
|
53
|
+
>
|
|
54
|
+
<RadioGroupPrimitive.Indicator className="flex items-center justify-center">
|
|
55
|
+
<Circle
|
|
56
|
+
className={cn(
|
|
57
|
+
"fill-main-950 text-main-950",
|
|
58
|
+
size === "small" ? "size-2" : "size-2.5"
|
|
59
|
+
)}
|
|
60
|
+
/>
|
|
61
|
+
</RadioGroupPrimitive.Indicator>
|
|
62
|
+
</RadioGroupPrimitive.Item>
|
|
63
|
+
)
|
|
64
|
+
})
|
|
65
|
+
RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName
|
|
66
|
+
|
|
67
|
+
export { RadioGroup, RadioGroupItem, radioGroupItemVariants }
|
|
68
|
+
export type { RadioGroupItemSize }
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react"
|
|
2
|
+
|
|
3
|
+
import { Separator } from "../Separator/Separator"
|
|
4
|
+
import { Flex } from "../Flex/Flex"
|
|
5
|
+
import { Typography } from "../Typography/Typography"
|
|
6
|
+
import { ScrollArea, ScrollBar } from "./ScrollArea"
|
|
7
|
+
|
|
8
|
+
const meta: Meta<typeof ScrollArea> = {
|
|
9
|
+
title: "Components/ScrollArea",
|
|
10
|
+
component: ScrollArea,
|
|
11
|
+
parameters: {
|
|
12
|
+
layout: "centered",
|
|
13
|
+
},
|
|
14
|
+
tags: ["autodocs"],
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default meta
|
|
18
|
+
type Story = StoryObj<typeof meta>
|
|
19
|
+
|
|
20
|
+
const tags = Array.from({ length: 50 }).map(
|
|
21
|
+
(_, i, a) => `v1.2.0-beta.${a.length - i}`
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
export const Default: Story = {
|
|
25
|
+
render: () => (
|
|
26
|
+
<ScrollArea className="h-72 w-48 rounded-md border border-grey-200 bg-white">
|
|
27
|
+
<div className="p-4">
|
|
28
|
+
<h4 className="mb-4 text-sm font-medium leading-none">Tags</h4>
|
|
29
|
+
{tags.map((tag) => (
|
|
30
|
+
<div key={tag}>
|
|
31
|
+
<div className="text-sm">{tag}</div>
|
|
32
|
+
<Separator className="my-2" />
|
|
33
|
+
</div>
|
|
34
|
+
))}
|
|
35
|
+
</div>
|
|
36
|
+
</ScrollArea>
|
|
37
|
+
),
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const artworks = [
|
|
41
|
+
{ artist: "Ornella Binni", art: "Reflected" },
|
|
42
|
+
{ artist: "Tom Byrom", art: "Mountain Mist" },
|
|
43
|
+
{ artist: "Vladimir Malyavko", art: "Spring Bloom" },
|
|
44
|
+
{ artist: "Joshua Newton", art: "River Flow" },
|
|
45
|
+
{ artist: "Pete Nowicki", art: "Sunset Valley" },
|
|
46
|
+
{ artist: "Laura Chouette", art: "Autumn Leaves" },
|
|
47
|
+
{ artist: "Nick Nice", art: "Ocean Waves" },
|
|
48
|
+
{ artist: "Daniel Olah", art: "City Lights" },
|
|
49
|
+
{ artist: "Igor Rodrigues", art: "Forest Path" },
|
|
50
|
+
{ artist: "Vadim Sherbakov", art: "Winter Snow" },
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
export const Horizontal: Story = {
|
|
54
|
+
render: () => (
|
|
55
|
+
<ScrollArea className="w-96 whitespace-nowrap rounded-md border border-grey-200 bg-white">
|
|
56
|
+
<div className="flex w-max space-x-4 p-4">
|
|
57
|
+
{artworks.map((artwork) => (
|
|
58
|
+
<figure key={artwork.artist} className="shrink-0">
|
|
59
|
+
<div className="overflow-hidden rounded-md">
|
|
60
|
+
<div className="h-[150px] w-[200px] bg-grey-100 flex items-center justify-center">
|
|
61
|
+
<span className="text-grey-400 text-sm">{artwork.art}</span>
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
<figcaption className="pt-2 text-xs text-grey-500">
|
|
65
|
+
Photo by{" "}
|
|
66
|
+
<span className="font-semibold text-main-950">
|
|
67
|
+
{artwork.artist}
|
|
68
|
+
</span>
|
|
69
|
+
</figcaption>
|
|
70
|
+
</figure>
|
|
71
|
+
))}
|
|
72
|
+
</div>
|
|
73
|
+
<ScrollBar orientation="horizontal" />
|
|
74
|
+
</ScrollArea>
|
|
75
|
+
),
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export const Both: Story = {
|
|
79
|
+
render: () => (
|
|
80
|
+
<ScrollArea className="h-[200px] w-[350px] rounded-md border border-grey-200 bg-white p-4">
|
|
81
|
+
<div className="w-[600px]">
|
|
82
|
+
<h4 className="mb-4 text-sm font-medium">Both Scrollbars</h4>
|
|
83
|
+
<p className="text-sm text-grey-500">
|
|
84
|
+
This content is wider and taller than the container, so it requires both horizontal and vertical scrolling.
|
|
85
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
|
86
|
+
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
|
|
87
|
+
</p>
|
|
88
|
+
<div className="mt-4 grid grid-cols-3 gap-4">
|
|
89
|
+
{Array.from({ length: 12 }).map((_, i) => (
|
|
90
|
+
<div key={i} className="h-20 w-40 bg-grey-100 rounded-md flex items-center justify-center">
|
|
91
|
+
<span className="text-grey-400 text-sm">Item {i + 1}</span>
|
|
92
|
+
</div>
|
|
93
|
+
))}
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
<ScrollBar orientation="horizontal" />
|
|
97
|
+
</ScrollArea>
|
|
98
|
+
),
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export const AllVariants: Story = {
|
|
102
|
+
render: () => (
|
|
103
|
+
<Flex direction="column" gap={6}>
|
|
104
|
+
<Typography variant="h4" className="text-white">ScrollArea Examples</Typography>
|
|
105
|
+
|
|
106
|
+
<Flex gap={6}>
|
|
107
|
+
<Flex direction="column" gap={2}>
|
|
108
|
+
<Typography variant="caption" className="text-grey-400">Vertical</Typography>
|
|
109
|
+
<ScrollArea className="h-48 w-48 rounded-md border border-grey-200 bg-white">
|
|
110
|
+
<div className="p-4">
|
|
111
|
+
{Array.from({ length: 20 }).map((_, i) => (
|
|
112
|
+
<div key={i} className="py-2 text-sm">
|
|
113
|
+
Item {i + 1}
|
|
114
|
+
</div>
|
|
115
|
+
))}
|
|
116
|
+
</div>
|
|
117
|
+
</ScrollArea>
|
|
118
|
+
</Flex>
|
|
119
|
+
|
|
120
|
+
<Flex direction="column" gap={2}>
|
|
121
|
+
<Typography variant="caption" className="text-grey-400">Horizontal</Typography>
|
|
122
|
+
<ScrollArea className="w-64 whitespace-nowrap rounded-md border border-grey-200 bg-white">
|
|
123
|
+
<div className="flex w-max space-x-4 p-4">
|
|
124
|
+
{Array.from({ length: 10 }).map((_, i) => (
|
|
125
|
+
<div key={i} className="shrink-0 h-20 w-20 bg-grey-100 rounded-md flex items-center justify-center">
|
|
126
|
+
<span className="text-grey-400 text-xs">{i + 1}</span>
|
|
127
|
+
</div>
|
|
128
|
+
))}
|
|
129
|
+
</div>
|
|
130
|
+
<ScrollBar orientation="horizontal" />
|
|
131
|
+
</ScrollArea>
|
|
132
|
+
</Flex>
|
|
133
|
+
</Flex>
|
|
134
|
+
</Flex>
|
|
135
|
+
),
|
|
136
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"
|
|
3
|
+
|
|
4
|
+
import { cn } from "../lib/utils"
|
|
5
|
+
|
|
6
|
+
const ScrollArea = React.forwardRef<
|
|
7
|
+
React.ElementRef<typeof ScrollAreaPrimitive.Root>,
|
|
8
|
+
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>
|
|
9
|
+
>(({ className, children, ...props }, ref) => (
|
|
10
|
+
<ScrollAreaPrimitive.Root
|
|
11
|
+
ref={ref}
|
|
12
|
+
className={cn("relative overflow-hidden", className)}
|
|
13
|
+
{...props}
|
|
14
|
+
>
|
|
15
|
+
<ScrollAreaPrimitive.Viewport className="h-full w-full rounded-[inherit]">
|
|
16
|
+
{children}
|
|
17
|
+
</ScrollAreaPrimitive.Viewport>
|
|
18
|
+
<ScrollBar />
|
|
19
|
+
<ScrollAreaPrimitive.Corner />
|
|
20
|
+
</ScrollAreaPrimitive.Root>
|
|
21
|
+
))
|
|
22
|
+
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName
|
|
23
|
+
|
|
24
|
+
const ScrollBar = React.forwardRef<
|
|
25
|
+
React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,
|
|
26
|
+
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>
|
|
27
|
+
>(({ className, orientation = "vertical", ...props }, ref) => (
|
|
28
|
+
<ScrollAreaPrimitive.ScrollAreaScrollbar
|
|
29
|
+
ref={ref}
|
|
30
|
+
orientation={orientation}
|
|
31
|
+
className={cn(
|
|
32
|
+
"flex touch-none select-none transition-colors",
|
|
33
|
+
orientation === "vertical" &&
|
|
34
|
+
"h-full w-2.5 border-l border-l-transparent p-[1px]",
|
|
35
|
+
orientation === "horizontal" &&
|
|
36
|
+
"h-2.5 flex-col border-t border-t-transparent p-[1px]",
|
|
37
|
+
className
|
|
38
|
+
)}
|
|
39
|
+
{...props}
|
|
40
|
+
>
|
|
41
|
+
<ScrollAreaPrimitive.ScrollAreaThumb className="relative flex-1 rounded-full bg-grey-300" />
|
|
42
|
+
</ScrollAreaPrimitive.ScrollAreaScrollbar>
|
|
43
|
+
))
|
|
44
|
+
ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName
|
|
45
|
+
|
|
46
|
+
export { ScrollArea, ScrollBar }
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react"
|
|
2
|
+
|
|
3
|
+
import { Label } from "../Label/Label"
|
|
4
|
+
import { Flex } from "../Flex/Flex"
|
|
5
|
+
import { Typography } from "../Typography/Typography"
|
|
6
|
+
import {
|
|
7
|
+
Select,
|
|
8
|
+
SelectContent,
|
|
9
|
+
SelectGroup,
|
|
10
|
+
SelectItem,
|
|
11
|
+
SelectLabel,
|
|
12
|
+
SelectTrigger,
|
|
13
|
+
SelectValue,
|
|
14
|
+
SelectSeparator,
|
|
15
|
+
} from "./Select"
|
|
16
|
+
|
|
17
|
+
const meta: Meta<typeof Select> = {
|
|
18
|
+
title: "Components/Select",
|
|
19
|
+
component: Select,
|
|
20
|
+
parameters: {
|
|
21
|
+
layout: "centered",
|
|
22
|
+
},
|
|
23
|
+
tags: ["autodocs"],
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export default meta
|
|
27
|
+
type Story = StoryObj<typeof meta>
|
|
28
|
+
|
|
29
|
+
export const Default: Story = {
|
|
30
|
+
render: () => (
|
|
31
|
+
<Select>
|
|
32
|
+
<SelectTrigger className="w-[180px]">
|
|
33
|
+
<SelectValue placeholder="Select a fruit" />
|
|
34
|
+
</SelectTrigger>
|
|
35
|
+
<SelectContent>
|
|
36
|
+
<SelectGroup>
|
|
37
|
+
<SelectLabel>Fruits</SelectLabel>
|
|
38
|
+
<SelectItem value="apple">Apple</SelectItem>
|
|
39
|
+
<SelectItem value="banana">Banana</SelectItem>
|
|
40
|
+
<SelectItem value="blueberry">Blueberry</SelectItem>
|
|
41
|
+
<SelectItem value="grapes">Grapes</SelectItem>
|
|
42
|
+
<SelectItem value="pineapple">Pineapple</SelectItem>
|
|
43
|
+
</SelectGroup>
|
|
44
|
+
</SelectContent>
|
|
45
|
+
</Select>
|
|
46
|
+
),
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export const WithLabel: Story = {
|
|
50
|
+
render: () => (
|
|
51
|
+
<Flex direction="column" gap={2}>
|
|
52
|
+
<Label htmlFor="framework">Framework</Label>
|
|
53
|
+
<Select>
|
|
54
|
+
<SelectTrigger id="framework" className="w-[180px]">
|
|
55
|
+
<SelectValue placeholder="Select a framework" />
|
|
56
|
+
</SelectTrigger>
|
|
57
|
+
<SelectContent>
|
|
58
|
+
<SelectItem value="next">Next.js</SelectItem>
|
|
59
|
+
<SelectItem value="sveltekit">SvelteKit</SelectItem>
|
|
60
|
+
<SelectItem value="astro">Astro</SelectItem>
|
|
61
|
+
<SelectItem value="nuxt">Nuxt.js</SelectItem>
|
|
62
|
+
</SelectContent>
|
|
63
|
+
</Select>
|
|
64
|
+
</Flex>
|
|
65
|
+
),
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export const WithGroups: Story = {
|
|
69
|
+
render: () => (
|
|
70
|
+
<Select>
|
|
71
|
+
<SelectTrigger className="w-[280px]">
|
|
72
|
+
<SelectValue placeholder="Select a timezone" />
|
|
73
|
+
</SelectTrigger>
|
|
74
|
+
<SelectContent>
|
|
75
|
+
<SelectGroup>
|
|
76
|
+
<SelectLabel>North America</SelectLabel>
|
|
77
|
+
<SelectItem value="est">Eastern Standard Time (EST)</SelectItem>
|
|
78
|
+
<SelectItem value="cst">Central Standard Time (CST)</SelectItem>
|
|
79
|
+
<SelectItem value="mst">Mountain Standard Time (MST)</SelectItem>
|
|
80
|
+
<SelectItem value="pst">Pacific Standard Time (PST)</SelectItem>
|
|
81
|
+
</SelectGroup>
|
|
82
|
+
<SelectSeparator />
|
|
83
|
+
<SelectGroup>
|
|
84
|
+
<SelectLabel>Europe & Africa</SelectLabel>
|
|
85
|
+
<SelectItem value="gmt">Greenwich Mean Time (GMT)</SelectItem>
|
|
86
|
+
<SelectItem value="cet">Central European Time (CET)</SelectItem>
|
|
87
|
+
<SelectItem value="eet">Eastern European Time (EET)</SelectItem>
|
|
88
|
+
</SelectGroup>
|
|
89
|
+
<SelectSeparator />
|
|
90
|
+
<SelectGroup>
|
|
91
|
+
<SelectLabel>Asia</SelectLabel>
|
|
92
|
+
<SelectItem value="ist">India Standard Time (IST)</SelectItem>
|
|
93
|
+
<SelectItem value="cst_china">China Standard Time (CST)</SelectItem>
|
|
94
|
+
<SelectItem value="jst">Japan Standard Time (JST)</SelectItem>
|
|
95
|
+
</SelectGroup>
|
|
96
|
+
</SelectContent>
|
|
97
|
+
</Select>
|
|
98
|
+
),
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export const Disabled: Story = {
|
|
102
|
+
render: () => (
|
|
103
|
+
<Select disabled>
|
|
104
|
+
<SelectTrigger className="w-[180px]">
|
|
105
|
+
<SelectValue placeholder="Select option" />
|
|
106
|
+
</SelectTrigger>
|
|
107
|
+
<SelectContent>
|
|
108
|
+
<SelectItem value="option1">Option 1</SelectItem>
|
|
109
|
+
<SelectItem value="option2">Option 2</SelectItem>
|
|
110
|
+
</SelectContent>
|
|
111
|
+
</Select>
|
|
112
|
+
),
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export const Small: Story = {
|
|
116
|
+
render: () => (
|
|
117
|
+
<Select>
|
|
118
|
+
<SelectTrigger size="small" className="w-[180px]">
|
|
119
|
+
<SelectValue placeholder="Select size" />
|
|
120
|
+
</SelectTrigger>
|
|
121
|
+
<SelectContent>
|
|
122
|
+
<SelectItem value="xs">Extra Small</SelectItem>
|
|
123
|
+
<SelectItem value="sm">Small</SelectItem>
|
|
124
|
+
<SelectItem value="md">Medium</SelectItem>
|
|
125
|
+
<SelectItem value="lg">Large</SelectItem>
|
|
126
|
+
<SelectItem value="xl">Extra Large</SelectItem>
|
|
127
|
+
</SelectContent>
|
|
128
|
+
</Select>
|
|
129
|
+
),
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export const Large: Story = {
|
|
133
|
+
render: () => (
|
|
134
|
+
<Select>
|
|
135
|
+
<SelectTrigger size="large" className="w-[180px]">
|
|
136
|
+
<SelectValue placeholder="Select size" />
|
|
137
|
+
</SelectTrigger>
|
|
138
|
+
<SelectContent>
|
|
139
|
+
<SelectItem value="xs">Extra Small</SelectItem>
|
|
140
|
+
<SelectItem value="sm">Small</SelectItem>
|
|
141
|
+
<SelectItem value="md">Medium</SelectItem>
|
|
142
|
+
<SelectItem value="lg">Large</SelectItem>
|
|
143
|
+
<SelectItem value="xl">Extra Large</SelectItem>
|
|
144
|
+
</SelectContent>
|
|
145
|
+
</Select>
|
|
146
|
+
),
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export const AllVariants: Story = {
|
|
150
|
+
render: () => (
|
|
151
|
+
<Flex direction="column" gap={6}>
|
|
152
|
+
<Typography variant="h4" className="text-white">Select Sizes</Typography>
|
|
153
|
+
|
|
154
|
+
<Flex gap={4} align="end">
|
|
155
|
+
<Flex direction="column" gap={2}>
|
|
156
|
+
<Typography variant="caption" className="text-grey-400">Small</Typography>
|
|
157
|
+
<Select defaultValue="option1">
|
|
158
|
+
<SelectTrigger size="small" className="w-[150px]">
|
|
159
|
+
<SelectValue />
|
|
160
|
+
</SelectTrigger>
|
|
161
|
+
<SelectContent>
|
|
162
|
+
<SelectItem value="option1">Option 1</SelectItem>
|
|
163
|
+
<SelectItem value="option2">Option 2</SelectItem>
|
|
164
|
+
</SelectContent>
|
|
165
|
+
</Select>
|
|
166
|
+
</Flex>
|
|
167
|
+
|
|
168
|
+
<Flex direction="column" gap={2}>
|
|
169
|
+
<Typography variant="caption" className="text-grey-400">Regular</Typography>
|
|
170
|
+
<Select defaultValue="option1">
|
|
171
|
+
<SelectTrigger size="regular" className="w-[150px]">
|
|
172
|
+
<SelectValue />
|
|
173
|
+
</SelectTrigger>
|
|
174
|
+
<SelectContent>
|
|
175
|
+
<SelectItem value="option1">Option 1</SelectItem>
|
|
176
|
+
<SelectItem value="option2">Option 2</SelectItem>
|
|
177
|
+
</SelectContent>
|
|
178
|
+
</Select>
|
|
179
|
+
</Flex>
|
|
180
|
+
|
|
181
|
+
<Flex direction="column" gap={2}>
|
|
182
|
+
<Typography variant="caption" className="text-grey-400">Large</Typography>
|
|
183
|
+
<Select defaultValue="option1">
|
|
184
|
+
<SelectTrigger size="large" className="w-[150px]">
|
|
185
|
+
<SelectValue />
|
|
186
|
+
</SelectTrigger>
|
|
187
|
+
<SelectContent>
|
|
188
|
+
<SelectItem value="option1">Option 1</SelectItem>
|
|
189
|
+
<SelectItem value="option2">Option 2</SelectItem>
|
|
190
|
+
</SelectContent>
|
|
191
|
+
</Select>
|
|
192
|
+
</Flex>
|
|
193
|
+
</Flex>
|
|
194
|
+
|
|
195
|
+
<Typography variant="h4" className="text-white mt-4">With Form Label</Typography>
|
|
196
|
+
|
|
197
|
+
<Flex direction="column" gap={2} className="w-[250px]">
|
|
198
|
+
<Label htmlFor="country">Country</Label>
|
|
199
|
+
<Select defaultValue="us">
|
|
200
|
+
<SelectTrigger id="country">
|
|
201
|
+
<SelectValue />
|
|
202
|
+
</SelectTrigger>
|
|
203
|
+
<SelectContent>
|
|
204
|
+
<SelectItem value="us">United States</SelectItem>
|
|
205
|
+
<SelectItem value="uk">United Kingdom</SelectItem>
|
|
206
|
+
<SelectItem value="ca">Canada</SelectItem>
|
|
207
|
+
<SelectItem value="au">Australia</SelectItem>
|
|
208
|
+
</SelectContent>
|
|
209
|
+
</Select>
|
|
210
|
+
</Flex>
|
|
211
|
+
|
|
212
|
+
<Typography variant="h4" className="text-white mt-4">States</Typography>
|
|
213
|
+
|
|
214
|
+
<Flex gap={4}>
|
|
215
|
+
<Flex direction="column" gap={2}>
|
|
216
|
+
<Typography variant="caption" className="text-grey-400">Default</Typography>
|
|
217
|
+
<Select>
|
|
218
|
+
<SelectTrigger className="w-[150px]">
|
|
219
|
+
<SelectValue placeholder="Select..." />
|
|
220
|
+
</SelectTrigger>
|
|
221
|
+
<SelectContent>
|
|
222
|
+
<SelectItem value="1">Option 1</SelectItem>
|
|
223
|
+
<SelectItem value="2">Option 2</SelectItem>
|
|
224
|
+
</SelectContent>
|
|
225
|
+
</Select>
|
|
226
|
+
</Flex>
|
|
227
|
+
|
|
228
|
+
<Flex direction="column" gap={2}>
|
|
229
|
+
<Typography variant="caption" className="text-grey-400">Disabled</Typography>
|
|
230
|
+
<Select disabled>
|
|
231
|
+
<SelectTrigger className="w-[150px]">
|
|
232
|
+
<SelectValue placeholder="Select..." />
|
|
233
|
+
</SelectTrigger>
|
|
234
|
+
<SelectContent>
|
|
235
|
+
<SelectItem value="1">Option 1</SelectItem>
|
|
236
|
+
</SelectContent>
|
|
237
|
+
</Select>
|
|
238
|
+
</Flex>
|
|
239
|
+
</Flex>
|
|
240
|
+
</Flex>
|
|
241
|
+
),
|
|
242
|
+
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import * as SelectPrimitive from "@radix-ui/react-select"
|
|
3
|
+
import { Check, ChevronDown, ChevronUp } from "lucide-react"
|
|
4
|
+
import { cva } from "class-variance-authority"
|
|
5
|
+
|
|
6
|
+
import { cn } from "../lib/utils"
|
|
7
|
+
|
|
8
|
+
type SelectTriggerSize = "small" | "regular" | "large"
|
|
9
|
+
|
|
10
|
+
const Select = SelectPrimitive.Root
|
|
11
|
+
|
|
12
|
+
const SelectGroup = SelectPrimitive.Group
|
|
13
|
+
|
|
14
|
+
const SelectValue = SelectPrimitive.Value
|
|
15
|
+
|
|
16
|
+
const selectTriggerVariants = cva(
|
|
17
|
+
"flex w-full items-center justify-between whitespace-nowrap border border-grey-300 bg-white text-main-950 ring-offset-white placeholder:text-grey-400 focus:outline-none focus:ring-2 focus:ring-main-950 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
|
|
18
|
+
{
|
|
19
|
+
variants: {
|
|
20
|
+
size: {
|
|
21
|
+
small: "h-8 px-3 text-sm rounded-md",
|
|
22
|
+
regular: "h-9 px-3 text-sm rounded-lg",
|
|
23
|
+
large: "h-10 px-3 text-base rounded-lg",
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
defaultVariants: {
|
|
27
|
+
size: "regular",
|
|
28
|
+
},
|
|
29
|
+
}
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
export interface SelectTriggerProps
|
|
33
|
+
extends React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger> {
|
|
34
|
+
size?: SelectTriggerSize
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const SelectTrigger = React.forwardRef<
|
|
38
|
+
React.ElementRef<typeof SelectPrimitive.Trigger>,
|
|
39
|
+
SelectTriggerProps
|
|
40
|
+
>(({ className, size, children, ...props }, ref) => (
|
|
41
|
+
<SelectPrimitive.Trigger
|
|
42
|
+
ref={ref}
|
|
43
|
+
className={cn(selectTriggerVariants({ size }), className)}
|
|
44
|
+
{...props}
|
|
45
|
+
>
|
|
46
|
+
{children}
|
|
47
|
+
<SelectPrimitive.Icon asChild>
|
|
48
|
+
<ChevronDown className="size-4 opacity-50" />
|
|
49
|
+
</SelectPrimitive.Icon>
|
|
50
|
+
</SelectPrimitive.Trigger>
|
|
51
|
+
))
|
|
52
|
+
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName
|
|
53
|
+
|
|
54
|
+
const SelectScrollUpButton = React.forwardRef<
|
|
55
|
+
React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
|
|
56
|
+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
|
|
57
|
+
>(({ className, ...props }, ref) => (
|
|
58
|
+
<SelectPrimitive.ScrollUpButton
|
|
59
|
+
ref={ref}
|
|
60
|
+
className={cn(
|
|
61
|
+
"flex cursor-default items-center justify-center py-1",
|
|
62
|
+
className
|
|
63
|
+
)}
|
|
64
|
+
{...props}
|
|
65
|
+
>
|
|
66
|
+
<ChevronUp className="size-4" />
|
|
67
|
+
</SelectPrimitive.ScrollUpButton>
|
|
68
|
+
))
|
|
69
|
+
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName
|
|
70
|
+
|
|
71
|
+
const SelectScrollDownButton = React.forwardRef<
|
|
72
|
+
React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
|
|
73
|
+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
|
|
74
|
+
>(({ className, ...props }, ref) => (
|
|
75
|
+
<SelectPrimitive.ScrollDownButton
|
|
76
|
+
ref={ref}
|
|
77
|
+
className={cn(
|
|
78
|
+
"flex cursor-default items-center justify-center py-1",
|
|
79
|
+
className
|
|
80
|
+
)}
|
|
81
|
+
{...props}
|
|
82
|
+
>
|
|
83
|
+
<ChevronDown className="size-4" />
|
|
84
|
+
</SelectPrimitive.ScrollDownButton>
|
|
85
|
+
))
|
|
86
|
+
SelectScrollDownButton.displayName =
|
|
87
|
+
SelectPrimitive.ScrollDownButton.displayName
|
|
88
|
+
|
|
89
|
+
const SelectContent = React.forwardRef<
|
|
90
|
+
React.ElementRef<typeof SelectPrimitive.Content>,
|
|
91
|
+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
|
|
92
|
+
>(({ className, children, position = "popper", ...props }, ref) => (
|
|
93
|
+
<SelectPrimitive.Portal>
|
|
94
|
+
<SelectPrimitive.Content
|
|
95
|
+
ref={ref}
|
|
96
|
+
className={cn(
|
|
97
|
+
"relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-lg border border-grey-200 bg-white text-main-950 shadow-md 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",
|
|
98
|
+
position === "popper" &&
|
|
99
|
+
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
|
|
100
|
+
className
|
|
101
|
+
)}
|
|
102
|
+
position={position}
|
|
103
|
+
{...props}
|
|
104
|
+
>
|
|
105
|
+
<SelectScrollUpButton />
|
|
106
|
+
<SelectPrimitive.Viewport
|
|
107
|
+
className={cn(
|
|
108
|
+
"p-1",
|
|
109
|
+
position === "popper" &&
|
|
110
|
+
"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
|
|
111
|
+
)}
|
|
112
|
+
>
|
|
113
|
+
{children}
|
|
114
|
+
</SelectPrimitive.Viewport>
|
|
115
|
+
<SelectScrollDownButton />
|
|
116
|
+
</SelectPrimitive.Content>
|
|
117
|
+
</SelectPrimitive.Portal>
|
|
118
|
+
))
|
|
119
|
+
SelectContent.displayName = SelectPrimitive.Content.displayName
|
|
120
|
+
|
|
121
|
+
const SelectLabel = React.forwardRef<
|
|
122
|
+
React.ElementRef<typeof SelectPrimitive.Label>,
|
|
123
|
+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
|
|
124
|
+
>(({ className, ...props }, ref) => (
|
|
125
|
+
<SelectPrimitive.Label
|
|
126
|
+
ref={ref}
|
|
127
|
+
className={cn("px-2 py-1.5 text-sm font-semibold text-grey-500", className)}
|
|
128
|
+
{...props}
|
|
129
|
+
/>
|
|
130
|
+
))
|
|
131
|
+
SelectLabel.displayName = SelectPrimitive.Label.displayName
|
|
132
|
+
|
|
133
|
+
const SelectItem = React.forwardRef<
|
|
134
|
+
React.ElementRef<typeof SelectPrimitive.Item>,
|
|
135
|
+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
|
|
136
|
+
>(({ className, children, ...props }, ref) => (
|
|
137
|
+
<SelectPrimitive.Item
|
|
138
|
+
ref={ref}
|
|
139
|
+
className={cn(
|
|
140
|
+
"relative flex w-full cursor-default select-none items-center rounded-md py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-grey-100 focus:text-main-950 data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
141
|
+
className
|
|
142
|
+
)}
|
|
143
|
+
{...props}
|
|
144
|
+
>
|
|
145
|
+
<span className="absolute right-2 flex size-3.5 items-center justify-center">
|
|
146
|
+
<SelectPrimitive.ItemIndicator>
|
|
147
|
+
<Check className="size-4" />
|
|
148
|
+
</SelectPrimitive.ItemIndicator>
|
|
149
|
+
</span>
|
|
150
|
+
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
|
|
151
|
+
</SelectPrimitive.Item>
|
|
152
|
+
))
|
|
153
|
+
SelectItem.displayName = SelectPrimitive.Item.displayName
|
|
154
|
+
|
|
155
|
+
const SelectSeparator = React.forwardRef<
|
|
156
|
+
React.ElementRef<typeof SelectPrimitive.Separator>,
|
|
157
|
+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
|
|
158
|
+
>(({ className, ...props }, ref) => (
|
|
159
|
+
<SelectPrimitive.Separator
|
|
160
|
+
ref={ref}
|
|
161
|
+
className={cn("-mx-1 my-1 h-px bg-grey-100", className)}
|
|
162
|
+
{...props}
|
|
163
|
+
/>
|
|
164
|
+
))
|
|
165
|
+
SelectSeparator.displayName = SelectPrimitive.Separator.displayName
|
|
166
|
+
|
|
167
|
+
export {
|
|
168
|
+
Select,
|
|
169
|
+
SelectGroup,
|
|
170
|
+
SelectValue,
|
|
171
|
+
SelectTrigger,
|
|
172
|
+
SelectContent,
|
|
173
|
+
SelectLabel,
|
|
174
|
+
SelectItem,
|
|
175
|
+
SelectSeparator,
|
|
176
|
+
SelectScrollUpButton,
|
|
177
|
+
SelectScrollDownButton,
|
|
178
|
+
selectTriggerVariants,
|
|
179
|
+
}
|
|
180
|
+
export type { SelectTriggerSize }
|