drab 2.7.0 → 2.8.1
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/README.md +0 -2
- package/dist/components/Accordion.svelte +4 -4
- package/dist/components/Accordion.svelte.d.ts +2 -2
- package/dist/components/Breakpoint.svelte +3 -5
- package/dist/components/Breakpoint.svelte.d.ts +1 -3
- package/dist/components/Chord.svelte +1 -1
- package/dist/components/Chord.svelte.d.ts +1 -1
- package/dist/components/ContextMenu.svelte +27 -12
- package/dist/components/ContextMenu.svelte.d.ts +20 -6
- package/dist/components/CopyButton.svelte +3 -5
- package/dist/components/CopyButton.svelte.d.ts +2 -4
- package/dist/components/DataTable.svelte +31 -16
- package/dist/components/DataTable.svelte.d.ts +9 -6
- package/dist/components/Editor.svelte +14 -12
- package/dist/components/Editor.svelte.d.ts +6 -4
- package/dist/components/FullscreenButton.svelte +10 -19
- package/dist/components/FullscreenButton.svelte.d.ts +7 -12
- package/dist/components/Popover.svelte +7 -9
- package/dist/components/Popover.svelte.d.ts +6 -8
- package/dist/components/ShareButton.svelte +72 -22
- package/dist/components/ShareButton.svelte.d.ts +44 -13
- package/dist/components/Sheet.svelte +11 -35
- package/dist/components/Sheet.svelte.d.ts +8 -9
- package/dist/components/Tabs.svelte +16 -18
- package/dist/components/Tabs.svelte.d.ts +10 -10
- package/dist/components/YouTube.svelte +2 -2
- package/dist/components/YouTube.svelte.d.ts +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
### Accordion
|
5
5
|
|
6
|
-
Displays a list of `details` elements with helpful defaults and transitions.
|
6
|
+
Displays a list of `details` elements with helpful defaults and transitions. Use `AccordionItem.data` to send any additional data through the slot props. Works without JavaScript.
|
7
7
|
|
8
8
|
@props
|
9
9
|
|
@@ -52,7 +52,7 @@ Displays a list of `details` elements with helpful defaults and transitions.
|
|
52
52
|
summary: "Is it animated?",
|
53
53
|
content: "Yes, with the transition prop.",
|
54
54
|
},
|
55
|
-
{ summary: "Does it work without
|
55
|
+
{ summary: "Does it work without JavaScript?", content: "Yes." },
|
56
56
|
]}
|
57
57
|
/>
|
58
58
|
|
@@ -112,9 +112,8 @@ const toggleOpen = (i) => {
|
|
112
112
|
items[i].open = !items[i].open;
|
113
113
|
if (autoClose) {
|
114
114
|
for (let j = 0; j < items.length; j++) {
|
115
|
-
const item = items[j];
|
116
115
|
if (j !== i)
|
117
|
-
|
116
|
+
items[j].open = false;
|
118
117
|
}
|
119
118
|
}
|
120
119
|
};
|
@@ -169,6 +168,7 @@ onMount(() => {
|
|
169
168
|
{/if}
|
170
169
|
</details>
|
171
170
|
{#if clientJs && item.open && transition}
|
171
|
+
<!-- outside the details for the transition -->
|
172
172
|
<div class={classContent} transition:slide={transition}>
|
173
173
|
<slot name="content" {item} {index}>{item.content}</slot>
|
174
174
|
</div>
|
@@ -49,7 +49,7 @@ export type AccordionSlots = typeof __propDef.slots;
|
|
49
49
|
/**
|
50
50
|
* ### Accordion
|
51
51
|
*
|
52
|
-
* Displays a list of `details` elements with helpful defaults and transitions.
|
52
|
+
* Displays a list of `details` elements with helpful defaults and transitions. Use `AccordionItem.data` to send any additional data through the slot props. Works without JavaScript.
|
53
53
|
*
|
54
54
|
* @props
|
55
55
|
*
|
@@ -98,7 +98,7 @@ export type AccordionSlots = typeof __propDef.slots;
|
|
98
98
|
* summary: "Is it animated?",
|
99
99
|
* content: "Yes, with the transition prop.",
|
100
100
|
* },
|
101
|
-
* { summary: "Does it work without
|
101
|
+
* { summary: "Does it work without JavaScript?", content: "Yes." },
|
102
102
|
* ]}
|
103
103
|
* />
|
104
104
|
*
|
@@ -20,11 +20,9 @@ With SvelteKit, this component can be wrapped in an `{#if dev}` block that check
|
|
20
20
|
import { Breakpoint } from "drab";
|
21
21
|
</script>
|
22
22
|
|
23
|
-
<
|
24
|
-
|
25
|
-
|
26
|
-
/>
|
27
|
-
</div>
|
23
|
+
<Breakpoint
|
24
|
+
class="inline-block rounded border px-2 py-1 font-mono tabular-nums shadow"
|
25
|
+
/>
|
28
26
|
```
|
29
27
|
-->
|
30
28
|
|
@@ -36,11 +36,9 @@ export type BreakpointSlots = typeof __propDef.slots;
|
|
36
36
|
* import { Breakpoint } from "drab";
|
37
37
|
* </script>
|
38
38
|
*
|
39
|
-
* <div>
|
40
39
|
* <Breakpoint
|
41
|
-
*
|
40
|
+
* class="inline-block rounded border px-2 py-1 font-mono tabular-nums shadow"
|
42
41
|
* />
|
43
|
-
* </div>
|
44
42
|
* ```
|
45
43
|
*/
|
46
44
|
export default class Breakpoint extends SvelteComponent<BreakpointProps, BreakpointEvents, BreakpointSlots> {
|
@@ -3,13 +3,14 @@
|
|
3
3
|
|
4
4
|
### ContextMenu
|
5
5
|
|
6
|
-
Displays when the
|
6
|
+
Displays when the `target` element is right clicked, or long pressed on mobile.
|
7
7
|
|
8
8
|
@props
|
9
9
|
|
10
10
|
- `class`
|
11
|
-
- `display` -
|
11
|
+
- `display` - shows / hides the menu
|
12
12
|
- `id`
|
13
|
+
- `target` - target element to right click, defaults to the parent element
|
13
14
|
- `transition` - fades the content, set to `false` to remove
|
14
15
|
|
15
16
|
@slots
|
@@ -21,12 +22,14 @@ Displays when the parent element is right clicked, or long pressed on mobile.
|
|
21
22
|
@example
|
22
23
|
|
23
24
|
```svelte
|
24
|
-
<script>
|
25
|
+
<script lang="ts">
|
25
26
|
import { ContextMenu } from "drab";
|
27
|
+
|
28
|
+
let target: HTMLButtonElement;
|
26
29
|
</script>
|
27
30
|
|
28
|
-
<div class="flex justify-center rounded border border-dashed p-12">
|
29
|
-
<div>
|
31
|
+
<div class="mb-8 flex justify-center rounded border border-dashed p-12">
|
32
|
+
<div>Parent right click</div>
|
30
33
|
<ContextMenu>
|
31
34
|
<div class="flex w-48 flex-col gap-2 rounded border bg-white p-2 shadow">
|
32
35
|
<div class="font-bold">Context Menu</div>
|
@@ -36,13 +39,22 @@ Displays when the parent element is right clicked, or long pressed on mobile.
|
|
36
39
|
</div>
|
37
40
|
</ContextMenu>
|
38
41
|
</div>
|
42
|
+
|
43
|
+
<button class="btn" bind:this={target}>Target Right Click</button>
|
44
|
+
<ContextMenu {target}>
|
45
|
+
<div class="flex w-48 flex-col gap-2 rounded border bg-white p-2 shadow">
|
46
|
+
<div class="font-bold">Context Menu</div>
|
47
|
+
<button role="menuitem" class="btn">Button</button>
|
48
|
+
<button role="menuitem" class="btn">Button</button>
|
49
|
+
<button role="menuitem" class="btn">Button</button>
|
50
|
+
</div>
|
51
|
+
</ContextMenu>
|
39
52
|
```
|
40
53
|
-->
|
41
54
|
|
42
55
|
<script>import { onMount, tick } from "svelte";
|
43
56
|
import { fade } from "svelte/transition";
|
44
57
|
import { duration } from "../util/transition";
|
45
|
-
import { messageNoScript } from "../util/messages";
|
46
58
|
import { prefersReducedMotion } from "../util/accessibility";
|
47
59
|
import { delay } from "../util/delay";
|
48
60
|
let className = "";
|
@@ -50,6 +62,7 @@ export { className as class };
|
|
50
62
|
export let id = "";
|
51
63
|
export let display = false;
|
52
64
|
export let transition = { duration };
|
65
|
+
export let target = null;
|
53
66
|
let contextMenu;
|
54
67
|
let base;
|
55
68
|
let coordinates = { x: 0, y: 0 };
|
@@ -94,12 +107,14 @@ onMount(() => {
|
|
94
107
|
if (transition)
|
95
108
|
transition.duration = 0;
|
96
109
|
}
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
110
|
+
if (!target) {
|
111
|
+
target = base.parentElement;
|
112
|
+
}
|
113
|
+
if (target) {
|
114
|
+
target.addEventListener("contextmenu", displayMenu);
|
115
|
+
target.addEventListener("touchstart", onTouchStart);
|
116
|
+
target.addEventListener("touchend", onTouchEnd);
|
117
|
+
target.addEventListener("touchcancel", onTouchEnd);
|
103
118
|
}
|
104
119
|
});
|
105
120
|
</script>
|
@@ -4,8 +4,9 @@ declare const __propDef: {
|
|
4
4
|
props: {
|
5
5
|
class?: string | undefined;
|
6
6
|
id?: string | undefined;
|
7
|
-
/**
|
7
|
+
/** shows / hides the menu */ display?: boolean | undefined;
|
8
8
|
/** fades the content, set to `false` to remove */ transition?: false | FadeParams | undefined;
|
9
|
+
/** target element to right click, defaults to the parent element */ target?: HTMLElement | null | undefined;
|
9
10
|
};
|
10
11
|
events: {
|
11
12
|
[evt: string]: CustomEvent<any>;
|
@@ -20,13 +21,14 @@ export type ContextMenuSlots = typeof __propDef.slots;
|
|
20
21
|
/**
|
21
22
|
* ### ContextMenu
|
22
23
|
*
|
23
|
-
* Displays when the
|
24
|
+
* Displays when the `target` element is right clicked, or long pressed on mobile.
|
24
25
|
*
|
25
26
|
* @props
|
26
27
|
*
|
27
28
|
* - `class`
|
28
|
-
* - `display` -
|
29
|
+
* - `display` - shows / hides the menu
|
29
30
|
* - `id`
|
31
|
+
* - `target` - target element to right click, defaults to the parent element
|
30
32
|
* - `transition` - fades the content, set to `false` to remove
|
31
33
|
*
|
32
34
|
* @slots
|
@@ -38,12 +40,14 @@ export type ContextMenuSlots = typeof __propDef.slots;
|
|
38
40
|
* @example
|
39
41
|
*
|
40
42
|
* ```svelte
|
41
|
-
* <script>
|
43
|
+
* <script lang="ts">
|
42
44
|
* import { ContextMenu } from "drab";
|
45
|
+
*
|
46
|
+
* let target: HTMLButtonElement;
|
43
47
|
* </script>
|
44
48
|
*
|
45
|
-
* <div class="flex justify-center rounded border border-dashed p-12">
|
46
|
-
* <div>
|
49
|
+
* <div class="mb-8 flex justify-center rounded border border-dashed p-12">
|
50
|
+
* <div>Parent right click</div>
|
47
51
|
* <ContextMenu>
|
48
52
|
* <div class="flex w-48 flex-col gap-2 rounded border bg-white p-2 shadow">
|
49
53
|
* <div class="font-bold">Context Menu</div>
|
@@ -53,6 +57,16 @@ export type ContextMenuSlots = typeof __propDef.slots;
|
|
53
57
|
* </div>
|
54
58
|
* </ContextMenu>
|
55
59
|
* </div>
|
60
|
+
*
|
61
|
+
* <button class="btn" bind:this={target}>Target Right Click</button>
|
62
|
+
* <ContextMenu {target}>
|
63
|
+
* <div class="flex w-48 flex-col gap-2 rounded border bg-white p-2 shadow">
|
64
|
+
* <div class="font-bold">Context Menu</div>
|
65
|
+
* <button role="menuitem" class="btn">Button</button>
|
66
|
+
* <button role="menuitem" class="btn">Button</button>
|
67
|
+
* <button role="menuitem" class="btn">Button</button>
|
68
|
+
* </div>
|
69
|
+
* </ContextMenu>
|
56
70
|
* ```
|
57
71
|
*/
|
58
72
|
export default class ContextMenu extends SvelteComponent<ContextMenuProps, ContextMenuEvents, ContextMenuSlots> {
|
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
### CopyButton
|
5
5
|
|
6
|
-
Uses the [Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/writeText) to copy text to the clipboard.
|
6
|
+
Uses the [Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/writeText) to copy text to the clipboard. If JavaScript is disabled, the button is disabled and `text` is displayed after the button.
|
7
7
|
|
8
8
|
@props
|
9
9
|
|
@@ -23,13 +23,11 @@ Uses the [Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipbo
|
|
23
23
|
@example
|
24
24
|
|
25
25
|
```svelte
|
26
|
-
<script>
|
26
|
+
<script lang="ts">
|
27
27
|
import { CopyButton } from "drab";
|
28
28
|
</script>
|
29
29
|
|
30
|
-
<
|
31
|
-
<CopyButton class="btn" text="Text to copy" />
|
32
|
-
</div>
|
30
|
+
<CopyButton class="btn" text="Text to copy" />
|
33
31
|
```
|
34
32
|
-->
|
35
33
|
|
@@ -21,7 +21,7 @@ export type CopyButtonSlots = typeof __propDef.slots;
|
|
21
21
|
/**
|
22
22
|
* ### CopyButton
|
23
23
|
*
|
24
|
-
* Uses the [Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/writeText) to copy text to the clipboard.
|
24
|
+
* Uses the [Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/writeText) to copy text to the clipboard. If JavaScript is disabled, the button is disabled and `text` is displayed after the button.
|
25
25
|
*
|
26
26
|
* @props
|
27
27
|
*
|
@@ -41,13 +41,11 @@ export type CopyButtonSlots = typeof __propDef.slots;
|
|
41
41
|
* @example
|
42
42
|
*
|
43
43
|
* ```svelte
|
44
|
-
* <script>
|
44
|
+
* <script lang="ts">
|
45
45
|
* import { CopyButton } from "drab";
|
46
46
|
* </script>
|
47
47
|
*
|
48
|
-
* <div>
|
49
48
|
* <CopyButton class="btn" text="Text to copy" />
|
50
|
-
* </div>
|
51
49
|
* ```
|
52
50
|
*/
|
53
51
|
export default class CopyButton extends SvelteComponent<CopyButtonProps, CopyButtonEvents, CopyButtonSlots> {
|
@@ -3,13 +3,13 @@
|
|
3
3
|
|
4
4
|
### DataTable
|
5
5
|
|
6
|
-
Data table to display an array of JS objects.
|
6
|
+
Data table to display an array of JS objects. Provides sorting and pagination. Set the `maxRows` prop to enable pagination. Data can be styled conditionally with slot props.
|
7
7
|
|
8
8
|
@props
|
9
9
|
|
10
|
-
- `ascending` -
|
10
|
+
- `ascending` - current sort order
|
11
11
|
- `classButton` - `button` class
|
12
|
-
- `classFooter` -
|
12
|
+
- `classFooter` - footer class
|
13
13
|
- `classNoscript` - `noscript` class
|
14
14
|
- `classPageControls` - class of `div` that wraps the "Previous" and "Next" buttons
|
15
15
|
- `classPageNumber` - class of `div` wrapping page numbers
|
@@ -30,6 +30,7 @@ Data table to display an array of JS objects. Click a column header to sort.
|
|
30
30
|
- `id`
|
31
31
|
- `maxRows` - maximum number of rows to show on each page, defaults to `0` - no pagination
|
32
32
|
- `sortBy` - column to sort by, defaults to first column
|
33
|
+
- `transition` - fades the rows in, set to `false` to disable
|
33
34
|
|
34
35
|
@slots
|
35
36
|
|
@@ -44,7 +45,7 @@ Data table to display an array of JS objects. Click a column header to sort.
|
|
44
45
|
@example
|
45
46
|
|
46
47
|
```svelte
|
47
|
-
<script>
|
48
|
+
<script lang="ts">
|
48
49
|
import { DataTable } from "drab";
|
49
50
|
</script>
|
50
51
|
|
@@ -109,8 +110,11 @@ Data table to display an array of JS objects. Click a column header to sort.
|
|
109
110
|
|
110
111
|
<script context="module"></script>
|
111
112
|
|
112
|
-
<script>import {
|
113
|
-
import {
|
113
|
+
<script>import { onMount } from "svelte";
|
114
|
+
import { fade } from "svelte/transition";
|
115
|
+
import { duration } from "../util/transition";
|
116
|
+
import { prefersReducedMotion } from "../util/accessibility";
|
117
|
+
import { messageNoScript } from "../util/messages";
|
114
118
|
let className = "";
|
115
119
|
export { className as class };
|
116
120
|
export let id = "";
|
@@ -137,6 +141,7 @@ export let classPageNumber = "";
|
|
137
141
|
export let classPageControls = "";
|
138
142
|
export let maxRows = 0;
|
139
143
|
export let currentPage = 1;
|
144
|
+
export let transition = { duration };
|
140
145
|
export let classNoscript = "";
|
141
146
|
let clientJs = false;
|
142
147
|
$:
|
@@ -175,8 +180,21 @@ const sort = (column, toggleAscending = true) => {
|
|
175
180
|
data = data;
|
176
181
|
sortBy = column;
|
177
182
|
};
|
183
|
+
const showRow = (i, currentPage2) => {
|
184
|
+
if (!maxRows)
|
185
|
+
return true;
|
186
|
+
const overMin = i >= maxRows * (currentPage2 - 1);
|
187
|
+
const underMax = i < maxRows * currentPage2;
|
188
|
+
return overMin && underMax;
|
189
|
+
};
|
178
190
|
sort(sortBy, false);
|
179
|
-
onMount(() =>
|
191
|
+
onMount(() => {
|
192
|
+
if (prefersReducedMotion()) {
|
193
|
+
if (transition)
|
194
|
+
transition.duration = 0;
|
195
|
+
}
|
196
|
+
clientJs = true;
|
197
|
+
});
|
180
198
|
</script>
|
181
199
|
|
182
200
|
<div class={className} {id}>
|
@@ -195,10 +213,11 @@ onMount(() => clientJs = true);
|
|
195
213
|
</thead>
|
196
214
|
<tbody class={classTbody}>
|
197
215
|
{#each data as row, i}
|
198
|
-
{
|
199
|
-
|
200
|
-
|
201
|
-
|
216
|
+
{#if showRow(i, currentPage)}
|
217
|
+
<tr
|
218
|
+
in:fade={transition ? transition : { duration: 0 }}
|
219
|
+
class={classTbodyTr}
|
220
|
+
>
|
202
221
|
{#each columns as column}
|
203
222
|
<td class="{classTd} {sortBy === column ? classTdSorted : ''}">
|
204
223
|
<slot name="td" {row} {column}>{row[column]}</slot>
|
@@ -237,10 +256,6 @@ onMount(() => clientJs = true);
|
|
237
256
|
</div>
|
238
257
|
</div>
|
239
258
|
|
240
|
-
<noscript>
|
241
|
-
<div class={classNoscript}>
|
242
|
-
{messageNoScript}
|
243
|
-
</div>
|
244
|
-
</noscript>
|
259
|
+
<noscript><div class={classNoscript}>{messageNoScript}</div></noscript>
|
245
260
|
{/if}
|
246
261
|
</div>
|
@@ -2,6 +2,7 @@ import { SvelteComponent } from "svelte";
|
|
2
2
|
export type DataTableRow<T> = {
|
3
3
|
[K in keyof T]: T[K];
|
4
4
|
};
|
5
|
+
import { type FadeParams } from "svelte/transition";
|
5
6
|
declare const __propDef: {
|
6
7
|
props: {
|
7
8
|
class?: string | undefined;
|
@@ -9,7 +10,7 @@ declare const __propDef: {
|
|
9
10
|
/** a list of objects to render in the table */ data: DataTableRow<any>[];
|
10
11
|
/** table columns, in order */ columns?: string[] | undefined;
|
11
12
|
/** column to sort by, defaults to first column */ sortBy?: string | undefined;
|
12
|
-
/**
|
13
|
+
/** current sort order */ ascending?: boolean | undefined;
|
13
14
|
/** `table` class */ classTable?: string | undefined;
|
14
15
|
/** `table` id */ idTable?: string | undefined;
|
15
16
|
/** `thead` class */ classThead?: string | undefined;
|
@@ -21,11 +22,12 @@ declare const __propDef: {
|
|
21
22
|
/** currently sorted `th` */ classThSorted?: string | undefined;
|
22
23
|
/** currently sorted `td` */ classTdSorted?: string | undefined;
|
23
24
|
/** `button` class */ classButton?: string | undefined;
|
24
|
-
/**
|
25
|
+
/** footer class */ classFooter?: string | undefined;
|
25
26
|
/** class of `div` wrapping page numbers */ classPageNumber?: string | undefined;
|
26
27
|
/** class of `div` that wraps the "Previous" and "Next" buttons */ classPageControls?: string | undefined;
|
27
28
|
/** maximum number of rows to show on each page, defaults to `0` - no pagination */ maxRows?: number | undefined;
|
28
29
|
/** current page, defaults to `1` */ currentPage?: number | undefined;
|
30
|
+
/** fades the rows in, set to `false` to disable */ transition?: false | FadeParams | undefined;
|
29
31
|
/** `noscript` class */ classNoscript?: string | undefined;
|
30
32
|
};
|
31
33
|
events: {
|
@@ -57,13 +59,13 @@ export type DataTableSlots = typeof __propDef.slots;
|
|
57
59
|
/**
|
58
60
|
* ### DataTable
|
59
61
|
*
|
60
|
-
* Data table to display an array of JS objects.
|
62
|
+
* Data table to display an array of JS objects. Provides sorting and pagination. Set the `maxRows` prop to enable pagination. Data can be styled conditionally with slot props.
|
61
63
|
*
|
62
64
|
* @props
|
63
65
|
*
|
64
|
-
* - `ascending` -
|
66
|
+
* - `ascending` - current sort order
|
65
67
|
* - `classButton` - `button` class
|
66
|
-
* - `classFooter` -
|
68
|
+
* - `classFooter` - footer class
|
67
69
|
* - `classNoscript` - `noscript` class
|
68
70
|
* - `classPageControls` - class of `div` that wraps the "Previous" and "Next" buttons
|
69
71
|
* - `classPageNumber` - class of `div` wrapping page numbers
|
@@ -84,6 +86,7 @@ export type DataTableSlots = typeof __propDef.slots;
|
|
84
86
|
* - `id`
|
85
87
|
* - `maxRows` - maximum number of rows to show on each page, defaults to `0` - no pagination
|
86
88
|
* - `sortBy` - column to sort by, defaults to first column
|
89
|
+
* - `transition` - fades the rows in, set to `false` to disable
|
87
90
|
*
|
88
91
|
* @slots
|
89
92
|
*
|
@@ -98,7 +101,7 @@ export type DataTableSlots = typeof __propDef.slots;
|
|
98
101
|
* @example
|
99
102
|
*
|
100
103
|
* ```svelte
|
101
|
-
* <script>
|
104
|
+
* <script lang="ts">
|
102
105
|
* import { DataTable } from "drab";
|
103
106
|
* </script>
|
104
107
|
*
|
@@ -3,7 +3,9 @@
|
|
3
3
|
|
4
4
|
### Editor
|
5
5
|
|
6
|
-
|
6
|
+
`textarea` element with controls to add content and keyboard shortcuts. Compared to other WYSIWYG editors, this component's value 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)
|
7
9
|
|
8
10
|
@props
|
9
11
|
|
@@ -17,13 +19,13 @@ Text editor with controls to add elements and keyboard shortcuts.
|
|
17
19
|
- `keyPairs` - keys that will auto-close if typed, value is their closing character
|
18
20
|
- `nameTextarea` - `name` of the `textarea` element
|
19
21
|
- `placeholderTextarea` - `placeholder` of the `textarea` element
|
20
|
-
- `
|
22
|
+
- `selectionStartTextarea` - `selectionStart` value of the `textarea`
|
21
23
|
- `valueTextarea` - `value` of the `textarea` element
|
22
24
|
|
23
25
|
@example
|
24
26
|
|
25
27
|
```svelte
|
26
|
-
<script>
|
28
|
+
<script lang="ts">
|
27
29
|
import { Editor } from "drab";
|
28
30
|
</script>
|
29
31
|
|
@@ -72,7 +74,7 @@ export let nameTextarea = "";
|
|
72
74
|
export let classButton = "";
|
73
75
|
export let classControls = "";
|
74
76
|
export let idControls = "";
|
75
|
-
export let
|
77
|
+
export let selectionStartTextarea = 0;
|
76
78
|
export let keyPairs = {
|
77
79
|
"(": ")",
|
78
80
|
"{": "}",
|
@@ -95,11 +97,11 @@ const insertChar = (str, char, index) => {
|
|
95
97
|
const removeChar = (str, index) => {
|
96
98
|
return str.slice(0, index) + str.slice(index + 1);
|
97
99
|
};
|
98
|
-
const insertText = async (el,
|
100
|
+
const insertText = async (el, selectionStart, selectionEnd) => {
|
99
101
|
if (el.display === "inline") {
|
100
102
|
valueTextarea = `${valueTextarea.slice(0, selectionEnd)}${el.text}${valueTextarea.slice(selectionEnd)}`;
|
101
103
|
} else if (el.display === "wrap") {
|
102
|
-
valueTextarea = insertChar(valueTextarea, el.text,
|
104
|
+
valueTextarea = insertChar(valueTextarea, el.text, selectionStart);
|
103
105
|
valueTextarea = insertChar(
|
104
106
|
valueTextarea,
|
105
107
|
keyPairs[el.text],
|
@@ -117,7 +119,7 @@ const insertText = async (el, selectionStart2, selectionEnd) => {
|
|
117
119
|
valueTextarea = lines.join("\n");
|
118
120
|
}
|
119
121
|
};
|
120
|
-
const setCaretPosition = async (text,
|
122
|
+
const setCaretPosition = async (text, selectionStart, selectionEnd) => {
|
121
123
|
let startPos = 0;
|
122
124
|
let endPos = 0;
|
123
125
|
if (/[a-z]/i.test(text)) {
|
@@ -133,7 +135,7 @@ const setCaretPosition = async (text, selectionStart2, selectionEnd) => {
|
|
133
135
|
}
|
134
136
|
}
|
135
137
|
} else {
|
136
|
-
startPos =
|
138
|
+
startPos = selectionStart + text.length;
|
137
139
|
endPos = selectionEnd + text.length;
|
138
140
|
}
|
139
141
|
textArea.setSelectionRange(startPos, endPos);
|
@@ -141,9 +143,9 @@ const setCaretPosition = async (text, selectionStart2, selectionEnd) => {
|
|
141
143
|
};
|
142
144
|
const addContent = async (el) => {
|
143
145
|
const selectionEnd = textArea.selectionEnd;
|
144
|
-
const
|
145
|
-
await insertText(el,
|
146
|
-
setCaretPosition(el.text,
|
146
|
+
const selectionStart = textArea.selectionStart;
|
147
|
+
await insertText(el, selectionStart, selectionEnd);
|
148
|
+
setCaretPosition(el.text, selectionStart, selectionEnd);
|
147
149
|
};
|
148
150
|
const onKeyDown = async (e) => {
|
149
151
|
const resetKeys = ["ArrowUp", "ArrowDown", "Delete"];
|
@@ -267,7 +269,7 @@ const trimSelection = () => {
|
|
267
269
|
}
|
268
270
|
};
|
269
271
|
const updateSelectionStart = () => {
|
270
|
-
|
272
|
+
selectionStartTextarea = textArea.selectionStart;
|
271
273
|
};
|
272
274
|
const getLineInfo = () => {
|
273
275
|
const lines = valueTextarea.split("\n");
|
@@ -30,7 +30,7 @@ declare const __propDef: {
|
|
30
30
|
/** `class` of all the `button` elements */ classButton?: string | undefined;
|
31
31
|
/** `class` of the `div` that wraps the controls */ classControls?: string | undefined;
|
32
32
|
/** `id` of the `div` that wraps the controls */ idControls?: string | undefined;
|
33
|
-
/** `selectionStart` value of the
|
33
|
+
/** `selectionStart` value of the `textarea` */ selectionStartTextarea?: number | undefined;
|
34
34
|
/** keys that will auto-close if typed, value is their closing character */ keyPairs?: {
|
35
35
|
[key: string]: string;
|
36
36
|
} | undefined;
|
@@ -49,7 +49,9 @@ export type EditorSlots = typeof __propDef.slots;
|
|
49
49
|
/**
|
50
50
|
* ### Editor
|
51
51
|
*
|
52
|
-
*
|
52
|
+
* `textarea` element with controls to add content and keyboard shortcuts. Compared to other WYSIWYG editors, this component's value is just a `string` so you can easily store it in a database or manipulate it without learning a separate API.
|
53
|
+
*
|
54
|
+
* - This component is used to create [Typo](https://typo.robino.dev)
|
53
55
|
*
|
54
56
|
* @props
|
55
57
|
*
|
@@ -63,13 +65,13 @@ export type EditorSlots = typeof __propDef.slots;
|
|
63
65
|
* - `keyPairs` - keys that will auto-close if typed, value is their closing character
|
64
66
|
* - `nameTextarea` - `name` of the `textarea` element
|
65
67
|
* - `placeholderTextarea` - `placeholder` of the `textarea` element
|
66
|
-
* - `
|
68
|
+
* - `selectionStartTextarea` - `selectionStart` value of the `textarea`
|
67
69
|
* - `valueTextarea` - `value` of the `textarea` element
|
68
70
|
*
|
69
71
|
* @example
|
70
72
|
*
|
71
73
|
* ```svelte
|
72
|
-
* <script>
|
74
|
+
* <script lang="ts">
|
73
75
|
* import { Editor } from "drab";
|
74
76
|
* </script>
|
75
77
|
*
|