@agilant/toga-blox 1.0.47 → 1.0.48

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.
@@ -9,7 +9,7 @@ const Dropdown = ({ options, selectedOption, onOptionSelect, optionClasses = "fl
9
9
  }, selectedOptionBgColor = "bg-gray-50", optionHoverBgColor = "hover:bg-gray-50", }) => {
10
10
  const [showMenu, setShowMenu] = useState(false);
11
11
  const toggleMenu = () => setShowMenu(!showMenu);
12
- return (_jsxs("div", { className: `flex items-center justify-between relative min-w-32 border-2 ${dropdownClasses}`, children: [_jsxs("div", { onClick: toggleMenu, className: `flex cursor-pointer items-center group h-full `, children: [_jsx("div", { className: `font-bold ${optionClasses}`, children: selectedOption }), _jsx("div", { className: `transform transition-transform duration-200 mx-1 px-1 rounded-full relative ${icon.iconClasses} ${showMenu ? "rotate-180" : "rotate-0"}`, children: _jsx("span", { children: getFontAwesomeIcon(icon.name) }) })] }), showMenu && (_jsx(AnimatePresence, { children: showMenu && (_jsx(motion.div, { initial: { opacity: 0, y: -10 }, animate: { opacity: 1, y: 0 }, exit: { opacity: 0, y: -10 }, className: `absolute top-0 z-10 right-0 left-0 ${menuClasses}`, children: _jsx("ul", { children: options.map((action) => (_jsxs("li", { className: `text-left px-4 py-2 cursor-pointer border-b ${action === selectedOption
12
+ return (_jsxs("div", { className: `flex items-center justify-between relative min-w-32 ${dropdownClasses}`, children: [_jsxs("div", { onClick: toggleMenu, className: `flex cursor-pointer items-center group h-full `, children: [_jsx("div", { className: `font-bold ${optionClasses}`, children: selectedOption }), _jsx("div", { className: `transform transition-transform duration-200 mx-1 px-1 rounded-full relative ${icon.iconClasses} ${showMenu ? "rotate-180" : "rotate-0"}`, "data-testid": "dropdown-icon", children: getFontAwesomeIcon(icon.name) })] }), showMenu && (_jsx(AnimatePresence, { children: showMenu && (_jsx(motion.div, { initial: { opacity: 0, y: -10 }, animate: { opacity: 1, y: 0 }, exit: { opacity: 0, y: -10 }, className: `absolute top-0 z-10 right-0 left-0 ${menuClasses}`, children: _jsx("ul", { children: options.map((action) => (_jsxs("li", { className: `text-left px-4 py-2 cursor-pointer border-b ${action === selectedOption
13
13
  ? `{${selectedOptionBgColor} font-semibold}`
14
14
  : `${optionHoverBgColor} text-black`}`, onClick: () => {
15
15
  onOptionSelect(action);
@@ -53,6 +53,6 @@ const MagnifyingIcon = forwardRef(({ columnIndex, editingHeader, setEditingHeade
53
53
  };
54
54
  return (_jsx("div", { ref: ref, "data-testid": "magnifying-icon-test-id", className: `flex items-center cursor-pointer size-[18px] rounded relative ml-1 ${iconColor} ${showActiveStyles
55
55
  ? `${iconActiveBackgroundColor} hover:bg-blue-500 still-active`
56
- : "hover:bg-white"}`, onClick: handleClick, children: _jsx("div", { className: `text-xs w-full ${additionalIconClasses} ${showActiveStyles ? "text-white" : iconActiveColor}`, children: getFontAwesomeIcon("magnifyingGlass", "solid") }) }));
56
+ : "hover:bg-white"}`, onClick: handleClick, children: _jsx("div", { className: `text-xs w-full ${additionalIconClasses} `, children: getFontAwesomeIcon("magnifyingGlass", "solid") }) }));
57
57
  });
58
58
  export default MagnifyingIcon;
@@ -44,6 +44,7 @@ export const WithActiveClass = {
44
44
  args: {
45
45
  ...Default.args,
46
46
  isActive: true,
47
+ additionalIconClasses: "text-green-500",
47
48
  },
48
49
  };
49
50
  export const WithClickAlert = {
@@ -11,6 +11,7 @@ interface SearchDropdownInputProps {
11
11
  bgColor?: string;
12
12
  textHighlight?: string;
13
13
  [key: string]: any;
14
+ handleFilter?: () => void;
14
15
  }
15
16
  /**
16
17
  * A wrapper around MultiSelectInput that appends a special "__footer__" option
@@ -5,7 +5,7 @@ import "./SearchDrowpdown.scss";
5
5
  * A wrapper around MultiSelectInput that appends a special "__footer__" option
6
6
  * and uses a custom item renderer to display "Clear" and "Filter" buttons.
7
7
  */
8
- const SearchDropdownInput = ({ options = [], selectedValue = [], onChange, placeholder = "Select...", disabled = false, hasSelectAll = true, bgColor, textHighlight, ...rest }) => {
8
+ const SearchDropdownInput = ({ options = [], selectedValue = [], onChange, placeholder = "Select", disabled = false, hasSelectAll = true, bgColor, textHighlight, handleFilter, ...rest }) => {
9
9
  const footerOption = [{ name: "", value: "__footer__" }];
10
10
  const extendedOptions = [...options, ...footerOption];
11
11
  const itemRenderer = ({ option, checked, disabled, onClick }) => {
@@ -16,8 +16,7 @@ const SearchDropdownInput = ({ options = [], selectedValue = [], onChange, place
16
16
  onChange([]); // Clear all selections
17
17
  }, children: "Clear" }), _jsx("button", { type: "button", className: `${bgColor} text-white px-3 py-1 rounded`, onClick: (e) => {
18
18
  e.stopPropagation();
19
- console.log("Filter clicked!", selectedValue);
20
- // ...your custom filter logic
19
+ handleFilter();
21
20
  }, children: "Filter" })] }));
22
21
  }
23
22
  else if (option.label === "Select All") {
@@ -1,3 +1,3 @@
1
1
  import { SearchInputProps } from "./SearchInput.types";
2
- declare const SearchInput: <T extends object>({ closeOutSearch, setResetSearch, setEditingHeader, bgColor, textHighlight, column, inputType, dropdownIconProp, dropdownOptions, selectedDropdownOption, onDropdownOptionSelect, searchItems, setSearchItems, toggleStatus, setToggleStatus, minValue, setMinValue, maxValue, setMaxValue, control, valueKey, dynamicDefaultValue, onChange, selectedValue, }: SearchInputProps<T>) => import("react/jsx-runtime").JSX.Element;
2
+ declare const SearchInput: <T extends object>({ bgColor, textHighlight, inputType, dropdownIconProp, dropdownOptions, selectedDropdownOption, onDropdownOptionSelect, searchItems, setSearchItems, toggleStatus, setToggleStatus, minValue, setMinValue, maxValue, setMaxValue, onChange, selectedValue, selectedDate, onDateSelect, selectedStartDate, onStartDateSelect, selectedEndDate, onEndDateSelect, handleFilter, }: SearchInputProps<T>) => import("react/jsx-runtime").JSX.Element;
3
3
  export default SearchInput;
@@ -1,71 +1,29 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useEffect, useRef, useState } from "react";
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useRef } from "react";
3
3
  import SearchTextInput from "./SearchTextInput";
4
4
  import SearchNumberInput from "./SearchNumberInput";
5
- import { Controller } from "react-hook-form";
6
5
  import SearchDropdownInput from "./SearchDropdownInput";
7
- // A simple helper function for default values
8
- function getDefaultValue(dynamicDefaultValue, valueKey) {
9
- if (typeof dynamicDefaultValue !== "undefined") {
10
- return dynamicDefaultValue;
11
- }
12
- return "";
13
- }
14
- const SearchInput = ({ closeOutSearch, setResetSearch, setEditingHeader, bgColor = "bg-sky-500", textHighlight = "text-sky-500", column, inputType = "text", dropdownIconProp = {
6
+ import SearchDatePickerInput from "./SearchInputDatePicker";
7
+ const SearchInput = ({ bgColor = "bg-sky-500", textHighlight = "text-sky-500", inputType = "text", dropdownIconProp = {
15
8
  name: "chevronDown",
16
9
  weight: "bold",
17
10
  iconClasses: "text-black",
18
- }, dropdownOptions = [], selectedDropdownOption = "", onDropdownOptionSelect, searchItems = [], setSearchItems, toggleStatus = false, setToggleStatus, minValue, setMinValue, maxValue, setMaxValue, control, valueKey, dynamicDefaultValue, onChange, selectedValue, }) => {
11
+ }, dropdownOptions = [], selectedDropdownOption = "", onDropdownOptionSelect, searchItems = [], setSearchItems, toggleStatus = false, setToggleStatus, minValue, setMinValue, maxValue, setMaxValue, onChange, selectedValue, selectedDate, onDateSelect, selectedStartDate, onStartDateSelect, selectedEndDate, onEndDateSelect, handleFilter, }) => {
19
12
  const containerRef = useRef(null);
20
- const [localSearchText, setLocalSearchText] = useState("");
21
13
  const inputRef = useRef(null);
22
14
  useEffect(() => {
23
15
  inputRef.current?.focus();
24
16
  }, []);
25
- const handleInputChange = (event) => {
26
- setLocalSearchText(event.target.value);
27
- };
28
- const handleSubmitClick = () => {
29
- const trimmedSearchText = localSearchText.trim();
30
- let safeHeader;
31
- if (typeof column.Header === "string") {
32
- safeHeader = column.Header;
33
- }
34
- else {
35
- safeHeader = column.accessor || "Unnamed Column";
36
- }
37
- if (trimmedSearchText === "") {
38
- // Remove criterion if text is empty
39
- }
40
- else {
41
- // Update or add criterion
42
- }
43
- setEditingHeader(null);
44
- };
45
17
  return (_jsx("div", { ref: containerRef, className: "", children: (() => {
46
18
  switch (inputType) {
47
19
  case "text":
48
- return (_jsx(SearchTextInput, { closeOutSearch: () => { }, setResetSearch: () => { }, setEditingHeader: () => { }, column: undefined, dropdownIconProp: dropdownIconProp, dropdownOptions: dropdownOptions, selectedDropdownOption: selectedDropdownOption, onDropdownOptionSelect: onDropdownOptionSelect, searchItems: searchItems, setSearchItems: setSearchItems }));
20
+ return (_jsx(SearchTextInput, { dropdownIconProp: dropdownIconProp, dropdownOptions: dropdownOptions, selectedDropdownOption: selectedDropdownOption, onDropdownOptionSelect: onDropdownOptionSelect, searchItems: searchItems, setSearchItems: setSearchItems, handleFilter: handleFilter }));
49
21
  case "number":
50
- return (_jsx(SearchNumberInput, { closeOutSearch: () => { }, setResetSearch: () => { }, setEditingHeader: () => { }, column: undefined, dropdownIconProp: dropdownIconProp, dropdownOptions: dropdownOptions, selectedDropdownOption: selectedDropdownOption, onDropdownOptionSelect: onDropdownOptionSelect, toggleStatus: toggleStatus, setToggleStatus: setToggleStatus, minValue: minValue, maxValue: maxValue, setMinValue: setMinValue, setMaxValue: setMaxValue }));
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 }));
51
23
  case "multiSelect":
52
- {
53
- console.log(dropdownOptions, "dropdownOptions");
54
- }
55
- return (_jsx(SearchDropdownInput, { options: dropdownOptions, isSearchable: true, placeholder: "Search", isMulti: true, hideSelectedOptions: true, closeMenuOnSelect: false, inputWidth: "w-full", inputTextSize: "text-sm", additionalClasses: "", customClassNames: {}, onChange: onChange, value: [], selectedValue: selectedValue, bgColor: bgColor, textHighlight: textHighlight }));
56
- case "boolean":
24
+ return (_jsx(SearchDropdownInput, { options: dropdownOptions, isSearchable: true, placeholder: "Search", isMulti: true, hideSelectedOptions: true, closeMenuOnSelect: false, inputWidth: "w-full", inputTextSize: "text-sm", additionalClasses: "", customClassNames: {}, onChange: onChange, value: [], selectedValue: selectedValue, bgColor: bgColor, textHighlight: textHighlight, handleFilter: handleFilter }));
57
25
  case "date":
58
- // Make sure control & valueKey exist before using them
59
- if (!control || !valueKey) {
60
- return (_jsxs("div", { className: "text-red-500", children: ["Missing ", _jsx("code", { children: "control" }), " or", " ", _jsx("code", { children: "valueKey" }), " prop for React Hook Form"] }));
61
- }
62
- return (_jsx(Controller, { name: valueKey, control: control, defaultValue: getDefaultValue(dynamicDefaultValue, valueKey), render: ({ field }) => (_jsx("div", { className: "inline-flex items-center", children: _jsxs("label", { className: "flex items-center cursor-pointer relative", children: [_jsx("input", { type: "checkbox", className: "peer h-5 w-5 cursor-pointer transition-all appearance-none rounded border border-stroke", id: valueKey, checked: !!field.value, onChange: (e) => {
63
- // You can log the value here:
64
- console.log("Checkbox changed to:", e.target.checked);
65
- field.onChange(e.target.checked);
66
- } }), _jsx("span", { className: "absolute text-white opacity-0 peer-checked:opacity-100 top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2", children: _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-3.5 w-3.5", viewBox: "0 0 20 20", fill: "currentColor", stroke: "currentColor", strokeWidth: "1", children: _jsx("path", { fillRule: "evenodd", d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z", clipRule: "evenodd" }) }) })] }) })) }));
67
- default:
68
- return null;
26
+ return (_jsx(SearchDatePickerInput, { textHighlight: textHighlight, dropdownOptions: dropdownOptions, selectedDropdownOption: selectedDropdownOption, onDropdownOptionSelect: onDropdownOptionSelect, toggleStatus: toggleStatus, setToggleStatus: setToggleStatus, selectedDate: selectedDate, onDateSelect: onDateSelect, selectedStartDate: selectedStartDate, onStartDateSelect: onStartDateSelect, selectedEndDate: selectedEndDate, onEndDateSelect: onEndDateSelect, handleFilter: handleFilter }));
69
27
  }
70
28
  })() }));
71
29
  };
@@ -6,4 +6,4 @@ export declare const TextInput: any;
6
6
  export declare const NumberInput: any;
7
7
  export declare const DropdownInput: any;
8
8
  export declare const BooleanInput: any;
9
- export declare const DisabledInput: any;
9
+ export declare const DatePickerInput: any;
@@ -1,6 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import SearchInput from "./SearchInput";
3
- import { getFontAwesomeIcon } from "../../utils/getFontAwesomeIcon";
4
3
  import { useState } from "react";
5
4
  export default {
6
5
  title: "Components/SearchInput",
@@ -13,10 +12,6 @@ export default {
13
12
  options: ["text", "number", "boolean", "date", "multiSelect"],
14
13
  },
15
14
  },
16
- closeOutSearch: { control: "none", table: { disable: true } },
17
- setResetSearch: { control: "none", table: { disable: true } },
18
- column: { control: "none", table: { disable: true } },
19
- setEditingHeader: { control: "none", table: { disable: true } },
20
15
  dropdownIconProp: {
21
16
  control: "object",
22
17
  description: "Icon configuration for dropdown",
@@ -56,6 +51,10 @@ const Template = (args) => {
56
51
  const [minValue, setMinValue] = useState();
57
52
  const [maxValue, setMaxValue] = useState();
58
53
  const [selectedValue, setSelectedValue] = useState(args.selectedValue || []);
54
+ // NEW: State for date control
55
+ const [selectedDate, setSelectedDate] = useState(args.selectedDate);
56
+ const [selectedStartDate, setSelectedStartDate] = useState(args.selectedStartDate);
57
+ const [selectedEndDate, setSelectedEndDate] = useState(args.selectedEndDate);
59
58
  // Handle onChange from the multi-select
60
59
  const handleOnChange = (newSelected) => {
61
60
  setSelectedValue(newSelected);
@@ -63,23 +62,25 @@ const Template = (args) => {
63
62
  args.onChange?.(newSelected);
64
63
  console.log("Selected items:", newSelected);
65
64
  };
66
- return (_jsx(SearchInput, { ...args, selectedDropdownOption: selectedOption, onDropdownOptionSelect: (option) => setSelectedOption(option), searchItems: searchItems, setSearchItems: setSearchItems, toggleStatus: toggleStatus, setToggleStatus: setToggleStatus, minValue: minValue, maxValue: maxValue, setMinValue: setMinValue, setMaxValue: setMaxValue, onChange: handleOnChange, selectedValue: selectedValue }));
65
+ return (_jsx(SearchInput, { ...args, selectedDropdownOption: selectedOption, onDropdownOptionSelect: (option) => setSelectedOption(option), searchItems: searchItems, setSearchItems: setSearchItems, toggleStatus: toggleStatus, setToggleStatus: setToggleStatus, minValue: minValue, maxValue: maxValue, setMinValue: setMinValue, setMaxValue: setMaxValue, onChange: handleOnChange, selectedValue: selectedValue, selectedDate: selectedDate, onDateSelect: setSelectedDate, selectedStartDate: selectedStartDate, onStartDateSelect: setSelectedStartDate, selectedEndDate: selectedEndDate, onEndDateSelect: setSelectedEndDate }));
67
66
  };
68
67
  export const Default = Template.bind({});
69
68
  Default.args = {
70
69
  inputType: "text",
71
- column: mockColumn,
72
- closeOutSearch: (value) => console.log(`Search cleared: ${value}`),
73
- setResetSearch: () => console.log("Reset search triggered"),
74
- setEditingHeader: (value) => console.log(`Editing header: ${value}`),
70
+ handleFilter: () => console.log(`Filter applied`),
71
+ dropdownOptions: [
72
+ "Starts with",
73
+ "Ends with",
74
+ "Exactly",
75
+ "Includes",
76
+ "Excludes",
77
+ ],
78
+ selectedDropdownOption: "Starts with",
75
79
  };
76
80
  export const TextInput = Template.bind({});
77
81
  TextInput.args = {
78
82
  inputType: "text",
79
- column: mockColumn,
80
- closeOutSearch: (value) => console.log(`Search cleared: ${value}`),
81
- setResetSearch: () => console.log("Reset search triggered"),
82
- setEditingHeader: (value) => console.log(`Editing header: ${value}`),
83
+ handleFilter: () => console.log(`Filter applied`),
83
84
  pillColor: "bg-sky-500",
84
85
  textHighlight: "text-sky-500",
85
86
  dropdownIconProp: {
@@ -99,10 +100,7 @@ TextInput.args = {
99
100
  export const NumberInput = Template.bind({});
100
101
  NumberInput.args = {
101
102
  inputType: "number",
102
- column: mockColumn,
103
- closeOutSearch: (value) => console.log(`Search cleared: ${value}`),
104
- setResetSearch: () => console.log("Reset search triggered"),
105
- setEditingHeader: (value) => console.log(`Editing header: ${value}`),
103
+ handleFilter: () => console.log(`Filter applied`),
106
104
  dropdownIconProp: {
107
105
  iconClasses: "text-sky-500",
108
106
  name: "chevronDown",
@@ -114,67 +112,48 @@ NumberInput.args = {
114
112
  export const DropdownInput = Template.bind({});
115
113
  DropdownInput.args = {
116
114
  inputType: "multiSelect",
117
- column: mockColumn,
118
- closeOutSearch: (value) => console.log(`Search cleared: ${value}`),
119
- setResetSearch: () => console.log("Reset search triggered"),
120
- setEditingHeader: (value) => console.log(`Editing header: ${value}`),
115
+ handleFilter: () => console.log(`Filter applied`),
121
116
  placeholder: "Search",
122
117
  dropdownOptions: [
123
118
  { uuid: "1", name: "Option 1", value: "option1" },
124
119
  { uuid: "2", name: "Option 2", value: "option2" },
125
120
  { uuid: "3", name: "Option 3", value: "option3" },
126
121
  ],
127
- /** For multi-select, `value` is typically an array */
128
122
  selectedValue: [],
129
- // onChange: (selected: OptionType[]) => {
130
- // console.log("Selected items:", selected);
131
- // },
132
- /** Additional props you might want to set */
133
123
  isSearchable: true,
134
124
  hasSelectAll: true,
135
125
  disabled: false,
136
126
  isLoading: false,
137
127
  type: "multiSelect",
138
- // etc...
139
128
  };
140
129
  export const BooleanInput = Template.bind({});
141
130
  BooleanInput.args = {
142
131
  inputType: "multiSelect",
143
- column: mockColumn,
144
- closeOutSearch: (value) => console.log(`Search cleared: ${value}`),
145
- setResetSearch: () => console.log("Reset search triggered"),
146
- setEditingHeader: (value) => console.log(`Editing header: ${value}`),
132
+ handleFilter: () => console.log(`Filter applied`),
147
133
  placeholder: "Search",
148
134
  dropdownOptions: [
149
135
  { uuid: "1", name: "True", value: "true" },
150
136
  { uuid: "2", name: "False", value: "false" },
151
137
  ],
152
138
  selectedValue: [],
153
- // onChange: (selected: OptionType[]) => {
154
- // console.log("Selected items:", selected);
155
- // },
156
139
  isSearchable: true,
157
140
  hasSelectAll: true,
158
141
  disabled: false,
159
142
  isLoading: false,
160
143
  type: "multiSelect",
161
- // etc...
162
144
  };
163
- export const DisabledInput = Template.bind({});
164
- DisabledInput.args = {
165
- inputType: "text",
166
- inputName: "disabledInput",
167
- hasPlaceholder: true,
168
- placeholder: "Disabled...",
169
- inputTextSize: "text-sm",
170
- inputShape: "rounded",
171
- backgroundColor: "bg-gray-200",
172
- inputWidth: "w-72",
173
- inputBorderClasses: "border border-gray-400 cursor-not-allowed",
174
- buttonText: _jsx("span", { children: "Disabled" }),
175
- buttonClasses: "bg-gray-500 text-gray-300 px-4 py-2 rounded",
176
- buttonIcon: getFontAwesomeIcon("ban"),
177
- buttonIconClasses: "text-gray-400",
178
- containerClasses: "flex items-center",
179
- onButtonClick: () => alert("Button is disabled."),
145
+ export const DatePickerInput = Template.bind({});
146
+ DatePickerInput.args = {
147
+ inputType: "date",
148
+ handleFilter: () => console.log(`Filter applied`),
149
+ textHighlight: "text-sky-500",
150
+ dropdownOptions: ["Exactly", "Before", "After"],
151
+ selectedDropdownOption: "Exactly",
152
+ onDropdownOptionSelect: (option) => console.log(`Option selected: ${option}`),
153
+ searchItems: [],
154
+ setSearchItems: () => { },
155
+ toggleStatus: false,
156
+ setToggleStatus: () => { },
157
+ themeBgColor: "bg-sky-500",
158
+ lightThemeBg: "bg-sky-100",
180
159
  };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,519 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { render, screen, fireEvent } from "@testing-library/react";
3
+ import { describe, expect, test, vi } from "vitest";
4
+ import SearchInput from "./SearchInput";
5
+ const mockOnDropdownOptionSelect = vi.fn();
6
+ const mockSetSearchItems = vi.fn();
7
+ const mockSetToggleStatus = vi.fn();
8
+ const mockSetMinValue = vi.fn();
9
+ const mockSetMaxValue = vi.fn();
10
+ const mockOnDateSelect = vi.fn();
11
+ const mockOnStartDateSelect = vi.fn();
12
+ const mockOnEndDateSelect = vi.fn();
13
+ const mockOnChange = vi.fn();
14
+ const mockHandleIconClick = vi.fn();
15
+ const mockHandleFilter = vi.fn();
16
+ const defaultProps = {
17
+ handleFilter: mockHandleFilter,
18
+ inputType: "text",
19
+ dropdownOptions: ["Option 1", "Option 2"],
20
+ selectedDropdownOption: "Option 1",
21
+ onDropdownOptionSelect: mockOnDropdownOptionSelect,
22
+ searchItems: [],
23
+ setSearchItems: mockSetSearchItems,
24
+ toggleStatus: false,
25
+ setToggleStatus: mockSetToggleStatus,
26
+ minValue: "",
27
+ maxValue: "",
28
+ setMinValue: mockSetMinValue,
29
+ setMaxValue: mockSetMaxValue,
30
+ selectedDate: null,
31
+ onDateSelect: mockOnDateSelect,
32
+ selectedStartDate: null,
33
+ onStartDateSelect: mockOnStartDateSelect,
34
+ selectedEndDate: null,
35
+ onEndDateSelect: mockOnEndDateSelect,
36
+ onChange: mockOnChange,
37
+ selectedValue: [],
38
+ value: [],
39
+ handleIconClick: mockHandleIconClick,
40
+ };
41
+ describe("SearchInput Component", () => {
42
+ describe("Text Input", () => {
43
+ test("renders search input field", () => {
44
+ render(_jsx(SearchInput, { ...defaultProps }));
45
+ expect(screen.getByPlaceholderText("Search")).toBeInTheDocument();
46
+ });
47
+ test("updates input value on change", () => {
48
+ render(_jsx(SearchInput, { ...defaultProps }));
49
+ const input = screen.getByPlaceholderText("Search");
50
+ fireEvent.change(input, { target: { value: "Test Input" } });
51
+ expect(input).toHaveValue("Test Input");
52
+ });
53
+ test("does not add empty search input to search items on enter press", () => {
54
+ render(_jsx(SearchInput, { ...defaultProps }));
55
+ const input = screen.getByPlaceholderText("Search");
56
+ fireEvent.keyDown(input, { key: "Enter", code: "Enter" });
57
+ expect(mockSetSearchItems).toHaveBeenCalled();
58
+ });
59
+ test("adds valid input to search items on enter press", () => {
60
+ render(_jsx(SearchInput, { ...defaultProps }));
61
+ const input = screen.getByPlaceholderText("Search");
62
+ fireEvent.change(input, { target: { value: "New Search" } });
63
+ fireEvent.keyDown(input, { key: "Enter", code: "Enter" });
64
+ expect(mockSetSearchItems).toHaveBeenCalledWith(["New Search"]);
65
+ });
66
+ test("clears input when clear icon is clicked", () => {
67
+ render(_jsx(SearchInput, { ...defaultProps }));
68
+ const input = screen.getByPlaceholderText("Search");
69
+ fireEvent.change(input, { target: { value: "Clear me" } });
70
+ const clearIcon = screen.getByTestId("clear-icon");
71
+ fireEvent.click(clearIcon);
72
+ expect(input).toHaveValue("");
73
+ });
74
+ test("removes search criterion when delete icon is clicked", () => {
75
+ render(_jsx(SearchInput, { ...defaultProps, searchItems: ["Test Item"] }));
76
+ fireEvent.click(screen.getByText("Test Item")); // Assuming clicking the item removes it
77
+ expect(mockSetSearchItems).toHaveBeenCalledWith([]);
78
+ });
79
+ test("renders dropdown with options", () => {
80
+ render(_jsx(SearchInput, { ...defaultProps }));
81
+ const dropdownTrigger = screen.getByText("Option 1"); // Default selected option
82
+ fireEvent.click(dropdownTrigger);
83
+ expect(screen.getByText("Option 2")).toBeInTheDocument();
84
+ });
85
+ test("calls dropdown selection handler when an option is clicked", () => {
86
+ render(_jsx(SearchInput, { ...defaultProps }));
87
+ const dropdownTrigger = screen.getByText("Option 1");
88
+ fireEvent.click(dropdownTrigger);
89
+ const option = screen.getByText("Option 2");
90
+ expect(option).toBeInTheDocument();
91
+ fireEvent.click(option);
92
+ expect(mockOnDropdownOptionSelect).toHaveBeenCalledWith("Option 2");
93
+ });
94
+ test("handles multiple items in search field", () => {
95
+ render(_jsx(SearchInput, { ...defaultProps, searchItems: ["Item 1", "Item 2"] }));
96
+ expect(screen.getByText("Item 1")).toBeInTheDocument();
97
+ expect(screen.getByText("Item 2")).toBeInTheDocument();
98
+ });
99
+ test("removes individual search item when close icon is clicked", () => {
100
+ render(_jsx(SearchInput, { ...defaultProps, searchItems: ["Item 1", "Item 2"] }));
101
+ const item1 = screen.getByText("Item 1");
102
+ fireEvent.click(item1);
103
+ expect(mockSetSearchItems).toHaveBeenCalledWith(["Item 2"]);
104
+ });
105
+ test("clears all search items when clicking on clear button", () => {
106
+ render(_jsx(SearchInput, { ...defaultProps, searchItems: ["Item 1", "Item 2"] }));
107
+ const clearIcons = screen.getAllByTestId("item-clear-icon");
108
+ expect(clearIcons).toHaveLength(2);
109
+ clearIcons.forEach((icon) => fireEvent.click(icon));
110
+ expect(mockSetSearchItems).toHaveBeenCalled();
111
+ });
112
+ test("renders a different dropdown icon when dropdownIconProp is provided", () => {
113
+ render(_jsx(SearchInput, { ...defaultProps, dropdownIconProp: {
114
+ iconClasses: "text-red-500",
115
+ name: "arrowDown",
116
+ weight: "bold",
117
+ } }));
118
+ const dropdownIconContainer = screen.getByTestId("dropdown-icon");
119
+ expect(dropdownIconContainer).toHaveClass("text-red-500");
120
+ console.log(dropdownIconContainer.classList);
121
+ });
122
+ test("does not add input text to search items when non-Enter key is pressed", () => {
123
+ render(_jsx(SearchInput, { ...defaultProps }));
124
+ const input = screen.getByPlaceholderText("Search");
125
+ fireEvent.change(input, { target: { value: "Test Input" } });
126
+ const initialCallCount = mockSetSearchItems.mock.calls.length;
127
+ fireEvent.keyDown(input, { key: "Escape", code: "Escape" });
128
+ expect(mockSetSearchItems.mock.calls.length).toBe(initialCallCount);
129
+ expect(input).toHaveValue("Test Input");
130
+ });
131
+ });
132
+ describe("Number Input", () => {
133
+ test("renders number input fields", () => {
134
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "number" }));
135
+ expect(screen.getByPlaceholderText("Amount")).toBeInTheDocument();
136
+ });
137
+ test("shows min and max fields only when toggle is clicked", () => {
138
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "number", toggleStatus: false }));
139
+ const toggleCheckbox = screen.getByRole("checkbox");
140
+ expect(toggleCheckbox).toBeInTheDocument();
141
+ fireEvent.click(toggleCheckbox);
142
+ expect(mockSetToggleStatus).toHaveBeenCalledWith(true);
143
+ // Re-render the component with the updated state
144
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "number", toggleStatus: true }));
145
+ expect(screen.getByPlaceholderText("Min")).toBeInTheDocument();
146
+ expect(screen.getByPlaceholderText("Max")).toBeInTheDocument();
147
+ });
148
+ test("updates min value on change after toggle is clicked", () => {
149
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "number", toggleStatus: true }));
150
+ const minInput = screen.getByPlaceholderText("Min");
151
+ fireEvent.change(minInput, { target: { value: "10" } });
152
+ expect(mockSetMinValue).toHaveBeenCalledWith("10");
153
+ });
154
+ test("updates max value on change after toggle is clicked", () => {
155
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "number", toggleStatus: true }));
156
+ const maxInput = screen.getByPlaceholderText("Max");
157
+ fireEvent.change(maxInput, { target: { value: "100" } });
158
+ expect(mockSetMaxValue).toHaveBeenCalledWith("100");
159
+ });
160
+ test("Filter button should be present", () => {
161
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "number" }));
162
+ const filterButton = screen.getByText("Filter");
163
+ expect(filterButton).toBeInTheDocument();
164
+ });
165
+ test("updates min value on input change", () => {
166
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "number", toggleStatus: true }));
167
+ const minInput = screen.getByPlaceholderText("Min");
168
+ fireEvent.change(minInput, { target: { value: "25" } });
169
+ expect(mockSetMinValue).toHaveBeenCalledWith("25");
170
+ });
171
+ test("renders a different dropdown icon when dropdownIconProp is provided", () => {
172
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "number", dropdownIconProp: {
173
+ iconClasses: "text-red-500",
174
+ name: "arrowDown",
175
+ weight: "bold",
176
+ } }));
177
+ const dropdownIconContainer = screen.getByTestId("dropdown-icon");
178
+ expect(dropdownIconContainer).toHaveClass("text-red-500");
179
+ });
180
+ });
181
+ describe("Dropdown Input", () => {
182
+ test("renders dropdown input with placeholder", () => {
183
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "multiSelect" }));
184
+ // Ensure the dropdown renders with the placeholder "Search"
185
+ expect(screen.getByText("Search")).toBeInTheDocument();
186
+ });
187
+ test("opens dropdown and selects an option", async () => {
188
+ const mockOnChange = vi.fn();
189
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "multiSelect", onChange: mockOnChange, dropdownOptions: [
190
+ {
191
+ uuid: "1",
192
+ name: "Option 1",
193
+ value: "option1",
194
+ label: "Option 1",
195
+ },
196
+ {
197
+ uuid: "2",
198
+ name: "Option 2",
199
+ value: "option2",
200
+ label: "Option 2",
201
+ },
202
+ ] }));
203
+ // Open dropdown
204
+ const dropdown = screen.getByText(/Search/i);
205
+ fireEvent.click(dropdown);
206
+ // Wait for "Select All" option to appear
207
+ const option = await screen.findByText("Select All");
208
+ fireEvent.click(option);
209
+ // Assert that onChange received the correct selection
210
+ expect(mockOnChange).toHaveBeenCalled();
211
+ });
212
+ test("clears all selections when Clear button is clicked", () => {
213
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "multiSelect", selectedValue: [{ name: "Option 1", value: "option1" }] }));
214
+ const clearButton = screen.getByRole("button", { name: /clear/i });
215
+ fireEvent.click(clearButton);
216
+ expect(mockOnChange).toHaveBeenCalledWith([]);
217
+ });
218
+ test("Clears when Clear button is clicked", async () => {
219
+ const mockOnChange = vi.fn();
220
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "multiSelect", onChange: mockOnChange, dropdownOptions: [
221
+ {
222
+ uuid: "1",
223
+ name: "Option 1",
224
+ value: "option1",
225
+ label: "Option 1",
226
+ },
227
+ {
228
+ uuid: "2",
229
+ name: "Option 2",
230
+ value: "option2",
231
+ label: "Option 2",
232
+ },
233
+ ] }));
234
+ const dropdown = screen.getByText(/Search/i);
235
+ fireEvent.click(dropdown);
236
+ const ClearButton = await screen.findByText("Clear");
237
+ fireEvent.click(ClearButton);
238
+ expect(mockOnChange).toHaveBeenCalled();
239
+ });
240
+ test("calls handleFilter on Filter button click and stops propagation", async () => {
241
+ const mockHandleFilter = vi.fn();
242
+ const mockStopPropagation = vi.fn();
243
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "multiSelect", handleFilter: mockHandleFilter, dropdownOptions: [
244
+ {
245
+ uuid: "1",
246
+ name: "Option 1",
247
+ value: "option1",
248
+ label: "Option 1",
249
+ },
250
+ {
251
+ uuid: "2",
252
+ name: "Option 2",
253
+ value: "option2",
254
+ label: "Option 2",
255
+ },
256
+ ] }));
257
+ const dropdown = screen.getByText(/Search/i);
258
+ fireEvent.click(dropdown);
259
+ const ClearButton = await screen.findByText("Filter");
260
+ fireEvent.click(ClearButton);
261
+ expect(mockHandleFilter).toHaveBeenCalled();
262
+ });
263
+ });
264
+ describe("Boolean Input", () => {
265
+ const mockOnChange = vi.fn();
266
+ test("renders boolean input with placeholder", () => {
267
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "multiSelect", dropdownOptions: [
268
+ {
269
+ uuid: "1",
270
+ name: "True",
271
+ value: "true",
272
+ label: "True",
273
+ },
274
+ {
275
+ uuid: "2",
276
+ name: "False",
277
+ value: "false",
278
+ label: "False",
279
+ },
280
+ ] }));
281
+ expect(screen.getByText(/Search/i)).toBeInTheDocument();
282
+ });
283
+ test("opens boolean dropdown and selects an option", async () => {
284
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "multiSelect", onChange: mockOnChange, dropdownOptions: [
285
+ {
286
+ uuid: "1",
287
+ name: "True",
288
+ value: "true",
289
+ label: "True",
290
+ },
291
+ {
292
+ uuid: "2",
293
+ name: "False",
294
+ value: "false",
295
+ label: "False",
296
+ },
297
+ ] }));
298
+ // Open dropdown
299
+ const dropdown = screen.getByText(/Search/i);
300
+ fireEvent.click(dropdown);
301
+ const option = await screen.findByText("True");
302
+ fireEvent.click(option);
303
+ expect(mockOnChange).toHaveBeenCalledWith(expect.arrayContaining([{ name: "True", value: "true" }]));
304
+ });
305
+ test("clears all selections when Clear button is clicked", async () => {
306
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "multiSelect", selectedValue: [{ uuid: "1", name: "True", value: "true" }], onChange: mockOnChange, dropdownOptions: [
307
+ {
308
+ uuid: "1",
309
+ name: "True",
310
+ value: "true",
311
+ label: "True",
312
+ },
313
+ {
314
+ uuid: "2",
315
+ name: "False",
316
+ value: "false",
317
+ label: "False",
318
+ },
319
+ ] }));
320
+ // Open dropdown
321
+ const dropdown = screen.getByText("True");
322
+ fireEvent.click(dropdown);
323
+ // Find and click "Clear" button
324
+ const clearButton = await screen.findByText("Clear");
325
+ fireEvent.click(clearButton);
326
+ // Verify clearing of selections
327
+ expect(mockOnChange).toHaveBeenCalledWith([]);
328
+ });
329
+ });
330
+ describe("DateTimePicker Input", () => {
331
+ const mockOnDateSelect = vi.fn();
332
+ const mockOnStartDateSelect = vi.fn();
333
+ const mockOnEndDateSelect = vi.fn();
334
+ const mockSetToggleStatus = vi.fn();
335
+ const mockSetEditingHeader = vi.fn();
336
+ const mockCloseOutSearch = vi.fn();
337
+ const mockSetResetSearch = vi.fn();
338
+ const mockHandleFilter = vi.fn();
339
+ // Mock scrollIntoView to prevent errors in test execution
340
+ Element.prototype.scrollIntoView = vi.fn();
341
+ const defaultProps = {
342
+ handleFilter: mockHandleFilter,
343
+ closeOutSearch: mockCloseOutSearch,
344
+ setResetSearch: mockSetResetSearch,
345
+ setEditingHeader: mockSetEditingHeader,
346
+ toggleStatus: false,
347
+ setToggleStatus: mockSetToggleStatus,
348
+ selectedDate: null,
349
+ onDateSelect: mockOnDateSelect,
350
+ selectedStartDate: null,
351
+ onStartDateSelect: mockOnStartDateSelect,
352
+ selectedEndDate: null,
353
+ onEndDateSelect: mockOnEndDateSelect,
354
+ dropdownOptions: ["Option 1", "Option 2"],
355
+ selectedDropdownOption: "Option 1",
356
+ onDropdownOptionSelect: vi.fn(),
357
+ onChange: mockOnChange,
358
+ selectedValue: [],
359
+ value: [],
360
+ };
361
+ test("renders single date picker input inside SearchInput", () => {
362
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "date" }));
363
+ expect(screen.getByText("Select Date")).toBeInTheDocument();
364
+ });
365
+ test("opens date picker when input is clicked", () => {
366
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "date" }));
367
+ const dateInput = screen.getByText("Select Date");
368
+ fireEvent.click(dateInput);
369
+ expect(screen.getByRole("grid")).toBeInTheDocument(); // DayPicker should appear
370
+ });
371
+ test("selects a single date from the picker", () => {
372
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "date" }));
373
+ fireEvent.click(screen.getByText("Select Date"));
374
+ const today = new Date().getDate();
375
+ fireEvent.click(screen.getByText(today.toString()));
376
+ expect(mockOnDateSelect).toHaveBeenCalled();
377
+ });
378
+ test("renders range date picker inputs when toggle is clicked", () => {
379
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "date", toggleStatus: true }));
380
+ expect(screen.getByText("Start Date")).toBeInTheDocument();
381
+ expect(screen.getByText("End Date")).toBeInTheDocument();
382
+ });
383
+ test("opens start date picker when Start Date is clicked", () => {
384
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "date", toggleStatus: true }));
385
+ const startDateInput = screen.getByText("Start Date");
386
+ fireEvent.click(startDateInput);
387
+ expect(screen.getByRole("grid")).toBeInTheDocument();
388
+ });
389
+ test("opens end date picker when End Date is clicked", () => {
390
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "date", toggleStatus: true }));
391
+ const endDateInput = screen.getByText("End Date");
392
+ fireEvent.click(endDateInput);
393
+ expect(screen.getByRole("grid")).toBeInTheDocument();
394
+ });
395
+ test("selects a start date from the picker", () => {
396
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "date", toggleStatus: true }));
397
+ fireEvent.click(screen.getByText("Start Date"));
398
+ const today = new Date().getDate();
399
+ fireEvent.click(screen.getByText(today.toString()));
400
+ expect(mockOnStartDateSelect).toHaveBeenCalled();
401
+ });
402
+ test("selects an end date from the picker", () => {
403
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "date", toggleStatus: true }));
404
+ fireEvent.click(screen.getByText("End Date"));
405
+ const tomorrow = new Date();
406
+ tomorrow.setDate(tomorrow.getDate() + 1);
407
+ fireEvent.click(screen.getByText(tomorrow.getDate().toString()));
408
+ expect(mockOnEndDateSelect).toHaveBeenCalled();
409
+ });
410
+ test("closes date picker when clicking outside", () => {
411
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "date" }));
412
+ const dateInput = screen.getByText("Select Date");
413
+ fireEvent.click(dateInput);
414
+ expect(screen.getByRole("grid")).toBeInTheDocument(); // Calendar is open
415
+ // Simulate clicking outside
416
+ fireEvent.mouseDown(document.body);
417
+ expect(screen.queryByRole("grid")).not.toBeInTheDocument(); // Calendar should be closed
418
+ });
419
+ test("calls handleSubmitClick and closes date picker when Filter button is clicked", () => {
420
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "date" }));
421
+ fireEvent.click(screen.getByText("Select Date")); // Open the calendar
422
+ expect(screen.getByRole("grid")).toBeInTheDocument();
423
+ fireEvent.click(screen.getByText("Filter")); // Click the filter button
424
+ expect(mockHandleFilter).toHaveBeenCalled();
425
+ expect(screen.queryByRole("grid")).not.toBeInTheDocument(); // Ensure picker is closed
426
+ });
427
+ test("does not close date picker if clicking inside", () => {
428
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "date" }));
429
+ fireEvent.click(screen.getByText("Select Date")); // Open the calendar
430
+ expect(screen.getByRole("grid")).toBeInTheDocument();
431
+ // Simulate clicking inside
432
+ fireEvent.mouseDown(screen.getByRole("grid"));
433
+ expect(screen.getByRole("grid")).toBeInTheDocument(); // Calendar should remain open
434
+ });
435
+ test("ensures handleSubmitClick closes the date picker and resets active input", () => {
436
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "date" }));
437
+ fireEvent.click(screen.getByText("Select Date"));
438
+ expect(screen.getByRole("grid")).toBeInTheDocument();
439
+ fireEvent.click(screen.getByText("Filter"));
440
+ expect(mockHandleFilter).toHaveBeenCalled();
441
+ expect(screen.queryByRole("grid")).not.toBeInTheDocument();
442
+ });
443
+ test("ensures clicking on dropdown opens dropdown options", () => {
444
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "date" }));
445
+ const dropdownTrigger = screen.getByText("Option 1");
446
+ fireEvent.click(dropdownTrigger);
447
+ expect(screen.getByText("Option 2")).toBeInTheDocument();
448
+ });
449
+ test("ensures clicking on an option in dropdown selects it", () => {
450
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "date" }));
451
+ const dropdownTrigger = screen.getByText("Option 1");
452
+ fireEvent.click(dropdownTrigger);
453
+ const option = screen.getByText("Option 2");
454
+ fireEvent.click(option);
455
+ expect(defaultProps.onDropdownOptionSelect).toHaveBeenCalledWith("Option 2");
456
+ });
457
+ test("ensures toggle button switches mode correctly", () => {
458
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "date" }));
459
+ const toggleCheckbox = screen.getByRole("checkbox");
460
+ fireEvent.click(toggleCheckbox);
461
+ expect(mockSetToggleStatus).toHaveBeenCalledWith(true);
462
+ });
463
+ test("ensures selecting a start and end date updates state", () => {
464
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "date", toggleStatus: true }));
465
+ fireEvent.click(screen.getByText("Start Date"));
466
+ fireEvent.click(screen.getByText(new Date().getDate().toString()));
467
+ expect(mockOnStartDateSelect).toHaveBeenCalled();
468
+ fireEvent.click(screen.getByText("End Date"));
469
+ fireEvent.click(screen.getByText(new Date().getDate().toString()));
470
+ expect(mockOnEndDateSelect).toHaveBeenCalled();
471
+ });
472
+ test("toggles range mode when toggle button is clicked", () => {
473
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "date" }));
474
+ const toggleCheckbox = screen.getByRole("checkbox");
475
+ fireEvent.click(toggleCheckbox);
476
+ expect(mockSetToggleStatus).toHaveBeenCalledWith(true);
477
+ });
478
+ test("renders selectedStartDate if provided, otherwise shows default text", () => {
479
+ const mockStartDate = new Date(2023, 5, 15); // June 15, 2023
480
+ const { rerender } = render(_jsx(SearchInput, { ...defaultProps, inputType: "date", toggleStatus: true, selectedStartDate: null }));
481
+ expect(screen.getByText("Start Date")).toBeInTheDocument();
482
+ rerender(_jsx(SearchInput, { ...defaultProps, inputType: "date", toggleStatus: true, selectedStartDate: mockStartDate }));
483
+ expect(screen.getByText(mockStartDate.toLocaleDateString())).toBeInTheDocument();
484
+ });
485
+ test("calls onStartDateSelect when a start date is selected", () => {
486
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "date", toggleStatus: true }));
487
+ // Open the Start Date Picker
488
+ fireEvent.click(screen.getByText("Start Date"));
489
+ // Pick a date (e.g., today's date)
490
+ const today = new Date().getDate();
491
+ fireEvent.click(screen.getByText(today.toString()));
492
+ // Expect the handler to be called
493
+ expect(mockOnStartDateSelect).toHaveBeenCalled();
494
+ });
495
+ test("calls onEndDateSelect when an end date is selected", () => {
496
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "date", toggleStatus: true }));
497
+ // Open the End Date Picker
498
+ fireEvent.click(screen.getByText("End Date"));
499
+ const tomorrow = new Date();
500
+ tomorrow.setDate(tomorrow.getDate() + 1);
501
+ fireEvent.click(screen.getByText(tomorrow.getDate().toString()));
502
+ // Expect the handler to be called
503
+ expect(mockOnEndDateSelect).toHaveBeenCalled();
504
+ });
505
+ test("calls onDateSelect when a single date is selected", () => {
506
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "date" }));
507
+ // Open the Date Picker
508
+ fireEvent.click(screen.getByText("Select Date"));
509
+ const today = new Date().getDate();
510
+ fireEvent.click(screen.getByText(today.toString()));
511
+ // Expect the handler to be called
512
+ expect(mockOnDateSelect).toHaveBeenCalled();
513
+ });
514
+ test("shows placeholder text when no date is selected", () => {
515
+ render(_jsx(SearchInput, { ...defaultProps, inputType: "date", selectedDate: null }));
516
+ expect(screen.getByText("Select Date")).toBeInTheDocument();
517
+ });
518
+ });
519
+ });
@@ -1,22 +1,13 @@
1
1
  import React from "react";
