diff options
| author | Oliver <oliver@mohlin.dev> | 2025-10-03 11:42:52 +0200 |
|---|---|---|
| committer | Tobias Järvelöv <tobias.jarvelov@mullvad.net> | 2025-10-10 13:38:06 +0200 |
| commit | 4a6afb7d70208107e95bf1385e9a4ccdeee5d86d (patch) | |
| tree | abd7ee5fc275fef194dc8f868948d95f28d4981e | |
| parent | c6602aa241b5a0f0833fbc05415228b0272a6eb4 (diff) | |
| download | mullvadvpn-4a6afb7d70208107e95bf1385e9a4ccdeee5d86d.tar.xz mullvadvpn-4a6afb7d70208107e95bf1385e9a4ccdeee5d86d.zip | |
Add AnimatedList component
5 files changed, 56 insertions, 0 deletions
diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/components/animated-list/AnimatedList.tsx b/desktop/packages/mullvad-vpn/src/renderer/lib/components/animated-list/AnimatedList.tsx new file mode 100644 index 0000000000..445378d93b --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/lib/components/animated-list/AnimatedList.tsx @@ -0,0 +1,25 @@ +import { AnimatePresence } from 'motion/react'; +import React from 'react'; +import styled from 'styled-components'; + +import { AnimatedListItem } from './components'; + +export type AnimatedListProps = React.ComponentPropsWithRef<'ul'>; + +const StyledUl = styled.ul` + width: 100%; +`; + +function AnimatedList({ children, ...props }: AnimatedListProps) { + return ( + <StyledUl {...props}> + <AnimatePresence initial={false}>{children}</AnimatePresence> + </StyledUl> + ); +} + +const AnimatedListNamespace = Object.assign(AnimatedList, { + Item: AnimatedListItem, +}); + +export { AnimatedListNamespace as AnimatedList }; diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/components/animated-list/components/animated-list-item/AnimatedListItem.tsx b/desktop/packages/mullvad-vpn/src/renderer/lib/components/animated-list/components/animated-list-item/AnimatedListItem.tsx new file mode 100644 index 0000000000..2836d5b558 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/lib/components/animated-list/components/animated-list-item/AnimatedListItem.tsx @@ -0,0 +1,28 @@ +import { motion } from 'motion/react'; +import styled from 'styled-components'; + +export type AnimatedListItemProps = React.ComponentPropsWithRef<'li'>; + +const StyledLi = styled(motion.li)` + overflow: hidden; +`; + +const itemVariants = { + hidden: { height: 0 }, + show: { height: 'auto' }, + exit: { height: 0 }, +}; + +export function AnimatedListItem({ children }: AnimatedListItemProps) { + return ( + <StyledLi + layout + variants={itemVariants} + initial="hidden" + animate="show" + exit="exit" + transition={{ duration: 0.1, ease: 'easeOut' }}> + {children} + </StyledLi> + ); +} diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/components/animated-list/components/animated-list-item/index.ts b/desktop/packages/mullvad-vpn/src/renderer/lib/components/animated-list/components/animated-list-item/index.ts new file mode 100644 index 0000000000..cdb2575bb2 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/lib/components/animated-list/components/animated-list-item/index.ts @@ -0,0 +1 @@ +export * from './AnimatedListItem'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/components/animated-list/components/index.ts b/desktop/packages/mullvad-vpn/src/renderer/lib/components/animated-list/components/index.ts new file mode 100644 index 0000000000..b520a7745f --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/lib/components/animated-list/components/index.ts @@ -0,0 +1 @@ +export * from './animated-list-item'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/components/animated-list/index.ts b/desktop/packages/mullvad-vpn/src/renderer/lib/components/animated-list/index.ts new file mode 100644 index 0000000000..b1b031e8a7 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/lib/components/animated-list/index.ts @@ -0,0 +1 @@ +export * from './AnimatedList'; |
