@seekora-ai/ui-sdk-react 0.2.14 → 0.2.15

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 (66) hide show
  1. package/dist/components/CurrentRefinements.d.ts.map +1 -1
  2. package/dist/components/CurrentRefinements.js +69 -9
  3. package/dist/components/FacetDropdown.d.ts +92 -0
  4. package/dist/components/FacetDropdown.d.ts.map +1 -0
  5. package/dist/components/FacetDropdown.js +374 -0
  6. package/dist/components/Facets.d.ts +26 -0
  7. package/dist/components/Facets.d.ts.map +1 -1
  8. package/dist/components/Facets.js +195 -6
  9. package/dist/components/FederatedDropdown.d.ts.map +1 -1
  10. package/dist/components/FederatedDropdown.js +45 -31
  11. package/dist/components/QuerySuggestionsDropdown.d.ts.map +1 -1
  12. package/dist/components/QuerySuggestionsDropdown.js +32 -18
  13. package/dist/components/RangeInput.d.ts.map +1 -1
  14. package/dist/components/RangeInput.js +6 -6
  15. package/dist/components/RangeSlider.d.ts.map +1 -1
  16. package/dist/components/RangeSlider.js +54 -32
  17. package/dist/components/RichQuerySuggestions.d.ts.map +1 -1
  18. package/dist/components/RichQuerySuggestions.js +40 -26
  19. package/dist/components/SearchBar.d.ts.map +1 -1
  20. package/dist/components/SearchBar.js +15 -7
  21. package/dist/components/SearchBarWithSuggestions.js +3 -3
  22. package/dist/components/SearchLayout.d.ts.map +1 -1
  23. package/dist/components/SearchLayout.js +10 -1
  24. package/dist/components/SearchResults.d.ts.map +1 -1
  25. package/dist/components/SearchResults.js +37 -25
  26. package/dist/components/primitives/ActionButtons.d.ts.map +1 -1
  27. package/dist/components/primitives/ActionButtons.js +34 -10
  28. package/dist/components/primitives/BadgeList.d.ts.map +1 -1
  29. package/dist/components/primitives/BadgeList.js +33 -13
  30. package/dist/components/primitives/ImageDisplay.d.ts.map +1 -1
  31. package/dist/components/primitives/ImageDisplay.js +11 -8
  32. package/dist/components/primitives/ImageZoom.js +26 -26
  33. package/dist/components/primitives/VariantSelector.js +10 -10
  34. package/dist/components/primitives/VariantSwatches.js +3 -3
  35. package/dist/components/product-page/ProductGallery.d.ts +8 -1
  36. package/dist/components/product-page/ProductGallery.d.ts.map +1 -1
  37. package/dist/components/product-page/ProductGallery.js +2 -2
  38. package/dist/components/section-primitives/SectionSearchProvider.d.ts +3 -1
  39. package/dist/components/section-primitives/SectionSearchProvider.d.ts.map +1 -1
  40. package/dist/components/section-primitives/SectionSearchProvider.js +3 -2
  41. package/dist/components/suggestions/MobileSheetDropdown.js +18 -18
  42. package/dist/components/suggestions/ShopifyDropdown.js +37 -37
  43. package/dist/components/suggestions-primitives/DropdownPanel.d.ts.map +1 -1
  44. package/dist/components/suggestions-primitives/DropdownPanel.js +15 -2
  45. package/dist/components/suggestions-primitives/ItemCard.d.ts.map +1 -1
  46. package/dist/components/suggestions-primitives/ItemCard.js +21 -8
  47. package/dist/components/suggestions-primitives/ItemGrid.d.ts.map +1 -1
  48. package/dist/components/suggestions-primitives/ItemGrid.js +9 -3
  49. package/dist/components/suggestions-primitives/ProductCard.d.ts.map +1 -1
  50. package/dist/components/suggestions-primitives/ProductCard.js +25 -10
  51. package/dist/components/suggestions-primitives/ProductCardLayouts.d.ts.map +1 -1
  52. package/dist/components/suggestions-primitives/ProductCardLayouts.js +24 -12
  53. package/dist/components/suggestions-primitives/SearchInput.d.ts.map +1 -1
  54. package/dist/components/suggestions-primitives/SearchInput.js +28 -9
  55. package/dist/components/suggestions-primitives/SuggestionItem.d.ts.map +1 -1
  56. package/dist/components/suggestions-primitives/SuggestionItem.js +3 -0
  57. package/dist/index.d.ts +3 -1
  58. package/dist/index.d.ts.map +1 -1
  59. package/dist/index.js +1 -0
  60. package/dist/index.umd.js +1 -1
  61. package/dist/src/index.d.ts +129 -4
  62. package/dist/src/index.esm.js +1361 -616
  63. package/dist/src/index.esm.js.map +1 -1
  64. package/dist/src/index.js +1361 -615
  65. package/dist/src/index.js.map +1 -1
  66. package/package.json +6 -6
@@ -9,6 +9,7 @@ import { useSearchContext } from './SearchProvider';
9
9
  import { useSearchState } from '../hooks/useSearchState';
10
10
  import { log } from '@seekora-ai/ui-sdk-core';
11
11
  import { clsx } from 'clsx';
12
+ import { RangeSlider } from './RangeSlider';
12
13
  // ---------------------------------------------------------------------------
13
14
  // Helpers
14
15
  // ---------------------------------------------------------------------------
