@flexiui/svelte-rich-text 0.0.50 → 0.0.51

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.
@@ -11,10 +11,16 @@
11
11
  import { onMount, onDestroy } from "svelte";
12
12
  import type { Readable } from "svelte/store";
13
13
 
14
- import { createEditor, Editor, EditorContent } from "svelte-tiptap";
14
+ import {
15
+ createEditor,
16
+ Editor,
17
+ EditorContent,
18
+ BubbleMenu,
19
+ } from "svelte-tiptap";
15
20
 
16
21
  import { computePosition, offset, autoUpdate } from "@floating-ui/dom";
17
22
  import { getRichTextExtensions } from "./getExtensions";
23
+ import { CellSelection } from "prosemirror-tables";
18
24
 
19
25
  declare interface Props {
20
26
  id?: string;
@@ -37,6 +43,7 @@
37
43
  onPaste?: (params: any) => void;
38
44
  };
39
45
  config?: {
46
+ editorAccentColor?: string;
40
47
  editorBgColor?: string;
41
48
  editorRadius?: string;
42
49
  toolbarStickyPosition?: number;
@@ -50,6 +57,7 @@
50
57
  docMarginInline?: string;
51
58
  docMarginBlock?: string;
52
59
  docRadius?: string;
60
+ buttonStyle?: "accent-soft" | "accent-solid";
53
61
  };
54
62
  }
55
63
 
@@ -78,6 +86,7 @@
78
86
 
79
87
  let editor = $state() as Readable<Editor>;
80
88
  const defaultEditorConfig = {
89
+ editorAccentColor: "var(--purple)",
81
90
  editorBgColor: "transparent",
82
91
  editorRadius: "12px",
83
92
  toolbarStickyPosition: 0,
@@ -91,6 +100,7 @@
91
100
  docMarginInline: "auto",
92
101
  docMarginBlock: "2rem",
93
102
  docRadius: "0",
103
+ buttonStyle: "accent-solid",
94
104
  };
95
105
 
96
106
  let editorConfig = $state({
@@ -98,8 +108,13 @@
98
108
  ...(config ?? {}),
99
109
  });
100
110
 
111
+ let bubbleOffset =
112
+ $editor?.storage.tableCell.customTableSelection === "column" ? 18 : 8;
113
+ let imageUrlInputEl: HTMLInputElement = $state(null) as HTMLInputElement;
114
+ let imageUrlInputValue: string = $state(null);
115
+
101
116
  const extensions = getRichTextExtensions({
102
- editable: true,
117
+ editable: true,
103
118
  customExtensions: [
104
119
  Mathematics.configure({
105
120
  inlineOptions: {
@@ -132,8 +147,8 @@
132
147
  },
133
148
  },
134
149
  }),
135
- ...customExtensions,
136
- ]
150
+ ...customExtensions,
151
+ ],
137
152
  });
138
153
 
139
154
  let tooltipVisible = $state(false);
@@ -142,13 +157,16 @@
142
157
  let tooltip: HTMLDivElement = null as HTMLDivElement;
143
158
  let cleanup: () => void;
144
159
  let currentTriggerEl: HTMLElement | null = null;
160
+ let textColorDropdownTriggerEl: HTMLElement | null = $state(
161
+ null
162
+ ) as HTMLElement;
145
163
  let activeDropdownType = $state(null);
146
164
  let enterPressed = $state(false);
147
165
  let fontSize = $state(16) as number;
148
166
  let lineHeight = $state(null) as number;
149
167
 
150
168
  const TEXT_COLOR_PALETTE = [
151
- "rgb(94, 23, 235)",
169
+ editorConfig.editorAccentColor,
152
170
  "rgb(183, 147, 255)",
153
171
  "rgb(255, 147, 223)",
154
172
  // "rgb(251, 109, 250)",
@@ -162,7 +180,7 @@
162
180
  ];
163
181
 
164
182
  const HIGHLIGHT_COLOR_PALETTE = [
165
- "rgb(94, 23, 235)",
183
+ editorConfig.editorAccentColor,
166
184
  "rgb(183, 147, 255)",
167
185
  "rgb(255, 147, 223)",
168
186
  // "rgb(251, 109, 250)",
@@ -223,6 +241,10 @@
223
241
  });
224
242
  }
225
243
 
