Skip to content

DatePicker

DatePicker

These are widgets for selecting dates and date ranges. The DatePicker component returns a JavaScript Date object via the onChange function, while the DateRangePicker returns a JavaScript Date array.

tsx
import React from 'react';
import { DatePicker, DateRangePicker } from 'intergalactic/date-picker';
import { Flex } from 'intergalactic/flex-box';
import { Text } from 'intergalactic/typography';

const Demo = () => {
  const [value, setValue] = React.useState(new Date('06/29/2020'));
  const [valueRange, setValueRange] = React.useState([]);

  return (
    <Flex gap={5} flexWrap>
      <Flex direction='column'>
        <Text tag='label' size={200} htmlFor='simple-date-picker'>
          Simple date picker
        </Text>
        <DatePicker value={value} onChange={(date) => setValue(date)}>
          <DatePicker.Trigger mt={2} id='simple-date-picker' />
          <DatePicker.Popper />
        </DatePicker>
      </Flex>
      <Flex direction='column'>
        <Text tag='label' size={200} htmlFor='simple-date-range-picker'>
          Date range picker
        </Text>
        <DateRangePicker value={valueRange} onChange={(date) => setValueRange(date)}>
          <DateRangePicker.Trigger mt={2} id='simple-date-range-picker' />
          <DateRangePicker.Popper />
        </DateRangePicker>
      </Flex>
    </Flex>
  );
};

export default Demo;
import React from 'react';
import { DatePicker, DateRangePicker } from 'intergalactic/date-picker';
import { Flex } from 'intergalactic/flex-box';
import { Text } from 'intergalactic/typography';

const Demo = () => {
  const [value, setValue] = React.useState(new Date('06/29/2020'));
  const [valueRange, setValueRange] = React.useState([]);

  return (
    <Flex gap={5} flexWrap>
      <Flex direction='column'>
        <Text tag='label' size={200} htmlFor='simple-date-picker'>
          Simple date picker
        </Text>
        <DatePicker value={value} onChange={(date) => setValue(date)}>
          <DatePicker.Trigger mt={2} id='simple-date-picker' />
          <DatePicker.Popper />
        </DatePicker>
      </Flex>
      <Flex direction='column'>
        <Text tag='label' size={200} htmlFor='simple-date-range-picker'>
          Date range picker
        </Text>
        <DateRangePicker value={valueRange} onChange={(date) => setValueRange(date)}>
          <DateRangePicker.Trigger mt={2} id='simple-date-range-picker' />
          <DateRangePicker.Popper />
        </DateRangePicker>
      </Flex>
    </Flex>
  );
};

export default Demo;

MonthRangePicker

These are widgets for selecting a single month and a range of months, respectively. The API is similar to that of the DatePicker and DateRangePicker components.

tsx
import React from 'react';
import { MonthPicker, MonthRangePicker } from 'intergalactic/date-picker';
import { Flex } from 'intergalactic/flex-box';
import { Text } from 'intergalactic/typography';

const Demo = () => {
  const [value, setValue] = React.useState(new Date());
  const [valueRange, setValueRange] = React.useState([]);

  return (
    <Flex gap={5} flexWrap>
      <Flex direction='column'>
        <Text tag='label' size={200} htmlFor='simple-month-picker'>
          Simple month picker
        </Text>
        <MonthPicker value={value} onChange={(date) => setValue(date)}>
          <MonthPicker.Trigger mt={2} id='simple-month-picker' />
          <MonthPicker.Popper />
        </MonthPicker>
      </Flex>
      <Flex direction='column'>
        <Text tag='label' size={200} htmlFor='simple-date-range-picker'>
          Month range picker
        </Text>
        <MonthRangePicker value={valueRange} onChange={(date) => setValueRange(date)}>
          <MonthRangePicker.Trigger mt={2} id='simple-date-range-picker' />
          <MonthRangePicker.Popper />
        </MonthRangePicker>
      </Flex>
    </Flex>
  );
};

