@agilant/toga-blox 1.0.75 → 1.0.77

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.
@@ -1,14 +1,11 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useEffect } from "react";
3
3
  import MultiSelectInput from "../MultiSelect/MultiSelect";
4
+ import updateLocalStorage from "../../utils/updateLocalStorage";
4
5
  const DEFAULT_STORAGE_KEY = "searchCriteria";
5
6
  const SearchDropdownInput = ({ options = [], selectedValue = [], onChange, placeholder = "Select", disabled = false, hasSelectAll = true, bgColor = "bg-sky-500", textHighlight = "text-sky-700", handleFilter, searchItems = [], setSearchItems, setSearchCriteria, column, setEditingHeader, localStorageKey = DEFAULT_STORAGE_KEY, ...rest }) => {
6
7
  // Are we able to store filters for this column?
7
8
  const canStore = !!column?.id && !!setSearchCriteria;
8
- /** Helper: write the entire searchCriteria array to localStorage */
9
- const updateLocalStorage = (criteria) => {
10
- localStorage.setItem(localStorageKey, JSON.stringify(criteria));
11
- };
12
9
  useEffect(() => {
13
10
  if (!canStore)
14
11
  return;
@@ -52,7 +49,7 @@ const SearchDropdownInput = ({ options = [], selectedValue = [], onChange, place
52
49
  if (isEmpty) {
53
50
  setSearchCriteria?.((prev) => {
54
51
  const newCriteria = prev.filter((c) => c.searchColumn.id !== column.id);
55
- updateLocalStorage(newCriteria);
52
+ updateLocalStorage(newCriteria, localStorageKey);
56
53
  return newCriteria;
57
54
  });
58
55
  }
@@ -66,7 +63,7 @@ const SearchDropdownInput = ({ options = [], selectedValue = [], onChange, place
66
63
  submittedSearchText: selectedLabels,
67
64
  },
68
65
  ];
69
- updateLocalStorage(newCriteria);
66
+ updateLocalStorage(newCriteria, localStorageKey);
70
67
  return newCriteria;
71
68
  });
72
69
  }
@@ -78,7 +75,7 @@ const SearchDropdownInput = ({ options = [], selectedValue = [], onChange, place
78
75
  if (canStore) {
79
76
  setSearchCriteria?.((prev) => {
80
77
  const newCriteria = prev.filter((c) => c.searchColumn.id !== column.id);
81
- updateLocalStorage(newCriteria);
78
+ updateLocalStorage(newCriteria, localStorageKey);
82
79
  return newCriteria;
83
80
  });
84
81
  setSearchItems?.([]);
@@ -19,7 +19,7 @@ const SearchInput = ({ bgColor = "bg-sky-500", textHighlight = "text-sky-500", i
19
19
  case "text":
20
20
  return (_jsx(SearchTextInput, { dropdownIconProp: dropdownIconProp, dropdownOptions: dropdownOptions, selectedDropdownOption: selectedDropdownOption, onDropdownOptionSelect: onDropdownOptionSelect, searchItems: searchItems, setSearchItems: setSearchItems, handleFilter: handleFilter, setSearchCriteria: setSearchCriteria, column: column, setEditingHeader: setEditingHeader, pillColor: pillColor, firstIconClasses: firstIconClasses }));
21
21
  case "number":
22
- return (_jsx(SearchNumberInput, { dropdownIconProp: dropdownIconProp, dropdownOptions: dropdownOptions, selectedDropdownOption: selectedDropdownOption, onDropdownOptionSelect: onDropdownOptionSelect, toggleStatus: toggleStatus, setToggleStatus: setToggleStatus, minValue: minValue, maxValue: maxValue, setMinValue: setMinValue, setMaxValue: setMaxValue, handleFilter: handleFilter }));
22
+ return (_jsx(SearchNumberInput, { dropdownIconProp: dropdownIconProp, dropdownOptions: dropdownOptions, selectedDropdownOption: selectedDropdownOption, onDropdownOptionSelect: onDropdownOptionSelect, toggleStatus: toggleStatus, setToggleStatus: setToggleStatus, minValue: minValue, maxValue: maxValue, setMinValue: setMinValue, setMaxValue: setMaxValue, handleFilter: handleFilter, setSearchCriteria: setSearchCriteria, column: column }));
23
23
  case "multiSelect":
24
24
  return (_jsx(SearchDropdownInput, { options: dropdownOptions, placeholder: "Search", additionalClasses: "", onChange: onChange, selectedValue: selectedValue, bgColor: bgColor, textHighlight: textHighlight, handleFilter: handleFilter, column: column, setSearchCriteria: setSearchCriteria }));
25
25
  case "date":
@@ -191,13 +191,13 @@ describe("SearchInput Component", () => {
191
191
  uuid: "1",
192
192
  name: "Option 1",
193
193
  value: "option1",
194
- label: "Option 1",
194
+ // label: "Option 1",
195
195
  },
196
196
  {
197
197
  uuid: "2",
198
198
  name: "Option 2",
199
199
  value: "option2",
200
- label: "Option 2",
200
+ // label: "Option 2",
201
201
  },
202
202
  ] }));
203
203
  // Open dropdown
@@ -222,13 +222,13 @@ describe("SearchInput Component", () => {
222
222
  uuid: "1",
223
223
  name: "Option 1",
224
224
  value: "option1",
225
- label: "Option 1",
225
+ // label: "Option 1",
226
226
  },
227
227
  {
228
228
  uuid: "2",
229
229
  name: "Option 2",
230
230
  value: "option2",
231
- label: "Option 2",
231
+ // label: "Option 2",
232
232
  },
233
233
  ] }));
234
234
  const dropdown = screen.getByText(/Search/i);
@@ -245,13 +245,13 @@ describe("SearchInput Component", () => {
245
245
  uuid: "1",
246
246
  name: "Option 1",
247
247
  value: "option1",
248
- label: "Option 1",
248
+ // label: "Option 1",
249
249
  },
250
250
  {
251
251
  uuid: "2",
252
252
  name: "Option 2",
253
253
  value: "option2",
254
- label: "Option 2",
254
+ // label: "Option 2",
255
255
  },
256
256
  ] }));