2
2
  import { Control } from "react-hook-form";
3
- import { Accessor, ColumnInstance } from "react-table";
4
- type ColumnWithAccessor<T extends object> = ColumnInstance<T> & {
5
- accessor?: string | number | symbol | Accessor<T>;
6
- };
7
3
  export type SearchInputProps<T extends object> = {
8
4
  onChange(newSelected: OptionType[]): unknown;
9
5
  selectedValue: any[];
10
6
  value: any[];
11
- closeOutSearch: (value: number | null) => void;
12
- setResetSearch: React.Dispatch<React.SetStateAction<boolean>>;
13
- columHeader?: any;
14
- column: ColumnWithAccessor<T>;
15
- parentIndex?: number;
16
- setEditingHeader: (value: number | null) => void;
7
+ handleFilter: () => void;
17
8
  bgColor?: string;
18
9
  textHighlight?: string;
19
- inputType?: string;
10
+ inputType?: 'text' | 'number' | 'date' | 'boolean' | 'multiSelect';
20
11
  dropdownOptions?: string[] | OptionType[] | number[];
21
12
  selectedDropdownOption?: string | OptionType | number;
22
13
  onDropdownOptionSelect?: (option: string) => void;
@@ -32,6 +23,12 @@ export type SearchInputProps<T extends object> = {
32
23
  control?: Control<any>;
33
24
  valueKey?: string;
34
25
  dynamicDefaultValue?: any;
26
+ selectedDate?: Date;
27
+ onDateSelect?: (date: Date) => void;
28
+ selectedStartDate?: Date;
29
+ onStartDateSelect?: (date: Date) => void;
30
+ selectedEndDate?: Date;
31
+ onEndDateSelect?: (date: Date) => void;
35
32
  };
36
33
  export interface OptionType {
37
34
  uuid: string;
@@ -44,4 +41,3 @@ export type searchDropdownIconProps = {
44
41
  weight: string;
45
42
  iconClasses: string;
46
43
  };
47
- export {};
@@ -0,0 +1,23 @@
1
+ import React from "react";
2
+ import "react-day-picker/dist/style.css";
3
+ import { searchDropdownIconProps } from "./SearchInput.types";
4
+ type SearchDatePickerInputProps<T extends object> = {
5
+ textHighlight?: string;
6
+ dropdownOptions?: string[];
7
+ selectedDropdownOption?: string;
8
+ onDropdownOptionSelect?: (option: string) => void;
9
+ dropdownIconProp?: searchDropdownIconProps;
10
+ toggleStatus?: boolean;
11
+ setToggleStatus?: React.Dispatch<React.SetStateAction<boolean>>;
12
+ themeBgColor?: string;
13
+ lightThemeBg?: string;
14
+ selectedDate?: Date;
15
+ onDateSelect?: (date: Date) => void;
16
+ selectedStartDate?: Date;
17
+ onStartDateSelect?: (date: Date) => void;
18
+ selectedEndDate?: Date;
19
+ onEndDateSelect?: (date: Date) => void;
20
+ handleFilter?: () => void;
21
+ };
22
+ declare function SearchDatePickerInput<T extends object>({ textHighlight, dropdownOptions, selectedDropdownOption, onDropdownOptionSelect, dropdownIconProp, toggleStatus, setToggleStatus, themeBgColor, lightThemeBg, selectedDate, onDateSelect, selectedStartDate, onStartDateSelect, selectedEndDate, onEndDateSelect, handleFilter, }: SearchDatePickerInputProps<T>): import("react/jsx-runtime").JSX.Element;
23
+ export default SearchDatePickerInput;
@@ -0,0 +1,72 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useEffect, useRef, useState } from "react";
3
+ import { DayPicker } from "react-day-picker";
4
+ import "react-day-picker/dist/style.css";
5
+ import Dropdown from "../Dropdown/Dropdown";
6
+ import ToggleButton from "../ToggleButton/ToggleButton";
7
+ import BaseButton from "../BaseButton";
8
+ function SearchDatePickerInput({ textHighlight = "text-sky-700", dropdownOptions = [], selectedDropdownOption = "", onDropdownOptionSelect, dropdownIconProp = {
9
+ iconClasses: "text-sky-500",
10
+ name: "chevronDown",
11
+ weight: "solid",
12
+ }, toggleStatus = false, setToggleStatus, themeBgColor = "bg-sky-500", lightThemeBg = "bg-sky-100", selectedDate, onDateSelect, selectedStartDate, onStartDateSelect, selectedEndDate, onEndDateSelect, handleFilter, }) {
13
+ const containerRef = useRef(null);
14
+ // Remove internal state for the date values (they come from props)
15
+ // Internal UI state for showing the calendar and active input remains:
16
+ const [isDatePickerOpen, setIsDatePickerOpen] = useState(false);
17
+ const [activeInput, setActiveInput] = useState(null);
18
+ useEffect(() => {
19
+ containerRef.current?.scrollIntoView();
20
+ }, []);
21
+ // Close calendar(s) when clicking outside the container
22
+ useEffect(() => {
23
+ function handleClickOutside(event) {
24
+ if (containerRef.current &&
25
+ !containerRef.current.contains(event.target)) {
26
+ setIsDatePickerOpen(false);
27
+ setActiveInput(null);
28
+ }
29
+ }
30
+ document.addEventListener("mousedown", handleClickOutside);
31
+ return () => {
32
+ document.removeEventListener("mousedown", handleClickOutside);
33
+ };
34
+ }, []);
35
+ // Handler for the Filter button remains similar,
36
+ // but it now uses the values from props.
37
+ const handleSubmitClick = () => {
38
+ // Close the calendar(s) after filtering
39
+ setIsDatePickerOpen(false);
40
+ setActiveInput(null);
41
+ handleFilter();
42
+ };
43
+ const modifiersClassNames = {
44
+ selected: `${themeBgColor} text-white rounded-full`,
45
+ today: `${lightThemeBg} ${textHighlight}`,
46
+ };
47
+ return (_jsxs("div", { ref: containerRef, className: "relative w-[425px] border-2 p-4", children: [_jsx("div", { className: "flex items-center justify-between h-12", children: toggleStatus ? (
48
+ // Toggle mode: two separate inputs with a "to" between them
49
+ _jsxs("div", { className: "flex items-center w-full", children: [_jsx("button", { onClick: () => setActiveInput("start"), className: "border-2 px-3 py-2 flex-1 h-10 text-left", children: selectedStartDate
50
+ ? selectedStartDate.toLocaleDateString()
51
+ : "Start Date" }), _jsx("span", { className: "mx-2", children: "to" }), _jsx("button", { onClick: () => setActiveInput("end"), className: "border-2 px-3 py-2 flex-1 h-10 text-left", children: selectedEndDate
52
+ ? selectedEndDate.toLocaleDateString()
53
+ : "End Date" })] })) : (
54
+ // Non-toggle mode: Dropdown and a single date input
55
+ _jsxs(_Fragment, { children: [_jsx(Dropdown, { options: dropdownOptions, selectedOption: selectedDropdownOption, onOptionSelect: onDropdownOptionSelect, optionClasses: "px-4 h-full flex items-center", menuClasses: "bg-white min-w-[150px] top-[-8px] left-[-2px]", dropdownClasses: "border-2 border-r-0 flex-[1] h-10 w-auto", icon: dropdownIconProp }), _jsx("button", { onClick: () => setIsDatePickerOpen((prev) => !prev), className: "border-2 px-3 py-2 flex-[2] h-10 text-left", children: selectedDate
56
+ ? selectedDate.toLocaleDateString()
57
+ : "Select Date" })] })) }), toggleStatus
58
+ ? activeInput && (_jsx("div", { className: "absolute p-4 top-16 w-auto z-50 shadow-lg bg-white", children: activeInput === "start" ? (_jsx(DayPicker, { mode: "single", selected: selectedStartDate, onSelect: (date) => {
59
+ if (onStartDateSelect)
60
+ onStartDateSelect(date);
61
+ setActiveInput(null); // close calendar after selection
62
+ }, modifiersClassNames: modifiersClassNames })) : (_jsx(DayPicker, { mode: "single", selected: selectedEndDate, onSelect: (date) => {
63
+ if (onEndDateSelect)
64
+ onEndDateSelect(date);
65
+ setActiveInput(null); // close calendar after selection
66
+ }, modifiersClassNames: modifiersClassNames })) }))
67
+ : isDatePickerOpen && (_jsx("div", { className: "absolute p-4 top-16 w-auto z-50 shadow-lg bg-white", children: _jsx(DayPicker, { mode: "single", selected: selectedDate, onSelect: (date) => {
68
+ if (onDateSelect)
69
+ onDateSelect(date);
70
+ }, modifiersClassNames: modifiersClassNames }) })), _jsxs("div", { className: "flex justify-between items-end bg-white px-2 rounded-md mt-4", 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: handleSubmitClick, shape: "rounded-full" })] })] }));
71
+ }
72
+ export default SearchDatePickerInput;
@@ -1,31 +1,19 @@
1
- import { Accessor } from "react-table";
2
1
  import React from "react";
