Widget

by evgkch

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.1/react-with-addons.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.1/JSXTransformer.js"></script>
<div id="app"></div>

SCSS

$widget-color: rgb(240,240,240);
$green-color: rgb(29, 182, 119);
$yellow-color: rgb(255, 191, 31);
$red-color: rgb(214, 0, 0);

body {
  background-color: rgb(30, 30, 30);
  margin: 0;
}

.frame {
  position: absolute;
  width: 100%;
  height: 100%;
}

.widget {
  user-select: none;
  position: absolute;
  -webkit-box-shadow: 0px 6px 14px 0px rgba(0,0,0,0.46);
  -moz-box-shadow: 0px 6px 14px 0px rgba(0,0,0,0.46);
  box-shadow: 0px 6px 14px 0px rgba(0,0,0,0.46);
  .header {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    border: solid 1px $widget-color;
    background-color: $widget-color;
    .expand, .toggle, .close {
      width: 15px;
      height: 15px;
      border-radius: 100%;
      margin: 5px 5px 5px 0;
      cursor: default;
      opacity: 0.6;
      transition: all 0.3s;
      &:hover {
        opacity: 1;
      }
    }
    .expand {
      background-color: $green-color;
    }
    .toggle {
      background-color: $yellow-color;
    }
    .close {
      background-color: $red-color;
    }
  }
  .label {
    display: flex;
    height: 100%;
    flex-direction: column;
    position: relative;
    padding: 15px;
    background-color: white;
    border-left: solid 1px $widget-color;
    border-right: solid 1px $widget-color;
    border-bottom: solid 1px $widget-color;
    .resize {
      width: 15px;
      height: 15px;
      background-color: $widget-color;
      position: absolute;
      right: 0px;
      bottom: -1px;
      cursor: se-resize;
      user-select: none;
    }
  }
}

Babel + JSX

class Store {
	constructor(storeID, data) {
  	this.storeID = storeID;
    this.state = data || {};
  }
	update(state) {
  	let bufferStore = Object.assign({}, this.state, state);
  	this.state = bufferStore;
    updateApp();
  }
  view() {
  	console.log(this)
  }
}

const globalStore = new Store('GLOBAL_STORE');

function setCoordinates(x, y) {
	globalStore.update({ x, y })
}

const updateApp = () => React.render(
	<App />,
  document.getElementById('app')
);

class App extends React.Component {
	constructor(props) {
  	super(props);
  }
  render() {
  	return (
    	<Widgets>
        {Array.from({ length: 10 }, (v, k) =>
        	<Example key={k} content={`Widget ${k}`} />
        )}
      </Widgets>
    );
  }
}

class Example extends React.Component {
	constructor(props) {
  	super(props);
  }
  render() {
  	return (
    	<div>{this.props.content}</div>
    );
  }
}

class Widgets extends React.Component {
	constructor(props) {
  	super(props);
    this.state = {
    	frameX: 0,
      frameY: 0,
      _isMouseDown: false,
      activeWidgetId: -1,
      widgetsOrder: new Map(),
    }
  }
  componentDidMount() {
  	const { children } = this.props;
    const entries = children.map((child, index) => [child.key, index * 10]);
  	this.setState({ widgetsOrder: new Map(entries) });
  }
  listenFrame(e) {
  	this.setState({ frameX: e.pageX, frameY: e.pageY });
  }
  checkMouseDown(flag) {
  	flag
    	? this.setState({ _isMouseDown: flag, })
      : this.setState({
      	_isMouseDown: flag,
        activeWidgetId: -1,
      })
  }
  transformWidget(id) {
  	const { widgetsOrder } = this.state;
  	this.setState({
    	activeWidgetId: id,
      widgetsOrder: this.getWidgetsOrder(widgetsOrder, id),
    });
  }
  getWidgetsOrder(widgetsOrder, id) {
  	let keys = Array.from(widgetsOrder.keys());
    const keysLength = keys.length;
    if (keys[keysLength - 1] === id.toString()) {
    	return widgetsOrder;
    } else {
    	const index = keys.indexOf(id.toString());
   ...