@grafana/ui
Version:
Grafana Components Library
1 lines • 12.2 kB
Source Map (JSON)
{"version":3,"file":"CalendarBody.mjs","sources":["../../../../../src/components/DateTimePickers/TimeRangePicker/CalendarBody.tsx"],"sourcesContent":["import { css } from '@emotion/css';\nimport { useCallback } from 'react';\nimport Calendar, { CalendarType } from 'react-calendar';\n\nimport { GrafanaTheme2, dateTimeParse, DateTime, TimeZone } from '@grafana/data';\nimport { t } from '@grafana/i18n';\n\nimport { useStyles2 } from '../../../themes/ThemeContext';\nimport { Icon } from '../../Icon/Icon';\nimport { getWeekStart, WeekStart } from '../WeekStartPicker';\nimport { adjustDateForReactCalendar } from '../utils/adjustDateForReactCalendar';\n\nimport { TimePickerCalendarProps } from './TimePickerCalendar';\n\nconst weekStartMap: Record<WeekStart, CalendarType> = {\n saturday: 'islamic',\n sunday: 'gregory',\n monday: 'iso8601',\n};\n\nexport function Body({ onChange, from, to, timeZone, weekStart }: TimePickerCalendarProps) {\n const value = inputToValue(from, to, new Date(), timeZone);\n const onCalendarChange = useOnCalendarChange(onChange, timeZone);\n const styles = useStyles2(getBodyStyles);\n const weekStartValue = getWeekStart(weekStart);\n\n return (\n <Calendar\n selectRange={true}\n next2Label={null}\n prev2Label={null}\n className={styles.body}\n tileClassName={styles.title}\n value={value}\n nextLabel={<Icon name=\"angle-right\" />}\n nextAriaLabel={t('time-picker.calendar.next-month', 'Next month')}\n prevLabel={<Icon name=\"angle-left\" />}\n prevAriaLabel={t('time-picker.calendar.previous-month', 'Previous month')}\n onChange={onCalendarChange}\n locale=\"en\"\n calendarType={weekStartMap[weekStartValue]}\n />\n );\n}\n\nBody.displayName = 'Body';\n\nexport function inputToValue(\n from: DateTime,\n to: DateTime,\n invalidDateDefault: Date = new Date(),\n timezone?: string\n): [Date, Date] {\n let fromAsDate = from.isValid() ? from.toDate() : invalidDateDefault;\n let toAsDate = to.isValid() ? to.toDate() : invalidDateDefault;\n\n if (timezone) {\n fromAsDate = adjustDateForReactCalendar(fromAsDate, timezone);\n toAsDate = adjustDateForReactCalendar(toAsDate, timezone);\n }\n\n if (fromAsDate > toAsDate) {\n return [toAsDate, fromAsDate];\n }\n\n return [fromAsDate, toAsDate];\n}\n\nfunction useOnCalendarChange(onChange: (from: DateTime, to: DateTime) => void, timeZone?: TimeZone) {\n return useCallback<NonNullable<React.ComponentProps<typeof Calendar>['onChange']>>(\n (value) => {\n if (!Array.isArray(value)) {\n return console.error('onCalendarChange: should be run in selectRange={true}');\n }\n\n if (value[0] && value[1]) {\n const from = dateTimeParse(dateInfo(value[0]), { timeZone });\n const to = dateTimeParse(dateInfo(value[1]), { timeZone });\n\n onChange(from, to);\n }\n },\n [onChange, timeZone]\n );\n}\n\nfunction dateInfo(date: Date): number[] {\n return [date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds()];\n}\n\nexport const getBodyStyles = (theme: GrafanaTheme2) => {\n // If a time range is part of only 1 day but does not encompass the whole day,\n // the class that react-calendar uses is '--hasActive' by itself (without being part of a '--range')\n const hasActiveSelector = `.react-calendar__tile--hasActive:not(.react-calendar__tile--range)`;\n\n return {\n title: css({\n color: theme.colors.text.primary,\n backgroundColor: theme.colors.background.primary,\n fontSize: theme.typography.size.md,\n border: '1px solid transparent',\n\n '&:hover, &:focus': {\n position: 'relative',\n },\n\n '&:disabled': {\n color: theme.colors.action.disabledText,\n cursor: 'not-allowed',\n },\n }),\n body: css({\n zIndex: theme.zIndex.modal,\n backgroundColor: theme.colors.background.elevated,\n width: '268px',\n\n '.react-calendar__navigation': {\n display: 'flex',\n },\n\n '.react-calendar__navigation__label, .react-calendar__navigation__arrow, .react-calendar__navigation': {\n paddingTop: '4px',\n backgroundColor: 'inherit',\n color: theme.colors.text.primary,\n border: 0,\n fontWeight: theme.typography.fontWeightMedium,\n },\n\n '.react-calendar__month-view__weekdays': {\n backgroundColor: 'inherit',\n textAlign: 'center',\n color: theme.colors.primary.text,\n\n abbr: {\n border: 0,\n textDecoration: 'none',\n cursor: 'default',\n display: 'block',\n padding: '4px 0 4px 0',\n },\n },\n\n '.react-calendar__month-view__days': {\n backgroundColor: 'inherit',\n },\n\n '.react-calendar__tile, .react-calendar__tile--now': {\n marginBottom: '4px',\n backgroundColor: 'inherit',\n height: '26px',\n },\n\n '.react-calendar__navigation__label, .react-calendar__navigation > button:focus, .time-picker-calendar-tile:focus':\n {\n outline: 0,\n },\n\n // The --hover modifier is active when the user is selecting a range and hovering over a tile - it shows the pending range.\n // It is applied to all dates between the clicked date and the hovered date.\n // The *clicked* date should have primary bg, while *pending* range dates should have hover bg.\n '.react-calendar__tile--hover': {\n backgroundColor: theme.colors.action.hover,\n // eslint-disable-next-line @grafana/no-border-radius-literal\n borderRadius: 0,\n },\n\n '.react-calendar__tile--hoverStart': {\n borderTopLeftRadius: theme.shape.radius.pill,\n borderBottomLeftRadius: theme.shape.radius.pill,\n },\n\n '.react-calendar__tile--hoverEnd': {\n borderTopRightRadius: theme.shape.radius.pill,\n borderBottomRightRadius: theme.shape.radius.pill,\n },\n\n // Addiitonally, when hovering a date before clicking any, it should show the hover bg.\n '.react-calendar__tile:hover:not(.react-calendar__tile--hover):not(.react-calendar__tile--active):not(.react-calendar__tile--hasActive)':\n {\n backgroundColor: theme.colors.action.hover,\n borderRadius: theme.shape.radius.pill,\n },\n\n // When the user is selecting a range (they've clicked one date, tiles have --hover), both --rangeStart and --rangeEnd are on the tile.\n // The --hover classes above handle the rounding of the tiles so they're contigious with the range\n [`${hasActiveSelector}, .react-calendar__tile--rangeStart:not(.react-calendar__tile--hover)`]: {\n borderTopLeftRadius: theme.shape.radius.pill,\n borderBottomLeftRadius: theme.shape.radius.pill,\n },\n\n [`${hasActiveSelector}, .react-calendar__tile--rangeEnd:not(.react-calendar__tile--hover)`]: {\n borderTopRightRadius: theme.shape.radius.pill,\n borderBottomRightRadius: theme.shape.radius.pill,\n },\n\n [`${hasActiveSelector}, .react-calendar__tile--active, .react-calendar__tile--rangeEnd, .react-calendar__tile--rangeStart`]:\n {\n color: theme.colors.primary.contrastText,\n fontWeight: theme.typography.fontWeightMedium,\n background: theme.colors.primary.main,\n border: '0px',\n },\n }),\n };\n};\n"],"names":[],"mappings":"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"}