@sveltia/ui 0.77.2 → 0.77.3
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/components/text-editor/lexical-root.svelte +24 -0
- package/dist/components/text-editor/lexical-root.svelte.d.ts +10 -0
- package/dist/components/text-editor/shiki/version.d.ts +1 -1
- package/dist/components/text-editor/shiki/version.js +1 -1
- package/dist/components/text-editor/text-editor.svelte +3 -1
- package/dist/components/text-editor/text-editor.svelte.d.ts +4 -2
- package/dist/components/text-editor/toolbar/code-language-switcher.svelte +14 -9
- package/package.json +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script>
|
|
2
|
+
import { $getRoot as getRoot } from 'lexical';
|
|
2
3
|
import { getContext, onMount } from 'svelte';
|
|
3
4
|
import { initEditor } from './core.js';
|
|
4
5
|
|
|
@@ -10,6 +11,8 @@
|
|
|
10
11
|
/**
|
|
11
12
|
* @typedef {object} Props
|
|
12
13
|
* @property {string} [class] The `class` attribute on the wrapper element.
|
|
14
|
+
* @property {'ltr' | 'rtl' | 'auto'} [dir] Direction of the text. With `auto` or no value, each
|
|
15
|
+
* paragraph takes the direction of its own text.
|
|
13
16
|
* @property {boolean} [hidden] Whether to hide the widget.
|
|
14
17
|
* @property {boolean} [disabled] Whether to disable the widget. An alias of the `aria-disabled`
|
|
15
18
|
* attribute.
|
|
@@ -28,6 +31,7 @@
|
|
|
28
31
|
let {
|
|
29
32
|
/* eslint-disable prefer-const */
|
|
30
33
|
class: className,
|
|
34
|
+
dir = undefined,
|
|
31
35
|
hidden = false,
|
|
32
36
|
disabled = false,
|
|
33
37
|
readonly = false,
|
|
@@ -53,6 +57,26 @@
|
|
|
53
57
|
editorStore.editor?.setEditable(editable);
|
|
54
58
|
});
|
|
55
59
|
|
|
60
|
+
$effect(() => {
|
|
61
|
+
// Lexical owns the root element’s `dir` attribute, so set the direction on the root node, which
|
|
62
|
+
// the paragraphs then follow. Without one, each paragraph gets `dir="auto"`
|
|
63
|
+
const { editor } = editorStore;
|
|
64
|
+
const direction = dir === 'ltr' || dir === 'rtl' ? dir : null;
|
|
65
|
+
|
|
66
|
+
// Check first, as even an update that changes nothing makes the editor convert its content
|
|
67
|
+
if (!editor || editor.getEditorState().read(() => getRoot().getDirection()) === direction) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
editor.update(
|
|
72
|
+
() => {
|
|
73
|
+
getRoot().setDirection(direction);
|
|
74
|
+
},
|
|
75
|
+
// Keep the change out of the undo history
|
|
76
|
+
{ tag: 'history-merge' },
|
|
77
|
+
);
|
|
78
|
+
});
|
|
79
|
+
|
|
56
80
|
/**
|
|
57
81
|
* Update {@link value} and other state variables whenever the editor content is updated.
|
|
58
82
|
* @param {Event} event `Update` custom event.
|
|
@@ -8,6 +8,11 @@ declare const LexicalRoot: import("svelte").Component<{
|
|
|
8
8
|
* The `class` attribute on the wrapper element.
|
|
9
9
|
*/
|
|
10
10
|
class?: string | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* Direction of the text. With `auto` or no value, each
|
|
13
|
+
* paragraph takes the direction of its own text.
|
|
14
|
+
*/
|
|
15
|
+
dir?: "ltr" | "rtl" | "auto" | undefined;
|
|
11
16
|
/**
|
|
12
17
|
* Whether to hide the widget.
|
|
13
18
|
*/
|
|
@@ -42,6 +47,11 @@ type Props = {
|
|
|
42
47
|
* The `class` attribute on the wrapper element.
|
|
43
48
|
*/
|
|
44
49
|
class?: string | undefined;
|
|
50
|
+
/**
|
|
51
|
+
* Direction of the text. With `auto` or no value, each
|
|
52
|
+
* paragraph takes the direction of its own text.
|
|
53
|
+
*/
|
|
54
|
+
dir?: "ltr" | "rtl" | "auto" | undefined;
|
|
45
55
|
/**
|
|
46
56
|
* Whether to hide the widget.
|
|
47
57
|
*/
|
|
@@ -23,7 +23,8 @@
|
|
|
23
23
|
* @typedef {object} Props
|
|
24
24
|
* @property {string} [value] Input value.
|
|
25
25
|
* @property {boolean} [flex] Make the text input container flexible.
|
|
26
|
-
* @property {'ltr' | 'rtl' | 'auto'} [dir] The `dir` attribute on the
|
|
26
|
+
* @property {'ltr' | 'rtl' | 'auto'} [dir] The `dir` attribute on the editable text box, both
|
|
27
|
+
* the rich text editor and the `<textarea>` element of the plain text mode.
|
|
27
28
|
* @property {TextEditorMode[]} [modes] Enabled modes.
|
|
28
29
|
* @property {TextEditorNodeType[]} [buttons] Enabled buttons.
|
|
29
30
|
* @property {TextEditorComponent[]} [components] Editor components.
|
|
@@ -137,6 +138,7 @@
|
|
|
137
138
|
<TextEditorToolbar {disabled} {readonly} />
|
|
138
139
|
<LexicalRoot
|
|
139
140
|
{...labelAttrs}
|
|
141
|
+
{dir}
|
|
140
142
|
hidden={!editorStore.useRichText || hidden}
|
|
141
143
|
{disabled}
|
|
142
144
|
{readonly}
|
|
@@ -14,7 +14,8 @@ declare const TextEditor: import("svelte").Component<{
|
|
|
14
14
|
*/
|
|
15
15
|
flex?: boolean | undefined;
|
|
16
16
|
/**
|
|
17
|
-
* The `dir` attribute on the
|
|
17
|
+
* The `dir` attribute on the editable text box, both
|
|
18
|
+
* the rich text editor and the `<textarea>` element of the plain text mode.
|
|
18
19
|
*/
|
|
19
20
|
dir?: "ltr" | "rtl" | "auto" | undefined;
|
|
20
21
|
/**
|
|
@@ -96,7 +97,8 @@ type Props = {
|
|
|
96
97
|
*/
|
|
97
98
|
flex?: boolean | undefined;
|
|
98
99
|
/**
|
|
99
|
-
* The `dir` attribute on the
|
|
100
|
+
* The `dir` attribute on the editable text box, both
|
|
101
|
+
* the rich text editor and the `<textarea>` element of the plain text mode.
|
|
100
102
|
*/
|
|
101
103
|
dir?: "ltr" | "rtl" | "auto" | undefined;
|
|
102
104
|
/**
|
|
@@ -36,6 +36,16 @@
|
|
|
36
36
|
|
|
37
37
|
let selectedLanguage = $state('plain');
|
|
38
38
|
|
|
39
|
+
// A code block can carry an alias, e.g. `js`, while the options are keyed by the canonical ID,
|
|
40
|
+
// e.g. `javascript`, so resolve the alias for the selector to find its option. A language that
|
|
41
|
+
// isn’t listed, e.g. `txt`, is shown as plain text; otherwise the selector would keep the label
|
|
42
|
+
// of the previous block, as it only updates the label when an option matches
|
|
43
|
+
const selectedKey = $derived(
|
|
44
|
+
codeLanguages.find(
|
|
45
|
+
({ key, aliases }) => key === selectedLanguage || aliases.includes(selectedLanguage),
|
|
46
|
+
)?.key ?? 'plain',
|
|
47
|
+
);
|
|
48
|
+
|
|
39
49
|
$effect(() => {
|
|
40
50
|
void editorStore.selection.blockNodeKey;
|
|
41
51
|
|
|
@@ -57,9 +67,9 @@
|
|
|
57
67
|
<Select
|
|
58
68
|
{disabled}
|
|
59
69
|
ariaLabel={_('_sui.text_editor.language')}
|
|
60
|
-
value={
|
|
70
|
+
value={selectedKey}
|
|
61
71
|
onChange={async ({ detail: { value: lang } }) => {
|
|
62
|
-
if (!editorStore.editor ||
|
|
72
|
+
if (!editorStore.editor || selectedKey === lang) {
|
|
63
73
|
return;
|
|
64
74
|
}
|
|
65
75
|
|
|
@@ -87,12 +97,7 @@
|
|
|
87
97
|
}}
|
|
88
98
|
>
|
|
89
99
|
<Option label={_('_sui.text_editor.plain_text')} value="plain" dir="ltr" />
|
|
90
|
-
{#each codeLanguages as { key, label
|
|
91
|
-
<Option
|
|
92
|
-
{label}
|
|
93
|
-
value={key}
|
|
94
|
-
selected={key === selectedLanguage || aliases.includes(selectedLanguage)}
|
|
95
|
-
dir="ltr"
|
|
96
|
-
/>
|
|
100
|
+
{#each codeLanguages as { key, label } (key)}
|
|
101
|
+
<Option {label} value={key} selected={key === selectedKey} dir="ltr" />
|
|
97
102
|
{/each}
|
|
98
103
|
</Select>
|