@sveltia/ui 0.40.3 → 0.40.5

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.
@@ -1,4 +1,7 @@
1
- export function initEditor({ components, isCodeEditor, defaultLanguage, }: TextEditorConfig): LexicalEditor;
1
+ export function initEditor({ components, isCodeEditor, defaultLanguage, }: TextEditorConfig): {
2
+ editor: LexicalEditor;
3
+ dispose: () => void;
4
+ };
2
5
  export function loadCodeHighlighter(lang: string): Promise<void>;
3
6
  export function convertMarkdownToLexical(editor: LexicalEditor, value: string): Promise<void>;
4
7
  export function focusEditor(editor: LexicalEditor): Promise<void>;
@@ -3,52 +3,57 @@
3
3
  import 'prismjs';
4
4
 
5
5
  import {
6
- $createCodeNode,
7
- $isCodeHighlightNode,
8
- $isCodeNode,
9
6
  CodeHighlightNode,
10
7
  CodeNode,
8
+ $createCodeNode as createCodeNode,
9
+ $isCodeHighlightNode as isCodeHighlightNode,
10
+ $isCodeNode as isCodeNode,
11
11
  } from '@lexical/code';
12
12
  import { PrismTokenizer, registerCodeHighlighting } from '@lexical/code-prism';
13
13
  import { registerDragonSupport } from '@lexical/dragon';
14
14
  import { HorizontalRuleNode } from '@lexical/extension';
15
15
  import { createEmptyHistoryState, registerHistory } from '@lexical/history';
16
- import { $isLinkNode, $toggleLink, LinkNode, TOGGLE_LINK_COMMAND } from '@lexical/link';
17
16
  import {
18
- $handleListInsertParagraph,
19
- $insertList,
20
- $isListItemNode,
21
- $isListNode,
17
+ $isLinkNode as isLinkNode,
18
+ LinkNode,
19
+ TOGGLE_LINK_COMMAND,
20
+ $toggleLink as toggleLink,
21
+ } from '@lexical/link';
22
+ import {
23
+ $handleListInsertParagraph as handleListInsertParagraph,
22
24
  INSERT_ORDERED_LIST_COMMAND,
23
25
  INSERT_UNORDERED_LIST_COMMAND,
26
+ $insertList as insertList,
27
+ $isListItemNode as isListItemNode,
28
+ $isListNode as isListNode,
24
29
  ListItemNode,
25
30
  ListNode,
26
31
  } from '@lexical/list';
27
32
  import {
28
- $convertFromMarkdownString,
29
- $convertToMarkdownString,
33
+ $convertFromMarkdownString as convertFromMarkdownString,
34
+ $convertToMarkdownString as convertToMarkdownString,
30
35
  TRANSFORMERS,
31
36
  } from '@lexical/markdown';
32
37
  import {
33
- $isHeadingNode,
34
- $isQuoteNode,
35
38
  HeadingNode,
39
+ $isHeadingNode as isHeadingNode,
40
+ $isQuoteNode as isQuoteNode,
36
41
  QuoteNode,
37
42
  registerRichText,
38
43
  } from '@lexical/rich-text';
39
44
  import { TableCellNode, TableNode, TableRowNode } from '@lexical/table';
40
- import { $getNearestNodeOfType } from '@lexical/utils';
45
+ import { $getNearestNodeOfType as getNearestNodeOfType } from '@lexical/utils';
41
46
  import { sleep } from '@sveltia/utils/misc';
42
47
  import {
43
- $getRoot,
44
- $getSelection,
45
- $isRangeSelection,
46
48
  COMMAND_PRIORITY_NORMAL,
49
+ createEditor,
47
50
  ElementNode,
51
+ $getRoot as getRoot,
52
+ $getSelection as getSelection,
48
53
  INDENT_CONTENT_COMMAND,
49
54
  INSERT_PARAGRAPH_COMMAND,
55
+ $isRangeSelection as isRangeSelection,
50
56
  OUTDENT_CONTENT_COMMAND,
51
- createEditor,
52
57
  } from 'lexical';
