Skip to content

Commit f7933e9

Browse files
committed
feat: useHtmlNormalizer and selectable props
1 parent b9310d7 commit f7933e9

5 files changed

Lines changed: 57 additions & 19 deletions

File tree

apps/example-web/src/App.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,7 @@ function App() {
337337
<EnrichedText
338338
style={enrichedTextStyle}
339339
htmlStyle={WEB_DEFAULT_HTML_STYLE}
340+
useHtmlNormalizer
340341
>
341342
{enrichedTextValue}
342343
</EnrichedText>

docs/TEXT_API_REFERENCE.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ A prop for customizing styles of HTML elements, including press colors for inter
4040

4141
If `true`, external HTML (e.g. from Google Docs, Word, web pages) will be normalized before rendering. This converts arbitrary HTML into the canonical tag subset that the enriched parser understands.
4242

43-
| Type | Default Value | Platform |
44-
| ------ | ------------- | ------------ |
45-
| `bool` | `false` | iOS, Android |
43+
| Type | Default Value | Platform |
44+
| ------ | ------------- | ----------------- |
45+
| `bool` | `false` | iOS, Android, Web |
4646

4747
### `ellipsizeMode`
4848

@@ -72,9 +72,9 @@ Limits the number of displayed lines. Set to `0` for unlimited lines.
7272

7373
If `true`, the text can be selected by the user (e.g. for copy/paste).
7474

75-
| Type | Default Value | Platform |
76-
| ------ | ------------- | ------------ |
77-
| `bool` | `false` | iOS, Android |
75+
| Type | Default Value | Platform |
76+
| ------ | ------------- | ----------------- |
77+
| `bool` | `false` | iOS, Android, Web |
7878

7979
### `selectionColor`
8080

src/web/EnrichedText.tsx

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
mergeWithDefaultEnrichedTextHtmlStyle,
88
} from './styleConversion/htmlStyleToCSSVariables';
99
import { ENRICHED_TEXT_CLASSNAME } from './constants/classNames';
10-
import { enrichedInputThemingToCSSProperties } from './styleConversion/enrichedThemingToCSSProperties';
10+
import { enrichedTextThemingToCSSProperties } from './styleConversion/enrichedThemingToCSSProperties';
1111
import { buildMentionRulesCSS } from './styleConversion/buildMentionRulesCSS';
1212
import { sanitizeHtml } from './sanitization/htmlSanitizer';
1313
import { prepareHtmlForWeb } from './normalization/prepareHtmlForWeb';
@@ -16,14 +16,21 @@ import { useImageErrorFallback } from './useImageErrorFallback';
1616
import { usePressInteractions } from './usePressInteractions';
1717

1818
export const EnrichedText = memo(
19-
({ children, htmlStyle, style, selectionColor }: EnrichedTextProps) => {
19+
({
20+
children,
21+
htmlStyle,
22+
style,
23+
selectionColor,
24+
selectable = false,
25+
useHtmlNormalizer = false,
26+
}: EnrichedTextProps) => {
2027
const containerRef = useRef<HTMLDivElement>(null);
2128

2229
const sanitizedHtml = useMemo(() => sanitizeHtml(children), [children]);
2330

2431
const finalHtml = useMemo(
25-
() => prepareHtmlForWeb(sanitizedHtml),
26-
[sanitizedHtml]
32+
() => prepareHtmlForWeb(sanitizedHtml, useHtmlNormalizer),
33+
[sanitizedHtml, useHtmlNormalizer]
2734
);
2835

2936
const resolvedHtmlStyle = useMemo(
@@ -45,8 +52,8 @@ export const EnrichedText = memo(
4552
);
4653

4754
const themingStyle = useMemo(
48-
() => enrichedInputThemingToCSSProperties({ selectionColor }),
49-
[selectionColor]
55+
() => enrichedTextThemingToCSSProperties({ selectionColor, selectable }),
56+
[selectionColor, selectable]
5057
);
5158

5259
const mentionRulesCSS = useMemo(

src/web/normalization/prepareHtmlForWeb.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1-
export function prepareHtmlForWeb(html: string) {
1+
import { normalizeHtml } from './htmlNormalizer';
2+
3+
export function prepareHtmlForWeb(
4+
html: string,
5+
useHtmlNormalizer: boolean | undefined
6+
) {
7+
if (useHtmlNormalizer) {
8+
html = normalizeHtml(html);
9+
}
210
return checkboxHtmlToWeb(html);
311
}
412

src/web/styleConversion/enrichedThemingToCSSProperties.ts

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,22 @@ import type { CSSProperties } from 'react';
22
import type { ColorValue } from 'react-native';
33
import { toColor } from './toColor';
44

5-
type EnrichedInputThemingStyle = Partial<
6-
Pick<CSSProperties, 'caretColor'> & {
5+
type EnrichedThemingStyle = Partial<
6+
Pick<CSSProperties, 'caretColor' | 'userSelect'> & {
77
'--et-placeholder-text-color': string;
88
'--et-selection-color': string;
99
}
1010
>;
1111

12+
function applySelectionColor(
13+
extra: EnrichedThemingStyle,
14+
selectionColor: ColorValue | undefined
15+
): EnrichedThemingStyle {
16+
const selectionCss = toColor(selectionColor);
17+
if (selectionCss) extra['--et-selection-color'] = selectionCss;
18+
return extra;
19+
}
20+
1221
export interface EnrichedInputThemingColors {
1322
cursorColor?: ColorValue;
1423
placeholderTextColor?: ColorValue;
@@ -20,15 +29,28 @@ export function enrichedInputThemingToCSSProperties({
2029
placeholderTextColor,
2130
selectionColor,
2231
}: EnrichedInputThemingColors): CSSProperties {
23-
const extra: EnrichedInputThemingStyle = {};
32+
const extra: EnrichedThemingStyle = {};
2433
const caret = toColor(cursorColor);
2534
if (caret) extra.caretColor = caret;
2635

2736
const placeholderCss = toColor(placeholderTextColor);
2837
if (placeholderCss) extra['--et-placeholder-text-color'] = placeholderCss;
2938

30-
const selectionCss = toColor(selectionColor);
31-
if (selectionCss) extra['--et-selection-color'] = selectionCss;
39+
return applySelectionColor(extra, selectionColor);
40+
}
3241

33-
return extra;
42+
export interface EnrichedTextThemingOptions {
43+
selectionColor?: ColorValue;
44+
selectable?: boolean;
45+
}
46+
47+
export function enrichedTextThemingToCSSProperties({
48+
selectionColor,
49+
selectable,
50+
}: EnrichedTextThemingOptions): CSSProperties {
51+
const extra: EnrichedThemingStyle = {};
52+
53+
if (selectable !== undefined) extra.userSelect = selectable ? 'text' : 'none';
54+
55+
return applySelectionColor(extra, selectionColor);
3456
}

0 commit comments

Comments
 (0)