export default Demo;
import React from 'react';
import { MonthPicker, MonthRangePicker } from 'intergalactic/date-picker';
import { Flex } from 'intergalactic/flex-box';
import { Text } from 'intergalactic/typography';

const Demo = () => {
  const [value, setValue] = React.useState(new Date());
  const [valueRange, setValueRange] = React.useState([]);

  return (
    <Flex gap={5} flexWrap>
      <Flex direction='column'>
        <Text tag='label' size={200} htmlFor='simple-month-picker'>
          Simple month picker
        </Text>
        <MonthPicker value={value} onChange={(date) => setValue(date)}>
          <MonthPicker.Trigger mt={2} id='simple-month-picker' />
          <MonthPicker.Popper />
        </MonthPicker>
      </Flex>
      <Flex direction='column'>
        <Text tag='label' size={200} htmlFor='simple-date-range-picker'>
          Month range picker
        </Text>
        <MonthRangePicker value={valueRange} onChange={(date) => setValueRange(date)}>
          <MonthRangePicker.Trigger mt={2} id='simple-date-range-picker' />
          <MonthRangePicker.Popper />
        </MonthRangePicker>
      </Flex>
    </Flex>
  );
};

export default Demo;

Trigger and Popper

To access the internal components, you must expand the component. The Trigger and Popper components are wrapped by Dropdown.Trigger and Dropdown.Popper, respectively. All the properties and examples available in Dropdown also work in DatePicker.

tsx
import React from 'react';
import { DatePicker } from 'intergalactic/date-picker';
import { Flex } from 'intergalactic/flex-box';
import { Text } from 'intergalactic/typography';

const Demo = () => {
  return (
    <Flex direction='column'>
      <Text tag='label' size={200} htmlFor='trigger-and-popper-example-picker'>
        Date picker
      </Text>
      <DatePicker>
        <DatePicker.Trigger mt={2}>
          <DatePicker.Trigger.SingleDateInput>
            <DatePicker.Trigger.SingleDateInput.Indicator />
            <DatePicker.Trigger.SingleDateInput.MaskedInput id='trigger-and-popper-example-picker' />
          </DatePicker.Trigger.SingleDateInput>
        </DatePicker.Trigger>
        <DatePicker.Popper />
      </DatePicker>
    </Flex>
  );
};

export default Demo;
import React from 'react';
import { DatePicker } from 'intergalactic/date-picker';
import { Flex } from 'intergalactic/flex-box';
import { Text } from 'intergalactic/typography';

const Demo = () => {
  return (
    <Flex direction='column'>
      <Text tag='label' size={200} htmlFor='trigger-and-popper-example-picker'>
        Date picker
      </Text>
      <DatePicker>
        <DatePicker.Trigger mt={2}>
          <DatePicker.Trigger.SingleDateInput>
            <DatePicker.Trigger.SingleDateInput.Indicator />
            <DatePicker.Trigger.SingleDateInput.MaskedInput id='trigger-and-popper-example-picker' />
          </DatePicker.Trigger.SingleDateInput>
        </DatePicker.Trigger>
        <DatePicker.Popper />
      </DatePicker>
    </Flex>
  );
};

export default Demo;

Custom header

You can change the header layout by expanding the component further.

tsx
import React from 'react';
import { DatePicker } from 'intergalactic/date-picker';
import { Flex } from 'intergalactic/flex-box';
import { Text } from 'intergalactic/typography';

const Demo = () => {
  return (
    <Flex direction='column'>
      <Text tag='label' size={200} htmlFor='custom-header-example-picker'>
        Date picker
      </Text>
      <DatePicker>
        <DatePicker.Trigger mt={2} id='custom-header-example-picker' />
        <DatePicker.Popper>
          <DatePicker.Header>
            <DatePicker.Prev />
            <DatePicker.Title>
              {({ displayedPeriod }) =>
                typeof displayedPeriod === 'string'
                  ? displayedPeriod
                  : new Intl.DateTimeFormat('en-US', {
                      month: 'short',
                      year: 'numeric',
                    }).format(displayedPeriod)
              }
            </DatePicker.Title>
            <DatePicker.Next />
          </DatePicker.Header>
          <DatePicker.Calendar />
        </DatePicker.Popper>
      </DatePicker>
    </Flex>
  );
};

