@flexiui/svelte-rich-text 0.0.19 → 0.0.21
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 +418 -193
- 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,48 @@
|
|
|
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
|
+
type="button"
|
|
829
|
+
aria-label="Decrease font size"
|
|
830
|
+
onclick={decrementFontSize}
|
|
831
|
+
class="fl-font-size-editor-button">-</button
|
|
832
|
+
>
|
|
833
|
+
<input type="text" bind:value={fontSize} />
|
|
834
|
+
<button
|
|
835
|
+
type="button"
|
|
836
|
+
aria-label="Increase font size"
|
|
837
|
+
onclick={incrementFontSize}
|
|
838
|
+
class="fl-font-size-editor-button">+</button
|
|
839
|
+
>
|
|
840
|
+
</div>
|
|
841
|
+
</div>
|
|
842
|
+
|
|
843
|
+
<!-- Line height -->
|
|
844
|
+
<div role="group" class="fl-rich-text-toolbar-group">
|
|
845
|
+
<button
|
|
846
|
+
class="fl-font-size-button"
|
|
847
|
+
aria-label="Line height"
|
|
848
|
+
type="button"
|
|
849
|
+
onclick={(e) => toogleDropdown(e.currentTarget, "line-height-dropdown")}
|
|
850
|
+
>
|
|
851
|
+
<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>
|
|
852
|
+
|
|
853
|
+
<svg
|
|
854
|
+
class="toogle-dropdown-button-icon"
|
|
855
|
+
aria-hidden="true"
|
|
856
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
857
|
+
fill="none"
|
|
858
|
+
viewBox="0 0 10 6"
|
|
859
|
+
>
|
|
860
|
+
<use href="#dropdown-arrow"></use>
|
|
861
|
+
</svg>
|
|
862
|
+
</button>
|
|
863
|
+
</div>
|
|
864
|
+
|
|
865
|
+
<!-- Bold, Italic, Underline, etc. -->
|
|
683
866
|
<div role="group" class="fl-rich-text-toolbar-group">
|
|
684
867
|
<button
|
|
685
868
|
type="button"
|
|
@@ -800,7 +983,9 @@
|
|
|
800
983
|
</button>
|
|
801
984
|
</div>
|
|
802
985
|
|
|
986
|
+
<!-- Link, special box, horizontal rule, etc. -->
|
|
803
987
|
<div role="group" class="fl-rich-text-toolbar-group">
|
|
988
|
+
<!-- Link -->
|
|
804
989
|
<button
|
|
805
990
|
type="button"
|
|
806
991
|
onclick={() => setLink()}
|
|
@@ -825,6 +1010,7 @@
|
|
|
825
1010
|
>
|
|
826
1011
|
</button>
|
|
827
1012
|
|
|
1013
|
+
<!-- Special box -->
|
|
828
1014
|
<button
|
|
829
1015
|
class="fl-bubble-menu-mark-button"
|
|
830
1016
|
class:is-active={$editor?.isActive("specialBox")}
|
|
@@ -835,6 +1021,7 @@
|
|
|
835
1021
|
<span class="special-box-icon">A</span>
|
|
836
1022
|
</button>
|
|
837
1023
|
|
|
1024
|
+
<!-- Horizontal rule -->
|
|
838
1025
|
<button
|
|
839
1026
|
type="button"
|
|
840
1027
|
onclick={() => $editor.chain().focus().setHorizontalRule().run()}
|
|
@@ -855,6 +1042,7 @@
|
|
|
855
1042
|
>
|
|
856
1043
|
</button>
|
|
857
1044
|
|
|
1045
|
+
<!-- Hard break -->
|
|
858
1046
|
<button
|
|
859
1047
|
type="button"
|
|
860
1048
|
onclick={() => $editor.chain().focus().setHardBreak().run()}
|
|
@@ -877,10 +1065,12 @@
|
|
|
877
1065
|
>
|
|
878
1066
|
</button>
|
|
879
1067
|
|
|
1068
|
+
<!-- Text color dropdown -->
|
|
880
1069
|
<button
|
|
881
1070
|
aria-label="Toggle text color dropdown"
|
|
882
1071
|
type="button"
|
|
883
|
-
onclick={(e) =>
|
|
1072
|
+
onclick={(e) =>
|
|
1073
|
+
toogleDropdown(e.currentTarget, "text-color-dropdown")}
|
|
884
1074
|
>
|
|
885
1075
|
<span
|
|
886
1076
|
class="fl-button-color-text-popover"
|
|
@@ -893,18 +1083,63 @@
|
|
|
893
1083
|
aria-hidden="true"
|
|
894
1084
|
xmlns="http://www.w3.org/2000/svg"
|
|
895
1085
|
fill="none"
|
|
896
|
-
viewBox="0 0
|
|
1086
|
+
viewBox="0 0 20 12"
|
|
1087
|
+
>
|
|
1088
|
+
<defs>
|
|
1089
|
+
<symbol id="dropdown-arrow" viewBox="0 0 10 6" fill="none">
|
|
1090
|
+
<path
|
|
1091
|
+
stroke="currentColor"
|
|
1092
|
+
stroke-linecap="round"
|
|
1093
|
+
stroke-linejoin="round"
|
|
1094
|
+
stroke-width="2"
|
|
1095
|
+
d="m1 1 4 4 4-4"
|
|
1096
|
+
></path>
|
|
1097
|
+
</symbol>
|
|
1098
|
+
</defs>
|
|
1099
|
+
<use href="#dropdown-arrow"></use>
|
|
1100
|
+
</svg>
|
|
1101
|
+
</button>
|
|
1102
|
+
|
|
1103
|
+
<!-- Highlight dropdown -->
|
|
1104
|
+
<button
|
|
1105
|
+
class="fl-bubble-menu-mark-button"
|
|
1106
|
+
type="button"
|
|
1107
|
+
aria-label="Highlight"
|
|
1108
|
+
onclick={(e) => toogleDropdown(e.currentTarget, "highlight")}
|
|
1109
|
+
>
|
|
1110
|
+
<svg
|
|
1111
|
+
width="24"
|
|
1112
|
+
height="24"
|
|
1113
|
+
class="tiptap-button-icon"
|
|
1114
|
+
viewBox="0 0 24 24"
|
|
1115
|
+
fill="currentColor"
|
|
1116
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
897
1117
|
><path
|
|
1118
|
+
fill-rule="evenodd"
|
|
1119
|
+
clip-rule="evenodd"
|
|
1120
|
+
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"
|
|
1121
|
+
fill="currentColor"
|
|
1122
|
+
></path>
|
|
1123
|
+
</svg>
|
|
1124
|
+
<svg
|
|
1125
|
+
class="toogle-dropdown-button-icon"
|
|
1126
|
+
aria-hidden="true"
|
|
1127
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
1128
|
+
fill="none"
|
|
1129
|
+
viewBox="0 0 10 6"
|
|
1130
|
+
>
|
|
1131
|
+
<path
|
|
898
1132
|
stroke="currentColor"
|
|
899
1133
|
stroke-linecap="round"
|
|
900
1134
|
stroke-linejoin="round"
|
|
901
1135
|
stroke-width="2"
|
|
902
1136
|
d="m1 1 4 4 4-4"
|
|
903
|
-
></path
|
|
904
|
-
>
|
|
1137
|
+
></path>
|
|
1138
|
+
</svg>
|
|
905
1139
|
</button>
|
|
906
1140
|
</div>
|
|
907
1141
|
|
|
1142
|
+
<!-- Inline math -->
|
|
908
1143
|
<div role="group" class="fl-rich-text-toolbar-group">
|
|
909
1144
|
<button
|
|
910
1145
|
type="button"
|
|
@@ -929,7 +1164,9 @@
|
|
|
929
1164
|
</button>
|
|
930
1165
|
</div>
|
|
931
1166
|
|
|
1167
|
+
<!-- Text align, clear formatting, clear nodes -->
|
|
932
1168
|
<div role="group" class="fl-rich-text-toolbar-group">
|
|
1169
|
+
<!-- Text align left -->
|
|
933
1170
|
<button
|
|
934
1171
|
type="button"
|
|
935
1172
|
onclick={() => $editor.chain().focus().toggleTextAlign("left").run()}
|
|
@@ -951,6 +1188,7 @@
|
|
|
951
1188
|
>
|
|
952
1189
|
</button>
|
|
953
1190
|
|
|
1191
|
+
<!-- Text align center -->
|
|
954
1192
|
<button
|
|
955
1193
|
type="button"
|
|
956
1194
|
onclick={() =>
|
|
@@ -973,6 +1211,7 @@
|
|
|
973
1211
|
>
|
|
974
1212
|
</button>
|
|
975
1213
|
|
|
1214
|
+
<!-- Text align right -->
|
|
976
1215
|
<button
|
|
977
1216
|
type="button"
|
|
978
1217
|
onclick={() => $editor.chain().focus().toggleTextAlign("right").run()}
|
|
@@ -994,6 +1233,7 @@
|
|
|
994
1233
|
>
|
|
995
1234
|
</button>
|
|
996
1235
|
|
|
1236
|
+
<!-- Clear formatting -->
|
|
997
1237
|
<button
|
|
998
1238
|
aria-label="Clear formatting"
|
|
999
1239
|
type="button"
|
|
@@ -1018,6 +1258,7 @@
|
|
|
1018
1258
|
>
|
|
1019
1259
|
</button>
|
|
1020
1260
|
|
|
1261
|
+
<!-- Clear nodes -->
|
|
1021
1262
|
<button
|
|
1022
1263
|
type="button"
|
|
1023
1264
|
onclick={() => $editor.chain().focus().clearNodes().run()}
|
|
@@ -1304,7 +1545,10 @@
|
|
|
1304
1545
|
onblur={(event: any) => {
|
|
1305
1546
|
const inclued = recentCustomColors.includes(event?.target?.value);
|
|
1306
1547
|
if (!inclued) {
|
|
1307
|
-
recentCustomColors = [
|
|
1548
|
+
recentCustomColors = [
|
|
1549
|
+
...recentCustomColors,
|
|
1550
|
+
event?.target?.value,
|
|
1551
|
+
];
|
|
1308
1552
|
}
|
|
1309
1553
|
$editor.chain().focus().setColor(event?.target?.value).run();
|
|
1310
1554
|
hideDropdown();
|
|
@@ -1312,7 +1556,10 @@
|
|
|
1312
1556
|
onchange={(event: any) => {
|
|
1313
1557
|
const inclued = recentCustomColors.includes(event?.target?.value);
|
|
1314
1558
|
if (!inclued) {
|
|
1315
|
-
recentCustomColors = [
|
|
1559
|
+
recentCustomColors = [
|
|
1560
|
+
...recentCustomColors,
|
|
1561
|
+
event?.target?.value,
|
|
1562
|
+
];
|
|
1316
1563
|
}
|
|
1317
1564
|
$editor.chain().focus().setColor(event?.target?.value).run();
|
|
1318
1565
|
hideDropdown();
|
|
@@ -1420,178 +1667,156 @@
|
|
|
1420
1667
|
</button>
|
|
1421
1668
|
{/if}
|
|
1422
1669
|
</div>
|
|
1423
|
-
{
|
|
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
|
-
display: flex;
|
|
1456
|
-
flex-wrap: nowrap;
|
|
1457
|
-
gap: var(--toolbar-gap);
|
|
1458
|
-
|
|
1459
|
-
button {
|
|
1460
|
-
padding: 8px 8px;
|
|
1461
|
-
flex: auto;
|
|
1462
|
-
border: none;
|
|
1463
|
-
background: rgba(255, 255, 255, 0.1);
|
|
1464
|
-
border-radius: 8px;
|
|
1465
|
-
color: var(--text-color);
|
|
1466
|
-
font-size: 14px;
|
|
1467
|
-
display: flex;
|
|
1468
|
-
align-items: center;
|
|
1469
|
-
justify-content: center;
|
|
1470
|
-
white-space: nowrap;
|
|
1471
|
-
gap: 2px;
|
|
1472
|
-
cursor: pointer;
|
|
1473
|
-
line-height: 1;
|
|
1474
|
-
|
|
1475
|
-
& svg {
|
|
1476
|
-
width: 16px;
|
|
1477
|
-
height: 16px;
|
|
1478
|
-
|
|
1479
|
-
&.toogle-dropdown-button-icon {
|
|
1480
|
-
width: 7px;
|
|
1481
|
-
height: 7px;
|
|
1482
|
-
margin-left: 4px;
|
|
1483
|
-
}
|
|
1484
|
-
}
|
|
1485
|
-
|
|
1486
|
-
&:disabled {
|
|
1487
|
-
cursor: not-allowed;
|
|
1488
|
-
opacity: 0.5;
|
|
1489
|
-
}
|
|
1490
|
-
}
|
|
1491
|
-
}
|
|
1492
|
-
|
|
1493
|
-
button.is-active {
|
|
1494
|
-
background: var(--purple);
|
|
1495
|
-
color: white;
|
|
1496
|
-
}
|
|
1497
|
-
|
|
1498
|
-
.special-box-icon {
|
|
1499
|
-
width: 16px;
|
|
1500
|
-
height: 16px;
|
|
1501
|
-
display: flex;
|
|
1502
|
-
align-items: center;
|
|
1503
|
-
justify-content: center;
|
|
1504
|
-
font-weight: 500;
|
|
1505
|
-
border: none;
|
|
1506
|
-
padding: 0px;
|
|
1507
|
-
font-size: 12px;
|
|
1508
|
-
border-radius: 3px;
|
|
1509
|
-
outline: 1px dashed #818181;
|
|
1510
|
-
scale: 1.1;
|
|
1511
|
-
}
|
|
1512
|
-
|
|
1513
|
-
.fl-button-color-text-popover {
|
|
1514
|
-
color: inherit;
|
|
1515
|
-
width: 16px;
|
|
1516
|
-
height: 16px;
|
|
1517
|
-
border-radius: 100%;
|
|
1518
|
-
border: 1px solid #d7d7d78a;
|
|
1519
|
-
box-sizing: border-box;
|
|
1520
|
-
display: flex;
|
|
1521
|
-
align-items: center;
|
|
1522
|
-
justify-content: center;
|
|
1523
|
-
}
|
|
1524
|
-
|
|
1525
|
-
.fl-editor-color-palette {
|
|
1526
|
-
width: 100%;
|
|
1527
|
-
display: grid;
|
|
1528
|
-
grid-template-columns: repeat(7, 1fr);
|
|
1529
|
-
gap: 6px;
|
|
1530
|
-
align-items: center;
|
|
1531
|
-
|
|
1532
|
-
.fl-color-swatch {
|
|
1533
|
-
display: flex;
|
|
1534
|
-
min-width: 17px;
|
|
1535
|
-
border-radius: 100%;
|
|
1536
|
-
align-items: center;
|
|
1537
|
-
justify-content: center;
|
|
1538
|
-
outline: 1px solid #83828238;
|
|
1539
|
-
position: relative;
|
|
1540
|
-
aspect-ratio: 1;
|
|
1541
|
-
border: none;
|
|
1542
|
-
padding: 0;
|
|
1543
|
-
cursor: pointer;
|
|
1544
|
-
|
|
1545
|
-
&.active {
|
|
1546
|
-
box-shadow: 0 0 0 2px #ffffff30;
|
|
1547
|
-
}
|
|
1548
|
-
|
|
1549
|
-
&.unset-color::after {
|
|
1550
|
-
content: "";
|
|
1551
|
-
width: 2px;
|
|
1552
|
-
height: 100%;
|
|
1553
|
-
background: red;
|
|
1554
|
-
position: absolute;
|
|
1555
|
-
transform: rotate(30deg) scaleY(1.2);
|
|
1556
|
-
}
|
|
1557
|
-
}
|
|
1670
|
+
{:else if activeDropdownType === "highlight"}
|
|
1671
|
+
<div class="fl-editor-color-palette">
|
|
1672
|
+
<button
|
|
1673
|
+
class="fl-color-swatch fl-color-picker-btn"
|
|
1674
|
+
aria-label="Highlight color picker"
|
|
1675
|
+
type="button"
|
|
1676
|
+
>
|
|
1677
|
+
<input
|
|
1678
|
+
type="color"
|
|
1679
|
+
onblur={(event: any) => {
|
|
1680
|
+
const inclued = recentCustomColors.includes(event?.target?.value);
|
|
1681
|
+
if (!inclued) {
|
|
1682
|
+
recentCustomColors = [
|
|
1683
|
+
...recentCustomColors,
|
|
1684
|
+
event?.target?.value,
|
|
1685
|
+
];
|
|
1686
|
+
}
|
|
1687
|
+
$editor
|
|
1688
|
+
.chain()
|
|
1689
|
+
.focus()
|
|
1690
|
+
.setHighlight({ color: event?.target?.value })
|
|
1691
|
+
.run();
|
|
1692
|
+
hideDropdown();
|
|
1693
|
+
}}
|
|
1694
|
+
onchange={(event: any) => {
|
|
1695
|
+
const inclued = recentCustomColors.includes(event?.target?.value);
|
|
1696
|
+
if (!inclued) {
|
|
1697
|
+
recentCustomColors = [
|
|
1698
|
+
...recentCustomColors,
|
|
1699
|
+
event?.target?.value,
|
|
1700
|
+
];
|
|
1701
|
+
}
|
|
1558
1702
|
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
&::-webkit-color-swatch-wrapper {
|
|
1573
|
-
padding: 0;
|
|
1574
|
-
}
|
|
1703
|
+
$editor
|
|
1704
|
+
.chain()
|
|
1705
|
+
.focus()
|
|
1706
|
+
.setHighlight({ color: event?.target?.value })
|
|
1707
|
+
.run();
|
|
1708
|
+
hideDropdown();
|
|
1709
|
+
}}
|
|
1710
|
+
value={rgbToHex($editor?.getAttributes("textStyle")?.color)}
|
|
1711
|
+
data-testid="setHiglight"
|
|
1712
|
+
id="colorPicker"
|
|
1713
|
+
/>
|
|
1714
|
+
</button>
|
|
1575
1715
|
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1716
|
+
{#each HIGHLIGHT_COLOR_PALETTE as color}
|
|
1717
|
+
<button
|
|
1718
|
+
class="fl-color-swatch"
|
|
1719
|
+
class:active={$editor?.isActive("textStyle", {
|
|
1720
|
+
color: color,
|
|
1721
|
+
})}
|
|
1722
|
+
onclick={() => {
|
|
1723
|
+
$editor?.chain().focus().setHighlight({ color }).run();
|
|
1724
|
+
hideDropdown();
|
|
1725
|
+
}}
|
|
1726
|
+
style="background-color: {color};"
|
|
1727
|
+
aria-label={color}
|
|
1728
|
+
>
|
|
1729
|
+
</button>
|
|
1730
|
+
{/each}
|
|
1580
1731
|
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1732
|
+
<button
|
|
1733
|
+
class="fl-color-swatch unset-color"
|
|
1734
|
+
onclick={() => {
|
|
1735
|
+
$editor?.chain().focus().unsetColor().run();
|
|
1736
|
+
hideDropdown();
|
|
1737
|
+
}}
|
|
1738
|
+
style="background-color: #ffffff;"
|
|
1739
|
+
aria-label="Unset color"
|
|
1740
|
+
>
|
|
1741
|
+
</button>
|
|
1586
1742
|
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1743
|
+
{#if recentCustomColors.length > 0}
|
|
1744
|
+
{#each recentCustomColors as color}
|
|
1745
|
+
<button
|
|
1746
|
+
class="fl-color-swatch"
|
|
1747
|
+
class:active={$editor?.isActive("textStyle", {
|
|
1748
|
+
color: color,
|
|
1749
|
+
})}
|
|
1750
|
+
onclick={() => {
|
|
1751
|
+
$editor?.chain().focus().setHighlight({ color }).run();
|
|
1752
|
+
hideDropdown();
|
|
1753
|
+
}}
|
|
1754
|
+
style="background-color: {color};"
|
|
1755
|
+
aria-label={color}
|
|
1756
|
+
>
|
|
1757
|
+
</button>
|
|
1758
|
+
{/each}
|
|
1759
|
+
{:else}
|
|
1760
|
+
<button
|
|
1761
|
+
class="fl-color-swatch"
|
|
1762
|
+
style="outline: 1px dashed #ffffff66;background: transparent;"
|
|
1763
|
+
onclick={() => alert("Not implemented yet")}
|
|
1764
|
+
aria-label="Add new color"
|
|
1765
|
+
>
|
|
1766
|
+
<svg
|
|
1767
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
1768
|
+
fill="none"
|
|
1769
|
+
viewBox="0 0 24 24"
|
|
1770
|
+
stroke-width="1.5"
|
|
1771
|
+
stroke="currentColor"
|
|
1772
|
+
class="size-6"
|
|
1773
|
+
style="
|
|
1774
|
+
width: 11px;
|
|
1775
|
+
height: 11px;
|
|
1776
|
+
"
|
|
1777
|
+
>
|
|
1778
|
+
<path
|
|
1779
|
+
stroke-linecap="round"
|
|
1780
|
+
stroke-linejoin="round"
|
|
1781
|
+
d="M12 4.5v15m7.5-7.5h-15"
|
|
1782
|
+
></path>
|
|
1783
|
+
</svg>
|
|
1784
|
+
</button>
|
|
1591
1785
|
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1786
|
+
<button
|
|
1787
|
+
class="fl-color-swatch"
|
|
1788
|
+
style="outline: 1px dashed #ffffff66;background: transparent;"
|
|
1789
|
+
onclick={() => alert("Not implemented yet")}
|
|
1790
|
+
aria-label="Add new color"
|
|
1791
|
+
>
|
|
1792
|
+
<svg
|
|
1793
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
1794
|
+
fill="none"
|
|
1795
|
+
viewBox="0 0 24 24"
|
|
1796
|
+
stroke-width="1.5"
|
|
1797
|
+
stroke="currentColor"
|
|
1798
|
+
class="size-6"
|
|
1799
|
+
style="
|
|
1800
|
+
width: 11px;
|
|
1801
|
+
height: 11px;
|
|
1802
|
+
"
|
|
1803
|
+
>
|
|
1804
|
+
<path
|
|
1805
|
+
stroke-linecap="round"
|
|
1806
|
+
stroke-linejoin="round"
|
|
1807
|
+
d="M12 4.5v15m7.5-7.5h-15"
|
|
1808
|
+
></path>
|
|
1809
|
+
</svg>
|
|
1810
|
+
</button>
|
|
1811
|
+
{/if}
|
|
1812
|
+
</div>
|
|
1813
|
+
{:else if activeDropdownType === "line-height-dropdown"}
|
|
1814
|
+
<div class="fl-range-element">
|
|
1815
|
+
<span class="fl-range-element-value">
|
|
1816
|
+
{lineHeight.toFixed(2)}
|
|
1817
|
+
</span>
|
|
1818
|
+
<input oninput={handleRangeInput} type="range" min="0.5" max="4" step="0.01" bind:value={lineHeight}>
|
|
1819
|
+
</div>
|
|
1820
|
+
|
|
1821
|
+
{/if}
|
|
1822
|
+
</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
|
+
}
|