257
257
  const dropdown = screen.getByText(/Search/i);
@@ -269,13 +269,13 @@ describe("SearchInput Component", () => {
269
269
  uuid: "1",
270
270
  name: "True",
271
271
  value: "true",
272
- label: "True",
272
+ // label: "True",
273
273
  },
274
274
  {
275
275
  uuid: "2",
276
276
  name: "False",
277
277
  value: "false",
278
- label: "False",
278
+ // label: "False",
279
279
  },
280
280
  ] }));
281
281
  expect(screen.getByText(/Search/i)).toBeInTheDocument();
@@ -286,13 +286,13 @@ describe("SearchInput Component", () => {
286
286
  uuid: "1",
287
287
  name: "True",
288
288
  value: "true",
289
- label: "True",
289
+ // label: "True",
290
290
  },
291
291
  {
292
292
  uuid: "2",
293
293
  name: "False",
294
294
  value: "false",
295
- label: "False",
295
+ // label: "False",
296
296
  },
297
297
  ] }));
298
298
  // Open dropdown
@@ -308,13 +308,13 @@ describe("SearchInput Component", () => {
308
308
  uuid: "1",
309
309
  name: "True",
310
310
  value: "true",
311
- label: "True",
311
+ // label: "True",
312
312
  },
313
313
  {
314
314
  uuid: "2",
315
315
  name: "False",
316
316
  value: "false",
317
- label: "False",
317
+ // label: "False",
318
318
  },
319
319
  ] }));
320
320
  // Open dropdown
@@ -1,5 +1,10 @@
1
1
  import React from "react";
2
2
  import { Control } from "react-hook-form";
