next-helios-fe 1.8.87 → 1.8.89

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-helios-fe",
3
- "version": "1.8.87",
3
+ "version": "1.8.89",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -25,7 +25,7 @@ export const Item: React.FC<ItemProps> = ({
25
25
  : `disabled:text-disabled ${
26
26
  as === "title" ? "" : "hover:bg-secondary-light"
27
27
  }`
28
- }`}
28
+ } outline-0`}
29
29
  disabled={active ? true : (disabled || as === "title") ?? false}
30
30
  onClick={onClick}
31
31
  >
@@ -11,6 +11,9 @@ export interface MultipleSelectProps
11
11
  menus: {
12
12
  label: string;
13
13
  value: string;
14
+ variant?: "button" | "title";
15
+ disabled?: boolean;
16
+ disableUnselect?: boolean;
14
17
  [key: string]: any;
15
18
  }[];
16
19
  label?: string;
@@ -126,6 +129,12 @@ export const MultipleSelect: React.FC<MultipleSelectProps> = ({
126
129
  </div>
127
130
  )}
128
131
  <div className="relative flex items-center">
132
+ <input
133
+ ref={inputRef}
134
+ type="text"
135
+ className="absolute bottom-0 -z-10 w-full border-0 rounded-md focus:ring-0"
136
+ disabled={disabled ?? false}
137
+ />
129
138
  <div
130
139
  ref={fakeInputRef}
131
140
  className={`group/button flex justify-between items-center gap-2 w-full min-h-10 px-4 border rounded-md caret-transparent focus:outline-none focus:ring-1 focus:ring-primary focus:shadow focus:shadow-primary focus:border-primary-dark ${height} ${
@@ -187,12 +196,6 @@ export const MultipleSelect: React.FC<MultipleSelectProps> = ({
187
196
  </div>
188
197
  )}
189
198
  </div>
190
- <input
191
- ref={inputRef}
192
- type="text"
193
- className="absolute bottom-0 -z-10 w-full border-0 focus:ring-0"
194
- disabled={disabled ?? false}
195
- />
196
199
  <div
197
200
  className="absolute left-4 flex flex-wrap gap-2 h-min pointer-events-none"
198
201
  style={{ width: itemContainerRef.current?.clientWidth }}
@@ -202,34 +205,38 @@ export const MultipleSelect: React.FC<MultipleSelectProps> = ({
202
205
  <div
203
206
  key={item}
204
207
  className={`flex items-center gap-2 px-2 py-0.5 rounded-md text-white select-none cursor-default pointer-events-auto ${
205
- disabled ? "bg-secondary" : "bg-primary"
208
+ disabled ||
209
+ menus.find((i) => i.value === item)?.disableUnselect
210
+ ? "bg-secondary"
211
+ : "bg-primary"
206
212
  }`}
207
213
  >
208
214
  <span>{menus.find((i) => i.value === item)?.label}</span>
209
- <div
210
- className="cursor-pointer active:opacity-70 active:duration-300 active:ease-out disabled:active:opacity-100"
215
+ <button
216
+ disabled={
217
+ disabled ||
218
+ menus.find((i) => i.value === item)?.disableUnselect
219
+ }
211
220
  onClick={() => {
212
- if (!disabled) {
213
- setTempValue(tempValue.filter((i) => i !== item));
214
- if (onChange) {
215
- onChange({
216
- target: {
217
- value: tempValue.filter((i) => i !== item),
218
- },
219
- } as any);
220
- }
221
- if (onRemove) {
222
- onRemove({
223
- target: {
224
- value: item,
225
- },
226
- });
227
- }
221
+ setTempValue(tempValue.filter((i) => i !== item));
222
+ if (onChange) {
223
+ onChange({
224
+ target: {
225
+ value: tempValue.filter((i) => i !== item),
226
+ },
227
+ } as any);
228
+ }
229
+ if (onRemove) {
230
+ onRemove({
231
+ target: {
232
+ value: item,
233
+ },
234
+ });
228
235
  }
229
236
  }}
230
237
  >
231
238
  <Icon icon="pajamas:close" />
232
- </div>
239
+ </button>
233
240
  </div>
234
241
  );
235
242
  })}
@@ -273,6 +280,8 @@ export const MultipleSelect: React.FC<MultipleSelectProps> = ({
273
280
  active={
274
281
  tempValue?.find((i) => i === item.value) ? true : false
275
282
  }
283
+ as={item.variant || "button"}
284
+ disabled={item.disabled ?? false}
276
285
  onClick={() => {
277
286
  setTempValue([...tempValue, item.value]);
278
287
  if (onChange) {
@@ -1,17 +1,19 @@
1
1
  "use client";
2
- import React, { useState, useEffect } from "react";
2
+ import React, { useState, useEffect, useRef } from "react";
3
3
  import { Tooltip } from "../../../components";
4
4
  import { Icon } from "@iconify/react";
5
5
 
6
6
  export interface TextareaProps
7
7
  extends Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, "rows"> {
8
8
  rows?: number;
9
- maxRows?: number;
10
9
  label?: string;
11
10
  description?: string;
12
11
  options?: {
13
12
  width?: "full" | "fit";
14
13
  height?: "short" | "medium" | "high";
14
+ autoGrow?: {
15
+ maxRows: number;
16
+ };
15
17
  disableResize?: boolean;
16
18
  hideInputDetail?: boolean;
17
19
  };
@@ -19,13 +21,13 @@ export interface TextareaProps
19
21
 
20
22
  export const Textarea: React.FC<TextareaProps> = ({
21
23
  rows,
22
- maxRows,
23
24
  options,
24
25
  label,
25
26
  description,
26
27
  ...rest
27
28
  }) => {
28
- const [tempRows, setTempRows] = useState<number>(rows || 10);
29
+ const mirrorInputRef = useRef<HTMLTextAreaElement>(null);
30
+ const [tempRows, setTempRows] = useState<number>(1);
29
31
  const width = options?.width === "fit" ? "w-fit" : "w-full";
30
32
  const height =
31
33
  options?.height === "short"
@@ -35,36 +37,56 @@ export const Textarea: React.FC<TextareaProps> = ({
35
37
  : "py-1.5";
36
38
 
37
39
  useEffect(() => {
38
- if (maxRows) {
39
- if (rest.value && (rest.value as string)?.includes("\n")) {
40
- if (((rest.value as string).match(/\n/g) || []).length < maxRows) {
41
- setTempRows(((rest.value as string).match(/\n/g) || []).length + 1);
42
- }
40
+ if (options?.autoGrow) {
41
+ if (
42
+ ((mirrorInputRef.current?.scrollHeight || 0) -
43
+ (options?.height === "short"
44
+ ? 4
45
+ : options?.height === "high"
46
+ ? 8
47
+ : 12)) /
48
+ 24 <=
49
+ options?.autoGrow.maxRows
50
+ ) {
51
+ setTempRows(
52
+ ((mirrorInputRef.current?.scrollHeight || 0) -
53
+ (options?.height === "short"
54
+ ? 4
55
+ : options?.height === "high"
56
+ ? 8
57
+ : 12)) /
58
+ 24
59
+ );
43
60
  } else {
44
- setTempRows(rows || 10);
61
+ setTempRows(options?.autoGrow.maxRows);
45
62
  }
46
63
  }
47
- }, [rows, maxRows, rest.value]);
64
+ }, [
65
+ options?.autoGrow,
66
+ mirrorInputRef.current?.scrollHeight,
67
+ rest.value,
68
+ options?.height,
69
+ ]);
48
70
 
49
71
  return (
50
- <label className={`flex flex-col gap-2 ${width}`}>
72
+ <label className={`relative flex flex-col gap-2 ${width}`}>
51
73
  {(label ||
52
74
  (!options?.hideInputDetail && (rest.maxLength || description))) && (
53
75
  <div className="flex items-center gap-2">
54
76
  {label && (
55
77
  <span
56
- className={`text-sm select-none ${
78
+ className={`select-none text-sm ${
57
79
  rest.required &&
58
- "after:content-['*'] after:ml-1 after:text-danger"
80
+ "after:ml-1 after:text-danger after:content-['*']"
59
81
  }`}
60
82
  >
61
83
  {label}
62
84
  </span>
63
85
  )}
