@rufous/ui 0.3.17 → 0.3.19

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
@@ -168,6 +168,12 @@ __export(main_exports, {
168
168
  ViewIcon: () => viewIcon_default,
169
169
  WorkItemIcon: () => workItemIcon_default,
170
170
  Zoom: () => Zoom,
171
+ getAllCountries: () => getAllCountries2,
172
+ getCitiesOfCountry: () => getCitiesOfCountry,
173
+ getCitiesOfState: () => getCitiesOfState,
174
+ getCountryByCode: () => getCountryByCode,
175
+ getStateByCode: () => getStateByCode,
176
+ getStatesOfCountry: () => getStatesOfCountry,
171
177
  transformLegacyTodos: () => transformLegacyTodos,
172
178
  useRufousTheme: () => useRufousTheme
173
179
  });
@@ -4697,7 +4703,11 @@ function DataGrid({
4697
4703
  onRowDoubleClick,
4698
4704
  onCellDoubleClick,
4699
4705
  headerActions,
4700
- toolbarContent
4706
+ toolbarContent,
4707
+ searchableColumns,
4708
+ onSearchChange,
4709
+ onFiltersChange,
4710
+ hideTopExport = false
4701
4711
  }) {
4702
4712
  const sxClass = useSx(sx);
4703
4713
  const [editingCell, setEditingCell] = (0, import_react23.useState)(null);
@@ -4802,6 +4812,9 @@ function DataGrid({
4802
4812
  return next;
4803
4813
  });
4804
4814
  }, [initialColumnsProp]);
