@atlaskit/calendar
Version:
An interactive calendar for date selection experiences.
130 lines (128 loc) • 4.83 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import React, { memo, useState } from 'react';
import { IconButton } from '@atlaskit/button/new';
import { useId } from '@atlaskit/ds-lib/use-id';
import Heading from '@atlaskit/heading';
import ChevronDoubleLeftIcon from '@atlaskit/icon/core/chevron-double-left';
import ChevronDoubleRightIcon from '@atlaskit/icon/core/chevron-double-right';
import ChevronLeftIcon from '@atlaskit/icon/core/chevron-left';
import ChevronRightIcon from '@atlaskit/icon/core/chevron-right';
import { Box, Inline } from '@atlaskit/primitives/compiled';
const Header = /*#__PURE__*/memo(function Header({
monthLongTitle,
year,
previousMonthLabel = 'Previous month',
previousYearLabel = 'Previous year',
previousMonthHeading,
previousYearHeading,
nextMonthLabel = 'Next month',
nextYearLabel = 'Next year',
nextMonthHeading,
nextYearHeading,
handleClickPrevMonth,
handleClickPrevYear,
handleClickNextMonth,
handleClickNextYear,
headerId,
tabIndex,
testId
}) {
const announceId = useId();
// All of this is because `aria-atomic` is not fully supported for different
// assistive technologies. We want the value of the current month and year to
// be announced, but *only* if that value has been interacted with since
// being mounted. This allows us to conditionally apply the `aria-live`
// attribute. Without this, the `aria-live` property is set on mount and
// overrides the default input's readout in downstream consumers (e.g.
// datetime picker).
const [hasInteractedWithMonthOrYear, setHasInteractedWithMonthOrYear] = useState(false);
const handlePrevMonthInteraction = e => {
if (!hasInteractedWithMonthOrYear) {
setHasInteractedWithMonthOrYear(true);
}
handleClickPrevMonth(e);
};
const handlePrevYearInteraction = e => {
if (!hasInteractedWithMonthOrYear) {
setHasInteractedWithMonthOrYear(true);
}
handleClickPrevYear(e);
};
const handleNextMonthInteraction = e => {
if (!hasInteractedWithMonthOrYear) {
setHasInteractedWithMonthOrYear(true);
}
handleClickNextMonth(e);
};
const handleNextYearInteraction = e => {
if (!hasInteractedWithMonthOrYear) {
setHasInteractedWithMonthOrYear(true);
}
handleClickNextYear(e);
};
return /*#__PURE__*/React.createElement(Box, {
paddingInline: "space.100"
}, /*#__PURE__*/React.createElement(Inline, {
space: "space.0",
alignBlock: "center",
spread: "space-between"
}, /*#__PURE__*/React.createElement(Inline, {
space: "space.100",
alignBlock: "start"
}, /*#__PURE__*/React.createElement(IconButton, {
appearance: "subtle",
spacing: "compact",
tabIndex: tabIndex,
onClick: handlePrevYearInteraction,
testId: testId && `${testId}--previous-year`,
icon: iconProps => /*#__PURE__*/React.createElement(ChevronDoubleLeftIcon, _extends({}, iconProps, {
size: "small"
})),
label: `${previousYearLabel}, ${previousYearHeading}`
}), /*#__PURE__*/React.createElement(IconButton, {
appearance: "subtle",
spacing: "compact",
tabIndex: tabIndex,
onClick: handlePrevMonthInteraction,
testId: testId && `${testId}--previous-month`,
icon: iconProps => /*#__PURE__*/React.createElement(ChevronLeftIcon, _extends({}, iconProps, {
size: "small"
})),
label: `${previousMonthLabel}, ${previousMonthHeading}`
})), /*#__PURE__*/React.createElement(Box, {
"aria-live": hasInteractedWithMonthOrYear ? 'polite' : undefined,
id: announceId,
testId: testId && `${testId}--current-month-year--container`
}, /*#__PURE__*/React.createElement(Heading, {
size: "xsmall",
as: "h2",
id: headerId,
testId: testId && `${testId}--current-month-year`
}, `${monthLongTitle} ${year}`)), /*#__PURE__*/React.createElement(Inline, {
space: "space.100",
alignBlock: "end"
}, /*#__PURE__*/React.createElement(IconButton, {
appearance: "subtle",
spacing: "compact",
tabIndex: tabIndex,
onClick: handleNextMonthInteraction,
testId: testId && `${testId}--next-month`,
icon: iconProps => /*#__PURE__*/React.createElement(ChevronRightIcon, _extends({}, iconProps, {
size: "small"
})),
label: `${nextMonthLabel}, ${nextMonthHeading}`
}), /*#__PURE__*/React.createElement(IconButton, {
appearance: "subtle",
spacing: "compact",
tabIndex: tabIndex,
onClick: handleNextYearInteraction,
testId: testId && `${testId}--next-year`,
icon: iconProps => /*#__PURE__*/React.createElement(ChevronDoubleRightIcon, _extends({}, iconProps, {
size: "small"
})),
label: `${nextYearLabel}, ${nextYearHeading}`
}))));
});
Header.displayName = 'Header';
// eslint-disable-next-line @repo/internal/react/require-jsdoc
export default Header;