You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-**Condition**: Flag ONLY when ALL of these are true:
833
+
834
+
- A **new feature** is being introduced OR an **existing component's API is being expanded with new props**
835
+
- The change adds configuration properties (flags, conditional logic)
836
+
- These configuration options control feature presence or behavior within the component
837
+
- These features could instead be expressed as composable child components
838
+
839
+
**Features that should be expressed as child components:**
840
+
- Optional UI elements that could be composed in
841
+
- New behavior that could be introduced as new children
842
+
- Features that currently require parent component code changes
843
+
844
+
**DO NOT flag if:**
845
+
- Props are narrow, stable values needed for coordination between composed parts (e.g., `reportID`, `data`, `columns`)
846
+
- The component uses composition and child components for features
847
+
- Parent components stay stable as features are added
848
+
849
+
-**Reasoning**: When new features are implemented by adding configuration (props, flags, conditional logic) to existing components, if requirements change, then those components must be repeatedly modified, increasing coupling, surface area, and regression risk. Composition ensures features scale horizontally, limits the scope of changes, and prevents components from becoming configuration-driven "mega components".
850
+
851
+
Good (composition):
852
+
853
+
- Features expressed as composable children
854
+
- Parent stays stable; add features by adding children
855
+
856
+
```tsx
857
+
<Tabledata={items}columns={columns}>
858
+
<Table.SearchBar />
859
+
<Table.Header />
860
+
<Table.Body />
861
+
</Table>
862
+
```
863
+
864
+
```tsx
865
+
<SelectionListdata={items}>
866
+
<SelectionList.TextInput />
867
+
<SelectionList.Body />
868
+
</SelectionList>
869
+
```
870
+
871
+
Bad (configuration):
872
+
873
+
- Features controlled by boolean flags
874
+
- Adding a new feature requires modifying the Table component's API
875
+
876
+
```tsx
877
+
<Table
878
+
data={items}
879
+
columns={columns}
880
+
shouldShowSearchBar
881
+
shouldShowHeader
882
+
shouldEnableSorting
883
+
shouldShowPagination
884
+
shouldHighlightOnHover
885
+
/>
886
+
887
+
typeTableProps= {
888
+
data:Item[];
889
+
columns:Column[];
890
+
shouldShowSearchBar?:boolean; // ❌ Could be <Table.SearchBar />
891
+
shouldShowHeader?:boolean; // ❌ Could be <Table.Header />
892
+
shouldEnableSorting?:boolean; // ❌ Configuration for header behavior
893
+
shouldShowPagination?:boolean; // ❌ Could be <Table.Pagination />
894
+
shouldHighlightOnHover?:boolean; // ❌ Configuration for styling behavior
895
+
};
896
+
```
897
+
898
+
```tsx
899
+
<SelectionList
900
+
data={items}
901
+
shouldShowTextInput
902
+
shouldShowTooltips
903
+
shouldScrollToFocusedIndex
904
+
shouldDebounceScrolling
905
+
shouldUpdateFocusedIndex
906
+
canSelectMultiple
907
+
disableKeyboardShortcuts
908
+
/>
909
+
910
+
typeSelectionListProps= {
911
+
shouldShowTextInput?:boolean; // ❌ Could be <SelectionList.TextInput />
912
+
shouldShowConfirmButton?:boolean; // ❌ Could be <SelectionList.ConfirmButton />
913
+
textInputOptions?: {...}; // ❌ Configuration object for the above
914
+
};
915
+
```
916
+
917
+
Good (children manage their own state):
918
+
919
+
```tsx
920
+
// Children are self-contained and manage their own state
921
+
// Parent only passes minimal data (IDs)
922
+
// Adding new features doesn't require changing the parent
923
+
function ReportScreen({ params: { reportID }}) {
924
+
return (
925
+
<>
926
+
<ReportActionsViewreportID={reportID} />
927
+
// other features
928
+
<Composer />
929
+
</>
930
+
);
931
+
}
932
+
933
+
// Component accesses stores and calculates its own state
about: A template to follow when creating a new issue in this repository that was found during Exploratory testing by QA
4
+
labels: Monthly, Not a priority
5
+
---
6
+
7
+
If you haven’t already, check out our [contributing guidelines](https://github.com/Expensify/ReactNativeChat/blob/main/contributingGuides/CONTRIBUTING.md) for onboarding and email contributors@expensify.com to request to join our Slack channel!
8
+
___
9
+
**For all Exploratory issues, start the title of the issue with `[Exploratory]`** (and, do **not** add the `External` label.
10
+
11
+
**Version Number:**
12
+
**Reproducible in staging?:**
13
+
**Reproducible in production?:**
14
+
**If this was caught during regression testing, add the test name, ID and link from BrowserStack:**
15
+
**Email or phone of affected tester (no customers):**
Copy file name to clipboardExpand all lines: contributingGuides/CONTRIBUTING.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -132,9 +132,9 @@ Additionally, if you want to discuss an idea with the open source community with
132
132
* You'll need a Mac to test the iOS and MacOS app.
133
133
* In case you don't have one, here's a helpful [document](https://github.com/Expensify/App/blob/main/contributingGuides/TESTING_MACOS_AND_IOS.md) on how you might test all platforms on a Windows/Linux device.
134
134
135
-
### Check GitHub for existing proposals from other users
135
+
### Check GitHub for existing proposals
136
136
137
-
1. Expensify reviews all solution proposals on a first come first serve basis. If you see other contributors have already proposed a solution, you can still provide a solution proposal and we will review it. We look for the earliest provided, best proposed solution that addresses the job.
137
+
1. Expensify reviews all solution proposals on a first come first serve basis. If you see proposals are already posted on an issue, you can still provide a solution proposal and we will review it. We look for the earliest provided, best proposed solution that addresses the job.
138
138
139
139
### Make sure you can reproduce the problem
140
140
2. Use your test account(s) to reproduce the problem by following the steps in the GitHub issue.
0 commit comments