next-helios-fe 1.8.105 → 1.8.107
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/dropdown/index.d.ts +3 -4
- package/dist/components/dropdown/item.d.ts +2 -2
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/components/dropdown/index.tsx +10 -18
- package/src/components/dropdown/item.tsx +5 -6
- package/src/components/form/input/checkbox.tsx +15 -4
- package/src/components/form/input/color.tsx +1 -0
- package/src/components/form/input/radio.tsx +11 -2
- package/src/components/form/input/range.tsx +1 -1
- package/src/components/form/other/emoji.tsx +1 -1
- package/src/components/form/other/multipleSelect.tsx +217 -198
- package/src/components/form/other/rating.tsx +1 -0
- package/src/components/form/other/select.tsx +25 -6
- package/src/components/table/index.tsx +2 -2
@@ -62,21 +62,20 @@ export const MultipleSelect: React.FC<MultipleSelectProps> = ({
|
|
62
62
|
onRemove,
|
63
63
|
...rest
|
64
64
|
}) => {
|
65
|
-
const [tempValue, setTempValue] = useState<string[]>([]);
|
66
|
-
const [openDropdown, setOpenDropdown] = useState(false);
|
67
|
-
const [dropdownWidth, setDropdownWidth] = useState<number>(0);
|
68
|
-
const [dropdownHeight, setDropdownHeight] = useState<number>(0);
|
69
|
-
const fakeInputRef = useRef<HTMLDivElement>(null);
|
70
65
|
const itemContainerRef = useRef<HTMLDivElement>(null);
|
71
66
|
const inputRef = useRef<HTMLInputElement>(null);
|
72
67
|
const dropdownRef = useRef<HTMLButtonElement>(null);
|
68
|
+
const [tempValue, setTempValue] = useState<string[]>([]);
|
69
|
+
const [openDropdown, setOpenDropdown] = useState(false);
|
70
|
+
const [inputHeight, setInputHeight] = useState<number>(0);
|
71
|
+
const [dropdownWidth, setDropdownWidth] = useState<number>(0);
|
73
72
|
const width = options?.width === "fit" ? "w-fit" : "w-full";
|
74
73
|
const height =
|
75
74
|
options?.height === "short"
|
76
|
-
? "py-
|
75
|
+
? "py-[3.5px]"
|
77
76
|
: options?.height === "high"
|
78
|
-
? "py-
|
79
|
-
: "py-
|
77
|
+
? "py-[7.5px]"
|
78
|
+
: "py-[5px]";
|
80
79
|
|
81
80
|
useEffect(() => {
|
82
81
|
document.addEventListener("mousedown", (e) => {
|
@@ -84,6 +83,16 @@ export const MultipleSelect: React.FC<MultipleSelectProps> = ({
|
|
84
83
|
setOpenDropdown(false);
|
85
84
|
}
|
86
85
|
});
|
86
|
+
|
87
|
+
const observer = new ResizeObserver((entries) => {
|
88
|
+
for (let entry of entries) {
|
89
|
+
setInputHeight(entry.contentRect.height);
|
90
|
+
}
|
91
|
+
});
|
92
|
+
|
93
|
+
observer.observe(itemContainerRef.current!);
|
94
|
+
|
95
|
+
return () => observer.disconnect();
|
87
96
|
}, []);
|
88
97
|
|
89
98
|
useEffect(() => {
|
@@ -107,211 +116,221 @@ export const MultipleSelect: React.FC<MultipleSelectProps> = ({
|
|
107
116
|
}, [tempValue]);
|
108
117
|
|
109
118
|
return (
|
110
|
-
<div className="
|
111
|
-
<
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
className={`text-silent select-none duration-300 ${
|
168
|
-
openDropdown ? "translate-x-1" : "translate-x-0"
|
169
|
-
}`}
|
170
|
-
>
|
171
|
-
{placeholder}
|
172
|
-
</span>
|
173
|
-
) : (
|
174
|
-
<div
|
175
|
-
ref={itemContainerRef}
|
176
|
-
className="flex flex-wrap gap-2 w-full h-min pointer-events-none invisible"
|
177
|
-
>
|
178
|
-
{tempValue?.map((item) => {
|
179
|
-
return (
|
180
|
-
<div
|
181
|
-
key={item}
|
182
|
-
className="flex items-center gap-2 px-2 py-0.5 rounded-md bg-primary text-white cursor-default pointer-events-auto"
|
183
|
-
>
|
184
|
-
<span>{menus.find((i) => i.value === item)?.label}</span>
|
185
|
-
<div className="cursor-pointer">
|
186
|
-
<Icon icon="pajamas:close" />
|
187
|
-
</div>
|
188
|
-
</div>
|
119
|
+
<div className="relative">
|
120
|
+
<div className="flex flex-row-reverse items-end">
|
121
|
+
<label className={`flex flex-col gap-2 ${width}`}>
|
122
|
+
{(label || description) && (
|
123
|
+
<div className="flex justify-between items-center gap-2">
|
124
|
+
{label && (
|
125
|
+
<span
|
126
|
+
className={`text-sm select-none ${
|
127
|
+
required &&
|
128
|
+
"after:content-['*'] after:ml-1 after:text-danger"
|
129
|
+
}`}
|
130
|
+
>
|
131
|
+
{label}
|
132
|
+
</span>
|
133
|
+
)}
|
134
|
+
{description && (
|
135
|
+
<Tooltip content={description}>
|
136
|
+
<Icon
|
137
|
+
icon="octicon:info-16"
|
138
|
+
className="text-sm text-primary-dark"
|
139
|
+
/>
|
140
|
+
</Tooltip>
|
141
|
+
)}
|
142
|
+
</div>
|
143
|
+
)}
|
144
|
+
<div className="relative flex items-center">
|
145
|
+
<div className="relative flex items-center w-full cursor-pointer">
|
146
|
+
<input
|
147
|
+
ref={inputRef}
|
148
|
+
type="text"
|
149
|
+
className="w-full ps-4 pe-14 border border-default rounded-md bg-secondary-bg text-transparent cursor-pointer caret-transparent duration-150 placeholder:duration-300 placeholder:text-silent focus:placeholder:translate-x-1 focus:outline-none focus:ring-1 focus:ring-primary focus:shadow focus:shadow-primary focus:border-primary-dark disabled:bg-secondary-light disabled:text-disabled disabled:cursor-default"
|
150
|
+
style={{
|
151
|
+
height:
|
152
|
+
tempValue.length !== 0
|
153
|
+
? inputHeight +
|
154
|
+
(options?.height === "short"
|
155
|
+
? 7
|
156
|
+
: options?.height === "high"
|
157
|
+
? 15
|
158
|
+
: 10)
|
159
|
+
: options?.height === "short"
|
160
|
+
? 35
|
161
|
+
: options?.height === "high"
|
162
|
+
? 43
|
163
|
+
: 39,
|
164
|
+
}}
|
165
|
+
placeholder={placeholder}
|
166
|
+
required={required}
|
167
|
+
disabled={disabled}
|
168
|
+
value={tempValue.join(", ")}
|
169
|
+
onChange={(e) => {}}
|
170
|
+
onClick={(e) => {
|
171
|
+
e.preventDefault();
|
172
|
+
setOpenDropdown(true);
|
173
|
+
dropdownRef.current?.click();
|
174
|
+
setDropdownWidth(
|
175
|
+
inputRef?.current?.getBoundingClientRect()?.width || 0
|
189
176
|
);
|
190
|
-
}
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
177
|
+
}}
|
178
|
+
onKeyDown={(e) => {
|
179
|
+
if (e.key === "Enter") {
|
180
|
+
e.preventDefault();
|
181
|
+
inputRef.current?.click();
|
182
|
+
}
|
183
|
+
}}
|
184
|
+
/>
|
185
|
+
<div className="absolute right-4 text-xl text-disabled pointer-events-none">
|
195
186
|
<Icon
|
196
187
|
icon={`gravity-ui:chevron-${openDropdown ? "up" : "down"}`}
|
197
188
|
/>
|
198
189
|
</div>
|
199
|
-
|
190
|
+
</div>
|
200
191
|
</div>
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
192
|
+
</label>
|
193
|
+
{!options?.disableDropdown && (
|
194
|
+
<div className="w-0 overflow-hidden">
|
195
|
+
<Dropdown
|
196
|
+
placement="bottom-start"
|
197
|
+
dismissOnClick={false}
|
198
|
+
trigger={
|
199
|
+
<button
|
200
|
+
type="button"
|
201
|
+
ref={dropdownRef}
|
202
|
+
className="w-0"
|
203
|
+
style={{
|
204
|
+
height:
|
205
|
+
tempValue.length !== 0
|
206
|
+
? inputHeight +
|
207
|
+
(options?.height === "short"
|
208
|
+
? 7
|
209
|
+
: options?.height === "high"
|
210
|
+
? 15
|
211
|
+
: 10)
|
212
|
+
: options?.height === "short"
|
213
|
+
? 35
|
214
|
+
: options?.height === "high"
|
215
|
+
? 43
|
216
|
+
: 39,
|
217
|
+
}}
|
218
|
+
tabIndex={-1}
|
219
|
+
disabled={disabled ?? false}
|
215
220
|
>
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
+
1
|
222
|
+
</button>
|
223
|
+
}
|
224
|
+
>
|
225
|
+
{menus.length === 0 ? (
|
226
|
+
<Dropdown.Item
|
227
|
+
onKeyDown={(e) => {
|
228
|
+
if (e.key === "Escape") {
|
229
|
+
e.preventDefault();
|
230
|
+
inputRef.current?.focus();
|
231
|
+
setOpenDropdown(false);
|
221
232
|
}
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
value: tempValue.filter((i) => i !== item),
|
228
|
-
},
|
229
|
-
} as any);
|
230
|
-
}
|
231
|
-
if (onRemove) {
|
232
|
-
onRemove({
|
233
|
-
target: {
|
234
|
-
value: item,
|
235
|
-
},
|
236
|
-
});
|
237
|
-
}
|
238
|
-
}}
|
233
|
+
}}
|
234
|
+
>
|
235
|
+
<div
|
236
|
+
className="flex justify-center"
|
237
|
+
style={{ width: dropdownWidth - 43 }}
|
239
238
|
>
|
240
|
-
<
|
241
|
-
</
|
242
|
-
</
|
243
|
-
)
|
244
|
-
|
239
|
+
<span>No data found</span>
|
240
|
+
</div>
|
241
|
+
</Dropdown.Item>
|
242
|
+
) : (
|
243
|
+
menus.map((item, index) => {
|
244
|
+
return (
|
245
|
+
<Dropdown.Item
|
246
|
+
key={index}
|
247
|
+
active={
|
248
|
+
tempValue?.find((i) => i === item.value) ? true : false
|
249
|
+
}
|
250
|
+
as={item.variant || "button"}
|
251
|
+
disabled={item.disabled ?? false}
|
252
|
+
onClick={() => {
|
253
|
+
setTempValue([...tempValue, item.value]);
|
254
|
+
if (onChange) {
|
255
|
+
onChange({
|
256
|
+
target: { value: [...tempValue, item.value] },
|
257
|
+
} as any);
|
258
|
+
}
|
259
|
+
if (onSelect) {
|
260
|
+
onSelect({
|
261
|
+
target: { value: item.value },
|
262
|
+
});
|
263
|
+
}
|
264
|
+
}}
|
265
|
+
onKeyDown={(e) => {
|
266
|
+
if (e.key === "Escape") {
|
267
|
+
e.preventDefault();
|
268
|
+
inputRef.current?.focus();
|
269
|
+
setOpenDropdown(false);
|
270
|
+
}
|
271
|
+
}}
|
272
|
+
>
|
273
|
+
<div
|
274
|
+
className="flex justify-between items-center gap-4"
|
275
|
+
style={{ width: dropdownWidth - 43 }}
|
276
|
+
>
|
277
|
+
<span>{item.label}</span>
|
278
|
+
{labelComponent ? labelComponent(item) : ""}
|
279
|
+
</div>
|
280
|
+
</Dropdown.Item>
|
281
|
+
);
|
282
|
+
})
|
283
|
+
)}
|
284
|
+
</Dropdown>
|
245
285
|
</div>
|
246
|
-
|
247
|
-
</
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
286
|
+
)}
|
287
|
+
</div>
|
288
|
+
<div
|
289
|
+
ref={itemContainerRef}
|
290
|
+
className={`absolute bottom-0 ps-4 pe-12 flex flex-wrap gap-2 w-full h-min pointer-events-none ${height}`}
|
291
|
+
>
|
292
|
+
{tempValue?.map((item) => {
|
293
|
+
return (
|
294
|
+
<div
|
295
|
+
key={item}
|
296
|
+
className={`flex items-center gap-2 px-2 py-0.5 rounded-md text-white select-none cursor-default pointer-events-auto ${
|
297
|
+
disabled || menus.find((i) => i.value === item)?.disableUnselect
|
298
|
+
? "bg-secondary"
|
299
|
+
: "bg-primary"
|
300
|
+
}`}
|
301
|
+
>
|
302
|
+
<span>{menus.find((i) => i.value === item)?.label}</span>
|
254
303
|
<button
|
255
304
|
type="button"
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
}}
|
305
|
+
disabled={
|
306
|
+
disabled ||
|
307
|
+
menus.find((i) => i.value === item)?.disableUnselect
|
308
|
+
}
|
261
309
|
tabIndex={-1}
|
262
|
-
|
310
|
+
onClick={() => {
|
311
|
+
setTempValue(tempValue.filter((i) => i !== item));
|
312
|
+
if (onChange) {
|
313
|
+
onChange({
|
314
|
+
target: {
|
315
|
+
value: tempValue.filter((i) => i !== item),
|
316
|
+
},
|
317
|
+
} as any);
|
318
|
+
}
|
319
|
+
if (onRemove) {
|
320
|
+
onRemove({
|
321
|
+
target: {
|
322
|
+
value: item,
|
323
|
+
},
|
324
|
+
});
|
325
|
+
}
|
326
|
+
}}
|
263
327
|
>
|
264
|
-
|
328
|
+
<Icon icon="pajamas:close" />
|
265
329
|
</button>
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
<div
|
271
|
-
className="flex justify-center"
|
272
|
-
style={{ width: dropdownWidth - 43 }}
|
273
|
-
>
|
274
|
-
<span>No data found</span>
|
275
|
-
</div>
|
276
|
-
</Dropdown.Item>
|
277
|
-
) : (
|
278
|
-
menus.map((item, index) => {
|
279
|
-
return (
|
280
|
-
<Dropdown.Item
|
281
|
-
key={index}
|
282
|
-
active={
|
283
|
-
tempValue?.find((i) => i === item.value) ? true : false
|
284
|
-
}
|
285
|
-
as={item.variant || "button"}
|
286
|
-
disabled={item.disabled ?? false}
|
287
|
-
onClick={() => {
|
288
|
-
setTempValue([...tempValue, item.value]);
|
289
|
-
if (onChange) {
|
290
|
-
onChange({
|
291
|
-
target: { value: [...tempValue, item.value] },
|
292
|
-
} as any);
|
293
|
-
}
|
294
|
-
if (onSelect) {
|
295
|
-
onSelect({
|
296
|
-
target: { value: item.value },
|
297
|
-
});
|
298
|
-
}
|
299
|
-
}}
|
300
|
-
>
|
301
|
-
<div
|
302
|
-
className="flex justify-between items-center gap-4"
|
303
|
-
style={{ width: dropdownWidth - 43 }}
|
304
|
-
>
|
305
|
-
<span>{item.label}</span>
|
306
|
-
{labelComponent ? labelComponent(item) : ""}
|
307
|
-
</div>
|
308
|
-
</Dropdown.Item>
|
309
|
-
);
|
310
|
-
})
|
311
|
-
)}
|
312
|
-
</Dropdown>
|
313
|
-
</div>
|
314
|
-
)}
|
330
|
+
</div>
|
331
|
+
);
|
332
|
+
})}
|
333
|
+
</div>
|
315
334
|
</div>
|
316
335
|
);
|
317
336
|
};
|
@@ -114,6 +114,7 @@ export const Rating: React.FC<RatingProps> = ({
|
|
114
114
|
<input
|
115
115
|
type="text"
|
116
116
|
className={`absolute top-0 w-full border-0 bg-transparent text-transparent caret-transparent pointer-events-none focus:ring-0 ${height}`}
|
117
|
+
tabIndex={-1}
|
117
118
|
required={rest.required}
|
118
119
|
readOnly
|
119
120
|
value={tempValue}
|
@@ -103,11 +103,7 @@ export const Select: React.FC<SelectProps> = ({
|
|
103
103
|
<input
|
104
104
|
ref={inputRef}
|
105
105
|
type="text"
|
106
|
-
className={`w-full ps-4 pe-14 border rounded-md bg-secondary-bg cursor-pointer caret-transparent placeholder:duration-300 placeholder:text-silent focus:placeholder:translate-x-1 focus:outline-none focus:ring-1 focus:ring-primary focus:shadow focus:shadow-primary focus:border-primary-dark disabled:bg-secondary-light disabled:text-disabled disabled:cursor-default ${height}
|
107
|
-
openDropdown
|
108
|
-
? "placeholder:translate-x-1 outline-none ring-1 ring-primary shadow shadow-primary border-primary-dark"
|
109
|
-
: "border-default placeholder:translate-x-0"
|
110
|
-
}`}
|
106
|
+
className={`w-full ps-4 pe-14 border border-default rounded-md bg-secondary-bg cursor-pointer caret-transparent placeholder:duration-300 placeholder:text-silent focus:placeholder:translate-x-1 focus:outline-none focus:ring-1 focus:ring-primary focus:shadow focus:shadow-primary focus:border-primary-dark disabled:bg-secondary-light disabled:text-disabled disabled:cursor-default ${height}`}
|
111
107
|
placeholder={placeholder}
|
112
108
|
required={rest.required}
|
113
109
|
disabled={rest.disabled}
|
@@ -125,6 +121,12 @@ export const Select: React.FC<SelectProps> = ({
|
|
125
121
|
inputRef?.current?.getBoundingClientRect()?.width || 0
|
126
122
|
);
|
127
123
|
}}
|
124
|
+
onKeyDown={(e) => {
|
125
|
+
if (e.key === "Enter") {
|
126
|
+
e.preventDefault();
|
127
|
+
inputRef.current?.click();
|
128
|
+
}
|
129
|
+
}}
|
128
130
|
/>
|
129
131
|
<div className="absolute right-4 text-xl text-disabled pointer-events-none">
|
130
132
|
<Icon icon={`gravity-ui:chevron-${openDropdown ? "up" : "down"}`} />
|
@@ -154,7 +156,15 @@ export const Select: React.FC<SelectProps> = ({
|
|
154
156
|
}
|
155
157
|
>
|
156
158
|
{menus.length === 0 ? (
|
157
|
-
<Dropdown.Item
|
159
|
+
<Dropdown.Item
|
160
|
+
onKeyDown={(e) => {
|
161
|
+
if (e.key === "Escape") {
|
162
|
+
e.preventDefault();
|
163
|
+
inputRef.current?.focus();
|
164
|
+
setOpenDropdown(false);
|
165
|
+
}
|
166
|
+
}}
|
167
|
+
>
|
158
168
|
<div
|
159
169
|
className="flex justify-center"
|
160
170
|
style={{ width: dropdownWidth - 43 }}
|
@@ -177,6 +187,15 @@ export const Select: React.FC<SelectProps> = ({
|
|
177
187
|
target: { value: item.value } as HTMLSelectElement,
|
178
188
|
} as any);
|
179
189
|
}
|
190
|
+
setOpenDropdown(false);
|
191
|
+
inputRef.current?.focus();
|
192
|
+
}}
|
193
|
+
onKeyDown={(e) => {
|
194
|
+
if (e.key === "Escape") {
|
195
|
+
e.preventDefault();
|
196
|
+
inputRef.current?.focus();
|
197
|
+
setOpenDropdown(false);
|
198
|
+
}
|
180
199
|
}}
|
181
200
|
>
|
182
201
|
<div
|
@@ -383,7 +383,7 @@ export const Table: TableComponentProps = ({
|
|
383
383
|
<input
|
384
384
|
type="search"
|
385
385
|
className="w-full border-x-0 border-b border-t-0 border-default bg-secondary-bg px-6 pb-0.5 pt-0 text-sm font-normal placeholder:translate-x-0 placeholder:text-silent placeholder:duration-300 focus:border-primary-dark focus:outline-none focus:ring-0 focus:placeholder:translate-x-1 disabled:bg-secondary-light disabled:text-disabled [&::-webkit-search-cancel-button]:appearance-none"
|
386
|
-
placeholder="
|
386
|
+
placeholder="Search..."
|
387
387
|
value={
|
388
388
|
filter?.find((filterItem) => filterItem.key === item.key)
|
389
389
|
?.value || ""
|
@@ -638,7 +638,7 @@ export const Table: TableComponentProps = ({
|
|
638
638
|
{options?.toolbar?.search?.show !== false && (
|
639
639
|
<Form.Search
|
640
640
|
options={{ width: "fit" }}
|
641
|
-
placeholder="
|
641
|
+
placeholder="Search..."
|
642
642
|
value={search}
|
643
643
|
onChange={(e) => {
|
644
644
|
setSearch(e.target.value);
|