mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
JS plumbing to get boxShadow into native (#45452)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/45452 With this we enable <View> to use BoxShadow. BoxShadow property can be a string as defined on MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/box-shadow Or it can also be a list of BoxShadow primitives: ``` [ { offsetX: 10, offsetY: 5, color: 'red', inset: true, }, { ... }, ] ``` The diff includes: * Style sheet changes so typing is valid * Process function to turn boxShadow format into parsed boxShadow primitive * Test for process function * View config changes on Android, iOS and ReactNativeStyleAttributes Changelog: [Internal] Reviewed By: joevilches Differential Revision: D57872933 fbshipit-source-id: 2c5732709959bd996cce2f979549fc95cf2410e2
This commit is contained in:
committed by
Facebook GitHub Bot
parent
66465fb69d
commit
27c6fcbe72
@@ -11,6 +11,7 @@
|
||||
import type {AnyAttributeType} from '../../Renderer/shims/ReactNativeTypes';
|
||||
|
||||
import processAspectRatio from '../../StyleSheet/processAspectRatio';
|
||||
import processBoxShadow from '../../StyleSheet/processBoxShadow';
|
||||
import processColor from '../../StyleSheet/processColor';
|
||||
import processFilter from '../../StyleSheet/processFilter';
|
||||
import processFontVariant from '../../StyleSheet/processFontVariant';
|
||||
@@ -125,6 +126,11 @@ const ReactNativeStyleAttributes: {[string]: AnyAttributeType, ...} = {
|
||||
*/
|
||||
experimental_mixBlendMode: true,
|
||||
|
||||
/*
|
||||
* BoxShadow
|
||||
*/
|
||||
experimental_boxShadow: {process: processBoxShadow},
|
||||
|
||||
/**
|
||||
* View
|
||||
*/
|
||||
|
||||
@@ -170,6 +170,9 @@ const validAttributesForNonEventProps = {
|
||||
process: require('../StyleSheet/processFilter').default,
|
||||
},
|
||||
experimental_mixBlendMode: true,
|
||||
experimental_boxShadow: {
|
||||
process: require('../StyleSheet/processBoxShadow').default,
|
||||
},
|
||||
opacity: true,
|
||||
elevation: true,
|
||||
shadowColor: {process: require('../StyleSheet/processColor').default},
|
||||
|
||||
@@ -223,6 +223,9 @@ const validAttributesForNonEventProps = {
|
||||
experimental_filter: {
|
||||
process: require('../StyleSheet/processFilter').default,
|
||||
},
|
||||
experimental_boxShadow: {
|
||||
process: require('../StyleSheet/processBoxShadow').default,
|
||||
},
|
||||
|
||||
borderTopWidth: true,
|
||||
borderTopColor: {process: require('../StyleSheet/processColor').default},
|
||||
|
||||
+46
-19
@@ -11,25 +11,6 @@ import {Animated} from '../Animated/Animated';
|
||||
import {ImageResizeMode} from '../Image/ImageResizeMode';
|
||||
import {ColorValue} from './StyleSheet';
|
||||
|
||||
export type FilterPrimitive =
|
||||
| {brightness: number | string}
|
||||
| {blur: number | string}
|
||||
| {contrast: number | string}
|
||||
| {grayscale: number | string}
|
||||
| {'hue-rotate': number | string}
|
||||
| {invert: number | string}
|
||||
| {opacity: number | string}
|
||||
| {saturate: number | string}
|
||||
| {sepia: number | string}
|
||||
| {'drop-shadow': DropShadowPrimitive | string};
|
||||
|
||||
export type DropShadowPrimitive = {
|
||||
offsetX: number | string;
|
||||
offsetY: number | string;
|
||||
standardDeviation?: number | string | undefined;
|
||||
color?: ColorValue | number | undefined;
|
||||
};
|
||||
|
||||
type FlexAlignType =
|
||||
| 'flex-start'
|
||||
| 'flex-end'
|
||||
@@ -246,6 +227,52 @@ export interface TransformsStyle {
|
||||
translateY?: AnimatableNumericValue | undefined;
|
||||
}
|
||||
|
||||
export type FilterPrimitive =
|
||||
| {brightness: number | string}
|
||||
| {blur: number | string}
|
||||
| {contrast: number | string}
|
||||
| {grayscale: number | string}
|
||||
| {'hue-rotate': number | string}
|
||||
| {invert: number | string}
|
||||
| {opacity: number | string}
|
||||
| {saturate: number | string}
|
||||
| {sepia: number | string}
|
||||
| {'drop-shadow': DropShadowPrimitive | string};
|
||||
|
||||
export type DropShadowPrimitive = {
|
||||
offsetX: number | string;
|
||||
offsetY: number | string;
|
||||
standardDeviation?: number | string | undefined;
|
||||
color?: ColorValue | number | undefined;
|
||||
};
|
||||
|
||||
export type BoxShadowPrimitive = {
|
||||
offsetX: number | string;
|
||||
offsetY: number | string;
|
||||
color?: string | undefined;
|
||||
blurRadius?: ColorValue | number | undefined;
|
||||
spreadDistance?: number | string | undefined;
|
||||
inset?: boolean | undefined;
|
||||
};
|
||||
|
||||
export type BlendMode =
|
||||
| 'normal'
|
||||
| 'multiply'
|
||||
| 'screen'
|
||||
| 'overlay'
|
||||
| 'darken'
|
||||
| 'lighten'
|
||||
| 'color-dodge'
|
||||
| 'color-burn'
|
||||
| 'hard-light'
|
||||
| 'soft-light'
|
||||
| 'difference'
|
||||
| 'exclusion'
|
||||
| 'hue'
|
||||
| 'saturation'
|
||||
| 'color'
|
||||
| 'luminosity';
|
||||
|
||||
/**
|
||||
* @see https://reactnative.dev/docs/view#style
|
||||
*/
|
||||
|
||||
+31
-25
@@ -34,25 +34,6 @@ export type EdgeInsetsValue = {
|
||||
bottom: number,
|
||||
};
|
||||
|
||||
export type FilterPrimitive =
|
||||
| {brightness: number | string}
|
||||
| {blur: number | string}
|
||||
| {contrast: number | string}
|
||||
| {grayscale: number | string}
|
||||
| {'hue-rotate': number | string}
|
||||
| {invert: number | string}
|
||||
| {opacity: number | string}
|
||||
| {saturate: number | string}
|
||||
| {sepia: number | string}
|
||||
| {'drop-shadow': DropShadowPrimitive | string};
|
||||
|
||||
export type DropShadowPrimitive = {
|
||||
offsetX: number | string,
|
||||
offsetY: number | string,
|
||||
standardDeviation?: number | string,
|
||||
color?: ____ColorValue_Internal | number,
|
||||
};
|
||||
|
||||
export type DimensionValue = number | string | 'auto' | AnimatedNode | null;
|
||||
export type AnimatableNumericValue = number | AnimatedNode;
|
||||
|
||||
@@ -709,11 +690,35 @@ export type ____ShadowStyle_Internal = $ReadOnly<{
|
||||
...____ShadowStyle_InternalOverrides,
|
||||
}>;
|
||||
|
||||
type ____FilterStyle_Internal = $ReadOnly<{
|
||||
experimental_filter?: $ReadOnlyArray<FilterPrimitive>,
|
||||
}>;
|
||||
export type FilterPrimitive =
|
||||
| {brightness: number | string}
|
||||
| {blur: number | string}
|
||||
| {contrast: number | string}
|
||||
| {grayscale: number | string}
|
||||
| {'hue-rotate': number | string}
|
||||
| {invert: number | string}
|
||||
| {opacity: number | string}
|
||||
| {saturate: number | string}
|
||||
| {sepia: number | string}
|
||||
| {'drop-shadow': DropShadowPrimitive | string};
|
||||
|
||||
export type ____MixBlendMode_Internal =
|
||||
export type DropShadowPrimitive = {
|
||||
offsetX: number | string,
|
||||
offsetY: number | string,
|
||||
standardDeviation?: number | string,
|
||||
color?: ____ColorValue_Internal,
|
||||
};
|
||||
|
||||
export type BoxShadowPrimitive = {
|
||||
offsetX: number | string,
|
||||
offsetY: number | string,
|
||||
color?: ____ColorValue_Internal,
|
||||
blurRadius?: number | string,
|
||||
spreadDistance?: number | string,
|
||||
inset?: boolean,
|
||||
};
|
||||
|
||||
type ____BlendMode_Internal =
|
||||
| 'normal'
|
||||
| 'multiply'
|
||||
| 'screen'
|
||||
@@ -735,8 +740,6 @@ export type ____ViewStyle_InternalCore = $ReadOnly<{
|
||||
...$Exact<____LayoutStyle_Internal>,
|
||||
...$Exact<____ShadowStyle_Internal>,
|
||||
...$Exact<____TransformStyle_Internal>,
|
||||
...____FilterStyle_Internal,
|
||||
experimental_mixBlendMode?: ____MixBlendMode_Internal,
|
||||
backfaceVisibility?: 'visible' | 'hidden',
|
||||
backgroundColor?: ____ColorValue_Internal,
|
||||
borderColor?: ____ColorValue_Internal,
|
||||
@@ -775,6 +778,9 @@ export type ____ViewStyle_InternalCore = $ReadOnly<{
|
||||
elevation?: number,
|
||||
pointerEvents?: 'auto' | 'none' | 'box-none' | 'box-only',
|
||||
cursor?: CursorValue,
|
||||
experimental_boxShadow?: $ReadOnlyArray<BoxShadowPrimitive>,
|
||||
experimental_filter?: $ReadOnlyArray<FilterPrimitive>,
|
||||
experimental_mixBlendMode?: ____BlendMode_Internal,
|
||||
}>;
|
||||
|
||||
export type ____ViewStyle_Internal = $ReadOnly<{
|
||||
|
||||
+269
@@ -0,0 +1,269 @@
|
||||
/**
|
||||
* 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 strict-local
|
||||
* @format
|
||||
* @oncall react_native
|
||||
*/
|
||||
|
||||
import processBoxShadow from '../processBoxShadow';
|
||||
import processColor from '../processColor';
|
||||
|
||||
// js1 test processBoxShadow
|
||||
describe('processBoxShadow', () => {
|
||||
it('should parse basic string', () => {
|
||||
expect(processBoxShadow('10px 5')).toEqual([
|
||||
{
|
||||
offsetX: 10,
|
||||
offsetY: 5,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should parse basic string with multiple whitespaces', () => {
|
||||
expect(processBoxShadow('10px 5')).toEqual([
|
||||
{
|
||||
offsetX: 10,
|
||||
offsetY: 5,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should parse string with color', () => {
|
||||
expect(processBoxShadow('red 10 5')).toEqual([
|
||||
{
|
||||
color: processColor('red'),
|
||||
offsetX: 10,
|
||||
offsetY: 5,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should parse string with color function rgba', () => {
|
||||
expect(processBoxShadow('rgba(255, 255, 255, 0.5) 10 5')).toEqual([
|
||||
{
|
||||
color: processColor('rgba(255, 255, 255, 0.5)'),
|
||||
offsetX: 10,
|
||||
offsetY: 5,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should parse string with color function hsl', () => {
|
||||
expect(processBoxShadow('hsl(318, 69%, 55%) 10 5')).toEqual([
|
||||
{
|
||||
color: processColor('hsl(318, 69%, 55%)'),
|
||||
offsetX: 10,
|
||||
offsetY: 5,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should parse string with hex color', () => {
|
||||
expect(processBoxShadow('#FFFFFF 10 5')).toEqual([
|
||||
{
|
||||
color: processColor('#FFFFFF'),
|
||||
offsetX: 10,
|
||||
offsetY: 5,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should parse string with blurRadius', () => {
|
||||
expect(processBoxShadow('red 10 5 2')).toEqual([
|
||||
{
|
||||
color: processColor('red'),
|
||||
blurRadius: 2,
|
||||
offsetX: 10,
|
||||
offsetY: 5,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should parse string with spreadDistance', () => {
|
||||
expect(processBoxShadow('red 10 5 2 3')).toEqual([
|
||||
{
|
||||
color: processColor('red'),
|
||||
blurRadius: 2,
|
||||
offsetX: 10,
|
||||
offsetY: 5,
|
||||
spreadDistance: 3,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should parse string arguments with units', () => {
|
||||
expect(processBoxShadow('5px 2px')).toEqual([
|
||||
{
|
||||
offsetX: 5,
|
||||
offsetY: 2,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should parse string with inset', () => {
|
||||
expect(processBoxShadow('5px 2px inset')).toEqual([
|
||||
{
|
||||
offsetX: 5,
|
||||
offsetY: 2,
|
||||
inset: true,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should parse string with inset and color before and after lengths', () => {
|
||||
expect(processBoxShadow('red 10 10 inset')).toEqual([
|
||||
{
|
||||
color: processColor('red'),
|
||||
offsetX: 10,
|
||||
offsetY: 10,
|
||||
inset: true,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should parse multiple box shadow strings', () => {
|
||||
expect(
|
||||
processBoxShadow('10 5 red, 5 12 inset, inset 10 45 13 red'),
|
||||
).toEqual([
|
||||
{
|
||||
offsetX: 10,
|
||||
offsetY: 5,
|
||||
color: processColor('red'),
|
||||
},
|
||||
{
|
||||
offsetX: 5,
|
||||
offsetY: 12,
|
||||
inset: true,
|
||||
},
|
||||
{
|
||||
offsetX: 10,
|
||||
offsetY: 45,
|
||||
blurRadius: 13,
|
||||
inset: true,
|
||||
color: processColor('red'),
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should fail to parse string with invalid units', () => {
|
||||
expect(processBoxShadow('red 10em 5$ 2| 3rp')).toEqual([]);
|
||||
});
|
||||
|
||||
it('should fail to parse too many lengths', () => {
|
||||
expect(processBoxShadow('10 5 2 3 10 10')).toEqual([]);
|
||||
});
|
||||
|
||||
it('should fail to parse inset between lengths', () => {
|
||||
expect(processBoxShadow('10 inset 5 2 3,')).toEqual([]);
|
||||
});
|
||||
|
||||
it('should fail to parse double color', () => {
|
||||
expect(processBoxShadow('red red 10 5')).toEqual([]);
|
||||
});
|
||||
|
||||
it('should fail to parse double inset', () => {
|
||||
expect(processBoxShadow('10 5 inset inset')).toEqual([]);
|
||||
});
|
||||
|
||||
it('should fail to parse color between lengths', () => {
|
||||
expect(processBoxShadow('10 red 5 2 3,')).toEqual([]);
|
||||
});
|
||||
|
||||
it('should fail to parse invalid unit', () => {
|
||||
expect(processBoxShadow('red 10foo 5 2 3,')).toEqual([]);
|
||||
});
|
||||
|
||||
it('should fail to parse invalid argument', () => {
|
||||
expect(processBoxShadow('red asf 5 2 3')).toEqual([]);
|
||||
});
|
||||
|
||||
it('should fail to parse negative blur', () => {
|
||||
expect(processBoxShadow('red 5 2 -3')).toEqual([]);
|
||||
});
|
||||
|
||||
it('should parse simple object', () => {
|
||||
expect(
|
||||
processBoxShadow([
|
||||
{
|
||||
offsetX: 10,
|
||||
offsetY: 5,
|
||||
},
|
||||
]),
|
||||
).toEqual([
|
||||
{
|
||||
offsetX: 10,
|
||||
offsetY: 5,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should parse object with color', () => {
|
||||
expect(
|
||||
processBoxShadow([
|
||||
{
|
||||
offsetX: 10,
|
||||
offsetY: 5,
|
||||
color: 'red',
|
||||
},
|
||||
]),
|
||||
).toEqual([
|
||||
{
|
||||
offsetX: 10,
|
||||
offsetY: 5,
|
||||
color: processColor('red'),
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should parse complex box shadow', () => {
|
||||
expect(
|
||||
processBoxShadow([
|
||||
{
|
||||
offsetX: '10px',
|
||||
offsetY: 5,
|
||||
blurRadius: 2,
|
||||
spreadDistance: 3,
|
||||
inset: true,
|
||||
color: '#FFFFFF',
|
||||
},
|
||||
]),
|
||||
).toEqual([
|
||||
{
|
||||
offsetX: 10,
|
||||
offsetY: 5,
|
||||
blurRadius: 2,
|
||||
spreadDistance: 3,
|
||||
inset: true,
|
||||
color: processColor('#FFFFFF'),
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should fail to parse object with negative blur', () => {
|
||||
expect(
|
||||
processBoxShadow([
|
||||
{
|
||||
offsetX: 10,
|
||||
offsetY: 5,
|
||||
color: 'red',
|
||||
blurRadius: -3,
|
||||
},
|
||||
]),
|
||||
).toEqual([]);
|
||||
});
|
||||
|
||||
it('should fail to parse object with invalid argument', () => {
|
||||
expect(
|
||||
processBoxShadow([
|
||||
{
|
||||
offsetX: 10,
|
||||
offsetY: 'asdf',
|
||||
},
|
||||
]),
|
||||
).toEqual([]);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,208 @@
|
||||
/**
|
||||
* 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 strict-local
|
||||
* @format
|
||||
* @oncall react-native
|
||||
*/
|
||||
|
||||
import type {ProcessedColorValue} from './processColor';
|
||||
import type {BoxShadowPrimitive} from './StyleSheetTypes';
|
||||
|
||||
import processColor from './processColor';
|
||||
|
||||
export type ParsedBoxShadow = {
|
||||
offsetX: number,
|
||||
offsetY: number,
|
||||
color?: ProcessedColorValue,
|
||||
blurRadius?: number,
|
||||
spreadDistance?: number,
|
||||
inset?: boolean,
|
||||
};
|
||||
|
||||
export default function processBoxShadow(
|
||||
rawBoxShadows: $ReadOnlyArray<BoxShadowPrimitive> | string,
|
||||
): Array<ParsedBoxShadow> {
|
||||
const result: Array<ParsedBoxShadow> = [];
|
||||
|
||||
const boxShadowList =
|
||||
typeof rawBoxShadows === 'string'
|
||||
? parseBoxShadowString(rawBoxShadows)
|
||||
: rawBoxShadows;
|
||||
|
||||
for (const rawBoxShadow of boxShadowList) {
|
||||
const parsedBoxShadow: ParsedBoxShadow = {
|
||||
offsetX: 0,
|
||||
offsetY: 0,
|
||||
};
|
||||
|
||||
let value;
|
||||
for (const arg in rawBoxShadow) {
|
||||
switch (arg) {
|
||||
case 'offsetX':
|
||||
value =
|
||||
typeof rawBoxShadow.offsetX === 'string'
|
||||
? parseLength(rawBoxShadow.offsetX)
|
||||
: rawBoxShadow.offsetX;
|
||||
if (value == null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
parsedBoxShadow.offsetX = value;
|
||||
break;
|
||||
case 'offsetY':
|
||||
value =
|
||||
typeof rawBoxShadow.offsetY === 'string'
|
||||
? parseLength(rawBoxShadow.offsetY)
|
||||
: rawBoxShadow.offsetY;
|
||||
if (value == null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
parsedBoxShadow.offsetY = value;
|
||||
break;
|
||||
case 'spreadDistance':
|
||||
value =
|
||||
typeof rawBoxShadow.spreadDistance === 'string'
|
||||
? parseLength(rawBoxShadow.spreadDistance)
|
||||
: rawBoxShadow.spreadDistance;
|
||||
if (value == null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
parsedBoxShadow.spreadDistance = value;
|
||||
break;
|
||||
case 'blurRadius':
|
||||
value =
|
||||
typeof rawBoxShadow.blurRadius === 'string'
|
||||
? parseLength(rawBoxShadow.blurRadius)
|
||||
: rawBoxShadow.blurRadius;
|
||||
if (value == null || value < 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
parsedBoxShadow.blurRadius = value;
|
||||
break;
|
||||
case 'color':
|
||||
const color = processColor(rawBoxShadow.color);
|
||||
if (color == null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
parsedBoxShadow.color = color;
|
||||
break;
|
||||
case 'inset':
|
||||
parsedBoxShadow.inset = rawBoxShadow.inset;
|
||||
}
|
||||
}
|
||||
result.push(parsedBoxShadow);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function parseBoxShadowString(
|
||||
rawBoxShadows: string,
|
||||
): Array<BoxShadowPrimitive> {
|
||||
let result: Array<BoxShadowPrimitive> = [];
|
||||
|
||||
for (const rawBoxShadow of rawBoxShadows
|
||||
.split(/,(?![^()]*\))/) // split by comma that is not in parenthesis
|
||||
.map(bS => bS.trim())
|
||||
.filter(bS => bS !== '')) {
|
||||
const boxShadow: BoxShadowPrimitive = {
|
||||
offsetX: 0,
|
||||
offsetY: 0,
|
||||
};
|
||||
let offsetX: number | string;
|
||||
let offsetY: number | string;
|
||||
let keywordDetectedAfterLength = false;
|
||||
|
||||
let lengthCount = 0;
|
||||
|
||||
// split rawBoxShadow string by all whitespaces that are not in parenthesis
|
||||
const args = rawBoxShadow.split(/\s+(?![^(]*\))/);
|
||||
for (const arg of args) {
|
||||
const processedColor = processColor(arg);
|
||||
if (processedColor != null) {
|
||||
if (boxShadow.color != null) {
|
||||
return [];
|
||||
}
|
||||
if (offsetX != null) {
|
||||
keywordDetectedAfterLength = true;
|
||||
}
|
||||
boxShadow.color = arg;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === 'inset') {
|
||||
if (boxShadow.inset != null) {
|
||||
return [];
|
||||
}
|
||||
if (offsetX != null) {
|
||||
keywordDetectedAfterLength = true;
|
||||
}
|
||||
boxShadow.inset = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (lengthCount) {
|
||||
case 0:
|
||||
offsetX = arg;
|
||||
lengthCount++;
|
||||
break;
|
||||
case 1:
|
||||
if (keywordDetectedAfterLength) {
|
||||
return [];
|
||||
}
|
||||
offsetY = arg;
|
||||
lengthCount++;
|
||||
break;
|
||||
case 2:
|
||||
if (keywordDetectedAfterLength) {
|
||||
return [];
|
||||
}
|
||||
boxShadow.blurRadius = arg;
|
||||
lengthCount++;
|
||||
break;
|
||||
case 3:
|
||||
if (keywordDetectedAfterLength) {
|
||||
return [];
|
||||
}
|
||||
boxShadow.spreadDistance = arg;
|
||||
lengthCount++;
|
||||
break;
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
if (offsetX == null || offsetY == null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
boxShadow.offsetX = offsetX;
|
||||
boxShadow.offsetY = offsetY;
|
||||
|
||||
result.push(boxShadow);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function parseLength(length: string): ?number {
|
||||
// matches on args with units like "1.5 5% -80deg"
|
||||
const argsWithUnitsRegex = /([+-]?\d*(\.\d+)?)([\w\W]+)?/g;
|
||||
const match = argsWithUnitsRegex.exec(length);
|
||||
|
||||
if (!match || Number.isNaN(match[1])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (match[3] != null && match[3] !== 'px') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Number(match[1]);
|
||||
}
|
||||
@@ -7571,23 +7571,6 @@ export type EdgeInsetsValue = {
|
||||
right: number,
|
||||
bottom: number,
|
||||
};
|
||||
export type FilterPrimitive =
|
||||
| { brightness: number | string }
|
||||
| { blur: number | string }
|
||||
| { contrast: number | string }
|
||||
| { grayscale: number | string }
|
||||
| { \\"hue-rotate\\": number | string }
|
||||
| { invert: number | string }
|
||||
| { opacity: number | string }
|
||||
| { saturate: number | string }
|
||||
| { sepia: number | string }
|
||||
| { \\"drop-shadow\\": DropShadowPrimitive | string };
|
||||
export type DropShadowPrimitive = {
|
||||
offsetX: number | string,
|
||||
offsetY: number | string,
|
||||
standardDeviation?: number | string,
|
||||
color?: ____ColorValue_Internal | number,
|
||||
};
|
||||
export type DimensionValue = number | string | \\"auto\\" | AnimatedNode | null;
|
||||
export type AnimatableNumericValue = number | AnimatedNode;
|
||||
export type CursorValue = \\"auto\\" | \\"pointer\\";
|
||||
@@ -7700,10 +7683,32 @@ export type ____ShadowStyle_Internal = $ReadOnly<{
|
||||
...____ShadowStyle_InternalCore,
|
||||
...____ShadowStyle_InternalOverrides,
|
||||
}>;
|
||||
type ____FilterStyle_Internal = $ReadOnly<{
|
||||
experimental_filter?: $ReadOnlyArray<FilterPrimitive>,
|
||||
}>;
|
||||
export type ____MixBlendMode_Internal =
|
||||
export type FilterPrimitive =
|
||||
| { brightness: number | string }
|
||||
| { blur: number | string }
|
||||
| { contrast: number | string }
|
||||
| { grayscale: number | string }
|
||||
| { \\"hue-rotate\\": number | string }
|
||||
| { invert: number | string }
|
||||
| { opacity: number | string }
|
||||
| { saturate: number | string }
|
||||
| { sepia: number | string }
|
||||
| { \\"drop-shadow\\": DropShadowPrimitive | string };
|
||||
export type DropShadowPrimitive = {
|
||||
offsetX: number | string,
|
||||
offsetY: number | string,
|
||||
standardDeviation?: number | string,
|
||||
color?: ____ColorValue_Internal,
|
||||
};
|
||||
export type BoxShadowPrimitive = {
|
||||
offsetX: number | string,
|
||||
offsetY: number | string,
|
||||
color?: ____ColorValue_Internal,
|
||||
blurRadius?: number | string,
|
||||
spreadDistance?: number | string,
|
||||
inset?: boolean,
|
||||
};
|
||||
type ____BlendMode_Internal =
|
||||
| \\"normal\\"
|
||||
| \\"multiply\\"
|
||||
| \\"screen\\"
|
||||
@@ -7724,8 +7729,6 @@ export type ____ViewStyle_InternalCore = $ReadOnly<{
|
||||
...$Exact<____LayoutStyle_Internal>,
|
||||
...$Exact<____ShadowStyle_Internal>,
|
||||
...$Exact<____TransformStyle_Internal>,
|
||||
...____FilterStyle_Internal,
|
||||
experimental_mixBlendMode?: ____MixBlendMode_Internal,
|
||||
backfaceVisibility?: \\"visible\\" | \\"hidden\\",
|
||||
backgroundColor?: ____ColorValue_Internal,
|
||||
borderColor?: ____ColorValue_Internal,
|
||||
@@ -7764,6 +7767,9 @@ export type ____ViewStyle_InternalCore = $ReadOnly<{
|
||||
elevation?: number,
|
||||
pointerEvents?: \\"auto\\" | \\"none\\" | \\"box-none\\" | \\"box-only\\",
|
||||
cursor?: CursorValue,
|
||||
experimental_boxShadow?: $ReadOnlyArray<BoxShadowPrimitive>,
|
||||
experimental_filter?: $ReadOnlyArray<FilterPrimitive>,
|
||||
experimental_mixBlendMode?: ____BlendMode_Internal,
|
||||
}>;
|
||||
export type ____ViewStyle_Internal = $ReadOnly<{
|
||||
...____ViewStyle_InternalCore,
|
||||
@@ -8005,6 +8011,21 @@ declare module.exports: processAspectRatio;
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`public API should not change unintentionally Libraries/StyleSheet/processBoxShadow.js 1`] = `
|
||||
"export type ParsedBoxShadow = {
|
||||
offsetX: number,
|
||||
offsetY: number,
|
||||
color?: ProcessedColorValue,
|
||||
blurRadius?: number,
|
||||
spreadDistance?: number,
|
||||
inset?: boolean,
|
||||
};
|
||||
declare export default function processBoxShadow(
|
||||
rawBoxShadows: $ReadOnlyArray<BoxShadowPrimitive> | string
|
||||
): Array<ParsedBoxShadow>;
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`public API should not change unintentionally Libraries/StyleSheet/processColor.js 1`] = `
|
||||
"export type ProcessedColorValue = number | NativeColorValue;
|
||||
declare function processColor(
|
||||
|
||||
+12
-1
@@ -32,7 +32,12 @@
|
||||
* Either the import or the reference only needs to appear once, anywhere in the project.
|
||||
*/
|
||||
|
||||
import {DimensionValue} from 'react-native/Libraries/StyleSheet/StyleSheetTypes';
|
||||
import {
|
||||
BlendMode,
|
||||
BoxShadowPrimitive,
|
||||
DimensionValue,
|
||||
FilterPrimitive,
|
||||
} from 'react-native/Libraries/StyleSheet/StyleSheetTypes';
|
||||
|
||||
export {};
|
||||
|
||||
@@ -142,4 +147,10 @@ declare module '.' {
|
||||
*/
|
||||
experimental_layoutConformance?: 'strict' | 'classic' | undefined;
|
||||
}
|
||||
|
||||
export interface ViewStyle {
|
||||
experimental_boxShadow?: BoxShadowPrimitive | undefined;
|
||||
experimental_filter?: ReadonlyArray<FilterPrimitive> | undefined;
|
||||
experimental_mixBlendMode?: BlendMode | undefined;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user