-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(react-motions): add
onMotionFinish()
to a component created by…
… `createPresenceMotion()` (#30529)
- Loading branch information
1 parent
2f30e14
commit d8b88c2
Showing
8 changed files
with
205 additions
and
12 deletions.
There are no files selected for viewing
7 changes: 7 additions & 0 deletions
7
change/@fluentui-react-motions-preview-41532783-fcce-4fdb-9b36-d4d9ddfa5ae5.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"type": "patch", | ||
"comment": "feat: add onMotionFinish() callback to createPresenceComponent()", | ||
"packageName": "@fluentui/react-motions-preview", | ||
"email": "olfedias@microsoft.com", | ||
"dependentChangeType": "patch" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
...mponents/react-motions-preview/stories/Motion/PresenceOnMotionFinish.stories.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
A React component created with `createPresenceMotion()` has an `onFinishMotion` prop. This callback will be called when a motion is finished and is useful for orchestrating motions. |
158 changes: 158 additions & 0 deletions
158
.../react-components/react-motions-preview/stories/Motion/PresenceOnMotionFinish.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
import { makeStyles, shorthands, tokens, Label, Slider, useId, Checkbox, Text } from '@fluentui/react-components'; | ||
import { createPresenceComponent, motionTokens } from '@fluentui/react-motions-preview'; | ||
import type { MotionImperativeRef } from '@fluentui/react-motions-preview'; | ||
import * as React from 'react'; | ||
|
||
import description from './PresenceOnMotionFinish.stories.md'; | ||
|
||
const useClasses = makeStyles({ | ||
container: { | ||
display: 'grid', | ||
gridTemplateColumns: '1fr 1fr', | ||
...shorthands.gap('10px'), | ||
}, | ||
card: { | ||
display: 'flex', | ||
flexDirection: 'column', | ||
|
||
...shorthands.border('3px', 'solid', tokens.colorNeutralForeground3), | ||
...shorthands.borderRadius(tokens.borderRadiusMedium), | ||
...shorthands.padding('10px'), | ||
|
||
alignItems: 'center', | ||
justifyContent: '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'), | ||
}, | ||
|
||
logContainer: { | ||
display: 'flex', | ||
flexDirection: 'column', | ||
}, | ||
logLabel: { | ||
color: tokens.colorNeutralForegroundOnBrand, | ||
backgroundColor: tokens.colorNeutralForeground3, | ||
width: 'fit-content', | ||
alignSelf: 'end', | ||
fontWeight: tokens.fontWeightBold, | ||
...shorthands.padding('2px', '12px'), | ||
...shorthands.borderRadius(tokens.borderRadiusMedium, tokens.borderRadiusMedium, 0, 0), | ||
}, | ||
log: { | ||
overflowY: 'auto', | ||
position: 'relative', | ||
height: '200px', | ||
...shorthands.border('3px', 'solid', tokens.colorNeutralForeground3), | ||
...shorthands.borderRadius(tokens.borderRadiusMedium), | ||
borderTopRightRadius: 0, | ||
...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 PresenceOnMotionFinish = () => { | ||
const classes = useClasses(); | ||
const sliderId = useId(); | ||
const logLabelId = useId(); | ||
|
||
const motionRef = React.useRef<MotionImperativeRef>(); | ||
const [statusLog, setStatusLog] = React.useState<[number, string][]>([]); | ||
|
||
const [playbackRate, setPlaybackRate] = React.useState<number>(30); | ||
const [visible, setVisible] = React.useState<boolean>(true); | ||
|
||
// 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} | ||
onMotionFinish={(ev, data) => { | ||
setStatusLog(entries => [[Date.now(), data.direction], ...entries]); | ||
}} | ||
visible={visible} | ||
> | ||
<div className={classes.item} /> | ||
</Fade> | ||
|
||
<code className={classes.description}>fade</code> | ||
</div> | ||
|
||
<div className={classes.logContainer}> | ||
<div className={classes.logLabel} id={logLabelId}> | ||
Status log | ||
</div> | ||
<div role="log" aria-labelledby={logLabelId} className={classes.log}> | ||
{statusLog.map(([time, direction], i) => ( | ||
<div key={i}> | ||
{new Date(time).toLocaleTimeString()} <Text weight="bold">onMotionFinish</Text> (direction: {direction}) | ||
</div> | ||
))} | ||
</div> | ||
</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> | ||
</> | ||
); | ||
}; | ||
|
||
PresenceOnMotionFinish.parameters = { | ||
docs: { | ||
description: { | ||
story: description, | ||
}, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters