Skip to content

Commit

Permalink
Slate editor (#38)
Browse files Browse the repository at this point in the history
* WIP: Slate editor

* WIP

* Focus at start / end working

* ah ha

* Super basic floating toolbar

* Nested list editing

* Pulling more logic into plugins

* inline code markdown

* Backspace at end of code block should remove mark

* Ensure there is always an empty line at editor end

* Add keyboard shortcuts for bold, italic, underline

* Add strikethrough shortcode and toolbar

* Toolbar to declarative
Fixed paragraph styling
Removed unused stuffs

* Super basic link editing

* Split Toolbar, now possible to edit and remove links

* Add new link to selection from toolbar working

* Ensure toolbar doesn't extend off screen

* Fix minor js issues, disable formatting of document title

* Boom, icons

* Remove codemirror, fix MD parsing issues

* CMD+S now saves inplace

* Add --- shortcut for horizontal rule

* Improved styling for link editor

* Add header anchors in readOnly

* More readable core text color

* Restored image file uploading 🎉

* Add support for inline md syntax, ** __ etc

* Centered

* Flooooow

* Checklist support

* Upgrade edit list plugin

* Finally. Allow keydown within rich textarea

* Update Markdown serializer

* Cleanup, remove async editor loading

* Editor > MarkdownEditor
Fixed unsaved changes warning triggered when all changes are saved

* MOAR typing

* Combine edit and view

* Fixed checkboxes still editable in readOnly

* wip

* Breadcrumb
Restored scroll

* Move document scene actions to menu

* Added: Support for code blocks, syntax highlighting

* Cleanup

*  > styled component

* Prevent CMD+Enter from adding linebreak

* Show image uploading in layout activity indicator

* Upgrade editor deps

* Improve link toolbar. Only one scenario where it's not working now
  • Loading branch information
jorilallo authored and tommoor committed May 18, 2017
1 parent 7b16d3e commit ff17047
Show file tree
Hide file tree
Showing 84 changed files with 2,531 additions and 1,659 deletions.
21 changes: 21 additions & 0 deletions frontend/components/Icon/BoldIcon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// @flow
import React from 'react';
import Icon from './Icon';
import type { Props } from './Icon';

export default function BoldIcon(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="M15.6 10.79c.97-.67 1.65-1.77 1.65-2.79 0-2.26-1.75-4-4-4H7v14h7.04c2.09 0 3.71-1.7 3.71-3.79 0-1.52-.86-2.82-2.15-3.42zM10 6.5h3c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5h-3v-3zm3.5 9H10v-3h3.5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5z" />
<path d="M0 0h24v24H0z" fill="none" />
</svg>
</Icon>
);
}
21 changes: 21 additions & 0 deletions frontend/components/Icon/BulletedListIcon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// @flow
import React from 'react';
import Icon from './Icon';
import type { Props } from './Icon';

export default function BulletedListIcon(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="M4 10.5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm0-6c-.83 0-1.5.67-1.5 1.5S3.17 7.5 4 7.5 5.5 6.83 5.5 6 4.83 4.5 4 4.5zm0 12c-.83 0-1.5.68-1.5 1.5s.68 1.5 1.5 1.5 1.5-.68 1.5-1.5-.67-1.5-1.5-1.5zM7 19h14v-2H7v2zm0-6h14v-2H7v2zm0-8v2h14V5H7z" />
<path d="M0 0h24v24H0V0z" fill="none" />
</svg>
</Icon>
);
}
21 changes: 21 additions & 0 deletions frontend/components/Icon/CloseIcon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// @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="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" />
<path d="M0 0h24v24H0z" fill="none" />
</svg>
</Icon>
);
}
21 changes: 21 additions & 0 deletions frontend/components/Icon/CodeIcon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// @flow
import React from 'react';
import Icon from './Icon';
import type { Props } from './Icon';

export default function CodeIcon(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="M0 0h24v24H0V0z" fill="none" />
<path d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z" />
</svg>
</Icon>
);
}
21 changes: 21 additions & 0 deletions frontend/components/Icon/Heading1Icon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// @flow
import React from 'react';
import Icon from './Icon';
import type { Props } from './Icon';

export default function Heading1Icon(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="M0 0h24v24H0z" fill="none" />
<path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-5 14h-2V9h-2V7h4v10z" />
</svg>
</Icon>
);
}
21 changes: 21 additions & 0 deletions frontend/components/Icon/Heading2Icon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// @flow
import React from 'react';
import Icon from './Icon';
import type { Props } from './Icon';

export default function Heading2Icon(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="M0 0h24v24H0z" fill="none" />
<path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-4 8c0 1.11-.9 2-2 2h-2v2h4v2H9v-4c0-1.11.9-2 2-2h2V9H9V7h4c1.1 0 2 .89 2 2v2z" />
</svg>
</Icon>
);
}
26 changes: 26 additions & 0 deletions frontend/components/Icon/Icon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// @flow
import React from 'react';
import styled from 'styled-components';

