diff --git a/packages/render-html/src/RenderHTMLConfigProvider.tsx b/packages/render-html/src/RenderHTMLConfigProvider.tsx
index 7d2e53b10..97bfde1d4 100644
--- a/packages/render-html/src/RenderHTMLConfigProvider.tsx
+++ b/packages/render-html/src/RenderHTMLConfigProvider.tsx
@@ -26,6 +26,7 @@ export const renderHTMLConfigPropTypes: RenderHTMLConfigPropTypes = {
bypassAnonymousTPhrasingNodes: PropTypes.bool,
defaultTextProps: PropTypes.object,
defaultViewProps: PropTypes.object,
+ enableExperimentalGhostLinesPrevention: PropTypes.bool,
enableExperimentalMarginCollapsing: PropTypes.bool,
remoteErrorView: PropTypes.func,
remoteLoadingView: PropTypes.func,
diff --git a/packages/render-html/src/TTextRenderer.ts b/packages/render-html/src/TTextRenderer.ts
index 27c3508c2..b222b2ca4 100644
--- a/packages/render-html/src/TTextRenderer.ts
+++ b/packages/render-html/src/TTextRenderer.ts
@@ -29,7 +29,16 @@ function TStandardTextRenderer(props: TNodeSubRendererProps) {
export default function TTextRenderer(props: TNodeSubRendererProps) {
const InternalTextRenderer = useInternalTextRenderer(props.tnode);
if (InternalTextRenderer) {
- return React.createElement(InternalTextRenderer);
+ return React.createElement(InternalTextRenderer, props);
+ }
+ // If ghost line prevention is enabled and the text data is empty, render
+ // nothing to avoid React Native painting a 20px height line.
+ // See also https://git.io/JErwX
+ if (
+ props.tnode.data === '' &&
+ props.sharedProps.enableExperimentalGhostLinesPrevention
+ ) {
+ return null;
}
return React.createElement(TStandardTextRenderer, props);
}
diff --git a/packages/render-html/src/context/defaultSharedProps.ts b/packages/render-html/src/context/defaultSharedProps.ts
index f9a30118c..ef8f2deb0 100644
--- a/packages/render-html/src/context/defaultSharedProps.ts
+++ b/packages/render-html/src/context/defaultSharedProps.ts
@@ -20,6 +20,7 @@ const defaultSharedProps: Required = {
allowFontScaling: true
},
defaultViewProps: {},
+ enableExperimentalGhostLinesPrevention: false,
enableExperimentalMarginCollapsing: false,
computeEmbeddedMaxWidth: (contentWidth) => contentWidth,
provideEmbeddedHeaders: () => null,
diff --git a/packages/render-html/src/render/render-types.tsx b/packages/render-html/src/render/render-types.tsx
index 8ef29f085..294f0532b 100644
--- a/packages/render-html/src/render/render-types.tsx
+++ b/packages/render-html/src/render/render-types.tsx
@@ -1,13 +1,14 @@
import { TBlock, TPhrasing, TText } from '@native-html/transient-render-engine';
import { ComponentType } from 'react';
+import { TNodeSubRendererProps } from '../internal-types';
import { CustomRenderer, InternalRenderer } from '../shared-types';
/**
* Special internal renderers for non-printable text (wbr, br).
*/
-export type InternalTextContentRenderer = ComponentType<{
- key?: string | number;
-}> & {
+export type InternalTextContentRenderer = ComponentType<
+ TNodeSubRendererProps
+> & {
isNativeInternalTextRenderer: true;
};
diff --git a/packages/render-html/src/shared-types.ts b/packages/render-html/src/shared-types.ts
index ecf278ef6..107db63fc 100644
--- a/packages/render-html/src/shared-types.ts
+++ b/packages/render-html/src/shared-types.ts
@@ -363,6 +363,26 @@ export interface RenderHTMLSharedProps {
*/
defaultWebViewProps?: any;
+ /**
+ * React Native doesn't handle lines like we would expect on a web browser.
+ * For example:
+ * ```jsx
+ *
+ *
+ *
+ * ```
+ * will span 20 dpi in height. Setting this prop to `true` will make
+ * the renderer take those React Native oddities into account.
+ * See also this ticket: https://git.io/JErwX
+ *
+ * @remarks It might not work when `bypassAnonymousTPhrasingNodes` is set to
+ * `false`. Also note that this is an experimental feature, thus subject to
+ * behavioral instability.
+ *
+ * @defaultValue false
+ */
+ enableExperimentalGhostLinesPrevention?: boolean;
+
/**
* Enable or disable margin collapsing CSS behavior (experimental!).
* See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing | MDN docs}.
@@ -374,6 +394,8 @@ export interface RenderHTMLSharedProps {
* flex), which is not standard.
* - Might not work well with {@link TPhrasing} nodes having only one child.
*
+ * This is an experimental feature, thus subject to behavioral instability.
+ *
* @defaultValue false
*/
enableExperimentalMarginCollapsing?: boolean;