@widgetic/editor 4.0.10 → 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 +242 -0
- package/dist/components/WidgetPreview.svelte +123 -86
- package/dist/components/WidgetPreview.svelte.d.ts +8 -0
- package/dist/components/color-select/ColorSelect.svelte +4 -4
- package/dist/components/editors/CompositionEditorApp.svelte +562 -0
- package/dist/components/editors/CompositionEditorApp.svelte.d.ts +95 -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 +267 -850
- package/dist/components/editors/PropsEditor.svelte.d.ts +10 -3
- package/dist/components/ic/AngleInputController.svelte +1 -1
- package/dist/components/ic/BrowserInputController.svelte +58 -31
- package/dist/components/ic/ColorPickerInputController.svelte +55 -21
- package/dist/components/ic/DateFieldInputController.svelte +34 -14
- package/dist/components/ic/DatePickerInputController.svelte +37 -21
- package/dist/components/ic/DropdownInputController.svelte +21 -9
- package/dist/components/ic/DropdownInputController.svelte.d.ts +1 -1
- package/dist/components/ic/FixedPositionInputController.svelte +12 -6
- package/dist/components/ic/FontInputController.svelte +100 -76
- package/dist/components/ic/InputControllerHeader.svelte +16 -9
- package/dist/components/ic/NumberControls.svelte +4 -4
- package/dist/components/ic/NumberInputController.svelte +6 -4
- package/dist/components/ic/PositionInputController.svelte +23 -15
- package/dist/components/ic/RangeCalendarInputController.svelte +36 -20
- package/dist/components/ic/RoundedCornersInputController.svelte +39 -26
- 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 +79 -51
- package/dist/components/ic/TextAreaPreviewInputController.svelte +27 -72
- package/dist/components/ic/TextInputController.svelte +17 -1
- package/dist/components/ic/TimeInputController.svelte +11 -4
- package/dist/components/ic/VectorInputController.svelte +101 -70
- package/dist/components/ic/shared/ItemGrid.svelte +12 -4
- package/dist/components/ic/shared/RecentItemsSection.svelte +16 -11
- package/dist/components/ic/shared/RecentItemsSection.svelte.d.ts +1 -1
- package/dist/composition/compositionApi.d.ts +95 -0
- package/dist/composition/compositionApi.js +289 -0
- package/dist/composition/compositionEditorController.d.ts +263 -0
- package/dist/composition/compositionEditorController.js +746 -0
- package/dist/composition/compositionHelpers.d.ts +74 -0
- package/dist/composition/compositionHelpers.js +405 -0
- 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 +4 -0
- package/dist/index.js +8 -0
- package/dist/mediaLibraryContext.d.ts +10 -0
- package/dist/mediaLibraryContext.js +30 -0
- package/dist/utils/FontManager.d.ts +21 -5
- package/dist/utils/FontManager.js +62 -67
- package/dist/utils/VectorManager.d.ts +0 -1
- package/dist/utils/VectorManager.js +10 -12
- package/dist/utils/dockPlacement.d.ts +12 -0
- package/dist/utils/dockPlacement.js +13 -0
- package/dist/utils/editorStorage.d.ts +23 -0
- package/dist/utils/editorStorage.js +95 -0
- package/dist/utils/fieldDirection.d.ts +13 -0
- package/dist/utils/fieldDirection.js +25 -0
- package/dist/utils/fontUtils.js +5 -3
- package/dist/utils/htmlSafety.d.ts +21 -0
- package/dist/utils/htmlSafety.js +38 -0
- package/dist/utils/itemReorder.d.ts +90 -0
- package/dist/utils/itemReorder.js +354 -0
- package/dist/utils/recentColors.js +4 -2
- package/dist/utils/richTextPreview.d.ts +38 -0
- package/dist/utils/richTextPreview.js +207 -0
- package/dist/utils/scrollActivity.d.ts +14 -0
- package/dist/utils/scrollActivity.js +63 -0
- package/dist/utils/shadowDom.d.ts +67 -0
- package/dist/utils/shadowDom.js +211 -0
- package/dist/utils/vectorUtils.js +5 -3
- package/dist/utils/visibilityCondition.d.ts +40 -0
- package/dist/utils/visibilityCondition.js +535 -0
- package/package.json +7 -6
|
@@ -37,6 +37,13 @@
|
|
|
37
37
|
<script lang="ts">
|
|
38
38
|
// Svelte imports
|
|
39
39
|
import { onMount, onDestroy } from 'svelte';
|
|
40
|
+
import { listenForScroll } from '../../utils/shadowDom';
|
|
41
|
+
import { useEditorLanguage } from '../../i18n/language';
|
|
42
|
+
import type { EditorMessageKey } from '../../i18n/messages';
|
|
43
|
+
import type { Translate } from '@widgetic/design-system/i18n';
|
|
44
|
+
|
|
45
|
+
// The words of the editor in the language of the page, and the language itself (how a month and a date are written).
|
|
46
|
+
const { t, locale } = useEditorLanguage();
|
|
40
47
|
|
|
41
48
|
// Shadcn UI Components
|
|
42
49
|
import { Button, Select } from '@widgetic/design-system/components';
|
|
@@ -65,12 +72,12 @@
|
|
|
65
72
|
let placeholder = today(getLocalTimeZone());
|
|
66
73
|
let currentValue: CalendarDate | undefined;
|
|
67
74
|
|
|
68
|
-
// Month and year options setup
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
75
|
+
// Month and year options setup: the names of the months are written by the language of the page
|
|
76
|
+
$: monthFmt = new DateFormatter($locale, { month: 'long' });
|
|
77
|
+
$: monthOptions = Array.from({ length: 12 }, (_, monthIndex) => ({
|
|
78
|
+
value: String(monthIndex + 1),
|
|
79
|
+
label: monthFmt.format(new Date(2021, monthIndex, 1))
|
|
80
|
+
}));
|
|
74
81
|
|
|
75
82
|
const yearOptions = Array.from({ length: 100 }, (_, i) => {
|
|
76
83
|
const year = String(new Date().getFullYear() - i);
|
|
@@ -140,15 +147,15 @@
|
|
|
140
147
|
* @param date - The date to format
|
|
141
148
|
* @returns Formatted date string
|
|
142
149
|
*/
|
|
143
|
-
function formatDate(date: CalendarDate | undefined): string {
|
|
144
|
-
if (!date || !(date instanceof CalendarDate)) return '
|
|
150
|
+
function formatDate(date: CalendarDate | undefined, languageTag: string, translate: Translate<EditorMessageKey>): string {
|
|
151
|
+
if (!date || !(date instanceof CalendarDate)) return translate('editor.date.pick');
|
|
145
152
|
try {
|
|
146
153
|
// Convert to JavaScript Date for localized formatting
|
|
147
154
|
const jsDate = new Date(date.year, date.month - 1, date.day);
|
|
148
|
-
return jsDate.toLocaleDateString(
|
|
155
|
+
return jsDate.toLocaleDateString(languageTag, { dateStyle: 'long' });
|
|
149
156
|
} catch (error) {
|
|
150
157
|
console.error('Error formatting date:', error);
|
|
151
|
-
return '
|
|
158
|
+
return translate('editor.date.pick');
|
|
152
159
|
}
|
|
153
160
|
}
|
|
154
161
|
|
|
@@ -209,25 +216,30 @@
|
|
|
209
216
|
}
|
|
210
217
|
}
|
|
211
218
|
|
|
212
|
-
//
|
|
219
|
+
// The control's own element, which says which tree (the page or a module's shadow root) to listen for scrolling in
|
|
220
|
+
let controllerElement: HTMLDivElement | undefined;
|
|
221
|
+
let stopListeningForScroll: () => void = () => {};
|
|
222
|
+
|
|
223
|
+
// Setup scroll event listener on mount (the page and, inside a module, the module's own panels: a scroll never
|
|
224
|
+
// leaves a shadow root, so a listener on the window alone does not hear about those)
|
|
213
225
|
onMount(() => {
|
|
214
|
-
|
|
226
|
+
stopListeningForScroll = listenForScroll(controllerElement, handleScroll);
|
|
215
227
|
});
|
|
216
228
|
|
|
217
229
|
// Cleanup scroll event listener on destroy
|
|
218
230
|
onDestroy(() => {
|
|
219
|
-
|
|
231
|
+
stopListeningForScroll();
|
|
220
232
|
});
|
|
221
233
|
</script>
|
|
222
234
|
|
|
223
235
|
<!-- Date Picker Container -->
|
|
224
|
-
<div class="flex flex-col gap-2 widgetic-colors">
|
|
236
|
+
<div bind:this={controllerElement} class="flex flex-col gap-2 widgetic-colors">
|
|
225
237
|
<div class="flex items-center w-full relative">
|
|
226
238
|
<div class="flex-1 min-w-0">
|
|
227
239
|
<InputControllerHeader {label} />
|
|
228
240
|
</div>
|
|
229
241
|
|
|
230
|
-
<div class="absolute
|
|
242
|
+
<div class="absolute end-0">
|
|
231
243
|
<div
|
|
232
244
|
class="h-[48px] w-[185px] rounded-large border border-grey2 flex items-center bg-grey1 transition-colors duration-200 hover:border-forest-green"
|
|
233
245
|
on:focusin={onFocus}
|
|
@@ -238,9 +250,9 @@
|
|
|
238
250
|
<Button
|
|
239
251
|
id="date-picker"
|
|
240
252
|
variant="ghost"
|
|
241
|
-
class="w-full h-full justify-between text-
|
|
253
|
+
class="w-full h-full justify-between text-start border-0 bg-transparent hover:bg-transparent focus:bg-transparent p-0 group"
|
|
242
254
|
>
|
|
243
|
-
<span class="subtext text-grey7 {!currentValue ? 'text-grey3' : ''}">{formatDate(currentValue)}</span>
|
|
255
|
+
<span class="subtext text-grey7 {!currentValue ? 'text-grey3' : ''}">{formatDate(currentValue, $locale, $t)}</span>
|
|
244
256
|
<IconCalendar class="w-[20px] h-[20px] text-grey5 transition-colors duration-200 group-hover:text-grey7" />
|
|
245
257
|
</Button>
|
|
246
258
|
</div>
|
|
@@ -274,8 +286,8 @@
|
|
|
274
286
|
}
|
|
275
287
|
}}
|
|
276
288
|
>
|
|
277
|
-
<Select.Trigger aria-label=
|
|
278
|
-
<span class="text-sm">{defaultMonth?.label ||
|
|
289
|
+
<Select.Trigger aria-label={$t('editor.date.selectMonth')} class="w-[60%] month-year-dropdown-content">
|
|
290
|
+
<span class="text-sm">{defaultMonth?.label || $t('editor.date.selectMonth')}</span>
|
|
279
291
|
</Select.Trigger>
|
|
280
292
|
<Select.Content class="max-h-[200px] overflow-y-auto month-year-dropdown-content">
|
|
281
293
|
{#each monthOptions as { value, label }}
|
|
@@ -309,8 +321,8 @@
|
|
|
309
321
|
}
|
|
310
322
|
}}
|
|
311
323
|
>
|
|
312
|
-
<Select.Trigger aria-label=
|
|
313
|
-
<span class="text-sm">{defaultYear?.label ||
|
|
324
|
+
<Select.Trigger aria-label={$t('editor.date.selectYear')} class="w-[40%] month-year-dropdown-content">
|
|
325
|
+
<span class="text-sm">{defaultYear?.label || $t('editor.date.selectYear')}</span>
|
|
314
326
|
</Select.Trigger>
|
|
315
327
|
<Select.Content class="max-h-[200px] overflow-y-auto month-year-dropdown-content">
|
|
316
328
|
{#each yearOptions as { value, label }}
|
|
@@ -324,6 +336,10 @@
|
|
|
324
336
|
<div class="calendar-no-header">
|
|
325
337
|
<Calendar
|
|
326
338
|
mode="single"
|
|
339
|
+
locale={$locale}
|
|
340
|
+
calendarLabel={$t('editor.date.calendarLabel')}
|
|
341
|
+
previousLabel={$t('editor.date.previousMonth')}
|
|
342
|
+
nextLabel={$t('editor.date.nextMonth')}
|
|
327
343
|
onValueChange={(date: DateValue | undefined) => {
|
|
328
344
|
// console.log('📅 [DatePicker] Calendar onValueChange:', { date, isCalendarDate: date instanceof CalendarDate });
|
|
329
345
|
if (date instanceof CalendarDate) {
|
|
@@ -31,6 +31,11 @@
|
|
|
31
31
|
* Required for component setup and cleanup
|
|
32
32
|
*/
|
|
33
33
|
import { onMount, onDestroy } from 'svelte';
|
|
34
|
+
import { listenForScroll } from '../../utils/shadowDom';
|
|
35
|
+
import { useEditorLanguage } from '../../i18n/language';
|
|
36
|
+
|
|
37
|
+
// The words of the editor in the language of the page.
|
|
38
|
+
const { t } = useEditorLanguage();
|
|
34
39
|
|
|
35
40
|
// Local Components imports
|
|
36
41
|
import { InputControllerHeader } from './index';
|
|
@@ -49,7 +54,8 @@
|
|
|
49
54
|
* External properties that configure the dropdown's behavior and appearance
|
|
50
55
|
*/
|
|
51
56
|
export let label: DropdownInputControllerProps['label'];
|
|
52
|
-
|
|
57
|
+
/** What the button says while nothing is chosen. Without one, the editor's own word, in the language of the page. */
|
|
58
|
+
export let defaultSelectedLabel: DropdownInputControllerProps['defaultSelectedLabel'] = undefined;
|
|
53
59
|
export let value: DropdownInputControllerProps['value'];
|
|
54
60
|
export let onChange: DropdownInputControllerProps['onChange'];
|
|
55
61
|
export let config: DropdownInputControllerProps['config'] = {};
|
|
@@ -113,13 +119,18 @@
|
|
|
113
119
|
* Lifecycle Hooks
|
|
114
120
|
* Setup and cleanup of scroll event listeners
|
|
115
121
|
*/
|
|
122
|
+
// The control's own element, which says which tree (the page or a module's shadow root) to listen for scrolling in
|
|
123
|
+
// (a scroll never leaves a shadow root, so a listener on the window alone only hears about the page scrolling)
|
|
124
|
+
let controllerElement: HTMLDivElement | undefined;
|
|
125
|
+
let stopListeningForScroll: () => void = () => {};
|
|
126
|
+
|
|
116
127
|
onMount(() => {
|
|
117
128
|
// console.log('DropdownInputController: onMount:', value);
|
|
118
|
-
|
|
129
|
+
stopListeningForScroll = listenForScroll(controllerElement, handleScroll);
|
|
119
130
|
});
|
|
120
131
|
|
|
121
132
|
onDestroy(() => {
|
|
122
|
-
|
|
133
|
+
stopListeningForScroll();
|
|
123
134
|
});
|
|
124
135
|
|
|
125
136
|
/**
|
|
@@ -147,20 +158,21 @@
|
|
|
147
158
|
/**
|
|
148
159
|
* The option label for the current selection. `value` accepts a bare string
|
|
149
160
|
* or an option object; normalize once instead of re-narrowing at each read.
|
|
161
|
+
* A missing selection is the empty string, as the select expects.
|
|
150
162
|
*/
|
|
151
|
-
$: selectedValue = typeof value === 'string' ? value : value?.value;
|
|
163
|
+
$: selectedValue = typeof value === 'string' ? value : (value?.value ?? '');
|
|
152
164
|
$: triggerContent =
|
|
153
|
-
options.find((o) => o.value === selectedValue)?.label ?? defaultSelectedLabel;
|
|
165
|
+
options.find((o) => o.value === selectedValue)?.label ?? defaultSelectedLabel ?? $t('editor.dropdown.select');
|
|
154
166
|
</script>
|
|
155
167
|
|
|
156
168
|
<!-- Dropdown Container -->
|
|
157
|
-
<div class="dropdown-ic flex flex-col gap-2 widgetic-colors">
|
|
169
|
+
<div bind:this={controllerElement} class="dropdown-ic flex flex-col gap-2 widgetic-colors">
|
|
158
170
|
<div class="flex items-center w-full relative">
|
|
159
171
|
<div class="flex-1 min-w-0">
|
|
160
172
|
<InputControllerHeader {label} />
|
|
161
173
|
</div>
|
|
162
174
|
|
|
163
|
-
<div class="absolute
|
|
175
|
+
<div class="absolute end-0">
|
|
164
176
|
<div
|
|
165
177
|
class="dropdown-main-container rounded-large flex items-center transition-colors duration-200 group"
|
|
166
178
|
style="height: 48px; width: 185px; border: 1px solid hsl(var(--grey2)); background: hsl(var(--grey1));"
|
|
@@ -175,10 +187,10 @@
|
|
|
175
187
|
>
|
|
176
188
|
<Select.Trigger
|
|
177
189
|
class="dropdown-ic-trigger h-full w-full border-0 bg-transparent subtext hover:bg-transparent focus:bg-transparent data-[state=open]:bg-transparent"
|
|
178
|
-
style="padding-
|
|
190
|
+
style="padding-inline-start: 16px; padding-inline-end: 16px; color: hsl(var(--grey7));"
|
|
179
191
|
id={controllerId}
|
|
180
192
|
>
|
|
181
|
-
<span class="truncate flex-1 text-
|
|
193
|
+
<span class="truncate flex-1 text-start subtext" style="color: hsl(var(--grey7));">
|
|
182
194
|
{triggerContent}
|
|
183
195
|
</span>
|
|
184
196
|
<IconCaretDownFilled class="dropdown-ic-trigger-icon" style="width: 20px; height: 20px; color: hsl(var(--grey5));"/>
|
|
@@ -39,7 +39,7 @@ declare const DropdownInputController: $$__sveltets_2_IsomorphicComponent<{
|
|
|
39
39
|
* Component Props
|
|
40
40
|
* External properties that configure the dropdown's behavior and appearance
|
|
41
41
|
*/ label: DropdownInputControllerProps["label"];
|
|
42
|
-
defaultSelectedLabel?: DropdownInputControllerProps["defaultSelectedLabel"];
|
|
42
|
+
/** What the button says while nothing is chosen. Without one, the editor's own word, in the language of the page. */ defaultSelectedLabel?: DropdownInputControllerProps["defaultSelectedLabel"];
|
|
43
43
|
value: DropdownInputControllerProps["value"];
|
|
44
44
|
onChange: DropdownInputControllerProps["onChange"];
|
|
45
45
|
config?: DropdownInputControllerProps["config"];
|
|
@@ -40,6 +40,11 @@
|
|
|
40
40
|
<script lang="ts">
|
|
41
41
|
// Svelte imports
|
|
42
42
|
import { onDestroy } from 'svelte';
|
|
43
|
+
import { useEditorLanguage } from '../../i18n/language';
|
|
44
|
+
import { fixedPositionLabel } from '../../i18n/labels';
|
|
45
|
+
|
|
46
|
+
// The words of the editor in the language of the page.
|
|
47
|
+
const { t } = useEditorLanguage();
|
|
43
48
|
|
|
44
49
|
// Import icons from Tabler
|
|
45
50
|
import {
|
|
@@ -259,10 +264,10 @@
|
|
|
259
264
|
|
|
260
265
|
function getCornerRounding(pos: Position): string {
|
|
261
266
|
switch (pos) {
|
|
262
|
-
case 'top-left': return 'rounded-tl-[15px]';
|
|
263
|
-
case 'top-right': return 'rounded-tr-[15px]';
|
|
264
|
-
case 'bottom-left': return 'rounded-bl-[15px]';
|
|
265
|
-
case 'bottom-right': return 'rounded-br-[15px]';
|
|
267
|
+
case 'top-left': return 'rounded-tl-[15px]'; // rtl-ok: the corner of the picture of a screen
|
|
268
|
+
case 'top-right': return 'rounded-tr-[15px]'; // rtl-ok: the corner of the picture of a screen
|
|
269
|
+
case 'bottom-left': return 'rounded-bl-[15px]'; // rtl-ok: the corner of the picture of a screen
|
|
270
|
+
case 'bottom-right': return 'rounded-br-[15px]'; // rtl-ok: the corner of the picture of a screen
|
|
266
271
|
default: return '';
|
|
267
272
|
}
|
|
268
273
|
}
|
|
@@ -270,9 +275,10 @@
|
|
|
270
275
|
|
|
271
276
|
<!-- Container with relative positioning for overlay -->
|
|
272
277
|
<div class="relative widgetic-colors">
|
|
273
|
-
<!-- Grid component -->
|
|
278
|
+
<!-- Grid component: the nine places of a screen, top left to bottom right, are a picture of the screen, so it is a left to right island -->
|
|
274
279
|
<div
|
|
275
280
|
class="fixed-position-grid grid grid-cols-3 gap-[1px] w-fit bg-white rounded-large relative"
|
|
281
|
+
dir="ltr"
|
|
276
282
|
{id}
|
|
277
283
|
>
|
|
278
284
|
{#each positions as position}
|
|
@@ -284,7 +290,7 @@
|
|
|
284
290
|
}"
|
|
285
291
|
on:click={() => handlePositionClick(position)}
|
|
286
292
|
on:focus={onFocus}
|
|
287
|
-
aria-label={
|
|
293
|
+
aria-label={$t('editor.fixedPosition.set', { position: fixedPositionLabel(position, $t) })}
|
|
288
294
|
aria-pressed={position === value}
|
|
289
295
|
>
|
|
290
296
|
<svelte:component
|