Repository: react-native
Issue: [w3c] ☂️ Web Styles (Part 1) umbrella issue
Labels: Help Wanted :octocat:,API: StyleSheet,Platform: All,Needs TypeScript Update,:open_umbrella: Umbrella

# Add support for Web styles to components

This is the umbrella issue for basic React DOM / Web style additions to React Native components, as described in this proposal: "[RFC: Reduce fragmentation across platforms](https://github.com/react-native-community/discussions-and-proposals/pull/496)".

Each of the tasks listed below can be tackled with individual PRs that link back to this issue. Not every task has a known solution or implementation yet, so feel free to discuss implementation details in the comments. Each new style property should take priority over any existing equivalents.

# Styles

## Basic extensions (All available in React Native 0.71)
- [x] [`aspectRatio`](https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio) support for string values, i.e., `'16 / 9'`, to align with CSS. https://github.com/facebook/react-native/pull/34629
- [x] [`fontVariant`](https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant) support for space-separated string values, i.e., `'small-caps common-ligatures'`.
  - [x] https://github.com/facebook/react-native/pull/34641
  - [x] https://github.com/facebook/react-native/pull/36740 
- [x] [`fontWeight`](https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight) support for number values, i.e., `900`. https://github.com/facebook/react-native/pull/34598
- [x] [`transform`](https://developer.mozilla.org/en-US/docs/Web/CSS/transform) support for string values, i.e., `'scaleX(2) translateX(20px)'`. https://github.com/facebook/react-native/pull/34660#pullrequestreview-1104804653

Examples:

```jsx
<View
  style={{
    aspectRatio: '16 / 9',
    transform: 'scaleX(2) translateX(20px)'
  }}
>

<Text
  style={{
    fontVariant: 'small-caps common-ligatures',
    fontWeight: 900
  }}
>
```

## Equivalents
### Available in React Native 0.71
- [x] `direction`.
- [x] Add [`objectFit`](https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit). Partial equivalent to the `resizeMode` style and prop of `<Image>`. https://github.com/facebook/react-native/pull/34576
  - [x] Map `objectFit === 'contain'` to `resizeMode = 'contain'`.
  - [x] Map `objectFit === 'cover'` to `resizeMode = 'cover'`
  - [x] Map `objectFit === 'fill'` to `resizeMode = 'stretch'`
  - [x] Map `objectFit === 'scale-down'` to `resizeMode = 'contain'`
  - [ ] Support `objectFit` value of `'none'`.
- [x] Add [`pointerEvents`](https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events). Equivalent to the `pointerEvents` prop of `<View>`. https://github.com/facebook/react-native/pull/34586/
  - [x] Retain the React Native specific `box-none` and `box-only` values.
- [x] Add [`userSelect`](https://developer.mozilla.org/en-US/docs/Web/CSS/user-select). Equivalent to using `selectable` prop on `<Text>`. https://github.com/facebook/react-native/pull/34575
- [x] Add [`verticalAlign`](https://developer.mozilla.org/en-US/docs/Web/CSS/vertical-align). https://github.com/facebook/react-native/pull/34567
  - [x] Map `verticalAlign` to `textAlignVertical`.
  - [x] Map `verticalAlign === 'middle'` to `textAlignVertical = 'center'`;

### Available in React Native 0.72 
- Add CSS Logical Properties
  - [x] Logical Border Radius 
    - [x] https://github.com/facebook/react-native/pull/35342
    - [x] https://github.com/facebook/react-native/pull/35572
    * [x] `borderEndEndRadius` is equivalent to `borderBottomEndRadius`.
    * [x] `borderEndStartRadius` is equivalent to `borderBottomStartRadius`.
    * [x] `borderStartEndRadius` is equivalent to `borderTopEndRadius`.
    * [x] `borderStartStartRadius` is equivalent to `borderTopStartRadius`.
  * [x] Logical margin (Fabric-only)
    * [x] Map `marginInlineStart` to `marginStart`.
    - [x] Map `marginInlineEnd` to `marginEnd`.
    - [x] Map `marginBlockStart` to `marginTop`.
    - [x] Map `marginBlockEnd` to `marginBottom`.
    - [x] Map `marginBlock` to `marginVertical`.
    - [x] Map `marginInline` to `marginHorizontal`.
  - [x] Logical padding (Fabric-only)
    - [x] Map `paddingInlineStart` to `paddingStart`.
    - [x] Map `paddingInlineEnd` to `paddingEnd`.
    - [x] Map `paddingBlockStart` to `paddingTop`.
    - [x] Map `paddingBlockEnd` to `paddingBottom`.
    - [x] Map `paddingBlock` to `paddingVertical`.
    - [x] Map `paddingInline` to `paddingHorizontal`.
  - [x] Logical insets (Fabric-only) https://github.com/facebook/react-native/commit/9669c10afceef65626c82149210afc07d47df98b
    * [x] `inset` is equivalent to `top` & `bottom` & `right` & `left`.
    * [x] `insetBlock` is equivalent to `top` & `bottom`.
    * [x] `insetBlockEnd` is equivalent to `bottom`.
    * [x] `insetBlockStart` is equivalent to `top`.
    * [x] `insetInline` is equivalent to `right` & `left`.
    * [x] `insetInlineEnd` is equivalent to `right` or `left`.
    * [x] `insetInlineStart` is equivalent to `right` or `left`.
  - [x] https://github.com/facebook/react-native/pull/35999
  * [x] `borderBlockColor` is equivalent to `borderTopColor` & `borderBottomColor`.
  * [x] `borderBlockEndColor` is equivalent to `borderBottomColor`.
  * [x] `borderBlockStartColor` is equivalent to `borderTopColor`.

### Outstanding (version to be determined) 

- [ ] `borderStyle` value of `'none'`.
- [ ] `transformOrigin` https://github.com/facebook/react-native/pull/37606
- [ ] Add CSS Logical Properties.
  - [ ] https://github.com/facebook/react-native/pull/36046
  - [ ] https://github.com/facebook/react-native/pull/36242
  * [ ] `borderInlineColor` is equivalent to `borderEndColor` & `borderStartColor`.
  * [ ] `borderInlineEndColor` is equivalent to `borderEndColor`.
  * [ ] `borderInlineStartColor` is equivalent to `borderStartColor`.
  * [ ] `borderBlockStyle` is equivalent to `borderTopStyle` & `borderBottomStyle`.
  * [ ] `borderBlockEndStyle` is equivalent to `borderBottomStyle`.
  * [ ] `borderBlockStartStyle` is equivalent to `borderTopStyle`.
  * [ ] `borderInlineStyle` is equivalent to `borderEndStyle` & `borderStartStyle`.
  * [ ] `borderInlineEndStyle` is equivalent to `borderEndStyle`.
  * [ ] `borderInlineStartStyle` is equivalent to `borderStartStyle`.
  * [ ] `borderBlockWidth` is equivalent to `borderTopWidth` & `borderBottomWidth`.
  * [ ] `borderBlockEndWidth` is equivalent to `borderBottomWidth`.
  * [ ] `borderBlockStartWidth` is equivalent to `borderTopWidth`.
  * [ ] `borderInlineWidth` is equivalent to `borderEndWidth` & `borderStartWidth`.
  * [ ] `borderInlineEndWidth` is equivalent to `borderEndWidth`.
  * [ ] `borderInlineStartWidth` is equivalent to `borderStartWidth`.


Examples:

```jsx
<View
  style={{
    pointerEvents: 'none'
  }}
>

<Text
  style={{
    userSelect: 'none',
    verticalAlign: 'middle'
  }}
>

<Image
  style={{
    objectFit: 'cover'
  }}
>
```

## New features

### Available in React Native 0.71
- [x] Add expanded support for CSS Colors, e.g., `hsla()`. Potentially via [Colorjs.io](https://colorjs.io/). https://github.com/facebook/react-native/pull/34600
- [x] Add [`gap`](https://developer.mozilla.org/en-US/docs/Web/CSS/gap). https://github.com/facebook/yoga/pull/1116

```jsx
<View
  style={{
    boxShadow: '1px 1px 1px 1px #eee',
    backgroundColor: 'hsla(50,50,50,0.5)',
    backgroundImage: 'url(https://image.png)',
    pointerEvents: 'none',
    transform: 'scale(0.9)',
    width: '5rem'
  }}
>

<Text
  style={{
    textShadow: '1px 1px 1px #eee',
    userSelect: 'none',
    verticalAlign: 'middle'
  }}
>

<Image
  style={{
    objectFit: 'cover'
  }}
>
```