feat: Keyboard shortcut reference inside editor

This commit is contained in:
Tom Moor
2019-08-08 21:13:58 -07:00
parent 789a1acea1
commit a26ae119fe
7 changed files with 167 additions and 57 deletions

View File

@ -21,6 +21,8 @@ import Sidebar from 'components/Sidebar';
import SettingsSidebar from 'components/Sidebar/Settings';
import Modals from 'components/Modals';
import DocumentHistory from 'components/DocumentHistory';
import Modal from 'components/Modal';
import KeyboardShortcuts from 'scenes/KeyboardShortcuts';
import ErrorSuspended from 'scenes/ErrorSuspended';
import AuthStore from 'stores/AuthStore';
import UiStore from 'stores/UiStore';
@ -41,6 +43,7 @@ type Props = {
class Layout extends React.Component<Props> {
scrollable: ?HTMLDivElement;
@observable redirectTo: ?string;
@observable keyboardShortcutsOpen: boolean = false;
componentWillMount() {
this.updateBackground();
@ -54,6 +57,15 @@ class Layout extends React.Component<Props> {
}
}
@keydown('shift+/')
handleOpenKeyboardShortcuts() {
this.keyboardShortcutsOpen = true;
}
handleCloseKeyboardShortcuts = () => {
this.keyboardShortcutsOpen = false;
};
updateBackground() {
// ensure the wider page color always matches the theme
window.document.body.style.background = this.props.theme.background;
@ -71,11 +83,6 @@ class Layout extends React.Component<Props> {
this.redirectTo = homeUrl();
}
@keydown('shift+/')
openKeyboardShortcuts() {
this.props.ui.setActiveModal('keyboard-shortcuts');
}
render() {
const { auth, ui } = this.props;
const { user, team } = auth;
@ -118,6 +125,13 @@ class Layout extends React.Component<Props> {
</Switch>
</Container>
<Modals ui={ui} />
<Modal
isOpen={this.keyboardShortcutsOpen}
onRequestClose={this.handleCloseKeyboardShortcuts}
title="Keyboard shortcuts"
>
<KeyboardShortcuts />
</Modal>
<GlobalStyles />
</Container>
);

View File

@ -9,7 +9,6 @@ import CollectionDelete from 'scenes/CollectionDelete';
import CollectionExport from 'scenes/CollectionExport';
import DocumentDelete from 'scenes/DocumentDelete';
import DocumentShare from 'scenes/DocumentShare';
import KeyboardShortcuts from 'scenes/KeyboardShortcuts';
type Props = {
ui: UiStore,
@ -55,9 +54,6 @@ class Modals extends React.Component<Props> {
<Modal name="document-delete" title="Delete document">
<DocumentDelete onSubmit={this.handleClose} />
</Modal>
<Modal name="keyboard-shortcuts" title="Keyboard shortcuts">
<KeyboardShortcuts />
</Modal>
</span>
);
}

View File

@ -9,6 +9,7 @@ type Props = {
children: React.Node,
delay?: number,
className?: string,
block?: boolean,
};
class Tooltip extends React.Component<Props> {
@ -17,7 +18,15 @@ class Tooltip extends React.Component<Props> {
}
render() {
const { tooltip, delay = 50, children, className, ...rest } = this.props;
const {
tooltip,
delay = 50,
children,
block,
className,
...rest
} = this.props;
const Component = block ? 'div' : 'span';
return (
<StyledTippy
@ -30,7 +39,7 @@ class Tooltip extends React.Component<Props> {
inertia
{...rest}
>
<span className={className}>{children}</span>
<Component className={className}>{children}</Component>
</StyledTippy>
);
}

View File

@ -1,6 +1,7 @@
// @flow
import * as React from 'react';
import { Link } from 'react-router-dom';
import { observable } from 'mobx';
import { inject, observer } from 'mobx-react';
import { MoonIcon } from 'outline-icons';
import styled, { withTheme } from 'styled-components';
@ -8,6 +9,8 @@ import UiStore from 'stores/UiStore';
import AuthStore from 'stores/AuthStore';
import Flex from 'shared/components/Flex';
import { DropdownMenu, DropdownMenuItem } from 'components/DropdownMenu';
import Modal from 'components/Modal';
import KeyboardShortcuts from 'scenes/KeyboardShortcuts';
import {
developers,
changelog,
@ -26,19 +29,33 @@ type Props = {
@observer
class AccountMenu extends React.Component<Props> {
handleOpenKeyboardShortcuts = () => {
this.props.ui.setActiveModal('keyboard-shortcuts');
};
@observable keyboardShortcutsOpen: boolean = false;
handleLogout = () => {
this.props.auth.logout();
};
handleOpenKeyboardShortcuts = () => {
this.keyboardShortcutsOpen = true;
};
handleCloseKeyboardShortcuts = () => {
this.keyboardShortcutsOpen = false;
};
render() {
const { ui, theme } = this.props;
const isLightTheme = ui.theme === 'light';
return (
<React.Fragment>
<Modal
isOpen={this.keyboardShortcutsOpen}
onRequestClose={this.handleCloseKeyboardShortcuts}
title="Keyboard shortcuts"
>
<KeyboardShortcuts />
</Modal>
<DropdownMenu
style={{ marginRight: 10, marginTop: -10 }}
label={this.props.label}
@ -75,8 +92,11 @@ class AccountMenu extends React.Component<Props> {
</NightMode>
</DropdownMenuItem>
<hr />
<DropdownMenuItem onClick={this.handleLogout}>Log out</DropdownMenuItem>
<DropdownMenuItem onClick={this.handleLogout}>
Log out
</DropdownMenuItem>
</DropdownMenu>
</React.Fragment>
);
}
}

View File

@ -22,6 +22,7 @@ import { emojiToUrl } from 'utils/emoji';
import Header from './components/Header';
import DocumentMove from './components/DocumentMove';
import Branding from './components/Branding';
import KeyboardShortcuts from './components/KeyboardShortcuts';
import Backlinks from './components/Backlinks';
import ErrorBoundary from 'components/ErrorBoundary';
import LoadingPlaceholder from 'components/LoadingPlaceholder';
@ -426,7 +427,7 @@ class DocumentScene extends React.Component<Props> {
</MaxWidth>
</Container>
</Container>
{isShare && <Branding />}
{isShare ? <Branding /> : <KeyboardShortcuts />}
</ErrorBoundary>
);
}

View File

@ -0,0 +1,72 @@
// @flow
import * as React from 'react';
import styled from 'styled-components';
import breakpoint from 'styled-components-breakpoint';
import { observable } from 'mobx';
import { observer } from 'mobx-react';
import { KeyboardIcon } from 'outline-icons';
import Modal from 'components/Modal';
import Tooltip from 'components/Tooltip';
import KeyboardShortcuts from 'scenes/KeyboardShortcuts';
type Props = {};
@observer
class KeyboardShortcutsButton extends React.Component<Props> {
@observable keyboardShortcutsOpen: boolean = false;
handleOpenKeyboardShortcuts = () => {
this.keyboardShortcutsOpen = true;
};
handleCloseKeyboardShortcuts = () => {
this.keyboardShortcutsOpen = false;
};
render() {
return (
<React.Fragment>
<Modal
isOpen={this.keyboardShortcutsOpen}
onRequestClose={this.handleCloseKeyboardShortcuts}
title="Keyboard shortcuts"
>
<KeyboardShortcuts />
</Modal>
<Button onClick={this.handleOpenKeyboardShortcuts}>
<Tooltip tooltip="Keyboard shortcuts" placement="left" block>
<KeyboardIcon />
</Tooltip>
</Button>
</React.Fragment>
);
}
}
const Button = styled.button`
display: none;
position: fixed;
bottom: 0;
right: 0;
margin: 24px;
width: 24px;
height: 24px;
opacity: 0.8;
background: none;
line-height: 0;
border: 0;
&:hover {
opacity: 1;
}
${breakpoint('tablet')`
display: block;
`};
@media print {
display: none;
}
`;
export default KeyboardShortcutsButton;

View File

@ -10,10 +10,8 @@ function KeyboardShortcuts() {
return (
<Flex column>
<HelpText>
Outline is designed to be super fast and easy to use. All of your usual
keyboard shortcuts work here, and there
{"'"}
s Markdown too.
Outline is designed to be fast and easy to use. All of your usual
keyboard shortcuts work here, and theres Markdown too.
</HelpText>
<h2>Navigation</h2>