Skip to content

Interactive Components ​

These components are powered by Zag.js state machines. They handle keyboard navigation, ARIA attributes, focus management, and complex interaction patterns automatically. You get accessible behavior without writing any of it yourself.

Every interactive component accepts a class prop for additional Tailwind classes.

Dialog ​

A modal dialog with focus trap, escape-to-close, and backdrop click to dismiss.

tsx
import { Dialog } from '@geajs/ui'

<Dialog
  title="Confirm Action"
  description="Are you sure you want to proceed?"
  triggerLabel="Open Dialog"
  onOpenChange={(details) => console.log(details.open)}
>
  <p>Dialog body content here.</p>
</Dialog>

Props ​

PropTypeDefaultDescription
titlestring—Dialog heading
descriptionstring—Subheading text
triggerLabelstring'Open'Text for the trigger button
openboolean—Controlled open state
defaultOpenboolean—Initial open state
modalbooleantrueWhether the dialog is modal
closeOnInteractOutsidebooleantrueClose when clicking the backdrop
closeOnEscapebooleantrueClose on Escape key
trapFocusbooleantrueTrap focus inside the dialog
preventScrollbooleantruePrevent body scroll when open
role'dialog' | 'alertdialog''dialog'ARIA role
onOpenChange(details: { open: boolean }) => void—Called when open state changes

Tabs ​

Tab panels with keyboard switching (arrow keys, Home, End).

tsx
import { Tabs } from '@geajs/ui'

<Tabs
  defaultValue="tab1"
  items={[
    { value: 'tab1', label: 'Account', content: 'Account settings...' },
    { value: 'tab2', label: 'Password', content: 'Password settings...' },
    { value: 'tab3', label: 'Notifications', content: 'Notification preferences...' },
  ]}
/>

Props ​

PropTypeDefaultDescription
itemsArray<{ value, label, content }>[]Tab definitions
defaultValuestring—Initially active tab
valuestring—Controlled active tab
onValueChange(details: { value: string }) => void—Called when active tab changes

Accordion ​

Expandable content sections. Supports single or multiple open panels and a collapsible mode where all panels can be closed.

tsx
import { Accordion } from '@geajs/ui'

<Accordion
  collapsible
  items={[
    { value: 'item1', label: 'What is @geajs/ui?', content: 'A component library for Gea.' },
    { value: 'item2', label: 'Is it accessible?', content: 'Yes, powered by Zag.js.' },
  ]}
/>

Props ​

PropTypeDefaultDescription
itemsArray<{ value, label, content }>[]Accordion items
collapsiblebooleanfalseAllow all panels to close
multiplebooleanfalseAllow multiple panels open at once
defaultValuestring[]—Initially open panels
valuestring[]—Controlled open panels
orientation'vertical' | 'horizontal''vertical'Layout direction
onValueChange(details: { value: string[] }) => void—Called when open panels change

Tooltip ​

Informational popup that appears on hover with a configurable delay.

tsx
import { Tooltip } from '@geajs/ui'

<Tooltip content="Add to library">
  <Button variant="outline">Hover me</Button>
</Tooltip>

<Tooltip content="Bold (Ctrl+B)" openDelay={200}>
  <Button variant="outline" size="icon">B</Button>
</Tooltip>

Props ​

PropTypeDefaultDescription
contentstring—Tooltip text
openDelaynumber—Milliseconds before showing
closeDelaynumber—Milliseconds before hiding

Popover ​

A floating content panel anchored to a trigger button with auto-positioning.

tsx
import { Popover } from '@geajs/ui'

<Popover title="Settings" description="Configure your preferences.">
  <p>Popover content...</p>
</Popover>

Props ​

PropTypeDefaultDescription
titlestring—Popover heading
descriptionstring—Subheading text
triggerLabelstring'Open'Text for the trigger button

Dropdown menu with keyboard navigation, typeahead search, and separator support.

tsx
import { Menu } from '@geajs/ui'

