import * as React from "react"; import { useTranslation } from "react-i18next"; import styled from "styled-components"; import { s } from "@shared/styles"; import { isMac } from "@shared/utils/browser"; import Flex from "~/components/Flex"; import InputSearch from "~/components/InputSearch"; import Key from "~/components/Key"; import { metaDisplay, altDisplay } from "~/utils/keyboard"; function KeyboardShortcuts() { const { t } = useTranslation(); const categories = React.useMemo( () => [ { title: t("Navigation"), items: [ { shortcut: ( <> {metaDisplay} + k ), label: t("Open command menu"), }, { shortcut: n, label: t("New document"), }, { shortcut: e, label: t("Edit current document"), }, { shortcut: m, label: t("Move current document"), }, { shortcut: h, label: t("Open document history"), }, { shortcut: ( <> / or t ), label: t("Jump to search"), }, { shortcut: d, label: t("Jump to home"), }, { shortcut: ( <> Ctrl + {altDisplay} + h ), label: t("Table of contents"), }, { shortcut: ( <> {metaDisplay} + . ), label: t("Toggle navigation"), }, { shortcut: ( <> {metaDisplay} + f ), label: t("Focus search input"), }, { shortcut: ?, label: t("Open this guide"), }, { shortcut: ( <> {metaDisplay} + {t("Enter")} ), label: t("Go to link"), }, { shortcut: ( <> {metaDisplay} + +{" "} p ), label: t("Publish document and exit"), }, { shortcut: ( <> {metaDisplay} + s ), label: t("Save document"), }, { shortcut: ( <> {isMac() ? metaDisplay : "⇧"} + Esc ), label: t("Cancel editing"), }, ], }, { title: t("Collaboration"), items: [ { shortcut: ( <> {metaDisplay} + Alt + m ), label: t("Comment"), }, ], }, { title: t("Formatting"), items: [ { shortcut: ( <> Ctrl + + 0 ), label: t("Paragraph"), }, { shortcut: ( <> Ctrl + + 1 ), label: t("Large header"), }, { shortcut: ( <> Ctrl + + 2 ), label: t("Medium header"), }, { shortcut: ( <> Ctrl + + 3 ), label: t("Small header"), }, { shortcut: ( <> Ctrl + + \ ), label: t("Code block"), }, { shortcut: ( <> {metaDisplay} + b ), label: t("Bold"), }, { shortcut: ( <> {metaDisplay} + i ), label: t("Italic"), }, { shortcut: ( <> {metaDisplay} + u ), label: t("Underline"), }, { shortcut: ( <> {metaDisplay} + d ), label: t("Strikethrough"), }, { shortcut: ( <> {metaDisplay} + k ), label: t("Link"), }, { shortcut: ( <> {metaDisplay} + z ), label: t("Undo"), }, { shortcut: ( <> {metaDisplay} + +{" "} z ), label: t("Redo"), }, ], }, { title: t("Lists"), items: [ { shortcut: ( <> Ctrl + + 7 ), label: t("Todo list"), }, { shortcut: ( <> Ctrl + + 8 ), label: t("Bulleted list"), }, { shortcut: ( <> Ctrl + + 9 ), label: t("Ordered list"), }, { shortcut: {t("Tab")}, label: t("Indent list item"), }, { shortcut: ( <> + {t("Tab")} ), label: t("Outdent list item"), }, { shortcut: ( <> {altDisplay} + ), label: t("Move list item up"), }, { shortcut: ( <> {altDisplay} + ), label: t("Move list item down"), }, ], }, { title: t("Tables"), items: [ { shortcut: ( <> {metaDisplay} + {t("Enter")} ), label: t("Insert row"), }, { shortcut: {t("Tab")}, label: t("Next cell"), }, { shortcut: ( <> + {t("Tab")} ), label: t("Previous cell"), }, ], }, { title: t("Markdown"), items: [ { shortcut: ( <> # {t("Space")} ), label: t("Large header"), }, { shortcut: ( <> ## {t("Space")} ), label: t("Medium header"), }, { shortcut: ( <> ### {t("Space")} ), label: t("Small header"), }, { shortcut: ( <> 1. {t("Space")} ), label: t("Numbered list"), }, { shortcut: ( <> - {t("Space")} ), label: t("Bulleted list"), }, { shortcut: ( <> [ ] {t("Space")} ), label: t("Todo list"), }, { shortcut: ( <> > {t("Space")} ), label: t("Blockquote"), }, { shortcut: ---, label: t("Horizontal divider"), }, { shortcut: {"```"}, label: t("Code block"), }, { shortcut: ( <> $$$ {t("Space")} ), label: t("LaTeX block"), }, { shortcut: {":::"}, label: t("Info notice"), }, { shortcut: "_italic_", label: t("Italic"), }, { shortcut: "**bold**", label: t("Bold"), }, { shortcut: "~~strikethrough~~", label: t("Strikethrough"), }, { shortcut: "`code`", label: t("Inline code"), }, { shortcut: "$$latex$$", label: t("Inline LaTeX"), }, { shortcut: "==highlight==", label: t("Highlight"), }, ], }, ], [t] ); const [searchTerm, setSearchTerm] = React.useState(""); const handleChange = React.useCallback((event) => { setSearchTerm(event.target.value); }, []); const handleKeyDown = React.useCallback((event) => { if (event.currentTarget.value && event.key === "Escape") { event.preventDefault(); event.stopPropagation(); setSearchTerm(""); } }, []); return ( {categories.map((category, x) => { const filtered = searchTerm ? category.items.filter((item) => item.label.toLowerCase().includes(searchTerm.toLowerCase()) ) : category.items; if (!filtered.length) { return null; } return (
{category.title}
{filtered.map((item) => ( {item.shortcut} ))}
); })}
); } const Header = styled.h2` font-size: 15px; font-weight: 500; margin-top: 2em; `; const List = styled.dl` font-size: 14px; width: 100%; overflow: hidden; padding: 0; margin: 0; user-select: none; `; const Keys = styled.dt` float: right; width: 45%; margin: 0 0 10px; clear: left; text-align: right; font-size: 12px; color: ${s("textSecondary")}; display: flex; align-items: center; justify-content: flex-end; `; const Label = styled.dd` float: left; width: 55%; margin: 0 0 10px; display: flex; align-items: center; color: ${s("textSecondary")}; `; export default React.memo(KeyboardShortcuts);