@sveltia/ui 0.11.1 → 0.12.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.
Files changed (90) hide show
  1. package/package/components/button/button.svelte +4 -1
  2. package/package/components/button/button.svelte.d.ts +4 -4
  3. package/package/components/button/select-button-group.svelte.d.ts +4 -4
  4. package/package/components/button/select-button.svelte.d.ts +4 -4
  5. package/package/components/button/split-button.svelte +2 -5
  6. package/package/components/button/split-button.svelte.d.ts +4 -4
  7. package/package/components/calendar/calendar.svelte +1 -1
  8. package/package/components/checkbox/checkbox.svelte +2 -2
  9. package/package/components/checkbox/checkbox.svelte.d.ts +6 -6
  10. package/package/components/dialog/dialog.svelte +2 -2
  11. package/package/components/dialog/dialog.svelte.d.ts +2 -2
  12. package/package/components/dialog/prompt-dialog.svelte +7 -1
  13. package/package/components/dialog/prompt-dialog.svelte.d.ts +2 -0
  14. package/package/components/disclosure/disclosure.svelte +2 -2
  15. package/package/components/disclosure/disclosure.svelte.d.ts +2 -2
  16. package/package/components/drawer/drawer.svelte +2 -2
  17. package/package/components/drawer/drawer.svelte.d.ts +2 -2
  18. package/package/components/grid/grid-body.svelte +2 -2
  19. package/package/components/grid/grid.svelte.d.ts +2 -2
  20. package/package/components/icon/icon.svelte +6 -0
  21. package/package/components/listbox/listbox.svelte.d.ts +8 -8
  22. package/package/components/listbox/option-group.svelte +2 -2
  23. package/package/components/listbox/option-group.svelte.d.ts +2 -2
  24. package/package/components/menu/menu-button.svelte +0 -8
  25. package/package/components/menu/menu-button.svelte.d.ts +4 -4
  26. package/package/components/menu/menu-item-checkbox.svelte.d.ts +4 -4
  27. package/package/components/menu/menu-item-group.svelte +2 -2
  28. package/package/components/menu/menu-item-group.svelte.d.ts +2 -2
  29. package/package/components/menu/menu-item-radio.svelte.d.ts +4 -4
  30. package/package/components/menu/menu-item.svelte +1 -1
  31. package/package/components/menu/menu-item.svelte.d.ts +2 -2
  32. package/package/components/radio/radio-group.svelte.d.ts +4 -4
  33. package/package/components/radio/radio.svelte +2 -2
  34. package/package/components/radio/radio.svelte.d.ts +4 -4
  35. package/package/components/select/combobox.svelte +3 -3
  36. package/package/components/select/combobox.svelte.d.ts +4 -4
  37. package/package/components/select/select.svelte.d.ts +4 -4
  38. package/package/components/slider/slider.svelte +1 -1
  39. package/package/components/slider/slider.svelte.d.ts +8 -8
  40. package/package/components/switch/switch.svelte.d.ts +6 -6
  41. package/package/components/table/table-body.svelte +2 -2
  42. package/package/components/tabs/tab-list.svelte +1 -1
  43. package/package/components/text-editor/core.d.ts +2 -0
  44. package/package/components/text-editor/core.js +206 -0
  45. package/package/components/text-editor/index.d.ts +23 -0
  46. package/package/components/text-editor/index.js +102 -0
  47. package/package/components/text-editor/lexical-root.svelte +123 -0
  48. package/package/components/text-editor/lexical-root.svelte.d.ts +27 -0
  49. package/package/components/text-editor/text-editor.svelte +154 -0
  50. package/package/components/{text-field/markdown-editor.svelte.d.ts → text-editor/text-editor.svelte.d.ts} +16 -12
  51. package/package/components/text-editor/toolbar/editor-toolbar.svelte +150 -0
  52. package/package/components/text-editor/toolbar/editor-toolbar.svelte.d.ts +25 -0
  53. package/package/components/text-editor/toolbar/format-text-button.svelte +33 -0
  54. package/package/components/text-editor/toolbar/format-text-button.svelte.d.ts +23 -0
  55. package/package/components/text-editor/toolbar/insert-link-button.svelte +231 -0
  56. package/package/components/text-editor/toolbar/insert-link-button.svelte.d.ts +23 -0
  57. package/package/components/text-editor/toolbar/toggle-block-menu-item.svelte +83 -0
  58. package/package/components/text-editor/toolbar/toggle-block-menu-item.svelte.d.ts +23 -0
  59. package/package/components/text-field/number-input.svelte +2 -2
  60. package/package/components/text-field/number-input.svelte.d.ts +10 -10
  61. package/package/components/text-field/password-input.svelte +2 -2
  62. package/package/components/text-field/password-input.svelte.d.ts +4 -4
  63. package/package/components/text-field/search-bar.svelte +3 -3
  64. package/package/components/text-field/search-bar.svelte.d.ts +4 -4
  65. package/package/components/text-field/text-area.svelte +3 -0
  66. package/package/components/text-field/text-area.svelte.d.ts +4 -4
  67. package/package/components/text-field/text-input.svelte +2 -2
  68. package/package/components/text-field/text-input.svelte.d.ts +4 -4
  69. package/package/components/toast/toast.svelte +2 -2
  70. package/package/components/util/app-shell.svelte +56 -4
  71. package/package/components/util/modal.svelte +3 -3
  72. package/package/components/util/modal.svelte.d.ts +4 -4
  73. package/package/components/util/popup.svelte +2 -2
  74. package/package/index.d.ts +1 -2
  75. package/package/index.js +9 -4
  76. package/package/locales/en.d.ts +25 -7
  77. package/package/locales/en.js +25 -6
  78. package/package/locales/ja.d.ts +25 -7
  79. package/package/locales/ja.js +25 -6
  80. package/package/services/events.js +2 -2
  81. package/package/services/group.js +7 -6
  82. package/package/services/popup.js +2 -2
  83. package/package/styles/core.scss +51 -2
  84. package/package/styles/variables.scss +3 -1
  85. package/package/typedef.d.ts +48 -0
  86. package/package/typedef.js +36 -0
  87. package/package.json +22 -18
  88. package/package/components/text-field/markdown-editor.svelte +0 -141
  89. package/package/services/util.d.ts +0 -3
  90. package/package/services/util.js +0 -35
