Code Monkey home page Code Monkey logo

react-loading-skeleton's Introduction

Logo

React Loading Skeleton

Make beautiful, animated loading skeletons that automatically adapt to your app.

Gif of the skeleton in action

Learn about the changes in version 3, or view the v2 documentation.

Basic Usage

Install via one of:

yarn add react-loading-skeleton
npm install react-loading-skeleton
import Skeleton from 'react-loading-skeleton'
import 'react-loading-skeleton/dist/skeleton.css'

<Skeleton /> // Simple, single-line loading skeleton
<Skeleton count={5} /> // Five-line loading skeleton

Principles

Adapts to the styles you have defined

The Skeleton component should be used directly in your components in place of content that is loading. While other libraries require you to meticulously craft a skeleton screen that matches the font size, line height, and margins of your content, the Skeleton component is automatically sized to the correct dimensions.

For example:

function BlogPost(props) {
  return (
    <div>
      <h1>{props.title || <Skeleton />}</h1>
      {props.body || <Skeleton count={10} />}
    </div>
  );
}

...will produce correctly-sized skeletons for the heading and body without any further configuration.

This ensures the loading state remains up-to-date with any changes to your layout or typography.

Don't make dedicated skeleton screens

Instead, make components with built-in skeleton states.

This approach is beneficial because:

  1. It keeps styles in sync.
  2. Components should represent all possible states — loading included.
  3. It allows for more flexible loading patterns. In the blog post example above, it's possible to have the title load before the body, while having both pieces of content show loading skeletons at the right time.

Theming

Customize individual skeletons with props, or render a SkeletonTheme to style all skeletons below it in the React hierarchy:

import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';

return (
  <SkeletonTheme baseColor="#202020" highlightColor="#444">
    <p>
      <Skeleton count={3} />
    </p>
  </SkeletonTheme>
);

Props Reference

Skeleton only

Prop Description Default
count?: number The number of lines of skeletons to render. If count is a decimal number like 3.5, three full skeletons and one half-width skeleton will be rendered. 1
wrapper?: React.FunctionComponent
<PropsWithChildren<unknown>>
A custom wrapper component that goes around the individual skeleton elements.
circle?: boolean Makes the skeleton circular by setting border-radius to 50%. false
className?: string A custom class name for the individual skeleton elements which is used alongside the default class, react-loading-skeleton.
containerClassName?: string A custom class name for the <span> that wraps the individual skeleton elements.
containerTestId?: string A string that is added to the container element as a data-testid attribute. Use it with screen.getByTestId('...') from React Testing Library.
style?: React.CSSProperties This is an escape hatch for advanced use cases and is not the preferred way to style the skeleton. Props (e.g. width, borderRadius) take priority over this style object.

Skeleton and SkeletonTheme

Prop Description Default
baseColor?: string The background color of the skeleton. #ebebeb
highlightColor?: string The highlight color in the skeleton animation. #f5f5f5
width?: string | number The width of the skeleton. 100%
height?: string | number The height of each skeleton line. The font size
borderRadius?: string | number The border radius of the skeleton. 0.25rem
inline?: boolean By default, a <br /> is inserted after each skeleton so that each skeleton gets its own line. When inline is true, no line breaks are inserted. false
duration?: number The length of the animation in seconds. 1.5
direction?: 'ltr' | 'rtl' The direction of the animation, either left-to-right or right-to-left. 'ltr'
enableAnimation?: boolean Whether the animation should play. The skeleton will be a solid color when this is false. You could use this prop to stop the animation if an error occurs. true

Examples

Custom Wrapper

There are two ways to wrap a skeleton in a container:

function Box({ children }: PropsWithChildren<unknown>) {
  return (
    <div
      style={{
        border: '1px solid #ccc',
        display: 'block',
        lineHeight: 2,
        padding: '1rem',
        marginBottom: '0.5rem',
        width: 100,
      }}
    >
      {children}
    </div>
  );
}

// Method 1: Use the wrapper prop
const wrapped1 = <Skeleton wrapper={Box} count={5} />;

