MDK Logo

Form components

Input and form control components for user interaction

Form components handle user input and form submission. All components are built with accessibility in mind and support keyboard navigation.

Prerequisites

Button

Configurable button with multiple variants, sizes, and loading state.

Import

import { Button } from '@mdk/core'

Props

PropTypeDefaultDescription
variant'primary' | 'secondary' | 'danger' | 'tertiary' | 'link' | 'icon' | 'outline' | 'ghost''secondary'Visual variant
size'sm' | 'md' | 'lg'noneButton size
loadingbooleanfalseShow loading spinner
fullWidthbooleanfalseExpand to container width
iconReactNodenoneIcon element
iconPosition'left' | 'right''left'Icon placement
disabledbooleanfalseDisable interaction

Basic usage

<Button>Default Button</Button>
<Button variant="primary">Primary</Button>
<Button variant="danger">Delete</Button>
<Button variant="outline">Outline</Button>

With icon

<Button icon={<PlusIcon />}>Add Item</Button>
<Button icon={<ArrowRightIcon />} iconPosition="right">
  Continue
</Button>

Loading state

<Button loading>Saving...</Button>
<Button variant="primary" loading disabled>
  Processing
</Button>

Styling

  • .mdk-button: Root element
  • .mdk-button--variant-{variant}: Variant modifier
  • .mdk-button--size-{size}: Size modifier
  • .mdk-button--full-width: Full width modifier
  • .mdk-button--loading: Loading state

Input

Text input with label support, prefix/suffix, and search variant.

Import

import { Input } from '@mdk/core'

Props

PropTypeDefaultDescription
labelstringnoneLabel displayed above input
variant'default' | 'search''default'Input variant
size'default' | 'medium''default'Input size
errorstringnoneError message (shows red border)
prefixReactNodenoneElement before input
suffixReactNodenoneElement after input
wrapperClassNamestringnoneWrapper element class

Basic usage

<Input label="Email" placeholder="Enter email" id="email" />
<Input variant="search" placeholder="Search miners..." />

With prefix/suffix

<Input prefix="$" suffix="USD" placeholder="0.00" />
<Input suffix="°C" placeholder="Temperature" />
<Input prefix={<UserIcon />} placeholder="Username" />

Error state

<Input
  label="MAC Address"
  error="Invalid MAC address format"
  value={mac}
  onChange={(e) => setMac(e.target.value)}
/>

Styling

  • .mdk-input: Input element
  • .mdk-input__wrapper: Wrapper container
  • .mdk-input__wrapper--error: Error state
  • .mdk-input__label: Label element
  • .mdk-input__prefix: Prefix element
  • .mdk-input__suffix: Suffix element
  • .mdk-input__error: Error message

Select

Dropdown select built on Radix UI primitives.

Import

import {
  Select,
  SelectTrigger,
  SelectValue,
  SelectContent,
  SelectItem,
  SelectGroup,
  SelectLabel,
} from '@mdk/core'

SelectTrigger props

PropTypeDefaultDescription
size'sm' | 'md' | 'lg''lg'Trigger size
variant'default' | 'colored''default'Visual variant
colorstringnoneCustom color for colored variant (hex)

Basic usage

<Select value={value} onValueChange={setValue}>
  <SelectTrigger>
    <SelectValue placeholder="Select option" />
  </SelectTrigger>
  <SelectContent>
    <SelectItem value="option1">Option 1</SelectItem>
    <SelectItem value="option2">Option 2</SelectItem>
    <SelectItem value="option3">Option 3</SelectItem>
  </SelectContent>
</Select>

With groups

<Select>
  <SelectTrigger size="md">
    <SelectValue placeholder="Select pool" />
  </SelectTrigger>
  <SelectContent>
    <SelectGroup>
      <SelectLabel>North America</SelectLabel>
      <SelectItem value="us-east">US East</SelectItem>
      <SelectItem value="us-west">US West</SelectItem>
    </SelectGroup>
    <SelectGroup>
      <SelectLabel>Europe</SelectLabel>
      <SelectItem value="eu-west">EU West</SelectItem>
    </SelectGroup>
  </SelectContent>
</Select>

Colored variant

<Select>
  <SelectTrigger variant="colored" color="#72F59E">
    <SelectValue placeholder="Status" />
  </SelectTrigger>
  <SelectContent>
    <SelectItem value="active">Active</SelectItem>
    <SelectItem value="inactive">Inactive</SelectItem>
  </SelectContent>
</Select>

Styling

  • .mdk-select__trigger: Trigger button
  • .mdk-select__trigger--{size}: Size modifier
  • .mdk-select__trigger--colored: Colored variant
  • .mdk-select__content: Dropdown content
  • .mdk-select__item: Option item

Checkbox

Checkbox input built on Radix UI primitives.

Import

import { Checkbox } from '@mdk/core'

Props

PropTypeDefaultDescription
size'xs' | 'sm' | 'md' | 'lg''md'Checkbox size
color'default' | 'primary' | 'success' | 'warning' | 'error''primary'Color when checked
radius'none' | 'small' | 'medium' | 'large' | 'full''none'Border radius
checkedboolean | 'indeterminate'noneChecked state (controlled)
onCheckedChangefunctionnoneChange callback

