@opentripplanner/vehicle-rental-overlay 1.3.1 → 1.3.2

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/esm/index.js CHANGED
@@ -27,16 +27,12 @@ var VehicleRentalOverlay = /*#__PURE__*/function (_MapLayer) {
27
27
 
28
28
  var _super = _createSuper(VehicleRentalOverlay);
29
29
 
30
- function VehicleRentalOverlay() {
30
+ function VehicleRentalOverlay(props) {
31
31
  var _this;
32
32
 
33
33
  _classCallCheck(this, VehicleRentalOverlay);
34
34
 
35
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
36
- args[_key] = arguments[_key];
37
- }
38
-
39
- _this = _super.call.apply(_super, [this].concat(args));
35
+ _this = _super.call(this, props);
40
36
 
41
37
  _this.renderSymbolWithPopup = function (_Symbol) {
42
38
  var SymbolWrapper = function SymbolWrapper(_ref) {
@@ -85,6 +81,24 @@ var VehicleRentalOverlay = /*#__PURE__*/function (_MapLayer) {
85
81
  });
86
82
  };
87
83
 
84
+ _this.onOverlayAdded = function () {
85
+ _this.startRefreshing();
86
+ };
87
+
88
+ _this.onOverlayRemoved = function () {
89
+ _this.stopRefreshing();
90
+ };
91
+
92
+ _this.onViewportChanged = function (viewport) {
93
+ var newZoom = viewport.zoom;
94
+
95
+ if (_this.state.zoom !== newZoom) {
96
+ _this.setState({
97
+ zoom: newZoom
98
+ });
99
+ }
100
+ };
101
+
88
102
  _this.renderPopupForStation = function (station) {
89
103
  var stationIsHub = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
90
104
  var _this$props = _this.props,
@@ -103,8 +117,17 @@ var VehicleRentalOverlay = /*#__PURE__*/function (_MapLayer) {
103
117
  }))));
104
118
  };
105
119
 
120
+ _this.state = {
121
+ zoom: props.leaflet.map.getZoom()
122
+ };
106
123
  return _this;
107
124
  }
125
+ /**
126
+ * This helper method will be passed to the ZoomBasedMarkers symbolTransform prop.
127
+ * It creates a component that inserts a popup
128
+ * as a child of the specified symbol from the mapSymbols prop.
129
+ */
130
+
108
131
 
