@flexiui/svelte-rich-text 0.0.18 → 0.0.20
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 +415 -195
- package/dist/RichText.svelte.d.ts +1 -1
- package/dist/extensions/NodeLineHeight.d.ts +10 -0
- package/dist/extensions/NodeLineHeight.js +41 -0
- package/dist/styles.css +234 -1
- package/package.json +1 -1
package/dist/RichText.svelte
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { NodeLineHeight } from './extensions/NodeLineHeight';
|
|
2
3
|
import {
|
|
3
4
|
Mathematics,
|
|
4
5
|
migrateMathStrings,
|
|
5
6
|
} from "@tiptap/extension-mathematics";
|
|
6
7
|
import { HEADINGS, rgbToHex } from "./utils";
|
|
7
8
|
import "./styles.css";
|
|
8
|
-
import
|
|
9
|
+
import "katex/dist/katex.min.css";
|
|
9
10
|
|
|
10
11
|
import { onMount, onDestroy } from "svelte";
|
|
11
12
|
import type { Readable } from "svelte/store";
|
|
12
13
|
|
|
13
14
|
import { createEditor, Editor, EditorContent } from "svelte-tiptap";
|
|
14
15
|
|
|
16
|
+
import { Paragraph } from "@tiptap/extension-paragraph";
|
|
17
|
+
import { Heading } from "@tiptap/extension-heading";
|
|
15
18
|
import StarterKit from "@tiptap/starter-kit";
|
|
16
19
|
import Highlight from "@tiptap/extension-highlight";
|
|
17
20
|
import TextAlign from "@tiptap/extension-text-align";
|
|
@@ -132,6 +135,7 @@
|
|
|
132
135
|
},
|
|
133
136
|
},
|
|
134
137
|
}),
|
|
138
|
+
NodeLineHeight,
|
|
135
139
|
...customExtensions,
|
|
136
140
|
];
|
|
137
141
|
|
|
@@ -142,6 +146,7 @@
|
|
|
142
146
|
let cleanup: () => void;
|
|
143
147
|
let currentTriggerEl: HTMLElement | null = null;
|
|
144
148
|
let activeDropdownType = $state(null);
|
|
149
|
+
let enterPressed = $state(false);
|
|
145
150
|
|
|
146
151
|
const TEXT_COLOR_PALETTE = [
|
|
147
152
|
"rgb(94, 23, 235)",
|
|
@@ -223,9 +228,114 @@
|
|
|
223
228
|
editor = createEditor({
|
|
224
229
|
extensions,
|
|
225
230
|
content,
|
|
231
|
+
editorProps: {
|
|
232
|
+
attributes: {
|
|
233
|
+
class: "fl-rich-text-content-eee",
|
|
234
|
+
},
|
|
235
|
+
handleKeyDown: (view, event) => {
|
|
236
|
+
if (event.key === "Enter" && !event.ctrlKey) {
|
|
237
|
+
console.log("Enter");
|
|
238
|
+
enterPressed = true;
|
|
239
|
+
|
|
240
|
+
setTimeout(() => {
|
|
241
|
+
enterPressed = false;
|
|
242
|
+
const { from } = view.state.selection;
|
|
243
|
+
|
|
244
|
+
// Obtener el nodo de ProseMirror en la posición actual
|
|
245
|
+
const pos = view.state.doc.resolve(from);
|
|
246
|
+
const nodeBefore = pos.node(pos.depth);
|
|
247
|
+
const parentNode = pos.node(pos.depth - 1);
|
|
248
|
+
|
|
249
|
+
console.log("Node type:", nodeBefore.type.name);
|
|
250
|
+
console.log("Parent node type:", parentNode?.type.name);
|
|
251
|
+
|
|
252
|
+
// Solo ejecutar si estamos en un párrafo Y el padre no es una lista
|
|
253
|
+
const isInList = parentNode?.type.name === "listItem" ||
|
|
254
|
+
parentNode?.type.name === "bulletList" ||
|
|
255
|
+
parentNode?.type.name === "orderedList";
|
|
256
|
+
|
|
257
|
+
if (nodeBefore.type.name === "paragraph" && !isInList) {
|
|
258
|
+
const domAtPos = view.domAtPos(from);
|
|
259
|
+
let element = domAtPos.node;
|
|
260
|
+
|
|
261
|
+
if (element.nodeType === Node.TEXT_NODE) {
|
|
262
|
+
element = element.parentElement;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (element instanceof HTMLElement) {
|
|
266
|
+
const computedSize = window.getComputedStyle(element).fontSize;
|
|
267
|
+
const computedLineHeight = window.getComputedStyle(element).lineHeight;
|
|
268
|
+
console.log({ computedSize, computedLineHeight });
|
|
269
|
+
|
|
270
|
+
const lineHeightPx = parseFloat(computedLineHeight.replace("px", ""))
|
|
271
|
+
const fontSizePx = parseFloat(computedSize.replace("px", ""))
|
|
272
|
+
|
|
273
|
+
const lineHeightUnitless = lineHeightPx / fontSizePx;
|
|
274
|
+
|
|
275
|
+
console.log(lineHeightUnitless.toFixed(2)); // ej: "x.xx"
|
|
276
|
+
|
|
277
|
+
fontSize = Math.round(Number(computedSize.replace("px", "")));
|
|
278
|
+
$editor.chain().focus().unsetFontSize().run();
|
|
279
|
+
|
|
280
|
+
$editor.chain().focus().unsetNodeLineHeight().run();
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}, 200);
|
|
284
|
+
}
|
|
285
|
+
},
|
|
286
|
+
},
|
|
226
287
|
onTransaction: ({ editor, transaction }) => {
|
|
227
288
|
editorEvents.onTransaction({ editor, transaction });
|
|
228
289
|
editor = editor;
|
|
290
|
+
|
|
291
|
+
if (enterPressed) {
|
|
292
|
+
console.log("Enter pressed");
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
const { from } = editor.state.selection;
|
|
297
|
+
|
|
298
|
+
// Obtener el elemento DOM
|
|
299
|
+
const domAtPos = editor.view.domAtPos(from);
|
|
300
|
+
let element = domAtPos.node;
|
|
301
|
+
|
|
302
|
+
// Si es un text node, obtener su padre
|
|
303
|
+
if (element.nodeType === Node.TEXT_NODE) {
|
|
304
|
+
element = element.parentElement;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Obtener el font-size computado
|
|
308
|
+
if (element instanceof HTMLElement) {
|
|
309
|
+
const computedSize = window.getComputedStyle(element).fontSize;
|
|
310
|
+
const computedLineHeight = window.getComputedStyle(element).lineHeight;
|
|
311
|
+
console.log("Get element font size:", computedSize);
|
|
312
|
+
console.log("Get element line height:", computedLineHeight);
|
|
313
|
+
const lineHeightPx = parseFloat(computedLineHeight.replace("px", ""))
|
|
314
|
+
const fontSizePx = parseFloat(computedSize.replace("px", ""))
|
|
315
|
+
const lineHeightUnitless = lineHeightPx / fontSizePx;
|
|
316
|
+
|
|
317
|
+
console.log(lineHeightUnitless.toFixed(2)); // ej: "x.xx"
|
|
318
|
+
|
|
319
|
+
// O desde Tiptap
|
|
320
|
+
const tiptapSize = editor.getAttributes("textStyle").fontSize;
|
|
321
|
+
const tiptapLineHeight = editor.getAttributes("textStyle").lineHeight;
|
|
322
|
+
console.log("Tiptap font size:", tiptapSize ? tiptapSize : "default");
|
|
323
|
+
console.log("Tiptap line height:", tiptapLineHeight ? tiptapLineHeight : "default");
|
|
324
|
+
|
|
325
|
+
if (tiptapSize) {
|
|
326
|
+
fontSize = Number(tiptapSize.replace("px", ""));
|
|
327
|
+
} else {
|
|
328
|
+
fontSize = Math.round(Number(computedSize.replace("px", "")));
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
if (tiptapLineHeight) {
|
|
332
|
+
lineHeight = Number(tiptapLineHeight.replace("px", ""));
|
|
333
|
+
} else {
|
|
334
|
+
lineHeight = Number(lineHeightUnitless.toFixed(2));
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
}
|
|
229
339
|
},
|
|
230
340
|
|
|
231
341
|
onBeforeCreate({ editor }) {
|
|
@@ -252,6 +362,7 @@
|
|
|
252
362
|
onSelectionUpdate({ editor }) {
|
|
253
363
|
editorEvents.onSelectionUpdate({ editor });
|
|
254
364
|
},
|
|
365
|
+
|
|
255
366
|
onFocus({ editor, event }) {
|
|
256
367
|
editorEvents.onFocus({ editor, event });
|
|
257
368
|
},
|
|
@@ -349,11 +460,45 @@
|
|
|
349
460
|
return $editor.chain().insertInlineMath({ latex }).focus().run();
|
|
350
461
|
}
|
|
351
462
|
}
|
|
463
|
+
|
|
464
|
+
let fontSize = $state(16) as number;
|
|
465
|
+
let lineHeight = $state(null) as number;
|
|
466
|
+
|
|
467
|
+
function decrementFontSize() {
|
|
468
|
+
fontSize = fontSize - 1;
|
|
469
|
+
$editor
|
|
470
|
+
.chain()
|
|
471
|
+
.focus()
|
|
472
|
+
.setFontSize(fontSize + "px")
|
|
473
|
+
.run();
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
function incrementFontSize() {
|
|
477
|
+
fontSize = fontSize + 1;
|
|
478
|
+
$editor
|
|
479
|
+
.chain()
|
|
480
|
+
.focus()
|
|
481
|
+
.setFontSize(fontSize + "px")
|
|
482
|
+
.run();
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
function handleRangeInput(e: any) {
|
|
486
|
+
|
|
487
|
+
|
|
488
|
+
|
|
489
|
+
$editor
|
|
490
|
+
.chain()
|
|
491
|
+
.focus()
|
|
492
|
+
.setNodeLineHeight(e.target.value.toString())
|
|
493
|
+
.run();
|
|
494
|
+
|
|
495
|
+
}
|
|
352
496
|
</script>
|
|
353
497
|
|
|
354
498
|
<div class="fl-rich-text {className}" class:editable>
|
|
355
499
|
{#if editor}
|
|
356
500
|
<header class="fl-rich-text-toolbar">
|
|
501
|
+
<!-- Undo/Redo -->
|
|
357
502
|
<div role="group" class="fl-rich-text-toolbar-group">
|
|
358
503
|
<button
|
|
359
504
|
type="button"
|
|
@@ -399,7 +544,9 @@
|
|
|
399
544
|
</button>
|
|
400
545
|
</div>
|
|
401
546
|
|
|
547
|
+
<!-- Heading & list dropdowns -->
|
|
402
548
|
<div class="fl-rich-text-toolbar-group">
|
|
549
|
+
<!-- Heading -->
|
|
403
550
|
<button
|
|
404
551
|
type="button"
|
|
405
552
|
onclick={(e) => toogleDropdown(e.currentTarget, "headings-dropdown")}
|
|
@@ -433,18 +580,12 @@
|
|
|
433
580
|
xmlns="http://www.w3.org/2000/svg"
|
|
434
581
|
fill="none"
|
|
435
582
|
viewBox="0 0 10 6"
|
|
436
|
-
><path
|
|
437
|
-
stroke="currentColor"
|
|
438
|
-
stroke-linecap="round"
|
|
439
|
-
stroke-linejoin="round"
|
|
440
|
-
stroke-width="2"
|
|
441
|
-
d="m1 1 4 4 4-4"
|
|
442
|
-
></path></svg
|
|
443
583
|
>
|
|
584
|
+
<use href="#dropdown-arrow"></use>
|
|
585
|
+
</svg>
|
|
444
586
|
</button>
|
|
445
|
-
</div>
|
|
446
587
|
|
|
447
|
-
|
|
588
|
+
<!-- List -->
|
|
448
589
|
<button
|
|
449
590
|
aria-label="List"
|
|
450
591
|
type="button"
|
|
@@ -616,16 +757,15 @@
|
|
|
616
757
|
xmlns="http://www.w3.org/2000/svg"
|
|
617
758
|
fill="none"
|
|
618
759
|
viewBox="0 0 10 6"
|
|
619
|
-
><path
|
|
620
|
-
stroke="currentColor"
|
|
621
|
-
stroke-linecap="round"
|
|
622
|
-
stroke-linejoin="round"
|
|
623
|
-
stroke-width="2"
|
|
624
|
-
d="m1 1 4 4 4-4"
|
|
625
|
-
></path></svg
|
|
626
760
|
>
|
|
761
|
+
<use href="#dropdown-arrow"></use>
|
|
762
|
+
</svg>
|
|
627
763
|
</button>
|
|
764
|
+
</div>
|
|
628
765
|
|
|
766
|
+
<!-- Code block & blockquote -->
|
|
767
|
+
<div role="group" class="fl-rich-text-toolbar-group">
|
|
768
|
+
<!-- Code block -->
|
|
629
769
|
<button
|
|
630
770
|
aria-label="Code block"
|
|
631
771
|
type="button"
|
|
@@ -658,6 +798,7 @@
|
|
|
658
798
|
>
|
|
659
799
|
</button>
|
|
660
800
|
|
|
801
|
+
<!-- Blockquote -->
|
|
661
802
|
<button
|
|
662
803
|
aria-label="Blockquote"
|
|
663
804
|
type="button"
|
|
@@ -680,6 +821,44 @@
|
|
|
680
821
|
</button>
|
|
681
822
|
</div>
|
|
682
823
|
|
|
824
|
+
<!-- Font size editor -->
|
|
825
|
+
<div role="group" class="fl-rich-text-toolbar-group flex-auto">
|
|
826
|
+
<div class="fl-font-size-editor flex-auto">
|
|
827
|
+
<button
|
|
828
|
+
onclick={decrementFontSize}
|
|
829
|
+
class="fl-font-size-editor-button">-</button
|
|
830
|
+
>
|
|
831
|
+
<input type="text" bind:value={fontSize} />
|
|
832
|
+
<button
|
|
833
|
+
onclick={incrementFontSize}
|
|
834
|
+
class="fl-font-size-editor-button">+</button
|
|
835
|
+
>
|
|
836
|
+
</div>
|
|
837
|
+
</div>
|
|
838
|
+
|
|
839
|
+
<!-- Line height -->
|
|
840
|
+
<div role="group" class="fl-rich-text-toolbar-group">
|
|
841
|
+
<button
|
|
842
|
+
class="fl-font-size-button"
|
|
843
|
+
aria-label="Line height"
|
|
844
|
+
type="button"
|
|
845
|
+
onclick={(e) => toogleDropdown(e.currentTarget, "line-height-dropdown")}
|
|
846
|
+
>
|
|
847
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-line-height"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M3 8l3 -3l3 3" /><path d="M3 16l3 3l3 -3" /><path d="M6 5l0 14" /><path d="M13 6l7 0" /><path d="M13 12l7 0" /><path d="M13 18l7 0" /></svg>
|
|
848
|
+
|
|
849
|
+
<svg
|
|
850
|
+
class="toogle-dropdown-button-icon"
|
|
851
|
+
aria-hidden="true"
|
|
852
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
853
|
+
fill="none"
|
|
854
|
+
viewBox="0 0 10 6"
|
|
855
|
+
>
|
|
856
|
+
<use href="#dropdown-arrow"></use>
|
|
857
|
+
</svg>
|
|
858
|
+
</button>
|
|
859
|
+
</div>
|
|
860
|
+
|
|
861
|
+
<!-- Bold, Italic, Underline, etc. -->
|
|
683
862
|
<div role="group" class="fl-rich-text-toolbar-group">
|
|
684
863
|
<button
|
|
685
864
|
type="button"
|
|
@@ -800,7 +979,9 @@
|
|
|
800
979
|
</button>
|
|
801
980
|
</div>
|
|
802
981
|
|
|
982
|
+
<!-- Link, special box, horizontal rule, etc. -->
|
|
803
983
|
<div role="group" class="fl-rich-text-toolbar-group">
|
|
984
|
+
<!-- Link -->
|
|
804
985
|
<button
|
|
805
986
|
type="button"
|
|
806
987
|
onclick={() => setLink()}
|
|
@@ -825,6 +1006,7 @@
|
|
|
825
1006
|
>
|
|
826
1007
|
</button>
|
|
827
1008
|
|
|
1009
|
+
<!-- Special box -->
|
|
828
1010
|
<button
|
|
829
1011
|
class="fl-bubble-menu-mark-button"
|
|
830
1012
|
class:is-active={$editor?.isActive("specialBox")}
|
|
@@ -835,6 +1017,7 @@
|
|
|
835
1017
|
<span class="special-box-icon">A</span>
|
|
836
1018
|
</button>
|
|
837
1019
|
|
|
1020
|
+
<!-- Horizontal rule -->
|
|
838
1021
|
<button
|
|
839
1022
|
type="button"
|
|
840
1023
|
onclick={() => $editor.chain().focus().setHorizontalRule().run()}
|
|
@@ -855,6 +1038,7 @@
|
|
|
855
1038
|
>
|
|
856
1039
|
</button>
|
|
857
1040
|
|
|
1041
|
+
<!-- Hard break -->
|
|
858
1042
|
<button
|
|
859
1043
|
type="button"
|
|
860
1044
|
onclick={() => $editor.chain().focus().setHardBreak().run()}
|
|
@@ -877,10 +1061,12 @@
|
|
|
877
1061
|
>
|
|
878
1062
|
</button>
|
|
879
1063
|
|
|
1064
|
+
<!-- Text color dropdown -->
|
|
880
1065
|
<button
|
|
881
1066
|
aria-label="Toggle text color dropdown"
|
|
882
1067
|
type="button"
|
|
883
|
-
onclick={(e) =>
|
|
1068
|
+
onclick={(e) =>
|
|
1069
|
+
toogleDropdown(e.currentTarget, "text-color-dropdown")}
|
|
884
1070
|
>
|
|
885
1071
|
<span
|
|
886
1072
|
class="fl-button-color-text-popover"
|
|
@@ -893,24 +1079,68 @@
|
|
|
893
1079
|
aria-hidden="true"
|
|
894
1080
|
xmlns="http://www.w3.org/2000/svg"
|
|
895
1081
|
fill="none"
|
|
896
|
-
viewBox="0 0
|
|
1082
|
+
viewBox="0 0 20 12"
|
|
1083
|
+
>
|
|
1084
|
+
<defs>
|
|
1085
|
+
<symbol id="dropdown-arrow" viewBox="0 0 10 6" fill="none">
|
|
1086
|
+
<path
|
|
1087
|
+
stroke="currentColor"
|
|
1088
|
+
stroke-linecap="round"
|
|
1089
|
+
stroke-linejoin="round"
|
|
1090
|
+
stroke-width="2"
|
|
1091
|
+
d="m1 1 4 4 4-4"
|
|
1092
|
+
></path>
|
|
1093
|
+
</symbol>
|
|
1094
|
+
</defs>
|
|
1095
|
+
<use href="#dropdown-arrow"></use>
|
|
1096
|
+
</svg>
|
|
1097
|
+
</button>
|
|
1098
|
+
|
|
1099
|
+
<!-- Highlight dropdown -->
|
|
1100
|
+
<button
|
|
1101
|
+
class="fl-bubble-menu-mark-button"
|
|
1102
|
+
type="button"
|
|
1103
|
+
aria-label="Highlight"
|
|
1104
|
+
onclick={(e) => toogleDropdown(e.currentTarget, "highlight")}
|
|
1105
|
+
>
|
|
1106
|
+
<svg
|
|
1107
|
+
width="24"
|
|
1108
|
+
height="24"
|
|
1109
|
+
class="tiptap-button-icon"
|
|
1110
|
+
viewBox="0 0 24 24"
|
|
1111
|
+
fill="currentColor"
|
|
1112
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
897
1113
|
><path
|
|
1114
|
+
fill-rule="evenodd"
|
|
1115
|
+
clip-rule="evenodd"
|
|
1116
|
+
d="M14.7072 4.70711C15.0977 4.31658 15.0977 3.68342 14.7072 3.29289C14.3167 2.90237 13.6835 2.90237 13.293 3.29289L8.69294 7.89286L8.68594 7.9C8.13626 8.46079 7.82837 9.21474 7.82837 10C7.82837 10.2306 7.85491 10.4584 7.90631 10.6795L2.29289 16.2929C2.10536 16.4804 2 16.7348 2 17V20C2 20.5523 2.44772 21 3 21H12C12.2652 21 12.5196 20.8946 12.7071 20.7071L15.3205 18.0937C15.5416 18.1452 15.7695 18.1717 16.0001 18.1717C16.7853 18.1717 17.5393 17.8639 18.1001 17.3142L22.7072 12.7071C23.0977 12.3166 23.0977 11.6834 22.7072 11.2929C22.3167 10.9024 21.6835 10.9024 21.293 11.2929L16.6971 15.8887C16.5105 16.0702 16.2605 16.1717 16.0001 16.1717C15.7397 16.1717 15.4897 16.0702 15.303 15.8887L10.1113 10.697C9.92992 10.5104 9.82837 10.2604 9.82837 10C9.82837 9.73963 9.92992 9.48958 10.1113 9.30297L14.7072 4.70711ZM13.5858 17L9.00004 12.4142L4 17.4142V19H11.5858L13.5858 17Z"
|
|
1117
|
+
fill="currentColor"
|
|
1118
|
+
></path>
|
|
1119
|
+
</svg>
|
|
1120
|
+
<svg
|
|
1121
|
+
class="toogle-dropdown-button-icon"
|
|
1122
|
+
aria-hidden="true"
|
|
1123
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
1124
|
+
fill="none"
|
|
1125
|
+
viewBox="0 0 10 6"
|
|
1126
|
+
>
|
|
1127
|
+
<path
|
|
898
1128
|
stroke="currentColor"
|
|
899
1129
|
stroke-linecap="round"
|
|
900
1130
|
stroke-linejoin="round"
|
|
901
1131
|
stroke-width="2"
|
|
902
1132
|
d="m1 1 4 4 4-4"
|
|
903
|
-
></path
|
|
904
|
-
>
|
|
1133
|
+
></path>
|
|
1134
|
+
</svg>
|
|
905
1135
|
</button>
|
|
906
1136
|
</div>
|
|
907
1137
|
|
|
1138
|
+
<!-- Inline math -->
|
|
908
1139
|
<div role="group" class="fl-rich-text-toolbar-group">
|
|
909
1140
|
<button
|
|
910
1141
|
type="button"
|
|
911
1142
|
onclick={addInlineMath}
|
|
912
|
-
|
|
913
|
-
aria-label="Bold"
|
|
1143
|
+
aria-label="Add inline LaTeX math"
|
|
914
1144
|
>
|
|
915
1145
|
<svg
|
|
916
1146
|
xmlns="http://www.w3.org/2000/svg"
|
|
@@ -930,7 +1160,9 @@
|
|
|
930
1160
|
</button>
|
|
931
1161
|
</div>
|
|
932
1162
|
|
|
1163
|
+
<!-- Text align, clear formatting, clear nodes -->
|
|
933
1164
|
<div role="group" class="fl-rich-text-toolbar-group">
|
|
1165
|
+
<!-- Text align left -->
|
|
934
1166
|
<button
|
|
935
1167
|
type="button"
|
|
936
1168
|
onclick={() => $editor.chain().focus().toggleTextAlign("left").run()}
|
|
@@ -952,6 +1184,7 @@
|
|
|
952
1184
|
>
|
|
953
1185
|
</button>
|
|
954
1186
|
|
|
1187
|
+
<!-- Text align center -->
|
|
955
1188
|
<button
|
|
956
1189
|
type="button"
|
|
957
1190
|
onclick={() =>
|
|
@@ -974,6 +1207,7 @@
|
|
|
974
1207
|
>
|
|
975
1208
|
</button>
|
|
976
1209
|
|
|
1210
|
+
<!-- Text align right -->
|
|
977
1211
|
<button
|
|
978
1212
|
type="button"
|
|
979
1213
|
onclick={() => $editor.chain().focus().toggleTextAlign("right").run()}
|
|
@@ -995,6 +1229,7 @@
|
|
|
995
1229
|
>
|
|
996
1230
|
</button>
|
|
997
1231
|
|
|
1232
|
+
<!-- Clear formatting -->
|
|
998
1233
|
<button
|
|
999
1234
|
aria-label="Clear formatting"
|
|
1000
1235
|
type="button"
|
|
@@ -1019,6 +1254,7 @@
|
|
|
1019
1254
|
>
|
|
1020
1255
|
</button>
|
|
1021
1256
|
|
|
1257
|
+
<!-- Clear nodes -->
|
|
1022
1258
|
<button
|
|
1023
1259
|
type="button"
|
|
1024
1260
|
onclick={() => $editor.chain().focus().clearNodes().run()}
|
|
@@ -1305,7 +1541,10 @@
|
|
|
1305
1541
|
onblur={(event: any) => {
|
|
1306
1542
|
const inclued = recentCustomColors.includes(event?.target?.value);
|
|
1307
1543
|
if (!inclued) {
|
|
1308
|
-
recentCustomColors = [
|
|
1544
|
+
recentCustomColors = [
|
|
1545
|
+
...recentCustomColors,
|
|
1546
|
+
event?.target?.value,
|
|
1547
|
+
];
|
|
1309
1548
|
}
|
|
1310
1549
|
$editor.chain().focus().setColor(event?.target?.value).run();
|
|
1311
1550
|
hideDropdown();
|
|
@@ -1313,7 +1552,10 @@
|
|
|
1313
1552
|
onchange={(event: any) => {
|
|
1314
1553
|
const inclued = recentCustomColors.includes(event?.target?.value);
|
|
1315
1554
|
if (!inclued) {
|
|
1316
|
-
recentCustomColors = [
|
|
1555
|
+
recentCustomColors = [
|
|
1556
|
+
...recentCustomColors,
|
|
1557
|
+
event?.target?.value,
|
|
1558
|
+
];
|
|
1317
1559
|
}
|
|
1318
1560
|
$editor.chain().focus().setColor(event?.target?.value).run();
|
|
1319
1561
|
hideDropdown();
|
|
@@ -1421,178 +1663,156 @@
|
|
|
1421
1663
|
</button>
|
|
1422
1664
|
{/if}
|
|
1423
1665
|
</div>
|
|
1424
|
-
{
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
display: flex;
|
|
1457
|
-
flex-wrap: nowrap;
|
|
1458
|
-
gap: var(--toolbar-gap);
|
|
1459
|
-
|
|
1460
|
-
button {
|
|
1461
|
-
padding: 8px 8px;
|
|
1462
|
-
flex: auto;
|
|
1463
|
-
border: none;
|
|
1464
|
-
background: rgba(255, 255, 255, 0.1);
|
|
1465
|
-
border-radius: 8px;
|
|
1466
|
-
color: var(--text-color);
|
|
1467
|
-
font-size: 14px;
|
|
1468
|
-
display: flex;
|
|
1469
|
-
align-items: center;
|
|
1470
|
-
justify-content: center;
|
|
1471
|
-
white-space: nowrap;
|
|
1472
|
-
gap: 2px;
|
|
1473
|
-
cursor: pointer;
|
|
1474
|
-
line-height: 1;
|
|
1475
|
-
|
|
1476
|
-
& svg {
|
|
1477
|
-
width: 16px;
|
|
1478
|
-
height: 16px;
|
|
1479
|
-
|
|
1480
|
-
&.toogle-dropdown-button-icon {
|
|
1481
|
-
width: 7px;
|
|
1482
|
-
height: 7px;
|
|
1483
|
-
margin-left: 4px;
|
|
1484
|
-
}
|
|
1485
|
-
}
|
|
1486
|
-
|
|
1487
|
-
&:disabled {
|
|
1488
|
-
cursor: not-allowed;
|
|
1489
|
-
opacity: 0.5;
|
|
1490
|
-
}
|
|
1491
|
-
}
|
|
1492
|
-
}
|
|
1493
|
-
|
|
1494
|
-
button.is-active {
|
|
1495
|
-
background: var(--purple);
|
|
1496
|
-
color: white;
|
|
1497
|
-
}
|
|
1498
|
-
|
|
1499
|
-
.special-box-icon {
|
|
1500
|
-
width: 16px;
|
|
1501
|
-
height: 16px;
|
|
1502
|
-
display: flex;
|
|
1503
|
-
align-items: center;
|
|
1504
|
-
justify-content: center;
|
|
1505
|
-
font-weight: 500;
|
|
1506
|
-
border: none;
|
|
1507
|
-
padding: 0px;
|
|
1508
|
-
font-size: 12px;
|
|
1509
|
-
border-radius: 3px;
|
|
1510
|
-
outline: 1px dashed #818181;
|
|
1511
|
-
scale: 1.1;
|
|
1512
|
-
}
|
|
1513
|
-
|
|
1514
|
-
.fl-button-color-text-popover {
|
|
1515
|
-
color: inherit;
|
|
1516
|
-
width: 16px;
|
|
1517
|
-
height: 16px;
|
|
1518
|
-
border-radius: 100%;
|
|
1519
|
-
border: 1px solid #d7d7d78a;
|
|
1520
|
-
box-sizing: border-box;
|
|
1521
|
-
display: flex;
|
|
1522
|
-
align-items: center;
|
|
1523
|
-
justify-content: center;
|
|
1524
|
-
}
|
|
1525
|
-
|
|
1526
|
-
.fl-editor-color-palette {
|
|
1527
|
-
width: 100%;
|
|
1528
|
-
display: grid;
|
|
1529
|
-
grid-template-columns: repeat(7, 1fr);
|
|
1530
|
-
gap: 6px;
|
|
1531
|
-
align-items: center;
|
|
1532
|
-
|
|
1533
|
-
.fl-color-swatch {
|
|
1534
|
-
display: flex;
|
|
1535
|
-
min-width: 17px;
|
|
1536
|
-
border-radius: 100%;
|
|
1537
|
-
align-items: center;
|
|
1538
|
-
justify-content: center;
|
|
1539
|
-
outline: 1px solid #83828238;
|
|
1540
|
-
position: relative;
|
|
1541
|
-
aspect-ratio: 1;
|
|
1542
|
-
border: none;
|
|
1543
|
-
padding: 0;
|
|
1544
|
-
cursor: pointer;
|
|
1545
|
-
|
|
1546
|
-
&.active {
|
|
1547
|
-
box-shadow: 0 0 0 2px #ffffff30;
|
|
1548
|
-
}
|
|
1549
|
-
|
|
1550
|
-
&.unset-color::after {
|
|
1551
|
-
content: "";
|
|
1552
|
-
width: 2px;
|
|
1553
|
-
height: 100%;
|
|
1554
|
-
background: red;
|
|
1555
|
-
position: absolute;
|
|
1556
|
-
transform: rotate(30deg) scaleY(1.2);
|
|
1557
|
-
}
|
|
1558
|
-
}
|
|
1666
|
+
{:else if activeDropdownType === "highlight"}
|
|
1667
|
+
<div class="fl-editor-color-palette">
|
|
1668
|
+
<button
|
|
1669
|
+
class="fl-color-swatch fl-color-picker-btn"
|
|
1670
|
+
aria-label="Highlight color picker"
|
|
1671
|
+
type="button"
|
|
1672
|
+
>
|
|
1673
|
+
<input
|
|
1674
|
+
type="color"
|
|
1675
|
+
onblur={(event: any) => {
|
|
1676
|
+
const inclued = recentCustomColors.includes(event?.target?.value);
|
|
1677
|
+
if (!inclued) {
|
|
1678
|
+
recentCustomColors = [
|
|
1679
|
+
...recentCustomColors,
|
|
1680
|
+
event?.target?.value,
|
|
1681
|
+
];
|
|
1682
|
+
}
|
|
1683
|
+
$editor
|
|
1684
|
+
.chain()
|
|
1685
|
+
.focus()
|
|
1686
|
+
.setHighlight({ color: event?.target?.value })
|
|
1687
|
+
.run();
|
|
1688
|
+
hideDropdown();
|
|
1689
|
+
}}
|
|
1690
|
+
onchange={(event: any) => {
|
|
1691
|
+
const inclued = recentCustomColors.includes(event?.target?.value);
|
|
1692
|
+
if (!inclued) {
|
|
1693
|
+
recentCustomColors = [
|
|
1694
|
+
...recentCustomColors,
|
|
1695
|
+
event?.target?.value,
|
|
1696
|
+
];
|
|
1697
|
+
}
|
|
1559
1698
|
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
&::-webkit-color-swatch-wrapper {
|
|
1574
|
-
padding: 0;
|
|
1575
|
-
}
|
|
1699
|
+
$editor
|
|
1700
|
+
.chain()
|
|
1701
|
+
.focus()
|
|
1702
|
+
.setHighlight({ color: event?.target?.value })
|
|
1703
|
+
.run();
|
|
1704
|
+
hideDropdown();
|
|
1705
|
+
}}
|
|
1706
|
+
value={rgbToHex($editor?.getAttributes("textStyle")?.color)}
|
|
1707
|
+
data-testid="setHiglight"
|
|
1708
|
+
id="colorPicker"
|
|
1709
|
+
/>
|
|
1710
|
+
</button>
|
|
1576
1711
|
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1712
|
+
{#each HIGHLIGHT_COLOR_PALETTE as color}
|
|
1713
|
+
<button
|
|
1714
|
+
class="fl-color-swatch"
|
|
1715
|
+
class:active={$editor?.isActive("textStyle", {
|
|
1716
|
+
color: color,
|
|
1717
|
+
})}
|
|
1718
|
+
onclick={() => {
|
|
1719
|
+
$editor?.chain().focus().setHighlight({ color }).run();
|
|
1720
|
+
hideDropdown();
|
|
1721
|
+
}}
|
|
1722
|
+
style="background-color: {color};"
|
|
1723
|
+
aria-label={color}
|
|
1724
|
+
>
|
|
1725
|
+
</button>
|
|
1726
|
+
{/each}
|
|
1581
1727
|
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1728
|
+
<button
|
|
1729
|
+
class="fl-color-swatch unset-color"
|
|
1730
|
+
onclick={() => {
|
|
1731
|
+
$editor?.chain().focus().unsetColor().run();
|
|
1732
|
+
hideDropdown();
|
|
1733
|
+
}}
|
|
1734
|
+
style="background-color: #ffffff;"
|
|
1735
|
+
aria-label="Unset color"
|
|
1736
|
+
>
|
|
1737
|
+
</button>
|
|
1587
1738
|
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1739
|
+
{#if recentCustomColors.length > 0}
|
|
1740
|
+
{#each recentCustomColors as color}
|
|
1741
|
+
<button
|
|
1742
|
+
class="fl-color-swatch"
|
|
1743
|
+
class:active={$editor?.isActive("textStyle", {
|
|
1744
|
+
color: color,
|
|
1745
|
+
})}
|
|
1746
|
+
onclick={() => {
|
|
1747
|
+
$editor?.chain().focus().setHighlight({ color }).run();
|
|
1748
|
+
hideDropdown();
|
|
1749
|
+
}}
|
|
1750
|
+
style="background-color: {color};"
|
|
1751
|
+
aria-label={color}
|
|
1752
|
+
>
|
|
1753
|
+
</button>
|
|
1754
|
+
{/each}
|
|
1755
|
+
{:else}
|
|
1756
|
+
<button
|
|
1757
|
+
class="fl-color-swatch"
|
|
1758
|
+
style="outline: 1px dashed #ffffff66;background: transparent;"
|
|
1759
|
+
onclick={() => alert("Not implemented yet")}
|
|
1760
|
+
aria-label="Add new color"
|
|
1761
|
+
>
|
|
1762
|
+
<svg
|
|
1763
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
1764
|
+
fill="none"
|
|
1765
|
+
viewBox="0 0 24 24"
|
|
1766
|
+
stroke-width="1.5"
|
|
1767
|
+
stroke="currentColor"
|
|
1768
|
+
class="size-6"
|
|
1769
|
+
style="
|
|
1770
|
+
width: 11px;
|
|
1771
|
+
height: 11px;
|
|
1772
|
+
"
|
|
1773
|
+
>
|
|
1774
|
+
<path
|
|
1775
|
+
stroke-linecap="round"
|
|
1776
|
+
stroke-linejoin="round"
|
|
1777
|
+
d="M12 4.5v15m7.5-7.5h-15"
|
|
1778
|
+
></path>
|
|
1779
|
+
</svg>
|
|
1780
|
+
</button>
|
|
1592
1781
|
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1782
|
+
<button
|
|
1783
|
+
class="fl-color-swatch"
|
|
1784
|
+
style="outline: 1px dashed #ffffff66;background: transparent;"
|
|
1785
|
+
onclick={() => alert("Not implemented yet")}
|
|
1786
|
+
aria-label="Add new color"
|
|
1787
|
+
>
|
|
1788
|
+
<svg
|
|
1789
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
1790
|
+
fill="none"
|
|
1791
|
+
viewBox="0 0 24 24"
|
|
1792
|
+
stroke-width="1.5"
|
|
1793
|
+
stroke="currentColor"
|
|
1794
|
+
class="size-6"
|
|
1795
|
+
style="
|
|
1796
|
+
width: 11px;
|
|
1797
|
+
height: 11px;
|
|
1798
|
+
"
|
|
1799
|
+
>
|
|
1800
|
+
<path
|
|
1801
|
+
stroke-linecap="round"
|
|
1802
|
+
stroke-linejoin="round"
|
|
1803
|
+
d="M12 4.5v15m7.5-7.5h-15"
|
|
1804
|
+
></path>
|
|
1805
|
+
</svg>
|
|
1806
|
+
</button>
|
|
1807
|
+
{/if}
|
|
1808
|
+
</div>
|
|
1809
|
+
{:else if activeDropdownType === "line-height-dropdown"}
|
|
1810
|
+
<div class="fl-range-element">
|
|
1811
|
+
<span class="fl-range-element-value">
|
|
1812
|
+
{lineHeight.toFixed(2)}
|
|
1813
|
+
</span>
|
|
1814
|
+
<input oninput={handleRangeInput} type="range" min="0.5" max="4" step="0.01" bind:value={lineHeight}>
|
|
1815
|
+
</div>
|
|
1816
|
+
|
|
1817
|
+
{/if}
|
|
1818
|
+
</div>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Extension } from '@tiptap/core';
|
|
2
|
+
declare module '@tiptap/core' {
|
|
3
|
+
interface Commands<ReturnType> {
|
|
4
|
+
lineHeight: {
|
|
5
|
+
setNodeLineHeight: (lineHeight: string) => ReturnType;
|
|
6
|
+
unsetNodeLineHeight: () => ReturnType;
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export declare const NodeLineHeight: Extension<any, any>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Extension } from '@tiptap/core';
|
|
2
|
+
export const NodeLineHeight = Extension.create({
|
|
3
|
+
name: 'nodeLineHeight',
|
|
4
|
+
addOptions() {
|
|
5
|
+
return {
|
|
6
|
+
types: ['paragraph', 'heading'], // Aplica a párrafos y encabezados
|
|
7
|
+
defaultLineHeight: 'normal',
|
|
8
|
+
};
|
|
9
|
+
},
|
|
10
|
+
addGlobalAttributes() {
|
|
11
|
+
return [
|
|
12
|
+
{
|
|
13
|
+
types: this.options.types,
|
|
14
|
+
attributes: {
|
|
15
|
+
lineHeight: {
|
|
16
|
+
default: this.options.defaultLineHeight,
|
|
17
|
+
parseHTML: element => element.style.lineHeight || this.options.defaultLineHeight,
|
|
18
|
+
renderHTML: attributes => {
|
|
19
|
+
if (!attributes.lineHeight || attributes.lineHeight === this.options.defaultLineHeight) {
|
|
20
|
+
return {};
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
style: `line-height: ${attributes.lineHeight}`,
|
|
24
|
+
};
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
];
|
|
30
|
+
},
|
|
31
|
+
addCommands() {
|
|
32
|
+
return {
|
|
33
|
+
setNodeLineHeight: (lineHeight) => ({ commands }) => {
|
|
34
|
+
return this.options.types.every((type) => commands.updateAttributes(type, { lineHeight }));
|
|
35
|
+
},
|
|
36
|
+
unsetNodeLineHeight: () => ({ commands }) => {
|
|
37
|
+
return this.options.types.every((type) => commands.resetAttributes(type, 'lineHeight'));
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
},
|
|
41
|
+
});
|
package/dist/styles.css
CHANGED
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
--gray-2: #e0e0e0;
|
|
8
8
|
--gray-3: #c0c0c0;
|
|
9
9
|
--toolbar-gap: 5px;
|
|
10
|
-
--toolbar-padding:
|
|
10
|
+
--toolbar-padding: 6px;
|
|
11
|
+
--fl-editor-radius: 12px;
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
/* Basic editor styles */
|
|
@@ -182,6 +183,7 @@
|
|
|
182
183
|
min-height: 56px;
|
|
183
184
|
padding: 2rem;
|
|
184
185
|
background: #242424;
|
|
186
|
+
border-radius: 0 0 var(--fl-editor-radius) var(--fl-editor-radius);
|
|
185
187
|
}
|
|
186
188
|
|
|
187
189
|
.fl-toolbar-dropdown-panel {
|
|
@@ -211,3 +213,234 @@
|
|
|
211
213
|
background-color: #d4d6ff3c;
|
|
212
214
|
}
|
|
213
215
|
}
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
.flex-auto {
|
|
219
|
+
flex: auto;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.fl-rich-text {
|
|
223
|
+
display: flex;
|
|
224
|
+
flex-direction: column;
|
|
225
|
+
width: 100%;
|
|
226
|
+
height: 100%;
|
|
227
|
+
min-height: 56px;
|
|
228
|
+
background-color: var(--fl-bg-color, #242424);
|
|
229
|
+
color: var(--text-color);
|
|
230
|
+
box-sizing: border-box;
|
|
231
|
+
border-radius: var(--fl-editor-radius);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.fl-rich-text-toolbar {
|
|
235
|
+
display: flex;
|
|
236
|
+
flex-wrap: nowrap;
|
|
237
|
+
overflow: auto;
|
|
238
|
+
align-items: center;
|
|
239
|
+
gap: var(--toolbar-gap);
|
|
240
|
+
padding: var(--toolbar-padding);
|
|
241
|
+
position: sticky;
|
|
242
|
+
top: var(--sticky-position, 0);
|
|
243
|
+
z-index: var(--fl-toolbar-z-index, 10);
|
|
244
|
+
background: var(--fl-toolbar-bg, #242424);
|
|
245
|
+
border-radius: var(--fl-editor-radius);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.fl-rich-text-toolbar-group {
|
|
249
|
+
display: flex;
|
|
250
|
+
flex-wrap: nowrap;
|
|
251
|
+
gap: var(--toolbar-gap);
|
|
252
|
+
|
|
253
|
+
button {
|
|
254
|
+
padding: 8px 8px;
|
|
255
|
+
flex: auto;
|
|
256
|
+
border: none;
|
|
257
|
+
background: rgba(255, 255, 255, 0.1);
|
|
258
|
+
border-radius: 8px;
|
|
259
|
+
color: var(--text-color);
|
|
260
|
+
font-size: 14px;
|
|
261
|
+
display: flex;
|
|
262
|
+
align-items: center;
|
|
263
|
+
justify-content: center;
|
|
264
|
+
white-space: nowrap;
|
|
265
|
+
gap: 2px;
|
|
266
|
+
cursor: pointer;
|
|
267
|
+
line-height: 1;
|
|
268
|
+
min-height: 32px;
|
|
269
|
+
|
|
270
|
+
&.fl-font-size-button {
|
|
271
|
+
font-size: 14px;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
& svg {
|
|
275
|
+
width: 16px;
|
|
276
|
+
height: 16px;
|
|
277
|
+
|
|
278
|
+
&.toogle-dropdown-button-icon {
|
|
279
|
+
width: 7px;
|
|
280
|
+
height: 7px;
|
|
281
|
+
margin-left: 4px;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
&:disabled {
|
|
286
|
+
cursor: not-allowed;
|
|
287
|
+
opacity: 0.5;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
button.is-active {
|
|
293
|
+
background: var(--purple);
|
|
294
|
+
color: white;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
.special-box-icon {
|
|
298
|
+
width: 16px;
|
|
299
|
+
height: 16px;
|
|
300
|
+
display: flex;
|
|
301
|
+
align-items: center;
|
|
302
|
+
justify-content: center;
|
|
303
|
+
font-weight: 500;
|
|
304
|
+
border: none;
|
|
305
|
+
padding: 0px;
|
|
306
|
+
font-size: 12px;
|
|
307
|
+
border-radius: 3px;
|
|
308
|
+
outline: 1px dashed #818181;
|
|
309
|
+
scale: 1.1;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
.fl-button-color-text-popover {
|
|
313
|
+
color: inherit;
|
|
314
|
+
width: 16px;
|
|
315
|
+
height: 16px;
|
|
316
|
+
border-radius: 100%;
|
|
317
|
+
border: 1px solid #d7d7d78a;
|
|
318
|
+
box-sizing: border-box;
|
|
319
|
+
display: flex;
|
|
320
|
+
align-items: center;
|
|
321
|
+
justify-content: center;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
.fl-editor-color-palette {
|
|
325
|
+
width: 100%;
|
|
326
|
+
display: grid;
|
|
327
|
+
grid-template-columns: repeat(7, 1fr);
|
|
328
|
+
gap: 6px;
|
|
329
|
+
align-items: center;
|
|
330
|
+
|
|
331
|
+
.fl-color-swatch {
|
|
332
|
+
display: flex;
|
|
333
|
+
min-width: 17px;
|
|
334
|
+
border-radius: 100%;
|
|
335
|
+
align-items: center;
|
|
336
|
+
justify-content: center;
|
|
337
|
+
outline: 1px solid #83828238;
|
|
338
|
+
position: relative;
|
|
339
|
+
aspect-ratio: 1;
|
|
340
|
+
border: none;
|
|
341
|
+
padding: 0;
|
|
342
|
+
cursor: pointer;
|
|
343
|
+
|
|
344
|
+
&.active {
|
|
345
|
+
box-shadow: 0 0 0 2px #ffffff30;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
&.unset-color::after {
|
|
349
|
+
content: "";
|
|
350
|
+
width: 2px;
|
|
351
|
+
height: 100%;
|
|
352
|
+
background: red;
|
|
353
|
+
position: absolute;
|
|
354
|
+
transform: rotate(30deg) scaleY(1.2);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
input[type="color"] {
|
|
359
|
+
display: inline-flex;
|
|
360
|
+
vertical-align: bottom;
|
|
361
|
+
border: none;
|
|
362
|
+
border-radius: var(--radius);
|
|
363
|
+
padding: 0;
|
|
364
|
+
min-width: 17px;
|
|
365
|
+
max-height: 17px;
|
|
366
|
+
aspect-ratio: 1;
|
|
367
|
+
background: transparent;
|
|
368
|
+
width: auto;
|
|
369
|
+
border-radius: 100%;
|
|
370
|
+
|
|
371
|
+
&::-webkit-color-swatch-wrapper {
|
|
372
|
+
padding: 0;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
&::-webkit-color-swatch {
|
|
376
|
+
border: 0;
|
|
377
|
+
border-radius: var(--radius);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
&::-moz-color-swatch {
|
|
381
|
+
border: 0;
|
|
382
|
+
border-radius: var(--radius);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
.fl-color-picker-btn {
|
|
387
|
+
cursor: pointer;
|
|
388
|
+
position: relative;
|
|
389
|
+
background: conic-gradient(in hsl longer hue, red 0 100%);
|
|
390
|
+
|
|
391
|
+
& input {
|
|
392
|
+
opacity: 0;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
.fl-font-size-editor {
|
|
398
|
+
display: flex;
|
|
399
|
+
align-items: center;
|
|
400
|
+
gap: 4px;
|
|
401
|
+
padding: 0 8px;
|
|
402
|
+
border-radius: 8px;
|
|
403
|
+
background: rgba(255, 255, 255, 0.1);
|
|
404
|
+
|
|
405
|
+
& button {
|
|
406
|
+
background: transparent;
|
|
407
|
+
border: none;
|
|
408
|
+
display: flex;
|
|
409
|
+
align-items: center;
|
|
410
|
+
justify-content: center;
|
|
411
|
+
padding: 2px;
|
|
412
|
+
backdrop-filter: blur(5px);
|
|
413
|
+
border-radius: 8px;
|
|
414
|
+
cursor: pointer;
|
|
415
|
+
|
|
416
|
+
& svg {
|
|
417
|
+
width: 18px;
|
|
418
|
+
height: 18px;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
input {
|
|
423
|
+
width: 32px;
|
|
424
|
+
text-align: center;
|
|
425
|
+
border: none;
|
|
426
|
+
background: transparent;
|
|
427
|
+
color: var(--text-color);
|
|
428
|
+
font-size: 14px;
|
|
429
|
+
padding: 0;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
.fl-range-element {
|
|
434
|
+
display: flex;
|
|
435
|
+
align-items: center;
|
|
436
|
+
gap: 8px;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
.fl-range-element input {
|
|
440
|
+
accent-color: #ffffff;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
.fl-range-element-value {
|
|
444
|
+
padding: 0 6px;
|
|
445
|
+
font-size: 14px;
|
|
446
|
+
}
|