Block menu commands API for adding custom commands to block context menus. This allows plugins to add custom actions that appear when users right-click on blocks' handle.
Registers a custom command in the block context menu.
A unique identifier for the command
The command configuration, including whether it works with multiple blocks and a render function that returns a React element
// Command that works on a single block
orca.blockMenuCommands.registerBlockMenuCommand("myplugin.exportBlock", {
worksOnMultipleBlocks: false,
render: (blockId, rootBlockId, close) => (
<orca.components.MenuText
preIcon="ti ti-file-export"
title="Export as JSON"
onClick={() => {
close()
exportBlockAsJson(blockId)
}}
/>
)
})
// Command that works on multiple blocks
orca.blockMenuCommands.registerBlockMenuCommand("myplugin.mergeBlocks", {
worksOnMultipleBlocks: true,
render: (blockIds, rootBlockId, close) => (
<orca.components.MenuText
preIcon="ti ti-combine"
title={`Merge ${blockIds.length} Blocks`}
onClick={() => {
close()
mergeSelectedBlocks(blockIds)
}}
/>
)
})
// Register a command for single block selection
orca.blockMenuCommands.registerBlockMenuCommand("myplugin.analyzeBlock", {
worksOnMultipleBlocks: false,
render: (blockId, rootBlockId, close) => (
<orca.components.MenuText
title="Analyze Block"
onClick={() => {
close()
analyzeBlockContent(blockId)
}}
/>
)
})
Broadcasts API, used for application-wide event messaging between different windows of Orca. This is useful for communication between different windows of the same plugin.
Broadcasts an event of a specific type with optional arguments to all registered handlers.
The broadcast type to emit
Any arguments to pass to the handlers
Checks if a handler is registered for a specific broadcast type.
The broadcast type to check
True if a handler is registered, false otherwise
Registers a handler function for a specific broadcast type.
The broadcast type to listen for
The function to execute when the broadcast is received
Unregisters a previously registered handler for a specific broadcast type.
The broadcast type of the handler to remove
The handler function to unregister
Commands API, used to register, invoke, and manage commands in Orca. Commands are the primary way to add functionality to Orca, and can be bound to shortcuts, toolbar buttons, slash commands, and more.
Invokes a command by its ID with optional arguments.
The identifier of the command to invoke
Optional arguments to pass to the command
A Promise that resolves to the result of the command execution
Invokes an editor command by its ID with cursor context and optional arguments.
The identifier of the editor command to invoke
The cursor data context for the command, or null
Optional arguments to pass to the command
A Promise that resolves to the result of the command execution
Executes a group of commands as a single undoable operation. This is useful when multiple commands should be treated as a single step in the undo/redo history.
An async function that will perform multiple command operations
Optional
options: { topGroup?: boolean; undoable?: boolean }Optional configuration for the command group
Optional
topGroup?: booleanWhether this is a top-level command group not nested in another group (defaults to false)
Optional
undoable?: booleanWhether the command group should be undoable (defaults to true)
// Group multiple editor commands as one undoable operation
await orca.commands.invokeGroup(async () => {
// Create a heading block
const headingId = await orca.commands.invokeEditorCommand(
"core.editor.insertBlock",
null,
null, // If there is no reference block, this is null
null, // Since it's null, the position parameter here is also null
null, // No content
{ type: "heading", level: 1 }, // repr parameter, defines this as a level 1 heading
)
// Add a content block under the heading block
await orca.commands.invokeEditorCommand(
"core.editor.insertBlock",
null,
orca.state.blocks[headingId], // Reference block (heading block)
"lastChild", // Position: as the last child of the heading block
[{ t: "t", v: "This is the first paragraph." }], // Content
{ type: "text" } // repr parameter
)
// Add another content block
await orca.commands.invokeEditorCommand(
"core.editor.insertBlock",
null,
orca.state.blocks[headingId], // Reference block (heading block)
"lastChild", // Position: as the last child of the heading block
[{ t: "t", v: "This is the second paragraph." }], // Content
{ type: "text" } // repr parameter
)
})
Invokes an editor command (as a top command) by its ID with cursor context and optional arguments.
The identifier of the editor command to invoke
The cursor data context for the command, or null
Optional arguments to pass to the command
A Promise that resolves to the result of the command execution
Registers an "after command" hook to execute code after a command completes.
The identifier of the command to hook into
The function to execute after the command completes. The first parameter is the command ID, followed by the arguments of the command being monitored.
Registers a "before command" hook to conditionally prevent a command from executing.
The identifier of the command to hook into
A predicate function that returns true if the command should proceed, false to cancel. The first parameter is the command ID, followed by the arguments of the command being monitored.
// Prevent deletion of locked blocks
orca.commands.registerBeforeCommand(
"core.editor.deleteBlocks",
(cmdId, blockIds) => {
// Check if any of the blocks are locked
const hasLockedBlock = blockIds.some(id => isBlockLocked(id))
if (hasLockedBlock) {
orca.notify("error", "Cannot delete locked blocks")
return false // Prevent the command from executing
}
return true // Allow the command to proceed
}
)
Registers a new command with Orca.
A unique identifier for the command
The function to execute when the command is invoked
A human-readable label for the command
Registers an editor command that can be undone/redone in the editor. Editor commands are automatically added to the undo/redo stack.
A unique identifier for the command
The function to execute when the command is invoked
The function to execute when the command is undone
Options for the command including label, whether it has arguments, and if focus is needed
// Register an editor command to format text
orca.commands.registerEditorCommand(
"myplugin.formatSelectedText",
// Do function
([panelId, rootBlockId, cursor]) => {
// Get the selected text
const selection = window.getSelection()
if (!selection || selection.isCollapsed) return null
// const formattedText = ...
// Return undo arguments
return {
ret: formattedText,
undoArgs: { text: formattedText }
}
},
// Undo function
(panelId, { text }) => {
// ...
},
{
label: "Format Selected Text",
hasArgs: false
}
)
Unregisters a previously registered "after command" hook.
The identifier of the command
The function to unregister
Unregisters a previously registered "before command" hook.
The identifier of the command
The predicate function to unregister
Pre-built UI components from Orca that can be used in plugin development. These components follow Orca's design system and provide consistent UI patterns.
Provides an editor interface for managing aliases/tags, including adding/removing aliases, formatting options, template selection, and inclusion relationships.
// Edit aliases for a block
<orca.components.AliasEditor
blockId={123}
>
{(open) => (
<orca.components.Button variant="outline" onClick={open}>
Edit Alias
</orca.components.Button>
)}
</orca.components.AliasEditor>
// With custom container
<orca.components.AliasEditor
blockId={456}
container={containerRef}
>
{(open) => (
<span onClick={open}>Configure Tag Settings</span>
)}
</orca.components.AliasEditor>
Renders a block with all its content and children
Renders a breadcrumb trail for a block's ancestors
Renders a block's children
Provides block selection functionality
// Block selection
<orca.components.BlockSelect
mode="block"
selected={[123, 456]}
onChange={async (selected) => {
console.log("Selected blocks:", selected);
}}
/>
// Reference selection with scope restriction
<orca.components.BlockSelect
mode="ref"
scope="project-blocks"
selected={[789]}
onChange={handleSelectionChange}
/>
Core component for block rendering with common UI elements
// Basic text block
<orca.components.BlockShell
panelId="main-panel"
blockId={123}
rndId="unique-rand-id"
blockLevel={0}
indentLevel={0}
reprClassName="orca-repr-text"
contentJsx={<div>This is text content</div>}
childrenJsx={<ChildrenComponent />}
/>
// Code block example
<orca.components.BlockShell
panelId="code-panel"
blockId={456}
rndId="code-rand-id"
blockLevel={1}
indentLevel={2}
withBreadcrumb={true}
reprClassName="orca-repr-code"
contentClassName="orca-repr-code-content"
contentAttrs={{ contentEditable: false }}
contentJsx={<CodeEditor />}
childrenJsx={childrenBlocks}
/>
Renders a generic breadcrumb navigation
// Simple breadcrumb
<orca.components.Breadcrumb
items={["Home", "Projects", "Document"]}
/>
// Breadcrumb with links and icons
<orca.components.Breadcrumb
items={[
<a href="#home">Home <i className="ti ti-home" /></a>,
<a href="#projects">Projects</a>,
"Current Document"
]}
className="custom-breadcrumb"
/>
Standard button component with multiple variants
// Basic button
<orca.components.Button variant="solid" onClick={handleClick}>
Save
</orca.components.Button>
// Dangerous action button
<orca.components.Button variant="dangerous" onClick={handleDelete}>
<i className="ti ti-trash" /> Delete
</orca.components.Button>
// Outline button with disabled state
<orca.components.Button variant="outline" disabled={true}>
Edit
</orca.components.Button>
// Simple icon button
<orca.components.Button variant="plain" onClick={handleRefresh}>
<i className="ti ti-refresh" />
</orca.components.Button>
Checkbox form element
// Basic checkbox
<orca.components.Checkbox
checked={isChecked}
onChange={({ checked }) => setIsChecked(checked)}
/>
// Disabled checkbox
<orca.components.Checkbox checked={true} disabled={true} />
// Indeterminate state checkbox
<orca.components.Checkbox
indeterminate={true}
onChange={handleSelectionChange}
/>
Input that handles IME composition events properly
// Basic input
<orca.components.CompositionInput
placeholder="Enter text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
/>
// Input with prefix and suffix
<orca.components.CompositionInput
pre={<i className="ti ti-search" />}
post={<Button onClick={clearInput}>Clear</Button>}
placeholder="Search..."
/>
// Input with validation error
<orca.components.CompositionInput
value={email}
onChange={handleEmailChange}
error={emailError ? <span className="error">{emailError}</span> : null}
/>
Textarea that handles IME composition events properly
// Basic multiline text input
<orca.components.CompositionTextArea
placeholder="Enter multiline text"
value={textValue}
onChange={(e) => setTextValue(e.target.value)}
/>
// Set rows and auto-grow
<orca.components.CompositionTextArea
rows={5}
style={{ minHeight: '100px' }}
placeholder="Enter notes..."
/>
Displays a confirmation dialog
// Basic confirmation dialog
<orca.components.ConfirmBox
text="Are you sure you want to delete this item?"
onConfirm={(e, close) => {
deleteItem();
close();
}}
>
{(open, close) => (
<orca.components.Button variant="dangerous" onClick={open}>
Delete
</orca.components.Button>
)}
</orca.components.ConfirmBox>
// Confirmation dialog with state
<orca.components.ConfirmBox
text="Are you sure you want to move this block?"
onConfirm={(e, close, state) => {
moveBlock(state.blockId, state.destination);
close();
}}
>
{(open) => (
<orca.components.Button
variant="soft"
onClick={(e) => open(e, { blockId: 123, destination: 'section-1' })}
>
Move
</orca.components.Button>
)}
</orca.components.ConfirmBox>
Creates a context menu attached to an element
// Basic context menu
<orca.components.ContextMenu
menu={(close) => (
<orca.components.Menu>
<orca.components.MenuText
title="Edit"
onClick={() => { editItem(); close(); }}
/>
<orca.components.MenuText
title="Delete"
dangerous={true}
onClick={() => { deleteItem(); close(); }}
/>
</orca.components.Menu>
)}
>
{(open) => (
<div onContextMenu={open}>Right-click here to show the menu</div>
)}
</orca.components.ContextMenu>
// Custom position and alignment menu
<orca.components.ContextMenu
placement="horizontal"
alignment="top"
defaultPlacement="right"
menu={(close) => (
<orca.components.Menu>
<orca.components.MenuText title="Option 1" onClick={close} />
<orca.components.MenuText title="Option 2" onClick={close} />
</orca.components.Menu>
)}
>
{(open) => (
<orca.components.Button variant="soft" onClick={open}>
Show Menu
</orca.components.Button>
)}
</orca.components.ContextMenu>
Calendar date picker
// Basic date picker
const [date, setDate] = useState(new Date());
<orca.components.DatePicker
value={date}
onChange={(newDate) => setDate(newDate)}
/>
// Date-time picker
<orca.components.DatePicker
mode="datetime"
value={dateTime}
onChange={handleDateTimeChange}
/>
// Date range picker
const [dateRange, setDateRange] = useState([new Date(), new Date(Date.now() + 86400000)]);
<orca.components.DatePicker
range={true}
value={dateRange}
onChange={(newRange) => setDateRange(newRange)}
/>
Context menu that appears on hover
// Basic hover menu
<orca.components.HoverContextMenu
menu={(close) => (
<orca.components.Menu>
<orca.components.MenuText
title="View"
preIcon="ti ti-eye"
onClick={close}
/>
<orca.components.MenuText
title="Edit"
preIcon="ti ti-pencil"
onClick={close}
/>
</orca.components.Menu>
)}
>
<div className="hoverable-element">Hover to show menu</div>
</orca.components.HoverContextMenu>
// Custom positioned hover menu
<orca.components.HoverContextMenu
placement="horizontal"
defaultPlacement="right"
menu={(close) => (
<orca.components.Menu>
<orca.components.MenuText
title="View Details"
preIcon="ti ti-info-circle"
onClick={() => { viewDetails(); close(); }}
/>
</orca.components.Menu>
)}
>
<i className="ti ti-info" />
</orca.components.HoverContextMenu>
Image component with loading states
// Basic image
<orca.components.Image
src="/path/to/image.jpg"
alt="Description"
/>
// Styled image
<orca.components.Image
src="/path/to/image.png"
alt="Logo"
className="profile-image"
style={{ width: 100, height: 100, borderRadius: '50%' }}
/>
// Handle loading events
<orca.components.Image
src="/path/to/large-image.jpg"
alt="Large Image"
onLoad={() => setImageLoaded(true)}
onError={() => handleImageError()}
/>
Standard text input component
// Basic input field
<orca.components.Input
placeholder="Enter text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
/>
// Input field with prefix and suffix
<orca.components.Input
pre={<i className="ti ti-user" />}
post={<orca.components.Button variant="plain">Clear</orca.components.Button>}
placeholder="Username"
/>
// Input field with error message
<orca.components.Input
value={email}
onChange={handleEmailChange}
error={emailError ? "Please enter a valid email address" : undefined}
/>
Input dialog with label and actions
// Basic input dialog
<orca.components.InputBox
label="Enter name"
defaultValue="Default value"
onConfirm={(value, e, close) => {
if (value) {
saveName(value);
close();
}
}}
>
{(open) => (
<orca.components.Button variant="soft" onClick={open}>
Edit Name
</orca.components.Button>
)}
</orca.components.InputBox>
// Input dialog with validation
<orca.components.InputBox
label="Enter URL"
error={urlError}
onConfirm={(url, e, close) => {
if (isValidUrl(url)) {
addUrl(url);
close();
} else {
setUrlError("Please enter a valid URL");
}
}}
>
{(open) => (
<orca.components.Button variant="outline" onClick={open}>
Add Link
</orca.components.Button>
)}
</orca.components.InputBox>
Component for loading more items in paginated lists
Efficient view container for switching between components
// Basic view switching container
<orca.components.MemoizedViews
name="main-views"
active="details"
views={{
"list": <ListView items={items} />,
"details": <DetailsView itemId={123} />,
"settings": <SettingsView />
}}
/>
// Horizontally arranged views
<orca.components.MemoizedViews
name="side-views"
active={currentTab}
orientation="horizontal"
className="side-panel"
views={{
"info": <InfoPanel />,
"history": <HistoryPanel />,
"comments": <CommentsPanel />
}}
/>
Standard menu container
// Basic menu
<orca.components.Menu>
<orca.components.MenuText title="Option 1" onClick={() => handleOption(1)} />
<orca.components.MenuText title="Option 2" onClick={() => handleOption(2)} />
<orca.components.MenuSeparator />
<orca.components.MenuText
title="Exit"
dangerous={true}
onClick={() => handleExit(0)}
/>
</orca.components.Menu>
// Menu with keyboard navigation enabled
<orca.components.Menu
keyboardNav={true}
navDirection="both"
onKeyboardNav={(el) => scrollToElement(el)}
className="keyboard-nav-menu"
>
<orca.components.MenuTitle title="Actions" />
<orca.components.MenuText title="Edit" onClick={() => handleEdit(123)} />
<orca.components.MenuText title="Copy" onClick={() => handleCopy(456)} />
<orca.components.MenuText title="Delete" onClick={() => handleDelete(789)} />
</orca.components.Menu>
Menu item component
// Basic menu item
<orca.components.MenuItem
jsx={<div>Option 1</div>}
onClick={() => handleOption(1)}
/>
// Menu item with nested content
<orca.components.MenuItem
jsx={<div className="menu-item-header">Display Settings</div>}
onClick={() => handleSettingsClick(123)}
>
<div className="submenu">
<div>Theme: {currentTheme}</div>
<div>Font Size: {fontSize}</div>
</div>
</orca.components.MenuItem>
// Menu item with custom styles
<orca.components.MenuItem
jsx={<div className="icon-item"><i className="ti ti-user"/> User</div>}
className="highlighted-item"
style={{ fontWeight: 'bold' }}
onClick={() => handleUserClick(456)}
/>
Visual separator for menus
// Add a separator between menu items
<orca.components.Menu>
<orca.components.MenuText title="Edit" onClick={() => handleEdit(123)} />
<orca.components.MenuText title="Copy" onClick={() => handleCopy(456)} />
<orca.components.MenuSeparator />
<orca.components.MenuText
title="Delete"
dangerous={true}
onClick={() => handleDelete(789)}
/>
</orca.components.Menu>
Text-based menu item
// Basic text menu item
<orca.components.MenuText
title="Save Document"
onClick={handleSave}
/>
// Menu item with icon and shortcut
<orca.components.MenuText
title="Copy"
preIcon="ti ti-copy"
shortcut="⌘C"
onClick={handleCopy}
/>
// Menu item with subtitle
<orca.components.MenuText
title="Export as PDF"
subtitle="Export the current document as a PDF file"
preIcon="ti ti-file-export"
onClick={handleExport}
/>
// Disabled menu item
<orca.components.MenuText
title="Delete"
preIcon="ti ti-trash"
dangerous={true}
disabled={!hasSelection}
onClick={handleDelete}
/>
// Menu item with context menu
<orca.components.MenuText
title="Share"
preIcon="ti ti-share"
contextMenu={(close) => (
<orca.components.Menu>
<orca.components.MenuText title="Copy Link" onClick={() => { copyLink(); close(); }} />
<orca.components.MenuText title="Send Email" onClick={() => { sendEmail(); close(); }} />
</orca.components.Menu>
)}
/>
Menu section title
// Basic menu title
<orca.components.Menu>
<orca.components.MenuTitle title="File Operations" />
<orca.components.MenuText title="New" onClick={handleNew} />
<orca.components.MenuText title="Open" onClick={handleOpen} />
<orca.components.MenuSeparator />
<orca.components.MenuTitle title="Edit Operations" />
<orca.components.MenuText title="Copy" onClick={handleCopy} />
<orca.components.MenuText title="Paste" onClick={handlePaste} />
</orca.components.Menu>
// Menu title with additional info
<orca.components.Menu>
<orca.components.MenuTitle
title="Recent Documents"
info={<span className="count">{recentDocs.length}</span>}
/>
{recentDocs.map(doc => (
<orca.components.MenuText
key={doc.id}
title={doc.name}
onClick={() => openDoc(doc.id)}
/>
))}
</orca.components.Menu>
Full-screen modal overlay
// Basic modal
const [isVisible, setIsVisible] = useState(false);
<orca.components.Button onClick={() => setIsVisible(true)}>
Open Modal
</orca.components.Button>
<orca.components.ModalOverlay
visible={isVisible}
canClose={true}
onClose={() => setIsVisible(false)}
>
<div className="modal-content">
<h2>Modal Title</h2>
<p>This is the content of the modal...</p>
<orca.components.Button onClick={() => setIsVisible(false)}>
Close
</orca.components.Button>
</div>
</orca.components.ModalOverlay>
// Modal with blur effect
<orca.components.ModalOverlay
visible={isImportant}
blurred={true}
canClose={false}
className="important-modal"
>
<div className="confirmation-dialog">
<h3>Important Action Confirmation</h3>
<p>Are you sure you want to proceed? This action cannot be undone.</p>
<div className="actions">
<orca.components.Button variant="outline" onClick={handleCancel}>
Cancel
</orca.components.Button>
<orca.components.Button variant="dangerous" onClick={handleConfirm}>
Confirm
</orca.components.Button>
</div>
</div>
</orca.components.ModalOverlay>
Popup panel attached to an element
// Basic popup panel
const [isVisible, setIsVisible] = useState(false);
const buttonRef = useRef(null);
<orca.components.Button
ref={buttonRef}
onClick={() => setIsVisible(true)}
>
Show Popup
</orca.components.Button>
<orca.components.Popup
refElement={buttonRef}
visible={isVisible}
onClose={() => setIsVisible(false)}
>
<div className="popup-content">
<p>This is the popup content</p>
</div>
</orca.components.Popup>
// Custom positioned and aligned popup panel
<orca.components.Popup
refElement={anchorRef}
visible={showPopup}
placement="horizontal"
defaultPlacement="right"
alignment="center"
offset={10}
onClose={closePopup}
className="custom-popup"
>
<div className="info-card">
<h3>Details</h3>
<p>Here is more detailed content...</p>
</div>
</orca.components.Popup>
Segmented control for selecting from options
// Basic segmented control
const [selected, setSelected] = useState("list");
<orca.components.Segmented
selected={selected}
options={[
{ value: "list", label: "List" },
{ value: "grid", label: "Grid" },
{ value: "table", label: "Table" }
]}
onChange={(value) => setSelected(value)}
/>
// Segmented control with custom JSX
<orca.components.Segmented
selected={viewMode}
options={[
{ value: "day", jsx: <i className="ti ti-calendar-day" /> },
{ value: "week", jsx: <i className="ti ti-calendar-week" /> },
{ value: "month", jsx: <i className="ti ti-calendar-month" /> }
]}
onChange={setViewMode}
className="calendar-mode-selector"
/>
Dropdown select component
// Basic dropdown selector
const [selected, setSelected] = useState(["option1"]);
<orca.components.Select
selected={selected}
options={[
{ value: "option1", label: "Option 1" },
{ value: "option2", label: "Option 2" },
{ value: "option3", label: "Option 3" }
]}
onChange={(newSelected) => setSelected(newSelected)}
/>
// Multi-select dropdown with filtering
<orca.components.Select
selected={selectedTags}
options={availableTags}
multiSelection={true}
filter={true}
filterPlaceholder="Search tags..."
placeholder="Select tags"
onChange={handleTagsChange}
/>
// Grouped dropdown selector
<orca.components.Select
selected={[selectedLanguage]}
options={[
{ value: "js", label: "JavaScript", group: "Frontend" },
{ value: "ts", label: "TypeScript", group: "Frontend" },
{ value: "py", label: "Python", group: "Backend" },
{ value: "go", label: "Golang", group: "Backend" }
]}
pre={<i className="ti ti-code" />}
alignment="left"
width="200px"
onChange={(selected) => setSelectedLanguage(selected[0])}
/>
Loading placeholder
// Basic loading placeholder
<div className="loading-container">
<orca.components.Skeleton />
</div>
// Layout during content loading
<div className="content-card">
<div className="header">
{isLoading ? <orca.components.Skeleton /> : <h2>{title}</h2>}
</div>
<div className="body">
{isLoading ? (
<>
<orca.components.Skeleton />
<orca.components.Skeleton />
<orca.components.Skeleton />
</>
) : (
<p>{content}</p>
)}
</div>
</div>
Toggle switch component
// Basic switch
const [isOn, setIsOn] = useState(false);
<orca.components.Switch
on={isOn}
onChange={(newValue) => setIsOn(newValue)}
/>
// Read-only switch
<orca.components.Switch
on={featureEnabled}
readonly={true}
/>
// Unset state switch
<orca.components.Switch
unset={true}
onChange={handleInheritedSetting}
/>
// Switch with label
<div className="setting-row">
<label>Enable Notifications</label>
<orca.components.Switch
on={notificationsEnabled}
onChange={toggleNotifications}
/>
</div>
Data table component
// Basic data table
<orca.components.Table
columns={[
{ name: "Name", icon: "ti ti-file" },
{ name: "Size", icon: "ti ti-ruler" },
{ name: "Modified Date", icon: "ti ti-calendar" }
]}
items={files}
initialColumnSizes="2fr 1fr 1fr"
rowRenderer={(item, className, index) => (
<tr key={item.id} className={className}>
<td>{item.name}</td>
<td>{item.size}</td>
<td>{item.modifiedDate}</td>
</tr>
)}
/>
// Table with pinned column and resizable columns
<orca.components.Table
columns={[
{ name: "ID" },
{ name: "Product Name" },
{ name: "Price" },
{ name: "Stock" }
]}
items={products}
initialColumnSizes="80px 2fr 1fr 1fr"
pinColumn={true}
onColumnResize={handleColumnResize}
className="products-table"
rowRenderer={(product, className, index) => (
<tr key={product.id} className={className} onClick={() => selectProduct(product.id)}>
<td>{product.id}</td>
<td>{product.name}</td>
<td>{formatCurrency(product.price)}</td>
<td>{product.stock}</td>
</tr>
)}
/>
Provides a popup menu for tag selection and creation. Allows users to search, select existing tags, or create new ones.
// Basic usage
<orca.components.TagPopup
blockId={123}
closeMenu={() => setMenuVisible(false)}
onTagClick={(tag) => console.log(`Selected tag: ${tag}`)}
>
{(open) => (
<orca.components.Button variant="outline" onClick={open}>
Add Tag
</orca.components.Button>
)}
</orca.components.TagPopup>
// Custom placeholder text
<orca.components.TagPopup
blockId={456}
closeMenu={handleClose}
onTagClick={handleTagSelect}
placeholder="Search or create a new tag..."
container={containerRef}
>
{(open) => (
<span onClick={open}>Manage Tags</span>
)}
</orca.components.TagPopup>
Provides an editor interface for managing and configuring tag properties. Allows users to add, edit, and delete tag properties, set property types and values.
// Basic usage
<orca.components.TagPropsEditor
blockId={123}
>
{(open) => (
<orca.components.Button variant="outline" onClick={open}>
Edit Tag Properties
</orca.components.Button>
)}
</orca.components.TagPropsEditor>
// With custom container
<orca.components.TagPropsEditor
blockId={456}
container={containerRef}
>
{(open) => (
<span onClick={open}>Configure Properties</span>
)}
</orca.components.TagPropsEditor>
// Combined with other components
<div className="tag-controls">
<orca.components.TagPropsEditor blockId={789}>
{(open) => (
<orca.components.Button
variant="plain"
onClick={open}
className="property-button"
>
<i className="ti ti-settings" />
</orca.components.Button>
)}
</orca.components.TagPropsEditor>
</div>
Tooltip component
// Basic text tooltip
<orca.components.Tooltip text="Delete this item">
<button><i className="ti ti-trash" /></button>
</orca.components.Tooltip>
// Tooltip with shortcut
<orca.components.Tooltip
text="Save document"
shortcut="⌘S"
defaultPlacement="bottom"
>
<orca.components.Button variant="solid">
<i className="ti ti-device-floppy" />
</orca.components.Button>
</orca.components.Tooltip>
// Tooltip with image preview
<orca.components.Tooltip
text="View original image"
image="/path/to/preview.jpg"
placement="horizontal"
alignment="top"
delay={500}
>
<div className="thumbnail">
<img src="/path/to/thumbnail.jpg" alt="Thumbnail" />
</div>
</orca.components.Tooltip>
Content converter API, used to register converters for transforming blocks and inline content between different formats (e.g., HTML, plain text, Markdown).
Converts a block to a specific format. This is typically used internally by the system when exporting content.
The target format to convert to
The block content to convert
The block representation object
Optional
block: BlockOptional full block data
Optional
forExport: booleanWhether the conversion is for export purposes
A Promise that resolves to the converted string
Converts an inline content fragment to a specific format. This is typically used internally by the system when exporting content.
The target format to convert to
The type of the inline content
The inline content fragment to convert
A Promise that resolves to the converted string
Registers a block converter for transforming a block type to a specific format.
The target format (e.g., "plain", "html", "markdown")
The block type to convert from
Conversion function that transforms block content to the target format
// Convert a countdown block to HTML
orca.converters.registerBlock(
"html",
"myplugin.countdown",
(blockContent, repr, block, forExport) => {
const date = new Date(repr.date)
return `<div class="countdown" data-date="${date.toISOString()}">
<span class="label">${repr.label}</span>
<span class="date">${date.toLocaleDateString()}</span>
</div>`
}
)
Registers an inline content converter for transforming inline content to a specific format.
The target format (e.g., "plain", "html", "markdown")
The inline content type to convert from
Conversion function that transforms inline content to the target format
// Convert a custom highlight inline content to Markdown
orca.converters.registerInline(
"markdown",
"myplugin.highlight",
(content) => {
return `==${content.v}==`
}
)
// Convert a user mention to HTML
orca.converters.registerInline(
"html",
"myplugin.userMention",
(content) => {
return `<span class="user-mention" data-user-id="${content.id}">@${content.v}</span>`
}
)
Headbar API for registering custom buttons in the application's header bar.
Registers a custom button in the Orca headbar.
A unique identifier for the button
A function that returns a React element to render
Navigation API, used to control Orca's panel navigation and layout. Provides methods for managing panels, navigating between views, and handling navigation history.
Adds a new panel next to an existing panel in the specified direction.
The ID of the existing panel to add the new panel next to
The direction to add the panel ("top", "bottom", "left", or "right")
Optional
src: Pick<ViewPanel, "view" | "viewArgs" | "viewState">Optional parameters for the new panel's view, view arguments, and state
The ID of the newly created panel, or null if the panel couldn't be created
Navigates to a specific view in the specified panel or current active panel.
The type of view to navigate to ("journal" or "block")
Optional
viewArgs: Record<string, any>Arguments for the view, such as blockId or date
Optional
panelId: stringOptional panel ID to navigate in, defaults to active panel
Moves a panel from one location to another in the specified direction.
The ID of the panel to move
The ID of the destination panel
The direction to move the panel relative to the destination panel
Opens a view in the last used panel or creates a new one if needed. Useful for opening content in a separate panel.
The type of view to open ("journal" or "block")
Optional
viewArgs: Record<string, any>Arguments for the view, such as blockId or date
Display a notification to the user. Notifications appear in the bottom right corner of the application and can be used to inform users about events, actions, or state changes.
The type of notification, which determines its appearance and icon
The main notification message to display
Optional
options: { action?: () => void | Promise<void>; title?: string }Optional configuration including title and action callback
// Simple info notification
orca.notify("info", "Processing complete")
// Error notification with title
orca.notify("error", "Failed to connect to API", {
title: "Connection Error"
})
// Success notification with action button
orca.notify("success", "File exported successfully", {
title: "Export Complete",
action: () => {
orca.commands.invokeCommand("myplugin.openExportedFile")
}
})
Plugin management API, used to register, enable, disable, and manage plugin data and settings.
Retrieves data stored by a plugin.
The name of the plugin
The key of the data to retrieve
A Promise that resolves to the stored data
Loads a plugin with the given schema and settings. This is typically called internally by the plugin system.
The name of the plugin to load
The settings schema for the plugin
The current settings for the plugin
A Promise that resolves when the plugin is loaded
Stores data for a plugin.
The name of the plugin
The key to store the data under
The data to store (string, number, ArrayBuffer, or null)
A Promise that resolves when the data is stored
Sets settings for a plugin at either the application or repository level.
The scope of the settings ("app" for application-wide or "repo" for repository-specific)
The name of the plugin
The settings to set
A Promise that resolves when settings are saved
Sets the settings schema for a plugin, defining what settings are available and how they should be presented in the UI.
The name of the plugin
The settings schema defining available settings
A Promise that resolves when the schema is set
Unloads a plugin. This is called when disabling or unregistering a plugin. This is typically called internally by the plugin system.
The name of the plugin to unload
A Promise that resolves when the plugin is unloaded
Renderer management API, used to register custom block and inline content renderers.
Registers a custom block renderer.
The type identifier for the block (e.g., "myplugin.diagram")
Whether this block type should be editable
The React component that renders the block
Optional
assetFields: string[]Optional array of property names that may contain asset references (used for proper asset handling during import/export)
import DiagramBlock from "./DiagramBlock"
// Register a block renderer without asset fields
orca.renderers.registerBlock(
"myplugin.diagram",
true,
DiagramBlock
)
// Register a block renderer with asset fields
orca.renderers.registerBlock(
"myplugin.attachment",
true,
AttachmentBlock,
["url", "thumbnailUrl"]
)
Registers a custom inline content renderer.
The type identifier for the inline content (e.g., "myplugin.special")
Whether this inline content should be editable
The React component that renders the inline content
Keyboard shortcuts management API, used to assign, reset and reload keyboard shortcuts.
Assigns a keyboard shortcut to a command. If the shortcut is empty, it will remove the shortcut from the command.
The keyboard shortcut string (e.g., "ctrl+shift+k" or "meta+p")
The command ID to bind the shortcut to
A Promise that resolves when the shortcut is assigned
Reloads all keyboard shortcuts from the database. Usually not needed to be called directly as the system handles this automatically.
A Promise that resolves when shortcuts are reloaded
Slash commands API for registering custom commands that appear when a user types '/' in the editor. Slash commands provide quick access to actions directly from the editor.
Registers a slash command that appears in the slash command menu.
A unique identifier for the command
The slash command configuration
The current state of the Orca Note application. This object contains the reactive state that updates as the application changes. Plugins can read from this state to understand the current context and subscribe to changes.
The ID of the currently active (focused) panel. This can be used to target operations to the user's current working context.
Registry of block converters that transform block content to different formats. Organized as a nested record with format as the first key and block type as the second.
Registry of block menu commands that appear in block context menus. These commands provide custom actions for blocks.
Registry of block renderer components used to render different block types. Each key is a block type, and the value is the React component used to render it.
Map of all blocks currently loaded in memory, indexed by their database IDs. This provides quick access to block data without needing backend queries.
Indicates whether the command palette is currently opened. This can be used to conditionally change behavior when the command palette is active.
Registry of all registered commands in the application, indexed by their IDs. Each command includes pinyin data for search functionality.
The absolute path to the application data directory. This is where Orca stores configuration and other application-level data.
Optional
filterInTags?: stringOptional filter for tags shown in the tags panel. When set, only tags that match this filter will be displayed.
Indicates whether the global search panel is currently opened. This can be used to conditionally change behavior when search is active.
Registry of custom buttons registered for the header bar. Each entry contains a render function that returns a React element.
Registry of inline content converters that transform inline content to different formats. Organized as a nested record with format as the first key and content type as the second.
Registry of inline renderer components used to render different inline content types. Each key is a content type, and the value is the React component used to render it.
The current locale of the application (e.g., "en" for English, "zh-CN" for Chinese). This determines the language used for the UI and can be used for localization.
Array of active notifications currently displayed to the user. Each notification includes a type, message, and optional title and action.
History of past panel states for backward navigation. This is used to implement the back button functionality in the UI.
History of forward panel states for forward navigation after going back. This is used to implement the forward button functionality in the UI.
The root panel structure that defines the current layout of the application. This contains all panels and their arrangement in rows and columns.
Registry of all installed plugins, indexed by their names. Each entry contains the plugin metadata and its loaded module if active.
The name of the current repository. This is the identifier for the currently open note repository.
Optional
repoDir?: stringThe absolute path to the current repository directory, if a repository is added from non-standard location. This is where the current note repository is stored on the file system.
Application and repository settings, indexed by their numeric IDs. Contains configuration values for both the application and the current repository.
Indicates whether the settings panel is currently opened. This can be used to conditionally change behavior when settings are being edited.
Registry of keyboard shortcuts, mapping shortcut strings to command IDs. This defines the current keyboard bindings in the application.
The currently active tab in the sidebar. This indicates which sidebar section is currently displayed.
Registry of slash commands available in the editor, indexed by their IDs. Each command includes pinyin data for search functionality.
Registry of tag menu commands that appear in tag context menus. These commands provide custom actions for tags.
The current theme mode of the application ("light" or "dark"). This determines whether the light or dark theme variant is active.
Registry of installed themes, mapping theme names to CSS file paths. This defines all available themes that can be selected.
Registry of toolbar buttons or button groups registered for the editor toolbar. Each entry can be a single button configuration or an array of related buttons.
Tag menu commands API for adding custom commands to tag context menus. This allows plugins to add custom actions that appear when users open the tag's context menu.
Registers a custom command in the tag context menu.
A unique identifier for the command
The command configuration, including a render function that returns a React element
Theme management API, used to register, unregister, and manage visual themes.
Injects a CSS resource into the application. Useful for adding styles that are not part of a theme but are needed by a plugin.
The URL or path to the CSS resource
A unique identifier for the resource to allow for later removal
Registers a theme with Orca.
The name of the plugin registering the theme
The display name of the theme
The file path to the theme CSS file (relative to plugin directory)
Toolbar API for registering custom buttons in the block editor toolbar.
Registers a toolbar button or group of buttons.
A unique identifier for the button
Button configuration or array of button configurations
// Register a single button with a command
orca.toolbar.registerToolbarButton("myplugin.formatButton", {
icon: "ti ti-wand",
tooltip: "Format text",
command: "myplugin.formatText"
})
// Register a button with a dropdown menu
const MenuText = orca.components.MenuText
orca.toolbar.registerToolbarButton("myplugin.insertButton", {
icon: "ti ti-plus",
tooltip: "Insert special content",
menu: (close) => (
<>
<MenuText
title="Insert Table"
onClick={() => {
close()
orca.commands.invokeCommand("myplugin.insertTable")
}}
/>
<MenuText
title="Insert Chart"
onClick={() => {
close()
orca.commands.invokeCommand("myplugin.insertChart")
}}
/>
</>
)
})
// Register a group of related buttons
orca.toolbar.registerToolbarButton("myplugin.formattingTools", [
{
icon: "ti ti-bold",
tooltip: "Bold",
command: "myplugin.makeBold"
},
{
icon: "ti ti-italic",
tooltip: "Italic",
command: "myplugin.makeItalic"
}
])
Invokes a backend API with the specified API type and arguments. This is a core method for plugins to communicate with the Orca backend systems.
The API message type to invoke, which specifies what backend functionality to call
Any additional arguments needed by the specified backend API
A Promise that resolves with the result from the backend call
// Get a block by its ID
const block = await orca.invokeBackend("get-block", 12345)
console.log(`Block content: ${block.text}`)
// Get blocks with specific tags
const taggedBlocks = await orca.invokeBackend(
"get-blocks-with-tags",
["project", "active"]
)
console.log(`Found ${taggedBlocks.length} active projects`)
The main Orca API entry, access it with the global
orca
object.Example