export default Demo;
import React from 'react';
import { DatePicker } from 'intergalactic/date-picker';
import { Flex } from 'intergalactic/flex-box';
import { Text } from 'intergalactic/typography';

const Demo = () => {
  return (
    <Flex direction='column'>
      <Text tag='label' size={200} htmlFor='custom-header-example-picker'>
        Date picker
      </Text>
      <DatePicker>
        <DatePicker.Trigger mt={2} id='custom-header-example-picker' />
        <DatePicker.Popper>
          <DatePicker.Header>
            <DatePicker.Prev />
            <DatePicker.Title>
              {({ displayedPeriod }) =>
                typeof displayedPeriod === 'string'
                  ? displayedPeriod
                  : new Intl.DateTimeFormat('en-US', {
                      month: 'short',
                      year: 'numeric',
                    }).format(displayedPeriod)
              }
            </DatePicker.Title>
            <DatePicker.Next />
          </DatePicker.Header>
          <DatePicker.Calendar />
        </DatePicker.Popper>
      </DatePicker>
    </Flex>
  );
};

export default Demo;

Custom day

Calendar days can have metrics, and you can change the units by passing a function to the Calendar component.

tsx
import React from 'react';
import { DatePicker } from 'intergalactic/date-picker';
import ProgressBar from 'intergalactic/progress-bar';
import { Flex } from 'intergalactic/flex-box';
import { Text } from 'intergalactic/typography';

function randomInteger(min, max) {
  let rand = min - 0.5 + Math.random() * (max - min + 1);
  rand = Math.round(rand);
  return rand;
}

const Demo = () => {
  return (
    <Flex direction='column'>
      <Text tag='label' size={200} htmlFor='custom-day-example-picker'>
        Date picker
      </Text>
      <DatePicker>
        <DatePicker.Trigger mt={2} id='custom-day-example-picker' />
        <DatePicker.Popper>
          <DatePicker.Header />
          <DatePicker.Calendar>
            {({ days }) =>
              days.map((data, i) => (
                <DatePicker.Calendar.Unit {...data} key={i}>
                  <Flex direction='column' p={1} w={'100%'} alignItems='center'>
                    {data.children}
                    <ProgressBar
                      size='s'
                      duration={0}
                      value={randomInteger(0, 100)}
                      theme='dark'
                      mt={1}
                    />
                  </Flex>
                </DatePicker.Calendar.Unit>
              ))
            }
          </DatePicker.Calendar>
        </DatePicker.Popper>
      </DatePicker>
    </Flex>
  );
};

export default Demo;
import React from 'react';
import { DatePicker } from 'intergalactic/date-picker';
import ProgressBar from 'intergalactic/progress-bar';
import { Flex } from 'intergalactic/flex-box';
import { Text } from 'intergalactic/typography';

function randomInteger(min, max) {
  let rand = min - 0.5 + Math.random() * (max - min + 1);
  rand = Math.round(rand);
  return rand;
}

const Demo = () => {
  return (
    <Flex direction='column'>
      <Text tag='label' size={200} htmlFor='custom-day-example-picker'>
        Date picker
      </Text>
      <DatePicker>
        <DatePicker.Trigger mt={2} id='custom-day-example-picker' />
        <DatePicker.Popper>
          <DatePicker.Header />
          <DatePicker.Calendar>
            {({ days }) =>
              days.map((data, i) => (
                <DatePicker.Calendar.Unit {...data} key={i}>
                  <Flex direction='column' p={1} w={'100%'} alignItems='center'>
                    {data.children}
                    <ProgressBar
                      size='s'
                      duration={0}
                      value={randomInteger(0, 100)}
                      theme='dark'
                      mt={1}
                    />
                  </Flex>
                </DatePicker.Calendar.Unit>
              ))
            }
          </DatePicker.Calendar>
        </DatePicker.Popper>
      </DatePicker>
    </Flex>
  );
};

