@flexiui/svelte-rich-text 0.0.34 → 0.0.36

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.
@@ -1,12 +1,4 @@
1
1
  <script lang="ts">
2
- import { CustomTableHeader } from "./extensions/Table/CustomTableHeader";
3
- import { CustomTableCell } from "./extensions/Table/CustomTableCell";
4
- import { TableKit } from "@tiptap/extension-table";
5
- import { CellSelection } from "prosemirror-tables";
6
-
7
- import { NodeLineHeight } from "./extensions/NodeLineHeight";
8
- import { MediaGridExtension } from "./extensions/MediaGrid/MediaGrid";
9
- import { MediaGridItemExtension } from "./extensions/MediaGrid/MediaGridItem";
10
2
  import {
11
3
  Mathematics,
12
4
  migrateMathStrings,
@@ -20,15 +12,8 @@
20
12
 
21
13
  import { createEditor, Editor, EditorContent } from "svelte-tiptap";
22
14
 
23
- import StarterKit from "@tiptap/starter-kit";
24
- import Highlight from "@tiptap/extension-highlight";
25
- import TextAlign from "@tiptap/extension-text-align";
26
- import Image from "@tiptap/extension-image";
27
- import { Audio } from "./extensions/Audio";
28
- import { ListKit } from "@tiptap/extension-list";
29
- import { TextStyleKit } from "@tiptap/extension-text-style";
30
- import { EnhancedLink } from "./extensions/EnhancedLink";
31
15
  import { computePosition, offset, autoUpdate } from "@floating-ui/dom";
16
+ import { getRichTextExtensions } from "./getExtensions";
32
17
 
33
18
  declare interface Props {
34
19
  id?: string;
@@ -112,85 +97,123 @@
112
97
  ...(config ?? {}),
113
98
  });
114
99
 
