Leave Yamada UI a star

Star
Yamada UIYamada UIv1.3.9

Loading

Yamada UI supports the loading animations needed in applications.

Usage

To display loading, use useLoading. useLoading returns instances of screen, page, background, and custom. These instances include several methods.

  • isLoading: Retrieves whether it is in the loading animation.
  • start: Starts the loading animation.
  • update: Updates the information of the loading animation.
  • finish: Ends the loading animation.

Editable example

const { screen, page, background } = useLoading()

const onLoadingScreen = async () => {
  try {
    screen.start()

    await wait(5000)
  } finally {
    screen.finish()
  }
}

const onLoadingPage = async () => {
  try {
    page.start()

    await wait(5000)
  } finally {
    page.finish()
  }
}

const onLoadingBackground = async () => {
  try {
    background.start()

    await wait(5000)
  } finally {
    background.finish()
  }
}

return (
  <Wrap gap="md">
    <Button onClick={onLoadingScreen}>Start screen loading</Button>
    <Button onClick={onLoadingPage}>Start page loading</Button>
    <Button onClick={onLoadingBackground}>Start background loading</Button>
  </Wrap>
)

Customizing Loading

By passing options to the method, you can customize loading.

Adding a Timeout

In cases such as communication, it is necessary to add a timeout. In that case, use duration.

Editable example

const { screen, page, background } = useLoading()

return (
  <Wrap gap="md">
    <Button onClick={() => screen.start({ duration: 5000 })}>
      Start screen loading
    </Button>
    <Button onClick={() => page.start({ duration: 5000 })}>
      Start page loading
    </Button>
    <Button onClick={() => background.start({ duration: 5000 })}>
      Start background loading
    </Button>
  </Wrap>
)

Adding a Message

To add a message to the loading, use message.

Editable example

const { screen, page, background } = useLoading()

return (
  <Wrap gap="md">
    <Button
      onClick={() => screen.start({ message: "Loading", duration: 5000 })}
    >
      Start screen loading
    </Button>
    <Button onClick={() => page.start({ message: "Loading", duration: 5000 })}>
      Start page loading
    </Button>
    <Button
      onClick={() => background.start({ message: "Loading", duration: 5000 })}
    >
      Start background loading
    </Button>
  </Wrap>
)

You can pass a JSX element to message.

Editable example

const { screen, page, background } = useLoading()

return (
  <Wrap gap="md">
    <Button
      onClick={() =>
        screen.start({
          message: <Text color="primary">Loading</Text>,
          duration: 5000,
        })
      }
    >
      Start screen loading
    </Button>
    <Button
      onClick={() =>
        page.start({
          message: <Text color="primary">Loading</Text>,
          duration: 5000,
        })
      }
    >
      Start page loading
    </Button>
    <Button
      onClick={() =>
        background.start({
          message: <Text color="primary">Loading</Text>,
          duration: 5000,
        })
      }
    >
      Start background loading
    </Button>
  </Wrap>
)

Update the Message

To update the message, pass options to the update method.

Editable example

const { screen, page, background } = useLoading()

const onLoadingScreen = async () => {
  try {
    screen.start({ message: "Loading" })

    await wait(3000)

    screen.update({ message: "Please wait" })

    await wait(3000)
  } finally {
    screen.finish()
  }
}

const onLoadingPage = async () => {
  try {
    page.start({ message: "Loading" })

    await wait(3000)

    page.update({ message: "Please wait" })

    await wait(3000)
  } finally {
    page.finish()
  }
}

const onLoadingBackground = async () => {
  try {
    background.start({ message: "Loading" })

    await wait(3000)

    background.update({ message: "Please wait" })

    await wait(3000)
  } finally {
    background.finish()
  }
}

return (
  <Wrap gap="md">
    <Button onClick={onLoadingScreen}>Start screen loading</Button>
    <Button onClick={onLoadingPage}>Start page loading</Button>
    <Button onClick={onLoadingBackground}>Start background loading</Button>
  </Wrap>
)

Customize from Config

If you want to set the loading settings for the entire application, customize the config.

