Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | 14x 1932x 1932x 1932x 1932x 1386x 2x 1932x 1932x 1932x 1932x 1932x 1932x 1932x 1932x 1932x 1932x 1932x 1932x 1932x 1932x 1932x 1932x 1932x 1932x 1932x 1932x 1932x 1932x | import React from 'react';
import type {DateTime} from '@gravity-ui/date-utils';
import {useLang} from '@gravity-ui/uikit';
import {formatDateTime} from '../../utils/dates';
import type {CalendarState, RangeCalendarState} from './types';
export function useCalendarCellProps(date: DateTime, state: CalendarState | RangeCalendarState) {
const ref = React.useRef<HTMLDivElement>(null);
const {lang} = useLang();
const isFocused = state.isCellFocused(date);
React.useEffect(() => {
if (isFocused) {
ref.current?.focus({preventScroll: true});
}
}, [isFocused]);
const tabIndex = state.focusedDate.isSame(date, state.mode) ? 0 : -1;
const isDisabled = state.isCellDisabled(date);
const isSelected = state.isSelected(date);
const highlightedRange = 'highlightedRange' in state && state.highlightedRange;
const isRangeSelection = Boolean(highlightedRange && isSelected);
const isSelectionStart =
isSelected && highlightedRange && date.isSame(highlightedRange.start, state.mode);
const isSelectionEnd =
isSelected && highlightedRange && date.isSame(highlightedRange.end, state.mode);
const isOutsideCurrentRange =
state.mode === 'days' ? !state.focusedDate.isSame(date, 'month') : false;
const isUnavailable = state.isCellUnavailable(date);
const isSelectable = !isDisabled && !isUnavailable;
const isCurrent = state.isCurrent(date);
const isWeekend = state.isWeekend(date);
const label = getDateLabel(date, state, lang);
const cellProps: React.HTMLAttributes<unknown> = {
role: 'gridcell',
'aria-selected': isSelected ? 'true' : undefined,
'aria-disabled': isDisabled ? 'true' : undefined,
};
const buttonProps: React.HTMLAttributes<unknown> & {ref: React.Ref<HTMLDivElement>} = {
ref,
role: 'button',
tabIndex: isDisabled ? undefined : tabIndex,
'aria-disabled': isSelectable ? undefined : 'true',
'aria-label': label,
onClick: isSelectable
? () => {
state.setFocusedDate(date);
state.selectDate(date);
}
: undefined,
onPointerEnter() {
if ('highlightDate' in state && isSelectable) {
if (isOutsideCurrentRange) {
const newDate = date.isBefore(state.focusedDate)
? state.focusedDate.startOf('month')
: state.focusedDate.endOf('month').startOf('date');
state.highlightDate(newDate);
} else {
state.highlightDate(date);
}
}
},
};
let formattedDate = formatDateTime(date, 'D', state.timeZone, lang);
Iif (state.mode === 'months') {
formattedDate = formatDateTime(date, 'MMM', state.timeZone, lang);
I} else if (state.mode === 'quarters') {
formattedDate = formatDateTime(date, '[Q]Q', state.timeZone, lang);
I} else if (state.mode === 'years') {
formattedDate = formatDateTime(date, 'YYYY', state.timeZone, lang);
}
return {
cellProps,
buttonProps,
formattedDate,
isDisabled,
isSelected,
isRangeSelection,
isSelectionStart,
isSelectionEnd,
isOutsideCurrentRange,
isUnavailable,
isCurrent,
isWeekend,
};
}
function getDateLabel(date: DateTime, state: CalendarState | RangeCalendarState, lang: string) {
switch (state.mode) {
case 'days': {
return `${formatDateTime(date, 'dddd', state.timeZone, lang)}, ${formatDateTime(date, 'LL', state.timeZone, lang)}`;
}
case 'months': {
return `${formatDateTime(date, 'MMMM YYYY', state.timeZone, lang)}`;
}
case 'quarters': {
return `${formatDateTime(date, '[Q]Q YYYY', state.timeZone, lang)}`;
}
case 'years': {
return `${formatDateTime(date, 'YYYY', state.timeZone, lang)}`;
}
default:
return '';
}
}
|