This commit is contained in:
Tom Moor 2017-10-21 14:05:20 -07:00
parent 56d27400ac
commit 38228d0315
28 changed files with 304 additions and 136 deletions

View File

@ -1,6 +1,7 @@
// @flow
import React from 'react';
import styled from 'styled-components';
import Flex from 'components/Flex';
import { color } from 'styles/constants';
const DropdownMenuItem = ({
@ -17,13 +18,12 @@ const DropdownMenuItem = ({
);
};
const MenuItem = styled.div`
const MenuItem = styled(Flex)`
margin: 0;
padding: 5px 10px;
height: 32px;
color: ${color.slateDark};
display: flex;
justify-content: left;
align-items: center;
cursor: pointer;
@ -41,6 +41,10 @@ const MenuItem = styled.div`
&:hover {
color: ${color.white};
background: ${color.primary};
svg {
fill: ${color.white};
}
}
`;

View File

@ -7,7 +7,7 @@ import { observable } from 'mobx';
import { observer } from 'mobx-react';
import styled from 'styled-components';
import { color } from 'styles/constants';
import Icon from 'components/Icon';
import PlusIcon from 'components/Icon/PlusIcon';
import BlockMenu from 'menus/BlockMenu';
import type { State } from '../types';
@ -151,7 +151,7 @@ export default class BlockInsert extends Component {
accept="image/*"
/>
<BlockMenu
label={<Icon type="PlusCircle" />}
label={<PlusIcon />}
onPickImage={this.onPickImage}
onInsertList={ev =>
this.insertBlock(ev, {
@ -183,11 +183,10 @@ const Trigger = styled.div`
z-index: 1;
opacity: 0;
background-color: ${color.white};
border-radius: 4px;
transition: opacity 250ms ease-in-out, transform 250ms ease-in-out;
line-height: 0;
height: 16px;
width: 16px;
margin-top: -2px;
margin-left: -4px;
transform: scale(.9);
${({ active }) => active && `

View File

@ -144,7 +144,7 @@ const Menu = styled.div`
top: -10000px;
left: -10000px;
opacity: 0;
background-color: #222;
background-color: #2F3336;
border-radius: 4px;
transition: opacity 250ms ease-in-out, transform 250ms ease-in-out;
line-height: 0;

View File

@ -3,7 +3,7 @@ import React from 'react';
import styled from 'styled-components';
import { fontWeight, color } from 'styles/constants';
import Document from 'models/Document';
import Icon from 'components/Icon';
import GoToIcon from 'components/Icon/GoToIcon';
type Props = {
innerRef?: Function,
@ -14,7 +14,7 @@ type Props = {
function DocumentResult({ document, ...rest }: Props) {
return (
<ListItem {...rest} href="">
<i><Icon type="ChevronRight" light /></i>
<i><GoToIcon light /></i>
{document.title}
</ListItem>
);

View File

@ -1,5 +1,6 @@
// @flow
import React, { Component } from 'react';
import styled from 'styled-components';
import type { State } from '../../../types';
import ToolbarButton from './ToolbarButton';
import BoldIcon from 'components/Icon/BoldIcon';
@ -10,7 +11,7 @@ import ItalicIcon from 'components/Icon/ItalicIcon';
import LinkIcon from 'components/Icon/LinkIcon';
import StrikethroughIcon from 'components/Icon/StrikethroughIcon';
export default class FormattingToolbar extends Component {
class FormattingToolbar extends Component {
props: {
state: State,
onChange: Function,
@ -92,9 +93,11 @@ export default class FormattingToolbar extends Component {
{this.renderMarkButton('bold', BoldIcon)}
{this.renderMarkButton('italic', ItalicIcon)}
{this.renderMarkButton('deleted', StrikethroughIcon)}
{this.renderMarkButton('code', CodeIcon)}
<Separator />
{this.renderBlockButton('heading1', Heading1Icon)}
{this.renderBlockButton('heading2', Heading2Icon)}
{this.renderMarkButton('code', CodeIcon)}
<Separator />
<ToolbarButton onMouseDown={this.onCreateLink}>
<LinkIcon light />
</ToolbarButton>
@ -102,3 +105,14 @@ export default class FormattingToolbar extends Component {
);
}
}
const Separator = styled.div`
height: 100%;
width: 1px;
background: #FFF;
opacity: .2;
display: inline-block;
margin-left: 10px;
`;
export default FormattingToolbar;

View File

@ -0,0 +1,28 @@
// @flow
import React from 'react';
import Icon from './Icon';
import type { Props } from './Icon';
export default function CheckboxIcon({
checked,
...rest
}: Props & { checked: boolean }) {
return (
<Icon {...rest}>
<svg
fill="#000000"
height="24"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
{checked
? <path d="M8,5 L16,5 L16,5 C17.6568542,5 19,6.34314575 19,8 L19,16 C19,17.6568542 17.6568542,19 16,19 L8,19 L8,19 C6.34314575,19 5,17.6568542 5,16 L5,8 L5,8 C5,6.34314575 6.34314575,5 8,5 L8,5 Z M10.958729,12.8883948 L9.26824635,10.8598156 C8.91468227,10.4355387 8.28411757,10.3782146 7.85984067,10.7317787 C7.43556378,11.0853428 7.37823971,11.7159075 7.73180379,12.1401844 L10.2318038,15.1401844 C10.6450125,15.6360348 11.4127535,15.616362 11.8000251,15.1 L16.3000251,9.1 C16.6313959,8.6581722 16.5418529,8.03137085 16.1000251,7.7 C15.6581973,7.36862915 15.0313959,7.4581722 14.7000251,7.9 L10.958729,12.8883948 Z" />
: <path
d="M8,5 L16,5 L16,5 C17.6568542,5 19,6.34314575 19,8 L19,16 C19,17.6568542 17.6568542,19 16,19 L8,19 L8,19 C6.34314575,19 5,17.6568542 5,16 L5,8 L5,8 C5,6.34314575 6.34314575,5 8,5 L8,5 Z M8,7 C7.44771525,7 7,7.44771525 7,8 L7,16 C7,16.5522847 7.44771525,17 8,17 L16,17 C16.5522847,17 17,16.5522847 17,16 L17,8 C17,7.44771525 16.5522847,7 16,7 L8,7 Z"
id="path-1"
/>}
</svg>
</Icon>
);
}

View File

@ -1,20 +0,0 @@
// @flow
import React from 'react';
import Icon from './Icon';
import type { Props } from './Icon';
export default function NextIcon(props: Props) {
return (
<Icon {...props}>
<svg
fill="#000000"
height="24"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M8.20710678,8.79289322 C7.81658249,8.40236893 7.18341751,8.40236893 6.79289322,8.79289322 C6.40236893,9.18341751 6.40236893,9.81658249 6.79289322,10.2071068 L11.7928932,15.2071068 C12.1834175,15.5976311 12.8165825,15.5976311 13.2071068,15.2071068 L18.2071068,10.2071068 C18.5976311,9.81658249 18.5976311,9.18341751 18.2071068,8.79289322 C17.8165825,8.40236893 17.1834175,8.40236893 16.7928932,8.79289322 L12.5,13.0857864 L8.20710678,8.79289322 Z" />
</svg>
</Icon>
);
}

View File

@ -0,0 +1,23 @@
// @flow
import React from 'react';
import Icon from './Icon';
import type { Props } from './Icon';
export default function CloseIcon(props: Props) {
return (
<Icon {...props}>
<svg
fill="#000000"
height="24"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12,10.5857864 L8.70710678,7.29289322 C8.31658249,6.90236893 7.68341751,6.90236893 7.29289322,7.29289322 C6.90236893,7.68341751 6.90236893,8.31658249 7.29289322,8.70710678 L10.5857864,12 L7.29289322,15.2928932 C6.90236893,15.6834175 6.90236893,16.3165825 7.29289322,16.7071068 C7.68341751,17.0976311 8.31658249,17.0976311 8.70710678,16.7071068 L12,13.4142136 L15.2928932,16.7071068 C15.6834175,17.0976311 16.3165825,17.0976311 16.7071068,16.7071068 C17.0976311,16.3165825 17.0976311,15.6834175 16.7071068,15.2928932 L13.4142136,12 L16.7071068,8.70710678 C17.0976311,8.31658249 17.0976311,7.68341751 16.7071068,7.29289322 C16.3165825,6.90236893 15.6834175,6.90236893 15.2928932,7.29289322 L12,10.5857864 Z"
id="path-1"
/>
</svg>
</Icon>
);
}

View File

@ -14,7 +14,6 @@ export default function CodeIcon(props: Props) {
xmlns="http://www.w3.org/2000/svg"
>
<path d="M11.9805807,17.1961161 C11.8722687,17.7376759 11.3454436,18.0888926 10.8038839,17.9805807 C10.2623241,17.8722687 9.91110737,17.3454436 10.0194193,16.8038839 L12.0194193,6.80388386 C12.1277313,6.26232411 12.6545564,5.91110737 13.1961161,6.01941932 C13.7376759,6.12773127 14.0888926,6.65455638 13.9805807,7.19611614 L11.9805807,17.1961161 Z M6.41421356,12 L8.70710678,14.2928932 C9.09763107,14.6834175 9.09763107,15.3165825 8.70710678,15.7071068 C8.31658249,16.0976311 7.68341751,16.0976311 7.29289322,15.7071068 L4.29289322,12.7071068 C3.90236893,12.3165825 3.90236893,11.6834175 4.29289322,11.2928932 L7.29289322,8.29289322 C7.68341751,7.90236893 8.31658249,7.90236893 8.70710678,8.29289322 C9.09763107,8.68341751 9.09763107,9.31658249 8.70710678,9.70710678 L6.41421356,12 Z M15.2928932,14.2928932 L17.5857864,12 L15.2928932,9.70710678 C14.9023689,9.31658249 14.9023689,8.68341751 15.2928932,8.29289322 C15.6834175,7.90236893 16.3165825,7.90236893 16.7071068,8.29289322 L19.7071068,11.2928932 C20.0976311,11.6834175 20.0976311,12.3165825 19.7071068,12.7071068 L16.7071068,15.7071068 C16.3165825,16.0976311 15.6834175,16.0976311 15.2928932,15.7071068 C14.9023689,15.3165825 14.9023689,14.6834175 15.2928932,14.2928932 Z" />
{' '}
</svg>
</Icon>
);

View File

@ -0,0 +1,23 @@
// @flow
import React from 'react';
import Icon from './Icon';
import type { Props } from './Icon';
export default function GoToIcon(props: Props) {
return (
<Icon {...props}>
<svg
fill="#000000"
height="24"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M14.080855,4.6060807 L8.08085497,18.6060807 C7.86329935,19.1137105 8.09845092,19.7015894 8.6060807,19.919145 C9.11371048,20.1367007 9.70158941,19.9015491 9.91914503,19.3939193 L15.919145,5.3939193 C16.1367007,4.88628952 15.9015491,4.29841059 15.3939193,4.08085497 C14.8862895,3.86329935 14.2984106,4.09845092 14.080855,4.6060807 Z"
id="path-1"
/>
</svg>
</Icon>
);
}

View File

@ -13,7 +13,10 @@ export default function HorizontalRuleIcon(props: Props) {
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M5,11 L19,11 C19.5522847,11 20,11.4477153 20,12 C20,12.5522847 19.5522847,13 19,13 L5,13 C4.44771525,13 4,12.5522847 4,12 C4,11.4477153 4.44771525,11 5,11 L5,11 Z M8,7 L16,7 L16,5 C16,4.44771525 16.4477153,4 17,4 C17.5522847,4 18,4.44771525 18,5 L18,8 C18,8.55228475 17.5522847,9 17,9 L7,9 C6.44771525,9 6,8.55228475 6,8 L6,5 C6,4.44771525 6.44771525,4 7,4 C7.55228475,4 8,4.44771525 8,5 L8,7 Z M8,17 L8,19 C8,19.5522847 7.55228475,20 7,20 C6.44771525,20 6,19.5522847 6,19 L6,16 C6,15.4477153 6.44771525,15 7,15 L17,15 C17.5522847,15 18,15.4477153 18,16 L18,19 C18,19.5522847 17.5522847,20 17,20 C16.4477153,20 16,19.5522847 16,19 L16,17 L8,17 Z" />
<path
d="M5,11 L19,11 C19.5522847,11 20,11.4477153 20,12 C20,12.5522847 19.5522847,13 19,13 L5,13 C4.44771525,13 4,12.5522847 4,12 C4,11.4477153 4.44771525,11 5,11 L5,11 Z M7,6 L17,6 C17.5522847,6 18,6.44771525 18,7 L18,8 C18,8.55228475 17.5522847,9 17,9 L7,9 C6.44771525,9 6,8.55228475 6,8 L6,7 L6,7 C6,6.44771525 6.44771525,6 7,6 Z M7,15 L17,15 C17.5522847,15 18,15.4477153 18,16 L18,17 C18,17.5522847 17.5522847,18 17,18 L7,18 C6.44771525,18 6,17.5522847 6,17 L6,16 C6,15.4477153 6.44771525,15 7,15 Z"
id="path-1"
/>
</svg>
</Icon>
);

View File

@ -2,12 +2,14 @@
import React from 'react';
import styled from 'styled-components';
import { color } from 'styles/constants';
import * as Icons from 'react-feather';
export type Props = {
className?: string,
type?: string,
light?: boolean,
black?: boolean,
primary?: boolean,
color?: string,
};
type BaseProps = {
@ -17,37 +19,27 @@ type BaseProps = {
export default function Icon({
children,
light,
black,
primary,
color,
type,
...rest
}: Props & BaseProps) {
if (type) {
children = React.createElement(Icons[type], {
size: '1em',
color: light ? color.white : undefined,
...rest,
});
return (
<FeatherWrapper {...rest}>
{children}
</FeatherWrapper>
);
}
return (
<Wrapper light={light} {...rest}>
<Wrapper light={light} black={black} primary={primary} {...rest}>
{children}
</Wrapper>
);
}
const FeatherWrapper = styled.span`
position: relative;
top: .1em;
`;
const Wrapper = styled.span`
svg {
fill: ${props => (props.light ? color.white : color.black)}
fill: ${props => {
if (props.color) return props.color;
if (props.light) return color.white;
if (props.black) return color.black;
if (props.primary) return color.primary;
return color.slateDark;
}};
}
`;

View File

@ -0,0 +1,23 @@
// @flow
import React from 'react';
import Icon from './Icon';
import type { Props } from './Icon';
export default function MoreIcon(props: Props) {
return (
<Icon {...props}>
<svg
fill="#000000"
height="24"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12,14 C10.8954305,14 10,13.1045695 10,12 C10,10.8954305 10.8954305,10 12,10 C13.1045695,10 14,10.8954305 14,12 C14,13.1045695 13.1045695,14 12,14 Z M18,14 C16.8954305,14 16,13.1045695 16,12 C16,10.8954305 16.8954305,10 18,10 C19.1045695,10 20,10.8954305 20,12 C20,13.1045695 19.1045695,14 18,14 Z M6,14 C4.8954305,14 4,13.1045695 4,12 C4,10.8954305 4.8954305,10 6,10 C7.1045695,10 8,10.8954305 8,12 C8,13.1045695 7.1045695,14 6,14 Z"
id="path-1"
/>
</svg>
</Icon>
);
}

View File

@ -0,0 +1,23 @@
// @flow
import React from 'react';
import Icon from './Icon';
import type { Props } from './Icon';
export default function NewDocumentIcon(props: Props) {
return (
<Icon {...props}>
<svg
fill="#000000"
height="24"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M19,18 L20,18 C20.5522847,18 21,18.4477153 21,19 C21,19.5522847 20.5522847,20 20,20 L19,20 L19,21 C19,21.5522847 18.5522847,22 18,22 C17.4477153,22 17,21.5522847 17,21 L17,20 L16,20 C15.4477153,20 15,19.5522847 15,19 C15,18.4477153 15.4477153,18 16,18 L17,18 L17,17 C17,16.4477153 17.4477153,16 18,16 C18.5522847,16 19,16.4477153 19,17 L19,18 Z M13.1000181,20 L7,20 C5.8954305,20 5,19.1045695 5,18 L5,6 L5,6 C5,4.8954305 5.8954305,4 7,4 L7,4 L14.5,4 L12,4 L12,9 C12,10.1045695 12.8954305,11 14,11 L19,11 L19,8.5 L19,14.1000181 C18.6768901,14.0344303 18.3424658,14 18,14 C15.2385763,14 13,16.2385763 13,19 C13,19.3424658 13.0344303,19.6768901 13.1000181,20 Z M14,4 L19,9 L14,9 L14,4 Z"
id="path-1"
/>
</svg>
</Icon>
);
}

View File

@ -0,0 +1,20 @@
// @flow
import React from 'react';
import Icon from './Icon';
import type { Props } from './Icon';
export default function PlusIcon(props: Props) {
return (
<Icon {...props}>
<svg
fill="#000000"
height="24"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M13,11 L13,6 C13,5.44771525 12.5522847,5 12,5 C11.4477153,5 11,5.44771525 11,6 L11,6 L11,11 L6,11 C5.44771525,11 5,11.4477153 5,12 C5,12.5522847 5.44771525,13 6,13 L11,13 L11,18 C11,18.5522847 11.4477153,19 12,19 C12.5522847,19 13,18.5522847 13,18 L13,13 L18,13 C18.5522847,13 19,12.5522847 19,12 C19,11.4477153 18.5522847,11 18,11 L13,11 Z" />
</svg>
</Icon>
);
}

View File

@ -0,0 +1,23 @@
// @flow
import React from 'react';
import Icon from './Icon';
import type { Props } from './Icon';
export default function TableIcon(props: Props) {
return (
<Icon {...props}>
<svg
fill="#000000"
height="24"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6,5 L18,5 C19.1045695,5 20,5.8954305 20,7 L20,17 C20,18.1045695 19.1045695,19 18,19 L6,19 C4.8954305,19 4,18.1045695 4,17 L4,7 C4,5.8954305 4.8954305,5 6,5 Z M6,7 L6,9 L11,9 L11,7 L6,7 Z M13,7 L13,9 L18,9 L18,7 L13,7 Z M6,11 L6,13 L11,13 L11,11 L6,11 Z M13,11 L13,13 L18,13 L18,11 L13,11 Z M6,15 L6,17 L11,17 L11,15 L6,15 Z M13,15 L13,17 L18,17 L18,15 L13,15 Z"
id="path-1"
/>
</svg>
</Icon>
);
}

View File

@ -13,7 +13,10 @@ export default function TodoListIcon(props: Props) {
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M8,5 L16,5 L16,5 C17.6568542,5 19,6.34314575 19,8 L19,16 C19,17.6568542 17.6568542,19 16,19 L8,19 L8,19 C6.34314575,19 5,17.6568542 5,16 L5,8 L5,8 C5,6.34314575 6.34314575,5 8,5 L8,5 Z M10.958729,12.8883948 L9.26824635,10.8598156 C8.91468227,10.4355387 8.28411757,10.3782146 7.85984067,10.7317787 C7.43556378,11.0853428 7.37823971,11.7159075 7.73180379,12.1401844 L10.2318038,15.1401844 C10.6450125,15.6360348 11.4127535,15.616362 11.8000251,15.1 L16.3000251,9.1 C16.6313959,8.6581722 16.5418529,8.03137085 16.1000251,7.7 C15.6581973,7.36862915 15.0313959,7.4581722 14.7000251,7.9 L10.958729,12.8883948 Z" />
<path
d="M9.99992841,5.99992841 L19.0000716,5.99992841 L19.0000716,5.99992841 C19.5523168,5.99992841 20,6.4476116 20,6.99985681 L20,6.99985681 C20,7.55210202 19.5523168,7.99978522 19.0000716,7.99978522 L9.99992841,7.99978522 L9.99992841,7.99978522 C9.4476832,7.99978522 9,7.55210202 9,6.99985681 C9,6.4476116 9.4476832,5.99992841 9.99992841,5.99992841 L9.99992841,5.99992841 Z M9.99992841,15.9992125 L19.0000716,15.9992125 L19.0000716,15.9992125 C19.5523168,15.9992125 20,16.4468957 20,16.9991409 L20,16.9991409 L20,16.9991409 C20,17.5513861 19.5523168,17.9990693 19.0000716,17.9990693 L9.99992841,17.9990693 C9.4476832,17.9990693 9,17.5513861 9,16.9991409 C9,16.4468957 9.4476832,15.9992125 9.99992841,15.9992125 Z M9.99992841,10.9995704 L19.0000716,10.9995704 L19.0000716,10.9995704 C19.5523168,10.9995704 20,11.4472536 20,11.9994988 L20,11.9994988 C20,12.5517441 19.5523168,12.9994273 19.0000716,12.9994273 L9.99992841,12.9994273 C9.4476832,12.9994273 9,12.5517441 9,11.9994988 C9,11.4472536 9.4476832,10.9995704 9.99992841,10.9995704 Z M5.22935099,7.69420576 L7.09998441,5.20002786 C7.26566855,4.97911569 7.57906677,4.93434451 7.79997895,5.10002864 C8.02089112,5.26571278 8.0656623,5.579111 7.89997817,5.80002318 L5.64999574,8.79999974 C5.45636149,9.05817875 5.07249394,9.06801504 4.86589123,8.82009178 L3.61590099,7.3201035 C3.43912033,7.10796671 3.46778214,6.79268682 3.67991893,6.61590616 C3.89205572,6.4391255 4.20733561,6.46778731 4.38411627,6.6799241 L5.22935099,7.69420576 Z M5.22935099,12.6942058 L7.09998441,10.2000279 C7.26566855,9.97911569 7.57906677,9.93434451 7.79997895,10.1000286 C8.02089112,10.2657128 8.0656623,10.579111 7.89997817,10.8000232 L5.64999574,13.7999997 C5.45636149,14.0581787 5.07249394,14.068015 4.86589123,13.8200918 L3.61590099,12.3201035 C3.43912033,12.1079667 3.46778214,11.7926868 3.67991893,11.6159062 C3.89205572,11.4391255 4.20733561,11.4677873 4.38411627,11.6799241 L5.22935099,12.6942058 Z M5.22935099,17.6942058 L7.09998441,15.2000279 C7.26566855,14.9791157 7.57906677,14.9343445 7.79997895,15.1000286 C8.02089112,15.2657128 8.0656623,15.579111 7.89997817,15.8000232 L5.64999574,18.7999997 C5.45636149,19.0581787 5.07249394,19.068015 4.86589123,18.8200918 L3.61590099,17.3201035 C3.43912033,17.1079667 3.46778214,16.7926868 3.67991893,16.6159062 C3.89205572,16.4391255 4.20733561,16.4677873 4.38411627,16.6799241 L5.22935099,17.6942058 Z"
id="path-1"
/>
</svg>
</Icon>
);

View File

@ -12,7 +12,9 @@ import { documentEditUrl, homeUrl, searchUrl } from 'utils/routeHelpers';
import Avatar from 'components/Avatar';
import { LoadingIndicatorBar } from 'components/LoadingIndicator';
import Scrollable from 'components/Scrollable';
import Icon from 'components/Icon';
import HomeIcon from 'components/Icon/HomeIcon';
import SearchIcon from 'components/Icon/SearchIcon';
import StarredIcon from 'components/Icon/StarredIcon';
import Toasts from 'components/Toasts';
import AccountMenu from 'menus/AccountMenu';
@ -127,14 +129,14 @@ type Props = {
<Flex auto column>
<Scrollable innerRef={this.setScrollableRef}>
<LinkSection>
<SidebarLink to="/dashboard">
<Icon type="Home" /> Home
<SidebarLink to="/dashboard" icon={<HomeIcon />}>
Home
</SidebarLink>
<SidebarLink to="/search">
<Icon type="Search" /> Search
<SidebarLink to="/search" icon={<SearchIcon />}>
Search
</SidebarLink>
<SidebarLink to="/starred">
<Icon type="Star" /> Starred
<SidebarLink to="/starred" icon={<StarredIcon />}>
Starred
</SidebarLink>
</LinkSection>
<LinkSection>

View File

@ -8,7 +8,8 @@ import { color, fontWeight } from 'styles/constants';
import SidebarLink from './SidebarLink';
import DropToImport from 'components/DropToImport';
import Icon from 'components/Icon';
import PlusIcon from 'components/Icon/PlusIcon';
import CollectionIcon from 'components/Icon/CollectionIcon';
import CollectionMenu from 'menus/CollectionMenu';
import CollectionsStore from 'stores/CollectionsStore';
@ -52,8 +53,11 @@ type Props = {
))}
{collections.isLoaded &&
<SidebarLink onClick={this.props.onCreateCollection}>
<Icon type="Plus" /> Add new collection
<SidebarLink
onClick={this.props.onCreateCollection}
icon={<PlusIcon />}
>
New collection
</SidebarLink>}
</Flex>
);
@ -77,6 +81,7 @@ type Props = {
ui,
activeDocumentRef,
} = this.props;
const expanded = collection.id === ui.activeCollectionId;
return (
<StyledDropToImport
@ -87,7 +92,11 @@ type Props = {
menuOpen={this.menuOpen}
dropzoneRef={ref => (this.dropzoneRef = ref)}
>
<SidebarLink key={collection.id} to={collection.url}>
<SidebarLink
key={collection.id}
to={collection.url}
icon={<CollectionIcon expanded={expanded} />}
>
<Flex justify="space-between">
{collection.name}
@ -103,7 +112,7 @@ type Props = {
</CollectionAction>
</Flex>
{collection.id === ui.activeCollectionId &&
{expanded &&
<Children column>
{collection.documents.map(document => (
<DocumentLink
@ -139,12 +148,11 @@ const DocumentLink = observer(
}: DocumentLinkProps) => {
const isActiveDocument =
activeDocument && activeDocument.id === document.id;
const showChildren =
activeDocument &&
const showChildren = !!(activeDocument &&
(activeDocument.pathToDocument
.map(entry => entry.id)
.includes(document.id) ||
isActiveDocument);
isActiveDocument));
return (
<Flex
@ -185,6 +193,8 @@ const DocumentLink = observer(
);
const CollectionAction = styled.a`
position: absolute;
right: 0;
color: ${color.slate};
svg { opacity: .75; }
@ -206,11 +216,12 @@ const StyledDropToImport = styled(DropToImport)`
`;
const Header = styled(Flex)`
font-size: 11px;
font-size: 12px;
font-weight: ${fontWeight.semiBold};
text-transform: uppercase;
color: ${color.slate};
letter-spacing: 0.04em;
margin-bottom: 4px;
`;
const Children = styled(Flex)`

View File

@ -3,9 +3,8 @@ import React from 'react';
import { NavLink } from 'react-router-dom';
import { color, fontWeight } from 'styles/constants';
import styled from 'styled-components';
import Flex from 'components/Flex';
import ChevronIcon from 'components/Icon/ChevronIcon';
import CollapsedIcon from 'components/Icon/CollapsedIcon';
const activeStyle = {
color: color.black,
@ -15,12 +14,30 @@ const activeStyle = {
// This is a hack for `styleComponent()` as NavLink fails to render without `to` prop
const StyleableDiv = props => <div {...props} />;
const StyledGoTo = styled(CollapsedIcon)`
margin-right: -10px;
svg {
margin-bottom: -4px;
margin-right: 6px;
${({ expanded }) => !expanded && 'transform: rotate(-90deg);'}
}
`;
const IconWrapper = styled.span`
margin-left: -4px;
margin-right: 4px;
height: 24px;
`;
const styleComponent = component => styled(component)`
display: flex;
width: 100%;
position: relative;
overflow: hidden;
text-overflow: ellipsis;
padding: 5px 0;
padding: 4px 0;
margin-left: ${({ hasChildren }) => (hasChildren ? '-20px;' : '0')};
color: ${color.slateDark};
font-size: 15px;
@ -30,38 +47,36 @@ const styleComponent = component => styled(component)`
color: ${color.text};
}
&.active ${StyledChevron} svg {
fill: ${activeStyle.color};
&.active {
svg {
fill: ${activeStyle.color}
}
}
`;
function SidebarLink(props: Object) {
const Component = styleComponent(props.to ? NavLink : StyleableDiv);
type Props = {
to?: string,
onClick?: SyntheticEvent => *,
children?: React$Element<*>,
icon?: React$Element<*>,
hasChildren?: boolean,
expanded?: boolean,
};
function SidebarLink({ icon, children, expanded, ...rest }: Props) {
const Component = styleComponent(rest.to ? NavLink : StyleableDiv);
return (
<Flex>
<Component exact activeStyle={activeStyle} {...props}>
{props.hasChildren && <StyledChevron expanded={props.expanded} />}
<Content>{props.children}</Content>
<Component exact activeStyle={activeStyle} {...rest}>
{icon && <IconWrapper>{icon}</IconWrapper>}
{rest.hasChildren && <StyledGoTo expanded={expanded} />}
<Content>{children}</Content>
</Component>
</Flex>
);
}
const StyledChevron = styled(ChevronIcon)`
margin-right: -10px;
svg {
height: 18px;
margin-bottom: -4px;
margin-right: 6px;
fill: ${color.slateDark};
${({ expanded }) => expanded && 'transform: rotate(90deg);'}
}
`;
const Content = styled.div`
width: 100%;
`;

View File

@ -5,7 +5,7 @@ import styled from 'styled-components';
import ReactModal from 'react-modal';
import { color } from 'styles/constants';
import { fadeAndScaleIn } from 'styles/animations';
import Icon from 'components/Icon';
import CloseIcon from 'components/Icon/CloseIcon';
import Flex from 'components/Flex';
type Props = {
@ -33,7 +33,7 @@ const Modal = ({
>
<Content column>
{title && <h1>{title}</h1>}
<Close onClick={onRequestClose}><Icon type="X" size={32} /></Close>
<Close onClick={onRequestClose}><CloseIcon size={32} /></Close>
{children}
</Content>
</StyledModal>

View File

@ -1,17 +1,16 @@
// @flow
import React, { Component } from 'react';
import { inject, observer } from 'mobx-react';
import styled from 'styled-components';
import Collection from 'models/Collection';
import UiStore from 'stores/UiStore';
import Icon from 'components/Icon';
import MoreIcon from 'components/Icon/MoreIcon';
import Flex from 'components/Flex';
import { DropdownMenu, DropdownMenuItem } from 'components/DropdownMenu';
@observer class CollectionMenu extends Component {
props: {
label?: React$Element<any>,
label?: React$Element<*>,
onOpen?: () => void,
onClose?: () => void,
onImport?: () => void,
@ -41,7 +40,7 @@ import { DropdownMenu, DropdownMenuItem } from 'components/DropdownMenu';
return (
<DropdownMenu
label={label || <MoreIcon type="MoreHorizontal" />}
label={label || <MoreIcon />}
onOpen={onOpen}
onClose={onClose}
>
@ -53,17 +52,13 @@ import { DropdownMenu, DropdownMenuItem } from 'components/DropdownMenu';
<DropdownMenuItem onClick={onImport}>
Import document
</DropdownMenuItem>
<DropdownMenuItem onClick={this.onEdit}>Edit</DropdownMenuItem>
<DropdownMenuItem onClick={this.onEdit}>Edit</DropdownMenuItem>
</Flex>}
{allowDelete &&
<DropdownMenuItem onClick={this.onDelete}>Delete</DropdownMenuItem>}
<DropdownMenuItem onClick={this.onDelete}>Delete</DropdownMenuItem>}
</DropdownMenu>
);
}
}
const MoreIcon = styled(Icon)`
width: 22px;
`;
export default inject('ui')(CollectionMenu);

View File

@ -4,7 +4,7 @@ import { withRouter } from 'react-router-dom';
import { inject, observer } from 'mobx-react';
import Document from 'models/Document';
import UiStore from 'stores/UiStore';
import Icon from 'components/Icon';
import MoreIcon from 'components/Icon/MoreIcon';
import { documentMoveUrl } from 'utils/routeHelpers';
import { DropdownMenu, DropdownMenuItem } from 'components/DropdownMenu';
@ -49,7 +49,7 @@ import { DropdownMenu, DropdownMenuItem } from 'components/DropdownMenu';
const { allowDelete } = document;
return (
<DropdownMenu label={label || <Icon type="MoreHorizontal" />}>
<DropdownMenu label={label || <MoreIcon />}>
{document.starred
? <DropdownMenuItem onClick={this.handleUnstar}>
Unstar

View File

@ -31,6 +31,7 @@ import LoadingIndicator from 'components/LoadingIndicator';
import Collaborators from 'components/Collaborators';
import CenteredContent from 'components/CenteredContent';
import PageTitle from 'components/PageTitle';
import NewDocumentIcon from 'components/Icon/NewDocumentIcon';
import Search from 'scenes/Search';
const DISCARD_CHANGES = `
@ -303,7 +304,7 @@ type Props = {
<HeaderAction>
{!this.isEditing &&
<a onClick={this.onClickNew}>
New
<NewDocumentIcon />
</a>}
</HeaderAction>
</Flex>
@ -329,15 +330,8 @@ const HeaderAction = styled(Flex)`
color: ${color.text};
padding: 0 0 0 14px;
a,
svg {
a {
color: ${color.text};
opacity: .8;
transition: opacity 100ms ease-in-out;
&:hover {
opacity: 1;
}
}
`;

View File

@ -7,7 +7,7 @@ import styled from 'styled-components';
import { color } from 'styles/constants';
import Flex from 'components/Flex';
import ChevronIcon from 'components/Icon/ChevronIcon';
import GoToIcon from 'components/Icon/GoToIcon';
import Document from 'models/Document';
@ -19,10 +19,7 @@ const ResultWrapper = styled.div`
cursor: default;
`;
const StyledChevronIcon = styled(ChevronIcon)`
padding-top: 2px;
width: 24px;
height: 24px;
const StyledGoToIcon = styled(GoToIcon)`
`;
const ResultWrapperLink = ResultWrapper.withComponent('a').extend`
@ -40,8 +37,10 @@ const ResultWrapperLink = ResultWrapper.withComponent('a').extend`
outline: none;
cursor: pointer;
${StyledChevronIcon} svg {
fill: ${color.smokeLight};
${StyledGoToIcon} {
svg {
fill: ${color.white};
}
}
}
`;
@ -82,14 +81,14 @@ type Props = {
if (!result) return <div />;
return (
<Component innerRef={ref} selectable href onClick={this.handleClick}>
<Component innerRef={ref} onClick={this.handleClick} selectable href>
{result.path
.map(doc => <span key={doc.id}>{doc.title}</span>)
.reduce((prev, curr) => [prev, <StyledChevronIcon />, curr])}
.reduce((prev, curr) => [prev, <StyledGoToIcon />, curr])}
{document &&
<Flex>
{' '}
<ChevronIcon />
<StyledGoToIcon />
{' '}{document.title}
</Flex>}
</Component>

View File

@ -50,7 +50,7 @@ svg {
max-height: 100%;
}
a {
color: #005aa6;
color: #16B3FF;
text-decoration: none;
cursor: pointer;
}

View File

@ -141,7 +141,6 @@
"react-addons-css-transition-group": "15.3.2",
"react-dom": "^15.6.1",
"react-dropzone": "3.6.0",
"react-feather": "^1.0.7",
"react-helmet": "3.1.0",
"react-keydown": "^1.7.3",
"react-modal": "^2.2.1",

View File

@ -7310,10 +7310,6 @@ react-dropzone@3.6.0:
dependencies:
attr-accept "^1.0.3"
react-feather@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/react-feather/-/react-feather-1.0.7.tgz#f2118f1d2402b0c1e6f23c732f9e7f9fd4ca61e2"
react-helmet@3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/react-helmet/-/react-helmet-3.1.0.tgz#63486194682f33004826f3687dc49a138b557050"