From 09d420707f586710bb0f00981aca989b00f8761a Mon Sep 17 00:00:00 2001 From: Gabriel Donadel Dall'Agnol Date: Wed, 14 Sep 2022 05:08:10 -0700 Subject: [PATCH] feat: Add space-separated string support for fontVariant (#34641) Summary: This updates `fontVariant` to support space-separated string values, i.e., `'small-caps common-ligatures'`, thus aligning it with the [CSS Fonts Module Level 4](https://drafts.csswg.org/css-fonts/#font-variant-prop) specification as requested on https://github.com/facebook/react-native/issues/34425. This also adds unit tests to the `processFontVariant` function ensuring the style processing works as expected. ## Changelog [General] [Added] - Add space-separated string support for fontVariant Pull Request resolved: https://github.com/facebook/react-native/pull/34641 Test Plan: This can be tested either through `processFontVariant-tests` or by using the following code: ```js ``` Reviewed By: javache Differential Revision: D39423317 Pulled By: cipolleschi fbshipit-source-id: ad971addb423ed338e178528a11fe9d456c03e6e --- .../View/ReactNativeStyleAttributes.js | 3 +- Libraries/StyleSheet/StyleSheetTypes.js | 56 ++++++++++--------- .../__tests__/processFontVariant-test.js | 50 +++++++++++++++++ Libraries/StyleSheet/processFontVariant.js | 30 ++++++++++ 4 files changed, 111 insertions(+), 28 deletions(-) create mode 100644 Libraries/StyleSheet/__tests__/processFontVariant-test.js create mode 100644 Libraries/StyleSheet/processFontVariant.js diff --git a/Libraries/Components/View/ReactNativeStyleAttributes.js b/Libraries/Components/View/ReactNativeStyleAttributes.js index 28fd4596338890..ab2b30344237fa 100644 --- a/Libraries/Components/View/ReactNativeStyleAttributes.js +++ b/Libraries/Components/View/ReactNativeStyleAttributes.js @@ -10,6 +10,7 @@ import type {AnyAttributeType} from '../../Renderer/shims/ReactNativeTypes'; import processColor from '../../StyleSheet/processColor'; +import processFontVariant from '../../StyleSheet/processFontVariant'; import processTransform from '../../StyleSheet/processTransform'; import sizesDiffer from '../../Utilities/differ/sizesDiffer'; @@ -120,7 +121,7 @@ const ReactNativeStyleAttributes: {[string]: AnyAttributeType, ...} = { fontFamily: true, fontSize: true, fontStyle: true, - fontVariant: true, + fontVariant: {process: processFontVariant}, fontWeight: true, includeFontPadding: true, letterSpacing: true, diff --git a/Libraries/StyleSheet/StyleSheetTypes.js b/Libraries/StyleSheet/StyleSheetTypes.js index 8537b6c96de1bb..b50b47b4be64de 100644 --- a/Libraries/StyleSheet/StyleSheetTypes.js +++ b/Libraries/StyleSheet/StyleSheetTypes.js @@ -615,6 +615,34 @@ export type ____FontWeight_Internal = | 'heavy' | 'black'; +export type ____FontVariantArray_Internal = $ReadOnlyArray< + | 'small-caps' + | 'oldstyle-nums' + | 'lining-nums' + | 'tabular-nums' + | 'proportional-nums' + | 'stylistic-one' + | 'stylistic-two' + | 'stylistic-three' + | 'stylistic-four' + | 'stylistic-five' + | 'stylistic-six' + | 'stylistic-seven' + | 'stylistic-eight' + | 'stylistic-nine' + | 'stylistic-ten' + | 'stylistic-eleven' + | 'stylistic-twelve' + | 'stylistic-thirteen' + | 'stylistic-fourteen' + | 'stylistic-fifteen' + | 'stylistic-sixteen' + | 'stylistic-seventeen' + | 'stylistic-eighteen' + | 'stylistic-nineteen' + | 'stylistic-twenty', +>; + export type ____TextStyle_InternalCore = $ReadOnly<{ ...$Exact<____ViewStyle_Internal>, color?: ____ColorValue_Internal, @@ -622,33 +650,7 @@ export type ____TextStyle_InternalCore = $ReadOnly<{ fontSize?: number, fontStyle?: 'normal' | 'italic', fontWeight?: ____FontWeight_Internal, - fontVariant?: $ReadOnlyArray< - | 'small-caps' - | 'oldstyle-nums' - | 'lining-nums' - | 'tabular-nums' - | 'proportional-nums' - | 'stylistic-one' - | 'stylistic-two' - | 'stylistic-three' - | 'stylistic-four' - | 'stylistic-five' - | 'stylistic-six' - | 'stylistic-seven' - | 'stylistic-eight' - | 'stylistic-nine' - | 'stylistic-ten' - | 'stylistic-eleven' - | 'stylistic-twelve' - | 'stylistic-thirteen' - | 'stylistic-fourteen' - | 'stylistic-fifteen' - | 'stylistic-sixteen' - | 'stylistic-seventeen' - | 'stylistic-eighteen' - | 'stylistic-nineteen' - | 'stylistic-twenty', - >, + fontVariant?: ____FontVariantArray_Internal | string, textShadowOffset?: $ReadOnly<{ width: number, height: number, diff --git a/Libraries/StyleSheet/__tests__/processFontVariant-test.js b/Libraries/StyleSheet/__tests__/processFontVariant-test.js new file mode 100644 index 00000000000000..550d7d92b5cc3c --- /dev/null +++ b/Libraries/StyleSheet/__tests__/processFontVariant-test.js @@ -0,0 +1,50 @@ +/** + * 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. + * + * @format + * @emails oncall+react_native + */ + +'use strict'; + +const processFontVariant = require('../processFontVariant'); + +describe('processFontVariant', () => { + it('should accept arrays', () => { + expect(processFontVariant([])).toEqual([]); + expect(processFontVariant(['oldstyle-nums'])).toEqual(['oldstyle-nums']); + expect(processFontVariant(['proportional-nums', 'lining-nums'])).toEqual([ + 'proportional-nums', + 'lining-nums', + ]); + }); + + it('should accept string values', () => { + expect(processFontVariant('oldstyle-nums')).toEqual(['oldstyle-nums']); + expect(processFontVariant('lining-nums ')).toEqual(['lining-nums']); + expect(processFontVariant(' tabular-nums')).toEqual(['tabular-nums']); + }); + + it('should accept string with multiple values', () => { + expect(processFontVariant('oldstyle-nums lining-nums')).toEqual([ + 'oldstyle-nums', + 'lining-nums', + ]); + expect( + processFontVariant('proportional-nums oldstyle-nums lining-nums'), + ).toEqual(['proportional-nums', 'oldstyle-nums', 'lining-nums']); + expect( + processFontVariant( + ' small-caps proportional-nums oldstyle-nums lining-nums', + ), + ).toEqual([ + 'small-caps', + 'proportional-nums', + 'oldstyle-nums', + 'lining-nums', + ]); + }); +}); diff --git a/Libraries/StyleSheet/processFontVariant.js b/Libraries/StyleSheet/processFontVariant.js new file mode 100644 index 00000000000000..9f11bbbe3beaa1 --- /dev/null +++ b/Libraries/StyleSheet/processFontVariant.js @@ -0,0 +1,30 @@ +/** + * 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. + * + * @format + * @flow + */ + +'use strict'; + +import type {____FontVariantArray_Internal} from './StyleSheetTypes'; + +function processFontVariant( + fontVariant: ____FontVariantArray_Internal | string, +): ?____FontVariantArray_Internal { + if (Array.isArray(fontVariant)) { + return fontVariant; + } + + // $FlowFixMe[incompatible-type] + const match: ?____FontVariantArray_Internal = fontVariant + .split(' ') + .filter(Boolean); + + return match; +} + +module.exports = processFontVariant;