Skip to content

Commit

Permalink
Fix boxShadow parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
MatiPl01 committed Jan 31, 2025
1 parent 24e223f commit 2f68811
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,10 @@ import { Button, Screen } from '@/apps/css/components';

const transitionStyles: Array<ViewStyle> = [
{
transform: [
{ perspective: 100 },
{ rotate: '45deg' },
{ skewX: '45deg' },
{ rotateX: '45deg' },
],
boxShadow: '0 0 10px 0 rgba(0, 0, 0, 0.5)',
},
{
backgroundColor: 'blue',
borderRadius: 100,
opacity: 0.5,
transform: [{ translateY: 200 }, { rotate: '45deg' }, { scale: 2 }],
},
{
backgroundColor: 'green',
transform: [
{ perspective: 200 },
{ rotate: '45deg' },
{ translateY: 150 },
{ rotateY: '-25deg' },
{ rotateX: '35deg' },
],
width: 200,
boxShadow: '0 0 20px 0 rgba(0, 0, 0, 0.5)',
},
];

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { processBoxShadow } from '../shadows';

describe(processBoxShadow, () => {});
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
'use strict';
import { parseBoxShadowString } from '../parsers';

describe(parseBoxShadowString, () => {
describe('correct number of shadows', () => {
it('works with empty string', () => {
expect(parseBoxShadowString('')).toHaveLength(0);
});

it('works with one shadow', () => {
expect(
parseBoxShadowString('0 0 10px 0 rgba(0, 0, 0, 0.5)')
).toHaveLength(1);
});

it('works with multiple shadows', () => {
expect(
parseBoxShadowString(
'0 0 10px 0 rgba(0, 0, 0, 0.5), 0 0 20px 0 rgba(0, 0, 0, 0.5)'
)
).toHaveLength(2);
});
});

describe('proper shadow values', () => {
it.each([
[
'0 0 10px 0 red',
[
{
offsetX: '0',
offsetY: '0',
blurRadius: '10px',
spreadDistance: '0',
color: 'red',
},
],
],
[
'blue 0 0 10px 0 inset',
[
{
offsetX: '0',
offsetY: '0',
blurRadius: '10px',
spreadDistance: '0',
color: 'blue',
inset: true,
},
],
],
[
'20px 20px 10px 0 red, 0 10px 20px 30px blue',
[
{
offsetX: '20px',
offsetY: '20px',
blurRadius: '10px',
spreadDistance: '0',
color: 'red',
},
{
offsetX: '0',
offsetY: '10px',
blurRadius: '20px',
spreadDistance: '30px',
color: 'blue',
},
],
],
])('works with %s', (value, expected) => {
expect(parseBoxShadowString(value)).toEqual(expected);
});
});

describe('different color formats', () => {
it.each([
'red',
'#ff0000',
'rgb(255, 0, 0)',
'rgba(255, 0, 0, 0.5)',
'hsl(0, 100%, 50%)',
'hsla(0, 100%, 50%, 0.5)',
])('works with %s', (value) => {
expect(parseBoxShadowString(`0 0 10px 0 ${value}`)).toEqual([
{
offsetX: '0',
offsetY: '0',
blurRadius: '10px',
spreadDistance: '0',
color: value,
},
]);
});
});
});
13 changes: 10 additions & 3 deletions packages/react-native-reanimated/src/css/utils/parsers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,32 @@ const LENGTH_MAPPINGS = [
'spreadDistance',
] as const;

const SHADOW_PARTS_REGEX = /(?:[^\s()]+|\([^()]*\))+/g;
const SHADOW_SPLIT_REGEX = /(?:[^,()]+|\([^)]*\))+(?=\s*,|$)/g;

export function parseBoxShadowString(value: string) {
if (value === 'none') {
return [];
}

return value.split(/\s*,\s*/).map<BoxShadowValue>((shadow) => {
const shadows = value.match(SHADOW_SPLIT_REGEX) || [];

return shadows.map<BoxShadowValue>((shadow) => {
const result: BoxShadowValue = {
offsetX: 0,
offsetY: 0,
};

let foundLengthsCount = 0;
shadow.split(/\s+/).forEach((part) => {
const parts = shadow.match(SHADOW_PARTS_REGEX) || [];

parts.forEach((part) => {
if (isLength(part)) {
result[LENGTH_MAPPINGS[foundLengthsCount++]] = part;
} else if (part === 'inset') {
result.inset = true;
} else {
result.color = part;
result.color = part.trim();
}
});

Expand Down

0 comments on commit 2f68811

Please sign in to comment.