<Menu
  triggerLabel="Actions"
  items={[
    { value: 'edit', label: 'Edit' },
    { value: 'duplicate', label: 'Duplicate' },
    { type: 'separator' },
    { value: 'delete', label: 'Delete' },
  ]}
  onSelect={(details) => console.log(details.value)}
/>

Props ​

PropTypeDefaultDescription
triggerLabelstring—Text for the trigger button
itemsArray<{ value, label } | { type: 'separator' }>[]Menu items
onSelect(details: { value: string }) => void—Called when an item is selected

Select ​

Dropdown select with keyboard navigation and auto-positioning.

tsx
import { Select } from '@geajs/ui'

<Select
  label="Framework"
  placeholder="Select a framework..."
  items={[
    { value: 'gea', label: 'Gea' },
    { value: 'react', label: 'React' },
    { value: 'vue', label: 'Vue' },
    { value: 'solid', label: 'Solid' },
  ]}
  onValueChange={(details) => console.log(details.value)}
/>

For advanced usage with grouped items or custom filtering, pass a Zag collection prop built with select.collection().

Props ​

PropTypeDefaultDescription
labelstring—Label text
placeholderstring'Select...'Placeholder when no value selected
itemsArray<{ value, label }>[]Options
collectionListCollection—Advanced: Zag collection for custom item handling
valuestring[]—Controlled selected values
defaultValuestring[]—Initially selected values
multipleboolean—Allow multiple selections
disabledboolean—Disable the select
onValueChange(details: { value: string[] }) => void—Called when selection changes
onOpenChange(details: { open: boolean }) => void—Called when dropdown opens/closes

Combobox ​

Searchable dropdown with keyboard navigation and typeahead filtering.

tsx
import { Combobox } from '@geajs/ui'

<Combobox
  label="Country"
  placeholder="Search..."
  items={[
    { value: 'us', label: 'United States' },
    { value: 'uk', label: 'United Kingdom' },
    { value: 'de', label: 'Germany' },
  ]}
/>

Props ​

PropTypeDefaultDescription
labelstring—Label text
placeholderstring—Input placeholder
itemsArray<{ value, label }>[]Options
collectionListCollection—Advanced: Zag collection

Switch ​

A toggle switch.

tsx
import { Switch } from '@geajs/ui'

<Switch label="Airplane Mode" onCheckedChange={(d) => console.log(d.checked)} />

Props ​

PropTypeDefaultDescription
labelstring—Label text
checkedboolean—Controlled checked state
defaultCheckedboolean—Initial checked state
disabledboolean—Disable the switch
namestring—Form field name
onCheckedChange(details: { checked: boolean }) => void—Called when toggled

Checkbox ​

A checkbox with optional indeterminate state.

tsx
import { Checkbox } from '@geajs/ui'

<Checkbox label="Accept terms" onCheckedChange={(d) => console.log(d.checked)} />

Props ​

PropTypeDefaultDescription
labelstring—Label text
checkedboolean—Controlled checked state
defaultCheckedboolean—Initial checked state
disabledboolean—Disable the checkbox
namestring—Form field name
onCheckedChange(details: { checked: boolean }) => void—Called when toggled

Radio Group ​

A group of mutually exclusive radio buttons.

tsx
import { RadioGroup } from '@geajs/ui'

<RadioGroup
  label="Plan"
  defaultValue="pro"
  items={[
    { value: 'free', label: 'Free' },
    { value: 'pro', label: 'Pro' },
    { value: 'enterprise', label: 'Enterprise' },
  ]}
  onValueChange={(d) => console.log(d.value)}
/>

Props ​

PropTypeDefaultDescription
labelstring—Group label
itemsArray<{ value, label }>[]Radio options
defaultValuestring—Initially selected value
valuestring—Controlled selected value
onValueChange(details: { value: string }) => void—Called when selection changes

Slider ​

A range slider.

