From 1a10dccc8de78268e2e4df5578625ecfa31d83eb Mon Sep 17 00:00:00 2001 From: Danijel Martinek Date: Mon, 6 Apr 2026 14:57:08 +0200 Subject: [PATCH] feat(ui): add Button, Input, Label atoms and FormField molecule with stories --- .../ui/src/atoms/button/button.stories.tsx | 38 +++++++++++++++++ packages/ui/src/atoms/button/button.tsx | 41 +++++++++++++++++++ packages/ui/src/atoms/button/index.ts | 1 + packages/ui/src/atoms/index.ts | 4 +- packages/ui/src/atoms/input/index.ts | 1 + packages/ui/src/atoms/input/input.stories.tsx | 19 +++++++++ packages/ui/src/atoms/input/input.tsx | 21 ++++++++++ packages/ui/src/atoms/label/index.ts | 1 + packages/ui/src/atoms/label/label.tsx | 20 +++++++++ .../form-field/form-field.stories.tsx | 31 ++++++++++++++ .../src/molecules/form-field/form-field.tsx | 31 ++++++++++++++ packages/ui/src/molecules/form-field/index.ts | 1 + packages/ui/src/molecules/index.ts | 2 +- 13 files changed, 209 insertions(+), 2 deletions(-) create mode 100644 packages/ui/src/atoms/button/button.stories.tsx create mode 100644 packages/ui/src/atoms/button/button.tsx create mode 100644 packages/ui/src/atoms/button/index.ts create mode 100644 packages/ui/src/atoms/input/index.ts create mode 100644 packages/ui/src/atoms/input/input.stories.tsx create mode 100644 packages/ui/src/atoms/input/input.tsx create mode 100644 packages/ui/src/atoms/label/index.ts create mode 100644 packages/ui/src/atoms/label/label.tsx create mode 100644 packages/ui/src/molecules/form-field/form-field.stories.tsx create mode 100644 packages/ui/src/molecules/form-field/form-field.tsx create mode 100644 packages/ui/src/molecules/form-field/index.ts diff --git a/packages/ui/src/atoms/button/button.stories.tsx b/packages/ui/src/atoms/button/button.stories.tsx new file mode 100644 index 0000000..958f932 --- /dev/null +++ b/packages/ui/src/atoms/button/button.stories.tsx @@ -0,0 +1,38 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { Button } from "./button.js"; + +const meta = { + title: "Atoms/Button", + component: Button, + tags: ["autodocs"], + argTypes: { + variant: { + control: "select", + options: ["default", "secondary", "destructive", "outline", "ghost"], + }, + size: { control: "select", options: ["sm", "default", "lg"] }, + }, +} satisfies Meta; +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + args: { children: "Button", variant: "default" }, +}; + +export const Secondary: Story = { + args: { children: "Secondary", variant: "secondary" }, +}; + +export const Destructive: Story = { + args: { children: "Destructive", variant: "destructive" }, +}; + +export const Outline: Story = { + args: { children: "Outline", variant: "outline" }, +}; + +export const Ghost: Story = { + args: { children: "Ghost", variant: "ghost" }, +}; diff --git a/packages/ui/src/atoms/button/button.tsx b/packages/ui/src/atoms/button/button.tsx new file mode 100644 index 0000000..bef3ba3 --- /dev/null +++ b/packages/ui/src/atoms/button/button.tsx @@ -0,0 +1,41 @@ +import { forwardRef, type ButtonHTMLAttributes } from "react"; +import { cn } from "../../lib/utils.js"; + +export interface ButtonProps extends ButtonHTMLAttributes { + variant?: "default" | "secondary" | "destructive" | "outline" | "ghost"; + size?: "sm" | "default" | "lg"; +} + +const variantStyles: Record, string> = { + default: "bg-primary text-primary-foreground hover:bg-primary/90", + secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80", + destructive: + "bg-destructive text-destructive-foreground hover:bg-destructive/90", + outline: + "border border-input bg-background hover:bg-accent hover:text-accent-foreground", + ghost: "hover:bg-accent hover:text-accent-foreground", +}; + +const sizeStyles: Record, string> = { + sm: "h-9 px-3 text-sm", + default: "h-10 px-4 py-2", + lg: "h-11 px-8 text-lg", +}; + +export const Button = forwardRef( + ({ className, variant = "default", size = "default", ...props }, ref) => { + return ( +