React components reference

Complete reference for all 85+ components, 12+ hooks, and utility functions exported by @cloudillo/react.

Layout Components

Container

Centered max-width container for page content.

import { Container } from '@cloudillo/react'

<Container>
  <h1>Page Content</h1>
</Container>

HBox, VBox, Group

Flexbox layout primitives.

import { HBox, VBox, Group } from '@cloudillo/react'

// Horizontal layout
<HBox gap="md">
  <Button>Left</Button>
  <Button>Right</Button>
</HBox>

// Vertical layout
<VBox gap="sm">
  <Input label="Name" />
  <Input label="Email" />
</VBox>

// Grouped items with spacing
<Group>
  <Tag>React</Tag>
  <Tag>TypeScript</Tag>
</Group>

Props (shared):

  • gap?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' - Spacing between children
  • align?: 'start' | 'center' | 'end' | 'stretch' - Alignment
  • justify?: 'start' | 'center' | 'end' | 'between' | 'around' - Justification

Panel

Bordered container with optional header.

import { Panel } from '@cloudillo/react'

<Panel title="Settings">
  <p>Panel content here</p>
</Panel>

Card

Elevated card container.

import { Card } from '@cloudillo/react'

<Card>
  <h3>Card Title</h3>
  <p>Card content</p>
</Card>

Fcd (Filter-Content-Details)

Three-column responsive layout pattern for list views.

import { Fcd, FcdContainer, FcdFilter, FcdContent, FcdDetails } from '@cloudillo/react'

<FcdContainer>
  <FcdFilter>
    <FilterBar />
  </FcdFilter>
  <FcdContent>
    <ItemList />
  </FcdContent>
  <FcdDetails>
    <ItemDetails />
  </FcdDetails>
</FcdContainer>

Collapsible sidebar with mobile support.

import {
  useSidebar,
  Sidebar,
  SidebarContent,
  SidebarHeader,
  SidebarFooter,
  SidebarNav,
  SidebarSection,
  SidebarToggle,
  SidebarBackdrop,
  SidebarResizeHandle
} from '@cloudillo/react'

function Layout() {
  const sidebar = useSidebar({ defaultOpen: true })

  return (
    <div>
      <SidebarBackdrop {...sidebar} />
      <Sidebar {...sidebar}>
        <SidebarHeader>
          <Logo />
        </SidebarHeader>
        <SidebarContent>
          <SidebarNav>
            <SidebarSection title="Main">
              <NavItem to="/home">Home</NavItem>
              <NavItem to="/files">Files</NavItem>
            </SidebarSection>
          </SidebarNav>
        </SidebarContent>
        <SidebarFooter>
          <ProfileCard />
        </SidebarFooter>
        <SidebarResizeHandle />
      </Sidebar>
      <SidebarToggle {...sidebar} />
    </div>
  )
}

useSidebar options:

interface UseSidebarOptions {
  defaultOpen?: boolean
  defaultWidth?: number
  minWidth?: number
  maxWidth?: number
  breakpoint?: number // Mobile breakpoint
}

Additional components:

  • SidebarBackdrop - Mobile overlay backdrop that closes sidebar when tapped
  • SidebarResizeHandle - Draggable handle for resizing sidebar width
  • SidebarContext / useSidebarContext - Context provider and hook for nested components

Navigation menu components.

import { Nav, NavGroup, NavItem, NavLink } from '@cloudillo/react'

<Nav>
  <NavGroup title="Main">
    <NavItem icon={<HomeIcon />}>
      <NavLink to="/home">Home</NavLink>
    </NavItem>
    <NavItem icon={<FilesIcon />}>
      <NavLink to="/files">Files</NavLink>
    </NavItem>
  </NavGroup>
</Nav>

Tabs, Tab

Tabbed interface.

import { Tabs, Tab } from '@cloudillo/react'

<Tabs defaultValue="tab1">
  <Tab value="tab1" label="General">
    <GeneralSettings />
  </Tab>
  <Tab value="tab2" label="Advanced">
    <AdvancedSettings />
  </Tab>
</Tabs>

Context: TabsContext is available for building custom tab implementations.


Form Components

Input

Text input with label and validation.

import { Input } from '@cloudillo/react'

<Input
  label="Email"
  type="email"
  placeholder="you@example.com"
  error="Invalid email address"
/>

Props:

  • label?: string - Input label
  • error?: string - Error message
  • hint?: string - Helper text
  • size?: 'sm' | 'md' | 'lg' - Input size
  • All standard <input> props

TextArea

