From a01fd739bd678c28df8be4d43fbae2123cc633ee Mon Sep 17 00:00:00 2001 From: Fabian Mueller Date: Tue, 9 Aug 2016 21:44:21 +0200 Subject: [PATCH 1/2] Add color picker dependency; use color picker in storage dialog --- .../modals/PreferencesModal/StorageItem.js | 43 ++++++++++++------- package.json | 2 + 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/browser/main/modals/PreferencesModal/StorageItem.js b/browser/main/modals/PreferencesModal/StorageItem.js index 374c9218..b298d26f 100644 --- a/browser/main/modals/PreferencesModal/StorageItem.js +++ b/browser/main/modals/PreferencesModal/StorageItem.js @@ -8,6 +8,7 @@ import store from 'browser/main/store' const electron = require('electron') const { shell, remote } = electron const { Menu, MenuItem } = remote +import { SketchPicker } from 'react-color' class UnstyledFolderItem extends React.Component { constructor (props) { @@ -16,6 +17,7 @@ class UnstyledFolderItem extends React.Component { this.state = { status: 'IDLE', folder: { + showColumnPicker: false, color: props.color, name: props.name } @@ -50,22 +52,18 @@ class UnstyledFolderItem extends React.Component { } handleColorButtonClick (e) { - var menu = new Menu() + const folder = Object.assign({}, this.state.folder, { showColumnPicker: true }) + this.setState({ folder }) + } - consts.FOLDER_COLORS.forEach((color, index) => { - menu.append(new MenuItem({ - label: consts.FOLDER_COLOR_NAMES[index], - click: (e) => { - let { folder } = this.state - folder.color = color - this.setState({ - folder - }) - } - })) - }) + handleColorChange (color) { + const folder = Object.assign({}, this.state.folder, { color: color.hex }) + this.setState({ folder }) + } - menu.popup(remote.getCurrentWindow()) + handleColorPickerClose (event) { + const folder = Object.assign({}, this.state.folder, { showColumnPicker: false }) + this.setState({ folder }) } handleCancelButtonClick (e) { @@ -75,12 +73,27 @@ class UnstyledFolderItem extends React.Component { } renderEdit (e) { + const popover = { position: 'absolute', zIndex: 2 } + const cover = { + position: 'fixed', + top: 0, right: 0, bottom: 0, left: 0 + } return (
Date: Wed, 10 Aug 2016 17:28:16 +0200 Subject: [PATCH 2/2] Set color picker pos correctly such that it is restricted to the viewport --- .../modals/PreferencesModal/StorageItem.js | 54 ++++++++++++++----- .../modals/PreferencesModal/StoragesTab.js | 13 ++++- browser/main/modals/PreferencesModal/index.js | 12 ++++- 3 files changed, 65 insertions(+), 14 deletions(-) diff --git a/browser/main/modals/PreferencesModal/StorageItem.js b/browser/main/modals/PreferencesModal/StorageItem.js index b298d26f..68cfb1fe 100644 --- a/browser/main/modals/PreferencesModal/StorageItem.js +++ b/browser/main/modals/PreferencesModal/StorageItem.js @@ -1,4 +1,5 @@ import React, { PropTypes } from 'react' +import ReactDOM from 'react-dom' import CSSModules from 'browser/lib/CSSModules' import styles from './StorageItem.styl' import consts from 'browser/lib/consts' @@ -18,6 +19,7 @@ class UnstyledFolderItem extends React.Component { status: 'IDLE', folder: { showColumnPicker: false, + colorPickerPos: { left: 0, top: 0 }, color: props.color, name: props.name } @@ -52,8 +54,22 @@ class UnstyledFolderItem extends React.Component { } handleColorButtonClick (e) { - const folder = Object.assign({}, this.state.folder, { showColumnPicker: true }) - this.setState({ folder }) + const folder = Object.assign({}, this.state.folder, { showColumnPicker: true, colorPickerPos: { left: 0, top: 0 } }) + this.setState({ folder }, function() { + // After the color picker has been painted, re-calculate its position + // by comparing its dimensions to the host dimensions. + const { hostBoundingBox } = this.props; + const colorPickerNode = ReactDOM.findDOMNode(this.refs.colorPicker) + const colorPickerBox = colorPickerNode.getBoundingClientRect() + const offsetTop = hostBoundingBox.bottom - colorPickerBox.bottom + const folder = Object.assign({}, this.state.folder, { + colorPickerPos: { + left: 25, + top: offsetTop < 0 ? offsetTop - 5 : 0 // subtract 5px for aestetics + } + }) + this.setState({ folder }) + }) } handleColorChange (color) { @@ -78,6 +94,9 @@ class UnstyledFolderItem extends React.Component { position: 'fixed', top: 0, right: 0, bottom: 0, left: 0 } + const pickerStyle = Object.assign({}, { + position: 'absolute' + }, this.state.folder.colorPickerPos) return (
@@ -88,10 +107,13 @@ class UnstyledFolderItem extends React.Component {
this.handleColorPickerClose() } /> - this.handleColorChange(color) } - onChangeComplete={ (color) => this.handleColorChange(color) } /> +
+ this.handleColorChange(color) } + onChangeComplete={ (color) => this.handleColorChange(color) } /> +
: null } @@ -154,13 +176,12 @@ class UnstyledFolderItem extends React.Component { } handleEditButtonClick (e) { - let { folder } = this.props + let { folder: propsFolder } = this.props + let { folder: stateFolder } = this.state + const folder = Object.assign({}, stateFolder, propsFolder) this.setState({ status: 'EDIT', - folder: { - color: folder.color, - name: folder.name - } + folder }, () => { this.refs.nameInput.select() }) @@ -293,11 +314,12 @@ class StorageItem extends React.Component { } render () { - let { storage } = this.props + let { storage, hostBoundingBox } = this.props let folderList = storage.folders.map((folder) => { return }) return ( @@ -360,6 +382,14 @@ class StorageItem extends React.Component { } StorageItem.propTypes = { + hostBoundingBox: PropTypes.shape({ + bottom: PropTypes.number, + height: PropTypes.number, + left: PropTypes.number, + right: PropTypes.number, + top: PropTypes.number, + width: PropTypes.number + }), storage: PropTypes.shape({ key: PropTypes.string }), diff --git a/browser/main/modals/PreferencesModal/StoragesTab.js b/browser/main/modals/PreferencesModal/StoragesTab.js index f9a7183c..ead759ba 100644 --- a/browser/main/modals/PreferencesModal/StoragesTab.js +++ b/browser/main/modals/PreferencesModal/StoragesTab.js @@ -51,12 +51,15 @@ class StoragesTab extends React.Component { } renderList () { - let { storages } = this.props + let { storages, boundingBox } = this.props + if (!boundingBox) { return null } let storageList = storages.map((storage) => { return }) return ( @@ -217,6 +220,14 @@ class StoragesTab extends React.Component { } StoragesTab.propTypes = { + boundingBox: PropTypes.shape({ + bottom: PropTypes.number, + height: PropTypes.number, + left: PropTypes.number, + right: PropTypes.number, + top: PropTypes.number, + width: PropTypes.number + }), dispatch: PropTypes.func } diff --git a/browser/main/modals/PreferencesModal/index.js b/browser/main/modals/PreferencesModal/index.js index 90c2718e..fead28f4 100644 --- a/browser/main/modals/PreferencesModal/index.js +++ b/browser/main/modals/PreferencesModal/index.js @@ -1,4 +1,5 @@ import React, { PropTypes } from 'react' +import ReactDOM from 'react-dom' import { connect } from 'react-redux' import ConfigTab from './ConfigTab' import InfoTab from './InfoTab' @@ -17,6 +18,8 @@ class Preferences extends React.Component { componentDidMount () { this.refs.root.focus() + const boundingBox = this.getContentBoundingBox() + this.setState({ boundingBox }) } switchTeam (teamId) { @@ -30,6 +33,7 @@ class Preferences extends React.Component { } renderContent () { + const { boundingBox } = this.state; let { dispatch, config, storages } = this.props switch (this.state.currentTab) { @@ -48,6 +52,7 @@ class Preferences extends React.Component { ) } @@ -59,6 +64,11 @@ class Preferences extends React.Component { } } + getContentBoundingBox () { + const node = ReactDOM.findDOMNode(this.refs.content) + return node.getBoundingClientRect(); + } + render () { let content = this.renderContent() @@ -97,7 +107,7 @@ class Preferences extends React.Component {
{navButtons}
-
+
{content}