109
132
  _createClass(VehicleRentalOverlay, [{
110
133
  key: "createLeafletElement",
@@ -131,26 +154,34 @@ var VehicleRentalOverlay = /*#__PURE__*/function (_MapLayer) {
131
154
  value: function stopRefreshing() {
132
155
  if (this.refreshTimer) clearInterval(this.refreshTimer);
133
156
  }
157
+ /**
158
+ * When the layer is added (or toggled on, or its visibility becomes true),
159
+ * start refreshing vehicle positions.
160
+ */
161
+
134
162
  }, {
135
163
  key: "componentDidMount",
136
- value: function componentDidMount() {
137
- var visible = this.props.visible;
164
+ value:
165
+ /**
166
+ * Upon mounting, see whether the vehicles should be fetched,
167
+ * and also call the register overlay prop that the
168
+ * @opentripplanner/base-map package has injected to listen to zoom/position changes.
169
+ */
170
+ function componentDidMount() {
171
+ var _this$props2 = this.props,
172
+ registerOverlay = _this$props2.registerOverlay,
173
+ visible = _this$props2.visible;
138
174
  if (visible) this.startRefreshing();
175
+
176
+ if (typeof registerOverlay === "function") {
177
+ registerOverlay(this);
178
+ }
139
179
  }
140
180
  }, {
141
181
  key: "componentWillUnmount",
142
182
  value: function componentWillUnmount() {
143
183
  this.stopRefreshing();
144
184
  }
145
- }, {
146
- key: "componentDidUpdate",
147
- value: function componentDidUpdate(prevProps) {
148
- if (!prevProps.visible && this.props.visible) {
149
- this.startRefreshing();
150
- } else if (prevProps.visible && !this.props.visible) {
151
- this.stopRefreshing();
152
- }
153
- }
154
185
  /**
155
186
  * Render some popup html for a station. This contains custom logic for
156
187
  * displaying rental vehicles in the TriMet MOD website that might not be
@@ -160,19 +191,15 @@ var VehicleRentalOverlay = /*#__PURE__*/function (_MapLayer) {
160
191
  }, {
161
192
  key: "render",
162
193
  value: function render() {
163
- var _this$props2 = this.props,
164
- companies = _this$props2.companies,
165
- mapSymbols = _this$props2.mapSymbols,
166
- stations = _this$props2.stations,
167
- visible = _this$props2.visible; // Render an empty FeatureGroup if the rental vehicles should not be visible
194
+ var _this$props3 = this.props,
195
+ companies = _this$props3.companies,
196
+ mapSymbols = _this$props3.mapSymbols,
197
+ stations = _this$props3.stations;
198
+ var zoom = this.state.zoom; // Render an empty FeatureGroup if the rental vehicles should not be visible
168
199
  // on the map. Otherwise previous stations may still be shown due to some
169
200
  // react-leaflet internals, maybe? Also, do not return null because that will
170
201
  // prevent the overlay from appearing in the layer controls.
171
202
 
172
- if (!visible) {
173
- return /*#__PURE__*/React.createElement(FeatureGroup, null);
174
- }
175
-
176
203
  var filteredStations = stations;
177
204
 
178
205
  if (companies) {
@@ -185,10 +212,8 @@ var VehicleRentalOverlay = /*#__PURE__*/function (_MapLayer) {
185
212
 
186
213
  if (!filteredStations || filteredStations.length === 0) {
187
214
  return /*#__PURE__*/React.createElement(FeatureGroup, null);
188
- } // get zoom to check which symbol to render
189
-
215
+ } // Convert map symbols for this overlay to zoomBasedSymbolType.
190
216
 
191
- var zoom = this.props.leaflet.map.getZoom(); // Convert map symbols for this overlay to zoomBasedSymbolType.
192
217
 
193
218
  var symbols = this.convertToZoomMarkerSymbols(mapSymbols);
194
219
  return /*#__PURE__*/React.createElement(FeatureGroup, null, /*#__PURE__*/React.createElement(ZoomBasedMarkers, {
package/esm/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.js"],"names":["Styled","BaseMapStyled","coreUtils","FromToLocationPicker","ZoomBasedMarkers","PropTypes","React","FeatureGroup","MapLayer","Popup","withLeaflet","GenericMarker","HubAndFloatingBike","SharedBikeCircle","VehicleRentalOverlay","renderSymbolWithPopup","Symbol","SymbolWrapper","station","entity","zoom","renderPopupForStation","bikesAvailable","undefined","isFloatingBike","propTypes","types","stationType","isRequired","number","convertToZoomMarkerSymbols","mapSymbols","map","mapSymbol","symbol","type","minZoom","stationIsHub","props","configCompanies","getStationName","setLocation","stationName","location","lat","y","lon","x","name","spacesAvailable","refreshVehicles","refreshTimer","setInterval","clearInterval","visible","startRefreshing","stopRefreshing","prevProps","companies","stations","filteredStations","filter","networks","value","includes","length","leaflet","getZoom","symbols","arrayOf","companyType","string","func","vehicleRentalMapOverlaySymbolsType","bool","defaultProps","stationNetworks","itinerary","getCompaniesLabelFromNetworks","id","isFloatingCar","isFloatingVehicle"],"mappings":"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","sourcesContent":["import { Styled as BaseMapStyled } from \"@opentripplanner/base-map\";\nimport coreUtils from \"@opentripplanner/core-utils\";\nimport FromToLocationPicker from \"@opentripplanner/from-to-location-picker\";\nimport ZoomBasedMarkers from \"@opentripplanner/zoom-based-markers\";\nimport PropTypes from \"prop-types\";\nimport React from \"react\";\nimport { FeatureGroup, MapLayer, Popup, withLeaflet } from \"react-leaflet\";\n\nimport {\n GenericMarker,\n HubAndFloatingBike,\n SharedBikeCircle\n} from \"./DefaultMarkers\";\n\n/**\n * This vehicle rental overlay can be used to render vehicle rentals of various\n * types. This layer can be configured to show different styles of markers at\n * different zoom levels.\n */\nclass VehicleRentalOverlay extends MapLayer {\n /**\n * This helper method will be passed to the ZoomBasedMarkers symbolTransform prop.\n * It creates a component that inserts a popup\n * as a child of the specified symbol from the mapSymbols prop.\n */\n renderSymbolWithPopup = Symbol => {\n const SymbolWrapper = ({ entity: station, zoom }) => (\n <Symbol entity={station} zoom={zoom}>\n {this.renderPopupForStation(\n station,\n station.bikesAvailable !== undefined && !station.isFloatingBike\n )}\n </Symbol>\n );\n SymbolWrapper.propTypes = {\n entity: coreUtils.types.stationType.isRequired,\n zoom: PropTypes.number.isRequired\n };\n\n return SymbolWrapper;\n };\n\n /**\n * Convert map symbols to zoomBasedSymbolType.\n */\n convertToZoomMarkerSymbols = mapSymbols =>\n mapSymbols.map(mapSymbol => {\n // If mapSymbol uses zoomBasedSymbolType, use it as is.\n if (mapSymbol.symbol) {\n return mapSymbol;\n }\n\n // Otherwise, convert into zoomBasedType (no support for symbols by type).\n let symbol;\n switch (mapSymbol.type) {\n case \"circle\":\n symbol = SharedBikeCircle(mapSymbol);\n break;\n case \"hubAndFloatingBike\":\n symbol = HubAndFloatingBike;\n break;\n default:\n symbol = GenericMarker(mapSymbol);\n }\n\n return {\n minZoom: mapSymbol.minZoom,\n symbol\n };\n });\n\n createLeafletElement() {}\n\n updateLeafletElement() {}\n\n startRefreshing() {\n const { refreshVehicles } = this.props;\n\n // Create the timer only if refreshVehicles is a valid function.\n if (typeof refreshVehicles === \"function\") {\n // initial station retrieval\n refreshVehicles();\n\n // set up timer to refresh stations periodically\n this.refreshTimer = setInterval(() => {\n refreshVehicles();\n }, 30000); // defaults to every 30 sec. TODO: make this configurable?\n }\n }\n\n stopRefreshing() {\n if (this.refreshTimer) clearInterval(this.refreshTimer);\n }\n\n componentDidMount() {\n const { visible } = this.props;\n if (visible) this.startRefreshing();\n }\n\n componentWillUnmount() {\n this.stopRefreshing();\n }\n\n componentDidUpdate(prevProps) {\n if (!prevProps.visible && this.props.visible) {\n this.startRefreshing();\n } else if (prevProps.visible && !this.props.visible) {\n this.stopRefreshing();\n }\n }\n\n /**\n * Render some popup html for a station. This contains custom logic for\n * displaying rental vehicles in the TriMet MOD website that might not be\n * applicable to other regions.\n */\n renderPopupForStation = (station, stationIsHub = false) => {\n const { configCompanies, getStationName, setLocation } = this.props;\n const stationName = getStationName(configCompanies, station);\n const location = {\n lat: station.y,\n lon: station.x,\n name: stationName\n };\n return (\n <Popup>\n <BaseMapStyled.MapOverlayPopup>\n <BaseMapStyled.PopupTitle>{stationName}</BaseMapStyled.PopupTitle>\n\n {/* render dock info if it is available */}\n {stationIsHub && (\n <BaseMapStyled.PopupRow>\n <div>Available bikes: {station.bikesAvailable}</div>\n <div>Available docks: {station.spacesAvailable}</div>\n </BaseMapStyled.PopupRow>\n )}\n\n {/* Set as from/to toolbar */}\n <BaseMapStyled.PopupRow>\n <b>Plan a trip:</b>\n <FromToLocationPicker\n location={location}\n setLocation={setLocation}\n />\n </BaseMapStyled.PopupRow>\n </BaseMapStyled.MapOverlayPopup>\n </Popup>\n );\n };\n\n render() {\n const { companies, mapSymbols, stations, visible } = this.props;\n // Render an empty FeatureGroup if the rental vehicles should not be visible\n // on the map. Otherwise previous stations may still be shown due to some\n // react-leaflet internals, maybe? Also, do not return null because that will\n // prevent the overlay from appearing in the layer controls.\n if (!visible) {\n return <FeatureGroup />;\n }\n\n let filteredStations = stations;\n if (companies) {\n filteredStations = stations.filter(\n station =>\n station.networks.filter(value => companies.includes(value)).length > 0\n );\n }\n\n if (!filteredStations || filteredStations.length === 0) {\n return <FeatureGroup />;\n }\n\n // get zoom to check which symbol to render\n const zoom = this.props.leaflet.map.getZoom();\n\n // Convert map symbols for this overlay to zoomBasedSymbolType.\n const symbols = this.convertToZoomMarkerSymbols(mapSymbols);\n\n return (\n <FeatureGroup>\n <ZoomBasedMarkers\n entities={filteredStations}\n symbols={symbols}\n symbolTransform={this.renderSymbolWithPopup}\n zoom={zoom}\n />\n </FeatureGroup>\n );\n }\n}\n\nVehicleRentalOverlay.props = {\n /**\n * The entire companies config array.\n */\n configCompanies: PropTypes.arrayOf(coreUtils.types.companyType.isRequired)\n .isRequired,\n /**\n * A list of companies that are applicable to just this instance of the\n * overlay.\n */\n companies: PropTypes.arrayOf(PropTypes.string.isRequired),\n /**\n * An optional custom function to create a string name of a particular vehicle\n * rental station. This function takes two arguments of the configCompanies\n * prop and a vehicle rental station. The function must return a string.\n */\n getStationName: PropTypes.func,\n /**\n * A configuration of what map markers or symbols to show at various\n * zoom levels.\n */\n mapSymbols: coreUtils.types.vehicleRentalMapOverlaySymbolsType,\n /**\n * If specified, a function that will be triggered every 30 seconds whenever this layer is\n * visible.\n */\n refreshVehicles: PropTypes.func,\n /**\n * A callback for when a user clicks on setting this stop as either the from\n * or to location of a new search.\n *\n * This will be dispatched with the following argument:\n *\n * ```js\n * {\n * location: {\n * lat: number,\n * lon: number,\n * name: string\n * },\n * locationType: \"from\" or \"to\"\n * }\n * ```\n */\n setLocation: PropTypes.func.isRequired,\n /**\n * A list of the vehicle rental stations specific to this overlay instance.\n */\n stations: PropTypes.arrayOf(coreUtils.types.stationType),\n /**\n * Whether the overlay is currently visible.\n */\n visible: PropTypes.bool\n};\n\nVehicleRentalOverlay.defaultProps = {\n getStationName: (configCompanies, station) => {\n const stationNetworks = coreUtils.itinerary.getCompaniesLabelFromNetworks(\n station.networks,\n configCompanies\n );\n let stationName = station.name || station.id;\n if (station.isFloatingBike) {\n stationName = `Free-floating bike: ${stationName}`;\n } else if (station.isFloatingCar) {\n stationName = `${stationNetworks} ${stationName}`;\n } else if (station.isFloatingVehicle) {\n // assumes that all floating vehicles are E-scooters\n stationName = `${stationNetworks} E-scooter`;\n }\n return stationName;\n },\n mapSymbols: [\n {\n zoom: 0,\n symbol: GenericMarker\n }\n ],\n refreshVehicles: null,\n stations: [],\n visible: false\n};\n\nexport default withLeaflet(VehicleRentalOverlay);\n"],"file":"index.js"}
1
+ {"version":3,"sources":["../src/index.js"],"names":["Styled","BaseMapStyled","coreUtils","FromToLocationPicker","ZoomBasedMarkers","PropTypes","React","FeatureGroup","MapLayer","Popup","withLeaflet","GenericMarker","HubAndFloatingBike","SharedBikeCircle","VehicleRentalOverlay","props","renderSymbolWithPopup","Symbol","SymbolWrapper","station","entity","zoom","renderPopupForStation","bikesAvailable","undefined","isFloatingBike","propTypes","types","stationType","isRequired","number","convertToZoomMarkerSymbols","mapSymbols","map","mapSymbol","symbol","type","minZoom","onOverlayAdded","startRefreshing","onOverlayRemoved","stopRefreshing","onViewportChanged","viewport","newZoom","state","setState","stationIsHub","configCompanies","getStationName","setLocation","stationName","location","lat","y","lon","x","name","spacesAvailable","leaflet","getZoom","refreshVehicles","refreshTimer","setInterval","clearInterval","registerOverlay","visible","companies","stations","filteredStations","filter","networks","value","includes","length","symbols","arrayOf","companyType","string","func","vehicleRentalMapOverlaySymbolsType","bool","defaultProps","stationNetworks","itinerary","getCompaniesLabelFromNetworks","id","isFloatingCar","isFloatingVehicle"],"mappings":"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","sourcesContent":["import { Styled as BaseMapStyled } from \"@opentripplanner/base-map\";\nimport coreUtils from \"@opentripplanner/core-utils\";\nimport FromToLocationPicker from \"@opentripplanner/from-to-location-picker\";\nimport ZoomBasedMarkers from \"@opentripplanner/zoom-based-markers\";\nimport PropTypes from \"prop-types\";\nimport React from \"react\";\nimport { FeatureGroup, MapLayer, Popup, withLeaflet } from \"react-leaflet\";\n\nimport {\n GenericMarker,\n HubAndFloatingBike,\n SharedBikeCircle\n} from \"./DefaultMarkers\";\n\n/**\n * This vehicle rental overlay can be used to render vehicle rentals of various\n * types. This layer can be configured to show different styles of markers at\n * different zoom levels.\n */\nclass VehicleRentalOverlay extends MapLayer {\n constructor(props) {\n super(props);\n this.state = {\n zoom: props.leaflet.map.getZoom()\n };\n }\n\n /**\n * This helper method will be passed to the ZoomBasedMarkers symbolTransform prop.\n * It creates a component that inserts a popup\n * as a child of the specified symbol from the mapSymbols prop.\n */\n renderSymbolWithPopup = Symbol => {\n const SymbolWrapper = ({ entity: station, zoom }) => (\n <Symbol entity={station} zoom={zoom}>\n {this.renderPopupForStation(\n station,\n station.bikesAvailable !== undefined && !station.isFloatingBike\n )}\n </Symbol>\n );\n SymbolWrapper.propTypes = {\n entity: coreUtils.types.stationType.isRequired,\n zoom: PropTypes.number.isRequired\n };\n\n return SymbolWrapper;\n };\n\n /**\n * Convert map symbols to zoomBasedSymbolType.\n */\n convertToZoomMarkerSymbols = mapSymbols =>\n mapSymbols.map(mapSymbol => {\n // If mapSymbol uses zoomBasedSymbolType, use it as is.\n if (mapSymbol.symbol) {\n return mapSymbol;\n }\n\n // Otherwise, convert into zoomBasedType (no support for symbols by type).\n let symbol;\n switch (mapSymbol.type) {\n case \"circle\":\n symbol = SharedBikeCircle(mapSymbol);\n break;\n case \"hubAndFloatingBike\":\n symbol = HubAndFloatingBike;\n break;\n default:\n symbol = GenericMarker(mapSymbol);\n }\n\n return {\n minZoom: mapSymbol.minZoom,\n symbol\n };\n });\n\n createLeafletElement() {}\n\n updateLeafletElement() {}\n\n startRefreshing() {\n const { refreshVehicles } = this.props;\n\n // Create the timer only if refreshVehicles is a valid function.\n if (typeof refreshVehicles === \"function\") {\n // initial station retrieval\n refreshVehicles();\n\n // set up timer to refresh stations periodically\n this.refreshTimer = setInterval(() => {\n refreshVehicles();\n }, 30000); // defaults to every 30 sec. TODO: make this configurable?\n }\n }\n\n stopRefreshing() {\n if (this.refreshTimer) clearInterval(this.refreshTimer);\n }\n\n /**\n * When the layer is added (or toggled on, or its visibility becomes true),\n * start refreshing vehicle positions.\n */\n onOverlayAdded = () => {\n this.startRefreshing();\n };\n\n /**\n * When the layer is removed (or toggled off, or its visibility becomes false),\n * stop refreshing vehicle positions.\n */\n onOverlayRemoved = () => {\n this.stopRefreshing();\n };\n\n /**\n * Listen to changes on the BaseMap's center or zoom.\n * @param viewport The viewport data. See https://github.com/PaulLeCam/react-leaflet/blob/master/example/components/viewport.js for details.\n */\n onViewportChanged = viewport => {\n const { zoom: newZoom } = viewport;\n if (this.state.zoom !== newZoom) {\n this.setState({ zoom: newZoom });\n }\n };\n\n /**\n * Upon mounting, see whether the vehicles should be fetched,\n * and also call the register overlay prop that the\n * @opentripplanner/base-map package has injected to listen to zoom/position changes.\n */\n componentDidMount() {\n const { registerOverlay, visible } = this.props;\n if (visible) this.startRefreshing();\n if (typeof registerOverlay === \"function\") {\n registerOverlay(this);\n }\n }\n\n componentWillUnmount() {\n this.stopRefreshing();\n }\n\n /**\n * Render some popup html for a station. This contains custom logic for\n * displaying rental vehicles in the TriMet MOD website that might not be\n * applicable to other regions.\n */\n renderPopupForStation = (station, stationIsHub = false) => {\n const { configCompanies, getStationName, setLocation } = this.props;\n const stationName = getStationName(configCompanies, station);\n const location = {\n lat: station.y,\n lon: station.x,\n name: stationName\n };\n return (\n <Popup>\n <BaseMapStyled.MapOverlayPopup>\n <BaseMapStyled.PopupTitle>{stationName}</BaseMapStyled.PopupTitle>\n\n {/* render dock info if it is available */}\n {stationIsHub && (\n <BaseMapStyled.PopupRow>\n <div>Available bikes: {station.bikesAvailable}</div>\n <div>Available docks: {station.spacesAvailable}</div>\n </BaseMapStyled.PopupRow>\n )}\n\n {/* Set as from/to toolbar */}\n <BaseMapStyled.PopupRow>\n <b>Plan a trip:</b>\n <FromToLocationPicker\n location={location}\n setLocation={setLocation}\n />\n </BaseMapStyled.PopupRow>\n </BaseMapStyled.MapOverlayPopup>\n </Popup>\n );\n };\n\n render() {\n const { companies, mapSymbols, stations } = this.props;\n const { zoom } = this.state;\n // Render an empty FeatureGroup if the rental vehicles should not be visible\n // on the map. Otherwise previous stations may still be shown due to some\n // react-leaflet internals, maybe? Also, do not return null because that will\n // prevent the overlay from appearing in the layer controls.\n\n let filteredStations = stations;\n if (companies) {\n filteredStations = stations.filter(\n station =>\n station.networks.filter(value => companies.includes(value)).length > 0\n );\n }\n\n if (!filteredStations || filteredStations.length === 0) {\n return <FeatureGroup />;\n }\n\n // Convert map symbols for this overlay to zoomBasedSymbolType.\n const symbols = this.convertToZoomMarkerSymbols(mapSymbols);\n\n return (\n <FeatureGroup>\n <ZoomBasedMarkers\n entities={filteredStations}\n symbols={symbols}\n symbolTransform={this.renderSymbolWithPopup}\n zoom={zoom}\n />\n </FeatureGroup>\n );\n }\n}\n\nVehicleRentalOverlay.props = {\n /**\n * The entire companies config array.\n */\n configCompanies: PropTypes.arrayOf(coreUtils.types.companyType.isRequired)\n .isRequired,\n /**\n * A list of companies that are applicable to just this instance of the\n * overlay.\n */\n companies: PropTypes.arrayOf(PropTypes.string.isRequired),\n /**\n * An optional custom function to create a string name of a particular vehicle\n * rental station. This function takes two arguments of the configCompanies\n * prop and a vehicle rental station. The function must return a string.\n */\n getStationName: PropTypes.func,\n /**\n * A configuration of what map markers or symbols to show at various\n * zoom levels.\n */\n mapSymbols: coreUtils.types.vehicleRentalMapOverlaySymbolsType,\n /**\n * If specified, a function that will be triggered every 30 seconds whenever this layer is\n * visible.\n */\n refreshVehicles: PropTypes.func,\n /**\n * A callback for when a user clicks on setting this stop as either the from\n * or to location of a new search.\n *\n * This will be dispatched with the following argument:\n *\n * ```js\n * {\n * location: {\n * lat: number,\n * lon: number,\n * name: string\n * },\n * locationType: \"from\" or \"to\"\n * }\n * ```\n */\n setLocation: PropTypes.func.isRequired,\n /**\n * A list of the vehicle rental stations specific to this overlay instance.\n */\n stations: PropTypes.arrayOf(coreUtils.types.stationType),\n /**\n * Whether the overlay is currently visible.\n */\n visible: PropTypes.bool\n};\n\nVehicleRentalOverlay.defaultProps = {\n getStationName: (configCompanies, station) => {\n const stationNetworks = coreUtils.itinerary.getCompaniesLabelFromNetworks(\n station.networks,\n configCompanies\n );\n let stationName = station.name || station.id;\n if (station.isFloatingBike) {\n stationName = `Free-floating bike: ${stationName}`;\n } else if (station.isFloatingCar) {\n stationName = `${stationNetworks} ${stationName}`;\n } else if (station.isFloatingVehicle) {\n // assumes that all floating vehicles are E-scooters\n stationName = `${stationNetworks} E-scooter`;\n }\n return stationName;\n },\n mapSymbols: [\n {\n zoom: 0,\n symbol: GenericMarker\n }\n ],\n refreshVehicles: null,\n stations: [],\n visible: false\n};\n\nexport default withLeaflet(VehicleRentalOverlay);\n"],"file":"index.js"}
package/lib/index.js CHANGED
@@ -29,8 +29,8 @@ var _DefaultMarkers = require("./DefaultMarkers");
29
29
  * different zoom levels.
30
30
  */
31
31
  class VehicleRentalOverlay extends _reactLeaflet.MapLayer {
32
- constructor(...args) {
33
- super(...args);
32
+ constructor(props) {
33
+ super(props);
34
34
 
35
35
  this.renderSymbolWithPopup = Symbol => {
36
36
  const SymbolWrapper = ({
@@ -76,6 +76,26 @@ class VehicleRentalOverlay extends _reactLeaflet.MapLayer {
76
76
  };
77
77
  });
78
78
 
79
+ this.onOverlayAdded = () => {
80
+ this.startRefreshing();
81
+ };
82
+
83
+ this.onOverlayRemoved = () => {
84
+ this.stopRefreshing();
85
+ };
86
+
87
+ this.onViewportChanged = viewport => {
88
+ const {
89
+ zoom: newZoom
90
+ } = viewport;
91
+
92
+ if (this.state.zoom !== newZoom) {
93
+ this.setState({
94
+ zoom: newZoom
95
+ });
96
+ }
97
+ };
98
+
79
99
  this.renderPopupForStation = (station, stationIsHub = false) => {
80
100
  const {
81
101
  configCompanies,
@@ -93,7 +113,17 @@ class VehicleRentalOverlay extends _reactLeaflet.MapLayer {
93
113
  setLocation: setLocation
94
114
  }))));
95
115
  };
116
+
117
+ this.state = {
118
+ zoom: props.leaflet.map.getZoom()
119
+ };
96
120
  }
121
+ /**
122
+ * This helper method will be passed to the ZoomBasedMarkers symbolTransform prop.
123
+ * It creates a component that inserts a popup
124
+ * as a child of the specified symbol from the mapSymbols prop.
125
+ */
126
+
97
127
 
98
128
  createLeafletElement() {}
99
129
 
@@ -117,25 +147,32 @@ class VehicleRentalOverlay extends _reactLeaflet.MapLayer {
117
147
  stopRefreshing() {
118
148
  if (this.refreshTimer) clearInterval(this.refreshTimer);
119
149
  }
150
+ /**
151
+ * When the layer is added (or toggled on, or its visibility becomes true),
152
+ * start refreshing vehicle positions.
153
+ */
120
154
 
155
+
156
+ /**
157
+ * Upon mounting, see whether the vehicles should be fetched,
158
+ * and also call the register overlay prop that the
159
+ * @opentripplanner/base-map package has injected to listen to zoom/position changes.
160
+ */
121
161
  componentDidMount() {
122
162
  const {
163
+ registerOverlay,
123
164
  visible
124
165
  } = this.props;
125
166
  if (visible) this.startRefreshing();
167
+
168
+ if (typeof registerOverlay === "function") {
169
+ registerOverlay(this);
170
+ }
126
171
  }
127
172
 
128
173
  componentWillUnmount() {
129
174
  this.stopRefreshing();
130
175
  }
131
-
132
- componentDidUpdate(prevProps) {
133
- if (!prevProps.visible && this.props.visible) {
134
- this.startRefreshing();
135
- } else if (prevProps.visible && !this.props.visible) {
136
- this.stopRefreshing();
137
- }
138
- }
139
176
  /**
140
177
  * Render some popup html for a station. This contains custom logic for
141
178
  * displaying rental vehicles in the TriMet MOD website that might not be
@@ -147,17 +184,15 @@ class VehicleRentalOverlay extends _reactLeaflet.MapLayer {
147
184
  const {
148
185
  companies,
149
186
  mapSymbols,
150
- stations,
151
- visible
152
- } = this.props; // Render an empty FeatureGroup if the rental vehicles should not be visible
187
+ stations
188
+ } = this.props;
189
+ const {
190
+ zoom
191
+ } = this.state; // Render an empty FeatureGroup if the rental vehicles should not be visible
153
192
  // on the map. Otherwise previous stations may still be shown due to some
154
193
  // react-leaflet internals, maybe? Also, do not return null because that will
155
194
  // prevent the overlay from appearing in the layer controls.
156
195
 
157
- if (!visible) {
158
- return /*#__PURE__*/_react.default.createElement(_reactLeaflet.FeatureGroup, null);
159
- }
160
-
161
196
  let filteredStations = stations;
162
197
 
163
198
  if (companies) {
@@ -166,10 +201,8 @@ class VehicleRentalOverlay extends _reactLeaflet.MapLayer {
166
201
 
167
202
  if (!filteredStations || filteredStations.length === 0) {
168
203
  return /*#__PURE__*/_react.default.createElement(_reactLeaflet.FeatureGroup, null);
169
- } // get zoom to check which symbol to render
170
-
204
+ } // Convert map symbols for this overlay to zoomBasedSymbolType.
171
205
 
172
- const zoom = this.props.leaflet.map.getZoom(); // Convert map symbols for this overlay to zoomBasedSymbolType.
173
206
 
174
207
  const symbols = this.convertToZoomMarkerSymbols(mapSymbols);
175
208
  return /*#__PURE__*/_react.default.createElement(_reactLeaflet.FeatureGroup, null, /*#__PURE__*/_react.default.createElement(_zoomBasedMarkers.default, {
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.js"],"names":["VehicleRentalOverlay","MapLayer","renderSymbolWithPopup","Symbol","SymbolWrapper","entity","station","zoom","renderPopupForStation","bikesAvailable","undefined","isFloatingBike","propTypes","coreUtils","types","stationType","isRequired","PropTypes","number","convertToZoomMarkerSymbols","mapSymbols","map","mapSymbol","symbol","type","HubAndFloatingBike","minZoom","stationIsHub","configCompanies","getStationName","setLocation","props","stationName","location","lat","y","lon","x","name","spacesAvailable","createLeafletElement","updateLeafletElement","startRefreshing","refreshVehicles","refreshTimer","setInterval","stopRefreshing","clearInterval","componentDidMount","visible","componentWillUnmount","componentDidUpdate","prevProps","render","companies","stations","filteredStations","filter","networks","value","includes","length","leaflet","getZoom","symbols","arrayOf","companyType","string","func","vehicleRentalMapOverlaySymbolsType","bool","defaultProps","stationNetworks","itinerary","getCompaniesLabelFromNetworks","id","isFloatingCar","isFloatingVehicle","GenericMarker"],"mappings":"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","sourcesContent":["import { Styled as BaseMapStyled } from \"@opentripplanner/base-map\";\nimport coreUtils from \"@opentripplanner/core-utils\";\nimport FromToLocationPicker from \"@opentripplanner/from-to-location-picker\";\nimport ZoomBasedMarkers from \"@opentripplanner/zoom-based-markers\";\nimport PropTypes from \"prop-types\";\nimport React from \"react\";\nimport { FeatureGroup, MapLayer, Popup, withLeaflet } from \"react-leaflet\";\n\nimport {\n GenericMarker,\n HubAndFloatingBike,\n SharedBikeCircle\n} from \"./DefaultMarkers\";\n\n/**\n * This vehicle rental overlay can be used to render vehicle rentals of various\n * types. This layer can be configured to show different styles of markers at\n * different zoom levels.\n */\nclass VehicleRentalOverlay extends MapLayer {\n /**\n * This helper method will be passed to the ZoomBasedMarkers symbolTransform prop.\n * It creates a component that inserts a popup\n * as a child of the specified symbol from the mapSymbols prop.\n */\n renderSymbolWithPopup = Symbol => {\n const SymbolWrapper = ({ entity: station, zoom }) => (\n <Symbol entity={station} zoom={zoom}>\n {this.renderPopupForStation(\n station,\n station.bikesAvailable !== undefined && !station.isFloatingBike\n )}\n </Symbol>\n );\n SymbolWrapper.propTypes = {\n entity: coreUtils.types.stationType.isRequired,\n zoom: PropTypes.number.isRequired\n };\n\n return SymbolWrapper;\n };\n\n /**\n * Convert map symbols to zoomBasedSymbolType.\n */\n convertToZoomMarkerSymbols = mapSymbols =>\n mapSymbols.map(mapSymbol => {\n // If mapSymbol uses zoomBasedSymbolType, use it as is.\n if (mapSymbol.symbol) {\n return mapSymbol;\n }\n\n // Otherwise, convert into zoomBasedType (no support for symbols by type).\n let symbol;\n switch (mapSymbol.type) {\n case \"circle\":\n symbol = SharedBikeCircle(mapSymbol);\n break;\n case \"hubAndFloatingBike\":\n symbol = HubAndFloatingBike;\n break;\n default:\n symbol = GenericMarker(mapSymbol);\n }\n\n return {\n minZoom: mapSymbol.minZoom,\n symbol\n };\n });\n\n createLeafletElement() {}\n\n updateLeafletElement() {}\n\n startRefreshing() {\n const { refreshVehicles } = this.props;\n\n // Create the timer only if refreshVehicles is a valid function.\n if (typeof refreshVehicles === \"function\") {\n // initial station retrieval\n refreshVehicles();\n\n // set up timer to refresh stations periodically\n this.refreshTimer = setInterval(() => {\n refreshVehicles();\n }, 30000); // defaults to every 30 sec. TODO: make this configurable?\n }\n }\n\n stopRefreshing() {\n if (this.refreshTimer) clearInterval(this.refreshTimer);\n }\n\n componentDidMount() {\n const { visible } = this.props;\n if (visible) this.startRefreshing();\n }\n\n componentWillUnmount() {\n this.stopRefreshing();\n }\n\n componentDidUpdate(prevProps) {\n if (!prevProps.visible && this.props.visible) {\n this.startRefreshing();\n } else if (prevProps.visible && !this.props.visible) {\n this.stopRefreshing();\n }\n }\n\n /**\n * Render some popup html for a station. This contains custom logic for\n * displaying rental vehicles in the TriMet MOD website that might not be\n * applicable to other regions.\n */\n renderPopupForStation = (station, stationIsHub = false) => {\n const { configCompanies, getStationName, setLocation } = this.props;\n const stationName = getStationName(configCompanies, station);\n const location = {\n lat: station.y,\n lon: station.x,\n name: stationName\n };\n return (\n <Popup>\n <BaseMapStyled.MapOverlayPopup>\n <BaseMapStyled.PopupTitle>{stationName}</BaseMapStyled.PopupTitle>\n\n {/* render dock info if it is available */}\n {stationIsHub && (\n <BaseMapStyled.PopupRow>\n <div>Available bikes: {station.bikesAvailable}</div>\n <div>Available docks: {station.spacesAvailable}</div>\n </BaseMapStyled.PopupRow>\n )}\n\n {/* Set as from/to toolbar */}\n <BaseMapStyled.PopupRow>\n <b>Plan a trip:</b>\n <FromToLocationPicker\n location={location}\n setLocation={setLocation}\n />\n </BaseMapStyled.PopupRow>\n </BaseMapStyled.MapOverlayPopup>\n </Popup>\n );\n };\n\n render() {\n const { companies, mapSymbols, stations, visible } = this.props;\n // Render an empty FeatureGroup if the rental vehicles should not be visible\n // on the map. Otherwise previous stations may still be shown due to some\n // react-leaflet internals, maybe? Also, do not return null because that will\n // prevent the overlay from appearing in the layer controls.\n if (!visible) {\n return <FeatureGroup />;\n }\n\n let filteredStations = stations;\n if (companies) {\n filteredStations = stations.filter(\n station =>\n station.networks.filter(value => companies.includes(value)).length > 0\n );\n }\n\n if (!filteredStations || filteredStations.length === 0) {\n return <FeatureGroup />;\n }\n\n // get zoom to check which symbol to render\n const zoom = this.props.leaflet.map.getZoom();\n\n // Convert map symbols for this overlay to zoomBasedSymbolType.\n const symbols = this.convertToZoomMarkerSymbols(mapSymbols);\n\n return (\n <FeatureGroup>\n <ZoomBasedMarkers\n entities={filteredStations}\n symbols={symbols}\n symbolTransform={this.renderSymbolWithPopup}\n zoom={zoom}\n />\n </FeatureGroup>\n );\n }\n}\n\nVehicleRentalOverlay.props = {\n /**\n * The entire companies config array.\n */\n configCompanies: PropTypes.arrayOf(coreUtils.types.companyType.isRequired)\n .isRequired,\n /**\n * A list of companies that are applicable to just this instance of the\n * overlay.\n */\n companies: PropTypes.arrayOf(PropTypes.string.isRequired),\n /**\n * An optional custom function to create a string name of a particular vehicle\n * rental station. This function takes two arguments of the configCompanies\n * prop and a vehicle rental station. The function must return a string.\n */\n getStationName: PropTypes.func,\n /**\n * A configuration of what map markers or symbols to show at various\n * zoom levels.\n */\n mapSymbols: coreUtils.types.vehicleRentalMapOverlaySymbolsType,\n /**\n * If specified, a function that will be triggered every 30 seconds whenever this layer is\n * visible.\n */\n refreshVehicles: PropTypes.func,\n /**\n * A callback for when a user clicks on setting this stop as either the from\n * or to location of a new search.\n *\n * This will be dispatched with the following argument:\n *\n * ```js\n * {\n * location: {\n * lat: number,\n * lon: number,\n * name: string\n * },\n * locationType: \"from\" or \"to\"\n * }\n * ```\n */\n setLocation: PropTypes.func.isRequired,\n /**\n * A list of the vehicle rental stations specific to this overlay instance.\n */\n stations: PropTypes.arrayOf(coreUtils.types.stationType),\n /**\n * Whether the overlay is currently visible.\n */\n visible: PropTypes.bool\n};\n\nVehicleRentalOverlay.defaultProps = {\n getStationName: (configCompanies, station) => {\n const stationNetworks = coreUtils.itinerary.getCompaniesLabelFromNetworks(\n station.networks,\n configCompanies\n );\n let stationName = station.name || station.id;\n if (station.isFloatingBike) {\n stationName = `Free-floating bike: ${stationName}`;\n } else if (station.isFloatingCar) {\n stationName = `${stationNetworks} ${stationName}`;\n } else if (station.isFloatingVehicle) {\n // assumes that all floating vehicles are E-scooters\n stationName = `${stationNetworks} E-scooter`;\n }\n return stationName;\n },\n mapSymbols: [\n {\n zoom: 0,\n symbol: GenericMarker\n }\n ],\n refreshVehicles: null,\n stations: [],\n visible: false\n};\n\nexport default withLeaflet(VehicleRentalOverlay);\n"],"file":"index.js"}
1
+ {"version":3,"sources":["../src/index.js"],"names":["VehicleRentalOverlay","MapLayer","constructor","props","renderSymbolWithPopup","Symbol","SymbolWrapper","entity","station","zoom","renderPopupForStation","bikesAvailable","undefined","isFloatingBike","propTypes","coreUtils","types","stationType","isRequired","PropTypes","number","convertToZoomMarkerSymbols","mapSymbols","map","mapSymbol","symbol","type","HubAndFloatingBike","minZoom","onOverlayAdded","startRefreshing","onOverlayRemoved","stopRefreshing","onViewportChanged","viewport","newZoom","state","setState","stationIsHub","configCompanies","getStationName","setLocation","stationName","location","lat","y","lon","x","name","spacesAvailable","leaflet","getZoom","createLeafletElement","updateLeafletElement","refreshVehicles","refreshTimer","setInterval","clearInterval","componentDidMount","registerOverlay","visible","componentWillUnmount","render","companies","stations","filteredStations","filter","networks","value","includes","length","symbols","arrayOf","companyType","string","func","vehicleRentalMapOverlaySymbolsType","bool","defaultProps","stationNetworks","itinerary","getCompaniesLabelFromNetworks","id","isFloatingCar","isFloatingVehicle","GenericMarker"],"mappings":"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","sourcesContent":["import { Styled as BaseMapStyled } from \"@opentripplanner/base-map\";\nimport coreUtils from \"@opentripplanner/core-utils\";\nimport FromToLocationPicker from \"@opentripplanner/from-to-location-picker\";\nimport ZoomBasedMarkers from \"@opentripplanner/zoom-based-markers\";\nimport PropTypes from \"prop-types\";\nimport React from \"react\";\nimport { FeatureGroup, MapLayer, Popup, withLeaflet } from \"react-leaflet\";\n\nimport {\n GenericMarker,\n HubAndFloatingBike,\n SharedBikeCircle\n} from \"./DefaultMarkers\";\n\n/**\n * This vehicle rental overlay can be used to render vehicle rentals of various\n * types. This layer can be configured to show different styles of markers at\n * different zoom levels.\n */\nclass VehicleRentalOverlay extends MapLayer {\n constructor(props) {\n super(props);\n this.state = {\n zoom: props.leaflet.map.getZoom()\n };\n }\n\n /**\n * This helper method will be passed to the ZoomBasedMarkers symbolTransform prop.\n * It creates a component that inserts a popup\n * as a child of the specified symbol from the mapSymbols prop.\n */\n renderSymbolWithPopup = Symbol => {\n const SymbolWrapper = ({ entity: station, zoom }) => (\n <Symbol entity={station} zoom={zoom}>\n {this.renderPopupForStation(\n station,\n station.bikesAvailable !== undefined && !station.isFloatingBike\n )}\n </Symbol>\n );\n SymbolWrapper.propTypes = {\n entity: coreUtils.types.stationType.isRequired,\n zoom: PropTypes.number.isRequired\n };\n\n return SymbolWrapper;\n };\n\n /**\n * Convert map symbols to zoomBasedSymbolType.\n */\n convertToZoomMarkerSymbols = mapSymbols =>\n mapSymbols.map(mapSymbol => {\n // If mapSymbol uses zoomBasedSymbolType, use it as is.\n if (mapSymbol.symbol) {\n return mapSymbol;\n }\n\n // Otherwise, convert into zoomBasedType (no support for symbols by type).\n let symbol;\n switch (mapSymbol.type) {\n case \"circle\":\n symbol = SharedBikeCircle(mapSymbol);\n break;\n case \"hubAndFloatingBike\":\n symbol = HubAndFloatingBike;\n break;\n default:\n symbol = GenericMarker(mapSymbol);\n }\n\n return {\n minZoom: mapSymbol.minZoom,\n symbol\n };\n });\n\n createLeafletElement() {}\n\n updateLeafletElement() {}\n\n startRefreshing() {\n const { refreshVehicles } = this.props;\n\n // Create the timer only if refreshVehicles is a valid function.\n if (typeof refreshVehicles === \"function\") {\n // initial station retrieval\n refreshVehicles();\n\n // set up timer to refresh stations periodically\n this.refreshTimer = setInterval(() => {\n refreshVehicles();\n }, 30000); // defaults to every 30 sec. TODO: make this configurable?\n }\n }\n\n stopRefreshing() {\n if (this.refreshTimer) clearInterval(this.refreshTimer);\n }\n\n /**\n * When the layer is added (or toggled on, or its visibility becomes true),\n * start refreshing vehicle positions.\n */\n onOverlayAdded = () => {\n this.startRefreshing();\n };\n\n /**\n * When the layer is removed (or toggled off, or its visibility becomes false),\n * stop refreshing vehicle positions.\n */\n onOverlayRemoved = () => {\n this.stopRefreshing();\n };\n\n /**\n * Listen to changes on the BaseMap's center or zoom.\n * @param viewport The viewport data. See https://github.com/PaulLeCam/react-leaflet/blob/master/example/components/viewport.js for details.\n */\n onViewportChanged = viewport => {\n const { zoom: newZoom } = viewport;\n if (this.state.zoom !== newZoom) {\n this.setState({ zoom: newZoom });\n }\n };\n\n /**\n * Upon mounting, see whether the vehicles should be fetched,\n * and also call the register overlay prop that the\n * @opentripplanner/base-map package has injected to listen to zoom/position changes.\n */\n componentDidMount() {\n const { registerOverlay, visible } = this.props;\n if (visible) this.startRefreshing();\n if (typeof registerOverlay === \"function\") {\n registerOverlay(this);\n }\n }\n\n componentWillUnmount() {\n this.stopRefreshing();\n }\n\n /**\n * Render some popup html for a station. This contains custom logic for\n * displaying rental vehicles in the TriMet MOD website that might not be\n * applicable to other regions.\n */\n renderPopupForStation = (station, stationIsHub = false) => {\n const { configCompanies, getStationName, setLocation } = this.props;\n const stationName = getStationName(configCompanies, station);\n const location = {\n lat: station.y,\n lon: station.x,\n name: stationName\n };\n return (\n <Popup>\n <BaseMapStyled.MapOverlayPopup>\n <BaseMapStyled.PopupTitle>{stationName}</BaseMapStyled.PopupTitle>\n\n {/* render dock info if it is available */}\n {stationIsHub && (\n <BaseMapStyled.PopupRow>\n <div>Available bikes: {station.bikesAvailable}</div>\n <div>Available docks: {station.spacesAvailable}</div>\n </BaseMapStyled.PopupRow>\n )}\n\n {/* Set as from/to toolbar */}\n <BaseMapStyled.PopupRow>\n <b>Plan a trip:</b>\n <FromToLocationPicker\n location={location}\n setLocation={setLocation}\n />\n </BaseMapStyled.PopupRow>\n </BaseMapStyled.MapOverlayPopup>\n </Popup>\n );\n };\n\n render() {\n const { companies, mapSymbols, stations } = this.props;\n const { zoom } = this.state;\n // Render an empty FeatureGroup if the rental vehicles should not be visible\n // on the map. Otherwise previous stations may still be shown due to some\n // react-leaflet internals, maybe? Also, do not return null because that will\n // prevent the overlay from appearing in the layer controls.\n\n let filteredStations = stations;\n if (companies) {\n filteredStations = stations.filter(\n station =>\n station.networks.filter(value => companies.includes(value)).length > 0\n );\n }\n\n if (!filteredStations || filteredStations.length === 0) {\n return <FeatureGroup />;\n }\n\n // Convert map symbols for this overlay to zoomBasedSymbolType.\n const symbols = this.convertToZoomMarkerSymbols(mapSymbols);\n\n return (\n <FeatureGroup>\n <ZoomBasedMarkers\n entities={filteredStations}\n symbols={symbols}\n symbolTransform={this.renderSymbolWithPopup}\n zoom={zoom}\n />\n </FeatureGroup>\n );\n }\n}\n\nVehicleRentalOverlay.props = {\n /**\n * The entire companies config array.\n */\n configCompanies: PropTypes.arrayOf(coreUtils.types.companyType.isRequired)\n .isRequired,\n /**\n * A list of companies that are applicable to just this instance of the\n * overlay.\n */\n companies: PropTypes.arrayOf(PropTypes.string.isRequired),\n /**\n * An optional custom function to create a string name of a particular vehicle\n * rental station. This function takes two arguments of the configCompanies\n * prop and a vehicle rental station. The function must return a string.\n */\n getStationName: PropTypes.func,\n /**\n * A configuration of what map markers or symbols to show at various\n * zoom levels.\n */\n mapSymbols: coreUtils.types.vehicleRentalMapOverlaySymbolsType,\n /**\n * If specified, a function that will be triggered every 30 seconds whenever this layer is\n * visible.\n */\n refreshVehicles: PropTypes.func,\n /**\n * A callback for when a user clicks on setting this stop as either the from\n * or to location of a new search.\n *\n * This will be dispatched with the following argument:\n *\n * ```js\n * {\n * location: {\n * lat: number,\n * lon: number,\n * name: string\n * },\n * locationType: \"from\" or \"to\"\n * }\n * ```\n */\n setLocation: PropTypes.func.isRequired,\n /**\n * A list of the vehicle rental stations specific to this overlay instance.\n */\n stations: PropTypes.arrayOf(coreUtils.types.stationType),\n /**\n * Whether the overlay is currently visible.\n */\n visible: PropTypes.bool\n};\n\nVehicleRentalOverlay.defaultProps = {\n getStationName: (configCompanies, station) => {\n const stationNetworks = coreUtils.itinerary.getCompaniesLabelFromNetworks(\n station.networks,\n configCompanies\n );\n let stationName = station.name || station.id;\n if (station.isFloatingBike) {\n stationName = `Free-floating bike: ${stationName}`;\n } else if (station.isFloatingCar) {\n stationName = `${stationNetworks} ${stationName}`;\n } else if (station.isFloatingVehicle) {\n // assumes that all floating vehicles are E-scooters\n stationName = `${stationNetworks} E-scooter`;\n }\n return stationName;\n },\n mapSymbols: [\n {\n zoom: 0,\n symbol: GenericMarker\n }\n ],\n refreshVehicles: null,\n stations: [],\n visible: false\n};\n\nexport default withLeaflet(VehicleRentalOverlay);\n"],"file":"index.js"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opentripplanner/vehicle-rental-overlay",
3
- "version": "1.3.1",
3
+ "version": "1.3.2",
4
4
  "description": "A map overlay to show vehicle rentals from a specific company",
5
5
  "main": "lib/index.js",
6
6
  "module": "esm/index.js",
@@ -1,7 +1,7 @@
1
1
  import BaseMap from "@opentripplanner/base-map";
2
2
  import coreUtils from "@opentripplanner/core-utils";
3
3
  import PropTypes from "prop-types";
4
- import React, { Component } from "react";
4
+ import React from "react";
5
5
  import { CircleMarker } from "react-leaflet";
6
6
  import { action } from "@storybook/addon-actions";
7
7
  import { boolean } from "@storybook/addon-knobs";
@@ -11,7 +11,6 @@ import bikeRentalStations from "../__mocks__/bike-rental-stations.json";
11
11
  import carRentalStations from "../__mocks__/car-rental-stations.json";
12
12
  import eScooterStations from "../__mocks__/e-scooter-rental-stations.json";
13
13
  import { HubAndFloatingBike } from "./DefaultMarkers";
14
- import LeafletLayerControlInterface from "./leaflet-layer-control-interface";
15
14
 
16
15
  import "../../../node_modules/leaflet/dist/leaflet.css";
17
16
 
@@ -165,51 +164,32 @@ const EScooterMapSymbols = [
165
164
  ];
166
165
  const setLocation = action("setLocation");
167
166
 
168
- class ZoomControlledMapWithVehicleRentalOverlay extends Component {
169
- constructor() {
170
- super();
171
- this.state = { zoom: 13 };
172
- }
173
-
174
- onViewportChanged = ({ zoom }) => {
175
- const { zoom: stateZoom } = this.state;
176
- if (zoom !== stateZoom) {
177
- this.setState({ zoom });
178
- }
179
- };
167
+ const INITIAL_ZOOM = 13;
180
168
 
181
- render() {
182
- const {
183
- companies,
184
- getStationName,
185
- mapSymbols,
186
- refreshVehicles,
187
- stations,
188
- visible
189
- } = this.props;
190
- const { zoom } = this.state;
191
- return (
192
- <BaseMap
193
- center={center}
194
- onViewportChanged={this.onViewportChanged}
195
- zoom={zoom}
196
- >
197
- <LeafletLayerControlInterface
198
- configCompanies={configCompanies}
199
- companies={companies}
200
- getStationName={getStationName}
201
- setLocation={setLocation}
202
- mapSymbols={mapSymbols}
203
- name="Rentals"
204
- refreshVehicles={refreshVehicles}
205
- stations={stations}
206
- visible={visible}
207
- zoom={zoom}
208
- />
209
- </BaseMap>
210
- );
211
- }
212
- }
169
+ const ZoomControlledMapWithVehicleRentalOverlay = ({
170
+ companies,
171
+ getStationName,
172
+ mapSymbols,
173
+ refreshVehicles,
174
+ stations,
175
+ visible
176
+ }) => (
177
+ // Caution, <BaseMap> must be a direct parent of <VehicleRentalOverlay>.
178
+ // Therefore, do not place <BaseMap> in a decorator at this time.
179
+ <BaseMap center={center} zoom={INITIAL_ZOOM}>
180
+ <VehicleRentalOverlay
181
+ configCompanies={configCompanies}
182
+ companies={companies}
183
+ getStationName={getStationName}
184
+ setLocation={setLocation}
185
+ mapSymbols={mapSymbols}
186
+ name="Rentals"
187
+ refreshVehicles={refreshVehicles}
188
+ stations={stations}
189
+ visible={visible}
190
+ />
191
+ </BaseMap>
192
+ );
213
193
 
214
194
  ZoomControlledMapWithVehicleRentalOverlay.propTypes = {
215
195
  companies: PropTypes.arrayOf(PropTypes.string.isRequired),
@@ -225,7 +205,7 @@ ZoomControlledMapWithVehicleRentalOverlay.defaultProps = {
225
205
  companies: null,
226
206
  getStationName: undefined,
227
207
  mapSymbols: null,
228
- visible: undefined
208
+ visible: true
229
209
  };
230
210
 
231
211
  function customStationName(_, station) {
@@ -249,7 +229,7 @@ export const RentalBicycles = () => (
249
229
  export const RentalBicyclesVisibilityControlledByKnob = () => {
250
230
  const isOverlayVisible = boolean(
251
231
  "Toggle visibility of vehicle rental overlay",
252
- true
232
+ false
253
233
  );
254
234
  return (
255
235
  <ZoomControlledMapWithVehicleRentalOverlay
package/src/index.js CHANGED
@@ -18,6 +18,13 @@ import {
18
18
  * different zoom levels.
19
19
  */
20
20
  class VehicleRentalOverlay extends MapLayer {
21
+ constructor(props) {
22
+ super(props);
23
+ this.state = {
24
+ zoom: props.leaflet.map.getZoom()
25
+ };
26
+ }
27
+
21
28
  /**
22
29
  * This helper method will be passed to the ZoomBasedMarkers symbolTransform prop.
23
30
  * It creates a component that inserts a popup
@@ -92,23 +99,50 @@ class VehicleRentalOverlay extends MapLayer {
92
99
  if (this.refreshTimer) clearInterval(this.refreshTimer);
93
100
  }
94
101
 
102
+ /**
103
+ * When the layer is added (or toggled on, or its visibility becomes true),
104
+ * start refreshing vehicle positions.
105
+ */
106
+ onOverlayAdded = () => {
107
+ this.startRefreshing();
108
+ };
109
+
110
+ /**
111
+ * When the layer is removed (or toggled off, or its visibility becomes false),
112
+ * stop refreshing vehicle positions.
113
+ */
114
+ onOverlayRemoved = () => {
115
+ this.stopRefreshing();
116
+ };
117
+
118
+ /**
119
+ * Listen to changes on the BaseMap's center or zoom.
120
+ * @param viewport The viewport data. See https://github.com/PaulLeCam/react-leaflet/blob/master/example/components/viewport.js for details.
121
+ */
122
+ onViewportChanged = viewport => {
123
+ const { zoom: newZoom } = viewport;
124
+ if (this.state.zoom !== newZoom) {
125
+ this.setState({ zoom: newZoom });
126
+ }
127
+ };
128
+
129
+ /**
130
+ * Upon mounting, see whether the vehicles should be fetched,
131
+ * and also call the register overlay prop that the
132
+ * @opentripplanner/base-map package has injected to listen to zoom/position changes.
133
+ */
95
134
  componentDidMount() {
96
- const { visible } = this.props;
135
+ const { registerOverlay, visible } = this.props;
97
136
  if (visible) this.startRefreshing();
137
+ if (typeof registerOverlay === "function") {
138
+ registerOverlay(this);
139
+ }
98
140
  }
99
141
 
100
142
  componentWillUnmount() {
101
143
  this.stopRefreshing();
102
144
  }
103
145
 
104
- componentDidUpdate(prevProps) {
105
- if (!prevProps.visible && this.props.visible) {
106
- this.startRefreshing();
107
- } else if (prevProps.visible && !this.props.visible) {
108
- this.stopRefreshing();
109
- }
110
- }
111
-
112
146
  /**
113
147
  * Render some popup html for a station. This contains custom logic for
114
148
  * displaying rental vehicles in the TriMet MOD website that might not be
@@ -149,14 +183,12 @@ class VehicleRentalOverlay extends MapLayer {
149
183
  };
150
184
 
151
185
  render() {
152
- const { companies, mapSymbols, stations, visible } = this.props;
186
+ const { companies, mapSymbols, stations } = this.props;
187
+ const { zoom } = this.state;
153
188
  // Render an empty FeatureGroup if the rental vehicles should not be visible
154
189
  // on the map. Otherwise previous stations may still be shown due to some
155
190
  // react-leaflet internals, maybe? Also, do not return null because that will
156
191
  // prevent the overlay from appearing in the layer controls.
157
- if (!visible) {
158
- return <FeatureGroup />;
159
- }
160
192
 
161
193
  let filteredStations = stations;
162
194
  if (companies) {
@@ -170,9 +202,6 @@ class VehicleRentalOverlay extends MapLayer {
170
202
  return <FeatureGroup />;
171
203
  }
172
204
 
173
- // get zoom to check which symbol to render
174
- const zoom = this.props.leaflet.map.getZoom();
175
-
176
205
  // Convert map symbols for this overlay to zoomBasedSymbolType.
177
206
  const symbols = this.convertToZoomMarkerSymbols(mapSymbols);
178
207
 
@@ -1,90 +0,0 @@
1
- import _extends from "@babel/runtime/helpers/extends";
2
- import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
3
- import _createClass from "@babel/runtime/helpers/createClass";
4
- import _inherits from "@babel/runtime/helpers/inherits";
5
- import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
6
- import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
7
-
8
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
9
-
10
- function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
11
-
12
- import React, { Component } from "react";
13
- import VehicleRentalOverlay from ".";
14
-
15
- /**
16
- * This class is a necessary intermediary to handle events proxied from the
17
- * parent @opentripplanner/base-map component handlers to this component.
18
- * Without this interface, there would be no way to detect when a user would
19
- * hide this layer from view on the Leaflet map. The visible property influences
20
- * and sets the Leaflet Layer Control which then is handled by the
21
- * @opentripplanner/base-map component and then delivered to the
22
- * `onOverlayAdded` and `onOverlayRemoved` handlers which then finally set this
23
- * component's state which is then finally used by the vehicle rental overlay
24
- * to properly manage the requesting of vehicle rentals.
25
- */
26
- var LeafletLayerControlInterface = /*#__PURE__*/function (_Component) {
27
- _inherits(LeafletLayerControlInterface, _Component);
28
-
29
- var _super = _createSuper(LeafletLayerControlInterface);
30
-
31
- function LeafletLayerControlInterface(props) {
32
- var _this;
33
-
34
- _classCallCheck(this, LeafletLayerControlInterface);
35
-
36
- _this = _super.call(this, props);
37
-
38
- _this.onOverlayAdded = function () {
39
- _this.setState({
40
- visible: true
41
- });
42
- };
43
-
44
- _this.onOverlayRemoved = function () {
45
- _this.setState({
46
- visible: false
47
- });
48
- };
49
-
50
- _this.state = {
51
- visible: props.visible
52
- };
53
- return _this;
54
- }
55
- /**
56
- * Upon mounting, this class calls the register overlay property that the
57
- * @opentripplanner/base-map package has injected into the props.
58
- */
59
-
60
-
61
- _createClass(LeafletLayerControlInterface, [{
62
- key: "componentDidMount",
63
- value: function componentDidMount() {
64
- var registerOverlay = this.props.registerOverlay;
65
- registerOverlay(this);
66
- }
67
- /**
68
- * A handler function for when this layer is toggled on by the user via the
69
- * leaflet layer control.
70
- */
71
-
72
- }, {
73
- key: "render",
74
- value: function render() {
75
- var visible = this.state.visible;
76
- return (
77
- /*#__PURE__*/
78
- // eslint-disable-next-line react/jsx-props-no-spreading
79
- React.createElement(VehicleRentalOverlay, _extends({}, this.props, {
80
- visible: visible
81
- }))
82
- );
83
- }
84
- }]);
85
-
86
- return LeafletLayerControlInterface;
87
- }(Component);
88
-
89
- export { LeafletLayerControlInterface as default };
90
- //# sourceMappingURL=leaflet-layer-control-interface.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/leaflet-layer-control-interface.tsx"],"names":["React","Component","VehicleRentalOverlay","LeafletLayerControlInterface","props","onOverlayAdded","setState","visible","onOverlayRemoved","state","registerOverlay"],"mappings":";;;;;;;;;;;AAAA,OAAOA,KAAP,IAAgBC,SAAhB,QAAiC,OAAjC;AAEA,OAAOC,oBAAP,MAAiC,GAAjC;;AA0BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;IACqBC,4B;;;;;AAInB,wCAAYC,KAAZ,EAA0B;AAAA;;AAAA;;AACxB,8BAAMA,KAAN;;AADwB,UAkB1BC,cAlB0B,GAkBT,YAAM;AACrB,YAAKC,QAAL,CAAc;AAAEC,QAAAA,OAAO,EAAE;AAAX,OAAd;AACD,KApByB;;AAAA,UA0B1BC,gBA1B0B,GA0BP,YAAM;AACvB,YAAKF,QAAL,CAAc;AAAEC,QAAAA,OAAO,EAAE;AAAX,OAAd;AACD,KA5ByB;;AAExB,UAAKE,KAAL,GAAa;AAAEF,MAAAA,OAAO,EAAEH,KAAK,CAACG;AAAjB,KAAb;AAFwB;AAGzB;AAED;AACF;AACA;AACA;;;;;WACE,6BAAoB;AAClB,UAAQG,eAAR,GAA4B,KAAKN,KAAjC,CAAQM,eAAR;AACAA,MAAAA,eAAe,CAAC,IAAD,CAAf;AACD;AAED;AACF;AACA;AACA;;;;WAaE,kBAAS;AACP,UAAQH,OAAR,GAAoB,KAAKE,KAAzB,CAAQF,OAAR;AACA;AAAA;AACE;AACA,4BAAC,oBAAD,eAA0B,KAAKH,KAA/B;AAAsC,UAAA,OAAO,EAAEG;AAA/C;AAFF;AAID;;;;EAxCuDN,S;;SAArCE,4B","sourcesContent":["import React, { Component } from \"react\";\n\nimport VehicleRentalOverlay from \".\";\n\ntype Props = {\n /**\n * This method is created by the @opentripplanner/base-map package when\n * mounting user-defined layers. This will allow the component to subscribe to\n * various leaflet events that then get forwarded on to this component.\n */\n registerOverlay: (component: Component) => void;\n /**\n * Whether or not to initially display the rental vehicles. Once the component\n * is mounted the subscribed events of a user toggling on or off the layer via\n * the layer control item will subsequently control the display of the\n * component.\n */\n visible?: boolean;\n};\n\ntype State = {\n /**\n * An internal state variable used to determine whether or not to display the\n * rental vehicles for this layer.\n */\n visible: boolean;\n};\n\n/**\n * This class is a necessary intermediary to handle events proxied from the\n * parent @opentripplanner/base-map component handlers to this component.\n * Without this interface, there would be no way to detect when a user would\n * hide this layer from view on the Leaflet map. The visible property influences\n * and sets the Leaflet Layer Control which then is handled by the\n * @opentripplanner/base-map component and then delivered to the\n * `onOverlayAdded` and `onOverlayRemoved` handlers which then finally set this\n * component's state which is then finally used by the vehicle rental overlay\n * to properly manage the requesting of vehicle rentals.\n */\nexport default class LeafletLayerControlInterface extends Component<\n Props,\n State\n> {\n constructor(props: Props) {\n super(props);\n this.state = { visible: props.visible };\n }\n\n /**\n * Upon mounting, this class calls the register overlay property that the\n * @opentripplanner/base-map package has injected into the props.\n */\n componentDidMount() {\n const { registerOverlay } = this.props;\n registerOverlay(this);\n }\n\n /**\n * A handler function for when this layer is toggled on by the user via the\n * leaflet layer control.\n */\n onOverlayAdded = () => {\n this.setState({ visible: true });\n };\n\n /**\n * A handler function for when this layer is toggled off by the user via the\n * leaflet layer control.\n */\n onOverlayRemoved = () => {\n this.setState({ visible: false });\n };\n\n render() {\n const { visible } = this.state;\n return (\n // eslint-disable-next-line react/jsx-props-no-spreading\n <VehicleRentalOverlay {...this.props} visible={visible} />\n );\n }\n}\n"],"file":"leaflet-layer-control-interface.js"}
@@ -1,85 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
-
5
- Object.defineProperty(exports, "__esModule", {
6
- value: true
7
- });
8
- exports.default = void 0;
9
-
10
- var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
11
-
12
- var _react = _interopRequireWildcard(require("react"));
13
-
14
- var _ = _interopRequireDefault(require("."));
15
-
16
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
17
-
18
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
19
-
20
- /**
21
- * This class is a necessary intermediary to handle events proxied from the
22
- * parent @opentripplanner/base-map component handlers to this component.
23
- * Without this interface, there would be no way to detect when a user would
24
- * hide this layer from view on the Leaflet map. The visible property influences
25
- * and sets the Leaflet Layer Control which then is handled by the
26
- * @opentripplanner/base-map component and then delivered to the
27
- * `onOverlayAdded` and `onOverlayRemoved` handlers which then finally set this
28
- * component's state which is then finally used by the vehicle rental overlay
29
- * to properly manage the requesting of vehicle rentals.
30
- */
31
- class LeafletLayerControlInterface extends _react.Component {
32
- constructor(props) {
33
- super(props);
34
-
35
- this.onOverlayAdded = () => {
36
- this.setState({
37
- visible: true
38
- });
39
- };
40
-
41
- this.onOverlayRemoved = () => {
42
- this.setState({
43
- visible: false
44
- });
45
- };
46
-
47
- this.state = {
48
- visible: props.visible
49
- };
50
- }
51
- /**
52
- * Upon mounting, this class calls the register overlay property that the
53
- * @opentripplanner/base-map package has injected into the props.
54
- */
55
-
56
-
57
- componentDidMount() {
58
- const {
59
- registerOverlay
60
- } = this.props;
61
- registerOverlay(this);
62
- }
63
- /**
64
- * A handler function for when this layer is toggled on by the user via the
65
- * leaflet layer control.
66
- */
67
-
68
-
69
- render() {
70
- const {
71
- visible
72
- } = this.state;
73
- return (
74
- /*#__PURE__*/
75
- // eslint-disable-next-line react/jsx-props-no-spreading
76
- _react.default.createElement(_.default, (0, _extends2.default)({}, this.props, {
77
- visible: visible
78
- }))
79
- );
80
- }
81
-
82
- }
83
-
84
- exports.default = LeafletLayerControlInterface;
85
- //# sourceMappingURL=leaflet-layer-control-interface.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/leaflet-layer-control-interface.tsx"],"names":["LeafletLayerControlInterface","Component","constructor","props","onOverlayAdded","setState","visible","onOverlayRemoved","state","componentDidMount","registerOverlay","render"],"mappings":";;;;;;;;;;;AAAA;;AAEA;;;;;;AA0BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACe,MAAMA,4BAAN,SAA2CC,gBAA3C,CAGb;AACAC,EAAAA,WAAW,CAACC,KAAD,EAAe;AACxB,UAAMA,KAAN;;AADwB,SAkB1BC,cAlB0B,GAkBT,MAAM;AACrB,WAAKC,QAAL,CAAc;AAAEC,QAAAA,OAAO,EAAE;AAAX,OAAd;AACD,KApByB;;AAAA,SA0B1BC,gBA1B0B,GA0BP,MAAM;AACvB,WAAKF,QAAL,CAAc;AAAEC,QAAAA,OAAO,EAAE;AAAX,OAAd;AACD,KA5ByB;;AAExB,SAAKE,KAAL,GAAa;AAAEF,MAAAA,OAAO,EAAEH,KAAK,CAACG;AAAjB,KAAb;AACD;AAED;AACF;AACA;AACA;;;AACEG,EAAAA,iBAAiB,GAAG;AAClB,UAAM;AAAEC,MAAAA;AAAF,QAAsB,KAAKP,KAAjC;AACAO,IAAAA,eAAe,CAAC,IAAD,CAAf;AACD;AAED;AACF;AACA;AACA;;;AAaEC,EAAAA,MAAM,GAAG;AACP,UAAM;AAAEL,MAAAA;AAAF,QAAc,KAAKE,KAAzB;AACA;AAAA;AACE;AACA,mCAAC,SAAD,6BAA0B,KAAKL,KAA/B;AAAsC,QAAA,OAAO,EAAEG;AAA/C;AAFF;AAID;;AArCD","sourcesContent":["import React, { Component } from \"react\";\n\nimport VehicleRentalOverlay from \".\";\n\ntype Props = {\n /**\n * This method is created by the @opentripplanner/base-map package when\n * mounting user-defined layers. This will allow the component to subscribe to\n * various leaflet events that then get forwarded on to this component.\n */\n registerOverlay: (component: Component) => void;\n /**\n * Whether or not to initially display the rental vehicles. Once the component\n * is mounted the subscribed events of a user toggling on or off the layer via\n * the layer control item will subsequently control the display of the\n * component.\n */\n visible?: boolean;\n};\n\ntype State = {\n /**\n * An internal state variable used to determine whether or not to display the\n * rental vehicles for this layer.\n */\n visible: boolean;\n};\n\n/**\n * This class is a necessary intermediary to handle events proxied from the\n * parent @opentripplanner/base-map component handlers to this component.\n * Without this interface, there would be no way to detect when a user would\n * hide this layer from view on the Leaflet map. The visible property influences\n * and sets the Leaflet Layer Control which then is handled by the\n * @opentripplanner/base-map component and then delivered to the\n * `onOverlayAdded` and `onOverlayRemoved` handlers which then finally set this\n * component's state which is then finally used by the vehicle rental overlay\n * to properly manage the requesting of vehicle rentals.\n */\nexport default class LeafletLayerControlInterface extends Component<\n Props,\n State\n> {\n constructor(props: Props) {\n super(props);\n this.state = { visible: props.visible };\n }\n\n /**\n * Upon mounting, this class calls the register overlay property that the\n * @opentripplanner/base-map package has injected into the props.\n */\n componentDidMount() {\n const { registerOverlay } = this.props;\n registerOverlay(this);\n }\n\n /**\n * A handler function for when this layer is toggled on by the user via the\n * leaflet layer control.\n */\n onOverlayAdded = () => {\n this.setState({ visible: true });\n };\n\n /**\n * A handler function for when this layer is toggled off by the user via the\n * leaflet layer control.\n */\n onOverlayRemoved = () => {\n this.setState({ visible: false });\n };\n\n render() {\n const { visible } = this.state;\n return (\n // eslint-disable-next-line react/jsx-props-no-spreading\n <VehicleRentalOverlay {...this.props} visible={visible} />\n );\n }\n}\n"],"file":"leaflet-layer-control-interface.js"}
@@ -1,81 +0,0 @@
1
- import React, { Component } from "react";
2
-
3
- import VehicleRentalOverlay from ".";
4
-
5
- type Props = {
6
- /**
7
- * This method is created by the @opentripplanner/base-map package when
8
- * mounting user-defined layers. This will allow the component to subscribe to
9
- * various leaflet events that then get forwarded on to this component.
10
- */
11
- registerOverlay: (component: Component) => void;
12
- /**
13
- * Whether or not to initially display the rental vehicles. Once the component
14
- * is mounted the subscribed events of a user toggling on or off the layer via
15
- * the layer control item will subsequently control the display of the
16
- * component.
17
- */
18
- visible?: boolean;
19
- };
20
-
21
- type State = {
22
- /**
23
- * An internal state variable used to determine whether or not to display the
24
- * rental vehicles for this layer.
25
- */
26
- visible: boolean;
27
- };
28
-
29
- /**
30
- * This class is a necessary intermediary to handle events proxied from the
31
- * parent @opentripplanner/base-map component handlers to this component.
32
- * Without this interface, there would be no way to detect when a user would
33
- * hide this layer from view on the Leaflet map. The visible property influences
34
- * and sets the Leaflet Layer Control which then is handled by the
35
- * @opentripplanner/base-map component and then delivered to the
36
- * `onOverlayAdded` and `onOverlayRemoved` handlers which then finally set this
37
- * component's state which is then finally used by the vehicle rental overlay
38
- * to properly manage the requesting of vehicle rentals.
39
- */
40
- export default class LeafletLayerControlInterface extends Component<
41
- Props,
42
- State
43
- > {
44
- constructor(props: Props) {
45
- super(props);
46
- this.state = { visible: props.visible };
47
- }
48
-
49
- /**
50
- * Upon mounting, this class calls the register overlay property that the
51
- * @opentripplanner/base-map package has injected into the props.
52
- */
53
- componentDidMount() {
54
- const { registerOverlay } = this.props;
55
- registerOverlay(this);
56
- }
57
-
58
- /**
59
- * A handler function for when this layer is toggled on by the user via the
60
- * leaflet layer control.
61
- */
62
- onOverlayAdded = () => {
63
- this.setState({ visible: true });
64
- };
65
-
66
- /**
67
- * A handler function for when this layer is toggled off by the user via the
68
- * leaflet layer control.
69
- */
70
- onOverlayRemoved = () => {
71
- this.setState({ visible: false });
72
- };
73
-
74
- render() {
75
- const { visible } = this.state;
76
- return (
77
- // eslint-disable-next-line react/jsx-props-no-spreading
78
- <VehicleRentalOverlay {...this.props} visible={visible} />
79
- );
80
- }
81
- }