Code Monkey home page Code Monkey logo

react-content-loader's Introduction

react-content-loader

Example's react-content-loader

SVG-Powered component to easily create placeholder loadings (like Facebook's cards loading).

Features

  • ⚙️ Customizable: Feel free to change the colors, speed, sizes, and even RTL;
  • 👌 Plug and play: with many presets to use, see the examples;
  • ✏️ DIY: use the create-content-loader to create your own custom loaders easily;
  • 📱 React Native support: same API, as same powerful features;
  • ⚛️ Really lightweight: less than 2kB and 0 dependencies for web version;

Index

Getting Started

npm i react-content-loader --save
yarn add react-content-loader

For React Native

npm i react-content-loader react-native-svg --save
yarn add react-content-loader react-native-svg

CDN from JSDELIVR

Usage

There are two ways to use it:

1. Presets, see the examples:

import ContentLoader, { Facebook } from 'react-content-loader'

const MyLoader = () => <ContentLoader />
const MyFacebookLoader = () => <Facebook />

2. Custom mode, see the online tool

const MyLoader = () => (
  <ContentLoader viewBox="0 0 380 70">
    {/* Only SVG shapes */}    
    <rect x="0" y="0" rx="5" ry="5" width="70" height="70" />
    <rect x="80" y="17" rx="4" ry="4" width="300" height="13" />
    <rect x="80" y="40" rx="3" ry="3" width="250" height="10" />
  </ContentLoader>
)

Still not clear? Take a look at this working example at codesandbox.io Or try the components editable demo hands-on and install it from bit.dev

Native

react-content-loader can be used with React Native in the same way as web version with the same import:

1. Presets, see the examples:

import ContentLoader, { Facebook } from 'react-content-loader/native'

const MyLoader = () => <ContentLoader />
const MyFacebookLoader = () => <Facebook />

2. Custom mode

To create custom loaders there is an important difference: as React Native doesn't have any native module for SVG components, it's necessary to import the shapes from react-native-svg or use the named export Rect and Circle from react-content-loader import:

import ContentLoader, { Rect, Circle } from 'react-content-loader/native'

const MyLoader = () => (
  <ContentLoader viewBox="0 0 380 70">
    <Circle cx="30" cy="30" r="30" />
    <Rect x="80" y="17" rx="4" ry="4" width="300" height="13" />
    <Rect x="80" y="40" rx="3" ry="3" width="250" height="10" />
  </ContentLoader>
)

Options

Prop name and type
Environment Description
animate?: boolean
Defaults to true
React DOM
React Native
Opt-out of animations with false
title?: string
Defaults to Loading...
React DOM only It's used to describe what element it is. 
Use '' (empty string) to remove.
baseUrl?: string
Defaults to an empty string
React DOM only Required if you're using <base url="/" /> document <head/>
This prop is common used as: 
<ContentLoader baseUrl={window.location.pathname} /> which will fill the SVG attribute with the relative path. Related #93.
speed?: number
Defaults to 1.2
React DOM
React Native
Animation speed in seconds.
viewBox?: string
Defaults to undefined
React DOM
React Native
Use viewBox props to set a custom viewBox value,
for more information about how to use it,
read the article How to Scale SVG.
gradientRatio?: number
Defaults to 1.2
React DOM only Width of the animated gradient as a fraction of the view box width.
rtl?: boolean
Defaults to false
React DOM
React Native
Content right-to-left.
backgroundColor?: string
Defaults to #f5f6f7
React DOM
React Native
Used as background of animation.
foregroundColor?: string
Defaults to #eee
React DOM
React Native
Used as the foreground of animation.
backgroundOpacity?: number
Defaults to 1
React DOM only Background opacity (0 = transparent, 1 = opaque)
used to solve an issue in Safari
foregroundOpacity?: number
Defaults to 1
React DOM only Animation opacity (0 = transparent, 1 = opaque)
used to solve an issue in Safari
style?: React.CSSProperties
Defaults to {}
React DOM only
uniqueKey?: string
Defaults to random unique id
React DOM only Use the same value of prop key, 
that will solve inconsistency on the SSR, see more here.
beforeMask?: JSX.Element
Defaults to null
React DOM
React Native
Define custom shapes before content, 
see more here.

See all options live

Examples

Facebook Style
import { Facebook } from 'react-content-loader'

const MyFacebookLoader = () => <Facebook />

Facebook Style

Instagram Style
import { Instagram } from 'react-content-loader'

const MyInstagramLoader = () => <Instagram />

Instagram Style

Code Style
import { Code } from 'react-content-loader'

const MyCodeLoader = () => <Code />

Code Style

List Style
import { List } from 'react-content-loader'

const MyListLoader = () => <List />

List Style

Bullet list Style
import { BulletList } from 'react-content-loader'

const MyBulletListLoader = () => <BulletList />

Bullet list Style

Custom Style

For the custom mode, use the online tool.

const MyLoader = () => (
  <ContentLoader
    height={140}
    speed={1}
    backgroundColor={'#333'}
    foregroundColor={'#999'}
    viewBox="0 0 380 70"
  >
    {/* Only SVG shapes */}
    <rect x="0" y="0" rx="5" ry="5" width="70" height="70" />
    <rect x="80" y="17" rx="4" ry="4" width="300" height="13" />
    <rect x="80" y="40" rx="3" ry="3" width="250" height="10" />
  </ContentLoader>
)

Custom

Troubleshooting

Responsive - Mobile version

In order to avoid unexpected behavior, the package doesn't have opinioned settings. So if it needs to be responsive, have in mind that the output of the package is a regular SVG, so it just needs the same attributes to become a regular SVG responsive, which means:

import { Code } from 'react-content-loader'

const MyCodeLoader = () => (
  <Code
    width={100}
    height={100}
    viewBox="0 0 100 100"
    style={{ width: '100%' }}
  />
)

Server-side rendering (SSR) - Match snapshot

As the main component generates random values to match the id of the SVG element with background style, it can encounter unexpected errors and unmatching warning on render, once the random value of id will be generated twice, in case of SSR: server and client; or in case of snapshot test: on the first match and re-running the test.

To fix it, set the prop uniqueKey, then the id will not be random anymore:

import { Facebook } from 'react-content-loader'

const MyFacebookLoader = () => <Facebook uniqueKey="my-random-value" />

Alpha is not working: Safari / iOS

When using rgba as a backgroundColor or foregroundColor value, Safari does not respect the alpha channel, meaning that the color will be opaque. To prevent this, instead of using a rgba value for backgroundColor/foregroundColor, use the rgb equivalent and move the alpha channel value to the backgroundOpacity/foregroundOpacity props.

{/* Opaque color in Safari and iOS */}
<ContentLoader
  backgroundColor="rgba(0,0,0,0.06)"
  foregroundColor="rgba(0,0,0,0.12)">


{/_ Semi-transparent color in Safari and iOS _/}
<ContentLoader
    backgroundColor="rgb(0,0,0)"
    foregroundColor="rgb(0,0,0)"
    backgroundOpacity={0.06}
    foregroundOpacity={0.12}>

Black box in Safari / iOS (again)

Using the base tag on a page that contains SVG elements fails to render and it looks like a black box. Just remove the base-href tag from the <head /> and the issue has been solved.

black box

See: #93 / 109

Browser supports SVG-Animate

Old browsers don't support animation in SVG (compatibility list), and if your project must support IE, for examples, here's a couple of ways to make sure that browser supports SVG Animate:

  • window.SVGAnimateElement
  • document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#SVG-Animation", "1.1")
  • Or even use https://modernizr.com/

Similar packages


Development

Fork the repo and then clone it

$ git clone [email protected]:YourUsername/react-content-loader.git && cd react-content-loader

$ npm i: Install the dependencies;

$ npm run build: Build to production;

$ npm run dev: Run the Storybook to see your changes;

$ npm run test: Run all tests: type checking, unit tests on web and native;

$ npm run test:watch: Watch unit tests;

React Native

As React Native doesn't support symbolic links (to link the dependency to another folder) and as there is no playground to check your contributions (like storybook), this is recommended strategy to run the project locally:

  1. Create a new React Native from scratch, either Metro or create-react-native-app;
  2. Install the dependency to your root project: yarn add react-content-loader react-native-svg
  3. Open the project just created and clone this repository there;
  4. Create your loading component and point the react-content-loader to the project just cloned, like: import ContentLoader, { Rect, Circle } from './react-content-loader/native'

Commit messages

Commit messages should follow the commit message convention so, changelogs could be generated automatically by that. Commit messages are validated automatically upon commit. If you aren't familiar with the commit message convention, you can use yarn commit (or npm run commit) instead of git commit, which provides an interactive CLI for generating proper commit messages.

License

MIT

react-content-loader's People

Contributors

aamnah avatar ajayposhak avatar alexkirsz avatar amiraliamhh avatar andarist avatar bahaa96 avatar danilowoz avatar dependabot[bot] avatar donroyco avatar enapupe avatar gcangussu avatar kqito avatar lcustodio avatar liam61 avatar michaeldeboey avatar nicholasyan avatar nicmitchell avatar nikolailiev avatar ombratteng avatar pallymore avatar patcito avatar pthrasher avatar rakeshgunduka avatar ricardomlima avatar samwalshnz avatar smaniotto avatar totominc avatar vitorleonel avatar walkeryr avatar zackseuberling 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  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

react-content-loader's Issues

Why save-dev?

Why do you recommend saving it as a dev dependency? Isn't it required if you're using it in your prod app to be in your dep's?

SSR matching of fill url

Using react-content-loader with SSR (in this case with Next.js) I'm getting the warning:

Warning: Prop `style` did not match. Server: "fill:url(#yu80c54k1c8)" Client: "fill:url(#zhqtwhb70bm)"

Any workaround?

Thanks!

Option to remove view box

This is not a bug, but a question/discussion

I'm not sure if I'm using svg's properly but for having responsive Skeletons, I thought of disabling viewBox. And I did so by passing unexpected values to width/height. Then by skeleton loader was responsive in the way I want (more with in desktop, same height for rectangles)

1- Do you think that's correct approach for this kind of svgs?
2- If you answered yes/maybe, can we add an option to remove view box?

Support for percentage width

I wanted a svg element that expanded to take all my div and only could achieve this passing "100%" to the width property. The problem is that the viewBox prop doesn't accept percentages and I received a lot of warnings on the console.

Removed custom components

Actually the custom components (<Rect /> <Circle />) isn't necessary anymore because I created the create-react-content-loader to replace this work.

What should I work here?

  • Remove the custom components, at /src/custom;
  • Remove the respective tests;
  • Update the readme removing the old references;
  • Update the readme with new references about the create tool;

View config not found for name rect

What did I do?

I write this code and I expected to run properly
this is my code :

const MyLoader = props => (
  <ContentLoader
    height={130}
    width={400}
    speed={2}
    primaryColor="#f3f3f3"
    secondaryColor="#ecebeb"
    {...props}
  >
    <rect x="19" y="45" rx="3" ry="3" width="245" height="5" /> 
    <circle cx="333.5" cy="78.76" r="49.5" /> 
    <rect x="19" y="75" rx="3" ry="3" width="245" height="5" /> 
    <rect x="19" y="105" rx="3" ry="3" width="245" height="5" />
  </ContentLoader>
)

render() {
  return(
      <MyLoader/>
  )
}

And i got this error

Invariant Violation: Invariant Violation: Invariant Violation: Invariant Violation: View config not found fot name rect

I used the last version of this library

Not working in Safari.

What did you do?

My Loader Component

const Loader = props => (
  <ContentLoader
    preserveAspectRatio="none"
    style={{width: '100%' }}
  >
    <rect x="0" y="0" rx="5" ry="5" width="100%" height={300} /> 
  </ContentLoader>
)

What did you expect to happen?

Expect to work for all browsers

What happened actually?

Working fine on Chrome and FireFox but giving black layout for safari.
image

Which versions of react-content-loader, and which browser are affected by this issue?

"react-content-loader": "^3.1.1"
"react": "^15.4.2"
Browsers: Safari

List component

Hi, I really like your lib.

Are you still interested in making the List component?
I would gladly open a PR and work on it and at the same time get my SVG muscles worked out a bit.

Improve props to the wrap

  • Classnames
  • SVG width and height

Maybe I should set all props that component will receive, like {...props}

Add "esnext" field in package.json

Hi, thanks for the awesome package!

Could you add the esnext field on package.json to point src directory please? So webpack can do tree shaking on the src directory.

Thanks.

EDIT: sorry the field name is "jsnext:main" ("module" also work).

RTL switch not working

I flipped the rtl flag on the component - seems that the navigation has changed, but the content stayed the same. Do I need to make my own RTL component? I thought it would switch around automatically.
I went to http://danilowoz.com/create-content-loader/ and switching RTL flag also does nothing.
Thanks

Suggestion: handle animation

It would be interesting if the package had an animation control. To remove the SVG animations tags and any extra code. So, there are two ways:

prop animation

Like <ContentLoader animation={false} />

speed 0

If speed is zero||null, remove the animation tags;

Why React 16?

Hi!

I just installed and tried out react-content-loader and it seems to be working great, even though, I have an app that uses React 15. I can't update because I have some packages in my project that are incompatible with React 16.

What's the exact functionality that is dependent on React 16 and not React 15? What's the latest version that supports React 15?

Thanks!

EDIT: I believe changing dependency requirements from react 15 to react 16 is a breaking change. If you're following semver, you should release new major version.

High CPU usage

image
As shown in the above image the home page's cpu usage is always more than 40% and also more 20% in my app. I think this is abnormal, please confirm whether it is a bug or the normal phenomenon?

Is it possible to have content floating over the animation?

Hi,
First of all, I just wanted to say thanks! This component saved me so much time...

I'm trying to place a reCaptcha over the Instagram-style loader. The overall idea is to give users the impression that the content they're watching is bot-protected... while it is actually public 🤣

So, I have this:

image

And I was wondering if I could get the reCaptcha floating over the animation (centered). I tried to implement it with without any success.

The code is:

<Recaptcha
	sitekey="XXXXX"
	render="explicit"
	verifyCallback={this.verifyRecaptcha}
	onloadCallback={this.onloadRecaptcha}
/>
{
	this.state.loadedDoc ?
		<object data={`${require(`../assets/docs/${this.state.loadedDoc.file}`)}#toolbar=0&navpanes=0&scrollbar=0&view=FitW`} type="application/pdf" className="embedded-document" style={{overflow:'hidden'}} width="100%" height="100%">
		</object> 
	: <Instagram />
}

My version is 3.4.1.

Thanks again!

Suggestion: Issue and pull request templates

Wouldn't it be nice to have templates for issues and pull requests for this repository?

I had scratched this yet for PRs:

Fix issue #[issue number].

Changes proposed by this pull request:
- Change 1
- Change 2
- Change 3

@[reviewer] and @[another reviewer], could you please review this PR?

Checklist:
- [x] Used template
- [ ] Described proposed changes
- [ ] Marked at least two reviewers
- [ ] Wrote tests

I think it would be nice to discuss the template and what is missing in the checklist.
Also, it would be great to have an contributing guide.

@danilowoz, any thoughts on that?

CSS classes do not work on Firefox

What did you do?

I tried to make some reusable content loaders so they could be editable via CSS. It doesn't work on Firefox. To make my content loaders editable, I had to do this.

What did you expect to happen?

I expected the Content Loader to be editable via CSS and work in all browsers.

What happened actually?

It didn't show up. But, I saw this and the note says it's possible to work on SVG2.
I know it's not the latest release, but is there a way you could allow the SVG version to be editable? It would probably solve my issue completely.

Here is sandbox so you can test it.

Which versions of react-content-loader, and which browser are affected by this issue?

react: '^16.3.2'
react-content-loader: '^3.1.2'
Browser affected: Mozilla Firefox

Improve test for Wrap.js

Now, I'm not validating the props and I think the main problem is if the size is right when configured

Accessibility - title/aria-labeledby

Hi,
While writing tests I have a problem with querying react-content-loader components because there is no text/label which may allow for identifying them besides <svg/> tag.

While this problem is not so hard to solve using getElementByTagName('svg') in tests it makes me think that for screen readers etc. it might be much more difficult to tell the user what these SVG images are about.

Why don't we provide default <title>Loading</title> tag for each ContentLoader component? (and/or aria-labeledby)
This Loading text might be configurable using props if one would like to provide more info like "Loading avatar image".

What do you think about that?

Dynamically update height

What did you do?

I don't know what the source code is, but the behavior is off.

What did you expect to happen?

The height to dynamically change with browser size changing.

What happened actually?

The height doesn't change when the browser shrinks vertically, even though the width changes when the browser shrinks horizontally.

Which versions of react-content-loader, and which browser are affected by this issue?

3.4.1 - Chrome

Black layout issue while base-href is set on Safari/iOS

What did you do?

React content Loaders

What did you expect to happen?

Expected to work for all browsers

What happened actually?

Black layout issue while base-href is set on Safari/iOS. Somehow we found out that SVG url() doesn't work under in Safari/iOS. We removed from page and issue solved.

Which versions of react-content-loader, and which browser are affected by this issue?

Latest, Safari (Web/Mobile)

Support for setting width and height attributes directly on the SVG element (not viewBox)

I checked the source and it doesn't seem possible to set the width and height of the SVG element; it's only possible to set the viewBox width and height. According to this stackoverflow answer (and the testing I've done myself), this is the only way to have an SVG element that has a constant height but stretches in width.

How about adding extra options for elementWidth and elementHeight that will set the width and height attribute directly on the SVG element?

I hope it's alright I didn't fill in the issue template. I felt this was easier to explain with words.

Implement Flow

I really would like to use flow on this project because it helps to scale the application, avoid many bugs and it is more secure to future contributors.

Feel free to others suggests :)

Support React 16

Currently getting multiple deprecation warnings from React 15 and can't use it at all with React 16:

Warning: Accessing PropTypes via the main React package is deprecated, and will be removed in React v16.0. Use the latest available v15.* prop-types package from npm instead. For info on usage, compatibility, migration and more, see https://fb.me/prop-types-docs

Warning: Accessing createClass via the main React package is deprecated, and will be removed in React v16.0. Use a plain JavaScript class instead. If you're not yet ready to migrate, create-react-class v15.* is available on npm as a temporary, drop-in replacement. For more info see https://fb.me/react-create-class

支持React16

目前还是直接依赖React.PropTypes,但是React16已经遗弃该API

Transition and display is not working properly in Firefox and Edge

What did you do?

I render 5 content loaders:

{[...[1, 2, 3, 4, 5]].map((x, i) =>

                                <ContentLoader
                                    key={i}
                                    height={70}
                                    width={500}
                                    speed={3}
                                    primaryColor="#f3f3f3"
                                    secondaryColor="#08c1b3">
                                    <rect x="70" y="15" rx="4" ry="4" width="117" height="6.4" />
                                    <rect x="70" y="35" rx="3" ry="3" width="85" height="6.4" />
                                    <circle cx="30" cy="30" r="30" />
                                </ContentLoader>
                            )}

What did you expect to happen?

I expected the transition to work along with having the right size.

What happened actually?

There was no transition and it was not the right size.

Which versions of react-content-loader, and which browser are affected by this issue?

Please also mention the version of react.
"react": "^15.6.2",
"react-content-loader": "^3.1.1",

Tested in Firefox Quantum version 59.0.2 and Edge 41.16299.248.0

This is how it looks in Edge & Firefox (There is no transition, it is just still):

2018-04-11_14h31_28

This is how it looks in Chrome (it works fine here):

2018-04-11_14h37_39

[Suggestion] Nested placeholder

i want to build a board with cards,
it will be nice if i can create a placeholder for Board, placeholder for Column and a placeholder for Card reusing the placeholder for card,
allowing me to reuse placeholders, and allowing the creation of dynamic columns and cards

expected usage:

function Column(){} // simple square
function Card(){} // a card placeholder

function Board({columnArray}){
   return (
      <ContentLoader>
        {columnArray.map(() => {
            return ( 
              <Column>
                   {Array(5).map(() => {
                     return (<Card/>);
                    )}
              </Column>
            );
        });}
      </ContentLoader>
  );
} 
 

When unmounting component with ContentLoader a LOOP Warning is thown

Im using ContentLoader inside a LoadingListItem Component. When a flag is changed I unmount this component to ListItem BUT when this happens a WARNING is thrown , this warning is consuming the memory.

Warning: Can only update a mounted or mounting component. This usually means you called setState, replaceState, or forceUpdate on an unmounted component. This is a no-op.

Please check the code for the ContentLoader component.

[proposal] Restructure API

Imho, for such a simple component with simple variants it would be much better to just export Wrap as default and all various flavours as named exports. This would be a breaking change, but I think it's better to export separate components that are composed from others, than to hardcore all of them as dependency (through props.type) of a single component. At the moment if Im interested in lets say Facebook variant only, I need to pull all variants into my app. The proposed change would allow me and others to pull only a subset of those variants.

Replicate test for bullet list component

There are some examples of test, it just need to replicate the same test for the bullet list component

Component: /src/stylized/BulletListStyle.js
Tests: /tests

Not able to overlay onto a component

What did you do?

Not sure what the source code is

What did you expect to happen?

If there is a component (say a Material-UI card), there is currently no way to overlay the content loader on top of the component so that the content loader is the same size/dimensions as the underlying content.

This results in having a content loader that is not the same size as what replaces it once loading is complete.

Which versions of react-content-loader, and which browser are affected by this issue?

3.4.1 on Chrome

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.