@allxsmith/bestax-bulma 5.26.5 → 5.26.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/dist/bestax.css +1 -1
- package/dist/bestax.css.map +1 -1
- package/dist/extras.css +1 -1
- package/dist/extras.css.map +1 -1
- package/dist/index.cjs +222 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +222 -17
- package/dist/index.esm.js.map +1 -1
- package/dist/types/form/Numberinput.d.ts +8 -1
- package/dist/types/form/_pickerInternals/Calendar.d.ts +45 -4
- package/dist/types/form/_pickerInternals/dateUtils.d.ts +17 -0
- package/dist/types/form/_pickerInternals/pickerTypes.d.ts +14 -0
- package/dist/types/helpers/statusRegion.d.ts +1 -0
- package/dist/types-cjs/form/Numberinput.d.ts +8 -1
- package/dist/types-cjs/form/_pickerInternals/Calendar.d.ts +45 -4
- package/dist/types-cjs/form/_pickerInternals/dateUtils.d.ts +17 -0
- package/dist/types-cjs/form/_pickerInternals/pickerTypes.d.ts +14 -0
- package/dist/types-cjs/helpers/statusRegion.d.ts +1 -0
- package/dist/versions/bestax-no-dark-mode.css +1 -1
- package/dist/versions/bestax-no-dark-mode.css.map +1 -1
- package/dist/versions/bestax-no-helpers-prefixed.css +1 -1
- package/dist/versions/bestax-no-helpers-prefixed.css.map +1 -1
- package/dist/versions/bestax-no-helpers.css +1 -1
- package/dist/versions/bestax-no-helpers.css.map +1 -1
- package/dist/versions/bestax-prefixed.css +1 -1
- package/dist/versions/bestax-prefixed.css.map +1 -1
- package/package.json +1 -1
- package/src/scss/form/_dateinput.scss +8 -1
package/dist/index.esm.js
CHANGED
|
@@ -7689,7 +7689,8 @@ const noAnnouncementsYet = {
|
|
|
7689
7689
|
// the accessibility tree. The declarations match the `extras-sr-only` mixin,
|
|
7690
7690
|
// plus `clip-path`, which replaces the deprecated `clip`. The negative margin
|
|
7691
7691
|
// pulls the 1px box back inside the page, so it doesn't add scrollable
|
|
7692
|
-
// overflow.
|
|
7692
|
+
// overflow. Exported for other live regions that must work without a
|
|
7693
|
+
// stylesheet, such as a range calendar's.
|
|
7693
7694
|
const visuallyHidden = {
|
|
7694
7695
|
position: 'absolute',
|
|
7695
7696
|
width: '1px',
|
|
@@ -10140,7 +10141,11 @@ const Numberinput = forwardRef(({
|
|
|
10140
10141
|
// Field props
|
|
10141
10142
|
label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName, value: controlledValue, defaultValue, min, max, step = 1, size, color, inputColor, controlsPosition = 'both', controlsRounded = false, compact = false, bare, variant = 'plusminus', disabled = false, editable = true, isLoading = false, exponential = false, onChange, className, ...props }, ref) => {
|
|
10142
10143
|
const insideField = useInsideField();
|
|
10143
|
-
|
|
10144
|
+
// Bare controls join their parent's row, which a `.control` does not lay
|
|
10145
|
+
// out. `useInsideControl()` is true anywhere below a `Control`, even past
|
|
10146
|
+
// a `Field` nested in it, so there they keep their own row as well.
|
|
10147
|
+
const insideControl = useInsideControl();
|
|
10148
|
+
const effectiveBare = bare ?? (insideField && !insideControl);
|
|
10144
10149
|
const { bulmaHelperClasses, rest } = useBulmaClasses(props);
|
|
10145
10150
|
const [internalValue, setInternalValue] = useState(defaultValue);
|
|
10146
10151
|
const inputRef = useRef(null);
|
|
@@ -11482,6 +11487,9 @@ const DEFAULT_PICKER_LABELS = {
|
|
|
11482
11487
|
chooseDate: 'Choose date',
|
|
11483
11488
|
chooseMonth: 'Choose month',
|
|
11484
11489
|
chooseYear: 'Choose year',
|
|
11490
|
+
rangeStart: 'Start date',
|
|
11491
|
+
rangeEnd: 'End date',
|
|
11492
|
+
rangePreviewEnd: 'Choose as end date',
|
|
11485
11493
|
hours: 'hours',
|
|
11486
11494
|
minutes: 'minutes',
|
|
11487
11495
|
seconds: 'seconds',
|
|
@@ -11634,6 +11642,43 @@ function isPeriodUnselectable(d, granularity, c) {
|
|
|
11634
11642
|
}
|
|
11635
11643
|
return true;
|
|
11636
11644
|
}
|
|
11645
|
+
/**
|
|
11646
|
+
* The most days {@link canCloseRange} walks between a range's ends, about
|
|
11647
|
+
* eleven years. A span it would have to walk further is refused, so the check
|
|
11648
|
+
* stays cheap enough to run on every pointer move over the calendar.
|
|
11649
|
+
*/
|
|
11650
|
+
const RANGE_WALK_LIMIT = 4000;
|
|
11651
|
+
/**
|
|
11652
|
+
* Whether `end` can close a range that opens on `start`: it falls on `start`'s
|
|
11653
|
+
* day or later, and, unless `allowDisabled`, no day between the two is one
|
|
11654
|
+
* that `shouldDisableDate` or `unselectableDates` disables. Checking that
|
|
11655
|
+
* walks the days between, so with either rule set and `allowDisabled` off,
|
|
11656
|
+
* an `end` more than {@link RANGE_WALK_LIMIT} days after `start` is refused.
|
|
11657
|
+
* The ends' own constraints, `min` and `max` among them, are the caller's to
|
|
11658
|
+
* check. Bounds can't fall between two days inside them, so they are not
|
|
11659
|
+
* walked.
|
|
11660
|
+
*/
|
|
11661
|
+
function canCloseRange(start, end, c, allowDisabled = false) {
|
|
11662
|
+
const first = startOfDay(start);
|
|
11663
|
+
const last = startOfDay(end).getTime();
|
|
11664
|
+
if (last < first.getTime())
|
|
11665
|
+
return false;
|
|
11666
|
+
if (allowDisabled)
|
|
11667
|
+
return true;
|
|
11668
|
+
const blocks = {
|
|
11669
|
+
shouldDisableDate: c.shouldDisableDate,
|
|
11670
|
+
unselectableDates: c.unselectableDates,
|
|
11671
|
+
};
|
|
11672
|
+
if (!blocks.shouldDisableDate && !blocks.unselectableDates?.length) {
|
|
11673
|
+
return true;
|
|
11674
|
+
}
|
|
11675
|
+
for (let d = addDays(first, 1), walked = 1; d.getTime() < last; d = addDays(d, 1), walked++) {
|
|
11676
|
+
if (walked >= RANGE_WALK_LIMIT || isDayUnselectable(d, blocks)) {
|
|
11677
|
+
return false;
|
|
11678
|
+
}
|
|
11679
|
+
}
|
|
11680
|
+
return true;
|
|
11681
|
+
}
|
|
11637
11682
|
function addDays(d, n) {
|
|
11638
11683
|
const r = new Date(d);
|
|
11639
11684
|
r.setDate(r.getDate() + n);
|
|
@@ -12094,6 +12139,28 @@ function nearestEnabled(i, disabled) {
|
|
|
12094
12139
|
}
|
|
12095
12140
|
return i;
|
|
12096
12141
|
}
|
|
12142
|
+
/** The long, spoken form of a date in a range's announcement. */
|
|
12143
|
+
const LONG_DATE = {
|
|
12144
|
+
year: 'numeric',
|
|
12145
|
+
month: 'long',
|
|
12146
|
+
day: 'numeric',
|
|
12147
|
+
};
|
|
12148
|
+
/** A range's pending start: its start, when it has no end. */
|
|
12149
|
+
const pendingStartOf = (range) => range?.[0] && !range[1] ? startOfDay(range[0]) : null;
|
|
12150
|
+
/**
|
|
12151
|
+
* The day grid's cells in rows of a week. A grid owns rows and rows own
|
|
12152
|
+
* cells, so assistive technology can walk the grid, and the selection it
|
|
12153
|
+
* reports, row by row.
|
|
12154
|
+
*/
|
|
12155
|
+
const inWeeks = (days, className) => {
|
|
12156
|
+
const rows = [];
|
|
12157
|
+
for (let i = 0; i < days.length; i += 7) {
|
|
12158
|
+
rows.push(jsx("div", { role: "row", className: className, children: days.slice(i, i + 7) }, i));
|
|
12159
|
+
}
|
|
12160
|
+
return rows;
|
|
12161
|
+
};
|
|
12162
|
+
/** A date's time, or `null` for none, for comparing ranges by value. */
|
|
12163
|
+
const timeOf = (d) => d ? d.getTime() : null;
|
|
12097
12164
|
/**
|
|
12098
12165
|
* The year list's keyboard, as the selection surface and as navigation:
|
|
12099
12166
|
* arrows move a year or a row, Home/End go to the list's ends. Returns the
|
|
@@ -12119,7 +12186,7 @@ function yearStep(key, focusedYear, years) {
|
|
|
12119
12186
|
return null;
|
|
12120
12187
|
}
|
|
12121
12188
|
}
|
|
12122
|
-
const Calendar = ({ value, focusedDate, onSelect, onFocusedDateChange, min: minProp, max, shouldDisableDate, unselectableDates, firstDayOfWeek = 0, locale, dayNames, monthNames, nearbyMonthDays = true, color, size, className, id, autoFocusCell = false, labels, yearsRange, granularity = 'day', }) => {
|
|
12189
|
+
const Calendar = ({ value, focusedDate, onSelect, onFocusedDateChange, min: minProp, max, shouldDisableDate, unselectableDates, firstDayOfWeek = 0, locale, dayNames, monthNames, nearbyMonthDays = true, color, size, className, id, autoFocusCell = false, labels, yearsRange, granularity = 'day', range, onRangeSelect, allowDisabledInRange = false, }) => {
|
|
12123
12190
|
const gridRef = useRef(null);
|
|
12124
12191
|
const monthGridRef = useRef(null);
|
|
12125
12192
|
const yearGridRef = useRef(null);
|
|
@@ -12176,6 +12243,80 @@ const Calendar = ({ value, focusedDate, onSelect, onFocusedDateChange, min: minP
|
|
|
12176
12243
|
const i = nearestEnabled(focusedDate.getDate() - 1, days.map(isDateUnselectable));
|
|
12177
12244
|
return days[i];
|
|
12178
12245
|
}, [cells, focusedDate, isDateUnselectable]);
|
|
12246
|
+
// ----- Range mode -----
|
|
12247
|
+
// Range props come only with the day grid.
|
|
12248
|
+
const rangeMode = !!range;
|
|
12249
|
+
const valuePending = pendingStartOf(range);
|
|
12250
|
+
// The start of a range being picked, which nothing outside the calendar
|
|
12251
|
+
// sees until its end is picked too. It starts as the range's own pending
|
|
12252
|
+
// start, and starts there again whenever the range changes from outside.
|
|
12253
|
+
const [anchor, setAnchor] = useState(valuePending);
|
|
12254
|
+
const rangeKey = `${timeOf(range?.[0])}|${timeOf(range?.[1])}`;
|
|
12255
|
+
const [anchorRangeKey, setAnchorRangeKey] = useState(rangeKey);
|
|
12256
|
+
if (anchorRangeKey !== rangeKey) {
|
|
12257
|
+
setAnchorRangeKey(rangeKey);
|
|
12258
|
+
setAnchor(valuePending);
|
|
12259
|
+
}
|
|
12260
|
+
// The day under the pointer while a start is pending, which the preview
|
|
12261
|
+
// runs to ahead of the focused day.
|
|
12262
|
+
const [hoverDate, setHoverDate] = useState(null);
|
|
12263
|
+
// Whether `day` can end a range that starts on `start`. The start is
|
|
12264
|
+
// checked as well as the end: one the range brought, or one picked before
|
|
12265
|
+
// the bounds or the disabled days changed, can rule itself out.
|
|
12266
|
+
const canEndAt = useCallback((start, day) => !isDateUnselectable(start) &&
|
|
12267
|
+
!isDateUnselectable(day) &&
|
|
12268
|
+
canCloseRange(start, day, { shouldDisableDate, unselectableDates }, allowDisabledInRange), [
|
|
12269
|
+
isDateUnselectable,
|
|
12270
|
+
shouldDisableDate,
|
|
12271
|
+
unselectableDates,
|
|
12272
|
+
allowDisabledInRange,
|
|
12273
|
+
]);
|
|
12274
|
+
// A pick in range mode: the end of the pending range when it can be one,
|
|
12275
|
+
// and otherwise the start of a new one.
|
|
12276
|
+
const pickRangeDay = useCallback((picked) => {
|
|
12277
|
+
const day = startOfDay(picked);
|
|
12278
|
+
// The pointer is on the picked day, which the focused day now is too.
|
|
12279
|
+
setHoverDate(null);
|
|
12280
|
+
if (anchor && canEndAt(anchor, day)) {
|
|
12281
|
+
setAnchor(null);
|
|
12282
|
+
onRangeSelect?.(anchor, day);
|
|
12283
|
+
}
|
|
12284
|
+
else {
|
|
12285
|
+
setAnchor(day);
|
|
12286
|
+
}
|
|
12287
|
+
}, [anchor, canEndAt, onRangeSelect]);
|
|
12288
|
+
// What the grid shows: while a start is pending, the range from it to the
|
|
12289
|
+
// hovered or focused day, when that day can end it; otherwise the
|
|
12290
|
+
// committed range.
|
|
12291
|
+
let shownStart;
|
|
12292
|
+
let shownEnd;
|
|
12293
|
+
if (anchor) {
|
|
12294
|
+
shownStart = anchor;
|
|
12295
|
+
const previewEnd = startOfDay(hoverDate ?? focusedDate);
|
|
12296
|
+
shownEnd = canEndAt(anchor, previewEnd) ? previewEnd : null;
|
|
12297
|
+
}
|
|
12298
|
+
else {
|
|
12299
|
+
shownStart = range?.[0] ? startOfDay(range[0]) : null;
|
|
12300
|
+
shownEnd = range?.[1] ? startOfDay(range[1]) : null;
|
|
12301
|
+
}
|
|
12302
|
+
const previewing = !!anchor;
|
|
12303
|
+
// Ids for the words that name a range's ends and state the whole range.
|
|
12304
|
+
const reactId = useId();
|
|
12305
|
+
const rangeIdBase = id ?? `calendar-${reactId}`;
|
|
12306
|
+
const rangeStartId = `${rangeIdBase}-range-start`;
|
|
12307
|
+
const rangeEndId = `${rangeIdBase}-range-end`;
|
|
12308
|
+
const rangePreviewEndId = `${rangeIdBase}-range-preview-end`;
|
|
12309
|
+
const rangeSummaryId = `${rangeIdBase}-range-summary`;
|
|
12310
|
+
// The selection in words: the pending start alone, or the committed ends.
|
|
12311
|
+
const selectedEnd = previewing ? null : shownEnd;
|
|
12312
|
+
const rangeSummary = [
|
|
12313
|
+
shownStart &&
|
|
12314
|
+
`${t.rangeStart}: ${formatDate(shownStart, LONG_DATE, locale)}`,
|
|
12315
|
+
selectedEnd &&
|
|
12316
|
+
`${t.rangeEnd}: ${formatDate(selectedEnd, LONG_DATE, locale)}`,
|
|
12317
|
+
]
|
|
12318
|
+
.filter(Boolean)
|
|
12319
|
+
.join(', ');
|
|
12179
12320
|
// Whether the grid on show holds focus, or held it last before focus went
|
|
12180
12321
|
// nowhere: the cell that had it left the page or became disabled. A blur
|
|
12181
12322
|
// that takes focus out of the grid, to nowhere included, is the user
|
|
@@ -12213,6 +12354,8 @@ const Calendar = ({ value, focusedDate, onSelect, onFocusedDateChange, min: minP
|
|
|
12213
12354
|
}
|
|
12214
12355
|
}, [min, max, isDateUnselectable, onFocusedDateChange]);
|
|
12215
12356
|
const handleKeyDown = useCallback((e) => {
|
|
12357
|
+
// A key takes the range preview back from the pointer.
|
|
12358
|
+
setHoverDate(null);
|
|
12216
12359
|
switch (e.key) {
|
|
12217
12360
|
case 'ArrowLeft':
|
|
12218
12361
|
e.preventDefault();
|
|
@@ -12255,11 +12398,35 @@ const Calendar = ({ value, focusedDate, onSelect, onFocusedDateChange, min: minP
|
|
|
12255
12398
|
case 'Enter':
|
|
12256
12399
|
case ' ':
|
|
12257
12400
|
e.preventDefault();
|
|
12258
|
-
if (
|
|
12259
|
-
|
|
12401
|
+
if (isDateUnselectable(focusedDate))
|
|
12402
|
+
break;
|
|
12403
|
+
if (rangeMode)
|
|
12404
|
+
pickRangeDay(focusedDate);
|
|
12405
|
+
else
|
|
12406
|
+
onSelect?.(focusedDate);
|
|
12407
|
+
break;
|
|
12408
|
+
case 'Escape':
|
|
12409
|
+
// A pending pick is taken back, and the key stops there so a
|
|
12410
|
+
// popover around the calendar stays open. The range's own pending
|
|
12411
|
+
// start is no pick, so Escape goes on to close the popover.
|
|
12412
|
+
if (anchor && !(valuePending && isSameDay(anchor, valuePending))) {
|
|
12413
|
+
e.preventDefault();
|
|
12414
|
+
e.stopPropagation();
|
|
12415
|
+
setAnchor(valuePending);
|
|
12416
|
+
}
|
|
12260
12417
|
break;
|
|
12261
12418
|
}
|
|
12262
|
-
}, [
|
|
12419
|
+
}, [
|
|
12420
|
+
focusedDate,
|
|
12421
|
+
firstDayOfWeek,
|
|
12422
|
+
isDateUnselectable,
|
|
12423
|
+
moveFocus,
|
|
12424
|
+
onSelect,
|
|
12425
|
+
rangeMode,
|
|
12426
|
+
pickRangeDay,
|
|
12427
|
+
anchor,
|
|
12428
|
+
valuePending,
|
|
12429
|
+
]);
|
|
12263
12430
|
// The month grid's counterpart to `moveFocus`: step by `direction` months
|
|
12264
12431
|
// until a month with a selectable day turns up, stopping at the min/max
|
|
12265
12432
|
// months. The cap guards against a range with nothing selectable.
|
|
@@ -12282,7 +12449,7 @@ const Calendar = ({ value, focusedDate, onSelect, onFocusedDateChange, min: minP
|
|
|
12282
12449
|
if (e.key === 'Enter' || e.key === ' ') {
|
|
12283
12450
|
e.preventDefault();
|
|
12284
12451
|
if (!isMonthUnselectable(focusedDate)) {
|
|
12285
|
-
onSelect(startOfMonth(focusedDate));
|
|
12452
|
+
onSelect?.(startOfMonth(focusedDate));
|
|
12286
12453
|
}
|
|
12287
12454
|
return;
|
|
12288
12455
|
}
|
|
@@ -12308,6 +12475,7 @@ const Calendar = ({ value, focusedDate, onSelect, onFocusedDateChange, min: minP
|
|
|
12308
12475
|
const dayNamesRowClass = usePrefixedClassNames('dateinput-day-names');
|
|
12309
12476
|
const dayNameClass = usePrefixedClassNames('dateinput-day-name');
|
|
12310
12477
|
const gridClass = usePrefixedClassNames('dateinput-grid');
|
|
12478
|
+
const weekClass = usePrefixedClassNames('dateinput-week');
|
|
12311
12479
|
const monthsGridClass = usePrefixedClassNames('dateinput-months-grid');
|
|
12312
12480
|
const monthsRowClass = usePrefixedClassNames('dateinput-months-row');
|
|
12313
12481
|
const yearsGridClass = usePrefixedClassNames('dateinput-years-grid');
|
|
@@ -12397,7 +12565,7 @@ const Calendar = ({ value, focusedDate, onSelect, onFocusedDateChange, min: minP
|
|
|
12397
12565
|
// pick and `onSelect` gets the year's first day.
|
|
12398
12566
|
const handleYearPick = useCallback((year) => {
|
|
12399
12567
|
onFocusedDateChange(clampDate(makeDate(year), min, max));
|
|
12400
|
-
onSelect(makeDate(year));
|
|
12568
|
+
onSelect?.(makeDate(year));
|
|
12401
12569
|
}, [min, max, onFocusedDateChange, onSelect]);
|
|
12402
12570
|
// Step through the listed years from `year` by `direction`, skipping
|
|
12403
12571
|
// disabled ones, and focus the first selectable year found.
|
|
@@ -12518,32 +12686,69 @@ const Calendar = ({ value, focusedDate, onSelect, onFocusedDateChange, min: minP
|
|
|
12518
12686
|
return (jsxs("div", { className: classNames(calendarClass, className), id: id, children: [jsxs("div", { className: headerClass, children: [isYearGranularity ? (jsx("span", { className: monthLabelClass, id: labelId, children: monthLabel })) : (jsxs("button", { type: "button", className: monthTriggerClass, "aria-haspopup": "listbox", "aria-expanded": view === 'years', onClick: () => {
|
|
12519
12687
|
setNavYear(null);
|
|
12520
12688
|
setView(v => (v === 'years' ? baseView : 'years'));
|
|
12521
|
-
}, children: [jsx("span", { className: monthLabelClass, id: labelId, "aria-live": "polite", children: monthLabel }), jsx("svg", { className: monthCaretClass, viewBox: "0 0 12 12", width: "10", height: "10", "aria-hidden": "true", children: jsx("path", { d: "M2 4l4 4 4-4", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" }) })] })), !isYearGranularity && (jsxs("div", { className: navGroupClass, children: [jsx("button", { type: "button", className: navPrevClass, "aria-label": isDayGranularity ? t.prevMonth : t.prevYear, disabled: prevDisabled || view !== baseView, onClick: () => onFocusedDateChange(prevAnchor), children: navArrow('M10 3l-5 5 5 5') }), jsx("button", { type: "button", className: navNextClass, "aria-label": isDayGranularity ? t.nextMonth : t.nextYear, disabled: nextDisabled || view !== baseView, onClick: () => onFocusedDateChange(nextAnchor), children: navArrow('M6 3l5 5-5 5') })] }))] }), view === 'days' && (jsxs(Fragment, { children: [jsx("div", { className: dayNamesRowClass, "aria-hidden": "true", children: computedDayNames.map((name, i) => (jsx("div", { className: dayNameClass, children: name }, i))) }), jsx("div", { ref: gridRef, role: "grid", "aria-labelledby": labelId, className: gridClass, onKeyDown: handleKeyDown, ...gridFocusHandlers, children: cells.map(cell => {
|
|
12689
|
+
}, children: [jsx("span", { className: monthLabelClass, id: labelId, "aria-live": "polite", children: monthLabel }), jsx("svg", { className: monthCaretClass, viewBox: "0 0 12 12", width: "10", height: "10", "aria-hidden": "true", children: jsx("path", { d: "M2 4l4 4 4-4", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" }) })] })), !isYearGranularity && (jsxs("div", { className: navGroupClass, children: [jsx("button", { type: "button", className: navPrevClass, "aria-label": isDayGranularity ? t.prevMonth : t.prevYear, disabled: prevDisabled || view !== baseView, onClick: () => onFocusedDateChange(prevAnchor), children: navArrow('M10 3l-5 5 5 5') }), jsx("button", { type: "button", className: navNextClass, "aria-label": isDayGranularity ? t.nextMonth : t.nextYear, disabled: nextDisabled || view !== baseView, onClick: () => onFocusedDateChange(nextAnchor), children: navArrow('M6 3l5 5-5 5') })] }))] }), view === 'days' && (jsxs(Fragment, { children: [jsx("div", { className: dayNamesRowClass, "aria-hidden": "true", children: computedDayNames.map((name, i) => (jsx("div", { className: dayNameClass, children: name }, i))) }), jsx("div", { ref: gridRef, role: "grid", "aria-labelledby": labelId, "aria-multiselectable": rangeMode || undefined, "aria-describedby": rangeMode ? rangeSummaryId : undefined, className: gridClass, onKeyDown: handleKeyDown, onMouseLeave: anchor ? () => setHoverDate(null) : undefined, ...gridFocusHandlers, children: inWeeks(cells.map(cell => {
|
|
12522
12690
|
const disabled = isDateUnselectable(cell.date);
|
|
12523
|
-
const
|
|
12691
|
+
const time = cell.date.getTime();
|
|
12692
|
+
// Range mode. The range on show has its ends filled. Every day
|
|
12693
|
+
// of a committed range is selected, and of a preview only the
|
|
12694
|
+
// start.
|
|
12695
|
+
const isStart = time === timeOf(shownStart);
|
|
12696
|
+
const isEnd = time === timeOf(shownEnd);
|
|
12697
|
+
const inRange = !!shownStart &&
|
|
12698
|
+
!!shownEnd &&
|
|
12699
|
+
time > shownStart.getTime() &&
|
|
12700
|
+
time < shownEnd.getTime();
|
|
12701
|
+
// The day a pending range would end on, which isn't picked
|
|
12702
|
+
// yet, so its description says what picking it does.
|
|
12703
|
+
const isPreviewEnd = previewing && isEnd && !isStart;
|
|
12704
|
+
const isPreview = (previewing && inRange) || isPreviewEnd;
|
|
12705
|
+
const isFilled = rangeMode
|
|
12706
|
+
? isStart || (isEnd && !previewing)
|
|
12707
|
+
: !!value && isSameDay(value, cell.date);
|
|
12708
|
+
const isSelected = isFilled || (rangeMode && !previewing && inRange);
|
|
12709
|
+
const describedBy = rangeMode
|
|
12710
|
+
? [
|
|
12711
|
+
isStart && rangeStartId,
|
|
12712
|
+
isEnd && !previewing && rangeEndId,
|
|
12713
|
+
isPreviewEnd && rangePreviewEndId,
|
|
12714
|
+
]
|
|
12715
|
+
.filter(Boolean)
|
|
12716
|
+
.join(' ') || undefined
|
|
12717
|
+
: undefined;
|
|
12524
12718
|
const isFocused = isSameDay(cell.date, tabStopDay);
|
|
12525
12719
|
const otherMonth = !cell.inCurrentMonth;
|
|
12526
12720
|
const cellClass = prefixedClassNames(classPrefix, 'dateinput-cell', {
|
|
12527
|
-
'is-selected':
|
|
12721
|
+
'is-selected': isFilled,
|
|
12722
|
+
'is-range-start': isStart,
|
|
12723
|
+
'is-range-end': isEnd,
|
|
12724
|
+
'is-in-range': inRange,
|
|
12725
|
+
'is-preview': isPreview,
|
|
12528
12726
|
'is-today': cell.isToday,
|
|
12529
12727
|
'is-disabled': disabled,
|
|
12530
12728
|
'is-other-month': otherMonth,
|
|
12531
12729
|
});
|
|
12532
12730
|
const display = !otherMonth || nearbyMonthDays;
|
|
12533
|
-
return (jsx("button", { type: "button", role: "gridcell", tabIndex: isFocused ? 0 : -1, "aria-selected": isSelected, "aria-disabled": disabled, "aria-current": cell.isToday ? 'date' : undefined, "data-focused": isFocused ? 'true' : undefined, disabled: disabled || !display, className: cellClass, onFocus: () => {
|
|
12731
|
+
return (jsx("button", { type: "button", role: "gridcell", tabIndex: isFocused ? 0 : -1, "aria-selected": isSelected, "aria-disabled": disabled, "aria-current": cell.isToday ? 'date' : undefined, "aria-describedby": describedBy, "data-focused": isFocused ? 'true' : undefined, disabled: disabled || !display, className: cellClass, onFocus: () => {
|
|
12534
12732
|
// Reached by Tab while the focused day is disabled, or
|
|
12535
12733
|
// by pointer: keys move on from here. A nearby month's
|
|
12536
12734
|
// day waits for its click, which turns the grid.
|
|
12537
12735
|
if (!otherMonth && !isSameDay(cell.date, focusedDate)) {
|
|
12538
12736
|
onFocusedDateChange(cell.date);
|
|
12539
12737
|
}
|
|
12540
|
-
},
|
|
12738
|
+
},
|
|
12739
|
+
// Mouseover rather than mouseenter: browsers send it to a
|
|
12740
|
+
// disabled day as well, where React holds mouseenter back,
|
|
12741
|
+
// so the preview leaves the last enabled day behind.
|
|
12742
|
+
onMouseOver: anchor ? () => setHoverDate(cell.date) : undefined, onClick: () => {
|
|
12541
12743
|
if (disabled)
|
|
12542
12744
|
return;
|
|
12543
12745
|
onFocusedDateChange(cell.date);
|
|
12544
|
-
|
|
12746
|
+
if (rangeMode)
|
|
12747
|
+
pickRangeDay(cell.date);
|
|
12748
|
+
else
|
|
12749
|
+
onSelect?.(cell.date);
|
|
12545
12750
|
}, style: !display ? { visibility: 'hidden' } : undefined, children: cell.date.getDate() }, cell.date.toISOString()));
|
|
12546
|
-
}) })] })), view === 'months' && (jsx("div", { ref: monthGridRef, role: "grid", "aria-labelledby": labelId, className: monthsGridClass, onKeyDown: handleMonthKeyDown, ...gridFocusHandlers, children: MONTH_ROWS.map(row => (jsx("div", { role: "row", className: monthsRowClass, children: row.map(month => {
|
|
12751
|
+
}), weekClass) })] })), view === 'months' && (jsx("div", { ref: monthGridRef, role: "grid", "aria-labelledby": labelId, className: monthsGridClass, onKeyDown: handleMonthKeyDown, ...gridFocusHandlers, children: MONTH_ROWS.map(row => (jsx("div", { role: "row", className: monthsRowClass, children: row.map(month => {
|
|
12547
12752
|
const date = makeDate(focusedYear, month);
|
|
12548
12753
|
const disabled = disabledMonths[month];
|
|
12549
12754
|
const isSelected = !!value && isSameMonth(value, date);
|
|
@@ -12562,7 +12767,7 @@ const Calendar = ({ value, focusedDate, onSelect, onFocusedDateChange, min: minP
|
|
|
12562
12767
|
}
|
|
12563
12768
|
}, onClick: () => {
|
|
12564
12769
|
onFocusedDateChange(clampDate(date, min, max));
|
|
12565
|
-
onSelect(date);
|
|
12770
|
+
onSelect?.(date);
|
|
12566
12771
|
}, children: monthCellNames[month] }, month));
|
|
12567
12772
|
}) }, row[0]))) })), view === 'years' && (jsx("div", { ref: yearGridRef, className: yearsGridClass, role: "listbox", "aria-label": isYearGranularity ? t.chooseYear : monthLabel, onKeyDown: handleYearListKeyDown, children: yearList.map(year => {
|
|
12568
12773
|
const isFocused = year === tabStopYear;
|
|
@@ -12593,7 +12798,7 @@ const Calendar = ({ value, focusedDate, onSelect, onFocusedDateChange, min: minP
|
|
|
12593
12798
|
}, onClick: () => isYearGranularity
|
|
12594
12799
|
? handleYearPick(year)
|
|
12595
12800
|
: handleYearSelect(year), children: year }, year));
|
|
12596
|
-
}) }))] }));
|
|
12801
|
+
}) })), rangeMode && (jsxs(Fragment, { children: [jsx("span", { id: rangeStartId, hidden: true, children: t.rangeStart }), jsx("span", { id: rangeEndId, hidden: true, children: t.rangeEnd }), jsx("span", { id: rangePreviewEndId, hidden: true, children: t.rangePreviewEnd }), jsx("div", { id: rangeSummaryId, "aria-live": "polite", style: visuallyHidden, children: rangeSummary })] }))] }));
|
|
12597
12802
|
};
|
|
12598
12803
|
Calendar.displayName = 'Calendar';
|
|
12599
12804
|
|