react-spatial
Version:
Components to build React map apps.
356 lines (304 loc) • 10.1 kB
JavaScript
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