diff --git a/package.json b/package.json index d94ad504..f1e98c5f 100644 --- a/package.json +++ b/package.json @@ -71,6 +71,7 @@ "react-responsive": "3.0.0", "react-style-proptype": "3.1.0", "react-test-renderer": "^16.0.0", + "react-tooltip": "3.4.0", "redux": "3.7.0", "redux-mock-store": "^1.2.3", "redux-throttle": "0.1.1", diff --git a/src/components/button/button.css b/src/components/button/button.css index 1633ab18..9d331158 100644 --- a/src/components/button/button.css +++ b/src/components/button/button.css @@ -11,7 +11,7 @@ :local(.mod-disabled) { cursor: auto; - opacity: .3; + opacity: .5; } :local(.mod-disabled:active) { background: none; diff --git a/src/components/coming-soon/aww-cat.png b/src/components/coming-soon/aww-cat.png new file mode 100644 index 00000000..bddfb8de Binary files /dev/null and b/src/components/coming-soon/aww-cat.png differ diff --git a/src/components/coming-soon/coming-soon.css b/src/components/coming-soon/coming-soon.css new file mode 100644 index 00000000..7f197577 --- /dev/null +++ b/src/components/coming-soon/coming-soon.css @@ -0,0 +1,72 @@ +/* DO NOT EDIT +@todo This file is copied from GUI and should be pulled out into a shared library. +See #13 */ + +/* + * NOTE: the copious use of `important` is needed to overwrite + * the default tooltip styling, and is required by the 3rd party + * library being used, `react-tooltip` + */ + +@import "../../css/colors.css"; + +.coming-soon { + background-color: $data-primary !important; + border: 1px solid hsla(0, 0%, 0%, .1) !important; + border-radius: .25rem !important; + box-shadow: 0 0 .5rem hsla(0, 0%, 0%, .25) !important; + padding: .75rem 1rem !important; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif !important; + font-size: 1rem !important; + line-height: 1.25rem !important; + z-index: 100 !important; +} + +.coming-soon:after { + content: ""; + border-top: 1px solid hsla(0, 0%, 0%, .1) !important; + border-left: 0 !important; + border-bottom: 0 !important; + border-right: 1px solid hsla(0, 0%, 0%, .1) !important; + border-radius: .25rem; + background-color: $data-primary !important; + height: 1rem !important; + width: 1rem !important; +} + +.show, +.show:before, +.show:after { + opacity: 1 !important; +} + +.left:after { + margin-top: -.5rem !important; + right: -.5rem !important; + transform: rotate(45deg) !important; +} + +.right:after { + margin-top: -.5rem !important; + left: -.5rem !important; + transform: rotate(-135deg) !important; +} + +.top:after { + margin-right: -.5rem !important; + bottom: -.5rem !important; + transform: rotate(135deg) !important; +} + +.bottom:after { + margin-left: -.5rem !important; + top: -.5rem !important; + transform: rotate(-45deg) !important; +} + +.coming-soon-image { + margin-left: .125rem; + width: 1.25rem; + height: 1.25rem; + vertical-align: middle; +} diff --git a/src/components/coming-soon/coming-soon.jsx b/src/components/coming-soon/coming-soon.jsx new file mode 100644 index 00000000..fa9285b0 --- /dev/null +++ b/src/components/coming-soon/coming-soon.jsx @@ -0,0 +1,147 @@ +/* DO NOT EDIT +@todo This file is copied from GUI and should be pulled out into a shared library. +See #13 */ + +import bindAll from 'lodash.bindall'; +import classNames from 'classnames'; +import {defineMessages, injectIntl, intlShape, FormattedMessage} from 'react-intl'; +import PropTypes from 'prop-types'; +import React from 'react'; +import ReactTooltip from 'react-tooltip'; + +import styles from './coming-soon.css'; + +import awwCatIcon from './aww-cat.png'; +import coolCatIcon from './cool-cat.png'; + +const messages = defineMessages({ + message1: { + defaultMessage: 'Don\'t worry, we\'re on it {emoji}', + description: 'One of the "coming soon" random messages for yet-to-be-done features', + id: 'gui.comingSoon.message1' + }, + message2: { + defaultMessage: 'Coming Soon...', + description: 'One of the "coming soon" random messages for yet-to-be-done features', + id: 'gui.comingSoon.message2' + }, + message3: { + defaultMessage: 'We\'re working on it {emoji}', + description: 'One of the "coming soon" random messages for yet-to-be-done features', + id: 'gui.comingSoon.message3' + } +}); + +class ComingSoonContent extends React.Component { + constructor (props) { + super(props); + bindAll(this, [ + 'setHide', + 'setShow', + 'getRandomMessage' + ]); + this.state = { + isShowing: false + }; + } + setShow () { + // needed to set the opacity to 1, since the default is .9 on show + this.setState({isShowing: true}); + } + setHide () { + this.setState({isShowing: false}); + } + getRandomMessage () { + // randomly chooses a messages from `messages` to display in the tooltip. + const images = [awwCatIcon, coolCatIcon]; + const messageNumber = Math.floor(Math.random() * Object.keys(messages).length) + 1; + const imageNumber = Math.floor(Math.random() * Object.keys(images).length); + return ( + + ) + }} + /> + ); + } + render () { + return ( + + ); + } +} + +ComingSoonContent.propTypes = { + className: PropTypes.string, + intl: intlShape, + place: PropTypes.oneOf(['top', 'right', 'bottom', 'left']), + tooltipId: PropTypes.string.isRequired +}; + +ComingSoonContent.defaultProps = { + place: 'bottom' +}; + +const ComingSoon = injectIntl(ComingSoonContent); + +const ComingSoonTooltip = props => ( +
+
+ {props.children} +
+ +
+); + +ComingSoonTooltip.propTypes = { + children: PropTypes.node.isRequired, + className: PropTypes.string, + delayHide: PropTypes.number, + delayShow: PropTypes.number, + place: PropTypes.oneOf(['top', 'right', 'bottom', 'left']), + tooltipClassName: PropTypes.string, + tooltipId: PropTypes.string.isRequired +}; + +ComingSoonTooltip.defaultProps = { + delayHide: 0, + delayShow: 0 +}; + +export { + ComingSoon as ComingSoonComponent, + ComingSoonTooltip +}; diff --git a/src/components/coming-soon/cool-cat.png b/src/components/coming-soon/cool-cat.png new file mode 100644 index 00000000..15b2151e Binary files /dev/null and b/src/components/coming-soon/cool-cat.png differ diff --git a/src/components/paint-editor/icons/bitmap.svg b/src/components/paint-editor/icons/bitmap.svg new file mode 100644 index 00000000..8b07f54e --- /dev/null +++ b/src/components/paint-editor/icons/bitmap.svg @@ -0,0 +1,12 @@ + + + + bitmap + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/src/components/paint-editor/paint-editor.css b/src/components/paint-editor/paint-editor.css index ea1dc341..0bcfb9a1 100644 --- a/src/components/paint-editor/paint-editor.css +++ b/src/components/paint-editor/paint-editor.css @@ -157,6 +157,32 @@ $border-radius: 0.25rem; overflow: hidden; } +.canvas-controls { + display: flex; + justify-content: space-between; +} + +.bitmap-tooltip { + margin-left: $grid-unit; + max-width: 10rem; +} + +.bitmap-button { + display: flex; + border-radius: 5px; + background-color: hsla(0, 0%, 0%, .25); + padding: calc(2 * $grid-unit); + line-height: 1.5rem; + font-size: calc(3 * $grid-unit); + font-weight: bold; + justify-content: center; + opacity: .5; +} + +.bitmap-button-icon { + margin-right: calc(2 * $grid-unit); +} + @media only screen and (max-width: $full-size-paint) { .editor-container { padding: calc(3 * $grid-unit) $grid-unit; diff --git a/src/components/paint-editor/paint-editor.jsx b/src/components/paint-editor/paint-editor.jsx index 46562a96..6c083d23 100644 --- a/src/components/paint-editor/paint-editor.jsx +++ b/src/components/paint-editor/paint-editor.jsx @@ -15,6 +15,7 @@ import Button from '../button/button.jsx'; import ButtonGroup from '../button-group/button-group.jsx'; import BrushMode from '../../containers/brush-mode.jsx'; import BufferedInputHOC from '../forms/buffered-input-hoc.jsx'; +import {ComingSoonTooltip} from '../coming-soon/coming-soon.jsx'; import Dropdown from '../dropdown/dropdown.jsx'; import EraserMode from '../../containers/eraser-mode.jsx'; import FillColorIndicatorComponent from '../../containers/fill-color-indicator.jsx'; @@ -32,10 +33,12 @@ import ReshapeMode from '../../containers/reshape-mode.jsx'; import SelectMode from '../../containers/select-mode.jsx'; import StrokeColorIndicatorComponent from '../../containers/stroke-color-indicator.jsx'; import StrokeWidthIndicatorComponent from '../../containers/stroke-width-indicator.jsx'; +import TextModeComponent from '../text-mode/text-mode.jsx'; import layout from '../../lib/layout-constants'; import styles from './paint-editor.css'; +import bitmapIcon from './icons/bitmap.svg'; import groupIcon from './icons/group.svg'; import redoIcon from './icons/redo.svg'; import sendBackIcon from './icons/send-back.svg'; @@ -99,6 +102,11 @@ const messages = defineMessages({ defaultMessage: 'More', description: 'Label for dropdown to access more action buttons', id: 'paint.paintEditor.more' + }, + bitmap: { + defaultMessage: 'Convert to Bitmap', + description: 'Label for button that converts the paint editor to bitmap mode', + id: 'paint.paintEditor.bitmap' } }); @@ -350,6 +358,8 @@ const PaintEditorComponent = props => { + {/* text tool, coming soon */} + ) : null} @@ -379,41 +389,58 @@ const PaintEditorComponent = props => { ) : null } - {/* Zoom controls */} - - - - - - - + + {props.intl.formatMessage(messages.bitmap)} + + + + {/* Zoom controls */} + + + + + + + + diff --git a/src/components/text-mode/text-mode.jsx b/src/components/text-mode/text-mode.jsx new file mode 100644 index 00000000..b76036d5 --- /dev/null +++ b/src/components/text-mode/text-mode.jsx @@ -0,0 +1,27 @@ +import React from 'react'; + +import {ComingSoonTooltip} from '../coming-soon/coming-soon.jsx'; +import ToolSelectComponent from '../tool-select-base/tool-select-base.jsx'; + +import textIcon from './text.svg'; + +const TextModeComponent = () => ( + + + +); + +export default TextModeComponent; diff --git a/src/components/text-mode/text.svg b/src/components/text-mode/text.svg new file mode 100644 index 00000000..847a903e --- /dev/null +++ b/src/components/text-mode/text.svg @@ -0,0 +1,12 @@ + + + + text + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/src/components/tool-select-base/tool-select-base.jsx b/src/components/tool-select-base/tool-select-base.jsx index b8e29169..1c27268e 100644 --- a/src/components/tool-select-base/tool-select-base.jsx +++ b/src/components/tool-select-base/tool-select-base.jsx @@ -14,6 +14,7 @@ const ToolSelectComponent = props => ( [styles.isSelected]: props.isSelected }) } + disabled={props.disabled} onClick={props.onMouseDown} > ( ToolSelectComponent.propTypes = { className: PropTypes.string, + disabled: PropTypes.bool, imgDescriptor: PropTypes.shape({ defaultMessage: PropTypes.string, description: PropTypes.string, diff --git a/src/css/colors.css b/src/css/colors.css index 0fe15fca..14d539c4 100644 --- a/src/css/colors.css +++ b/src/css/colors.css @@ -20,4 +20,6 @@ $sound-tertiary: #A63FA6; $control-primary: #FFAB19; +$data-primary: #FF8C1A; + $form-border: #E9EEF2;