3
- import { ColumnInstance } from "react-table";
4
2
  import { searchDropdownIconProps } from "./SearchInput.types";
5
- type ColumnWithAccessor<T extends object> = ColumnInstance<T> & {
6
- accessor?: string | number | symbol | Accessor<T>;
7
- };
8
3
  type SearchNumberInputProps<T extends object> = {
9
- closeOutSearch: (value: number | null) => void;
10
- setResetSearch: React.Dispatch<React.SetStateAction<boolean>>;
11
- columHeader?: any;
12
- parentIndex?: number;
13
4
  pillColor?: string;
14
5
  textHighlight?: string;
15
- column: ColumnWithAccessor<T>;
16
- setEditingHeader: (value: number | null) => void;
17
6
  dropdownOptions?: string[];
18
7
  selectedDropdownOption?: string;
19
8
  onDropdownOptionSelect?: (option: string) => void;
20
9
  dropdownIconProp?: searchDropdownIconProps;
21
- searchItems?: string[];
22
- setSearchItems?: React.Dispatch<React.SetStateAction<string[]>>;
23
10
  toggleStatus?: boolean;
24
11
  setToggleStatus?: React.Dispatch<React.SetStateAction<boolean>>;
25
12
  minValue?: string;
26
13
  setMinValue?: React.Dispatch<React.SetStateAction<string>>;
27
14
  maxValue?: string;
28
15
  setMaxValue?: React.Dispatch<React.SetStateAction<string>>;
16
+ handleFilter?: () => void;
29
17
  };
