Surfaced by an extended parity fuzz discovery run.
When the flattened style declares a userSelect value, RN's wrapper unconditionally replaces the direct selectable prop with the map lookup (Text.js: if (processedStyle.userSelect != null) { _selectable = userSelectToSelectableMap[processedStyle.userSelect]; }). For an invalid value like 'xyz' the lookup is undefined, so selectable is dropped and never reaches the host. Boost only overrides selectable when the lookup succeeds, so the direct prop survives.
This is the degenerate cousin of #29: userSelect must win over selectable even when its value is invalid.
Repro
const isSelectable = true;
<Text style={{ userSelect: 'xyz' }} selectable={isSelectable}>hello</Text>
- Expected:
selectable is omitted (the invalid userSelect clobbers it, matching RN)
- Actual: native host receives
selectable: true
Surfaced by an extended parity fuzz discovery run.
When the flattened style declares a
userSelectvalue, RN's wrapper unconditionally replaces the directselectableprop with the map lookup (Text.js:if (processedStyle.userSelect != null) { _selectable = userSelectToSelectableMap[processedStyle.userSelect]; }). For an invalid value like'xyz'the lookup isundefined, soselectableis dropped and never reaches the host. Boost only overridesselectablewhen the lookup succeeds, so the direct prop survives.This is the degenerate cousin of #29:
userSelectmust win overselectableeven when its value is invalid.Repro
selectableis omitted (the invaliduserSelectclobbers it, matching RN)selectable: true