@symbiote-native/react 3.0.3 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -436,21 +436,13 @@ export function VirtualizedList(props) {
|
|
|
436
436
|
index: planCell.index,
|
|
437
437
|
separators: makeSeparators(planCell.index),
|
|
438
438
|
});
|
|
439
|
-
//
|
|
440
|
-
//
|
|
441
|
-
//
|
|
442
|
-
// gap + separator + gap while a spacer collapsing that region replaces it with one gap — the
|
|
443
|
-
// leading spacer then lands every cell below it short by (separator + gap), and the content
|
|
444
|
-
// visibly jumps by that amount each time the window's first index moves. Measured at exactly
|
|
445
|
-
// 17px on device 2026-08-19 (a 1px divider under a 16px container gap); see
|
|
446
|
-
// .claude/rules/list-geometry-feedback-loop.md. Inside the wrapper it is part of the cell's
|
|
447
|
-
// measured length instead, and every cell stays exactly one child.
|
|
439
|
+
// The separator lives INSIDE the cell's own measuring wrapper, not as a sibling: a sibling
|
|
440
|
+
// is an extra flex child, so a leading-spacer collapse would land every cell below it short
|
|
441
|
+
// by (separator + gap). See .claude/rules/list-geometry-feedback-loop.md.
|
|
448
442
|
const separator =
|
|
449
|
-
//
|
|
450
|
-
//
|
|
451
|
-
//
|
|
452
|
-
// would make a cell's own measured height change as the window slides past it. Device-measured
|
|
453
|
-
// 2026-08-19 as a run of cells all shifting by exactly the divider's 1px.
|
|
443
|
+
// Gated on the last index of the DATA, not the WINDOW: since the separator lives inside
|
|
444
|
+
// the measuring wrapper, gating on the window would make a cell's own measured height
|
|
445
|
+
// change as the window slides past it.
|
|
454
446
|
planCell.index < count - 1
|
|
455
447
|
? renderSeparatorElement(ItemSeparatorComponent, item, getItem(data, planCell.index + 1), separatorOverridesRef.current.get(planCell.index))
|
|
456
448
|
: undefined;
|
package/build/host-config.js
CHANGED
|
@@ -91,6 +91,8 @@ const reconciler = createReconciler({
|
|
|
91
91
|
noTimeout: -1,
|
|
92
92
|
scheduleTimeout: setTimeout,
|
|
93
93
|
cancelTimeout: clearTimeout,
|
|
94
|
+
supportsMicrotasks: true,
|
|
95
|
+
scheduleMicrotask: queueMicrotask,
|
|
94
96
|
getRootHostContext: () => ({ isInsideText: false }),
|
|
95
97
|
getChildHostContext(parentHostContext, type) {
|
|
96
98
|
const isInsideText = descriptorFor(type).isText;
|
package/build/render.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// the reconciler drive shared, which commits into nativeFabricUIManager.
|
|
4
4
|
import { createSurface, disposeRoot, setEventDispatcher, dlog, reportUncaughtError, } from '@symbiote-native/engine';
|
|
5
5
|
import reconciler, { flushExternalUpdate } from './host-config.js';
|
|
6
|
-
import {
|
|
6
|
+
import { ConcurrentRoot } from './reconciler-constants.js';
|
|
7
7
|
const noop = () => { };
|
|
8
8
|
function errorReporter(origin) {
|
|
9
9
|
return (error, info) => {
|
|
@@ -63,15 +63,13 @@ export function mount(rootTag, element) {
|
|
|
63
63
|
// first) starts clean. Otherwise the stale container double-drives the surface.
|
|
64
64
|
teardown(rootTag);
|
|
65
65
|
const surface = createSurface(rootTag);
|
|
66
|
-
const container = reconciler.createContainer(surface,
|
|
66
|
+
const container = reconciler.createContainer(surface, ConcurrentRoot, null, false, null, 'symbiote', onUncaughtError, onCaughtError, onRecoverableError,
|
|
67
67
|
// onDefaultTransitionIndicator - the ONE that is genuinely a no-op. RN's own renderer says
|
|
68
68
|
// so in as many words: "Native doesn't have a default indicator" (ReactFabric.js's
|
|
69
69
|
// nativeOnDefaultTransitionIndicator).
|
|
70
70
|
noop, null);
|
|
71
71
|
containers.set(rootTag, container);
|
|
72
|
-
// react-reconciler 0.33
|
|
73
|
-
// immediate render/commit; @types 0.32 still lists the older updateContainer /
|
|
74
|
-
// flushSync names, so these calls are type-suppressed until the types catch up.
|
|
72
|
+
// react-reconciler 0.33 renamed updateContainer/flushSync; @types 0.32 still has the old names.
|
|
75
73
|
// @ts-expect-error updateContainerSync exists at runtime in react-reconciler 0.33
|
|
76
74
|
reconciler.updateContainerSync(element, container, null, noop);
|
|
77
75
|
// @ts-expect-error flushSyncWork exists at runtime in react-reconciler 0.33
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@symbiote-native/react",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "SymbioteNative's React adapter — a react-reconciler host config (mutation mode) driving real native iOS/Android views through stock React Native Fabric.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -57,20 +57,21 @@
|
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
59
|
"react-reconciler": "^0.33.0",
|
|
60
|
-
"@symbiote-native/components": "3.1.
|
|
61
|
-
"@symbiote-native/css-parser": "0.5.
|
|
60
|
+
"@symbiote-native/components": "3.1.3",
|
|
61
|
+
"@symbiote-native/css-parser": "0.5.2"
|
|
62
62
|
},
|
|
63
63
|
"peerDependencies": {
|
|
64
64
|
"react": ">=19.0.0",
|
|
65
65
|
"react-native": ">=0.86",
|
|
66
|
-
"@symbiote-native/engine": "^1.
|
|
66
|
+
"@symbiote-native/engine": "^1.4.0"
|
|
67
67
|
},
|
|
68
68
|
"devDependencies": {
|
|
69
|
+
"@types/node": "^26.0.0",
|
|
69
70
|
"@types/react": "^19.2.0",
|
|
70
71
|
"@types/react-reconciler": "^0.32.2",
|
|
71
72
|
"react": "19.2.3",
|
|
72
|
-
"@symbiote-native/engine": "1.
|
|
73
|
-
"@symbiote-native/test-utils": "0.4.
|
|
73
|
+
"@symbiote-native/engine": "1.4.0",
|
|
74
|
+
"@symbiote-native/test-utils": "0.4.5"
|
|
74
75
|
},
|
|
75
76
|
"scripts": {
|
|
76
77
|
"typecheck": "tsc --build",
|