For example, if you want to change the loading icon for the entire application, pass an option to loading.

Editable example

const customConfig = extendConfig({
  loading: {
    screen: {
      icon: {
        variant: "grid",
      },
    },
    page: {
      icon: {
        variant: "grid",
      },
    },
    background: {
      icon: {
        variant: "grid",
      },
    },
  },
})

function App() {
  const { screen, page, background } = useLoading()

  return (
    <Wrap gap="md">
      <Button onClick={() => screen.start({ duration: 5000 })}>
        Start screen loading
      </Button>
      <Button onClick={() => page.start({ duration: 5000 })}>
        Start page loading
      </Button>
      <Button onClick={() => background.start({ duration: 5000 })}>
        Start background loading
      </Button>
    </Wrap>
  )
}

return (
  <UIProvider config={customConfig}>
    <App />
  </UIProvider>
)

Using initialState

By using initialState, a loading display will be shown when the application is loaded.

This is suitable for communication during loading (such as obtaining user information).

import { UIProvider, extendConfig } from "@yamada-ui/react"
const customConfig = extendConfig({
loading: {
screen: {
initialState: true,
},
},
})
const App = () => {
return (
<UIProvider config={customConfig}>
<YourApplication />
</UIProvider>
)
}

Using Custom Components

Depending on the scenario, you may need to implement a loading animation that fits your project.

In that case, you can utilize custom.

Editable example

const customConfig = extendConfig({
  loading: {
    custom: {
      component: ({ initialState, message, duration, onFinish }) => {
        useTimeout(onFinish, duration)

        return (
          <Motion
            initial={!initialState ? "initial" : false}
            animate="animate"
            exit="exit"
            variants={{
              initial: {
                opacity: 0,
              },
              animate: {
                opacity: 1,
                transition: {
                  duration: 0.4,
                  ease: [0.4, 0, 0.2, 1],
                },
              },
              exit: {
                opacity: 0,
                transition: {
                  duration: 0.4,
                  ease: [0.4, 0, 1, 1],
                },
              },
            }}
            sx={{
              position: "fixed",
              top: 0,
              right: 0,
              bottom: 0,
              left: 0,
              zIndex: 9999,
              bg: "blackAlpha.600",
              w: "100vw",
              h: "100vh",
              p: "md",
              display: "flex",
              justifyContent: "center",
              alignItems: "center",
            }}
          >
            <Motion
              initial={!initialState ? "initial" : false}
              animate="animate"
              exit="exit"
              variants={{
                initial: {
                  opacity: 0,
                  scale: 0.95,
                },
                animate: {
                  opacity: 1,
                  scale: 1,
                  transition: {
                    duration: 0.4,
                    ease: [0.4, 0, 0.2, 1],
                  },
                },
                exit: {
                  opacity: 0,
                  scale: 0.95,
                  transition: {
                    duration: 0.4,
                    ease: [0.4, 0, 1, 1],
                  },
                },
              }}
              sx={{
                bg: ["white", "black"],
                maxW: "md",
                p: "md",
                display: "flex",
                flexDirection: "column",
                justifyContent: "center",
                alignItems: "center",
                gap: "sm",
                rounded: "md",
                boxShadow: ["lg", "dark-lg"],
              }}
            >
              <Loading variant="dots" size="6xl" />

              <VStack align="center" mb="md" gap="sm">
                <Text>Downloading files…</Text>
                {message ? (
                  isValidElement(message) ? (
                    message
                  ) : (
                    <Text lineClamp={3}>{message}</Text>
                  )
                ) : null}
              </VStack>

              <Button size="sm" onClick={onFinish}>
                Play to background
              </Button>
            </Motion>
          </Motion>
        )
      },
    },
  },
})

function App() {
  const { custom } = useLoading()

  return (
    <Button onClick={() => custom.start({ duration: 5000 })}>
      Start custom loading
    </Button>
  )
}

return (
  <UIProvider config={customConfig}>
    <App />
  </UIProvider>
)

Edit this page on GitHub

PreviousText and Layer StylesNextNotification