Multi-line text input.

import { TextArea } from '@cloudillo/react'

<TextArea
  label="Description"
  rows={4}
  placeholder="Enter description..."
/>

Select

Custom dropdown select.

import { Select } from '@cloudillo/react'

<Select
  label="Country"
  options={[
    { value: 'us', label: 'United States' },
    { value: 'uk', label: 'United Kingdom' },
    { value: 'de', label: 'Germany' }
  ]}
  onChange={(value) => console.log(value)}
/>

NativeSelect

Native browser select element.

import { NativeSelect } from '@cloudillo/react'

<NativeSelect label="Priority">
  <option value="low">Low</option>
  <option value="medium">Medium</option>
  <option value="high">High</option>
</NativeSelect>

NumberInput

Numeric input with increment/decrement buttons.

import { NumberInput } from '@cloudillo/react'

<NumberInput
  label="Quantity"
  min={0}
  max={100}
  step={1}
  value={5}
  onChange={(value) => console.log(value)}
/>

ColorInput

Color picker input.

import { ColorInput } from '@cloudillo/react'

<ColorInput
  label="Theme Color"
  value="#3b82f6"
  onChange={(color) => console.log(color)}
/>

Toggle

On/off toggle switch.

import { Toggle } from '@cloudillo/react'

<Toggle
  label="Enable notifications"
  checked={enabled}
  onChange={setEnabled}
/>

Fieldset

Group related form fields.

import { Fieldset } from '@cloudillo/react'

<Fieldset legend="Contact Information">
  <Input label="Phone" />
  <Input label="Address" />
</Fieldset>

InputGroup

Group input with addons (prefix/suffix).

import { InputGroup } from '@cloudillo/react'

<InputGroup>
  <InputGroup.Addon>https://</InputGroup.Addon>
  <Input placeholder="example.com" />
</InputGroup>

TagInput

Multi-value tag input with autocomplete.

import { TagInput } from '@cloudillo/react'

<TagInput
  label="Tags"
  value={['react', 'typescript']}
  onChange={setTags}
  suggestions={['react', 'vue', 'angular', 'typescript']}
  placeholder="Add tags..."
/>

InlineEditForm

Inline editable text field.

import { InlineEditForm } from '@cloudillo/react'

<InlineEditForm
  value={title}
  onSave={(newValue) => updateTitle(newValue)}
  placeholder="Click to edit..."
/>

Button Components

Button

Primary button component.

import { Button } from '@cloudillo/react'

<Button variant="primary" onClick={handleClick}>
  Save Changes
</Button>

<Button variant="secondary" size="sm">
  Cancel
</Button>

<Button variant="danger" loading>
  Deleting...
</Button>

Props:

  • variant?: 'primary' | 'secondary' | 'danger' | 'ghost'
  • size?: 'xs' | 'sm' | 'md' | 'lg'
  • loading?: boolean - Shows spinner
  • disabled?: boolean
  • icon?: ReactNode - Left icon
  • iconRight?: ReactNode - Right icon

LinkButton

Button styled as a link.

import { LinkButton } from '@cloudillo/react'

<LinkButton to="/settings">Go to Settings</LinkButton>

Dialog & Overlay Components

Dialog

Modal dialog with backdrop.

import { Dialog, useDialog } from '@cloudillo/react'

function MyComponent() {
  const dialog = useDialog()

  return (
    <>
      <Button onClick={dialog.open}>Open Dialog</Button>

      <Dialog {...dialog} title="Confirm Action">
        <p>Are you sure you want to proceed?</p>
        <HBox gap="sm">
          <Button variant="secondary" onClick={dialog.close}>Cancel</Button>
          <Button variant="primary" onClick={handleConfirm}>Confirm</Button>
        </HBox>
      </Dialog>
    </>
  )
}

useDialog returns:

interface UseDialogReturn {
  isOpen: boolean
  open: () => void
  close: () => void
  toggle: () => void
}

DialogContainer

Wrapper component for rendering dialogs at the root level.

import { DialogContainer } from '@cloudillo/react'

function App() {
  return (
    <>
      <MainContent />
      <DialogContainer />
    </>
  )
}

Low-level modal wrapper.

import { Modal } from '@cloudillo/react'

<Modal isOpen={isOpen} onClose={handleClose}>
  <div className="modal-content">
    Custom modal content
  </div>
</Modal>

BottomSheet

Mobile-friendly bottom sheet.

import { BottomSheet } from '@cloudillo/react'

