@rufous/ui 0.3.19 → 0.3.21

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/main.cjs CHANGED
@@ -169,13 +169,22 @@ __export(main_exports, {
169
169
  WorkItemIcon: () => workItemIcon_default,
170
170
  Zoom: () => Zoom,
171
171
  getAllCountries: () => getAllCountries2,
172
+ getCitiesByName: () => getCitiesByName,
172
173
  getCitiesOfCountry: () => getCitiesOfCountry,
173
174
  getCitiesOfState: () => getCitiesOfState,
175
+ getCityByName: () => getCityByName,
176
+ getCountriesByName: () => getCountriesByName,
174
177
  getCountryByCode: () => getCountryByCode,
178
+ getCountryByName: () => getCountryByName,
175
179
  getStateByCode: () => getStateByCode,
180
+ getStateByName: () => getStateByName,
181
+ getStatesByName: () => getStatesByName,
176
182
  getStatesOfCountry: () => getStatesOfCountry,
177
183
  transformLegacyTodos: () => transformLegacyTodos,
178
- useRufousTheme: () => useRufousTheme
184
+ useCitiesSearch: () => useCitiesSearch,
185
+ useCountriesSearch: () => useCountriesSearch,
186
+ useRufousTheme: () => useRufousTheme,
187
+ useStatesSearch: () => useStatesSearch
179
188
  });
180
189
  module.exports = __toCommonJS(main_exports);
181
190
 
