diginet-core-ui 1.4.52 → 1.4.53-beta.10

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.
Files changed (113) hide show
  1. package/assets/images/menu/dhr/MHRP09N0036.svg +13 -0
  2. package/assets/images/menu/dhr/MHRP09N0037.svg +14 -0
  3. package/assets/images/menu/dhr/MHRP25N0009.svg +15 -0
  4. package/components/accordion/details.js +1 -1
  5. package/components/accordion/group.js +1 -1
  6. package/components/accordion/index.js +1 -1
  7. package/components/accordion/summary.js +1 -1
  8. package/components/alert/index.js +1 -1
  9. package/components/alert/notify.js +1 -1
  10. package/components/avatar/index.js +2 -2
  11. package/components/badge/index.js +1 -1
  12. package/components/breadcrumb/index.js +1 -1
  13. package/components/button/icon.js +1 -1
  14. package/components/button/index.js +1 -1
  15. package/components/button/more.js +2 -2
  16. package/components/button/ripple-effect.js +1 -1
  17. package/components/card/body.js +1 -1
  18. package/components/card/extra.js +1 -1
  19. package/components/card/footer.js +1 -1
  20. package/components/card/header.js +1 -1
  21. package/components/card/index.js +1 -1
  22. package/components/chart/Pie/Circle.js +1 -1
  23. package/components/chart/Pie/Sector.js +1 -1
  24. package/components/chart/Pie/index.js +1 -1
  25. package/components/chart/Pie-v2/Circle.js +1 -1
  26. package/components/chart/Pie-v2/Sector.js +1 -1
  27. package/components/chart/Pie-v2/index.js +1 -1
  28. package/components/chart/bar/Bar.js +1 -1
  29. package/components/chart/bar/index.js +1 -1
  30. package/components/chart/bar-v2/Bar.js +1 -1
  31. package/components/chart/bar-v2/index.js +1 -1
  32. package/components/chart/line/index.js +1 -1
  33. package/components/chart/line-v2/index.js +1 -1
  34. package/components/check-text/index.js +1 -1
  35. package/components/check-text/interview-confirmation.js +1 -1
  36. package/components/check-text/interview-status.js +1 -1
  37. package/components/chip/index.js +1 -1
  38. package/components/collapse/index.js +1 -1
  39. package/components/divider/index.js +1 -1
  40. package/components/form-control/attachment/index.js +3 -3
  41. package/components/form-control/calendar/function.js +1 -1
  42. package/components/form-control/calendar/index.js +2 -2
  43. package/components/form-control/calendar/range.js +1 -1
  44. package/components/form-control/checkbox/index.js +1 -1
  45. package/components/form-control/control/index.js +1 -1
  46. package/components/form-control/date-input/index.js +1 -1
  47. package/components/form-control/date-input/useDateInputState.js +3 -5
  48. package/components/form-control/date-picker/index.js +28 -8
  49. package/components/form-control/date-range-picker/index.js +1 -1
  50. package/components/form-control/dropdown/index.js +3 -1
  51. package/components/form-control/dropdown-box/index.js +64 -22
  52. package/components/form-control/form-group/index.js +1 -1
  53. package/components/form-control/helper-text/index.js +1 -1
  54. package/components/form-control/input-base/UncontrolledInputBase.js +1 -1
  55. package/components/form-control/input-base/index.js +1 -1
  56. package/components/form-control/label/index.js +1 -1
  57. package/components/form-control/money-input/index.js +87 -12
  58. package/components/form-control/number-input/index2.js +53 -36
  59. package/components/form-control/password-input/index.js +1 -1
  60. package/components/form-control/phone-input/index.js +1 -1
  61. package/components/form-control/radio/index.js +1 -1
  62. package/components/form-control/text-input/index.js +1 -1
  63. package/components/form-control/time-picker/index.js +1 -1
  64. package/components/form-control/time-picker/v2/index.js +1 -1
  65. package/components/form-control/toggle/index.js +1 -1
  66. package/components/form-view/input.js +1 -1
  67. package/components/grid/index.js +1 -1
  68. package/components/image/index.js +1 -1
  69. package/components/list/list-item-action.js +1 -1
  70. package/components/list/list-item-icon.js +1 -1
  71. package/components/list/list-item-text.js +1 -1
  72. package/components/list/list-item.js +1 -1
  73. package/components/list/list.js +1 -1
  74. package/components/list/sub-header.js +1 -1
  75. package/components/modal/body.js +1 -1
  76. package/components/modal/footer.js +1 -1
  77. package/components/modal/header.js +1 -1
  78. package/components/modal/index.js +1 -1
  79. package/components/modal/modal.js +1 -1
  80. package/components/others/option-wrapper/index.js +1 -1
  81. package/components/paging/page-info.js +1 -1
  82. package/components/paging/page-selector.js +1 -1
  83. package/components/paper/index.js +1 -1
  84. package/components/popover/body.js +1 -1
  85. package/components/popover/footer.js +1 -1
  86. package/components/popover/header.js +1 -1
  87. package/components/popover/index.js +14 -14
  88. package/components/popup/index.js +1 -1
  89. package/components/popup/v2/index.js +1 -1
  90. package/components/progress/circular.js +1 -1
  91. package/components/progress/linear.js +1 -1
  92. package/components/rating/index.js +1 -1
  93. package/components/skeleton/index.js +1 -1
  94. package/components/slider/slider-container.js +1 -1
  95. package/components/slider/slider-item.js +1 -1
  96. package/components/status/index.js +1 -1
  97. package/components/tab/tab-container.js +1 -1
  98. package/components/tab/tab-header.js +1 -1
  99. package/components/tab/tab-panel.js +1 -1
  100. package/components/tab/tab.js +1 -1
  101. package/components/tooltip/index.js +1 -1
  102. package/components/transfer/index.js +1 -1
  103. package/components/tree-view/index.js +82 -46
  104. package/components/typography/index.js +1 -1
  105. package/global/index.js +80 -0
  106. package/icons/effect.js +1 -1
  107. package/icons/menu/v2/index.js +1 -1
  108. package/locale/index.js +1 -1
  109. package/package.json +78 -44
  110. package/readme.md +7 -0
  111. package/theme/settings.js +4 -3
  112. package/utils/getLang.js +69 -0
  113. package/utils/index.js +1 -0
