No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Curso de React.js

Curso de React.js

Juan David Castro Gallego

Juan David Castro Gallego

Reto: loading skeletons

21/34
Recursos

¿Cómo mejorar la experiencia de carga en tu aplicación con loading skeletons?

Introducir loading skeletons en nuestra aplicación no solo mejora su aspecto visual durante el proceso de carga de datos, sino que también ofrece a los usuarios una mejor experiencia durante esos momentos de espera. Esta técnica es esencial para evitar las incómodas transiciones con pantallas vacías o mensajes de carga sencillos. Exploraremos cómo implementar estos loading skeletons y darles un toque estético y funcional.

¿Qué cambios iniciales debes realizar para comenzar?

Es crucial empezar asignando componentes específicos para diferentes estados de tu aplicación, como error, carga y vacío. Esto no solo organiza mejor tu código, sino que también te permite personalizar la experiencia del usuario según cada escenario.

En el siguiente ejemplo, se crean directorios y archivos índice para diferentes estados:

// Crear los directorios y archivos de índice
todosLoading/index.js
todosError/index.js
emptyTodos/index.js

¿Cómo crear componentes visuales de carga?

La implementación comienza modificando los componentes de carga para que muestren un diseño más atractivo, con la ayuda de CSS y animaciones.

  1. Estructura básica del componente de carga:

    Cambiaremos de un simple texto de carga a una estructura de div y span que permita aplicar estilos:

    function todosLoading() {
        return (
            <div className="loading-todo-container">
                <span className="loading-todo-complete-icon"></span>
                <p className="loading-todo-text"></p>
                <span className="loading-todo-delete-icon"></span>
            </div>
        );
    }
    
  2. Incorporación de estilos y animaciones CSS:

    Aquí es donde se da vida a los loading skeletons. Utilizamos gradientes y animaciones para crear un efecto dinámico:

    .loading-todo-container {
        position: relative;
        display: flex;
        background: linear-gradient(to right, #ddd, #eee, #ddd);
        animation: loading 1.5s infinite;
    }
    
    @keyframes loading {
        0% { background-position: 0% 50%; }
        50% { background-position: 100% 50%; }
        100% { background-position: 0% 50%; }
    }
    

¿Por qué replicar la estructura existente del componente?

Replicar la estructura del componente original de los items (como los íconos de completar y eliminar) en tu diseño de carga, garantiza que la interfaz visual provisional sea coherente con el diseño final. Así construí nuevas clases que emulan estas posiciones y estilos, asegurando homogeneidad entre el estado de carga y el resultado final, usando un border-radius y una paleta de colores adecuada.

¿Qué hacer para manejar varios estados de carga?

En este caso, se agregaron varios componentes de carga a la vista inicial, mostrando múltiples loading skeletons al mismo tiempo. Esta decisión estética crea una anticipación visual sobre el contenido que está por venir:

// En AppUI.js
return (
    <>
        <todosLoading />
        <todosLoading />
        <todosLoading />
    </>
);

¿Por qué es importante cuidar la experiencia del usuario (UX) durante la carga?

Los loading skeletons no solo son agradables a la vista, sino que también ofrecen a los usuarios una experiencia más fluida y menos frustrante al interactuar con una aplicación que está cargando datos. Este enfoque evita dejar a los usuarios con la percepción de error o vacíos inexplicables.

Reto Opcional: Expansion del uso de Loading Skeletons

Intenta implementar loading skeletons para otras partes de la aplicación, como el campo de búsqueda de Todo y el conteo de Todo, para asegurar una experiencia cohesiva durante todo el proceso de carga. Esto puede solucionar inconsistencias, como mostrar "0 de 0 todos completados", mejorando aún más la experiencia general.

Finalmente, recuerda que estas prácticas no solo mejoran la apariencia de tu aplicación, sino que también su usabilidad y percepción de profesionalismo. ¡Explora, experimenta y sigue aprendiendo para hacer tus aplicaciones más increíbles!

Aportes 67

Preguntas 4

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Asi es como va actualmente mi TodoMachine

Aun no he visto los cursos de animaciones pero me puse a buscar mas o menos como funciona cada propiedad que usa el profesor para entender y aplicarlo a mi diseno.
Aplique lo mismo solo que con mis colores y le agregue un borde con un color con muy baja opacidad

Yo añadí una animación de puntitos rebotando

Cumpliendo con el reto, he utilizado material UI para la animación de <TodosLoading/>
(

import  CircularProgress  from "@mui/material/CircularProgress"
import Box from "@mui/material/Box"

function TodosLoading () {
    return (
        <Box sx={{ display: 'flex' }}>
            <CircularProgress />
        </Box>
    )
}

export { TodosLoading}
Este es el resultado de mi propio, Loading Skeleton, me base en un video de Youtube y me siento orgulloso del resultado. ![](https://github.com/CruzHumbeto/RE-todo-ACT/blob/main/imgs/skeleton%20loading%20%E2%80%90%20Hecho%20con%20Clipchamp.gif?raw=true)

Aqui dejo una animacion sencilla con dots que hice para el reto !!!
🤗

Así van los míos ![](https://static.platzi.com/media/user_upload/skeleton-41615655-4afb-4d51-96e5-db8b84c9a40f.jpg)

Asi va quedando

Y esta es otra version

No creo que se vea tan aburrido 😅

**Así solucioné el reto con el TodoCounter 🤗** ```js function TodoCounter({ completed, total, loading }) { return ( loading ? <h1 className='TodoCounter'>Cargando las tareas. : total === completed ? <h1 className='TodoCounter'>Felicidades, completaste todas las tareas 🥳. : <h1 className='TodoCounter'>Has completado {completed} de {total} tareas 👍. ) } ```

Para los que ya saben CSS y quieren seguir avanzando con mas conceptos de react, les dejo el CSS de TodosLoading.js y la estructura del componente

COMPONENTE:

import './TodosLoading.css'

function TodosLoading() {
  return (
    <div className='LoadingTodo-container'>
      <span
      className='LoadingTodo-completeIcon'>
      </span>
      <p className='LoadingTodo-text'></p>
      <span
      className='LoadinTodo-deleteIcon'></span>
    </div>
  );
};

export { TodosLoading };

CSS:

.LoadingTodo-container {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  margin-top: 24px;
  box-shadow: 0px 5px 50px rgba(32, 35 41 0.15);
  border-radius: 10px;
  padding: 12px 0;
}

.LoadingTodo-text {
  margin: 24px 0 24px 24px;
  Width: calc(100% - 120px);
  font-size: 18px;
  line-height: 24px;
  font-weight: 400;
}

.LoadingTodo-completeIcon,
.LoadinTodo-deleteIcon {
  cursor: pointer;
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 50px;
  height: 48px;
  width: 48px;
}

.LoadingTodo-completeIcon {
  position: absolute;
  left: 12px;
}

.LoadinTodo-deleteIcon {
  position: absolute;
  top: -24px;
  right: 0;
}

.LoadingTodo-container,
.LoadingTodo-completeIcon,
.LoadinTodo-deleteIcon {
  background: linear-gradient(90deg, rgba(250, 250, 250, 1), rgb(200, 199, 199));
  background-size: 400% 400%;
  animation: loadingAnimation 3s ease-in-out infinite;
}
  
@keyframes loadingAnimation {
  0% {
    background-position: 0% 50%;
  }
  50% {
    background-position: 100% 50%;
  }
  100% {
    background-position: 0% 50%;
  }
};

Gracias!!!

Buenas, dejo mi aporte sobre el loading skeleton.

.TodoLoading,
  .TodoLoadingCheck,
  .TodosLoadingDelete {
    background: linear-gradient(90deg, rgb(25, 25, 25), rgb(76, 76, 76));
    background-size: 400% 400%;
    animation: skeleton-loading 2s ease-in infinite;
  }
  
  @keyframes skeleton-loading {
    0% {
      background-position: 80% 50%;
    }
    50% {
      background-position: 50% 80%;
    }
    100% {
        background-position: 75% 45%;
      }
  }

css del min 08:40

Vaya que me demore haciendo girar la ruedita

Reutilizando código del curso del **Curso Práctico de Maquetación y Animaciones con CSS **. Les dejo mi proyecto y mi github.

Les comparto mi loading.

Hasta ahora amando React... Así vamos ![](https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExcGl0Mmx3OGFjZ3UwbHZxajl5M3lpN3R3NmF5NzhoamM4MHFsd2pibSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/EluiBLb79nW7Tj3Dlo/giphy.gif) ![]()


TodosLoading.js

import React from 'react';
import './TodosLoading.css';

function TodosLoading() {
  return (
    <div className="loading-wave-container">
      <div className="loading-wave">
        <div className="loading-bar"></div>
        <div className="loading-bar"></div>
        <div className="loading-bar"></div>
        <div className="loading-bar"></div>
      </div>
    </div>
  );
}

export { TodosLoading };

TodosLoading.css

.loading-wave-container {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  margin-top: 50px;
}

.loading-wave {
  width: 300px;
  height: 100px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.loading-bar {
  width: 20px;
  height: 10px;
  margin: 0 5px;
  background-color: #3498db;
  border-radius: 5px;
  animation: loading-wave-animation 1s ease-in-out infinite;
}

.loading-bar:nth-child(2) {
  animation-delay: 0.1s;
}

.loading-bar:nth-child(3) {
  animation-delay: 0.2s;
}

.loading-bar:nth-child(4) {
  animation-delay: 0.3s;
}

@keyframes loading-wave-animation {
  0% {
    height: 10px;
  }

  50% {
    height: 50px;
  }

  100% {
    height: 10px;
  }
}

🟢 Reto completado, construí el loading skeleton con CSS. ![](https://static.platzi.com/media/user_upload/image-f4fd10e1-2b32-4c42-99ac-57a66533119e.jpg) Y estas son las otras vistas para error y vacío. ![](https://static.platzi.com/media/user_upload/image-11094fdb-35f7-4d2a-a39d-0246eada3fd8.jpg) ![](https://static.platzi.com/media/user_upload/image-f271412f-8e84-4f1e-9a3b-bcee256cbc3d.jpg)

Por acá te dejo mi aporte por si tienes dudas de cómo generar la animación con ese efecto brilloso. Te dejo también un enlace para que aprendas a crearlo por tu cuenta:

Skeleton Loading Shine Cards


JSX:

import React from 'react';
import './LoadingTodos.scss';

function LoadingTodos() {
    return (
        <div className="loading-box">
            <div className="loading-animation"></div>
        </div>
    )
}

export { LoadingTodos }

CSS

//Estilos del contenedor de mis todos
.loading-box {
  width: 30rem;
  height: 4rem;
  margin: 1rem 0;
  border: none;
  background-color: #ccc;
  border-radius: 0.7rem;
  position: relative;
  overflow: hidden;
}

//Estilos del contenedor de animación
.loading-box {
  width: 30rem;
  height: 4rem;
  margin: 1rem 0;
  border: transparent;
  border-radius: 0.7rem;
  background-color: #e2e5e7;
  position: relative;
}

.loading-animation {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-image: linear-gradient(
    90deg,
    rgba(255, 255, 255, 0),
    rgba(255, 255, 255, 0.5),
    rgba(255, 255, 255, 0)
  );
  background-size: 40px 100%;
  background-repeat: no-repeat;
  background-position: left -40px top 0;
  animation: shine 1s ease infinite;
  border-radius: 0.7rem;
}

@keyframes shine {
  to {
    background-position: right -40px top 0;
  }
}

Esta es mi implementación, aún no he visto los cursos de CSS avanzado ni de animaciones, no soy buen diseñador, pero esta es mi respuesta al reto:

El primer elemento, es el skeleton, lo dejé para ver lo que se veía, en comparación con la lista de ToDOs, pero serían igual que lo hizo JuanDC tres elementos, y la barra de cargando información se va cargando. Se hizo con CSS:

TodoLoading.js

import React from 'react';
import './TodosLoading.css';

function TodosLoading() {
  return (
    <>
      <li className={`TodoItem-loading cat-0`}>
        
        <p className={`TodoItem-p-loading`}>
        <span className="loader-1"></span>
        </p>
      </li>
    </>
  );
}

export {TodosLoading};

y TodoLoading.css

.TodoItem-loading{
  list-style-type: none;
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 90%;
  margin: 10px auto;
  padding: 10px;
  /* border: 1px solid darkgray; */
  box-shadow: 0px 1px 4px 0 LightBlue;
  border-radius: 10px;
  
  background: linear-gradient(90deg, rgba(250,250,250,1), rgb(200, 199, 199));
  background-size: 400% 400%;
  animation: loadingAnimation 3s ease-in-out infinite;
}

@keyframes loadingAnimation {
  0% {background-position: 0% 50%;}
  50% {background-position: 100% 50%;}
  100% {background-position: 0% 50%;}
}

.TodoItem-p-loading {
  width: 100%;
  text-align: center;
}

.cat-0 {
  border-left: 10px solid gray;
}

.loader-1{
  color: gray;
  display: inline-block;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 20px;
  line-height: 16px;
  font-weight: 400;
  position: relative;
}
.loader-1:after{
  content: 'Cargando tu información... ';
  position: relative;
  z-index: 5;
  vertical-align:super;
}
.loader-1:before{
  content: '';
  height: 6px;
  border: 1px solid;
  border-radius: 10px;
  width: 100%;
  position: absolute;
  bottom: 0px;
  background: linear-gradient(#FF3D00 100%, transparent 0) no-repeat;
  background-size: 0% auto;
  animation: 10s lineGrow linear infinite;
}

@keyframes lineGrow {to {  background-size: 100% auto}}

Use la fuente Flow circular
Para hacer que el texto se ve con border radius

Si colocas un de total

console.log(total);

en el componente AppUI, verán que se sigue renderizando ese componente de manera infinita.
Alguna idea de como arreglarlo ?

Mi solucion:

  • Crear 3 contenedores esquematicos con las mismas medidas de los que se cargaran.
  • En CSS ponerle con un before un background degradado.
  • Mediante una animacion CSS tranladar ese grandiente para hacer la animacion

RETO TodoCounter

import React from "react";
import "./TodoCounter.css";

function TodoCounter({ total, completed }) {
  let message;

  if (total === 0) {
    message = "No hay tareas pendientes.";
  } else if (total === completed) {
    message = "¡Felicidades, has completado todos los TODOs!";
  } else {
    message = `Has completado ${completed} de ${total} TODOs`;
  }

  return <h1 className="TodoCounter">{message}</h1>;
}

export { TodoCounter };

RETO.

Componente:

import React from 'react';
import './TodosLoading.css';

function TodosLoading() {
  return (

      <div className="loadingProcess"></div>

  );
}

export { TodosLoading };

CSS:

.loadingProcess {
  position: fixed;
  top: 20px;
  left: 0;
  width: 100vw;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}

.loadingProcess::after {
  content: "";
  width: 105px;
  height: 105px;
  border: 15px solid #f3f3f3;
  border-top: 15px solid #72A9F2;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}


@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}  

Creo que me falta aun mejorar. No es si deba quitar la palabra loading y poner un grafico de carga mas intuitivo para el usuario.

Logré hacerle un efecto de onda con bing chat

Yo use TailwindCSS con Flowbite. En su libreria de componentes hay unos spinners muy sencillos y chulos.

https://flowbite.com/docs/components/spinner/

Me sentí como un niño en una juguetería JAJAJA… fue mucha la curiosidad que me dio al estilizar el loader y probar con los diferentes estilos de CSS, falta por mejorar miles y miles de cosas… No paremos de aprender.

Asi quedo mi pantalla de carga, con una animacion en el titulo y la lista de todo's ![](https://static.platzi.com/media/user_upload/Screenshot%202023-11-25%20at%2022-45-32%20React%20App-736bfdf4-4dbd-44a8-8e97-40a24fbd935a.jpg)
![](https://static.platzi.com/media/user_upload/image-98a3afb9-9fbc-4cc2-8bd9-fa5b26bcd01d.jpg) Así va mi todo app, logre hacer este loading tan bonito gracias al comentario de un compañero en el que nos comparte esta pagina <https://uiverse.io/> tan chevere para sacar loaders !!!
Hola! quiero compartir con ustedes un proyecto propio de un restaurante realizado a partir de este curso... todas las observaciones son bienvenidas gracias link deploy <https://alejog1996.github.io/Dtravesia_menuPage/> link repositorio <https://github.com/AlejoG1996/Dtravesia_menuPage>
![](https://static.platzi.com/media/user_upload/image-03fd4306-20f6-490e-9524-589bb248c4ae.jpg)
![](https://static.platzi.com/media/user_upload/Screenshot%202025-02-20%20at%2012.21.28p.m.-ca1fc77c-1502-4351-9374-d89d7953d75c.jpg)
Vamos bien ![](https://static.platzi.com/media/user_upload/image-361ef589-5bbd-4463-90fe-d4515c0bbeaf.jpg)
Yo hice mi loading skeleton con MUI: ![](https://static.platzi.com/media/user_upload/Screenshot%202025-01-18%20at%204.58.31p.m.-9bab3049-1e05-423f-944f-dafb2f94bb96.jpg) Y el reto del TodoCounter: ![](https://static.platzi.com/media/user_upload/Screenshot%202025-01-18%20at%205.00.39p.m.-c6774e05-7690-4c97-9f62-4bdfe6f44f57.jpg)
Mi solución con Skeleton ```js import './TodoLoading.css'; import Skeleton from 'react-loading-skeleton' import 'react-loading-skeleton/dist/skeleton.css'; function TodoLoading({total}){ return ( Array(total).fill(0).map((item) =>
  • <Skeleton circle width={40} className={`TodoSkeleton-icon-container`}/>
    <Skeleton circle width={40} baseColor='#CBCBCB' className={`TodoSkeleton-icon-container TodoSkeleton-deleteIcon`}/>
  • ) ); } export { TodoLoading } ```import './TodoLoading.css';import Skeleton from 'react-loading-skeleton'import 'react-loading-skeleton/dist/skeleton.css'; function TodoLoading({total}){ return ( Array(total).fill(0).map((item) => \
  • \
    \<Skeleton circle width={40} className={`TodoSkeleton-icon-container`}/> \
    \
    \<Skeleton circle width={40} baseColor='#CBCBCB' className={`TodoSkeleton-icon-container TodoSkeleton-deleteIcon`}/> \
    \
  • ) ); } export { TodoLoading }
    Así va mi proyecto :D ![]()![](https://i.postimg.cc/yxcfV7ks/React-Project.gif) También les recomiendo estos blogs para saber más sobre loading skeletons: * <https://www.freecodecamp.org/news/how-to-build-skeleton-screens-using-css-for-better-user-experience/> * <https://flowbite.com/docs/components/skeleton/> * ![]()https://www.smashingmagazine.com/2020/04/skeleton-screens-react/
    ![](https://cdn.discordapp.com/attachments/1109505527207174214/1161454391245688893/Untitled_design.gif?ex=65385bb1\&is=6525e6b1\&hm=734a346bdb84047652d7d5da8a5d0345e82372bfa547ad426683196a39972093&)Creo que esto no tiene nada que ver con loading skeletons pero es la única forma que se me ocurrió que iba con mi "diseño" xd ```js import "./TodoLoading.css"; import pen from "./pen.png" function TodoLoading({ status }) { if (status === "Loading") return (
    ); } export { TodoLoading }; ``````css .pensil-Img-Container { position: absolute; top: 18px; animation: zigzagHorizontal 3s linear infinite; } .pensil-Img { width: 10%; height: auto; margin: 0; } @keyframes zigzagHorizontal { 0% { transform: translateX(0) translateY(0); } 8% { transform: translateX(20px) translateY(-10px); } 16% { transform: translateX(40px) translateY(0); } 24% { transform: translateX(60px) translateY(-10px); } 32% { transform: translateX(80px) translateY(0); } 40% { transform: translateX(100px) translateY(-10px); } 48% { transform: translateX(120px) translateY(0); } 56% { transform: translateX(140px) translateY(-10px); } 64% { transform: translateX(160px) translateY(0); } 72% { transform: translateX(180px) translateY(-10px); } 80% { transform: translateX(200px) translateY(0); } 88% { transform: translateX(220px) translateY(-10px); } 100% { transform: translateX(240px) translateY(0); } } ```

    mi solucion al reto

    Le pedi a chatGPT, que me hiciera la pagina con taildwind y react, cuando estuviera cargando:
    Esta es su respuesta, a mi me gusto

    import React from 'react';
    
    const LoadingPage = () => {
      return (
        <div className="min-h-screen flex items-center justify-center bg-gray-900 text-white">
          <div className="animate-pulse">
            <div className="w-20 h-20 rounded-full bg-blue-500"></div>
            <div className="mt-4 flex justify-center space-x-2">
              <div className="w-4 h-4 rounded-full bg-blue-500"></div>
              <div className="w-4 h-4 rounded-full bg-blue-500"></div>
              <div className="w-4 h-4 rounded-full bg-blue-500"></div>
            </div>
          </div>
        </div>
      );
    };
    
    export default LoadingPage;
    
    

    Aqui les dejo mi metodo, quise hacerlo de esta forma para evitar poner tanto codigo en AppUI.jsx y pues creo que a la hora de hacer responsive los diseños o proyectos con mas contenido no aplicar tres si no numero mayor de skeletons (por llamarlos de alguna forma) aunque me fuese gustado aplicar una logica en la que colocando una etiqueta <li> pueda renderizar N canidades de veces para llenar todo los espacios necesarios tal cual lo hace Youtube a la hora de cargar…

    Mi solución la hice así:

    Estoy utilizando Sass en mi caso porque se me hace mas facil hacer CSS

    TodosLoading.js

    En este solamente cree un span y lo multiplique en varios al hacer return

    import React from "react";
    
    function TodosLoading() {
      const TodoLoading = () =>
       <span className="todosLoading"></span>
        return (
          <>
          <TodoLoading />
          <TodoLoading />
          <TodoLoading />
          <TodoLoading />
          <TodoLoading />
          </>
        )
      }
    
    export { TodosLoading };
      
    

    CSS o SASS

    En mi caso estoy utilizando Sass y al archivo donde puse el skeleton decidí llamar TodosLoading.scss y esta compuesto de esta manera el cual va a mostrar una bonita animacion de carga que va de arriba y hacia abajo apareciendo y desapareciendo los elementos

    @keyframes loading-skeleton {
        0%, 100% {
          opacity: 100%;
        }
        50% {
          opacity: 0%;
        }
    }
    
    .todosLoading {
        height: 60px;
        width: auto;
        background: $todoLoading;
        border-radius: 10px;
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 20px;
        padding: 2px 10px 2px 10px;
        filter: drop-shadow(0px 4px 4px rgba(0, 0, 0, 0.25));
        animation: loading-skeleton infinite 1.5s;
    
        &:nth-child(2) {
            animation-delay: .2s;
        }
    
        &:nth-child(3) {
            animation-delay: .4s;
        }
    
        &:nth-child(4) {
            animation-delay: .2s;
        }
    
        &:nth-child(5) {
            animation-delay: .4s;
        }
    

    Yo lo hice de la siguiente manera que me parecio que es mucho mas facil

    Codigo para la parte de TodosLoading.js
    
    import React from "react";
    import '../styles/TodosLoading.css'
    import 'bootstrap/dist/css/bootstrap.min.css';
    import {Spinner} from 'reactstrap';
    function TodosLoading(){
        return(
            <div className="container-loading">
                <div className="loading">
                <Spinner color= "primary" />
                </div>
            </div>
        );
    }
    
    export {TodosLoading}; 
    
    

    antes de ejecutarlo recuerden que hay que instalar las dependencias que se hace con el siguiente comando

    npm i bootstrap reactstrap
    
    código para la parte de css 
    
    .container-loading {
        height: 100vh;
        position: relative;
    }
    
    .loading {
        margin: 0;
        position: absolute;
        top: 50%;
        left: 50%;
        -ms-transform: translate(-50%, -50%);
        transform: translate(-50%, -50%);
    }
    

    hay ya el loading quedaría centralizado y para mi se vería mucho mas chimbita jejej 😎

    pda: No agrego imágenes porque no se como carajos ponerlas (Si alguien sabe que me explique por favor 😢)

    Yo estoy utilizando MUI, así que implementé el componente Skeleton.

    export const TodoLoading = () => {
      return (
        <Box>
          <Skeleton variant='text' width={350} height={40}  />
          <Skeleton variant='text' width={350} height={40}  />
          <Skeleton variant='text' width={350} height={40}  />
          <Skeleton variant='text' width={350} height={40}  />
        </Box>
       
      )
    }
    
    

    Skeleton

    Aqui dejo mi solucion al TodosLoading, he instalado Chakra UI y Framer-Motion para crearlo:

    import { Box, Spinner } from '@chakra-ui/react'
    
    function ToDosLoading() {
        return (
            <Box className='w-16 h-16 mb-12' >
                <Spinner
                    thickness='4px'
                    speed='0.65s'
                    color='#000000'
                    emptyColor='#707070'
                    height={'100%'}
                    width={'100%'}
                />
            </Box>
        )
    }
    
    export default ToDosLoading```
    
    en mi aplicacion utilice 2 div y con esitlos css una simple barra de carga
    En mi caso, como no sabia crear animaciones en css, le pedi a chatgpt que me ayude, y aprender porque y para que es cada cosa. Al final ya que un circulito de carga era basico, use unas listas con gradientes animados vacia. Para error, fui a lo sencillo y puse un gif de un gato con un error, y para first todo, igualmente, un liindo gatito.
    ## ✨🦄Mi skelenton para los Todos me quedó así :3 ![](https://static.platzi.com/media/user_upload/localhost_3000_-df2b3ba9-6c61-44d1-9fac-456dc4a70bc9.jpg)
    Comparto lo que hice: Loading: ![](https://static.platzi.com/media/user_upload/image-4cb54ee1-4b9a-452f-b2c9-0d7ed2628004.jpg) Error: ![](https://static.platzi.com/media/user_upload/image-bb8acced-eeba-4f9a-bf51-b1fce2f67320.jpg) No hay tareas: ![](https://static.platzi.com/media/user_upload/image-788767a6-9317-4e0a-b28c-5e5e7eed8150.jpg)
    ```txt ```![](https://static.platzi.com/media/user_upload/image-75e1bedb-e9ff-434d-bebc-c7147a34dbf5.jpg)
    Pésima clase profe Juan, no se puede saltar y crear archivos como los TodosLoading.css sin mostrarlo, le repito no porque usted ya tenga conocimiento de como se hacen las cosas crea que sus estudiantes también lo tienen, se supone son clases para mostrar y aprender no de cosas por hecho
    este fue mi resultado. use ayuda de una pagina que encontré googleando : <https://loading.io/css/> en dicha pagina habían excelentes opciones para un loading este fue el resultado.![](https://static.platzi.com/media/user_upload/image-797a55b2-7b3e-4446-ae5e-d5fdb22f7242.jpg)
    Yo hice la animación ligeramente diferente. ```css .LoadingTodo-container, .LoadingTodo-completeIcon, .LoadingTodo-deleteIcon { background: linear-gradient(0.25turn, transparent, #FFF, transparent), linear-gradient(#DDD, #DDD), radial-gradient(38px circle at 19px 19px, #DDD 50%, transparent 51%), linear-gradient(#DDD, #DDD); background-size: 400% 400%; animation: loadingAnimation 3s ease-in-out infinite; } @keyframes loadingAnimation { 0% { background-position: 0% 0, 0 0, 70px 5px, 70px 38px, 0px 66px; } 100% { background-position: 150% 0, 0 0, 70px 5px, 70px 38px, 0px 66px; } } ```
    Reto de TodoCounter ```js import React from "react"; import "./TodoCounter.css"; function TodoCounter({ total, completed }) { let message; const messageSpan = <>Has completado {completed} de {total} TODOs if (total === 0) { message = "No hay tareas pendientes."; } else if (total === completed) { message = "🎉¡Felicidades, completaste todos los TODOs!🎉"; } else { message = messageSpan; } return <h1 className="TodoCounter">{message}; } export { TodoCounter }; ```import React from "react";import "./TodoCounter.css"; function TodoCounter({ total, completed }) {    let message;    const messageSpan = <>Has completado \{completed}\ de \{total}\ TODOs\     if (total === 0) {        message = "No hay tareas pendientes.";    } else if (total === completed) {        message = "🎉¡Felicidades, completaste todos los TODOs!🎉";    } else {        message = messageSpan;    } return \<h1 className="TodoCounter">{message}\;} export { TodoCounter };

    De esta forma va mi estado de carga en mi todo App

    Así quedo el mío, lo saqué de \[uiverse.io]\(https://uiverse.io/vk-uiux/neat-goat-26) 👀 : ![](https://i.postimg.cc/vB5NFh17/demo-loading-todo-app.gif) ```js import '../../assets/App.css' const TodosLoading = () => { return (
    ) } export { TodosLoading } ``````css .todo__item--loading { display: flex; align-items: baseline; gap: 8px; padding: 10px 0; border-bottom: 0.1rem solid lightgray; } .todo__item--loading { height: 40px; margin-bottom: 3px; background-image: linear-gradient( 90deg, #ccc 0px, rgb(229 229 229 / 90%) 40px, #ccc 80px ); background-size: 300%; background-position: 100% 0; border-radius: 5px; animation: shimmer 1.6s infinite; } @keyframes shimmer { to { background-position: -100% 0; } } ```
    ![](https://static.platzi.com/media/user_upload/image-f084abbe-7b06-4269-8f60-719330010233.jpg) Este es mi componente de loading, las barras cambian de tamaño de manera secuencial
    Hola, dejo mi aporte de Skeleton -> Todos tienen movimiento, saludos. cargando: ![](https://static.platzi.com/media/user_upload/imagen-33b730fc-f21b-49e6-abea-dcf37a3a7db6.jpg) cargado OK: ![](https://static.platzi.com/media/user_upload/imagen-6bb63678-706c-4786-9cd4-40685e68206f.jpg) error de localStore (gira el astronauta): ![](https://static.platzi.com/media/user_upload/imagen-39e94c4a-e509-49b0-99a5-de0d8b05f121.jpg) sin TODOS: ![](https://static.platzi.com/media/user_upload/imagen-0384e733-d847-423d-bb1d-02cba38d8b2f.jpg) Muchas gracias, quedo abierto a opiniones y sugerencias.

    [](C:\Users\User\Pictures\Screenshots\Captura de pantalla 2023-10-24 084951.png)

    import React from 'react';
    import { Bars  } from 'react-loader-spinner';
    
    import './TodosLoanding.css';
    
    function TodosLoading() {
      return (
        <div className="loader-container">
          <Bars 
            color="#00BFFF"
            height={100}
            width={100}
            timeout={3000}
          />
          <p>Cargando...</p>
        </div>
      );
    }
    
    export { TodosLoading };
    
    
    .loader-container {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        height: 50vh;
      }
      
      .loader-container p {
        margin-top: 0px;
      }
      
    
    Yo utilice está herramienta [react-loading-skeleton - npm (npmjs.com)](https://www.npmjs.com/package/react-loading-skeleton)
    buenos días, necesito comparar mi código con lo que estamos viendo en clase, pero con la actualización los "recursos" están vacíos