framer-motion#AnimateSharedLayout TypeScript Examples
The following examples show how to use
framer-motion#AnimateSharedLayout.
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: projects.tsx From portfolio with MIT License | 6 votes |
Projects: React.FC<ProjectsProps> = ({ projects }) => {
return (
<VStack align="start" spacing={8}>
<Header underlineColor={ORANGE} mt={0} mb={0}>
Projects
</Header>
<AnimateSharedLayout>
<SimpleGrid columns={1} spacing={4} mt={5} w="100%">
{projects.map((project, index) => (
<MotionBox whileHover={{ y: -5 }} key={index}>
<ProjectCard
key={project.id}
title={project.title}
description={project.desc}
blurHash={project.blurHash}
logo={project.logo}
link={project.link}
technologies={project.technologies}
/>
</MotionBox>
))}
</SimpleGrid>
</AnimateSharedLayout>
</VStack>
);
}
Example #2
Source File: _app.tsx From rcvr-app with GNU Affero General Public License v3.0 | 6 votes |
RecoverApp: RecoverAppFC = ({
Component,
pageProps: { localeContext, ...pageProps },
}) => {
useA11yFocusRing()
return (
<ThemeProvider theme={theme}>
<QueryClientProvider client={queryClient}>
<LocalesContextProvider value={localeContext}>
<Global styles={globalStyles} />
<AnimateSharedLayout>
<SupportedBrowsersAlert />
<Component {...pageProps} />
</AnimateSharedLayout>
</LocalesContextProvider>
</QueryClientProvider>
</ThemeProvider>
)
}
Example #3
Source File: segmentedcontrol.tsx From samuelkraft-next with MIT License | 6 votes |
SegmentedControl = ({ items }: SegmentedControlProps): JSX.Element => {
const [activeItem, setActiveitem] = useState(0)
return (
<AnimateSharedLayout>
<ol className={styles.list}>
{items.map((item, i) => {
const isActive = i === activeItem
return (
<motion.li
className={isActive || i === activeItem - 1 ? styles.itemNoDivider : styles.item}
whileTap={isActive ? { scale: 0.95 } : { opacity: 0.6 }}
key={item}
>
<button onClick={() => setActiveitem(i)} type="button" className={styles.button}>
{isActive && <motion.div layoutId="SegmentedControlActive" className={styles.active} />}
<span className={styles.label}>{item}</span>
</button>
</motion.li>
)
})}
</ol>
</AnimateSharedLayout>
)
}
Example #4
Source File: SidebarOverlay.tsx From meshtastic-web with GNU General Public License v3.0 | 5 votes |
SidebarOverlay = ({
title,
open,
close,
direction,
children,
}: SidebarOverlayProps): JSX.Element => {
return (
<AnimatePresence>
{open && (
<m.div
className="absolute z-30 flex h-full w-full flex-col bg-white dark:bg-primaryDark"
animate={direction === 'x' ? { translateX: 0 } : { translateY: 0 }}
initial={
direction === 'x' ? { translateX: '-100%' } : { translateY: '100%' }
}
exit={
direction === 'x' ? { translateX: '-100%' } : { translateY: '100%' }
}
transition={{ type: 'just' }}
>
{/* @ts-expect-error */}
<AnimateSharedLayout>
{/* <div className="flex gap-2 border-b border-gray-400 p-2 dark:border-gray-600"> */}
<div className="bg-white px-1 pt-1 drop-shadow-md dark:bg-primaryDark">
<div className="flex h-10 gap-1">
<div className="my-auto">
<IconButton
onClick={(): void => {
close();
}}
icon={<FiArrowLeft />}
/>
</div>
<div className="my-auto text-lg font-medium dark:text-white">
{title}
</div>
</div>
</div>
<div className="flex-grow overflow-y-auto">{children}</div>
</AnimateSharedLayout>
</m.div>
)}
</AnimatePresence>
);
}
Example #5
Source File: themechanger.tsx From samuelkraft-next with MIT License | 5 votes |
ThemeChanger = (): JSX.Element => {
const [mounted, setMounted] = useState(false)
const [active, setActive] = useState(false)
const [hovered, setHovered] = useState('')
const { setTheme, theme } = useTheme()
// When mounted on client, now we can show the UI
useEffect(() => setMounted(true), [])
if (!mounted) return <div className={styles.wrapper} /> // skeleton on server
return (
<AnimateSharedLayout>
<div className={styles.wrapper}>
<motion.div layout className={styles.menu}>
<AnimatePresence initial={false}>
{active && (
<motion.div
layout
initial={{ borderRadius: 26, opacity: 0, scale: 0.9 }}
exit={{ opacity: 0, scale: 0.9 }}
animate={{ opacity: 1, scale: 1 }}
className={styles.bg}
/>
)}
{variants.map(variant => {
const selected = theme === variant
const isHovered = hovered === variant
return (
<Fragment key={variant}>
{(selected || active) && (
<motion.button
onHoverStart={() => setHovered(variant)}
layout
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.85 }}
initial={{ opacity: 0, scale: 0.85 }}
type="button"
title={variant}
key={variant}
className={styles.button}
onClick={() => {
if (!active) {
return setActive(true)
}
setActive(false)
return setTheme(variant)
}}
>
{((!active && selected) || isHovered) && (
<motion.span layoutId="buttonBackground" className={styles.buttonBackground} />
)}
<span className={styles.buttonLabel}>{getIcon(variant)}</span>
</motion.button>
)}
</Fragment>
)
})}
</AnimatePresence>
</motion.div>
</div>
</AnimateSharedLayout>
)
}
Example #6
Source File: notes-list.tsx From notebook with MIT License | 4 votes |
NotesList: React.SFC<NotesListProps> = ({
notes,
handleClick,
setNotes
}) => {
const bg = useColorModeValue("white", "#2f3244");
const [selectedNote, setSelectedNote] = React.useState<note>();
const toast = useToast();
const { isOpen, onOpen, onClose } = useDisclosure();
const onDelete = (
id: string,
e: React.MouseEvent<SVGElement, MouseEvent>
) => {
const newNotes: note[] = notes.filter((note: note) => note.id !== id);
setNotes(newNotes);
showToast();
e.stopPropagation();
};
const onClick = (id: string, e: React.MouseEvent<SVGElement, MouseEvent>) => {
handleClick(id);
e.stopPropagation();
};
const handleSelectedNote = (note: note) => {
setSelectedNote(note);
onOpen();
};
const showToast = () => {
toast({
title: "Note deleted.",
status: "success",
position: "top",
duration: 2000,
isClosable: true
});
};
return (
<>
<AnimateSharedLayout type="crossfade">
<Box minH={"50vh"}>
{/* <SimpleGrid
columns={[1, 2, 2, 3]}
mt="40px"
gridGap="10px"
position="relative"
overflow="hidden"
> */}
<StackGrid columnWidth={330}>
{notes.map(note => (
<Fade in={true}>
<motion.div
whileHover={{ y: -10 }}
layoutId={note.id}
onClick={() => handleSelectedNote(note)}
>
<Center py={2} px={2} key={note.id}>
<Box
maxH={"400px"}
w="100%"
boxShadow={"lg"}
rounded={"md"}
p={6}
overflow={"hidden"}
cursor="pointer"
_hover={{ boxShadow: "xl" }}
bg={bg}
role="group"
// onClick={() => handleClick(note.id, true)}
>
<Stack>
<Flex
_groupHover={{ justifyContent: "space-between" }}
justifyContent="center"
align="center"
>
<Box>
<Text
color={"green.500"}
textTransform={"uppercase"}
fontWeight={800}
fontSize={"sm"}
letterSpacing={1.1}
>
Note
</Text>
</Box>
<Box
_groupHover={{ display: "block" }}
display="none"
>
<HStack spacing="2">
<Icon
color={"green.500"}
_hover={{ color: "green.600" }}
_groupHover={{ display: "block" }}
as={EditIcon}
w={4}
h={4}
onClick={e => onClick(note.id, e)}
/>
<Icon
color={"green.500"}
_hover={{ color: "#ca364a" }}
_groupHover={{ display: "block" }}
as={DeleteIcon}
w={4}
h={4}
onClick={e => onDelete(note.id, e)}
/>
</HStack>
</Box>
</Flex>
<Heading
fontSize={"xl"}
fontFamily={"body"}
textTransform="capitalize"
noOfLines={2}
>
{note.title}
</Heading>
<Text
color={"gray.500"}
fontSize="md"
noOfLines={{ base: 3, md: 4 }}
>
{note.body}
</Text>
</Stack>
</Box>
</Center>
</motion.div>
</Fade>
))}
</StackGrid>
{/* </SimpleGrid> */}
</Box>
{isOpen ? (
<NoteModal
isOpen={isOpen}
onClose={onClose}
selectedNote={selectedNote}
/>
) : (
""
)}
</AnimateSharedLayout>
</>
);
}
Example #7
Source File: Checkers.tsx From dnd-kit with MIT License | 4 votes |
export function Checkers() {
const [board] = useState(generateBoard);
const [pieces, setPieces] = useState(() => generatePieces(board));
const [movingPiece, setMovingPiece] = useState<PieceProps | null>(null);
const [isOddTurn, setIsOddTurn] = useState(true);
const [oddScore, setOddScore] = useState(0);
const [evenScore, setEvenScore] = useState(0);
const {evenWon, oddWon} = useMemo(() => checkEnd(pieces), [pieces]);
const checkCanMove = useCallback(
function (
isOddTurn: boolean,
isOddPiece: boolean,
movingPiece: PieceProps,
moveToX: number,
moveToY: number
): CanMoveProps {
if (movingPiece.position) {
const {x: moveFromX, y: moveFromY} = movingPiece.position;
const dx = moveToX - moveFromX;
const dy = moveToY - moveFromY;
if (isOddTurn && isOddPiece) {
if (dy < 0) {
return {canMove: false};
}
if (Math.abs(dx) === 2 && Math.abs(dy) === 2) {
const potentialEnemyPieceCoordinates = {
x: moveFromX + dx / 2,
y: moveFromY + dy / 2,
};
const potentialEnemyPiece =
pieces[potentialEnemyPieceCoordinates.y][
potentialEnemyPieceCoordinates.x
];
if (potentialEnemyPiece == null || potentialEnemyPiece.odd) {
return {canMove: false};
} else {
return {canMove: true, toRemove: potentialEnemyPiece};
}
}
const canMove =
(dy === 1 || dy === 2) && Math.abs(dx) === Math.abs(dy);
return {canMove};
} else if (!isOddTurn && !isOddPiece) {
if (dy > 0) {
return {canMove: false};
}
if (Math.abs(dx) === 2 && Math.abs(dy) === 2) {
const potentialEnemyPieceCoordinates = {
x: moveFromX + dx / 2,
y: moveFromY + dy / 2,
};
const potentialEnemyPiece =
pieces[potentialEnemyPieceCoordinates.y][
potentialEnemyPieceCoordinates.x
];
if (potentialEnemyPiece == null || !potentialEnemyPiece.odd) {
return {canMove: false};
} else {
return {canMove: true, toRemove: potentialEnemyPiece};
}
}
const canMove =
(dy === -1 || dy === -2) && Math.abs(dx) === Math.abs(dy);
return {canMove};
}
}
return {canMove: false};
},
[pieces]
);
const handleDragCancel = useCallback(() => {
setMovingPiece(null);
}, []);
const handleDragEnd = useCallback(
function handleDragEnd(event: DragEndEvent) {
if (!movingPiece?.position || !event.over?.id) {
return;
}
const {x: movingPieceX, y: movingPieceY} = movingPiece.position;
const [cellY, cellX] = event.over.id.toString().split('-').map(Number);
const potentialExistingPiece = pieces[cellY][cellX];
setMovingPiece(null);
if (event.over && !potentialExistingPiece) {
const {canMove, toRemove} = checkCanMove(
isOddTurn,
movingPiece.odd,
movingPiece,
cellX,
cellY
);
if (!canMove) {
return;
}
const newPiece: PieceProps = {
...movingPiece,
position: {x: cellX, y: cellY},
};
// Clone pieces
const newPieces = pieces.map((row) => row.slice());
// Place new
delete newPieces[movingPieceY][movingPieceX];
newPieces[cellY][cellX] = newPiece;
// Remove enemy
if (toRemove?.position) {
delete newPieces[toRemove.position?.y][toRemove.position?.x];
if (toRemove.odd) {
setEvenScore((score) => score + 1);
} else {
setOddScore((score) => score + 1);
}
}
setPieces(newPieces);
setIsOddTurn((turn) => !turn);
}
},
[movingPiece, pieces, checkCanMove, isOddTurn]
);
const handleDragStart = useCallback(
function handleDragStart({active}: DragStartEvent) {
const piece = pieces.reduce<PieceProps | undefined>((acc, row) => {
return acc ?? row.find((cell) => cell?.id === active.id);
}, undefined);
if (piece) {
setMovingPiece(piece);
}
},
[pieces]
);
const players = ['Blue', 'Black'];
const gameEnded = evenWon || oddWon;
return (
<AnimateSharedLayout type="crossfade">
<DndContext
onDragStart={handleDragStart}
onDragEnd={handleDragEnd}
onDragCancel={handleDragCancel}
>
<div className={styles.Checkers}>
{gameEnded ? (
<Endgame
winnerLabel={oddWon ? players[1] : players[0]}
winnerScore={oddWon ? oddScore : evenScore}
onPlayAgain={handleRestart}
/>
) : (
<Score
oddLabel={players[0]}
evenLabel={players[1]}
oddScore={oddScore}
evenScore={evenScore}
oddTurn={isOddTurn}
/>
)}
<Board size={BOARD_SIZE}>
{board.map((row, y) =>
row.map((rowCase, x) => {
const piece = pieces[y][x];
const disabled =
(piece?.odd && !isOddTurn) || (!piece?.odd && isOddTurn);
if (!piece) {
const canDrop = movingPiece
? checkCanMove(
isOddTurn,
movingPiece.odd,
movingPiece,
x,
y
).canMove
: false;
return (
<Cell
key={rowCase.id}
validDropLocation={canDrop}
{...rowCase}
/>
);
}
const pieceMarkup = disabled ? (
<Piece {...piece} disabled />
) : (
<DraggablePiece {...piece} />
);
return (
<Cell key={rowCase.id} {...rowCase}>
{pieceMarkup}
</Cell>
);
})
)}
</Board>
</div>
<DragOverlay dropAnimation={null}>
{movingPiece == null ? null : (
<Piece odd={movingPiece.odd} clone id={movingPiece.id} />
)}
</DragOverlay>
</DndContext>
</AnimateSharedLayout>
);
function handleRestart() {
setPieces(generatePieces(board));
setOddScore(0);
setEvenScore(0);
}
}