@opentripplanner/vehicle-rental-overlay 1.4.4 → 2.0.0-alpha.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/StationPopup.js +99 -0
- package/esm/StationPopup.js.map +1 -0
- package/esm/index.js +147 -355
- package/esm/index.js.map +1 -1
- package/esm/styled.js +48 -50
- package/esm/styled.js.map +1 -1
- package/lib/StationPopup.d.ts +16 -0
- package/lib/StationPopup.d.ts.map +1 -0
- package/lib/StationPopup.js +119 -0
- package/lib/StationPopup.js.map +1 -0
- package/lib/index.d.ts +62 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +125 -333
- package/lib/index.js.map +1 -1
- package/lib/styled.d.ts +11 -0
- package/lib/styled.d.ts.map +1 -0
- package/lib/styled.js +48 -63
- package/lib/styled.js.map +1 -1
- package/package.json +10 -8
- package/src/StationPopup.tsx +146 -0
- package/src/VehicleRentalOverlay.story.tsx +122 -0
- package/src/index.tsx +256 -0
- package/src/styled.ts +52 -0
- package/tsconfig.json +15 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/esm/DefaultMarkers/index.js +0 -140
- package/esm/DefaultMarkers/index.js.map +0 -1
- package/esm/bike-icons.js +0 -21
- package/esm/bike-icons.js.map +0 -1
- package/lib/DefaultMarkers/index.js +0 -165
- package/lib/DefaultMarkers/index.js.map +0 -1
- package/lib/bike-icons.js +0 -38
- package/lib/bike-icons.js.map +0 -1
- package/src/DefaultMarkers/index.js +0 -130
- package/src/VehicleRentalOverlay.story.js +0 -284
- package/src/bike-icons.js +0 -23
- package/src/index.js +0 -377
- package/src/styled.js +0 -78
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import { divIcon } from "leaflet";
|
|
2
|
-
import memoize from "lodash.memoize";
|
|
3
|
-
import PropTypes from "prop-types";
|
|
4
|
-
import React from "react";
|
|
5
|
-
import ReactDOMServer from "react-dom/server";
|
|
6
|
-
import { CircleMarker, Marker } from "react-leaflet";
|
|
7
|
-
|
|
8
|
-
import { floatingBikeIcon, hubIcons } from "../bike-icons";
|
|
9
|
-
import * as Styled from "../styled";
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* This file contains default marker types for rental vehicles,
|
|
13
|
-
* that can be used when defining the VehicleRentalOverlay's symbol prop:
|
|
14
|
-
* - SharedBikeCircle
|
|
15
|
-
* - GenericMarker
|
|
16
|
-
* - HubAndFloatingBike
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
// Prop types reused across components.
|
|
20
|
-
const templatePropTypes = {
|
|
21
|
-
/** The children of the component. */
|
|
22
|
-
children: PropTypes.node,
|
|
23
|
-
/** The rental vehicle or station to render. */
|
|
24
|
-
// entity: coreUtils.types.stationType.isRequired,
|
|
25
|
-
// eslint-disable-next-line react/forbid-prop-types
|
|
26
|
-
entity: PropTypes.object.isRequired,
|
|
27
|
-
/** leaflet attribute to control tabindex value for keyboaryd-only / SR users */
|
|
28
|
-
keyboard: PropTypes.bool
|
|
29
|
-
};
|
|
30
|
-
const templateDefaultProps = {
|
|
31
|
-
children: null,
|
|
32
|
-
keyboard: false
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Renders a shared bike or shared bike dock as a circle
|
|
37
|
-
* with predefined colors and size.
|
|
38
|
-
*/
|
|
39
|
-
export const SharedBikeCircle = ({
|
|
40
|
-
dockStrokeColor,
|
|
41
|
-
fillColor = "gray",
|
|
42
|
-
pixels,
|
|
43
|
-
strokeColor
|
|
44
|
-
}) => {
|
|
45
|
-
const GeneratedMarker = ({ children, keyboard, entity: station }) => {
|
|
46
|
-
let newStrokeColor = strokeColor || fillColor;
|
|
47
|
-
|
|
48
|
-
if (!station.isFloatingBike) {
|
|
49
|
-
newStrokeColor = dockStrokeColor || strokeColor;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return (
|
|
53
|
-
<CircleMarker
|
|
54
|
-
center={[station.y, station.x]}
|
|
55
|
-
color={newStrokeColor}
|
|
56
|
-
fillColor={fillColor}
|
|
57
|
-
fillOpacity={1}
|
|
58
|
-
keyboard={keyboard}
|
|
59
|
-
radius={pixels - (station.isFloatingBike ? 1 : 0)}
|
|
60
|
-
weight={1}
|
|
61
|
-
>
|
|
62
|
-
{children}
|
|
63
|
-
</CircleMarker>
|
|
64
|
-
);
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
GeneratedMarker.propTypes = templatePropTypes;
|
|
68
|
-
GeneratedMarker.defaultProps = templateDefaultProps;
|
|
69
|
-
return GeneratedMarker;
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* A component that renders rental bike entities
|
|
74
|
-
* either as a bike or a bike dock (or hub, showing spaces available).
|
|
75
|
-
*/
|
|
76
|
-
export const HubAndFloatingBike = ({ children, keyboard, entity: station }) => {
|
|
77
|
-
let icon;
|
|
78
|
-
if (station.isFloatingBike) {
|
|
79
|
-
icon = floatingBikeIcon;
|
|
80
|
-
} else {
|
|
81
|
-
const capacity = station.bikesAvailable + station.spacesAvailable;
|
|
82
|
-
if (capacity === 0) return null;
|
|
83
|
-
const pctFull = station.bikesAvailable / capacity;
|
|
84
|
-
const i = Math.round(pctFull * 9);
|
|
85
|
-
icon = hubIcons[i];
|
|
86
|
-
}
|
|
87
|
-
return (
|
|
88
|
-
<Marker icon={icon} keyboard={keyboard} position={[station.y, station.x]}>
|
|
89
|
-
{children}
|
|
90
|
-
</Marker>
|
|
91
|
-
);
|
|
92
|
-
};
|
|
93
|
-
HubAndFloatingBike.propTypes = templatePropTypes;
|
|
94
|
-
HubAndFloatingBike.defaultProps = templateDefaultProps;
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Creates and caches a leaflet element icon based on color.
|
|
98
|
-
*/
|
|
99
|
-
const getStationMarkerByColor = memoize(color =>
|
|
100
|
-
divIcon({
|
|
101
|
-
className: "",
|
|
102
|
-
iconSize: [11, 16],
|
|
103
|
-
popupAnchor: [0, -6],
|
|
104
|
-
html: ReactDOMServer.renderToStaticMarkup(
|
|
105
|
-
<Styled.StationMarker color={color} />
|
|
106
|
-
)
|
|
107
|
-
})
|
|
108
|
-
);
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Helper function to create a leaflet Marker component to render entities
|
|
112
|
-
* using fixed fill color.
|
|
113
|
-
* Usage: GenericMarker({ fillColor: "#F204B5" })
|
|
114
|
-
*/
|
|
115
|
-
export const GenericMarker = ({ fillColor = "gray" }) => {
|
|
116
|
-
const markerIcon = getStationMarkerByColor(fillColor);
|
|
117
|
-
|
|
118
|
-
const GeneratedMarker = ({ children, keyboard, entity: station }) => (
|
|
119
|
-
<Marker
|
|
120
|
-
icon={markerIcon}
|
|
121
|
-
keyboard={keyboard}
|
|
122
|
-
position={[station.y, station.x]}
|
|
123
|
-
>
|
|
124
|
-
{children}
|
|
125
|
-
</Marker>
|
|
126
|
-
);
|
|
127
|
-
GeneratedMarker.propTypes = templatePropTypes;
|
|
128
|
-
GeneratedMarker.defaultProps = templateDefaultProps;
|
|
129
|
-
return GeneratedMarker;
|
|
130
|
-
};
|
|
@@ -1,284 +0,0 @@
|
|
|
1
|
-
// Removed as core-utils is typescripted. TODO: Remove when typescripting!
|
|
2
|
-
/* eslint-disable react/forbid-prop-types */
|
|
3
|
-
import BaseMap from "@opentripplanner/base-map";
|
|
4
|
-
import PropTypes from "prop-types";
|
|
5
|
-
import React from "react";
|
|
6
|
-
import { CircleMarker } from "react-leaflet";
|
|
7
|
-
import { action } from "@storybook/addon-actions";
|
|
8
|
-
import { boolean } from "@storybook/addon-knobs";
|
|
9
|
-
|
|
10
|
-
import VehicleRentalOverlay from ".";
|
|
11
|
-
import bikeRentalStations from "../__mocks__/bike-rental-stations.json";
|
|
12
|
-
import carRentalStations from "../__mocks__/car-rental-stations.json";
|
|
13
|
-
import eScooterStations from "../__mocks__/e-scooter-rental-stations.json";
|
|
14
|
-
import { HubAndFloatingBike } from "./DefaultMarkers";
|
|
15
|
-
|
|
16
|
-
import "../../../node_modules/leaflet/dist/leaflet.css";
|
|
17
|
-
|
|
18
|
-
const center = [45.518092, -122.671202];
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Creates an example Circle component to render entities
|
|
22
|
-
* using a fixed size, fill color, and stroke color.
|
|
23
|
-
*/
|
|
24
|
-
const MyCircle = ({ fillColor = "gray", pixels, strokeColor }) => {
|
|
25
|
-
const newStrokeColor = strokeColor || fillColor;
|
|
26
|
-
|
|
27
|
-
const GeneratedCircle = ({ children, entity: station }) => (
|
|
28
|
-
<CircleMarker
|
|
29
|
-
center={[station.y, station.x]}
|
|
30
|
-
color={newStrokeColor}
|
|
31
|
-
fillColor={fillColor}
|
|
32
|
-
fillOpacity={1}
|
|
33
|
-
radius={pixels}
|
|
34
|
-
weight={1}
|
|
35
|
-
>
|
|
36
|
-
{children}
|
|
37
|
-
</CircleMarker>
|
|
38
|
-
);
|
|
39
|
-
GeneratedCircle.propTypes = {
|
|
40
|
-
children: PropTypes.node,
|
|
41
|
-
// entity: coreUtils.types.stationType.isRequired
|
|
42
|
-
entity: PropTypes.object.isRequired
|
|
43
|
-
};
|
|
44
|
-
GeneratedCircle.defaultProps = {
|
|
45
|
-
children: null
|
|
46
|
-
};
|
|
47
|
-
return GeneratedCircle;
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
const bikeMapSymbols = [
|
|
51
|
-
{
|
|
52
|
-
dockStrokeColor: "#000000",
|
|
53
|
-
fillColor: "#FF2E28",
|
|
54
|
-
minZoom: 0,
|
|
55
|
-
pixels: 4,
|
|
56
|
-
type: "circle"
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
dockStrokeColor: "#000000",
|
|
60
|
-
fillColor: "#FF2E28",
|
|
61
|
-
minZoom: 14,
|
|
62
|
-
pixels: 6,
|
|
63
|
-
type: "circle"
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
minZoom: 18,
|
|
67
|
-
type: "hubAndFloatingBike"
|
|
68
|
-
}
|
|
69
|
-
];
|
|
70
|
-
// Bike symbols using new symbols prop.
|
|
71
|
-
const bikeSymbols = [
|
|
72
|
-
{
|
|
73
|
-
getType: station => (station.isFloatingBike ? "floatingBike" : "dock"),
|
|
74
|
-
minZoom: 0,
|
|
75
|
-
symbol: MyCircle({ fillColor: "#FF2E28", pixels: 3 }),
|
|
76
|
-
symbolByType: {
|
|
77
|
-
dock: MyCircle({
|
|
78
|
-
fillColor: "#FF2E28",
|
|
79
|
-
pixels: 4,
|
|
80
|
-
strokeColor: "#000000"
|
|
81
|
-
})
|
|
82
|
-
}
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
getType: station => (station.isFloatingBike ? "floatingBike" : "dock"),
|
|
86
|
-
minZoom: 14,
|
|
87
|
-
symbol: MyCircle({ fillColor: "#FF2E28", pixels: 5 }),
|
|
88
|
-
symbolByType: {
|
|
89
|
-
dock: MyCircle({
|
|
90
|
-
fillColor: "#FF2E28",
|
|
91
|
-
pixels: 6,
|
|
92
|
-
strokeColor: "#000000"
|
|
93
|
-
})
|
|
94
|
-
}
|
|
95
|
-
},
|
|
96
|
-
{
|
|
97
|
-
minZoom: 18,
|
|
98
|
-
symbol: HubAndFloatingBike
|
|
99
|
-
}
|
|
100
|
-
];
|
|
101
|
-
const carMapSymbols = [
|
|
102
|
-
{
|
|
103
|
-
fillColor: "#009cde",
|
|
104
|
-
minZoom: 0,
|
|
105
|
-
pixels: 4,
|
|
106
|
-
type: "circle"
|
|
107
|
-
},
|
|
108
|
-
{
|
|
109
|
-
fillColor: "#009cde",
|
|
110
|
-
minZoom: 14,
|
|
111
|
-
pixels: 6,
|
|
112
|
-
type: "circle"
|
|
113
|
-
},
|
|
114
|
-
{
|
|
115
|
-
fillColor: "#009cde",
|
|
116
|
-
minZoom: 18,
|
|
117
|
-
type: "marker"
|
|
118
|
-
}
|
|
119
|
-
];
|
|
120
|
-
const configCompanies = [
|
|
121
|
-
{
|
|
122
|
-
id: "BIKETOWN",
|
|
123
|
-
label: "Biketown",
|
|
124
|
-
modes: "BICYCLE_RENT"
|
|
125
|
-
},
|
|
126
|
-
{
|
|
127
|
-
id: "CAR2GO",
|
|
128
|
-
label: "car2go",
|
|
129
|
-
modes: "CAR_RENT"
|
|
130
|
-
},
|
|
131
|
-
{
|
|
132
|
-
id: "RAZOR",
|
|
133
|
-
label: "Razor",
|
|
134
|
-
modes: "MICROMOBILITY_RENT"
|
|
135
|
-
},
|
|
136
|
-
{
|
|
137
|
-
id: "SHARED",
|
|
138
|
-
label: "Shared",
|
|
139
|
-
modes: "MICROMOBILITY_RENT"
|
|
140
|
-
}
|
|
141
|
-
];
|
|
142
|
-
const EScooterMapSymbols = [
|
|
143
|
-
{
|
|
144
|
-
fillColor: "#F80600",
|
|
145
|
-
minZoom: 0,
|
|
146
|
-
pixels: 4,
|
|
147
|
-
strokeColor: "#CCCCCC",
|
|
148
|
-
type: "circle"
|
|
149
|
-
},
|
|
150
|
-
// You can combine predefined symbols (type = "<type>")
|
|
151
|
-
// and external symbols (symbol = Component<({ entity, zoom })>.
|
|
152
|
-
// (the color and pixel properties are ignored if you use the symbol syntax.).
|
|
153
|
-
{
|
|
154
|
-
minZoom: 14,
|
|
155
|
-
symbol: MyCircle({
|
|
156
|
-
fillColor: "#F80600",
|
|
157
|
-
pixels: 6,
|
|
158
|
-
strokeColor: "#CCCCCC"
|
|
159
|
-
})
|
|
160
|
-
},
|
|
161
|
-
{
|
|
162
|
-
fillColor: "#F80600",
|
|
163
|
-
minZoom: 18,
|
|
164
|
-
type: "marker"
|
|
165
|
-
}
|
|
166
|
-
];
|
|
167
|
-
const setLocation = action("setLocation");
|
|
168
|
-
|
|
169
|
-
const INITIAL_ZOOM = 13;
|
|
170
|
-
|
|
171
|
-
const ZoomControlledMapWithVehicleRentalOverlay = ({
|
|
172
|
-
companies,
|
|
173
|
-
getStationName,
|
|
174
|
-
mapSymbols,
|
|
175
|
-
refreshVehicles,
|
|
176
|
-
stations,
|
|
177
|
-
visible
|
|
178
|
-
}) => (
|
|
179
|
-
// Caution, <BaseMap> must be a direct parent of <VehicleRentalOverlay>.
|
|
180
|
-
// Therefore, do not place <BaseMap> in a decorator at this time.
|
|
181
|
-
<BaseMap center={center} zoom={INITIAL_ZOOM}>
|
|
182
|
-
<VehicleRentalOverlay
|
|
183
|
-
configCompanies={configCompanies}
|
|
184
|
-
companies={companies}
|
|
185
|
-
getStationName={getStationName}
|
|
186
|
-
setLocation={setLocation}
|
|
187
|
-
mapSymbols={mapSymbols}
|
|
188
|
-
name="Rentals"
|
|
189
|
-
refreshVehicles={refreshVehicles}
|
|
190
|
-
stations={stations}
|
|
191
|
-
visible={visible}
|
|
192
|
-
/>
|
|
193
|
-
</BaseMap>
|
|
194
|
-
);
|
|
195
|
-
|
|
196
|
-
ZoomControlledMapWithVehicleRentalOverlay.propTypes = {
|
|
197
|
-
companies: PropTypes.arrayOf(PropTypes.string.isRequired),
|
|
198
|
-
getStationName: PropTypes.func,
|
|
199
|
-
// mapSymbols: coreUtils.types.vehicleRentalMapOverlaySymbolsType,
|
|
200
|
-
mapSymbols: PropTypes.object,
|
|
201
|
-
refreshVehicles: PropTypes.func.isRequired,
|
|
202
|
-
// stations: PropTypes.arrayOf(coreUtils.types.stationType.isRequired)
|
|
203
|
-
// .isRequired,
|
|
204
|
-
stations: PropTypes.arrayOf(PropTypes.object.isRequired).isRequired,
|
|
205
|
-
visible: PropTypes.bool
|
|
206
|
-
};
|
|
207
|
-
|
|
208
|
-
ZoomControlledMapWithVehicleRentalOverlay.defaultProps = {
|
|
209
|
-
companies: null,
|
|
210
|
-
getStationName: undefined,
|
|
211
|
-
mapSymbols: null,
|
|
212
|
-
visible: true
|
|
213
|
-
};
|
|
214
|
-
|
|
215
|
-
function customStationName(_, station) {
|
|
216
|
-
return `🛴 (ID: ${station.id})`;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
export default {
|
|
220
|
-
title: "VehicleRentalOverlay",
|
|
221
|
-
component: VehicleRentalOverlay
|
|
222
|
-
};
|
|
223
|
-
|
|
224
|
-
export const RentalBicycles = () => (
|
|
225
|
-
<ZoomControlledMapWithVehicleRentalOverlay
|
|
226
|
-
companies={["BIKETOWN"]}
|
|
227
|
-
mapSymbols={bikeMapSymbols}
|
|
228
|
-
refreshVehicles={action("refresh bicycles")}
|
|
229
|
-
stations={bikeRentalStations}
|
|
230
|
-
/>
|
|
231
|
-
);
|
|
232
|
-
|
|
233
|
-
export const RentalBicyclesVisibilityControlledByKnob = () => {
|
|
234
|
-
const isOverlayVisible = boolean(
|
|
235
|
-
"Toggle visibility of vehicle rental overlay",
|
|
236
|
-
false
|
|
237
|
-
);
|
|
238
|
-
return (
|
|
239
|
-
<ZoomControlledMapWithVehicleRentalOverlay
|
|
240
|
-
companies={["BIKETOWN"]}
|
|
241
|
-
mapSymbols={bikeMapSymbols}
|
|
242
|
-
refreshVehicles={action("refresh bicycles")}
|
|
243
|
-
stations={bikeRentalStations}
|
|
244
|
-
visible={isOverlayVisible}
|
|
245
|
-
/>
|
|
246
|
-
);
|
|
247
|
-
};
|
|
248
|
-
|
|
249
|
-
export const RentalBicyclesUsingNewSymbolsProp = () => (
|
|
250
|
-
<ZoomControlledMapWithVehicleRentalOverlay
|
|
251
|
-
companies={["BIKETOWN"]}
|
|
252
|
-
refreshVehicles={action("refresh bicycles")}
|
|
253
|
-
mapSymbols={bikeSymbols}
|
|
254
|
-
stations={bikeRentalStations}
|
|
255
|
-
/>
|
|
256
|
-
);
|
|
257
|
-
|
|
258
|
-
export const RentalCars = () => (
|
|
259
|
-
<ZoomControlledMapWithVehicleRentalOverlay
|
|
260
|
-
companies={["CAR2GO"]}
|
|
261
|
-
mapSymbols={carMapSymbols}
|
|
262
|
-
refreshVehicles={action("refresh cars")}
|
|
263
|
-
stations={carRentalStations}
|
|
264
|
-
/>
|
|
265
|
-
);
|
|
266
|
-
|
|
267
|
-
export const RentalEScooters = () => (
|
|
268
|
-
<ZoomControlledMapWithVehicleRentalOverlay
|
|
269
|
-
companies={["SHARED"]}
|
|
270
|
-
mapSymbols={EScooterMapSymbols}
|
|
271
|
-
refreshVehicles={action("refresh E-scooters")}
|
|
272
|
-
stations={eScooterStations}
|
|
273
|
-
/>
|
|
274
|
-
);
|
|
275
|
-
|
|
276
|
-
export const RentalEScootersWithCustomNaming = () => (
|
|
277
|
-
<ZoomControlledMapWithVehicleRentalOverlay
|
|
278
|
-
companies={["SHARED"]}
|
|
279
|
-
getStationName={customStationName}
|
|
280
|
-
mapSymbols={EScooterMapSymbols}
|
|
281
|
-
refreshVehicles={action("refresh E-scooters")}
|
|
282
|
-
stations={eScooterStations}
|
|
283
|
-
/>
|
|
284
|
-
);
|
package/src/bike-icons.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { divIcon } from "leaflet";
|
|
2
|
-
import React from "react";
|
|
3
|
-
import ReactDOMServer from "react-dom/server";
|
|
4
|
-
|
|
5
|
-
import * as S from "./styled";
|
|
6
|
-
|
|
7
|
-
export const floatingBikeIcon = divIcon({
|
|
8
|
-
iconSize: [24, 24],
|
|
9
|
-
iconAnchor: [12, 24],
|
|
10
|
-
popupAnchor: [0, -12],
|
|
11
|
-
html: ReactDOMServer.renderToStaticMarkup(<S.OutOfHubBikeIcon />),
|
|
12
|
-
className: ""
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
export const hubIcons = S.hubIcons.map(StyledIcon =>
|
|
16
|
-
divIcon({
|
|
17
|
-
iconSize: [24, 24],
|
|
18
|
-
iconAnchor: [12, 24],
|
|
19
|
-
popupAnchor: [0, -12],
|
|
20
|
-
html: ReactDOMServer.renderToStaticMarkup(<StyledIcon />),
|
|
21
|
-
className: ""
|
|
22
|
-
})
|
|
23
|
-
);
|