-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
4 changed files
with
333 additions
and
0 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import type { Meta, StoryObj } from "@storybook/react"; | ||
import { | ||
Select, | ||
SelectContent, | ||
SelectItem, | ||
SelectTrigger, | ||
SelectValue, | ||
SelectGroup, | ||
SelectLabel, | ||
} from "@/foundations/select" | ||
|
||
const meta: Meta = { | ||
component: Select, | ||
title: "Foundations / select", | ||
parameters: { | ||
layout: "centered", | ||
}, | ||
tags: ["autodocs"], | ||
} | ||
|
||
export default meta; | ||
type Story = StoryObj<typeof meta>; | ||
|
||
export const Basic: Story = { | ||
render: () => { | ||
return ( | ||
<Select> | ||
<SelectTrigger className="w-[180px]"> | ||
<SelectValue placeholder="Theme" /> | ||
</SelectTrigger> | ||
<SelectContent> | ||
<SelectItem value="light">Light</SelectItem> | ||
<SelectItem value="dark">Dark</SelectItem> | ||
<SelectItem value="system">System</SelectItem> | ||
</SelectContent> | ||
</Select> | ||
) | ||
} | ||
}; | ||
|
||
export const Scrollable: Story = { | ||
render: () => { | ||
return ( | ||
<Select> | ||
<SelectTrigger className="w-[280px]"> | ||
<SelectValue placeholder="Select a timezone" /> | ||
</SelectTrigger> | ||
<SelectContent> | ||
<SelectGroup> | ||
<SelectLabel>North America</SelectLabel> | ||
<SelectItem value="est">Eastern Standard Time (EST)</SelectItem> | ||
<SelectItem value="cst">Central Standard Time (CST)</SelectItem> | ||
<SelectItem value="mst">Mountain Standard Time (MST)</SelectItem> | ||
<SelectItem value="pst">Pacific Standard Time (PST)</SelectItem> | ||
<SelectItem value="akst">Alaska Standard Time (AKST)</SelectItem> | ||
<SelectItem value="hst">Hawaii Standard Time (HST)</SelectItem> | ||
</SelectGroup> | ||
<SelectGroup> | ||
<SelectLabel>Europe & Africa</SelectLabel> | ||
<SelectItem value="gmt">Greenwich Mean Time (GMT)</SelectItem> | ||
<SelectItem value="cet">Central European Time (CET)</SelectItem> | ||
<SelectItem value="eet">Eastern European Time (EET)</SelectItem> | ||
<SelectItem value="west"> | ||
Western European Summer Time (WEST) | ||
</SelectItem> | ||
<SelectItem value="cat">Central Africa Time (CAT)</SelectItem> | ||
<SelectItem value="eat">East Africa Time (EAT)</SelectItem> | ||
</SelectGroup> | ||
<SelectGroup> | ||
<SelectLabel>Asia</SelectLabel> | ||
<SelectItem value="msk">Moscow Time (MSK)</SelectItem> | ||
<SelectItem value="ist">India Standard Time (IST)</SelectItem> | ||
<SelectItem value="cst_china">China Standard Time (CST)</SelectItem> | ||
<SelectItem value="jst">Japan Standard Time (JST)</SelectItem> | ||
<SelectItem value="kst">Korea Standard Time (KST)</SelectItem> | ||
<SelectItem value="ist_indonesia"> | ||
Indonesia Central Standard Time (WITA) | ||
</SelectItem> | ||
</SelectGroup> | ||
<SelectGroup> | ||
<SelectLabel>Australia & Pacific</SelectLabel> | ||
<SelectItem value="awst"> | ||
Australian Western Standard Time (AWST) | ||
</SelectItem> | ||
<SelectItem value="acst"> | ||
Australian Central Standard Time (ACST) | ||
</SelectItem> | ||
<SelectItem value="aest"> | ||
Australian Eastern Standard Time (AEST) | ||
</SelectItem> | ||
<SelectItem value="nzst">New Zealand Standard Time (NZST)</SelectItem> | ||
<SelectItem value="fjt">Fiji Time (FJT)</SelectItem> | ||
</SelectGroup> | ||
<SelectGroup> | ||
<SelectLabel>South America</SelectLabel> | ||
<SelectItem value="art">Argentina Time (ART)</SelectItem> | ||
<SelectItem value="bot">Bolivia Time (BOT)</SelectItem> | ||
<SelectItem value="brt">Brasilia Time (BRT)</SelectItem> | ||
<SelectItem value="clt">Chile Standard Time (CLT)</SelectItem> | ||
</SelectGroup> | ||
</SelectContent> | ||
</Select> | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
"use client" | ||
|
||
import * as React from "react" | ||
import * as SelectPrimitive from "@radix-ui/react-select" | ||
import { Check, ChevronDown, ChevronUp } from "lucide-react" | ||
|
||
import { cn } from "@/lib/utils" | ||
|
||
const Select = SelectPrimitive.Root | ||
|
||
const SelectGroup = SelectPrimitive.Group | ||
|
||
const SelectValue = SelectPrimitive.Value | ||
|
||
const SelectTrigger = React.forwardRef< | ||
React.ElementRef<typeof SelectPrimitive.Trigger>, | ||
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger> | ||
>(({ className, children, ...props }, ref) => ( | ||
<SelectPrimitive.Trigger | ||
ref={ref} | ||
className={cn( | ||
"flex h-10 w-full items-center justify-between rounded-lg border-2 border-input bg-background px-3 py-2 text-sm transition-colors hover:border-input-hover focus-visible:border-input-hover ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1 disabled:bg-muted", | ||
className | ||
)} | ||
{...props} | ||
> | ||
{children} | ||
<SelectPrimitive.Icon asChild> | ||
<ChevronDown className="h-4 w-4 opacity-50" /> | ||
</SelectPrimitive.Icon> | ||
</SelectPrimitive.Trigger> | ||
)) | ||
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName | ||
|
||
const SelectScrollUpButton = React.forwardRef< | ||
React.ElementRef<typeof SelectPrimitive.ScrollUpButton>, | ||
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton> | ||
>(({ className, ...props }, ref) => ( | ||
<SelectPrimitive.ScrollUpButton | ||
ref={ref} | ||
className={cn( | ||
"flex cursor-default items-center justify-center py-1", | ||
className | ||
)} | ||
{...props} | ||
> | ||
<ChevronUp className="h-4 w-4 text-secondary-foreground" /> | ||
</SelectPrimitive.ScrollUpButton> | ||
)) | ||
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName | ||
|
||
const SelectScrollDownButton = React.forwardRef< | ||
React.ElementRef<typeof SelectPrimitive.ScrollDownButton>, | ||
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton> | ||
>(({ className, ...props }, ref) => ( | ||
<SelectPrimitive.ScrollDownButton | ||
ref={ref} | ||
className={cn( | ||
"flex cursor-default items-center justify-center py-1", | ||
className | ||
)} | ||
{...props} | ||
> | ||
<ChevronDown className="h-4 w-4 text-secondary-foreground" /> | ||
</SelectPrimitive.ScrollDownButton> | ||
)) | ||
SelectScrollDownButton.displayName = | ||
SelectPrimitive.ScrollDownButton.displayName | ||
|
||
const SelectContent = React.forwardRef< | ||
React.ElementRef<typeof SelectPrimitive.Content>, | ||
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content> | ||
>(({ className, children, position = "popper", ...props }, ref) => ( | ||
<SelectPrimitive.Portal> | ||
<SelectPrimitive.Content | ||
ref={ref} | ||
className={cn( | ||
"relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-lg border bg-popover text-popover-foreground shadow-lg 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", | ||
position === "popper" && | ||
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1", | ||
className | ||
)} | ||
position={position} | ||
{...props} | ||
> | ||
<SelectScrollUpButton /> | ||
<SelectPrimitive.Viewport | ||
className={cn( | ||
"p-1", | ||
position === "popper" && | ||
"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]" | ||
)} | ||
> | ||
{children} | ||
</SelectPrimitive.Viewport> | ||
<SelectScrollDownButton /> | ||
</SelectPrimitive.Content> | ||
</SelectPrimitive.Portal> | ||
)) | ||
SelectContent.displayName = SelectPrimitive.Content.displayName | ||
|
||
const SelectLabel = React.forwardRef< | ||
React.ElementRef<typeof SelectPrimitive.Label>, | ||
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label> | ||
>(({ className, ...props }, ref) => ( | ||
<SelectPrimitive.Label | ||
ref={ref} | ||
className={cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className)} | ||
{...props} | ||
/> | ||
)) | ||
SelectLabel.displayName = SelectPrimitive.Label.displayName | ||
|
||
const SelectItem = React.forwardRef< | ||
React.ElementRef<typeof SelectPrimitive.Item>, | ||
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item> | ||
>(({ className, children, ...props }, ref) => ( | ||
<SelectPrimitive.Item | ||
ref={ref} | ||
className={cn( | ||
"relative flex w-full cursor-default select-none items-center rounded-md py-2 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50", | ||
className | ||
)} | ||
{...props} | ||
> | ||
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center"> | ||
<SelectPrimitive.ItemIndicator> | ||
<Check className="h-4 w-4" /> | ||
</SelectPrimitive.ItemIndicator> | ||
</span> | ||
|
||
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText> | ||
</SelectPrimitive.Item> | ||
)) | ||
SelectItem.displayName = SelectPrimitive.Item.displayName | ||
|
||
const SelectSeparator = React.forwardRef< | ||
React.ElementRef<typeof SelectPrimitive.Separator>, | ||
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator> | ||
>(({ className, ...props }, ref) => ( | ||
<SelectPrimitive.Separator | ||
ref={ref} | ||
className={cn("-mx-1 my-1 h-px bg-muted", className)} | ||
{...props} | ||
/> | ||
)) | ||
SelectSeparator.displayName = SelectPrimitive.Separator.displayName | ||
|
||
export { | ||
Select, | ||
SelectGroup, | ||
SelectValue, | ||
SelectTrigger, | ||
SelectContent, | ||
SelectLabel, | ||
SelectItem, | ||
SelectSeparator, | ||
SelectScrollUpButton, | ||
SelectScrollDownButton, | ||
} |