@@ -1,2 +1,50 @@
1
1
  type PopupPosition = ('top-left' | 'top-right' | 'right-top' | 'right-bottom' | 'bottom-left' | 'bottom-right' | 'left-top' | 'left-bottom');
2
2
  type ToastPosition = 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';
3
+ type TextEditorBlockType = 'paragraph' | 'heading-1' | 'heading-2' | 'heading-3' | 'heading-4' | 'heading-5' | 'heading-6' | 'bulleted-list' | 'numbered-list' | 'blockquote';
4
+ type TextEditorFormatType = 'bold' | 'italic' | 'code';
5
+ type TextEditorInlineType = TextEditorFormatType | 'link';
6
+ type TextEditorMode = 'rich-text' | 'plain-text';
7
+ type TextEditorState = {
8
+ /**
9
+ * - Lexical
10
+ * editor instance.
11
+ */
12
+ editor: import('svelte/store').Writable<import('lexical').LexicalEditor>;
13
+ /**
14
+ * - Random ID assigned to the editor.
15
+ */
16
+ editorId: import('svelte/store').Writable<string>;
17
+ /**
18
+ * - Block level
19
+ * type of the current selection.
20
+ */
21
+ selectionBlockType: import('svelte/store').Writable<TextEditorBlockType>;
22
+ /**
23
+ * - Inline
24
+ * level types of the current selection.
25
+ */
26
+ selectionInlineTypes: import('svelte/store').Writable<TextEditorInlineType[]>;
27
+ /**
28
+ * - Enabled modes.
29
+ */
30
+ modes: TextEditorMode[];
31
+ /**
32
+ * - Whether to use rich text mode.
33
+ * If `false`, the editor shows the plain text editor.
34
+ */
35
+ useRichText: import('svelte/store').Writable<boolean>;
36
+ /**
37
+ * - `true` if there was an
38
+ * error while converting Markdown to Lexical nodes.
39
+ */
40
+ hasConverterError: import('svelte/store').Writable<boolean>;
41
+ /**
42
+ * - Enabled buttons for
43
+ * the editor.
44
+ */
45
+ enabledButtons: (TextEditorBlockType | TextEditorInlineType)[];
46
+ /**
47
+ * Function to trigger the Lexical converter.
48
+ */
49
+ convertMarkdown: Function;
50
+ };
@@ -7,3 +7,39 @@
7
7
  * @typedef {'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' |
8
8
  * 'bottom-right'} ToastPosition
