@widgetic/editor 4.0.1 → 4.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/WidgetPreview.svelte +2 -2
- package/dist/components/editors/PropsEditor.svelte +140 -83
- package/dist/components/ic/BrowserInputController.svelte +12 -5
- package/dist/components/ic/FontInputController.svelte +97 -61
- package/dist/components/ic/FontInputController.svelte.d.ts +1 -1
- package/dist/components/ic/TextAreaInputController.svelte +190 -62
- package/dist/components/ic/TextAreaInputController.svelte.d.ts +1 -0
- package/dist/components/ic/TextAreaPreviewInputController.svelte +80 -78
- 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/utils/FontManager.d.ts +2 -0
- package/dist/utils/FontManager.js +21 -2
- package/package.json +1 -1
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
* @prop {Function} onFocus - Optional focus handler
|
|
79
79
|
*/
|
|
80
80
|
export let label: string;
|
|
81
|
-
export let value: { family: string; weight: string; category: string } | null = null;
|
|
81
|
+
export let value: { family: string; weight: string; category: string } | string | null = null;
|
|
82
82
|
export let onChange: ((newValue: { family: string; weight: string; category: string }) => void) | undefined = undefined;
|
|
83
83
|
export let description: string | undefined = undefined;
|
|
84
84
|
export let controllerId: string;
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
|
|
92
92
|
// Font weight state - remove localStorage check on init
|
|
93
93
|
let selectedWeight = `${controllerId}-Regular`;
|
|
94
|
-
let availableWeights: string[] = [];
|
|
94
|
+
let availableWeights: string[] = ['Regular', 'Medium', 'SemiBold', 'Bold'];
|
|
95
95
|
|
|
96
96
|
// Font search and filter state
|
|
97
97
|
let allFonts: FontItem[] = [];
|
|
@@ -120,6 +120,25 @@
|
|
|
120
120
|
export let hideRecentFromList: boolean = false;
|
|
121
121
|
export let hideTrashIcon: boolean = true;
|
|
122
122
|
|
|
123
|
+
function coerceFontValue(raw: typeof value): { family: string; weight: string; category: string } | null {
|
|
124
|
+
if (!raw) return null;
|
|
125
|
+
if (typeof raw === 'object' && raw.family) {
|
|
126
|
+
return {
|
|
127
|
+
family: raw.family,
|
|
128
|
+
weight: raw.weight || 'Regular',
|
|
129
|
+
category: raw.category || 'Sans Serif',
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
if (typeof raw === 'string' && raw.trim()) {
|
|
133
|
+
const family = raw.split(',')[0].replace(/['"]/g, '').trim();
|
|
134
|
+
if (!family) return null;
|
|
135
|
+
return { family, weight: 'Regular', category: 'Sans Serif' };
|
|
136
|
+
}
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
$: resolvedFont = coerceFontValue(value);
|
|
141
|
+
|
|
123
142
|
// Add scroll state tracking
|
|
124
143
|
let isScrolled = false;
|
|
125
144
|
|
|
@@ -188,9 +207,12 @@
|
|
|
188
207
|
onMount(async () => {
|
|
189
208
|
try {
|
|
190
209
|
if (browser) {
|
|
191
|
-
|
|
192
|
-
if (
|
|
193
|
-
selectedWeight = `${controllerId}-${
|
|
210
|
+
const coerced = coerceFontValue(value);
|
|
211
|
+
if (coerced?.weight) {
|
|
212
|
+
selectedWeight = `${controllerId}-${coerced.weight}`;
|
|
213
|
+
}
|
|
214
|
+
if (typeof value === 'string' && coerced && onChange) {
|
|
215
|
+
onChange(coerced);
|
|
194
216
|
}
|
|
195
217
|
|
|
196
218
|
// Load saved filter
|
|
@@ -1368,8 +1390,8 @@
|
|
|
1368
1390
|
}
|
|
1369
1391
|
}
|
|
1370
1392
|
|
|
1371
|
-
$: if (
|
|
1372
|
-
fetchFontWeights(
|
|
1393
|
+
$: if (resolvedFont?.family) {
|
|
1394
|
+
fetchFontWeights(resolvedFont.family);
|
|
1373
1395
|
}
|
|
1374
1396
|
|
|
1375
1397
|
/**
|
|
@@ -1597,7 +1619,7 @@
|
|
|
1597
1619
|
}
|
|
1598
1620
|
|
|
1599
1621
|
function isFontSelected(font: FontItem) {
|
|
1600
|
-
return
|
|
1622
|
+
return resolvedFont?.family === font.family;
|
|
1601
1623
|
}
|
|
1602
1624
|
|
|
1603
1625
|
function isCustomFont(font: FontItem) {
|
|
@@ -1617,30 +1639,25 @@
|
|
|
1617
1639
|
}
|
|
1618
1640
|
</script>
|
|
1619
1641
|
|
|
1620
|
-
<!--
|
|
1621
|
-
<div class="flex flex-col widgetic-colors">
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
/>
|
|
1630
|
-
</div>
|
|
1631
|
-
|
|
1632
|
-
<div class="absolute right-0">
|
|
1633
|
-
<div class="h-[48px] w-[185px] rounded-large border border-grey2 flex items-center bg-grey1 transition-colors duration-200 hover:border-forest-green">
|
|
1642
|
+
<!-- Dual IC: labels left, 185px inputs on the right (even when label is empty) -->
|
|
1643
|
+
<div class="font-ic flex flex-col gap-2 w-full min-w-0 widgetic-colors">
|
|
1644
|
+
<div class="font-family-row flex items-center justify-between w-full min-w-0 gap-2" style="min-height: 48px;">
|
|
1645
|
+
<div class="font-family-label-ct flex-1 min-w-0">
|
|
1646
|
+
{#if label}
|
|
1647
|
+
<InputControllerHeader {label} />
|
|
1648
|
+
{/if}
|
|
1649
|
+
</div>
|
|
1650
|
+
<div class="font-family-input-ct h-12 shrink-0 rounded-large border border-grey2 flex items-center bg-grey1 transition-colors duration-200 hover:border-forest-green" style="width: 185px; max-width: 185px; min-width: 185px; margin-left: auto;">
|
|
1634
1651
|
<!-- Font Family Button -->
|
|
1635
1652
|
<Popover.Root
|
|
1636
1653
|
open={$openDropdowns?.has(controllerId)}
|
|
1637
1654
|
onOpenChange={(isOpen) => {
|
|
1638
1655
|
if (isOpen !== $openDropdowns?.has(controllerId)) {
|
|
1639
|
-
if (!isOpen &&
|
|
1656
|
+
if (!isOpen && resolvedFont?.family && !shouldSkipFont(resolvedFont.family)) {
|
|
1640
1657
|
fontUtils.addRecentFont({
|
|
1641
|
-
family:
|
|
1642
|
-
category: normalizeCategory(
|
|
1643
|
-
isCustom: fontManagerInstance?.isCustomFont(
|
|
1658
|
+
family: resolvedFont.family,
|
|
1659
|
+
category: normalizeCategory(resolvedFont.category) as FontItem['category'],
|
|
1660
|
+
isCustom: fontManagerInstance?.isCustomFont(resolvedFont.family) || false
|
|
1644
1661
|
});
|
|
1645
1662
|
} else if (isOpen) {
|
|
1646
1663
|
// Reset active search index when opening the dropdown
|
|
@@ -1676,9 +1693,9 @@
|
|
|
1676
1693
|
>
|
|
1677
1694
|
<span
|
|
1678
1695
|
class="truncate flex-1 text-left subtext text-grey7"
|
|
1679
|
-
style="font-family: '{
|
|
1696
|
+
style="font-family: '{resolvedFont?.family || 'system-ui'}', sans-serif; font-display: swap;"
|
|
1680
1697
|
>
|
|
1681
|
-
{
|
|
1698
|
+
{resolvedFont?.family || "Select font..."}
|
|
1682
1699
|
</span>
|
|
1683
1700
|
<IconCaretDownFilled class="w-5 h-5 shrink-0 text-grey5 group-hover:text-grey7" />
|
|
1684
1701
|
</Popover.Trigger>
|
|
@@ -1809,9 +1826,9 @@
|
|
|
1809
1826
|
{#each filteredFonts as font, index (`${font.family}-${searchTerm ? 'search' : currentFilter}-${index}`)}
|
|
1810
1827
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
1811
1828
|
<div
|
|
1812
|
-
class="w-full py-1 px-4 cursor-pointer overflow-hidden relative rounded-small h-[42px] flex items-center
|
|
1813
|
-
{
|
|
1814
|
-
index === activeSearchIndex && searchTerm ? 'bg-light-green
|
|
1829
|
+
class="font-list-row w-full py-1 px-4 cursor-pointer overflow-hidden relative rounded-small h-[42px] flex items-center
|
|
1830
|
+
{isFontSelected(font) ? 'bg-sage-green selected-item' :
|
|
1831
|
+
index === activeSearchIndex && searchTerm ? 'bg-light-green' :
|
|
1815
1832
|
'hover:bg-light-green'}"
|
|
1816
1833
|
data-font={font.family}
|
|
1817
1834
|
use:observeFont
|
|
@@ -1819,12 +1836,13 @@
|
|
|
1819
1836
|
onmouseenter={() => handleMouseEnter(index)}
|
|
1820
1837
|
role="button"
|
|
1821
1838
|
tabindex="0"
|
|
1839
|
+
style="color: {isFontSelected(font) ? '#ffffff' : 'hsl(var(--grey7))'};"
|
|
1822
1840
|
>
|
|
1823
1841
|
<div class="flex items-center flex-1 min-w-0 group">
|
|
1824
|
-
<Check class="mr-2 h-6 w-6 flex-shrink-0 {
|
|
1842
|
+
<Check class="mr-2 h-6 w-6 flex-shrink-0 {isFontSelected(font) ? 'text-white' : 'text-sage-green opacity-0'}"/>
|
|
1825
1843
|
<span
|
|
1826
1844
|
class="text-[24px] truncate {index === activeSearchIndex && searchTerm ? 'font-medium' : ''}"
|
|
1827
|
-
style="font-family: '{font.family}', sans-serif; font-display: swap;"
|
|
1845
|
+
style="font-family: '{font.family}', sans-serif; font-display: swap; color: inherit; -webkit-text-fill-color: currentColor;"
|
|
1828
1846
|
>
|
|
1829
1847
|
{@html highlightMatch(font.family, searchTerm)}
|
|
1830
1848
|
</span>
|
|
@@ -1861,15 +1879,13 @@
|
|
|
1861
1879
|
</Popover.Content>
|
|
1862
1880
|
</Popover.Root>
|
|
1863
1881
|
</div>
|
|
1864
|
-
|
|
1865
|
-
</div>
|
|
1882
|
+
</div>
|
|
1866
1883
|
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
<!-- Font Weight Button -->
|
|
1884
|
+
<div class="font-weight-row flex items-center justify-between w-full min-w-0 gap-2" style="min-height: 48px;">
|
|
1885
|
+
<div class="font-weight-label-ct flex-1 min-w-0">
|
|
1886
|
+
<InputControllerHeader label="Font Weight" />
|
|
1887
|
+
</div>
|
|
1888
|
+
<div class="font-weight-input-ct h-12 shrink-0 rounded-large border border-grey2 flex items-center bg-grey1 transition-colors duration-200 hover:border-forest-green" style="width: 185px; max-width: 185px; min-width: 185px; margin-left: auto;">
|
|
1873
1889
|
<Popover.Root
|
|
1874
1890
|
open={$openDropdowns?.has('weight-' + controllerId)}
|
|
1875
1891
|
onOpenChange={(isOpen) => {
|
|
@@ -1880,33 +1896,33 @@
|
|
|
1880
1896
|
>
|
|
1881
1897
|
<Popover.Trigger class="w-full h-full flex items-center border-0 bg-transparent hover:bg-transparent focus:bg-transparent pl-3 pr-[16px] group">
|
|
1882
1898
|
<span class="truncate flex-1 text-left subtext text-grey7">
|
|
1883
|
-
{displayWeight}
|
|
1899
|
+
{displayWeight || 'Regular'}
|
|
1884
1900
|
</span>
|
|
1885
1901
|
<IconCaretDownFilled class="w-5 h-5 shrink-0 text-grey5 group-hover:text-grey7" />
|
|
1886
1902
|
</Popover.Trigger>
|
|
1887
1903
|
<Popover.Content class="p-0 w-[150px]">
|
|
1888
1904
|
<Command.Root>
|
|
1889
|
-
<Command.
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1905
|
+
<Command.List>
|
|
1906
|
+
<Command.Group>
|
|
1907
|
+
{#each availableWeights as weight}
|
|
1908
|
+
<Command.Item
|
|
1909
|
+
value={weight}
|
|
1910
|
+
onSelect={() => handleWeightSelect(weight)}
|
|
1911
|
+
class="px-2 py-2"
|
|
1912
|
+
>
|
|
1913
|
+
<Check
|
|
1914
|
+
class="mr-1 h-4 w-4 {displayWeight === weight ? 'opacity-100' : 'opacity-0'}"
|
|
1915
|
+
/>
|
|
1916
|
+
<span class="truncate">{weight}</span>
|
|
1917
|
+
</Command.Item>
|
|
1918
|
+
{/each}
|
|
1919
|
+
</Command.Group>
|
|
1920
|
+
</Command.List>
|
|
1903
1921
|
</Command.Root>
|
|
1904
1922
|
</Popover.Content>
|
|
1905
1923
|
</Popover.Root>
|
|
1906
|
-
</div>
|
|
1907
1924
|
</div>
|
|
1908
1925
|
</div>
|
|
1909
|
-
</div>
|
|
1910
1926
|
|
|
1911
1927
|
{#if description}
|
|
1912
1928
|
<p class="subtext text-grey5">{description}</p>
|
|
@@ -1914,6 +1930,24 @@
|
|
|
1914
1930
|
</div>
|
|
1915
1931
|
|
|
1916
1932
|
<style>
|
|
1933
|
+
.font-family-row,
|
|
1934
|
+
.font-weight-row {
|
|
1935
|
+
display: flex;
|
|
1936
|
+
align-items: center;
|
|
1937
|
+
justify-content: space-between;
|
|
1938
|
+
width: 100%;
|
|
1939
|
+
}
|
|
1940
|
+
|
|
1941
|
+
.font-family-input-ct,
|
|
1942
|
+
.font-weight-input-ct {
|
|
1943
|
+
width: 185px !important;
|
|
1944
|
+
max-width: 185px !important;
|
|
1945
|
+
min-width: 185px !important;
|
|
1946
|
+
margin-left: auto;
|
|
1947
|
+
flex-shrink: 0;
|
|
1948
|
+
position: relative;
|
|
1949
|
+
}
|
|
1950
|
+
|
|
1917
1951
|
/* Update button styles */
|
|
1918
1952
|
:global(button.bg-transparent) {
|
|
1919
1953
|
background: transparent !important;
|
|
@@ -1932,9 +1966,11 @@
|
|
|
1932
1966
|
scrollbar-color: hsl(var(--grey3)) transparent;
|
|
1933
1967
|
}
|
|
1934
1968
|
|
|
1935
|
-
/*
|
|
1936
|
-
:global(.popover-trigger),
|
|
1937
|
-
:global(.popover-trigger button)
|
|
1969
|
+
/* Trigger fills the 185px column only — do not leak width:100% to other ICs */
|
|
1970
|
+
.font-family-input-ct :global(.popover-trigger),
|
|
1971
|
+
.font-family-input-ct :global(.popover-trigger button),
|
|
1972
|
+
.font-weight-input-ct :global(.popover-trigger),
|
|
1973
|
+
.font-weight-input-ct :global(.popover-trigger button) {
|
|
1938
1974
|
width: 100% !important;
|
|
1939
1975
|
height: 100% !important;
|
|
1940
1976
|
}
|