Basic usage

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

<label className="flex items-center gap-2">
  <Checkbox checked={terms} onCheckedChange={setTerms} />
  I agree to the terms
</label>

Sizes and colors

<Checkbox size="xs" />
<Checkbox size="sm" />
<Checkbox size="md" />
<Checkbox size="lg" color="success" />

Styling

  • .mdk-checkbox: Root element
  • .mdk-checkbox--{size}: Size modifier
  • .mdk-checkbox--{color}: Color modifier
  • .mdk-checkbox__indicator: Check mark container

Switch

Toggle switch for on/off states.

Import

import { Switch } from '@mdk/core'

Props

PropTypeDefaultDescription
size'sm' | 'md' | 'lg''md'Switch size
color'default' | 'primary' | 'success' | 'warning' | 'error''default'Color when checked
radius'none' | 'small' | 'medium' | 'large' | 'full''none'Border radius
checkedbooleannoneChecked state (controlled)
onCheckedChangefunctionnoneChange callback

Basic usage

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

<label className="flex items-center gap-2">
  <Switch checked={darkMode} onCheckedChange={setDarkMode} />
  Dark Mode
</label>

Sizes and colors

<Switch size="sm" />
<Switch size="md" color="primary" />
<Switch size="lg" color="success" />

Styling

  • .mdk-switch: Root element
  • .mdk-switch--{size}: Size modifier
  • .mdk-switch--{color}: Color modifier
  • .mdk-switch__thumb: Toggle thumb

ActionButton

Button with loading state and icon support for async actions.

Import

import { ActionButton } from '@mdk/core'

Basic usage

<ActionButton onClick={handleAction}>Save</ActionButton>
<ActionButton loading onClick={handleAction}>Processing</ActionButton>
<ActionButton icon={<CheckIcon />} onClick={handleAction}>Approve</ActionButton>

TextArea

Multi-line text input for longer content.

Import

import { TextArea } from '@mdk/core'

Basic usage

<TextArea
  label="Description"
  placeholder="Enter description"
  rows={4}
  value={value}
  onChange={(e) => setValue(e.target.value)}
/>

Cascader

Multi-level dropdown selector for hierarchical data.

Import

import { Cascader } from '@mdk/core'

Basic usage

<Cascader
  options={[
    {
      value: 'na',
      label: 'North America',
      children: [
        { value: 'us-east', label: 'US East' },
        { value: 'us-west', label: 'US West' },
      ],
    },
  ]}
  value={value}
  onChange={setValue}
/>

Radio

Radio button for single-select from a group.

Import

import { Radio, RadioGroup } from '@mdk/core'

Basic usage

<RadioGroup value={value} onValueChange={setValue}>
  <Radio value="small">Small</Radio>
  <Radio value="medium">Medium</Radio>
  <Radio value="large">Large</Radio>
</RadioGroup>

DatePicker

Calendar-based date selection input.

Import

import { DatePicker } from '@mdk/core'

Basic usage

<DatePicker
  value={date}
  onChange={setDate}
  placeholder="Select date"
/>

Slider

Range input for numeric values.

Import

import { Slider } from '@mdk/core'

Basic usage

<Slider
  value={[volume]}
  min={0}
  max={100}
  step={1}
  onValueChange={([v]) => setVolume(v)}
/>

Form

Form wrapper with validation and submission handling built on react-hook-form.

The package includes a complete form system built on react-hook-form.

Import

import {
  Form,
  FormField,
  FormItem,
  FormLabel,
  FormControl,
  FormDescription,
  FormMessage,
  useFormField,
} from '@mdk/core'

Pre-built form fields

import {
  FormInput,
  FormTextArea,
  FormSelect,
  FormCheckbox,
  FormSwitch,
  FormRadioGroup,
  FormDatePicker,
} from '@mdk/core'

Basic usage

import { useForm } from 'react-hook-form'
import { Form, FormField, FormItem, FormLabel, FormControl, FormMessage } from '@mdk/core'

function MyForm() {
  const form = useForm({
    defaultValues: { email: '' },
  })

  return (
    <Form {...form}>
      <form onSubmit={form.handleSubmit(onSubmit)}>
        <FormField
          control={form.control}
          name="email"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Email</FormLabel>
              <FormControl>
                <Input placeholder="email@example.com" {...field} />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />
        <Button type="submit">Submit</Button>
      </form>
    </Form>
  )
}

Built-in validators

import { validators, loginSchema, registerSchema } from '@mdk/core'

Label

Form field label with optional required indicator.

Import

import { Label } from '@mdk/core'

Basic usage

<Label htmlFor="email">Email</Label>
<Input id="email" type="email" />

<Label htmlFor="password" required>Password</Label>
<Input id="password" type="password" />

TagInput

Input for entering multiple tags.

Import

import { TagInput } from '@mdk/core'

Basic usage

<TagInput
  value={tags}
  onChange={setTags}
  placeholder="Add tags..."
/>

On this page