@1urso/generic-editor
v0.1.82
Published
<div align="center"> <a href="https://bearry.app"> <img src="https://cdn.bearry.app/images/logo_png.png" alt="Bearry - Streaming Tools" height="100"> </a> <br /> <br />
Readme
Overview
Generic Editor is an extensible visual layout builder built for modern React applications. It combines the ease-of-use of visual design suites with developer-grade data binding, real-time list rendering, 3D spatial transformations, and automated HTML generation for server-side printing or browser sources.
The library powers the overlay and template design tools found in Bearry - Streaming Tools.
Table of Contents
- Installation & Setup
- Key Capabilities
- User Interface Architecture
- 3D Transforms & Visual Effects
- Modes: Single Item vs. List
- Data Binding & Variables
- Style Bindings & Conditional Rules
- Templates
- Real-time Broadcasting & HTML Generation
- JSON Schema & Output
- API Reference
Installation & Setup
1. Install Package
npm install @1urso/generic-editor
# or
yarn add @1urso/generic-editor
# or
pnpm add @1urso/generic-editor2. Peer Dependencies
Install the required peer dependencies:
npm install @radix-ui/themes @radix-ui/react-icons react-resizable-panels re-resizable framer-motion @dnd-kit/core @dnd-kit/sortable @dnd-kit/utilities @emotion/react @emotion/styled3. Import Styles
Import the component stylesheet and Radix UI styles in your application root (e.g. main.tsx, App.tsx, or layout.tsx):
import "@1urso/generic-editor/dist/generic-editor.css";
import "@radix-ui/themes/styles.css";Key Capabilities
- Fluid Header Navigation: All primary sidebar controls (Properties, Blocks, Layers, History) and action triggers (Undo, Redo, Preview, Shortcuts, Import/Export, Templates) are centralized in the top header, maximizing vertical canvas area.
- Full-Height Workspace: The left sidebar offers 100% vertical space dedicated to the active tool, eliminating awkward nested scrollbars.
- 3D Spatial Transformations: Configure perspective, tilt, rotation across X/Y/Z axes, depth offsets, and floating animations for cards, badges, and list items.
- Single & List Layout Modes: Design static single-surface assets (certificates, banners, ID cards) or repeating dynamic lists (chat overlays, leaderboards, price lists).
- Interpolation & Data Binding: Double-brace syntax
{{variable}}with visual variable pickers. - Dynamic Style Binding: Bind element colors, backgrounds, and borders directly to live data properties without custom CSS.
- Real-Time Live Feed API: Exported list layouts include live broadcast hooks via
window.addItem(data)for streaming software like OBS, vMix, and WebViews. - Zero Emoji Design: Interface and iconography rely exclusively on clean SVG vector icons.
User Interface Architecture
Global Header
The top header is structured into functional segments:
- Navigation Island: Lateral collapse/expand toggle, brand indicator, and segmented tabs (
Propriedades,Blocos,Camadas,Histórico). - History Island: Instant Undo (
ResetIcon) and Redo (ReloadIcon) with shortcut bindings (Ctrl+Z,Ctrl+Y). - Mode Indicators: Visual pills displaying current operation mode (
Modo ListaorModo Único) and element counter. - Action Suite:
Preview: Live toggle with blue active highlight.Atalhos: Keyboard shortcut reference modal.Adicionar: Quick element insertion dropdown (Text, Image, Box, Text Container).Importar/Exportar: Full JSON serialization with Base64 asset preservation.Templates: Modal catalog of pre-configured layout templates.Testar&Salvar: Validation wizard and save callback hooks.
Full-Height Sidebar
The left panel automatically adapts based on header tab selection:
- Blocos: Categorized library of basic elements (Text, Image, Container), composite components (Text in Box, Badge, Separator), and structured list cards.
- Camadas: Complete element hierarchy and z-index reordering with drag-and-drop grouping.
- Histórico: Full step-by-step history log with one-click restore points.
- Propriedades: Activates automatically whenever an element is selected on canvas.
Properties Inspector & 3D Effects
When an element is selected, the inspector presents four segmented configuration tabs:
- Estilo:
- Typography: Font family (system and Google Fonts), size, weight, line height, text color, and alignment.
- Surface: Fill color, opacity, corner border radius, border thickness, border style, and shadow.
- Layout:
- Direct numerical coordinate inputs (X, Y).
- Exact dimensions (Width, Height).
- Rotation angle slider and circular handle.
- 3D:
- Preset buttons:
Isométrico,Tilt Suave,Cartão Flutuante,Resetar 3D. - Perspective field of view (
200pxto2000px). - 3D Rotations: Rotate X (tilt up/down), Rotate Y (tilt left/right), Rotate Z.
- 3D Depth: Translate Z (elevation off the surface).
- Levitation animation toggle: Continuous smooth floating effect.
- Preset buttons:
- Mais:
- Dynamic data binding and style variable assignments (
color,backgroundColor,borderColor). - Conditional formatting rules (greater than, less than, equals, contains).
- Dynamic data binding and style variable assignments (
3D Transforms & Visual Effects
Elements support CSS 3D matrix rendering in both single-canvas mode and repeating list items.
Available 3D Controls
| Property | CSS Equivalent | Range / Options | Description |
| :--- | :--- | :--- | :--- |
| perspective | perspective: <value>px | 200 to 2000 | Defines viewing distance and depth perception |
| rotateX | rotateX(<value>deg) | -180 to 180 | Vertical tilt forward or backward |
| rotateY | rotateY(<value>deg) | -180 to 180 | Horizontal tilt left or right |
| rotateZ | rotateZ(<value>deg) | -180 to 180 | Planar canvas rotation |
| translateZ | translateZ(<value>px) | -200 to 200 | Depth translation along Z axis |
| is3DFloating | Keyframe animation | boolean | Smooth continuous vertical hover floating |
3D JSON Representation
{
"id": "card-3d",
"type": "box",
"x": 40,
"y": 40,
"width": 320,
"height": 180,
"style": {
"backgroundColor": "#1e293b",
"borderRadius": "16px",
"perspective": 800,
"rotateX": 15,
"rotateY": -12,
"rotateZ": 2,
"translateZ": 30,
"is3DFloating": true,
"boxShadow": "0 20px 40px rgba(0,0,0,0.3)"
}
}Modes: Single Item vs. List
Single Mode (isList: false)
Ideal for standalone designs such as business cards, certificates, banners, or single-camera stream frames.
- Accepts a single data object:
{ "nome": "Gabriel", "cargo": "Engenheiro" }. - The canvas represents one independent surface.
List Mode (isList: true)
Ideal for live chat boxes, recent subscriber lists, alert queues, catalogs, and dynamic feeds.
- Accepts an array of objects:
[{ "nome": "Alice" }, { "nome": "Bob" }]. - The canvas defines the item blueprint which repeats automatically for each record.
- Configurable sorting, scroll direction (standard down or chat-style bottom-to-top), and max container heights.
Data Binding & Variables
Variables use double braces {{variableName}}. The editor matches them against incoming data records.
const layoutConfig = {
name: "Notificação de Stream",
isList: false,
props: [
{ name: "Nome do Usuário", dataName: "userName" },
{ name: "Mensagem", dataName: "message" },
{ name: "Avatar", dataName: "avatarUrl" }
]
};When an element contains Olá, {{userName}}!, providing { "userName": "Gabriel" } renders Olá, Gabriel!.
Style Bindings & Conditional Rules
Direct Style Bindings
Bind CSS styling attributes directly to variables in your data payload:
{
"type": "text",
"content": "Status: {{statusText}}",
"styleBindings": {
"color": "statusColor",
"backgroundColor": "badgeBg",
"borderColor": "statusBorder"
}
}Conditional Formatting Rules
Create rules that evaluate live values and apply styles or toggle visibility:
{
"conditions": [
{
"id": "rule-high-value",
"property": "price",
"operator": "greaterThan",
"value": "100",
"style": {
"color": "#ef4444",
"fontWeight": "bold"
}
}
]
}Supported operators: equals, notEquals, contains, greaterThan, lessThan, truthy, and falsy.
Templates
Pass predefined layout states to allow users to quickly switch presets:
import { EditorContent, type ITemplate } from "@1urso/generic-editor";
const templates: ITemplate[] = [
{
id: "classic-chat",
name: "Chat Clássico",
description: "Layout leve para chat de stream.",
state: templateJsonClassic
},
{
id: "modern-card",
name: "Cartão 3D",
description: "Card moderno com profundidade 3D.",
state: templateJsonCard
}
];
export function MyEditor() {
return (
<EditorContent
layout={layoutConfig}
templates={templates}
onSave={(json) => console.log(json)}
/>
);
}Real-time Broadcasting & HTML Generation
Use generateHTML to convert your saved JSON layouts into standalone HTML strings ready for OBS browser sources, headless Chrome rendering, or PDF generation.
import { generateHTML } from "@1urso/generic-editor";
const htmlOutput = generateHTML(savedState.elements, initialData, {
isList: savedState.isList,
listSettings: savedState.listSettings,
canvasHeight: savedState.canvasHeight
});Live Updates via window.addItem(data)
When isList: true is generated, the resulting HTML automatically embeds an event listener for live updates without page refreshes:
// In your OBS Browser Source or client script
if (window.addItem) {
window.addItem({
userName: "NovoSeguidor",
message: "Obrigado pela live!",
avatarUrl: "https://example.com/avatar.png"
});
}New items smoothly animate into view, respecting sorting and list height limits.
JSON Schema & Output
The payload returned by onSave includes full layout geometry, 3D transformations, and list properties:
{
"isList": true,
"elements": [
{
"id": "el-1700000000000",
"type": "text",
"content": "{{userName}}",
"x": 20,
"y": 20,
"width": 200,
"height": 36,
"rotation": 0,
"style": {
"color": "#ffffff",
"fontSize": "16px",
"fontFamily": "Inter",
"perspective": 800,
"rotateX": 10,
"rotateY": -5,
"translateZ": 20
}
}
],
"listSettings": {
"sortProp": "timestamp",
"sortOrder": "desc",
"newestPosition": "top",
"scrollDirection": "down",
"containerHeight": 600
},
"canvasHeight": 80
}API Reference
Component <EditorContent />
| Prop | Type | Required | Default | Description |
| :--- | :--- | :--- | :--- | :--- |
| layout | ILayout | Yes | - | Variable metadata and default list mode. |
| initialState | any | No | null | Pre-existing JSON layout state to load on mount. |
| onSave | (json: string) => void | No | - | Callback executed when user clicks Salvar. |
| theme | 'light' \| 'dark' | No | 'light' | Theme applied to Radix theme provider. |
| templates | ITemplate[] | No | [] | Catalog of ready-to-use template layouts. |
| activeTemplateId| string | No | - | Controlled template ID from parent. |
| onTemplateChange| (id: string) => void | No | - | Callback fired when user switches template. |
Core Types
export interface IProp {
name: string;
dataName: string;
}
export interface ILayout {
name: string;
isList?: boolean;
props: IProp[];
}
export interface ITemplate {
id: string;
name: string;
description?: string;
state: any;
}License
MIT - Developed by Bearry.
