Ползунок внутри модального не работает — Интерфейс React Material

#javascript #html #reactjs

#javascript #HTML #reactjs

Вопрос:

Я пытаюсь присоединить пользовательский компонент слайдера к модальному компоненту MUI.

Мой слайдер довольно хорошо работает в сборнике рассказов, это поведение, как и ожидалось:

Ожидаемое поведение

Но когда я добавляю его в модальный интерфейс Material UI, это поведение:

Текущее поведение

Я действительно не знаю, что может происходить… Я попытался создать свой собственный модальный (без MUI), используя другую библиотеку слайдеров, и все они ведут себя одинаково.

Я получаю это предупреждение, когда пытаюсь переместить свой слайдер на модальный:

 Slider.js:770 [Violation] Added non-passive event listener to a scroll-blocking 'touchstart' event. 
Consider marking the event handler as 'passive' to make the page more responsive. 
See https://www.chromestatus.com/feature/5745543795965952
  

Это мой код слайдера (который, чтобы подчеркнуть, отлично работает вне модального:

 import React from "react";
import {
  styled,
  Grid,
  Slider as MUISlider,
  InputBase,
  Tooltip,
} from "@material-ui/core";

const CustomSlider = styled(MUISlider)(({ theme }) => ({
  color: theme.palette.secondary.light,
  width: 86,
}));

const GasInput = styled(InputBase)(({ theme }) => ({
  color: theme.palette.secondary.light,
  width: 48,
  height: 32,
  border: "1px solid #ECEFF3",
  borderRadius: 4,
  background: "#FAFCFF",
  fontSize: 12,
  boxSizing: "border-box",
  padding: 12,
}));

const SliderContainer = styled(Grid)({
  width: 200,
  height: 20,
  marginTop: -10,
});

const Input = styled(Grid)({
  paddingLeft: 8,
});

export interface SliderProps {
  value: number;
  min: number;
  max: number;
  onChangeValue: (value: number) => void;
}

interface Props {
  children: React.ReactElement;
  open: boolean;
  value: number;
}

function ValueLabelComponent(props: Props) {
  const { children, open, value } = props;

  return (
    <Tooltip open={open} enterTouchDelay={0} placement="top" title={value}>
      {children}
    </Tooltip>
  );
}

export function Slider({ min, max, value, onChangeValue }: SliderProps) {
  const handleSliderChange = (
    _: React.ChangeEvent<unknown>,
    value: number | number[]
  ) => {
    onChangeValue(Number(value));
  };

  const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    onChangeValue(parseInt(event.target.value, 10));
  };

  return (
    <SliderContainer
      container
      direction="row"
      alignItems="center"
      justify="flex-end"
    >
      <Grid item>
        <CustomSlider
          ValueLabelComponent={ValueLabelComponent}
          min={min}
          max={max}
          value={value}
          onChange={handleSliderChange}
        />
      </Grid>
      <Input item>
        <GasInput type="number" value={value} onChange={handleInputChange} />
      </Input>
    </SliderContainer>
  );
}

  

Ответ №1:

Я создал пример, используя ваш код. Кажется, все работает так, как ожидалось. Сравните ваш локальный код с этим.

Комментарии:

1. Да, это потому, что он будет работать так, как ожидалось, когда находится за пределами модального, но вы добавляете этот код внутри модального компонента, он сломает @jack.benson

2. Я обновил пример, чтобы использовать модальный, кажется, все еще работает нормально. codesandbox.io/s/cool-payne-tlolu?file=/src/App.tsx

3. Боже мой. Вы правы, сэр. Странное поведение было сделано потому, что я использовал styled внутри созданного мной модального. Я создам ответ с точной ошибкой

Ответ №2:

Благодаря ответу @jack.benson я смог выяснить, что происходит на самом деле (очень признателен, сэр).

Я создал модальный компонент, который абстрагировал основные элементы модального, которые я буду использовать во всем приложении:

 import React from "react";
import { Modal as MUIModal, Box, styled } from "@material-ui/core";

interface ModalProps {
  width: number;
  height: number;
  children: React.ReactNode;
  open: boolean;
}

export function Modal({ width, height, children, open }: ModalProps) {
  const ModalContainer = styled(MUIModal)({
    height,
    width,
    margin: "auto",
    borderRadius: 12,
  });

  const ModalBox = styled(Box)({
    height,
    width,
    background: "#FFFFFF",
    borderRadius: 12,
    outline: "none",
  });

  return (
    <ModalContainer open={open}>
      <ModalBox>{children}</ModalBox>
    </ModalContainer>
  );
}
  

Как вы можете видеть, я использую styled функцию для стилизации своих компонентов. И это то, что вызывало у меня проблему. Я не знаю, в чем причина, но если я перейду styled к makeStyles нему, он будет работать отлично, это новый код моего модального компонента:

 import React from "react";
import { Modal as MUIModal, Box, makeStyles } from "@material-ui/core";

interface ModalProps {
  width: number;
  height: number;
  children: React.ReactNode;
  open: boolean;
}

const useStyles = ({ height, width }: Partial<ModalProps>) => makeStyles({
  root: {
    height: `${height}px`,
    width: `${width}px`,
    margin: "auto",
    borderRadius: 12,
  },
  box: {
    height: `${height}px`,
    width: `${width}px`,
    background: "#FFFFFF",
    borderRadius: 12,
    outline: 0,
  }
});

export function Modal({ width, height, children, open }: ModalProps) {
  const classes = useStyles({ width, height })()
  return (
    <MUIModal className={classes.root} open={open}>
      <Box className={classes.box}>{children}</Box>
    </MUIModal>
  );
}