feat: Add keyboard shortcuts to tooltips

This commit is contained in:
Tom Moor
2019-08-28 23:30:27 -07:00
parent b56f8e7870
commit 579eaf325b
6 changed files with 74 additions and 76 deletions

View File

@ -51,7 +51,7 @@ const Modal = ({
<Content column>
{title && <h1>{title}</h1>}
<Close onClick={onRequestClose}>
<CloseIcon size={40} />
<CloseIcon size={40} color="currentColor" />
<Esc>esc</Esc>
</Close>
{children}
@ -98,8 +98,8 @@ const Close = styled.a`
position: fixed;
top: 16px;
right: 16px;
opacity: 0.5;
color: ${props => props.theme.textSecondary};
opacity: 0.75;
color: ${props => props.theme.text};
&:hover {
opacity: 1;

View File

@ -1,58 +0,0 @@
// @flow
import * as React from 'react';
import { observable } from 'mobx';
import { observer } from 'mobx-react';
import styled from 'styled-components';
import { CloseIcon } from 'outline-icons';
import Tooltip from './Tooltip';
import Flex from 'shared/components/Flex';
type Props = {
id: string,
children: React.Node,
disabled?: boolean,
};
@observer
class Tip extends React.Component<Props> {
@observable
isHidden: boolean = window.localStorage.getItem(this.storageId) === 'hidden';
get storageId() {
return `tip-${this.props.id}`;
}
hide = () => {
window.localStorage.setItem(this.storageId, 'hidden');
this.isHidden = true;
};
render() {
const { children } = this.props;
if (this.props.disabled || this.isHidden) return null;
return (
<Wrapper align="flex-start">
<span>{children}</span>
<Tooltip tooltip="Hide this message" placement="bottom">
<Close type="close" size={32} color="#000" onClick={this.hide} />
</Tooltip>
</Wrapper>
);
}
}
const Close = styled(CloseIcon)`
margin-top: 8px;
`;
const Wrapper = styled(Flex)`
background: ${props => props.theme.primary};
color: ${props => props.theme.text};
padding: 8px 16px;
border-radius: 4px;
font-weight: 400;
`;
export default Tip;

View File

@ -5,6 +5,7 @@ import Tippy from '@tippy.js/react';
type Props = {
tooltip: React.Node,
shortcut?: React.Node,
placement?: 'top' | 'bottom' | 'left' | 'right',
children: React.Node,
delay?: number,
@ -19,6 +20,7 @@ class Tooltip extends React.Component<Props> {
render() {
const {
shortcut,
tooltip,
delay = 50,
children,
@ -28,12 +30,22 @@ class Tooltip extends React.Component<Props> {
} = this.props;
const Component = block ? 'div' : 'span';
let content = tooltip;
if (shortcut) {
content = (
<React.Fragment>
{tooltip} &middot; <Shortcut>{shortcut}</Shortcut>
</React.Fragment>
);
}
return (
<StyledTippy
arrow
arrowType="round"
animation="shift-away"
content={tooltip}
content={content}
delay={delay}
duration={[200, 150]}
inertia
@ -45,6 +57,21 @@ class Tooltip extends React.Component<Props> {
}
}
const Shortcut = styled.kbd`
position: relative;
top: -2px;
display: inline-block;
padding: 2px 4px;
font: 10px 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier,
monospace;
line-height: 10px;
color: ${props => props.theme.tooltipBackground};
vertical-align: middle;
background-color: ${props => props.theme.tooltipText};
border-radius: 3px;
`;
const StyledTippy = styled(Tippy)`
font-size: 13px;
background-color: ${props => props.theme.tooltipBackground};

View File

@ -24,6 +24,7 @@ import Search from 'scenes/Search';
import CollectionMenu from 'menus/CollectionMenu';
import Actions, { Action, Separator } from 'components/Actions';
import Heading from 'components/Heading';
import Tooltip from 'components/Tooltip';
import CenteredContent from 'components/CenteredContent';
import { ListPlaceholder } from 'components/LoadingPlaceholder';
import Mask from 'components/Mask';
@ -104,9 +105,16 @@ class CollectionScene extends React.Component<Props> {
return (
<Actions align="center" justify="flex-end">
<Action>
<Tooltip
tooltip="New document"
shortcut="n"
delay={500}
placement="bottom"
>
<Button onClick={this.onNewDocument} icon={<PlusIcon />}>
New doc
</Button>
</Tooltip>
</Action>
<Separator />
<Action>

View File

@ -19,6 +19,7 @@ import DocumentMenu from 'menus/DocumentMenu';
import NewChildDocumentMenu from 'menus/NewChildDocumentMenu';
import DocumentShare from 'scenes/DocumentShare';
import Button from 'components/Button';
import Tooltip from 'components/Tooltip';
import Modal from 'components/Modal';
import Badge from 'components/Badge';
import Collaborators from 'components/Collaborators';
@ -182,6 +183,12 @@ class Header extends React.Component<Props> {
)}
{canEdit && (
<Action>
<Tooltip
tooltip="Edit document"
shortcut="e"
delay={500}
placement="bottom"
>
<Button
icon={<EditIcon />}
onClick={this.handleEdit}
@ -190,6 +197,7 @@ class Header extends React.Component<Props> {
>
Edit
</Button>
</Tooltip>
</Action>
)}
{canEdit &&
@ -198,9 +206,16 @@ class Header extends React.Component<Props> {
<NewChildDocumentMenu
document={document}
label={
<Tooltip
tooltip="New document"
shortcut="n"
delay={500}
placement="bottom"
>
<Button icon={<PlusIcon />} neutral>
New doc
</Button>
</Tooltip>
}
/>
</Action>

View File

@ -34,7 +34,13 @@ class KeyboardShortcutsButton extends React.Component<Props> {
<KeyboardShortcuts />
</Modal>
<Button onClick={this.handleOpenKeyboardShortcuts}>
<Tooltip tooltip="Keyboard shortcuts" placement="left" block>
<Tooltip
tooltip="Keyboard shortcuts"
shortcut="?"
placement="left"
delay={500}
block
>
<KeyboardIcon />
</Tooltip>
</Button>