Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/35825

Changelog:
[iOS][Removed] - removed Slider module
[Android][Removed] - removed Slider module

Reviewed By: cortinico

Differential Revision: D42394124

fbshipit-source-id: 92ba3bc50d16996a597148fa2f8178e6bd6d8eb7
This commit is contained in:
Ruslan Lesiutin 2023-01-16 02:42:18 -08:00 коммит произвёл Facebook GitHub Bot
Родитель b40beebd26
Коммит 465e937533
45 изменённых файлов: 18 добавлений и 2696 удалений

2
BUCK
Просмотреть файл

@ -522,7 +522,6 @@ rn_apple_xplat_cxx_library(
react_fabric_component_plugin_provider("ScrollView", "RCTScrollViewCls"),
react_fabric_component_plugin_provider("PullToRefreshView", "RCTPullToRefreshViewCls"),
react_fabric_component_plugin_provider("ActivityIndicatorView", "RCTActivityIndicatorViewCls"),
react_fabric_component_plugin_provider("Slider", "RCTSliderCls"),
react_fabric_component_plugin_provider("Switch", "RCTSwitchCls"),
react_fabric_component_plugin_provider("UnimplementedNativeView", "RCTUnimplementedNativeViewCls"),
react_fabric_component_plugin_provider("Paragraph", "RCTParagraphCls"),
@ -563,7 +562,6 @@ rn_apple_xplat_cxx_library(
exported_deps = [
react_native_xplat_target("react/renderer/animations:animations"),
react_native_xplat_target("react/renderer/components/scrollview:scrollview"),
react_native_xplat_target("react/renderer/components/slider:slider"),
react_native_xplat_target("react/renderer/components/safeareaview:safeareaview"),
react_native_xplat_target("react/renderer/components/modal:modal"),
react_native_xplat_target("react/renderer/components/unimplementedview:unimplementedview"),

132
Libraries/Components/Slider/Slider.d.ts поставляемый
Просмотреть файл

@ -1,132 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import type * as React from 'react';
import {Constructor} from '../../../types/private/Utilities';
import {ImageURISource} from '../../Image/ImageSource';
import {NativeMethods} from '../../../types/public/ReactNativeTypes';
import {ColorValue, StyleProp} from '../../StyleSheet/StyleSheet';
import {ViewStyle} from '../../StyleSheet/StyleSheetTypes';
import {ViewProps} from '../View/ViewPropTypes';
export interface SliderPropsAndroid extends ViewProps {
/**
* Color of the foreground switch grip.
*/
thumbTintColor?: ColorValue | undefined;
}
export interface SliderPropsIOS extends ViewProps {
/**
* Assigns a maximum track image. Only static images are supported.
* The leftmost pixel of the image will be stretched to fill the track.
*/
maximumTrackImage?: ImageURISource | undefined;
/**
* Assigns a minimum track image. Only static images are supported.
* The rightmost pixel of the image will be stretched to fill the track.
*/
minimumTrackImage?: ImageURISource | undefined;
/**
* Sets an image for the thumb. Only static images are supported.
*/
thumbImage?: ImageURISource | undefined;
/**
* 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?: ImageURISource | undefined;
}
export interface SliderProps extends SliderPropsIOS, SliderPropsAndroid {
/**
* If true the user won't be able to move the slider.
* Default value is false.
*/
disabled?: boolean | undefined;
/**
* The color used for the track to the right of the button.
* Overrides the default blue gradient image.
*/
maximumTrackTintColor?: ColorValue | undefined;
/**
* Initial maximum value of the slider. Default value is 1.
*/
maximumValue?: number | undefined;
/**
* The color used for the track to the left of the button.
* Overrides the default blue gradient image.
*/
minimumTrackTintColor?: ColorValue | undefined;
/**
* Initial minimum value of the slider. Default value is 0.
*/
minimumValue?: number | undefined;
/**
* Callback called when the user finishes changing the value (e.g. when the slider is released).
*/
onSlidingComplete?: ((value: number) => void) | undefined;
/**
* Callback continuously called while the user is dragging the slider.
*/
onValueChange?: ((value: number) => void) | undefined;
/**
* Step value of the slider. The value should be between 0 and (maximumValue - minimumValue). Default value is 0.
*/
step?: number | undefined;
/**
* Used to style and layout the Slider. See StyleSheet.js for more info.
*/
style?: StyleProp<ViewStyle> | undefined;
/**
* Used to locate this view in UI automation tests.
*/
testID?: string | undefined;
/**
* 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 | undefined;
}
/**
* A component used to select a single value from a range of values.
*/
declare class SliderComponent extends React.Component<SliderProps> {}
declare const SliderBase: Constructor<NativeMethods> & typeof SliderComponent;
/**
* Slider has been extracted from react-native core and will be removed in a future release.
* It can now be installed and imported from `@react-native-community/slider` instead of 'react-native'.
* @see https://github.com/callstack/react-native-slider
* @deprecated
*/
export class Slider extends SliderBase {}
/** SliderIOS has been removed from react-native.
* It can now be installed and imported from `@react-native-community/slider` instead of 'react-native'.
* @see https://github.com/callstack/react-native-slider
* @deprecated
*/
export type SliderIOS = Slider;

Просмотреть файл

@ -1,282 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and 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
*/
import type {ImageSource} from '../../Image/ImageSource';
import type {SyntheticEvent} from '../../Types/CoreEventTypes';
import type {AccessibilityState} from '../View/ViewAccessibility';
import type {ViewProps} from '../View/ViewPropTypes';
import StyleSheet, {
type ColorValue,
type ViewStyleProp,
} from '../../StyleSheet/StyleSheet';
import Platform from '../../Utilities/Platform';
import SliderNativeComponent from './SliderNativeComponent';
import * as React from 'react';
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,
/**
Indicates to accessibility services that UI Component is in a specific State.
*/
accessibilityState?: ?AccessibilityState,
|}>;
/**
* 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 {
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 onSlidingCompleteEvent = onSlidingComplete
? (event: Event) => {
onSlidingComplete(event.nativeEvent.value);
}
: null;
const disabled =
props.disabled === true || props.accessibilityState?.disabled === true;
const accessibilityState = disabled
? {...props.accessibilityState, disabled: true}
: props.accessibilityState;
return (
<SliderNativeComponent
{...localProps}
accessibilityState={accessibilityState}
// TODO: Reconcile these across the two platforms.
enabled={!disabled}
disabled={disabled}
maximumValue={maximumValue}
minimumValue={minimumValue}
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') {
styles = StyleSheet.create({
slider: {
height: 40,
},
});
} else {
styles = StyleSheet.create({
slider: {},
});
}
module.exports = SliderWithRef;

Просмотреть файл

@ -1,56 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and 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
*/
import type {ImageSource} from '../../Image/ImageSource';
import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes';
import type {ColorValue} from '../../StyleSheet/StyleSheet';
import type {
BubblingEventHandler,
DirectEventHandler,
Double,
WithDefault,
} from '../../Types/CodegenTypes';
import type {ViewProps} from '../View/ViewPropTypes';
import codegenNativeComponent from '../../Utilities/codegenNativeComponent';
type Event = $ReadOnly<{|
value: Double,
fromUser?: boolean,
|}>;
type NativeProps = $ReadOnly<{|
...ViewProps,
// Props
disabled?: WithDefault<boolean, false>,
enabled?: WithDefault<boolean, true>,
maximumTrackImage?: ?ImageSource,
maximumTrackTintColor?: ?ColorValue,
maximumValue?: WithDefault<Double, 1>,
minimumTrackImage?: ?ImageSource,
minimumTrackTintColor?: ?ColorValue,
minimumValue?: WithDefault<Double, 0>,
step?: WithDefault<Double, 0>,
testID?: WithDefault<string, ''>,
thumbImage?: ?ImageSource,
thumbTintColor?: ?ColorValue,
trackImage?: ?ImageSource,
value?: WithDefault<Double, 0>,
// Events
onValueChange?: ?BubblingEventHandler<Event>,
onSlidingComplete?: ?DirectEventHandler<Event>,
|}>;
export default (codegenNativeComponent<NativeProps>('Slider', {
interfaceOnly: true,
paperComponentName: 'RCTSlider',
}): HostComponent<NativeProps>);

Просмотреть файл

@ -1,37 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
* @format
*/
import Slider from '../Slider/Slider';
import * as React from 'react';
import ReactTestRenderer from 'react-test-renderer';
describe('<Slider />', () => {
it('should render as expected', () => {
expect(ReactTestRenderer.create(<Slider />)).toMatchSnapshot();
});
it('should set disabled as false', () => {
// Slider component should set disabled prop as false by default
expect(ReactTestRenderer.create(<Slider />)).toMatchSnapshot();
expect(
ReactTestRenderer.create(
<Slider accessibilityState={{disabled: false}} />,
),
).toMatchSnapshot();
});
it('should set disabled as true', () => {
expect(ReactTestRenderer.create(<Slider disabled />)).toMatchSnapshot();
expect(
ReactTestRenderer.create(
<Slider accessibilityState={{disabled: true}} />,
),
).toMatchSnapshot();
});
});

Просмотреть файл

@ -1,116 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<Slider /> should render as expected 1`] = `
<RCTSlider
disabled={false}
enabled={true}
maximumValue={1}
minimumValue={0}
onResponderTerminationRequest={[Function]}
onSlidingComplete={null}
onStartShouldSetResponder={[Function]}
onValueChange={null}
step={0}
style={
Object {
"height": 40,
}
}
value={0.5}
/>
`;
exports[`<Slider /> should set disabled as false 1`] = `
<RCTSlider
disabled={false}
enabled={true}
maximumValue={1}
minimumValue={0}
onResponderTerminationRequest={[Function]}
onSlidingComplete={null}
onStartShouldSetResponder={[Function]}
onValueChange={null}
step={0}
style={
Object {
"height": 40,
}
}
value={0.5}
/>
`;
exports[`<Slider /> should set disabled as false 2`] = `
<RCTSlider
accessibilityState={
Object {
"disabled": false,
}
}
disabled={false}
enabled={true}
maximumValue={1}
minimumValue={0}
onResponderTerminationRequest={[Function]}
onSlidingComplete={null}
onStartShouldSetResponder={[Function]}
onValueChange={null}
step={0}
style={
Object {
"height": 40,
}
}
value={0.5}
/>
`;
exports[`<Slider /> should set disabled as true 1`] = `
<RCTSlider
accessibilityState={
Object {
"disabled": true,
}
}
disabled={true}
enabled={false}
maximumValue={1}
minimumValue={0}
onResponderTerminationRequest={[Function]}
onSlidingComplete={null}
onStartShouldSetResponder={[Function]}
onValueChange={null}
step={0}
style={
Object {
"height": 40,
}
}
value={0.5}
/>
`;
exports[`<Slider /> should set disabled as true 2`] = `
<RCTSlider
accessibilityState={
Object {
"disabled": true,
}
}
disabled={true}
enabled={false}
maximumValue={1}
minimumValue={0}
onResponderTerminationRequest={[Function]}
onSlidingComplete={null}
onStartShouldSetResponder={[Function]}
onValueChange={null}
step={0}
style={
Object {
"height": 40,
}
}
value={0.5}
/>
`;

Просмотреть файл

@ -34,7 +34,6 @@ Class<RCTComponentViewProtocol> RCTSafeAreaViewCls(void) __attribute__((used));
Class<RCTComponentViewProtocol> RCTScrollViewCls(void) __attribute__((used));
Class<RCTComponentViewProtocol> RCTPullToRefreshViewCls(void) __attribute__((used));
Class<RCTComponentViewProtocol> RCTActivityIndicatorViewCls(void) __attribute__((used));
Class<RCTComponentViewProtocol> RCTSliderCls(void) __attribute__((used));
Class<RCTComponentViewProtocol> RCTSwitchCls(void) __attribute__((used));
Class<RCTComponentViewProtocol> RCTUnimplementedNativeViewCls(void) __attribute__((used));
Class<RCTComponentViewProtocol> RCTParagraphCls(void) __attribute__((used));

Просмотреть файл

@ -22,7 +22,6 @@ Class<RCTComponentViewProtocol> RCTFabricComponentsProvider(const char *name) {
{"ScrollView", RCTScrollViewCls},
{"PullToRefreshView", RCTPullToRefreshViewCls},
{"ActivityIndicatorView", RCTActivityIndicatorViewCls},
{"Slider", RCTSliderCls},
{"Switch", RCTSwitchCls},
{"UnimplementedNativeView", RCTUnimplementedNativeViewCls},
{"Paragraph", RCTParagraphCls},

Просмотреть файл

@ -1,21 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <UIKit/UIKit.h>
#import <React/RCTViewComponentView.h>
NS_ASSUME_NONNULL_BEGIN
/**
* UIView class for root <Slider> component.
*/
@interface RCTSliderComponentView : RCTViewComponentView
@end
NS_ASSUME_NONNULL_END

Просмотреть файл

@ -1,352 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTSliderComponentView.h"
#import <React/RCTConversions.h>
#import <React/RCTImageResponseDelegate.h>
#import <React/RCTImageResponseObserverProxy.h>
#import <react/renderer/components/rncore/EventEmitters.h>
#import <react/renderer/components/rncore/Props.h>
#import <react/renderer/components/slider/SliderComponentDescriptor.h>
#import "RCTFabricComponentsPlugins.h"
using namespace facebook::react;
@interface RCTSliderComponentView () <RCTImageResponseDelegate>
@end
@implementation RCTSliderComponentView {
UISlider *_sliderView;
float _previousValue;
UIImage *_trackImage;
UIImage *_minimumTrackImage;
UIImage *_maximumTrackImage;
UIImage *_thumbImage;
ImageResponseObserverCoordinator const *_trackImageCoordinator;
ImageResponseObserverCoordinator const *_minimumTrackImageCoordinator;
ImageResponseObserverCoordinator const *_maximumTrackImageCoordinator;
ImageResponseObserverCoordinator const *_thumbImageCoordinator;
RCTImageResponseObserverProxy _trackImageResponseObserverProxy;
RCTImageResponseObserverProxy _minimumTrackImageResponseObserverProxy;
RCTImageResponseObserverProxy _maximumTrackImageResponseObserverProxy;
RCTImageResponseObserverProxy _thumbImageResponseObserverProxy;
}
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
static const auto defaultProps = std::make_shared<const SliderProps>();
_props = defaultProps;
_sliderView = [[UISlider alloc] initWithFrame:self.bounds];
[_sliderView addTarget:self action:@selector(onChange:) forControlEvents:UIControlEventValueChanged];
[_sliderView addTarget:self
action:@selector(sliderTouchEnd:)
forControlEvents:(UIControlEventTouchUpInside | UIControlEventTouchUpOutside | UIControlEventTouchCancel)];
_sliderView.value = (float)defaultProps->value;
_trackImageResponseObserverProxy = RCTImageResponseObserverProxy(self);
_minimumTrackImageResponseObserverProxy = RCTImageResponseObserverProxy(self);
_maximumTrackImageResponseObserverProxy = RCTImageResponseObserverProxy(self);
_thumbImageResponseObserverProxy = RCTImageResponseObserverProxy(self);
self.contentView = _sliderView;
}
return self;
}
// Recycling still doesn't work 100% properly
// TODO: T40099998 implement recycling properly for Fabric Slider component
- (void)prepareForRecycle
{
[super prepareForRecycle];
self.trackImageCoordinator = nullptr;
self.minimumTrackImageCoordinator = nullptr;
self.maximumTrackImageCoordinator = nullptr;
self.thumbImageCoordinator = nullptr;
// Tint colors will be taken care of when props are set again - we just
// need to make sure that image properties are reset here
[_sliderView setMinimumTrackImage:nil forState:UIControlStateNormal];
[_sliderView setMaximumTrackImage:nil forState:UIControlStateNormal];
if (_thumbImage) {
[_sliderView setThumbImage:nil forState:UIControlStateNormal];
}
_trackImage = nil;
_minimumTrackImage = nil;
_maximumTrackImage = nil;
_thumbImage = nil;
const auto &props = *std::static_pointer_cast<const SliderProps>(_props);
_sliderView.value = (float)props.value;
_previousValue = (float)props.value;
}
#pragma mark - RCTComponentViewProtocol
+ (ComponentDescriptorProvider)componentDescriptorProvider
{
return concreteComponentDescriptorProvider<SliderComponentDescriptor>();
}
- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
{
const auto &oldSliderProps = *std::static_pointer_cast<const SliderProps>(_props);
const auto &newSliderProps = *std::static_pointer_cast<const SliderProps>(props);
// `minimumValue`
if (oldSliderProps.minimumValue != newSliderProps.minimumValue) {
_sliderView.minimumValue = (float)newSliderProps.minimumValue;
}
// `maximumValue`
if (oldSliderProps.maximumValue != newSliderProps.maximumValue) {
_sliderView.maximumValue = (float)newSliderProps.maximumValue;
}
// `value`
if (oldSliderProps.value != newSliderProps.value) {
_sliderView.value = (float)newSliderProps.value;
_previousValue = (float)newSliderProps.value;
}
// `disabled`
if (oldSliderProps.disabled != newSliderProps.disabled) {
_sliderView.enabled = !newSliderProps.disabled;
}
// `thumbTintColor`
if (oldSliderProps.thumbTintColor != newSliderProps.thumbTintColor) {
_sliderView.thumbTintColor = RCTUIColorFromSharedColor(newSliderProps.thumbTintColor);
}
// `minimumTrackTintColor`
if (oldSliderProps.minimumTrackTintColor != newSliderProps.minimumTrackTintColor) {
_sliderView.minimumTrackTintColor = RCTUIColorFromSharedColor(newSliderProps.minimumTrackTintColor);
}
// `maximumTrackTintColor`
if (oldSliderProps.maximumTrackTintColor != newSliderProps.maximumTrackTintColor) {
_sliderView.maximumTrackTintColor = RCTUIColorFromSharedColor(newSliderProps.maximumTrackTintColor);
}
[super updateProps:props oldProps:oldProps];
}
- (void)updateState:(facebook::react::State::Shared const &)state
oldState:(facebook::react::State::Shared const &)oldState
{
auto _state = std::static_pointer_cast<SliderShadowNode::ConcreteState const>(state);
auto _oldState = std::static_pointer_cast<SliderShadowNode::ConcreteState const>(oldState);
auto data = _state->getData();
bool havePreviousData = _oldState != nullptr;
auto getCoordinator = [](ImageRequest const *request) -> ImageResponseObserverCoordinator const * {
if (request) {
return &request->getObserverCoordinator();
} else {
return nullptr;
}
};
if (!havePreviousData || data.getTrackImageSource() != _oldState->getData().getTrackImageSource()) {
self.trackImageCoordinator = getCoordinator(&data.getTrackImageRequest());
}
if (!havePreviousData || data.getMinimumTrackImageSource() != _oldState->getData().getMinimumTrackImageSource()) {
self.minimumTrackImageCoordinator = getCoordinator(&data.getMinimumTrackImageRequest());
}
if (!havePreviousData || data.getMaximumTrackImageSource() != _oldState->getData().getMaximumTrackImageSource()) {
self.maximumTrackImageCoordinator = getCoordinator(&data.getMaximumTrackImageRequest());
}
if (!havePreviousData || data.getThumbImageSource() != _oldState->getData().getThumbImageSource()) {
self.thumbImageCoordinator = getCoordinator(&data.getThumbImageRequest());
}
}
- (void)setTrackImageCoordinator:(const ImageResponseObserverCoordinator *)coordinator
{
if (_trackImageCoordinator) {
_trackImageCoordinator->removeObserver(_trackImageResponseObserverProxy);
}
_trackImageCoordinator = coordinator;
if (_trackImageCoordinator) {
_trackImageCoordinator->addObserver(_trackImageResponseObserverProxy);
}
}
- (void)setMinimumTrackImageCoordinator:(const ImageResponseObserverCoordinator *)coordinator
{
if (_minimumTrackImageCoordinator) {
_minimumTrackImageCoordinator->removeObserver(_minimumTrackImageResponseObserverProxy);
}
_minimumTrackImageCoordinator = coordinator;
if (_minimumTrackImageCoordinator) {
_minimumTrackImageCoordinator->addObserver(_minimumTrackImageResponseObserverProxy);
}
}
- (void)setMaximumTrackImageCoordinator:(const ImageResponseObserverCoordinator *)coordinator
{
if (_maximumTrackImageCoordinator) {
_maximumTrackImageCoordinator->removeObserver(_maximumTrackImageResponseObserverProxy);
}
_maximumTrackImageCoordinator = coordinator;
if (_maximumTrackImageCoordinator) {
_maximumTrackImageCoordinator->addObserver(_maximumTrackImageResponseObserverProxy);
}
}
- (void)setThumbImageCoordinator:(const ImageResponseObserverCoordinator *)coordinator
{
if (_thumbImageCoordinator) {
_thumbImageCoordinator->removeObserver(_thumbImageResponseObserverProxy);
}
_thumbImageCoordinator = coordinator;
if (_thumbImageCoordinator) {
_thumbImageCoordinator->addObserver(_thumbImageResponseObserverProxy);
}
}
- (void)setTrackImage:(UIImage *)trackImage
{
if ([trackImage isEqual:_trackImage]) {
return;
}
_trackImage = trackImage;
_minimumTrackImage = nil;
_maximumTrackImage = nil;
CGFloat width = trackImage.size.width / 2;
UIImage *minimumTrackImage = [trackImage resizableImageWithCapInsets:(UIEdgeInsets){0, width, 0, width}
resizingMode:UIImageResizingModeStretch];
UIImage *maximumTrackImage = [trackImage resizableImageWithCapInsets:(UIEdgeInsets){0, width, 0, width}
resizingMode:UIImageResizingModeStretch];
[_sliderView setMinimumTrackImage:minimumTrackImage forState:UIControlStateNormal];
[_sliderView setMaximumTrackImage:maximumTrackImage forState:UIControlStateNormal];
}
- (void)setMinimumTrackImage:(UIImage *)minimumTrackImage
{
if ([minimumTrackImage isEqual:_minimumTrackImage] && _trackImage == nil) {
return;
}
_trackImage = nil;
_minimumTrackImage = minimumTrackImage;
_minimumTrackImage =
[_minimumTrackImage resizableImageWithCapInsets:(UIEdgeInsets){0, _minimumTrackImage.size.width, 0, 0}
resizingMode:UIImageResizingModeStretch];
[_sliderView setMinimumTrackImage:_minimumTrackImage forState:UIControlStateNormal];
}
- (void)setMaximumTrackImage:(UIImage *)maximumTrackImage
{
if ([maximumTrackImage isEqual:_maximumTrackImage] && _trackImage == nil) {
return;
}
_trackImage = nil;
_maximumTrackImage = maximumTrackImage;
_maximumTrackImage =
[_maximumTrackImage resizableImageWithCapInsets:(UIEdgeInsets){0, 0, 0, _maximumTrackImage.size.width}
resizingMode:UIImageResizingModeStretch];
[_sliderView setMaximumTrackImage:_maximumTrackImage forState:UIControlStateNormal];
}
- (void)setThumbImage:(UIImage *)thumbImage
{
if ([thumbImage isEqual:_thumbImage]) {
return;
}
_thumbImage = thumbImage;
[_sliderView setThumbImage:thumbImage forState:UIControlStateNormal];
}
- (void)onChange:(UISlider *)sender
{
[self onChange:sender withContinuous:YES];
}
- (void)sliderTouchEnd:(UISlider *)sender
{
[self onChange:sender withContinuous:NO];
}
- (void)onChange:(UISlider *)sender withContinuous:(BOOL)continuous
{
float value = sender.value;
const auto &props = *std::static_pointer_cast<const SliderProps>(_props);
if (props.step > 0 && props.step <= (props.maximumValue - props.minimumValue)) {
value = (float)std::max(
props.minimumValue,
std::min(
props.maximumValue, props.minimumValue + round((value - props.minimumValue) / props.step) * props.step));
[_sliderView setValue:value animated:YES];
}
if (continuous && _previousValue != value) {
std::dynamic_pointer_cast<const SliderEventEmitter>(_eventEmitter)
->onValueChange(SliderEventEmitter::OnValueChange{.value = static_cast<Float>(value)});
}
if (!continuous) {
std::dynamic_pointer_cast<const SliderEventEmitter>(_eventEmitter)
->onSlidingComplete(SliderEventEmitter::OnSlidingComplete{.value = static_cast<Float>(value)});
}
_previousValue = value;
}
#pragma mark - RCTImageResponseDelegate
- (void)didReceiveImage:(UIImage *)image metadata:(id)metadata fromObserver:(void const *)observer
{
if (observer == &_trackImageResponseObserverProxy) {
self.trackImage = image;
} else if (observer == &_minimumTrackImageResponseObserverProxy) {
self.minimumTrackImage = image;
} else if (observer == &_maximumTrackImageResponseObserverProxy) {
self.maximumTrackImage = image;
} else if (observer == &_thumbImageResponseObserverProxy) {
self.thumbImage = image;
}
}
- (void)didReceiveProgress:(float)progress fromObserver:(void const *)observer
{
}
- (void)didReceiveFailureFromObserver:(void const *)observer
{
}
@end
Class<RCTComponentViewProtocol> RCTSliderCls(void)
{
return RCTSliderComponentView.class;
}

Просмотреть файл

@ -1,26 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <UIKit/UIKit.h>
#import <React/RCTComponent.h>
@interface RCTSlider : UISlider
@property (nonatomic, copy) RCTBubblingEventBlock onValueChange;
@property (nonatomic, copy) RCTDirectEventBlock onSlidingComplete;
@property (nonatomic, assign) float step;
@property (nonatomic, assign) float lastValue;
@property (nonatomic, strong) UIImage *trackImage;
@property (nonatomic, strong) UIImage *minimumTrackImage;
@property (nonatomic, strong) UIImage *maximumTrackImage;
@property (nonatomic, strong) UIImage *thumbImage;
@end

Просмотреть файл

@ -1,104 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTSlider.h"
@implementation RCTSlider {
float _unclippedValue;
}
- (void)setValue:(float)value
{
_unclippedValue = value;
super.value = value;
}
- (void)setMinimumValue:(float)minimumValue
{
super.minimumValue = minimumValue;
super.value = _unclippedValue;
}
- (void)setMaximumValue:(float)maximumValue
{
super.maximumValue = maximumValue;
super.value = _unclippedValue;
}
- (void)setTrackImage:(UIImage *)trackImage
{
if (trackImage != _trackImage) {
_trackImage = trackImage;
CGFloat width = trackImage.size.width / 2;
UIImage *minimumTrackImage = [trackImage resizableImageWithCapInsets:(UIEdgeInsets){0, width, 0, width}
resizingMode:UIImageResizingModeStretch];
UIImage *maximumTrackImage = [trackImage resizableImageWithCapInsets:(UIEdgeInsets){0, width, 0, width}
resizingMode:UIImageResizingModeStretch];
[self setMinimumTrackImage:minimumTrackImage forState:UIControlStateNormal];
[self setMaximumTrackImage:maximumTrackImage forState:UIControlStateNormal];
}
}
- (void)setMinimumTrackImage:(UIImage *)minimumTrackImage
{
_trackImage = nil;
minimumTrackImage =
[minimumTrackImage resizableImageWithCapInsets:(UIEdgeInsets){0, minimumTrackImage.size.width, 0, 0}
resizingMode:UIImageResizingModeStretch];
[self setMinimumTrackImage:minimumTrackImage forState:UIControlStateNormal];
}
- (UIImage *)minimumTrackImage
{
return [self thumbImageForState:UIControlStateNormal];
}
- (void)setMaximumTrackImage:(UIImage *)maximumTrackImage
{
_trackImage = nil;
maximumTrackImage =
[maximumTrackImage resizableImageWithCapInsets:(UIEdgeInsets){0, 0, 0, maximumTrackImage.size.width}
resizingMode:UIImageResizingModeStretch];
[self setMaximumTrackImage:maximumTrackImage forState:UIControlStateNormal];
}
- (UIImage *)maximumTrackImage
{
return [self thumbImageForState:UIControlStateNormal];
}
- (void)setThumbImage:(UIImage *)thumbImage
{
[self setThumbImage:thumbImage forState:UIControlStateNormal];
}
- (UIImage *)thumbImage
{
return [self thumbImageForState:UIControlStateNormal];
}
- (void)accessibilityIncrement
{
[super accessibilityIncrement];
if (_onSlidingComplete) {
_onSlidingComplete(@{
@"value" : @(self.value),
});
}
}
- (void)accessibilityDecrement
{
[super accessibilityDecrement];
if (_onSlidingComplete) {
_onSlidingComplete(@{
@"value" : @(self.value),
});
}
}
@end

Просмотреть файл

@ -1,12 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <React/RCTViewManager.h>
@interface RCTSliderManager : RCTViewManager
@end

Просмотреть файл

@ -1,91 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTSliderManager.h"
#import "RCTBridge.h"
#import "RCTSlider.h"
#import "UIView+React.h"
@implementation RCTSliderManager
RCT_EXPORT_MODULE()
- (UIView *)view
{
RCTSlider *slider = [RCTSlider new];
[slider addTarget:self action:@selector(sliderValueChanged:) forControlEvents:UIControlEventValueChanged];
[slider addTarget:self
action:@selector(sliderTouchEnd:)
forControlEvents:(UIControlEventTouchUpInside | UIControlEventTouchUpOutside | UIControlEventTouchCancel)];
return slider;
}
static void RCTSendSliderEvent(RCTSlider *sender, BOOL continuous)
{
float value = sender.value;
if (sender.step > 0 && sender.step <= (sender.maximumValue - sender.minimumValue)) {
value =
MAX(sender.minimumValue,
MIN(sender.maximumValue,
sender.minimumValue + round((sender.value - sender.minimumValue) / sender.step) * sender.step));
[sender setValue:value animated:YES];
}
if (continuous) {
if (sender.onValueChange && sender.lastValue != value) {
sender.onValueChange(@{
@"value" : @(value),
});
}
} else {
if (sender.onSlidingComplete) {
sender.onSlidingComplete(@{
@"value" : @(value),
});
}
}
sender.lastValue = value;
}
- (void)sliderValueChanged:(RCTSlider *)sender
{
RCTSendSliderEvent(sender, YES);
}
- (void)sliderTouchEnd:(RCTSlider *)sender
{
RCTSendSliderEvent(sender, NO);
}
RCT_EXPORT_VIEW_PROPERTY(value, float);
RCT_EXPORT_VIEW_PROPERTY(step, float);
RCT_EXPORT_VIEW_PROPERTY(trackImage, UIImage);
RCT_EXPORT_VIEW_PROPERTY(minimumTrackImage, UIImage);
RCT_EXPORT_VIEW_PROPERTY(maximumTrackImage, UIImage);
RCT_EXPORT_VIEW_PROPERTY(minimumValue, float);
RCT_EXPORT_VIEW_PROPERTY(maximumValue, float);
RCT_EXPORT_VIEW_PROPERTY(minimumTrackTintColor, UIColor);
RCT_EXPORT_VIEW_PROPERTY(maximumTrackTintColor, UIColor);
RCT_EXPORT_VIEW_PROPERTY(onValueChange, RCTBubblingEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onSlidingComplete, RCTDirectEventBlock);
RCT_EXPORT_VIEW_PROPERTY(thumbTintColor, UIColor);
RCT_EXPORT_VIEW_PROPERTY(thumbImage, UIImage);
RCT_CUSTOM_VIEW_PROPERTY(disabled, BOOL, RCTSlider)
{
if (json) {
view.enabled = !([RCTConvert BOOL:json]);
} else {
view.enabled = defaultView.enabled;
}
}
RCT_CUSTOM_VIEW_PROPERTY(enabled, BOOL, RCTSlider) {}
@end

Просмотреть файл

@ -33,7 +33,6 @@ rn_android_library(
react_native_target("java/com/facebook/react/uimanager/util:util"),
react_native_target("java/com/facebook/react/views/progressbar:progressbar"),
react_native_target("java/com/facebook/react/views/scroll:scroll"),
react_native_target("java/com/facebook/react/views/slider:slider"),
react_native_target("java/com/facebook/react/views/swiperefresh:swiperefresh"),
react_native_target("java/com/facebook/react/views/text:text"),
react_native_target("java/com/facebook/react/views/textinput:textinput"),

Просмотреть файл

@ -56,7 +56,6 @@ rn_android_library(
react_native_target("java/com/facebook/react/views/modal:modal"),
react_native_target("java/com/facebook/react/views/progressbar:progressbar"),
react_native_target("java/com/facebook/react/views/scroll:scroll"),
react_native_target("java/com/facebook/react/views/slider:slider"),
react_native_target("java/com/facebook/react/views/swiperefresh:swiperefresh"),
react_native_target("java/com/facebook/react/views/switchview:switchview"),
react_native_target("java/com/facebook/react/views/text:text"),

Просмотреть файл

@ -46,7 +46,6 @@ import com.facebook.react.views.progressbar.ReactProgressBarViewManager;
import com.facebook.react.views.scroll.ReactHorizontalScrollContainerViewManager;
import com.facebook.react.views.scroll.ReactHorizontalScrollViewManager;
import com.facebook.react.views.scroll.ReactScrollViewManager;
import com.facebook.react.views.slider.ReactSliderManager;
import com.facebook.react.views.swiperefresh.SwipeRefreshLayoutManager;
import com.facebook.react.views.switchview.ReactSwitchManager;
import com.facebook.react.views.text.ReactRawTextManager;
@ -158,7 +157,6 @@ public class MainReactPackage extends TurboReactPackage {
viewManagers.add(new ReactHorizontalScrollContainerViewManager());
viewManagers.add(new ReactProgressBarViewManager());
viewManagers.add(new ReactScrollViewManager());
viewManagers.add(new ReactSliderManager());
viewManagers.add(new ReactSwitchManager());
viewManagers.add(new SwipeRefreshLayoutManager());

Просмотреть файл

@ -1,29 +0,0 @@
load("//tools/build_defs/oss:rn_defs.bzl", "YOGA_TARGET", "react_native_dep", "react_native_root_target", "react_native_target", "rn_android_library")
rn_android_library(
name = "slider",
srcs = glob(["*.java"]),
autoglob = False,
labels = [
"pfh:ReactNative_CommonInfrastructurePlaceholder",
],
language = "JAVA",
visibility = [
"PUBLIC",
],
deps = [
YOGA_TARGET,
react_native_dep("third-party/android/androidx:annotation"),
react_native_dep("third-party/android/androidx:appcompat"),
react_native_dep("third-party/android/androidx:core"),
react_native_dep("third-party/android/androidx:fragment"),
react_native_dep("third-party/android/androidx:legacy-support-core-utils"),
react_native_dep("third-party/java/infer-annotations:infer-annotations"),
react_native_dep("third-party/java/jsr-305:jsr-305"),
react_native_root_target(":generated_components_java-FBReactNativeComponentSpec"),
react_native_target("java/com/facebook/react/bridge:bridge"),
react_native_target("java/com/facebook/react/common:common"),
react_native_target("java/com/facebook/react/uimanager:uimanager"),
react_native_target("java/com/facebook/react/uimanager/annotations:annotations"),
],
)

Просмотреть файл

@ -1,118 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.views.slider;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatSeekBar;
import com.facebook.infer.annotation.Nullsafe;
/**
* Slider that behaves more like the iOS one, for consistency.
*
* <p>On iOS, the value is 0..1. Android SeekBar only supports integer values. For consistency, we
* pretend in JS that the value is 0..1 but set the SeekBar value to 0..100.
*
* <p>Note that the slider is _not_ a controlled component (setValue isn't called during dragging).
*/
@Nullsafe(Nullsafe.Mode.LOCAL)
public class ReactSlider extends AppCompatSeekBar {
/**
* If step is 0 (unset) we default to this total number of steps. Don't use 100 which leads to
* rounding errors (0.200000000001).
*/
private static int DEFAULT_TOTAL_STEPS = 128;
/**
* We want custom min..max range. Android only supports 0..max range so we implement this
* ourselves.
*/
private double mMinValue = 0;
private double mMaxValue = 0;
/**
* Value sent from JS (setState). Doesn't get updated during drag (slider is not a controlled
* component).
*/
private double mValue = 0;
/** If zero it's determined automatically. */
private double mStep = 0;
private double mStepCalculated = 0;
public ReactSlider(Context context, @Nullable AttributeSet attrs, int style) {
super(context, attrs, style);
disableStateListAnimatorIfNeeded();
}
/* package */ void disableStateListAnimatorIfNeeded() {
// We disable the state list animator for Android 6 and 7; this is a hack to prevent T37452851
// and https://github.com/facebook/react-native/issues/9979
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
super.setStateListAnimator(null);
}
}
/* package */ void setMaxValue(double max) {
mMaxValue = max;
updateAll();
}
/* package */ void setMinValue(double min) {
mMinValue = min;
updateAll();
}
/* package */ void setValue(double value) {
mValue = value;
updateValue();
}
/* package */ void setStep(double step) {
mStep = step;
updateAll();
}
/**
* Convert SeekBar's native progress value (e.g. 0..100) to a value passed to JS (e.g. -1.0..2.5).
*/
public double toRealProgress(int seekBarProgress) {
if (seekBarProgress == getMax()) {
return mMaxValue;
}
return seekBarProgress * getStepValue() + mMinValue;
}
/** Update underlying native SeekBar's values. */
private void updateAll() {
if (mStep == 0) {
mStepCalculated = (mMaxValue - mMinValue) / (double) DEFAULT_TOTAL_STEPS;
}
setMax(getTotalSteps());
updateValue();
}
/** Update value only (optimization in case only value is set). */
private void updateValue() {
setProgress((int) Math.round((mValue - mMinValue) / (mMaxValue - mMinValue) * getTotalSteps()));
}
private int getTotalSteps() {
return (int) Math.ceil((mMaxValue - mMinValue) / getStepValue());
}
private double getStepValue() {
return mStep > 0 ? mStep : mStepCalculated;
}
}

Просмотреть файл

@ -1,56 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.views.slider;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.uimanager.events.Event;
import com.facebook.react.uimanager.events.RCTEventEmitter;
/** Event emitted by a ReactSliderManager when user changes slider position. */
@Nullsafe(Nullsafe.Mode.LOCAL)
public class ReactSliderEvent extends Event<ReactSliderEvent> {
public static final String EVENT_NAME = "topValueChange";
private final double mValue;
private final boolean mFromUser;
public ReactSliderEvent(int viewId, double value, boolean fromUser) {
super(viewId);
mValue = value;
mFromUser = fromUser;
}
public double getValue() {
return mValue;
}
public boolean isFromUser() {
return mFromUser;
}
@Override
public String getEventName() {
return EVENT_NAME;
}
@Override
public void dispatch(RCTEventEmitter rctEventEmitter) {
rctEventEmitter.receiveEvent(getViewTag(), getEventName(), serializeEventData());
}
private WritableMap serializeEventData() {
WritableMap eventData = Arguments.createMap();
eventData.putInt("target", getViewTag());
eventData.putDouble("value", getValue());
eventData.putBoolean("fromUser", isFromUser());
return eventData;
}
}

Просмотреть файл

@ -1,336 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.views.slider;
import android.content.Context;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SeekBar;
import androidx.annotation.Nullable;
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.LayoutShadowNode;
import com.facebook.react.uimanager.PixelUtil;
import com.facebook.react.uimanager.ReactAccessibilityDelegate;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.UIManagerHelper;
import com.facebook.react.uimanager.ViewManagerDelegate;
import com.facebook.react.uimanager.ViewProps;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.react.viewmanagers.SliderManagerDelegate;
import com.facebook.react.viewmanagers.SliderManagerInterface;
import com.facebook.yoga.YogaMeasureFunction;
import com.facebook.yoga.YogaMeasureMode;
import com.facebook.yoga.YogaMeasureOutput;
import com.facebook.yoga.YogaNode;
import java.util.HashMap;
import java.util.Map;
/**
* Manages instances of {@code ReactSlider}.
*
* <p>Note that the slider is _not_ a controlled component.
*/
public class ReactSliderManager extends SimpleViewManager<ReactSlider>
implements SliderManagerInterface<ReactSlider> {
private static final int STYLE = android.R.attr.seekBarStyle;
public static final String REACT_CLASS = "RCTSlider";
static class ReactSliderShadowNode extends LayoutShadowNode implements YogaMeasureFunction {
private int mWidth;
private int mHeight;
private boolean mMeasured;
private ReactSliderShadowNode() {
initMeasureFunction();
}
private void initMeasureFunction() {
setMeasureFunction(this);
}
@Override
public long measure(
YogaNode node,
float width,
YogaMeasureMode widthMode,
float height,
YogaMeasureMode heightMode) {
if (!mMeasured) {
ReactSlider reactSlider = new ReactSlider(getThemedContext(), null, STYLE);
// reactSlider is used for measurements purposes, it is not necessary to set a
// StateListAnimator.
// It is not safe to access StateListAnimator from a background thread.
reactSlider.disableStateListAnimatorIfNeeded();
final int spec =
View.MeasureSpec.makeMeasureSpec(
ViewGroup.LayoutParams.WRAP_CONTENT, View.MeasureSpec.UNSPECIFIED);
reactSlider.measure(spec, spec);
mWidth = reactSlider.getMeasuredWidth();
mHeight = reactSlider.getMeasuredHeight();
mMeasured = true;
}
return YogaMeasureOutput.make(mWidth, mHeight);
}
}
private static final SeekBar.OnSeekBarChangeListener ON_CHANGE_LISTENER =
new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekbar, int progress, boolean fromUser) {
ReactContext reactContext = (ReactContext) seekbar.getContext();
EventDispatcher eventDispatcher =
UIManagerHelper.getEventDispatcherForReactTag(reactContext, seekbar.getId());
if (eventDispatcher != null) {
eventDispatcher.dispatchEvent(
new ReactSliderEvent(
seekbar.getId(), ((ReactSlider) seekbar).toRealProgress(progress), fromUser));
}
}
@Override
public void onStartTrackingTouch(SeekBar seekbar) {}
@Override
public void onStopTrackingTouch(SeekBar seekbar) {
ReactContext reactContext = (ReactContext) seekbar.getContext();
EventDispatcher eventDispatcher =
UIManagerHelper.getEventDispatcherForReactTag(reactContext, seekbar.getId());
if (eventDispatcher != null) {
eventDispatcher.dispatchEvent(
new ReactSlidingCompleteEvent(
UIManagerHelper.getSurfaceId(seekbar),
seekbar.getId(),
((ReactSlider) seekbar).toRealProgress(seekbar.getProgress())));
}
}
};
private final ViewManagerDelegate<ReactSlider> mDelegate;
public ReactSliderManager() {
mDelegate = new SliderManagerDelegate<>(this);
}
@Override
public String getName() {
return REACT_CLASS;
}
@Override
public LayoutShadowNode createShadowNodeInstance() {
return new ReactSliderShadowNode();
}
@Override
public Class getShadowNodeClass() {
return ReactSliderShadowNode.class;
}
@Override
protected ReactSlider createViewInstance(ThemedReactContext context) {
final ReactSlider slider = new ReactSlider(context, null, STYLE);
ReactSliderAccessibilityDelegate.setDelegate(
slider, slider.isFocusable(), slider.getImportantForAccessibility());
return slider;
}
@Override
@ReactProp(name = ViewProps.ENABLED, defaultBoolean = true)
public void setEnabled(ReactSlider view, boolean enabled) {
view.setEnabled(enabled);
}
@Override
@ReactProp(name = "value", defaultDouble = 0d)
public void setValue(ReactSlider view, double value) {
view.setOnSeekBarChangeListener(null);
view.setValue(value);
view.setOnSeekBarChangeListener(ON_CHANGE_LISTENER);
}
@Override
@ReactProp(name = "minimumValue", defaultDouble = 0d)
public void setMinimumValue(ReactSlider view, double value) {
view.setMinValue(value);
}
@Override
@ReactProp(name = "maximumValue", defaultDouble = 1d)
public void setMaximumValue(ReactSlider view, double value) {
view.setMaxValue(value);
}
@Override
@ReactProp(name = "step", defaultDouble = 0d)
public void setStep(ReactSlider view, double value) {
view.setStep(value);
}
@Override
@ReactProp(name = "thumbTintColor", customType = "Color")
public void setThumbTintColor(ReactSlider view, Integer color) {
if (color == null) {
view.getThumb().clearColorFilter();
} else {
view.getThumb().setColorFilter(color, PorterDuff.Mode.SRC_IN);
}
}
@Override
@ReactProp(name = "minimumTrackTintColor", customType = "Color")
public void setMinimumTrackTintColor(ReactSlider view, Integer color) {
LayerDrawable drawable = (LayerDrawable) view.getProgressDrawable().getCurrent();
Drawable progress = drawable.findDrawableByLayerId(android.R.id.progress);
if (color == null) {
progress.clearColorFilter();
} else {
progress.setColorFilter(color, PorterDuff.Mode.SRC_IN);
}
}
@Override
@ReactProp(name = "maximumTrackTintColor", customType = "Color")
public void setMaximumTrackTintColor(ReactSlider view, Integer color) {
LayerDrawable drawable = (LayerDrawable) view.getProgressDrawable().getCurrent();
Drawable background = drawable.findDrawableByLayerId(android.R.id.background);
if (color == null) {
background.clearColorFilter();
} else {
background.setColorFilter(color, PorterDuff.Mode.SRC_IN);
}
}
@Override
@ReactProp(name = "disabled")
public void setDisabled(ReactSlider view, boolean value) {}
@Override
@ReactProp(name = "maximumTrackImage", customType = "ImageSource")
public void setMaximumTrackImage(ReactSlider view, @Nullable ReadableMap value) {}
@Override
@ReactProp(name = "minimumTrackImage", customType = "ImageSource")
public void setMinimumTrackImage(ReactSlider view, @Nullable ReadableMap value) {}
@Override
public void setTestID(ReactSlider view, @Nullable String value) {
super.setTestId(view, value);
}
@Override
@ReactProp(name = "thumbImage", customType = "ImageSource")
public void setThumbImage(ReactSlider view, @Nullable ReadableMap value) {}
@Override
@ReactProp(name = "trackImage", customType = "ImageSource")
public void setTrackImage(ReactSlider view, @Nullable ReadableMap value) {}
@Override
protected void addEventEmitters(final ThemedReactContext reactContext, final ReactSlider view) {
view.setOnSeekBarChangeListener(ON_CHANGE_LISTENER);
}
@Override
public Map getExportedCustomDirectEventTypeConstants() {
@Nullable
Map<String, Object> baseEventTypeConstants = super.getExportedCustomDirectEventTypeConstants();
Map<String, Object> eventTypeConstants =
baseEventTypeConstants == null ? new HashMap<String, Object>() : baseEventTypeConstants;
eventTypeConstants.putAll(
MapBuilder.of(
ReactSlidingCompleteEvent.EVENT_NAME,
MapBuilder.of("registrationName", "onSlidingComplete")));
return eventTypeConstants;
}
@Nullable
@Override
public Map<String, Object> getExportedCustomBubblingEventTypeConstants() {
@Nullable
Map<String, Object> baseEventTypeConstants =
super.getExportedCustomBubblingEventTypeConstants();
Map<String, Object> eventTypeConstants =
baseEventTypeConstants == null ? new HashMap<String, Object>() : baseEventTypeConstants;
eventTypeConstants.putAll(
MapBuilder.<String, Object>builder()
.put(
"topValueChange",
MapBuilder.of(
"phasedRegistrationNames",
MapBuilder.of("bubbled", "onValueChange", "captured", "onValueChangeCapture")))
.build());
return eventTypeConstants;
}
@Override
public long measure(
Context context,
ReadableMap localData,
ReadableMap props,
ReadableMap state,
float width,
YogaMeasureMode widthMode,
float height,
YogaMeasureMode heightMode,
@Nullable float[] attachmentsPositions) {
SeekBar reactSlider = new ReactSlider(context, null, STYLE);
final int spec =
View.MeasureSpec.makeMeasureSpec(
ViewGroup.LayoutParams.WRAP_CONTENT, View.MeasureSpec.UNSPECIFIED);
reactSlider.measure(spec, spec);
return YogaMeasureOutput.make(
PixelUtil.toDIPFromPixel(reactSlider.getMeasuredWidth()),
PixelUtil.toDIPFromPixel(reactSlider.getMeasuredHeight()));
}
@Override
protected ViewManagerDelegate<ReactSlider> getDelegate() {
return mDelegate;
}
protected class ReactSliderAccessibilityDelegate extends ReactAccessibilityDelegate {
public ReactSliderAccessibilityDelegate(
final View view, boolean originalFocus, int originalImportantForAccessibility) {
super(view, originalFocus, originalImportantForAccessibility);
}
private boolean isSliderAction(int action) {
return (action == AccessibilityActionCompat.ACTION_SCROLL_FORWARD.getId())
|| (action == AccessibilityActionCompat.ACTION_SCROLL_BACKWARD.getId())
|| (action == AccessibilityActionCompat.ACTION_SET_PROGRESS.getId());
}
@Override
public boolean performAccessibilityAction(View host, int action, Bundle args) {
if (isSliderAction(action)) {
ON_CHANGE_LISTENER.onStartTrackingTouch((SeekBar) host);
}
final boolean rv = super.performAccessibilityAction(host, action, args);
if (isSliderAction(action)) {
ON_CHANGE_LISTENER.onStopTrackingTouch((SeekBar) host);
}
return rv;
}
};
}

Просмотреть файл

@ -1,56 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.views.slider;
import androidx.annotation.Nullable;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.uimanager.events.Event;
/** Event emitted when the user finishes dragging the slider. */
@Nullsafe(Nullsafe.Mode.LOCAL)
public class ReactSlidingCompleteEvent extends Event<ReactSlidingCompleteEvent> {
public static final String EVENT_NAME = "topSlidingComplete";
private final double mValue;
@Deprecated
public ReactSlidingCompleteEvent(int viewId, double value) {
this(-1, viewId, value);
}
public ReactSlidingCompleteEvent(int surfaceId, int viewId, double value) {
super(surfaceId, viewId);
mValue = value;
}
public double getValue() {
return mValue;
}
@Override
public String getEventName() {
return EVENT_NAME;
}
@Nullable
@Override
protected WritableMap getEventData() {
WritableMap eventData = Arguments.createMap();
eventData.putInt("target", getViewTag());
eventData.putDouble("value", getValue());
return eventData;
}
@Override
public boolean canCoalesce() {
return false;
}
}

Просмотреть файл

@ -82,7 +82,6 @@ add_react_common_subdir(react/renderer/components/view)
add_react_common_subdir(react/renderer/components/switch)
add_react_common_subdir(react/renderer/components/textinput)
add_react_common_subdir(react/renderer/components/progressbar)
add_react_common_subdir(react/renderer/components/slider)
add_react_common_subdir(react/renderer/components/root)
add_react_common_subdir(react/renderer/components/image)
add_react_common_subdir(react/renderer/componentregistry/native)

Просмотреть файл

@ -45,7 +45,6 @@ rn_xplat_cxx_library(
"//xplat/js/react-native-github:generated_components-rncore",
react_native_xplat_target("react/renderer/components/image:image"),
react_native_xplat_target("react/renderer/components/modal:modal"),
react_native_xplat_target("react/renderer/components/slider:slider"),
react_native_xplat_target("react/renderer/components/switch:androidswitch"),
react_native_xplat_target("react/renderer/components/progressbar:androidprogressbar"),
react_native_xplat_target("react/renderer/components/text:text"),

Просмотреть файл

@ -50,7 +50,6 @@ target_link_libraries(
rrc_progressbar
rrc_root
rrc_scrollview
rrc_slider
rrc_switch
rrc_text
rrc_textinput

Просмотреть файл

@ -19,7 +19,6 @@
#include <react/renderer/components/progressbar/AndroidProgressBarComponentDescriptor.h>
#include <react/renderer/components/rncore/ComponentDescriptors.h>
#include <react/renderer/components/scrollview/ScrollViewComponentDescriptor.h>
#include <react/renderer/components/slider/SliderComponentDescriptor.h>
#include <react/renderer/components/text/ParagraphComponentDescriptor.h>
#include <react/renderer/components/text/RawTextComponentDescriptor.h>
#include <react/renderer/components/text/TextComponentDescriptor.h>
@ -58,8 +57,6 @@ CoreComponentsRegistry::sharedProviderRegistry() {
concreteComponentDescriptorProvider<TextComponentDescriptor>());
providerRegistry->add(
concreteComponentDescriptorProvider<RawTextComponentDescriptor>());
providerRegistry->add(
concreteComponentDescriptorProvider<SliderComponentDescriptor>());
providerRegistry->add(
concreteComponentDescriptorProvider<ScrollViewComponentDescriptor>());
providerRegistry->add(

Просмотреть файл

@ -34,7 +34,6 @@ rn_robolectric_test(
react_native_target("java/com/facebook/react/uimanager:uimanager"),
react_native_target("java/com/facebook/react/uimanager/annotations:annotations"),
react_native_target("java/com/facebook/react/views/image:image"),
react_native_target("java/com/facebook/react/views/slider:slider"),
react_native_target("java/com/facebook/react/views/text:text"),
react_native_target("java/com/facebook/react/views/textinput:textinput"),
react_native_target("java/com/facebook/react/views/view:view"),

Просмотреть файл

@ -1,100 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.views.slider;
import static org.assertj.core.api.Assertions.assertThat;
import android.widget.SeekBar;
import com.facebook.react.bridge.CatalystInstance;
import com.facebook.react.bridge.JavaOnlyMap;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactTestHelper;
import com.facebook.react.uimanager.ReactStylesDiffMap;
import com.facebook.react.uimanager.ThemedReactContext;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.modules.junit4.rule.PowerMockRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
/** Verify {@link SeekBar} view property being applied properly by {@link ReactSliderManager} */
@RunWith(RobolectricTestRunner.class)
@PowerMockIgnore({"org.mockito.*", "org.robolectric.*", "androidx.*", "android.*"})
public class ReactSliderPropertyTest {
@Rule public PowerMockRule rule = new PowerMockRule();
private ThemedReactContext mThemedContext;
private ReactSliderManager mManager;
@Before
public void setup() {
ReactApplicationContext mContext = new ReactApplicationContext(RuntimeEnvironment.application);
CatalystInstance mCatalystInstanceMock = ReactTestHelper.createMockCatalystInstance();
mContext.initializeWithInstance(mCatalystInstanceMock);
mThemedContext = new ThemedReactContext(mContext, mContext);
mManager = new ReactSliderManager();
}
public ReactStylesDiffMap buildStyles(Object... keysAndValues) {
return new ReactStylesDiffMap(JavaOnlyMap.of(keysAndValues));
}
@Test
public void testValueWithMaxValue() {
ReactSlider view = mManager.createViewInstance(mThemedContext);
mManager.updateProperties(view, buildStyles("maximumValue", 10.0));
mManager.updateProperties(view, buildStyles("value", 5.5));
assertThat(view.getProgress()).isEqualTo(70);
}
@Test
public void testValueWithMaxValueSetBeforeMinValue() {
ReactSlider view = mManager.createViewInstance(mThemedContext);
mManager.updateProperties(view, buildStyles("maximumValue", 10.0));
mManager.updateProperties(view, buildStyles("minimumValue", 5.0));
mManager.updateProperties(view, buildStyles("value", 5.5));
assertThat(view.getProgress()).isEqualTo(13);
}
@Test
public void testValueWithMinValueSetBeforeMaxValue() {
ReactSlider view = mManager.createViewInstance(mThemedContext);
mManager.updateProperties(view, buildStyles("minimumValue", 5.0));
mManager.updateProperties(view, buildStyles("maximumValue", 10.0));
mManager.updateProperties(view, buildStyles("value", 5.5));
assertThat(view.getProgress()).isEqualTo(13);
}
@Test
public void testValueWithMaxValueAndStep() {
ReactSlider view = mManager.createViewInstance(mThemedContext);
mManager.updateProperties(view, buildStyles("maximumValue", 10.0));
mManager.updateProperties(view, buildStyles("step", 3.0));
mManager.updateProperties(view, buildStyles("value", 5.5));
assertThat(view.getProgress()).isEqualTo(2);
}
@Test
public void testValueWithMaxValueAndMinValueAndStep() {
ReactSlider view = mManager.createViewInstance(mThemedContext);
mManager.updateProperties(view, buildStyles("maximumValue", 10.0));
mManager.updateProperties(view, buildStyles("minimumValue", 5.0));
mManager.updateProperties(view, buildStyles("step", 3.0));
mManager.updateProperties(view, buildStyles("value", 10.0));
assertThat(view.getProgress()).isEqualTo(2);
}
}

Просмотреть файл

@ -174,16 +174,6 @@ Pod::Spec.new do |s|
sss.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/ReactCommon\" \"$(PODS_ROOT)/RCT-Folly\"" }
end
ss.subspec "slider" do |sss|
sss.dependency folly_dep_name, folly_version
sss.compiler_flags = folly_compiler_flags
sss.source_files = "react/renderer/components/slider/**/*.{m,mm,cpp,h}"
sss.exclude_files = "react/renderer/components/slider/tests/**/*",
"react/renderer/components/slider/platform/android"
sss.header_dir = "react/renderer/components/slider"
sss.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/ReactCommon\" \"$(PODS_ROOT)/RCT-Folly\"" }
end
ss.subspec "text" do |sss|
sss.dependency folly_dep_name, folly_version
sss.compiler_flags = folly_compiler_flags

Просмотреть файл

@ -1,117 +0,0 @@
load(
"//tools/build_defs/oss:rn_defs.bzl",
"ANDROID",
"APPLE",
"CXX",
"YOGA_CXX_TARGET",
"fb_xplat_cxx_test",
"get_apple_compiler_flags",
"get_apple_inspector_flags",
"get_preprocessor_flags_for_build_mode",
"react_native_target",
"react_native_xplat_target",
"rn_xplat_cxx_library",
"subdir_glob",
)
APPLE_COMPILER_FLAGS = get_apple_compiler_flags()
rn_xplat_cxx_library(
name = "slider",
srcs = glob(
["**/*.cpp"],
exclude = glob([
"tests/**/*.cpp",
"platform/**/*.cpp",
]),
),
headers = [],
header_namespace = "",
exported_headers = subdir_glob(
[
("", "*.h"),
],
prefix = "react/renderer/components/slider",
),
compiler_flags_pedantic = True,
cxx_tests = [":tests"],
fbandroid_deps = [
"//xplat/folly:dynamic",
react_native_target("jni/react/jni:jni"),
react_native_xplat_target("react/renderer/mapbuffer:mapbuffer"),
],
fbandroid_exported_headers = subdir_glob(
[
("", "*.h"),
("platform/android/react/renderer/components/slider", "*.h"),
],
prefix = "react/renderer/components/slider",
),
fbandroid_headers = glob(
["platform/android/react/renderer/components/slider/*.h"],
),
fbandroid_srcs = glob(
["platform/android/react/renderer/components/slider/*.cpp"],
),
fbobjc_compiler_flags = APPLE_COMPILER_FLAGS,
fbobjc_preprocessor_flags = get_preprocessor_flags_for_build_mode() + get_apple_inspector_flags(),
force_static = True,
ios_exported_headers = subdir_glob(
[
("", "*.h"),
("platform/ios", "*.h"),
],
prefix = "react/renderer/components/slider",
),
ios_headers = glob(
["platform/ios/*.h"],
),
ios_srcs = glob(
["platform/ios/*.cpp"],
),
labels = [
"pfh:ReactNative_CommonInfrastructurePlaceholder",
],
platforms = (ANDROID, APPLE, CXX),
preprocessor_flags = [
"-DLOG_TAG=\"ReactNative\"",
"-DWITH_FBSYSTRACE=1",
],
visibility = ["PUBLIC"],
deps = [
YOGA_CXX_TARGET,
react_native_xplat_target("react/debug:debug"),
react_native_xplat_target("react/renderer/debug:debug"),
react_native_xplat_target("react/renderer/core:core"),
react_native_xplat_target("react/renderer/components/image:image"),
react_native_xplat_target("react/renderer/components/view:view"),
react_native_xplat_target("react/renderer/graphics:graphics"),
react_native_xplat_target("react/renderer/imagemanager:imagemanager"),
react_native_xplat_target("react/renderer/uimanager:uimanager"),
react_native_xplat_target("react/renderer/componentregistry:componentregistry"),
"//xplat/js/react-native-github:generated_components-rncore",
],
)
fb_xplat_cxx_test(
name = "tests",
srcs = glob(["tests/**/*.cpp"]),
headers = glob(["tests/**/*.h"]),
compiler_flags = [
"-fexceptions",
"-frtti",
"-std=c++17",
"-Wall",
],
contacts = ["oncall+react_native@xmail.facebook.com"],
platforms = (
# `Apple` and `Android` flavors are disabled because the module (built with those flavors) requires Emulator/Simulator (which is expensive and slow). At the same time, we don't really have tests here.
# ANDROID,
# APPLE,
CXX,
),
deps = [
":slider",
"//xplat/third-party/gmock:gtest",
],
)

Просмотреть файл

@ -1,45 +0,0 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
cmake_minimum_required(VERSION 3.13)
set(CMAKE_VERBOSE_MAKEFILE on)
add_compile_options(
-fexceptions
-frtti
-std=c++17
-Wall
-Wpedantic
-Wno-gnu-zero-variadic-macro-arguments
-DLOG_TAG=\"Fabric\")
file(GLOB rrc_slider_SRC CONFIGURE_DEPENDS *.cpp platform/android/react/renderer/components/slider/*.cpp)
add_library(rrc_slider STATIC ${rrc_slider_SRC})
target_include_directories(rrc_slider
PUBLIC
${REACT_COMMON_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/platform/android/
)
target_link_libraries(rrc_slider
glog
fbjni
folly_runtime
glog_init
react_codegen_rncore
react_debug
react_render_componentregistry
react_render_core
react_render_debug
react_render_graphics
react_render_imagemanager
react_render_mapbuffer
react_render_uimanager
reactnativejni
rrc_image
rrc_view
yoga
)

Просмотреть файл

@ -1,58 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <react/renderer/components/slider/SliderMeasurementsManager.h>
#include <react/renderer/components/slider/SliderShadowNode.h>
#include <react/renderer/core/ConcreteComponentDescriptor.h>
namespace facebook {
namespace react {
/*
* Descriptor for <Slider> component.
*/
class SliderComponentDescriptor final
: public ConcreteComponentDescriptor<SliderShadowNode> {
public:
SliderComponentDescriptor(ComponentDescriptorParameters const &parameters)
: ConcreteComponentDescriptor(parameters),
imageManager_(std::make_shared<ImageManager>(contextContainer_)),
measurementsManager_(
SliderMeasurementsManager::shouldMeasureSlider()
? std::make_shared<SliderMeasurementsManager>(contextContainer_)
: nullptr) {}
void adopt(ShadowNode::Unshared const &shadowNode) const override {
ConcreteComponentDescriptor::adopt(shadowNode);
auto sliderShadowNode =
std::static_pointer_cast<SliderShadowNode>(shadowNode);
// `SliderShadowNode` uses `ImageManager` to initiate image loading and
// communicate the loading state and results to mounting layer.
sliderShadowNode->setImageManager(imageManager_);
if (measurementsManager_) {
// `SliderShadowNode` uses `SliderMeasurementsManager` to
// provide measurements to Yoga.
sliderShadowNode->setSliderMeasurementsManager(measurementsManager_);
// All `SliderShadowNode`s must have leaf Yoga nodes with properly
// setup measure function.
sliderShadowNode->enableMeasurement();
}
}
private:
const SharedImageManager imageManager_;
const std::shared_ptr<SliderMeasurementsManager> measurementsManager_;
};
} // namespace react
} // namespace facebook

Просмотреть файл

@ -1,100 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "SliderShadowNode.h"
#include <react/renderer/core/LayoutContext.h>
namespace facebook::react {
extern const char SliderComponentName[] = "Slider";
void SliderShadowNode::setImageManager(const SharedImageManager &imageManager) {
ensureUnsealed();
imageManager_ = imageManager;
}
void SliderShadowNode::setSliderMeasurementsManager(
const std::shared_ptr<SliderMeasurementsManager> &measurementsManager) {
ensureUnsealed();
measurementsManager_ = measurementsManager;
}
void SliderShadowNode::updateStateIfNeeded() {
const auto &newTrackImageSource = getTrackImageSource();
const auto &newMinimumTrackImageSource = getMinimumTrackImageSource();
const auto &newMaximumTrackImageSource = getMaximumTrackImageSource();
const auto &newThumbImageSource = getThumbImageSource();
auto const &currentState = getStateData();
auto trackImageSource = currentState.getTrackImageSource();
auto minimumTrackImageSource = currentState.getMinimumTrackImageSource();
auto maximumTrackImageSource = currentState.getMaximumTrackImageSource();
auto thumbImageSource = currentState.getThumbImageSource();
bool anyChanged = newTrackImageSource != trackImageSource ||
newMinimumTrackImageSource != minimumTrackImageSource ||
newMaximumTrackImageSource != maximumTrackImageSource ||
newThumbImageSource != thumbImageSource;
if (!anyChanged) {
return;
}
// Now we are about to mutate the Shadow Node.
ensureUnsealed();
// It is not possible to copy or move image requests from SliderLocalData,
// so instead we recreate any image requests (that may already be in-flight?)
// TODO: check if multiple requests are cached or if it's a net loss
auto state = SliderState{
newTrackImageSource,
imageManager_->requestImage(newTrackImageSource, getSurfaceId()),
newMinimumTrackImageSource,
imageManager_->requestImage(newMinimumTrackImageSource, getSurfaceId()),
newMaximumTrackImageSource,
imageManager_->requestImage(newMaximumTrackImageSource, getSurfaceId()),
newThumbImageSource,
imageManager_->requestImage(newThumbImageSource, getSurfaceId())};
setStateData(std::move(state));
}
ImageSource SliderShadowNode::getTrackImageSource() const {
return getConcreteProps().trackImage;
}
ImageSource SliderShadowNode::getMinimumTrackImageSource() const {
return getConcreteProps().minimumTrackImage;
}
ImageSource SliderShadowNode::getMaximumTrackImageSource() const {
return getConcreteProps().maximumTrackImage;
}
ImageSource SliderShadowNode::getThumbImageSource() const {
return getConcreteProps().thumbImage;
}
#pragma mark - LayoutableShadowNode
Size SliderShadowNode::measureContent(
LayoutContext const & /*layoutContext*/,
LayoutConstraints const &layoutConstraints) const {
if (SliderMeasurementsManager::shouldMeasureSlider()) {
return measurementsManager_->measure(getSurfaceId(), layoutConstraints);
}
return {};
}
void SliderShadowNode::layout(LayoutContext layoutContext) {
updateStateIfNeeded();
ConcreteViewShadowNode::layout(layoutContext);
}
} // namespace facebook::react

Просмотреть файл

@ -1,77 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <react/renderer/components/rncore/EventEmitters.h>
#include <react/renderer/components/rncore/Props.h>
#include <react/renderer/components/slider/SliderMeasurementsManager.h>
#include <react/renderer/components/slider/SliderState.h>
#include <react/renderer/components/view/ConcreteViewShadowNode.h>
#include <react/renderer/imagemanager/ImageManager.h>
#include <react/renderer/imagemanager/primitives.h>
namespace facebook {
namespace react {
extern const char SliderComponentName[];
/*
* `ShadowNode` for <Slider> component.
*/
class SliderShadowNode final : public ConcreteViewShadowNode<
SliderComponentName,
SliderProps,
SliderEventEmitter,
SliderState> {
public:
using ConcreteViewShadowNode::ConcreteViewShadowNode;
// Associates a shared `ImageManager` with the node.
void setImageManager(const SharedImageManager &imageManager);
// Associates a shared `SliderMeasurementsManager` with the node.
void setSliderMeasurementsManager(
const std::shared_ptr<SliderMeasurementsManager> &measurementsManager);
static SliderState initialStateData(
ShadowNodeFragment const &fragment,
ShadowNodeFamilyFragment const &familyFragment,
ComponentDescriptor const &componentDescriptor) {
auto imageSource = ImageSource{ImageSource::Type::Invalid};
return {
imageSource,
{imageSource, nullptr},
imageSource,
{imageSource, nullptr},
imageSource,
{imageSource, nullptr},
imageSource,
{imageSource, nullptr}};
}
#pragma mark - LayoutableShadowNode
Size measureContent(
LayoutContext const &layoutContext,
LayoutConstraints const &layoutConstraints) const override;
void layout(LayoutContext layoutContext) override;
private:
void updateStateIfNeeded();
ImageSource getTrackImageSource() const;
ImageSource getMinimumTrackImageSource() const;
ImageSource getMaximumTrackImageSource() const;
ImageSource getThumbImageSource() const;
SharedImageManager imageManager_;
std::shared_ptr<SliderMeasurementsManager> measurementsManager_;
};
} // namespace react
} // namespace facebook

Просмотреть файл

@ -1,44 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "SliderState.h"
namespace facebook::react {
ImageSource SliderState::getTrackImageSource() const {
return trackImageSource_;
}
ImageRequest const &SliderState::getTrackImageRequest() const {
return *trackImageRequest_;
}
ImageSource SliderState::getMinimumTrackImageSource() const {
return minimumTrackImageSource_;
}
ImageRequest const &SliderState::getMinimumTrackImageRequest() const {
return *minimumTrackImageRequest_;
}
ImageSource SliderState::getMaximumTrackImageSource() const {
return maximumTrackImageSource_;
}
ImageRequest const &SliderState::getMaximumTrackImageRequest() const {
return *maximumTrackImageRequest_;
}
ImageSource SliderState::getThumbImageSource() const {
return thumbImageSource_;
}
ImageRequest const &SliderState::getThumbImageRequest() const {
return *thumbImageRequest_;
}
} // namespace facebook::react

Просмотреть файл

@ -1,89 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#ifdef ANDROID
#include <folly/dynamic.h>
#include <react/renderer/mapbuffer/MapBuffer.h>
#include <react/renderer/mapbuffer/MapBufferBuilder.h>
#endif
#include <react/renderer/imagemanager/ImageRequest.h>
#include <react/renderer/imagemanager/primitives.h>
namespace facebook {
namespace react {
/*
* State for <Slider> component.
*/
class SliderState final {
public:
SliderState(
ImageSource const &trackImageSource,
ImageRequest trackImageRequest,
ImageSource const &minimumTrackImageSource,
ImageRequest minimumTrackImageRequest,
ImageSource const &maximumTrackImageSource,
ImageRequest maximumTrackImageRequest,
ImageSource const &thumbImageSource,
ImageRequest thumbImageRequest)
: trackImageSource_(trackImageSource),
trackImageRequest_(
std::make_shared<ImageRequest>(std::move(trackImageRequest))),
minimumTrackImageSource_(minimumTrackImageSource),
minimumTrackImageRequest_(std::make_shared<ImageRequest>(
std::move(minimumTrackImageRequest))),
maximumTrackImageSource_(maximumTrackImageSource),
maximumTrackImageRequest_(std::make_shared<ImageRequest>(
std::move(maximumTrackImageRequest))),
thumbImageSource_(thumbImageSource),
thumbImageRequest_(
std::make_shared<ImageRequest>(std::move(thumbImageRequest))){};
SliderState() = default;
ImageSource getTrackImageSource() const;
ImageRequest const &getTrackImageRequest() const;
ImageSource getMinimumTrackImageSource() const;
ImageRequest const &getMinimumTrackImageRequest() const;
ImageSource getMaximumTrackImageSource() const;
ImageRequest const &getMaximumTrackImageRequest() const;
ImageSource getThumbImageSource() const;
ImageRequest const &getThumbImageRequest() const;
#ifdef ANDROID
SliderState(SliderState const &previousState, folly::dynamic data){};
/*
* Empty implementation for Android because it doesn't use this class.
*/
folly::dynamic getDynamic() const {
return {};
};
MapBuffer getMapBuffer() const {
return MapBufferBuilder::EMPTY();
};
#endif
private:
ImageSource trackImageSource_;
std::shared_ptr<ImageRequest> trackImageRequest_;
ImageSource minimumTrackImageSource_;
std::shared_ptr<ImageRequest> minimumTrackImageRequest_;
ImageSource maximumTrackImageSource_;
std::shared_ptr<ImageRequest> maximumTrackImageRequest_;
ImageSource thumbImageSource_;
std::shared_ptr<ImageRequest> thumbImageRequest_;
};
} // namespace react
} // namespace facebook

Просмотреть файл

@ -1,72 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "SliderMeasurementsManager.h"
#include <fbjni/fbjni.h>
#include <react/jni/ReadableNativeMap.h>
#include <react/renderer/core/conversions.h>
using namespace facebook::jni;
namespace facebook::react {
Size SliderMeasurementsManager::measure(
SurfaceId surfaceId,
LayoutConstraints layoutConstraints) const {
{
std::lock_guard<std::mutex> lock(mutex_);
if (hasBeenMeasured_) {
return cachedMeasurement_;
}
}
const jni::global_ref<jobject> &fabricUIManager =
contextContainer_->at<jni::global_ref<jobject>>("FabricUIManager");
static auto measure =
jni::findClassStatic("com/facebook/react/fabric/FabricUIManager")
->getMethod<jlong(
jint,
jstring,
ReadableMap::javaobject,
ReadableMap::javaobject,
ReadableMap::javaobject,
jfloat,
jfloat,
jfloat,
jfloat)>("measure");
auto minimumSize = layoutConstraints.minimumSize;
auto maximumSize = layoutConstraints.maximumSize;
local_ref<JString> componentName = make_jstring("RCTSlider");
auto measurement = yogaMeassureToSize(measure(
fabricUIManager,
surfaceId,
componentName.get(),
nullptr,
nullptr,
nullptr,
minimumSize.width,
maximumSize.width,
minimumSize.height,
maximumSize.height));
// Explicitly release smart pointers to free up space faster in JNI tables
componentName.reset();
{
std::lock_guard<std::mutex> lock(mutex_);
cachedMeasurement_ = measurement;
}
return measurement;
}
} // namespace facebook::react

Просмотреть файл

@ -1,40 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <react/renderer/core/ConcreteComponentDescriptor.h>
#include <react/renderer/core/LayoutConstraints.h>
#include <react/utils/ContextContainer.h>
namespace facebook {
namespace react {
/**
* Class that manages slider measurements across platforms.
* On iOS it is a noop, since the height is passed in from JS on iOS only.
*/
class SliderMeasurementsManager {
public:
SliderMeasurementsManager(const ContextContainer::Shared &contextContainer)
: contextContainer_(contextContainer) {}
static inline bool shouldMeasureSlider() {
return true;
}
Size measure(SurfaceId surfaceId, LayoutConstraints layoutConstraints) const;
private:
const ContextContainer::Shared contextContainer_;
mutable std::mutex mutex_;
mutable bool hasBeenMeasured_ = false;
mutable Size cachedMeasurement_{};
};
} // namespace react
} // namespace facebook

Просмотреть файл

@ -1,23 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "SliderMeasurementsManager.h"
#include <react/debug/react_native_assert.h>
namespace facebook {
namespace react {
Size SliderMeasurementsManager::measure(
SurfaceId surfaceId,
LayoutConstraints layoutConstraints) const {
react_native_assert(false); // should never reach this point
return {};
}
} // namespace react
} // namespace facebook

Просмотреть файл

@ -1,33 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <react/renderer/core/ConcreteComponentDescriptor.h>
#include <react/renderer/core/LayoutConstraints.h>
#include <react/utils/ContextContainer.h>
namespace facebook {
namespace react {
/**
* Class that manages slider measurements across platforms.
* On iOS it is a noop, since the height is passed in from JS on iOS only.
*/
class SliderMeasurementsManager {
public:
SliderMeasurementsManager(ContextContainer::Shared const &contextContainer) {}
static inline bool shouldMeasureSlider() {
return false;
}
Size measure(SurfaceId surfaceId, LayoutConstraints layoutConstraints) const;
};
} // namespace react
} // namespace facebook

Просмотреть файл

@ -1,14 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include <memory>
#include <gtest/gtest.h>
TEST(SliderTest, testSomething) {
// TODO
}

Просмотреть файл

@ -27,7 +27,6 @@ import typeof RefreshControl from './Libraries/Components/RefreshControl/Refresh
import typeof SafeAreaView from './Libraries/Components/SafeAreaView/SafeAreaView';
import typeof ScrollView from './Libraries/Components/ScrollView/ScrollView';
import typeof SectionList from './Libraries/Lists/SectionList';
import typeof Slider from './Libraries/Components/Slider/Slider';
import typeof StatusBar from './Libraries/Components/StatusBar/StatusBar';
import typeof Switch from './Libraries/Components/Switch/Switch';
import typeof Text from './Libraries/Text/Text';
@ -161,15 +160,6 @@ module.exports = {
get SectionList(): SectionList {
return require('./Libraries/Lists/SectionList').default;
},
get Slider(): Slider {
warnOnce(
'slider-moved',
'Slider has been extracted from react-native core and will be removed in a future release. ' +
"It can now be installed and imported from '@react-native-community/slider' instead of 'react-native'. " +
'See https://github.com/callstack/react-native-slider',
);
return require('./Libraries/Components/Slider/Slider');
},
get StatusBar(): StatusBar {
return require('./Libraries/Components/StatusBar/StatusBar');
},
@ -779,4 +769,19 @@ if (__DEV__) {
);
},
});
/* $FlowFixMe[prop-missing] This is intentional: Flow will error when
* attempting to access Slider. */
/* $FlowFixMe[invalid-export] This is intentional: Flow will error when
* attempting to access Slider. */
Object.defineProperty(module.exports, 'Slider', {
configurable: true,
get() {
invariant(
false,
'Slider has been removed from react-native core. ' +
"It can now be installed and imported from '@react-native-community/slider' instead of 'react-native'. " +
'See https://github.com/callstack/react-native-slider',
);
},
});
}

Просмотреть файл

@ -369,7 +369,6 @@ PODS:
- React-Fabric/components/root (= 1000.0.0)
- React-Fabric/components/safeareaview (= 1000.0.0)
- React-Fabric/components/scrollview (= 1000.0.0)
- React-Fabric/components/slider (= 1000.0.0)
- React-Fabric/components/text (= 1000.0.0)
- React-Fabric/components/textinput (= 1000.0.0)
- React-Fabric/components/unimplementedview (= 1000.0.0)
@ -442,14 +441,6 @@ PODS:
- React-jsi (= 1000.0.0)
- React-jsiexecutor (= 1000.0.0)
- ReactCommon/turbomodule/core (= 1000.0.0)
- React-Fabric/components/slider (1000.0.0):
- RCT-Folly/Fabric (= 2021.07.22.00)
- RCTRequired (= 1000.0.0)
- RCTTypeSafety (= 1000.0.0)
- React-graphics (= 1000.0.0)
- React-jsi (= 1000.0.0)
- React-jsiexecutor (= 1000.0.0)
- ReactCommon/turbomodule/core (= 1000.0.0)
- React-Fabric/components/text (1000.0.0):
- RCT-Folly/Fabric (= 2021.07.22.00)
- RCTRequired (= 1000.0.0)
@ -938,7 +929,7 @@ SPEC CHECKSUMS:
FlipperKit: b353b63cb4048a5747529412524407d6efa68336
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
hermes-engine: a9b1fde1130ab22bd832e7eb3535f374a93aead9
hermes-engine: 094454894cb46a8522d3f72e803e634f86536889
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c
RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1
@ -950,7 +941,7 @@ SPEC CHECKSUMS:
React-Core: 719bec4b41c93b1affb1e2c3a43956ec482ecb9f
React-CoreModules: feaa45c54c58e1420981f6dd544c8b3d01200caa
React-cxxreact: 97903bdac0fb53409663fd312e2183ae1dd730e5
React-Fabric: 4d08ce0b0f15513b2724ae1000c2aaedf73ebc32
React-Fabric: 62b9929a7345f941d8833630f37d9440b2dda438
React-graphics: cb8a85648695c60f33a00d732b985f734d1470d8
React-hermes: e35ea664b36773a2ce84c583febf1396080e59f7
React-jsi: e4c75a1cf727c8761908ac2eeb1084e47ba88a26
@ -971,7 +962,7 @@ SPEC CHECKSUMS:
React-RCTTest: 81ebfa8c2e1b0b482effe12485e6486dc0ff70d7
React-RCTText: 4e5ae05b778a0ed2b22b012af025da5e1a1c4e54
React-RCTVibration: ecfd04c1886a9c9a4e31a466c0fbcf6b36e92fde
React-rncore: 3761a64f7cb20e8d82be0ac186d7182eac1e3885
React-rncore: ec7a711a56a4a64d122be8572b37a67572d5de60
React-runtimeexecutor: c7b2cd6babf6cc50340398bfbb7a9da13c93093f
ReactCommon: a11d5523be510a2d75e50e435de607297072172a
ScreenshotManager: 37152a3841a53f2de5c0013c58835b8738894553

1
types/index.d.ts поставляемый
Просмотреть файл

@ -89,7 +89,6 @@ export * from '../Libraries/Components/ProgressBarAndroid/ProgressBarAndroid';
export * from '../Libraries/Components/RefreshControl/RefreshControl';
export * from '../Libraries/Components/SafeAreaView/SafeAreaView';
export * from '../Libraries/Components/ScrollView/ScrollView';
export * from '../Libraries/Components/Slider/Slider';
export * from '../Libraries/Components/StatusBar/StatusBar';
export * from '../Libraries/Components/Switch/Switch';
export * from '../Libraries/Components/TextInput/InputAccessoryView';

12
types/public/DeprecatedPropertiesAlias.d.ts поставляемый
Просмотреть файл

@ -31,9 +31,6 @@ import {
RefreshControlProps,
RefreshControlPropsIOS,
RefreshControlPropsAndroid,
SliderProps,
SliderPropsIOS,
SliderPropsAndroid,
ImageSourcePropType,
ImageProps,
ImagePropsIOS,
@ -130,15 +127,6 @@ export type RefreshControlPropertiesIOS = RefreshControlPropsIOS;
/** @deprecated Use RefreshControlPropsAndroid */
export type RefreshControlPropertiesAndroid = RefreshControlPropsAndroid;
/** @deprecated Use SliderProps */
export type SliderProperties = SliderProps;
/** @deprecated Use SliderPropsIOS */
export type SliderPropertiesIOS = SliderPropsIOS;
/** @deprecated Use SliderPropsAndroid */
export type SliderPropertiesAndroid = SliderPropsAndroid;
/** @deprecated Use ImageSourcePropType */
export type ImagePropertiesSourceOptions = ImageSourcePropType;