@@ -52,17 +53,19 @@ const CheckmarkIcon = ({ size = 16 }) => (React.createElement("svg", { width: si
52
53
  // CSS variable defaults
53
54
  // ---------------------------------------------------------------------------
54
55
  const CSS_VAR_DEFAULTS = {
55
- '--seekora-facet-bg': '#ffffff',
56
+ '--seekora-facet-bg': 'transparent',
56
57
  '--seekora-facet-border': '#dee2e6',
57
- '--seekora-facet-active-bg': '#f0f7ff',
58
+ '--seekora-facet-active-bg': 'rgba(0, 0, 0, 0.05)',
58
59
  '--seekora-facet-swatch-size': '32px',
59
60
  '--seekora-facet-count-bg': '#e9ecef',
60
61
  '--seekora-facet-count-color': '#495057',
62
+ '--seekora-primary': '#3b82f6',
63
+ '--seekora-primary-text': '#ffffff',
61
64
  };
62
65
  // ---------------------------------------------------------------------------
63
66
  // Component
64
67
  // ---------------------------------------------------------------------------
65
- export const Facets = ({ results: resultsProp, facets: facetsProp, onFacetChange, renderFacet, renderFacetItem, maxItems = 10, showMore = true, className, style, theme: customTheme, variant = 'checkbox', searchable = false, showCounts = true, colorMap, defaultCollapsed = false, size = 'medium', }) => {
68
+ export const Facets = ({ results: resultsProp, facets: facetsProp, onFacetChange, renderFacet, renderFacetItem, maxItems = 10, showMore = true, className, style, theme: customTheme, variant = 'checkbox', searchable = false, showCounts = true, colorMap, defaultCollapsed = false, size = 'medium', facetRanges, }) => {
66
69
  const { theme } = useSearchContext();
67
70
  const { results: stateResults, refinements, addRefinement, removeRefinement } = useSearchState();
68
71
  const facetsTheme = customTheme || {};
@@ -112,6 +115,7 @@ export const Facets = ({ results: resultsProp, facets: facetsProp, onFacetChange
112
115
  count: count.count,
113
116
  selected: refinements.some(r => r.field === fieldName && r.value === count.value),
114
117
  })) : [],
118
+ stats: facet.stats || undefined,
115
119
  };
116
120
  });
117
121
  log.verbose('Facets: Extracted facets', {
@@ -189,7 +193,7 @@ export const Facets = ({ results: resultsProp, facets: facetsProp, onFacetChange
189
193
  const sizeScale = useMemo(() => {
190
194
  switch (size) {
191
195
  case 'small':
192
- return { font: theme.typography.fontSize.small, padding: '0.25rem', gap: '0.25rem' };
196
+ return { font: theme.typography.fontSize.small, padding: '0.5rem', gap: '0.5rem' };
193
197
  case 'large':
194
198
  return { font: theme.typography.fontSize.large, padding: '0.75rem', gap: '0.75rem' };
195
199
  case 'medium':
@@ -258,6 +262,7 @@ export const Facets = ({ results: resultsProp, facets: facetsProp, onFacetChange
258
262
  ? 'var(--seekora-facet-active-bg, ' + theme.colors.hover + ')'
259
263
  : 'transparent',
260
264
  transition: 'background-color 0.2s ease',
265
+ boxSizing: 'border-box',
261
266
  } },
262
267
  React.createElement("input", { type: "checkbox", checked: refinements.some(r => r.field === facet.field && r.value === item.value) || item.selected || false, onChange: () => handleFacetToggle(facet.field, item.value, item.selected || false), className: facetsTheme.checkbox, style: {
263
268
  marginRight: sizeScale.gap,
@@ -266,6 +271,7 @@ export const Facets = ({ results: resultsProp, facets: facetsProp, onFacetChange
266
271
  React.createElement("span", { className: facetsTheme.facetItemLabel, style: {
267
272
  flex: 1,
268
273
  fontSize: sizeScale.font,
274
+ lineHeight: 1.5,
269
275
  color: theme.colors.text,
270
276
  } }, item.value),
271
277
  renderCountBadge(item.count)));
@@ -294,13 +300,13 @@ export const Facets = ({ results: resultsProp, facets: facetsProp, onFacetChange
294
300
  borderRadius: '50%',
295
301
  backgroundColor: color,
296
302
  border: isChecked
297
- ? `3px solid ${theme.colors.primary}`
303
+ ? `3px solid var(--seekora-primary, ${theme.colors.primary})`
298
304
  : `2px solid var(--seekora-facet-border, ${theme.colors.border})`,
299
305
  display: 'flex',
300
306
  alignItems: 'center',
301
307
  justifyContent: 'center',
302
308
  transition: 'border 0.2s ease, box-shadow 0.2s ease',
303
- boxShadow: isChecked ? `0 0 0 2px ${theme.colors.primary}33` : 'none',
309
+ boxShadow: isChecked ? `0 0 0 2px var(--seekora-primary-alpha, ${theme.colors.primary}33)` : 'none',
304
310
  position: 'relative',
305
311
  } }, isChecked && (React.createElement("span", { className: clsx(facetsTheme.colorSwatchInner), style: {
306
312
  display: 'flex',
@@ -526,9 +532,192 @@ export const Facets = ({ results: resultsProp, facets: facetsProp, onFacetChange
526
532
  } }, "Show less"))))));
527
533
  };
528
534
  // -------------------------------------------------------------------
535
+ // Render-type detection for numeric / range facets
536
+ // -------------------------------------------------------------------
537
+ const determineFacetRenderType = (fieldName, stats) => {
538
+ // If explicit range config exists for this field → range buttons
539
+ if (facetRanges?.some((rc) => rc.field === fieldName)) {
540
+ return 'range-buttons';
541
+ }
542
+ // If stats with valid min/max → range slider
543
+ if (stats && typeof stats.min === 'number' && typeof stats.max === 'number' && stats.min !== stats.max) {
544
+ return 'range-slider';
545
+ }
546
+ return 'list';
547
+ };
548
+ // -------------------------------------------------------------------
549
+ // Range button facet renderer
550
+ // -------------------------------------------------------------------
551
+ const renderRangeButtonFacet = (facet, _index) => {
552
+ const rangeConfig = facetRanges?.find((rc) => rc.field === facet.field);
553
+ if (!rangeConfig)
554
+ return null;
555
+ // Build a lookup from item value → count
556
+ const countMap = new Map();
557
+ facet.items.forEach((item) => countMap.set(item.value, item.count));
558
+ // Detect currently active range from refinements
559
+ const activeMin = refinements.find((r) => r.field === facet.field && r.value.startsWith('>='));
560
+ const activeMax = refinements.find((r) => r.field === facet.field && r.value.startsWith('<='));
561
+ const activeFromVal = activeMin ? parseFloat(activeMin.value.slice(2)) : undefined;
562
+ const activeToVal = activeMax ? parseFloat(activeMax.value.slice(2)) : undefined;
563
+ const isRangeActive = (range) => {
564
+ const fromMatch = range.from === undefined
565
+ ? activeFromVal === undefined
566
+ : activeFromVal === range.from;
567
+ const toMatch = range.to === undefined
568
+ ? activeToVal === undefined
569
+ : activeToVal === range.to;
570
+ return fromMatch && toMatch;
571
+ };
572
+ const handleRangeClick = (range) => {
573
+ // Clear existing range refinements for this field
574
+ refinements
575
+ .filter((r) => r.field === facet.field)
576
+ .forEach((r) => removeRefinement(facet.field, r.value, false));
577
+ if (isRangeActive(range)) {
578
+ // Was active → just clear (already removed above), trigger search
579
+ addRefinement(facet.field, '__noop__', false);
580
+ removeRefinement(facet.field, '__noop__', true);
581
+ return;
582
+ }
583
+ // Set new range
584
+ if (range.from !== undefined) {
585
+ addRefinement(facet.field, `>=${range.from}`, false);
586
+ }
587
+ if (range.to !== undefined) {
588
+ addRefinement(facet.field, `<=${range.to}`, true);
589
+ }
590
+ else if (range.from !== undefined) {
591
+ // Only "from" set — trigger search
592
+ addRefinement(facet.field, `>=${range.from}`, true);
593
+ }
594
+ };
595
+ const hasActiveRange = activeMin !== undefined || activeMax !== undefined;
596
+ const handleClear = () => {
597
+ refinements
598
+ .filter((r) => r.field === facet.field)
599
+ .forEach((r) => removeRefinement(facet.field, r.value, false));
600
+ // Trigger search after clearing
601
+ addRefinement(facet.field, '__noop__', false);
602
+ removeRefinement(facet.field, '__noop__', true);
603
+ };
604
+ return (React.createElement("div", { key: facet.field, className: facetsTheme.facet, style: {
605
+ marginBottom: theme.spacing.large,
606
+ padding: theme.spacing.medium,
607
+ backgroundColor: 'var(--seekora-facet-bg, ' + theme.colors.background + ')',
608
+ border: `1px solid var(--seekora-facet-border, ${theme.colors.border})`,
609
+ borderRadius: typeof theme.borderRadius === 'string' ? theme.borderRadius : theme.borderRadius.medium,
610
+ } },
611
+ React.createElement("h3", { className: facetsTheme.facetTitle, style: {
612
+ fontSize: theme.typography.fontSize.large,
613
+ fontWeight: 'bold',
614
+ margin: 0,
615
+ marginBottom: theme.spacing.medium,
616
+ color: theme.colors.text,
617
+ } }, facet.label || facet.field),
618
+ React.createElement("div", { style: {
619
+ display: 'flex',
620
+ flexWrap: 'wrap',
621
+ gap: sizeScale.gap,
622
+ } }, rangeConfig.ranges.map((range) => {
623
+ const count = countMap.get(range.label) ?? 0;
624
+ const active = isRangeActive(range);
625
+ return (React.createElement("button", { key: range.label, type: "button", className: clsx(facetsTheme.rangeButton, active && facetsTheme.rangeButtonActive), disabled: count === 0 && !active, onClick: () => handleRangeClick(range), style: {
626
+ display: 'inline-flex',
627
+ alignItems: 'center',
628
+ gap: '0.35em',
629
+ padding: `${sizeScale.padding} 0.75em`,
630
+ fontSize: sizeScale.font,
631
+ border: `1px solid ${active ? 'var(--seekora-primary, ' + theme.colors.primary + ')' : 'var(--seekora-facet-border, ' + theme.colors.border + ')'}`,
632
+ borderRadius: typeof theme.borderRadius === 'string' ? theme.borderRadius : theme.borderRadius.full,
633
+ backgroundColor: active ? 'var(--seekora-primary, ' + theme.colors.primary + ')' : 'var(--seekora-facet-bg, ' + theme.colors.background + ')',
634
+ color: active ? 'var(--seekora-primary-text, #fff)' : theme.colors.text,
635
+ cursor: count === 0 && !active ? 'not-allowed' : 'pointer',
636
+ opacity: count === 0 && !active ? 0.5 : 1,
637
+ transition: 'all 0.2s ease',
638
+ } },
639
+ range.label,
640
+ showCounts && (React.createElement("span", { className: clsx(facetsTheme.rangeButtonCount), style: {
641
+ fontSize: theme.typography.fontSize.small,
642
+ opacity: 0.8,
643
+ } },
644
+ "(",
645
+ count,
646
+ ")"))));
647
+ })),
648
+ hasActiveRange && (React.createElement("button", { type: "button", className: clsx(facetsTheme.rangeClear), onClick: handleClear, style: {
649
+ marginTop: sizeScale.gap,
650
+ padding: sizeScale.padding,
651
+ border: 'none',
652
+ backgroundColor: 'transparent',
653
+ color: theme.colors.primary,
654
+ cursor: 'pointer',
655
+ fontSize: theme.typography.fontSize.small,
656
+ textDecoration: 'underline',
657
+ } }, "Clear"))));
658
+ };
659
+ // -------------------------------------------------------------------
660
+ // Range slider facet renderer
661
+ // -------------------------------------------------------------------
662
+ const renderRangeSliderFacet = (facet, _index) => {
663
+ if (!facet.stats)
664
+ return null;
665
+ const { min: statsMin, max: statsMax } = facet.stats;
666
+ // Auto-detect formatting for common field names
667
+ const fieldLower = facet.field.toLowerCase();
668
+ const isPriceField = fieldLower.includes('price') || fieldLower.includes('cost') || fieldLower.includes('amount');
669
+ const formatValue = isPriceField
670
+ ? (v) => `$${v.toFixed(2)}`
671
+ : (v) => v.toString();
672
+ // Determine step: use 0.01 for price, 1 for integer ranges, 0.1 otherwise
673
+ const range = statsMax - statsMin;
674
+ const step = isPriceField ? 0.01 : range > 10 ? 1 : 0.1;
675
+ // Check if there's an active range refinement
676
+ const hasActiveRange = refinements.some((r) => r.field === facet.field && (r.value.startsWith('>=') || r.value.startsWith('<=')));
677
+ const handleClear = () => {
678
+ refinements
679
+ .filter((r) => r.field === facet.field && (r.value.startsWith('>=') || r.value.startsWith('<=')))
680
+ .forEach((r) => removeRefinement(facet.field, r.value, false));
681
+ // Trigger search after clearing
682
+ addRefinement(facet.field, '__noop__', false);
683
+ removeRefinement(facet.field, '__noop__', true);
684
+ };
685
+ return (React.createElement("div", { key: facet.field, className: facetsTheme.facet, style: {
686
+ marginBottom: theme.spacing.large,
687
+ padding: theme.spacing.medium,
688
+ backgroundColor: 'var(--seekora-facet-bg, ' + theme.colors.background + ')',
689
+ border: `1px solid var(--seekora-facet-border, ${theme.colors.border})`,
690
+ borderRadius: typeof theme.borderRadius === 'string' ? theme.borderRadius : theme.borderRadius.medium,
691
+ } },
692
+ React.createElement("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: theme.spacing.small } },
693
+ React.createElement("h3", { className: facetsTheme.facetTitle, style: {
694
+ fontSize: theme.typography.fontSize.large,
695
+ fontWeight: 'bold',
696
+ margin: 0,
697
+ color: theme.colors.text,
698
+ } }, facet.label || facet.field),
699
+ hasActiveRange && (React.createElement("button", { type: "button", className: clsx(facetsTheme.rangeClear), onClick: handleClear, style: {
700
+ padding: '0.15em 0.5em',
701
+ border: 'none',
702
+ backgroundColor: 'transparent',
703
+ color: theme.colors.primary,
704
+ cursor: 'pointer',
705
+ fontSize: theme.typography.fontSize.small,
706
+ textDecoration: 'underline',
707
+ } }, "Clear"))),
708
+ React.createElement(RangeSlider, { field: facet.field, min: statsMin, max: statsMax, step: step, formatValue: formatValue, syncWithState: true })));
709
+ };
710
+ // -------------------------------------------------------------------
529
711
  // Default facet renderer dispatcher
530
712
  // -------------------------------------------------------------------
531
713
  const defaultRenderFacet = (facet, index) => {
714
+ const renderType = determineFacetRenderType(facet.field, facet.stats);
715
+ if (renderType === 'range-buttons') {
716
+ return renderRangeButtonFacet(facet, index);
717
+ }
718
+ if (renderType === 'range-slider') {
719
+ return renderRangeSliderFacet(facet, index);
720
+ }
532
721
  switch (variant) {
533
722
  case 'color-swatch':
534
723
  return renderColorSwatchFacet(facet, index);
@@ -1 +1 @@
1
- {"version":3,"file":"FederatedDropdown.d.ts","sourceRoot":"","sources":["../../src/components/FederatedDropdown.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FederatedDropdown.d.ts","sourceRoot":"","sources":["../../src/components/FederatedDropdown.tsx"],"names":[],"mappings":"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"}
@@ -15,20 +15,34 @@ import { useSearchContext } from './SearchProvider';
15
15
  import { useQuerySuggestionsEnhanced } from '../hooks/useQuerySuggestionsEnhanced';
16
16
  import { clsx } from 'clsx';
17
17
  // ============================================================================
18
+ // Constants
19
+ // ============================================================================
20
+ const TRANSITIONS = {
21
+ fast: '150ms ease-in-out',
22
+ normal: '200ms ease-in-out',
23
+ slow: '300ms ease-in-out',
24
+ };
25
+ const BORDER_RADIUS = {
26
+ sm: 4,
27
+ md: 6,
28
+ lg: 8,
29
+ full: 9999,
30
+ };
31
+ // ============================================================================
18
32
  // Styles
19
33
  // ============================================================================
20
34
  const styles = {
21
35
  container: {
22
- backgroundColor: 'var(--seekora-bg-surface, #ffffff)',
23
- border: '1px solid var(--seekora-border-color, #e5e7eb)',
24
- borderRadius: 'var(--seekora-border-radius-lg, 12px)',
36
+ backgroundColor: 'var(--seekora-bg-surface, transparent)',
37
+ border: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
38
+ borderRadius: `var(--seekora-border-radius-lg, ${BORDER_RADIUS.lg * 1.5}px)`,
25
39
  boxShadow: '0 25px 50px -12px rgba(0, 0, 0, 0.25)',
26
40
  overflow: 'hidden',
27
41
  },
28
42
  header: {
29
43
  padding: '12px 20px',
30
- borderBottom: '1px solid var(--seekora-border-color, #e5e7eb)',
31
- backgroundColor: 'var(--seekora-bg-secondary, #f9fafb)',
44
+ borderBottom: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
45
+ backgroundColor: 'var(--seekora-bg-secondary, rgba(255, 255, 255, 0.1))',
32
46
  },
33
47
  content: {
34
48
  display: 'flex',
@@ -38,13 +52,13 @@ const styles = {
38
52
  flexDirection: 'column',
39
53
  },
40
54
  suggestionsColumn: {
41
- borderRight: '1px solid var(--seekora-border-color, #e5e7eb)',
55
+ borderRight: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
42
56
  overflowY: 'auto',
43
57
  },
44
58
  productsColumn: {
45
59
  flex: 1,
46
60
  overflowY: 'auto',
47
- backgroundColor: 'var(--seekora-bg-secondary, #fafafa)',
61
+ backgroundColor: 'var(--seekora-bg-secondary, rgba(255, 255, 255, 0.1))',
48
62
  },
49
63
  section: {
50
64
  padding: '12px 0',
@@ -75,7 +89,7 @@ const styles = {
75
89
  alignItems: 'center',
76
90
  padding: '10px 20px',
77
91
  cursor: 'pointer',
78
- transition: 'background-color 100ms ease',
92
+ transition: `background-color ${TRANSITIONS.fast}`,
79
93
  gap: '12px',
80
94
  },
81
95
  suggestionItemActive: {
@@ -90,7 +104,7 @@ const styles = {
90
104
  suggestionText: {
91
105
  flex: 1,
92
106
  fontSize: '14px',
93
- color: 'var(--seekora-text-primary, #111827)',
107
+ color: 'var(--seekora-text-primary, inherit)',
94
108
  fontWeight: 500,
95
109
  overflow: 'hidden',
96
110
  textOverflow: 'ellipsis',
@@ -114,7 +128,7 @@ const styles = {
114
128
  display: 'flex',
115
129
  gap: '4px',
116
130
  padding: '12px 20px',
117
- borderBottom: '1px solid var(--seekora-border-color, #e5e7eb)',
131
+ borderBottom: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
118
132
  overflowX: 'auto',
119
133
  },
120
134
  tab: {
@@ -124,13 +138,13 @@ const styles = {
124
138
  padding: '8px 16px',
125
139
  fontSize: '13px',
126
140
  fontWeight: 500,
127
- color: 'var(--seekora-text-secondary, #6b7280)',
141
+ color: 'var(--seekora-text-secondary, inherit)',
128
142
  backgroundColor: 'transparent',
129
143
  border: '1px solid transparent',
130
- borderRadius: '20px',
144
+ borderRadius: `${BORDER_RADIUS.full}px`,
131
145
  cursor: 'pointer',
132
146
  whiteSpace: 'nowrap',
133
- transition: 'all 150ms ease',
147
+ transition: `all ${TRANSITIONS.fast}`,
134
148
  },
135
149
  tabActive: {
136
150
  color: 'var(--seekora-primary, #3b82f6)',
@@ -141,8 +155,8 @@ const styles = {
141
155
  fontSize: '11px',
142
156
  fontWeight: 600,
143
157
  padding: '2px 6px',
144
- borderRadius: '10px',
145
- backgroundColor: 'var(--seekora-bg-tertiary, #e5e7eb)',
158
+ borderRadius: `${BORDER_RADIUS.lg}px`,
159
+ backgroundColor: 'var(--seekora-bg-tertiary, rgba(255, 255, 255, 0.1))',
146
160
  },
147
161
  tabCountActive: {
148
162
  backgroundColor: 'var(--seekora-primary, #3b82f6)',
@@ -157,12 +171,12 @@ const styles = {
157
171
  productCard: {
158
172
  display: 'flex',
159
173
  flexDirection: 'column',
160
- backgroundColor: 'var(--seekora-bg-surface, #ffffff)',
161
- borderRadius: '8px',
174
+ backgroundColor: 'var(--seekora-bg-surface, transparent)',
175
+ borderRadius: `${BORDER_RADIUS.lg}px`,
162
176
  overflow: 'hidden',
163
177
  cursor: 'pointer',
164
- transition: 'transform 150ms ease, box-shadow 150ms ease',
165
- border: '1px solid var(--seekora-border-color, #e5e7eb)',
178
+ transition: `transform ${TRANSITIONS.fast}, box-shadow ${TRANSITIONS.fast}`,
179
+ border: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
166
180
  },
167
181
  productCardHover: {
168
182
  transform: 'translateY(-2px)',
@@ -180,7 +194,7 @@ const styles = {
180
194
  productTitle: {
181
195
  fontSize: '13px',
182
196
  fontWeight: 500,
183
- color: 'var(--seekora-text-primary, #111827)',
197
+ color: 'var(--seekora-text-primary, inherit)',
184
198
  margin: 0,
185
199
  overflow: 'hidden',
186
200
  textOverflow: 'ellipsis',
@@ -208,12 +222,12 @@ const styles = {
208
222
  padding: '8px 14px',
209
223
  fontSize: '13px',
210
224
  fontWeight: 500,
211
- color: 'var(--seekora-text-primary, #374151)',
212
- backgroundColor: 'var(--seekora-bg-surface, #ffffff)',
213
- border: '1px solid var(--seekora-border-color, #e5e7eb)',
214
- borderRadius: '8px',
225
+ color: 'var(--seekora-text-primary, inherit)',
226
+ backgroundColor: 'var(--seekora-bg-surface, transparent)',
227
+ border: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
228
+ borderRadius: `${BORDER_RADIUS.lg}px`,
215
229
  cursor: 'pointer',
216
- transition: 'all 150ms ease',
230
+ transition: `all ${TRANSITIONS.fast}`,
217
231
  },
218
232
  brandChipHover: {
219
233
  borderColor: 'var(--seekora-primary, #3b82f6)',
@@ -222,30 +236,30 @@ const styles = {
222
236
  brandLogo: {
223
237
  width: '20px',
224
238
  height: '20px',
225
- borderRadius: '4px',
239
+ borderRadius: `${BORDER_RADIUS.sm}px`,
226
240
  objectFit: 'contain',
227
241
  backgroundColor: 'var(--seekora-bg-secondary, #f3f4f6)',
228
242
  },
229
243
  footer: {
230
244
  padding: '12px 20px',
231
- borderTop: '1px solid var(--seekora-border-color, #e5e7eb)',
232
- backgroundColor: 'var(--seekora-bg-secondary, #f9fafb)',
245
+ borderTop: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
246
+ backgroundColor: 'var(--seekora-bg-secondary, rgba(255, 255, 255, 0.1))',
233
247
  display: 'flex',
234
248
  alignItems: 'center',
235
249
  justifyContent: 'space-between',
236
250
  fontSize: '12px',
237
- color: 'var(--seekora-text-secondary, #6b7280)',
251
+ color: 'var(--seekora-text-secondary, inherit)',
238
252
  },
239
253
  emptyState: {
240
254
  padding: '48px 20px',
241
255
  textAlign: 'center',
242
- color: 'var(--seekora-text-secondary, #6b7280)',
256
+ color: 'var(--seekora-text-secondary, inherit)',
243
257
  },
244
258
  highlight: {
245
259
  backgroundColor: 'var(--seekora-highlight-bg, #fef9c3)',
246
260
  fontWeight: 600,
247
261
  padding: '0 2px',
248
- borderRadius: '2px',
262
+ borderRadius: `${BORDER_RADIUS.sm / 2}px`,
249
263
  },
250
264
  };
251
265
  // ============================================================================
@@ -1 +1 @@
1
- {"version":3,"file":"QuerySuggestionsDropdown.d.ts","sourceRoot":"","sources":["../../src/components/QuerySuggestionsDropdown.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAQN,MAAM,OAAO,CAAC;AAIf,OAAO,KAAK,EACV,cAAc,EACd,YAAY,EACZ,0BAA0B,EAC1B,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,6BAA6B,EAC9B,MAAM,0BAA0B,CAAC;AAMlC,MAAM,WAAW,6BAA8B,SAAQ,6BAA6B;IAClF,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,qCAAqC;IACrC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kDAAkD;IAClD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,2BAA2B;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mCAAmC;IACnC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,yCAAyC;IACzC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,6BAA6B;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yFAAyF;IACzF,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uCAAuC;IACvC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,8BAA8B;IAC9B,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,wCAAwC;IACxC,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,8BAA8B;IAC9B,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,yBAAyB;IACzB,UAAU,CAAC,EAAE,0BAA0B,CAAC;IACxC,wBAAwB;IACxB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,wCAAwC;IACxC,gBAAgB,CAAC,EAAE,CACjB,UAAU,EAAE,cAAc,EAC1B,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,OAAO,EACjB,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,KACzC,KAAK,CAAC,SAAS,CAAC;IACrB,2CAA2C;IAC3C,kBAAkB,CAAC,EAAE,CACnB,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,OAAO,KACd,KAAK,CAAC,SAAS,CAAC;IACrB,sCAAsC;IACtC,aAAa,CAAC,EAAE,MAAM,KAAK,CAAC,SAAS,CAAC;IACtC,oCAAoC;IACpC,WAAW,CAAC,EAAE,MAAM,KAAK,CAAC,SAAS,CAAC;IACpC,4BAA4B;IAC5B,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC;IAChC,qBAAqB;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,2BAA2B;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wCAAwC;IACxC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IAC7C,6BAA6B;IAC7B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,0BAA0B;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,iBAAiB;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,2BAA2B;IAC1C,uCAAuC;IACvC,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,4BAA4B;IAC5B,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,gCAAgC;IAChC,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,sBAAsB;IACtB,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,uBAAuB;IACvB,cAAc,EAAE,MAAM,MAAM,CAAC;IAC7B,4BAA4B;IAC5B,aAAa,EAAE,MAAM,MAAM,CAAC;CAC7B;AAsKD,eAAO,MAAM,wBAAwB,mHAmanC,CAAC;AAEH,eAAe,wBAAwB,CAAC"}
1
+ {"version":3,"file":"QuerySuggestionsDropdown.d.ts","sourceRoot":"","sources":["../../src/components/QuerySuggestionsDropdown.tsx"],"names":[],"mappings":"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"}
@@ -14,13 +14,27 @@ import { useSearchContext } from './SearchProvider';
14
14
  import { useQuerySuggestionsEnhanced } from '../hooks/useQuerySuggestionsEnhanced';
15
15
  import { clsx } from 'clsx';
16
16
  // ============================================================================
17
+ // Constants
18
+ // ============================================================================
19
+ const TRANSITIONS = {
20
+ fast: '150ms ease-in-out',
21
+ normal: '200ms ease-in-out',
22
+ slow: '300ms ease-in-out',
23
+ };
24
+ const BORDER_RADIUS = {
25
+ sm: 4,
26
+ md: 6,
27
+ lg: 8,
28
+ full: 9999,
29
+ };
30
+ // ============================================================================
17
31
  // Styles
18
32
  // ============================================================================
19
33
  const defaultStyles = {
20
34
  container: {
21
- backgroundColor: 'var(--seekora-bg-surface, #ffffff)',
22
- border: '1px solid var(--seekora-border-color, #e5e7eb)',
23
- borderRadius: 'var(--seekora-border-radius, 8px)',
35
+ backgroundColor: 'var(--seekora-bg-surface, transparent)',
36
+ border: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
37
+ borderRadius: `var(--seekora-border-radius, ${BORDER_RADIUS.lg}px)`,
24
38
  boxShadow: 'var(--seekora-shadow-lg, 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05))',
25
39
  maxHeight: '400px',
26
40
  overflowY: 'auto',
@@ -32,7 +46,7 @@ const defaultStyles = {
32
46
  sectionTitle: {
33
47
  fontSize: '12px',
34
48
  fontWeight: 600,
35
- color: 'var(--seekora-text-secondary, #6b7280)',
49
+ color: 'var(--seekora-text-secondary, inherit)',
36
50
  textTransform: 'uppercase',
37
51
  letterSpacing: '0.05em',
38
52
  padding: '8px 16px 4px',
@@ -43,9 +57,9 @@ const defaultStyles = {
43
57
  alignItems: 'center',
44
58
  padding: '10px 16px',
45
59
  cursor: 'pointer',
46
- transition: 'background-color 150ms ease',
60
+ transition: `background-color ${TRANSITIONS.fast}`,
47
61
  fontSize: '14px',
48
- color: 'var(--seekora-text-primary, #111827)',
62
+ color: 'var(--seekora-text-primary, inherit)',
49
63
  gap: '12px',
50
64
  },
51
65
  suggestionItemActive: {
@@ -65,10 +79,10 @@ const defaultStyles = {
65
79
  },
66
80
  highlight: {
67
81
  fontWeight: 600,
68
- color: 'var(--seekora-text-primary, #111827)',
82
+ color: 'var(--seekora-text-primary, inherit)',
69
83
  backgroundColor: 'var(--seekora-highlight-bg, #fef3c7)',
70
84
  padding: '0 2px',
71
- borderRadius: '2px',
85
+ borderRadius: `${BORDER_RADIUS.sm / 2}px`,
72
86
  },
73
87
  recentIcon: {
74
88
  width: '16px',
@@ -78,13 +92,13 @@ const defaultStyles = {
78
92
  },
79
93
  removeButton: {
80
94
  padding: '4px',
81
- borderRadius: '4px',
95
+ borderRadius: `${BORDER_RADIUS.sm}px`,
82
96
  border: 'none',
83
97
  background: 'transparent',
84
98
  cursor: 'pointer',
85
99
  color: 'var(--seekora-text-secondary, #9ca3af)',
86
100
  opacity: 0,
87
- transition: 'opacity 150ms ease, color 150ms ease',
101
+ transition: `opacity ${TRANSITIONS.fast}, color ${TRANSITIONS.fast}`,
88
102
  },
89
103
  removeButtonVisible: {
90
104
  opacity: 1,
@@ -94,7 +108,7 @@ const defaultStyles = {
94
108
  alignItems: 'center',
95
109
  justifyContent: 'center',
96
110
  padding: '24px 16px',
97
- color: 'var(--seekora-text-secondary, #6b7280)',
111
+ color: 'var(--seekora-text-secondary, inherit)',
98
112
  fontSize: '14px',
99
113
  gap: '8px',
100
114
  },
@@ -104,20 +118,20 @@ const defaultStyles = {
104
118
  alignItems: 'center',
105
119
  justifyContent: 'center',
106
120
  padding: '24px 16px',
107
- color: 'var(--seekora-text-secondary, #6b7280)',
121
+ color: 'var(--seekora-text-secondary, inherit)',
108
122
  fontSize: '14px',
109
123
  textAlign: 'center',
110
124
  },
111
125
  divider: {
112
126
  height: '1px',
113
- backgroundColor: 'var(--seekora-border-color, #e5e7eb)',
127
+ backgroundColor: 'var(--seekora-border-color, rgba(128,128,128,0.2))',
114
128
  margin: '4px 0',
115
129
  },
116
130
  footer: {
117
- borderTop: '1px solid var(--seekora-border-color, #e5e7eb)',
131
+ borderTop: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
118
132
  padding: '8px 16px',
119
133
  fontSize: '12px',
120
- color: 'var(--seekora-text-secondary, #6b7280)',
134
+ color: 'var(--seekora-text-secondary, inherit)',
121
135
  display: 'flex',
122
136
  alignItems: 'center',
123
137
  justifyContent: 'space-between',
@@ -135,9 +149,9 @@ const defaultStyles = {
135
149
  minWidth: '20px',
136
150
  height: '18px',
137
151
  padding: '0 4px',
138
- borderRadius: '3px',
139
- backgroundColor: 'var(--seekora-bg-secondary, #f3f4f6)',
140
- border: '1px solid var(--seekora-border-color, #e5e7eb)',
152
+ borderRadius: `${BORDER_RADIUS.sm - 1}px`,
153
+ backgroundColor: 'var(--seekora-bg-secondary, rgba(255, 255, 255, 0.1))',
154
+ border: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
141
155
  fontSize: '10px',
142
156
  fontWeight: 500,
143
157
  },
@@ -1 +1 @@
1
- {"version":3,"file":"RangeInput.d.ts","sourceRoot":"","sources":["../../src/components/RangeInput.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAoD,MAAM,OAAO,CAAC;AAKzE,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oBAAoB;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oBAAoB;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4BAA4B;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kCAAkC;IAClC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAC3E,6BAA6B;IAC7B,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE;QACzB,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;QACxB,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;QACxB,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;QACjD,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;QACjD,OAAO,EAAE,MAAM,IAAI,CAAC;KACrB,KAAK,KAAK,CAAC,SAAS,CAAC;IACtB,uBAAuB;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,mBAAmB;IACnB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,wBAAwB;IACxB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,kCAAkC;IAClC,WAAW,CAAC,EAAE;QACZ,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;IACF,8DAA8D;IAC9D,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AA8BD,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAsQhD,CAAC"}
1
+ {"version":3,"file":"RangeInput.d.ts","sourceRoot":"","sources":["../../src/components/RangeInput.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAA2C,MAAM,OAAO,CAAC;AAKhE,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oBAAoB;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oBAAoB;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4BAA4B;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kCAAkC;IAClC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAC3E,6BAA6B;IAC7B,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE;QACzB,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;QACxB,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;QACxB,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;QACjD,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;QACjD,OAAO,EAAE,MAAM,IAAI,CAAC;KACrB,KAAK,KAAK,CAAC,SAAS,CAAC;IACtB,uBAAuB;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,mBAAmB;IACnB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,wBAAwB;IACxB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,kCAAkC;IAClC,WAAW,CAAC,EAAE;QACZ,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;IACF,8DAA8D;IAC9D,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AA8BD,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAuQhD,CAAC"}
@@ -4,7 +4,7 @@
4
4
  * Displays a range input for filtering numeric values (e.g., price range)
5
5
  * Integrates with SearchStateManager for automatic state sync
6
6
  */
7
- import React, { useState, useCallback, useEffect, useMemo } from 'react';
7
+ import React, { useState, useCallback, useEffect } from 'react';
8
8
  import { useSearchContext } from './SearchProvider';
9
9
  import { useSearchState } from '../hooks/useSearchState';
10
10
  import { clsx } from 'clsx';
@@ -35,11 +35,11 @@ export const RangeInput = ({ field, label, min, max, currentMin: currentMinProp,
35
35
  const { refinements, addRefinement, removeRefinement } = useSearchState();
36
36
  const rangeInputTheme = customTheme || {};
37
37
  // Parse current range from StateManager
38
- const stateRange = useMemo(() => {
39
- if (!syncWithState)
40
- return { min: undefined, max: undefined };
41
- return parseRangeFromRefinements(refinements, field);
42
- }, [syncWithState, refinements, field]);
38
+ // NOTE: computed every render (no useMemo) because the state manager mutates
39
+ // the refinements array in place — the reference never changes.
40
+ const stateRange = !syncWithState
41
+ ? { min: undefined, max: undefined }
42
+ : parseRangeFromRefinements(refinements, field);
43
43
  const [internalMin, setInternalMin] = useState(currentMinProp ?? stateRange.min);
44
44
  const [internalMax, setInternalMax] = useState(currentMaxProp ?? stateRange.max);
45
45
  const [appliedMin, setAppliedMin] = useState(currentMinProp ?? stateRange.min);