export default Demo;

Disabled dates

You can prevent selection of certain dates or a range of dates using the disabled property (and imagine yourself as a superhero 🕺🏻). The property takes an array of dates or an array with two dates to specify a range, or a crontab format for selecting dates periodically.

tsx
import React from 'react';
import { DatePicker } from 'intergalactic/date-picker';
import { Flex } from 'intergalactic/flex-box';
import { Text } from 'intergalactic/typography';

const Demo = () => {
  const today = new Date();
  return (
    <Flex direction='column'>
      <Text tag='label' size={200} htmlFor='disabled-dates-example-picker'>
        Date picker
      </Text>
      <DatePicker
        disabled={[new Date(today.getFullYear(), 0, 1), [today, false], '* * 6,7']}
        disabledErrorText='January 1 of this year is off-limits, only dates before today work, and Saturdays are a no-go.'
      >
        <DatePicker.Trigger mt={2} id='disabled-dates-example-picker' />
        <DatePicker.Popper />
      </DatePicker>
    </Flex>
  );
};

export default Demo;
import React from 'react';
import { DatePicker } from 'intergalactic/date-picker';
import { Flex } from 'intergalactic/flex-box';
import { Text } from 'intergalactic/typography';

const Demo = () => {
  const today = new Date();
  return (
    <Flex direction='column'>
      <Text tag='label' size={200} htmlFor='disabled-dates-example-picker'>
        Date picker
      </Text>
      <DatePicker
        disabled={[new Date(today.getFullYear(), 0, 1), [today, false], '* * 6,7']}
        disabledErrorText='January 1 of this year is off-limits, only dates before today work, and Saturdays are a no-go.'
      >
        <DatePicker.Trigger mt={2} id='disabled-dates-example-picker' />
        <DatePicker.Popper />
      </DatePicker>
    </Flex>
  );
};

export default Demo;

Custom date ranges

Date ranges may be customized or switched off at all, by transferring periods={[]}.

tsx
import React from 'react';
import { DateRangePicker } from 'intergalactic/date-picker';
import { Flex } from 'intergalactic/flex-box';
import { Text } from 'intergalactic/typography';

const Demo = () => {
  const pastYear = new Date();
  pastYear.setFullYear(pastYear.getFullYear() - 1);
  const past6days = new Date();
  past6days.setDate(past6days.getDate() - 6);
  const past13days = new Date();
  past13days.setDate(past13days.getDate() - 13);

  const periods = [
    { children: 'Last 7 days', value: [past6days, new Date()] },
    { children: 'Last 14 days', value: [past13days, new Date()] },
    { children: 'Last Year', value: [pastYear, new Date()] },
  ];
  return (
    <Flex gap={5} flexWrap>
      <Flex direction='column'>
        <Text tag='label' size={200} htmlFor='customized-periods'>
          Customized periods
        </Text>
        <DateRangePicker periods={periods}>
          <DateRangePicker.Trigger mt={2} id='customized-periods' />
          <DateRangePicker.Popper />
        </DateRangePicker>
      </Flex>
      <Flex direction='column'>
        <Text tag='label' size={200} htmlFor='normal-periods'>
          Normal periods
        </Text>
        <DateRangePicker>
          <DateRangePicker.Trigger mt={2} id='normal-periods' />
          <DateRangePicker.Popper />
        </DateRangePicker>
      </Flex>
    </Flex>
  );
};

export default Demo;
import React from 'react';
import { DateRangePicker } from 'intergalactic/date-picker';
import { Flex } from 'intergalactic/flex-box';
import { Text } from 'intergalactic/typography';

