Skip to main content

Form Components

Form input components for building interactive forms with CyberPod styling.

Button

Versatile button component with multiple variants and sizes.

Preview

Live Editor
function ButtonDemo() {
  const [loading, setLoading] = React.useState(false);
  
  const handleClick = () => {
    setLoading(true);
    setTimeout(() => setLoading(false), 1500);
  };
  
  return (
    <div style={{ display: 'flex', flexWrap: 'wrap', gap: '12px', alignItems: 'center' }}>
      <button style={{
        padding: '10px 20px',
        borderRadius: '8px',
        background: 'linear-gradient(135deg, #8b5cf6 0%, #6366f1 100%)',
        color: 'white',
        border: 'none',
        cursor: 'pointer',
        fontWeight: 600,
      }}>
        Primary
      </button>
      <button style={{
        padding: '10px 20px',
        borderRadius: '8px',
        background: '#ef4444',
        color: 'white',
        border: 'none',
        cursor: 'pointer',
        fontWeight: 600,
      }}>
        Destructive
      </button>
      <button style={{
        padding: '10px 20px',
        borderRadius: '8px',
        background: 'white',
        border: '1px solid #e2e8f0',
        cursor: 'pointer',
        fontWeight: 600,
      }}>
        Outline
      </button>
      <button style={{
        padding: '10px 20px',
        borderRadius: '8px',
        background: '#f1f5f9',
        border: 'none',
        cursor: 'pointer',
        fontWeight: 600,
      }}>
        Secondary
      </button>
      <button style={{
        padding: '10px 20px',
        borderRadius: '8px',
        background: 'transparent',
        border: 'none',
        cursor: 'pointer',
        fontWeight: 600,
      }}>
        Ghost
      </button>
      <button
        onClick={handleClick}
        disabled={loading}
        style={{
          padding: '10px 20px',
          borderRadius: '8px',
          background: loading ? '#a78bfa' : 'linear-gradient(135deg, #8b5cf6 0%, #6366f1 100%)',
          color: 'white',
          border: 'none',
          cursor: loading ? 'not-allowed' : 'pointer',
          fontWeight: 600,
          opacity: loading ? 0.7 : 1,
        }}
      >
        {loading ? '⏳ Loading...' : 'Click to Load'}
      </button>
    </div>
  );
}
Result
Loading...

Usage

import { Button } from "@cpod/react";

// Basic button
<Button>Click me</Button>

// Variants
<Button variant="default">Primary</Button>
<Button variant="destructive">Delete</Button>
<Button variant="outline">Cancel</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="link">Link</Button>

// Sizes
<Button size="sm">Small</Button>
<Button size="default">Default</Button>
<Button size="lg">Large</Button>
<Button size="icon"><SearchIcon /></Button>

// Loading state
<Button loading disabled>Processing...</Button>

// As a link (using asChild)
<Button asChild>
<a href="/docs">View Docs</a>
</Button>

Props

PropTypeDefaultDescription
variantdefault | destructive | outline | secondary | ghost | linkdefaultVisual style
sizesm | default | lg | icondefaultButton size
loadingbooleanfalseShow loading spinner
asChildbooleanfalseRender as child element
disabledbooleanfalseDisable button

Input

Form input component with error states and variants.

Preview

