diff --git a/apps/vr-tests-react-components/src/stories/PresenceBadge.stories.tsx b/apps/vr-tests-react-components/src/stories/PresenceBadge.stories.tsx index 537d44061f264..bb430a79932ea 100644 --- a/apps/vr-tests-react-components/src/stories/PresenceBadge.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/PresenceBadge.stories.tsx @@ -1,16 +1,12 @@ import { storiesOf } from '@storybook/react'; import * as React from 'react'; -import { PresenceBadge, PresenceBadgeProps } from '@fluentui/react-badge'; +import { PresenceBadge } from '@fluentui/react-badge'; +import { tokens } from '@fluentui/react-theme'; +import { Steps, StoryWright } from 'storywright'; +import { TestWrapperDecorator } from '../utilities/TestWrapperDecorator'; -const statuses: PresenceBadgeProps['status'][] = [ - 'available', - 'away', - 'busy', - 'do-not-disturb', - 'offline', - 'out-of-office', - 'unknown', -]; +const statuses = ['available', 'away', 'busy', 'do-not-disturb', 'offline', 'out-of-office', 'unknown'] as const; +const sizes = ['tiny', 'extra-small', 'small', 'medium', 'large', 'extra-large'] as const; storiesOf('PresenceBadge Converged - status', module).addStory( 'default', @@ -40,12 +36,43 @@ storiesOf('PresenceBadge Converged - sizes', module).addStory( 'default', () => (
- {(['tiny', 'extra-small', 'small', 'medium', 'large', 'extra-large'] as PresenceBadgeProps['size'][]).map( - size => ( - - ), - )} + {sizes.map(size => ( + + ))}
), { includeRtl: true }, ); + +storiesOf('PresenceBadge Converged - inverted background', module) + .addDecorator(TestWrapperDecorator) + .addDecorator(story => ( + {story()} + )) + .addStory( + 'default', + () => ( +
+ {sizes.map(size => ( + <> + {statuses.map(status => ( + + ))} + {statuses.map(status => ( + + ))} + + ))} +
+ ), + { includeHighContrast: true, includeDarkMode: true }, + ); diff --git a/change/@fluentui-react-badge-4df99d1f-b2d8-4ebd-a8c8-defa2b7568f2.json b/change/@fluentui-react-badge-4df99d1f-b2d8-4ebd-a8c8-defa2b7568f2.json new file mode 100644 index 0000000000000..f87b9b22f9b97 --- /dev/null +++ b/change/@fluentui-react-badge-4df99d1f-b2d8-4ebd-a8c8-defa2b7568f2.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "fix: Remove white border around presence badge when on a dark background", + "packageName": "@fluentui/react-badge", + "email": "behowell@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/react-components/react-badge/src/components/PresenceBadge/usePresenceBadgeStyles.styles.ts b/packages/react-components/react-badge/src/components/PresenceBadge/usePresenceBadgeStyles.styles.ts index aa2e505d68174..599edae2e48f8 100644 --- a/packages/react-components/react-badge/src/components/PresenceBadge/usePresenceBadgeStyles.styles.ts +++ b/packages/react-components/react-badge/src/components/PresenceBadge/usePresenceBadgeStyles.styles.ts @@ -18,17 +18,25 @@ const getIsBusy = (status: PresenceBadgeStatus): boolean => { }; const useRootClassName = makeResetStyles({ - padding: 0, display: 'inline-flex', boxSizing: 'border-box', alignItems: 'center', justifyContent: 'center', - '& span': { - display: 'flex', - }, borderRadius: tokens.borderRadiusCircular, backgroundColor: tokens.colorNeutralBackground1, + + // The background color bleeds around the edge of the icon due to antialiasing on the svg and element background. + // Since all presence icons have a border around the edge that is at least 1px wide*, we can inset the background + // using padding and backgroundClip. The icon has margin: -1px to account for the padding. + // (* except size="tiny", where backgroundClip is unset) + padding: '1px', + backgroundClip: 'content-box', +}); + +const useIconClassName = makeResetStyles({ + display: 'flex', + margin: '-1px', }); const useStyles = makeStyles({ @@ -69,6 +77,7 @@ const useStyles = makeStyles({ tiny: { aspectRatio: '1', width: '6px', + backgroundClip: 'unset', // tiny icons have a border less than 1px wide, and can't use the backgroundClip fix '& svg': { width: '6px !important', height: '6px !important', @@ -97,6 +106,7 @@ const useStyles = makeStyles({ */ export const usePresenceBadgeStyles_unstable = (state: PresenceBadgeState): PresenceBadgeState => { const rootClassName = useRootClassName(); + const iconClassName = useIconClassName(); const styles = useStyles(); const isBusy = getIsBusy(state.status); state.root.className = mergeClasses( @@ -122,7 +132,7 @@ export const usePresenceBadgeStyles_unstable = (state: PresenceBadgeState): Pres ); if (state.icon) { - state.icon.className = mergeClasses(presenceBadgeClassNames.icon, state.icon.className); + state.icon.className = mergeClasses(presenceBadgeClassNames.icon, iconClassName, state.icon.className); } return state;