diff --git a/src/components/Card.js b/src/components/Card.js index e5d2952c7..be4267fbf 100644 --- a/src/components/Card.js +++ b/src/components/Card.js @@ -1,14 +1,7 @@ import React, {Component} from 'react' import PropTypes from 'prop-types' -import { - MovableCardWrapper, - CardHeader, - CardRightContent, - CardTitle, - Detail, - Footer -} from 'rt/styles/Base' +import {MovableCardWrapper, CardHeader, CardRightContent, CardTitle, Detail, Footer} from 'rt/styles/Base' import InlineInput from 'rt/widgets/InlineInput' import Tag from './Card/Tag' import DeleteButton from 'rt/widgets/DeleteButton' @@ -19,7 +12,7 @@ class Card extends Component { e.stopPropagation() } - render() { + render() { const { showDeleteButton, style, @@ -38,38 +31,64 @@ class Card extends Component { t } = this.props - const updateCard = (card) => { + const updateCard = card => { onChange({...card, id}) } return ( - + - {editable ? updateCard({title: value})} /> : title} + {editable ? ( + updateCard({title: value})} + /> + ) : ( + title + )} - {editable ? updateCard({label: value})} /> : label} + {editable ? ( + updateCard({label: value})} + /> + ) : ( + label + )} {showDeleteButton && } - {editable ? updateCard({description: value})} /> : description} + {editable ? ( + updateCard({description: value})} + /> + ) : ( + description + )} - {tags && tags.length> 0 && ( -
- {tags.map(tag => ( - - ))} -
- )} + {tags && + tags.length > 0 && ( +
+ {tags.map(tag => ( + + ))} +
+ )}
- ) + ) } } @@ -84,7 +103,7 @@ Card.propTypes = { title: PropTypes.string.isRequired, label: PropTypes.string, description: PropTypes.string, - tags: PropTypes.array, + tags: PropTypes.array } Card.defaultProps = { diff --git a/src/components/index.js b/src/components/index.js index f5c7a754c..969c450da 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -6,7 +6,7 @@ import NewLaneForm from './NewLaneForm' import NewCardForm from './NewCardForm' import AddCardLink from './AddCardLink' import NewLaneSection from './NewLaneSection' -import {GlobalStyle, Section, BoardWrapper, ScrollableLane } from 'rt/styles/Base' +import {GlobalStyle, Section, BoardWrapper, ScrollableLane} from 'rt/styles/Base' export default { GlobalStyle, @@ -20,5 +20,5 @@ export default { NewLaneSection, NewCardForm, Card, - AddCardLink, + AddCardLink } diff --git a/src/controllers/Board.js b/src/controllers/Board.js index 4e5c06673..45a0aa9c7 100644 --- a/src/controllers/Board.js +++ b/src/controllers/Board.js @@ -11,6 +11,7 @@ import boardReducer from 'rt/reducers/BoardReducer' const middlewares = process.env.REDUX_LOGGING ? [logger] : [] export default class Board extends Component { + state = {isDown: false, startPos: 0, currentPos: 0, isBoardMoving: false, isBoardClicked: false} constructor({id}) { super() this.store = this.getStore() @@ -25,6 +26,7 @@ export default class Board extends Component { render() { const {id, className, components} = this.props const allClassNames = classNames('react-trello-board', className || '') + return ( <> @@ -33,8 +35,34 @@ export default class Board extends Component { id={this.id} {...this.props} className={allClassNames} + isBoardMoving={this.state.isBoardMoving} + isBoardClicked={this.state.isBoardClicked} + interactions={{ + onMouseDown: event => { + this.setState({isDown: true, startPos: event.pageX, isBoardMoving: false, isBoardClicked: true}) + }, + onMouseUp: event => { + const el = document.querySelector('.react-trello-board-wrapper') + this.setState({ + isDown: false, + isBoardClicked: false, + currentPos: el.getBoundingClientRect().x + 8, + isBoardMoving: false + }) + }, + onMouseMove: event => { + if (this.state.isDown) { + this.setState({isBoardMoving: true}) + const el = document.querySelector('.react-trello-board-wrapper') + // prettier-ignore + const moveX = event.pageX <= el.parentElement.getBoundingClientRect().width / 6 ? 0 : Math.abs(this.state.startPos - event.pageX + this.state.currentPos) + + el.style.transform = `translateX(-${moveX}px)` + } + } + }} /> - + ) } diff --git a/src/controllers/BoardContainer.js b/src/controllers/BoardContainer.js index 7603b8940..554462041 100644 --- a/src/controllers/BoardContainer.js +++ b/src/controllers/BoardContainer.js @@ -7,10 +7,11 @@ import PropTypes from 'prop-types' import pick from 'lodash/pick' import isEqual from 'lodash/isEqual' import Lane from './Lane' -import { PopoverWrapper } from 'react-popopo' +import {PopoverWrapper} from 'react-popopo' import * as boardActions from 'rt/actions/BoardActions' import * as laneActions from 'rt/actions/LaneActions' +import {CustomPopoverContentWrapper} from '../styles/Base' class BoardContainer extends Component { state = { @@ -136,6 +137,9 @@ class BoardContainer extends Component { laneStyle, onCardMoveAcrossLanes, t, + isBoardMoving, + isBoardClicked, + interactions, ...otherProps } = this.props @@ -169,7 +173,11 @@ class BoardContainer extends Component { return ( - + {laneToRender} : laneToRender })} - + {canAddLanes && ( - {editable && !addLaneMode ? : ( - addLaneMode && + {editable && !addLaneMode ? ( + + ) : ( + addLaneMode && )} )} @@ -250,11 +260,11 @@ BoardContainer.propTypes = { laneDragClass: PropTypes.string, laneDropClass: PropTypes.string, onCardMoveAcrossLanes: PropTypes.func.isRequired, - t: PropTypes.func.isRequired, + t: PropTypes.func.isRequired } BoardContainer.defaultProps = { - t: v=>v, + t: v => v, onDataChange: () => {}, handleDragStart: () => {}, handleDragEnd: () => {}, diff --git a/src/controllers/Lane.js b/src/controllers/Lane.js index 3a8303a81..0196b053c 100644 --- a/src/controllers/Lane.js +++ b/src/controllers/Lane.js @@ -47,7 +47,7 @@ class Lane extends Component { sortCards(cards, sortFunction) { if (!cards) return [] if (!sortFunction) return cards - return cards.concat().sort(function (card1, card2) { + return cards.concat().sort(function(card1, card2) { return sortFunction(card1, card2) }) } @@ -328,4 +328,7 @@ const mapDispatchToProps = dispatch => ({ actions: bindActionCreators(laneActions, dispatch) }) -export default connect(null, mapDispatchToProps)(Lane) +export default connect( + null, + mapDispatchToProps +)(Lane) diff --git a/src/index.js b/src/index.js index 650203e2b..4c67f8ff3 100644 --- a/src/index.js +++ b/src/index.js @@ -13,22 +13,14 @@ import widgets from './widgets' import createTranslate from './helpers/createTranslate' -export { - Draggable, - Container, - BoardContainer, - Lane, - createTranslate, - locales, - widgets -} +export {Draggable, Container, BoardContainer, Lane, createTranslate, locales, widgets} -export { DefaultComponents as components } +export {DefaultComponents as components} -const DEFAULT_LANG='en' +const DEFAULT_LANG = 'en' -export default ({ components, lang=DEFAULT_LANG, ...otherProps }) => { - deprecationWarnings(otherProps); +export default ({components, lang = DEFAULT_LANG, ...otherProps}) => { + deprecationWarnings(otherProps) const translate = createTranslate(locales[lang].translation) return } diff --git a/src/styles/Base.js b/src/styles/Base.js index c8ab5896a..cf5553b3f 100644 --- a/src/styles/Base.js +++ b/src/styles/Base.js @@ -1,4 +1,4 @@ -import {PopoverContainer, PopoverContent} from 'react-popopo' +import {PopoverContainer, PopoverContent, PopoverWrapper} from 'react-popopo' import styled, {createGlobalStyle, css} from 'styled-components' export const GlobalStyle = createGlobalStyle` @@ -88,6 +88,22 @@ export const BoardWrapper = styled.div` flex-direction: row; align-items: flex-start; height: 100vh; + position: relative; + overflow: hidden; // 🟢 +` + +export const CustomPopoverContentWrapper = styled(PopoverWrapper)` + position: absolute; + top: 0; + left: 0em; + height: 100%; + cursor: grab; + ${props => + (props.isBoardMoving || props.isBoardClicked) && + ` + user-select: none; + cursor: grabbing; + `}; ` export const Header = styled.header`