const Demo = () => {
  const pastYear = new Date();
  pastYear.setFullYear(pastYear.getFullYear() - 1);
  const past6days = new Date();
  past6days.setDate(past6days.getDate() - 6);
  const past13days = new Date();
  past13days.setDate(past13days.getDate() - 13);

  const periods = [
    { children: 'Last 7 days', value: [past6days, new Date()] },
    { children: 'Last 14 days', value: [past13days, new Date()] },
    { children: 'Last Year', value: [pastYear, new Date()] },
  ];
  return (
    <Flex gap={5} flexWrap>
      <Flex direction='column'>
        <Text tag='label' size={200} htmlFor='customized-periods'>
          Customized periods
        </Text>
        <DateRangePicker periods={periods}>
          <DateRangePicker.Trigger mt={2} id='customized-periods' />
          <DateRangePicker.Popper />
        </DateRangePicker>
      </Flex>
      <Flex direction='column'>
        <Text tag='label' size={200} htmlFor='normal-periods'>
          Normal periods
        </Text>
        <DateRangePicker>
          <DateRangePicker.Trigger mt={2} id='normal-periods' />
          <DateRangePicker.Popper />
        </DateRangePicker>
      </Flex>
    </Flex>
  );
};

export default Demo;

Week picker made from DateRangePicker

You can manually select a custom period, if needed (for example, a week) by taking all the control in manual mode.

tsx
import React from 'react';
import { DateRangePicker } from 'intergalactic/date-picker';
import { Flex } from 'intergalactic/flex-box';
import { Text } from 'intergalactic/typography';

function dateToClosestWeek(date) {
  const startWeek = new Date(date);
  const endWeek = new Date(date);

  startWeek.setDate(startWeek.getDate() + 1 - (startWeek.getDay() || 7));
  endWeek.setDate(endWeek.getDate() + 7 - (endWeek.getDay() || 7));
  return [startWeek, endWeek];
}

const Demo = () => {
  const [visible, setVisible] = React.useState(false);
  const [value, setValue] = React.useState([]);
  const [highlighted, setHighlighted] = React.useState([]);

  React.useEffect(() => {
    if (!value[0]) return;
    const week = dateToClosestWeek(value[0]);
    if (!value[1] || week[0].getTime() !== value[0].getTime()) {
      setValue(week);
    }
  }, [value[0]?.getTime()]);

  return (
    <Flex direction='column'>
      <Text tag='label' size={200} htmlFor='week-picker'>
        Week picker
      </Text>
      <DateRangePicker
        visible={visible}
        onVisibleChange={(visible) => setVisible(visible)}
        value={value}
        onChange={setValue}
        highlighted={highlighted}
      >
        <DateRangePicker.Trigger mt={2}>
          <DateRangePicker.Trigger.DateRange>
            <DateRangePicker.Trigger.DateRange.Indicator />
            <DateRangePicker.Trigger.DateRange.FromMaskedInput id='week-picker' />
            <DateRangePicker.Trigger.DateRange.RangeSep />
            <DateRangePicker.Trigger.DateRange.ToMaskedInput disabled />
          </DateRangePicker.Trigger.DateRange>
        </DateRangePicker.Trigger>
        <DateRangePicker.Popper>
          <DateRangePicker.Header />
          <DateRangePicker.Calendar
            renderOutdated
            onHighlightedChange={(date) => {
              if (date.length === 1) setHighlighted([]);
            }}
          >
            {({ days }) =>
              days.map((data, i) => (
                <DateRangePicker.Calendar.Unit
                  {...data}
                  key={i}
                  onMouseEnter={() => {
                    setHighlighted(dateToClosestWeek(data.date));
                  }}
                  onClick={() => {
                    setValue(dateToClosestWeek(data.date));
                    setVisible(false);
                    return false;
                  }}
                />
              ))
            }
          </DateRangePicker.Calendar>
        </DateRangePicker.Popper>
      </DateRangePicker>
    </Flex>
  );
};

