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
@@ -0,0 +1,55 @@
/**
* 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 { parseTextShadow } from '../parseTextShadow';

describe('parseTextShadow', () => {
test('parses offsets, blur radius and color', () => {
expect(parseTextShadow('1px 2px 3px red')).toEqual({
textShadowColor: 'red',
textShadowOffset: { width: 1, height: 2 },
textShadowRadius: 3
});
});

test('parses a trailing color with a negative offset', () => {
expect(parseTextShadow('1px -2px 3px red')).toEqual({
textShadowColor: 'red',
textShadowOffset: { width: 1, height: -2 },
textShadowRadius: 3
});
});

test('parses a negative offset when no color is provided', () => {
// The vertical offset is negative and is the last token. It must be
// treated as a length, not as a color.
expect(parseTextShadow('1px -2px')).toEqual({
textShadowColor: null,
textShadowOffset: { width: 1, height: -2 },
textShadowRadius: undefined
});
});

test('parses a color that precedes the offset values', () => {
// CSS allows the color to be specified before or after the offsets.
expect(parseTextShadow('red 1px 2px 3px')).toEqual({
textShadowColor: 'red',
textShadowOffset: { width: 1, height: 2 },
textShadowRadius: 3
});
});

test('parses a decimal blur radius when no color is provided', () => {
// The blur radius is a decimal length and is the last token. It must be
// treated as a length, not as a color.
expect(parseTextShadow('1px 1px 2.5px')).toEqual({
textShadowColor: null,
textShadowOffset: { width: 1, height: 1 },
textShadowRadius: 2.5
});
});
});
14 changes: 7 additions & 7 deletions packages/react-strict-dom/src/native/css/parseTextShadow.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { warnMsg } from '../../shared/logUtils';

const VALUES_REG = /,(?![^(]*\))/;
const PARTS_REG = /\s(?![^(]*\))/;
const LENGTH_REG = /^[0-9]+[a-zA-Z%]+?$/;
const LENGTH_REG = /^-?(?:[0-9]*\.)?[0-9]+[a-zA-Z%]+$/;

function isLength(v: string): boolean {
return v === '0' || LENGTH_REG.test(v);
Expand All @@ -26,13 +26,13 @@ function toMaybeNum(v: string): number | string {
function parseValue(str: string) {
const parts = str.split(PARTS_REG);
const inset = parts.includes('inset');
const last = parts.slice(-1)[0];
const color = !isLength(last) ? last : null;
const tokens = parts.filter((n) => n !== 'inset');
// The color is the single token that is not a length value. CSS allows it to
// be specified either before or after the offset values, so search all tokens
// rather than assuming it is last.
const color = tokens.find((n) => !isLength(n)) ?? null;

const nums = parts
.filter((n) => n !== 'inset')
.filter((n) => n !== color)
.map(toMaybeNum);
const nums = tokens.filter((n) => n !== color).map(toMaybeNum);

const [offsetX, offsetY, blurRadius, spreadRadius] = nums;

Expand Down