244
+ // función para saber si hay una selección de celdas
245
+ const isCellSelection = () =>
246
+ $editor && $editor.state.selection instanceof CellSelection;
247
+
226
248
  onMount(() => {
227
249
  editor = createEditor({
228
250
  extensions,
@@ -525,6 +547,7 @@
525
547
  class="fl-rich-text {className}"
526
548
  class:editable
527
549
  style="
550
+ --fl-editor-accent-color: {editorConfig.editorAccentColor};
528
551
  --fl-editor-radius: {editorConfig.editorRadius};
529
552
  --fl-editor-bg: {editorConfig.editorBgColor};
530
553
  --fl-toolbar-sticky-position: {editorConfig.toolbarStickyPosition}px;
@@ -542,6 +565,7 @@
542
565
  >
543
566
  {#if editor}
544
567
  <header class="fl-rich-text-toolbar">
568
+
545
569
  <!-- Undo/Redo -->
546
570
  <div role="group" class="fl-rich-text-toolbar-group">
547
571
  <button
@@ -595,19 +619,19 @@
595
619
  <button
596
620
  type="button"
597
621
  onclick={(e) => toogleDropdown(e.currentTarget, "headings-dropdown")}
598
- class:is-active={$editor.isActive("heading") || $editor.isActive("h1")}
622
+ class:is-active={$editor.isActive("heading") ||
623
+ $editor.isActive("h1")}
624
+ class:accent-soft={editorConfig.buttonStyle === "accent-soft"}
599
625
  aria-label="Heading"
600
626
  >
601
-
602
-
603
627
  {#if $editor.isActive("heading")}
604
- {#each HEADINGS as heading}
605
- {#if $editor.isActive("heading", { level: Number(heading.level) })}
606
- {@html heading.icon}
607
- {/if}
608
- {/each}
628
+ {#each HEADINGS as heading}
629
+ {#if $editor.isActive( "heading", { level: Number(heading.level) } )}
630
+ {@html heading.icon}
631
+ {/if}
632
+ {/each}
609
633
  {:else if $editor.isActive("h1")}
610
- {@html HEADINGS[0].icon}
634
+ {@html HEADINGS[0].icon}
611
635
  {/if}
612
636
 
613
637
  {#if !$editor.isActive("heading") && !$editor.isActive("h1")}
@@ -630,8 +654,19 @@
630
654
  aria-hidden="true"
631
655
  xmlns="http://www.w3.org/2000/svg"
632
656
  fill="none"
633
- viewBox="0 0 10 6"
657
+ viewBox="0 0 20 12"
634
658
  >
659
+ <defs>
660
+ <symbol id="dropdown-arrow" viewBox="0 0 10 6" fill="none">
661
+ <path
662
+ stroke="currentColor"
663
+ stroke-linecap="round"
664
+ stroke-linejoin="round"
665
+ stroke-width="2"
666
+ d="m1 1 4 4 4-4"
667
+ ></path>
668
+ </symbol>
669
+ </defs>
635
670
  <use href="#dropdown-arrow"></use>
636
671
  </svg>
637
672
  </button>
@@ -644,6 +679,7 @@
644
679
  class:is-active={$editor.isActive("bulletList") ||
645
680
  $editor.isActive("orderedList") ||
646
681
  $editor.isActive("taskList")}
682
+ class:accent-soft={editorConfig.buttonStyle === "accent-soft"}
647
683
  >
648
684
  {#if $editor.isActive("bulletList")}
649
685
  <svg
@@ -822,6 +858,7 @@
822
858
  type="button"
823
859
  onclick={() => $editor.chain().focus().toggleCodeBlock().run()}
824
860
  class={$editor.isActive("codeBlock") ? "is-active" : ""}
861
+ class:accent-soft={editorConfig.buttonStyle === "accent-soft"}
825
862
  >
826
863
  <svg
827
864
  width="24"
@@ -855,6 +892,7 @@
855
892
  type="button"
856
893
  onclick={() => $editor.chain().focus().toggleBlockquote().run()}
857
894
  class={$editor.isActive("blockquote") ? "is-active" : ""}
895
+ class:accent-soft={editorConfig.buttonStyle === "accent-soft"}
858
896
  >
859
897
  <svg
860
898
  width="15"
@@ -962,8 +1000,8 @@
962
1000
  </button>
963
1001
  </div>
964
1002
 
965
- <!-- Bold, Italic, Underline, etc. -->
966
- <div role="group" class="fl-rich-text-toolbar-group">
1003
+ <!-- Bold, Italic, Underline, Strike, Code, Link -->
1004
+ <!-- <div role="group" class="fl-rich-text-toolbar-group">
967
1005
  <button
968
1006
  type="button"
969
1007
  onclick={() => $editor.chain().focus().toggleBold().run()}
@@ -1011,7 +1049,7 @@
1011
1049
  <button
1012
1050
  type="button"
1013
1051
  onclick={() => $editor.chain().focus().toggleUnderline().run()}
1014
- disabled={!$editor.can().chain().focus().toggleStrike().run()}
1052
+ disabled={!$editor.can().chain().focus().toggleUnderline().run()}
1015
1053
  class={$editor.isActive("underline") ? "is-active" : ""}
1016
1054
  aria-label="Underline"
1017
1055
  >
@@ -1081,11 +1119,7 @@
1081
1119
  ></path></svg
1082
1120
  >
1083
1121
  </button>
1084
- </div>
1085
1122
 
1086
- <!-- Link, special box, horizontal rule, etc. -->
1087
- <div role="group" class="fl-rich-text-toolbar-group">
1088
- <!-- Link -->
1089
1123
  <button
1090
1124
  type="button"
1091
1125
  onclick={() => setLink()}
@@ -1109,11 +1143,15 @@
1109
1143
  ></path></svg
1110
1144
  >
1111
1145
  </button>
1146
+ </div> -->
1112
1147
 
1148
+ <!-- Special box, horizontal rule, Hard break -->
1149
+ <div role="group" class="fl-rich-text-toolbar-group">
1113
1150
  <!-- Special box -->
1114
1151
  <button
1115
1152
  class="fl-bubble-menu-mark-button"
1116
1153
  class:is-active={$editor?.isActive("specialBox")}
1154
+ class:accent-soft={editorConfig.buttonStyle === "accent-soft"}
1117
1155
  onclick={toggleSpecialBox}
1118
1156
  type="button"
1119
1157
  aria-label="Special Box"
@@ -1164,8 +1202,10 @@
1164
1202
  ></path></svg
1165
1203
  >
1166
1204
  </button>
1205
+ </div>
1167
1206
 
1168
- <!-- Text color dropdown -->
1207
+ <!-- Text color & highlight -->
1208
+ <!-- <div role="group" class="fl-rich-text-toolbar-group">
1169
1209
  <button
1170
1210
  aria-label="Toggle text color dropdown"
1171
1211
  type="button"
@@ -1185,22 +1225,10 @@
1185
1225
  fill="none"
1186
1226
  viewBox="0 0 20 12"
1187
1227
  >
1188
- <defs>
1189
- <symbol id="dropdown-arrow" viewBox="0 0 10 6" fill="none">
1190
- <path
1191
- stroke="currentColor"
1192
- stroke-linecap="round"
1193
- stroke-linejoin="round"
1194
- stroke-width="2"
1195
- d="m1 1 4 4 4-4"
1196
- ></path>
1197
- </symbol>
1198
- </defs>
1199
1228
  <use href="#dropdown-arrow"></use>
1200
1229
  </svg>
1201
1230
  </button>
1202
1231
 
1203
- <!-- Highlight dropdown -->
1204
1232
  <button
1205
1233
  class="fl-bubble-menu-mark-button"
1206
1234
  type="button"
@@ -1237,7 +1265,7 @@
1237
1265
  ></path>
1238
1266
  </svg>
1239
1267
  </button>
1240
- </div>
1268
+ </div> -->
1241
1269
 
1242
1270
  <!-- Inline math -->
1243
1271
  <div role="group" class="fl-rich-text-toolbar-group">
@@ -1272,6 +1300,7 @@
1272
1300
  onclick={addImage}
1273
1301
  aria-label="Image"
1274
1302
  class:is-active={$editor.isActive("image")}
1303
+ class:accent-soft={editorConfig.buttonStyle === "accent-soft"}
1275
1304
  >
1276
1305
  <svg
1277
1306
  xmlns="http://www.w3.org/2000/svg"
@@ -1291,8 +1320,19 @@
1291
1320
  onclick={addAudio}
1292
1321
  aria-label="Audio"
1293
1322
  class:is-active={$editor.isActive("audio")}
1323
+ class:accent-soft={editorConfig.buttonStyle === "accent-soft"}
1294
1324
  >
1295
- <svg style="transform: scale(1.1);" fill="currentColor" width="24px" viewBox="0 -960 960 960" height="24px" xmlns="http://www.w3.org/2000/svg"><path d="M400-120q-66 0-113-47t-47-113q0-66 47-113t113-47q23 0 42.5 5.5T480-418v-422h240v160H560v400q0 66-47 113t-113 47Z"></path></svg>
1325
+ <svg
1326
+ style="transform: scale(1.1);"
1327
+ fill="currentColor"
1328
+ width="24px"
1329
+ viewBox="0 -960 960 960"
1330
+ height="24px"
1331
+ xmlns="http://www.w3.org/2000/svg"
1332
+ ><path
1333
+ d="M400-120q-66 0-113-47t-47-113q0-66 47-113t113-47q23 0 42.5 5.5T480-418v-422h240v160H560v400q0 66-47 113t-113 47Z"
1334
+ ></path></svg
1335
+ >
1296
1336
  </button>
1297
1337
  </div>
1298
1338
 
@@ -1304,6 +1344,7 @@
1304
1344
  onclick={addMediaGrid}
1305
1345
  aria-label="Media grid"
1306
1346
  class:is-active={$editor.isActive("MediaGridComponent")}
1347
+ class:accent-soft={editorConfig.buttonStyle === "accent-soft"}
1307
1348
  >
1308
1349
  <svg
1309
1350
  xmlns="http://www.w3.org/2000/svg"
@@ -1329,6 +1370,7 @@
1329
1370
  onclick={addTable}
1330
1371
  aria-label="Table"
1331
1372
  class:is-active={$editor.isActive("table")}
1373
+ class:accent-soft={editorConfig.buttonStyle === "accent-soft"}
1332
1374
  >
1333
1375
  <svg
1334
1376
  xmlns="http://www.w3.org/2000/svg"
@@ -1355,6 +1397,7 @@
1355
1397
  type="button"
1356
1398
  onclick={() => $editor.chain().focus().toggleTextAlign("left").run()}
1357
1399
  class:is-active={$editor.isActive({ textAlign: "left" })}
1400
+ class:accent-soft={editorConfig.buttonStyle === "accent-soft"}
1358
1401
  aria-label="Align left"
1359
1402
  >
1360
1403
  <svg
@@ -1378,6 +1421,7 @@
1378
1421
  onclick={() =>
1379
1422
  $editor.chain().focus().toggleTextAlign("center").run()}
1380
1423
  class:is-active={$editor.isActive({ textAlign: "center" })}
1424
+ class:accent-soft={editorConfig.buttonStyle === "accent-soft"}
1381
1425
  aria-label="Align center"
1382
1426
  >
1383
1427
  <svg
@@ -1400,6 +1444,7 @@
1400
1444
  type="button"
1401
1445
  onclick={() => $editor.chain().focus().toggleTextAlign("right").run()}
1402
1446
  class:is-active={$editor.isActive({ textAlign: "right" })}
1447
+ class:accent-soft={editorConfig.buttonStyle === "accent-soft"}
1403
1448
  aria-label="Align right"
1404
1449
  >
1405
1450
  <svg
@@ -1447,7 +1492,7 @@
1447
1492
  type="button"
1448
1493
  onclick={() => $editor.chain().focus().clearNodes().run()}
1449
1494
  >
1450
- Clear nodes
1495
+ Clear
1451
1496
  </button>
1452
1497
  </div>
1453
1498
  </header>
@@ -1461,7 +1506,11 @@
1461
1506
  bind:this={tooltip}
1462
1507
  style="display: {tooltipVisible
1463
1508
  ? 'flex'
1464
- : 'none'}; left: {tooltipX}px; top: {tooltipY}px;"
1509
+ : 'none'};
1510
+ left: {tooltipX}px;
1511
+ top: {tooltipY}px;
1512
+ --fl-editor-accent-color: {editorConfig.editorAccentColor};
1513
+ "
1465
1514
  >
1466
1515
  {#if activeDropdownType === "headings-dropdown"}
1467
1516
  <div role="group" class="fl-rich-text-toolbar-group">
@@ -1469,7 +1518,11 @@
1469
1518
  type="button"
1470
1519
  onclick={() =>
1471
1520
  $editor.chain().focus().toggleHeading({ level: 1 }).run()}
1472
- class={($editor.isActive("heading", { level: 1 }) || $editor.isActive("h1")) ? "is-active" : ""}
1521
+ class={$editor.isActive("heading", { level: 1 }) ||
1522
+ $editor.isActive("h1")
1523
+ ? "is-active"
1524
+ : ""}
1525
+ class:accent-soft={editorConfig.buttonStyle === "accent-soft"}
1473
1526
  aria-label="H1"
1474
1527
  disabled={!$editor.isActive("h1")}
1475
1528
  >
@@ -1490,6 +1543,7 @@
1490
1543
  onclick={() =>
1491
1544
  $editor.chain().focus().toggleHeading({ level: 2 }).run()}
1492
1545
  class={$editor.isActive("heading", { level: 2 }) ? "is-active" : ""}
1546
+ class:accent-soft={editorConfig.buttonStyle === "accent-soft"}
1493
1547
  aria-label="H2"
1494
1548
  disabled={$editor.isActive("h1")}
1495
1549
  >
@@ -1510,6 +1564,7 @@
1510
1564
  onclick={() =>
1511
1565
  $editor.chain().focus().toggleHeading({ level: 3 }).run()}
1512
1566
  class={$editor.isActive("heading", { level: 3 }) ? "is-active" : ""}
1567
+ class:accent-soft={editorConfig.buttonStyle === "accent-soft"}
1513
1568
  aria-label="H3"
1514
1569
  disabled={$editor.isActive("h1")}
1515
1570
  >
@@ -1530,6 +1585,7 @@
1530
1585
  onclick={() =>
1531
1586
  $editor.chain().focus().toggleHeading({ level: 4 }).run()}
1532
1587
  class={$editor.isActive("heading", { level: 4 }) ? "is-active" : ""}
1588
+ class:accent-soft={editorConfig.buttonStyle === "accent-soft"}
1533
1589
  aria-label="H4"
1534
1590
  disabled={$editor.isActive("h1")}
1535
1591
  >
@@ -1550,6 +1606,7 @@
1550
1606
  onclick={() =>
1551
1607
  $editor.chain().focus().toggleHeading({ level: 5 }).run()}
1552
1608
  class={$editor.isActive("heading", { level: 5 }) ? "is-active" : ""}
1609
+ class:accent-soft={editorConfig.buttonStyle === "accent-soft"}
1553
1610
  aria-label="H5"
1554
1611
  disabled={$editor.isActive("h1")}
1555
1612
  >
@@ -1570,6 +1627,7 @@
1570
1627
  onclick={() =>
1571
1628
  $editor.chain().focus().toggleHeading({ level: 6 }).run()}
1572
1629
  class={$editor.isActive("heading", { level: 6 }) ? "is-active" : ""}
1630
+ class:accent-soft={editorConfig.buttonStyle === "accent-soft"}
1573
1631
  aria-label="H6"
1574
1632
  disabled={$editor.isActive("h1")}
1575
1633
  >
@@ -1592,6 +1650,7 @@
1592
1650
  type="button"
1593
1651
  onclick={() => $editor.chain().focus().toggleBulletList().run()}
1594
1652
  class={$editor.isActive("bulletList") ? "is-active" : ""}
1653
+ class:accent-soft={editorConfig.buttonStyle === "accent-soft"}
1595
1654
  >
1596
1655
  <svg
1597
1656
  width="24"
@@ -1639,6 +1698,7 @@
1639
1698
  type="button"
1640
1699
  onclick={() => $editor.chain().focus().toggleOrderedList().run()}
1641
1700
  class={$editor.isActive("orderedList") ? "is-active" : ""}
1701
+ class:accent-soft={editorConfig.buttonStyle === "accent-soft"}
1642
1702
  >
1643
1703
  <svg
1644
1704
  width="24"
@@ -1686,6 +1746,7 @@
1686
1746
  type="button"
1687
1747
  onclick={() => $editor.chain().focus().toggleTaskList().run()}
1688
1748
  class={$editor.isActive("taskList") ? "is-active" : ""}
1749
+ class:accent-soft={editorConfig.buttonStyle === "accent-soft"}
1689
1750
  >
1690
1751
  <svg
1691
1752
  width="24"
@@ -2016,3 +2077,702 @@
2016
2077
  </div>
2017
2078
  {/if}
2018
2079
  </div>
2080
+
2081
+ {#if $editor}
2082
+ <!-- General Menu -->
2083
+ <BubbleMenu
2084
+ options={{ placement: "top", offset: bubbleOffset, flip: false }}
2085
+ editor={$editor}
2086
+ shouldShow={() => {
2087
+ const emptySelection = $editor.state.selection.empty;
2088
+ const isImage = $editor.isActive("image");
2089
+ const isCodeBlock = $editor.isActive("codeBlock");
2090
+ const isAudio = $editor.isActive("audio");
2091
+ const selection = $editor.state.selection;
2092
+ const isRow = $editor.storage.tableCell.customTableSelection === "row";
2093
+ const isColumn =
2094
+ $editor.storage.tableCell.customTableSelection === "column";
2095
+
2096
+ // ⛔️ Ocultar si hay flag de selección completa por fila/columna
2097
+ if (isRow || isColumn) {
2098
+ console.log(
2099
+ "Ocultar si hay flag de selección completa por fila/columna"
2100
+ );
2101
+ return false;
2102
+ }
2103
+
2104
+ // // ⛔️ Ocultar si es CellSelection completa (por seguridad)
2105
+ // if (selection instanceof CellSelection) {
2106
+ // return false;
2107
+ // }
2108
+
2109
+ if (emptySelection || isImage || isCodeBlock || isAudio) {
2110
+ return false;
2111
+ }
2112
+ return true;
2113
+ }}
2114
+ >
2115
+ <div data-test-id="bubble-menu" class="fl-bubble-menu flex">
2116
+ <div role="group" class="fl-rich-text-toolbar-group">
2117
+ <!-- Bold -->
2118
+ <button
2119
+ type="button"
2120
+ onclick={() => $editor.chain().focus().toggleBold().run()}
2121
+ disabled={!$editor.can().chain().focus().toggleBold().run()}
2122
+ class="fl-bubble-menu-mark-button"
2123
+ class:is-active={$editor.isActive("bold")}
2124
+ class:accent-soft={editorConfig.buttonStyle === "accent-soft"}
2125
+ aria-label="Bold"
2126
+ >
2127
+ <svg
2128
+ width="24"
2129
+ height="24"
2130
+ class="fl-button-icon"
2131
+ viewBox="0 0 24 24"
2132
+ fill="currentColor"
2133
+ xmlns="http://www.w3.org/2000/svg"
2134
+ ><path
2135
+ fill-rule="evenodd"
2136
+ clip-rule="evenodd"
2137
+ d="M6 2.5C5.17157 2.5 4.5 3.17157 4.5 4V20C4.5 20.8284 5.17157 21.5 6 21.5H15C16.4587 21.5 17.8576 20.9205 18.8891 19.8891C19.9205 18.8576 20.5 17.4587 20.5 16C20.5 14.5413 19.9205 13.1424 18.8891 12.1109C18.6781 11.9 18.4518 11.7079 18.2128 11.5359C19.041 10.5492 19.5 9.29829 19.5 8C19.5 6.54131 18.9205 5.14236 17.8891 4.11091C16.8576 3.07946 15.4587 2.5 14 2.5H6ZM14 10.5C14.663 10.5 15.2989 10.2366 15.7678 9.76777C16.2366 9.29893 16.5 8.66304 16.5 8C16.5 7.33696 16.2366 6.70107 15.7678 6.23223C15.2989 5.76339 14.663 5.5 14 5.5H7.5V10.5H14ZM7.5 18.5V13.5H15C15.663 13.5 16.2989 13.7634 16.7678 14.2322C17.2366 14.7011 17.5 15.337 17.5 16C17.5 16.663 17.2366 17.2989 16.7678 17.7678C16.2989 18.2366 15.663 18.5 15 18.5H7.5Z"
2138
+ fill="currentColor"
2139
+ ></path></svg
2140
+ >
2141
+ </button>
2142
+
2143
+ <!-- Italic -->
2144
+ <button
2145
+ type="button"
2146
+ onclick={() => $editor.chain().focus().toggleItalic().run()}
2147
+ disabled={!$editor.can().chain().focus().toggleItalic().run()}
2148
+ class="fl-bubble-menu-mark-button"
2149
+ class:is-active={$editor.isActive("italic")}
2150
+ class:accent-soft={editorConfig.buttonStyle === "accent-soft"}
2151
+ aria-label="Italic"
2152
+ >
2153
+ <svg
2154
+ width="24"
2155
+ height="24"
2156
+ class="tiptap-button-icon"
2157
+ viewBox="0 0 24 24"
2158
+ fill="currentColor"
2159
+ xmlns="http://www.w3.org/2000/svg"
2160
+ ><path
2161
+ d="M15.0222 3H19C19.5523 3 20 3.44772 20 4C20 4.55228 19.5523 5 19 5H15.693L10.443 19H14C14.5523 19 15 19.4477 15 20C15 20.5523 14.5523 21 14 21H9.02418C9.00802 21.0004 8.99181 21.0004 8.97557 21H5C4.44772 21 4 20.5523 4 20C4 19.4477 4.44772 19 5 19H8.30704L13.557 5H10C9.44772 5 9 4.55228 9 4C9 3.44772 9.44772 3 10 3H14.9782C14.9928 2.99968 15.0075 2.99967 15.0222 3Z"
2162
+ fill="currentColor"
2163
+ ></path></svg
2164
+ >
2165
+ </button>
2166
+
2167
+ <!-- Underline -->
2168
+ <button
2169
+ type="button"
2170
+ onclick={() => $editor.chain().focus().toggleUnderline().run()}
2171
+ disabled={!$editor.can().chain().focus().toggleStrike().run()}
2172
+ class="fl-bubble-menu-mark-button"
2173
+ class:is-active={$editor.isActive("underline")}
2174
+ class:accent-soft={editorConfig.buttonStyle === "accent-soft"}
2175
+ aria-label="Underline"
2176
+ >
2177
+ <svg
2178
+ width="24"
2179
+ height="24"
2180
+ class="tiptap-button-icon"
2181
+ viewBox="0 0 24 24"
2182
+ fill="currentColor"
2183
+ xmlns="http://www.w3.org/2000/svg"
2184
+ ><path
2185
+ fill-rule="evenodd"
2186
+ clip-rule="evenodd"
2187
+ d="M7 4C7 3.44772 6.55228 3 6 3C5.44772 3 5 3.44772 5 4V10C5 11.8565 5.7375 13.637 7.05025 14.9497C8.36301 16.2625 10.1435 17 12 17C13.8565 17 15.637 16.2625 16.9497 14.9497C18.2625 13.637 19 11.8565 19 10V4C19 3.44772 18.5523 3 18 3C17.4477 3 17 3.44772 17 4V10C17 11.3261 16.4732 12.5979 15.5355 13.5355C14.5979 14.4732 13.3261 15 12 15C10.6739 15 9.40215 14.4732 8.46447 13.5355C7.52678 12.5979 7 11.3261 7 10V4ZM4 19C3.44772 19 3 19.4477 3 20C3 20.5523 3.44772 21 4 21H20C20.5523 21 21 20.5523 21 20C21 19.4477 20.5523 19 20 19H4Z"
2188
+ fill="currentColor"
2189
+ ></path></svg
2190
+ >
2191
+ </button>
2192
+
2193
+ <!-- Strike -->
2194
+ <button
2195
+ type="button"
2196
+ onclick={() => $editor.chain().focus().toggleStrike().run()}
2197
+ disabled={!$editor.can().chain().focus().toggleStrike().run()}
2198
+ class="fl-bubble-menu-mark-button"
2199
+ class:is-active={$editor.isActive("strike")}
2200
+ class:accent-soft={editorConfig.buttonStyle === "accent-soft"}
2201
+ aria-label="Strike"
2202
+ >
2203
+ <svg
2204
+ width="24"
2205
+ height="24"
2206
+ class="tiptap-button-icon"
2207
+ viewBox="0 0 24 24"
2208
+ fill="currentColor"
2209
+ xmlns="http://www.w3.org/2000/svg"
2210
+ ><path
2211
+ d="M9.00039 3H16.0001C16.5524 3 17.0001 3.44772 17.0001 4C17.0001 4.55229 16.5524 5 16.0001 5H9.00011C8.68006 4.99983 8.36412 5.07648 8.07983 5.22349C7.79555 5.37051 7.55069 5.5836 7.36585 5.84487C7.181 6.10614 7.06155 6.40796 7.01754 6.72497C6.97352 7.04198 7.00623 7.36492 7.11292 7.66667C7.29701 8.18737 7.02414 8.75872 6.50344 8.94281C5.98274 9.1269 5.4114 8.85403 5.2273 8.33333C5.01393 7.72984 4.94851 7.08396 5.03654 6.44994C5.12456 5.81592 5.36346 5.21229 5.73316 4.68974C6.10285 4.1672 6.59256 3.74101 7.16113 3.44698C7.72955 3.15303 8.36047 2.99975 9.00039 3Z"
2212
+ fill="currentColor"
2213
+ ></path><path
2214
+ d="M18 13H20C20.5523 13 21 12.5523 21 12C21 11.4477 20.5523 11 20 11H4C3.44772 11 3 11.4477 3 12C3 12.5523 3.44772 13 4 13H14C14.7956 13 15.5587 13.3161 16.1213 13.8787C16.6839 14.4413 17 15.2044 17 16C17 16.7956 16.6839 17.5587 16.1213 18.1213C15.5587 18.6839 14.7956 19 14 19H6C5.44772 19 5 19.4477 5 20C5 20.5523 5.44772 21 6 21H14C15.3261 21 16.5979 20.4732 17.5355 19.5355C18.4732 18.5979 19 17.3261 19 16C19 14.9119 18.6453 13.8604 18 13Z"
2215
+ fill="currentColor"
2216
+ ></path></svg
2217
+ >
2218
+ </button>
2219
+
2220
+ <!-- Code -->
2221
+ <button
2222
+ type="button"
2223
+ onclick={() => $editor.chain().focus().toggleCode().run()}
2224
+ disabled={!$editor.can().chain().focus().toggleCode().run()}
2225
+ class="fl-bubble-menu-mark-button"
2226
+ class:is-active={$editor.isActive("code")}
2227
+ class:accent-soft={editorConfig.buttonStyle === "accent-soft"}
2228
+ aria-label="Code"
2229
+ >
2230
+ <svg
2231
+ width="24"
2232
+ height="24"
2233
+ class="tiptap-button-icon"
2234
+ viewBox="0 0 24 24"
2235
+ fill="currentColor"
2236
+ xmlns="http://www.w3.org/2000/svg"
2237
+ ><path
2238
+ d="M15.4545 4.2983C15.6192 3.77115 15.3254 3.21028 14.7983 3.04554C14.2712 2.88081 13.7103 3.1746 13.5455 3.70175L8.54554 19.7017C8.38081 20.2289 8.6746 20.7898 9.20175 20.9545C9.72889 21.1192 10.2898 20.8254 10.4545 20.2983L15.4545 4.2983Z"
2239
+ fill="currentColor"
2240
+ ></path><path
2241
+ d="M6.70711 7.29289C7.09763 7.68342 7.09763 8.31658 6.70711 8.70711L3.41421 12L6.70711 15.2929C7.09763 15.6834 7.09763 16.3166 6.70711 16.7071C6.31658 17.0976 5.68342 17.0976 5.29289 16.7071L1.29289 12.7071C0.902369 12.3166 0.902369 11.6834 1.29289 11.2929L5.29289 7.29289C5.68342 6.90237 6.31658 6.90237 6.70711 7.29289Z"
2242
+ fill="currentColor"
2243
+ ></path><path
2244
+ d="M17.2929 7.29289C17.6834 6.90237 18.3166 6.90237 18.7071 7.29289L22.7071 11.2929C23.0976 11.6834 23.0976 12.3166 22.7071 12.7071L18.7071 16.7071C18.3166 17.0976 17.6834 17.0976 17.2929 16.7071C16.9024 16.3166 16.9024 15.6834 17.2929 15.2929L20.5858 12L17.2929 8.70711C16.9024 8.31658 16.9024 7.68342 17.2929 7.29289Z"
2245
+ fill="currentColor"
2246
+ ></path></svg
2247
+ >
2248
+ </button>
2249
+
2250
+ <!-- Link -->
2251
+ <button
2252
+ type="button"
2253
+ onclick={() => setLink()}
2254
+ class="fl-bubble-menu-mark-button"
2255
+ class:is-active={$editor.isActive("link")}
2256
+ class:accent-soft={editorConfig.buttonStyle === "accent-soft"}
2257
+ aria-label="Link"
2258
+ >
2259
+ <svg
2260
+ width="24"
2261
+ height="24"
2262
+ class="tiptap-button-icon"
2263
+ viewBox="0 0 24 24"
2264
+ fill="currentColor"
2265
+ xmlns="http://www.w3.org/2000/svg"
2266
+ ><path
2267
+ d="M16.9958 1.06669C15.4226 1.05302 13.907 1.65779 12.7753 2.75074L12.765 2.76086L11.045 4.47086C10.6534 4.86024 10.6515 5.49341 11.0409 5.88507C11.4303 6.27673 12.0634 6.27858 12.4551 5.88919L14.1697 4.18456C14.9236 3.45893 15.9319 3.05752 16.9784 3.06662C18.0272 3.07573 19.0304 3.49641 19.772 4.23804C20.5137 4.97967 20.9344 5.98292 20.9435 7.03171C20.9526 8.07776 20.5515 9.08563 19.8265 9.83941L16.833 12.8329C16.4274 13.2386 15.9393 13.5524 15.4019 13.7529C14.8645 13.9533 14.2903 14.0359 13.7181 13.9949C13.146 13.9539 12.5894 13.7904 12.0861 13.5154C11.5827 13.2404 11.1444 12.8604 10.8008 12.401C10.47 11.9588 9.84333 11.8685 9.40108 12.1993C8.95883 12.5301 8.86849 13.1568 9.1993 13.599C9.71464 14.288 10.3721 14.858 11.1272 15.2705C11.8822 15.683 12.7171 15.9283 13.5753 15.9898C14.4334 16.0513 15.2948 15.9274 16.1009 15.6267C16.907 15.326 17.639 14.8555 18.2473 14.247L21.2472 11.2471L21.2593 11.2347C22.3523 10.1031 22.9571 8.58751 22.9434 7.01433C22.9297 5.44115 22.2987 3.93628 21.1863 2.82383C20.0738 1.71138 18.5689 1.08036 16.9958 1.06669Z"
2268
+ fill="currentColor"
2269
+ ></path><path
2270
+ d="M10.4247 8.0102C9.56657 7.94874 8.70522 8.07256 7.89911 8.37326C7.09305 8.67395 6.36096 9.14458 5.75272 9.753L2.75285 12.7529L2.74067 12.7653C1.64772 13.8969 1.04295 15.4125 1.05662 16.9857C1.07029 18.5589 1.70131 20.0637 2.81376 21.1762C3.9262 22.2886 5.43108 22.9196 7.00426 22.9333C8.57744 22.947 10.0931 22.3422 11.2247 21.2493L11.2371 21.2371L12.9471 19.5271C13.3376 19.1366 13.3376 18.5034 12.9471 18.1129C12.5565 17.7223 11.9234 17.7223 11.5328 18.1129L9.82932 19.8164C9.07555 20.5414 8.06768 20.9425 7.02164 20.9334C5.97285 20.9243 4.9696 20.5036 4.22797 19.762C3.48634 19.0203 3.06566 18.0171 3.05655 16.9683C3.04746 15.9222 3.44851 14.9144 4.17355 14.1606L7.16719 11.167C7.5727 10.7613 8.06071 10.4476 8.59811 10.2471C9.13552 10.0467 9.70976 9.96412 10.2819 10.0051C10.854 10.0461 11.4106 10.2096 11.9139 10.4846C12.4173 10.7596 12.8556 11.1397 13.1992 11.599C13.53 12.0412 14.1567 12.1316 14.5989 11.8007C15.0412 11.4699 15.1315 10.8433 14.8007 10.401C14.2854 9.71205 13.6279 9.14198 12.8729 8.72948C12.1178 8.31697 11.2829 8.07166 10.4247 8.0102Z"
2271
+ fill="currentColor"
2272
+ ></path></svg
2273
+ >
2274
+ </button>
2275
+
2276
+ <!-- Highlight -->
2277
+ <button
2278
+ class="fl-bubble-menu-mark-button"
2279
+ type="button"
2280
+ aria-label="Highlight"
2281
+ onclick={(e) => toogleDropdown(e.currentTarget, "highlight")}
2282
+ >
2283
+ <svg
2284
+ width="24"
2285
+ height="24"
2286
+ class="tiptap-button-icon"
2287
+ viewBox="0 0 24 24"
2288
+ fill="currentColor"
2289
+ xmlns="http://www.w3.org/2000/svg"
2290
+ ><path
2291
+ fill-rule="evenodd"
2292
+ clip-rule="evenodd"
2293
+ 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"
2294
+ fill="currentColor"
2295
+ ></path>
2296
+ </svg>
2297
+ <svg
2298
+ class="toogle-dropdown-button-icon"
2299
+ aria-hidden="true"
2300
+ xmlns="http://www.w3.org/2000/svg"
2301
+ fill="none"
2302
+ viewBox="0 0 10 6"
2303
+ >
2304
+ <path
2305
+ stroke="currentColor"
2306
+ stroke-linecap="round"
2307
+ stroke-linejoin="round"
2308
+ stroke-width="2"
2309
+ d="m1 1 4 4 4-4"
2310
+ ></path>
2311
+ </svg>
2312
+ </button>
2313
+
2314
+ <!-- Text color -->
2315
+ <button
2316
+ aria-label="Text color"
2317
+ type="button"
2318
+ bind:this={textColorDropdownTriggerEl}
2319
+ onclick={() =>
2320
+ toogleDropdown(textColorDropdownTriggerEl, "text-color-dropdown")}
2321
+ class="fl-bubble-menu-mark-button"
2322
+ >
2323
+ <span
2324
+ class="fl-button-color-text-popover"
2325
+ style="background: {$editor?.getAttributes('textStyle')?.color ||
2326
+ 'currentColor'}"
2327
+ ></span>
2328
+
2329
+ <svg
2330
+ class="toogle-dropdown-button-icon"
2331
+ aria-hidden="true"
2332
+ xmlns="http://www.w3.org/2000/svg"
2333
+ fill="none"
2334
+ viewBox="0 0 10 6"
2335
+ >
2336
+ <path
2337
+ stroke="currentColor"
2338
+ stroke-linecap="round"
2339
+ stroke-linejoin="round"
2340
+ stroke-width="2"
2341
+ d="m1 1 4 4 4-4"
2342
+ ></path>
2343
+ </svg>
2344
+ </button>
2345
+
2346
+ {#if !isCellSelection()}
2347
+ <button
2348
+ class="fl-bubble-menu-mark-button"
2349
+ type="button"
2350
+ onclick={() => $editor.chain().focus().setHardBreak().run()}
2351
+ aria-label="Hard break"
2352
+ >
2353
+ <svg
2354
+ xmlns="http://www.w3.org/2000/svg"
2355
+ width="24"
2356
+ height="24"
2357
+ viewBox="0 0 24 24"
2358
+ fill="none"
2359
+ stroke="currentColor"
2360
+ stroke-width="2"
2361
+ stroke-linecap="round"
2362
+ stroke-linejoin="round"
2363
+ class="icon icon-tabler icons-tabler-outline icon-tabler-corner-down-left"
2364
+ ><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path
2365
+ d="M18 6v6a3 3 0 0 1 -3 3h-10l4 -4m0 8l-4 -4"
2366
+ ></path></svg
2367
+ >
2368
+ </button>
2369
+ {/if}
2370
+
2371
+ {#if isCellSelection()}
2372
+ <button
2373
+ class="fl-bubble-menu-mark-button"
2374
+ type="button"
2375
+ aria-label="Merge cells"
2376
+ title="Merge cells"
2377
+ onclick={() => $editor?.chain().focus().mergeCells().run()}
2378
+ >
2379
+ <svg
2380
+ xmlns="http://www.w3.org/2000/svg"
2381
+ viewBox="0 0 24 24"
2382
+ width="16"
2383
+ height="16"
2384
+ fill="none"
2385
+ stroke="currentColor"
2386
+ stroke-width="2"
2387
+ stroke-linecap="round"
2388
+ stroke-linejoin="round"
2389
+ style="opacity:1;"
2390
+ ><path d="M12 21v-6m0-6V3M3 15h18M3 9h18"></path><rect
2391
+ width="18"
2392
+ height="18"
2393
+ x="3"
2394
+ y="3"
2395
+ rx="2"
2396
+ ></rect></svg
2397
+ >
2398
+ </button>
2399
+
2400
+ <button
2401
+ class="fl-bubble-menu-mark-button"
2402
+ type="button"
2403
+ aria-label="Split cell"
2404
+ title="Split cell"
2405
+ onclick={() => $editor?.chain().focus().splitCell().run()}
2406
+ >
2407
+ <svg
2408
+ xmlns="http://www.w3.org/2000/svg"
2409
+ viewBox="0 0 24 24"
2410
+ width="16"
2411
+ height="16"
2412
+ fill="none"
2413
+ stroke="currentColor"
2414
+ stroke-width="2"
2415
+ stroke-linecap="round"
2416
+ stroke-linejoin="round"
2417
+ style="opacity:1;"
2418
+ ><path d="M12 15V9m-9 6h18M3 9h18" /><rect
2419
+ width="18"
2420
+ height="18"
2421
+ x="3"
2422
+ y="3"
2423
+ rx="2"
2424
+ /></svg
2425
+ >
2426
+ </button>
2427
+ {/if}
2428
+ </div>
2429
+ </div>
2430
+
2431
+ <!-- <div
2432
+ class="fl-toolbar-dropdown-panel"
2433
+ bind:this={tooltip}
2434
+ style="display: {tooltipVisible
2435
+ ? 'flex'
2436
+ : 'none'}; left: {tooltipX}px; top: {tooltipY}px;"
2437
+ >
2438
+ {#if activeDropdownType === "text-color"}
2439
+ <div class="fl-editor-color-palette">
2440
+ <button
2441
+ class="fl-color-swatch fl-color-picker-btn"
2442
+ aria-label="Text color picker"
2443
+ type="button"
2444
+ >
2445
+ <input
2446
+ type="color"
2447
+ onchange={(event: any) => {
2448
+ recentCustomColors = [
2449
+ ...recentCustomColors,
2450
+ event?.target?.value,
2451
+ ];
2452
+ $editor.chain().focus().setColor(event?.target?.value).run();
2453
+ hideDropdown();
2454
+ }}
2455
+ value={rgbToHex($editor?.getAttributes("textStyle")?.color)}
2456
+ data-testid="setColor"
2457
+ id="colorPicker"
2458
+ />
2459
+ </button>
2460
+
2461
+ {#each TEXT_COLOR_PALETTE as color}
2462
+ <button
2463
+ class="fl-color-swatch"
2464
+ class:active={$editor?.isActive("textStyle", {
2465
+ color: color,
2466
+ })}
2467
+ onclick={() => {
2468
+ $editor?.chain().focus().setColor(color).run();
2469
+ hideDropdown();
2470
+ }}
2471
+ style="background-color: {color};"
2472
+ aria-label={color}
2473
+ >
2474
+ </button>
2475
+ {/each}
2476
+
2477
+ <button
2478
+ class="fl-color-swatch unset-color"
2479
+ onclick={() => {
2480
+ $editor?.chain().focus().unsetColor().run();
2481
+ hideDropdown();
2482
+ }}
2483
+ style="background-color: #ffffff;"
2484
+ aria-label="Unset color"
2485
+ >
2486
+ </button>
2487
+
2488
+ {#if recentCustomColors.length > 0}
2489
+ {#each recentCustomColors as color}
2490
+ <button
2491
+ class="fl-color-swatch"
2492
+ class:active={$editor?.isActive("textStyle", {
2493
+ color: color,
2494
+ })}
2495
+ onclick={() => {
2496
+ $editor?.chain().focus().setColor(color).run();
2497
+ hideDropdown();
2498
+ }}
2499
+ style="background-color: {color};"
2500
+ aria-label={color}
2501
+ >
2502
+ </button>
2503
+ {/each}
2504
+ {:else}
2505
+ <button
2506
+ class="fl-color-swatch"
2507
+ style="outline: 1px dashed #ffffff66;background: transparent;"
2508
+ onclick={() => alert("Not implemented yet")}
2509
+ aria-label="Add new color"
2510
+ >
2511
+ <svg
2512
+ xmlns="http://www.w3.org/2000/svg"
2513
+ fill="none"
2514
+ viewBox="0 0 24 24"
2515
+ stroke-width="1.5"
2516
+ stroke="currentColor"
2517
+ class="size-6"
2518
+ style="
2519
+ width: 11px;
2520
+ height: 11px;
2521
+ "
2522
+ >
2523
+ <path
2524
+ stroke-linecap="round"
2525
+ stroke-linejoin="round"
2526
+ d="M12 4.5v15m7.5-7.5h-15"
2527
+ ></path>
2528
+ </svg>
2529
+ </button>
2530
+
2531
+ <button
2532
+ class="fl-color-swatch"
2533
+ style="outline: 1px dashed #ffffff66;background: transparent;"
2534
+ onclick={() => alert("Not implemented yet")}
2535
+ aria-label="Add new color"
2536
+ >
2537
+ <svg
2538
+ xmlns="http://www.w3.org/2000/svg"
2539
+ fill="none"
2540
+ viewBox="0 0 24 24"
2541
+ stroke-width="1.5"
2542
+ stroke="currentColor"
2543
+ class="size-6"
2544
+ style="
2545
+ width: 11px;
2546
+ height: 11px;
2547
+ "
2548
+ >
2549
+ <path
2550
+ stroke-linecap="round"
2551
+ stroke-linejoin="round"
2552
+ d="M12 4.5v15m7.5-7.5h-15"
2553
+ ></path>
2554
+ </svg>
2555
+ </button>
2556
+ {/if}
2557
+ </div>
2558
+ {:else if activeDropdownType === "highlight"}
2559
+ <div class="fl-editor-color-palette">
2560
+ <button
2561
+ class="fl-color-swatch fl-color-picker-btn"
2562
+ aria-label="Highlight color picker"
2563
+ type="button"
2564
+ >
2565
+ <input
2566
+ type="color"
2567
+ onchange={(event: any) => {
2568
+ recentCustomColors = [
2569
+ ...recentCustomColors,
2570
+ event?.target?.value,
2571
+ ];
2572
+ $editor
2573
+ .chain()
2574
+ .focus()
2575
+ .setHighlight({ color: event?.target?.value })
2576
+ .run();
2577
+ hideDropdown();
2578
+ }}
2579
+ value={rgbToHex($editor?.getAttributes("textStyle")?.color)}
2580
+ data-testid="setHiglight"
2581
+ id="colorPicker"
2582
+ />
2583
+ </button>
2584
+
2585
+ {#each HIGHLIGHT_COLOR_PALETTE as color}
2586
+ <button
2587
+ class="fl-color-swatch"
2588
+ class:active={$editor?.isActive("textStyle", {
2589
+ color: color,
2590
+ })}
2591
+ onclick={() => {
2592
+ $editor?.chain().focus().setHighlight({ color }).run();
2593
+ hideDropdown();
2594
+ }}
2595
+ style="background-color: {color};"
2596
+ aria-label={color}
2597
+ >
2598
+ </button>
2599
+ {/each}
2600
+
2601
+ <button
2602
+ class="fl-color-swatch unset-color"
2603
+ onclick={() => {
2604
+ $editor?.chain().focus().unsetColor().run();
2605
+ hideDropdown();
2606
+ }}
2607
+ style="background-color: #ffffff;"
2608
+ aria-label="Unset color"
2609
+ >
2610
+ </button>
2611
+
2612
+ {#if recentCustomColors.length > 0}
2613
+ {#each recentCustomColors as color}
2614
+ <button
2615
+ class="fl-color-swatch"
2616
+ class:active={$editor?.isActive("textStyle", {
2617
+ color: color,
2618
+ })}
2619
+ onclick={() => {
2620
+ $editor?.chain().focus().setHighlight({ color }).run();
2621
+ hideDropdown();
2622
+ }}
2623
+ style="background-color: {color};"
2624
+ aria-label={color}
2625
+ >
2626
+ </button>
2627
+ {/each}
2628
+ {:else}
2629
+ <button
2630
+ class="fl-color-swatch"
2631
+ style="outline: 1px dashed #ffffff66;background: transparent;"
2632
+ onclick={() => alert("Not implemented yet")}
2633
+ aria-label="Add new color"
2634
+ >
2635
+ <svg
2636
+ xmlns="http://www.w3.org/2000/svg"
2637
+ fill="none"
2638
+ viewBox="0 0 24 24"
2639
+ stroke-width="1.5"
2640
+ stroke="currentColor"
2641
+ class="size-6"
2642
+ style="
2643
+ width: 11px;
2644
+ height: 11px;
2645
+ "
2646
+ >
2647
+ <path
2648
+ stroke-linecap="round"
2649
+ stroke-linejoin="round"
2650
+ d="M12 4.5v15m7.5-7.5h-15"
2651
+ ></path>
2652
+ </svg>
2653
+ </button>
2654
+
2655
+ <button
2656
+ class="fl-color-swatch"
2657
+ style="outline: 1px dashed #ffffff66;background: transparent;"
2658
+ onclick={() => alert("Not implemented yet")}
2659
+ aria-label="Add new color"
2660
+ >
2661
+ <svg
2662
+ xmlns="http://www.w3.org/2000/svg"
2663
+ fill="none"
2664
+ viewBox="0 0 24 24"
2665
+ stroke-width="1.5"
2666
+ stroke="currentColor"
2667
+ class="size-6"
2668
+ style="
2669
+ width: 11px;
2670
+ height: 11px;
2671
+ "
2672
+ >
2673
+ <path
2674
+ stroke-linecap="round"
2675
+ stroke-linejoin="round"
2676
+ d="M12 4.5v15m7.5-7.5h-15"
2677
+ ></path>
2678
+ </svg>
2679
+ </button>
2680
+ {/if}
2681
+ </div>
2682
+ {/if}
2683
+ </div> -->
2684
+ </BubbleMenu>
2685
+
2686
+ <!-- Image Menu -->
2687
+ <BubbleMenu
2688
+ editor={$editor}
2689
+ shouldShow={() => {
2690
+ const emptySelection = $editor.state.selection.empty;
2691
+ if (emptySelection) {
2692
+ return false;
2693
+ }
2694
+ return $editor.isActive("image");
2695
+ }}
2696
+ >
2697
+ <div data-test-id="bubble-menu" class="fl-bubble-menu flex">
2698
+ <input
2699
+ class="fl-editor-image-url-input"
2700
+ type="text"
2701
+ placeholder="Insert image url"
2702
+ bind:this={imageUrlInputEl}
2703
+ value={$editor.getAttributes("image").src}
2704
+ oninput={(e: any) => {
2705
+ // console.log(e.target.value);
2706
+ imageUrlInputValue = e.target.value;
2707
+ }}
2708
+ onkeydown={(e: any) => {
2709
+ if (e.key === "Enter") {
2710
+ e.preventDefault();
2711
+ $editor
2712
+ .chain()
2713
+ .focus()
2714
+ .setImage({ src: imageUrlInputEl?.value })
2715
+ .run();
2716
+ }
2717
+ }}
2718
+ />
2719
+ <button
2720
+ type="button"
2721
+ aria-label="Insert image from url"
2722
+ disabled={!imageUrlInputValue ||
2723
+ imageUrlInputValue === $editor.getAttributes("image").src}
2724
+ class:is-active={imageUrlInputValue &&
2725
+ imageUrlInputValue !== $editor.getAttributes("image").src}
2726
+ class:accent-soft={editorConfig.buttonStyle === "accent-soft"}
2727
+ onclick={() => {
2728
+ $editor
2729
+ .chain()
2730
+ .focus()
2731
+ .setImage({ src: imageUrlInputEl?.value })
2732
+ .run();
2733
+ }}
2734
+ >
2735
+ <svg
2736
+ width="16"
2737
+ height="16"
2738
+ class="tiptap-button-icon"
2739
+ viewBox="0 0 24 24"
2740
+ fill="currentColor"
2741
+ xmlns="http://www.w3.org/2000/svg"
2742
+ ><path
2743
+ fill-rule="evenodd"
2744
+ clip-rule="evenodd"
2745
+ d="M21 4C21 3.44772 20.5523 3 20 3C19.4477 3 19 3.44772 19 4V11C19 11.7956 18.6839 12.5587 18.1213 13.1213C17.5587 13.6839 16.7956 14 16 14H6.41421L9.70711 10.7071C10.0976 10.3166 10.0976 9.68342 9.70711 9.29289C9.31658 8.90237 8.68342 8.90237 8.29289 9.29289L3.29289 14.2929C2.90237 14.6834 2.90237 15.3166 3.29289 15.7071L8.29289 20.7071C8.68342 21.0976 9.31658 21.0976 9.70711 20.7071C10.0976 20.3166 10.0976 19.6834 9.70711 19.2929L6.41421 16H16C17.3261 16 18.5979 15.4732 19.5355 14.5355C20.4732 13.5979 21 12.3261 21 11V4Z"
2746
+ fill="currentColor"
2747
+ class="s-m1-89pp0R0Iu"
2748
+ ></path></svg
2749
+ >
2750
+ </button>
2751
+
2752
+ <button
2753
+ type="button"
2754
+ onclick={() => setLink()}
2755
+ class="fl-bubble-menu-mark-button"
2756
+ class:is-active={$editor.isActive("link")}
2757
+ class:accent-soft={editorConfig.buttonStyle === "accent-soft"}
2758
+ aria-label="Link"
2759
+ >
2760
+ <svg
2761
+ width="16"
2762
+ height="16"
2763
+ class="tiptap-button-icon"
2764
+ viewBox="0 0 24 24"
2765
+ fill="currentColor"
2766
+ xmlns="http://www.w3.org/2000/svg"
2767
+ ><path
2768
+ d="M16.9958 1.06669C15.4226 1.05302 13.907 1.65779 12.7753 2.75074L12.765 2.76086L11.045 4.47086C10.6534 4.86024 10.6515 5.49341 11.0409 5.88507C11.4303 6.27673 12.0634 6.27858 12.4551 5.88919L14.1697 4.18456C14.9236 3.45893 15.9319 3.05752 16.9784 3.06662C18.0272 3.07573 19.0304 3.49641 19.772 4.23804C20.5137 4.97967 20.9344 5.98292 20.9435 7.03171C20.9526 8.07776 20.5515 9.08563 19.8265 9.83941L16.833 12.8329C16.4274 13.2386 15.9393 13.5524 15.4019 13.7529C14.8645 13.9533 14.2903 14.0359 13.7181 13.9949C13.146 13.9539 12.5894 13.7904 12.0861 13.5154C11.5827 13.2404 11.1444 12.8604 10.8008 12.401C10.47 11.9588 9.84333 11.8685 9.40108 12.1993C8.95883 12.5301 8.86849 13.1568 9.1993 13.599C9.71464 14.288 10.3721 14.858 11.1272 15.2705C11.8822 15.683 12.7171 15.9283 13.5753 15.9898C14.4334 16.0513 15.2948 15.9274 16.1009 15.6267C16.907 15.326 17.639 14.8555 18.2473 14.247L21.2472 11.2471L21.2593 11.2347C22.3523 10.1031 22.9571 8.58751 22.9434 7.01433C22.9297 5.44115 22.2987 3.93628 21.1863 2.82383C20.0738 1.71138 18.5689 1.08036 16.9958 1.06669Z"
2769
+ fill="currentColor"
2770
+ ></path><path
2771
+ d="M10.4247 8.0102C9.56657 7.94874 8.70522 8.07256 7.89911 8.37326C7.09305 8.67395 6.36096 9.14458 5.75272 9.753L2.75285 12.7529L2.74067 12.7653C1.64772 13.8969 1.04295 15.4125 1.05662 16.9857C1.07029 18.5589 1.70131 20.0637 2.81376 21.1762C3.9262 22.2886 5.43108 22.9196 7.00426 22.9333C8.57744 22.947 10.0931 22.3422 11.2247 21.2493L11.2371 21.2371L12.9471 19.5271C13.3376 19.1366 13.3376 18.5034 12.9471 18.1129C12.5565 17.7223 11.9234 17.7223 11.5328 18.1129L9.82932 19.8164C9.07555 20.5414 8.06768 20.9425 7.02164 20.9334C5.97285 20.9243 4.9696 20.5036 4.22797 19.762C3.48634 19.0203 3.06566 18.0171 3.05655 16.9683C3.04746 15.9222 3.44851 14.9144 4.17355 14.1606L7.16719 11.167C7.5727 10.7613 8.06071 10.4476 8.59811 10.2471C9.13552 10.0467 9.70976 9.96412 10.2819 10.0051C10.854 10.0461 11.4106 10.2096 11.9139 10.4846C12.4173 10.7596 12.8556 11.1397 13.1992 11.599C13.53 12.0412 14.1567 12.1316 14.5989 11.8007C15.0412 11.4699 15.1315 10.8433 14.8007 10.401C14.2854 9.71205 13.6279 9.14198 12.8729 8.72948C12.1178 8.31697 11.2829 8.07166 10.4247 8.0102Z"
2772
+ fill="currentColor"
2773
+ ></path></svg
2774
+ >
2775
+ </button>
2776
+ </div>
2777
+ </BubbleMenu>
2778
+ {/if}