1761 objects settings add a cover image (#2096)
* add image * overflow hidden * add close button * add animation to cover image * use cookie to store user preference * refactor to have a reusable component called AnimatedFadeOut * corrected close button position * modified according to comments
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 119 KiB |
@ -0,0 +1,58 @@
|
||||
import { useState } from 'react';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
import { IconX } from '@/ui/display/icon';
|
||||
import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
|
||||
import { AnimatedFadeOut } from '@/ui/utilities/animation/components/AnimatedFadeOut';
|
||||
import { cookieStorage } from '~/utils/cookie-storage';
|
||||
|
||||
import CoverImage from '../assets/build-your-business-logic.jpg';
|
||||
|
||||
const StyledCoverImageContainer = styled.div`
|
||||
border: 1px solid ${({ theme }) => theme.border.color.medium};
|
||||
border-radius: ${({ theme }) => theme.border.radius.md};
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const StyledCoverImage = styled.img`
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const StyledLighIconButton = styled(LightIconButton)`
|
||||
position: absolute;
|
||||
right: ${({ theme }) => theme.spacing(1)};
|
||||
top: ${({ theme }) => theme.spacing(1)};
|
||||
`;
|
||||
|
||||
export const SettingsObjectCoverImage = () => {
|
||||
const theme = useTheme();
|
||||
|
||||
const [cookieState, setCookieState] = useState(
|
||||
cookieStorage.getItem('settings-object-cover-image'),
|
||||
);
|
||||
|
||||
return (
|
||||
<AnimatedFadeOut
|
||||
isOpen={cookieState !== 'closed'}
|
||||
marginBottom={theme.spacing(8)}
|
||||
>
|
||||
<StyledCoverImageContainer>
|
||||
<StyledCoverImage src={CoverImage} alt="Build your business logic" />
|
||||
<StyledLighIconButton
|
||||
Icon={IconX}
|
||||
accent="tertiary"
|
||||
size="small"
|
||||
onClick={() => {
|
||||
cookieStorage.setItem('settings-object-cover-image', 'closed');
|
||||
setCookieState('closed');
|
||||
}}
|
||||
/>
|
||||
</StyledCoverImageContainer>
|
||||
</AnimatedFadeOut>
|
||||
);
|
||||
};
|
||||
@ -5,3 +5,5 @@ export const animation = {
|
||||
normal: 0.3,
|
||||
},
|
||||
};
|
||||
|
||||
export type AnimationDuration = 'instant' | 'fast' | 'normal';
|
||||
|
||||
@ -1,19 +1,26 @@
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { motion } from 'framer-motion';
|
||||
|
||||
import { AnimationDuration } from '@/ui/theme/constants/animation';
|
||||
|
||||
type AnimatedEaseInProps = Omit<
|
||||
React.ComponentProps<typeof motion.div>,
|
||||
'initial' | 'animated' | 'transition'
|
||||
> & {
|
||||
duration?: number;
|
||||
duration?: AnimationDuration;
|
||||
};
|
||||
|
||||
export const AnimatedEaseIn = ({
|
||||
children,
|
||||
duration = 0.3,
|
||||
duration = 'normal',
|
||||
}: AnimatedEaseInProps) => {
|
||||
const theme = useTheme();
|
||||
const initial = { opacity: 0 };
|
||||
const animate = { opacity: 1 };
|
||||
const transition = { ease: 'linear', duration };
|
||||
const transition = {
|
||||
ease: 'linear',
|
||||
duration: theme.animation.duration[duration],
|
||||
};
|
||||
|
||||
return (
|
||||
<motion.div initial={initial} animate={animate} transition={transition}>
|
||||
|
||||
@ -0,0 +1,42 @@
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { AnimatePresence, motion } from 'framer-motion';
|
||||
|
||||
import { AnimationDuration } from '@/ui/theme/constants/animation';
|
||||
|
||||
type AnimatedFadeOutProps = {
|
||||
isOpen: boolean;
|
||||
children: React.ReactNode;
|
||||
duration?: AnimationDuration;
|
||||
marginBottom?: string;
|
||||
marginTop?: string;
|
||||
};
|
||||
|
||||
export const AnimatedFadeOut = ({
|
||||
isOpen,
|
||||
children,
|
||||
duration = 'normal',
|
||||
marginBottom,
|
||||
marginTop,
|
||||
}: AnimatedFadeOutProps) => {
|
||||
const theme = useTheme();
|
||||
return (
|
||||
<AnimatePresence>
|
||||
{isOpen && (
|
||||
<motion.div
|
||||
initial={{
|
||||
opacity: 1,
|
||||
marginBottom: marginBottom ?? 0,
|
||||
marginTop: marginTop ?? 0,
|
||||
}}
|
||||
exit={{ opacity: 0, height: 0, marginBottom: 0, marginTop: 0 }}
|
||||
transition={{
|
||||
duration: theme.animation.duration[duration],
|
||||
ease: 'easeOut',
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user