@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
|
@@ -24,7 +24,12 @@
|
|
|
24
24
|
* The component is made for ONE composition: to edit another one, make another component.
|
|
25
25
|
*/
|
|
26
26
|
import { createEventDispatcher, onDestroy, onMount, tick } from 'svelte';
|
|
27
|
+
import { get, writable } from 'svelte/store';
|
|
27
28
|
import { createWidgeticMediaLibrary, type MediaLibraryProvider } from '@widgetic/file-browser';
|
|
29
|
+
import type { MessageOverrides } from '@widgetic/design-system/i18n';
|
|
30
|
+
import { shareTextDirection, type TextDirection } from '@widgetic/design-system/components/textDirection';
|
|
31
|
+
import { leftOnThisScreen } from '../../utils/dockPlacement';
|
|
32
|
+
import { provideEditorLanguage } from '../../i18n/language.js';
|
|
28
33
|
import PropsEditor from './PropsEditor.svelte';
|
|
29
34
|
import WidgetPreview from '../WidgetPreview.svelte';
|
|
30
35
|
import { setGoogleFontsApiKey } from '../../config';
|
|
@@ -75,6 +80,43 @@
|
|
|
75
80
|
export let autosaveDelayMs: number | undefined = undefined;
|
|
76
81
|
/** Writes what the layout does to the console. */
|
|
77
82
|
export let debug = false;
|
|
83
|
+
/**
|
|
84
|
+
* The language of the editor: a BCP 47 tag ("de", "pt-BR") that sets how plurals, numbers and dates are written.
|
|
85
|
+
* Without it, English. The words themselves come from `messages`.
|
|
86
|
+
*/
|
|
87
|
+
export let locale: string | null | undefined = undefined;
|
|
88
|
+
/**
|
|
89
|
+
* The words of the editor in the language of the page: any of the keys of `EDITOR_MESSAGES` (and of the File
|
|
90
|
+
* Browser's and the rich text editor's catalogs, which are inside the editor). One flat object; a key left out keeps
|
|
91
|
+
* its English text. See `checkEditorMessages` to test it.
|
|
92
|
+
*/
|
|
93
|
+
export let messages: MessageOverrides | null | undefined = undefined;
|
|
94
|
+
/**
|
|
95
|
+
* Which way the editor is read: "ltr" or "rtl". The page that puts it on screen sets `dir` on an element around it and the
|
|
96
|
+
* browser turns the layout around; this prop says the same to the parts that wrap a library which writes a `dir` of its own
|
|
97
|
+
* (the menus, the scroll areas, the File Browser and the rich text editor inside it), and to the code that places the settings
|
|
98
|
+
* editor and the preview: with "rtl" the settings editor is on the right of the middle and the preview on its left.
|
|
99
|
+
* It is NOT worked out from `locale`: an editor on a page that is laid out left to right can speak Arabic and still be left
|
|
100
|
+
* to right. Left out, the editor is read the way the screen around it is, and left to right when nothing around it says.
|
|
101
|
+
* Can change while the editor is open.
|
|
102
|
+
*/
|
|
103
|
+
export let dir: TextDirection | undefined = undefined;
|
|
104
|
+
|
|
105
|
+
// --- the direction ----------------------------------------------------------------------------------
|
|
106
|
+
|
|
107
|
+
// Every part below reads the direction from Svelte's context (the File Browser and the rich text editor too), and follows
|
|
108
|
+
// when the page changes `dir`. `textDirection` is the answer, for the editor's own decisions.
|
|
109
|
+
const givenDirection = writable<TextDirection | undefined>(dir);
|
|
110
|
+
const textDirection = shareTextDirection(givenDirection);
|
|
111
|
+
$: givenDirection.set(dir);
|
|
112
|
+
|
|
113
|
+
// --- the language -----------------------------------------------------------------------------------
|
|
114
|
+
|
|
115
|
+
// Every part of the editor reads its words from here (and the File Browser and the rich text editor inside it from
|
|
116
|
+
// what this hands them). Setting `locale` or `messages` again changes what is on the screen.
|
|
117
|
+
const language = provideEditorLanguage({ locale, messages });
|
|
118
|
+
const { t } = language;
|
|
119
|
+
$: language.update({ locale, messages });
|
|
78
120
|
|
|
79
121
|
// --- the controller -------------------------------------------------------------------------------
|
|
80
122
|
|
|
@@ -88,6 +130,8 @@
|
|
|
88
130
|
compositionId,
|
|
89
131
|
api,
|
|
90
132
|
autosaveDelayMs,
|
|
133
|
+
// The sentences the controller makes (why there is no preview) are made in the language of the moment.
|
|
134
|
+
translate: (key, values) => get(language.t)(key, values),
|
|
91
135
|
// The preview page hears about every change as it happens (and everything, once its page has loaded).
|
|
92
136
|
onPreviewMessage: (message: PreviewMessage) =>
|
|
93
137
|
previewRef?.sendMessageToPreview?.({ ...message })
|
|
@@ -193,7 +237,7 @@
|
|
|
193
237
|
$: isMobilePreview = state.deviceView === 'mobile';
|
|
194
238
|
// "Loading editor…" sits in the middle while the composition loads, and where the editor is about to appear after.
|
|
195
239
|
$: loadingCardPosition =
|
|
196
|
-
state.phase === 'ready' ? '
|
|
240
|
+
state.phase === 'ready' ? 'start-4 top-4' : 'left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2';
|
|
197
241
|
// A preview address that has just arrived is a page still to load: the preview says so until its frame has loaded.
|
|
198
242
|
$: startHydrating(previewSrc);
|
|
199
243
|
|
|
@@ -264,7 +308,8 @@
|
|
|
264
308
|
|
|
265
309
|
$: if (googleFontsApiKey) setGoogleFontsApiKey(googleFontsApiKey);
|
|
266
310
|
|
|
267
|
-
// --- the layout: settings editor
|
|
311
|
+
// --- the layout: settings editor beside the middle, preview on the other side of it -------------
|
|
312
|
+
// (the editor on the left and the preview on the right of a left to right screen; the other way round on a right to left one)
|
|
268
313
|
|
|
269
314
|
const EDITOR_WIDTH_PX = 450;
|
|
270
315
|
const EDITOR_PADDING = 20;
|
|
@@ -278,7 +323,8 @@
|
|
|
278
323
|
$: editorVisible =
|
|
279
324
|
state.phase === 'ready' && !state.schemasLoading && !state.schemasError && schemasAvailable;
|
|
280
325
|
// Placed once the editor is on the screen, not on every change: it must not jump back while it is being dragged.
|
|
281
|
-
|
|
326
|
+
// It is placed again when the screen turns around, because the pair is the mirror of itself.
|
|
327
|
+
$: if (editorVisible && $textDirection) requestDock();
|
|
282
328
|
|
|
283
329
|
function log(message: string, details?: unknown) {
|
|
284
330
|
if (!debug) return;
|
|
@@ -294,7 +340,7 @@
|
|
|
294
340
|
void tick().then(() => requestAnimationFrame(() => dockFloatingEditorOnce()));
|
|
295
341
|
}
|
|
296
342
|
|
|
297
|
-
/** Editor
|
|
343
|
+
/** Editor on one side of the middle, preview on the other, each EDITOR_PADDING from the middle: the editor starts the line, the preview follows it. */
|
|
298
344
|
function dockFloatingEditorOnce() {
|
|
299
345
|
if (!editorShellEl) return;
|
|
300
346
|
try {
|
|
@@ -304,9 +350,9 @@
|
|
|
304
350
|
|
|
305
351
|
const middleX = Math.round(shellWidth / 2);
|
|
306
352
|
const previewHeight = state.previewHeight + PREVIEW_CHROME_HEIGHT;
|
|
307
|
-
const leftEditor = Math.max(EDITOR_PADDING, middleX - EDITOR_PADDING - EDITOR_WIDTH_PX);
|
|
353
|
+
const leftEditor = leftOnThisScreen($textDirection, Math.max(EDITOR_PADDING, middleX - EDITOR_PADDING - EDITOR_WIDTH_PX), EDITOR_WIDTH_PX, shellWidth);
|
|
308
354
|
const topEditor = EDITOR_PADDING;
|
|
309
|
-
const leftPreview = middleX + EDITOR_PADDING;
|
|
355
|
+
const leftPreview = leftOnThisScreen($textDirection, middleX + EDITOR_PADDING, state.previewWidth, shellWidth);
|
|
310
356
|
const topPreview = Math.max(EDITOR_PADDING, Math.round((shellHeight - previewHeight) / 2));
|
|
311
357
|
|
|
312
358
|
void tick().then(() => {
|
|
@@ -314,6 +360,7 @@
|
|
|
314
360
|
previewRef?.setShellPosition?.(leftPreview, topPreview);
|
|
315
361
|
});
|
|
316
362
|
log('Docked the editor and the preview', {
|
|
363
|
+
direction: $textDirection,
|
|
317
364
|
height: floatingEditorHeight,
|
|
318
365
|
middleX,
|
|
319
366
|
leftEditor,
|
|
@@ -362,6 +409,7 @@
|
|
|
362
409
|
|
|
363
410
|
<div
|
|
364
411
|
class="composition-editor-ct relative h-full min-h-0 w-full overflow-hidden {className}"
|
|
412
|
+
dir={$textDirection}
|
|
365
413
|
{style}
|
|
366
414
|
bind:this={editorShellEl}
|
|
367
415
|
>
|
|
@@ -410,7 +458,7 @@
|
|
|
410
458
|
role="alert"
|
|
411
459
|
class="composition-editor-error absolute left-1/2 top-1/2 z-30 flex w-max max-w-sm -translate-x-1/2 -translate-y-1/2 flex-col gap-2 rounded-lg border border-red-200 bg-white p-4 shadow-sm"
|
|
412
460
|
>
|
|
413
|
-
<p class="text-sm text-red-600">{failureMessage(state.loadError, 'load')}</p>
|
|
461
|
+
<p class="text-sm text-red-600">{failureMessage(state.loadError, 'load', $t)}</p>
|
|
414
462
|
<button
|
|
415
463
|
type="button"
|
|
416
464
|
class="retry-load-btn w-fit cursor-pointer rounded-lg bg-blue-100 px-2 py-1 text-xs text-blue-700 hover:bg-blue-200 focus:outline-none focus-visible:outline-none"
|
|
@@ -418,7 +466,7 @@
|
|
|
418
466
|
void controller.load();
|
|
419
467
|
}}
|
|
420
468
|
>
|
|
421
|
-
|
|
469
|
+
{$t('editor.app.tryAgain')}
|
|
422
470
|
</button>
|
|
423
471
|
</div>
|
|
424
472
|
{:else if state.phase !== 'ready' || state.schemasLoading}
|
|
@@ -426,12 +474,12 @@
|
|
|
426
474
|
role="status"
|
|
427
475
|
class="composition-editor-loading absolute z-30 rounded-lg border border-gray-200 bg-white px-4 py-3 text-sm text-gray-500 shadow-sm {loadingCardPosition}"
|
|
428
476
|
>
|
|
429
|
-
|
|
477
|
+
{$t('editor.app.loading')}
|
|
430
478
|
</div>
|
|
431
479
|
{:else if state.schemasError}
|
|
432
480
|
<div
|
|
433
481
|
role="alert"
|
|
434
|
-
class="composition-editor-error absolute
|
|
482
|
+
class="composition-editor-error absolute start-4 top-4 z-30 flex max-w-sm flex-col gap-2 rounded-lg border border-red-200 bg-white p-4 shadow-sm"
|
|
435
483
|
>
|
|
436
484
|
<span class="text-xs text-red-600">{state.schemasError}</span>
|
|
437
485
|
<button
|
|
@@ -441,14 +489,20 @@
|
|
|
441
489
|
void controller.reloadSchemas();
|
|
442
490
|
}}
|
|
443
491
|
>
|
|
444
|
-
|
|
492
|
+
{$t('editor.app.retry')}
|
|
445
493
|
</button>
|
|
446
494
|
</div>
|
|
447
495
|
{:else if schemasAvailable}
|
|
496
|
+
<!--
|
|
497
|
+
The panel is placed from the left edge of the editor's area, so it says `position: absolute` itself: the class of the
|
|
498
|
+
same name loses to the `relative` the panel's own root carries, and a relative box moves from where it sits in the flow,
|
|
499
|
+
which is the left edge only on a left to right screen (on a right to left one it sits at the right edge, and a `left` of
|
|
500
|
+
720px puts it 720px beyond that: out of sight).
|
|
501
|
+
-->
|
|
448
502
|
<PropsEditor
|
|
449
503
|
bind:this={propsEditorRef}
|
|
450
504
|
class="composition-props-editor absolute z-20 shadow-lg"
|
|
451
|
-
style="left: {EDITOR_PADDING}px; top: {EDITOR_PADDING}px;"
|
|
505
|
+
style="position: absolute; left: {EDITOR_PADDING}px; top: {EDITOR_PADDING}px; /* rtl-ok: the dock puts the panel in pixels from the left edge as soon as it is on screen (see dockFloatingEditorOnce) */"
|
|
452
506
|
designSchema={state.designSchema}
|
|
453
507
|
contentSchema={propsEditorContentSchema}
|
|
454
508
|
initialDesignValues={state.designValues}
|
|
@@ -473,9 +527,9 @@
|
|
|
473
527
|
{#if state.phase === 'ready' && state.saveError}
|
|
474
528
|
<div
|
|
475
529
|
role="alert"
|
|
476
|
-
class="composition-editor-save-error absolute bottom-4
|
|
530
|
+
class="composition-editor-save-error absolute bottom-4 start-4 z-30 flex max-w-sm flex-col gap-2 rounded-lg border border-red-200 bg-white p-4 shadow-sm"
|
|
477
531
|
>
|
|
478
|
-
<p class="text-sm text-red-600">{failureMessage(state.saveError, 'save')}</p>
|
|
532
|
+
<p class="text-sm text-red-600">{failureMessage(state.saveError, 'save', $t)}</p>
|
|
479
533
|
<button
|
|
480
534
|
type="button"
|
|
481
535
|
class="retry-save-btn w-fit cursor-pointer rounded-lg bg-blue-100 px-2 py-1 text-xs text-blue-700 hover:bg-blue-200 focus:outline-none focus-visible:outline-none"
|
|
@@ -483,7 +537,7 @@
|
|
|
483
537
|
void controller.save('manual');
|
|
484
538
|
}}
|
|
485
539
|
>
|
|
486
|
-
|
|
540
|
+
{$t('editor.app.tryAgain')}
|
|
487
541
|
</button>
|
|
488
542
|
</div>
|
|
489
543
|
{/if}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { type MediaLibraryProvider } from '@widgetic/file-browser';
|
|
2
|
+
import type { MessageOverrides } from '@widgetic/design-system/i18n';
|
|
3
|
+
import { type TextDirection } from '@widgetic/design-system/components/textDirection';
|
|
2
4
|
import { type TokenReason } from '../../composition/compositionApi.js';
|
|
3
5
|
import { type CompositionEditorState, type EditorFailure } from '../../composition/compositionEditorController.js';
|
|
4
6
|
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
@@ -33,6 +35,24 @@ declare const CompositionEditorApp: $$__sveltets_2_IsomorphicComponent<{
|
|
|
33
35
|
/** The key the font pickers list Google Fonts with. Without one only the fonts that need no key are listed. */ googleFontsApiKey?: string;
|
|
34
36
|
/** Wait this long after the last change before saving by itself; `0` turns saving by itself off. Read once, when the editor starts. */ autosaveDelayMs?: number | undefined;
|
|
35
37
|
/** Writes what the layout does to the console. */ debug?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* The language of the editor: a BCP 47 tag ("de", "pt-BR") that sets how plurals, numbers and dates are written.
|
|
40
|
+
* Without it, English. The words themselves come from `messages`.
|
|
41
|
+
*/ locale?: string | null | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* The words of the editor in the language of the page: any of the keys of `EDITOR_MESSAGES` (and of the File
|
|
44
|
+
* Browser's and the rich text editor's catalogs, which are inside the editor). One flat object; a key left out keeps
|
|
45
|
+
* its English text. See `checkEditorMessages` to test it.
|
|
46
|
+
*/ messages?: MessageOverrides | null | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* Which way the editor is read: "ltr" or "rtl". The page that puts it on screen sets `dir` on an element around it and the
|
|
49
|
+
* browser turns the layout around; this prop says the same to the parts that wrap a library which writes a `dir` of its own
|
|
50
|
+
* (the menus, the scroll areas, the File Browser and the rich text editor inside it), and to the code that places the settings
|
|
51
|
+
* editor and the preview: with "rtl" the settings editor is on the right of the middle and the preview on its left.
|
|
52
|
+
* It is NOT worked out from `locale`: an editor on a page that is laid out left to right can speak Arabic and still be left
|
|
53
|
+
* to right. Left out, the editor is read the way the screen around it is, and left to right when nothing around it says.
|
|
54
|
+
* Can change while the editor is open.
|
|
55
|
+
*/ dir?: TextDirection | undefined;
|
|
36
56
|
save?: () => Promise<boolean>;
|
|
37
57
|
flush?: () => Promise<boolean>;
|
|
38
58
|
isDirty?: () => boolean;
|
|
@@ -13,12 +13,14 @@ import { onMount } from 'svelte';
|
|
|
13
13
|
import { toast, CopyableHeader } from '@widgetic/design-system/components';
|
|
14
14
|
import OK from '../icons/ok.svelte';
|
|
15
15
|
import PropsEditor from './PropsEditor.svelte';
|
|
16
|
+
import { useEditorLanguage } from '../../i18n/language';
|
|
16
17
|
|
|
17
18
|
/** Component configuration — existing public props and methods are preserved. */
|
|
18
19
|
let className = '';
|
|
19
20
|
export { className as class };
|
|
20
21
|
export let style = '';
|
|
21
|
-
|
|
22
|
+
/** The title of the code box. Without one, the editor's own word in the language of the page. */
|
|
23
|
+
export let embedHeaderText: string | undefined = undefined;
|
|
22
24
|
export let embedCode = '';
|
|
23
25
|
export let height = 720;
|
|
24
26
|
export let embedSchema: any;
|
|
@@ -33,6 +35,9 @@ export let saveDirty = false;
|
|
|
33
35
|
/** True while a save request is in flight. */
|
|
34
36
|
export let saveSaving = false;
|
|
35
37
|
|
|
38
|
+
// The words of the editor in the language of the page: the editor above this one chose it (see `provideEditorLanguage`).
|
|
39
|
+
const { t } = useEditorLanguage();
|
|
40
|
+
|
|
36
41
|
// Loading is currently local initialization; preserve the loading/error presentation.
|
|
37
42
|
let loading = true;
|
|
38
43
|
let wrapperElement = null;
|
|
@@ -52,9 +57,11 @@ function showToast(type: 'success' | 'error', message: string, options = {}) {
|
|
|
52
57
|
...options,
|
|
53
58
|
duration: 5000,
|
|
54
59
|
unstyled: true,
|
|
60
|
+
// The toast puts itself in place with its own classes below (fixed, at the end of the line), so the corner that the
|
|
61
|
+
// toaster knows is only a name it needs.
|
|
55
62
|
position: 'bottom-right',
|
|
56
63
|
classes: {
|
|
57
|
-
toast: 'embed-editor-toast flex items-center gap-3 fixed bottom-5
|
|
64
|
+
toast: 'embed-editor-toast flex items-center gap-3 fixed bottom-5 end-5',
|
|
58
65
|
title: 'embed-editor-toast-title',
|
|
59
66
|
description: 'embed-editor-toast-description',
|
|
60
67
|
closeButton: 'embed-editor-toast-close-button'
|
|
@@ -99,7 +106,7 @@ export function getPosition() {
|
|
|
99
106
|
{showSaveButton}
|
|
100
107
|
{saveDirty}
|
|
101
108
|
{saveSaving}
|
|
102
|
-
title=
|
|
109
|
+
title={$t('editor.embed.title')}
|
|
103
110
|
dragHandleClass="text-forest-green"
|
|
104
111
|
headerClass={!loading && embedCode ? 'bg-grey2' : ''}
|
|
105
112
|
showSchemaError={false}
|
|
@@ -108,28 +115,32 @@ export function getPosition() {
|
|
|
108
115
|
>
|
|
109
116
|
{#snippet headerContent()}
|
|
110
117
|
{#if loading}
|
|
111
|
-
<div class="embed-editor-loading subtext text-grey5 flex items-center justify-center h-full">
|
|
118
|
+
<div class="embed-editor-loading subtext text-grey5 flex items-center justify-center h-full">{$t('editor.embed.loading')}</div>
|
|
112
119
|
{:else if !embedCode}
|
|
113
120
|
<div class="embed-editor-error flex flex-col items-center justify-center h-full">
|
|
114
|
-
<div class="embed-editor-error-title text-error text-lg font-medium">
|
|
115
|
-
<div class="embed-editor-error-code text-grey5 subtext mt-1">
|
|
121
|
+
<div class="embed-editor-error-title text-error text-lg font-medium">{$t('editor.embed.noCode')}</div>
|
|
122
|
+
<div class="embed-editor-error-code text-grey5 subtext mt-1">{$t('editor.failure.errorCode', { code: 'EMBED_CODE_NOT_FOUND' })}</div>
|
|
116
123
|
</div>
|
|
117
124
|
{:else}
|
|
118
125
|
<!-- The only additional panel: code display, help link and clipboard control. -->
|
|
119
|
-
<section class="embed-editor-code-header header-hover-area relative shrink-0 bg-grey2" aria-label=
|
|
126
|
+
<section class="embed-editor-code-header header-hover-area relative shrink-0 bg-grey2" aria-label={$t('editor.embed.headerArea')}>
|
|
120
127
|
<CopyableHeader
|
|
121
|
-
headerText={embedHeaderText}
|
|
128
|
+
headerText={embedHeaderText ?? $t('editor.embed.codeHeader')}
|
|
122
129
|
content={embedCode}
|
|
123
|
-
helpText=
|
|
130
|
+
helpText={$t('editor.embed.readMore')}
|
|
124
131
|
helpUrl="/embed"
|
|
125
132
|
showStandaloneCopyButton={true}
|
|
126
|
-
standaloneCopyButtonText=
|
|
133
|
+
standaloneCopyButtonText={$t('editor.embed.copy')}
|
|
134
|
+
copiedTitle={$t('editor.embed.copied')}
|
|
135
|
+
copiedDescription={$t('editor.embed.copiedDone')}
|
|
136
|
+
copyFailedTitle={$t('editor.embed.copyFailed')}
|
|
137
|
+
copyFailedDescription={$t('editor.embed.copyFailedHint')}
|
|
127
138
|
showButtonText={false}
|
|
128
139
|
buttonClass="bg-grey2 text-grey7 hover:bg-white rounded-small focus:outline-none focus-visible:outline-none focus:shadow-none focus-visible:shadow-none"
|
|
129
|
-
style="border-
|
|
140
|
+
style="border-start-start-radius: var(--radius-large); border-start-end-radius: var(--radius-large);"
|
|
130
141
|
on:copy={() => {
|
|
131
|
-
showToast('success', '
|
|
132
|
-
description: '
|
|
142
|
+
showToast('success', $t('editor.embed.copied'), {
|
|
143
|
+
description: $t('editor.embed.copiedHint'),
|
|
133
144
|
icon: OK
|
|
134
145
|
});
|
|
135
146
|
}}
|
|
@@ -161,16 +172,16 @@ export function getPosition() {
|
|
|
161
172
|
border-radius: var(--radius-medium) !important;
|
|
162
173
|
}
|
|
163
174
|
:global(.embed-editor-container .accordion-item[data-position="first"]) {
|
|
164
|
-
border-
|
|
165
|
-
border-
|
|
166
|
-
border-
|
|
167
|
-
border-
|
|
175
|
+
border-start-start-radius: var(--radius-medium) !important;
|
|
176
|
+
border-start-end-radius: var(--radius-medium) !important;
|
|
177
|
+
border-end-start-radius: 0 !important;
|
|
178
|
+
border-end-end-radius: 0 !important;
|
|
168
179
|
}
|
|
169
180
|
:global(.embed-editor-container .accordion-item[data-position="last"]) {
|
|
170
|
-
border-
|
|
171
|
-
border-
|
|
172
|
-
border-
|
|
173
|
-
border-
|
|
181
|
+
border-start-start-radius: 0 !important;
|
|
182
|
+
border-start-end-radius: 0 !important;
|
|
183
|
+
border-end-start-radius: var(--radius-medium) !important;
|
|
184
|
+
border-end-end-radius: var(--radius-medium) !important;
|
|
174
185
|
margin-bottom: 0 !important;
|
|
175
186
|
}
|
|
176
187
|
:global(.embed-editor-container .accordion-trigger) {
|
|
@@ -224,7 +235,7 @@ export function getPosition() {
|
|
|
224
235
|
:global(.embed-editor-toast) {
|
|
225
236
|
position: fixed !important;
|
|
226
237
|
bottom: 20px !important;
|
|
227
|
-
|
|
238
|
+
inset-inline-end: 20px !important;
|
|
228
239
|
top: auto !important;
|
|
229
240
|
display: flex !important;
|
|
230
241
|
align-items: center !important;
|
|
@@ -14,7 +14,7 @@ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> =
|
|
|
14
14
|
declare const EmbedEditor: $$__sveltets_2_IsomorphicComponent<{
|
|
15
15
|
/** Component configuration — existing public props and methods are preserved. */ class?: string;
|
|
16
16
|
style?: string;
|
|
17
|
-
embedHeaderText?: string;
|
|
17
|
+
/** The title of the code box. Without one, the editor's own word in the language of the page. */ embedHeaderText?: string | undefined;
|
|
18
18
|
embedCode?: string;
|
|
19
19
|
height?: number;
|
|
20
20
|
embedSchema: any;
|