export default Demo;
import React from 'react';
import { DateRangePicker } from 'intergalactic/date-picker';
import { Flex } from 'intergalactic/flex-box';
import { Text } from 'intergalactic/typography';

function dateToClosestWeek(date) {
  const startWeek = new Date(date);
  const endWeek = new Date(date);

  startWeek.setDate(startWeek.getDate() + 1 - (startWeek.getDay() || 7));
  endWeek.setDate(endWeek.getDate() + 7 - (endWeek.getDay() || 7));
  return [startWeek, endWeek];
}

const Demo = () => {
  const [visible, setVisible] = React.useState(false);
  const [value, setValue] = React.useState([]);
  const [highlighted, setHighlighted] = React.useState([]);

  React.useEffect(() => {
    if (!value[0]) return;
    const week = dateToClosestWeek(value[0]);
    if (!value[1] || week[0].getTime() !== value[0].getTime()) {
      setValue(week);
    }
  }, [value[0]?.getTime()]);

  return (
    <Flex direction='column'>
      <Text tag='label' size={200} htmlFor='week-picker'>
        Week picker
      </Text>
      <DateRangePicker
        visible={visible}
        onVisibleChange={(visible) => setVisible(visible)}
        value={value}
        onChange={setValue}
        highlighted={highlighted}
      >
        <DateRangePicker.Trigger mt={2}>
          <DateRangePicker.Trigger.DateRange>
            <DateRangePicker.Trigger.DateRange.Indicator />
            <DateRangePicker.Trigger.DateRange.FromMaskedInput id='week-picker' />
            <DateRangePicker.Trigger.DateRange.RangeSep />
            <DateRangePicker.Trigger.DateRange.ToMaskedInput disabled />
          </DateRangePicker.Trigger.DateRange>
        </DateRangePicker.Trigger>
        <DateRangePicker.Popper>
          <DateRangePicker.Header />
          <DateRangePicker.Calendar
            renderOutdated
            onHighlightedChange={(date) => {
              if (date.length === 1) setHighlighted([]);
            }}
          >
            {({ days }) =>
              days.map((data, i) => (
                <DateRangePicker.Calendar.Unit
                  {...data}
                  key={i}
                  onMouseEnter={() => {
                    setHighlighted(dateToClosestWeek(data.date));
                  }}
                  onClick={() => {
                    setValue(dateToClosestWeek(data.date));
                    setVisible(false);
                    return false;
                  }}
                />
              ))
            }
          </DateRangePicker.Calendar>
        </DateRangePicker.Popper>
      </DateRangePicker>
    </Flex>
  );
};

export default Demo;

DateRangeComparator

DateRangeComparator allows user to compare two date ranges. Additional date range may be controlled with compare and onCompareChange props.

tsx
import React from 'react';
import { DateRangeComparator, MonthDateRangeComparator } from 'intergalactic/date-picker';
import { Flex } from 'intergalactic/flex-box';

const Demo = () => {
  return (
    <Flex gap={4} flexWrap>
      <DateRangeComparator />
      <MonthDateRangeComparator />
    </Flex>
  );
};

export default Demo;
import React from 'react';
import { DateRangeComparator, MonthDateRangeComparator } from 'intergalactic/date-picker';
import { Flex } from 'intergalactic/flex-box';

const Demo = () => {
  return (
    <Flex gap={4} flexWrap>
      <DateRangeComparator />
      <MonthDateRangeComparator />
    </Flex>
  );
};

export default Demo;

DateRangeComparator advanced usage

DateRangeComparator internal structure maybe deeply redefined for flexible customization.

tsx
import React from 'react';
import { DateRangeComparator, MonthDateRangeComparator } from 'intergalactic/date-picker';
import { Flex } from 'intergalactic/flex-box';
import Notice from 'intergalactic/notice';
import WarningIcon from 'intergalactic/icon/Warning/m';
import { Text } from 'intergalactic/typography';

