@acusti/date-picker 0.8.0 → 0.8.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/README.md +2 -2
- package/dist/DatePicker.d.ts +16 -7
- package/dist/DatePicker.js +139 -66
- package/dist/DatePicker.js.flow +20 -20
- package/dist/DatePicker.js.map +1 -1
- package/dist/MonthCalendar.d.ts +14 -4
- package/dist/MonthCalendar.js +214 -85
- package/dist/MonthCalendar.js.flow +10 -10
- package/dist/index.js +1 -1
- package/dist/index.js.flow +3 -3
- package/dist/styles/date-picker.d.ts +3 -2
- package/dist/styles/date-picker.js +1 -1
- package/dist/styles/month-calendar.d.ts +3 -2
- package/dist/styles/month-calendar.js +1 -1
- package/dist/utils.d.ts +5 -1
- package/dist/utils.js +6 -8
- package/dist/utils.js.flow +4 -7
- package/dist/utils.test.js +79 -23
- package/package.json +3 -3
- package/src/DatePicker.tsx +4 -4
- package/src/MonthCalendar.tsx +4 -4
package/README.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# @acusti/date-picker
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@acusti/date-picker)
|
|
4
|
-
[](https://bundlephobia.com/package/@acusti/date-picker)
|
|
5
4
|
[](https://www.npmjs.com/package/@acusti/date-picker)
|
|
6
|
-
[](https://bundlejs.com/?q=%40acusti%2Fdate-picker)
|
|
6
|
+
[](https://socket.dev/npm/package/@acusti/date-picker/overview/0.8.0)
|
|
7
7
|
|
|
8
8
|
A group of React components and utils for rendering a date picker with
|
|
9
9
|
support for ranges via a two-up month calendar view.
|
package/dist/DatePicker.d.ts
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
export type Props = {
|
|
3
3
|
className?: string;
|
|
4
|
-
dateEnd?: Date |
|
|
5
|
-
dateStart?: Date |
|
|
4
|
+
dateEnd?: Date | number | string;
|
|
5
|
+
dateStart?: Date | number | string;
|
|
6
6
|
initialMonth?: number;
|
|
7
7
|
isRange?: boolean;
|
|
8
8
|
isTwoUp?: boolean;
|
|
9
9
|
monthLimitFirst?: number;
|
|
10
10
|
monthLimitLast?: number;
|
|
11
|
-
onChange: (payload: {
|
|
12
|
-
dateEnd?: string | null;
|
|
13
|
-
dateStart: string;
|
|
14
|
-
}) => void;
|
|
11
|
+
onChange: (payload: { dateEnd?: null | string; dateStart: string }) => void;
|
|
15
12
|
/**
|
|
16
13
|
* Boolean to specify that date picker should initially render with the
|
|
17
14
|
* end date’s month visible. The default behavior is to initially render
|
|
@@ -20,4 +17,16 @@ export type Props = {
|
|
|
20
17
|
showEndInitially?: boolean;
|
|
21
18
|
useMonthAbbreviations?: boolean;
|
|
22
19
|
};
|
|
23
|
-
export default function DatePicker({
|
|
20
|
+
export default function DatePicker({
|
|
21
|
+
className,
|
|
22
|
+
dateEnd: _dateEnd,
|
|
23
|
+
dateStart: _dateStart,
|
|
24
|
+
initialMonth,
|
|
25
|
+
isRange,
|
|
26
|
+
isTwoUp,
|
|
27
|
+
monthLimitFirst,
|
|
28
|
+
monthLimitLast,
|
|
29
|
+
onChange,
|
|
30
|
+
showEndInitially,
|
|
31
|
+
useMonthAbbreviations,
|
|
32
|
+
}: Props): React.JSX.Element;
|
package/dist/DatePicker.js
CHANGED
|
@@ -4,27 +4,52 @@ import clsx from 'clsx';
|
|
|
4
4
|
import * as React from 'react';
|
|
5
5
|
import MonthCalendar from './MonthCalendar.js';
|
|
6
6
|
import { ROOT_CLASS_NAME, STYLES } from './styles/date-picker.js';
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
getMonthAbbreviationFromMonth,
|
|
9
|
+
getMonthFromDate,
|
|
10
|
+
getYearFromMonth,
|
|
11
|
+
} from './utils.js';
|
|
8
12
|
const { Fragment, useCallback, useEffect, useRef, useState } = React;
|
|
9
|
-
const getAbbreviatedMonthTitle = (month) =>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
const getAbbreviatedMonthTitle = (month) =>
|
|
14
|
+
`${getMonthAbbreviationFromMonth(month)} ${getYearFromMonth(month)}`;
|
|
15
|
+
export default function DatePicker({
|
|
16
|
+
className,
|
|
17
|
+
dateEnd: _dateEnd,
|
|
18
|
+
dateStart: _dateStart,
|
|
19
|
+
initialMonth,
|
|
20
|
+
isRange = _dateEnd != null,
|
|
21
|
+
isTwoUp,
|
|
22
|
+
monthLimitFirst,
|
|
23
|
+
monthLimitLast,
|
|
24
|
+
onChange,
|
|
25
|
+
showEndInitially,
|
|
26
|
+
useMonthAbbreviations,
|
|
27
|
+
}) {
|
|
28
|
+
const dateEndFromProps =
|
|
29
|
+
_dateEnd != null && typeof _dateEnd !== 'string'
|
|
30
|
+
? new Date(_dateEnd).toISOString()
|
|
31
|
+
: _dateEnd;
|
|
32
|
+
const dateStartFromProps =
|
|
33
|
+
_dateStart != null && typeof _dateStart !== 'string'
|
|
34
|
+
? new Date(_dateStart).toISOString()
|
|
35
|
+
: _dateStart;
|
|
36
|
+
const [dateEnd, setDateEnd] = useState(
|
|
37
|
+
dateEndFromProps !== null && dateEndFromProps !== void 0
|
|
38
|
+
? dateEndFromProps
|
|
39
|
+
: null,
|
|
40
|
+
);
|
|
41
|
+
const [dateStart, setDateStart] = useState(
|
|
42
|
+
dateStartFromProps !== null && dateStartFromProps !== void 0
|
|
43
|
+
? dateStartFromProps
|
|
44
|
+
: null,
|
|
45
|
+
);
|
|
19
46
|
const updatingDateEndRef = useRef(false);
|
|
20
47
|
useEffect(() => {
|
|
21
|
-
if (dateEndFromProps == null)
|
|
22
|
-
return;
|
|
48
|
+
if (dateEndFromProps == null) return;
|
|
23
49
|
setDateEnd(dateEndFromProps);
|
|
24
50
|
}, [dateEndFromProps]);
|
|
25
51
|
useEffect(() => {
|
|
26
|
-
if (dateStartFromProps == null)
|
|
27
|
-
return;
|
|
52
|
+
if (dateStartFromProps == null) return;
|
|
28
53
|
setDateStart(dateStartFromProps);
|
|
29
54
|
}, [dateStartFromProps]);
|
|
30
55
|
if (initialMonth == null) {
|
|
@@ -32,7 +57,9 @@ export default function DatePicker({ className, dateEnd: _dateEnd, dateStart: _d
|
|
|
32
57
|
const useDateEnd = dateStart == null || Boolean(showEndInitially && dateEnd);
|
|
33
58
|
// use date from props if set
|
|
34
59
|
const initialDate = useDateEnd ? dateEnd : dateStart;
|
|
35
|
-
initialMonth = getMonthFromDate(
|
|
60
|
+
initialMonth = getMonthFromDate(
|
|
61
|
+
initialDate == null ? new Date() : new Date(initialDate),
|
|
62
|
+
);
|
|
36
63
|
if (useDateEnd && isTwoUp) {
|
|
37
64
|
initialMonth -= 1;
|
|
38
65
|
}
|
|
@@ -44,65 +71,111 @@ export default function DatePicker({ className, dateEnd: _dateEnd, dateStart: _d
|
|
|
44
71
|
monthLimitLast -= 1;
|
|
45
72
|
}
|
|
46
73
|
const handleClickLeftArrow = useCallback(() => {
|
|
47
|
-
setMonth((existingMonth) =>
|
|
48
|
-
|
|
49
|
-
|
|
74
|
+
setMonth((existingMonth) =>
|
|
75
|
+
monthLimitFirst == null || existingMonth > monthLimitFirst
|
|
76
|
+
? existingMonth - 1
|
|
77
|
+
: existingMonth,
|
|
78
|
+
);
|
|
50
79
|
}, [monthLimitFirst]);
|
|
51
80
|
const handleClickRightArrow = useCallback(() => {
|
|
52
|
-
setMonth((existingMonth) =>
|
|
53
|
-
|
|
54
|
-
|
|
81
|
+
setMonth((existingMonth) =>
|
|
82
|
+
monthLimitLast == null || existingMonth < monthLimitLast
|
|
83
|
+
? existingMonth + 1
|
|
84
|
+
: existingMonth,
|
|
85
|
+
);
|
|
55
86
|
}, [monthLimitLast]);
|
|
56
|
-
const handleChange = useCallback(
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
87
|
+
const handleChange = useCallback(
|
|
88
|
+
(date) => {
|
|
89
|
+
// If we last set the dateStart or we have a dateStart but no dateEnd, set dateEnd
|
|
90
|
+
if (
|
|
91
|
+
isRange &&
|
|
92
|
+
dateStart != null &&
|
|
93
|
+
(updatingDateEndRef.current || dateEnd == null)
|
|
94
|
+
) {
|
|
95
|
+
// Ensure that dateEnd is after dateStart; if not, swap them
|
|
96
|
+
if (date < dateStart) {
|
|
97
|
+
setDateStart(date);
|
|
98
|
+
setDateEnd(dateStart);
|
|
99
|
+
onChange({ dateEnd: dateStart, dateStart: date });
|
|
100
|
+
} else {
|
|
101
|
+
setDateEnd(date);
|
|
102
|
+
onChange({ dateEnd: date, dateStart });
|
|
103
|
+
}
|
|
104
|
+
updatingDateEndRef.current = false;
|
|
105
|
+
} else {
|
|
63
106
|
setDateStart(date);
|
|
64
|
-
setDateEnd(
|
|
65
|
-
|
|
107
|
+
setDateEnd(null);
|
|
108
|
+
if (isRange) {
|
|
109
|
+
onChange({ dateEnd: null, dateStart: date });
|
|
110
|
+
updatingDateEndRef.current = true;
|
|
111
|
+
} else {
|
|
112
|
+
onChange({ dateStart: date });
|
|
113
|
+
}
|
|
66
114
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
updatingDateEndRef.current = false;
|
|
72
|
-
}
|
|
73
|
-
else {
|
|
74
|
-
setDateStart(date);
|
|
75
|
-
setDateEnd(null);
|
|
76
|
-
if (isRange) {
|
|
77
|
-
onChange({ dateEnd: null, dateStart: date });
|
|
78
|
-
updatingDateEndRef.current = true;
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
onChange({ dateStart: date });
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}, [dateEnd, dateStart, isRange, onChange]);
|
|
115
|
+
},
|
|
116
|
+
[dateEnd, dateStart, isRange, onChange],
|
|
117
|
+
);
|
|
85
118
|
const handleChangeEndPreview = useCallback((date) => {
|
|
86
119
|
setDateEndPreview(date);
|
|
87
120
|
}, []);
|
|
88
|
-
return
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
121
|
+
return React.createElement(
|
|
122
|
+
Fragment,
|
|
123
|
+
null,
|
|
124
|
+
React.createElement(Style, { href: '@acusti/date-picker/DatePicker' }, STYLES),
|
|
125
|
+
React.createElement(
|
|
126
|
+
'div',
|
|
127
|
+
{
|
|
128
|
+
className: clsx(ROOT_CLASS_NAME, className, {
|
|
129
|
+
'two-up': isTwoUp,
|
|
130
|
+
}),
|
|
131
|
+
},
|
|
132
|
+
React.createElement(
|
|
133
|
+
'div',
|
|
134
|
+
{ className: `${ROOT_CLASS_NAME}-range-arrow-wrap` },
|
|
135
|
+
React.createElement('div', {
|
|
136
|
+
className: clsx(`${ROOT_CLASS_NAME}-range-arrow left-arrow`, {
|
|
95
137
|
disabled: monthLimitFirst != null && month <= monthLimitFirst,
|
|
96
|
-
}),
|
|
97
|
-
|
|
138
|
+
}),
|
|
139
|
+
onClick: handleClickLeftArrow,
|
|
140
|
+
}),
|
|
141
|
+
React.createElement('div', {
|
|
142
|
+
className: clsx(`${ROOT_CLASS_NAME}-range-arrow right-arrow`, {
|
|
98
143
|
disabled: monthLimitLast != null && month >= monthLimitLast,
|
|
99
|
-
}),
|
|
100
|
-
|
|
101
|
-
|
|
144
|
+
}),
|
|
145
|
+
onClick: handleClickRightArrow,
|
|
146
|
+
}),
|
|
147
|
+
),
|
|
148
|
+
React.createElement(
|
|
149
|
+
'div',
|
|
150
|
+
{ className: `${ROOT_CLASS_NAME}-month-container` },
|
|
151
|
+
React.createElement(MonthCalendar, {
|
|
152
|
+
dateEnd: dateEnd,
|
|
153
|
+
dateEndPreview: dateEndPreview,
|
|
154
|
+
dateStart: dateStart,
|
|
155
|
+
isRange: isRange,
|
|
156
|
+
month: month,
|
|
157
|
+
onChange: handleChange,
|
|
158
|
+
onChangeEndPreview: handleChangeEndPreview,
|
|
159
|
+
title: useMonthAbbreviations
|
|
102
160
|
? getAbbreviatedMonthTitle(month)
|
|
103
|
-
: undefined
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
161
|
+
: undefined,
|
|
162
|
+
}),
|
|
163
|
+
isTwoUp
|
|
164
|
+
? React.createElement(MonthCalendar, {
|
|
165
|
+
dateEnd: dateEnd,
|
|
166
|
+
dateEndPreview: dateEndPreview,
|
|
167
|
+
dateStart: dateStart,
|
|
168
|
+
isRange: isRange,
|
|
169
|
+
month: month + 1,
|
|
170
|
+
onChange: handleChange,
|
|
171
|
+
onChangeEndPreview: handleChangeEndPreview,
|
|
172
|
+
title: useMonthAbbreviations
|
|
173
|
+
? getAbbreviatedMonthTitle(month + 1)
|
|
174
|
+
: undefined,
|
|
175
|
+
})
|
|
176
|
+
: null,
|
|
177
|
+
),
|
|
178
|
+
),
|
|
179
|
+
);
|
|
107
180
|
}
|
|
108
|
-
//# sourceMappingURL=DatePicker.js.map
|
|
181
|
+
//# sourceMappingURL=DatePicker.js.map
|
package/dist/DatePicker.js.flow
CHANGED
|
@@ -5,27 +5,27 @@
|
|
|
5
5
|
* @flow
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import * as React from
|
|
8
|
+
import * as React from 'react';
|
|
9
9
|
export type Props = {|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
10
|
+
className?: string,
|
|
11
|
+
dateEnd?: Date | number | string,
|
|
12
|
+
dateStart?: Date | number | string,
|
|
13
|
+
initialMonth?: number,
|
|
14
|
+
isRange?: boolean,
|
|
15
|
+
isTwoUp?: boolean,
|
|
16
|
+
monthLimitFirst?: number,
|
|
17
|
+
monthLimitLast?: number,
|
|
18
|
+
onChange: (payload: {|
|
|
19
|
+
dateEnd?: null | string,
|
|
20
|
+
dateStart: string,
|
|
21
|
+
|}) => void,
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Boolean to specify that date picker should initially render with the
|
|
25
|
+
* end date’s month visible. The default behavior is to initially render
|
|
26
|
+
* with the start date’s month visible.
|
|
27
|
+
*/
|
|
28
|
+
showEndInitially?: boolean,
|
|
29
|
+
useMonthAbbreviations?: boolean,
|
|
30
30
|
|};
|
|
31
31
|
declare export default function DatePicker(x: Props): React.Node;
|
package/dist/DatePicker.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatePicker.js","sourceRoot":"","sources":["../src/DatePicker.tsx"],"names":[],"mappings":"AAAA,mGAAmG;AACnG,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,aAAa,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EACH,6BAA6B,EAC7B,gBAAgB,EAChB,gBAAgB,GACnB,MAAM,YAAY,CAAC;AAqBpB,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;AAErE,MAAM,wBAAwB,GAAG,CAAC,KAAa,EAAE,EAAE,CAC/C,GAAG,6BAA6B,CAAC,KAAK,CAAC,IAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;AAEzE,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,EAC/B,SAAS,EACT,OAAO,EAAE,QAAQ,EACjB,SAAS,EAAE,UAAU,EACrB,OAAO,GAAG,QAAQ,IAAI,IAAI,EAC1B,OAAO,EACP,
|
|
1
|
+
{"version":3,"file":"DatePicker.js","sourceRoot":"","sources":["../src/DatePicker.tsx"],"names":[],"mappings":"AAAA,mGAAmG;AACnG,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,aAAa,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EACH,6BAA6B,EAC7B,gBAAgB,EAChB,gBAAgB,GACnB,MAAM,YAAY,CAAC;AAqBpB,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;AAErE,MAAM,wBAAwB,GAAG,CAAC,KAAa,EAAE,EAAE,CAC/C,GAAG,6BAA6B,CAAC,KAAK,CAAC,IAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;AAEzE,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,EAC/B,SAAS,EACT,OAAO,EAAE,QAAQ,EACjB,SAAS,EAAE,UAAU,EACrB,YAAY,EACZ,OAAO,GAAG,QAAQ,IAAI,IAAI,EAC1B,OAAO,EACP,eAAe,EACf,cAAc,EACd,QAAQ,EACR,gBAAgB,EAChB,qBAAqB,GACjB;IACJ,MAAM,gBAAgB,GAClB,QAAQ,IAAI,IAAI,IAAI,OAAO,QAAQ,KAAK,QAAQ;QAC5C,CAAC,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE;QAClC,CAAC,CAAC,QAAQ,CAAC;IACnB,MAAM,kBAAkB,GACpB,UAAU,IAAI,IAAI,IAAI,OAAO,UAAU,KAAK,QAAQ;QAChD,CAAC,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE;QACpC,CAAC,CAAC,UAAU,CAAC;IACrB,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAgB,gBAAgB,aAAhB,gBAAgB,cAAhB,gBAAgB,GAAI,IAAI,CAAC,CAAC;IAChF,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAgB,kBAAkB,aAAlB,kBAAkB,cAAlB,kBAAkB,GAAI,IAAI,CAAC,CAAC;IACtF,MAAM,kBAAkB,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAEzC,SAAS,CAAC,GAAG,EAAE;QACX,IAAI,gBAAgB,IAAI,IAAI;YAAE,OAAO;QACrC,UAAU,CAAC,gBAAgB,CAAC,CAAC;IACjC,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAEvB,SAAS,CAAC,GAAG,EAAE;QACX,IAAI,kBAAkB,IAAI,IAAI;YAAE,OAAO;QACvC,YAAY,CAAC,kBAAkB,CAAC,CAAC;IACrC,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAEzB,IAAI,YAAY,IAAI,IAAI,EAAE,CAAC;QACvB,qEAAqE;QACrE,MAAM,UAAU,GAAG,SAAS,IAAI,IAAI,IAAI,OAAO,CAAC,gBAAgB,IAAI,OAAO,CAAC,CAAC;QAC7E,6BAA6B;QAC7B,MAAM,WAAW,GAAG,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;QACrD,YAAY,GAAG,gBAAgB,CAC3B,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,CAC3D,CAAC;QACF,IAAI,UAAU,IAAI,OAAO,EAAE,CAAC;YACxB,YAAY,IAAI,CAAC,CAAC;QACtB,CAAC;IACL,CAAC;IAED,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAC1E,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAS,YAAY,CAAC,CAAC;IAEzD,2EAA2E;IAC3E,IAAI,OAAO,IAAI,cAAc,IAAI,IAAI,EAAE,CAAC;QACpC,cAAc,IAAI,CAAC,CAAC;IACxB,CAAC;IAED,MAAM,oBAAoB,GAAG,WAAW,CAAC,GAAG,EAAE;QAC1C,QAAQ,CAAC,CAAC,aAAqB,EAAE,EAAE,CAC/B,eAAe,IAAI,IAAI,IAAI,aAAa,GAAG,eAAe;YACtD,CAAC,CAAC,aAAa,GAAG,CAAC;YACnB,CAAC,CAAC,aAAa,CACtB,CAAC;IACN,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC;IAEtB,MAAM,qBAAqB,GAAG,WAAW,CAAC,GAAG,EAAE;QAC3C,QAAQ,CAAC,CAAC,aAAqB,EAAE,EAAE,CAC/B,cAAc,IAAI,IAAI,IAAI,aAAa,GAAG,cAAc;YACpD,CAAC,CAAC,aAAa,GAAG,CAAC;YACnB,CAAC,CAAC,aAAa,CACtB,CAAC;IACN,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;IAErB,MAAM,YAAY,GAAG,WAAW,CAC5B,CAAC,IAAY,EAAE,EAAE;QACb,kFAAkF;QAClF,IACI,OAAO;YACP,SAAS,IAAI,IAAI;YACjB,CAAC,kBAAkB,CAAC,OAAO,IAAI,OAAO,IAAI,IAAI,CAAC,EACjD,CAAC;YACC,4DAA4D;YAC5D,IAAI,IAAI,GAAG,SAAS,EAAE,CAAC;gBACnB,YAAY,CAAC,IAAI,CAAC,CAAC;gBACnB,UAAU,CAAC,SAAS,CAAC,CAAC;gBACtB,QAAQ,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACtD,CAAC;iBAAM,CAAC;gBACJ,UAAU,CAAC,IAAI,CAAC,CAAC;gBACjB,QAAQ,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;YAC3C,CAAC;YACD,kBAAkB,CAAC,OAAO,GAAG,KAAK,CAAC;QACvC,CAAC;aAAM,CAAC;YACJ,YAAY,CAAC,IAAI,CAAC,CAAC;YACnB,UAAU,CAAC,IAAI,CAAC,CAAC;YACjB,IAAI,OAAO,EAAE,CAAC;gBACV,QAAQ,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC7C,kBAAkB,CAAC,OAAO,GAAG,IAAI,CAAC;YACtC,CAAC;iBAAM,CAAC;gBACJ,QAAQ,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAClC,CAAC;QACL,CAAC;IACL,CAAC,EACD,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,CAAC,CAC1C,CAAC;IAEF,MAAM,sBAAsB,GAAG,WAAW,CAAC,CAAC,IAAY,EAAE,EAAE;QACxD,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,CACH,oBAAC,QAAQ;QACL,oBAAC,KAAK,IAAC,IAAI,EAAC,gCAAgC,IAAE,MAAM,CAAS;QAC7D,6BACI,SAAS,EAAE,IAAI,CAAC,eAAe,EAAE,SAAS,EAAE;gBACxC,QAAQ,EAAE,OAAO;aACpB,CAAC;YAEF,6BAAK,SAAS,EAAE,GAAG,eAAe,mBAAmB;gBACjD,6BACI,SAAS,EAAE,IAAI,CAAC,GAAG,eAAe,yBAAyB,EAAE;wBACzD,QAAQ,EAAE,eAAe,IAAI,IAAI,IAAI,KAAK,IAAI,eAAe;qBAChE,CAAC,EACF,OAAO,EAAE,oBAAoB,GAC/B;gBACF,6BACI,SAAS,EAAE,IAAI,CAAC,GAAG,eAAe,0BAA0B,EAAE;wBAC1D,QAAQ,EAAE,cAAc,IAAI,IAAI,IAAI,KAAK,IAAI,cAAc;qBAC9D,CAAC,EACF,OAAO,EAAE,qBAAqB,GAChC,CACA;YACN,6BAAK,SAAS,EAAE,GAAG,eAAe,kBAAkB;gBAChD,oBAAC,aAAa,IACV,OAAO,EAAE,OAAO,EAChB,cAAc,EAAE,cAAc,EAC9B,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,YAAY,EACtB,kBAAkB,EAAE,sBAAsB,EAC1C,KAAK,EACD,qBAAqB;wBACjB,CAAC,CAAC,wBAAwB,CAAC,KAAK,CAAC;wBACjC,CAAC,CAAC,SAAS,GAErB;gBACD,OAAO,CAAC,CAAC,CAAC,CACP,oBAAC,aAAa,IACV,OAAO,EAAE,OAAO,EAChB,cAAc,EAAE,cAAc,EAC9B,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,KAAK,GAAG,CAAC,EAChB,QAAQ,EAAE,YAAY,EACtB,kBAAkB,EAAE,sBAAsB,EAC1C,KAAK,EACD,qBAAqB;wBACjB,CAAC,CAAC,wBAAwB,CAAC,KAAK,GAAG,CAAC,CAAC;wBACrC,CAAC,CAAC,SAAS,GAErB,CACL,CAAC,CAAC,CAAC,IAAI,CACN,CACJ,CACC,CACd,CAAC;AACN,CAAC"}
|
package/dist/MonthCalendar.d.ts
CHANGED
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
export type Props = {
|
|
3
3
|
className?: string;
|
|
4
|
-
dateEnd?: Date |
|
|
5
|
-
dateEndPreview?:
|
|
6
|
-
dateStart?: Date |
|
|
4
|
+
dateEnd?: Date | null | number | string;
|
|
5
|
+
dateEndPreview?: null | string;
|
|
6
|
+
dateStart?: Date | null | number | string;
|
|
7
7
|
isRange?: boolean;
|
|
8
8
|
month: number;
|
|
9
9
|
onChange?: (date: string) => void;
|
|
10
10
|
onChangeEndPreview?: (date: string) => void;
|
|
11
11
|
title?: string;
|
|
12
12
|
};
|
|
13
|
-
export default function MonthCalendar({
|
|
13
|
+
export default function MonthCalendar({
|
|
14
|
+
className,
|
|
15
|
+
dateEnd,
|
|
16
|
+
dateEndPreview,
|
|
17
|
+
dateStart,
|
|
18
|
+
isRange,
|
|
19
|
+
month,
|
|
20
|
+
onChange,
|
|
21
|
+
onChangeEndPreview,
|
|
22
|
+
title,
|
|
23
|
+
}: Props): React.JSX.Element;
|
package/dist/MonthCalendar.js
CHANGED
|
@@ -2,12 +2,31 @@ import { Style } from '@acusti/styling';
|
|
|
2
2
|
import clsx from 'clsx';
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { ROOT_CLASS_NAME, STYLES } from './styles/month-calendar.js';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
getDateFromMonthAndDay,
|
|
7
|
+
getLastDateFromMonth,
|
|
8
|
+
getMonthFromDate,
|
|
9
|
+
getMonthNameFromMonth,
|
|
10
|
+
getYearFromMonth,
|
|
11
|
+
} from './utils.js';
|
|
6
12
|
const { Fragment, useCallback } = React;
|
|
7
13
|
const DAYS = Array(7).fill(null);
|
|
8
|
-
export default function MonthCalendar({
|
|
14
|
+
export default function MonthCalendar({
|
|
15
|
+
className,
|
|
16
|
+
dateEnd,
|
|
17
|
+
dateEndPreview,
|
|
18
|
+
dateStart,
|
|
19
|
+
isRange,
|
|
20
|
+
month,
|
|
21
|
+
onChange,
|
|
22
|
+
onChangeEndPreview,
|
|
23
|
+
title,
|
|
24
|
+
}) {
|
|
9
25
|
const year = getYearFromMonth(month);
|
|
10
|
-
title =
|
|
26
|
+
title =
|
|
27
|
+
title !== null && title !== void 0
|
|
28
|
+
? title
|
|
29
|
+
: `${getMonthNameFromMonth(month)} ${year}`;
|
|
11
30
|
const firstDate = getDateFromMonthAndDay(month, 1);
|
|
12
31
|
const lastDate = getLastDateFromMonth(month);
|
|
13
32
|
const totalDays = lastDate.getDate();
|
|
@@ -18,88 +37,198 @@ export default function MonthCalendar({ className, dateEnd, dateEndPreview, date
|
|
|
18
37
|
dateStart,
|
|
19
38
|
dateEnd,
|
|
20
39
|
dateEndPreview,
|
|
21
|
-
].reduce(
|
|
22
|
-
|
|
23
|
-
date
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
return acc;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
acc[index] =
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
acc[index - 1] = endDay;
|
|
40
|
-
acc[index] = startDay;
|
|
40
|
+
].reduce(
|
|
41
|
+
(acc, date, index) => {
|
|
42
|
+
if (date != null && !(date instanceof Date)) {
|
|
43
|
+
date = new Date(date);
|
|
44
|
+
}
|
|
45
|
+
if (date == null || Number.isNaN(date.getTime())) return acc;
|
|
46
|
+
const dateMonth = getMonthFromDate(date);
|
|
47
|
+
if (dateMonth < month) acc[index] = -1;
|
|
48
|
+
else if (dateMonth > month) acc[index] = totalDays + 1;
|
|
49
|
+
else acc[index] = date.getDate();
|
|
50
|
+
if (index === 1) {
|
|
51
|
+
const startDay = acc[index - 1];
|
|
52
|
+
const endDay = acc[index];
|
|
53
|
+
// Ensure that end date is after start date and swap them if not
|
|
54
|
+
if (startDay != null && endDay != null && startDay > endDay) {
|
|
55
|
+
acc[index - 1] = endDay;
|
|
56
|
+
acc[index] = startDay;
|
|
57
|
+
}
|
|
41
58
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
onChange(date);
|
|
49
|
-
}, [onChange]);
|
|
50
|
-
const handleMouseEnterDay = useCallback((event) => {
|
|
51
|
-
if (isRange && onChangeEndPreview) {
|
|
59
|
+
return acc;
|
|
60
|
+
},
|
|
61
|
+
[null, null, null],
|
|
62
|
+
);
|
|
63
|
+
const handleClickDay = useCallback(
|
|
64
|
+
(event) => {
|
|
52
65
|
const { date } = event.currentTarget.dataset;
|
|
53
|
-
if (date)
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
'
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
66
|
+
if (date && onChange) onChange(date);
|
|
67
|
+
},
|
|
68
|
+
[onChange],
|
|
69
|
+
);
|
|
70
|
+
const handleMouseEnterDay = useCallback(
|
|
71
|
+
(event) => {
|
|
72
|
+
if (isRange && onChangeEndPreview) {
|
|
73
|
+
const { date } = event.currentTarget.dataset;
|
|
74
|
+
if (date) onChangeEndPreview(date);
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
[isRange, onChangeEndPreview],
|
|
78
|
+
);
|
|
79
|
+
return React.createElement(
|
|
80
|
+
Fragment,
|
|
81
|
+
null,
|
|
82
|
+
React.createElement(Style, { href: '@acusti/date-picker/MonthCalendar' }, STYLES),
|
|
83
|
+
React.createElement(
|
|
84
|
+
'div',
|
|
85
|
+
{ className: clsx(ROOT_CLASS_NAME, className) },
|
|
86
|
+
React.createElement(
|
|
87
|
+
'div',
|
|
88
|
+
{ className: `${ROOT_CLASS_NAME}-month-title` },
|
|
89
|
+
React.createElement(
|
|
90
|
+
'h3',
|
|
91
|
+
{ className: `${ROOT_CLASS_NAME}-month-title-text` },
|
|
92
|
+
title,
|
|
93
|
+
),
|
|
94
|
+
),
|
|
95
|
+
React.createElement(
|
|
96
|
+
'div',
|
|
97
|
+
{ className: `${ROOT_CLASS_NAME}-month-week` },
|
|
98
|
+
React.createElement(
|
|
99
|
+
'div',
|
|
100
|
+
{ className: 'week-day-item' },
|
|
101
|
+
React.createElement(
|
|
102
|
+
'span',
|
|
103
|
+
{ className: 'week-day-item-text' },
|
|
104
|
+
'Su',
|
|
105
|
+
),
|
|
106
|
+
),
|
|
107
|
+
React.createElement(
|
|
108
|
+
'div',
|
|
109
|
+
{ className: 'week-day-item' },
|
|
110
|
+
React.createElement(
|
|
111
|
+
'span',
|
|
112
|
+
{ className: 'week-day-item-text' },
|
|
113
|
+
'Mo',
|
|
114
|
+
),
|
|
115
|
+
),
|
|
116
|
+
React.createElement(
|
|
117
|
+
'div',
|
|
118
|
+
{ className: 'week-day-item' },
|
|
119
|
+
React.createElement(
|
|
120
|
+
'span',
|
|
121
|
+
{ className: 'week-day-item-text' },
|
|
122
|
+
'Tu',
|
|
123
|
+
),
|
|
124
|
+
),
|
|
125
|
+
React.createElement(
|
|
126
|
+
'div',
|
|
127
|
+
{ className: 'week-day-item' },
|
|
128
|
+
React.createElement(
|
|
129
|
+
'span',
|
|
130
|
+
{ className: 'week-day-item-text' },
|
|
131
|
+
'We',
|
|
132
|
+
),
|
|
133
|
+
),
|
|
134
|
+
React.createElement(
|
|
135
|
+
'div',
|
|
136
|
+
{ className: 'week-day-item' },
|
|
137
|
+
React.createElement(
|
|
138
|
+
'span',
|
|
139
|
+
{ className: 'week-day-item-text' },
|
|
140
|
+
'Th',
|
|
141
|
+
),
|
|
142
|
+
),
|
|
143
|
+
React.createElement(
|
|
144
|
+
'div',
|
|
145
|
+
{ className: 'week-day-item' },
|
|
146
|
+
React.createElement(
|
|
147
|
+
'span',
|
|
148
|
+
{ className: 'week-day-item-text' },
|
|
149
|
+
'Fr',
|
|
150
|
+
),
|
|
151
|
+
),
|
|
152
|
+
React.createElement(
|
|
153
|
+
'div',
|
|
154
|
+
{ className: 'week-day-item' },
|
|
155
|
+
React.createElement(
|
|
156
|
+
'span',
|
|
157
|
+
{ className: 'week-day-item-text' },
|
|
158
|
+
'Sa',
|
|
159
|
+
),
|
|
160
|
+
),
|
|
161
|
+
),
|
|
162
|
+
React.createElement(
|
|
163
|
+
'div',
|
|
164
|
+
{ className: `${ROOT_CLASS_NAME}-month-days` },
|
|
165
|
+
Array(Math.floor(daySpaces / 7))
|
|
166
|
+
.fill(null)
|
|
167
|
+
.map((_, weekIndex) =>
|
|
168
|
+
React.createElement(
|
|
169
|
+
'div',
|
|
170
|
+
{
|
|
171
|
+
className: `${ROOT_CLASS_NAME}-month-row`,
|
|
172
|
+
key: `MonthRow-${weekIndex}`,
|
|
173
|
+
},
|
|
174
|
+
DAYS.map((__, dayIndex) => {
|
|
175
|
+
dayIndex += weekIndex * 7;
|
|
176
|
+
const dayNumber = (dayIndex - firstDay) + 1; // prettier-ignore
|
|
177
|
+
const isEmpty = dayNumber < 1 || dayNumber > totalDays;
|
|
178
|
+
const date = isEmpty
|
|
179
|
+
? null
|
|
180
|
+
: getDateFromMonthAndDay(month, dayNumber);
|
|
181
|
+
const isAfterDateRangeStart =
|
|
182
|
+
dateRangeStartDay != null &&
|
|
183
|
+
dayNumber > dateRangeStartDay;
|
|
184
|
+
const isBeforeDateRangeEnd =
|
|
185
|
+
(dateRangeEndDay == null &&
|
|
186
|
+
dateRangeEndPreviewDay != null &&
|
|
187
|
+
dayNumber < dateRangeEndPreviewDay) ||
|
|
188
|
+
(dateRangeEndDay != null &&
|
|
189
|
+
dayNumber < dateRangeEndDay);
|
|
190
|
+
return React.createElement(
|
|
191
|
+
'button',
|
|
192
|
+
{
|
|
193
|
+
className: clsx(
|
|
194
|
+
`${ROOT_CLASS_NAME}-month-day-item`,
|
|
195
|
+
{
|
|
196
|
+
'end-date':
|
|
197
|
+
!isEmpty &&
|
|
198
|
+
dayNumber === dateRangeEndDay,
|
|
199
|
+
'is-empty': isEmpty,
|
|
200
|
+
'is-selected':
|
|
201
|
+
!isEmpty &&
|
|
202
|
+
isAfterDateRangeStart &&
|
|
203
|
+
isBeforeDateRangeEnd,
|
|
204
|
+
'start-date':
|
|
205
|
+
!isEmpty &&
|
|
206
|
+
dayNumber === dateRangeStartDay,
|
|
207
|
+
},
|
|
208
|
+
),
|
|
209
|
+
'data-date':
|
|
210
|
+
date === null || date === void 0
|
|
211
|
+
? void 0
|
|
212
|
+
: date.toISOString(),
|
|
213
|
+
disabled: isEmpty,
|
|
214
|
+
key: `MonthDayItem-${dayNumber}`,
|
|
215
|
+
onClick: handleClickDay,
|
|
216
|
+
onMouseEnter: handleMouseEnterDay,
|
|
217
|
+
type: 'button',
|
|
218
|
+
},
|
|
219
|
+
isEmpty
|
|
220
|
+
? null
|
|
221
|
+
: React.createElement(
|
|
222
|
+
'span',
|
|
223
|
+
{ className: 'month-day-item-text' },
|
|
224
|
+
dayNumber,
|
|
225
|
+
),
|
|
226
|
+
);
|
|
227
|
+
}),
|
|
228
|
+
),
|
|
229
|
+
),
|
|
230
|
+
),
|
|
231
|
+
),
|
|
232
|
+
);
|
|
104
233
|
}
|
|
105
|
-
//# sourceMappingURL=MonthCalendar.js.map
|
|
234
|
+
//# sourceMappingURL=MonthCalendar.js.map
|
|
@@ -5,16 +5,16 @@
|
|
|
5
5
|
* @flow
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import * as React from
|
|
8
|
+
import * as React from 'react';
|
|
9
9
|
export type Props = {|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
10
|
+
className?: string,
|
|
11
|
+
dateEnd?: Date | null | number | string,
|
|
12
|
+
dateEndPreview?: null | string,
|
|
13
|
+
dateStart?: Date | null | number | string,
|
|
14
|
+
isRange?: boolean,
|
|
15
|
+
month: number,
|
|
16
|
+
onChange?: (date: string) => void,
|
|
17
|
+
onChangeEndPreview?: (date: string) => void,
|
|
18
|
+
title?: string,
|
|
19
19
|
|};
|
|
20
20
|
declare export default function MonthCalendar(x: Props): React.Node;
|
package/dist/index.js
CHANGED
package/dist/index.js.flow
CHANGED
|
@@ -5,6 +5,6 @@
|
|
|
5
5
|
* @flow
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
declare export { default as DatePicker } from
|
|
9
|
-
declare export { default as MonthCalendar } from
|
|
10
|
-
declare export * from
|
|
8
|
+
declare export { default as DatePicker } from './DatePicker.js';
|
|
9
|
+
declare export { default as MonthCalendar } from './MonthCalendar.js';
|
|
10
|
+
declare export * from './utils.js';
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
export declare const ROOT_CLASS_NAME =
|
|
2
|
-
export declare const STYLES =
|
|
1
|
+
export declare const ROOT_CLASS_NAME = 'uktdatepicker';
|
|
2
|
+
export declare const STYLES =
|
|
3
|
+
'\n.uktdatepicker {\n display: flex;\n box-sizing: border-box;\n padding: 40px 60px 60px;\n flex: 1 1 auto;\n position: relative;\n max-width: 450px;\n}\n\n.uktdatepicker.two-up {\n max-width: 820px;\n}\n\n.uktdatepicker-range-arrow-wrap {\n position: absolute;\n top: 30px;\n left: 0px;\n display: flex;\n justify-content: space-between;\n height: 0px;\n width: 100%;\n padding: 0px 60px;\n box-sizing: border-box;\n}\n\n.uktdatepicker-range-arrow {\n width: 35px;\n height: 35px;\n text-align: center;\n cursor: pointer;\n}\n\n.uktdatepicker-range-arrow.disabled {\n color: #ccc;\n cursor: default;\n}\n\n.uktdatepicker-range-arrow:active {\n transform: translateY(1px);\n}\n\n.uktdatepicker-range-arrow.left-arrow:after,\n.uktdatepicker-range-arrow.right-arrow:after {\n content: "\u2039";\n font-size: 24px;\n line-height: 35px;\n font-weight: bold;\n}\n\n.uktdatepicker-range-arrow.right-arrow:after {\n content: "\u203A";\n}\n\n.uktdatepicker-month-container {\n display: flex;\n flex: 1 1 auto;\n justify-content: space-between;\n}\n';
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
export declare const ROOT_CLASS_NAME =
|
|
2
|
-
export declare const STYLES =
|
|
1
|
+
export declare const ROOT_CLASS_NAME = 'uktmonthcalendar';
|
|
2
|
+
export declare const STYLES =
|
|
3
|
+
'\n.uktmonthcalendar {\n display: flex;\n flex-direction: column;\n flex: 1 1 auto;\n box-sizing: border-box;\n max-width: 325px;\n}\n\n.uktmonthcalendar-month-title {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 auto;\n box-sizing: border-box;\n padding-bottom: 25px;\n}\n\nh3.uktmonthcalendar-month-title-text {\n font-size: 18px;\n line-height: 23px;\n font-weight: 600;\n color: #000;\n margin: 0px;\n text-align: center;\n}\n\n.uktmonthcalendar-month-week {\n flex: 0 0 auto;\n display: grid;\n grid-column-gap: 0px;\n grid-template-columns: repeat(auto-fit, minmax(46px, 1fr));\n grid-auto-flow: dense;\n box-sizing: border-box;\n padding-bottom: 12px;\n}\n\n.uktmonthcalendar-month-week .week-day-item {\n flex: 1 1 auto;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n.uktmonthcalendar-month-week span.week-day-item-text {\n text-align: center;\n font-size: 13px;\n line-height: 21px;\n margin: 0px;\n color: #9a9a9a;\n}\n\n.uktmonthcalendar-month-days {\n flex: 1 1 auto;\n display: flex;\n flex-direction: column;\n}\n\n.uktmonthcalendar-month-row {\n flex: 1 1 auto;\n display: grid;\n grid-column-gap: 0px;\n grid-template-columns: repeat(auto-fit, minmax(46px, 1fr));\n grid-auto-flow: dense;\n margin-bottom: 1px;\n}\n\n.uktmonthcalendar-month-day-item {\n display: flex;\n justify-content: center;\n align-items: center;\n position: relative;\n height: 46px;\n width: 46px;\n cursor: pointer;\n border: none;\n background-color: transparent;\n}\n\n.uktmonthcalendar-month-day-item:disabled {\n cursor: auto;\n}\n\n.uktmonthcalendar-month-day-item.is-selected {\n background-color: #f8f8f8;\n}\n\n.uktmonthcalendar-month-day-item.start-date {\n background-color: #f8f8f8;\n border-top-left-radius: 50%;\n border-bottom-left-radius: 50%;\n}\n\n.uktmonthcalendar-month-day-item.start-date:after {\n background-color: #000;\n opacity: 1;\n visibility: visible;\n}\n.uktmonthcalendar-month-day-item.start-date span.month-day-item-text {\n color: #fff;\n}\n\n.uktmonthcalendar-month-day-item.end-date {\n background-color: #f8f8f8;\n border-top-right-radius: 50%;\n border-bottom-right-radius: 50%;\n}\n\n.uktmonthcalendar-month-day-item.end-date:after {\n background-color: #000;\n opacity: 1;\n visibility: visible;\n}\n.uktmonthcalendar-month-day-item.end-date span.month-day-item-text {\n color: #fff;\n}\n\n.uktmonthcalendar-month-day-item:hover:after {\n opacity: 1;\n visibility: visible;\n}\n\n.uktmonthcalendar-month-day-item:after {\n content: "";\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n pointer-events: none;\n border-radius: 50%;\n border: 1px solid #000;\n width: 43px;\n height: 43px;\n transition: opacity 0.25s ease-in-out;\n opacity: 0;\n visibility: hidden;\n}\n\n.uktmonthcalendar-month-day-item.is-empty:after {\n content: none;\n}\n\n.uktmonthcalendar-month-day-item span.month-day-item-text {\n text-align: center;\n font-size: 13px;\n line-height: 21px;\n margin: 0px;\n color: #000;\n position: relative;\n z-index: 1;\n}\n';
|
package/dist/utils.d.ts
CHANGED
|
@@ -2,5 +2,9 @@ export declare const getMonthFromDate: (date: Date, asUTC?: boolean) => number;
|
|
|
2
2
|
export declare const getYearFromMonth: (month: number) => number;
|
|
3
3
|
export declare const getMonthNameFromMonth: (month: number) => string;
|
|
4
4
|
export declare const getMonthAbbreviationFromMonth: (month: number) => string;
|
|
5
|
-
export declare const getDateFromMonthAndDay: (
|
|
5
|
+
export declare const getDateFromMonthAndDay: (
|
|
6
|
+
month: number,
|
|
7
|
+
day: number,
|
|
8
|
+
asUTC?: boolean,
|
|
9
|
+
) => Date;
|
|
6
10
|
export declare const getLastDateFromMonth: (month: number, asUTC?: boolean) => Date;
|
package/dist/utils.js
CHANGED
|
@@ -15,7 +15,8 @@ const MONTH_NAMES = [
|
|
|
15
15
|
'November',
|
|
16
16
|
'December',
|
|
17
17
|
];
|
|
18
|
-
const getYearFromDate = (date, asUTC) =>
|
|
18
|
+
const getYearFromDate = (date, asUTC) =>
|
|
19
|
+
(asUTC ? date.getUTCFullYear() : date.getFullYear()) - START_YEAR;
|
|
19
20
|
export const getMonthFromDate = (date, asUTC) => {
|
|
20
21
|
const yearAsMonths = getYearFromDate(date, asUTC) * 12;
|
|
21
22
|
return yearAsMonths + (asUTC ? date.getUTCMonth() : date.getMonth());
|
|
@@ -23,16 +24,13 @@ export const getMonthFromDate = (date, asUTC) => {
|
|
|
23
24
|
export const getYearFromMonth = (month) => Math.floor(month / 12) + START_YEAR;
|
|
24
25
|
export const getMonthNameFromMonth = (month) => {
|
|
25
26
|
let index = month % 12;
|
|
26
|
-
if (Number.isNaN(index))
|
|
27
|
-
|
|
28
|
-
if (index < 0)
|
|
29
|
-
index = 12 + index;
|
|
27
|
+
if (Number.isNaN(index)) return '';
|
|
28
|
+
if (index < 0) index = 12 + index;
|
|
30
29
|
return MONTH_NAMES[index];
|
|
31
30
|
};
|
|
32
31
|
export const getMonthAbbreviationFromMonth = (month) => {
|
|
33
32
|
const monthName = getMonthNameFromMonth(month);
|
|
34
|
-
if (monthName === 'September')
|
|
35
|
-
return 'Sept';
|
|
33
|
+
if (monthName === 'September') return 'Sept';
|
|
36
34
|
return monthName.substring(0, 3);
|
|
37
35
|
};
|
|
38
36
|
export const getDateFromMonthAndDay = (month, day, asUTC) => {
|
|
@@ -46,4 +44,4 @@ export const getLastDateFromMonth = (month, asUTC) => {
|
|
|
46
44
|
// day 0 of the next month is the last day of the current month
|
|
47
45
|
return getDateFromMonthAndDay(month + 1, 0, asUTC);
|
|
48
46
|
};
|
|
49
|
-
//# sourceMappingURL=utils.js.map
|
|
47
|
+
//# sourceMappingURL=utils.js.map
|
package/dist/utils.js.flow
CHANGED
|
@@ -10,11 +10,8 @@ declare export var getYearFromMonth: (month: number) => number;
|
|
|
10
10
|
declare export var getMonthNameFromMonth: (month: number) => string;
|
|
11
11
|
declare export var getMonthAbbreviationFromMonth: (month: number) => string;
|
|
12
12
|
declare export var getDateFromMonthAndDay: (
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
) => Date;
|
|
17
|
-
declare export var getLastDateFromMonth: (
|
|
18
|
-
month: number,
|
|
19
|
-
asUTC?: boolean
|
|
13
|
+
month: number,
|
|
14
|
+
day: number,
|
|
15
|
+
asUTC?: boolean,
|
|
20
16
|
) => Date;
|
|
17
|
+
declare export var getLastDateFromMonth: (month: number, asUTC?: boolean) => Date;
|
package/dist/utils.test.js
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
getDateFromMonthAndDay,
|
|
4
|
+
getLastDateFromMonth,
|
|
5
|
+
getMonthFromDate,
|
|
6
|
+
getMonthNameFromMonth,
|
|
7
|
+
getYearFromMonth,
|
|
8
|
+
} from './utils.js';
|
|
3
9
|
const INVALID_DATE = new Date('');
|
|
4
10
|
describe('@acusti/date-picker', () => {
|
|
5
11
|
describe('utils', () => {
|
|
@@ -17,7 +23,9 @@ describe('@acusti/date-picker', () => {
|
|
|
17
23
|
expect(getMonthFromDate(date, true)).toBe(0);
|
|
18
24
|
// if test is run in a timezone behind UTC, ommitting asUTC returns -1
|
|
19
25
|
// if not, the month should be the same with or without asUTC flag
|
|
20
|
-
expect(getMonthFromDate(date)).toBe(
|
|
26
|
+
expect(getMonthFromDate(date)).toBe(
|
|
27
|
+
date.getTimezoneOffset() >= 60 ? -1 : 0,
|
|
28
|
+
);
|
|
21
29
|
});
|
|
22
30
|
it('returns NaN for an Invalid Date', () => {
|
|
23
31
|
expect(getMonthFromDate(INVALID_DATE)).toBe(NaN);
|
|
@@ -25,12 +33,20 @@ describe('@acusti/date-picker', () => {
|
|
|
25
33
|
});
|
|
26
34
|
describe('getYearFromMonth', () => {
|
|
27
35
|
it('returns the correct year for a post-unix epoch date', () => {
|
|
28
|
-
expect(getYearFromMonth(getMonthFromDate(new Date(1970, 0, 1)))).toBe(
|
|
29
|
-
|
|
36
|
+
expect(getYearFromMonth(getMonthFromDate(new Date(1970, 0, 1)))).toBe(
|
|
37
|
+
1970,
|
|
38
|
+
);
|
|
39
|
+
expect(getYearFromMonth(getMonthFromDate(new Date(2048, 4, 31)))).toBe(
|
|
40
|
+
2048,
|
|
41
|
+
);
|
|
30
42
|
});
|
|
31
43
|
it('returns the correct year digit for a pre-unix epoch date', () => {
|
|
32
|
-
expect(getYearFromMonth(getMonthFromDate(new Date(1970, 0, 0)))).toBe(
|
|
33
|
-
|
|
44
|
+
expect(getYearFromMonth(getMonthFromDate(new Date(1970, 0, 0)))).toBe(
|
|
45
|
+
1969,
|
|
46
|
+
);
|
|
47
|
+
expect(getYearFromMonth(getMonthFromDate(new Date(100, 11, 31)))).toBe(
|
|
48
|
+
100,
|
|
49
|
+
);
|
|
34
50
|
});
|
|
35
51
|
it('returns NaN for an Invalid Date', () => {
|
|
36
52
|
expect(getYearFromMonth(getMonthFromDate(INVALID_DATE))).toBe(NaN);
|
|
@@ -38,10 +54,14 @@ describe('@acusti/date-picker', () => {
|
|
|
38
54
|
});
|
|
39
55
|
describe('getMonthNameFromMonth', () => {
|
|
40
56
|
it('returns the correct month name for a post-unix epoch month', () => {
|
|
41
|
-
expect(
|
|
57
|
+
expect(
|
|
58
|
+
getMonthNameFromMonth(getMonthFromDate(new Date(2023, 5, 19))),
|
|
59
|
+
).toBe('June');
|
|
42
60
|
});
|
|
43
61
|
it('returns the correct month name for a pre-unix epoch month', () => {
|
|
44
|
-
expect(
|
|
62
|
+
expect(
|
|
63
|
+
getMonthNameFromMonth(getMonthFromDate(new Date(1865, 5, 2))),
|
|
64
|
+
).toBe('June');
|
|
45
65
|
});
|
|
46
66
|
it('returns an empty string if given NaN (e.g. if dealing with an Invalid Date)', () => {
|
|
47
67
|
expect(getMonthNameFromMonth(getMonthFromDate(INVALID_DATE))).toBe('');
|
|
@@ -49,40 +69,76 @@ describe('@acusti/date-picker', () => {
|
|
|
49
69
|
});
|
|
50
70
|
describe('getDateFromMonthAndDay', () => {
|
|
51
71
|
it('returns the date of the specified day for a post-unix epoch month', () => {
|
|
52
|
-
expect(
|
|
53
|
-
|
|
54
|
-
|
|
72
|
+
expect(
|
|
73
|
+
getDateFromMonthAndDay(getMonthFromDate(new Date(2008, 2, 13)), 1),
|
|
74
|
+
).toEqual(new Date(2008, 2, 1));
|
|
75
|
+
expect(
|
|
76
|
+
getDateFromMonthAndDay(getMonthFromDate(new Date(1999, 11, 1)), 31),
|
|
77
|
+
).toEqual(new Date(1999, 11, 31));
|
|
78
|
+
expect(
|
|
79
|
+
getDateFromMonthAndDay(getMonthFromDate(new Date(2000, 0, 0)), 31),
|
|
80
|
+
).toEqual(new Date(1999, 11, 31));
|
|
55
81
|
});
|
|
56
82
|
it('returns the correct date for a pre-unix epoch month', () => {
|
|
57
|
-
expect(
|
|
58
|
-
|
|
83
|
+
expect(
|
|
84
|
+
getDateFromMonthAndDay(getMonthFromDate(new Date(1865, 5, 2)), 30),
|
|
85
|
+
).toEqual(new Date(1865, 5, 30));
|
|
86
|
+
expect(
|
|
87
|
+
getDateFromMonthAndDay(getMonthFromDate(new Date(101, 0, 0)), 1),
|
|
88
|
+
).toEqual(new Date(100, 11, 1));
|
|
59
89
|
});
|
|
60
90
|
it('returns date for start of day as UTC time if asUTC is true', () => {
|
|
61
|
-
expect(
|
|
62
|
-
|
|
91
|
+
expect(
|
|
92
|
+
getDateFromMonthAndDay(
|
|
93
|
+
getMonthFromDate(new Date(1865, 5, 2)),
|
|
94
|
+
30,
|
|
95
|
+
true,
|
|
96
|
+
),
|
|
97
|
+
).toEqual(new Date(Date.UTC(1865, 5, 30)));
|
|
98
|
+
expect(
|
|
99
|
+
getDateFromMonthAndDay(
|
|
100
|
+
getMonthFromDate(new Date(101, 0, 0)),
|
|
101
|
+
1,
|
|
102
|
+
true,
|
|
103
|
+
),
|
|
104
|
+
).toEqual(new Date(Date.UTC(100, 11, 1)));
|
|
63
105
|
});
|
|
64
106
|
it('returns an invalid date if given NaN (e.g. if dealing with an Invalid Date)', () => {
|
|
65
|
-
expect(getDateFromMonthAndDay(getMonthFromDate(INVALID_DATE), 1)).toEqual(
|
|
107
|
+
expect(getDateFromMonthAndDay(getMonthFromDate(INVALID_DATE), 1)).toEqual(
|
|
108
|
+
INVALID_DATE,
|
|
109
|
+
);
|
|
66
110
|
});
|
|
67
111
|
});
|
|
68
112
|
describe('getLastDateFromMonth', () => {
|
|
69
113
|
it('returns the date of the last day for a post-unix epoch month', () => {
|
|
70
|
-
expect(
|
|
114
|
+
expect(
|
|
115
|
+
getLastDateFromMonth(getMonthFromDate(new Date(2008, 2, 13))),
|
|
116
|
+
).toEqual(new Date(2008, 2, 31));
|
|
71
117
|
// february in a leap year
|
|
72
|
-
expect(
|
|
118
|
+
expect(
|
|
119
|
+
getLastDateFromMonth(getMonthFromDate(new Date(2024, 1, 23))),
|
|
120
|
+
).toEqual(new Date(2024, 1, 29));
|
|
73
121
|
// february in a non-leap year
|
|
74
|
-
expect(
|
|
122
|
+
expect(
|
|
123
|
+
getLastDateFromMonth(getMonthFromDate(new Date(1985, 1, 1))),
|
|
124
|
+
).toEqual(new Date(1985, 1, 28));
|
|
75
125
|
});
|
|
76
126
|
it('returns the correct date for a pre-unix epoch month', () => {
|
|
77
|
-
expect(
|
|
127
|
+
expect(
|
|
128
|
+
getLastDateFromMonth(getMonthFromDate(new Date(1865, 5, 2))),
|
|
129
|
+
).toEqual(new Date(1865, 5, 30));
|
|
78
130
|
});
|
|
79
131
|
it('returns date for start of day as UTC time if asUTC is true', () => {
|
|
80
|
-
expect(
|
|
132
|
+
expect(
|
|
133
|
+
getLastDateFromMonth(getMonthFromDate(new Date(1865, 5, 2)), true),
|
|
134
|
+
).toEqual(new Date(Date.UTC(1865, 5, 30)));
|
|
81
135
|
});
|
|
82
136
|
it('returns an invalid date if given NaN (e.g. if dealing with an Invalid Date)', () => {
|
|
83
|
-
expect(getLastDateFromMonth(getMonthFromDate(INVALID_DATE))).toEqual(
|
|
137
|
+
expect(getLastDateFromMonth(getMonthFromDate(INVALID_DATE))).toEqual(
|
|
138
|
+
INVALID_DATE,
|
|
139
|
+
);
|
|
84
140
|
});
|
|
85
141
|
});
|
|
86
142
|
});
|
|
87
143
|
});
|
|
88
|
-
//# sourceMappingURL=utils.test.js.map
|
|
144
|
+
//# sourceMappingURL=utils.test.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@acusti/date-picker",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"exports": "./dist/index.js",
|
|
@@ -49,11 +49,11 @@
|
|
|
49
49
|
"happy-dom": "^15.11.7",
|
|
50
50
|
"react": "^19.0.0",
|
|
51
51
|
"react-dom": "^19.0.0",
|
|
52
|
-
"typescript": "5.
|
|
52
|
+
"typescript": "5.7.3",
|
|
53
53
|
"vitest": "^2.1.8"
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@acusti/styling": "^1",
|
|
56
|
+
"@acusti/styling": "^1.0.1",
|
|
57
57
|
"clsx": "^2"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
package/src/DatePicker.tsx
CHANGED
|
@@ -13,14 +13,14 @@ import {
|
|
|
13
13
|
|
|
14
14
|
export type Props = {
|
|
15
15
|
className?: string;
|
|
16
|
-
dateEnd?: Date |
|
|
17
|
-
dateStart?: Date |
|
|
16
|
+
dateEnd?: Date | number | string;
|
|
17
|
+
dateStart?: Date | number | string;
|
|
18
18
|
initialMonth?: number;
|
|
19
19
|
isRange?: boolean;
|
|
20
20
|
isTwoUp?: boolean;
|
|
21
21
|
monthLimitFirst?: number;
|
|
22
22
|
monthLimitLast?: number;
|
|
23
|
-
onChange: (payload: { dateEnd?:
|
|
23
|
+
onChange: (payload: { dateEnd?: null | string; dateStart: string }) => void;
|
|
24
24
|
/**
|
|
25
25
|
* Boolean to specify that date picker should initially render with the
|
|
26
26
|
* end date’s month visible. The default behavior is to initially render
|
|
@@ -39,9 +39,9 @@ export default function DatePicker({
|
|
|
39
39
|
className,
|
|
40
40
|
dateEnd: _dateEnd,
|
|
41
41
|
dateStart: _dateStart,
|
|
42
|
+
initialMonth,
|
|
42
43
|
isRange = _dateEnd != null,
|
|
43
44
|
isTwoUp,
|
|
44
|
-
initialMonth,
|
|
45
45
|
monthLimitFirst,
|
|
46
46
|
monthLimitLast,
|
|
47
47
|
onChange,
|
package/src/MonthCalendar.tsx
CHANGED
|
@@ -13,9 +13,9 @@ import {
|
|
|
13
13
|
|
|
14
14
|
export type Props = {
|
|
15
15
|
className?: string;
|
|
16
|
-
dateEnd?: Date |
|
|
17
|
-
dateEndPreview?:
|
|
18
|
-
dateStart?: Date |
|
|
16
|
+
dateEnd?: Date | null | number | string;
|
|
17
|
+
dateEndPreview?: null | string;
|
|
18
|
+
dateStart?: Date | null | number | string;
|
|
19
19
|
isRange?: boolean;
|
|
20
20
|
month: number; // a unique numerical value representing the number of months since jan 1970
|
|
21
21
|
onChange?: (date: string) => void;
|
|
@@ -23,7 +23,7 @@ export type Props = {
|
|
|
23
23
|
title?: string;
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
-
type DateRangeDays = [
|
|
26
|
+
type DateRangeDays = [null | number, null | number, null | number];
|
|
27
27
|
|
|
28
28
|
const { Fragment, useCallback } = React;
|
|
29
29
|
|