@widgetic/editor 4.0.2 → 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.
Files changed (34) hide show
  1. package/dist/components/MockWidget.svelte +1 -1
  2. package/dist/components/WidgetPreview.svelte +34 -50
  3. package/dist/components/editors/EmbedEditor.svelte +1 -1
  4. package/dist/components/editors/PropsEditor.svelte +173 -148
  5. package/dist/components/ic/BrowserInputController.svelte +14 -14
  6. package/dist/components/ic/CheckboxInputController.svelte +1 -1
  7. package/dist/components/ic/ColorPickerInputController.svelte +37 -37
  8. package/dist/components/ic/DatePickerInputController.svelte +6 -6
  9. package/dist/components/ic/DropdownInputController.svelte +1 -1
  10. package/dist/components/ic/FontInputController.svelte +136 -63
  11. package/dist/components/ic/FontInputController.svelte.d.ts +3 -1
  12. package/dist/components/ic/NumberInputController.svelte +37 -37
  13. package/dist/components/ic/RadioGroupInputController.svelte +1 -1
  14. package/dist/components/ic/SliderRangeInputController.svelte +1 -1
  15. package/dist/components/ic/SwitchInputController.svelte +1 -1
  16. package/dist/components/ic/TextAreaInputController.svelte +23 -23
  17. package/dist/components/ic/TextAreaPreviewInputController.svelte +2 -2
  18. package/dist/components/ic/VectorInputController.svelte +34 -34
  19. package/dist/components/ic/shared/CategoryTabs.svelte +1 -0
  20. package/dist/components/ic/shared/RecentItemsSection.svelte +21 -6
  21. package/dist/components/ic/shared/RecentItemsSection.svelte.d.ts +1 -0
  22. package/dist/stores/userSession.d.ts +1 -1
  23. package/dist/stores/userSession.js +17 -2
  24. package/dist/utils/FontManager.d.ts +1 -1
  25. package/dist/utils/FontManager.js +75 -102
  26. package/dist/utils/VectorManager.d.ts +3 -1
  27. package/dist/utils/VectorManager.js +30 -70
  28. package/dist/utils/colorTransparency.js +3 -3
  29. package/dist/utils/fontUtils.js +1 -1
  30. package/dist/utils/passiveEvents.d.ts +5 -0
  31. package/dist/utils/passiveEvents.js +9 -18
  32. package/dist/utils/recentColors.js +15 -15
  33. package/dist/utils/vectorUtils.js +1 -1
  34. package/package.json +1 -1
@@ -77,7 +77,10 @@
77
77
  * @prop {Function} toggleDropdown - Function to toggle dropdown state
78
78
  * @prop {Function} onFocus - Optional focus handler
79
79
  */
80
- export let label: string;
80
+ export let label: string = '';
81
+ let className = '';
82
+ export { className as class };
83
+ export let style = '';
81
84
  export let value: { family: string; weight: string; category: string } | string | null = null;
82
85
  export let onChange: ((newValue: { family: string; weight: string; category: string }) => void) | undefined = undefined;
83
86
  export let description: string | undefined = undefined;
@@ -103,6 +106,9 @@
103
106
 
104
107
  // Font loading optimization
105
108
  let fontListContainer: HTMLElement;
109
+ let familyTriggerEl: HTMLDivElement | undefined;
110
+ let familyPopoverStyle = '';
111
+ let familyPopoverSide: 'top' | 'bottom' = 'bottom';
106
112
  let fontObserver = new IntersectionObserver(() => {});
107
113
 
108
114
  // Initialize FontManager instance
@@ -120,6 +126,27 @@
120
126
  export let hideRecentFromList: boolean = false;
121
127
  export let hideTrashIcon: boolean = true;
122
128
 