// Method 2: Do it "the normal way"
const wrapped2 = (
  <Box>
    <Skeleton />
  </Box>
);

Troubleshooting

The skeleton width is 0 when the parent has display: flex!

In the example below, the width of the skeleton will be 0:

<div style={{ display: 'flex' }}>
  <Skeleton />
</div>

This happens because the skeleton has no intrinsic width. You can fix it by applying flex: 1 to the skeleton container via the containerClassName prop.

For example, if you are using Tailwind, your code would look like this:

<div style={{ display: 'flex' }}>
  <Skeleton containerClassName="flex-1" />
</div>

The height of my container is off by a few pixels!

In the example below, the height of the <div> will be slightly larger than 30 even though the react-loading-skeleton element is exactly 30px.

<div>
  <Skeleton height={30} />
</div>

This is a consequence of how line-height works in CSS. If you need the <div> to be exactly 30px tall, set its line-height to 1. See here for more details.

Contributing

Contributions are welcome! See CONTRIBUTING.md to get started.

Acknowledgements

Our logo is based off an image from Font Awesome. Thanks!

react-loading-skeleton's People

Contributors

aboodz avatar ag-systems avatar cravend avatar dependabot[bot] avatar dvtng avatar elliottsj avatar erhathaway avatar hoffination avatar icedmonk avatar immunity20 avatar jonmajorc avatar kwangminini avatar larsmunkholm avatar mariuszkogut avatar mattrothenberg avatar rosemagura avatar royneau-jt avatar srmagura avatar ssi02014 avatar tauantcamargo avatar zignis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-loading-skeleton's Issues

<span> wrapper is affected by line-height

When rendering in a container with custom line-height, the ´´ is affected by it and results in a pretty ugly offset:

Offset when using line-height

I suggest adding a line-height: 1 to the wrapper.

span englobing tag is causing DOM validation issues

I'm using the Skeleton component inside a table to show that the rows are loading.

I'm getting DOM validation warnings, because the Skeleton component contains a <span> at the root. Specifically, the <span> cannot appear as a child of a <tbody>. I've tried using the wrapper props, to include the skeletons inside a <tr>, but the englobing span is still causing issues.

Could this be replaced with something else ? A fragment, or a div ? Is it absolutely necessary to use a span ?

Circulair option

Loving this library.
It's easy and working like a charm.

But i'm missing shapes or images that could be occur in a skeleton.
1_5goezexrmdfe71z8yz01fa

Skeleton Mask Function (New Feature)

What are your thoughts on adding a function like the following (this is a quick example) as part of the package? My idea is to show the data when it's available and <Skeleton /> otherwise.

function skeletonMask(data, options = {}){
  const {
    skeleton = <Skeleton />,
    view = data
  } = options;
  return !data ? skeleton : view;
}

Example Usage:

const View = ({ id, title, completed }) => (
  <div>
    <div>{skeletonMask(completed)}</div>
    <div>{skeletonMask(id, { skeleton: <Skeleton height={50} />})}</div>
    <div>{skeletonMask(title, { view: `Title: ${title}`})}</div>
  </div>
);

Radius props?

Do we have any radius prop for this? I want to set the Skeleton for a button with a curved edges

Add live demo

This package is awesome, but not have a live demo page :|

Today, any React Package need a demo page, use some React Lib, like React Live

Or deploy a simple HTML and Css page, like there: https://lakscastro.github.io/menu-hamburger

The most important is show your lib working

Thank you, and I hope it takes into account the suggestion :)

Really Need Support For Typescript Integration

Really Need Support For Typescript Integration!
I'm going to make a scalable ReactJS App using Typescript, and I'm so dissapointed because this beautiful library has not supported typescript yet. Please add support to this to make your library more awesome.
After some research at the NPM market, there is no skeleton library supportting typescript. So, chances are you will make a difference.
Really appreciate it if you could help!

Export SkeletonProps and SkeletonThemeProps interfaces

