@jk-core/components 0.0.6 → 0.0.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/dist/Calendar/components/DayTile/index.d.ts +11 -0
- package/dist/Calendar/components/MonthTile/index.d.ts +9 -0
- package/dist/Calendar/components/YearTile/index.d.ts +8 -0
- package/dist/Calendar/hooks/useCalendarNav.d.ts +14 -0
- package/dist/Calendar/hooks/useDateSelect.d.ts +14 -0
- package/dist/Calendar/index.d.ts +13 -0
- package/{src/Calendar/type.ts → dist/Calendar/type.d.ts} +2 -3
- package/dist/Calendar/utils/getWeeksInMonth.d.ts +5 -0
- package/dist/Calendar/utils/isInRange.d.ts +3 -0
- package/dist/Calendar/utils/isSameDay.d.ts +3 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +937 -0
- package/dist/index.js.map +1 -0
- package/dist/index.umd.cjs +40 -0
- package/dist/index.umd.cjs.map +1 -0
- package/dist/main.d.ts +1 -0
- package/dist/style.css +402 -0
- package/dist/style.css.map +1 -0
- package/package.json +16 -5
- package/src/Calendar/{Calendar.module.scss → scss/_calendar.scss} +9 -0
- package/src/Calendar/scss/_tile.scss +214 -0
- package/src/Calendar/scss/main.scss +3 -0
- package/.eslintrc.json +0 -63
- package/.stylelintrc.json +0 -29
- package/src/Calendar/components/DayTile/DayTile.module.scss +0 -79
- package/src/Calendar/components/DayTile/index.tsx +0 -52
- package/src/Calendar/components/MonthTile/MonthTile.module.scss +0 -44
- package/src/Calendar/components/MonthTile/index.tsx +0 -38
- package/src/Calendar/components/YearTile/YearTile.module.scss +0 -85
- package/src/Calendar/components/YearTile/index.tsx +0 -60
- package/src/Calendar/components/mixin.module.scss +0 -5
- package/src/Calendar/hooks/useCalendarNav.ts +0 -80
- package/src/Calendar/hooks/useDateSelect.ts +0 -47
- package/src/Calendar/index.tsx +0 -166
- package/src/Calendar/utils/getWeeksInMonth.ts +0 -45
- package/src/Calendar/utils/isInRange.ts +0 -8
- package/src/Calendar/utils/isSameDay.ts +0 -21
- package/src/assets/close.svg +0 -16
- package/src/assets/drop-arrow.svg +0 -3
- package/src/index.tsx +0 -3
- package/src/styles/mediaQuery.scss +0 -22
- package/src/svg.d.ts +0 -6
- package/src/vite-env.d.ts +0 -1
- package/tsconfig.json +0 -13
- package/vite.config.ts +0 -58
- /package/src/{styles/color.scss → Calendar/scss/_variables.scss} +0 -0
package/.eslintrc.json
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"env": {
|
|
3
|
-
"browser": true,
|
|
4
|
-
"es2021": true
|
|
5
|
-
},
|
|
6
|
-
"extends": [
|
|
7
|
-
"eslint:recommended",
|
|
8
|
-
"plugin:@typescript-eslint/recommended",
|
|
9
|
-
"plugin:react/recommended",
|
|
10
|
-
"airbnb",
|
|
11
|
-
"airbnb/hooks",
|
|
12
|
-
"airbnb-typescript"
|
|
13
|
-
],
|
|
14
|
-
"parser": "@typescript-eslint/parser",
|
|
15
|
-
"parserOptions": {
|
|
16
|
-
"ecmaVersion": "latest",
|
|
17
|
-
"sourceType": "module",
|
|
18
|
-
"project": ["./tsconfig.json"]
|
|
19
|
-
},
|
|
20
|
-
"plugins": [
|
|
21
|
-
"@typescript-eslint",
|
|
22
|
-
"react"
|
|
23
|
-
],
|
|
24
|
-
"rules": {
|
|
25
|
-
"import/prefer-default-export":"off",
|
|
26
|
-
"no-var": "error",
|
|
27
|
-
"jsx-a11y/control-has-associated-label":"off",
|
|
28
|
-
"jsx-a11y/label-has-associated-control": [
|
|
29
|
-
2,
|
|
30
|
-
{
|
|
31
|
-
"labelAttributes": ["htmlFor"],
|
|
32
|
-
"depth": 3
|
|
33
|
-
}
|
|
34
|
-
],
|
|
35
|
-
"react/react-in-jsx-scope": "off",
|
|
36
|
-
"react/jsx-props-no-spreading": "off",
|
|
37
|
-
"react/require-default-props": "off",
|
|
38
|
-
"react/jsx-one-expression-per-line": "off",
|
|
39
|
-
"implicit-arrow-linebreak": "off",
|
|
40
|
-
"linebreak-style" : "off",
|
|
41
|
-
"import/no-extraneous-dependencies": ["error", {"devDependencies": true}],
|
|
42
|
-
"no-restricted-imports": [
|
|
43
|
-
"error",
|
|
44
|
-
{
|
|
45
|
-
"patterns": [
|
|
46
|
-
{
|
|
47
|
-
"group": ["../../../*"],
|
|
48
|
-
"message": "Please use absolute path."
|
|
49
|
-
}
|
|
50
|
-
]
|
|
51
|
-
}
|
|
52
|
-
],
|
|
53
|
-
"sort-imports": [
|
|
54
|
-
"error",
|
|
55
|
-
{
|
|
56
|
-
"ignoreCase": true,
|
|
57
|
-
"ignoreDeclarationSort": true,
|
|
58
|
-
"ignoreMemberSort": false,
|
|
59
|
-
"memberSyntaxSortOrder": ["none", "all", "multiple", "single"]
|
|
60
|
-
}
|
|
61
|
-
]
|
|
62
|
-
}
|
|
63
|
-
}
|
package/.stylelintrc.json
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": [
|
|
3
|
-
"stylelint-config-standard",
|
|
4
|
-
"stylelint-config-standard-scss"
|
|
5
|
-
],
|
|
6
|
-
"plugins": ["stylelint-scss","stylelint-selector-bem-pattern"],
|
|
7
|
-
"recommendations": ["stylelint.vscode-stylelint"],
|
|
8
|
-
"rules": {
|
|
9
|
-
"property-no-vendor-prefix":null,
|
|
10
|
-
"import-notation": "string",
|
|
11
|
-
"selector-class-pattern": null,
|
|
12
|
-
"color-hex-length": null,
|
|
13
|
-
"no-descending-specificity": null,
|
|
14
|
-
"color-function-notation":null,
|
|
15
|
-
"alpha-value-notation":null,
|
|
16
|
-
"scss/percent-placeholder-pattern":null,
|
|
17
|
-
"custom-property-pattern":null,
|
|
18
|
-
"declaration-empty-line-before":null,
|
|
19
|
-
"scss/at-mixin-pattern":null,
|
|
20
|
-
"plugin/selector-bem-pattern": {
|
|
21
|
-
"componentName": "[A-Z]+",
|
|
22
|
-
"componentSelectors": {
|
|
23
|
-
"initial": "^\\.{componentName}(?:-[a-z]+)?$",
|
|
24
|
-
"combined": "^\\.combined-{componentName}-[a-z]+$"
|
|
25
|
-
},
|
|
26
|
-
"utilitySelectors": "^\\.util-[a-z]+$"
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
@use "../mixin.module.scss" as mixin;
|
|
2
|
-
@use "../../../styles/mediaQuery.scss" as media;
|
|
3
|
-
|
|
4
|
-
.body {
|
|
5
|
-
@include mixin.body;
|
|
6
|
-
|
|
7
|
-
&__tile {
|
|
8
|
-
display: flex;
|
|
9
|
-
flex-direction: column;
|
|
10
|
-
justify-content: space-between;
|
|
11
|
-
gap: 5px;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
&__weeks {
|
|
15
|
-
display: flex;
|
|
16
|
-
justify-content: space-between;
|
|
17
|
-
font-weight: 400;
|
|
18
|
-
font-size: 1em;
|
|
19
|
-
|
|
20
|
-
&--date {
|
|
21
|
-
flex: 1 0;
|
|
22
|
-
display: flex;
|
|
23
|
-
justify-content: center;
|
|
24
|
-
align-items: center;
|
|
25
|
-
min-width: 40px;
|
|
26
|
-
padding: 5px 0;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
&__week {
|
|
31
|
-
display: flex;
|
|
32
|
-
justify-content: space-between;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
&__day {
|
|
36
|
-
display: flex;
|
|
37
|
-
justify-content: center;
|
|
38
|
-
align-items: center;
|
|
39
|
-
flex-direction: column;
|
|
40
|
-
width: 100%;
|
|
41
|
-
min-width: 40px;
|
|
42
|
-
min-height: 40px;
|
|
43
|
-
border-radius: 100%;
|
|
44
|
-
padding: 5px;
|
|
45
|
-
border: none;
|
|
46
|
-
font-weight: 400;
|
|
47
|
-
font-size: 1em;
|
|
48
|
-
|
|
49
|
-
&:hover {
|
|
50
|
-
@include media.pc {
|
|
51
|
-
background-color: var(--G-5);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
&:active {
|
|
56
|
-
background-color: var(--G-10);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
&--today {
|
|
60
|
-
color: var(--P-50);
|
|
61
|
-
font-weight: 600;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
&--selected {
|
|
65
|
-
background-color: var(--P-50) !important;
|
|
66
|
-
color: var(--white) !important;
|
|
67
|
-
font-weight: 600;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
&--before {
|
|
71
|
-
color: var(--G-40);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
&--tile {
|
|
75
|
-
border-radius: 10px;
|
|
76
|
-
gap: 5px;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/* eslint-disable max-len */
|
|
2
|
-
/* eslint-disable react/no-array-index-key */
|
|
3
|
-
import { cn } from '@jk-core/utils';
|
|
4
|
-
import isSameDay from '../../utils/isSameDay';
|
|
5
|
-
import styles from './DayTile.module.scss';
|
|
6
|
-
|
|
7
|
-
const WEEKS = ['일', '월', '화', '수', '목', '금', '토'];
|
|
8
|
-
|
|
9
|
-
interface Props {
|
|
10
|
-
selectedDate?: Date;
|
|
11
|
-
weeksInMonth: {
|
|
12
|
-
thisMonth: boolean;
|
|
13
|
-
date: Date;
|
|
14
|
-
}[][];
|
|
15
|
-
tileContent?: () => React.ReactNode;
|
|
16
|
-
handleDayClick: (day: Date) => void;
|
|
17
|
-
}
|
|
18
|
-
export default function DayTile({
|
|
19
|
-
selectedDate, weeksInMonth, tileContent, handleDayClick,
|
|
20
|
-
}: Props) {
|
|
21
|
-
return (
|
|
22
|
-
<div className={styles.body}>
|
|
23
|
-
<div className={styles.body__weeks}>
|
|
24
|
-
{WEEKS.map((week) => (<div className={styles['body__weeks--date']} key={week}>{week}</div>))}
|
|
25
|
-
</div>
|
|
26
|
-
|
|
27
|
-
<div className={styles.body__tile}>
|
|
28
|
-
{weeksInMonth.map((week, index) => (
|
|
29
|
-
<div key={index} className={styles.body__week}>
|
|
30
|
-
{week.map((day, idx) => (
|
|
31
|
-
<button
|
|
32
|
-
className={cn({
|
|
33
|
-
[styles.body__day]: true,
|
|
34
|
-
[styles['body__day--today']]: isSameDay(day.date, new Date()),
|
|
35
|
-
[styles['body__day--selected']]: !!selectedDate && isSameDay(day.date, selectedDate),
|
|
36
|
-
[styles['body__day--before']]: !day.thisMonth,
|
|
37
|
-
[styles['body__day--tile']]: !!(tileContent && tileContent()),
|
|
38
|
-
})}
|
|
39
|
-
type="button"
|
|
40
|
-
key={idx}
|
|
41
|
-
onClick={() => handleDayClick(day.date)}
|
|
42
|
-
>
|
|
43
|
-
{day.date.getDate()}
|
|
44
|
-
{tileContent && tileContent()}
|
|
45
|
-
</button>
|
|
46
|
-
))}
|
|
47
|
-
</div>
|
|
48
|
-
))}
|
|
49
|
-
</div>
|
|
50
|
-
</div>
|
|
51
|
-
);
|
|
52
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
@use "../mixin.module.scss" as mixin;
|
|
2
|
-
|
|
3
|
-
.body {
|
|
4
|
-
display: grid;
|
|
5
|
-
grid-template-columns: repeat(3, 1fr);
|
|
6
|
-
grid-template-rows: repeat(4, 1fr);
|
|
7
|
-
gap: 5px;
|
|
8
|
-
|
|
9
|
-
@include mixin.body;
|
|
10
|
-
|
|
11
|
-
&__month {
|
|
12
|
-
display: flex;
|
|
13
|
-
flex-direction: column;
|
|
14
|
-
justify-content: center;
|
|
15
|
-
align-items: center;
|
|
16
|
-
padding: 5px;
|
|
17
|
-
border-radius: 10px;
|
|
18
|
-
|
|
19
|
-
svg {
|
|
20
|
-
width: 15px;
|
|
21
|
-
height: 15px;
|
|
22
|
-
cursor: pointer;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
&:active {
|
|
26
|
-
background-color: var(--G-10);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
&--selected {
|
|
30
|
-
background-color: var(--P-50) !important;
|
|
31
|
-
color: var(--white) !important;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
&--today {
|
|
35
|
-
color: var(--P-50);
|
|
36
|
-
font-weight: 600;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
&--tile {
|
|
40
|
-
justify-content: flex-start;
|
|
41
|
-
gap: 5px;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { cn } from '@jk-core/utils';
|
|
2
|
-
import styles from './MonthTile.module.scss';
|
|
3
|
-
import isSameDay from '../../utils/isSameDay';
|
|
4
|
-
import { CalendarView } from '../../type';
|
|
5
|
-
|
|
6
|
-
const MONTHS = Array.from({ length: 12 }, (_, i) => i);
|
|
7
|
-
|
|
8
|
-
interface Props {
|
|
9
|
-
selectedDate?: Date;
|
|
10
|
-
viewDate: Date;
|
|
11
|
-
handleMonthClick: (month: number) => void;
|
|
12
|
-
tileContent?: (date: Date, view:CalendarView) => React.ReactNode;
|
|
13
|
-
}
|
|
14
|
-
export default function MonthTile({
|
|
15
|
-
selectedDate, viewDate, handleMonthClick, tileContent = () => false,
|
|
16
|
-
}: Props) {
|
|
17
|
-
return (
|
|
18
|
-
<div className={styles.body}>
|
|
19
|
-
{MONTHS.map((month) => (
|
|
20
|
-
<button
|
|
21
|
-
className={cn({
|
|
22
|
-
[styles.body__month]: true,
|
|
23
|
-
[styles['body__month--selected']]: !!selectedDate && isSameDay(selectedDate, new Date(viewDate.getFullYear(), month), 'month'),
|
|
24
|
-
[styles['body__month--today']]: isSameDay(new Date(viewDate.getFullYear(), month), new Date(), 'month'),
|
|
25
|
-
[styles['body__month--tile']]: !!tileContent(new Date(viewDate.getFullYear(), month - 1, 1), 'month'),
|
|
26
|
-
})}
|
|
27
|
-
type="button"
|
|
28
|
-
key={month}
|
|
29
|
-
onClick={() => handleMonthClick(month)}
|
|
30
|
-
>
|
|
31
|
-
<span>{`${month + 1}월`}</span>
|
|
32
|
-
{!!tileContent(new Date(viewDate.getFullYear(), month - 1, 1), 'month')
|
|
33
|
-
&& tileContent(new Date(viewDate.getFullYear(), month - 1, 1), 'month')}
|
|
34
|
-
</button>
|
|
35
|
-
))}
|
|
36
|
-
</div>
|
|
37
|
-
);
|
|
38
|
-
}
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
@use "../mixin.module.scss" as mixin;
|
|
2
|
-
@use "../../../styles/mediaQuery.scss" as media;
|
|
3
|
-
|
|
4
|
-
.body {
|
|
5
|
-
@include mixin.body;
|
|
6
|
-
|
|
7
|
-
position: relative;
|
|
8
|
-
height: 310px;
|
|
9
|
-
display: flex;
|
|
10
|
-
flex-direction: column;
|
|
11
|
-
align-items: center;
|
|
12
|
-
overflow: auto;
|
|
13
|
-
gap: 10px;
|
|
14
|
-
|
|
15
|
-
&::-webkit-scrollbar {
|
|
16
|
-
display: none;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
&__blank {
|
|
20
|
-
height: calc(50% - 40px);
|
|
21
|
-
flex-shrink: 0;
|
|
22
|
-
|
|
23
|
-
&:last-child {
|
|
24
|
-
height: 50%;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
&__year {
|
|
29
|
-
min-width: 50%;
|
|
30
|
-
display: flex;
|
|
31
|
-
flex-direction: column;
|
|
32
|
-
align-items: center;
|
|
33
|
-
justify-content: center;
|
|
34
|
-
min-height: 40px;
|
|
35
|
-
border-radius: 6px;
|
|
36
|
-
flex-shrink: 0;
|
|
37
|
-
overflow: hidden;
|
|
38
|
-
font-weight: 400;
|
|
39
|
-
font-size: 1.2em;
|
|
40
|
-
|
|
41
|
-
&:hover {
|
|
42
|
-
@include media.pc {
|
|
43
|
-
background-color: var(--P-5);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
&:active {
|
|
48
|
-
background-color: var(--P-10);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
&--border {
|
|
52
|
-
border: 1px solid var(--G-30);
|
|
53
|
-
background-color: var(--P-5);
|
|
54
|
-
|
|
55
|
-
&:hover {
|
|
56
|
-
@include media.pc {
|
|
57
|
-
background-color: var(--P-10);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
&--year {
|
|
63
|
-
height: 40px;
|
|
64
|
-
display: flex;
|
|
65
|
-
align-items: center;
|
|
66
|
-
justify-content: center;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
&--selected {
|
|
70
|
-
color: var(--white);
|
|
71
|
-
background-color: var(--P-50) !important;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
&--tile {
|
|
75
|
-
display: flex;
|
|
76
|
-
align-items: center;
|
|
77
|
-
justify-content: center;
|
|
78
|
-
min-height: 40px;
|
|
79
|
-
color: var(--G-80);
|
|
80
|
-
width: 100%;
|
|
81
|
-
background-color: var(--white);
|
|
82
|
-
border-top: var(--P-50);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { cn } from '@jk-core/utils';
|
|
2
|
-
import { useEffect, useRef } from 'react';
|
|
3
|
-
import styles from './YearTile.module.scss';
|
|
4
|
-
import { CalendarView } from '../../type';
|
|
5
|
-
|
|
6
|
-
interface Props {
|
|
7
|
-
selectedDate?: Date;
|
|
8
|
-
onClick: (year: number) => void;
|
|
9
|
-
tileContent?: (date: Date, view:CalendarView) => React.ReactNode;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const YEARS = Array.from({ length: 100 }, (_, i) => i + 2000);
|
|
13
|
-
|
|
14
|
-
export default function YearTile({
|
|
15
|
-
selectedDate, onClick,
|
|
16
|
-
tileContent = () => false,
|
|
17
|
-
}: Props) {
|
|
18
|
-
const wrapperRef = useRef<HTMLDivElement>(null);
|
|
19
|
-
const selectedRef = useRef<HTMLButtonElement>(null);
|
|
20
|
-
|
|
21
|
-
useEffect(() => {
|
|
22
|
-
const selectedElement = selectedRef.current;
|
|
23
|
-
const wrapperElement = wrapperRef.current;
|
|
24
|
-
if (!selectedElement || !wrapperElement) return;
|
|
25
|
-
|
|
26
|
-
const { clientHeight } = wrapperElement;
|
|
27
|
-
const { offsetTop, clientHeight: selectedHeight } = selectedElement;
|
|
28
|
-
|
|
29
|
-
wrapperElement.scrollTo({
|
|
30
|
-
top: offsetTop - clientHeight / 2 + selectedHeight,
|
|
31
|
-
});
|
|
32
|
-
}, []);
|
|
33
|
-
|
|
34
|
-
return (
|
|
35
|
-
<div className={styles.body} ref={wrapperRef}>
|
|
36
|
-
<div className={styles.body__blank} />
|
|
37
|
-
{YEARS.map((year) => (
|
|
38
|
-
<button
|
|
39
|
-
className={cn({
|
|
40
|
-
[styles.body__year]: true,
|
|
41
|
-
[styles['body__year--selected']]: !!selectedDate && selectedDate.getFullYear() === year,
|
|
42
|
-
[styles['body__year--border']]: !!tileContent(new Date(year, 1, 1), 'year'),
|
|
43
|
-
})}
|
|
44
|
-
key={year}
|
|
45
|
-
type="button"
|
|
46
|
-
ref={!!selectedDate && selectedDate.getFullYear() === year ? selectedRef : null}
|
|
47
|
-
onClick={() => onClick(year)}
|
|
48
|
-
>
|
|
49
|
-
<span className={styles['body__year--year']}>{year}</span>
|
|
50
|
-
{tileContent(new Date(year, 1, 1), 'year') && (
|
|
51
|
-
<div className={styles['body__year--tile']}>
|
|
52
|
-
{tileContent(new Date(year, 1, 1), 'year')}
|
|
53
|
-
</div>
|
|
54
|
-
)}
|
|
55
|
-
</button>
|
|
56
|
-
))}
|
|
57
|
-
<div className={styles.body__blank} />
|
|
58
|
-
</div>
|
|
59
|
-
);
|
|
60
|
-
}
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { CalendarView } from '../type';
|
|
2
|
-
|
|
3
|
-
interface Props {
|
|
4
|
-
method: CalendarView;
|
|
5
|
-
selectMode: CalendarView;
|
|
6
|
-
date: Date;
|
|
7
|
-
setDate:(date: Date) => void;
|
|
8
|
-
min: Date;
|
|
9
|
-
max: Date;
|
|
10
|
-
}
|
|
11
|
-
const useCalendarNav = ({
|
|
12
|
-
method, selectMode, date, setDate, min, max,
|
|
13
|
-
}:Props) => {
|
|
14
|
-
const disabled = (direction: 'prev' | 'next') => {
|
|
15
|
-
if (selectMode === 'year' || method !== selectMode) return true;
|
|
16
|
-
|
|
17
|
-
if (method === 'day') {
|
|
18
|
-
if (direction === 'prev') {
|
|
19
|
-
const prevMonth = new Date(date.getFullYear(), date.getMonth() - 1, 1);
|
|
20
|
-
return prevMonth < min;
|
|
21
|
-
}
|
|
22
|
-
const nextMonth = new Date(date.getFullYear(), date.getMonth() + 1, 1);
|
|
23
|
-
return nextMonth > max;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if (method === 'month') {
|
|
27
|
-
if (direction === 'prev') {
|
|
28
|
-
const prevYear = new Date(date.getFullYear() - 1, date.getMonth(), 1);
|
|
29
|
-
return prevYear < min;
|
|
30
|
-
}
|
|
31
|
-
const nextYear = new Date(date.getFullYear() + 1, date.getMonth(), 1);
|
|
32
|
-
return nextYear > max;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
if (method === 'year') {
|
|
36
|
-
if (direction === 'prev') {
|
|
37
|
-
const prevDecade = new Date(date.getFullYear() - 10, date.getMonth(), 1);
|
|
38
|
-
return prevDecade < min;
|
|
39
|
-
}
|
|
40
|
-
const nextDecade = new Date(date.getFullYear() + 10, date.getMonth(), 1);
|
|
41
|
-
return nextDecade > max;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return false;
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
const onArrowClick = (direction: 'prev' | 'next') => {
|
|
48
|
-
const offset = direction === 'prev' ? -1 : 1;
|
|
49
|
-
const minDate = new Date(2000, 0, 1);
|
|
50
|
-
const maxDate = new Date(2099, 11, 31);
|
|
51
|
-
|
|
52
|
-
if (method === 'day') {
|
|
53
|
-
const newDate = new Date(date.getFullYear(), date.getMonth() + offset, 1);
|
|
54
|
-
|
|
55
|
-
if (newDate >= minDate && newDate <= maxDate) {
|
|
56
|
-
setDate(newDate);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (method === 'month') {
|
|
61
|
-
const newDate = new Date(date.getFullYear() + offset, date.getMonth(), 1);
|
|
62
|
-
|
|
63
|
-
if (newDate >= minDate && newDate <= maxDate) {
|
|
64
|
-
setDate(newDate);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (method === 'year') {
|
|
69
|
-
const newDate = new Date(date.getFullYear() + offset * 10, date.getMonth(), 1);
|
|
70
|
-
|
|
71
|
-
if (newDate >= minDate && newDate <= maxDate) {
|
|
72
|
-
setDate(newDate);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
return { disabled, onArrowClick };
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
export default useCalendarNav;
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { CalendarView } from '../type';
|
|
2
|
-
|
|
3
|
-
interface UseDateSelectProps {
|
|
4
|
-
viewDate: Date;
|
|
5
|
-
setViewDate: (date: Date) => void;
|
|
6
|
-
method: CalendarView;
|
|
7
|
-
setSelectMode:(mode:CalendarView) => void;
|
|
8
|
-
onChange:(date:Date) => void;
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const useDateSelect = ({
|
|
13
|
-
viewDate, setViewDate, onChange, setSelectMode, method,
|
|
14
|
-
}: UseDateSelectProps) => {
|
|
15
|
-
const min = new Date(2000, 0, 1);
|
|
16
|
-
const max = new Date(2099, 11, 31);
|
|
17
|
-
|
|
18
|
-
const onDayClick = (day: Date) => {
|
|
19
|
-
if (day < min || day > max) {
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
setViewDate(day);
|
|
24
|
-
onChange(day);
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
const onMonthClick = (month:number) => {
|
|
28
|
-
const newDate = new Date(viewDate.getFullYear(), month, 1);
|
|
29
|
-
|
|
30
|
-
setViewDate(newDate);
|
|
31
|
-
|
|
32
|
-
if (method !== 'month') setSelectMode(method);
|
|
33
|
-
if (method === 'month') onChange(newDate);
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const onYearClick = (year:number) => {
|
|
37
|
-
const newDate = new Date(year, 0, 1);
|
|
38
|
-
|
|
39
|
-
setViewDate(newDate);
|
|
40
|
-
if (method !== 'year') setSelectMode(method);
|
|
41
|
-
if (method === 'year') onChange(newDate);
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
return { onDayClick, onMonthClick, onYearClick };
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
export default useDateSelect;
|