From 7bceb502dc288643e72d1e0f01671d869c41726a Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Tue, 5 Dec 2023 12:28:54 +0100 Subject: [PATCH 1/6] [TS migration] Migrate 'InlineCodeBlock' component --- src/components/InlineCodeBlock/WrappedText.js | 77 ------------------- .../InlineCodeBlock/WrappedText.tsx | 63 +++++++++++++++ src/components/InlineCodeBlock/index.js | 22 ------ .../{index.native.js => index.native.tsx} | 17 ++-- src/components/InlineCodeBlock/index.tsx | 21 +++++ .../inlineCodeBlockPropTypes.js | 10 --- src/components/InlineCodeBlock/types.ts | 11 +++ src/styles/codeStyles/types.ts | 2 +- 8 files changed, 105 insertions(+), 118 deletions(-) delete mode 100644 src/components/InlineCodeBlock/WrappedText.js create mode 100644 src/components/InlineCodeBlock/WrappedText.tsx delete mode 100644 src/components/InlineCodeBlock/index.js rename src/components/InlineCodeBlock/{index.native.js => index.native.tsx} (50%) create mode 100644 src/components/InlineCodeBlock/index.tsx delete mode 100644 src/components/InlineCodeBlock/inlineCodeBlockPropTypes.js create mode 100644 src/components/InlineCodeBlock/types.ts diff --git a/src/components/InlineCodeBlock/WrappedText.js b/src/components/InlineCodeBlock/WrappedText.js deleted file mode 100644 index f00ec891116b..000000000000 --- a/src/components/InlineCodeBlock/WrappedText.js +++ /dev/null @@ -1,77 +0,0 @@ -import PropTypes from 'prop-types'; -import React, {Fragment} from 'react'; -import {View} from 'react-native'; -import _ from 'underscore'; -import Text from '@components/Text'; -import useThemeStyles from '@styles/useThemeStyles'; -import CONST from '@src/CONST'; - -/** - * Breaks the text into matrix - * for eg: My Name is Rajat - * [ - * [My,' ',Name,' ',' ',is,' ',Rajat], - * ] - * - * @param {String} text - * @returns {Array} - */ -function getTextMatrix(text) { - return _.map(text.split('\n'), (row) => _.without(row.split(CONST.REGEX.SPACE_OR_EMOJI), '')); -} - -const propTypes = { - /** Required text */ - children: PropTypes.string.isRequired, - - /** Style to be applied to Text */ - // eslint-disable-next-line react/forbid-prop-types - textStyles: PropTypes.arrayOf(PropTypes.object), - - /** Style for each word(Token) in the text, remember that token also includes whitespaces among words */ - // eslint-disable-next-line react/forbid-prop-types - wordStyles: PropTypes.arrayOf(PropTypes.object), -}; - -const defaultProps = { - textStyles: [], - wordStyles: [], -}; - -function WrappedText(props) { - const styles = useThemeStyles(); - if (!_.isString(props.children)) { - return null; - } - - const textMatrix = getTextMatrix(props.children); - return ( - <> - {_.map(textMatrix, (rowText, rowIndex) => ( - - {_.map(rowText, (colText, colIndex) => ( - // Outer View is important to vertically center the Text - - - {colText} - - - ))} - - ))} - - ); -} - -WrappedText.propTypes = propTypes; -WrappedText.defaultProps = defaultProps; -WrappedText.displayName = 'WrappedText'; - -export default WrappedText; diff --git a/src/components/InlineCodeBlock/WrappedText.tsx b/src/components/InlineCodeBlock/WrappedText.tsx new file mode 100644 index 000000000000..1cb6becd70ea --- /dev/null +++ b/src/components/InlineCodeBlock/WrappedText.tsx @@ -0,0 +1,63 @@ +import React, {Fragment} from 'react'; +import {StyleProp, TextStyle, View, ViewStyle} from 'react-native'; +import Text from '@components/Text'; +import useThemeStyles from '@styles/useThemeStyles'; +import CONST from '@src/CONST'; +import type ChildrenProps from '@src/types/utils/ChildrenProps'; + +type WrappedTextProps = ChildrenProps & { + /** Style to be applied to Text */ + textStyles?: StyleProp; + + /** Style for each word(Token) in the text, remember that token also includes whitespaces among words */ + wordStyles?: StyleProp; +}; + +/** + * Breaks the text into matrix + * for eg: My Name is Rajat + * [ + * [My,' ',Name,' ',' ',is,' ',Rajat], + * ] + */ +function getTextMatrix(text: string): string[][] { + return text.split('\n').map((row) => row.split(CONST.REGEX.SPACE_OR_EMOJI).filter((value) => value !== '')); +} + +function WrappedText({children, wordStyles, textStyles}: WrappedTextProps) { + const styles = useThemeStyles(); + + if (typeof children !== 'string') { + return null; + } + + const textMatrix = getTextMatrix(children); + + return ( + <> + {textMatrix.map((rowText, rowIndex) => ( + + {rowText.map((colText, colIndex) => ( + // Outer View is important to vertically center the Text + + + {colText} + + + ))} + + ))} + + ); +} + +WrappedText.displayName = 'WrappedText'; + +export default WrappedText; diff --git a/src/components/InlineCodeBlock/index.js b/src/components/InlineCodeBlock/index.js deleted file mode 100644 index 84666931d9b2..000000000000 --- a/src/components/InlineCodeBlock/index.js +++ /dev/null @@ -1,22 +0,0 @@ -import _ from 'lodash'; -import React from 'react'; -import Text from '@components/Text'; -import inlineCodeBlockPropTypes from './inlineCodeBlockPropTypes'; - -function InlineCodeBlock(props) { - const TDefaultRenderer = props.TDefaultRenderer; - const textStyles = _.omit(props.textStyle, 'textDecorationLine'); - - return ( - - {props.defaultRendererProps.tnode.data} - - ); -} - -InlineCodeBlock.propTypes = inlineCodeBlockPropTypes; -InlineCodeBlock.displayName = 'InlineCodeBlock'; -export default InlineCodeBlock; diff --git a/src/components/InlineCodeBlock/index.native.js b/src/components/InlineCodeBlock/index.native.tsx similarity index 50% rename from src/components/InlineCodeBlock/index.native.js rename to src/components/InlineCodeBlock/index.native.tsx index 983463222532..308b88e76e88 100644 --- a/src/components/InlineCodeBlock/index.native.js +++ b/src/components/InlineCodeBlock/index.native.tsx @@ -1,26 +1,27 @@ import React from 'react'; +import type {TText} from 'react-native-render-html'; import useThemeStyles from '@styles/useThemeStyles'; -import inlineCodeBlockPropTypes from './inlineCodeBlockPropTypes'; +import type InlineCodeBlockProps from './types'; import WrappedText from './WrappedText'; -function InlineCodeBlock(props) { +function InlineCodeBlock({TDefaultRenderer, defaultRendererProps, textStyle, boxModelStyle}: InlineCodeBlockProps) { const styles = useThemeStyles(); - const TDefaultRenderer = props.TDefaultRenderer; + return ( - {props.defaultRendererProps.tnode.data} + {defaultRendererProps.tnode.data} ); } -InlineCodeBlock.propTypes = inlineCodeBlockPropTypes; InlineCodeBlock.displayName = 'InlineCodeBlock'; + export default InlineCodeBlock; diff --git a/src/components/InlineCodeBlock/index.tsx b/src/components/InlineCodeBlock/index.tsx new file mode 100644 index 000000000000..a89c1785cfca --- /dev/null +++ b/src/components/InlineCodeBlock/index.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import type {TText} from 'react-native-render-html'; +import Text from '@components/Text'; +import type InlineCodeBlockProps from './types'; + +function InlineCodeBlock({TDefaultRenderer, textStyle, defaultRendererProps, boxModelStyle}: InlineCodeBlockProps) { + const {textDecorationLine, ...textStyles} = textStyle; + + return ( + + {defaultRendererProps.tnode.data} + + ); +} + +InlineCodeBlock.displayName = 'InlineCodeBlock'; + +export default InlineCodeBlock; diff --git a/src/components/InlineCodeBlock/inlineCodeBlockPropTypes.js b/src/components/InlineCodeBlock/inlineCodeBlockPropTypes.js deleted file mode 100644 index e8430d17d849..000000000000 --- a/src/components/InlineCodeBlock/inlineCodeBlockPropTypes.js +++ /dev/null @@ -1,10 +0,0 @@ -import PropTypes from 'prop-types'; - -const inlineCodeBlockPropTypes = { - TDefaultRenderer: PropTypes.func.isRequired, - defaultRendererProps: PropTypes.object.isRequired, - boxModelStyle: PropTypes.any.isRequired, - textStyle: PropTypes.any.isRequired, -}; - -export default inlineCodeBlockPropTypes; diff --git a/src/components/InlineCodeBlock/types.ts b/src/components/InlineCodeBlock/types.ts new file mode 100644 index 000000000000..e9e93d85cf30 --- /dev/null +++ b/src/components/InlineCodeBlock/types.ts @@ -0,0 +1,11 @@ +import {TextStyle, ViewStyle} from 'react-native'; +import {TDefaultRenderer, TDefaultRendererProps, TText} from 'react-native-render-html'; + +type InlineCodeBlockProps = { + TDefaultRenderer: TDefaultRenderer; + textStyle: TextStyle; + defaultRendererProps: TDefaultRendererProps; + boxModelStyle: ViewStyle & TextStyle; +}; + +export default InlineCodeBlockProps; diff --git a/src/styles/codeStyles/types.ts b/src/styles/codeStyles/types.ts index 25e35f492089..f223d980e67b 100644 --- a/src/styles/codeStyles/types.ts +++ b/src/styles/codeStyles/types.ts @@ -1,7 +1,7 @@ import {TextStyle, ViewStyle} from 'react-native'; type CodeWordWrapperStyles = ViewStyle; -type CodeWordStyles = TextStyle; +type CodeWordStyles = ViewStyle; type CodeTextStyles = TextStyle; export type {CodeTextStyles, CodeWordStyles, CodeWordWrapperStyles}; From 29e8e638b0213696a7010e615884d993ea81cba1 Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Tue, 5 Dec 2023 17:26:37 +0100 Subject: [PATCH 2/6] Update type import --- src/components/InlineCodeBlock/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/InlineCodeBlock/types.ts b/src/components/InlineCodeBlock/types.ts index e9e93d85cf30..314c458b665a 100644 --- a/src/components/InlineCodeBlock/types.ts +++ b/src/components/InlineCodeBlock/types.ts @@ -1,5 +1,5 @@ import {TextStyle, ViewStyle} from 'react-native'; -import {TDefaultRenderer, TDefaultRendererProps, TText} from 'react-native-render-html'; +import type {TDefaultRenderer, TDefaultRendererProps, TText} from 'react-native-render-html'; type InlineCodeBlockProps = { TDefaultRenderer: TDefaultRenderer; From 0d7757821c736780851e66eeeae23427198334c1 Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Tue, 5 Dec 2023 17:33:12 +0100 Subject: [PATCH 3/6] Remove fragment --- .../InlineCodeBlock/WrappedText.tsx | 36 +++++++++---------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/src/components/InlineCodeBlock/WrappedText.tsx b/src/components/InlineCodeBlock/WrappedText.tsx index 1cb6becd70ea..1cb1322ee5a6 100644 --- a/src/components/InlineCodeBlock/WrappedText.tsx +++ b/src/components/InlineCodeBlock/WrappedText.tsx @@ -33,29 +33,25 @@ function WrappedText({children, wordStyles, textStyles}: WrappedTextProps) { const textMatrix = getTextMatrix(children); - return ( - <> - {textMatrix.map((rowText, rowIndex) => ( - ( + + {rowText.map((colText, colIndex) => ( + // Outer View is important to vertically center the Text + - {rowText.map((colText, colIndex) => ( - // Outer View is important to vertically center the Text - - - {colText} - - - ))} - + + {colText} + + ))} - - ); + + )); } WrappedText.displayName = 'WrappedText'; From b75f5134a1be064ea252110382d5f99d6c70c981 Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Wed, 6 Dec 2023 10:08:22 +0100 Subject: [PATCH 4/6] Update InlineCodeBlockProps typing --- src/components/InlineCodeBlock/index.tsx | 6 ++++-- src/components/InlineCodeBlock/types.ts | 6 +++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/components/InlineCodeBlock/index.tsx b/src/components/InlineCodeBlock/index.tsx index a89c1785cfca..0613191c0534 100644 --- a/src/components/InlineCodeBlock/index.tsx +++ b/src/components/InlineCodeBlock/index.tsx @@ -1,17 +1,19 @@ import React from 'react'; +import {StyleProp, StyleSheet, TextStyle} from 'react-native'; import type {TText} from 'react-native-render-html'; import Text from '@components/Text'; import type InlineCodeBlockProps from './types'; function InlineCodeBlock({TDefaultRenderer, textStyle, defaultRendererProps, boxModelStyle}: InlineCodeBlockProps) { - const {textDecorationLine, ...textStyles} = textStyle; + const flattenTextStyle = StyleSheet.flatten(textStyle); + const {textDecorationLine, ...textStyles} = flattenTextStyle; return ( - {defaultRendererProps.tnode.data} + , textStyles]}>{defaultRendererProps.tnode.data} ); } diff --git a/src/components/InlineCodeBlock/types.ts b/src/components/InlineCodeBlock/types.ts index 314c458b665a..8554a722f865 100644 --- a/src/components/InlineCodeBlock/types.ts +++ b/src/components/InlineCodeBlock/types.ts @@ -1,11 +1,11 @@ -import {TextStyle, ViewStyle} from 'react-native'; +import {StyleProp, TextStyle, ViewStyle} from 'react-native'; import type {TDefaultRenderer, TDefaultRendererProps, TText} from 'react-native-render-html'; type InlineCodeBlockProps = { TDefaultRenderer: TDefaultRenderer; - textStyle: TextStyle; + textStyle: StyleProp; defaultRendererProps: TDefaultRendererProps; - boxModelStyle: ViewStyle & TextStyle; + boxModelStyle: StyleProp; }; export default InlineCodeBlockProps; From 0c300b9410ea75f6e583856f6959e7f7fcba246f Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Fri, 8 Dec 2023 11:56:06 +0100 Subject: [PATCH 5/6] Update boxModelStyle typing --- src/components/InlineCodeBlock/index.tsx | 4 ++-- src/components/InlineCodeBlock/types.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/InlineCodeBlock/index.tsx b/src/components/InlineCodeBlock/index.tsx index 0613191c0534..0802d4752661 100644 --- a/src/components/InlineCodeBlock/index.tsx +++ b/src/components/InlineCodeBlock/index.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import {StyleProp, StyleSheet, TextStyle} from 'react-native'; +import {StyleSheet} from 'react-native'; import type {TText} from 'react-native-render-html'; import Text from '@components/Text'; import type InlineCodeBlockProps from './types'; @@ -13,7 +13,7 @@ function InlineCodeBlock({TDefaultRenderer, textStyle, // eslint-disable-next-line react/jsx-props-no-spreading {...defaultRendererProps} > - , textStyles]}>{defaultRendererProps.tnode.data} + {defaultRendererProps.tnode.data} ); } diff --git a/src/components/InlineCodeBlock/types.ts b/src/components/InlineCodeBlock/types.ts index 8554a722f865..a100177e41a7 100644 --- a/src/components/InlineCodeBlock/types.ts +++ b/src/components/InlineCodeBlock/types.ts @@ -5,7 +5,7 @@ type InlineCodeBlockProps = { TDefaultRenderer: TDefaultRenderer; textStyle: StyleProp; defaultRendererProps: TDefaultRendererProps; - boxModelStyle: StyleProp; + boxModelStyle: StyleProp; }; export default InlineCodeBlockProps; From 9a6f7a470b9b7492911cec0a26cc9e5ef929e55f Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Mon, 11 Dec 2023 16:37:20 +0100 Subject: [PATCH 6/6] Improve comments --- src/components/InlineCodeBlock/WrappedText.tsx | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/components/InlineCodeBlock/WrappedText.tsx b/src/components/InlineCodeBlock/WrappedText.tsx index 1cb1322ee5a6..6dbd17f18e2a 100644 --- a/src/components/InlineCodeBlock/WrappedText.tsx +++ b/src/components/InlineCodeBlock/WrappedText.tsx @@ -9,16 +9,23 @@ type WrappedTextProps = ChildrenProps & { /** Style to be applied to Text */ textStyles?: StyleProp; - /** Style for each word(Token) in the text, remember that token also includes whitespaces among words */ + /** + * Style for each individual word (token) in the text. Note that a token can also include whitespace characters between words. + */ wordStyles?: StyleProp; }; /** * Breaks the text into matrix - * for eg: My Name is Rajat - * [ - * [My,' ',Name,' ',' ',is,' ',Rajat], - * ] + * + * @example + * const text = "My Name is Rajat"; + * const resultMatrix = getTextMatrix(text); + * console.log(resultMatrix); + * // Output: + * // [ + * // ['My', ' ', 'Name', ' ', 'is', ' ', 'Rajat'], + * // ] */ function getTextMatrix(text: string): string[][] { return text.split('\n').map((row) => row.split(CONST.REGEX.SPACE_OR_EMOJI).filter((value) => value !== ''));