129
+ function updateFamilyPopoverBox() {
130
+ if (!familyTriggerEl || typeof window === 'undefined') return;
131
+ const rect = familyTriggerEl.getBoundingClientRect();
132
+ const pad = 12;
133
+ const viewportH = window.visualViewport?.height ?? window.innerHeight;
134
+ const below = viewportH - rect.bottom - pad;
135
+ const above = rect.top - pad;
136
+ const openAbove = above > below;
137
+ familyPopoverSide = openAbove ? 'top' : 'bottom';
138
+ const available = Math.max(0, openAbove ? above : below);
139
+ const height = Math.min(565, available);
140
+ const width = Math.min(374, Math.max(240, window.innerWidth - 16));
141
+ familyPopoverStyle = `width: ${width}px; height: ${height}px; max-width: calc(100vw - 16px); max-height: ${height}px;`;
142
+ }
143
+
144
+ function handleFamilyPopoverViewportChange() {
145
+ if ($openDropdowns?.has(controllerId)) {
146
+ updateFamilyPopoverBox();
147
+ }
148
+ }
149
+
123
150
  function coerceFontValue(raw: typeof value): { family: string; weight: string; category: string } | null {
124
151
  if (!raw) return null;
125
152
  if (typeof raw === 'object' && raw.family) {
@@ -350,13 +377,13 @@
350
377
  preloadedFonts = fontManagerInstance.getPreloadedFonts('Mine');
351
378
 
352
379
  if (preloadedFonts.length > 0) {
353
- console.log(`✅ [FontInput:${controllerId}] Using preloaded custom fonts for Mine category:`, {
354
- count: preloadedFonts.length,
355
- fonts: preloadedFonts.slice(0, 3).map(f => f.family)
356
- });
380
+ // console.log(`✅ [FontInput:${controllerId}] Using preloaded custom fonts for Mine category:`, {
381
+ // count: preloadedFonts.length,
382
+ // fonts: preloadedFonts.slice(0, 3).map(f => f.family)
383
+ // });
357
384
  } else {
358
385
  // If no preloaded fonts found, load them now
359
- console.log(`📚 [FontInput:${controllerId}] No preloaded custom fonts found, loading them now...`);
386
+ // console.log(`📚 [FontInput:${controllerId}] No preloaded custom fonts found, loading them now...`);
360
387
  preloadedFonts = await fontManagerInstance.loadCustomFonts();
361
388
  }
362
389
 
@@ -421,13 +448,13 @@
421
448
  initialFonts = fontManagerInstance.getPreloadedFonts('Mine');
422
449
 
423
450
  if (initialFonts.length > 0) {
424
- console.log(`📚 [FontInput:${controllerId}] Using preloaded custom fonts:`, {
425
- count: initialFonts.length,
426
- fonts: initialFonts.slice(0, 3).map(f => f.family)
427
- });
451
+ // console.log(`📚 [FontInput:${controllerId}] Using preloaded custom fonts:`, {
452
+ // count: initialFonts.length,
453
+ // fonts: initialFonts.slice(0, 3).map(f => f.family)
454
+ // });
428
455
  } else {
429
456
  // If no preloaded fonts, load them now
430
- console.log(`📚 [FontInput:${controllerId}] No preloaded custom fonts found, loading them now...`);
457
+ // console.log(`📚 [FontInput:${controllerId}] No preloaded custom fonts found, loading them now...`);
431
458
  initialFonts = await fontManagerInstance.loadCustomFonts();
432
459
  }
433
460
  } else if (currentFilter === 'All') {
@@ -537,14 +564,14 @@
537
564
  const preloadedCustomFonts = fontManagerInstance.getPreloadedFonts('Mine');
538
565
 
539
566
  if (preloadedCustomFonts.length > 0) {
540
- console.log(`📚 [FontInput:${controllerId}] Using preloaded custom fonts in initializeFonts:`, {
541
- count: preloadedCustomFonts.length,
542
- fonts: preloadedCustomFonts.slice(0, 3).map(f => f.family)
543
- });
567
+ // console.log(`📚 [FontInput:${controllerId}] Using preloaded custom fonts in initializeFonts:`, {
568
+ // count: preloadedCustomFonts.length,
569
+ // fonts: preloadedCustomFonts.slice(0, 3).map(f => f.family)
570
+ // });
544
571
  return preloadedCustomFonts;
545
572
  } else {
546
573
  // If no preloaded fonts, load them now
547
- console.log(`📚 [FontInput:${controllerId}] No preloaded custom fonts found in initializeFonts, loading them now...`);
574
+ // console.log(`📚 [FontInput:${controllerId}] No preloaded custom fonts found in initializeFonts, loading them now...`);
548
575
  const customFonts = await fontManagerInstance.loadCustomFonts();
549
576
  return customFonts;
550
577
  }
@@ -914,16 +941,16 @@
914
941
 
915
942
  if (preloadedCustomFonts.length > 0) {
916
943
  // Use preloaded custom fonts
917
- console.log(`📚 [FontInput:${controllerId}] Using preloaded custom fonts for empty search:`, {
918
- count: preloadedCustomFonts.length,
919
- fonts: preloadedCustomFonts.slice(0, 3).map(f => f.family)
920
- });
944
+ // console.log(`📚 [FontInput:${controllerId}] Using preloaded custom fonts for empty search:`, {
945
+ // count: preloadedCustomFonts.length,
946
+ // fonts: preloadedCustomFonts.slice(0, 3).map(f => f.family)
947
+ // });
921
948
  allFonts = preloadedCustomFonts;
922
949
  filteredFonts = [];
923
950
  updateFilteredFonts();
924
951
  } else {
925
952
  // If no preloaded fonts, load them asynchronously
926
- console.log(`📚 [FontInput:${controllerId}] No preloaded custom fonts found for empty search, loading them now...`);
953
+ // console.log(`📚 [FontInput:${controllerId}] No preloaded custom fonts found for empty search, loading them now...`);
927
954
  fontManagerInstance.loadCustomFonts().then(customFonts => {
928
955
  allFonts = customFonts || [];
929
956
  filteredFonts = [];
@@ -1021,13 +1048,13 @@
1021
1048
 
1022
1049
  if (fonts.length === 0) {
1023
1050
  // If no preloaded custom fonts found, load them
1024
- console.log(`📚 [FontInput:${controllerId}] No preloaded custom fonts found, loading them now...`);
1051
+ // console.log(`📚 [FontInput:${controllerId}] No preloaded custom fonts found, loading them now...`);
1025
1052
  fonts = await fontManagerInstance.loadCustomFonts();
1026
1053
  } else {
1027
- console.log(`📚 [FontInput:${controllerId}] Using preloaded custom fonts:`, {
1028
- count: fonts.length,
1029
- fonts: fonts.slice(0, 3).map(f => f.family)
1030
- });
1054
+ // console.log(`📚 [FontInput:${controllerId}] Using preloaded custom fonts:`, {
1055
+ // count: fonts.length,
1056
+ // fonts: fonts.slice(0, 3).map(f => f.family)
1057
+ // });
1031
1058
  }
1032
1059
  } else {
1033
1060
  // For other categories, first try to get preloaded fonts
@@ -1475,6 +1502,8 @@
1475
1502
  capture: true,
1476
1503
  passive: true
1477
1504
  });
1505
+ window.addEventListener('resize', handleFamilyPopoverViewportChange);
1506
+ window.visualViewport?.addEventListener('resize', handleFamilyPopoverViewportChange);
1478
1507
 
1479
1508
  // Add touch listeners with passive option
1480
1509
  window.addEventListener('touchstart', () => {}, { passive: true });
@@ -1484,6 +1513,8 @@
1484
1513
  // Update onDestroy to remove all listeners
1485
1514
  onDestroy(() => {
1486
1515
  window.removeEventListener('scroll', handleGlobalScroll, true);
1516
+ window.removeEventListener('resize', handleFamilyPopoverViewportChange);
1517
+ window.visualViewport?.removeEventListener('resize', handleFamilyPopoverViewportChange);
1487
1518
  window.removeEventListener('touchstart', () => {});
1488
1519
  window.removeEventListener('touchmove', () => {});
1489
1520
 
@@ -1498,10 +1529,10 @@
1498
1529
  clearTimeout(initialLoadTimeout);
1499
1530
  }
1500
1531
 
1501
- console.log('🧹 [FontInput] Cleanup complete:', {
1502
- controllerId,
1503
- lastFilter: currentFilter
1504
- });
1532
+ // console.log('🧹 [FontInput] Cleanup complete:', {
1533
+ // controllerId,
1534
+ // lastFilter: currentFilter
1535
+ // });
1505
1536
  });
1506
1537
 
1507
1538
  // Add this function to the script section
@@ -1552,12 +1583,12 @@
1552
1583
  // Update filtered fonts
1553
1584
  updateFilteredFonts();
1554
1585
 
1555
- console.log('✅ [FontInput] Font removed:', {
1556
- fontFamily,
1557
- remainingFonts: allFonts.length,
1558
- filteredFonts: filteredFonts.length,
1559
- recentFonts: recentFonts.length
1560
- });
1586
+ // console.log('✅ [FontInput] Font removed:', {
1587
+ // fontFamily,
1588
+ // remainingFonts: allFonts.length,
1589
+ // filteredFonts: filteredFonts.length,
1590
+ // recentFonts: recentFonts.length
1591
+ // });
1561
1592
  } catch (error) {
1562
1593
  console.error('❌ [FontInput] Error removing font:', error);
1563
1594
  }
@@ -1569,11 +1600,12 @@
1569
1600
  if (browser) {
1570
1601
  localStorage.setItem(FONT_WEIGHT_KEY(controllerId), selectedWeight);
1571
1602
  }
1603
+ const current = coerceFontValue(value);
1572
1604
  if (onChange) {
1573
1605
  onChange({
1574
- family: value?.family || '',
1606
+ family: current?.family || '',
1575
1607
  weight: weight,
1576
- category: value?.category || ''
1608
+ category: current?.category || 'Sans Serif'
1577
1609
  });
1578
1610
  }
1579
1611
  }
