From 11335d6f6a6dacacb37acb1865edf19753c68e20 Mon Sep 17 00:00:00 2001 From: Alex Khomenko Date: Wed, 16 Jun 2021 15:57:12 +0300 Subject: [PATCH] grafana/ui: Add DatePicker (#35742) * Move DatePicker to grafana/ui * Export the pickers * Reuse TimePicker styles * Fix date formatting * Remove mockdate * Add release tags * Switch to input type='text' * Move DatePicker to pickers * Add mdx files * Update types * Update tests --- .../DateTimePickers/DatePicker/DatePicker.mdx | 25 +++++++ .../DatePicker/DatePicker.story.tsx | 28 +++++++ .../DatePicker/DatePicker.test.tsx | 54 +++++++++++++ .../DateTimePickers/DatePicker/DatePicker.tsx | 71 ++++++++++++++++++ .../DatePickerWithInput.mdx | 18 +++++ .../DatePickerWithInput.story.tsx | 21 ++++++ .../DatePickerWithInput.test.tsx | 66 ++++++++++++++++ .../DatePickerWithInput.tsx | 75 +++++++++++++++++++ .../RelativeTimeRangePicker.story.tsx | 0 .../RelativeTimeRangePicker.test.tsx | 0 .../RelativeTimeRangePicker.tsx | 0 .../RelativeTimeRangePicker/utils.test.ts | 0 .../RelativeTimeRangePicker/utils.ts | 0 .../TimeOfDayPicker.story.tsx | 0 .../TimeOfDayPicker.tsx | 0 .../TimeRangeInput.mdx | 0 .../TimeRangeInput.story.tsx | 0 .../TimeRangeInput.tsx | 0 .../TimeRangePicker.story.tsx | 0 .../TimeRangePicker.test.tsx | 0 .../TimeRangePicker.tsx | 2 + .../TimePickerCalendar.test.tsx | 0 .../TimeRangePicker/TimePickerCalendar.tsx | 6 +- .../TimePickerContent.test.tsx | 0 .../TimeRangePicker/TimePickerContent.tsx | 0 .../TimeRangePicker/TimePickerFooter.tsx | 0 .../TimeRangePicker/TimePickerTitle.tsx | 0 .../TimeRangePicker/TimeRangeForm.tsx | 0 .../TimeRangePicker/TimeRangeList.tsx | 0 .../TimeRangePicker/TimeRangeOption.tsx | 0 .../TimeRangePicker/mapper.ts | 0 .../TimeZonePicker.story.tsx | 0 .../TimeZonePicker.tsx | 0 .../TimeZonePicker/TimeZoneDescription.tsx | 0 .../TimeZonePicker/TimeZoneGroup.tsx | 0 .../TimeZonePicker/TimeZoneOffset.tsx | 0 .../TimeZonePicker/TimeZoneOption.tsx | 0 .../TimeZonePicker/TimeZoneTitle.tsx | 0 .../_TimeOfDayPicker.scss | 0 .../rangeOptions.ts | 0 packages/grafana-ui/src/components/index.scss | 2 +- packages/grafana-ui/src/components/index.ts | 15 ++-- .../TimePicker/TimePickerWithHistory.tsx | 2 +- 43 files changed, 375 insertions(+), 10 deletions(-) create mode 100644 packages/grafana-ui/src/components/DateTimePickers/DatePicker/DatePicker.mdx create mode 100644 packages/grafana-ui/src/components/DateTimePickers/DatePicker/DatePicker.story.tsx create mode 100644 packages/grafana-ui/src/components/DateTimePickers/DatePicker/DatePicker.test.tsx create mode 100644 packages/grafana-ui/src/components/DateTimePickers/DatePicker/DatePicker.tsx create mode 100644 packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.mdx create mode 100644 packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.story.tsx create mode 100644 packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.test.tsx create mode 100644 packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.tsx rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/RelativeTimeRangePicker/RelativeTimeRangePicker.story.tsx (100%) rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/RelativeTimeRangePicker/RelativeTimeRangePicker.test.tsx (100%) rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/RelativeTimeRangePicker/RelativeTimeRangePicker.tsx (100%) rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/RelativeTimeRangePicker/utils.test.ts (100%) rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/RelativeTimeRangePicker/utils.ts (100%) rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/TimeOfDayPicker.story.tsx (100%) rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/TimeOfDayPicker.tsx (100%) rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/TimeRangeInput.mdx (100%) rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/TimeRangeInput.story.tsx (100%) rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/TimeRangeInput.tsx (100%) rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/TimeRangePicker.story.tsx (100%) rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/TimeRangePicker.test.tsx (100%) rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/TimeRangePicker.tsx (99%) rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/TimeRangePicker/TimePickerCalendar.test.tsx (100%) rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/TimeRangePicker/TimePickerCalendar.tsx (97%) rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/TimeRangePicker/TimePickerContent.test.tsx (100%) rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/TimeRangePicker/TimePickerContent.tsx (100%) rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/TimeRangePicker/TimePickerFooter.tsx (100%) rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/TimeRangePicker/TimePickerTitle.tsx (100%) rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/TimeRangePicker/TimeRangeForm.tsx (100%) rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/TimeRangePicker/TimeRangeList.tsx (100%) rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/TimeRangePicker/TimeRangeOption.tsx (100%) rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/TimeRangePicker/mapper.ts (100%) rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/TimeZonePicker.story.tsx (100%) rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/TimeZonePicker.tsx (100%) rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/TimeZonePicker/TimeZoneDescription.tsx (100%) rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/TimeZonePicker/TimeZoneGroup.tsx (100%) rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/TimeZonePicker/TimeZoneOffset.tsx (100%) rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/TimeZonePicker/TimeZoneOption.tsx (100%) rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/TimeZonePicker/TimeZoneTitle.tsx (100%) rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/_TimeOfDayPicker.scss (100%) rename packages/grafana-ui/src/components/{TimePicker => DateTimePickers}/rangeOptions.ts (100%) diff --git a/packages/grafana-ui/src/components/DateTimePickers/DatePicker/DatePicker.mdx b/packages/grafana-ui/src/components/DateTimePickers/DatePicker/DatePicker.mdx new file mode 100644 index 00000000000..54c83d355f0 --- /dev/null +++ b/packages/grafana-ui/src/components/DateTimePickers/DatePicker/DatePicker.mdx @@ -0,0 +1,25 @@ +import { ArgsTable} from '@storybook/addon-docs/blocks'; +import { DatePicker } from './DatePicker'; + +# DatePicker + +A component with a calendar view for selecting a date. + +### Usage +```tsx +import React, { useState } from 'react'; +import { DatePicker, Button } from '@grafana/ui'; + +const [date, setDate] = useState(new Date()); +const [open, setOpen] = useState(false); + +return ( + <> + + setDate(newDate)} onClose={() => setOpen(false)} /> + +) +``` + +### Props + diff --git a/packages/grafana-ui/src/components/DateTimePickers/DatePicker/DatePicker.story.tsx b/packages/grafana-ui/src/components/DateTimePickers/DatePicker/DatePicker.story.tsx new file mode 100644 index 00000000000..878e02f0905 --- /dev/null +++ b/packages/grafana-ui/src/components/DateTimePickers/DatePicker/DatePicker.story.tsx @@ -0,0 +1,28 @@ +import React, { useState } from 'react'; +import { DatePicker } from './DatePicker'; +import { Button } from '../../Button/Button'; +import mdx from './DatePicker.mdx'; +import { withCenteredStory } from '../../../utils/storybook/withCenteredStory'; + +export default { + title: 'Pickers And Editors/DatePicker', + component: DatePicker, + decorators: [withCenteredStory], + parameters: { + docs: { + page: mdx, + }, + }, +}; + +export const Basic = () => { + const [date, setDate] = useState(new Date()); + const [open, setOpen] = useState(false); + + return ( + <> + + setDate(newDate)} onClose={() => setOpen(false)} /> + + ); +}; diff --git a/packages/grafana-ui/src/components/DateTimePickers/DatePicker/DatePicker.test.tsx b/packages/grafana-ui/src/components/DateTimePickers/DatePicker/DatePicker.test.tsx new file mode 100644 index 00000000000..61b56adfcd9 --- /dev/null +++ b/packages/grafana-ui/src/components/DateTimePickers/DatePicker/DatePicker.test.tsx @@ -0,0 +1,54 @@ +import React from 'react'; +import { fireEvent, render, screen } from '@testing-library/react'; +import { DatePicker } from './DatePicker'; + +describe('DatePicker', () => { + it('does not render calendar when isOpen is false', () => { + render(); + + expect(screen.queryByTestId('date-picker')).not.toBeInTheDocument(); + }); + + it('renders calendar when isOpen is true', () => { + render(); + + expect(screen.getByTestId('date-picker')).toBeInTheDocument(); + }); + + it('renders calendar with default date', () => { + render(); + + expect(screen.getByText('May 2014')).toBeInTheDocument(); + }); + + it('renders calendar with date passed in', () => { + render(); + + expect(screen.getByText('December 2020')).toBeInTheDocument(); + }); + + it('calls onChange when date is selected', () => { + const onChange = jest.fn(); + + render(); + + expect(onChange).not.toHaveBeenCalled(); + + // clicking the date + fireEvent.click(screen.getByText('14')); + + expect(onChange).toHaveBeenCalledTimes(1); + }); + + it('calls onClose when outside of wrapper is clicked', () => { + const onClose = jest.fn(); + + render(); + + expect(onClose).not.toHaveBeenCalled(); + + fireEvent.click(document); + + expect(onClose).toHaveBeenCalledTimes(1); + }); +}); diff --git a/packages/grafana-ui/src/components/DateTimePickers/DatePicker/DatePicker.tsx b/packages/grafana-ui/src/components/DateTimePickers/DatePicker/DatePicker.tsx new file mode 100644 index 00000000000..c33427f5b76 --- /dev/null +++ b/packages/grafana-ui/src/components/DateTimePickers/DatePicker/DatePicker.tsx @@ -0,0 +1,71 @@ +import React, { memo } from 'react'; +import Calendar from 'react-calendar/dist/entry.nostyle'; +import { css } from 'emotion'; +import { GrafanaTheme2 } from '@grafana/data'; +import { useStyles2 } from '../../../themes'; +import { ClickOutsideWrapper } from '../../ClickOutsideWrapper/ClickOutsideWrapper'; +import { Icon } from '../../Icon/Icon'; +import { getBodyStyles } from '../TimeRangePicker/TimePickerCalendar'; + +/** @public */ +export interface DatePickerProps { + isOpen?: boolean; + onClose: () => void; + onChange: (value: Date) => void; + value?: Date; +} + +/** @public */ +export const DatePicker = memo((props) => { + const styles = useStyles2(getStyles); + const { isOpen, onClose } = props; + + if (!isOpen) { + return null; + } + + return ( + +
+ +
+
+ ); +}); + +DatePicker.displayName = 'DatePicker'; + +const Body = memo(({ value, onChange }) => { + const styles = useStyles2(getBodyStyles); + + return ( + } + prevLabel={} + onChange={(ev) => { + if (!Array.isArray(ev)) { + onChange(ev); + } + }} + locale="en" + /> + ); +}); + +Body.displayName = 'Body'; + +export const getStyles = (theme: GrafanaTheme2) => { + return { + modal: css` + z-index: ${theme.zIndex.modal}; + position: absolute; + box-shadow: ${theme.shadows.z3}; + background-color: ${theme.colors.background.primary}; + border: 1px solid ${theme.colors.border.weak}; + border-radius: 2px 0 0 2px; + `, + }; +}; diff --git a/packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.mdx b/packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.mdx new file mode 100644 index 00000000000..fcdfbdaebad --- /dev/null +++ b/packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.mdx @@ -0,0 +1,18 @@ +import { ArgsTable} from '@storybook/addon-docs/blocks'; +import { DatePickerWithInput } from './DatePickerWithInput'; + +# DatePickerWithInput + +An input with a calendar view, used to select a date. + +### Usage +```tsx +import React, { useState } from 'react'; +import { DatePickerWithInput } from '@grafana/ui'; + +const [date, setDate] = useState(new Date()); +return setDate(newDate)} />; +``` + +### Props + diff --git a/packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.story.tsx b/packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.story.tsx new file mode 100644 index 00000000000..b7469850491 --- /dev/null +++ b/packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.story.tsx @@ -0,0 +1,21 @@ +import React, { useState } from 'react'; +import { DatePickerWithInput } from './DatePickerWithInput'; +import { withCenteredStory } from '../../../utils/storybook/withCenteredStory'; +import mdx from './DatePickerWithInput.mdx'; + +export default { + title: 'Pickers And Editors/DatePickerWithInput', + component: DatePickerWithInput, + decorators: [withCenteredStory], + parameters: { + docs: { + page: mdx, + }, + }, +}; + +export const Basic = () => { + const [date, setDate] = useState(new Date()); + + return setDate(newDate)} />; +}; diff --git a/packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.test.tsx b/packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.test.tsx new file mode 100644 index 00000000000..e80823e91f9 --- /dev/null +++ b/packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.test.tsx @@ -0,0 +1,66 @@ +import React from 'react'; +import { fireEvent, render, screen } from '@testing-library/react'; +import { DatePickerWithInput } from './DatePickerWithInput'; +import { dateTimeFormat } from '@grafana/data'; + +describe('DatePickerWithInput', () => { + it('renders date input', () => { + render(); + + expect(screen.getByDisplayValue(dateTimeFormat(1400000000000, { format: 'L' }))).toBeInTheDocument(); + }); + + it('renders date input with date passed in', () => { + render(); + + expect(screen.getByDisplayValue(dateTimeFormat(1607431703363, { format: 'L' }))).toBeInTheDocument(); + }); + + it('does not render calendar', () => { + render(); + + expect(screen.queryByTestId('date-picker')).not.toBeInTheDocument(); + }); + + describe('input is clicked', () => { + it('renders input', () => { + render(); + + fireEvent.click(screen.getByPlaceholderText('Date')); + + expect(screen.getByPlaceholderText('Date')).toBeInTheDocument(); + }); + + it('renders calendar', () => { + render(); + + fireEvent.click(screen.getByPlaceholderText('Date')); + + expect(screen.queryByTestId('date-picker')).toBeInTheDocument(); + }); + }); + + it('calls onChange after date is selected', () => { + const onChange = jest.fn(); + render(); + + // open calendar and select a date + fireEvent.click(screen.getByPlaceholderText('Date')); + fireEvent.click(screen.getByText('14')); + + expect(onChange).toHaveBeenCalledTimes(1); + }); + + it('closes calendar after outside wrapper is clicked', () => { + render(); + + // open calendar and click outside + fireEvent.click(screen.getByPlaceholderText('Date')); + + expect(screen.getByTestId('date-picker')).toBeInTheDocument(); + + fireEvent.click(document); + + expect(screen.queryByTestId('date-picker')).not.toBeInTheDocument(); + }); +}); diff --git a/packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.tsx b/packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.tsx new file mode 100644 index 00000000000..ac6b198158b --- /dev/null +++ b/packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.tsx @@ -0,0 +1,75 @@ +import React, { ChangeEvent } from 'react'; +import { css } from '@emotion/css'; +import { dateTimeFormat } from '@grafana/data'; +import { DatePicker } from '../DatePicker/DatePicker'; +import { Props as InputProps, Input } from '../../Input/Input'; +import { useStyles } from '../../../themes'; + +export const formatDate = (date: Date | string) => dateTimeFormat(date, { format: 'L' }); + +/** @public */ +export interface DatePickerWithInputProps extends Omit { + value?: Date | string; + onChange: (value: Date | string) => void; + /** Hide the calendar when date is selected */ + closeOnSelect?: boolean; + placeholder?: string; +} + +/** @public */ +export const DatePickerWithInput = ({ + value, + onChange, + closeOnSelect, + placeholder = 'Date', + ...rest +}: DatePickerWithInputProps) => { + const [open, setOpen] = React.useState(false); + const styles = useStyles(getStyles); + + return ( +
+ setOpen(true)} + onChange={(ev: ChangeEvent) => { + // Allow resetting the date + if (ev.target.value === '') { + onChange(''); + } + }} + className={styles.input} + {...rest} + /> + { + onChange(ev); + if (closeOnSelect) { + setOpen(false); + } + }} + onClose={() => setOpen(false)} + /> +
+ ); +}; + +const getStyles = () => { + return { + container: css` + position: relative; + `, + input: css` + /* hides the native Calendar picker icon given when using type=date */ + input[type='date']::-webkit-inner-spin-button, + input[type='date']::-webkit-calendar-picker-indicator { + display: none; + -webkit-appearance: none; + `, + }; +}; diff --git a/packages/grafana-ui/src/components/TimePicker/RelativeTimeRangePicker/RelativeTimeRangePicker.story.tsx b/packages/grafana-ui/src/components/DateTimePickers/RelativeTimeRangePicker/RelativeTimeRangePicker.story.tsx similarity index 100% rename from packages/grafana-ui/src/components/TimePicker/RelativeTimeRangePicker/RelativeTimeRangePicker.story.tsx rename to packages/grafana-ui/src/components/DateTimePickers/RelativeTimeRangePicker/RelativeTimeRangePicker.story.tsx diff --git a/packages/grafana-ui/src/components/TimePicker/RelativeTimeRangePicker/RelativeTimeRangePicker.test.tsx b/packages/grafana-ui/src/components/DateTimePickers/RelativeTimeRangePicker/RelativeTimeRangePicker.test.tsx similarity index 100% rename from packages/grafana-ui/src/components/TimePicker/RelativeTimeRangePicker/RelativeTimeRangePicker.test.tsx rename to packages/grafana-ui/src/components/DateTimePickers/RelativeTimeRangePicker/RelativeTimeRangePicker.test.tsx diff --git a/packages/grafana-ui/src/components/TimePicker/RelativeTimeRangePicker/RelativeTimeRangePicker.tsx b/packages/grafana-ui/src/components/DateTimePickers/RelativeTimeRangePicker/RelativeTimeRangePicker.tsx similarity index 100% rename from packages/grafana-ui/src/components/TimePicker/RelativeTimeRangePicker/RelativeTimeRangePicker.tsx rename to packages/grafana-ui/src/components/DateTimePickers/RelativeTimeRangePicker/RelativeTimeRangePicker.tsx diff --git a/packages/grafana-ui/src/components/TimePicker/RelativeTimeRangePicker/utils.test.ts b/packages/grafana-ui/src/components/DateTimePickers/RelativeTimeRangePicker/utils.test.ts similarity index 100% rename from packages/grafana-ui/src/components/TimePicker/RelativeTimeRangePicker/utils.test.ts rename to packages/grafana-ui/src/components/DateTimePickers/RelativeTimeRangePicker/utils.test.ts diff --git a/packages/grafana-ui/src/components/TimePicker/RelativeTimeRangePicker/utils.ts b/packages/grafana-ui/src/components/DateTimePickers/RelativeTimeRangePicker/utils.ts similarity index 100% rename from packages/grafana-ui/src/components/TimePicker/RelativeTimeRangePicker/utils.ts rename to packages/grafana-ui/src/components/DateTimePickers/RelativeTimeRangePicker/utils.ts diff --git a/packages/grafana-ui/src/components/TimePicker/TimeOfDayPicker.story.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeOfDayPicker.story.tsx similarity index 100% rename from packages/grafana-ui/src/components/TimePicker/TimeOfDayPicker.story.tsx rename to packages/grafana-ui/src/components/DateTimePickers/TimeOfDayPicker.story.tsx diff --git a/packages/grafana-ui/src/components/TimePicker/TimeOfDayPicker.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeOfDayPicker.tsx similarity index 100% rename from packages/grafana-ui/src/components/TimePicker/TimeOfDayPicker.tsx rename to packages/grafana-ui/src/components/DateTimePickers/TimeOfDayPicker.tsx diff --git a/packages/grafana-ui/src/components/TimePicker/TimeRangeInput.mdx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangeInput.mdx similarity index 100% rename from packages/grafana-ui/src/components/TimePicker/TimeRangeInput.mdx rename to packages/grafana-ui/src/components/DateTimePickers/TimeRangeInput.mdx diff --git a/packages/grafana-ui/src/components/TimePicker/TimeRangeInput.story.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangeInput.story.tsx similarity index 100% rename from packages/grafana-ui/src/components/TimePicker/TimeRangeInput.story.tsx rename to packages/grafana-ui/src/components/DateTimePickers/TimeRangeInput.story.tsx diff --git a/packages/grafana-ui/src/components/TimePicker/TimeRangeInput.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangeInput.tsx similarity index 100% rename from packages/grafana-ui/src/components/TimePicker/TimeRangeInput.tsx rename to packages/grafana-ui/src/components/DateTimePickers/TimeRangeInput.tsx diff --git a/packages/grafana-ui/src/components/TimePicker/TimeRangePicker.story.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.story.tsx similarity index 100% rename from packages/grafana-ui/src/components/TimePicker/TimeRangePicker.story.tsx rename to packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.story.tsx diff --git a/packages/grafana-ui/src/components/TimePicker/TimeRangePicker.test.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.test.tsx similarity index 100% rename from packages/grafana-ui/src/components/TimePicker/TimeRangePicker.test.tsx rename to packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.test.tsx diff --git a/packages/grafana-ui/src/components/TimePicker/TimeRangePicker.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.tsx similarity index 99% rename from packages/grafana-ui/src/components/TimePicker/TimeRangePicker.tsx rename to packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.tsx index a5afb778b67..c91adc61913 100644 --- a/packages/grafana-ui/src/components/TimePicker/TimeRangePicker.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.tsx @@ -26,6 +26,7 @@ import { Themeable } from '../../types'; import { otherOptions, quickOptions } from './rangeOptions'; import { ButtonGroup, ToolbarButton } from '../Button'; +/** @public */ export interface TimeRangePickerProps extends Themeable { hideText?: boolean; value: TimeRange; @@ -179,6 +180,7 @@ const formattedRange = (value: TimeRange, timeZone?: TimeZone) => { return rangeUtil.describeTimeRange(adjustedTimeRange, timeZone); }; +/** @public */ export const TimeRangePicker = withTheme(UnthemedTimeRangePicker); const getStyles = stylesFactory((theme: GrafanaTheme) => { diff --git a/packages/grafana-ui/src/components/TimePicker/TimeRangePicker/TimePickerCalendar.test.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerCalendar.test.tsx similarity index 100% rename from packages/grafana-ui/src/components/TimePicker/TimeRangePicker/TimePickerCalendar.test.tsx rename to packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerCalendar.test.tsx diff --git a/packages/grafana-ui/src/components/TimePicker/TimeRangePicker/TimePickerCalendar.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerCalendar.tsx similarity index 97% rename from packages/grafana-ui/src/components/TimePicker/TimeRangePicker/TimePickerCalendar.tsx rename to packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerCalendar.tsx index f276c6e19ab..c4054ed5508 100644 --- a/packages/grafana-ui/src/components/TimePicker/TimeRangePicker/TimePickerCalendar.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerCalendar.tsx @@ -9,7 +9,7 @@ import { Icon } from '../../Icon/Icon'; import { Portal } from '../../Portal/Portal'; import { ClickOutsideWrapper } from '../../ClickOutsideWrapper/ClickOutsideWrapper'; -const getStyles = stylesFactory((theme: GrafanaTheme2, isReversed = false) => { +export const getStyles = stylesFactory((theme: GrafanaTheme2, isReversed = false) => { return { container: css` top: -1px; @@ -74,7 +74,7 @@ const getFooterStyles = stylesFactory((theme: GrafanaTheme2) => { }; }); -const getBodyStyles = stylesFactory((theme: GrafanaTheme2) => { +export const getBodyStyles = stylesFactory((theme: GrafanaTheme2) => { return { title: css` color: ${theme.colors.text}; @@ -245,7 +245,7 @@ const Header = memo(({ onClose }) => { Header.displayName = 'Header'; -const Body = memo(({ onChange, from, to, timeZone }) => { +export const Body = memo(({ onChange, from, to, timeZone }) => { const value = inputToValue(from, to); const theme = useTheme2(); const onCalendarChange = useOnCalendarChange(onChange, timeZone); diff --git a/packages/grafana-ui/src/components/TimePicker/TimeRangePicker/TimePickerContent.test.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.test.tsx similarity index 100% rename from packages/grafana-ui/src/components/TimePicker/TimeRangePicker/TimePickerContent.test.tsx rename to packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.test.tsx diff --git a/packages/grafana-ui/src/components/TimePicker/TimeRangePicker/TimePickerContent.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx similarity index 100% rename from packages/grafana-ui/src/components/TimePicker/TimeRangePicker/TimePickerContent.tsx rename to packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx diff --git a/packages/grafana-ui/src/components/TimePicker/TimeRangePicker/TimePickerFooter.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerFooter.tsx similarity index 100% rename from packages/grafana-ui/src/components/TimePicker/TimeRangePicker/TimePickerFooter.tsx rename to packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerFooter.tsx diff --git a/packages/grafana-ui/src/components/TimePicker/TimeRangePicker/TimePickerTitle.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerTitle.tsx similarity index 100% rename from packages/grafana-ui/src/components/TimePicker/TimeRangePicker/TimePickerTitle.tsx rename to packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerTitle.tsx diff --git a/packages/grafana-ui/src/components/TimePicker/TimeRangePicker/TimeRangeForm.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeForm.tsx similarity index 100% rename from packages/grafana-ui/src/components/TimePicker/TimeRangePicker/TimeRangeForm.tsx rename to packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeForm.tsx diff --git a/packages/grafana-ui/src/components/TimePicker/TimeRangePicker/TimeRangeList.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeList.tsx similarity index 100% rename from packages/grafana-ui/src/components/TimePicker/TimeRangePicker/TimeRangeList.tsx rename to packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeList.tsx diff --git a/packages/grafana-ui/src/components/TimePicker/TimeRangePicker/TimeRangeOption.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeOption.tsx similarity index 100% rename from packages/grafana-ui/src/components/TimePicker/TimeRangePicker/TimeRangeOption.tsx rename to packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeOption.tsx diff --git a/packages/grafana-ui/src/components/TimePicker/TimeRangePicker/mapper.ts b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/mapper.ts similarity index 100% rename from packages/grafana-ui/src/components/TimePicker/TimeRangePicker/mapper.ts rename to packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/mapper.ts diff --git a/packages/grafana-ui/src/components/TimePicker/TimeZonePicker.story.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker.story.tsx similarity index 100% rename from packages/grafana-ui/src/components/TimePicker/TimeZonePicker.story.tsx rename to packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker.story.tsx diff --git a/packages/grafana-ui/src/components/TimePicker/TimeZonePicker.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker.tsx similarity index 100% rename from packages/grafana-ui/src/components/TimePicker/TimeZonePicker.tsx rename to packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker.tsx diff --git a/packages/grafana-ui/src/components/TimePicker/TimeZonePicker/TimeZoneDescription.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneDescription.tsx similarity index 100% rename from packages/grafana-ui/src/components/TimePicker/TimeZonePicker/TimeZoneDescription.tsx rename to packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneDescription.tsx diff --git a/packages/grafana-ui/src/components/TimePicker/TimeZonePicker/TimeZoneGroup.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneGroup.tsx similarity index 100% rename from packages/grafana-ui/src/components/TimePicker/TimeZonePicker/TimeZoneGroup.tsx rename to packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneGroup.tsx diff --git a/packages/grafana-ui/src/components/TimePicker/TimeZonePicker/TimeZoneOffset.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneOffset.tsx similarity index 100% rename from packages/grafana-ui/src/components/TimePicker/TimeZonePicker/TimeZoneOffset.tsx rename to packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneOffset.tsx diff --git a/packages/grafana-ui/src/components/TimePicker/TimeZonePicker/TimeZoneOption.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneOption.tsx similarity index 100% rename from packages/grafana-ui/src/components/TimePicker/TimeZonePicker/TimeZoneOption.tsx rename to packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneOption.tsx diff --git a/packages/grafana-ui/src/components/TimePicker/TimeZonePicker/TimeZoneTitle.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneTitle.tsx similarity index 100% rename from packages/grafana-ui/src/components/TimePicker/TimeZonePicker/TimeZoneTitle.tsx rename to packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneTitle.tsx diff --git a/packages/grafana-ui/src/components/TimePicker/_TimeOfDayPicker.scss b/packages/grafana-ui/src/components/DateTimePickers/_TimeOfDayPicker.scss similarity index 100% rename from packages/grafana-ui/src/components/TimePicker/_TimeOfDayPicker.scss rename to packages/grafana-ui/src/components/DateTimePickers/_TimeOfDayPicker.scss diff --git a/packages/grafana-ui/src/components/TimePicker/rangeOptions.ts b/packages/grafana-ui/src/components/DateTimePickers/rangeOptions.ts similarity index 100% rename from packages/grafana-ui/src/components/TimePicker/rangeOptions.ts rename to packages/grafana-ui/src/components/DateTimePickers/rangeOptions.ts diff --git a/packages/grafana-ui/src/components/index.scss b/packages/grafana-ui/src/components/index.scss index 7be51f5b148..9bb5adf1a36 100644 --- a/packages/grafana-ui/src/components/index.scss +++ b/packages/grafana-ui/src/components/index.scss @@ -2,7 +2,7 @@ @import 'Drawer/Drawer'; @import 'RefreshPicker/RefreshPicker'; @import 'Forms/Legacy/Select/Select'; -@import 'TimePicker/TimeOfDayPicker'; +@import 'DateTimePickers/TimeOfDayPicker'; @import 'Tooltip/Tooltip'; @import 'Slider/Slider'; @import 'uPlot/Plot'; diff --git a/packages/grafana-ui/src/components/index.ts b/packages/grafana-ui/src/components/index.ts index f900ea39c38..696527725ff 100644 --- a/packages/grafana-ui/src/components/index.ts +++ b/packages/grafana-ui/src/components/index.ts @@ -21,9 +21,14 @@ export { EmptySearchResult } from './EmptySearchResult/EmptySearchResult'; export { UnitPicker } from './UnitPicker/UnitPicker'; export { StatsPicker } from './StatsPicker/StatsPicker'; export { RefreshPicker, defaultIntervals } from './RefreshPicker/RefreshPicker'; -export { TimeRangePicker } from './TimePicker/TimeRangePicker'; -export { TimeOfDayPicker } from './TimePicker/TimeOfDayPicker'; -export { TimeZonePicker } from './TimePicker/TimeZonePicker'; +export { TimeRangePicker, TimeRangePickerProps } from './DateTimePickers/TimeRangePicker'; +export { TimeOfDayPicker } from './DateTimePickers/TimeOfDayPicker'; +export { TimeZonePicker } from './DateTimePickers/TimeZonePicker'; +export { DatePicker, DatePickerProps } from './DateTimePickers/DatePicker/DatePicker'; +export { + DatePickerWithInput, + DatePickerWithInputProps, +} from './DateTimePickers/DatePickerWithInput/DatePickerWithInput'; export { List } from './List/List'; export { TagsInput } from './TagsInput/TagsInput'; export { Pagination } from './Pagination/Pagination'; @@ -195,8 +200,8 @@ export { Checkbox } from './Forms/Checkbox'; export { TextArea } from './TextArea/TextArea'; export { FileUpload } from './FileUpload/FileUpload'; -export { TimeRangeInput } from './TimePicker/TimeRangeInput'; -export { RelativeTimeRangePicker } from './TimePicker/RelativeTimeRangePicker/RelativeTimeRangePicker'; +export { TimeRangeInput } from './DateTimePickers/TimeRangeInput'; +export { RelativeTimeRangePicker } from './DateTimePickers/RelativeTimeRangePicker/RelativeTimeRangePicker'; export { Card, Props as CardProps, getCardStyles } from './Card/Card'; export { CardContainer, CardContainerProps } from './Card/CardContainer'; export { FormattedValueDisplay } from './FormattedValueDisplay/FormattedValueDisplay'; diff --git a/public/app/core/components/TimePicker/TimePickerWithHistory.tsx b/public/app/core/components/TimePicker/TimePickerWithHistory.tsx index bc32092fbf1..2306922ba70 100644 --- a/public/app/core/components/TimePicker/TimePickerWithHistory.tsx +++ b/public/app/core/components/TimePicker/TimePickerWithHistory.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { LocalStorageValueProvider } from '../LocalStorageValueProvider'; import { TimeRange, isDateTime, toUtc } from '@grafana/data'; -import { TimeRangePickerProps, TimeRangePicker } from '@grafana/ui/src/components/TimePicker/TimeRangePicker'; +import { TimeRangePickerProps, TimeRangePicker } from '@grafana/ui'; const LOCAL_STORAGE_KEY = 'grafana.dashboard.timepicker.history';