UNPKG

7.26 kBJavaScriptView Raw
1import _extends from "@babel/runtime/helpers/esm/extends";
2import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3import * as React from 'react';
4import PropTypes from 'prop-types';
5import clsx from 'clsx';
6import { chainPropTypes } from '@material-ui/utils';
7import withStyles from '../styles/withStyles';
8import capitalize from '../utils/capitalize';
9const SIZE = 44;
10export const styles = theme => ({
11 /* Styles applied to the root element. */
12 root: {
13 display: 'inline-block'
14 },
15
16 /* Styles applied to the root element if `variant="static"`. */
17 static: {
18 transition: theme.transitions.create('transform')
19 },
20
21 /* Styles applied to the root element if `variant="indeterminate"`. */
22 indeterminate: {
23 animation: '$circular-rotate 1.4s linear infinite'
24 },
25
26 /* Styles applied to the root element if `variant="determinate"`. */
27 determinate: {
28 transition: theme.transitions.create('transform')
29 },
30
31 /* Styles applied to the root element if `color="primary"`. */
32 colorPrimary: {
33 color: theme.palette.primary.main
34 },
35
36 /* Styles applied to the root element if `color="secondary"`. */
37 colorSecondary: {
38 color: theme.palette.secondary.main
39 },
40
41 /* Styles applied to the `svg` element. */
42 svg: {
43 display: 'block' // Keeps the progress centered
44
45 },
46
47 /* Styles applied to the `circle` svg path. */
48 circle: {
49 stroke: 'currentColor' // Use butt to follow the specification, by chance, it's already the default CSS value.
50 // strokeLinecap: 'butt',
51
52 },
53
54 /* Styles applied to the `circle` svg path if `variant="static"`. */
55 circleStatic: {
56 transition: theme.transitions.create('stroke-dashoffset')
57 },
58
59 /* Styles applied to the `circle` svg path if `variant="indeterminate"`. */
60 circleIndeterminate: {
61 animation: '$circular-dash 1.4s ease-in-out infinite',
62 // Some default value that looks fine waiting for the animation to kicks in.
63 strokeDasharray: '80px, 200px',
64 strokeDashoffset: '0px' // Add the unit to fix a Edge 16 and below bug.
65
66 },
67
68 /* Styles applied to the `circle` svg path if `variant="determinate"`. */
69 circleDeterminate: {
70 transition: theme.transitions.create('stroke-dashoffset')
71 },
72 '@keyframes circular-rotate': {
73 '0%': {
74 // Fix IE 11 wobbly
75 transformOrigin: '50% 50%'
76 },
77 '100%': {
78 transform: 'rotate(360deg)'
79 }
80 },
81 '@keyframes circular-dash': {
82 '0%': {
83 strokeDasharray: '1px, 200px',
84 strokeDashoffset: '0px'
85 },
86 '50%': {
87 strokeDasharray: '100px, 200px',
88 strokeDashoffset: '-15px'
89 },
90 '100%': {
91 strokeDasharray: '100px, 200px',
92 strokeDashoffset: '-125px'
93 }
94 },
95
96 /* Styles applied to the `circle` svg path if `disableShrink={true}`. */
97 circleDisableShrink: {
98 animation: 'none'
99 }
100});
101/**
102 * ## ARIA
103 *
104 * If the progress bar is describing the loading progress of a particular region of a page,
105 * you should use `aria-describedby` to point to the progress bar, and set the `aria-busy`
106 * attribute to `true` on that region until it has finished loading.
107 */
108
109const CircularProgress = /*#__PURE__*/React.forwardRef(function CircularProgress(props, ref) {
110 const {
111 classes,
112 className,
113 color = 'primary',
114 disableShrink = false,
115 size = 40,
116 style,
117 thickness = 3.6,
118 value = 0,
119 variant = 'indeterminate'
120 } = props,
121 other = _objectWithoutPropertiesLoose(props, ["classes", "className", "color", "disableShrink", "size", "style", "thickness", "value", "variant"]);
122
123 const circleStyle = {};
124 const rootStyle = {};
125 const rootProps = {};
126
127 if (variant === 'determinate' || variant === 'static') {
128 const circumference = 2 * Math.PI * ((SIZE - thickness) / 2);
129 circleStyle.strokeDasharray = circumference.toFixed(3);
130 rootProps['aria-valuenow'] = Math.round(value);
131 circleStyle.strokeDashoffset = `${((100 - value) / 100 * circumference).toFixed(3)}px`;
132 rootStyle.transform = 'rotate(-90deg)';
133 }
134
135 return /*#__PURE__*/React.createElement("div", _extends({
136 className: clsx(classes.root, className, color !== 'inherit' && classes[`color${capitalize(color)}`], {
137 'determinate': classes.determinate,
138 'indeterminate': classes.indeterminate,
139 'static': classes.static
140 }[variant]),
141 style: _extends({
142 width: size,
143 height: size
144 }, rootStyle, style),
145 ref: ref,
146 role: "progressbar"
147 }, rootProps, other), /*#__PURE__*/React.createElement("svg", {
148 className: classes.svg,
149 viewBox: `${SIZE / 2} ${SIZE / 2} ${SIZE} ${SIZE}`
150 }, /*#__PURE__*/React.createElement("circle", {
151 className: clsx(classes.circle, disableShrink && classes.circleDisableShrink, {
152 'determinate': classes.circleDeterminate,
153 'indeterminate': classes.circleIndeterminate,
154 'static': classes.circleStatic
155 }[variant]),
156 style: circleStyle,
157 cx: SIZE,
158 cy: SIZE,
159 r: (SIZE - thickness) / 2,
160 fill: "none",
161 strokeWidth: thickness
162 })));
163});
164process.env.NODE_ENV !== "production" ? CircularProgress.propTypes = {
165 // ----------------------------- Warning --------------------------------
166 // | These PropTypes are generated from the TypeScript type definitions |
167 // | To update them edit the d.ts file and run "yarn proptypes" |
168 // ----------------------------------------------------------------------
169
170 /**
171 * Override or extend the styles applied to the component.
172 * See [CSS API](#css) below for more details.
173 */
174 classes: PropTypes.object,
175
176 /**
177 * @ignore
178 */
179 className: PropTypes.string,
180
181 /**
182 * The color of the component. It supports those theme colors that make sense for this component.
183 */
184 color: PropTypes.oneOf(['inherit', 'primary', 'secondary']),
185
186 /**
187 * If `true`, the shrink animation is disabled.
188 * This only works if variant is `indeterminate`.
189 */
190 disableShrink: chainPropTypes(PropTypes.bool, props => {
191 if (props.disableShrink && props.variant && props.variant !== 'indeterminate') {
192 return new Error('Material-UI: You have provided the `disableShrink` prop ' + 'with a variant other than `indeterminate`. This will have no effect.');
193 }
194
195 return null;
196 }),
197
198 /**
199 * The size of the circle.
200 * If using a number, the pixel unit is assumed.
201 * If using a string, you need to provide the CSS unit, e.g '3rem'.
202 */
203 size: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
204
205 /**
206 * @ignore
207 */
208 style: PropTypes.object,
209
210 /**
211 * The thickness of the circle.
212 */
213 thickness: PropTypes.number,
214
215 /**
216 * The value of the progress indicator for the determinate variant.
217 * Value between 0 and 100.
218 */
219 value: PropTypes.number,
220
221 /**
222 * The variant to use.
223 * Use indeterminate when there is no progress value.
224 */
225 variant: chainPropTypes(PropTypes.oneOf(['determinate', 'indeterminate', 'static']), props => {
226 const {
227 variant
228 } = props;
229
230 if (variant === 'static') {
231 throw new Error('Material-UI: `variant="static"` was deprecated. Use `variant="determinate"` instead.');
232 }
233
234 return null;
235 })
236} : void 0;
237export default withStyles(styles, {
238 name: 'MuiCircularProgress',
239 flip: false
240})(CircularProgress);
\No newline at end of file