64
86
  {!options?.hideInputDetail && (
65
- <div className="flex-1 flex justify-end items-center gap-2">
87
+ <div className="flex flex-1 items-center justify-end gap-2">
66
88
  {rest.maxLength && (
67
- <span className="text-sm select-none">
89
+ <span className="select-none text-sm">
68
90
  {rest.value ? (rest.value as string).length : 0}/
69
91
  {rest.maxLength}
70
92
  </span>
@@ -82,12 +104,20 @@ export const Textarea: React.FC<TextareaProps> = ({
82
104
  </div>
83
105
  )}
84
106
  <textarea
85
- rows={tempRows}
86
- className={`w-full px-4 border-default border rounded-md bg-secondary-bg placeholder:duration-300 placeholder:translate-x-0 focus:placeholder:translate-x-1 placeholder:text-silent 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 ${
107
+ rows={options?.autoGrow ? tempRows : rows || 10}
108
+ className={`w-full rounded-md border border-default bg-secondary-bg px-4 placeholder:translate-x-0 placeholder:text-silent placeholder:duration-300 focus:border-primary-dark focus:shadow focus:shadow-primary focus:outline-none focus:ring-1 focus:ring-primary focus:placeholder:translate-x-1 disabled:bg-secondary-light disabled:text-disabled ${
87
109
  options?.disableResize && "resize-none"
88
110
  } ${height}`}
89
111
  {...rest}
90
112
  />
113
+ <textarea
114
+ ref={mirrorInputRef}
115
+ rows={1}
116
+ className={`absolute w-full rounded-md border border-default bg-secondary-bg px-4 pointer-events-none opacity-0 placeholder:translate-x-0 placeholder:text-silent placeholder:duration-300 focus:border-primary-dark focus:shadow focus:shadow-primary focus:outline-none focus:ring-1 focus:ring-primary focus:placeholder:translate-x-1 disabled:bg-secondary-light disabled:text-disabled ${height}`}
117
+ readOnly
118
+ tabIndex={-1}
119
+ value={rest.value}
120
+ />
91
121
  </label>
92
122
  );
93
123
  };