@spark-web/spinner 1.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/CHANGELOG.md ADDED
@@ -0,0 +1,18 @@
1
+ # @spark-web/spinner
2
+
3
+ ## 1.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - [#44](https://github.com/brighte-labs/spark-web/pull/44)
8
+ [`11e7365`](https://github.com/brighte-labs/spark-web/commit/11e73659ff4a01a48a8761821bff34c6ec28568b)
9
+ Thanks [@matildaPan](https://github.com/matildaPan)! - initial release of
10
+ spinner component
11
+
12
+ ### Patch Changes
13
+
14
+ - Updated dependencies
15
+ [[`11e7365`](https://github.com/brighte-labs/spark-web/commit/11e73659ff4a01a48a8761821bff34c6ec28568b),
16
+ [`11e7365`](https://github.com/brighte-labs/spark-web/commit/11e73659ff4a01a48a8761821bff34c6ec28568b)]:
17
+ - @spark-web/icon@1.1.0
18
+ - @spark-web/utils@1.1.0
package/README.md ADDED
@@ -0,0 +1,57 @@
1
+ ---
2
+ title: Spinner
3
+ storybookPath: feedback-overlays-spinner-—default
4
+ ---
5
+
6
+ Spinner indicates users that their request is in progress
7
+
8
+ ## Examples
9
+
10
+ ### Tones
11
+
12
+ The appearance of Spinner can be cutomised with the tone prop.
13
+
14
+ Defaults to `primary`.
15
+
16
+ ```jsx live
17
+ const tones = ['secondary', 'critical', 'positive', 'neutral'];
18
+
19
+ return (
20
+ <Stack align="left" gap="xxlarge">
21
+ <Inline gap="xxlarge">
22
+ {tones.map((tone, index) => (
23
+ <Button tone={tone} prominence="low" key={`low-btn-${index}`}>
24
+ <Spinner />
25
+ </Button>
26
+ ))}
27
+ </Inline>
28
+ <Inline gap="xxlarge">
29
+ {tones.map((tone, index) => (
30
+ <Button tone={tone} key={`btn-${index}`}>
31
+ <Spinner />
32
+ </Button>
33
+ ))}
34
+ </Inline>
35
+ <Inline gap="xxlarge">
36
+ {tones.map((tone, index) => (
37
+ <Spinner tone={tone} key={`spinner-${index}`} />
38
+ ))}
39
+ </Inline>
40
+ </Stack>
41
+ );
42
+ ```
43
+
44
+ ## Size
45
+
46
+ Spinners available in two size: `xxsmall` and `xsmall`.
47
+
48
+ Defaults to `xsmall`.
49
+
50
+ ```jsx live
51
+ <Inline gap="xxlarge">
52
+ <Row gap="xxlarge">
53
+ <Spinner size="xxsmall" />
54
+ <Spinner size="xsmall" />
55
+ </Row>
56
+ </Inline>
57
+ ```
@@ -0,0 +1,10 @@
1
+ /// <reference types="react" />
2
+ import type { IconProps } from '@spark-web/icon';
3
+ export declare type SpinnerProps = {
4
+ tone?: IconProps['tone'];
5
+ size?: 'xxsmall' | 'xsmall';
6
+ };
7
+ export declare function Spinner({ tone, size }: SpinnerProps): JSX.Element;
8
+ export declare namespace Spinner {
9
+ var displayName: string;
10
+ }
@@ -0,0 +1,2 @@
1
+ export { Spinner } from './Spinner';
2
+ export type { SpinnerProps } from './Spinner';
@@ -0,0 +1 @@
1
+ export * from "./declarations/src/index";
@@ -0,0 +1,72 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var css = require('@emotion/css');
6
+ var box = require('@spark-web/box');
7
+ var icon = require('@spark-web/icon');
8
+ var utils = require('@spark-web/utils');
9
+ var jsxRuntime = require('react/jsx-runtime');
10
+
11
+ function Spinner(_ref) {
12
+ var tone = _ref.tone,
13
+ _ref$size = _ref.size,
14
+ size = _ref$size === void 0 ? 'xxsmall' : _ref$size;
15
+ var spinAnimationRef = utils.useSynchronizedAnimation(spinAnimation);
16
+ var strokeAnimationRef = utils.useSynchronizedAnimation(strokeDashAnimation);
17
+ var styles = useSpinnerStyles();
18
+ return /*#__PURE__*/jsxRuntime.jsx(box.Box, {
19
+ as: "span",
20
+ ref: spinAnimationRef,
21
+ className: css.css(styles),
22
+ height: size,
23
+ width: size,
24
+ display: "inline-flex",
25
+ alignItems: "center",
26
+ justifyContent: "center",
27
+ children: /*#__PURE__*/jsxRuntime.jsx(SpinnerIcon, {
28
+ size: size,
29
+ tone: tone,
30
+ ref: strokeAnimationRef
31
+ })
32
+ });
33
+ }
34
+ Spinner.displayName = 'Spinner';
35
+ var SpinnerIcon = icon.createIcon( /*#__PURE__*/jsxRuntime.jsx("circle", {
36
+ cx: 12,
37
+ cy: 12,
38
+ r: 9
39
+ }), 'SpinnerIcon');
40
+ var spinAnimation = css.keyframes({
41
+ from: {
42
+ transform: 'rotate(0deg)'
43
+ },
44
+ to: {
45
+ transform: 'rotate(360deg)'
46
+ }
47
+ });
48
+ var strokeDashAnimation = css.keyframes({
49
+ '0%': {
50
+ strokeDasharray: '1px, 200px',
51
+ strokeDashoffset: 0
52
+ },
53
+ '50%': {
54
+ strokeDasharray: '100px, 200px',
55
+ strokeDashoffset: '-15px'
56
+ },
57
+ '100%': {
58
+ strokeDasharray: '100px, 200px',
59
+ strokeDashoffset: '-125px'
60
+ }
61
+ });
62
+
63
+ function useSpinnerStyles() {
64
+ return {
65
+ animation: "".concat(spinAnimation, " 1.4s linear infinite"),
66
+ '& circle': {
67
+ animation: "".concat(strokeDashAnimation, " 1.4s ease-in-out infinite")
68
+ }
69
+ };
70
+ }
71
+
72
+ exports.Spinner = Spinner;
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ if (process.env.NODE_ENV === "production") {
4
+ module.exports = require("./spark-web-spinner.cjs.prod.js");
5
+ } else {
6
+ module.exports = require("./spark-web-spinner.cjs.dev.js");
7
+ }
@@ -0,0 +1,72 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var css = require('@emotion/css');
6
+ var box = require('@spark-web/box');
7
+ var icon = require('@spark-web/icon');
8
+ var utils = require('@spark-web/utils');
9
+ var jsxRuntime = require('react/jsx-runtime');
10
+
11
+ function Spinner(_ref) {
12
+ var tone = _ref.tone,
13
+ _ref$size = _ref.size,
14
+ size = _ref$size === void 0 ? 'xxsmall' : _ref$size;
15
+ var spinAnimationRef = utils.useSynchronizedAnimation(spinAnimation);
16
+ var strokeAnimationRef = utils.useSynchronizedAnimation(strokeDashAnimation);
17
+ var styles = useSpinnerStyles();
18
+ return /*#__PURE__*/jsxRuntime.jsx(box.Box, {
19
+ as: "span",
20
+ ref: spinAnimationRef,
21
+ className: css.css(styles),
22
+ height: size,
23
+ width: size,
24
+ display: "inline-flex",
25
+ alignItems: "center",
26
+ justifyContent: "center",
27
+ children: /*#__PURE__*/jsxRuntime.jsx(SpinnerIcon, {
28
+ size: size,
29
+ tone: tone,
30
+ ref: strokeAnimationRef
31
+ })
32
+ });
33
+ }
34
+ Spinner.displayName = 'Spinner';
35
+ var SpinnerIcon = icon.createIcon( /*#__PURE__*/jsxRuntime.jsx("circle", {
36
+ cx: 12,
37
+ cy: 12,
38
+ r: 9
39
+ }), 'SpinnerIcon');
40
+ var spinAnimation = css.keyframes({
41
+ from: {
42
+ transform: 'rotate(0deg)'
43
+ },
44
+ to: {
45
+ transform: 'rotate(360deg)'
46
+ }
47
+ });
48
+ var strokeDashAnimation = css.keyframes({
49
+ '0%': {
50
+ strokeDasharray: '1px, 200px',
51
+ strokeDashoffset: 0
52
+ },
53
+ '50%': {
54
+ strokeDasharray: '100px, 200px',
55
+ strokeDashoffset: '-15px'
56
+ },
57
+ '100%': {
58
+ strokeDasharray: '100px, 200px',
59
+ strokeDashoffset: '-125px'
60
+ }
61
+ });
62
+
63
+ function useSpinnerStyles() {
64
+ return {
65
+ animation: "".concat(spinAnimation, " 1.4s linear infinite"),
66
+ '& circle': {
67
+ animation: "".concat(strokeDashAnimation, " 1.4s ease-in-out infinite")
68
+ }
69
+ };
70
+ }
71
+
72
+ exports.Spinner = Spinner;
@@ -0,0 +1,68 @@
1
+ import { keyframes, css } from '@emotion/css';
2
+ import { Box } from '@spark-web/box';
3
+ import { createIcon } from '@spark-web/icon';
4
+ import { useSynchronizedAnimation } from '@spark-web/utils';
5
+ import { jsx } from 'react/jsx-runtime';
6
+
7
+ function Spinner(_ref) {
8
+ var tone = _ref.tone,
9
+ _ref$size = _ref.size,
10
+ size = _ref$size === void 0 ? 'xxsmall' : _ref$size;
11
+ var spinAnimationRef = useSynchronizedAnimation(spinAnimation);
12
+ var strokeAnimationRef = useSynchronizedAnimation(strokeDashAnimation);
13
+ var styles = useSpinnerStyles();
14
+ return /*#__PURE__*/jsx(Box, {
15
+ as: "span",
16
+ ref: spinAnimationRef,
17
+ className: css(styles),
18
+ height: size,
19
+ width: size,
20
+ display: "inline-flex",
21
+ alignItems: "center",
22
+ justifyContent: "center",
23
+ children: /*#__PURE__*/jsx(SpinnerIcon, {
24
+ size: size,
25
+ tone: tone,
26
+ ref: strokeAnimationRef
27
+ })
28
+ });
29
+ }
30
+ Spinner.displayName = 'Spinner';
31
+ var SpinnerIcon = createIcon( /*#__PURE__*/jsx("circle", {
32
+ cx: 12,
33
+ cy: 12,
34
+ r: 9
35
+ }), 'SpinnerIcon');
36
+ var spinAnimation = keyframes({
37
+ from: {
38
+ transform: 'rotate(0deg)'
39
+ },
40
+ to: {
41
+ transform: 'rotate(360deg)'
42
+ }
43
+ });
44
+ var strokeDashAnimation = keyframes({
45
+ '0%': {
46
+ strokeDasharray: '1px, 200px',
47
+ strokeDashoffset: 0
48
+ },
49
+ '50%': {
50
+ strokeDasharray: '100px, 200px',
51
+ strokeDashoffset: '-15px'
52
+ },
53
+ '100%': {
54
+ strokeDasharray: '100px, 200px',
55
+ strokeDashoffset: '-125px'
56
+ }
57
+ });
58
+
59
+ function useSpinnerStyles() {
60
+ return {
61
+ animation: "".concat(spinAnimation, " 1.4s linear infinite"),
62
+ '& circle': {
63
+ animation: "".concat(strokeDashAnimation, " 1.4s ease-in-out infinite")
64
+ }
65
+ };
66
+ }
67
+
68
+ export { Spinner };
package/package.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "@spark-web/spinner",
3
+ "version": "1.0.0",
4
+ "license": "MIT",
5
+ "main": "dist/spark-web-spinner.cjs.js",
6
+ "module": "dist/spark-web-spinner.esm.js",
7
+ "dependencies": {
8
+ "@babel/runtime": "^7.14.6",
9
+ "@emotion/css": "^11.7.1",
10
+ "@spark-web/box": "^1.0.2",
11
+ "@spark-web/icon": "^1.1.0",
12
+ "@spark-web/utils": "^1.1.0"
13
+ },
14
+ "devDependencies": {
15
+ "@types/react": "^17.0.12",
16
+ "react": "^17.0.2"
17
+ },
18
+ "peerDependencies": {
19
+ "react": ">=17.0.2"
20
+ },
21
+ "engines": {
22
+ "node": ">= 14.13"
23
+ }
24
+ }
@@ -0,0 +1,43 @@
1
+ import { Inline } from '@spark-web/inline';
2
+ import { Stack } from '@spark-web/stack';
3
+ import type { ComponentMeta, ComponentStory } from '@storybook/react';
4
+
5
+ import type { SpinnerProps } from './Spinner';
6
+ import { Spinner } from './Spinner';
7
+
8
+ export default {
9
+ title: 'Feedback & Overlays / Spinner',
10
+ component: Spinner,
11
+ } as ComponentMeta<typeof Spinner>;
12
+
13
+ const SpinnerStory: ComponentStory<typeof Spinner> = (args: SpinnerProps) => (
14
+ <Stack align="left" gap="xxlarge">
15
+ <Inline gap="xxlarge">
16
+ <Spinner {...args} />
17
+ </Inline>
18
+ </Stack>
19
+ );
20
+
21
+ export const Default = SpinnerStory.bind({});
22
+ export const Critical = SpinnerStory.bind({});
23
+ export const Caution = SpinnerStory.bind({});
24
+ export const Positive = SpinnerStory.bind({});
25
+ export const Primary = SpinnerStory.bind({});
26
+
27
+ Default.args = {} as SpinnerProps;
28
+
29
+ Caution.args = {
30
+ tone: 'caution',
31
+ } as SpinnerProps;
32
+
33
+ Critical.args = {
34
+ tone: 'critical',
35
+ } as SpinnerProps;
36
+
37
+ Positive.args = {
38
+ tone: 'positive',
39
+ } as SpinnerProps;
40
+
41
+ Primary.args = {
42
+ tone: 'primary',
43
+ } as SpinnerProps;
@@ -0,0 +1,55 @@
1
+ import { css, keyframes } from '@emotion/css';
2
+ import { Box } from '@spark-web/box';
3
+ import type { IconProps } from '@spark-web/icon';
4
+ import { createIcon } from '@spark-web/icon';
5
+ import { useSynchronizedAnimation } from '@spark-web/utils';
6
+
7
+ export type SpinnerProps = {
8
+ // TODO: match tones to design in Figma
9
+ tone?: IconProps['tone'];
10
+ size?: 'xxsmall' | 'xsmall';
11
+ };
12
+
13
+ export function Spinner({ tone, size = 'xxsmall' }: SpinnerProps) {
14
+ const spinAnimationRef = useSynchronizedAnimation(spinAnimation);
15
+ const strokeAnimationRef = useSynchronizedAnimation(strokeDashAnimation);
16
+ const styles = useSpinnerStyles();
17
+
18
+ return (
19
+ <Box
20
+ as="span"
21
+ ref={spinAnimationRef}
22
+ className={css(styles)}
23
+ height={size}
24
+ width={size}
25
+ display="inline-flex"
26
+ alignItems="center"
27
+ justifyContent="center"
28
+ >
29
+ <SpinnerIcon size={size} tone={tone} ref={strokeAnimationRef} />
30
+ </Box>
31
+ );
32
+ }
33
+ Spinner.displayName = 'Spinner';
34
+
35
+ const SpinnerIcon = createIcon(<circle cx={12} cy={12} r={9} />, 'SpinnerIcon');
36
+
37
+ const spinAnimation = keyframes({
38
+ from: { transform: 'rotate(0deg)' },
39
+ to: { transform: 'rotate(360deg)' },
40
+ });
41
+
42
+ const strokeDashAnimation = keyframes({
43
+ '0%': { strokeDasharray: '1px, 200px', strokeDashoffset: 0 },
44
+ '50%': { strokeDasharray: '100px, 200px', strokeDashoffset: '-15px' },
45
+ '100%': { strokeDasharray: '100px, 200px', strokeDashoffset: '-125px' },
46
+ });
47
+
48
+ function useSpinnerStyles() {
49
+ return {
50
+ animation: `${spinAnimation} 1.4s linear infinite`,
51
+ '& circle': {
52
+ animation: `${strokeDashAnimation} 1.4s ease-in-out infinite`,
53
+ },
54
+ } as const;
55
+ }
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ export { Spinner } from './Spinner';
2
+
3
+ // types
4
+
5
+ export type { SpinnerProps } from './Spinner';