<BottomSheet
  isOpen={isOpen}
  onClose={handleClose}
  snapPoints={['50%', '90%']}
>
  <div>Sheet content</div>
</BottomSheet>

Dropdown menu container.

import { Dropdown } from '@cloudillo/react'

<Dropdown
  trigger={<Button>Options</Button>}
  align="end"
>
  <MenuItem onClick={handleEdit}>Edit</MenuItem>
  <MenuItem onClick={handleDelete}>Delete</MenuItem>
</Dropdown>

Popper

Floating positioned element (tooltips, popovers).

import { Popper } from '@cloudillo/react'

<Popper
  trigger={<Button>Hover me</Button>}
  placement="top"
>
  <div>Tooltip content</div>
</Popper>

QRCodeDialog

Dialog showing a QR code.

import { QRCodeDialog } from '@cloudillo/react'

<QRCodeDialog
  isOpen={isOpen}
  onClose={handleClose}
  value="https://cloudillo.net/share/abc123"
  title="Share Link"
/>

Context menu and dropdown menu items.

import { Menu, MenuItem, MenuDivider, MenuHeader } from '@cloudillo/react'

<Menu>
  <MenuHeader>Actions</MenuHeader>
  <MenuItem icon={<EditIcon />} onClick={handleEdit}>
    Edit
  </MenuItem>
  <MenuItem icon={<CopyIcon />} onClick={handleCopy}>
    Copy
  </MenuItem>
  <MenuDivider />
  <MenuItem icon={<TrashIcon />} variant="danger" onClick={handleDelete}>
    Delete
  </MenuItem>
</Menu>

ActionSheet

Mobile action sheet (bottom menu).

import { ActionSheet, ActionSheetItem, ActionSheetDivider } from '@cloudillo/react'

<ActionSheet isOpen={isOpen} onClose={handleClose}>
  <ActionSheetItem onClick={handleShare}>Share</ActionSheetItem>
  <ActionSheetItem onClick={handleCopy}>Copy Link</ActionSheetItem>
  <ActionSheetDivider />
  <ActionSheetItem variant="danger" onClick={handleDelete}>
    Delete
  </ActionSheetItem>
</ActionSheet>

Feedback Components

Toast

Toast notification system.

import { useToast, ToastContainer } from '@cloudillo/react'

// In your app root
function App() {
  return (
    <>
      <ToastContainer />
      <MainContent />
    </>
  )
}

// In any component
function MyComponent() {
  const toast = useToast()

  const handleSave = async () => {
    try {
      await saveData()
      toast.success('Saved successfully!')
    } catch (err) {
      toast.error('Failed to save')
    }
  }

  return <Button onClick={handleSave}>Save</Button>
}

useToast methods:

  • toast.success(message, options?) - Success toast
  • toast.error(message, options?) - Error toast
  • toast.warning(message, options?) - Warning toast
  • toast.info(message, options?) - Info toast
  • toast.custom(content, options?) - Custom toast

Toast sub-components:

For building custom toast layouts:

import {
  Toast,
  ToastIcon,
  ToastContent,
  ToastTitle,
  ToastMessage,
  ToastActions,
  ToastClose,
  ToastProgress
} from '@cloudillo/react'

// Custom toast layout
<Toast variant="success">
  <ToastIcon />
  <ToastContent>
    <ToastTitle>Success!</ToastTitle>
    <ToastMessage>Your changes have been saved.</ToastMessage>
  </ToastContent>
  <ToastActions>
    <Button size="sm">Undo</Button>
  </ToastActions>
  <ToastClose />
  <ToastProgress />
</Toast>

Context: ToastContext and useToastContext are available for building custom toast providers.

LoadingSpinner

Spinning loader indicator.

import { LoadingSpinner } from '@cloudillo/react'

<LoadingSpinner size="md" />

{isLoading && <LoadingSpinner />}

Skeleton, SkeletonText, SkeletonCard, SkeletonList

Loading skeleton placeholders.

import { Skeleton, SkeletonText, SkeletonCard, SkeletonList } from '@cloudillo/react'

// Basic skeleton
<Skeleton width={200} height={20} />

// Text skeleton
<SkeletonText lines={3} />

// Card skeleton
<SkeletonCard />

// List skeleton
<SkeletonList count={5} />

Progress

Progress bar.

import { Progress } from '@cloudillo/react'

<Progress value={75} max={100} />

<Progress value={uploadProgress} showLabel />

EmptyState

Empty state placeholder.

import { EmptyState } from '@cloudillo/react'

