Skip to content

Commit

Permalink
Merge branch 'master' into add-portal-slot-to-combos
Browse files Browse the repository at this point in the history
  • Loading branch information
GeoffCoxMSFT authored Jul 28, 2023
2 parents 80535b1 + bdbf3ae commit c0726d2
Show file tree
Hide file tree
Showing 294 changed files with 2,518 additions and 1,645 deletions.
8 changes: 7 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// Default eslintrc for packages without one, or files outside a package
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
Expand All @@ -20,5 +19,12 @@
"**/node_modules",
"**/temp",
"**/*.scss.ts"
],
"overrides": [
{
"files": "*.json",
"parser": "jsonc-eslint-parser",
"rules": {}
}
]
}
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
},
"editor.rulers": [120],
"eslint.workingDirectories": [{ "mode": "auto" }], // infer working directory based on .eslintrc/package.json location
"eslint.validate": ["json"],
"files.associations": {
"**/package.json.hbs": "json",
"**/*.json.hbs": "jsonc",
Expand Down
116 changes: 116 additions & 0 deletions apps/vr-tests-react-components/src/stories/Positioning.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,99 @@ const AutoSize = () => {
);
};

const AutoSizeAsyncContent = () => {
const styles = useStyles();
const [overflowBoundary, setOverflowBoundary] = React.useState<HTMLDivElement | null>(null);
const { containerRef, targetRef } = usePositioning({
position: 'below',
autoSize: true,
overflowBoundary,
});

return (
<div
ref={setOverflowBoundary}
className={styles.boundary}
style={{
display: 'flex',
flexDirection: 'column',
height: 200,
padding: '10px 50px',
position: 'relative',
}}
>
<button ref={targetRef}>Target</button>
<Box ref={containerRef} style={{ overflow: 'auto', border: '3px solid green' }}>
<AsyncFloatingContent />
</Box>
</div>
);
};
const AsyncFloatingContent = () => {
const [isLoaded, setLoaded] = React.useState(false);
const onLoaded = () => setLoaded(true);
return isLoaded ? (
<span id="full-content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
magna aliqua. In fermentum et sollicitudin ac orci phasellus egestas. Facilisi cras fermentum odio eu feugiat
pretium nibh ipsum consequat.
</span>
) : (
<button id="load-content" onClick={onLoaded}>
load
</button>
);
};

const AutoSizeUpdatePosition = () => {
const styles = useStyles();
const [overflowBoundary, setOverflowBoundary] = React.useState<HTMLDivElement | null>(null);
const positioningRef = React.useRef<PositioningImperativeRef>(null);
const { containerRef, targetRef } = usePositioning({
position: 'below',
align: 'start',
autoSize: true,
overflowBoundary,
positioningRef,
});

const [isLoaded, setLoaded] = React.useState(false);
const onLoaded = () => setLoaded(true);

React.useEffect(() => {
if (isLoaded) {
positioningRef.current?.updatePosition();
}
}, [isLoaded]);

return (
<div
ref={setOverflowBoundary}
className={styles.boundary}
style={{
display: 'flex',
flexDirection: 'column',
height: 200,
width: 250,
position: 'relative',
}}
>
<button ref={targetRef} style={{ width: 'fit-content', marginLeft: 100, marginTop: 10 }}>
Target
</button>
<Box ref={containerRef} style={{ overflow: 'clip', overflowClipMargin: 10, border: '3px solid green' }}>
{isLoaded ? (
<div id="full-content" style={{ backgroundColor: 'cornflowerblue', width: 300, height: 100 }} />
) : (
<button id="load-content" onClick={onLoaded}>
load + update position
</button>
)}
</Box>
</div>
);
};

