@widgetic/editor 4.0.11 → 4.1.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.
- package/README.md +124 -0
- package/dist/components/WidgetPreview.svelte +58 -59
- package/dist/components/color-select/ColorSelect.svelte +4 -4
- package/dist/components/editors/CompositionEditorApp.svelte +69 -15
- package/dist/components/editors/CompositionEditorApp.svelte.d.ts +20 -0
- package/dist/components/editors/EmbedEditor.svelte +33 -22
- package/dist/components/editors/EmbedEditor.svelte.d.ts +1 -1
- package/dist/components/editors/PropsEditor.svelte +74 -58
- package/dist/components/editors/PropsEditor.svelte.d.ts +3 -3
- package/dist/components/ic/AngleInputController.svelte +1 -1
- package/dist/components/ic/BrowserInputController.svelte +37 -29
- package/dist/components/ic/ColorPickerInputController.svelte +31 -15
- package/dist/components/ic/DateFieldInputController.svelte +27 -11
- package/dist/components/ic/DatePickerInputController.svelte +27 -17
- package/dist/components/ic/DropdownInputController.svelte +10 -5
- package/dist/components/ic/DropdownInputController.svelte.d.ts +1 -1
- package/dist/components/ic/FixedPositionInputController.svelte +12 -6
- package/dist/components/ic/FontInputController.svelte +32 -27
- package/dist/components/ic/InputControllerHeader.svelte +5 -1
- package/dist/components/ic/NumberControls.svelte +4 -4
- package/dist/components/ic/NumberInputController.svelte +2 -2
- package/dist/components/ic/PositionInputController.svelte +9 -4
- package/dist/components/ic/RangeCalendarInputController.svelte +26 -16
- package/dist/components/ic/RoundedCornersInputController.svelte +22 -17
- package/dist/components/ic/SliderInputController.svelte +7 -2
- package/dist/components/ic/SwitchInputController.svelte +12 -3
- package/dist/components/ic/TagsInputController.svelte +19 -4
- package/dist/components/ic/TextAreaInputController.svelte +59 -44
- package/dist/components/ic/TextAreaPreviewInputController.svelte +8 -3
- package/dist/components/ic/TextInputController.svelte +17 -1
- package/dist/components/ic/TimeInputController.svelte +2 -1
- package/dist/components/ic/VectorInputController.svelte +21 -16
- package/dist/components/ic/shared/ItemGrid.svelte +7 -3
- package/dist/components/ic/shared/RecentItemsSection.svelte +16 -11
- package/dist/components/ic/shared/RecentItemsSection.svelte.d.ts +1 -1
- package/dist/composition/compositionEditorController.d.ts +11 -2
- package/dist/composition/compositionEditorController.js +33 -21
- package/dist/composition/compositionHelpers.d.ts +3 -1
- package/dist/composition/compositionHelpers.js +4 -2
- package/dist/i18n/index.d.ts +4 -0
- package/dist/i18n/index.js +4 -0
- package/dist/i18n/labels.d.ts +15 -0
- package/dist/i18n/labels.js +57 -0
- package/dist/i18n/language.d.ts +228 -0
- package/dist/i18n/language.js +34 -0
- package/dist/i18n/languageKit.d.ts +54 -0
- package/dist/i18n/languageKit.js +102 -0
- package/dist/i18n/messages.d.ts +241 -0
- package/dist/i18n/messages.js +253 -0
- package/dist/i18n/translate.d.ts +6 -0
- package/dist/i18n/translate.js +8 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +4 -0
- package/dist/utils/dockPlacement.d.ts +12 -0
- package/dist/utils/dockPlacement.js +13 -0
- package/dist/utils/fieldDirection.d.ts +13 -0
- package/dist/utils/fieldDirection.js +25 -0
- package/package.json +2 -2
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { SHAD_EDITOR_MESSAGES } from '@widgetic/design-system/shad-editor';
|
|
2
|
+
import { FILE_BROWSER_MESSAGES } from '@widgetic/file-browser';
|
|
3
|
+
import { EDITOR_MESSAGES } from './messages.js';
|
|
4
|
+
import { createEditorLanguageKit } from './languageKit.js';
|
|
5
|
+
/**
|
|
6
|
+
* The language of an editor on a page. The editor has two packages inside it (the File Browser that picks a file, and
|
|
7
|
+
* the rich text editor of the text boxes), each with its own catalog; a page gives ONE flat `messages` object and the
|
|
8
|
+
* editor hands each package the keys that are its own. See `languageKit.ts` for how, and for what a test can swap.
|
|
9
|
+
*/
|
|
10
|
+
/** The catalogs of the editor and of the packages inside it. A key belongs to one of them. */
|
|
11
|
+
export const EDITOR_CATALOGS = {
|
|
12
|
+
editor: EDITOR_MESSAGES,
|
|
13
|
+
fileBrowser: FILE_BROWSER_MESSAGES,
|
|
14
|
+
shadEditor: SHAD_EDITOR_MESSAGES
|
|
15
|
+
};
|
|
16
|
+
const editorLanguageKit = createEditorLanguageKit({ catalogs: EDITOR_CATALOGS });
|
|
17
|
+
/** Every message of the editor and of the packages inside it, as one catalog: what a page's `messages` may have a key of. */
|
|
18
|
+
export const ALL_EDITOR_MESSAGES = editorLanguageKit.allMessages;
|
|
19
|
+
/**
|
|
20
|
+
* Checks a page's `messages` against all the editor's catalogs without showing anything: a key that does not exist (with
|
|
21
|
+
* the nearest real one), a value that is not text, a template that does not parse, or one that asks for a value the message
|
|
22
|
+
* is never given. An empty list means every message will be used. For a test or a build step of the page.
|
|
23
|
+
*/
|
|
24
|
+
export const checkEditorMessages = editorLanguageKit.checkMessages;
|
|
25
|
+
/**
|
|
26
|
+
* Called by the root component of an editor while it is created, so everything inside it speaks the page's language.
|
|
27
|
+
* The context belongs to one root component, so two editors on a page can speak two languages.
|
|
28
|
+
*/
|
|
29
|
+
export const provideEditorLanguage = editorLanguageKit.provideLanguage;
|
|
30
|
+
/**
|
|
31
|
+
* Called by a part of the editor while it is created. Gives its words as stores, so a part that is already on the screen
|
|
32
|
+
* changes when the page sets the language again. Outside an editor (a control used on its own) it speaks English.
|
|
33
|
+
*/
|
|
34
|
+
export const useEditorLanguage = editorLanguageKit.useLanguage;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { type Readable } from 'svelte/store';
|
|
2
|
+
import { type I18nContext, type I18nSettings, type MessageOverrides, type MessageProblem, type SvelteContextApi } from '@widgetic/design-system/i18n';
|
|
3
|
+
import type { EditorMessageKey } from './messages.js';
|
|
4
|
+
/**
|
|
5
|
+
* The language of an editor on a page, shared with every part of it through Svelte's component context.
|
|
6
|
+
*
|
|
7
|
+
* The editor has two packages inside it (the File Browser that picks a file, and the rich text editor of the text boxes),
|
|
8
|
+
* and each speaks from its own catalog. A page does not have to know that: it gives ONE flat `messages` object, and this
|
|
9
|
+
* hands each package the keys that are its own.
|
|
10
|
+
*
|
|
11
|
+
* It is made from the catalogs, in a function, so a test can make one from catalogs of its own and with stand-ins for
|
|
12
|
+
* Svelte's context (the packages inside the editor are Svelte components, which a test in Node cannot load). The editor
|
|
13
|
+
* makes the one it uses in `language.ts`.
|
|
14
|
+
*/
|
|
15
|
+
/** The catalogs of the editor and of the packages inside it. A key belongs to one of them. */
|
|
16
|
+
export interface EditorCatalogs {
|
|
17
|
+
editor: Readonly<Record<EditorMessageKey, string>>;
|
|
18
|
+
fileBrowser: Readonly<Record<string, string>>;
|
|
19
|
+
shadEditor: Readonly<Record<string, string>>;
|
|
20
|
+
}
|
|
21
|
+
/** What the screens of the editor read their words from. */
|
|
22
|
+
export interface EditorLanguage extends I18nContext<EditorMessageKey> {
|
|
23
|
+
/** What the File Browser inside the editor is given: the page's language and the keys that are the File Browser's. */
|
|
24
|
+
fileBrowser: Readable<I18nSettings>;
|
|
25
|
+
/** What the rich text editor inside the editor is given: the page's language and the keys that are its own. */
|
|
26
|
+
shadEditor: Readable<I18nSettings>;
|
|
27
|
+
}
|
|
28
|
+
/** What `provideEditorLanguage` gives back to the component that called it. */
|
|
29
|
+
export interface EditorLanguageHandle extends EditorLanguage {
|
|
30
|
+
/** Changes the language every part below speaks. Cheap to call on every change of the props. */
|
|
31
|
+
update(settings: I18nSettings): void;
|
|
32
|
+
}
|
|
33
|
+
export interface EditorLanguageKitOptions {
|
|
34
|
+
catalogs: EditorCatalogs;
|
|
35
|
+
/** Stand-ins for Svelte's `getContext` and `setContext`; tests only. */
|
|
36
|
+
contextApi?: SvelteContextApi;
|
|
37
|
+
/** Where the warnings go; tests only. */
|
|
38
|
+
logger?: Pick<Console, 'warn'>;
|
|
39
|
+
}
|
|
40
|
+
export interface EditorLanguageKit {
|
|
41
|
+
/** Every message of the editor and of the packages inside it, as one catalog: what a page's `messages` may have a key of. */
|
|
42
|
+
allMessages: Readonly<Record<string, string>>;
|
|
43
|
+
/**
|
|
44
|
+
* Checks a page's `messages` against all the editor's catalogs without showing anything: a key that does not exist
|
|
45
|
+
* (with the nearest real one), a value that is not text, a template that does not parse, or one that asks for a value
|
|
46
|
+
* the message is never given. An empty list means every message will be used. For a test or a build step of the page.
|
|
47
|
+
*/
|
|
48
|
+
checkMessages(messages: MessageOverrides): MessageProblem[];
|
|
49
|
+
/** Called by the root component of an editor while it is created, so everything inside it speaks the page's language. */
|
|
50
|
+
provideLanguage(initial: I18nSettings): EditorLanguageHandle;
|
|
51
|
+
/** Called by a part of the editor while it is created. Outside an editor it speaks English. */
|
|
52
|
+
useLanguage(): EditorLanguage;
|
|
53
|
+
}
|
|
54
|
+
export declare function createEditorLanguageKit(options: EditorLanguageKitOptions): EditorLanguageKit;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { getContext, setContext } from 'svelte';
|
|
2
|
+
import { readable, writable } from 'svelte/store';
|
|
3
|
+
import { createI18n, describeMessageProblem, findMessageProblems, splitMessages } from '@widgetic/design-system/i18n';
|
|
4
|
+
/** How many different problems the console is told about, so a page that keeps changing its messages cannot fill memory. */
|
|
5
|
+
const MAX_REPORTED_KEYS = 200;
|
|
6
|
+
/** Two settings are the same language when they have the same locale and the same words. */
|
|
7
|
+
function signatureOf(settings) {
|
|
8
|
+
try {
|
|
9
|
+
return JSON.stringify([settings.locale ?? null, settings.messages ?? null]);
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
// Not serializable (a cycle, a BigInt): treat it as new every time rather than guess.
|
|
13
|
+
return `${Math.random()}`;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/** What the packages inside the editor are told when no editor above chose a language: nothing. */
|
|
17
|
+
const NOTHING_CHOSEN = readable({});
|
|
18
|
+
export function createEditorLanguageKit(options) {
|
|
19
|
+
const { catalogs } = options;
|
|
20
|
+
const api = options.contextApi ?? { getContext, setContext };
|
|
21
|
+
const logger = options.logger ?? console;
|
|
22
|
+
// The context belongs to one root component, so two editors on a page can speak two languages. The key is shared by
|
|
23
|
+
// every copy of the package, like the media library's.
|
|
24
|
+
const contextKey = Symbol.for('widgetic.editor.language');
|
|
25
|
+
const allMessages = {
|
|
26
|
+
...catalogs.fileBrowser,
|
|
27
|
+
...catalogs.shadEditor,
|
|
28
|
+
...catalogs.editor
|
|
29
|
+
};
|
|
30
|
+
const editorWords = createI18n({
|
|
31
|
+
catalog: catalogs.editor,
|
|
32
|
+
label: 'Editor',
|
|
33
|
+
contextApi: options.contextApi
|
|
34
|
+
});
|
|
35
|
+
/** What a part speaks when no editor above it chose a language: English, with nothing to tell the packages inside. */
|
|
36
|
+
const englishLanguage = Object.freeze({
|
|
37
|
+
t: readable(editorWords.translateEnglish),
|
|
38
|
+
locale: readable('en'),
|
|
39
|
+
fileBrowser: NOTHING_CHOSEN,
|
|
40
|
+
shadEditor: NOTHING_CHOSEN
|
|
41
|
+
});
|
|
42
|
+
const reportedKeys = new Set();
|
|
43
|
+
/** Says a key of the page's `messages` that no catalog has, once per page however often the language is set. */
|
|
44
|
+
function reportUnclaimedKeys(unclaimed) {
|
|
45
|
+
if (Object.keys(unclaimed).length === 0)
|
|
46
|
+
return;
|
|
47
|
+
for (const problem of findMessageProblems(allMessages, unclaimed)) {
|
|
48
|
+
const text = describeMessageProblem(problem);
|
|
49
|
+
if (reportedKeys.has(text) || reportedKeys.size >= MAX_REPORTED_KEYS)
|
|
50
|
+
continue;
|
|
51
|
+
reportedKeys.add(text);
|
|
52
|
+
logger.warn(`[Editor] ${text}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const slicesOf = (settings) => splitMessages(settings.messages, catalogs);
|
|
56
|
+
function provideLanguage(initial) {
|
|
57
|
+
const first = slicesOf(initial);
|
|
58
|
+
// The editor's own translator hears only the editor's keys: a key of the File Browser is not "unknown" to it.
|
|
59
|
+
const translator = editorWords.provideI18n({ locale: initial.locale, messages: first.slices.editor });
|
|
60
|
+
const fileBrowser = writable({ locale: initial.locale, messages: first.slices.fileBrowser });
|
|
61
|
+
const shadEditor = writable({ locale: initial.locale, messages: first.slices.shadEditor });
|
|
62
|
+
reportUnclaimedKeys(first.unclaimed);
|
|
63
|
+
const language = {
|
|
64
|
+
t: translator.t,
|
|
65
|
+
locale: translator.locale,
|
|
66
|
+
fileBrowser: { subscribe: fileBrowser.subscribe },
|
|
67
|
+
shadEditor: { subscribe: shadEditor.subscribe }
|
|
68
|
+
};
|
|
69
|
+
api.setContext(contextKey, language);
|
|
70
|
+
let lastSignature = signatureOf(initial);
|
|
71
|
+
return {
|
|
72
|
+
...language,
|
|
73
|
+
update(next) {
|
|
74
|
+
// Setting the same language again would rebuild every message for nothing.
|
|
75
|
+
const signature = signatureOf(next);
|
|
76
|
+
if (signature === lastSignature)
|
|
77
|
+
return;
|
|
78
|
+
lastSignature = signature;
|
|
79
|
+
const nextSlices = slicesOf(next);
|
|
80
|
+
translator.update({ locale: next.locale, messages: nextSlices.slices.editor });
|
|
81
|
+
fileBrowser.set({ locale: next.locale, messages: nextSlices.slices.fileBrowser });
|
|
82
|
+
shadEditor.set({ locale: next.locale, messages: nextSlices.slices.shadEditor });
|
|
83
|
+
reportUnclaimedKeys(nextSlices.unclaimed);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function useLanguage() {
|
|
88
|
+
try {
|
|
89
|
+
return api.getContext(contextKey) ?? englishLanguage;
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
// getContext only works while a component is being created; anywhere else there is no editor above to ask.
|
|
93
|
+
return englishLanguage;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
allMessages,
|
|
98
|
+
checkMessages: (messages) => findMessageProblems(allMessages, messages),
|
|
99
|
+
provideLanguage,
|
|
100
|
+
useLanguage
|
|
101
|
+
};
|
|
102
|
+
}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every word the editor shows to the person using it, in English: the one place to read them, and the keys a page can
|
|
3
|
+
* replace with the `messages` of the editor.
|
|
4
|
+
*
|
|
5
|
+
* A message is plain text. `{name}` is a value the editor puts in; `{count, plural, one {# file} other {# files}}` picks
|
|
6
|
+
* the form that fits a number in the page's language. `\{`, `\}`, `\#` and `\\` write those characters themselves. See
|
|
7
|
+
* `@widgetic/design-system/i18n` for the whole format.
|
|
8
|
+
*
|
|
9
|
+
* Keys are grouped by where the words appear. A key that is left out of a page's `messages` keeps the English text below,
|
|
10
|
+
* so a language can be added a screen at a time.
|
|
11
|
+
*
|
|
12
|
+
* Words that are NOT here, on purpose:
|
|
13
|
+
* - what the widget says about itself: the names, descriptions and options of its settings are written by the person who
|
|
14
|
+
* made the widget, and are shown as they were written;
|
|
15
|
+
* - what the File Browser and the rich text editor inside this editor say: they have their own catalogs
|
|
16
|
+
* (`FILE_BROWSER_MESSAGES`, `SHAD_EDITOR_MESSAGES`), and the same `messages` object can carry all three;
|
|
17
|
+
* - text the editor writes into the composition: the title of a new item ("Item 03"), the name of a composition that has
|
|
18
|
+
* none ("Untitled Composition"). Those are saved with the composition, so they do not change with the language.
|
|
19
|
+
*/
|
|
20
|
+
export declare const EDITOR_MESSAGES: {
|
|
21
|
+
readonly 'editor.app.loading': "Loading editor…";
|
|
22
|
+
readonly 'editor.app.tryAgain': "Try again";
|
|
23
|
+
readonly 'editor.app.retry': "Retry";
|
|
24
|
+
readonly 'editor.failure.widgetNotPublished': "Publish the widget before editing a composition.";
|
|
25
|
+
readonly 'editor.failure.sessionEndedWhileSaving': "Your session has ended, so your changes could not be saved. Reload the page to continue.";
|
|
26
|
+
readonly 'editor.failure.sessionEnded': "Your session has ended. Reload the page to continue.";
|
|
27
|
+
readonly 'editor.failure.compositionNotFound': "This composition could not be found.";
|
|
28
|
+
readonly 'editor.failure.noAccess': "You do not have access to this composition.";
|
|
29
|
+
readonly 'editor.failure.noWidget': "This composition has no widget.";
|
|
30
|
+
readonly 'editor.failure.widgetNotFound': "The widget this composition is made with could not be found.";
|
|
31
|
+
readonly 'editor.failure.saveNeedsConnection': "Your changes could not be saved. Check the connection and try again.";
|
|
32
|
+
readonly 'editor.failure.loadNeedsConnection': "The editor could not be loaded. Check the connection and try again.";
|
|
33
|
+
readonly 'editor.failure.saveFailed': "Your changes could not be saved.";
|
|
34
|
+
readonly 'editor.failure.loadFailed': "The editor could not be loaded.";
|
|
35
|
+
readonly 'editor.failure.settingsLoadFailed': "The editor settings could not be loaded. Try again.";
|
|
36
|
+
readonly 'editor.failure.noSettings': "No editable settings found. Generate and publish the widget first.";
|
|
37
|
+
/** A line under a message that has an error code: "Error code: CONFIG_NOT_FOUND". The code is not translated. */
|
|
38
|
+
readonly 'editor.failure.errorCode': "Error code: {code}";
|
|
39
|
+
readonly 'editor.props.title': "Edit Properties";
|
|
40
|
+
readonly 'editor.props.designTab': "Design";
|
|
41
|
+
readonly 'editor.props.contentTab': "Content";
|
|
42
|
+
/** The title of the card of settings that belong to no item, when the widget gave it none. */
|
|
43
|
+
readonly 'editor.props.contentCard': "Content";
|
|
44
|
+
readonly 'editor.props.save': "Save";
|
|
45
|
+
readonly 'editor.props.saving': "Saving";
|
|
46
|
+
readonly 'editor.props.noConfiguration': "No schema configuration available";
|
|
47
|
+
readonly 'editor.props.noDesignSchema': "No design schema available";
|
|
48
|
+
readonly 'editor.props.noSchemaData': "No schema data available";
|
|
49
|
+
readonly 'editor.props.noComponents': "No components defined in schema";
|
|
50
|
+
readonly 'editor.props.noProperties': "No properties available";
|
|
51
|
+
readonly 'editor.props.addItem': "Add new";
|
|
52
|
+
readonly 'editor.props.deleteItem': "Delete item";
|
|
53
|
+
readonly 'editor.embed.title': "Edit Options";
|
|
54
|
+
readonly 'editor.embed.loading': "Loading...";
|
|
55
|
+
readonly 'editor.embed.noCode': "No embed code available";
|
|
56
|
+
readonly 'editor.embed.codeHeader': "Embed code";
|
|
57
|
+
readonly 'editor.embed.headerArea': "Embed code header area";
|
|
58
|
+
readonly 'editor.embed.readMore': "Read more about embedding";
|
|
59
|
+
readonly 'editor.embed.copy': "Copy to clipboard";
|
|
60
|
+
/** The pop-ups after a copy: the title of the one that worked is the same for the editor's pop-up and the header's. */
|
|
61
|
+
readonly 'editor.embed.copied': "Copied to clipboard";
|
|
62
|
+
readonly 'editor.embed.copiedHint': "Paste it anywhere on your site.";
|
|
63
|
+
readonly 'editor.embed.copiedDone': "Content copied successfully.";
|
|
64
|
+
readonly 'editor.embed.copyFailed': "Copy failed";
|
|
65
|
+
readonly 'editor.embed.copyFailedHint': "Please try manual selection";
|
|
66
|
+
readonly 'editor.preview.title': "Preview";
|
|
67
|
+
readonly 'editor.preview.dragHandle': "Drag preview";
|
|
68
|
+
readonly 'editor.preview.desktop': "Desktop preview";
|
|
69
|
+
readonly 'editor.preview.mobile': "Mobile preview";
|
|
70
|
+
/** The first letters of "width" and "height", beside the two boxes where the size of the preview is typed. */
|
|
71
|
+
readonly 'editor.preview.widthShort': "W";
|
|
72
|
+
readonly 'editor.preview.heightShort': "H";
|
|
73
|
+
readonly 'editor.preview.noUrl': "no URL";
|
|
74
|
+
readonly 'editor.preview.copyUrl': "Copy URL";
|
|
75
|
+
readonly 'editor.preview.refresh': "Refresh preview";
|
|
76
|
+
readonly 'editor.preview.fitToPanel': "Fit preview to panel";
|
|
77
|
+
readonly 'editor.preview.mobileViewport': "Mobile viewport";
|
|
78
|
+
readonly 'editor.preview.desktopViewport': "Desktop viewport (full window)";
|
|
79
|
+
readonly 'editor.preview.openInNewTab': "Open in new tab";
|
|
80
|
+
readonly 'editor.preview.newTab': "↗ New tab";
|
|
81
|
+
readonly 'editor.preview.selectWidget': "Select a widget to preview";
|
|
82
|
+
/** What the name of a widget is when it has none. */
|
|
83
|
+
readonly 'editor.preview.widgetName': "Widget";
|
|
84
|
+
readonly 'editor.preview.notPublished': "Not published yet";
|
|
85
|
+
readonly 'editor.preview.publishToPreview': "Publish the widget in Widget Creator to preview it here.";
|
|
86
|
+
readonly 'editor.preview.frameTitle': "Widget preview";
|
|
87
|
+
readonly 'editor.preview.frameTitleNamed': "Widget preview – {name}";
|
|
88
|
+
readonly 'editor.preview.unavailable': "Preview Unavailable";
|
|
89
|
+
readonly 'editor.preview.loadFailedPreview': "Failed to load widget preview.";
|
|
90
|
+
readonly 'editor.preview.retry': "Retry";
|
|
91
|
+
readonly 'editor.preview.retryBuild': "Retry Build";
|
|
92
|
+
readonly 'editor.preview.retryPreview': "Retry Preview";
|
|
93
|
+
readonly 'editor.preview.fixErrors': "Fix Errors";
|
|
94
|
+
readonly 'editor.preview.viewErrors': "View Errors";
|
|
95
|
+
readonly 'editor.preview.runtimeError': "Widget runtime error";
|
|
96
|
+
readonly 'editor.preview.compilationErrors': "Code Has Compilation Errors";
|
|
97
|
+
/** `{status}` is the HTTP status the preview page answered with. */
|
|
98
|
+
readonly 'editor.preview.compilationErrorsDetail': "The generated code has syntax or compilation errors (HTTP {status}).";
|
|
99
|
+
readonly 'editor.preview.noCodeYet': "No Code Generated Yet";
|
|
100
|
+
readonly 'editor.preview.noPreview': "No Preview Available";
|
|
101
|
+
readonly 'editor.preview.building': "Building Preview...";
|
|
102
|
+
readonly 'editor.preview.loadingWidget': "Loading widget…";
|
|
103
|
+
readonly 'editor.preview.loadingPreview': "Loading Preview…";
|
|
104
|
+
readonly 'editor.preview.checkingWidget': "Checking widget on Worker…";
|
|
105
|
+
readonly 'editor.preview.applyingSettings': "Applying composition settings…";
|
|
106
|
+
readonly 'editor.preview.connecting': "Connecting to the widget preview…";
|
|
107
|
+
readonly 'editor.preview.generatingCode': "Generating code…";
|
|
108
|
+
readonly 'editor.list.recentlyUsed': "Recently used";
|
|
109
|
+
readonly 'editor.list.more': "More";
|
|
110
|
+
readonly 'editor.list.searchResults': "Search results";
|
|
111
|
+
readonly 'editor.list.loadingMore': "Loading more items...";
|
|
112
|
+
readonly 'editor.list.deleteItem': "Delete";
|
|
113
|
+
/** The tabs above a list of fonts or vectors. */
|
|
114
|
+
readonly 'editor.category.all': "All";
|
|
115
|
+
readonly 'editor.category.mine': "Mine";
|
|
116
|
+
readonly 'editor.category.sansSerif': "Sans Serif";
|
|
117
|
+
readonly 'editor.category.serif': "Serif";
|
|
118
|
+
readonly 'editor.category.script': "Script";
|
|
119
|
+
readonly 'editor.category.other': "Other";
|
|
120
|
+
readonly 'editor.category.icons': "Icons";
|
|
121
|
+
readonly 'editor.category.emojis': "Emojis";
|
|
122
|
+
readonly 'editor.category.clipart': "Clipart";
|
|
123
|
+
readonly 'editor.font.select': "Select font...";
|
|
124
|
+
readonly 'editor.font.title': "Fonts";
|
|
125
|
+
readonly 'editor.font.search': "Search fonts...";
|
|
126
|
+
readonly 'editor.font.list': "Font list";
|
|
127
|
+
readonly 'editor.font.loading': "Loading fonts";
|
|
128
|
+
readonly 'editor.font.noneFound': "No fonts found";
|
|
129
|
+
readonly 'editor.font.noneAvailable': "No fonts available";
|
|
130
|
+
readonly 'editor.font.remove': "Remove font";
|
|
131
|
+
readonly 'editor.font.weight': "Font Weight";
|
|
132
|
+
/** The name a screen reader gives the list of weights a font has, when its menu is open. */
|
|
133
|
+
readonly 'editor.font.weightList': "Font weights";
|
|
134
|
+
/** The look of a weight that has a name of its own; `{weight}` is one of the names below ("Bold Italic"). */
|
|
135
|
+
readonly 'editor.fontWeight.withItalic': "{weight} Italic";
|
|
136
|
+
readonly 'editor.fontWeight.italic': "Italic";
|
|
137
|
+
readonly 'editor.fontWeight.thin': "Thin";
|
|
138
|
+
readonly 'editor.fontWeight.extraLight': "ExtraLight";
|
|
139
|
+
readonly 'editor.fontWeight.light': "Light";
|
|
140
|
+
readonly 'editor.fontWeight.regular': "Regular";
|
|
141
|
+
readonly 'editor.fontWeight.medium': "Medium";
|
|
142
|
+
readonly 'editor.fontWeight.semiBold': "SemiBold";
|
|
143
|
+
readonly 'editor.fontWeight.bold': "Bold";
|
|
144
|
+
readonly 'editor.fontWeight.extraBold': "ExtraBold";
|
|
145
|
+
readonly 'editor.fontWeight.black': "Black";
|
|
146
|
+
readonly 'editor.vector.select': "Select vector...";
|
|
147
|
+
readonly 'editor.vector.title': "Vectors";
|
|
148
|
+
readonly 'editor.vector.search': "Search vectors...";
|
|
149
|
+
readonly 'editor.vector.list': "Vector list";
|
|
150
|
+
readonly 'editor.vector.noneFound': "No vectors found";
|
|
151
|
+
readonly 'editor.vector.noneAvailable': "No vectors available";
|
|
152
|
+
readonly 'editor.file.useFile': "Use file";
|
|
153
|
+
readonly 'editor.file.useImage': "Use image";
|
|
154
|
+
readonly 'editor.file.useVideo': "Use video";
|
|
155
|
+
readonly 'editor.file.useAudio': "Use audio";
|
|
156
|
+
readonly 'editor.file.useDocument': "Use document";
|
|
157
|
+
readonly 'editor.file.addFile': "Add file...";
|
|
158
|
+
readonly 'editor.file.addImage': "Add image...";
|
|
159
|
+
readonly 'editor.file.addVideo': "Add video...";
|
|
160
|
+
readonly 'editor.file.addAudio': "Add audio...";
|
|
161
|
+
readonly 'editor.file.addDocument': "Add docs...";
|
|
162
|
+
readonly 'editor.file.play': "Play";
|
|
163
|
+
readonly 'editor.file.pause': "Pause";
|
|
164
|
+
readonly 'editor.file.notFound': "File not found";
|
|
165
|
+
readonly 'editor.file.emptyFolder': "Empty folder";
|
|
166
|
+
readonly 'editor.file.clear': "Clear file";
|
|
167
|
+
readonly 'editor.file.dialogTitle': "Select file";
|
|
168
|
+
readonly 'editor.file.closeDialog': "Close file browser";
|
|
169
|
+
readonly 'editor.color.noRecent': "No recent colors";
|
|
170
|
+
readonly 'editor.color.picker': "Color picker";
|
|
171
|
+
readonly 'editor.date.pick': "Pick a date";
|
|
172
|
+
readonly 'editor.date.pickRange': "Pick a date range";
|
|
173
|
+
readonly 'editor.date.invalid': "Invalid date";
|
|
174
|
+
readonly 'editor.date.selectMonth': "Select month";
|
|
175
|
+
readonly 'editor.date.selectYear': "Select year";
|
|
176
|
+
/**
|
|
177
|
+
* The name a screen reader gives the calendar of one date. The library writes the month and year after it ("Date
|
|
178
|
+
* October 2026"), so a short noun is best.
|
|
179
|
+
*/
|
|
180
|
+
readonly 'editor.date.calendarLabel': "Date";
|
|
181
|
+
/** The same for the calendar of a range of dates ("Date range October - November 2026"). */
|
|
182
|
+
readonly 'editor.date.rangeCalendarLabel': "Date range";
|
|
183
|
+
/** The name a screen reader gives the buttons of a calendar that show the month before and the month after. */
|
|
184
|
+
readonly 'editor.date.previousMonth': "Previous month";
|
|
185
|
+
readonly 'editor.date.nextMonth': "Next month";
|
|
186
|
+
/** What is typed in the three boxes of a date: the hint inside the box, and its name for a screen reader. */
|
|
187
|
+
readonly 'editor.dateField.dayHint': "DD";
|
|
188
|
+
readonly 'editor.dateField.monthHint': "MM";
|
|
189
|
+
readonly 'editor.dateField.yearHint': "YYYY";
|
|
190
|
+
readonly 'editor.dateField.dayLabel': "Day input";
|
|
191
|
+
readonly 'editor.dateField.monthLabel': "Month input";
|
|
192
|
+
readonly 'editor.dateField.yearLabel': "Year input";
|
|
193
|
+
readonly 'editor.dropdown.select': "Select an option";
|
|
194
|
+
readonly 'editor.switch.off': "Off";
|
|
195
|
+
readonly 'editor.switch.on': "On";
|
|
196
|
+
readonly 'editor.tags.add': "Add tag...";
|
|
197
|
+
/** The two letters beside the position of a point in a picture: how far across, and how far down. */
|
|
198
|
+
readonly 'editor.position.x': "X:";
|
|
199
|
+
readonly 'editor.position.y': "Y:";
|
|
200
|
+
/** The buttons of the nine places on a screen; `{position}` is one of the names below. */
|
|
201
|
+
readonly 'editor.fixedPosition.set': "Set position to {position}";
|
|
202
|
+
readonly 'editor.fixedPosition.topLeft': "top-left";
|
|
203
|
+
readonly 'editor.fixedPosition.topCenter': "top-center";
|
|
204
|
+
readonly 'editor.fixedPosition.topRight': "top-right";
|
|
205
|
+
readonly 'editor.fixedPosition.centerLeft': "center-left";
|
|
206
|
+
readonly 'editor.fixedPosition.centerCenter': "center-center";
|
|
207
|
+
readonly 'editor.fixedPosition.centerRight': "center-right";
|
|
208
|
+
readonly 'editor.fixedPosition.bottomLeft': "bottom-left";
|
|
209
|
+
readonly 'editor.fixedPosition.bottomCenter': "bottom-center";
|
|
210
|
+
readonly 'editor.fixedPosition.bottomRight': "bottom-right";
|
|
211
|
+
/** The corners of a box: the name of the group, of each of the four boxes, and of the lock between them. */
|
|
212
|
+
readonly 'editor.corners.group': "Corner radius";
|
|
213
|
+
readonly 'editor.corners.topLeft': "Top left corner radius";
|
|
214
|
+
readonly 'editor.corners.topRight': "Top right corner radius";
|
|
215
|
+
readonly 'editor.corners.bottomLeft': "Bottom left corner radius";
|
|
216
|
+
readonly 'editor.corners.bottomRight': "Bottom right corner radius";
|
|
217
|
+
readonly 'editor.corners.lock': "Lock corner radius values";
|
|
218
|
+
readonly 'editor.corners.unlock': "Unlock corner radius values";
|
|
219
|
+
readonly 'editor.textArea.toolbar': "Text formatting toolbar";
|
|
220
|
+
readonly 'editor.textArea.toggleBold': "Toggle bold";
|
|
221
|
+
readonly 'editor.textArea.toggleItalic': "Toggle italic";
|
|
222
|
+
readonly 'editor.textArea.toggleUnderline': "Toggle underline";
|
|
223
|
+
readonly 'editor.textArea.toggleLink': "Toggle link";
|
|
224
|
+
readonly 'editor.textArea.text': "Text";
|
|
225
|
+
readonly 'editor.textArea.paragraph': "Paragraph";
|
|
226
|
+
readonly 'editor.textArea.heading1': "H1";
|
|
227
|
+
readonly 'editor.textArea.heading2': "H2";
|
|
228
|
+
readonly 'editor.textArea.heading3': "H3";
|
|
229
|
+
readonly 'editor.textArea.bulletList': "Bullet List";
|
|
230
|
+
readonly 'editor.textArea.numberedList': "Numbered List";
|
|
231
|
+
readonly 'editor.textArea.checkList': "Check List";
|
|
232
|
+
/** The name a screen reader gives the list of text styles (paragraph, headings) when its menu is open. */
|
|
233
|
+
readonly 'editor.textArea.textStyles': "Text styles";
|
|
234
|
+
/** The name a screen reader gives the list of list styles (bullets, numbers, checks) when its menu is open. */
|
|
235
|
+
readonly 'editor.textArea.listStyles': "List styles";
|
|
236
|
+
/** The question the browser asks when a link is added. */
|
|
237
|
+
readonly 'editor.textArea.enterUrl': "Enter URL";
|
|
238
|
+
readonly 'editor.schema.subtitleFont': "Subtitle Font";
|
|
239
|
+
};
|
|
240
|
+
/** The name of one message. */
|
|
241
|
+
export type EditorMessageKey = keyof typeof EDITOR_MESSAGES;
|