UNPKG

@awsui/components-react

Version:

On July 19th, 2022, we launched [Cloudscape Design System](https://cloudscape.design). Cloudscape is an evolution of AWS-UI. It consists of user interface guidelines, front-end components, design resources, and development tools for building intuitive, en

109 lines • 8.95 kB
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 import React, { useEffect, useRef, useState } from 'react'; import clsx from 'clsx'; import InternalAlert from '../alert/internal'; import InternalBox from '../box/internal'; import { InternalButton } from '../button/internal'; import { useInternalI18n } from '../i18n/context'; import FocusLock from '../internal/components/focus-lock'; import InternalLiveRegion from '../live-region/internal'; import InternalSpaceBetween from '../space-between/internal'; import Calendar from './calendar'; import ModeSwitcher from './mode-switcher'; import RelativeRangePicker from './relative-range'; import { normalizeTimeOffset } from './time-offset'; import { formatValue, getDefaultMode, joinAbsoluteValue, splitAbsoluteValue } from './utils'; import styles from './styles.css.js'; import testutilStyles from './test-classes/styles.css.js'; const VALID_RANGE = { valid: true }; export function DateRangePickerDropdown({ locale = '', startOfWeek, isDateEnabled, dateDisabledReason = () => '', isValidRange, value, onClear: clearValue, onApply: applyValue, getTimeOffset, timeOffset, onDropdownClose, relativeOptions, showClearButton, isSingleGrid, i18nStrings, dateOnly, timeInputFormat, rangeSelectorMode, ariaLabelledby, ariaDescribedby, customAbsoluteRangeControl, customRelativeRangeUnits, granularity = 'day', }) { const i18n = useInternalI18n('date-range-picker'); const isMonthPicker = granularity === 'month'; const hideTime = dateOnly || isMonthPicker; const liveRegionRef = useRef(null); const [rangeSelectionMode, setRangeSelectionMode] = useState(getDefaultMode(value, relativeOptions, rangeSelectorMode)); const [selectedAbsoluteRange, setSelectedAbsoluteRange] = useState(() => splitAbsoluteValue((value === null || value === void 0 ? void 0 : value.type) === 'absolute' ? value : null, hideTime)); const [selectedRelativeRange, setSelectedRelativeRange] = useState((value === null || value === void 0 ? void 0 : value.type) === 'relative' ? value : null); const scrollableContainerRef = useRef(null); const applyButtonRef = useRef(null); const [applyClicked, setApplyClicked] = useState(false); const [validationResult, setValidationResult] = useState(VALID_RANGE); const closeDropdown = () => { setApplyClicked(false); onDropdownClose(); }; const onClear = () => { closeDropdown(); clearValue(); }; const onApply = () => { var _a; const newValue = rangeSelectionMode === 'relative' ? selectedRelativeRange : joinAbsoluteValue(selectedAbsoluteRange, hideTime); const newValidationResult = applyValue(newValue); if (newValidationResult.valid === false) { setApplyClicked(true); setValidationResult(newValidationResult); (_a = liveRegionRef.current) === null || _a === void 0 ? void 0 : _a.reannounce(); } else { setApplyClicked(false); closeDropdown(); } }; useEffect(() => { if (applyClicked) { const visibleRange = rangeSelectionMode === 'relative' ? selectedRelativeRange : joinAbsoluteValue(selectedAbsoluteRange); const formattedRange = formatValue(visibleRange, { dateOnly, monthOnly: isMonthPicker, timeOffset: dateOnly || isMonthPicker ? null : normalizeTimeOffset(visibleRange, getTimeOffset, timeOffset), }); const newValidationResult = isValidRange(formattedRange); setValidationResult(newValidationResult || VALID_RANGE); } }, [ applyClicked, isValidRange, rangeSelectionMode, selectedRelativeRange, selectedAbsoluteRange, setValidationResult, dateOnly, isMonthPicker, getTimeOffset, timeOffset, ]); useEffect(() => { var _a; return (_a = scrollableContainerRef.current) === null || _a === void 0 ? void 0 : _a.focus(); }, [scrollableContainerRef]); return (React.createElement(React.Fragment, null, React.createElement(FocusLock, { className: styles['focus-lock'], autoFocus: true }, React.createElement("div", { ref: scrollableContainerRef, className: clsx(styles.dropdown, testutilStyles.dropdown), tabIndex: 0, role: "dialog", "aria-label": i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.ariaLabel, "aria-labelledby": ariaLabelledby !== null && ariaLabelledby !== void 0 ? ariaLabelledby : i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.ariaLabelledby, "aria-describedby": ariaDescribedby !== null && ariaDescribedby !== void 0 ? ariaDescribedby : i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.ariaDescribedby }, React.createElement("div", { className: clsx(styles['dropdown-content'], { [styles['one-grid']]: isSingleGrid, }) }, React.createElement(InternalSpaceBetween, { size: "l" }, React.createElement(InternalBox, { padding: { top: 'm', horizontal: 'l' } }, React.createElement(InternalSpaceBetween, { direction: "vertical", size: "s" }, rangeSelectorMode === 'default' && (React.createElement(ModeSwitcher, { mode: rangeSelectionMode, onChange: (mode) => { setRangeSelectionMode(mode); setApplyClicked(false); setValidationResult(VALID_RANGE); }, i18nStrings: i18nStrings })), rangeSelectionMode === 'absolute' && (React.createElement(Calendar, { value: selectedAbsoluteRange, setValue: setSelectedAbsoluteRange, locale: locale, startOfWeek: startOfWeek, isDateEnabled: isDateEnabled, dateDisabledReason: dateDisabledReason, i18nStrings: i18nStrings, dateOnly: dateOnly, timeInputFormat: timeInputFormat, customAbsoluteRangeControl: customAbsoluteRangeControl, granularity: granularity })), rangeSelectionMode === 'relative' && (React.createElement(RelativeRangePicker, { isSingleGrid: isSingleGrid, options: relativeOptions, dateOnly: dateOnly, initialSelection: selectedRelativeRange, onChange: range => setSelectedRelativeRange(range), i18nStrings: i18nStrings, customUnits: customRelativeRangeUnits, granularity: granularity }))), React.createElement(InternalBox, { className: testutilStyles['validation-section'], margin: !validationResult.valid ? { top: 's' } : undefined }, !validationResult.valid && (React.createElement(React.Fragment, null, React.createElement(InternalAlert, { type: "error", statusIconAriaLabel: i18n('i18nStrings.errorIconAriaLabel', i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.errorIconAriaLabel) }, React.createElement("span", { className: testutilStyles['validation-error'] }, validationResult.errorMessage)), React.createElement(InternalLiveRegion, { hidden: true, tagName: "span", ref: liveRegionRef }, validationResult.errorMessage))))), React.createElement("div", { className: clsx(styles.footer, { [styles['one-grid']]: isSingleGrid, [styles['has-clear-button']]: showClearButton, }) }, showClearButton && (React.createElement("div", { className: styles['footer-button-wrapper'] }, React.createElement(InternalButton, { onClick: onClear, className: testutilStyles['clear-button'], variant: "link", formAction: "none" }, i18n('i18nStrings.clearButtonLabel', i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.clearButtonLabel)))), React.createElement("div", { className: styles['footer-button-wrapper'] }, React.createElement(InternalSpaceBetween, { size: "xs", direction: "horizontal" }, React.createElement(InternalButton, { onClick: closeDropdown, className: testutilStyles['cancel-button'], variant: "link", formAction: "none" }, i18n('i18nStrings.cancelButtonLabel', i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.cancelButtonLabel)), React.createElement(InternalButton, { onClick: onApply, className: testutilStyles['apply-button'], ref: applyButtonRef, formAction: "none" }, i18n('i18nStrings.applyButtonLabel', i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.applyButtonLabel))))))))))); } //# sourceMappingURL=dropdown.js.map