UNPKG

react-columns

Version:

React component for rendering columns from a list of children with horizontal ordering

519 lines (438 loc) 16.3 kB
/*! * react-columns v1.2.1 - http://novascreen.github.io/react-columns/ * MIT Licensed */ (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(require("react")); else if(typeof define === 'function' && define.amd) define(["react"], factory); else if(typeof exports === 'object') exports["ReactColumns"] = factory(require("react")); else root["ReactColumns"] = factory(root["React"]); })(window, function(__WEBPACK_EXTERNAL_MODULE__0__) { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); /******/ } /******/ }; /******/ /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it /******/ // mode & 2: merge all properties of value into the ns /******/ // mode & 4: return value when already ns object /******/ // mode & 8|1: behave like require /******/ __webpack_require__.t = function(value, mode) { /******/ if(mode & 1) value = __webpack_require__(value); /******/ if(mode & 8) return value; /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; /******/ var ns = Object.create(null); /******/ __webpack_require__.r(ns); /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); /******/ return ns; /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 2); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports) { module.exports = __WEBPACK_EXTERNAL_MODULE__0__; /***/ }), /* 1 */ /***/ (function(module, exports, __webpack_require__) { /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ if (false) { var throwOnDirectAccess, ReactIs; } else { // By explicitly using `prop-types` you are opting into new production behavior. // http://fb.me/prop-types-in-prod module.exports = __webpack_require__(3)(); } /***/ }), /* 2 */ /***/ (function(module, exports, __webpack_require__) { module.exports = __webpack_require__(5); /***/ }), /* 3 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var ReactPropTypesSecret = __webpack_require__(4); function emptyFunction() {} function emptyFunctionWithReset() {} emptyFunctionWithReset.resetWarningCache = emptyFunction; module.exports = function() { function shim(props, propName, componentName, location, propFullName, secret) { if (secret === ReactPropTypesSecret) { // It is still safe when called from React. return; } var err = new Error( 'Calling PropTypes validators directly is not supported by the `prop-types` package. ' + 'Use PropTypes.checkPropTypes() to call them. ' + 'Read more at http://fb.me/use-check-prop-types' ); err.name = 'Invariant Violation'; throw err; }; shim.isRequired = shim; function getShim() { return shim; }; // Important! // Keep this list in sync with production version in `./factoryWithTypeCheckers.js`. var ReactPropTypes = { array: shim, bool: shim, func: shim, number: shim, object: shim, string: shim, symbol: shim, any: shim, arrayOf: getShim, element: shim, elementType: shim, instanceOf: getShim, node: shim, objectOf: getShim, oneOf: getShim, oneOfType: getShim, shape: getShim, exact: getShim, checkPropTypes: emptyFunctionWithReset, resetWarningCache: emptyFunction }; ReactPropTypes.PropTypes = ReactPropTypes; return ReactPropTypes; }; /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED'; module.exports = ReactPropTypesSecret; /***/ }), /* 5 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); // EXTERNAL MODULE: external {"root":"React","commonjs2":"react","commonjs":"react","amd":"react"} var external_root_React_commonjs2_react_commonjs_react_amd_react_ = __webpack_require__(0); var external_root_React_commonjs2_react_commonjs_react_amd_react_default = /*#__PURE__*/__webpack_require__.n(external_root_React_commonjs2_react_commonjs_react_amd_react_); // EXTERNAL MODULE: ./node_modules/prop-types/index.js var prop_types = __webpack_require__(1); var prop_types_default = /*#__PURE__*/__webpack_require__.n(prop_types); // CONCATENATED MODULE: ./src/mq.js var mediaQueries = {}; function mediaQuery() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref$query = _ref.query, query = _ref$query === undefined ? '' : _ref$query, _ref$full = _ref.full, full = _ref$full === undefined ? false : _ref$full, _ref$onChange = _ref.onChange, onChange = _ref$onChange === undefined ? function () {} : _ref$onChange; var result = { query: query, full: full, queryMatches: false, _mq: null }; if (!query) { return result; } function listener(mq) { result.queryMatches = mq.matches; onChange(result.queryMatches); } function removeListener() { result._mq.removeListener(listener); } result.query = !full && query[query.length - 1] !== ')' ? '(' + query + ')' : query; if (!mediaQueries[result.query]) { mediaQueries[result.query] = window.matchMedia(result.query); } result._mq = mediaQueries[result.query]; result.queryMatches = result._mq.matches; result.removeListener = removeListener; result._mq.addListener(listener); return result; } function mediaQueryMapper() { var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref2$queries = _ref2.queries, queries = _ref2$queries === undefined ? [] : _ref2$queries, _ref2$valueKey = _ref2.valueKey, valueKey = _ref2$valueKey === undefined ? 'value' : _ref2$valueKey, _ref2$defaultValue = _ref2.defaultValue, defaultValue = _ref2$defaultValue === undefined ? '' : _ref2$defaultValue, _ref2$onChange = _ref2.onChange, onChange = _ref2$onChange === undefined ? function () {} : _ref2$onChange; var mQs = queries.map(function (query) { return mediaQuery({ query: query.query, full: query.full, onChange: onMqChange }); }); function getValue() { var value = defaultValue; mQs.forEach(function (mQ, i) { if (mQ.queryMatches) { value = queries[i][valueKey]; } }); return value; } function onMqChange(mq) { onChange(getValue()); } function removeListeners() { mQs.forEach(function (mq, i) { mq.removeListener(); }); } return { getValue: getValue, removeListeners: removeListeners }; } // CONCATENATED MODULE: ./src/mapNodesToColumns.js function mapNodesToColumns() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref$children = _ref.children, children = _ref$children === undefined ? [] : _ref$children, _ref$columns = _ref.columns, columns = _ref$columns === undefined ? 1 : _ref$columns, _ref$dimensions = _ref.dimensions, dimensions = _ref$dimensions === undefined ? [] : _ref$dimensions; var nodes = []; var heights = []; if (columns === 1) { return children; } // use dimensions to calculate the best column for each child if (dimensions.length && dimensions.length === children.length) { for (var i = 0; i < columns; i++) { nodes[i] = []; heights[i] = 0; } children.forEach(function (child, i) { var _dimensions$i = dimensions[i], width = _dimensions$i.width, height = _dimensions$i.height; var index = heights.indexOf(Math.min.apply(Math, heights)); nodes[index].push(child); heights[index] += height / width; }); } // equally spread the children across the columns else { var _loop = function _loop(_i) { nodes[_i] = children.filter(function (child, j) { return j % columns === _i; }); }; for (var _i = 0; _i < columns; _i++) { _loop(_i); } } return nodes; } // CONCATENATED MODULE: ./src/index.js function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var src_Columns = function (_Component) { _inherits(Columns, _Component); function Columns(props) { _classCallCheck(this, Columns); var _this = _possibleConstructorReturn(this, _Component.call(this, props)); _this.setColumns = _this.setColumns.bind(_this); _this.state = {}; return _this; } Columns.prototype.componentDidMount = function componentDidMount() { this.updateColumns(this.props); }; Columns.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { var queriesChanged = this.props.queries !== nextProps.queries; var columnsChanged = this.props.columns !== nextProps.columns; if (queriesChanged || columnsChanged) { this.updateColumns(nextProps); } }; Columns.prototype.componentWillUnmount = function componentWillUnmount() { this.removeColumnListeners(); }; Columns.prototype.updateColumns = function updateColumns(props) { if (props.queries.length) { this.removeColumnListeners(); this._columns = mediaQueryMapper({ queries: props.queries, valueKey: 'columns', defaultValue: props.queries.length ? 1 : props.columns, onChange: this.setColumns }); this.setColumns(); } }; Columns.prototype.setColumns = function setColumns() { var _this2 = this; this.setState(function () { return { columns: _this2._columns.getValue() }; }); }; Columns.prototype.removeColumnListeners = function removeColumnListeners() { if (this._columns) { this._columns.removeListeners(); } }; Columns.prototype.renderColumns = function renderColumns(columns) { var _props = this.props, children = _props.children, dimensions = _props.dimensions, gap = _props.gap; var columnStyles = { boxSizing: 'border-box', float: 'left', width: 1 / columns * 100 + '%', paddingLeft: gap, paddingRight: gap }; var renderedColumns = children; if (columns > 1) { var columnsContainers = mapNodesToColumns({ children: children, columns: columns, dimensions: dimensions }); renderedColumns = columnsContainers.map(function (column, i) { return external_root_React_commonjs2_react_commonjs_react_amd_react_default.a.createElement( 'div', { key: i, style: columnStyles }, column ); }); } return renderedColumns; }; Columns.prototype.render = function render() { var _props2 = this.props, className = _props2.className, gap = _props2.gap, rootStyles = _props2.rootStyles; var _state$columns = this.state.columns, columns = _state$columns === undefined ? this.props.columns : _state$columns; var rowStyles = columns === 1 ? {} : { marginLeft: 'calc(' + gap + ' * -1)', marginRight: 'calc(' + gap + ' * -1)' }; return external_root_React_commonjs2_react_commonjs_react_amd_react_default.a.createElement( 'div', { className: className, style: rootStyles }, external_root_React_commonjs2_react_commonjs_react_amd_react_default.a.createElement( 'div', { style: rowStyles }, this.renderColumns(columns), external_root_React_commonjs2_react_commonjs_react_amd_react_default.a.createElement('div', { style: { clear: 'both' } }) ) ); }; return Columns; }(external_root_React_commonjs2_react_commonjs_react_amd_react_["Component"]); src_Columns.defaultProps = { className: '', rootStyles: { overflowX: 'hidden' }, queries: [], columns: 3, gap: '0px' }; src_Columns.propTypes = { className: prop_types_default.a.string, rootStyles: prop_types_default.a.object, queries: prop_types_default.a.array, columns: prop_types_default.a.number, gap: prop_types_default.a.string }; /* harmony default export */ var src = __webpack_exports__["default"] = (src_Columns); /***/ }) /******/ ])["default"]; });