@pnkx-lib/ui 1.9.369 → 1.9.371
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/style.css +1 -1
- package/es/chunks/logo-header-DlnEN3-o.js +137 -0
- package/es/fields/DatePicker.js +46 -46
- package/es/fields/Input.js +50 -1
- package/es/fields/InputRangePicker.js +163 -0
- package/es/fields/index.js +1 -0
- package/es/index.js +1 -0
- package/es/ui/SelectTable.js +127 -0
- package/es/ui/Sidebar.js +4 -137
- package/es/ui/SidebarV2.js +420 -0
- package/package.json +2 -2
- package/types/components/fields/InputRangePicker.d.ts +17 -0
- package/types/components/fields/index.d.ts +1 -0
- package/types/components/ui/SelectTable.d.ts +21 -0
- package/types/components/ui/SidebarV2.d.ts +19 -0
- package/types/fields/InputRangePicker.d.ts +2 -0
- package/types/ui/SelectTable.d.ts +4 -0
- package/types/ui/SidebarV2.d.ts +4 -0
package/es/fields/Input.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import React__default, { useRef, useState, useEffect, useLayoutEffect, useMemo, forwardRef, useCallback } from 'react';
|
|
3
3
|
import { Input as Input$1 } from 'antd';
|
|
4
4
|
import { g as get } from '../chunks/get-DPccfEM4.js';
|
|
@@ -1228,6 +1228,51 @@ function NumericFormat(props) {
|
|
|
1228
1228
|
return React__default.createElement(NumberFormatBase, Object.assign({}, numericFormatProps));
|
|
1229
1229
|
}
|
|
1230
1230
|
|
|
1231
|
+
const AllowClearIcon = ({
|
|
1232
|
+
size = 6,
|
|
1233
|
+
color = "currentColor",
|
|
1234
|
+
className,
|
|
1235
|
+
style,
|
|
1236
|
+
onClick,
|
|
1237
|
+
"aria-label": ariaLabel,
|
|
1238
|
+
title,
|
|
1239
|
+
...props
|
|
1240
|
+
}) => /* @__PURE__ */ jsx(
|
|
1241
|
+
"div",
|
|
1242
|
+
{
|
|
1243
|
+
className,
|
|
1244
|
+
style: {
|
|
1245
|
+
width: size,
|
|
1246
|
+
height: size,
|
|
1247
|
+
cursor: onClick ? "pointer" : "default",
|
|
1248
|
+
...style
|
|
1249
|
+
},
|
|
1250
|
+
onClick,
|
|
1251
|
+
role: onClick ? "button" : void 0,
|
|
1252
|
+
"aria-label": ariaLabel,
|
|
1253
|
+
title,
|
|
1254
|
+
...props,
|
|
1255
|
+
children: /* @__PURE__ */ jsx(
|
|
1256
|
+
"svg",
|
|
1257
|
+
{
|
|
1258
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1259
|
+
width: "100%",
|
|
1260
|
+
height: "100%",
|
|
1261
|
+
fill: "none",
|
|
1262
|
+
children: /* @__PURE__ */ jsx(
|
|
1263
|
+
"path",
|
|
1264
|
+
{
|
|
1265
|
+
fill: color || "#116DFF",
|
|
1266
|
+
fillRule: "evenodd",
|
|
1267
|
+
d: "M5.2 0 3 2.2.8 0 0 .8 2.2 3 0 5.3l.8.7L3 3.8 5.2 6l.8-.7L3.8 3 6 .8 5.2 0Z",
|
|
1268
|
+
clipRule: "evenodd"
|
|
1269
|
+
}
|
|
1270
|
+
)
|
|
1271
|
+
}
|
|
1272
|
+
)
|
|
1273
|
+
}
|
|
1274
|
+
);
|
|
1275
|
+
|
|
1231
1276
|
const Input = (props) => {
|
|
1232
1277
|
//! State
|
|
1233
1278
|
const {
|
|
@@ -1246,6 +1291,7 @@ const Input = (props) => {
|
|
|
1246
1291
|
classNameLabel,
|
|
1247
1292
|
inputPassword,
|
|
1248
1293
|
toUpperCaseValue,
|
|
1294
|
+
allowClear,
|
|
1249
1295
|
...restProps
|
|
1250
1296
|
} = props;
|
|
1251
1297
|
const { name, value, onChange, onBlur } = field || {};
|
|
@@ -1404,6 +1450,9 @@ const Input = (props) => {
|
|
|
1404
1450
|
suffix: iconEndInput,
|
|
1405
1451
|
className: twMerge("pnkx-default-input", classNameInput),
|
|
1406
1452
|
status: (isTouched || isSubmitted) && errorMessage ? "error" : "",
|
|
1453
|
+
allowClear: allowClear ? {
|
|
1454
|
+
clearIcon: /* @__PURE__ */ jsx("div", { className: "allowClearIcon", children: /* @__PURE__ */ jsx(AllowClearIcon, { color: "#116DFF" }) })
|
|
1455
|
+
} : false,
|
|
1407
1456
|
...restProps
|
|
1408
1457
|
}
|
|
1409
1458
|
),
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useCallback } from 'react';
|
|
3
|
+
import { InputNumber } from 'antd';
|
|
4
|
+
import { g as get } from '../chunks/get-DPccfEM4.js';
|
|
5
|
+
import { ErrorMessage } from '../ui/ErrorMessage.js';
|
|
6
|
+
import { Label } from '../ui/Label.js';
|
|
7
|
+
import { t as twMerge } from '../chunks/bundle-mjs-BME7zF0Z.js';
|
|
8
|
+
|
|
9
|
+
const InputRangePicker = (props) => {
|
|
10
|
+
//! State
|
|
11
|
+
const {
|
|
12
|
+
label,
|
|
13
|
+
required,
|
|
14
|
+
field,
|
|
15
|
+
formState,
|
|
16
|
+
afterOnChange,
|
|
17
|
+
classNameContainer,
|
|
18
|
+
classNameInput,
|
|
19
|
+
classNameInputWrapper,
|
|
20
|
+
classNameLabel,
|
|
21
|
+
thousandSeparator = true,
|
|
22
|
+
placeholderFrom = "Từ",
|
|
23
|
+
placeholderTo = "Đến",
|
|
24
|
+
...restProps
|
|
25
|
+
} = props;
|
|
26
|
+
const { name, value, onChange, onBlur } = field || {};
|
|
27
|
+
const { touchedFields, errors, isSubmitted } = formState || {};
|
|
28
|
+
const isTouched = get(touchedFields, name);
|
|
29
|
+
const errorMessage = get(errors, name)?.message;
|
|
30
|
+
const rangeValue = value;
|
|
31
|
+
const fromValue = rangeValue?.[0] ?? null;
|
|
32
|
+
const toValue = rangeValue?.[1] ?? null;
|
|
33
|
+
//! Function
|
|
34
|
+
const handleFromChange = useCallback(
|
|
35
|
+
(val) => {
|
|
36
|
+
const newValue = [
|
|
37
|
+
val,
|
|
38
|
+
toValue
|
|
39
|
+
];
|
|
40
|
+
onChange?.(newValue);
|
|
41
|
+
afterOnChange?.(newValue);
|
|
42
|
+
},
|
|
43
|
+
[onChange, afterOnChange, toValue]
|
|
44
|
+
);
|
|
45
|
+
const handleToChange = useCallback(
|
|
46
|
+
(val) => {
|
|
47
|
+
const newValue = [
|
|
48
|
+
fromValue,
|
|
49
|
+
val
|
|
50
|
+
];
|
|
51
|
+
onChange?.(newValue);
|
|
52
|
+
afterOnChange?.(newValue);
|
|
53
|
+
},
|
|
54
|
+
[onChange, afterOnChange, fromValue]
|
|
55
|
+
);
|
|
56
|
+
const handleBlur = useCallback(() => {
|
|
57
|
+
onBlur?.();
|
|
58
|
+
}, [onBlur]);
|
|
59
|
+
//! Render
|
|
60
|
+
const renderLabel = () => {
|
|
61
|
+
if (!label) return null;
|
|
62
|
+
return /* @__PURE__ */ jsx(
|
|
63
|
+
Label,
|
|
64
|
+
{
|
|
65
|
+
label,
|
|
66
|
+
required,
|
|
67
|
+
classNameLabel
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
};
|
|
71
|
+
const renderInput = () => {
|
|
72
|
+
return /* @__PURE__ */ jsxs(
|
|
73
|
+
"div",
|
|
74
|
+
{
|
|
75
|
+
className: twMerge(
|
|
76
|
+
"relative flex items-center border border-gray-300 rounded-lg bg-white hover:border-blue-400 focus-within:border-blue-500 focus-within:ring-1 focus-within:ring-blue-500 transition-colors",
|
|
77
|
+
(isTouched || isSubmitted) && errorMessage && "border-red-500 focus-within:border-red-500 focus-within:ring-red-500",
|
|
78
|
+
classNameInputWrapper
|
|
79
|
+
),
|
|
80
|
+
children: [
|
|
81
|
+
/* @__PURE__ */ jsx(
|
|
82
|
+
InputNumber,
|
|
83
|
+
{
|
|
84
|
+
name: `${name}_from`,
|
|
85
|
+
value: fromValue,
|
|
86
|
+
onChange: handleFromChange,
|
|
87
|
+
onBlur: handleBlur,
|
|
88
|
+
placeholder: placeholderFrom,
|
|
89
|
+
className: twMerge("flex-1", classNameInput),
|
|
90
|
+
style: {
|
|
91
|
+
border: "none",
|
|
92
|
+
boxShadow: "none",
|
|
93
|
+
background: "transparent"
|
|
94
|
+
},
|
|
95
|
+
formatter: thousandSeparator ? (value2) => `${value2}`.replace(/\B(?=(\d{3})+(?!\d))/g, ",") : void 0,
|
|
96
|
+
parser: thousandSeparator ? (value2) => value2.replace(/\$\s?|(,*)/g, "") : void 0,
|
|
97
|
+
controls: false,
|
|
98
|
+
...restProps
|
|
99
|
+
}
|
|
100
|
+
),
|
|
101
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-center px-2 text-gray-400", children: /* @__PURE__ */ jsx(
|
|
102
|
+
"svg",
|
|
103
|
+
{
|
|
104
|
+
width: "20",
|
|
105
|
+
height: "20",
|
|
106
|
+
viewBox: "0 0 24 24",
|
|
107
|
+
fill: "none",
|
|
108
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
109
|
+
children: /* @__PURE__ */ jsx(
|
|
110
|
+
"path",
|
|
111
|
+
{
|
|
112
|
+
d: "M5 12H18M13 6L18.2929 11.2929C18.6834 11.6834 18.6834 12.3166 18.2929 12.7071L13 18",
|
|
113
|
+
stroke: "black",
|
|
114
|
+
"stroke-width": "1.5",
|
|
115
|
+
"stroke-linecap": "round"
|
|
116
|
+
}
|
|
117
|
+
)
|
|
118
|
+
}
|
|
119
|
+
) }),
|
|
120
|
+
/* @__PURE__ */ jsx(
|
|
121
|
+
InputNumber,
|
|
122
|
+
{
|
|
123
|
+
name: `${name}_to`,
|
|
124
|
+
value: toValue,
|
|
125
|
+
onChange: handleToChange,
|
|
126
|
+
onBlur: handleBlur,
|
|
127
|
+
placeholder: placeholderTo,
|
|
128
|
+
className: twMerge("flex-1 ", classNameInput),
|
|
129
|
+
style: {
|
|
130
|
+
border: "none",
|
|
131
|
+
boxShadow: "none",
|
|
132
|
+
background: "transparent"
|
|
133
|
+
},
|
|
134
|
+
formatter: thousandSeparator ? (value2) => `${value2}`.replace(/\B(?=(\d{3})+(?!\d))/g, ",") : void 0,
|
|
135
|
+
parser: thousandSeparator ? (value2) => value2.replace(/\$\s?|(,*)/g, "") : void 0,
|
|
136
|
+
controls: false,
|
|
137
|
+
max: 9999999999,
|
|
138
|
+
...restProps
|
|
139
|
+
}
|
|
140
|
+
)
|
|
141
|
+
]
|
|
142
|
+
}
|
|
143
|
+
);
|
|
144
|
+
};
|
|
145
|
+
const renderErrorMessage = () => {
|
|
146
|
+
if (!errorMessage) return null;
|
|
147
|
+
return /* @__PURE__ */ jsx(
|
|
148
|
+
ErrorMessage,
|
|
149
|
+
{
|
|
150
|
+
errorMessage,
|
|
151
|
+
isTouched,
|
|
152
|
+
isSubmitted
|
|
153
|
+
}
|
|
154
|
+
);
|
|
155
|
+
};
|
|
156
|
+
return /* @__PURE__ */ jsxs("div", { className: twMerge("w-full", classNameContainer), children: [
|
|
157
|
+
renderLabel(),
|
|
158
|
+
renderInput(),
|
|
159
|
+
renderErrorMessage()
|
|
160
|
+
] });
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
export { InputRangePicker };
|
package/es/fields/index.js
CHANGED
package/es/index.js
CHANGED
|
@@ -79,5 +79,6 @@ export { SliderRange } from './fields/SliderRanger.js';
|
|
|
79
79
|
export { TimeRangePicker } from './fields/TimeRangePicker.js';
|
|
80
80
|
export { TimePicker } from './fields/TimePicker.js';
|
|
81
81
|
export { Cascader } from './fields/CascaderField.js';
|
|
82
|
+
export { InputRangePicker } from './fields/InputRangePicker.js';
|
|
82
83
|
export { useToast } from './hooks/useToast.js';
|
|
83
84
|
export { useMessage } from './hooks/useMessage.js';
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import { Select, Table, Spin } from 'antd';
|
|
3
|
+
import { useState, useCallback } from 'react';
|
|
4
|
+
|
|
5
|
+
function SelectTable({
|
|
6
|
+
columns,
|
|
7
|
+
dataSource = [],
|
|
8
|
+
selectedKeys = [],
|
|
9
|
+
onSelectionChange,
|
|
10
|
+
onLoadMore,
|
|
11
|
+
onSearch,
|
|
12
|
+
hasMore = false,
|
|
13
|
+
loading = false,
|
|
14
|
+
rowKey = "key",
|
|
15
|
+
tableProps = {},
|
|
16
|
+
infiniteScroll = false,
|
|
17
|
+
loadMoreThreshold = 50,
|
|
18
|
+
searchPlaceholder = "Tìm kiếm...",
|
|
19
|
+
...selectProps
|
|
20
|
+
}) {
|
|
21
|
+
const [open, setOpen] = useState(false);
|
|
22
|
+
const [internalDataSource] = useState(dataSource);
|
|
23
|
+
const [internalLoading, setInternalLoading] = useState(false);
|
|
24
|
+
const [searchValue, setSearchValue] = useState("");
|
|
25
|
+
const [isClearing, setIsClearing] = useState(false);
|
|
26
|
+
const currentDataSource = dataSource.length > 0 ? dataSource : internalDataSource;
|
|
27
|
+
const loadMoreData = useCallback(async () => {
|
|
28
|
+
if (internalLoading || loading || !hasMore || !onLoadMore) return;
|
|
29
|
+
setInternalLoading(true);
|
|
30
|
+
try {
|
|
31
|
+
await onLoadMore();
|
|
32
|
+
} catch (error) {
|
|
33
|
+
console.error("Error loading more data:", error);
|
|
34
|
+
} finally {
|
|
35
|
+
setInternalLoading(false);
|
|
36
|
+
}
|
|
37
|
+
}, [onLoadMore, internalLoading, loading, hasMore]);
|
|
38
|
+
const handleScroll = useCallback(
|
|
39
|
+
(e) => {
|
|
40
|
+
if (!infiniteScroll) return;
|
|
41
|
+
const { scrollTop, scrollHeight, clientHeight } = e.currentTarget;
|
|
42
|
+
if (scrollHeight - scrollTop <= clientHeight + loadMoreThreshold) {
|
|
43
|
+
loadMoreData();
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
[infiniteScroll, loadMoreThreshold, loadMoreData]
|
|
47
|
+
);
|
|
48
|
+
const onSelectChange = (newSelectedRowKeys, newSelectedRows) => {
|
|
49
|
+
if (onSelectionChange) {
|
|
50
|
+
onSelectionChange(newSelectedRowKeys, newSelectedRows);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
const rowSelection = {
|
|
54
|
+
selectedRowKeys: selectedKeys,
|
|
55
|
+
onChange: onSelectChange
|
|
56
|
+
};
|
|
57
|
+
const getDisplayValue = useCallback(() => {
|
|
58
|
+
return [];
|
|
59
|
+
}, []);
|
|
60
|
+
const handleSearch = (value) => {
|
|
61
|
+
setSearchValue(value);
|
|
62
|
+
if (onSearch) {
|
|
63
|
+
onSearch(value);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
const handleClear = () => {
|
|
67
|
+
setIsClearing(true);
|
|
68
|
+
setSearchValue("");
|
|
69
|
+
if (onSearch) {
|
|
70
|
+
onSearch("");
|
|
71
|
+
}
|
|
72
|
+
setTimeout(() => {
|
|
73
|
+
setOpen(true);
|
|
74
|
+
setIsClearing(false);
|
|
75
|
+
}, 10);
|
|
76
|
+
};
|
|
77
|
+
const handleDropdownVisibleChange = (visible) => {
|
|
78
|
+
if (isClearing && !visible) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
setOpen(visible);
|
|
82
|
+
};
|
|
83
|
+
const dropdownRender = () => /* @__PURE__ */ jsx("div", { className: "select-table-dropdown", children: /* @__PURE__ */ jsxs("div", { className: "overflow-x-hidden w-full", children: [
|
|
84
|
+
/* @__PURE__ */ jsx(
|
|
85
|
+
Table,
|
|
86
|
+
{
|
|
87
|
+
className: "select-table-custom",
|
|
88
|
+
rowSelection,
|
|
89
|
+
columns,
|
|
90
|
+
dataSource: currentDataSource,
|
|
91
|
+
rowKey,
|
|
92
|
+
size: tableProps.size || "small",
|
|
93
|
+
pagination: false,
|
|
94
|
+
scroll: { y: 500 },
|
|
95
|
+
style: { overflowX: "hidden" },
|
|
96
|
+
loading: false,
|
|
97
|
+
onScroll: handleScroll,
|
|
98
|
+
...tableProps
|
|
99
|
+
}
|
|
100
|
+
),
|
|
101
|
+
(internalLoading || loading) && /* @__PURE__ */ jsxs("div", { className: "text-center py-2 border-t border-gray-200", children: [
|
|
102
|
+
/* @__PURE__ */ jsx(Spin, { size: "small" }),
|
|
103
|
+
" Đang tải thêm..."
|
|
104
|
+
] })
|
|
105
|
+
] }) });
|
|
106
|
+
return /* @__PURE__ */ jsx(
|
|
107
|
+
Select,
|
|
108
|
+
{
|
|
109
|
+
...selectProps,
|
|
110
|
+
open,
|
|
111
|
+
onDropdownVisibleChange: handleDropdownVisibleChange,
|
|
112
|
+
dropdownRender,
|
|
113
|
+
value: getDisplayValue(),
|
|
114
|
+
mode: "multiple",
|
|
115
|
+
showSearch: true,
|
|
116
|
+
onSearch: handleSearch,
|
|
117
|
+
onClear: handleClear,
|
|
118
|
+
placeholder: searchPlaceholder,
|
|
119
|
+
maxTagCount: 0,
|
|
120
|
+
showArrow: true,
|
|
121
|
+
filterOption: false,
|
|
122
|
+
searchValue
|
|
123
|
+
}
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export { SelectTable as default };
|