@flexiui/svelte-rich-text 0.0.24 → 0.0.26

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.
Files changed (35) hide show
  1. package/dist/AudioPlayerSimple.svelte +7 -0
  2. package/dist/AudioPlayerSimple.svelte.d.ts +25 -0
  3. package/dist/RichText.svelte +110 -5
  4. package/dist/extensions/Audio.d.ts +29 -0
  5. package/dist/extensions/Audio.js +123 -0
  6. package/dist/extensions/AudioPlayer.svelte +622 -0
  7. package/dist/extensions/AudioPlayer.svelte.d.ts +20 -0
  8. package/dist/extensions/AudioPlayerWrapper.svelte +123 -0
  9. package/dist/extensions/AudioPlayerWrapper.svelte.d.ts +21 -0
  10. package/dist/extensions/MediaGrid/MediaGrid.d.ts +2 -0
  11. package/dist/extensions/MediaGrid/MediaGrid.js +90 -0
  12. package/dist/extensions/MediaGrid/MediaGrid.svelte +265 -0
  13. package/dist/extensions/MediaGrid/MediaGrid.svelte.d.ts +14 -0
  14. package/dist/extensions/MediaGrid/MediaGridItem.d.ts +2 -0
  15. package/dist/extensions/MediaGrid/MediaGridItem.js +24 -0
  16. package/dist/extensions/MediaGrid/MediaGridItem.svelte +484 -0
  17. package/dist/extensions/MediaGrid/MediaGridItem.svelte.d.ts +14 -0
  18. package/dist/extensions/MediaGrid/auth-service.d.ts +1 -0
  19. package/dist/extensions/MediaGrid/auth-service.js +11 -0
  20. package/dist/extensions/Table/CustomTableCell.d.ts +19 -0
  21. package/dist/extensions/Table/CustomTableCell.js +86 -0
  22. package/dist/extensions/Table/CustomTableHeader.d.ts +1 -0
  23. package/dist/extensions/Table/CustomTableHeader.js +33 -0
  24. package/dist/extensions/Table/TableCellControls.d.ts +0 -0
  25. package/dist/extensions/Table/TableCellControls.js +0 -0
  26. package/dist/extensions/Table/TableCellNodeView.svelte +576 -0
  27. package/dist/extensions/Table/TableCellNodeView.svelte.d.ts +14 -0
  28. package/dist/extensions/Table/TableCellSelection.d.ts +12 -0
  29. package/dist/extensions/Table/TableCellSelection.js +35 -0
  30. package/dist/extensions/audioStore.d.ts +1 -0
  31. package/dist/extensions/audioStore.js +2 -0
  32. package/dist/extensions/extensions.d.ts +7 -0
  33. package/dist/extensions/extensions.js +86 -0
  34. package/dist/styles.css +182 -0
  35. package/package.json +2 -1
