diff --git a/README.md b/README.md index 9191d87ba..de9d00d77 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# gantt-task-react +# gantt-task-react (한국식 날짜 표기 적용) ## Interactive Gantt Chart for React with TypeScript. @@ -9,7 +9,15 @@ ## Install ``` -npm install gantt-task-react +npm install gantt-task-react-korea +yarn add gantt-task-react-korea +``` + +## Updates + +``` +locale값에 kor을 사용하면 한국식 날짜 표기를 사용합니다. +Today에 Jira 스타일 노란색 화살표를 추가했습니다! ``` ## How to use it @@ -84,13 +92,13 @@ npm start ### DisplayOption -| Parameter Name | Type | Description | -| :------------- | :------ | :---------------------------------------------------------------------------------------------------------- | +| Parameter Name | Type | Description | +| :------------- | :------ | :----------------------------------------------------------------------------------------------------------------------- | | viewMode | enum | Specifies the time scale. Hour, Quarter Day, Half Day, Day, Week(ISO-8601, 1st day is Monday), Month, QuarterYear, Year. | -| viewDate | date | Specifies display date and time for display. | -| preStepsCount | number | Specifies empty space before the fist task | -| locale | string | Specifies the month name language. Able formats: ISO 639-2, Java Locale. | -| rtl | boolean | Sets rtl mode. | +| viewDate | date | Specifies display date and time for display. | +| preStepsCount | number | Specifies empty space before the fist task | +| locale | string | Specifies the month name language. Able formats: ISO 639-2, Java Locale. | +| rtl | boolean | Sets rtl mode. | ### StylingOption diff --git a/package-lock.json b/package-lock.json index aeca7dc81..cf1059504 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "gantt-task-react", - "version": "0.3.8", + "version": "0.0.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "gantt-task-react", - "version": "0.3.8", + "version": "0.0.2", "license": "MIT", "devDependencies": { "@testing-library/jest-dom": "^5.16.4", diff --git a/package.json b/package.json index a0097baa7..701c25640 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { - "name": "gantt-task-react", - "version": "0.3.9", - "description": "Interactive Gantt Chart for React with TypeScript.", + "name": "gantt-task-react-korea", + "version": "0.0.2", + "description": "This is a package that clones MaTeMaTuK/gantt-task-react to support the korean format.", "author": "MaTeMaTuK ", - "homepage": "https://github.com/MaTeMaTuK/gantt-task-react", + "homepage": "https://github.com/ohshinyeop/gantt-task-react-korea", "license": "MIT", - "repository": "MaTeMaTuK/gantt-task-react", + "repository": "ohshinyeop/gantt-task-react-korea", "main": "dist/index.js", "module": "dist/index.modern.js", "source": "src/index.tsx", diff --git a/src/components/calendar/calendar.tsx b/src/components/calendar/calendar.tsx index a5860db52..e36d3ee9e 100644 --- a/src/components/calendar/calendar.tsx +++ b/src/components/calendar/calendar.tsx @@ -6,7 +6,7 @@ import { getDaysInMonth, getLocalDayOfWeek, getLocaleMonth, - getWeekNumberISO8601, + getWeekOfMonth, } from "../../helpers/date-helper"; import { DateSetup } from "../../types/date-setup"; import styles from "./calendar.module.css"; @@ -40,14 +40,24 @@ export const Calendar: React.FC = ({ const date = dateSetup.dates[i]; const bottomValue = date.getFullYear(); bottomValues.push( - - {bottomValue} - + + + + {bottomValue} + + ); if ( i === 0 || @@ -129,14 +139,24 @@ export const Calendar: React.FC = ({ const date = dateSetup.dates[i]; const bottomValue = getLocaleMonth(date, locale); bottomValues.push( - - {bottomValue} - + + + + {bottomValue} + + ); if ( i === 0 || @@ -176,20 +196,37 @@ export const Calendar: React.FC = ({ let topValue = ""; if (i === 0 || date.getMonth() !== dates[i - 1].getMonth()) { // top - topValue = `${getLocaleMonth(date, locale)}, ${date.getFullYear()}`; + if (locale === "kor") { + topValue = `${date.getFullYear()}년 ${getLocaleMonth(date, locale)}`; + } else { + topValue = `${getLocaleMonth(date, locale)}, ${date.getFullYear()}`; + } } // bottom - const bottomValue = `W${getWeekNumberISO8601(date)}`; + const bottomValue = + locale === "kor" + ? `${getLocaleMonth(date, locale)} ${getWeekOfMonth(date)}주` + : `W${getWeekOfMonth(date)}`; bottomValues.push( - - {bottomValue} - + + + + {bottomValue} + + ); if (topValue) { @@ -221,19 +258,39 @@ export const Calendar: React.FC = ({ const dates = dateSetup.dates; for (let i = 0; i < dates.length; i++) { const date = dates[i]; - const bottomValue = `${getLocalDayOfWeek(date, locale, "short")}, ${date - .getDate() - .toString()}`; + const bottomValue = + locale === "kor" + ? `${getLocaleMonth( + date, + locale + )} ${date.getDate()}일 (${getLocalDayOfWeek( + date, + locale, + "short" + )})` + : `${getLocalDayOfWeek(date, locale, "short")}, ${date + .getDate() + .toString()}`; bottomValues.push( - - {bottomValue} - + + + + {bottomValue} + + ); if ( i + 1 !== dates.length && @@ -275,22 +332,41 @@ export const Calendar: React.FC = ({ }).format(date); bottomValues.push( - - {bottomValue} - + + + + {bottomValue} + + ); if (i === 0 || date.getDate() !== dates[i - 1].getDate()) { - const topValue = `${getLocalDayOfWeek( - date, - locale, - "short" - )}, ${date.getDate()} ${getLocaleMonth(date, locale)}`; + const topValue = + locale === "kor" + ? `${getLocaleMonth( + date, + locale + )} ${date.getDate()}일 (${getLocalDayOfWeek( + date, + locale, + "short" + )})` + : `${getLocalDayOfWeek( + date, + locale, + "short" + )}, ${date.getDate()} ${getLocaleMonth(date, locale)}`; topValues.push( = ({ }).format(date); bottomValues.push( - - {bottomValue} - + + + + {bottomValue} + + ); if (i !== 0 && date.getDate() !== dates[i - 1].getDate()) { const displayDate = dates[i - 1]; - const topValue = `${getLocalDayOfWeek( - displayDate, - locale, - "long" - )}, ${displayDate.getDate()} ${getLocaleMonth(displayDate, locale)}`; + const topValue = + locale === "kor" + ? `${getLocaleMonth( + displayDate, + locale + )} ${displayDate.getDate()}일 (${getLocalDayOfWeek( + displayDate, + locale, + "long" + )})` + : `${getLocalDayOfWeek( + date, + locale, + "long" + )}, ${date.getDate()} ${getLocaleMonth(date, locale)}`; const topPosition = (date.getHours() - 24) / 2; topValues.push( = ({ ).getTime() >= now.getTime()) ) { today = ( - + // + // + + // + + // + + {/* 사각형 (배경) */} + + + {/* 중앙 세로선 */} + + + {/* 세로로 긴 역삼각형 화살표 머리 */} + + ); } // rtl for today diff --git a/src/components/other/horizontal-scroll.module.css b/src/components/other/horizontal-scroll.module.css index dcf787e52..1e831a5d4 100644 --- a/src/components/other/horizontal-scroll.module.css +++ b/src/components/other/horizontal-scroll.module.css @@ -1,33 +1,5 @@ .scrollWrapper { overflow: auto; max-width: 100%; - /*firefox*/ - scrollbar-width: thin; - /*iPad*/ height: 1.2rem; } -.scrollWrapper::-webkit-scrollbar { - width: 1.1rem; - height: 1.1rem; -} -.scrollWrapper::-webkit-scrollbar-corner { - background: transparent; -} -.scrollWrapper::-webkit-scrollbar-thumb { - border: 6px solid transparent; - background: rgba(0, 0, 0, 0.2); - background: var(--palette-black-alpha-20, rgba(0, 0, 0, 0.2)); - border-radius: 10px; - background-clip: padding-box; -} -.scrollWrapper::-webkit-scrollbar-thumb:hover { - border: 4px solid transparent; - background: rgba(0, 0, 0, 0.3); - background: var(--palette-black-alpha-30, rgba(0, 0, 0, 0.3)); - background-clip: padding-box; -} -@media only screen and (max-device-width: 1024px) and (-webkit-min-device-pixel-ratio: 2) { -} -.scroll { - height: 1px; -} diff --git a/src/components/other/tooltip.tsx b/src/components/other/tooltip.tsx index 7542a14eb..938a09076 100644 --- a/src/components/other/tooltip.tsx +++ b/src/components/other/tooltip.tsx @@ -123,13 +123,18 @@ export const StandardTooltipContent: React.FC<{ }; return (
- {`${ - task.name - }: ${task.start.getDate()}-${ - task.start.getMonth() + 1 - }-${task.start.getFullYear()} - ${task.end.getDate()}-${ - task.end.getMonth() + 1 - }-${task.end.getFullYear()}`} + {`${task.name}`} +

