text: /**
   * 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.
   *
   * @format
   * @flow strict-local
   */
  
  'use strict';
  
  const Platform = require('../../Utilities/Platform');
  import SliderNativeComponent from './SliderNativeComponent';
  const React = require('react');
  const StyleSheet = require('../../StyleSheet/StyleSheet');
  
  import type {ImageSource} from '../../Image/ImageSource';
  import type {ViewStyleProp} from '../../StyleSheet/StyleSheet';
  import type {ColorValue} from '../../StyleSheet/StyleSheetTypes';
  import type {ViewProps} from '../View/ViewPropTypes';
  import type {SyntheticEvent} from '../../Types/CoreEventTypes';
  
  type Event = SyntheticEvent<
    $ReadOnly<{|
      value: number,
      /**
       * Android Only.
       */
      fromUser?: boolean,
    |}>,
  >;
  
  type IOSProps = $ReadOnly<{|
    /**
     * Assigns a single image for the track. Only static images are supported.
     * The center pixel of the image will be stretched to fill the track.
     */
    trackImage?: ?ImageSource,
  
    /**
     * Assigns a minimum track image. Only static images are supported. The
     * rightmost pixel of the image will be stretched to fill the track.
     */
    minimumTrackImage?: ?ImageSource,
  
    /**
     * Assigns a maximum track image. Only static images are supported. The
     * leftmost pixel of the image will be stretched to fill the track.
     */
    maximumTrackImage?: ?ImageSource,
  
    /**
     * Sets an image for the thumb. Only static images are supported.
     */
    thumbImage?: ?ImageSource,
  |}>;
  
  type Props = $ReadOnly<{|
    ...ViewProps,
    ...IOSProps,
  
    /**
     * Used to style and layout the `Slider`.  See `StyleSheet.js` and
     * `DeprecatedViewStylePropTypes.js` for more info.
     */
    style?: ?ViewStyleProp,
  
    /**
     * Initial value of the slider. The value should be between minimumValue
     * and maximumValue, which default to 0 and 1 respectively.
     * Default value is 0.
     *
     * *This is not a controlled component*, you don't need to update the
     * value during dragging.
     */
    value?: ?number,
  
    /**
     * Step value of the slider. The value should be
     * between 0 and (maximumValue - minimumValue).
     * Default value is 0.
     */
    step?: ?number,
  
    /**
     * Initial minimum value of the slider. Default value is 0.
     */
    minimumValue?: ?number,
  
    /**
     * Initial maximum value of the slider. Default value is 1.
     */
    maximumValue?: ?number,
  
    /**
     * The color used for the track to the left of the button.
     * Overrides the default blue gradient image on iOS.
     */
    minimumTrackTintColor?: ?ColorValue,
  
    /**
     * The color used for the track to the right of the button.
     * Overrides the default blue gradient image on iOS.
     */
    maximumTrackTintColor?: ?ColorValue,
    /**
     * The color used to tint the default thumb images on iOS, or the
     * color of the foreground switch grip on Android.
     */
    thumbTintColor?: ?ColorValue,
  
    /**
     * If true the user won't be able to move the slider.
     * Default value is false.
     */
    disabled?: ?boolean,
  
    /**
     * Callback continuously called while the user is dragging the slider.
     */
    onValueChange?: ?(value: number) => void,
  
    /**
     * Callback that is called when the user releases the slider,
     * regardless if the value has changed. The current value is passed
     * as an argument to the callback handler.
     */
    onSlidingComplete?: ?(value: number) => void,
  
    /**
     * Used to locate this view in UI automation tests.
     */
    testID?: ?string,
  |}>;
  
  /**
   * A component used to select a single value from a range of values.
   *
   * ### Usage
   *
   * The example below shows how to use `Slider` to change
   * a value used by `Text`. The value is stored using
   * the state of the root component (`App`). The same component
   * subscribes to the `onValueChange`  of `Slider` and changes
   * the value using `setState`.
   *
   *```
   * import React from 'react';
   * import { StyleSheet, Text, View, Slider } from 'react-native';
   *
   * export default class App extends React.Component {
   *   constructor(props) {
   *     super(props);
   *     this.state = {
   *       value: 50
   *     }
   *   }
   *
   *   change(value) {
   *     this.setState(() => {
   *       return {
   *         value: parseFloat(value)
   *       };
   *     });
   *   }
   *
   *   render() {
   *     const {value} = this.state;
   *     return (
   *       <View style={styles.container}>
   *         <Text style={styles.text}>{String(value)}</Text>
   *         <Slider
   *           step={1}
   *           maximumValue={100}
   *           onValueChange={this.change.bind(this)}
   *           value={value} />
   *       </View>
   *     );
   *   }
   * }
   *
   * const styles = StyleSheet.create({
   *   container: {
   *     flex: 1,
   *     flexDirection: 'column',
   *     justifyContent: 'center'
   *   },
   *   text: {
   *     fontSize: 50,
   *     textAlign: 'center'
   *   }
   * });
   *```
   *
   */
  const Slider = (
    props: Props,
    forwardedRef?: ?React.Ref<typeof SliderNativeComponent>,
  ) => {
    const style = StyleSheet.compose(
      styles.slider,
      props.style,
    );
  
    const {
      disabled = false,
      value = 0.5,
      minimumValue = 0,
      maximumValue = 1,
      step = 0,
      onValueChange,
      onSlidingComplete,
      ...localProps
    } = props;
  
    const onValueChangeEvent = onValueChange
      ? (event: Event) => {
          let userEvent = true;
          if (Platform.OS === 'android') {
            // On Android there's a special flag telling us the user is
            // dragging the slider.
            userEvent =
              event.nativeEvent.fromUser != null && event.nativeEvent.fromUser;
          }
          userEvent && onValueChange(event.nativeEvent.value);
        }
      : null;
  
    const onChangeEvent = onValueChangeEvent;
    const onSlidingCompleteEvent = onSlidingComplete
      ? (event: Event) => {
          onSlidingComplete(event.nativeEvent.value);
        }
      : null;
  
    return (
      <SliderNativeComponent
        {...localProps}
        // TODO: Reconcile these across the two platforms.
        enabled={!disabled}
        disabled={disabled}
        maximumValue={maximumValue}
        minimumValue={minimumValue}
        onChange={onChangeEvent}
        onResponderTerminationRequest={() => false}
        onSlidingComplete={onSlidingCompleteEvent}
        onStartShouldSetResponder={() => true}
        onValueChange={onValueChangeEvent}
        ref={forwardedRef}
        step={step}
        style={style}
        value={value}
      />
    );
  };
  
  const SliderWithRef: React.AbstractComponent<
    Props,
    React.ElementRef<typeof SliderNativeComponent>,
  > = React.forwardRef(Slider);
  
  let styles;
  if (
    Platform.OS === 'ios' ||
    Platform.OS === 'macos' /* TODO(macOS ISS#2323203) */
  ) {
    styles = StyleSheet.create({
      slider: {
        height: 40,
      },
    });
  } else {
    styles = StyleSheet.create({
      slider: {},
    });
  }
  
  module.exports = SliderWithRef;
  