-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Make getKey and selection props mutually exclusive #24048
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make getKey and selection props mutually exclusive #24048
Conversation
📊 Bundle size report🤖 This report was generated against a4e6775a446d201c641c9d10c455efd7b6e66cba |
Perf Analysis (
|
| Scenario | Render type | Master Ticks | PR Ticks | Iterations | Status |
|---|---|---|---|---|---|
| BaseButton | mount | 802 | 805 | 5000 | |
| Breadcrumb | mount | 2222 | 2246 | 1000 | |
| Checkbox | mount | 2132 | 2140 | 5000 | |
| CheckboxBase | mount | 1865 | 1895 | 5000 | |
| ChoiceGroup | mount | 3733 | 3745 | 5000 | |
| ComboBox | mount | 911 | 896 | 1000 | |
| CommandBar | mount | 8258 | 8225 | 1000 | |
| ContextualMenu | mount | 15753 | 16572 | 1000 | |
| DefaultButton | mount | 981 | 987 | 5000 | |
| DetailsRow | mount | 2901 | 2906 | 5000 | |
| DetailsRowFast | mount | 2906 | 2905 | 5000 | |
| DetailsRowNoStyles | mount | 2643 | 2617 | 5000 | |
| Dialog | mount | 3464 | 3471 | 1000 | |
| DocumentCardTitle | mount | 315 | 322 | 1000 | |
| Dropdown | mount | 2545 | 2561 | 5000 | |
| FocusTrapZone | mount | 1507 | 1513 | 5000 | |
| FocusZone | mount | 1475 | 1454 | 5000 | |
| GroupedList | mount | 51034 | 59206 | 2 | |
| GroupedList | virtual-rerender | 22068 | 24523 | 2 | |
| GroupedList | virtual-rerender-with-unmount | 75685 | 74878 | 2 | |
| GroupedListV2 | mount | 303 | 312 | 2 | |
| GroupedListV2 | virtual-rerender | 291 | 290 | 2 | |
| GroupedListV2 | virtual-rerender-with-unmount | 314 | 317 | 2 | |
| IconButton | mount | 1403 | 1423 | 5000 | |
| Label | mount | 460 | 460 | 5000 | |
| Layer | mount | 3585 | 3587 | 5000 | |
| Link | mount | 531 | 530 | 5000 | |
| MenuButton | mount | 1233 | 1232 | 5000 | |
| MessageBar | mount | 27509 | 27526 | 5000 | |
| Nav | mount | 2547 | 2532 | 1000 | |
| OverflowSet | mount | 1008 | 1016 | 5000 | |
| Panel | mount | 2240 | 2251 | 1000 | |
| Persona | mount | 980 | 980 | 1000 | |
| Pivot | mount | 1165 | 1192 | 1000 | |
| PrimaryButton | mount | 1093 | 1098 | 5000 | |
| Rating | mount | 5738 | 5776 | 5000 | |
| SearchBox | mount | 1186 | 1164 | 5000 | |
| Shimmer | mount | 2411 | 2369 | 5000 | |
| Slider | mount | 1713 | 1737 | 5000 | |
| SpinButton | mount | 3749 | 3701 | 5000 | |
| Spinner | mount | 522 | 528 | 5000 | |
| SplitButton | mount | 2463 | 2460 | 5000 | |
| Stack | mount | 546 | 533 | 5000 | |
| StackWithIntrinsicChildren | mount | 1146 | 1157 | 5000 | |
| StackWithTextChildren | mount | 3223 | 3213 | 5000 | |
| SwatchColorPicker | mount | 8277 | 8143 | 5000 | |
| TagPicker | mount | 2004 | 2004 | 5000 | |
| Text | mount | 500 | 499 | 5000 | |
| TextField | mount | 1156 | 1203 | 5000 | |
| ThemeProvider | mount | 1123 | 1146 | 5000 | |
| ThemeProvider | virtual-rerender | 772 | 798 | 5000 | |
| ThemeProvider | virtual-rerender-with-unmount | 1718 | 1731 | 5000 | |
| Toggle | mount | 803 | 804 | 5000 | |
| buttonNative | mount | 280 | 290 | 5000 |
c17e0b6 to
d0cbcb7
Compare
d0cbcb7 to
22c8363
Compare
|
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit 58d2f32:
|
Asset size changesSize Auditor did not detect a change in bundle size for any component! Baseline commit: a4e6775a446d201c641c9d10c455efd7b6e66cba (build) |
24d79c3 to
b03a22a
Compare
|
@spmonahan Could you please take a look at this? |
|
@okonech Thanks for the PR and sorry it's taken me a bit to look at it. I agree that the existing behavior is confusing but this PR is a breaking API change so we cannot accept it as-is. In reviewing your PR I looked into /** Custom logic to generate item keys. Required if `TItem` does not have a `key` property. */
getKey?: (item: TItem, index?: number) => string | number;Of course this is far from ideal because not only do you have to read the Fluent source code to be aware of it, but it's also counterintuitive that you'd need to provide Perhaps there is also an opportunity to change the way selection is initialized in What do you think? cc @behowell |
spmonahan
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change is a breaking API change. Putting a block on merging it while other options are discussed.
|
This gets a little wonky, but the simplest non-breaking change would be a new method for the Selection object: setGetKey(getKey: (item: TItem, index?: number) => string | number) : void. Then in the referenced code, we would update the passed selection object with the passed getKey implementation. It would be cleaner to instead spread the props of the Selection object passed to DetailsList and create a new Selection object (plus the DetailsList's implementation of getKey if a getKey was not provided)
but that might break use cases where the users rely on their manually created Selection object's reference being passed in some way. What do you think? |
|
@spmonahan do you have any thoughts? |
… mutually exclusive
7307c24 to
6e77323
Compare
|
@spmonahan I've made the change to revert the breaking types change. The PR is now limited to warning users when they use the selection and getKey properties as they are intended to be mutually exclusive. This also fixes the recommended storybook example to follow suit. |
|
@ThomasMichon could you please take a look at this? |
|
@ThomasMichon ping :) |
|
@ThomasMichon could you please review? |
🕵 fluentuiv8 No visual regressions between this PR and main |
|
/azp run Fluent UI React - PR and CI |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
🎉 Handy links: |
* master: (24 commits) chore(react-tabster): upgrade tabster to v4.4.2 (microsoft#27540) feat(react-tags): Add TagGroup with context (microsoft#27886) applying package updates fix(react-infobutton): Add aria-owns to InfoLabel (microsoft#27834) fix(recipes-react-components): Add a FluentProvider to the local storybook (microsoft#27746) chore: update RFC template (microsoft#27880) applying package updates feat: implement Toaster offset (microsoft#27854) feat(react-drawer): create DrawerFooter component (microsoft#27583) Make getKey and selection props mutually exclusive (microsoft#24048) Added MIGRATION.md to the Breadcrumb (microsoft#27846) update Github CODEOWNERS file (microsoft#27849) feat(react-tags): make basic Tag a button instead of div (microsoft#27858) chore: add test-ssr script to v9 packages (microsoft#27690) chore(react-tree): exports TreeItemAside unstable (microsoft#27856) bugfix(react-dialog): removes unnecessary grid gaps (microsoft#27845) applying package updates fix(react-textarea): Don't remove outline when filled and disabled and apply correct disabled color to text (microsoft#27837) feat: Implement limit for toast stacking (microsoft#27848) Update README.md for fluent 2 theme to include import instructions (microsoft#27847) ...
* feat/drawer-header: (24 commits) chore(react-tabster): upgrade tabster to v4.4.2 (microsoft#27540) feat(react-tags): Add TagGroup with context (microsoft#27886) applying package updates fix(react-infobutton): Add aria-owns to InfoLabel (microsoft#27834) fix(recipes-react-components): Add a FluentProvider to the local storybook (microsoft#27746) chore: update RFC template (microsoft#27880) applying package updates feat: implement Toaster offset (microsoft#27854) feat(react-drawer): create DrawerFooter component (microsoft#27583) Make getKey and selection props mutually exclusive (microsoft#24048) fix: move style override to outside the component Added MIGRATION.md to the Breadcrumb (microsoft#27846) update Github CODEOWNERS file (microsoft#27849) feat(react-tags): make basic Tag a button instead of div (microsoft#27858) chore: add test-ssr script to v9 packages (microsoft#27690) chore(react-tree): exports TreeItemAside unstable (microsoft#27856) bugfix(react-dialog): removes unnecessary grid gaps (microsoft#27845) applying package updates fix(react-textarea): Don't remove outline when filled and disabled and apply correct disabled color to text (microsoft#27837) feat: Implement limit for toast stacking (microsoft#27848) ...
Current Behavior
DetailsList allows passing the "getKey" prop along with a "selection" prop. This is confusing to users, since the "getKey" prop function will never be called. Instead, the Selection object passed in the "selection" prop either explicitly declares a getKey function, or uses the default getKey implementation (item) => item.key.
The function passed in the "getKey" prop is only used when a Selection object is not passed in the "selection" prop. In this case, DetailsListBase creates a new internally passed Selection object which is passed the function from "getKey" prop.
User Impact
Items may not receive proper selection when loading new data. Items may not retain checked status when the Detailslist is sorted
Workaround
Do not pass the getKey function if the Selection object is passed. Users must instead define the getKey function on the Selection object.
New Behavior
DetailsList will warn uses in non-production environments when "getKey" and "selection" props are passed simultaneously. Making "getKey" and "selection" mutually exclusive DetailsList properties prevents users from making this mistake.
Related Issue(s)
(#23614)
Fixes #