@sveltia/ui 0.23.2 → 0.24.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.
Files changed (33) hide show
  1. package/dist/components/text-editor/code-editor.svelte +121 -0
  2. package/dist/components/text-editor/code-editor.svelte.d.ts +106 -0
  3. package/dist/components/text-editor/core.d.ts +3 -4
  4. package/dist/components/text-editor/core.js +78 -33
  5. package/dist/components/text-editor/lexical-root.svelte +42 -19
  6. package/dist/components/text-editor/lexical-root.svelte.d.ts +1 -9
  7. package/dist/components/text-editor/store.svelte.d.ts +1 -0
  8. package/dist/components/text-editor/store.svelte.js +120 -0
  9. package/dist/components/text-editor/text-editor.svelte +21 -86
  10. package/dist/components/text-editor/toolbar/code-editor-toolbar.svelte +28 -0
  11. package/dist/components/text-editor/toolbar/{editor-toolbar.svelte.d.ts → code-editor-toolbar.svelte.d.ts} +3 -3
  12. package/dist/components/text-editor/toolbar/code-language-switcher.svelte +96 -0
  13. package/dist/components/text-editor/toolbar/code-language-switcher.svelte.d.ts +17 -0
  14. package/dist/components/text-editor/toolbar/format-text-button.svelte +10 -10
  15. package/dist/components/text-editor/toolbar/insert-image-button.svelte +5 -8
  16. package/dist/components/text-editor/toolbar/insert-link-button.svelte +27 -25
  17. package/dist/components/text-editor/toolbar/insert-menu-button.svelte +4 -7
  18. package/dist/components/text-editor/toolbar/{editor-toolbar.svelte → text-editor-toolbar.svelte} +59 -87
  19. package/dist/components/text-editor/toolbar/text-editor-toolbar.svelte.d.ts +37 -0
  20. package/dist/components/text-editor/toolbar/toggle-block-menu-item.svelte +14 -17
  21. package/dist/components/text-editor/toolbar/toolbar-wrapper.svelte +58 -0
  22. package/dist/components/text-editor/toolbar/toolbar-wrapper.svelte.d.ts +37 -0
  23. package/dist/components/util/app-shell.svelte +2 -2
  24. package/dist/index.d.ts +1 -0
  25. package/dist/index.js +1 -0
  26. package/dist/locales/en.d.ts +3 -0
  27. package/dist/locales/en.js +3 -0
  28. package/dist/locales/ja.d.ts +3 -0
  29. package/dist/locales/ja.js +3 -0
  30. package/dist/styles/variables.scss +2 -2
  31. package/dist/typedefs.d.ts +59 -26
  32. package/dist/typedefs.js +26 -13
  33. package/package.json +5 -5
