@sveltia/ui 0.28.0 → 0.28.2
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/{index.d.ts → constants.d.ts} +8 -4
- package/dist/components/text-editor/{index.js → constants.js} +12 -4
- package/dist/components/text-editor/core.js +3 -3
- package/dist/components/text-editor/text-editor.svelte +2 -2
- package/dist/components/text-editor/toolbar/format-text-button.svelte +3 -3
- package/dist/components/text-editor/toolbar/insert-link-button.svelte +3 -3
- package/dist/components/text-editor/toolbar/text-editor-toolbar.svelte +13 -6
- package/dist/components/text-editor/toolbar/toggle-block-menu-item.svelte +3 -3
- package/dist/services/i18n.js +1 -1
- package/package.json +4 -4
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* List of available buttons.
|
|
6
6
|
* @type {{ [key: string]: { labelKey: string, icon: string, inline: boolean } }}
|
|
7
7
|
*/
|
|
8
|
-
export const
|
|
8
|
+
export const AVAILABLE_BUTTONS: {
|
|
9
9
|
[key: string]: {
|
|
10
10
|
labelKey: string;
|
|
11
11
|
icon: string;
|
|
@@ -15,15 +15,19 @@ export const availableButtons: {
|
|
|
15
15
|
/**
|
|
16
16
|
* @type {TextEditorFormatType[]}
|
|
17
17
|
*/
|
|
18
|
-
export const
|
|
18
|
+
export const TEXT_FORMAT_BUTTON_TYPES: TextEditorFormatType[];
|
|
19
19
|
/**
|
|
20
20
|
* @type {TextEditorInlineType[]}
|
|
21
21
|
*/
|
|
22
|
-
export const
|
|
22
|
+
export const INLINE_BUTTON_TYPES: TextEditorInlineType[];
|
|
23
23
|
/**
|
|
24
24
|
* @type {TextEditorBlockType[]}
|
|
25
25
|
*/
|
|
26
|
-
export const
|
|
26
|
+
export const BLOCK_BUTTON_TYPES: TextEditorBlockType[];
|
|
27
|
+
/**
|
|
28
|
+
* Image related components IDs. `linked-image` is used in Sveltia CMS.
|
|
29
|
+
*/
|
|
30
|
+
export const IMAGE_COMPONENT_IDS: string[];
|
|
27
31
|
import type { TextEditorFormatType } from '../../typedefs';
|
|
28
32
|
import type { TextEditorInlineType } from '../../typedefs';
|
|
29
33
|
import type { TextEditorBlockType } from '../../typedefs';
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* List of available buttons.
|
|
7
7
|
* @type {{ [key: string]: { labelKey: string, icon: string, inline: boolean } }}
|
|
8
8
|
*/
|
|
9
|
-
export const
|
|
9
|
+
export const AVAILABLE_BUTTONS = {
|
|
10
10
|
bold: {
|
|
11
11
|
labelKey: 'bold',
|
|
12
12
|
icon: 'format_bold',
|
|
@@ -83,18 +83,21 @@ export const availableButtons = {
|
|
|
83
83
|
inline: false,
|
|
84
84
|
},
|
|
85
85
|
};
|
|
86
|
+
|
|
86
87
|
/**
|
|
87
88
|
* @type {TextEditorFormatType[]}
|
|
88
89
|
*/
|
|
89
|
-
export const
|
|
90
|
+
export const TEXT_FORMAT_BUTTON_TYPES = ['bold', 'italic', 'code'];
|
|
91
|
+
|
|
90
92
|
/**
|
|
91
93
|
* @type {TextEditorInlineType[]}
|
|
92
94
|
*/
|
|
93
|
-
export const
|
|
95
|
+
export const INLINE_BUTTON_TYPES = [...TEXT_FORMAT_BUTTON_TYPES, 'link'];
|
|
96
|
+
|
|
94
97
|
/**
|
|
95
98
|
* @type {TextEditorBlockType[]}
|
|
96
99
|
*/
|
|
97
|
-
export const
|
|
100
|
+
export const BLOCK_BUTTON_TYPES = [
|
|
98
101
|
'paragraph',
|
|
99
102
|
'heading-1',
|
|
100
103
|
'heading-2',
|
|
@@ -107,3 +110,8 @@ export const blockButtonTypes = [
|
|
|
107
110
|
'blockquote',
|
|
108
111
|
'code-block',
|
|
109
112
|
];
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Image related components IDs. `linked-image` is used in Sveltia CMS.
|
|
116
|
+
*/
|
|
117
|
+
export const IMAGE_COMPONENT_IDS = ['image', 'linked-image'];
|
|
@@ -52,7 +52,7 @@ import {
|
|
|
52
52
|
$isRangeSelection as isRangeSelection,
|
|
53
53
|
} from 'lexical';
|
|
54
54
|
import prismComponents from 'prismjs/components';
|
|
55
|
-
import {
|
|
55
|
+
import { BLOCK_BUTTON_TYPES, TEXT_FORMAT_BUTTON_TYPES } from './constants';
|
|
56
56
|
import { TABLE } from './transformers/table';
|
|
57
57
|
|
|
58
58
|
/**
|
|
@@ -155,7 +155,7 @@ const getSelectionTypes = () => {
|
|
|
155
155
|
/** @type {ElementNode | null} */
|
|
156
156
|
let parent = null;
|
|
157
157
|
/** @type {TextEditorInlineType[]} */
|
|
158
|
-
const inlineTypes =
|
|
158
|
+
const inlineTypes = TEXT_FORMAT_BUTTON_TYPES.filter((type) => selection.hasFormat(type));
|
|
159
159
|
|
|
160
160
|
if (anchor.getType() !== 'root') {
|
|
161
161
|
parent = anchor instanceof ElementNode ? anchor : getNearestNodeOfType(anchor, ElementNode);
|
|
@@ -194,7 +194,7 @@ const getSelectionTypes = () => {
|
|
|
194
194
|
|
|
195
195
|
const type = parent.getType();
|
|
196
196
|
|
|
197
|
-
if (
|
|
197
|
+
if (BLOCK_BUTTON_TYPES.includes(/** @type {any} */ (type))) {
|
|
198
198
|
return type;
|
|
199
199
|
}
|
|
200
200
|
|
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
<script>
|
|
6
6
|
import { setContext, untrack } from 'svelte';
|
|
7
7
|
import { _ } from 'svelte-i18n';
|
|
8
|
-
import { blockButtonTypes, inlineButtonTypes } from '.';
|
|
9
8
|
import Alert from '../alert/alert.svelte';
|
|
10
9
|
import TextArea from '../text-field/text-area.svelte';
|
|
11
10
|
import Toast from '../toast/toast.svelte';
|
|
11
|
+
import { BLOCK_BUTTON_TYPES, INLINE_BUTTON_TYPES } from './constants';
|
|
12
12
|
import LexicalRoot from './lexical-root.svelte';
|
|
13
13
|
import { createEditorStore } from './store.svelte';
|
|
14
14
|
import TextEditorToolbar from './toolbar/text-editor-toolbar.svelte';
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
value = $bindable(''),
|
|
52
52
|
flex = false,
|
|
53
53
|
modes = ['rich-text', 'plain-text'],
|
|
54
|
-
buttons = [...
|
|
54
|
+
buttons = [...INLINE_BUTTON_TYPES, ...BLOCK_BUTTON_TYPES],
|
|
55
55
|
components = [],
|
|
56
56
|
hidden = false,
|
|
57
57
|
disabled = false,
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
import { FORMAT_TEXT_COMMAND } from 'lexical';
|
|
3
3
|
import { getContext } from 'svelte';
|
|
4
4
|
import { _ } from 'svelte-i18n';
|
|
5
|
-
import { availableButtons } from '..';
|
|
6
5
|
import Button from '../../button/button.svelte';
|
|
7
6
|
import Icon from '../../icon/icon.svelte';
|
|
7
|
+
import { AVAILABLE_BUTTONS } from '../constants';
|
|
8
8
|
import { focusEditor } from '../core';
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
|
|
33
33
|
<Button
|
|
34
34
|
iconic
|
|
35
|
-
aria-label={$_(`_sui.text_editor.${
|
|
35
|
+
aria-label={$_(`_sui.text_editor.${AVAILABLE_BUTTONS[type].labelKey}`)}
|
|
36
36
|
aria-controls="{editorStore.editorId}-lexical-root"
|
|
37
37
|
disabled={!editorStore.useRichText}
|
|
38
38
|
pressed={selectionTypeMatches}
|
|
@@ -44,6 +44,6 @@
|
|
|
44
44
|
}}
|
|
45
45
|
>
|
|
46
46
|
{#snippet startIcon()}
|
|
47
|
-
<Icon name={
|
|
47
|
+
<Icon name={AVAILABLE_BUTTONS[type].icon} />
|
|
48
48
|
{/snippet}
|
|
49
49
|
</Button>
|
|
@@ -15,12 +15,12 @@
|
|
|
15
15
|
} from 'lexical';
|
|
16
16
|
import { getContext } from 'svelte';
|
|
17
17
|
import { _ } from 'svelte-i18n';
|
|
18
|
-
import { availableButtons } from '..';
|
|
19
18
|
import { isMac, matchShortcuts } from '../../../services/events.svelte';
|
|
20
19
|
import Button from '../../button/button.svelte';
|
|
21
20
|
import Dialog from '../../dialog/dialog.svelte';
|
|
22
21
|
import Icon from '../../icon/icon.svelte';
|
|
23
22
|
import TextInput from '../../text-field/text-input.svelte';
|
|
23
|
+
import { AVAILABLE_BUTTONS } from '../constants';
|
|
24
24
|
import { focusEditor } from '../core';
|
|
25
25
|
|
|
26
26
|
/**
|
|
@@ -188,7 +188,7 @@
|
|
|
188
188
|
|
|
189
189
|
<Button
|
|
190
190
|
iconic
|
|
191
|
-
aria-label={$_(`_sui.text_editor.${
|
|
191
|
+
aria-label={$_(`_sui.text_editor.${AVAILABLE_BUTTONS[type].labelKey}`)}
|
|
192
192
|
aria-controls="{editorStore.editorId}-lexical-root"
|
|
193
193
|
disabled={!editorStore.useRichText}
|
|
194
194
|
pressed={selectionTypeMatches}
|
|
@@ -197,7 +197,7 @@
|
|
|
197
197
|
}}
|
|
198
198
|
>
|
|
199
199
|
{#snippet startIcon()}
|
|
200
|
-
<Icon name={
|
|
200
|
+
<Icon name={AVAILABLE_BUTTONS[type].icon} />
|
|
201
201
|
{/snippet}
|
|
202
202
|
</Button>
|
|
203
203
|
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
import { unique } from '@sveltia/utils/array';
|
|
3
3
|
import { getContext } from 'svelte';
|
|
4
4
|
import { _ } from 'svelte-i18n';
|
|
5
|
-
import { availableButtons, blockButtonTypes, inlineButtonTypes } from '..';
|
|
6
5
|
import ButtonGroup from '../../button/button-group.svelte';
|
|
7
6
|
import Button from '../../button/button.svelte';
|
|
8
7
|
import Divider from '../../divider/divider.svelte';
|
|
@@ -10,6 +9,12 @@
|
|
|
10
9
|
import Icon from '../../icon/icon.svelte';
|
|
11
10
|
import MenuButton from '../../menu/menu-button.svelte';
|
|
12
11
|
import Menu from '../../menu/menu.svelte';
|
|
12
|
+
import {
|
|
13
|
+
AVAILABLE_BUTTONS,
|
|
14
|
+
BLOCK_BUTTON_TYPES,
|
|
15
|
+
IMAGE_COMPONENT_IDS,
|
|
16
|
+
INLINE_BUTTON_TYPES,
|
|
17
|
+
} from '../constants';
|
|
13
18
|
import CodeLanguageSwitcher from './code-language-switcher.svelte';
|
|
14
19
|
import FormatTextButton from './format-text-button.svelte';
|
|
15
20
|
import InsertImageButton from './insert-image-button.svelte';
|
|
@@ -43,9 +48,11 @@
|
|
|
43
48
|
|
|
44
49
|
/** @type {TextEditorStore} */
|
|
45
50
|
const editorStore = getContext('editorStore');
|
|
46
|
-
const imageComponent = $derived(
|
|
51
|
+
const imageComponent = $derived(
|
|
52
|
+
editorStore.config.components.find(({ id }) => IMAGE_COMPONENT_IDS.includes(id)),
|
|
53
|
+
);
|
|
47
54
|
const otherComponents = $derived(
|
|
48
|
-
editorStore.config.components.filter(({ id }) => id
|
|
55
|
+
editorStore.config.components.filter(({ id }) => !IMAGE_COMPONENT_IDS.includes(id)),
|
|
49
56
|
);
|
|
50
57
|
|
|
51
58
|
/**
|
|
@@ -56,7 +63,7 @@
|
|
|
56
63
|
unique([
|
|
57
64
|
'paragraph', // Always needed
|
|
58
65
|
...editorStore.config.enabledButtons.filter((type) =>
|
|
59
|
-
|
|
66
|
+
BLOCK_BUTTON_TYPES.includes(/** @type {any} */ (type)),
|
|
60
67
|
),
|
|
61
68
|
]),
|
|
62
69
|
);
|
|
@@ -68,7 +75,7 @@
|
|
|
68
75
|
const inlineLevelButtons = $derived(
|
|
69
76
|
unique([
|
|
70
77
|
...editorStore.config.enabledButtons.filter((type) =>
|
|
71
|
-
|
|
78
|
+
INLINE_BUTTON_TYPES.includes(/** @type {any} */ (type)),
|
|
72
79
|
),
|
|
73
80
|
]),
|
|
74
81
|
);
|
|
@@ -82,7 +89,7 @@
|
|
|
82
89
|
>
|
|
83
90
|
{#snippet startIcon()}
|
|
84
91
|
<Icon
|
|
85
|
-
name={
|
|
92
|
+
name={AVAILABLE_BUTTONS[editorStore.selection.blockType ?? '']?.icon ?? 'format_paragraph'}
|
|
86
93
|
/>
|
|
87
94
|
{/snippet}
|
|
88
95
|
{#snippet popup()}
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
} from 'lexical';
|
|
13
13
|
import { getContext } from 'svelte';
|
|
14
14
|
import { _ } from 'svelte-i18n';
|
|
15
|
-
import { availableButtons } from '..';
|
|
16
15
|
import Icon from '../../icon/icon.svelte';
|
|
17
16
|
import MenuItemCheckbox from '../../menu/menu-item-checkbox.svelte';
|
|
17
|
+
import { AVAILABLE_BUTTONS } from '../constants';
|
|
18
18
|
import { focusEditor } from '../core';
|
|
19
19
|
|
|
20
20
|
/**
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
|
|
91
91
|
{#key selectionTypeMatches}
|
|
92
92
|
<MenuItemCheckbox
|
|
93
|
-
label={$_(`_sui.text_editor.${
|
|
93
|
+
label={$_(`_sui.text_editor.${AVAILABLE_BUTTONS[type].labelKey}`)}
|
|
94
94
|
checked={selectionTypeMatches}
|
|
95
95
|
onclick={() => {
|
|
96
96
|
if (!selectionTypeMatches) {
|
|
@@ -99,7 +99,7 @@
|
|
|
99
99
|
}}
|
|
100
100
|
>
|
|
101
101
|
{#snippet startIcon()}
|
|
102
|
-
<Icon name={
|
|
102
|
+
<Icon name={AVAILABLE_BUTTONS[type].icon} />
|
|
103
103
|
{/snippet}
|
|
104
104
|
</MenuItemCheckbox>
|
|
105
105
|
{/key}
|
package/dist/services/i18n.js
CHANGED
|
@@ -10,7 +10,7 @@ import { addMessages, locale as appLocale, init } from 'svelte-i18n';
|
|
|
10
10
|
*/
|
|
11
11
|
export const initLocales = ({ fallbackLocale = 'en', initialLocale = 'en' } = {}) => {
|
|
12
12
|
/** @type {{ [key: string]: { strings: object }}} */
|
|
13
|
-
const modules = import.meta.glob('
|
|
13
|
+
const modules = import.meta.glob('../locales/*.js', { eager: true });
|
|
14
14
|
|
|
15
15
|
Object.entries(modules).forEach(([path, { strings }]) => {
|
|
16
16
|
const [, locale] = /** @type {string[]} */ (path.match(/([a-zA-Z-]+)\.js/));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sveltia/ui",
|
|
3
|
-
"version": "0.28.
|
|
3
|
+
"version": "0.28.2",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -49,15 +49,15 @@
|
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@sveltejs/adapter-auto": "^6.1.0",
|
|
52
|
-
"@sveltejs/kit": "^2.
|
|
53
|
-
"@sveltejs/package": "^2.5.
|
|
52
|
+
"@sveltejs/kit": "^2.40.0",
|
|
53
|
+
"@sveltejs/package": "^2.5.2",
|
|
54
54
|
"@sveltejs/vite-plugin-svelte": "6.2.0",
|
|
55
55
|
"cspell": "^9.2.1",
|
|
56
56
|
"eslint": "^8.57.1",
|
|
57
57
|
"eslint-config-airbnb-base": "^15.0.0",
|
|
58
58
|
"eslint-config-prettier": "^10.1.8",
|
|
59
59
|
"eslint-plugin-import": "^2.32.0",
|
|
60
|
-
"eslint-plugin-jsdoc": "^57.0.
|
|
60
|
+
"eslint-plugin-jsdoc": "^57.0.10",
|
|
61
61
|
"eslint-plugin-svelte": "^2.46.1",
|
|
62
62
|
"postcss": "^8.5.6",
|
|
63
63
|
"postcss-html": "^1.8.0",
|