@widgetic/editor 4.0.1 → 4.0.3
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/MockWidget.svelte +1 -1
- package/dist/components/WidgetPreview.svelte +36 -52
- package/dist/components/editors/EmbedEditor.svelte +1 -1
- package/dist/components/editors/PropsEditor.svelte +309 -227
- package/dist/components/ic/BrowserInputController.svelte +26 -19
- package/dist/components/ic/CheckboxInputController.svelte +1 -1
- package/dist/components/ic/ColorPickerInputController.svelte +37 -37
- package/dist/components/ic/DatePickerInputController.svelte +6 -6
- package/dist/components/ic/DropdownInputController.svelte +1 -1
- package/dist/components/ic/FontInputController.svelte +225 -116
- package/dist/components/ic/FontInputController.svelte.d.ts +4 -2
- package/dist/components/ic/NumberInputController.svelte +37 -37
- package/dist/components/ic/RadioGroupInputController.svelte +1 -1
- package/dist/components/ic/SliderRangeInputController.svelte +1 -1
- package/dist/components/ic/SwitchInputController.svelte +1 -1
- package/dist/components/ic/TextAreaInputController.svelte +213 -85
- package/dist/components/ic/TextAreaInputController.svelte.d.ts +1 -0
- package/dist/components/ic/TextAreaPreviewInputController.svelte +81 -79
- package/dist/components/ic/VectorInputController.svelte +34 -34
- package/dist/components/ic/shared/CategoryTabs.svelte +1 -0
- package/dist/components/ic/shared/RecentItemsSection.svelte +21 -6
- package/dist/components/ic/shared/RecentItemsSection.svelte.d.ts +1 -0
- package/dist/config.d.ts +6 -0
- package/dist/config.js +19 -7
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/stores/userSession.d.ts +1 -1
- package/dist/stores/userSession.js +17 -2
- package/dist/utils/FontManager.d.ts +3 -1
- package/dist/utils/FontManager.js +95 -103
- package/dist/utils/VectorManager.d.ts +3 -1
- package/dist/utils/VectorManager.js +30 -70
- package/dist/utils/colorTransparency.js +3 -3
- package/dist/utils/fontUtils.js +1 -1
- package/dist/utils/passiveEvents.d.ts +5 -0
- package/dist/utils/passiveEvents.js +9 -18
- package/dist/utils/recentColors.js +15 -15
- package/dist/utils/vectorUtils.js +1 -1
- package/package.json +1 -1
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
import { IconArrowsDiagonal, IconArrowsMaximize, IconX, IconBrush, IconBold, IconItalic, IconUnderline, IconLink } from '@widgetic/design-system/icons';
|
|
2
|
+
import { Portal } from '@widgetic/design-system/components';
|
|
3
|
+
import { IconArrowsDiagonal } from '@widgetic/design-system/icons';
|
|
5
4
|
import { onMount, onDestroy } from 'svelte';
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
import { InputControllerHeader, TextAreaInputController } from './index';
|
|
6
|
+
import { TextAreaInputController } from './index';
|
|
9
7
|
import type { InputControllerConfig } from './index';
|
|
10
8
|
|
|
11
9
|
/**
|
|
@@ -50,8 +48,15 @@
|
|
|
50
48
|
function createPreviewText(text: string) {
|
|
51
49
|
if (!text) return '';
|
|
52
50
|
|
|
51
|
+
let html = text;
|
|
52
|
+
if (!html.includes('<') && html.includes('<')) {
|
|
53
|
+
const decoded = document.createElement('textarea');
|
|
54
|
+
decoded.innerHTML = html;
|
|
55
|
+
html = decoded.value;
|
|
56
|
+
}
|
|
57
|
+
|
|
53
58
|
const parser = new DOMParser();
|
|
54
|
-
const doc = parser.parseFromString(
|
|
59
|
+
const doc = parser.parseFromString(html, 'text/html');
|
|
55
60
|
|
|
56
61
|
function processNode(node: Node): string {
|
|
57
62
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
@@ -60,63 +65,63 @@
|
|
|
60
65
|
|
|
61
66
|
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
62
67
|
const element = node as Element;
|
|
63
|
-
|
|
68
|
+
let tag = element.tagName.toLowerCase();
|
|
64
69
|
const attributes: Record<string, string> = {};
|
|
70
|
+
const children = Array.from(node.childNodes)
|
|
71
|
+
.map(child => processNode(child))
|
|
72
|
+
.join('');
|
|
73
|
+
|
|
74
|
+
// Flatten block wrappers so marks render inside the compact clamp box
|
|
75
|
+
if (tag === 'p' || tag === 'div' || tag === 'br') {
|
|
76
|
+
return tag === 'br' ? ' ' : `${children} `;
|
|
77
|
+
}
|
|
65
78
|
|
|
66
|
-
// Preserve all style attributes
|
|
67
79
|
const style = element.getAttribute('style');
|
|
68
80
|
if (style) {
|
|
69
|
-
// Extract color value from style
|
|
70
81
|
const colorMatch = style.match(/color:\s*([^;]+)/);
|
|
71
82
|
if (colorMatch) {
|
|
72
|
-
|
|
73
|
-
// Set the color as a CSS variable
|
|
74
|
-
attributes.style = `--color: ${color}; ${style}`;
|
|
83
|
+
attributes.style = `--color: ${colorMatch[1]}; ${style}`;
|
|
75
84
|
} else {
|
|
76
85
|
attributes.style = style;
|
|
77
86
|
}
|
|
78
87
|
}
|
|
79
88
|
|
|
80
|
-
// Preserve data-text-style attribute
|
|
81
89
|
const textStyle = element.getAttribute('data-text-style');
|
|
82
90
|
if (textStyle) {
|
|
83
91
|
attributes['data-text-style'] = textStyle;
|
|
84
|
-
// Add preserve-color class
|
|
85
92
|
attributes.class = (attributes.class || '') + ' preserve-color';
|
|
86
93
|
}
|
|
87
94
|
|
|
88
|
-
// Preserve heading classes
|
|
89
95
|
if (tag.match(/^h[1-4]$/)) {
|
|
96
|
+
tag = 'span';
|
|
90
97
|
attributes.class = (attributes.class || '') + ' tiptap-heading';
|
|
91
98
|
}
|
|
92
99
|
|
|
93
|
-
// Build start tag with attributes
|
|
94
100
|
let startTag = `<${tag}`;
|
|
95
|
-
for (const [key,
|
|
96
|
-
startTag += ` ${key}="${
|
|
101
|
+
for (const [key, attrValue] of Object.entries(attributes)) {
|
|
102
|
+
startTag += ` ${key}="${attrValue.trim()}"`;
|
|
97
103
|
}
|
|
98
104
|
startTag += '>';
|
|
99
105
|
|
|
100
|
-
// Process child nodes
|
|
101
|
-
const children = Array.from(node.childNodes)
|
|
102
|
-
.map(child => processNode(child))
|
|
103
|
-
.join('');
|
|
104
|
-
|
|
105
106
|
return `${startTag}${children}</${tag}>`;
|
|
106
107
|
}
|
|
107
108
|
|
|
108
109
|
return '';
|
|
109
110
|
}
|
|
110
111
|
|
|
111
|
-
|
|
112
|
+
return Array.from(doc.body.childNodes)
|
|
112
113
|
.map(node => processNode(node))
|
|
113
|
-
.join('')
|
|
114
|
+
.join('')
|
|
115
|
+
.trim();
|
|
116
|
+
}
|
|
114
117
|
|
|
115
|
-
|
|
118
|
+
function handleFullEditorChange(html: string) {
|
|
119
|
+
value = html;
|
|
120
|
+
if (typeof onChange === 'function') onChange(html);
|
|
116
121
|
}
|
|
117
122
|
|
|
118
123
|
function handleClick() {
|
|
119
|
-
console.log('Opening text area in portal');
|
|
124
|
+
// console.log('Opening text area in portal');
|
|
120
125
|
isShowingTextArea = !isShowingTextArea;
|
|
121
126
|
}
|
|
122
127
|
|
|
@@ -139,6 +144,10 @@
|
|
|
139
144
|
}
|
|
140
145
|
}
|
|
141
146
|
|
|
147
|
+
$: if (value) {
|
|
148
|
+
// console.log('[TextAreaPreview] compact preview html', value.slice(0, 180));
|
|
149
|
+
}
|
|
150
|
+
|
|
142
151
|
function handlePortalMouseEnter() {
|
|
143
152
|
// console.log('Portal mouse entered');
|
|
144
153
|
isPortalHovered = true;
|
|
@@ -211,42 +220,31 @@
|
|
|
211
220
|
}
|
|
212
221
|
</script>
|
|
213
222
|
|
|
214
|
-
<div class="text-area-preview-input-controller
|
|
215
|
-
<div class="header-container flex-1 min-w-0">
|
|
216
|
-
<InputControllerHeader {label} />
|
|
217
|
-
</div>
|
|
218
|
-
|
|
223
|
+
<div class="text-area-preview-input-controller w-full min-w-0 overflow-hidden widgetic-colors">
|
|
219
224
|
<div
|
|
220
|
-
class="text-area-preview-main-container w-
|
|
225
|
+
class="text-area-preview-main-container w-full min-w-0 overflow-hidden"
|
|
221
226
|
>
|
|
222
227
|
<div
|
|
223
|
-
class="h-[92px] w-full border border-grey2
|
|
228
|
+
class="textarea-ic-preview-box relative h-[92px] w-full min-w-0 border border-grey2 bg-grey1 transition-colors duration-200 hover:border-forest-green cursor-pointer group overflow-hidden"
|
|
224
229
|
style="border-radius: var(--radius-large);"
|
|
225
230
|
on:click={handleClick}
|
|
226
231
|
on:keydown={(e) => e.key === 'Enter' && handleClick()}
|
|
227
232
|
role="button"
|
|
228
233
|
tabindex="0"
|
|
229
234
|
>
|
|
230
|
-
<div class="
|
|
235
|
+
<div class="textarea-ic-preview-copy min-w-0 overflow-hidden pr-10 pt-[13px] pb-4 pl-4">
|
|
231
236
|
<div
|
|
232
|
-
class="
|
|
237
|
+
class="textarea-ic-preview-html break-words text-grey7 text-sm leading-5"
|
|
238
|
+
class:text-grey3={isShowingPlaceholder}
|
|
233
239
|
>
|
|
234
|
-
|
|
235
|
-
<div
|
|
236
|
-
class="subtext line-clamp-3 break-words text-ellipsis prose-sm w-[129px] text-grey7"
|
|
237
|
-
class:text-grey3={isShowingPlaceholder}
|
|
238
|
-
style="display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden;"
|
|
239
|
-
>
|
|
240
|
-
{@html previewText}
|
|
241
|
-
</div>
|
|
242
|
-
</div>
|
|
243
|
-
<div class="absolute top-[14px] right-[12px]">
|
|
244
|
-
<IconArrowsDiagonal
|
|
245
|
-
class="w-5 h-5 text-grey5 group-hover:text-grey7 transition-colors duration-200"
|
|
246
|
-
/>
|
|
247
|
-
</div>
|
|
240
|
+
{@html previewText}
|
|
248
241
|
</div>
|
|
249
242
|
</div>
|
|
243
|
+
<div class="textarea-ic-expand-icon absolute top-[14px] right-[12px]">
|
|
244
|
+
<IconArrowsDiagonal
|
|
245
|
+
class="w-5 h-5 text-grey5 group-hover:text-grey7 transition-colors duration-200"
|
|
246
|
+
/>
|
|
247
|
+
</div>
|
|
250
248
|
</div>
|
|
251
249
|
</div>
|
|
252
250
|
|
|
@@ -280,24 +278,14 @@
|
|
|
280
278
|
style="border-radius: var(--radius-large);"
|
|
281
279
|
></div>
|
|
282
280
|
|
|
283
|
-
<Button
|
|
284
|
-
variant="ghost"
|
|
285
|
-
class="absolute z-[999] p-0 hover:bg-transparent h-[32px] w-[32px] top-[10px] right-[10px]"
|
|
286
|
-
onclick={handleClose}
|
|
287
|
-
>
|
|
288
|
-
<IconX
|
|
289
|
-
class="w-[24px] h-[24px] text-grey5 hover:text-grey7 transition-colors duration-200"
|
|
290
|
-
style="min-width: 24px; min-height: 24px;"
|
|
291
|
-
/>
|
|
292
|
-
</Button>
|
|
293
|
-
|
|
294
281
|
<TextAreaInputController
|
|
295
282
|
class="text-area w-full h-full transition-colors duration-200 {isPortalHovered ? 'border-solid !border-forest-green' : ''}"
|
|
296
283
|
label={label}
|
|
297
|
-
value
|
|
298
|
-
onChange={
|
|
284
|
+
bind:value
|
|
285
|
+
onChange={handleFullEditorChange}
|
|
299
286
|
config={config}
|
|
300
287
|
description={description}
|
|
288
|
+
onClose={handleClose}
|
|
301
289
|
/>
|
|
302
290
|
</div>
|
|
303
291
|
</Portal>
|
|
@@ -318,7 +306,7 @@
|
|
|
318
306
|
|
|
319
307
|
|
|
320
308
|
/* Heading styles matching tiptap editor */
|
|
321
|
-
:global(.
|
|
309
|
+
:global(.textarea-ic-preview-html h1.tiptap-heading) {
|
|
322
310
|
font-size: 2em !important;
|
|
323
311
|
font-weight: 600 !important;
|
|
324
312
|
line-height: 1.2 !important;
|
|
@@ -327,7 +315,7 @@
|
|
|
327
315
|
color: inherit !important;
|
|
328
316
|
}
|
|
329
317
|
|
|
330
|
-
:global(.
|
|
318
|
+
:global(.textarea-ic-preview-html h2.tiptap-heading) {
|
|
331
319
|
font-size: 1.5em !important;
|
|
332
320
|
font-weight: 600 !important;
|
|
333
321
|
line-height: 1.3 !important;
|
|
@@ -336,7 +324,7 @@
|
|
|
336
324
|
color: inherit !important;
|
|
337
325
|
}
|
|
338
326
|
|
|
339
|
-
:global(.
|
|
327
|
+
:global(.textarea-ic-preview-html h3.tiptap-heading) {
|
|
340
328
|
font-size: 1.17em !important;
|
|
341
329
|
font-weight: 600 !important;
|
|
342
330
|
line-height: 1.3 !important;
|
|
@@ -345,7 +333,7 @@
|
|
|
345
333
|
color: inherit !important;
|
|
346
334
|
}
|
|
347
335
|
|
|
348
|
-
:global(.
|
|
336
|
+
:global(.textarea-ic-preview-html h4.tiptap-heading) {
|
|
349
337
|
font-size: 1em !important;
|
|
350
338
|
font-weight: 600 !important;
|
|
351
339
|
line-height: 1.4 !important;
|
|
@@ -354,36 +342,50 @@
|
|
|
354
342
|
color: inherit !important;
|
|
355
343
|
}
|
|
356
344
|
|
|
345
|
+
:global(.textarea-ic-preview-html) {
|
|
346
|
+
display: -webkit-box;
|
|
347
|
+
-webkit-box-orient: vertical;
|
|
348
|
+
-webkit-line-clamp: 3;
|
|
349
|
+
line-clamp: 3;
|
|
350
|
+
overflow: hidden;
|
|
351
|
+
}
|
|
352
|
+
|
|
357
353
|
/* Color preservation */
|
|
358
|
-
:global(.
|
|
354
|
+
:global(.textarea-ic-preview-html [style*="color"]) {
|
|
359
355
|
color: var(--color) !important;
|
|
360
356
|
}
|
|
361
357
|
|
|
362
|
-
/* Text formatting */
|
|
363
|
-
:global(.
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
358
|
+
/* Text formatting — {@html} children need :global; include b/i as well as strong/em/u */
|
|
359
|
+
:global(.textarea-ic-preview-html :is(strong, b, [style*="font-weight"])) {
|
|
360
|
+
font-weight: 700 !important;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
:global(.textarea-ic-preview-html :is(em, i)) {
|
|
364
|
+
font-style: italic !important;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
:global(.textarea-ic-preview-html :is(u, [style*="text-decoration: underline"])) {
|
|
368
|
+
text-decoration: underline !important;
|
|
367
369
|
}
|
|
368
370
|
|
|
369
|
-
:global(.
|
|
370
|
-
:global(.
|
|
371
|
-
:global(.
|
|
371
|
+
:global(.textarea-ic-preview-html strong[style*="color"]),
|
|
372
|
+
:global(.textarea-ic-preview-html em[style*="color"]),
|
|
373
|
+
:global(.textarea-ic-preview-html u[style*="color"]) {
|
|
372
374
|
color: var(--color) !important;
|
|
373
375
|
}
|
|
374
376
|
|
|
375
377
|
/* Add specific color inheritance for data-text-style */
|
|
376
|
-
:global(.
|
|
378
|
+
:global(.textarea-ic-preview-html [data-text-style*="color"]) {
|
|
377
379
|
color: var(--color) !important;
|
|
378
380
|
}
|
|
379
381
|
|
|
380
382
|
/* Ensure all text elements can inherit colors */
|
|
381
|
-
:global(.
|
|
383
|
+
:global(.textarea-ic-preview-html *) {
|
|
382
384
|
color: inherit;
|
|
383
385
|
}
|
|
384
386
|
|
|
385
387
|
/* Ensure paragraphs have no margins */
|
|
386
|
-
:global(.
|
|
388
|
+
:global(.textarea-ic-preview-html p) {
|
|
387
389
|
margin-top: 0 !important;
|
|
388
390
|
margin-bottom: 0 !important;
|
|
389
391
|
}
|
|
@@ -329,7 +329,7 @@
|
|
|
329
329
|
const testImg = new Image();
|
|
330
330
|
testImg.onload = () => {
|
|
331
331
|
// Vector loads successfully
|
|
332
|
-
console.log(`✅ [VectorInput] Current vector loads successfully: ${value.name}`);
|
|
332
|
+
// console.log(`✅ [VectorInput] Current vector loads successfully: ${value.name}`);
|
|
333
333
|
};
|
|
334
334
|
testImg.onerror = () => {
|
|
335
335
|
// Mark as error if it fails to load
|
|
@@ -420,13 +420,13 @@
|
|
|
420
420
|
|
|
421
421
|
// Preload the vectors to detect missing files early
|
|
422
422
|
if (filteredVectors.length > 0) {
|
|
423
|
-
console.log(`🔍 [VectorInput] Preloading ${filteredVectors.length} vectors to detect missing files...`);
|
|
423
|
+
// console.log(`🔍 [VectorInput] Preloading ${filteredVectors.length} vectors to detect missing files...`);
|
|
424
424
|
preloadVectors(filteredVectors);
|
|
425
425
|
}
|
|
426
426
|
|
|
427
427
|
// Also preload recent vectors
|
|
428
428
|
if (recentVectors.length > 0) {
|
|
429
|
-
console.log(`🔍 [VectorInput] Preloading ${recentVectors.length} recent vectors...`);
|
|
429
|
+
// console.log(`🔍 [VectorInput] Preloading ${recentVectors.length} recent vectors...`);
|
|
430
430
|
preloadVectors(recentVectors);
|
|
431
431
|
}
|
|
432
432
|
|
|
@@ -897,12 +897,12 @@
|
|
|
897
897
|
}
|
|
898
898
|
}, 0);
|
|
899
899
|
|
|
900
|
-
console.log('📝 [VectorSearch] Loaded next batch:', {
|
|
901
|
-
batchSize: nextBatch.length,
|
|
902
|
-
totalDisplayed: filteredVectors.length,
|
|
903
|
-
remainingVectors: currentSearchResults.length - filteredVectors.length,
|
|
904
|
-
nextBatchSize: SEARCH_BATCH_SIZE
|
|
905
|
-
});
|
|
900
|
+
// console.log('📝 [VectorSearch] Loaded next batch:', {
|
|
901
|
+
// batchSize: nextBatch.length,
|
|
902
|
+
// totalDisplayed: filteredVectors.length,
|
|
903
|
+
// remainingVectors: currentSearchResults.length - filteredVectors.length,
|
|
904
|
+
// nextBatchSize: SEARCH_BATCH_SIZE
|
|
905
|
+
// });
|
|
906
906
|
}
|
|
907
907
|
} else {
|
|
908
908
|
// Normal vector list scrolling
|
|
@@ -971,17 +971,17 @@
|
|
|
971
971
|
}
|
|
972
972
|
showVectorModal = false;
|
|
973
973
|
|
|
974
|
-
console.log('🧹 [VectorInput] Cleanup complete:', {
|
|
975
|
-
controllerId,
|
|
976
|
-
lastFilter: currentFilter
|
|
977
|
-
});
|
|
974
|
+
// console.log('🧹 [VectorInput] Cleanup complete:', {
|
|
975
|
+
// controllerId,
|
|
976
|
+
// lastFilter: currentFilter
|
|
977
|
+
// });
|
|
978
978
|
});
|
|
979
979
|
|
|
980
980
|
/**
|
|
981
981
|
* Opens the file browser for vector selection
|
|
982
982
|
*/
|
|
983
983
|
async function openFileBrowser() {
|
|
984
|
-
console.log('🔍 [VectorInput] Opening file browser for vectors');
|
|
984
|
+
// console.log('🔍 [VectorInput] Opening file browser for vectors');
|
|
985
985
|
|
|
986
986
|
try {
|
|
987
987
|
// Get the current vector's ID if it exists in our custom vectors
|
|
@@ -990,10 +990,10 @@
|
|
|
990
990
|
.find(v => v.name === value.name && v.category === 'Mine')?.name
|
|
991
991
|
: undefined;
|
|
992
992
|
|
|
993
|
-
console.log('🔍 [VectorInput] Opening file browser:', {
|
|
994
|
-
fileTypes: ['svg'],
|
|
995
|
-
selectedId
|
|
996
|
-
});
|
|
993
|
+
// console.log('🔍 [VectorInput] Opening file browser:', {
|
|
994
|
+
// fileTypes: ['svg'],
|
|
995
|
+
// selectedId
|
|
996
|
+
// });
|
|
997
997
|
|
|
998
998
|
// TODO: Implement file browser functionality
|
|
999
999
|
// This will be similar to FontInputController but for SVG files
|
|
@@ -1167,21 +1167,21 @@
|
|
|
1167
1167
|
// Add to VectorInputController.svelte
|
|
1168
1168
|
function handleToggle() {
|
|
1169
1169
|
const beforeState = $openDropdowns?.has(controllerId);
|
|
1170
|
-
console.log('🟡 [VectorInput] Toggle start:', {
|
|
1171
|
-
controllerId,
|
|
1172
|
-
beforeState,
|
|
1173
|
-
openDropdowns: Array.from($openDropdowns || new Set())
|
|
1174
|
-
});
|
|
1170
|
+
// console.log('🟡 [VectorInput] Toggle start:', {
|
|
1171
|
+
// controllerId,
|
|
1172
|
+
// beforeState,
|
|
1173
|
+
// openDropdowns: Array.from($openDropdowns || new Set())
|
|
1174
|
+
// });
|
|
1175
1175
|
|
|
1176
1176
|
toggleDropdown(controllerId);
|
|
1177
1177
|
|
|
1178
1178
|
const afterState = $openDropdowns?.has(controllerId);
|
|
1179
|
-
console.log('🟢 [VectorInput] Toggle complete:', {
|
|
1180
|
-
controllerId,
|
|
1181
|
-
beforeState,
|
|
1182
|
-
afterState,
|
|
1183
|
-
openDropdowns: Array.from($openDropdowns || new Set())
|
|
1184
|
-
});
|
|
1179
|
+
// console.log('🟢 [VectorInput] Toggle complete:', {
|
|
1180
|
+
// controllerId,
|
|
1181
|
+
// beforeState,
|
|
1182
|
+
// afterState,
|
|
1183
|
+
// openDropdowns: Array.from($openDropdowns || new Set())
|
|
1184
|
+
// });
|
|
1185
1185
|
}
|
|
1186
1186
|
|
|
1187
1187
|
function closeDropdown() {
|
|
@@ -1216,7 +1216,7 @@
|
|
|
1216
1216
|
|
|
1217
1217
|
// If scrolling outside our containers, close dropdowns
|
|
1218
1218
|
if ($openDropdowns?.has(controllerId)) {
|
|
1219
|
-
console.log('🔴 [VectorInput] Closing dropdown due to external scroll');
|
|
1219
|
+
// console.log('🔴 [VectorInput] Closing dropdown due to external scroll');
|
|
1220
1220
|
toggleDropdown(controllerId);
|
|
1221
1221
|
}
|
|
1222
1222
|
}
|
|
@@ -1283,7 +1283,7 @@
|
|
|
1283
1283
|
// Create a Svelte action to handle image error events
|
|
1284
1284
|
function handleImageError(node: HTMLElement, vectorName: string) {
|
|
1285
1285
|
const errorHandler = (event: Event) => {
|
|
1286
|
-
console.log(`❌ [VectorInput] Image failed to load: ${vectorName}`);
|
|
1286
|
+
// console.log(`❌ [VectorInput] Image failed to load: ${vectorName}`);
|
|
1287
1287
|
svgLoadErrors.set(vectorName, true);
|
|
1288
1288
|
svgLoadErrors = new Map(svgLoadErrors);
|
|
1289
1289
|
|
|
@@ -1481,7 +1481,7 @@
|
|
|
1481
1481
|
if (hasSvgLoadError(value.name)) {
|
|
1482
1482
|
svgLoadErrors.delete(value.name);
|
|
1483
1483
|
svgLoadErrors = new Map(svgLoadErrors);
|
|
1484
|
-
console.log(`✅ [VectorInput] Vector now loads successfully: ${value.name}`);
|
|
1484
|
+
// console.log(`✅ [VectorInput] Vector now loads successfully: ${value.name}`);
|
|
1485
1485
|
}
|
|
1486
1486
|
};
|
|
1487
1487
|
testImg.onerror = () => {
|
|
@@ -1648,10 +1648,10 @@
|
|
|
1648
1648
|
// Ensure the observer is set up after the DOM updates
|
|
1649
1649
|
setTimeout(() => {
|
|
1650
1650
|
setupVectorObserver();
|
|
1651
|
-
console.log('🔄 [VectorSearch] Observer setup after search clear');
|
|
1651
|
+
// console.log('🔄 [VectorSearch] Observer setup after search clear');
|
|
1652
1652
|
}, 50);
|
|
1653
1653
|
|
|
1654
|
-
console.log('🔄 [VectorSearch] Search cleared');
|
|
1654
|
+
// console.log('🔄 [VectorSearch] Search cleared');
|
|
1655
1655
|
}}
|
|
1656
1656
|
/>
|
|
1657
1657
|
</div>
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
export let displayMode: 'list' | 'grid' = 'list';
|
|
27
27
|
export let hideTrashIcon: boolean = false;
|
|
28
28
|
export let itemType: 'font' | 'vector' = 'font';
|
|
29
|
+
export let selectionToken = '';
|
|
29
30
|
|
|
30
31
|
// Helper function to determine if the result has HTML content
|
|
31
32
|
function hasHtml(result: { html: string } | string): result is { html: string } {
|
|
@@ -39,7 +40,7 @@
|
|
|
39
40
|
|
|
40
41
|
{#if displayMode === 'list'}
|
|
41
42
|
<div class="grid grid-cols-1">
|
|
42
|
-
{#each recentItems as item (getItemKey(item))}
|
|
43
|
+
{#each recentItems as item (getItemKey(item) + '-' + selectionToken)}
|
|
43
44
|
{@const renderedItem = renderItem(item)}
|
|
44
45
|
{@const selected = isItemSelected(item)}
|
|
45
46
|
|
|
@@ -47,9 +48,10 @@
|
|
|
47
48
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
48
49
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
49
50
|
<div
|
|
50
|
-
class="w-full px-4 cursor-pointer overflow-hidden relative rounded-small"
|
|
51
|
+
class="font-list-row w-full px-4 cursor-pointer overflow-hidden relative rounded-small"
|
|
51
52
|
class:bg-sage-green={selected}
|
|
52
53
|
class:text-white={selected}
|
|
54
|
+
class:text-grey7={!selected}
|
|
53
55
|
class:hover:bg-light-green={!selected}
|
|
54
56
|
class:selected-item={selected}
|
|
55
57
|
onclick={() => onItemSelect(item)}
|
|
@@ -69,6 +71,7 @@
|
|
|
69
71
|
{#if isCustomItem(item) && !hideTrashIcon}
|
|
70
72
|
<button
|
|
71
73
|
type="button"
|
|
74
|
+
tabindex="-1"
|
|
72
75
|
class="p-1 rounded-full hover:bg-red-100 hover:text-red-500 transition-colors"
|
|
73
76
|
onclick={(e) => {
|
|
74
77
|
e.stopPropagation();
|
|
@@ -84,9 +87,10 @@
|
|
|
84
87
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
85
88
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
86
89
|
<div
|
|
87
|
-
class="w-full px-4 cursor-pointer overflow-hidden relative rounded-small"
|
|
90
|
+
class="font-list-row w-full px-4 cursor-pointer overflow-hidden relative rounded-small"
|
|
88
91
|
class:bg-sage-green={selected}
|
|
89
92
|
class:text-white={selected}
|
|
93
|
+
class:text-grey7={!selected}
|
|
90
94
|
class:hover:bg-light-green={!selected}
|
|
91
95
|
class:selected-item={selected}
|
|
92
96
|
onclick={() => onItemSelect(item)}
|
|
@@ -105,6 +109,7 @@
|
|
|
105
109
|
{#if isCustomItem(item) && !hideTrashIcon}
|
|
106
110
|
<button
|
|
107
111
|
type="button"
|
|
112
|
+
tabindex="-1"
|
|
108
113
|
class="p-1 rounded-full hover:bg-red-100 hover:text-red-500 transition-colors"
|
|
109
114
|
onclick={(e) => {
|
|
110
115
|
e.stopPropagation();
|
|
@@ -121,7 +126,7 @@
|
|
|
121
126
|
</div>
|
|
122
127
|
{:else}
|
|
123
128
|
<div class="grid grid-cols-3 gap-x-6 gap-y-4 pt-2 pb-0">
|
|
124
|
-
{#each recentItems as item (getItemKey(item))}
|
|
129
|
+
{#each recentItems as item (getItemKey(item) + '-' + selectionToken)}
|
|
125
130
|
{@const renderedItem = renderItem(item)}
|
|
126
131
|
{@const selected = isItemSelected(item)}
|
|
127
132
|
|
|
@@ -132,6 +137,7 @@
|
|
|
132
137
|
class="flex-shrink-0 flex items-center justify-center widgetic-radius rounded transition-colors cursor-pointer border-2 border-grey2"
|
|
133
138
|
class:bg-sage-green={selected}
|
|
134
139
|
class:text-white={selected}
|
|
140
|
+
class:text-grey7={!selected}
|
|
135
141
|
class:border-sage-green={selected}
|
|
136
142
|
class:hover:bg-light-green={!selected}
|
|
137
143
|
class:selected-item={selected}
|
|
@@ -152,6 +158,7 @@
|
|
|
152
158
|
<button
|
|
153
159
|
type="button"
|
|
154
160
|
class="absolute top-1 right-1 p-1 rounded-full hover:bg-red-100 hover:text-red-500 transition-colors bg-white"
|
|
161
|
+
tabindex="-1"
|
|
155
162
|
onclick={(e) => {
|
|
156
163
|
e.stopPropagation();
|
|
157
164
|
onItemDelete(item, e);
|
|
@@ -169,6 +176,7 @@
|
|
|
169
176
|
class="flex-shrink-0 flex items-center justify-center widgetic-radius rounded transition-colors cursor-pointer border-2 border-grey2"
|
|
170
177
|
class:bg-sage-green={selected}
|
|
171
178
|
class:text-white={selected}
|
|
179
|
+
class:text-grey7={!selected}
|
|
172
180
|
class:border-sage-green={selected}
|
|
173
181
|
class:hover:bg-light-green={!selected}
|
|
174
182
|
class:selected-item={selected}
|
|
@@ -188,6 +196,7 @@
|
|
|
188
196
|
<button
|
|
189
197
|
type="button"
|
|
190
198
|
class="absolute top-1 right-1 p-1 rounded-full hover:bg-red-100 hover:text-red-500 transition-colors bg-white"
|
|
199
|
+
tabindex="-1"
|
|
191
200
|
onclick={(e) => {
|
|
192
201
|
e.stopPropagation();
|
|
193
202
|
onItemDelete(item, e);
|
|
@@ -252,9 +261,15 @@
|
|
|
252
261
|
background-color: hsl(var(--light-green)) !important;
|
|
253
262
|
}
|
|
254
263
|
|
|
255
|
-
|
|
256
|
-
:global(.selected-item:hover) {
|
|
264
|
+
:global(.font-list-row.selected-item:hover),
|
|
265
|
+
:global([data-item].selected-item:hover) {
|
|
257
266
|
background-color: hsl(var(--sage-green)) !important;
|
|
267
|
+
color: white !important;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
:global(.font-list-row:not(.selected-item)),
|
|
271
|
+
:global([data-item]:not(.selected-item)) {
|
|
272
|
+
color: hsl(var(--grey7)) !important;
|
|
258
273
|
}
|
|
259
274
|
|
|
260
275
|
</style>
|
package/dist/config.d.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
interface Config {
|
|
2
2
|
GOOGLE_FONTS_API_KEY: string;
|
|
3
3
|
}
|
|
4
|
+
export declare function setGoogleFontsApiKey(key: string): void;
|
|
5
|
+
/**
|
|
6
|
+
* Google Fonts Web Fonts API key.
|
|
7
|
+
* Order: runtime setter → PUBLIC_GOOGLE_FONTS_API_KEY → VITE_GOOGLE_FONTS_API_KEY.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getGoogleFontsKey(): string;
|
|
4
10
|
export declare const config: Config;
|
|
5
11
|
export {};
|
package/dist/config.js
CHANGED
|
@@ -1,19 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Set by the consuming app (widget-creator / site) so the published
|
|
3
|
+
* `@widgetic/editor` package never bakes a key into dist at pack time.
|
|
4
|
+
* Vite still inlines PUBLIC_/VITE_ keys when the consumer bundles this source.
|
|
5
|
+
*/
|
|
6
|
+
let runtimeGoogleFontsApiKey = '';
|
|
7
|
+
export function setGoogleFontsApiKey(key) {
|
|
8
|
+
runtimeGoogleFontsApiKey = String(key || '').trim();
|
|
9
|
+
}
|
|
1
10
|
/**
|
|
2
11
|
* Google Fonts Web Fonts API key.
|
|
3
|
-
*
|
|
4
|
-
* Avoids $env/static/public import so the library works when embedded in site/creator.
|
|
12
|
+
* Order: runtime setter → PUBLIC_GOOGLE_FONTS_API_KEY → VITE_GOOGLE_FONTS_API_KEY.
|
|
5
13
|
*/
|
|
6
|
-
function getGoogleFontsKey() {
|
|
14
|
+
export function getGoogleFontsKey() {
|
|
15
|
+
if (runtimeGoogleFontsApiKey)
|
|
16
|
+
return runtimeGoogleFontsApiKey;
|
|
7
17
|
if (typeof import.meta !== 'undefined' && import.meta.env) {
|
|
8
|
-
const fromVite = import.meta.env.VITE_GOOGLE_FONTS_API_KEY;
|
|
9
|
-
if (fromVite && String(fromVite).trim())
|
|
10
|
-
return String(fromVite).trim();
|
|
11
18
|
const fromPublicMeta = import.meta.env.PUBLIC_GOOGLE_FONTS_API_KEY;
|
|
12
19
|
if (fromPublicMeta && String(fromPublicMeta).trim())
|
|
13
20
|
return String(fromPublicMeta).trim();
|
|
21
|
+
const fromVite = import.meta.env.VITE_GOOGLE_FONTS_API_KEY;
|
|
22
|
+
if (fromVite && String(fromVite).trim())
|
|
23
|
+
return String(fromVite).trim();
|
|
14
24
|
}
|
|
15
25
|
return '';
|
|
16
26
|
}
|
|
17
27
|
export const config = {
|
|
18
|
-
GOOGLE_FONTS_API_KEY
|
|
28
|
+
get GOOGLE_FONTS_API_KEY() {
|
|
29
|
+
return getGoogleFontsKey();
|
|
30
|
+
},
|
|
19
31
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { default as PropsEditor } from './components/editors/PropsEditor.svelte';
|
|
2
2
|
export { default as WidgetPreview } from './components/WidgetPreview.svelte';
|
|
3
3
|
export { setFileBrowserUploadConfig } from '@widgetic/file-browser';
|
|
4
|
+
export { setGoogleFontsApiKey, getGoogleFontsKey } from './config';
|
|
4
5
|
export { default as EmbedEditor } from './components/editors/EmbedEditor.svelte';
|
package/dist/index.js
CHANGED
|
@@ -4,5 +4,6 @@
|
|
|
4
4
|
export { default as PropsEditor } from './components/editors/PropsEditor.svelte';
|
|
5
5
|
export { default as WidgetPreview } from './components/WidgetPreview.svelte';
|
|
6
6
|
export { setFileBrowserUploadConfig } from '@widgetic/file-browser';
|
|
7
|
+
export { setGoogleFontsApiKey, getGoogleFontsKey } from './config';
|
|
7
8
|
// Embed Editor
|
|
8
9
|
export { default as EmbedEditor } from './components/editors/EmbedEditor.svelte';
|