@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.
- package/dist/components/CurrentRefinements.d.ts.map +1 -1
- package/dist/components/CurrentRefinements.js +69 -9
- package/dist/components/FacetDropdown.d.ts +92 -0
- package/dist/components/FacetDropdown.d.ts.map +1 -0
- package/dist/components/FacetDropdown.js +374 -0
- package/dist/components/Facets.d.ts +26 -0
- package/dist/components/Facets.d.ts.map +1 -1
- package/dist/components/Facets.js +195 -6
- package/dist/components/FederatedDropdown.d.ts.map +1 -1
- package/dist/components/FederatedDropdown.js +45 -31
- package/dist/components/QuerySuggestionsDropdown.d.ts.map +1 -1
- package/dist/components/QuerySuggestionsDropdown.js +32 -18
- package/dist/components/RangeInput.d.ts.map +1 -1
- package/dist/components/RangeInput.js +6 -6
- package/dist/components/RangeSlider.d.ts.map +1 -1
- package/dist/components/RangeSlider.js +54 -32
- package/dist/components/RichQuerySuggestions.d.ts.map +1 -1
- package/dist/components/RichQuerySuggestions.js +40 -26
- package/dist/components/SearchBar.d.ts.map +1 -1
- package/dist/components/SearchBar.js +15 -7
- package/dist/components/SearchBarWithSuggestions.js +3 -3
- package/dist/components/SearchLayout.d.ts.map +1 -1
- package/dist/components/SearchLayout.js +10 -1
- package/dist/components/SearchResults.d.ts.map +1 -1
- package/dist/components/SearchResults.js +37 -25
- package/dist/components/primitives/ActionButtons.d.ts.map +1 -1
- package/dist/components/primitives/ActionButtons.js +34 -10
- package/dist/components/primitives/BadgeList.d.ts.map +1 -1
- package/dist/components/primitives/BadgeList.js +33 -13
- package/dist/components/primitives/ImageDisplay.d.ts.map +1 -1
- package/dist/components/primitives/ImageDisplay.js +11 -8
- package/dist/components/primitives/ImageZoom.js +26 -26
- package/dist/components/primitives/VariantSelector.js +10 -10
- package/dist/components/primitives/VariantSwatches.js +3 -3
- package/dist/components/product-page/ProductGallery.d.ts +8 -1
- package/dist/components/product-page/ProductGallery.d.ts.map +1 -1
- package/dist/components/product-page/ProductGallery.js +2 -2
- package/dist/components/section-primitives/SectionSearchProvider.d.ts +3 -1
- package/dist/components/section-primitives/SectionSearchProvider.d.ts.map +1 -1
- package/dist/components/section-primitives/SectionSearchProvider.js +3 -2
- package/dist/components/suggestions/MobileSheetDropdown.js +18 -18
- package/dist/components/suggestions/ShopifyDropdown.js +37 -37
- package/dist/components/suggestions-primitives/DropdownPanel.d.ts.map +1 -1
- package/dist/components/suggestions-primitives/DropdownPanel.js +15 -2
- package/dist/components/suggestions-primitives/ItemCard.d.ts.map +1 -1
- package/dist/components/suggestions-primitives/ItemCard.js +21 -8
- package/dist/components/suggestions-primitives/ItemGrid.d.ts.map +1 -1
- package/dist/components/suggestions-primitives/ItemGrid.js +9 -3
- package/dist/components/suggestions-primitives/ProductCard.d.ts.map +1 -1
- package/dist/components/suggestions-primitives/ProductCard.js +25 -10
- package/dist/components/suggestions-primitives/ProductCardLayouts.d.ts.map +1 -1
- package/dist/components/suggestions-primitives/ProductCardLayouts.js +24 -12
- package/dist/components/suggestions-primitives/SearchInput.d.ts.map +1 -1
- package/dist/components/suggestions-primitives/SearchInput.js +28 -9
- package/dist/components/suggestions-primitives/SuggestionItem.d.ts.map +1 -1
- package/dist/components/suggestions-primitives/SuggestionItem.js +3 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.umd.js +1 -1
- package/dist/src/index.d.ts +129 -4
- package/dist/src/index.esm.js +1361 -616
- package/dist/src/index.esm.js.map +1 -1
- package/dist/src/index.js +1361 -615
- package/dist/src/index.js.map +1 -1
- package/package.json +6 -6
package/dist/src/index.esm.js
CHANGED
|
@@ -1568,6 +1568,9 @@ function r(e){var t,f,n="";if("string"==typeof e||"number"==typeof e)n+=e;else i
|
|
|
1568
1568
|
*
|
|
1569
1569
|
* Interactive search input component with query suggestions support
|
|
1570
1570
|
*/
|
|
1571
|
+
// Z-index scale for consistent layering
|
|
1572
|
+
const Z_INDEX$2 = {
|
|
1573
|
+
dropdown: 100};
|
|
1571
1574
|
const SIZE_CONFIG = {
|
|
1572
1575
|
small: {
|
|
1573
1576
|
padding: '0.375rem 0.5rem',
|
|
@@ -1751,9 +1754,9 @@ const SearchBar = ({ placeholder = 'Search...', showSuggestions = true, debounce
|
|
|
1751
1754
|
const inputPaddingLeft = sizeConfig.iconPaddingLeft ;
|
|
1752
1755
|
const inputPaddingRight = hasClearBtn ? sizeConfig.iconPaddingRight : sizeConfig.padding.split(' ')[1] || sizeConfig.padding;
|
|
1753
1756
|
const borderRadius = typeof theme.borderRadius === 'string' ? theme.borderRadius : theme.borderRadius.medium;
|
|
1754
|
-
const focusBorderColor = isFocused ? theme.colors.focus : theme.colors.border
|
|
1757
|
+
const focusBorderColor = isFocused ? `var(--seekora-border-focus, ${theme.colors.focus})` : `var(--seekora-border, ${theme.colors.border})`;
|
|
1755
1758
|
const focusRingShadow = isFocused
|
|
1756
|
-
? `0 0 0 3px ${theme.colors.focus}33`
|
|
1759
|
+
? `0 0 0 3px var(--seekora-border-focus-alpha, ${theme.colors.focus}33)`
|
|
1757
1760
|
: undefined;
|
|
1758
1761
|
const handleClear = useCallback(() => {
|
|
1759
1762
|
setQuery('', false);
|
|
@@ -1787,7 +1790,7 @@ const SearchBar = ({ placeholder = 'Search...', showSuggestions = true, debounce
|
|
|
1787
1790
|
justifyContent: 'center',
|
|
1788
1791
|
pointerEvents: 'none',
|
|
1789
1792
|
color: 'var(--seekora-searchbar-icon-color)',
|
|
1790
|
-
zIndex:
|
|
1793
|
+
zIndex: 2,
|
|
1791
1794
|
} }, renderSearchIcon ? renderSearchIcon() : React.createElement(DefaultSearchIcon, { size: sizeConfig.iconSize }))),
|
|
1792
1795
|
React.createElement("input", { ref: inputRef, type: "text", value: query, onChange: handleInputChange, onKeyDown: handleKeyDown, onFocus: handleFocus, onBlur: handleBlur, placeholder: placeholder, className: clsx(searchBarTheme.input, isFocused && searchBarTheme.inputFocused), style: {
|
|
1793
1796
|
width: '100%',
|
|
@@ -1823,7 +1826,7 @@ const SearchBar = ({ placeholder = 'Search...', showSuggestions = true, debounce
|
|
|
1823
1826
|
borderRadius: '50%',
|
|
1824
1827
|
color: 'var(--seekora-searchbar-icon-color)',
|
|
1825
1828
|
transition: theme.transitions?.fast || '150ms ease-in-out',
|
|
1826
|
-
zIndex:
|
|
1829
|
+
zIndex: 2,
|
|
1827
1830
|
}, onMouseDown: (e) => {
|
|
1828
1831
|
// Prevent input blur so the clear action doesn't race with blur handler
|
|
1829
1832
|
e.preventDefault();
|
|
@@ -1834,8 +1837,8 @@ const SearchBar = ({ placeholder = 'Search...', showSuggestions = true, debounce
|
|
|
1834
1837
|
fontSize: sizeConfig.fontSize,
|
|
1835
1838
|
fontFamily: theme.typography.fontFamily,
|
|
1836
1839
|
fontWeight: theme.typography.fontWeight?.medium ?? 500,
|
|
1837
|
-
backgroundColor: theme.colors.primary
|
|
1838
|
-
color: '#ffffff',
|
|
1840
|
+
backgroundColor: `var(--seekora-primary, ${theme.colors.primary})`,
|
|
1841
|
+
color: 'var(--seekora-primary-text, #ffffff)',
|
|
1839
1842
|
border: 'none',
|
|
1840
1843
|
borderRadius: 'var(--seekora-searchbar-radius)',
|
|
1841
1844
|
cursor: 'pointer',
|
|
@@ -1863,7 +1866,8 @@ const SearchBar = ({ placeholder = 'Search...', showSuggestions = true, debounce
|
|
|
1863
1866
|
boxShadow: theme.shadows.medium,
|
|
1864
1867
|
maxHeight: '400px',
|
|
1865
1868
|
overflowY: 'auto',
|
|
1866
|
-
zIndex:
|
|
1869
|
+
zIndex: Z_INDEX$2.dropdown,
|
|
1870
|
+
boxSizing: 'border-box',
|
|
1867
1871
|
} },
|
|
1868
1872
|
isLoading && displayedSuggestions.length === 0 && showLoadingState && (renderLoading ? renderLoading() : defaultRenderLoading()),
|
|
1869
1873
|
displayedSuggestions.length > 0 && (React.createElement(React.Fragment, null, displayedSuggestions.map((suggestion, index) => {
|
|
@@ -1932,6 +1936,43 @@ const SearchResults = ({ results: resultsProp, loading: loadingProp, error: erro
|
|
|
1932
1936
|
}
|
|
1933
1937
|
}
|
|
1934
1938
|
}, [activeIndex, enableKeyboardNavigation]);
|
|
1939
|
+
// Global keyboard listener for seamless navigation from search box to results
|
|
1940
|
+
useEffect(() => {
|
|
1941
|
+
if (!enableKeyboardNavigation)
|
|
1942
|
+
return;
|
|
1943
|
+
const handleGlobalKeyDown = (e) => {
|
|
1944
|
+
// Only handle if we have results and the container exists
|
|
1945
|
+
if (!containerRef.current)
|
|
1946
|
+
return;
|
|
1947
|
+
const resultElements = containerRef.current.querySelectorAll('[data-result-index]');
|
|
1948
|
+
const maxIndex = resultElements.length - 1;
|
|
1949
|
+
if (maxIndex < 0)
|
|
1950
|
+
return;
|
|
1951
|
+
// Check if focus is on an input/textarea (search box)
|
|
1952
|
+
const activeElement = document.activeElement;
|
|
1953
|
+
const isInputFocused = activeElement?.tagName === 'INPUT' || activeElement?.tagName === 'TEXTAREA';
|
|
1954
|
+
if (e.key === 'ArrowDown') {
|
|
1955
|
+
// If in search box or no result selected, select first result
|
|
1956
|
+
if (isInputFocused || activeIndex === -1) {
|
|
1957
|
+
e.preventDefault();
|
|
1958
|
+
setActiveIndex(0);
|
|
1959
|
+
containerRef.current?.focus();
|
|
1960
|
+
}
|
|
1961
|
+
}
|
|
1962
|
+
else if (e.key === 'ArrowUp') {
|
|
1963
|
+
// If first result is selected, go back to search box
|
|
1964
|
+
if (activeIndex === 0) {
|
|
1965
|
+
e.preventDefault();
|
|
1966
|
+
setActiveIndex(-1);
|
|
1967
|
+
// Find and focus the search input
|
|
1968
|
+
const searchInput = document.querySelector('input[type="text"], input[type="search"]');
|
|
1969
|
+
searchInput?.focus();
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
};
|
|
1973
|
+
document.addEventListener('keydown', handleGlobalKeyDown);
|
|
1974
|
+
return () => document.removeEventListener('keydown', handleGlobalKeyDown);
|
|
1975
|
+
}, [enableKeyboardNavigation, activeIndex]);
|
|
1935
1976
|
// Keyboard navigation handler
|
|
1936
1977
|
const handleKeyDown = useCallback((e) => {
|
|
1937
1978
|
if (!enableKeyboardNavigation)
|
|
@@ -2307,31 +2348,6 @@ const SearchResults = ({ results: resultsProp, loading: loadingProp, error: erro
|
|
|
2307
2348
|
results?.totalResults || results?.data?.total_results || 0,
|
|
2308
2349
|
" result",
|
|
2309
2350
|
(results?.totalResults || results?.data?.total_results || 0) !== 1 ? 's' : '')),
|
|
2310
|
-
enableKeyboardNavigation && resultItems.length > 0 && (React.createElement("div", { style: {
|
|
2311
|
-
fontSize: '12px',
|
|
2312
|
-
color: theme.colors.text,
|
|
2313
|
-
opacity: 0.6,
|
|
2314
|
-
marginBottom: theme.spacing.small,
|
|
2315
|
-
display: 'flex',
|
|
2316
|
-
gap: '8px',
|
|
2317
|
-
alignItems: 'center',
|
|
2318
|
-
} },
|
|
2319
|
-
React.createElement("span", { style: {
|
|
2320
|
-
display: 'inline-flex',
|
|
2321
|
-
gap: '4px',
|
|
2322
|
-
padding: '2px 6px',
|
|
2323
|
-
backgroundColor: theme.colors.hover,
|
|
2324
|
-
borderRadius: '4px',
|
|
2325
|
-
fontSize: '11px',
|
|
2326
|
-
} }, "\u2191\u2193 navigate"),
|
|
2327
|
-
React.createElement("span", { style: {
|
|
2328
|
-
display: 'inline-flex',
|
|
2329
|
-
gap: '4px',
|
|
2330
|
-
padding: '2px 6px',
|
|
2331
|
-
backgroundColor: theme.colors.hover,
|
|
2332
|
-
borderRadius: '4px',
|
|
2333
|
-
fontSize: '11px',
|
|
2334
|
-
} }, "\u21B5 select"))),
|
|
2335
2351
|
React.createElement("div", { className: searchResultsTheme.resultsList, style: resultsListStyle }, resultItems.map((result, index) => renderFn(result, index, index === activeIndex)))));
|
|
2336
2352
|
};
|
|
2337
2353
|
|
|
@@ -2993,6 +3009,261 @@ const SortBy = ({ options, value: valueProp, defaultValue, onSortChange, renderS
|
|
|
2993
3009
|
return null;
|
|
2994
3010
|
};
|
|
2995
3011
|
|
|
3012
|
+
/**
|
|
3013
|
+
* RangeSlider Component
|
|
3014
|
+
*
|
|
3015
|
+
* Visual slider for numeric range filtering
|
|
3016
|
+
* Alternative to RangeInput for a more interactive UX
|
|
3017
|
+
*/
|
|
3018
|
+
const SHADOWS$1 = {
|
|
3019
|
+
md: '0 2px 4px rgba(0,0,0,0.1)'};
|
|
3020
|
+
const RangeSlider = ({ field, label, min, max, step = 1, currentMin: currentMinProp, currentMax: currentMaxProp, onRangeChange, formatValue = (v) => v.toString(), className, style, theme: customTheme, showValues = true, syncWithState = true, debounceMs = 300, }) => {
|
|
3021
|
+
const { theme } = useSearchContext();
|
|
3022
|
+
const { refinements, addRefinement, removeRefinement } = useSearchState();
|
|
3023
|
+
const rangeSliderTheme = customTheme || {};
|
|
3024
|
+
const thumbClass = rangeSliderTheme.thumb || 'seekora-range-slider__thumb';
|
|
3025
|
+
// Parse current range from StateManager
|
|
3026
|
+
// NOTE: computed every render (no useMemo) because the state manager mutates
|
|
3027
|
+
// the refinements array in place — the reference never changes.
|
|
3028
|
+
let stateRange;
|
|
3029
|
+
if (!syncWithState) {
|
|
3030
|
+
stateRange = { min: undefined, max: undefined };
|
|
3031
|
+
}
|
|
3032
|
+
else {
|
|
3033
|
+
let minVal;
|
|
3034
|
+
let maxVal;
|
|
3035
|
+
refinements.forEach(r => {
|
|
3036
|
+
if (r.field === field) {
|
|
3037
|
+
const minMatch = r.value.match(/^>=(\d+(?:\.\d+)?)$/);
|
|
3038
|
+
if (minMatch)
|
|
3039
|
+
minVal = parseFloat(minMatch[1]);
|
|
3040
|
+
const maxMatch = r.value.match(/^<=(\d+(?:\.\d+)?)$/);
|
|
3041
|
+
if (maxMatch)
|
|
3042
|
+
maxVal = parseFloat(maxMatch[1]);
|
|
3043
|
+
}
|
|
3044
|
+
});
|
|
3045
|
+
stateRange = { min: minVal, max: maxVal };
|
|
3046
|
+
}
|
|
3047
|
+
const [internalMin, setInternalMin] = useState(currentMinProp ?? stateRange.min ?? min);
|
|
3048
|
+
const [internalMax, setInternalMax] = useState(currentMaxProp ?? stateRange.max ?? max);
|
|
3049
|
+
const isDraggingRef = useRef(false);
|
|
3050
|
+
const debounceRef = useRef(null);
|
|
3051
|
+
const pendingMinRef = useRef(internalMin);
|
|
3052
|
+
const pendingMaxRef = useRef(internalMax);
|
|
3053
|
+
// Sync with StateManager changes (only when stateRange actually changes, not on drag)
|
|
3054
|
+
useEffect(() => {
|
|
3055
|
+
if (syncWithState && !isDraggingRef.current) {
|
|
3056
|
+
if (stateRange.min !== undefined)
|
|
3057
|
+
setInternalMin(stateRange.min);
|
|
3058
|
+
else
|
|
3059
|
+
setInternalMin(min);
|
|
3060
|
+
if (stateRange.max !== undefined)
|
|
3061
|
+
setInternalMax(stateRange.max);
|
|
3062
|
+
else
|
|
3063
|
+
setInternalMax(max);
|
|
3064
|
+
}
|
|
3065
|
+
}, [syncWithState, stateRange.min, stateRange.max, min, max]);
|
|
3066
|
+
// Update StateManager with range refinements
|
|
3067
|
+
const updateStateManager = useCallback((minVal, maxVal) => {
|
|
3068
|
+
if (!syncWithState)
|
|
3069
|
+
return;
|
|
3070
|
+
// Remove existing range refinements for this field
|
|
3071
|
+
refinements.forEach(r => {
|
|
3072
|
+
if (r.field === field) {
|
|
3073
|
+
removeRefinement(field, r.value, false);
|
|
3074
|
+
}
|
|
3075
|
+
});
|
|
3076
|
+
// Add new range refinements — trigger search on the last one added
|
|
3077
|
+
const setMin = minVal > min;
|
|
3078
|
+
const setMax = maxVal < max;
|
|
3079
|
+
if (setMin && setMax) {
|
|
3080
|
+
addRefinement(field, `>=${minVal}`, false);
|
|
3081
|
+
addRefinement(field, `<=${maxVal}`, true);
|
|
3082
|
+
}
|
|
3083
|
+
else if (setMin) {
|
|
3084
|
+
addRefinement(field, `>=${minVal}`, true);
|
|
3085
|
+
}
|
|
3086
|
+
else if (setMax) {
|
|
3087
|
+
addRefinement(field, `<=${maxVal}`, true);
|
|
3088
|
+
}
|
|
3089
|
+
}, [syncWithState, field, refinements, addRefinement, removeRefinement, min, max]);
|
|
3090
|
+
// Debounced update (during drag only)
|
|
3091
|
+
const debouncedUpdate = useCallback((minVal, maxVal) => {
|
|
3092
|
+
pendingMinRef.current = minVal;
|
|
3093
|
+
pendingMaxRef.current = maxVal;
|
|
3094
|
+
if (debounceRef.current) {
|
|
3095
|
+
clearTimeout(debounceRef.current);
|
|
3096
|
+
}
|
|
3097
|
+
debounceRef.current = setTimeout(() => {
|
|
3098
|
+
updateStateManager(minVal, maxVal);
|
|
3099
|
+
if (onRangeChange) {
|
|
3100
|
+
onRangeChange(minVal, maxVal);
|
|
3101
|
+
}
|
|
3102
|
+
}, debounceMs);
|
|
3103
|
+
}, [updateStateManager, onRangeChange, debounceMs]);
|
|
3104
|
+
// Handle min slider change
|
|
3105
|
+
const handleMinChange = (e) => {
|
|
3106
|
+
const value = Math.min(Number(e.target.value), internalMax - step);
|
|
3107
|
+
setInternalMin(value);
|
|
3108
|
+
isDraggingRef.current = true;
|
|
3109
|
+
debouncedUpdate(value, internalMax);
|
|
3110
|
+
};
|
|
3111
|
+
// Handle max slider change
|
|
3112
|
+
const handleMaxChange = (e) => {
|
|
3113
|
+
const value = Math.max(Number(e.target.value), internalMin + step);
|
|
3114
|
+
setInternalMax(value);
|
|
3115
|
+
isDraggingRef.current = true;
|
|
3116
|
+
debouncedUpdate(internalMin, value);
|
|
3117
|
+
};
|
|
3118
|
+
// Handle drag end — flush pending update immediately
|
|
3119
|
+
const handleDragEnd = () => {
|
|
3120
|
+
isDraggingRef.current = false;
|
|
3121
|
+
// Cancel the debounce and commit immediately
|
|
3122
|
+
if (debounceRef.current) {
|
|
3123
|
+
clearTimeout(debounceRef.current);
|
|
3124
|
+
debounceRef.current = null;
|
|
3125
|
+
}
|
|
3126
|
+
updateStateManager(pendingMinRef.current, pendingMaxRef.current);
|
|
3127
|
+
if (onRangeChange) {
|
|
3128
|
+
onRangeChange(pendingMinRef.current, pendingMaxRef.current);
|
|
3129
|
+
}
|
|
3130
|
+
};
|
|
3131
|
+
// Handle keyboard navigation for enhanced control (Shift+Arrow for 10x step, Home/End)
|
|
3132
|
+
const handleMinKeyDown = (e) => {
|
|
3133
|
+
let newValue = null;
|
|
3134
|
+
if (e.key === 'Home') {
|
|
3135
|
+
e.preventDefault();
|
|
3136
|
+
newValue = min;
|
|
3137
|
+
}
|
|
3138
|
+
else if (e.key === 'End') {
|
|
3139
|
+
e.preventDefault();
|
|
3140
|
+
newValue = internalMax - step;
|
|
3141
|
+
}
|
|
3142
|
+
else if (e.shiftKey && (e.key === 'ArrowLeft' || e.key === 'ArrowDown')) {
|
|
3143
|
+
e.preventDefault();
|
|
3144
|
+
newValue = Math.max(min, internalMin - step * 10);
|
|
3145
|
+
}
|
|
3146
|
+
else if (e.shiftKey && (e.key === 'ArrowRight' || e.key === 'ArrowUp')) {
|
|
3147
|
+
e.preventDefault();
|
|
3148
|
+
newValue = Math.min(internalMax - step, internalMin + step * 10);
|
|
3149
|
+
}
|
|
3150
|
+
if (newValue !== null) {
|
|
3151
|
+
setInternalMin(newValue);
|
|
3152
|
+
debouncedUpdate(newValue, internalMax);
|
|
3153
|
+
}
|
|
3154
|
+
};
|
|
3155
|
+
const handleMaxKeyDown = (e) => {
|
|
3156
|
+
let newValue = null;
|
|
3157
|
+
if (e.key === 'Home') {
|
|
3158
|
+
e.preventDefault();
|
|
3159
|
+
newValue = internalMin + step;
|
|
3160
|
+
}
|
|
3161
|
+
else if (e.key === 'End') {
|
|
3162
|
+
e.preventDefault();
|
|
3163
|
+
newValue = max;
|
|
3164
|
+
}
|
|
3165
|
+
else if (e.shiftKey && (e.key === 'ArrowLeft' || e.key === 'ArrowDown')) {
|
|
3166
|
+
e.preventDefault();
|
|
3167
|
+
newValue = Math.max(internalMin + step, internalMax - step * 10);
|
|
3168
|
+
}
|
|
3169
|
+
else if (e.shiftKey && (e.key === 'ArrowRight' || e.key === 'ArrowUp')) {
|
|
3170
|
+
e.preventDefault();
|
|
3171
|
+
newValue = Math.min(max, internalMax + step * 10);
|
|
3172
|
+
}
|
|
3173
|
+
if (newValue !== null) {
|
|
3174
|
+
setInternalMax(newValue);
|
|
3175
|
+
debouncedUpdate(internalMin, newValue);
|
|
3176
|
+
}
|
|
3177
|
+
};
|
|
3178
|
+
// Calculate filled track position
|
|
3179
|
+
const minPercent = ((internalMin - min) / (max - min)) * 100;
|
|
3180
|
+
const maxPercent = ((internalMax - min) / (max - min)) * 100;
|
|
3181
|
+
return (React.createElement("div", { className: clsx(rangeSliderTheme.root, className), style: {
|
|
3182
|
+
fontFamily: 'inherit',
|
|
3183
|
+
...style,
|
|
3184
|
+
} },
|
|
3185
|
+
label && (React.createElement("label", { className: rangeSliderTheme.label, style: {
|
|
3186
|
+
display: 'block',
|
|
3187
|
+
marginBottom: theme.spacing.small,
|
|
3188
|
+
fontSize: theme.typography.fontSize.medium,
|
|
3189
|
+
fontWeight: theme.typography.fontWeight?.medium || 500,
|
|
3190
|
+
color: theme.colors.text,
|
|
3191
|
+
} }, label)),
|
|
3192
|
+
React.createElement("div", { className: rangeSliderTheme.slider, style: {
|
|
3193
|
+
position: 'relative',
|
|
3194
|
+
minHeight: '40px',
|
|
3195
|
+
display: 'flex',
|
|
3196
|
+
alignItems: 'center',
|
|
3197
|
+
} },
|
|
3198
|
+
React.createElement("div", { className: rangeSliderTheme.track, style: {
|
|
3199
|
+
position: 'absolute',
|
|
3200
|
+
width: '100%',
|
|
3201
|
+
height: '4px',
|
|
3202
|
+
backgroundColor: theme.colors.border,
|
|
3203
|
+
borderRadius: '2px',
|
|
3204
|
+
} }),
|
|
3205
|
+
React.createElement("div", { className: rangeSliderTheme.trackFilled, style: {
|
|
3206
|
+
position: 'absolute',
|
|
3207
|
+
left: `${minPercent}%`,
|
|
3208
|
+
width: `${maxPercent - minPercent}%`,
|
|
3209
|
+
height: '4px',
|
|
3210
|
+
backgroundColor: theme.colors.primary,
|
|
3211
|
+
borderRadius: '2px',
|
|
3212
|
+
} }),
|
|
3213
|
+
React.createElement("input", { type: "range", min: min, max: max, step: step, value: internalMin, onChange: handleMinChange, onMouseUp: handleDragEnd, onTouchEnd: handleDragEnd, onKeyDown: handleMinKeyDown, tabIndex: 0, "aria-valuenow": internalMin, "aria-valuemin": min, "aria-valuemax": max, className: thumbClass, style: {
|
|
3214
|
+
position: 'absolute',
|
|
3215
|
+
width: '100%',
|
|
3216
|
+
height: '4px',
|
|
3217
|
+
background: 'transparent',
|
|
3218
|
+
WebkitAppearance: 'none',
|
|
3219
|
+
appearance: 'none',
|
|
3220
|
+
cursor: 'pointer',
|
|
3221
|
+
pointerEvents: 'none',
|
|
3222
|
+
}, "aria-label": `Minimum ${label || field}` }),
|
|
3223
|
+
React.createElement("input", { type: "range", min: min, max: max, step: step, value: internalMax, onChange: handleMaxChange, onMouseUp: handleDragEnd, onTouchEnd: handleDragEnd, onKeyDown: handleMaxKeyDown, tabIndex: 0, "aria-valuenow": internalMax, "aria-valuemin": min, "aria-valuemax": max, className: thumbClass, style: {
|
|
3224
|
+
position: 'absolute',
|
|
3225
|
+
width: '100%',
|
|
3226
|
+
height: '4px',
|
|
3227
|
+
background: 'transparent',
|
|
3228
|
+
WebkitAppearance: 'none',
|
|
3229
|
+
appearance: 'none',
|
|
3230
|
+
cursor: 'pointer',
|
|
3231
|
+
pointerEvents: 'none',
|
|
3232
|
+
}, "aria-label": `Maximum ${label || field}` })),
|
|
3233
|
+
showValues && (React.createElement("div", { className: rangeSliderTheme.values, style: {
|
|
3234
|
+
display: 'flex',
|
|
3235
|
+
justifyContent: 'space-between',
|
|
3236
|
+
marginTop: theme.spacing.small,
|
|
3237
|
+
fontSize: theme.typography.fontSize.small,
|
|
3238
|
+
color: theme.colors.textSecondary,
|
|
3239
|
+
} },
|
|
3240
|
+
React.createElement("span", { className: rangeSliderTheme.value }, formatValue(internalMin)),
|
|
3241
|
+
React.createElement("span", { className: rangeSliderTheme.value }, formatValue(internalMax)))),
|
|
3242
|
+
React.createElement("style", null, `
|
|
3243
|
+
.${thumbClass}::-webkit-slider-thumb {
|
|
3244
|
+
-webkit-appearance: none;
|
|
3245
|
+
appearance: none;
|
|
3246
|
+
width: 20px;
|
|
3247
|
+
height: 20px;
|
|
3248
|
+
background: ${theme.colors.primary};
|
|
3249
|
+
border-radius: 50%;
|
|
3250
|
+
cursor: pointer;
|
|
3251
|
+
pointer-events: all;
|
|
3252
|
+
box-shadow: ${SHADOWS$1.md};
|
|
3253
|
+
}
|
|
3254
|
+
.${thumbClass}::-moz-range-thumb {
|
|
3255
|
+
width: 20px;
|
|
3256
|
+
height: 20px;
|
|
3257
|
+
background: ${theme.colors.primary};
|
|
3258
|
+
border-radius: 50%;
|
|
3259
|
+
cursor: pointer;
|
|
3260
|
+
pointer-events: all;
|
|
3261
|
+
border: none;
|
|
3262
|
+
box-shadow: ${SHADOWS$1.md};
|
|
3263
|
+
}
|
|
3264
|
+
`)));
|
|
3265
|
+
};
|
|
3266
|
+
|
|
2996
3267
|
/**
|
|
2997
3268
|
* Facets Component
|
|
2998
3269
|
*
|
|
@@ -3042,17 +3313,19 @@ const CheckmarkIcon = ({ size = 16 }) => (React.createElement("svg", { width: si
|
|
|
3042
3313
|
// CSS variable defaults
|
|
3043
3314
|
// ---------------------------------------------------------------------------
|
|
3044
3315
|
const CSS_VAR_DEFAULTS = {
|
|
3045
|
-
'--seekora-facet-bg': '
|
|
3316
|
+
'--seekora-facet-bg': 'transparent',
|
|
3046
3317
|
'--seekora-facet-border': '#dee2e6',
|
|
3047
|
-
'--seekora-facet-active-bg': '
|
|
3318
|
+
'--seekora-facet-active-bg': 'rgba(0, 0, 0, 0.05)',
|
|
3048
3319
|
'--seekora-facet-swatch-size': '32px',
|
|
3049
3320
|
'--seekora-facet-count-bg': '#e9ecef',
|
|
3050
3321
|
'--seekora-facet-count-color': '#495057',
|
|
3322
|
+
'--seekora-primary': '#3b82f6',
|
|
3323
|
+
'--seekora-primary-text': '#ffffff',
|
|
3051
3324
|
};
|
|
3052
3325
|
// ---------------------------------------------------------------------------
|
|
3053
3326
|
// Component
|
|
3054
3327
|
// ---------------------------------------------------------------------------
|
|
3055
|
-
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', }) => {
|
|
3328
|
+
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, }) => {
|
|
3056
3329
|
const { theme } = useSearchContext();
|
|
3057
3330
|
const { results: stateResults, refinements, addRefinement, removeRefinement } = useSearchState();
|
|
3058
3331
|
const facetsTheme = customTheme || {};
|
|
@@ -3102,6 +3375,7 @@ const Facets = ({ results: resultsProp, facets: facetsProp, onFacetChange, rende
|
|
|
3102
3375
|
count: count.count,
|
|
3103
3376
|
selected: refinements.some(r => r.field === fieldName && r.value === count.value),
|
|
3104
3377
|
})) : [],
|
|
3378
|
+
stats: facet.stats || undefined,
|
|
3105
3379
|
};
|
|
3106
3380
|
});
|
|
3107
3381
|
log.verbose('Facets: Extracted facets', {
|
|
@@ -3179,7 +3453,7 @@ const Facets = ({ results: resultsProp, facets: facetsProp, onFacetChange, rende
|
|
|
3179
3453
|
const sizeScale = useMemo(() => {
|
|
3180
3454
|
switch (size) {
|
|
3181
3455
|
case 'small':
|
|
3182
|
-
return { font: theme.typography.fontSize.small, padding: '0.
|
|
3456
|
+
return { font: theme.typography.fontSize.small, padding: '0.5rem', gap: '0.5rem' };
|
|
3183
3457
|
case 'large':
|
|
3184
3458
|
return { font: theme.typography.fontSize.large, padding: '0.75rem', gap: '0.75rem' };
|
|
3185
3459
|
case 'medium':
|
|
@@ -3248,6 +3522,7 @@ const Facets = ({ results: resultsProp, facets: facetsProp, onFacetChange, rende
|
|
|
3248
3522
|
? 'var(--seekora-facet-active-bg, ' + theme.colors.hover + ')'
|
|
3249
3523
|
: 'transparent',
|
|
3250
3524
|
transition: 'background-color 0.2s ease',
|
|
3525
|
+
boxSizing: 'border-box',
|
|
3251
3526
|
} },
|
|
3252
3527
|
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: {
|
|
3253
3528
|
marginRight: sizeScale.gap,
|
|
@@ -3256,6 +3531,7 @@ const Facets = ({ results: resultsProp, facets: facetsProp, onFacetChange, rende
|
|
|
3256
3531
|
React.createElement("span", { className: facetsTheme.facetItemLabel, style: {
|
|
3257
3532
|
flex: 1,
|
|
3258
3533
|
fontSize: sizeScale.font,
|
|
3534
|
+
lineHeight: 1.5,
|
|
3259
3535
|
color: theme.colors.text,
|
|
3260
3536
|
} }, item.value),
|
|
3261
3537
|
renderCountBadge(item.count)));
|
|
@@ -3284,13 +3560,13 @@ const Facets = ({ results: resultsProp, facets: facetsProp, onFacetChange, rende
|
|
|
3284
3560
|
borderRadius: '50%',
|
|
3285
3561
|
backgroundColor: color,
|
|
3286
3562
|
border: isChecked
|
|
3287
|
-
? `3px solid ${theme.colors.primary}`
|
|
3563
|
+
? `3px solid var(--seekora-primary, ${theme.colors.primary})`
|
|
3288
3564
|
: `2px solid var(--seekora-facet-border, ${theme.colors.border})`,
|
|
3289
3565
|
display: 'flex',
|
|
3290
3566
|
alignItems: 'center',
|
|
3291
3567
|
justifyContent: 'center',
|
|
3292
3568
|
transition: 'border 0.2s ease, box-shadow 0.2s ease',
|
|
3293
|
-
boxShadow: isChecked ? `0 0 0 2px ${theme.colors.primary}33` : 'none',
|
|
3569
|
+
boxShadow: isChecked ? `0 0 0 2px var(--seekora-primary-alpha, ${theme.colors.primary}33)` : 'none',
|
|
3294
3570
|
position: 'relative',
|
|
3295
3571
|
} }, isChecked && (React.createElement("span", { className: clsx(facetsTheme.colorSwatchInner), style: {
|
|
3296
3572
|
display: 'flex',
|
|
@@ -3516,21 +3792,204 @@ const Facets = ({ results: resultsProp, facets: facetsProp, onFacetChange, rende
|
|
|
3516
3792
|
} }, "Show less"))))));
|
|
3517
3793
|
};
|
|
3518
3794
|
// -------------------------------------------------------------------
|
|
3519
|
-
//
|
|
3795
|
+
// Render-type detection for numeric / range facets
|
|
3520
3796
|
// -------------------------------------------------------------------
|
|
3521
|
-
const
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
case 'collapsible':
|
|
3526
|
-
return renderCollapsibleFacet(facet);
|
|
3527
|
-
case 'checkbox':
|
|
3528
|
-
default:
|
|
3529
|
-
return renderCheckboxFacet(facet);
|
|
3797
|
+
const determineFacetRenderType = (fieldName, stats) => {
|
|
3798
|
+
// If explicit range config exists for this field → range buttons
|
|
3799
|
+
if (facetRanges?.some((rc) => rc.field === fieldName)) {
|
|
3800
|
+
return 'range-buttons';
|
|
3530
3801
|
}
|
|
3802
|
+
// If stats with valid min/max → range slider
|
|
3803
|
+
if (stats && typeof stats.min === 'number' && typeof stats.max === 'number' && stats.min !== stats.max) {
|
|
3804
|
+
return 'range-slider';
|
|
3805
|
+
}
|
|
3806
|
+
return 'list';
|
|
3531
3807
|
};
|
|
3532
3808
|
// -------------------------------------------------------------------
|
|
3533
|
-
//
|
|
3809
|
+
// Range button facet renderer
|
|
3810
|
+
// -------------------------------------------------------------------
|
|
3811
|
+
const renderRangeButtonFacet = (facet, _index) => {
|
|
3812
|
+
const rangeConfig = facetRanges?.find((rc) => rc.field === facet.field);
|
|
3813
|
+
if (!rangeConfig)
|
|
3814
|
+
return null;
|
|
3815
|
+
// Build a lookup from item value → count
|
|
3816
|
+
const countMap = new Map();
|
|
3817
|
+
facet.items.forEach((item) => countMap.set(item.value, item.count));
|
|
3818
|
+
// Detect currently active range from refinements
|
|
3819
|
+
const activeMin = refinements.find((r) => r.field === facet.field && r.value.startsWith('>='));
|
|
3820
|
+
const activeMax = refinements.find((r) => r.field === facet.field && r.value.startsWith('<='));
|
|
3821
|
+
const activeFromVal = activeMin ? parseFloat(activeMin.value.slice(2)) : undefined;
|
|
3822
|
+
const activeToVal = activeMax ? parseFloat(activeMax.value.slice(2)) : undefined;
|
|
3823
|
+
const isRangeActive = (range) => {
|
|
3824
|
+
const fromMatch = range.from === undefined
|
|
3825
|
+
? activeFromVal === undefined
|
|
3826
|
+
: activeFromVal === range.from;
|
|
3827
|
+
const toMatch = range.to === undefined
|
|
3828
|
+
? activeToVal === undefined
|
|
3829
|
+
: activeToVal === range.to;
|
|
3830
|
+
return fromMatch && toMatch;
|
|
3831
|
+
};
|
|
3832
|
+
const handleRangeClick = (range) => {
|
|
3833
|
+
// Clear existing range refinements for this field
|
|
3834
|
+
refinements
|
|
3835
|
+
.filter((r) => r.field === facet.field)
|
|
3836
|
+
.forEach((r) => removeRefinement(facet.field, r.value, false));
|
|
3837
|
+
if (isRangeActive(range)) {
|
|
3838
|
+
// Was active → just clear (already removed above), trigger search
|
|
3839
|
+
addRefinement(facet.field, '__noop__', false);
|
|
3840
|
+
removeRefinement(facet.field, '__noop__', true);
|
|
3841
|
+
return;
|
|
3842
|
+
}
|
|
3843
|
+
// Set new range
|
|
3844
|
+
if (range.from !== undefined) {
|
|
3845
|
+
addRefinement(facet.field, `>=${range.from}`, false);
|
|
3846
|
+
}
|
|
3847
|
+
if (range.to !== undefined) {
|
|
3848
|
+
addRefinement(facet.field, `<=${range.to}`, true);
|
|
3849
|
+
}
|
|
3850
|
+
else if (range.from !== undefined) {
|
|
3851
|
+
// Only "from" set — trigger search
|
|
3852
|
+
addRefinement(facet.field, `>=${range.from}`, true);
|
|
3853
|
+
}
|
|
3854
|
+
};
|
|
3855
|
+
const hasActiveRange = activeMin !== undefined || activeMax !== undefined;
|
|
3856
|
+
const handleClear = () => {
|
|
3857
|
+
refinements
|
|
3858
|
+
.filter((r) => r.field === facet.field)
|
|
3859
|
+
.forEach((r) => removeRefinement(facet.field, r.value, false));
|
|
3860
|
+
// Trigger search after clearing
|
|
3861
|
+
addRefinement(facet.field, '__noop__', false);
|
|
3862
|
+
removeRefinement(facet.field, '__noop__', true);
|
|
3863
|
+
};
|
|
3864
|
+
return (React.createElement("div", { key: facet.field, className: facetsTheme.facet, style: {
|
|
3865
|
+
marginBottom: theme.spacing.large,
|
|
3866
|
+
padding: theme.spacing.medium,
|
|
3867
|
+
backgroundColor: 'var(--seekora-facet-bg, ' + theme.colors.background + ')',
|
|
3868
|
+
border: `1px solid var(--seekora-facet-border, ${theme.colors.border})`,
|
|
3869
|
+
borderRadius: typeof theme.borderRadius === 'string' ? theme.borderRadius : theme.borderRadius.medium,
|
|
3870
|
+
} },
|
|
3871
|
+
React.createElement("h3", { className: facetsTheme.facetTitle, style: {
|
|
3872
|
+
fontSize: theme.typography.fontSize.large,
|
|
3873
|
+
fontWeight: 'bold',
|
|
3874
|
+
margin: 0,
|
|
3875
|
+
marginBottom: theme.spacing.medium,
|
|
3876
|
+
color: theme.colors.text,
|
|
3877
|
+
} }, facet.label || facet.field),
|
|
3878
|
+
React.createElement("div", { style: {
|
|
3879
|
+
display: 'flex',
|
|
3880
|
+
flexWrap: 'wrap',
|
|
3881
|
+
gap: sizeScale.gap,
|
|
3882
|
+
} }, rangeConfig.ranges.map((range) => {
|
|
3883
|
+
const count = countMap.get(range.label) ?? 0;
|
|
3884
|
+
const active = isRangeActive(range);
|
|
3885
|
+
return (React.createElement("button", { key: range.label, type: "button", className: clsx(facetsTheme.rangeButton, active && facetsTheme.rangeButtonActive), disabled: count === 0 && !active, onClick: () => handleRangeClick(range), style: {
|
|
3886
|
+
display: 'inline-flex',
|
|
3887
|
+
alignItems: 'center',
|
|
3888
|
+
gap: '0.35em',
|
|
3889
|
+
padding: `${sizeScale.padding} 0.75em`,
|
|
3890
|
+
fontSize: sizeScale.font,
|
|
3891
|
+
border: `1px solid ${active ? 'var(--seekora-primary, ' + theme.colors.primary + ')' : 'var(--seekora-facet-border, ' + theme.colors.border + ')'}`,
|
|
3892
|
+
borderRadius: typeof theme.borderRadius === 'string' ? theme.borderRadius : theme.borderRadius.full,
|
|
3893
|
+
backgroundColor: active ? 'var(--seekora-primary, ' + theme.colors.primary + ')' : 'var(--seekora-facet-bg, ' + theme.colors.background + ')',
|
|
3894
|
+
color: active ? 'var(--seekora-primary-text, #fff)' : theme.colors.text,
|
|
3895
|
+
cursor: count === 0 && !active ? 'not-allowed' : 'pointer',
|
|
3896
|
+
opacity: count === 0 && !active ? 0.5 : 1,
|
|
3897
|
+
transition: 'all 0.2s ease',
|
|
3898
|
+
} },
|
|
3899
|
+
range.label,
|
|
3900
|
+
showCounts && (React.createElement("span", { className: clsx(facetsTheme.rangeButtonCount), style: {
|
|
3901
|
+
fontSize: theme.typography.fontSize.small,
|
|
3902
|
+
opacity: 0.8,
|
|
3903
|
+
} },
|
|
3904
|
+
"(",
|
|
3905
|
+
count,
|
|
3906
|
+
")"))));
|
|
3907
|
+
})),
|
|
3908
|
+
hasActiveRange && (React.createElement("button", { type: "button", className: clsx(facetsTheme.rangeClear), onClick: handleClear, style: {
|
|
3909
|
+
marginTop: sizeScale.gap,
|
|
3910
|
+
padding: sizeScale.padding,
|
|
3911
|
+
border: 'none',
|
|
3912
|
+
backgroundColor: 'transparent',
|
|
3913
|
+
color: theme.colors.primary,
|
|
3914
|
+
cursor: 'pointer',
|
|
3915
|
+
fontSize: theme.typography.fontSize.small,
|
|
3916
|
+
textDecoration: 'underline',
|
|
3917
|
+
} }, "Clear"))));
|
|
3918
|
+
};
|
|
3919
|
+
// -------------------------------------------------------------------
|
|
3920
|
+
// Range slider facet renderer
|
|
3921
|
+
// -------------------------------------------------------------------
|
|
3922
|
+
const renderRangeSliderFacet = (facet, _index) => {
|
|
3923
|
+
if (!facet.stats)
|
|
3924
|
+
return null;
|
|
3925
|
+
const { min: statsMin, max: statsMax } = facet.stats;
|
|
3926
|
+
// Auto-detect formatting for common field names
|
|
3927
|
+
const fieldLower = facet.field.toLowerCase();
|
|
3928
|
+
const isPriceField = fieldLower.includes('price') || fieldLower.includes('cost') || fieldLower.includes('amount');
|
|
3929
|
+
const formatValue = isPriceField
|
|
3930
|
+
? (v) => `$${v.toFixed(2)}`
|
|
3931
|
+
: (v) => v.toString();
|
|
3932
|
+
// Determine step: use 0.01 for price, 1 for integer ranges, 0.1 otherwise
|
|
3933
|
+
const range = statsMax - statsMin;
|
|
3934
|
+
const step = isPriceField ? 0.01 : range > 10 ? 1 : 0.1;
|
|
3935
|
+
// Check if there's an active range refinement
|
|
3936
|
+
const hasActiveRange = refinements.some((r) => r.field === facet.field && (r.value.startsWith('>=') || r.value.startsWith('<=')));
|
|
3937
|
+
const handleClear = () => {
|
|
3938
|
+
refinements
|
|
3939
|
+
.filter((r) => r.field === facet.field && (r.value.startsWith('>=') || r.value.startsWith('<=')))
|
|
3940
|
+
.forEach((r) => removeRefinement(facet.field, r.value, false));
|
|
3941
|
+
// Trigger search after clearing
|
|
3942
|
+
addRefinement(facet.field, '__noop__', false);
|
|
3943
|
+
removeRefinement(facet.field, '__noop__', true);
|
|
3944
|
+
};
|
|
3945
|
+
return (React.createElement("div", { key: facet.field, className: facetsTheme.facet, style: {
|
|
3946
|
+
marginBottom: theme.spacing.large,
|
|
3947
|
+
padding: theme.spacing.medium,
|
|
3948
|
+
backgroundColor: 'var(--seekora-facet-bg, ' + theme.colors.background + ')',
|
|
3949
|
+
border: `1px solid var(--seekora-facet-border, ${theme.colors.border})`,
|
|
3950
|
+
borderRadius: typeof theme.borderRadius === 'string' ? theme.borderRadius : theme.borderRadius.medium,
|
|
3951
|
+
} },
|
|
3952
|
+
React.createElement("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: theme.spacing.small } },
|
|
3953
|
+
React.createElement("h3", { className: facetsTheme.facetTitle, style: {
|
|
3954
|
+
fontSize: theme.typography.fontSize.large,
|
|
3955
|
+
fontWeight: 'bold',
|
|
3956
|
+
margin: 0,
|
|
3957
|
+
color: theme.colors.text,
|
|
3958
|
+
} }, facet.label || facet.field),
|
|
3959
|
+
hasActiveRange && (React.createElement("button", { type: "button", className: clsx(facetsTheme.rangeClear), onClick: handleClear, style: {
|
|
3960
|
+
padding: '0.15em 0.5em',
|
|
3961
|
+
border: 'none',
|
|
3962
|
+
backgroundColor: 'transparent',
|
|
3963
|
+
color: theme.colors.primary,
|
|
3964
|
+
cursor: 'pointer',
|
|
3965
|
+
fontSize: theme.typography.fontSize.small,
|
|
3966
|
+
textDecoration: 'underline',
|
|
3967
|
+
} }, "Clear"))),
|
|
3968
|
+
React.createElement(RangeSlider, { field: facet.field, min: statsMin, max: statsMax, step: step, formatValue: formatValue, syncWithState: true })));
|
|
3969
|
+
};
|
|
3970
|
+
// -------------------------------------------------------------------
|
|
3971
|
+
// Default facet renderer dispatcher
|
|
3972
|
+
// -------------------------------------------------------------------
|
|
3973
|
+
const defaultRenderFacet = (facet, index) => {
|
|
3974
|
+
const renderType = determineFacetRenderType(facet.field, facet.stats);
|
|
3975
|
+
if (renderType === 'range-buttons') {
|
|
3976
|
+
return renderRangeButtonFacet(facet);
|
|
3977
|
+
}
|
|
3978
|
+
if (renderType === 'range-slider') {
|
|
3979
|
+
return renderRangeSliderFacet(facet);
|
|
3980
|
+
}
|
|
3981
|
+
switch (variant) {
|
|
3982
|
+
case 'color-swatch':
|
|
3983
|
+
return renderColorSwatchFacet(facet);
|
|
3984
|
+
case 'collapsible':
|
|
3985
|
+
return renderCollapsibleFacet(facet);
|
|
3986
|
+
case 'checkbox':
|
|
3987
|
+
default:
|
|
3988
|
+
return renderCheckboxFacet(facet);
|
|
3989
|
+
}
|
|
3990
|
+
};
|
|
3991
|
+
// -------------------------------------------------------------------
|
|
3992
|
+
// Empty state
|
|
3534
3993
|
// -------------------------------------------------------------------
|
|
3535
3994
|
if (facets.length === 0) {
|
|
3536
3995
|
log.verbose('Facets: No facets to display', {
|
|
@@ -3552,12 +4011,381 @@ const Facets = ({ results: resultsProp, facets: facetsProp, onFacetChange, rende
|
|
|
3552
4011
|
})));
|
|
3553
4012
|
};
|
|
3554
4013
|
|
|
4014
|
+
/**
|
|
4015
|
+
* FacetDropdown Component
|
|
4016
|
+
*
|
|
4017
|
+
* A dropdown component that displays facet values from a specific field
|
|
4018
|
+
* and allows users to filter search results by selecting values.
|
|
4019
|
+
*
|
|
4020
|
+
* Can be used standalone (fetches its own data) or integrated with SearchProvider.
|
|
4021
|
+
*
|
|
4022
|
+
* @cssVariables
|
|
4023
|
+
* Customize the dropdown appearance using CSS variables:
|
|
4024
|
+
*
|
|
4025
|
+
* Button:
|
|
4026
|
+
* - `--facet-dropdown-button-bg`: Button background color
|
|
4027
|
+
* - `--facet-dropdown-text`: Button text color
|
|
4028
|
+
* - `--facet-dropdown-border`: Button and panel border color
|
|
4029
|
+
* - `--facet-dropdown-font-size`: Button font size (default: 0.875rem)
|
|
4030
|
+
* - `--facet-dropdown-font-weight`: Button font weight (default: 500)
|
|
4031
|
+
*
|
|
4032
|
+
* Dropdown Panel:
|
|
4033
|
+
* - `--facet-dropdown-bg`: Panel background color
|
|
4034
|
+
* - `--facet-dropdown-shadow`: Panel box shadow
|
|
4035
|
+
*
|
|
4036
|
+
* Options:
|
|
4037
|
+
* - `--facet-dropdown-option-text`: Option text color
|
|
4038
|
+
* - `--facet-dropdown-option-font-size`: Option font size (default: 0.875rem)
|
|
4039
|
+
* - `--facet-dropdown-option-font-weight-active`: Active option font weight (default: 500)
|
|
4040
|
+
* - `--facet-dropdown-option-active-bg`: Active option background color
|
|
4041
|
+
*
|
|
4042
|
+
* Count Badge:
|
|
4043
|
+
* - `--facet-dropdown-count-text`: Count text color
|
|
4044
|
+
* - `--facet-dropdown-count-font-size`: Count font size (default: 0.75rem)
|
|
4045
|
+
*
|
|
4046
|
+
* Scrollbar:
|
|
4047
|
+
* - `--facet-dropdown-scrollbar-thumb`: Scrollbar thumb color
|
|
4048
|
+
* - `--facet-dropdown-scrollbar-thumb-hover`: Scrollbar thumb hover color
|
|
4049
|
+
*
|
|
4050
|
+
* @example
|
|
4051
|
+
* ```tsx
|
|
4052
|
+
* <FacetDropdown
|
|
4053
|
+
* field="category"
|
|
4054
|
+
* placeholder="All Categories"
|
|
4055
|
+
* applyFilter={true}
|
|
4056
|
+
* showCounts={true}
|
|
4057
|
+
* />
|
|
4058
|
+
* ```
|
|
4059
|
+
*/
|
|
4060
|
+
// Z-index scale for consistent layering
|
|
4061
|
+
// SearchOverlay uses z-100, so dropdown must be higher
|
|
4062
|
+
const Z_INDEX$1 = {
|
|
4063
|
+
dropdown: 150};
|
|
4064
|
+
// ---------------------------------------------------------------------------
|
|
4065
|
+
// Component
|
|
4066
|
+
// ---------------------------------------------------------------------------
|
|
4067
|
+
const FacetDropdown = ({ field, placeholder = 'All Categories', className, theme: customTheme = {}, onChange, value: controlledValue, maxOptions = 10, showCounts = true, options: providedOptions, client: providedClient, applyFilter = true, navigateOnSelect = false, searchPageUrl = '/search', }) => {
|
|
4068
|
+
const { client: contextClient, theme } = useSearchContext();
|
|
4069
|
+
const { addRefinement, removeRefinement, refinements, search } = useSearchState();
|
|
4070
|
+
const client = providedClient || contextClient;
|
|
4071
|
+
const [open, setOpen] = useState(false);
|
|
4072
|
+
const [facetOptions, setFacetOptions] = useState(providedOptions || []);
|
|
4073
|
+
const [internalValue, setInternalValue] = useState(controlledValue || '');
|
|
4074
|
+
const [dropdownPosition, setDropdownPosition] = useState(null);
|
|
4075
|
+
const dropdownRef = useRef(null);
|
|
4076
|
+
const buttonRef = useRef(null);
|
|
4077
|
+
// Determine the current value (controlled or uncontrolled)
|
|
4078
|
+
const currentValue = controlledValue !== undefined ? controlledValue : internalValue;
|
|
4079
|
+
// ---------------------------------------------------------------------------
|
|
4080
|
+
// Fetch facet values
|
|
4081
|
+
// ---------------------------------------------------------------------------
|
|
4082
|
+
const fetchFacetValues = useCallback(async () => {
|
|
4083
|
+
if (providedOptions || !client)
|
|
4084
|
+
return;
|
|
4085
|
+
try {
|
|
4086
|
+
log.verbose('FacetDropdown: Fetching facet values', { field });
|
|
4087
|
+
// Perform a search with facet_by parameter to get facet counts
|
|
4088
|
+
const response = await client.search('*', {
|
|
4089
|
+
facet_by: field,
|
|
4090
|
+
max_facet_values: 100,
|
|
4091
|
+
per_page: 0, // We only need facets, not results
|
|
4092
|
+
});
|
|
4093
|
+
log.verbose('FacetDropdown: Search response', { response });
|
|
4094
|
+
// Extract facet counts from the response
|
|
4095
|
+
const facetsData = response?.data?.facets || response?.facets;
|
|
4096
|
+
const facets = Array.isArray(facetsData) ? facetsData : [];
|
|
4097
|
+
const targetFacet = facets.find((f) => f.field_name === field || f.field === field);
|
|
4098
|
+
if (targetFacet && targetFacet.counts) {
|
|
4099
|
+
const options = targetFacet.counts.map((count) => ({
|
|
4100
|
+
value: count.value,
|
|
4101
|
+
count: count.count,
|
|
4102
|
+
label: count.value,
|
|
4103
|
+
}));
|
|
4104
|
+
setFacetOptions(options);
|
|
4105
|
+
log.verbose('FacetDropdown: Facet options loaded', { field, count: options.length });
|
|
4106
|
+
}
|
|
4107
|
+
else {
|
|
4108
|
+
log.verbose('FacetDropdown: No facet data found', { field, facets });
|
|
4109
|
+
setFacetOptions([]);
|
|
4110
|
+
}
|
|
4111
|
+
}
|
|
4112
|
+
catch (error) {
|
|
4113
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
4114
|
+
log.error('FacetDropdown: Error fetching facet values', {
|
|
4115
|
+
field,
|
|
4116
|
+
error: err.message,
|
|
4117
|
+
});
|
|
4118
|
+
setFacetOptions([]);
|
|
4119
|
+
}
|
|
4120
|
+
}, [field, client, providedOptions]);
|
|
4121
|
+
useEffect(() => {
|
|
4122
|
+
if (!providedOptions && client) {
|
|
4123
|
+
fetchFacetValues();
|
|
4124
|
+
}
|
|
4125
|
+
}, [fetchFacetValues, providedOptions, client]);
|
|
4126
|
+
// ---------------------------------------------------------------------------
|
|
4127
|
+
// Calculate dropdown position when opened
|
|
4128
|
+
// ---------------------------------------------------------------------------
|
|
4129
|
+
useEffect(() => {
|
|
4130
|
+
if (!open || !buttonRef.current)
|
|
4131
|
+
return;
|
|
4132
|
+
const updatePosition = () => {
|
|
4133
|
+
if (!buttonRef.current)
|
|
4134
|
+
return;
|
|
4135
|
+
const rect = buttonRef.current.getBoundingClientRect();
|
|
4136
|
+
setDropdownPosition({
|
|
4137
|
+
top: rect.bottom + window.scrollY + 4,
|
|
4138
|
+
left: rect.left + window.scrollX,
|
|
4139
|
+
width: rect.width,
|
|
4140
|
+
});
|
|
4141
|
+
};
|
|
4142
|
+
updatePosition();
|
|
4143
|
+
window.addEventListener('scroll', updatePosition, true);
|
|
4144
|
+
window.addEventListener('resize', updatePosition);
|
|
4145
|
+
return () => {
|
|
4146
|
+
window.removeEventListener('scroll', updatePosition, true);
|
|
4147
|
+
window.removeEventListener('resize', updatePosition);
|
|
4148
|
+
};
|
|
4149
|
+
}, [open]);
|
|
4150
|
+
// ---------------------------------------------------------------------------
|
|
4151
|
+
// Click outside handler
|
|
4152
|
+
// ---------------------------------------------------------------------------
|
|
4153
|
+
useEffect(() => {
|
|
4154
|
+
if (!open)
|
|
4155
|
+
return;
|
|
4156
|
+
const handleClickOutside = (e) => {
|
|
4157
|
+
if (dropdownRef.current &&
|
|
4158
|
+
!dropdownRef.current.contains(e.target) &&
|
|
4159
|
+
buttonRef.current &&
|
|
4160
|
+
!buttonRef.current.contains(e.target)) {
|
|
4161
|
+
setOpen(false);
|
|
4162
|
+
}
|
|
4163
|
+
};
|
|
4164
|
+
const handleEscape = (e) => {
|
|
4165
|
+
if (e.key === 'Escape') {
|
|
4166
|
+
setOpen(false);
|
|
4167
|
+
}
|
|
4168
|
+
};
|
|
4169
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
4170
|
+
document.addEventListener('keydown', handleEscape);
|
|
4171
|
+
return () => {
|
|
4172
|
+
document.removeEventListener('mousedown', handleClickOutside);
|
|
4173
|
+
document.removeEventListener('keydown', handleEscape);
|
|
4174
|
+
};
|
|
4175
|
+
}, [open]);
|
|
4176
|
+
// ---------------------------------------------------------------------------
|
|
4177
|
+
// Selection handler
|
|
4178
|
+
// ---------------------------------------------------------------------------
|
|
4179
|
+
const handleSelect = useCallback((value) => {
|
|
4180
|
+
log.verbose('FacetDropdown: Value selected', { field, value });
|
|
4181
|
+
// Update internal state
|
|
4182
|
+
setInternalValue(value);
|
|
4183
|
+
setOpen(false);
|
|
4184
|
+
// Call onChange callback
|
|
4185
|
+
if (onChange) {
|
|
4186
|
+
onChange(value);
|
|
4187
|
+
}
|
|
4188
|
+
// Apply filter if enabled and we have search state
|
|
4189
|
+
if (applyFilter && addRefinement && removeRefinement) {
|
|
4190
|
+
// Remove any existing refinement for this field
|
|
4191
|
+
const existingRefinement = refinements.find(r => r.field === field);
|
|
4192
|
+
if (existingRefinement) {
|
|
4193
|
+
removeRefinement(field, existingRefinement.value, false);
|
|
4194
|
+
}
|
|
4195
|
+
// Add new refinement if value is not empty
|
|
4196
|
+
if (value) {
|
|
4197
|
+
addRefinement(field, value, true); // true = trigger search
|
|
4198
|
+
}
|
|
4199
|
+
else if (search) {
|
|
4200
|
+
// If clearing the filter, trigger search manually
|
|
4201
|
+
search();
|
|
4202
|
+
}
|
|
4203
|
+
}
|
|
4204
|
+
// Navigate to search page if enabled
|
|
4205
|
+
if (navigateOnSelect && value && typeof window !== 'undefined') {
|
|
4206
|
+
const url = new URL(window.location.origin + searchPageUrl);
|
|
4207
|
+
url.searchParams.set(field, value);
|
|
4208
|
+
window.location.href = url.toString();
|
|
4209
|
+
}
|
|
4210
|
+
}, [field, onChange, applyFilter, addRefinement, removeRefinement, refinements, search, navigateOnSelect, searchPageUrl]);
|
|
4211
|
+
// ---------------------------------------------------------------------------
|
|
4212
|
+
// Render
|
|
4213
|
+
// ---------------------------------------------------------------------------
|
|
4214
|
+
const displayLabel = currentValue || placeholder;
|
|
4215
|
+
const hasOptions = facetOptions.length > 0;
|
|
4216
|
+
const buttonClass = [
|
|
4217
|
+
'facet-dropdown-button',
|
|
4218
|
+
customTheme.button,
|
|
4219
|
+
className,
|
|
4220
|
+
open && customTheme.buttonOpen,
|
|
4221
|
+
]
|
|
4222
|
+
.filter(Boolean)
|
|
4223
|
+
.join(' ');
|
|
4224
|
+
// Render dropdown panel via portal
|
|
4225
|
+
const renderDropdown = () => {
|
|
4226
|
+
if (!open || !hasOptions || !dropdownPosition || typeof document === 'undefined') {
|
|
4227
|
+
return null;
|
|
4228
|
+
}
|
|
4229
|
+
const dropdown = (React.createElement("div", { ref: dropdownRef, className: customTheme.panel || 'facet-dropdown-panel', role: "listbox", "aria-label": `${field} options`, style: {
|
|
4230
|
+
position: 'absolute',
|
|
4231
|
+
top: `${dropdownPosition.top}px`,
|
|
4232
|
+
left: `${dropdownPosition.left}px`,
|
|
4233
|
+
minWidth: `${dropdownPosition.width}px`,
|
|
4234
|
+
width: 'max-content',
|
|
4235
|
+
maxWidth: 'min(24rem, 90vw)',
|
|
4236
|
+
maxHeight: `calc(100vh - 100px)`,
|
|
4237
|
+
overflowY: 'auto',
|
|
4238
|
+
overflowX: 'hidden',
|
|
4239
|
+
backgroundColor: 'var(--facet-dropdown-bg, var(--background))',
|
|
4240
|
+
border: '1px solid var(--facet-dropdown-border, var(--border-color))',
|
|
4241
|
+
borderRadius: theme?.borderRadius && typeof theme.borderRadius !== 'string'
|
|
4242
|
+
? theme.borderRadius.medium
|
|
4243
|
+
: '0.5rem',
|
|
4244
|
+
boxShadow: 'var(--facet-dropdown-shadow, var(--shadow-lg))',
|
|
4245
|
+
zIndex: Z_INDEX$1.dropdown,
|
|
4246
|
+
padding: '0.25rem',
|
|
4247
|
+
} },
|
|
4248
|
+
React.createElement("button", { type: "button", role: "option", "aria-selected": !currentValue, onClick: (e) => {
|
|
4249
|
+
e.preventDefault();
|
|
4250
|
+
e.stopPropagation();
|
|
4251
|
+
handleSelect('');
|
|
4252
|
+
}, className: [
|
|
4253
|
+
customTheme.option,
|
|
4254
|
+
!currentValue && customTheme.optionActive,
|
|
4255
|
+
]
|
|
4256
|
+
.filter(Boolean)
|
|
4257
|
+
.join(' '), style: {
|
|
4258
|
+
width: '100%',
|
|
4259
|
+
textAlign: 'left',
|
|
4260
|
+
padding: '0.5rem 0.75rem',
|
|
4261
|
+
fontSize: 'var(--facet-dropdown-option-font-size, 0.875rem)',
|
|
4262
|
+
fontWeight: !currentValue ? 'var(--facet-dropdown-option-font-weight-active, 500)' : 'normal',
|
|
4263
|
+
color: 'var(--facet-dropdown-option-text, var(--text-color, currentColor))',
|
|
4264
|
+
backgroundColor: !currentValue ? 'var(--facet-dropdown-option-active-bg, var(--hover-color))' : 'transparent',
|
|
4265
|
+
border: 'none',
|
|
4266
|
+
borderRadius: theme?.borderRadius && typeof theme.borderRadius !== 'string'
|
|
4267
|
+
? theme.borderRadius.small
|
|
4268
|
+
: '0.25rem',
|
|
4269
|
+
cursor: 'pointer',
|
|
4270
|
+
transition: 'background-color 0.15s ease',
|
|
4271
|
+
display: 'flex',
|
|
4272
|
+
alignItems: 'center',
|
|
4273
|
+
justifyContent: 'space-between',
|
|
4274
|
+
} },
|
|
4275
|
+
React.createElement("span", null, placeholder)),
|
|
4276
|
+
facetOptions.map((option) => {
|
|
4277
|
+
const isActive = currentValue === option.value;
|
|
4278
|
+
return (React.createElement("button", { key: option.value, type: "button", role: "option", "aria-selected": isActive, onClick: (e) => {
|
|
4279
|
+
e.preventDefault();
|
|
4280
|
+
e.stopPropagation();
|
|
4281
|
+
handleSelect(option.value);
|
|
4282
|
+
}, className: [
|
|
4283
|
+
customTheme.option,
|
|
4284
|
+
isActive && customTheme.optionActive,
|
|
4285
|
+
]
|
|
4286
|
+
.filter(Boolean)
|
|
4287
|
+
.join(' '), style: {
|
|
4288
|
+
width: '100%',
|
|
4289
|
+
textAlign: 'left',
|
|
4290
|
+
padding: '0.5rem 0.75rem',
|
|
4291
|
+
fontSize: 'var(--facet-dropdown-option-font-size, 0.875rem)',
|
|
4292
|
+
fontWeight: isActive ? 'var(--facet-dropdown-option-font-weight-active, 500)' : 'normal',
|
|
4293
|
+
color: 'var(--facet-dropdown-option-text, var(--text-color, currentColor))',
|
|
4294
|
+
backgroundColor: isActive ? 'var(--facet-dropdown-option-active-bg, var(--hover-color))' : 'transparent',
|
|
4295
|
+
border: 'none',
|
|
4296
|
+
borderRadius: theme?.borderRadius && typeof theme.borderRadius !== 'string'
|
|
4297
|
+
? theme.borderRadius.small
|
|
4298
|
+
: '0.25rem',
|
|
4299
|
+
cursor: 'pointer',
|
|
4300
|
+
transition: 'background-color 0.15s ease',
|
|
4301
|
+
display: 'flex',
|
|
4302
|
+
alignItems: 'center',
|
|
4303
|
+
justifyContent: 'space-between',
|
|
4304
|
+
} },
|
|
4305
|
+
React.createElement("span", { style: { flex: 1, overflow: 'hidden', textOverflow: 'ellipsis' } }, option.label || option.value),
|
|
4306
|
+
showCounts && (React.createElement("span", { style: {
|
|
4307
|
+
fontSize: 'var(--facet-dropdown-count-font-size, 0.75rem)',
|
|
4308
|
+
color: 'var(--facet-dropdown-count-text, var(--text-secondary, currentColor))',
|
|
4309
|
+
opacity: 0.7,
|
|
4310
|
+
marginLeft: '0.5rem',
|
|
4311
|
+
flexShrink: 0,
|
|
4312
|
+
} },
|
|
4313
|
+
"(",
|
|
4314
|
+
option.count,
|
|
4315
|
+
")"))));
|
|
4316
|
+
})));
|
|
4317
|
+
return createPortal(dropdown, document.body);
|
|
4318
|
+
};
|
|
4319
|
+
return (React.createElement("div", { className: "facet-dropdown-container", style: { position: 'relative' } },
|
|
4320
|
+
React.createElement("style", { dangerouslySetInnerHTML: {
|
|
4321
|
+
__html: `
|
|
4322
|
+
.facet-dropdown-panel {
|
|
4323
|
+
--scrollbar-track: transparent;
|
|
4324
|
+
--scrollbar-thumb: var(--facet-dropdown-scrollbar-thumb, var(--border-color));
|
|
4325
|
+
--scrollbar-thumb-hover: var(--facet-dropdown-scrollbar-thumb-hover, var(--text-secondary));
|
|
4326
|
+
}
|
|
4327
|
+
.facet-dropdown-panel::-webkit-scrollbar {
|
|
4328
|
+
width: 6px;
|
|
4329
|
+
}
|
|
4330
|
+
.facet-dropdown-panel::-webkit-scrollbar-track {
|
|
4331
|
+
background: var(--scrollbar-track);
|
|
4332
|
+
}
|
|
4333
|
+
.facet-dropdown-panel::-webkit-scrollbar-thumb {
|
|
4334
|
+
background: var(--scrollbar-thumb);
|
|
4335
|
+
border-radius: 3px;
|
|
4336
|
+
}
|
|
4337
|
+
.facet-dropdown-panel::-webkit-scrollbar-thumb:hover {
|
|
4338
|
+
background: var(--scrollbar-thumb-hover);
|
|
4339
|
+
}
|
|
4340
|
+
.facet-dropdown-panel {
|
|
4341
|
+
scrollbar-width: thin;
|
|
4342
|
+
scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track);
|
|
4343
|
+
}
|
|
4344
|
+
`
|
|
4345
|
+
} }),
|
|
4346
|
+
React.createElement("button", { ref: buttonRef, type: "button", onClick: (e) => {
|
|
4347
|
+
e.preventDefault();
|
|
4348
|
+
e.stopPropagation();
|
|
4349
|
+
setOpen(prev => !prev);
|
|
4350
|
+
}, className: buttonClass, "aria-label": `Filter by ${field}`, "aria-expanded": open, "aria-haspopup": "listbox", style: {
|
|
4351
|
+
display: 'flex',
|
|
4352
|
+
alignItems: 'center',
|
|
4353
|
+
gap: '0.375rem',
|
|
4354
|
+
padding: '0.625rem 0.75rem',
|
|
4355
|
+
fontSize: 'var(--facet-dropdown-font-size, 0.875rem)',
|
|
4356
|
+
fontWeight: 'var(--facet-dropdown-font-weight, 500)',
|
|
4357
|
+
color: 'var(--facet-dropdown-text, var(--text-color, currentColor))',
|
|
4358
|
+
backgroundColor: 'var(--facet-dropdown-button-bg, var(--background, transparent))',
|
|
4359
|
+
border: '1px solid var(--facet-dropdown-border, var(--border-color))',
|
|
4360
|
+
borderRadius: theme?.borderRadius && typeof theme.borderRadius !== 'string'
|
|
4361
|
+
? theme.borderRadius.medium
|
|
4362
|
+
: '0.5rem',
|
|
4363
|
+
cursor: 'pointer',
|
|
4364
|
+
transition: 'all 0.2s ease',
|
|
4365
|
+
outline: 'none',
|
|
4366
|
+
whiteSpace: 'nowrap',
|
|
4367
|
+
minWidth: '8rem',
|
|
4368
|
+
...(!hasOptions && { opacity: 0.6, cursor: 'not-allowed' }),
|
|
4369
|
+
}, disabled: !hasOptions },
|
|
4370
|
+
React.createElement("span", { style: { flex: 1, textAlign: 'left', overflow: 'hidden', textOverflow: 'ellipsis' } }, displayLabel),
|
|
4371
|
+
React.createElement("svg", { className: customTheme.caretIcon, width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", style: {
|
|
4372
|
+
transform: open ? 'rotate(180deg)' : 'rotate(0deg)',
|
|
4373
|
+
transition: 'transform 0.2s ease',
|
|
4374
|
+
flexShrink: 0,
|
|
4375
|
+
}, "aria-hidden": "true" },
|
|
4376
|
+
React.createElement("path", { d: "M4 6L8 10L12 6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }))),
|
|
4377
|
+
renderDropdown()));
|
|
4378
|
+
};
|
|
4379
|
+
|
|
3555
4380
|
/**
|
|
3556
4381
|
* CurrentRefinements Component
|
|
3557
4382
|
*
|
|
3558
4383
|
* Displays currently active filters/refinements with ability to clear them.
|
|
3559
4384
|
* Supports StateManager auto-sync, display variants, layout modes, and animations.
|
|
3560
4385
|
*/
|
|
4386
|
+
const TRANSITIONS$7 = {
|
|
4387
|
+
fast: '150ms ease-in-out',
|
|
4388
|
+
normal: '200ms ease-in-out'};
|
|
3561
4389
|
/** Get variant-specific styles */
|
|
3562
4390
|
const getVariantStyles = (variant, themeColors, themeSpacing, themeBorderRadius, fieldColor) => {
|
|
3563
4391
|
const baseBg = fieldColor || `var(--seekora-refinement-bg, ${themeColors.hover})`;
|
|
@@ -3641,10 +4469,59 @@ const CurrentRefinements = ({ refinements: refinementsProp, onRefinementClear, o
|
|
|
3641
4469
|
const { theme } = useSearchContext();
|
|
3642
4470
|
const { refinements: stateRefinements, removeRefinement, clearRefinements } = useSearchState();
|
|
3643
4471
|
const refinementsTheme = customTheme || {};
|
|
4472
|
+
// Format a numeric value for display (auto-detect price fields)
|
|
4473
|
+
const formatRangeValue = (field, val) => {
|
|
4474
|
+
const f = field.toLowerCase();
|
|
4475
|
+
if (f.includes('price') || f.includes('cost') || f.includes('amount')) {
|
|
4476
|
+
return `$${val.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
|
|
4477
|
+
}
|
|
4478
|
+
return val.toLocaleString();
|
|
4479
|
+
};
|
|
4480
|
+
// Create a stable serialized key from stateRefinements to detect actual changes
|
|
4481
|
+
// (needed because state manager mutates the array in place)
|
|
4482
|
+
const stateRefinementsKey = useMemo(() => stateRefinements.map(r => `${r.field}:${r.value}`).sort().join('|'), [stateRefinements.map(r => `${r.field}:${r.value}`).sort().join('|')]);
|
|
3644
4483
|
// Use props if provided, otherwise auto-read from StateManager
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
4484
|
+
// Combines >= / <= range refinements into single formatted pills
|
|
4485
|
+
const refinements = useMemo(() => {
|
|
4486
|
+
if (refinementsProp !== undefined) {
|
|
4487
|
+
return refinementsProp;
|
|
4488
|
+
}
|
|
4489
|
+
const rangeMap = new Map();
|
|
4490
|
+
const nonRange = [];
|
|
4491
|
+
stateRefinements.forEach(r => {
|
|
4492
|
+
const minMatch = r.value.match(/^>=(\d+(?:\.\d+)?)$/);
|
|
4493
|
+
const maxMatch = r.value.match(/^<=(\d+(?:\.\d+)?)$/);
|
|
4494
|
+
if (minMatch || maxMatch) {
|
|
4495
|
+
if (!rangeMap.has(r.field))
|
|
4496
|
+
rangeMap.set(r.field, {});
|
|
4497
|
+
const entry = rangeMap.get(r.field);
|
|
4498
|
+
if (minMatch)
|
|
4499
|
+
entry.minVal = parseFloat(minMatch[1]);
|
|
4500
|
+
if (maxMatch)
|
|
4501
|
+
entry.maxVal = parseFloat(maxMatch[1]);
|
|
4502
|
+
}
|
|
4503
|
+
else {
|
|
4504
|
+
nonRange.push({ field: r.field, value: r.value });
|
|
4505
|
+
}
|
|
4506
|
+
});
|
|
4507
|
+
rangeMap.forEach((range, field) => {
|
|
4508
|
+
let displayValue;
|
|
4509
|
+
if (range.minVal !== undefined && range.maxVal !== undefined) {
|
|
4510
|
+
displayValue = `${formatRangeValue(field, range.minVal)} – ${formatRangeValue(field, range.maxVal)}`;
|
|
4511
|
+
}
|
|
4512
|
+
else if (range.minVal !== undefined) {
|
|
4513
|
+
displayValue = `≥ ${formatRangeValue(field, range.minVal)}`;
|
|
4514
|
+
}
|
|
4515
|
+
else if (range.maxVal !== undefined) {
|
|
4516
|
+
displayValue = `≤ ${formatRangeValue(field, range.maxVal)}`;
|
|
4517
|
+
}
|
|
4518
|
+
else {
|
|
4519
|
+
return;
|
|
4520
|
+
}
|
|
4521
|
+
nonRange.push({ field, value: '__range__', displayValue });
|
|
4522
|
+
});
|
|
4523
|
+
return nonRange;
|
|
4524
|
+
}, [refinementsProp, stateRefinementsKey]);
|
|
3648
4525
|
// Track items for entry/exit animations
|
|
3649
4526
|
const [visibleItems, setVisibleItems] = useState(new Set());
|
|
3650
4527
|
const [exitingItems, setExitingItems] = useState(new Set());
|
|
@@ -3668,9 +4545,15 @@ const CurrentRefinements = ({ refinements: refinementsProp, onRefinementClear, o
|
|
|
3668
4545
|
prevRefinementsRef.current = [...refinements];
|
|
3669
4546
|
}, [refinements]);
|
|
3670
4547
|
const handleClear = (field, value) => {
|
|
3671
|
-
// If synced with StateManager and no prop provided, auto-clear via StateManager
|
|
3672
4548
|
if (refinementsProp === undefined) {
|
|
3673
|
-
|
|
4549
|
+
if (value === '__range__') {
|
|
4550
|
+
// Clear all range refinements for this field
|
|
4551
|
+
const rangeRefs = stateRefinements.filter(r => r.field === field && (/^>=/.test(r.value) || /^<=/.test(r.value)));
|
|
4552
|
+
rangeRefs.forEach((r, i) => removeRefinement(field, r.value, i === rangeRefs.length - 1));
|
|
4553
|
+
}
|
|
4554
|
+
else {
|
|
4555
|
+
removeRefinement(field, value);
|
|
4556
|
+
}
|
|
3674
4557
|
}
|
|
3675
4558
|
if (onRefinementClear) {
|
|
3676
4559
|
onRefinementClear(field, value);
|
|
@@ -3697,7 +4580,7 @@ const CurrentRefinements = ({ refinements: refinementsProp, onRefinementClear, o
|
|
|
3697
4580
|
margin: layout === 'vertical'
|
|
3698
4581
|
? `0 0 ${theme.spacing.small} 0`
|
|
3699
4582
|
: `0 ${theme.spacing.small} ${theme.spacing.small} 0`,
|
|
3700
|
-
transition:
|
|
4583
|
+
transition: `all ${TRANSITIONS$7.normal}`,
|
|
3701
4584
|
opacity: exitingItems.has(key) ? 0 : 1,
|
|
3702
4585
|
transform: exitingItems.has(key) ? 'scale(0.8)' : 'scale(1)',
|
|
3703
4586
|
animation: isEntering ? 'seekoraChipIn 200ms ease-out' : undefined,
|
|
@@ -3721,7 +4604,7 @@ const CurrentRefinements = ({ refinements: refinementsProp, onRefinementClear, o
|
|
|
3721
4604
|
alignItems: 'center',
|
|
3722
4605
|
justifyContent: 'center',
|
|
3723
4606
|
borderRadius: '50%',
|
|
3724
|
-
transition:
|
|
4607
|
+
transition: `opacity ${TRANSITIONS$7.fast}`,
|
|
3725
4608
|
opacity: 0.6,
|
|
3726
4609
|
}, "aria-label": `Clear ${refinement.label || refinement.field}: ${refinement.value}`, onMouseEnter: e => (e.currentTarget.style.opacity = '1'), onMouseLeave: e => (e.currentTarget.style.opacity = '0.6') }, renderCloseIcon ? renderCloseIcon() : defaultCloseIcon())));
|
|
3727
4610
|
};
|
|
@@ -3780,7 +4663,7 @@ const CurrentRefinements = ({ refinements: refinementsProp, onRefinementClear, o
|
|
|
3780
4663
|
cursor: 'pointer',
|
|
3781
4664
|
fontSize: theme.typography.fontSize.small,
|
|
3782
4665
|
textDecoration: 'underline',
|
|
3783
|
-
transition:
|
|
4666
|
+
transition: `background-color ${TRANSITIONS$7.fast}`,
|
|
3784
4667
|
} }, "Clear all filters"))));
|
|
3785
4668
|
};
|
|
3786
4669
|
|
|
@@ -3882,6 +4765,8 @@ const SearchLayout = ({ sidebar, children, header, footer, sidebarWidth = '300px
|
|
|
3882
4765
|
display: 'flex',
|
|
3883
4766
|
flexDirection: 'column',
|
|
3884
4767
|
minHeight: '100vh',
|
|
4768
|
+
width: '100%',
|
|
4769
|
+
maxWidth: '100%',
|
|
3885
4770
|
backgroundColor: theme.colors.background,
|
|
3886
4771
|
...style,
|
|
3887
4772
|
} },
|
|
@@ -3893,20 +4778,27 @@ const SearchLayout = ({ sidebar, children, header, footer, sidebarWidth = '300px
|
|
|
3893
4778
|
React.createElement("div", { style: {
|
|
3894
4779
|
display: 'flex',
|
|
3895
4780
|
flex: 1,
|
|
4781
|
+
width: '100%',
|
|
4782
|
+
maxWidth: '100%',
|
|
3896
4783
|
gap: theme.spacing.large,
|
|
3897
4784
|
padding: theme.spacing.medium,
|
|
3898
4785
|
backgroundColor: theme.colors.background,
|
|
3899
4786
|
color: theme.colors.text,
|
|
4787
|
+
overflow: 'hidden',
|
|
3900
4788
|
} },
|
|
3901
4789
|
sidebar && (!isMobile || showSidebarOnMobile) && (React.createElement("aside", { className: layoutTheme.sidebar, style: {
|
|
3902
4790
|
width: sidebarWidth,
|
|
3903
4791
|
minWidth: sidebarWidth,
|
|
4792
|
+
flexShrink: 0,
|
|
3904
4793
|
} }, sidebar)),
|
|
3905
4794
|
React.createElement("main", { className: layoutTheme.main, style: {
|
|
3906
4795
|
flex: 1,
|
|
3907
|
-
minWidth: 0,
|
|
4796
|
+
minWidth: 0,
|
|
4797
|
+
width: '100%',
|
|
4798
|
+
maxWidth: '100%',
|
|
3908
4799
|
backgroundColor: theme.colors.background,
|
|
3909
4800
|
color: theme.colors.text,
|
|
4801
|
+
overflow: 'auto',
|
|
3910
4802
|
} }, children)),
|
|
3911
4803
|
footer && (React.createElement("footer", { className: layoutTheme.footer, style: {
|
|
3912
4804
|
padding: theme.spacing.medium,
|
|
@@ -3948,11 +4840,11 @@ const RangeInput = ({ field, label, min, max, currentMin: currentMinProp, curren
|
|
|
3948
4840
|
const { refinements, addRefinement, removeRefinement } = useSearchState();
|
|
3949
4841
|
const rangeInputTheme = customTheme || {};
|
|
3950
4842
|
// Parse current range from StateManager
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
4843
|
+
// NOTE: computed every render (no useMemo) because the state manager mutates
|
|
4844
|
+
// the refinements array in place — the reference never changes.
|
|
4845
|
+
const stateRange = !syncWithState
|
|
4846
|
+
? { min: undefined, max: undefined }
|
|
4847
|
+
: parseRangeFromRefinements(refinements, field);
|
|
3956
4848
|
const [internalMin, setInternalMin] = useState(currentMinProp ?? stateRange.min);
|
|
3957
4849
|
const [internalMax, setInternalMax] = useState(currentMaxProp ?? stateRange.max);
|
|
3958
4850
|
const [appliedMin, setAppliedMin] = useState(currentMinProp ?? stateRange.min);
|
|
@@ -4715,311 +5607,78 @@ const HierarchicalMenu = ({ attributes, separator = ' > ', limit = 10, showMore
|
|
|
4715
5607
|
const button = parentItem.querySelector(':scope > button');
|
|
4716
5608
|
if (button)
|
|
4717
5609
|
button.focus();
|
|
4718
|
-
else
|
|
4719
|
-
parentItem.focus();
|
|
4720
|
-
}
|
|
4721
|
-
}
|
|
4722
|
-
}
|
|
4723
|
-
break;
|
|
4724
|
-
}
|
|
4725
|
-
case 'Enter': {
|
|
4726
|
-
if (!currentItem)
|
|
4727
|
-
break;
|
|
4728
|
-
e.preventDefault();
|
|
4729
|
-
const button = currentItem.querySelector('button');
|
|
4730
|
-
if (button)
|
|
4731
|
-
button.click();
|
|
4732
|
-
break;
|
|
4733
|
-
}
|
|
4734
|
-
}
|
|
4735
|
-
}, [getVisibleTreeItems]);
|
|
4736
|
-
// Render a level of the hierarchy
|
|
4737
|
-
const renderLevel = (items, level) => {
|
|
4738
|
-
if (!items || items.length === 0)
|
|
4739
|
-
return null;
|
|
4740
|
-
const isExpanded = expanded[level] || false;
|
|
4741
|
-
const displayLimit = isExpanded ? showMoreLimit : limit;
|
|
4742
|
-
const displayItems = items.slice(0, displayLimit);
|
|
4743
|
-
const hasMore = items.length > displayLimit;
|
|
4744
|
-
return (React.createElement("ul", { role: level === 0 ? 'tree' : 'group', className: hierarchicalTheme.list, style: {
|
|
4745
|
-
listStyle: 'none',
|
|
4746
|
-
margin: 0,
|
|
4747
|
-
padding: level > 0 ? `0 0 0 ${theme.spacing.medium}` : 0,
|
|
4748
|
-
} },
|
|
4749
|
-
displayItems.map((item, index) => (React.createElement("li", { key: item.value, role: "treeitem", ...(item.data && item.data.length > 0
|
|
4750
|
-
? { 'aria-expanded': !!item.isRefined }
|
|
4751
|
-
: {}), className: clsx(hierarchicalTheme.item, item.isRefined && hierarchicalTheme.itemSelected, item.data && item.data.length > 0 && hierarchicalTheme.itemParent), style: {
|
|
4752
|
-
padding: `${theme.spacing.small} 0`,
|
|
4753
|
-
} }, renderItem ? (renderItem(item, level)) : (React.createElement(React.Fragment, null,
|
|
4754
|
-
React.createElement("button", { type: "button", onClick: () => handleItemClick(item, level), className: hierarchicalTheme.link, style: {
|
|
4755
|
-
display: 'flex',
|
|
4756
|
-
alignItems: 'center',
|
|
4757
|
-
gap: theme.spacing.small,
|
|
4758
|
-
width: '100%',
|
|
4759
|
-
padding: 0,
|
|
4760
|
-
background: 'none',
|
|
4761
|
-
border: 'none',
|
|
4762
|
-
cursor: 'pointer',
|
|
4763
|
-
textAlign: 'left',
|
|
4764
|
-
fontFamily: 'inherit',
|
|
4765
|
-
fontSize: theme.typography.fontSize.small,
|
|
4766
|
-
color: item.isRefined ? theme.colors.primary : theme.colors.text,
|
|
4767
|
-
fontWeight: item.isRefined ? 600 : 400,
|
|
4768
|
-
} },
|
|
4769
|
-
React.createElement("span", { className: hierarchicalTheme.label, style: { flex: 1 } }, item.label),
|
|
4770
|
-
item.count !== undefined && (React.createElement("span", { className: hierarchicalTheme.count, style: {
|
|
4771
|
-
color: theme.colors.textSecondary,
|
|
4772
|
-
fontSize: theme.typography.fontSize.small,
|
|
4773
|
-
} }, item.count))),
|
|
4774
|
-
item.isRefined && item.data && item.data.length > 0 && (renderLevel(item.data, level + 1))))))),
|
|
4775
|
-
showMore && hasMore && (React.createElement("li", null,
|
|
4776
|
-
React.createElement("button", { type: "button", onClick: () => toggleShowMore(level), className: hierarchicalTheme.showMore, style: {
|
|
4777
|
-
padding: `${theme.spacing.small} 0`,
|
|
4778
|
-
background: 'none',
|
|
4779
|
-
border: 'none',
|
|
4780
|
-
cursor: 'pointer',
|
|
4781
|
-
fontSize: theme.typography.fontSize.small,
|
|
4782
|
-
color: theme.colors.primary,
|
|
4783
|
-
textDecoration: 'underline',
|
|
4784
|
-
} }, isExpanded ? 'Show less' : `Show ${items.length - displayLimit} more`)))));
|
|
4785
|
-
};
|
|
4786
|
-
if (processedItems.length === 0) {
|
|
4787
|
-
return null;
|
|
4788
|
-
}
|
|
4789
|
-
return (React.createElement("div", { ref: containerRef, className: clsx(hierarchicalTheme.root, className), style: style, tabIndex: 0, onKeyDown: handleKeyDown }, renderLevel(processedItems, 0)));
|
|
4790
|
-
};
|
|
4791
|
-
|
|
4792
|
-
/**
|
|
4793
|
-
* RangeSlider Component
|
|
4794
|
-
*
|
|
4795
|
-
* Visual slider for numeric range filtering
|
|
4796
|
-
* Alternative to RangeInput for a more interactive UX
|
|
4797
|
-
*/
|
|
4798
|
-
const RangeSlider = ({ field, label, min, max, step = 1, currentMin: currentMinProp, currentMax: currentMaxProp, onRangeChange, formatValue = (v) => v.toString(), className, style, theme: customTheme, showValues = true, syncWithState = true, debounceMs = 300, }) => {
|
|
4799
|
-
const { theme } = useSearchContext();
|
|
4800
|
-
const { refinements, addRefinement, removeRefinement } = useSearchState();
|
|
4801
|
-
const rangeSliderTheme = customTheme || {};
|
|
4802
|
-
// Parse current range from StateManager
|
|
4803
|
-
const stateRange = useMemo(() => {
|
|
4804
|
-
if (!syncWithState)
|
|
4805
|
-
return { min: undefined, max: undefined };
|
|
4806
|
-
let minVal;
|
|
4807
|
-
let maxVal;
|
|
4808
|
-
refinements.forEach(r => {
|
|
4809
|
-
if (r.field === field) {
|
|
4810
|
-
const minMatch = r.value.match(/^>=(\d+(?:\.\d+)?)$/);
|
|
4811
|
-
if (minMatch)
|
|
4812
|
-
minVal = parseFloat(minMatch[1]);
|
|
4813
|
-
const maxMatch = r.value.match(/^<=(\d+(?:\.\d+)?)$/);
|
|
4814
|
-
if (maxMatch)
|
|
4815
|
-
maxVal = parseFloat(maxMatch[1]);
|
|
4816
|
-
}
|
|
4817
|
-
});
|
|
4818
|
-
return { min: minVal, max: maxVal };
|
|
4819
|
-
}, [syncWithState, refinements, field]);
|
|
4820
|
-
const [internalMin, setInternalMin] = useState(currentMinProp ?? stateRange.min ?? min);
|
|
4821
|
-
const [internalMax, setInternalMax] = useState(currentMaxProp ?? stateRange.max ?? max);
|
|
4822
|
-
const [isDragging, setIsDragging] = useState(false);
|
|
4823
|
-
const debounceRef = useRef(null);
|
|
4824
|
-
// Sync with StateManager changes
|
|
4825
|
-
useEffect(() => {
|
|
4826
|
-
if (syncWithState && !isDragging) {
|
|
4827
|
-
if (stateRange.min !== undefined)
|
|
4828
|
-
setInternalMin(stateRange.min);
|
|
4829
|
-
else
|
|
4830
|
-
setInternalMin(min);
|
|
4831
|
-
if (stateRange.max !== undefined)
|
|
4832
|
-
setInternalMax(stateRange.max);
|
|
4833
|
-
else
|
|
4834
|
-
setInternalMax(max);
|
|
4835
|
-
}
|
|
4836
|
-
}, [syncWithState, stateRange.min, stateRange.max, isDragging, min, max]);
|
|
4837
|
-
// Update StateManager with range refinements
|
|
4838
|
-
const updateStateManager = useCallback((minVal, maxVal) => {
|
|
4839
|
-
if (!syncWithState)
|
|
4840
|
-
return;
|
|
4841
|
-
// Remove existing range refinements for this field
|
|
4842
|
-
refinements.forEach(r => {
|
|
4843
|
-
if (r.field === field) {
|
|
4844
|
-
removeRefinement(field, r.value, false);
|
|
4845
|
-
}
|
|
4846
|
-
});
|
|
4847
|
-
// Add new range refinements
|
|
4848
|
-
if (minVal > min) {
|
|
4849
|
-
addRefinement(field, `>=${minVal}`, false);
|
|
4850
|
-
}
|
|
4851
|
-
if (maxVal < max) {
|
|
4852
|
-
addRefinement(field, `<=${maxVal}`, minVal <= min); // Trigger search if only max is set
|
|
4853
|
-
}
|
|
4854
|
-
if (minVal > min && maxVal >= max) {
|
|
4855
|
-
// Trigger search after setting min
|
|
4856
|
-
addRefinement(field, `>=${minVal}`, true);
|
|
4857
|
-
}
|
|
4858
|
-
}, [syncWithState, field, refinements, addRefinement, removeRefinement, min, max]);
|
|
4859
|
-
// Debounced update
|
|
4860
|
-
const debouncedUpdate = useCallback((minVal, maxVal) => {
|
|
4861
|
-
if (debounceRef.current) {
|
|
4862
|
-
clearTimeout(debounceRef.current);
|
|
4863
|
-
}
|
|
4864
|
-
debounceRef.current = setTimeout(() => {
|
|
4865
|
-
updateStateManager(minVal, maxVal);
|
|
4866
|
-
if (onRangeChange) {
|
|
4867
|
-
onRangeChange(minVal, maxVal);
|
|
4868
|
-
}
|
|
4869
|
-
}, debounceMs);
|
|
4870
|
-
}, [updateStateManager, onRangeChange, debounceMs]);
|
|
4871
|
-
// Handle min slider change
|
|
4872
|
-
const handleMinChange = (e) => {
|
|
4873
|
-
const value = Math.min(Number(e.target.value), internalMax - step);
|
|
4874
|
-
setInternalMin(value);
|
|
4875
|
-
setIsDragging(true);
|
|
4876
|
-
debouncedUpdate(value, internalMax);
|
|
4877
|
-
};
|
|
4878
|
-
// Handle max slider change
|
|
4879
|
-
const handleMaxChange = (e) => {
|
|
4880
|
-
const value = Math.max(Number(e.target.value), internalMin + step);
|
|
4881
|
-
setInternalMax(value);
|
|
4882
|
-
setIsDragging(true);
|
|
4883
|
-
debouncedUpdate(internalMin, value);
|
|
4884
|
-
};
|
|
4885
|
-
// Handle drag end
|
|
4886
|
-
const handleDragEnd = () => {
|
|
4887
|
-
setIsDragging(false);
|
|
4888
|
-
};
|
|
4889
|
-
// Handle keyboard navigation for enhanced control (Shift+Arrow for 10x step, Home/End)
|
|
4890
|
-
const handleMinKeyDown = (e) => {
|
|
4891
|
-
let newValue = null;
|
|
4892
|
-
if (e.key === 'Home') {
|
|
4893
|
-
e.preventDefault();
|
|
4894
|
-
newValue = min;
|
|
4895
|
-
}
|
|
4896
|
-
else if (e.key === 'End') {
|
|
4897
|
-
e.preventDefault();
|
|
4898
|
-
newValue = internalMax - step;
|
|
4899
|
-
}
|
|
4900
|
-
else if (e.shiftKey && (e.key === 'ArrowLeft' || e.key === 'ArrowDown')) {
|
|
4901
|
-
e.preventDefault();
|
|
4902
|
-
newValue = Math.max(min, internalMin - step * 10);
|
|
4903
|
-
}
|
|
4904
|
-
else if (e.shiftKey && (e.key === 'ArrowRight' || e.key === 'ArrowUp')) {
|
|
4905
|
-
e.preventDefault();
|
|
4906
|
-
newValue = Math.min(internalMax - step, internalMin + step * 10);
|
|
4907
|
-
}
|
|
4908
|
-
if (newValue !== null) {
|
|
4909
|
-
setInternalMin(newValue);
|
|
4910
|
-
debouncedUpdate(newValue, internalMax);
|
|
4911
|
-
}
|
|
4912
|
-
};
|
|
4913
|
-
const handleMaxKeyDown = (e) => {
|
|
4914
|
-
let newValue = null;
|
|
4915
|
-
if (e.key === 'Home') {
|
|
4916
|
-
e.preventDefault();
|
|
4917
|
-
newValue = internalMin + step;
|
|
4918
|
-
}
|
|
4919
|
-
else if (e.key === 'End') {
|
|
4920
|
-
e.preventDefault();
|
|
4921
|
-
newValue = max;
|
|
4922
|
-
}
|
|
4923
|
-
else if (e.shiftKey && (e.key === 'ArrowLeft' || e.key === 'ArrowDown')) {
|
|
4924
|
-
e.preventDefault();
|
|
4925
|
-
newValue = Math.max(internalMin + step, internalMax - step * 10);
|
|
4926
|
-
}
|
|
4927
|
-
else if (e.shiftKey && (e.key === 'ArrowRight' || e.key === 'ArrowUp')) {
|
|
4928
|
-
e.preventDefault();
|
|
4929
|
-
newValue = Math.min(max, internalMax + step * 10);
|
|
4930
|
-
}
|
|
4931
|
-
if (newValue !== null) {
|
|
4932
|
-
setInternalMax(newValue);
|
|
4933
|
-
debouncedUpdate(internalMin, newValue);
|
|
5610
|
+
else
|
|
5611
|
+
parentItem.focus();
|
|
5612
|
+
}
|
|
5613
|
+
}
|
|
5614
|
+
}
|
|
5615
|
+
break;
|
|
5616
|
+
}
|
|
5617
|
+
case 'Enter': {
|
|
5618
|
+
if (!currentItem)
|
|
5619
|
+
break;
|
|
5620
|
+
e.preventDefault();
|
|
5621
|
+
const button = currentItem.querySelector('button');
|
|
5622
|
+
if (button)
|
|
5623
|
+
button.click();
|
|
5624
|
+
break;
|
|
5625
|
+
}
|
|
4934
5626
|
}
|
|
4935
|
-
};
|
|
4936
|
-
//
|
|
4937
|
-
const
|
|
4938
|
-
|
|
4939
|
-
|
|
4940
|
-
|
|
4941
|
-
|
|
4942
|
-
|
|
4943
|
-
|
|
4944
|
-
|
|
4945
|
-
|
|
4946
|
-
|
|
4947
|
-
|
|
4948
|
-
color: theme.colors.text,
|
|
4949
|
-
} }, label)),
|
|
4950
|
-
React.createElement("div", { className: rangeSliderTheme.slider, style: {
|
|
4951
|
-
position: 'relative',
|
|
4952
|
-
height: '40px',
|
|
4953
|
-
display: 'flex',
|
|
4954
|
-
alignItems: 'center',
|
|
4955
|
-
} },
|
|
4956
|
-
React.createElement("div", { className: rangeSliderTheme.track, style: {
|
|
4957
|
-
position: 'absolute',
|
|
4958
|
-
width: '100%',
|
|
4959
|
-
height: '4px',
|
|
4960
|
-
backgroundColor: theme.colors.border,
|
|
4961
|
-
borderRadius: '2px',
|
|
4962
|
-
} }),
|
|
4963
|
-
React.createElement("div", { className: rangeSliderTheme.trackFilled, style: {
|
|
4964
|
-
position: 'absolute',
|
|
4965
|
-
left: `${minPercent}%`,
|
|
4966
|
-
width: `${maxPercent - minPercent}%`,
|
|
4967
|
-
height: '4px',
|
|
4968
|
-
backgroundColor: theme.colors.primary,
|
|
4969
|
-
borderRadius: '2px',
|
|
4970
|
-
} }),
|
|
4971
|
-
React.createElement("input", { type: "range", min: min, max: max, step: step, value: internalMin, onChange: handleMinChange, onMouseUp: handleDragEnd, onTouchEnd: handleDragEnd, onKeyDown: handleMinKeyDown, tabIndex: 0, "aria-valuenow": internalMin, "aria-valuemin": min, "aria-valuemax": max, className: rangeSliderTheme.thumb, style: {
|
|
4972
|
-
position: 'absolute',
|
|
4973
|
-
width: '100%',
|
|
4974
|
-
height: '4px',
|
|
4975
|
-
background: 'transparent',
|
|
4976
|
-
WebkitAppearance: 'none',
|
|
4977
|
-
appearance: 'none',
|
|
4978
|
-
cursor: 'pointer',
|
|
4979
|
-
pointerEvents: 'none',
|
|
4980
|
-
}, "aria-label": `Minimum ${label || field}` }),
|
|
4981
|
-
React.createElement("input", { type: "range", min: min, max: max, step: step, value: internalMax, onChange: handleMaxChange, onMouseUp: handleDragEnd, onTouchEnd: handleDragEnd, onKeyDown: handleMaxKeyDown, tabIndex: 0, "aria-valuenow": internalMax, "aria-valuemin": min, "aria-valuemax": max, className: rangeSliderTheme.thumb, style: {
|
|
4982
|
-
position: 'absolute',
|
|
4983
|
-
width: '100%',
|
|
4984
|
-
height: '4px',
|
|
4985
|
-
background: 'transparent',
|
|
4986
|
-
WebkitAppearance: 'none',
|
|
4987
|
-
appearance: 'none',
|
|
4988
|
-
cursor: 'pointer',
|
|
4989
|
-
pointerEvents: 'none',
|
|
4990
|
-
}, "aria-label": `Maximum ${label || field}` })),
|
|
4991
|
-
showValues && (React.createElement("div", { className: rangeSliderTheme.values, style: {
|
|
4992
|
-
display: 'flex',
|
|
4993
|
-
justifyContent: 'space-between',
|
|
4994
|
-
marginTop: theme.spacing.small,
|
|
4995
|
-
fontSize: theme.typography.fontSize.small,
|
|
4996
|
-
color: theme.colors.textSecondary,
|
|
5627
|
+
}, [getVisibleTreeItems]);
|
|
5628
|
+
// Render a level of the hierarchy
|
|
5629
|
+
const renderLevel = (items, level) => {
|
|
5630
|
+
if (!items || items.length === 0)
|
|
5631
|
+
return null;
|
|
5632
|
+
const isExpanded = expanded[level] || false;
|
|
5633
|
+
const displayLimit = isExpanded ? showMoreLimit : limit;
|
|
5634
|
+
const displayItems = items.slice(0, displayLimit);
|
|
5635
|
+
const hasMore = items.length > displayLimit;
|
|
5636
|
+
return (React.createElement("ul", { role: level === 0 ? 'tree' : 'group', className: hierarchicalTheme.list, style: {
|
|
5637
|
+
listStyle: 'none',
|
|
5638
|
+
margin: 0,
|
|
5639
|
+
padding: level > 0 ? `0 0 0 ${theme.spacing.medium}` : 0,
|
|
4997
5640
|
} },
|
|
4998
|
-
React.createElement("
|
|
4999
|
-
|
|
5000
|
-
|
|
5001
|
-
|
|
5002
|
-
|
|
5003
|
-
|
|
5004
|
-
|
|
5005
|
-
|
|
5006
|
-
|
|
5007
|
-
|
|
5008
|
-
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
|
|
5012
|
-
|
|
5013
|
-
|
|
5014
|
-
|
|
5015
|
-
|
|
5016
|
-
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
|
|
5021
|
-
|
|
5022
|
-
|
|
5641
|
+
displayItems.map((item, index) => (React.createElement("li", { key: item.value, role: "treeitem", ...(item.data && item.data.length > 0
|
|
5642
|
+
? { 'aria-expanded': !!item.isRefined }
|
|
5643
|
+
: {}), className: clsx(hierarchicalTheme.item, item.isRefined && hierarchicalTheme.itemSelected, item.data && item.data.length > 0 && hierarchicalTheme.itemParent), style: {
|
|
5644
|
+
padding: `${theme.spacing.small} 0`,
|
|
5645
|
+
} }, renderItem ? (renderItem(item, level)) : (React.createElement(React.Fragment, null,
|
|
5646
|
+
React.createElement("button", { type: "button", onClick: () => handleItemClick(item, level), className: hierarchicalTheme.link, style: {
|
|
5647
|
+
display: 'flex',
|
|
5648
|
+
alignItems: 'center',
|
|
5649
|
+
gap: theme.spacing.small,
|
|
5650
|
+
width: '100%',
|
|
5651
|
+
padding: 0,
|
|
5652
|
+
background: 'none',
|
|
5653
|
+
border: 'none',
|
|
5654
|
+
cursor: 'pointer',
|
|
5655
|
+
textAlign: 'left',
|
|
5656
|
+
fontFamily: 'inherit',
|
|
5657
|
+
fontSize: theme.typography.fontSize.small,
|
|
5658
|
+
color: item.isRefined ? theme.colors.primary : theme.colors.text,
|
|
5659
|
+
fontWeight: item.isRefined ? 600 : 400,
|
|
5660
|
+
} },
|
|
5661
|
+
React.createElement("span", { className: hierarchicalTheme.label, style: { flex: 1 } }, item.label),
|
|
5662
|
+
item.count !== undefined && (React.createElement("span", { className: hierarchicalTheme.count, style: {
|
|
5663
|
+
color: theme.colors.textSecondary,
|
|
5664
|
+
fontSize: theme.typography.fontSize.small,
|
|
5665
|
+
} }, item.count))),
|
|
5666
|
+
item.isRefined && item.data && item.data.length > 0 && (renderLevel(item.data, level + 1))))))),
|
|
5667
|
+
showMore && hasMore && (React.createElement("li", null,
|
|
5668
|
+
React.createElement("button", { type: "button", onClick: () => toggleShowMore(level), className: hierarchicalTheme.showMore, style: {
|
|
5669
|
+
padding: `${theme.spacing.small} 0`,
|
|
5670
|
+
background: 'none',
|
|
5671
|
+
border: 'none',
|
|
5672
|
+
cursor: 'pointer',
|
|
5673
|
+
fontSize: theme.typography.fontSize.small,
|
|
5674
|
+
color: theme.colors.primary,
|
|
5675
|
+
textDecoration: 'underline',
|
|
5676
|
+
} }, isExpanded ? 'Show less' : `Show ${items.length - displayLimit} more`)))));
|
|
5677
|
+
};
|
|
5678
|
+
if (processedItems.length === 0) {
|
|
5679
|
+
return null;
|
|
5680
|
+
}
|
|
5681
|
+
return (React.createElement("div", { ref: containerRef, className: clsx(hierarchicalTheme.root, className), style: style, tabIndex: 0, onKeyDown: handleKeyDown }, renderLevel(processedItems, 0)));
|
|
5023
5682
|
};
|
|
5024
5683
|
|
|
5025
5684
|
/**
|
|
@@ -6165,13 +6824,21 @@ function useQuerySuggestionsEnhanced(options) {
|
|
|
6165
6824
|
* - Accessibility support
|
|
6166
6825
|
*/
|
|
6167
6826
|
// ============================================================================
|
|
6827
|
+
// Constants
|
|
6828
|
+
// ============================================================================
|
|
6829
|
+
const TRANSITIONS$6 = {
|
|
6830
|
+
fast: '150ms ease-in-out'};
|
|
6831
|
+
const BORDER_RADIUS$9 = {
|
|
6832
|
+
sm: 4,
|
|
6833
|
+
lg: 8};
|
|
6834
|
+
// ============================================================================
|
|
6168
6835
|
// Styles
|
|
6169
6836
|
// ============================================================================
|
|
6170
6837
|
const defaultStyles$1 = {
|
|
6171
6838
|
container: {
|
|
6172
|
-
backgroundColor: 'var(--seekora-bg-surface,
|
|
6173
|
-
border: '1px solid var(--seekora-border-color,
|
|
6174
|
-
borderRadius:
|
|
6839
|
+
backgroundColor: 'var(--seekora-bg-surface, transparent)',
|
|
6840
|
+
border: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
|
|
6841
|
+
borderRadius: `var(--seekora-border-radius, ${BORDER_RADIUS$9.lg}px)`,
|
|
6175
6842
|
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))',
|
|
6176
6843
|
maxHeight: '400px',
|
|
6177
6844
|
overflowY: 'auto',
|
|
@@ -6180,7 +6847,7 @@ const defaultStyles$1 = {
|
|
|
6180
6847
|
sectionTitle: {
|
|
6181
6848
|
fontSize: '12px',
|
|
6182
6849
|
fontWeight: 600,
|
|
6183
|
-
color: 'var(--seekora-text-secondary,
|
|
6850
|
+
color: 'var(--seekora-text-secondary, inherit)',
|
|
6184
6851
|
textTransform: 'uppercase',
|
|
6185
6852
|
letterSpacing: '0.05em',
|
|
6186
6853
|
padding: '8px 16px 4px',
|
|
@@ -6191,9 +6858,9 @@ const defaultStyles$1 = {
|
|
|
6191
6858
|
alignItems: 'center',
|
|
6192
6859
|
padding: '10px 16px',
|
|
6193
6860
|
cursor: 'pointer',
|
|
6194
|
-
transition:
|
|
6861
|
+
transition: `background-color ${TRANSITIONS$6.fast}`,
|
|
6195
6862
|
fontSize: '14px',
|
|
6196
|
-
color: 'var(--seekora-text-primary,
|
|
6863
|
+
color: 'var(--seekora-text-primary, inherit)',
|
|
6197
6864
|
gap: '12px',
|
|
6198
6865
|
},
|
|
6199
6866
|
suggestionItemActive: {
|
|
@@ -6213,10 +6880,10 @@ const defaultStyles$1 = {
|
|
|
6213
6880
|
},
|
|
6214
6881
|
highlight: {
|
|
6215
6882
|
fontWeight: 600,
|
|
6216
|
-
color: 'var(--seekora-text-primary,
|
|
6883
|
+
color: 'var(--seekora-text-primary, inherit)',
|
|
6217
6884
|
backgroundColor: 'var(--seekora-highlight-bg, #fef3c7)',
|
|
6218
6885
|
padding: '0 2px',
|
|
6219
|
-
borderRadius:
|
|
6886
|
+
borderRadius: `${BORDER_RADIUS$9.sm / 2}px`,
|
|
6220
6887
|
},
|
|
6221
6888
|
recentIcon: {
|
|
6222
6889
|
width: '16px',
|
|
@@ -6226,13 +6893,13 @@ const defaultStyles$1 = {
|
|
|
6226
6893
|
},
|
|
6227
6894
|
removeButton: {
|
|
6228
6895
|
padding: '4px',
|
|
6229
|
-
borderRadius:
|
|
6896
|
+
borderRadius: `${BORDER_RADIUS$9.sm}px`,
|
|
6230
6897
|
border: 'none',
|
|
6231
6898
|
background: 'transparent',
|
|
6232
6899
|
cursor: 'pointer',
|
|
6233
6900
|
color: 'var(--seekora-text-secondary, #9ca3af)',
|
|
6234
6901
|
opacity: 0,
|
|
6235
|
-
transition:
|
|
6902
|
+
transition: `opacity ${TRANSITIONS$6.fast}, color ${TRANSITIONS$6.fast}`,
|
|
6236
6903
|
},
|
|
6237
6904
|
removeButtonVisible: {
|
|
6238
6905
|
opacity: 1,
|
|
@@ -6242,7 +6909,7 @@ const defaultStyles$1 = {
|
|
|
6242
6909
|
alignItems: 'center',
|
|
6243
6910
|
justifyContent: 'center',
|
|
6244
6911
|
padding: '24px 16px',
|
|
6245
|
-
color: 'var(--seekora-text-secondary,
|
|
6912
|
+
color: 'var(--seekora-text-secondary, inherit)',
|
|
6246
6913
|
fontSize: '14px',
|
|
6247
6914
|
gap: '8px',
|
|
6248
6915
|
},
|
|
@@ -6252,20 +6919,20 @@ const defaultStyles$1 = {
|
|
|
6252
6919
|
alignItems: 'center',
|
|
6253
6920
|
justifyContent: 'center',
|
|
6254
6921
|
padding: '24px 16px',
|
|
6255
|
-
color: 'var(--seekora-text-secondary,
|
|
6922
|
+
color: 'var(--seekora-text-secondary, inherit)',
|
|
6256
6923
|
fontSize: '14px',
|
|
6257
6924
|
textAlign: 'center',
|
|
6258
6925
|
},
|
|
6259
6926
|
divider: {
|
|
6260
6927
|
height: '1px',
|
|
6261
|
-
backgroundColor: 'var(--seekora-border-color,
|
|
6928
|
+
backgroundColor: 'var(--seekora-border-color, rgba(128,128,128,0.2))',
|
|
6262
6929
|
margin: '4px 0',
|
|
6263
6930
|
},
|
|
6264
6931
|
footer: {
|
|
6265
|
-
borderTop: '1px solid var(--seekora-border-color,
|
|
6932
|
+
borderTop: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
|
|
6266
6933
|
padding: '8px 16px',
|
|
6267
6934
|
fontSize: '12px',
|
|
6268
|
-
color: 'var(--seekora-text-secondary,
|
|
6935
|
+
color: 'var(--seekora-text-secondary, inherit)',
|
|
6269
6936
|
display: 'flex',
|
|
6270
6937
|
alignItems: 'center',
|
|
6271
6938
|
justifyContent: 'space-between',
|
|
@@ -6283,9 +6950,9 @@ const defaultStyles$1 = {
|
|
|
6283
6950
|
minWidth: '20px',
|
|
6284
6951
|
height: '18px',
|
|
6285
6952
|
padding: '0 4px',
|
|
6286
|
-
borderRadius:
|
|
6287
|
-
backgroundColor: 'var(--seekora-bg-secondary,
|
|
6288
|
-
border: '1px solid var(--seekora-border-color,
|
|
6953
|
+
borderRadius: `${BORDER_RADIUS$9.sm - 1}px`,
|
|
6954
|
+
backgroundColor: 'var(--seekora-bg-secondary, rgba(255, 255, 255, 0.1))',
|
|
6955
|
+
border: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
|
|
6289
6956
|
fontSize: '10px',
|
|
6290
6957
|
fontWeight: 500,
|
|
6291
6958
|
},
|
|
@@ -6553,6 +7220,16 @@ const QuerySuggestionsDropdown = forwardRef(function QuerySuggestionsDropdown(pr
|
|
|
6553
7220
|
* - Configurable sections
|
|
6554
7221
|
* - Rich styling options
|
|
6555
7222
|
*/
|
|
7223
|
+
// ============================================================================
|
|
7224
|
+
// Constants
|
|
7225
|
+
// ============================================================================
|
|
7226
|
+
const TRANSITIONS$5 = {
|
|
7227
|
+
fast: '150ms ease-in-out'};
|
|
7228
|
+
const BORDER_RADIUS$8 = {
|
|
7229
|
+
sm: 4,
|
|
7230
|
+
lg: 8,
|
|
7231
|
+
full: 9999,
|
|
7232
|
+
};
|
|
6556
7233
|
// Default section order
|
|
6557
7234
|
const DEFAULT_SECTIONS = [
|
|
6558
7235
|
{ id: 'recent', title: 'Recent Searches', maxItems: 5, enabled: true, order: 1 },
|
|
@@ -6565,16 +7242,16 @@ const DEFAULT_SECTIONS = [
|
|
|
6565
7242
|
// ============================================================================
|
|
6566
7243
|
const styles$2 = {
|
|
6567
7244
|
container: {
|
|
6568
|
-
backgroundColor: 'var(--seekora-bg-surface,
|
|
6569
|
-
border: '1px solid var(--seekora-border-color,
|
|
6570
|
-
borderRadius:
|
|
7245
|
+
backgroundColor: 'var(--seekora-bg-surface, transparent)',
|
|
7246
|
+
border: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
|
|
7247
|
+
borderRadius: `var(--seekora-border-radius-lg, ${BORDER_RADIUS$8.lg * 1.5}px)`,
|
|
6571
7248
|
boxShadow: 'var(--seekora-shadow-xl, 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04))',
|
|
6572
7249
|
overflow: 'hidden',
|
|
6573
7250
|
},
|
|
6574
7251
|
header: {
|
|
6575
7252
|
padding: '12px 16px',
|
|
6576
|
-
borderBottom: '1px solid var(--seekora-border-color,
|
|
6577
|
-
backgroundColor: 'var(--seekora-bg-secondary,
|
|
7253
|
+
borderBottom: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
|
|
7254
|
+
backgroundColor: 'var(--seekora-bg-secondary, rgba(255, 255, 255, 0.1))',
|
|
6578
7255
|
},
|
|
6579
7256
|
content: {
|
|
6580
7257
|
overflowY: 'auto',
|
|
@@ -6606,7 +7283,7 @@ const styles$2 = {
|
|
|
6606
7283
|
alignItems: 'flex-start',
|
|
6607
7284
|
padding: '10px 16px',
|
|
6608
7285
|
cursor: 'pointer',
|
|
6609
|
-
transition:
|
|
7286
|
+
transition: `background-color ${TRANSITIONS$5.fast}`,
|
|
6610
7287
|
gap: '12px',
|
|
6611
7288
|
},
|
|
6612
7289
|
itemActive: {
|
|
@@ -6625,7 +7302,7 @@ const styles$2 = {
|
|
|
6625
7302
|
},
|
|
6626
7303
|
itemQuery: {
|
|
6627
7304
|
fontSize: '14px',
|
|
6628
|
-
color: 'var(--seekora-text-primary,
|
|
7305
|
+
color: 'var(--seekora-text-primary, inherit)',
|
|
6629
7306
|
fontWeight: 500,
|
|
6630
7307
|
margin: 0,
|
|
6631
7308
|
overflow: 'hidden',
|
|
@@ -6650,11 +7327,11 @@ const styles$2 = {
|
|
|
6650
7327
|
padding: '3px 8px',
|
|
6651
7328
|
fontSize: '11px',
|
|
6652
7329
|
fontWeight: 500,
|
|
6653
|
-
color: 'var(--seekora-text-secondary,
|
|
6654
|
-
backgroundColor: 'var(--seekora-bg-tertiary,
|
|
6655
|
-
borderRadius:
|
|
7330
|
+
color: 'var(--seekora-text-secondary, inherit)',
|
|
7331
|
+
backgroundColor: 'var(--seekora-bg-tertiary, rgba(255, 255, 255, 0.1))',
|
|
7332
|
+
borderRadius: `${BORDER_RADIUS$8.lg * 1.5}px`,
|
|
6656
7333
|
cursor: 'pointer',
|
|
6657
|
-
transition:
|
|
7334
|
+
transition: `all ${TRANSITIONS$5.fast}`,
|
|
6658
7335
|
},
|
|
6659
7336
|
categoryPillHover: {
|
|
6660
7337
|
backgroundColor: 'var(--seekora-primary-light, #dbeafe)',
|
|
@@ -6676,12 +7353,12 @@ const styles$2 = {
|
|
|
6676
7353
|
padding: '6px 12px',
|
|
6677
7354
|
fontSize: '13px',
|
|
6678
7355
|
fontWeight: 500,
|
|
6679
|
-
color: 'var(--seekora-text-primary,
|
|
6680
|
-
backgroundColor: 'var(--seekora-bg-secondary,
|
|
6681
|
-
border: '1px solid var(--seekora-border-color,
|
|
6682
|
-
borderRadius:
|
|
7356
|
+
color: 'var(--seekora-text-primary, inherit)',
|
|
7357
|
+
backgroundColor: 'var(--seekora-bg-secondary, rgba(255, 255, 255, 0.1))',
|
|
7358
|
+
border: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
|
|
7359
|
+
borderRadius: `${BORDER_RADIUS$8.full}px`,
|
|
6683
7360
|
cursor: 'pointer',
|
|
6684
|
-
transition:
|
|
7361
|
+
transition: `all ${TRANSITIONS$5.fast}`,
|
|
6685
7362
|
},
|
|
6686
7363
|
trendingChipHover: {
|
|
6687
7364
|
borderColor: 'var(--seekora-primary, #3b82f6)',
|
|
@@ -6695,7 +7372,7 @@ const styles$2 = {
|
|
|
6695
7372
|
trendingRank: {
|
|
6696
7373
|
width: '18px',
|
|
6697
7374
|
height: '18px',
|
|
6698
|
-
borderRadius:
|
|
7375
|
+
borderRadius: `${BORDER_RADIUS$8.full}px`,
|
|
6699
7376
|
backgroundColor: 'var(--seekora-primary, #3b82f6)',
|
|
6700
7377
|
color: 'white',
|
|
6701
7378
|
fontSize: '10px',
|
|
@@ -6707,25 +7384,25 @@ const styles$2 = {
|
|
|
6707
7384
|
removeButton: {
|
|
6708
7385
|
padding: '4px',
|
|
6709
7386
|
marginLeft: 'auto',
|
|
6710
|
-
borderRadius:
|
|
7387
|
+
borderRadius: `${BORDER_RADIUS$8.sm}px`,
|
|
6711
7388
|
border: 'none',
|
|
6712
7389
|
background: 'transparent',
|
|
6713
7390
|
cursor: 'pointer',
|
|
6714
7391
|
color: 'var(--seekora-text-tertiary, #9ca3af)',
|
|
6715
7392
|
opacity: 0,
|
|
6716
|
-
transition:
|
|
7393
|
+
transition: `opacity ${TRANSITIONS$5.fast}`,
|
|
6717
7394
|
},
|
|
6718
7395
|
divider: {
|
|
6719
7396
|
height: '1px',
|
|
6720
|
-
backgroundColor: 'var(--seekora-border-color,
|
|
7397
|
+
backgroundColor: 'var(--seekora-border-color, rgba(128,128,128,0.2))',
|
|
6721
7398
|
margin: '4px 16px',
|
|
6722
7399
|
},
|
|
6723
7400
|
footer: {
|
|
6724
7401
|
padding: '12px 16px',
|
|
6725
|
-
borderTop: '1px solid var(--seekora-border-color,
|
|
6726
|
-
backgroundColor: 'var(--seekora-bg-secondary,
|
|
7402
|
+
borderTop: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
|
|
7403
|
+
backgroundColor: 'var(--seekora-bg-secondary, rgba(255, 255, 255, 0.1))',
|
|
6727
7404
|
fontSize: '12px',
|
|
6728
|
-
color: 'var(--seekora-text-secondary,
|
|
7405
|
+
color: 'var(--seekora-text-secondary, inherit)',
|
|
6729
7406
|
},
|
|
6730
7407
|
loadingOverlay: {
|
|
6731
7408
|
position: 'absolute',
|
|
@@ -6733,12 +7410,12 @@ const styles$2 = {
|
|
|
6733
7410
|
display: 'flex',
|
|
6734
7411
|
alignItems: 'center',
|
|
6735
7412
|
justifyContent: 'center',
|
|
6736
|
-
backgroundColor: 'rgba(255, 255, 255, 0.
|
|
7413
|
+
backgroundColor: 'rgba(255, 255, 255, 0.1)',
|
|
6737
7414
|
},
|
|
6738
7415
|
emptyState: {
|
|
6739
7416
|
padding: '32px 16px',
|
|
6740
7417
|
textAlign: 'center',
|
|
6741
|
-
color: 'var(--seekora-text-secondary,
|
|
7418
|
+
color: 'var(--seekora-text-secondary, inherit)',
|
|
6742
7419
|
},
|
|
6743
7420
|
highlight: {
|
|
6744
7421
|
backgroundColor: 'var(--seekora-highlight-bg, #fef9c3)',
|
|
@@ -7033,20 +7710,30 @@ const RichQuerySuggestions = forwardRef(function RichQuerySuggestions(props, ref
|
|
|
7033
7710
|
* - Rich product cards
|
|
7034
7711
|
*/
|
|
7035
7712
|
// ============================================================================
|
|
7713
|
+
// Constants
|
|
7714
|
+
// ============================================================================
|
|
7715
|
+
const TRANSITIONS$4 = {
|
|
7716
|
+
fast: '150ms ease-in-out'};
|
|
7717
|
+
const BORDER_RADIUS$7 = {
|
|
7718
|
+
sm: 4,
|
|
7719
|
+
lg: 8,
|
|
7720
|
+
full: 9999,
|
|
7721
|
+
};
|
|
7722
|
+
// ============================================================================
|
|
7036
7723
|
// Styles
|
|
7037
7724
|
// ============================================================================
|
|
7038
7725
|
const styles$1 = {
|
|
7039
7726
|
container: {
|
|
7040
|
-
backgroundColor: 'var(--seekora-bg-surface,
|
|
7041
|
-
border: '1px solid var(--seekora-border-color,
|
|
7042
|
-
borderRadius:
|
|
7727
|
+
backgroundColor: 'var(--seekora-bg-surface, transparent)',
|
|
7728
|
+
border: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
|
|
7729
|
+
borderRadius: `var(--seekora-border-radius-lg, ${BORDER_RADIUS$7.lg * 1.5}px)`,
|
|
7043
7730
|
boxShadow: '0 25px 50px -12px rgba(0, 0, 0, 0.25)',
|
|
7044
7731
|
overflow: 'hidden',
|
|
7045
7732
|
},
|
|
7046
7733
|
header: {
|
|
7047
7734
|
padding: '12px 20px',
|
|
7048
|
-
borderBottom: '1px solid var(--seekora-border-color,
|
|
7049
|
-
backgroundColor: 'var(--seekora-bg-secondary,
|
|
7735
|
+
borderBottom: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
|
|
7736
|
+
backgroundColor: 'var(--seekora-bg-secondary, rgba(255, 255, 255, 0.1))',
|
|
7050
7737
|
},
|
|
7051
7738
|
content: {
|
|
7052
7739
|
display: 'flex',
|
|
@@ -7056,13 +7743,13 @@ const styles$1 = {
|
|
|
7056
7743
|
flexDirection: 'column',
|
|
7057
7744
|
},
|
|
7058
7745
|
suggestionsColumn: {
|
|
7059
|
-
borderRight: '1px solid var(--seekora-border-color,
|
|
7746
|
+
borderRight: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
|
|
7060
7747
|
overflowY: 'auto',
|
|
7061
7748
|
},
|
|
7062
7749
|
productsColumn: {
|
|
7063
7750
|
flex: 1,
|
|
7064
7751
|
overflowY: 'auto',
|
|
7065
|
-
backgroundColor: 'var(--seekora-bg-secondary,
|
|
7752
|
+
backgroundColor: 'var(--seekora-bg-secondary, rgba(255, 255, 255, 0.1))',
|
|
7066
7753
|
},
|
|
7067
7754
|
section: {
|
|
7068
7755
|
padding: '12px 0',
|
|
@@ -7093,7 +7780,7 @@ const styles$1 = {
|
|
|
7093
7780
|
alignItems: 'center',
|
|
7094
7781
|
padding: '10px 20px',
|
|
7095
7782
|
cursor: 'pointer',
|
|
7096
|
-
transition:
|
|
7783
|
+
transition: `background-color ${TRANSITIONS$4.fast}`,
|
|
7097
7784
|
gap: '12px',
|
|
7098
7785
|
},
|
|
7099
7786
|
suggestionItemActive: {
|
|
@@ -7108,7 +7795,7 @@ const styles$1 = {
|
|
|
7108
7795
|
suggestionText: {
|
|
7109
7796
|
flex: 1,
|
|
7110
7797
|
fontSize: '14px',
|
|
7111
|
-
color: 'var(--seekora-text-primary,
|
|
7798
|
+
color: 'var(--seekora-text-primary, inherit)',
|
|
7112
7799
|
fontWeight: 500,
|
|
7113
7800
|
overflow: 'hidden',
|
|
7114
7801
|
textOverflow: 'ellipsis',
|
|
@@ -7132,7 +7819,7 @@ const styles$1 = {
|
|
|
7132
7819
|
display: 'flex',
|
|
7133
7820
|
gap: '4px',
|
|
7134
7821
|
padding: '12px 20px',
|
|
7135
|
-
borderBottom: '1px solid var(--seekora-border-color,
|
|
7822
|
+
borderBottom: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
|
|
7136
7823
|
overflowX: 'auto',
|
|
7137
7824
|
},
|
|
7138
7825
|
tab: {
|
|
@@ -7142,13 +7829,13 @@ const styles$1 = {
|
|
|
7142
7829
|
padding: '8px 16px',
|
|
7143
7830
|
fontSize: '13px',
|
|
7144
7831
|
fontWeight: 500,
|
|
7145
|
-
color: 'var(--seekora-text-secondary,
|
|
7832
|
+
color: 'var(--seekora-text-secondary, inherit)',
|
|
7146
7833
|
backgroundColor: 'transparent',
|
|
7147
7834
|
border: '1px solid transparent',
|
|
7148
|
-
borderRadius:
|
|
7835
|
+
borderRadius: `${BORDER_RADIUS$7.full}px`,
|
|
7149
7836
|
cursor: 'pointer',
|
|
7150
7837
|
whiteSpace: 'nowrap',
|
|
7151
|
-
transition:
|
|
7838
|
+
transition: `all ${TRANSITIONS$4.fast}`,
|
|
7152
7839
|
},
|
|
7153
7840
|
tabActive: {
|
|
7154
7841
|
color: 'var(--seekora-primary, #3b82f6)',
|
|
@@ -7159,8 +7846,8 @@ const styles$1 = {
|
|
|
7159
7846
|
fontSize: '11px',
|
|
7160
7847
|
fontWeight: 600,
|
|
7161
7848
|
padding: '2px 6px',
|
|
7162
|
-
borderRadius:
|
|
7163
|
-
backgroundColor: 'var(--seekora-bg-tertiary,
|
|
7849
|
+
borderRadius: `${BORDER_RADIUS$7.lg}px`,
|
|
7850
|
+
backgroundColor: 'var(--seekora-bg-tertiary, rgba(255, 255, 255, 0.1))',
|
|
7164
7851
|
},
|
|
7165
7852
|
tabCountActive: {
|
|
7166
7853
|
backgroundColor: 'var(--seekora-primary, #3b82f6)',
|
|
@@ -7175,12 +7862,12 @@ const styles$1 = {
|
|
|
7175
7862
|
productCard: {
|
|
7176
7863
|
display: 'flex',
|
|
7177
7864
|
flexDirection: 'column',
|
|
7178
|
-
backgroundColor: 'var(--seekora-bg-surface,
|
|
7179
|
-
borderRadius:
|
|
7865
|
+
backgroundColor: 'var(--seekora-bg-surface, transparent)',
|
|
7866
|
+
borderRadius: `${BORDER_RADIUS$7.lg}px`,
|
|
7180
7867
|
overflow: 'hidden',
|
|
7181
7868
|
cursor: 'pointer',
|
|
7182
|
-
transition:
|
|
7183
|
-
border: '1px solid var(--seekora-border-color,
|
|
7869
|
+
transition: `transform ${TRANSITIONS$4.fast}, box-shadow ${TRANSITIONS$4.fast}`,
|
|
7870
|
+
border: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
|
|
7184
7871
|
},
|
|
7185
7872
|
productCardHover: {
|
|
7186
7873
|
transform: 'translateY(-2px)',
|
|
@@ -7198,7 +7885,7 @@ const styles$1 = {
|
|
|
7198
7885
|
productTitle: {
|
|
7199
7886
|
fontSize: '13px',
|
|
7200
7887
|
fontWeight: 500,
|
|
7201
|
-
color: 'var(--seekora-text-primary,
|
|
7888
|
+
color: 'var(--seekora-text-primary, inherit)',
|
|
7202
7889
|
margin: 0,
|
|
7203
7890
|
overflow: 'hidden',
|
|
7204
7891
|
textOverflow: 'ellipsis',
|
|
@@ -7226,12 +7913,12 @@ const styles$1 = {
|
|
|
7226
7913
|
padding: '8px 14px',
|
|
7227
7914
|
fontSize: '13px',
|
|
7228
7915
|
fontWeight: 500,
|
|
7229
|
-
color: 'var(--seekora-text-primary,
|
|
7230
|
-
backgroundColor: 'var(--seekora-bg-surface,
|
|
7231
|
-
border: '1px solid var(--seekora-border-color,
|
|
7232
|
-
borderRadius:
|
|
7916
|
+
color: 'var(--seekora-text-primary, inherit)',
|
|
7917
|
+
backgroundColor: 'var(--seekora-bg-surface, transparent)',
|
|
7918
|
+
border: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
|
|
7919
|
+
borderRadius: `${BORDER_RADIUS$7.lg}px`,
|
|
7233
7920
|
cursor: 'pointer',
|
|
7234
|
-
transition:
|
|
7921
|
+
transition: `all ${TRANSITIONS$4.fast}`,
|
|
7235
7922
|
},
|
|
7236
7923
|
brandChipHover: {
|
|
7237
7924
|
borderColor: 'var(--seekora-primary, #3b82f6)',
|
|
@@ -7240,25 +7927,25 @@ const styles$1 = {
|
|
|
7240
7927
|
brandLogo: {
|
|
7241
7928
|
width: '20px',
|
|
7242
7929
|
height: '20px',
|
|
7243
|
-
borderRadius:
|
|
7930
|
+
borderRadius: `${BORDER_RADIUS$7.sm}px`,
|
|
7244
7931
|
objectFit: 'contain',
|
|
7245
7932
|
backgroundColor: 'var(--seekora-bg-secondary, #f3f4f6)',
|
|
7246
7933
|
},
|
|
7247
7934
|
footer: {
|
|
7248
7935
|
padding: '12px 20px',
|
|
7249
|
-
borderTop: '1px solid var(--seekora-border-color,
|
|
7250
|
-
backgroundColor: 'var(--seekora-bg-secondary,
|
|
7936
|
+
borderTop: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
|
|
7937
|
+
backgroundColor: 'var(--seekora-bg-secondary, rgba(255, 255, 255, 0.1))',
|
|
7251
7938
|
display: 'flex',
|
|
7252
7939
|
alignItems: 'center',
|
|
7253
7940
|
justifyContent: 'space-between',
|
|
7254
7941
|
fontSize: '12px',
|
|
7255
|
-
color: 'var(--seekora-text-secondary,
|
|
7942
|
+
color: 'var(--seekora-text-secondary, inherit)',
|
|
7256
7943
|
},
|
|
7257
7944
|
highlight: {
|
|
7258
7945
|
backgroundColor: 'var(--seekora-highlight-bg, #fef9c3)',
|
|
7259
7946
|
fontWeight: 600,
|
|
7260
7947
|
padding: '0 2px',
|
|
7261
|
-
borderRadius:
|
|
7948
|
+
borderRadius: `${BORDER_RADIUS$7.sm / 2}px`,
|
|
7262
7949
|
},
|
|
7263
7950
|
};
|
|
7264
7951
|
// ============================================================================
|
|
@@ -7782,8 +8469,8 @@ const styles = {
|
|
|
7782
8469
|
transition: 'border-color 150ms ease, box-shadow 150ms ease',
|
|
7783
8470
|
},
|
|
7784
8471
|
inputWrapperFocused: {
|
|
7785
|
-
borderColor: 'var(--seekora-primary, #3b82f6)',
|
|
7786
|
-
boxShadow: '0 0 0 3px var(--seekora-primary-light, rgba(59, 130, 246, 0.1))',
|
|
8472
|
+
borderColor: 'var(--seekora-border-focus, var(--seekora-primary, #3b82f6))',
|
|
8473
|
+
boxShadow: '0 0 0 3px var(--seekora-border-focus-alpha, var(--seekora-primary-light, rgba(59, 130, 246, 0.1)))',
|
|
7787
8474
|
},
|
|
7788
8475
|
input: {
|
|
7789
8476
|
flex: 1,
|
|
@@ -7826,7 +8513,7 @@ const styles = {
|
|
|
7826
8513
|
margin: '4px',
|
|
7827
8514
|
border: 'none',
|
|
7828
8515
|
backgroundColor: 'var(--seekora-primary, #3b82f6)',
|
|
7829
|
-
color: 'white',
|
|
8516
|
+
color: 'var(--seekora-primary-text, white)',
|
|
7830
8517
|
borderRadius: 'var(--seekora-border-radius, 6px)',
|
|
7831
8518
|
fontSize: '14px',
|
|
7832
8519
|
fontWeight: 600,
|
|
@@ -8267,6 +8954,13 @@ function SuggestionsProvider({ children, minQueryLength = 1, debounceMs = 200, m
|
|
|
8267
8954
|
* Single input bound to suggestions context: query, setQuery, focus opens dropdown,
|
|
8268
8955
|
* keydown ArrowUp/Down/Enter/Escape delegates to context. Overridable via className/style.
|
|
8269
8956
|
*/
|
|
8957
|
+
const SPACING$3 = {
|
|
8958
|
+
sm: 8,
|
|
8959
|
+
md: 12};
|
|
8960
|
+
const TRANSITIONS$3 = {
|
|
8961
|
+
fast: '150ms ease-in-out'};
|
|
8962
|
+
const BORDER_RADIUS$6 = {
|
|
8963
|
+
md: 6};
|
|
8270
8964
|
const defaultStyles = {
|
|
8271
8965
|
position: 'relative',
|
|
8272
8966
|
width: '100%',
|
|
@@ -8274,22 +8968,23 @@ const defaultStyles = {
|
|
|
8274
8968
|
const inputWrapperStyles = {
|
|
8275
8969
|
display: 'flex',
|
|
8276
8970
|
alignItems: 'center',
|
|
8277
|
-
gap:
|
|
8278
|
-
padding:
|
|
8279
|
-
border: '1px solid var(--seekora-border-color,
|
|
8280
|
-
borderRadius:
|
|
8281
|
-
backgroundColor: 'var(--seekora-bg-surface,
|
|
8282
|
-
transition:
|
|
8971
|
+
gap: `${SPACING$3.sm}px`,
|
|
8972
|
+
padding: `${SPACING$3.sm}px ${SPACING$3.md}px`,
|
|
8973
|
+
border: '1px solid var(--seekora-border-color, rgba(0,0,0,0.1))',
|
|
8974
|
+
borderRadius: `var(--seekora-border-radius, ${BORDER_RADIUS$6.md}px)`,
|
|
8975
|
+
backgroundColor: 'var(--seekora-bg-surface, transparent)',
|
|
8976
|
+
transition: `border-color ${TRANSITIONS$3.fast}, box-shadow ${TRANSITIONS$3.fast}`,
|
|
8977
|
+
boxSizing: 'border-box',
|
|
8283
8978
|
};
|
|
8284
8979
|
const inputStyles = {
|
|
8285
8980
|
flex: 1,
|
|
8286
8981
|
minWidth: 0,
|
|
8287
|
-
padding:
|
|
8982
|
+
padding: `${SPACING$3.sm}px 0`,
|
|
8288
8983
|
border: 'none',
|
|
8289
8984
|
outline: 'none',
|
|
8290
8985
|
backgroundColor: 'transparent',
|
|
8291
8986
|
fontSize: 'inherit',
|
|
8292
|
-
color: 'var(--seekora-text-primary,
|
|
8987
|
+
color: 'var(--seekora-text-primary, inherit)',
|
|
8293
8988
|
fontFamily: 'inherit',
|
|
8294
8989
|
};
|
|
8295
8990
|
function SearchInput({ placeholder = 'Search...', autoFocus = false, showClearButton = true, closeOnBlur = true, leftIcon, className, style, inputClassName, inputStyle, ariaLabel = 'Search', }) {
|
|
@@ -8338,7 +9033,7 @@ function SearchInput({ placeholder = 'Search...', autoFocus = false, showClearBu
|
|
|
8338
9033
|
leftIcon ? (React.createElement("span", { className: "seekora-suggestions-input-left-icon", style: { display: 'flex', flexShrink: 0, color: 'var(--seekora-text-secondary, #6b7280)' } }, leftIcon)) : null,
|
|
8339
9034
|
React.createElement("input", { ref: inputRef, type: "text", value: query, onChange: handleChange, onFocus: handleFocus, onBlur: handleBlur, onKeyDown: handleKeyDown, placeholder: placeholder, autoFocus: autoFocus, autoComplete: "off", autoCorrect: "off", autoCapitalize: "off", spellCheck: false, "aria-label": ariaLabel, "aria-expanded": isOpen, "aria-haspopup": "listbox", "aria-autocomplete": "list", role: "combobox", className: clsx('seekora-suggestions-input', inputClassName), style: { ...inputStyles, ...inputStyle } }),
|
|
8340
9035
|
showClearButton && query ? (React.createElement("button", { type: "button", onClick: handleClear, className: "seekora-suggestions-input-clear", "aria-label": "Clear search", style: {
|
|
8341
|
-
padding:
|
|
9036
|
+
padding: 8,
|
|
8342
9037
|
border: 'none',
|
|
8343
9038
|
background: 'transparent',
|
|
8344
9039
|
cursor: 'pointer',
|
|
@@ -8360,7 +9055,12 @@ function ClearIcon() {
|
|
|
8360
9055
|
* Shows when isOpen; handles click-outside and Escape to close. Children = any composition
|
|
8361
9056
|
* of SuggestionList, ProductGrid, etc. Position and z-index configurable.
|
|
8362
9057
|
*/
|
|
8363
|
-
|
|
9058
|
+
const BORDER_RADIUS$5 = {
|
|
9059
|
+
md: 6};
|
|
9060
|
+
// Z-index scale for consistent layering
|
|
9061
|
+
const Z_INDEX = {
|
|
9062
|
+
dropdown: 100};
|
|
9063
|
+
function DropdownPanel({ children, position = 'absolute', top = '100%', left = 0, right, width = '100%', maxHeight = '80vh', zIndex = Z_INDEX.dropdown, className, style, closeOnClickOutside = true, closeOnEscape = true, }) {
|
|
8364
9064
|
const { isOpen, close } = useSuggestionsContext();
|
|
8365
9065
|
const panelRef = useRef(null);
|
|
8366
9066
|
useEffect(() => {
|
|
@@ -8399,7 +9099,7 @@ function DropdownPanel({ children, position = 'absolute', top = '100%', left = 0
|
|
|
8399
9099
|
overflow: 'auto',
|
|
8400
9100
|
backgroundColor: 'var(--seekora-bg-surface, #fff)',
|
|
8401
9101
|
border: '1px solid var(--seekora-border-color, #e5e7eb)',
|
|
8402
|
-
borderRadius:
|
|
9102
|
+
borderRadius: `var(--seekora-border-radius, ${BORDER_RADIUS$5.md}px)`,
|
|
8403
9103
|
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))',
|
|
8404
9104
|
marginTop: 4,
|
|
8405
9105
|
};
|
|
@@ -8490,6 +9190,9 @@ const defaultItemStyle = {
|
|
|
8490
9190
|
backgroundColor: 'transparent',
|
|
8491
9191
|
color: 'var(--seekora-text-primary, #111827)',
|
|
8492
9192
|
transition: 'background-color 120ms ease',
|
|
9193
|
+
overflow: 'hidden',
|
|
9194
|
+
textOverflow: 'ellipsis',
|
|
9195
|
+
whiteSpace: 'nowrap',
|
|
8493
9196
|
};
|
|
8494
9197
|
function SuggestionItem({ suggestion, index, isActive, onSelect, className, style, enableHighlightMarkup = true, highlightMarkupOptions, renderHighlight, }) {
|
|
8495
9198
|
const displayText = suggestion.highlightedQuery ?? suggestion.query;
|
|
@@ -8674,8 +9377,8 @@ function ImageZoom({ src, alt = '', mode = 'both', zoomLevel = 2.5, className, s
|
|
|
8674
9377
|
backgroundRepeat: 'no-repeat',
|
|
8675
9378
|
border: '2px solid var(--seekora-border-color, #e5e7eb)',
|
|
8676
9379
|
borderRadius: 8,
|
|
8677
|
-
boxShadow: '0 8px 24px rgba(0,0,0,0.2)',
|
|
8678
|
-
backgroundColor: '#fff',
|
|
9380
|
+
boxShadow: 'var(--seekora-zoom-panel-shadow, 0 8px 24px rgba(0,0,0,0.2))',
|
|
9381
|
+
backgroundColor: 'var(--seekora-zoom-panel-bg, #fff)',
|
|
8679
9382
|
pointerEvents: 'none',
|
|
8680
9383
|
zIndex: 9998,
|
|
8681
9384
|
};
|
|
@@ -8690,9 +9393,9 @@ function ImageZoom({ src, alt = '', mode = 'both', zoomLevel = 2.5, className, s
|
|
|
8690
9393
|
height: lensSize,
|
|
8691
9394
|
left: cursorPos.x - lensSize / 2,
|
|
8692
9395
|
top: cursorPos.y - lensSize / 2,
|
|
8693
|
-
border: '2px solid rgba(255,255,255,0.8)',
|
|
9396
|
+
border: 'var(--seekora-lens-border, 2px solid rgba(255,255,255,0.8))',
|
|
8694
9397
|
borderRadius: '50%',
|
|
8695
|
-
boxShadow: '0 0 0 1px rgba(0,0,0,0.3), inset 0 0 0 1px rgba(0,0,0,0.3)',
|
|
9398
|
+
boxShadow: 'var(--seekora-lens-shadow, 0 0 0 1px rgba(0,0,0,0.3), inset 0 0 0 1px rgba(0,0,0,0.3))',
|
|
8696
9399
|
pointerEvents: 'none',
|
|
8697
9400
|
overflow: 'hidden',
|
|
8698
9401
|
zIndex: 100,
|
|
@@ -8722,8 +9425,8 @@ function ImageZoom({ src, alt = '', mode = 'both', zoomLevel = 2.5, className, s
|
|
|
8722
9425
|
width: 32,
|
|
8723
9426
|
height: 32,
|
|
8724
9427
|
borderRadius: '50%',
|
|
8725
|
-
backgroundColor: 'rgba(0,0,0,0.6)',
|
|
8726
|
-
color: '#fff',
|
|
9428
|
+
backgroundColor: 'var(--seekora-zoom-indicator-bg, rgba(0,0,0,0.6))',
|
|
9429
|
+
color: 'var(--seekora-zoom-indicator-text, #fff)',
|
|
8727
9430
|
display: 'flex',
|
|
8728
9431
|
alignItems: 'center',
|
|
8729
9432
|
justifyContent: 'center',
|
|
@@ -8740,8 +9443,8 @@ function ImageZoom({ src, alt = '', mode = 'both', zoomLevel = 2.5, className, s
|
|
|
8740
9443
|
top: cursorPos.y - 75,
|
|
8741
9444
|
width: 150,
|
|
8742
9445
|
height: 150,
|
|
8743
|
-
border: '2px solid rgba(0,0,0,0.3)',
|
|
8744
|
-
backgroundColor: 'rgba(255,255,255,0.1)',
|
|
9446
|
+
border: 'var(--seekora-hover-area-border, 2px solid rgba(0,0,0,0.3))',
|
|
9447
|
+
backgroundColor: 'var(--seekora-hover-area-bg, rgba(255,255,255,0.1))',
|
|
8745
9448
|
pointerEvents: 'none',
|
|
8746
9449
|
zIndex: 50,
|
|
8747
9450
|
} })),
|
|
@@ -8752,7 +9455,7 @@ function ImageZoom({ src, alt = '', mode = 'both', zoomLevel = 2.5, className, s
|
|
|
8752
9455
|
left: 0,
|
|
8753
9456
|
right: 0,
|
|
8754
9457
|
bottom: 0,
|
|
8755
|
-
backgroundColor: 'rgba(0,0,0,0.95)',
|
|
9458
|
+
backgroundColor: 'var(--seekora-lightbox-bg, rgba(0,0,0,0.95))',
|
|
8756
9459
|
zIndex: 9999,
|
|
8757
9460
|
display: 'flex',
|
|
8758
9461
|
alignItems: 'center',
|
|
@@ -8768,8 +9471,8 @@ function ImageZoom({ src, alt = '', mode = 'both', zoomLevel = 2.5, className, s
|
|
|
8768
9471
|
height: 44,
|
|
8769
9472
|
borderRadius: '50%',
|
|
8770
9473
|
border: 'none',
|
|
8771
|
-
backgroundColor: 'rgba(255,255,255,0.2)',
|
|
8772
|
-
color: '#fff',
|
|
9474
|
+
backgroundColor: 'var(--seekora-lightbox-btn-bg, rgba(255,255,255,0.2))',
|
|
9475
|
+
color: 'var(--seekora-lightbox-btn-text, #fff)',
|
|
8773
9476
|
fontSize: '1.5rem',
|
|
8774
9477
|
cursor: 'pointer',
|
|
8775
9478
|
display: 'flex',
|
|
@@ -8781,9 +9484,9 @@ function ImageZoom({ src, alt = '', mode = 'both', zoomLevel = 2.5, className, s
|
|
|
8781
9484
|
e.stopPropagation();
|
|
8782
9485
|
closeLightbox();
|
|
8783
9486
|
}, onMouseEnter: (e) => {
|
|
8784
|
-
e.currentTarget.style.backgroundColor = 'rgba(255,255,255,0.3)';
|
|
9487
|
+
e.currentTarget.style.backgroundColor = 'var(--seekora-lightbox-btn-bg-hover, rgba(255,255,255,0.3))';
|
|
8785
9488
|
}, onMouseLeave: (e) => {
|
|
8786
|
-
e.currentTarget.style.backgroundColor = 'rgba(255,255,255,0.2)';
|
|
9489
|
+
e.currentTarget.style.backgroundColor = 'var(--seekora-lightbox-btn-bg, rgba(255,255,255,0.2))';
|
|
8787
9490
|
} }, "\u2715"),
|
|
8788
9491
|
hasMultipleImages && (React.createElement(React.Fragment, null,
|
|
8789
9492
|
React.createElement("button", { type: "button", "aria-label": "Previous image", style: {
|
|
@@ -8795,8 +9498,8 @@ function ImageZoom({ src, alt = '', mode = 'both', zoomLevel = 2.5, className, s
|
|
|
8795
9498
|
height: 56,
|
|
8796
9499
|
borderRadius: '50%',
|
|
8797
9500
|
border: 'none',
|
|
8798
|
-
backgroundColor: 'rgba(255,255,255,0.2)',
|
|
8799
|
-
color: '#fff',
|
|
9501
|
+
backgroundColor: 'var(--seekora-lightbox-btn-bg, rgba(255,255,255,0.2))',
|
|
9502
|
+
color: 'var(--seekora-lightbox-btn-text, #fff)',
|
|
8800
9503
|
fontSize: '2rem',
|
|
8801
9504
|
fontWeight: 'bold',
|
|
8802
9505
|
cursor: 'pointer',
|
|
@@ -8809,9 +9512,9 @@ function ImageZoom({ src, alt = '', mode = 'both', zoomLevel = 2.5, className, s
|
|
|
8809
9512
|
e.stopPropagation();
|
|
8810
9513
|
goToPrev();
|
|
8811
9514
|
}, onMouseEnter: (e) => {
|
|
8812
|
-
e.currentTarget.style.backgroundColor = 'rgba(255,255,255,0.3)';
|
|
9515
|
+
e.currentTarget.style.backgroundColor = 'var(--seekora-lightbox-btn-bg-hover, rgba(255,255,255,0.3))';
|
|
8813
9516
|
}, onMouseLeave: (e) => {
|
|
8814
|
-
e.currentTarget.style.backgroundColor = 'rgba(255,255,255,0.2)';
|
|
9517
|
+
e.currentTarget.style.backgroundColor = 'var(--seekora-lightbox-btn-bg, rgba(255,255,255,0.2))';
|
|
8815
9518
|
} }, "\u2039"),
|
|
8816
9519
|
React.createElement("button", { type: "button", "aria-label": "Next image", style: {
|
|
8817
9520
|
position: 'absolute',
|
|
@@ -8822,8 +9525,8 @@ function ImageZoom({ src, alt = '', mode = 'both', zoomLevel = 2.5, className, s
|
|
|
8822
9525
|
height: 56,
|
|
8823
9526
|
borderRadius: '50%',
|
|
8824
9527
|
border: 'none',
|
|
8825
|
-
backgroundColor: 'rgba(255,255,255,0.2)',
|
|
8826
|
-
color: '#fff',
|
|
9528
|
+
backgroundColor: 'var(--seekora-lightbox-btn-bg, rgba(255,255,255,0.2))',
|
|
9529
|
+
color: 'var(--seekora-lightbox-btn-text, #fff)',
|
|
8827
9530
|
fontSize: '2rem',
|
|
8828
9531
|
fontWeight: 'bold',
|
|
8829
9532
|
cursor: 'pointer',
|
|
@@ -8836,9 +9539,9 @@ function ImageZoom({ src, alt = '', mode = 'both', zoomLevel = 2.5, className, s
|
|
|
8836
9539
|
e.stopPropagation();
|
|
8837
9540
|
goToNext();
|
|
8838
9541
|
}, onMouseEnter: (e) => {
|
|
8839
|
-
e.currentTarget.style.backgroundColor = 'rgba(255,255,255,0.3)';
|
|
9542
|
+
e.currentTarget.style.backgroundColor = 'var(--seekora-lightbox-btn-bg-hover, rgba(255,255,255,0.3))';
|
|
8840
9543
|
}, onMouseLeave: (e) => {
|
|
8841
|
-
e.currentTarget.style.backgroundColor = 'rgba(255,255,255,0.2)';
|
|
9544
|
+
e.currentTarget.style.backgroundColor = 'var(--seekora-lightbox-btn-bg, rgba(255,255,255,0.2))';
|
|
8842
9545
|
} }, "\u203A"))),
|
|
8843
9546
|
React.createElement("img", { src: allImages[lightboxIndex], alt: alt, style: {
|
|
8844
9547
|
maxWidth: '90%',
|
|
@@ -8864,7 +9567,7 @@ function ImageZoom({ src, alt = '', mode = 'both', zoomLevel = 2.5, className, s
|
|
|
8864
9567
|
width: 60,
|
|
8865
9568
|
height: 60,
|
|
8866
9569
|
padding: 0,
|
|
8867
|
-
border: i === lightboxIndex ? '3px solid #fff' : '2px solid rgba(255,255,255,0.3)',
|
|
9570
|
+
border: i === lightboxIndex ? 'var(--seekora-lightbox-thumb-border-active, 3px solid #fff)' : 'var(--seekora-lightbox-thumb-border, 2px solid rgba(255,255,255,0.3))',
|
|
8868
9571
|
borderRadius: 4,
|
|
8869
9572
|
overflow: 'hidden',
|
|
8870
9573
|
cursor: 'pointer',
|
|
@@ -8880,10 +9583,10 @@ function ImageZoom({ src, alt = '', mode = 'both', zoomLevel = 2.5, className, s
|
|
|
8880
9583
|
} },
|
|
8881
9584
|
React.createElement("img", { src: img, alt: "", style: { width: '100%', height: '100%', objectFit: 'cover' } }))))),
|
|
8882
9585
|
React.createElement("div", { style: {
|
|
8883
|
-
color: 'rgba(255,255,255,0.9)',
|
|
9586
|
+
color: 'var(--seekora-lightbox-counter-text, rgba(255,255,255,0.9))',
|
|
8884
9587
|
fontSize: '0.875rem',
|
|
8885
9588
|
textAlign: 'center',
|
|
8886
|
-
backgroundColor: 'rgba(0,0,0,0.5)',
|
|
9589
|
+
backgroundColor: 'var(--seekora-lightbox-counter-bg, rgba(0,0,0,0.5))',
|
|
8887
9590
|
padding: '4px 12px',
|
|
8888
9591
|
borderRadius: 12,
|
|
8889
9592
|
} },
|
|
@@ -8895,10 +9598,10 @@ function ImageZoom({ src, alt = '', mode = 'both', zoomLevel = 2.5, className, s
|
|
|
8895
9598
|
top: 20,
|
|
8896
9599
|
left: '50%',
|
|
8897
9600
|
transform: 'translateX(-50%)',
|
|
8898
|
-
color: 'rgba(255,255,255,0.7)',
|
|
9601
|
+
color: 'var(--seekora-lightbox-instructions-text, rgba(255,255,255,0.7))',
|
|
8899
9602
|
fontSize: '0.875rem',
|
|
8900
9603
|
textAlign: 'center',
|
|
8901
|
-
backgroundColor: 'rgba(0,0,0,0.5)',
|
|
9604
|
+
backgroundColor: 'var(--seekora-lightbox-instructions-bg, rgba(0,0,0,0.5))',
|
|
8902
9605
|
padding: '8px 16px',
|
|
8903
9606
|
borderRadius: 12,
|
|
8904
9607
|
} }, hasMultipleImages ? 'Use arrow keys or click thumbnails to navigate • ESC to close' : 'Click outside or press ESC to close')))));
|
|
@@ -8912,10 +9615,13 @@ function ImageZoom({ src, alt = '', mode = 'both', zoomLevel = 2.5, className, s
|
|
|
8912
9615
|
*/
|
|
8913
9616
|
const imgBaseStyle = {
|
|
8914
9617
|
width: '100%',
|
|
9618
|
+
height: 'auto',
|
|
8915
9619
|
aspectRatio: '1',
|
|
8916
9620
|
objectFit: 'cover',
|
|
8917
9621
|
borderRadius: 4,
|
|
8918
9622
|
backgroundColor: 'var(--seekora-bg-secondary, #f3f4f6)',
|
|
9623
|
+
display: 'block',
|
|
9624
|
+
overflow: 'hidden',
|
|
8919
9625
|
};
|
|
8920
9626
|
function ImageDisplay({ images, variant = 'single', alt = '', className, style, carouselAutoplay = false, carouselIntervalMs = 4000, enableZoom = false, zoomMode = 'both', zoomLevel = 2.5, showDots = true, }) {
|
|
8921
9627
|
const [index, setIndex] = useState(0);
|
|
@@ -8958,8 +9664,8 @@ function ImageDisplay({ images, variant = 'single', alt = '', className, style,
|
|
|
8958
9664
|
return (React.createElement("div", { className: clsx('seekora-img-display', 'seekora-img-carousel', className), style: { position: 'relative', ...style } },
|
|
8959
9665
|
mainImage,
|
|
8960
9666
|
safeImages.length > 1 && (React.createElement(React.Fragment, null,
|
|
8961
|
-
React.createElement("button", { type: "button", "aria-label": "Previous", className: "seekora-img-carousel-prev", style: arrowStyle(true), onMouseDown: (e) => { e.stopPropagation(); e.preventDefault(); go(-1); }, onClick: (e) => e.stopPropagation(), onMouseEnter: (e) => { e.currentTarget.style.backgroundColor = 'rgba(255,255,255,1)'; }, onMouseLeave: (e) => { e.currentTarget.style.backgroundColor = 'rgba(255,255,255,0.9)'; } }, "\u2039"),
|
|
8962
|
-
React.createElement("button", { type: "button", "aria-label": "Next", className: "seekora-img-carousel-next", style: arrowStyle(false), onMouseDown: (e) => { e.stopPropagation(); e.preventDefault(); go(1); }, onClick: (e) => e.stopPropagation(), onMouseEnter: (e) => { e.currentTarget.style.backgroundColor = 'rgba(255,255,255,1)'; }, onMouseLeave: (e) => { e.currentTarget.style.backgroundColor = 'rgba(255,255,255,0.9)'; } }, "\u203A"),
|
|
9667
|
+
React.createElement("button", { type: "button", "aria-label": "Previous", className: "seekora-img-carousel-prev", style: arrowStyle(true), onMouseDown: (e) => { e.stopPropagation(); e.preventDefault(); go(-1); }, onClick: (e) => { e.stopPropagation(); e.preventDefault(); }, onMouseEnter: (e) => { e.currentTarget.style.backgroundColor = 'var(--seekora-carousel-btn-bg-hover, rgba(255,255,255,1))'; }, onMouseLeave: (e) => { e.currentTarget.style.backgroundColor = 'var(--seekora-carousel-btn-bg, rgba(255,255,255,0.9))'; } }, "\u2039"),
|
|
9668
|
+
React.createElement("button", { type: "button", "aria-label": "Next", className: "seekora-img-carousel-next", style: arrowStyle(false), onMouseDown: (e) => { e.stopPropagation(); e.preventDefault(); go(1); }, onClick: (e) => { e.stopPropagation(); e.preventDefault(); }, onMouseEnter: (e) => { e.currentTarget.style.backgroundColor = 'var(--seekora-carousel-btn-bg-hover, rgba(255,255,255,1))'; }, onMouseLeave: (e) => { e.currentTarget.style.backgroundColor = 'var(--seekora-carousel-btn-bg, rgba(255,255,255,0.9))'; } }, "\u203A"),
|
|
8963
9669
|
showDots && (React.createElement("div", { className: "seekora-img-carousel-dots", style: {
|
|
8964
9670
|
position: 'absolute',
|
|
8965
9671
|
bottom: 8,
|
|
@@ -8968,16 +9674,16 @@ function ImageDisplay({ images, variant = 'single', alt = '', className, style,
|
|
|
8968
9674
|
display: 'flex',
|
|
8969
9675
|
gap: 6,
|
|
8970
9676
|
padding: '6px 12px',
|
|
8971
|
-
backgroundColor: 'rgba(0,0,0,0.5)',
|
|
9677
|
+
backgroundColor: 'var(--seekora-carousel-dots-bg, rgba(0,0,0,0.5))',
|
|
8972
9678
|
borderRadius: 12,
|
|
8973
9679
|
zIndex: 10,
|
|
8974
|
-
} }, safeImages.map((_, i) => (React.createElement("button", { key: i, type: "button", "aria-label": `Go to image ${i + 1}`, onMouseDown: (e) => { e.stopPropagation(); e.preventDefault(); }, onClick: (e) => { e.stopPropagation(); setIndex(i); }, style: {
|
|
9680
|
+
} }, safeImages.map((_, i) => (React.createElement("button", { key: i, type: "button", "aria-label": `Go to image ${i + 1}`, onMouseDown: (e) => { e.stopPropagation(); e.preventDefault(); }, onClick: (e) => { e.stopPropagation(); e.preventDefault(); setIndex(i); }, style: {
|
|
8975
9681
|
width: 8,
|
|
8976
9682
|
height: 8,
|
|
8977
9683
|
borderRadius: '50%',
|
|
8978
9684
|
border: 'none',
|
|
8979
9685
|
padding: 0,
|
|
8980
|
-
backgroundColor: i === index ? '#fff' : 'rgba(255,255,255,0.5)',
|
|
9686
|
+
backgroundColor: i === index ? 'var(--seekora-carousel-dot-active, #fff)' : 'var(--seekora-carousel-dot, rgba(255,255,255,0.5))',
|
|
8981
9687
|
cursor: 'pointer',
|
|
8982
9688
|
transition: 'all 150ms ease',
|
|
8983
9689
|
} })))))))));
|
|
@@ -8987,7 +9693,7 @@ function ImageDisplay({ images, variant = 'single', alt = '', className, style,
|
|
|
8987
9693
|
const mainImage = enableZoom ? (React.createElement(ImageZoom, { src: current, alt: alt, mode: zoomMode, zoomLevel: zoomLevel, images: safeImages, currentIndex: index, className: "seekora-img-thumb-main", style: thumbMainStyle })) : (React.createElement("img", { src: current, alt: alt, className: "seekora-img-thumb-main", style: thumbMainStyle, loading: "lazy" }));
|
|
8988
9694
|
return (React.createElement("div", { className: clsx('seekora-img-display', 'seekora-img-thumbstrip', className), style: { display: 'flex', flexDirection: 'column', gap: 8, ...style } },
|
|
8989
9695
|
mainImage,
|
|
8990
|
-
React.createElement("div", { className: "seekora-img-thumbs", style: { display: 'flex', gap: 4, overflowX: 'auto', paddingBottom: 4 } }, safeImages.map((src, i) => (React.createElement("button", { type: "button", key: i, className: clsx('seekora-img-thumb', i === index && 'seekora-img-thumb--active'), style: { flexShrink: 0, width: 48, height: 48, padding: 0, border: i === index ? '2px solid var(--seekora-primary)' : '1px solid transparent', borderRadius: 4, overflow: 'hidden', cursor: 'pointer', background: 'none' }, onMouseDown: (e) => { e.stopPropagation(); e.preventDefault(); setIndex(i); }, onClick: (e) => e.stopPropagation() },
|
|
9696
|
+
React.createElement("div", { className: "seekora-img-thumbs", style: { display: 'flex', gap: 4, overflowX: 'auto', paddingBottom: 4 } }, safeImages.map((src, i) => (React.createElement("button", { type: "button", key: i, className: clsx('seekora-img-thumb', i === index && 'seekora-img-thumb--active'), style: { flexShrink: 0, width: 48, height: 48, padding: 0, border: i === index ? '2px solid var(--seekora-primary)' : '1px solid transparent', borderRadius: 4, overflow: 'hidden', cursor: 'pointer', background: 'none' }, onMouseDown: (e) => { e.stopPropagation(); e.preventDefault(); setIndex(i); }, onClick: (e) => { e.stopPropagation(); e.preventDefault(); } },
|
|
8991
9697
|
React.createElement("img", { src: src, alt: "", style: { width: '100%', height: '100%', objectFit: 'cover' } })))))));
|
|
8992
9698
|
}
|
|
8993
9699
|
return React.createElement("img", { src: current, alt: alt, className: clsx('seekora-img-display', className), style: { ...imgBaseStyle, ...style }, loading: "lazy" });
|
|
@@ -9002,8 +9708,8 @@ function arrowStyle(left) {
|
|
|
9002
9708
|
height: 32,
|
|
9003
9709
|
borderRadius: '50%',
|
|
9004
9710
|
border: 'none',
|
|
9005
|
-
backgroundColor: 'rgba(255, 255, 255, 0.9)',
|
|
9006
|
-
color: '#111',
|
|
9711
|
+
backgroundColor: 'var(--seekora-carousel-btn-bg, rgba(255, 255, 255, 0.9))',
|
|
9712
|
+
color: 'var(--seekora-carousel-btn-text, #111)',
|
|
9007
9713
|
fontSize: '1.25rem',
|
|
9008
9714
|
fontWeight: 'bold',
|
|
9009
9715
|
cursor: 'pointer',
|
|
@@ -9022,6 +9728,14 @@ function arrowStyle(left) {
|
|
|
9022
9728
|
* Renders a set of action buttons for product cards. Can be positioned absolutely
|
|
9023
9729
|
* over the image (on hover) or inline below the card content.
|
|
9024
9730
|
*/
|
|
9731
|
+
const SPACING$2 = {
|
|
9732
|
+
sm: 8};
|
|
9733
|
+
const TRANSITIONS$2 = {
|
|
9734
|
+
fast: '150ms ease-in-out'};
|
|
9735
|
+
const BORDER_RADIUS$4 = {
|
|
9736
|
+
md: 6};
|
|
9737
|
+
const SHADOWS = {
|
|
9738
|
+
md: '0 2px 4px rgba(0,0,0,0.1)'};
|
|
9025
9739
|
const DEFAULT_ICONS = {
|
|
9026
9740
|
addToCart: '🛒',
|
|
9027
9741
|
wishlist: '♡',
|
|
@@ -9037,8 +9751,8 @@ const DEFAULT_LABELS = {
|
|
|
9037
9751
|
compare: 'Compare',
|
|
9038
9752
|
};
|
|
9039
9753
|
const BUTTON_SIZES = {
|
|
9040
|
-
small: { width:
|
|
9041
|
-
medium: { width:
|
|
9754
|
+
small: { width: 44, height: 44, fontSize: '0.75rem', iconSize: '1rem' },
|
|
9755
|
+
medium: { width: 44, height: 44, fontSize: '0.875rem', iconSize: '1.25rem' },
|
|
9042
9756
|
large: { width: 44, height: 44, fontSize: '1rem', iconSize: '1.5rem' },
|
|
9043
9757
|
};
|
|
9044
9758
|
function ActionButtons({ buttons, layout = 'horizontal', position = 'inline', showLabels = false, size = 'medium', className, style, }) {
|
|
@@ -9047,11 +9761,11 @@ function ActionButtons({ buttons, layout = 'horizontal', position = 'inline', sh
|
|
|
9047
9761
|
const containerStyle = {
|
|
9048
9762
|
display: 'flex',
|
|
9049
9763
|
flexDirection: layout === 'vertical' ? 'column' : 'row',
|
|
9050
|
-
gap:
|
|
9764
|
+
gap: SPACING$2.sm,
|
|
9051
9765
|
...(isOverlay ? {
|
|
9052
9766
|
position: 'absolute',
|
|
9053
|
-
...(position === 'top-right' ? { top:
|
|
9054
|
-
...(position === 'bottom-center' ? { bottom:
|
|
9767
|
+
...(position === 'top-right' ? { top: SPACING$2.sm, right: SPACING$2.sm } : {}),
|
|
9768
|
+
...(position === 'bottom-center' ? { bottom: SPACING$2.sm, left: '50%', transform: 'translateX(-50%)' } : {}),
|
|
9055
9769
|
} : {}),
|
|
9056
9770
|
...style,
|
|
9057
9771
|
};
|
|
@@ -9066,12 +9780,12 @@ function ActionButtons({ buttons, layout = 'horizontal', position = 'inline', sh
|
|
|
9066
9780
|
fontSize: sizeConfig.fontSize,
|
|
9067
9781
|
fontWeight: 500,
|
|
9068
9782
|
border: 'none',
|
|
9069
|
-
borderRadius:
|
|
9070
|
-
backgroundColor: 'var(--seekora-bg-surface,
|
|
9071
|
-
color: 'var(--seekora-text,
|
|
9783
|
+
borderRadius: BORDER_RADIUS$4.md,
|
|
9784
|
+
backgroundColor: 'var(--seekora-bg-surface, transparent)',
|
|
9785
|
+
color: 'var(--seekora-text, inherit)',
|
|
9072
9786
|
cursor: 'pointer',
|
|
9073
|
-
transition:
|
|
9074
|
-
boxShadow:
|
|
9787
|
+
transition: `all ${TRANSITIONS$2.fast}`,
|
|
9788
|
+
boxShadow: SHADOWS.md,
|
|
9075
9789
|
};
|
|
9076
9790
|
const handleClick = (btn, e) => {
|
|
9077
9791
|
e.stopPropagation();
|
|
@@ -9100,6 +9814,11 @@ function ActionButtons({ buttons, layout = 'horizontal', position = 'inline', sh
|
|
|
9100
9814
|
* optional description, image, url. Overridable via className/style. Use for
|
|
9101
9815
|
* search results, section blocks, or any list; for e-commerce products use ProductCard.
|
|
9102
9816
|
*/
|
|
9817
|
+
const TRANSITIONS$1 = {
|
|
9818
|
+
fast: '150ms ease-in-out'};
|
|
9819
|
+
const BORDER_RADIUS$3 = {
|
|
9820
|
+
sm: 4,
|
|
9821
|
+
md: 6};
|
|
9103
9822
|
const cardStyle$1 = {
|
|
9104
9823
|
display: 'flex',
|
|
9105
9824
|
flexDirection: 'column',
|
|
@@ -9107,19 +9826,21 @@ const cardStyle$1 = {
|
|
|
9107
9826
|
padding: 8,
|
|
9108
9827
|
cursor: 'pointer',
|
|
9109
9828
|
border: 'none',
|
|
9110
|
-
borderRadius:
|
|
9829
|
+
borderRadius: `var(--seekora-border-radius, ${BORDER_RADIUS$3.md}px)`,
|
|
9111
9830
|
backgroundColor: 'transparent',
|
|
9112
9831
|
textAlign: 'left',
|
|
9113
9832
|
fontSize: 'inherit',
|
|
9114
9833
|
fontFamily: 'inherit',
|
|
9115
|
-
transition:
|
|
9834
|
+
transition: `background-color ${TRANSITIONS$1.fast}`,
|
|
9116
9835
|
};
|
|
9117
9836
|
const imgStyle$1 = {
|
|
9118
9837
|
width: '100%',
|
|
9119
|
-
aspectRatio: '1',
|
|
9838
|
+
aspectRatio: 'var(--seekora-card-aspect-ratio, 1)',
|
|
9120
9839
|
objectFit: 'cover',
|
|
9121
|
-
borderRadius:
|
|
9840
|
+
borderRadius: BORDER_RADIUS$3.sm,
|
|
9122
9841
|
backgroundColor: 'var(--seekora-bg-secondary, #f3f4f6)',
|
|
9842
|
+
display: 'block',
|
|
9843
|
+
overflow: 'hidden',
|
|
9123
9844
|
};
|
|
9124
9845
|
function ItemCard({ item, position, onSelect, className, style, asLink = true, imageVariant = 'single', layout = 'vertical', actionButtons, actionButtonsPosition = 'overlay-top-right', showActionLabels = false, }) {
|
|
9125
9846
|
const images = item.images?.length ? item.images : item.image ?? item.imageUrl ? [String(item.image ?? item.imageUrl)] : [];
|
|
@@ -9127,12 +9848,12 @@ function ItemCard({ item, position, onSelect, className, style, asLink = true, i
|
|
|
9127
9848
|
const description = item.description ?? item.secondaryText;
|
|
9128
9849
|
const href = item.url;
|
|
9129
9850
|
const isHorizontal = layout === 'horizontal';
|
|
9130
|
-
const imageBlock = images.length > 0 ? (React.createElement("div", { style: { position: 'relative', ...(isHorizontal ? {
|
|
9851
|
+
const imageBlock = images.length > 0 ? (React.createElement("div", { style: { position: 'relative', overflow: 'hidden', borderRadius: 4, ...(isHorizontal ? { minWidth: 80, flexBasis: '20%', maxWidth: 120, flexShrink: 0 } : {}) } },
|
|
9131
9852
|
React.createElement(ImageDisplay, { images: images, variant: imageVariant, alt: String(title), className: "seekora-item-card-image" }),
|
|
9132
|
-
actionButtons && actionButtons.length > 0 && actionButtonsPosition?.startsWith('overlay') && (React.createElement(ActionButtons, { buttons: actionButtons, position: actionButtonsPosition === 'overlay-top-right' ? 'top-right' : 'bottom-center', showLabels: showActionLabels, size: "small" })))) : (React.createElement("div", { className: "seekora-item-card-placeholder", style: { ...imgStyle$1, ...(isHorizontal ? {
|
|
9853
|
+
actionButtons && actionButtons.length > 0 && actionButtonsPosition?.startsWith('overlay') && (React.createElement(ActionButtons, { buttons: actionButtons, position: actionButtonsPosition === 'overlay-top-right' ? 'top-right' : 'bottom-center', showLabels: showActionLabels, size: "small" })))) : (React.createElement("div", { className: "seekora-item-card-placeholder", style: { ...imgStyle$1, ...(isHorizontal ? { minWidth: 80, flexBasis: '20%', maxWidth: 120, height: 80, flexShrink: 0 } : {}) }, "aria-hidden": true }));
|
|
9133
9854
|
const textBlock = (React.createElement("div", { style: isHorizontal ? { display: 'flex', flexDirection: 'column', gap: 4, flex: 1, minWidth: 0 } : undefined },
|
|
9134
|
-
React.createElement("span", { className: "seekora-item-card-title", style: { fontSize: '0.875rem', fontWeight: 500 } }, String(title)),
|
|
9135
|
-
description ? (React.createElement("span", { className: "seekora-item-card-description", style: { fontSize: '0.8125rem', color: 'var(--seekora-text-secondary, #6b7280)', lineHeight: 1.3 } }, String(description))) : null,
|
|
9855
|
+
React.createElement("span", { className: "seekora-item-card-title", style: { fontSize: '0.875rem', fontWeight: 500, lineHeight: 1.4, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } }, String(title)),
|
|
9856
|
+
description ? (React.createElement("span", { className: "seekora-item-card-description", style: { fontSize: '0.8125rem', color: 'var(--seekora-text-secondary, #6b7280)', lineHeight: 1.3, display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical', overflow: 'hidden' } }, String(description))) : null,
|
|
9136
9857
|
actionButtons && actionButtons.length > 0 && actionButtonsPosition === 'inline' && (React.createElement(ActionButtons, { buttons: actionButtons, position: "inline", showLabels: showActionLabels, size: "small", layout: "horizontal" }))));
|
|
9137
9858
|
const content = isHorizontal ? (React.createElement("div", { style: { display: 'flex', gap: 12, alignItems: 'flex-start' } },
|
|
9138
9859
|
imageBlock,
|
|
@@ -9163,11 +9884,12 @@ function ItemCard({ item, position, onSelect, className, style, asLink = true, i
|
|
|
9163
9884
|
* or custom renderItem. Use for search hits, section blocks, docs, articles; for
|
|
9164
9885
|
* product-only lists use ProductGrid.
|
|
9165
9886
|
*/
|
|
9887
|
+
const SPACING$1 = {
|
|
9888
|
+
md: 12};
|
|
9166
9889
|
const defaultGridStyle = {
|
|
9167
9890
|
display: 'grid',
|
|
9168
|
-
|
|
9169
|
-
|
|
9170
|
-
padding: 12,
|
|
9891
|
+
gap: SPACING$1.md,
|
|
9892
|
+
padding: SPACING$1.md,
|
|
9171
9893
|
};
|
|
9172
9894
|
function toGenericItem(item, getItemId, getItemTitle, getItemImage, getItemDescription, getItemUrl) {
|
|
9173
9895
|
return {
|
|
@@ -9764,19 +10486,24 @@ function PriceDisplay({ price, comparePrice, priceRange, currency = '$', currenc
|
|
|
9764
10486
|
/**
|
|
9765
10487
|
* BadgeList – renders product badges (sale, new, sold out, custom)
|
|
9766
10488
|
*/
|
|
10489
|
+
const SPACING = {
|
|
10490
|
+
xs: 4,
|
|
10491
|
+
sm: 8};
|
|
10492
|
+
const BORDER_RADIUS$2 = {
|
|
10493
|
+
sm: 4};
|
|
9767
10494
|
const positionStyles = {
|
|
9768
|
-
'top-left': { position: 'absolute', top:
|
|
9769
|
-
'top-right': { position: 'absolute', top:
|
|
9770
|
-
'bottom-left': { position: 'absolute', bottom:
|
|
9771
|
-
'bottom-right': { position: 'absolute', bottom:
|
|
10495
|
+
'top-left': { position: 'absolute', top: SPACING.sm, left: SPACING.sm },
|
|
10496
|
+
'top-right': { position: 'absolute', top: SPACING.sm, right: SPACING.sm },
|
|
10497
|
+
'bottom-left': { position: 'absolute', bottom: SPACING.sm, left: SPACING.sm },
|
|
10498
|
+
'bottom-right': { position: 'absolute', bottom: SPACING.sm, right: SPACING.sm },
|
|
9772
10499
|
inline: {},
|
|
9773
10500
|
};
|
|
9774
10501
|
const typeColors = {
|
|
9775
|
-
sale: { bg: '#ef4444', text: '#fff' },
|
|
9776
|
-
new: { bg: '#3b82f6', text: '#fff' },
|
|
9777
|
-
soldOut: { bg: '#6b7280', text: '#fff' },
|
|
9778
|
-
limited: { bg: '#f59e0b', text: '#fff' },
|
|
9779
|
-
custom: { bg: '#111827', text: '#fff' },
|
|
10502
|
+
sale: { bg: 'var(--seekora-badge-sale-bg, #ef4444)', text: 'var(--seekora-badge-sale-text, #fff)' },
|
|
10503
|
+
new: { bg: 'var(--seekora-badge-new-bg, #3b82f6)', text: 'var(--seekora-badge-new-text, #fff)' },
|
|
10504
|
+
soldOut: { bg: 'var(--seekora-badge-soldout-bg, #6b7280)', text: 'var(--seekora-badge-soldout-text, #fff)' },
|
|
10505
|
+
limited: { bg: 'var(--seekora-badge-limited-bg, #f59e0b)', text: 'var(--seekora-badge-limited-text, #fff)' },
|
|
10506
|
+
custom: { bg: 'var(--seekora-badge-custom-bg, #111827)', text: 'var(--seekora-badge-custom-text, #fff)' },
|
|
9780
10507
|
};
|
|
9781
10508
|
function BadgeList({ badges, maxBadges, position = 'top-left', className, style, }) {
|
|
9782
10509
|
if (!badges || badges.length === 0)
|
|
@@ -9785,8 +10512,8 @@ function BadgeList({ badges, maxBadges, position = 'top-left', className, style,
|
|
|
9785
10512
|
return (React.createElement("div", { className: clsx('seekora-badge-list', className), style: {
|
|
9786
10513
|
display: 'flex',
|
|
9787
10514
|
flexWrap: 'wrap',
|
|
9788
|
-
gap:
|
|
9789
|
-
zIndex:
|
|
10515
|
+
gap: SPACING.xs,
|
|
10516
|
+
zIndex: 2,
|
|
9790
10517
|
...positionStyles[position],
|
|
9791
10518
|
...style,
|
|
9792
10519
|
} }, visible.map((badge, i) => {
|
|
@@ -9794,10 +10521,10 @@ function BadgeList({ badges, maxBadges, position = 'top-left', className, style,
|
|
|
9794
10521
|
return (React.createElement("span", { key: `${badge.text}-${i}`, className: clsx('seekora-badge', badge.type && `seekora-badge--${badge.type === 'soldOut' ? 'sold-out' : badge.type}`), style: {
|
|
9795
10522
|
display: 'inline-block',
|
|
9796
10523
|
padding: '2px 8px',
|
|
9797
|
-
borderRadius:
|
|
10524
|
+
borderRadius: BORDER_RADIUS$2.sm,
|
|
9798
10525
|
fontSize: '0.6875rem',
|
|
9799
10526
|
fontWeight: 600,
|
|
9800
|
-
lineHeight: 1.
|
|
10527
|
+
lineHeight: 1.2,
|
|
9801
10528
|
backgroundColor: badge.color ?? colors.bg,
|
|
9802
10529
|
color: badge.textColor ?? colors.text,
|
|
9803
10530
|
whiteSpace: 'nowrap',
|
|
@@ -10027,7 +10754,7 @@ function VariantSwatches({ options, visibleOptions, maxValues = 5, colorMap, sel
|
|
|
10027
10754
|
outlineOffset: 2,
|
|
10028
10755
|
cursor: onSwatchClick && isAvailable ? 'pointer' : 'not-allowed',
|
|
10029
10756
|
flexShrink: 0,
|
|
10030
|
-
boxShadow: isSelected ? '0 0 0 1px #fff' : 'none',
|
|
10757
|
+
boxShadow: isSelected ? 'var(--seekora-swatch-ring, 0 0 0 1px #fff)' : 'none',
|
|
10031
10758
|
opacity: isAvailable ? 1 : 0.3,
|
|
10032
10759
|
position: 'relative',
|
|
10033
10760
|
}, onMouseEnter: () => isAvailable && onSwatchHover?.(option.name, value), onMouseDown: (e) => {
|
|
@@ -10044,7 +10771,7 @@ function VariantSwatches({ options, visibleOptions, maxValues = 5, colorMap, sel
|
|
|
10044
10771
|
left: '-2px',
|
|
10045
10772
|
right: '-2px',
|
|
10046
10773
|
height: 1,
|
|
10047
|
-
backgroundColor: '#ef4444',
|
|
10774
|
+
backgroundColor: 'var(--seekora-unavailable-line, #ef4444)',
|
|
10048
10775
|
transform: 'translateY(-50%) rotate(-45deg)',
|
|
10049
10776
|
} }))));
|
|
10050
10777
|
}
|
|
@@ -10060,7 +10787,7 @@ function VariantSwatches({ options, visibleOptions, maxValues = 5, colorMap, sel
|
|
|
10060
10787
|
? 'var(--seekora-primary, #111827)'
|
|
10061
10788
|
: 'transparent',
|
|
10062
10789
|
color: isSelected
|
|
10063
|
-
? '#fff'
|
|
10790
|
+
? 'var(--seekora-primary-text, #fff)'
|
|
10064
10791
|
: 'var(--seekora-text-secondary, #6b7280)',
|
|
10065
10792
|
cursor: onSwatchClick && isAvailable ? 'pointer' : 'not-allowed',
|
|
10066
10793
|
whiteSpace: 'nowrap',
|
|
@@ -10096,17 +10823,21 @@ function VariantSwatches({ options, visibleOptions, maxValues = 5, colorMap, sel
|
|
|
10096
10823
|
* Not exported from the package. Each layout renders the same product data
|
|
10097
10824
|
* with different visual emphasis.
|
|
10098
10825
|
*/
|
|
10826
|
+
const BORDER_RADIUS$1 = {
|
|
10827
|
+
sm: 4};
|
|
10099
10828
|
const imgPlaceholderStyle = {
|
|
10100
10829
|
width: '100%',
|
|
10101
10830
|
aspectRatio: '1',
|
|
10102
10831
|
objectFit: 'cover',
|
|
10103
|
-
borderRadius:
|
|
10832
|
+
borderRadius: BORDER_RADIUS$1.sm,
|
|
10104
10833
|
backgroundColor: 'var(--seekora-bg-secondary, #f3f4f6)',
|
|
10105
10834
|
};
|
|
10106
10835
|
function ImageBlock({ images, title, imageVariant, aspectRatio, enableZoom, zoomMode, zoomLevel }) {
|
|
10107
|
-
const ar = aspectRatio
|
|
10836
|
+
const ar = aspectRatio
|
|
10837
|
+
? (aspectRatio.includes(':') ? aspectRatio.replace(':', '/') : aspectRatio)
|
|
10838
|
+
: '1';
|
|
10108
10839
|
if (images.length > 0) {
|
|
10109
|
-
return (React.createElement("div", { className: "seekora-product-card__image", style: { position: 'relative', overflow: 'hidden', borderRadius:
|
|
10840
|
+
return (React.createElement("div", { className: "seekora-product-card__image", style: { position: 'relative', overflow: 'hidden', borderRadius: BORDER_RADIUS$1.sm } },
|
|
10110
10841
|
React.createElement(ImageDisplay, { images: images, variant: images.length > 1 ? imageVariant : 'single', alt: title, className: "seekora-suggestions-product-card-image", style: { aspectRatio: ar }, enableZoom: enableZoom, zoomMode: zoomMode, zoomLevel: zoomLevel })));
|
|
10111
10842
|
}
|
|
10112
10843
|
return React.createElement("div", { className: "seekora-product-card__image seekora-suggestions-product-card-placeholder", style: { ...imgPlaceholderStyle, aspectRatio: ar }, "aria-hidden": true });
|
|
@@ -10115,7 +10846,7 @@ function ImageBlock({ images, title, imageVariant, aspectRatio, enableZoom, zoom
|
|
|
10115
10846
|
function MinimalLayout({ images, title, price, product, imageVariant, displayConfig, enableImageZoom, imageZoomMode, imageZoomLevel }) {
|
|
10116
10847
|
return (React.createElement(React.Fragment, null,
|
|
10117
10848
|
React.createElement(ImageBlock, { images: images, title: title, imageVariant: imageVariant, aspectRatio: displayConfig.imageAspectRatio, enableZoom: enableImageZoom, zoomMode: imageZoomMode, zoomLevel: imageZoomLevel }),
|
|
10118
|
-
React.createElement("span", { className: "seekora-product-card__title", style: { fontSize: '0.875rem', fontWeight: 500 } }, title),
|
|
10849
|
+
React.createElement("span", { className: "seekora-product-card__title", style: { fontSize: '0.875rem', fontWeight: 500, lineHeight: 1.4, overflow: 'hidden', textOverflow: 'ellipsis' } }, title),
|
|
10119
10850
|
price != null && !Number.isNaN(price) && (React.createElement("span", { className: "seekora-product-card__price seekora-suggestions-product-card-price", style: { fontSize: '0.875rem', color: 'var(--seekora-text-secondary, #6b7280)' } },
|
|
10120
10851
|
product.currency ?? '$',
|
|
10121
10852
|
price.toFixed(2)))));
|
|
@@ -10123,31 +10854,35 @@ function MinimalLayout({ images, title, price, product, imageVariant, displayCon
|
|
|
10123
10854
|
/** standard: image, badges, brand, title, price + compare price, color swatches */
|
|
10124
10855
|
function StandardLayout({ images, title, price, comparePrice, brand, badges, options, variants, product, imageVariant, displayConfig, onVariantHover, onVariantClick, selectedVariants, actionButtons, actionButtonsPosition, showActionLabels, enableImageZoom, imageZoomMode, imageZoomLevel, }) {
|
|
10125
10856
|
const cfg = displayConfig;
|
|
10857
|
+
// Normalize position: 'overlay-*' positions render over image, everything else renders inline
|
|
10858
|
+
const isOverlayPosition = actionButtonsPosition?.startsWith('overlay');
|
|
10126
10859
|
return (React.createElement(React.Fragment, null,
|
|
10127
10860
|
React.createElement("div", { style: { position: 'relative' } },
|
|
10128
10861
|
React.createElement(ImageBlock, { images: images, title: title, imageVariant: imageVariant, aspectRatio: cfg.imageAspectRatio, enableZoom: enableImageZoom, zoomMode: imageZoomMode, zoomLevel: imageZoomLevel }),
|
|
10129
10862
|
cfg.showBadges !== false && badges.length > 0 && (React.createElement(BadgeList, { badges: badges, position: "top-left", maxBadges: 2 })),
|
|
10130
|
-
actionButtons && actionButtons.length > 0 &&
|
|
10863
|
+
actionButtons && actionButtons.length > 0 && isOverlayPosition && (React.createElement(ActionButtons, { buttons: actionButtons, position: actionButtonsPosition === 'overlay-top-right' ? 'top-right' : 'bottom-center', showLabels: showActionLabels, size: "small" }))),
|
|
10131
10864
|
React.createElement("div", { className: "seekora-product-card__body", style: { display: 'flex', flexDirection: 'column', gap: 4 } },
|
|
10132
10865
|
cfg.showBrand !== false && brand && (React.createElement("span", { className: "seekora-product-card__brand", style: { fontSize: '0.75rem', color: 'var(--seekora-text-secondary, #6b7280)', textTransform: 'uppercase', letterSpacing: '0.02em' } }, brand)),
|
|
10133
|
-
React.createElement("span", { className: "seekora-product-card__title", style: { fontSize: '0.875rem', fontWeight: 500 } }, title),
|
|
10866
|
+
React.createElement("span", { className: "seekora-product-card__title", style: { fontSize: '0.875rem', fontWeight: 500, lineHeight: 1.4, overflow: 'hidden', textOverflow: 'ellipsis' } }, title),
|
|
10134
10867
|
React.createElement("div", { className: "seekora-product-card__price" },
|
|
10135
10868
|
React.createElement(PriceDisplay, { price: price ?? undefined, comparePrice: comparePrice ?? undefined, currency: cfg.currency ?? product.currency, currencyPosition: cfg.currencyPosition, priceDecimals: cfg.priceDecimals, showDiscount: cfg.showDiscount, style: { fontSize: '0.875rem' } })),
|
|
10136
10869
|
cfg.showVariants !== false && options.length > 0 && (React.createElement(VariantSwatches, { options: options, visibleOptions: cfg.variantOptionsToShow, maxValues: cfg.maxVariantValues, selectedValues: selectedVariants, variants: variants, onSwatchHover: onVariantHover, onSwatchClick: onVariantClick })),
|
|
10137
|
-
actionButtons && actionButtons.length > 0 &&
|
|
10870
|
+
actionButtons && actionButtons.length > 0 && !isOverlayPosition && (React.createElement(ActionButtons, { buttons: actionButtons, position: "inline", showLabels: showActionLabels, size: "small", layout: "horizontal" })))));
|
|
10138
10871
|
}
|
|
10139
10872
|
/** detailed: image, badges, brand, title, price + compare + discount, rating, all swatches, stock */
|
|
10140
10873
|
function DetailedLayout({ images, title, price, comparePrice, brand, badges, priceRange, options, variants, product, imageVariant, displayConfig, onVariantHover, onVariantClick, selectedVariants, actionButtons, actionButtonsPosition, showActionLabels, enableImageZoom, imageZoomMode, imageZoomLevel, }) {
|
|
10141
10874
|
const cfg = displayConfig;
|
|
10142
10875
|
const available = product.available;
|
|
10876
|
+
// Normalize position: 'overlay-*' positions render over image, everything else renders inline
|
|
10877
|
+
const isOverlayPosition = actionButtonsPosition?.startsWith('overlay');
|
|
10143
10878
|
return (React.createElement(React.Fragment, null,
|
|
10144
10879
|
React.createElement("div", { style: { position: 'relative' } },
|
|
10145
10880
|
React.createElement(ImageBlock, { images: images, title: title, imageVariant: imageVariant, aspectRatio: cfg.imageAspectRatio, enableZoom: enableImageZoom, zoomMode: imageZoomMode, zoomLevel: imageZoomLevel }),
|
|
10146
10881
|
cfg.showBadges !== false && badges.length > 0 && (React.createElement(BadgeList, { badges: badges, position: "top-left" })),
|
|
10147
|
-
actionButtons && actionButtons.length > 0 &&
|
|
10882
|
+
actionButtons && actionButtons.length > 0 && isOverlayPosition && (React.createElement(ActionButtons, { buttons: actionButtons, position: actionButtonsPosition === 'overlay-top-right' ? 'top-right' : 'bottom-center', showLabels: showActionLabels, size: "small" }))),
|
|
10148
10883
|
React.createElement("div", { className: "seekora-product-card__body", style: { display: 'flex', flexDirection: 'column', gap: 4 } },
|
|
10149
10884
|
cfg.showBrand !== false && brand && (React.createElement("span", { className: "seekora-product-card__brand", style: { fontSize: '0.75rem', color: 'var(--seekora-text-secondary, #6b7280)', textTransform: 'uppercase', letterSpacing: '0.02em' } }, brand)),
|
|
10150
|
-
React.createElement("span", { className: "seekora-product-card__title", style: { fontSize: '0.875rem', fontWeight: 500 } }, title),
|
|
10885
|
+
React.createElement("span", { className: "seekora-product-card__title", style: { fontSize: '0.875rem', fontWeight: 500, lineHeight: 1.4, overflow: 'hidden', textOverflow: 'ellipsis' } }, title),
|
|
10151
10886
|
cfg.showRating !== false && product.rating != null && (React.createElement(RatingDisplay, { rating: product.rating, reviewCount: product.reviewCount, variant: "compact", size: "small", showNumeric: false, showReviewCount: true, className: "seekora-product-card__rating" })),
|
|
10152
10887
|
React.createElement("div", { className: "seekora-product-card__price" }, cfg.showPriceRange && priceRange ? (React.createElement(PriceDisplay, { priceRange: priceRange, currency: cfg.currency ?? product.currency, currencyPosition: cfg.currencyPosition, priceDecimals: cfg.priceDecimals, style: { fontSize: '0.875rem' } })) : (React.createElement(PriceDisplay, { price: price ?? undefined, comparePrice: comparePrice ?? undefined, currency: cfg.currency ?? product.currency, currencyPosition: cfg.currencyPosition, priceDecimals: cfg.priceDecimals, showDiscount: cfg.showDiscount, style: { fontSize: '0.875rem' } }))),
|
|
10153
10888
|
cfg.showVariants !== false && options.length > 0 && (React.createElement(VariantSwatches, { options: options, visibleOptions: cfg.variantOptionsToShow, maxValues: cfg.maxVariantValues, selectedValues: selectedVariants, variants: variants, onSwatchHover: onVariantHover, onSwatchClick: onVariantClick })),
|
|
@@ -10155,7 +10890,7 @@ function DetailedLayout({ images, title, price, comparePrice, brand, badges, pri
|
|
|
10155
10890
|
fontSize: '0.75rem',
|
|
10156
10891
|
color: available ? 'var(--seekora-success, #22c55e)' : 'var(--seekora-error, #ef4444)',
|
|
10157
10892
|
} }, available ? 'In Stock' : 'Out of Stock')),
|
|
10158
|
-
actionButtons && actionButtons.length > 0 &&
|
|
10893
|
+
actionButtons && actionButtons.length > 0 && !isOverlayPosition && (React.createElement(ActionButtons, { buttons: actionButtons, position: "inline", showLabels: showActionLabels, size: "small", layout: "horizontal" })))));
|
|
10159
10894
|
}
|
|
10160
10895
|
/** compact: smaller image, 1-line title, price */
|
|
10161
10896
|
function CompactLayout({ images, title, price, product, imageVariant, displayConfig, enableImageZoom, imageZoomMode, imageZoomLevel }) {
|
|
@@ -10176,13 +10911,13 @@ function CompactLayout({ images, title, price, product, imageVariant, displayCon
|
|
|
10176
10911
|
function HorizontalLayout({ images, title, price, comparePrice, brand, badges, options, variants, product, imageVariant, displayConfig, onVariantHover, onVariantClick, selectedVariants, actionButtons, actionButtonsPosition, showActionLabels, enableImageZoom, imageZoomMode, imageZoomLevel, }) {
|
|
10177
10912
|
const cfg = displayConfig;
|
|
10178
10913
|
return (React.createElement("div", { style: { display: 'flex', gap: 12, alignItems: 'flex-start' } },
|
|
10179
|
-
React.createElement("div", { style: { position: 'relative',
|
|
10914
|
+
React.createElement("div", { style: { position: 'relative', minWidth: 80, flexBasis: '25%', maxWidth: 120, flexShrink: 0 } },
|
|
10180
10915
|
React.createElement(ImageBlock, { images: images, title: title, imageVariant: imageVariant, aspectRatio: "1:1", enableZoom: enableImageZoom, zoomMode: imageZoomMode, zoomLevel: imageZoomLevel }),
|
|
10181
10916
|
cfg.showBadges !== false && badges.length > 0 && (React.createElement(BadgeList, { badges: badges, position: "top-left", maxBadges: 1 })),
|
|
10182
10917
|
actionButtons && actionButtons.length > 0 && actionButtonsPosition?.startsWith('overlay') && (React.createElement(ActionButtons, { buttons: actionButtons, position: actionButtonsPosition === 'overlay-top-right' ? 'top-right' : 'bottom-center', showLabels: showActionLabels, size: "small" }))),
|
|
10183
10918
|
React.createElement("div", { className: "seekora-product-card__body", style: { display: 'flex', flexDirection: 'column', gap: 4, flex: 1, minWidth: 0 } },
|
|
10184
10919
|
cfg.showBrand !== false && brand && (React.createElement("span", { className: "seekora-product-card__brand", style: { fontSize: '0.75rem', color: 'var(--seekora-text-secondary, #6b7280)', textTransform: 'uppercase' } }, brand)),
|
|
10185
|
-
React.createElement("span", { className: "seekora-product-card__title", style: { fontSize: '0.875rem', fontWeight: 500 } }, title),
|
|
10920
|
+
React.createElement("span", { className: "seekora-product-card__title", style: { fontSize: '0.875rem', fontWeight: 500, lineHeight: 1.4, overflow: 'hidden', textOverflow: 'ellipsis' } }, title),
|
|
10186
10921
|
React.createElement("div", { className: "seekora-product-card__price" },
|
|
10187
10922
|
React.createElement(PriceDisplay, { price: price ?? undefined, comparePrice: comparePrice ?? undefined, currency: cfg.currency ?? product.currency, currencyPosition: cfg.currencyPosition, priceDecimals: cfg.priceDecimals, showDiscount: cfg.showDiscount, style: { fontSize: '0.875rem' } })),
|
|
10188
10923
|
cfg.showVariants !== false && options.length > 0 && (React.createElement(VariantSwatches, { options: options, visibleOptions: cfg.variantOptionsToShow, maxValues: cfg.maxVariantValues ?? 3, selectedValues: selectedVariants, variants: variants, onSwatchHover: onVariantHover, onSwatchClick: onVariantClick })),
|
|
@@ -10195,6 +10930,11 @@ function HorizontalLayout({ images, title, price, comparePrice, brand, badges, o
|
|
|
10195
10930
|
* Without displayConfig: renders the original minimal layout (image, title, price).
|
|
10196
10931
|
* With displayConfig: renders layout variants (minimal, standard, detailed, compact, horizontal).
|
|
10197
10932
|
*/
|
|
10933
|
+
const TRANSITIONS = {
|
|
10934
|
+
fast: '150ms ease-in-out'};
|
|
10935
|
+
const BORDER_RADIUS = {
|
|
10936
|
+
sm: 4,
|
|
10937
|
+
md: 6};
|
|
10198
10938
|
const cardStyle = {
|
|
10199
10939
|
display: 'flex',
|
|
10200
10940
|
flexDirection: 'column',
|
|
@@ -10202,19 +10942,19 @@ const cardStyle = {
|
|
|
10202
10942
|
padding: 8,
|
|
10203
10943
|
cursor: 'pointer',
|
|
10204
10944
|
border: 'none',
|
|
10205
|
-
borderRadius:
|
|
10945
|
+
borderRadius: `var(--seekora-border-radius, ${BORDER_RADIUS.md}px)`,
|
|
10206
10946
|
backgroundColor: 'transparent',
|
|
10207
10947
|
textAlign: 'left',
|
|
10208
|
-
transition:
|
|
10948
|
+
transition: `background-color ${TRANSITIONS.fast}`,
|
|
10209
10949
|
};
|
|
10210
10950
|
const imgStyle = {
|
|
10211
10951
|
width: '100%',
|
|
10212
10952
|
aspectRatio: '1',
|
|
10213
10953
|
objectFit: 'cover',
|
|
10214
|
-
borderRadius:
|
|
10954
|
+
borderRadius: BORDER_RADIUS.sm,
|
|
10215
10955
|
backgroundColor: 'var(--seekora-bg-secondary, #f3f4f6)',
|
|
10216
10956
|
};
|
|
10217
|
-
function ProductCard({ product, position, section, tabId, onSelect, className, style, imageVariant = 'single', displayConfig, onVariantHover, onVariantClick, selectedVariants, asLink, actionButtons, actionButtonsPosition = '
|
|
10957
|
+
function ProductCard({ product, position, section, tabId, onSelect, className, style, imageVariant = 'single', displayConfig, onVariantHover, onVariantClick, selectedVariants, asLink, actionButtons, actionButtonsPosition = 'inline', showActionLabels = false, enableImageZoom = false, imageZoomMode = 'both', imageZoomLevel = 2.5, }) {
|
|
10218
10958
|
// Find selected variant if selections are provided
|
|
10219
10959
|
const selectedVariant = useMemo(() => {
|
|
10220
10960
|
if (!selectedVariants || !product.options || !product.variants)
|
|
@@ -10259,9 +10999,11 @@ function ProductCard({ product, position, section, tabId, onSelect, className, s
|
|
|
10259
10999
|
const price = effectivePrice;
|
|
10260
11000
|
// If no displayConfig, render original minimal layout (backwards compat)
|
|
10261
11001
|
if (!displayConfig) {
|
|
10262
|
-
return (React.createElement("
|
|
10263
|
-
e.
|
|
10264
|
-
|
|
11002
|
+
return (React.createElement("div", { role: "button", tabIndex: 0, className: clsx('seekora-suggestions-product-card', className), style: { ...cardStyle, ...style }, onClick: () => onSelect(), onKeyDown: (e) => {
|
|
11003
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
11004
|
+
e.preventDefault();
|
|
11005
|
+
onSelect();
|
|
11006
|
+
}
|
|
10265
11007
|
}, "data-position": position, "data-section": section, "data-tab-id": tabId },
|
|
10266
11008
|
images.length > 0 ? (React.createElement(ImageDisplay, { images: images, variant: imageVariant, alt: title, className: "seekora-suggestions-product-card-image", enableZoom: enableImageZoom, zoomMode: imageZoomMode, zoomLevel: imageZoomLevel })) : (React.createElement("div", { className: "seekora-suggestions-product-card-placeholder", style: imgStyle, "aria-hidden": true })),
|
|
10267
11009
|
React.createElement("span", { className: "seekora-suggestions-product-card-title", style: { fontSize: '0.875rem', fontWeight: 500 } }, title),
|
|
@@ -10331,9 +11073,11 @@ function ProductCard({ product, position, section, tabId, onSelect, className, s
|
|
|
10331
11073
|
}, "data-position": position, "data-section": section, "data-tab-id": tabId },
|
|
10332
11074
|
React.createElement(LayoutComponent, { ...layoutProps })));
|
|
10333
11075
|
}
|
|
10334
|
-
return (React.createElement("
|
|
10335
|
-
e.
|
|
10336
|
-
|
|
11076
|
+
return (React.createElement("div", { role: "button", tabIndex: 0, className: rootClassName, style: rootStyle, onClick: () => onSelect(), onKeyDown: (e) => {
|
|
11077
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
11078
|
+
e.preventDefault();
|
|
11079
|
+
onSelect();
|
|
11080
|
+
}
|
|
10337
11081
|
}, "data-position": position, "data-section": section, "data-tab-id": tabId },
|
|
10338
11082
|
React.createElement(LayoutComponent, { ...layoutProps })));
|
|
10339
11083
|
}
|
|
@@ -10609,10 +11353,10 @@ function VariantSelector({ options, variants, selections, onSelectionChange, opt
|
|
|
10609
11353
|
fontSize: '0.875rem',
|
|
10610
11354
|
fontWeight: 600,
|
|
10611
11355
|
marginBottom: 8,
|
|
10612
|
-
color: 'var(--seekora-text-primary,
|
|
11356
|
+
color: 'var(--seekora-text-primary, inherit)',
|
|
10613
11357
|
} },
|
|
10614
11358
|
option.name,
|
|
10615
|
-
selected && (React.createElement("span", { style: { fontWeight: 400, marginLeft: 6, color: 'var(--seekora-text-secondary,
|
|
11359
|
+
selected && (React.createElement("span", { style: { fontWeight: 400, marginLeft: 6, color: 'var(--seekora-text-secondary, inherit)' } }, selected))),
|
|
10616
11360
|
mode === 'dropdown' ? (React.createElement("select", { className: "seekora-variant-dropdown", value: selected ?? '', onChange: (e) => {
|
|
10617
11361
|
e.stopPropagation();
|
|
10618
11362
|
onSelectionChange(option.name, e.target.value);
|
|
@@ -10620,9 +11364,9 @@ function VariantSelector({ options, variants, selections, onSelectionChange, opt
|
|
|
10620
11364
|
padding: '8px 12px',
|
|
10621
11365
|
fontSize: '0.875rem',
|
|
10622
11366
|
borderRadius: 6,
|
|
10623
|
-
border: '1px solid var(--seekora-border-color,
|
|
10624
|
-
backgroundColor: 'var(--seekora-bg-surface,
|
|
10625
|
-
color: 'var(--seekora-text-primary,
|
|
11367
|
+
border: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
|
|
11368
|
+
backgroundColor: 'var(--seekora-bg-surface, transparent)',
|
|
11369
|
+
color: 'var(--seekora-text-primary, inherit)',
|
|
10626
11370
|
cursor: 'pointer',
|
|
10627
11371
|
minWidth: 120,
|
|
10628
11372
|
} },
|
|
@@ -10656,7 +11400,7 @@ function VariantSelector({ options, variants, selections, onSelectionChange, opt
|
|
|
10656
11400
|
backgroundColor: color,
|
|
10657
11401
|
border: isActive
|
|
10658
11402
|
? '2px solid var(--seekora-primary, #111827)'
|
|
10659
|
-
: '1px solid var(--seekora-border-color,
|
|
11403
|
+
: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
|
|
10660
11404
|
outline: isActive ? '2px solid var(--seekora-primary, #111827)' : 'none',
|
|
10661
11405
|
outlineOffset: 2,
|
|
10662
11406
|
cursor: available ? 'pointer' : 'not-allowed',
|
|
@@ -10677,13 +11421,13 @@ function VariantSelector({ options, variants, selections, onSelectionChange, opt
|
|
|
10677
11421
|
borderRadius: 6,
|
|
10678
11422
|
border: isActive
|
|
10679
11423
|
? '2px solid var(--seekora-primary, #111827)'
|
|
10680
|
-
: '1px solid var(--seekora-border-color,
|
|
11424
|
+
: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
|
|
10681
11425
|
backgroundColor: isActive
|
|
10682
11426
|
? 'var(--seekora-primary, #111827)'
|
|
10683
|
-
: 'var(--seekora-bg-surface,
|
|
11427
|
+
: 'var(--seekora-bg-surface, transparent)',
|
|
10684
11428
|
color: isActive
|
|
10685
|
-
? '
|
|
10686
|
-
: 'var(--seekora-text-primary,
|
|
11429
|
+
? 'transparent'
|
|
11430
|
+
: 'var(--seekora-text-primary, inherit)',
|
|
10687
11431
|
cursor: available ? 'pointer' : 'not-allowed',
|
|
10688
11432
|
opacity: available ? 1 : 0.5,
|
|
10689
11433
|
textDecoration: !available ? 'line-through' : 'none',
|
|
@@ -10902,7 +11646,7 @@ function extractTotal(response) {
|
|
|
10902
11646
|
return Number(data.data.total_results);
|
|
10903
11647
|
return 0;
|
|
10904
11648
|
}
|
|
10905
|
-
function SectionSearchProvider({ children, query, refinements = [], maxItems = 12, sortBy, enabled = true, sectionId, }) {
|
|
11649
|
+
function SectionSearchProvider({ children, query, refinements = [], maxItems = 12, sortBy, enabled = true, sectionId, searchOptions, }) {
|
|
10906
11650
|
const { client } = useSearchContext();
|
|
10907
11651
|
const [items, setItems] = useState([]);
|
|
10908
11652
|
const [loading, setLoading] = useState(true);
|
|
@@ -10920,6 +11664,7 @@ function SectionSearchProvider({ children, query, refinements = [], maxItems = 1
|
|
|
10920
11664
|
setLoading(true);
|
|
10921
11665
|
setError(null);
|
|
10922
11666
|
const options = {
|
|
11667
|
+
...searchOptions,
|
|
10923
11668
|
per_page: maxItems,
|
|
10924
11669
|
page: 1,
|
|
10925
11670
|
};
|
|
@@ -10947,7 +11692,7 @@ function SectionSearchProvider({ children, query, refinements = [], maxItems = 1
|
|
|
10947
11692
|
return () => {
|
|
10948
11693
|
cancelled = true;
|
|
10949
11694
|
};
|
|
10950
|
-
}, [client, enabled, query, maxItems, sortBy, refinements]);
|
|
11695
|
+
}, [client, enabled, query, maxItems, sortBy, refinements, searchOptions]);
|
|
10951
11696
|
const trackClick = useCallback((item, position) => {
|
|
10952
11697
|
if (!client?.trackEvent)
|
|
10953
11698
|
return;
|
|
@@ -11012,9 +11757,9 @@ function SectionItemGrid({ columns = 4, maxItems = 12, className, style, showLoa
|
|
|
11012
11757
|
* Uses ImageDisplay with configurable variant (carousel, thumbStrip, etc.).
|
|
11013
11758
|
* For use on individual product page.
|
|
11014
11759
|
*/
|
|
11015
|
-
function ProductGallery({ images, variant = 'thumbStrip', alt = 'Product', className, style, carouselAutoplay, carouselIntervalMs, }) {
|
|
11760
|
+
function ProductGallery({ images, variant = 'thumbStrip', alt = 'Product', className, style, carouselAutoplay, carouselIntervalMs, enableZoom, zoomMode, zoomLevel, }) {
|
|
11016
11761
|
return (React.createElement("div", { className: clsx('seekora-product-gallery', className), style: style },
|
|
11017
|
-
React.createElement(ImageDisplay, { images: images, variant: variant, alt: alt, carouselAutoplay: carouselAutoplay, carouselIntervalMs: carouselIntervalMs })));
|
|
11762
|
+
React.createElement(ImageDisplay, { images: images, variant: variant, alt: alt, carouselAutoplay: carouselAutoplay, carouselIntervalMs: carouselIntervalMs, enableZoom: enableZoom, zoomMode: zoomMode, zoomLevel: zoomLevel })));
|
|
11018
11763
|
}
|
|
11019
11764
|
|
|
11020
11765
|
/**
|
|
@@ -13318,8 +14063,8 @@ const createStyles$3 = (isMobile = false) => ({
|
|
|
13318
14063
|
right: 0,
|
|
13319
14064
|
bottom: isMobile ? 0 : 'auto',
|
|
13320
14065
|
marginTop: isMobile ? 0 : '8px',
|
|
13321
|
-
backgroundColor: 'var(--seekora-bg-surface,
|
|
13322
|
-
color: 'var(--seekora-text-primary,
|
|
14066
|
+
backgroundColor: 'var(--seekora-bg-surface, transparent)',
|
|
14067
|
+
color: 'var(--seekora-text-primary, inherit)',
|
|
13323
14068
|
borderRadius: isMobile ? 0 : '16px',
|
|
13324
14069
|
boxShadow: isMobile ? 'none' : '0 4px 30px rgba(0, 0, 0, 0.12)',
|
|
13325
14070
|
overflow: 'hidden',
|
|
@@ -13337,14 +14082,14 @@ const createStyles$3 = (isMobile = false) => ({
|
|
|
13337
14082
|
overflowY: 'auto',
|
|
13338
14083
|
},
|
|
13339
14084
|
leftPanel: {
|
|
13340
|
-
backgroundColor: 'var(--seekora-bg-surface,
|
|
13341
|
-
borderRight: isMobile ? 'none' : '1px solid var(--seekora-border-color,
|
|
13342
|
-
borderBottom: isMobile ? '1px solid var(--seekora-border-color,
|
|
14085
|
+
backgroundColor: 'var(--seekora-bg-surface, transparent)',
|
|
14086
|
+
borderRight: isMobile ? 'none' : '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
|
|
14087
|
+
borderBottom: isMobile ? '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))' : 'none',
|
|
13343
14088
|
display: 'flex',
|
|
13344
14089
|
flexDirection: 'column',
|
|
13345
14090
|
},
|
|
13346
14091
|
rightPanel: {
|
|
13347
|
-
backgroundColor: 'var(--seekora-bg-secondary,
|
|
14092
|
+
backgroundColor: 'var(--seekora-bg-secondary, rgba(255, 255, 255, 0.1))',
|
|
13348
14093
|
padding: isMobile ? '16px' : '24px',
|
|
13349
14094
|
display: 'flex',
|
|
13350
14095
|
flexDirection: 'column',
|
|
@@ -13359,7 +14104,7 @@ const createStyles$3 = (isMobile = false) => ({
|
|
|
13359
14104
|
display: 'flex',
|
|
13360
14105
|
alignItems: 'center',
|
|
13361
14106
|
justifyContent: 'space-between',
|
|
13362
|
-
borderBottom: '1px solid var(--seekora-border-color,
|
|
14107
|
+
borderBottom: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
|
|
13363
14108
|
},
|
|
13364
14109
|
sectionTitle: {
|
|
13365
14110
|
fontSize: '11px',
|
|
@@ -13370,7 +14115,7 @@ const createStyles$3 = (isMobile = false) => ({
|
|
|
13370
14115
|
},
|
|
13371
14116
|
viewAllLink: {
|
|
13372
14117
|
fontSize: '12px',
|
|
13373
|
-
color: 'var(--seekora-text-primary,
|
|
14118
|
+
color: 'var(--seekora-text-primary, inherit)',
|
|
13374
14119
|
textDecoration: 'underline',
|
|
13375
14120
|
cursor: 'pointer',
|
|
13376
14121
|
},
|
|
@@ -13384,11 +14129,11 @@ const createStyles$3 = (isMobile = false) => ({
|
|
|
13384
14129
|
minHeight: '48px',
|
|
13385
14130
|
margin: '4px 8px',
|
|
13386
14131
|
borderRadius: '10px',
|
|
13387
|
-
color: 'var(--seekora-text-primary,
|
|
14132
|
+
color: 'var(--seekora-text-primary, inherit)',
|
|
13388
14133
|
},
|
|
13389
14134
|
suggestionItemActive: {
|
|
13390
|
-
backgroundColor: 'var(--seekora-bg-hover,
|
|
13391
|
-
color: 'var(--seekora-text-primary,
|
|
14135
|
+
backgroundColor: 'var(--seekora-bg-hover, rgba(255, 255, 255, 0.1))',
|
|
14136
|
+
color: 'var(--seekora-text-primary, inherit)',
|
|
13392
14137
|
},
|
|
13393
14138
|
suggestionIcon: {
|
|
13394
14139
|
display: 'flex',
|
|
@@ -13403,12 +14148,12 @@ const createStyles$3 = (isMobile = false) => ({
|
|
|
13403
14148
|
},
|
|
13404
14149
|
suggestionQuery: {
|
|
13405
14150
|
fontSize: '14px',
|
|
13406
|
-
color: 'var(--seekora-text-primary,
|
|
14151
|
+
color: 'var(--seekora-text-primary, inherit)',
|
|
13407
14152
|
fontWeight: 400,
|
|
13408
14153
|
},
|
|
13409
14154
|
suggestionMeta: {
|
|
13410
14155
|
fontSize: '12px',
|
|
13411
|
-
color: 'var(--seekora-text-secondary,
|
|
14156
|
+
color: 'var(--seekora-text-secondary, inherit)',
|
|
13412
14157
|
marginTop: '2px',
|
|
13413
14158
|
},
|
|
13414
14159
|
suggestionArrow: {
|
|
@@ -13426,29 +14171,29 @@ const createStyles$3 = (isMobile = false) => ({
|
|
|
13426
14171
|
display: 'grid',
|
|
13427
14172
|
gridTemplateColumns: 'repeat(2, 1fr)',
|
|
13428
14173
|
gap: '1px',
|
|
13429
|
-
backgroundColor: 'var(--seekora-border-color,
|
|
13430
|
-
borderTop: '1px solid var(--seekora-border-color,
|
|
14174
|
+
backgroundColor: 'var(--seekora-border-color, rgba(128,128,128,0.2))',
|
|
14175
|
+
borderTop: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
|
|
13431
14176
|
},
|
|
13432
14177
|
collectionItem: {
|
|
13433
|
-
backgroundColor: 'var(--seekora-bg-surface,
|
|
13434
|
-
color: 'var(--seekora-text-primary,
|
|
14178
|
+
backgroundColor: 'var(--seekora-bg-surface, transparent)',
|
|
14179
|
+
color: 'var(--seekora-text-primary, inherit)',
|
|
13435
14180
|
padding: '16px 20px',
|
|
13436
14181
|
cursor: 'pointer',
|
|
13437
14182
|
transition: 'background-color 150ms',
|
|
13438
14183
|
},
|
|
13439
14184
|
collectionItemHover: {
|
|
13440
|
-
backgroundColor: 'var(--seekora-bg-hover,
|
|
13441
|
-
color: 'var(--seekora-text-primary,
|
|
14185
|
+
backgroundColor: 'var(--seekora-bg-hover, rgba(255, 255, 255, 0.1))',
|
|
14186
|
+
color: 'var(--seekora-text-primary, inherit)',
|
|
13442
14187
|
},
|
|
13443
14188
|
collectionName: {
|
|
13444
14189
|
fontSize: '13px',
|
|
13445
14190
|
fontWeight: 500,
|
|
13446
|
-
color: 'var(--seekora-text-primary,
|
|
14191
|
+
color: 'var(--seekora-text-primary, inherit)',
|
|
13447
14192
|
marginBottom: '4px',
|
|
13448
14193
|
},
|
|
13449
14194
|
collectionCount: {
|
|
13450
14195
|
fontSize: '11px',
|
|
13451
|
-
color: 'var(--seekora-text-secondary,
|
|
14196
|
+
color: 'var(--seekora-text-secondary, inherit)',
|
|
13452
14197
|
},
|
|
13453
14198
|
heroProduct: {
|
|
13454
14199
|
marginBottom: '24px',
|
|
@@ -13464,13 +14209,13 @@ const createStyles$3 = (isMobile = false) => ({
|
|
|
13464
14209
|
heroTitle: {
|
|
13465
14210
|
fontSize: '16px',
|
|
13466
14211
|
fontWeight: 500,
|
|
13467
|
-
color: 'var(--seekora-text-primary,
|
|
14212
|
+
color: 'var(--seekora-text-primary, inherit)',
|
|
13468
14213
|
marginBottom: '8px',
|
|
13469
14214
|
lineHeight: 1.3,
|
|
13470
14215
|
},
|
|
13471
14216
|
heroBrand: {
|
|
13472
14217
|
fontSize: '12px',
|
|
13473
|
-
color: 'var(--seekora-text-secondary,
|
|
14218
|
+
color: 'var(--seekora-text-secondary, inherit)',
|
|
13474
14219
|
marginBottom: '12px',
|
|
13475
14220
|
textTransform: 'uppercase',
|
|
13476
14221
|
letterSpacing: '0.05em',
|
|
@@ -13484,7 +14229,7 @@ const createStyles$3 = (isMobile = false) => ({
|
|
|
13484
14229
|
heroPrice: {
|
|
13485
14230
|
fontSize: '18px',
|
|
13486
14231
|
fontWeight: 500,
|
|
13487
|
-
color: 'var(--seekora-text-primary,
|
|
14232
|
+
color: 'var(--seekora-text-primary, inherit)',
|
|
13488
14233
|
},
|
|
13489
14234
|
heroComparePrice: {
|
|
13490
14235
|
fontSize: '14px',
|
|
@@ -13502,8 +14247,8 @@ const createStyles$3 = (isMobile = false) => ({
|
|
|
13502
14247
|
heroButton: {
|
|
13503
14248
|
width: '100%',
|
|
13504
14249
|
padding: '14px 20px',
|
|
13505
|
-
backgroundColor: 'var(--seekora-text-primary,
|
|
13506
|
-
color: 'var(--seekora-bg-surface,
|
|
14250
|
+
backgroundColor: 'var(--seekora-text-primary, inherit)',
|
|
14251
|
+
color: 'var(--seekora-bg-surface, transparent)',
|
|
13507
14252
|
border: 'none',
|
|
13508
14253
|
borderRadius: '2px',
|
|
13509
14254
|
fontSize: '13px',
|
|
@@ -13514,8 +14259,8 @@ const createStyles$3 = (isMobile = false) => ({
|
|
|
13514
14259
|
transition: 'background-color 150ms',
|
|
13515
14260
|
},
|
|
13516
14261
|
heroButtonHover: {
|
|
13517
|
-
backgroundColor: 'var(--seekora-text-secondary,
|
|
13518
|
-
color: 'var(--seekora-bg-surface,
|
|
14262
|
+
backgroundColor: 'var(--seekora-text-secondary, inherit)',
|
|
14263
|
+
color: 'var(--seekora-bg-surface, transparent)',
|
|
13519
14264
|
},
|
|
13520
14265
|
productsScroll: {
|
|
13521
14266
|
flex: 1,
|
|
@@ -13543,7 +14288,7 @@ const createStyles$3 = (isMobile = false) => ({
|
|
|
13543
14288
|
},
|
|
13544
14289
|
productTitle: {
|
|
13545
14290
|
fontSize: '12px',
|
|
13546
|
-
color: 'var(--seekora-text-primary,
|
|
14291
|
+
color: 'var(--seekora-text-primary, inherit)',
|
|
13547
14292
|
marginBottom: '4px',
|
|
13548
14293
|
whiteSpace: 'nowrap',
|
|
13549
14294
|
overflow: 'hidden',
|
|
@@ -13552,20 +14297,20 @@ const createStyles$3 = (isMobile = false) => ({
|
|
|
13552
14297
|
productPrice: {
|
|
13553
14298
|
fontSize: '12px',
|
|
13554
14299
|
fontWeight: 500,
|
|
13555
|
-
color: 'var(--seekora-text-primary,
|
|
14300
|
+
color: 'var(--seekora-text-primary, inherit)',
|
|
13556
14301
|
},
|
|
13557
14302
|
footer: {
|
|
13558
14303
|
padding: '12px 20px',
|
|
13559
|
-
borderTop: '1px solid var(--seekora-border-color,
|
|
13560
|
-
backgroundColor: 'var(--seekora-bg-secondary,
|
|
14304
|
+
borderTop: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
|
|
14305
|
+
backgroundColor: 'var(--seekora-bg-secondary, rgba(255, 255, 255, 0.1))',
|
|
13561
14306
|
display: 'flex',
|
|
13562
14307
|
alignItems: 'center',
|
|
13563
14308
|
justifyContent: 'space-between',
|
|
13564
14309
|
fontSize: '11px',
|
|
13565
|
-
color: 'var(--seekora-text-secondary,
|
|
14310
|
+
color: 'var(--seekora-text-secondary, inherit)',
|
|
13566
14311
|
},
|
|
13567
14312
|
footerLink: {
|
|
13568
|
-
color: 'var(--seekora-text-primary,
|
|
14313
|
+
color: 'var(--seekora-text-primary, inherit)',
|
|
13569
14314
|
textDecoration: 'underline',
|
|
13570
14315
|
cursor: 'pointer',
|
|
13571
14316
|
},
|
|
@@ -13574,13 +14319,13 @@ const createStyles$3 = (isMobile = false) => ({
|
|
|
13574
14319
|
alignItems: 'center',
|
|
13575
14320
|
justifyContent: 'center',
|
|
13576
14321
|
padding: '60px',
|
|
13577
|
-
color: 'var(--seekora-text-secondary,
|
|
14322
|
+
color: 'var(--seekora-text-secondary, inherit)',
|
|
13578
14323
|
},
|
|
13579
14324
|
spinner: {
|
|
13580
14325
|
width: '24px',
|
|
13581
14326
|
height: '24px',
|
|
13582
|
-
border: '2px solid var(--seekora-border-color,
|
|
13583
|
-
borderTopColor: 'var(--seekora-text-primary,
|
|
14327
|
+
border: '2px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
|
|
14328
|
+
borderTopColor: 'var(--seekora-text-primary, inherit)',
|
|
13584
14329
|
borderRadius: '50%',
|
|
13585
14330
|
animation: 'seekora-spin 0.8s linear infinite',
|
|
13586
14331
|
},
|
|
@@ -13771,7 +14516,7 @@ const createStyles$2 = () => ({
|
|
|
13771
14516
|
left: 0,
|
|
13772
14517
|
right: 0,
|
|
13773
14518
|
bottom: 0,
|
|
13774
|
-
backgroundColor: 'var(--seekora-bg-surface,
|
|
14519
|
+
backgroundColor: 'var(--seekora-bg-surface, transparent)',
|
|
13775
14520
|
borderRadius: '16px 16px 0 0',
|
|
13776
14521
|
boxShadow: '0 -4px 20px rgba(0, 0, 0, 0.15)',
|
|
13777
14522
|
fontFamily: 'var(--seekora-font-family, -apple-system, BlinkMacSystemFont, "SF Pro Text", sans-serif)',
|
|
@@ -13795,17 +14540,17 @@ const createStyles$2 = () => ({
|
|
|
13795
14540
|
dragBar: {
|
|
13796
14541
|
width: '36px',
|
|
13797
14542
|
height: '5px',
|
|
13798
|
-
backgroundColor: 'var(--seekora-border-color,
|
|
14543
|
+
backgroundColor: 'var(--seekora-border-color, rgba(128,128,128,0.2))',
|
|
13799
14544
|
borderRadius: '3px',
|
|
13800
14545
|
},
|
|
13801
14546
|
header: {
|
|
13802
14547
|
padding: '0 16px 16px',
|
|
13803
|
-
borderBottom: '1px solid var(--seekora-border-color,
|
|
14548
|
+
borderBottom: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
|
|
13804
14549
|
},
|
|
13805
14550
|
searchContainer: {
|
|
13806
14551
|
display: 'flex',
|
|
13807
14552
|
alignItems: 'center',
|
|
13808
|
-
backgroundColor: 'var(--seekora-bg-secondary,
|
|
14553
|
+
backgroundColor: 'var(--seekora-bg-secondary, rgba(255, 255, 255, 0.1))',
|
|
13809
14554
|
borderRadius: '12px',
|
|
13810
14555
|
padding: '12px 16px',
|
|
13811
14556
|
gap: '12px',
|
|
@@ -13821,7 +14566,7 @@ const createStyles$2 = () => ({
|
|
|
13821
14566
|
border: 'none',
|
|
13822
14567
|
background: 'transparent',
|
|
13823
14568
|
fontSize: '17px',
|
|
13824
|
-
color: 'var(--seekora-text-primary,
|
|
14569
|
+
color: 'var(--seekora-text-primary, inherit)',
|
|
13825
14570
|
outline: 'none',
|
|
13826
14571
|
},
|
|
13827
14572
|
cancelBtn: {
|
|
@@ -13869,11 +14614,11 @@ const createStyles$2 = () => ({
|
|
|
13869
14614
|
cursor: 'pointer',
|
|
13870
14615
|
transition: 'background-color 100ms',
|
|
13871
14616
|
minHeight: '56px', // Touch-friendly
|
|
13872
|
-
color: 'var(--seekora-text-primary,
|
|
14617
|
+
color: 'var(--seekora-text-primary, inherit)',
|
|
13873
14618
|
},
|
|
13874
14619
|
itemActive: {
|
|
13875
|
-
backgroundColor: 'var(--seekora-bg-hover,
|
|
13876
|
-
color: 'var(--seekora-text-primary,
|
|
14620
|
+
backgroundColor: 'var(--seekora-bg-hover, rgba(255, 255, 255, 0.1))',
|
|
14621
|
+
color: 'var(--seekora-text-primary, inherit)',
|
|
13877
14622
|
},
|
|
13878
14623
|
itemIcon: {
|
|
13879
14624
|
width: '24px',
|
|
@@ -13895,14 +14640,14 @@ const createStyles$2 = () => ({
|
|
|
13895
14640
|
},
|
|
13896
14641
|
itemTitle: {
|
|
13897
14642
|
fontSize: '17px',
|
|
13898
|
-
color: 'var(--seekora-text-primary,
|
|
14643
|
+
color: 'var(--seekora-text-primary, inherit)',
|
|
13899
14644
|
whiteSpace: 'nowrap',
|
|
13900
14645
|
overflow: 'hidden',
|
|
13901
14646
|
textOverflow: 'ellipsis',
|
|
13902
14647
|
},
|
|
13903
14648
|
itemSubtitle: {
|
|
13904
14649
|
fontSize: '15px',
|
|
13905
|
-
color: 'var(--seekora-text-secondary,
|
|
14650
|
+
color: 'var(--seekora-text-secondary, inherit)',
|
|
13906
14651
|
marginTop: '2px',
|
|
13907
14652
|
whiteSpace: 'nowrap',
|
|
13908
14653
|
overflow: 'hidden',
|
|
@@ -13935,7 +14680,7 @@ const createStyles$2 = () => ({
|
|
|
13935
14680
|
},
|
|
13936
14681
|
productTitle: {
|
|
13937
14682
|
fontSize: '15px',
|
|
13938
|
-
color: 'var(--seekora-text-primary,
|
|
14683
|
+
color: 'var(--seekora-text-primary, inherit)',
|
|
13939
14684
|
marginBottom: '4px',
|
|
13940
14685
|
whiteSpace: 'nowrap',
|
|
13941
14686
|
overflow: 'hidden',
|
|
@@ -13944,19 +14689,19 @@ const createStyles$2 = () => ({
|
|
|
13944
14689
|
productPrice: {
|
|
13945
14690
|
fontSize: '15px',
|
|
13946
14691
|
fontWeight: 600,
|
|
13947
|
-
color: 'var(--seekora-text-primary,
|
|
14692
|
+
color: 'var(--seekora-text-primary, inherit)',
|
|
13948
14693
|
},
|
|
13949
14694
|
footer: {
|
|
13950
14695
|
padding: '12px 16px',
|
|
13951
14696
|
paddingBottom: 'calc(12px + env(safe-area-inset-bottom, 0px))',
|
|
13952
|
-
borderTop: '1px solid var(--seekora-border-color,
|
|
13953
|
-
backgroundColor: 'var(--seekora-bg-secondary,
|
|
14697
|
+
borderTop: '1px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
|
|
14698
|
+
backgroundColor: 'var(--seekora-bg-secondary, rgba(255, 255, 255, 0.1))',
|
|
13954
14699
|
},
|
|
13955
14700
|
footerBtn: {
|
|
13956
14701
|
width: '100%',
|
|
13957
14702
|
padding: '16px',
|
|
13958
14703
|
backgroundColor: 'var(--seekora-primary, #007aff)',
|
|
13959
|
-
color: 'var(--seekora-text-inverse,
|
|
14704
|
+
color: 'var(--seekora-text-inverse, transparent)',
|
|
13960
14705
|
border: 'none',
|
|
13961
14706
|
borderRadius: '12px',
|
|
13962
14707
|
fontSize: '17px',
|
|
@@ -13968,12 +14713,12 @@ const createStyles$2 = () => ({
|
|
|
13968
14713
|
alignItems: 'center',
|
|
13969
14714
|
justifyContent: 'center',
|
|
13970
14715
|
padding: '60px',
|
|
13971
|
-
color: 'var(--seekora-text-secondary,
|
|
14716
|
+
color: 'var(--seekora-text-secondary, inherit)',
|
|
13972
14717
|
},
|
|
13973
14718
|
spinner: {
|
|
13974
14719
|
width: '28px',
|
|
13975
14720
|
height: '28px',
|
|
13976
|
-
border: '3px solid var(--seekora-border-color,
|
|
14721
|
+
border: '3px solid var(--seekora-border-color, rgba(128,128,128,0.2))',
|
|
13977
14722
|
borderTopColor: 'var(--seekora-primary, #007aff)',
|
|
13978
14723
|
borderRadius: '50%',
|
|
13979
14724
|
animation: 'seekora-spin 0.8s linear infinite',
|
|
@@ -13981,7 +14726,7 @@ const createStyles$2 = () => ({
|
|
|
13981
14726
|
empty: {
|
|
13982
14727
|
padding: '60px 20px',
|
|
13983
14728
|
textAlign: 'center',
|
|
13984
|
-
color: 'var(--seekora-text-secondary,
|
|
14729
|
+
color: 'var(--seekora-text-secondary, inherit)',
|
|
13985
14730
|
fontSize: '17px',
|
|
13986
14731
|
},
|
|
13987
14732
|
emptyIcon: {
|
|
@@ -17435,5 +18180,5 @@ function updateSuggestionsStyles(theme) {
|
|
|
17435
18180
|
injectSuggestionsStyles(theme, true);
|
|
17436
18181
|
}
|
|
17437
18182
|
|
|
17438
|
-
export { ActionButtons, AmazonDropdown, AnalyticsProvider, BadgeList, Breadcrumb, CategoriesTabs, ClearRefinements, CurrentRefinements, DocSearch, DocSearchButton, DropdownPanel, Facets, FederatedDropdown, Fingerprint, FrequentlyBoughtTogether, GoogleDropdown, HierarchicalMenu, Highlight$1 as Highlight, HitsPerPage, ImageDisplay, ImageZoom, InfiniteHits, ItemCard, ItemGrid, MinimalDropdown, MobileFilters, MobileFiltersButton, MobileSheetDropdown, Pagination, PinterestDropdown, PriceDisplay, ProductCard, ProductGallery, ProductGrid, ProductInfo, ProductRecommendations, QuerySuggestions, QuerySuggestionsDropdown, RangeInput, RangeSlider, RatingDisplay, RecentSearchesList, RecentlyViewed, RelatedProducts, RichQuerySuggestions, SearchBar, SearchBarWithSuggestions, SearchInput, SearchLayout, SearchProvider, SearchResults, SectionError, SectionItemGrid, SectionLoading, SectionSearchProvider, ShopifyDropdown, Snippet, SortBy, SpotlightDropdown, Stats, SuggestionDropdownVariants, SuggestionItem, SuggestionList, SuggestionSearchBar, SuggestionsDropdownComposition, SuggestionsError, SuggestionsLoading, SuggestionsProvider, TrendingItems, TrendingList, VariantSelector, VariantSwatches, addRecentSearch, addToRecentlyViewed, brandPresets, breakpoints, clearRecentSearches, clearSuggestionsCache, createSuggestionsCache, createSuggestionsTheme, createTheme, darkTheme, darkThemeVariables, defaultTheme, extractBadges, extractBrand, extractCategory, extractProduct, extractSuggestion, findVariantBySelections, formatParsedFilters, formatPriceRange, formatPrice as formatSuggestionPrice, generateSuggestionsStylesheet, getAvailableValuesForOption, getFingerprint, getPriceRange, getRecentSearches, getShortcutText, getSuggestionsCache, highlightText, injectGlobalResponsiveStyles, injectSuggestionsStyles, lightThemeVariables, mediaQueries, mergeThemes, minimalTheme, minimalThemeVariables, parseHighlightMarkup, removeRecentSearch, touchTargets, updateSuggestionsStyles, useAnalytics, useAnalyticsProvider, useDocSearch, useSeekoraSearch$1 as useDocSearchSeekoraSearch, useInjectResponsiveStyles, useKeyboard, useNaturalLanguageFilters, useProductAnalytics, useQuerySuggestions, useQuerySuggestionsEnhanced, useResponsive, useSearchContext, useSearchState, useSectionSearchContext, useSeekoraSearch, useSmartSuggestions, useSuggestionsAnalytics, useSuggestionsContext, useVariantSelection, withAnalytics };
|
|
18183
|
+
export { ActionButtons, AmazonDropdown, AnalyticsProvider, BadgeList, Breadcrumb, CategoriesTabs, ClearRefinements, CurrentRefinements, DocSearch, DocSearchButton, DropdownPanel, FacetDropdown, Facets, FederatedDropdown, Fingerprint, FrequentlyBoughtTogether, GoogleDropdown, HierarchicalMenu, Highlight$1 as Highlight, HitsPerPage, ImageDisplay, ImageZoom, InfiniteHits, ItemCard, ItemGrid, MinimalDropdown, MobileFilters, MobileFiltersButton, MobileSheetDropdown, Pagination, PinterestDropdown, PriceDisplay, ProductCard, ProductGallery, ProductGrid, ProductInfo, ProductRecommendations, QuerySuggestions, QuerySuggestionsDropdown, RangeInput, RangeSlider, RatingDisplay, RecentSearchesList, RecentlyViewed, RelatedProducts, RichQuerySuggestions, SearchBar, SearchBarWithSuggestions, SearchInput, SearchLayout, SearchProvider, SearchResults, SectionError, SectionItemGrid, SectionLoading, SectionSearchProvider, ShopifyDropdown, Snippet, SortBy, SpotlightDropdown, Stats, SuggestionDropdownVariants, SuggestionItem, SuggestionList, SuggestionSearchBar, SuggestionsDropdownComposition, SuggestionsError, SuggestionsLoading, SuggestionsProvider, TrendingItems, TrendingList, VariantSelector, VariantSwatches, addRecentSearch, addToRecentlyViewed, brandPresets, breakpoints, clearRecentSearches, clearSuggestionsCache, createSuggestionsCache, createSuggestionsTheme, createTheme, darkTheme, darkThemeVariables, defaultTheme, extractBadges, extractBrand, extractCategory, extractProduct, extractSuggestion, findVariantBySelections, formatParsedFilters, formatPriceRange, formatPrice as formatSuggestionPrice, generateSuggestionsStylesheet, getAvailableValuesForOption, getFingerprint, getPriceRange, getRecentSearches, getShortcutText, getSuggestionsCache, highlightText, injectGlobalResponsiveStyles, injectSuggestionsStyles, lightThemeVariables, mediaQueries, mergeThemes, minimalTheme, minimalThemeVariables, parseHighlightMarkup, removeRecentSearch, touchTargets, updateSuggestionsStyles, useAnalytics, useAnalyticsProvider, useDocSearch, useSeekoraSearch$1 as useDocSearchSeekoraSearch, useInjectResponsiveStyles, useKeyboard, useNaturalLanguageFilters, useProductAnalytics, useQuerySuggestions, useQuerySuggestionsEnhanced, useResponsive, useSearchContext, useSearchState, useSectionSearchContext, useSeekoraSearch, useSmartSuggestions, useSuggestionsAnalytics, useSuggestionsContext, useVariantSelection, withAnalytics };
|
|
17439
18184
|
//# sourceMappingURL=index.esm.js.map
|