Skip to content
This repository has been archived by the owner on Jan 13, 2024. It is now read-only.

Commit

Permalink
feat: add Select component
Browse files Browse the repository at this point in the history
  • Loading branch information
MikaelSiidorow committed Jul 22, 2023
1 parent 2a866da commit fa78cbf
Show file tree
Hide file tree
Showing 9 changed files with 548 additions and 105 deletions.
3 changes: 2 additions & 1 deletion .storybook/preview.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ export const parameters = {
color: /(background|color)$/i,
date: /Date$/
}
}
},
layout: "centered"
};
29 changes: 29 additions & 0 deletions lib/components/Select/Select.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type { Meta, StoryFn } from "@storybook/react";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "~/components/Select";

/**
* ```typescript
* import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@tietokilta/ui";
* ```
*/
export default {
title: "Select",
component: Select
} satisfies Meta<typeof Select>;

const Template: StoryFn<typeof Select> = (args) => (
<Select {...args}>
<SelectTrigger>
<SelectValue placeholder="Year" />
</SelectTrigger>
<SelectContent>
{Array.from({ length: 37 }).map((_, i) => (
<SelectItem value={(2023 - i).toString()} key={i} disabled={i > 1 && i < 4}>
{2023 - i}
</SelectItem>
))}
</SelectContent>
</Select>
);

export const Primary = Template.bind({});
15 changes: 15 additions & 0 deletions lib/components/Select/Select.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { render, screen } from "@testing-library/react";
import { Select, SelectTrigger, SelectValue } from "~/components/Select";

describe("Select", () => {
it("should display placeholder text", () => {
render(
<Select>
<SelectTrigger>
<SelectValue placeholder="Placeholder" />
</SelectTrigger>
</Select>
);
expect(screen.getByRole("combobox")).toHaveTextContent("Placeholder");
});
});
76 changes: 76 additions & 0 deletions lib/components/Select/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import * as SelectPrimitive from "@radix-ui/react-select";
import { ChevronDown, ChevronUp } from "lucide-react";
import * as React from "react";
import { cn } from "~/utils";

const Select = SelectPrimitive.Root;
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 w-full items-center justify-between gap-1 rounded-lg border-2 border-gray-900 bg-gray-100 px-2 py-1 drop-shadow-[4px_4px_black] hover:bg-gray-300 focus-visible:bg-gray-200 focus-visible:outline focus-visible:outline-2 focus-visible:outline-gray-900 disabled:cursor-not-allowed disabled:opacity-50 data-[placeholder]:text-gray-600",
className
)}
{...props}
>
{children}
<SelectPrimitive.Icon asChild>
<ChevronDown className="h-4 w-4" />
</SelectPrimitive.Icon>
</SelectPrimitive.Trigger>
));
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;

const SelectContent = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
>(({ className, children, ...props }, ref) => (
<SelectPrimitive.Portal>
<SelectPrimitive.Content
ref={ref}
className={cn(
"relative z-50 overflow-hidden 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",
"rounded-lg border-2 border-gray-900 bg-gray-100 p-2 drop-shadow-[4px_4px_black]",
className
)}
{...props}
>
<SelectPrimitive.ScrollUpButton
className={"flex h-6 cursor-default items-center justify-center bg-gray-100 text-gray-900"}
>
<ChevronUp className="h-4 w-4" />
</SelectPrimitive.ScrollUpButton>
<SelectPrimitive.Viewport>{children}</SelectPrimitive.Viewport>
<SelectPrimitive.ScrollDownButton
className={"flex h-6 cursor-default items-center justify-center bg-gray-100 text-gray-900"}
>
<ChevronDown className="h-4 w-4" />
</SelectPrimitive.ScrollDownButton>
</SelectPrimitive.Content>
</SelectPrimitive.Portal>
));
SelectContent.displayName = SelectPrimitive.Content.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 gap-1 px-2 py-1 outline-none data-[disabled]:pointer-events-none data-[highlighted]:data-[state=unchecked]:bg-gray-300 data-[state=checked]:bg-gray-300 data-[state=checked]:font-medium data-[disabled]:text-gray-400 data-[highlighted]:outline-none",
className
)}
{...props}
>
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
</SelectPrimitive.Item>
));
SelectItem.displayName = SelectPrimitive.Item.displayName;

export { Select, SelectContent, SelectItem, SelectTrigger, SelectValue };
1 change: 1 addition & 0 deletions lib/main.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { default as Button, type ButtonProps } from "~/components/Button";
export * as Select from "~/components/Select";
export * from "~/components/Tabs";
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,13 @@
"test": "vitest"
},
"dependencies": {
"@radix-ui/react-select": "^1.2.2",
"@radix-ui/react-tabs": "1.0.4",
"class-variance-authority": "^0.7.0",
"clsx": "^2.0.0",
"tailwind-merge": "^1.14.0"
"lucide-react": "^0.263.0",
"tailwind-merge": "^1.14.0",
"tailwindcss-animate": "^1.0.6"
},
"devDependencies": {
"@commitlint/cli": "^17.6.7",
Expand Down
Loading

0 comments on commit fa78cbf

Please sign in to comment.