@@ -2,8 +2,7 @@
2
2
  /** @jsx jsx */
3
3
  import { css, jsx } from '@emotion/core';
4
4
  import { Button, ButtonIcon, DateInput, HelperText, InputBase, Label, Popover, Tooltip } from "../..";
5
- import { format, isValid, parse } from 'date-fns';
6
- import { enUS, vi } from 'date-fns/locale';
5
+ import { isValid, parse } from 'date-fns';
7
6
  import { getGlobal } from "../../../global";
8
7
  import locale from "../../../locale";
9
8
  import PropTypes from 'prop-types';
@@ -14,6 +13,7 @@ import useThemeProps from "../../../theme/utils/useThemeProps";
14
13
  import { capitalizeSentenceCase, classNames, isValidDate, useControlled } from "../../../utils";
15
14
  import Calendar from "../calendar";
16
15
  import { lowerCaseDayYear } from "../date-input/utils";
16
+ import { parseDateString } from "../../../utils/getLang";
17
17
  const unique = {
18
18
  footer: 'DGN-UI-DatePicker-Footer',
19
19
  cancel: 'DGN-UI-DatePicker-cancel',
@@ -23,6 +23,10 @@ const unique = {
23
23
  const confirmText = getGlobal(['confirm']);
24
24
  const cancelText = getGlobal(['cancel']);
25
25
  const viDisplayFormat = new Map([['year', 'YYYY'], ['quarter', 'Q-YYYY'], ['month', 'MM-YYYY']]);
26
+ const zhDisplayFormat = new Map([['year', 'YYYY年'], ['quarter', 'YYYY年第Q季度'], ['month', 'YYYY年MM月']]);
27
+ const enDisplayFormat = new Map([['year', 'YYYY'], ['quarter', 'YYYY [Q]Q'],
28
+ // Exp: 2025 Q1
29
+ ['month', 'MM/YYYY']]);
26
30
  const pickerReturnFormat = new Map([['year', 'YYYY'], ['quarter', 'YYYY-Q'], ['month', 'YYYY-MM']]);
27
31
  const parseValueToDate = valueProp => {
28
32
  if (!valueProp) return null;else if (isValidDate(valueProp)) {
@@ -42,8 +46,26 @@ const parseValueToDate = valueProp => {
42
46
  return valueProp;
43
47
  }
44
48
  };
45
- const DatePicker = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((inProps, reference) => {
46
- var _ref, _pickerReturnFormat$g, _ipRef$current, _ipRef$current2;
49
+ const getDateFormats = (locale, minZoom) => {
50
+ let formatMap;
51
+ switch (locale) {
52
+ case 'vi':
53
+ formatMap = viDisplayFormat;
54
+ break;
55
+ case 'zh':
56
+ formatMap = zhDisplayFormat;
57
+ break;
58
+ case 'en':
59
+ formatMap = enDisplayFormat;
60
+ break;
61
+ default:
62
+ formatMap = pickerReturnFormat; // fallback
63
+ break;
64
+ }
65
+ return formatMap.get(minZoom);
66
+ };
67
+ const DatePicker = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((inProps, reference) => {
68
+ var _getDateFormats, _pickerReturnFormat$g, _ipRef$current, _ipRef$current2;
47
69
  if (!reference) reference = useRef(null);
48
70
  const theme = useTheme();
49
71
 
@@ -87,7 +109,7 @@ const DatePicker = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((inProps, referenc
87
109
  ...other
88
110
  } = props;
89
111
  const dateLocale = locale.get();
90
- const displayFormat = (_ref = dateLocale === 'vi' ? viDisplayFormat.get(minZoom) : pickerReturnFormat.get(minZoom)) !== null && _ref !== void 0 ? _ref : displayFormatProp;
112
+ const displayFormat = (_getDateFormats = getDateFormats(dateLocale, minZoom)) !== null && _getDateFormats !== void 0 ? _getDateFormats : displayFormatProp;
91
113
  const returnFormat = (_pickerReturnFormat$g = pickerReturnFormat.get(minZoom)) !== null && _pickerReturnFormat$g !== void 0 ? _pickerReturnFormat$g : returnFormatProp;
92
114
  const placeholder = placeholderProp !== null && placeholderProp !== void 0 ? placeholderProp : displayFormat;
93
115
  const [value, setValue] = useControlled(parseValueToDate(valueProp), parseValueToDate(defaultValue));
@@ -112,9 +134,7 @@ const DatePicker = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((inProps, referenc
112
134
  };
113
135
  const formatValue = (value, formatStr) => {
114
136
  // return moment(value).format(format, utc = false);
115
- return format(value, lowerCaseDayYear(formatStr), {
116
- locale: dateLocale === 'vi' ? vi : enUS
117
- });
137
+ return parseDateString(value, lowerCaseDayYear(formatStr), dateLocale);
118
138
  };
119
139
  const onChangeValue = e => {
120
140
  const vl = (e === null || e === void 0 ? void 0 : e.value) || e;
@@ -65,7 +65,7 @@ const isAfter = (max, time) => {
65
65
  const parseDate = day => {
66
66
  return Date.parse(new Date(day));
67
67
  };
68
- const DateRangePicker = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((inProps, reference) => {
68
+ const DateRangePicker = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((inProps, reference) => {
69
69
  // props priority: `inProps` > `themeDefaultProps`
70
70
  const props = useThemeProps({
71
71
  props: inProps,
@@ -47,7 +47,7 @@ const uniqBy = (arr, iteratee) => {
47
47
  return true;
48
48
  });
49
49
  };
50
- const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((inProps, reference) => {
50
+ const Dropdown = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((inProps, reference) => {
51
51
  if (!reference) reference = useRef(null);
52
52
  const theme = useTheme();
53
53
  const {
@@ -294,6 +294,7 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((inProps, reference)
294
294
  * @return {boolean}
295
295
  */
296
296
  const handleRenderBySearch = (text = '') => {
297
+ if (text === null || text === undefined) text = '';
297
298
  if (typeof text !== 'string') text = text.toString();
298
299
  if (!txtSearch) return true;
299
300
  if (searchMode === 'startswith') {
@@ -436,6 +437,7 @@ const Dropdown = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((inProps, reference)
436
437
  }, items !== null && items !== void 0 && items.length ? items : EmptyDataText);
437
438
  };
438
439
  const mapTreeView = () => {
440
+ console.log('here');
439
441
  return jsx("div", {
440
442
  css: _DropdownListCSS,
441
443
  ref: dropdownListRef,
@@ -1,14 +1,16 @@
1
1
  /** @jsxRuntime classic */
2
2
  /** @jsx jsx */
3
3
  import { css, jsx } from '@emotion/core';
4
- import { ButtonIcon, InputBase, Label, Popover, PopoverBody } from "../..";
4
+ import { ButtonIcon, InputBase, Label, Popover, PopoverBody, HelperText } from "../..";
5
5
  import PropTypes from 'prop-types';
6
- import { Fragment, forwardRef, memo, useEffect, useImperativeHandle, useLayoutEffect, useRef, useState } from 'react';
6
+ import { Fragment, forwardRef, memo, useEffect, useImperativeHandle, useLayoutEffect, useRef, useState, useMemo } from 'react';
7
7
  import { animation, borderColor, displayBlock, overflowHidden, parseHeight, parseMinWidth, positionRelative, scaleX } from "../../../styles/general";
8
8
  import { useTheme } from "../../../theme";
9
9
  import useThemeProps from "../../../theme/utils/useThemeProps";
10
10
  import { classNames, getProp } from "../../../utils";
11
- const DropdownBox = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((inProps, reference) => {
11
+ const regexBetween = /[^{}]+(?=})/g;
12
+ const regexInclude = /{|}/g;
13
+ const DropdownBox = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((inProps, reference) => {
12
14
  if (!reference) reference = useRef(null);
13
15
  const theme = useTheme();
14
16
  const {
@@ -22,10 +24,14 @@ const DropdownBox = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((inProps, referen
22
24
  });
23
25
  const {
24
26
  action = {},
27
+ allowInput,
25
28
  bgColor: bgColorProp,
26
29
  children,
27
30
  className,
28
31
  delayOnInput,
32
+ disabled,
33
+ displayExpr: displayExprProp,
34
+ error,
29
35
  endIcon,
30
36
  inputProps,
31
37
  inputRef,
@@ -39,10 +45,19 @@ const DropdownBox = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((inProps, referen
39
45
  placeholder,
40
46
  startIcon,
41
47
  style,
42
- value,
43
- viewType
48
+ value: valueProps,
49
+ valueExpr,
50
+ viewType,
51
+ helperTextProps
44
52
  } = props;
53
+ let displayExpr = displayExprProp;
45
54
  const bgColor = typeof bgColorProp === 'string' ? getProp(colors, bgColorProp, bgColorProp) : bgColorProp;
55
+ const ErrorView = useMemo(() => {
56
+ return error ? jsx(HelperText, {
57
+ ...helperTextProps,
58
+ disabled: disabled
59
+ }, error) : null;
60
+ }, [disabled, error, helperTextProps]);
46
61
  const ref = useRef(null);
47
62
  const dropdownBoxRef = useRef(null);
48
63
  const timer = useRef(null);
@@ -85,6 +100,28 @@ const DropdownBox = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((inProps, referen
85
100
  onClosed === null || onClosed === void 0 ? void 0 : onClosed();
86
101
  }
87
102
  };
103
+
104
+ /**
105
+ * Chuyển đổi data thành giá trị cần hiện thị dựa vào displayExpr [string, string object {field} - {field}], renderSelectedItem, displayExpr, valueExpr
106
+ * @param data {object} rowData of dataSource
107
+ * @return {string}
108
+ */
109
+ const displayValue = data => {
110
+ let text = '';
111
+ if (data || data === 0) {
112
+ displayExpr = displayExpr || valueExpr;
113
+ let mask = data === null || data === void 0 ? void 0 : data[displayExpr];
114
+ // convert {id} - {name} to {<data[id]>} - {<data[name]>}
115
+ if (!mask && regexBetween.test(displayExpr)) {
116
+ var _displayExpr;
117
+ mask = (_displayExpr = displayExpr) === null || _displayExpr === void 0 ? void 0 : _displayExpr.replace(regexBetween, _ => (data === null || data === void 0 ? void 0 : data[_]) || '');
118
+ } else if (!mask) {
119
+ mask = typeof data !== 'object' ? data : '';
120
+ }
121
+ text = mask.toString().replace(regexInclude, '');
122
+ }
123
+ return text;
124
+ };
88
125
  useLayoutEffect(() => {
89
126
  if (ref.current) {
90
127
  const {
@@ -130,15 +167,17 @@ const DropdownBox = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((inProps, referen
130
167
  onClick: openOnClickAt === 'icon' ? onTriggerDropdown : null
131
168
  }) : null;
132
169
  };
170
+ const value = displayValue(valueProps);
133
171
  return jsx(Fragment, null, jsx("div", {
134
172
  ref: ref,
135
173
  css: _DropdownBoxRootCSS,
136
- className: classNames('DGN-UI-Dropdown-Box', className),
174
+ className: classNames('DGN-UI-Dropdown-Box', className, error && 'error'),
137
175
  style: style
138
176
  }, label ? jsx(Label, {
139
177
  ...labelProps
140
178
  }, label) : null, jsx(InputBase, {
141
179
  ...inputProps,
180
+ readOnly: !allowInput,
142
181
  style: inputStyle,
143
182
  viewType: viewType,
144
183
  inputRef: inputRef,
@@ -157,7 +196,7 @@ const DropdownBox = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((inProps, referen
157
196
  anchor: ref.current,
158
197
  width: popoverWidth,
159
198
  onClose: closeDropdownBox
160
- }, jsx(PopoverBody, null, children)));
199
+ }, jsx(PopoverBody, null, children)), ErrorView);
161
200
  }));
162
201
  const DropdownBoxRootCSS = (bgColorProp, {
163
202
  colors
@@ -166,6 +205,17 @@ const DropdownBoxRootCSS = (bgColorProp, {
166
205
  ${positionRelative};
167
206
  ${parseMinWidth(150)};
168
207
  ${parseHeight('max-content')};
208
+ &.error {
209
+ .DGN-UI-InputBase {
210
+ ${borderColor(getProp(colors, 'semantic/danger'))};
211
+ &::before {
212
+ ${borderColor(getProp(colors, 'semantic/danger'))};
213
+ }
214
+ &::after {
215
+ ${borderColor(getProp(colors, 'semantic/danger'))};
216
+ }
217
+ }
218
+ }
169
219
  .DGN-UI-InputBase {
170
220
  background: ${bgColorProp ? bgColorProp === true ? getProp(colors, 'fill/disabled') : bgColorProp : 'inherit'} !important;
171
221
  ${openState && css`
@@ -183,20 +233,6 @@ const DropdownBoxCSS = ({
183
233
  margin-top: ${spacing([1])};
184
234
  ${overflowHidden};
185
235
  `;
186
-
187
- // DropdownBox.defaultProps = {
188
- // className: '',
189
- // label: '',
190
- // placeholder: '',
191
- // startIcon: 'Search',
192
- // endIcon: 'ArrowDown',
193
- // openOnClickAt: 'icon',
194
- // viewType: 'underlined',
195
- // inputProps: {},
196
- // delayOnInput: 700,
197
- // zIndex: zIndexCORE(1),
198
- // };
199
-
200
236
  DropdownBox.propTypes = {
201
237
  /** class for dropdown */
202
238
  className: PropTypes.string,
@@ -233,6 +269,12 @@ DropdownBox.propTypes = {
233
269
  /** the function will run after open */
234
270
  onOpened: PropTypes.func,
235
271
  /** the function will run after close */
236
- onClosed: PropTypes.func
272
+ onClosed: PropTypes.func,
273
+ /** Error message displayed below the input. */
274
+ error: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
275
+ /** If `true`, the component is disabled. */
276
+ disabled: PropTypes.bool,
277
+ /** If `true`, the input is enable. */
278
+ allowInput: PropTypes.bool
237
279
  };
238
280
  export default DropdownBox;
@@ -4,7 +4,7 @@ import { css, jsx } from '@emotion/core';
4
4
  import PropTypes from 'prop-types';
5
5
  import { Children, forwardRef, memo, useEffect, useImperativeHandle, useRef } from 'react';
6
6
  import { useTheme } from "../../../theme";
7
- const FormGroup = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
7
+ const FormGroup = /*#__PURE__*/memo(/*#__PURE__*/forwardRef(({
8
8
  fullWidth,
9
9
  oneHelperText,
10
10
  marginRight,
@@ -9,7 +9,7 @@ import { useTheme } from "../../../theme";
9
9
  import useThemeProps from "../../../theme/utils/useThemeProps";
10
10
  import { classNames, getProp } from "../../../utils";
11
11
  const colorMap = new Map([['default', 'semantic/danger'], ['success', 'semantic/success'], ['warning', 'semantic/warning'], ['danger', 'semantic/danger'], ['info', 'semantic/info']]);
12
- const HelperText = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((inProps, reference) => {
12
+ const HelperText = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((inProps, reference) => {
13
13
  if (!reference) reference = useRef(null);
14
14
  const theme = useTheme();
15
15
  const {
@@ -9,7 +9,7 @@ import { bgColor, border, borderBottom, borderBottomColor, borderColor, borderNo
9
9
  import { useTheme } from "../../../theme";
10
10
  import useThemeProps from "../../../theme/utils/useThemeProps";
11
11
  import { classNames, refType as ref, getProp } from "../../../utils";
12
- const UncontrolledInputBase = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((inProps, reference) => {
12
+ const UncontrolledInputBase = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((inProps, reference) => {
13
13
  if (!reference) reference = useRef(null);
14
14
  const theme = useTheme();
15
15
  const {
@@ -9,7 +9,7 @@ import { bgColor, bgTransparent, border, borderBottom, borderBottomColor, border
9
9
  import { useTheme } from "../../../theme";
10
10
  import useThemeProps from "../../../theme/utils/useThemeProps";
11
11
  import { classNames, refType as ref, useInput, getProp } from "../../../utils";
12
- const InputBase = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((inProps, reference) => {
12
+ const InputBase = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((inProps, reference) => {
13
13
  if (!reference) reference = useRef(null);
14
14
  const theme = useTheme();
15
15
  const {
@@ -9,7 +9,7 @@ import { flexRow, parseMinHeight, typographyTypes } from "../../../styles/genera
9
9
  import { useTheme } from "../../../theme";
10
10
  import useThemeProps from "../../../theme/utils/useThemeProps";
11
11
  import { classNames, getProp } from "../../../utils";
12
- const Label = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((inProps, reference) => {
12
+ const Label = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((inProps, reference) => {
13
13
  if (!reference) reference = useRef(null);
14
14
  const theme = useTheme();
15
15
  const {
@@ -10,6 +10,7 @@ import { forwardRef, memo, useEffect, useImperativeHandle, useRef } from 'react'
10
10
  import { displayBlock, positionRelative } from "../../../styles/general";
11
11
  import useThemeProps from "../../../theme/utils/useThemeProps";
12
12
  import { onValidate } from "../../../utils";
13
+ import { getThousandSeparatorByCountry } from "../../../utils/getLang";
13
14
  const num2WordsVi = function () {
14
15
  let t = ['không', 'một', 'hai', 'ba', 'bốn', 'năm', 'sáu', 'bảy', 'tám', 'chín'],
15
16
  r = function (r, n) {
@@ -72,7 +73,62 @@ const num2WordsEn = n => {
72
73
  if (n === '0') return 'zero';
73
74
  return comp(chunk(3))(reverse)(arr(n)).map(makeGroup).map(thousand).filter(comp(not)(isEmpty)).reverse().join(' ');
74
75
  };
75
- const MoneyInput = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((inProps, reference) => {
76
+ const num2WordsZh = (() => {
77
+ const t = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'];
78
+ const units = ['', '十', '百', '千'];
79
+ const bigUnits = ['', '万', '亿', '兆'];
80
+ const readSection = num => {
81
+ let str = '';
82
+ let zero = true;
83
+ for (let i = 0; i < 4 && num > 0; i++) {
84
+ const digit = num % 10;
85
+ if (digit === 0) {
86
+ if (!zero) {
87
+ zero = true;
88
+ str = t[0] + str;
89
+ }
90
+ } else {
91
+ zero = false;
92
+ str = t[digit] + units[i] + str;
93
+ }
94
+ num = Math.floor(num / 10);
95
+ }
96
+ return str;
97
+ };
98
+ return {
99
+ convert: num => {
100
+ if (num === 0) return t[0];
101
+ let str = '';
102
+ let unitPos = 0;
103
+ let needZero = false;
104
+ while (num > 0) {
105
+ const section = num % 10000;
106
+ if (section === 0) {
107
+ if (needZero) {
108
+ str = t[0] + str;
109
+ needZero = false;
110
+ }
111
+ } else {
112
+ const sectionStr = readSection(section) + bigUnits[unitPos];
113
+ str = sectionStr + str;
114
+ needZero = true;
115
+ }
116
+ num = Math.floor(num / 10000);
117
+ unitPos++;
118
+ }
119
+
120
+ // Special cases
121
+ str = str.replace(/^一十/, '十'); // "一十X" => "十X"
122
+ return str;
123
+ }
124
+ };
125
+ })();
126
+ const converters = {
127
+ vi: num2WordsVi,
128
+ en: num2WordsEn,
129
+ zh: num2WordsZh
130
+ };
131
+ const MoneyInput = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((inProps, reference) => {
76
132
  if (!reference) reference = useRef(null);
77
133
 
78
134
  // props priority: `inProps` > `themeDefaultProps`
@@ -116,6 +172,7 @@ const MoneyInput = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((inProps, referenc
116
172
  viewType,
117
173
  defaultValue,
118
174
  value,
175
+ fixedDecimalDigit,
119
176
  ...other
120
177
  } = props;
121
178
  const ref = useRef(null);
@@ -125,7 +182,7 @@ const MoneyInput = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((inProps, referenc
125
182
  isPaste: false,
126
183
  clipboardText: ''
127
184
  });
128
- const separatorSymbol = typeof thousandSeparator === 'string' ? thousandSeparator : locale.get() === 'vi' ? '.' : ',';
185
+ const separatorSymbol = typeof thousandSeparator === 'string' ? thousandSeparator : getThousandSeparatorByCountry(locale.get());
129
186
  const decimalSymbol = separatorSymbol === '.' ? ',' : '.';
130
187
  const thousandSeparatorPattern = new RegExp(`[0-9]|Backspace|Delete|Arrow|Home|End|Tab${decimalDigit === 0 ? '' : '|\\' + decimalSymbol}${disabledNegative ? '' : '|-'}`);
131
188
  const isError = !!error && !value && value !== 0;
@@ -145,7 +202,7 @@ const MoneyInput = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((inProps, referenc
145
202
  if (decimal && decimal.length > decimalDigit) {
146
203
  if (decimalDigit) {
147
204
  decimal = decimal.slice(0, decimalDigit);
148
- return number + decimalSymbol + decimal;
205
+ return parseValueWithFix(number + decimalSymbol + decimal);
149
206
  } else {
150
207
  return number;
151
208
  }
@@ -332,11 +389,26 @@ const MoneyInput = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((inProps, referenc
332
389
  if (value === null) {
333
390
  inputRef.current.value = '';
334
391
  } else {
335
- const v = getValueWithDecimal(value.toString().replace('.', decimalSymbol));
392
+ let number = value;
393
+ if (fixedDecimalDigit && !!decimalDigit) {
394
+ var _strVal$split;
395
+ const strVal = String(value);
396
+ const isDecimalNum = strVal.indexOf('.') > -1 && (((_strVal$split = strVal.split('.')) === null || _strVal$split === void 0 ? void 0 : _strVal$split[1]) || '').length >= decimalDigit;
397
+ if (isDecimalNum) {
398
+ const coreToFixed = (num, precision) => {
399
+ return (+(Math.round(+(num + 'e' + precision)) + 'e' + -precision)).toFixed(precision);
400
+ };
401
+ const val = coreToFixed(Number(String(value).replace(thousandSeparator, '')), decimalDigit);
402
+ number = String(val);
403
+ }
404
+ }
405
+ const v = getValueWithDecimal(number.toString().replace('.', decimalSymbol));
336
406
  if (convertToWords && !decimalDigit && (disabled || readOnly)) {
337
407
  let valueConverted = getGlobal('helperInvalid');
338
- if (Number.isInteger(value)) {
339
- valueConverted = locale.get() === 'vi' ? num2WordsVi.convert(value) : num2WordsEn(value);
408
+ if (Number.isInteger(number)) {
409
+ const currentLocale = locale.get();
410
+ const converter = converters[currentLocale] || num2WordsVi; // fallback VN
411
+ valueConverted = converter.convert(number);
340
412
  }
341
413
  inputRef.current.value = parseValueWithFix(valueConverted);
342
414
  } else {
@@ -345,11 +417,12 @@ const MoneyInput = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((inProps, referenc
345
417
  }
346
418
  }
347
419
  }, [disabled, readOnly, value, prefix, suffix]);
348
- useEffect(() => {
349
- const valueInput = inputRef.current.value;
350
- inputRef.current.value = getValueWithDecimal(valueInput);
351
- }, [decimalDigit]);
352
- /* End handler */
420
+
421
+ // useEffect(() => {
422
+ // const valueInput = inputRef.current.value;
423
+ // inputRef.current.value = getValueWithDecimal(valueInput);
424
+ // }, [decimalDigit]);
425
+ // /* End handler */
353
426
 
354
427
  useImperativeHandle(reference, () => {
355
428
  const currentRef = ref.current || {};
@@ -508,6 +581,8 @@ MoneyInput.propTypes = {
508
581
  /** [Props](https://core.diginet.com.vn/ui/?path=/docs/form-control-text-label) of label. */
509
582
  labelProps: PropTypes.object,
510
583
  /** [Props](https://core.diginet.com.vn/ui/?path=/story/form-control-text-helpertext) of helper text. */
511
- helperTextProps: PropTypes.object
584
+ helperTextProps: PropTypes.object,
585
+ /** If `true`, decimal digit is fixed. */
586
+ fixedDecimalDigit: PropTypes.bool
512
587
  };
513
588
  export default MoneyInput;
@@ -49,7 +49,7 @@ const NumberInput = /*#__PURE__*/forwardRef((inProps, reference) => {
49
49
  labelProps,
50
50
  max: maxProp,
51
51
  maxDigit,
52
- min,
52
+ min: minProp,
53
53
  nonStyle,
54
54
  onBlur,
55
55
  onChange,
@@ -69,9 +69,12 @@ const NumberInput = /*#__PURE__*/forwardRef((inProps, reference) => {
69
69
  viewType
70
70
  } = props;
71
71
  let max = maxProp;
72
+ let min = minProp;
72
73
  let thousandSymbol = thousandSeparator;
73
74
  let decimalSymbol = decimalSymbolProp;
74
75
  let valueProps = valueProp;
76
+ if (!min && min !== 0) min = -Infinity;
77
+ if (!max && max !== 0) max = Infinity;
75
78
  const pos = useRef(null);
76
79
  const ref = useRef(null);
77
80
  const globalRef = useRef({});
@@ -111,6 +114,18 @@ const NumberInput = /*#__PURE__*/forwardRef((inProps, reference) => {
111
114
  }
112
115
  } = inputRef;
113
116
  let number = convertMoneyToNumber(vl, isNumber);
117
+ if (fixedDecimalDigit && !!decimalDigit) {
118
+ var _strVal$split;
119
+ const strVal = String(vl);
120
+ const isDecimalNum = strVal.indexOf('.') > -1 && (((_strVal$split = strVal.split('.')) === null || _strVal$split === void 0 ? void 0 : _strVal$split[1]) || '').length >= decimalDigit;
121
+ if (isDecimalNum) {
122
+ const coreToFixed = (num, precision) => {
123
+ return (+(Math.round(+(num + 'e' + precision)) + 'e' + -precision)).toFixed(precision);
124
+ };
125
+ const val = coreToFixed(Number(String(vl).replaceAll(thousandSymbol, '')), decimalDigit);
126
+ number = String(val);
127
+ }
128
+ }
114
129
 
115
130
  // if (disabledNegative && Number(number || 0) < 0) number = clamp(number, min, max);
116
131
  // if (typeof max !== 'undefined' && Number(number) > max) number = Math.min(number, max);
@@ -134,15 +149,6 @@ const NumberInput = /*#__PURE__*/forwardRef((inProps, reference) => {
134
149
  if (((_number3 = number) === null || _number3 === void 0 ? void 0 : _number3.indexOf(thousandSymbol)) > -1 && selectionStart !== number.length + 1) {
135
150
  pos.current = selectionStart + (number.toString().length - 1 === vl.toString().length ? 1 : 0);
136
151
  }
137
- if (fixedDecimalDigit && !!decimalDigit) {
138
- var _strVal$split;
139
- const strVal = String(vl);
140
- const isDecimalNum = strVal.indexOf('.') > -1 && (((_strVal$split = strVal.split('.')) === null || _strVal$split === void 0 ? void 0 : _strVal$split[1]) || '').length >= decimalDigit;
141
- if (isDecimalNum) {
142
- const val = Number(vl).toFixed(decimalDigit);
143
- number = String(val);
144
- }
145
- }
146
152
  return number;
147
153
  }, [decimalSymbol, max, value, decimalDigit, fixedDecimalDigit]);
148
154
 
@@ -178,7 +184,7 @@ const NumberInput = /*#__PURE__*/forwardRef((inProps, reference) => {
178
184
  if (flag) _onChange(e);
179
185
  }, [min, max, decimalDigit]);
180
186
  const _onBlur = useCallback(e => {
181
- var _e$value;
187
+ var _e$value, _e$value2;
182
188
  let value = (_e$value = e.value) !== null && _e$value !== void 0 ? _e$value : e.target.value;
183
189
  if (fixedDecimalDigit) value = Number(value).toFixed(decimalDigit);
184
190
  value = convertMoneyToNumber(value);
@@ -190,6 +196,15 @@ const NumberInput = /*#__PURE__*/forwardRef((inProps, reference) => {
190
196
  target
191
197
  }, true);
192
198
  }
199
+ if (((_e$value2 = e.value) !== null && _e$value2 !== void 0 ? _e$value2 : e.target.value).slice(-1) === decimalSymbol) {
200
+ var _e$value3;
201
+ const target = e.target;
202
+ target.value = Number(String((_e$value3 = e.value) !== null && _e$value3 !== void 0 ? _e$value3 : e.target.value).replaceAll(thousandSymbol, ''));
203
+ _onInput({
204
+ ...e,
205
+ target
206
+ }, true);
207
+ }
193
208
  onBlur && onBlur(e);
194
209
  }, [min, max]);
195
210
  const _onKeyDown = e => {
@@ -280,6 +295,10 @@ const NumberInput = /*#__PURE__*/forwardRef((inProps, reference) => {
280
295
  const target = e.target;
281
296
  target.value = globalRef.current.valueString;
282
297
  target.valueString = globalRef.current.returnValue;
298
+ // eslint-disable-next-line no-extra-boolean-cast
299
+ if (String(e.target.valueString).slice(-1) === decimalSymbol) {
300
+ return;
301
+ }
283
302
  onChange({
284
303
  ...e,
285
304
  value: globalRef.current.value,
@@ -315,8 +334,7 @@ const NumberInput = /*#__PURE__*/forwardRef((inProps, reference) => {
315
334
  // nếu không cho nhập số âm mà value đầu vào là âm thì reset value về 0
316
335
  valueProps = clamp(0, min, max);
317
336
  }
318
-
319
- // setValue(parseNumberToMoney(valueProps?.toString().replace(regexValidNumber, ''), true));
337
+ // setValue(valueProps);
320
338
  setValue(parseNumberToMoney((_valueProps = valueProps) === null || _valueProps === void 0 ? void 0 : _valueProps.toString().replace(regexValidNumber, ''), true));
321
339
  }
322
340
  }, [valueProps, decimalDigit]);
@@ -384,29 +402,28 @@ const NumberInputRootCSS = ({
384
402
  ${cursorNotAllowed};
385
403
  }
386
404
  `;
387
-
388
- // NumberInput.defaultProps = {
389
- // autoFocus: false,
390
- // className: '',
391
- // decimalDigit: Infinity,
392
- // decimalSymbol: locale.get() === 'vi' ? ',' : '.',
393
- // disabled: false,
394
- // disabledNegative: false,
395
- // endIcon: '',
396
- // error: '',
397
- // fixedDecimalDigit: false,
398
- // label: '',
399
- // max: Infinity,
400
- // min: -Infinity,
401
- // readOnly: false,
402
- // required: false,
403
- // startIcon: '',
404
- // step: 1,
405
- // style: {},
406
- // thousandSeparator: false,
407
- // viewType: 'underlined',
408
- // };
409
-
405
+ NumberInput.defaultProps = {
406
+ // delayOnChange: 500,
407
+ // autoFocus: false,
408
+ // className: '',
409
+ // decimalDigit: Infinity,
410
+ // decimalSymbol: locale.get() === 'vi' ? ',' : '.',
411
+ // disabled: false,
412
+ // disabledNegative: false,
413
+ // endIcon: '',
414
+ // error: '',
415
+ // fixedDecimalDigit: false,
416
+ // label: '',
417
+ // max: Infinity,
418
+ // min: -Infinity,
419
+ // readOnly: false,
420
+ // required: false,
421
+ // startIcon: '',
422
+ // step: 1,
423
+ // style: {},
424
+ // thousandSeparator: false,
425
+ // viewType: 'underlined',
426
+ };
410
427
  NumberInput.propTypes = {
411
428
  /** If `true`, the input element is focused during the first mount. */
412
429
  autoFocus: PropTypes.bool,
@@ -8,7 +8,7 @@ import { cursorNotAllowed, displayBlock, positionRelative } from "../../../style
8
8
  import { useTheme } from "../../../theme";
9
9
  import useThemeProps from "../../../theme/utils/useThemeProps";
10
10
  import { classNames, onValidate, refType as ref } from "../../../utils";
11
- const PasswordInput = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((inProps, reference) => {
11
+ const PasswordInput = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((inProps, reference) => {
12
12
  if (!reference) reference = useRef(null);
13
13
  const theme = useTheme();
14
14
 
@@ -17,7 +17,7 @@ const ensigns = {
17
17
  mark: '____ _______'
18
18
  }
19
19
  };
20
- const PhoneInput = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
20
+ const PhoneInput = /*#__PURE__*/memo(/*#__PURE__*/forwardRef(({
21
21
  viewType,
22
22
  ensign,
23
23
  required,
@@ -8,7 +8,7 @@ import { boxBorder, cursorNoDrop, cursorPointer, displayBlock, displayNone, posi
8
8
  import { useTheme } from "../../../theme";
9
9
  import useThemeProps from "../../../theme/utils/useThemeProps";
10
10
  import { classNames, getProp, randomString } from "../../../utils";
11
- const Radio = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((inProps, reference) => {
11
+ const Radio = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((inProps, reference) => {
12
12
  if (!reference) reference = useRef(null);
13
13
  const theme = useTheme();
14
14
  const {