@zauru-sdk/components 2.0.66 → 2.0.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,14 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [2.0.67](https://github.com/intuitiva/zauru-typescript-sdk/compare/v2.0.66...v2.0.67) (2024-11-15)
7
+
8
+ **Note:** Version bump only for package @zauru-sdk/components
9
+
10
+
11
+
12
+
13
+
6
14
  ## [2.0.66](https://github.com/intuitiva/zauru-typescript-sdk/compare/v2.0.65...v2.0.66) (2024-11-13)
7
15
 
8
16
  **Note:** Version bump only for package @zauru-sdk/components
@@ -18,6 +18,7 @@ type Props = {
18
18
  style?: React.CSSProperties;
19
19
  className?: string;
20
20
  required?: boolean;
21
+ autoComplete?: React.HTMLInputAutoCompleteAttribute;
21
22
  };
22
23
  export declare const TextField: (props: Props) => import("react/jsx-runtime").JSX.Element;
23
24
  export {};
@@ -38,18 +38,58 @@ export const SelectField = (props) => {
38
38
  setIsOpen(false);
39
39
  }
40
40
  };
41
- if (defaultValue) {
42
- setValue(defaultValue);
43
- setInputValue(defaultValue.label);
44
- if (setFormValue) {
45
- setFormValue(name || "", defaultValue.value);
46
- }
47
- }
48
41
  document.addEventListener("mousedown", handleClickOutside);
49
42
  return () => {
50
43
  document.removeEventListener("mousedown", handleClickOutside);
51
44
  };
52
45
  }, []);
