@1urso/generic-editor 0.1.9 → 0.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +133 -130
- package/dist/editor/context.d.ts +4 -0
- package/dist/editor/utils/htmlGenerator.d.ts +1 -0
- package/dist/generic-editor.js +6018 -4978
- package/dist/generic-editor.umd.cjs +42 -33
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,141 +1,140 @@
|
|
|
1
1
|
# Generic Editor
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A powerful, framework-agnostic, and **100% customizable** React library for creating dynamic layouts, template generation, and visual editing. Designed to be the design engine within your application (Web, Electron, Tauri, Next.js, etc.).
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
## 📚
|
|
8
|
-
|
|
9
|
-
1. [
|
|
10
|
-
2. [
|
|
11
|
-
- [
|
|
12
|
-
- [Menu
|
|
13
|
-
- [
|
|
14
|
-
- [
|
|
15
|
-
3. [
|
|
16
|
-
- [
|
|
17
|
-
- [Data Binding
|
|
18
|
-
- [
|
|
19
|
-
- [
|
|
20
|
-
- [
|
|
7
|
+
## 📚 Table of Contents
|
|
8
|
+
|
|
9
|
+
1. [Installation and Configuration](#installation-and-configuration)
|
|
10
|
+
2. [User Guide (Visual Interface)](#user-guide-visual-interface)
|
|
11
|
+
- [Basic Manipulation](#basic-manipulation)
|
|
12
|
+
- [Context Menu and Styling](#context-menu-and-styling)
|
|
13
|
+
- [Working with Text and Fonts](#working-with-text-and-fonts)
|
|
14
|
+
- [Working with Images](#working-with-images)
|
|
15
|
+
3. [Developer Guide (Integration)](#developer-guide-integration)
|
|
16
|
+
- [Initialization and Props](#initialization-and-props)
|
|
17
|
+
- [Data Binding and Variables](#data-binding-and-variables)
|
|
18
|
+
- [Modes: Single Item vs. List](#modes-single-item-vs-list)
|
|
19
|
+
- [JSON Structure](#json-structure)
|
|
20
|
+
- [Generating HTML (Backend/Print)](#generating-html-backendprint)
|
|
21
21
|
4. [API Reference](#api-reference)
|
|
22
22
|
|
|
23
23
|
---
|
|
24
24
|
|
|
25
|
-
##
|
|
25
|
+
## Installation and Configuration
|
|
26
26
|
|
|
27
|
-
### 1.
|
|
27
|
+
### 1. Install the package
|
|
28
28
|
|
|
29
29
|
```bash
|
|
30
30
|
npm install @1urso/generic-editor
|
|
31
|
-
#
|
|
31
|
+
# or
|
|
32
32
|
yarn add @1urso/generic-editor
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
### 2.
|
|
35
|
+
### 2. Install Peer Dependencies
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
The editor uses modern libraries to ensure performance and accessibility. You need to install them in your project:
|
|
38
38
|
|
|
39
39
|
```bash
|
|
40
40
|
npm install @radix-ui/themes @radix-ui/react-icons react-resizable-panels re-resizable framer-motion @dnd-kit/core
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
### 3.
|
|
43
|
+
### 3. Import Styles
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
In your application entry file (e.g., `main.tsx`, `App.tsx`, or `layout.tsx` in Next.js), import the editor's CSS (required for the context menu) and Radix UI:
|
|
46
46
|
|
|
47
47
|
```tsx
|
|
48
|
-
import "@1urso/generic-editor/dist/generic-editor.css"; //
|
|
48
|
+
import "@1urso/generic-editor/dist/generic-editor.css"; // Essential for the editor to work
|
|
49
49
|
import "@radix-ui/themes/styles.css";
|
|
50
50
|
```
|
|
51
51
|
|
|
52
52
|
---
|
|
53
53
|
|
|
54
|
-
##
|
|
54
|
+
## User Guide (Visual Interface)
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
This section describes the features available to the **end user** who will use the editor on your platform.
|
|
57
57
|
|
|
58
|
-
###
|
|
58
|
+
### Basic Manipulation
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
The editor offers an experience similar to design tools like Canva or Figma:
|
|
61
61
|
|
|
62
|
-
- **
|
|
63
|
-
- **
|
|
64
|
-
- **
|
|
65
|
-
- **
|
|
66
|
-
- **
|
|
62
|
+
- **Add Elements**: Use the sidebar (or buttons you implement) to drag or click and add Texts, Images, or Boxes.
|
|
63
|
+
- **Move**: Click and drag any element to reposition it.
|
|
64
|
+
- **Resize**: Click on the element to select it. Pull the handles (blue squares) on the edges or corners to change the size.
|
|
65
|
+
- **Rotate**: When selecting an element, a circular handle will appear above it. Click and drag to rotate freely.
|
|
66
|
+
- **Delete**: Select an element and press the `Delete` key or use the context menu.
|
|
67
67
|
|
|
68
|
-
### Menu
|
|
68
|
+
### Context Menu and Styling
|
|
69
69
|
|
|
70
|
-
**
|
|
70
|
+
**Right-click** on any element to open the advanced options menu.
|
|
71
71
|
|
|
72
|
-
####
|
|
72
|
+
#### General Options (All Elements)
|
|
73
73
|
|
|
74
|
-
- **
|
|
75
|
-
- **
|
|
76
|
-
- **
|
|
77
|
-
-
|
|
78
|
-
-
|
|
79
|
-
- **
|
|
80
|
-
- **
|
|
81
|
-
-
|
|
82
|
-
-
|
|
74
|
+
- **Duplicate**: Creates an exact copy of the element next to the original.
|
|
75
|
+
- **Remove**: Deletes the element.
|
|
76
|
+
- **Layers**:
|
|
77
|
+
- _Bring to front_: Places the element above all others.
|
|
78
|
+
- _Send to back_: Places the element behind all others.
|
|
79
|
+
- **Background Color**: Changes the background color of the element (includes transparent).
|
|
80
|
+
- **Borders**:
|
|
81
|
+
- _Radius_: From 0px (square) to 50% (circle/oval).
|
|
82
|
+
- _Thickness_: Adds a solid border from 1px to 4px.
|
|
83
83
|
|
|
84
|
-
###
|
|
84
|
+
### Settings and Test Data
|
|
85
85
|
|
|
86
|
-
|
|
86
|
+
At the top of the left sidebar, the **Settings** button (gear icon) allows you to simulate how the layout will look with real data.
|
|
87
87
|
|
|
88
|
-
- **
|
|
89
|
-
-
|
|
90
|
-
-
|
|
91
|
-
-
|
|
92
|
-
-
|
|
93
|
-
- _Dados Únicos_: Um objeto JSON `{...}` para testar o modo único.
|
|
94
|
-
> Edite esses JSONs para ver o layout reagir em tempo real às suas variáveis.
|
|
88
|
+
- **List Configuration Tab**:
|
|
89
|
+
- _Sort Property_: Defines which field will be used to sort the list (e.g., `price`, `name`).
|
|
90
|
+
- _Order_: Ascending or Descending.
|
|
91
|
+
- _Newest Position_: Defines where the newest item appears ('top' or 'bottom').
|
|
92
|
+
- _Scroll Behavior_: Defines the scroll direction ('down' - default, or 'up' - chat-like).
|
|
95
93
|
|
|
96
|
-
###
|
|
94
|
+
### Working with Text and Fonts
|
|
97
95
|
|
|
98
|
-
|
|
96
|
+
When right-clicking on a **Text** element:
|
|
99
97
|
|
|
100
|
-
- **
|
|
101
|
-
- **
|
|
102
|
-
-
|
|
103
|
-
- **
|
|
104
|
-
- **
|
|
105
|
-
- **
|
|
106
|
-
- **
|
|
98
|
+
- **Edit Text**: Opens a window to type content. This is where you insert variables (e.g., Customer Name) by clicking on the available buttons.
|
|
99
|
+
- **Font**: Select from various web-safe fonts (Arial, Helvetica, etc.) and popular Google Fonts (Roboto, Open Sans, Montserrat).
|
|
100
|
+
- _Import Google Font_: Allows you to type the name of any Google Fonts font (e.g., "Pacifico") and the editor will automatically load it.
|
|
101
|
+
- **Size**: Adjust from 12px to 64px.
|
|
102
|
+
- **Text Color**: Pre-defined color palette.
|
|
103
|
+
- **Weight**: Normal or Bold.
|
|
104
|
+
- **Alignment**: Left, Center, or Right.
|
|
105
|
+
- **Vertical Alignment**: Top, Center, or Bottom.
|
|
107
106
|
|
|
108
|
-
###
|
|
107
|
+
### Working with Images
|
|
109
108
|
|
|
110
|
-
|
|
109
|
+
When right-clicking on an **Image** element:
|
|
111
110
|
|
|
112
|
-
- **
|
|
113
|
-
- _Upload_:
|
|
114
|
-
- _URL_:
|
|
115
|
-
- **
|
|
116
|
-
-
|
|
117
|
-
-
|
|
118
|
-
- **
|
|
111
|
+
- **Change Image**:
|
|
112
|
+
- _Upload_: Upload an image from your computer.
|
|
113
|
+
- _URL_: Paste a direct link to an image from the web.
|
|
114
|
+
- **Fit (Object Fit)**:
|
|
115
|
+
- _Fit (Contain)_: The entire image is shown inside the box, maintaining proportions (may leave white space).
|
|
116
|
+
- _Stretch (Fill)_: The image fills the entire box, potentially being cropped or distorted depending on the aspect ratio.
|
|
117
|
+
- **Bind Data**: Connects the image to a dynamic variable (e.g., Product Photo).
|
|
119
118
|
|
|
120
119
|
---
|
|
121
120
|
|
|
122
|
-
##
|
|
121
|
+
## Developer Guide (Integration)
|
|
123
122
|
|
|
124
|
-
###
|
|
123
|
+
### Initialization and Props
|
|
125
124
|
|
|
126
|
-
|
|
125
|
+
To start the editor, you must provide the `layout` configuration which dictates what data (variables) will be available to the user.
|
|
127
126
|
|
|
128
127
|
```tsx
|
|
129
128
|
import { EditorContent } from "@1urso/generic-editor";
|
|
130
129
|
|
|
131
130
|
const config = {
|
|
132
|
-
isList: false, //
|
|
133
|
-
name: "
|
|
131
|
+
isList: false, // Single mode (e.g., ID Card) or List (e.g., Catalog)
|
|
132
|
+
name: "Employee ID Card",
|
|
134
133
|
props: [
|
|
135
|
-
// Define
|
|
136
|
-
{ name: "
|
|
137
|
-
{ name: "
|
|
138
|
-
{ name: "
|
|
134
|
+
// Define the variables that will appear in the "Insert Variable" button
|
|
135
|
+
{ name: "Full Name", dataName: "nome" },
|
|
136
|
+
{ name: "Role", dataName: "cargo" },
|
|
137
|
+
{ name: "Profile Picture", dataName: "fotoUrl" },
|
|
139
138
|
],
|
|
140
139
|
};
|
|
141
140
|
|
|
@@ -145,44 +144,45 @@ function App() {
|
|
|
145
144
|
<EditorContent
|
|
146
145
|
layout={config}
|
|
147
146
|
onSave={(json) => saveToBackend(json)}
|
|
148
|
-
theme="light" //
|
|
147
|
+
theme="light" // Optional: 'light' or 'dark'
|
|
149
148
|
/>
|
|
150
149
|
</div>
|
|
151
150
|
);
|
|
152
151
|
}
|
|
153
152
|
```
|
|
154
153
|
|
|
155
|
-
### Data Binding
|
|
154
|
+
### Data Binding and Variables
|
|
156
155
|
|
|
157
|
-
|
|
156
|
+
The editor uses an interpolation system based on double braces `{{key}}`.
|
|
158
157
|
|
|
159
|
-
1. **
|
|
160
|
-
2. **
|
|
161
|
-
-
|
|
162
|
-
-
|
|
158
|
+
1. **Insertion**: The user does not need to type `{{...}}` manually. In the text edit window, they will see buttons (badges) with friendly names (e.g., "Full Name"). Clicking them inserts the `{{nome}}` code.
|
|
159
|
+
2. **Rendering**:
|
|
160
|
+
- If `data = { nome: "Maria" }`, the text "Hello {{nome}}" becomes "Hello Maria".
|
|
161
|
+
- If the variable does not exist in the data, the editor keeps the original text `{{nome}}` or displays empty, depending on the configuration.
|
|
163
162
|
|
|
164
|
-
###
|
|
163
|
+
### Modes: Single Item vs. List
|
|
165
164
|
|
|
166
|
-
|
|
165
|
+
The `isList` property drastically changes how the editor and HTML generator behave.
|
|
167
166
|
|
|
168
|
-
#### `isList: false` (
|
|
167
|
+
#### `isList: false` (Single Mode)
|
|
169
168
|
|
|
170
|
-
- **
|
|
171
|
-
- **
|
|
172
|
-
- **Canvas**:
|
|
169
|
+
- **Usage**: Certificates, ID Cards, Banners, Covers.
|
|
170
|
+
- **Data**: Expects a **Single Object** `{ nome: 'John', cargo: 'Dev' }`.
|
|
171
|
+
- **Canvas**: Shows a single page/art.
|
|
173
172
|
|
|
174
|
-
#### `isList: true` (
|
|
173
|
+
#### `isList: true` (List Mode)
|
|
175
174
|
|
|
176
|
-
- **
|
|
177
|
-
- **
|
|
175
|
+
- **Usage**: Price Lists, Catalogs, Shelf Labels, Reports.
|
|
176
|
+
- **Data**: Expects an **Array of Objects** `[{ nome: 'A' }, { nome: 'B' }]`.
|
|
178
177
|
- **Canvas**:
|
|
179
|
-
-
|
|
180
|
-
-
|
|
181
|
-
-
|
|
178
|
+
- The user designs the "Template Item".
|
|
179
|
+
- The editor repeats this model vertically for each item in the mock data array.
|
|
180
|
+
- Allows visualization of how the list behaves with multiple items.
|
|
181
|
+
- **Height Limit**: Elements are constrained within the defined item height (canvas height).
|
|
182
182
|
|
|
183
|
-
###
|
|
183
|
+
### JSON Structure
|
|
184
184
|
|
|
185
|
-
|
|
185
|
+
The output of `onSave` is a JSON ready to be stored.
|
|
186
186
|
|
|
187
187
|
```json
|
|
188
188
|
{
|
|
@@ -191,7 +191,7 @@ O output do `onSave` é um JSON pronto para ser armazenado.
|
|
|
191
191
|
{
|
|
192
192
|
"id": "uuid-v4",
|
|
193
193
|
"type": "text", // 'text' | 'image' | 'box'
|
|
194
|
-
"content": "
|
|
194
|
+
"content": "Name: {{nome}}",
|
|
195
195
|
"x": 50,
|
|
196
196
|
"y": 100,
|
|
197
197
|
"width": 200,
|
|
@@ -203,34 +203,37 @@ O output do `onSave` é um JSON pronto para ser armazenado.
|
|
|
203
203
|
"fontFamily": "Roboto",
|
|
204
204
|
"textAlign": "center"
|
|
205
205
|
},
|
|
206
|
-
"dataBinding": "nome" //
|
|
206
|
+
"dataBinding": "nome" // Optional, used for direct binding
|
|
207
207
|
}
|
|
208
208
|
],
|
|
209
209
|
"listSettings": {
|
|
210
210
|
"sortProp": "nome",
|
|
211
|
-
"sortOrder": "asc"
|
|
211
|
+
"sortOrder": "asc",
|
|
212
|
+
"newestPosition": "bottom",
|
|
213
|
+
"scrollDirection": "down"
|
|
212
214
|
}
|
|
213
215
|
}
|
|
214
216
|
```
|
|
215
217
|
|
|
216
|
-
###
|
|
218
|
+
### Generating HTML (Backend/Print)
|
|
217
219
|
|
|
218
|
-
|
|
220
|
+
To generate the final result (for printing, saving as PDF, or sending via email), use the `generateHTML` function. It runs in any JS environment (Node, Browser, etc.).
|
|
219
221
|
|
|
220
222
|
```typescript
|
|
221
223
|
import { generateHTML } from "@1urso/generic-editor";
|
|
222
224
|
|
|
223
|
-
// 1.
|
|
225
|
+
// 1. Load layout and data
|
|
224
226
|
const layout = JSON.parse(db.getLayout());
|
|
225
|
-
const dados = db.getFuncionarios(); // Array
|
|
227
|
+
const dados = db.getFuncionarios(); // Array or Object
|
|
226
228
|
|
|
227
|
-
// 2.
|
|
229
|
+
// 2. Generate HTML
|
|
228
230
|
const htmlString = generateHTML(layout.elements, dados, {
|
|
229
|
-
isList: layout.isList, //
|
|
231
|
+
isList: layout.isList, // Important to pass the correct mode
|
|
230
232
|
listSettings: layout.listSettings,
|
|
233
|
+
canvasHeight: layout.canvasHeight, // Optional: Force item height
|
|
231
234
|
});
|
|
232
235
|
|
|
233
|
-
// 3.
|
|
236
|
+
// 3. Inject where needed
|
|
234
237
|
document.getElementById("preview").innerHTML = htmlString;
|
|
235
238
|
```
|
|
236
239
|
|
|
@@ -238,24 +241,24 @@ document.getElementById("preview").innerHTML = htmlString;
|
|
|
238
241
|
|
|
239
242
|
## API Reference
|
|
240
243
|
|
|
241
|
-
###
|
|
244
|
+
### Component `<EditorContent />`
|
|
242
245
|
|
|
243
|
-
|
|
|
244
|
-
| -------------- | ------------------------ |
|
|
245
|
-
| `layout` | `ILayout` | **
|
|
246
|
-
| `initialState` | `any` |
|
|
247
|
-
| `onSave` | `(json: string) => void` |
|
|
248
|
-
| `mockData` | `any[]` |
|
|
246
|
+
| Property | Type | Required | Default | Description |
|
|
247
|
+
| -------------- | ------------------------ | -------- | ------- | --------------------------------------------- |
|
|
248
|
+
| `layout` | `ILayout` | **Yes** | - | Initial configuration of variables and mode. |
|
|
249
|
+
| `initialState` | `any` | No | `null` | JSON state to load a saved layout. |
|
|
250
|
+
| `onSave` | `(json: string) => void` | No | - | Callback triggered when clicking Save button. |
|
|
251
|
+
| `mockData` | `any[]` | No | `[]` | Data for immediate preview during editing. |
|
|
249
252
|
|
|
250
|
-
###
|
|
253
|
+
### TypeScript Types
|
|
251
254
|
|
|
252
255
|
#### `ILayout`
|
|
253
256
|
|
|
254
257
|
```typescript
|
|
255
258
|
interface ILayout {
|
|
256
|
-
name: string; //
|
|
257
|
-
isList?: boolean; //
|
|
258
|
-
props: IProp[]; //
|
|
259
|
+
name: string; // Layout name (metadata)
|
|
260
|
+
isList?: boolean; // Defines default behavior (List or Single)
|
|
261
|
+
props: IProp[]; // List of available variables
|
|
259
262
|
}
|
|
260
263
|
```
|
|
261
264
|
|
|
@@ -263,16 +266,16 @@ interface ILayout {
|
|
|
263
266
|
|
|
264
267
|
```typescript
|
|
265
268
|
interface IProp {
|
|
266
|
-
name: string; //
|
|
267
|
-
dataName: string; //
|
|
269
|
+
name: string; // Visible label (e.g., "Product Price")
|
|
270
|
+
dataName: string; // Object key (e.g., "product_price")
|
|
268
271
|
}
|
|
269
272
|
```
|
|
270
273
|
|
|
271
274
|
#### `EditorProps`
|
|
272
275
|
|
|
273
|
-
| Prop |
|
|
274
|
-
| -------------- | ------------------------ |
|
|
275
|
-
| `layout` | `ILayout` |
|
|
276
|
-
| `onSave` | `(json: string) => void` |
|
|
277
|
-
| `initialState` | `any` |
|
|
278
|
-
| `theme` | `'light' \| 'dark'` |
|
|
276
|
+
| Prop | Type | Required | Description |
|
|
277
|
+
| -------------- | ------------------------ | -------- | ------------------------------------- |
|
|
278
|
+
| `layout` | `ILayout` | Yes | Initial configuration and metadata. |
|
|
279
|
+
| `onSave` | `(json: string) => void` | No | Callback triggered on save. |
|
|
280
|
+
| `initialState` | `any` | No | Previously saved state (parsed JSON). |
|
|
281
|
+
| `theme` | `'light' \| 'dark'` | No | Interface theme (default: `'light'`). |
|
package/dist/editor/context.d.ts
CHANGED
|
@@ -14,6 +14,8 @@ export interface IElement {
|
|
|
14
14
|
export interface IListSettings {
|
|
15
15
|
sortProp?: string;
|
|
16
16
|
sortOrder: 'asc' | 'desc';
|
|
17
|
+
newestPosition?: 'top' | 'bottom';
|
|
18
|
+
scrollDirection?: 'up' | 'down';
|
|
17
19
|
}
|
|
18
20
|
export interface IProp {
|
|
19
21
|
name: string;
|
|
@@ -26,6 +28,7 @@ interface IEditorState {
|
|
|
26
28
|
mockData: any[];
|
|
27
29
|
singleMockData: Record<string, any>;
|
|
28
30
|
listSettings: IListSettings;
|
|
31
|
+
canvasHeight?: number;
|
|
29
32
|
availableProps: IProp[];
|
|
30
33
|
availableFonts: string[];
|
|
31
34
|
theme: 'light' | 'dark';
|
|
@@ -39,6 +42,7 @@ interface IEditorContext {
|
|
|
39
42
|
updateElement: (id: string, updates: Partial<IElement>) => void;
|
|
40
43
|
setMockData: (data: any[], singleData: Record<string, any>) => void;
|
|
41
44
|
updateListSettings: (settings: Partial<IListSettings>) => void;
|
|
45
|
+
setCanvasHeight: (height: number) => void;
|
|
42
46
|
loadState: (savedState: Partial<IEditorState>) => void;
|
|
43
47
|
}
|
|
44
48
|
export declare const EditorProvider: React.FC<{
|
|
@@ -2,6 +2,7 @@ import { IElement, IListSettings } from '../context';
|
|
|
2
2
|
interface RenderOptions {
|
|
3
3
|
isList?: boolean;
|
|
4
4
|
listSettings?: IListSettings;
|
|
5
|
+
canvasHeight?: number;
|
|
5
6
|
}
|
|
6
7
|
export declare const generateHTML: (elements: IElement[], data: any, options?: RenderOptions) => string;
|
|
7
8
|
export declare const getRendererCode: () => string;
|