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 >
Navigation Components
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
Nav, NavGroup, NavItem, NavLink
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.
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 >
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 )}
/>
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 >
Group input with addons (prefix/suffix).
import { InputGroup } from '@cloudillo/react'
<InputGroup >
<InputGroup.Addon >https : //</InputGroup.Addon>
<Input placeholder = "example.com" />
</InputGroup >
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..."
/>
Inline editable text field.
import { InlineEditForm } from '@cloudillo/react'
<InlineEditForm
value = {title }
onSave = {(newValue ) => updateTitle (newValue )}
placeholder = "Click to edit..."
/>
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
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 />
</>
)
}
Modal
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
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"
/>
ProfileSelect
Profile selection input with search.
import { ProfileSelect } from '@cloudillo/react'
<ProfileSelect
value = {selectedProfile }
onChange = {setSelectedProfile }
placeholder = "Search profiles..."
/>
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 >
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 }
/>
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.
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 >
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.
ZoomableImage
Image component with pinch-to-zoom and pan support.
import { ZoomableImage } from '@cloudillo/react'
<ZoomableImage src = {imageUrl } alt = "Zoomable photo" />
DocumentEmbed, DocumentEmbedIframe, SvgDocumentEmbed
Components for embedding documents within other documents.
import { DocumentEmbedIframe , SvgDocumentEmbed , useDocumentEmbed } from '@cloudillo/react'
// Iframe-based embed (for HTML/interactive documents)
<DocumentEmbedIframe
fileId = {targetFileId }
contentType = "cloudillo/quillo"
sourceFileId = {currentFileId }
/>
// SVG-based embed (for embedding within SVG canvases)
<SvgDocumentEmbed
fileId = {targetFileId }
contentType = "cloudillo/quillo"
sourceFileId = {currentFileId }
width = {400 }
height = {300 }
/>
The useDocumentEmbed hook manages the embed lifecycle (requesting embed URLs from the shell, tracking loading state).
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 >
}
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 >
)
}
useDebouncedValue
Debounce a value that changes rapidly (e.g., search input).
import { useDebouncedValue } from '@cloudillo/react'
function SearchField() {
const [query , setQuery ] = useState ('' )
const debouncedQuery = useDebouncedValue (query , 300 )
// debouncedQuery updates 300ms after the last query change
}
useDocumentEmbed
Manage state for embedding documents (requesting embed URLs from the shell).
import { useDocumentEmbed } from '@cloudillo/react'
function EmbedManager ({ fileId , contentType }) {
const { embedUrl , loading , error } = useDocumentEmbed ({
targetFileId : fileId ,
targetContentType : contentType ,
sourceFileId : currentFileId
})
}
See Also