ワンクリックで
heimdall-overlays
Heimdall component guide for Overlays: Modal, ConfirmDialog, Toast, CommandPalette, WorkspaceSwitcherDialog, Drawer
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Heimdall component guide for Overlays: Modal, ConfirmDialog, Toast, CommandPalette, WorkspaceSwitcherDialog, Drawer
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Heimdall component guide for Charts: Sparkline, LineChart, BarChart, BarV, BarH, StackedBar, Donut, PieChart, Heatmap, StatusTimeline, ProgressBar, MetricRow
Heimdall component guide for Chat: ChatMessage, ToolBlock, ThinkingBlock, ChatDivider, ChatSuggestions, ChatComposer, ChatContainer
Heimdall component guide for Data Display: StatTile, StatGrid, Table, KVGrid, InspectorPanel
Heimdall component guide for Graph: GraphCanvas, GraphNode, GraphEdge, GraphInspector, TopologyNode, HierarchyRow, HierarchyTree
Heimdall component guide for Inputs: TextInput, TextArea, NumberInput, Select, TriState, Field, FilterDropdown, EntityPicker, KeyValueEditor, OrderedList, RelationshipBuilder
Heimdall component guide for Layout: Panel, SplitPane
| name | heimdall-overlays |
| description | Heimdall component guide for Overlays: Modal, ConfirmDialog, Toast, CommandPalette, WorkspaceSwitcherDialog, Drawer |
Import all components from @tinkermonkey/heimdall-ui. Import the CSS once at your app entry point:
import '@tinkermonkey/heimdall-ui/css'
General-purpose dialog with header, body, footer, and optional hint strip.
import { Modal } from '@tinkermonkey/heimdall-ui'
| Prop | Type | Default | Description |
|---|---|---|---|
isOpen | boolean | required | Controls visibility |
onClose | () => void | required | Called on Escape, backdrop click, or close button |
title | string | — | Header title |
subtitle | string | — | Secondary line below title |
children | ReactNode | required | Modal body |
footer | ReactNode | — | Footer slot (typically action buttons) |
hintFooter | string | — | Monospace hint strip below footer |
size | 'sm' | 'md' | 'lg' | 'xl' | 'md' | Width: sm=360px, md=480px, lg=640px, xl=820px |
// Minimal
<Modal isOpen={open} onClose={() => setOpen(false)} title="Create entity">
<p>Modal body content.</p>
</Modal>
// With footer and hint
<Modal
isOpen={open}
onClose={() => setOpen(false)}
title="Import data"
subtitle="428 individuals · last synced 2m ago"
size="lg"
footer={
<div className="flex gap-2 justify-end">
<Button variant="ghost" onClick={() => setOpen(false)}>Cancel</Button>
<Button variant="primary" onClick={handleImport}>Import</Button>
</div>
}
hintFooter="↵ confirm esc close"
>
{/* form content */}
</Modal>
useFocusTrap)useBodyOverflow)title is providedonClose only when clicking the backdrop itself, not child elementsSpecialized two-button confirmation dialog. Default variant is 'danger' (red confirm button).
import { ConfirmDialog } from '@tinkermonkey/heimdall-ui'
| Prop | Type | Default | Description |
|---|---|---|---|
isOpen | boolean | required | Controls visibility |
onClose | () => void | required | Cancel handler |
onConfirm | () => void | required | Confirm handler |
title | string | — | Dialog title |
subtitle | string | — | Secondary line below title |
message | ReactNode | required | Consequence description |
confirmLabel | string | 'Confirm' | Confirm button text |
cancelLabel | string | 'Cancel' | Cancel button text |
variant | 'primary' | 'danger' | 'danger' | Confirm button color |
<ConfirmDialog
isOpen={open}
onClose={() => setOpen(false)}
onConfirm={() => { deleteEntity(); setOpen(false) }}
title="Delete entity"
message={<>Delete <code>cls_organism</code>? 47 individuals will be unlinked.</>}
confirmLabel="Delete"
/>
// Primary variant (non-destructive confirmation)
<ConfirmDialog
isOpen={open}
onClose={() => setOpen(false)}
onConfirm={() => { deploy(); setOpen(false) }}
title="Deploy to production"
message="This will push the current build to the production environment."
confirmLabel="Deploy"
variant="primary"
/>
onConfirm does not auto-close — you must call setOpen(false) inside your onConfirm handleronClose is wired to the Cancel button and does auto-closeModal; inherits Escape key, backdrop click, and focus trap behaviorAuto-dismissing notification. Positioned via style prop — the component does not self-position.
import { Toast } from '@tinkermonkey/heimdall-ui'
| Prop | Type | Default | Description |
|---|---|---|---|
isOpen | boolean | required | Controls visibility |
onClose | () => void | required | Called after auto-dismiss or dismiss button click |
title | string | — | Primary message |
subtitle | string | — | Secondary detail |
variant | 'success' | 'error' | 'warning' | 'info' | 'info' | Color and icon preset |
icon | IconName | — | Overrides variant's default icon |
duration | number | 4000 | Auto-dismiss delay in ms; 0 disables auto-dismiss |
// Positioned at bottom-right
<Toast
isOpen={toastOpen}
onClose={() => setToastOpen(false)}
title="Pipeline complete"
subtitle="1,234 records processed."
variant="success"
style={{ position: 'fixed', bottom: 24, right: 24, zIndex: 9999 }}
/>
// Error that stays open until dismissed
<Toast
isOpen={toastOpen}
onClose={() => setToastOpen(false)}
title="Sync failed"
subtitle="Connection timeout after 30s."
variant="error"
duration={0}
style={{ position: 'fixed', bottom: 24, right: 24, zIndex: 9999 }}
/>
style — it has no built-in fixed positioningduration={0} disables auto-dismiss; the user must click the dismiss buttonvariant controls both color (emerald/rose/amber/cyan) and ARIA role (role="alert" for error/warning, role="status" for others)Full-screen command search overlay with fuzzy text filter and keyboard navigation.
import { CommandPalette } from '@tinkermonkey/heimdall-ui'
| Prop | Type | Default | Description |
|---|---|---|---|
isOpen | boolean | required | Controls visibility |
onClose | () => void | required | Called on Escape or backdrop click |
commands | Command[] | [] | Available commands |
placeholder | string | 'Search commands…' | Search input placeholder |
emptyMessage | string | 'No commands found' | Message when no results match |
interface Command {
id: string
label: string
description?: string
icon?: IconName
onSelect: () => void
}
<CommandPalette
isOpen={paletteOpen}
onClose={() => setPaletteOpen(false)}
commands={[
{ id: 'create', label: 'Create class', description: 'Add a new schema class', icon: 'plus', onSelect: () => navigate('/schema/new') },
{ id: 'run', label: 'Run pipeline', icon: 'pipeline', onSelect: () => runPipeline() },
{ id: 'settings', label: 'Open settings', icon: 'settings', onSelect: () => navigate('/settings') },
]}
/>
isOpen becomes truelabel and description (case-insensitive)onSelect(), and closes the paletteModal for switching between workspaces, with recent workspace list and optional action tiles.
import { WorkspaceSwitcherDialog } from '@tinkermonkey/heimdall-ui'
| Prop | Type | Default | Description |
|---|---|---|---|
isOpen | boolean | required | Controls visibility |
onClose | () => void | required | Called when dialog should close |
title | string | 'Switch Workspace' | Dialog heading |
current | Workspace | — | Currently active workspace (highlighted with "open" badge) |
recent | Workspace[] | [] | List of recent workspaces |
onPickRecent | (workspace: Workspace) => void | required | Called when a recent workspace is selected |
onOpenFolder | () => void | — | When provided, renders "Open folder…" action tile |
onNewWorkspace | () => void | — | When provided, renders "New workspace…" action tile |
onCloneFromGit | () => void | — | When provided, renders "Clone from git…" action tile |
interface Workspace {
id: string
name: string
path?: string
classCount?: number
individualCount?: number
}
<WorkspaceSwitcherDialog
isOpen={open}
onClose={() => setOpen(false)}
current={{ id: 'ws-1', name: 'Production', path: '/workspaces/prod' }}
recent={[
{ id: 'ws-1', name: 'Production', path: '/workspaces/prod', classCount: 14, individualCount: 302 },
{ id: 'ws-2', name: 'Staging', path: '/workspaces/staging', classCount: 12, individualCount: 145 },
]}
onPickRecent={ws => { switchWorkspace(ws); setOpen(false) }}
onOpenFolder={() => openFolderPicker()}
onNewWorkspace={() => navigate('/new')}
/>
onPickRecent is required and does not auto-close — you must call setOpen(false) inside itsetOpen(false) there tooid matches current?.idSlide-in side panel with optional title, configurable edge, and custom width.
import { Drawer } from '@tinkermonkey/heimdall-ui'
| Prop | Type | Default | Description |
|---|---|---|---|
isOpen | boolean | required | Controls visibility |
onClose | () => void | required | Called on Escape or backdrop click |
title | string | — | Header title; omit for titleless drawer |
position | 'left' | 'right' | 'right' | Which edge to slide in from |
width | string | '320px' | Width as any CSS length |
children | ReactNode | required | Drawer body |
...HTMLAttributes | Standard div attributes |
// Right drawer (default)
<Drawer isOpen={open} onClose={() => setOpen(false)} title="Record details">
<KVGrid rows={metadataRows} />
</Drawer>
// Left navigation drawer
<Drawer
isOpen={open}
onClose={() => setOpen(false)}
title="Filters"
position="left"
width="380px"
>
{/* filter controls */}
</Drawer>
// Titleless drawer
<Drawer isOpen={open} onClose={() => setOpen(false)}>
{/* custom header rendered inside */}
</Drawer>
title is providedwidth accepts any valid CSS length: '320px', '50vw', '400px'