export type Props = {
className?: string,
light?: boolean,
};

type BaseProps = {
children?: React$Element<any>,
};

export default function Icon({ children, ...rest }: Props & BaseProps) {
return (
<Wrapper {...rest}>
{children}
</Wrapper>
);
}

const Wrapper = styled.span`
svg {
fill: ${props => (props.light ? '#fff' : '#000')};
}
`;
9 changes: 9 additions & 0 deletions frontend/components/Icon/Icon.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.icon {

}

.light {
svg {
fill: #fff;
}
}
21 changes: 21 additions & 0 deletions frontend/components/Icon/ItalicIcon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// @flow
import React from 'react';
import Icon from './Icon';
import type { Props } from './Icon';

export default function ItalicIcon(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="M0 0h24v24H0z" fill="none" />
<path d="M10 4v3h2.21l-3.42 8H6v3h8v-3h-2.21l3.42-8H18V4z" />
</svg>
</Icon>
);
}
21 changes: 21 additions & 0 deletions frontend/components/Icon/LinkIcon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// @flow
import React from 'react';
import Icon from './Icon';
import type { Props } from './Icon';

export default function LinkIcon(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="M0 0h24v24H0z" fill="none" />
<path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z" />
</svg>
</Icon>
);
}
21 changes: 21 additions & 0 deletions frontend/components/Icon/OrderedListIcon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// @flow
import React from 'react';
import Icon from './Icon';
import type { Props } from './Icon';

export default function OrderedListIcon(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="M2 17h2v.5H3v1h1v.5H2v1h3v-4H2v1zm1-9h1V4H2v1h1v3zm-1 3h1.8L2 13.1v.9h3v-1H3.2L5 10.9V10H2v1zm5-6v2h14V5H7zm0 14h14v-2H7v2zm0-6h14v-2H7v2z" />
<path d="M0 0h24v24H0z" fill="none" />
</svg>
</Icon>
);
}
21 changes: 21 additions & 0 deletions frontend/components/Icon/QuoteIcon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// @flow
import React from 'react';
import Icon from './Icon';
import type { Props } from './Icon';

export default function QuoteIcon(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 17h3l2-4V7H5v6h3zm8 0h3l2-4V7h-6v6h3z" />
<path d="M0 0h24v24H0z" fill="none" />
</svg>
</Icon>
);
}
21 changes: 21 additions & 0 deletions frontend/components/Icon/StrikethroughIcon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// @flow
import React from 'react';
import Icon from './Icon';
import type { Props } from './Icon';

export default function StrikethroughIcon(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="M0 0h24v24H0z" fill="none" />
<path d="M10 19h4v-3h-4v3zM5 4v3h5v3h4V7h5V4H5zM3 14h18v-2H3v2z" />
</svg>
</Icon>
);
}
21 changes: 21 additions & 0 deletions frontend/components/Icon/UnderlinedIcon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// @flow
import React from 'react';
import Icon from './Icon';
import type { Props } from './Icon';

export default function UnderlinedIcon(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="M0 0h24v24H0z" fill="none" />
<path d="M12 17c3.31 0 6-2.69 6-6V3h-2.5v8c0 1.93-1.57 3.5-3.5 3.5S8.5 12.93 8.5 11V3H6v8c0 3.31 2.69 6 6 6zm-7 2v2h14v-2H5z" />
</svg>
</Icon>
);
}
3 changes: 3 additions & 0 deletions frontend/components/Icon/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// @flow
import Icon from './Icon';
export default Icon;
14 changes: 5 additions & 9 deletions frontend/components/Layout/Layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,16 @@ import { browserHistory, Link } from 'react-router';
import Helmet from 'react-helmet';
import styled from 'styled-components';
import { observer, inject } from 'mobx-react';
import keydown from 'react-keydown';
import _ from 'lodash';
import keydown from 'react-keydown';
import classNames from 'classnames/bind';
import searchIcon from 'assets/icons/search.svg';
import { Flex } from 'reflexbox';

import styles from './Layout.scss';
import DropdownMenu, { MenuItem } from 'components/DropdownMenu';

import LoadingIndicator from 'components/LoadingIndicator';
import UserStore from 'stores/UserStore';

import styles from './Layout.scss';
import classNames from 'classnames/bind';
const cx = classNames.bind(styles);

type Props = {
Expand Down Expand Up @@ -89,10 +88,7 @@ type Props = {
className={styles.search}
title="Search (/)"
>
<img
src={require('assets/icons/search.svg')}
alt="Search"
/>
<img src={searchIcon} alt="Search" />
</div>
</Flex>}
<DropdownMenu label={<Avatar src={user.user.avatarUrl} />}>
Expand Down

0 comments on commit ff17047

Please sign in to comment.