@wonjin-dev/reacts 1.3.2 → 1.4.1
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/components/index.esm.js +13 -64
- package/dist/components/index.esm.js.map +1 -1
- package/dist/components/index.js +13 -64
- package/dist/components/index.js.map +1 -1
- package/dist/components/utils/formatCareerPeriod/index.d.ts +42 -0
- package/dist/components/utils/formatCareerPeriod/index.test.d.ts +1 -0
- package/dist/components/utils/index.d.ts +1 -0
- package/dist/hooks/index.esm.js +37 -117
- package/dist/hooks/index.esm.js.map +1 -1
- package/dist/hooks/index.js +37 -117
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/utils/formatCareerPeriod/index.d.ts +42 -0
- package/dist/hooks/utils/formatCareerPeriod/index.test.d.ts +1 -0
- package/dist/hooks/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts +43 -1
- package/dist/utils/index.esm.js +74 -8
- package/dist/utils/index.esm.js.map +1 -1
- package/dist/utils/index.js +74 -7
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/utils/formatCareerPeriod/index.d.ts +42 -0
- package/dist/utils/utils/formatCareerPeriod/index.test.d.ts +1 -0
- package/dist/utils/utils/index.d.ts +1 -0
- package/package.json +1 -1
package/dist/utils/index.esm.js
CHANGED
|
@@ -1,15 +1,81 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
4
|
-
args[_i] = arguments[_i];
|
|
5
|
-
}
|
|
6
|
-
return args.reduce(function (acc, className) {
|
|
1
|
+
const classNames = (...args) => {
|
|
2
|
+
return args.reduce((acc, className) => {
|
|
7
3
|
if (className) {
|
|
8
|
-
return acc ?
|
|
4
|
+
return acc ? `${acc} ${className}` : className;
|
|
9
5
|
}
|
|
10
6
|
return acc;
|
|
11
7
|
}, '');
|
|
12
8
|
};
|
|
13
9
|
|
|
14
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Formats the career duration between two dates into a readable string.
|
|
12
|
+
* It handles internationalization (Korean/English) and the "Present" status for ongoing roles.
|
|
13
|
+
*
|
|
14
|
+
* @param props - The configuration object.
|
|
15
|
+
* @param props.startAt - The start date of the period.
|
|
16
|
+
* @param props.endAt - The end date. If undefined, it defaults to the current date (calculates duration up to now) and displays "Present" or "현재".
|
|
17
|
+
* @param props.showDuration - Whether to append the calculated duration (e.g., "(2y 6m)"). Defaults to true.
|
|
18
|
+
* @param props.lng - Language code ('ko' | 'en'). Defaults to 'ko'.
|
|
19
|
+
* @returns A formatted string: "YYYY.MM ~ YYYY.MM (Duration)" or "YYYY.MM ~ Present (Duration)".
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* // 1. Ongoing role (Korean default)
|
|
23
|
+
* // Current date: 2024-02
|
|
24
|
+
* formatCareerPeriod({ startAt: new Date('2023-01-01') });
|
|
25
|
+
* // Output: "2023.01 ~ 현재 (1년 2개월)"
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* // 2. Completed role with duration (English)
|
|
29
|
+
* formatCareerPeriod({
|
|
30
|
+
* startAt: new Date('2020-01-01'),
|
|
31
|
+
* endAt: new Date('2022-06-01'),
|
|
32
|
+
* lng: 'en'
|
|
33
|
+
* });
|
|
34
|
+
* // Output: "2020.01 ~ 2022.06 (2y 6m)"
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* // 3. Hide duration
|
|
38
|
+
* formatCareerPeriod({
|
|
39
|
+
* startAt: new Date('2020-01-01'),
|
|
40
|
+
* endAt: new Date('2020-05-01'),
|
|
41
|
+
* showDuration: false
|
|
42
|
+
* });
|
|
43
|
+
* // Output: "2020.01 ~ 2020.05"
|
|
44
|
+
*/
|
|
45
|
+
const formatCareerPeriod = ({ startAt, endAt, showDuration = true, lng = 'ko', }) => {
|
|
46
|
+
const lang = lng === 'en' ? 'en' : 'ko';
|
|
47
|
+
const LABELS = {
|
|
48
|
+
current: { ko: '현재', en: 'Present' },
|
|
49
|
+
year: { ko: '년', en: 'y' },
|
|
50
|
+
month: { ko: '개월', en: 'm' },
|
|
51
|
+
};
|
|
52
|
+
const formatYearMonth = (d) => {
|
|
53
|
+
const year = d.getFullYear();
|
|
54
|
+
const month = String(d.getMonth() + 1).padStart(2, '0');
|
|
55
|
+
return `${year}.${month}`;
|
|
56
|
+
};
|
|
57
|
+
const endDate = endAt || new Date();
|
|
58
|
+
const startText = formatYearMonth(startAt);
|
|
59
|
+
const endText = endAt ? formatYearMonth(endAt) : LABELS.current[lang];
|
|
60
|
+
if (!showDuration) {
|
|
61
|
+
return `${startText} ~ ${endText}`;
|
|
62
|
+
}
|
|
63
|
+
const totalMonths = (endDate.getFullYear() - startAt.getFullYear()) * 12 +
|
|
64
|
+
(endDate.getMonth() - startAt.getMonth()) +
|
|
65
|
+
1;
|
|
66
|
+
if (totalMonths < 1) {
|
|
67
|
+
return `${startText} ~ ${endText}`;
|
|
68
|
+
}
|
|
69
|
+
const years = Math.floor(totalMonths / 12);
|
|
70
|
+
const months = totalMonths % 12;
|
|
71
|
+
const durationParts = [
|
|
72
|
+
years > 0 ? `${years}${LABELS.year[lang]}` : null,
|
|
73
|
+
months > 0 ? `${months}${LABELS.month[lang]}` : null,
|
|
74
|
+
].filter(Boolean);
|
|
75
|
+
const durationString = durationParts.join(' ');
|
|
76
|
+
const durationSuffix = durationString ? ` (${durationString})` : '';
|
|
77
|
+
return `${startText} ~ ${endText}${durationSuffix}`;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export { classNames, formatCareerPeriod };
|
|
15
81
|
//# sourceMappingURL=index.esm.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.js","sources":["../../src/utils/classNames/index.ts"],"sourcesContent":["const classNames = (...args: (string | undefined)[]) => {\n\treturn args.reduce((acc, className) => {\n\t\tif (className) {\n\t\t\treturn acc ? `${acc} ${className}` : className;\n\t\t}\n\t\treturn acc;\n\t}, '');\n};\n\nexport default classNames;\n"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../../src/utils/classNames/index.ts","../../src/utils/formatCareerPeriod/index.ts"],"sourcesContent":["const classNames = (...args: (string | undefined)[]) => {\n\treturn args.reduce((acc, className) => {\n\t\tif (className) {\n\t\t\treturn acc ? `${acc} ${className}` : className;\n\t\t}\n\t\treturn acc;\n\t}, '');\n};\n\nexport default classNames;\n","type SupportedLang = 'ko' | 'en';\n\n/**\n * Formats the career duration between two dates into a readable string.\n * It handles internationalization (Korean/English) and the \"Present\" status for ongoing roles.\n *\n * @param props - The configuration object.\n * @param props.startAt - The start date of the period.\n * @param props.endAt - The end date. If undefined, it defaults to the current date (calculates duration up to now) and displays \"Present\" or \"현재\".\n * @param props.showDuration - Whether to append the calculated duration (e.g., \"(2y 6m)\"). Defaults to true.\n * @param props.lng - Language code ('ko' | 'en'). Defaults to 'ko'.\n * @returns A formatted string: \"YYYY.MM ~ YYYY.MM (Duration)\" or \"YYYY.MM ~ Present (Duration)\".\n *\n * @example\n * // 1. Ongoing role (Korean default)\n * // Current date: 2024-02\n * formatCareerPeriod({ startAt: new Date('2023-01-01') });\n * // Output: \"2023.01 ~ 현재 (1년 2개월)\"\n *\n * @example\n * // 2. Completed role with duration (English)\n * formatCareerPeriod({\n * startAt: new Date('2020-01-01'),\n * endAt: new Date('2022-06-01'),\n * lng: 'en'\n * });\n * // Output: \"2020.01 ~ 2022.06 (2y 6m)\"\n *\n * @example\n * // 3. Hide duration\n * formatCareerPeriod({\n * startAt: new Date('2020-01-01'),\n * endAt: new Date('2020-05-01'),\n * showDuration: false\n * });\n * // Output: \"2020.01 ~ 2020.05\"\n */\nconst formatCareerPeriod = ({\n\tstartAt,\n\tendAt,\n\tshowDuration = true,\n\tlng = 'ko',\n}: {\n\tstartAt: Date;\n\tendAt?: Date;\n\tshowDuration?: boolean;\n\tlng?: string;\n}): string => {\n\tconst lang: SupportedLang = lng === 'en' ? 'en' : 'ko';\n\n\tconst LABELS = {\n\t\tcurrent: { ko: '현재', en: 'Present' },\n\t\tyear: { ko: '년', en: 'y' },\n\t\tmonth: { ko: '개월', en: 'm' },\n\t} as const;\n\n\tconst formatYearMonth = (d: Date) => {\n\t\tconst year = d.getFullYear();\n\t\tconst month = String(d.getMonth() + 1).padStart(2, '0');\n\t\treturn `${year}.${month}`;\n\t};\n\n\tconst endDate = endAt || new Date();\n\n\tconst startText = formatYearMonth(startAt);\n\tconst endText = endAt ? formatYearMonth(endAt) : LABELS.current[lang];\n\n\tif (!showDuration) {\n\t\treturn `${startText} ~ ${endText}`;\n\t}\n\n\tconst totalMonths =\n\t\t(endDate.getFullYear() - startAt.getFullYear()) * 12 +\n\t\t(endDate.getMonth() - startAt.getMonth()) +\n\t\t1;\n\n\tif (totalMonths < 1) {\n\t\treturn `${startText} ~ ${endText}`;\n\t}\n\n\tconst years = Math.floor(totalMonths / 12);\n\tconst months = totalMonths % 12;\n\n\tconst durationParts = [\n\t\tyears > 0 ? `${years}${LABELS.year[lang]}` : null,\n\t\tmonths > 0 ? `${months}${LABELS.month[lang]}` : null,\n\t].filter(Boolean);\n\n\tconst durationString = durationParts.join(' ');\n\tconst durationSuffix = durationString ? ` (${durationString})` : '';\n\n\treturn `${startText} ~ ${endText}${durationSuffix}`;\n};\n\nexport default formatCareerPeriod;\n"],"names":[],"mappings":"AAAA,MAAM,UAAU,GAAG,CAAC,GAAG,IAA4B,KAAI;IACtD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,SAAS,KAAI;QACrC,IAAI,SAAS,EAAE;AACd,YAAA,OAAO,GAAG,GAAG,CAAG,EAAA,GAAG,CAAI,CAAA,EAAA,SAAS,CAAE,CAAA,GAAG,SAAS,CAAC;SAC/C;AACD,QAAA,OAAO,GAAG,CAAC;KACX,EAAE,EAAE,CAAC,CAAC;AACR;;ACLA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCG;AACH,MAAM,kBAAkB,GAAG,CAAC,EAC3B,OAAO,EACP,KAAK,EACL,YAAY,GAAG,IAAI,EACnB,GAAG,GAAG,IAAI,GAMV,KAAY;AACZ,IAAA,MAAM,IAAI,GAAkB,GAAG,KAAK,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEvD,IAAA,MAAM,MAAM,GAAG;QACd,OAAO,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE;QACpC,IAAI,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE;QAC1B,KAAK,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE;KACnB,CAAC;AAEX,IAAA,MAAM,eAAe,GAAG,CAAC,CAAO,KAAI;AACnC,QAAA,MAAM,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;AAC7B,QAAA,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACxD,QAAA,OAAO,CAAG,EAAA,IAAI,CAAI,CAAA,EAAA,KAAK,EAAE,CAAC;AAC3B,KAAC,CAAC;AAEF,IAAA,MAAM,OAAO,GAAG,KAAK,IAAI,IAAI,IAAI,EAAE,CAAC;AAEpC,IAAA,MAAM,SAAS,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;AAC3C,IAAA,MAAM,OAAO,GAAG,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtE,IAAI,CAAC,YAAY,EAAE;AAClB,QAAA,OAAO,CAAG,EAAA,SAAS,CAAM,GAAA,EAAA,OAAO,EAAE,CAAC;KACnC;AAED,IAAA,MAAM,WAAW,GAChB,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG,OAAO,CAAC,WAAW,EAAE,IAAI,EAAE;SACnD,OAAO,CAAC,QAAQ,EAAE,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;AACzC,QAAA,CAAC,CAAC;AAEH,IAAA,IAAI,WAAW,GAAG,CAAC,EAAE;AACpB,QAAA,OAAO,CAAG,EAAA,SAAS,CAAM,GAAA,EAAA,OAAO,EAAE,CAAC;KACnC;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC;AAC3C,IAAA,MAAM,MAAM,GAAG,WAAW,GAAG,EAAE,CAAC;AAEhC,IAAA,MAAM,aAAa,GAAG;AACrB,QAAA,KAAK,GAAG,CAAC,GAAG,CAAA,EAAG,KAAK,CAAG,EAAA,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI;AACjD,QAAA,MAAM,GAAG,CAAC,GAAG,CAAA,EAAG,MAAM,CAAG,EAAA,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI;AACpD,KAAA,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAElB,MAAM,cAAc,GAAG,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,IAAA,MAAM,cAAc,GAAG,cAAc,GAAG,CAAK,EAAA,EAAA,cAAc,CAAG,CAAA,CAAA,GAAG,EAAE,CAAC;AAEpE,IAAA,OAAO,GAAG,SAAS,CAAA,GAAA,EAAM,OAAO,CAAG,EAAA,cAAc,EAAE,CAAC;AACrD;;;;"}
|
package/dist/utils/index.js
CHANGED
|
@@ -1,17 +1,84 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
6
|
-
args[_i] = arguments[_i];
|
|
7
|
-
}
|
|
8
|
-
return args.reduce(function (acc, className) {
|
|
3
|
+
const classNames = (...args) => {
|
|
4
|
+
return args.reduce((acc, className) => {
|
|
9
5
|
if (className) {
|
|
10
|
-
return acc ?
|
|
6
|
+
return acc ? `${acc} ${className}` : className;
|
|
11
7
|
}
|
|
12
8
|
return acc;
|
|
13
9
|
}, '');
|
|
14
10
|
};
|
|
15
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Formats the career duration between two dates into a readable string.
|
|
14
|
+
* It handles internationalization (Korean/English) and the "Present" status for ongoing roles.
|
|
15
|
+
*
|
|
16
|
+
* @param props - The configuration object.
|
|
17
|
+
* @param props.startAt - The start date of the period.
|
|
18
|
+
* @param props.endAt - The end date. If undefined, it defaults to the current date (calculates duration up to now) and displays "Present" or "현재".
|
|
19
|
+
* @param props.showDuration - Whether to append the calculated duration (e.g., "(2y 6m)"). Defaults to true.
|
|
20
|
+
* @param props.lng - Language code ('ko' | 'en'). Defaults to 'ko'.
|
|
21
|
+
* @returns A formatted string: "YYYY.MM ~ YYYY.MM (Duration)" or "YYYY.MM ~ Present (Duration)".
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* // 1. Ongoing role (Korean default)
|
|
25
|
+
* // Current date: 2024-02
|
|
26
|
+
* formatCareerPeriod({ startAt: new Date('2023-01-01') });
|
|
27
|
+
* // Output: "2023.01 ~ 현재 (1년 2개월)"
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* // 2. Completed role with duration (English)
|
|
31
|
+
* formatCareerPeriod({
|
|
32
|
+
* startAt: new Date('2020-01-01'),
|
|
33
|
+
* endAt: new Date('2022-06-01'),
|
|
34
|
+
* lng: 'en'
|
|
35
|
+
* });
|
|
36
|
+
* // Output: "2020.01 ~ 2022.06 (2y 6m)"
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* // 3. Hide duration
|
|
40
|
+
* formatCareerPeriod({
|
|
41
|
+
* startAt: new Date('2020-01-01'),
|
|
42
|
+
* endAt: new Date('2020-05-01'),
|
|
43
|
+
* showDuration: false
|
|
44
|
+
* });
|
|
45
|
+
* // Output: "2020.01 ~ 2020.05"
|
|
46
|
+
*/
|
|
47
|
+
const formatCareerPeriod = ({ startAt, endAt, showDuration = true, lng = 'ko', }) => {
|
|
48
|
+
const lang = lng === 'en' ? 'en' : 'ko';
|
|
49
|
+
const LABELS = {
|
|
50
|
+
current: { ko: '현재', en: 'Present' },
|
|
51
|
+
year: { ko: '년', en: 'y' },
|
|
52
|
+
month: { ko: '개월', en: 'm' },
|
|
53
|
+
};
|
|
54
|
+
const formatYearMonth = (d) => {
|
|
55
|
+
const year = d.getFullYear();
|
|
56
|
+
const month = String(d.getMonth() + 1).padStart(2, '0');
|
|
57
|
+
return `${year}.${month}`;
|
|
58
|
+
};
|
|
59
|
+
const endDate = endAt || new Date();
|
|
60
|
+
const startText = formatYearMonth(startAt);
|
|
61
|
+
const endText = endAt ? formatYearMonth(endAt) : LABELS.current[lang];
|
|
62
|
+
if (!showDuration) {
|
|
63
|
+
return `${startText} ~ ${endText}`;
|
|
64
|
+
}
|
|
65
|
+
const totalMonths = (endDate.getFullYear() - startAt.getFullYear()) * 12 +
|
|
66
|
+
(endDate.getMonth() - startAt.getMonth()) +
|
|
67
|
+
1;
|
|
68
|
+
if (totalMonths < 1) {
|
|
69
|
+
return `${startText} ~ ${endText}`;
|
|
70
|
+
}
|
|
71
|
+
const years = Math.floor(totalMonths / 12);
|
|
72
|
+
const months = totalMonths % 12;
|
|
73
|
+
const durationParts = [
|
|
74
|
+
years > 0 ? `${years}${LABELS.year[lang]}` : null,
|
|
75
|
+
months > 0 ? `${months}${LABELS.month[lang]}` : null,
|
|
76
|
+
].filter(Boolean);
|
|
77
|
+
const durationString = durationParts.join(' ');
|
|
78
|
+
const durationSuffix = durationString ? ` (${durationString})` : '';
|
|
79
|
+
return `${startText} ~ ${endText}${durationSuffix}`;
|
|
80
|
+
};
|
|
81
|
+
|
|
16
82
|
exports.classNames = classNames;
|
|
83
|
+
exports.formatCareerPeriod = formatCareerPeriod;
|
|
17
84
|
//# sourceMappingURL=index.js.map
|
package/dist/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/utils/classNames/index.ts"],"sourcesContent":["const classNames = (...args: (string | undefined)[]) => {\n\treturn args.reduce((acc, className) => {\n\t\tif (className) {\n\t\t\treturn acc ? `${acc} ${className}` : className;\n\t\t}\n\t\treturn acc;\n\t}, '');\n};\n\nexport default classNames;\n"],"names":[],"mappings":";;AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/utils/classNames/index.ts","../../src/utils/formatCareerPeriod/index.ts"],"sourcesContent":["const classNames = (...args: (string | undefined)[]) => {\n\treturn args.reduce((acc, className) => {\n\t\tif (className) {\n\t\t\treturn acc ? `${acc} ${className}` : className;\n\t\t}\n\t\treturn acc;\n\t}, '');\n};\n\nexport default classNames;\n","type SupportedLang = 'ko' | 'en';\n\n/**\n * Formats the career duration between two dates into a readable string.\n * It handles internationalization (Korean/English) and the \"Present\" status for ongoing roles.\n *\n * @param props - The configuration object.\n * @param props.startAt - The start date of the period.\n * @param props.endAt - The end date. If undefined, it defaults to the current date (calculates duration up to now) and displays \"Present\" or \"현재\".\n * @param props.showDuration - Whether to append the calculated duration (e.g., \"(2y 6m)\"). Defaults to true.\n * @param props.lng - Language code ('ko' | 'en'). Defaults to 'ko'.\n * @returns A formatted string: \"YYYY.MM ~ YYYY.MM (Duration)\" or \"YYYY.MM ~ Present (Duration)\".\n *\n * @example\n * // 1. Ongoing role (Korean default)\n * // Current date: 2024-02\n * formatCareerPeriod({ startAt: new Date('2023-01-01') });\n * // Output: \"2023.01 ~ 현재 (1년 2개월)\"\n *\n * @example\n * // 2. Completed role with duration (English)\n * formatCareerPeriod({\n * startAt: new Date('2020-01-01'),\n * endAt: new Date('2022-06-01'),\n * lng: 'en'\n * });\n * // Output: \"2020.01 ~ 2022.06 (2y 6m)\"\n *\n * @example\n * // 3. Hide duration\n * formatCareerPeriod({\n * startAt: new Date('2020-01-01'),\n * endAt: new Date('2020-05-01'),\n * showDuration: false\n * });\n * // Output: \"2020.01 ~ 2020.05\"\n */\nconst formatCareerPeriod = ({\n\tstartAt,\n\tendAt,\n\tshowDuration = true,\n\tlng = 'ko',\n}: {\n\tstartAt: Date;\n\tendAt?: Date;\n\tshowDuration?: boolean;\n\tlng?: string;\n}): string => {\n\tconst lang: SupportedLang = lng === 'en' ? 'en' : 'ko';\n\n\tconst LABELS = {\n\t\tcurrent: { ko: '현재', en: 'Present' },\n\t\tyear: { ko: '년', en: 'y' },\n\t\tmonth: { ko: '개월', en: 'm' },\n\t} as const;\n\n\tconst formatYearMonth = (d: Date) => {\n\t\tconst year = d.getFullYear();\n\t\tconst month = String(d.getMonth() + 1).padStart(2, '0');\n\t\treturn `${year}.${month}`;\n\t};\n\n\tconst endDate = endAt || new Date();\n\n\tconst startText = formatYearMonth(startAt);\n\tconst endText = endAt ? formatYearMonth(endAt) : LABELS.current[lang];\n\n\tif (!showDuration) {\n\t\treturn `${startText} ~ ${endText}`;\n\t}\n\n\tconst totalMonths =\n\t\t(endDate.getFullYear() - startAt.getFullYear()) * 12 +\n\t\t(endDate.getMonth() - startAt.getMonth()) +\n\t\t1;\n\n\tif (totalMonths < 1) {\n\t\treturn `${startText} ~ ${endText}`;\n\t}\n\n\tconst years = Math.floor(totalMonths / 12);\n\tconst months = totalMonths % 12;\n\n\tconst durationParts = [\n\t\tyears > 0 ? `${years}${LABELS.year[lang]}` : null,\n\t\tmonths > 0 ? `${months}${LABELS.month[lang]}` : null,\n\t].filter(Boolean);\n\n\tconst durationString = durationParts.join(' ');\n\tconst durationSuffix = durationString ? ` (${durationString})` : '';\n\n\treturn `${startText} ~ ${endText}${durationSuffix}`;\n};\n\nexport default formatCareerPeriod;\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Formats the career duration between two dates into a readable string.
|
|
3
|
+
* It handles internationalization (Korean/English) and the "Present" status for ongoing roles.
|
|
4
|
+
*
|
|
5
|
+
* @param props - The configuration object.
|
|
6
|
+
* @param props.startAt - The start date of the period.
|
|
7
|
+
* @param props.endAt - The end date. If undefined, it defaults to the current date (calculates duration up to now) and displays "Present" or "현재".
|
|
8
|
+
* @param props.showDuration - Whether to append the calculated duration (e.g., "(2y 6m)"). Defaults to true.
|
|
9
|
+
* @param props.lng - Language code ('ko' | 'en'). Defaults to 'ko'.
|
|
10
|
+
* @returns A formatted string: "YYYY.MM ~ YYYY.MM (Duration)" or "YYYY.MM ~ Present (Duration)".
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* // 1. Ongoing role (Korean default)
|
|
14
|
+
* // Current date: 2024-02
|
|
15
|
+
* formatCareerPeriod({ startAt: new Date('2023-01-01') });
|
|
16
|
+
* // Output: "2023.01 ~ 현재 (1년 2개월)"
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* // 2. Completed role with duration (English)
|
|
20
|
+
* formatCareerPeriod({
|
|
21
|
+
* startAt: new Date('2020-01-01'),
|
|
22
|
+
* endAt: new Date('2022-06-01'),
|
|
23
|
+
* lng: 'en'
|
|
24
|
+
* });
|
|
25
|
+
* // Output: "2020.01 ~ 2022.06 (2y 6m)"
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* // 3. Hide duration
|
|
29
|
+
* formatCareerPeriod({
|
|
30
|
+
* startAt: new Date('2020-01-01'),
|
|
31
|
+
* endAt: new Date('2020-05-01'),
|
|
32
|
+
* showDuration: false
|
|
33
|
+
* });
|
|
34
|
+
* // Output: "2020.01 ~ 2020.05"
|
|
35
|
+
*/
|
|
36
|
+
declare const formatCareerPeriod: ({ startAt, endAt, showDuration, lng, }: {
|
|
37
|
+
startAt: Date;
|
|
38
|
+
endAt?: Date | undefined;
|
|
39
|
+
showDuration?: boolean | undefined;
|
|
40
|
+
lng?: string | undefined;
|
|
41
|
+
}) => string;
|
|
42
|
+
export default formatCareerPeriod;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|