tsx
import { Slider } from '@geajs/ui'

<Slider label="Volume" defaultValue={[50]} min={0} max={100} step={1} />

Props ​

PropTypeDefaultDescription
labelstring—Label text
defaultValuenumber[]—Initial thumb positions
valuenumber[]—Controlled thumb positions
minnumber0Minimum value
maxnumber100Maximum value
stepnumber1Step increment
onValueChange(details: { value: number[] }) => void—Called when value changes

Number Input ​

A numeric input with increment/decrement buttons.

tsx
import { NumberInput } from '@geajs/ui'

<NumberInput label="Quantity" min={0} max={99} step={1} />

Props ​

PropTypeDefaultDescription
labelstring—Label text
minnumber—Minimum value
maxnumber—Maximum value
stepnumber1Step increment
defaultValuestring—Initial value
onValueChange(details: { value: string, valueAsNumber: number }) => void—Called when value changes

Pin Input ​

A multi-field input for verification codes.

tsx
import { PinInput } from '@geajs/ui'

<PinInput
  label="Verification Code"
  count={6}
  type="numeric"
  onValueComplete={(d) => console.log(d.valueAsString)}
/>

Props ​

PropTypeDefaultDescription
labelstring—Label text
countnumber4Number of input fields
type'alphanumeric' | 'numeric' | 'alphabetic''alphanumeric'Allowed characters
maskbooleanfalseMask the input (like a password)
onValueComplete(details: { value: string[], valueAsString: string }) => void—Called when all fields are filled

Tags Input ​

A field for entering and managing tags.

tsx
import { TagsInput } from '@geajs/ui'

<TagsInput
  label="Tags"
  placeholder="Add tag..."
  defaultValue={['gea', 'ui']}
  onValueChange={(d) => console.log(d.value)}
/>

Props ​

PropTypeDefaultDescription
labelstring—Label text
placeholderstring—Input placeholder
defaultValuestring[]—Initial tags
valuestring[]—Controlled tags
onValueChange(details: { value: string[] }) => void—Called when tags change

Toggle Group ​

A group of toggle buttons supporting single or multiple selection.

tsx
import { ToggleGroup } from '@geajs/ui'

<ToggleGroup
  items={[
    { value: 'bold', label: 'B' },
    { value: 'italic', label: 'I' },
    { value: 'underline', label: 'U' },
  ]}
  multiple
/>

Props ​

PropTypeDefaultDescription
itemsArray<{ value, label }>[]Toggle options
multiplebooleanfalseAllow multiple active toggles
defaultValuestring[]—Initially active values
valuestring[]—Controlled active values
onValueChange(details: { value: string[] }) => void—Called when selection changes

Progress ​

A progress bar.

tsx
import { Progress } from '@geajs/ui'

<Progress label="Upload" value={65} />

Props ​

PropTypeDefaultDescription
labelstring—Label text
valuenumber0Current progress (0–100)
maxnumber100Maximum value

Rating Group ​

A star rating input.

tsx
import { RatingGroup } from '@geajs/ui'

<RatingGroup label="Rating" count={5} defaultValue={3} />
<RatingGroup label="Half stars" count={5} allowHalf defaultValue={3.5} />

Props ​

PropTypeDefaultDescription
labelstring—Label text
countnumber5Number of stars
defaultValuenumber—Initial rating
valuenumber—Controlled rating
allowHalfbooleanfalseEnable half-star increments
onValueChange(details: { value: number }) => void—Called when rating changes

Clipboard ​

A copy-to-clipboard field with visual feedback.

tsx
import { Clipboard } from '@geajs/ui'

<Clipboard label="API Key" value="sk-abc123..." />

Props ​

PropTypeDefaultDescription
labelstring—Label text
valuestring—Text to copy

Avatar ​

A user avatar with image and fallback support.

tsx
import { Avatar } from '@geajs/ui'

<Avatar src="/avatar.jpg" name="John Doe" />
<Avatar name="JD" />

