@flexiui/svelte-rich-text 0.0.35 → 0.0.37
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 +118 -96
- package/dist/extensions/Audio.js +53 -31
- package/dist/extensions/AudioPlayer.svelte +70 -14
- package/dist/extensions/AudioPlayer.svelte.d.ts +9 -1
- package/dist/extensions/AudioPlayerWrapper.svelte +14 -7
- package/dist/getExtensions.d.ts +4 -0
- package/dist/getExtensions.js +66 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/renderRichText.d.ts +7 -0
- package/dist/renderRichText.js +65 -0
- package/package.json +1 -1
package/dist/RichText.svelte
CHANGED
|
@@ -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
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
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
|
-
|
|
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
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
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)",
|
|
@@ -517,9 +542,6 @@
|
|
|
517
542
|
}
|
|
518
543
|
}
|
|
519
544
|
|
|
520
|
-
let fontSize = $state(16) as number;
|
|
521
|
-
let lineHeight = $state(null) as number;
|
|
522
|
-
|
|
523
545
|
function decrementFontSize() {
|
|
524
546
|
fontSize = fontSize - 1;
|
|
525
547
|
$editor
|
package/dist/extensions/Audio.js
CHANGED
|
@@ -39,59 +39,81 @@ export const Audio = Node.create({
|
|
|
39
39
|
parseHTML: el => el.hasAttribute('loop'),
|
|
40
40
|
renderHTML: attrs => (attrs.loop ? { loop: true } : {}),
|
|
41
41
|
},
|
|
42
|
-
|
|
43
|
-
default:
|
|
44
|
-
parseHTML: el => el.getAttribute('data-
|
|
42
|
+
id: {
|
|
43
|
+
default: `fl-audio-player-${Math.random().toString(36).substring(2, 15)}`,
|
|
44
|
+
parseHTML: el => el.getAttribute('data-id') || null,
|
|
45
45
|
renderHTML: attrs => ({
|
|
46
|
-
'data-
|
|
46
|
+
'data-id': attrs.id,
|
|
47
|
+
}),
|
|
48
|
+
},
|
|
49
|
+
bgColor: {
|
|
50
|
+
default: '#8c8c8c45',
|
|
51
|
+
parseHTML: el => el.getAttribute('data-bg-color'),
|
|
52
|
+
renderHTML: attrs => ({
|
|
53
|
+
'data-bg-color': attrs.bgColor,
|
|
47
54
|
}),
|
|
48
55
|
},
|
|
49
|
-
|
|
50
|
-
default: '
|
|
51
|
-
parseHTML: el => el.getAttribute('data-color
|
|
56
|
+
textColor: {
|
|
57
|
+
default: 'currentColor',
|
|
58
|
+
parseHTML: el => el.getAttribute('data-text-color'),
|
|
52
59
|
renderHTML: attrs => ({
|
|
53
|
-
'data-color
|
|
60
|
+
'data-text-color': attrs.textColor,
|
|
61
|
+
}),
|
|
62
|
+
},
|
|
63
|
+
borderRadius: {
|
|
64
|
+
default: '18px',
|
|
65
|
+
parseHTML: el => el.getAttribute('data-border-radius'),
|
|
66
|
+
renderHTML: attrs => ({
|
|
67
|
+
'data-border-radius': attrs.borderRadius,
|
|
68
|
+
}),
|
|
69
|
+
},
|
|
70
|
+
accentColor: {
|
|
71
|
+
default: '#5e17eb',
|
|
72
|
+
parseHTML: el => el.getAttribute('data-accent-color'),
|
|
73
|
+
renderHTML: attrs => ({
|
|
74
|
+
'data-accent-color': attrs.accentColor,
|
|
75
|
+
}),
|
|
76
|
+
},
|
|
77
|
+
accentColorPaused: {
|
|
78
|
+
default: '#fff',
|
|
79
|
+
parseHTML: el => el.getAttribute('data-accent-color-paused'),
|
|
80
|
+
renderHTML: attrs => ({
|
|
81
|
+
'data-accent-color-paused': attrs.accentColorPaused,
|
|
82
|
+
}),
|
|
83
|
+
},
|
|
84
|
+
seekBarBgColor: {
|
|
85
|
+
default: '#8d8d8d3a',
|
|
86
|
+
parseHTML: el => el.getAttribute('data-seek-bar-bg-color'),
|
|
87
|
+
renderHTML: attrs => ({
|
|
88
|
+
'data-seek-bar-bg-color': attrs.seekBarBgColor,
|
|
89
|
+
}),
|
|
90
|
+
},
|
|
91
|
+
colorPlay: {
|
|
92
|
+
default: '#5d5d5dc9',
|
|
93
|
+
parseHTML: el => el.getAttribute('data-color-play'),
|
|
94
|
+
renderHTML: attrs => ({
|
|
95
|
+
'data-color-play': attrs.colorPlay,
|
|
54
96
|
}),
|
|
55
97
|
},
|
|
56
98
|
maxWidth: {
|
|
57
99
|
default: '100%',
|
|
58
|
-
parseHTML: el => el.getAttribute('data-max-width')
|
|
100
|
+
parseHTML: el => el.getAttribute('data-max-width'),
|
|
59
101
|
renderHTML: attrs => ({
|
|
60
102
|
'data-max-width': attrs.maxWidth,
|
|
61
103
|
}),
|
|
62
104
|
},
|
|
63
|
-
id: {
|
|
64
|
-
default: "fl-audio-" + Math.random().toString(36).slice(2),
|
|
65
|
-
parseHTML: el => el.getAttribute('data-id') || null,
|
|
66
|
-
renderHTML: attrs => ({
|
|
67
|
-
'data-id': attrs.id,
|
|
68
|
-
}),
|
|
69
|
-
}
|
|
70
105
|
};
|
|
71
106
|
},
|
|
72
107
|
parseHTML() {
|
|
73
108
|
return [
|
|
74
109
|
{
|
|
75
|
-
tag: 'audio-player',
|
|
76
|
-
getAttrs: el => {
|
|
77
|
-
if (!(el instanceof HTMLElement))
|
|
78
|
-
return false;
|
|
79
|
-
return {
|
|
80
|
-
src: el.getAttribute('src'),
|
|
81
|
-
controls: el.hasAttribute('controls'),
|
|
82
|
-
autoplay: el.hasAttribute('autoplay'),
|
|
83
|
-
loop: el.hasAttribute('loop'),
|
|
84
|
-
colorPlay: el.getAttribute('data-color-play') || '#333',
|
|
85
|
-
colorBar: el.getAttribute('data-color-bar') || '#888',
|
|
86
|
-
maxWidth: el.getAttribute('data-max-width') || '100%',
|
|
87
|
-
};
|
|
88
|
-
},
|
|
110
|
+
tag: 'fl-audio-player',
|
|
89
111
|
},
|
|
90
112
|
];
|
|
91
113
|
},
|
|
92
114
|
renderHTML({ HTMLAttributes }) {
|
|
93
115
|
return [
|
|
94
|
-
'audio-player',
|
|
116
|
+
'fl-audio-player',
|
|
95
117
|
mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),
|
|
96
118
|
];
|
|
97
119
|
},
|
|
@@ -7,17 +7,27 @@
|
|
|
7
7
|
import WaveSurfer from "wavesurfer.js";
|
|
8
8
|
import { activeAudioId } from "./audioStore";
|
|
9
9
|
|
|
10
|
-
export let id: string
|
|
10
|
+
export let id: string;
|
|
11
11
|
export let src: string;
|
|
12
|
+
export let controls: any
|
|
12
13
|
export let showSeekbar: boolean = true;
|
|
13
14
|
export let config: any = {};
|
|
14
|
-
|
|
15
15
|
export let playerType: "waveform" | "seekbar" = "waveform";
|
|
16
|
+
export let bgColor: string;
|
|
17
|
+
export let textColor: string;
|
|
18
|
+
export let borderRadius: string;
|
|
19
|
+
export let accentColor: string;
|
|
20
|
+
export let accentColorPaused: string;
|
|
21
|
+
export let colorPlay: string;
|
|
22
|
+
export let maxWidth: string;
|
|
16
23
|
|
|
17
24
|
let wavesurfer: WaveSurfer | null = null;
|
|
25
|
+
let waveformEl: HTMLDivElement | null = null;
|
|
18
26
|
let wavesurferReady: boolean = false;
|
|
19
27
|
let loading: boolean = true;
|
|
20
|
-
let audio: any = null;
|
|
28
|
+
// let audio: any = null;
|
|
29
|
+
let audio: HTMLAudioElement | null = null;
|
|
30
|
+
|
|
21
31
|
let playing: boolean = false;
|
|
22
32
|
let mounted: boolean = false;
|
|
23
33
|
let seekbarEl: HTMLDivElement | null = null;
|
|
@@ -30,6 +40,8 @@
|
|
|
30
40
|
let audioDuration: number = 0;
|
|
31
41
|
let audioCurrentTime: number = 0;
|
|
32
42
|
|
|
43
|
+
id = id + "-" + Math.random().toString(36).substring(2, 15);
|
|
44
|
+
|
|
33
45
|
function formatTime(seconds: number) {
|
|
34
46
|
if (isNaN(seconds) || seconds < 0) return "0:00";
|
|
35
47
|
|
|
@@ -105,8 +117,12 @@
|
|
|
105
117
|
if (WaveSurfer) {
|
|
106
118
|
|
|
107
119
|
setTimeout(() => {
|
|
120
|
+
const identifier = "waveform-" + id;
|
|
121
|
+
console.log({ identifier });
|
|
122
|
+
console.log({ waveformEl });
|
|
123
|
+
|
|
108
124
|
wavesurfer = WaveSurfer?.create({
|
|
109
|
-
container:
|
|
125
|
+
container: waveformEl,
|
|
110
126
|
height: 46,
|
|
111
127
|
normalize: false,
|
|
112
128
|
waveColor: "#b0b0b0",
|
|
@@ -147,10 +163,10 @@
|
|
|
147
163
|
// wavesurfer?.stop();
|
|
148
164
|
// });
|
|
149
165
|
|
|
150
|
-
audio = new Audio(src);
|
|
166
|
+
// audio = new Audio(src);
|
|
167
|
+
// audio.load();
|
|
151
168
|
audio.volume = volume;
|
|
152
169
|
audio.preload = "auto";
|
|
153
|
-
audio.load();
|
|
154
170
|
|
|
155
171
|
audio.addEventListener("loadedmetadata", () => {
|
|
156
172
|
audioDuration = audio.duration;
|
|
@@ -168,6 +184,19 @@
|
|
|
168
184
|
}
|
|
169
185
|
});
|
|
170
186
|
|
|
187
|
+
audio.onended = () => {
|
|
188
|
+
playing = false;
|
|
189
|
+
console.log("Audio playback ended");
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
audio.addEventListener("play", () => {
|
|
193
|
+
playing = true;
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
audio.addEventListener("pause", () => {
|
|
197
|
+
playing = false;
|
|
198
|
+
});
|
|
199
|
+
|
|
171
200
|
setTimeout(() => {
|
|
172
201
|
loading = false;
|
|
173
202
|
}, 500);
|
|
@@ -257,7 +286,19 @@
|
|
|
257
286
|
}
|
|
258
287
|
</script>
|
|
259
288
|
|
|
260
|
-
<div
|
|
289
|
+
<div
|
|
290
|
+
class="audio-player"
|
|
291
|
+
{id}
|
|
292
|
+
class:playing
|
|
293
|
+
style={`
|
|
294
|
+
--player-bg-color: ${bgColor};
|
|
295
|
+
--player-play-btn-bg: ${colorPlay};
|
|
296
|
+
--player-primary-color: ${accentColor};
|
|
297
|
+
--player-progress-default-bg: ${accentColorPaused};
|
|
298
|
+
--player-text-color: ${textColor};
|
|
299
|
+
--player-border-radius: ${borderRadius};
|
|
300
|
+
`}
|
|
301
|
+
>
|
|
261
302
|
<button
|
|
262
303
|
onclick={() => togglePlayPause()}
|
|
263
304
|
type="button"
|
|
@@ -296,6 +337,7 @@
|
|
|
296
337
|
<!-- <span class="media-item-number">{index+1}</span> -->
|
|
297
338
|
|
|
298
339
|
<div
|
|
340
|
+
bind:this={waveformEl}
|
|
299
341
|
class="audio-player-wave"
|
|
300
342
|
id={"waveform-" + id}
|
|
301
343
|
class:hidden={mounted && !wavesurferReady}
|
|
@@ -435,11 +477,12 @@
|
|
|
435
477
|
</div>
|
|
436
478
|
</div>
|
|
437
479
|
|
|
438
|
-
<!--
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
{
|
|
480
|
+
<!-- Reproductor de audo nativo -->
|
|
481
|
+
<audio
|
|
482
|
+
bind:this={audio}
|
|
483
|
+
src={src}
|
|
484
|
+
id={'native-audio-' + id}
|
|
485
|
+
></audio>
|
|
443
486
|
</div>
|
|
444
487
|
|
|
445
488
|
<style>
|
|
@@ -450,13 +493,14 @@
|
|
|
450
493
|
|
|
451
494
|
.audio-player {
|
|
452
495
|
--player-primary-color: #5e17eb;
|
|
453
|
-
--player-bg-color: #
|
|
496
|
+
--player-bg-color: #8c8c8c45;
|
|
454
497
|
--player-border-radius: 18px;
|
|
455
498
|
--player-seekbar-bg: #8d8d8d3a;
|
|
456
499
|
--player-seekbar-height: 6px;
|
|
457
500
|
--player-progress-default-bg: #f5f5f5;
|
|
458
501
|
--player-play-btn-bg: #8d8d8d26;
|
|
459
502
|
--player-play-btn-color: #fff;
|
|
503
|
+
--player-text-color: currentColor;
|
|
460
504
|
|
|
461
505
|
display: flex;
|
|
462
506
|
align-items: center;
|
|
@@ -466,6 +510,7 @@
|
|
|
466
510
|
padding: 12px;
|
|
467
511
|
width: 100%;
|
|
468
512
|
box-sizing: border-box;
|
|
513
|
+
color: var(--player-text-color);
|
|
469
514
|
|
|
470
515
|
&.playing {
|
|
471
516
|
.audio-player-wave {
|
|
@@ -490,6 +535,16 @@
|
|
|
490
535
|
border-radius: 100%;
|
|
491
536
|
outline-offset: 4px;
|
|
492
537
|
outline-color: var(--player-play-btn-bg);
|
|
538
|
+
cursor: pointer;
|
|
539
|
+
transition: filter 0.3s ease, transform 0.3s ease, background 0.3s ease;
|
|
540
|
+
|
|
541
|
+
&:hover {
|
|
542
|
+
/* background: var(--player-primary-color); */
|
|
543
|
+
&:not(.playing) {
|
|
544
|
+
filter: brightness(1.2);
|
|
545
|
+
}
|
|
546
|
+
transform: scale(1.06);
|
|
547
|
+
}
|
|
493
548
|
|
|
494
549
|
svg {
|
|
495
550
|
width: 20px;
|
|
@@ -581,7 +636,7 @@
|
|
|
581
636
|
margin-right: 4px;
|
|
582
637
|
|
|
583
638
|
&:hover {
|
|
584
|
-
background: #
|
|
639
|
+
background: #7a7a7a17;
|
|
585
640
|
}
|
|
586
641
|
|
|
587
642
|
&:hover .audio-player-seekbar,
|
|
@@ -615,6 +670,7 @@
|
|
|
615
670
|
border: none;
|
|
616
671
|
padding: 4px;
|
|
617
672
|
background: #0d121600;
|
|
673
|
+
color: currentColor;
|
|
618
674
|
border-radius: 100%;
|
|
619
675
|
height: 36px;
|
|
620
676
|
width: 36px;
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
import { SvelteComponentTyped } from "svelte";
|
|
2
2
|
declare const __propDef: {
|
|
3
3
|
props: {
|
|
4
|
-
id
|
|
4
|
+
id: string;
|
|
5
5
|
src: string;
|
|
6
|
+
controls: any;
|
|
6
7
|
showSeekbar?: boolean;
|
|
7
8
|
config?: any;
|
|
8
9
|
playerType?: "waveform" | "seekbar";
|
|
10
|
+
bgColor: string;
|
|
11
|
+
textColor: string;
|
|
12
|
+
borderRadius: string;
|
|
13
|
+
accentColor: string;
|
|
14
|
+
accentColorPaused: string;
|
|
15
|
+
colorPlay: string;
|
|
16
|
+
maxWidth: string;
|
|
9
17
|
};
|
|
10
18
|
events: {
|
|
11
19
|
[evt: string]: CustomEvent<any>;
|
|
@@ -62,12 +62,8 @@
|
|
|
62
62
|
<NodeViewWrapper class="fl-audio-player-wrapper">
|
|
63
63
|
<div
|
|
64
64
|
bind:this={targetElement}
|
|
65
|
-
class="fl-audio-player"
|
|
65
|
+
class="fl-audio-player-container"
|
|
66
66
|
class:selected={selected}
|
|
67
|
-
style="
|
|
68
|
-
--color-play: {attrs.colorPlay};
|
|
69
|
-
--color-bar: {attrs.colorBar};
|
|
70
|
-
"
|
|
71
67
|
>
|
|
72
68
|
<!-- <audio
|
|
73
69
|
src={attrs.src}
|
|
@@ -76,7 +72,18 @@
|
|
|
76
72
|
loop={attrs.loop}
|
|
77
73
|
></audio> -->
|
|
78
74
|
|
|
79
|
-
<AudioPlayer
|
|
75
|
+
<AudioPlayer
|
|
76
|
+
id={attrs.id}
|
|
77
|
+
controls={true}
|
|
78
|
+
src={attrs.src}
|
|
79
|
+
bgColor={attrs.bgColor}
|
|
80
|
+
textColor={attrs.textColor}
|
|
81
|
+
borderRadius={attrs.borderRadius}
|
|
82
|
+
accentColor={attrs.accentColor}
|
|
83
|
+
accentColorPaused={attrs.accentColorPaused}
|
|
84
|
+
colorPlay={attrs.colorPlay}
|
|
85
|
+
maxWidth={attrs.maxWidth}
|
|
86
|
+
></AudioPlayer>
|
|
80
87
|
|
|
81
88
|
{#if selected}
|
|
82
89
|
<span
|
|
@@ -93,7 +100,7 @@
|
|
|
93
100
|
</NodeViewWrapper>
|
|
94
101
|
|
|
95
102
|
<style>
|
|
96
|
-
.fl-audio-player {
|
|
103
|
+
.fl-audio-player-container {
|
|
97
104
|
display: flex;
|
|
98
105
|
align-items: center;
|
|
99
106
|
position: relative;
|
|
@@ -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
package/dist/index.js
CHANGED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { renderToHTMLString, serializeChildrenToHTMLString } from "@tiptap/static-renderer";
|
|
2
|
+
import katex from "katex";
|
|
3
|
+
import { getRichTextExtensions } from "./getExtensions";
|
|
4
|
+
const nodeMapping = {
|
|
5
|
+
inlineMath({ node }) {
|
|
6
|
+
const latex = node.attrs.latex || '';
|
|
7
|
+
return `<span class="math-inline">${katex.renderToString(latex, { throwOnError: false })}</span>`;
|
|
8
|
+
},
|
|
9
|
+
MediaGridComponent({ node, children }) {
|
|
10
|
+
const cols = node.attrs.cols || 2;
|
|
11
|
+
const gap = node.attrs.gap || '1rem';
|
|
12
|
+
const showIndicator = node.attrs.showIndicator || false;
|
|
13
|
+
const indicatorType = node.attrs.indicatorType || 'numeric';
|
|
14
|
+
return `
|
|
15
|
+
<div
|
|
16
|
+
class="fl-media-grid"
|
|
17
|
+
data-cols="${cols}"
|
|
18
|
+
data-gap="${gap}"
|
|
19
|
+
data-show-indicator="${showIndicator}"
|
|
20
|
+
data-indicator-type="${indicatorType}"
|
|
21
|
+
style="
|
|
22
|
+
--fl-grid-cols: ${cols};
|
|
23
|
+
--fl-grid-gap: ${gap};
|
|
24
|
+
">
|
|
25
|
+
${serializeChildrenToHTMLString(children)}
|
|
26
|
+
</div>`;
|
|
27
|
+
},
|
|
28
|
+
gridItem({ node, children }) {
|
|
29
|
+
return `<div class="fl-grid-item">${serializeChildrenToHTMLString(children)}</div>`;
|
|
30
|
+
},
|
|
31
|
+
audio({ node, children }) {
|
|
32
|
+
const { id, src, controls, bgColor, textColor, borderRadius, accentColor, accentColorPaused, maxWidth, colorPlay } = node.attrs;
|
|
33
|
+
return `
|
|
34
|
+
<fl-audio-player
|
|
35
|
+
class="fl-audio-player"
|
|
36
|
+
id="${id}"
|
|
37
|
+
src="${src}"
|
|
38
|
+
controls="${controls}"
|
|
39
|
+
bgColor="${bgColor}"
|
|
40
|
+
textColor="${textColor}"
|
|
41
|
+
borderRadius="${borderRadius}"
|
|
42
|
+
accentColor="${accentColor}"
|
|
43
|
+
accentColorPaused="${accentColorPaused}"
|
|
44
|
+
maxWidth="${maxWidth}"
|
|
45
|
+
colorPlay="${colorPlay}"
|
|
46
|
+
>
|
|
47
|
+
</fl-audio-player>
|
|
48
|
+
`;
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
export function renderHTMLFromJSON({ json, customExtensions = [], customNodeMapping = {} }) {
|
|
52
|
+
const extensions = getRichTextExtensions({ customExtensions });
|
|
53
|
+
const finalNodeMapping = {
|
|
54
|
+
...nodeMapping,
|
|
55
|
+
...customNodeMapping,
|
|
56
|
+
};
|
|
57
|
+
const html = renderToHTMLString({
|
|
58
|
+
extensions: extensions, // using your extensions
|
|
59
|
+
content: json,
|
|
60
|
+
options: {
|
|
61
|
+
nodeMapping: finalNodeMapping,
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
return html;
|
|
65
|
+
}
|