framer-motion#AnimatePresence TypeScript Examples
The following examples show how to use
framer-motion#AnimatePresence.
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: motion.tsx From notebook with MIT License | 6 votes |
AnimatePage = ({ children }) => {
return (
<AnimatePresence initial={true} exitBeforeEnter>
<MotionBox
as="main"
animate="enter"
exit="exit"
flexGrow={1}
initial="initial"
variants={{
initial: { opacity: 0, y: -200 },
enter: { opacity: 1, y: 0 },
exit: { opacity: 0, y: 250 }
}}
>
{children}
</MotionBox>
</AnimatePresence>
);
}
Example #2
Source File: Demo.tsx From postel with MIT License | 6 votes |
DemoCaret = React.forwardRef((props: DemoCaretProps, ref: any) => {
const motionProps = props.animated && {
initial: { scale: 1, opacity: 0 },
animate: { scale: 1, opacity: 1 },
exit: { scale: 0.8, opacity: 0 },
transition: {
ease: "easeInOut",
duration: 0.1,
},
};
return (
<AnimatePresence>
{!props.isTransitioningOut && (
<div
ref={ref}
style={{
filter: "drop-shadow(rgba(50, 50, 0, 0.5) -1px 16px 6px)",
}}
>
<motion.div
{...motionProps}
style={{
height: 10,
width: 10,
background: props.caretColor,
clipPath: "polygon(100% 0, 0% 100%, 100% 100%)",
}}
></motion.div>
</div>
)}
</AnimatePresence>
);
})
Example #3
Source File: _app.tsx From samuelkraft-next with MIT License | 6 votes |
function MyApp({ Component, pageProps }: AppProps): JSX.Element {
const router = useRouter()
useEffect(() => {
const handleRouteChange = (url: string) => {
gtag.pageview(url)
}
router.events.on('routeChangeComplete', handleRouteChange)
return () => {
router.events.off('routeChangeComplete', handleRouteChange)
}
}, [router.events])
return (
<ThemeProvider defaultTheme="system">
<SEO />
<Head>
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
</Head>
<AnimatePresence initial={false}>
<Component {...pageProps} key={router.route} />
</AnimatePresence>
</ThemeProvider>
)
}
Example #4
Source File: Loading.tsx From rcvr-app with GNU Affero General Public License v3.0 | 6 votes |
Loading: React.FC<Props> = ({ show = false }) => {
const transition = {
ease: 'easeInOut',
yoyo: Infinity,
duration: 0.6,
}
return (
<AnimatePresence>
{show && (
<Overlay
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
css={{ pointerEvents: show ? 'initial' : 'none' }}
>
{[0, 1, 2].map((i) => (
<motion.div
key={i}
animate={{ y: -40 }}
initial={{ y: 40 }}
transition={{ ...transition, delay: i * 0.15 }}
>
<Dot />
</motion.div>
))}
</Overlay>
)}
</AnimatePresence>
)
}
Example #5
Source File: Modal.tsx From Meshtastic with GNU General Public License v3.0 | 6 votes |
Modal = ({ open, onClose, children }: ModalProps): JSX.Element => {
return (
<AnimatePresence initial={false} exitBeforeEnter={true}>
<Dialog
as="div"
className="fixed inset-0 z-10 overflow-y-auto"
open={open}
onClose={onClose}
>
<div className="min-h-screen px-0.5 text-center md:px-4">
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
<Dialog.Overlay className="fixed inset-0 backdrop-blur-md" />
</motion.div>
<span
className="inline-block h-screen align-middle"
aria-hidden="true"
>
​
</span>
<div className="inline-block w-full transform text-left align-middle transition-all 2xl:max-w-7xl">
<div className="group relative">
<div className="animate-tilt absolute -inset-0.5 rotate-2 rounded-lg bg-accent shadow-md transition duration-1000 group-hover:opacity-100 group-hover:duration-200"></div>
<div className="relative flex flex-col overflow-hidden rounded-2xl bg-base shadow-md md:aspect-[2/1] md:flex-row md:bg-primary">
{children}
</div>
</div>
</div>
</div>
</Dialog>
</AnimatePresence>
);
}
Example #6
Source File: back-button.tsx From bitpay-browser-extension with MIT License | 6 votes |
BackButton: React.FC<{ show: boolean; onClick: () => void }> = ({ show, onClick }) => (
<AnimatePresence>
{show && (
<motion.button
key="BackButton"
initial={{ opacity: 0, x: -20 }}
animate={{ opacity: 1, x: 0, y: -1, transition: { duration: 0.1 } }}
exit={{ opacity: 0, x: FrameDimensions.width * -3 }}
className="back-button"
type="button"
onClick={onClick}
>
<img alt="go back" src="../assets/icons/go-back-icon.svg" />
<span className="back-button--text">Back</span>
</motion.button>
)}
</AnimatePresence>
)
Example #7
Source File: note-modal.tsx From notebook with MIT License | 6 votes |
NoteModal: React.SFC<NoteFormProps> = ({
isOpen,
onClose,
selectedNote
}) => {
return (
<AnimatePresence>
<motion.div layoutId={selectedNote?.id}>
<Modal
isOpen={isOpen}
onClose={onClose}
scrollBehavior={"inside"}
isCentered
motionPreset="slideInBottom"
>
<ModalOverlay />
<ModalContent>
<motion.div>
<ModalHeader isTruncated paddingRight="10">
{selectedNote?.title}
</ModalHeader>
</motion.div>
<ModalCloseButton />
<motion.div>
<ModalBody pb={6}>{selectedNote?.body}</ModalBody>
</motion.div>
</ModalContent>
</Modal>
</motion.div>
</AnimatePresence>
);
}
Example #8
Source File: Main.tsx From Intro_to_React with GNU General Public License v2.0 | 6 votes |
Main = () => {
return (
<main>
<AnimatePresence>
<Switch>
<Route path="/:mission_id" component={Detail} />
<Route path="/" component={SpaceX} />
</Switch>
</AnimatePresence>
</main>
)
}
Example #9
Source File: History.tsx From useDApp with MIT License | 6 votes |
TransactionsList = () => {
const { transactions } = useTransactions()
return (
<TableWrapper title="Transactions history">
<AnimatePresence initial={false}>
{transactions.map((transaction) => (
<ListElement
transaction={transaction.transaction}
title={transaction.transactionName}
icon={TransactionIcon(transaction)}
key={transaction.transaction.hash}
date={transaction.submittedAt}
/>
))}
</AnimatePresence>
</TableWrapper>
)
}
Example #10
Source File: index.tsx From gatsby-markdown-typescript-personal-website with MIT License | 6 votes |
Layout: React.FC<Props> = ({ children }) => {
const data = useStaticQuery(graphql`
query SiteTitleQuery {
site {
siteMetadata {
title
}
}
}
`);
return (
<>
<GlobalStyles />
<AnimatePresence exitBeforeEnter>
<Styled.Layout>
<Header siteTitle={data.site.siteMetadata.title} />
<motion.div
initial={{ y: 30, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ delay: 0.2 }}
>
{children}
<Newsletter />
<Footer />
</motion.div>
</Styled.Layout>
</AnimatePresence>
</>
);
}
Example #11
Source File: IconGridItem.tsx From phosphor-home with MIT License | 5 votes |
IconGridItem: React.FC<IconGridItemProps> = (props) => {
const { index, originOffset, entry } = props;
const { name, Icon } = entry;
const [open, setOpen] = useRecoilState(iconPreviewOpenAtom);
const isOpen = open === name;
const isNew = entry.tags.includes("*new*");
const isUpdated = entry.tags.includes("*updated*");
const delayRef = useRef<number>(0);
const offset = useRef({ top: 0, left: 0 });
const ref = useRef<any>();
const handleOpen = () => setOpen(isOpen ? false : name);
// The measurement for all elements happens in the layoutEffect cycle
// This ensures that when we calculate distance in the effect cycle
// all elements have already been measured
useLayoutEffect(() => {
const element = ref.current;
if (!element) return;
offset.current = {
top: element.offsetTop,
left: element.offsetLeft,
};
if (index === originIndex) {
originOffset.current = offset.current;
}
}, [index, originOffset]);
useEffect(() => {
const dx = Math.abs(offset.current.left - originOffset.current.left);
const dy = Math.abs(offset.current.top - originOffset.current.top);
const d = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
delayRef.current = d * delayPerPixel;
}, [originOffset]);
return (
<>
<motion.div
className="grid-item"
key={name}
ref={ref}
tabIndex={0}
style={{
order: index,
backgroundColor: isOpen ? "rgba(163, 159, 171, 0.1)" : undefined,
}}
custom={delayRef}
transition={transition}
variants={itemVariants}
onKeyPress={(e) => e.key === "Enter" && handleOpen()}
onClick={handleOpen}
>
<Icon />
<p>
{name}
{isNew && <span className="badge new">•</span>}
{isUpdated && <span className="badge updated">•</span>}
</p>
</motion.div>
<AnimatePresence initial={false}>
{isOpen && <DetailsPanel {...props} />}
</AnimatePresence>
</>
);
}
Example #12
Source File: FileBrowser.tsx From meshtastic-web with GNU General Public License v3.0 | 5 votes |
FileBrowser = (): JSX.Element => {
const connectionParams = useAppSelector(
(state) => state.app.connectionParams,
);
const appState = useAppSelector((state) => state.app);
const meshtasticState = useAppSelector((state) => state.meshtastic);
const { data } = useSWR<Files>(
`${connectionParams.HTTP.tls ? 'https' : 'http'}://${
connectionParams.HTTP.address
}${
meshtasticState.radio.hardware.firmwareVersion.includes('1.2')
? '/json/spiffs/browse/static'
: '/json/fs/browse/static'
}`,
fetcher,
);
return (
<div className="flex h-full p-4">
<Card
title="File Browser"
actions={<Button icon={<FiFilePlus />}>Upload File</Button>}
className="flex-grow flex-col"
>
<div className="h-full px-4">
<AnimatePresence>
{(!data || data?.data.files.length === 0) && (
<div className="flex h-full w-full">
<m.img
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className="m-auto h-64 w-64 text-green-500"
src={appState.darkMode ? '/Files_Dark.svg' : '/Files.svg'}
/>
</div>
)}
</AnimatePresence>
{data?.data.files.map((file) => (
<div
key={file.name}
className="flex h-10 w-full border-b border-gray-400 px-4 font-medium dark:border-gray-600 dark:text-white"
>
<div className="my-auto w-1/3">
<a
target="_blank"
rel="noopener noreferrer"
href={`${connectionParams.HTTP.tls ? 'https' : 'http'}://${
connectionParams.HTTP.address
}/${file.name.replace('static/', '')}`}
>
{file.name.replace('static/', '').replace('.gz', '')}
</a>
</div>
<div className="my-auto w-1/3"></div>
</div>
))}
</div>
</Card>
</div>
);
}
Example #13
Source File: TransactionForm.tsx From useDApp with MIT License | 5 votes |
StatusAnimation = ({ transaction }: StatusAnimationProps) => {
const [showTransactionStatus, setShowTransactionStatus] = useState(false)
const [timer, setTimer] = useState(
setTimeout(() => {
void 0
}, 1)
)
useEffect(() => {
setShowTransactionStatus(true)
clearTimeout(timer)
if (transaction.status != 'Mining') setTimer(setTimeout(() => setShowTransactionStatus(false), 5000))
}, [transaction])
return (
<AnimationWrapper>
<AnimatePresence initial={false} exitBeforeEnter>
{showTransactionStatus && transactionErrored(transaction) && (
<StatusBlock
color={Colors.Red['400']}
text={transaction?.errorMessage || ''}
icon={<ExclamationIcon />}
key={transaction?.chainId + transaction.status}
/>
)}
{showTransactionStatus && transaction.status === 'Mining' && (
<StatusBlock
color="black"
text="Transaction is being mined"
icon={<SpinnerIcon />}
key={transaction?.chainId + transaction.status}
/>
)}
{showTransactionStatus && transaction.status === 'Success' && (
<StatusBlock
color="green"
text="Transaction successful"
icon={<CheckIcon />}
key={transaction?.chainId + transaction.status}
/>
)}
</AnimatePresence>
</AnimationWrapper>
)
}
Example #14
Source File: Modal.tsx From chroma-react with MIT License | 5 votes |
Modal = React.forwardRef<HTMLDivElement, ModalProps>(
(
{
allowPinchZoom,
isFullScreen,
isOpen,
onDismiss,
disableDismissOnClickOutside,
size = 0,
overlayClassName,
...rootProps
},
ref
) => {
const ownRef = React.useRef(null);
// If a ref is forwarded, use it; otherwise, use ourselves as the ref
const thisRef = ref || ownRef;
return (
<AnimatePresence>
{isOpen ? (
<Overlay
overlayClassName={overlayClassName}
allowPinchZoom={allowPinchZoom}
isOpen={isOpen}
onDismiss={onDismiss}
disableDismissOnClickOutside={disableDismissOnClickOutside}
>
{isFullScreen ? (
<FullScreenContent
ref={thisRef}
size={size}
onDismiss={onDismiss}
{...rootProps}
/>
) : (
<Content
ref={thisRef}
size={size}
onDismiss={onDismiss}
{...rootProps}
/>
)}
</Overlay>
) : null}
</AnimatePresence>
);
}
)
Example #15
Source File: ToastNotification.tsx From website with MIT License | 5 votes |
ToastNotification: React.FC<ToastNotificationProps> = ({
children,
type,
onDidDismiss,
}) => {
const [show, setShow] = useState(true);
const [didDismiss, setDidDismiss] = useState(false);
const backgroundColorClass = getBackgroundColorClass(type);
useEffect(() => {
let timeoutDismiss = null;
let timeoutHide = null;
if (show) {
timeoutHide = setTimeout(() => {
setShow(false);
}, showTime);
} else {
if (!didDismiss)
timeoutDismiss = setTimeout(() => {
setDidDismiss(true);
onDidDismiss();
}, delayByAnimation);
}
return () => {
clearTimeout(timeoutHide);
clearTimeout(timeoutDismiss);
};
}, [show, onDidDismiss, didDismiss]);
return (
<AnimatePresence>
{show && (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className={`fixed top-12 max-w-md w-11/12 rounded-lg overflow-hidden mx-auto inset-x-0 flex justify-center items-center
${backgroundColorClass} text-primary text-sm font-bold px-4 py-3 mt-2`}
role="alert"
onClick={() => setShow(false)}
>
<ToastNotificationIcon type={type} />
{children}
</motion.div>
)}
</AnimatePresence>
);
}
Example #16
Source File: AllActions.tsx From nosgestesclimat-site with MIT License | 5 votes |
List = ({ actions, rules, bilans, actionChoices, focusedAction, focusAction, }) => ( <ul css={` display: flex; justify-content: center; align-items: center; flex-wrap: wrap; list-style-type: none; padding-left: 0; `} > <AnimatePresence> {actions.map((evaluation) => { const cardComponent = ( <motion.li key={evaluation.dottedName} layoutId={evaluation.dottedName} animate={{ scale: 1 }} initial={{ scale: 0.8 }} exit={{ scale: 0.2 }} transition={{ duration: 1 }} css={` width: 11rem; height: 16rem; margin: 0.4rem; @media (min-width: 800px) { width: 12rem; } `} > <ActionListCard focusAction={focusAction} focused={focusedAction === evaluation.dottedName} key={evaluation.dottedName} rule={rules[evaluation.dottedName]} evaluation={evaluation} total={bilans.length ? bilans[0].nodeValue : null} /> </motion.li> ) if (focusedAction === evaluation.dottedName) { const convId = 'conv' return ( <> <motion.li key={convId} layoutId={convId} animate={{ scale: 1 }} initial={{ scale: 0.8 }} exit={{ scale: 0.2 }} transition={{ duration: 0.5 }} css={` margin-top: 1.6rem 1rem 1rem; width: 100%; height: auto; `} > <ActionConversation key={focusedAction} dottedName={focusedAction} /> <ScrollToElement delay={1000} center /> </motion.li> {cardComponent} </> ) } return cardComponent })} </AnimatePresence> </ul> )
Example #17
Source File: ModalBase.tsx From rcvr-app with GNU Affero General Public License v3.0 | 5 votes |
ModalBase: React.FC<ModalBaseProps & Props> = ({
open,
onClose,
children,
maxWidth,
loading,
title,
...rest
}) => {
const ref = React.useRef()
const close = React.useCallback(() => {
if (loading) return
onClose()
}, [loading, onClose])
useClickAway(ref, close)
React.useEffect(() => {
if (open) document.body.classList.add('no-scroll')
if (!open) document.body.classList.remove('no-scroll')
}, [open])
return (
<AnimatePresence>
{open && (
<Overlay
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.2 }}
css={{ pointerEvents: open ? 'initial' : 'none' }}
>
<ModalBox
ref={ref}
{...rest}
css={{ maxWidth }}
initial={{ scale: 1.1 }}
animate={{ scale: 1 }}
exit={{ scale: 0.9 }}
>
<Loading show={loading} />
<CloseButton onClose={close} />
<Box height={4} />
{title && (
<Box px={10}>
<Text variant="h3" textAlign="center">
{title}
</Text>
<Box height={6} />
</Box>
)}
{children}
</ModalBox>
</Overlay>
)}
</AnimatePresence>
)
}
Example #18
Source File: payment.tsx From bitpay-browser-extension with MIT License | 5 votes |
Payment: React.FC<RouteComponentProps & {
user?: BitpayUser;
setEmail: Dispatch<SetStateAction<string>>;
purchasedGiftCards: GiftCard[];
setPurchasedGiftCards: Dispatch<SetStateAction<GiftCard[]>>;
supportedMerchant?: Merchant;
initiallyCollapsed: boolean;
}> = ({
location,
history,
user,
setEmail,
purchasedGiftCards,
setPurchasedGiftCards,
supportedMerchant,
initiallyCollapsed
}) => {
const ref = useRef<HTMLDivElement>(null);
const emailRef = useRef<HTMLInputElement>(null);
const { amount, invoiceParams, cardConfig, isFirstPage } = location.state as {
amount: number;
invoiceParams: GiftCardInvoiceParams;
cardConfig: CardConfig;
isFirstPage: boolean;
};
const [email, setReceiptEmail] = useState(invoiceParams.email || '');
const card: UnsoldGiftCard = {
amount,
currency: invoiceParams.currency,
name: cardConfig.name,
discounts: cardConfig.discounts
};
const shouldShowLineItems = !!(
(cardConfig.discounts && cardConfig.discounts.length) ||
(cardConfig.activationFees && cardConfig.activationFees.length)
);
const onEmailChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
emailRef.current?.validity.valid ? setReceiptEmail(event.target.value) : setReceiptEmail('');
};
useEffect(() => {
if (initiallyCollapsed && isFirstPage) return;
resizeToFitPage(ref, 71, 100);
}, [ref, initiallyCollapsed, isFirstPage]);
return (
<div className="payment">
<div ref={ref}>
<AnimatePresence initial={false}>
<CardHeader cardConfig={cardConfig} card={card} />
{shouldShowLineItems && <LineItems cardConfig={cardConfig} card={card} />}
</AnimatePresence>
{!invoiceParams.email && !user && (
<div className="settings-group">
<div className="settings-group__label">Email</div>
<div className="settings-group__input">
<input type="email" placeholder="[email protected]" autoFocus onChange={onEmailChange} ref={emailRef} />
</div>
<div className="settings-group__caption">Email used for purchase receipts and communication</div>
</div>
)}
<PayWithBitpay
invoiceParams={{ ...invoiceParams, amount, email }}
cardConfig={cardConfig}
history={history}
user={user}
setEmail={setEmail}
purchasedGiftCards={purchasedGiftCards}
setPurchasedGiftCards={setPurchasedGiftCards}
supportedMerchant={supportedMerchant}
/>
</div>
</div>
);
}
Example #19
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 #20
Source File: index.tsx From frontend-boilerplate with MIT License | 5 votes |
export default function Home() {
const [isOpen, setOpen] = useState<boolean>(false);
const toggleModal = () => setOpen(!isOpen);
return (
<DefaultLayout title={'Index'}>
<Layout.Container center>
<div className={'pt-12 md:pt-20 text-center'}>
<h1 className={'font-bold text-white text-3xl md:text-5xl mb-8'}>
React, Next.js & TailwindCSS
</h1>
<h2 className={'text-lg text-on-naked-50'}>
Don't waste time structuring or setting up interfaces on your next
project!
</h2>
</div>
<Button.Group className="flex mt-12 space-y-5 sm:space-y-0 sm:space-x-5">
<Button.Primary
title={`Open modal`}
size="xl"
className="!px-6"
onClick={() => toggleModal()}
/>
</Button.Group>
</Layout.Container>
<AnimatePresence>
{isOpen && (
<Modal.Default open={isOpen} onClose={() => toggleModal()}>
<Modal.Title onClose={() => toggleModal()}>Title</Modal.Title>
<Modal.Body>
<h1 className="text-[17px] font-semibold text-on-naked-100">
Did you know that..?
</h1>
{[...Array(30)].map(() => (
<h3 className="mt-1 text-base text-on-naked-800">
There is a technical name for the "fear of long words."
</h3>
))}
</Modal.Body>
<Modal.Footer>
<h4 className="text-sm text-center xs:text-left">
This is my cute little footer!
</h4>
<div
className="flex items-center justify-center px-5 py-3 mt-4 mb-5 font-semibold text-white rounded-full xs:hidden bg-types-200"
onClick={() => toggleModal()}
>
Close
</div>
</Modal.Footer>
</Modal.Default>
)}
</AnimatePresence>
</DefaultLayout>
);
}
Example #21
Source File: LastCheckins.tsx From rcvr-app with GNU Affero General Public License v3.0 | 4 votes |
LastCheckins: React.FC<Props> = ({ checkins, onCheckout }) => {
const [checkin] = checkins
const { t } = useLocaleObject(LastCheckinsLocales)
const area = useArea(checkins[0].areaId).data
const checkedOut = !!checkin.leftAt
const idRef = React.useRef<string>(uuidv4())
const [showProxyCheckin, setShowProxyCheckin] = React.useState(false)
const [isLoading, setLoading] = React.useState(false)
const [showEditData, setShowEditData] = React.useState(false)
const queryClient = useQueryClient()
const mutation = useMutation(checkinAction)
const handleEditGuest = (guest, _opts) => {
setLoading(true)
updateCurrentGuest(queryClient, guest).then((_checkin) => {
setLoading(false)
setShowEditData(false)
})
}
const proxyCheckin = React.useCallback(
async (guest: Guest) => {
const id = idRef.current
try {
setLoading(true)
const ticket = {
...checkin,
id,
publicKey: area.publicKey,
encryptedData: null,
proxyCheckin: true,
enteredAt: new Date(),
}
await mutation.mutateAsync({ ticket, guest })
idRef.current = uuidv4() // add a new one for the next
await queryClient.invalidateQueries('checkins')
setShowProxyCheckin(false)
setLoading(false)
} catch (error) {
console.error(error)
}
},
[checkin, setShowProxyCheckin, area, queryClient, mutation]
)
return (
<Container>
<Box height={16} />
<Circle animated delay={0.5} color={checkedOut ? 'pink' : 'green'}>
{checkedOut ? (
<Thumb delay={0.8} />
) : (
<Check delay={0.8} css={{ position: 'relative', top: 2 }} />
)}
</Circle>
<Box height={4} />
<Text variant="h2">
{checkedOut ? t('header_checkedOut') : t('header')}
</Text>
<Box height={1} />
<Text variant="h4" data-wfd-location={checkin.business}>
{checkin.business}
</Text>
{checkins.length > 1 && (
<>
<Box height={1} />
<Text variant="h4">
{checkins.length} {t('people')}
</Text>
</>
)}
<Box height={4} />
<CheckinDates from={checkin.enteredAt} to={checkin.leftAt} />
{!checkedOut && checkin.cwaLinkEnabled && checkin.cwaSeed && (
<>
<Box height={4} />
<ButtonLink
href={generateCwaLink(checkin)}
name="cwaCheckinUrl"
target="_blank"
>
<CwaLink>
<CwaLogo width="24" height="24" />
{t('CWALinkText')}
</CwaLink>
</ButtonLink>
<Box height={4} />
</>
)}
<Box height={2} />
{checkins
.map(({ guest }) => guest)
.filter((guest) => guest != null)
.map((guest, index) => (
<GuestDetails key={index}>
{index > 0 && <Box height={2} />}
<Text variant="label" as="label">
{t('name')}{' '}
<Text variant="regular" as="span">
{guest.name}
</Text>
</Text>
<Box height={1} />
<Text variant="label" as="label">
{t('address')}{' '}
<Text variant="regular" as="span">
{guest.address}, {guest.postalCode} {guest.city}
</Text>
</Text>
<Box height={1} />
<Text variant="label" as="label">
{t('telephone')}{' '}
<Text variant="regular" as="span">
{guest.phone}
</Text>
</Text>
<Box height={1} />
</GuestDetails>
))}
<AnimatePresence>
{!checkin.leftAt && (
<motion.div
css={{ width: '100%' }}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
<Box height={8} />
<Button
css={{ width: '100%' }}
left={<ArrowsRight color="pink" />}
right={<ArrowsLeft color="pink" />}
onClick={() => onCheckout(checkins)}
dataAttributes={{ 'wfd-action': 'check-out' }}
>
{t('checkOutButtonText')}
</Button>
<Box height={4} />
<Button
css={{ width: '100%' }}
onClick={() => setShowEditData(!showEditData)}
>
{t('changeYourDataButtonText')}
</Button>
<Box height={4} />
{showEditData && (
<Onboarding
area={area}
onSubmit={handleEditGuest}
hideRememberMe={true}
prefilledGuest={checkin.guest}
submitButtonValue={t('onboardingButtonText')}
/>
)}
<Loading show={isLoading} />
<Box height={8} />
{showProxyCheckin ? (
<>
<Box height={4} />
<Text variant="h3">{t('checkInMorePeopleHeadline')}</Text>
<Box height={2} />
<Onboarding
area={area}
prefilledGuest={{
address: checkin.guest?.address,
postalCode: checkin.guest?.postalCode,
city: checkin.guest?.city,
phone: checkin.guest?.phone,
}}
hideRememberMe={true}
onSubmit={proxyCheckin}
onAbort={() => setShowProxyCheckin(false)}
/>
</>
) : (
<Button
css={{ width: '100%', marginTop: '10px' }}
onClick={() => setShowProxyCheckin(true)}
>
{t('addPersonButtonText')}
</Button>
)}
</motion.div>
)}
</AnimatePresence>
<AnimatePresence>
{!checkin.leftAt && area?.menuLink && (
<motion.div
css={{ width: '100%' }}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
<Box height={4} />
<a href={area.menuLink} target="_blank" rel="noopener noreferrer">
<Button as="div" css={{ width: '100%' }}>
{area.menuAlias || t('additionalInfoLinkText')}
</Button>
</a>
</motion.div>
)}
</AnimatePresence>
</Container>
)
}
Example #22
Source File: QRExpandedState.tsx From rainbow-button with MIT License | 4 votes |
QRExpandedState = ({
enabled,
value,
setIsQRCodeOpen,
}: {
enabled: boolean;
value: string;
setIsQRCodeOpen: Dispatch<SetStateAction<boolean>>;
}) => {
return (
<AnimatePresence>
{enabled && (
<>
<UniqueTokenExpandedStateContent key={value}>
<motion.div
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
initial={{ opacity: 0 }}
transition={easingConfig}
>
<ExpandedStateBackground
onClick={() => setIsQRCodeOpen(false)}
opacity={0.8}
/>
</motion.div>
<ExpandedState
animate={{ scale: 1, y: 0 }}
as={motion.div}
exit={{ scale: 0.8, y: '100vh' }}
initial={{ scale: 0.8, y: '100vh' }}
qr
style={{ pointerEvents: 'auto' }}
transition={springConfig}
>
<Column
onClick={() => setIsQRCodeOpen(false)}
style={{ height: '100%', justifyContent: 'center' }}
>
<TitleText>
<span aria-labelledby="emoji" role="img">
?
</span>{' '}
Scan to connect to Rainbow
</TitleText>
<Container onClick={(proxy) => proxy.stopPropagation()}>
<QRCode logoSize={100} size={380} value={value} />
</Container>
<DownloadContainer>
<TitleText subtitle>
<span aria-labelledby="emoji" role="img">
?
</span>{' '}
Don’t have the app yet?{' '}
<span aria-labelledby="emoji" role="img">
?
</span>
</TitleText>
<div style={{ display: 'flex', flexDirection: 'row' }}>
<DownloadButton
href="https://apps.apple.com/us/app/rainbow-ethereum-wallet/id1457119021"
onClick={(proxy) => proxy.stopPropagation()}
target="_blank"
>
<div style={{ marginRight: 6 }}>
<LogoAppStore />
</div>
App Store
</DownloadButton>
</div>
</DownloadContainer>
</Column>
</ExpandedState>
</UniqueTokenExpandedStateContent>
<XButtonWrapper onClick={() => setIsQRCodeOpen(false)}>
<motion.div
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0 }}
initial={{ opacity: 0, scale: 0 }}
transition={easingConfig}
>
<XButton />
</motion.div>
</XButtonWrapper>
</>
)}
</AnimatePresence>
);
}
Example #23
Source File: Notifications.tsx From realayers with Apache License 2.0 | 4 votes |
Notifications: FC<NotificationsProps> = ({
children,
limit,
timeout,
showClose,
preventFlooding
}) => {
const [notifications, setNotifications] = useState<any[]>([]);
const clearNotification = useCallback(
(id: number) => setNotifications(notifications.filter(n => n.id !== id)),
[notifications]
);
const clearAllNotifications = useCallback(() => setNotifications([]), []);
const notify = useCallback(
(title: string, options: NotificationOptions = {}) => {
// If we are flooded with the same message over and over,
// dont add more of the same type. Mainly used for error use cases.
if (preventFlooding) {
const has = notifications.find(n => n.title === title);
if (has) {
return false;
}
}
const id = nextId++;
const obj = {
title,
id,
variant: 'default',
timeout,
showClose,
...options
};
const sorted = [obj, ...notifications];
// Clear old notifications if we hit limit
if (sorted.length >= limit) {
sorted.pop();
}
// Update the container instance
setNotifications(sorted);
return id;
},
[limit, notifications, preventFlooding, showClose, timeout]
);
const notifyError = useCallback(
(title: string, options: NotificationOptions = {}) =>
notify(title, { ...options, variant: 'error' }),
[notify]
);
const notifyWarning = useCallback(
(title: string, options: NotificationOptions = {}) =>
notify(title, { ...options, variant: 'warning' }),
[notify]
);
const notifySuccess = useCallback(
(title: string, options: NotificationOptions = {}) =>
notify(title, { ...options, variant: 'success' }),
[notify]
);
const values = useMemo(
() => ({
notify,
notifyError,
notifyWarning,
notifySuccess,
clearNotification,
clearAllNotifications
}),
[
clearNotification,
clearAllNotifications,
notify,
notifyError,
notifySuccess,
notifyWarning
]
);
return (
<Fragment>
<NotificationsContext.Provider value={values}>
{children}
</NotificationsContext.Provider>
<div className={css.container}>
<div className={css.positions}>
<AnimatePresence>
{!!notifications.length && (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
{notifications.map(n => (
<Notification {...n} key={n.id} onClose={clearNotification} />
))}
</motion.div>
)}
</AnimatePresence>
</div>
</div>
</Fragment>
);
}
Example #24
Source File: project-card.tsx From portfolio with MIT License | 4 votes |
ProjectCard: React.FC<ProjectCardProps> = ({
title,
description,
logo,
blurHash,
link,
technologies
}) => {
const textColor = useColorModeValue("gray.500", "gray.200");
const [isOpen, setIsOpen] = React.useState(false);
const toggleOpen = () => setIsOpen(!isOpen);
return (
<motion.div layout onClick={toggleOpen}>
<HStack
p={4}
bg={useColorModeValue("white", "gray.800")}
rounded="xl"
borderWidth="1px"
borderColor={useColorModeValue("gray.100", "gray.700")}
w="100%"
h="100%"
textAlign="left"
align="start"
spacing={4}
cursor="pointer"
_hover={{ shadow: "lg" }}
>
<LazyImage
src={logo}
blurHash={blurHash}
size="sm"
width={33}
height={33}
layout="fixed"
rounded="md"
/>
<VStack align="start" justify="flex-start">
<VStack spacing={0} align="start">
<motion.div layout>
<HStack>
<Text
as={Link}
href={link}
fontWeight="bold"
fontSize="md"
noOfLines={1}
onClick={e => e.stopPropagation()}
isExternal
>
{title}
</Text>
<HStack spacing="1">
{technologies.map(tech => (
<Tag size="sm" colorScheme={getTagColor(tech)}>
{tech}
</Tag>
))}
</HStack>
</HStack>
</motion.div>
<AnimatePresence>
<motion.div
layout
initial={{ opacity: 1 }}
animate={{ opacity: 1 }}
exit={{ opacity: 1 }}
>
{!isOpen && (
<Text fontSize="sm" color={textColor} noOfLines={{ base: 2 }}>
{description}
</Text>
)}
</motion.div>
</AnimatePresence>
<AnimatePresence>
<motion.div
layout
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
variants={{ exit: { transition: { staggerChildren: 0.1 } } }}
>
{isOpen && (
<Text
fontSize="sm"
color={textColor}
// noOfLines={{ base: isOpen ? 5 : 2 }}
>
{description}
</Text>
)}
</motion.div>
</AnimatePresence>
</VStack>
</VStack>
</HStack>
</motion.div>
);
}
Example #25
Source File: navbar.tsx From next-mdx with MIT License | 4 votes |
export function Navbar() {
const [showMenu, setShowMenu] = React.useState(false)
const [colorMode, setColorMode] = useColorMode()
return (
<header
borderBottomWidth="1px"
position="relative|sticky"
top="0"
zIndex="1000"
sx={{
":after": {
content: '""',
position: "absolute",
top: 0,
left: 0,
w: "full",
h: "100%",
zIndex: 10,
bg: "background",
opacity: "0.85",
backdropFilter: "saturate(100%) blur(10px)",
},
}}
>
<div
variant="container"
display="flex"
alignItems="center"
h="14"
position="relative"
zIndex="1000"
>
<button
display="block|block|block|none"
mr="2"
onClick={() => setShowMenu(!showMenu)}
color="text"
>
<Icon name="menu-alt" size="6" />
</button>
<Link href="/" passHref>
<a
display="none|flex"
textDecoration="none"
color="text"
alignItems="center"
fontSize="md|||xl"
fontWeight="semibold"
mr="0|0|0|10"
>
<Icon name="logo" size="6" mr="2" />
{site.name}
</a>
</Link>
<div
display="none|none|none|inline-grid"
col={`repeat(${site.links.length}, minmax(0,auto))`}
gap="8"
>
{site.links.map((link, index) => (
<NavbarLink
key={index}
href={link.url}
external={link.external}
activePathNames={link.activePathNames}
>
{link.title}
</NavbarLink>
))}
</div>
<div display="flex" ml="0|auto" flex="1|none">
<DocSearch ml="4" mr="4" flex="1" />
<a
href={`https://github.com/${site.social.github}`}
target="_blank"
rel="noreferrer"
variant="button.navbar"
ml="auto|0"
>
<Icon name="github" />
</a>
<button
variant="button.navbar"
onClick={() =>
setColorMode(colorMode === "dark" ? "light" : "dark")
}
>
<Icon name={colorMode === "dark" ? "sun" : "moon"} size="5" />
<VisuallyHidden>Toggle color mode</VisuallyHidden>
</button>
</div>
</div>
<AnimatePresence>
{showMenu ? (
<motion.div
initial={{
opacity: 0,
x: -50,
}}
animate={{
opacity: 1,
x: 0,
}}
exit={{
opacity: 0,
x: -50,
}}
transition={{
ease: "easeInOut",
}}
sx={{
px: 6,
top: "18|18",
position: "absolute",
w: "full",
}}
>
<div
boxShadow="xl"
borderWidth="1"
rounded="lg"
bg="background"
w="full"
h="85vh"
overflow="scroll"
>
<div
display="grid"
row={`repeat(${site.links.length}, minmax(0,auto))`}
gap="2|2|2|8"
zIndex="100"
position="relative"
py="4|4|4|0"
>
{site.links.map((link) => (
<NavbarLink
key={link.url}
href={link.url}
external={link.external}
activePathNames={link.activePathNames}
fontWeight="medium"
fontSize="xl"
py="0"
>
{link.title}
</NavbarLink>
))}
</div>
<div p="6" borderTopWidth="1">
<SidebarNav
items={docs.links}
onLinkClick={() => setShowMenu(false)}
/>
</div>
</div>
</motion.div>
) : null}
</AnimatePresence>
</header>
)
}
Example #26
Source File: index.tsx From color-copy-paste with MIT License | 4 votes |
IndexPage = () => {
const controls = useAnimation()
const controlSlider = useAnimation()
const controlColor = useAnimation()
const [color, setColor] = React.useState("#DDDDDD")
const [colors, setColors] = React.useState([])
const canvasRef = React.useRef(null)
const sliderRef = React.useRef(null)
const renderCanvas = () => {
try {
const canvas = canvasRef.current
var context = canvas.getContext("2d")
canvas.width = 1080
canvas.height = 152
context.drawImage(sliderRef.current, 0, 0, 1080, 152)
} catch (e) {
console.log(e)
}
}
React.useEffect(() => {
controls.start({ x: 720 }, { damping: 300 })
controlSlider.start({ x: -800 }, { damping: 300 })
setTimeout(() => renderCanvas(), 500)
setTimeout(() => renderCanvas(), 1500)
}, [])
return (
<>
<SEO title="Color Copy Paste" />
<div
style={{
margin: `0 auto`,
maxWidth: 960,
padding: `0 1.0875rem 1.45rem`,
}}
>
<div className="header">
<div className="header-column">
<div className="header-wrap">
<img src={Logo} style={{ marginBottom: 16 }} />
<h1 style={{ display: "none" }}>Color Copy Paste</h1>
<a
className="github-button"
href="https://github.com/sonnylazuardi/color-copy-paste"
data-size="large"
data-show-count="true"
aria-label="Star sonnylazuardi/color-copy-paste on GitHub"
>
Star
</a>
</div>
</div>
<div className="header-column column-two">
<div className="header-wrap">
<div className="header-label">
Copy & paste colour directly from your camera to:
</div>
<a
href="https://www.figma.com/community/plugin/845733021314534317/Camera-Color-Copy-Paste"
className="button-web button-blue"
>
<img className="button-icon" src={IconFigma} />
Figma Plugin
</a>
<a
href="color-copy-paste.sketchplugin.zip"
className="button-web button-yellow"
>
<img className="button-icon" src={IconSketch} />
Sketch Plugin
</a>
<Link to="app" className="button-web button-yellow">
<img className="button-icon" src={IconBrowser} />
Web Browser
</Link>
</div>
</div>
</div>
<img
src={BgSlider}
ref={sliderRef}
style={{ width: 1080, height: 152, display: "none" }}
onLoad={() => renderCanvas()}
/>
<canvas ref={canvasRef} style={{ display: "none" }}></canvas>
<img src={BgStatic} className="content-static" />
<motion.div
className="content-default"
onMouseMove={e => {
function getElementOffset(element) {
var de = document.documentElement
var box = element.getBoundingClientRect()
var left = box.left + window.pageXOffset - de.clientLeft
return left
}
const relativeX = e.pageX - getElementOffset(e.target)
if (relativeX > 70 && relativeX < 790) {
controls.start(
{
x: relativeX,
},
{ damping: 300 }
)
controlSlider.start(
{
x: relativeX * -1 - 180,
},
{ damping: 300 }
)
const canvas = canvasRef.current
var context = canvas.getContext("2d")
var pixel = context.getImageData(relativeX + 224, 68, 1, 1).data
controlColor.start({
backgroundColor: `rgb(${pixel[0]},${pixel[1]},${pixel[2]})`,
})
setColor(rgbToHex(pixel[0], pixel[1], pixel[2]))
}
}}
onClick={() => {
setColors([...colors, color])
}}
>
<div style={{ height: 500, overflow: "hidden" }}>
<img src={BgDesk} style={{ width: "100%" }} draggable={false} />
</div>
<motion.div
drag="x"
dragConstraints={{
left: -100,
right: 200,
}}
animate={controls}
className="control-hand"
style={{
backgroundImage: `url(${Hand})`,
}}
>
<div className="phone-screen">
<motion.div
animate={controlSlider}
className="control-slider"
style={{
backgroundImage: `url(${BgSlider})`,
}}
/>
</div>
<div className="bubble">
<motion.div animate={controlColor} className="control-color" />
{color.toUpperCase()}
</div>
</motion.div>
<div className="pallete">
{colors.length > 0 ? (
<AnimatePresence>
<div className="grid-demo">
{colors.map((item: any, i: number) => {
return (
<motion.div
key={i}
className="color-demo"
initial={{ scale: 0 }}
animate={{ scale: 1 }}
exit={{ scale: 0 }}
style={{ backgroundColor: item }}
onClick={() => {
copyTextToClipboard(item)
}}
></motion.div>
)
})}
</div>
</AnimatePresence>
) : (
<div className="empty">
<img src={IconClick} style={{ marginBottom: 8 }} />
Click to capture colour
</div>
)}
</div>
</motion.div>
</div>
<div className="section">
<div
style={{
margin: `0 auto`,
maxWidth: 960,
padding: `0 1.0875rem 1.45rem`,
}}
>
<div className="row">
<div className="column">
<div className="box">
<h3>How can I copy color?</h3>
<p>
Tap and hold the capture button located in the bottom of your
screen. Release to paste it to web browser or plugin.
</p>
</div>
</div>
<div className="column">
<div className="box">
<h3>Where is my color saved?</h3>
<p>
It is saved inside the local storage of the plugin or web
browser.
</p>
</div>
</div>
<div className="column">
<div className="box">
<h3>How does my phone connect?</h3>
<p>
The app uses socket to connect phone to your computer. It will
generate unique id when showing QR Code.
</p>
</div>
</div>
<div className="column">
<div className="box">
<h3>Can I save to color style?</h3>
<p>
Currently not yet, but you can click on the color to change
the object's color and copy the hex code
</p>
</div>
</div>
</div>
</div>
</div>
<div
style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
marginTop: 80,
padding: 16,
}}
>
<blockquote className="twitter-tweet" data-theme="dark">
<a href="https://twitter.com/sonnylazuardi/status/1263895972456697856">
@sonnylazuardi
</a>
</blockquote>
</div>
<div className="section-dark">
<div
style={{
margin: `0 auto`,
maxWidth: 960,
padding: `0 1.0875rem 1.45rem`,
}}
>
<h2>What others are saying</h2>
<div className="row">
<div className="column">
<div className="card">
<div
className="card-avatar"
style={{ backgroundImage: `url(${avatar1})` }}
/>
<div className="card-comment">
Well this just might be the coolest plugin I've ever reviewed.
:) Great job on this.
</div>
<div className="card-name">Josh, Figma Review</div>
</div>
</div>
<div className="column">
<div className="card">
<div
className="card-avatar"
style={{ backgroundImage: `url(${avatar2})` }}
/>
<div className="card-comment">
Get the inspiration from nature, so... going out door to pick
colour
</div>
<div className="card-name">Clu, Product Designer</div>
</div>
</div>
<div className="column">
<div className="card">
<div
className="card-avatar"
style={{ backgroundImage: `url(${avatar7})` }}
/>
<div className="card-comment">
Yeah nooo! This is some crazy stuff right here @sonnylazuardi
More reasons why we love the @figmadesign community ?
</div>
<div className="card-name">Uche, Product Designer</div>
</div>
</div>
<div className="column">
<div className="card">
<div
className="card-avatar"
style={{ backgroundImage: `url(${avatar4})` }}
/>
<div className="card-comment">
So cool, moving 3D real world elements into 2D interface or
digital world, the boundary is becoming blur.
</div>
<div className="card-name">Mi Yuhao, AI UX Designer</div>
</div>
</div>
<div className="column">
<div className="card">
<div
className="card-avatar"
style={{ backgroundImage: `url(${avatar5})` }}
/>
<div className="card-comment">This is neat!</div>
<div className="card-name">Ernest Ojeh, Product Designer</div>
</div>
</div>
<div className="column">
<div className="card">
<div
className="card-avatar"
style={{ backgroundImage: `url(${avatar6})` }}
/>
<div className="card-comment">Gokil sekali</div>
<div className="card-name">Dimas, Product Designer</div>
</div>
</div>
<div className="column">
<div className="card">
<div
className="card-avatar"
style={{ backgroundImage: `url(${avatar3})` }}
/>
<div className="card-comment">So goood mas!</div>
<div className="card-name">Afnizar, UX Designer</div>
</div>
</div>
<div className="column">
<div className="card">
<div
className="card-avatar"
style={{ backgroundImage: `url(${avatar8})` }}
/>
<div className="card-comment">
@sonnylazuardi built a @figmadesign plugin through a @framer
prototype ?
</div>
<div className="card-name">
Addison, Frontend Dev & Designer
</div>
</div>
</div>
<div className="column">
<div className="card">
<div
className="card-avatar"
style={{ backgroundImage: `url(${avatar9})` }}
/>
<div className="card-comment">
Marvellous plugin as always! Easy to use yet useful. Hats off!
</div>
<div className="card-name">Tyas, Product Designer</div>
</div>
</div>
<div className="column">
<div className="card">
<div
className="card-avatar"
style={{ backgroundImage: `url(${avatar10})` }}
/>
<div className="card-comment">
That’s pretty insane. Great work!
</div>
<div className="card-name">
Andy Ngo, Designer & Frontend Dev
</div>
</div>
</div>
<div className="column">
<div className="card">
<div
className="card-avatar"
style={{ backgroundImage: `url(${avatar11})` }}
/>
<div className="card-comment">Sorcery ?♂️</div>
<div className="card-name">Arif Eka, UI Designer</div>
</div>
</div>
<div className="column">
<div className="card">
<div
className="card-avatar"
style={{ backgroundImage: `url(${avatar12})` }}
/>
<div className="card-comment">You’re on a roll ?</div>
<div className="card-name">Gaddafi Rusli, Product Designer</div>
</div>
</div>
<div className="column">
<div className="card">
<div
className="card-avatar"
style={{ backgroundImage: `url(${avatar14})` }}
/>
<div className="card-comment">
This is amazing! Looking forward to the plugin ?
</div>
<div className="card-name">Soliudeen, Product Designer</div>
</div>
</div>
<div className="column">
<div className="card">
<div
className="card-avatar"
style={{ backgroundImage: `url(${avatar13})` }}
/>
<div className="card-comment">?</div>
<div className="card-name">Jacky Lee, Product Designer</div>
</div>
</div>
</div>
</div>
</div>
<div className="section-footer">
<div className="footer-caption">
This project was built for fun and to explore what’s possible with
design plugin. If you like this app, give me a{" "}
<a href="https://twitter.com/sonnylazuardi">follow on twitter</a>, an
upvote in{" "}
<a href="https://www.producthunt.com/posts/color-copy-paste">
Product Hunt
</a>{" "}
or star on{" "}
<a href="https://github.com/sonnylazuardi/color-copy-paste">github</a>
. We built this to give back ? to the design community.
</div>
<div className="producthunt-wrap">
<a
href="https://www.producthunt.com/posts/color-copy-paste?utm_source=badge-top-post-badge&utm_medium=badge&utm_souce=badge-color-copy-paste"
target="_blank"
>
<img
src="https://api.producthunt.com/widgets/embed-image/v1/top-post-badge.svg?post_id=205039&theme=dark&period=daily"
alt="Color Copy Paste - Copy colors from your phone & paste on web, figma, or sketch | Product Hunt Embed"
style={{ width: 250, height: 54 }}
width="250px"
height="54px"
/>
</a>
</div>
<div className="footer">
Built by{" "}
<a href="https://twitter.com/sonnylazuardi">@sonnylazuardi</a> in
Singapore. Illustrated by{" "}
<a href="https://dribbble.com/alzea">Alzea Arafat</a>
</div>
</div>
</>
)
}
Example #27
Source File: carousel.tsx From notebook with MIT License | 4 votes |
Carousel: React.SFC<CarouselProps> = ({
onOpen,
onClose,
isOpen,
repoId
}) => {
const [[page, direction], setPage] = React.useState([0, 0]);
const [imageIndex, setImageIndex] = React.useState<number>(0);
const paginate = (newDirection: number) => {
setPage([page + newDirection, newDirection]);
};
React.useEffect(() => {
setImageIndex(repoId);
}, [repoId]);
const nextImage = (newDirection: number) => {
paginate(newDirection);
setImageIndex(imageIndex + 1 < coverImages.length ? imageIndex + 1 : 0);
};
const prevImage = (newDirection: number) => {
paginate(newDirection);
setImageIndex(
0 === imageIndex ? coverImages.length - 1 : imageIndex - 1
);
};
return (
<Modal isCentered onClose={onClose} size={"6xl"} isOpen={isOpen}>
<ModalOverlay />
<ModalContent>
<ModalBody padding="0">
<div className="carousel-container">
<AnimatePresence initial={false} custom={direction}>
<motion.img
key={page}
src={coverImages[imageIndex]}
custom={direction}
variants={variants}
initial="enter"
animate="center"
exit="exit"
transition={{
x: { type: "spring", stiffness: 300, damping: 30 },
opacity: { duration: 0.2 }
}}
drag="x"
dragConstraints={{ left: 0, right: 0 }}
dragElastic={1}
onDragEnd={(e, { offset, velocity }) => {
const swipe = swipePower(offset.x, velocity.x);
if (swipe < -swipeConfidenceThreshold) {
paginate(1);
} else if (swipe > swipeConfidenceThreshold) {
paginate(-1);
}
}}
/>
</AnimatePresence>
<div className="next" onClick={() => nextImage(1)}>
<IconButton
aria-label="left image"
icon={<ChevronLeftIcon />}
cursor="pointer"
as={ChevronRightIcon}
size="md"
colorScheme="teal"
borderRadius="full"
/>
</div>
<div className="prev" onClick={() => prevImage(-1)}>
<IconButton
aria-label="right image"
icon={<ChevronRightIcon />}
cursor="pointer"
as={ChevronLeftIcon}
size="md"
colorScheme="teal"
borderRadius="full"
/>
</div>
</div>
</ModalBody>
</ModalContent>
</Modal>
);
}
Example #28
Source File: Snackbar.tsx From chroma-react with MIT License | 4 votes |
Snackbar: React.FC<SnackbarProps> = React.forwardRef<
HTMLDivElement,
SnackbarProps
>(
(
{
className,
duration = 6000,
icon: Icon,
isOpen = false,
allowDismiss = false,
onClose,
role = 'status',
statusType = 'info',
title,
children,
...rootProps
},
ref
) => {
const classes = useStyles({});
const shouldReduceMotion = useReducedMotion();
const [snackbarTimeout, setSnackbarTimeout] = React.useState<number | null>(
duration
);
// Event handlers
const onMouseEnter = () => setSnackbarTimeout(null);
const onMouseLeave = () => setSnackbarTimeout(duration);
const closeSnackbar = React.useCallback(() => {
onClose && onClose();
}, [onClose]);
// Use a ref to close our Snackbar after the timeout
const callbackRef = React.useRef<() => void | null>();
React.useEffect(() => {
if (!callbackRef.current) {
callbackRef.current = closeSnackbar;
}
}, [closeSnackbar]);
React.useEffect(() => {
// Ignore setting up a timer for the Snackbar
// if one is not isOpen.
if (!isOpen) {
return;
}
const tick = () => {
if (callbackRef.current) {
callbackRef.current();
}
};
if (snackbarTimeout) {
const id = setTimeout(tick, snackbarTimeout);
return () => clearTimeout(id);
}
}, [snackbarTimeout, isOpen]);
return (
<AnimatePresence initial={false}>
{isOpen ? (
<motion.div
ref={ref}
className={clsx(
classes.root,
{
[classes.infoModifier]: statusType === 'info',
[classes.errorModifier]: statusType === 'error',
[classes.warningModifier]: statusType === 'warning',
[classes.successModifier]: statusType === 'success',
},
className
)}
aria-live={role === 'alert' ? 'assertive' : 'polite'}
role={role}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
positionTransition
initial={
shouldReduceMotion ? { opacity: 0 } : { opacity: 0, y: -40 }
}
animate={
shouldReduceMotion
? { opacity: 1 }
: {
opacity: 1,
y: 0,
}
}
exit={
shouldReduceMotion
? { opacity: 0 }
: {
opacity: 0,
y: 60,
transition: { duration: 0.25, ease: 'easeIn' },
}
}
{...rootProps}
>
{!!Icon && <Icon role="img" aria-hidden className={classes.icon} />}
{children ? (
children
) : (
<Text className={classes.title}>{title}</Text>
)}
{allowDismiss && (
<>
<IconButton
className={classes.closeButton}
aria-label="Close Notification"
size={0}
paddingTop={0}
paddingBottom={0}
paddingRight={0}
icon={X}
onClick={closeSnackbar}
/>
</>
)}
</motion.div>
) : null}
</AnimatePresence>
);
}
)
Example #29
Source File: Logs.tsx From meshtastic-web with GNU General Public License v3.0 | 4 votes |
Logs = (): JSX.Element => {
const dispatch = useAppDispatch();
const meshtasticState = useAppSelector((state) => state.meshtastic);
const appState = useAppSelector((state) => state.app);
type lookupType = { [key: number]: string };
const emitterLookup: lookupType = {
[Types.Emitter.sendText]: 'text-rose-500',
[Types.Emitter.sendPacket]: 'text-pink-500',
[Types.Emitter.sendRaw]: 'text-fuchsia-500',
[Types.Emitter.setConfig]: 'text-purple-500',
[Types.Emitter.confirmSetConfig]: 'text-violet-500',
[Types.Emitter.setOwner]: 'text-indigo-500',
[Types.Emitter.setChannel]: 'text-blue-500',
[Types.Emitter.confirmSetChannel]: 'text-sky-500',
[Types.Emitter.deleteChannel]: 'text-cyan-500',
[Types.Emitter.getChannel]: 'text-teal-500',
[Types.Emitter.getAllChannels]: 'text-emerald-500',
[Types.Emitter.getConfig]: 'text-green-500',
[Types.Emitter.getOwner]: 'text-lime-500',
[Types.Emitter.configure]: 'text-yellow-500',
[Types.Emitter.handleFromRadio]: 'text-amber-500',
[Types.Emitter.handleMeshPacket]: 'text-orange-500',
[Types.Emitter.connect]: 'text-red-500',
[Types.Emitter.ping]: 'text-stone-500',
[Types.Emitter.readFromRadio]: 'text-zinc-500',
[Types.Emitter.writeToRadio]: 'text-gray-500',
[Types.Emitter.setDebugMode]: 'text-slate-500',
};
const levelLookup: lookupType = {
[Protobuf.LogRecord_Level.UNSET]: 'text-green-500',
[Protobuf.LogRecord_Level.CRITICAL]: 'text-purple-500',
[Protobuf.LogRecord_Level.ERROR]: 'text-red-500',
[Protobuf.LogRecord_Level.WARNING]: 'text-orange-500',
[Protobuf.LogRecord_Level.INFO]: 'text-blue-500',
[Protobuf.LogRecord_Level.DEBUG]: 'text-neutral-500',
[Protobuf.LogRecord_Level.TRACE]: 'text-slate-500',
};
return (
<div className="flex h-full flex-col gap-4 p-4">
<Card
title="Device Logs"
actions={
<IconButton
icon={<FiTrash />}
onClick={(): void => {
dispatch(clearLogs());
}}
/>
}
className="flex-grow overflow-y-auto"
>
<table className="table-cell flex-grow">
<tbody
className="
block h-full flex-col overflow-y-auto font-mono text-xs dark:text-gray-400"
>
<AnimatePresence>
{meshtasticState.logs.length === 0 && (
<div className="flex h-full w-full">
<m.img
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className="m-auto h-64 w-64 text-green-500"
src={
appState.darkMode
? '/View_Code_Dark.svg'
: '/View_Code.svg'
}
/>
</div>
)}
{meshtasticState.logs.map((log, index) => (
<m.tr
key={index}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.3 }}
className="group hover:bg-gray-300 dark:hover:bg-secondaryDark"
>
<m.td
className="w-6 cursor-pointer"
whileHover={{ scale: 1.01 }}
whileTap={{ scale: 0.99 }}
>
<div className="m-auto pl-2 text-white group-hover:text-black dark:text-primaryDark dark:group-hover:text-gray-400">
<FiArrowRight />
</div>
</m.td>
<Wrapper>
{log.date
.toLocaleString(undefined, {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
})
.replaceAll('/', '-')
.replace(',', '')}
</Wrapper>
<Wrapper>
<div className={emitterLookup[log.emitter]}>
[{Types.EmitterScope[log.scope]}.
{Types.Emitter[log.emitter]}]
</div>
</Wrapper>
<Wrapper className={levelLookup[log.level]}>
[{Protobuf.LogRecord_Level[log.level]}]{/* </div> */}
</Wrapper>
<td
className={`m-auto ${
log.packet ? '' : 'dark:text-secondaryDark'
}`}
>
<FiPaperclip />
</td>
<td className="w-full truncate pl-1">{log.message}</td>
</m.tr>
// </ContextMenu>
))}
</AnimatePresence>
</tbody>
</table>
</Card>
</div>
);
}