const Demo = () => {
  return (
    <Flex flexWrap>
      <DateRangeComparator>
        <DateRangeComparator.Trigger />
        <DateRangeComparator.Popper>
          <DateRangeComparator.Header>
            <DateRangeComparator.ValueDateRange />
            <DateRangeComparator.CompareToggle />
            <DateRangeComparator.CompareDateRange />
          </DateRangeComparator.Header>
          <DateRangeComparator.Body>
            <DateRangeComparator.RangeCalendar />
            <DateRangeComparator.Periods>
              <DateRangeComparator.Periods.Divider />
              <DateRangeComparator.Periods.Column>
                <DateRangeComparator.Periods.Options />
                <DateRangeComparator.Periods.Controls>
                  <DateRangeComparator.Apply />
                  <DateRangeComparator.Reset />
                </DateRangeComparator.Periods.Controls>
              </DateRangeComparator.Periods.Column>
            </DateRangeComparator.Periods>
          </DateRangeComparator.Body>
          <DateRangeComparator.Footer>
            Place for a hint, useful message or controls.
          </DateRangeComparator.Footer>
          <Notice theme='warning' style={{ borderTopLeftRadius: 0, borderTopRightRadius: 0 }}>
            <Notice.Content>
              <Flex mb={1}>
                <Notice.Label>
                  <WarningIcon />
                </Notice.Label>
                <Text bold>Notice heading</Text>
              </Flex>
              If you change your location, all previously collected data for this article will be
              lost.
            </Notice.Content>
          </Notice>
        </DateRangeComparator.Popper>
      </DateRangeComparator>
    </Flex>
  );
};

export default Demo;
import React from 'react';
import { DateRangeComparator, MonthDateRangeComparator } from 'intergalactic/date-picker';
import { Flex } from 'intergalactic/flex-box';
import Notice from 'intergalactic/notice';
import WarningIcon from 'intergalactic/icon/Warning/m';
import { Text } from 'intergalactic/typography';

const Demo = () => {
  return (
    <Flex flexWrap>
      <DateRangeComparator>
        <DateRangeComparator.Trigger />
        <DateRangeComparator.Popper>
          <DateRangeComparator.Header>
            <DateRangeComparator.ValueDateRange />
            <DateRangeComparator.CompareToggle />
            <DateRangeComparator.CompareDateRange />
          </DateRangeComparator.Header>
          <DateRangeComparator.Body>
            <DateRangeComparator.RangeCalendar />
            <DateRangeComparator.Periods>
              <DateRangeComparator.Periods.Divider />
              <DateRangeComparator.Periods.Column>
                <DateRangeComparator.Periods.Options />
                <DateRangeComparator.Periods.Controls>
                  <DateRangeComparator.Apply />
                  <DateRangeComparator.Reset />
                </DateRangeComparator.Periods.Controls>
              </DateRangeComparator.Periods.Column>
            </DateRangeComparator.Periods>
          </DateRangeComparator.Body>
          <DateRangeComparator.Footer>
            Place for a hint, useful message or controls.
          </DateRangeComparator.Footer>
          <Notice theme='warning' style={{ borderTopLeftRadius: 0, borderTopRightRadius: 0 }}>
            <Notice.Content>
              <Flex mb={1}>
                <Notice.Label>
                  <WarningIcon />
                </Notice.Label>
                <Text bold>Notice heading</Text>
              </Flex>
              If you change your location, all previously collected data for this article will be
              lost.
            </Notice.Content>
          </Notice>
        </DateRangeComparator.Popper>
      </DateRangeComparator>
    </Flex>
  );
};

export default Demo;

MonthRangeComparator advanced usage

MonthDateRangeComparator internal structure maybe deeply redefined for flexible customization.

tsx
import React from 'react';
import { MonthDateRangeComparator } from 'intergalactic/date-picker';
import { Flex } from 'intergalactic/flex-box';
import Notice from 'intergalactic/notice';
import WarningIcon from 'intergalactic/icon/Warning/m';
import { Text } from 'intergalactic/typography';

