svg-loaders-react 3.1.5 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/test.yml +1 -1
- package/README.md +5 -0
- package/package.json +21 -13
- package/test/__snapshots__/audio.test.js.snap +75 -0
- package/test/__snapshots__/ball-triangle.test.js.snap +91 -0
- package/test/__snapshots__/bars.test.js.snap +130 -0
- package/test/__snapshots__/circles.test.js.snap +36 -0
- package/test/__snapshots__/grid.test.js.snap +139 -0
- package/test/__snapshots__/hearts.test.js.snap +41 -0
- package/test/__snapshots__/oval.test.js.snap +37 -0
- package/test/__snapshots__/puff.test.js.snap +70 -0
- package/test/__snapshots__/rings.test.js.snap +95 -0
- package/test/__snapshots__/spinning-circles.test.js.snap +138 -0
- package/test/__snapshots__/tail-spin.test.js.snap +70 -0
- package/test/__snapshots__/three-dots.test.js.snap +91 -0
- package/test/audio.test.js +6 -11
- package/test/ball-triangle.test.js +6 -11
- package/test/bars.test.js +6 -11
- package/test/circles.test.js +6 -11
- package/test/grid.test.js +6 -11
- package/test/hearts.test.js +6 -11
- package/test/helpers/loader-behavior.js +111 -0
- package/test/index.test.js +16 -0
- package/test/oval.test.js +6 -11
- package/test/puff.test.js +6 -11
- package/test/rings.test.js +6 -11
- package/test/spinning-circles.test.js +5 -11
- package/test/tail-spin.test.js +5 -11
- package/test/three-dots.test.js +6 -11
- package/src/setupTests.js +0 -6
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import React, { StrictMode } from 'react';
|
|
2
|
+
import { render } from '@testing-library/react';
|
|
3
|
+
import { renderToStaticMarkup } from 'react-dom/server.node';
|
|
4
|
+
|
|
5
|
+
const getSvg = (container) => container.querySelector('svg');
|
|
6
|
+
|
|
7
|
+
// Shared behavior suite run against every loader component.
|
|
8
|
+
// `defaults` lists the attributes the component sets on its root <svg>.
|
|
9
|
+
export default function describeLoader(name, Component, defaults) {
|
|
10
|
+
describe(`<${name} />`, () => {
|
|
11
|
+
it('renders a single root <svg> element', () => {
|
|
12
|
+
const { container } = render(<Component />);
|
|
13
|
+
expect(container.children).toHaveLength(1);
|
|
14
|
+
expect(getSvg(container)).not.toBeNull();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('renders the expected default attributes', () => {
|
|
18
|
+
const svg = getSvg(render(<Component />).container);
|
|
19
|
+
Object.entries(defaults).forEach(([attr, value]) => {
|
|
20
|
+
expect(svg.getAttribute(attr)).toBe(String(value));
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('has a viewBox with four numeric values', () => {
|
|
25
|
+
const viewBox = getSvg(render(<Component />).container).getAttribute('viewBox');
|
|
26
|
+
expect(viewBox.split(' ').map(Number).every(Number.isFinite)).toBe(true);
|
|
27
|
+
expect(viewBox.split(' ')).toHaveLength(4);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('applies only the base class when no className is given', () => {
|
|
31
|
+
const svg = getSvg(render(<Component />).container);
|
|
32
|
+
expect(svg.getAttribute('class')).toBe('svg-loaders-svg');
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('appends a custom className to the base class', () => {
|
|
36
|
+
const svg = getSvg(render(<Component className="custom extra" />).container);
|
|
37
|
+
expect(svg.getAttribute('class')).toBe('svg-loaders-svg custom extra');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('ignores an empty className', () => {
|
|
41
|
+
const svg = getSvg(render(<Component className="" />).container);
|
|
42
|
+
expect(svg.getAttribute('class')).toBe('svg-loaders-svg');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('lets props override the default dimensions and colors', () => {
|
|
46
|
+
const svg = getSvg(render(
|
|
47
|
+
<Component width={10} height={20} fill="red" stroke="blue" viewBox="0 0 1 1" />,
|
|
48
|
+
).container);
|
|
49
|
+
expect(svg.getAttribute('width')).toBe('10');
|
|
50
|
+
expect(svg.getAttribute('height')).toBe('20');
|
|
51
|
+
expect(svg.getAttribute('fill')).toBe('red');
|
|
52
|
+
expect(svg.getAttribute('stroke')).toBe('blue');
|
|
53
|
+
expect(svg.getAttribute('viewBox')).toBe('0 0 1 1');
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('passes through arbitrary props to the root <svg>', () => {
|
|
57
|
+
const onClick = jest.fn();
|
|
58
|
+
const svg = getSvg(render(
|
|
59
|
+
<Component
|
|
60
|
+
id="loader"
|
|
61
|
+
role="img"
|
|
62
|
+
aria-label="Loading"
|
|
63
|
+
data-testid="loader"
|
|
64
|
+
style={{ opacity: 0.5 }}
|
|
65
|
+
onClick={onClick}
|
|
66
|
+
/>,
|
|
67
|
+
).container);
|
|
68
|
+
expect(svg.id).toBe('loader');
|
|
69
|
+
expect(svg.getAttribute('role')).toBe('img');
|
|
70
|
+
expect(svg.getAttribute('aria-label')).toBe('Loading');
|
|
71
|
+
expect(svg.getAttribute('data-testid')).toBe('loader');
|
|
72
|
+
expect(svg.style.opacity).toBe('0.5');
|
|
73
|
+
svg.dispatchEvent(new MouseEvent('click', { bubbles: true }));
|
|
74
|
+
expect(onClick).toHaveBeenCalledTimes(1);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('forwards a ref to the root <svg> (React 19 ref-as-prop)', () => {
|
|
78
|
+
const ref = React.createRef();
|
|
79
|
+
render(<Component ref={ref} />);
|
|
80
|
+
expect(ref.current).toBeInstanceOf(SVGSVGElement);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('contains SVG animation elements', () => {
|
|
84
|
+
const { container } = render(<Component />);
|
|
85
|
+
expect(container.querySelectorAll('animate, animateTransform').length).toBeGreaterThan(0);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it('renders under StrictMode without errors or warnings', () => {
|
|
89
|
+
const error = jest.spyOn(console, 'error').mockImplementation(() => {});
|
|
90
|
+
const warn = jest.spyOn(console, 'warn').mockImplementation(() => {});
|
|
91
|
+
try {
|
|
92
|
+
render(<StrictMode><Component /></StrictMode>);
|
|
93
|
+
expect(error).not.toHaveBeenCalled();
|
|
94
|
+
expect(warn).not.toHaveBeenCalled();
|
|
95
|
+
} finally {
|
|
96
|
+
error.mockRestore();
|
|
97
|
+
warn.mockRestore();
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('renders on the server to the same markup as the client', () => {
|
|
102
|
+
const html = renderToStaticMarkup(<Component />);
|
|
103
|
+
expect(html.startsWith('<svg')).toBe(true);
|
|
104
|
+
expect(html).toBe(render(<Component />).container.innerHTML);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('matches the markup snapshot', () => {
|
|
108
|
+
expect(getSvg(render(<Component />).container)).toMatchSnapshot();
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as SVGLoaders from '../src';
|
|
2
|
+
|
|
3
|
+
const EXPECTED = [
|
|
4
|
+
'Audio', 'BallTriangle', 'Bars', 'Circles', 'Grid', 'Hearts',
|
|
5
|
+
'Oval', 'Puff', 'Rings', 'SpinningCircles', 'TailSpin', 'ThreeDots',
|
|
6
|
+
];
|
|
7
|
+
|
|
8
|
+
describe('package entry point', () => {
|
|
9
|
+
it('exports exactly the twelve loader components', () => {
|
|
10
|
+
expect(Object.keys(SVGLoaders).sort()).toEqual([...EXPECTED].sort());
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it.each(EXPECTED)('exports %s as a function component', (name) => {
|
|
14
|
+
expect(typeof SVGLoaders[name]).toBe('function');
|
|
15
|
+
});
|
|
16
|
+
});
|
package/test/oval.test.js
CHANGED
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { shallow, mount } from 'enzyme';
|
|
3
|
-
|
|
4
1
|
import { Oval } from '../src/svg-loader-components/oval';
|
|
2
|
+
import describeLoader from './helpers/loader-behavior';
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const OvalComponent = mount(<Oval />).find('svg');
|
|
12
|
-
expect(OvalComponent.prop('viewBox')).toBeDefined();
|
|
13
|
-
});
|
|
4
|
+
describeLoader('Oval', Oval, {
|
|
5
|
+
width: '38',
|
|
6
|
+
height: '38',
|
|
7
|
+
stroke: '#fff',
|
|
8
|
+
viewBox: '0 0 38 38',
|
|
14
9
|
});
|
package/test/puff.test.js
CHANGED
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { shallow, mount } from 'enzyme';
|
|
3
|
-
|
|
4
1
|
import { Puff } from '../src/svg-loader-components/puff';
|
|
2
|
+
import describeLoader from './helpers/loader-behavior';
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const PuffComponent = mount(<Puff />).find('svg');
|
|
12
|
-
expect(PuffComponent.prop('viewBox')).toBeDefined();
|
|
13
|
-
});
|
|
4
|
+
describeLoader('Puff', Puff, {
|
|
5
|
+
width: '44',
|
|
6
|
+
height: '44',
|
|
7
|
+
stroke: '#fff',
|
|
8
|
+
viewBox: '0 0 44 44',
|
|
14
9
|
});
|
package/test/rings.test.js
CHANGED
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { shallow, mount } from 'enzyme';
|
|
3
|
-
|
|
4
1
|
import { Rings } from '../src/svg-loader-components/rings';
|
|
2
|
+
import describeLoader from './helpers/loader-behavior';
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const RingsComponent = mount(<Rings />).find('svg');
|
|
12
|
-
expect(RingsComponent.prop('viewBox')).toBeDefined();
|
|
13
|
-
});
|
|
4
|
+
describeLoader('Rings', Rings, {
|
|
5
|
+
width: '45',
|
|
6
|
+
height: '45',
|
|
7
|
+
stroke: '#fff',
|
|
8
|
+
viewBox: '0 0 45 45',
|
|
14
9
|
});
|
|
@@ -1,14 +1,8 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { shallow, mount } from 'enzyme';
|
|
3
|
-
|
|
4
1
|
import { SpinningCircles } from '../src/svg-loader-components/spinning-circles';
|
|
2
|
+
import describeLoader from './helpers/loader-behavior';
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
it('viewBox property is defined', () => {
|
|
11
|
-
const SpinningCirclesComponent = mount(<SpinningCircles />).find('svg');
|
|
12
|
-
expect(SpinningCirclesComponent.prop('viewBox')).toBeDefined();
|
|
13
|
-
});
|
|
4
|
+
describeLoader('SpinningCircles', SpinningCircles, {
|
|
5
|
+
width: '58',
|
|
6
|
+
height: '58',
|
|
7
|
+
viewBox: '0 0 58 58',
|
|
14
8
|
});
|
package/test/tail-spin.test.js
CHANGED
|
@@ -1,14 +1,8 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { shallow, mount } from 'enzyme';
|
|
3
|
-
|
|
4
1
|
import { TailSpin } from '../src/svg-loader-components/tail-spin';
|
|
2
|
+
import describeLoader from './helpers/loader-behavior';
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
it('viewBox property is defined', () => {
|
|
11
|
-
const TailSpinComponent = mount(<TailSpin />).find('svg');
|
|
12
|
-
expect(TailSpinComponent.prop('viewBox')).toBeDefined();
|
|
13
|
-
});
|
|
4
|
+
describeLoader('TailSpin', TailSpin, {
|
|
5
|
+
width: '38',
|
|
6
|
+
height: '38',
|
|
7
|
+
viewBox: '0 0 38 38',
|
|
14
8
|
});
|
package/test/three-dots.test.js
CHANGED
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { shallow, mount } from 'enzyme';
|
|
3
|
-
|
|
4
1
|
import { ThreeDots } from '../src/svg-loader-components/three-dots';
|
|
2
|
+
import describeLoader from './helpers/loader-behavior';
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const ThreeDotsComponent = mount(<ThreeDots />).find('svg');
|
|
12
|
-
expect(ThreeDotsComponent.prop('viewBox')).toBeDefined();
|
|
13
|
-
});
|
|
4
|
+
describeLoader('ThreeDots', ThreeDots, {
|
|
5
|
+
width: '120',
|
|
6
|
+
height: '30',
|
|
7
|
+
fill: '#fff',
|
|
8
|
+
viewBox: '0 0 120 30',
|
|
14
9
|
});
|