Skip to content

Commit 135adde

Browse files
authored
Merge branch 'main' into @ksienkiewicz/fix-android-initial-measuring
2 parents ced2b76 + 49da66a commit 135adde

35 files changed

Lines changed: 1372 additions & 1246 deletions
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { test, expect } from '@playwright/test';
2+
3+
const ROOT_SELECTOR = '[data-testid="test-render-cycle-root"]';
4+
const EDITOR_SELECTOR = `${ROOT_SELECTOR} .eti-editor [contenteditable="true"]`;
5+
const TOGGLE_BUTTON_SELECTOR = '[data-testid="toggle-variant-button"]';
6+
const VARIANT_OUTPUT_SELECTOR = '[data-testid="variant-output"]';
7+
const PAGE_PATH = '/test-render-cycle';
8+
9+
test.describe('EnrichedTextInput render cycle', () => {
10+
test('does not throw on simultaneous defaultValue and htmlStyle change', async ({
11+
page,
12+
}) => {
13+
const pageErrors: Error[] = [];
14+
const consoleErrors: string[] = [];
15+
16+
page.on('pageerror', (error) => pageErrors.push(error));
17+
page.on('console', (message) => {
18+
if (message.type() === 'error') {
19+
consoleErrors.push(message.text());
20+
}
21+
});
22+
23+
await page.goto(PAGE_PATH);
24+
await page.waitForSelector(EDITOR_SELECTOR);
25+
26+
await expect(page.locator(EDITOR_SELECTOR)).toContainText('Variant A');
27+
28+
await page.click(TOGGLE_BUTTON_SELECTOR);
29+
await expect(page.locator(VARIANT_OUTPUT_SELECTOR)).toHaveText('b');
30+
await expect(page.locator(EDITOR_SELECTOR)).toContainText('Variant B');
31+
32+
await page.click(TOGGLE_BUTTON_SELECTOR);
33+
await expect(page.locator(VARIANT_OUTPUT_SELECTOR)).toHaveText('a');
34+
await expect(page.locator(EDITOR_SELECTOR)).toContainText('Variant A');
35+
36+
const editor = page.locator(EDITOR_SELECTOR);
37+
await editor.click();
38+
await expect(editor).toBeFocused();
39+
await editor.pressSequentially(' more text');
40+
await expect(editor).toContainText('Variant A more text');
41+
42+
expect(pageErrors).toEqual([]);
43+
expect(consoleErrors).toEqual([]);
44+
});
45+
});

android/gradle.properties

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
ReactNativeEnrichedHtml_kotlinVersion=2.0.21
1+
ReactNativeEnrichedHtml_kotlinVersion=2.2.0
22
ReactNativeEnrichedHtml_minSdkVersion=24
3-
ReactNativeEnrichedHtml_targetSdkVersion=34
4-
ReactNativeEnrichedHtml_compileSdkVersion=35
3+
ReactNativeEnrichedHtml_targetSdkVersion=36
4+
ReactNativeEnrichedHtml_compileSdkVersion=37
55
ReactNativeEnrichedHtml_ndkVersion=27.1.12297006

apps/example-web/src/RouteSelector.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { VisualRegression } from './testScreens/VisualRegression';
66
import { TestSubmitProps } from './testScreens/TestSubmitProps';
77
import { TestEnrichedText } from './testScreens/TestEnrichedText';
88
import { TestEllipsize } from './testScreens/TestEllipsize';
9+
import { TestRenderCycle } from './testScreens/TestRenderCycle';
910
import { useEffect, useState } from 'react';
1011

