drab 4.1.6 → 5.0.0-beta.0
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/animate/define.d.ts +2 -0
- package/animate/define.iife.js +1 -0
- package/animate/define.js +1 -0
- package/animate.d.ts +54 -0
- package/animate.iife.js +1 -0
- package/animate.js +1 -0
- package/base/define.d.ts +2 -0
- package/base/define.iife.js +1 -0
- package/base/define.js +1 -0
- package/base.d.ts +69 -0
- package/base.iife.js +1 -0
- package/base.js +1 -0
- package/breakpoint/define.d.ts +2 -0
- package/breakpoint/define.iife.js +1 -0
- package/breakpoint/define.js +1 -0
- package/breakpoint.d.ts +24 -0
- package/breakpoint.iife.js +1 -0
- package/breakpoint.js +1 -0
- package/chunk-2ZZQECRY.js +1 -0
- package/chunk-57VEEUFG.js +1 -0
- package/chunk-5JV4T7GM.js +1 -0
- package/chunk-6HYPZWQ4.js +1 -0
- package/chunk-7F7CQUEG.js +1 -0
- package/chunk-7KU2PRW5.js +1 -0
- package/chunk-7S6DTKGH.js +1 -0
- package/chunk-FNJ7AESC.js +9 -0
- package/chunk-IQJQPZUL.js +1 -0
- package/chunk-JMJUWKN2.js +1 -0
- package/chunk-MXKU7AKV.js +1 -0
- package/chunk-T7RZI3ZL.js +1 -0
- package/chunk-TSTTUEAF.js +1 -0
- package/chunk-VEVFQB5N.js +1 -0
- package/contextmenu/define.d.ts +2 -0
- package/contextmenu/define.iife.js +1 -0
- package/contextmenu/define.js +1 -0
- package/contextmenu.d.ts +15 -0
- package/contextmenu.iife.js +1 -0
- package/contextmenu.js +1 -0
- package/copy/define.d.ts +2 -0
- package/copy/define.iife.js +1 -0
- package/copy/define.js +1 -0
- package/copy.d.ts +13 -0
- package/copy.iife.js +1 -0
- package/copy.js +1 -0
- package/define.d.ts +2 -0
- package/define.iife.js +9 -0
- package/define.js +1 -0
- package/details/define.d.ts +2 -0
- package/details/define.iife.js +1 -0
- package/details/define.js +1 -0
- package/details.d.ts +23 -0
- package/details.iife.js +1 -0
- package/details.js +1 -0
- package/dialog/define.d.ts +2 -0
- package/dialog/define.iife.js +1 -0
- package/dialog/define.js +1 -0
- package/dialog.d.ts +20 -0
- package/dialog.iife.js +1 -0
- package/dialog.js +1 -0
- package/editor/define.d.ts +2 -0
- package/editor/define.iife.js +9 -0
- package/editor/define.js +1 -0
- package/editor.d.ts +58 -0
- package/editor.iife.js +9 -0
- package/editor.js +1 -0
- package/fullscreen/define.d.ts +2 -0
- package/fullscreen/define.iife.js +1 -0
- package/fullscreen/define.js +1 -0
- package/fullscreen.d.ts +23 -0
- package/fullscreen.iife.js +1 -0
- package/fullscreen.js +1 -0
- package/index-22PHGcPf.d.ts +17 -0
- package/index.d.ts +14 -0
- package/index.iife.js +9 -0
- package/index.js +1 -0
- package/package.json +131 -59
- package/popover/define.d.ts +2 -0
- package/popover/define.iife.js +1 -0
- package/popover/define.js +1 -0
- package/popover.d.ts +29 -0
- package/popover.iife.js +1 -0
- package/popover.js +1 -0
- package/share/define.d.ts +2 -0
- package/share/define.iife.js +1 -0
- package/share/define.js +1 -0
- package/share.d.ts +19 -0
- package/share.iife.js +1 -0
- package/share.js +1 -0
- package/tablesort/define.d.ts +2 -0
- package/tablesort/define.iife.js +1 -0
- package/tablesort/define.js +1 -0
- package/tablesort.d.ts +21 -0
- package/tablesort.iife.js +1 -0
- package/tablesort.js +1 -0
- package/youtube/define.d.ts +2 -0
- package/youtube/define.iife.js +1 -0
- package/youtube/define.js +1 -0
- package/youtube.d.ts +29 -0
- package/youtube.iife.js +1 -0
- package/youtube.js +1 -0
- package/LICENSE.md +0 -21
- package/README.md +0 -131
- package/dist/components/Breakpoint.svelte +0 -55
- package/dist/components/Breakpoint.svelte.d.ts +0 -46
- package/dist/components/ContextMenu.svelte +0 -150
- package/dist/components/ContextMenu.svelte.d.ts +0 -76
- package/dist/components/CopyButton.svelte +0 -97
- package/dist/components/CopyButton.svelte.d.ts +0 -60
- package/dist/components/DataTable.svelte +0 -208
- package/dist/components/DataTable.svelte.d.ts +0 -155
- package/dist/components/Details.svelte +0 -101
- package/dist/components/Details.svelte.d.ts +0 -67
- package/dist/components/Editor.svelte +0 -404
- package/dist/components/Editor.svelte.d.ts +0 -111
- package/dist/components/FrettedChord.svelte +0 -213
- package/dist/components/FrettedChord.svelte.d.ts +0 -79
- package/dist/components/FullscreenButton.svelte +0 -95
- package/dist/components/FullscreenButton.svelte.d.ts +0 -62
- package/dist/components/Popover.svelte +0 -153
- package/dist/components/Popover.svelte.d.ts +0 -80
- package/dist/components/ShareButton.svelte +0 -133
- package/dist/components/ShareButton.svelte.d.ts +0 -93
- package/dist/components/Sheet.svelte +0 -180
- package/dist/components/Sheet.svelte.d.ts +0 -99
- package/dist/components/Tablature.svelte +0 -173
- package/dist/components/Tablature.svelte.d.ts +0 -93
- package/dist/components/YouTube.svelte +0 -51
- package/dist/components/YouTube.svelte.d.ts +0 -49
- package/dist/index.d.ts +0 -14
- package/dist/index.js +0 -14
- package/dist/util/accessibility.d.ts +0 -6
- package/dist/util/accessibility.js +0 -11
- package/dist/util/delay.d.ts +0 -1
- package/dist/util/delay.js +0 -1
- package/dist/util/transition.d.ts +0 -2
- package/dist/util/transition.js +0 -2
@@ -1,404 +0,0 @@
|
|
1
|
-
<!--
|
2
|
-
@component
|
3
|
-
|
4
|
-
### Editor
|
5
|
-
|
6
|
-
`textarea` element with controls to add content and keyboard shortcuts. Compared to other WYSIWYG editors, the `valueTextarea` is just a `string`, so you can easily store it in a database or manipulate it without learning a separate API.
|
7
|
-
|
8
|
-
- This component is used to create [Typo](https://typo.robino.dev)
|
9
|
-
|
10
|
-
@props
|
11
|
-
|
12
|
-
- `classButton` - `class` of all the `button` elements
|
13
|
-
- `classControls` - `class` of the `div` that wraps the controls
|
14
|
-
- `classTextarea` - `class` of the `textarea` element
|
15
|
-
- `contentElements` - an array of `EditorContentElement`s for the controls
|
16
|
-
- `idControls` - `id` of the `div` that wraps the controls
|
17
|
-
- `idTextarea` - `id` of the `textarea` element
|
18
|
-
- `keyPairs` - keys that will auto-close if typed, value is their closing character
|
19
|
-
- `nameTextarea` - `name` of the `textarea` element
|
20
|
-
- `placeholderTextarea` - `placeholder` of the `textarea` element
|
21
|
-
- `selectionStartTextarea` - `selectionStart` value of the `textarea`
|
22
|
-
- `spellcheckTextarea` - `spellcheck` of the `textarea` element
|
23
|
-
- `valueTextarea` - `value` of the `textarea` element
|
24
|
-
|
25
|
-
@Events
|
26
|
-
|
27
|
-
| name | event |
|
28
|
-
| ------- | ----------------------- |
|
29
|
-
| `input` | forward from `textarea` |
|
30
|
-
|
31
|
-
@example
|
32
|
-
|
33
|
-
```svelte
|
34
|
-
<script lang="ts">
|
35
|
-
import { Editor } from "drab";
|
36
|
-
</script>
|
37
|
-
|
38
|
-
<Editor
|
39
|
-
classButton="button button-primary"
|
40
|
-
classControls="flex gap-2"
|
41
|
-
classTextarea="input h-36 mb-2"
|
42
|
-
placeholderTextarea="asterisk: ctrl+i, anchor: ctrl+["
|
43
|
-
contentElements={[
|
44
|
-
{
|
45
|
-
title: "Bullet",
|
46
|
-
text: "- ",
|
47
|
-
display: "block",
|
48
|
-
icon: "Bullet",
|
49
|
-
},
|
50
|
-
{
|
51
|
-
title: "Italic",
|
52
|
-
text: "*",
|
53
|
-
display: "wrap",
|
54
|
-
icon: "Italic",
|
55
|
-
key: "i",
|
56
|
-
class: "italic",
|
57
|
-
},
|
58
|
-
{
|
59
|
-
title: "Anchor",
|
60
|
-
text: "[text](href)",
|
61
|
-
display: "inline",
|
62
|
-
icon: "Anchor",
|
63
|
-
key: "[",
|
64
|
-
},
|
65
|
-
]}
|
66
|
-
/>
|
67
|
-
```
|
68
|
-
-->
|
69
|
-
|
70
|
-
<script>import { onMount } from "svelte";
|
71
|
-
export let contentElements = [];
|
72
|
-
export let valueTextarea = "";
|
73
|
-
export let placeholderTextarea = "";
|
74
|
-
export let spellcheckTextarea = true;
|
75
|
-
export let classTextarea = "";
|
76
|
-
export let idTextarea = "";
|
77
|
-
export let nameTextarea = "";
|
78
|
-
export let classButton = "";
|
79
|
-
export let classControls = "";
|
80
|
-
export let idControls = "";
|
81
|
-
export let selectionStartTextarea = 0;
|
82
|
-
export let keyPairs = {
|
83
|
-
"(": ")",
|
84
|
-
"{": "}",
|
85
|
-
"[": "]",
|
86
|
-
"<": ">",
|
87
|
-
'"': '"',
|
88
|
-
"`": "`"
|
89
|
-
};
|
90
|
-
let clientJs = false;
|
91
|
-
let textArea;
|
92
|
-
contentElements.forEach((el) => {
|
93
|
-
if (el.display === "wrap")
|
94
|
-
keyPairs[el.text] = el.text;
|
95
|
-
});
|
96
|
-
let openChars = [];
|
97
|
-
const insertChar = (str, char, index) => {
|
98
|
-
return str.slice(0, index) + char + str.slice(index);
|
99
|
-
};
|
100
|
-
const removeChar = (str, index) => {
|
101
|
-
return str.slice(0, index) + str.slice(index + 1);
|
102
|
-
};
|
103
|
-
const insertText = async (el, selectionStart, selectionEnd) => {
|
104
|
-
if (el.display === "inline") {
|
105
|
-
valueTextarea = `${valueTextarea.slice(0, selectionEnd)}${el.text}${valueTextarea.slice(selectionEnd)}`;
|
106
|
-
} else if (el.display === "wrap") {
|
107
|
-
valueTextarea = insertChar(valueTextarea, el.text, selectionStart);
|
108
|
-
valueTextarea = insertChar(
|
109
|
-
valueTextarea,
|
110
|
-
keyPairs[el.text],
|
111
|
-
selectionEnd + el.text.length
|
112
|
-
);
|
113
|
-
if (el.text.length < 2)
|
114
|
-
openChars.push(el.text);
|
115
|
-
} else if (el.display === "block") {
|
116
|
-
const { lines, lineNumber } = getLineInfo();
|
117
|
-
if (lines[lineNumber].startsWith(el.text[0])) {
|
118
|
-
lines[lineNumber] = el.text.trim() + lines[lineNumber];
|
119
|
-
} else {
|
120
|
-
lines[lineNumber] = el.text + lines[lineNumber];
|
121
|
-
}
|
122
|
-
valueTextarea = lines.join("\n");
|
123
|
-
}
|
124
|
-
};
|
125
|
-
const setCaretPosition = async (text, selectionStart, selectionEnd) => {
|
126
|
-
let startPos = 0;
|
127
|
-
let endPos = 0;
|
128
|
-
if (/[a-z]/i.test(text)) {
|
129
|
-
for (let i = selectionEnd; i < valueTextarea.length; i++) {
|
130
|
-
if (valueTextarea[i].match(/[a-z]/i)) {
|
131
|
-
if (!startPos) {
|
132
|
-
startPos = i;
|
133
|
-
} else {
|
134
|
-
endPos = i + 1;
|
135
|
-
}
|
136
|
-
} else if (startPos) {
|
137
|
-
break;
|
138
|
-
}
|
139
|
-
}
|
140
|
-
} else {
|
141
|
-
startPos = selectionStart + text.length;
|
142
|
-
endPos = selectionEnd + text.length;
|
143
|
-
}
|
144
|
-
textArea.setSelectionRange(startPos, endPos);
|
145
|
-
textArea.focus();
|
146
|
-
};
|
147
|
-
const addContent = async (el) => {
|
148
|
-
const selectionEnd = textArea.selectionEnd;
|
149
|
-
const selectionStart = textArea.selectionStart;
|
150
|
-
await insertText(el, selectionStart, selectionEnd);
|
151
|
-
setCaretPosition(el.text, selectionStart, selectionEnd);
|
152
|
-
};
|
153
|
-
const onKeyDown = async (e) => {
|
154
|
-
const resetKeys = ["ArrowUp", "ArrowDown", "Delete"];
|
155
|
-
const nextChar = valueTextarea[textArea.selectionEnd];
|
156
|
-
if (resetKeys.includes(e.key)) {
|
157
|
-
openChars = [];
|
158
|
-
} else if (e.key === "Backspace") {
|
159
|
-
const prevChar = valueTextarea[textArea.selectionStart - 1];
|
160
|
-
if (prevChar in keyPairs && nextChar === keyPairs[prevChar]) {
|
161
|
-
e.preventDefault();
|
162
|
-
const start = textArea.selectionStart - 1;
|
163
|
-
const end = textArea.selectionEnd - 1;
|
164
|
-
valueTextarea = removeChar(valueTextarea, start);
|
165
|
-
valueTextarea = removeChar(valueTextarea, end);
|
166
|
-
setTimeout(() => {
|
167
|
-
textArea.setSelectionRange(start, end);
|
168
|
-
}, 0);
|
169
|
-
openChars.pop();
|
170
|
-
}
|
171
|
-
if (prevChar === "\n" && textArea.selectionStart === textArea.selectionEnd) {
|
172
|
-
e.preventDefault();
|
173
|
-
const newPos = textArea.selectionStart - 1;
|
174
|
-
const { lineNumber } = getLineInfo();
|
175
|
-
correctFollowing(lineNumber, true);
|
176
|
-
valueTextarea = removeChar(valueTextarea, newPos);
|
177
|
-
setTimeout(async () => {
|
178
|
-
textArea.setSelectionRange(newPos, newPos);
|
179
|
-
}, 0);
|
180
|
-
}
|
181
|
-
} else if (e.key === "Tab") {
|
182
|
-
if (getCurrentBlock() % 2 !== 0) {
|
183
|
-
e.preventDefault();
|
184
|
-
await addContent({
|
185
|
-
display: "inline",
|
186
|
-
text: " ",
|
187
|
-
icon: "tab",
|
188
|
-
title: "tab"
|
189
|
-
});
|
190
|
-
}
|
191
|
-
} else if (e.key === "Enter") {
|
192
|
-
const { lines, lineNumber, columnNumber } = getLineInfo();
|
193
|
-
const currentLine = lines[lineNumber];
|
194
|
-
let repeat = getRepeat(currentLine);
|
195
|
-
const original = repeat;
|
196
|
-
const num = startsWithNumberAndPeriod(repeat);
|
197
|
-
if (num)
|
198
|
-
repeat = `${num + 1}. `;
|
199
|
-
if (repeat && original.length < columnNumber) {
|
200
|
-
e.preventDefault();
|
201
|
-
if (num)
|
202
|
-
correctFollowing(lineNumber);
|
203
|
-
await addContent({
|
204
|
-
display: "inline",
|
205
|
-
text: `
|
206
|
-
${repeat}`,
|
207
|
-
icon: "",
|
208
|
-
title: ""
|
209
|
-
});
|
210
|
-
} else if (repeat && original.length === columnNumber) {
|
211
|
-
e.preventDefault();
|
212
|
-
const selectionEnd = textArea.selectionEnd;
|
213
|
-
const newPos = selectionEnd - original.length;
|
214
|
-
for (let i = 0; i < original.length; i++) {
|
215
|
-
valueTextarea = removeChar(
|
216
|
-
valueTextarea,
|
217
|
-
textArea.selectionEnd - (i + 1)
|
218
|
-
);
|
219
|
-
}
|
220
|
-
setTimeout(async () => {
|
221
|
-
textArea.setSelectionRange(newPos, newPos);
|
222
|
-
textArea.focus();
|
223
|
-
await addContent({
|
224
|
-
display: "inline",
|
225
|
-
text: `
|
226
|
-
`,
|
227
|
-
icon: "",
|
228
|
-
title: ""
|
229
|
-
});
|
230
|
-
}, 0);
|
231
|
-
}
|
232
|
-
} else {
|
233
|
-
const nextCharIsClosing = Object.values(keyPairs).includes(nextChar);
|
234
|
-
const highlighted = textArea.selectionStart !== textArea.selectionEnd;
|
235
|
-
if (e.ctrlKey || e.metaKey) {
|
236
|
-
if (textArea.selectionStart === textArea.selectionEnd) {
|
237
|
-
if (e.key === "c" || e.key === "x") {
|
238
|
-
e.preventDefault();
|
239
|
-
const { lines, lineNumber, columnNumber } = getLineInfo();
|
240
|
-
await navigator.clipboard.writeText(
|
241
|
-
`${lineNumber === 0 && e.key === "x" ? "" : "\n"}${lines[lineNumber]}`
|
242
|
-
);
|
243
|
-
if (e.key === "x") {
|
244
|
-
const newPos = textArea.selectionStart - columnNumber;
|
245
|
-
lines.splice(lineNumber, 1);
|
246
|
-
valueTextarea = lines.join("\n");
|
247
|
-
setTimeout(() => {
|
248
|
-
textArea.setSelectionRange(newPos, newPos);
|
249
|
-
}, 0);
|
250
|
-
}
|
251
|
-
}
|
252
|
-
}
|
253
|
-
}
|
254
|
-
if ((e.ctrlKey || e.metaKey) && e.key) {
|
255
|
-
const matchedEl = contentElements.find((el) => el.key === e.key);
|
256
|
-
if (matchedEl)
|
257
|
-
addContent(matchedEl);
|
258
|
-
} else if (nextCharIsClosing && (nextChar === e.key || e.key === "ArrowRight") && openChars.length && !highlighted) {
|
259
|
-
e.preventDefault();
|
260
|
-
textArea.setSelectionRange(
|
261
|
-
textArea.selectionStart + 1,
|
262
|
-
textArea.selectionEnd + 1
|
263
|
-
);
|
264
|
-
openChars.pop();
|
265
|
-
} else if (e.key in keyPairs) {
|
266
|
-
e.preventDefault();
|
267
|
-
await addContent({
|
268
|
-
display: "wrap",
|
269
|
-
text: e.key,
|
270
|
-
icon: "",
|
271
|
-
title: ""
|
272
|
-
});
|
273
|
-
openChars.push(e.key);
|
274
|
-
}
|
275
|
-
}
|
276
|
-
};
|
277
|
-
const trimSelection = () => {
|
278
|
-
if (textArea.selectionStart !== textArea.selectionEnd) {
|
279
|
-
if (valueTextarea[textArea.selectionStart] === " ") {
|
280
|
-
textArea.setSelectionRange(
|
281
|
-
textArea.selectionStart + 1,
|
282
|
-
textArea.selectionEnd
|
283
|
-
);
|
284
|
-
}
|
285
|
-
if (valueTextarea[textArea.selectionEnd - 1] === " ") {
|
286
|
-
textArea.setSelectionRange(
|
287
|
-
textArea.selectionStart,
|
288
|
-
textArea.selectionEnd - 1
|
289
|
-
);
|
290
|
-
}
|
291
|
-
}
|
292
|
-
};
|
293
|
-
const updateSelectionStart = () => {
|
294
|
-
selectionStartTextarea = textArea.selectionStart;
|
295
|
-
};
|
296
|
-
const getLineInfo = () => {
|
297
|
-
const lines = valueTextarea.split("\n");
|
298
|
-
let characterCount = 0;
|
299
|
-
for (let i = 0; i < lines.length; i++) {
|
300
|
-
characterCount++;
|
301
|
-
characterCount += lines[i].length;
|
302
|
-
if (characterCount > textArea.selectionEnd) {
|
303
|
-
return {
|
304
|
-
lines,
|
305
|
-
lineNumber: i,
|
306
|
-
columnNumber: textArea.selectionEnd - (characterCount - lines[i].length - 1)
|
307
|
-
};
|
308
|
-
}
|
309
|
-
}
|
310
|
-
return { lines, lineNumber: 0, columnNumber: 0 };
|
311
|
-
};
|
312
|
-
const getCurrentBlock = () => {
|
313
|
-
const blocks = valueTextarea.split("```");
|
314
|
-
let totalChars = 0;
|
315
|
-
for (const [i, block] of blocks.entries()) {
|
316
|
-
totalChars += block.length + 3;
|
317
|
-
if (textArea.selectionStart < totalChars) {
|
318
|
-
return i;
|
319
|
-
}
|
320
|
-
}
|
321
|
-
return 0;
|
322
|
-
};
|
323
|
-
const getRepeat = (str) => {
|
324
|
-
const blockStrings = [];
|
325
|
-
contentElements.forEach((el) => {
|
326
|
-
if (el.display === "block")
|
327
|
-
blockStrings.push(el.text);
|
328
|
-
});
|
329
|
-
for (let i = 0; i < blockStrings.length; i++) {
|
330
|
-
const repeatString = blockStrings[i];
|
331
|
-
if (str.startsWith(repeatString)) {
|
332
|
-
return repeatString;
|
333
|
-
}
|
334
|
-
}
|
335
|
-
const repeatNum = startsWithNumberAndPeriod(str);
|
336
|
-
if (repeatNum)
|
337
|
-
return `${repeatNum}. `;
|
338
|
-
return "";
|
339
|
-
};
|
340
|
-
const startsWithNumberAndPeriod = (str) => {
|
341
|
-
const result = str.match(/^(\d+)\./);
|
342
|
-
return result ? Number(result[1]) : null;
|
343
|
-
};
|
344
|
-
const correctFollowing = (currentLineNumber, decrement = false) => {
|
345
|
-
const { lines } = getLineInfo();
|
346
|
-
for (let i = currentLineNumber + 1; i < lines.length; i++) {
|
347
|
-
const num = startsWithNumberAndPeriod(lines[i]);
|
348
|
-
if (!num) {
|
349
|
-
break;
|
350
|
-
} else {
|
351
|
-
let newNum;
|
352
|
-
if (decrement) {
|
353
|
-
if (num > 1) {
|
354
|
-
newNum = num - 1;
|
355
|
-
} else {
|
356
|
-
break;
|
357
|
-
}
|
358
|
-
} else {
|
359
|
-
newNum = num + 1;
|
360
|
-
}
|
361
|
-
lines[i] = lines[i].slice(String(num).length);
|
362
|
-
lines[i] = String(newNum) + lines[i];
|
363
|
-
}
|
364
|
-
}
|
365
|
-
valueTextarea = lines.join("\n");
|
366
|
-
};
|
367
|
-
onMount(() => clientJs = true);
|
368
|
-
</script>
|
369
|
-
|
370
|
-
<textarea
|
371
|
-
id={idTextarea}
|
372
|
-
class={classTextarea}
|
373
|
-
name={nameTextarea}
|
374
|
-
placeholder={placeholderTextarea}
|
375
|
-
spellcheck={spellcheckTextarea}
|
376
|
-
on:keydown={onKeyDown}
|
377
|
-
on:keyup={updateSelectionStart}
|
378
|
-
on:dblclick={trimSelection}
|
379
|
-
bind:value={valueTextarea}
|
380
|
-
bind:this={textArea}
|
381
|
-
on:click={() => {
|
382
|
-
openChars = [];
|
383
|
-
updateSelectionStart();
|
384
|
-
}}
|
385
|
-
on:input
|
386
|
-
/>
|
387
|
-
|
388
|
-
<div id={idControls} class={classControls}>
|
389
|
-
{#each contentElements as el}
|
390
|
-
<button
|
391
|
-
type="button"
|
392
|
-
class={el.class ? `${classButton} ${el.class}` : classButton}
|
393
|
-
on:click={() => addContent(el)}
|
394
|
-
title={el.title}
|
395
|
-
disabled={!clientJs}
|
396
|
-
>
|
397
|
-
{#if typeof el.icon !== "string"}
|
398
|
-
<svelte:component this={el.icon} />
|
399
|
-
{:else}
|
400
|
-
{el.icon}
|
401
|
-
{/if}
|
402
|
-
</button>
|
403
|
-
{/each}
|
404
|
-
</div>
|
@@ -1,111 +0,0 @@
|
|
1
|
-
import { SvelteComponent } from "svelte";
|
2
|
-
import { type ComponentType } from "svelte";
|
3
|
-
declare const __propDef: {
|
4
|
-
props: {
|
5
|
-
/** an array of `EditorContentElement`s for the controls */ contentElements?: {
|
6
|
-
/** title of element and it's corresponding button */
|
7
|
-
title: string;
|
8
|
-
/** text to add */
|
9
|
-
text: string;
|
10
|
-
/** controls how the text is added */
|
11
|
-
display: "inline" | "block" | "wrap";
|
12
|
-
/** contents of the `button` */
|
13
|
-
icon: string | ComponentType<any>;
|
14
|
-
/** keyboard shortcut */
|
15
|
-
key?: string | undefined;
|
16
|
-
/** class to apply to the specific `button` */
|
17
|
-
class?: string | undefined;
|
18
|
-
}[] | undefined;
|
19
|
-
/** `value` of the `textarea` element */ valueTextarea?: string | undefined;
|
20
|
-
/** `placeholder` of the `textarea` element */ placeholderTextarea?: string | undefined;
|
21
|
-
/** `spellcheck` of the `textarea` element */ spellcheckTextarea?: boolean | undefined;
|
22
|
-
/** `class` of the `textarea` element */ classTextarea?: string | undefined;
|
23
|
-
/** `id` of the `textarea` element */ idTextarea?: string | undefined;
|
24
|
-
/** `name` of the `textarea` element */ nameTextarea?: string | undefined;
|
25
|
-
/** `class` of all the `button` elements */ classButton?: string | undefined;
|
26
|
-
/** `class` of the `div` that wraps the controls */ classControls?: string | undefined;
|
27
|
-
/** `id` of the `div` that wraps the controls */ idControls?: string | undefined;
|
28
|
-
/** `selectionStart` value of the `textarea` */ selectionStartTextarea?: number | undefined;
|
29
|
-
/** keys that will auto-close if typed, value is their closing character */ keyPairs?: {
|
30
|
-
[key: string]: string;
|
31
|
-
} | undefined;
|
32
|
-
};
|
33
|
-
events: {
|
34
|
-
input: Event;
|
35
|
-
} & {
|
36
|
-
[evt: string]: CustomEvent<any>;
|
37
|
-
};
|
38
|
-
slots: {};
|
39
|
-
};
|
40
|
-
export type EditorProps = typeof __propDef.props;
|
41
|
-
export type EditorEvents = typeof __propDef.events;
|
42
|
-
export type EditorSlots = typeof __propDef.slots;
|
43
|
-
/**
|
44
|
-
* ### Editor
|
45
|
-
*
|
46
|
-
* `textarea` element with controls to add content and keyboard shortcuts. Compared to other WYSIWYG editors, the `valueTextarea` is just a `string`, so you can easily store it in a database or manipulate it without learning a separate API.
|
47
|
-
*
|
48
|
-
* - This component is used to create [Typo](https://typo.robino.dev)
|
49
|
-
*
|
50
|
-
* @props
|
51
|
-
*
|
52
|
-
* - `classButton` - `class` of all the `button` elements
|
53
|
-
* - `classControls` - `class` of the `div` that wraps the controls
|
54
|
-
* - `classTextarea` - `class` of the `textarea` element
|
55
|
-
* - `contentElements` - an array of `EditorContentElement`s for the controls
|
56
|
-
* - `idControls` - `id` of the `div` that wraps the controls
|
57
|
-
* - `idTextarea` - `id` of the `textarea` element
|
58
|
-
* - `keyPairs` - keys that will auto-close if typed, value is their closing character
|
59
|
-
* - `nameTextarea` - `name` of the `textarea` element
|
60
|
-
* - `placeholderTextarea` - `placeholder` of the `textarea` element
|
61
|
-
* - `selectionStartTextarea` - `selectionStart` value of the `textarea`
|
62
|
-
* - `spellcheckTextarea` - `spellcheck` of the `textarea` element
|
63
|
-
* - `valueTextarea` - `value` of the `textarea` element
|
64
|
-
*
|
65
|
-
* @Events
|
66
|
-
*
|
67
|
-
* | name | event |
|
68
|
-
* | ------- | ----------------------- |
|
69
|
-
* | `input` | forward from `textarea` |
|
70
|
-
*
|
71
|
-
* @example
|
72
|
-
*
|
73
|
-
* ```svelte
|
74
|
-
* <script lang="ts">
|
75
|
-
* import { Editor } from "drab";
|
76
|
-
* </script>
|
77
|
-
*
|
78
|
-
* <Editor
|
79
|
-
* classButton="button button-primary"
|
80
|
-
* classControls="flex gap-2"
|
81
|
-
* classTextarea="input h-36 mb-2"
|
82
|
-
* placeholderTextarea="asterisk: ctrl+i, anchor: ctrl+["
|
83
|
-
* contentElements={[
|
84
|
-
* {
|
85
|
-
* title: "Bullet",
|
86
|
-
* text: "- ",
|
87
|
-
* display: "block",
|
88
|
-
* icon: "Bullet",
|
89
|
-
* },
|
90
|
-
* {
|
91
|
-
* title: "Italic",
|
92
|
-
* text: "*",
|
93
|
-
* display: "wrap",
|
94
|
-
* icon: "Italic",
|
95
|
-
* key: "i",
|
96
|
-
* class: "italic",
|
97
|
-
* },
|
98
|
-
* {
|
99
|
-
* title: "Anchor",
|
100
|
-
* text: "[text](href)",
|
101
|
-
* display: "inline",
|
102
|
-
* icon: "Anchor",
|
103
|
-
* key: "[",
|
104
|
-
* },
|
105
|
-
* ]}
|
106
|
-
* />
|
107
|
-
* ```
|
108
|
-
*/
|
109
|
-
export default class Editor extends SvelteComponent<EditorProps, EditorEvents, EditorSlots> {
|
110
|
-
}
|
111
|
-
export {};
|