30
- declare const SearchNumberInput: <T extends object>({ closeOutSearch, setResetSearch, setEditingHeader, textHighlight, column, dropdownIconProp, dropdownOptions, selectedDropdownOption, onDropdownOptionSelect, searchItems, setSearchItems, toggleStatus, setToggleStatus, minValue, setMinValue, maxValue, setMaxValue, }: SearchNumberInputProps<T>) => import("react/jsx-runtime").JSX.Element;
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;
31
19
  export default SearchNumberInput;
@@ -5,11 +5,11 @@ 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 SearchNumberInput = ({ closeOutSearch, setResetSearch, setEditingHeader, textHighlight = "text-sky-500", column, dropdownIconProp = {
8
+ const SearchNumberInput = ({ textHighlight = "text-sky-500", dropdownIconProp = {
9
9
  iconClasses: textHighlight,
10
10
  name: "chevronDown",
11
11
  weight: "solid",
12
- }, dropdownOptions = [], selectedDropdownOption = "", onDropdownOptionSelect, searchItems = [], setSearchItems, toggleStatus, setToggleStatus, minValue, setMinValue, maxValue, setMaxValue, }) => {
12
+ }, dropdownOptions = [], selectedDropdownOption = "", onDropdownOptionSelect, toggleStatus, setToggleStatus, minValue, setMinValue, maxValue, setMaxValue, handleFilter, }) => {
13
13
  const containerRef = useRef(null);
14
14
  const inputRef = useRef(null);
15
15
  // Focus the input when editing starts (if needed)
@@ -22,39 +22,20 @@ const SearchNumberInput = ({ closeOutSearch, setResetSearch, setEditingHeader, t
22
22
  const handleMaximumInputChange = (event) => {
23
23
  setMaxValue(event.target.value);
24
24
  };
25
- const handleSubmitClick = () => {
26
- let safeHeader;
27
- if (typeof column.Header === "string") {
28
- safeHeader = column.Header;
29
- }
30
- else {
31
- safeHeader = column.accessor || "Unnamed Column";
32
- }
33
- if (!minValue) {
34
- // Remove criterion if text is empty
35
- }
36
- else {
37
- // Update or add criterion
38
- }
39
- setEditingHeader(null);
40
- };
41
- const handleIconClick = (item) => {
42
- // Remove criterion
43
- const filteredItems = searchItems.filter((ele) => ele !== item);
44
- setSearchItems(filteredItems);
45
- setResetSearch((prevResetSearch) => !prevResetSearch);
46
- closeOutSearch(null);
47
- };
48
- const handleKeyDown = (e) => {
49
- if (e.key === "Enter") {
50
- e.preventDefault();
51
- // setSearchItems([...searchItems, localSearchText]);
52
- // setLocalSearchText("");
53
- handleSubmitClick();
54
- }
55
- };
56
- 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", onKeyDown: handleKeyDown, required: false, id: "", name: "", type: "number", onChange: handleInputChange, additionalClasses: "min-w-[180px] max-w-[180px] h-10 text-gray flex border-2 focus:border-transparent ", 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", onKeyDown: handleKeyDown, required: false, id: "", name: "", type: "number", onChange: handleMaximumInputChange, additionalClasses: "min-w-[180px] max-w-[180px] h-10 text-gray flex border-2 focus:border-transparent ", 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 border-r-2 w-auto", icon: dropdownIconProp }), _jsx(Input, { focusRingColor: "focus:ring-transparent", hasAutoFocus: true, value: minValue, iconColor: "text-navy-400", onKeyDown: handleKeyDown, required: false, id: "", name: "", type: "number", onChange: handleInputChange, additionalClasses: "min-w-[200px] h-10 text-gray flex ", placeholder: "Amount", hasIcons: true, iconPosition: "both" })] })) }), _jsxs("div", { className: "flex flex-[1] justify-between items-end bg-white px-2 rounded-md ", children: [_jsx(ToggleButton, { initialStatus: toggleStatus, onClick: () => {
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 border-2 focus:border-transparent ", 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-transparent ", 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 rounded-md ", children: [_jsx(ToggleButton, { initialStatus: toggleStatus, onClick: () => {
57
38
  setToggleStatus(!toggleStatus);
58
- }, 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: handleSubmitClick, shape: "rounded-full" })] })] }) }));
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" })] })] }) }));
59
40
  };