<EmptyState
  icon={<FilesIcon />}
  title="No files yet"
  description="Upload your first file to get started"
  action={<Button>Upload File</Button>}
/>

Profile Components

Avatar, AvatarStatus, AvatarBadge, AvatarGroup

User avatar components.

import { Avatar, AvatarStatus, AvatarBadge, AvatarGroup } from '@cloudillo/react'

// Basic avatar
<Avatar src={profilePic} name="Alice" size="md" />

// With status indicator
<Avatar src={profilePic}>
  <AvatarStatus status="online" />
</Avatar>

// With badge
<Avatar src={profilePic}>
  <AvatarBadge>3</AvatarBadge>
</Avatar>

// Group of avatars
<AvatarGroup max={3}>
  <Avatar src={user1.pic} name={user1.name} />
  <Avatar src={user2.pic} name={user2.name} />
  <Avatar src={user3.pic} name={user3.name} />
  <Avatar src={user4.pic} name={user4.name} />
</AvatarGroup>

ProfilePicture, UnknownProfilePicture

Cloudillo profile picture components.

import { ProfilePicture, UnknownProfilePicture } from '@cloudillo/react'

<ProfilePicture idTag="alice.cloudillo.net" size="lg" />

<UnknownProfilePicture size="md" />

IdentityTag

Display identity tag with icon.

import { IdentityTag } from '@cloudillo/react'

<IdentityTag idTag="alice.cloudillo.net" />

ProfileCard

Profile card with picture, name, and actions.

import { ProfileCard } from '@cloudillo/react'

<ProfileCard
  profile={profile}
  onConnect={handleConnect}
  onFollow={handleFollow}
/>

ProfileAudienceCard

Profile card optimized for audience selection.

import { ProfileAudienceCard } from '@cloudillo/react'

<ProfileAudienceCard
  profile={profile}
  selected={isSelected}
  onSelect={handleSelect}
/>

EditProfileList

Editable list of profiles (for managing connections, etc.).

import { EditProfileList } from '@cloudillo/react'

<EditProfileList
  profiles={connections}
  onRemove={handleRemove}
  emptyMessage="No connections yet"
/>

Data Display Components

TreeView, TreeItem

Hierarchical tree view.

import { TreeView, TreeItem } from '@cloudillo/react'

<TreeView>
  <TreeItem label="Documents" icon={<FolderIcon />}>
    <TreeItem label="Report.pdf" icon={<FileIcon />} />
    <TreeItem label="Notes.txt" icon={<FileIcon />} />
  </TreeItem>
  <TreeItem label="Images" icon={<FolderIcon />}>
    <TreeItem label="Photo.jpg" icon={<ImageIcon />} />
  </TreeItem>
</TreeView>

Accordion, AccordionItem

Collapsible accordion sections.

import { Accordion, AccordionItem } from '@cloudillo/react'

<Accordion>
  <AccordionItem title="General Settings">
    <GeneralSettings />
  </AccordionItem>
  <AccordionItem title="Advanced Settings">
    <AdvancedSettings />
  </AccordionItem>
</Accordion>

PropertyPanel, PropertySection, PropertyField

Property inspector panel (like IDE properties).

import { PropertyPanel, PropertySection, PropertyField } from '@cloudillo/react'

<PropertyPanel>
  <PropertySection title="Appearance">
    <PropertyField label="Width">
      <NumberInput value={width} onChange={setWidth} />
    </PropertyField>
    <PropertyField label="Color">
      <ColorInput value={color} onChange={setColor} />
    </PropertyField>
  </PropertySection>
</PropertyPanel>

TimeFormat

Formatted time display (relative or absolute).

import { TimeFormat } from '@cloudillo/react'

<TimeFormat value={createdAt} />
// Renders: "2 hours ago" or "Jan 15, 2025"

Badge

Status badge.

import { Badge } from '@cloudillo/react'

<Badge variant="success">Active</Badge>
<Badge variant="warning">Pending</Badge>
<Badge variant="danger">Error</Badge>

Tag, TagList

Tags and tag lists.

import { Tag, TagList } from '@cloudillo/react'

<Tag>React</Tag>

<TagList
  tags={['react', 'typescript', 'cloudillo']}
  onRemove={handleRemoveTag}
/>

Filter & Toolbar Components

FilterBar

Filter bar with search and filters.

import {
  FilterBar,
  FilterBarSearch,
  FilterBarItem,
  FilterBarSection,
  FilterBarDivider
} from '@cloudillo/react'

