es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Centrar un diálogo de material UI en el centro de la pantalla aunque su altura pueda variar.

Tengo un diálogo MUI, cuya altura varía debido a que es una lista que es filtrada por el usuario. Resulta molesto porque el diálogo “salta” por la pantalla tratando de mantener su posición central a medida que crece y se reduce. Esto es lo que parece:

Una solución simple para este problema particular sería simplemente anular la propiedad de alineación de alignItems de dialogPaper a través de la propiedad classes. Algo como esto:

“`const useStyles = makeStyles((theme) => ({
pivottedDialog: {
alignItems: 'unset',

},
}));

const MyDialog = () => (
<dialog {…otherprops}="" classes="{{" scrollpaper:="" classes.pivotteddialog="" }}="">

</dialog>
)
“`

Esto, sin embargo, hace que pierda su posicionamiento centrado en la pantalla, cuando todavía necesito que esté centrado (en referencia al diálogo con la lista completa, sin nada filtrado). Me gustaría que su punto de partida fuera el mismo que el diálogo sin cambios, en todos los tamaños de pantalla aplicables (por encima de 600px de ancho).

¿Cómo podría hacer esto?

He intentado jugar con el posicionamiento y la propiedad de top en la clase pivottedDialog, pero cambia dependiendo del tamaño de la pantalla. Esto debe ser receptivo y centrado en todos los tamaños de pantalla por encima de 600px de ancho.

Hice una aplicación de muestra con los dos diálogos, que se puede jugar aquí: https://codesandbox.io/s/crazy-tesla-emc8m?file=/src/App.js

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Un enfoque para resolver este problema sería calcular dinámicamente la posición superior del diálogo utilizando JavaScript. De esta manera, siempre podemos asegurarnos de que el diálogo esté centrado independientemente de su altura.

    En primer lugar, necesitamos agregar una referencia a nuestro componente de diálogo. Podemos hacer esto utilizando el gancho useRef proporcionado por React:

    const dialogRef = useRef(null);
    
    // ...
    
    <dialog ...="" ref="{dialogRef}">
      // ...
    </dialog>
    

    Luego, necesitamos calcular la posición superior del diálogo en píxeles. Podemos hacer esto restando la mitad de la altura del diálogo de la mitad de la altura de la ventana gráfica:

    const viewportHeight = window.innerHeight;
    const dialogHeight = dialogRef.current?.clientHeight;
    const top = Math.max((viewportHeight - dialogHeight) / 2, 0);
    

    Necesitamos usar Math.max para asegurarnos de que la posición superior no vaya por debajo de 0 si la altura del diálogo es mayor que la altura de la ventana gráfica.

    Finalmente, podemos establecer la posición superior utilizando estilos en línea:

    <dialog ...="" ref="{dialogRef}" style="{{" top="" }}="">
      // ...
    </dialog>
    

    Al poner todo junto, nuestro componente MyDialog se vería algo así:

    import { useRef, useEffect, useState } from "react";
    
    const useStyles = makeStyles((theme) => ({
      pivottedDialog: {
        alignItems: "unset",
        "& .MuiDialogTitle-root": {
          paddingTop: 0,
        },
      },
    }));
    
    const MyDialog = (props) => {
      const dialogRef = useRef(null);
      const [top, setTop] = useState(0);
    
      useEffect(() => {
        const recalculateTop = () => {
          const viewportHeight = window.innerHeight;
          const dialogHeight = dialogRef.current?.clientHeight;
          setTop(Math.max((viewportHeight - dialogHeight) / 2, 0));
        };
    
        recalculateTop();
        window.addEventListener("resize", recalculateTop);
        return () => {
          window.removeEventListener("resize", recalculateTop);
        };
      }, []);
    
      const classes = useStyles();
    
      return (
        <dialog {...props}="" classes="{{" scrollpaper:="" classes.pivotteddialog,="" }}="" ref="{dialogRef}" style="{{" top="" }}="">
          // ...
        </dialog>
      );
    };
    

    Con este enfoque, el diálogo siempre estará centrado en la pantalla independientemente de su altura y seguirá siendo receptivo para todos los tamaños de pantalla por encima de los 600 píxeles de ancho.

Comments are closed.