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