@flexiui/svelte-rich-text 0.0.57 → 0.0.59
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/dist/RichText.svelte +83 -7
- package/dist/RichText.svelte.d.ts +1 -0
- package/dist/extensions/AudioPlayer.svelte +8 -8
- package/dist/extensions/MediaGrid/MediaGrid.svelte +1 -1
- package/dist/extensions/MediaGrid/MediaGridItem.svelte +13 -13
- package/dist/extensions/Table/CustomTableCell.js +3 -3
- package/dist/styles.css +59 -1
- package/package.json +1 -1
package/dist/RichText.svelte
CHANGED
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
className?: string;
|
|
28
28
|
editable?: boolean;
|
|
29
29
|
content?: string | {type: string, content: any[]} | null;
|
|
30
|
+
nodesLimit?: number;
|
|
30
31
|
customExtensions?: any[];
|
|
31
32
|
editorEvents?: {
|
|
32
33
|
onTransaction?: (params: any) => void;
|
|
@@ -70,6 +71,7 @@
|
|
|
70
71
|
className,
|
|
71
72
|
editable,
|
|
72
73
|
content,
|
|
74
|
+
nodesLimit,
|
|
73
75
|
customExtensions = [],
|
|
74
76
|
editorEvents = {
|
|
75
77
|
onTransaction: () => {},
|
|
@@ -172,6 +174,8 @@
|
|
|
172
174
|
let enterPressed = $state(false);
|
|
173
175
|
let fontSize = $state(16) as number;
|
|
174
176
|
let lineHeight = $state(null) as number;
|
|
177
|
+
let currentNodeCount = $state(0);
|
|
178
|
+
let showLimitWarning = $state(false);
|
|
175
179
|
|
|
176
180
|
const TEXT_COLOR_PALETTE = [
|
|
177
181
|
editorConfig.editorAccentColor,
|
|
@@ -253,6 +257,25 @@
|
|
|
253
257
|
const isCellSelection = () =>
|
|
254
258
|
$editor && $editor.state.selection instanceof CellSelection;
|
|
255
259
|
|
|
260
|
+
// función para contar nodos en el documento
|
|
261
|
+
function countNodes(doc: any): number {
|
|
262
|
+
// Solo contar los nodos de primer nivel (hijos directos del doc)
|
|
263
|
+
console.log(doc);
|
|
264
|
+
if (doc.type === 'doc' && doc.content) {
|
|
265
|
+
return doc.content.length;
|
|
266
|
+
}
|
|
267
|
+
return 0;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// función para actualizar el contador de nodos
|
|
271
|
+
function updateNodeCount() {
|
|
272
|
+
if ($editor) {
|
|
273
|
+
|
|
274
|
+
currentNodeCount = countNodes($editor.getJSON());
|
|
275
|
+
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
256
279
|
onMount(() => {
|
|
257
280
|
editor = createEditor({
|
|
258
281
|
extensions,
|
|
@@ -263,8 +286,27 @@
|
|
|
263
286
|
},
|
|
264
287
|
handleKeyDown: (view, event) => {
|
|
265
288
|
if (event.key === "Enter" && !event.ctrlKey) {
|
|
289
|
+
// Verificar si hay límite de nodos y si se ha alcanzado
|
|
266
290
|
enterPressed = true;
|
|
267
291
|
|
|
292
|
+
if (nodesLimit) {
|
|
293
|
+
const currentCount = currentNodeCount;
|
|
294
|
+
if (currentCount >= nodesLimit) {
|
|
295
|
+
|
|
296
|
+
if(!showLimitWarning){
|
|
297
|
+
showLimitWarning = true;
|
|
298
|
+
setTimeout(() => {
|
|
299
|
+
showLimitWarning = false;
|
|
300
|
+
}, 3000);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
event.preventDefault();
|
|
304
|
+
event.stopPropagation();
|
|
305
|
+
return true;
|
|
306
|
+
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
268
310
|
setTimeout(() => {
|
|
269
311
|
enterPressed = false;
|
|
270
312
|
const { from } = view.state.selection;
|
|
@@ -318,14 +360,18 @@
|
|
|
318
360
|
},
|
|
319
361
|
},
|
|
320
362
|
onTransaction: ({ editor, transaction }) => {
|
|
321
|
-
|
|
322
|
-
|
|
363
|
+
|
|
364
|
+
// Actualizar contador de nodos
|
|
365
|
+
|
|
366
|
+
updateNodeCount();
|
|
323
367
|
|
|
324
368
|
if (enterPressed) {
|
|
325
|
-
// console.log("Enter pressed");
|
|
326
369
|
return;
|
|
327
370
|
}
|
|
328
371
|
|
|
372
|
+
editorEvents.onTransaction({ editor, transaction });
|
|
373
|
+
editor = editor;
|
|
374
|
+
|
|
329
375
|
const { from } = editor.state.selection;
|
|
330
376
|
|
|
331
377
|
// Obtener el elemento DOM
|
|
@@ -377,6 +423,8 @@
|
|
|
377
423
|
onCreate: ({ editor }) => {
|
|
378
424
|
editorEvents.onCreate({ editor });
|
|
379
425
|
migrateMathStrings(editor);
|
|
426
|
+
|
|
427
|
+
updateNodeCount();
|
|
380
428
|
},
|
|
381
429
|
|
|
382
430
|
onUpdate: ({ editor }) => {
|
|
@@ -461,7 +509,7 @@
|
|
|
461
509
|
});
|
|
462
510
|
}, 100);
|
|
463
511
|
} catch (e) {
|
|
464
|
-
console.log(e.message);
|
|
512
|
+
// console.log(e.message);
|
|
465
513
|
}
|
|
466
514
|
}
|
|
467
515
|
|
|
@@ -1510,6 +1558,22 @@
|
|
|
1510
1558
|
{/if}
|
|
1511
1559
|
|
|
1512
1560
|
<EditorContent editor={$editor} class="fl-rich-text-content" />
|
|
1561
|
+
|
|
1562
|
+
<!-- Bottom bar showing node count -->
|
|
1563
|
+
{#if nodesLimit}
|
|
1564
|
+
<div class="fl-node-count-bar">
|
|
1565
|
+
<span class="fl-node-count-text">
|
|
1566
|
+
<strong>Límite:</strong> {currentNodeCount} de {nodesLimit} nodos
|
|
1567
|
+
</span>
|
|
1568
|
+
<div class="fl-node-count-progress">
|
|
1569
|
+
<div
|
|
1570
|
+
class="fl-node-count-progress-bar"
|
|
1571
|
+
style="width: {Math.min((currentNodeCount / nodesLimit) * 100, 100)}%"
|
|
1572
|
+
></div>
|
|
1573
|
+
</div>
|
|
1574
|
+
</div>
|
|
1575
|
+
{/if}
|
|
1576
|
+
|
|
1513
1577
|
</div>
|
|
1514
1578
|
|
|
1515
1579
|
<div
|
|
@@ -2107,9 +2171,9 @@
|
|
|
2107
2171
|
|
|
2108
2172
|
// ⛔️ Ocultar si hay flag de selección completa por fila/columna
|
|
2109
2173
|
if (isRow || isColumn) {
|
|
2110
|
-
console.log(
|
|
2111
|
-
|
|
2112
|
-
);
|
|
2174
|
+
// console.log(
|
|
2175
|
+
// "Ocultar si hay flag de selección completa por fila/columna"
|
|
2176
|
+
// );
|
|
2113
2177
|
return false;
|
|
2114
2178
|
}
|
|
2115
2179
|
|
|
@@ -2793,9 +2857,21 @@
|
|
|
2793
2857
|
</div>
|
|
2794
2858
|
{/if}
|
|
2795
2859
|
|
|
2860
|
+
<!-- Warning message for node limit -->
|
|
2861
|
+
{#if showLimitWarning && nodesLimit}
|
|
2862
|
+
<div class="fl-node-limit-warning">
|
|
2863
|
+
No se pueden añadir más elementos. Límite alcanzado: {nodesLimit} elementos.
|
|
2864
|
+
</div>
|
|
2865
|
+
{/if}
|
|
2796
2866
|
|
|
2797
2867
|
<style>
|
|
2798
2868
|
.hidden {
|
|
2799
2869
|
display: none;
|
|
2800
2870
|
}
|
|
2871
|
+
|
|
2872
|
+
.fl-node-count-text {
|
|
2873
|
+
strong {
|
|
2874
|
+
margin-right: 4px;
|
|
2875
|
+
}
|
|
2876
|
+
}
|
|
2801
2877
|
</style>
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
id = id + "-" + Math.random().toString(36).substring(2, 15);
|
|
47
47
|
|
|
48
48
|
audioAttributes.subscribe((value) => {
|
|
49
|
-
console.log({ value });
|
|
49
|
+
// console.log({ value });
|
|
50
50
|
});
|
|
51
51
|
|
|
52
52
|
// audioAttributes.set({
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
|
|
74
74
|
function togglePlayPause() {
|
|
75
75
|
playing = !playing;
|
|
76
|
-
console.log({ playing });
|
|
76
|
+
// console.log({ playing });
|
|
77
77
|
|
|
78
78
|
if (playing) {
|
|
79
79
|
activeAudioId.set(id);
|
|
@@ -130,15 +130,15 @@
|
|
|
130
130
|
wavesurfer?.pause();
|
|
131
131
|
}
|
|
132
132
|
});
|
|
133
|
-
console.log({ src });
|
|
134
|
-
console.log({ WaveSurfer });
|
|
133
|
+
// console.log({ src });
|
|
134
|
+
// console.log({ WaveSurfer });
|
|
135
135
|
|
|
136
136
|
if (WaveSurfer) {
|
|
137
137
|
|
|
138
138
|
setTimeout(() => {
|
|
139
139
|
const identifier = "waveform-" + id;
|
|
140
|
-
console.log({ identifier });
|
|
141
|
-
console.log({ waveformEl });
|
|
140
|
+
// console.log({ identifier });
|
|
141
|
+
// console.log({ waveformEl });
|
|
142
142
|
|
|
143
143
|
wavesurfer = WaveSurfer?.create({
|
|
144
144
|
container: waveformEl,
|
|
@@ -193,7 +193,7 @@
|
|
|
193
193
|
|
|
194
194
|
audio.onended = () => {
|
|
195
195
|
playing = false;
|
|
196
|
-
console.log("Audio playback ended");
|
|
196
|
+
// console.log("Audio playback ended");
|
|
197
197
|
};
|
|
198
198
|
|
|
199
199
|
audio.addEventListener("timeupdate", () => {
|
|
@@ -205,7 +205,7 @@
|
|
|
205
205
|
|
|
206
206
|
audio.onended = () => {
|
|
207
207
|
playing = false;
|
|
208
|
-
console.log("Audio playback ended");
|
|
208
|
+
// console.log("Audio playback ended");
|
|
209
209
|
};
|
|
210
210
|
|
|
211
211
|
audio.addEventListener("play", () => {
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
const { node, updateAttributes, selected, getPos, editor }: NodeViewProps = $props();
|
|
7
7
|
|
|
8
|
-
console.log(node);
|
|
8
|
+
// console.log(node);
|
|
9
9
|
let cols = $state(node.attrs.cols || 2);
|
|
10
10
|
let gap = $state(node.attrs.gap || 1);
|
|
11
11
|
let showIndicator = $state(node.attrs.showIndicator || false);
|
|
@@ -119,10 +119,10 @@
|
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
async function handleDragOver(e: any) {
|
|
122
|
-
console.log(e);
|
|
122
|
+
// console.log(e);
|
|
123
123
|
dragging = true;
|
|
124
124
|
e.preventDefault();
|
|
125
|
-
console.log("Drag over");
|
|
125
|
+
// console.log("Drag over");
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
async function handleDrop(e: DragEvent) {
|
|
@@ -140,18 +140,18 @@
|
|
|
140
140
|
);
|
|
141
141
|
|
|
142
142
|
if (files.length > 0) {
|
|
143
|
-
console.log("Dropped local files:", files);
|
|
143
|
+
// console.log("Dropped local files:", files);
|
|
144
144
|
await uploadFiles(files);
|
|
145
145
|
}
|
|
146
146
|
} else {
|
|
147
147
|
dragging = false;
|
|
148
|
-
console.log("Dropped external content:", types);
|
|
148
|
+
// console.log("Dropped external content:", types);
|
|
149
149
|
|
|
150
150
|
// puede ser desde navegador (ejemplo: arrastrar imagen desde otra pestaña)
|
|
151
151
|
if (types.includes("text/uri-list")) {
|
|
152
152
|
const url = e.dataTransfer?.getData("text/uri-list");
|
|
153
153
|
if (url) {
|
|
154
|
-
console.log("Dropped image URL:", url);
|
|
154
|
+
// console.log("Dropped image URL:", url);
|
|
155
155
|
insertImage(url);
|
|
156
156
|
}
|
|
157
157
|
}
|
|
@@ -159,19 +159,19 @@
|
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
function handleDragEnter(e: any) {
|
|
162
|
-
console.log("Drag enter");
|
|
162
|
+
// console.log("Drag enter");
|
|
163
163
|
dragging = true;
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
function handleDragLeave(e: any) {
|
|
167
|
-
console.log("Drag leave");
|
|
167
|
+
// console.log("Drag leave");
|
|
168
168
|
dragging = false;
|
|
169
169
|
}
|
|
170
170
|
|
|
171
171
|
function handleFileChange(e: any) {
|
|
172
|
-
console.log("File change");
|
|
172
|
+
// console.log("File change");
|
|
173
173
|
const files = [...e.target.files];
|
|
174
|
-
console.log(files);
|
|
174
|
+
// console.log(files);
|
|
175
175
|
|
|
176
176
|
uploadFiles(files);
|
|
177
177
|
}
|
|
@@ -200,7 +200,7 @@
|
|
|
200
200
|
// console.log({ errorMessage: docs.message });
|
|
201
201
|
|
|
202
202
|
if (json.error === "Token expired") {
|
|
203
|
-
console.log("Token expired: MediaModal.svelte");
|
|
203
|
+
// console.log("Token expired: MediaModal.svelte");
|
|
204
204
|
// return Astro.redirect('/admin/logout');
|
|
205
205
|
const refreshTokenData = await refreshUserToken(refreshToken);
|
|
206
206
|
|
|
@@ -217,7 +217,7 @@
|
|
|
217
217
|
console.error({ error, message });
|
|
218
218
|
}
|
|
219
219
|
} else if (json.error === "Token missing or invalid") {
|
|
220
|
-
console.log("Token missing or invalid");
|
|
220
|
+
// console.log("Token missing or invalid");
|
|
221
221
|
}
|
|
222
222
|
}
|
|
223
223
|
|
|
@@ -246,9 +246,9 @@
|
|
|
246
246
|
}
|
|
247
247
|
|
|
248
248
|
function dragAreaClickHandler(e) {
|
|
249
|
-
console.log("Clicked drag area");
|
|
249
|
+
// console.log("Clicked drag area");
|
|
250
250
|
if (addGridMediaIconEl) {
|
|
251
|
-
console.log("Add grid Media icon el: ", addGridMediaIconEl);
|
|
251
|
+
// console.log("Add grid Media icon el: ", addGridMediaIconEl);
|
|
252
252
|
showTooltip(addGridMediaIconEl);
|
|
253
253
|
}
|
|
254
254
|
}
|
|
@@ -15,7 +15,7 @@ export const CustomTableCell = TableCell.extend({
|
|
|
15
15
|
},
|
|
16
16
|
addNodeView() {
|
|
17
17
|
const editor = this.editor; // ✅ aquí lo tienes disponible
|
|
18
|
-
console.log('Editor:', editor)
|
|
18
|
+
// console.log('Editor:', editor)
|
|
19
19
|
return SvelteNodeViewRenderer(TableCellNodeView, {
|
|
20
20
|
as: 'td',
|
|
21
21
|
stopEvent: () => false,
|
|
@@ -34,7 +34,7 @@ export const CustomTableCell = TableCell.extend({
|
|
|
34
34
|
this.storage.prevGripSelectionIsInFirstRow = isFirst; // ✅ nuevo flag
|
|
35
35
|
tr.setSelection(rowSel);
|
|
36
36
|
dispatch(tr);
|
|
37
|
-
console.log('Row selected. Is first row?', isFirst);
|
|
37
|
+
// console.log('Row selected. Is first row?', isFirst);
|
|
38
38
|
}
|
|
39
39
|
return true;
|
|
40
40
|
},
|
|
@@ -49,7 +49,7 @@ export const CustomTableCell = TableCell.extend({
|
|
|
49
49
|
this.storage.prevGripSelectionIsInFirstRow = isFirst; // ✅ nuevo flag
|
|
50
50
|
tr.setSelection(colSel);
|
|
51
51
|
dispatch(tr);
|
|
52
|
-
console.log('Column selected. Is first row?', isFirst);
|
|
52
|
+
// console.log('Column selected. Is first row?', isFirst);
|
|
53
53
|
}
|
|
54
54
|
return true;
|
|
55
55
|
},
|
package/dist/styles.css
CHANGED
|
@@ -411,7 +411,7 @@ button {
|
|
|
411
411
|
}
|
|
412
412
|
|
|
413
413
|
.fl-range-element input {
|
|
414
|
-
accent-color:
|
|
414
|
+
accent-color: var(--fl-editor-accent-color);
|
|
415
415
|
}
|
|
416
416
|
|
|
417
417
|
.fl-range-element-value {
|
|
@@ -490,6 +490,64 @@ button {
|
|
|
490
490
|
}
|
|
491
491
|
}
|
|
492
492
|
|
|
493
|
+
/* Node limit styles */
|
|
494
|
+
.fl-node-limit-warning {
|
|
495
|
+
position: fixed;
|
|
496
|
+
bottom: 20px;
|
|
497
|
+
right: 20px;
|
|
498
|
+
background: #ff4444;
|
|
499
|
+
color: white;
|
|
500
|
+
padding: 12px 16px;
|
|
501
|
+
border-radius: 8px;
|
|
502
|
+
font-size: 14px;
|
|
503
|
+
font-weight: 500;
|
|
504
|
+
box-shadow: 0 4px 12px rgba(255, 68, 68, 0.3);
|
|
505
|
+
z-index: 1000;
|
|
506
|
+
animation: slideInRight 0.3s ease-out;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
.fl-node-count-bar {
|
|
510
|
+
background: var(--fl-toolbar-bg, #242424);
|
|
511
|
+
border-top: 1px solid #333;
|
|
512
|
+
padding: 8px 16px;
|
|
513
|
+
display: flex;
|
|
514
|
+
align-items: center;
|
|
515
|
+
gap: 12px;
|
|
516
|
+
font-size: 12px;
|
|
517
|
+
color: var(--fl-toolbar-text-color, currentColor);
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
.fl-node-count-text {
|
|
521
|
+
font-weight: 500;
|
|
522
|
+
min-width: fit-content;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
.fl-node-count-progress {
|
|
526
|
+
flex: 1;
|
|
527
|
+
height: 4px;
|
|
528
|
+
background: rgba(255, 255, 255, 0.1);
|
|
529
|
+
border-radius: 2px;
|
|
530
|
+
overflow: hidden;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
.fl-node-count-progress-bar {
|
|
534
|
+
height: 100%;
|
|
535
|
+
background: var(--fl-editor-accent-color, #535bf2);
|
|
536
|
+
transition: width 0.2s ease;
|
|
537
|
+
border-radius: 2px;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
@keyframes slideInRight {
|
|
541
|
+
from {
|
|
542
|
+
transform: translateX(100%);
|
|
543
|
+
opacity: 0;
|
|
544
|
+
}
|
|
545
|
+
to {
|
|
546
|
+
transform: translateX(0);
|
|
547
|
+
opacity: 1;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
|
|
493
551
|
.media-grid-item-view-content > div {
|
|
494
552
|
display: flex;
|
|
495
553
|
height: 100%;
|