Live Editor
function InputDemo() {
  const [value, setValue] = React.useState('');
  
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: '12px', maxWidth: '300px' }}>
      <input
        type="text"
        placeholder="Default input"
        value={value}
        onChange={(e) => setValue(e.target.value)}
        style={{
          padding: '10px 12px',
          borderRadius: '8px',
          border: '1px solid #e2e8f0',
          fontSize: '14px',
          outline: 'none',
        }}
      />
      <input
        type="email"
        placeholder="Email input"
        style={{
          padding: '10px 12px',
          borderRadius: '8px',
          border: '1px solid #e2e8f0',
          fontSize: '14px',
          outline: 'none',
        }}
      />
      <input
        type="text"
        placeholder="Error state"
        style={{
          padding: '10px 12px',
          borderRadius: '8px',
          border: '1px solid #ef4444',
          fontSize: '14px',
          outline: 'none',
          background: '#fef2f2',
        }}
      />
      <input
        type="text"
        placeholder="Disabled input"
        disabled
        style={{
          padding: '10px 12px',
          borderRadius: '8px',
          border: '1px solid #e2e8f0',
          fontSize: '14px',
          outline: 'none',
          background: '#f8fafc',
          cursor: 'not-allowed',
          opacity: 0.6,
        }}
      />
    </div>
  );
}
Result
Loading...

Usage

import { Input } from "@cpod/react";

// Basic input
<Input placeholder="Enter your email" />

// With type
<Input type="email" placeholder="user@example.com" />
<Input type="password" placeholder="••••••••" />
<Input type="number" placeholder="Enter amount" />

// Error state
<Input error placeholder="This field has an error" />

// Different sizes
<Input size="sm" placeholder="Small input" />
<Input size="md" placeholder="Medium input" />
<Input size="lg" placeholder="Large input" />

// Variants
<Input variant="default" placeholder="Default" />
<Input variant="outline" placeholder="Outline" />
<Input variant="ghost" placeholder="Ghost" />

// Disabled
<Input disabled placeholder="Disabled input" />

Props

PropTypeDefaultDescription
variantdefault | outline | ghostdefaultVisual style
sizesm | md | lgmdInput size
errorbooleanfalseShow error state
typestringtextHTML input type
disabledbooleanfalseDisable input
placeholderstring-Placeholder text

Textarea

Multi-line text input component.

Preview

Live Editor
function TextareaDemo() {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: '12px', maxWidth: '400px' }}>
      <textarea 
        placeholder="Write your message here..."
        rows={4}
        style={{
          width: '100%',
          padding: '12px',
          borderRadius: '16px',
          border: '1px solid #e2e8f0',
          fontSize: '14px',
          fontFamily: 'inherit',
          resize: 'vertical',
        }}
      />
    </div>
  );
}
Result
Loading...

Usage

import { Textarea } from "@cpod/react";

// Basic textarea
<Textarea placeholder="Enter your message..." />

// With custom rows
<Textarea rows={5} placeholder="Longer text area" />

// Disabled state
<Textarea disabled placeholder="Read-only content" />

Props

PropTypeDefaultDescription
placeholderstring-Placeholder text
rowsnumber-Number of visible rows
disabledbooleanfalseDisable input
classNamestring-Additional CSS classes

Select

Dropdown select component with full keyboard navigation.

Preview

Live Editor
function SelectDemo() {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: '12px', maxWidth: '300px' }}>
      <select style={{
        width: '100%',
        padding: '10px 16px',
        borderRadius: '16px',
        border: '1px solid #e2e8f0',
        fontSize: '14px',
        fontFamily: 'inherit',
        backgroundColor: 'white',
        cursor: 'pointer',
      }}>
        <option value="">Select a fruit...</option>
        <option value="apple">Apple</option>
        <option value="banana">Banana</option>
        <option value="orange">Orange</option>
        <option value="grape">Grape</option>
      </select>
    </div>
  );
}
Result
Loading...

Usage

import {
Select,
SelectTrigger,
SelectValue,
SelectContent,
SelectItem,
SelectGroup,
SelectLabel,
SelectSeparator,
} from "@cpod/react";

// Basic select
<Select>
<SelectTrigger>
<SelectValue placeholder="Select a fruit..." />
</SelectTrigger>
<SelectContent>
<SelectItem value="apple">Apple</SelectItem>
<SelectItem value="banana">Banana</SelectItem>
<SelectItem value="orange">Orange</SelectItem>
</SelectContent>
</Select>

