UNPKG

@fluentui/react

Version:

Reusable React components for building web experiences.

251 lines 14.3 kB
import { __assign, __spreadArray } from "tslib"; import * as React from 'react'; import { KeyCodes, getRTL, classNamesFunction, css, format } from '../../../Utilities'; import { FocusZone } from '../../../FocusZone'; import { Icon } from '../../../Icon'; import { usePrevious } from '@fluentui/react-hooks'; import { defaultCalendarNavigationIcons } from '../defaults'; var getClassNames = classNamesFunction(); var CELL_COUNT = 12; var CELLS_PER_ROW = 4; var DefaultCalendarYearStrings = { prevRangeAriaLabel: undefined, nextRangeAriaLabel: undefined, }; var CalendarYearGridCell = function (props) { var _a; var _b; var styles = props.styles, theme = props.theme, className = props.className, highlightCurrentYear = props.highlightCurrentYear, highlightSelectedYear = props.highlightSelectedYear, year = props.year, selected = props.selected, disabled = props.disabled, componentRef = props.componentRef, onSelectYear = props.onSelectYear, onRenderYear = props.onRenderYear; var buttonRef = React.useRef(null); React.useImperativeHandle(componentRef, function () { return ({ focus: function () { var _a, _b; (_b = (_a = buttonRef.current) === null || _a === void 0 ? void 0 : _a.focus) === null || _b === void 0 ? void 0 : _b.call(_a); }, }); }, []); var onClick = function () { onSelectYear === null || onSelectYear === void 0 ? void 0 : onSelectYear(year); }; var onKeyDown = function (ev) { // eslint-disable-next-line deprecation/deprecation if (ev.which === KeyCodes.enter) { onSelectYear === null || onSelectYear === void 0 ? void 0 : onSelectYear(year); } }; var classNames = getClassNames(styles, { theme: theme, className: className, highlightCurrent: highlightCurrentYear, highlightSelected: highlightSelectedYear, }); return (React.createElement("button", { className: css(classNames.itemButton, (_a = {}, _a[classNames.selected] = selected, _a[classNames.disabled] = disabled, _a)), type: "button", role: "gridcell", onClick: !disabled ? onClick : undefined, onKeyDown: !disabled ? onKeyDown : undefined, disabled: disabled, "aria-selected": selected, ref: buttonRef }, (_b = onRenderYear === null || onRenderYear === void 0 ? void 0 : onRenderYear(year)) !== null && _b !== void 0 ? _b : year)); }; CalendarYearGridCell.displayName = 'CalendarYearGridCell'; var CalendarYearGrid = function (props) { var styles = props.styles, theme = props.theme, className = props.className, fromYear = props.fromYear, toYear = props.toYear, animationDirection = props.animationDirection, animateBackwards = props.animateBackwards, minYear = props.minYear, maxYear = props.maxYear, onSelectYear = props.onSelectYear, selectedYear = props.selectedYear, componentRef = props.componentRef; var selectedCellRef = React.useRef(null); var currentCellRef = React.useRef(null); React.useImperativeHandle(componentRef, function () { return ({ focus: function () { var _a, _b; (_b = (_a = (selectedCellRef.current || currentCellRef.current)) === null || _a === void 0 ? void 0 : _a.focus) === null || _b === void 0 ? void 0 : _b.call(_a); }, }); }, []); var renderCell = function (yearToRender) { var selected = yearToRender === selectedYear; var disabled = (minYear !== undefined && yearToRender < minYear) || (maxYear !== undefined && yearToRender > maxYear); var current = yearToRender === new Date().getFullYear(); return (React.createElement(CalendarYearGridCell, __assign({}, props, { key: yearToRender, year: yearToRender, selected: selected, current: current, disabled: disabled, onSelectYear: onSelectYear, componentRef: selected ? selectedCellRef : current ? currentCellRef : undefined, theme: theme }))); }; var classNames = getClassNames(styles, { theme: theme, className: className, animateBackwards: animateBackwards, animationDirection: animationDirection, }); var onRenderYear = function (value) { var _a, _b; return (_b = (_a = props.onRenderYear) === null || _a === void 0 ? void 0 : _a.call(props, value)) !== null && _b !== void 0 ? _b : value; }; var gridAriaLabel = "".concat(onRenderYear(fromYear), " - ").concat(onRenderYear(toYear)); var year = fromYear; var cells = []; for (var i = 0; i < (toYear - fromYear + 1) / CELLS_PER_ROW; i++) { cells.push([]); for (var j = 0; j < CELLS_PER_ROW; j++) { cells[i].push(renderCell(year)); year++; } } return (React.createElement(FocusZone, null, React.createElement("div", { className: classNames.gridContainer, role: "grid", "aria-label": gridAriaLabel }, cells.map(function (cellRow, index) { return (React.createElement.apply(React, __spreadArray(["div", { key: 'yearPickerRow_' + index + '_' + fromYear, role: "row", className: classNames.buttonRow }], cellRow, false))); })))); }; CalendarYearGrid.displayName = 'CalendarYearGrid'; var CalendarYearNavDirection; (function (CalendarYearNavDirection) { CalendarYearNavDirection[CalendarYearNavDirection["Previous"] = 0] = "Previous"; CalendarYearNavDirection[CalendarYearNavDirection["Next"] = 1] = "Next"; })(CalendarYearNavDirection || (CalendarYearNavDirection = {})); var CalendarYearNavArrow = function (props) { var _a; var styles = props.styles, theme = props.theme, className = props.className, _b = props.navigationIcons, navigationIcons = _b === void 0 ? defaultCalendarNavigationIcons : _b, _c = props.strings, strings = _c === void 0 ? DefaultCalendarYearStrings : _c, direction = props.direction, onSelectPrev = props.onSelectPrev, onSelectNext = props.onSelectNext, fromYear = props.fromYear, toYear = props.toYear, maxYear = props.maxYear, minYear = props.minYear; var classNames = getClassNames(styles, { theme: theme, className: className, }); var ariaLabel = direction === CalendarYearNavDirection.Previous ? strings.prevRangeAriaLabel : strings.nextRangeAriaLabel; var newRangeOffset = direction === CalendarYearNavDirection.Previous ? -CELL_COUNT : CELL_COUNT; var newRange = { fromYear: fromYear + newRangeOffset, toYear: toYear + newRangeOffset }; var ariaLabelString = ariaLabel ? (typeof ariaLabel === 'string' ? ariaLabel : ariaLabel(newRange)) : undefined; var disabled = direction === CalendarYearNavDirection.Previous ? minYear !== undefined && fromYear < minYear : maxYear !== undefined && props.fromYear + CELL_COUNT > maxYear; var onNavigate = function () { direction === CalendarYearNavDirection.Previous ? onSelectPrev === null || onSelectPrev === void 0 ? void 0 : onSelectPrev() : onSelectNext === null || onSelectNext === void 0 ? void 0 : onSelectNext(); }; var onKeyDown = function (ev) { // eslint-disable-next-line deprecation/deprecation if (ev.which === KeyCodes.enter) { onNavigate(); } }; // can be condensed, but leaving verbose for clarity due to regressions var isLeftNavigation = getRTL() ? direction === CalendarYearNavDirection.Next : direction === CalendarYearNavDirection.Previous; return (React.createElement("button", { className: css(classNames.navigationButton, (_a = {}, _a[classNames.disabled] = disabled, _a)), onClick: !disabled ? onNavigate : undefined, onKeyDown: !disabled ? onKeyDown : undefined, type: "button", title: ariaLabelString, disabled: disabled }, React.createElement(Icon, { iconName: isLeftNavigation ? navigationIcons.leftNavigation : navigationIcons.rightNavigation }))); }; CalendarYearNavArrow.displayName = 'CalendarYearNavArrow'; var CalendarYearNav = function (props) { var styles = props.styles, theme = props.theme, className = props.className; var classNames = getClassNames(styles, { theme: theme, className: className, }); return (React.createElement("div", { className: classNames.navigationButtonsContainer }, React.createElement(CalendarYearNavArrow, __assign({}, props, { direction: CalendarYearNavDirection.Previous })), React.createElement(CalendarYearNavArrow, __assign({}, props, { direction: CalendarYearNavDirection.Next })))); }; CalendarYearNav.displayName = 'CalendarYearNav'; var CalendarYearTitle = function (props) { var styles = props.styles, theme = props.theme, className = props.className, fromYear = props.fromYear, toYear = props.toYear, _a = props.strings, strings = _a === void 0 ? DefaultCalendarYearStrings : _a, animateBackwards = props.animateBackwards, animationDirection = props.animationDirection; var onHeaderSelect = function () { var _a; (_a = props.onHeaderSelect) === null || _a === void 0 ? void 0 : _a.call(props, true); }; var onHeaderKeyDown = function (ev) { // eslint-disable-next-line deprecation/deprecation if (ev.which === KeyCodes.enter || ev.which === KeyCodes.space) { onHeaderSelect(); } }; var onRenderYear = function (year) { var _a, _b; return (_b = (_a = props.onRenderYear) === null || _a === void 0 ? void 0 : _a.call(props, year)) !== null && _b !== void 0 ? _b : year; }; var classNames = getClassNames(styles, { theme: theme, className: className, hasHeaderClickCallback: !!props.onHeaderSelect, animateBackwards: animateBackwards, animationDirection: animationDirection, }); if (props.onHeaderSelect) { var rangeAriaLabel = strings.rangeAriaLabel; var headerAriaLabelFormatString = strings.headerAriaLabelFormatString; var currentDateRange = rangeAriaLabel ? typeof rangeAriaLabel === 'string' ? rangeAriaLabel : rangeAriaLabel(props) : undefined; var ariaLabel = headerAriaLabelFormatString ? format(headerAriaLabelFormatString, currentDateRange) : currentDateRange; return (React.createElement("button", { className: classNames.currentItemButton, onClick: onHeaderSelect, onKeyDown: onHeaderKeyDown, "aria-label": ariaLabel, role: "button", type: "button" }, React.createElement("span", { "aria-live": "assertive", "aria-atomic": "true" }, onRenderYear(fromYear), " - ", onRenderYear(toYear)))); } return (React.createElement("div", { className: classNames.current }, onRenderYear(fromYear), " - ", onRenderYear(toYear))); }; CalendarYearTitle.displayName = 'CalendarYearTitle'; var CalendarYearHeader = function (props) { var _a; var styles = props.styles, theme = props.theme, className = props.className, animateBackwards = props.animateBackwards, animationDirection = props.animationDirection, onRenderTitle = props.onRenderTitle; var classNames = getClassNames(styles, { theme: theme, className: className, hasHeaderClickCallback: !!props.onHeaderSelect, animateBackwards: animateBackwards, animationDirection: animationDirection, }); return (React.createElement("div", { className: classNames.headerContainer }, (_a = onRenderTitle === null || onRenderTitle === void 0 ? void 0 : onRenderTitle(props)) !== null && _a !== void 0 ? _a : React.createElement(CalendarYearTitle, __assign({}, props)), React.createElement(CalendarYearNav, __assign({}, props)))); }; CalendarYearHeader.displayName = 'CalendarYearHeader'; function useAnimateBackwards(_a) { var selectedYear = _a.selectedYear, navigatedYear = _a.navigatedYear; var rangeYear = selectedYear || navigatedYear || new Date().getFullYear(); var fromYear = Math.floor(rangeYear / 10) * 10; var previousFromYear = usePrevious(fromYear); if (!previousFromYear || previousFromYear === fromYear) { return undefined; } else if (previousFromYear > fromYear) { return true; } else { return false; } } function useYearRangeState(_a) { var selectedYear = _a.selectedYear, navigatedYear = _a.navigatedYear; var rangeYear = React.useMemo(function () { return selectedYear || navigatedYear || Math.floor(new Date().getFullYear() / 10) * 10; }, [navigatedYear, selectedYear]); var _b = React.useState(rangeYear), fromYear = _b[0], setFromYear = _b[1]; var onNavNext = function () { setFromYear(function (year) { return year + CELL_COUNT; }); }; var onNavPrevious = function () { setFromYear(function (year) { return year - CELL_COUNT; }); }; React.useEffect(function () { setFromYear(rangeYear); }, [rangeYear]); var toYear = fromYear + CELL_COUNT - 1; return [fromYear, toYear, onNavNext, onNavPrevious]; } export var CalendarYearBase = function (props) { var animateBackwards = useAnimateBackwards(props); var _a = useYearRangeState(props), fromYear = _a[0], toYear = _a[1], onNavNext = _a[2], onNavPrevious = _a[3]; var gridRef = React.useRef(null); React.useImperativeHandle(props.componentRef, function () { return ({ focus: function () { var _a, _b; (_b = (_a = gridRef.current) === null || _a === void 0 ? void 0 : _a.focus) === null || _b === void 0 ? void 0 : _b.call(_a); }, }); }); var styles = props.styles, theme = props.theme, className = props.className; var classNames = getClassNames(styles, { theme: theme, className: className, }); return (React.createElement("div", { className: classNames.root }, React.createElement(CalendarYearHeader, __assign({}, props, { fromYear: fromYear, toYear: toYear, onSelectPrev: onNavPrevious, onSelectNext: onNavNext, animateBackwards: animateBackwards })), React.createElement(CalendarYearGrid, __assign({}, props, { fromYear: fromYear, toYear: toYear, animateBackwards: animateBackwards, componentRef: gridRef })))); }; CalendarYearBase.displayName = 'CalendarYearBase'; //# sourceMappingURL=CalendarYear.base.js.map