Skip to content

Commit

Permalink
docs(react-motions): restructure docs (#30573)
Browse files Browse the repository at this point in the history
  • Loading branch information
layershifter authored Feb 19, 2024
1 parent 10be419 commit 2d8daef
Show file tree
Hide file tree
Showing 29 changed files with 195 additions and 252 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
You can create completely custom motion that are defined by `AtomMotion` interface. `AtomMotion` contains definitions for `keyframes` and its options that are used internally to create [`KeyframeEffect`](https://developer.mozilla.org/en-US/docs/Web/API/KeyframeEffect) for an animation.

```tsx
import type { AtomMotion, createMotionComponent } from '@fluentui/react-motions-preview';

const customAtom: AtomMotion = {
// opacity will be animated from 0 to 1
keyframes: [{ opacity: 0 }, { opacity: 1 }],
// duration of the animation will be "1000ms"
duration: 1000,
};
const CustomMotion = createMotionComponent(customAtom);
```
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { makeStyles, shorthands, tokens } from '@fluentui/react-components';
import { createMotionComponent } from '@fluentui/react-motions-preview';
import * as React from 'react';

import description from './CustomMotion.stories.md';
import description from './CreateMotionComponent.stories.md';

const useClasses = makeStyles({
container: {
Expand Down Expand Up @@ -39,7 +39,7 @@ const DropIn = createMotionComponent({
duration: 4000,
});

export const CustomMotion = () => {
export const CreateMotionComponent = () => {
const classes = useClasses();

return (
Expand All @@ -55,7 +55,7 @@ export const CustomMotion = () => {
);
};

CustomMotion.parameters = {
CreateMotionComponent.parameters = {
docs: {
description: {
story: description,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const FadeEnter = createMotionComponent({
duration: motionTokens.durationSlow,
});

export const MotionDefault = () => {
export const CreateMotionComponentDefault = () => {
const classes = useClasses();
const motionRef = React.useRef<MotionImperativeRef>();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
`createMotionComponent()` is a factory function that creates a custom motion component powered by Web Animations API.

<!-- Don't allow prettier to collapse code block into single line -->
<!-- prettier-ignore -->
> **⚠️ Preview packages are considered unstable:**
> - Features and APIs may change before final release
> - Please contact us if you intend to use this in your product
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fluent UI provides a set of design tokens, via `tokens` object, for example `tokens.colorNeutralForeground1`. You can use them to create your own motions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,9 @@ TokensUsage.parameters = {
description: {
story: description,
},
name: 'foo',
},
name: 'foo',
storyName: 'foo',
title: 'components/Button',
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import CreateMotionComponentDescription from './CreateMotionComponentDescription.md';

export { CreateMotionComponentDefault as Default } from './CreateMotionComponentDefault.stories';

export { CreateMotionComponent as createMotionComponent } from './CreateMotionComponent.stories';

export { ImperativeRefPlayState as imperativeRef } from './ImperativeRefPlayState.stories';
export { TokensUsage as tokens } from './TokensUsage.stories';

export default {
title: 'Utilities/Web Motions (Preview)/createMotionComponent',
component: null,
parameters: {
docs: {
description: {
component: CreateMotionComponentDescription,
},
},
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
You can create completely custom motions with `createPresenceComponent()` factory. `PresenceMotion` contains definitions for `enter` and `exit` atoms defined by `AtomMotion` interface:

```tsx
import { createPresenceComponent } from '@fluentui/react-motions-preview';
import type { AtomMotion, PresenceMotion } from '@fluentui/react-motions-preview';

const enterAtom: AtomMotion = {
// opacity will be animated from 0 to 1
keyframes: { opacity: [0, 1] },
// duration of the animation will be "1000ms"
duration: 1000,
};

const exitAtom: AtomMotion = {
// opacity will be animated from 1 to 0
keyframes: { opacity: [1, 0] },
// duration of the animation will be "500ms"
duration: 500,
};

const presense: PresenceMotion = {
enter: enterAtom,
exit: exitAtom,
};

const Fade = createPresenceComponent(presense);
```
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { makeStyles, shorthands, tokens, Label, Slider, useId, Checkbox } from '@fluentui/react-components';
import { createPresenceComponent, motionTokens } from '@fluentui/react-motions-preview';
import { makeStyles, shorthands, tokens, Checkbox } from '@fluentui/react-components';
import { createPresenceComponent } from '@fluentui/react-motions-preview';
import type { MotionImperativeRef } from '@fluentui/react-motions-preview';
import * as React from 'react';

Expand Down Expand Up @@ -43,62 +43,42 @@ const useClasses = makeStyles({
},
});

const Fade = createPresenceComponent({
const DropIn = createPresenceComponent({
enter: {
keyframes: [{ opacity: 0 }, { opacity: 1 }],
duration: motionTokens.durationSlow,
keyframes: [
{ transform: 'rotate(-30deg) translateY(-100%)', opacity: 0 },
{ transform: 'rotate(0deg) translateY(0%)', opacity: 1 },
],
duration: 2000,
},
exit: {
keyframes: [{ opacity: 1 }, { opacity: 0 }],
duration: motionTokens.durationSlow,
duration: 1000,
},
});

export const CreatePresenceComponent = () => {
const classes = useClasses();
const sliderId = useId();

const motionRef = React.useRef<MotionImperativeRef>();

const [playbackRate, setPlaybackRate] = React.useState<number>(30);
const [visible, setVisible] = React.useState<boolean>(false);

// Heads up!
// This is optional and is intended solely to slow down the animations, making motions more visible in the examples.
React.useEffect(() => {
motionRef.current?.setPlaybackRate(playbackRate / 100);
}, [playbackRate, visible]);

return (
<>
<div className={classes.container}>
<div className={classes.card}>
<Fade imperativeRef={motionRef} visible={visible}>
<DropIn imperativeRef={motionRef} visible={visible}>
<div className={classes.item} />
</Fade>
</DropIn>

<code className={classes.description}>fadeSlow</code>
<code className={classes.description}>Drop in</code>
</div>
</div>

<div className={classes.controls}>
<div>
<Checkbox label={<code>visible</code>} checked={visible} onChange={() => setVisible(v => !v)} />
</div>
<div>
<Label htmlFor={sliderId}>
<code>playbackRate</code>: {playbackRate}%
</Label>
<Slider
aria-valuetext={`Value is ${playbackRate}%`}
value={playbackRate}
onChange={(ev, data) => setPlaybackRate(data.value)}
min={0}
id={sliderId}
max={100}
step={10}
/>
</div>
</div>
</>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { makeStyles, shorthands, tokens, Checkbox } from '@fluentui/react-components';
import { createPresenceComponent, motionTokens } from '@fluentui/react-motions-preview';
import * as React from 'react';

const useClasses = makeStyles({
container: {
display: 'grid',
gridTemplateColumns: '1fr',
...shorthands.gap('10px'),
},
card: {
display: 'flex',
flexDirection: 'column',

...shorthands.border('3px', 'solid', tokens.colorNeutralForeground3),
...shorthands.borderRadius(tokens.borderRadiusMedium),
...shorthands.padding('10px'),

alignItems: 'center',
},
item: {
backgroundColor: tokens.colorBrandBackground,
...shorthands.borderRadius('50%'),

width: '100px',
height: '100px',
},
description: {
...shorthands.margin('5px'),
},
controls: {
display: 'flex',
flexDirection: 'column',

marginTop: '20px',

...shorthands.border('3px', 'solid', tokens.colorNeutralForeground3),
...shorthands.borderRadius(tokens.borderRadiusMedium),
...shorthands.padding('10px'),
},
});

const Fade = createPresenceComponent({
enter: {
keyframes: [{ opacity: 0 }, { opacity: 1 }],
duration: motionTokens.durationSlow,
},
exit: {
keyframes: [{ opacity: 1 }, { opacity: 0 }],
duration: motionTokens.durationSlow,
},
});

export const CreatePresenceComponentDefault = () => {
const classes = useClasses();
const [visible, setVisible] = React.useState<boolean>(false);

return (
<>
<div className={classes.container}>
<div className={classes.card}>
<Fade visible={visible}>
<div className={classes.item} />
</Fade>

<code className={classes.description}>fadeSlow</code>
</div>
</div>

<div className={classes.controls}>
<div>
<Checkbox label={<code>visible</code>} checked={visible} onChange={() => setVisible(v => !v)} />
</div>
</div>
</>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
`createPresenceComponent()` is a factory function that creates a React component based on the provided presence definition. This component can be used to animate any element and intended to have a state via the `visible` prop.

<!-- Don't allow prettier to collapse code block into single line -->
<!-- prettier-ignore -->
> **⚠️ Preview packages are considered unstable:**
> - Features and APIs may change before final release
> - Please contact us if you intend to use this in your product
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import CreatePresenceComponentDescription from './CreatePresenceComponentDescription.md';

export { CreatePresenceComponentDefault as Default } from './CreatePresenceComponentDefault.stories';

export { CreatePresenceComponent as createPresenceComponent } from './CreatePresenceComponent.stories';

export { PresenceAppear as appear } from './PresenceAppear.stories';
export { PresenceUnmountOnExit as unmountOnExit } from './PresenceUnmountOnExit.stories';
export { PresenceOnMotionFinish as onMotionFinish } from './PresenceOnMotionFinish.stories';

export { MotionFunctions as functions } from './MotionFunctions.stories';

export default {
title: 'Utilities/Web Motions (Preview)/createPresenceComponent',
component: null,
parameters: {
docs: {
description: {
component: CreatePresenceComponentDescription,
},
},
},
};

This file was deleted.

Loading

0 comments on commit 2d8daef

Please sign in to comment.