diff --git a/frontend/components/DropdownMenu/DropdownMenu.js b/frontend/components/DropdownMenu/DropdownMenu.js index 20ecf1ce..953f620b 100644 --- a/frontend/components/DropdownMenu/DropdownMenu.js +++ b/frontend/components/DropdownMenu/DropdownMenu.js @@ -5,19 +5,7 @@ import { observer } from 'mobx-react'; import styled from 'styled-components'; import Flex from 'components/Flex'; import { color } from 'styles/constants'; - -type MenuItemProps = { - onClick?: Function, - children?: React.Element, -}; - -const DropdownMenuItem = ({ onClick, children }: MenuItemProps) => { - return ( - - {children} - - ); -}; +import { fadeAndScaleIn } from 'styles/animations'; type DropdownMenuProps = { label: React.Element, @@ -73,37 +61,18 @@ const MenuContainer = styled.div` `; const Menu = styled.div` + animation: ${fadeAndScaleIn} 250ms ease; + transform-origin: 75% 0; + position: absolute; right: 0; z-index: 1000; - border: 1px solid #eee; - background-color: #fff; + border: ${color.slateLight}; + background: ${color.white}; + border-radius: 2px; min-width: 160px; + overflow: hidden; + box-shadow: 0 0 0 1px rgba(0,0,0,.05), 0 4px 8px rgba(0,0,0,.08), 0 2px 4px rgba(0,0,0,.08); `; -const MenuItem = styled.div` - margin: 0; - padding: 5px 10px; - height: 32px; - - display: flex; - justify-content: space-between; - align-items: center; - cursor: pointer; - border-left: 2px solid transparent; - - span { - margin-top: 2px; - } - - a { - text-decoration: none; - width: 100%; - } - - &:hover { - border-left: 2px solid ${color.primary}; - } -`; - -export { DropdownMenu, DropdownMenuItem }; +export default DropdownMenu; diff --git a/frontend/components/DropdownMenu/DropdownMenuItem.js b/frontend/components/DropdownMenu/DropdownMenuItem.js new file mode 100644 index 00000000..77cf6f7e --- /dev/null +++ b/frontend/components/DropdownMenu/DropdownMenuItem.js @@ -0,0 +1,42 @@ +// @flow +import React from 'react'; +import styled from 'styled-components'; +import { color } from 'styles/constants'; + +const DropdownMenuItem = ({ + onClick, + children, +}: { + onClick?: Function, + children?: React.Element, +}) => { + return ( + + {children} + + ); +}; + +const MenuItem = styled.div` + margin: 0; + padding: 5px 10px; + height: 32px; + + display: flex; + justify-content: space-between; + align-items: center; + cursor: pointer; + font-size: 15px; + + a { + text-decoration: none; + width: 100%; + } + + &:hover { + color: ${color.white}; + background: ${color.primary}; + } +`; + +export default DropdownMenuItem; diff --git a/frontend/components/DropdownMenu/index.js b/frontend/components/DropdownMenu/index.js index 11e84f9c..f6b44681 100644 --- a/frontend/components/DropdownMenu/index.js +++ b/frontend/components/DropdownMenu/index.js @@ -1,2 +1,3 @@ // @flow -export { DropdownMenu, DropdownMenuItem } from './DropdownMenu'; +export { default as DropdownMenu } from './DropdownMenu'; +export { default as DropdownMenuItem } from './DropdownMenuItem'; diff --git a/frontend/models/Document.js b/frontend/models/Document.js index ea39c2f6..48b38dc2 100644 --- a/frontend/models/Document.js +++ b/frontend/models/Document.js @@ -79,6 +79,16 @@ class Document extends BaseModel { return !this.isEmpty && !this.isSaving; } + @computed get allowDelete(): boolean { + const collection = this.collection; + return ( + collection && + collection.type === 'atlas' && + collection.documents && + collection.documents.length > 1 + ); + } + /* Actions */ @action star = async () => { @@ -182,6 +192,14 @@ class Document extends BaseModel { return; }; + download() { + const a = window.document.createElement('a'); + a.textContent = 'download'; + a.download = `${this.title}.md`; + a.href = `data:text/markdown;charset=UTF-8,${encodeURIComponent(this.text)}`; + a.click(); + } + updateData(data: Object = {}, dirty: boolean = false) { if (data.text) { const { title, emoji } = parseTitle(data.text); diff --git a/frontend/scenes/Document/Document.js b/frontend/scenes/Document/Document.js index 24e48b9a..67047377 100644 --- a/frontend/scenes/Document/Document.js +++ b/frontend/scenes/Document/Document.js @@ -204,8 +204,7 @@ type Props = { /> - {document && - !isNew && + {!isNew && !isEditing && } diff --git a/frontend/scenes/Document/components/Menu.js b/frontend/scenes/Document/components/Menu.js index 9bae6f0b..d178f42f 100644 --- a/frontend/scenes/Document/components/Menu.js +++ b/frontend/scenes/Document/components/Menu.js @@ -1,6 +1,5 @@ // @flow import React, { Component } from 'react'; -import invariant from 'invariant'; import get from 'lodash/get'; import { withRouter } from 'react-router-dom'; import { observer } from 'mobx-react'; @@ -21,7 +20,6 @@ type Props = { }; onCreateChild = () => { - invariant(this.props.document, 'Document is not available'); this.props.history.push(`${this.props.document.url}/new`); }; @@ -41,41 +39,24 @@ type Props = { }; onExport = () => { - const doc = this.props.document; - if (doc) { - const a = document.createElement('a'); - a.textContent = 'download'; - a.download = `${doc.title}.md`; - a.href = `data:text/markdown;charset=UTF-8,${encodeURIComponent(doc.text)}`; - a.click(); - } + this.props.document.download(); }; render() { - const document = get(this.props, 'document'); - if (document) { - const collection = document.collection; - const allowDelete = - collection && - collection.type === 'atlas' && - collection.documents && - collection.documents.length > 1; + const collection = this.props.document.collection; + const allowDelete = this.props.document.allowDelete; - return ( - }> - {collection && -
- - New document - -
} - Export - {allowDelete && - Delete} -
- ); - } - return null; + return ( + } top right> + {collection && + + New document + } + Export + {allowDelete && + Delete} + + ); } }