react-transition-group#Transition TypeScript Examples
The following examples show how to use
react-transition-group#Transition.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: TabsOfTruth.tsx From mStable-apps with GNU Lesser General Public License v3.0 | 6 votes |
TabsOfTruth: FC<
State & {
setActiveIndex: (index: number) => void
className?: string
}
> = ({ tabs, setActiveIndex, activeTabIndex, className }) => {
const container = useRef<HTMLDivElement>(undefined as never)
const prevActiveTabIndex = usePrevious(activeTabIndex)
const [activePos, setActivePos] = useState<[number, number]>([0, 0])
useLayoutEffect(() => {
const { offsetWidth, offsetLeft } = container.current.childNodes.item(activeTabIndex + 1) as HTMLElement
setActivePos([offsetLeft, offsetWidth])
}, [activeTabIndex])
return (
<TabsContainer ref={container} className={className}>
<Transition in={activeTabIndex !== prevActiveTabIndex} appear timeout={250} unmountOnExit={false}>
{className => <ActiveTab pos={activePos} className={className} />}
</Transition>
{tabs.map(({ id, title, active }, index) => (
<TabButton
active={active}
key={id}
onClick={() => {
setActiveIndex(index)
}}
>
{title}
</TabButton>
))}
</TabsContainer>
)
}
Example #2
Source File: LoadProgress.tsx From NetworkViewPCF with MIT License | 6 votes |
render() {
const { progressText, isLoading, cancelRequested, isPaused } = this.props.vm;
return (
<>
<Transition in={isLoading || isPaused} timeout={500} classNames="my-node">
{state =>
state != "exited" && (
<Stack style={progressBoxStyle} className={this.getTransitionClass(state)}>
<Stack.Item>{progressText}</Stack.Item>
{isLoading && (
<Stack.Item>
{!cancelRequested && <DefaultButton text="Cancel" onClick={this.onCancel}></DefaultButton>}
</Stack.Item>
)}
{isPaused && (
<Stack.Item>
{!cancelRequested && <DefaultButton text="Resume" onClick={this.onResume}></DefaultButton>}
</Stack.Item>
)}
</Stack>
)
}
</Transition>
</>
);
}
Example #3
Source File: SlideTransition.tsx From firetable with Apache License 2.0 | 5 votes |
SlideTransition: React.ForwardRefExoticComponent<
Pick<TransitionProps, React.ReactText> & React.RefAttributes<any>
> = React.forwardRef(
({ children, ...props }: TransitionProps, ref: React.Ref<any>) => {
const theme = useTheme();
if (!children) return null;
const defaultStyle = {
opacity: 0,
transform: "translateY(16px)",
transition: theme.transitions.create(["transform", "opacity"], {
duration: "300ms",
easing: "cubic-bezier(0.075, 0.82, 0.165, 1)",
}),
};
const transitionStyles = {
entering: {
willChange: "transform, opacity",
},
entered: {
opacity: 1,
transform: "none",
},
exiting: {
opacity: 0,
transform: "none",
transition: theme.transitions.create(["opacity"], {
duration: theme.transitions.duration.leavingScreen,
}),
},
exited: {
opacity: 0,
transform: "none",
transition: "none",
},
unmounted: {},
};
return (
<Transition
appear
timeout={{ enter: 0, exit: theme.transitions.duration.leavingScreen }}
{...props}
>
{(state) =>
React.cloneElement(children as any, {
style: { ...defaultStyle, ...transitionStyles[state] },
ref,
})
}
</Transition>
);
}
)
Example #4
Source File: SlideTransition.tsx From firetable with Apache License 2.0 | 5 votes |
SlideTransitionMui = React.forwardRef(function Transition(
props: MuiTransitionProps & { children?: React.ReactElement<any, any> },
ref: React.Ref<unknown>
) {
return <SlideTransition ref={ref} {...props} />;
})
Example #5
Source File: LoadingIndicator.tsx From tobira with Apache License 2.0 | 5 votes |
LoadingIndicator: React.FC = () => {
const router = useRouter();
// If search is active, there is a loading indicator next to the search input.
if (isSearchActive()) {
return null;
}
const START_DURATION = 1200;
const EXIT_DURATION = 150;
// TODO: maybe disable this for `prefers-reduced-motion: reduce`
return <Transition in={router.isTransitioning} timeout={EXIT_DURATION}>{state => (
<div css={{
position: "fixed",
zIndex: 2000,
left: 0,
top: 0,
height: 4,
backgroundColor: "var(--accent-color)",
...match(state, {
"entering": () => ({
width: "70%",
transition: `width ${START_DURATION}ms`,
}),
"entered": () => ({
width: "70%",
transition: `width ${START_DURATION}ms`,
}),
"exiting": () => ({
width: "100%",
opacity: 0,
transition: `width ${EXIT_DURATION}ms, `
+ `opacity ${0.2 * EXIT_DURATION}ms ease ${0.8 * EXIT_DURATION}ms`,
}),
"exited": () => ({
width: "0%",
transition: "none",
}),
"unmounted": () => ({}),
}),
}} />
)}</Transition>;
}
Example #6
Source File: Toast.tsx From viewer with MIT License | 5 votes |
public render(): JSX.Element {
const { text, category, type, hasCloseButton, link } = this.props;
return (
<Transition
timeout={240}
in={this.state.isVisible}
appear={true}
unmountOnExit={true}
onExited={this.props.onRemove}
>
{(state) => (
<div
className={`itwin-toast-all itwin-toast-${state}`}
style={{
height: this.state.height,
marginBottom: this.state.isVisible ? "0" : -this.state.height,
}}
>
<div ref={this.onRef} style={{ padding: "0px 16px 16px 16px" }}>
<div className={`itwin-toast-${category}`}>
<div className="status-icon-container">
<div className={"status-icon-background"}>
{this.getCategoryIcon()}
</div>
</div>
<div className="message">{text}</div>
{link && (
<div className="link">
{typeof link.url === "string" ? (
<a
href={link.url}
target="_blank"
rel="noopener noreferrer"
>
{link.title}
</a>
) : (
<a onClick={link.url}>{link.title}</a>
)}
</div>
)}
{(type === "persisting" ||
(type === "temporary" && hasCloseButton)) && (
<div className="close-icon-container">
<Close className="close-icon" onClick={this.close} />
</div>
)}
</div>
</div>
</div>
)}
</Transition>
);
}
Example #7
Source File: Toast.tsx From itwin-viewer with MIT License | 5 votes |
public render() {
const { text, category, type, hasCloseButton, link } = this.props;
return (
<Transition
timeout={240}
in={this.state.isVisible}
appear={true}
unmountOnExit={true}
onExited={this.props.onRemove}
>
{(state) => (
<div
className={`itwin-toast-all itwin-toast-${state}`}
style={{
height: this.state.height,
marginBottom: this.state.isVisible ? "0" : -this.state.height,
}}
>
<div ref={this.onRef} style={{ padding: "0px 16px 16px 16px" }}>
<div className={`itwin-toast-${category}`}>
<div className="status-icon-container">
<div className={"status-icon-background"}>
{this.getCategoryIcon()}
</div>
</div>
<div className="message">{text}</div>
{link && (
<div className="link">
{typeof link.url === "string" ? (
<a
href={link.url}
target="_blank"
rel="noopener noreferrer"
>
{link.title}
</a>
) : (
<a onClick={link.url}>{link.title}</a>
)}
</div>
)}
{(type === "persisting" ||
(type === "temporary" && hasCloseButton)) && (
<div className="close-icon-container">
<Close className="close-icon" onClick={this.close} />
</div>
)}
</div>
</div>
</div>
)}
</Transition>
);
}
Example #8
Source File: SlideFadeTransition.tsx From firecms with MIT License | 4 votes |
SlideFade = React.forwardRef(function SlideFade(props: SlideProps, ref) {
const {
children,
in: inProp,
timeout,
onExitAnimation,
...other
} = props;
const theme: any = useTheme();
const childrenRef = React.useRef<any>(null);
const handleRefIntermediary = useForkRef(children.ref, childrenRef);
const handleRef = useForkRef(handleRefIntermediary, ref);
const normalizedTransitionCallback = (callback: any) => (isAppearing: boolean) => {
if (callback) {
// onEnterXxx and onExitXxx callbacks have a different arguments.length value.
if (isAppearing === undefined) {
callback(childrenRef.current);
} else {
callback(childrenRef.current, isAppearing);
}
}
};
const handleEnter = normalizedTransitionCallback((node: any) => {
setTranslateValue(node);
reflow(node);
});
const handleEntering = normalizedTransitionCallback((node: any) => {
const transitionProps = getTransitionProps(
{ timeout },
{
mode: "enter"
}
);
node.style.webkitTransition = theme.transitions.create("-webkit-transform", {
...transitionProps,
easing: theme.transitions.easing.easeOut
});
node.style.transition = theme.transitions.create("transform", {
...transitionProps,
easing: theme.transitions.easing.easeOut
});
node.style.webkitTransform = "none";
node.style.transform = "none";
node.style.opacity = 1;
});
const handleExit: any = normalizedTransitionCallback((node: any) => {
const transitionProps = getTransitionProps(
{ timeout },
{
mode: "exit"
}
);
node.style.opacity = 0.5;
node.style.webkitTransition = theme.transitions.create(["-webkit-transform", "opacity"], {
...transitionProps,
easing: theme.transitions.easing.sharp
});
node.style.transition = theme.transitions.create(["transform", "opacity"], {
...transitionProps,
easing: theme.transitions.easing.sharp
});
setTranslateValue(node);
});
const handleExited: any = normalizedTransitionCallback((node: any) => {
// No need for transitions when the component is hidden
node.style.webkitTransition = "";
node.style.transition = "";
});
const updatePosition = React.useCallback(() => {
if (childrenRef.current) {
setTranslateValue(childrenRef.current);
}
}, []);
React.useEffect(() => {
// Skip configuration where the position is screen size invariant.
if (inProp) {
return undefined;
}
const handleResize = debounce(() => {
if (childrenRef.current) {
setTranslateValue(childrenRef.current);
}
});
const containerWindow = ownerWindow(childrenRef.current);
containerWindow.addEventListener("resize", handleResize);
return () => {
handleResize.clear();
containerWindow.removeEventListener("resize", handleResize);
};
}, [inProp]);
React.useEffect(() => {
if (!inProp) {
// We need to update the position of the drawer when the direction change and
// when it's hidden.d
updatePosition();
}
}, [inProp, updatePosition]);
return (
<Transition
nodeRef={childrenRef}
onEnter={handleEnter}
onEntering={handleEntering}
onExit={handleExit}
onExited={handleExited}
appear={true}
in={inProp}
timeout={timeout}
{...other}
>
{((state: any, childProps: any) => {
return React.cloneElement(children, {
ref: handleRef,
style: {
visibility: state === "exited" && !inProp ? "hidden" : undefined,
...children.props.style
},
...childProps
});
}) as any}
</Transition>
);
})
Example #9
Source File: FileGallery.tsx From abrechnung with GNU Affero General Public License v3.0 | 4 votes |
export default function FileGallery({ transaction }) {
const [files, setFiles] = useState([]); // map of file id to object
const [active, setActive] = useState(0);
const setTransactions = useSetRecoilState(groupTransactions(transaction.group_id));
const [showUploadDialog, setShowUploadDialog] = useState(false);
const [showImage, setShowImage] = useState(false);
useEffect(() => {
const newFileIDs = new Set(transaction.files.map((file) => file.id));
const filteredFiles = files.reduce((map, file) => {
map[file.id] = file;
return map;
}, {});
for (const loadedFile of files) {
if (!newFileIDs.has(loadedFile.id)) {
URL.revokeObjectURL(loadedFile.objectUrl); // clean up memory
delete filteredFiles[loadedFile.id];
}
}
setFiles(Object.values(filteredFiles)); // TODO: maybe include placeholders
setActive(Math.max(0, Math.min(active, transaction.files.length - 1)));
const newFiles = transaction.files.filter((file) => !filteredFiles.hasOwnProperty(file.id));
Promise.all(
newFiles.map((newFile) => {
return fetchFile({
fileID: newFile.id,
blobID: newFile.blob_id,
}).then((resp) => {
const objectUrl = URL.createObjectURL(resp.data);
return {
...newFile,
objectUrl: objectUrl,
};
});
})
)
.then((newlyLoadedFiles) => {
setFiles([...Object.values(filteredFiles), ...newlyLoadedFiles]);
})
.catch((err) => {
toast.error(`Error loading file: ${err}`);
});
}, [transaction]);
const toNextImage = () => {
if (active < files.length - 1) {
setActive(active + 1);
}
};
const toPrevImage = () => {
if (active > 0) {
setActive(active - 1);
}
};
const doShowImage = (img) => {
setShowImage(true);
};
const deleteSelectedFile = () => {
if (active < files.length) {
// sanity check, should not be needed
deleteFile({ fileID: files[active].id })
.then((t) => {
updateTransactionInState(t, setTransactions);
setShowImage(false);
})
.catch((err) => {
toast.error(`Error deleting file: ${err}`);
});
}
};
// @ts-ignore
return (
<>
<Grid
container
justifyContent="center"
alignItems="center"
style={{
position: "relative",
height: "200px",
width: "100%",
}}
>
{files.length === 0 ? (
<img height="100%" src={placeholderImg} alt="placeholder" />
) : (
files.map((item, idx) => (
<Transition key={item.id} in={active === idx} timeout={duration}>
{(state) => (
<img
height="100%"
style={{
...defaultStyle,
...transitionStyles[state],
}}
onClick={() => doShowImage(item)}
src={item.objectUrl}
srcSet={item.objectUrl}
alt={item.filename.split(".")[0]}
loading="lazy"
/>
)}
</Transition>
))
)}
<Chip
sx={{ position: "absolute", top: "5px", right: "10px" }}
size="small"
label={`${Math.min(files.length, active + 1)} / ${files.length}`}
/>
{active > 0 && (
<IconButton onClick={toPrevImage} sx={{ position: "absolute", top: "40%", left: "10px" }}>
<ChevronLeft />
</IconButton>
)}
{active < files.length - 1 && (
<IconButton onClick={toNextImage} sx={{ position: "absolute", top: "40%", right: "10px" }}>
<ChevronRight />
</IconButton>
)}
{transaction.is_wip && (
<>
<IconButton
color="primary"
sx={{
position: "absolute",
top: "80%",
right: "10px",
}}
onClick={() => setShowUploadDialog(true)}
>
<AddCircle fontSize="large" />
</IconButton>
<ImageUploadDialog
transaction={transaction}
show={showUploadDialog}
onClose={() => setShowUploadDialog(false)}
/>
</>
)}
</Grid>
<Dialog open={showImage} onClose={() => setShowImage(false)} scroll="body">
{active < files.length && <DialogTitle>{files[active].filename.split(".")[0]}</DialogTitle>}
<DialogContent>
<Grid
container
justifyContent="center"
alignItems="center"
style={{
position: "relative",
}}
>
{active < files.length && (
<img
height="100%"
width="100%"
src={files[active]?.objectUrl}
srcSet={files[active]?.objectUrl}
alt={files[active]?.filename}
loading="lazy"
/>
)}
{active > 0 && (
<IconButton
onClick={toPrevImage}
sx={{
position: "absolute",
top: "40%",
left: "0px",
}}
>
<ChevronLeft />
</IconButton>
)}
{active < files.length - 1 && (
<IconButton
onClick={toNextImage}
sx={{
position: "absolute",
top: "40%",
right: "0px",
}}
>
<ChevronRight />
</IconButton>
)}
</Grid>
</DialogContent>
{transaction.is_wip && (
<DialogActions>
<Button startIcon={<Delete />} onClick={deleteSelectedFile} variant="outlined" color="error">
Delete
</Button>
</DialogActions>
)}
</Dialog>
</>
);
}
Example #10
Source File: index.tsx From midway with MIT License | 4 votes |
Layout = ({ children, location, pageContext }: { children: any, location: { pathname: string }, pageContext: { site?: {}, layout: string }}) => {
const { site } = pageContext
// Render documentation for CMS minus header/footer experience
if (pageContext.layout === 'docs') {
return (
<div>
{children}
</div>
)
}
if (pageContext.layout === 'accounts') {
return (
<React.Fragment>
<Helmet title='Accounts' />
<Header />
<div>{children}</div>
<Footer {...site} />
</React.Fragment>
)
}
useEffect(() => {
tighpo('spaghetti', function () {
const style = document.createElement('style')
document.body.appendChild(style)
style.sheet.insertRule('html, body { cursor: url(https://spaghet.now.sh), auto !important; }')
})
}, [0])
return (
<React.Fragment>
<Helmet title='Midway'>
<link href='https://fonts.googleapis.com/css2?family=Space+Mono:wght@400;700&display=swap' rel='stylesheet' />
</Helmet>
<Analytics
googleAnalyticsPropertyId={process.env.GATSBY_GA_ID} />
<PasswordWrapper>
<div>
<a
name='maincontent'
className='pf top left z10 skip'
href='#maincontent'
>
Skip to main content
</a>
<Header />
<CartDrawer />
{/*
Smooth transition credits to Ian Williams: https://github.com/dictions
*/}
{!/account/.test(location.pathname) ? (
<SwitchTransition>
<Transition
key={location.pathname}
mountOnEnter={true}
unmountOnExit={true}
appear={true}
timeout={TRANSITION_DURATION}>
{status => (
<main
className='site'
id='maincontent'
style={{
...TRANSITION_STYLES.default,
...TRANSITION_STYLES[status],
}}>
{children}
<Footer {...site} />
</main>
)}
</Transition>
</SwitchTransition>
) : (
<div>
{children}
<Footer {...site} />
</div>
)}
</div>
</PasswordWrapper>
</React.Fragment>
)
}
Example #11
Source File: NotificationsProvider.tsx From mantine with MIT License | 4 votes |
export function NotificationsProvider({
className,
position = 'bottom-right',
autoClose = 4000,
transitionDuration = 250,
containerWidth = 440,
notificationMaxHeight = 200,
limit = 5,
zIndex = getDefaultZIndex('overlay'),
style,
children,
...others
}: NotificationProviderProps) {
const forceUpdate = useForceUpdate();
const refs = useRef<Record<string, HTMLDivElement>>({});
const previousLength = useRef<number>(0);
const {
notifications,
queue,
showNotification,
updateNotification,
hideNotification,
clean,
cleanQueue,
} = useNotificationsState({ limit });
const reduceMotion = useReducedMotion();
const duration = reduceMotion ? 1 : transitionDuration;
const { classes, cx, theme } = useStyles();
const positioning = (POSITIONS.includes(position) ? position : 'bottom-right').split(
'-'
) as NotificationsProviderPositioning;
const ctx = {
notifications,
queue,
showNotification,
hideNotification,
updateNotification,
clean,
cleanQueue,
};
useDidUpdate(() => {
if (notifications.length > previousLength.current) {
setTimeout(() => forceUpdate(), 0);
}
previousLength.current = notifications.length;
}, [notifications]);
useNotificationsEvents(ctx);
const items = notifications.map((notification) => (
<Transition
key={notification.id}
timeout={duration}
onEnter={() => refs.current[notification.id].offsetHeight}
nodeRef={{ current: refs.current[notification.id] }}
>
{(state) => (
<NotificationContainer
innerRef={(node) => {
refs.current[notification.id] = node;
}}
notification={notification}
onHide={hideNotification}
className={classes.notification}
autoClose={autoClose}
sx={[
{
...getNotificationStateStyles({
state,
positioning,
transitionDuration: duration,
maxHeight: notificationMaxHeight,
}),
},
...(Array.isArray(notification.sx) ? notification.sx : [notification.sx]),
]}
/>
)}
</Transition>
));
return (
<NotificationsContext.Provider value={ctx}>
<Portal zIndex={zIndex}>
<Box
className={cx(classes.notifications, className)}
style={style}
sx={{
maxWidth: containerWidth,
...getPositionStyles(positioning, containerWidth, theme.spacing.md),
}}
{...others}
>
<TransitionGroup>{items}</TransitionGroup>
</Box>
</Portal>
{children}
</NotificationsContext.Provider>
);
}