feat: New keyboard shortcuts guide (#2051)

* feat: Add search

* feat: New design for keyboard shortcuts guide
feat: Include quick search
fix: Add missing shortcuts

* tweaks

* fix: Two other spots that should trigger guide-style instead of modal

* sink,lift -> indent,outdent

* fix: Animation should slide out as well as in
This commit is contained in:
Tom Moor
2021-04-21 18:15:07 -07:00
committed by GitHub
parent 50fdd73610
commit 2ffc0ae81c
12 changed files with 568 additions and 205 deletions

112
app/components/Guide.js Normal file
View File

@@ -0,0 +1,112 @@
// @flow
import { observer } from "mobx-react";
import * as React from "react";
import { Dialog, DialogBackdrop, useDialogState } from "reakit/Dialog";
import styled from "styled-components";
import Scrollable from "components/Scrollable";
import usePrevious from "hooks/usePrevious";
type Props = {|
children?: React.Node,
isOpen: boolean,
title?: string,
onRequestClose: () => void,
|};
const Guide = ({
children,
isOpen,
title = "Untitled",
onRequestClose,
...rest
}: Props) => {
const dialog = useDialogState({ animated: 250 });
const wasOpen = usePrevious(isOpen);
React.useEffect(() => {
if (!wasOpen && isOpen) {
dialog.show();
}
if (wasOpen && !isOpen) {
dialog.hide();
}
}, [dialog, wasOpen, isOpen]);
return (
<DialogBackdrop {...dialog}>
{(props) => (
<Backdrop {...props}>
<Dialog
{...dialog}
aria-label={title}
preventBodyScrollhideOnEsc
hide={onRequestClose}
>
{(props) => (
<Scene {...props} {...rest}>
<Content>
{title && <Header>{title}</Header>}
{children}
</Content>
</Scene>
)}
</Dialog>
</Backdrop>
)}
</DialogBackdrop>
);
};
const Header = styled.h1`
font-size: 18px;
margin-top: 0;
margin-bottom: 1em;
`;
const Backdrop = styled.div`
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: ${(props) => props.theme.backdrop} !important;
z-index: ${(props) => props.theme.depths.modalOverlay};
transition: opacity 200ms ease-in-out;
opacity: 0;
&[data-enter] {
opacity: 1;
}
`;
const Scene = styled.div`
position: absolute;
top: 0;
right: 0;
bottom: 0;
margin: 12px;
z-index: ${(props) => props.theme.depths.modal};
display: flex;
justify-content: center;
align-items: flex-start;
width: 350px;
background: ${(props) => props.theme.background};
transition: ${(props) => props.theme.backgroundTransition};
border-radius: 8px;
outline: none;
opacity: 0;
transform: translateX(16px);
transition: transform 250ms ease, opacity 250ms ease;
&[data-enter] {
opacity: 1;
transform: translateX(0px);
}
`;
const Content = styled(Scrollable)`
width: 100%;
padding: 16px;
`;
export default observer(Guide);

View File

@@ -35,6 +35,10 @@ const RealInput = styled.input`
color: ${(props) => props.theme.placeholder};
}
&::-webkit-search-cancel-button {
-webkit-appearance: none;
}
${breakpoint("mobile", "tablet")`
font-size: 16px;
`};

View File

@@ -20,6 +20,9 @@ type Props = {
label?: string,
labelHidden?: boolean,
collectionId?: string,
redirectDisabled?: boolean,
maxWidth?: string,
onChange: (event: SyntheticInputEvent<>) => mixed,
t: TFunction,
};
@@ -56,7 +59,7 @@ class InputSearch extends React.Component<Props> {
};
render() {
const { t } = this.props;
const { t, redirectDisabled, onChange } = this.props;
const { theme, placeholder = `${t("Search")}` } = this.props;
return (
@@ -64,7 +67,8 @@ class InputSearch extends React.Component<Props> {
ref={(ref) => (this.input = ref)}
type="search"
placeholder={placeholder}
onInput={this.handleSearchInput}
onInput={redirectDisabled ? undefined : this.handleSearchInput}
onChange={onChange}
icon={
<SearchIcon
color={this.focused ? theme.inputBorderFocused : theme.inputBorder}
@@ -72,6 +76,7 @@ class InputSearch extends React.Component<Props> {
}
label={this.props.label}
labelHidden={this.props.labelHidden}
maxWidth={this.props.maxWidth}
onFocus={this.handleFocus}
onBlur={this.handleBlur}
margin={0}
@@ -81,7 +86,7 @@ class InputSearch extends React.Component<Props> {
}
const InputMaxWidth = styled(Input)`
max-width: 30vw;
max-width: ${(props) => props.maxWidth};
`;
export default withTranslation()<InputSearch>(

View File

@@ -24,8 +24,8 @@ import KeyboardShortcuts from "scenes/KeyboardShortcuts";
import Button from "components/Button";
import DocumentHistory from "components/DocumentHistory";
import Flex from "components/Flex";
import Guide from "components/Guide";
import { LoadingIndicatorBar } from "components/LoadingIndicator";
import Modal from "components/Modal";
import Sidebar from "components/Sidebar";
import SettingsSidebar from "components/Sidebar/Settings";
import SkipNavContent from "components/SkipNavContent";
@@ -161,13 +161,13 @@ class Layout extends React.Component<Props> {
/>
</Switch>
</Container>
<Modal
<Guide
isOpen={this.keyboardShortcutsOpen}
onRequestClose={this.handleCloseKeyboardShortcuts}
title={t("Keyboard shortcuts")}
>
<KeyboardShortcuts />
</Modal>
</Guide>
</Container>
);
}