// With groups
<Select>
<SelectTrigger className="w-[200px]">
<SelectValue placeholder="Select a category..." />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>Fruits</SelectLabel>
<SelectItem value="apple">Apple</SelectItem>
<SelectItem value="banana">Banana</SelectItem>
</SelectGroup>
<SelectSeparator />
<SelectGroup>
<SelectLabel>Vegetables</SelectLabel>
<SelectItem value="carrot">Carrot</SelectItem>
<SelectItem value="potato">Potato</SelectItem>
</SelectGroup>
</SelectContent>
</Select>

Sub-components

ComponentDescription
SelectRoot component
SelectTriggerButton that opens the select
SelectValueDisplays selected value
SelectContentDropdown content container
SelectItemIndividual option
SelectGroupGroup of options
SelectLabelLabel for a group
SelectSeparatorVisual separator

Checkbox

Checkbox input for boolean values.

Preview

Live Editor
function CheckboxDemo() {
  const [checked, setChecked] = React.useState(false);
  
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
      <label style={{ display: 'flex', alignItems: 'center', gap: '8px', cursor: 'pointer' }}>
        <input 
          type="checkbox"
          checked={checked}
          onChange={(e) => setChecked(e.target.checked)}
          style={{ width: '16px', height: '16px', accentColor: '#8b5cf6' }}
        />
        <span>Accept terms and conditions</span>
      </label>
      <label style={{ display: 'flex', alignItems: 'center', gap: '8px', cursor: 'pointer' }}>
        <input 
          type="checkbox"
          defaultChecked
          style={{ width: '16px', height: '16px', accentColor: '#8b5cf6' }}
        />
        <span>Subscribe to newsletter</span>
      </label>
    </div>
  );
}
Result
Loading...

Usage

import { Checkbox } from "@cpod/react";

// Basic checkbox
<Checkbox id="terms" />

// With label
<div className="flex items-center space-x-2">
<Checkbox id="terms" />
<label htmlFor="terms">Accept terms and conditions</label>
</div>

// Controlled
const [checked, setChecked] = useState(false);

<Checkbox
checked={checked}
onCheckedChange={setChecked}
/>

Props

PropTypeDefaultDescription
checkedboolean-Controlled checked state
defaultCheckedbooleanfalseDefault checked state
onCheckedChange(checked: boolean) => void-Change handler
disabledbooleanfalseDisable checkbox

RadioGroup

Radio button group for single selection.

Preview

Live Editor
function RadioGroupDemo() {
  const [value, setValue] = React.useState('option1');
  
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
      {['option1', 'option2', 'option3'].map((option) => (
        <label key={option} style={{ display: 'flex', alignItems: 'center', gap: '8px', cursor: 'pointer' }}>
          <input 
            type="radio"
            name="options"
            value={option}
            checked={value === option}
            onChange={(e) => setValue(e.target.value)}
            style={{ width: '16px', height: '16px', accentColor: '#8b5cf6' }}
          />
          <span>Option {option.slice(-1)}</span>
        </label>
      ))}
    </div>
  );
}
Result
Loading...

Usage

import { RadioGroup, RadioGroupItem } from "@cpod/react";
import { Label } from "@cpod/react";

<RadioGroup defaultValue="option1">
<div className="flex items-center space-x-2">
<RadioGroupItem value="option1" id="r1" />
<Label htmlFor="r1">Option 1</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="option2" id="r2" />
<Label htmlFor="r2">Option 2</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="option3" id="r3" />
<Label htmlFor="r3">Option 3</Label>
</div>
</RadioGroup>

Props

RadioGroup:

PropTypeDefaultDescription
valuestring-Controlled value
defaultValuestring-Default value
onValueChange(value: string) => void-Change handler
disabledbooleanfalseDisable all items

Switch

Toggle switch for on/off states.

Preview