1112
export default function RouteSelector() {
@@ -50,5 +51,9 @@ export default function RouteSelector() {
5051
return <TestEllipsize />;
5152
}
5253

54+
if (path === '/test-render-cycle') {
55+
return <TestRenderCycle />;
56+
}
57+
5358
return <App />;
5459
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { useMemo, useRef, useState } from 'react';
2+
import {
3+
EnrichedTextInput,
4+
type EnrichedTextInputInstance,
5+
type HtmlStyle,
6+
} from 'react-native-enriched-html';
7+
import { WEB_DEFAULT_HTML_STYLE } from '../defaultHtmlStyle';
8+
9+
const VARIANTS = {
10+
a: {
11+
defaultValue: '<p>Variant A</p>',
12+
htmlStyle: WEB_DEFAULT_HTML_STYLE,
13+
},
14+
b: {
15+
defaultValue: '<h1>Variant B</h1>',
16+
htmlStyle: { ...WEB_DEFAULT_HTML_STYLE, h1: { fontSize: 48 } },
17+
},
18+
} as const satisfies Record<
19+
string,
20+
{ defaultValue: string; htmlStyle: HtmlStyle }
21+
>;
22+
23+
export function TestRenderCycle() {
24+
const ref = useRef<EnrichedTextInputInstance>(null);
25+
const [variant, setVariant] = useState<keyof typeof VARIANTS>('a');
26+
27+
const { defaultValue, htmlStyle } = useMemo(
28+
() => VARIANTS[variant],
29+
[variant]
30+
);
31+
32+
return (
33+
<div data-testid="test-render-cycle-root">
34+
<div
35+
className="editor-wrapper"
36+
style={editorContainerStyle}
37+
data-testid="editor-container"
38+
onClick={() => ref.current?.focus()}
39+
>
40+
<EnrichedTextInput
41+
ref={ref}
42+
defaultValue={defaultValue}
43+
htmlStyle={htmlStyle}
44+
placeholder="Test editor"
45+
autoFocus
46+
editable
47+
scrollEnabled
48+
/>
49+
</div>
50+
51+
<button
52+
type="button"
53+
data-testid="toggle-variant-button"
54+
onClick={() => {
55+
setVariant((prev) => (prev === 'a' ? 'b' : 'a'));
56+
}}
57+
>
58+
Toggle variant
59+
</button>
60+
61+
<pre data-testid="variant-output">{variant}</pre>
62+
</div>
63+
);
64+
}
65+
66+
const editorContainerStyle = {
67+
backgroundColor: '#ddd',
68+
padding: '16px',
69+
borderRadius: '8px',
70+
} as const;

apps/example-web/tsconfig.app.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
"compilerOptions": {
44
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
55
"types": ["vite/client"],
6-
"baseUrl": ".",
76
"paths": {
87
"react-native-enriched-html": ["../../src/index.tsx"]
98
}

apps/example/android/app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ android {
102102
// see https://reactnative.dev/docs/signed-apk-android.
103103
signingConfig signingConfigs.debug
104104
minifyEnabled enableProguardInReleaseBuilds
105-
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
105+
proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
106106
}
107107
}
108108
}

apps/example/android/build.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
buildscript {
22
ext {
3-
buildToolsVersion = "36.0.0"
3+
buildToolsVersion = "37.0.0"
44
minSdkVersion = 24
5-
compileSdkVersion = 36
5+
compileSdkVersion = 37
66
targetSdkVersion = 36
77
ndkVersion = "27.1.12297006"
8-
kotlinVersion = "2.1.20"
8+
kotlinVersion = "2.2.0"
99
}
1010
repositories {
1111
google()

apps/example/android/gradle.properties

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,9 @@ hermesEnabled=true
4141
# Use this property to enable edge-to-edge display support.
4242
# This allows your app to draw behind system bars for an immersive UI.
4343
# Note: Only works with ReactActivity and should not be used with custom Activity.
44-
edgeToEdgeEnabled=false
44+
edgeToEdgeEnabled=true
45+
46+
# Opt out of built-in kotlin and new DSL behavior that ships with AGP 9.
47+
# Starting from AGP 10.x these opt outs will be removed.
48+
android.builtInKotlin=false
49+
android.newDsl=false
2.73 KB
Binary file not shown.

apps/example/android/gradle/wrapper/gradle-wrapper.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-bin.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip
44
networkTimeout=10000
55
validateDistributionUrl=true
66
zipStoreBase=GRADLE_USER_HOME

0 commit comments

Comments
 (0)