const Demo = () => {
  return (
    <Flex flexWrap>
      <MonthDateRangeComparator>
        <MonthDateRangeComparator.Trigger />
        <MonthDateRangeComparator.Popper>
          <MonthDateRangeComparator.Header>
            <MonthDateRangeComparator.ValueDateRange />
            <MonthDateRangeComparator.CompareToggle />
            <MonthDateRangeComparator.CompareDateRange />
          </MonthDateRangeComparator.Header>
          <MonthDateRangeComparator.Body>
            <MonthDateRangeComparator.RangeCalendar />
            <MonthDateRangeComparator.Periods>
              <MonthDateRangeComparator.Periods.Divider />
              <MonthDateRangeComparator.Periods.Column>
                <MonthDateRangeComparator.Periods.Options />
                <MonthDateRangeComparator.Periods.Controls>
                  <MonthDateRangeComparator.Apply />
                  <MonthDateRangeComparator.Reset />
                </MonthDateRangeComparator.Periods.Controls>
              </MonthDateRangeComparator.Periods.Column>
            </MonthDateRangeComparator.Periods>
          </MonthDateRangeComparator.Body>
          <MonthDateRangeComparator.Footer>
            Place for a hint, useful message or controls.
          </MonthDateRangeComparator.Footer>
          <Notice theme='warning' style={{ borderTopLeftRadius: 0, borderTopRightRadius: 0 }}>
            <Notice.Content>
              <Flex mb={1}>
                <Notice.Label>
                  <WarningIcon />
                </Notice.Label>
                <Text bold>Notice heading</Text>
              </Flex>
              If you change your location, all previously collected data for this article will be
              lost.
            </Notice.Content>
          </Notice>
        </MonthDateRangeComparator.Popper>
      </MonthDateRangeComparator>
    </Flex>
  );
};

export default Demo;
import React from 'react';
import { MonthDateRangeComparator } from 'intergalactic/date-picker';
import { Flex } from 'intergalactic/flex-box';
import Notice from 'intergalactic/notice';
import WarningIcon from 'intergalactic/icon/Warning/m';
import { Text } from 'intergalactic/typography';

const Demo = () => {
  return (
    <Flex flexWrap>
      <MonthDateRangeComparator>
        <MonthDateRangeComparator.Trigger />
        <MonthDateRangeComparator.Popper>
          <MonthDateRangeComparator.Header>
            <MonthDateRangeComparator.ValueDateRange />
            <MonthDateRangeComparator.CompareToggle />
            <MonthDateRangeComparator.CompareDateRange />
          </MonthDateRangeComparator.Header>
          <MonthDateRangeComparator.Body>
            <MonthDateRangeComparator.RangeCalendar />
            <MonthDateRangeComparator.Periods>
              <MonthDateRangeComparator.Periods.Divider />
              <MonthDateRangeComparator.Periods.Column>
                <MonthDateRangeComparator.Periods.Options />
                <MonthDateRangeComparator.Periods.Controls>
                  <MonthDateRangeComparator.Apply />
                  <MonthDateRangeComparator.Reset />
                </MonthDateRangeComparator.Periods.Controls>
              </MonthDateRangeComparator.Periods.Column>
            </MonthDateRangeComparator.Periods>
          </MonthDateRangeComparator.Body>
          <MonthDateRangeComparator.Footer>
            Place for a hint, useful message or controls.
          </MonthDateRangeComparator.Footer>
          <Notice theme='warning' style={{ borderTopLeftRadius: 0, borderTopRightRadius: 0 }}>
            <Notice.Content>
              <Flex mb={1}>
                <Notice.Label>
                  <WarningIcon />
                </Notice.Label>
                <Text bold>Notice heading</Text>
              </Flex>
              If you change your location, all previously collected data for this article will be
              lost.
            </Notice.Content>
          </Notice>
        </MonthDateRangeComparator.Popper>
      </MonthDateRangeComparator>
    </Flex>
  );
};

export default Demo;

Released under the MIT License.

Released under the MIT License.