@tfw.in/structura-lib 0.2.0 → 0.2.1
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 +9 -361
- package/dist/cjs/EditableContent.js +45 -18
- package/dist/cjs/HtmlViewer.js +217 -83
- package/dist/cjs/MathRenderer.js +88 -0
- package/dist/cjs/PdfDocumentViewer.js +1 -1
- package/dist/cjs/SemanticTagParser.js +189 -0
- package/dist/cjs/SemanticTagRenderer.js +135 -0
- package/dist/cjs/Structura.js +20 -66
- package/dist/cjs/Table.js +73 -8
- package/dist/cjs/TableCell.js +33 -10
- package/dist/cjs/index.js +12 -0
- package/dist/cjs/node_modules/react-icons/fa/index.esm.js +6 -0
- package/dist/cjs/styles.css +2 -4
- package/dist/cjs/styles.css.map +1 -1
- package/dist/esm/EditableContent.js +49 -19
- package/dist/esm/HtmlViewer.js +259 -100
- package/dist/esm/MathRenderer.js +85 -0
- package/dist/esm/PdfDocumentViewer.js +1 -1
- package/dist/esm/SemanticTagParser.js +187 -0
- package/dist/esm/SemanticTagRenderer.js +140 -0
- package/dist/esm/Structura.js +21 -69
- package/dist/esm/Table.js +82 -8
- package/dist/esm/TableCell.js +32 -6
- package/dist/esm/index.js +3 -0
- package/dist/esm/node_modules/react-icons/fa/index.esm.js +5 -1
- package/dist/esm/styles.css +2 -4
- package/dist/esm/styles.css.map +1 -1
- package/dist/esm/types/DocumentOutline.d.ts +7 -0
- package/dist/esm/types/EditableContent.d.ts +7 -1
- package/dist/esm/types/HtmlViewer.d.ts +1 -2
- package/dist/esm/types/MathRenderer.d.ts +25 -0
- package/dist/esm/types/SemanticTagParser.d.ts +33 -0
- package/dist/esm/types/SemanticTagRenderer.d.ts +17 -0
- package/dist/esm/types/Structura.d.ts +1 -2
- package/dist/esm/types/Table.d.ts +3 -1
- package/dist/esm/types/TableCell.d.ts +6 -1
- package/dist/esm/types/helpers/index.d.ts +0 -1
- package/dist/esm/types/index.d.ts +3 -0
- package/dist/esm/types/test-app/src/App.d.ts +1 -2
- package/dist/index.d.ts +78 -4
- package/package.json +9 -16
- package/PRODUCTION_ARCHITECTURE.md +0 -511
- package/SAVE_FUNCTIONALITY_COMPLETE.md +0 -448
- package/dist/cjs/ui/badge.js +0 -34
- package/dist/esm/types/helpers/jsonToHtml.d.ts +0 -40
- package/dist/esm/ui/badge.js +0 -31
- package/server/README.md +0 -203
- package/server/db.js +0 -142
- package/server/server.js +0 -165
package/README.md
CHANGED
|
@@ -1,379 +1,27 @@
|
|
|
1
1
|
# Structura Library
|
|
2
2
|
|
|
3
|
-
A React component library for viewing and
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- 📄 **PDF Viewer** - Side-by-side PDF and structured content view
|
|
8
|
-
- ✏️ **Inline Editing** - Double-click to edit any text element
|
|
9
|
-
- 💾 **Persistent Storage** - Automatic save to SQLite database
|
|
10
|
-
- 🔄 **Version History** - Track all edits with timestamps
|
|
11
|
-
- 🎯 **Bidirectional Mapping** - Click highlighting between PDF and content
|
|
12
|
-
- 📦 **Production Ready** - Zero configuration, auto-initialization
|
|
3
|
+
A React component library for document viewing and processing.
|
|
13
4
|
|
|
14
5
|
## Installation
|
|
15
6
|
|
|
16
7
|
```bash
|
|
17
|
-
npm install
|
|
8
|
+
npm install structura_lib
|
|
18
9
|
```
|
|
19
10
|
|
|
20
|
-
##
|
|
11
|
+
## Usage
|
|
21
12
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
import { Structura } from '@tfw.in/structura-lib';
|
|
26
|
-
import '@tfw.in/structura-lib/dist/esm/styles.css';
|
|
13
|
+
```jsx
|
|
14
|
+
import { Structura } from 'structura-lib';
|
|
15
|
+
import 'structura_lib/dist/styles.css'
|
|
27
16
|
|
|
28
17
|
function App() {
|
|
29
18
|
return (
|
|
30
|
-
<Structura
|
|
31
|
-
initialPdfPath="/document.pdf"
|
|
32
|
-
initialJsonData={jsonData}
|
|
19
|
+
<Structura
|
|
33
20
|
props={{
|
|
34
|
-
APIKey: "your-api-key"
|
|
35
|
-
|
|
36
|
-
console.log('Document saved:', editedData);
|
|
37
|
-
}
|
|
21
|
+
APIKey: "your-api-key"
|
|
22
|
+
baseURL: "optional-api-base-url"
|
|
38
23
|
}}
|
|
39
24
|
/>
|
|
40
25
|
);
|
|
41
26
|
}
|
|
42
27
|
```
|
|
43
|
-
|
|
44
|
-
### 2. With Backend Storage
|
|
45
|
-
|
|
46
|
-
```tsx
|
|
47
|
-
import { Structura } from '@tfw.in/structura-lib';
|
|
48
|
-
import '@tfw.in/structura-lib/dist/esm/styles.css';
|
|
49
|
-
|
|
50
|
-
function App() {
|
|
51
|
-
const [jsonData, setJsonData] = useState(null);
|
|
52
|
-
|
|
53
|
-
const handleSave = async (editedData) => {
|
|
54
|
-
const response = await fetch('http://localhost:3002/api/save', {
|
|
55
|
-
method: 'POST',
|
|
56
|
-
headers: { 'Content-Type': 'application/json' },
|
|
57
|
-
body: JSON.stringify({
|
|
58
|
-
pdfName: 'document.pdf',
|
|
59
|
-
editedJson: editedData,
|
|
60
|
-
originalJson: jsonData // Only on first save
|
|
61
|
-
})
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
const result = await response.json();
|
|
65
|
-
console.log('Saved:', result);
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
return (
|
|
69
|
-
<Structura
|
|
70
|
-
initialPdfPath="/document.pdf"
|
|
71
|
-
initialJsonData={jsonData}
|
|
72
|
-
props={{
|
|
73
|
-
APIKey: "your-api-key",
|
|
74
|
-
onSave: handleSave
|
|
75
|
-
}}
|
|
76
|
-
/>
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
## Props
|
|
82
|
-
|
|
83
|
-
### `Structura` Component
|
|
84
|
-
|
|
85
|
-
| Prop | Type | Required | Description |
|
|
86
|
-
|------|------|----------|-------------|
|
|
87
|
-
| `initialPdfPath` | `string \| null` | No | URL or path to PDF file |
|
|
88
|
-
| `initialJsonData` | `any \| null` | No | Pre-loaded JSON data (bypasses API call) |
|
|
89
|
-
| `props.APIKey` | `string` | Yes | Structura API key for processing |
|
|
90
|
-
| `props.baseUrl` | `string` | No | Custom API base URL |
|
|
91
|
-
| `props.onSave` | `(data: any) => void \| Promise<void>` | No | Callback when user saves edits |
|
|
92
|
-
|
|
93
|
-
## Backend Server (Optional)
|
|
94
|
-
|
|
95
|
-
The library includes an Express server for persistent storage.
|
|
96
|
-
|
|
97
|
-
### Start the Server
|
|
98
|
-
|
|
99
|
-
```bash
|
|
100
|
-
cd node_modules/@tfw.in/structura-lib
|
|
101
|
-
npm run server
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
Server runs on `http://localhost:3002`
|
|
105
|
-
|
|
106
|
-
### API Endpoints
|
|
107
|
-
|
|
108
|
-
#### POST /api/save
|
|
109
|
-
Save edited document.
|
|
110
|
-
|
|
111
|
-
```bash
|
|
112
|
-
curl -X POST http://localhost:3002/api/save \
|
|
113
|
-
-H "Content-Type: application/json" \
|
|
114
|
-
-d '{
|
|
115
|
-
"pdfName": "document.pdf",
|
|
116
|
-
"editedJson": {...},
|
|
117
|
-
"originalJson": {...}
|
|
118
|
-
}'
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
#### GET /api/load/:pdfName
|
|
122
|
-
Load document with latest edit.
|
|
123
|
-
|
|
124
|
-
```bash
|
|
125
|
-
curl http://localhost:3002/api/load/document.pdf
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
#### GET /api/history/:pdfName
|
|
129
|
-
Get full edit history.
|
|
130
|
-
|
|
131
|
-
```bash
|
|
132
|
-
curl http://localhost:3002/api/history/document.pdf
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
## Usage Patterns
|
|
136
|
-
|
|
137
|
-
### Pattern 1: Database-First Loading
|
|
138
|
-
|
|
139
|
-
```tsx
|
|
140
|
-
useEffect(() => {
|
|
141
|
-
const pdfName = 'document.pdf';
|
|
142
|
-
|
|
143
|
-
// Try database first
|
|
144
|
-
fetch(`http://localhost:3002/api/load/${pdfName}`)
|
|
145
|
-
.then(res => res.json())
|
|
146
|
-
.then(result => {
|
|
147
|
-
setJsonData(result.document.currentJson);
|
|
148
|
-
})
|
|
149
|
-
.catch(() => {
|
|
150
|
-
// Fallback to file
|
|
151
|
-
fetch('/data.json')
|
|
152
|
-
.then(res => res.json())
|
|
153
|
-
.then(data => setJsonData(data));
|
|
154
|
-
});
|
|
155
|
-
}, []);
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
### Pattern 2: Auto-Save on Edit
|
|
159
|
-
|
|
160
|
-
```tsx
|
|
161
|
-
const handleSave = async (editedData) => {
|
|
162
|
-
await fetch('http://localhost:3002/api/save', {
|
|
163
|
-
method: 'POST',
|
|
164
|
-
headers: { 'Content-Type': 'application/json' },
|
|
165
|
-
body: JSON.stringify({
|
|
166
|
-
pdfName: pdfUrl.split('/').pop(),
|
|
167
|
-
editedJson: editedData
|
|
168
|
-
})
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
// Reload from database to verify
|
|
172
|
-
const response = await fetch(`http://localhost:3002/api/load/${pdfName}`);
|
|
173
|
-
const result = await response.json();
|
|
174
|
-
setJsonData(result.document.currentJson);
|
|
175
|
-
};
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
### Pattern 3: URL Parameters
|
|
179
|
-
|
|
180
|
-
```tsx
|
|
181
|
-
// Load from URL: ?pdf=/doc.pdf&json=/data.json
|
|
182
|
-
useEffect(() => {
|
|
183
|
-
const params = new URLSearchParams(window.location.search);
|
|
184
|
-
const pdf = params.get('pdf');
|
|
185
|
-
const json = params.get('json');
|
|
186
|
-
|
|
187
|
-
if (pdf && json) {
|
|
188
|
-
setPdfUrl(pdf);
|
|
189
|
-
fetch(json)
|
|
190
|
-
.then(res => res.json())
|
|
191
|
-
.then(data => setJsonData(data));
|
|
192
|
-
}
|
|
193
|
-
}, []);
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
## Features
|
|
197
|
-
|
|
198
|
-
### Inline Editing
|
|
199
|
-
|
|
200
|
-
Double-click any text to edit:
|
|
201
|
-
- Edits are tracked automatically
|
|
202
|
-
- Green **Save** button appears when changes are made
|
|
203
|
-
- Yellow highlight indicates edited content
|
|
204
|
-
|
|
205
|
-
### Version History
|
|
206
|
-
|
|
207
|
-
Every save creates a new version:
|
|
208
|
-
- Full edit history preserved
|
|
209
|
-
- Timestamps for each edit
|
|
210
|
-
- Can restore any previous version
|
|
211
|
-
|
|
212
|
-
### Bidirectional Mapping
|
|
213
|
-
|
|
214
|
-
Click elements to highlight corresponding content:
|
|
215
|
-
- PDF → HTML viewer
|
|
216
|
-
- HTML viewer → PDF location
|
|
217
|
-
- Smooth scrolling and highlighting
|
|
218
|
-
|
|
219
|
-
## Development
|
|
220
|
-
|
|
221
|
-
### Build the Library
|
|
222
|
-
|
|
223
|
-
```bash
|
|
224
|
-
npm run build
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
### Run Test App
|
|
228
|
-
|
|
229
|
-
```bash
|
|
230
|
-
cd test-app
|
|
231
|
-
npm install
|
|
232
|
-
npm run dev
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
Open: `http://localhost:5175`
|
|
236
|
-
|
|
237
|
-
### Run with Backend
|
|
238
|
-
|
|
239
|
-
Terminal 1:
|
|
240
|
-
```bash
|
|
241
|
-
npm run server
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
Terminal 2:
|
|
245
|
-
```bash
|
|
246
|
-
cd test-app
|
|
247
|
-
npm run dev
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
## Database Schema
|
|
251
|
-
|
|
252
|
-
### documents table
|
|
253
|
-
```sql
|
|
254
|
-
CREATE TABLE documents (
|
|
255
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
256
|
-
pdf_name TEXT NOT NULL,
|
|
257
|
-
original_json TEXT NOT NULL,
|
|
258
|
-
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
259
|
-
);
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
### edits table
|
|
263
|
-
```sql
|
|
264
|
-
CREATE TABLE edits (
|
|
265
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
266
|
-
document_id INTEGER NOT NULL,
|
|
267
|
-
edited_json TEXT NOT NULL,
|
|
268
|
-
edit_summary TEXT,
|
|
269
|
-
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
270
|
-
FOREIGN KEY (document_id) REFERENCES documents(id)
|
|
271
|
-
);
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
## Architecture
|
|
275
|
-
|
|
276
|
-
```
|
|
277
|
-
┌──────────────────┐
|
|
278
|
-
│ React Component │
|
|
279
|
-
│ (Structura) │
|
|
280
|
-
└────────┬─────────┘
|
|
281
|
-
│
|
|
282
|
-
├─── PDF Viewer (Left)
|
|
283
|
-
│ - Render PDF pages
|
|
284
|
-
│ - Click to highlight
|
|
285
|
-
│
|
|
286
|
-
└─── HTML Viewer (Right)
|
|
287
|
-
- Structured content
|
|
288
|
-
- Inline editing
|
|
289
|
-
- Save button
|
|
290
|
-
│
|
|
291
|
-
▼
|
|
292
|
-
┌──────────────┐
|
|
293
|
-
│ Express API │
|
|
294
|
-
│ (port 3002) │
|
|
295
|
-
└──────┬───────┘
|
|
296
|
-
│
|
|
297
|
-
▼
|
|
298
|
-
┌──────────────┐
|
|
299
|
-
│ SQLite DB │
|
|
300
|
-
│ (edits.db) │
|
|
301
|
-
└──────────────┘
|
|
302
|
-
```
|
|
303
|
-
|
|
304
|
-
## Production Deployment
|
|
305
|
-
|
|
306
|
-
### Using PM2
|
|
307
|
-
|
|
308
|
-
```bash
|
|
309
|
-
npm install -g pm2
|
|
310
|
-
pm2 start server/server.js --name structura-server
|
|
311
|
-
pm2 save
|
|
312
|
-
pm2 startup
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
### Docker
|
|
316
|
-
|
|
317
|
-
```dockerfile
|
|
318
|
-
FROM node:18
|
|
319
|
-
WORKDIR /app
|
|
320
|
-
COPY package*.json ./
|
|
321
|
-
RUN npm install --production
|
|
322
|
-
COPY . .
|
|
323
|
-
EXPOSE 3002
|
|
324
|
-
CMD ["node", "server/server.js"]
|
|
325
|
-
```
|
|
326
|
-
|
|
327
|
-
### Nginx
|
|
328
|
-
|
|
329
|
-
```nginx
|
|
330
|
-
location /api/ {
|
|
331
|
-
proxy_pass http://localhost:3002;
|
|
332
|
-
client_max_body_size 50M;
|
|
333
|
-
}
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
## Configuration
|
|
337
|
-
|
|
338
|
-
### Environment Variables
|
|
339
|
-
|
|
340
|
-
```bash
|
|
341
|
-
PORT=3002 # Server port
|
|
342
|
-
NODE_ENV=production # Environment
|
|
343
|
-
DATABASE_PATH=./edits.db # SQLite path
|
|
344
|
-
MAX_JSON_SIZE=50mb # Request limit
|
|
345
|
-
```
|
|
346
|
-
|
|
347
|
-
## Troubleshooting
|
|
348
|
-
|
|
349
|
-
### Save button not appearing
|
|
350
|
-
|
|
351
|
-
1. Check `onSave` prop is provided
|
|
352
|
-
2. Make an edit (double-click text)
|
|
353
|
-
3. Rebuild library: `npm run build`
|
|
354
|
-
|
|
355
|
-
### Database not persisting
|
|
356
|
-
|
|
357
|
-
1. Check server is running: `curl http://localhost:3002/health`
|
|
358
|
-
2. Check database file exists: `ls -la server/edits.db`
|
|
359
|
-
3. Check browser console for errors
|
|
360
|
-
|
|
361
|
-
### PDF not loading
|
|
362
|
-
|
|
363
|
-
1. Check CORS settings on PDF server
|
|
364
|
-
2. Verify PDF path is correct
|
|
365
|
-
3. Check browser console for errors
|
|
366
|
-
|
|
367
|
-
## License
|
|
368
|
-
|
|
369
|
-
MIT
|
|
370
|
-
|
|
371
|
-
## Author
|
|
372
|
-
|
|
373
|
-
TFW
|
|
374
|
-
|
|
375
|
-
## Support
|
|
376
|
-
|
|
377
|
-
For issues and questions:
|
|
378
|
-
- GitHub: https://github.com/ChakshuGautam/structura-lib
|
|
379
|
-
- Documentation: See `/server/README.md` for API details
|
|
@@ -4,6 +4,9 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
6
|
var React = require('react');
|
|
7
|
+
var SemanticTagRenderer = require('./SemanticTagRenderer.js');
|
|
8
|
+
var SemanticTagParser = require('./SemanticTagParser.js');
|
|
9
|
+
var MathRenderer = require('./MathRenderer.js');
|
|
7
10
|
|
|
8
11
|
// Helper function to extract text content while preserving structure
|
|
9
12
|
const extractTextPreservingStructure = html => {
|
|
@@ -25,7 +28,12 @@ function EditableContent({
|
|
|
25
28
|
content,
|
|
26
29
|
onContentChange,
|
|
27
30
|
isHeading = false,
|
|
28
|
-
|
|
31
|
+
isEditMode = false,
|
|
32
|
+
isJsonMode = false,
|
|
33
|
+
onNodeClick,
|
|
34
|
+
onJsonClick,
|
|
35
|
+
enableSemanticTags = true,
|
|
36
|
+
onSemanticTagClick
|
|
29
37
|
}) {
|
|
30
38
|
const [isEditing, setIsEditing] = React.useState(false);
|
|
31
39
|
const [editedContent, setEditedContent] = React.useState(content);
|
|
@@ -55,24 +63,22 @@ function EditableContent({
|
|
|
55
63
|
const getHeadingStyles = level => {
|
|
56
64
|
switch (level) {
|
|
57
65
|
case 1:
|
|
58
|
-
return "text-2xl font-bold";
|
|
59
|
-
case 2:
|
|
60
66
|
return "text-xl font-bold";
|
|
61
|
-
case
|
|
67
|
+
case 2:
|
|
62
68
|
return "text-lg font-bold";
|
|
63
|
-
case
|
|
69
|
+
case 3:
|
|
64
70
|
return "text-base font-bold";
|
|
65
|
-
case
|
|
71
|
+
case 4:
|
|
66
72
|
return "text-sm font-bold";
|
|
67
|
-
case
|
|
73
|
+
case 5:
|
|
68
74
|
return "text-xs font-bold";
|
|
75
|
+
case 6:
|
|
76
|
+
return "text-xs font-semibold";
|
|
69
77
|
default:
|
|
70
|
-
return "text-
|
|
78
|
+
return "text-sm";
|
|
71
79
|
}
|
|
72
80
|
};
|
|
73
|
-
const
|
|
74
|
-
// Stop propagation to prevent parent click handlers from firing
|
|
75
|
-
e.stopPropagation();
|
|
81
|
+
const startEditing = () => {
|
|
76
82
|
if (onContentChange) {
|
|
77
83
|
// Extract text content for textarea while preserving structure
|
|
78
84
|
setTextAreaContent(extractTextPreservingStructure(editedContent));
|
|
@@ -111,6 +117,18 @@ function EditableContent({
|
|
|
111
117
|
e.stopPropagation();
|
|
112
118
|
return;
|
|
113
119
|
}
|
|
120
|
+
// In JSON mode, show JSON on click
|
|
121
|
+
if (isJsonMode && onJsonClick) {
|
|
122
|
+
e.stopPropagation();
|
|
123
|
+
onJsonClick();
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
// In edit mode, single click activates editing
|
|
127
|
+
if (isEditMode && onContentChange) {
|
|
128
|
+
e.stopPropagation();
|
|
129
|
+
startEditing();
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
114
132
|
// If there's an onNodeClick handler, call it
|
|
115
133
|
if (onNodeClick) {
|
|
116
134
|
e.stopPropagation(); // Prevent click from reaching parent containers
|
|
@@ -124,25 +142,34 @@ function EditableContent({
|
|
|
124
142
|
handleBlur();
|
|
125
143
|
}
|
|
126
144
|
};
|
|
145
|
+
// Render math expressions in content
|
|
146
|
+
const renderedContent = React.useMemo(() => {
|
|
147
|
+
return MathRenderer.renderMathInHtml(editedContent);
|
|
148
|
+
}, [editedContent]);
|
|
127
149
|
return jsxRuntime.jsx("div", {
|
|
128
|
-
className: `w-full ${isEdited ? "bg-yellow-100" : ""} ${onNodeClick && !isEditing ? "cursor-pointer" : ""}`,
|
|
150
|
+
className: `w-full ${isEdited ? "bg-yellow-100" : ""} ${isJsonMode ? "cursor-pointer hover:bg-purple-50 border border-transparent hover:border-purple-300 rounded" : ""} ${isEditMode && !isEditing ? "cursor-pointer hover:bg-blue-50 border border-transparent hover:border-blue-300 rounded" : ""} ${onNodeClick && !isEditing && !isEditMode && !isJsonMode ? "cursor-pointer" : ""}`,
|
|
129
151
|
onClick: handleClick,
|
|
130
|
-
onDoubleClick: handleDoubleClick,
|
|
131
152
|
children: isEditing ? jsxRuntime.jsx("textarea", {
|
|
132
153
|
value: textAreaContent,
|
|
133
154
|
onChange: handleChange,
|
|
134
155
|
onBlur: handleBlur,
|
|
135
156
|
onKeyDown: handleKeyDown,
|
|
136
157
|
autoFocus: true,
|
|
137
|
-
className: "w-full p-1 border border-blue-400 rounded focus:outline-none focus:ring-2 focus:ring-blue-500
|
|
158
|
+
className: "w-full p-1 border border-blue-400 rounded focus:outline-none focus:ring-2 focus:ring-blue-500",
|
|
138
159
|
onClick: e => e.stopPropagation(),
|
|
139
160
|
rows: 3
|
|
140
161
|
}) : jsxRuntime.jsx("div", {
|
|
141
162
|
ref: contentRef,
|
|
142
|
-
className: `prose max-w-none ${isHeading ? getHeadingStyles(headingLevel) : ""}`,
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
163
|
+
className: `prose prose-sm max-w-none ${isHeading ? getHeadingStyles(headingLevel) : "text-sm"}`,
|
|
164
|
+
children: enableSemanticTags && SemanticTagParser.hasSemanticTags(editedContent) ? jsxRuntime.jsx(SemanticTagRenderer.default, {
|
|
165
|
+
content: editedContent,
|
|
166
|
+
showTooltips: true,
|
|
167
|
+
onTagClick: onSemanticTagClick
|
|
168
|
+
}) : jsxRuntime.jsx("span", {
|
|
169
|
+
dangerouslySetInnerHTML: {
|
|
170
|
+
__html: renderedContent
|
|
171
|
+
}
|
|
172
|
+
})
|
|
146
173
|
})
|
|
147
174
|
});
|
|
148
175
|
}
|