diginet-core-ui 1.4.53-beta.6 → 1.4.53-beta.8
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/components/form-control/date-input/useDateInputState.js +3 -5
- package/components/form-control/date-picker/index.js +27 -7
- package/components/form-control/dropdown/index.js +1 -0
- package/components/form-control/money-input/index.js +60 -2
- package/components/tree-view/index.js +12 -10
- package/locale/index.js +1 -1
- package/package.json +1 -1
- package/theme/settings.js +4 -3
- package/utils/getLang.js +69 -0
- package/utils/index.js +1 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { useEffect } from 'react';
|
|
2
|
-
import { addDays, addHours, addMinutes, addMonths, addSeconds, addYears,
|
|
3
|
-
import { enUS, vi } from 'date-fns/locale';
|
|
2
|
+
import { addDays, addHours, addMinutes, addMonths, addSeconds, addYears, isLastDayOfMonth, isValid, lastDayOfMonth } from 'date-fns';
|
|
4
3
|
import { getGlobal } from "../../../global";
|
|
5
4
|
import { capitalize } from "../../../utils";
|
|
6
5
|
import { patternMap, useDateField } from "./DateField";
|
|
7
6
|
import { lowerCaseDayYear } from "./utils";
|
|
7
|
+
import { parseDateString } from "../../../utils/getLang";
|
|
8
8
|
export const useDateInputState = ({
|
|
9
9
|
formatStr,
|
|
10
10
|
locale,
|
|
@@ -95,9 +95,7 @@ export const useDateInputState = ({
|
|
|
95
95
|
};
|
|
96
96
|
const toControlledDateString = () => {
|
|
97
97
|
if (date && isValid(date)) {
|
|
98
|
-
return
|
|
99
|
-
locale: locale === 'vi' ? vi : enUS
|
|
100
|
-
});
|
|
98
|
+
return parseDateString(date, lowerCaseDayYear(formatStr), locale);
|
|
101
99
|
}
|
|
102
100
|
// if date is not valid, return uncontrolled date string
|
|
103
101
|
return toDateString();
|
|
@@ -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 {
|
|
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
|
};
|
|
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
|
+
};
|
|
45
67
|
const DatePicker = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((inProps, reference) => {
|
|
46
|
-
var
|
|
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, reference
|
|
|
87
109
|
...other
|
|
88
110
|
} = props;
|
|
89
111
|
const dateLocale = locale.get();
|
|
90
|
-
const displayFormat = (
|
|
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, reference
|
|
|
112
134
|
};
|
|
113
135
|
const formatValue = (value, formatStr) => {
|
|
114
136
|
// return moment(value).format(format, utc = false);
|
|
115
|
-
return
|
|
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;
|
|
@@ -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') {
|
|
@@ -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,6 +73,61 @@ 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
|
};
|
|
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
|
+
};
|
|
75
131
|
const MoneyInput = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((inProps, reference) => {
|
|
76
132
|
if (!reference) reference = useRef(null);
|
|
77
133
|
|
|
@@ -126,7 +182,7 @@ const MoneyInput = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((inProps, reference
|
|
|
126
182
|
isPaste: false,
|
|
127
183
|
clipboardText: ''
|
|
128
184
|
});
|
|
129
|
-
const separatorSymbol = typeof thousandSeparator === 'string' ? thousandSeparator : locale.get()
|
|
185
|
+
const separatorSymbol = typeof thousandSeparator === 'string' ? thousandSeparator : getThousandSeparatorByCountry(locale.get());
|
|
130
186
|
const decimalSymbol = separatorSymbol === '.' ? ',' : '.';
|
|
131
187
|
const thousandSeparatorPattern = new RegExp(`[0-9]|Backspace|Delete|Arrow|Home|End|Tab${decimalDigit === 0 ? '' : '|\\' + decimalSymbol}${disabledNegative ? '' : '|-'}`);
|
|
132
188
|
const isError = !!error && !value && value !== 0;
|
|
@@ -350,7 +406,9 @@ const MoneyInput = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((inProps, reference
|
|
|
350
406
|
if (convertToWords && !decimalDigit && (disabled || readOnly)) {
|
|
351
407
|
let valueConverted = getGlobal('helperInvalid');
|
|
352
408
|
if (Number.isInteger(number)) {
|
|
353
|
-
|
|
409
|
+
const currentLocale = locale.get();
|
|
410
|
+
const converter = converters[currentLocale] || num2WordsVi; // fallback VN
|
|
411
|
+
valueConverted = converter.convert(number);
|
|
354
412
|
}
|
|
355
413
|
inputRef.current.value = parseValueWithFix(valueConverted);
|
|
356
414
|
} else {
|
|
@@ -239,8 +239,10 @@ const TreeView = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((inProps, reference)
|
|
|
239
239
|
// // Trường hợp phải set về false để xét các input đã check không bao gồm node này
|
|
240
240
|
checkbox.firstChild.checked = isChecked;
|
|
241
241
|
determinateCheckbox(checkbox.firstChild, !mustDisabled);
|
|
242
|
-
|
|
243
|
-
|
|
242
|
+
setTimeout(() => {
|
|
243
|
+
// Nếu có ít nhất một input con được check thì phải checked cho input này
|
|
244
|
+
checkbox.firstChild.checked = mustDisabled;
|
|
245
|
+
}, 200);
|
|
244
246
|
node.classList[mustDisabled || isChecked ? 'add' : 'remove']('disabled');
|
|
245
247
|
checkbox.classList[mustDisabled || isChecked ? 'add' : 'remove']('disabled');
|
|
246
248
|
Array.from(node.childNodes).forEach(e => {
|
|
@@ -691,16 +693,16 @@ const TreeView = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((inProps, reference)
|
|
|
691
693
|
}
|
|
692
694
|
};
|
|
693
695
|
} else if (disabledRelevantValue) {
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
if (
|
|
697
|
-
|
|
696
|
+
setTimeout(() => {
|
|
697
|
+
Array.from(ref.current.querySelectorAll('.TreeView-Item.non-child, .DGN-UI-Accordion')).forEach(el => {
|
|
698
|
+
if (el.firstChild.querySelector('input').checked) {
|
|
699
|
+
if (!el.classList.contains('non-child')) {
|
|
698
700
|
handleDisabledChildren(el, true);
|
|
699
|
-
}
|
|
701
|
+
}
|
|
702
|
+
handleDisabledParent(el.parentNode, true);
|
|
700
703
|
}
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
});
|
|
704
|
+
});
|
|
705
|
+
}, 200);
|
|
704
706
|
}
|
|
705
707
|
}
|
|
706
708
|
}, []);
|
package/locale/index.js
CHANGED
package/package.json
CHANGED
package/theme/settings.js
CHANGED
|
@@ -3,6 +3,7 @@ import { font } from "../styles/font";
|
|
|
3
3
|
import { typography as typographies } from "../styles/typography";
|
|
4
4
|
import createTheme from "./createTheme";
|
|
5
5
|
import locale from "../locale";
|
|
6
|
+
import { getFormatDateByCountry, getDecimalSymbolByCountry } from "../utils/getLang";
|
|
6
7
|
// import { getGlobal } from 'global';
|
|
7
8
|
const {
|
|
8
9
|
fontSize,
|
|
@@ -345,7 +346,7 @@ const settings = {
|
|
|
345
346
|
className: '',
|
|
346
347
|
disabled: false,
|
|
347
348
|
error: '',
|
|
348
|
-
format: locale.get()
|
|
349
|
+
format: getFormatDateByCountry(locale.get()),
|
|
349
350
|
label: '',
|
|
350
351
|
readOnly: false,
|
|
351
352
|
required: false,
|
|
@@ -360,7 +361,7 @@ const settings = {
|
|
|
360
361
|
controls: false,
|
|
361
362
|
disabled: false,
|
|
362
363
|
displayAnotherMonth: true,
|
|
363
|
-
displayFormat: locale.get()
|
|
364
|
+
displayFormat: getFormatDateByCountry(locale.get()),
|
|
364
365
|
pressESCToClose: true,
|
|
365
366
|
readOnly: false,
|
|
366
367
|
required: false,
|
|
@@ -596,7 +597,7 @@ const settings = {
|
|
|
596
597
|
autoFocus: false,
|
|
597
598
|
className: '',
|
|
598
599
|
decimalDigit: Infinity,
|
|
599
|
-
decimalSymbol: locale.get()
|
|
600
|
+
decimalSymbol: getDecimalSymbolByCountry(locale.get()),
|
|
600
601
|
disabled: false,
|
|
601
602
|
disabledNegative: false,
|
|
602
603
|
endIcon: '',
|
package/utils/getLang.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { format } from 'date-fns';
|
|
2
|
+
import { lowerCaseDayYear } from "../components/form-control/date-input/utils";
|
|
3
|
+
import { enUS, zhCN, vi, ja } from 'date-fns/locale';
|
|
4
|
+
const getFormatDateByCountry = (lang, isDateFns = false) => {
|
|
5
|
+
let result = '';
|
|
6
|
+
switch (lang) {
|
|
7
|
+
case 'en':
|
|
8
|
+
result = isDateFns ? enUS : 'MM/DD/YYYY';
|
|
9
|
+
break;
|
|
10
|
+
case 'zh':
|
|
11
|
+
result = isDateFns ? zhCN : 'YYYY/MM/DD';
|
|
12
|
+
break;
|
|
13
|
+
case 'ja':
|
|
14
|
+
result = isDateFns ? ja : 'YYYY/MM/DD';
|
|
15
|
+
break;
|
|
16
|
+
case 'vi':
|
|
17
|
+
result = isDateFns ? vi : 'DD/MM/YYYY';
|
|
18
|
+
break;
|
|
19
|
+
default:
|
|
20
|
+
result = 'DD/MM/YYYY';
|
|
21
|
+
break;
|
|
22
|
+
}
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
const parseDateString = (date, formatStr, locale) => {
|
|
26
|
+
return format(date, lowerCaseDayYear(formatStr), {
|
|
27
|
+
locale: getFormatDateByCountry(locale, true)
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
const getDecimalSymbolByCountry = lang => {
|
|
31
|
+
let result = '';
|
|
32
|
+
switch (lang) {
|
|
33
|
+
case 'vi': // Việt Nam
|
|
34
|
+
case 'de': // Đức
|
|
35
|
+
case 'fr': // Pháp
|
|
36
|
+
case 'it': // Ý
|
|
37
|
+
case 'es': // Tây Ban Nha
|
|
38
|
+
case 'ru':
|
|
39
|
+
// Nga
|
|
40
|
+
result = ','; // Dấu phẩy làm thập phân
|
|
41
|
+
break;
|
|
42
|
+
case 'en': // Anh, Mỹ
|
|
43
|
+
case 'zh': // Trung Quốc
|
|
44
|
+
case 'ja': // Nhật Bản
|
|
45
|
+
default:
|
|
46
|
+
result = '.'; // Dấu chấm làm thập phân
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
return result;
|
|
50
|
+
};
|
|
51
|
+
const getThousandSeparatorByCountry = lang => {
|
|
52
|
+
switch (lang) {
|
|
53
|
+
case 'vi': // Việt Nam
|
|
54
|
+
case 'de': // Đức
|
|
55
|
+
case 'es':
|
|
56
|
+
// Tây Ban Nha
|
|
57
|
+
return '.';
|
|
58
|
+
case 'fr':
|
|
59
|
+
// Pháp
|
|
60
|
+
return '\u00A0';
|
|
61
|
+
// space không ngắt
|
|
62
|
+
case 'en': // Anh, Mỹ
|
|
63
|
+
case 'zh': // Trung Quốc
|
|
64
|
+
case 'ja': // Nhật
|
|
65
|
+
default:
|
|
66
|
+
return ',';
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
export { getFormatDateByCountry, parseDateString, getDecimalSymbolByCountry, getThousandSeparatorByCountry };
|