UNPKG

react-spatial

Version:

Components to build React map apps.

356 lines (304 loc) 10.1 kB
import React, { Component } from 'react'; import PropTypes from 'prop-types'; import Checkbox from '../Checkbox'; import Button from '../Button'; var propTypes = { /** * Layers provider. */ layerService: PropTypes.object, /** * CSS class to apply on the container. */ className: PropTypes.string, /** * CSS class to apply on each item. */ classNameItem: PropTypes.string, /** * CSS class to apply to the label element which contains the input. * Unused if you use `renderItem` property. */ classNameInput: PropTypes.string, /** * CSS class to apply to the toggle button which contains the title and the arrow. * Unused if you use `renderItem` property. */ classNameToggle: PropTypes.string, /** * CSS class to apply to the arrow. * Unused if you use `renderItem` property. */ classNameArrow: PropTypes.string, /** * Padding left to apply on each level. */ padding: PropTypes.number, /** * Determine if the item is hidden in the tree or not. * * @param {object} item The item to hide or not. * * @return {bool} true if the item is not displayed in the tree */ isItemHidden: PropTypes.func, /** * Determine the className used by the div containing the parent and its children. */ getParentClassName: PropTypes.func, /** * Custom function to render an item in the tree. * * @param {object} item The item to render. * * @return {node} A jsx node. */ renderItem: PropTypes.func, /** * Custom function to render only the content of an item in the tree. * * @param {object} item The item to render. * * @return {node} A jsx node. */ renderItemContent: PropTypes.func, /** * Object holding title for the layer tree's buttons. */ buttonTitles: PropTypes.shape({ /** * aria-label on checkbox to show layer. */ layerShow: PropTypes.string, /** * aria-label on checkbox to hide layer. */ layerHide: PropTypes.string, /** * title on button to show sublayers. */ subLayerShow: PropTypes.string, /** * title on button to show sublayers. */ subLayerHide: PropTypes.string, }), /** * Translation function. * @param {function} Translation function returning the translated string. */ t: PropTypes.func, }; var defaultProps = { layerService: undefined, className: 'tm-layer-tree', classNameItem: 'tm-layer-tree-item', classNameInput: 'tm-layer-tree-input', classNameToggle: 'tm-layer-tree-toggle', classNameArrow: 'tm-layer-tree-arrow', padding: 30, isItemHidden: function () { return false; }, getParentClassName: function () { return undefined; }, renderItem: null, renderItemContent: null, buttonTitles: { layerShow: 'Show layer', layerHide: 'Hide layer', subLayerShow: 'Show sublayer', subLayerHide: 'Hide sublayer', }, t: function (s) { return s; }, }; var LayerTree = /*@__PURE__*/(function (Component) { function LayerTree(props) { Component.call(this, props); var ref = this.props; var layerService = ref.layerService; var isItemHidden = ref.isItemHidden; var initialExpandedLayerNames = layerService && layerService.getLayers() ? layerService .getLayers() .filter(function (l) { return !isItemHidden(l) && l.getVisibleChildren().length; }) : []; this.state = { layers: layerService ? layerService.getLayers() : [], expandedLayerNames: initialExpandedLayerNames, }; this.updateLayers = this.updateLayers.bind(this); this.olKeys = []; } if ( Component ) LayerTree.__proto__ = Component; LayerTree.prototype = Object.create( Component && Component.prototype ); LayerTree.prototype.constructor = LayerTree; LayerTree.prototype.componentDidMount = function componentDidMount () { this.updateLayerService(); }; LayerTree.prototype.componentDidUpdate = function componentDidUpdate (prevProps) { var ref = this.props; var layerService = ref.layerService; if (layerService !== prevProps.layerService) { this.updateLayerService(); } }; LayerTree.prototype.componentWillUnmount = function componentWillUnmount () { var ref = this.props; var layerService = ref.layerService; layerService.un('change:visible', this.updateLayers); }; LayerTree.prototype.onInputClick = function onInputClick (layer, toggle) { if ( toggle === void 0 ) toggle = false; if (toggle) { this.onToggle(layer); } else { layer.setVisible(!layer.getVisible()); } }; LayerTree.prototype.onToggle = function onToggle (layer) { var ref = this.state; var expandedLayerNames = ref.expandedLayerNames; var pos = expandedLayerNames.indexOf(layer); if (pos > -1) { expandedLayerNames.splice(pos, 1); } else { expandedLayerNames.push(layer); } this.setState({ expandedLayerNames: expandedLayerNames }); }; LayerTree.prototype.updateLayerService = function updateLayerService () { var ref = this.props; var layerService = ref.layerService; if (layerService) { layerService.un('change:visible', this.updateLayers); this.updateLayers(); layerService.on('change:visible', this.updateLayers); } }; LayerTree.prototype.updateLayers = function updateLayers () { var ref = this.props; var layerService = ref.layerService; this.setState({ layers: layerService.getLayers(), }); }; LayerTree.prototype.renderInput = function renderInput (layer) { var this$1 = this; var ref = this.props; var classNameInput = ref.classNameInput; var buttonTitles = ref.buttonTitles; var tabIndex = 0; if (!layer.getChildren().length) { // We forbid focus on keypress event for first level layers and layers without children. tabIndex = -1; } var inputType = layer.getRadioGroup() ? 'radio' : 'checkbox'; return ( React.createElement( Checkbox, { tabIndex: tabIndex, inputType: inputType, checked: layer.getVisible(), title: layer.getVisible() ? buttonTitles.layerHide : buttonTitles.layerShow, className: (classNameInput + " " + classNameInput + "-" + inputType), onClick: function () { return this$1.onInputClick(layer); } }) ); }; LayerTree.prototype.renderArrow = function renderArrow (layer) { var ref = this.props; var classNameArrow = ref.classNameArrow; var ref$1 = this.state; var expandedLayerNames = ref$1.expandedLayerNames; if (!layer.getChildren().length) { return null; } return ( React.createElement( 'div', { className: (classNameArrow + " " + classNameArrow + (!expandedLayerNames.includes(layer) ? '-collapsed' : '-expanded')) }) ); }; // Render a button which expands/collapse the layer if there is children // or simulate a click on the input otherwise. LayerTree.prototype.renderToggleButton = function renderToggleButton (layer) { var this$1 = this; var ref = this.props; var t = ref.t; var classNameToggle = ref.classNameToggle; var buttonTitles = ref.buttonTitles; var ref$1 = this.state; var expandedLayerNames = ref$1.expandedLayerNames; var tabIndex = 0; return ( React.createElement( Button, { tabIndex: tabIndex, title: ((layer.getName()) + " " + (!expandedLayerNames.includes(layer) ? buttonTitles.subLayerShow : buttonTitles.subLayerHide)), className: classNameToggle, onClick: function () { this$1.onInputClick(layer, layer.getChildren().length); } }, React.createElement( 'div', null, t(layer.getName()) ), this.renderArrow(layer) ) ); }; LayerTree.prototype.renderItemContent = function renderItemContent (layer) { return ( React.createElement( React.Fragment, null, this.renderInput(layer), this.renderToggleButton(layer) ) ); }; LayerTree.prototype.renderItem = function renderItem (layer, level) { var this$1 = this; var ref = this.props; var renderItem = ref.renderItem; var renderItemContent = ref.renderItemContent; var classNameItem = ref.classNameItem; var padding = ref.padding; var getParentClassName = ref.getParentClassName; var ref$1 = this.state; var expandedLayerNames = ref$1.expandedLayerNames; var children = expandedLayerNames.includes(layer) ? [].concat( layer.getChildren() ) : []; if (renderItem) { return renderItem(layer, this.onInputClick, this.onToggle); } return ( React.createElement( 'div', { className: getParentClassName(), key: layer.getKey() }, React.createElement( 'div', { className: (classNameItem + " " + (layer.getVisible() ? 'tm-visible' : '')), style: { paddingLeft: ((padding * level) + "px"), } }, renderItemContent ? renderItemContent(layer, this) : this.renderItemContent(layer) ), [].concat( children ) .reverse() .map(function (child) { return this$1.renderItem(child, level + 1); }) ) ); }; LayerTree.prototype.renderTree = function renderTree () { var this$1 = this; var ref = this.props; var isItemHidden = ref.isItemHidden; var ref$1 = this.state; var layers = ref$1.layers; if (!layers) { return null; } return ( React.createElement( React.Fragment, null, layers .filter(function (l) { return !isItemHidden(l); }) .reverse() .map(function (l) { return this$1.renderItem(l, 0); }) ) ); }; LayerTree.prototype.render = function render () { var ref = this.props; var className = ref.className; return React.createElement( 'div', { className: className }, this.renderTree()); }; return LayerTree; }(Component)); LayerTree.propTypes = propTypes; LayerTree.defaultProps = defaultProps; export default LayerTree; //# sourceMappingURL=LayerTree.js.map