feat: basic structure for share link

This commit is contained in:
MAZE 2024-01-02 22:20:59 +03:30
parent 35e32152b1
commit ef81f198ba
9 changed files with 131 additions and 71 deletions

View file

@ -0,0 +1,9 @@
import { Item } from '../item';
interface ShareProps {
open: () => void;
}
export function Share({ open }: ShareProps) {
return <Item onClick={open}>Share Sounds</Item>;
}

View file

@ -1 +0,0 @@
export { Share } from './share';

View file

@ -1,36 +0,0 @@
import { useState } from 'react';
import { createPortal } from 'react-dom';
import { IoCopyOutline } from 'react-icons/io5/index';
import { Modal } from '@/components/modal';
import { Item } from '../../item';
import styles from './share.module.css';
export function Share() {
const [isModalOpen, setIsModalOpen] = useState(false);
return (
<>
<Item onClick={() => setIsModalOpen(true)}>Share Sounds</Item>
{createPortal(
<Modal show={isModalOpen} onClose={() => setIsModalOpen(false)}>
<h1 className={styles.heading}>Share your sound selection!</h1>
<p className={styles.desc}>
Copy and send the following link to the person you want to share
your selection with.
</p>
<div className={styles.inputWrapper}>
<input type="text" onFocus={e => e.stopPropagation()} />
<button>
<IoCopyOutline />
</button>
</div>
</Modal>,
document.body,
)}
</>
);
}

View file

@ -15,6 +15,7 @@ import {
} from '@floating-ui/react';
import { ShuffleItem, ShareItem } from './items';
import { ShareLinkModal } from '@/components/modals/share-link';
import { slideY, fade, mix } from '@/lib/motion';
@ -23,6 +24,8 @@ import styles from './menu.module.css';
export function Menu() {
const [isOpen, setIsOpen] = useState(false);
const [showShareLink, setShowShareLink] = useState(false);
const variants = mix(slideY(-20), fade());
const { context, floatingStyles, refs } = useFloating({
@ -44,6 +47,7 @@ export function Menu() {
]);
return (
<>
<div className={styles.wrapper}>
<button
aria-label="Menu"
@ -57,7 +61,7 @@ export function Menu() {
<AnimatePresence>
{isOpen && (
<FloatingFocusManager context={context}>
<FloatingFocusManager context={context} modal={false}>
<div
ref={refs.setFloating}
style={floatingStyles}
@ -70,7 +74,7 @@ export function Menu() {
initial="hidden"
variants={variants}
>
<ShareItem />
<ShareItem open={() => setShowShareLink(true)} />
<ShuffleItem />
</motion.div>
</div>
@ -78,5 +82,11 @@ export function Menu() {
)}
</AnimatePresence>
</div>
<ShareLinkModal
show={showShareLink}
onClose={() => setShowShareLink(false)}
/>
</>
);
}

View file

@ -15,6 +15,7 @@
max-height: 100%;
padding: 50px 0;
overflow-y: auto;
pointer-events: none;
transform: translate(-50%, -50%);
& .content {
@ -22,8 +23,27 @@
width: 90%;
max-width: 500px;
padding: 20px;
padding-top: 40px;
margin: 0 auto;
pointer-events: fill;
background-color: var(--color-neutral-100);
border-radius: 8px;
& .close {
position: absolute;
top: 10px;
right: 10px;
display: flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
font-size: 16px;
color: var(--color-foreground-subtle);
cursor: pointer;
background-color: transparent;
border: none;
outline: none;
}
}
}

View file

@ -1,4 +1,5 @@
import { AnimatePresence } from 'framer-motion';
import { IoClose } from 'react-icons/io5/index';
import styles from './modal.module.css';
@ -19,7 +20,13 @@ export function Modal({ children, onClose, show }: ModalProps) {
onKeyDown={onClose}
/>
<div className={styles.modal}>
<div className={styles.content}>{children}</div>
<div className={styles.content}>
<button className={styles.close} onClick={onClose}>
<IoClose />
</button>
{children}
</div>
</div>
</>
)}

View file

@ -0,0 +1 @@
export { ShareLinkModal } from './share-link';

View file

@ -15,6 +15,7 @@
align-items: center;
width: 100%;
height: 45px;
padding: 4px;
margin-top: 12px;
background-color: var(--color-neutral-50);
border: 1px solid var(--color-neutral-200);
@ -23,9 +24,30 @@
& input {
flex-grow: 1;
height: 100%;
color: red;
padding: 0 10px;
font-size: var(--font-sm);
color: var(--color-foreground);
background: transparent;
border: none;
outline: none;
}
& button {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
aspect-ratio: 1 / 1;
color: var(--color-foreground);
cursor: pointer;
background-color: var(--color-neutral-100);
border: none;
border-radius: 4px;
outline: none;
transition: 0.2s;
&:hover {
background-color: var(--color-neutral-200);
}
}
}

View file

@ -0,0 +1,28 @@
import { IoCopyOutline } from 'react-icons/io5/index';
import { Modal } from '@/components/modal';
import styles from './share-link.module.css';
interface ShareLinkModalProps {
onClose: () => void;
show: boolean;
}
export function ShareLinkModal({ onClose, show }: ShareLinkModalProps) {
return (
<Modal show={show} onClose={onClose}>
<h1 className={styles.heading}>Share your sound selection!</h1>
<p className={styles.desc}>
Copy and send the following link to the person you want to share your
selection with.
</p>
<div className={styles.inputWrapper}>
<input type="text" value="https://moodist.app/?share=test" />
<button>
<IoCopyOutline />
</button>
</div>
</Modal>
);
}