diff --git a/packages/react-native-web/src/exports/StyleSheet/__tests__/createReactDOMStyle-test.js b/packages/react-native-web/src/exports/StyleSheet/__tests__/createReactDOMStyle-test.js index 72960ae7..c2d3d980 100644 --- a/packages/react-native-web/src/exports/StyleSheet/__tests__/createReactDOMStyle-test.js +++ b/packages/react-native-web/src/exports/StyleSheet/__tests__/createReactDOMStyle-test.js @@ -208,6 +208,46 @@ describe('StyleSheet/createReactDOMStyle', () => { }); }); + describe('textDecoration styles', () => { + test('textDecorationColor only', () => { + expect( + createReactDOMStyle({ + textDecorationColor: 'red' + }) + ).toEqual({}); + }); + + test('textDecorationLine only', () => { + expect( + createReactDOMStyle({ + textDecorationLine: 'underline' + }) + ).toEqual({ + textDecoration: 'underline' + }); + }); + + test('textDecorationStyle only', () => { + expect( + createReactDOMStyle({ + textDecorationStyle: 'dashed' + }) + ).toEqual({}); + }); + + test('textDecorationColor, textDecorationLine, textDecorationStyle', () => { + expect( + createReactDOMStyle({ + textDecorationColor: 'red', + textDecorationLine: 'underline', + textDecorationStyle: 'dashed' + }) + ).toEqual({ + textDecoration: 'underline dashed rgba(255,0,0,1.00)' + }); + }); + }); + test('textShadowOffset', () => { expect( createReactDOMStyle({ diff --git a/packages/react-native-web/src/exports/StyleSheet/createReactDOMStyle.js b/packages/react-native-web/src/exports/StyleSheet/createReactDOMStyle.js index 3e14a0d6..a7e85f7e 100644 --- a/packages/react-native-web/src/exports/StyleSheet/createReactDOMStyle.js +++ b/packages/react-native-web/src/exports/StyleSheet/createReactDOMStyle.js @@ -40,7 +40,6 @@ const styleShortFormProperties = { padding: ['paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft'], paddingHorizontal: ['paddingRight', 'paddingLeft'], paddingVertical: ['paddingTop', 'paddingBottom'], - textDecorationLine: ['textDecoration'], writingDirection: ['direction'] }; @@ -85,17 +84,31 @@ const defaultOffset = { height: 0, width: 0 }; // TODO: add inset and spread support const resolveShadow = (resolvedStyle, style) => { - const { height, width } = style.shadowOffset || defaultOffset; + const { boxShadow, shadowColor, shadowOffset, shadowOpacity, shadowRadius } = style; + const { height, width } = shadowOffset || defaultOffset; const offsetX = normalizeValue(null, width); const offsetY = normalizeValue(null, height); - const blurRadius = normalizeValue(null, style.shadowRadius || 0); - const color = normalizeColor(style.shadowColor, style.shadowOpacity); + const blurRadius = normalizeValue(null, shadowRadius || 0); + const color = normalizeColor(shadowColor, shadowOpacity); if (color) { - const boxShadow = `${offsetX} ${offsetY} ${blurRadius} ${color}`; - resolvedStyle.boxShadow = style.boxShadow ? `${style.boxShadow}, ${boxShadow}` : boxShadow; - } else if (style.boxShadow) { - resolvedStyle.boxShadow = style.boxShadow; + const shadow = `${offsetX} ${offsetY} ${blurRadius} ${color}`; + resolvedStyle.boxShadow = boxShadow ? `${boxShadow}, ${shadow}` : shadow; + } else if (boxShadow) { + resolvedStyle.boxShadow = boxShadow; + } +}; + +/** + * Text Decoration + */ + +const resolveTextDecoration = (resolvedStyle, style) => { + const { textDecorationColor, textDecorationLine, textDecorationStyle } = style; + const color = normalizeColor(textDecorationColor) || ''; + const lineStyle = textDecorationStyle || ''; + if (textDecorationLine) { + resolvedStyle.textDecoration = `${textDecorationLine} ${lineStyle} ${color}`.trim(); } }; @@ -104,11 +117,12 @@ const resolveShadow = (resolvedStyle, style) => { */ const resolveTextShadow = (resolvedStyle, style) => { - const { height, width } = style.textShadowOffset || defaultOffset; + const { textShadowColor, textShadowOffset, textShadowRadius } = style; + const { height, width } = textShadowOffset || defaultOffset; const offsetX = normalizeValue(null, width); const offsetY = normalizeValue(null, height); - const blurRadius = normalizeValue(null, style.textShadowRadius || 0); - const color = normalizeColor(style.textShadowColor); + const blurRadius = normalizeValue(null, textShadowRadius || 0); + const color = normalizeColor(textShadowColor); if (color) { resolvedStyle.textShadow = `${offsetX} ${offsetY} ${blurRadius} ${color}`; @@ -149,6 +163,7 @@ const resolveTransform = (resolvedStyle, style) => { const createReducer = (style, styleProps) => { let hasResolvedShadow = false; + let hasResolvedTextDecoration = false; let hasResolvedTextShadow = false; return (resolvedStyle, prop) => { @@ -250,6 +265,16 @@ const createReducer = (style, styleProps) => { break; } + case 'textDecorationColor': + case 'textDecorationLine': + case 'textDecorationStyle': { + if (!hasResolvedTextDecoration) { + resolveTextDecoration(resolvedStyle, style); + } + hasResolvedTextDecoration = true; + break; + } + case 'textShadowColor': case 'textShadowOffset': case 'textShadowRadius': { diff --git a/packages/website/storybook/1-components/Text/TextScreen.js b/packages/website/storybook/1-components/Text/TextScreen.js index 509e13bc..8d7b0a7e 100644 --- a/packages/website/storybook/1-components/Text/TextScreen.js +++ b/packages/website/storybook/1-components/Text/TextScreen.js @@ -220,10 +220,18 @@ const stylePropTypes = [ name: 'textAlignVertical', typeInfo: 'string' }, + { + name: 'textDecorationColor', + typeInfo: 'color' + }, { name: 'textDecorationLine', typeInfo: 'string' }, + { + name: 'textDecorationStyle', + typeInfo: 'string' + }, { label: 'web', name: 'textIndent',