My team is using this library in a TypeScript project. We've build a wrapper component around a Skeleton component because our wrapper components supports some additional props.

However, we also support all of the props mentioned in the SkeletonProps interface so we want to extend this interface. This isn't possible because the SkeletonProps and SkeletonThemeProps` aren't exported.

Replace emotion as a dependency?

I found it a bit of a pain setting up react-loading-skeleton with Storybook. Especially considering emotion isn't the default styling method I'm using within my project. Perhaps the library would be a bit more light weight if we swapped it out with a more default css solution.

Adding margin props?

Any thoughts on adding margin props? It would be helpful for fixing issues like this

screenshot 2018-09-18 09 13 11

screenshot 2018-09-18 09 13 54

TypeError: (0 , u.keyframes) is not a function

when I import the module
I get this error TypeError: (0 , u.keyframes) is not a function

eval
node_modules/babel-loader/lib/index.js??ref--6-oneOf-2!/Users/yotav/Desktop/500tech/projects/simplifi/client/node_modules/react-loading-skeleton/dist/bundle.js:89
  86 | 
  87 | var f = t.defaultBaseColor = "#eee",
  88 |     d = t.defaultHighlightColor = "#f5f5f5",
> 89 |     h = t.skeletonKeyframes = (0, u.keyframes)(i),
     | ^  90 |     p = t.skeletonClass = (0, u.css)(o, f, f, d, f),
  91 |     b = function (e) {
  92 |   function t() {
View compiled

ps. I think the error is because a conflict between emotion to style-component

Edge Support

Does not animate on Edge

I tried Chrome and Firefox, and iOS Safari. Works.

Emotion 9 and 10 are incompatible on the same screen

Ran into a problem bumping my version of Storybook to 5 because of conflicting versions of Emotion. Here is a link detailing the problem: https://www.gitmemory.com/issue/emotion-js/emotion/1347/492623945

Uncaught TypeError: Cannot read property 'length' of undefined
    at serializeStyles (main.3173126555acebfe0d1a.bundle.js:445)
    at css (vendors~main.ad7bd95803918bf0d539.bundle.js:643)
    at Module.keyframes (vendors~main.ad7bd95803918bf0d539.bundle.js:504)
    at Object../node_modules/@storybook/theming/dist/animation.js (vendors~main.ad7bd95803918bf0d539.bundle.js:7687)
    at __webpack_require__ (runtime~main.7b4918090cfe19b7778a.bundle.js:79)
    at Object../node_modules/@storybook/theming/dist/create.js (vendors~main.ad7bd95803918bf0d539.bundle.js:7845)
    at __webpack_require__ (runtime~main.7b4918090cfe19b7778a.bundle.js:79)
    at Object../node_modules/@storybook/theming/dist/index.js (vendors~main.ad7bd95803918bf0d539.bundle.js:8126)
    at __webpack_require__ (runtime~main.7b4918090cfe19b7778a.bundle.js:79)
    at Object../node_modules/@storybook/router/dist/visibility.js (vendors~main.ad7bd95803918bf0d539.bundle.js:7643)

Add testId prop

That's a nice library!! But for testing purposes, it would be awesome to have the properties testId and/or aria-label to implement those tests correctly!

Add test property

It would be nice to add an extra property like testId or something similar, for testing purposes!!!
I really love it!!

Can't find variable document

I tried installing in expo, I got error when importing "Can't find variable document".

import Skeleton from "react-loading-skeleton";

I use sdk36 and RN 0.60

Expose a prop to remove the pulse from the animation

Use case: If your component has an error state, you can kill the animation and only show the shapes with a solid color.

At the moment, the workaround is to use SkeletonTheme with the same color and highlightColor or use an extremely high duration number.

Not working inside iframe

I'm using react-frame-component to put part of my app inside an iframe and none of the css of the Skeletons inserted inside the iframe are generated. I don't get why

Doesn't work with SSR

ReferenceError: window is not defined
    at Object.<anonymous> (/Users/some_path/node_modules/react-loading-skeleton/dist/bundle.js:1:240)

npm start error on windows

Hi,
I really appreciate you for this work. But I wanted to benefit from the examples, but I get error when 'npm start' on windows 10. Attached is the log file.

npm-debug.log

Skeleton does not work properly if we also use another library that is using @emotion/**

I find that, this does not work as expected if we use the other library that is using @emotion/** too.
In production mode, Skeleton will be dissapeared because there is no css style is generated.

I tried by using:

  • React 17+ (Next.js 10)
  • https://github.com/JedWatson/react-select version: latest
  • https://github.com/dvtng/react-loading-skeleton version: latest

It used to work perfectly when I use react-select version 3 (it uses @emotion/** version 10)

documentation

Hello,
Is there documentation for this package? If there is, please provide the link.

Span Wrapper with Width=null is getting width 0

When i'm not adding width to the component the spa n wrapper holding the skeleton is getting width = 0, it doesnt stretch since it is missing also width=100% (since it is in a flex element and there is no content inside)

Maybe it will be better to use a Div ? will be also great to support width and height in precentage.

Thanks

Allow specifying width

I found after using skeletons that I nearly always want to specify a width. To get that I have to wrap each <Skeleton /> with an extra component so I can set the width:

<span style={{ width: '100px' }}><Skeleton /></span>

I made a wrapper to make this easer:

<Span width="100px"><Skeleton /></Span>

However I would prefer just setting the (optional) width directly on the skeleton:

<Skeleton width="100px" />

I'm willing to submit a pull request if you're interested in incorporating it.

Add React 17 support

Looks like an awesome component, but I can't install it in combination with React 17. Could you bump the dependency version from 16 to 17?

SkeletonTheme can't be changed at runtime

I have two themes in my site that can be changed in any moment. I'd like to change SkeletonTheme with it.

I've tried using ternary operators in the colors, and I even made a wrapper component:

import React from 'react';
import {SkeletonTheme} from "react-loading-skeleton";

const ThemeAwareSkeletonTheme = ({theme, children}) => {
    if (theme === "white") {
        return (<SkeletonTheme color={"#eee"} highlightColor={"#f5f5f5"}>{children}</SkeletonTheme>)
    } else {
        return (<SkeletonTheme color={"#245b89"} highlightColor={"#152e4d"}>{children}</SkeletonTheme>)
    }
};

export default ThemeAwareSkeletonTheme;

But it doesn't work, if the first loaded theme is white, it can't be changed to the other one, it just keeps the same colors.

I can't find in the code what is causing it, can you help me to find it?

Thanks!

Regards

Width prop breaks multi-line skeleton

Hi,

When a multi-line skeleton is given width the lines display in one line, because of display: inline-block and the lack of line breaks.
image

A clean and easy solution could be to add line break </br> after every line when width attribute is set.
If you consider it acceptable I can contribute with PR for this change.

Regards,
Hrabur

Support for style prop!!

Plesase, this is a great package, but its so important to support styling props to build a good skeleton page!

Support RTL animation

First of all I'd like to thank you for this great package,

Right now there is no support for RTL skeleton animation, is there a way to add a direction (direction: string, Defaults to ltr) or rtl (rtl: boolean Defaults to false) prop on SkeletonTheme component to deal with that?

Happy to help on that!

Does not display if width in % and child of Flex or Grid

I want to use percent widths in a responsive layout, but if the Skeleton component is within a Flex or Grid parent then you must supply a px width. Is there any plan to add a classname to the default 'span' wrapper? This would at least allow me to add a custom style object in this situation.

Support for shadow dom

When using this Skeleton loader inside Shadow DOM, styles are being attached to head. As Shadow DOM encapsulates styles we are not able to use this. It would be great if can add some parameter to address this issue.

Skeleton with Lazy Suspense

Hi, just wondering if anyone got the Skeleton to work with Lazy/Suspense from 16.6?

I'm trying to do this component level as suggested, but the Lazy/Suspense kicks in and shows the loading fallback the entire time instead.

Any ideas? Should I just add a generic skeleton in there instead of per component?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.