@@ -0,0 +1,121 @@
1
+ <!--
2
+ @component
3
+ A code editor based on Lexical.
4
+ -->
5
+ <script>
6
+ import { setContext, untrack } from 'svelte';
7
+ import { _ } from 'svelte-i18n';
8
+ import Alert from '../alert/alert.svelte';
9
+ import Toast from '../toast/toast.svelte';
10
+ import LexicalRoot from './lexical-root.svelte';
11
+ import { createEditorStore } from './store.svelte';
12
+ import CodeEditorToolbar from './toolbar/code-editor-toolbar.svelte';
13
+
14
+ /**
15
+ * @typedef {object} Props
16
+ * @property {string} [code] - Input value.
17
+ * @property {string} [lang] - Selected language.
18
+ * @property {boolean} [showLanguageSwitcher] - Whether to show the language selector.
19
+ * @property {boolean} [flex] - Make the text input container flexible.
20
+ * @property {string} [class] - The `class` attribute on the wrapper element.
21
+ * @property {boolean} [hidden] - Whether to hide the widget.
22
+ * @property {boolean} [disabled] - Whether to disable the widget. An alias of the `aria-disabled`
23
+ * attribute.
24
+ * @property {boolean} [readonly] - Whether to make the widget read-only. An alias of the
25
+ * `aria-readonly` attribute.
26
+ * @property {boolean} [required] - Whether to mark the widget required. An alias of the
27
+ * `aria-required` attribute.
28
+ * @property {boolean} [invalid] - Whether to mark the widget invalid. An alias of the
29
+ * `aria-invalid` attribute.
30
+ * @property {import('svelte').Snippet} [children] - Primary slot content.
31
+ */
32
+
33
+ /**
34
+ * @type {Props & Record<string, any>}
35
+ */
36
+ let {
37
+ /* eslint-disable prefer-const */
38
+ code = $bindable(''),
39
+ lang = $bindable(''),
40
+ showLanguageSwitcher = false,
41
+ flex = false,
42
+ hidden = false,
43
+ disabled = false,
44
+ readonly = false,
45
+ required = false,
46
+ invalid = false,
47
+ children,
48
+ ...restProps
49
+ /* eslint-enable prefer-const */
50
+ } = $props();
51
+
52
+ const backticks = '```';
53
+ const editorStore = createEditorStore();
54
+
55
+ editorStore.config.isCodeEditor = true;
56
+ editorStore.config.defaultLanguage = lang;
57
+
58
+ setContext('editorStore', editorStore);
59
+
60
+ $effect(() => {
61
+ if (!editorStore.initialized) {
62
+ return;
63
+ }
64
+
65
+ void code;
66
+ void lang;
67
+
68
+ untrack(() => {
69
+ const newValue = code
70
+ ? `${backticks}${lang}\n${code}\n${backticks}`
71
+ : `${backticks}${lang}\n${backticks}`;
72
+
73
+ editorStore.inputValue = newValue;
74
+ });
75
+ });
76
+
77
+ $effect(() => {
78
+ if (!editorStore.initialized) {
79
+ return;
80
+ }
81
+
82
+ void editorStore.inputValue;
83
+
84
+ untrack(() => {
85
+ const { lang: _lang = '', code: _code = '' } =
86
+ editorStore.inputValue.match(/^```(?<lang>\w+?)?\n(?:(?<code>.*)\n)?```/s)?.groups ?? {};
87
+
88
+ if (lang !== _lang) {
89
+ lang = _lang;
90
+ }
91
+
92
+ if (code !== _code) {
93
+ code = _code;
94
+ }
95
+ });
96
+ });
97
+ </script>
98
+
99
+ <div {...restProps} role="none" class="sui code-editor" class:flex {hidden}>
100
+ {#if showLanguageSwitcher}
101
+ <CodeEditorToolbar {disabled} {readonly} />
102
+ {/if}
103
+ <LexicalRoot
104
+ hidden={!editorStore.useRichText || hidden}
105
+ {disabled}
106
+ {readonly}
107
+ {required}
108
+ {invalid}
109
+ />
110
+ </div>
111
+
112
+ {#if editorStore.showConverterError}
113
+ <Toast bind:show={editorStore.showConverterError}>
114
+ <Alert status="error">{$_('_sui.text_editor.converter_error')}</Alert>
115
+ </Toast>
116
+ {/if}
117
+
118
+ <style>.code-editor {
119
+ margin: var(--sui-focus-ring-width);
120
+ width: calc(100% - var(--sui-focus-ring-width) * 2);
121
+ }</style>
@@ -0,0 +1,106 @@
1
+ export default CodeEditor;
2
+ type CodeEditor = {
3
+ $on?(type: string, callback: (e: any) => void): () => void;
4
+ $set?(props: Partial<Props & Record<string, any>>): void;
5
+ };
6
+ /** A code editor based on Lexical. */
7
+ declare const CodeEditor: import("svelte").Component<{
8
+ /**
9
+ * - Input value.
10
+ */
11
+ code?: string | undefined;
12
+ /**
13
+ * - Selected language.
14
+ */
15
+ lang?: string | undefined;
16
+ /**
17
+ * - Whether to show the language selector.
18
+ */
19
+ showLanguageSwitcher?: boolean | undefined;
20
+ /**
21
+ * - Make the text input container flexible.
22
+ */
23
+ flex?: boolean | undefined;
24
+ /**
25
+ * - The `class` attribute on the wrapper element.
26
+ */
27
+ class?: string | undefined;
28
+ /**
29
+ * - Whether to hide the widget.
30
+ */
31
+ hidden?: boolean | undefined;
32
+ /**
33
+ * - Whether to disable the widget. An alias of the `aria-disabled`
34
+ * attribute.
35
+ */
36
+ disabled?: boolean | undefined;
37
+ /**
38
+ * - Whether to make the widget read-only. An alias of the
39
+ * `aria-readonly` attribute.
40
+ */
41
+ readonly?: boolean | undefined;
42
+ /**
43
+ * - Whether to mark the widget required. An alias of the
44
+ * `aria-required` attribute.
45
+ */
46
+ required?: boolean | undefined;
47
+ /**
48
+ * - Whether to mark the widget invalid. An alias of the
49
+ * `aria-invalid` attribute.
50
+ */
51
+ invalid?: boolean | undefined;
52
+ /**
53
+ * - Primary slot content.
54
+ */
55
+ children?: import("svelte").Snippet<[]> | undefined;
56
+ } & Record<string, any>, {}, "code" | "lang">;
57
+ type Props = {
58
+ /**
59
+ * - Input value.
60
+ */
61
+ code?: string | undefined;
62
+ /**
63
+ * - Selected language.
64
+ */
65
+ lang?: string | undefined;
66
+ /**
67
+ * - Whether to show the language selector.
68
+ */
69
+ showLanguageSwitcher?: boolean | undefined;
70
+ /**
71
+ * - Make the text input container flexible.
72
+ */
73
+ flex?: boolean | undefined;
74
+ /**
75
+ * - The `class` attribute on the wrapper element.
76
+ */
77
+ class?: string | undefined;
78
+ /**
79
+ * - Whether to hide the widget.
80
+ */
81
+ hidden?: boolean | undefined;
82
+ /**
83
+ * - Whether to disable the widget. An alias of the `aria-disabled`
84
+ * attribute.
85
+ */
86
+ disabled?: boolean | undefined;
87
+ /**
88
+ * - Whether to make the widget read-only. An alias of the
89
+ * `aria-readonly` attribute.
90
+ */
91
+ readonly?: boolean | undefined;
92
+ /**
93
+ * - Whether to mark the widget required. An alias of the
94
+ * `aria-required` attribute.
95
+ */
96
+ required?: boolean | undefined;
97
+ /**
98
+ * - Whether to mark the widget invalid. An alias of the
99
+ * `aria-invalid` attribute.
100
+ */
101
+ invalid?: boolean | undefined;
102
+ /**
103
+ * - Primary slot content.
104
+ */
105
+ children?: import("svelte").Snippet<[]> | undefined;
106
+ };
@@ -1,5 +1,4 @@
1
- export function initEditor({ components }?: {
2
- components?: import("../../typedefs").TextEditorComponent[] | undefined;
3
- } | undefined): import("lexical").LexicalEditor;
4
- export function convertMarkdown(editor: import("lexical").LexicalEditor, value: string): Promise<void>;
1
+ export function initEditor({ components, isCodeEditor, defaultLanguage }: import("../../typedefs").TextEditorConfig): import("lexical").LexicalEditor;
2
+ export function loadCodeHighlighter(lang: string): Promise<void>;
3
+ export function convertMarkdownToLexical(editor: import("lexical").LexicalEditor, value: string): Promise<void>;
5
4
  export function focusEditor(editor: import("lexical").LexicalEditor): Promise<void>;
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  CodeHighlightNode,
3
3
  CodeNode,
4
+ $createCodeNode as createCodeNode,
4
5
  $isCodeHighlightNode as isCodeHighlightNode,
5
6
  $isCodeNode as isCodeNode,
6
7
  registerCodeHighlighting,
@@ -45,6 +46,7 @@ import {
45
46
  INSERT_PARAGRAPH_COMMAND,
46
47
  OUTDENT_CONTENT_COMMAND,
47
48
  createEditor,
49
+ $getRoot as getRoot,
48
50
  $getSelection as getSelection,
49
51
  $isRangeSelection as isRangeSelection,
50
52
  } from 'lexical';
@@ -122,15 +124,18 @@ const editorConfig = {
122
124
  };
123
125
 
124
126
  /**
125
- * Get the current selection’s block and inline level types.
126
- * @returns {{ blockType: import('../../typedefs').TextEditorBlockType,
127
- * inlineTypes: import('../../typedefs').TextEditorInlineType[] }} Types.
127
+ * Get the current selection’s block node key as well as block and inline level types.
128
+ * @returns {import('../../typedefs').TextEditorSelectionState} Current selection state.
128
129
  */
129
130
  const getSelectionTypes = () => {
130
131
  const selection = getSelection();
131
132
 
132
133
  if (!isRangeSelection(selection)) {
133
- return { blockType: 'paragraph', inlineTypes: [] };
134
+ return {
135
+ blockNodeKey: null,
136
+ blockType: 'paragraph',
137
+ inlineTypes: [],
138
+ };
134
139
  }
135
140
 
136
141
  const anchor = selection.anchor.getNode();
@@ -184,7 +189,11 @@ const getSelectionTypes = () => {
184
189
  })()
185
190
  );
186
191
 
187
- return { blockType, inlineTypes };
192
+ return {
193
+ blockNodeKey: parent?.getKey() ?? null,
194
+ blockType,
195
+ inlineTypes,
196
+ };
188
197
  };
