2022-03-25 16:37:54 -04:00
|
|
|
import { Button, Link, Text, Popover } from '@geist-ui/core'
|
2022-03-25 16:01:46 -04:00
|
|
|
import FileIcon from '@geist-ui/icons/fileText'
|
2022-03-25 17:31:10 -04:00
|
|
|
import CodeIcon from '@geist-ui/icons/fileFunction'
|
2022-03-25 16:01:46 -04:00
|
|
|
import styles from './dropdown.module.css'
|
2022-03-25 17:31:10 -04:00
|
|
|
import { useCallback, useEffect, useRef, useState } from "react"
|
2022-03-25 16:01:46 -04:00
|
|
|
import { codeFileExtensions } from "@lib/constants"
|
|
|
|
import ChevronDown from '@geist-ui/icons/chevronDown'
|
|
|
|
import ShiftBy from "@components/shift-by"
|
|
|
|
import type { File } from '@lib/types'
|
|
|
|
|
|
|
|
type Item = File & {
|
|
|
|
icon: JSX.Element
|
|
|
|
}
|
|
|
|
|
|
|
|
const FileDropdown = ({
|
2022-04-02 01:55:27 -04:00
|
|
|
files,
|
|
|
|
isMobile
|
2022-03-25 16:01:46 -04:00
|
|
|
}: {
|
2022-04-02 01:55:27 -04:00
|
|
|
files: File[],
|
|
|
|
isMobile: boolean
|
2022-03-25 16:01:46 -04:00
|
|
|
}) => {
|
|
|
|
const [expanded, setExpanded] = useState(false)
|
|
|
|
const [items, setItems] = useState<Item[]>([])
|
2022-04-01 20:26:01 -04:00
|
|
|
const changeHandler = (next: boolean) => {
|
|
|
|
setExpanded(next)
|
|
|
|
}
|
2022-03-25 17:31:10 -04:00
|
|
|
|
|
|
|
const onOpen = useCallback(() => {
|
|
|
|
setExpanded(true)
|
|
|
|
}, [])
|
|
|
|
|
|
|
|
const onClose = useCallback(() => {
|
|
|
|
setExpanded(false)
|
|
|
|
// contentRef.current?.focus()
|
|
|
|
}, [])
|
|
|
|
|
2022-03-25 16:01:46 -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])
|
|
|
|
|
|
|
|
const content = useCallback(() => (<ul className={styles.content}>
|
|
|
|
{items.map(item => (
|
2022-03-25 17:31:10 -04:00
|
|
|
<li key={item.id} onClick={onClose}>
|
|
|
|
<a href={`#${item.title}`}>
|
2022-03-25 16:01:46 -04:00
|
|
|
<ShiftBy y={5}><span className={styles.fileIcon}>
|
|
|
|
{item.icon}</span></ShiftBy>
|
2022-03-25 16:37:54 -04:00
|
|
|
<span className={styles.fileTitle}>{item.title ? item.title : 'Untitled'}</span>
|
2022-03-25 17:31:10 -04:00
|
|
|
</a>
|
2022-03-25 16:01:46 -04:00
|
|
|
</li>
|
|
|
|
))}
|
|
|
|
</ul>
|
2022-03-25 17:31:10 -04:00
|
|
|
), [items, onClose])
|
2022-03-25 16:01:46 -04:00
|
|
|
|
|
|
|
// a list of files with an icon and a title
|
|
|
|
return (
|
2022-04-01 20:26:01 -04:00
|
|
|
<>
|
2022-04-02 01:55:27 -04:00
|
|
|
<Button auto onClick={onOpen} className={styles.button} iconRight={<ChevronDown />} style={{ textTransform: 'none' }} >
|
2022-03-25 17:31:10 -04:00
|
|
|
Jump to {files.length} {files.length === 1 ? 'file' : 'files'}
|
2022-04-01 20:26:01 -04:00
|
|
|
</Button>
|
|
|
|
<Popover
|
2022-04-02 01:55:27 -04:00
|
|
|
style={{ transform: isMobile ? "translateX(110px)" : "translateX(-75px)" }}
|
2022-04-01 20:26:01 -04:00
|
|
|
onVisibleChange={changeHandler}
|
|
|
|
content={content} visible={expanded} hideArrow={true} onClick={onClose} />
|
|
|
|
</>
|
|
|
|
|
2022-03-25 16:01:46 -04:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
export default FileDropdown
|