All files / react-native-web/src/exports/ActivityIndicator index.js

100% Statements 10/10
100% Branches 11/11
100% Functions 2/2
100% Lines 10/10

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117                                1x   1x 32x                           1x               16x     16x                         16x                                         1x   1x                                               1x                        
/**
 * Copyright (c) Nicolas Gallagher.
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */
 
import type { ViewProps } from '../View';
 
import * as React from 'react';
import StyleSheet from '../StyleSheet';
import View from '../View';
 
const accessibilityValue = { max: 1, min: 0 };
 
const createSvgCircle = (style) => (
  <circle cx="16" cy="16" fill="none" r="14" strokeWidth="4" style={style} />
);
 
type ActivityIndicatorProps = {
  ...ViewProps,
  animating?: boolean,
  color?: ?string,
  hidesWhenStopped?: boolean,
  size?: 'small' | 'large' | number
};
 
const ActivityIndicator: React.AbstractComponent<
  ActivityIndicatorProps,
  React.ElementRef<typeof View>
> = React.forwardRef((props, forwardedRef) => {
  const {
    animating = true,
    color = '#1976D2',
    hidesWhenStopped = true,
    size = 'small',
    style,
    ...other
  } = props;
 
  const svg = (
    <svg height="100%" viewBox="0 0 32 32" width="100%">
      {createSvgCircle({
        stroke: color,
        opacity: 0.2
      })}
      {createSvgCircle({
        stroke: color,
        strokeDasharray: 80,
        strokeDashoffset: 60
      })}
    </svg>
  );
 
  return (
    <View
      {...other}
      accessibilityRole="progressbar"
      accessibilityValue={accessibilityValue}
      ref={forwardedRef}
      style={[styles.container, style]}
    >
      <View
        children={svg}
        style={[
          typeof size === 'number' ? { height: size, width: size } : indicatorSizes[size],
          styles.animation,
          !animating && styles.animationPause,
          !animating && hidesWhenStopped && styles.hidesWhenStopped
        ]}
      />
    </View>
  );
});
 
ActivityIndicator.displayName = 'ActivityIndicator';
 
const styles = StyleSheet.create({
  container: {
    alignItems: 'center',
    justifyContent: 'center'
  },
  hidesWhenStopped: {
    visibility: 'hidden'
  },
  animation: {
    animationDuration: '0.75s',
    animationKeyframes: [
      {
        '0%': { transform: [{ rotate: '0deg' }] },
        '100%': { transform: [{ rotate: '360deg' }] }
      }
    ],
    animationTimingFunction: 'linear',
    animationIterationCount: 'infinite'
  },
  animationPause: {
    animationPlayState: 'paused'
  }
});
 
const indicatorSizes = StyleSheet.create({
  small: {
    width: 20,
    height: 20
  },
  large: {
    width: 36,
    height: 36
  }
});
 
export default ActivityIndicator;