feat: Backlinks (#979)
* feat: backlinks * feat: add backlinkDocumentId to documents.list * chore: refactor fix: create and delete backlink handling * fix: guard against self links * feat: basic frontend fix: race condition * styling * test: fix parse ids * self review * linting * feat: Improved link styling * fix: Increase clickable area at bottom of doc / between references * perf: global styles are SLOW
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const ClickablePadding = styled.div`
|
||||
min-height: 6em;
|
||||
min-height: 10em;
|
||||
cursor: ${({ onClick }) => (onClick ? 'text' : 'default')};
|
||||
${({ grow }) => grow && `flex-grow: 100;`};
|
||||
`;
|
||||
|
||||
@@ -2,14 +2,13 @@
|
||||
import * as React from 'react';
|
||||
import { observer } from 'mobx-react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import Document from 'models/Document';
|
||||
import { StarredIcon } from 'outline-icons';
|
||||
import styled, { withTheme } from 'styled-components';
|
||||
import { darken } from 'polished';
|
||||
import Flex from 'shared/components/Flex';
|
||||
import Highlight from 'components/Highlight';
|
||||
import { StarredIcon } from 'outline-icons';
|
||||
import PublishingInfo from './components/PublishingInfo';
|
||||
import PublishingInfo from 'components/PublishingInfo';
|
||||
import DocumentMenu from 'menus/DocumentMenu';
|
||||
import Document from 'models/Document';
|
||||
|
||||
type Props = {
|
||||
document: Document,
|
||||
@@ -45,8 +44,8 @@ const StyledDocumentMenu = styled(DocumentMenu)`
|
||||
|
||||
const DocumentLink = styled(Link)`
|
||||
display: block;
|
||||
margin: 0 -16px;
|
||||
padding: 10px 16px;
|
||||
margin: 8px -8px;
|
||||
padding: 6px 8px;
|
||||
border-radius: 8px;
|
||||
border: 2px solid transparent;
|
||||
max-height: 50vh;
|
||||
@@ -62,7 +61,6 @@ const DocumentLink = styled(Link)`
|
||||
&:active,
|
||||
&:focus {
|
||||
background: ${props => props.theme.listItemHoverBackground};
|
||||
border: 2px solid ${props => props.theme.listItemHoverBorder};
|
||||
outline: none;
|
||||
|
||||
${StyledStar}, ${StyledDocumentMenu} {
|
||||
@@ -73,10 +71,6 @@ const DocumentLink = styled(Link)`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:focus {
|
||||
border: 2px solid ${props => darken(0.5, props.theme.listItemHoverBorder)};
|
||||
}
|
||||
`;
|
||||
|
||||
const Heading = styled.h3`
|
||||
|
||||
@@ -3,8 +3,10 @@ import * as React from 'react';
|
||||
import { Redirect } from 'react-router-dom';
|
||||
import { observable } from 'mobx';
|
||||
import { observer } from 'mobx-react';
|
||||
import { withTheme } from 'styled-components';
|
||||
import { lighten } from 'polished';
|
||||
import styled, { withTheme } from 'styled-components';
|
||||
import RichMarkdownEditor from 'rich-markdown-editor';
|
||||
import Placeholder from 'rich-markdown-editor/lib/components/Placeholder';
|
||||
import { uploadFile } from 'utils/uploadFile';
|
||||
import isInternalUrl from 'utils/isInternalUrl';
|
||||
import Tooltip from 'components/Tooltip';
|
||||
@@ -79,7 +81,7 @@ class Editor extends React.Component<Props> {
|
||||
if (this.redirectTo) return <Redirect to={this.redirectTo} push />;
|
||||
|
||||
return (
|
||||
<RichMarkdownEditor
|
||||
<StyledEditor
|
||||
ref={this.props.forwardedRef}
|
||||
uploadImage={this.onUploadImage}
|
||||
onClickLink={this.onClickLink}
|
||||
@@ -92,6 +94,38 @@ class Editor extends React.Component<Props> {
|
||||
}
|
||||
}
|
||||
|
||||
const StyledEditor = styled(RichMarkdownEditor)`
|
||||
justify-content: start;
|
||||
|
||||
> div {
|
||||
transition: ${props => props.theme.backgroundTransition};
|
||||
}
|
||||
|
||||
p {
|
||||
${Placeholder} {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
p:nth-child(2):last-child {
|
||||
${Placeholder} {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
a {
|
||||
color: ${props => props.theme.link};
|
||||
border-bottom: 1px solid ${props => lighten(0.5, props.theme.link)};
|
||||
font-weight: 500;
|
||||
|
||||
&:hover {
|
||||
border-bottom: 1px solid ${props => props.theme.link};
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const EditorTooltip = props => <Tooltip offset={8} {...props} />;
|
||||
|
||||
export default withTheme(
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import { observer } from 'mobx-react';
|
||||
import { darken } from 'polished';
|
||||
import styled from 'styled-components';
|
||||
import { GoToIcon, CollectionIcon, PrivateCollectionIcon } from 'outline-icons';
|
||||
import Flex from 'shared/components/Flex';
|
||||
@@ -92,13 +91,8 @@ const ResultWrapperLink = styled(ResultWrapper.withComponent('a'))`
|
||||
&:active,
|
||||
&:focus {
|
||||
background: ${props => props.theme.listItemHoverBackground};
|
||||
border: 2px solid ${props => props.theme.listItemHoverBorder};
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
border: 2px solid ${props => darken(0.5, props.theme.listItemHoverBorder)};
|
||||
}
|
||||
`;
|
||||
|
||||
export default PathToDocument;
|
||||
|
||||
@@ -201,13 +201,21 @@ type Props = {
|
||||
offset?: number,
|
||||
};
|
||||
|
||||
const Tooltip = function({ offset = 0, ...rest }: Props) {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<GlobalStyles offset={offset} />
|
||||
<TooltipTrigger {...rest} />
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
class Tooltip extends React.Component<Props> {
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { offset = 0, ...rest } = this.props;
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<GlobalStyles offset={offset} />
|
||||
<TooltipTrigger {...rest} />
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Tooltip;
|
||||
|
||||
Reference in New Issue
Block a user