#impr3siones – #PR4 Contexto de diálogos
Empezamos con el frontal de #impr3siones añadiendo un contexto de diálogos para poder mostrarlos desde cualquier parte de la aplicación web con un hook. Puedes ver la #PR4 en github.
Seguramente parezca un punto de partida raro para empezar el frontal por el contexto de diálogos, pero al empezar por aquí sentamos unas bases para todo el frontal. Con este inicio definimos como gestionar contextos, componentes, hooks e incluso como definimos y usamos los estilos de los componentes.
¿A qué nos referimos con diálogo?
Un diálogo, conceptualmente, es un mensaje que aparece en la página, por encima del resto de la web, y al que el usuario tiene que hacer caso para continuar usando la web.
Puede haber distintos tipos de diálogos, de momento hemos creado dos tipos, de alerta y de confirmación. Los diálogos de alerta sirven para mostrar un mensaje al usuario, y los diálogos de confirmación para que el usuario pueda aceptar o rechazar una acción.
Una cosa a tener en cuenta de los diálogos es que no se deberían de apilar. Esto quiere decir que un diálogo no se puede mostrar si ya se está mostrando otro, aunque sean de distintos tipos.
El contexto de diálogos
¿Por qué un contexto de diálogos?
Un contexto nos permite centralizar la gestión de los diálogos para toda la web, de manera que podamos resolver el que no se puedan apilar, y también nos permite, con un simple hook, poder mostrar todos los tipos de diálogos desde cualquier componente.
¿Cómo funciona el contexto?
Nuestro contexto expone las funciones que, al llamarlas, encolarán los diálogos y devolverán una promesa que se resuelve en el momento que el diálogo se cierra, ya sea con o sin resultado.
export interface DialogsContext {
showAlertDialog: (
content: Omit<AlertDialogContent, 'close'>
) => Promise<void>;
showConfirmDialog: (
content: Omit<ConfirmDialogContent, 'close'>
) => Promise<boolean>;
}
Puedes ver toda la implementación del contexto en la PR.
¿Cómo usamos los diálogos?
La manera mas sencilla de poder usar los diálogos es con el hook de diálogos, el cual expone el contexto para poder usarse desde cualquier componente.
const { showConfirmDialog } = useDialogs();
const showDialogs = async () => {
const result = await showConfirmDialog({
title: 'Título',
message: 'Diálogo de confirmación'
});
};
Instalación de un contexto en Next.js
Los contextos en React tienen que estar por encima de los componentes que los utilicen, por lo tanto la manera de engancharlos en Next.js es en el archivo pages/_app.tsx
import '../styles/globals.css';
import type { AppProps } from 'next/app';
import { DialogsProvider } from '../contexts/dialogs';
function MyApp({ Component, pageProps }: AppProps) {
return (
<DialogsProvider>
<Component {...pageProps} />
</DialogsProvider>
);
}
export default MyApp;
He de decir que tengo dudas sobre si esta es la manera correcta de usar contextos en Next.js, ya que me da la sensación de que puede que el contexto se pierda al cambiar de página, pero eso es algo que veremos en el futuro.
Componentes
Otra de las cosas que incluye esta PR son los primeros componentes comunes, que caerán bajo la carpeta /frontend/components.
Button
El componente más básico con el cual el usuario puede interactuar con la página, a partir de ahora en vez de usar el componente button de html, podremos usar el componente Button. Además tenemos dos variantes de botón a las que daremos estilos distintos.
Diálogos
Actualmente tenemos dos tipos de diálogos, el de alerta y el de confirmación, pero para construirlos tenemos una serie de componentes básicos:
- DialogTitle – El título del diálogo.
- DialogContent – El cuerpo central del diálogo.
- DialogActions – La sección de acciones de los diálogos.
- DialogAction – Botón para las acciones de los diálogos.
Estilos
Para dar estilo a los componentes usaremos SCSS, con nomenclatura BEM y los estilos encapsulados a nivel de componente. De esta manera para cada componente definido en un fichero .tsx, tendremos los estilos en un fichero con el mismo nombre pero acabado en .module.scss.
...
import styles from './button.module.scss';
...
const Button: React.FC<Props> = ({
children,
className,
onClick,
variant
}: Props) => {
return (
<button
className={classnames(
styles['button'],
className,
variant ? styles[`button--${variant}`] : ''
)}
onClick={onClick}
>
{children}
</button>
);
};
...
La manera de usar las clases, ya que el css está encapsulado, es mediante el objeto styles. El objeto styles es un objeto en el que los atributos son las clases del archivo scss y los valores de esas claves son las clases que genera Next.js para encapsularlas. Pero puesto que usamos BEM y para ello usamos carácteres como «__» o «–» la manera que vamos a acceder esas claves es con [‘ ‘] para unificar la manera de acceder a ellas.
¡Con esta pull request damos el pistoletazo de salida al frontal de impr3siones! En la próxima entrada empezaremos con la página principal.