46
+ const handleSetSingleValue = (value) => {
47
+ if (value) {
48
+ setValue(value);
49
+ setInputValue(value.label);
50
+ if (setFormValue) {
51
+ setFormValue(name || "", value.value);
52
+ }
53
+ }
54
+ else {
55
+ setValue(null);
56
+ setInputValue("");
57
+ if (setFormValue) {
58
+ setFormValue(name || "", "");
59
+ }
60
+ }
61
+ onChange && onChange(value ?? null);
62
+ };
63
+ const handleAddMultiValue = (value) => {
64
+ if (value) {
65
+ const existValue = options.some((v) => v.value === value.value);
66
+ const noEstaYaSeleccionado = !valueMulti.some((v) => v.value === value.value);
67
+ if (existValue && noEstaYaSeleccionado) {
68
+ const newValue = [...valueMulti, value];
69
+ setValueMulti(newValue);
70
+ if (setFormValue) {
71
+ setFormValue(name || "", newValue.map((v) => v.value));
72
+ }
73
+ onChangeMulti && onChangeMulti(newValue);
74
+ }
75
+ }
76
+ else {
77
+ setValueMulti([]);
78
+ if (setFormValue) {
79
+ setFormValue(name || "", []);
80
+ }
81
+ setInputValue("");
82
+ onChangeMulti && onChangeMulti([]);
83
+ }
84
+ };
85
+ const handleRemoveMultiValue = (value) => {
86
+ const newValue = valueMulti.filter((v) => v.value !== value.value);
87
+ setValueMulti(newValue);
88
+ if (setFormValue) {
89
+ setFormValue(name || "", newValue.map((v) => v.value));
90
+ }
91
+ onChangeMulti && onChangeMulti(newValue);
92
+ };
53
93
  const handleInputChange = (e) => {
54
94
  const newValue = e.target.value;
55
95
  if (register) {
@@ -62,44 +102,23 @@ export const SelectField = (props) => {
62
102
  };
63
103
  const handleOptionClick = (option) => {
64
104
  if (isMulti) {
65
- const newValue = valueMulti.some((v) => v.value === option.value)
66
- ? valueMulti.filter((v) => v.value !== option.value)
67
- : [...valueMulti, option];
68
- setValueMulti(newValue);
69
- onChangeMulti && onChangeMulti(newValue);
70
- if (setFormValue) {
71
- setFormValue(name || "", newValue.map((v) => v.value));
72
- }
105
+ handleAddMultiValue(option);
73
106
  }
74
107
  else {
75
- setValue(option);
76
- setInputValue(option.label);
77
- onChange && onChange(option);
78
- if (setFormValue) {
79
- setFormValue(name || "", option.value);
80
- }
108
+ handleSetSingleValue(option);
81
109
  }
82
110
  setHighlightedIndex(-1);
83
111
  setIsSearching(false);
84
- setFilteredOptions([]);
112
+ setFilteredOptions(options);
85
113
  setIsOpen(false);
86
114
  };
87
115
  const handleClear = () => {
88
116
  if (isMulti) {
89
- setValueMulti([]);
90
- onChangeMulti && onChangeMulti([]);
91
- if (setFormValue) {
92
- setFormValue(name || "", []);
93
- }
117
+ handleAddMultiValue();
94
118
  }
95
119
  else {
96
- setValue(null);
97
- onChange && onChange(null);
98
- if (setFormValue) {
99
- setFormValue(name || "", "");
100
- }
120
+ handleSetSingleValue();
101
121
  }
102
- setInputValue("");
103
122
  };
104
123
  const handleBlur = () => {
105
124
  setTimeout(() => {
@@ -109,6 +128,7 @@ export const SelectField = (props) => {
109
128
  else if (isTabPressed && filteredOptions.length > 0 && isSearching) {
110
129
  handleOptionClick(filteredOptions[0]);
111
130
  }
131
+ setHighlightedIndex(-1);
112
132
  setIsTabPressed(false);
113
133
  setIsSearching(false);
114
134
  setIsOpen(false);
@@ -155,13 +175,13 @@ export const SelectField = (props) => {
155
175
  }
156
176
  return (_jsxs("div", { className: `col-span-6 sm:col-span-3 ${className}`, ref: selectRef, children: [title && (_jsxs("label", { htmlFor: error ? `${name}-error` : `${name}-success`, className: `block text-sm font-medium ${color === "red"
157
177
  ? "text-red-700 dark:text-red-500"
158
- : "text-gray-700 dark:text-gray-500"}`, children: [title, required && _jsx("span", { className: "text-red-500", children: "*" })] })), _jsxs("div", { className: "relative", children: [_jsx("input", { type: "text", id: id, value: inputValue, onFocus: () => setIsOpen(true), onKeyDown: handleKeyDown, readOnly: isReadOnly, disabled: disabled, className: `block w-full rounded-md ${bgColor} ${borderColor} ${textColor} shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm pr-10`, placeholder: isMulti ? "Select options..." : "Select an option...", autoComplete: "off", onChange: handleInputChange, onBlur: handleBlur, required: required }), _jsx("input", { type: "hidden", ...(register ?? {}), name: name, value: isMulti
178
+ : "text-gray-700 dark:text-gray-500"}`, children: [title, required && _jsx("span", { className: "text-red-500", children: "*" })] })), _jsxs("div", { className: "relative", children: [_jsxs("div", { className: "flex items-center", children: [_jsx("input", { type: "text", id: id, value: inputValue, onFocus: () => setIsOpen(true), onKeyDown: handleKeyDown, readOnly: isReadOnly, disabled: disabled, className: `block w-full rounded-md ${bgColor} ${borderColor} ${textColor} shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm pr-10`, placeholder: isMulti ? "Select options..." : "Select an option...", autoComplete: "off", onChange: handleInputChange, onBlur: handleBlur, required: required }), isClearable && (value || valueMulti.length > 0) && (_jsx("button", { type: "button", onClick: handleClear, className: "absolute inset-y-0 right-0 pr-3 flex items-center", children: "\u00D7" })), helpText && (_jsx("div", { className: "flex items-center relative ml-3", children: _jsxs("div", { className: "relative cursor-pointer", onMouseEnter: () => setShowTooltip(true), onMouseLeave: () => setShowTooltip(false), children: [_jsx(IdeaIconSVG, {}), showTooltip && (_jsx("div", { className: "absolute -left-48 top-0 mt-8 p-2 bg-white border rounded shadow text-black z-50", children: helpText }))] }) }))] }), _jsx("input", { type: "hidden", ...(register ?? {}), name: name, value: isMulti
159
179
  ? valueMulti.map((v) => v.value).join(",")
160
- : value?.value || "" }), isClearable && (value || valueMulti.length > 0) && (_jsx("button", { type: "button", onClick: handleClear, className: "absolute inset-y-0 right-0 pr-3 flex items-center", children: "\u00D7" })), !isClearable && (value || valueMulti.length > 0) && (_jsx("span", { className: "absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none", children: _jsx("svg", { className: "h-5 w-5 text-green-500", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }) })), isOpen && !isReadOnly && (_jsx("ul", { ref: optionsRef, className: "absolute z-10 mt-1 w-full bg-white shadow-lg max-h-60 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm", children: filteredOptions.map((option, index) => (_jsx("li", { className: `cursor-pointer select-none relative py-2 pl-3 pr-9 ${(isMulti
180
+ : value?.value || "" }), isOpen && !isReadOnly && (_jsx("ul", { ref: optionsRef, className: "absolute z-10 mt-1 w-full bg-white shadow-lg max-h-60 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm", children: filteredOptions.map((option, index) => (_jsx("li", { className: `cursor-pointer select-none relative py-2 pl-3 pr-9 ${(isMulti
161
181
  ? valueMulti.some((v) => v.value === option.value)
162
182
  : value?.value === option.value)
163
183
  ? "text-white bg-indigo-600"
164
184
  : index === highlightedIndex
165
185
  ? "text-black bg-sky-200"
166
- : "text-gray-900"}`, onClick: () => handleOptionClick(option), onMouseEnter: () => setHighlightedIndex(index), onMouseLeave: () => setHighlightedIndex(-1), children: option.label }, `${option.value}-${index}`))) }))] }), isMulti && (_jsx("div", { className: "mt-2 flex flex-wrap gap-2", children: valueMulti.map((option, index) => (_jsxs("span", { className: "bg-blue-100 text-blue-800 text-xs font-semibold mr-2 px-2.5 py-0.5 rounded", children: [option.label, _jsx("button", { type: "button", onClick: () => handleOptionClick(option), className: "ml-1 text-blue-600 hover:text-blue-800", children: "\u00D7" })] }, `${option.value}-${index}`))) })), helpText && (_jsx("div", { className: "flex items-center relative mt-1", children: _jsxs("div", { className: "relative cursor-pointer", onMouseEnter: () => setShowTooltip(true), onMouseLeave: () => setShowTooltip(false), children: [_jsx(IdeaIconSVG, {}), showTooltip && (_jsx("div", { className: "absolute -left-48 top-0 mt-8 p-2 bg-white border rounded shadow text-black z-50", children: helpText }))] }) })), error && (_jsxs("p", { className: `mt-2 text-sm text-${color}-600 dark:text-${color}-500`, children: [_jsx("span", { className: "font-medium", children: "Oops!" }), " ", error?.message?.toString() || "Error desconocido"] })), !error && hint && (_jsx("p", { className: `mt-2 italic text-sm text-${color}-500 dark:text-${color}-400`, children: hint }))] }));
186
+ : "text-gray-900"}`, onClick: () => handleOptionClick(option), onMouseEnter: () => setHighlightedIndex(index), onMouseLeave: () => setHighlightedIndex(-1), children: option.label }, `${option.value}-${index}`))) }))] }), isMulti && valueMulti.length > 0 && (_jsx("div", { className: "mt-2 flex flex-wrap gap-2", children: valueMulti.map((option, index) => (_jsxs("span", { className: "bg-blue-100 text-blue-800 text-xs font-semibold mr-2 px-2.5 py-0.5 rounded", children: [option.label, _jsx("button", { type: "button", onClick: () => handleRemoveMultiValue(option), className: "ml-1 text-blue-600 hover:text-blue-800", children: "\u00D7" })] }, `${option.value}-${index}`))) })), error && (_jsxs("p", { className: `mt-2 text-sm text-${color}-600 dark:text-${color}-500`, children: [_jsx("span", { className: "font-medium", children: "Oops!" }), " ", error?.message?.toString() || "Error desconocido"] })), !error && hint && (_jsx("p", { className: `mt-2 italic text-sm text-${color}-500 dark:text-${color}-400`, children: hint }))] }));
167
187
  };
@@ -3,7 +3,7 @@ import { IdeaIconSVG } from "@zauru-sdk/icons";
3
3
  import { useEffect, useState } from "react";
4
4
  import { useFormContext } from "react-hook-form";
5
5
  export const TextField = (props) => {
6
- const { id, name, defaultValue = "", hidden, type = "text", onChange, onKeyDown, disabled = false, readOnly = false, min, integer = false, stopChangeEvents, style, title, helpText, className = "", hint, required, } = props;
6
+ const { id, name, defaultValue = "", hidden, type = "text", onChange, onKeyDown, disabled = false, readOnly = false, min, integer = false, stopChangeEvents, style, title, helpText, className = "", hint, required, autoComplete = "off", } = props;
7
7
  const [showTooltip, setShowTooltip] = useState(false);
8
8
  const [value, setValue] = useState(defaultValue);
9
9
  const { register: tempRegister, formState: { errors }, setValue: setOnFormValue, } = useFormContext() || { formState: {} }; // Obtener el contexto solo si existe
@@ -56,13 +56,13 @@ export const TextField = (props) => {
56
56
  if (hidden) {
57
57
  return (_jsx("input", { type: type, id: id ?? name, value: value, hidden: true, ...(register ?? {}), name: name, onChange: handleInputChange }));
58
58
  }
59
- const inputComponent = (_jsx("input", { type: type, readOnly: isReadOnly, disabled: disabled, id: id ?? name, autoComplete: "off", value: value, onWheel: (e) => {
59
+ const inputComponent = (_jsx("input", { type: type, readOnly: isReadOnly, disabled: disabled, id: id ?? name, value: value, onWheel: (e) => {
60
60
  e.currentTarget.blur();
61
61
  }, step: type === "number" ? 0.01 : undefined, onKeyDown: (event) => {
62
62
  handleKeyDown(event);
63
63
  onKeyDown && onKeyDown(event);
64
- }, min: min, style: style, className: `block w-full rounded-md ${bgColor} ${borderColor} ${textColor} shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm`, ...(register ?? {}), name: name, onChange: handleInputChange }));
65
- if (!error && !title) {
64
+ }, min: min, style: style, className: `block w-full rounded-md ${bgColor} ${borderColor} ${textColor} shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm`, ...(register ?? {}), name: name, autoComplete: autoComplete, onChange: handleInputChange }));
65
+ if (!error && !title && !helpText) {
66
66
  return _jsx("div", { className: `${className}`, children: inputComponent });
67
67
  }
68
68
  return (_jsxs("div", { className: `col-span-6 sm:col-span-3 ${className}`, children: [title && (_jsxs("label", { htmlFor: error ? `${name}-error` : `${name}-success`, className: `block mb-1 text-sm font-medium text-${color}-700 dark:text-${color}-500`, children: [title, required && _jsx("span", { className: "text-red-500", children: "*" })] })), _jsxs("div", { className: "flex relative items-center", children: [inputComponent, helpText && (_jsx("div", { className: "flex items-center relative ml-3", children: _jsxs("div", { className: "relative cursor-pointer", onMouseEnter: () => setShowTooltip(true), onMouseLeave: () => setShowTooltip(false), children: [_jsx(IdeaIconSVG, {}), showTooltip && (_jsx("div", { className: "absolute -left-48 top-0 mt-8 p-2 bg-white border rounded shadow text-black z-50", children: helpText }))] }) }))] }), error && (_jsxs("p", { className: `mt-2 text-sm text-${color}-600 dark:text-${color}-500`, children: [_jsx("span", { className: "font-medium", children: "Oops!" }), " ", error.message?.toString()] })), !error && hint && (_jsx("p", { className: `mt-2 italic text-sm text-${color}-500 dark:text-${color}-400`, children: hint }))] }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zauru-sdk/components",
3
- "version": "2.0.66",
3
+ "version": "2.0.67",
4
4
  "description": "Componentes reutilizables en las WebApps de Zauru.",
5
5
  "main": "./dist/esm/index.js",
6
6
  "module": "./dist/esm/index.js",
@@ -37,7 +37,7 @@
37
37
  "@zauru-sdk/hooks": "^2.0.66",
38
38
  "@zauru-sdk/icons": "^2.0.0",
39
39
  "@zauru-sdk/types": "^2.0.51",
40
- "@zauru-sdk/utils": "^2.0.64",
40
+ "@zauru-sdk/utils": "^2.0.67",
41
41
  "framer-motion": "^11.7.0",
42
42
  "jsonwebtoken": "^9.0.2",
43
43
  "react": "^18.2.0",
@@ -49,5 +49,5 @@
49
49
  "styled-components": "^5.3.5",
50
50
  "zod": "^3.23.8"
51
51
  },
52
- "gitHead": "9448a1f8c79c28126c09778ad4da0c38a5a88908"
52
+ "gitHead": "375907d0686b86fb116f4831ce7807097179c3f5"
53
53
  }
@@ -94,20 +94,68 @@ export const SelectField = (props: Props) => {
94
94
  }
95
95
  };
96
96
 
97
- if (defaultValue) {
98
- setValue(defaultValue);
99
- setInputValue(defaultValue.label);
100
- if (setFormValue) {
101
- setFormValue(name || "", defaultValue.value);
102
- }
103
- }
104
-
105
97
  document.addEventListener("mousedown", handleClickOutside);
106
98
  return () => {
107
99
  document.removeEventListener("mousedown", handleClickOutside);
108
100
  };
109
101
  }, []);
110
102
 
103
+ const handleSetSingleValue = (value?: SelectFieldOption) => {
104
+ if (value) {
105
+ setValue(value);
106
+ setInputValue(value.label);
107
+ if (setFormValue) {
108
+ setFormValue(name || "", value.value);
109
+ }
110
+ } else {
111
+ setValue(null);
112
+ setInputValue("");
113
+ if (setFormValue) {
114
+ setFormValue(name || "", "");
115
+ }
116
+ }
117
+ onChange && onChange(value ?? null);
118
+ };
119
+
120
+ const handleAddMultiValue = (value?: SelectFieldOption) => {
121
+ if (value) {
122
+ const existValue = options.some((v) => v.value === value.value);
123
+ const noEstaYaSeleccionado = !valueMulti.some(
124
+ (v) => v.value === value.value
125
+ );
126
+ if (existValue && noEstaYaSeleccionado) {
127
+ const newValue = [...valueMulti, value];
128
+ setValueMulti(newValue);
129
+ if (setFormValue) {
130
+ setFormValue(
131
+ name || "",
132
+ newValue.map((v) => v.value)
133
+ );
134
+ }
135
+ onChangeMulti && onChangeMulti(newValue);
136
+ }
137
+ } else {
138
+ setValueMulti([]);
139
+ if (setFormValue) {
140
+ setFormValue(name || "", []);
141
+ }
142
+ setInputValue("");
143
+ onChangeMulti && onChangeMulti([]);
144
+ }
145
+ };
146
+
147
+ const handleRemoveMultiValue = (value: SelectFieldOption) => {
148
+ const newValue = valueMulti.filter((v) => v.value !== value.value);
149
+ setValueMulti(newValue);
150
+ if (setFormValue) {
151
+ setFormValue(
152
+ name || "",
153
+ newValue.map((v) => v.value)
154
+ );
155
+ }
156
+ onChangeMulti && onChangeMulti(newValue);
157
+ };
158
+
111
159
  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
112
160
  const newValue = e.target.value;
113
161
  if (register) {
@@ -125,46 +173,22 @@ export const SelectField = (props: Props) => {
125
173
 
126
174
  const handleOptionClick = (option: SelectFieldOption) => {
127
175
  if (isMulti) {
128
- const newValue = valueMulti.some((v) => v.value === option.value)
129
- ? valueMulti.filter((v) => v.value !== option.value)
130
- : [...valueMulti, option];
131
- setValueMulti(newValue);
132
- onChangeMulti && onChangeMulti(newValue);
133
- if (setFormValue) {
134
- setFormValue(
135
- name || "",
136
- newValue.map((v) => v.value)
137
- );
138
- }
176
+ handleAddMultiValue(option);
139
177
  } else {
140
- setValue(option);
141
- setInputValue(option.label);
142
- onChange && onChange(option);
143
- if (setFormValue) {
144
- setFormValue(name || "", option.value);
145
- }
178
+ handleSetSingleValue(option);
146
179
  }
147
180
  setHighlightedIndex(-1);
148
181
  setIsSearching(false);
149
- setFilteredOptions([]);
182
+ setFilteredOptions(options);
150
183
  setIsOpen(false);
151
184
  };
152
185
 
153
186
  const handleClear = () => {
154
187
  if (isMulti) {
155
- setValueMulti([]);
156
- onChangeMulti && onChangeMulti([]);
157
- if (setFormValue) {
158
- setFormValue(name || "", []);
159
- }
188
+ handleAddMultiValue();
160
189
  } else {
161
- setValue(null);
162
- onChange && onChange(null);
163
- if (setFormValue) {
164
- setFormValue(name || "", "");
165
- }
190
+ handleSetSingleValue();
166
191
  }
167
- setInputValue("");
168
192
  };
169
193
 
170
194
  const handleBlur = () => {
@@ -175,6 +199,7 @@ export const SelectField = (props: Props) => {
175
199
  handleOptionClick(filteredOptions[0]);
176
200
  }
177
201
 
202
+ setHighlightedIndex(-1);
178
203
  setIsTabPressed(false);
179
204
  setIsSearching(false);
180
205
  setIsOpen(false);
@@ -260,21 +285,48 @@ export const SelectField = (props: Props) => {
260
285
  </label>
261
286
  )}
262
287
  <div className="relative">
263
- <input
264
- type="text"
265
- id={id}
266
- value={inputValue}
267
- onFocus={() => setIsOpen(true)}
268
- onKeyDown={handleKeyDown}
269
- readOnly={isReadOnly}
270
- disabled={disabled}
271
- className={`block w-full rounded-md ${bgColor} ${borderColor} ${textColor} shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm pr-10`}
272
- placeholder={isMulti ? "Select options..." : "Select an option..."}
273
- autoComplete="off"
274
- onChange={handleInputChange}
275
- onBlur={handleBlur}
276
- required={required}
277
- />
288
+ <div className="flex items-center">
289
+ <input
290
+ type="text"
291
+ id={id}
292
+ value={inputValue}
293
+ onFocus={() => setIsOpen(true)}
294
+ onKeyDown={handleKeyDown}
295
+ readOnly={isReadOnly}
296
+ disabled={disabled}
297
+ className={`block w-full rounded-md ${bgColor} ${borderColor} ${textColor} shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm pr-10`}
298
+ placeholder={isMulti ? "Select options..." : "Select an option..."}
299
+ autoComplete="off"
300
+ onChange={handleInputChange}
301
+ onBlur={handleBlur}
302
+ required={required}
303
+ />
304
+ {isClearable && (value || valueMulti.length > 0) && (
305
+ <button
306
+ type="button"
307
+ onClick={handleClear}
308
+ className="absolute inset-y-0 right-0 pr-3 flex items-center"
309
+ >
310
+ ×
311
+ </button>
312
+ )}
313
+ {helpText && (
314
+ <div className="flex items-center relative ml-3">
315
+ <div
316
+ className="relative cursor-pointer"
317
+ onMouseEnter={() => setShowTooltip(true)}
318
+ onMouseLeave={() => setShowTooltip(false)}
319
+ >
320
+ <IdeaIconSVG />
321
+ {showTooltip && (
322
+ <div className="absolute -left-48 top-0 mt-8 p-2 bg-white border rounded shadow text-black z-50">
323
+ {helpText}
324
+ </div>
325
+ )}
326
+ </div>
327
+ </div>
328
+ )}
329
+ </div>
278
330
  <input
279
331
  type="hidden"
280
332
  {...(register ?? {})}
@@ -285,33 +337,6 @@ export const SelectField = (props: Props) => {
285
337
  : value?.value || ""
286
338
  }
287
339
  />
288
- {isClearable && (value || valueMulti.length > 0) && (
289
- <button
290
- type="button"
291
- onClick={handleClear}
292
- className="absolute inset-y-0 right-0 pr-3 flex items-center"
293
- >
294
- ×
295
- </button>
296
- )}
297
- {!isClearable && (value || valueMulti.length > 0) && (
298
- <span className="absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none">
299
- <svg
300
- className="h-5 w-5 text-green-500"
301
- fill="none"
302
- stroke="currentColor"
303
- viewBox="0 0 24 24"
304
- xmlns="http://www.w3.org/2000/svg"
305
- >
306
- <path
307
- strokeLinecap="round"
308
- strokeLinejoin="round"
309
- strokeWidth={2}
310
- d="M5 13l4 4L19 7"
311
- />
312
- </svg>
313
- </span>
314
- )}
315
340
  {isOpen && !isReadOnly && (
316
341
  <ul
317
342
  ref={optionsRef}
@@ -341,7 +366,7 @@ export const SelectField = (props: Props) => {
341
366
  </ul>
342
367
  )}
343
368
  </div>
344
- {isMulti && (
369
+ {isMulti && valueMulti.length > 0 && (
345
370
  <div className="mt-2 flex flex-wrap gap-2">
346
371
  {valueMulti.map((option, index) => (
347
372
  <span
@@ -351,7 +376,7 @@ export const SelectField = (props: Props) => {
351
376
  {option.label}
352
377
  <button
353
378
  type="button"
354
- onClick={() => handleOptionClick(option)}
379
+ onClick={() => handleRemoveMultiValue(option)}
355
380
  className="ml-1 text-blue-600 hover:text-blue-800"
356
381
  >
357
382
  ×
@@ -360,22 +385,6 @@ export const SelectField = (props: Props) => {
360
385
  ))}
361
386
  </div>
362
387
  )}
363
- {helpText && (
364
- <div className="flex items-center relative mt-1">
365
- <div
366
- className="relative cursor-pointer"
367
- onMouseEnter={() => setShowTooltip(true)}
368
- onMouseLeave={() => setShowTooltip(false)}
369
- >
370
- <IdeaIconSVG />
371
- {showTooltip && (
372
- <div className="absolute -left-48 top-0 mt-8 p-2 bg-white border rounded shadow text-black z-50">
373
- {helpText}
374
- </div>
375
- )}
376
- </div>
377
- </div>
378
- )}
379
388
  {error && (
380
389
  <p className={`mt-2 text-sm text-${color}-600 dark:text-${color}-500`}>
381
390
  <span className="font-medium">Oops!</span>{" "}
@@ -24,6 +24,7 @@ type Props = {
24
24
  style?: React.CSSProperties;
25
25
  className?: string;
26
26
  required?: boolean;
27
+ autoComplete?: React.HTMLInputAutoCompleteAttribute;
27
28
  };
28
29
 
29
30
  export const TextField = (props: Props) => {
@@ -46,6 +47,7 @@ export const TextField = (props: Props) => {
46
47
  className = "",
47
48
  hint,
48
49
  required,
50
+ autoComplete = "off",
49
51
  } = props;
50
52
 
51
53
  const [showTooltip, setShowTooltip] = useState<boolean>(false);
@@ -129,7 +131,6 @@ export const TextField = (props: Props) => {
129
131
  readOnly={isReadOnly}
130
132
  disabled={disabled}
131
133
  id={id ?? name}
132
- autoComplete="off"
133
134
  value={value}
134
135
  onWheel={(e: React.WheelEvent<HTMLInputElement>) => {
135
136
  e.currentTarget.blur();
@@ -144,11 +145,12 @@ export const TextField = (props: Props) => {
144
145
  className={`block w-full rounded-md ${bgColor} ${borderColor} ${textColor} shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm`}
145
146
  {...(register ?? {})}
146
147
  name={name}
148
+ autoComplete={autoComplete}
147
149
  onChange={handleInputChange}
148
150
  />
149
151
  );
150
152
 
151
- if (!error && !title) {
153
+ if (!error && !title && !helpText) {
152
154
  return <div className={`${className}`}>{inputComponent}</div>;
153
155
  }
154
156