@1urso/generic-editor 0.1.21 → 0.1.22

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.
Files changed (2) hide show
  1. package/README.md +340 -316
  2. package/package.json +77 -77
package/README.md CHANGED
@@ -1,316 +1,340 @@
1
- # Generic Editor
2
-
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
-
5
- ---
6
-
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
- 4. [API Reference](#api-reference)
22
-
23
- ---
24
-
25
- ## Installation and Configuration
26
-
27
- ### 1. Install the package
28
-
29
- ```bash
30
- npm install @1urso/generic-editor
31
- # or
32
- yarn add @1urso/generic-editor
33
- ```
34
-
35
- ### 2. Install Peer Dependencies
36
-
37
- The editor uses modern libraries to ensure performance and accessibility. You need to install them in your project:
38
-
39
- ```bash
40
- npm install @radix-ui/themes @radix-ui/react-icons react-resizable-panels re-resizable framer-motion @dnd-kit/core
41
- ```
42
-
43
- ### 3. Import Styles
44
-
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
-
47
- ```tsx
48
- import "@1urso/generic-editor/dist/generic-editor.css"; // Essential for the editor to work
49
- import "@radix-ui/themes/styles.css";
50
- ```
51
-
52
- ---
53
-
54
- ## User Guide (Visual Interface)
55
-
56
- This section describes the features available to the **end user** who will use the editor on your platform.
57
-
58
- ### Basic Manipulation
59
-
60
- The editor offers an experience similar to design tools like Canva or Figma:
61
-
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
-
68
- ### Context Menu and Styling
69
-
70
- **Right-click** on any element to open the advanced options menu.
71
-
72
- #### General Options (All Elements)
73
-
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
-
84
- #### Advanced Settings (Formatting and Conditions)
85
-
86
- **Right-click** and select **Advanced Settings** to access powerful data formatting and conditional styling options.
87
-
88
- - **Data Formatting**:
89
-
90
- - _Type_: Choose between Text (Default), Boolean (True/False), Date, or Number/Currency.
91
- - _Boolean_: Define custom labels for true/false values (e.g., "Active" / "Inactive").
92
- - _Date_: Custom date patterns (e.g., "DD/MM/YYYY HH:mm").
93
- - _Number_: Format as Decimal, Currency (with symbol), or Percentage.
94
-
95
- - **Conditional Formatting**:
96
- - Define rules to change the element's style based on data values.
97
- - _Example_: If `price` is greater than `100`, set text color to `red`.
98
- - _Action_: Choose between applying styles (Color, Bold, Background, etc.) or **Hiding the Element** completely.
99
- - Supports multiple rules with operators like Equals, Not Equals, Contains, Greater Than, Less Than, Truthy, and Falsy.
100
-
101
- ### Settings and Test Data
102
-
103
- At the top of the left sidebar, the **Settings** button (gear icon) allows you to simulate how the layout will look with real data.
104
-
105
- - **List Configuration Tab**:
106
- - _Sort Property_: Defines which field will be used to sort the list (e.g., `price`, `name`).
107
- - _Order_: Ascending or Descending.
108
- - _Newest Position_: Defines where the newest item appears ('top' or 'bottom').
109
- - _Scroll Behavior_: Defines the scroll direction ('down' - default, or 'up' - chat-like).
110
- - _Container Height_: Defines the fixed height of the list container in pixels. If the content exceeds this height, a vertical scrollbar will appear automatically.
111
-
112
- ### Working with Text and Fonts
113
-
114
- When right-clicking on a **Text** element:
115
-
116
- - **Edit Text**: Opens a window to type content. This is where you insert variables (e.g., Customer Name) by clicking on the available buttons.
117
- - **Font**: Select from various web-safe fonts (Arial, Helvetica, etc.) and popular Google Fonts (Roboto, Open Sans, Montserrat).
118
- - _Import Google Font_: Allows you to type the name of any Google Fonts font (e.g., "Pacifico") and the editor will automatically load it.
119
- - **Size**: Adjust from 12px to 64px.
120
- - **Text Color**: Pre-defined color palette.
121
- - **Weight**: Normal or Bold.
122
- - **Alignment**: Left, Center, or Right.
123
- - **Vertical Alignment**: Top, Center, or Bottom.
124
-
125
- ### Working with Images
126
-
127
- When right-clicking on an **Image** element:
128
-
129
- - **Change Image**:
130
- - _Upload_: Upload an image from your computer.
131
- - _URL_: Paste a direct link to an image from the web.
132
- - **Fit (Object Fit)**:
133
- - _Fit (Contain)_: The entire image is shown inside the box, maintaining proportions (may leave white space).
134
- - _Stretch (Fill)_: The image fills the entire box, potentially being cropped or distorted depending on the aspect ratio.
135
- - **Bind Data**: Connects the image to a dynamic variable (e.g., Product Photo).
136
-
137
- ---
138
-
139
- ## Developer Guide (Integration)
140
-
141
- ### Initialization and Props
142
-
143
- To start the editor, you must provide the `layout` configuration which dictates what data (variables) will be available to the user.
144
-
145
- ```tsx
146
- import { EditorContent } from "@1urso/generic-editor";
147
-
148
- const config = {
149
- isList: false, // Single mode (e.g., ID Card) or List (e.g., Catalog)
150
- name: "Employee ID Card",
151
- props: [
152
- // Define the variables that will appear in the "Insert Variable" button
153
- { name: "Full Name", dataName: "nome" },
154
- { name: "Role", dataName: "cargo" },
155
- { name: "Profile Picture", dataName: "fotoUrl" },
156
- ],
157
- };
158
-
159
- function App() {
160
- return (
161
- <div style={{ height: "100vh", width: "100%" }}>
162
- <EditorContent
163
- layout={config}
164
- onSave={(json) => saveToBackend(json)}
165
- theme="light" // Optional: 'light' or 'dark'
166
- />
167
- </div>
168
- );
169
- }
170
- ```
171
-
172
- ### Data Binding and Variables
173
-
174
- The editor uses an interpolation system based on double braces `{{key}}`.
175
-
176
- 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.
177
- 2. **Rendering**:
178
- - If `data = { nome: "Maria" }`, the text "Hello {{nome}}" becomes "Hello Maria".
179
- - If the variable does not exist in the data, the editor keeps the original text `{{nome}}` or displays empty, depending on the configuration.
180
-
181
- ### Modes: Single Item vs. List
182
-
183
- The `isList` property drastically changes how the editor and HTML generator behave.
184
-
185
- #### `isList: false` (Single Mode)
186
-
187
- - **Usage**: Certificates, ID Cards, Banners, Covers.
188
- - **Data**: Expects a **Single Object** `{ nome: 'John', cargo: 'Dev' }`.
189
- - **Canvas**: Shows a single page/art.
190
-
191
- #### `isList: true` (List Mode)
192
-
193
- - **Usage**: Price Lists, Catalogs, Shelf Labels, Reports.
194
- - **Data**: Expects an **Array of Objects** `[{ nome: 'A' }, { nome: 'B' }]`.
195
- - **Canvas**:
196
- - The user designs the "Template Item".
197
- - The editor repeats this model vertically for each item in the mock data array.
198
- - Allows visualization of how the list behaves with multiple items.
199
- - **Height Limit**: Elements are constrained within the defined item height (canvas height).
200
-
201
- ### JSON Structure
202
-
203
- The output of `onSave` is a JSON ready to be stored.
204
-
205
- ```json
206
- {
207
- "isList": false,
208
- "elements": [
209
- {
210
- "id": "uuid-v4",
211
- "type": "text", // 'text' | 'image' | 'box'
212
- "content": "Name: {{nome}}",
213
- "x": 50,
214
- "y": 100,
215
- "width": 200,
216
- "height": 40,
217
- "rotation": 0,
218
- "style": {
219
- "color": "#000000",
220
- "fontSize": "16px",
221
- "fontFamily": "Roboto",
222
- "textAlign": "center"
223
- },
224
- "dataBinding": "nome", // Optional, used for direct binding
225
- "formatting": {
226
- "type": "text" // 'text' | 'boolean' | 'date' | 'number'
227
- // Extra fields based on type:
228
- // trueLabel, falseLabel (boolean)
229
- // dateFormat (date)
230
- // numberFormat, currencySymbol, decimalPlaces (number)
231
- },
232
- "conditions": [
233
- {
234
- "id": "rule-1",
235
- "property": "price",
236
- "operator": "greaterThan",
237
- "value": "100",
238
- "style": { "color": "red", "fontWeight": "bold" }
239
- }
240
- ]
241
- }
242
- ],
243
- "listSettings": {
244
- "sortProp": "nome",
245
- "sortOrder": "asc",
246
- "newestPosition": "bottom",
247
- "scrollDirection": "down",
248
- "containerHeight": 400 // Optional: Limits the list height (scrollable)
249
- }
250
- }
251
- ```
252
-
253
- ### Generating HTML (Backend/Print)
254
-
255
- 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.).
256
-
257
- ```typescript
258
- import { generateHTML } from "@1urso/generic-editor";
259
-
260
- // 1. Load layout and data
261
- const layout = JSON.parse(db.getLayout());
262
- const dados = db.getFuncionarios(); // Array or Object
263
-
264
- // 2. Generate HTML
265
- const htmlString = generateHTML(layout.elements, dados, {
266
- isList: layout.isList, // Important to pass the correct mode
267
- listSettings: layout.listSettings,
268
- canvasHeight: layout.canvasHeight, // Optional: Force item height
269
- });
270
-
271
- // 3. Inject where needed
272
- document.getElementById("preview").innerHTML = htmlString;
273
- ```
274
-
275
- ---
276
-
277
- ## API Reference
278
-
279
- ### Component `<EditorContent />`
280
-
281
- | Property | Type | Required | Default | Description |
282
- | -------------- | ------------------------ | -------- | ------- | --------------------------------------------- |
283
- | `layout` | `ILayout` | **Yes** | - | Initial configuration of variables and mode. |
284
- | `initialState` | `any` | No | `null` | JSON state to load a saved layout. |
285
- | `onSave` | `(json: string) => void` | No | - | Callback triggered when clicking Save button. |
286
- | `mockData` | `any[]` | No | `[]` | Data for immediate preview during editing. |
287
-
288
- ### TypeScript Types
289
-
290
- #### `ILayout`
291
-
292
- ```typescript
293
- interface ILayout {
294
- name: string; // Layout name (metadata)
295
- isList?: boolean; // Defines default behavior (List or Single)
296
- props: IProp[]; // List of available variables
297
- }
298
- ```
299
-
300
- #### `IProp`
301
-
302
- ```typescript
303
- interface IProp {
304
- name: string; // Visible label (e.g., "Product Price")
305
- dataName: string; // Object key (e.g., "product_price")
306
- }
307
- ```
308
-
309
- #### `EditorProps`
310
-
311
- | Prop | Type | Required | Description |
312
- | -------------- | ------------------------ | -------- | ------------------------------------- |
313
- | `layout` | `ILayout` | Yes | Initial configuration and metadata. |
314
- | `onSave` | `(json: string) => void` | No | Callback triggered on save. |
315
- | `initialState` | `any` | No | Previously saved state (parsed JSON). |
316
- | `theme` | `'light' \| 'dark'` | No | Interface theme (default: `'light'`). |
1
+ <div align="center">
2
+ <a href="https://bearry.app">
3
+ <img src="https://bearry.app/logo.png" alt="Bearry - Streaming Tools" height="100">
4
+ </a>
5
+ <br />
6
+ <br />
7
+
8
+ <h1>🐻 Bearry - Streaming Tools</h1>
9
+
10
+ <p>
11
+ <strong>The ultimate toolkit for streamers and content creators.</strong>
12
+ <br />
13
+ Create stunning overlays, manage your stream, and engage your audience like never before.
14
+ </p>
15
+
16
+ <p>
17
+ <a href="https://bearry.app"><strong>🌐 Visit Bearry.app</strong></a>
18
+ </p>
19
+ </div>
20
+
21
+ <hr />
22
+
23
+ # Generic Editor
24
+
25
+ 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.).
26
+
27
+ **This library is the core engine behind the visual editors found in [Bearry - Streaming Tools](https://bearry.app).**
28
+
29
+ ---
30
+
31
+ ## 📚 Table of Contents
32
+
33
+ 1. [Installation and Configuration](#installation-and-configuration)
34
+ 2. [User Guide (Visual Interface)](#user-guide-visual-interface)
35
+ - [Basic Manipulation](#basic-manipulation)
36
+ - [Context Menu and Styling](#context-menu-and-styling)
37
+ - [Working with Text and Fonts](#working-with-text-and-fonts)
38
+ - [Working with Images](#working-with-images)
39
+ 3. [Developer Guide (Integration)](#developer-guide-integration)
40
+ - [Initialization and Props](#initialization-and-props)
41
+ - [Data Binding and Variables](#data-binding-and-variables)
42
+ - [Modes: Single Item vs. List](#modes-single-item-vs-list)
43
+ - [JSON Structure](#json-structure)
44
+ - [Generating HTML (Backend/Print)](#generating-html-backendprint)
45
+ 4. [API Reference](#api-reference)
46
+
47
+ ---
48
+
49
+ ## Installation and Configuration
50
+
51
+ ### 1. Install the package
52
+
53
+ ```bash
54
+ npm install @1urso/generic-editor
55
+ # or
56
+ yarn add @1urso/generic-editor
57
+ ```
58
+
59
+ ### 2. Install Peer Dependencies
60
+
61
+ The editor uses modern libraries to ensure performance and accessibility. You need to install them in your project:
62
+
63
+ ```bash
64
+ npm install @radix-ui/themes @radix-ui/react-icons react-resizable-panels re-resizable framer-motion @dnd-kit/core
65
+ ```
66
+
67
+ ### 3. Import Styles
68
+
69
+ 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:
70
+
71
+ ```tsx
72
+ import "@1urso/generic-editor/dist/generic-editor.css"; // Essential for the editor to work
73
+ import "@radix-ui/themes/styles.css";
74
+ ```
75
+
76
+ ---
77
+
78
+ ## User Guide (Visual Interface)
79
+
80
+ This section describes the features available to the **end user** who will use the editor on your platform.
81
+
82
+ ### Basic Manipulation
83
+
84
+ The editor offers an experience similar to design tools like Canva or Figma:
85
+
86
+ - **Add Elements**: Use the sidebar (or buttons you implement) to drag or click and add Texts, Images, or Boxes.
87
+ - **Move**: Click and drag any element to reposition it.
88
+ - **Resize**: Click on the element to select it. Pull the handles (blue squares) on the edges or corners to change the size.
89
+ - **Rotate**: When selecting an element, a circular handle will appear above it. Click and drag to rotate freely.
90
+ - **Delete**: Select an element and press the `Delete` key or use the context menu.
91
+
92
+ ### Context Menu and Styling
93
+
94
+ **Right-click** on any element to open the advanced options menu.
95
+
96
+ #### General Options (All Elements)
97
+
98
+ - **Duplicate**: Creates an exact copy of the element next to the original.
99
+ - **Remove**: Deletes the element.
100
+ - **Layers**:
101
+ - _Bring to front_: Places the element above all others.
102
+ - _Send to back_: Places the element behind all others.
103
+ - **Background Color**: Changes the background color of the element (includes transparent).
104
+ - **Borders**:
105
+ - _Radius_: From 0px (square) to 50% (circle/oval).
106
+ - _Thickness_: Adds a solid border from 1px to 4px.
107
+
108
+ #### Advanced Settings (Formatting and Conditions)
109
+
110
+ **Right-click** and select **Advanced Settings** to access powerful data formatting and conditional styling options.
111
+
112
+ - **Data Formatting**:
113
+
114
+ - _Type_: Choose between Text (Default), Boolean (True/False), Date, or Number/Currency.
115
+ - _Boolean_: Define custom labels for true/false values (e.g., "Active" / "Inactive").
116
+ - _Date_: Custom date patterns (e.g., "DD/MM/YYYY HH:mm").
117
+ - _Number_: Format as Decimal, Currency (with symbol), or Percentage.
118
+
119
+ - **Conditional Formatting**:
120
+ - Define rules to change the element's style based on data values.
121
+ - _Example_: If `price` is greater than `100`, set text color to `red`.
122
+ - _Action_: Choose between applying styles (Color, Bold, Background, etc.) or **Hiding the Element** completely.
123
+ - Supports multiple rules with operators like Equals, Not Equals, Contains, Greater Than, Less Than, Truthy, and Falsy.
124
+
125
+ ### Settings and Test Data
126
+
127
+ At the top of the left sidebar, the **Settings** button (gear icon) allows you to simulate how the layout will look with real data.
128
+
129
+ - **List Configuration Tab**:
130
+ - _Sort Property_: Defines which field will be used to sort the list (e.g., `price`, `name`).
131
+ - _Order_: Ascending or Descending.
132
+ - _Newest Position_: Defines where the newest item appears ('top' or 'bottom').
133
+ - _Scroll Behavior_: Defines the scroll direction ('down' - default, or 'up' - chat-like).
134
+ - _Container Height_: Defines the fixed height of the list container in pixels. If the content exceeds this height, a vertical scrollbar will appear automatically.
135
+
136
+ ### Working with Text and Fonts
137
+
138
+ When right-clicking on a **Text** element:
139
+
140
+ - **Edit Text**: Opens a window to type content. This is where you insert variables (e.g., Customer Name) by clicking on the available buttons.
141
+ - **Font**: Select from various web-safe fonts (Arial, Helvetica, etc.) and popular Google Fonts (Roboto, Open Sans, Montserrat).
142
+ - _Import Google Font_: Allows you to type the name of any Google Fonts font (e.g., "Pacifico") and the editor will automatically load it.
143
+ - **Size**: Adjust from 12px to 64px.
144
+ - **Text Color**: Pre-defined color palette.
145
+ - **Weight**: Normal or Bold.
146
+ - **Alignment**: Left, Center, or Right.
147
+ - **Vertical Alignment**: Top, Center, or Bottom.
148
+
149
+ ### Working with Images
150
+
151
+ When right-clicking on an **Image** element:
152
+
153
+ - **Change Image**:
154
+ - _Upload_: Upload an image from your computer.
155
+ - _URL_: Paste a direct link to an image from the web.
156
+ - **Fit (Object Fit)**:
157
+ - _Fit (Contain)_: The entire image is shown inside the box, maintaining proportions (may leave white space).
158
+ - _Stretch (Fill)_: The image fills the entire box, potentially being cropped or distorted depending on the aspect ratio.
159
+ - **Bind Data**: Connects the image to a dynamic variable (e.g., Product Photo).
160
+
161
+ ---
162
+
163
+ ## Developer Guide (Integration)
164
+
165
+ ### Initialization and Props
166
+
167
+ To start the editor, you must provide the `layout` configuration which dictates what data (variables) will be available to the user.
168
+
169
+ ```tsx
170
+ import { EditorContent } from "@1urso/generic-editor";
171
+
172
+ const config = {
173
+ isList: false, // Single mode (e.g., ID Card) or List (e.g., Catalog)
174
+ name: "Employee ID Card",
175
+ props: [
176
+ // Define the variables that will appear in the "Insert Variable" button
177
+ { name: "Full Name", dataName: "nome" },
178
+ { name: "Role", dataName: "cargo" },
179
+ { name: "Profile Picture", dataName: "fotoUrl" },
180
+ ],
181
+ };
182
+
183
+ function App() {
184
+ return (
185
+ <div style={{ height: "100vh", width: "100%" }}>
186
+ <EditorContent
187
+ layout={config}
188
+ onSave={(json) => saveToBackend(json)}
189
+ theme="light" // Optional: 'light' or 'dark'
190
+ />
191
+ </div>
192
+ );
193
+ }
194
+ ```
195
+
196
+ ### Data Binding and Variables
197
+
198
+ The editor uses an interpolation system based on double braces `{{key}}`.
199
+
200
+ 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.
201
+ 2. **Rendering**:
202
+ - If `data = { nome: "Maria" }`, the text "Hello {{nome}}" becomes "Hello Maria".
203
+ - If the variable does not exist in the data, the editor keeps the original text `{{nome}}` or displays empty, depending on the configuration.
204
+
205
+ ### Modes: Single Item vs. List
206
+
207
+ The `isList` property drastically changes how the editor and HTML generator behave.
208
+
209
+ #### `isList: false` (Single Mode)
210
+
211
+ - **Usage**: Certificates, ID Cards, Banners, Covers.
212
+ - **Data**: Expects a **Single Object** `{ nome: 'John', cargo: 'Dev' }`.
213
+ - **Canvas**: Shows a single page/art.
214
+
215
+ #### `isList: true` (List Mode)
216
+
217
+ - **Usage**: Price Lists, Catalogs, Shelf Labels, Reports.
218
+ - **Data**: Expects an **Array of Objects** `[{ nome: 'A' }, { nome: 'B' }]`.
219
+ - **Canvas**:
220
+ - The user designs the "Template Item".
221
+ - The editor repeats this model vertically for each item in the mock data array.
222
+ - Allows visualization of how the list behaves with multiple items.
223
+ - **Height Limit**: Elements are constrained within the defined item height (canvas height).
224
+
225
+ ### JSON Structure
226
+
227
+ The output of `onSave` is a JSON ready to be stored.
228
+
229
+ ```json
230
+ {
231
+ "isList": false,
232
+ "elements": [
233
+ {
234
+ "id": "uuid-v4",
235
+ "type": "text", // 'text' | 'image' | 'box'
236
+ "content": "Name: {{nome}}",
237
+ "x": 50,
238
+ "y": 100,
239
+ "width": 200,
240
+ "height": 40,
241
+ "rotation": 0,
242
+ "style": {
243
+ "color": "#000000",
244
+ "fontSize": "16px",
245
+ "fontFamily": "Roboto",
246
+ "textAlign": "center"
247
+ },
248
+ "dataBinding": "nome", // Optional, used for direct binding
249
+ "formatting": {
250
+ "type": "text" // 'text' | 'boolean' | 'date' | 'number'
251
+ // Extra fields based on type:
252
+ // trueLabel, falseLabel (boolean)
253
+ // dateFormat (date)
254
+ // numberFormat, currencySymbol, decimalPlaces (number)
255
+ },
256
+ "conditions": [
257
+ {
258
+ "id": "rule-1",
259
+ "property": "price",
260
+ "operator": "greaterThan",
261
+ "value": "100",
262
+ "style": { "color": "red", "fontWeight": "bold" }
263
+ }
264
+ ]
265
+ }
266
+ ],
267
+ "listSettings": {
268
+ "sortProp": "nome",
269
+ "sortOrder": "asc",
270
+ "newestPosition": "bottom",
271
+ "scrollDirection": "down",
272
+ "containerHeight": 400 // Optional: Limits the list height (scrollable)
273
+ }
274
+ }
275
+ ```
276
+
277
+ ### Generating HTML (Backend/Print)
278
+
279
+ 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.).
280
+
281
+ ```typescript
282
+ import { generateHTML } from "@1urso/generic-editor";
283
+
284
+ // 1. Load layout and data
285
+ const layout = JSON.parse(db.getLayout());
286
+ const dados = db.getFuncionarios(); // Array or Object
287
+
288
+ // 2. Generate HTML
289
+ const htmlString = generateHTML(layout.elements, dados, {
290
+ isList: layout.isList, // Important to pass the correct mode
291
+ listSettings: layout.listSettings,
292
+ canvasHeight: layout.canvasHeight, // Optional: Force item height
293
+ });
294
+
295
+ // 3. Inject where needed
296
+ document.getElementById("preview").innerHTML = htmlString;
297
+ ```
298
+
299
+ ---
300
+
301
+ ## API Reference
302
+
303
+ ### Component `<EditorContent />`
304
+
305
+ | Property | Type | Required | Default | Description |
306
+ | -------------- | ------------------------ | -------- | ------- | --------------------------------------------- |
307
+ | `layout` | `ILayout` | **Yes** | - | Initial configuration of variables and mode. |
308
+ | `initialState` | `any` | No | `null` | JSON state to load a saved layout. |
309
+ | `onSave` | `(json: string) => void` | No | - | Callback triggered when clicking Save button. |
310
+ | `mockData` | `any[]` | No | `[]` | Data for immediate preview during editing. |
311
+
312
+ ### TypeScript Types
313
+
314
+ #### `ILayout`
315
+
316
+ ```typescript
317
+ interface ILayout {
318
+ name: string; // Layout name (metadata)
319
+ isList?: boolean; // Defines default behavior (List or Single)
320
+ props: IProp[]; // List of available variables
321
+ }
322
+ ```
323
+
324
+ #### `IProp`
325
+
326
+ ```typescript
327
+ interface IProp {
328
+ name: string; // Visible label (e.g., "Product Price")
329
+ dataName: string; // Object key (e.g., "product_price")
330
+ }
331
+ ```
332
+
333
+ #### `EditorProps`
334
+
335
+ | Prop | Type | Required | Description |
336
+ | -------------- | ------------------------ | -------- | ------------------------------------- |
337
+ | `layout` | `ILayout` | Yes | Initial configuration and metadata. |
338
+ | `onSave` | `(json: string) => void` | No | Callback triggered on save. |
339
+ | `initialState` | `any` | No | Previously saved state (parsed JSON). |
340
+ | `theme` | `'light' \| 'dark'` | No | Interface theme (default: `'light'`). |
package/package.json CHANGED
@@ -1,77 +1,77 @@
1
- {
2
- "name": "@1urso/generic-editor",
3
- "version": "0.1.21",
4
- "publishConfig": {
5
- "access": "public"
6
- },
7
- "type": "module",
8
- "main": "./dist/generic-editor.umd.cjs",
9
- "module": "./dist/generic-editor.js",
10
- "types": "./dist/index.d.ts",
11
- "exports": {
12
- ".": {
13
- "import": "./dist/generic-editor.js",
14
- "require": "./dist/generic-editor.umd.cjs"
15
- },
16
- "./dist/generic-editor.css": "./dist/generic-editor.css"
17
- },
18
- "files": [
19
- "dist"
20
- ],
21
- "scripts": {
22
- "dev": "vite",
23
- "build": "tsc -b && vite build",
24
- "lint": "eslint .",
25
- "preview": "vite preview",
26
- "pack:local": "npm run build && npm pack"
27
- },
28
- "peerDependencies": {
29
- "@dnd-kit/core": "^6.3.1",
30
- "@dnd-kit/sortable": "^10.0.0",
31
- "@dnd-kit/utilities": "^3.2.2",
32
- "@emotion/react": "^11.14.0",
33
- "@emotion/styled": "^11.14.1",
34
- "@radix-ui/react-dropdown-menu": "^2.1.16",
35
- "@radix-ui/react-icons": "^1.3.2",
36
- "@radix-ui/themes": "^3.2.1",
37
- "framer-motion": "^12.24.12",
38
- "re-resizable": "^6.11.2",
39
- "react": "^19.2.0",
40
- "react-dom": "^19.2.0",
41
- "react-resizable-panels": "^4.3.1"
42
- },
43
- "devDependencies": {
44
- "@dnd-kit/core": "^6.3.1",
45
- "@dnd-kit/sortable": "^10.0.0",
46
- "@dnd-kit/utilities": "^3.2.2",
47
- "@emotion/react": "^11.14.0",
48
- "@emotion/styled": "^11.14.1",
49
- "@eslint/js": "^9.39.1",
50
- "@radix-ui/react-dropdown-menu": "^2.1.16",
51
- "@radix-ui/react-icons": "^1.3.2",
52
- "@radix-ui/themes": "^3.2.1",
53
- "@types/node": "^24.10.1",
54
- "@types/react": "^19.2.5",
55
- "@types/react-dom": "^19.2.3",
56
- "@vitejs/plugin-react-swc": "^4.2.2",
57
- "eslint": "^9.39.1",
58
- "eslint-plugin-react-hooks": "^7.0.1",
59
- "eslint-plugin-react-refresh": "^0.4.24",
60
- "framer-motion": "^12.24.12",
61
- "globals": "^16.5.0",
62
- "re-resizable": "^6.11.2",
63
- "react": "^19.2.0",
64
- "react-dom": "^19.2.0",
65
- "react-resizable-panels": "^4.3.1",
66
- "typescript": "~5.9.3",
67
- "typescript-eslint": "^8.46.4",
68
- "vite": "npm:rolldown-vite@7.2.5",
69
- "vite-plugin-dts": "^4.5.4"
70
- },
71
- "resolutions": {
72
- "vite": "npm:rolldown-vite@7.2.5"
73
- },
74
- "dependencies": {
75
- "@radix-ui/react-context-menu": "^2.2.16"
76
- }
77
- }
1
+ {
2
+ "name": "@1urso/generic-editor",
3
+ "version": "0.1.22",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
7
+ "type": "module",
8
+ "main": "./dist/generic-editor.umd.cjs",
9
+ "module": "./dist/generic-editor.js",
10
+ "types": "./dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "import": "./dist/generic-editor.js",
14
+ "require": "./dist/generic-editor.umd.cjs"
15
+ },
16
+ "./dist/generic-editor.css": "./dist/generic-editor.css"
17
+ },
18
+ "files": [
19
+ "dist"
20
+ ],
21
+ "scripts": {
22
+ "dev": "vite",
23
+ "build": "tsc -b && vite build",
24
+ "lint": "eslint .",
25
+ "preview": "vite preview",
26
+ "pack:local": "npm run build && npm pack"
27
+ },
28
+ "peerDependencies": {
29
+ "@dnd-kit/core": "^6.3.1",
30
+ "@dnd-kit/sortable": "^10.0.0",
31
+ "@dnd-kit/utilities": "^3.2.2",
32
+ "@emotion/react": "^11.14.0",
33
+ "@emotion/styled": "^11.14.1",
34
+ "@radix-ui/react-dropdown-menu": "^2.1.16",
35
+ "@radix-ui/react-icons": "^1.3.2",
36
+ "@radix-ui/themes": "^3.2.1",
37
+ "framer-motion": "^12.24.12",
38
+ "re-resizable": "^6.11.2",
39
+ "react": "^19.2.0",
40
+ "react-dom": "^19.2.0",
41
+ "react-resizable-panels": "^4.3.1"
42
+ },
43
+ "devDependencies": {
44
+ "@dnd-kit/core": "^6.3.1",
45
+ "@dnd-kit/sortable": "^10.0.0",
46
+ "@dnd-kit/utilities": "^3.2.2",
47
+ "@emotion/react": "^11.14.0",
48
+ "@emotion/styled": "^11.14.1",
49
+ "@eslint/js": "^9.39.1",
50
+ "@radix-ui/react-dropdown-menu": "^2.1.16",
51
+ "@radix-ui/react-icons": "^1.3.2",
52
+ "@radix-ui/themes": "^3.2.1",
53
+ "@types/node": "^24.10.1",
54
+ "@types/react": "^19.2.5",
55
+ "@types/react-dom": "^19.2.3",
56
+ "@vitejs/plugin-react-swc": "^4.2.2",
57
+ "eslint": "^9.39.1",
58
+ "eslint-plugin-react-hooks": "^7.0.1",
59
+ "eslint-plugin-react-refresh": "^0.4.24",
60
+ "framer-motion": "^12.24.12",
61
+ "globals": "^16.5.0",
62
+ "re-resizable": "^6.11.2",
63
+ "react": "^19.2.0",
64
+ "react-dom": "^19.2.0",
65
+ "react-resizable-panels": "^4.3.1",
66
+ "typescript": "~5.9.3",
67
+ "typescript-eslint": "^8.46.4",
68
+ "vite": "npm:rolldown-vite@7.2.5",
69
+ "vite-plugin-dts": "^4.5.4"
70
+ },
71
+ "resolutions": {
72
+ "vite": "npm:rolldown-vite@7.2.5"
73
+ },
74
+ "dependencies": {
75
+ "@radix-ui/react-context-menu": "^2.2.16"
76
+ }
77
+ }