diff --git a/src/components/HTMLEngineProvider/BaseHTMLEngineProvider.js b/src/components/HTMLEngineProvider/BaseHTMLEngineProvider.tsx
similarity index 55%
rename from src/components/HTMLEngineProvider/BaseHTMLEngineProvider.js
rename to src/components/HTMLEngineProvider/BaseHTMLEngineProvider.tsx
index 46d04ca9404d..690f2fc6883a 100755
--- a/src/components/HTMLEngineProvider/BaseHTMLEngineProvider.js
+++ b/src/components/HTMLEngineProvider/BaseHTMLEngineProvider.tsx
@@ -1,27 +1,19 @@
-import PropTypes from 'prop-types';
import React, {useMemo} from 'react';
-import {defaultHTMLElementModels, RenderHTMLConfigProvider, TRenderEngineProvider} from 'react-native-render-html';
-import _ from 'underscore';
+import type {TextProps} from 'react-native';
+import {HTMLContentModel, HTMLElementModel, RenderHTMLConfigProvider, TRenderEngineProvider} from 'react-native-render-html';
import useThemeStyles from '@hooks/useThemeStyles';
import convertToLTR from '@libs/convertToLTR';
import FontUtils from '@styles/utils/FontUtils';
+import type ChildrenProps from '@src/types/utils/ChildrenProps';
import * as HTMLEngineUtils from './htmlEngineUtils';
import htmlRenderers from './HTMLRenderers';
-const propTypes = {
+type BaseHTMLEngineProviderProps = ChildrenProps & {
/** Whether text elements should be selectable */
- textSelectable: PropTypes.bool,
+ textSelectable?: boolean;
/** Handle line breaks according to the HTML standard (default on web) */
- enableExperimentalBRCollapsing: PropTypes.bool,
-
- children: PropTypes.node,
-};
-
-const defaultProps = {
- textSelectable: false,
- children: null,
- enableExperimentalBRCollapsing: false,
+ enableExperimentalBRCollapsing?: boolean;
};
// We are using the explicit composite architecture for performance gains.
@@ -29,52 +21,62 @@ const defaultProps = {
// context to RenderHTMLSource components. See https://git.io/JRcZb
// Beware that each prop should be referentialy stable between renders to avoid
// costly invalidations and commits.
-function BaseHTMLEngineProvider(props) {
+function BaseHTMLEngineProvider({textSelectable = false, children, enableExperimentalBRCollapsing = false}: BaseHTMLEngineProviderProps) {
const styles = useThemeStyles();
// Declare nonstandard tags and their content model here
+ /* eslint-disable @typescript-eslint/naming-convention */
const customHTMLElementModels = useMemo(
() => ({
- edited: defaultHTMLElementModels.span.extend({
+ edited: HTMLElementModel.fromCustomModel({
tagName: 'edited',
+ contentModel: HTMLContentModel.textual,
}),
- 'alert-text': defaultHTMLElementModels.div.extend({
+ 'alert-text': HTMLElementModel.fromCustomModel({
tagName: 'alert-text',
mixedUAStyles: {...styles.formError, ...styles.mb0},
+ contentModel: HTMLContentModel.block,
}),
- 'muted-text': defaultHTMLElementModels.div.extend({
+ 'muted-text': HTMLElementModel.fromCustomModel({
tagName: 'muted-text',
mixedUAStyles: {...styles.colorMuted, ...styles.mb0},
+ contentModel: HTMLContentModel.block,
}),
- comment: defaultHTMLElementModels.div.extend({
+ comment: HTMLElementModel.fromCustomModel({
tagName: 'comment',
mixedUAStyles: {whiteSpace: 'pre'},
+ contentModel: HTMLContentModel.block,
}),
- 'email-comment': defaultHTMLElementModels.div.extend({
+ 'email-comment': HTMLElementModel.fromCustomModel({
tagName: 'email-comment',
mixedUAStyles: {whiteSpace: 'normal'},
+ contentModel: HTMLContentModel.block,
}),
- strong: defaultHTMLElementModels.span.extend({
+ strong: HTMLElementModel.fromCustomModel({
tagName: 'strong',
mixedUAStyles: {whiteSpace: 'pre'},
+ contentModel: HTMLContentModel.textual,
}),
- 'mention-user': defaultHTMLElementModels.span.extend({tagName: 'mention-user'}),
- 'mention-here': defaultHTMLElementModels.span.extend({tagName: 'mention-here'}),
- 'next-step': defaultHTMLElementModels.span.extend({
+ 'mention-user': HTMLElementModel.fromCustomModel({tagName: 'mention-user', contentModel: HTMLContentModel.textual}),
+ 'mention-here': HTMLElementModel.fromCustomModel({tagName: 'mention-here', contentModel: HTMLContentModel.textual}),
+ 'next-step': HTMLElementModel.fromCustomModel({
tagName: 'next-step',
mixedUAStyles: {...styles.textLabelSupporting, ...styles.lh16},
+ contentModel: HTMLContentModel.textual,
}),
- 'next-step-email': defaultHTMLElementModels.span.extend({tagName: 'next-step-email'}),
- video: defaultHTMLElementModels.div.extend({
+ 'next-step-email': HTMLElementModel.fromCustomModel({tagName: 'next-step-email', contentModel: HTMLContentModel.textual}),
+ video: HTMLElementModel.fromCustomModel({
tagName: 'video',
mixedUAStyles: {whiteSpace: 'pre'},
+ contentModel: HTMLContentModel.block,
}),
}),
[styles.colorMuted, styles.formError, styles.mb0, styles.textLabelSupporting, styles.lh16],
);
+ /* eslint-enable @typescript-eslint/naming-convention */
// We need to memoize this prop to make it referentially stable.
- const defaultTextProps = useMemo(() => ({selectable: props.textSelectable, allowFontScaling: false, textBreakStrategy: 'simple'}), [props.textSelectable]);
+ const defaultTextProps: TextProps = useMemo(() => ({selectable: textSelectable, allowFontScaling: false, textBreakStrategy: 'simple'}), [textSelectable]);
const defaultViewProps = {style: [styles.alignItemsStart, styles.userSelectText]};
return (
(text.data = convertToLTR(text.data)),
@@ -91,18 +93,17 @@ function BaseHTMLEngineProvider(props) {
- {props.children}
+ {children}
);
}
BaseHTMLEngineProvider.displayName = 'BaseHTMLEngineProvider';
-BaseHTMLEngineProvider.propTypes = propTypes;
-BaseHTMLEngineProvider.defaultProps = defaultProps;
export default BaseHTMLEngineProvider;
diff --git a/src/components/HTMLEngineProvider/htmlEnginePropTypes.js b/src/components/HTMLEngineProvider/htmlEnginePropTypes.js
deleted file mode 100644
index 6c8537c8d228..000000000000
--- a/src/components/HTMLEngineProvider/htmlEnginePropTypes.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import PropTypes from 'prop-types';
-
-const propTypes = {
- children: PropTypes.node,
-
- /** Optional debug flag. Prints the TRT in the console when true. */
- debug: PropTypes.bool,
-};
-
-const defaultProps = {
- children: null,
- debug: false,
-};
-
-export {propTypes, defaultProps};
diff --git a/src/components/HTMLEngineProvider/htmlEngineUtils.js b/src/components/HTMLEngineProvider/htmlEngineUtils.ts
similarity index 57%
rename from src/components/HTMLEngineProvider/htmlEngineUtils.js
rename to src/components/HTMLEngineProvider/htmlEngineUtils.ts
index 4495cb8ff136..5f082424a565 100644
--- a/src/components/HTMLEngineProvider/htmlEngineUtils.js
+++ b/src/components/HTMLEngineProvider/htmlEngineUtils.ts
@@ -1,4 +1,6 @@
-import lodashGet from 'lodash/get';
+import type {TNode} from 'react-native-render-html';
+
+type Predicate = (node: TNode) => boolean;
const MAX_IMG_DIMENSIONS = 512;
@@ -7,12 +9,12 @@ const MAX_IMG_DIMENSIONS = 512;
* is used by the HTML component in the default renderer for img tags to scale
* down images that would otherwise overflow horizontally.
*
- * @param {string} tagName - The name of the tag for which max width should be constrained.
- * @param {number} contentWidth - The content width provided to the HTML
+ * @param contentWidth - The content width provided to the HTML
* component.
- * @returns {number} The minimum between contentWidth and MAX_IMG_DIMENSIONS
+ * @param tagName - The name of the tag for which max width should be constrained.
+ * @returns The minimum between contentWidth and MAX_IMG_DIMENSIONS
*/
-function computeEmbeddedMaxWidth(tagName, contentWidth) {
+function computeEmbeddedMaxWidth(contentWidth: number, tagName: string): number {
if (tagName === 'img') {
return Math.min(MAX_IMG_DIMENSIONS, contentWidth);
}
@@ -22,21 +24,15 @@ function computeEmbeddedMaxWidth(tagName, contentWidth) {
/**
* Check if tagName is equal to any of our custom tags wrapping chat comments.
*
- * @param {string} tagName
- * @returns {Boolean}
*/
-function isCommentTag(tagName) {
+function isCommentTag(tagName: string): boolean {
return tagName === 'email-comment' || tagName === 'comment';
}
/**
* Check if there is an ancestor node for which the predicate returns true.
- *
- * @param {TNode} tnode
- * @param {Function} predicate
- * @returns {Boolean}
*/
-function isChildOfNode(tnode, predicate) {
+function isChildOfNode(tnode: TNode, predicate: Predicate): boolean {
let currentNode = tnode.parent;
while (currentNode) {
if (predicate(currentNode)) {
@@ -50,21 +46,17 @@ function isChildOfNode(tnode, predicate) {
/**
* Check if there is an ancestor node with name 'comment'.
* Finding node with name 'comment' flags that we are rendering a comment.
- * @param {TNode} tnode
- * @returns {Boolean}
*/
-function isChildOfComment(tnode) {
- return isChildOfNode(tnode, (node) => isCommentTag(lodashGet(node, 'domNode.name', '')));
+function isChildOfComment(tnode: TNode): boolean {
+ return isChildOfNode(tnode, (node) => node.domNode?.name !== undefined && isCommentTag(node.domNode.name));
}
/**
* Check if there is an ancestor node with the name 'h1'.
* Finding a node with the name 'h1' flags that we are rendering inside an h1 element.
- * @param {TNode} tnode
- * @returns {Boolean}
*/
-function isChildOfH1(tnode) {
- return isChildOfNode(tnode, (node) => lodashGet(node, 'domNode.name', '').toLowerCase() === 'h1');
+function isChildOfH1(tnode: TNode): boolean {
+ return isChildOfNode(tnode, (node) => node.domNode?.name !== undefined && node.domNode.name.toLowerCase() === 'h1');
}
export {computeEmbeddedMaxWidth, isChildOfComment, isCommentTag, isChildOfH1};
diff --git a/src/components/HTMLEngineProvider/index.js b/src/components/HTMLEngineProvider/index.js
deleted file mode 100755
index 8a8e96269411..000000000000
--- a/src/components/HTMLEngineProvider/index.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import React from 'react';
-import withWindowDimensions from '@components/withWindowDimensions';
-import * as DeviceCapabilities from '@libs/DeviceCapabilities';
-import BaseHTMLEngineProvider from './BaseHTMLEngineProvider';
-import {defaultProps, propTypes} from './htmlEnginePropTypes';
-
-function HTMLEngineProvider(props) {
- return (
-
- {props.children}
-
- );
-}
-
-HTMLEngineProvider.displayName = 'HTMLEngineProvider';
-HTMLEngineProvider.propTypes = propTypes;
-HTMLEngineProvider.defaultProps = defaultProps;
-
-export default withWindowDimensions(HTMLEngineProvider);
diff --git a/src/components/HTMLEngineProvider/index.native.js b/src/components/HTMLEngineProvider/index.native.js
deleted file mode 100755
index f760a5a36649..000000000000
--- a/src/components/HTMLEngineProvider/index.native.js
+++ /dev/null
@@ -1,20 +0,0 @@
-import React from 'react';
-import BaseHTMLEngineProvider from './BaseHTMLEngineProvider';
-import {defaultProps, propTypes} from './htmlEnginePropTypes';
-
-function HTMLEngineProvider(props) {
- return (
-
- {props.children}
-
- );
-}
-
-HTMLEngineProvider.displayName = 'HTMLEngineProvider';
-HTMLEngineProvider.propTypes = propTypes;
-HTMLEngineProvider.defaultProps = defaultProps;
-
-export default HTMLEngineProvider;
diff --git a/src/components/HTMLEngineProvider/index.native.tsx b/src/components/HTMLEngineProvider/index.native.tsx
new file mode 100755
index 000000000000..c77bcaf7c5e3
--- /dev/null
+++ b/src/components/HTMLEngineProvider/index.native.tsx
@@ -0,0 +1,11 @@
+import React from 'react';
+import type ChildrenProps from '@src/types/utils/ChildrenProps';
+import BaseHTMLEngineProvider from './BaseHTMLEngineProvider';
+
+function HTMLEngineProvider({children}: ChildrenProps) {
+ return {children};
+}
+
+HTMLEngineProvider.displayName = 'HTMLEngineProvider';
+
+export default HTMLEngineProvider;
diff --git a/src/components/HTMLEngineProvider/index.tsx b/src/components/HTMLEngineProvider/index.tsx
new file mode 100755
index 000000000000..9addb549d13a
--- /dev/null
+++ b/src/components/HTMLEngineProvider/index.tsx
@@ -0,0 +1,15 @@
+import React from 'react';
+import useWindowDimensions from '@hooks/useWindowDimensions';
+import * as DeviceCapabilities from '@libs/DeviceCapabilities';
+import type ChildrenProps from '@src/types/utils/ChildrenProps';
+import BaseHTMLEngineProvider from './BaseHTMLEngineProvider';
+
+function HTMLEngineProvider({children}: ChildrenProps) {
+ const {isSmallScreenWidth} = useWindowDimensions();
+
+ return {children};
+}
+
+HTMLEngineProvider.displayName = 'HTMLEngineProvider';
+
+export default HTMLEngineProvider;