Skip to content

Commit 01e4d1f

Browse files
committed
Merge branch 'main' into mkzie2-issue/77663
2 parents 0d87cc2 + db10c65 commit 01e4d1f

398 files changed

Lines changed: 32049 additions & 25741 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/agents/code-inline-reviewer.md

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -975,6 +975,110 @@ function ReportScreen({ params: { reportID }}) {
975975

976976
---
977977

978+
### [CLEAN-REACT-PATTERNS-2] Let components own their behavior and effects
979+
980+
- **Search patterns**: Large prop counts in JSX, props named `*Report`, `*Policy`, `*Transaction`, `*Actions`, `useOnyx`/context results passed directly as props
981+
982+
- **Condition**: Flag when a parent component acts as a pure data intermediary — fetching or computing state only to pass it to children without using it for its own logic.
983+
984+
**Signs of violation:**
985+
- Parent imports hooks/contexts only to satisfy child's data needs
986+
- Props that are direct pass-throughs of hook results (e.g., `report={reportOnyx}`)
987+
- Component receives props that are just passed through to children or that it could fetch itself
988+
- Removing or commenting out the child would leave unused variables in the parent
989+
990+
**DO NOT flag if:**
991+
- Props are minimal, domain-relevant identifiers (e.g., `reportID`, `transactionID`, `policyID`)
992+
- Props are callback/event handlers for coordination (e.g., `onSelectRow`, `onLayout`, `onPress`)
993+
- Props are structural/presentational that can't be derived internally (e.g., `style`, `testID`)
994+
- Parent genuinely uses the data for its own rendering or logic
995+
- Data is shared coordination state that parent legitimately owns (e.g., selection state managed by parent)
996+
997+
- **Reasoning**: When parent components compute and pass behavioral state to children, if a child's requirements change, then parent components must change as well, increasing coupling and causing behavior to leak across concerns. Letting components own their behavior keeps logic local, allows independent evolution, and follows the principle: "If removing a child breaks parent behavior, coupling exists."
998+
999+
Good (component owns its behavior):
1000+
1001+
- Component receives only IDs and handlers
1002+
- Internally accesses stores, contexts, and computes values
1003+
- Children follow the same pattern
1004+
1005+
```tsx
1006+
<OptionRowLHNData
1007+
reportID={reportID}
1008+
onSelectRow={onSelectRow}
1009+
/>
1010+
```
1011+
1012+
```tsx
1013+
function OptionRowLHNData({reportID, onSelectRow}) {
1014+
// Component fetches its own data
1015+
const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`);
1016+
const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID}`);
1017+
const [viewMode] = useOnyx(ONYXKEYS.NVP_VIEW_MODE);
1018+
// ... other data this component needs
1019+
1020+
return (
1021+
<View>
1022+
{/* Children own their state too */}
1023+
<Avatars reportID={reportID} />
1024+
<DisplayNames reportID={reportID} />
1025+
<Status reportID={reportID} />
1026+
</View>
1027+
);
1028+
}
1029+
```
1030+
1031+
Bad (parent micromanages child's state):
1032+
1033+
- Parent gathers, computes, and dictates the child's entire contextual awareness
1034+
- Parent imports hooks/stores only because the child needs the information
1035+
- Double coupling: parent → child's dependencies, child → prop names/types
1036+
1037+
```tsx
1038+
<OptionRowLHNData
1039+
reportID={reportID}
1040+
fullReport={item}
1041+
reportAttributes={itemReportAttributes}
1042+
oneTransactionThreadReport={itemOneTransactionThreadReport}
1043+
reportNameValuePairs={itemReportNameValuePairs}
1044+
reportActions={itemReportActions}
1045+
parentReportAction={itemParentReportAction}
1046+
iouReportReportActions={itemIouReportReportActions}
1047+
policy={itemPolicy}
1048+
invoiceReceiverPolicy={itemInvoiceReceiverPolicy}
1049+
personalDetails={personalDetails ?? {}}
1050+
transaction={itemTransaction}
1051+
lastReportActionTransaction={lastReportActionTransaction}
1052+
receiptTransactions={transactions}
1053+
viewMode={optionMode}
1054+
isOptionFocused={!shouldDisableFocusOptions}
1055+
lastMessageTextFromReport={lastMessageTextFromReport}
1056+
onSelectRow={onSelectRow}
1057+
preferredLocale={preferredLocale}
1058+
hasDraftComment={hasDraftComment}
1059+
transactionViolations={transactionViolations}
1060+
onLayout={onLayoutItem}
1061+
shouldShowRBRorGBRTooltip={shouldShowRBRorGBRTooltip}
1062+
activePolicyID={activePolicyID}
1063+
onboardingPurpose={introSelected?.choice}
1064+
isFullscreenVisible={isFullscreenVisible}
1065+
isReportsSplitNavigatorLast={isReportsSplitNavigatorLast}
1066+
isScreenFocused={isScreenFocused}
1067+
localeCompare={localeCompare}
1068+
testID={index}
1069+
isReportArchived={isReportArchived}
1070+
lastAction={lastAction}
1071+
lastActionReport={lastActionReport}
1072+
/>
1073+
```
1074+
1075+
In this example:
1076+
- The parent fetches `fullReport`, `policy`, `transaction`, `reportActions`, `personalDetails`, `transactionViolations`, and routing/layout state
1077+
- These dependencies exist only because the child needs them — the parent is a data intermediary
1078+
- If `OptionRowLHNData` requirements change, the parent must change too
1079+
1080+
---
1081+
9781082
## Instructions
9791083

9801084
1. **First, get the list of changed files and their diffs:**

.claude/settings.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
{
2+
"extraKnownMarketplaces": {
3+
"callstack-agent-skills": {
4+
"source": {
5+
"source": "github",
6+
"repo": "callstackincubator/agent-skills"
7+
}
8+
}
9+
},
210
"permissions": {
311
"allow": [
412
"mcp__playwright__browser_navigate",

.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ CAPTURE_METRICS=false
1515
ONYX_METRICS=false
1616
USE_THIRD_PARTY_SCRIPTS=false
1717
IS_EXPENSIFY_EMPLOYEE=false
18+
ENABLE_SENTRY_ON_DEV=false
1819

1920
EXPENSIFY_ACCOUNT_ID_ACCOUNTING=-1
2021
EXPENSIFY_ACCOUNT_ID_ACCOUNTS_PAYABLE=-1

0 commit comments

Comments
 (0)