Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pickers] slotProps not working as expected #10172

Closed
2 tasks done
jstgermain opened this issue Aug 30, 2023 · 2 comments
Closed
2 tasks done

[pickers] slotProps not working as expected #10172

jstgermain opened this issue Aug 30, 2023 · 2 comments
Labels
component: pickers This is the name of the generic UI component, not the React module!

Comments

@jstgermain
Copy link

Duplicates

  • I have searched the existing issues

Latest version

  • I have tested the latest version

Steps to reproduce 🕹

When using <DatePicker ... />, there is the new slotProps. From the docs and digging into the actual files, it looks like an icon should be able to be assigned with a component.

import { SetStateAction, useEffect, useState } from 'react';
import { DatePicker as MuiXDatePicker } from '@mui/x-date-pickers/DatePicker';
import { DatePickerProps as MuiXDatePickerProps } from '@mui/x-date-pickers/DatePicker';

import {
    getCurrentMonthBounds,
    getToday,
    dateInPast,
} from '@rcc-ui/utils/Date';
import Red from '@rcc-ui/styles/colors/Red';
import { ChevronIcon } from 'components/icons';

export interface DatePickerProps<TDate> extends MuiXDatePickerProps<TDate> {
    disablePastDates?: boolean; // @default false
}

interface DisabledProps {
    shouldDisableDate?: (date: Date, timezone?: string) => boolean;
}

const DatePicker = (props: DatePickerProps<Date>) => {
    const { disablePastDates, ...datePickerProps } = props;

    const [value, setValue] = useState<Date | null>(null);
    const [disabledProps, setDisabledProps] = useState<DisabledProps>({});
    const [popupOpened, setPopupOpened] = useState(false);

    useEffect(() => {
        console.log('getCurrentMonthBounds', getCurrentMonthBounds());
        console.log('getToday', getToday());
        console.log('dateInPast', dateInPast());

        if (props.disablePastDates)
            setDisabledProps({
                shouldDisableDate: (date) => dateInPast(date),
            });
    }, [props.disablePastDates]);

    const handleMonthChange = (newMonth: Date) => {
        // Your logic to handle month change
        console.log('Month changed:', newMonth);
    };

    const handleOnOpen = () => {
        if (!popupOpened) {
            console.log('opened');
            setPopupOpened(true);
        }
    };

    const handleOnClose = () => {
        console.log('closed');
        setPopupOpened(false);
    };

    const PickerIcon = () => <ChevronIcon />;

    return (
        <MuiXDatePicker
            {...datePickerProps}
            {...disabledProps}
            onMonthChange={handleMonthChange}
            onOpen={handleOnOpen}
            onClose={handleOnClose}
            slotProps={{
                leftArrowIcon: <ChevronIcon sx={{ color: Red[500] }} />,
                nextIconButton: (
                    <ChevronIcon variant='right' sx={{ color: Red[500] }} />
                ),
            }}
            value={value}
            onChange={(newValue: SetStateAction<Date | null>) => {
                setValue(newValue);
            }}
        />
    );
};

export default DatePicker;

The screen shot shows that the default ArrowLeft and ArrowRight icons. Standard MUI icons have been tried, but not working either.

Screenshot 2023-08-29 at 7 39 54 PM

Chevron component below that uses the MUI SvgIcon component

import { useEffect, useState } from 'react';
import SvgIcon, { SvgIconProps } from '@mui/material/SvgIcon';

export interface ChevronProps extends SvgIconProps {
    variant?:
    | 'down-alt'
    | 'down-circle-outline'
    | 'down'
    | 'left-alt'
    | 'left-circle-outline'
    | 'left'
    | 'right-alt'
    | 'right-circle-outline'
    | 'right'
    | 'up-alt'
    | 'up-circle-outline'
    | 'up'
    | undefined;
}

