react-native icon indicating copy to clipboard operation
react-native copied to clipboard

feat: added `textShadow` property in `TextStyleProps`

Open dhruvtailor7 opened this issue 3 years ago • 28 comments

Summary

This PR is for adding the support fortextShadow property in TextStyleProps as required in the issue https://github.com/facebook/react-native/issues/34425. Unit Test cases and an example are also added in this PR.

Changelog

[General] [added] - Added support for textShadow property in style prop for Text Component,

Test Plan

  1. Added unit test cases for the function processTextShadow.
  2. Added an example in the RNTester app.

dhruvtailor7 avatar Sep 09 '22 11:09 dhruvtailor7

Platform Engine Arch Size (bytes) Diff
android hermes arm64-v8a 7,748,211 -20,296
android hermes armeabi-v7a 7,150,055 -19,408
android hermes x86 8,059,405 -22,242
android hermes x86_64 8,030,131 -23,019
android jsc arm64-v8a 9,609,341 -19,885
android jsc armeabi-v7a 8,374,662 -18,994
android jsc x86 9,556,814 -21,828
android jsc x86_64 10,149,163 -22,588

Base commit: cb3a5cc6913d81b3e16bcb3a9d5f29e5cfa1de73 Branch: main

analysis-bot avatar Sep 09 '22 11:09 analysis-bot

Platform Engine Arch Size (bytes) Diff
ios - universal n/a --

Base commit: b5aec963404dbe48ee068cfb98e2e1a03dc64dcf Branch: main

analysis-bot avatar Sep 09 '22 12:09 analysis-bot

@cipolleschi has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

facebook-github-bot avatar Sep 12 '22 07:09 facebook-github-bot

Could you please rebase this @dhruvtailor7?

cipolleschi avatar Sep 13 '22 07:09 cipolleschi

@dhruvtailor7 Could you please take care of the warnings and rebase onto main? 🙏

cipolleschi avatar Sep 15 '22 11:09 cipolleschi

Textshadow can accept comma separated values. Also regex used is not maintainable easily better to read spec and follow accordingly.

https://drafts.csswg.org/css-text-decor/#text-shadow-property

Hello @jacdebug. How can I map multiple textShadow values because currently the Text Component only supports single text-shadow through props?

or, As part of this PR, should we enhance the text component on the native side to support multiple text shadows?

dhruvtailor7 avatar Sep 16 '22 07:09 dhruvtailor7

Textshadow can accept comma separated values. Also regex used is not maintainable easily better to read spec and follow accordingly.

https://drafts.csswg.org/css-text-decor/#text-shadow-property

Hello @necolas @jacdebug , I am not sure what would be the most optimal way to derive the textShadow values from the string. Do you have any suggestions?

dhruvtailor7 avatar Sep 23 '22 13:09 dhruvtailor7

Hi @dhruvtailor7, could you take care of fixing the linting errors? 🙏 As per your question:

Hello @necolas @jacdebug , I am not sure what would be the most optimal way to derive the textShadow values from the string. Do you have any suggestions?

I have a couple of ideas.

Manually splitting

One idea could be to manually try to split the string. For example, you can split it using white-spaces and then process the various pieces of the array. This will avoid to instantiate the regex every time and will make the logic more readable. Although it will make it imperative instead of declarative.

The downsides, this could be:

  • An imperative approach instead of a declarative one
  • It could become hard to properly handle all the use cases. @jacdebug was saying that we have also to support comma separated shadows, so the following are valid values: '1, 1,1, red', 1,1, 1,rgb(1,1,0).

Composing the regex