60
41
  export default SearchNumberInput;
@@ -1,24 +1,15 @@
1
- import { Accessor } from "react-table";
2
1
  import React from "react";
3
- import { ColumnInstance } from "react-table";
4
2
  import { searchDropdownIconProps } from "./SearchInput.types";
5
- type ColumnWithAccessor<T extends object> = ColumnInstance<T> & {
6
- accessor?: string | number | symbol | Accessor<T>;
7
- };
8
3
  type SearchTextInputProps<T extends object> = {
9
- closeOutSearch: (value: number | null) => void;
10
- setResetSearch: React.Dispatch<React.SetStateAction<boolean>>;
11
- columHeader?: any;
12
4
  pillColor?: string;
13
5
  textHighlight?: string;
14
- column: ColumnWithAccessor<T>;
15
- setEditingHeader: (value: number | null) => void;
16
6
  dropdownIconProp?: searchDropdownIconProps;
17
7
  selectedDropdownOption?: string;
18
8
  onDropdownOptionSelect?: (option: string) => void;
19
9
  dropdownOptions?: string[];
20
10
  searchItems?: string[];
21
11
  setSearchItems?: React.Dispatch<React.SetStateAction<string[]>>;
12
+ handleFilter?: () => void;
22
13
  };
23
- declare const SearchTextInput: <T extends object>({ closeOutSearch, setResetSearch, setEditingHeader, pillColor, textHighlight, column, dropdownIconProp, dropdownOptions, selectedDropdownOption, onDropdownOptionSelect, searchItems, setSearchItems, }: SearchTextInputProps<T>) => import("react/jsx-runtime").JSX.Element;
14
+ declare const SearchTextInput: <T extends object>({ pillColor, textHighlight, dropdownIconProp, dropdownOptions, selectedDropdownOption, onDropdownOptionSelect, searchItems, setSearchItems, handleFilter, }: SearchTextInputProps<T>) => import("react/jsx-runtime").JSX.Element;
24
15
  export default SearchTextInput;
