|
| 1 | +import { TNode } from '@native-html/transient-render-engine'; |
1 | 2 | import React from 'react'; |
2 | | -import { Text } from 'react-native'; |
| 3 | +import { Platform, Text, View } from 'react-native'; |
3 | 4 | import { InternalTextContentRenderer } from '../render/render-types'; |
4 | 5 |
|
5 | 6 | const emptyProps = { |
6 | 7 | testID: 'br' |
7 | 8 | }; |
8 | 9 |
|
| 10 | +const isWeb = Platform.OS === 'web'; |
| 11 | + |
| 12 | +function renderEmptyLineBreak(tnode: TNode) { |
| 13 | + const lineHeight = |
| 14 | + tnode.styles.nativeTextFlow.lineHeight || |
| 15 | + tnode.styles.nativeTextFlow.fontSize! * 1.4; |
| 16 | + return <View style={{ height: lineHeight }} />; |
| 17 | +} |
| 18 | + |
9 | 19 | const BRRenderer: InternalTextContentRenderer = function BRRenderer({ |
10 | 20 | renderIndex, |
11 | 21 | renderLength, |
12 | | - sharedProps |
| 22 | + sharedProps, |
| 23 | + tnode |
13 | 24 | }) { |
14 | | - // If it is the last child and BR collapsing is enabled, render nothing to |
15 | | - // prevent inserting an undesired space and follow HTML specs. |
| 25 | + // If it is the last child and BR collapsing is enabled, render an empty |
| 26 | + // string to prevent inserting an undesired space to follow HTML specs, |
| 27 | + // unless the platform is web and it is also the first child. |
| 28 | + // |
| 29 | + // Note that we are taking advantage of the Ghost Line oddity in React |
| 30 | + // Native, where an empty <Text /> element displays a line, since a |
| 31 | + // line break opening **and** closing an inline formatting context |
| 32 | + // should be printed as a one line-height item. |
| 33 | + const isFirst = renderIndex === 0; |
| 34 | + const isLast = renderIndex === renderLength - 1; |
| 35 | + const isLonelyBreak = isFirst && isLast; |
16 | 36 | const shouldCollapse = |
17 | 37 | sharedProps.enableExperimentalBRCollapsing && |
18 | | - renderIndex === renderLength - 1; |
19 | | - return React.createElement(Text, emptyProps, shouldCollapse ? '' : '\n'); |
| 38 | + (isFirst ? isLast && !isWeb : isLast); |
| 39 | + return isLonelyBreak && shouldCollapse |
| 40 | + ? renderEmptyLineBreak(tnode) |
| 41 | + : React.createElement(Text, emptyProps, shouldCollapse ? '' : '\n'); |
20 | 42 | }; |
21 | 43 |
|
22 | 44 | BRRenderer.isNativeInternalTextRenderer = true; |
|
0 commit comments