React-date-picker: Create a portal to render the calendar

Created on 21 Aug 2018  路  9Comments  路  Source: wojtekmaj/react-date-picker

Right now, when I click on the input, the calendar's HTML is rendered next to the input element.

It would be good render it inside a Portal (https://reactjs.org/docs/portals.html), so that it doesn't interfere with the styling of the input element's container.

Most helpful comment

Hacky workaround:

class MyDatePicker extends ReactDatePicker {
  renderCalendar() {
    const elem = super.renderCalendar();
    if (!elem) { return null; }
    return (
      <Popover
         active={this.state.isOpen}
         targetEl={this.props.name}
      >
        {elem}
      </Popover>
    );
  }
}

Popover (or whatever) is custom component which renders child through portal (this.props.name used as id to obtain element dimensions). Hope you won't rename renderCalendar or isOpen state prop at some time 馃槃

All 9 comments

This makes positioning very tricky. I personally had tons of issues with such solutions in popups and other non-body containers.

Additionally, in case someone would use React-Calendar independently, this could create styling problems for them.

I'd need to give it a thought!

Had a similar problem here.

I try to use the datePicker inside overflow:hidden container so when I open the calendar popup, obviously, the popup is partially hidden and doesn't shown as expected.
With portal, or even a lighter option - to able to render the calendar popup under body container, will be really helpful.

Thanks!

You could use position: fixed to let the calendar render regardless of overflow: hidden but I don't know if that will be sufficient for your app.

Hacky workaround:

class MyDatePicker extends ReactDatePicker {
  renderCalendar() {
    const elem = super.renderCalendar();
    if (!elem) { return null; }
    return (
      <Popover
         active={this.state.isOpen}
         targetEl={this.props.name}
      >
        {elem}
      </Popover>
    );
  }
}

Popover (or whatever) is custom component which renders child through portal (this.props.name used as id to obtain element dimensions). Hope you won't rename renderCalendar or isOpen state prop at some time 馃槃

@wojtekmaj I would suggest to implement both option in the calendar render:

  1. via existing way
  2. via portal

As for good example, react-select uses those two types of render, you just have to select the prop to do it

You could use position: fixed to let the calendar render regardless of overflow: hidden but I don't know if that will be sufficient for your app.

@asvetliakov there is no renderCalendar method

finally, I found a solution to solving this problem

using react-calendar and wrap it into 'popover' which is from 'material-ui'

image

works like a charm

image

You could use position: fixed to let the calendar render regardless of overflow: hidden but I don't know if that will be sufficient for your app.

@wojtekmaj Could you please describe how to use it? Or do you just mean to set fixed on the date picker so that it does not scroll with the other content?

@gius

Or do you just mean to set fixed on the date picker so that it does not scroll with the other content?

That's what I meant.

Was this page helpful?
0 / 5 - 0 ratings