UNPKG

4.63 kBJavaScriptView Raw
1import _extends from "@babel/runtime/helpers/esm/extends";
2import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3import * as React from 'react';
4import clsx from 'clsx';
5import PropTypes from 'prop-types';
6import { alpha, withStyles } from '@material-ui/core/styles';
7export const styles = theme => ({
8 /* Styles applied to the root element. */
9 root: {
10 display: 'block',
11 // Create a "on paper" color with sufficient contrast retaining the color
12 backgroundColor: alpha(theme.palette.text.primary, theme.palette.type === 'light' ? 0.11 : 0.13),
13 height: '1.2em'
14 },
15
16 /* Styles applied to the root element if `variant="text"`. */
17 text: {
18 marginTop: 0,
19 marginBottom: 0,
20 height: 'auto',
21 transformOrigin: '0 60%',
22 transform: 'scale(1, 0.60)',
23 borderRadius: theme.shape.borderRadius,
24 '&:empty:before': {
25 content: '"\\00a0"'
26 }
27 },
28
29 /* Styles applied to the root element if `variant="rect"`. */
30 rect: {},
31
32 /* Styles applied to the root element if `variant="circle"`. */
33 circle: {
34 borderRadius: '50%'
35 },
36
37 /* Styles applied to the root element if `animation="pulse"`. */
38 pulse: {
39 animation: '$pulse 1.5s ease-in-out 0.5s infinite'
40 },
41 '@keyframes pulse': {
42 '0%': {
43 opacity: 1
44 },
45 '50%': {
46 opacity: 0.4
47 },
48 '100%': {
49 opacity: 1
50 }
51 },
52
53 /* Styles applied to the root element if `animation="wave"`. */
54 wave: {
55 position: 'relative',
56 overflow: 'hidden',
57 '&::after': {
58 animation: '$wave 1.6s linear 0.5s infinite',
59 background: `linear-gradient(90deg, transparent, ${theme.palette.action.hover}, transparent)`,
60 content: '""',
61 position: 'absolute',
62 transform: 'translateX(-100%)',
63 // Avoid flash during server-side hydration
64 bottom: 0,
65 left: 0,
66 right: 0,
67 top: 0
68 }
69 },
70 '@keyframes wave': {
71 '0%': {
72 transform: 'translateX(-100%)'
73 },
74 '60%': {
75 // +0.5s of delay between each loop
76 transform: 'translateX(100%)'
77 },
78 '100%': {
79 transform: 'translateX(100%)'
80 }
81 },
82
83 /* Styles applied when the component is passed children. */
84 withChildren: {
85 '& > *': {
86 visibility: 'hidden'
87 }
88 },
89
90 /* Styles applied when the component is passed children and no width. */
91 fitContent: {
92 maxWidth: 'fit-content'
93 },
94
95 /* Styles applied when the component is passed children and no height. */
96 heightAuto: {
97 height: 'auto'
98 }
99});
100const Skeleton = /*#__PURE__*/React.forwardRef(function Skeleton(props, ref) {
101 const {
102 animation = 'pulse',
103 classes,
104 className,
105 component: Component = 'span',
106 height,
107 variant = 'text',
108 width
109 } = props,
110 other = _objectWithoutPropertiesLoose(props, ["animation", "classes", "className", "component", "height", "variant", "width"]);
111
112 const hasChildren = Boolean(other.children);
113 return /*#__PURE__*/React.createElement(Component, _extends({
114 ref: ref,
115 className: clsx(classes.root, classes[variant], className, hasChildren && [classes.withChildren, !width && classes.fitContent, !height && classes.heightAuto], animation !== false && classes[animation])
116 }, other, {
117 style: _extends({
118 width,
119 height
120 }, other.style)
121 }));
122});
123process.env.NODE_ENV !== "production" ? Skeleton.propTypes = {
124 /**
125 * The animation.
126 * If `false` the animation effect is disabled.
127 */
128 animation: PropTypes.oneOf(['pulse', 'wave', false]),
129
130 /**
131 * Optional children to infer width and height from.
132 */
133 children: PropTypes.node,
134
135 /**
136 * Override or extend the styles applied to the component.
137 * See [CSS API](#css) below for more details.
138 */
139 classes: PropTypes.object.isRequired,
140
141 /**
142 * @ignore
143 */
144 className: PropTypes.string,
145
146 /**
147 * The component used for the root node.
148 * Either a string to use a HTML element or a component.
149 */
150 component: PropTypes
151 /* @typescript-to-proptypes-ignore */
152 .elementType,
153
154 /**
155 * Height of the skeleton.
156 * Useful when you don't want to adapt the skeleton to a text element but for instance a card.
157 */
158 height: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
159
160 /**
161 * The type of content that will be rendered.
162 */
163 variant: PropTypes.oneOf(['text', 'rect', 'circle']),
164
165 /**
166 * Width of the skeleton.
167 * Useful when the skeleton is inside an inline element with no width of its own.
168 */
169 width: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
170} : void 0;
171export default withStyles(styles, {
172 name: 'MuiSkeleton'
173})(Skeleton);
\No newline at end of file