webapp/src/components/EditorNew/Sidebar.tsx
2023-02-17 10:21:02 +01:00

111 lines
2.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { For, createEffect, createSignal, onCleanup, onMount } from 'solid-js'
import type { JSX } from 'solid-js'
import { undo, redo } from 'prosemirror-history'
import { clsx } from 'clsx'
import styles from './Sidebar.module.scss'
import { useOutsideClickHandler } from '../../utils/useOutsideClickHandler'
import { useEscKeyDownHandler } from '../../utils/useEscKeyDownHandler'
import type { EditorView } from 'prosemirror-view'
const Off = (props) => <div class={styles.sidebarOff}>{props.children}</div>
const Link = (props: {
disabled?: boolean
title?: string
className?: string
children: JSX.Element
onClick?: () => void
}) => (
<button
class={clsx(styles.sidebarLink, props.className)}
onClick={props.onClick}
disabled={props.disabled}
title={props.title}
data-testid={props['data-testid']}
>
{props.children}
</button>
)
const Keys = (props: { keys: string[] }) => (
<span>
<For each={props.keys}>{(k) => <i>{k}</i>}</For>
</span>
)
type SidebarProps = {
editorViewRef: {
current: EditorView
}
}
export const Sidebar = (props: SidebarProps) => {
const [lastAction, setLastAction] = createSignal<string | undefined>()
const { editorViewRef } = props
const onUndo = () => undo(editorViewRef.current.state, editorViewRef.current.dispatch)
const onRedo = () => redo(editorViewRef.current.state, editorViewRef.current.dispatch)
const [isHidden, setIsHidden] = createSignal(true)
const toggleSidebar = () => {
setIsHidden((oldIsHidden) => !oldIsHidden)
}
createEffect(() => {
setLastAction()
})
createEffect(() => {
if (!lastAction()) return
const id = setTimeout(() => {
setLastAction()
}, 1000)
onCleanup(() => clearTimeout(id))
})
const [mod, setMod] = createSignal<'Ctrl' | 'Cmd'>('Ctrl')
onMount(() => {
setMod(navigator.platform.includes('Mac') ? 'Cmd' : 'Ctrl')
})
const containerRef: { current: HTMLElement } = {
current: null
}
useEscKeyDownHandler(() => setIsHidden(true))
useOutsideClickHandler({
containerRef,
predicate: () => !isHidden(),
handler: () => setIsHidden(true)
})
return (
<div
class={clsx(styles.sidebarContainer, {
[styles.sidebarContainerHidden]: isHidden()
})}
ref={(el) => (containerRef.current = el)}
>
<span class={styles.sidebarOpener} onClick={toggleSidebar}>
Советы и&nbsp;предложения
</span>
<Off onClick={() => editorViewRef.current.focus()}>
<div class={styles.sidebarCloser} onClick={toggleSidebar} />
<div>
<Link onClick={onUndo}>
Undo <Keys keys={[mod(), 'z']} />
</Link>
<Link onClick={onRedo}>
Redo <Keys keys={[mod(), 'Shift', 'z']} />
</Link>
</div>
</Off>
</div>
)
}