ENG-9676 fix: route memo RestProp CSS props into css instead of dropping them#6605
ENG-9676 fix: route memo RestProp CSS props into css instead of dropping them#6605FarhanAliRaza wants to merge 3 commits into
Conversation
A `rx.RestProp` only forwarded kwargs that matched a declared field of the target component; any other forwarded prop (e.g. `font_weight`) was emitted as a raw plain prop the target silently ignored. Track each RestProp target's field names during body evaluation so the call site can fold non-field props into emotion `css`, matching how a normal component handles unknown kwargs.
Merging this PR will not alter performance
Comparing Footnotes
|
Greptile SummaryThis PR fixes a silent-drop bug in
Confidence Score: 5/5The change is well-scoped and correctly routes non-field rest props into emotion css, matching the existing component behaviour. The core logic in take_rest is straightforward: keys in rest_target_fields get camel-cased plain-prop treatment; everything else is gathered into a Style dict and wrapped in a single css LiteralVar. The set-accumulation in _lift_rest_props is mutated in-place before the call site reads it (forced by rest_target_field_names()), which is the correct evaluation order for both the eager and lazy paths. Tests cover both the new CSS-routing path and the real-target-field guard. No files require special attention. Important Files Changed
Reviews (2): Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." | Re-trigger Greptile |
| if css: | ||
| rest["css"] = LiteralVar.create( | ||
| convert_dict_to_style_and_format_emotion(css) | ||
| ) |
There was a problem hiding this comment.
convert_dict_to_style_and_format_emotion can return None
format_as_emotion returns None when its internal emotion_style dict ends up empty after processing (e.g. all entries are filtered or a Var-only style resolves to nothing). Passing None to LiteralVar.create would produce a css={null} prop in the JSX output, which silently drops all emotion styles at runtime. The if css: guard only checks the pre-conversion dict, not the output. A None check on the result would make this safe.
Adds the 6605 bugfix changelog entry documenting that `@rx.memo` forwards undeclared RestProp kwargs into `css`, and regenerates the memo.pyi hash.
|
Want your agent to iterate on Greptile's feedback? Try greploops. |
masenf
left a comment
There was a problem hiding this comment.
so one weird thing about this PR:
def test_memo_props_on_create_do_not_become_css():
"""Handle props passed via the RestProp that correspond to kwargs accepted by `create`.
In this case, the create kwargs are not _real_ props, but they are consumed
like real props and should NOT become CSS.
"""
class CustomText(Span):
@classmethod
def create(cls, *children, prefix: rx.Var[str] | str = "", **props) -> Component:
return super().create(prefix, *children, **props)
@rx.memo
def styled_text(rest: rx.RestProp) -> rx.Component:
return CustomText.create("Foo", rest)
rendered = str(styled_text(prefix="P: ", class_name="c"))
print(rendered)
assert "css:" not in rendered
assert '["prefix"] : "P: "' not in rendered
assert 'prefix:"P:"' in rendered
# A genuine base `Component` field stays a normal plain prop.
assert 'className:"c"' in renderedI don't think there's actually a way to handle this because rest is not resolvable at compile time and create kwargs are only resolvable at compile time...
Otherwise I generally like the fix here. I wonder if we should audit the component code base in an attempt to remove these kind of "shadow" props that get resolved at compile time?
At the very least, we need to add a line to the documentation for RestProp that there is a limitation that create kwargs cannot be passed via RestProp; only actual component props and css props would be passed through.
A
rx.RestProponly forwarded kwargs that matched a declared field of the target component; any other forwarded prop (e.g.font_weight) was emitted as a raw plain prop the target silently ignored. Track each RestProp target's field names during body evaluation so the call site can fold non-field props into emotioncss, matching how a normal component handles unknown kwargs.All Submissions:
Type of change
Please delete options that are not relevant.
New Feature Submission:
Changes To Core Features:
fixes @rx.memo with rx.RestProp doesn't handle CSS props correctly #6599