@@ -1609,7 +1641,7 @@
1609
1641
  <div class="flex items-center flex-1 min-w-0">
1610
1642
  <span
1611
1643
  class="text-[24px] truncate"
1612
- style="font-family: '${font.family}', sans-serif; font-display: swap;"
1644
+ style="font-family: '${font.family}', sans-serif; font-display: swap; color: inherit; -webkit-text-fill-color: currentColor;"
1613
1645
  >
1614
1646
  ${font.family}
1615
1647
  </span>
@@ -1639,15 +1671,17 @@
1639
1671
  }
1640
1672
  </script>
1641
1673
 
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">
1674
+ <!-- Dual IC: header zone always on the left (even if label is empty); 185px inputs on the right. -->
1675
+ <div class="font-ic flex flex-col gap-2 w-full min-w-0 widgetic-colors {className}" style={style}>
1644
1676
  <div class="font-family-row flex items-center justify-between w-full min-w-0 gap-2" style="min-height: 48px;">
1645
1677
  <div class="font-family-label-ct flex-1 min-w-0">
1646
- {#if label}
1647
- <InputControllerHeader {label} />
1648
- {/if}
1678
+ <InputControllerHeader label={label || ''} />
1649
1679
  </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;">
1680
+ <div
1681
+ 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"
1682
+ style="width: 185px; max-width: 185px; min-width: 185px;"
1683
+ bind:this={familyTriggerEl}
1684
+ >
1651
1685
  <!-- Font Family Button -->
1652
1686
  <Popover.Root
1653
1687
  open={$openDropdowns?.has(controllerId)}
@@ -1660,8 +1694,11 @@
1660
1694
  isCustom: fontManagerInstance?.isCustomFont(resolvedFont.family) || false
1661
1695
  });