const Chevron = (props: ChevronProps) => {
    const { variant = 'right', sx, ...reducedProps } = props;
    const [variantDirection, setVariantDirection] =
        useState<string>('rotate(0)');

    // Default Variation
    const [variation, setVariation] = useState<string>(
        'M80.6,50L28.8,98.5c-2.2,2-5.5,2-7.7,0c-2-1.8-2.1-4.9-0.3-6.9c0.1-0.1,0.2-0.2,0.3-0.3L65.1,50L21,8.7c-2-1.8-2.1-4.9-0.3-6.9c0.1-0.1,0.2-0.2,0.3-0.3c2.2-2,5.5-2,7.7,0L80.6,50',
    );

    useEffect(() => {
        if (
            variant === 'down' ||
            variant === 'down-circle-outline' ||
            variant === 'down-alt'
        )
            setVariantDirection('rotate(90deg)');

        if (
            variant === 'left' ||
            variant === 'left-circle-outline' ||
            variant === 'left-alt'
        )
            setVariantDirection('rotate(180deg)');

        if (
            variant === 'up' ||
            variant === 'up-circle-outline' ||
            variant === 'up-alt'
        )
            setVariantDirection('rotate(270deg)');

        // Set Alt Icon
        if (
            variant === 'right-alt' ||
            variant === 'down-alt' ||
            variant === 'left-alt' ||
            variant === 'up-alt'
        )
            setVariation(
                'M83.3,50L34.6,97C30.5,101,24,101,19.8,97c-3.9-3.7-4.1-9.9-0.4-13.8c0.1-0.1,0.3-0.3,0.4-0.4L53.7,50l-34-32.8c-3.9-3.7-4.1-10-0.3-13.9c0.1-0.1,0.2-0.2,0.3-0.3C23.9-1,30.4-1,34.5,2.9L83.3,50z',
            );

        // Set Circle Outline Icon
        if (
            variant === 'right-circle-outline' ||
            variant === 'down-circle-outline' ||
            variant === 'left-circle-outline' ||
            variant === 'up-circle-outline'
        )
            setVariation(
                'M0,50C0,22.4,22.4,0,50,0s50,22.4,50,50s-22.4,50-50,50S0,77.6,0,50z M92.3,50c0-23.3-19-42.3-42.3-42.3S7.7,26.7,7.7,50s19,42.3,42.3,42.3S92.3,73.3,92.3,50z M75.6,50L45.6,79c-2.5,2.4-6.5,2.4-9.1,0c-2.4-2.3-2.5-6.1-0.3-8.5c0.1-0.1,0.2-0.2,0.3-0.3L57.4,50L36.5,29.8c-2.4-2.3-2.5-6.1-0.2-8.5c0.1-0.1,0.1-0.1,0.2-0.2c2.5-2.4,6.5-2.4,9.1,0L75.6,50z',
            );
    }, [variant]);

    return (
        <SvgIcon
            {...reducedProps}
            sx={{ ...sx, transform: variantDirection }} // Apply the transform style directly
            viewBox='0 0 100 100'
        >
            <path d={variation} />
        </SvgIcon>
    );
};

export default Chevron;

Below is a screen show that shows that the ChevronIcon works

Screenshot 2023-08-29 at 7 42 51 PM

Current behavior 😯

When trying to assign leftArrowIcon and rightArrowIcon, just the default ArrowLeft and ArrowRight appear.

Expected behavior 🤔

The custom component for <ChevronIcon /> should be displaying in place of ArrowLeft and ArrowRight

Context 🔦

Trying to customize the DatePicker for company brand style guide.

Your environment 🌎

npx @mui/envinfo

I am using Brave Browser

  System:
    OS: macOS 13.4.1
  Binaries:
    Node: 19.6.0 - ~/.nvm/versions/node/v19.6.0/bin/node
    Yarn: 1.22.19 - ~/.nvm/versions/node/v19.6.0/bin/yarn
    npm: 9.4.0 - ~/.nvm/versions/node/v19.6.0/bin/npm
  Browsers:
    Chrome: Not Found
    Edge: Not Found
    Safari: 16.5.2
  npmPackages:
    @emotion/react:  11.11.1 
    @emotion/styled:  11.11.0 
    @mui/base:  5.0.0-beta.11 
    @mui/core-downloads-tracker:  5.14.5 
    @mui/icons-material:  5.14.3 
    @mui/material:  5.14.5 
    @mui/private-theming:  5.14.5 
    @mui/styled-engine:  5.13.2 
    @mui/system:  5.14.5 
    @mui/types:  7.2.4 
    @mui/utils:  5.14.5 
    @mui/x-date-pickers:  6.12.0 
    @types/react:  18.2.20 
    react:  18.2.0 
    react-dom:  18.2.0 
    styled-components:  6.0.7 
    typescript:  4.9.5 

Order ID or Support key 💳 (optional)

No response

@jstgermain jstgermain added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Aug 30, 2023
@LukasTy
Copy link
Member

LukasTy commented Aug 30, 2023

Hello,
have you tried using slots instead? slotProps are for exactly that - passing props to certain slots.
Feel free to check the documentation example with the given slots overridden.

Closing the issue as the solution to the problem seems to be documented. 👍
If you feel that there is some missing information, feel free to reopen the issue. 😉

@LukasTy LukasTy closed this as not planned Won't fix, can't repro, duplicate, stale Aug 30, 2023
@LukasTy LukasTy added component: pickers This is the name of the generic UI component, not the React module! and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Aug 30, 2023
@LukasTy LukasTy changed the title slotProps not working as expected [pickers] slotProps not working as expected Aug 30, 2023
@jstgermain
Copy link
Author

@LukasTy I did try that too but must have done something incorrectly to begin with, and it looked like slotProps was the appropriate way. Thanks for clarifying. I got it to change now. Appreciate the direction.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: pickers This is the name of the generic UI component, not the React module!
Projects
None yet
Development

No branches or pull requests

2 participants