Explore reusable UI components and layout patterns in the Getradg application.
Buttons are used to trigger actions. Below are the available variants with their visual states.
Example usage:
import { Button } from "@/components/ui/button";
import { Icon } from "@/components/ui/Icon";
export default function Example() {
return (
<div className="flex gap-4">
<Button variant="primary">Primary</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="destructive">Destructive</Button>
<Button variant="muted" disabled>Disabled</Button>
<Button variant="tertiary">Tertiary Example</Button>
<Button variant="tertiary"> <Icon name="Star" /></Button>
</div>
);
}Button Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | 'primary' | 'secondary' | 'destructive' | 'muted' | 'tertiary' | "primary" | The visual style of the button. |
| disabled | boolean | false | Disables the button, preventing any interaction. |
| 2 properties | |||
Accordions group content and allow users to expand and collapse sections. Below is a simple example and the available props.
Content for section one. Use accordions to hide optional or lengthy details.
Nested content for boxed variant — looks outlined and grouped.
This boxed item shows an extra icon on the right, followed by the accordion chevron.
Example usage:
import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '@/components/ui/accordion'
<Accordion type="single" defaultValue="item-1">
<AccordionItem value="item-1">
<AccordionTrigger>Section One</AccordionTrigger>
<AccordionContent>Content for section one</AccordionContent>
</AccordionItem>
</Accordion>
<Accordion variant="boxed" iconPosition="left" type="single" defaultValue="boxed-1">
<AccordionItem value="boxed-1">
<AccordionTrigger>Title</AccordionTrigger>
<AccordionContent>Content for boxed item</AccordionContent>
</AccordionItem>
</Accordion>Accordion Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| type | 'single' | 'multiple' | 'single' | Accordion mode: single allows one open item, multiple allows many. |
| value | string | string[] | undefined | Controlled open item(s) value(s). |
| defaultValue | string | string[] | undefined | Uncontrolled initial open item(s). |
| iconPosition | 'left' | 'right' | 'right' | Position of the chevron icon in the trigger (left or right). |
| 4 properties | |||
Icons enhance visual communication and can be used standalone or inside other components. Below are a few examples.
Example usage:
import { Button } from "@/components/ui/button";
import { Icon } from "../ui/Icon";
export default function Example() {
return (
<div className="flex gap-4">
<Icon name="Star" size="lg" className="text-muted-foreground" />
<Icon name="Check" size="lg" className="text-green-600" />
<Icon name="X" size="lg" className="text-red-600" />
<Button variant="primary">
<Star className="w-4 h-4 mr-2" /> Star Button
</Button>
</div>
);
}Icon Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| size | string | number | "24" | Width and height of the icon in pixels. |
| color | string | "currentColor" | Color of the icon, accepts any valid CSS color. |
| 2 properties | |||
A searchable combobox built from the project's Popover andCommand primitives. Supports controlled and uncontrolled usage and shows a check icon for the selected value.
Controlled
Selected: none
Uncontrolled
Example usage:
import Combobox from "@/components/ui/combobox";
const items = [ { value: "next.js", label: "Next.js" } ];
export default function Example() {
const [value, setValue] = React.useState("");
return (
<Combobox items={items} value={value} onChange={setValue} />
);
}Combobox Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| items | ComboboxItem[] | [] | Array of items with `value` and `label` to show in the list. |
| value | string | undefined | Controlled value for selected item. |
| defaultValue | string | undefined | Uncontrolled initial value. |
| onChange | (value: string) => void | undefined | Change handler called when selection changes. |
| 4 properties | |||
The Avatar component displays a user's profile image or initials with an optional fallback.
Example usage:
import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar";
export default function Example() {
return (
<div className="flex gap-4">
<Avatar>
<AvatarImage src="/user-avatar.svg" alt="User avatar" />
<AvatarFallback>JD</AvatarFallback>
</Avatar>
</div>
);
}Avatar Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | undefined | Applies custom Tailwind CSS classes for styling the avatar container. |
| src | string | undefined | The image URL for the avatar. |
| fallback | ReactNode | undefined | Fallback content shown when the image cannot load. |
| 3 properties | |||
The Card component is a flexible container used to group content. Supports slots like CardHeader, CardContent, CardFooter, and CardAction.
Example usage:
import {
Card,
CardHeader,
CardTitle,
CardDescription,
CardContent,
CardFooter,
CardAction,
} from "@/components/ui/card";
export default function Example() {
return (
<Card>
<CardHeader>
<CardTitle>Card Title</CardTitle>
<CardAction>Action</CardAction>
</CardHeader>
<CardDescription>Optional description text.</CardDescription>
<CardContent>This is the main content of the card.</CardContent>
<CardFooter>Footer content like buttons or metadata.</CardFooter>
</Card>
);
}Card Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | "" | Custom Tailwind classes for Card. |
| children | React.ReactNode | undefined | Content inside the Card. |
| 2 properties | |||
Demonstrates a form placed inside the Dialog component. This mirrors a modal form pattern where users can create or edit items without leaving the current page.
Example usage:
import { Dialog, DialogTrigger, DialogContent } from "@/components/ui/dialog";
import { Form } from "@/components/ui/form";
<Dialog>
<DialogTrigger>
<Button>Open Form Dialog</Button>
</DialogTrigger>
<DialogContent>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
</form>
</Form>
</DialogContent>
</Dialog>Dialog Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| open | boolean | false | Controls whether the dialog is open. |
| onOpenChange | (open: boolean) => void | undefined | Callback fired when dialog open state changes. |
| asChild | boolean | false | If true, renders the child element as the trigger without an extra wrapper. |
| children | React.ReactNode | undefined | Dialog content, header, and footer elements. |
| 4 properties | |||
The CustomPagination component provides an intuitive, theme-aware way to navigate through paginated datasets. It includes a page size dropdown and accessible navigation controls for flexible pagination handling.
Example usage:
import { CustomPagination } from "@/components/ui/custom-pagination";
import React from "react";
export default function Example() {
const [page, setPage] = React.useState(1);
const [pageSize, setPageSize] = React.useState(10);
return (
<CustomPagination
total={100}
page={page}
pageSize={pageSize}
onPageChange={setPage}
onPageSizeChange={setPageSize}
/>
);
}Pagination Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| total | number | 0 | Total number of items to paginate. |
| page | number | 1 | Current page number (1-based index). |
| pageSize | number | 10 | Number of items displayed per page. |
| onPageChange | (page: number) => void | () => {} | Callback triggered when page number changes. |
| onPageSizeChange | (size: number) => void | () => {} | Callback triggered when page size changes. |
| pageSizeOptions | number[] | [10, 25, 50, 100] | Available options for items per page dropdown. |
| className | string | "" | Optional custom className for layout overrides. |
| 7 properties | |||
The Form component is a wrapper around React Hook Form integrated with ShadCN UI styling. It standardizes form layout, validation, and accessibility using reusable UI elements like Input and Select.
Example usage:
import { Form, FormField, FormItem, FormLabel, FormControl } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
<FormField
control={form.control}
name="title"
render={({ field }) => (
<FormItem>
<FormLabel>Title</FormLabel>
<FormControl>
<Input placeholder="Enter title..." {...field} />
</FormControl>
</FormItem>
)}
/>
</form>
</Form>Form Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| control | Control<z.infer<typeof formSchema>> | Required | React Hook Form control object used for field management. |
| name | string | undefined | Unique name key that identifies the field in the form schema. |
| render | ({ field }) => React.ReactNode | Required | Render prop function for each form field element. |
| onSubmit | (values: T) => void | undefined | Callback executed when form is submitted successfully. |
| 4 properties | |||
The DataTable component provides a reusable, theme-aware table with built-in pagination and selection support. Define dynamic columns and easily map row data.
| Alice | alice@example.com | Admin | Active | |
| Bob | bob@example.com | Manager | Inactive | |
| Charlie | charlie@example.com | User | Active | |
| David | david@example.com | User | Active | |
| Emma | emma@example.com | Viewer | Inactive |
Example usage:
import { DataTable } from "@/components/ui/table";
const columns = [
{ key: "name", header: "Name" },
{ key: "email", header: "Email" },
{ key: "role", header: "Role" },
{ key: "status", header: "Status", render: (r) => r.status }
];
<DataTable columns={columns} data={usersArray} pageSize={5} />;Table Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| columns | Column[] | [] | Array of column definitions: { key, header, render?, className? } |
| data | any[] | [] | Array of row objects to display in the table. |
| pageSize | number | 5 | Number of rows per page. |
| className | string | "" | Optional wrapper className for layout customization. |
| 4 properties | |||
The Label component provides accessible text for form elements. It automatically adapts its color when the related input is focused or invalid, and can also represent visual states like default, focus, danger, and muted.
(neutral)
(active / focus state)
(error / invalid state)
(optional)
This is a helper text
This is an error helper text
Example usage:
import { Label } from "@/components/ui/label";
<Label>Default Label</Label>
<Label className="text-blue-600">Focus Label</Label>
<Label className="text-red-600">Danger Label</Label>
<Label className="text-muted-foreground">Title (optional)</Label>
<p className="text-xs text-gray-500">Helper text</p>
<p className="text-xs text-red-500">Error helper text</p>Label Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| children | React.ReactNode | undefined | Label text or node content displayed within the label. |
| htmlFor | string | undefined | Associates the label with a form control via its ID. |
| className | string | "" | Optional custom class for overriding styles. |
| 3 properties | |||
The Input component is a styled input field that supports various states such as default, focused, invalid, disabled, and clearable. It uses ShadCN’s design tokens for consistent color, radius, and border behaviors.
Example usage:
import { Input } from "@/components/ui/input";
import Icon from "@/components/ui/Icon";
<Input placeholder="Suggestion..." />
<Input aria-invalid="true" placeholder="Invalid input" />
<Input placeholder="Suggestion..." disabled />
<div className="relative">
<Input placeholder="Input" className="pr-8" />
<Icon name="X" size="sm" className="absolute right-2 top-1/2 -translate-y-1/2 text-muted-foreground cursor-pointer hover:text-foreground transition-colors" />
</div>Input Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| type | string | "text" | Defines the input type such as text, email, password, etc. |
| className | string | "" | Optional custom className to override styles. |
| disabled | boolean | false | Disables user interaction with the input field. |
| aria-invalid | boolean | false | Applies red border and destructive ring for invalid state. |
| placeholder | string | "" | Text hint displayed when the input is empty. |
| 5 properties | |||
The Textarea component provides a multi-line input field supporting focus, invalid, disabled, and character count states — styled for consistency with ShadCN’s design tokens.
Example usage:
import { Textarea } from "@/components/ui/textarea";
<Textarea placeholder="Suggestion..." showCount maxLength={100} />
<Textarea aria-invalid={true} value="Input" showCount readOnly />
<Textarea placeholder="Disabled..." disabled showCount maxLength={100} />Textarea Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| showCount | boolean | false | Displays character count at the bottom-right corner. |
| maxLength | number | 100 | Sets maximum allowed characters. |
| aria-invalid | boolean | false | Applies error border for invalid state. |
| disabled | boolean | false | Prevents user interaction when true. |
| readOnly | boolean | false | Makes the textarea non-editable but still selectable. |
| 5 properties | |||
Checkbox states: default, hover, checked, indeterminate, disabled.
Example usage:
import { Checkbox } from "@/components/ui/checkbox";
<Checkbox />
<Checkbox defaultChecked />
<Checkbox disabled />Checkbox Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| defaultChecked | boolean | false | Marks the checkbox as checked by default. |
| disabled | boolean | false | Disables user interaction. |
| 2 properties | |||
The RadioGroup component provides an accessible, themed way to render a list of radio options. It supports interactive states like default, hover, focus, selected, read-only, and disabled.
Example usage:
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
<RadioGroup>
<label className="flex items-center gap-3">
<RadioGroupItem value="1" />
<span>Option</span>
</label>
</RadioGroup>Radio Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| value | string | "" | Defines the radio item’s value within a group. |
| disabled | boolean | false | Disables the radio item and prevents user interaction. |
| id | string | undefined | Optional ID used to associate the radio with a label. |
| className | string | "" | Optional custom className for additional styling. |
| 4 properties | |||
The CommonTabs set provides a reusable, theme-safe tabs UI (underline style) composed with Radix + ShadCN tokens. Use the low-level parts for full control or the array-driven CommonSimpleTabs for quick setups.
Example usage (Manual composition):
import {
CommonTabsRoot as TabsRoot,
CommonTabsList as TabsList,
CommonTabsTrigger as TabsTrigger,
CommonTabsContent as TabsContent,
} from "@/components/ui/common-tabs";
export default function ManualTabsDemo() {
return (
<TabsRoot defaultValue="account" className="w-full">
<TabsList>
<TabsTrigger value="account">Account</TabsTrigger>
<TabsTrigger value="password">Password</TabsTrigger>
</TabsList>
<TabsContent value="account">
Make changes to your account here.
</TabsContent>
<TabsContent value="password">
Change your password here.
</TabsContent>
</TabsRoot>
);
}Example usage (Array-driven):
import { CommonSimpleTabs } from "@/components/ui/common-tabs";
export default function SimpleTabsDemo() {
return (
<CommonSimpleTabs
defaultValue="account"
items={[
{ value: "account", label: "Account", content: "Make changes to your account here." },
{ value: "password", label: "Password", content: "Change your password here." },
]}
/>
);
}Common Tabs Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| items | { value: string; label: ReactNode; content: ReactNode; triggerClassName?: string }[] | — | Array-driven tabs (for <CommonSimpleTabs>). |
| defaultValue | string | items[0]?.value | Initial active tab (uncontrolled). |
| value | string | — | Controlled active tab value. |
| onValueChange | (v: string) => void | — | Callback when tab changes. |
| className | string | "" | Additional classes for root/list/trigger/content. |
| listClassName | string | "" | Extra classes for the tabs list (SimpleTabs only). |
| triggerClassName | string | "" | Extra classes for each trigger (SimpleTabs only). |
| contentClassName | string | "" | Extra classes for content panels (SimpleTabs only). |
| 8 properties | |||
The dropdown supports both DropdownOptionItem (simple or with icon) and DropdownOptionCheckboxItem (with checkbox column) options, with optional subtext for additional context.
Without subtext
With subtext
Example usage:
import * as React from "react";
import { Button } from "@/components/ui/button";
import {
DropdownMenu,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownOptionItem,
DropdownOptionCheckboxItem,
} from "@/components/ui/dropdown-menu";
import { Icon } from "../ui/Icon";
export default function Example() {
const [selectedId, setSelectedId] = React.useState("opt-2");
const [checked, setChecked] = React.useState<Record<string, boolean>>({ "chk-1": true });
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="secondary" className="w-56 justify-between">
Open dropdown
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-64">
<DropdownMenuLabel>Options</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownOptionItem
selected={selectedId === "opt-1"}
onSelect={(e) => { e.preventDefault(); setSelectedId("opt-1"); }}
>
Option
</DropdownOptionItem>
<DropdownOptionItem
iconLeft={<Icon name="Star" size="sm" />}
selected={selectedId === "opt-2"}
onSelect={(e) => { e.preventDefault(); setSelectedId("opt-2"); }}
>
Option
</DropdownOptionItem>
<DropdownOptionCheckboxItem
checked={!!checked["chk-1"]}
onCheckedChange={(next) => setChecked(p => ({ ...p, "chk-1": !!next }))}
>
Option
</DropdownOptionCheckboxItem>
<DropdownOptionItem subtext="Subtext">Option</DropdownOptionItem>
</DropdownMenuContent>
</DropdownMenu>
);
}Dropdown Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| selected | boolean | false | Indicates if the dropdown option is currently selected. |
| iconLeft | ReactNode | undefined | Optional icon displayed to the left of the option label. |
| subtext | string | undefined | Optional subtext displayed below the option label. |
| checked | boolean | false | For checkbox items, controls whether the option is checked. |
| 4 properties | |||