@ridit/editor-ui
Headless UI primitives for @ridit/editor. Framework-agnostic, DOM-based components built for performance — virtualized lists, file trees, resizable panels, context menus, and more.
Installation
npm install @ridit/editor-ui
Components
VirtualTree
A virtualized file explorer tree with lazy-loading, drag-and-drop, rename, and context menu support.
import { VirtualTree } from "@ridit/editor-ui";
const tree = VirtualTree(
{
folderStructure: {
root: { name: "my-project" },
path: "/my-project",
structure: [],
},
rowHeight: 28,
onSelect: (id, node) => {
console.log("selected:", node.path);
},
onOpenFoldersChange: (openFolders) => {
},
initialOpenFolders: ["/my-project/src"],
renderRight: (row) => {
return null;
},
},
fileSystemService,
);
document.body.appendChild(tree.el);
API
tree.select('/my-project/src/index.ts')
tree.highlight('/my-project/src/index.ts')
tree.clear_highlight()
tree.open('/my-project/src')
tree.close('/my-project/src')
tree.toggle('/my-project/src')
tree.add(node)
tree.remove('/my-project/src/old.ts')
tree.rename('/old/path', '/new/path')
tree.mutate((nodes) => { ... })
tree.destroy()
VirtualList
High-performance virtualized list for rendering large datasets.
import { VirtualList } from "@ridit/editor-ui";
const list = VirtualList<MyItem>({
items: myItems,
itemHeight: 32,
overscan: 5,
render: async (item) => {
const el = document.createElement("div");
el.textContent = item.name;
return el;
},
});
document.body.appendChild(list.el);
list.update_rows(newItems);
list.refresh();
list.destroy();
Splitter
Resizable panel splitter with collapse support.
import { Splitter } from '@ridit/editor-ui'
const splitter = Splitter({
direction: 'horizontal',
panels: [
{ id: 'sidebar', size: 20, collapsible: true, el: sidebarEl },
{ id: 'editor', el: editorEl },
],
gutterSize: 1,
onCollapse: (id, collapsed) => { ... },
onResizeEnd: (sizes) => { ... },
})
document.body.appendChild(splitter.el)
splitter.destroy()
ScrollArea
Custom scrollbar overlay with smooth scrolling.
import { ScrollArea } from "@ridit/editor-ui";
const scroll = ScrollArea();
scroll.viewport.appendChild(myContent);
document.body.appendChild(scroll.el);
Keyboard-accessible right-click context menu.
import { ContextMenu } from '@ridit/editor-ui'
const menu = ContextMenu()
menu.bind(myElement, () => [
{
type: 'item',
label: 'Rename',
onClick: () => { ... },
command_id: 'F2',
},
{ type: 'separator' },
{
type: 'item',
label: 'Delete',
onClick: () => { ... },
command_id: 'Delete',
},
])
document.body.appendChild(menu.el)
menu.destroy()
Button
Accessible button with variants and tooltip support.
import { Button } from '@ridit/editor-ui'
import { icon } from '@ridit/editor-ui/utils'
const btn = Button(icon('plus'), {
variant: 'ghost',
onClick: (e) => { ... },
tooltip: { text: 'Add item', delay: 200 },
})
Styling
Import the bundled CSS in your entry point:
import "@ridit/editor-ui/static-css/workbench.css";
or individual component styling:
import "@ridit/editor-ui/static-css/components/componentName.css";
Components use CSS variables for theming. Override them to match your design:
:root {
--explorer-foreground: #abb2bf;
--explorer-item-hover-background: rgba(255, 255, 255, 0.05);
--explorer-item-hover-foreground: #ffffff;
--explorer-item-active-background: rgba(255, 255, 255, 0.1);
--explorer-item-active-foreground: #ffffff;
}
License
MIT