1662
1696
  } else if (isOpen) {
1663
- // Reset active search index when opening the dropdown
1664
1697
  activeSearchIndex = -1;
1698
+ void tick().then(() => {
1699
+ updateFamilyPopoverBox();
1700
+ requestAnimationFrame(updateFamilyPopoverBox);
1701
+ });
1665
1702
 
1666
1703
  // When opening, ensure we have fonts ready
1667
1704
  if (filteredFonts.length === 0 && allFonts.length > 0) {
@@ -1682,7 +1719,7 @@
1682
1719
  }
1683
1720
  }}
1684
1721
  >
1685
- <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"
1722
+ <Popover.Trigger tabindex="-1" class="w-full h-full flex items-center border-0 bg-transparent hover:bg-transparent focus:bg-transparent pl-3 pr-[16px] group"
1686
1723
  onmouseenter={() => {
1687
1724
  // Preload fonts when hovering over the button
1688
1725
  // This reduces the delay when actually clicking to open
@@ -1700,13 +1737,20 @@
1700
1737
  <IconCaretDownFilled class="w-5 h-5 shrink-0 text-grey5 group-hover:text-grey7" />
1701
1738
  </Popover.Trigger>
1702
1739
 
1703
- <Popover.Content class="font-input-popover w-[374px] h-[565px] !p-0 widgetic-colors widgetic-radius rounded-medium modal-shadow border border-grey2">
1704
- <div class="flex flex-col h-full font-popover-content">
1740
+ <Popover.Content
1741
+ collisionPadding={12}
1742
+ side={familyPopoverSide}
1743
+ sideOffset={4}
1744
+ class="font-input-popover !p-0 widgetic-colors widgetic-radius rounded-medium modal-shadow border border-grey2"
1745
+ style={familyPopoverStyle}
1746
+ >
1747
+ <div class="flex flex-col h-full min-h-0 font-popover-content">
1705
1748
  <!-- Title and upload icon -->
1706
- <div class="relative pt-6 pb-[11px] px-5">
1749
+ <div class="font-popover-header shrink-0 relative pt-6 pb-[11px] px-5">
1707
1750
  <div class="h5 text-grey7 widgetic-colors">Fonts</div>
1708
1751
  <button
1709
1752
  type="button"
1753
+ tabindex="-1"
1710
1754
  class="absolute right-6 top-[26px] bg-transparent border-0 cursor-pointer p-0 rounded-full hover:bg-grey3 transition-all duration-300"
1711
1755
  onclick={() => {
1712
1756
  try {
@@ -1725,7 +1769,7 @@
1725
1769
  {/if}
1726
1770
 
1727
1771
  <!-- Search input -->
1728
- <div class="relative px-4">
1772
+ <div class="font-popover-search shrink-0 relative px-4">
1729
1773
  <SearchInput
1730
1774
  placeholder="Search fonts..."
1731
1775
  bind:value={searchTerm}
@@ -1750,7 +1794,7 @@
1750
1794
  </div>
1751
1795
  <!-- Filter toggle group - sticky header -->
1752
1796
  {#if !searchTerm}
1753
- <div class="sticky top-0 bg-white z-10">
1797
+ <div class="font-popover-tabs shrink-0 sticky top-0 bg-white z-10">
1754
1798
  <CategoryTabs
1755
1799
  categories={filterOptions}
1756
1800
  activeCategory={currentFilter}
@@ -1789,6 +1833,7 @@
1789
1833
  displayMode="list"
1790
1834
  hideTrashIcon={hideTrashIcon}
1791
1835
  itemType="font"
1836
+ selectionToken={resolvedFont?.family || ''}
1792
1837
  />
1793
1838
  {/if}
1794
1839
 
@@ -1835,7 +1880,7 @@
1835
1880
  onclick={() => handleFontSelect(font)}
1836
1881
  onmouseenter={() => handleMouseEnter(index)}
1837
1882
  role="button"
1838
- tabindex="0"
1883
+ tabindex="-1"
1839
1884
  style="color: {isFontSelected(font) ? '#ffffff' : 'hsl(var(--grey7))'};"
1840
1885
  >
1841
1886
  <div class="flex items-center flex-1 min-w-0 group">
@@ -1883,9 +1928,9 @@
1883
1928
 
1884
1929
  <div class="font-weight-row flex items-center justify-between w-full min-w-0 gap-2" style="min-height: 48px;">
1885
1930
  <div class="font-weight-label-ct flex-1 min-w-0">
1886
- <InputControllerHeader label="Font Weight" />
1931
+ <InputControllerHeader label={label ? 'Font Weight' : ''} />
1887
1932
  </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;">
1933
+ <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;">
1889
1934
  <Popover.Root
1890
1935
  open={$openDropdowns?.has('weight-' + controllerId)}
1891
1936
  onOpenChange={(isOpen) => {
@@ -1894,7 +1939,7 @@
1894
1939
  }
1895
1940
  }}
1896
1941
  >
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">
1942
+ <Popover.Trigger tabindex="-1" class="w-full h-full flex items-center border-0 bg-transparent hover:bg-transparent focus:bg-transparent pl-3 pr-[16px] group">
1898
1943
  <span class="truncate flex-1 text-left subtext text-grey7">
1899
1944
  {displayWeight || 'Regular'}
1900
1945
  </span>
@@ -1938,6 +1983,12 @@
1938
1983
  width: 100%;
1939
1984
  }
1940
1985
 
1986
+ .font-family-label-ct,
1987
+ .font-weight-label-ct {
1988
+ flex: 1 1 auto;
1989
+ min-width: 0;
1990
+ }
1991
+
1941
1992
  .font-family-input-ct,
1942
1993
  .font-weight-input-ct {
1943
1994
  width: 185px !important;
@@ -1989,12 +2040,28 @@
1989
2040
  background-color: hsl(var(--light-green)) !important;
1990
2041
  }
1991
2042
 
1992
- /* Optimize font popover rendering */
2043
+ .font-family-input-ct :global(button:focus),
2044
+ .font-family-input-ct :global(button:focus-visible),
2045
+ .font-weight-input-ct :global(button:focus),
2046
+ .font-weight-input-ct :global(button:focus-visible),
2047
+ :global(.font-input-popover button:focus),
2048
+ :global(.font-input-popover button:focus-visible),
2049
+ :global(.font-list-row:focus),
2050
+ :global(.font-list-row:focus-visible),
2051
+ :global(.font-input-popover [data-item]:focus),
2052
+ :global(.font-input-popover [data-item]:focus-visible) {
2053
+ outline: none;
2054
+ box-shadow: none;
2055
+ }
2056
+
2057
+ /* Clamp to the viewport so the Fonts header and list stay on screen */
1993
2058
  :global(.font-input-popover) {
1994
2059
  z-index: 50;
1995
2060
  will-change: transform;
1996
2061
  transform: translateZ(0);
1997
2062
  backface-visibility: hidden;
2063
+ max-width: calc(100vw - 16px) !important;
2064
+ overflow: hidden;
1998
2065
  }
1999
2066
 
2000
2067
  :global(.font-popover-content) {
@@ -2034,14 +2101,20 @@
2034
2101
  z-index: 10; /* Ensure it appears above other content */
2035
2102
  }
2036
2103
 
2037
- /* Prevent hover effect on selected items */
2038
- :global(.selected-item:hover) {
2039
- background-color: hsl(var(--sage-green)) !important;
2104
+ /* Selected row only — never leave white text on a white (deselected) row. */
2105
+ :global(.font-list-row.selected-item),
2106
+ :global([data-item].selected-item) {
2040
2107
  color: white !important;
2041
2108
  }
2042
-
2043
- /* Ensure text is white in selected items */
2044
- :global(.selected-item) {
2109
+ :global(.font-list-row:not(.selected-item)),
2110
+ :global([data-item]:not(.selected-item)) {
2111
+ color: hsl(var(--grey7)) !important;
2112
+ }
2113
+
2114
+ /* Prevent hover from keeping sage+white on a row that is no longer selected. */
2115
+ :global(.font-list-row.selected-item:hover),
2116
+ :global([data-item].selected-item:hover) {
2117
+ background-color: hsl(var(--sage-green)) !important;
2045
2118
  color: white !important;
2046
2119
  }
2047
2120
 
@@ -23,7 +23,9 @@ declare const FontInputController: $$__sveltets_2_IsomorphicComponent<{
23
23
  * @prop {any} openDropdowns - Store tracking open dropdown states
24
24
  * @prop {Function} toggleDropdown - Function to toggle dropdown state
25
25
  * @prop {Function} onFocus - Optional focus handler
26
- */ label: string;
26
+ */ label?: string;
27
+ class?: string;
28
+ style?: string;
27
29
  value?: {
28
30
  family: string;
29
31
  weight: string;
@@ -57,9 +57,9 @@
57
57
 
58
58
  if (!isEditing && !bothBoundsUndefined) {
59
59
  if (value < minValue || value > maxValue) {
60
- console.log('Value out of bounds, adjusting:', {
61
- value, minValue, maxValue, isEditing
62
- });
60
+ // console.log('Value out of bounds, adjusting:', {
61
+ // value, minValue, maxValue, isEditing
62
+ // });
63
63
  const clampedValue = Math.max(minValue, Math.min(maxValue, value));
64
64
  value = clampedValue;
65
65
  if (typeof onChange === 'function') {
@@ -98,24 +98,24 @@
98
98
  */
99
99
  function handleValueChange(adjustment: number) {
100
100
  try {
101
- console.log('🔄 handleValueChange:', { currentValue: value, adjustment, min, max });
101
+ // console.log('🔄 handleValueChange:', { currentValue: value, adjustment, min, max });
102
102
  const newValue = value + adjustment;
103
103
 
104
104
  if (min !== undefined && newValue < min) {
105
- console.log('⚠️ Value would go below min, clamping to:', min);
105
+ // console.log('⚠️ Value would go below min, clamping to:', min);
106
106
  value = min;
107
107
  if (onChange) onChange(min);
108
108
  return;
109
109
  }
110
110
 
111
111
  if (max !== undefined && newValue > max) {
112
- console.log('⚠️ Value would exceed max, clamping to:', max);
112
+ // console.log('⚠️ Value would exceed max, clamping to:', max);
113
113
  value = max;
114
114
  if (onChange) onChange(max);
115
115
  return;
116
116
  }
117
117
 
118
- console.log('✅ Setting new value:', newValue);
118
+ // console.log('✅ Setting new value:', newValue);
119
119
  value = newValue;
120
120
  if (onChange) onChange(newValue);
121
121
  } catch (error) {
@@ -132,24 +132,24 @@
132
132
  const input = e.currentTarget as HTMLInputElement;
133
133
  const inputValue = input.value;
134
134
 
135
- console.log('handleInput start:', {
136
- inputValue,
137
- isEditing,
138
- currentValue: value,
139
- min,
140
- max
141
- });
135
+ // console.log('handleInput start:', {
136
+ // inputValue,
137
+ // isEditing,
138
+ // currentValue: value,
139
+ // min,
140
+ // max
141
+ // });
142
142
 
143
143
  // Handle empty input
144
144
  if (inputValue === '') {
145
- console.log('Empty input detected - allowing editing');
145
+ // console.log('Empty input detected - allowing editing');
146
146
  isEditing = true;
147
147
  return;
148
148
  }
149
149
 
150
150
  // Prevent multiple minus signs
151
151
  if (inputValue.split('-').length > 2) {
152
- console.log('Multiple minus signs detected, preventing');
152
+ // console.log('Multiple minus signs detected, preventing');
153
153
  input.value = inputValue.charAt(0) === '-' ?
154
154
  '-' + inputValue.replace(/-/g, '') :
155
155
  inputValue.replace(/-/g, '');
@@ -158,14 +158,14 @@
158
158
 
159
159
  // Allow single minus sign for negative numbers
160
160
  if (inputValue === '-' && min! < 0) {
161
- console.log('Single minus sign detected');
161
+ // console.log('Single minus sign detected');
162
162
  isEditing = true;
163
163
  return;
164
164
  }
165
165
 
166
166
  // Validate numeric input
167
167
  if (!/^-?\d*$/.test(inputValue)) {
168
- console.log('Invalid character detected');
168
+ // console.log('Invalid character detected');
169
169
  input.value = inputValue.replace(/[^\d-]/g, '');
170
170
  return;
171
171
  }
@@ -173,7 +173,7 @@
173
173
  const numValue = parseFloat(inputValue);
174
174
  if (!isNaN(numValue)) {
175
175
  if (max !== undefined && numValue > max) {
176
- console.log('Number exceeds max:', { numValue, max });
176
+ // console.log('Number exceeds max:', { numValue, max });
177
177
  input.value = String(max);
178
178
  value = max;
179
179
  return;
@@ -190,7 +190,7 @@
190
190
  * Validates and normalizes input when focus is lost
191
191
  */
192
192
  function handleBlur() {
193
- console.log('handleBlur:', { value, isEditing, min, max });
193
+ // console.log('handleBlur:', { value, isEditing, min, max });
194
194
 
195
195
  isEditing = false;
196
196
  const input = document.getElementById('number-input') as HTMLInputElement;
@@ -228,7 +228,7 @@
228
228
  * Handles continuous increment/decrement while button is held
229
229
  */
230
230
  function startAutoRepeat(operation: 'increment' | 'decrement', event: MouseEvent) {
231
- console.log('🎯 startAutoRepeat called:', { operation });
231
+ // console.log('🎯 startAutoRepeat called:', { operation });
232
232
  event.preventDefault();
233
233
  event.stopPropagation();
234
234
 
@@ -239,20 +239,20 @@
239
239
  isPressed = true;
240
240
 
241
241
  // Handle initial click
242
- console.log('👆 Initial click, applying adjustment:', adjustment);
242
+ // console.log('👆 Initial click, applying adjustment:', adjustment);
243
243
  handleValueChange(adjustment);
244
244
 
245
245
  // Set up auto-repeat
246
- console.log('⏳ Setting up auto-repeat timer for', HOLD_DELAY, 'ms');
246
+ // console.log('⏳ Setting up auto-repeat timer for', HOLD_DELAY, 'ms');
247
247
 
248
248
  // Start auto-repeat after hold delay
249
249
  autoRepeatTimer = setTimeout(() => {
250
- console.log('⌛ Hold delay completed, isPressed:', isPressed);
250
+ // console.log('⌛ Hold delay completed, isPressed:', isPressed);
251
251
  if (isPressed) {
252
- console.log('🔄 Starting interval timer with delay:', REPEAT_INTERVAL);
252
+ // console.log('🔄 Starting interval timer with delay:', REPEAT_INTERVAL);
253
253
  autoRepeatInterval = setInterval(() => {
254
254
  if (isPressed) {
255
- console.log('⚡ Interval tick - applying adjustment:', adjustment);
255
+ // console.log('⚡ Interval tick - applying adjustment:', adjustment);
256
256
  handleValueChange(adjustment);
257
257
  }
258
258
  }, REPEAT_INTERVAL);
@@ -270,15 +270,15 @@
270
270
  event.stopPropagation();
271
271
  }
272
272
 
273
- console.log('🛑 stopAutoRepeat called');
273
+ // console.log('🛑 stopAutoRepeat called');
274
274
 
275
275
  if (autoRepeatTimer) {
276
- console.log('🧹 Clearing auto-repeat timer');
276
+ // console.log('🧹 Clearing auto-repeat timer');
277
277
  clearTimeout(autoRepeatTimer);
278
278
  autoRepeatTimer = undefined;
279
279
  }
280
280
  if (autoRepeatInterval) {
281
- console.log('🧹 Clearing auto-repeat interval');
281
+ // console.log('🧹 Clearing auto-repeat interval');
282
282
  clearInterval(autoRepeatInterval);
283
283
  autoRepeatInterval = undefined;
284
284
  }
@@ -291,7 +291,7 @@
291
291
  * Ensures auto-repeat timer is cleared when component is destroyed
292
292
  */
293
293
  onDestroy(() => {
294
- console.log('♻️ Component destroying, cleaning up timers');
294
+ // console.log('♻️ Component destroying, cleaning up timers');
295
295
  stopAutoRepeat();
296
296
  });
297
297
 
@@ -321,16 +321,16 @@
321
321
  * Manages keyboard interactions and shortcuts
322
322
  */
323
323
  function handleKeyDown(e: KeyboardEvent) {
324
- console.log('handleKeyDown:', {
325
- key: e.key,
326
- metaKey: e.metaKey,
327
- ctrlKey: e.ctrlKey,
328
- isEditing
329
- });
324
+ // console.log('handleKeyDown:', {
325
+ // key: e.key,
326
+ // metaKey: e.metaKey,
327
+ // ctrlKey: e.ctrlKey,
328
+ // isEditing
329
+ // });
330
330
 
331
331
  // Handle selection shortcuts
332
332
  if ((e.metaKey || e.ctrlKey) && e.key === 'a') {
333
- console.log('CMD+A detected, setting editing mode');
333
+ // console.log('CMD+A detected, setting editing mode');
334
334
  isEditing = true;
335
335
  return;
336
336
  }
@@ -44,7 +44,7 @@
44
44
  * @param newValue - The newly selected value
45
45
  */
46
46
  function handleValueChange(newValue: string) {
47
- console.log('RadioGroupInputController: handleValueChange', newValue);
47
+ // console.log('RadioGroupInputController: handleValueChange', newValue);
48
48
  localValue = newValue;
49
49
  onChange(newValue);
50
50
  }
@@ -84,7 +84,7 @@
84
84
  const adjustedValue = validateAndAdjustValue(value);
85
85
 
86
86
  if (adjustedValue[0] !== value[0] || adjustedValue[1] !== value[1]) {
87
- console.log('Adjusting initial range values to match constraints:', { original: value, adjusted: adjustedValue });
87
+ // console.log('Adjusting initial range values to match constraints:', { original: value, adjusted: adjustedValue });
88
88
  value = adjustedValue;
89
89
 
90
90
  // Wait for next tick to prevent scroll jump
@@ -15,7 +15,7 @@
15
15
 
16
16
  function toggle(newValue?: boolean) {
17
17
  value = typeof newValue === 'boolean' ? newValue : !value;
18
- console.log('[SwitchIC] Toggled:', { label, value });
18
+ // console.log('[SwitchIC] Toggled:', { label, value });
19
19
  onChange(value);
20
20
  }
21
21
  </script>