mirror of
https://github.com/storybookjs/storybook.git
synced 2025-04-04 19:21:07 +08:00
Merge branch 'iframe-mode'
This commit is contained in:
commit
20f7e217f4
86
dist/client/data.js
vendored
86
dist/client/data.js
vendored
@ -1,34 +1,76 @@
|
||||
"use strict";
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
var _extends2 = require("babel-runtime/helpers/extends");
|
||||
var _stringify = require('babel-runtime/core-js/json/stringify');
|
||||
|
||||
var _stringify2 = _interopRequireDefault(_stringify);
|
||||
|
||||
var _extends2 = require('babel-runtime/helpers/extends');
|
||||
|
||||
var _extends3 = _interopRequireDefault(_extends2);
|
||||
|
||||
var _keys = require("babel-runtime/core-js/object/keys");
|
||||
var _keys = require('babel-runtime/core-js/object/keys');
|
||||
|
||||
var _keys2 = _interopRequireDefault(_keys);
|
||||
|
||||
exports.setData = setData;
|
||||
exports.watchData = watchData;
|
||||
exports.getData = getData;
|
||||
exports.getDataKey = getDataKey;
|
||||
exports.getRequestKey = getRequestKey;
|
||||
|
||||
var _pageBus = require('page-bus');
|
||||
|
||||
var _pageBus2 = _interopRequireDefault(_pageBus);
|
||||
|
||||
var _uuid = require('uuid');
|
||||
|
||||
var _uuid2 = _interopRequireDefault(_uuid);
|
||||
|
||||
var _queryString = require('query-string');
|
||||
|
||||
var _queryString2 = _interopRequireDefault(_queryString);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
var data = {};
|
||||
var parsedQs = _queryString2.default.parse(window.location.search);
|
||||
// We need to check whether we are inside a iframe or not.
|
||||
// This is used by here and as well as in the UI
|
||||
var iframeMode = Boolean(parsedQs.iframe);
|
||||
|
||||
// We need to create a unique Id for each page. We need to communicate
|
||||
// using this id as a namespace. Otherwise, each every iframe will get the
|
||||
// data.
|
||||
// We create a new UUID if this is main page. Then, this is used by UI to
|
||||
// create queryString param when creating the iframe.
|
||||
// If we are in the iframe, we'll get it from the queryString.
|
||||
var dataId = iframeMode ? parsedQs.dataId : _uuid2.default.v4();
|
||||
var data = { iframeMode: iframeMode, dataId: dataId };
|
||||
|
||||
var handlers = [];
|
||||
var bus = (0, _pageBus2.default)();
|
||||
|
||||
function setData(fields) {
|
||||
(0, _keys2.default)(fields).forEach(function (key) {
|
||||
data[key] = fields[key];
|
||||
});
|
||||
|
||||
handlers.forEach(function (handler) {
|
||||
return handler(getData());
|
||||
});
|
||||
// We only need to handle setData if we are in the main page. Otherwise,
|
||||
// we don't need to handle data come from the live changes.
|
||||
if (!iframeMode) {
|
||||
// In page-bus, we must send non-identical data.
|
||||
// Otherwise, it'll cache and won't trigger.
|
||||
// That's why we are setting the __lastUpdated value here.
|
||||
var __lastUpdated = Date.now();
|
||||
var newData = (0, _extends3.default)({}, data, { __lastUpdated: __lastUpdated });
|
||||
bus.emit(getDataKey(), (0, _stringify2.default)(newData));
|
||||
handlers.forEach(function (handler) {
|
||||
return handler(getData());
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function watchData(fn) {
|
||||
@ -41,4 +83,34 @@ function watchData(fn) {
|
||||
|
||||
function getData() {
|
||||
return (0, _extends3.default)({}, data);
|
||||
}
|
||||
|
||||
function getDataKey() {
|
||||
return 'data-' + data.dataId;
|
||||
}
|
||||
|
||||
function getRequestKey() {
|
||||
return 'data-request-' + data.dataId;
|
||||
}
|
||||
|
||||
if (iframeMode) {
|
||||
// If this is the iframeMode, we need to listen for the data.
|
||||
bus.on(getDataKey(), function (dataString) {
|
||||
var data = JSON.parse(dataString);
|
||||
handlers.forEach(function (handler) {
|
||||
var newData = (0, _extends3.default)({}, data);
|
||||
// we need to set the iframeMode value to true since original data
|
||||
// doesn't have it.
|
||||
newData.iframeMode = true;
|
||||
handler(newData);
|
||||
});
|
||||
});
|
||||
|
||||
// We need to request for the initial data.
|
||||
bus.emit(getRequestKey());
|
||||
} else {
|
||||
// look for initial data request and process it.
|
||||
bus.on(getRequestKey(), function () {
|
||||
bus.emit(getDataKey(), (0, _stringify2.default)(data));
|
||||
});
|
||||
}
|
17
dist/client/index.js
vendored
17
dist/client/index.js
vendored
@ -19,17 +19,21 @@ var _ui2 = _interopRequireDefault(_ui);
|
||||
|
||||
var _data = require('./data');
|
||||
|
||||
var _papers = require('./papers');
|
||||
|
||||
var _papers2 = _interopRequireDefault(_papers);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
var papers = {};
|
||||
|
||||
function paper(paperName, m) {
|
||||
// XXX: Add a better way to create paper and mutate them.
|
||||
m.hot.dispose(function () {
|
||||
delete papers[paperName];
|
||||
delete _papers2.default[paperName];
|
||||
});
|
||||
papers[paperName] = {};
|
||||
|
||||
_papers2.default[paperName] = {};
|
||||
function block(name, fn) {
|
||||
papers[paperName][name] = fn;
|
||||
_papers2.default[paperName][name] = fn;
|
||||
return { block: block };
|
||||
}
|
||||
|
||||
@ -37,13 +41,12 @@ function paper(paperName, m) {
|
||||
}
|
||||
|
||||
function getPapers() {
|
||||
return papers;
|
||||
return _papers2.default;
|
||||
}
|
||||
|
||||
function renderMain(papers) {
|
||||
var data = (0, _data.getData)();
|
||||
data.error = null;
|
||||
data.papers = papers;
|
||||
|
||||
data.selectedPaper = papers[data.selectedPaper] ? data.selectedPaper : (0, _keys2.default)(papers)[0];
|
||||
|
||||
|
7
dist/client/papers.js
vendored
Normal file
7
dist/client/papers.js
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
var papers = {};
|
||||
exports.default = papers;
|
4
dist/client/ui/controls.js
vendored
4
dist/client/ui/controls.js
vendored
@ -50,9 +50,7 @@ var PaperControls = function (_React$Component) {
|
||||
fontFamily: '"Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif',
|
||||
padding: '10px',
|
||||
marginRight: '10px',
|
||||
color: '#444',
|
||||
borderRight: '3px solid #DDD',
|
||||
minHeight: '1500px'
|
||||
color: '#444'
|
||||
};
|
||||
|
||||
var h1Style = {
|
||||
|
41
dist/client/ui/index.js
vendored
41
dist/client/ui/index.js
vendored
@ -10,6 +10,7 @@ var _keys2 = _interopRequireDefault(_keys);
|
||||
|
||||
exports.default = renderUI;
|
||||
exports.getControls = getControls;
|
||||
exports.getIframe = getIframe;
|
||||
exports.renderError = renderError;
|
||||
exports.renderMain = renderMain;
|
||||
|
||||
@ -35,6 +36,10 @@ var _layout2 = _interopRequireDefault(_layout);
|
||||
|
||||
var _data = require('../data');
|
||||
|
||||
var _papers = require('../papers');
|
||||
|
||||
var _papers2 = _interopRequireDefault(_papers);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
var rootEl = document.getElementById('root');
|
||||
@ -51,9 +56,9 @@ function renderUI(data) {
|
||||
'There is no blocks yet!'
|
||||
);
|
||||
|
||||
var paper = data.papers[data.selectedPaper];
|
||||
var paper = _papers2.default[data.selectedPaper];
|
||||
if (paper) {
|
||||
var block = data.papers[data.selectedPaper][data.selectedBlock];
|
||||
var block = _papers2.default[data.selectedPaper][data.selectedBlock];
|
||||
if (block) {
|
||||
try {
|
||||
main = block();
|
||||
@ -68,23 +73,47 @@ function renderUI(data) {
|
||||
|
||||
function getControls(data) {
|
||||
return _react2.default.createElement(_controls2.default, {
|
||||
papers: data.papers,
|
||||
papers: _papers2.default,
|
||||
selectedPaper: data.selectedPaper,
|
||||
selectedBlock: data.selectedBlock,
|
||||
onPaper: setSelectedPaper,
|
||||
onBlock: setSelectedBlock });
|
||||
}
|
||||
|
||||
function getIframe(data) {
|
||||
var iframeStyle = {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
border: '0'
|
||||
};
|
||||
|
||||
// We need to send iframe=true and dataId via queryString
|
||||
// That's how our data layer can start communicate via the iframe.
|
||||
var queryString = 'iframe=true&dataId=' + data.dataId;
|
||||
|
||||
return _react2.default.createElement('iframe', {
|
||||
style: iframeStyle,
|
||||
src: '/?' + queryString });
|
||||
}
|
||||
|
||||
function renderError(data, error) {
|
||||
var controls = getControls(data);
|
||||
// We always need to render redbox in the mainPage if we get an error.
|
||||
// Since this is an error, this affects to the main page as well.
|
||||
var redBox = _react2.default.createElement(_redboxReact2.default, { error: error });
|
||||
var controls = getControls(data);
|
||||
var root = _react2.default.createElement(_layout2.default, { controls: controls, content: redBox });
|
||||
_reactDom2.default.render(root, rootEl);
|
||||
}
|
||||
|
||||
function renderMain(data, main) {
|
||||
// Inside iframe, we simply render the main component.
|
||||
if (data.iframeMode) {
|
||||
return _reactDom2.default.render(main, rootEl);
|
||||
}
|
||||
|
||||
// Inside the main page, we simply render iframe.
|
||||
var controls = getControls(data);
|
||||
var root = _react2.default.createElement(_layout2.default, { controls: controls, content: main });
|
||||
var root = _react2.default.createElement(_layout2.default, { controls: controls, content: getIframe(data) });
|
||||
_reactDom2.default.render(root, rootEl);
|
||||
}
|
||||
|
||||
@ -92,7 +121,7 @@ function renderMain(data, main) {
|
||||
function setSelectedPaper(paper) {
|
||||
var data = (0, _data.getData)();
|
||||
data.selectedPaper = paper;
|
||||
data.selectedBlock = (0, _keys2.default)(data.papers[paper])[0];
|
||||
data.selectedBlock = (0, _keys2.default)(_papers2.default[paper])[0];
|
||||
(0, _data.setData)(data);
|
||||
}
|
||||
|
||||
|
112
dist/client/ui/layout.js
vendored
112
dist/client/ui/layout.js
vendored
@ -4,29 +4,105 @@ Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
|
||||
|
||||
var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
|
||||
|
||||
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
|
||||
|
||||
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
|
||||
|
||||
var _createClass2 = require('babel-runtime/helpers/createClass');
|
||||
|
||||
var _createClass3 = _interopRequireDefault(_createClass2);
|
||||
|
||||
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
|
||||
|
||||
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
|
||||
|
||||
var _inherits2 = require('babel-runtime/helpers/inherits');
|
||||
|
||||
var _inherits3 = _interopRequireDefault(_inherits2);
|
||||
|
||||
var _react = require('react');
|
||||
|
||||
var _react2 = _interopRequireDefault(_react);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
var Layout = function Layout(_ref) {
|
||||
var controls = _ref.controls;
|
||||
var content = _ref.content;
|
||||
return _react2.default.createElement(
|
||||
'div',
|
||||
{ style: {} },
|
||||
_react2.default.createElement(
|
||||
'div',
|
||||
{ style: { width: '250px', float: 'left' } },
|
||||
controls
|
||||
),
|
||||
_react2.default.createElement(
|
||||
'div',
|
||||
{ style: { marginLeft: '250px' } },
|
||||
content
|
||||
)
|
||||
);
|
||||
};
|
||||
var Layout = function (_React$Component) {
|
||||
(0, _inherits3.default)(Layout, _React$Component);
|
||||
|
||||
function Layout() {
|
||||
(0, _classCallCheck3.default)(this, Layout);
|
||||
return (0, _possibleConstructorReturn3.default)(this, (0, _getPrototypeOf2.default)(Layout).apply(this, arguments));
|
||||
}
|
||||
|
||||
(0, _createClass3.default)(Layout, [{
|
||||
key: 'render',
|
||||
value: function render() {
|
||||
var _props = this.props;
|
||||
var controls = _props.controls;
|
||||
var content = _props.content;
|
||||
var height = this.state.height;
|
||||
|
||||
|
||||
var rootStyles = {
|
||||
height: height
|
||||
};
|
||||
var controlsStyle = {
|
||||
width: '240px',
|
||||
float: 'left',
|
||||
height: '100%',
|
||||
overflowY: 'auto'
|
||||
};
|
||||
// borderRight: '3px solid #DDD',
|
||||
var contentStyle = {
|
||||
height: height,
|
||||
marginLeft: '250px',
|
||||
border: '1px solid #DDD',
|
||||
borderRadius: '4px',
|
||||
boxShadow: '0px 2px 6px -1px #b8b8b8'
|
||||
};
|
||||
|
||||
return _react2.default.createElement(
|
||||
'div',
|
||||
{ style: rootStyles },
|
||||
_react2.default.createElement(
|
||||
'div',
|
||||
{ style: controlsStyle },
|
||||
controls
|
||||
),
|
||||
_react2.default.createElement(
|
||||
'div',
|
||||
{ style: contentStyle },
|
||||
content
|
||||
)
|
||||
);
|
||||
}
|
||||
}, {
|
||||
key: 'componentWillMount',
|
||||
value: function componentWillMount() {
|
||||
this.updateHeight();
|
||||
}
|
||||
}, {
|
||||
key: 'componentDidMount',
|
||||
value: function componentDidMount() {
|
||||
window.addEventListener("resize", this.updateHeight.bind(this));
|
||||
}
|
||||
}, {
|
||||
key: 'updateHeight',
|
||||
value: function updateHeight() {
|
||||
var _document = document;
|
||||
var documentElement = _document.documentElement;
|
||||
var body = _document.body;
|
||||
|
||||
var height = documentElement.clientHeight || body.clientHeight;
|
||||
height -= 20;
|
||||
this.setState({ height: height });
|
||||
}
|
||||
}]);
|
||||
return Layout;
|
||||
}(_react2.default.Component);
|
||||
|
||||
exports.default = Layout;
|
@ -9,14 +9,17 @@
|
||||
"babel-core": "^6.3.15",
|
||||
"babel-loader": "^6.2.0",
|
||||
"babel-preset-es2015": "^6.3.13",
|
||||
"babel-preset-stage-2": "^6.3.13",
|
||||
"babel-preset-react": "^6.3.13",
|
||||
"babel-preset-stage-2": "^6.3.13",
|
||||
"babel-runtime": "^6.3.14",
|
||||
"expect": "^1.6.0",
|
||||
"express": "^4.13.3",
|
||||
"node-libs-browser": "^0.5.2",
|
||||
"page-bus": "^3.0.1",
|
||||
"query-string": "^3.0.3",
|
||||
"redbox-react": "^1.2.2",
|
||||
"stack-source-map": "^1.0.4",
|
||||
"uuid": "^2.0.1",
|
||||
"webpack": "^1.9.11",
|
||||
"webpack-dev-middleware": "^1.2.0",
|
||||
"webpack-hot-middleware": "^2.2.0"
|
||||
|
@ -1,5 +1,23 @@
|
||||
const data = {};
|
||||
import createPageBus from 'page-bus';
|
||||
import UUID from 'uuid';
|
||||
import QS from 'query-string';
|
||||
|
||||
const parsedQs = QS.parse(window.location.search);
|
||||
// We need to check whether we are inside a iframe or not.
|
||||
// This is used by here and as well as in the UI
|
||||
const iframeMode = Boolean(parsedQs.iframe);
|
||||
|
||||
// We need to create a unique Id for each page. We need to communicate
|
||||
// using this id as a namespace. Otherwise, each every iframe will get the
|
||||
// data.
|
||||
// We create a new UUID if this is main page. Then, this is used by UI to
|
||||
// create queryString param when creating the iframe.
|
||||
// If we are in the iframe, we'll get it from the queryString.
|
||||
const dataId = iframeMode? parsedQs.dataId : UUID.v4();
|
||||
const data = {iframeMode, dataId};
|
||||
|
||||
const handlers = [];
|
||||
const bus = createPageBus();
|
||||
|
||||
export function setData(fields) {
|
||||
Object
|
||||
@ -8,7 +26,17 @@ export function setData(fields) {
|
||||
data[key] = fields[key]
|
||||
});
|
||||
|
||||
handlers.forEach(handler => handler(getData()));
|
||||
// We only need to handle setData if we are in the main page. Otherwise,
|
||||
// we don't need to handle data come from the live changes.
|
||||
if (!iframeMode) {
|
||||
// In page-bus, we must send non-identical data.
|
||||
// Otherwise, it'll cache and won't trigger.
|
||||
// That's why we are setting the __lastUpdated value here.
|
||||
const __lastUpdated = Date.now();
|
||||
const newData = {...data, __lastUpdated};
|
||||
bus.emit(getDataKey(), JSON.stringify(newData));
|
||||
handlers.forEach(handler => handler(getData()));
|
||||
}
|
||||
};
|
||||
|
||||
export function watchData(fn) {
|
||||
@ -22,3 +50,33 @@ export function watchData(fn) {
|
||||
export function getData() {
|
||||
return {...data};
|
||||
}
|
||||
|
||||
export function getDataKey() {
|
||||
return `data-${data.dataId}`;
|
||||
}
|
||||
|
||||
export function getRequestKey() {
|
||||
return `data-request-${data.dataId}`;
|
||||
}
|
||||
|
||||
if (iframeMode) {
|
||||
// If this is the iframeMode, we need to listen for the data.
|
||||
bus.on(getDataKey(), function(dataString) {
|
||||
const data = JSON.parse(dataString);
|
||||
handlers.forEach(handler => {
|
||||
const newData = {...data};
|
||||
// we need to set the iframeMode value to true since original data
|
||||
// doesn't have it.
|
||||
newData.iframeMode = true;
|
||||
handler(newData);
|
||||
});
|
||||
});
|
||||
|
||||
// We need to request for the initial data.
|
||||
bus.emit(getRequestKey());
|
||||
} else {
|
||||
// look for initial data request and process it.
|
||||
bus.on(getRequestKey(), function() {
|
||||
bus.emit(getDataKey(), JSON.stringify(data));
|
||||
})
|
||||
}
|
||||
|
@ -5,12 +5,14 @@ import {
|
||||
watchData
|
||||
} from './data';
|
||||
|
||||
const papers = {};
|
||||
import papers from './papers';
|
||||
|
||||
export function paper(paperName, m) {
|
||||
// XXX: Add a better way to create paper and mutate them.
|
||||
m.hot.dispose(() => {
|
||||
delete papers[paperName];
|
||||
});
|
||||
|
||||
papers[paperName] = {};
|
||||
function block(name, fn) {
|
||||
papers[paperName][name] = fn;
|
||||
@ -27,7 +29,6 @@ export function getPapers() {
|
||||
export function renderMain(papers) {
|
||||
const data = getData();
|
||||
data.error = null;
|
||||
data.papers = papers;
|
||||
|
||||
data.selectedPaper =
|
||||
(papers[data.selectedPaper])? data.selectedPaper : Object.keys(papers)[0];
|
||||
|
2
src/client/papers.js
Normal file
2
src/client/papers.js
Normal file
@ -0,0 +1,2 @@
|
||||
const papers = {};
|
||||
export default papers;
|
4
src/client/ui/controls.js
vendored
4
src/client/ui/controls.js
vendored
@ -7,9 +7,7 @@ export default class PaperControls extends React.Component {
|
||||
fontFamily: '"Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif',
|
||||
padding: '10px',
|
||||
marginRight: '10px',
|
||||
color: '#444',
|
||||
borderRight: '3px solid #DDD',
|
||||
minHeight: '1500px'
|
||||
color: '#444'
|
||||
};
|
||||
|
||||
const h1Style = {
|
||||
|
@ -4,6 +4,7 @@ import ReadBox from 'redbox-react';
|
||||
import PaperControls from './controls';
|
||||
import Layout from './layout';
|
||||
import {setData, getData} from '../data';
|
||||
import papers from '../papers';
|
||||
|
||||
const rootEl = document.getElementById('root');
|
||||
|
||||
@ -15,9 +16,9 @@ export default function renderUI(data) {
|
||||
// default main
|
||||
let main = (<p>There is no blocks yet!</p>);
|
||||
|
||||
const paper = data.papers[data.selectedPaper];
|
||||
const paper = papers[data.selectedPaper];
|
||||
if (paper) {
|
||||
const block = data.papers[data.selectedPaper][data.selectedBlock];
|
||||
const block = papers[data.selectedPaper][data.selectedBlock];
|
||||
if (block) {
|
||||
try {
|
||||
main = block();
|
||||
@ -33,7 +34,7 @@ export default function renderUI(data) {
|
||||
export function getControls(data) {
|
||||
return (
|
||||
<PaperControls
|
||||
papers={data.papers}
|
||||
papers={papers}
|
||||
selectedPaper={data.selectedPaper}
|
||||
selectedBlock={data.selectedBlock}
|
||||
onPaper={setSelectedPaper}
|
||||
@ -41,16 +42,42 @@ export function getControls(data) {
|
||||
);
|
||||
}
|
||||
|
||||
export function getIframe(data) {
|
||||
const iframeStyle = {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
border: '0'
|
||||
};
|
||||
|
||||
// We need to send iframe=true and dataId via queryString
|
||||
// That's how our data layer can start communicate via the iframe.
|
||||
const queryString = `iframe=true&dataId=${data.dataId}`;
|
||||
|
||||
return (
|
||||
<iframe
|
||||
style={iframeStyle}
|
||||
src={`/?${queryString}`}/>
|
||||
);
|
||||
}
|
||||
|
||||
export function renderError(data, error) {
|
||||
const controls = getControls(data);
|
||||
// We always need to render redbox in the mainPage if we get an error.
|
||||
// Since this is an error, this affects to the main page as well.
|
||||
const redBox = (<ReadBox error={error}/>);
|
||||
const root = (<Layout controls={controls} content={redBox}/>);
|
||||
const controls = getControls(data);
|
||||
const root = (<Layout controls={controls} content={redBox} />);
|
||||
ReactDOM.render(root, rootEl);
|
||||
}
|
||||
|
||||
export function renderMain(data, main) {
|
||||
// Inside iframe, we simply render the main component.
|
||||
if (data.iframeMode) {
|
||||
return ReactDOM.render(main, rootEl);
|
||||
}
|
||||
|
||||
// Inside the main page, we simply render iframe.
|
||||
const controls = getControls(data);
|
||||
const root = (<Layout controls={controls} content={main}/>);
|
||||
const root = (<Layout controls={controls} content={getIframe(data)}/>);
|
||||
ReactDOM.render(root, rootEl);
|
||||
}
|
||||
|
||||
@ -58,7 +85,7 @@ export function renderMain(data, main) {
|
||||
function setSelectedPaper(paper) {
|
||||
const data = getData();
|
||||
data.selectedPaper = paper;
|
||||
data.selectedBlock = Object.keys(data.papers[paper])[0];
|
||||
data.selectedBlock = Object.keys(papers[paper])[0];
|
||||
setData(data);
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,54 @@
|
||||
import React from 'react';
|
||||
|
||||
const Layout = ({controls, content}) => (
|
||||
<div style={{}}>
|
||||
<div style={{width: '250px', float: 'left'}}>
|
||||
{controls}
|
||||
</div>
|
||||
<div style={{marginLeft: '250px'}}>
|
||||
{content}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
class Layout extends React.Component {
|
||||
render() {
|
||||
const {controls, content} = this.props;
|
||||
const {height} = this.state;
|
||||
|
||||
const rootStyles = {
|
||||
height
|
||||
};
|
||||
const controlsStyle = {
|
||||
width: '240px',
|
||||
float: 'left',
|
||||
height: '100%',
|
||||
overflowY: 'auto',
|
||||
// borderRight: '3px solid #DDD',
|
||||
};
|
||||
const contentStyle = {
|
||||
height,
|
||||
marginLeft: '250px',
|
||||
border: '1px solid #DDD',
|
||||
borderRadius: '4px',
|
||||
boxShadow: '0px 2px 6px -1px #b8b8b8'
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={rootStyles}>
|
||||
<div style={controlsStyle}>
|
||||
{controls}
|
||||
</div>
|
||||
<div style={contentStyle}>
|
||||
{content}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
this.updateHeight();
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
window.addEventListener("resize", this.updateHeight.bind(this));
|
||||
}
|
||||
|
||||
updateHeight() {
|
||||
const {documentElement, body} = document;
|
||||
let height = documentElement.clientHeight|| body.clientHeight;
|
||||
height -= 20;
|
||||
this.setState({height});
|
||||
}
|
||||
}
|
||||
|
||||
export default Layout;
|
||||
|
Loading…
x
Reference in New Issue
Block a user