react-spatial 1.2.3-beta.3 → 1.2.3-beta.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/components/LayerTree/LayerTree.js +2 -2
- package/components/LayerTree/LayerTree.js.map +2 -2
- package/components/RouteSchedule/RouteSchedule.scss +7 -0
- package/package.json +4 -4
- package/themes/default/components.scss +0 -4
- package/themes/default/examples.scss +0 -1
- package/LayerService.js +0 -137
- package/LayerService.js.map +0 -7
- package/components/FilterButton/FilterButton.js +0 -66
- package/components/FilterButton/FilterButton.js.map +0 -7
- package/components/FilterButton/FilterButton.scss +0 -36
- package/components/FilterButton/index.js +0 -1
- package/components/FilterButton/index.js.map +0 -7
- package/components/FollowButton/FollowButton.js +0 -73
- package/components/FollowButton/FollowButton.js.map +0 -7
- package/components/FollowButton/FollowButton.scss +0 -36
- package/components/FollowButton/index.js +0 -1
- package/components/FollowButton/index.js.map +0 -7
- package/components/Search/Search.js +0 -166
- package/components/Search/Search.js.map +0 -7
- package/components/Search/Search.md.scss +0 -4
- package/components/Search/Search.scss +0 -78
- package/components/Search/SearchService.js +0 -48
- package/components/Search/SearchService.js.map +0 -7
- package/components/Search/engines/Engine.js +0 -19
- package/components/Search/engines/Engine.js.map +0 -7
- package/components/Search/engines/StopFinder.js +0 -30
- package/components/Search/engines/StopFinder.js.map +0 -7
- package/components/Search/index.js +0 -3
- package/components/Search/index.js.map +0 -7
- package/components/TrackerControl/TrackerControl.js +0 -116
- package/components/TrackerControl/TrackerControl.js.map +0 -7
- package/components/TrackerControl/TrackerControl.scss +0 -30
- package/components/TrackerControl/index.js +0 -1
- package/components/TrackerControl/index.js.map +0 -7
- package/images/FilterButton/filter.svg +0 -1
- package/images/FollowButton/follow.svg +0 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
[](https://github.com/geops/react-spatial/actions?query=workflow%3Amain)
|
|
5
5
|
[](https://renovatebot.com)
|
|
6
6
|
[](https://github.com/prettier/prettier)
|
|
7
|
-
|
|
7
|
+

|
|
8
8
|
|
|
9
9
|
This library provides React components to build web applications and to visualize real-time geographical information based on [OpenLayers](https://openlayers.org/) and [Mapbox GL](https://docs.mapbox.com/mapbox-gl-js/api/).
|
|
10
10
|
|
|
@@ -3,7 +3,7 @@ import PropTypes from "prop-types";
|
|
|
3
3
|
import { Layer, getLayersAsFlatArray } from "mobility-toolbox-js/ol";
|
|
4
4
|
import { unByKey } from "ol/Observable";
|
|
5
5
|
const propTypes = {
|
|
6
|
-
layers: PropTypes.arrayOf(Layer),
|
|
6
|
+
layers: PropTypes.arrayOf(PropTypes.instanceOf(Layer)),
|
|
7
7
|
className: PropTypes.string,
|
|
8
8
|
padding: PropTypes.number,
|
|
9
9
|
isItemHidden: PropTypes.func,
|
|
@@ -128,7 +128,7 @@ class LayerTree extends Component {
|
|
|
128
128
|
}
|
|
129
129
|
getLayersAsFlatArray(rootLayer).forEach((layer) => {
|
|
130
130
|
this.olKeys.push(
|
|
131
|
-
layer.on("propertychange", (
|
|
131
|
+
layer.on("propertychange", () => {
|
|
132
132
|
const { revision } = this.state;
|
|
133
133
|
this.setState({ revision: revision + 1 });
|
|
134
134
|
})
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/components/LayerTree/LayerTree.js"],
|
|
4
|
-
"sourcesContent": ["import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport { Layer, getLayersAsFlatArray } from 'mobility-toolbox-js/ol';\nimport { unByKey } from 'ol/Observable';\n\nconst propTypes = {\n /**\n * Layers provider.\n */\n layers: PropTypes.arrayOf(Layer),\n\n /**\n * CSS class to apply on the container.\n */\n className: PropTypes.string,\n\n /**\n * Padding left to apply on each level.\n */\n padding: PropTypes.number,\n\n /**\n * Determine if the item is hidden in the tree or not.\n *\n * @param {object} item The item to hide or not.\n *\n * @return {bool} true if the item is not displayed in the tree\n */\n isItemHidden: PropTypes.func,\n\n /**\n * Determine the className used by the div containing the parent and its children.\n */\n getParentClassName: PropTypes.func,\n\n /**\n * Custom function to render an item in the tree.\n *\n * @param {object} item The item to render.\n *\n * @return {node} A jsx node.\n */\n renderItem: PropTypes.func,\n\n /**\n * Custom function to render only the content of an item in the tree.\n *\n * @param {object} item The item to render.\n *\n * @return {node} A jsx node.\n */\n renderItemContent: PropTypes.func,\n\n /**\n * Custom function to render custom content before the list of children of an item.\n *\n * @param {object} item The item to render.\n *\n * @return {node} A jsx node.\n */\n renderBeforeItem: PropTypes.func,\n\n /**\n * Custom function to render custom content after the list of children of an item.\n *\n * @param {object} item The item to render.\n *\n * @return {node} A jsx node.\n */\n renderAfterItem: PropTypes.func,\n\n /**\n * Custom function to render the label.\n *\n * @param {string} item The label to render.\n * @param {LayerTree} comp The LayerTree component.\n *\n * @return {node} A jsx node.\n */\n renderLabel: PropTypes.func,\n\n /**\n * Object holding title for the layer tree's buttons.\n */\n titles: PropTypes.shape({\n /**\n * aria-label on checkbox to show layer.\n */\n layerShow: PropTypes.string,\n /**\n * aria-label on checkbox to hide layer.\n */\n layerHide: PropTypes.string,\n /**\n * title on button to show sublayers.\n */\n subLayerShow: PropTypes.string,\n /**\n * title on button to show sublayers.\n */\n subLayerHide: PropTypes.string,\n }),\n\n /**\n * Boolean determining whether children collapse/expand when their parent is toggled\n * @param {...(boolean|function)} expandChildren Boolean or function returning a boolean.\n * @return {boolean} True or false\n */\n expandChildren: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),\n\n /**\n * Translation function.\n * @param {function} Translation function returning the translated string.\n */\n t: PropTypes.func,\n};\n\nconst defaultProps = {\n layers: [],\n className: 'rs-layer-tree',\n padding: 30,\n isItemHidden: () => {\n return false;\n },\n getParentClassName: () => {\n return undefined;\n },\n renderItem: null,\n renderItemContent: null,\n renderBeforeItem: null,\n renderAfterItem: null,\n renderLabel: (layer, layerComp) => {\n const { t } = layerComp.props;\n return t(layer.name);\n },\n titles: {\n layerShow: 'Show layer',\n layerHide: 'Hide layer',\n subLayerShow: 'Show sublayer',\n subLayerHide: 'Hide sublayer',\n },\n t: (s) => {\n return s;\n },\n expandChildren: false,\n};\n\n/**\n * The LayerTree component renders an interface for toggling\n * [mobility-toolbox-js layers](https://mobility-toolbox-js.geops.io/api/identifiers%20html#ol-layers)\n * and their corresponding child layers.\n */\n\nclass LayerTree extends Component {\n constructor(props) {\n super(props);\n\n const { layers, isItemHidden } = this.props;\n const initialExpandedLayers = layers\n ? this.getExpandedLayers(\n layers.filter((l) => {\n return (\n !isItemHidden(l) &&\n (l.children || [])\n .filter((child) => {\n return child.visible;\n })\n .filter((c) => {\n return !isItemHidden(c);\n }).length\n );\n }),\n )\n : [];\n\n this.state = {\n rootLayer: new Layer(),\n expandedLayers: initialExpandedLayers,\n revision: 0,\n };\n // this.updateLayers = this.updateLayers.bind(this);\n this.olKeys = [];\n }\n\n componentDidMount() {\n this.updateLayers();\n }\n\n componentDidUpdate(prevProps) {\n const { layers } = this.props;\n\n if (layers !== prevProps.layers) {\n this.updateLayers();\n }\n }\n\n componentWillUnmount() {\n unByKey(this.olKeys);\n this.olKeys = [];\n }\n\n onInputClick(layer, toggle = false) {\n if (toggle) {\n this.onToggle(layer);\n } else if (layer.setVisible) {\n layer.setVisible(!layer.visible);\n } else {\n // eslint-disable-next-line no-param-reassign\n layer.visible = !layer.visible;\n }\n }\n\n onToggle(layer) {\n const { expandedLayers } = this.state;\n const pos = expandedLayers.indexOf(layer);\n if (pos > -1) {\n expandedLayers.splice(pos, 1);\n } else {\n expandedLayers.push(...this.getExpandedLayers([layer]));\n }\n this.setState({ expandedLayers });\n }\n\n /**\n * Get the always expanded ancestors (isAlwaysExpanded=true) of the given layers\n * together with the (given) initially expanded layers\n *\n * @param {Layer} layers Initially expanded layers\n * @return {Array.<Layer>} Initially expanded layers and all its always expanded ancestors\n */\n getExpandedLayers(layers) {\n const { isItemHidden } = this.props;\n const children = layers.flatMap((l) => {\n return l.children.filter((c) => {\n return !isItemHidden(c) && c.get('isAlwaysExpanded');\n });\n });\n\n if (!children.length) {\n return layers;\n }\n return [...layers, this.getExpandedLayers(children)].flat();\n }\n\n updateLayers() {\n const { layers, expandChildren } = this.props;\n\n // Update the root layer\n let rootLayer = new Layer();\n if (Array.isArray(layers)) {\n if (layers.length === 1) {\n [rootLayer] = layers;\n }\n rootLayer = new Layer({ children: layers });\n } else {\n rootLayer = layers;\n }\n\n getLayersAsFlatArray(rootLayer).forEach((layer) => {\n this.olKeys.push(\n layer.on('propertychange', (evt) => {\n const { revision } = this.state;\n this.setState({ revision: revision + 1 });\n }),\n );\n });\n\n const state = { rootLayer };\n if (\n typeof expandChildren === 'function'\n ? expandChildren(layers)\n : expandChildren\n ) {\n state.expandedLayers = rootLayer.children.flatMap((l) => {\n return this.expandLayer(l);\n });\n }\n\n this.setState(state);\n }\n\n expandLayer(layer, expLayers = []) {\n const { isItemHidden } = this.props;\n if (layer.visible && !isItemHidden(layer)) {\n const children = layer.children\n .filter((c) => {\n return !isItemHidden(c) && !c.get('isAlwaysExpanded');\n })\n .flatMap((c) => {\n return this.expandLayer(c, expLayers);\n });\n return [...expLayers, ...children, layer];\n }\n return expLayers;\n }\n\n renderInput(layer) {\n const { titles, isItemHidden } = this.props;\n let tabIndex = 0;\n\n if (\n !(layer.children || []).filter((c) => {\n return !isItemHidden(c);\n }).length\n ) {\n // We forbid focus on keypress event for first level layers and layers without children.\n tabIndex = -1;\n }\n\n const inputType = layer.get('group') ? 'radio' : 'checkbox';\n return (\n // eslint-disable-next-line jsx-a11y/label-has-associated-control,jsx-a11y/no-noninteractive-element-interactions\n <label\n className={`rs-layer-tree-input rs-layer-tree-input-${inputType} rs-${inputType}`}\n tabIndex={tabIndex}\n title={layer.visible ? titles.layerHide : titles.layerShow}\n aria-label={layer.visible ? titles.layerHide : titles.layerShow}\n onKeyPress={(e) => {\n if (e.which === 13) {\n this.onInputClick(layer);\n }\n }}\n >\n <input\n type={inputType}\n tabIndex={-1}\n checked={layer.visible}\n readOnly\n onClick={() => {\n return this.onInputClick(layer);\n }}\n />\n <span />\n </label>\n );\n }\n\n renderArrow(layer) {\n const { isItemHidden } = this.props;\n const { expandedLayers } = this.state;\n\n if (\n !(layer.children || []).filter((c) => {\n return !isItemHidden(c);\n }).length ||\n layer.get('isAlwaysExpanded')\n ) {\n return null;\n }\n\n return (\n <div\n className={`rs-layer-tree-arrow rs-layer-tree-arrow-${\n !expandedLayers.includes(layer) ? 'collapsed' : 'expanded'\n }`}\n />\n );\n }\n\n // Render a button which expands/collapse the layer if there is children\n // or simulate a click on the input otherwise.\n renderToggleButton(layer) {\n const { t, titles, isItemHidden, renderLabel } = this.props;\n const { expandedLayers } = this.state;\n\n const onInputClick = () => {\n this.onInputClick(\n layer,\n (layer.children || []).filter((c) => {\n return !isItemHidden(c);\n }).length && !layer.get('isAlwaysExpanded'),\n );\n };\n const title = `${t(layer.name)} ${\n expandedLayers.includes(layer) ? titles.subLayerHide : titles.subLayerShow\n }`;\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n className=\"rs-layer-tree-toggle\"\n title={title}\n aria-expanded={expandedLayers.includes(layer)}\n aria-label={title}\n onClick={onInputClick}\n onKeyPress={onInputClick}\n >\n <div>{renderLabel(layer, this)}</div>\n {this.renderArrow(layer)}\n </div>\n );\n }\n\n renderItemContent(layer) {\n return (\n <>\n {this.renderInput(layer)}\n {this.renderToggleButton(layer)}\n </>\n );\n }\n\n renderItem(layer, level) {\n const { isItemHidden } = this.props;\n const { expandedLayers } = this.state;\n const {\n renderItem,\n renderItemContent,\n renderBeforeItem,\n renderAfterItem,\n padding,\n getParentClassName,\n } = this.props;\n\n const children = expandedLayers.includes(layer)\n ? [\n ...(layer.children || []).filter((c) => {\n return !isItemHidden(c);\n }),\n ]\n : [];\n\n if (renderItem) {\n return renderItem(layer, this.onInputClick, this.onToggle);\n }\n\n return (\n <div className={getParentClassName()} key={layer.key}>\n <div\n className={`rs-layer-tree-item ${layer.visible ? 'rs-visible' : ''}`}\n style={{\n paddingLeft: `${padding * level}px`,\n }}\n >\n {renderItemContent\n ? renderItemContent(layer, this)\n : this.renderItemContent(layer)}\n </div>\n {renderBeforeItem && renderBeforeItem(layer, level, this)}\n {[...children].reverse().map((child) => {\n return this.renderItem(child, level + 1);\n })}\n {renderAfterItem && renderAfterItem(layer, level, this)}\n </div>\n );\n }\n\n renderTree() {\n const { isItemHidden } = this.props;\n const { rootLayer } = this.state;\n\n if (!rootLayer?.children?.length) {\n return null;\n }\n\n return (\n <>\n {rootLayer.children\n .filter((l) => {\n return !isItemHidden(l);\n })\n .reverse()\n .map((l) => {\n return this.renderItem(l, 0);\n })}\n </>\n );\n }\n\n render() {\n const { className } = this.props;\n return <div className={className}>{this.renderTree()}</div>;\n }\n}\n\nLayerTree.propTypes = propTypes;\nLayerTree.defaultProps = defaultProps;\n\nexport default LayerTree;\n"],
|
|
5
|
-
"mappings": "AAAA,OAAO,SAAS,iBAAiB;AACjC,OAAO,eAAe;AACtB,SAAS,OAAO,4BAA4B;AAC5C,SAAS,eAAe;AAExB,MAAM,YAAY;AAAA,EAIhB,QAAQ,UAAU,QAAQ,KAAK;AAAA,
|
|
4
|
+
"sourcesContent": ["import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport { Layer, getLayersAsFlatArray } from 'mobility-toolbox-js/ol';\nimport { unByKey } from 'ol/Observable';\n\nconst propTypes = {\n /**\n * Layers provider.\n */\n layers: PropTypes.arrayOf(PropTypes.instanceOf(Layer)),\n\n /**\n * CSS class to apply on the container.\n */\n className: PropTypes.string,\n\n /**\n * Padding left to apply on each level.\n */\n padding: PropTypes.number,\n\n /**\n * Determine if the item is hidden in the tree or not.\n *\n * @param {object} item The item to hide or not.\n *\n * @return {bool} true if the item is not displayed in the tree\n */\n isItemHidden: PropTypes.func,\n\n /**\n * Determine the className used by the div containing the parent and its children.\n */\n getParentClassName: PropTypes.func,\n\n /**\n * Custom function to render an item in the tree.\n *\n * @param {object} item The item to render.\n *\n * @return {node} A jsx node.\n */\n renderItem: PropTypes.func,\n\n /**\n * Custom function to render only the content of an item in the tree.\n *\n * @param {object} item The item to render.\n *\n * @return {node} A jsx node.\n */\n renderItemContent: PropTypes.func,\n\n /**\n * Custom function to render custom content before the list of children of an item.\n *\n * @param {object} item The item to render.\n *\n * @return {node} A jsx node.\n */\n renderBeforeItem: PropTypes.func,\n\n /**\n * Custom function to render custom content after the list of children of an item.\n *\n * @param {object} item The item to render.\n *\n * @return {node} A jsx node.\n */\n renderAfterItem: PropTypes.func,\n\n /**\n * Custom function to render the label.\n *\n * @param {string} item The label to render.\n * @param {LayerTree} comp The LayerTree component.\n *\n * @return {node} A jsx node.\n */\n renderLabel: PropTypes.func,\n\n /**\n * Object holding title for the layer tree's buttons.\n */\n titles: PropTypes.shape({\n /**\n * aria-label on checkbox to show layer.\n */\n layerShow: PropTypes.string,\n /**\n * aria-label on checkbox to hide layer.\n */\n layerHide: PropTypes.string,\n /**\n * title on button to show sublayers.\n */\n subLayerShow: PropTypes.string,\n /**\n * title on button to show sublayers.\n */\n subLayerHide: PropTypes.string,\n }),\n\n /**\n * Boolean determining whether children collapse/expand when their parent is toggled\n * @param {...(boolean|function)} expandChildren Boolean or function returning a boolean.\n * @return {boolean} True or false\n */\n expandChildren: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),\n\n /**\n * Translation function.\n * @param {function} Translation function returning the translated string.\n */\n t: PropTypes.func,\n};\n\nconst defaultProps = {\n layers: [],\n className: 'rs-layer-tree',\n padding: 30,\n isItemHidden: () => {\n return false;\n },\n getParentClassName: () => {\n return undefined;\n },\n renderItem: null,\n renderItemContent: null,\n renderBeforeItem: null,\n renderAfterItem: null,\n renderLabel: (layer, layerComp) => {\n const { t } = layerComp.props;\n return t(layer.name);\n },\n titles: {\n layerShow: 'Show layer',\n layerHide: 'Hide layer',\n subLayerShow: 'Show sublayer',\n subLayerHide: 'Hide sublayer',\n },\n t: (s) => {\n return s;\n },\n expandChildren: false,\n};\n\n/**\n * The LayerTree component renders an interface for toggling\n * [mobility-toolbox-js layers](https://mobility-toolbox-js.geops.io/api/identifiers%20html#ol-layers)\n * and their corresponding child layers.\n */\n\nclass LayerTree extends Component {\n constructor(props) {\n super(props);\n\n const { layers, isItemHidden } = this.props;\n const initialExpandedLayers = layers\n ? this.getExpandedLayers(\n layers.filter((l) => {\n return (\n !isItemHidden(l) &&\n (l.children || [])\n .filter((child) => {\n return child.visible;\n })\n .filter((c) => {\n return !isItemHidden(c);\n }).length\n );\n }),\n )\n : [];\n\n this.state = {\n rootLayer: new Layer(),\n expandedLayers: initialExpandedLayers,\n revision: 0,\n };\n // this.updateLayers = this.updateLayers.bind(this);\n this.olKeys = [];\n }\n\n componentDidMount() {\n this.updateLayers();\n }\n\n componentDidUpdate(prevProps) {\n const { layers } = this.props;\n\n if (layers !== prevProps.layers) {\n this.updateLayers();\n }\n }\n\n componentWillUnmount() {\n unByKey(this.olKeys);\n this.olKeys = [];\n }\n\n onInputClick(layer, toggle = false) {\n if (toggle) {\n this.onToggle(layer);\n } else if (layer.setVisible) {\n layer.setVisible(!layer.visible);\n } else {\n // eslint-disable-next-line no-param-reassign\n layer.visible = !layer.visible;\n }\n }\n\n onToggle(layer) {\n const { expandedLayers } = this.state;\n const pos = expandedLayers.indexOf(layer);\n if (pos > -1) {\n expandedLayers.splice(pos, 1);\n } else {\n expandedLayers.push(...this.getExpandedLayers([layer]));\n }\n this.setState({ expandedLayers });\n }\n\n /**\n * Get the always expanded ancestors (isAlwaysExpanded=true) of the given layers\n * together with the (given) initially expanded layers\n *\n * @param {Layer} layers Initially expanded layers\n * @return {Array.<Layer>} Initially expanded layers and all its always expanded ancestors\n */\n getExpandedLayers(layers) {\n const { isItemHidden } = this.props;\n const children = layers.flatMap((l) => {\n return l.children.filter((c) => {\n return !isItemHidden(c) && c.get('isAlwaysExpanded');\n });\n });\n\n if (!children.length) {\n return layers;\n }\n return [...layers, this.getExpandedLayers(children)].flat();\n }\n\n updateLayers() {\n const { layers, expandChildren } = this.props;\n\n // Update the root layer\n let rootLayer = new Layer();\n if (Array.isArray(layers)) {\n if (layers.length === 1) {\n [rootLayer] = layers;\n }\n rootLayer = new Layer({ children: layers });\n } else {\n rootLayer = layers;\n }\n\n getLayersAsFlatArray(rootLayer).forEach((layer) => {\n this.olKeys.push(\n layer.on('propertychange', () => {\n const { revision } = this.state;\n this.setState({ revision: revision + 1 });\n }),\n );\n });\n\n const state = { rootLayer };\n if (\n typeof expandChildren === 'function'\n ? expandChildren(layers)\n : expandChildren\n ) {\n state.expandedLayers = rootLayer.children.flatMap((l) => {\n return this.expandLayer(l);\n });\n }\n\n this.setState(state);\n }\n\n expandLayer(layer, expLayers = []) {\n const { isItemHidden } = this.props;\n if (layer.visible && !isItemHidden(layer)) {\n const children = layer.children\n .filter((c) => {\n return !isItemHidden(c) && !c.get('isAlwaysExpanded');\n })\n .flatMap((c) => {\n return this.expandLayer(c, expLayers);\n });\n return [...expLayers, ...children, layer];\n }\n return expLayers;\n }\n\n renderInput(layer) {\n const { titles, isItemHidden } = this.props;\n let tabIndex = 0;\n\n if (\n !(layer.children || []).filter((c) => {\n return !isItemHidden(c);\n }).length\n ) {\n // We forbid focus on keypress event for first level layers and layers without children.\n tabIndex = -1;\n }\n\n const inputType = layer.get('group') ? 'radio' : 'checkbox';\n return (\n // eslint-disable-next-line jsx-a11y/label-has-associated-control,jsx-a11y/no-noninteractive-element-interactions\n <label\n className={`rs-layer-tree-input rs-layer-tree-input-${inputType} rs-${inputType}`}\n tabIndex={tabIndex}\n title={layer.visible ? titles.layerHide : titles.layerShow}\n aria-label={layer.visible ? titles.layerHide : titles.layerShow}\n onKeyPress={(e) => {\n if (e.which === 13) {\n this.onInputClick(layer);\n }\n }}\n >\n <input\n type={inputType}\n tabIndex={-1}\n checked={layer.visible}\n readOnly\n onClick={() => {\n return this.onInputClick(layer);\n }}\n />\n <span />\n </label>\n );\n }\n\n renderArrow(layer) {\n const { isItemHidden } = this.props;\n const { expandedLayers } = this.state;\n\n if (\n !(layer.children || []).filter((c) => {\n return !isItemHidden(c);\n }).length ||\n layer.get('isAlwaysExpanded')\n ) {\n return null;\n }\n\n return (\n <div\n className={`rs-layer-tree-arrow rs-layer-tree-arrow-${\n !expandedLayers.includes(layer) ? 'collapsed' : 'expanded'\n }`}\n />\n );\n }\n\n // Render a button which expands/collapse the layer if there is children\n // or simulate a click on the input otherwise.\n renderToggleButton(layer) {\n const { t, titles, isItemHidden, renderLabel } = this.props;\n const { expandedLayers } = this.state;\n\n const onInputClick = () => {\n this.onInputClick(\n layer,\n (layer.children || []).filter((c) => {\n return !isItemHidden(c);\n }).length && !layer.get('isAlwaysExpanded'),\n );\n };\n const title = `${t(layer.name)} ${\n expandedLayers.includes(layer) ? titles.subLayerHide : titles.subLayerShow\n }`;\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n className=\"rs-layer-tree-toggle\"\n title={title}\n aria-expanded={expandedLayers.includes(layer)}\n aria-label={title}\n onClick={onInputClick}\n onKeyPress={onInputClick}\n >\n <div>{renderLabel(layer, this)}</div>\n {this.renderArrow(layer)}\n </div>\n );\n }\n\n renderItemContent(layer) {\n return (\n <>\n {this.renderInput(layer)}\n {this.renderToggleButton(layer)}\n </>\n );\n }\n\n renderItem(layer, level) {\n const { isItemHidden } = this.props;\n const { expandedLayers } = this.state;\n const {\n renderItem,\n renderItemContent,\n renderBeforeItem,\n renderAfterItem,\n padding,\n getParentClassName,\n } = this.props;\n\n const children = expandedLayers.includes(layer)\n ? [\n ...(layer.children || []).filter((c) => {\n return !isItemHidden(c);\n }),\n ]\n : [];\n\n if (renderItem) {\n return renderItem(layer, this.onInputClick, this.onToggle);\n }\n\n return (\n <div className={getParentClassName()} key={layer.key}>\n <div\n className={`rs-layer-tree-item ${layer.visible ? 'rs-visible' : ''}`}\n style={{\n paddingLeft: `${padding * level}px`,\n }}\n >\n {renderItemContent\n ? renderItemContent(layer, this)\n : this.renderItemContent(layer)}\n </div>\n {renderBeforeItem && renderBeforeItem(layer, level, this)}\n {[...children].reverse().map((child) => {\n return this.renderItem(child, level + 1);\n })}\n {renderAfterItem && renderAfterItem(layer, level, this)}\n </div>\n );\n }\n\n renderTree() {\n const { isItemHidden } = this.props;\n const { rootLayer } = this.state;\n\n if (!rootLayer?.children?.length) {\n return null;\n }\n\n return (\n <>\n {rootLayer.children\n .filter((l) => {\n return !isItemHidden(l);\n })\n .reverse()\n .map((l) => {\n return this.renderItem(l, 0);\n })}\n </>\n );\n }\n\n render() {\n const { className } = this.props;\n return <div className={className}>{this.renderTree()}</div>;\n }\n}\n\nLayerTree.propTypes = propTypes;\nLayerTree.defaultProps = defaultProps;\n\nexport default LayerTree;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-spatial",
|
|
3
3
|
"description": "Components to build React map apps.",
|
|
4
|
-
"version": "1.2.3-beta.
|
|
4
|
+
"version": "1.2.3-beta.7",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"dependencies": {
|
|
7
7
|
"@geops/geops-ui": "0.1.13",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"re-resizable": "6.9.1",
|
|
15
15
|
"react-autosuggest": "10.1.0",
|
|
16
16
|
"react-draggable": "4.4.4",
|
|
17
|
-
"react-icons": "4.
|
|
17
|
+
"react-icons": "4.4.0",
|
|
18
18
|
"resize-observer-polyfill": "1.5.1"
|
|
19
19
|
},
|
|
20
20
|
"peerDependencies": {
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"lint-staged": "11.2.0",
|
|
71
71
|
"mapbox-gl": "1.13.1",
|
|
72
72
|
"maplibre-gl": "2.4.0",
|
|
73
|
-
"mobility-toolbox-js": "2.0.0-beta.
|
|
73
|
+
"mobility-toolbox-js": "2.0.0-beta.51",
|
|
74
74
|
"ol": "6.14.1",
|
|
75
75
|
"prettier": "2.4.1",
|
|
76
76
|
"proj4": "2.7.5",
|
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
"xml-beautifier": "0.5.0"
|
|
97
97
|
},
|
|
98
98
|
"scripts": {
|
|
99
|
-
"esbuild": "esbuild src/*.js src/**/*.js src/**/**/*.js
|
|
99
|
+
"esbuild": "esbuild src/*.js src/**/*.js src/**/**/*.js --target=chrome100 --outdir=build/ --loader:.js=jsx --sourcemap=external",
|
|
100
100
|
"buble": "buble --no modules,asyncAwait -i src -o build --objectAssign Object.assign --sourcemap",
|
|
101
101
|
"build": "yarn esbuild && find build -type f -name '*.test.*' -delete && rm -rf build/styleguidist && cp package.json README.md LICENSE build && cp -rf src/images build && cp -rf src/themes build",
|
|
102
102
|
"coverage": "yarn test --coverage --coverageDirectory=coverage",
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* This file load the css of components.
|
|
3
3
|
*/
|
|
4
|
-
@import '../../components/FilterButton/FilterButton.scss';
|
|
5
|
-
@import '../../components/FollowButton/FollowButton.scss';
|
|
6
4
|
@import '../../components/BaseLayerSwitcher/BaseLayerSwitcher.scss';
|
|
7
5
|
@import '../../components/Geolocation/Geolocation.scss';
|
|
8
6
|
@import '../../components/LayerTree/LayerTree.scss';
|
|
@@ -11,6 +9,4 @@
|
|
|
11
9
|
@import '../../components/ScaleLine/ScaleLine.scss';
|
|
12
10
|
@import '../../components/Zoom/Zoom.scss';
|
|
13
11
|
@import '../../components/RouteSchedule/RouteSchedule.scss';
|
|
14
|
-
@import '../../components/TrackerControl/TrackerControl.scss';
|
|
15
|
-
@import '../../components/Search/Search.scss';
|
|
16
12
|
@import '../../components/Overlay/Overlay.scss';
|
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
@import '../../components/Zoom/Zoom.md.scss';
|
|
16
16
|
@import '../../components/RouteSchedule/RouteSchedule.md.scss';
|
|
17
17
|
@import '../../components/Copyright/Copyright.md.scss';
|
|
18
|
-
@import '../../components/Search/Search.md.scss';
|
|
19
18
|
@import '../../components/Overlay/Overlay.md.scss';
|
|
20
19
|
|
|
21
20
|
$link-color: #000;
|
package/LayerService.js
DELETED
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import { unByKey } from "ol/Observable";
|
|
2
|
-
export default class LayerService {
|
|
3
|
-
constructor(layers) {
|
|
4
|
-
this.layers = layers;
|
|
5
|
-
this.callbacks = {};
|
|
6
|
-
this.keys = [];
|
|
7
|
-
this.listenChangeEvt();
|
|
8
|
-
}
|
|
9
|
-
addLayer(layer) {
|
|
10
|
-
this.layers.push(layer);
|
|
11
|
-
}
|
|
12
|
-
getLayers() {
|
|
13
|
-
return this.layers;
|
|
14
|
-
}
|
|
15
|
-
setLayers(layers) {
|
|
16
|
-
this.layers = layers;
|
|
17
|
-
this.listenChangeEvt();
|
|
18
|
-
(this.callbacks["change:layers"] || []).forEach((cb) => {
|
|
19
|
-
return cb(layers);
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
getLayersAsFlatArray(optLayers) {
|
|
23
|
-
let layers = [];
|
|
24
|
-
(optLayers || this.getLayers() || []).forEach((l) => {
|
|
25
|
-
layers.push(l);
|
|
26
|
-
const { children } = l;
|
|
27
|
-
layers = layers.concat(this.getLayersAsFlatArray(children || []));
|
|
28
|
-
});
|
|
29
|
-
return layers;
|
|
30
|
-
}
|
|
31
|
-
getLayer(name) {
|
|
32
|
-
return this.getLayersAsFlatArray().find((l) => {
|
|
33
|
-
return l.name === name;
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
getParent(child) {
|
|
37
|
-
return this.getLayersAsFlatArray().find((l) => {
|
|
38
|
-
return !!l.children.includes(child);
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
getParents(child) {
|
|
42
|
-
let layer = child;
|
|
43
|
-
const parents = [];
|
|
44
|
-
let parentLayer;
|
|
45
|
-
do {
|
|
46
|
-
parentLayer = this.getParent(layer);
|
|
47
|
-
if (parentLayer) {
|
|
48
|
-
parents.push(parentLayer);
|
|
49
|
-
layer = parentLayer;
|
|
50
|
-
}
|
|
51
|
-
} while (parentLayer);
|
|
52
|
-
return parents;
|
|
53
|
-
}
|
|
54
|
-
getRadioGroupLayers(radioGroupName) {
|
|
55
|
-
if (radioGroupName) {
|
|
56
|
-
return this.getLayersAsFlatArray().filter((l) => {
|
|
57
|
-
return l.get("radioGroup") === radioGroupName;
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
return null;
|
|
61
|
-
}
|
|
62
|
-
getBaseLayers() {
|
|
63
|
-
return this.getLayersAsFlatArray().filter((l) => {
|
|
64
|
-
return l.isBaseLayer;
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
getQueryableLayers() {
|
|
68
|
-
return this.getLayersAsFlatArray().filter((layer) => {
|
|
69
|
-
return layer.visible && layer.isQueryable;
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
getFeatureInfoAtCoordinate(coordinate, layers) {
|
|
73
|
-
const promises = (layers || this.getQueryableLayers()).map((layer) => {
|
|
74
|
-
return layer.getFeatureInfoAtCoordinate(coordinate).then((featureInfo) => {
|
|
75
|
-
return featureInfo;
|
|
76
|
-
});
|
|
77
|
-
});
|
|
78
|
-
return Promise.all(promises);
|
|
79
|
-
}
|
|
80
|
-
on(evt, callback) {
|
|
81
|
-
this.un(evt, callback);
|
|
82
|
-
this.callbacks[evt] = this.callbacks[evt] || [];
|
|
83
|
-
this.callbacks[evt].push(callback);
|
|
84
|
-
}
|
|
85
|
-
un(evt, callback) {
|
|
86
|
-
for (let i = 0; i < (this.callbacks[evt] || []).length; i += 1) {
|
|
87
|
-
if (callback === this.callbacks[evt][i]) {
|
|
88
|
-
this.callbacks[evt].splice(i, 1);
|
|
89
|
-
break;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
listenChangeEvt() {
|
|
94
|
-
if (this.keys) {
|
|
95
|
-
unByKey(this.keys);
|
|
96
|
-
this.keys = [];
|
|
97
|
-
}
|
|
98
|
-
this.getLayersAsFlatArray().forEach((layer) => {
|
|
99
|
-
this.keys.push(
|
|
100
|
-
layer.on("change:copyright", (evt) => {
|
|
101
|
-
(this.callbacks["change:copyright"] || []).forEach((cb) => {
|
|
102
|
-
return cb(evt.target);
|
|
103
|
-
});
|
|
104
|
-
}),
|
|
105
|
-
layer.on("change:visible", (evt) => {
|
|
106
|
-
const { visible } = evt.target;
|
|
107
|
-
if (!evt.stopPropagationSiblings && layer.get("radioGroup") && visible) {
|
|
108
|
-
const siblings = this.getRadioGroupLayers(
|
|
109
|
-
layer.get("radioGroup")
|
|
110
|
-
).filter((l) => {
|
|
111
|
-
return l !== layer;
|
|
112
|
-
});
|
|
113
|
-
siblings.forEach((s) => {
|
|
114
|
-
if (visible && s.get("radioGroup") && evt.target.get("radioGroup") === s.get("radioGroup")) {
|
|
115
|
-
s.visible = false;
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
if (!evt.stopPropagationDown && layer.children) {
|
|
120
|
-
layer.children.forEach((child) => {
|
|
121
|
-
child.visible = visible;
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
const parentLayer = this.getParent(layer);
|
|
125
|
-
if (!evt.stopPropagationUp && parentLayer && (visible || !visible && !parentLayer.children.find((c) => {
|
|
126
|
-
return c.visible;
|
|
127
|
-
}))) {
|
|
128
|
-
parentLayer.visible = visible;
|
|
129
|
-
}
|
|
130
|
-
(this.callbacks["change:visible"] || []).forEach((cb) => {
|
|
131
|
-
return cb(evt.target);
|
|
132
|
-
});
|
|
133
|
-
})
|
|
134
|
-
);
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
}
|
package/LayerService.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/LayerService.js"],
|
|
4
|
-
"sourcesContent": ["import { unByKey } from 'ol/Observable';\n\n/**\n * A layer service class to handle layer adding, removing and visiblity.\n */\nexport default class LayerService {\n constructor(layers) {\n this.layers = layers;\n this.callbacks = {};\n this.keys = [];\n this.listenChangeEvt();\n }\n\n addLayer(layer) {\n this.layers.push(layer);\n }\n\n getLayers() {\n return this.layers;\n }\n\n setLayers(layers) {\n this.layers = layers;\n this.listenChangeEvt();\n // When we change the layers we trigger an change:layers event\n (this.callbacks['change:layers'] || []).forEach((cb) => {\n return cb(layers);\n });\n }\n\n getLayersAsFlatArray(optLayers) {\n let layers = [];\n (optLayers || this.getLayers() || []).forEach((l) => {\n layers.push(l);\n const { children } = l;\n layers = layers.concat(this.getLayersAsFlatArray(children || []));\n });\n return layers;\n }\n\n getLayer(name) {\n return this.getLayersAsFlatArray().find((l) => {\n return l.name === name;\n });\n }\n\n getParent(child) {\n return this.getLayersAsFlatArray().find((l) => {\n return !!l.children.includes(child);\n });\n }\n\n getParents(child) {\n let layer = child;\n const parents = [];\n\n let parentLayer;\n do {\n parentLayer = this.getParent(layer);\n if (parentLayer) {\n parents.push(parentLayer);\n layer = parentLayer;\n }\n } while (parentLayer);\n\n return parents;\n }\n\n getRadioGroupLayers(radioGroupName) {\n if (radioGroupName) {\n return this.getLayersAsFlatArray().filter((l) => {\n return l.get('radioGroup') === radioGroupName;\n });\n }\n\n return null;\n }\n\n getBaseLayers() {\n return this.getLayersAsFlatArray().filter((l) => {\n return l.isBaseLayer;\n });\n }\n\n getQueryableLayers() {\n return this.getLayersAsFlatArray().filter((layer) => {\n return layer.visible && layer.isQueryable;\n });\n }\n\n getFeatureInfoAtCoordinate(coordinate, layers) {\n const promises = (layers || this.getQueryableLayers()).map((layer) => {\n return layer\n .getFeatureInfoAtCoordinate(coordinate)\n .then((featureInfo) => {\n return featureInfo;\n });\n });\n return Promise.all(promises);\n }\n\n on(evt, callback) {\n this.un(evt, callback);\n this.callbacks[evt] = this.callbacks[evt] || [];\n this.callbacks[evt].push(callback);\n }\n\n un(evt, callback) {\n for (let i = 0; i < (this.callbacks[evt] || []).length; i += 1) {\n if (callback === this.callbacks[evt][i]) {\n this.callbacks[evt].splice(i, 1);\n break;\n }\n }\n }\n\n listenChangeEvt() {\n if (this.keys) {\n unByKey(this.keys);\n this.keys = [];\n }\n this.getLayersAsFlatArray().forEach((layer) => {\n this.keys.push(\n layer.on('change:copyright', (evt) => {\n (this.callbacks['change:copyright'] || []).forEach((cb) => {\n return cb(evt.target);\n });\n }),\n layer.on('change:visible', (evt) => {\n const { visible } = evt.target;\n\n // Apply to siblings only if it's a radio group.\n if (\n !evt.stopPropagationSiblings &&\n layer.get('radioGroup') &&\n visible\n ) {\n const siblings = this.getRadioGroupLayers(\n layer.get('radioGroup'),\n ).filter((l) => {\n return l !== layer;\n });\n\n siblings.forEach((s) => {\n if (\n visible &&\n s.get('radioGroup') &&\n evt.target.get('radioGroup') === s.get('radioGroup')\n ) {\n // eslint-disable-next-line no-param-reassign\n s.visible = false;\n }\n });\n }\n\n // Apply to children\n if (!evt.stopPropagationDown && layer.children) {\n layer.children.forEach((child) => {\n // eslint-disable-next-line no-param-reassign\n child.visible = visible;\n });\n }\n\n // Apply to parent only if:\n // - a child is visible\n // - all children are hidden\n const parentLayer = this.getParent(layer);\n\n if (\n !evt.stopPropagationUp &&\n parentLayer &&\n (visible ||\n (!visible &&\n !parentLayer.children.find((c) => {\n return c.visible;\n })))\n ) {\n parentLayer.visible = visible;\n }\n\n (this.callbacks['change:visible'] || []).forEach((cb) => {\n return cb(evt.target);\n });\n }),\n );\n });\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import React, { PureComponent } from "react";
|
|
2
|
-
import qs from "query-string";
|
|
3
|
-
import PropTypes from "prop-types";
|
|
4
|
-
import { RealtimeLayer as TrackerLayer } from "mobility-toolbox-js/ol";
|
|
5
|
-
const propTypes = {
|
|
6
|
-
className: PropTypes.string,
|
|
7
|
-
title: PropTypes.string,
|
|
8
|
-
routeIdentifier: PropTypes.string.isRequired,
|
|
9
|
-
active: PropTypes.bool.isRequired,
|
|
10
|
-
onClick: PropTypes.func.isRequired,
|
|
11
|
-
trackerLayer: PropTypes.instanceOf(TrackerLayer).isRequired,
|
|
12
|
-
children: PropTypes.element.isRequired
|
|
13
|
-
};
|
|
14
|
-
const defaultProps = {
|
|
15
|
-
className: "rt-route-filter",
|
|
16
|
-
title: "Filter"
|
|
17
|
-
};
|
|
18
|
-
class FilterButton extends PureComponent {
|
|
19
|
-
updatePermalink(isRemoving) {
|
|
20
|
-
const { routeIdentifier } = this.props;
|
|
21
|
-
const parameters = qs.parse(window.location.search.toLowerCase());
|
|
22
|
-
if (isRemoving) {
|
|
23
|
-
delete parameters.tripnumber;
|
|
24
|
-
} else {
|
|
25
|
-
parameters.tripnumber = parseInt(routeIdentifier.split(".")[0], 10);
|
|
26
|
-
}
|
|
27
|
-
const qStr = qs.stringify(parameters, { encode: false });
|
|
28
|
-
const search = `?${qStr}`;
|
|
29
|
-
const { hash } = window.location;
|
|
30
|
-
window.history.replaceState(void 0, void 0, `${search}${hash || ""}`);
|
|
31
|
-
}
|
|
32
|
-
toggleFilter(routeIdentifier) {
|
|
33
|
-
const { trackerLayer, active, onClick } = this.props;
|
|
34
|
-
const activated = !active;
|
|
35
|
-
if (trackerLayer) {
|
|
36
|
-
if (activated) {
|
|
37
|
-
this.updatePermalink(false);
|
|
38
|
-
[trackerLayer.tripNumber] = routeIdentifier.split(".");
|
|
39
|
-
} else {
|
|
40
|
-
this.updatePermalink(true);
|
|
41
|
-
trackerLayer.tripNumber = null;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
onClick(activated);
|
|
45
|
-
}
|
|
46
|
-
render() {
|
|
47
|
-
const { className, title, routeIdentifier, active, children } = this.props;
|
|
48
|
-
const toggle = () => {
|
|
49
|
-
return this.toggleFilter(routeIdentifier);
|
|
50
|
-
};
|
|
51
|
-
return /* @__PURE__ */ React.createElement("div", {
|
|
52
|
-
"aria-label": title,
|
|
53
|
-
className: `${className}${active ? " rt-active" : ""}`,
|
|
54
|
-
title,
|
|
55
|
-
onClick: toggle,
|
|
56
|
-
onKeyPress: (e) => {
|
|
57
|
-
return e.which === 13 && toggle();
|
|
58
|
-
},
|
|
59
|
-
role: "button",
|
|
60
|
-
tabIndex: 0
|
|
61
|
-
}, children);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
FilterButton.propTypes = propTypes;
|
|
65
|
-
FilterButton.defaultProps = defaultProps;
|
|
66
|
-
export default FilterButton;
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/components/FilterButton/FilterButton.js"],
|
|
4
|
-
"sourcesContent": ["import React, { PureComponent } from 'react';\nimport qs from 'query-string';\nimport PropTypes from 'prop-types';\nimport { RealtimeLayer as TrackerLayer } from 'mobility-toolbox-js/ol';\n\nconst propTypes = {\n /**\n * CSS class of the filter button.\n */\n className: PropTypes.string,\n\n /**\n * Title.\n */\n title: PropTypes.string,\n\n /**\n * Line info route identifer.\n */\n routeIdentifier: PropTypes.string.isRequired,\n\n /**\n * Button is active.\n */\n active: PropTypes.bool.isRequired,\n\n /**\n * Function triggered on button click.\n */\n onClick: PropTypes.func.isRequired,\n\n /**\n * Trackerlayer.\n */\n trackerLayer: PropTypes.instanceOf(TrackerLayer).isRequired,\n\n /**\n * Children content of the button.\n */\n children: PropTypes.element.isRequired,\n};\n\nconst defaultProps = {\n className: 'rt-route-filter',\n title: 'Filter',\n};\n\n/**\n * Button enables the filtering of a selected train.\n */\nclass FilterButton extends PureComponent {\n updatePermalink(isRemoving) {\n const { routeIdentifier } = this.props;\n\n const parameters = qs.parse(window.location.search.toLowerCase());\n if (isRemoving) {\n delete parameters.tripnumber;\n } else {\n parameters.tripnumber = parseInt(routeIdentifier.split('.')[0], 10);\n }\n\n const qStr = qs.stringify(parameters, { encode: false });\n const search = `?${qStr}`;\n const { hash } = window.location;\n window.history.replaceState(undefined, undefined, `${search}${hash || ''}`);\n }\n\n toggleFilter(routeIdentifier) {\n const { trackerLayer, active, onClick } = this.props;\n const activated = !active;\n\n if (trackerLayer) {\n if (activated) {\n this.updatePermalink(false);\n [trackerLayer.tripNumber] = routeIdentifier.split('.');\n } else {\n this.updatePermalink(true);\n trackerLayer.tripNumber = null;\n }\n }\n\n onClick(activated);\n }\n\n render() {\n const { className, title, routeIdentifier, active, children } = this.props;\n const toggle = () => {\n return this.toggleFilter(routeIdentifier);\n };\n\n return (\n <div\n aria-label={title}\n className={`${className}${active ? ' rt-active' : ''}`}\n title={title}\n onClick={toggle}\n onKeyPress={(e) => {\n return e.which === 13 && toggle();\n }}\n role=\"button\"\n tabIndex={0}\n >\n {children}\n </div>\n );\n }\n}\n\nFilterButton.propTypes = propTypes;\nFilterButton.defaultProps = defaultProps;\n\nexport default FilterButton;\n"],
|
|
5
|
-
"mappings": "AAAA,OAAO,SAAS,qBAAqB;AACrC,OAAO,QAAQ;AACf,OAAO,eAAe;AACtB,SAAS,iBAAiB,oBAAoB;AAE9C,MAAM,YAAY;AAAA,EAIhB,WAAW,UAAU;AAAA,EAKrB,OAAO,UAAU;AAAA,EAKjB,iBAAiB,UAAU,OAAO;AAAA,EAKlC,QAAQ,UAAU,KAAK;AAAA,EAKvB,SAAS,UAAU,KAAK;AAAA,EAKxB,cAAc,UAAU,WAAW,YAAY,EAAE;AAAA,EAKjD,UAAU,UAAU,QAAQ;AAC9B;AAEA,MAAM,eAAe;AAAA,EACnB,WAAW;AAAA,EACX,OAAO;AACT;AAKA,MAAM,qBAAqB,cAAc;AAAA,EACvC,gBAAgB,YAAY;AAC1B,UAAM,EAAE,gBAAgB,IAAI,KAAK;AAEjC,UAAM,aAAa,GAAG,MAAM,OAAO,SAAS,OAAO,YAAY,CAAC;AAChE,QAAI,YAAY;AACd,aAAO,WAAW;AAAA,IACpB,OAAO;AACL,iBAAW,aAAa,SAAS,gBAAgB,MAAM,GAAG,EAAE,IAAI,EAAE;AAAA,IACpE;AAEA,UAAM,OAAO,GAAG,UAAU,YAAY,EAAE,QAAQ,MAAM,CAAC;AACvD,UAAM,SAAS,IAAI;AACnB,UAAM,EAAE,KAAK,IAAI,OAAO;AACxB,WAAO,QAAQ,aAAa,QAAW,QAAW,GAAG,SAAS,QAAQ,IAAI;AAAA,EAC5E;AAAA,EAEA,aAAa,iBAAiB;AAC5B,UAAM,EAAE,cAAc,QAAQ,QAAQ,IAAI,KAAK;AAC/C,UAAM,YAAY,CAAC;AAEnB,QAAI,cAAc;AAChB,UAAI,WAAW;AACb,aAAK,gBAAgB,KAAK;AAC1B,SAAC,aAAa,UAAU,IAAI,gBAAgB,MAAM,GAAG;AAAA,MACvD,OAAO;AACL,aAAK,gBAAgB,IAAI;AACzB,qBAAa,aAAa;AAAA,MAC5B;AAAA,IACF;AAEA,YAAQ,SAAS;AAAA,EACnB;AAAA,EAEA,SAAS;AACP,UAAM,EAAE,WAAW,OAAO,iBAAiB,QAAQ,SAAS,IAAI,KAAK;AACrE,UAAM,SAAS,MAAM;AACnB,aAAO,KAAK,aAAa,eAAe;AAAA,IAC1C;AAEA,WACE,oCAAC;AAAA,MACC,cAAY;AAAA,MACZ,WAAW,GAAG,YAAY,SAAS,eAAe;AAAA,MAClD;AAAA,MACA,SAAS;AAAA,MACT,YAAY,CAAC,MAAM;AACjB,eAAO,EAAE,UAAU,MAAM,OAAO;AAAA,MAClC;AAAA,MACA,MAAK;AAAA,MACL,UAAU;AAAA,OAET,QACH;AAAA,EAEJ;AACF;AAEA,aAAa,YAAY;AACzB,aAAa,eAAe;AAE5B,eAAe;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
.rt-route-filter {
|
|
2
|
-
display: flex;
|
|
3
|
-
justify-content: center;
|
|
4
|
-
align-items: center;
|
|
5
|
-
height: 35px;
|
|
6
|
-
width: 35px;
|
|
7
|
-
border-radius: 7px;
|
|
8
|
-
margin: 15px;
|
|
9
|
-
margin-top: 10px;
|
|
10
|
-
border: 2px solid #eee;
|
|
11
|
-
background-color: white;
|
|
12
|
-
|
|
13
|
-
svg {
|
|
14
|
-
height: 30px;
|
|
15
|
-
width: 30px;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
&:hover {
|
|
19
|
-
background-color: #eee;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
&.rt-active {
|
|
23
|
-
border-color: red;
|
|
24
|
-
background-color: red;
|
|
25
|
-
|
|
26
|
-
svg {
|
|
27
|
-
path {
|
|
28
|
-
fill: white;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
&:hover {
|
|
33
|
-
background-color: red;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from "./FilterButton";
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import React, { PureComponent } from "react";
|
|
2
|
-
import PropTypes from "prop-types";
|
|
3
|
-
import { RealtimeLayer as TrackerLayer } from "mobility-toolbox-js/ol";
|
|
4
|
-
const propTypes = {
|
|
5
|
-
className: PropTypes.string,
|
|
6
|
-
title: PropTypes.string,
|
|
7
|
-
routeIdentifier: PropTypes.string.isRequired,
|
|
8
|
-
active: PropTypes.bool.isRequired,
|
|
9
|
-
onClick: PropTypes.func.isRequired,
|
|
10
|
-
trackerLayer: PropTypes.instanceOf(TrackerLayer).isRequired,
|
|
11
|
-
setCenter: PropTypes.func.isRequired,
|
|
12
|
-
children: PropTypes.element.isRequired
|
|
13
|
-
};
|
|
14
|
-
const defaultProps = {
|
|
15
|
-
className: "rt-route-follow",
|
|
16
|
-
title: "Follow"
|
|
17
|
-
};
|
|
18
|
-
class FollowButton extends PureComponent {
|
|
19
|
-
constructor() {
|
|
20
|
-
super();
|
|
21
|
-
this.onClick = this.onClick.bind(this);
|
|
22
|
-
}
|
|
23
|
-
componentDidUpdate(prevProps) {
|
|
24
|
-
const { routeIdentifier, active, trackerLayer, onClick } = this.props;
|
|
25
|
-
if (routeIdentifier !== prevProps.routeIdentifier) {
|
|
26
|
-
onClick(false);
|
|
27
|
-
}
|
|
28
|
-
if (active !== prevProps.active) {
|
|
29
|
-
if (active && trackerLayer) {
|
|
30
|
-
this.centerOnTrajectory(routeIdentifier);
|
|
31
|
-
this.updateInterval = window.setInterval(() => {
|
|
32
|
-
this.centerOnTrajectory(routeIdentifier);
|
|
33
|
-
}, 50);
|
|
34
|
-
} else {
|
|
35
|
-
clearInterval(this.updateInterval);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
componentWillUnmount() {
|
|
40
|
-
clearInterval(this.updateInterval);
|
|
41
|
-
}
|
|
42
|
-
onClick() {
|
|
43
|
-
const { active, onClick } = this.props;
|
|
44
|
-
onClick(!active);
|
|
45
|
-
}
|
|
46
|
-
centerOnTrajectory(routeIdentifier) {
|
|
47
|
-
const { trackerLayer, setCenter } = this.props;
|
|
48
|
-
const [trajectory] = trackerLayer.getVehicle((r) => {
|
|
49
|
-
return r.routeIdentifier === routeIdentifier;
|
|
50
|
-
});
|
|
51
|
-
const firstCoord = trajectory && trajectory.coordinate;
|
|
52
|
-
if (firstCoord) {
|
|
53
|
-
setCenter(firstCoord);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
render() {
|
|
57
|
-
const { className, title, active, children } = this.props;
|
|
58
|
-
return /* @__PURE__ */ React.createElement("div", {
|
|
59
|
-
"aria-label": title,
|
|
60
|
-
className: `${className}${active ? " rt-active" : ""}`,
|
|
61
|
-
title,
|
|
62
|
-
onClick: this.onClick,
|
|
63
|
-
onKeyPress: (e) => {
|
|
64
|
-
return e.which === 13 && this.onClick;
|
|
65
|
-
},
|
|
66
|
-
role: "button",
|
|
67
|
-
tabIndex: 0
|
|
68
|
-
}, children);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
FollowButton.propTypes = propTypes;
|
|
72
|
-
FollowButton.defaultProps = defaultProps;
|
|
73
|
-
export default FollowButton;
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/components/FollowButton/FollowButton.js"],
|
|
4
|
-
"sourcesContent": ["import React, { PureComponent } from 'react';\nimport PropTypes from 'prop-types';\nimport { RealtimeLayer as TrackerLayer } from 'mobility-toolbox-js/ol';\n\nconst propTypes = {\n /**\n * CSS class of the follow button.\n */\n className: PropTypes.string,\n\n /**\n * Title.\n */\n title: PropTypes.string,\n\n /**\n * Line info route identifer.\n */\n routeIdentifier: PropTypes.string.isRequired,\n\n /**\n * Button is active.\n */\n active: PropTypes.bool.isRequired,\n\n /**\n * Function triggered on button click.\n */\n onClick: PropTypes.func.isRequired,\n\n /**\n * Trackerlayer.\n */\n trackerLayer: PropTypes.instanceOf(TrackerLayer).isRequired,\n\n /**\n * Function to set the map center, Used to follow a train.\n */\n setCenter: PropTypes.func.isRequired,\n\n /**\n * Children content of the button.\n */\n children: PropTypes.element.isRequired,\n};\n\nconst defaultProps = {\n className: 'rt-route-follow',\n title: 'Follow',\n};\n\n/**\n * Button enables the follow of a selected train.\n */\nclass FollowButton extends PureComponent {\n constructor() {\n super();\n this.onClick = this.onClick.bind(this);\n }\n\n componentDidUpdate(prevProps) {\n const { routeIdentifier, active, trackerLayer, onClick } = this.props;\n\n if (routeIdentifier !== prevProps.routeIdentifier) {\n onClick(false);\n }\n\n if (active !== prevProps.active) {\n if (active && trackerLayer) {\n this.centerOnTrajectory(routeIdentifier);\n this.updateInterval = window.setInterval(() => {\n this.centerOnTrajectory(routeIdentifier);\n }, 50);\n } else {\n clearInterval(this.updateInterval);\n }\n }\n }\n\n componentWillUnmount() {\n clearInterval(this.updateInterval);\n }\n\n onClick() {\n const { active, onClick } = this.props;\n onClick(!active);\n }\n\n centerOnTrajectory(routeIdentifier) {\n const { trackerLayer, setCenter } = this.props;\n\n const [trajectory] = trackerLayer.getVehicle((r) => {\n return r.routeIdentifier === routeIdentifier;\n });\n const firstCoord = trajectory && trajectory.coordinate;\n if (firstCoord) {\n setCenter(firstCoord);\n }\n }\n\n render() {\n const { className, title, active, children } = this.props;\n\n return (\n <div\n aria-label={title}\n className={`${className}${active ? ' rt-active' : ''}`}\n title={title}\n onClick={this.onClick}\n onKeyPress={(e) => {\n return e.which === 13 && this.onClick;\n }}\n role=\"button\"\n tabIndex={0}\n >\n {children}\n </div>\n );\n }\n}\n\nFollowButton.propTypes = propTypes;\nFollowButton.defaultProps = defaultProps;\n\nexport default FollowButton;\n"],
|
|
5
|
-
"mappings": "AAAA,OAAO,SAAS,qBAAqB;AACrC,OAAO,eAAe;AACtB,SAAS,iBAAiB,oBAAoB;AAE9C,MAAM,YAAY;AAAA,EAIhB,WAAW,UAAU;AAAA,EAKrB,OAAO,UAAU;AAAA,EAKjB,iBAAiB,UAAU,OAAO;AAAA,EAKlC,QAAQ,UAAU,KAAK;AAAA,EAKvB,SAAS,UAAU,KAAK;AAAA,EAKxB,cAAc,UAAU,WAAW,YAAY,EAAE;AAAA,EAKjD,WAAW,UAAU,KAAK;AAAA,EAK1B,UAAU,UAAU,QAAQ;AAC9B;AAEA,MAAM,eAAe;AAAA,EACnB,WAAW;AAAA,EACX,OAAO;AACT;AAKA,MAAM,qBAAqB,cAAc;AAAA,EACvC,cAAc;AACZ,UAAM;AACN,SAAK,UAAU,KAAK,QAAQ,KAAK,IAAI;AAAA,EACvC;AAAA,EAEA,mBAAmB,WAAW;AAC5B,UAAM,EAAE,iBAAiB,QAAQ,cAAc,QAAQ,IAAI,KAAK;AAEhE,QAAI,oBAAoB,UAAU,iBAAiB;AACjD,cAAQ,KAAK;AAAA,IACf;AAEA,QAAI,WAAW,UAAU,QAAQ;AAC/B,UAAI,UAAU,cAAc;AAC1B,aAAK,mBAAmB,eAAe;AACvC,aAAK,iBAAiB,OAAO,YAAY,MAAM;AAC7C,eAAK,mBAAmB,eAAe;AAAA,QACzC,GAAG,EAAE;AAAA,MACP,OAAO;AACL,sBAAc,KAAK,cAAc;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,uBAAuB;AACrB,kBAAc,KAAK,cAAc;AAAA,EACnC;AAAA,EAEA,UAAU;AACR,UAAM,EAAE,QAAQ,QAAQ,IAAI,KAAK;AACjC,YAAQ,CAAC,MAAM;AAAA,EACjB;AAAA,EAEA,mBAAmB,iBAAiB;AAClC,UAAM,EAAE,cAAc,UAAU,IAAI,KAAK;AAEzC,UAAM,CAAC,UAAU,IAAI,aAAa,WAAW,CAAC,MAAM;AAClD,aAAO,EAAE,oBAAoB;AAAA,IAC/B,CAAC;AACD,UAAM,aAAa,cAAc,WAAW;AAC5C,QAAI,YAAY;AACd,gBAAU,UAAU;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,SAAS;AACP,UAAM,EAAE,WAAW,OAAO,QAAQ,SAAS,IAAI,KAAK;AAEpD,WACE,oCAAC;AAAA,MACC,cAAY;AAAA,MACZ,WAAW,GAAG,YAAY,SAAS,eAAe;AAAA,MAClD;AAAA,MACA,SAAS,KAAK;AAAA,MACd,YAAY,CAAC,MAAM;AACjB,eAAO,EAAE,UAAU,MAAM,KAAK;AAAA,MAChC;AAAA,MACA,MAAK;AAAA,MACL,UAAU;AAAA,OAET,QACH;AAAA,EAEJ;AACF;AAEA,aAAa,YAAY;AACzB,aAAa,eAAe;AAE5B,eAAe;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
.rt-route-follow {
|
|
2
|
-
display: flex;
|
|
3
|
-
justify-content: center;
|
|
4
|
-
align-items: center;
|
|
5
|
-
height: 35px;
|
|
6
|
-
width: 35px;
|
|
7
|
-
border-radius: 7px;
|
|
8
|
-
margin: 15px;
|
|
9
|
-
margin-top: 10px;
|
|
10
|
-
border: 2px solid #eee;
|
|
11
|
-
background-color: white;
|
|
12
|
-
|
|
13
|
-
svg {
|
|
14
|
-
height: 30px;
|
|
15
|
-
width: 30px;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
&:hover {
|
|
19
|
-
background-color: #eee;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
&.rt-active {
|
|
23
|
-
border-color: red;
|
|
24
|
-
background-color: red;
|
|
25
|
-
|
|
26
|
-
svg {
|
|
27
|
-
path {
|
|
28
|
-
fill: white;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
&:hover {
|
|
33
|
-
background-color: red;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from "./FollowButton";
|
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
import PropTypes from "prop-types";
|
|
2
|
-
import React, { useMemo, useState } from "react";
|
|
3
|
-
import Autosuggest from "react-autosuggest";
|
|
4
|
-
import { FaSearch, FaTimes } from "react-icons/fa";
|
|
5
|
-
import SearchService from "./SearchService";
|
|
6
|
-
import StopFinder from "./engines/StopFinder";
|
|
7
|
-
const propTypes = {
|
|
8
|
-
engines: PropTypes.object,
|
|
9
|
-
getRenderSectionTitle: PropTypes.func,
|
|
10
|
-
initialValue: PropTypes.string,
|
|
11
|
-
inputProps: PropTypes.object,
|
|
12
|
-
onHighlight: PropTypes.func,
|
|
13
|
-
shouldRenderSuggestions: PropTypes.func,
|
|
14
|
-
onSelect: PropTypes.func,
|
|
15
|
-
className: PropTypes.string,
|
|
16
|
-
apiKey: PropTypes.string
|
|
17
|
-
};
|
|
18
|
-
const defaultProps = {
|
|
19
|
-
apiKey: null,
|
|
20
|
-
engines: null,
|
|
21
|
-
getRenderSectionTitle: () => {
|
|
22
|
-
return () => {
|
|
23
|
-
return null;
|
|
24
|
-
};
|
|
25
|
-
},
|
|
26
|
-
initialValue: "",
|
|
27
|
-
onHighlight: () => {
|
|
28
|
-
return null;
|
|
29
|
-
},
|
|
30
|
-
shouldRenderSuggestions: (newValue) => {
|
|
31
|
-
return newValue.trim().length > 2;
|
|
32
|
-
},
|
|
33
|
-
onSelect: () => {
|
|
34
|
-
return null;
|
|
35
|
-
},
|
|
36
|
-
className: "rt-search",
|
|
37
|
-
inputProps: {}
|
|
38
|
-
};
|
|
39
|
-
function Search({
|
|
40
|
-
apiKey,
|
|
41
|
-
engines,
|
|
42
|
-
getRenderSectionTitle,
|
|
43
|
-
initialValue,
|
|
44
|
-
inputProps,
|
|
45
|
-
onHighlight,
|
|
46
|
-
shouldRenderSuggestions,
|
|
47
|
-
onSelect,
|
|
48
|
-
className
|
|
49
|
-
}) {
|
|
50
|
-
const currentEngines = useMemo(() => {
|
|
51
|
-
if (!engines) {
|
|
52
|
-
return {
|
|
53
|
-
stops: new StopFinder(void 0, { apiKey })
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
if (apiKey) {
|
|
57
|
-
Object.values(engines).forEach((engine) => {
|
|
58
|
-
if (engine.setApiKey) {
|
|
59
|
-
engine.setApiKey(apiKey);
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
return engines;
|
|
64
|
-
}, [apiKey, engines]);
|
|
65
|
-
const [suggestions, setSuggestions] = useState([]);
|
|
66
|
-
const [value, setValue] = useState(initialValue);
|
|
67
|
-
const searchService = useMemo(() => {
|
|
68
|
-
return new SearchService({
|
|
69
|
-
apiKey,
|
|
70
|
-
engines: currentEngines,
|
|
71
|
-
setSuggestions
|
|
72
|
-
});
|
|
73
|
-
}, [apiKey, currentEngines]);
|
|
74
|
-
const theme = useMemo(() => {
|
|
75
|
-
return {
|
|
76
|
-
container: `${className}__container`,
|
|
77
|
-
containerOpen: `${className}__container--open`,
|
|
78
|
-
input: `${className}__input`,
|
|
79
|
-
inputOpen: `${className}__input--open`,
|
|
80
|
-
inputFocused: `${className}__input--focused`,
|
|
81
|
-
suggestionsContainer: `${className}__suggestions-container`,
|
|
82
|
-
suggestionsContainerOpen: `${className}__suggestions-container--open`,
|
|
83
|
-
suggestionsList: `${className}__suggestions-list`,
|
|
84
|
-
suggestion: `${className}__suggestion`,
|
|
85
|
-
suggestionFirst: `${className}__suggestion--first`,
|
|
86
|
-
suggestionHighlighted: `${className}__suggestion--highlighted`,
|
|
87
|
-
sectionContainer: `${className}__section-container`,
|
|
88
|
-
sectionContainerFirst: `${className}__section-container--first`,
|
|
89
|
-
sectionTitle: `${className}__section-title`
|
|
90
|
-
};
|
|
91
|
-
}, [className]);
|
|
92
|
-
return Object.keys(currentEngines).length > 0 && /* @__PURE__ */ React.createElement("div", {
|
|
93
|
-
className: "rt-search"
|
|
94
|
-
}, /* @__PURE__ */ React.createElement(Autosuggest, {
|
|
95
|
-
theme,
|
|
96
|
-
inputProps: {
|
|
97
|
-
autoFocus: true,
|
|
98
|
-
tabIndex: 0,
|
|
99
|
-
onChange: (e, { newValue }) => {
|
|
100
|
-
return setValue(newValue);
|
|
101
|
-
},
|
|
102
|
-
onKeyUp: ({ key }) => {
|
|
103
|
-
if (key === "Enter") {
|
|
104
|
-
const filtered = suggestions.filter((s) => {
|
|
105
|
-
return s.items.length > 0;
|
|
106
|
-
});
|
|
107
|
-
if (filtered.length > 0) {
|
|
108
|
-
const { items, section } = filtered[0];
|
|
109
|
-
const targetSuggestion = { ...items[0], section };
|
|
110
|
-
setValue(searchService.value(targetSuggestion));
|
|
111
|
-
onSelect(targetSuggestion);
|
|
112
|
-
}
|
|
113
|
-
} else if ((key === "ArrowDown" || key === "ArrowUp") && typeof searchService.highlightSection === "function") {
|
|
114
|
-
searchService.highlightSection();
|
|
115
|
-
}
|
|
116
|
-
},
|
|
117
|
-
value,
|
|
118
|
-
...inputProps
|
|
119
|
-
},
|
|
120
|
-
multiSection: true,
|
|
121
|
-
getSectionSuggestions: ({ items, section }) => {
|
|
122
|
-
return items ? items.map((i) => {
|
|
123
|
-
return { ...i, section };
|
|
124
|
-
}) : [];
|
|
125
|
-
},
|
|
126
|
-
getSuggestionValue: (suggestion) => {
|
|
127
|
-
return searchService.value(suggestion);
|
|
128
|
-
},
|
|
129
|
-
onSuggestionsFetchRequested: ({ value: newValue }) => {
|
|
130
|
-
return searchService.search(newValue);
|
|
131
|
-
},
|
|
132
|
-
onSuggestionsClearRequested: () => {
|
|
133
|
-
return setSuggestions([]);
|
|
134
|
-
},
|
|
135
|
-
onSuggestionHighlighted: ({ suggestion }) => {
|
|
136
|
-
return onHighlight(suggestion);
|
|
137
|
-
},
|
|
138
|
-
onSuggestionSelected: (e, { suggestion }) => {
|
|
139
|
-
return onSelect(suggestion);
|
|
140
|
-
},
|
|
141
|
-
renderSuggestion: (suggestion) => {
|
|
142
|
-
return searchService.render(suggestion);
|
|
143
|
-
},
|
|
144
|
-
renderSectionTitle: getRenderSectionTitle(searchService),
|
|
145
|
-
shouldRenderSuggestions: (newValue) => {
|
|
146
|
-
return shouldRenderSuggestions(newValue);
|
|
147
|
-
},
|
|
148
|
-
suggestions
|
|
149
|
-
}), value && /* @__PURE__ */ React.createElement("button", {
|
|
150
|
-
type: "button",
|
|
151
|
-
tabIndex: 0,
|
|
152
|
-
className: "rt-search-button rt-search-button-clear",
|
|
153
|
-
onClick: () => {
|
|
154
|
-
return setValue("");
|
|
155
|
-
}
|
|
156
|
-
}, /* @__PURE__ */ React.createElement(FaTimes, null)), /* @__PURE__ */ React.createElement("button", {
|
|
157
|
-
type: "button",
|
|
158
|
-
tabIndex: 0,
|
|
159
|
-
className: "rt-search-button rt-search-button-submit"
|
|
160
|
-
}, /* @__PURE__ */ React.createElement(FaSearch, {
|
|
161
|
-
focusable: false
|
|
162
|
-
})));
|
|
163
|
-
}
|
|
164
|
-
Search.propTypes = propTypes;
|
|
165
|
-
Search.defaultProps = defaultProps;
|
|
166
|
-
export default Search;
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/components/Search/Search.js"],
|
|
4
|
-
"sourcesContent": ["import PropTypes from 'prop-types';\nimport React, { useMemo, useState } from 'react';\nimport Autosuggest from 'react-autosuggest';\nimport { FaSearch, FaTimes } from 'react-icons/fa';\n\nimport SearchService from './SearchService';\nimport StopFinder from './engines/StopFinder';\n\nconst propTypes = {\n /**\n * Flat object to provide custom search engines: key is the section and value an instance of the Engine class.\n */\n engines: PropTypes.object,\n\n /**\n * A function which will receive the searchService instance and needs to return a render function for the section title, see [react-autosuggest documentation](https://github.com/moroshko/react-autosuggest#render-section-title-prop) for details.\n */\n getRenderSectionTitle: PropTypes.func,\n\n /**\n * Initial value for the search input field.\n */\n initialValue: PropTypes.string,\n\n /**\n * Props for the search input field, see [react-autosuggest documentation](https://github.com/moroshko/react-autosuggest#input-props-prop) for details.\n */\n inputProps: PropTypes.object,\n\n /**\n * Callback function which will be called with the hovered suggestion.\n */\n onHighlight: PropTypes.func,\n\n /**\n * Function to define whether the suggestions are displayed or not.\n * See 'shouldRenderSuggestions' in [react-autosuggest documentation](https://github.com/moroshko/react-autosuggest#input-props-prop) for details.\n */\n shouldRenderSuggestions: PropTypes.func,\n\n /**\n * Callback function which will be called with the selected suggestion.\n */\n onSelect: PropTypes.func,\n\n /**\n * CSS class of the component.\n */\n className: PropTypes.string,\n\n /**\n * Key to access the engine api.\n */\n apiKey: PropTypes.string,\n};\n\nconst defaultProps = {\n apiKey: null,\n engines: null,\n getRenderSectionTitle: () => {\n return () => {\n return null;\n };\n },\n initialValue: '',\n onHighlight: () => {\n return null;\n },\n shouldRenderSuggestions: (newValue) => {\n return newValue.trim().length > 2;\n },\n onSelect: () => {\n return null;\n },\n className: 'rt-search',\n inputProps: {},\n};\n\n/**\n * The Search component renders a text input field which searches for stops\n * using the input string and centers the map on the selected stop.\n */\nfunction Search({\n apiKey,\n engines,\n getRenderSectionTitle,\n initialValue,\n inputProps,\n onHighlight,\n shouldRenderSuggestions,\n onSelect,\n className,\n}) {\n const currentEngines = useMemo(() => {\n if (!engines) {\n return {\n stops: new StopFinder(undefined, { apiKey }),\n };\n }\n if (apiKey) {\n Object.values(engines).forEach((engine) => {\n if (engine.setApiKey) {\n engine.setApiKey(apiKey);\n }\n });\n }\n return engines;\n }, [apiKey, engines]);\n\n const [suggestions, setSuggestions] = useState([]);\n const [value, setValue] = useState(initialValue);\n\n const searchService = useMemo(() => {\n return new SearchService({\n apiKey,\n engines: currentEngines,\n setSuggestions,\n });\n }, [apiKey, currentEngines]);\n\n const theme = useMemo(() => {\n return {\n container: `${className}__container`,\n containerOpen: `${className}__container--open`,\n input: `${className}__input`,\n inputOpen: `${className}__input--open`,\n inputFocused: `${className}__input--focused`,\n suggestionsContainer: `${className}__suggestions-container`,\n suggestionsContainerOpen: `${className}__suggestions-container--open`,\n suggestionsList: `${className}__suggestions-list`,\n suggestion: `${className}__suggestion`,\n suggestionFirst: `${className}__suggestion--first`,\n suggestionHighlighted: `${className}__suggestion--highlighted`,\n sectionContainer: `${className}__section-container`,\n sectionContainerFirst: `${className}__section-container--first`,\n sectionTitle: `${className}__section-title`,\n };\n }, [className]);\n\n return (\n Object.keys(currentEngines).length > 0 && (\n <div className=\"rt-search\">\n <Autosuggest\n theme={theme}\n inputProps={{\n autoFocus: true,\n tabIndex: 0,\n onChange: (e, { newValue }) => {\n return setValue(newValue);\n },\n onKeyUp: ({ key }) => {\n if (key === 'Enter') {\n const filtered = suggestions.filter((s) => {\n return s.items.length > 0;\n });\n if (filtered.length > 0) {\n const { items, section } = filtered[0];\n const targetSuggestion = { ...items[0], section };\n setValue(searchService.value(targetSuggestion));\n onSelect(targetSuggestion);\n }\n } else if (\n (key === 'ArrowDown' || key === 'ArrowUp') &&\n typeof searchService.highlightSection === 'function'\n ) {\n searchService.highlightSection(); // for improved accessibility\n }\n },\n value,\n ...inputProps,\n }}\n multiSection\n getSectionSuggestions={({ items, section }) => {\n return items\n ? items.map((i) => {\n return { ...i, section };\n })\n : [];\n }}\n getSuggestionValue={(suggestion) => {\n return searchService.value(suggestion);\n }}\n onSuggestionsFetchRequested={({ value: newValue }) => {\n return searchService.search(newValue);\n }}\n onSuggestionsClearRequested={() => {\n return setSuggestions([]);\n }}\n onSuggestionHighlighted={({ suggestion }) => {\n return onHighlight(suggestion);\n }}\n onSuggestionSelected={(e, { suggestion }) => {\n return onSelect(suggestion);\n }}\n renderSuggestion={(suggestion) => {\n return searchService.render(suggestion);\n }}\n renderSectionTitle={getRenderSectionTitle(searchService)}\n shouldRenderSuggestions={(newValue) => {\n return shouldRenderSuggestions(newValue);\n }}\n suggestions={suggestions}\n />\n {value && (\n <button\n type=\"button\"\n tabIndex={0}\n className=\"rt-search-button rt-search-button-clear\"\n onClick={() => {\n return setValue('');\n }}\n >\n <FaTimes />\n </button>\n )}\n <button\n type=\"button\"\n tabIndex={0}\n className=\"rt-search-button rt-search-button-submit\"\n >\n <FaSearch focusable={false} />\n </button>\n </div>\n )\n );\n}\n\nSearch.propTypes = propTypes;\nSearch.defaultProps = defaultProps;\n\nexport default Search;\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
.rt-search {
|
|
2
|
-
display: flex;
|
|
3
|
-
font-family: Arial, sans-serif;
|
|
4
|
-
height: 50px;
|
|
5
|
-
width: 350px;
|
|
6
|
-
position: relative;
|
|
7
|
-
|
|
8
|
-
.rt-search__container {
|
|
9
|
-
width: 100%;
|
|
10
|
-
position: relative;
|
|
11
|
-
|
|
12
|
-
.rt-search__input {
|
|
13
|
-
border: 1px solid #515151;
|
|
14
|
-
padding: 0 0 0 1em;
|
|
15
|
-
text-overflow: ellipsis;
|
|
16
|
-
font-size: 1em;
|
|
17
|
-
height: 48px;
|
|
18
|
-
width: calc(100% - 1em);
|
|
19
|
-
|
|
20
|
-
&::-ms-clear {
|
|
21
|
-
display: none;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
.rt-search__suggestions-container--open {
|
|
26
|
-
background-color: #fff;
|
|
27
|
-
position: absolute;
|
|
28
|
-
top: calc(100% - 1px);
|
|
29
|
-
width: 100%;
|
|
30
|
-
border: 1px solid #515151;
|
|
31
|
-
z-index: 1;
|
|
32
|
-
|
|
33
|
-
.rt-search__suggestions-list {
|
|
34
|
-
padding: 0;
|
|
35
|
-
margin: 0.5em 0;
|
|
36
|
-
list-style: none;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
.rt-search__suggestion {
|
|
40
|
-
padding: 0.5em 1em;
|
|
41
|
-
cursor: pointer;
|
|
42
|
-
color: #515151;
|
|
43
|
-
|
|
44
|
-
&:hover {
|
|
45
|
-
color: #eb0000;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
.rt-search-button {
|
|
52
|
-
font-size: 1em;
|
|
53
|
-
cursor: pointer;
|
|
54
|
-
background: none;
|
|
55
|
-
border: none;
|
|
56
|
-
display: flex;
|
|
57
|
-
justify-content: center;
|
|
58
|
-
align-items: center;
|
|
59
|
-
height: 50px;
|
|
60
|
-
padding: 0;
|
|
61
|
-
|
|
62
|
-
svg {
|
|
63
|
-
width: 50px;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
&.rt-search-button-clear {
|
|
67
|
-
position: absolute;
|
|
68
|
-
color: #515151;
|
|
69
|
-
right: 50px;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
&.rt-search-button-submit {
|
|
73
|
-
border: 1px solid #515151;
|
|
74
|
-
background-color: #515151;
|
|
75
|
-
color: #fff;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
class SearchService {
|
|
2
|
-
constructor({ apiKey, engines, setSuggestions }) {
|
|
3
|
-
this.engines = engines;
|
|
4
|
-
this.setSuggestions = setSuggestions;
|
|
5
|
-
Object.entries(this.engines).forEach(([, e]) => {
|
|
6
|
-
return e.setApiKey(apiKey);
|
|
7
|
-
});
|
|
8
|
-
}
|
|
9
|
-
countItems(section) {
|
|
10
|
-
return this.engines[section].items && this.engines[section].items.length;
|
|
11
|
-
}
|
|
12
|
-
render(item) {
|
|
13
|
-
return this.engines[item.section].render(item);
|
|
14
|
-
}
|
|
15
|
-
value(item) {
|
|
16
|
-
return this.engines[item.section].constructor.value(item);
|
|
17
|
-
}
|
|
18
|
-
search(value) {
|
|
19
|
-
Object.entries(this.engines).forEach(([section, engine], position) => {
|
|
20
|
-
engine.search(value).then((items) => {
|
|
21
|
-
engine.setItems(items);
|
|
22
|
-
this.upsert(section, engine.getItems(items), position);
|
|
23
|
-
});
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
sectionCollapsed(section) {
|
|
27
|
-
return this.engines[section].collapsed;
|
|
28
|
-
}
|
|
29
|
-
toggleSection(toggledSection) {
|
|
30
|
-
Object.entries(this.engines).forEach(([section, engine], position) => {
|
|
31
|
-
engine.collapse(!(section === toggledSection && engine.collapsed));
|
|
32
|
-
this.upsert(section, engine.getItems(), position);
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
upsert(section, items, position) {
|
|
36
|
-
this.setSuggestions((oldSuggestions) => {
|
|
37
|
-
const sectionIndex = oldSuggestions.findIndex((s) => {
|
|
38
|
-
return s.section === section;
|
|
39
|
-
});
|
|
40
|
-
const start = sectionIndex === -1 ? position : sectionIndex;
|
|
41
|
-
const deleteCount = sectionIndex === -1 ? 0 : 1;
|
|
42
|
-
const newSuggestions = [...oldSuggestions];
|
|
43
|
-
newSuggestions.splice(start, deleteCount, { section, items });
|
|
44
|
-
return newSuggestions;
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
export default SearchService;
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/components/Search/SearchService.js"],
|
|
4
|
-
"sourcesContent": ["class SearchService {\n constructor({ apiKey, engines, setSuggestions }) {\n this.engines = engines;\n this.setSuggestions = setSuggestions;\n Object.entries(this.engines).forEach(([, e]) => {\n return e.setApiKey(apiKey);\n });\n }\n\n countItems(section) {\n return this.engines[section].items && this.engines[section].items.length;\n }\n\n render(item) {\n return this.engines[item.section].render(item);\n }\n\n value(item) {\n return this.engines[item.section].constructor.value(item);\n }\n\n search(value) {\n Object.entries(this.engines).forEach(([section, engine], position) => {\n engine.search(value).then((items) => {\n engine.setItems(items);\n this.upsert(section, engine.getItems(items), position);\n });\n });\n }\n\n sectionCollapsed(section) {\n return this.engines[section].collapsed;\n }\n\n toggleSection(toggledSection) {\n Object.entries(this.engines).forEach(([section, engine], position) => {\n engine.collapse(!(section === toggledSection && engine.collapsed));\n this.upsert(section, engine.getItems(), position);\n });\n }\n\n upsert(section, items, position) {\n this.setSuggestions((oldSuggestions) => {\n const sectionIndex = oldSuggestions.findIndex((s) => {\n return s.section === section;\n });\n const start = sectionIndex === -1 ? position : sectionIndex;\n const deleteCount = sectionIndex === -1 ? 0 : 1;\n const newSuggestions = [...oldSuggestions];\n newSuggestions.splice(start, deleteCount, { section, items });\n return newSuggestions;\n });\n }\n}\n\nexport default SearchService;\n"],
|
|
5
|
-
"mappings": "AAAA,MAAM,cAAc;AAAA,EAClB,YAAY,EAAE,QAAQ,SAAS,eAAe,GAAG;AAC/C,SAAK,UAAU;AACf,SAAK,iBAAiB;AACtB,WAAO,QAAQ,KAAK,OAAO,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,MAAM;AAC9C,aAAO,EAAE,UAAU,MAAM;AAAA,IAC3B,CAAC;AAAA,EACH;AAAA,EAEA,WAAW,SAAS;AAClB,WAAO,KAAK,QAAQ,SAAS,SAAS,KAAK,QAAQ,SAAS,MAAM;AAAA,EACpE;AAAA,EAEA,OAAO,MAAM;AACX,WAAO,KAAK,QAAQ,KAAK,SAAS,OAAO,IAAI;AAAA,EAC/C;AAAA,EAEA,MAAM,MAAM;AACV,WAAO,KAAK,QAAQ,KAAK,SAAS,YAAY,MAAM,IAAI;AAAA,EAC1D;AAAA,EAEA,OAAO,OAAO;AACZ,WAAO,QAAQ,KAAK,OAAO,EAAE,QAAQ,CAAC,CAAC,SAAS,MAAM,GAAG,aAAa;AACpE,aAAO,OAAO,KAAK,EAAE,KAAK,CAAC,UAAU;AACnC,eAAO,SAAS,KAAK;AACrB,aAAK,OAAO,SAAS,OAAO,SAAS,KAAK,GAAG,QAAQ;AAAA,MACvD,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,iBAAiB,SAAS;AACxB,WAAO,KAAK,QAAQ,SAAS;AAAA,EAC/B;AAAA,EAEA,cAAc,gBAAgB;AAC5B,WAAO,QAAQ,KAAK,OAAO,EAAE,QAAQ,CAAC,CAAC,SAAS,MAAM,GAAG,aAAa;AACpE,aAAO,SAAS,EAAE,YAAY,kBAAkB,OAAO,UAAU;AACjE,WAAK,OAAO,SAAS,OAAO,SAAS,GAAG,QAAQ;AAAA,IAClD,CAAC;AAAA,EACH;AAAA,EAEA,OAAO,SAAS,OAAO,UAAU;AAC/B,SAAK,eAAe,CAAC,mBAAmB;AACtC,YAAM,eAAe,eAAe,UAAU,CAAC,MAAM;AACnD,eAAO,EAAE,YAAY;AAAA,MACvB,CAAC;AACD,YAAM,QAAQ,iBAAiB,KAAK,WAAW;AAC/C,YAAM,cAAc,iBAAiB,KAAK,IAAI;AAC9C,YAAM,iBAAiB,CAAC,GAAG,cAAc;AACzC,qBAAe,OAAO,OAAO,aAAa,EAAE,SAAS,MAAM,CAAC;AAC5D,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AACF;AAEA,eAAe;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
class Engine {
|
|
2
|
-
constructor() {
|
|
3
|
-
this.collapsed = true;
|
|
4
|
-
this.items = [];
|
|
5
|
-
}
|
|
6
|
-
collapse(collapsed) {
|
|
7
|
-
this.collapsed = collapsed;
|
|
8
|
-
}
|
|
9
|
-
getItems() {
|
|
10
|
-
return this.collapsed ? this.items.slice(0, 2) : this.items;
|
|
11
|
-
}
|
|
12
|
-
setApiKey(apiKey) {
|
|
13
|
-
this.apiKey = apiKey;
|
|
14
|
-
}
|
|
15
|
-
setItems(items = []) {
|
|
16
|
-
this.items = items;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
export default Engine;
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../../src/components/Search/engines/Engine.js"],
|
|
4
|
-
"sourcesContent": ["class Engine {\n constructor() {\n this.collapsed = true;\n this.items = [];\n }\n\n collapse(collapsed) {\n this.collapsed = collapsed;\n }\n\n getItems() {\n return this.collapsed ? this.items.slice(0, 2) : this.items;\n }\n\n setApiKey(apiKey) {\n this.apiKey = apiKey;\n }\n\n setItems(items = []) {\n this.items = items;\n }\n}\n\nexport default Engine;\n"],
|
|
5
|
-
"mappings": "AAAA,MAAM,OAAO;AAAA,EACX,cAAc;AACZ,SAAK,YAAY;AACjB,SAAK,QAAQ,CAAC;AAAA,EAChB;AAAA,EAEA,SAAS,WAAW;AAClB,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,WAAW;AACT,WAAO,KAAK,YAAY,KAAK,MAAM,MAAM,GAAG,CAAC,IAAI,KAAK;AAAA,EACxD;AAAA,EAEA,UAAU,QAAQ;AAChB,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,SAAS,QAAQ,CAAC,GAAG;AACnB,SAAK,QAAQ;AAAA,EACf;AACF;AAEA,eAAe;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { StopsAPI } from "mobility-toolbox-js/api";
|
|
3
|
-
import Engine from "./Engine";
|
|
4
|
-
class StopFinder extends Engine {
|
|
5
|
-
constructor(endpoint = "https://api.geops.io/stops/v1/", options = {}) {
|
|
6
|
-
super();
|
|
7
|
-
this.options = options;
|
|
8
|
-
delete this.options.apiKey;
|
|
9
|
-
this.api = new StopsAPI({
|
|
10
|
-
url: endpoint,
|
|
11
|
-
apiKey: options.apiKey
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
search(value) {
|
|
15
|
-
return this.api.search({
|
|
16
|
-
q: encodeURIComponent(value),
|
|
17
|
-
...this.options
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
setApiKey(apiKey) {
|
|
21
|
-
this.api.apiKey = apiKey;
|
|
22
|
-
}
|
|
23
|
-
render(item) {
|
|
24
|
-
return /* @__PURE__ */ React.createElement("div", null, item.properties.name);
|
|
25
|
-
}
|
|
26
|
-
static value(item) {
|
|
27
|
-
return item.properties.name;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
export default StopFinder;
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../../src/components/Search/engines/StopFinder.js"],
|
|
4
|
-
"sourcesContent": ["import React from 'react';\n\nimport { StopsAPI } from 'mobility-toolbox-js/api';\nimport Engine from './Engine';\n\nclass StopFinder extends Engine {\n constructor(endpoint = 'https://api.geops.io/stops/v1/', options = {}) {\n super();\n this.options = options;\n // apiKey is passed as key in StopsAPI, delete to avoid duplicates.\n delete this.options.apiKey;\n this.api = new StopsAPI({\n url: endpoint,\n apiKey: options.apiKey,\n });\n }\n\n search(value) {\n return this.api.search({\n q: encodeURIComponent(value),\n ...this.options,\n });\n }\n\n setApiKey(apiKey) {\n this.api.apiKey = apiKey;\n }\n\n render(item) {\n return <div>{item.properties.name}</div>;\n }\n\n static value(item) {\n return item.properties.name;\n }\n}\n\nexport default StopFinder;\n"],
|
|
5
|
-
"mappings": "AAAA,OAAO,WAAW;AAElB,SAAS,gBAAgB;AACzB,OAAO,YAAY;AAEnB,MAAM,mBAAmB,OAAO;AAAA,EAC9B,YAAY,WAAW,kCAAkC,UAAU,CAAC,GAAG;AACrE,UAAM;AACN,SAAK,UAAU;AAEf,WAAO,KAAK,QAAQ;AACpB,SAAK,MAAM,IAAI,SAAS;AAAA,MACtB,KAAK;AAAA,MACL,QAAQ,QAAQ;AAAA,IAClB,CAAC;AAAA,EACH;AAAA,EAEA,OAAO,OAAO;AACZ,WAAO,KAAK,IAAI,OAAO;AAAA,MACrB,GAAG,mBAAmB,KAAK;AAAA,MAC3B,GAAG,KAAK;AAAA,IACV,CAAC;AAAA,EACH;AAAA,EAEA,UAAU,QAAQ;AAChB,SAAK,IAAI,SAAS;AAAA,EACpB;AAAA,EAEA,OAAO,MAAM;AACX,WAAO,oCAAC,aAAK,KAAK,WAAW,IAAK;AAAA,EACpC;AAAA,EAEA,OAAO,MAAM,MAAM;AACjB,WAAO,KAAK,WAAW;AAAA,EACzB;AACF;AAEA,eAAe;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/components/Search/index.js"],
|
|
4
|
-
"sourcesContent": ["export { default as Engine } from './engines/Engine';\nexport { default as StopFinder } from './engines/StopFinder';\n\nexport { default } from './Search';\n"],
|
|
5
|
-
"mappings": "AAAA,kCAAkC;AAClC,sCAAsC;AAEtC,wBAAwB;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import React, { useState, useEffect, useCallback } from "react";
|
|
2
|
-
import PropTypes from "prop-types";
|
|
3
|
-
import { IoIosSpeedometer } from "react-icons/io";
|
|
4
|
-
import { FaPlay, FaForward, FaBackward, FaRegDotCircle } from "react-icons/fa";
|
|
5
|
-
import { RealtimeLayer as TrackerLayer } from "mobility-toolbox-js/ol";
|
|
6
|
-
const increaseSpeed = (speed) => {
|
|
7
|
-
let delta = 0.1;
|
|
8
|
-
if (speed >= 1) {
|
|
9
|
-
delta = 1;
|
|
10
|
-
}
|
|
11
|
-
if (speed >= 10) {
|
|
12
|
-
delta = 5;
|
|
13
|
-
}
|
|
14
|
-
const nextSpeed = speed + delta;
|
|
15
|
-
return nextSpeed > 30 ? speed : nextSpeed;
|
|
16
|
-
};
|
|
17
|
-
const decreaseSpeed = (speed) => {
|
|
18
|
-
let delta = 0.1;
|
|
19
|
-
if (speed > 1) {
|
|
20
|
-
delta = 1;
|
|
21
|
-
}
|
|
22
|
-
if (speed > 10) {
|
|
23
|
-
delta = 5;
|
|
24
|
-
}
|
|
25
|
-
const nextSpeed = speed - delta;
|
|
26
|
-
if (nextSpeed < 0.1) {
|
|
27
|
-
return speed;
|
|
28
|
-
}
|
|
29
|
-
return nextSpeed;
|
|
30
|
-
};
|
|
31
|
-
const defaultRenderButton = (icon, onClick, title) => {
|
|
32
|
-
return /* @__PURE__ */ React.createElement("div", {
|
|
33
|
-
"aria-label": title,
|
|
34
|
-
role: "button",
|
|
35
|
-
onClick,
|
|
36
|
-
onKeyPress: onClick,
|
|
37
|
-
className: "rt-control-button",
|
|
38
|
-
tabIndex: 0,
|
|
39
|
-
title
|
|
40
|
-
}, icon);
|
|
41
|
-
};
|
|
42
|
-
function TrackerControl({
|
|
43
|
-
className,
|
|
44
|
-
iconDateReset,
|
|
45
|
-
iconSpeedDown,
|
|
46
|
-
iconSpeedReset,
|
|
47
|
-
iconSpeedUp,
|
|
48
|
-
iconSpeed,
|
|
49
|
-
renderButton,
|
|
50
|
-
trackerLayer
|
|
51
|
-
}) {
|
|
52
|
-
const [speed, setSpeed] = useState(1);
|
|
53
|
-
const onSpeedChange = useCallback(
|
|
54
|
-
(newSpeed) => {
|
|
55
|
-
if (trackerLayer) {
|
|
56
|
-
trackerLayer.speed = newSpeed;
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
[trackerLayer]
|
|
60
|
-
);
|
|
61
|
-
const resetDate = () => {
|
|
62
|
-
trackerLayer.setCurrTime(new Date());
|
|
63
|
-
};
|
|
64
|
-
useEffect(() => {
|
|
65
|
-
onSpeedChange(speed);
|
|
66
|
-
}, [speed, onSpeedChange]);
|
|
67
|
-
return /* @__PURE__ */ React.createElement("div", {
|
|
68
|
-
className
|
|
69
|
-
}, renderButton(
|
|
70
|
-
iconDateReset,
|
|
71
|
-
() => {
|
|
72
|
-
return resetDate();
|
|
73
|
-
},
|
|
74
|
-
"reset date"
|
|
75
|
-
), renderButton(
|
|
76
|
-
iconSpeedDown,
|
|
77
|
-
() => {
|
|
78
|
-
return setSpeed(decreaseSpeed(speed));
|
|
79
|
-
},
|
|
80
|
-
"speed down"
|
|
81
|
-
), renderButton(
|
|
82
|
-
iconSpeedReset,
|
|
83
|
-
() => {
|
|
84
|
-
return setSpeed(1);
|
|
85
|
-
},
|
|
86
|
-
"speed reset"
|
|
87
|
-
), renderButton(
|
|
88
|
-
iconSpeedUp,
|
|
89
|
-
() => {
|
|
90
|
-
return setSpeed(increaseSpeed(speed));
|
|
91
|
-
},
|
|
92
|
-
"speed up"
|
|
93
|
-
), /* @__PURE__ */ React.createElement("div", {
|
|
94
|
-
className: "rt-tracker-speed"
|
|
95
|
-
}, iconSpeed, `${speed < 1 ? speed.toFixed(1) : speed}`));
|
|
96
|
-
}
|
|
97
|
-
TrackerControl.propTypes = {
|
|
98
|
-
className: PropTypes.string,
|
|
99
|
-
iconDateReset: PropTypes.element,
|
|
100
|
-
iconSpeedDown: PropTypes.element,
|
|
101
|
-
iconSpeedUp: PropTypes.element,
|
|
102
|
-
iconSpeedReset: PropTypes.element,
|
|
103
|
-
iconSpeed: PropTypes.element,
|
|
104
|
-
renderButton: PropTypes.func,
|
|
105
|
-
trackerLayer: PropTypes.instanceOf(TrackerLayer).isRequired
|
|
106
|
-
};
|
|
107
|
-
TrackerControl.defaultProps = {
|
|
108
|
-
className: "rt-tracker-control",
|
|
109
|
-
iconDateReset: /* @__PURE__ */ React.createElement(FaRegDotCircle, null),
|
|
110
|
-
iconSpeedDown: /* @__PURE__ */ React.createElement(FaBackward, null),
|
|
111
|
-
iconSpeedReset: /* @__PURE__ */ React.createElement(FaPlay, null),
|
|
112
|
-
iconSpeedUp: /* @__PURE__ */ React.createElement(FaForward, null),
|
|
113
|
-
iconSpeed: /* @__PURE__ */ React.createElement(IoIosSpeedometer, null),
|
|
114
|
-
renderButton: defaultRenderButton
|
|
115
|
-
};
|
|
116
|
-
export default TrackerControl;
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/components/TrackerControl/TrackerControl.js"],
|
|
4
|
-
"sourcesContent": ["import React, { useState, useEffect, useCallback } from 'react';\nimport PropTypes from 'prop-types';\nimport { IoIosSpeedometer } from 'react-icons/io';\nimport { FaPlay, FaForward, FaBackward, FaRegDotCircle } from 'react-icons/fa';\nimport { RealtimeLayer as TrackerLayer } from 'mobility-toolbox-js/ol';\n\nconst increaseSpeed = (speed) => {\n let delta = 0.1;\n if (speed >= 1) {\n delta = 1;\n }\n if (speed >= 10) {\n delta = 5;\n }\n const nextSpeed = speed + delta;\n return nextSpeed > 30 ? speed : nextSpeed;\n};\n\nconst decreaseSpeed = (speed) => {\n let delta = 0.1;\n if (speed > 1) {\n delta = 1;\n }\n if (speed > 10) {\n delta = 5;\n }\n const nextSpeed = speed - delta;\n if (nextSpeed < 0.1) {\n return speed;\n }\n return nextSpeed;\n};\n\nconst defaultRenderButton = (icon, onClick, title) => {\n return (\n <div\n aria-label={title}\n role=\"button\"\n onClick={onClick}\n onKeyPress={onClick}\n className=\"rt-control-button\"\n tabIndex={0}\n title={title}\n >\n {icon}\n </div>\n );\n};\n\n/**\n * TrackerControl allows the user to control the speed of a\n * [mobility-toolbox-js tracker layer](https://mobility-toolbox-js.geops.io/api/class/src/mapbox/layers/RealtimeLayer%20js~RealtimeLayer%20html-offset-anchor).\n */\nfunction TrackerControl({\n className,\n iconDateReset,\n iconSpeedDown,\n iconSpeedReset,\n iconSpeedUp,\n iconSpeed,\n renderButton,\n trackerLayer,\n}) {\n const [speed, setSpeed] = useState(1);\n\n const onSpeedChange = useCallback(\n (newSpeed) => {\n if (trackerLayer) {\n // eslint-disable-next-line no-param-reassign\n trackerLayer.speed = newSpeed;\n }\n },\n [trackerLayer],\n );\n\n const resetDate = () => {\n trackerLayer.setCurrTime(new Date());\n };\n\n useEffect(() => {\n onSpeedChange(speed);\n }, [speed, onSpeedChange]);\n\n return (\n <div className={className}>\n {renderButton(\n iconDateReset,\n () => {\n return resetDate();\n },\n 'reset date',\n )}\n {renderButton(\n iconSpeedDown,\n () => {\n return setSpeed(decreaseSpeed(speed));\n },\n 'speed down',\n )}\n {renderButton(\n iconSpeedReset,\n () => {\n return setSpeed(1);\n },\n 'speed reset',\n )}\n {renderButton(\n iconSpeedUp,\n () => {\n return setSpeed(increaseSpeed(speed));\n },\n 'speed up',\n )}\n <div className=\"rt-tracker-speed\">\n {iconSpeed}\n {`${speed < 1 ? speed.toFixed(1) : speed}`}\n </div>\n </div>\n );\n}\n\nTrackerControl.propTypes = {\n /**\n * CSS class of the tracker control.\n */\n className: PropTypes.string,\n\n /**\n * Icon of the date reset button.\n */\n iconDateReset: PropTypes.element,\n\n /**\n * Icon of the speed down button.\n */\n iconSpeedDown: PropTypes.element,\n\n /**\n * Icon of the speed up button.\n */\n iconSpeedUp: PropTypes.element,\n\n /**\n * Icon of the speed reset button.\n */\n iconSpeedReset: PropTypes.element,\n\n /**\n * Icon speed.\n */\n iconSpeed: PropTypes.element,\n\n /**\n * Render function for buttons.\n */\n renderButton: PropTypes.func,\n\n /**\n * Trackerlayer.\n */\n trackerLayer: PropTypes.instanceOf(TrackerLayer).isRequired,\n};\n\nTrackerControl.defaultProps = {\n className: 'rt-tracker-control',\n iconDateReset: <FaRegDotCircle />,\n iconSpeedDown: <FaBackward />,\n iconSpeedReset: <FaPlay />,\n iconSpeedUp: <FaForward />,\n iconSpeed: <IoIosSpeedometer />,\n renderButton: defaultRenderButton,\n};\n\nexport default TrackerControl;\n"],
|
|
5
|
-
"mappings": "AAAA,OAAO,SAAS,UAAU,WAAW,mBAAmB;AACxD,OAAO,eAAe;AACtB,SAAS,wBAAwB;AACjC,SAAS,QAAQ,WAAW,YAAY,sBAAsB;AAC9D,SAAS,iBAAiB,oBAAoB;AAE9C,MAAM,gBAAgB,CAAC,UAAU;AAC/B,MAAI,QAAQ;AACZ,MAAI,SAAS,GAAG;AACd,YAAQ;AAAA,EACV;AACA,MAAI,SAAS,IAAI;AACf,YAAQ;AAAA,EACV;AACA,QAAM,YAAY,QAAQ;AAC1B,SAAO,YAAY,KAAK,QAAQ;AAClC;AAEA,MAAM,gBAAgB,CAAC,UAAU;AAC/B,MAAI,QAAQ;AACZ,MAAI,QAAQ,GAAG;AACb,YAAQ;AAAA,EACV;AACA,MAAI,QAAQ,IAAI;AACd,YAAQ;AAAA,EACV;AACA,QAAM,YAAY,QAAQ;AAC1B,MAAI,YAAY,KAAK;AACnB,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,MAAM,sBAAsB,CAAC,MAAM,SAAS,UAAU;AACpD,SACE,oCAAC;AAAA,IACC,cAAY;AAAA,IACZ,MAAK;AAAA,IACL;AAAA,IACA,YAAY;AAAA,IACZ,WAAU;AAAA,IACV,UAAU;AAAA,IACV;AAAA,KAEC,IACH;AAEJ;AAMA,SAAS,eAAe;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAG;AACD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,CAAC;AAEpC,QAAM,gBAAgB;AAAA,IACpB,CAAC,aAAa;AACZ,UAAI,cAAc;AAEhB,qBAAa,QAAQ;AAAA,MACvB;AAAA,IACF;AAAA,IACA,CAAC,YAAY;AAAA,EACf;AAEA,QAAM,YAAY,MAAM;AACtB,iBAAa,YAAY,IAAI,KAAK,CAAC;AAAA,EACrC;AAEA,YAAU,MAAM;AACd,kBAAc,KAAK;AAAA,EACrB,GAAG,CAAC,OAAO,aAAa,CAAC;AAEzB,SACE,oCAAC;AAAA,IAAI;AAAA,KACF;AAAA,IACC;AAAA,IACA,MAAM;AACJ,aAAO,UAAU;AAAA,IACnB;AAAA,IACA;AAAA,EACF,GACC;AAAA,IACC;AAAA,IACA,MAAM;AACJ,aAAO,SAAS,cAAc,KAAK,CAAC;AAAA,IACtC;AAAA,IACA;AAAA,EACF,GACC;AAAA,IACC;AAAA,IACA,MAAM;AACJ,aAAO,SAAS,CAAC;AAAA,IACnB;AAAA,IACA;AAAA,EACF,GACC;AAAA,IACC;AAAA,IACA,MAAM;AACJ,aAAO,SAAS,cAAc,KAAK,CAAC;AAAA,IACtC;AAAA,IACA;AAAA,EACF,GACA,oCAAC;AAAA,IAAI,WAAU;AAAA,KACZ,WACA,GAAG,QAAQ,IAAI,MAAM,QAAQ,CAAC,IAAI,OACrC,CACF;AAEJ;AAEA,eAAe,YAAY;AAAA,EAIzB,WAAW,UAAU;AAAA,EAKrB,eAAe,UAAU;AAAA,EAKzB,eAAe,UAAU;AAAA,EAKzB,aAAa,UAAU;AAAA,EAKvB,gBAAgB,UAAU;AAAA,EAK1B,WAAW,UAAU;AAAA,EAKrB,cAAc,UAAU;AAAA,EAKxB,cAAc,UAAU,WAAW,YAAY,EAAE;AACnD;AAEA,eAAe,eAAe;AAAA,EAC5B,WAAW;AAAA,EACX,eAAe,oCAAC,oBAAe;AAAA,EAC/B,eAAe,oCAAC,gBAAW;AAAA,EAC3B,gBAAgB,oCAAC,YAAO;AAAA,EACxB,aAAa,oCAAC,eAAU;AAAA,EACxB,WAAW,oCAAC,sBAAiB;AAAA,EAC7B,cAAc;AAChB;AAEA,eAAe;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
.rt-tracker-control {
|
|
2
|
-
display: flex;
|
|
3
|
-
align-items: center;
|
|
4
|
-
|
|
5
|
-
.rt-control-button {
|
|
6
|
-
border: 1px solid #ccc;
|
|
7
|
-
color: #333;
|
|
8
|
-
background-color: #fff;
|
|
9
|
-
padding: 8px 12px 4px 12px;
|
|
10
|
-
margin: 2px;
|
|
11
|
-
border-radius: 4px;
|
|
12
|
-
|
|
13
|
-
&:hover {
|
|
14
|
-
cursor: pointer;
|
|
15
|
-
background-color: #f5f5f5;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
.rt-tracker-speed {
|
|
20
|
-
display: flex;
|
|
21
|
-
align-items: center;
|
|
22
|
-
padding-left: 15px;
|
|
23
|
-
|
|
24
|
-
svg {
|
|
25
|
-
height: 1.2em;
|
|
26
|
-
width: 1.2em;
|
|
27
|
-
padding-right: 5px;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from "./TrackerControl";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><title>deactive Filter</title><g id="Ebene_2" data-name="Ebene 2"><g id="Ebene_1-2" data-name="Ebene 1"><rect width="48" height="48" fill="none" rx="2.8"/><path fill="#fff" d="M9.6,14.7H38.4v2.6l-.2.3-11,9.1a.8.8,0,0,0-.2.5V39.4c0,.2-.1.3-.3.2l-5.7-3c-.1,0-.1-.1-.1-.2V27.2a.8.8,0,0,0-.2-.5L9.8,17.5c-.1,0-.2-.1-.2-.3Z"/><path fill="#fff" d="M38.4,9.7V13H9.6V9.7a.4.4,0,0,1,.4-.4H38A.4.4,0,0,1,38.4,9.7Z"/><path fill="#1d1d1b" d="M9.6,14.7H38.4v2.6l-.2.3-11,9.1a.8.8,0,0,0-.2.5V39.4c0,.2-.1.3-.3.2l-5.7-3c-.1,0-.1-.1-.1-.2V27.2a.8.8,0,0,0-.2-.5L9.8,17.5c-.1,0-.2-.1-.2-.3Z"/><path fill="#1d1d1b" d="M38.4,9.7V13H9.6V9.7a.4.4,0,0,1,.4-.4H38A.4.4,0,0,1,38.4,9.7Z"/></g></g></svg>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" id="svg10" width="72" height="72" version="1.1" viewBox="0 0 108 108"><metadata id="metadata16"/><title id="title2">deactive Folgen</title><g id="Ebene_2" data-name="Ebene 2" transform="matrix(2.25,0,0,2.25,-0.10663006,-0.01748344)"><g id="Ebene_1-2" data-name="Ebene 1"><rect id="rect4" width="48" height="48" x="0" y="0" fill="none" rx="2.8"/><path id="path6" fill="#1d1d1b" d="M 25.7,39.1 23.6,24 8.5,21.9 c -0.1,-0.1 -0.1,-0.2 0,-0.2 l 29.3,-12 c 0.1,-0.1 0.2,0 0.1,0.1 l -12,29.3 c 0,0.1 -0.2,0.1 -0.2,0 z"/></g></g></svg>
|