@flexiui/svelte-rich-text 0.0.36 → 0.0.38
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 +67 -31
- package/dist/extensions/AudioPlayer.svelte +66 -13
- package/dist/extensions/AudioPlayer.svelte.d.ts +11 -1
- package/dist/extensions/AudioPlayerWrapper.svelte +16 -7
- package/dist/renderRichText.d.ts +2 -1
- package/dist/renderRichText.js +48 -34
- package/package.json +1 -1
package/dist/extensions/Audio.js
CHANGED
|
@@ -39,59 +39,95 @@ 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
47
|
}),
|
|
48
48
|
},
|
|
49
|
-
|
|
50
|
-
default: '#
|
|
51
|
-
parseHTML: el => el.getAttribute('data-color
|
|
49
|
+
bgColor: {
|
|
50
|
+
default: '#8c8c8c45',
|
|
51
|
+
parseHTML: el => el.getAttribute('data-bg-color'),
|
|
52
52
|
renderHTML: attrs => ({
|
|
53
|
-
'data-color
|
|
53
|
+
'data-bg-color': attrs.bgColor,
|
|
54
|
+
}),
|
|
55
|
+
},
|
|
56
|
+
textColor: {
|
|
57
|
+
default: 'currentColor',
|
|
58
|
+
parseHTML: el => el.getAttribute('data-text-color'),
|
|
59
|
+
renderHTML: attrs => ({
|
|
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
|
+
playBtnBgColor: {
|
|
92
|
+
default: '#8d8d8d26',
|
|
93
|
+
parseHTML: el => el.getAttribute('data-play-btn-bg-color'),
|
|
94
|
+
renderHTML: attrs => ({
|
|
95
|
+
'data-play-btn-bg-color': attrs.playBtnBgColor,
|
|
96
|
+
}),
|
|
97
|
+
},
|
|
98
|
+
playBtnTextColor: {
|
|
99
|
+
default: 'currentColor',
|
|
100
|
+
parseHTML: el => el.getAttribute('data-play-btn-text-color'),
|
|
101
|
+
renderHTML: attrs => ({
|
|
102
|
+
'data-play-btn-text-color': attrs.playBtnTextColor,
|
|
103
|
+
}),
|
|
104
|
+
},
|
|
105
|
+
colorPlay: {
|
|
106
|
+
default: '#5d5d5dc9',
|
|
107
|
+
parseHTML: el => el.getAttribute('data-color-play'),
|
|
108
|
+
renderHTML: attrs => ({
|
|
109
|
+
'data-color-play': attrs.colorPlay,
|
|
54
110
|
}),
|
|
55
111
|
},
|
|
56
112
|
maxWidth: {
|
|
57
113
|
default: '100%',
|
|
58
|
-
parseHTML: el => el.getAttribute('data-max-width')
|
|
114
|
+
parseHTML: el => el.getAttribute('data-max-width'),
|
|
59
115
|
renderHTML: attrs => ({
|
|
60
116
|
'data-max-width': attrs.maxWidth,
|
|
61
117
|
}),
|
|
62
118
|
},
|
|
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
119
|
};
|
|
71
120
|
},
|
|
72
121
|
parseHTML() {
|
|
73
122
|
return [
|
|
74
123
|
{
|
|
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
|
-
},
|
|
124
|
+
tag: 'fl-audio-player',
|
|
89
125
|
},
|
|
90
126
|
];
|
|
91
127
|
},
|
|
92
128
|
renderHTML({ HTMLAttributes }) {
|
|
93
129
|
return [
|
|
94
|
-
'audio-player',
|
|
130
|
+
'fl-audio-player',
|
|
95
131
|
mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),
|
|
96
132
|
];
|
|
97
133
|
},
|
|
@@ -7,18 +7,29 @@
|
|
|
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 playBtnBgColor: string;
|
|
22
|
+
export let playBtnTextColor: string;
|
|
23
|
+
export let colorPlay: string;
|
|
24
|
+
export let maxWidth: string;
|
|
16
25
|
|
|
17
26
|
let wavesurfer: WaveSurfer | null = null;
|
|
18
27
|
let waveformEl: HTMLDivElement | null = null;
|
|
19
28
|
let wavesurferReady: boolean = false;
|
|
20
29
|
let loading: boolean = true;
|
|
21
|
-
let audio: any = null;
|
|
30
|
+
// let audio: any = null;
|
|
31
|
+
let audio: HTMLAudioElement | null = null;
|
|
32
|
+
|
|
22
33
|
let playing: boolean = false;
|
|
23
34
|
let mounted: boolean = false;
|
|
24
35
|
let seekbarEl: HTMLDivElement | null = null;
|
|
@@ -31,6 +42,8 @@
|
|
|
31
42
|
let audioDuration: number = 0;
|
|
32
43
|
let audioCurrentTime: number = 0;
|
|
33
44
|
|
|
45
|
+
id = id + "-" + Math.random().toString(36).substring(2, 15);
|
|
46
|
+
|
|
34
47
|
function formatTime(seconds: number) {
|
|
35
48
|
if (isNaN(seconds) || seconds < 0) return "0:00";
|
|
36
49
|
|
|
@@ -152,10 +165,10 @@
|
|
|
152
165
|
// wavesurfer?.stop();
|
|
153
166
|
// });
|
|
154
167
|
|
|
155
|
-
audio = new Audio(src);
|
|
168
|
+
// audio = new Audio(src);
|
|
169
|
+
// audio.load();
|
|
156
170
|
audio.volume = volume;
|
|
157
171
|
audio.preload = "auto";
|
|
158
|
-
audio.load();
|
|
159
172
|
|
|
160
173
|
audio.addEventListener("loadedmetadata", () => {
|
|
161
174
|
audioDuration = audio.duration;
|
|
@@ -173,6 +186,19 @@
|
|
|
173
186
|
}
|
|
174
187
|
});
|
|
175
188
|
|
|
189
|
+
audio.onended = () => {
|
|
190
|
+
playing = false;
|
|
191
|
+
console.log("Audio playback ended");
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
audio.addEventListener("play", () => {
|
|
195
|
+
playing = true;
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
audio.addEventListener("pause", () => {
|
|
199
|
+
playing = false;
|
|
200
|
+
});
|
|
201
|
+
|
|
176
202
|
setTimeout(() => {
|
|
177
203
|
loading = false;
|
|
178
204
|
}, 500);
|
|
@@ -262,7 +288,20 @@
|
|
|
262
288
|
}
|
|
263
289
|
</script>
|
|
264
290
|
|
|
265
|
-
<div
|
|
291
|
+
<div
|
|
292
|
+
class="audio-player"
|
|
293
|
+
{id}
|
|
294
|
+
class:playing
|
|
295
|
+
style={`
|
|
296
|
+
--player-bg-color: ${bgColor};
|
|
297
|
+
--player-play-btn-bg: ${playBtnBgColor};
|
|
298
|
+
--player-play-btn-color: ${playBtnTextColor};
|
|
299
|
+
--player-primary-color: ${accentColor};
|
|
300
|
+
--player-progress-default-bg: ${accentColorPaused};
|
|
301
|
+
--player-text-color: ${textColor};
|
|
302
|
+
--player-border-radius: ${borderRadius};
|
|
303
|
+
`}
|
|
304
|
+
>
|
|
266
305
|
<button
|
|
267
306
|
onclick={() => togglePlayPause()}
|
|
268
307
|
type="button"
|
|
@@ -441,11 +480,12 @@
|
|
|
441
480
|
</div>
|
|
442
481
|
</div>
|
|
443
482
|
|
|
444
|
-
<!--
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
{
|
|
483
|
+
<!-- Reproductor de audo nativo -->
|
|
484
|
+
<audio
|
|
485
|
+
bind:this={audio}
|
|
486
|
+
src={src}
|
|
487
|
+
id={'native-audio-' + id}
|
|
488
|
+
></audio>
|
|
449
489
|
</div>
|
|
450
490
|
|
|
451
491
|
<style>
|
|
@@ -456,13 +496,14 @@
|
|
|
456
496
|
|
|
457
497
|
.audio-player {
|
|
458
498
|
--player-primary-color: #5e17eb;
|
|
459
|
-
--player-bg-color: #
|
|
499
|
+
--player-bg-color: #8c8c8c45;
|
|
460
500
|
--player-border-radius: 18px;
|
|
461
501
|
--player-seekbar-bg: #8d8d8d3a;
|
|
462
502
|
--player-seekbar-height: 6px;
|
|
463
503
|
--player-progress-default-bg: #f5f5f5;
|
|
464
504
|
--player-play-btn-bg: #8d8d8d26;
|
|
465
505
|
--player-play-btn-color: #fff;
|
|
506
|
+
--player-text-color: currentColor;
|
|
466
507
|
|
|
467
508
|
display: flex;
|
|
468
509
|
align-items: center;
|
|
@@ -472,6 +513,7 @@
|
|
|
472
513
|
padding: 12px;
|
|
473
514
|
width: 100%;
|
|
474
515
|
box-sizing: border-box;
|
|
516
|
+
color: var(--player-text-color);
|
|
475
517
|
|
|
476
518
|
&.playing {
|
|
477
519
|
.audio-player-wave {
|
|
@@ -496,6 +538,16 @@
|
|
|
496
538
|
border-radius: 100%;
|
|
497
539
|
outline-offset: 4px;
|
|
498
540
|
outline-color: var(--player-play-btn-bg);
|
|
541
|
+
cursor: pointer;
|
|
542
|
+
transition: filter 0.3s ease, transform 0.3s ease, background 0.3s ease;
|
|
543
|
+
|
|
544
|
+
&:hover {
|
|
545
|
+
/* background: var(--player-primary-color); */
|
|
546
|
+
&:not(.playing) {
|
|
547
|
+
filter: brightness(1.2);
|
|
548
|
+
}
|
|
549
|
+
transform: scale(1.06);
|
|
550
|
+
}
|
|
499
551
|
|
|
500
552
|
svg {
|
|
501
553
|
width: 20px;
|
|
@@ -587,7 +639,7 @@
|
|
|
587
639
|
margin-right: 4px;
|
|
588
640
|
|
|
589
641
|
&:hover {
|
|
590
|
-
background: #
|
|
642
|
+
background: #7a7a7a17;
|
|
591
643
|
}
|
|
592
644
|
|
|
593
645
|
&:hover .audio-player-seekbar,
|
|
@@ -621,6 +673,7 @@
|
|
|
621
673
|
border: none;
|
|
622
674
|
padding: 4px;
|
|
623
675
|
background: #0d121600;
|
|
676
|
+
color: currentColor;
|
|
624
677
|
border-radius: 100%;
|
|
625
678
|
height: 36px;
|
|
626
679
|
width: 36px;
|
|
@@ -1,11 +1,21 @@
|
|
|
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
|
+
playBtnBgColor: string;
|
|
16
|
+
playBtnTextColor: string;
|
|
17
|
+
colorPlay: string;
|
|
18
|
+
maxWidth: string;
|
|
9
19
|
};
|
|
10
20
|
events: {
|
|
11
21
|
[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,20 @@
|
|
|
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
|
+
playBtnBgColor={attrs.playBtnBgColor}
|
|
85
|
+
playBtnTextColor={attrs.playBtnTextColor}
|
|
86
|
+
colorPlay={attrs.colorPlay}
|
|
87
|
+
maxWidth={attrs.maxWidth}
|
|
88
|
+
></AudioPlayer>
|
|
80
89
|
|
|
81
90
|
{#if selected}
|
|
82
91
|
<span
|
|
@@ -93,7 +102,7 @@
|
|
|
93
102
|
</NodeViewWrapper>
|
|
94
103
|
|
|
95
104
|
<style>
|
|
96
|
-
.fl-audio-player {
|
|
105
|
+
.fl-audio-player-container {
|
|
97
106
|
display: flex;
|
|
98
107
|
align-items: center;
|
|
99
108
|
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,43 @@ 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, playBtnBgColor, playBtnTextColor, 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
|
+
playBtnBgColor="${playBtnBgColor}"
|
|
45
|
+
playBtnTextColor="${playBtnTextColor}"
|
|
46
|
+
maxWidth="${maxWidth}"
|
|
47
|
+
colorPlay="${colorPlay}"
|
|
48
|
+
>
|
|
49
|
+
</fl-audio-player>
|
|
50
|
+
`;
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
export function renderHTMLFromJSON({ json, customExtensions = [], customNodeMapping = {} }) {
|
|
54
|
+
const extensions = getRichTextExtensions({ customExtensions });
|
|
55
|
+
const finalNodeMapping = {
|
|
56
|
+
...nodeMapping,
|
|
57
|
+
...customNodeMapping,
|
|
58
|
+
};
|
|
59
|
+
const html = renderToHTMLString({
|
|
60
|
+
extensions: extensions, // using your extensions
|
|
61
|
+
content: json,
|
|
62
|
+
options: {
|
|
63
|
+
nodeMapping: finalNodeMapping,
|
|
50
64
|
}
|
|
51
65
|
});
|
|
52
66
|
return html;
|