@@ -0,0 +1,123 @@
1
+ <script lang="ts">
2
+ import { NodeViewWrapper } from 'svelte-tiptap'
3
+ import type { NodeViewProps } from '@tiptap/core'
4
+ import AudioPlayer from './AudioPlayer.svelte';
5
+ import { onDestroy } from 'svelte';
6
+
7
+ export let node: NodeViewProps['node']
8
+ export let selected: NodeViewProps['selected'] // 👈 aquí
9
+ export let getPos: NodeViewProps['getPos']
10
+ export let editor: NodeViewProps['editor']
11
+
12
+ const attrs = node.attrs
13
+
14
+ export let targetElement: any = null;
15
+
16
+ let minWidth = 316;
17
+ let maxWidth = "100%";
18
+
19
+ let startX = 0;
20
+ let startWidth = 0;
21
+
22
+ function onMouseDown(e: MouseEvent) {
23
+ e.preventDefault();
24
+
25
+ if (!targetElement) return;
26
+
27
+ startX = e.clientX;
28
+ startWidth = targetElement.offsetWidth;
29
+
30
+ window.addEventListener("mousemove", onMouseMove);
31
+ window.addEventListener("mouseup", onMouseUp);
32
+ }
33
+
34
+ function onMouseMove(e: MouseEvent) {
35
+ if (!targetElement) return;
36
+
37
+ // 🔥 Obtenemos el DOM node de ProseMirror
38
+ const domNode = editor.view.nodeDOM(getPos()) as HTMLElement
39
+
40
+ const deltaX = (e.clientX - startX);
41
+ let newWidth = startWidth + deltaX;
42
+
43
+ if (newWidth < minWidth) {
44
+ newWidth = minWidth;
45
+ }
46
+
47
+ domNode.style.maxWidth = `${newWidth}px`;
48
+
49
+ }
50
+
51
+ function onMouseUp() {
52
+ window.removeEventListener("mousemove", onMouseMove);
53
+ window.removeEventListener("mouseup", onMouseUp);
54
+ }
55
+
56
+ onDestroy(() => {
57
+ window.removeEventListener("mousemove", onMouseMove);
58
+ window.removeEventListener("mouseup", onMouseUp);
59
+ });
60
+ </script>
61
+
62
+ <NodeViewWrapper class="fl-audio-player-wrapper">
63
+ <div
64
+ bind:this={targetElement}
65
+ class="fl-audio-player"
66
+ class:selected={selected}
67
+ style="
68
+ --color-play: {attrs.colorPlay};
69
+ --color-bar: {attrs.colorBar};
70
+ "
71
+ >
72
+ <!-- <audio
73
+ src={attrs.src}
74
+ controls={attrs.controls}
75
+ autoplay={attrs.autoplay}
76
+ loop={attrs.loop}
77
+ ></audio> -->
78
+
79
+ <AudioPlayer src={attrs.src}></AudioPlayer>
80
+
81
+ {#if selected}
82
+ <span
83
+ class="resize-grab"
84
+ role="button"
85
+ tabindex="0"
86
+ aria-label="Arrastra para cambiar el tamaño"
87
+ contenteditable="false"
88
+ on:mousedown={onMouseDown}
89
+ >
90
+ </span>
91
+ {/if}
92
+ </div>
93
+ </NodeViewWrapper>
94
+
95
+ <style>
96
+ .fl-audio-player {
97
+ display: flex;
98
+ align-items: center;
99
+ position: relative;
100
+ }
101
+
102
+ .resize-grab {
103
+ position: absolute;
104
+ right: -4px;
105
+ width: 6px;
106
+ background: #535bf2;
107
+ height: 50%;
108
+ border-radius: 13px;
109
+ cursor: col-resize;
110
+ display: flex;
111
+ align-items: center;
112
+
113
+ &::after {
114
+ content: "";
115
+ position: absolute;
116
+ width: 14px;
117
+ height: 14px;
118
+ left: -4px;
119
+ background: inherit;
120
+ border-radius: 100%;
121
+ }
122
+ }
123
+ </style>
@@ -0,0 +1,21 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ import type { NodeViewProps } from '@tiptap/core';
3
+ declare const __propDef: {
4
+ props: {
5
+ node: NodeViewProps["node"];
6
+ selected: NodeViewProps["selected"];
7
+ getPos: NodeViewProps["getPos"];
8
+ editor: NodeViewProps["editor"];
9
+ targetElement?: any;
10
+ };
11
+ events: {
12
+ [evt: string]: CustomEvent<any>;
13
+ };
14
+ slots: {};
15
+ };
16
+ export type AudioPlayerWrapperProps = typeof __propDef.props;
17
+ export type AudioPlayerWrapperEvents = typeof __propDef.events;
18
+ export type AudioPlayerWrapperSlots = typeof __propDef.slots;
19
+ export default class AudioPlayerWrapper extends SvelteComponentTyped<AudioPlayerWrapperProps, AudioPlayerWrapperEvents, AudioPlayerWrapperSlots> {
20
+ }
21
+ export {};
@@ -0,0 +1,2 @@
1
+ import { Node } from '@tiptap/core';
2
+ export declare const MediaGridExtension: Node<any, any>;
@@ -0,0 +1,90 @@
1
+ import { Node, mergeAttributes } from '@tiptap/core';
2
+ import { SvelteNodeViewRenderer } from 'svelte-tiptap';
3
+ import MediaGridComponent from './MediaGrid.svelte';
4
+ export const MediaGridExtension = Node.create({
5
+ name: 'MediaGridComponent',
6
+ group: 'block',
7
+ content: 'gridItem+',
8
+ defining: true,
9
+ addAttributes() {
10
+ return {
11
+ class: {
12
+ default: "fl-media-grid",
13
+ parseHTML: element => element.getAttribute('class') || null,
14
+ renderHTML: attributes => {
15
+ if (!attributes.class)
16
+ return {};
17
+ return { class: attributes.class };
18
+ },
19
+ },
20
+ cols: {
21
+ default: 2,
22
+ parseHTML: element => parseInt(element.getAttribute('data-cols') || '2', 10),
23
+ renderHTML: attrs => ({ 'data-cols': attrs.cols }),
24
+ },
25
+ gap: {
26
+ default: '1rem',
27
+ parseHTML: element => element.getAttribute('data-gap') || '1rem',
28
+ renderHTML: attrs => ({ 'data-gap': attrs.gap }),
29
+ },
30
+ showIndicator: {
31
+ default: false,
32
+ parseHTML: element => element.getAttribute('data-show-indicator') || false,
33
+ renderHTML: attrs => ({ 'data-show-indicator': attrs.showIndicator }),
34
+ },
35
+ indicatorType: {
36
+ default: 'numeric', // 'numeric' | 'alphabetic'
37
+ parseHTML: element => element.getAttribute('data-indicator-type') || 'numeric',
38
+ renderHTML: attrs => ({ 'data-indicator-type': attrs.indicatorType }),
39
+ }
40
+ };
41
+ },
42
+ parseHTML() {
43
+ return [{ tag: 'media-grid-component' }];
44
+ },
45
+ renderHTML({ HTMLAttributes }) {
46
+ return ['div', mergeAttributes(HTMLAttributes), 0];
47
+ },
48
+ addCommands() {
49
+ return {
50
+ insertGrid: (options) => ({ tr, state, dispatch }) => {
51
+ const { schema } = state;
52
+ const cols = options?.cols || 2;
53
+ // const items = Array.from({ length: cols }, () =>
54
+ // schema.nodes.gridItem.create(
55
+ // null,
56
+ // schema.nodes.image.create({ src: 'https://placehold.co/800x400' })
57
+ // )
58
+ // )
59
+ const items = Array.from({ length: cols }, () => schema.nodes.gridItem.create() // 👈 sin contenido
60
+ );
61
+ const grid = this.type.create({ cols }, items);
62
+ if (dispatch) {
63
+ tr.replaceSelectionWith(grid).scrollIntoView();
64
+ dispatch(tr);
65
+ }
66
+ return true;
67
+ },
68
+ addGridItem: () => ({ tr, state, dispatch }) => {
69
+ const { schema, selection } = state;
70
+ const { $from } = selection;
71
+ for (let depth = $from.depth; depth > 0; depth--) {
72
+ const node = $from.node(depth);
73
+ if (node.type.name === this.name) {
74
+ if (dispatch) {
75
+ const pos = $from.end(depth) - 1;
76
+ const gridItem = schema.nodes.gridItem.create();
77
+ tr.insert(pos, gridItem).scrollIntoView();
78
+ dispatch(tr);
79
+ }
80
+ return true;
81
+ }
82
+ }
83
+ return false;
84
+ },
85
+ };
86
+ },
87
+ addNodeView() {
88
+ return SvelteNodeViewRenderer(MediaGridComponent);
89
+ },
90
+ });
@@ -0,0 +1,265 @@
1
+ <script lang="ts">
2
+ import type { NodeViewProps } from "@tiptap/core";
3
+ import cx from "clsx";
4
+ import { NodeViewContent, NodeViewWrapper } from "svelte-tiptap";
5
+
6
+ const { node, updateAttributes, selected, getPos, editor }: NodeViewProps = $props();
7
+
8
+ let cols = $state(node.attrs.cols || 2);
9
+ let gap = $state(node.attrs.gap || 1);
10
+ let showIndicator = $state(node.attrs.showIndicator || false);
11
+ let indicatorType = $state(node.attrs.indicatorType || 'numeric');
12
+
13
+ function handleColsChange(e) {
14
+ cols = e.target.value;
15
+ updateAttributes({ cols });
16
+ }
17
+
18
+ function handleGapChange(e) {
19
+ gap = e.target.value;
20
+ updateAttributes({ gap });
21
+ }
22
+
23
+ function handleShowIndicatorChange(e) {
24
+ showIndicator = e.target.checked;
25
+ updateAttributes({ showIndicator });
26
+ }
27
+
28
+ function handleIndicatorTypeChange(e) {
29
+ indicatorType = e.target.value;
30
+ updateAttributes({ indicatorType });
31
+ }
32
+ </script>
33
+
34
+ <NodeViewWrapper
35
+ id="svelte-component"
36
+ data-selected={selected}
37
+ class={cx("fl-editor-custom-component svelte-component")}
38
+ data-drag-handle=""
39
+ >
40
+ <div class="flex fl-editor-component-header" contentEditable={false}>
41
+
42
+ <button
43
+ class="fl-add-grid-item-btn"
44
+ onclick={() => {
45
+ const pos = getPos();
46
+ if (typeof pos === "number") {
47
+ // Coloca el cursor dentro del grid (contentDOM)
48
+ editor
49
+ .chain()
50
+ .focus()
51
+ .setTextSelection(pos + 1) // 👈 entra dentro del content
52
+ .addGridItem()
53
+ .run();
54
+ } else {
55
+ editor.chain().focus().addGridItem().run();
56
+ }
57
+ }}
58
+ >
59
+ Add grid item
60
+ </button>
61
+
62
+ <div class="fl-editor-component-options">
63
+ <div class="fl-editor-component-option">
64
+ <label>
65
+ <span class="fl-editor-component-option-icon">
66
+ <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-columns"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M4 6l5.5 0"></path><path d="M4 10l5.5 0"></path><path d="M4 14l5.5 0"></path><path d="M4 18l5.5 0"></path><path d="M14.5 6l5.5 0"></path><path d="M14.5 10l5.5 0"></path><path d="M14.5 14l5.5 0"></path><path d="M14.5 18l5.5 0"></path></svg>
67
+ </span>
68
+ <input
69
+ class="fl-editor-option-input input-number option--cols"
70
+ oninput={handleColsChange}
71
+ type="number"
72
+ id="cols"
73
+ value={cols}
74
+ min="1"
75
+ max="10"
76
+ step="1"
77
+ />
78
+ </label>
79
+ </div>
80
+
81
+ <div class="fl-editor-component-option">
82
+ <label>
83
+ <span class="fl-editor-component-option-icon">
84
+ <svg xmlns="http://www.w3.org/2000/svg" width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-spacing-horizontal"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M20 20h-2a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h2" /><path d="M4 20h2a2 2 0 0 0 2 -2v-12a2 2 0 0 0 -2 -2h-2" /><path d="M12 8v8" /></svg>
85
+ </span>
86
+ <input
87
+ class="fl-editor-option-input input-text option--gap"
88
+ oninput={handleGapChange}
89
+ type="text"
90
+ id="gap"
91
+ value={gap}
92
+ />
93
+ </label>
94
+ </div>
95
+
96
+ <div class="fl-editor-component-option m-l-small">
97
+ <label>
98
+ <input
99
+ class="fl-editor-option-input input-checkbox option--show-indicator"
100
+ oninput={handleShowIndicatorChange}
101
+ type="checkbox"
102
+ id="show-indicator"
103
+ value={showIndicator}
104
+ />
105
+ Show indicators
106
+ </label>
107
+ </div>
108
+
109
+ {#if showIndicator}
110
+ <div class="fl-editor-component-option">
111
+ <label>
112
+ <select id="indicator-type" value={indicatorType} onchange={handleIndicatorTypeChange}>
113
+ <option value="numeric">Numeric</option>
114
+ <option value="alphabetic">Alphabetic</option>
115
+ </select>
116
+ </label>
117
+ </div>
118
+ {/if}
119
+ </div>
120
+ </div>
121
+
122
+
123
+ <!-- <div class="fl-grid" >
124
+ {#each Array(node.childCount) as _, i}
125
+ <div class="fl-grid-item">
126
+ <span class="fl-grid-item-badge">
127
+ {i + 1}
128
+ </span>
129
+ <img src="https://template.tiptap.dev/images/tiptap-ui-placeholder-image.jpg" alt="Imagen de ejemplo" />
130
+ <div class="fl-grid-item-actions">
131
+ <button type="button" onclick={() => {
132
+ editor.commands.addGridItem();
133
+ }}>
134
+ Add
135
+ </button>
136
+ </div>
137
+ </div>
138
+ {/each}
139
+
140
+ </div> -->
141
+
142
+ <NodeViewContent
143
+ class="media-grid-view-content"
144
+ style="
145
+ --fl-grid-cols: {cols};
146
+ --fl-grid-gap: {gap};
147
+ "
148
+ />
149
+
150
+
151
+
152
+ <!-- <div class="fl-editor-component-option">
153
+ <button type="button" onclick={addItem}> Add item </button>
154
+ </div> -->
155
+
156
+ </NodeViewWrapper>
157
+
158
+
159
+
160
+ <style>
161
+ .placeholder {
162
+ opacity: 0.4;
163
+ border: 1px dashed #aaa;
164
+ }
165
+
166
+ .fl-editor-component-header {
167
+ display: flex;
168
+ gap: 10px;
169
+ margin-bottom: 1rem;
170
+ }
171
+
172
+ .fl-add-grid-item-btn {
173
+ padding: 6px 15px;
174
+ border-radius: 12px;
175
+ border: none;
176
+ background: #6b6b6b;
177
+ }
178
+
179
+ .fl-editor-component-options {
180
+ display: flex;
181
+ align-items: center;
182
+ gap: 8px;
183
+ font-size: 14px;
184
+ color: #ffffffc2;
185
+ background-color: #2a2a2a00;
186
+ backdrop-filter: blur(10px);
187
+ padding: 6px 8px;
188
+ border-radius: 12px;
189
+ }
190
+
191
+ .fl-editor-component-option {
192
+ & label {
193
+ display: flex;
194
+ align-items: center;
195
+ gap: 8px;
196
+ }
197
+
198
+ & .fl-editor-component-option-icon {
199
+ display: flex;
200
+ }
201
+
202
+ &.m-l-small {
203
+ margin-left: 4px;
204
+ }
205
+
206
+ select {
207
+ background-color: #131313;
208
+ border: none;
209
+ padding: 3px 2px;
210
+ outline: none;
211
+
212
+ &:focus {
213
+ text-decoration: underline;
214
+ }
215
+ }
216
+ }
217
+
218
+ .fl-editor-option-input {
219
+
220
+ &.input-number, &.input-text {
221
+ border: none;
222
+ background: #7e7e7e80;
223
+ padding: 6px 7px;
224
+ border-radius: 8px;
225
+ }
226
+
227
+ &.option--cols {
228
+ width: 32px;
229
+ }
230
+
231
+ &.option--gap {
232
+ width: 74px;
233
+ }
234
+
235
+ &.input-checkbox {
236
+ width: 15px;
237
+ margin: 0;
238
+ height: 15px;
239
+ accent-color: #535bf2;
240
+ }
241
+
242
+ }
243
+
244
+ .fl-grid-item-badge {
245
+ position: absolute;
246
+ left: 10px;
247
+ top: 10px;
248
+ background: #535bf2;
249
+ width: 30px;
250
+ height: 30px;
251
+ display: flex;
252
+ align-items: center;
253
+ justify-content: center;
254
+ font-weight: 600;
255
+ border-radius: 100%;
256
+ }
257
+
258
+ .fl-grid-item-actions {
259
+ display: flex;
260
+ gap: 10px;
261
+ position: absolute;
262
+ top: 10px;
263
+ right: 10px;
264
+ }
265
+ </style>
@@ -0,0 +1,14 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: Record<string, never>;
4
+ events: {
5
+ [evt: string]: CustomEvent<any>;
6
+ };
7
+ slots: {};
8
+ };
9
+ export type MediaGridProps = typeof __propDef.props;
10
+ export type MediaGridEvents = typeof __propDef.events;
11
+ export type MediaGridSlots = typeof __propDef.slots;
12
+ export default class MediaGrid extends SvelteComponentTyped<MediaGridProps, MediaGridEvents, MediaGridSlots> {
13
+ }
14
+ export {};
@@ -0,0 +1,2 @@
1
+ import { Node } from '@tiptap/core';
2
+ export declare const MediaGridItemExtension: Node<any, any>;
@@ -0,0 +1,24 @@
1
+ import { Node, mergeAttributes } from '@tiptap/core';
2
+ import { SvelteNodeViewRenderer } from 'svelte-tiptap';
3
+ import MediaGridItemComponent from './MediaGridItem.svelte';
4
+ export const MediaGridItemExtension = Node.create({
5
+ name: 'gridItem',
6
+ content: 'image?', // 👈 solo permite un nodo image
7
+ selectable: true,
8
+ parseHTML() {
9
+ return [{ tag: 'div[data-type="grid-item"]' }];
10
+ },
11
+ renderHTML({ HTMLAttributes }) {
12
+ return [
13
+ 'div',
14
+ mergeAttributes(HTMLAttributes, {
15
+ 'data-type': 'grid-item',
16
+ class: 'fl-grid-item',
17
+ }),
18
+ 0,
19
+ ];
20
+ },
21
+ addNodeView() {
22
+ return SvelteNodeViewRenderer(MediaGridItemComponent);
23
+ },
24
+ });