CoastalCommitsPastes/client/app/(posts)/components/file-dropdown/index.tsx

93 lines
2.1 KiB
TypeScript
Raw Normal View History

2022-11-12 04:28:06 -05:00
import ShiftBy from "@components/shift-by"
2022-11-09 21:38:05 -05:00
import { Button, Popover } from "@geist-ui/core/dist"
import ChevronDown from "@geist-ui/icons/chevronDown"
2022-04-09 20:48:19 -04:00
import CodeIcon from "@geist-ui/icons/fileFunction"
import FileIcon from "@geist-ui/icons/fileText"
2022-03-25 16:01:46 -04:00
import { codeFileExtensions } from "@lib/constants"
2022-11-12 04:28:06 -05:00
import type { File } from "lib/server/prisma"
import { useCallback, useEffect, useState } from "react"
import styles from "./dropdown.module.css"
2022-03-25 16:01:46 -04:00
type Item = File & {
2022-04-09 20:48:19 -04:00
icon: JSX.Element
2022-03-25 16:01:46 -04:00
}
const FileDropdown = ({
2022-04-09 20:48:19 -04:00
files,
isMobile
2022-03-25 16:01:46 -04:00
}: {
2022-04-09 20:48:19 -04:00
files: File[]
isMobile: boolean
2022-03-25 16:01:46 -04:00
}) => {
2022-04-09 20:48:19 -04:00
const [expanded, setExpanded] = useState(false)
const [items, setItems] = useState<Item[]>([])
const changeHandler = (next: boolean) => {
setExpanded(next)
}
const onOpen = () => setExpanded(true)
const onClose = useCallback(() => setExpanded(false), [setExpanded])
2022-04-09 20:48:19 -04:00
useEffect(() => {
const newItems = files.map((file) => {
const extension = file.title.split(".").pop()
if (codeFileExtensions.includes(extension || "")) {
return {
...file,
icon: <CodeIcon />
}
} else {
return {
...file,
icon: <FileIcon />
}
}
})
setItems(newItems)
}, [files])
2022-03-25 16:01:46 -04:00
const content = (
<ul className={styles.content}>
{items.map((item) => (
<li key={item.id} onClick={onClose}>
<a href={`#${item.title}`}>
<ShiftBy y={5}>
<span className={styles.fileIcon}>{item.icon}</span>
</ShiftBy>
<span className={styles.fileTitle}>
{item.title ? item.title : "Untitled"}
</span>
</a>
</li>
))}
</ul>
)
2022-03-25 16:01:46 -04:00
2022-04-09 20:48:19 -04:00
// a list of files with an icon and a title
return (
<>
<Button
auto
onClick={onOpen}
className={styles.button}
iconRight={<ChevronDown />}
style={{ textTransform: "none" }}
>
Jump to {files.length} {files.length === 1 ? "file" : "files"}
</Button>
<Popover
style={{
transform: isMobile ? "translateX(110px)" : "translateX(-75px)"
}}
onVisibleChange={changeHandler}
content={content}
visible={expanded}
hideArrow={true}
onClick={onClose}
/>
</>
)
2022-03-25 16:01:46 -04:00
}
2022-04-09 20:48:19 -04:00
export default FileDropdown