client: add more formatting icons and improve formatting bar responsiveness

This commit is contained in:
Max Leiter 2022-04-22 15:42:54 -07:00
parent a52e9a1c62
commit 6a951cad78
No known key found for this signature in database
GPG key ID: A3512F2F2F17EBDA
3 changed files with 44 additions and 18 deletions

View file

@ -38,3 +38,10 @@
position: absolute; position: absolute;
right: 0; right: 0;
} }
@media (max-width: 768px) {
.actionWrapper .actions {
position: relative;
margin-left: 0 !important;
}
}

View file

@ -1,10 +1,13 @@
import Bold from "@geist-ui/icons/bold" import Bold from "@geist-ui/icons/bold"
import Italic from "@geist-ui/icons/italic" import Italic from "@geist-ui/icons/italic"
import Link from "@geist-ui/icons/link" import Link from "@geist-ui/icons/link"
import Code from "@geist-ui/icons/code"
import List from "@geist-ui/icons/list"
import ImageIcon from "@geist-ui/icons/image" import ImageIcon from "@geist-ui/icons/image"
import { RefObject, useCallback, useMemo } from "react" import { RefObject, useMemo } from "react"
import styles from "../document.module.css" import styles from "../document.module.css"
import { Button, ButtonGroup } from "@geist-ui/core" import { Button, ButtonGroup, Tooltip } from "@geist-ui/core"
import { TextareaMarkdownRef } from "textarea-markdown-editor" import { TextareaMarkdownRef } from "textarea-markdown-editor"
// TODO: clean up // TODO: clean up
@ -19,6 +22,9 @@ const FormattingIcons = ({
const handleItalicClick = () => textareaRef?.current?.trigger("italic") const handleItalicClick = () => textareaRef?.current?.trigger("italic")
const handleLinkClick = () => textareaRef?.current?.trigger("link") const handleLinkClick = () => textareaRef?.current?.trigger("link")
const handleImageClick = () => textareaRef?.current?.trigger("image") const handleImageClick = () => textareaRef?.current?.trigger("image")
const handleCodeClick = () => textareaRef?.current?.trigger("code")
const handleListClick = () =>
textareaRef?.current?.trigger("unordered-list")
return [ return [
{ {
icon: <Bold />, icon: <Bold />,
@ -30,11 +36,6 @@ const FormattingIcons = ({
name: "italic", name: "italic",
action: handleItalicClick action: handleItalicClick
}, },
// {
// icon: <Underline />,
// name: 'underline',
// action: handleUnderlineClick
// },
{ {
icon: <Link />, icon: <Link />,
name: "hyperlink", name: "hyperlink",
@ -44,6 +45,16 @@ const FormattingIcons = ({
icon: <ImageIcon />, icon: <ImageIcon />,
name: "image", name: "image",
action: handleImageClick action: handleImageClick
},
{
icon: <Code />,
name: "code",
action: handleCodeClick
},
{
icon: <List />,
name: "unordered-list",
action: handleListClick
} }
] ]
}, [textareaRef]) }, [textareaRef])
@ -52,16 +63,20 @@ const FormattingIcons = ({
<div className={styles.actionWrapper}> <div className={styles.actionWrapper}>
<ButtonGroup className={styles.actions}> <ButtonGroup className={styles.actions}>
{formattingActions.map(({ icon, name, action }) => ( {formattingActions.map(({ icon, name, action }) => (
<Tooltip
text={name[0].toUpperCase() + name.slice(1).replace("-", " ")}
key={name}
>
<Button <Button
auto auto
scale={2 / 3} scale={2 / 3}
px={0.6} px={0.6}
aria-label={name} aria-label={name}
key={name}
icon={icon} icon={icon}
onMouseDown={(e) => e.preventDefault()} onMouseDown={(e) => e.preventDefault()}
onClick={action} onClick={action}
/> />
</Tooltip>
))} ))}
</ButtonGroup> </ButtonGroup>
</div> </div>

View file

@ -1,4 +1,4 @@
import { Text, useTheme, useToasts } from "@geist-ui/core" import { Text, useMediaQuery, useTheme, useToasts } from "@geist-ui/core"
import { memo } from "react" import { memo } from "react"
import { useDropzone } from "react-dropzone" import { useDropzone } from "react-dropzone"
import styles from "./drag-and-drop.module.css" import styles from "./drag-and-drop.module.css"
@ -14,6 +14,9 @@ import byteToMB from "@lib/byte-to-mb"
function FileDropzone({ setDocs }: { setDocs: (docs: Document[]) => void }) { function FileDropzone({ setDocs }: { setDocs: (docs: Document[]) => void }) {
const { palette } = useTheme() const { palette } = useTheme()
const { setToast } = useToasts() const { setToast } = useToasts()
const isMobile = useMediaQuery("xs", {
match: "down"
})
const onDrop = async (acceptedFiles: File[]) => { const onDrop = async (acceptedFiles: File[]) => {
const newDocs = await Promise.all( const newDocs = await Promise.all(
acceptedFiles.map((file) => { acceptedFiles.map((file) => {
@ -84,6 +87,7 @@ function FileDropzone({ setDocs }: { setDocs: (docs: Document[]) => void }) {
</li> </li>
)) ))
const verb = isMobile ? "tap" : "click"
return ( return (
<div className={styles.container}> <div className={styles.container}>
<div <div
@ -95,7 +99,7 @@ function FileDropzone({ setDocs }: { setDocs: (docs: Document[]) => void }) {
> >
<input {...getInputProps()} /> <input {...getInputProps()} />
{!isDragActive && ( {!isDragActive && (
<Text p>Drag some files here, or click to select files</Text> <Text p>Drag some files here, or {verb} to select files</Text>
)} )}
{isDragActive && <Text p>Release to drop the files here</Text>} {isDragActive && <Text p>Release to drop the files here</Text>}
</div> </div>