Live Editor
function SwitchDemo() {
  const [enabled, setEnabled] = React.useState(false);
  
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
      <label style={{ display: 'flex', alignItems: 'center', gap: '12px', cursor: 'pointer' }}>
        <button
          onClick={() => setEnabled(!enabled)}
          style={{
            width: '42px',
            height: '22px',
            borderRadius: '11px',
            border: 'none',
            backgroundColor: enabled ? '#8b5cf6' : '#94a3b8',
            position: 'relative',
            cursor: 'pointer',
            transition: 'background-color 0.2s',
          }}
        >
          <span style={{
            position: 'absolute',
            top: '3px',
            left: enabled ? '23px' : '3px',
            width: '16px',
            height: '16px',
            borderRadius: '50%',
            backgroundColor: 'white',
            transition: 'left 0.2s',
            boxShadow: '0 1px 2px rgba(0,0,0,0.25)',
          }} />
        </button>
        <span>Enable notifications</span>
      </label>
    </div>
  );
}
Result
Loading...

Usage

import { Switch } from "@cpod/react";
import { Label } from "@cpod/react";

// Basic switch
<Switch />

// With label
<div className="flex items-center space-x-2">
<Switch id="airplane-mode" />
<Label htmlFor="airplane-mode">Airplane Mode</Label>
</div>

// Controlled
const [enabled, setEnabled] = useState(false);

<Switch
checked={enabled}
onCheckedChange={setEnabled}
/>

Props

PropTypeDefaultDescription
checkedboolean-Controlled state
defaultCheckedbooleanfalseDefault state
onCheckedChange(checked: boolean) => void-Change handler
disabledbooleanfalseDisable switch

Slider

Range slider for numeric values.

Preview

Live Editor
function SliderDemo() {
  const [value, setValue] = React.useState(50);
  
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: '16px', maxWidth: '300px' }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: '14px' }}>
        <span>Volume</span>
        <span>{value}%</span>
      </div>
      <input
        type="range"
        min="0"
        max="100"
        value={value}
        onChange={(e) => setValue(parseInt(e.target.value))}
        style={{
          width: '100%',
          height: '8px',
          borderRadius: '4px',
          accentColor: '#8b5cf6',
        }}
      />
    </div>
  );
}
Result
Loading...

Usage

import { Slider } from "@cpod/react";

// Basic slider
<Slider defaultValue={[50]} max={100} step={1} />

// With range
<Slider defaultValue={[25, 75]} max={100} step={1} />

// Controlled
const [value, setValue] = useState([50]);

<Slider value={value} onValueChange={setValue} />

Props

PropTypeDefaultDescription
valuenumber[]-Controlled value
defaultValuenumber[]-Default value
onValueChange(value: number[]) => void-Change handler
minnumber0Minimum value
maxnumber100Maximum value
stepnumber1Step increment
disabledbooleanfalseDisable slider

Label

Form label component for accessibility.

Preview

Live Editor
function LabelDemo() {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: '16px', maxWidth: '300px' }}>
      <div style={{ display: 'flex', flexDirection: 'column', gap: '6px' }}>
        <label style={{ fontSize: '14px', fontWeight: 500 }}>Email</label>
        <input 
          type="email"
          placeholder="you@example.com"
          style={{
            padding: '10px 12px',
            borderRadius: '8px',
            border: '1px solid #e2e8f0',
            fontSize: '14px',
          }}
        />
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: '6px' }}>
        <label style={{ fontSize: '14px', fontWeight: 500 }}>Password</label>
        <input 
          type="password"
          placeholder="••••••••"
          style={{
            padding: '10px 12px',
            borderRadius: '8px',
            border: '1px solid #e2e8f0',
            fontSize: '14px',
          }}
        />
      </div>
    </div>
  );
}
Result
Loading...

Usage

import { Label } from "@cpod/react";
import { Input, Checkbox } from "@cpod/react";

// With input
<div className="grid gap-2">
<Label htmlFor="email">Email</Label>
<Input id="email" type="email" placeholder="Enter your email" />
</div>

