Component Library

EduNest ships a typed, reusable component library in src/components — an admin UI kit (components/admin) and a 30+ field form kit (components/form). Each component is shown individually below — interact with it, then copy its snippet.

Buttons

Btn

Four variants (primary, secondary, danger, ghost), two sizes, and a loading state.

import { Btn } from "@/components/admin/ui";

<Btn>Primary</Btn>
<Btn variant="secondary">Secondary</Btn>
<Btn variant="danger">Danger</Btn>
<Btn variant="ghost">Ghost</Btn>
<Btn size="sm">Small</Btn>
<Btn loading>Saving…</Btn>

Text Fields

The input family extends native input props — value is a string, onChange is the native change event.

InputField

Labelled single-line text input with optional icon, helper text and error state.

import { InputField } from "@/components/form";

<InputField label="Full name" value={v}
  onChange={(e) => setV(e.target.value)} />

EmailField

Email input with built-in format validation.

import { EmailField } from "@/components/form";

<EmailField label="Email" value={v}
  onChange={(e) => setV(e.target.value)} />

PasswordField

Password input with a show/hide reveal toggle.

import { PasswordField } from "@/components/form";

<PasswordField label="Password" value={v}
  onChange={(e) => setV(e.target.value)} />

UrlField

URL input that normalises and validates web addresses.

import { UrlField } from "@/components/form";

<UrlField label="Website" value={v}
  onChange={(e) => setV(e.target.value)} />

NumberField

Numeric input with min/max/step and stepper buttons.

import { NumberField } from "@/components/form";

<NumberField label="Seats" min={0} value={v}
  onChange={(e) => setV(e.target.value)} />

PhoneField

Phone input with a country-code selector.

import { PhoneField } from "@/components/form";

<PhoneField label="Phone" value={v}
  onChange={(e) => setV(e.target.value)} />

TextareaField

Multi-line text input with an optional character limit.

import { TextareaField } from "@/components/form";

<TextareaField label="Bio" rows={3} value={v}
  onChange={(e) => setV(e.target.value)} />

Selects

Dropdowns bound to an options array; onChange yields the selected value(s).

SelectField

Single-choice dropdown.

import { SelectField } from "@/components/form";

<SelectField label="Status" value={v}
  onChange={(v) => setV(v ?? "")} options={opts} />

SearchableSelectField

Single-choice dropdown with a type-to-filter search box.

import { SearchableSelectField } from "@/components/form";

<SearchableSelectField label="Level" value={v}
  onChange={(v) => setV(v ?? "")} options={opts} />

MultiSelectField

Multi-choice dropdown that returns an array of values.

import { MultiSelectField } from "@/components/form";

<MultiSelectField label="Tags" value={v}
  onChange={setV} options={opts} />

Toggles, Checkboxes & Radios

SwitchField

On/off toggle with a label and optional helper text.

Active

Toggle this on or off.

import { SwitchField } from "@/components/form";

<SwitchField label="Active" checked={on} onChange={setOn} />

CheckboxField

A single boolean checkbox (event-based onChange).

import { CheckboxField } from "@/components/form";

<CheckboxField checked={c}
  onChange={(e) => setC(e.currentTarget.checked)} label="Featured" />

CheckboxGroupField

A group of checkboxes returning the selected values as an array.

|
import { CheckboxGroupField } from "@/components/form";

<CheckboxGroupField label="Show on" value={v}
  onChange={setV} options={opts} />

RadioGroupField

A single-choice radio group.

import { RadioGroupField } from "@/components/form";

<RadioGroupField label="Level" value={v}
  onChange={setV} options={opts} />

Tags, Rating, Range & Color

TagField

Free-form tag entry rendered as removable chips.

mathalgebra
import { TagField } from "@/components/form";

<TagField label="Tags" value={tags} onChange={setTags} />

RatingField

Star rating selector.

4/5
import { RatingField } from "@/components/form";

<RatingField label="Rating" value={n} onChange={setN} />

RangeField

Slider for a single value or a [min, max] range.

400100
import { RangeField } from "@/components/form";

<RangeField label="Progress" min={0} max={100}
  value={n} onChange={setN} />

ColorField

Colour swatch + hex input.

import { ColorField } from "@/components/form";

<ColorField label="Brand colour" value={hex} onChange={setHex} />

Date & Time

DatePickerField

Calendar date picker storing an ISO date string.

import { DatePickerField } from "@/components/form";

<DatePickerField label="Starts on" value={d}
  onChange={(v) => setD(v ?? "")} />

TimePickerField

Clock time picker.

import { TimePickerField } from "@/components/form";

<TimePickerField label="Start time" value={t} onChange={setT} />

Rich Text & Markdown

EditorField

WYSIWYG rich-text editor that outputs HTML.

import { EditorField } from "@/components/form";

<EditorField label="Description" value={html} onChange={setHtml} />

MarkdownEditor

Markdown editor with a live preview toggle.

Markdown supported · 9 words40 characters · 1 sections
import { MarkdownEditor } from "@/components/form";

<MarkdownEditor value={md} onChange={setMd} />

File & Image Upload

Drag-and-drop uploaders that push to your configured storage (Cloudflare R2).

ImageUploadField

Single image uploader with preview.

Upload image

import { ImageUploadField } from "@/components/form";

<ImageUploadField label="Course image"
  onChange={(file) => setFile(file)} />

FileField

Single file uploader with an accept filter.

Click to upload or drag and drop

.pdf,.zip

import { FileField } from "@/components/form";

<FileField label="Resource" accept=".pdf,.zip"
  onChange={(file) => setFile(file)} />

Display

StatusBadge

Compact active/draft pill used across admin lists.

ActiveDraft
import { StatusBadge } from "@/components/admin/ui";

<StatusBadge active />
<StatusBadge active={false} />

Card

The standard rounded surface used to group admin content.

Revenue

$12,480

Last 30 days

import { Card } from "@/components/admin/ui";

<Card className="p-5">…</Card>

Table

The admin data table (Table + Td) used for courses, orders and customers.

CourseStatusPrice
Algebra 101Active$49
Calculus Crash CourseDraft$79
import { Table, Td } from "@/components/admin/ui";

<Table headers={["Course", "Status", "Price"]}>
  <tr><Td>Algebra 101</Td><Td>Published</Td><Td>$49</Td></tr>
</Table>

Overlays

Click each button to trigger the overlay.

ConfirmModal

Confirmation dialog for destructive actions.

import { ConfirmModal } from "@/components/admin/ui";

<ConfirmModal open={open} title="Delete this course?"
  onConfirm={…} onCancel={() => setOpen(false)} />

Toast

Auto-dismissing notification (success / error / info / warning).

import { Toast } from "@/components/admin/ui";

<Toast message={msg} type="success" onClose={() => setMsg("")} />

More in the kit

The form kit ships additional fields not shown live because they need real upload handlers, generics, or async data sources to be meaningful:

  • AvatarUpload, MultiFileField — avatar / multi-file uploaders (push to R2).
  • SearchableMultiSelectField, AutocompleteField — async / typeahead selects backed by an API.
  • RepeaterField — repeatable row groups (generic renderRow).
  • RadioField, HiddenField, FormField, SearchSelect — primitives composed by the fields above.
  • Admin UI kit: MultiImageUpload, VariantImageUpload, VideoUpload, FileUpload, ArrayEditor.