const DisableTether = () => {
const styles = useStyles();
const { containerRef, targetRef } = usePositioning({
Expand Down Expand Up @@ -1019,6 +1112,29 @@ storiesOf('Positioning', module)
.addStory('horizontal overflow', () => <HorizontalOverflow />, { includeRtl: true })
.addStory('pinned', () => <Pinned />)
.addStory('auto size', () => <AutoSize />)
.addStory('auto size with async content', () => (
<StoryWright
steps={new Steps()
.click('#load-content')
.wait('#full-content')
.snapshot('floating element is within the boundary')
.end()}
>
<AutoSizeAsyncContent />
</StoryWright>
))
.addStory('auto size with async content reset styles on updatePosition', () => (
<StoryWright
steps={new Steps()
.click('#load-content')
.wait('#full-content')
.wait(250) // let updatePosition finish
.snapshot('floating element width fills boundary and overflows 10px because of overflow:clip')
.end()}
>
<AutoSizeUpdatePosition />
</StoryWright>
))
.addStory('disable tether', () => <DisableTether />)
.addStory('position fixed', () => <PositionAndAlignProps positionFixed />, { includeRtl: true })
.addStory('virtual element', () => <VirtualElement />)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import * as React from 'react';
import { InteractionTag } from '@fluentui/react-tags-preview';
import { bundleIcon, CalendarMonthFilled, CalendarMonthRegular } from '@fluentui/react-icons';
import { ComponentMeta } from '@storybook/react';
import { getStoryVariant, withStoryWrightSteps, DARK_MODE, HIGH_CONTRAST } from '../../utilities';
import { Steps } from 'storywright';

const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular);

const contentId = 'content-id';
const dismissButtonId = 'dismiss-button-id';
const steps = new Steps()
.snapshot('default', { cropTo: '.testWrapper' })
.hover(`#${contentId}`)
.snapshot('hover content', { cropTo: '.testWrapper' })
.mouseDown(`#${contentId}`)
.snapshot('pressed content', { cropTo: '.testWrapper' })
.hover(`#${dismissButtonId}`)
.snapshot('hover dismiss', { cropTo: '.testWrapper' })
.mouseDown(`#${dismissButtonId}`)
.snapshot('pressed dismiss', { cropTo: '.testWrapper' })
.end();

export default {
title: 'InteractionTag Converged',
Component: InteractionTag,
decorators: [story => withStoryWrightSteps({ story, steps })],
} as ComponentMeta<typeof InteractionTag>;

export const Filled = () => (
<InteractionTag
content={{ id: contentId }}
appearance="filled"
dismissible
dismissButton={{ id: dismissButtonId }}
icon={<CalendarMonth />}
>
Primary Text
</InteractionTag>
);
export const FilledHighContrast = getStoryVariant(Filled, HIGH_CONTRAST);
export const FilledDarkMode = getStoryVariant(Filled, DARK_MODE);

export const Outline = () => (
<InteractionTag
content={{ id: contentId }}
appearance="outline"
dismissible
dismissButton={{ id: dismissButtonId }}
icon={<CalendarMonth />}
>
Primary Text
</InteractionTag>
);
export const OutlineHighContrast = getStoryVariant(Outline, HIGH_CONTRAST);
export const OutlineDarkMode = getStoryVariant(Outline, DARK_MODE);

export const Brand = () => (
<InteractionTag
content={{ id: contentId }}
appearance="brand"
dismissible
dismissButton={{ id: dismissButtonId }}
icon={<CalendarMonth />}
>
Primary Text
</InteractionTag>
);
export const BrandHighContrast = getStoryVariant(Brand, HIGH_CONTRAST);
export const BrandDarkMode = getStoryVariant(Brand, DARK_MODE);
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import * as React from 'react';
import { InteractionTag } from '@fluentui/react-tags-preview';
import { ComponentMeta } from '@storybook/react';
import { getStoryVariant, withStoryWrightSteps, RTL } from '../../utilities';
import { Avatar } from '@fluentui/react-avatar';
import { Steps } from 'storywright';

const contentId = 'content-id';
const dismissButtonId = 'dismiss-button-id';
const steps = new Steps()
.snapshot('default', { cropTo: '.testWrapper' })

// This needs to be added so that the focus outline is shown correctly
.executeScript(`document.querySelector('#${contentId}').setAttribute('data-fui-focus-visible', '')`)
.focus(`#${contentId}`)
.snapshot('focus content', { cropTo: '.testWrapper' })
.executeScript(`document.querySelector('#${contentId}').removeAttribute('data-fui-focus-visible')`)

// This needs to be added so that the focus outline is shown correctly
.executeScript(`document.querySelector('#${dismissButtonId}').setAttribute('data-fui-focus-visible', '')`)
.focus(`#${dismissButtonId}`)
.snapshot('focus dismiss', { cropTo: '.testWrapper' })
.executeScript(`document.querySelector('#${dismissButtonId}').removeAttribute('data-fui-focus-visible')`)

.end();

export default {
title: 'InteractionTag Converged',
Component: InteractionTag,
decorators: [story => withStoryWrightSteps({ story, steps })],
} as ComponentMeta<typeof InteractionTag>;

export const Rounded = () => <InteractionTag content={{ id: contentId }}>Primary Text</InteractionTag>;

export const RoundedWithSecondaryText = () => (
<InteractionTag content={{ id: contentId }} secondaryText="Secondary Text">
Primary Text
</InteractionTag>
);

export const RoundedWithMedia = () => (
<InteractionTag content={{ id: contentId }} media={<Avatar name="Lydia Bauer" badge={{ status: 'available' }} />}>
Primary Text
</InteractionTag>
);
export const RoundedWithMediaRTL = getStoryVariant(RoundedWithMedia, RTL);

export const RoundedDismissible = () => (
<InteractionTag content={{ id: contentId }} dismissible dismissButton={{ id: dismissButtonId }}>
Primary Text
</InteractionTag>
);
export const RoundedDismissibleRTL = getStoryVariant(RoundedDismissible, RTL);

export const Circular = () => (
<InteractionTag content={{ id: contentId }} shape="circular">
Primary Text
</InteractionTag>
);

export const CircularWithSecondaryText = () => (
<InteractionTag content={{ id: contentId }} shape="circular" secondaryText="Secondary Text">
Primary Text
</InteractionTag>
);

export const CircularWithMedia = () => (
<InteractionTag
content={{ id: contentId }}
shape="circular"
media={<Avatar name="Lydia Bauer" badge={{ status: 'available' }} />}
>
Primary Text
</InteractionTag>
);
export const CircularWithMediaRTL = getStoryVariant(CircularWithMedia, RTL);

export const CircularDismissible = () => (
<InteractionTag content={{ id: contentId }} shape="circular" dismissible dismissButton={{ id: dismissButtonId }}>
Primary Text
</InteractionTag>
);
export const CircularDismissibleRTL = getStoryVariant(CircularDismissible, RTL);
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import * as React from 'react';
import { Tag } from '@fluentui/react-tags-preview';
import { bundleIcon, CalendarMonthFilled, CalendarMonthRegular } from '@fluentui/react-icons';
import { ComponentMeta } from '@storybook/react';
import { getStoryVariant, withStoryWrightSteps, DARK_MODE, HIGH_CONTRAST } from '../../utilities';
import { Steps } from 'storywright';

const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular);

const tagId = 'tag-id';
const steps = new Steps()
.snapshot('default', { cropTo: '.testWrapper' })
.hover(`#${tagId}}`)
.snapshot('hover', { cropTo: '.testWrapper' })
.mouseDown(`#${tagId}}`)
.snapshot('pressed', { cropTo: '.testWrapper' })
.end();

export default {
title: 'Tag Converged',
Component: Tag,
decorators: [story => withStoryWrightSteps({ story, steps })],
} as ComponentMeta<typeof Tag>;

export const Filled = () => (
<Tag id={tagId} appearance="filled" dismissible icon={<CalendarMonth />}>
Primary Text
</Tag>
);

export const FilledHighContrast = getStoryVariant(Filled, HIGH_CONTRAST);
export const FilledDarkMode = getStoryVariant(Filled, DARK_MODE);

export const Outline = () => (
<Tag id={tagId} appearance="outline" dismissible icon={<CalendarMonth />}>
Primary Text
</Tag>
);

export const OutlineHighContrast = getStoryVariant(Outline, HIGH_CONTRAST);
export const OutlineDarkMode = getStoryVariant(Outline, DARK_MODE);

export const Brand = () => (
<Tag id={tagId} appearance="brand" dismissible icon={<CalendarMonth />}>
Primary Text
</Tag>
);
export const BrandHighContrast = getStoryVariant(Brand, HIGH_CONTRAST);
export const BrandDarkMode = getStoryVariant(Brand, DARK_MODE);
Loading

0 comments on commit c0726d2

Please sign in to comment.