Skip to content

Commit

Permalink
[feat] Support style boxShadow as array
Browse files Browse the repository at this point in the history
  • Loading branch information
rosko committed Jan 4, 2025
1 parent a5ba27c commit c04da7a
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,43 @@ describe('StyleSheet/preprocess', () => {
expect(preprocess({ aspectRatio: undefined })).toEqual({});
});

describe('boxShadow', () => {
// passthrough if boxShadow value is ever a string
test('string', () => {
const boxShadow = '0 1px 2px rgba(0, 0, 0, 0.5)';
const style = { boxShadow };
const resolved = preprocess(style);

expect(resolved).toEqual({ boxShadow });
});

test('array', () => {
const boxShadow = [
'0 1px 2px rgba(0, 0, 0, 0.5)',
{
offsetX: 1,
offsetY: 2,
blurRadius: 3
},
{
offsetX: 5,
offsetY: 6,
blurRadius: 7,
spreadDistance: 8,
color: 'rgba(0, 255, 0, 0.75)',
inset: true
}
];
const style = { boxShadow };
const resolved = preprocess(style);

expect(resolved).toEqual({
boxShadow:
'0 1px 2px rgba(0, 0, 0, 0.5), 1px 2px 3px 0 black, inset 5px 6px 7px 8px rgba(0,255,0,0.75)'
});
});
});

test('fontVariant', () => {
expect(
preprocess({ fontVariant: 'common-ligatures small-caps' })
Expand Down Expand Up @@ -190,6 +227,43 @@ describe('StyleSheet/preprocess', () => {
boxShadow: '1px 2px 3px rgba(50,60,70,0.25)'
});
});

test('shadow styles and string boxShadow together', () => {
expect(
preprocess({
shadowColor: 'rgba(50,60,70,0.5)',
shadowOffset: { width: 1, height: 2 },
shadowOpacity: 0.5,
shadowRadius: 3,
boxShadow: '4px 5px 6px black'
})
).toEqual({
boxShadow: '4px 5px 6px black, 1px 2px 3px rgba(50,60,70,0.25)'
});
});

test('shadow styles and array boxShadow together', () => {
expect(
preprocess({
shadowColor: 'rgba(50,60,70,0.5)',
shadowOffset: { width: 1, height: 2 },
shadowOpacity: 0.5,
shadowRadius: 3,
boxShadow: [
{
offsetX: 2,
offsetY: 3,
spreadDistance: 5,
color: 'rgba(10,20,30,0.45)',
inset: true
}
]
})
).toEqual({
boxShadow:
'inset 2px 3px 0 5px rgba(10,20,30,0.45), 1px 2px 3px rgba(50,60,70,0.25)'
});
});
});

describe('preprocesses multiple textShadow styles into a single declaration', () => {
Expand Down
33 changes: 27 additions & 6 deletions packages/react-native-web/src/exports/StyleSheet/preprocess.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,25 @@ export const createTextShadowValue = (style: Object): void | string => {
}
};

// { offsetX: 1, offsetY: 2, blurRadius: 3, spreadDistance: 4, color: 'rgba(255, 0, 0)', inset: true }
// => 'rgba(255, 0, 0) 1px 2px 3px 4px inset'
const mapBoxShadow = (boxShadow: Object | string): string => {
if (typeof boxShadow === 'string') {
return boxShadow;
}
const offsetX = normalizeValueWithProperty(boxShadow.offsetX) || 0;
const offsetY = normalizeValueWithProperty(boxShadow.offsetY) || 0;
const blurRadius = normalizeValueWithProperty(boxShadow.blurRadius) || 0;
const spreadDistance =
normalizeValueWithProperty(boxShadow.spreadDistance) || 0;
const color = normalizeColor(boxShadow.color) || 'black';
const position = boxShadow.inset ? 'inset ' : '';
return `${position}${offsetX} ${offsetY} ${blurRadius} ${spreadDistance} ${color}`;
};
export const createBoxShadowArrayValue = (value: Array<Object>): string => {
return value.map(mapBoxShadow).join(', ');
};

// { scale: 2 } => 'scale(2)'
// { translateX: 20 } => 'translateX(20px)'
// { matrix: [1,2,3,4,5,6] } => 'matrix(1,2,3,4,5,6)'
Expand Down Expand Up @@ -126,12 +145,8 @@ export const preprocess = <T: {| [key: string]: any |}>(
`"shadow*" style props are deprecated. Use "boxShadow".`
);
const boxShadowValue = createBoxShadowValue(style);
if (boxShadowValue != null && nextStyle.boxShadow == null) {
const { boxShadow } = style;
const value = boxShadow
? `${boxShadow}, ${boxShadowValue}`
: boxShadowValue;
nextStyle.boxShadow = value;
if (boxShadowValue != null) {
nextStyle.boxShadow = boxShadowValue;
}
}

Expand Down Expand Up @@ -184,6 +199,12 @@ export const preprocess = <T: {| [key: string]: any |}>(

if (prop === 'aspectRatio' && typeof value === 'number') {
nextStyle[prop] = value.toString();
} else if (prop === 'boxShadow') {
if (Array.isArray(value)) {
value = createBoxShadowArrayValue(value);
}
const { boxShadow } = nextStyle;
nextStyle.boxShadow = boxShadow ? `${value}, ${boxShadow}` : value;
} else if (prop === 'fontVariant') {
if (Array.isArray(value) && value.length > 0) {
/*
Expand Down

0 comments on commit c04da7a

Please sign in to comment.