Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* @format
*/

import type {NativeColorValue} from '../StyleSheet/StyleSheetTypes';
import type AnimatedAddition from './nodes/AnimatedAddition';
import type AnimatedDiffClamp from './nodes/AnimatedDiffClamp';
import type AnimatedDivision from './nodes/AnimatedDivision';
Expand Down Expand Up @@ -46,6 +47,7 @@ export type WithAnimatedValue<+T> = T extends Builtin | Nullable
| AnimatedInterpolation<number | string>
| AnimatedInterpolation<number>
| AnimatedInterpolation<string>
| AnimatedInterpolation<NativeColorValue>
: T extends $ReadOnlyArray<infer P>
? $ReadOnlyArray<WithAnimatedValue<P>>
: T extends {...}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

'use strict';

import type {NativeColorValue} from '../../StyleSheet/StyleSheetTypes';
import type {PlatformConfig} from '../AnimatedPlatformConfig';
import type AnimatedNode from './AnimatedNode';
import type {AnimatedNodeConfig} from './AnimatedNode';
Expand All @@ -26,7 +27,14 @@ import invariant from 'invariant';

type ExtrapolateType = 'extend' | 'identity' | 'clamp';

export type InterpolationConfigType<OutputT: number | string> = $ReadOnly<{
export type InterpolationConfigSupportedOutputType =
| number
| string
| NativeColorValue;

export type InterpolationConfigType<
OutputT: InterpolationConfigSupportedOutputType,
> = $ReadOnly<{
...AnimatedNodeConfig,
inputRange: $ReadOnlyArray<number>,
outputRange: $ReadOnlyArray<OutputT>,
Expand Down Expand Up @@ -82,6 +90,28 @@ function createNumericInterpolation(
};
}

function createPlatformColorInterpolation(
config: InterpolationConfigType<NativeColorValue>,
): (input: number) => NativeColorValue {
const outputRange = config.outputRange;
const outputRangeIndices = Array.from(Array(outputRange.length).keys());
const interpolateIndex = createNumericInterpolation({
...config,
inputRange: config.inputRange,
outputRange: outputRangeIndices,
});

return input => {
const interpolateResult = interpolateIndex(input);
if (!Number.isInteger(interpolateResult)) {
console.warn(
'PlatformColor interpolation should happen natively, here we fallback to the closest color',
);
}
return outputRange[Math.floor(interpolateResult)];
};
}

function interpolate(
input: number,
inputMin: number,
Expand Down Expand Up @@ -277,7 +307,7 @@ function findRange(input: number, inputRange: $ReadOnlyArray<number>) {
return i - 1;
}

function checkValidRanges<OutputT: number | string>(
function checkValidRanges<OutputT: InterpolationConfigSupportedOutputType>(
inputRange: $ReadOnlyArray<number>,
outputRange: $ReadOnlyArray<OutputT>,
) {
Expand All @@ -304,7 +334,7 @@ function checkValidInputRange(arr: $ReadOnlyArray<number>) {
}
}

function checkInfiniteRange<OutputT: number | string>(
function checkInfiniteRange<OutputT: InterpolationConfigSupportedOutputType>(
name: string,
arr: $ReadOnlyArray<OutputT>,
) {
Expand All @@ -322,7 +352,7 @@ function checkInfiniteRange<OutputT: number | string>(
}

export default class AnimatedInterpolation<
OutputT: number | string,
OutputT: InterpolationConfigSupportedOutputType,
> extends AnimatedWithChildren {
_parent: AnimatedNode;
_config: InterpolationConfigType<OutputT>;
Expand All @@ -347,6 +377,10 @@ export default class AnimatedInterpolation<
const config = this._config;
if (config.outputRange && typeof config.outputRange[0] === 'string') {
this._interpolation = (createStringInterpolation((config: any)): any);
} else if (typeof config.outputRange[0] === 'object') {
this._interpolation = (createPlatformColorInterpolation(
(config: any),
): any);
} else {
this._interpolation = (createNumericInterpolation((config: any)): any);
}
Expand Down Expand Up @@ -403,6 +437,8 @@ export default class AnimatedInterpolation<
return NativeAnimatedHelper.transformDataType(value);
}
}): any);
} else if (typeof outputRange[0] === 'object') {
outputType = 'platform_color';
}

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ import type {EventSubscription} from '../../vendor/emitter/EventEmitter';
import type {PlatformConfig} from '../AnimatedPlatformConfig';
import type Animation from '../animations/Animation';
import type {EndCallback} from '../animations/Animation';
import type {InterpolationConfigType} from './AnimatedInterpolation';
import type {
InterpolationConfigSupportedOutputType,
InterpolationConfigType,
} from './AnimatedInterpolation';
import type AnimatedNode from './AnimatedNode';
import type {AnimatedNodeConfig} from './AnimatedNode';
import type AnimatedTracking from './AnimatedTracking';
Expand Down Expand Up @@ -298,7 +301,7 @@ export default class AnimatedValue extends AnimatedWithChildren {
* Interpolates the value before updating the property, e.g. mapping 0-1 to
* 0-10.
*/
interpolate<OutputT: number | string>(
interpolate<OutputT: InterpolationConfigSupportedOutputType>(
config: InterpolationConfigType<OutputT>,
): AnimatedInterpolation<OutputT> {
return new AnimatedInterpolation(this, config);
Expand Down
54 changes: 30 additions & 24 deletions packages/react-native/ReactNativeApi.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<1eb51bd683ea578d108218d5a48c42ec>>
* @generated SignedSource<<fe4e120a96b8868072879c03da80112b>>
*
* This file was generated by scripts/js-api/build-types/index.js.
*/
Expand Down Expand Up @@ -1453,7 +1453,7 @@ declare class AnimatedEvent {
)
}
declare class AnimatedInterpolation_default<
OutputT extends number | string,
OutputT extends InterpolationConfigSupportedOutputType,
> extends AnimatedWithChildren_default {
constructor(
parent: AnimatedNode_default,
Expand Down Expand Up @@ -1534,7 +1534,7 @@ declare class AnimatedValue_default extends AnimatedWithChildren_default {
constructor(value: number, config?: AnimatedValueConfig | null | undefined)
extractOffset(): void
flattenOffset(): void
interpolate<OutputT extends number | string>(
interpolate<OutputT extends InterpolationConfigSupportedOutputType>(
config: InterpolationConfigType<OutputT>,
): AnimatedInterpolation_default<OutputT>
removeAllListeners(): void
Expand Down Expand Up @@ -2766,17 +2766,22 @@ declare type InternalTextInput = (
ref?: React.Ref<TextInputInstance>
},
) => React.ReactNode
declare type InterpolationConfigType<OutputT extends number | string> =
Readonly<
AnimatedNodeConfig & {
extrapolate?: ExtrapolateType
extrapolateLeft?: ExtrapolateType
extrapolateRight?: ExtrapolateType
inputRange: ReadonlyArray<number>
outputRange: ReadonlyArray<OutputT>
easing?: (input: number) => number
}
>
declare type InterpolationConfigSupportedOutputType =
| NativeColorValue
| number
| string
declare type InterpolationConfigType<
OutputT extends InterpolationConfigSupportedOutputType,
> = Readonly<
AnimatedNodeConfig & {
extrapolate?: ExtrapolateType
extrapolateLeft?: ExtrapolateType
extrapolateRight?: ExtrapolateType
inputRange: ReadonlyArray<number>
outputRange: ReadonlyArray<OutputT>
easing?: (input: number) => number
}
>
declare type IOSKeyboardEvent = Readonly<
BaseKeyboardEvent & {
isEventFromThisApp: boolean
Expand Down Expand Up @@ -5899,6 +5904,7 @@ declare type WithAnimatedValue<T> = T extends Builtin | Nullable
| AnimatedAddition_default
| AnimatedDiffClamp_default
| AnimatedDivision_default
| AnimatedInterpolation_default<NativeColorValue>
| AnimatedInterpolation_default<number | string>
| AnimatedInterpolation_default<number>
| AnimatedInterpolation_default<string>
Expand Down Expand Up @@ -5940,7 +5946,7 @@ export {
AlertOptions, // a0cdac0f
AlertType, // 5ab91217
AndroidKeyboardEvent, // e03becc8
Animated, // 6b6a0b2e
Animated, // e48a2408
AppConfig, // ebddad4b
AppRegistry, // 6cdee1d6
AppState, // f7097b1b
Expand Down Expand Up @@ -5986,8 +5992,8 @@ export {
EventSubscription, // b8d084aa
ExtendedExceptionData, // 5a6ccf5a
FilterFunction, // bf24c0e3
FlatList, // cbb48cbe
FlatListProps, // 451be810
FlatList, // ee0215d3
FlatListProps, // 53c344dc
FocusEvent, // 529b43eb
FontVariant, // 7c7558bb
GestureResponderEvent, // b466f6d6
Expand Down Expand Up @@ -6120,14 +6126,14 @@ export {
ScrollToLocationParamsType, // d7ecdad1
ScrollView, // 7fb7c469
ScrollViewImperativeMethods, // eb20aa46
ScrollViewProps, // 27986ff5
ScrollViewProps, // bb4d0dd0
ScrollViewPropsAndroid, // 84e2134b
ScrollViewPropsIOS, // d83c9733
ScrollViewScrollToOptions, // 3313411e
SectionBase, // b376bddc
SectionList, // ff1193b2
SectionList, // 84642036
SectionListData, // 119baf83
SectionListProps, // c9ac8e07
SectionListProps, // 4fe82009
SectionListRenderItem, // 1fad0435
SectionListRenderItemInfo, // 745e1992
Separators, // 6a45f7e3
Expand Down Expand Up @@ -6176,7 +6182,7 @@ export {
TouchableNativeFeedback, // aaa5b42c
TouchableNativeFeedbackProps, // 372d3213
TouchableOpacity, // 7e33acfd
TouchableOpacityProps, // ba6c0ba4
TouchableOpacityProps, // 73c84562
TouchableWithoutFeedback, // 7363a906
TouchableWithoutFeedbackProps, // 68e3d87f
TransformsStyle, // 65e70f18
Expand All @@ -6192,17 +6198,17 @@ export {
ViewStyle, // c2db0e6e
VirtualViewMode, // 85a69ef6
VirtualizedList, // 4d513939
VirtualizedListProps, // a99d36db
VirtualizedListProps, // 06d07d2b
VirtualizedSectionList, // 446ba0df
VirtualizedSectionListProps, // 6cd4b378
VirtualizedSectionListProps, // 05937609
WrapperComponentProvider, // 9cf3844c
codegenNativeCommands, // e16d62f7
codegenNativeComponent, // ed4c8103
findNodeHandle, // c6b08494
processColor, // 00453092
registerCallableModule, // 86b65226
requireNativeComponent, // e659aa32
useAnimatedValue, // 2c80bbc2
useAnimatedValue, // b18adb63
useColorScheme, // c216d6f7
useWindowDimensions, // bb4b683f
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,20 @@
* @format
*/

import type {InterpolationConfigType} from '../../../Libraries/Animated/nodes/AnimatedInterpolation';
import type {
InterpolationConfigSupportedOutputType,
InterpolationConfigType,
} from '../../../Libraries/Animated/nodes/AnimatedInterpolation';

import {
isSupportedInterpolationParam,
isSupportedStyleProp,
isSupportedTransformProp,
} from '../../../Libraries/Animated/NativeAnimatedAllowlist';

export function validateInterpolation<OutputT: number | string>(
config: InterpolationConfigType<OutputT>,
): void {
export function validateInterpolation<
OutputT: InterpolationConfigSupportedOutputType,
>(config: InterpolationConfigType<OutputT>): void {
for (const key in config) {
if (key !== 'debugID' && !isSupportedInterpolationParam(key)) {
console.error(
Expand Down
Loading