Props ​

PropTypeDefaultDescription
srcstring—Image URL
namestring—Fallback text (initials)

Collapsible ​

A single expandable/collapsible section.

tsx
import { Collapsible } from '@geajs/ui'

<Collapsible label="Show more">
  <p>Hidden content revealed on toggle.</p>
</Collapsible>

Props ​

PropTypeDefaultDescription
labelstring—Trigger button text
openboolean—Controlled open state
defaultOpenboolean—Initial open state
onOpenChange(details: { open: boolean }) => void—Called when toggled

Hover Card ​

A rich content preview that appears when hovering over a trigger.

tsx
import { HoverCard } from '@geajs/ui'

<HoverCard triggerLabel="@dashersw">
  <p>Profile information...</p>
</HoverCard>

Props ​

PropTypeDefaultDescription
triggerLabelstring—Trigger text
hrefstring—Optional link URL for the trigger
openDelaynumber—Milliseconds before showing
closeDelaynumber—Milliseconds before hiding

Pagination ​

Page navigation controls with previous/next buttons and page numbers.

tsx
import { Pagination } from '@geajs/ui'

<Pagination
  count={100}
  defaultPageSize={10}
  onPageChange={(d) => console.log(d.page)}
/>

Props ​

PropTypeDefaultDescription
countnumber—Total number of items
defaultPageSizenumber10Items per page
defaultPagenumber1Initially active page
pagenumber—Controlled active page
onPageChange(details: { page: number }) => void—Called when page changes

File Upload ​

A file picker with drag-and-drop support and file type filtering.

tsx
import { FileUpload } from '@geajs/ui'

<FileUpload
  label="Upload Documents"
  accept={{ 'application/pdf': ['.pdf'] }}
  maxFiles={5}
  onFileChange={(d) => console.log(d.acceptedFiles)}
/>

Props ​

PropTypeDefaultDescription
labelstring—Label text
acceptRecord<string, string[]>—Accepted MIME types and extensions
maxFilesnumber—Maximum number of files
maxFileSizenumber—Maximum file size in bytes
onFileChange(details: { acceptedFiles: File[], rejectedFiles: File[] }) => void—Called when files are selected

Toast ​

Temporary notification messages with auto-dismiss. Unlike other components, toasts use a global store pattern.

Setup ​

Add the Toaster component once at your app root:

tsx
import { Component } from '@geajs/core'
import { Toaster } from '@geajs/ui'

class App extends Component {
  template() {
    return (
      <div>
        {/* Your app content */}
        <Toaster />
      </div>
    )
  }
}

Creating Toasts ​

Use the ToastStore singleton to create toasts from anywhere in your app:

tsx
import { ToastStore } from '@geajs/ui'

ToastStore.success({ title: 'Saved!', description: 'Your changes have been saved.' })
ToastStore.error({ title: 'Error', description: 'Something went wrong.' })
ToastStore.info({ title: 'Info', description: 'Here is some information.' })
ToastStore.loading({ title: 'Loading...', description: 'Please wait.' })

ToastStore Methods ​

MethodDescription
create(options)Create a toast with full control over type and options
success(options)Create a success toast
error(options)Create an error toast
info(options)Create an info toast
loading(options)Create a loading toast
dismiss(id?)Dismiss a specific toast, or all toasts if no ID given

Toast Options ​

OptionTypeDescription
titlestringToast heading
descriptionstringBody text
type'success' | 'error' | 'info' | 'loading'Toast variant (set automatically by convenience methods)
durationnumberAuto-dismiss delay in milliseconds (default: 5000)

Tree View ​

A hierarchical tree for displaying nested data. Accepts a Zag tree collection for full control over the data structure.

tsx
import { TreeView } from '@geajs/ui'

<TreeView collection={treeCollection}>
  {/* Render tree nodes */}
</TreeView>

See the Zag.js Tree View docs for details on building tree collections.

Released under the MIT License.