189
198
 
190
199
  /**
@@ -192,8 +201,6 @@ const getSelectionTypes = () => {
192
201
  * @param {import('lexical').LexicalEditor} editor - Editor instance.
193
202
  */
194
203
  const onEditorUpdate = (editor) => {
195
- const { blockType, inlineTypes } = getSelectionTypes();
196
-
197
204
  editor.getRootElement()?.dispatchEvent(
198
205
  new CustomEvent('Update', {
199
206
  detail: {
@@ -201,8 +208,7 @@ const onEditorUpdate = (editor) => {
201
208
  // Use underscores for italic text in Markdown instead of asterisks
202
209
  allTransformers.filter((/** @type {any} */ { tag }) => tag !== '*'),
203
210
  ),
204
- selectionBlockType: blockType,
205
- selectionInlineTypes: inlineTypes,
211
+ selection: getSelectionTypes(),
206
212
  },
207
213
  }),
208
214
  );
@@ -210,12 +216,11 @@ const onEditorUpdate = (editor) => {
210
216
 
211
217
  /**
212
218
  * Initialize the Lexical editor.
213
- * @param {object} [options] - Options.
214
- * @param {import('../../typedefs').TextEditorComponent[]} [options.components] - Editor components.
219
+ * @param {import('../../typedefs').TextEditorConfig} config - Editor configuration.
215
220
  * @returns {import('lexical').LexicalEditor} Editor instance.
216
221
  */
217
- export const initEditor = ({ components } = {}) => {
218
- components?.forEach(({ node, transformer }) => {
222
+ export const initEditor = ({ components = [], isCodeEditor = false, defaultLanguage = '' }) => {
223
+ components.forEach(({ node, transformer }) => {
219
224
  /** @type {any[]} */ (editorConfig.nodes).unshift(node);
220
225
  allTransformers.unshift(transformer);
221
226
  });
@@ -227,10 +232,10 @@ export const initEditor = ({ components } = {}) => {
227
232
  registerHistory(editor, createEmptyHistoryState(), 1000);
228
233
 
229
234
  registerCodeHighlighting(editor, {
230
- defaultLanguage: '',
235
+ defaultLanguage,
231
236
  // eslint-disable-next-line jsdoc/require-jsdoc
232
- tokenize: (code, language = 'plain') =>
233
- window.Prism.tokenize(code, window.Prism.languages[language] ?? window.Prism.languages.plain),
237
+ tokenize: (code, lang = 'plain') =>
238
+ window.Prism.tokenize(code, window.Prism.languages[lang] ?? window.Prism.languages.plain),
234
239
  });
235
240
 
236
241
  editor.registerCommand(
@@ -270,12 +275,31 @@ export const initEditor = ({ components } = {}) => {
270
275
  COMMAND_PRIORITY_NORMAL,
271
276
  );
272
277
 
273
- editor.registerUpdateListener(({ editorState }) => {
278
+ editor.registerUpdateListener(async () => {
274
279
  if (editor?.isComposing()) {
275
280
  return;
276
281
  }
277
282
 
278
- editorState.read(() => {
283
+ await sleep(100);
284
+
285
+ editor.update(() => {
286
+ // Prevent CodeNode from being removed
287
+ if (isCodeEditor) {
288
+ const root = getRoot();
289
+ const children = root.getChildren();
290
+
291
+ if (children.length === 1 && !isCodeNode(children[0])) {
292
+ children[0].remove();
293
+ }
294
+
295
+ if (children.length === 0) {
296
+ const node = createCodeNode();
297
+
298
+ node.setLanguage(defaultLanguage);
299
+ root.append(node);
300
+ }
301
+ }
302
+
279
303
  onEditorUpdate(editor);
280
304
  });
281
305
  });
@@ -316,6 +340,35 @@ export const initEditor = ({ components } = {}) => {
316
340
  return editor;
317
341
  };
318
342
 
343
+ /**
344
+ * Load additional Prism syntax highlighter settings for the given programming language.
345
+ * @param {string} lang - Language name, like scss.
346
+ */
347
+ export const loadCodeHighlighter = async (lang) => {
348
+ if (lang in window.Prism.languages) {
349
+ return;
350
+ }
351
+
352
+ const canonicalLang = Object.entries(prismComponents.languages).find(
353
+ // @ts-ignore
354
+ ([key, { alias }]) =>
355
+ key === lang || (Array.isArray(alias) ? alias.includes(lang) : alias === lang),
356
+ )?.[0];
357
+
358
+ if (!canonicalLang) {
359
+ return;
360
+ }
361
+
362
+ try {
363
+ await import(
364
+ // eslint-disable-next-line jsdoc/no-bad-blocks
365
+ /* @vite-ignore */ `https://unpkg.com/prismjs@1.29.0/components/prism-${canonicalLang}.min.js`
366
+ );
367
+ } catch {
368
+ //
369
+ }
370
+ };
371
+
319
372
  /**
320
373
  * Convert Markdown to Lexical nodes.
321
374
  * @param {import('lexical').LexicalEditor} editor - Editor instance.
@@ -323,28 +376,19 @@ export const initEditor = ({ components } = {}) => {
323
376
  * @returns {Promise<void>} Nothing.
324
377
  * @throws {Error} Failed to convert the value to Lexical nodes.
325
378
  */
326
- export const convertMarkdown = async (editor, value) => {
379
+ export const convertMarkdownToLexical = async (editor, value) => {
327
380
  // Load Prism language support on demand; the `loadLanguages` Prism utility method cannot be used
328
381
  await Promise.all(
329
- [...value.matchAll(/^```(?<lang>.+?)\n/gm)].map(async ({ groups: { lang } = {} }) => {
330
- if (!(lang in window.Prism.languages) && lang in prismComponents.languages) {
331
- try {
332
- await import(
333
- // eslint-disable-next-line jsdoc/no-bad-blocks
334
- /* @vite-ignore */ `https://unpkg.com/prismjs@1.29.0/components/prism-${lang}.min.js`
335
- );
336
- } catch {
337
- //
338
- }
339
- }
340
- }),
382
+ [...value.matchAll(/^```(?<lang>.+?)\n/gm)].map(async ({ groups: { lang } = {} }) =>
383
+ loadCodeHighlighter(lang),
384
+ ),
341
385
  );
342
386
 
343
387
  return new Promise((resolve, reject) => {
344
388
  editor.update(() => {
345
389
  try {
346
390
  convertFromMarkdownString(value, allTransformers);
347
- resolve(void 0);
391
+ resolve(undefined);
348
392
  } catch (ex) {
349
393
  reject(new Error('Failed to convert Markdown', { cause: ex }));
350
394
  }
@@ -362,7 +406,8 @@ export const focusEditor = async (editor) => {
362
406
  editor.getRootElement()?.focus();
363
407
 
364
408
  return new Promise((resolve) => {
365
- editor.focus(() => {
409
+ editor.focus(async () => {
410
+ await sleep(100);
366
411
  resolve(undefined);
367
412
  });
368
413
  });
@@ -1,9 +1,9 @@
1
1
  <script>
2
2
  import { getContext, onMount } from 'svelte';
3
+ import { initEditor } from './core';
3
4
 
4
5
  /**
5
6
  * @typedef {object} Props
6
- * @property {string} [value] - Input value.
7
7
  * @property {string} [class] - The `class` attribute on the wrapper element.
8
8
  * @property {boolean} [hidden] - Whether to hide the widget.
9
9
  * @property {boolean} [disabled] - Whether to disable the widget. An alias of the `aria-disabled`
@@ -22,7 +22,6 @@
22
22
  */
23
23
  let {
24
24
  /* eslint-disable prefer-const */
25
- value = $bindable(),
26
25
  class: className,
27
26
  hidden = false,
28
27
  disabled = false,
@@ -34,12 +33,8 @@
34
33
  /* eslint-enable prefer-const */
35
34
  } = $props();
36
35
 
37
- /**
38
- * Text editor state.
39
- * @type {import('../../typedefs').TextEditorState}
40
- */
41
- const { editor, editorId, selectionBlockType, selectionInlineTypes, hasConverterError } =
42
- getContext('state');
36
+ /** @type {import('../../typedefs').TextEditorStore} */
37
+ const editorStore = getContext('editorStore');
43
38
 
44
39
  /**
45
40
  * Reference to the Lexical editor root element.
@@ -50,7 +45,7 @@
50
45
  const editable = $derived(!(disabled || readonly));
51
46
 
52
47
  $effect(() => {
53
- $editor?.setEditable(editable);
48
+ editorStore.editor?.setEditable(editable);
54
49
  });
55
50
 
56
51
  /**
@@ -58,19 +53,31 @@
58
53
  * @param {Event} event - `Update` custom event.
59
54
  */
60
55
  const onUpdate = (event) => {
61
- if ($hasConverterError) {
56
+ if (editorStore.hasConverterError) {
62
57
  return;
63
58
  }
64
59
 
65
60
  const { detail } = /** @type {CustomEvent} */ (event);
66
61
  const newValue = detail.value;
67
62
 
68
- if (value !== newValue) {
69
- value = newValue;
63
+ if (editorStore.inputValue !== newValue) {
64
+ const { useRichText } = editorStore;
65
+
66
+ if (useRichText) {
67
+ // Temporarily disable rich text to prevent unnecessary Markdown conversion that resets
68
+ // Lexical nodes and selection
69
+ editorStore.useRichText = false;
70
+ }
71
+
72
+ editorStore.inputValue = newValue;
73
+
74
+ if (useRichText) {
75
+ // Restore the rich text state
76
+ editorStore.useRichText = true;
77
+ }
70
78
  }
71
79
 
72
- $selectionBlockType = detail.selectionBlockType;
73
- $selectionInlineTypes = detail.selectionInlineTypes;
80
+ editorStore.selection = detail.selection;
74
81
  };
75
82
 
76
83
  /**
@@ -84,6 +91,8 @@
84
91
  };
85
92
 
86
93
  onMount(() => {
94
+ editorStore.editor = initEditor(editorStore.config);
95
+
87
96
  lexicalRoot?.addEventListener('Update', onUpdate);
88
97
  lexicalRoot?.addEventListener('click', onClick);
89
98
 
@@ -94,8 +103,9 @@
94
103
  });
95
104
 
96
105
  $effect(() => {
97
- if ($editor && lexicalRoot) {
98
- $editor.setRootElement(lexicalRoot);
106
+ if (editorStore.editor && lexicalRoot) {
107
+ editorStore.editor.setRootElement(lexicalRoot);
108
+ editorStore.initialized = true;
99
109
  }
100
110
  });
101
111
  </script>
@@ -111,14 +121,16 @@
111
121
  aria-required={required}
112
122
  aria-invalid={invalid}
113
123
  class="lexical-root"
114
- id="{$editorId}-lexical-root"
124
+ class:code={editorStore.config.isCodeEditor}
125
+ id="{editorStore.editorId}-lexical-root"
115
126
  contenteditable={editable}
116
127
  {hidden}
117
128
  ></div>
118
129
 
119
130
  <style>.lexical-root {
131
+ overflow: hidden;
120
132
  border: 1px solid var(--sui-textbox-border-color);
121
- border-radius: 0 0 var(--sui-textbox-border-radius) var(--sui-textbox-border-radius) !important;
133
+ border-radius: var(--sui-textbox-border-radius) !important;
122
134
  padding: var(--sui-textbox-multiline-padding);
123
135
  min-height: 8em;
124
136
  color: var(--sui-textbox-foreground-color);
@@ -127,6 +139,17 @@
127
139
  font-size: var(--sui-textbox-font-size);
128
140
  line-height: var(--sui-textbox-multiline-line-height);
129
141
  }
142
+ .lexical-root:not(:first-child) {
143
+ border-top-left-radius: 0 !important;
144
+ border-top-right-radius: 0 !important;
145
+ }
146
+ .lexical-root.code {
147
+ padding: 0;
148
+ }
149
+ .lexical-root.code :global(.code-block) {
150
+ border-radius: 0 !important;
151
+ min-height: 120px;
152
+ }
130
153
  .lexical-root:focus-visible {
131
154
  outline: 0;
132
155
  }
@@ -166,7 +189,7 @@
166
189
  padding: 8px;
167
190
  min-width: 40px;
168
191
  color: var(--sui-tertiary-foreground-color);
169
- background-color: var(--sui-secondary-background-color);
192
+ background-color: var(--sui-tertiary-background-color);
170
193
  text-align: right;
171
194
  }
172
195
  .lexical-root :global([data-lexical-text=true]) {
@@ -4,10 +4,6 @@ type LexicalRoot = {
4
4
  $set?(props: Partial<Props & Record<string, any>>): void;
5
5
  };
6
6
  declare const LexicalRoot: import("svelte").Component<{
7
- /**
8
- * - Input value.
9
- */
10
- value?: string | undefined;
11
7
  /**
12
8
  * - The `class` attribute on the wrapper element.
13
9
  */
@@ -40,12 +36,8 @@ declare const LexicalRoot: import("svelte").Component<{
40
36
  * - Primary slot content.
41
37
  */
42
38
  children?: import("svelte").Snippet<[]> | undefined;
43
- } & Record<string, any>, {}, "value">;
39
+ } & Record<string, any>, {}, "">;
44
40
  type Props = {
45
- /**
46
- * - Input value.
47
- */
48
- value?: string | undefined;
49
41
  /**
50
42
  * - The `class` attribute on the wrapper element.
51
43
  */
@@ -0,0 +1 @@
1
+ export function createEditorStore(): import("../../typedefs").TextEditorStore;