@flexiui/svelte-rich-text 0.0.36 → 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/extensions/Audio.js +53 -31
- package/dist/extensions/AudioPlayer.svelte +63 -13
- package/dist/extensions/AudioPlayer.svelte.d.ts +9 -1
- package/dist/extensions/AudioPlayerWrapper.svelte +14 -7
- package/dist/renderRichText.d.ts +2 -1
- package/dist/renderRichText.js +46 -34
- package/package.json +1 -1
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,18 +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;
|
|
18
25
|
let waveformEl: HTMLDivElement | null = null;
|
|
19
26
|
let wavesurferReady: boolean = false;
|
|
20
27
|
let loading: boolean = true;
|
|
21
|
-
let audio: any = null;
|
|
28
|
+
// let audio: any = null;
|
|
29
|
+
let audio: HTMLAudioElement | null = null;
|
|
30
|
+
|
|
22
31
|
let playing: boolean = false;
|
|
23
32
|
let mounted: boolean = false;
|
|
24
33
|
let seekbarEl: HTMLDivElement | null = null;
|
|
@@ -31,6 +40,8 @@
|
|
|
31
40
|
let audioDuration: number = 0;
|
|
32
41
|
let audioCurrentTime: number = 0;
|
|
33
42
|
|
|
43
|
+
id = id + "-" + Math.random().toString(36).substring(2, 15);
|
|
44
|
+
|
|
34
45
|
function formatTime(seconds: number) {
|
|
35
46
|
if (isNaN(seconds) || seconds < 0) return "0:00";
|
|
36
47
|
|
|
@@ -152,10 +163,10 @@
|
|
|
152
163
|
// wavesurfer?.stop();
|
|
153
164
|
// });
|
|
154
165
|
|
|
155
|
-
audio = new Audio(src);
|
|
166
|
+
// audio = new Audio(src);
|
|
167
|
+
// audio.load();
|
|
156
168
|
audio.volume = volume;
|
|
157
169
|
audio.preload = "auto";
|
|
158
|
-
audio.load();
|
|
159
170
|
|
|
160
171
|
audio.addEventListener("loadedmetadata", () => {
|
|
161
172
|
audioDuration = audio.duration;
|
|
@@ -173,6 +184,19 @@
|
|
|
173
184
|
}
|
|
174
185
|
});
|
|
175
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
|
+
|
|
176
200
|
setTimeout(() => {
|
|
177
201
|
loading = false;
|
|
178
202
|
}, 500);
|
|
@@ -262,7 +286,19 @@
|
|
|
262
286
|
}
|
|
263
287
|
</script>
|
|
264
288
|
|
|
265
|
-
<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
|
+
>
|
|
266
302
|
<button
|
|
267
303
|
onclick={() => togglePlayPause()}
|
|
268
304
|
type="button"
|
|
@@ -441,11 +477,12 @@
|
|
|
441
477
|
</div>
|
|
442
478
|
</div>
|
|
443
479
|
|
|
444
|
-
<!--
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
{
|
|
480
|
+
<!-- Reproductor de audo nativo -->
|
|
481
|
+
<audio
|
|
482
|
+
bind:this={audio}
|
|
483
|
+
src={src}
|
|
484
|
+
id={'native-audio-' + id}
|
|
485
|
+
></audio>
|
|
449
486
|
</div>
|
|
450
487
|
|
|
451
488
|
<style>
|
|
@@ -456,13 +493,14 @@
|
|
|
456
493
|
|
|
457
494
|
.audio-player {
|
|
458
495
|
--player-primary-color: #5e17eb;
|
|
459
|
-
--player-bg-color: #
|
|
496
|
+
--player-bg-color: #8c8c8c45;
|
|
460
497
|
--player-border-radius: 18px;
|
|
461
498
|
--player-seekbar-bg: #8d8d8d3a;
|
|
462
499
|
--player-seekbar-height: 6px;
|
|
463
500
|
--player-progress-default-bg: #f5f5f5;
|
|
464
501
|
--player-play-btn-bg: #8d8d8d26;
|
|
465
502
|
--player-play-btn-color: #fff;
|
|
503
|
+
--player-text-color: currentColor;
|
|
466
504
|
|
|
467
505
|
display: flex;
|
|
468
506
|
align-items: center;
|
|
@@ -472,6 +510,7 @@
|
|
|
472
510
|
padding: 12px;
|
|
473
511
|
width: 100%;
|
|
474
512
|
box-sizing: border-box;
|
|
513
|
+
color: var(--player-text-color);
|
|
475
514
|
|
|
476
515
|
&.playing {
|
|
477
516
|
.audio-player-wave {
|
|
@@ -496,6 +535,16 @@
|
|
|
496
535
|
border-radius: 100%;
|
|
497
536
|
outline-offset: 4px;
|
|
498
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
|
+
}
|
|
499
548
|
|
|
500
549
|
svg {
|
|
501
550
|
width: 20px;
|
|
@@ -587,7 +636,7 @@
|
|
|
587
636
|
margin-right: 4px;
|
|
588
637
|
|
|
589
638
|
&:hover {
|
|
590
|
-
background: #
|
|
639
|
+
background: #7a7a7a17;
|
|
591
640
|
}
|
|
592
641
|
|
|
593
642
|
&:hover .audio-player-seekbar,
|
|
@@ -621,6 +670,7 @@
|
|
|
621
670
|
border: none;
|
|
622
671
|
padding: 4px;
|
|
623
672
|
background: #0d121600;
|
|
673
|
+
color: currentColor;
|
|
624
674
|
border-radius: 100%;
|
|
625
675
|
height: 36px;
|
|
626
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;
|
package/dist/renderRichText.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
interface RenderOptions {
|
|
2
2
|
json: any;
|
|
3
3
|
customExtensions?: any[];
|
|
4
|
+
customNodeMapping?: any;
|
|
4
5
|
}
|
|
5
|
-
export declare function renderHTMLFromJSON({ json, customExtensions }: RenderOptions): string;
|
|
6
|
+
export declare function renderHTMLFromJSON({ json, customExtensions, customNodeMapping }: RenderOptions): string;
|
|
6
7
|
export {};
|
package/dist/renderRichText.js
CHANGED
|
@@ -1,25 +1,17 @@
|
|
|
1
1
|
import { renderToHTMLString, serializeChildrenToHTMLString } from "@tiptap/static-renderer";
|
|
2
2
|
import katex from "katex";
|
|
3
3
|
import { getRichTextExtensions } from "./getExtensions";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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 `
|
|
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 `
|
|
23
15
|
<div
|
|
24
16
|
class="fl-media-grid"
|
|
25
17
|
data-cols="${cols}"
|
|
@@ -32,21 +24,41 @@ export function renderHTMLFromJSON({ json, customExtensions = [] }) {
|
|
|
32
24
|
">
|
|
33
25
|
${serializeChildrenToHTMLString(children)}
|
|
34
26
|
</div>`;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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,
|
|
50
62
|
}
|
|
51
63
|
});
|
|
52
64
|
return html;
|