cph2117
cph2117

Reputation: 2681

Material UI date picker behaving differently on mobile device

I'm using Material UI datepicker in a React project. I've created a calendar + time selection (code below). For some reason when I test this on Chrome desktop using the device toolbar to emulate iphone 8 it works fine, but when I go to the site on my actual iphone 8, the UI is broken (images below). Any thoughts?

import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { Button, Typography } from '@material-ui/core';
import { makeStyles } from '@material-ui/core/styles';
import moment from 'moment';
import { MuiPickersUtilsProvider, DatePicker } from '@material-ui/pickers';
import DateFnsUtils from '@date-io/date-fns';

const useStyles = makeStyles(theme => ({
    root: {
        display: 'flex',
        flexDirection: 'row',
        padding: theme.spacing(3),
        [theme.breakpoints.down('sm')]: {
            padding: 0,
        },
    },
    picker: {
        display: 'flex',
        flexDirection: 'row',
        [theme.breakpoints.down('sm')]: {
            flexDirection: 'column',
        },
    },
    timeContainer: {
        display: 'flex',
        flexDirection: 'column',
        marginLeft: theme.spacing(2),
        overflowY: 'scroll',
        [theme.breakpoints.down('sm')]: {
            alignItems: 'center',
            marginLeft: 0,
            marginBottom: theme.spacing(3),
        },
    },
    timeButton: { width: 226, height: 50 },
}));

export default function Timesgrid(props) {
    const classes = useStyles();

    const [selectedDate, setSeletedDate] = useState(moment());

    const disableDay = date => {
        const formattedDate = moment(date).format('YYYY-MM-DD');
        return formattedDate in props.availability &&
            props.availability[formattedDate].length > 0
            ? false
            : true;
    };

    const handleDateChange = date => {
        setSeletedDate(moment(date));
    };

    const renderTimes = () => {
        const dateStr = moment(selectedDate).format('YYYY-MM-DD');
        const availability = props.availability[dateStr];
        return availability && availability.length ? (
            <div className={classes.timeContainer}>
                {availability.map((time, i) => (
                    <Button
                        style={{ marginTop: i === 0 ? 0 : 10 }}
                        key={time}
                        className={classes.timeButton}
                        variant="outlined"
                        color="primary"
                        onClick={() => props.onDatetimeSelected(moment(time))}
                    >
                        <b>{moment(time).format('LT')}</b>
                    </Button>
                ))}
            </div>
        ) : (
            <Typography variant="h6" className={classes.timeContainer}>
                No availability
            </Typography>
        );
    };
    const renderPicker = () => {
        return (
            <div className={classes.picker}>
                <MuiPickersUtilsProvider utils={DateFnsUtils}>
                    <DatePicker
                        disablePast
                        shouldDisableDate={disableDay}
                        variant="static"
                        defaultValue={selectedDate}
                        value={selectedDate}
                        onChange={handleDateChange}
                    />
                </MuiPickersUtilsProvider>
                {renderTimes()}
            </div>
        );
    };

    return <div className={classes.root}>{renderPicker()}</div>;
}

Timesgrid.propTypes = {
    availability: PropTypes.object.isRequired,
    onDatetimeSelected: PropTypes.func.isRequired,
};

On the Chrome iphone8 emulator

On my iphone8

Upvotes: 0

Views: 3475

Answers (1)

Nicholas_Jones
Nicholas_Jones

Reputation: 330

The answer to your question as we discussed in comments was to add the following CSS styling.

overflow: scroll
height: 100%

Justification:

The reason I suggested this solution was due to the comparisons in your images. The popup screen for the component was mushed together on the native browser popup but, not on the Chrome DevTools popup. This indicated that the native browser container was not allowing for overflow to occur.

Setting the height of the component to 100% ensures that it takes up the full height of it's container and allowing overflow ensures that if your component is greater than 100% of the containers height that it will render as shown in the devtools view.

Furthermore, In your reply you said your solution was

overflowY: scroll, 
height: 100%

and overflow: scroll allows for overflow on both axes. Since the x-axis doesn't require overflow, this is a better solution.

Glad to see it worked.

Upvotes: 2

Related Questions