@seekora-ai/ui-sdk-react 0.2.18 → 0.2.20

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/src/index.js CHANGED
@@ -1687,7 +1687,7 @@ const DefaultSearchIcon = ({ size = 18 }) => (React.createElement("svg", { width
1687
1687
  const DefaultClearIcon = ({ size = 14 }) => (React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" },
1688
1688
  React.createElement("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1689
1689
  React.createElement("line", { x1: "6", y1: "6", x2: "18", y2: "18" })));
1690
- const SearchBar = ({ placeholder = 'Powered by Seekora', showSuggestions = true, debounceMs = 300, minQueryLength = 2, maxSuggestions = 10, onSearch, onQueryChange, onSuggestionSelect, onSearchStateChange, searchOptions, className, style, theme: customTheme, renderSuggestion, renderSearchIcon, showClearButton = true, renderClearIcon, showSubmitButton = false, renderSubmitButton, size = 'medium', }) => {
1690
+ const SearchBar = ({ placeholder = 'Powered by Seekora', showSuggestions = true, debounceMs = 300, minQueryLength = 2, maxSuggestions = 10, onSearch, onQueryChange, onSuggestionSelect, onSearchStateChange, searchOptions, className, style, theme: customTheme, renderSuggestion, renderSearchIcon, showClearButton = true, renderClearIcon, showSubmitButton = false, renderSubmitButton, size = 'medium', searchAsYouType = false, }) => {
1691
1691
  const { client, theme, enableAnalytics, autoTrackSearch } = useSearchContext();
1692
1692
  const { query, setQuery, search: triggerSearch, results, loading: searchLoading, error: searchError } = useSearchState();
1693
1693
  const [isFocused, setIsFocused] = React.useState(false);
@@ -1695,6 +1695,14 @@ const SearchBar = ({ placeholder = 'Powered by Seekora', showSuggestions = true,
1695
1695
  const inputRef = React.useRef(null);
1696
1696
  const containerRef = React.useRef(null);
1697
1697
  const isSearchingRef = React.useRef(false); // Flag to prevent blur handler from interfering
1698
+ const searchAsYouTypeRef = React.useRef(null);
1699
+ // Cleanup searchAsYouType timer on unmount
1700
+ React.useEffect(() => {
1701
+ return () => {
1702
+ if (searchAsYouTypeRef.current)
1703
+ clearTimeout(searchAsYouTypeRef.current);
1704
+ };
1705
+ }, []);
1698
1706
  const { suggestions, loading: suggestionsLoading } = useQuerySuggestions({
1699
1707
  client,
1700
1708
  query,
@@ -1724,6 +1732,11 @@ const SearchBar = ({ placeholder = 'Powered by Seekora', showSuggestions = true,
1724
1732
  }
1725
1733
  }, [query, onQueryChange]);
1726
1734
  const handleSearch = React.useCallback(async (searchQuery) => {
1735
+ // Cancel any pending searchAsYouType debounce — user explicitly submitted
1736
+ if (searchAsYouTypeRef.current) {
1737
+ clearTimeout(searchAsYouTypeRef.current);
1738
+ searchAsYouTypeRef.current = null;
1739
+ }
1727
1740
  // Allow empty queries - use empty string for search
1728
1741
  const query = searchQuery.trim();
1729
1742
  log.info('SearchBar: Triggering search', { query, originalQuery: searchQuery, isEmpty: !query });
@@ -1760,10 +1773,18 @@ const SearchBar = ({ placeholder = 'Powered by Seekora', showSuggestions = true,
1760
1773
  const handleInputChange = React.useCallback((e) => {
1761
1774
  const value = e.target.value;
1762
1775
  // Update query in state manager but don't trigger search immediately
1763
- // Search will be triggered on Enter or suggestion select
1776
+ // Search will be triggered on Enter, suggestion select, or after debounce if searchAsYouType
1764
1777
  setQuery(value, false); // false = don't trigger search immediately
1765
1778
  setSelectedIndex(-1);
1766
- }, [setQuery]);
1779
+ if (searchAsYouType) {
1780
+ if (searchAsYouTypeRef.current)
1781
+ clearTimeout(searchAsYouTypeRef.current);
1782
+ searchAsYouTypeRef.current = setTimeout(() => {
1783
+ searchAsYouTypeRef.current = null;
1784
+ triggerSearch();
1785
+ }, debounceMs);
1786
+ }
1787
+ }, [setQuery, searchAsYouType, debounceMs, triggerSearch]);
1767
1788
  const handleKeyDown = React.useCallback((e) => {
1768
1789
  switch (e.key) {
1769
1790
  case 'ArrowDown':
@@ -1839,10 +1860,17 @@ const SearchBar = ({ placeholder = 'Powered by Seekora', showSuggestions = true,
1839
1860
  ? `0 0 0 3px var(--seekora-border-focus-alpha, ${theme.colors.focus}33)`
1840
1861
  : undefined;
1841
1862
  const handleClear = React.useCallback(() => {
1863
+ if (searchAsYouTypeRef.current) {
1864
+ clearTimeout(searchAsYouTypeRef.current);
1865
+ searchAsYouTypeRef.current = null;
1866
+ }
1842
1867
  setQuery('', false);
1843
1868
  setSelectedIndex(-1);
1844
1869
  inputRef.current?.focus();
1845
- }, [setQuery]);
1870
+ if (searchAsYouType) {
1871
+ triggerSearch();
1872
+ }
1873
+ }, [setQuery, searchAsYouType, triggerSearch]);
1846
1874
  const handleSubmit = React.useCallback(() => {
1847
1875
  const currentValue = inputRef.current?.value || query;
1848
1876
  handleSearch(currentValue);