9
9
  */
10
+
11
+ /**
12
+ * @typedef {'paragraph' | 'heading-1' | 'heading-2' | 'heading-3' | 'heading-4' | 'heading-5' |
13
+ * 'heading-6' | 'bulleted-list' | 'numbered-list' | 'blockquote'} TextEditorBlockType
14
+ */
15
+
16
+ /**
17
+ * @typedef {'bold' | 'italic' | 'code'} TextEditorFormatType
18
+ */
19
+
20
+ /**
21
+ * @typedef {TextEditorFormatType | 'link'} TextEditorInlineType
22
+ */
23
+
24
+ /**
25
+ * @typedef {'rich-text' | 'plain-text'} TextEditorMode
26
+ */
27
+
28
+ /**
29
+ * @typedef {object} TextEditorState
30
+ * @property {import('svelte/store').Writable<import('lexical').LexicalEditor>} editor - Lexical
31
+ * editor instance.
32
+ * @property {import('svelte/store').Writable<string>} editorId - Random ID assigned to the editor.
33
+ * @property {import('svelte/store').Writable<TextEditorBlockType>} selectionBlockType - Block level
34
+ * type of the current selection.
35
+ * @property {import('svelte/store').Writable<TextEditorInlineType[]>} selectionInlineTypes - Inline
36
+ * level types of the current selection.
37
+ * @property {TextEditorMode[]} modes - Enabled modes.
38
+ * @property {import('svelte/store').Writable<boolean>} useRichText - Whether to use rich text mode.
39
+ * If `false`, the editor shows the plain text editor.
40
+ * @property {import('svelte/store').Writable<boolean>} hasConverterError - `true` if there was an
41
+ * error while converting Markdown to Lexical nodes.
42
+ * @property {(TextEditorBlockType | TextEditorInlineType)[]} enabledButtons - Enabled buttons for
43
+ * the editor.
44
+ * @property {Function} convertMarkdown Function to trigger the Lexical converter.
45
+ */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltia/ui",
3
- "version": "0.11.1",
3
+ "version": "0.12.1",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -23,12 +23,23 @@
23
23
  "test:unit": "vitest"
24
24
  },
25
25
  "dependencies": {
26
- "svelte": "^4.2.14"
26
+ "@lexical/code": "^0.14.5",
27
+ "@lexical/history": "^0.14.5",
28
+ "@lexical/link": "^0.14.5",
29
+ "@lexical/list": "^0.14.5",
30
+ "@lexical/markdown": "^0.14.5",
31
+ "@lexical/rich-text": "^0.14.5",
32
+ "@lexical/selection": "^0.14.5",
33
+ "@lexical/table": "^0.14.5",
34
+ "@lexical/utils": "^0.14.5",
35
+ "@sveltia/utils": "^0.1.0",
36
+ "lexical": "^0.14.5",
37
+ "svelte": "^4.2.15"
27
38
  },
28
39
  "devDependencies": {
29
40
  "@playwright/test": "^1.43.1",
30
41
  "@sveltejs/adapter-auto": "^3.2.0",
31
- "@sveltejs/kit": "^2.5.5",
42
+ "@sveltejs/kit": "^2.5.7",
32
43
  "@sveltejs/package": "^2.3.1",
33
44
  "@sveltejs/vite-plugin-svelte": "^3.1.0",
34
45
  "cspell": "^8.7.0",
@@ -49,9 +60,9 @@
49
60
  "stylelint-scss": "^6.2.1",
50
61
  "svelte-check": "^3.6.9",
51
62
  "svelte-i18n": "^4.0.0",
52
- "svelte-preprocess": "^5.1.3",
63
+ "svelte-preprocess": "^5.1.4",
53
64
  "tslib": "^2.6.2",
54
- "vite": "^5.2.8",
65
+ "vite": "^5.2.10",
55
66
  "vitest": "^1.5.0"
56
67
  },
57
68
  "exports": {
@@ -326,10 +337,10 @@
326
337
  "svelte": "./package/components/tabs/tab.svelte",
327
338
  "default": "./package/components/tabs/tab.svelte"
328
339
  },
