-
Notifications
You must be signed in to change notification settings - Fork 2.9k
feat: Implement shared AvatarContext #24807
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
feat: Implement shared AvatarContext #24807
Conversation
Done as part or RFC 24790. Creates a new context in react-shared-contexts that will be consumed by the `Avatar` component. This context provider can be used only internally and it is up to the component author to make sure that the provider is located as close as possible to where the overrides need to occur.
📊 Bundle size reportUnchanged fixtures
|
Asset size changesUnable to find bundle size details for Baseline commit: a0d258e Possible causes
Recommendations
|
|
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 810164e:
|
Perf Analysis (
|
| Scenario | Render type | Master Ticks | PR Ticks | Iterations | Status |
|---|---|---|---|---|---|
| Avatar | mount | 1689 | 1697 | 5000 | |
| Button | mount | 1178 | 1179 | 5000 | |
| FluentProvider | mount | 1959 | 1941 | 5000 | |
| FluentProviderWithTheme | mount | 720 | 717 | 10 | |
| FluentProviderWithTheme | virtual-rerender | 667 | 679 | 10 | |
| FluentProviderWithTheme | virtual-rerender-with-unmount | 730 | 734 | 10 | |
| MakeStyles | mount | 2338 | 2311 | 50000 | |
| SpinButton | mount | 3305 | 3237 | 5000 |
| @@ -0,0 +1,28 @@ | |||
| import * as React from 'react'; | |||
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.
It's up to you, but I think that it should be hosted in a separate package as portal-compat-context.
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.
Or is there any real issue with including it in the react-avatar package? The rest of react-avatar should be tree shaken out of react-table if it's not used, right?
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.
I don't mind, I've moved the avatar context to react-avatar in e29a351
|
|
||
| const avatar = React.useMemo( | ||
| () => ({ | ||
| size: tableAvatarSizeMap[tableSize], |
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.
IMO, a value should be stored in state so it could be overridden with composition patterns.
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.
you're right, I added avatarSize to state
|
Could also be moved to a specific package like |
| @@ -1,5 +1,6 @@ | |||
| import { PresenceBadge } from '@fluentui/react-badge'; | |||
| import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities'; | |||
| import type { AvatarSizes as AvatarContextSizes } from '@fluentui/react-shared-contexts'; | |||
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.
Would it work to just export it directly?
| import type { AvatarSizes as AvatarContextSizes } from '@fluentui/react-shared-contexts'; | |
| export type { AvatarSizes } from '@fluentui/react-shared-contexts'; |
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.
yeah that would work
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.
Fixed in e48ff9c
| <AvatarContextProvider value={contextValues.avatar}> | ||
| {slots.media && <slots.media {...slotProps.media} />} | ||
| </AvatarContextProvider> |
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.
Don't need to include the AvatarContextProvider if there's no media content:
| <AvatarContextProvider value={contextValues.avatar}> | |
| {slots.media && <slots.media {...slotProps.media} />} | |
| </AvatarContextProvider> | |
| {slots.media && ( | |
| <AvatarContextProvider value={contextValues.avatar}> | |
| <slots.media {...slotProps.media} /> | |
| </AvatarContextProvider> | |
| )} |
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.
Fixed in e29a351
| import { useTableContext } from '../../contexts/tableContext'; | ||
|
|
||
| const tableAvatarSizeMap = { | ||
| medium: undefined, |
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.
Should this be 32 instead of undefined? Unless table specifically doesn't care about the size in this state.
| medium: undefined, | |
| medium: 32, |
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.
32 is the default so I didn't think I'd need to add it, but I can
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.
Added in f792ca2
| badge={{ status: item.author.status as PresenceBadgeStatus }} | ||
| size={24} | ||
| /> | ||
| <Avatar name={item.author.label} badge={{ status: item.author.status as PresenceBadgeStatus }} /> |
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.
(nit) This is unrelated to this change, but we should encourage as casts like this in stories. You could either define the entire items array as const, or possibly adding making the individual statuses as const in the object, like status: 'available' as const
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.
Fixed in bcf7dab
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.
Thanks! I just realized I left out "not" in "should not encourage" 🤦♂️ but I think you figured it out 🙂
| @@ -0,0 +1,28 @@ | |||
| import * as React from 'react'; | |||
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.
Or is there any real issue with including it in the react-avatar package? The rest of react-avatar should be tree shaken out of react-table if it's not used, right?
behowell
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.
Looks good, thanks for adding this!
| /** | ||
| * Sizes for the avatar | ||
| */ | ||
| export type AvatarSizes = 16 | 20 | 24 | 28 | 32 | 36 | 40 | 48 | 56 | 64 | 72 | 96 | 120 | 128; |
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.
Since this is now in react-avatar, could you leave the AvatarSizes type in Avatar.types.ts, and import it here instead?
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.
done in d0a098d
| { | ||
| "type": "minor", | ||
| "comment": "feat: Implement AvatarContext", | ||
| "packageName": "@fluentui/react-shared-contexts", | ||
| "email": "[email protected]", | ||
| "dependentChangeType": "patch" | ||
| } |
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 can be removed
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.
Removed in ef70cc8
| @@ -0,0 +1,7 @@ | |||
| { | |||
| "type": "minor", | |||
| "comment": "feat: consume shared AvatarContext", | |||
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.
(nit) Update this description now that AvatarContext is implemented in react-avatar
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.
Updated in ef70cc8
| */ | ||
| export type TableCellLayoutState = ComponentState<TableCellLayoutSlots> & Pick<TableCellLayoutProps, 'appearance'>; | ||
| export type TableCellLayoutState = ComponentState<TableCellLayoutSlots> & | ||
| Pick<TableCellLayoutProps, 'appearance'> & { size: TableContextValue['size']; avatarSize: AvatarSizes | undefined }; |
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.
(nit) You don't seem to be using the new size state variable anywhere (unless I'm missing it). I suppose it doesn't hurt to have it, but is it needed?
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.
done in 810164e
* feat: Implement shared AvatarContext Done as part or RFC 24790. Creates a new context in react-shared-contexts that will be consumed by the `Avatar` component. This context provider can be used only internally and it is up to the component author to make sure that the provider is located as close as possible to where the overrides need to occur. * update md * changefiles * improve types * avatar sizes source of truth * remove doc * update mdn * use react-avatar-context * avatar context belongs in react-avatar * be explicit about medium size * avatar sizes exported from react-avatar * remove casts for status * update md * update import * define avatar size in avatar types * update changefiles * update table types

Done as part or RFC 24790. Creates a new context in react-shared-contexts that will be consumed by the
Avatarcomponent.This context provider can be used only internally and it is up to the component author to make sure that the provider is located as close as possible to where the overrides need to occur.
The PR includes the first usage of this context in the
mediaslot ofTableCellLayoutFixes #24805