4815
+ (0, import_react23.useEffect)(() => {
4816
+ onFiltersChange?.(advancedFilters);
4817
+ }, [advancedFilters, onFiltersChange]);
4805
4818
  const handleSort = (fieldKey, dir) => {
4806
4819
  if (dir !== void 0) {
4807
4820
  setSortField(fieldKey);
@@ -4851,10 +4864,10 @@ function DataGrid({
4851
4864
  };
4852
4865
  const filteredData = (0, import_react23.useMemo)(() => {
4853
4866
  return data.filter((item) => {
4854
- const matchesGlobal = !filterText || resolvedColumns.some((col) => {
4855
- if (col.hidden) return false;
4856
- return getDisplayValue(item, col).toLowerCase().includes(filterText.toLowerCase());
4857
- });
4867
+ const searchCols = searchableColumns ? resolvedColumns.filter((col) => searchableColumns.includes(String(col.field))) : resolvedColumns.filter((col) => !col.hidden);
4868
+ const matchesGlobal = !filterText || searchCols.some(
4869
+ (col) => getDisplayValue(item, col).toLowerCase().includes(filterText.toLowerCase())
4870
+ );
4858
4871
  const evalFilter = (f) => {
4859
4872
  if (!f.value && f.operator !== "is empty" && f.operator !== "is not empty") return true;
4860
4873
  const col = resolvedColumns.find((c) => String(c.field) === f.column || String(c.key) === f.column);
@@ -4962,7 +4975,11 @@ function DataGrid({
4962
4975
  }
4963
4976
  return matchesGlobal && matchesAdvanced;
4964
4977
  });
4965
- }, [data, filterText, advancedFilters, resolvedColumns]);
4978
+ }, [data, filterText, advancedFilters, resolvedColumns, searchableColumns]);
4979
+ (0, import_react23.useEffect)(() => {
4980
+ if (!onSearchChange || !filterText) return;
4981
+ if (filteredData.length === 0) onSearchChange(filterText);
4982
+ }, [filteredData, filterText, onSearchChange]);
4966
4983
  const sortedData = (0, import_react23.useMemo)(() => {
4967
4984
  if (!sortField || !sortDirection) return filteredData;
4968
4985
  const col = resolvedColumns.find((c) => c.field === sortField);
@@ -4993,11 +5010,16 @@ function DataGrid({
4993
5010
  (item) => exportableCols.map((c) => {
4994
5011
  const field = String(c.field);
4995
5012
  const raw = item[field];
4996
- let val = c.valueGetter ? c.valueGetter({ value: raw, row: item, field }) : raw;
4997
- if (c.valueFormatter) {
4998
- val = c.valueFormatter({ value: val, row: item, field });
5013
+ let str;
5014
+ if (c.exportValue) {
5015
+ str = c.exportValue(raw, item).replace(/"/g, '""');
5016
+ } else {
5017
+ let val = c.valueGetter ? c.valueGetter({ value: raw, row: item, field }) : raw;
5018
+ if (c.valueFormatter) {
5019
+ val = c.valueFormatter({ value: val, row: item, field });
5020
+ }
5021
+ str = val === null || val === void 0 ? "" : String(val).replace(/"/g, '""');
4999
5022
  }
5000
- const str = val === null || val === void 0 ? "" : String(val).replace(/"/g, '""');
5001
5023
  return `"${str}"`;
5002
5024
  }).join(",")
5003
5025
  );
@@ -5090,7 +5112,7 @@ function DataGrid({
5090
5112
  onClick: () => setShowManageColumns(true)
5091
5113
  },
5092
5114
  /* @__PURE__ */ import_react23.default.createElement(import_lucide_react2.Columns, { size: 16 })
5093
- )), /* @__PURE__ */ import_react23.default.createElement("button", { className: "dg-action-btn", onClick: handleExport }, /* @__PURE__ */ import_react23.default.createElement(import_lucide_react2.Download, { size: 14 }), " Export CSV"), headerActions && /* @__PURE__ */ import_react23.default.createElement("div", { className: `dg-header-slot ${alignClass(headerActions.align)}` }, headerActions.content))), /* @__PURE__ */ import_react23.default.createElement("div", { className: `dg-toolbar ${alignClass(toolbarContent?.align)}` }, toolbarContent?.content || ""), /* @__PURE__ */ import_react23.default.createElement("div", { className: `dg-table-wrap${paginatedData.length === 0 && !loading ? " dg-table-wrap--empty" : ""}` }, loading && /* @__PURE__ */ import_react23.default.createElement("div", { className: "dg-loading-overlay" }, /* @__PURE__ */ import_react23.default.createElement("div", { className: "dg-loading-spinner" })), /* @__PURE__ */ import_react23.default.createElement("table", { className: "dg-table" }, /* @__PURE__ */ import_react23.default.createElement("thead", null, /* @__PURE__ */ import_react23.default.createElement("tr", null, visibleColumns.map((col, idx) => {
5115
+ )), !hideTopExport && /* @__PURE__ */ import_react23.default.createElement("button", { className: "dg-action-btn", onClick: handleExport }, /* @__PURE__ */ import_react23.default.createElement(import_lucide_react2.Download, { size: 14 }), " Export CSV"), headerActions && /* @__PURE__ */ import_react23.default.createElement("div", { className: `dg-header-slot ${alignClass(headerActions.align)}` }, headerActions.content))), /* @__PURE__ */ import_react23.default.createElement("div", { className: `dg-toolbar ${alignClass(toolbarContent?.align)}` }, toolbarContent?.content || ""), /* @__PURE__ */ import_react23.default.createElement("div", { className: `dg-table-wrap${paginatedData.length === 0 && !loading ? " dg-table-wrap--empty" : ""}` }, loading && /* @__PURE__ */ import_react23.default.createElement("div", { className: "dg-loading-overlay" }, /* @__PURE__ */ import_react23.default.createElement("div", { className: "dg-loading-spinner" })), /* @__PURE__ */ import_react23.default.createElement("table", { className: "dg-table" }, /* @__PURE__ */ import_react23.default.createElement("thead", null, /* @__PURE__ */ import_react23.default.createElement("tr", null, visibleColumns.map((col, idx) => {
5094
5116
  const colField = String(col.field);
5095
5117
  const width = columnWidths[colField] || 200;
5096
5118
  const leftOffset = getLeftOffset(col, idx);
@@ -5111,9 +5133,8 @@ function DataGrid({
5111
5133
  onClick: () => col.sortable !== false && handleSort(col.field || "")
5112
5134
  },
5113
5135
  col.headerName,
5114
- isSorted && sortDirection === "asc" && /* @__PURE__ */ import_react23.default.createElement(import_lucide_react2.ChevronUp, { size: 12 }),
5115
- isSorted && sortDirection === "desc" && /* @__PURE__ */ import_react23.default.createElement(import_lucide_react2.ChevronDown, { size: 12 })
5116
- ), /* @__PURE__ */ import_react23.default.createElement("div", { className: `dg-th-actions${isFiltered ? " dg-th-actions--filtered" : ""}` }, isFiltered && /* @__PURE__ */ import_react23.default.createElement(import_lucide_react2.Filter, { size: 11, style: { color: "var(--primary-color)" } }), !col.disableColumnMenu && /* @__PURE__ */ import_react23.default.createElement(
5136
+ 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(
5117
5138
  "button",
5118
5139
  {
5119
5140
  className: "dg-th-menu-btn",
@@ -5205,7 +5226,7 @@ function DataGrid({
5205
5226
  },
5206
5227
  action.icon
5207
5228
  )))));
5208
- })()))))), paginatedData.length === 0 && /* @__PURE__ */ import_react23.default.createElement("div", { className: "dg-empty-state" }, /* @__PURE__ */ import_react23.default.createElement("svg", { className: "dg-empty-icon", viewBox: "0 0 200 160", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ import_react23.default.createElement("rect", { x: "20", y: "30", width: "160", height: "100", rx: "8", fill: "var(--hover-color)", stroke: "var(--border-color)", strokeWidth: "1.5" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "20", y: "30", width: "160", height: "28", rx: "8", fill: "var(--border-color)", opacity: "0.5" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "20", y: "50", width: "160", height: "8", rx: "0", fill: "var(--border-color)", opacity: "0.5" }), /* @__PURE__ */ import_react23.default.createElement("line", { x1: "72", y1: "30", x2: "72", y2: "130", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ import_react23.default.createElement("line", { x1: "128", y1: "30", x2: "128", y2: "130", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ import_react23.default.createElement("line", { x1: "20", y1: "78", x2: "180", y2: "78", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ import_react23.default.createElement("line", { x1: "20", y1: "104", x2: "180", y2: "104", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "32", y: "87", width: "28", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.4" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "84", y: "87", width: "28", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.4" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "140", y: "87", width: "28", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.4" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "32", y: "113", width: "20", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.3" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "84", y: "113", width: "32", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.3" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "140", y: "113", width: "20", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.3" }), /* @__PURE__ */ import_react23.default.createElement("circle", { cx: "148", cy: "108", r: "26", fill: "var(--surface-color)", stroke: "var(--border-color)", strokeWidth: "1.5" }), /* @__PURE__ */ import_react23.default.createElement("circle", { cx: "145", cy: "105", r: "10", stroke: "var(--text-secondary)", strokeWidth: "2.5", opacity: "0.5" }), /* @__PURE__ */ import_react23.default.createElement("line", { x1: "152", y1: "113", x2: "161", y2: "122", stroke: "var(--text-secondary)", strokeWidth: "2.5", strokeLinecap: "round", opacity: "0.5" }), /* @__PURE__ */ import_react23.default.createElement("line", { x1: "141", y1: "101", x2: "149", y2: "109", stroke: "var(--text-secondary)", strokeWidth: "2", strokeLinecap: "round", opacity: "0.5" }), /* @__PURE__ */ import_react23.default.createElement("line", { x1: "149", y1: "101", x2: "141", y2: "109", stroke: "var(--text-secondary)", strokeWidth: "2", strokeLinecap: "round", opacity: "0.5" })), /* @__PURE__ */ import_react23.default.createElement("p", { className: "dg-empty-title" }, "No data found"), /* @__PURE__ */ import_react23.default.createElement("p", { className: "dg-empty-subtitle" }, filterText || hasActiveFilters ? "Try adjusting your search or filters" : "No records to display"))), pagination && /* @__PURE__ */ import_react23.default.createElement("div", { className: "dg-pagination" }, /* @__PURE__ */ import_react23.default.createElement("div", { className: "dg-page-info" }, /* @__PURE__ */ import_react23.default.createElement("div", { className: "dg-per-page" }, /* @__PURE__ */ import_react23.default.createElement("span", null, "Rows per page:"), /* @__PURE__ */ import_react23.default.createElement(
5229
+ })()))))), paginatedData.length === 0 && /* @__PURE__ */ import_react23.default.createElement("div", { className: "dg-empty-state" }, /* @__PURE__ */ import_react23.default.createElement("svg", { className: "dg-empty-icon", viewBox: "0 0 200 160", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ import_react23.default.createElement("rect", { x: "20", y: "30", width: "160", height: "100", rx: "8", fill: "var(--hover-color)", stroke: "var(--border-color)", strokeWidth: "1.5" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "20", y: "30", width: "160", height: "28", rx: "8", fill: "var(--border-color)", opacity: "0.5" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "20", y: "50", width: "160", height: "8", rx: "0", fill: "var(--border-color)", opacity: "0.5" }), /* @__PURE__ */ import_react23.default.createElement("line", { x1: "72", y1: "30", x2: "72", y2: "130", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ import_react23.default.createElement("line", { x1: "128", y1: "30", x2: "128", y2: "130", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ import_react23.default.createElement("line", { x1: "20", y1: "78", x2: "180", y2: "78", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ import_react23.default.createElement("line", { x1: "20", y1: "104", x2: "180", y2: "104", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "32", y: "87", width: "28", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.4" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "84", y: "87", width: "28", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.4" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "140", y: "87", width: "28", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.4" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "32", y: "113", width: "20", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.3" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "84", y: "113", width: "32", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.3" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "140", y: "113", width: "20", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.3" }), /* @__PURE__ */ import_react23.default.createElement("circle", { cx: "148", cy: "108", r: "26", fill: "var(--surface-color)", stroke: "var(--border-color)", strokeWidth: "1.5" }), /* @__PURE__ */ import_react23.default.createElement("circle", { cx: "145", cy: "105", r: "10", stroke: "var(--text-secondary)", strokeWidth: "2.5", opacity: "0.5" }), /* @__PURE__ */ import_react23.default.createElement("line", { x1: "152", y1: "113", x2: "161", y2: "122", stroke: "var(--text-secondary)", strokeWidth: "2.5", strokeLinecap: "round", opacity: "0.5" }), /* @__PURE__ */ import_react23.default.createElement("line", { x1: "141", y1: "101", x2: "149", y2: "109", stroke: "var(--text-secondary)", strokeWidth: "2", strokeLinecap: "round", opacity: "0.5" }), /* @__PURE__ */ import_react23.default.createElement("line", { x1: "149", y1: "101", x2: "141", y2: "109", stroke: "var(--text-secondary)", strokeWidth: "2", strokeLinecap: "round", opacity: "0.5" })), /* @__PURE__ */ import_react23.default.createElement("p", { className: "dg-empty-title" }, "No data found"), /* @__PURE__ */ import_react23.default.createElement("p", { className: "dg-empty-subtitle" }, filterText || hasActiveFilters ? "Try adjusting your search or filters" : "No records to display"))), pagination && /* @__PURE__ */ import_react23.default.createElement("div", { className: "dg-pagination" }, /* @__PURE__ */ import_react23.default.createElement("div", { className: "dg-page-info" }, /* @__PURE__ */ import_react23.default.createElement(Tooltip, { title: "Export CSV", placement: "top" }, /* @__PURE__ */ import_react23.default.createElement("button", { className: "dg-icon-btn", onClick: handleExport }, /* @__PURE__ */ import_react23.default.createElement(import_lucide_react2.Download, { size: 14 }))), /* @__PURE__ */ import_react23.default.createElement("div", { className: "dg-per-page" }, /* @__PURE__ */ import_react23.default.createElement("span", null, "Rows per page:"), /* @__PURE__ */ import_react23.default.createElement(
5209
5230
  FilterSelect,
5210
5231
  {
5211
5232
  placement: "top",
@@ -9520,6 +9541,7 @@ function SmartSelect({
9520
9541
  value,
9521
9542
  onChange,
9522
9543
  onSearchChange,
9544
+ debounceMs = 300,
9523
9545
  getOptionLabel,
9524
9546
  getOptionValue,
9525
9547
  getOptionSubLabel,
@@ -9544,6 +9566,10 @@ function SmartSelect({
9544
9566
  style,
9545
9567
  sx
9546
9568
  }) {
9569
+ const debounceTimer = (0, import_react51.useRef)(null);
9570
+ (0, import_react51.useEffect)(() => () => {
9571
+ if (debounceTimer.current) clearTimeout(debounceTimer.current);
9572
+ }, []);
9547
9573
  const getValue = (0, import_react51.useCallback)(
9548
9574
  (o) => getOptionValue ? getOptionValue(o) : String(getOptionLabel(o)),
9549
9575
  [getOptionValue, getOptionLabel]
@@ -9570,6 +9596,7 @@ function SmartSelect({
9570
9596
  }, [multiple, value, getValue]);
9571
9597
  const handleInputChange = (0, import_react51.useCallback)((_, inputValue) => {
9572
9598
  if (!onSearchChange) return;
9599
+ if (debounceTimer.current) clearTimeout(debounceTimer.current);
9573
9600
  if (!inputValue) {
9574
9601
  onSearchChange("");
9575
9602
  return;
@@ -9577,10 +9604,15 @@ function SmartSelect({
9577
9604
  const hasLocalMatch = flatOptionsList.some(
9578
9605
  (opt) => getOptionLabel(opt).toLowerCase().includes(inputValue.toLowerCase()) || (getOptionSubLabel?.(opt) ?? "").toLowerCase().includes(inputValue.toLowerCase())
9579
9606
  );
9580
- if (!hasLocalMatch) {
9607
+ if (hasLocalMatch) return;
9608
+ if (debounceMs <= 0) {
9581
9609
  onSearchChange(inputValue);
9610
+ } else {
9611
+ debounceTimer.current = setTimeout(() => {
9612
+ onSearchChange(inputValue);
9613
+ }, debounceMs);
9582
9614
  }
9583
- }, [onSearchChange, flatOptionsList, getOptionLabel, getOptionSubLabel]);
9615
+ }, [onSearchChange, debounceMs, flatOptionsList, getOptionLabel, getOptionSubLabel]);
9584
9616
  const handleChange = (0, import_react51.useCallback)((_, newValue) => {
9585
9617
  if (!multiple || !allowChildNodesSelection || !getOptionChildren) {
9586
9618
  onChange?.(newValue);
@@ -13590,6 +13622,57 @@ var RufousTextContent = ({ content, className, style, sx }) => {
13590
13622
  }
13591
13623
  );
13592
13624
  };
13625
+
13626
+ // lib/utils/locationData.ts
13627
+ var import_country_state_city3 = require("country-state-city");
13628
+ var _stateNameCache = /* @__PURE__ */ new Map();
13629
+ function getStateNameMap(countryCode) {
13630
+ if (!_stateNameCache.has(countryCode)) {
13631
+ const map = /* @__PURE__ */ new Map();
13632
+ import_country_state_city3.State.getStatesOfCountry(countryCode).forEach((s2) => map.set(s2.isoCode, s2.name));
13633
+ _stateNameCache.set(countryCode, map);
13634
+ }
13635
+ return _stateNameCache.get(countryCode);
13636
+ }
13637
+ function getAllCountries2() {
13638
+ return import_country_state_city3.Country.getAllCountries();
13639
+ }
13640
+ function getCountryByCode(isoCode) {
13641
+ return import_country_state_city3.Country.getCountryByCode(isoCode) ?? void 0;
13642
+ }
13643
+ function getStatesOfCountry(countryCode) {
13644
+ const countryName = import_country_state_city3.Country.getCountryByCode(countryCode)?.name ?? "";
13645
+ return import_country_state_city3.State.getStatesOfCountry(countryCode).map((state) => ({
13646
+ ...state,
13647
+ countryName
13648
+ }));
13649
+ }
13650
+ function getStateByCode(stateCode, countryCode) {
13651
+ const state = import_country_state_city3.State.getStateByCodeAndCountry(stateCode, countryCode);
13652
+ if (!state) return void 0;
13653
+ const countryName = import_country_state_city3.Country.getCountryByCode(countryCode)?.name ?? "";
13654
+ return { ...state, countryName };
13655
+ }
13656
+ function getCitiesOfState(countryCode, stateCode) {
13657
+ const countryName = import_country_state_city3.Country.getCountryByCode(countryCode)?.name ?? "";
13658
+ const stateName = import_country_state_city3.State.getStateByCodeAndCountry(stateCode, countryCode)?.name ?? "";
13659
+ return import_country_state_city3.City.getCitiesOfState(countryCode, stateCode).map((city) => ({
13660
+ ...city,
13661
+ cityCode: city.name.slice(0, 3),
13662
+ countryName,
13663
+ stateName
13664
+ }));
13665
+ }
13666
+ function getCitiesOfCountry(countryCode) {
13667
+ const countryName = import_country_state_city3.Country.getCountryByCode(countryCode)?.name ?? "";
13668
+ const stateNameMap = getStateNameMap(countryCode);
13669
+ return (import_country_state_city3.City.getCitiesOfCountry(countryCode) ?? []).map((city) => ({
13670
+ ...city,
13671
+ cityCode: city.name.slice(0, 3),
13672
+ countryName,
13673
+ stateName: stateNameMap.get(city.stateCode) ?? ""
13674
+ }));
13675
+ }
13593
13676
  // Annotate the CommonJS export names for ESM import in node:
13594
13677
  0 && (module.exports = {
13595
13678
  APP_THEMES,
@@ -13731,6 +13814,12 @@ var RufousTextContent = ({ content, className, style, sx }) => {
13731
13814
  ViewIcon,
13732
13815
  WorkItemIcon,
13733
13816
  Zoom,
13817
+ getAllCountries,
13818
+ getCitiesOfCountry,
13819
+ getCitiesOfState,
13820
+ getCountryByCode,
13821
+ getStateByCode,
13822
+ getStatesOfCountry,
13734
13823
  transformLegacyTodos,
13735
13824
  useRufousTheme
13736
13825
  });
package/dist/main.css CHANGED
@@ -507,6 +507,21 @@
507
507
  .dg-th-label.no-sort {
508
508
  cursor: default;
509
509
  }
510
+ .dg-sort-icon {
511
+ display: flex;
512
+ align-items: center;
513
+ opacity: 0;
514
+ transition: opacity 0.15s;
515
+ flex-shrink: 0;
516
+ color: var(--text-secondary);
517
+ }
518
+ .dg-sort-icon--active {
519
+ opacity: 1;
520
+ color: var(--primary-color);
521
+ }
522
+ .dg-thead-cell:hover .dg-sort-icon {
523
+ opacity: 1;
524
+ }
510
525
  .dg-th-actions {
511
526
  display: flex;
512
527
  align-items: center;
@@ -534,6 +549,20 @@
534
549
  background: var(--border-color);
535
550
  color: var(--text-color);
536
551
  }
552
+ .dg-th-filter-btn {
553
+ background: none;
554
+ border: none;
555
+ cursor: pointer;
556
+ padding: 3px;
557
+ border-radius: 4px;
558
+ color: var(--primary-color);
559
+ display: flex;
560
+ align-items: center;
561
+ transition: background 0.15s;
562
+ }
563
+ .dg-th-filter-btn:hover {
564
+ background: rgba(164, 27, 6, 0.08);
565
+ }
537
566
  .dg-resizer {
538
567
  width: 4px;
539
568
  height: 16px;
package/dist/main.d.cts CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import React__default, { ReactNode, CSSProperties, InputHTMLAttributes, TextareaHTMLAttributes, ReactElement, ComponentType } from 'react';
3
+ import { ICity, ICountry, IState } from 'country-state-city';
3
4
 
4
5
  declare const APP_THEMES: {
5
6
  default: {
@@ -850,6 +851,12 @@ interface Column<T> {
850
851
  row: T;
851
852
  field: string;
852
853
  }) => string;
854
+ /**
855
+ * Override the value written to CSV export for this column.
856
+ * Receives the raw field value and the full row item.
857
+ * Takes precedence over valueGetter / valueFormatter for export purposes.
858
+ */
859
+ exportValue?: (value: any, item: T) => string;
853
860
  width?: string | number;
854
861
  minWidth?: string | number;
855
862
  maxWidth?: string | number;
@@ -875,6 +882,12 @@ interface Column<T> {
875
882
  disableColumnMenu?: boolean;
876
883
  isExportable?: boolean;
877
884
  }
885
+ interface FilterState {
886
+ column: string;
887
+ operator: string;
888
+ value: string;
889
+ logic: 'AND' | 'OR';
890
+ }
878
891
  interface Action<T> {
879
892
  label: string;
880
893
  icon: React__default.ReactNode;
@@ -932,11 +945,25 @@ interface DataGridProps<T> {
932
945
  headerActions?: DataGridToolbarSlot;
933
946
  /** Extra content rendered in a second row below the header */
934
947
  toolbarContent?: DataGridToolbarSlot;
948
+ /**
949
+ * Limit global search to these column field names.
950
+ * When omitted, all visible columns are searched.
951
+ */
952
+ searchableColumns?: string[];
953
+ /**
954
+ * Called when the search query finds no local results.
955
+ * Use this to trigger a server-side search.
956
+ */
957
+ onSearchChange?: (query: string) => void;
958
+ /** Called whenever the applied advanced filters change. */
959
+ onFiltersChange?: (filters: FilterState[]) => void;
960
+ /** Hide the "Export CSV" button in the header toolbar. */
961
+ hideTopExport?: boolean;
935
962
  }
936
963
 
937
964
  declare function DataGrid<T extends {
938
965
  id: string | number;
939
- }>({ columns: initialColumnsProp, data, actions, loading, pagination, paginationMode, rowCount, paginationModel, onPaginationModelChange, pageSize: initialPageSize, pageSizeOptions, title, className, sx, onRowDoubleClick, onCellDoubleClick, headerActions, toolbarContent, }: DataGridProps<T>): React__default.JSX.Element;
966
+ }>({ columns: initialColumnsProp, data, actions, loading, pagination, paginationMode, rowCount, paginationModel, onPaginationModelChange, pageSize: initialPageSize, pageSizeOptions, title, className, sx, onRowDoubleClick, onCellDoubleClick, headerActions, toolbarContent, searchableColumns, onSearchChange, onFiltersChange, hideTopExport, }: DataGridProps<T>): React__default.JSX.Element;
940
967
 
941
968
  type SelectOption = {
942
969
  value: string | number;
@@ -1886,6 +1913,11 @@ interface SmartSelectProps<T = any> {
1886
1913
  * use this to trigger an API / server search.
1887
1914
  */
1888
1915
  onSearchChange?: (query: string) => void;
1916
+ /**
1917
+ * Debounce delay in ms before `onSearchChange` fires.
1918
+ * Defaults to 300 ms. Pass 0 to disable debouncing.
1919
+ */
1920
+ debounceMs?: number;
1889
1921
  /** Primary display label for an option (required) */
1890
1922
  getOptionLabel: (option: T) => string;
1891
1923
  /** Unique key for an option — defaults to the label string */
@@ -1939,7 +1971,7 @@ interface SmartSelectProps<T = any> {
1939
1971
  style?: CSSProperties;
1940
1972
  sx?: SxProp;
1941
1973
  }
1942
- declare function SmartSelect<T = any>({ options, value, onChange, onSearchChange, 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;
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;
1943
1975
 
1944
1976
  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' | '|';
1945
1977
  type EditorVariant = 'default' | 'basic';
@@ -2027,4 +2059,48 @@ interface MentionItemData {
2027
2059
  shortName?: string;
2028
2060
  }
2029
2061
 
2030
- 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, 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, transformLegacyTodos, useRufousTheme };
2062
+ /** Country same shape as the library; re-exported with a typed name for convenience. */
2063
+ type EnhancedCountry = ICountry;
2064
+ /** State enriched with the full name of its parent country. */
2065
+ interface EnhancedState extends IState {
2066
+ countryName: string;
2067
+ }
2068
+ /** City enriched with a short city code and the full state + country names. */
2069
+ interface EnhancedCity extends ICity {
2070
+ /** First three characters of the city name (e.g. "Des" for "Des Moines"). */
2071
+ cityCode: string;
2072
+ /** Full name of the parent country (e.g. "United States"). */
2073
+ countryName: string;
2074
+ /** Full name of the parent state (e.g. "Iowa"). */
2075
+ stateName: string;
2076
+ }
2077
+ /** Returns all countries (same data as the library, typed as EnhancedCountry). */
2078
+ declare function getAllCountries(): EnhancedCountry[];
2079
+ /** Returns a single country by its ISO 2-letter code, or undefined if not found. */
2080
+ declare function getCountryByCode(isoCode: string): EnhancedCountry | undefined;
2081
+ /**
2082
+ * Returns all states for a country, each enriched with `countryName`.
2083
+ * @param countryCode ISO 2-letter country code, e.g. "US"
2084
+ */
2085
+ declare function getStatesOfCountry(countryCode: string): EnhancedState[];
2086
+ /**
2087
+ * Returns a single state by its code + parent country, enriched with `countryName`.
2088
+ * @param stateCode ISO state code, e.g. "IA"
2089
+ * @param countryCode ISO 2-letter country code, e.g. "US"
2090
+ */
2091
+ declare function getStateByCode(stateCode: string, countryCode: string): EnhancedState | undefined;
2092
+ /**
2093
+ * Returns all cities for a given state, each enriched with `cityCode`, `countryName`,
2094
+ * and `stateName`.
2095
+ * @param countryCode ISO 2-letter country code, e.g. "US"
2096
+ * @param stateCode ISO state code, e.g. "IA"
2097
+ */
2098
+ declare function getCitiesOfState(countryCode: string, stateCode: string): EnhancedCity[];
2099
+ /**
2100
+ * Returns all cities for a given country, each enriched with `cityCode`, `countryName`,
2101
+ * and `stateName`.
2102
+ * @param countryCode ISO 2-letter country code, e.g. "US"
2103
+ */
2104
+ declare function getCitiesOfCountry(countryCode: string): EnhancedCity[];
2105
+
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 };
package/dist/main.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import React__default, { ReactNode, CSSProperties, InputHTMLAttributes, TextareaHTMLAttributes, ReactElement, ComponentType } from 'react';
3
+ import { ICity, ICountry, IState } from 'country-state-city';
3
4
 
4
5
  declare const APP_THEMES: {
5
6
  default: {
@@ -850,6 +851,12 @@ interface Column<T> {
850
851
  row: T;
851
852
  field: string;
852
853
  }) => string;
854
+ /**
855
+ * Override the value written to CSV export for this column.
856
+ * Receives the raw field value and the full row item.
857
+ * Takes precedence over valueGetter / valueFormatter for export purposes.
858
+ */
859
+ exportValue?: (value: any, item: T) => string;
853
860
  width?: string | number;
854
861
  minWidth?: string | number;
855
862
  maxWidth?: string | number;
@@ -875,6 +882,12 @@ interface Column<T> {
875
882
  disableColumnMenu?: boolean;
876
883
  isExportable?: boolean;
877
884
  }
885
+ interface FilterState {
886
+ column: string;
887
+ operator: string;
888
+ value: string;
889
+ logic: 'AND' | 'OR';
890
+ }
878
891
  interface Action<T> {
879
892
  label: string;
880
893
  icon: React__default.ReactNode;
@@ -932,11 +945,25 @@ interface DataGridProps<T> {
932
945
  headerActions?: DataGridToolbarSlot;
933
946
  /** Extra content rendered in a second row below the header */
934
947
  toolbarContent?: DataGridToolbarSlot;
948
+ /**
949
+ * Limit global search to these column field names.
950
+ * When omitted, all visible columns are searched.
951
+ */
952
+ searchableColumns?: string[];
953
+ /**
954
+ * Called when the search query finds no local results.
955
+ * Use this to trigger a server-side search.
956
+ */
957
+ onSearchChange?: (query: string) => void;
958
+ /** Called whenever the applied advanced filters change. */
959
+ onFiltersChange?: (filters: FilterState[]) => void;
960
+ /** Hide the "Export CSV" button in the header toolbar. */
961
+ hideTopExport?: boolean;
935
962
  }
936
963
 
937
964
  declare function DataGrid<T extends {
938
965
  id: string | number;
939
- }>({ columns: initialColumnsProp, data, actions, loading, pagination, paginationMode, rowCount, paginationModel, onPaginationModelChange, pageSize: initialPageSize, pageSizeOptions, title, className, sx, onRowDoubleClick, onCellDoubleClick, headerActions, toolbarContent, }: DataGridProps<T>): React__default.JSX.Element;
966
+ }>({ columns: initialColumnsProp, data, actions, loading, pagination, paginationMode, rowCount, paginationModel, onPaginationModelChange, pageSize: initialPageSize, pageSizeOptions, title, className, sx, onRowDoubleClick, onCellDoubleClick, headerActions, toolbarContent, searchableColumns, onSearchChange, onFiltersChange, hideTopExport, }: DataGridProps<T>): React__default.JSX.Element;
940
967
 
941
968
  type SelectOption = {
942
969
  value: string | number;
@@ -1886,6 +1913,11 @@ interface SmartSelectProps<T = any> {
1886
1913
  * use this to trigger an API / server search.
1887
1914
  */
1888
1915
  onSearchChange?: (query: string) => void;
1916
+ /**
1917
+ * Debounce delay in ms before `onSearchChange` fires.
1918
+ * Defaults to 300 ms. Pass 0 to disable debouncing.
1919
+ */
1920
+ debounceMs?: number;
1889
1921
  /** Primary display label for an option (required) */
1890
1922
  getOptionLabel: (option: T) => string;
1891
1923
  /** Unique key for an option — defaults to the label string */
@@ -1939,7 +1971,7 @@ interface SmartSelectProps<T = any> {
1939
1971
  style?: CSSProperties;
1940
1972
  sx?: SxProp;
1941
1973
  }
1942
- declare function SmartSelect<T = any>({ options, value, onChange, onSearchChange, 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;
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;
1943
1975
 
1944
1976
  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' | '|';
1945
1977
  type EditorVariant = 'default' | 'basic';
@@ -2027,4 +2059,48 @@ interface MentionItemData {
2027
2059
  shortName?: string;
2028
2060
  }
2029
2061
 
2030
- 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, 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, transformLegacyTodos, useRufousTheme };
2062
+ /** Country same shape as the library; re-exported with a typed name for convenience. */
2063
+ type EnhancedCountry = ICountry;
2064
+ /** State enriched with the full name of its parent country. */
2065
+ interface EnhancedState extends IState {
2066
+ countryName: string;
2067
+ }
2068
+ /** City enriched with a short city code and the full state + country names. */
2069
+ interface EnhancedCity extends ICity {
2070
+ /** First three characters of the city name (e.g. "Des" for "Des Moines"). */
2071
+ cityCode: string;
2072
+ /** Full name of the parent country (e.g. "United States"). */
2073
+ countryName: string;
2074
+ /** Full name of the parent state (e.g. "Iowa"). */
2075
+ stateName: string;
2076
+ }
2077
+ /** Returns all countries (same data as the library, typed as EnhancedCountry). */
2078
+ declare function getAllCountries(): EnhancedCountry[];
2079
+ /** Returns a single country by its ISO 2-letter code, or undefined if not found. */
2080
+ declare function getCountryByCode(isoCode: string): EnhancedCountry | undefined;
2081
+ /**
2082
+ * Returns all states for a country, each enriched with `countryName`.
2083
+ * @param countryCode ISO 2-letter country code, e.g. "US"
2084
+ */
2085
+ declare function getStatesOfCountry(countryCode: string): EnhancedState[];
2086
+ /**
2087
+ * Returns a single state by its code + parent country, enriched with `countryName`.
2088
+ * @param stateCode ISO state code, e.g. "IA"
2089
+ * @param countryCode ISO 2-letter country code, e.g. "US"
2090
+ */
2091
+ declare function getStateByCode(stateCode: string, countryCode: string): EnhancedState | undefined;
2092
+ /**
2093
+ * Returns all cities for a given state, each enriched with `cityCode`, `countryName`,
2094
+ * and `stateName`.
2095
+ * @param countryCode ISO 2-letter country code, e.g. "US"
2096
+ * @param stateCode ISO state code, e.g. "IA"
2097
+ */
2098
+ declare function getCitiesOfState(countryCode: string, stateCode: string): EnhancedCity[];
2099
+ /**
2100
+ * Returns all cities for a given country, each enriched with `cityCode`, `countryName`,
2101
+ * and `stateName`.
2102
+ * @param countryCode ISO 2-letter country code, e.g. "US"
2103
+ */
2104
+ declare function getCitiesOfCountry(countryCode: string): EnhancedCity[];
2105
+
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 };
package/dist/main.js CHANGED
@@ -4471,7 +4471,8 @@ import {
4471
4471
  ArrowUp,
4472
4472
  ArrowDown,
4473
4473
  Trash2,
4474
- Plus
4474
+ Plus,
4475
+ ChevronsUpDown
4475
4476
  } from "lucide-react";
4476
4477
  function FilterSelect({
4477
4478
  value,
@@ -4566,7 +4567,11 @@ function DataGrid({
4566
4567
  onRowDoubleClick,
4567
4568
  onCellDoubleClick,
4568
4569
  headerActions,
4569
- toolbarContent
4570
+ toolbarContent,
4571
+ searchableColumns,
4572
+ onSearchChange,
4573
+ onFiltersChange,
4574
+ hideTopExport = false
4570
4575
  }) {
4571
4576
  const sxClass = useSx(sx);
4572
4577
  const [editingCell, setEditingCell] = useState9(null);
@@ -4671,6 +4676,9 @@ function DataGrid({
4671
4676
  return next;
4672
4677
  });
4673
4678
  }, [initialColumnsProp]);
4679
+ useEffect9(() => {
4680
+ onFiltersChange?.(advancedFilters);
4681
+ }, [advancedFilters, onFiltersChange]);
4674
4682
  const handleSort = (fieldKey, dir) => {
4675
4683
  if (dir !== void 0) {
4676
4684
  setSortField(fieldKey);
@@ -4720,10 +4728,10 @@ function DataGrid({
4720
4728
  };
4721
4729
  const filteredData = useMemo2(() => {
4722
4730
  return data.filter((item) => {
4723
- const matchesGlobal = !filterText || resolvedColumns.some((col) => {
4724
- if (col.hidden) return false;
4725
- return getDisplayValue(item, col).toLowerCase().includes(filterText.toLowerCase());
4726
- });
4731
+ const searchCols = searchableColumns ? resolvedColumns.filter((col) => searchableColumns.includes(String(col.field))) : resolvedColumns.filter((col) => !col.hidden);
4732
+ const matchesGlobal = !filterText || searchCols.some(
4733
+ (col) => getDisplayValue(item, col).toLowerCase().includes(filterText.toLowerCase())
4734
+ );
4727
4735
  const evalFilter = (f) => {
4728
4736
  if (!f.value && f.operator !== "is empty" && f.operator !== "is not empty") return true;
4729
4737
  const col = resolvedColumns.find((c) => String(c.field) === f.column || String(c.key) === f.column);
@@ -4831,7 +4839,11 @@ function DataGrid({
4831
4839
  }
4832
4840
  return matchesGlobal && matchesAdvanced;
4833
4841
  });
4834
- }, [data, filterText, advancedFilters, resolvedColumns]);
4842
+ }, [data, filterText, advancedFilters, resolvedColumns, searchableColumns]);
4843
+ useEffect9(() => {
4844
+ if (!onSearchChange || !filterText) return;
4845
+ if (filteredData.length === 0) onSearchChange(filterText);
4846
+ }, [filteredData, filterText, onSearchChange]);
4835
4847
  const sortedData = useMemo2(() => {
4836
4848
  if (!sortField || !sortDirection) return filteredData;
4837
4849
  const col = resolvedColumns.find((c) => c.field === sortField);
@@ -4862,11 +4874,16 @@ function DataGrid({
4862
4874
  (item) => exportableCols.map((c) => {
4863
4875
  const field = String(c.field);
4864
4876
  const raw = item[field];
4865
- let val = c.valueGetter ? c.valueGetter({ value: raw, row: item, field }) : raw;
4866
- if (c.valueFormatter) {
4867
- val = c.valueFormatter({ value: val, row: item, field });
4877
+ let str;
4878
+ if (c.exportValue) {
4879
+ str = c.exportValue(raw, item).replace(/"/g, '""');
4880
+ } else {
4881
+ let val = c.valueGetter ? c.valueGetter({ value: raw, row: item, field }) : raw;
4882
+ if (c.valueFormatter) {
4883
+ val = c.valueFormatter({ value: val, row: item, field });
4884
+ }
4885
+ str = val === null || val === void 0 ? "" : String(val).replace(/"/g, '""');
4868
4886
  }
4869
- const str = val === null || val === void 0 ? "" : String(val).replace(/"/g, '""');
4870
4887
  return `"${str}"`;
4871
4888
  }).join(",")
4872
4889
  );
@@ -4959,7 +4976,7 @@ function DataGrid({
4959
4976
  onClick: () => setShowManageColumns(true)
4960
4977
  },
4961
4978
  /* @__PURE__ */ React75.createElement(Columns, { size: 16 })
4962
- )), /* @__PURE__ */ React75.createElement("button", { className: "dg-action-btn", onClick: handleExport }, /* @__PURE__ */ React75.createElement(Download, { size: 14 }), " Export CSV"), headerActions && /* @__PURE__ */ React75.createElement("div", { className: `dg-header-slot ${alignClass(headerActions.align)}` }, headerActions.content))), /* @__PURE__ */ React75.createElement("div", { className: `dg-toolbar ${alignClass(toolbarContent?.align)}` }, toolbarContent?.content || ""), /* @__PURE__ */ React75.createElement("div", { className: `dg-table-wrap${paginatedData.length === 0 && !loading ? " dg-table-wrap--empty" : ""}` }, loading && /* @__PURE__ */ React75.createElement("div", { className: "dg-loading-overlay" }, /* @__PURE__ */ React75.createElement("div", { className: "dg-loading-spinner" })), /* @__PURE__ */ React75.createElement("table", { className: "dg-table" }, /* @__PURE__ */ React75.createElement("thead", null, /* @__PURE__ */ React75.createElement("tr", null, visibleColumns.map((col, idx) => {
4979
+ )), !hideTopExport && /* @__PURE__ */ React75.createElement("button", { className: "dg-action-btn", onClick: handleExport }, /* @__PURE__ */ React75.createElement(Download, { size: 14 }), " Export CSV"), headerActions && /* @__PURE__ */ React75.createElement("div", { className: `dg-header-slot ${alignClass(headerActions.align)}` }, headerActions.content))), /* @__PURE__ */ React75.createElement("div", { className: `dg-toolbar ${alignClass(toolbarContent?.align)}` }, toolbarContent?.content || ""), /* @__PURE__ */ React75.createElement("div", { className: `dg-table-wrap${paginatedData.length === 0 && !loading ? " dg-table-wrap--empty" : ""}` }, loading && /* @__PURE__ */ React75.createElement("div", { className: "dg-loading-overlay" }, /* @__PURE__ */ React75.createElement("div", { className: "dg-loading-spinner" })), /* @__PURE__ */ React75.createElement("table", { className: "dg-table" }, /* @__PURE__ */ React75.createElement("thead", null, /* @__PURE__ */ React75.createElement("tr", null, visibleColumns.map((col, idx) => {
4963
4980
  const colField = String(col.field);
4964
4981
  const width = columnWidths[colField] || 200;
4965
4982
  const leftOffset = getLeftOffset(col, idx);
@@ -4980,9 +4997,8 @@ function DataGrid({
4980
4997
  onClick: () => col.sortable !== false && handleSort(col.field || "")
4981
4998
  },
4982
4999
  col.headerName,
4983
- isSorted && sortDirection === "asc" && /* @__PURE__ */ React75.createElement(ChevronUp, { size: 12 }),
4984
- isSorted && sortDirection === "desc" && /* @__PURE__ */ React75.createElement(ChevronDown, { size: 12 })
4985
- ), /* @__PURE__ */ React75.createElement("div", { className: `dg-th-actions${isFiltered ? " dg-th-actions--filtered" : ""}` }, isFiltered && /* @__PURE__ */ React75.createElement(Filter, { size: 11, style: { color: "var(--primary-color)" } }), !col.disableColumnMenu && /* @__PURE__ */ React75.createElement(
5000
+ 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(
4986
5002
  "button",
4987
5003
  {
4988
5004
  className: "dg-th-menu-btn",
@@ -5074,7 +5090,7 @@ function DataGrid({
5074
5090
  },
5075
5091
  action.icon
5076
5092
  )))));
5077
- })()))))), paginatedData.length === 0 && /* @__PURE__ */ React75.createElement("div", { className: "dg-empty-state" }, /* @__PURE__ */ React75.createElement("svg", { className: "dg-empty-icon", viewBox: "0 0 200 160", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ React75.createElement("rect", { x: "20", y: "30", width: "160", height: "100", rx: "8", fill: "var(--hover-color)", stroke: "var(--border-color)", strokeWidth: "1.5" }), /* @__PURE__ */ React75.createElement("rect", { x: "20", y: "30", width: "160", height: "28", rx: "8", fill: "var(--border-color)", opacity: "0.5" }), /* @__PURE__ */ React75.createElement("rect", { x: "20", y: "50", width: "160", height: "8", rx: "0", fill: "var(--border-color)", opacity: "0.5" }), /* @__PURE__ */ React75.createElement("line", { x1: "72", y1: "30", x2: "72", y2: "130", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ React75.createElement("line", { x1: "128", y1: "30", x2: "128", y2: "130", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ React75.createElement("line", { x1: "20", y1: "78", x2: "180", y2: "78", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ React75.createElement("line", { x1: "20", y1: "104", x2: "180", y2: "104", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ React75.createElement("rect", { x: "32", y: "87", width: "28", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.4" }), /* @__PURE__ */ React75.createElement("rect", { x: "84", y: "87", width: "28", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.4" }), /* @__PURE__ */ React75.createElement("rect", { x: "140", y: "87", width: "28", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.4" }), /* @__PURE__ */ React75.createElement("rect", { x: "32", y: "113", width: "20", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.3" }), /* @__PURE__ */ React75.createElement("rect", { x: "84", y: "113", width: "32", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.3" }), /* @__PURE__ */ React75.createElement("rect", { x: "140", y: "113", width: "20", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.3" }), /* @__PURE__ */ React75.createElement("circle", { cx: "148", cy: "108", r: "26", fill: "var(--surface-color)", stroke: "var(--border-color)", strokeWidth: "1.5" }), /* @__PURE__ */ React75.createElement("circle", { cx: "145", cy: "105", r: "10", stroke: "var(--text-secondary)", strokeWidth: "2.5", opacity: "0.5" }), /* @__PURE__ */ React75.createElement("line", { x1: "152", y1: "113", x2: "161", y2: "122", stroke: "var(--text-secondary)", strokeWidth: "2.5", strokeLinecap: "round", opacity: "0.5" }), /* @__PURE__ */ React75.createElement("line", { x1: "141", y1: "101", x2: "149", y2: "109", stroke: "var(--text-secondary)", strokeWidth: "2", strokeLinecap: "round", opacity: "0.5" }), /* @__PURE__ */ React75.createElement("line", { x1: "149", y1: "101", x2: "141", y2: "109", stroke: "var(--text-secondary)", strokeWidth: "2", strokeLinecap: "round", opacity: "0.5" })), /* @__PURE__ */ React75.createElement("p", { className: "dg-empty-title" }, "No data found"), /* @__PURE__ */ React75.createElement("p", { className: "dg-empty-subtitle" }, filterText || hasActiveFilters ? "Try adjusting your search or filters" : "No records to display"))), pagination && /* @__PURE__ */ React75.createElement("div", { className: "dg-pagination" }, /* @__PURE__ */ React75.createElement("div", { className: "dg-page-info" }, /* @__PURE__ */ React75.createElement("div", { className: "dg-per-page" }, /* @__PURE__ */ React75.createElement("span", null, "Rows per page:"), /* @__PURE__ */ React75.createElement(
5093
+ })()))))), paginatedData.length === 0 && /* @__PURE__ */ React75.createElement("div", { className: "dg-empty-state" }, /* @__PURE__ */ React75.createElement("svg", { className: "dg-empty-icon", viewBox: "0 0 200 160", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ React75.createElement("rect", { x: "20", y: "30", width: "160", height: "100", rx: "8", fill: "var(--hover-color)", stroke: "var(--border-color)", strokeWidth: "1.5" }), /* @__PURE__ */ React75.createElement("rect", { x: "20", y: "30", width: "160", height: "28", rx: "8", fill: "var(--border-color)", opacity: "0.5" }), /* @__PURE__ */ React75.createElement("rect", { x: "20", y: "50", width: "160", height: "8", rx: "0", fill: "var(--border-color)", opacity: "0.5" }), /* @__PURE__ */ React75.createElement("line", { x1: "72", y1: "30", x2: "72", y2: "130", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ React75.createElement("line", { x1: "128", y1: "30", x2: "128", y2: "130", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ React75.createElement("line", { x1: "20", y1: "78", x2: "180", y2: "78", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ React75.createElement("line", { x1: "20", y1: "104", x2: "180", y2: "104", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ React75.createElement("rect", { x: "32", y: "87", width: "28", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.4" }), /* @__PURE__ */ React75.createElement("rect", { x: "84", y: "87", width: "28", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.4" }), /* @__PURE__ */ React75.createElement("rect", { x: "140", y: "87", width: "28", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.4" }), /* @__PURE__ */ React75.createElement("rect", { x: "32", y: "113", width: "20", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.3" }), /* @__PURE__ */ React75.createElement("rect", { x: "84", y: "113", width: "32", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.3" }), /* @__PURE__ */ React75.createElement("rect", { x: "140", y: "113", width: "20", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.3" }), /* @__PURE__ */ React75.createElement("circle", { cx: "148", cy: "108", r: "26", fill: "var(--surface-color)", stroke: "var(--border-color)", strokeWidth: "1.5" }), /* @__PURE__ */ React75.createElement("circle", { cx: "145", cy: "105", r: "10", stroke: "var(--text-secondary)", strokeWidth: "2.5", opacity: "0.5" }), /* @__PURE__ */ React75.createElement("line", { x1: "152", y1: "113", x2: "161", y2: "122", stroke: "var(--text-secondary)", strokeWidth: "2.5", strokeLinecap: "round", opacity: "0.5" }), /* @__PURE__ */ React75.createElement("line", { x1: "141", y1: "101", x2: "149", y2: "109", stroke: "var(--text-secondary)", strokeWidth: "2", strokeLinecap: "round", opacity: "0.5" }), /* @__PURE__ */ React75.createElement("line", { x1: "149", y1: "101", x2: "141", y2: "109", stroke: "var(--text-secondary)", strokeWidth: "2", strokeLinecap: "round", opacity: "0.5" })), /* @__PURE__ */ React75.createElement("p", { className: "dg-empty-title" }, "No data found"), /* @__PURE__ */ React75.createElement("p", { className: "dg-empty-subtitle" }, filterText || hasActiveFilters ? "Try adjusting your search or filters" : "No records to display"))), pagination && /* @__PURE__ */ React75.createElement("div", { className: "dg-pagination" }, /* @__PURE__ */ React75.createElement("div", { className: "dg-page-info" }, /* @__PURE__ */ React75.createElement(Tooltip, { title: "Export CSV", placement: "top" }, /* @__PURE__ */ React75.createElement("button", { className: "dg-icon-btn", onClick: handleExport }, /* @__PURE__ */ React75.createElement(Download, { size: 14 }))), /* @__PURE__ */ React75.createElement("div", { className: "dg-per-page" }, /* @__PURE__ */ React75.createElement("span", null, "Rows per page:"), /* @__PURE__ */ React75.createElement(
5078
5094
  FilterSelect,
5079
5095
  {
5080
5096
  placement: "top",
@@ -9433,7 +9449,7 @@ function UserSelectionField({
9433
9449
  }
9434
9450
 
9435
9451
  // lib/SmartSelect/SmartSelect.tsx
9436
- import React108, { useCallback as useCallback11, useMemo as useMemo3 } from "react";
9452
+ import React108, { useCallback as useCallback11, useEffect as useEffect21, useMemo as useMemo3, useRef as useRef25 } from "react";
9437
9453
  var CheckIcon3 = () => /* @__PURE__ */ React108.createElement("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React108.createElement("polyline", { points: "20 6 9 17 4 12" }));
9438
9454
  function flattenTree(options, getChildren, depth = 0) {
9439
9455
  return options.flatMap((opt) => [
@@ -9458,6 +9474,7 @@ function SmartSelect({
9458
9474
  value,
9459
9475
  onChange,
9460
9476
  onSearchChange,
9477
+ debounceMs = 300,
9461
9478
  getOptionLabel,
9462
9479
  getOptionValue,
9463
9480
  getOptionSubLabel,
@@ -9482,6 +9499,10 @@ function SmartSelect({
9482
9499
  style,
9483
9500
  sx
9484
9501
  }) {
9502
+ const debounceTimer = useRef25(null);
9503
+ useEffect21(() => () => {
9504
+ if (debounceTimer.current) clearTimeout(debounceTimer.current);
9505
+ }, []);
9485
9506
  const getValue = useCallback11(
9486
9507
  (o) => getOptionValue ? getOptionValue(o) : String(getOptionLabel(o)),
9487
9508
  [getOptionValue, getOptionLabel]
@@ -9508,6 +9529,7 @@ function SmartSelect({
9508
9529
  }, [multiple, value, getValue]);
9509
9530
  const handleInputChange = useCallback11((_, inputValue) => {
9510
9531
  if (!onSearchChange) return;
9532
+ if (debounceTimer.current) clearTimeout(debounceTimer.current);
9511
9533
  if (!inputValue) {
9512
9534
  onSearchChange("");
9513
9535
  return;
@@ -9515,10 +9537,15 @@ function SmartSelect({
9515
9537
  const hasLocalMatch = flatOptionsList.some(
9516
9538
  (opt) => getOptionLabel(opt).toLowerCase().includes(inputValue.toLowerCase()) || (getOptionSubLabel?.(opt) ?? "").toLowerCase().includes(inputValue.toLowerCase())
9517
9539
  );
9518
- if (!hasLocalMatch) {
9540
+ if (hasLocalMatch) return;
9541
+ if (debounceMs <= 0) {
9519
9542
  onSearchChange(inputValue);
9543
+ } else {
9544
+ debounceTimer.current = setTimeout(() => {
9545
+ onSearchChange(inputValue);
9546
+ }, debounceMs);
9520
9547
  }
9521
- }, [onSearchChange, flatOptionsList, getOptionLabel, getOptionSubLabel]);
9548
+ }, [onSearchChange, debounceMs, flatOptionsList, getOptionLabel, getOptionSubLabel]);
9522
9549
  const handleChange = useCallback11((_, newValue) => {
9523
9550
  if (!multiple || !allowChildNodesSelection || !getOptionChildren) {
9524
9551
  onChange?.(newValue);
@@ -9658,7 +9685,7 @@ function SmartSelect({
9658
9685
  }
9659
9686
 
9660
9687
  // lib/RufousTextEditor/RufousTextEditor.tsx
9661
- import React119, { useMemo as useMemo5, useCallback as useCallback16, useState as useState35, useRef as useRef32, useEffect as useEffect29 } from "react";
9688
+ import React119, { useMemo as useMemo5, useCallback as useCallback16, useState as useState35, useRef as useRef33, useEffect as useEffect30 } from "react";
9662
9689
  import { createPortal as createPortal8 } from "react-dom";
9663
9690
  import { useEditor, EditorContent, EditorContext, FloatingMenu, BubbleMenu } from "@tiptap/react";
9664
9691
  import StarterKit from "@tiptap/starter-kit";
@@ -9684,7 +9711,7 @@ import { ReactRenderer } from "@tiptap/react";
9684
9711
  import tippy from "tippy.js";
9685
9712
 
9686
9713
  // lib/RufousTextEditor/MentionList.tsx
9687
- import React109, { forwardRef as forwardRef11, useEffect as useEffect21, useImperativeHandle, useState as useState26 } from "react";
9714
+ import React109, { forwardRef as forwardRef11, useEffect as useEffect22, useImperativeHandle, useState as useState26 } from "react";
9688
9715
  var MentionList = forwardRef11((props, ref) => {
9689
9716
  const [selectedIndex, setSelectedIndex] = useState26(0);
9690
9717
  const selectItem = (index) => {
@@ -9693,7 +9720,7 @@ var MentionList = forwardRef11((props, ref) => {
9693
9720
  props.command({ id: item.id, label: item.shortName || item.name });
9694
9721
  }
9695
9722
  };
9696
- useEffect21(() => setSelectedIndex(0), [props.items]);
9723
+ useEffect22(() => setSelectedIndex(0), [props.items]);
9697
9724
  useImperativeHandle(ref, () => ({
9698
9725
  onKeyDown: ({ event }) => {
9699
9726
  if (event.key === "ArrowUp") {
@@ -9780,11 +9807,11 @@ function createMentionSuggestion(users) {
9780
9807
  }
9781
9808
 
9782
9809
  // lib/RufousTextEditor/Toolbar.tsx
9783
- import React115, { useState as useState31, useRef as useRef28, useEffect as useEffect25, useCallback as useCallback15 } from "react";
9810
+ import React115, { useState as useState31, useRef as useRef29, useEffect as useEffect26, useCallback as useCallback15 } from "react";
9784
9811
  import { createPortal as createPortal4 } from "react-dom";
9785
9812
 
9786
9813
  // lib/RufousTextEditor/TextToSpeech.tsx
9787
- import React110, { useState as useState27, useEffect as useEffect22, useRef as useRef25, useCallback as useCallback12, forwardRef as forwardRef12, useImperativeHandle as useImperativeHandle2 } from "react";
9814
+ import React110, { useState as useState27, useEffect as useEffect23, useRef as useRef26, useCallback as useCallback12, forwardRef as forwardRef12, useImperativeHandle as useImperativeHandle2 } from "react";
9788
9815
  var TextToSpeech = forwardRef12(({ editor, onTextToSpeech }, ref) => {
9789
9816
  const [speaking, setSpeaking] = useState27(false);
9790
9817
  const [paused, setPaused] = useState27(false);
@@ -9792,9 +9819,9 @@ var TextToSpeech = forwardRef12(({ editor, onTextToSpeech }, ref) => {
9792
9819
  const [selectedVoice, setSelectedVoice] = useState27("");
9793
9820
  const [rate, setRate] = useState27(1);
9794
9821
  const [showPanel, setShowPanel] = useState27(false);
9795
- const utteranceRef = useRef25(null);
9796
- const panelRef = useRef25(null);
9797
- useEffect22(() => {
9822
+ const utteranceRef = useRef26(null);
9823
+ const panelRef = useRef26(null);
9824
+ useEffect23(() => {
9798
9825
  const synth = window.speechSynthesis;
9799
9826
  const loadVoices = () => {
9800
9827
  const available = synth.getVoices();
@@ -9812,7 +9839,7 @@ var TextToSpeech = forwardRef12(({ editor, onTextToSpeech }, ref) => {
9812
9839
  synth.removeEventListener("voiceschanged", loadVoices);
9813
9840
  };
9814
9841
  }, [selectedVoice]);
9815
- useEffect22(() => {
9842
+ useEffect23(() => {
9816
9843
  const handleClick = (e) => {
9817
9844
  if (panelRef.current && !panelRef.current.contains(e.target)) {
9818
9845
  setShowPanel(false);
@@ -9929,18 +9956,18 @@ var TextToSpeech = forwardRef12(({ editor, onTextToSpeech }, ref) => {
9929
9956
  var TextToSpeech_default = TextToSpeech;
9930
9957
 
9931
9958
  // lib/RufousTextEditor/SpeechToText.tsx
9932
- import React111, { useState as useState28, useRef as useRef26, useCallback as useCallback13, useEffect as useEffect23, forwardRef as forwardRef13, useImperativeHandle as useImperativeHandle3 } from "react";
9959
+ import React111, { useState as useState28, useRef as useRef27, useCallback as useCallback13, useEffect as useEffect24, forwardRef as forwardRef13, useImperativeHandle as useImperativeHandle3 } from "react";
9933
9960
  var SpeechToText = forwardRef13(({ editor, onSpeechToText }, ref) => {
9934
9961
  const [listening, setListening] = useState28(false);
9935
9962
  const [showPanel, setShowPanel] = useState28(false);
9936
9963
  const [language, setLanguage] = useState28("en-US");
9937
9964
  const [interim, setInterim] = useState28("");
9938
- const recognitionRef = useRef26(null);
9939
- const panelRef = useRef26(null);
9940
- const isListeningRef = useRef26(false);
9965
+ const recognitionRef = useRef27(null);
9966
+ const panelRef = useRef27(null);
9967
+ const isListeningRef = useRef27(false);
9941
9968
  const SpeechRecognitionAPI = typeof window !== "undefined" ? window.SpeechRecognition || window.webkitSpeechRecognition : null;
9942
9969
  const supported = !!SpeechRecognitionAPI;
9943
- useEffect23(() => {
9970
+ useEffect24(() => {
9944
9971
  const handleClick = (e) => {
9945
9972
  if (panelRef.current && !panelRef.current.contains(e.target)) {
9946
9973
  setShowPanel(false);
@@ -10091,7 +10118,7 @@ var SpeechToText = forwardRef13(({ editor, onSpeechToText }, ref) => {
10091
10118
  var SpeechToText_default = SpeechToText;
10092
10119
 
10093
10120
  // lib/RufousTextEditor/AICommands.tsx
10094
- import React112, { useState as useState29, useRef as useRef27, useEffect as useEffect24, useCallback as useCallback14 } from "react";
10121
+ import React112, { useState as useState29, useRef as useRef28, useEffect as useEffect25, useCallback as useCallback14 } from "react";
10095
10122
  import { createPortal as createPortal2 } from "react-dom";
10096
10123
  var AI_COMMANDS = [
10097
10124
  { id: "improve", label: "Improve writing", prompt: "Improve the following text to make it clearer, more engaging, and well-structured. Return only the improved text, no explanations." },
@@ -10147,8 +10174,8 @@ var AICommands = ({ editor, onAICommand }) => {
10147
10174
  const [originalText, setOriginalText] = useState29("");
10148
10175
  const [selectionRange, setSelectionRange] = useState29(null);
10149
10176
  const [previousResults, setPreviousResults] = useState29([]);
10150
- const panelRef = useRef27(null);
10151
- useEffect24(() => {
10177
+ const panelRef = useRef28(null);
10178
+ useEffect25(() => {
10152
10179
  const handleClick = (e) => {
10153
10180
  if (panelRef.current && !panelRef.current.contains(e.target)) {
10154
10181
  setOpen(false);
@@ -11346,9 +11373,9 @@ var SPECIAL_CHARS = [
11346
11373
  ];
11347
11374
  var Dropdown = ({ trigger, children, className = "", keepOpen = false }) => {
11348
11375
  const [open, setOpen] = useState31(false);
11349
- const ref = useRef28(null);
11350
- const menuRef = useRef28(null);
11351
- useEffect25(() => {
11376
+ const ref = useRef29(null);
11377
+ const menuRef = useRef29(null);
11378
+ useEffect26(() => {
11352
11379
  const handleClick = (e) => {
11353
11380
  const target = e.target;
11354
11381
  const inTrigger = ref.current?.contains(target);
@@ -11360,7 +11387,7 @@ var Dropdown = ({ trigger, children, className = "", keepOpen = false }) => {
11360
11387
  document.addEventListener("mousedown", handleClick);
11361
11388
  return () => document.removeEventListener("mousedown", handleClick);
11362
11389
  }, []);
11363
- useEffect25(() => {
11390
+ useEffect26(() => {
11364
11391
  if (!open || !menuRef.current || !ref.current) return;
11365
11392
  const menu = menuRef.current;
11366
11393
  const trigger2 = ref.current;
@@ -11477,7 +11504,7 @@ var ImagePanel = ({ editor, onClose, onImageUpload }) => {
11477
11504
  const [activeTab, setActiveTab] = useState31("upload");
11478
11505
  const [url, setUrl] = useState31("");
11479
11506
  const [isDragging, setIsDragging] = useState31(false);
11480
- const fileInputRef = useRef28(null);
11507
+ const fileInputRef = useRef29(null);
11481
11508
  const getBase64 = (file) => {
11482
11509
  return new Promise((resolve, reject) => {
11483
11510
  const reader = new FileReader();
@@ -11655,10 +11682,10 @@ var ColorPickerPanel = ({ editor, onClose }) => {
11655
11682
  var Toolbar = ({ editor, setLink, onAICommand, onTranslate, onSpeechToText, onTextToSpeech, onClose, onImageUpload, visibleButtons, isFullscreen, onToggleFullscreen }) => {
11656
11683
  const [, setEditorState] = useState31(0);
11657
11684
  const [todoEnabled, setTodoEnabled] = useState31(false);
11658
- const ttsRef = useRef28(null);
11659
- const sttRef = useRef28(null);
11685
+ const ttsRef = useRef29(null);
11686
+ const sttRef = useRef29(null);
11660
11687
  const show = (id) => !visibleButtons || visibleButtons.has(id);
11661
- useEffect25(() => {
11688
+ useEffect26(() => {
11662
11689
  if (!editor) return;
11663
11690
  const onTransaction = () => setEditorState((n) => n + 1);
11664
11691
  editor.on("transaction", onTransaction);
@@ -12281,7 +12308,7 @@ var Toolbar = ({ editor, setLink, onAICommand, onTranslate, onSpeechToText, onTe
12281
12308
  var Toolbar_default = Toolbar;
12282
12309
 
12283
12310
  // lib/RufousTextEditor/ImageToolbar.tsx
12284
- import React116, { useState as useState32, useEffect as useEffect26, useRef as useRef29 } from "react";
12311
+ import React116, { useState as useState32, useEffect as useEffect27, useRef as useRef30 } from "react";
12285
12312
  import { createPortal as createPortal5 } from "react-dom";
12286
12313
  var ALIGNMENTS = [
12287
12314
  { value: "left", label: "Left", icon: "\u2630" },
@@ -12300,7 +12327,7 @@ var ImagePropertiesModal = ({ editor, node, onClose }) => {
12300
12327
  const [lockRatio, setLockRatio] = useState32(true);
12301
12328
  const [naturalWidth, setNaturalWidth] = useState32(0);
12302
12329
  const [naturalHeight, setNaturalHeight] = useState32(0);
12303
- useEffect26(() => {
12330
+ useEffect27(() => {
12304
12331
  if (src) {
12305
12332
  const img = new window.Image();
12306
12333
  img.onload = () => {
@@ -12423,8 +12450,8 @@ var ImageToolbar = ({ editor }) => {
12423
12450
  const [showVAlign, setShowVAlign] = useState32(false);
12424
12451
  const [copyStatus, setCopyStatus] = useState32("");
12425
12452
  const [pos, setPos] = useState32(null);
12426
- const toolbarRef = useRef29(null);
12427
- useEffect26(() => {
12453
+ const toolbarRef = useRef30(null);
12454
+ useEffect27(() => {
12428
12455
  if (!editor) return;
12429
12456
  const update = () => {
12430
12457
  const { selection } = editor.state;
@@ -12560,7 +12587,7 @@ var ImageToolbar = ({ editor }) => {
12560
12587
  var ImageToolbar_default = ImageToolbar;
12561
12588
 
12562
12589
  // lib/RufousTextEditor/VideoToolbar.tsx
12563
- import React117, { useState as useState33, useEffect as useEffect27, useRef as useRef30 } from "react";
12590
+ import React117, { useState as useState33, useEffect as useEffect28, useRef as useRef31 } from "react";
12564
12591
  import { createPortal as createPortal6 } from "react-dom";
12565
12592
  var ALIGNMENTS2 = [
12566
12593
  { value: "left", label: "Left", icon: "\u2630" },
@@ -12675,8 +12702,8 @@ var VideoToolbar = ({ editor }) => {
12675
12702
  const [showAlign, setShowAlign] = useState33(false);
12676
12703
  const [copyStatus, setCopyStatus] = useState33("");
12677
12704
  const [pos, setPos] = useState33(null);
12678
- const toolbarRef = useRef30(null);
12679
- useEffect27(() => {
12705
+ const toolbarRef = useRef31(null);
12706
+ useEffect28(() => {
12680
12707
  if (!editor) return;
12681
12708
  const update = () => {
12682
12709
  const { selection } = editor.state;
@@ -12800,7 +12827,7 @@ var VideoToolbar = ({ editor }) => {
12800
12827
  var VideoToolbar_default = VideoToolbar;
12801
12828
 
12802
12829
  // lib/RufousTextEditor/TableToolbar.tsx
12803
- import React118, { useState as useState34, useEffect as useEffect28, useRef as useRef31 } from "react";
12830
+ import React118, { useState as useState34, useEffect as useEffect29, useRef as useRef32 } from "react";
12804
12831
  import { createPortal as createPortal7 } from "react-dom";
12805
12832
  var IconAddRowBefore = () => /* @__PURE__ */ React118.createElement("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "currentColor" }, /* @__PURE__ */ React118.createElement("path", { d: "M20 3H4c-.55 0-1 .45-1 1v16c0 .55.45 1 1 1h16c.55 0 1-.45 1-1V4c0-.55-.45-1-1-1zm-1 8H5V5h14v6zm0 8H5v-6h14v6z" }), /* @__PURE__ */ React118.createElement("path", { d: "M9 6h2v1.5h1.5v2H11V11H9V9.5H7.5v-2H9z" }));
12806
12833
  var IconAddRowAfter = () => /* @__PURE__ */ React118.createElement("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "currentColor" }, /* @__PURE__ */ React118.createElement("path", { d: "M20 3H4c-.55 0-1 .45-1 1v16c0 .55.45 1 1 1h16c.55 0 1-.45 1-1V4c0-.55-.45-1-1-1zm-1 8H5V5h14v6zm0 8H5v-6h14v6z" }), /* @__PURE__ */ React118.createElement("path", { d: "M9 14h2v1.5h1.5v2H11V19H9v-1.5H7.5v-2H9z" }));
@@ -12814,8 +12841,8 @@ var IconSplitCell = () => /* @__PURE__ */ React118.createElement("svg", { width:
12814
12841
  var IconToggleHeader = () => /* @__PURE__ */ React118.createElement("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "currentColor" }, /* @__PURE__ */ React118.createElement("path", { d: "M3 3h18v18H3V3zm2 2v4h14V5H5zm0 6v8h14v-8H5z" }), /* @__PURE__ */ React118.createElement("rect", { x: "5", y: "5", width: "14", height: "4", opacity: "0.4" }));
12815
12842
  var TableToolbar = ({ editor }) => {
12816
12843
  const [pos, setPos] = useState34(null);
12817
- const toolbarRef = useRef31(null);
12818
- useEffect28(() => {
12844
+ const toolbarRef = useRef32(null);
12845
+ useEffect29(() => {
12819
12846
  if (!editor) return;
12820
12847
  const update = () => {
12821
12848
  if (!editor.isActive("table")) {
@@ -13054,12 +13081,12 @@ var RufousTextEditor = ({
13054
13081
  return visible;
13055
13082
  }, [buttons, variant, hideButtons]);
13056
13083
  const mentionSuggestion = useMemo5(() => createMentionSuggestion(mentions), [mentions]);
13057
- const onChangeRef = useRef32(onChange);
13058
- const onBlurRef = useRef32(onBlur);
13059
- useEffect29(() => {
13084
+ const onChangeRef = useRef33(onChange);
13085
+ const onBlurRef = useRef33(onBlur);
13086
+ useEffect30(() => {
13060
13087
  onChangeRef.current = onChange;
13061
13088
  }, [onChange]);
13062
- useEffect29(() => {
13089
+ useEffect30(() => {
13063
13090
  onBlurRef.current = onBlur;
13064
13091
  }, [onBlur]);
13065
13092
  const isEditable = editable && !disabled;
@@ -13160,8 +13187,8 @@ var RufousTextEditor = ({
13160
13187
  onChangeRef.current?.(e.getHTML(), e.getJSON());
13161
13188
  }
13162
13189
  });
13163
- const wrapperRef = useRef32(null);
13164
- useEffect29(() => {
13190
+ const wrapperRef = useRef33(null);
13191
+ useEffect30(() => {
13165
13192
  if (!editor) return;
13166
13193
  let blurTimer = null;
13167
13194
  const handler = ({ event }) => {
@@ -13179,7 +13206,7 @@ var RufousTextEditor = ({
13179
13206
  if (blurTimer) clearTimeout(blurTimer);
13180
13207
  };
13181
13208
  }, [editor]);
13182
- const setLinkRef = useRef32(null);
13209
+ const setLinkRef = useRef33(null);
13183
13210
  const [linkModalOpen, setLinkModalOpen] = useState35(false);
13184
13211
  const [linkUrl, setLinkUrl] = useState35("");
13185
13212
  const [linkText, setLinkText] = useState35("");
@@ -13224,10 +13251,10 @@ var RufousTextEditor = ({
13224
13251
  setLinkSelection({ from, to });
13225
13252
  setLinkModalOpen(true);
13226
13253
  }, [editor]);
13227
- useEffect29(() => {
13254
+ useEffect30(() => {
13228
13255
  setLinkRef.current = setLink;
13229
13256
  }, [setLink]);
13230
- useEffect29(() => {
13257
+ useEffect30(() => {
13231
13258
  if (!editor?.view) return;
13232
13259
  const handleKeyDown = (event) => {
13233
13260
  if ((event.ctrlKey || event.metaKey) && event.key === "k") {
@@ -13528,6 +13555,57 @@ var RufousTextContent = ({ content, className, style, sx }) => {
13528
13555
  }
13529
13556
  );
13530
13557
  };
13558
+
13559
+ // lib/utils/locationData.ts
13560
+ import { Country as Country3, State as State2, City as City2 } from "country-state-city";
13561
+ var _stateNameCache = /* @__PURE__ */ new Map();
13562
+ function getStateNameMap(countryCode) {
13563
+ if (!_stateNameCache.has(countryCode)) {
13564
+ const map = /* @__PURE__ */ new Map();
13565
+ State2.getStatesOfCountry(countryCode).forEach((s2) => map.set(s2.isoCode, s2.name));
13566
+ _stateNameCache.set(countryCode, map);
13567
+ }
13568
+ return _stateNameCache.get(countryCode);
13569
+ }
13570
+ function getAllCountries2() {
13571
+ return Country3.getAllCountries();
13572
+ }
13573
+ function getCountryByCode(isoCode) {
13574
+ return Country3.getCountryByCode(isoCode) ?? void 0;
13575
+ }
13576
+ function getStatesOfCountry(countryCode) {
13577
+ const countryName = Country3.getCountryByCode(countryCode)?.name ?? "";
13578
+ return State2.getStatesOfCountry(countryCode).map((state) => ({
13579
+ ...state,
13580
+ countryName
13581
+ }));
13582
+ }
13583
+ function getStateByCode(stateCode, countryCode) {
13584
+ const state = State2.getStateByCodeAndCountry(stateCode, countryCode);
13585
+ if (!state) return void 0;
13586
+ const countryName = Country3.getCountryByCode(countryCode)?.name ?? "";
13587
+ return { ...state, countryName };
13588
+ }
13589
+ function getCitiesOfState(countryCode, stateCode) {
13590
+ const countryName = Country3.getCountryByCode(countryCode)?.name ?? "";
13591
+ const stateName = State2.getStateByCodeAndCountry(stateCode, countryCode)?.name ?? "";
13592
+ return City2.getCitiesOfState(countryCode, stateCode).map((city) => ({
13593
+ ...city,
13594
+ cityCode: city.name.slice(0, 3),
13595
+ countryName,
13596
+ stateName
13597
+ }));
13598
+ }
13599
+ function getCitiesOfCountry(countryCode) {
13600
+ const countryName = Country3.getCountryByCode(countryCode)?.name ?? "";
13601
+ const stateNameMap = getStateNameMap(countryCode);
13602
+ return (City2.getCitiesOfCountry(countryCode) ?? []).map((city) => ({
13603
+ ...city,
13604
+ cityCode: city.name.slice(0, 3),
13605
+ countryName,
13606
+ stateName: stateNameMap.get(city.stateCode) ?? ""
13607
+ }));
13608
+ }
13531
13609
  export {
13532
13610
  APP_THEMES,
13533
13611
  Accordion,
@@ -13668,6 +13746,12 @@ export {
13668
13746
  viewIcon_default as ViewIcon,
13669
13747
  workItemIcon_default as WorkItemIcon,
13670
13748
  Zoom,
13749
+ getAllCountries2 as getAllCountries,
13750
+ getCitiesOfCountry,
13751
+ getCitiesOfState,
13752
+ getCountryByCode,
13753
+ getStateByCode,
13754
+ getStatesOfCountry,
13671
13755
  transformLegacyTodos,
13672
13756
  useRufousTheme
13673
13757
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rufous/ui",
3
3
  "private": false,
4
- "version": "0.3.17",
4
+ "version": "0.3.19",
5
5
  "type": "module",
6
6
  "description": "Experimental: A lightweight React UI component library (Beta)",
7
7
  "style": "./dist/main.css",