@@ -6,11 +6,11 @@ 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
- const SearchTextInput = ({ closeOutSearch, setResetSearch, setEditingHeader, pillColor = "bg-sky-500", textHighlight = "text-sky-500", column, dropdownIconProp = {
9
+ const SearchTextInput = ({ pillColor = "bg-sky-500", textHighlight = "text-sky-500", dropdownIconProp = {
10
10
  iconClasses: textHighlight,
11
11
  name: "chevronDown",
12
12
  weight: "solid",
13
- }, dropdownOptions = [], selectedDropdownOption = "", onDropdownOptionSelect, searchItems = [], setSearchItems, }) => {
13
+ }, dropdownOptions = [], selectedDropdownOption = "", onDropdownOptionSelect, searchItems = [], setSearchItems, handleFilter, }) => {
14
14
  const containerRef = useRef(null);
15
15
  const [localSearchText, setLocalSearchText] = useState("");
16
16
  const inputRef = useRef(null);
@@ -21,45 +21,26 @@ const SearchTextInput = ({ closeOutSearch, setResetSearch, setEditingHeader, pil
21
21
  const handleInputChange = (event) => {
22
22
  setLocalSearchText(event.target.value);
23
23
  };
24
- const handleSubmitClick = () => {
25
- const trimmedSearchText = localSearchText.trim();
26
- let safeHeader;
27
- if (typeof column.Header === "string") {
28
- safeHeader = column.Header;
29
- }
30
- else {
31
- safeHeader = column.accessor || "Unnamed Column";
32
- }
33
- if (trimmedSearchText === "") {
34
- // Remove criterion if text is empty
35
- }
36
- else {
37
- // Update or add criterion
38
- }
39
- setEditingHeader(null);
40
- };
41
24
  const handleIconClick = (item) => {
42
25
  // Remove criterion
43
26
  const filteredItems = searchItems.filter((ele) => ele !== item);
44
27
  setSearchItems(filteredItems);
45
- setResetSearch((prevResetSearch) => !prevResetSearch);
46
- closeOutSearch(null);
47
28
  };
48
29
  const handleKeyDown = (e) => {
49
30
  if (e.key === "Enter") {
50
31
  e.preventDefault();
51
32
  setSearchItems([...searchItems, localSearchText]);
52
33
  setLocalSearchText("");
53
- handleSubmitClick();
34
+ handleFilter();
54
35
  }
55
36
  };
56
37
  const pillClassnames = `${pillColor} p-1 max-w-fit min-w-20 rounded-full flex justify-between items-center text-white text-xs px-4 border-none mr-4`;
57
38
  return (_jsx("div", { ref: containerRef, className: "w-[425px]", children: _jsxs("div", { className: "flex flex-col border-2 border-navy-200 rounded-md", children: [_jsxs("div", { className: `flex ${searchItems.length ? "border-b-2" : ""} h-full`, children: [_jsx(Dropdown, { options: dropdownOptions, selectedOption: selectedDropdownOption, onOptionSelect: onDropdownOptionSelect, optionClasses: "px-4 py-1 h-full flex items-center", menuClasses: "bg-white min-w-32", icon: dropdownIconProp, dropdownClasses: "border-0 border-r-2 w-auto" }), _jsx(Input, { focusRingColor: "focus:ring-transparent", hasAutoFocus: true, value: localSearchText, iconColor: "text-navy-400", onKeyDown: handleKeyDown, required: false, id: "", name: "", type: "text", onChange: handleInputChange, additionalClasses: " min-w-[250px] min-h-full text-gray flex", placeholder: "Search", hasIcons: true, firstIcon: localSearchText === "" ? (_jsx(AnimatePresence, { children: _jsx(motion.div, { initial: "initial", animate: "animate", exit: "exit", className: "text-navy-400", children: getFontAwesomeIcon("search", "regular") }) })) : undefined, iconPosition: "both", secondIcon: _jsx("div", { className: "border-transparent text-white min-w-9", children: _jsx(AnimatePresence, { children: localSearchText !== "" && (_jsxs(motion.div, { className: "flex justify-between items-center min-w-4 text-navy-400 hover:cursor-pointer hover:text-primary", initial: "initial", animate: "animate", exit: "exit", children: [_jsx("div", { className: "bg-navy-50 pr-2 pl-1 text-gray-500", onClick: () => {
58
39
  setLocalSearchText("");
59
- }, children: getFontAwesomeIcon("xmark", "regular") }), _jsx("div", { className: `${textHighlight} text-sm hover:text-primary`, children: getFontAwesomeIcon("search", "solid") })] })) }) }), onIconClick: () => {
40
+ }, "data-testid": "clear-icon", children: getFontAwesomeIcon("xmark", "regular") }), _jsx("div", { className: `${textHighlight} text-sm hover:text-primary`, children: getFontAwesomeIcon("search", "solid") })] })) }) }), onIconClick: () => {
60
41
  setLocalSearchText("");
61
42
  } })] }), searchItems?.length ? (_jsx("div", { className: " flex bg-white py-2 px-2 rounded-md ", children: searchItems?.map((item, index) => {
62
- return (_jsx(Badge, { backgroundColor: pillColor, borderRadius: "rounded-full", hasMobileStyle: true, hasRightIcon: true, icon: _jsx("div", { className: "text-white text-xxs", children: getFontAwesomeIcon("xmark", "solid") }), iconSize: "text-sm", mobileIconLabel: item, onClick: () => handleIconClick(item), text: _jsx(Text, { color: "text-white", fontFamily: "font-serif", size: "text-sm", tag: "span", text: item }), badgeContainerClasses: pillClassnames, type: "span" }));
43
+ return (_jsx(Badge, { backgroundColor: pillColor, borderRadius: "rounded-full", hasMobileStyle: true, hasRightIcon: true, icon: _jsx("div", { className: "text-white text-xxs", "data-testid": "item-clear-icon", children: getFontAwesomeIcon("xmark", "solid") }), iconSize: "text-sm", mobileIconLabel: item, onClick: () => handleIconClick(item), text: _jsx(Text, { color: "text-white", fontFamily: "font-serif", size: "text-sm", tag: "span", text: item }), badgeContainerClasses: pillClassnames, type: "span" }));
63
44
  }) })) : null] }) }));
64
45
  };
65
46
  export default SearchTextInput;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@agilant/toga-blox",
3
3
  "private": false,
4
- "version": "1.0.47",
4
+ "version": "1.0.48",
5
5
  "description": "",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -34,6 +34,7 @@
34
34
  "framer-motion": "^11.0.8",
35
35
  "nouislider": "^15.8.1",
36
36
  "react": "^18.2.0",
37
+ "react-day-picker": "^9.5.1",
37
38
  "react-dom": "^18.2.0",
38
39
  "react-multi-select-component": "^4.3.4",
39
40
  "react-router-dom": "^6.16.0",