@pnkx-lib/ui 1.9.352 → 1.9.354

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.
@@ -1433,6 +1433,7 @@ const NumericFormatCustom = forwardRef((props, ref) => {
1433
1433
  } = props;
1434
1434
  const isMoney = type === "money";
1435
1435
  const isNumberCustom = type === "number_custom";
1436
+ const MAX_VALUE = 999999999999999;
1436
1437
  //! Function
1437
1438
  const handleValueChange = (values) => {
1438
1439
  const numericValue = parseFloat(values.value.replace(/,/g, ""));
@@ -1457,11 +1458,15 @@ const NumericFormatCustom = forwardRef((props, ref) => {
1457
1458
  customInput: Input,
1458
1459
  onValueChange: handleValueChange,
1459
1460
  value,
1460
- thousandSeparator: isNumberCustom ? `.` : ",",
1461
- decimalSeparator: isNumberCustom ? `,` : ".",
1461
+ thousandSeparator: isNumberCustom ? `,` : ".",
1462
+ decimalSeparator: isNumberCustom ? `.` : ",",
1462
1463
  valueIsNumericString: true,
1463
1464
  getInputRef: ref,
1464
1465
  prefix: isMoney ? "$" : prefix,
1466
+ isAllowed: (values) => {
1467
+ const { floatValue } = values;
1468
+ return floatValue === void 0 || floatValue <= MAX_VALUE;
1469
+ },
1465
1470
  ...restProps
1466
1471
  }
1467
1472
  ),
@@ -6,6 +6,7 @@ import { Label } from '../ui/Label.js';
6
6
  import { t as twMerge } from '../chunks/bundle-mjs-BBFHkixS.js';
7
7
  import { R as RefIcon } from '../chunks/CloseOutlined-D4eYNdNo.js';
8
8
  import { R as RefIcon$1 } from '../chunks/DownOutlined-DifOcKuo.js';
9
+ import { useRef } from 'react';
9
10
  import { M as MAX_TAG_TEXT_LENGTH, a as MAX_TAG_COUNT } from '../chunks/common-BcURBmQ-.js';
10
11
 
11
12
  const SelectClearIcon = ({
@@ -78,10 +79,14 @@ const Select = (props) => {
78
79
  const { touchedFields, errors, isSubmitted } = formState || {};
79
80
  const isTouched = get(touchedFields, name);
80
81
  const errorMessage = get(errors, name)?.message;
82
+ const selectRef = useRef(null);
81
83
  //! Function
82
84
  const handleChange = (val) => {
83
85
  onChange?.(val);
84
86
  afterOnChange?.(val);
87
+ if (mode === "multiple" && selectRef.current) {
88
+ selectRef.current?.focus();
89
+ }
85
90
  };
86
91
  const renderErrorMessage = () => {
87
92
  if (!errorMessage) return null;
@@ -123,6 +128,7 @@ const Select = (props) => {
123
128
  /* @__PURE__ */ jsx(
124
129
  Select$1,
125
130
  {
131
+ ref: selectRef,
126
132
  suffixIcon,
127
133
  onChange: handleChange,
128
134
  onBlur,
@@ -1,9 +1,8 @@
1
1
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
2
  import { Upload } from 'antd';
3
- import * as React from 'react';
4
- import { useState } from 'react';
5
3
  import { R as RefIcon$2 } from '../chunks/InboxOutlined-DNCJCjk3.js';
6
4
  import { I as Icon, _ as _extends } from '../chunks/AntdIcon-DSoxq9aC.js';
5
+ import * as React from 'react';
7
6
 
8
7
  // This icon file is generated automatically.
9
8
  var CheckCircleFilled$1 = { "icon": { "tag": "svg", "attrs": { "viewBox": "64 64 896 896", "focusable": "false" }, "children": [{ "tag": "path", "attrs": { "d": "M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm193.5 301.7l-210.6 292a31.8 31.8 0 01-51.7 0L318.5 484.9c-3.8-5.3 0-12.7 6.5-12.7h46.9c10.2 0 19.9 4.9 25.9 13.3l71.2 98.8 157.2-218c6-8.3 15.6-13.3 25.9-13.3H699c6.5 0 10.3 7.4 6.5 12.7z" } }] }, "name": "check-circle", "theme": "filled" };
@@ -38,74 +37,25 @@ if (process.env.NODE_ENV !== 'production') {
38
37
  }
39
38
 
40
39
  const { Dragger } = Upload;
41
- const ImportFile = ({ onUploadSuccess, ...rest }) => {
42
- const [loading, setLoading] = useState(false);
43
- const [status, setStatus] = useState({
44
- type: "",
45
- message: ""
46
- });
47
- const handleUploadFile = async (options) => {
48
- const { file, onSuccess, onError } = options;
49
- const maxSize = 5 * 1024 * 1024;
50
- if (file.size > maxSize) {
51
- setStatus((prev) => ({
52
- ...prev,
53
- type: "error",
54
- message: `File ${file.name} có kích thước quá lớn.
55
-
56
- ${file.name} không đúng định dạng! Vui lòng tải lại file này, xem các lỗi được ghi chú, sau đó chỉnh sửa và thử nhập lại.
57
-
58
- Việc tải lên không thể hoàn tất do kết nối mạng hiện tại bị gián đoạn hoặc quá chậm.`
59
- }));
60
- onError(new Error("File too large"));
61
- return;
62
- }
63
- const formData = new FormData();
64
- formData.append("file", file);
65
- formData.append("upload_preset", "ml_default");
66
- setLoading(true);
67
- try {
68
- const res = await fetch(
69
- "https://api.cloudinary.com/v1_1/dhtrzmzd3/auto/upload",
70
- {
71
- method: "POST",
72
- body: formData
73
- }
74
- );
75
- const data = await res.json();
76
- setStatus((prev) => ({
77
- ...prev,
78
- type: "success",
79
- message: "File đã tải lên thành công! vui lòng ấn xác nhận để lưu dữ liệu vào database"
80
- }));
81
- onSuccess(data);
82
- if (onUploadSuccess) {
83
- onUploadSuccess(data);
84
- }
85
- } catch (err) {
86
- console.error("Upload failed:", err);
87
- onError(err);
88
- setStatus((prev) => ({
89
- ...prev,
90
- type: "error",
91
- message: `Việc tải lên không thể hoàn tất do kết nối mạng hiện tại bị gián đoạn hoặc quá chậm.`
92
- }));
93
- } finally {
94
- setLoading(false);
95
- }
96
- };
40
+ const ImportFile = ({
41
+ customRequest,
42
+ loading,
43
+ status,
44
+ setStatus,
45
+ ...rest
46
+ }) => {
97
47
  return /* @__PURE__ */ jsxs(Fragment, { children: [
98
48
  /* @__PURE__ */ jsx(
99
49
  Dragger,
100
50
  {
101
- customRequest: handleUploadFile,
51
+ customRequest,
102
52
  listType: "picture",
103
53
  accept: ".xlsx",
104
54
  ...rest,
105
- onRemove: () => setStatus(() => ({
55
+ onRemove: () => setStatus({
106
56
  message: "",
107
57
  type: ""
108
- })),
58
+ }),
109
59
  children: /* @__PURE__ */ jsxs("div", { children: [
110
60
  /* @__PURE__ */ jsx("p", { className: "ant-upload-drag-icon", children: /* @__PURE__ */ jsx(RefIcon$2, {}) }),
111
61
  /* @__PURE__ */ jsx("p", { className: "ant-upload-text", children: "Kéo tập tin của bạn hoặc nhấp để duyệt một tập tin" }),
@@ -113,9 +63,9 @@ const ImportFile = ({ onUploadSuccess, ...rest }) => {
113
63
  ] })
114
64
  }
115
65
  ),
116
- status.message && !loading && /* @__PURE__ */ jsxs("div", { className: "flex gap-2 mt-4", children: [
117
- status.type === "error" ? /* @__PURE__ */ jsx(RefIcon, { className: "!text-[#FF4D4F] text-xl" }) : /* @__PURE__ */ jsx(RefIcon$1, { className: "!text-[#52C41A] text-xl" }),
118
- /* @__PURE__ */ jsx("p", { className: "text-sm", children: status.message })
66
+ status?.message && !loading && /* @__PURE__ */ jsxs("div", { className: "flex gap-2 mt-4", children: [
67
+ status?.type === "error" ? /* @__PURE__ */ jsx(RefIcon, { className: "!text-[#FF4D4F] text-xl" }) : /* @__PURE__ */ jsx(RefIcon$1, { className: "!text-[#52C41A] text-xl" }),
68
+ /* @__PURE__ */ jsx("p", { className: "text-sm", children: status?.message })
119
69
  ] })
120
70
  ] });
121
71
  };
@@ -20,11 +20,13 @@ const UploadComponent = ({
20
20
  content = "Tải hình ảnh lên",
21
21
  description = "Ảnh có kích thước 400x400 px và dung lượng ảnh < 1 mb",
22
22
  customRequest,
23
+ setImageUpload,
23
24
  ...restProps
24
25
  }) => {
25
- const imageUrl = field?.value;
26
+ const imageUrl = typeof field?.value === "string" ? field.value : field?.value instanceof File ? URL.createObjectURL(field.value) : null;
26
27
  const handleRemoveImage = () => {
27
28
  field.onChange(null);
29
+ setImageUpload?.("");
28
30
  };
29
31
  return /* @__PURE__ */ jsxs("div", { className: customStyleContainer, children: [
30
32
  label && /* @__PURE__ */ jsx(Label, { label, required }),
@@ -38,11 +40,10 @@ const UploadComponent = ({
38
40
  customRequest: async (options) => {
39
41
  const { file, onSuccess, onError } = options;
40
42
  try {
41
- const url = await customRequest?.(file);
42
- field.onChange(url);
43
- onSuccess?.({ url }, file);
44
- } catch (error) {
45
- onError?.(error);
43
+ await customRequest?.(file, field.onChange);
44
+ onSuccess?.({}, file);
45
+ } catch (err) {
46
+ onError?.(err);
46
47
  }
47
48
  },
48
49
  children: /* @__PURE__ */ jsx("div", { children: loading ? /* @__PURE__ */ jsx(Spin, {}) : imageUrl || imageUpload ? /* @__PURE__ */ jsx("div", { className: customStyleUpload, children: /* @__PURE__ */ jsxs(
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pnkx-lib/ui",
3
3
  "private": false,
4
- "version": "1.9.352",
4
+ "version": "1.9.354",
5
5
  "type": "module",
6
6
  "main": "./es/index.js",
7
7
  "module": "./es/index.js",
@@ -1,6 +1,13 @@
1
1
  import { UploadProps } from 'antd';
2
+ type UploadStatus = {
3
+ type: "success" | "error" | "";
4
+ message: string;
5
+ };
2
6
  interface ImportFileProps extends UploadProps {
3
- onUploadSuccess: any;
7
+ customRequest?: any;
8
+ loading?: boolean;
9
+ status?: UploadStatus;
10
+ setStatus(status: UploadStatus): void;
4
11
  }
5
- export declare const ImportFile: ({ onUploadSuccess, ...rest }: ImportFileProps) => import("react/jsx-runtime").JSX.Element;
12
+ export declare const ImportFile: ({ customRequest, loading, status, setStatus, ...rest }: ImportFileProps) => import("react/jsx-runtime").JSX.Element;
6
13
  export {};