@zauru-sdk/components 2.0.65 → 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,22 @@
|
|
|
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
|
+
|
|
14
|
+
## [2.0.66](https://github.com/intuitiva/zauru-typescript-sdk/compare/v2.0.65...v2.0.66) (2024-11-13)
|
|
15
|
+
|
|
16
|
+
**Note:** Version bump only for package @zauru-sdk/components
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
6
22
|
## [2.0.65](https://github.com/intuitiva/zauru-typescript-sdk/compare/v2.0.64...v2.0.65) (2024-11-13)
|
|
7
23
|
|
|
8
24
|
**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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
90
|
-
onChangeMulti && onChangeMulti([]);
|
|
91
|
-
if (setFormValue) {
|
|
92
|
-
setFormValue(name || "", []);
|
|
93
|
-
}
|
|
117
|
+
handleAddMultiValue();
|
|
94
118
|
}
|
|
95
119
|
else {
|
|
96
|
-
|
|
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 || "" }),
|
|
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: () =>
|
|
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,
|
|
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.
|
|
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",
|
|
@@ -34,10 +34,10 @@
|
|
|
34
34
|
"@reduxjs/toolkit": "^2.2.1",
|
|
35
35
|
"@remix-run/react": "^2.8.1",
|
|
36
36
|
"@zauru-sdk/common": "^2.0.51",
|
|
37
|
-
"@zauru-sdk/hooks": "^2.0.
|
|
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.
|
|
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": "
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
156
|
-
onChangeMulti && onChangeMulti([]);
|
|
157
|
-
if (setFormValue) {
|
|
158
|
-
setFormValue(name || "", []);
|
|
159
|
-
}
|
|
188
|
+
handleAddMultiValue();
|
|
160
189
|
} else {
|
|
161
|
-
|
|
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
|
-
<
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
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={() =>
|
|
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
|
|