├── .github
└── workflows
│ ├── main.yml
│ └── size.yml
├── .gitignore
├── LICENSE
├── README.md
├── __mocks__
└── fileMock.js
├── example
├── .npmignore
├── index.html
├── index.tsx
├── indicator.gif
├── package-lock.json
├── package.json
├── src
│ ├── Docs.tsx
│ ├── IconList.tsx
│ └── Spinner.tsx
├── styles.css
└── tsconfig.json
├── package-lock.json
├── package.json
├── src
├── CommonLoaderProps.ts
├── LoaderContext.tsx
├── index.tsx
├── svg-loaders
│ ├── audio.svg
│ ├── ball-triangle.svg
│ ├── bars.svg
│ ├── circles.svg
│ ├── grid.svg
│ ├── hearts.svg
│ ├── oval.svg
│ ├── puff.svg
│ ├── rings.svg
│ ├── spinning-circles.svg
│ ├── tail-spin.svg
│ └── three-dots.svg
├── svg.d.ts
└── useLoading.tsx
├── test
└── useLoading.test.tsx
├── tsconfig.json
└── tsdx.config.js
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 | on: [push]
3 | jobs:
4 | build:
5 | name: Build, lint, and test on Node ${{ matrix.node }} and ${{ matrix.os }}
6 |
7 | runs-on: ${{ matrix.os }}
8 | strategy:
9 | matrix:
10 | node: ['10.x', '12.x', '14.x']
11 | os: [ubuntu-latest, windows-latest, macOS-latest]
12 |
13 | steps:
14 | - name: Checkout repo
15 | uses: actions/checkout@v2
16 |
17 | - name: Use Node ${{ matrix.node }}
18 | uses: actions/setup-node@v1
19 | with:
20 | node-version: ${{ matrix.node }}
21 |
22 | - name: Install deps and build (with cache)
23 | uses: bahmutov/npm-install@v1
24 |
25 | - name: Lint
26 | run: yarn lint
27 |
28 | - name: Test
29 | run: yarn test --ci --coverage --maxWorkers=2
30 |
31 | - name: Build
32 | run: yarn build
33 |
--------------------------------------------------------------------------------
/.github/workflows/size.yml:
--------------------------------------------------------------------------------
1 | name: size
2 | on: [pull_request]
3 | jobs:
4 | size:
5 | runs-on: ubuntu-latest
6 | env:
7 | CI_JOB_NUMBER: 1
8 | steps:
9 | - uses: actions/checkout@v1
10 | - uses: andresz1/size-limit-action@v1
11 | with:
12 | github_token: ${{ secrets.GITHUB_TOKEN }}
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.log
2 | .DS_Store
3 | node_modules
4 | .cache
5 | dist
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Agney
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
React Loading
2 |
3 | Simple and Accessible loading indicators with React.
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | Comes bundled with React components of [Sam Herbert's animated SVG loaders](https://github.com/SamHerbert/SVG-Loaders) in a tree shakeable package.
22 |
23 | 
24 |
25 | ## Installation
26 |
27 | ```bash
28 | npm i @agney/react-loading
29 | # OR
30 | yarn add @agney/react-loading
31 | ```
32 |
33 | [Demo](https://agneym.github.io/react-loading/)
34 |
35 | ## Features
36 |
37 | - **Small Size**
38 |
39 | The entire library is about [20kB minified](https://bundlephobia.com/result?p=@agney/react-loading). _But you would never need the whole bundle._
40 |
41 | The library is build to be treeshakeable that when you use one or two of the bundled loaders, you would have **less than 1kB** in your bundle.
42 |
43 | No dependencies either 😇
44 |
45 | - **Accessibility**
46 |
47 | Provides accessibility attributes on your loading components and containers.
48 |
49 | `aria-busy` is set to `true` on container on loading and progress indicators have `role=progressbar`.
50 |
51 | - **Specify a Global loader**
52 |
53 | You probably don't want loader components mixed everywhere, so you can specify a `LoaderContext` that can be overridden later if necessary.
54 |
55 | - **Bring your own loader**
56 |
57 | If you decide to bring your own loading indicator, library would support that as well, keeping all your logic the same.
58 |
59 | - TypeScript support. Zero extra CSS.
60 |
61 | ## Usage
62 |
63 | ```javascript
64 | import { useLoading, Audio } from '@agney/react-loading';
65 |
66 | function Content() {
67 | const { containerProps, indicatorEl } = useLoading({
68 | loading: true,
69 | indicator: ,
70 | });
71 |
72 | return (
73 | {/* Accessibility props injected to container */}
74 |
75 | {indicatorEl} {/* renders only while loading */}
76 |
77 | );
78 | }
79 | ```
80 | [Sample](https://codesandbox.io/s/agneyreact-loading-example-9jj7c)
81 |
82 | ## Loaders
83 |
84 | This library comes bundled with React components of [Sam Herbert's animated SVG loaders](https://github.com/SamHerbert/SVG-Loaders) in a tree shakeable package.
85 |
86 | Each loader is an SVG and all props passed shall be applied to the top SVG element. All SVGs are set to inherit `currentColor` from it's parents for fill/stroke.
87 |
88 | Available loaders are:
89 |
90 | ```javascript
91 | import {
92 | Audio,
93 | BallTriangle,
94 | Bars,
95 | Circles,
96 | Grid,
97 | Hearts,
98 | Oval,
99 | Puff,
100 | Rings,
101 | SpinningCircles,
102 | TailSpin,
103 | ThreeDots,
104 | } from '@agney/react-loading';
105 | ```
106 |
107 | Only the ones you use will be included in your bundle when you use a bundler like Webpack/Rollup.
108 |
109 | ## Context
110 |
111 | You can specify a single loading indicator reused across hooks with the `LoaderProvider`.
112 |
113 | ```javascript
114 | import { LoaderProvider, useLoading, BallTriangle } from '@agney/react-loading';
115 |
116 | function App() {
117 | const { containerProps, indicatorEl } = useLoading({
118 | loading: true,
119 | });
120 | return {indicatorEl};
121 | }
122 |
123 | ReactDOM.render(
124 | }>
125 |
126 |
127 | );
128 | ```
129 |
130 | You can use as many `LoaderProvider` provider elements as you like and React will pick the one closest to the hook you are rendering.
131 |
132 | [More on React Context](https://reactjs.org/docs/context.html)
133 |
134 | ## Extra Props on Loader
135 |
136 | If you want to provide specific props on a loader specifically when you use the hook:
137 |
138 | ```javascript
139 | useLoading({
140 | loading: true,
141 | loaderProps: {
142 | // Any props here would be spread on to the indicator element.
143 | style: {{ margin: '0 auto' }}
144 | }
145 | });
146 | ```
147 |
148 | We also a provide a special key for `valueText`, that will be used as description for indicator:
149 |
150 | ```javascript
151 | useLoading({
152 | loading: true,
153 | loaderProps: {
154 | valueText: 'Fetching video from the Great Internet',
155 | },
156 | });
157 |
158 | // now this will generate:
159 | /* */
160 | ```
161 |
162 | `aria-valuetext` will be read by screenreaders.
163 |
164 | You could also provide `aria-valuenow` for indicators that display progress (but the prebundled ones are best for indeterminate progress indicators)
165 |
166 | [MDN for Reference on `progressbar`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_progressbar_role)
167 |
168 | ## Bring your own loader
169 |
170 | Just switch the import to your own loading indicator (just make sure that it accepts props)
171 |
172 | ```javascript
173 | import { LoaderProvider, useLoading } from '@agney/react-loading';
174 |
175 | const Loader = ({ ...rest }) =>