refactor: extract shortcuts from help modal

Co-authored-by: Erik Michelson <github@erik.michelson.eu>
Signed-off-by: Erik Michelson <github@erik.michelson.eu>
Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
Tilman Vatteroth 2023-06-29 22:01:01 +02:00 committed by Erik Michelson
parent ae37bd36f9
commit ff004a5a63
11 changed files with 254 additions and 252 deletions

View file

@ -0,0 +1,14 @@
/*
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { isMac } from '../../editor-page/utils'
import React from 'react'
/**
* Renders a keyboard alt/option key hint depending on if the browser is running on macOS or not.
*/
export const AltKey: React.FC = () => {
return isMac() ? <kbd></kbd> : <kbd>Alt</kbd>
}

View file

@ -0,0 +1,32 @@
/*
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import type { PropsWithChildren } from 'react'
import React from 'react'
import { Card, ListGroup } from 'react-bootstrap'
import { Trans, useTranslation } from 'react-i18next'
interface CategoryProps extends PropsWithChildren {
headerI18nKey: string
}
/**
* Renders a group of shortcut lines
*
* @param headerI18nKey The i18n key of the header
* @param children The lines to include
*/
export const CategoryCard: React.FC<CategoryProps> = ({ headerI18nKey, children }) => {
useTranslation()
return (
<Card key={headerI18nKey} className={'mb-4'}>
<Card.Header>
<Trans i18nKey={headerI18nKey} />
</Card.Header>
<ListGroup variant='flush'>{children}</ListGroup>
</Card>
)
}

View file

@ -0,0 +1,14 @@
/*
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { isMac } from '../../editor-page/utils'
import React from 'react'
/**
* Renders a keyboard control/command key hint depending on if the browser is running on macOS or not.
*/
export const ModifierKey: React.FC = () => {
return isMac() ? <kbd></kbd> : <kbd>Ctrl</kbd>
}

View file

@ -0,0 +1,56 @@
/*
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { ShowIf } from '../../common/show-if/show-if'
import { AltKey } from './alt-key'
import { ModifierKey } from './modifier-key'
import React from 'react'
import { ListGroup } from 'react-bootstrap'
import { Trans, useTranslation } from 'react-i18next'
interface ShortcutLineProps {
functionNameI18nKey: string
showModifierKey: boolean
showAltKey: boolean
functionKeyCode: string
}
/**
* Renders one shortcut hint for the modal
*
* @param functionNameI18nKey The i18n key of the function name that is associated to the shortcut
* @param showAltKey Defines if the shortcut requires the alt/option key
* @param showModifierKey Defines if the shortcut requires the control/command key
* @param functionKeyCode The actual key of the shortcut
*/
export const ShortcutLine: React.FC<ShortcutLineProps> = ({
functionNameI18nKey,
showAltKey,
showModifierKey,
functionKeyCode
}) => {
useTranslation()
return (
<ListGroup.Item className={'d-flex justify-content-between'}>
<span>
<Trans i18nKey={functionNameI18nKey} />
</span>
<span>
<ShowIf condition={showModifierKey}>
<ModifierKey />
<span> + </span>
</ShowIf>
<ShowIf condition={showAltKey}>
<AltKey />
<span> + </span>
</ShowIf>
<kbd>{functionKeyCode.toUpperCase()}</kbd>
</span>
</ListGroup.Item>
)
}

View file

@ -0,0 +1,78 @@
/*
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { CategoryCard } from './category-card'
import { ShortcutLine } from './shortcut-line'
import React from 'react'
import { Container } from 'react-bootstrap'
/**
* Renders a list of shortcuts usable in HedgeDoc.
*/
export const ShortcutsContent: React.FC = () => {
return (
<Container>
<CategoryCard headerI18nKey={'shortcuts.viewMode.header'}>
<ShortcutLine
functionNameI18nKey={'shortcuts.viewMode.view'}
showModifierKey={true}
showAltKey={true}
functionKeyCode={'v'}
/>
<ShortcutLine
functionNameI18nKey={'shortcuts.viewMode.both'}
showModifierKey={true}
showAltKey={true}
functionKeyCode={'b'}
/>
<ShortcutLine
functionNameI18nKey={'shortcuts.viewMode.edit'}
showModifierKey={true}
showAltKey={true}
functionKeyCode={'e'}
/>
</CategoryCard>
<CategoryCard headerI18nKey={'shortcuts.editor.header'}>
<ShortcutLine
functionNameI18nKey={'shortcuts.editor.bold'}
showModifierKey={true}
showAltKey={false}
functionKeyCode={'b'}
/>
<ShortcutLine
functionNameI18nKey={'shortcuts.editor.italic'}
showModifierKey={true}
showAltKey={false}
functionKeyCode={'i'}
/>
<ShortcutLine
functionNameI18nKey={'shortcuts.editor.underline'}
showModifierKey={true}
showAltKey={false}
functionKeyCode={'u'}
/>
<ShortcutLine
functionNameI18nKey={'shortcuts.editor.strikethrough'}
showModifierKey={true}
showAltKey={false}
functionKeyCode={'d'}
/>
<ShortcutLine
functionNameI18nKey={'shortcuts.editor.mark'}
showModifierKey={true}
showAltKey={false}
functionKeyCode={'m'}
/>
<ShortcutLine
functionNameI18nKey={'shortcuts.editor.link'}
showModifierKey={true}
showAltKey={false}
functionKeyCode={'k'}
/>
</CategoryCard>
</Container>
)
}

View file

@ -0,0 +1,29 @@
/*
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { useTranslatedText } from '../../../hooks/common/use-translated-text'
import type { ModalVisibilityProps } from '../../common/modals/common-modal'
import { CommonModal } from '../../common/modals/common-modal'
import { ShortcutsContent } from './shortcuts-content'
import React from 'react'
import { Modal } from 'react-bootstrap'
import { QuestionCircle as IconQuestionCircle } from 'react-bootstrap-icons'
/**
* Renders the keyboard shortcuts overview modal.
* @param show True when the modal should be shown
* @param onHide Callback when the modal should be hidden
*/
export const ShortcutsModal: React.FC<ModalVisibilityProps> = ({ show, onHide }) => {
const title = useTranslatedText('shortcuts.title')
return (
<CommonModal titleIcon={IconQuestionCircle} show={show} onHide={onHide} showCloseButton={true} title={title}>
<Modal.Body>
<ShortcutsContent />
</Modal.Body>
</CommonModal>
)
}