53
58
  import prismComponents from 'prismjs/components';
54
59
  import { BLOCK_BUTTON_TYPES, TEXT_FORMAT_BUTTON_TYPES } from './constants.js';
@@ -144,9 +149,9 @@ const editorConfig = {
144
149
  * @returns {TextEditorSelectionState} Current selection state.
145
150
  */
146
151
  const getSelectionTypes = () => {
147
- const selection = $getSelection();
152
+ const selection = getSelection();
148
153
 
149
- if (!$isRangeSelection(selection)) {
154
+ if (!isRangeSelection(selection)) {
150
155
  return {
151
156
  blockNodeKey: null,
152
157
  blockType: 'paragraph',
@@ -161,15 +166,15 @@ const getSelectionTypes = () => {
161
166
  const inlineTypes = TEXT_FORMAT_BUTTON_TYPES.filter((type) => selection.hasFormat(type));
162
167
 
163
168
  if (anchor.getType() !== 'root') {
164
- parent = anchor instanceof ElementNode ? anchor : $getNearestNodeOfType(anchor, ElementNode);
169
+ parent = anchor instanceof ElementNode ? anchor : getNearestNodeOfType(anchor, ElementNode);
165
170
 
166
- if ($isLinkNode(parent)) {
171
+ if (isLinkNode(parent)) {
167
172
  inlineTypes.push('link');
168
- parent = $getNearestNodeOfType(parent, ElementNode);
173
+ parent = getNearestNodeOfType(parent, ElementNode);
169
174
  }
170
175
 
171
- if ($isListItemNode(parent)) {
172
- parent = $getNearestNodeOfType(parent, ListNode);
176
+ if (isListItemNode(parent)) {
177
+ parent = getNearestNodeOfType(parent, ListNode);
173
178
  }
174
179
  }
175
180
 
@@ -179,19 +184,19 @@ const getSelectionTypes = () => {
179
184
  return 'paragraph';
180
185
  }
181
186
 
182
- if ($isHeadingNode(parent)) {
187
+ if (isHeadingNode(parent)) {
183
188
  return `heading-${parent.getTag().match(/\d/)?.[0]}`;
184
189
  }
185
190
 
186
- if ($isListNode(parent)) {
191
+ if (isListNode(parent)) {
187
192
  return parent.getListType() === 'bullet' ? 'bulleted-list' : 'numbered-list';
188
193
  }
189
194
 
190
- if ($isQuoteNode(parent)) {
195
+ if (isQuoteNode(parent)) {
191
196
  return 'blockquote';
192
197
  }
193
198
 
194
- if ($isCodeNode(parent) || $isCodeHighlightNode(parent)) {
199
+ if (isCodeNode(parent) || isCodeHighlightNode(parent)) {
195
200
  return 'code-block';
196
201
  }
197
202
 
@@ -220,7 +225,7 @@ const onEditorUpdate = (editor) => {
220
225
  editor.getRootElement()?.dispatchEvent(
221
226
  new CustomEvent('Update', {
222
227
  detail: {
223
- value: $convertToMarkdownString(
228
+ value: convertToMarkdownString(
224
229
  // Use underscores for italic text in Markdown instead of asterisks
225
230
  allTransformers.filter((/** @type {any} */ { tag }) => tag !== '*'),
226
231
  ) // Remove unnecessary backslash for underscore and backslash characters
@@ -241,7 +246,7 @@ const onEditorUpdate = (editor) => {
241
246
  /**
242
247
  * Initialize the Lexical editor.
243
248
  * @param {TextEditorConfig} config Editor configuration.
244
- * @returns {LexicalEditor} Editor instance.
249
+ * @returns {{ editor: LexicalEditor, dispose: () => void }} Editor instance and cleanup.
245
250
  */
246
251
  export const initEditor = ({
247
252
  components = [],
@@ -254,106 +259,138 @@ export const initEditor = ({
254
259
  });
255
260
 
256
261
  const editor = createEditor(editorConfig);
262
+ /** @type {Array<() => void>} */
263
+ const unregisters = [];
264
+
265
+ /**
266
+ * Add a cleanup handler if it is defined.
267
+ * @param {(() => void) | undefined | null} unregister Cleanup handler.
268
+ */
269
+ const addUnregister = (unregister) => {
270
+ if (typeof unregister === 'function') {
271
+ unregisters.push(unregister);
272
+ }
273
+ };
257
274
 
258
- registerRichText(editor);
259
- registerDragonSupport(editor);
260
- registerHistory(editor, createEmptyHistoryState(), 1000);
261
-
262
- registerCodeHighlighting(editor, {
263
- defaultLanguage,
264
- // eslint-disable-next-line jsdoc/require-jsdoc
265
- tokenize: (code, lang = 'plain') =>
266
- window.Prism.tokenize(code, window.Prism.languages[lang] ?? window.Prism.languages.plain),
267
- $tokenize: PrismTokenizer.$tokenize,
268
- });
275
+ addUnregister(registerRichText(editor));
276
+ addUnregister(registerDragonSupport(editor));
277
+ addUnregister(registerHistory(editor, createEmptyHistoryState(), 1000));
278
+
279
+ addUnregister(
280
+ registerCodeHighlighting(editor, {
281
+ defaultLanguage,
282
+ // eslint-disable-next-line jsdoc/require-jsdoc
283
+ tokenize: (code, lang = 'plain') =>
284
+ window.Prism.tokenize(code, window.Prism.languages[lang] ?? window.Prism.languages.plain),
285
+ $tokenize: PrismTokenizer.$tokenize,
286
+ }),
287
+ );
269
288
 
270
- editor.registerCommand(
271
- TOGGLE_LINK_COMMAND,
272
- (payload) => {
273
- $toggleLink(typeof payload === 'string' ? payload : null);
289
+ addUnregister(
290
+ editor.registerCommand(
291
+ TOGGLE_LINK_COMMAND,
292
+ (payload) => {
293
+ toggleLink(typeof payload === 'string' ? payload : null);
274
294
 
275
- return true;
276
- },
277
- COMMAND_PRIORITY_NORMAL,
295
+ return true;
296
+ },
297
+ COMMAND_PRIORITY_NORMAL,
298
+ ),
278
299
  );
279
300
 
280
- editor.registerCommand(
281
- INSERT_UNORDERED_LIST_COMMAND,
282
- () => {
283
- $insertList('bullet');
301
+ addUnregister(
302
+ editor.registerCommand(
303
+ INSERT_UNORDERED_LIST_COMMAND,
304
+ () => {
305
+ insertList('bullet');
284
306
 
285
- return true;
286
- },
287
- COMMAND_PRIORITY_NORMAL,
307
+ return true;
308
+ },
309
+ COMMAND_PRIORITY_NORMAL,
310
+ ),
288
311
  );
289
312
 
290
- editor.registerCommand(
291
- INSERT_ORDERED_LIST_COMMAND,
292
- () => {
293
- $insertList('number');
313
+ addUnregister(
314
+ editor.registerCommand(
315
+ INSERT_ORDERED_LIST_COMMAND,
316
+ () => {
317
+ insertList('number');
294
318
 
295
- return true;
296
- },
297
- COMMAND_PRIORITY_NORMAL,
319
+ return true;
320
+ },
321
+ COMMAND_PRIORITY_NORMAL,
322
+ ),
298
323
  );
299
324
 
300
325
  // https://github.com/facebook/lexical/blob/main/packages/lexical-react/src/shared/useList.ts
301
- editor.registerCommand(
302
- INSERT_PARAGRAPH_COMMAND,
303
- () => $handleListInsertParagraph(),
304
- COMMAND_PRIORITY_NORMAL,
326
+ addUnregister(
327
+ editor.registerCommand(
328
+ INSERT_PARAGRAPH_COMMAND,
329
+ () => handleListInsertParagraph(),
330
+ COMMAND_PRIORITY_NORMAL,
331
+ ),
305
332
  );
306
333
 
307
- editor.registerUpdateListener(() => {
308
- if (editor?.isComposing()) {
309
- return;
310
- }
334
+ addUnregister(
335
+ editor.registerUpdateListener(() => {
336
+ if (editor?.isComposing()) {
337
+ return;
338
+ }
311
339
 
312
- (async () => {
313
- await sleep(100);
340
+ (async () => {
341
+ await sleep(100);
314
342
 
315
- editor.update(() => {
316
- // Prevent CodeNode from being removed
317
- if (isCodeEditor) {
318
- const root = $getRoot();
319
- const children = root.getChildren();
343
+ editor.update(() => {
344
+ // Prevent CodeNode from being removed
345
+ if (isCodeEditor) {
346
+ const root = getRoot();
347
+ const children = root.getChildren();
320
348
 
321
- if (children.length === 1 && !$isCodeNode(children[0])) {
322
- children[0].remove();
323
- }
349
+ if (children.length === 1 && !isCodeNode(children[0])) {
350
+ children[0].remove();
351
+ }
324
352
 
325
- if (children.length === 0) {
326
- const node = $createCodeNode();
353
+ if (children.length === 0) {
354
+ const node = createCodeNode();
327
355
 
328
- node.setLanguage(defaultLanguage);
329
- root.append(node);
356
+ node.setLanguage(defaultLanguage);
357
+ root.append(node);
358
+ }
330
359
  }
331
- }
332
360
 
333
- onEditorUpdate(editor);
334
- });
335
- })();
336
- });
361
+ onEditorUpdate(editor);
362
+ });
363
+ })();
364
+ }),
365
+ );
337
366
 
338
367
  // `editor.registerCommand(KEY_TAB_COMMAND, listener, priority)` doesn’t work for some reason, so
339
368
  // use another method
340
- editor.registerRootListener((root) => {
341
- if (root) {
342
- root.addEventListener('keydown', (event) => {
369
+ addUnregister(
370
+ editor.registerRootListener((root) => {
371
+ if (!root) {
372
+ return undefined;
373
+ }
374
+
375
+ /**
376
+ * Handle Tab indentation shortcuts.
377
+ * @param {KeyboardEvent} event Keydown event.
378
+ */
379
+ const onKeydown = (event) => {
343
380
  editor.update(() => {
344
381
  if (event.key === 'Tab') {
345
- const selection = $getSelection();
382
+ const selection = getSelection();
346
383
 
347
- if (!$isRangeSelection(selection)) {
384
+ if (!isRangeSelection(selection)) {
348
385
  return;
349
386
  }
350
387
 
351
388
  const anchor = selection.anchor.getNode();
352
389
 
353
390
  const parent =
354
- anchor instanceof ElementNode ? anchor : $getNearestNodeOfType(anchor, ElementNode);
391
+ anchor instanceof ElementNode ? anchor : getNearestNodeOfType(anchor, ElementNode);
355
392
 
356
- if ($isListItemNode(parent) && parent.canIndent()) {
393
+ if (isListItemNode(parent) && parent.canIndent()) {
357
394
  if (!event.shiftKey) {
358
395
  event.preventDefault();
359
396
  editor.dispatchCommand(INDENT_CONTENT_COMMAND, undefined);
@@ -364,11 +401,25 @@ export const initEditor = ({
364
401
  }
365
402
  }
366
403
  });
367
- });
368
- }
369
- });
404
+ };
405
+
406
+ root.addEventListener('keydown', onKeydown);
407
+
408
+ return () => {
409
+ root.removeEventListener('keydown', onKeydown);
410
+ };
411
+ }),
412
+ );
370
413
 
371
- return editor;
414
+ return {
415
+ editor,
416
+ /**
417
+ * Remove all registered Lexical listeners.
418
+ */
419
+ dispose: () => {
420
+ unregisters.forEach((unregister) => unregister());
421
+ },
422
+ };
372
423
  };
373
424
 
374
425
  /**
@@ -422,7 +473,7 @@ export const convertMarkdownToLexical = async (editor, value) => {
422
473
  return new Promise((resolve, reject) => {
423
474
  editor.update(() => {
424
475
  try {
425
- $convertFromMarkdownString(value, allTransformers);
476
+ convertFromMarkdownString(value, allTransformers);
426
477
  resolve(undefined);
427
478
  } catch (ex) {
428
479
  reject(new Error('Failed to convert Markdown', { cause: ex }));
@@ -88,7 +88,9 @@
88
88
  };
89
89
 
90
90
  onMount(() => {
91
- editorStore.editor = initEditor(editorStore.config);
91
+ const { editor, dispose } = initEditor(editorStore.config);
92
+
93
+ editorStore.editor = editor;
92
94
 
93
95
  lexicalRoot?.addEventListener('Update', onUpdate);
94
96
  lexicalRoot?.addEventListener('click', onClick);
@@ -96,6 +98,10 @@
96
98
  return () => {
97
99
  lexicalRoot?.removeEventListener('Update', onUpdate);
98
100
  lexicalRoot?.removeEventListener('click', onClick);
101
+ dispose();
102
+ editor.setRootElement(null);
103
+ editorStore.initialized = false;
104
+ editorStore.editor = undefined;
99
105
  };
100
106
  });
101
107
 
@@ -3,9 +3,9 @@
3
3
  /* eslint-disable jsdoc/require-jsdoc */
4
4
 
5
5
  import {
6
- $createHorizontalRuleNode,
7
- $isHorizontalRuleNode,
6
+ $createHorizontalRuleNode as createHorizontalRuleNode,
8
7
  HorizontalRuleNode,
8
+ $isHorizontalRuleNode as isHorizontalRuleNode,
9
9
  } from '@lexical/extension';
10
10
 
11
11
  /**
@@ -17,10 +17,10 @@ import {
17
17
  */
18
18
  export const HR = {
19
19
  dependencies: [HorizontalRuleNode],
20
- export: (node) => ($isHorizontalRuleNode(node) ? '***' : null),
20
+ export: (node) => (isHorizontalRuleNode(node) ? '***' : null),
21
21
  regExp: /^(---|\*\*\*|___)\s?$/,
22
22
  replace: (parentNode, _1, _2, isImport) => {
23
- const line = $createHorizontalRuleNode();
23
+ const line = createHorizontalRuleNode();
24
24
 
25
25
  if (isImport || parentNode.getNextSibling() !== null) {
26
26
  parentNode.replace(line);
@@ -5,23 +5,23 @@
5
5
  /* eslint-disable jsdoc/require-param-description */
6
6
 
7
7
  import {
8
- $convertFromMarkdownString,
9
- $convertToMarkdownString,
8
+ $convertFromMarkdownString as convertFromMarkdownString,
9
+ $convertToMarkdownString as convertToMarkdownString,
10
10
  TRANSFORMERS,
11
11
  } from '@lexical/markdown';
12
12
  import {
13
- $createTableCellNode,
14
- $createTableNode,
15
- $createTableRowNode,
16
- $isTableCellNode,
17
- $isTableNode,
18
- $isTableRowNode,
13
+ $createTableCellNode as createTableCellNode,
14
+ $createTableNode as createTableNode,
15
+ $createTableRowNode as createTableRowNode,
16
+ $isTableCellNode as isTableCellNode,
17
+ $isTableNode as isTableNode,
18
+ $isTableRowNode as isTableRowNode,
19
19
  TableCellHeaderStates,
20
20
  TableCellNode,
21
21
  TableNode,
22
22
  TableRowNode,
23
23
  } from '@lexical/table';
24
- import { $isParagraphNode, $isTextNode } from 'lexical';
24
+ import { $isParagraphNode as isParagraphNode, $isTextNode as isTextNode } from 'lexical';
25
25
 
26
26
  /**
27
27
  * @import { ElementTransformer } from '@lexical/markdown';
@@ -38,7 +38,7 @@ const TABLE_ROW_DIVIDER_REG_EXP = /^(\| ?:?-*:? ?)+\|\s?$/;
38
38
  function getTableColumnsSize(table) {
39
39
  const row = table.getFirstChild();
40
40
 
41
- return $isTableRowNode(row) ? row.getChildrenSize() : 0;
41
+ return isTableRowNode(row) ? row.getChildrenSize() : 0;
42
42
  }
43
43
 
44
44
  /**
@@ -49,9 +49,9 @@ function getTableColumnsSize(table) {
49
49
  const createTableCell = (textContent) => {
50
50
  textContent = textContent.replace(/\\n/g, '\n');
51
51
 
52
- const cell = $createTableCellNode(TableCellHeaderStates.NO_STATUS);
52
+ const cell = createTableCellNode(TableCellHeaderStates.NO_STATUS);
53
53
 
54
- $convertFromMarkdownString(textContent, TRANSFORMERS, cell);
54
+ convertFromMarkdownString(textContent, TRANSFORMERS, cell);
55
55
 
56
56
  return cell;
57
57
  };
@@ -77,7 +77,7 @@ const mapToTableCells = (textContent) => {
77
77
  export const TABLE = {
78
78
  dependencies: [TableNode, TableRowNode, TableCellNode],
79
79
  export: (node) => {
80
- if (!$isTableNode(node)) {
80
+ if (!isTableNode(node)) {
81
81
  return null;
82
82
  }
83
83
 
@@ -88,7 +88,7 @@ export const TABLE = {
88
88
  /** @type {string[]} */
89
89
  const rowOutput = [];
90
90
 
91
- if (!$isTableRowNode(row)) {
91
+ if (!isTableRowNode(row)) {
92
92
  return;
93
93
  }
94
94
 
@@ -96,8 +96,8 @@ export const TABLE = {
96
96
 
97
97
  row.getChildren().forEach((cell) => {
98
98
  // It’s TableCellNode so it’s just to make flow happy
99
- if ($isTableCellNode(cell)) {
100
- rowOutput.push($convertToMarkdownString(TRANSFORMERS, cell).replace(/\n/g, '\\n').trim());
99
+ if (isTableCellNode(cell)) {
100
+ rowOutput.push(convertToMarkdownString(TRANSFORMERS, cell).replace(/\n/g, '\\n').trim());
101
101
 
102
102
  if (cell.__headerState === TableCellHeaderStates.ROW) {
103
103
  isHeaderRow = true;
@@ -120,20 +120,20 @@ export const TABLE = {
120
120
  if (TABLE_ROW_DIVIDER_REG_EXP.test(textContent)) {
121
121
  const table = parentNode.getPreviousSibling();
122
122
 
123
- if (!table || !$isTableNode(table)) {
123
+ if (!table || !isTableNode(table)) {
124
124
  return;
125
125
  }
126
126
 
127
127
  const rows = table.getChildren();
128
128
  const lastRow = rows[rows.length - 1];
129
129
 
130
- if (!lastRow || !$isTableRowNode(lastRow)) {
130
+ if (!lastRow || !isTableRowNode(lastRow)) {
131
131
  return;
132
132
  }
133
133
 
134
134
  // Add header state to row cells
135
135
  lastRow.getChildren().forEach((cell) => {
136
- if (!$isTableCellNode(cell)) {
136
+ if (!isTableCellNode(cell)) {
137
137
  return;
138
138
  }
139
139
 
@@ -157,7 +157,7 @@ export const TABLE = {
157
157
  let maxCells = matchCells.length;
158
158
 
159
159
  while (sibling) {
160
- if (!$isParagraphNode(sibling)) {
160
+ if (!isParagraphNode(sibling)) {
161
161
  break;
162
162
  }
163
163
 
@@ -167,7 +167,7 @@ export const TABLE = {
167
167
 
168
168
  const firstChild = sibling.getFirstChild();
169
169
 
170
- if (!$isTextNode(firstChild)) {
170
+ if (!isTextNode(firstChild)) {
171
171
  break;
172
172
  }
173
173
 
@@ -186,10 +186,10 @@ export const TABLE = {
186
186
  sibling = previousSibling;
187
187
  }
188
188
 
189
- const table = $createTableNode();
189
+ const table = createTableNode();
190
190
 
191
191
  rows.forEach((cells) => {
192
- const tableRow = $createTableRowNode();
192
+ const tableRow = createTableRowNode();
193
193
 
194
194
  table.append(tableRow);
195
195
 
@@ -200,7 +200,7 @@ export const TABLE = {
200
200
 
201
201
  const previousSibling = parentNode.getPreviousSibling();
202
202
 
203
- if ($isTableNode(previousSibling) && getTableColumnsSize(previousSibling) === maxCells) {
203
+ if (isTableNode(previousSibling) && getTableColumnsSize(previousSibling) === maxCells) {
204
204
  previousSibling.append(...table.getChildren());
205
205
  parentNode.remove();
206
206
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltia/ui",
3
- "version": "0.40.3",
3
+ "version": "0.40.5",
4
4
  "description": "A collection of Svelte components and utilities for building user interfaces.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -46,42 +46,42 @@
46
46
  "@lexical/table": "^0.45.0",
47
47
  "@lexical/utils": "^0.45.0",
48
48
  "@sveltia/i18n": "^1.1.1",
49
- "@sveltia/utils": "^0.10.6",
49
+ "@sveltia/utils": "^0.10.7",
50
50
  "lexical": "^0.45.0",
51
51
  "prismjs": "^1.30.0",
52
52
  "yaml": "^2.9.0"
53
53
  },
54
54
  "devDependencies": {
55
55
  "@sveltejs/adapter-auto": "^7.0.1",
56
- "@sveltejs/kit": "^2.61.1",
57
- "@sveltejs/package": "^2.5.7",
56
+ "@sveltejs/kit": "^2.64.0",
57
+ "@sveltejs/package": "^2.5.8",
58
58
  "@sveltejs/vite-plugin-svelte": "^7.1.2",
59
- "@vitest/coverage-v8": "^4.1.7",
59
+ "@vitest/coverage-v8": "^4.1.8",
60
60
  "cspell": "^10.0.1",
61
61
  "eslint": "^9.39.4",
62
62
  "eslint-config-airbnb-extended": "^3.1.0",
63
63
  "eslint-config-prettier": "^10.1.8",
64
64
  "eslint-plugin-import": "^2.32.0",
65
- "eslint-plugin-jsdoc": "^63.0.0",
66
- "eslint-plugin-package-json": "^1.2.0",
65
+ "eslint-plugin-jsdoc": "^63.0.2",
66
+ "eslint-plugin-package-json": "^1.3.0",
67
67
  "eslint-plugin-svelte": "^3.19.0",
68
68
  "globals": "^17.6.0",
69
- "happy-dom": "^20.9.0",
70
- "oxlint": "^1.67.0",
69
+ "happy-dom": "^20.10.2",
70
+ "oxlint": "^1.69.0",
71
71
  "postcss": "^8.5.15",
72
72
  "postcss-html": "^1.8.1",
73
- "prettier": "^3.8.3",
74
- "prettier-plugin-svelte": "^4.0.1",
73
+ "prettier": "^3.8.4",
74
+ "prettier-plugin-svelte": "^4.1.0",
75
75
  "sass": "^1.100.0",
76
- "stylelint": "^17.12.0",
76
+ "stylelint": "^17.13.0",
77
77
  "stylelint-config-recommended-scss": "^17.0.1",
78
- "stylelint-scss": "^7.1.1",
79
- "svelte": "^5.56.0",
80
- "svelte-check": "^4.4.8",
78
+ "stylelint-scss": "^7.2.0",
79
+ "svelte": "^5.56.3",
80
+ "svelte-check": "^4.6.0",
81
81
  "svelte-preprocess": "^6.0.5",
82
82
  "tslib": "^2.8.1",
83
- "vite": "^8.0.14",
84
- "vitest": "^4.1.7"
83
+ "vite": "^8.0.16",
84
+ "vitest": "^4.1.8"
85
85
  },
86
86
  "peerDependencies": {
87
87
  "svelte": "^5.0.0"