@instructure/ui-calendar 8.51.0 → 8.51.1-snapshot-6
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/CHANGELOG.md +11 -0
- package/es/Calendar/__new-tests__/Calendar.test.js +76 -0
- package/es/Calendar/index.js +191 -26
- package/es/Calendar/props.js +13 -7
- package/lib/Calendar/__new-tests__/Calendar.test.js +79 -0
- package/lib/Calendar/index.js +193 -26
- package/lib/Calendar/props.js +13 -7
- package/package.json +21 -17
- package/src/Calendar/README.md +51 -0
- package/src/Calendar/__new-tests__/Calendar.test.tsx +83 -0
- package/src/Calendar/index.tsx +241 -29
- package/src/Calendar/props.ts +98 -31
- package/tsconfig.build.json +54 -16
- package/tsconfig.build.tsbuildinfo +1 -1
- package/types/Calendar/__new-tests__/Calendar.test.d.ts +2 -0
- package/types/Calendar/__new-tests__/Calendar.test.d.ts.map +1 -0
- package/types/Calendar/index.d.ts +56 -18
- package/types/Calendar/index.d.ts.map +1 -1
- package/types/Calendar/props.d.ts +65 -20
- package/types/Calendar/props.d.ts.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [8.51.1-snapshot-6](https://github.com/instructure/instructure-ui/compare/v8.51.0...v8.51.1-snapshot-6) (2024-01-19)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **ui-calendar:** make easy and minimal configuration possible ([911ac1b](https://github.com/instructure/instructure-ui/commit/911ac1b3c4523455a1e49f0581575952dcfc8605))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
# [8.51.0](https://github.com/instructure/instructure-ui/compare/v8.50.0...v8.51.0) (2023-12-14)
|
|
7
18
|
|
|
8
19
|
**Note:** Version bump only for package @instructure/ui-calendar
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
var _Calendar, _Calendar2, _Calendar3, _Calendar4;
|
|
2
|
+
/*
|
|
3
|
+
* The MIT License (MIT)
|
|
4
|
+
*
|
|
5
|
+
* Copyright (c) 2015 - present Instructure, Inc.
|
|
6
|
+
*
|
|
7
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
* in the Software without restriction, including without limitation the rights
|
|
10
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
* furnished to do so, subject to the following conditions:
|
|
13
|
+
*
|
|
14
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
* copies or substantial portions of the Software.
|
|
16
|
+
*
|
|
17
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
* SOFTWARE.
|
|
24
|
+
*/
|
|
25
|
+
import React from 'react';
|
|
26
|
+
import { render, screen } from '@testing-library/react';
|
|
27
|
+
import '@testing-library/jest-dom';
|
|
28
|
+
import Calendar from '../index';
|
|
29
|
+
describe('<Calendar />', () => {
|
|
30
|
+
describe('with minimal config', () => {
|
|
31
|
+
it('should render 44 buttons without config', async () => {
|
|
32
|
+
render(_Calendar || (_Calendar = /*#__PURE__*/React.createElement(Calendar, null)));
|
|
33
|
+
const buttons = document.getElementsByTagName('button');
|
|
34
|
+
expect(buttons.length).toEqual(44);
|
|
35
|
+
});
|
|
36
|
+
it('should render proper week names by default', async () => {
|
|
37
|
+
const _render = render(_Calendar2 || (_Calendar2 = /*#__PURE__*/React.createElement(Calendar, null))),
|
|
38
|
+
container = _render.container;
|
|
39
|
+
const thead = container.querySelector('thead');
|
|
40
|
+
expect(thead).toHaveTextContent('SundaySuMondayMoTuesdayTuWednesdayWeThursdayThFridayFrSaturdaySa');
|
|
41
|
+
});
|
|
42
|
+
it('should render proper week names if locale is set', async () => {
|
|
43
|
+
const _render2 = render(_Calendar3 || (_Calendar3 = /*#__PURE__*/React.createElement(Calendar, {
|
|
44
|
+
locale: "hu"
|
|
45
|
+
}))),
|
|
46
|
+
container = _render2.container;
|
|
47
|
+
const thead = container.querySelector('thead');
|
|
48
|
+
expect(thead).toHaveTextContent('hétfőhkeddkszerdaszecsütörtökcspéntekpszombatszovasárnapv');
|
|
49
|
+
});
|
|
50
|
+
it('should disable days properly', async () => {
|
|
51
|
+
const _render3 = render( /*#__PURE__*/React.createElement(Calendar, {
|
|
52
|
+
currentDate: "2023-12-15",
|
|
53
|
+
disabledDates: ['2023-12-22', '2023-12-12', '2023-12-11']
|
|
54
|
+
})),
|
|
55
|
+
container = _render3.container;
|
|
56
|
+
const buttons = container.querySelectorAll('button[disabled]');
|
|
57
|
+
const disabledTexts = ['11 December 202311', '12 December 202312', '22 December 202322'];
|
|
58
|
+
buttons.forEach((button, index) => {
|
|
59
|
+
expect(button).toHaveTextContent(disabledTexts[index]);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
it('should indicate selected day', async () => {
|
|
63
|
+
var _screen$queryByText, _screen$queryByText$p;
|
|
64
|
+
render(_Calendar4 || (_Calendar4 = /*#__PURE__*/React.createElement(Calendar, {
|
|
65
|
+
currentDate: "2023-12-15",
|
|
66
|
+
selectedDate: "2023-12-22"
|
|
67
|
+
})));
|
|
68
|
+
const selectedDay = (_screen$queryByText = screen.queryByText('22 December 2023')) === null || _screen$queryByText === void 0 ? void 0 : (_screen$queryByText$p = _screen$queryByText.parentElement) === null || _screen$queryByText$p === void 0 ? void 0 : _screen$queryByText$p.parentElement;
|
|
69
|
+
expect(selectedDay).toBeDefined();
|
|
70
|
+
if (selectedDay) {
|
|
71
|
+
var _window$getComputedSt;
|
|
72
|
+
expect((_window$getComputedSt = window.getComputedStyle(selectedDay)) === null || _window$getComputedSt === void 0 ? void 0 : _window$getComputedSt.background).toBe('rgb(11, 135, 75)');
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
});
|
package/es/Calendar/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var _dec, _dec2, _class, _class2;
|
|
1
|
+
var _dec, _dec2, _class, _class2, _IconButton, _IconButton2;
|
|
2
2
|
/*
|
|
3
3
|
* The MIT License (MIT)
|
|
4
4
|
*
|
|
@@ -30,22 +30,27 @@ import { safeCloneElement, callRenderProp, omitProps } from '@instructure/ui-rea
|
|
|
30
30
|
import { createChainedFunction } from '@instructure/ui-utils';
|
|
31
31
|
import { logError as error } from '@instructure/console';
|
|
32
32
|
import { uid } from '@instructure/uid';
|
|
33
|
+
import { AccessibleContent } from '@instructure/ui-a11y-content';
|
|
33
34
|
import { testable } from '@instructure/ui-testable';
|
|
34
35
|
import { withStyle, jsx } from '@instructure/emotion';
|
|
36
|
+
import { Locale, DateTime, ApplyLocaleContext } from '@instructure/ui-i18n';
|
|
35
37
|
import generateStyle from './styles';
|
|
36
38
|
import generateComponentTheme from './theme';
|
|
37
39
|
import { Day } from './Day';
|
|
38
40
|
import { propTypes, allowedProps } from './props';
|
|
41
|
+
import { IconButton } from '@instructure/ui-buttons';
|
|
42
|
+
import { IconArrowOpenStartSolid, IconArrowOpenEndSolid } from '@instructure/ui-icons';
|
|
43
|
+
|
|
39
44
|
/**
|
|
40
45
|
---
|
|
41
46
|
category: components
|
|
42
47
|
---
|
|
43
48
|
**/
|
|
44
49
|
let Calendar = (_dec = withStyle(generateStyle, generateComponentTheme), _dec2 = testable(), _dec(_class = _dec2(_class = (_class2 = class Calendar extends Component {
|
|
45
|
-
constructor(
|
|
46
|
-
super(
|
|
50
|
+
constructor(props) {
|
|
51
|
+
super(props);
|
|
47
52
|
this.ref = null;
|
|
48
|
-
this._weekdayHeaderIds = this.props.renderWeekdayLabels.reduce((ids, _label, i) => {
|
|
53
|
+
this._weekdayHeaderIds = (this.props.renderWeekdayLabels || this.defaultWeekdays).reduce((ids, _label, i) => {
|
|
49
54
|
return {
|
|
50
55
|
...ids,
|
|
51
56
|
[i]: uid(`weekday-header-${i}`)
|
|
@@ -54,35 +59,107 @@ let Calendar = (_dec = withStyle(generateStyle, generateComponentTheme), _dec2 =
|
|
|
54
59
|
this.handleRef = el => {
|
|
55
60
|
this.ref = el;
|
|
56
61
|
};
|
|
62
|
+
this.calculateState = (locale, timezone, currentDate) => ({
|
|
63
|
+
renderedDate: currentDate ? DateTime.parse(currentDate, locale, timezone) : DateTime.now(locale, timezone),
|
|
64
|
+
today: currentDate ? DateTime.parse(currentDate, locale, timezone) : DateTime.now(locale, timezone)
|
|
65
|
+
});
|
|
66
|
+
this.renderMonthNavigationButtons = () => {
|
|
67
|
+
const _this$props = this.props,
|
|
68
|
+
renderNextMonthButton = _this$props.renderNextMonthButton,
|
|
69
|
+
renderPrevMonthButton = _this$props.renderPrevMonthButton;
|
|
70
|
+
return {
|
|
71
|
+
prevButton: renderPrevMonthButton ? callRenderProp(renderPrevMonthButton) : _IconButton || (_IconButton = jsx(IconButton, {
|
|
72
|
+
size: "small",
|
|
73
|
+
withBackground: false,
|
|
74
|
+
withBorder: false,
|
|
75
|
+
renderIcon: jsx(IconArrowOpenStartSolid, {
|
|
76
|
+
color: "primary"
|
|
77
|
+
}),
|
|
78
|
+
screenReaderLabel: "Previous month"
|
|
79
|
+
})),
|
|
80
|
+
nextButton: renderNextMonthButton ? callRenderProp(renderNextMonthButton) : _IconButton2 || (_IconButton2 = jsx(IconButton, {
|
|
81
|
+
size: "small",
|
|
82
|
+
withBackground: false,
|
|
83
|
+
withBorder: false,
|
|
84
|
+
renderIcon: jsx(IconArrowOpenEndSolid, {
|
|
85
|
+
color: "primary"
|
|
86
|
+
}),
|
|
87
|
+
screenReaderLabel: "Next month"
|
|
88
|
+
}))
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
this.handleMonthChange = direction => e => {
|
|
92
|
+
const _this$props2 = this.props,
|
|
93
|
+
onRequestRenderNextMonth = _this$props2.onRequestRenderNextMonth,
|
|
94
|
+
onRequestRenderPrevMonth = _this$props2.onRequestRenderPrevMonth;
|
|
95
|
+
const renderedDate = this.state.renderedDate;
|
|
96
|
+
const newDate = renderedDate.clone();
|
|
97
|
+
if (direction === 'prev') {
|
|
98
|
+
if (onRequestRenderPrevMonth) {
|
|
99
|
+
onRequestRenderPrevMonth(e);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
newDate.subtract({
|
|
103
|
+
months: 1
|
|
104
|
+
});
|
|
105
|
+
} else {
|
|
106
|
+
if (onRequestRenderNextMonth) {
|
|
107
|
+
onRequestRenderNextMonth(e);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
newDate.add({
|
|
111
|
+
months: 1
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
this.setState({
|
|
115
|
+
renderedDate: newDate
|
|
116
|
+
});
|
|
117
|
+
};
|
|
118
|
+
// date is returned es a ISO string, like 2021-09-14T22:00:00.000Z
|
|
119
|
+
this.handleDayClick = (event, {
|
|
120
|
+
date
|
|
121
|
+
}) => {
|
|
122
|
+
if (this.props.onDateSelected) {
|
|
123
|
+
const parsedDate = DateTime.parse(date, this.locale(), this.timezone());
|
|
124
|
+
this.props.onDateSelected(parsedDate.toISOString(), parsedDate, event);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
this.state = this.calculateState(this.locale(), this.timezone(), props.currentDate);
|
|
57
128
|
}
|
|
58
129
|
componentDidMount() {
|
|
59
|
-
var _this$props$makeStyle, _this$
|
|
60
|
-
(_this$props$makeStyle = (_this$
|
|
130
|
+
var _this$props$makeStyle, _this$props3;
|
|
131
|
+
(_this$props$makeStyle = (_this$props3 = this.props).makeStyles) === null || _this$props$makeStyle === void 0 ? void 0 : _this$props$makeStyle.call(_this$props3);
|
|
61
132
|
}
|
|
62
|
-
componentDidUpdate() {
|
|
63
|
-
var _this$props$makeStyle2, _this$
|
|
64
|
-
(_this$props$makeStyle2 = (_this$
|
|
133
|
+
componentDidUpdate(prevProps) {
|
|
134
|
+
var _this$props$makeStyle2, _this$props4;
|
|
135
|
+
(_this$props$makeStyle2 = (_this$props4 = this.props).makeStyles) === null || _this$props$makeStyle2 === void 0 ? void 0 : _this$props$makeStyle2.call(_this$props4);
|
|
136
|
+
const isUpdated = prevProps.locale !== this.props.locale || prevProps.timezone !== this.props.timezone;
|
|
137
|
+
if (isUpdated) {
|
|
138
|
+
this.setState(() => {
|
|
139
|
+
return {
|
|
140
|
+
...this.calculateState(this.locale(), this.timezone(), this.props.currentDate)
|
|
141
|
+
};
|
|
142
|
+
});
|
|
143
|
+
}
|
|
65
144
|
}
|
|
66
145
|
get role() {
|
|
67
146
|
return this.props.role === 'listbox' ? this.props.role : void 0;
|
|
68
147
|
}
|
|
69
148
|
renderHeader() {
|
|
70
|
-
const _this$
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const nextButton = callRenderProp(renderNextMonthButton);
|
|
78
|
-
const prevButton = callRenderProp(renderPrevMonthButton);
|
|
149
|
+
const _this$props5 = this.props,
|
|
150
|
+
renderNavigationLabel = _this$props5.renderNavigationLabel,
|
|
151
|
+
styles = _this$props5.styles;
|
|
152
|
+
const renderedDate = this.state.renderedDate;
|
|
153
|
+
const _this$renderMonthNavi = this.renderMonthNavigationButtons(),
|
|
154
|
+
prevButton = _this$renderMonthNavi.prevButton,
|
|
155
|
+
nextButton = _this$renderMonthNavi.nextButton;
|
|
79
156
|
const cloneButton = (button, onClick) => safeCloneElement(button, {
|
|
80
157
|
onClick: createChainedFunction(button.props.onClick, onClick)
|
|
81
158
|
});
|
|
82
159
|
const style = [styles === null || styles === void 0 ? void 0 : styles.navigation, ...(prevButton || nextButton ? [styles === null || styles === void 0 ? void 0 : styles.navigationWithButtons] : [])];
|
|
83
160
|
return jsx("div", {
|
|
84
161
|
css: style
|
|
85
|
-
}, prevButton && cloneButton(prevButton,
|
|
162
|
+
}, prevButton && cloneButton(prevButton, this.handleMonthChange('prev')), renderNavigationLabel ? callRenderProp(renderNavigationLabel) : jsx("span", null, jsx("div", null, renderedDate.format('MMMM')), jsx("div", null, renderedDate.format('YYYY'))), nextButton && cloneButton(nextButton, this.handleMonthChange('next')));
|
|
86
163
|
}
|
|
87
164
|
renderBody() {
|
|
88
165
|
return jsx("table", {
|
|
@@ -90,9 +167,8 @@ let Calendar = (_dec = withStyle(generateStyle, generateComponentTheme), _dec2 =
|
|
|
90
167
|
}, jsx("thead", null, this.renderWeekdayHeaders()), jsx("tbody", null, this.renderDays()));
|
|
91
168
|
}
|
|
92
169
|
renderWeekdayHeaders() {
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
styles = _this$props4.styles;
|
|
170
|
+
const styles = this.props.styles;
|
|
171
|
+
const renderWeekdayLabels = this.props.renderWeekdayLabels || this.defaultWeekdays;
|
|
96
172
|
const length = renderWeekdayLabels.length;
|
|
97
173
|
error(length === 7, `[Calendar] \`renderWeekdayLabels\` should be an array with 7 labels (one for each weekday). ${length} provided.`);
|
|
98
174
|
return jsx("tr", null, renderWeekdayLabels.map((label, i) => {
|
|
@@ -104,12 +180,39 @@ let Calendar = (_dec = withStyle(generateStyle, generateComponentTheme), _dec2 =
|
|
|
104
180
|
}, callRenderProp(label));
|
|
105
181
|
}));
|
|
106
182
|
}
|
|
183
|
+
get defaultWeekdays() {
|
|
184
|
+
const shortDayNames = DateTime.getLocalDayNamesOfTheWeek(this.locale(), 'short');
|
|
185
|
+
const longDayNames = DateTime.getLocalDayNamesOfTheWeek(this.locale(), 'long');
|
|
186
|
+
return [jsx(AccessibleContent, {
|
|
187
|
+
key: 1,
|
|
188
|
+
alt: longDayNames[0]
|
|
189
|
+
}, shortDayNames[0]), jsx(AccessibleContent, {
|
|
190
|
+
key: 2,
|
|
191
|
+
alt: longDayNames[1]
|
|
192
|
+
}, shortDayNames[1]), jsx(AccessibleContent, {
|
|
193
|
+
key: 3,
|
|
194
|
+
alt: longDayNames[2]
|
|
195
|
+
}, shortDayNames[2]), jsx(AccessibleContent, {
|
|
196
|
+
key: 4,
|
|
197
|
+
alt: longDayNames[3]
|
|
198
|
+
}, shortDayNames[3]), jsx(AccessibleContent, {
|
|
199
|
+
key: 5,
|
|
200
|
+
alt: longDayNames[4]
|
|
201
|
+
}, shortDayNames[4]), jsx(AccessibleContent, {
|
|
202
|
+
key: 6,
|
|
203
|
+
alt: longDayNames[5]
|
|
204
|
+
}, shortDayNames[5]), jsx(AccessibleContent, {
|
|
205
|
+
key: 7,
|
|
206
|
+
alt: longDayNames[6]
|
|
207
|
+
}, shortDayNames[6])];
|
|
208
|
+
}
|
|
107
209
|
renderDays() {
|
|
108
|
-
const children =
|
|
109
|
-
const
|
|
210
|
+
const children = this.props.children;
|
|
211
|
+
const childrenArr = Children.toArray(children ? children : this.renderDefaultdays());
|
|
212
|
+
const length = childrenArr.length;
|
|
110
213
|
const role = this.role === 'listbox' ? 'presentation' : void 0;
|
|
111
214
|
error(length === Calendar.DAY_COUNT, `[Calendar] should have exactly ${Calendar.DAY_COUNT} children. ${length} provided.`);
|
|
112
|
-
return
|
|
215
|
+
return childrenArr.reduce((days, day, i) => {
|
|
113
216
|
const index = Math.floor(i / 7);
|
|
114
217
|
if (!days[index]) days.push([]);
|
|
115
218
|
days[index].push(day);
|
|
@@ -124,6 +227,68 @@ let Calendar = (_dec = withStyle(generateStyle, generateComponentTheme), _dec2 =
|
|
|
124
227
|
'aria-describedby': this._weekdayHeaderIds[i]
|
|
125
228
|
}) : day))));
|
|
126
229
|
}
|
|
230
|
+
locale() {
|
|
231
|
+
if (this.props.locale) {
|
|
232
|
+
return this.props.locale;
|
|
233
|
+
} else if (this.context && this.context.locale) {
|
|
234
|
+
return this.context.locale;
|
|
235
|
+
}
|
|
236
|
+
return Locale.browserLocale();
|
|
237
|
+
}
|
|
238
|
+
timezone() {
|
|
239
|
+
if (this.props.timezone) {
|
|
240
|
+
return this.props.timezone;
|
|
241
|
+
} else if (this.context && this.context.timezone) {
|
|
242
|
+
return this.context.timezone;
|
|
243
|
+
}
|
|
244
|
+
return DateTime.browserTimeZone();
|
|
245
|
+
}
|
|
246
|
+
isDisabledDate(date) {
|
|
247
|
+
const disabledDates = this.props.disabledDates;
|
|
248
|
+
if (!disabledDates) {
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
251
|
+
if (Array.isArray(disabledDates)) {
|
|
252
|
+
for (const aDisabledDate of disabledDates) {
|
|
253
|
+
if (date.isSame(aDisabledDate, 'day')) {
|
|
254
|
+
return true;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return false;
|
|
258
|
+
}
|
|
259
|
+
return disabledDates(date.toISOString());
|
|
260
|
+
}
|
|
261
|
+
renderDefaultdays() {
|
|
262
|
+
const selectedDate = this.props.selectedDate;
|
|
263
|
+
const _this$state = this.state,
|
|
264
|
+
renderedDate = _this$state.renderedDate,
|
|
265
|
+
today = _this$state.today;
|
|
266
|
+
// Sets it to the first local day of the week counting back from the start of the month.
|
|
267
|
+
// Note that first day depends on the locale, e.g. it's Sunday in the US and
|
|
268
|
+
// Monday in most of the EU.
|
|
269
|
+
const currDate = DateTime.getFirstDayOfWeek(renderedDate.clone().startOf('month'));
|
|
270
|
+
const arr = [];
|
|
271
|
+
for (let i = 0; i < Calendar.DAY_COUNT; i++) {
|
|
272
|
+
arr.push(currDate.clone());
|
|
273
|
+
currDate.add({
|
|
274
|
+
days: 1
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
return arr.map(date => {
|
|
278
|
+
const dateStr = date.toISOString();
|
|
279
|
+
return jsx(Calendar.Day, {
|
|
280
|
+
key: dateStr,
|
|
281
|
+
date: dateStr,
|
|
282
|
+
isSelected: selectedDate ? date.isSame(selectedDate, 'day') : false,
|
|
283
|
+
isToday: date.isSame(today, 'day'),
|
|
284
|
+
isOutsideMonth: !date.isSame(renderedDate, 'month'),
|
|
285
|
+
label: date.format('D MMMM YYYY') // used by screen readers
|
|
286
|
+
,
|
|
287
|
+
onClick: this.handleDayClick,
|
|
288
|
+
interaction: this.isDisabledDate(date) ? 'disabled' : 'enabled'
|
|
289
|
+
}, date.format('DD'));
|
|
290
|
+
});
|
|
291
|
+
}
|
|
127
292
|
render() {
|
|
128
293
|
const passthroughProps = View.omitViewProps(omitProps(this.props, Calendar.allowedProps), Calendar);
|
|
129
294
|
return jsx(View, Object.assign({}, passthroughProps, {
|
|
@@ -134,7 +299,7 @@ let Calendar = (_dec = withStyle(generateStyle, generateComponentTheme), _dec2 =
|
|
|
134
299
|
elementRef: this.handleRef
|
|
135
300
|
}), this.renderHeader(), this.renderBody());
|
|
136
301
|
}
|
|
137
|
-
}, _class2.displayName = "Calendar", _class2.componentId = 'Calendar', _class2.Day = Day, _class2.DAY_COUNT = 42, _class2.propTypes = propTypes, _class2.allowedProps = allowedProps, _class2.defaultProps = {
|
|
302
|
+
}, _class2.displayName = "Calendar", _class2.componentId = 'Calendar', _class2.contextType = ApplyLocaleContext, _class2.Day = Day, _class2.DAY_COUNT = 42, _class2.propTypes = propTypes, _class2.allowedProps = allowedProps, _class2.defaultProps = {
|
|
138
303
|
as: 'span',
|
|
139
304
|
role: 'table'
|
|
140
305
|
}, _class2)) || _class) || _class);
|
package/es/Calendar/props.js
CHANGED
|
@@ -26,15 +26,21 @@ import PropTypes from 'prop-types';
|
|
|
26
26
|
import { Children as ChildrenPropTypes } from '@instructure/ui-prop-types';
|
|
27
27
|
import { Day } from './Day';
|
|
28
28
|
const propTypes = {
|
|
29
|
+
as: PropTypes.elementType,
|
|
29
30
|
children: ChildrenPropTypes.oneOf([Day]),
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
currentDate: PropTypes.string,
|
|
32
|
+
disabledDates: PropTypes.oneOfType([PropTypes.array, PropTypes.func]),
|
|
33
|
+
locale: PropTypes.string,
|
|
34
|
+
onDateSelected: PropTypes.func,
|
|
34
35
|
onRequestRenderNextMonth: PropTypes.func,
|
|
35
36
|
onRequestRenderPrevMonth: PropTypes.func,
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
renderNavigationLabel: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
|
|
38
|
+
renderNextMonthButton: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
|
|
39
|
+
renderPrevMonthButton: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
|
|
40
|
+
renderWeekdayLabels: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.node, PropTypes.func])),
|
|
41
|
+
role: PropTypes.oneOf(['table', 'listbox']),
|
|
42
|
+
selectedDate: PropTypes.string,
|
|
43
|
+
timezone: PropTypes.string
|
|
38
44
|
};
|
|
39
|
-
const allowedProps = ['children', '
|
|
45
|
+
const allowedProps = ['as', 'children', 'currentDate', 'disabledDates', 'locale', 'onDateSelected', 'onRequestRenderNextMonth', 'onRequestRenderPrevMonth', 'renderNavigationLabel', 'renderNextMonthButton', 'renderPrevMonthButton', 'renderWeekdayLabels', 'role', 'selectedDate', 'timezone'];
|
|
40
46
|
export { propTypes, allowedProps };
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
4
|
+
var _react = _interopRequireDefault(require("react"));
|
|
5
|
+
var _react2 = require("@testing-library/react");
|
|
6
|
+
require("@testing-library/jest-dom");
|
|
7
|
+
var _index = _interopRequireDefault(require("../index"));
|
|
8
|
+
var _Calendar, _Calendar2, _Calendar3, _Calendar4;
|
|
9
|
+
/*
|
|
10
|
+
* The MIT License (MIT)
|
|
11
|
+
*
|
|
12
|
+
* Copyright (c) 2015 - present Instructure, Inc.
|
|
13
|
+
*
|
|
14
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
15
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
16
|
+
* in the Software without restriction, including without limitation the rights
|
|
17
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
18
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
19
|
+
* furnished to do so, subject to the following conditions:
|
|
20
|
+
*
|
|
21
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
22
|
+
* copies or substantial portions of the Software.
|
|
23
|
+
*
|
|
24
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
25
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
26
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
27
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
28
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
29
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
30
|
+
* SOFTWARE.
|
|
31
|
+
*/
|
|
32
|
+
describe('<Calendar />', () => {
|
|
33
|
+
describe('with minimal config', () => {
|
|
34
|
+
it('should render 44 buttons without config', async () => {
|
|
35
|
+
(0, _react2.render)(_Calendar || (_Calendar = /*#__PURE__*/_react.default.createElement(_index.default, null)));
|
|
36
|
+
const buttons = document.getElementsByTagName('button');
|
|
37
|
+
expect(buttons.length).toEqual(44);
|
|
38
|
+
});
|
|
39
|
+
it('should render proper week names by default', async () => {
|
|
40
|
+
const _render = (0, _react2.render)(_Calendar2 || (_Calendar2 = /*#__PURE__*/_react.default.createElement(_index.default, null))),
|
|
41
|
+
container = _render.container;
|
|
42
|
+
const thead = container.querySelector('thead');
|
|
43
|
+
expect(thead).toHaveTextContent('SundaySuMondayMoTuesdayTuWednesdayWeThursdayThFridayFrSaturdaySa');
|
|
44
|
+
});
|
|
45
|
+
it('should render proper week names if locale is set', async () => {
|
|
46
|
+
const _render2 = (0, _react2.render)(_Calendar3 || (_Calendar3 = /*#__PURE__*/_react.default.createElement(_index.default, {
|
|
47
|
+
locale: "hu"
|
|
48
|
+
}))),
|
|
49
|
+
container = _render2.container;
|
|
50
|
+
const thead = container.querySelector('thead');
|
|
51
|
+
expect(thead).toHaveTextContent('hétfőhkeddkszerdaszecsütörtökcspéntekpszombatszovasárnapv');
|
|
52
|
+
});
|
|
53
|
+
it('should disable days properly', async () => {
|
|
54
|
+
const _render3 = (0, _react2.render)( /*#__PURE__*/_react.default.createElement(_index.default, {
|
|
55
|
+
currentDate: "2023-12-15",
|
|
56
|
+
disabledDates: ['2023-12-22', '2023-12-12', '2023-12-11']
|
|
57
|
+
})),
|
|
58
|
+
container = _render3.container;
|
|
59
|
+
const buttons = container.querySelectorAll('button[disabled]');
|
|
60
|
+
const disabledTexts = ['11 December 202311', '12 December 202312', '22 December 202322'];
|
|
61
|
+
buttons.forEach((button, index) => {
|
|
62
|
+
expect(button).toHaveTextContent(disabledTexts[index]);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
it('should indicate selected day', async () => {
|
|
66
|
+
var _screen$queryByText, _screen$queryByText$p;
|
|
67
|
+
(0, _react2.render)(_Calendar4 || (_Calendar4 = /*#__PURE__*/_react.default.createElement(_index.default, {
|
|
68
|
+
currentDate: "2023-12-15",
|
|
69
|
+
selectedDate: "2023-12-22"
|
|
70
|
+
})));
|
|
71
|
+
const selectedDay = (_screen$queryByText = _react2.screen.queryByText('22 December 2023')) === null || _screen$queryByText === void 0 ? void 0 : (_screen$queryByText$p = _screen$queryByText.parentElement) === null || _screen$queryByText$p === void 0 ? void 0 : _screen$queryByText$p.parentElement;
|
|
72
|
+
expect(selectedDay).toBeDefined();
|
|
73
|
+
if (selectedDay) {
|
|
74
|
+
var _window$getComputedSt;
|
|
75
|
+
expect((_window$getComputedSt = window.getComputedStyle(selectedDay)) === null || _window$getComputedSt === void 0 ? void 0 : _window$getComputedSt.background).toBe('rgb(11, 135, 75)');
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
});
|