To address the non-maintainable part of the feedback, we can try to split the regex in something more readable and then we can combine it together. For example, we can have (I've never used JS regex, so the syntax may be wrong):

const offsetRE = '\d\.\d';
const separatorRE = '( |,)';
// other components
const fullShadow = `${offsetRE}${separato}${offsetRE}${separator}${blurRadiusRE}${separator}${colorRE}`;
const colorShadow = `${colorRE}`

return new RegEx(`${fullShadow}|...|${colorShadow}`); // concatenate in OR all the possible formats for the shadow.

This will make it readable, maintainable and we are going to keep a declarative approach.

WDYT?

cipolleschi avatar Sep 27 '22 09:09 cipolleschi

so the following are valid values: '1, 1,1, red', 1,1, 1,rgb(1,1,0)

No, multiple shadows are separated by commas. You can split on comma to detect multiple shadows and print a warning that only the first shadow will be supported by RN. The trickier part will be detecting which part of the shadow is a color. Best to refer to the spec for details about the syntax

necolas avatar Sep 28 '22 00:09 necolas

You can split on comma to detect multiple shadows

Splitting with a comma will not work when the shadow color is in rgb or hsl format. So, I guess using regex with all possible shadow formats is the only option.

dhruvtailor7 avatar Sep 28 '22 05:09 dhruvtailor7

Sorry, my bad... I'm not super familiar with web development. However, I think that we can rework the regex to make it more readable and maintainable as I suggested above.

The final regex could be:

const OffsetRegEx = '\d.\d';
...
const fullShadow = `${OffsetRegEx} ${OffsetRegEx} ${borderRadiusRegEx} ${ColorRegEx}`;
const shadowRegEx = `${shadowWithOnlyXOffset}|${shadowWithXAndYOffset}|...|${fullShadow}`;
return new RegEx(`${shadowRegEx}(,${shadowRegEx})+`);

At least we address the maintainability issue and we manage to parse multiple shadows. WDYT?

cipolleschi avatar Sep 28 '22 14:09 cipolleschi

Splitting with a comma will not work when the shadow color is in rgb or hsl format.

Good point! I think eventually a lot of this stuff will move into native code. Note that CSS Color 4 allows space separated rgb values, which would make things easier if we didn't also have comma-separated. Ideas for another day.

necolas avatar Sep 28 '22 18:09 necolas

Thanks for doing this. I saw that you also modified the StyleSheetTypes.js file. Could you please update the types of TypeScript also? 🙏

Thank you so much!

cipolleschi avatar Sep 29 '22 12:09 cipolleschi

@cipolleschi has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

facebook-github-bot avatar Sep 29 '22 12:09 facebook-github-bot

Thanks for doing this. I saw that you also modified the StyleSheetTypes.js file. Could you please update the types of TypeScript also? 🙏

Thank you so much!

@cipolleschi Updated the Typescript type definition. Thanks.

dhruvtailor7 avatar Sep 29 '22 14:09 dhruvtailor7

@necolas I see there are many new css properties added recently and each of then has its own css parsing. Can we use something like reworkcss/css instead, WDYT?

jacdebug avatar Sep 29 '22 15:09 jacdebug

I think https://github.com/postcss/postcss would be a better choice. We use it for some value parsing in stylex and react-native-web. Similarly https://colorjs.io/ might be useful for colors. It depends on what you all think we should do in JS vs native code in the long term

necolas avatar Sep 29 '22 15:09 necolas

Thanks to @javache for suggestion,

We need to reuse the logic from https://github.com/facebook/react-native/blob/main/packages/normalize-color/index.js for both color list and parsing logic.

jacdebug avatar Sep 30 '22 13:09 jacdebug

@jacdebug I have updated the PR. Can you review it? Thanks.

dhruvtailor7 avatar Oct 06 '22 09:10 dhruvtailor7

@cipolleschi has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

facebook-github-bot avatar Oct 06 '22 12:10 facebook-github-bot

This PR has some import issues. Our Flow static analyzer is reporting errors like this in several places: Screenshot 2022-10-06 at 16 46 35

These are happening here: Screenshot 2022-10-06 at 16 48 43

Could you have a look at them? To reproduce them, you can try to install and run flow locally.

cipolleschi avatar Oct 06 '22 15:10 cipolleschi

Could you have a look at them? To reproduce them, you can try to install and run flow locally.

Hmm. I do have flow installed but I am not getting any errors. Screenshot 2022-10-07 at 11 03 21 AM

dhruvtailor7 avatar Oct 07 '22 05:10 dhruvtailor7

Also if a new colour is added then do we need to update this index?

@jacdebug Yes, If the new color regex has a capturing group.

dhruvtailor7 avatar Oct 07 '22 09:10 dhruvtailor7

@cipolleschi has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

facebook-github-bot avatar Oct 10 '22 10:10 facebook-github-bot

@cipolleschi has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

facebook-github-bot avatar Oct 10 '22 16:10 facebook-github-bot

I'm sorry that this PR is taking so long to be merged. We have some internal components that use the shadow that are impacted by these changes. I haven't had the time to look into those yet.

cipolleschi avatar Oct 18 '22 11:10 cipolleschi

@cipolleschi has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

facebook-github-bot avatar Oct 18 '22 11:10 facebook-github-bot

It's alright. Thanks for the update.

dhruvtailor7 avatar Oct 18 '22 11:10 dhruvtailor7

I don't think we can merge while it includes a change to the normalize-color export. It will cause too much churn internally and in the ecosystem. I don't think we need to reuse its logic either. We can probably use something like postcss-value-parser to break the textShadow value down into its parts before forwarding them to the existing RN style properties.

necolas avatar Nov 09 '22 00:11 necolas

Someone said multiple shadows, May be positioning multiple Text components on top of each other do the trick??

arasrezaei avatar Dec 23 '22 05:12 arasrezaei