115
- const extensions = [
116
- // Color.configure({ types: [TextStyle.name, ListItem.name] }),
117
- Highlight.configure({ multicolor: true }),
118
- TextStyleKit,
119
- StarterKit.configure({
120
- // Disable an included extension
121
- trailingNode: false,
122
- link: false,
123
- bulletList: false,
124
- listItem: false,
125
- orderedList: false,
126
- listKeymap: false,
127
- }),
128
- EnhancedLink,
129
- Audio.configure({
130
- HTMLAttributes: { class: "audio-player" },
131
- }),
132
- Image.configure({
133
- inline: true,
134
- }),
135
- ListKit,
136
- TextAlign.configure({
137
- types: [
138
- "heading",
139
- "paragraph",
140
- "bulletList",
141
- "taskList",
142
- "listItem",
143
- "blockquote",
144
- ],
145
- }),
146
- Mathematics.configure({
147
- inlineOptions: {
148
- onClick: (node, pos) => {
149
- // you can do anything on click, e.g. open a dialog to edit the math node
150
- // or just a prompt to edit the LaTeX code for a quick prototype
151
- const katex = prompt(
152
- "Update math LaTeX expression:",
153
- node.attrs.latex
154
- );
155
- if (katex) {
156
- $editor
157
- .chain()
158
- .setNodeSelection(pos)
159
- .updateInlineMath({ latex: katex })
160
- .focus()
161
- .run();
162
- }
100
+ // const extensions = [
101
+ // // Color.configure({ types: [TextStyle.name, ListItem.name] }),
102
+ // Highlight.configure({ multicolor: true }),
103
+ // TextStyleKit,
104
+ // StarterKit.configure({
105
+ // // Disable an included extension
106
+ // trailingNode: false,
107
+ // link: false,
108
+ // bulletList: false,
109
+ // listItem: false,
110
+ // orderedList: false,
111
+ // listKeymap: false,
112
+ // }),
113
+ // EnhancedLink,
114
+ // Audio.configure({
115
+ // HTMLAttributes: { class: "audio-player" },
116
+ // }),
117
+ // Image.configure({
118
+ // inline: true,
119
+ // }),
120
+ // ListKit,
121
+ // TextAlign.configure({
122
+ // types: [
123
+ // "heading",
124
+ // "paragraph",
125
+ // "bulletList",
126
+ // "taskList",
127
+ // "listItem",
128
+ // "blockquote",
129
+ // ],
130
+ // }),
131
+ // Mathematics.configure({
132
+ // inlineOptions: {
133
+ // onClick: (node, pos) => {
134
+ // // you can do anything on click, e.g. open a dialog to edit the math node
135
+ // // or just a prompt to edit the LaTeX code for a quick prototype
136
+ // const katex = prompt(
137
+ // "Update math LaTeX expression:",
138
+ // node.attrs.latex
139
+ // );
140
+ // if (katex) {
141
+ // $editor
142
+ // .chain()
143
+ // .setNodeSelection(pos)
144
+ // .updateInlineMath({ latex: katex })
145
+ // .focus()
146
+ // .run();
147
+ // }
148
+ // },
149
+ // },
150
+ // blockOptions: {
151
+ // // optional options for the block math node
152
+ // },
153
+ // katexOptions: {
154
+ // displayMode: false,
155
+ // throwOnError: false,
156
+ // macros: {
157
+ // "\\RR": "\\mathbb{R}",
158
+ // "\\ZZ": "\\mathbb{Z}",
159
+ // },
160
+ // },
161
+ // }),
162
+ // NodeLineHeight,
163
+ // MediaGridExtension,
164
+ // MediaGridItemExtension,
165
+ // TableKit.configure({
166
+ // table: {
167
+ // HTMLAttributes: { class: "fl-table-editable" },
168
+ // resizable: true,
169
+ // },
170
+ // }),
171
+ // CustomTableCell.configure({
172
+ // HTMLAttributes: { class: "fl-cell-editable" },
173
+ // }),
174
+ // CustomTableHeader.configure({
175
+ // HTMLAttributes: { class: "fl-cell-editable" },
176
+ // }),
177
+ // ...customExtensions,
178
+ // ];
179
+
180
+ const extensions = getRichTextExtensions({
181
+ editable: true,
182
+ customExtensions: [
183
+ ...customExtensions,
184
+ Mathematics.configure({
185
+ inlineOptions: {
186
+ onClick: (node, pos) => {
187
+ // you can do anything on click, e.g. open a dialog to edit the math node
188
+ // or just a prompt to edit the LaTeX code for a quick prototype
189
+ const katex = prompt(
190
+ "Update math LaTeX expression:",
191
+ node.attrs.latex
192
+ );
193
+ if (katex) {
194
+ $editor
195
+ .chain()
196
+ .setNodeSelection(pos)
197
+ .updateInlineMath({ latex: katex })
198
+ .focus()
199
+ .run();
200
+ }
201
+ },
163
202
  },
164
- },
165
- blockOptions: {
166
- // optional options for the block math node
167
- },
168
- katexOptions: {
169
- displayMode: false,
170
- throwOnError: false,
171
- macros: {
172
- "\\RR": "\\mathbb{R}",
173
- "\\ZZ": "\\mathbb{Z}",
203
+ blockOptions: {
204
+ // optional options for the block math node
174
205
  },
175
- },
176
- }),
177
- NodeLineHeight,
178
- MediaGridExtension,
179
- MediaGridItemExtension,
180
- TableKit.configure({
181
- table: {
182
- HTMLAttributes: { class: "fl-table-editable" },
183
- resizable: true,
184
- },
185
- }),
186
- CustomTableCell.configure({
187
- HTMLAttributes: { class: "fl-cell-editable" },
188
- }),
189
- CustomTableHeader.configure({
190
- HTMLAttributes: { class: "fl-cell-editable" },
191
- }),
192
- ...customExtensions,
193
- ];
206
+ katexOptions: {
207
+ displayMode: false,
208
+ throwOnError: false,
209
+ macros: {
210
+ "\\RR": "\\mathbb{R}",
211
+ "\\ZZ": "\\mathbb{Z}",
212
+ },
213
+ },
214
+ })
215
+ ]
216
+ });
194
217
 
195
218
  let tooltipVisible = $state(false);
196
219
  let tooltipX = $state(0);
@@ -200,6 +223,8 @@
200
223
  let currentTriggerEl: HTMLElement | null = null;
201
224
  let activeDropdownType = $state(null);
202
225
  let enterPressed = $state(false);
226
+ let fontSize = $state(16) as number;
227
+ let lineHeight = $state(null) as number;
203
228
 
204
229
  const TEXT_COLOR_PALETTE = [
205
230
  "rgb(94, 23, 235)",
@@ -280,8 +305,7 @@
280
305
  onMount(() => {
281
306
  editor = createEditor({
282
307
  extensions,
283
- content:
284
- '<h2 style="line-height: 1;"><span style="font-size: 22px;">Aquí tens algunes expressions bàsiques en català. Llegeix-les, escolta-les i repeteix-les.</span></h2><table class="fl-table-editable" style="min-width: 75px;"><colgroup><col style="min-width: 25px;"><col style="min-width: 25px;"><col style="min-width: 25px;"></colgroup><tbody><tr><th class="fl-cell-editable" colspan="1" rowspan="1"><p></p></th><th class="fl-cell-editable" colspan="1" rowspan="1"><p></p></th><th class="fl-cell-editable" colspan="1" rowspan="1"><p></p></th></tr><tr><td class="fl-cell-editable" colspan="1" rowspan="1"><p></p></td><td class="fl-cell-editable" colspan="1" rowspan="1"><p></p></td><td class="fl-cell-editable" colspan="1" rowspan="1"><p></p></td></tr><tr><td class="fl-cell-editable" colspan="1" rowspan="1"><p></p></td><td class="fl-cell-editable" colspan="1" rowspan="1"><p></p></td><td class="fl-cell-editable" colspan="1" rowspan="1"><p></p></td></tr></tbody></table><ul><li><p style="line-height: 1.5;">Hola!</p></li><li><p style="line-height: 1.5;">Com estàs?</p></li><li><p style="line-height: 1.5;">Com et dius?</p></li><li><p style="line-height: 1.5;">Com es diu agua en català?</p></li><li><p style="line-height: 1.5;">Què vol dir rentadora?</p></li><li><p style="line-height: 1.5;">Com s\'escriu bolígraf?</p></li><li><p style="line-height: 1.5;">Com es pronuncia aquesta paraula?</p></li><li><p style="line-height: 1.5;">M\'ho pots repetir, si us plau?</p></li><li><p style="line-height: 1.5;">A poc a poc, si us plau.</p></li><li><p style="line-height: 1.5;">Com?</p></li><li><p style="line-height: 1.5;">No t\'entenc.</p></li><li><p style="line-height: 1.5;">Gràcies.</p></li><li><p style="line-height: 1.5;">De res.</p></li><li><p style="line-height: 1.5;">Perdona.</p></li><li><p style="line-height: 1.5;">I tant!</p></li><li><p style="line-height: 1.5;">Edited</p></li></ul><pre><code>const name = "Alex";\nconsole.log(`Hello ${name}`)</code></pre><media-grid-component class="fl-media-grid" data-cols="3" data-gap="1.5rem" data-show-indicator="false" data-indicator-type="numeric"><div data-type="grid-item" class="fl-grid-item"><img src="https://img2.rtve.es/n/16848600?w=1600"></div><div data-type="grid-item" class="fl-grid-item"><img src="https://img2.rtve.es/n/16848600?w=1600"></div><div data-type="grid-item" class="fl-grid-item"><img src="https://img2.rtve.es/n/16848600?w=1600"></div></media-grid-component><audio-player class="audio-player" src="https://pub-503cb197f1134814ac02f257b9cde1c1.r2.dev/uploads/audio-festa-major.mp3" controls="true" data-color-play="#333" data-color-bar="#888" data-max-width="100%" data-id="fl-audio-4i336em9v43"></audio-player><blockquote><p>- Hola! Com estàs?<br>- Molt bé, i tu?</p></blockquote><audio-player class="audio-player" src="https://pub-503cb197f1134814ac02f257b9cde1c1.r2.dev/uploads/dictat-buscar-habitatge.mp3" controls="true" data-color-play="#333" data-color-bar="#888" data-max-width="100%" data-id="fl-audio-4i336em9v43"></audio-player><blockquote><p>- Com et dius?<br>- Em dic Sara, i tu?</p></blockquote><audio-player class="audio-player" src="https://pub-503cb197f1134814ac02f257b9cde1c1.r2.dev/uploads/dictat-buscar-habitatge.mp3" controls="true" data-color-play="#333" data-color-bar="#888" data-max-width="100%" data-id="fl-audio-4i336em9v43"></audio-player><blockquote><p>Com es diu mesa en català?</p></blockquote><audio-player class="audio-player" src="https://pub-503cb197f1134814ac02f257b9cde1c1.r2.dev/uploads/dictat-buscar-habitatge.mp3" controls="true" data-color-play="#333" data-color-bar="#888" data-max-width="100%" data-id="fl-audio-4i336em9v43"></audio-player><blockquote><p>Què vol dir rentadora?</p></blockquote><audio-player class="audio-player" src="https://pub-503cb197f1134814ac02f257b9cde1c1.r2.dev/uploads/dictat-buscar-habitatge.mp3" controls="true" data-color-play="#333" data-color-bar="#888" data-max-width="100%" data-id="fl-audio-4i336em9v43"></audio-player><blockquote><p>Com s\'escriu &nbsp;bolígraf?</p></blockquote><audio-player class="audio-player" src="https://pub-503cb197f1134814ac02f257b9cde1c1.r2.dev/uploads/dictat-buscar-habitatge.mp3" controls="true" data-color-play="#333" data-color-bar="#888" data-max-width="100%" data-id="fl-audio-4i336em9v43"></audio-player><blockquote><p>Com es pronuncia això?</p></blockquote><audio-player class="audio-player" src="https://pub-503cb197f1134814ac02f257b9cde1c1.r2.dev/uploads/dictat-buscar-habitatge.mp3" controls="true" data-color-play="#333" data-color-bar="#888" data-max-width="100%" data-id="fl-audio-4i336em9v43"></audio-player><blockquote><p>- No t\'entenc. A poc a poc, si us plau.<br>- Ostres, perdona.</p></blockquote><audio-player class="audio-player" src="https://pub-503cb197f1134814ac02f257b9cde1c1.r2.dev/uploads/dictat-buscar-habitatge.mp3" controls="true" data-color-play="#333" data-color-bar="#888" data-max-width="100%" data-id="fl-audio-4i336em9v43"></audio-player><blockquote><p>- Com? M\'ho pots repetir, si us plau?<br>- Sí, i tant!</p></blockquote><audio-player class="audio-player" src="https://pub-503cb197f1134814ac02f257b9cde1c1.r2.dev/uploads/dictat-buscar-habitatge.mp3" controls="true" data-color-play="#333" data-color-bar="#888" data-max-width="100%" data-id="fl-audio-4i336em9v43"></audio-player><blockquote><p>- Gràcies.<br>- De res!</p></blockquote>',
308
+ content,
285
309
  editorProps: {
286
310
  attributes: {
287
311
  class: "fl-rich-text-content-doc",
@@ -518,9 +542,6 @@
518
542
  }
519
543
  }
520
544
 
521
- let fontSize = $state(16) as number;
522
- let lineHeight = $state(null) as number;
523
-
524
545
  function decrementFontSize() {
525
546
  fontSize = fontSize - 1;
526
547
  $editor
@@ -15,6 +15,7 @@
15
15
  export let playerType: "waveform" | "seekbar" = "waveform";
16
16
 
17
17
  let wavesurfer: WaveSurfer | null = null;
18
+ let waveformEl: HTMLDivElement | null = null;
18
19
  let wavesurferReady: boolean = false;
19
20
  let loading: boolean = true;
20
21
  let audio: any = null;
@@ -105,8 +106,12 @@
105
106
  if (WaveSurfer) {
106
107
 
107
108
  setTimeout(() => {
109
+ const identifier = "waveform-" + id;
110
+ console.log({ identifier });
111
+ console.log({ waveformEl });
112
+
108
113
  wavesurfer = WaveSurfer?.create({
109
- container: "#waveform-" + id,
114
+ container: waveformEl,
110
115
  height: 46,
111
116
  normalize: false,
112
117
  waveColor: "#b0b0b0",
@@ -296,6 +301,7 @@
296
301
  <!-- <span class="media-item-number">{index+1}</span> -->
297
302
 
298
303
  <div
304
+ bind:this={waveformEl}
299
305
  class="audio-player-wave"
300
306
  id={"waveform-" + id}
301
307
  class:hidden={mounted && !wavesurferReady}
@@ -0,0 +1,4 @@
1
+ export declare function getRichTextExtensions(options?: {
2
+ editable?: boolean;
3
+ customExtensions?: any[];
4
+ }): any[];
@@ -0,0 +1,66 @@
1
+ // getExtensions.ts
2
+ import StarterKit from "@tiptap/starter-kit";
3
+ import Highlight from "@tiptap/extension-highlight";
4
+ import TextAlign from "@tiptap/extension-text-align";
5
+ import Image from "@tiptap/extension-image";
6
+ import { ListKit } from "@tiptap/extension-list";
7
+ import { TextStyleKit } from "@tiptap/extension-text-style";
8
+ import { Mathematics } from "@tiptap/extension-mathematics";
9
+ import { TableKit } from "@tiptap/extension-table";
10
+ import { Audio } from "./extensions/Audio";
11
+ import { NodeLineHeight } from "./extensions/NodeLineHeight";
12
+ import { MediaGridExtension } from "./extensions/MediaGrid/MediaGrid";
13
+ import { MediaGridItemExtension } from "./extensions/MediaGrid/MediaGridItem";
14
+ import { CustomTableCell } from "./extensions/Table/CustomTableCell";
15
+ import { CustomTableHeader } from "./extensions/Table/CustomTableHeader";
16
+ import { EnhancedLink } from "./extensions/EnhancedLink";
17
+ export function getRichTextExtensions(options) {
18
+ const { editable = false, customExtensions = [] } = options ?? {};
19
+ return [
20
+ Highlight.configure({ multicolor: true }),
21
+ TextStyleKit,
22
+ StarterKit.configure({
23
+ trailingNode: false,
24
+ link: false,
25
+ bulletList: false,
26
+ listItem: false,
27
+ orderedList: false,
28
+ listKeymap: false,
29
+ }),
30
+ EnhancedLink,
31
+ Image.configure({ inline: true }),
32
+ Audio.configure({
33
+ HTMLAttributes: { class: "audio-player" },
34
+ }),
35
+ ListKit,
36
+ TextAlign.configure({
37
+ types: [
38
+ "heading",
39
+ "paragraph",
40
+ "bulletList",
41
+ "taskList",
42
+ "listItem",
43
+ "blockquote",
44
+ ],
45
+ }),
46
+ NodeLineHeight,
47
+ MediaGridExtension,
48
+ MediaGridItemExtension,
49
+ TableKit.configure({
50
+ table: {
51
+ HTMLAttributes: { class: "fl-table-editable" },
52
+ resizable: true,
53
+ },
54
+ tableCell: false,
55
+ tableHeader: false,
56
+ }),
57
+ CustomTableCell.configure({
58
+ HTMLAttributes: { class: "fl-cell-editable" },
59
+ }),
60
+ CustomTableHeader.configure({
61
+ HTMLAttributes: { class: "fl-cell-editable" },
62
+ }),
63
+ !editable ? Mathematics : null,
64
+ ...customExtensions,
65
+ ];
66
+ }
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  import RichText from './RichText.svelte';
2
- export { RichText };
2
+ import { renderHTMLFromJSON } from './renderRichText';
3
+ export { RichText, renderHTMLFromJSON };
package/dist/index.js CHANGED
@@ -1,2 +1,3 @@
1
1
  import RichText from './RichText.svelte';
2
- export { RichText };
2
+ import { renderHTMLFromJSON } from './renderRichText';
3
+ export { RichText, renderHTMLFromJSON };
@@ -0,0 +1,6 @@
1
+ interface RenderOptions {
2
+ json: any;
3
+ customExtensions?: any[];
4
+ }
5
+ export declare function renderHTMLFromJSON({ json, customExtensions }: RenderOptions): string;
6
+ export {};
@@ -0,0 +1,53 @@
1
+ import { renderToHTMLString, serializeChildrenToHTMLString } from "@tiptap/static-renderer";
2
+ import katex from "katex";
3
+ import { getRichTextExtensions } from "./getExtensions";
4
+ export function renderHTMLFromJSON({ json, customExtensions = [] }) {
5
+ const extensions = getRichTextExtensions({ customExtensions });
6
+ const html = renderToHTMLString({
7
+ extensions: extensions, // using your extensions
8
+ content: json,
9
+ options: {
10
+ nodeMapping: {
11
+ // Aquí le dices cómo renderizar el nodo "mathematics"
12
+ inlineMath({ node }) {
13
+ const latex = node.attrs.latex || '';
14
+ // Devuelve el HTML que quieres que se genere
15
+ return `<span class="math-inline">${katex.renderToString(latex, { throwOnError: false })}</span>`;
16
+ },
17
+ MediaGridComponent({ node, children }) {
18
+ const cols = node.attrs.cols || 2;
19
+ const gap = node.attrs.gap || '1rem';
20
+ const showIndicator = node.attrs.showIndicator || false;
21
+ const indicatorType = node.attrs.indicatorType || 'numeric';
22
+ return `
23
+ <div
24
+ class="fl-media-grid"
25
+ data-cols="${cols}"
26
+ data-gap="${gap}"
27
+ data-show-indicator="${showIndicator}"
28
+ data-indicator-type="${indicatorType}"
29
+ style="
30
+ --fl-grid-cols: ${cols};
31
+ --fl-grid-gap: ${gap};
32
+ ">
33
+ ${serializeChildrenToHTMLString(children)}
34
+ </div>`;
35
+ },
36
+ gridItem({ node, children }) {
37
+ return `<div class="fl-grid-item">${serializeChildrenToHTMLString(children)}</div>`;
38
+ },
39
+ audio({ node, children }) {
40
+ const src = node.attrs.src;
41
+ const controls = node.attrs.controls;
42
+ return `
43
+ <fl-audio-player
44
+ class="fl-audio-player"
45
+ id="fl-audio-player-${node.attrs.id}"
46
+ src="${src}">
47
+ </fl-audio-player>`;
48
+ }
49
+ }
50
+ }
51
+ });
52
+ return html;
53
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flexiui/svelte-rich-text",
3
- "version": "0.0.34",
3
+ "version": "0.0.36",
4
4
  "description": "A lightweight and flexible rich text editor component for Svelte",
5
5
  "keywords": [
6
6
  "svelte",