@sveltia/ui 0.11.0 → 0.12.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 (93) hide show
  1. package/package/components/button/button.svelte +4 -1
  2. package/package/components/button/button.svelte.d.ts +12 -12
  3. package/package/components/button/select-button-group.svelte.d.ts +4 -4
  4. package/package/components/button/select-button.svelte.d.ts +6 -6
  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-group.svelte.d.ts +2 -2
  9. package/package/components/checkbox/checkbox.svelte +1 -1
  10. package/package/components/checkbox/checkbox.svelte.d.ts +10 -10
  11. package/package/components/dialog/dialog.svelte +1 -1
  12. package/package/components/dialog/dialog.svelte.d.ts +2 -2
  13. package/package/components/dialog/prompt-dialog.svelte +7 -1
  14. package/package/components/dialog/prompt-dialog.svelte.d.ts +4 -2
  15. package/package/components/disclosure/disclosure.svelte +1 -1
  16. package/package/components/disclosure/disclosure.svelte.d.ts +2 -2
  17. package/package/components/drawer/drawer.svelte +1 -1
  18. package/package/components/drawer/drawer.svelte.d.ts +6 -6
  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.d.ts +2 -2
  23. package/package/components/listbox/option.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 +6 -6
  26. package/package/components/menu/menu-item-checkbox.svelte.d.ts +4 -4
  27. package/package/components/menu/menu-item-group.svelte.d.ts +2 -2
  28. package/package/components/menu/menu-item-radio.svelte.d.ts +4 -4
  29. package/package/components/menu/menu-item.svelte +1 -1
  30. package/package/components/menu/menu-item.svelte.d.ts +4 -4
  31. package/package/components/menu/menu.svelte.d.ts +2 -2
  32. package/package/components/radio/radio-group.svelte.d.ts +4 -4
  33. package/package/components/radio/radio.svelte +1 -1
  34. package/package/components/radio/radio.svelte.d.ts +6 -6
  35. package/package/components/select/combobox.svelte +2 -2
  36. package/package/components/select/combobox.svelte.d.ts +6 -6
  37. package/package/components/select/select.svelte.d.ts +6 -6
  38. package/package/components/slider/slider.svelte +13 -20
  39. package/package/components/slider/slider.svelte.d.ts +10 -12
  40. package/package/components/switch/switch.svelte.d.ts +8 -8
  41. package/package/components/tabs/tab-list.svelte +1 -1
  42. package/package/components/tabs/tab-list.svelte.d.ts +2 -2
  43. package/package/components/tabs/tab.svelte.d.ts +2 -2
  44. package/package/components/text-editor/core.d.ts +2 -0
  45. package/package/components/text-editor/core.js +206 -0
  46. package/package/components/text-editor/index.d.ts +23 -0
  47. package/package/components/text-editor/index.js +102 -0
  48. package/package/components/text-editor/lexical-root.svelte +123 -0
  49. package/package/components/text-editor/lexical-root.svelte.d.ts +27 -0
  50. package/package/components/text-editor/text-editor.svelte +154 -0
  51. package/package/components/{text-field/markdown-editor.svelte.d.ts → text-editor/text-editor.svelte.d.ts} +18 -14
  52. package/package/components/text-editor/toolbar/editor-toolbar.svelte +150 -0
  53. package/package/components/text-editor/toolbar/editor-toolbar.svelte.d.ts +25 -0
  54. package/package/components/text-editor/toolbar/format-text-button.svelte +33 -0
  55. package/package/components/text-editor/toolbar/format-text-button.svelte.d.ts +23 -0
  56. package/package/components/text-editor/toolbar/insert-link-button.svelte +231 -0
  57. package/package/components/text-editor/toolbar/insert-link-button.svelte.d.ts +23 -0
  58. package/package/components/text-editor/toolbar/toggle-block-menu-item.svelte +83 -0
  59. package/package/components/text-editor/toolbar/toggle-block-menu-item.svelte.d.ts +23 -0
  60. package/package/components/text-field/number-input.svelte +1 -1
  61. package/package/components/text-field/number-input.svelte.d.ts +12 -12
  62. package/package/components/text-field/password-input.svelte +1 -1
  63. package/package/components/text-field/password-input.svelte.d.ts +6 -6
  64. package/package/components/text-field/search-bar.svelte +2 -2
  65. package/package/components/text-field/search-bar.svelte.d.ts +6 -6
  66. package/package/components/text-field/text-area.svelte +3 -0
  67. package/package/components/text-field/text-area.svelte.d.ts +6 -6
  68. package/package/components/text-field/text-input.svelte.d.ts +8 -8
  69. package/package/components/toast/toast.svelte +2 -2
  70. package/package/components/toast/toast.svelte.d.ts +2 -2
  71. package/package/components/toolbar/toolbar.svelte.d.ts +2 -2
  72. package/package/components/util/app-shell.svelte +56 -4
  73. package/package/components/util/group.svelte.d.ts +2 -2
  74. package/package/components/util/modal.svelte +2 -2
  75. package/package/components/util/modal.svelte.d.ts +6 -6
  76. package/package/components/util/popup.svelte +2 -2
  77. package/package/components/util/popup.svelte.d.ts +6 -3
  78. package/package/index.d.ts +1 -1
  79. package/package/index.js +1 -1
  80. package/package/locales/en.d.ts +25 -7
  81. package/package/locales/en.js +25 -6
  82. package/package/locales/ja.d.ts +25 -7
  83. package/package/locales/ja.js +25 -6
  84. package/package/services/events.js +7 -5
  85. package/package/services/group.js +4 -4
  86. package/package/services/util.d.ts +1 -0
  87. package/package/services/util.js +22 -1
  88. package/package/styles/core.scss +51 -2
  89. package/package/styles/variables.scss +3 -1
  90. package/package/typedef.d.ts +48 -0
  91. package/package/typedef.js +36 -0
  92. package/package.json +26 -16
  93. package/package/components/text-field/markdown-editor.svelte +0 -141