// With checkbox
<div className="flex items-center space-x-2">
<Checkbox id="terms" />
<Label htmlFor="terms">Accept terms and conditions</Label>
</div>

Props

PropTypeDefaultDescription
htmlForstring-Associated input ID
classNamestring-Additional CSS classes

Complete Form Example

Here's a comprehensive example showing how all form components work together:

import {
Button,
Input,
Textarea,
Select,
SelectTrigger,
SelectValue,
SelectContent,
SelectItem,
Checkbox,
RadioGroup,
RadioGroupItem,
Switch,
Slider,
Label,
Card,
CardHeader,
CardTitle,
CardDescription,
CardContent,
CardFooter,
} from "@cpod/react";

function SettingsForm() {
const [notifications, setNotifications] = useState(true);
const [volume, setVolume] = useState([50]);

const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
// Handle form submission
};

return (
<Card className="w-full max-w-lg">
<CardHeader>
<CardTitle>Account Settings</CardTitle>
<CardDescription>
Update your account preferences and settings.
</CardDescription>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit} className="space-y-6">
{/* Text Input */}
<div className="space-y-2">
<Label htmlFor="name">Display Name</Label>
<Input id="name" placeholder="Enter your name" />
</div>

{/* Email Input */}
<div className="space-y-2">
<Label htmlFor="email">Email</Label>
<Input id="email" type="email" placeholder="you@example.com" />
</div>

{/* Textarea */}
<div className="space-y-2">
<Label htmlFor="bio">Bio</Label>
<Textarea id="bio" placeholder="Tell us about yourself..." rows={3} />
</div>

{/* Select */}
<div className="space-y-2">
<Label>Timezone</Label>
<Select>
<SelectTrigger>
<SelectValue placeholder="Select timezone" />
</SelectTrigger>
<SelectContent>
<SelectItem value="utc">UTC</SelectItem>
<SelectItem value="est">Eastern Time</SelectItem>
<SelectItem value="pst">Pacific Time</SelectItem>
</SelectContent>
</Select>
</div>

{/* Radio Group */}
<div className="space-y-2">
<Label>Preferred Contact</Label>
<RadioGroup defaultValue="email">
<div className="flex items-center space-x-2">
<RadioGroupItem value="email" id="contact-email" />
<Label htmlFor="contact-email">Email</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="sms" id="contact-sms" />
<Label htmlFor="contact-sms">SMS</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="push" id="contact-push" />
<Label htmlFor="contact-push">Push Notification</Label>
</div>
</RadioGroup>
</div>

{/* Checkbox */}
<div className="flex items-center space-x-2">
<Checkbox id="marketing" />
<Label htmlFor="marketing">Receive marketing emails</Label>
</div>

{/* Switch */}
<div className="flex items-center justify-between">
<Label htmlFor="notifications">Enable Notifications</Label>
<Switch
id="notifications"
checked={notifications}
onCheckedChange={setNotifications}
/>
</div>

{/* Slider */}
<div className="space-y-2">
<div className="flex justify-between">
<Label>Notification Volume</Label>
<span className="text-sm text-muted-foreground">{volume[0]}%</span>
</div>
<Slider
value={volume}
onValueChange={setVolume}
max={100}
step={1}
/>
</div>
</form>
</CardContent>
<CardFooter className="flex justify-end gap-2">
<Button variant="outline">Cancel</Button>
<Button type="submit">Save Changes</Button>
</CardFooter>
</Card>
);
}

This example demonstrates:

  • ✅ Text and email inputs with labels
  • ✅ Textarea for longer content
  • ✅ Select dropdown with options
  • ✅ Radio buttons for single selection
  • ✅ Checkbox for boolean toggles
  • ✅ Switch for on/off settings
  • ✅ Slider for numeric values
  • ✅ Card container for form layout
  • ✅ Proper form submission handling