From b27c9820dbffe1e5a3ffc87d62b1c9c167dbae8c Mon Sep 17 00:00:00 2001 From: Nicolas Gallagher Date: Mon, 28 Feb 2022 12:19:33 -0800 Subject: [PATCH] [change] StyleSheet rewrite * Improves React Native compatibility by making StyleSheet.create the identify function. * Improves React 18 support by inserting styles on eval. * Supports use with multiple windows (i.e., iframes) and shadow roots. * Supports nested LTR/RTL layouts. * Supports 3rd party compilers and extraction to static CSS. * Fixes static and dynamic short/longform deduplication. * Reduces browser support: Safari 10.1+, Chromium Edge, no IE, no legacy Android browsers. * Removes automatic vendor-prefixing of inline styles (for better perf). * Removes focus-visible polyfill as modern browsers no longer show focus rings for mouse interactions. Close #2208 Fix #2138 Fix #2196 Fix #2007 Fix #1517 --- flow-typed/npm/styleq.js | 34 ++ .../src/__tests__/index-test.js | 16 +- .../__snapshots__/index-test.js.snap | 48 +-- .../__snapshots__/index-test.js.snap | 36 -- .../AppRegistry/__tests__/index-test.js | 126 ++++--- .../AppRegistry/__tests__/index-test.node.js | 141 ++++++++ .../exports/AppRegistry/renderApplication.js | 4 +- .../__snapshots__/index-test.js.snap | 22 +- .../__snapshots__/index-test.js.snap | 36 +- .../__snapshots__/index-test.js.snap | 19 - .../Dimensions/__tests__/index-test.js | 25 +- .../I18nManager/__tests__/index-test.js | 30 -- .../src/exports/I18nManager/index.js | 10 +- .../__snapshots__/index-test.js.snap | 108 +++--- .../src/exports/Image/index.js | 30 +- .../__tests__/{index.js => index-test.js} | 11 +- .../src/exports/ImageBackground/index.js | 2 +- .../__tests__/{index.js => index-test.js} | 7 +- .../__snapshots__/index-test.js.snap | 47 ++- .../__snapshots__/index-test.js.snap | 8 +- .../StyleSheet/ReactNativePropRegistry.js | 43 --- .../src/exports/StyleSheet/StyleSheet.js | 65 ---- .../__snapshots__/compile-test.js.snap | 105 ------ .../createOrderedCSSStyleSheet-test.js.snap | 65 ---- .../createReactDOMStyle-test.js.snap | 66 ---- .../createStyleResolver-test.js.snap | 203 ----------- .../__snapshots__/flattenStyle-test.js.snap | 28 -- .../StyleSheet/__tests__/compile-test.js | 68 ---- ...s => compiler-createReactDOMStyle-test.js} | 88 ++++- .../__tests__/compiler-preprocess-test.js | 294 +++++++++++++++ .../StyleSheet/__tests__/compiler-test.js | 170 +++++++++ .../__tests__/createCompileableStyle-test.js | 120 ------- .../__tests__/createStyleResolver-test.js | 109 ------ ...=> dom-createOrderedCSSStyleSheet-test.js} | 107 ++++-- .../exports/StyleSheet/__tests__/dom-test.js | 60 ++++ .../StyleSheet/__tests__/dom-test.node.js | 34 ++ .../StyleSheet/__tests__/flattenStyle-test.js | 39 -- .../StyleSheet/__tests__/i18nStyle-test.js | 253 ------------- .../StyleSheet/__tests__/index-test.js | 334 ++++++++++++++++-- .../normalizeValueWithProperty-test.js | 20 -- .../StyleSheet/__tests__/validate-test.js | 42 +++ .../compiler/createReactDOMStyle.js | 200 +++++++++++ .../src/exports/StyleSheet/compiler/hash.js | 60 ++++ .../StyleSheet/compiler/hyphenateStyleName.js | 27 ++ .../{compile.js => compiler/index.js} | 125 +++---- .../StyleSheet/compiler/normalizeColor.js | 31 ++ .../normalizeValueWithProperty.js | 4 +- .../{i18nStyle.js => compiler/preprocess.js} | 106 ++++-- .../{ => compiler}/resolveShadowValue.js | 2 +- .../StyleSheet/compiler/unitlessNumbers.js | 76 ++++ .../src/exports/StyleSheet/constants.js | 59 ---- .../exports/StyleSheet/createCSSStyleSheet.js | 31 -- .../StyleSheet/createCompileableStyle.js | 70 ---- .../exports/StyleSheet/createReactDOMStyle.js | 190 ---------- .../exports/StyleSheet/createStyleResolver.js | 254 ------------- .../src/exports/StyleSheet/css.js | 26 -- .../StyleSheet/dom/createCSSStyleSheet.js | 42 +++ .../{ => dom}/createOrderedCSSStyleSheet.js | 24 +- .../src/exports/StyleSheet/dom/index.js | 85 +++++ .../src/exports/StyleSheet/flattenStyle.js | 47 --- .../src/exports/StyleSheet/index.js | 177 +++++++++- .../src/exports/StyleSheet/initialRules.js | 20 -- .../src/exports/StyleSheet/modality.js | 275 -------------- .../src/exports/StyleSheet/styleResolver.js | 12 - .../src/exports/StyleSheet/validate.js | 31 +- .../__snapshots__/index-test.js.snap | 12 +- .../__snapshots__/index-test.js.snap | 50 +-- .../src/exports/Text/index.js | 81 +++-- .../src/exports/TextInput/index.js | 28 +- .../__snapshots__/index-test.js.snap | 54 +-- .../src/exports/View/index.js | 31 +- .../src/exports/render/index.js | 17 +- .../src/modules/RTLContext/index.js | 15 + .../src/modules/createDOMProps/index.js | 55 +-- .../src/modules/flattenArray/index.js | 27 -- .../Animated/nodes/AnimatedStyle.js | 4 +- scripts/inline-style-prefixer/create.js | 19 +- 77 files changed, 2558 insertions(+), 2882 deletions(-) create mode 100644 flow-typed/npm/styleq.js delete mode 100644 packages/react-native-web/src/exports/AppRegistry/__tests__/__snapshots__/index-test.js.snap create mode 100644 packages/react-native-web/src/exports/AppRegistry/__tests__/index-test.node.js delete mode 100644 packages/react-native-web/src/exports/Dimensions/__tests__/__snapshots__/index-test.js.snap rename packages/react-native-web/src/exports/ImageBackground/__tests__/{index.js => index-test.js} (78%) rename packages/react-native-web/src/exports/Modal/__tests__/{index.js => index-test.js} (99%) delete mode 100644 packages/react-native-web/src/exports/StyleSheet/ReactNativePropRegistry.js delete mode 100644 packages/react-native-web/src/exports/StyleSheet/StyleSheet.js delete mode 100644 packages/react-native-web/src/exports/StyleSheet/__tests__/__snapshots__/compile-test.js.snap delete mode 100644 packages/react-native-web/src/exports/StyleSheet/__tests__/__snapshots__/createOrderedCSSStyleSheet-test.js.snap delete mode 100644 packages/react-native-web/src/exports/StyleSheet/__tests__/__snapshots__/createReactDOMStyle-test.js.snap delete mode 100644 packages/react-native-web/src/exports/StyleSheet/__tests__/__snapshots__/createStyleResolver-test.js.snap delete mode 100644 packages/react-native-web/src/exports/StyleSheet/__tests__/__snapshots__/flattenStyle-test.js.snap delete mode 100644 packages/react-native-web/src/exports/StyleSheet/__tests__/compile-test.js rename packages/react-native-web/src/exports/StyleSheet/__tests__/{createReactDOMStyle-test.js => compiler-createReactDOMStyle-test.js} (64%) create mode 100644 packages/react-native-web/src/exports/StyleSheet/__tests__/compiler-preprocess-test.js create mode 100644 packages/react-native-web/src/exports/StyleSheet/__tests__/compiler-test.js delete mode 100644 packages/react-native-web/src/exports/StyleSheet/__tests__/createCompileableStyle-test.js delete mode 100644 packages/react-native-web/src/exports/StyleSheet/__tests__/createStyleResolver-test.js rename packages/react-native-web/src/exports/StyleSheet/__tests__/{createOrderedCSSStyleSheet-test.js => dom-createOrderedCSSStyleSheet-test.js} (50%) create mode 100644 packages/react-native-web/src/exports/StyleSheet/__tests__/dom-test.js create mode 100644 packages/react-native-web/src/exports/StyleSheet/__tests__/dom-test.node.js delete mode 100644 packages/react-native-web/src/exports/StyleSheet/__tests__/flattenStyle-test.js delete mode 100644 packages/react-native-web/src/exports/StyleSheet/__tests__/i18nStyle-test.js delete mode 100644 packages/react-native-web/src/exports/StyleSheet/__tests__/normalizeValueWithProperty-test.js create mode 100644 packages/react-native-web/src/exports/StyleSheet/__tests__/validate-test.js create mode 100644 packages/react-native-web/src/exports/StyleSheet/compiler/createReactDOMStyle.js create mode 100644 packages/react-native-web/src/exports/StyleSheet/compiler/hash.js create mode 100644 packages/react-native-web/src/exports/StyleSheet/compiler/hyphenateStyleName.js rename packages/react-native-web/src/exports/StyleSheet/{compile.js => compiler/index.js} (73%) create mode 100644 packages/react-native-web/src/exports/StyleSheet/compiler/normalizeColor.js rename packages/react-native-web/src/exports/StyleSheet/{ => compiler}/normalizeValueWithProperty.js (87%) rename packages/react-native-web/src/exports/StyleSheet/{i18nStyle.js => compiler/preprocess.js} (57%) rename packages/react-native-web/src/exports/StyleSheet/{ => compiler}/resolveShadowValue.js (94%) create mode 100644 packages/react-native-web/src/exports/StyleSheet/compiler/unitlessNumbers.js delete mode 100644 packages/react-native-web/src/exports/StyleSheet/constants.js delete mode 100644 packages/react-native-web/src/exports/StyleSheet/createCSSStyleSheet.js delete mode 100644 packages/react-native-web/src/exports/StyleSheet/createCompileableStyle.js delete mode 100644 packages/react-native-web/src/exports/StyleSheet/createReactDOMStyle.js delete mode 100644 packages/react-native-web/src/exports/StyleSheet/createStyleResolver.js delete mode 100644 packages/react-native-web/src/exports/StyleSheet/css.js create mode 100644 packages/react-native-web/src/exports/StyleSheet/dom/createCSSStyleSheet.js rename packages/react-native-web/src/exports/StyleSheet/{ => dom}/createOrderedCSSStyleSheet.js (90%) create mode 100644 packages/react-native-web/src/exports/StyleSheet/dom/index.js delete mode 100644 packages/react-native-web/src/exports/StyleSheet/flattenStyle.js delete mode 100644 packages/react-native-web/src/exports/StyleSheet/initialRules.js delete mode 100644 packages/react-native-web/src/exports/StyleSheet/modality.js delete mode 100644 packages/react-native-web/src/exports/StyleSheet/styleResolver.js create mode 100644 packages/react-native-web/src/modules/RTLContext/index.js delete mode 100644 packages/react-native-web/src/modules/flattenArray/index.js diff --git a/flow-typed/npm/styleq.js b/flow-typed/npm/styleq.js new file mode 100644 index 00000000..a77fadf9 --- /dev/null +++ b/flow-typed/npm/styleq.js @@ -0,0 +1,34 @@ +type CompiledStyle = { + $$css: boolean, + [key: string]: string, +}; + +type InlineStyle = { + [key: string]: mixed, +}; + +type EitherStyle = CompiledStyle | InlineStyle; + +type StylesArray<+T> = T | $ReadOnlyArray>; +type Styles = StylesArray; +type Style<+T = EitherStyle> = StylesArray; + +type StyleqOptions = { + disableCache?: boolean, + disableMix?: boolean, + transform?: (CompiledStyle) => CompiledStyle, +}; + +type StyleqResult = [string, InlineStyle | null]; +type Styleq = (styles: Styles) => StyleqResult; + +type IStyleq = { + (...styles: $ReadOnlyArray): StyleqResult, + factory: (options?: StyleqOptions) => Styleq, +}; + +declare module "styleq" { + declare module.exports: { + styleq: IStyleq + }; +} diff --git a/packages/dom-event-testing-library/src/__tests__/index-test.js b/packages/dom-event-testing-library/src/__tests__/index-test.js index faa040e7..58518479 100644 --- a/packages/dom-event-testing-library/src/__tests__/index-test.js +++ b/packages/dom-event-testing-library/src/__tests__/index-test.js @@ -1,5 +1,3 @@ -/* eslint-env jasmine, jest */ - /** * Copyright (c) Facebook, Inc. and its affiliates. * @@ -49,7 +47,7 @@ describe('createEventTarget', () => { const target = createEventTarget(node); expect(target.node).toEqual(node); expect(Object.keys(target)).toMatchInlineSnapshot(` - Array [ + [ "node", "blur", "click", @@ -331,9 +329,7 @@ describe('createEventTarget', () => { }); /** - * Complex event sequences - * - * ...coming soon + * TODO: Complex event sequences */ /** @@ -343,24 +339,28 @@ describe('createEventTarget', () => { test('.setBoundingClientRect()', () => { const target = createEventTarget(node); expect(node.getBoundingClientRect()).toMatchInlineSnapshot(` - Object { + { "bottom": 0, "height": 0, "left": 0, "right": 0, "top": 0, "width": 0, + "x": 0, + "y": 0, } `); target.setBoundingClientRect({ x: 10, y: 20, width: 100, height: 200 }); expect(node.getBoundingClientRect()).toMatchInlineSnapshot(` - Object { + { "bottom": 220, "height": 200, "left": 10, "right": 110, "top": 20, "width": 100, + "x": 10, + "y": 20, } `); }); diff --git a/packages/react-native-web/src/exports/ActivityIndicator/__tests__/__snapshots__/index-test.js.snap b/packages/react-native-web/src/exports/ActivityIndicator/__tests__/__snapshots__/index-test.js.snap index 5a4bbcb8..51d701c6 100644 --- a/packages/react-native-web/src/exports/ActivityIndicator/__tests__/__snapshots__/index-test.js.snap +++ b/packages/react-native-web/src/exports/ActivityIndicator/__tests__/__snapshots__/index-test.js.snap @@ -5,11 +5,11 @@ exports[`components/ActivityIndicator prop "accessibilityLabel" value is set 1`] aria-label="accessibility label" aria-valuemax="1" aria-valuemin="0" - class="css-view-1dbjc4n r-alignItems-1awozwy r-justifyContent-1777fci" + class="css-view-175oi2r r-alignItems-1awozwy r-justifyContent-1777fci" role="progressbar" >
*{pointer-events:auto;} -.r-pointerEvents-12vffkv{pointer-events:none!important;}" -`; - -exports[`AppRegistry getApplication returns "element" and "getStyleElement" 1`] = ` - - - -`; - -exports[`AppRegistry getApplication returns "element" and "getStyleElement" 2`] = ` -"" -`; diff --git a/packages/react-native-web/src/exports/AppRegistry/__tests__/index-test.js b/packages/react-native-web/src/exports/AppRegistry/__tests__/index-test.js index 80809405..bde49cbc 100644 --- a/packages/react-native-web/src/exports/AppRegistry/__tests__/index-test.js +++ b/packages/react-native-web/src/exports/AppRegistry/__tests__/index-test.js @@ -1,76 +1,16 @@ -/* eslint-env jasmine, jest */ +/** + * Copyright (c) Nicolas Gallagher. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ import AppRegistry from '..'; -import ExecutionEnvironment from 'fbjs/lib/ExecutionEnvironment'; import React from 'react'; -import ReactDOMServer from 'react-dom/server'; -import { render } from '@testing-library/react'; -import StyleSheet from '../../StyleSheet'; -import Text from '../../Text'; -import View from '../../View'; -const canUseDOM = ExecutionEnvironment.canUseDOM; -const NoopComponent = () =>
; +const NoopComponent = () => React.createElement('div'); describe('AppRegistry', () => { - describe('getApplication', () => { - beforeEach(() => { - ExecutionEnvironment.canUseDOM = false; - }); - - afterEach(() => { - ExecutionEnvironment.canUseDOM = canUseDOM; - }); - - test('does not throw when missing appParameters', () => { - AppRegistry.registerComponent('App', () => NoopComponent); - expect(() => AppRegistry.getApplication('App')).not.toThrow(); - }); - - test('returns "element" and "getStyleElement"', () => { - AppRegistry.registerComponent('App', () => NoopComponent); - const { element, getStyleElement } = AppRegistry.getApplication('App', {}); - const styleElement = ReactDOMServer.renderToStaticMarkup(getStyleElement()); - - expect(element).toMatchSnapshot(); - expect(styleElement).toMatchSnapshot(); - }); - - test('"getStyleElement" adds props to " + `); + }); + + test('"getStyleElement" adds props to