@@ -4764,6 +4773,7 @@ function DataGrid({
4764
4773
  const menuRef = (0, import_react23.useRef)(null);
4765
4774
  const [showManageColumns, setShowManageColumns] = (0, import_react23.useState)(false);
4766
4775
  const [showAdvancedFilter, setShowAdvancedFilter] = (0, import_react23.useState)(false);
4776
+ const [focusFilterIdx, setFocusFilterIdx] = (0, import_react23.useState)(-1);
4767
4777
  const filterableColumnsProp = initialColumnsProp.filter((c) => c.filterable !== false);
4768
4778
  const initialFilterCol = String(filterableColumnsProp[0]?.field || filterableColumnsProp[0]?.key || "");
4769
4779
  const [advancedFilters, setAdvancedFilters] = (0, import_react23.useState)([
@@ -4812,9 +4822,13 @@ function DataGrid({
4812
4822
  return next;
4813
4823
  });
4814
4824
  }, [initialColumnsProp]);
4825
+ const onFiltersChangeRef = (0, import_react23.useRef)(onFiltersChange);
4815
4826
  (0, import_react23.useEffect)(() => {
4816
- onFiltersChange?.(advancedFilters);
4817
- }, [advancedFilters, onFiltersChange]);
4827
+ onFiltersChangeRef.current = onFiltersChange;
4828
+ });
4829
+ (0, import_react23.useEffect)(() => {
4830
+ onFiltersChangeRef.current?.(advancedFilters);
4831
+ }, [advancedFilters]);
4818
4832
  const handleSort = (fieldKey, dir) => {
4819
4833
  if (dir !== void 0) {
4820
4834
  setSortField(fieldKey);
@@ -5083,6 +5097,7 @@ function DataGrid({
5083
5097
  if (!firstCol) return prev;
5084
5098
  return [{ column: String(firstCol.field), operator: getDefaultOperator(firstCol.type), value: "", logic: "AND" }];
5085
5099
  });
5100
+ setFocusFilterIdx(-1);
5086
5101
  setShowAdvancedFilter(false);
5087
5102
  };
5088
5103
  const activeMenuCol = activeMenu ? resolvedColumns.find((c) => String(c.field) === activeMenu) : null;
@@ -5134,7 +5149,18 @@ function DataGrid({
5134
5149
  },
5135
5150
  col.headerName,
5136
5151
  col.sortable !== false && /* @__PURE__ */ import_react23.default.createElement("span", { className: `dg-sort-icon${isSorted ? " dg-sort-icon--active" : ""}` }, isSorted && sortDirection === "asc" && /* @__PURE__ */ import_react23.default.createElement(import_lucide_react2.ChevronUp, { size: 14 }), isSorted && sortDirection === "desc" && /* @__PURE__ */ import_react23.default.createElement(import_lucide_react2.ChevronDown, { size: 14 }), !isSorted && /* @__PURE__ */ import_react23.default.createElement(import_lucide_react2.ChevronsUpDown, { size: 14 }))
5137
- ), /* @__PURE__ */ import_react23.default.createElement("div", { className: `dg-th-actions${isFiltered ? " dg-th-actions--filtered" : ""}` }, isFiltered && /* @__PURE__ */ import_react23.default.createElement("button", { className: "dg-th-filter-btn", onClick: () => setShowAdvancedFilter(true) }, /* @__PURE__ */ import_react23.default.createElement(import_lucide_react2.Filter, { size: 11 })), !col.disableColumnMenu && /* @__PURE__ */ import_react23.default.createElement(
5152
+ ), /* @__PURE__ */ import_react23.default.createElement("div", { className: `dg-th-actions${isFiltered ? " dg-th-actions--filtered" : ""}` }, isFiltered && /* @__PURE__ */ import_react23.default.createElement(
5153
+ "button",
5154
+ {
5155
+ className: "dg-th-filter-btn",
5156
+ onClick: () => {
5157
+ const idx2 = advancedFilters.findIndex((f) => f.column === colField);
5158
+ setFocusFilterIdx(idx2);
5159
+ setShowAdvancedFilter(true);
5160
+ }
5161
+ },
5162
+ /* @__PURE__ */ import_react23.default.createElement(import_lucide_react2.Filter, { size: 11 })
5163
+ ), !col.disableColumnMenu && /* @__PURE__ */ import_react23.default.createElement(
5138
5164
  "button",
5139
5165
  {
5140
5166
  className: "dg-th-menu-btn",
@@ -5363,7 +5389,7 @@ function DataGrid({
5363
5389
  className: "dg-filter-input",
5364
5390
  placeholder: "Value\u2026",
5365
5391
  value: f.value,
5366
- autoFocus: idx === advancedFilters.length - 1,
5392
+ autoFocus: focusFilterIdx >= 0 ? idx === focusFilterIdx : idx === advancedFilters.length - 1,
5367
5393
  onChange: (e) => setAdvancedFilters((p) => p.map((fi, i) => i === idx ? { ...fi, value: e.target.value } : fi))
5368
5394
  }
5369
5395
  ));
@@ -9541,7 +9567,9 @@ function SmartSelect({
9541
9567
  value,
9542
9568
  onChange,
9543
9569
  onSearchChange,
9570
+ searchResults = [],
9544
9571
  debounceMs = 300,
9572
+ searchThreshold = 10,
9545
9573
  getOptionLabel,
9546
9574
  getOptionValue,
9547
9575
  getOptionSubLabel,
@@ -9579,14 +9607,20 @@ function SmartSelect({
9579
9607
  return flattenTree(options, getOptionChildren);
9580
9608
  }, [options, getOptionChildren]);
9581
9609
  const flatOptionsList = (0, import_react51.useMemo)(() => flatItems.map((f) => f.option), [flatItems]);
9610
+ const displayOptions = (0, import_react51.useMemo)(() => {
9611
+ if (!searchResults.length) return flatOptionsList;
9612
+ const localKeys = new Set(flatOptionsList.map((o) => getValue(o)));
9613
+ const serverOnly = searchResults.filter((o) => !localKeys.has(getValue(o)));
9614
+ return [...flatOptionsList, ...serverOnly];
9615
+ }, [flatOptionsList, searchResults, getValue]);
9582
9616
  const depthMap = (0, import_react51.useMemo)(() => {
9583
9617
  const map = /* @__PURE__ */ new Map();
9584
9618
  flatItems.forEach(({ option, depth }) => map.set(getValue(option), depth));
9585
9619
  return map;
9586
9620
  }, [flatItems, getValue]);
9587
9621
  const lookup = (0, import_react51.useMemo)(
9588
- () => buildLookup(options, getOptionChildren, getValue),
9589
- [options, getOptionChildren, getValue]
9622
+ () => buildLookup(displayOptions, getOptionChildren, getValue),
9623
+ [displayOptions, getOptionChildren, getValue]
9590
9624
  );
9591
9625
  const selectedKeys = (0, import_react51.useMemo)(() => {
9592
9626
  if (multiple) {
@@ -9598,21 +9632,27 @@ function SmartSelect({
9598
9632
  if (!onSearchChange) return;
9599
9633
  if (debounceTimer.current) clearTimeout(debounceTimer.current);
9600
9634
  if (!inputValue) {
9601
- onSearchChange("");
9635
+ onSearchChange("", 0);
9602
9636
  return;
9603
9637
  }
9604
- const hasLocalMatch = flatOptionsList.some(
9605
- (opt) => getOptionLabel(opt).toLowerCase().includes(inputValue.toLowerCase()) || (getOptionSubLabel?.(opt) ?? "").toLowerCase().includes(inputValue.toLowerCase())
9606
- );
9607
- if (hasLocalMatch) return;
9638
+ const q = inputValue.toLowerCase();
9639
+ let localCount = 0;
9640
+ for (const opt of flatOptionsList) {
9641
+ if (getOptionLabel(opt).toLowerCase().includes(q) || (getOptionSubLabel?.(opt) ?? "").toLowerCase().includes(q)) {
9642
+ localCount++;
9643
+ if (localCount >= searchThreshold) break;
9644
+ }
9645
+ }
9646
+ if (localCount >= searchThreshold) return;
9647
+ const needed = searchThreshold - localCount;
9608
9648
  if (debounceMs <= 0) {
9609
- onSearchChange(inputValue);
9649
+ onSearchChange(inputValue, needed);
9610
9650
  } else {
9611
9651
  debounceTimer.current = setTimeout(() => {
9612
- onSearchChange(inputValue);
9652
+ onSearchChange(inputValue, needed);
9613
9653
  }, debounceMs);
9614
9654
  }
9615
- }, [onSearchChange, debounceMs, flatOptionsList, getOptionLabel, getOptionSubLabel]);
9655
+ }, [onSearchChange, debounceMs, searchThreshold, flatOptionsList, getOptionLabel, getOptionSubLabel]);
9616
9656
  const handleChange = (0, import_react51.useCallback)((_, newValue) => {
9617
9657
  if (!multiple || !allowChildNodesSelection || !getOptionChildren) {
9618
9658
  onChange?.(newValue);
@@ -9699,10 +9739,12 @@ function SmartSelect({
9699
9739
  if (multiple) {
9700
9740
  const selected = opts.filter((o) => selectedKeys.has(getValue(o)));
9701
9741
  const unselected = opts.filter((o) => !selectedKeys.has(getValue(o)));
9702
- const filteredRest = inputValue ? unselected.filter(
9703
- (opt) => getOptionLabel(opt).toLowerCase().includes(inputValue.toLowerCase()) || (getOptionSubLabel?.(opt) ?? "").toLowerCase().includes(inputValue.toLowerCase())
9704
- ) : unselected;
9705
- return [...selected, ...filteredRest];
9742
+ if (!inputValue) return [...selected, ...unselected];
9743
+ const q2 = inputValue.toLowerCase();
9744
+ const filteredUnselected = unselected.filter(
9745
+ (opt) => getOptionLabel(opt).toLowerCase().includes(q2) || (getOptionSubLabel?.(opt) ?? "").toLowerCase().includes(q2)
9746
+ ).slice(0, searchThreshold);
9747
+ return [...selected, ...filteredUnselected];
9706
9748
  }
9707
9749
  if (value != null) {
9708
9750
  const selectedLabel = getOptionLabel(value);
@@ -9718,12 +9760,12 @@ function SmartSelect({
9718
9760
  const q = inputValue.toLowerCase();
9719
9761
  return opts.filter(
9720
9762
  (opt) => getOptionLabel(opt).toLowerCase().includes(q) || (getOptionSubLabel?.(opt) ?? "").toLowerCase().includes(q)
9721
- );
9722
- }, [filterOptionsProp, multiple, selectedKeys, getValue, getOptionLabel, getOptionSubLabel, value]);
9763
+ ).slice(0, searchThreshold);
9764
+ }, [filterOptionsProp, multiple, selectedKeys, getValue, getOptionLabel, getOptionSubLabel, value, searchThreshold]);
9723
9765
  return /* @__PURE__ */ import_react51.default.createElement(
9724
9766
  Autocomplete,
9725
9767
  {
9726
- options: flatOptionsList,
9768
+ options: displayOptions,
9727
9769
  value: value ?? (multiple ? [] : null),
9728
9770
  onChange: handleChange,
9729
9771
  onInputChange: handleInputChange,
@@ -13634,12 +13676,54 @@ function getStateNameMap(countryCode) {
13634
13676
  }
13635
13677
  return _stateNameCache.get(countryCode);
13636
13678
  }
13679
+ var _allCountriesCache = null;
13680
+ function getAllCountriesCached() {
13681
+ if (!_allCountriesCache) _allCountriesCache = import_country_state_city3.Country.getAllCountries();
13682
+ return _allCountriesCache;
13683
+ }
13684
+ var _allStatesCache = null;
13685
+ function getAllStatesCached() {
13686
+ if (!_allStatesCache) {
13687
+ const countryMap = new Map(import_country_state_city3.Country.getAllCountries().map((c) => [c.isoCode, c.name]));
13688
+ _allStatesCache = import_country_state_city3.State.getAllStates().map((s2) => ({
13689
+ ...s2,
13690
+ countryName: countryMap.get(s2.countryCode) ?? ""
13691
+ }));
13692
+ }
13693
+ return _allStatesCache;
13694
+ }
13695
+ var _allCitiesCache = null;
13696
+ function getAllCitiesCached() {
13697
+ if (!_allCitiesCache) {
13698
+ const countryMap = new Map(import_country_state_city3.Country.getAllCountries().map((c) => [c.isoCode, c.name]));
13699
+ const stateMap = new Map(import_country_state_city3.State.getAllStates().map((s2) => [`${s2.countryCode}:${s2.isoCode}`, s2.name]));
13700
+ _allCitiesCache = import_country_state_city3.City.getAllCities().map((city) => ({
13701
+ ...city,
13702
+ cityCode: city.name.slice(0, 3),
13703
+ countryName: countryMap.get(city.countryCode) ?? "",
13704
+ stateName: stateMap.get(`${city.countryCode}:${city.stateCode}`) ?? ""
13705
+ }));
13706
+ }
13707
+ return _allCitiesCache;
13708
+ }
13637
13709
  function getAllCountries2() {
13638
- return import_country_state_city3.Country.getAllCountries();
13710
+ return getAllCountriesCached();
13639
13711
  }
13640
13712
  function getCountryByCode(isoCode) {
13641
13713
  return import_country_state_city3.Country.getCountryByCode(isoCode) ?? void 0;
13642
13714
  }
13715
+ function getCountryByName(name, exact = false) {
13716
+ const q = name.toLowerCase();
13717
+ return getAllCountriesCached().find(
13718
+ (c) => exact ? c.name.toLowerCase() === q : c.name.toLowerCase().includes(q)
13719
+ );
13720
+ }
13721
+ function getCountriesByName(name, exact = false) {
13722
+ const q = name.toLowerCase();
13723
+ return getAllCountriesCached().filter(
13724
+ (c) => exact ? c.name.toLowerCase() === q : c.name.toLowerCase().includes(q)
13725
+ );
13726
+ }
13643
13727
  function getStatesOfCountry(countryCode) {
13644
13728
  const countryName = import_country_state_city3.Country.getCountryByCode(countryCode)?.name ?? "";
13645
13729
  return import_country_state_city3.State.getStatesOfCountry(countryCode).map((state) => ({
@@ -13653,6 +13737,18 @@ function getStateByCode(stateCode, countryCode) {
13653
13737
  const countryName = import_country_state_city3.Country.getCountryByCode(countryCode)?.name ?? "";
13654
13738
  return { ...state, countryName };
13655
13739
  }
13740
+ function getStateByName(name, exact = false) {
13741
+ const q = name.toLowerCase();
13742
+ return getAllStatesCached().find(
13743
+ (s2) => exact ? s2.name.toLowerCase() === q : s2.name.toLowerCase().includes(q)
13744
+ );
13745
+ }
13746
+ function getStatesByName(name, exact = false) {
13747
+ const q = name.toLowerCase();
13748
+ return getAllStatesCached().filter(
13749
+ (s2) => exact ? s2.name.toLowerCase() === q : s2.name.toLowerCase().includes(q)
13750
+ );
13751
+ }
13656
13752
  function getCitiesOfState(countryCode, stateCode) {
13657
13753
  const countryName = import_country_state_city3.Country.getCountryByCode(countryCode)?.name ?? "";
13658
13754
  const stateName = import_country_state_city3.State.getStateByCodeAndCountry(stateCode, countryCode)?.name ?? "";
@@ -13673,6 +13769,67 @@ function getCitiesOfCountry(countryCode) {
13673
13769
  stateName: stateNameMap.get(city.stateCode) ?? ""
13674
13770
  }));
13675
13771
  }
13772
+ function getCityByName(name, exact = false) {
13773
+ const q = name.toLowerCase();
13774
+ return getAllCitiesCached().find(
13775
+ (c) => exact ? c.name.toLowerCase() === q : c.name.toLowerCase().includes(q)
13776
+ );
13777
+ }
13778
+ function getCitiesByName(name, exact = false) {
13779
+ const q = name.toLowerCase();
13780
+ return getAllCitiesCached().filter(
13781
+ (c) => exact ? c.name.toLowerCase() === q : c.name.toLowerCase().includes(q)
13782
+ );
13783
+ }
13784
+
13785
+ // lib/utils/useLocationSearch.ts
13786
+ var import_react64 = require("react");
13787
+ function useDebounced(searcher, debounceMs) {
13788
+ const [query, setQuery] = (0, import_react64.useState)("");
13789
+ const [results, setResults] = (0, import_react64.useState)([]);
13790
+ const timer = (0, import_react64.useRef)(null);
13791
+ (0, import_react64.useEffect)(() => () => {
13792
+ if (timer.current) clearTimeout(timer.current);
13793
+ }, []);
13794
+ const search = (0, import_react64.useCallback)((name) => {
13795
+ setQuery(name);
13796
+ if (timer.current) clearTimeout(timer.current);
13797
+ if (!name.trim()) {
13798
+ setResults([]);
13799
+ return;
13800
+ }
13801
+ timer.current = setTimeout(() => {
13802
+ setResults(searcher(name));
13803
+ }, debounceMs);
13804
+ }, [searcher, debounceMs]);
13805
+ const clear = (0, import_react64.useCallback)(() => {
13806
+ if (timer.current) clearTimeout(timer.current);
13807
+ setQuery("");
13808
+ setResults([]);
13809
+ }, []);
13810
+ return { results, query, search, clear };
13811
+ }
13812
+ function useCountriesSearch(debounceMs = 300) {
13813
+ const searcher = (0, import_react64.useCallback)(
13814
+ (q) => getCountriesByName(q),
13815
+ []
13816
+ );
13817
+ return useDebounced(searcher, debounceMs);
13818
+ }
13819
+ function useStatesSearch(debounceMs = 300) {
13820
+ const searcher = (0, import_react64.useCallback)(
13821
+ (q) => getStatesByName(q),
13822
+ []
13823
+ );
13824
+ return useDebounced(searcher, debounceMs);
13825
+ }
13826
+ function useCitiesSearch(debounceMs = 300) {
13827
+ const searcher = (0, import_react64.useCallback)(
13828
+ (q) => getCitiesByName(q),
13829
+ []
13830
+ );
13831
+ return useDebounced(searcher, debounceMs);
13832
+ }
13676
13833
  // Annotate the CommonJS export names for ESM import in node:
13677
13834
  0 && (module.exports = {
13678
13835
  APP_THEMES,
@@ -13815,11 +13972,20 @@ function getCitiesOfCountry(countryCode) {
13815
13972
  WorkItemIcon,
13816
13973
  Zoom,
13817
13974
  getAllCountries,
13975
+ getCitiesByName,
13818
13976
  getCitiesOfCountry,
13819
13977
  getCitiesOfState,
13978
+ getCityByName,
13979
+ getCountriesByName,
13820
13980
  getCountryByCode,
13981
+ getCountryByName,
13821
13982
  getStateByCode,
13983
+ getStateByName,
13984
+ getStatesByName,
13822
13985
  getStatesOfCountry,
13823
13986
  transformLegacyTodos,
13824
- useRufousTheme
13987
+ useCitiesSearch,
13988
+ useCountriesSearch,
13989
+ useRufousTheme,
13990
+ useStatesSearch
13825
13991
  });
package/dist/main.d.cts CHANGED
@@ -1909,15 +1909,28 @@ interface SmartSelectProps<T = any> {
1909
1909
  /** Called when selection changes */
1910
1910
  onChange?: (value: T | T[] | null) => void;
1911
1911
  /**
1912
- * Called when the typed text finds no local match —
1913
- * use this to trigger an API / server search.
1912
+ * Called when local matches fall below `searchThreshold`.
1913
+ * Receives the current query and how many more records are needed to fill the threshold.
1914
+ * Use this to trigger an API / server search and update `searchResults`.
1914
1915
  */
1915
- onSearchChange?: (query: string) => void;
1916
+ onSearchChange?: (query: string, needed: number) => void;
1917
+ /**
1918
+ * Results returned by the API for the current query.
1919
+ * Merged with local matches (duplicates excluded) to fill up to `searchThreshold`.
1920
+ * Reset this to [] when the query is cleared.
1921
+ */
1922
+ searchResults?: T[];
1916
1923
  /**
1917
1924
  * Debounce delay in ms before `onSearchChange` fires.
1918
1925
  * Defaults to 300 ms. Pass 0 to disable debouncing.
1919
1926
  */
1920
1927
  debounceMs?: number;
1928
+ /**
1929
+ * Max results to show when a query is active.
1930
+ * If local matches are fewer than this, `onSearchChange` fires with how many more are needed.
1931
+ * Defaults to 10. Pass 0 to always call the API.
1932
+ */
1933
+ searchThreshold?: number;
1921
1934
  /** Primary display label for an option (required) */
1922
1935
  getOptionLabel: (option: T) => string;
1923
1936
  /** Unique key for an option — defaults to the label string */
@@ -1971,7 +1984,7 @@ interface SmartSelectProps<T = any> {
1971
1984
  style?: CSSProperties;
1972
1985
  sx?: SxProp;
1973
1986
  }
1974
- declare function SmartSelect<T = any>({ options, value, onChange, onSearchChange, debounceMs, getOptionLabel, getOptionValue, getOptionSubLabel, getOptionChildren, multiple, allowChildNodesSelection, loading, loadingText, filterOptions: filterOptionsProp, renderOption: renderOptionProp, limitTags, label, placeholder, variant, size, disabled, error, helperText, fullWidth, required, className, style, sx, }: SmartSelectProps<T>): React__default.JSX.Element;
1987
+ declare function SmartSelect<T = any>({ options, value, onChange, onSearchChange, searchResults, debounceMs, searchThreshold, getOptionLabel, getOptionValue, getOptionSubLabel, getOptionChildren, multiple, allowChildNodesSelection, loading, loadingText, filterOptions: filterOptionsProp, renderOption: renderOptionProp, limitTags, label, placeholder, variant, size, disabled, error, helperText, fullWidth, required, className, style, sx, }: SmartSelectProps<T>): React__default.JSX.Element;
1975
1988
 
1976
1989
  type ToolbarButton = 'undo' | 'redo' | 'ai' | 'paragraph' | 'fontsize' | 'font' | 'color' | 'bold' | 'italic' | 'strike' | 'link' | 'lineheight' | 'ul' | 'ol' | 'align' | 'indent' | 'outdent' | 'table' | 'image' | 'video' | 'cut' | 'copy' | 'paste' | 'specialchars' | 'code' | 'fullscreen' | 'tts' | 'stt' | 'translate' | 'todo' | '|';
1977
1990
  type EditorVariant = 'default' | 'basic';
@@ -2078,6 +2091,20 @@ interface EnhancedCity extends ICity {
2078
2091
  declare function getAllCountries(): EnhancedCountry[];
2079
2092
  /** Returns a single country by its ISO 2-letter code, or undefined if not found. */
2080
2093
  declare function getCountryByCode(isoCode: string): EnhancedCountry | undefined;
2094
+ /**
2095
+ * Returns the first country whose name matches the query (case-insensitive).
2096
+ * Pass `exact: false` (default) to also match partial names.
2097
+ * @param name Country name or partial name, e.g. "United States" or "united"
2098
+ * @param exact When true, requires an exact case-insensitive match. Default false.
2099
+ */
2100
+ declare function getCountryByName(name: string, exact?: boolean): EnhancedCountry | undefined;
2101
+ /**
2102
+ * Returns all countries whose names match the query (case-insensitive, partial by default).
2103
+ * Useful for search-as-you-type flows where you want multiple candidates.
2104
+ * @param name Search string, e.g. "ind" matches "India", "Indonesia", etc.
2105
+ * @param exact When true, only exact case-insensitive matches are returned. Default false.
2106
+ */
2107
+ declare function getCountriesByName(name: string, exact?: boolean): EnhancedCountry[];
2081
2108
  /**
2082
2109
  * Returns all states for a country, each enriched with `countryName`.
2083
2110
  * @param countryCode ISO 2-letter country code, e.g. "US"
@@ -2089,6 +2116,18 @@ declare function getStatesOfCountry(countryCode: string): EnhancedState[];
2089
2116
  * @param countryCode ISO 2-letter country code, e.g. "US"
2090
2117
  */
2091
2118
  declare function getStateByCode(stateCode: string, countryCode: string): EnhancedState | undefined;
2119
+ /**
2120
+ * Returns the first state whose name matches the query across **all countries** (case-insensitive).
2121
+ * @param name State name or partial name, e.g. "Iowa" or "iow"
2122
+ * @param exact When true, requires an exact case-insensitive match. Default false.
2123
+ */
2124
+ declare function getStateByName(name: string, exact?: boolean): EnhancedState | undefined;
2125
+ /**
2126
+ * Returns all states whose names match the query across **all countries** (case-insensitive, partial by default).
2127
+ * @param name Search string, e.g. "new" matches "New York", "New South Wales", etc.
2128
+ * @param exact When true, only exact case-insensitive matches are returned. Default false.
2129
+ */
2130
+ declare function getStatesByName(name: string, exact?: boolean): EnhancedState[];
2092
2131
  /**
2093
2132
  * Returns all cities for a given state, each enriched with `cityCode`, `countryName`,
2094
2133
  * and `stateName`.
@@ -2102,5 +2141,63 @@ declare function getCitiesOfState(countryCode: string, stateCode: string): Enhan
2102
2141
  * @param countryCode ISO 2-letter country code, e.g. "US"
2103
2142
  */
2104
2143
  declare function getCitiesOfCountry(countryCode: string): EnhancedCity[];
2144
+ /**
2145
+ * Returns the first city whose name matches the query across **all countries and states** (case-insensitive).
2146
+ * @param name City name or partial name, e.g. "Delhi" or "del"
2147
+ * @param exact When true, requires an exact case-insensitive match. Default false.
2148
+ */
2149
+ declare function getCityByName(name: string, exact?: boolean): EnhancedCity | undefined;
2150
+ /**
2151
+ * Returns all cities whose names match the query across **all countries and states** (case-insensitive, partial by default).
2152
+ * Searches ~148k cities — prefer the debounced `useCitiesSearch` hook in React components.
2153
+ * @param name Search string, e.g. "spring" matches "Springfield", "Spring Hill", etc.
2154
+ * @param exact When true, only exact case-insensitive matches are returned. Default false.
2155
+ */
2156
+ declare function getCitiesByName(name: string, exact?: boolean): EnhancedCity[];
2157
+
2158
+ interface SearchResult<T> {
2159
+ /** Filtered results. Empty while query is blank. */
2160
+ results: T[];
2161
+ /** Current value of the search input (updated immediately on each keystroke). */
2162
+ query: string;
2163
+ /** Call this on every keystroke — triggers the debounced filter. */
2164
+ search: (name: string) => void;
2165
+ /** Resets query and results immediately. */
2166
+ clear: () => void;
2167
+ }
2168
+ /**
2169
+ * Debounced country name search across all ~250 countries.
2170
+ *
2171
+ * @param debounceMs Delay before filtering runs. Defaults to 300 ms.
2172
+ *
2173
+ * @example
2174
+ * const { results, search, clear, query } = useCountriesSearch();
2175
+ * <input onChange={e => search(e.target.value)} value={query} />
2176
+ * {results.map(c => <div key={c.isoCode}>{c.flag} {c.name}</div>)}
2177
+ */
2178
+ declare function useCountriesSearch(debounceMs?: number): SearchResult<EnhancedCountry>;
2179
+ /**
2180
+ * Debounced state / province name search across **all countries** (~5k states).
2181
+ * No country scoping — results include `countryName` so you can display origin.
2182
+ *
2183
+ * @param debounceMs Delay before filtering runs. Defaults to 300 ms.
2184
+ *
2185
+ * @example
2186
+ * const { results, search, clear } = useStatesSearch();
2187
+ * // results[0] → { name, isoCode, countryCode, countryName, latitude, longitude }
2188
+ */
2189
+ declare function useStatesSearch(debounceMs?: number): SearchResult<EnhancedState>;
2190
+ /**
2191
+ * Debounced city name search across **all countries and states** (~148k cities).
2192
+ * No country / state scoping — results include `countryName` and `stateName`.
2193
+ * Debouncing is strongly recommended given the dataset size.
2194
+ *
2195
+ * @param debounceMs Delay before filtering runs. Defaults to 300 ms.
2196
+ *
2197
+ * @example
2198
+ * const { results, search, clear } = useCitiesSearch(400);
2199
+ * // results[0] → { name, cityCode, stateCode, stateName, countryCode, countryName, … }
2200
+ */
2201
+ declare function useCitiesSearch(debounceMs?: number): SearchResult<EnhancedCity>;
2105
2202
 
2106
- export { APP_THEMES, Accordion, AccordionDetails, type AccordionDetailsProps, type AccordionProps, AccordionSummary, type AccordionSummaryProps, type Action, ActivateUserIcon, AddButton, AddressLookup, ArchivedIcon, AssignGroupIcon, Autocomplete, type AutocompleteProps, Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, BaseDialog, Box, type BoxProps, Breadcrumbs, type BreadcrumbsProps, Button, type ButtonProps, CameraIcon, CancelButton, Card, CardActions, type CardActionsProps, CardContent, type CardContentProps, CardHeader, type CardHeaderProps, CardMedia, type CardMediaProps, type CardProps, Checkbox, type CheckboxProps, Chip, type ChipProps, CircularProgress, CircularProgressIcon, type CircularProgressIconProps, CloseIcon, Collapse, type CollapseProps, type Column, CopyIcon, DataGrid, type DataGridProps, DateField, type DateFieldProps, type DateFormatString, DateRangeField, type DateRangeFieldProps, type DateRangeValue, DifficultyAllIcon, DifficultyEasyIcon, DifficultyHardIcon, DifficultyMediumIcon, Divider, type DividerProps, DollarIcon, DownloadIcon, DownloadPdfIcon, Drawer, type DrawerProps, EditChatIcon, EditIcon, EngagementIcon, type EnhancedCity, type EnhancedCountry, type EnhancedState, Fade, type FadeProps, FunctionIcon, Grid, type GridProps, Grow, type GrowProps, HelpOutlinedIcon, HierarchyIcon, IconButton, type IconButtonProps, ImageField, type ImageFieldProps, InactiveGroupIcon, IndustryIcon, InvoiceIcon, Link, type LinkProps, List, ListItem, ListItemButton, type ListItemButtonProps, ListItemIcon, type ListItemIconProps, type ListItemProps, ListItemText, type ListItemTextProps, type ListProps, ListSubheader, type ListSubheaderProps, LocationPinIcon, LogsIcon, Menu, MenuDivider, MenuItem, type MenuItemProps, MenuList, type MenuListProps, type MenuProps, MinExperienceIcon, NineDotMenuIcon, NotificationIcon, type NumberVariant, Paper, type PaperProps, PhoneField, type PhoneFieldProps, Popover, type PopoverProps, Popper, type PopperProps, ProjectIcon, QualificationsIcon, QuestionStatusAllIcon, QuestionStatusPrivateIcon, QuestionStatusPublicIcon, QuestionTypeAllIcon, QuestionTypeCodingIcon, QuestionTypeDescriptiveIcon, QuestionTypeMultipleIcon, QuestionTypeSingleIcon, Radio, RadioGroup, type RadioGroupProps, type RadioProps, Rating, type RatingProps, RefreshIcon, ResendInviteIcon, RolesIcon, RufousAiIcon, RufousBirdIcon, RufousLauncherIcon, RufousLogoLoader, type RufousLogoLoaderProps, RufousTextContent, type RufousTextContentProps, RufousTextEditor, type MentionItemData as RufousTextEditorMentionItem, type RufousTextEditorProps, RufousThemeProvider, Select, type SelectProps, SidebarIcon, Skeleton, type SkeletonProps, Slide, type SlideProps, Slider, type SliderProps, SmartSelect, type SmartSelectProps, Snackbar, type SnackbarProps, SoftSkillsIcon, type SortDirection, Stack, type StackProps, StandardButton, Step, StepButton, type StepButtonProps, StepContent, type StepContentProps, StepLabel, type StepLabelProps, type StepProps, Stepper, type StepperProps, SubmitButton, SubscribeIcon, SuspendUserIcon, Switch, type SwitchProps, type SxProp, Tab, TabPanel, type TabPanelProps, type TabProps, Tabs, type TabsProps, TechnicalSkillsIcon, TextField, type TextFieldProps, TickIcon, TimerIcon, ToggleButton, ToggleButtonGroup, type ToggleButtonGroupProps, type ToggleButtonProps, Tooltip, type TooltipProps, TrashIcon, type TreeNode, TreeSelect, type TreeSelectMultiValue, type TreeSelectProps, type TreeSelectValue, Typography, type TypographyProps, UnArchivedIcon, UnsubscribeIcon, UploadIcon, UserAssignIcon, type UserOption, UserSelectionField, type UserSelectionFieldProps, ViewIcon, WorkItemIcon, Zoom, type ZoomProps, getAllCountries, getCitiesOfCountry, getCitiesOfState, getCountryByCode, getStateByCode, getStatesOfCountry, transformLegacyTodos, useRufousTheme };
2203
+ export { APP_THEMES, Accordion, AccordionDetails, type AccordionDetailsProps, type AccordionProps, AccordionSummary, type AccordionSummaryProps, type Action, ActivateUserIcon, AddButton, AddressLookup, ArchivedIcon, AssignGroupIcon, Autocomplete, type AutocompleteProps, Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, BaseDialog, Box, type BoxProps, Breadcrumbs, type BreadcrumbsProps, Button, type ButtonProps, CameraIcon, CancelButton, Card, CardActions, type CardActionsProps, CardContent, type CardContentProps, CardHeader, type CardHeaderProps, CardMedia, type CardMediaProps, type CardProps, Checkbox, type CheckboxProps, Chip, type ChipProps, CircularProgress, CircularProgressIcon, type CircularProgressIconProps, CloseIcon, Collapse, type CollapseProps, type Column, CopyIcon, DataGrid, type DataGridProps, DateField, type DateFieldProps, type DateFormatString, DateRangeField, type DateRangeFieldProps, type DateRangeValue, DifficultyAllIcon, DifficultyEasyIcon, DifficultyHardIcon, DifficultyMediumIcon, Divider, type DividerProps, DollarIcon, DownloadIcon, DownloadPdfIcon, Drawer, type DrawerProps, EditChatIcon, EditIcon, EngagementIcon, type EnhancedCity, type EnhancedCountry, type EnhancedState, Fade, type FadeProps, FunctionIcon, Grid, type GridProps, Grow, type GrowProps, HelpOutlinedIcon, HierarchyIcon, IconButton, type IconButtonProps, ImageField, type ImageFieldProps, InactiveGroupIcon, IndustryIcon, InvoiceIcon, Link, type LinkProps, List, ListItem, ListItemButton, type ListItemButtonProps, ListItemIcon, type ListItemIconProps, type ListItemProps, ListItemText, type ListItemTextProps, type ListProps, ListSubheader, type ListSubheaderProps, LocationPinIcon, LogsIcon, Menu, MenuDivider, MenuItem, type MenuItemProps, MenuList, type MenuListProps, type MenuProps, MinExperienceIcon, NineDotMenuIcon, NotificationIcon, type NumberVariant, Paper, type PaperProps, PhoneField, type PhoneFieldProps, Popover, type PopoverProps, Popper, type PopperProps, ProjectIcon, QualificationsIcon, QuestionStatusAllIcon, QuestionStatusPrivateIcon, QuestionStatusPublicIcon, QuestionTypeAllIcon, QuestionTypeCodingIcon, QuestionTypeDescriptiveIcon, QuestionTypeMultipleIcon, QuestionTypeSingleIcon, Radio, RadioGroup, type RadioGroupProps, type RadioProps, Rating, type RatingProps, RefreshIcon, ResendInviteIcon, RolesIcon, RufousAiIcon, RufousBirdIcon, RufousLauncherIcon, RufousLogoLoader, type RufousLogoLoaderProps, RufousTextContent, type RufousTextContentProps, RufousTextEditor, type MentionItemData as RufousTextEditorMentionItem, type RufousTextEditorProps, RufousThemeProvider, Select, type SelectProps, SidebarIcon, Skeleton, type SkeletonProps, Slide, type SlideProps, Slider, type SliderProps, SmartSelect, type SmartSelectProps, Snackbar, type SnackbarProps, SoftSkillsIcon, type SortDirection, Stack, type StackProps, StandardButton, Step, StepButton, type StepButtonProps, StepContent, type StepContentProps, StepLabel, type StepLabelProps, type StepProps, Stepper, type StepperProps, SubmitButton, SubscribeIcon, SuspendUserIcon, Switch, type SwitchProps, type SxProp, Tab, TabPanel, type TabPanelProps, type TabProps, Tabs, type TabsProps, TechnicalSkillsIcon, TextField, type TextFieldProps, TickIcon, TimerIcon, ToggleButton, ToggleButtonGroup, type ToggleButtonGroupProps, type ToggleButtonProps, Tooltip, type TooltipProps, TrashIcon, type TreeNode, TreeSelect, type TreeSelectMultiValue, type TreeSelectProps, type TreeSelectValue, Typography, type TypographyProps, UnArchivedIcon, UnsubscribeIcon, UploadIcon, UserAssignIcon, type UserOption, UserSelectionField, type UserSelectionFieldProps, ViewIcon, WorkItemIcon, Zoom, type ZoomProps, getAllCountries, getCitiesByName, getCitiesOfCountry, getCitiesOfState, getCityByName, getCountriesByName, getCountryByCode, getCountryByName, getStateByCode, getStateByName, getStatesByName, getStatesOfCountry, transformLegacyTodos, useCitiesSearch, useCountriesSearch, useRufousTheme, useStatesSearch };
package/dist/main.d.ts CHANGED
@@ -1909,15 +1909,28 @@ interface SmartSelectProps<T = any> {
1909
1909
  /** Called when selection changes */
1910
1910
  onChange?: (value: T | T[] | null) => void;
1911
1911
  /**
1912
- * Called when the typed text finds no local match —
1913
- * use this to trigger an API / server search.
1912
+ * Called when local matches fall below `searchThreshold`.
1913
+ * Receives the current query and how many more records are needed to fill the threshold.
1914
+ * Use this to trigger an API / server search and update `searchResults`.
1914
1915
  */
1915
- onSearchChange?: (query: string) => void;
1916
+ onSearchChange?: (query: string, needed: number) => void;
1917
+ /**
1918
+ * Results returned by the API for the current query.
1919
+ * Merged with local matches (duplicates excluded) to fill up to `searchThreshold`.
1920
+ * Reset this to [] when the query is cleared.
1921
+ */
1922
+ searchResults?: T[];
1916
1923
  /**
1917
1924
  * Debounce delay in ms before `onSearchChange` fires.
1918
1925
  * Defaults to 300 ms. Pass 0 to disable debouncing.
1919
1926
  */
1920
1927
  debounceMs?: number;
1928
+ /**
1929
+ * Max results to show when a query is active.
1930
+ * If local matches are fewer than this, `onSearchChange` fires with how many more are needed.
1931
+ * Defaults to 10. Pass 0 to always call the API.
1932
+ */
1933
+ searchThreshold?: number;
1921
1934
  /** Primary display label for an option (required) */
1922
1935
  getOptionLabel: (option: T) => string;
1923
1936
  /** Unique key for an option — defaults to the label string */
@@ -1971,7 +1984,7 @@ interface SmartSelectProps<T = any> {
1971
1984
  style?: CSSProperties;
1972
1985
  sx?: SxProp;
1973
1986
  }
1974
- declare function SmartSelect<T = any>({ options, value, onChange, onSearchChange, debounceMs, getOptionLabel, getOptionValue, getOptionSubLabel, getOptionChildren, multiple, allowChildNodesSelection, loading, loadingText, filterOptions: filterOptionsProp, renderOption: renderOptionProp, limitTags, label, placeholder, variant, size, disabled, error, helperText, fullWidth, required, className, style, sx, }: SmartSelectProps<T>): React__default.JSX.Element;
1987
+ declare function SmartSelect<T = any>({ options, value, onChange, onSearchChange, searchResults, debounceMs, searchThreshold, getOptionLabel, getOptionValue, getOptionSubLabel, getOptionChildren, multiple, allowChildNodesSelection, loading, loadingText, filterOptions: filterOptionsProp, renderOption: renderOptionProp, limitTags, label, placeholder, variant, size, disabled, error, helperText, fullWidth, required, className, style, sx, }: SmartSelectProps<T>): React__default.JSX.Element;
1975
1988
 
1976
1989
  type ToolbarButton = 'undo' | 'redo' | 'ai' | 'paragraph' | 'fontsize' | 'font' | 'color' | 'bold' | 'italic' | 'strike' | 'link' | 'lineheight' | 'ul' | 'ol' | 'align' | 'indent' | 'outdent' | 'table' | 'image' | 'video' | 'cut' | 'copy' | 'paste' | 'specialchars' | 'code' | 'fullscreen' | 'tts' | 'stt' | 'translate' | 'todo' | '|';
1977
1990
  type EditorVariant = 'default' | 'basic';
@@ -2078,6 +2091,20 @@ interface EnhancedCity extends ICity {
2078
2091
  declare function getAllCountries(): EnhancedCountry[];
2079
2092
  /** Returns a single country by its ISO 2-letter code, or undefined if not found. */
2080
2093
  declare function getCountryByCode(isoCode: string): EnhancedCountry | undefined;
2094
+ /**
2095
+ * Returns the first country whose name matches the query (case-insensitive).
2096
+ * Pass `exact: false` (default) to also match partial names.
2097
+ * @param name Country name or partial name, e.g. "United States" or "united"
2098
+ * @param exact When true, requires an exact case-insensitive match. Default false.
2099
+ */
2100
+ declare function getCountryByName(name: string, exact?: boolean): EnhancedCountry | undefined;
2101
+ /**
2102
+ * Returns all countries whose names match the query (case-insensitive, partial by default).
2103
+ * Useful for search-as-you-type flows where you want multiple candidates.
2104
+ * @param name Search string, e.g. "ind" matches "India", "Indonesia", etc.
2105
+ * @param exact When true, only exact case-insensitive matches are returned. Default false.
2106
+ */
2107
+ declare function getCountriesByName(name: string, exact?: boolean): EnhancedCountry[];
2081
2108
  /**
2082
2109
  * Returns all states for a country, each enriched with `countryName`.
2083
2110
  * @param countryCode ISO 2-letter country code, e.g. "US"
@@ -2089,6 +2116,18 @@ declare function getStatesOfCountry(countryCode: string): EnhancedState[];
2089
2116
  * @param countryCode ISO 2-letter country code, e.g. "US"
2090
2117
  */
2091
2118
  declare function getStateByCode(stateCode: string, countryCode: string): EnhancedState | undefined;
2119
+ /**
2120
+ * Returns the first state whose name matches the query across **all countries** (case-insensitive).
2121
+ * @param name State name or partial name, e.g. "Iowa" or "iow"
2122
+ * @param exact When true, requires an exact case-insensitive match. Default false.
2123
+ */
2124
+ declare function getStateByName(name: string, exact?: boolean): EnhancedState | undefined;
2125
+ /**
2126
+ * Returns all states whose names match the query across **all countries** (case-insensitive, partial by default).
2127
+ * @param name Search string, e.g. "new" matches "New York", "New South Wales", etc.
2128
+ * @param exact When true, only exact case-insensitive matches are returned. Default false.
2129
+ */
2130
+ declare function getStatesByName(name: string, exact?: boolean): EnhancedState[];
2092
2131
  /**
2093
2132
  * Returns all cities for a given state, each enriched with `cityCode`, `countryName`,
2094
2133
  * and `stateName`.
@@ -2102,5 +2141,63 @@ declare function getCitiesOfState(countryCode: string, stateCode: string): Enhan
2102
2141
  * @param countryCode ISO 2-letter country code, e.g. "US"
2103
2142
  */
2104
2143
  declare function getCitiesOfCountry(countryCode: string): EnhancedCity[];
2144
+ /**
2145
+ * Returns the first city whose name matches the query across **all countries and states** (case-insensitive).
2146
+ * @param name City name or partial name, e.g. "Delhi" or "del"
2147
+ * @param exact When true, requires an exact case-insensitive match. Default false.
2148
+ */
2149
+ declare function getCityByName(name: string, exact?: boolean): EnhancedCity | undefined;
2150
+ /**
2151
+ * Returns all cities whose names match the query across **all countries and states** (case-insensitive, partial by default).
2152
+ * Searches ~148k cities — prefer the debounced `useCitiesSearch` hook in React components.
2153
+ * @param name Search string, e.g. "spring" matches "Springfield", "Spring Hill", etc.
2154
+ * @param exact When true, only exact case-insensitive matches are returned. Default false.
2155
+ */
2156
+ declare function getCitiesByName(name: string, exact?: boolean): EnhancedCity[];
2157
+
2158
+ interface SearchResult<T> {
2159
+ /** Filtered results. Empty while query is blank. */
2160
+ results: T[];
2161
+ /** Current value of the search input (updated immediately on each keystroke). */
2162
+ query: string;
2163
+ /** Call this on every keystroke — triggers the debounced filter. */
2164
+ search: (name: string) => void;
2165
+ /** Resets query and results immediately. */
2166
+ clear: () => void;
2167
+ }
2168
+ /**
2169
+ * Debounced country name search across all ~250 countries.
2170
+ *
2171
+ * @param debounceMs Delay before filtering runs. Defaults to 300 ms.
2172
+ *
2173
+ * @example
2174
+ * const { results, search, clear, query } = useCountriesSearch();
2175
+ * <input onChange={e => search(e.target.value)} value={query} />
2176
+ * {results.map(c => <div key={c.isoCode}>{c.flag} {c.name}</div>)}
2177
+ */
2178
+ declare function useCountriesSearch(debounceMs?: number): SearchResult<EnhancedCountry>;
2179
+ /**
2180
+ * Debounced state / province name search across **all countries** (~5k states).
2181
+ * No country scoping — results include `countryName` so you can display origin.
2182
+ *
2183
+ * @param debounceMs Delay before filtering runs. Defaults to 300 ms.
2184
+ *
2185
+ * @example
2186
+ * const { results, search, clear } = useStatesSearch();
2187
+ * // results[0] → { name, isoCode, countryCode, countryName, latitude, longitude }
2188
+ */
2189
+ declare function useStatesSearch(debounceMs?: number): SearchResult<EnhancedState>;
2190
+ /**
2191
+ * Debounced city name search across **all countries and states** (~148k cities).
2192
+ * No country / state scoping — results include `countryName` and `stateName`.
2193
+ * Debouncing is strongly recommended given the dataset size.
2194
+ *
2195
+ * @param debounceMs Delay before filtering runs. Defaults to 300 ms.
2196
+ *
2197
+ * @example
2198
+ * const { results, search, clear } = useCitiesSearch(400);
2199
+ * // results[0] → { name, cityCode, stateCode, stateName, countryCode, countryName, … }
2200
+ */
2201
+ declare function useCitiesSearch(debounceMs?: number): SearchResult<EnhancedCity>;
2105
2202
 
2106
- export { APP_THEMES, Accordion, AccordionDetails, type AccordionDetailsProps, type AccordionProps, AccordionSummary, type AccordionSummaryProps, type Action, ActivateUserIcon, AddButton, AddressLookup, ArchivedIcon, AssignGroupIcon, Autocomplete, type AutocompleteProps, Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, BaseDialog, Box, type BoxProps, Breadcrumbs, type BreadcrumbsProps, Button, type ButtonProps, CameraIcon, CancelButton, Card, CardActions, type CardActionsProps, CardContent, type CardContentProps, CardHeader, type CardHeaderProps, CardMedia, type CardMediaProps, type CardProps, Checkbox, type CheckboxProps, Chip, type ChipProps, CircularProgress, CircularProgressIcon, type CircularProgressIconProps, CloseIcon, Collapse, type CollapseProps, type Column, CopyIcon, DataGrid, type DataGridProps, DateField, type DateFieldProps, type DateFormatString, DateRangeField, type DateRangeFieldProps, type DateRangeValue, DifficultyAllIcon, DifficultyEasyIcon, DifficultyHardIcon, DifficultyMediumIcon, Divider, type DividerProps, DollarIcon, DownloadIcon, DownloadPdfIcon, Drawer, type DrawerProps, EditChatIcon, EditIcon, EngagementIcon, type EnhancedCity, type EnhancedCountry, type EnhancedState, Fade, type FadeProps, FunctionIcon, Grid, type GridProps, Grow, type GrowProps, HelpOutlinedIcon, HierarchyIcon, IconButton, type IconButtonProps, ImageField, type ImageFieldProps, InactiveGroupIcon, IndustryIcon, InvoiceIcon, Link, type LinkProps, List, ListItem, ListItemButton, type ListItemButtonProps, ListItemIcon, type ListItemIconProps, type ListItemProps, ListItemText, type ListItemTextProps, type ListProps, ListSubheader, type ListSubheaderProps, LocationPinIcon, LogsIcon, Menu, MenuDivider, MenuItem, type MenuItemProps, MenuList, type MenuListProps, type MenuProps, MinExperienceIcon, NineDotMenuIcon, NotificationIcon, type NumberVariant, Paper, type PaperProps, PhoneField, type PhoneFieldProps, Popover, type PopoverProps, Popper, type PopperProps, ProjectIcon, QualificationsIcon, QuestionStatusAllIcon, QuestionStatusPrivateIcon, QuestionStatusPublicIcon, QuestionTypeAllIcon, QuestionTypeCodingIcon, QuestionTypeDescriptiveIcon, QuestionTypeMultipleIcon, QuestionTypeSingleIcon, Radio, RadioGroup, type RadioGroupProps, type RadioProps, Rating, type RatingProps, RefreshIcon, ResendInviteIcon, RolesIcon, RufousAiIcon, RufousBirdIcon, RufousLauncherIcon, RufousLogoLoader, type RufousLogoLoaderProps, RufousTextContent, type RufousTextContentProps, RufousTextEditor, type MentionItemData as RufousTextEditorMentionItem, type RufousTextEditorProps, RufousThemeProvider, Select, type SelectProps, SidebarIcon, Skeleton, type SkeletonProps, Slide, type SlideProps, Slider, type SliderProps, SmartSelect, type SmartSelectProps, Snackbar, type SnackbarProps, SoftSkillsIcon, type SortDirection, Stack, type StackProps, StandardButton, Step, StepButton, type StepButtonProps, StepContent, type StepContentProps, StepLabel, type StepLabelProps, type StepProps, Stepper, type StepperProps, SubmitButton, SubscribeIcon, SuspendUserIcon, Switch, type SwitchProps, type SxProp, Tab, TabPanel, type TabPanelProps, type TabProps, Tabs, type TabsProps, TechnicalSkillsIcon, TextField, type TextFieldProps, TickIcon, TimerIcon, ToggleButton, ToggleButtonGroup, type ToggleButtonGroupProps, type ToggleButtonProps, Tooltip, type TooltipProps, TrashIcon, type TreeNode, TreeSelect, type TreeSelectMultiValue, type TreeSelectProps, type TreeSelectValue, Typography, type TypographyProps, UnArchivedIcon, UnsubscribeIcon, UploadIcon, UserAssignIcon, type UserOption, UserSelectionField, type UserSelectionFieldProps, ViewIcon, WorkItemIcon, Zoom, type ZoomProps, getAllCountries, getCitiesOfCountry, getCitiesOfState, getCountryByCode, getStateByCode, getStatesOfCountry, transformLegacyTodos, useRufousTheme };
2203
+ export { APP_THEMES, Accordion, AccordionDetails, type AccordionDetailsProps, type AccordionProps, AccordionSummary, type AccordionSummaryProps, type Action, ActivateUserIcon, AddButton, AddressLookup, ArchivedIcon, AssignGroupIcon, Autocomplete, type AutocompleteProps, Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, BaseDialog, Box, type BoxProps, Breadcrumbs, type BreadcrumbsProps, Button, type ButtonProps, CameraIcon, CancelButton, Card, CardActions, type CardActionsProps, CardContent, type CardContentProps, CardHeader, type CardHeaderProps, CardMedia, type CardMediaProps, type CardProps, Checkbox, type CheckboxProps, Chip, type ChipProps, CircularProgress, CircularProgressIcon, type CircularProgressIconProps, CloseIcon, Collapse, type CollapseProps, type Column, CopyIcon, DataGrid, type DataGridProps, DateField, type DateFieldProps, type DateFormatString, DateRangeField, type DateRangeFieldProps, type DateRangeValue, DifficultyAllIcon, DifficultyEasyIcon, DifficultyHardIcon, DifficultyMediumIcon, Divider, type DividerProps, DollarIcon, DownloadIcon, DownloadPdfIcon, Drawer, type DrawerProps, EditChatIcon, EditIcon, EngagementIcon, type EnhancedCity, type EnhancedCountry, type EnhancedState, Fade, type FadeProps, FunctionIcon, Grid, type GridProps, Grow, type GrowProps, HelpOutlinedIcon, HierarchyIcon, IconButton, type IconButtonProps, ImageField, type ImageFieldProps, InactiveGroupIcon, IndustryIcon, InvoiceIcon, Link, type LinkProps, List, ListItem, ListItemButton, type ListItemButtonProps, ListItemIcon, type ListItemIconProps, type ListItemProps, ListItemText, type ListItemTextProps, type ListProps, ListSubheader, type ListSubheaderProps, LocationPinIcon, LogsIcon, Menu, MenuDivider, MenuItem, type MenuItemProps, MenuList, type MenuListProps, type MenuProps, MinExperienceIcon, NineDotMenuIcon, NotificationIcon, type NumberVariant, Paper, type PaperProps, PhoneField, type PhoneFieldProps, Popover, type PopoverProps, Popper, type PopperProps, ProjectIcon, QualificationsIcon, QuestionStatusAllIcon, QuestionStatusPrivateIcon, QuestionStatusPublicIcon, QuestionTypeAllIcon, QuestionTypeCodingIcon, QuestionTypeDescriptiveIcon, QuestionTypeMultipleIcon, QuestionTypeSingleIcon, Radio, RadioGroup, type RadioGroupProps, type RadioProps, Rating, type RatingProps, RefreshIcon, ResendInviteIcon, RolesIcon, RufousAiIcon, RufousBirdIcon, RufousLauncherIcon, RufousLogoLoader, type RufousLogoLoaderProps, RufousTextContent, type RufousTextContentProps, RufousTextEditor, type MentionItemData as RufousTextEditorMentionItem, type RufousTextEditorProps, RufousThemeProvider, Select, type SelectProps, SidebarIcon, Skeleton, type SkeletonProps, Slide, type SlideProps, Slider, type SliderProps, SmartSelect, type SmartSelectProps, Snackbar, type SnackbarProps, SoftSkillsIcon, type SortDirection, Stack, type StackProps, StandardButton, Step, StepButton, type StepButtonProps, StepContent, type StepContentProps, StepLabel, type StepLabelProps, type StepProps, Stepper, type StepperProps, SubmitButton, SubscribeIcon, SuspendUserIcon, Switch, type SwitchProps, type SxProp, Tab, TabPanel, type TabPanelProps, type TabProps, Tabs, type TabsProps, TechnicalSkillsIcon, TextField, type TextFieldProps, TickIcon, TimerIcon, ToggleButton, ToggleButtonGroup, type ToggleButtonGroupProps, type ToggleButtonProps, Tooltip, type TooltipProps, TrashIcon, type TreeNode, TreeSelect, type TreeSelectMultiValue, type TreeSelectProps, type TreeSelectValue, Typography, type TypographyProps, UnArchivedIcon, UnsubscribeIcon, UploadIcon, UserAssignIcon, type UserOption, UserSelectionField, type UserSelectionFieldProps, ViewIcon, WorkItemIcon, Zoom, type ZoomProps, getAllCountries, getCitiesByName, getCitiesOfCountry, getCitiesOfState, getCityByName, getCountriesByName, getCountryByCode, getCountryByName, getStateByCode, getStateByName, getStatesByName, getStatesOfCountry, transformLegacyTodos, useCitiesSearch, useCountriesSearch, useRufousTheme, useStatesSearch };
package/dist/main.js CHANGED
@@ -4628,6 +4628,7 @@ function DataGrid({
4628
4628
  const menuRef = useRef10(null);
4629
4629
  const [showManageColumns, setShowManageColumns] = useState9(false);
4630
4630
  const [showAdvancedFilter, setShowAdvancedFilter] = useState9(false);
4631
+ const [focusFilterIdx, setFocusFilterIdx] = useState9(-1);
4631
4632
  const filterableColumnsProp = initialColumnsProp.filter((c) => c.filterable !== false);
4632
4633
  const initialFilterCol = String(filterableColumnsProp[0]?.field || filterableColumnsProp[0]?.key || "");
4633
4634
  const [advancedFilters, setAdvancedFilters] = useState9([
@@ -4676,9 +4677,13 @@ function DataGrid({
4676
4677
  return next;
4677
4678
  });
4678
4679
  }, [initialColumnsProp]);
4680
+ const onFiltersChangeRef = useRef10(onFiltersChange);
4679
4681
  useEffect9(() => {
4680
- onFiltersChange?.(advancedFilters);
4681
- }, [advancedFilters, onFiltersChange]);
4682
+ onFiltersChangeRef.current = onFiltersChange;
4683
+ });
4684
+ useEffect9(() => {
4685
+ onFiltersChangeRef.current?.(advancedFilters);
4686
+ }, [advancedFilters]);
4682
4687
  const handleSort = (fieldKey, dir) => {
4683
4688
  if (dir !== void 0) {
4684
4689
  setSortField(fieldKey);
@@ -4947,6 +4952,7 @@ function DataGrid({
4947
4952
  if (!firstCol) return prev;
4948
4953
  return [{ column: String(firstCol.field), operator: getDefaultOperator(firstCol.type), value: "", logic: "AND" }];
4949
4954
  });
4955
+ setFocusFilterIdx(-1);
4950
4956
  setShowAdvancedFilter(false);
4951
4957
  };
4952
4958
  const activeMenuCol = activeMenu ? resolvedColumns.find((c) => String(c.field) === activeMenu) : null;
@@ -4998,7 +5004,18 @@ function DataGrid({
4998
5004
  },
4999
5005
  col.headerName,
5000
5006
  col.sortable !== false && /* @__PURE__ */ React75.createElement("span", { className: `dg-sort-icon${isSorted ? " dg-sort-icon--active" : ""}` }, isSorted && sortDirection === "asc" && /* @__PURE__ */ React75.createElement(ChevronUp, { size: 14 }), isSorted && sortDirection === "desc" && /* @__PURE__ */ React75.createElement(ChevronDown, { size: 14 }), !isSorted && /* @__PURE__ */ React75.createElement(ChevronsUpDown, { size: 14 }))
5001
- ), /* @__PURE__ */ React75.createElement("div", { className: `dg-th-actions${isFiltered ? " dg-th-actions--filtered" : ""}` }, isFiltered && /* @__PURE__ */ React75.createElement("button", { className: "dg-th-filter-btn", onClick: () => setShowAdvancedFilter(true) }, /* @__PURE__ */ React75.createElement(Filter, { size: 11 })), !col.disableColumnMenu && /* @__PURE__ */ React75.createElement(
5007
+ ), /* @__PURE__ */ React75.createElement("div", { className: `dg-th-actions${isFiltered ? " dg-th-actions--filtered" : ""}` }, isFiltered && /* @__PURE__ */ React75.createElement(
5008
+ "button",
5009
+ {
5010
+ className: "dg-th-filter-btn",
5011
+ onClick: () => {
5012
+ const idx2 = advancedFilters.findIndex((f) => f.column === colField);
5013
+ setFocusFilterIdx(idx2);
5014
+ setShowAdvancedFilter(true);
5015
+ }
5016
+ },
5017
+ /* @__PURE__ */ React75.createElement(Filter, { size: 11 })
5018
+ ), !col.disableColumnMenu && /* @__PURE__ */ React75.createElement(
5002
5019
  "button",
5003
5020
  {
5004
5021
  className: "dg-th-menu-btn",
@@ -5227,7 +5244,7 @@ function DataGrid({
5227
5244
  className: "dg-filter-input",
5228
5245
  placeholder: "Value\u2026",
5229
5246
  value: f.value,
5230
- autoFocus: idx === advancedFilters.length - 1,
5247
+ autoFocus: focusFilterIdx >= 0 ? idx === focusFilterIdx : idx === advancedFilters.length - 1,
5231
5248
  onChange: (e) => setAdvancedFilters((p) => p.map((fi, i) => i === idx ? { ...fi, value: e.target.value } : fi))
5232
5249
  }
5233
5250
  ));
@@ -9474,7 +9491,9 @@ function SmartSelect({
9474
9491
  value,
9475
9492
  onChange,
9476
9493
  onSearchChange,
9494
+ searchResults = [],
9477
9495
  debounceMs = 300,
9496
+ searchThreshold = 10,
9478
9497
  getOptionLabel,
9479
9498
  getOptionValue,
9480
9499
  getOptionSubLabel,
@@ -9512,14 +9531,20 @@ function SmartSelect({
9512
9531
  return flattenTree(options, getOptionChildren);
9513
9532
  }, [options, getOptionChildren]);
9514
9533
  const flatOptionsList = useMemo3(() => flatItems.map((f) => f.option), [flatItems]);
9534
+ const displayOptions = useMemo3(() => {
9535
+ if (!searchResults.length) return flatOptionsList;
9536
+ const localKeys = new Set(flatOptionsList.map((o) => getValue(o)));
9537
+ const serverOnly = searchResults.filter((o) => !localKeys.has(getValue(o)));
9538
+ return [...flatOptionsList, ...serverOnly];
9539
+ }, [flatOptionsList, searchResults, getValue]);
9515
9540
  const depthMap = useMemo3(() => {
9516
9541
  const map = /* @__PURE__ */ new Map();
9517
9542
  flatItems.forEach(({ option, depth }) => map.set(getValue(option), depth));
9518
9543
  return map;
9519
9544
  }, [flatItems, getValue]);
9520
9545
  const lookup = useMemo3(
9521
- () => buildLookup(options, getOptionChildren, getValue),
9522
- [options, getOptionChildren, getValue]
9546
+ () => buildLookup(displayOptions, getOptionChildren, getValue),
9547
+ [displayOptions, getOptionChildren, getValue]
9523
9548
  );
9524
9549
  const selectedKeys = useMemo3(() => {
9525
9550
  if (multiple) {
@@ -9531,21 +9556,27 @@ function SmartSelect({
9531
9556
  if (!onSearchChange) return;
9532
9557
  if (debounceTimer.current) clearTimeout(debounceTimer.current);
9533
9558
  if (!inputValue) {
9534
- onSearchChange("");
9559
+ onSearchChange("", 0);
9535
9560
  return;
9536
9561
  }
9537
- const hasLocalMatch = flatOptionsList.some(
9538
- (opt) => getOptionLabel(opt).toLowerCase().includes(inputValue.toLowerCase()) || (getOptionSubLabel?.(opt) ?? "").toLowerCase().includes(inputValue.toLowerCase())
9539
- );
9540
- if (hasLocalMatch) return;
9562
+ const q = inputValue.toLowerCase();
9563
+ let localCount = 0;
9564
+ for (const opt of flatOptionsList) {
9565
+ if (getOptionLabel(opt).toLowerCase().includes(q) || (getOptionSubLabel?.(opt) ?? "").toLowerCase().includes(q)) {
9566
+ localCount++;
9567
+ if (localCount >= searchThreshold) break;
9568
+ }
9569
+ }
9570
+ if (localCount >= searchThreshold) return;
9571
+ const needed = searchThreshold - localCount;
9541
9572
  if (debounceMs <= 0) {
9542
- onSearchChange(inputValue);
9573
+ onSearchChange(inputValue, needed);
9543
9574
  } else {
9544
9575
  debounceTimer.current = setTimeout(() => {
9545
- onSearchChange(inputValue);
9576
+ onSearchChange(inputValue, needed);
9546
9577
  }, debounceMs);
9547
9578
  }
9548
- }, [onSearchChange, debounceMs, flatOptionsList, getOptionLabel, getOptionSubLabel]);
9579
+ }, [onSearchChange, debounceMs, searchThreshold, flatOptionsList, getOptionLabel, getOptionSubLabel]);
9549
9580
  const handleChange = useCallback11((_, newValue) => {
9550
9581
  if (!multiple || !allowChildNodesSelection || !getOptionChildren) {
9551
9582
  onChange?.(newValue);
@@ -9632,10 +9663,12 @@ function SmartSelect({
9632
9663
  if (multiple) {
9633
9664
  const selected = opts.filter((o) => selectedKeys.has(getValue(o)));
9634
9665
  const unselected = opts.filter((o) => !selectedKeys.has(getValue(o)));
9635
- const filteredRest = inputValue ? unselected.filter(
9636
- (opt) => getOptionLabel(opt).toLowerCase().includes(inputValue.toLowerCase()) || (getOptionSubLabel?.(opt) ?? "").toLowerCase().includes(inputValue.toLowerCase())
9637
- ) : unselected;
9638
- return [...selected, ...filteredRest];
9666
+ if (!inputValue) return [...selected, ...unselected];
9667
+ const q2 = inputValue.toLowerCase();
9668
+ const filteredUnselected = unselected.filter(
9669
+ (opt) => getOptionLabel(opt).toLowerCase().includes(q2) || (getOptionSubLabel?.(opt) ?? "").toLowerCase().includes(q2)
9670
+ ).slice(0, searchThreshold);
9671
+ return [...selected, ...filteredUnselected];
9639
9672
  }
9640
9673
  if (value != null) {
9641
9674
  const selectedLabel = getOptionLabel(value);
@@ -9651,12 +9684,12 @@ function SmartSelect({
9651
9684
  const q = inputValue.toLowerCase();
9652
9685
  return opts.filter(
9653
9686
  (opt) => getOptionLabel(opt).toLowerCase().includes(q) || (getOptionSubLabel?.(opt) ?? "").toLowerCase().includes(q)
9654
- );
9655
- }, [filterOptionsProp, multiple, selectedKeys, getValue, getOptionLabel, getOptionSubLabel, value]);
9687
+ ).slice(0, searchThreshold);
9688
+ }, [filterOptionsProp, multiple, selectedKeys, getValue, getOptionLabel, getOptionSubLabel, value, searchThreshold]);
9656
9689
  return /* @__PURE__ */ React108.createElement(
9657
9690
  Autocomplete,
9658
9691
  {
9659
- options: flatOptionsList,
9692
+ options: displayOptions,
9660
9693
  value: value ?? (multiple ? [] : null),
9661
9694
  onChange: handleChange,
9662
9695
  onInputChange: handleInputChange,
@@ -13567,12 +13600,54 @@ function getStateNameMap(countryCode) {
13567
13600
  }
13568
13601
  return _stateNameCache.get(countryCode);
13569
13602
  }
13603
+ var _allCountriesCache = null;
13604
+ function getAllCountriesCached() {
13605
+ if (!_allCountriesCache) _allCountriesCache = Country3.getAllCountries();
13606
+ return _allCountriesCache;
13607
+ }
13608
+ var _allStatesCache = null;
13609
+ function getAllStatesCached() {
13610
+ if (!_allStatesCache) {
13611
+ const countryMap = new Map(Country3.getAllCountries().map((c) => [c.isoCode, c.name]));
13612
+ _allStatesCache = State2.getAllStates().map((s2) => ({
13613
+ ...s2,
13614
+ countryName: countryMap.get(s2.countryCode) ?? ""
13615
+ }));
13616
+ }
13617
+ return _allStatesCache;
13618
+ }
13619
+ var _allCitiesCache = null;
13620
+ function getAllCitiesCached() {
13621
+ if (!_allCitiesCache) {
13622
+ const countryMap = new Map(Country3.getAllCountries().map((c) => [c.isoCode, c.name]));
13623
+ const stateMap = new Map(State2.getAllStates().map((s2) => [`${s2.countryCode}:${s2.isoCode}`, s2.name]));
13624
+ _allCitiesCache = City2.getAllCities().map((city) => ({
13625
+ ...city,
13626
+ cityCode: city.name.slice(0, 3),
13627
+ countryName: countryMap.get(city.countryCode) ?? "",
13628
+ stateName: stateMap.get(`${city.countryCode}:${city.stateCode}`) ?? ""
13629
+ }));
13630
+ }
13631
+ return _allCitiesCache;
13632
+ }
13570
13633
  function getAllCountries2() {
13571
- return Country3.getAllCountries();
13634
+ return getAllCountriesCached();
13572
13635
  }
13573
13636
  function getCountryByCode(isoCode) {
13574
13637
  return Country3.getCountryByCode(isoCode) ?? void 0;
13575
13638
  }
13639
+ function getCountryByName(name, exact = false) {
13640
+ const q = name.toLowerCase();
13641
+ return getAllCountriesCached().find(
13642
+ (c) => exact ? c.name.toLowerCase() === q : c.name.toLowerCase().includes(q)
13643
+ );
13644
+ }
13645
+ function getCountriesByName(name, exact = false) {
13646
+ const q = name.toLowerCase();
13647
+ return getAllCountriesCached().filter(
13648
+ (c) => exact ? c.name.toLowerCase() === q : c.name.toLowerCase().includes(q)
13649
+ );
13650
+ }
13576
13651
  function getStatesOfCountry(countryCode) {
13577
13652
  const countryName = Country3.getCountryByCode(countryCode)?.name ?? "";
13578
13653
  return State2.getStatesOfCountry(countryCode).map((state) => ({
@@ -13586,6 +13661,18 @@ function getStateByCode(stateCode, countryCode) {
13586
13661
  const countryName = Country3.getCountryByCode(countryCode)?.name ?? "";
13587
13662
  return { ...state, countryName };
13588
13663
  }
13664
+ function getStateByName(name, exact = false) {
13665
+ const q = name.toLowerCase();
13666
+ return getAllStatesCached().find(
13667
+ (s2) => exact ? s2.name.toLowerCase() === q : s2.name.toLowerCase().includes(q)
13668
+ );
13669
+ }
13670
+ function getStatesByName(name, exact = false) {
13671
+ const q = name.toLowerCase();
13672
+ return getAllStatesCached().filter(
13673
+ (s2) => exact ? s2.name.toLowerCase() === q : s2.name.toLowerCase().includes(q)
13674
+ );
13675
+ }
13589
13676
  function getCitiesOfState(countryCode, stateCode) {
13590
13677
  const countryName = Country3.getCountryByCode(countryCode)?.name ?? "";
13591
13678
  const stateName = State2.getStateByCodeAndCountry(stateCode, countryCode)?.name ?? "";
@@ -13606,6 +13693,67 @@ function getCitiesOfCountry(countryCode) {
13606
13693
  stateName: stateNameMap.get(city.stateCode) ?? ""
13607
13694
  }));
13608
13695
  }
13696
+ function getCityByName(name, exact = false) {
13697
+ const q = name.toLowerCase();
13698
+ return getAllCitiesCached().find(
13699
+ (c) => exact ? c.name.toLowerCase() === q : c.name.toLowerCase().includes(q)
13700
+ );
13701
+ }
13702
+ function getCitiesByName(name, exact = false) {
13703
+ const q = name.toLowerCase();
13704
+ return getAllCitiesCached().filter(
13705
+ (c) => exact ? c.name.toLowerCase() === q : c.name.toLowerCase().includes(q)
13706
+ );
13707
+ }
13708
+
13709
+ // lib/utils/useLocationSearch.ts
13710
+ import { useState as useState36, useEffect as useEffect31, useRef as useRef34, useCallback as useCallback17 } from "react";
13711
+ function useDebounced(searcher, debounceMs) {
13712
+ const [query, setQuery] = useState36("");
13713
+ const [results, setResults] = useState36([]);
13714
+ const timer = useRef34(null);
13715
+ useEffect31(() => () => {
13716
+ if (timer.current) clearTimeout(timer.current);
13717
+ }, []);
13718
+ const search = useCallback17((name) => {
13719
+ setQuery(name);
13720
+ if (timer.current) clearTimeout(timer.current);
13721
+ if (!name.trim()) {
13722
+ setResults([]);
13723
+ return;
13724
+ }
13725
+ timer.current = setTimeout(() => {
13726
+ setResults(searcher(name));
13727
+ }, debounceMs);
13728
+ }, [searcher, debounceMs]);
13729
+ const clear = useCallback17(() => {
13730
+ if (timer.current) clearTimeout(timer.current);
13731
+ setQuery("");
13732
+ setResults([]);
13733
+ }, []);
13734
+ return { results, query, search, clear };
13735
+ }
13736
+ function useCountriesSearch(debounceMs = 300) {
13737
+ const searcher = useCallback17(
13738
+ (q) => getCountriesByName(q),
13739
+ []
13740
+ );
13741
+ return useDebounced(searcher, debounceMs);
13742
+ }
13743
+ function useStatesSearch(debounceMs = 300) {
13744
+ const searcher = useCallback17(
13745
+ (q) => getStatesByName(q),
13746
+ []
13747
+ );
13748
+ return useDebounced(searcher, debounceMs);
13749
+ }
13750
+ function useCitiesSearch(debounceMs = 300) {
13751
+ const searcher = useCallback17(
13752
+ (q) => getCitiesByName(q),
13753
+ []
13754
+ );
13755
+ return useDebounced(searcher, debounceMs);
13756
+ }
13609
13757
  export {
13610
13758
  APP_THEMES,
13611
13759
  Accordion,
@@ -13747,11 +13895,20 @@ export {
13747
13895
  workItemIcon_default as WorkItemIcon,
13748
13896
  Zoom,
13749
13897
  getAllCountries2 as getAllCountries,
13898
+ getCitiesByName,
13750
13899
  getCitiesOfCountry,
13751
13900
  getCitiesOfState,
13901
+ getCityByName,
13902
+ getCountriesByName,
13752
13903
  getCountryByCode,
13904
+ getCountryByName,
13753
13905
  getStateByCode,
13906
+ getStateByName,
13907
+ getStatesByName,
13754
13908
  getStatesOfCountry,
13755
13909
  transformLegacyTodos,
13756
- useRufousTheme
13910
+ useCitiesSearch,
13911
+ useCountriesSearch,
13912
+ useRufousTheme,
13913
+ useStatesSearch
13757
13914
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rufous/ui",
3
3
  "private": false,
4
- "version": "0.3.19",
4
+ "version": "0.3.21",
5
5
  "type": "module",
6
6
  "description": "Experimental: A lightweight React UI component library (Beta)",
7
7
  "style": "./dist/main.css",