Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactored Calendar component to remove dependency of primereact. (#2592 #2592

Merged
merged 14 commits into from
Mar 25, 2023
1 change: 0 additions & 1 deletion packages/neuron-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@
"immer": "9.0.16",
"jsqr": "1.4.0",
"office-ui-fabric-react": "7.199.6",
"primereact": "8.7.1",
"qr.js": "0.0.0",
"react": "17.0.2",
"react-dom": "17.0.2",
Expand Down
2 changes: 2 additions & 0 deletions packages/neuron-ui/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,8 @@
"tag": "D"
},
"timezone": "Time Zone",
"previous-month": "previous month",
"next-month": "next month",
"start-tomorrow": "Selected time should start from tomorrow."
},
"sign-and-verify": {
Expand Down
2 changes: 2 additions & 0 deletions packages/neuron-ui/src/locales/zh-tw.json
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,8 @@
"tag": "十二月"
},
"timezone": "時區",
"previous-month": "上個月",
"next-month": "下個月",
"start-tomorrow": "所選時間不能早於明天。"
},
"sign-and-verify": {
Expand Down
2 changes: 2 additions & 0 deletions packages/neuron-ui/src/locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,8 @@
"tag": "十二月"
},
"timezone": "时区",
"previous-month": "上个月",
"next-month": "下个月",
"start-tomorrow": "所选时间不能早于明天。"
},
"sign-and-verify": {
Expand Down
128 changes: 128 additions & 0 deletions packages/neuron-ui/src/tests/calendar/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import {
isDayInRange,
isMonthInRange,
isYearInRange,
isDateEqual,
getMonthCalendar,
getLocalMonthNames,
getLocalWeekNames,
} from '../../widgets/Calendar/utils'

describe('Check day in range', () => {
it('check no restrictions', () => {
expect(isDayInRange(new Date(2023, 1, 1), {})).toBe(true)
})
it('check minDate', () => {
expect(isDayInRange(new Date(2023, 1, 1), { minDate: new Date(2023, 1, 1) })).toBe(true)
expect(isDayInRange(new Date(2023, 1, 1), { minDate: new Date(2023, 1, 1, 12) })).toBe(true)
expect(isDayInRange(new Date(2023, 1, 1), { minDate: new Date(2023, 1, 2) })).toBe(false)
})
it('check maxDate', () => {
expect(isDayInRange(new Date(2023, 1, 2), { maxDate: new Date(2023, 1, 2) })).toBe(true)
expect(isDayInRange(new Date(2023, 1, 2), { maxDate: new Date(2023, 1, 1) })).toBe(false)
expect(isDayInRange(new Date(2023, 1, 2), { maxDate: new Date(2023, 1, 1, 12) })).toBe(false)
})
})

describe('Check month in range', () => {
it('check no restrictions', () => {
expect(isMonthInRange(2023, 1, {})).toBe(true)
})
it('check minDate', () => {
expect(isMonthInRange(2023, 1, { minDate: new Date(2023, 1, 1) })).toBe(false)
expect(isMonthInRange(2023, 1, { minDate: new Date(2023, 0, 31) })).toBe(true)
})
it('check maxDate', () => {
expect(isMonthInRange(2023, 2, { maxDate: new Date(2023, 1, 1) })).toBe(true)
expect(isMonthInRange(2023, 2, { maxDate: new Date(2023, 0, 31) })).toBe(false)
})
})

describe('Check year in range', () => {
it('check no restrictions', () => {
expect(isYearInRange(2023, {})).toBe(true)
})
it('check minDate', () => {
expect(isYearInRange(2023, { minDate: new Date(2023, 1, 1) })).toBe(true)
expect(isYearInRange(2023, { minDate: new Date(2024, 1, 1) })).toBe(false)
expect(isYearInRange(2023, { minDate: new Date(2022, 1, 1) })).toBe(true)
})
it('check maxDate', () => {
expect(isYearInRange(2023, { maxDate: new Date(2023, 1, 1) })).toBe(true)
expect(isYearInRange(2023, { maxDate: new Date(2024, 1, 1) })).toBe(true)
expect(isYearInRange(2023, { maxDate: new Date(2022, 1, 1) })).toBe(false)
})
})

describe('Check date equal', () => {
it('undefined in one side', () => {
expect(isDateEqual(new Date(2023, 2, 1), undefined)).toBe(false)
expect(isDateEqual(undefined, new Date(2023, 2, 1))).toBe(false)
})
it('check date equal', () => {
expect(isDateEqual(new Date(2023, 2, 1), new Date(2023, 2, 1))).toBe(true)
})
it('check date equal ignore time', () => {
expect(isDateEqual(new Date(2023, 2, 1, 12), new Date(2023, 2, 1, 18))).toBe(true)
})
})

describe('Generate monthly calendar data', () => {
it('Test month calendar output', () => {
expect(getMonthCalendar(2023, 1).map(week => week.map(date => `${date.year}/${date.month}/${date.date}`))).toEqual([
['2023/1/1', '2023/1/2', '2023/1/3', '2023/1/4', '2023/1/5', '2023/1/6', '2023/1/7'],
['2023/1/8', '2023/1/9', '2023/1/10', '2023/1/11', '2023/1/12', '2023/1/13', '2023/1/14'],
['2023/1/15', '2023/1/16', '2023/1/17', '2023/1/18', '2023/1/19', '2023/1/20', '2023/1/21'],
['2023/1/22', '2023/1/23', '2023/1/24', '2023/1/25', '2023/1/26', '2023/1/27', '2023/1/28'],
['2023/1/29', '2023/1/30', '2023/1/31', '2023/2/1', '2023/2/2', '2023/2/3', '2023/2/4'],
['2023/2/5', '2023/2/6', '2023/2/7', '2023/2/8', '2023/2/9', '2023/2/10', '2023/2/11'],
])
})

it('Test month canlendar with specified start weekday', () => {
expect(
getMonthCalendar(2023, 1, 1).map(week => week.map(date => `${date.year}/${date.month}/${date.date}`))
).toEqual([
['2022/12/26', '2022/12/27', '2022/12/28', '2022/12/29', '2022/12/30', '2022/12/31', '2023/1/1'],
['2023/1/2', '2023/1/3', '2023/1/4', '2023/1/5', '2023/1/6', '2023/1/7', '2023/1/8'],
['2023/1/9', '2023/1/10', '2023/1/11', '2023/1/12', '2023/1/13', '2023/1/14', '2023/1/15'],
['2023/1/16', '2023/1/17', '2023/1/18', '2023/1/19', '2023/1/20', '2023/1/21', '2023/1/22'],
['2023/1/23', '2023/1/24', '2023/1/25', '2023/1/26', '2023/1/27', '2023/1/28', '2023/1/29'],
['2023/1/30', '2023/1/31', '2023/2/1', '2023/2/2', '2023/2/3', '2023/2/4', '2023/2/5'],
])
})
})

describe('Get Local Month Names', () => {
it('Chinese', () => {
const names = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
expect(getLocalMonthNames('zh')).toEqual(names)
})

it('English', () => {
const names = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
expect(getLocalMonthNames('en')).toEqual(names)
})
})

describe('Get Local Week Names', () => {
it('Chinese', () => {
const names = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
expect(getLocalWeekNames('zh')).toEqual(names)
})

it('English', () => {
const names = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
expect(getLocalWeekNames('en')).toEqual(names)
})

it('Traditional Chinese', () => {
const names = ['週日', '週一', '週二', '週三', '週四', '週五', '週六']
expect(getLocalWeekNames('zh-TW')).toEqual(names)
})

it('Japanese', () => {
const names = ['日', '月', '火', '水', '木', '金', '土']
expect(getLocalWeekNames('ja')).toEqual(names)
})
})
130 changes: 130 additions & 0 deletions packages/neuron-ui/src/widgets/Calendar/calendar.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
@import '../../styles/mixin.scss';

.srOnly {
position: absolute;
top: -10000px;
left: -10000px;
}

@mixin button {
@include medium-text;
appearance: none;
cursor: pointer;
font-size: 0.75rem;
line-height: 1rem;
font-weight: 500;
padding: 7px 7px;
border: none;
border-radius: 2px;
margin: 0;
box-sizing: border-box;
border-radius: 2px;
background-color: transparent;
min-width: 0;
&:hover, &:focus {
@include semi-bold-text;
background-color: #efefef;
}
&[disabled] {
cursor: not-allowed;
opacity: 0.5;
box-shadow: none !important;
pointer-events: none;
&:hover {
background-color: transparent;
}
}
}

.calendar {
.calOptions {
width: 100%;
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
list-style-type: none;
list-style: none;
padding: 0;

li {
flex-grow: 1;
}

button {
@include button;
width: 100px;
&[aria-checked="true"] {
background-color: var(--nervos-green);
color: white;
}
}
}
}

.calendarHeader {
display: flex;
justify-content: space-between;
border-bottom: 1px solid #eee;
margin-top: 10px;
margin-bottom: 10px;

.calPrev, .calNext {
@include button;
width: 30px;
}
.calPrev {
order: 1;

&::before {
content: '<';
}
}
.calNext {
order: 3;

&::before {
content: '>';
}
}

.calTitle {
order: 2;
margin: 0;
font-size: 0;

button {
@include button;
@include semi-bold-text;
height: 100%;
min-width: 100px;
margin-right: 10px;
}
}
}

.calendarTable {
width: 100%;

td {
text-align: center;
}

.calTableHeader {
@include semi-bold-text;
font-size: 13px;
}

.calDateItem {
@include button;
width: 30px;
height: 30px;
border-radius: 50%;
&[aria-current="date"] {
color: var(--nervos-green);
}
&[aria-pressed="true"] {
background-color: var(--nervos-green);
color: white;
}
}
}
Loading