329
- "./components/text-field/markdown-editor.svelte": {
330
- "types": "./package/components/text-field/markdown-editor.svelte.d.ts",
331
- "svelte": "./package/components/text-field/markdown-editor.svelte",
332
- "default": "./package/components/text-field/markdown-editor.svelte"
340
+ "./components/text-editor/text-editor.svelte": {
341
+ "types": "./package/components/text-editor/text-editor.svelte.d.ts",
342
+ "svelte": "./package/components/text-editor/text-editor.svelte",
343
+ "default": "./package/components/text-editor/text-editor.svelte"
333
344
  },
334
345
  "./components/text-field/number-input.svelte": {
335
346
  "types": "./package/components/text-field/number-input.svelte.d.ts",
@@ -416,10 +427,6 @@
416
427
  "types": "./package/services/popup.d.ts",
417
428
  "default": "./package/services/popup.js"
418
429
  },
419
- "./services/util": {
420
- "types": "./package/services/util.d.ts",
421
- "default": "./package/services/util.js"
422
- },
423
430
  "./styles/core.scss": "./package/styles/core.scss",
424
431
  "./styles/variables.scss": "./package/styles/variables.scss",
425
432
  "./typedef": {
@@ -595,8 +602,8 @@
595
602
  "components/tabs/tab.svelte": [
596
603
  "./package/components/tabs/tab.svelte.d.ts"
597
604
  ],
598
- "components/text-field/markdown-editor.svelte": [
599
- "./package/components/text-field/markdown-editor.svelte.d.ts"
605
+ "components/text-editor/text-editor.svelte": [
606
+ "./package/components/text-editor/text-editor.svelte.d.ts"
600
607
  ],
601
608
  "components/text-field/number-input.svelte": [
602
609
  "./package/components/text-field/number-input.svelte.d.ts"
@@ -652,9 +659,6 @@
652
659
  "services/popup": [
653
660
  "./package/services/popup.d.ts"
654
661
  ],
655
- "services/util": [
656
- "./package/services/util.d.ts"
657
- ],
658
662
  "typedef": [
659
663
  "./package/typedef.d.ts"
660
664
  ]
@@ -1,141 +0,0 @@
1
- <!--
2
- @component
3
- A Markdown text editor.
4
- -->
5
- <script>
6
- import { _ } from 'svelte-i18n';
7
- import { getRandomId } from '../../services/util';
8
- import Button from '../button/button.svelte';
9
- import Divider from '../divider/divider.svelte';
10
- import Icon from '../icon/icon.svelte';
11
- import Toolbar from '../toolbar/toolbar.svelte';
12
- import TextArea from './text-area.svelte';
13
-
14
- /**
15
- * Make the text input container flexible.
16
- * @type {boolean}
17
- */
18
- export let flex = false;
19
- /**
20
- * Whether to hide the widget. An alias of the `aria-hidden` attribute.
21
- * @type {boolean | undefined}
22
- */
23
- export let hidden = undefined;
24
- /**
25
- * Whether to disable the widget. An alias of the `aria-disabled` attribute.
26
- * @type {boolean}
27
- */
28
- export let disabled = false;
29
- /**
30
- * Whether to disable the widget. An alias of `aria-readonly` attribute.
31
- * @type {boolean}
32
- */
33
- export let readonly = false;
34
- /**
35
- * Whether to mark the widget required. An alias of the `aria-required` attribute.
36
- * @type {boolean}
37
- */
38
- export let required = false;
39
- /**
40
- * Whether to mark the widget invalid. An alias of the `aria-invalid` attribute.
41
- * @type {boolean}
42
- */
43
- export let invalid = false;
44
- /**
45
- * Input value.
46
- * @type {string | undefined}
47
- */
48
- export let value = undefined;
49
-
50
- const id = getRandomId('editor');
51
-
52
- const defaultButtons = [
53
- { name: 'bold', label: $_('_sui.markdown_editor.bold'), icon: 'format_bold' },
54
- { name: 'italic', label: $_('_sui.markdown_editor.italic'), icon: 'format_italic' },
55
- { name: 'code', label: $_('_sui.markdown_editor.code'), icon: 'code' },
56
- { name: 'link', label: $_('_sui.markdown_editor.link'), icon: 'link' },
57
- { separator: true },
58
- {
59
- name: 'heading-one',
60
- label: $_('_sui.markdown_editor.heading_x', { values: { level: 1 } }),
61
- icon: 'format_h1',
62
- },
63
- {
64
- name: 'heading-two',
65
- label: $_('_sui.markdown_editor.heading_x', { values: { level: 2 } }),
66
- icon: 'format_h2',
67
- },
68
- { name: 'quote', label: $_('_sui.markdown_editor.quote'), icon: 'format_quote' },
69
- { separator: true },
70
- {
71
- name: 'bulleted-list',
72
- label: $_('_sui.markdown_editor.bulleted_list'),
73
- icon: 'format_list_bulleted',
74
- },
75
- {
76
- name: 'numbered-list',
77
- label: $_('_sui.markdown_editor.numbered_list'),
78
- icon: 'format_list_numbered',
79
- },
80
- ];
81
- </script>
82
-
83
- <div role="none" class="wrapper" hidden={hidden || undefined} {...$$restProps}>
84
- <div role="none" class="inner">
85
- <Toolbar
86
- disabled={disabled || readonly}
87
- aria-label={$_('_sui.markdown_editor.markdown_editor')}
88
- >
89
- {#each defaultButtons as { label, icon, separator }}
90
- {#if separator}
91
- <Divider />
92
- {:else}
93
- <Button iconic aria-label={label} aria-controls={id}>
94
- <Icon slot="start-icon" name={icon} />
95
- </Button>
96
- {/if}
97
- {/each}
98
- </Toolbar>
99
- <TextArea
100
- {id}
101
- autoResize={true}
102
- bind:value
103
- {flex}
104
- {hidden}
105
- {disabled}
106
- {readonly}
107
- {required}
108
- {invalid}
109
- />
110
- </div>
111
- </div>
112
-
113
- <style>.wrapper {
114
- margin: var(--sui-focus-ring-width);
115
- width: calc(100% - var(--sui-focus-ring-width) * 2);
116
- }
117
- .wrapper :global([role="toolbar"]) {
118
- display: flex;
119
- gap: 0;
120
- border-radius: 4px 4px 0 0;
121
- padding: 8px;
122
- background-color: var(--sui-tertiary-background-color);
123
- }
124
- .wrapper :global([role="toolbar"]) :global(button) {
125
- flex: none;
126
- margin: 0 !important;
127
- }
128
- .wrapper :global([role="toolbar"]) + :global(div) {
129
- width: 100%;
130
- }
131
- .wrapper :global([role="toolbar"]) + :global(div) :global(textarea) {
132
- border-radius: 0 0 4px 4px !important;
133
- }
134
-
135
- .inner {
136
- display: contents;
137
- }
138
- .inner :global(.text-area) {
139
- margin: 0 !important;
140
- width: 100% !important;
141
- }</style>
@@ -1,3 +0,0 @@
1
- export function getRandomId(prefix?: string | undefined, length?: number | undefined): string;
2
- export function isObject(input: any): boolean;
3
- export function sleep(ms?: number | undefined): Promise<void>;
@@ -1,35 +0,0 @@
1
- /**
2
- * Get a random ID that can be used for elements.
3
- * @param {string} [prefix] - Prefix to be added to the ID, e.g. `popup`.
4
- * @param {number} [length] - Number of characters to be used in the ID.
5
- * @returns {string} Generated ID.
6
- */
7
- export const getRandomId = (prefix = 'e', length = 7) =>
8
- [
9
- prefix,
10
- new Array(length)
11
- .fill(0)
12
- .map(() => '0123456789abcdef'[Math.floor(Math.random() * 12)])
13
- .join(''),
14
- ].join('-');
15
-
16
- /**
17
- * Check if the given input is a simple object.
18
- * @param {*} input - Input, probably an object.
19
- * @returns {boolean} Result.
20
- */
21
- export const isObject = (input) =>
22
- input !== null && typeof input === 'object' && !Array.isArray(input);
23
-
24
- /**
25
- * Return a simple `Promise` to resolve in the given time, making it easier to wait for a bit in the
26
- * code, particularly while making sequential HTTP requests.
27
- * @param {number} [ms] - Milliseconds to wait.
28
- * @returns {Promise<void>} Nothing.
29
- */
30
- export const sleep = (ms = 1000) =>
31
- new Promise((resolve) => {
32
- window.setTimeout(() => {
33
- resolve();
34
- }, ms);
35
- });