3
+ export type MixedOption = string | {
4
+ uuid: string;
5
+ name: string;
6
+ value: string;
7
+ };
3
8
  export type SearchInputProps<T extends object> = {
4
9
  onChange(newSelected: OptionType[]): unknown;
5
10
  selectedValue: any[];
@@ -8,7 +13,7 @@ export type SearchInputProps<T extends object> = {
8
13
  bgColor?: string;
9
14
  textHighlight?: string;
10
15
  inputType?: "text" | "number" | "date" | "boolean" | "multiSelect";
11
- dropdownOptions?: string[] | OptionType[] | number[];
16
+ dropdownOptions?: MixedOption[] | number[];
12
17
  selectedDropdownOption?: string | OptionType | number;
13
18
  onDropdownOptionSelect?: (option: string) => void;
14
19
  dropdownIconProp?: searchDropdownIconProps;
@@ -8,6 +8,7 @@ import BaseButton from "../BaseButton";
8
8
  import Badge from "../Badge/Badge";
9
9
  import Text from "../Text";
10
10
  import { getFontAwesomeIcon } from "../../utils/getFontAwesomeIcon";
11
+ import updateLocalStorage from "../../utils/updateLocalStorage";
11
12
  /**
12
13
  * A helper to convert a Date object to 'YYYY-MM-DD'
13
14
  * so we don't get slashes in the final string.
@@ -71,9 +72,6 @@ searchItems = [], setSearchItems, handleFilter, setSearchCriteria, column, setEd
71
72
  document.addEventListener("mousedown", handleClickOutside);
72
73
  return () => document.removeEventListener("mousedown", handleClickOutside);
73
74
  }, []);
74
- const updateLocalStorage = (criteria) => {
75
- localStorage.setItem(localStorageKey, JSON.stringify(criteria));
76
- };
77
75
  /**
78
76
  * Build a string in 'YYYY-MM-DD' (or range) format,
79
77
  * so it won't break in your URL as "mm%2Fdd%2Fyyyy"
@@ -111,7 +109,7 @@ searchItems = [], setSearchItems, handleFilter, setSearchCriteria, column, setEd
111
109
  if (canStore) {
112
110
  setSearchCriteria?.((prev) => {
113
111
  const newCriteria = prev.filter((c) => c.searchColumn.id !== column.id);
114
- updateLocalStorage(newCriteria);
112
+ updateLocalStorage(newCriteria, localStorageKey);
115
113
  return newCriteria;
116
114
  });
117
115
  }
@@ -130,7 +128,7 @@ searchItems = [], setSearchItems, handleFilter, setSearchCriteria, column, setEd
130
128
  submittedSearchText: dateString,
131
129
  },
132
130
  ];
133
- updateLocalStorage(newCriteria);
131
+ updateLocalStorage(newCriteria, localStorageKey);
134
132
  return newCriteria;
135
133
  });
136
134
  }
@@ -188,7 +186,7 @@ searchItems = [], setSearchItems, handleFilter, setSearchCriteria, column, setEd
188
186
  setSearchCriteria?.((prev) => {
189
187
  const filtered = prev.filter((crit) => crit.submittedSearchText !==
190
188
  item);
191
- updateLocalStorage(filtered);
189
+ updateLocalStorage(filtered, localStorageKey);
192
190
  return filtered;
193
191
  });
194
192
  }
@@ -1,5 +1,7 @@
1
1
  import React from "react";
2
+ import { ColumnInstance } from "react-table";
2
3
  import { searchDropdownIconProps } from "./SearchInput.types";
4
+ /** The parent can pass these props to replicate local-storage filter usage. */
3
5
  type SearchNumberInputProps<T extends object> = {
4
6
  pillColor?: string;
5
7
  textHighlight?: string;
@@ -13,7 +15,28 @@ type SearchNumberInputProps<T extends object> = {
13
15
  setMinValue?: React.Dispatch<React.SetStateAction<string>>;
14
16
  maxValue?: string;
15
17
  setMaxValue?: React.Dispatch<React.SetStateAction<string>>;
18
+ /** Called after we store or remove the filter in localStorage. */
16
19
  handleFilter?: () => void;
20
+ /** The array of “badges” (previously added filters) for this column. */
21
+ searchItems?: string[];
22
+ setSearchItems?: React.Dispatch<React.SetStateAction<string[]>>;
23
+ /** The full array of all filters for the table. */
24
+ setSearchCriteria?: React.Dispatch<React.SetStateAction<any[]>>;
25
+ /** The column object must have an .id so we know which filter is ours. */
26
+ column?: ColumnInstance<any> | {
27
+ id: string;
28
+ [key: string]: any;
29
+ };
30
+ /** If you want to close the popover or overlay once we filter/clear */
31
+ setEditingHeader?: React.Dispatch<React.SetStateAction<any>>;
32
+ /** localStorage key to store all the table’s filters (default "searchCriteria"). */
33
+ localStorageKey?: string;
17
34
  };
18
- declare const SearchNumberInput: <T extends object>({ textHighlight, dropdownIconProp, dropdownOptions, selectedDropdownOption, onDropdownOptionSelect, toggleStatus, setToggleStatus, minValue, setMinValue, maxValue, setMaxValue, handleFilter, }: SearchNumberInputProps<T>) => import("react/jsx-runtime").JSX.Element;
35
+ /**
36
+ * A numeric filter component that:
37
+ * 1. Uses toggleStatus to switch single vs. range
38
+ * 2. On Filter => either remove or store a string in localStorage
39
+ * 3. On mount => read any existing filter for this column, parse, and set min/max
40
+ */
41
+ declare const SearchNumberInput: <T extends object>({ textHighlight, dropdownIconProp, dropdownOptions, selectedDropdownOption, onDropdownOptionSelect, toggleStatus, setToggleStatus, minValue, setMinValue, maxValue, setMaxValue, handleFilter, searchItems, setSearchItems, setSearchCriteria, column, setEditingHeader, localStorageKey, }: SearchNumberInputProps<T>) => import("react/jsx-runtime").JSX.Element;
19
42
  export default SearchNumberInput;
@@ -1,41 +1,163 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useEffect, useRef } from "react";
2
+ import { useEffect, useRef, useCallback } from "react";
3
3
  import { Input } from "../Input";
4
4
  import Dropdown from "../Dropdown/Dropdown";
5
5
  import ToggleButton from "../ToggleButton/ToggleButton";
6
6
  import BaseButton from "../BaseButton";
7
7
  import Text from "../Text";
8
+ const DEFAULT_STORAGE_KEY = "searchCriteria";
9
+ /**
10
+ * A numeric filter component that:
11
+ * 1. Uses toggleStatus to switch single vs. range
12
+ * 2. On Filter => either remove or store a string in localStorage
13
+ * 3. On mount => read any existing filter for this column, parse, and set min/max
14
+ */
8
15
  const SearchNumberInput = ({ textHighlight = "text-sky-500", dropdownIconProp = {
9
- iconClasses: textHighlight,
16
+ iconClasses: "text-sky-500",
10
17
  name: "chevronDown",
11
18
  weight: "solid",
12
- }, dropdownOptions = [], selectedDropdownOption = "", onDropdownOptionSelect, toggleStatus, setToggleStatus, minValue, setMinValue, maxValue, setMaxValue, handleFilter, }) => {
19
+ }, dropdownOptions = [], selectedDropdownOption = "", onDropdownOptionSelect, toggleStatus = false, setToggleStatus, minValue = "", setMinValue, maxValue = "", setMaxValue, handleFilter,
20
+ // local-storage
21
+ searchItems = [], setSearchItems, setSearchCriteria, column, setEditingHeader, localStorageKey = DEFAULT_STORAGE_KEY, }) => {
13
22
  const containerRef = useRef(null);
14
23
  const inputRef = useRef(null);
15
- // Focus the input when editing starts (if needed)
24
+ /** Decide if we can store for this column */
25
+ const canStore = !!column?.id && !!setSearchCriteria;
26
+ /** On mount, read localStorage once => if there's a saved filter => parse & set */
27
+ useEffect(() => {
28
+ if (!canStore)
29
+ return;
30
+ // Make sure this runs only once
31
+ const stored = localStorage.getItem(localStorageKey);
32
+ if (!stored)
33
+ return;
34
+ try {
35
+ const parsed = JSON.parse(stored);
36
+ const existing = parsed.find((c) => c.searchColumn?.id === column?.id);
37
+ if (existing) {
38
+ const savedString = existing.submittedSearchText;
39
+ if (savedString && typeof savedString === "string") {
40
+ if (savedString.includes(" - ")) {
41
+ // It's a range: "100 - 200"
42
+ setToggleStatus?.(true);
43
+ const [minPart, maxPart] = savedString.split(" - ");
44
+ setMinValue?.(minPart.trim());
45
+ setMaxValue?.(maxPart.trim());
46
+ }
47
+ else {
48
+ // Single e.g. "Exactly 123" or "default 2" or just "2"
49
+ setToggleStatus?.(false);
50
+ const segments = savedString.split(" ");
51
+ // If the first word is in your dropdown => use it, else treat as pure number
52
+ if (segments.length > 1 &&
53
+ dropdownOptions.includes(segments[0])) {
54
+ onDropdownOptionSelect?.(segments[0]);
55
+ setMinValue?.(segments[1]);
56
+ }
57
+ else {
58
+ // no prefix => assume it's just the number
59
+ setMinValue?.(savedString);
60
+ }
61
+ }
62
+ // Also set searchItems so the "badge" might show
63
+ setSearchItems?.([savedString]);
64
+ }
65
+ }
66
+ }
67
+ catch (err) {
68
+ console.error("Error reading stored number filter:", err);
69
+ }
70
+ // empty dependency array => only once on mount
71
+ }, []);
72
+ /** Focus on mount if needed */
16
73
  useEffect(() => {
17
74
  inputRef.current?.focus();
18
75
  }, []);
19
- const handleInputChange = (event) => {
20
- setMinValue(event.target.value);
21
- };
22
- const handleMaximumInputChange = (event) => {
23
- setMaxValue(event.target.value);
76
+ /**
77
+ * Build the final string to store.
78
+ *
79
+ * 1) If toggleStatus => "minValue - maxValue"
80
+ * 2) If single => skip "default" prefix
81
+ */
82
+ const buildNumberString = useCallback(() => {
83
+ if (toggleStatus) {
84
+ // Range mode => "min - max"
85
+ if (minValue && maxValue) {
86
+ return `${minValue} - ${maxValue}`;
87
+ }
88
+ else if (minValue) {
89
+ return `${minValue} - `;
90
+ }
91
+ else if (maxValue) {
92
+ return ` - ${maxValue}`;
93
+ }
94
+ else {
95
+ return ""; // no input => empty
96
+ }
97
+ }
98
+ else {
99
+ // Single value mode => e.g. "Exactly 123" or "2"
100
+ const prefix = selectedDropdownOption?.toLowerCase() === "default"
101
+ ? "" // if your dropdown used "default" for something
102
+ : selectedDropdownOption;
103
+ if (prefix && minValue) {
104
+ return `${prefix} ${minValue}`;
105
+ }
106
+ else if (minValue) {
107
+ return minValue; // fallback
108
+ }
109
+ else {
110
+ return "";
111
+ }
112
+ }
113
+ }, [toggleStatus, minValue, maxValue, selectedDropdownOption]);
114
+ /**
115
+ * Called when user clicks "Filter" button at the bottom.
116
+ * We remove or store the built string, then call handleFilter.
117
+ */
118
+ const handleFilterClick = () => {
119
+ const finalString = buildNumberString().trim();
120
+ if (!finalString) {
121
+ // remove existing filter for this column
122
+ if (canStore) {
123
+ setSearchCriteria?.((prev) => {
124
+ const newCriteria = prev.filter((c) => c.searchColumn.id !== column?.id);
125
+ localStorage.setItem(localStorageKey, JSON.stringify(newCriteria));
126
+ return newCriteria;
127
+ });
128
+ }
129
+ }
130
+ else {
131
+ // store it
132
+ if (!searchItems.includes(finalString)) {
133
+ setSearchItems?.([...searchItems, finalString]);
134
+ }
135
+ if (canStore) {
136
+ setSearchCriteria?.((prev) => {
137
+ // remove old for this column if you want only one number filter per column
138
+ const filtered = prev.filter((c) => c.searchColumn.id !== column?.id);
139
+ const newCriteria = [
140
+ ...filtered,
141
+ {
142
+ searchColumn: column,
143
+ submittedSearchText: finalString,
144
+ },
145
+ ];
146
+ localStorage.setItem(localStorageKey, JSON.stringify(newCriteria));
147
+ return newCriteria;
148
+ });
149
+ }
150
+ }
151
+ // Optionally close the popover
152
+ setEditingHeader?.(null);
153
+ // Let the parent know a filter was applied
154
+ handleFilter?.();
24
155
  };
25
- // const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
26
- // console.log("Key Pressed:", e.key);
27
- // if (e.key === "Enter") {
28
- // e.preventDefault();
29
- // }
30
- // };
31
- return (_jsx("div", { ref: containerRef, className: "w-[425px]", children: _jsxs("div", { className: `flex flex-col p-4 h-[130px] border-2 border-navy-200 rounded-md`, children: [_jsx("div", { className: `flex flex-[1] ${toggleStatus ? "" : "border-2"} h-full max-h-11 items-center justify-around`, children: toggleStatus ? (_jsxs(_Fragment, { children: [_jsx(Input, { focusRingColor: "focus:ring-2", hasAutoFocus: true, value: minValue, iconColor: "text-navy-400",
32
- // onKeyDown={handleKeyDown}
33
- required: false, id: "", name: "", type: "number", onChange: handleInputChange, additionalClasses: "min-w-[180px] max-w-[180px] h-10 text-gray flex focus:border-l-2 ", placeholder: "Min" }), _jsx(Text, { size: "text-md", tag: "span", text: "to", additionalClasses: "px-2" }), _jsx(Input, { focusRingColor: "focus:ring-2", value: maxValue, iconColor: "text-navy-400",
34
- // onKeyDown={handleKeyDown}
35
- required: false, id: "", name: "", type: "number", onChange: handleMaximumInputChange, additionalClasses: "min-w-[180px] max-w-[180px] h-10 text-gray flex border-2 focus:border-l-2 focus:border- ", placeholder: "Max", hasIcons: true, iconPosition: "both" })] })) : (_jsxs(_Fragment, { children: [_jsx(Dropdown, { options: dropdownOptions, selectedOption: selectedDropdownOption, onOptionSelect: onDropdownOptionSelect, optionClasses: "px-4 h-full flex items-center", menuClasses: "bg-white w-min-[150px] top-[-8px] left-[-2px]", dropdownClasses: "border-0 w-auto", icon: dropdownIconProp }), _jsx(Input, { focusRingColor: "focus:ring-transparent", hasAutoFocus: true, value: minValue, iconColor: "text-navy-400",
36
- // onKeyDown={handleKeyDown}
37
- required: false, id: "", name: "", type: "number", onChange: handleInputChange, additionalClasses: "min-w-[200px] h-10 text-gray flex border-l-2 ", placeholder: "Amount", hasIcons: true, iconPosition: "both" })] })) }), _jsxs("div", { className: "flex flex-[1] justify-between items-end bg-white px-2 ", children: [_jsx(ToggleButton, { initialStatus: toggleStatus, onClick: () => {
38
- setToggleStatus(!toggleStatus);
39
- }, activeColorBackground: "bg-sky-500", activeColorBorder: "border-sky-500", activeLabel: "Range", activeTextColor: "text-sky-500", additionalClasses: "flex items-center", inactiveColorBackground: "bg-gray-300", inactiveColorBorder: "border-gray-300", inactiveLabel: "Range", inactiveTextColor: "text-gray-500", pillHeight: "h-8", textPosition: "right", textSize: "text-sm", smallToggle: false, borderStyle: false }), _jsx(BaseButton, { text: "Filter", backgroundColor: "bg-sky-500", additionalClasses: "py-1.5 px-6 text-white", borderColor: "border-none", onClick: handleFilter, shape: "rounded-full" })] })] }) }));
156
+ return (_jsx("div", { ref: containerRef, className: "w-[425px]", children: _jsxs("div", { className: "flex flex-col p-4 h-[130px] border-2 border-navy-200 rounded-md", children: [_jsx("div", { className: `flex flex-[1] ${toggleStatus ? "" : "border-2"}
157
+ h-full max-h-11 items-center justify-around`, children: toggleStatus ? (
158
+ // Range mode
159
+ _jsxs(_Fragment, { children: [_jsx(Input, { focusRingColor: "focus:ring-2", hasAutoFocus: true, value: minValue, iconColor: "text-navy-400", required: false, id: "", name: "", type: "number", onChange: (e) => setMinValue?.(e.target.value), additionalClasses: "min-w-[180px] max-w-[180px] h-10 text-gray flex focus:border-l-2 ", placeholder: "Min" }), _jsx(Text, { size: "text-md", tag: "span", text: "to", additionalClasses: "px-2" }), _jsx(Input, { focusRingColor: "focus:ring-2", value: maxValue, iconColor: "text-navy-400", required: false, id: "", name: "", type: "number", onChange: (e) => setMaxValue?.(e.target.value), additionalClasses: "min-w-[180px] max-w-[180px] h-10 text-gray flex border-2 focus:border-l-2 ", placeholder: "Max" })] })) : (
160
+ // Single value mode
161
+ _jsxs(_Fragment, { children: [_jsx(Dropdown, { options: dropdownOptions, selectedOption: selectedDropdownOption, onOptionSelect: onDropdownOptionSelect, optionClasses: "px-4 h-full flex items-center", menuClasses: "bg-white w-min-[150px] top-[-8px] left-[-2px]", dropdownClasses: "border-0 w-auto", icon: dropdownIconProp }), _jsx(Input, { ref: inputRef, focusRingColor: "focus:ring-transparent", hasAutoFocus: true, value: minValue, iconColor: "text-navy-400", required: false, id: "", name: "", type: "number", onChange: (e) => setMinValue?.(e.target.value), additionalClasses: "min-w-[200px] h-10 text-gray flex border-l-2 ", placeholder: "Amount", hasIcons: true, iconPosition: "both" })] })) }), _jsxs("div", { className: "flex flex-[1] justify-between items-end bg-white px-2", children: [_jsx(ToggleButton, { initialStatus: toggleStatus, onClick: () => setToggleStatus?.(!toggleStatus), activeColorBackground: "bg-sky-500", activeColorBorder: "border-sky-500", activeLabel: "Range", activeTextColor: "text-sky-500", additionalClasses: "flex items-center", inactiveColorBackground: "bg-gray-300", inactiveColorBorder: "border-gray-300", inactiveLabel: "Range", inactiveTextColor: "text-gray-500", pillHeight: "h-8", textPosition: "right", textSize: "text-sm", smallToggle: false, borderStyle: false }), _jsx(BaseButton, { text: "Filter", backgroundColor: "bg-sky-500", additionalClasses: "py-1.5 px-6 text-white", borderColor: "border-none", onClick: handleFilterClick, shape: "rounded-full" })] })] }) }));
40
162
  };
41
163
  export default SearchNumberInput;
@@ -6,6 +6,7 @@ import { getFontAwesomeIcon } from "../../utils/getFontAwesomeIcon";
6
6
  import Dropdown from "../Dropdown/Dropdown";
7
7
  import Badge from "../Badge/Badge";
8
8
  import Text from "../Text";
9
+ import updateLocalStorage from "../../utils/updateLocalStorage";
9
10
  const SearchTextInput = ({ pillColor = "bg-sky-500", textHighlight = "text-sky-500", dropdownIconProp = {
10
11
  iconClasses: textHighlight,
11
12
  name: "chevronDown",
@@ -31,10 +32,6 @@ const SearchTextInput = ({ pillColor = "bg-sky-500", textHighlight = "text-sky-5
31
32
  }
32
33
  }
33
34
  }, [column.id, localStorageKey]);
34
- // Helper to update local storage.
35
- const updateLocalStorage = (criteria) => {
36
- localStorage.setItem(localStorageKey, JSON.stringify(criteria));
37
- };
38
35
  const handleInputChange = (event) => {
39
36
  setLocalSearchText(event.target.value);
40
37
  };
@@ -46,7 +43,7 @@ const SearchTextInput = ({ pillColor = "bg-sky-500", textHighlight = "text-sky-5
46
43
  // Remove corresponding criterion from searchCriteria.
47
44
  setSearchCriteria((prev) => {
48
45
  const newCriteria = prev.filter((crit) => crit.submittedSearchText !== item);
49
- updateLocalStorage(newCriteria);
46
+ updateLocalStorage(newCriteria, localStorageKey);
50
47
  console.log("Removed badge criterion, newCriteria:", newCriteria);
51
48
  return newCriteria;
52
49
  });
@@ -70,7 +67,7 @@ const SearchTextInput = ({ pillColor = "bg-sky-500", textHighlight = "text-sky-5
70
67
  // Remove any criteria for this column.
71
68
  setSearchCriteria((prev) => {
72
69
  const newCriteria = prev.filter((c) => c.searchColumn.id !== column.id);
73
- updateLocalStorage(newCriteria);
70
+ updateLocalStorage(newCriteria, localStorageKey);
74
71
  console.log("Removed criterion, newCriteria:", newCriteria);
75
72
  return newCriteria;
76
73
  });
@@ -82,7 +79,7 @@ const SearchTextInput = ({ pillColor = "bg-sky-500", textHighlight = "text-sky-5
82
79
  ...prev,
83
80
  { searchColumn: column, submittedSearchText: trimmed },
84
81
  ];
85
- updateLocalStorage(newCriteria);
82
+ updateLocalStorage(newCriteria, localStorageKey);
86
83
  console.log("Appended criterion, newCriteria:", newCriteria);
87
84
  return newCriteria;
88
85
  });
@@ -0,0 +1,2 @@
1
+ declare const updateLocalStorage: (criteria: any[], localStorageKey: string) => void;
2
+ export default updateLocalStorage;
@@ -0,0 +1,4 @@
1
+ const updateLocalStorage = (criteria, localStorageKey) => {
2
+ localStorage.setItem(localStorageKey, JSON.stringify(criteria));
3
+ };
4
+ export default updateLocalStorage;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@agilant/toga-blox",
3
3
  "private": false,
4
- "version": "1.0.75",
4
+ "version": "1.0.77",
5
5
  "description": "",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",