@@ -101,6 +101,7 @@
101
101
  --sui-selected-background-color: hsl(var(--sui-background-color-5-hsl) / 75%);
102
102
  --sui-active-background-color: hsl(var(--sui-background-color-5-hsl) / 100%);
103
103
  --sui-content-background-color: hsl(var(--sui-background-color-1-hsl));
104
+ --sui-code-background-color: hsl(var(--sui-background-color-4-hsl));
104
105
  --sui-primary-background-color: hsl(var(--sui-background-color-2-hsl));
105
106
  --sui-primary-background-color-translucent: hsl(var(--sui-background-color-2-hsl) / 80%);
106
107
  --sui-secondary-background-color: hsl(var(--sui-background-color-3-hsl));
@@ -160,10 +161,11 @@
160
161
  --sui-font-weight-normal: 300;
161
162
  --sui-font-weight-bold: 600;
162
163
  --sui-font-family-monospace: "Noto Sans Mono", monospace;
163
- --sui-font-size-monospace: 12.5px;
164
+ --sui-font-size-monospace: 0.9em;
164
165
  --sui-line-height-default: 1.25;
165
166
  --sui-line-height-compact: 1.5;
166
167
  --sui-line-height-comfortable: 1.75;
168
+ --sui-word-spacing-normal: 0.1ex;
167
169
  // Controls
168
170
  --sui-control-small-border-width: 1px;
169
171
  --sui-control-small-border-radius: calc(var(--sui-control-small-height) / 8);
@@ -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.0",
3
+ "version": "0.12.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -23,36 +23,46 @@
23
23
  "test:unit": "vitest"
24
24
  },
25
25
  "dependencies": {
26
- "svelte": "^4.2.12"
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
+ "lexical": "^0.14.5",
36
+ "svelte": "^4.2.14"
27
37
  },
28
38
  "devDependencies": {
29
- "@playwright/test": "^1.43.0",
39
+ "@playwright/test": "^1.43.1",
30
40
  "@sveltejs/adapter-auto": "^3.2.0",
31
41
  "@sveltejs/kit": "^2.5.5",
32
42
  "@sveltejs/package": "^2.3.1",
33
- "@sveltejs/vite-plugin-svelte": "^3.0.2",
34
- "cspell": "^8.6.1",
43
+ "@sveltejs/vite-plugin-svelte": "^3.1.0",
44
+ "cspell": "^8.7.0",
35
45
  "eslint": "^8.57.0",
36
46
  "eslint-config-airbnb-base": "^15.0.0",
37
47
  "eslint-config-prettier": "^9.1.0",
38
48
  "eslint-plugin-import": "^2.29.1",
39
49
  "eslint-plugin-jsdoc": "^48.2.3",
40
- "eslint-plugin-svelte": "^2.35.1",
50
+ "eslint-plugin-svelte": "^2.37.0",
41
51
  "npm-run-all": "^4.1.5",
42
52
  "postcss": "^8.4.38",
43
53
  "postcss-html": "^1.6.0",
44
54
  "prettier": "^3.2.5",
45
- "prettier-plugin-svelte": "^3.2.2",
46
- "sass": "^1.74.1",
55
+ "prettier-plugin-svelte": "^3.2.3",
56
+ "sass": "^1.75.0",
47
57
  "stylelint": "^16.3.1",
48
58
  "stylelint-config-recommended-scss": "^14.0.0",
49
59
  "stylelint-scss": "^6.2.1",
50
60
  "svelte-check": "^3.6.9",
51
61
  "svelte-i18n": "^4.0.0",
52
- "svelte-preprocess": "^5.1.3",
62
+ "svelte-preprocess": "^5.1.4",
53
63
  "tslib": "^2.6.2",
54
64
  "vite": "^5.2.8",
55
- "vitest": "^1.4.0"
65
+ "vitest": "^1.5.0"
56
66
  },
57
67
  "exports": {
58
68
  "./package.json": "./package.json",
@@ -326,10 +336,10 @@
326
336
  "svelte": "./package/components/tabs/tab.svelte",
327
337
  "default": "./package/components/tabs/tab.svelte"
328
338
  },
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"
339
+ "./components/text-editor/text-editor.svelte": {
340
+ "types": "./package/components/text-editor/text-editor.svelte.d.ts",
341
+ "svelte": "./package/components/text-editor/text-editor.svelte",
342
+ "default": "./package/components/text-editor/text-editor.svelte"
333
343
  },
334
344
  "./components/text-field/number-input.svelte": {
335
345
  "types": "./package/components/text-field/number-input.svelte.d.ts",
@@ -595,8 +605,8 @@
595
605
  "components/tabs/tab.svelte": [
596
606
  "./package/components/tabs/tab.svelte.d.ts"
597
607
  ],
598
- "components/text-field/markdown-editor.svelte": [
599
- "./package/components/text-field/markdown-editor.svelte.d.ts"
608
+ "components/text-editor/text-editor.svelte": [
609
+ "./package/components/text-editor/text-editor.svelte.d.ts"
600
610
  ],
601
611
  "components/text-field/number-input.svelte": [
602
612
  "./package/components/text-field/number-input.svelte.d.ts"
@@ -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>