+

+ {`date : ${task.start.getFullYear()}-${ + task.start.getMonth() + 1 + }-${task.start.getDate()} ~ ${task.end.getFullYear()}-${ + task.end.getMonth() + 1 + }-${task.end.getDate()}`} +

{task.end.getTime() - task.start.getTime() !== 0 && (

{`Duration: ${~~( (task.end.getTime() - task.start.getTime()) / diff --git a/src/components/other/vertical-scroll.module.css b/src/components/other/vertical-scroll.module.css index da55a2e2e..3d9553798 100644 --- a/src/components/other/vertical-scroll.module.css +++ b/src/components/other/vertical-scroll.module.css @@ -2,26 +2,4 @@ overflow: hidden auto; width: 1rem; flex-shrink: 0; - /*firefox*/ - scrollbar-width: thin; -} -.scroll::-webkit-scrollbar { - width: 1.1rem; - height: 1.1rem; -} -.scroll::-webkit-scrollbar-corner { - background: transparent; -} -.scroll::-webkit-scrollbar-thumb { - border: 6px solid transparent; - background: rgba(0, 0, 0, 0.2); - background: var(--palette-black-alpha-20, rgba(0, 0, 0, 0.2)); - border-radius: 10px; - background-clip: padding-box; -} -.scroll::-webkit-scrollbar-thumb:hover { - border: 4px solid transparent; - background: rgba(0, 0, 0, 0.3); - background: var(--palette-black-alpha-30, rgba(0, 0, 0, 0.3)); - background-clip: padding-box; } diff --git a/src/components/task-item/project/project.tsx b/src/components/task-item/project/project.tsx index 5a47ba90b..8793b2cbc 100644 --- a/src/components/task-item/project/project.tsx +++ b/src/components/task-item/project/project.tsx @@ -11,23 +11,6 @@ export const Project: React.FC = ({ task, isSelected }) => { : task.styles.progressColor; const projectWith = task.x2 - task.x1; - const projectLeftTriangle = [ - task.x1, - task.y + task.height / 2 - 1, - task.x1, - task.y + task.height, - task.x1 + 15, - task.y + task.height / 2 - 1, - ].join(","); - const projectRightTriangle = [ - task.x2, - task.y + task.height / 2 - 1, - task.x2, - task.y + task.height, - task.x2 - 15, - task.y + task.height / 2 - 1, - ].join(","); - return ( = ({ task, isSelected }) => { rx={task.barCornerRadius} fill={processColor} /> - - - ); }; diff --git a/src/components/task-item/task-item.tsx b/src/components/task-item/task-item.tsx index cf0628498..7cd0f530f 100644 --- a/src/components/task-item/task-item.tsx +++ b/src/components/task-item/task-item.tsx @@ -117,6 +117,7 @@ export const TaskItem: React.FC = props => { : style.barLabel && style.barLabelOutside } ref={textRef} + fontSize={12} > {task.name} diff --git a/src/helpers/date-helper.ts b/src/helpers/date-helper.ts index 1b2a0f5c4..3429d4d07 100644 --- a/src/helpers/date-helper.ts +++ b/src/helpers/date-helper.ts @@ -216,6 +216,30 @@ const getMonday = (date: Date) => { return new Date(date.setDate(diff)); }; +export const getWeekOfMonth = (date: any) => { + // 주어진 날짜의 첫 번째 날을 가져옵니다. + const startOfMonth = new Date(date.getFullYear(), date.getMonth(), 1); + + // 주어진 날짜의 첫 번째 월요일을 가져옵니다. + const firstMonday: any = new Date(startOfMonth); + while (firstMonday.getDay() !== 1) { + firstMonday.setDate(firstMonday.getDate() + 1); + } + + // 주어진 날짜와 첫 번째 월요일 사이의 일수를 계산합니다. + const diffDays = Math.ceil((date - firstMonday) / (24 * 60 * 60 * 1000)); + + // 주 수를 계산합니다. 주어진 날짜가 첫 번째 월요일 이전이면 1주차로 간주합니다. + const weekNumber = Math.ceil((diffDays + 1) / 7); + + // 만약 주어진 날짜가 첫 번째 월요일보다 앞에 있다면 첫 번째 주로 간주합니다. + if (diffDays < 0) { + return 1; + } + + return weekNumber; +}; + export const getWeekNumberISO8601 = (date: Date) => { const tmpDate = new Date(date.valueOf()); const dayNumber = (tmpDate.getDay() + 6) % 7;