dce-reactkit 4.0.0 → 4.0.2-beta-simple-date-chooser.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/dist/cjs/index.js +355 -91
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/components/SimpleDateChooser.d.ts +3 -1
- package/dist/cjs/types/components/SimpleTimeChooser.d.ts +20 -0
- package/dist/cjs/types/index.d.ts +2 -1
- package/dist/cjs/types/types/ReactKitErrorCode.d.ts +3 -1
- package/dist/esm/index.js +355 -92
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/components/SimpleDateChooser.d.ts +3 -1
- package/dist/esm/types/components/SimpleTimeChooser.d.ts +20 -0
- package/dist/esm/types/index.d.ts +2 -1
- package/dist/esm/types/types/ReactKitErrorCode.d.ts +3 -1
- package/dist/index.d.ts +41 -17
- package/package.json +1 -1
- package/src/components/LogReviewer.tsx +2 -2
- package/src/components/SimpleDateChooser.tsx +397 -119
- package/src/components/SimpleTimeChooser.tsx +196 -0
- package/src/index.ts +2 -0
- package/src/types/LogSource.ts +1 -1
- package/src/types/ReactKitErrorCode.tsx +3 -1
|
@@ -1,16 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* A very simple, lightweight date chooser
|
|
3
3
|
* @author Gabe Abrams
|
|
4
|
+
* @author Gardenia Liu
|
|
4
5
|
*/
|
|
5
6
|
|
|
6
7
|
// Import React
|
|
7
|
-
import React from 'react';
|
|
8
|
-
|
|
8
|
+
import React, { useReducer } from 'react';
|
|
9
|
+
|
|
10
|
+
// Import AppWrapper helpers
|
|
11
|
+
import { confirm } from './AppWrapper';
|
|
9
12
|
|
|
10
13
|
// Import helpers
|
|
11
14
|
import getOrdinal from '../helpers/getOrdinal';
|
|
15
|
+
import getMonthName from '../helpers/getMonthName';
|
|
12
16
|
import getTimeInfoInET from '../helpers/getTimeInfoInET';
|
|
13
17
|
|
|
18
|
+
// Import classes
|
|
19
|
+
import ErrorWithCode from '../errors/ErrorWithCode';
|
|
20
|
+
|
|
21
|
+
// Import types
|
|
22
|
+
import ReactKitErrorCode from '../types/ReactKitErrorCode';
|
|
23
|
+
|
|
14
24
|
/*------------------------------------------------------------------------*/
|
|
15
25
|
/* -------------------------------- Types ------------------------------- */
|
|
16
26
|
/*------------------------------------------------------------------------*/
|
|
@@ -33,40 +43,97 @@ type Props = {
|
|
|
33
43
|
* @param year new full year number
|
|
34
44
|
*/
|
|
35
45
|
onChange: (month: number, day: number, year: number) => void,
|
|
36
|
-
// Number of months to allow the user to choose from
|
|
37
|
-
//
|
|
46
|
+
// Number of months in either the past or future to allow the user to choose from
|
|
47
|
+
// If we aren't allowing the past or the future, we will throw an error
|
|
48
|
+
// (max is 12, default is 6 in the past and 6 in the future)
|
|
38
49
|
numMonthsToShow?: number,
|
|
39
|
-
// If true,
|
|
40
|
-
|
|
41
|
-
|
|
50
|
+
// If true, the user isn't allowed to select dates in the past
|
|
51
|
+
dontAllowPast?: boolean,
|
|
52
|
+
// If true, the user isn't allowed to select dates in the future
|
|
53
|
+
dontAllowFuture?: boolean,
|
|
42
54
|
};
|
|
43
55
|
|
|
44
56
|
/*------------------------------------------------------------------------*/
|
|
45
|
-
/*
|
|
57
|
+
/* -------------------------------- State ------------------------------- */
|
|
46
58
|
/*------------------------------------------------------------------------*/
|
|
47
59
|
|
|
48
|
-
|
|
49
|
-
/*------------------------------------------------------------------------*/
|
|
50
|
-
/* -------------------------------- Setup ------------------------------- */
|
|
51
|
-
/*------------------------------------------------------------------------*/
|
|
60
|
+
/* -------------- Views ------------- */
|
|
52
61
|
|
|
53
|
-
|
|
62
|
+
enum View {
|
|
63
|
+
// Date chooser
|
|
64
|
+
DateChooser = 'DateChooser',
|
|
65
|
+
// Invalid date
|
|
66
|
+
InvalidDate = 'InvalidDate',
|
|
67
|
+
}
|
|
54
68
|
|
|
55
|
-
|
|
56
|
-
ariaLabel,
|
|
57
|
-
name,
|
|
58
|
-
onChange,
|
|
59
|
-
chooseFromPast,
|
|
60
|
-
numMonthsToShow = 6,
|
|
61
|
-
} = props;
|
|
69
|
+
/* -------- State Definition -------- */
|
|
62
70
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
71
|
+
type State = {
|
|
72
|
+
view: View,
|
|
73
|
+
};
|
|
66
74
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
75
|
+
/* ------------- Actions ------------ */
|
|
76
|
+
|
|
77
|
+
// Types of actions
|
|
78
|
+
enum ActionType {
|
|
79
|
+
// Fix invalid date so it is now in range
|
|
80
|
+
FixInvalidDate = 'FixInvalidDate',
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Action definitions
|
|
84
|
+
type Action = {
|
|
85
|
+
// Action type
|
|
86
|
+
type: ActionType.FixInvalidDate,
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Reducer that executes actions
|
|
91
|
+
* @author Gardenia Liu
|
|
92
|
+
* @param state current state
|
|
93
|
+
* @param action action to execute
|
|
94
|
+
* @returns updated state
|
|
95
|
+
*/
|
|
96
|
+
const reducer = (state: State, action: Action): State => {
|
|
97
|
+
switch (action.type) {
|
|
98
|
+
case ActionType.FixInvalidDate: {
|
|
99
|
+
return {
|
|
100
|
+
...state,
|
|
101
|
+
view: View.DateChooser,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
default: {
|
|
105
|
+
return state;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
/*------------------------------------------------------------------------*/
|
|
111
|
+
/* --------------------------- Static Helpers --------------------------- */
|
|
112
|
+
/*------------------------------------------------------------------------*/
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Get the list of choices in the date chooser given props
|
|
116
|
+
* @author Gardenia Liu
|
|
117
|
+
* @author Gabe Abrams
|
|
118
|
+
* @param opts object containing all arguments
|
|
119
|
+
* @param opts.numMonthsToShow number of months to show
|
|
120
|
+
* @param opts.dontAllowPast if true, the user isn't allowed to select dates in the past
|
|
121
|
+
* @param opts.dontAllowFuture if true, the user isn't allowed to select dates in the future
|
|
122
|
+
* @returns choices
|
|
123
|
+
*/
|
|
124
|
+
const getChoices = (
|
|
125
|
+
opts: {
|
|
126
|
+
numMonthsToShow?: number,
|
|
127
|
+
dontAllowPast?: boolean,
|
|
128
|
+
dontAllowFuture?: boolean,
|
|
129
|
+
},
|
|
130
|
+
) => {
|
|
131
|
+
// Destructure props
|
|
132
|
+
const {
|
|
133
|
+
dontAllowFuture,
|
|
134
|
+
dontAllowPast,
|
|
135
|
+
numMonthsToShow = 6,
|
|
136
|
+
} = opts;
|
|
70
137
|
|
|
71
138
|
// Determine the set of choices allowed
|
|
72
139
|
const today = getTimeInfoInET();
|
|
@@ -76,16 +143,41 @@ const SimpleDateChooser: React.FC<Props> = (props) => {
|
|
|
76
143
|
days: number[],
|
|
77
144
|
year: number,
|
|
78
145
|
}[] = [];
|
|
146
|
+
|
|
79
147
|
let startYear = today.year;
|
|
80
148
|
let startMonth = today.month;
|
|
81
|
-
|
|
149
|
+
|
|
150
|
+
// Don't allow past or future dates
|
|
151
|
+
if (dontAllowPast && dontAllowFuture) {
|
|
152
|
+
throw new ErrorWithCode(
|
|
153
|
+
'No past or future dates allowed',
|
|
154
|
+
ReactKitErrorCode.SimpleDateChooserInvalidDateRange,
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Require numMonthsToShow to be positive
|
|
159
|
+
if (numMonthsToShow <= 0) {
|
|
160
|
+
throw new ErrorWithCode(
|
|
161
|
+
'numMonthsToShow must be positive',
|
|
162
|
+
ReactKitErrorCode.SimpleDateChooserInvalidNumMonths,
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Recalculate startMonth and startYear when allowing past dates
|
|
167
|
+
if (!dontAllowPast) {
|
|
82
168
|
startMonth -= Math.max(0, numMonthsToShow - 1);
|
|
83
169
|
while (startMonth <= 0) {
|
|
84
170
|
startMonth += 12;
|
|
85
171
|
startYear -= 1;
|
|
86
172
|
}
|
|
87
173
|
}
|
|
88
|
-
|
|
174
|
+
// Calculate total number of months to show
|
|
175
|
+
let totalMonthsToShow = numMonthsToShow;
|
|
176
|
+
if (!dontAllowPast && !dontAllowFuture) {
|
|
177
|
+
totalMonthsToShow = totalMonthsToShow * 2 - 1;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
for (let i = 0; i < totalMonthsToShow; i++) {
|
|
89
181
|
// Get month and year info
|
|
90
182
|
const unmoddedMonth = (startMonth + i);
|
|
91
183
|
let month = unmoddedMonth;
|
|
@@ -105,24 +197,25 @@ const SimpleDateChooser: React.FC<Props> = (props) => {
|
|
|
105
197
|
// Figure out which days are allowed
|
|
106
198
|
const days = [];
|
|
107
199
|
const numDaysInMonth = (new Date(year, month, 0)).getDate();
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
days.push(day);
|
|
200
|
+
|
|
201
|
+
// Current month
|
|
202
|
+
if (month === today.month && year === today.year) {
|
|
203
|
+
// Past selection: add all previous days of the month
|
|
204
|
+
if (!dontAllowPast) {
|
|
205
|
+
for (let day = 1; day < today.day; day++) {
|
|
206
|
+
days.push(day);
|
|
207
|
+
}
|
|
117
208
|
}
|
|
118
|
-
|
|
209
|
+
days.push(today.day); // Add current day
|
|
119
210
|
// Future selection: add all remaining days of the month
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
211
|
+
if (!dontAllowFuture) {
|
|
212
|
+
for (let day = today.day + 1; day <= numDaysInMonth; day++) {
|
|
213
|
+
days.push(day);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
} else { // Past or future month
|
|
217
|
+
// Include all days in the month
|
|
218
|
+
for (let day = 1; day <= numDaysInMonth; day++) {
|
|
126
219
|
days.push(day);
|
|
127
220
|
}
|
|
128
221
|
}
|
|
@@ -135,93 +228,278 @@ const SimpleDateChooser: React.FC<Props> = (props) => {
|
|
|
135
228
|
});
|
|
136
229
|
}
|
|
137
230
|
|
|
138
|
-
//
|
|
231
|
+
// Return choices
|
|
232
|
+
return choices;
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Checks whether a given date is outside the valid range of allowed choices
|
|
237
|
+
* @author Gardenia Liu
|
|
238
|
+
* @param opts object containing all arguments
|
|
239
|
+
* @param opts.month 1-indexed month
|
|
240
|
+
* @param opts.day day of the month
|
|
241
|
+
* @param opts.year full year
|
|
242
|
+
* @param opts.choices valid date choices
|
|
243
|
+
* @returns true if date is out of range
|
|
244
|
+
*/
|
|
245
|
+
const isDateOutOfRange = (
|
|
246
|
+
opts: {
|
|
247
|
+
month: number,
|
|
248
|
+
day: number,
|
|
249
|
+
year: number,
|
|
250
|
+
choices: {
|
|
251
|
+
month: number,
|
|
252
|
+
year: number,
|
|
253
|
+
days: number[]
|
|
254
|
+
}[],
|
|
255
|
+
},
|
|
256
|
+
): boolean => {
|
|
257
|
+
const {
|
|
258
|
+
month,
|
|
259
|
+
day,
|
|
260
|
+
year,
|
|
261
|
+
choices,
|
|
262
|
+
} = opts;
|
|
263
|
+
|
|
264
|
+
return !choices.some((choice) => {
|
|
265
|
+
return (
|
|
266
|
+
choice.month === month
|
|
267
|
+
&& choice.year === year
|
|
268
|
+
&& choice.days.includes(day)
|
|
269
|
+
);
|
|
270
|
+
});
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
/*------------------------------------------------------------------------*/
|
|
274
|
+
/* ------------------------------ Component ----------------------------- */
|
|
275
|
+
/*------------------------------------------------------------------------*/
|
|
276
|
+
|
|
277
|
+
const SimpleDateChooser: React.FC<Props> = (props) => {
|
|
278
|
+
/*------------------------------------------------------------------------*/
|
|
279
|
+
/* -------------------------------- Setup ------------------------------- */
|
|
280
|
+
/*------------------------------------------------------------------------*/
|
|
281
|
+
|
|
282
|
+
/* -------------- Props ------------- */
|
|
283
|
+
|
|
139
284
|
const {
|
|
285
|
+
ariaLabel,
|
|
286
|
+
name,
|
|
287
|
+
dontAllowPast,
|
|
288
|
+
dontAllowFuture,
|
|
289
|
+
numMonthsToShow,
|
|
290
|
+
onChange,
|
|
140
291
|
month,
|
|
141
292
|
day,
|
|
142
293
|
year,
|
|
143
294
|
} = props;
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
choices
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
295
|
+
|
|
296
|
+
// Get choices
|
|
297
|
+
const choices = getChoices({
|
|
298
|
+
numMonthsToShow,
|
|
299
|
+
dontAllowPast,
|
|
300
|
+
dontAllowFuture,
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
/* -------------- State ------------- */
|
|
304
|
+
|
|
305
|
+
// Check if the currently selected date is out of range
|
|
306
|
+
const currentSelectedDateOutOfRange = isDateOutOfRange({
|
|
307
|
+
month,
|
|
308
|
+
day,
|
|
309
|
+
year,
|
|
310
|
+
choices,
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
// Initial state
|
|
314
|
+
const initialState: State = {
|
|
315
|
+
view: (
|
|
316
|
+
currentSelectedDateOutOfRange
|
|
317
|
+
? View.InvalidDate
|
|
318
|
+
: View.DateChooser
|
|
319
|
+
),
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
// Initialize state
|
|
323
|
+
const [state, dispatch] = useReducer(reducer, initialState);
|
|
324
|
+
|
|
325
|
+
// Destructure common state
|
|
326
|
+
const {
|
|
327
|
+
view,
|
|
328
|
+
} = state;
|
|
329
|
+
|
|
330
|
+
/*------------------------------------------------------------------------*/
|
|
331
|
+
/* ------------------------- Component Functions ------------------------ */
|
|
332
|
+
/*------------------------------------------------------------------------*/
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Ask the user if they want to edit an invalid date
|
|
336
|
+
* @author Gardenia Liu
|
|
337
|
+
* @author Gabe Abrams
|
|
338
|
+
*/
|
|
339
|
+
const askToEditInvalidDate = async () => {
|
|
340
|
+
// Ask the user if they want to edit the date
|
|
341
|
+
const confirmed = await confirm(
|
|
342
|
+
'Are you sure?',
|
|
343
|
+
'The current date is outside the normal range. If you edit it, you\'ll need to choose a new date in the normal range.',
|
|
344
|
+
{
|
|
345
|
+
confirmButtonText: 'Edit Date',
|
|
346
|
+
},
|
|
159
347
|
);
|
|
160
348
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
//
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
aria-label={`choose date ${dayChoice}`}
|
|
171
|
-
>
|
|
172
|
-
{dayChoice}
|
|
173
|
-
{ordinal}
|
|
174
|
-
</option>,
|
|
175
|
-
);
|
|
349
|
+
// Check if user confirmed
|
|
350
|
+
if (confirmed) {
|
|
351
|
+
// Update the date to today
|
|
352
|
+
const today = getTimeInfoInET();
|
|
353
|
+
onChange(today.month, today.day, today.year);
|
|
354
|
+
|
|
355
|
+
// Update state
|
|
356
|
+
dispatch({
|
|
357
|
+
type: ActionType.FixInvalidDate,
|
|
176
358
|
});
|
|
177
359
|
}
|
|
178
|
-
}
|
|
360
|
+
};
|
|
179
361
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
362
|
+
/*------------------------------------------------------------------------*/
|
|
363
|
+
/* ------------------------------- Render ------------------------------- */
|
|
364
|
+
/*------------------------------------------------------------------------*/
|
|
365
|
+
|
|
366
|
+
/*----------------------------------------*/
|
|
367
|
+
/* ---------------- Views --------------- */
|
|
368
|
+
/*----------------------------------------*/
|
|
369
|
+
|
|
370
|
+
// Body that will be filled with the current view
|
|
371
|
+
let body: React.ReactNode;
|
|
372
|
+
|
|
373
|
+
/* ---------- DateChooser ---------- */
|
|
374
|
+
|
|
375
|
+
if (view === View.DateChooser) {
|
|
376
|
+
// Create lists of options
|
|
377
|
+
const monthOptions: React.ReactNode[] = [];
|
|
378
|
+
const dayOptions: React.ReactNode[] = [];
|
|
379
|
+
|
|
380
|
+
// Render each option and add it to the list
|
|
381
|
+
choices.forEach((choice) => {
|
|
382
|
+
// Create month option
|
|
383
|
+
monthOptions.push(
|
|
384
|
+
<option
|
|
385
|
+
key={`${choice.year}-${choice.month}`}
|
|
386
|
+
value={`${choice.month}-${choice.year}`}
|
|
387
|
+
aria-label={`choose ${choice.choiceName}`}
|
|
388
|
+
onSelect={() => {
|
|
389
|
+
onChange(choice.month, choice.days[0], choice.year);
|
|
390
|
+
}}
|
|
391
|
+
>
|
|
392
|
+
{choice.choiceName}
|
|
393
|
+
</option>,
|
|
394
|
+
);
|
|
395
|
+
|
|
396
|
+
// This is the currently selected month
|
|
397
|
+
if (month === choice.month) {
|
|
398
|
+
// Create day options
|
|
399
|
+
choice.days.forEach((dayChoice) => {
|
|
400
|
+
const ordinal = getOrdinal(dayChoice);
|
|
401
|
+
dayOptions.push(
|
|
402
|
+
<option
|
|
403
|
+
key={`${choice.year}-${choice.month}-${dayChoice}`}
|
|
404
|
+
value={dayChoice}
|
|
405
|
+
aria-label={`choose date ${dayChoice}`}
|
|
406
|
+
>
|
|
407
|
+
{dayChoice}
|
|
408
|
+
{ordinal}
|
|
409
|
+
</option>,
|
|
219
410
|
);
|
|
220
|
-
}
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
// Create body
|
|
416
|
+
body = (
|
|
417
|
+
<div
|
|
418
|
+
className="SimpleDateChooser-inner-container d-inline-block"
|
|
419
|
+
aria-label={`date chooser with selected date: ${month}/${day}/${year}`}
|
|
221
420
|
>
|
|
222
|
-
{
|
|
223
|
-
|
|
224
|
-
|
|
421
|
+
{/* Month Chooser */}
|
|
422
|
+
<select
|
|
423
|
+
aria-label={`month for ${ariaLabel}`}
|
|
424
|
+
className="custom-select d-inline-block mr-1"
|
|
425
|
+
style={{ width: 'auto' }}
|
|
426
|
+
id={`SimpleDateChooser-${name}-month`}
|
|
427
|
+
value={`${month}-${year}`}
|
|
428
|
+
onChange={(e) => {
|
|
429
|
+
const choice = choices[e.target.selectedIndex];
|
|
430
|
+
|
|
431
|
+
// Change day, month, and year
|
|
432
|
+
onChange(
|
|
433
|
+
choice.month,
|
|
434
|
+
choice.days[0],
|
|
435
|
+
choice.year,
|
|
436
|
+
);
|
|
437
|
+
}}
|
|
438
|
+
>
|
|
439
|
+
{monthOptions}
|
|
440
|
+
</select>
|
|
441
|
+
|
|
442
|
+
{/* Day Chooser */}
|
|
443
|
+
<select
|
|
444
|
+
aria-label={`day for ${ariaLabel}`}
|
|
445
|
+
className="custom-select d-inline-block"
|
|
446
|
+
style={{ width: 'auto' }}
|
|
447
|
+
id={`SimpleDateChooser-${name}-day`}
|
|
448
|
+
value={day}
|
|
449
|
+
onChange={(e) => {
|
|
450
|
+
// Only change the day
|
|
451
|
+
onChange(
|
|
452
|
+
month,
|
|
453
|
+
Number.parseInt(e.target.value, 10),
|
|
454
|
+
year,
|
|
455
|
+
);
|
|
456
|
+
}}
|
|
457
|
+
>
|
|
458
|
+
{dayOptions}
|
|
459
|
+
</select>
|
|
460
|
+
</div>
|
|
461
|
+
);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/* --------- DateOutOfRange --------- */
|
|
465
|
+
|
|
466
|
+
if (view === View.InvalidDate) {
|
|
467
|
+
body = (
|
|
468
|
+
<div className="SimpleDateChooser-inner-container d-inline-block">
|
|
469
|
+
<button
|
|
470
|
+
type="button"
|
|
471
|
+
className="btn btn-light"
|
|
472
|
+
onClick={askToEditInvalidDate}
|
|
473
|
+
aria-label={`edit date for ${ariaLabel}`}
|
|
474
|
+
>
|
|
475
|
+
{getMonthName(month).full}
|
|
476
|
+
{' '}
|
|
477
|
+
{day}
|
|
478
|
+
{getOrdinal(day)}
|
|
479
|
+
,
|
|
480
|
+
{' '}
|
|
481
|
+
{year}
|
|
482
|
+
</button>
|
|
483
|
+
<button
|
|
484
|
+
type="button"
|
|
485
|
+
className="btn btn-secondary"
|
|
486
|
+
onClick={askToEditInvalidDate}
|
|
487
|
+
aria-label={`edit date for ${ariaLabel}`}
|
|
488
|
+
>
|
|
489
|
+
Edit
|
|
490
|
+
</button>
|
|
491
|
+
</div>
|
|
492
|
+
);
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
/*----------------------------------------*/
|
|
496
|
+
/* --------------- Main UI -------------- */
|
|
497
|
+
/*----------------------------------------*/
|
|
498
|
+
|
|
499
|
+
return (
|
|
500
|
+
<span className="SimpleDateChooser-outer-container">
|
|
501
|
+
{body}
|
|
502
|
+
</span>
|
|
225
503
|
);
|
|
226
504
|
};
|
|
227
505
|
|