diff --git a/package.json b/package.json index bcef26cc..40249d8b 100644 --- a/package.json +++ b/package.json @@ -68,6 +68,7 @@ "react-intl-redux": "0.6.0", "react-popover": "0.5.4", "react-redux": "5.0.5", + "react-responsive": "3.0.0", "react-test-renderer": "^16.0.0", "redux": "3.7.0", "redux-mock-store": "^1.2.3", diff --git a/src/components/dropdown/dropdown-caret.svg b/src/components/dropdown/dropdown-caret.svg new file mode 100644 index 00000000..42ef29f4 --- /dev/null +++ b/src/components/dropdown/dropdown-caret.svg @@ -0,0 +1,12 @@ + + + + dropdown-caret + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/src/components/dropdown/dropdown.css b/src/components/dropdown/dropdown.css new file mode 100644 index 00000000..c9574cb7 --- /dev/null +++ b/src/components/dropdown/dropdown.css @@ -0,0 +1,30 @@ +@import '../../css/colors.css'; + +$arrow-border-width: 14px; + +.dropdown { + border: 1px solid $form-border; + border-radius: 5px; + overflow: visible; + min-width: 3.5rem; + color: $motion-primary; + padding: .5rem; +} + +.mod-open { + background-color: $form-border; +} + +.dropdown-icon { + width: .5rem; + height: .5rem; + margin-left: .5rem; + vertical-align: middle; + padding-bottom: .2rem; +} + +.mod-caret-up { + transform: rotate(180deg); + padding-bottom: 0; + padding-top: .2rem; +} diff --git a/src/components/dropdown/dropdown.jsx b/src/components/dropdown/dropdown.jsx new file mode 100644 index 00000000..31d2ba6d --- /dev/null +++ b/src/components/dropdown/dropdown.jsx @@ -0,0 +1,67 @@ +import bindAll from 'lodash.bindall'; +import classNames from 'classnames'; +import Popover from 'react-popover'; +import PropTypes from 'prop-types'; +import React from 'react'; + +import styles from './dropdown.css'; + +import dropdownIcon from './dropdown-caret.svg'; + +class Dropdown extends React.Component { + constructor (props) { + super(props); + bindAll(this, [ + 'handleClosePopover', + 'handleToggleOpenState' + ]); + this.state = { + isOpen: false + }; + } + handleClosePopover () { + this.setState({ + isOpen: false + }); + } + handleToggleOpenState () { + this.setState({ + isOpen: !this.state.isOpen + }); + } + render () { + return ( + +
+ {this.props.children} + +
+
+ ); + } +} + +Dropdown.propTypes = { + children: PropTypes.node.isRequired, + className: PropTypes.string, + popoverContent: PropTypes.node.isRequired +}; + +export default Dropdown; diff --git a/src/components/forms/live-input-hoc.jsx b/src/components/forms/live-input-hoc.jsx index 266477d1..a9f20e0e 100644 --- a/src/components/forms/live-input-hoc.jsx +++ b/src/components/forms/live-input-hoc.jsx @@ -59,8 +59,8 @@ export default function (Input) { } LiveInput.propTypes = { - max: PropTypes.number, - min: PropTypes.number, + max: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), + min: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), onSubmit: PropTypes.func.isRequired, value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]) }; diff --git a/src/components/input-group/input-group.css b/src/components/input-group/input-group.css index 66905a2a..6c9d8b83 100644 --- a/src/components/input-group/input-group.css +++ b/src/components/input-group/input-group.css @@ -1,7 +1,7 @@ @import '../../css/units.css'; .input-group + .input-group { - margin-left: calc(3 * $grid-unit); + margin-left: calc(2 * $grid-unit); } .disabled { diff --git a/src/components/labeled-icon-button/labeled-icon-button.css b/src/components/labeled-icon-button/labeled-icon-button.css index 54a755e4..f150fda6 100644 --- a/src/components/labeled-icon-button/labeled-icon-button.css +++ b/src/components/labeled-icon-button/labeled-icon-button.css @@ -15,8 +15,8 @@ $border-radius: 0.25rem; } .edit-field-icon { - width: 1.5rem; - height: 1.5rem; + width: 1.25rem; + height: 1.25rem; flex-grow: 1; vertical-align: middle; } diff --git a/src/components/mode-tools/mode-tools.jsx b/src/components/mode-tools/mode-tools.jsx index f6343375..aa1d8040 100644 --- a/src/components/mode-tools/mode-tools.jsx +++ b/src/components/mode-tools/mode-tools.jsx @@ -13,7 +13,7 @@ import Input from '../forms/input.jsx'; import InputGroup from '../input-group/input-group.jsx'; import LabeledIconButton from '../labeled-icon-button/labeled-icon-button.jsx'; // import LabeledIconButton from '../labeled-icon-button/labeled-icon-button.jsx'; -import Modes from '../../modes/modes'; +import Modes from '../../lib/modes'; import styles from './mode-tools.css'; import copyIcon from './icons/copy.svg'; diff --git a/src/components/paint-editor/paint-editor.css b/src/components/paint-editor/paint-editor.css index 5d28c5cc..9e28b9f9 100644 --- a/src/components/paint-editor/paint-editor.css +++ b/src/components/paint-editor/paint-editor.css @@ -4,7 +4,7 @@ .editor-container { display: flex; flex-direction: column; - padding: calc(4 * $grid-unit); + padding: calc(3 * $grid-unit); } .row { @@ -30,7 +30,11 @@ .mod-dashed-border { border-right: 1px dashed $ui-pane-border; - padding-right: calc(3 * $grid-unit); + padding-right: calc(2 * $grid-unit); +} + +.mod-unselect { + user-select: none; } .mod-labeled-icon-height { @@ -44,7 +48,7 @@ $border-radius: 0.25rem; border: 1px solid $ui-pane-border; border-radius: 0; border-left: none; - padding: calc(2 * $grid-unit); + padding: .35rem; } .button-group-button:last-of-type { @@ -72,13 +76,50 @@ $border-radius: 0.25rem; vertical-align: middle; } +.mod-context-menu { + display: flex; + flex-direction: column; +} + +.mod-top-divider { + border-top: 1px solid $ui-pane-border; +} + +.mod-menu-item { + display: flex; + margin: 0 -$grid-unit; + min-width: 6.25rem; + padding: calc(3 * $grid-unit); + white-space: nowrap; + cursor: pointer; + transition: 0.1s ease; + align-items: center; + font-family: "Helvetica Neue", Helvetica, sans-serif; +} + +.mod-disabled { + cursor: auto; +} + +.mod-menu-item:hover { + background: $motion-transparent; +} + +.mod-disabled:hover { + background-color: transparent; +} + +.menu-item-icon { + margin-right: calc(2 * $grid-unit); +} + .mod-mode-tools { - margin-left: calc(3 * $grid-unit); + margin-left: calc(2 * $grid-unit); } .canvas-container { - width: 500px; - height: 400px; + width: 480px; + height: 360px; box-sizing: content-box; border: 1px solid #e8edf1; border-radius: .25rem; @@ -89,7 +130,7 @@ $border-radius: 0.25rem; .mode-selector { display: flex; margin-right: calc(2 * $grid-unit); - max-width: 5.5rem; + max-width: 6rem; flex-direction: row; flex-wrap: wrap; align-items: flex-start; @@ -101,3 +142,15 @@ $border-radius: 0.25rem; display: flex; flex-direction: row-reverse; } + +@media only screen and (max-width: $full-size-paint) { + .editor-container { + padding: calc(3 * $grid-unit) $grid-unit; + } + + .mode-selector { + margin-right: $grid-unit; + flex-direction: column; + justify-content: flex-start; + } +} diff --git a/src/components/paint-editor/paint-editor.jsx b/src/components/paint-editor/paint-editor.jsx index c010102a..d68c3c2c 100644 --- a/src/components/paint-editor/paint-editor.jsx +++ b/src/components/paint-editor/paint-editor.jsx @@ -1,6 +1,7 @@ import bindAll from 'lodash.bindall'; import classNames from 'classnames'; import {defineMessages, injectIntl, intlShape} from 'react-intl'; +import MediaQuery from 'react-responsive'; import React from 'react'; import PropTypes from 'prop-types'; @@ -13,6 +14,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 Dropdown from '../dropdown/dropdown.jsx'; import EraserMode from '../../containers/eraser-mode.jsx'; import FillColorIndicatorComponent from '../../containers/fill-color-indicator.jsx'; import Input from '../forms/input.jsx'; @@ -28,6 +30,7 @@ import SelectMode from '../../containers/select-mode.jsx'; import StrokeColorIndicatorComponent from '../../containers/stroke-color-indicator.jsx'; import StrokeWidthIndicatorComponent from '../../containers/stroke-width-indicator.jsx'; +import layout from '../../lib/layout-constants'; import styles from './paint-editor.css'; import groupIcon from './icons/group.svg'; @@ -88,6 +91,11 @@ const messages = defineMessages({ defaultMessage: 'Back', description: 'Label for the `Send to back of canvas` button', id: 'paint.paintEditor.back' + }, + more: { + defaultMessage: 'More', + description: 'Label for dropdown to access more action buttons', + id: 'paint.paintEditor.more' } }); @@ -114,13 +122,22 @@ class PaintEditorComponent extends React.Component {
{/* Name field */} - + {/* Undo/Redo */} @@ -197,31 +214,87 @@ class PaintEditorComponent extends React.Component { /> - {/* Front/Back */} - - - - + +
+ + + + - {/* To be rotation point */} - {/* - - */} + {/* To be rotation point */} + {/* + + */} +
+
+ + + + + + + {/* To be rotation point */} + {/* */} + + } + tipSize={.01} + > + {this.props.intl.formatMessage(messages.more)} + + +
{/* Second Row */} diff --git a/src/components/tool-select-base/tool-select-base.css b/src/components/tool-select-base/tool-select-base.css index fdfb3aa5..d6b87b4a 100644 --- a/src/components/tool-select-base/tool-select-base.css +++ b/src/components/tool-select-base/tool-select-base.css @@ -1,14 +1,16 @@ @import '../../css/colors.css'; +@import "../../css/units.css"; $border-radius: .25rem; .mod-tool-select { display: inline-block; + margin: $grid-unit; border: none; border-radius: $border-radius; outline: none; background: none; - padding: 0.25rem; + padding: $grid-unit; font-size: 0.85rem; transition: 0.2s; } @@ -27,3 +29,9 @@ img.tool-select-icon { flex-grow: 1; vertical-align: middle; } + +@media only screen and (max-width: $full-size-paint) { + .mod-tool-select { + margin: 0; + } +} diff --git a/src/containers/brush-mode.jsx b/src/containers/brush-mode.jsx index ee218613..6c089a8d 100644 --- a/src/containers/brush-mode.jsx +++ b/src/containers/brush-mode.jsx @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import {connect} from 'react-redux'; import bindAll from 'lodash.bindall'; -import Modes from '../modes/modes'; +import Modes from '../lib/modes'; import Blobbiness from '../helper/blob-tools/blob'; import {MIXED} from '../helper/style-path'; diff --git a/src/containers/eraser-mode.jsx b/src/containers/eraser-mode.jsx index 45412f63..838bad44 100644 --- a/src/containers/eraser-mode.jsx +++ b/src/containers/eraser-mode.jsx @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import {connect} from 'react-redux'; import bindAll from 'lodash.bindall'; -import Modes from '../modes/modes'; +import Modes from '../lib/modes'; import Blobbiness from '../helper/blob-tools/blob'; import {changeBrushSize} from '../reducers/eraser-mode'; import {clearSelectedItems} from '../reducers/selected-items'; diff --git a/src/containers/fill-color-indicator.jsx b/src/containers/fill-color-indicator.jsx index 279b2a04..c21d724f 100644 --- a/src/containers/fill-color-indicator.jsx +++ b/src/containers/fill-color-indicator.jsx @@ -4,7 +4,7 @@ import React from 'react'; import bindAll from 'lodash.bindall'; import {changeFillColor} from '../reducers/fill-color'; import {openFillColor, closeFillColor} from '../reducers/modals'; -import Modes from '../modes/modes'; +import Modes from '../lib/modes'; import FillColorIndicatorComponent from '../components/fill-color-indicator.jsx'; import {applyFillColorToSelection} from '../helper/style-path'; diff --git a/src/containers/line-mode.jsx b/src/containers/line-mode.jsx index f0d57031..6c836026 100644 --- a/src/containers/line-mode.jsx +++ b/src/containers/line-mode.jsx @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import {connect} from 'react-redux'; import bindAll from 'lodash.bindall'; -import Modes from '../modes/modes'; +import Modes from '../lib/modes'; import {clearSelection} from '../helper/selection'; import {endPointHit, touching} from '../helper/snapping'; import {drawHitPoint, removeHitPoint} from '../helper/guides'; diff --git a/src/containers/oval-mode.jsx b/src/containers/oval-mode.jsx index 7578cef7..809488be 100644 --- a/src/containers/oval-mode.jsx +++ b/src/containers/oval-mode.jsx @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import {connect} from 'react-redux'; import bindAll from 'lodash.bindall'; -import Modes from '../modes/modes'; +import Modes from '../lib/modes'; import {MIXED} from '../helper/style-path'; import {changeFillColor, DEFAULT_COLOR} from '../reducers/fill-color'; diff --git a/src/containers/paint-editor.jsx b/src/containers/paint-editor.jsx index bc5d3f0f..7fc5fe0b 100644 --- a/src/containers/paint-editor.jsx +++ b/src/containers/paint-editor.jsx @@ -14,7 +14,7 @@ import {groupSelection, ungroupSelection} from '../helper/group'; import {clearSelection, getSelectedLeafItems, getSelectedRootItems} from '../helper/selection'; import {resetZoom, zoomOnSelection} from '../helper/view'; -import Modes from '../modes/modes'; +import Modes from '../lib/modes'; import {connect} from 'react-redux'; import bindAll from 'lodash.bindall'; import paper from '@scratch/paper'; diff --git a/src/containers/paper-canvas.css b/src/containers/paper-canvas.css index 82e8e028..ef983c99 100644 --- a/src/containers/paper-canvas.css +++ b/src/containers/paper-canvas.css @@ -1,6 +1,6 @@ .paper-canvas { - width: 500px; - height: 400px; + width: 480px; + height: 360px; margin: auto; position: relative; background-color: #fff; diff --git a/src/containers/paper-canvas.jsx b/src/containers/paper-canvas.jsx index 0117cafb..751ef558 100644 --- a/src/containers/paper-canvas.jsx +++ b/src/containers/paper-canvas.jsx @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import {connect} from 'react-redux'; import paper from '@scratch/paper'; -import Modes from '../modes/modes'; +import Modes from '../lib/modes'; import {performSnapshot} from '../helper/undo'; import {undoSnapshot, clearUndoState} from '../reducers/undo'; @@ -150,9 +150,9 @@ class PaperCanvas extends React.Component { return ( ); diff --git a/src/containers/rect-mode.jsx b/src/containers/rect-mode.jsx index 22ee8abe..ffdfc72c 100644 --- a/src/containers/rect-mode.jsx +++ b/src/containers/rect-mode.jsx @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import {connect} from 'react-redux'; import bindAll from 'lodash.bindall'; -import Modes from '../modes/modes'; +import Modes from '../lib/modes'; import {MIXED} from '../helper/style-path'; import {changeFillColor, DEFAULT_COLOR} from '../reducers/fill-color'; diff --git a/src/containers/reshape-mode.jsx b/src/containers/reshape-mode.jsx index 3dfe2c2c..1b84710e 100644 --- a/src/containers/reshape-mode.jsx +++ b/src/containers/reshape-mode.jsx @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import {connect} from 'react-redux'; import bindAll from 'lodash.bindall'; -import Modes from '../modes/modes'; +import Modes from '../lib/modes'; import {changeMode} from '../reducers/modes'; import {clearHoveredItem, setHoveredItem} from '../reducers/hover'; diff --git a/src/containers/rounded-rect-mode.jsx b/src/containers/rounded-rect-mode.jsx index fc61eceb..fa733d71 100644 --- a/src/containers/rounded-rect-mode.jsx +++ b/src/containers/rounded-rect-mode.jsx @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import {connect} from 'react-redux'; import bindAll from 'lodash.bindall'; -import Modes from '../modes/modes'; +import Modes from '../lib/modes'; import {changeMode} from '../reducers/modes'; import {clearHoveredItem, setHoveredItem} from '../reducers/hover'; diff --git a/src/containers/select-mode.jsx b/src/containers/select-mode.jsx index 596805b9..b8c18276 100644 --- a/src/containers/select-mode.jsx +++ b/src/containers/select-mode.jsx @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import {connect} from 'react-redux'; import bindAll from 'lodash.bindall'; -import Modes from '../modes/modes'; +import Modes from '../lib/modes'; import {changeMode} from '../reducers/modes'; import {clearHoveredItem, setHoveredItem} from '../reducers/hover'; diff --git a/src/containers/stroke-color-indicator.jsx b/src/containers/stroke-color-indicator.jsx index dfbaa6e9..23043f87 100644 --- a/src/containers/stroke-color-indicator.jsx +++ b/src/containers/stroke-color-indicator.jsx @@ -4,7 +4,7 @@ import React from 'react'; import bindAll from 'lodash.bindall'; import {changeStrokeColor} from '../reducers/stroke-color'; import {openStrokeColor, closeStrokeColor} from '../reducers/modals'; -import Modes from '../modes/modes'; +import Modes from '../lib/modes'; import StrokeColorIndicatorComponent from '../components/stroke-color-indicator.jsx'; import {applyStrokeColorToSelection} from '../helper/style-path'; diff --git a/src/containers/stroke-width-indicator.jsx b/src/containers/stroke-width-indicator.jsx index 14e717e1..e462a02d 100644 --- a/src/containers/stroke-width-indicator.jsx +++ b/src/containers/stroke-width-indicator.jsx @@ -5,7 +5,7 @@ import bindAll from 'lodash.bindall'; import {changeStrokeWidth} from '../reducers/stroke-width'; import StrokeWidthIndicatorComponent from '../components/stroke-width-indicator.jsx'; import {applyStrokeWidthToSelection} from '../helper/style-path'; -import Modes from '../modes/modes'; +import Modes from '../lib/modes'; class StrokeWidthIndicator extends React.Component { constructor (props) { diff --git a/src/css/units.css b/src/css/units.css index c9e15169..07cbf5d6 100644 --- a/src/css/units.css +++ b/src/css/units.css @@ -4,7 +4,9 @@ See https://github.com/LLK/scratch-paint/issues/13 */ /* ACTUALLY, THIS IS EDITED ;) THIS WAS CHANGED ON 10/25/2017 BY @mewtaylor TO ADD A VARIABLE FOR THE SMALLEST -GRID UNITS.*/ +GRID UNITS. + +ALSO EDITED ON 11/13/2017 TO ADD IN CONTANTS FOR LAYOUT FROM `layout-contents.js`*/ $space: 0.5rem; $grid-unit: .25rem; @@ -18,3 +20,7 @@ $stage-menu-height: 2.75rem; $library-header-height: 4.375rem; $form-radius: calc($space / 2); + +/* layout contants from `layout-constants.js`, minus 1px */ +$full-size: 1095px; +$full-size-paint: 1249px; diff --git a/src/helper/selection-tools/move-tool.js b/src/helper/selection-tools/move-tool.js index 778c47c9..0d0a633f 100644 --- a/src/helper/selection-tools/move-tool.js +++ b/src/helper/selection-tools/move-tool.js @@ -1,4 +1,4 @@ -import Modes from '../../modes/modes'; +import Modes from '../../lib/modes'; import {isGroup} from '../group'; import {isCompoundPathItem, getRootItem} from '../item'; import {snapDeltaToAngle} from '../math'; diff --git a/src/helper/selection-tools/reshape-tool.js b/src/helper/selection-tools/reshape-tool.js index be5796c9..7ca0eefc 100644 --- a/src/helper/selection-tools/reshape-tool.js +++ b/src/helper/selection-tools/reshape-tool.js @@ -2,7 +2,7 @@ import paper from '@scratch/paper'; import log from '../../log/log'; import keyMirror from 'keymirror'; -import Modes from '../../modes/modes'; +import Modes from '../../lib/modes'; import {getHoveredItem} from '../hover'; import {getRootItem, isPGTextItem} from '../item'; import MoveTool from './move-tool'; diff --git a/src/helper/selection-tools/select-tool.js b/src/helper/selection-tools/select-tool.js index bc34e069..0400787d 100644 --- a/src/helper/selection-tools/select-tool.js +++ b/src/helper/selection-tools/select-tool.js @@ -1,4 +1,4 @@ -import Modes from '../../modes/modes'; +import Modes from '../../lib/modes'; import {getHoveredItem} from '../hover'; import {selectRootItem} from '../selection'; diff --git a/src/helper/selection.js b/src/helper/selection.js index bd164809..13a372fa 100644 --- a/src/helper/selection.js +++ b/src/helper/selection.js @@ -1,5 +1,5 @@ import paper from '@scratch/paper'; -import Modes from '../modes/modes'; +import Modes from '../lib/modes'; import {getItemsGroup, isGroup} from './group'; import {getRootItem, isCompoundPathItem, isBoundsItem, isPathItem, isPGTextItem} from './item'; diff --git a/src/helper/tools/oval-tool.js b/src/helper/tools/oval-tool.js index 88a28323..55d552d3 100644 --- a/src/helper/tools/oval-tool.js +++ b/src/helper/tools/oval-tool.js @@ -1,5 +1,5 @@ import paper from '@scratch/paper'; -import Modes from '../../modes/modes'; +import Modes from '../../lib/modes'; import {styleShape} from '../style-path'; import {clearSelection} from '../selection'; import BoundingBoxTool from '../selection-tools/bounding-box-tool'; diff --git a/src/helper/tools/rect-tool.js b/src/helper/tools/rect-tool.js index 0c5d71fd..a1acce27 100644 --- a/src/helper/tools/rect-tool.js +++ b/src/helper/tools/rect-tool.js @@ -1,5 +1,5 @@ import paper from '@scratch/paper'; -import Modes from '../../modes/modes'; +import Modes from '../../lib/modes'; import {styleShape} from '../style-path'; import {clearSelection} from '../selection'; import BoundingBoxTool from '../selection-tools/bounding-box-tool'; diff --git a/src/lib/layout-constants.js b/src/lib/layout-constants.js new file mode 100644 index 00000000..d19dda60 --- /dev/null +++ b/src/lib/layout-constants.js @@ -0,0 +1,3 @@ +export default { + fullSizeEditorMinWidth: 1250 +}; diff --git a/src/modes/modes.js b/src/lib/modes.js similarity index 100% rename from src/modes/modes.js rename to src/lib/modes.js diff --git a/src/reducers/modes.js b/src/reducers/modes.js index 831ed7df..3454f31b 100644 --- a/src/reducers/modes.js +++ b/src/reducers/modes.js @@ -1,4 +1,4 @@ -import Modes from '../modes/modes'; +import Modes from '../lib/modes'; import log from '../log/log'; const CHANGE_MODE = 'scratch-paint/modes/CHANGE_MODE'; diff --git a/test/unit/modes-reducer.test.js b/test/unit/modes-reducer.test.js index df81f64c..88d0177e 100644 --- a/test/unit/modes-reducer.test.js +++ b/test/unit/modes-reducer.test.js @@ -1,5 +1,5 @@ /* eslint-env jest */ -import Modes from '../../src/modes/modes'; +import Modes from '../../src/lib/modes'; import reducer from '../../src/reducers/modes'; import {changeMode} from '../../src/reducers/modes';