<FilterBar>
  <FilterBarSearch
    value={search}
    onChange={setSearch}
    placeholder="Search files..."
  />
  <FilterBarDivider />
  <FilterBarSection>
    <FilterBarItem
      label="Type"
      value={typeFilter}
      onChange={setTypeFilter}
      options={typeOptions}
    />
    <FilterBarItem
      label="Date"
      value={dateFilter}
      onChange={setDateFilter}
      options={dateOptions}
    />
  </FilterBarSection>
</FilterBar>

Alternative export: FilterBarComponent is also exported for cases where you need to avoid naming conflicts.

Toolbar

Action toolbar.

import { Toolbar, ToolbarGroup, ToolbarDivider, ToolbarSpacer } from '@cloudillo/react'

<Toolbar>
  <ToolbarGroup>
    <Button icon={<BoldIcon />} />
    <Button icon={<ItalicIcon />} />
    <Button icon={<UnderlineIcon />} />
  </ToolbarGroup>
  <ToolbarDivider />
  <ToolbarGroup>
    <Button icon={<AlignLeftIcon />} />
    <Button icon={<AlignCenterIcon />} />
  </ToolbarGroup>
  <ToolbarSpacer />
  <Button>Save</Button>
</Toolbar>

Infinite Scroll Components

LoadMoreTrigger

Intersection observer trigger for infinite scroll.

import { LoadMoreTrigger } from '@cloudillo/react'
import { useInfiniteScroll } from '@cloudillo/react'

function FileList() {
  const { items, isLoading, sentinelRef } = useInfiniteScroll({
    fetchPage: async (cursor, limit) => {
      const result = await api.files.list({ cursor, limit })
      return {
        items: result.data,
        nextCursor: result.cursorPagination?.nextCursor ?? null,
        hasMore: result.cursorPagination?.hasMore ?? false
      }
    }
  })

  return (
    <div>
      {items.map(file => <FileCard key={file.fileId} file={file} />)}
      <LoadMoreTrigger ref={sentinelRef} isLoading={isLoading} />
    </div>
  )
}

Utility Components

FormattedText

Render formatted text with markdown support.

import { FormattedText } from '@cloudillo/react'

<FormattedText content="**Bold** and *italic* text" />

FontPicker

Font selection component. Works with the @cloudillo/fonts library for font metadata and pairing suggestions.

import { FontPicker } from '@cloudillo/react'
import { getSuggestedBodyFonts } from '@cloudillo/fonts'

<FontPicker
  value={fontFamily}
  onChange={setFontFamily}
/>

// Use with font pairings
const suggestedBodies = getSuggestedBodyFonts(headingFont)

See @cloudillo/fonts for available fonts and pairing APIs.


Utility Hooks

useMergedRefs

Combine multiple refs into one.

import { useMergedRefs } from '@cloudillo/react'

function MyComponent({ forwardedRef }) {
  const localRef = useRef()
  const mergedRef = useMergedRefs(localRef, forwardedRef)

  return <div ref={mergedRef} />
}

useBodyScrollLock

Lock body scroll (for modals).

import { useBodyScrollLock } from '@cloudillo/react'

function Modal({ isOpen }) {
  useBodyScrollLock(isOpen)

  return isOpen ? <div className="modal">...</div> : null
}

useEscapeKey

Handle Escape key press.

import { useEscapeKey } from '@cloudillo/react'

function Modal({ onClose }) {
  useEscapeKey(onClose)

  return <div className="modal">...</div>
}

useOutsideClick

Detect clicks outside an element.

import { useOutsideClick } from '@cloudillo/react'

function Dropdown({ onClose }) {
  const ref = useRef()
  useOutsideClick(ref, onClose)

  return <div ref={ref} className="dropdown">...</div>
}

useMediaQuery

Responsive media query hook.

import { useMediaQuery } from '@cloudillo/react'

function MyComponent() {
  const isMobile = useMediaQuery('(max-width: 768px)')

  return isMobile ? <MobileView /> : <DesktopView />
}

useIsMobile

Shorthand for mobile detection.

import { useIsMobile } from '@cloudillo/react'

function MyComponent() {
  const isMobile = useIsMobile()

  return isMobile ? <MobileNav /> : <DesktopNav />
}

usePrefersReducedMotion

Accessibility: detect reduced motion preference.

import { usePrefersReducedMotion } from '@cloudillo/react'

function AnimatedComponent() {
  const prefersReducedMotion = usePrefersReducedMotion()

  return (
    <div className={prefersReducedMotion ? 'no-animation' : 'animated'}>
      ...
    </div>
  )
}

See Also