@geops/rvf-mobility-web-component 0.1.64 → 0.1.66

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.
Files changed (43) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/docutils.js +125 -51
  3. package/index.html +48 -21
  4. package/index.js +291 -234
  5. package/package.json +12 -12
  6. package/search.html +25 -22
  7. package/src/BaseLayer/BaseLayer.tsx +18 -2
  8. package/src/Copyright/Copyright.tsx +2 -2
  9. package/src/Copyright/index.tsx +1 -1
  10. package/src/LayerTree/TreeItem/TreeItem.tsx +1 -1
  11. package/src/LinesNetworkPlanLayerHighlight/LinesNetworkPlanLayerHighlight.tsx +1 -0
  12. package/src/Map/Map.tsx +27 -1
  13. package/src/MapLayout/MapLayout.tsx +1 -1
  14. package/src/MapLayout/index.tsx +1 -1
  15. package/src/MobilityMap/MobilityMap.tsx +5 -11
  16. package/src/MobilityMap/MobilityMapAttributes.ts +8 -5
  17. package/src/MobilitySearch/MobilitySearchAttributes.ts +12 -0
  18. package/src/NotificationDetails/NotificationDetails.tsx +75 -57
  19. package/src/OverlayDetailsHeader/OverlayDetailsHeader.tsx +1 -1
  20. package/src/Permalink/Permalink.tsx +17 -6
  21. package/src/PermalinkInput/PermalinkInput.tsx +4 -1
  22. package/src/RealtimeLayer/index.tsx +1 -1
  23. package/src/RvfCopyright/RvfCopyright.tsx +32 -0
  24. package/src/RvfCopyright/index.tsx +1 -0
  25. package/src/RvfInputCopy/RvfInputCopy.tsx +18 -8
  26. package/src/RvfMapLayout/RvfMapLayout.tsx +198 -0
  27. package/src/RvfMapLayout/index.tsx +1 -0
  28. package/src/RvfMobilityMap/RvfMobilityMap.tsx +10 -580
  29. package/src/RvfRealtimeLayer/RvfRealtimeLayer.tsx +64 -0
  30. package/src/RvfRealtimeLayer/index.tsx +1 -0
  31. package/src/RvfStationsLayer/RvfStationsLayer.tsx +19 -0
  32. package/src/RvfStationsLayer/index.tsx +1 -0
  33. package/src/ShareMenu/ShareMenu.tsx +3 -1
  34. package/src/StationsLayer/index.tsx +1 -1
  35. package/src/ui/InputCopy/InputCopy.tsx +21 -10
  36. package/src/utils/constants.ts +1 -1
  37. package/src/utils/getUrlFromTemplate.test.ts +23 -0
  38. package/src/utils/getUrlFromTemplate.ts +47 -0
  39. package/src/utils/hooks/useI18n.tsx +2 -4
  40. package/src/utils/hooks/useInitialLayersVisiblity.tsx +27 -4
  41. package/src/utils/hooks/useInitialPermalink.tsx +31 -21
  42. package/src/utils/hooks/usePermalink.tsx +25 -0
  43. package/src/utils/translations.ts +4 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,42 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [0.1.66](https://github.com/geops/rvf-mobility-web-component/compare/v0.1.65...v0.1.66) (2025-10-15)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * add documentation for url paramters ([e759e58](https://github.com/geops/rvf-mobility-web-component/commit/e759e589105c7551819ca83df0b36769fb45a0b0))
11
+ * add documentation for url paramters ([b4083e2](https://github.com/geops/rvf-mobility-web-component/commit/b4083e2521fc10b445be9edd464b8e94d88dcf66))
12
+ * add documentation for url paramters ([6eb1629](https://github.com/geops/rvf-mobility-web-component/commit/6eb1629afda1afec9caddf1e0807546d70c434fd))
13
+ * add noapply url parameter documentation ([6e42a63](https://github.com/geops/rvf-mobility-web-component/commit/6e42a6307438989265b3546f4ca789c6ddf71662))
14
+ * fix layer config title display when there is not translation ([feba3da](https://github.com/geops/rvf-mobility-web-component/commit/feba3dafc92ad1e941899eb9de2e99ccaccf2b67))
15
+
16
+ ### [0.1.65](https://github.com/geops/rvf-mobility-web-component/compare/v0.1.64...v0.1.65) (2025-10-14)
17
+
18
+
19
+ ### Features
20
+
21
+ * add lines attribute ([#28](https://github.com/geops/rvf-mobility-web-component/issues/28)) ([3475b21](https://github.com/geops/rvf-mobility-web-component/commit/3475b2121f02997219821ea79fff71d289b37878))
22
+
23
+
24
+ ### Bug Fixes
25
+
26
+ * active docu permalink ([821ea85](https://github.com/geops/rvf-mobility-web-component/commit/821ea85d97f0c5c6f1ae8ca1394fd8152c2bb70a))
27
+ * add a container ([fae18ad](https://github.com/geops/rvf-mobility-web-component/commit/fae18ad2cd72fac8ac566d5dbf20e2ae2e05c7cd))
28
+ * add missing file ([5bcca16](https://github.com/geops/rvf-mobility-web-component/commit/5bcca16dcaf6bbc0ba80734149ed07ee79ea55d8))
29
+ * always read url parameters when a permalink template is set ([5636bce](https://github.com/geops/rvf-mobility-web-component/commit/5636bceb97b669328bf1e009370e91435a51d991))
30
+ * fix inout copy rendering ([b3da415](https://github.com/geops/rvf-mobility-web-component/commit/b3da41560a4a49ec0dea11710f4324b591471128))
31
+ * fix input copy ([1201c0c](https://github.com/geops/rvf-mobility-web-component/commit/1201c0c478dfb0d175c914c57916d1ff6698bf71))
32
+ * highlight hidden by default ([6882da0](https://github.com/geops/rvf-mobility-web-component/commit/6882da08563820c133dd2c132e0990054d0b33b7))
33
+ * make the layers permalink params work ([cf961b2](https://github.com/geops/rvf-mobility-web-component/commit/cf961b2ec5edfc6424baae4d7f43fd8866f26083))
34
+ * make the layers permalink params work ([0559bc8](https://github.com/geops/rvf-mobility-web-component/commit/0559bc8e6dee0859abc53f9d2a6d7d2d04c186b8))
35
+ * move rvf customs code in other components ([0fff2d7](https://github.com/geops/rvf-mobility-web-component/commit/0fff2d7c260e876dffa042966892796f35776de0))
36
+ * preserve drawing buffer when necessary ([5e4f199](https://github.com/geops/rvf-mobility-web-component/commit/5e4f19975b3dcc50cbc66b483143efdaa72b8cf0))
37
+ * read properly the layers url param ([926ddfd](https://github.com/geops/rvf-mobility-web-component/commit/926ddfd4bd1a62502994cd8d7ad60f7714483b40))
38
+ * remove default zoom attribute ([b45821a](https://github.com/geops/rvf-mobility-web-component/commit/b45821ad08ac39bc55e46e15b229f33d117fc646))
39
+ * set width in pixels to keep always the same size ([29ff7c9](https://github.com/geops/rvf-mobility-web-component/commit/29ff7c9142a3243809ad70b2cf827ed137e96f31))
40
+
5
41
  ### [0.1.64](https://github.com/geops/rvf-mobility-web-component/compare/v0.1.63...v0.1.64) (2025-10-14)
6
42
 
7
43
 
package/docutils.js CHANGED
@@ -1,4 +1,8 @@
1
- function onLoad(wc, attributes, events, pkgSrc) {
1
+ /* Will ignore web component attributes defined as url parameters */
2
+ const doNotApplyAttributesUrlParameters =
3
+ new URLSearchParams(window.location.search).get("noapply") === "true";
4
+
5
+ function onLoad(wc, attributes, events, pkgSrc, urlParameters = {}) {
2
6
  /* Show private attributes for dev purpose */
3
7
  const showPrivate =
4
8
  new URLSearchParams(window.location.search).get("private") === "true";
@@ -8,7 +12,7 @@ function onLoad(wc, attributes, events, pkgSrc) {
8
12
  const booleanAttrs = Object.entries(attributes)
9
13
  .filter(([, attr]) => attr.type === "boolean")
10
14
  .map(([key]) => key);
11
- const booleanTrueByDefault = booleanAttrs.filter(
15
+ const booleanTrueByDefaultAttrs = booleanAttrs.filter(
12
16
  (key) => attributes[key].defaultValue === "true",
13
17
  );
14
18
  const reloadAttrs = Object.entries(attributes)
@@ -35,6 +39,25 @@ function onLoad(wc, attributes, events, pkgSrc) {
35
39
  {},
36
40
  );
37
41
 
42
+ const attrsContent = generateAttributesTable(
43
+ wc,
44
+ attrs,
45
+ booleanAttrs,
46
+ booleanTrueByDefaultAttrs,
47
+ descriptionByAttr,
48
+ defaultValueByAttr,
49
+ reloadAttrs,
50
+ );
51
+
52
+ if (attrsContent) {
53
+ const elt = document.querySelector("#attributes");
54
+ if (elt) {
55
+ elt.innerHTML = attrsContent;
56
+ }
57
+ } else {
58
+ document.querySelector("#attributesDoc")?.remove();
59
+ }
60
+
38
61
  /* Events */
39
62
  const evts = Object.keys(events);
40
63
  const descriptionByEvent = Object.entries(events)
@@ -49,30 +72,66 @@ function onLoad(wc, attributes, events, pkgSrc) {
49
72
  return acc;
50
73
  }, {});
51
74
 
52
- /* Build HTML */
53
- const attrsContent = generateAttributesTable(
54
- wc,
55
- attrs,
56
- booleanAttrs,
57
- booleanTrueByDefault,
58
- descriptionByAttr,
59
- defaultValueByAttr,
60
- reloadAttrs,
61
- );
62
- console.log(attrsContent);
63
- if (attrsContent) {
64
- document.querySelector("#attributes").innerHTML = attrsContent;
75
+ const evtsContent = generateEventsTable(wc, evts, descriptionByEvent);
76
+ if (evtsContent) {
77
+ const elt = document.querySelector("#events");
78
+ if (elt) {
79
+ elt.innerHTML = evtsContent;
80
+ }
65
81
  } else {
66
- document.querySelector("#attributesDoc").remove();
82
+ document.querySelector("#eventsDoc")?.remove();
67
83
  }
68
84
 
69
- const evtsContent = generateEventsTable(wc, evts, descriptionByEvent);
70
- if (evtsContent) {
71
- document.querySelector("#events").innerHTML = evtsContent;
85
+ /* URL Parameters */
86
+ const params = Object.keys(urlParameters);
87
+ const booleanParams = Object.entries(urlParameters)
88
+ .filter(([, attr]) => attr.type === "boolean")
89
+ .map(([key]) => key);
90
+ const booleanTrueByDefaultParams = booleanParams.filter(
91
+ (key) => urlParameters[key].defaultValue === "true",
92
+ );
93
+ const reloadParams = Object.entries(urlParameters).map(([key]) => key);
94
+
95
+ const descriptionByParam = Object.entries(urlParameters)
96
+ .filter(([key, attr]) => {
97
+ if (showPrivate) {
98
+ return true;
99
+ }
100
+ return attr.public;
101
+ })
102
+ .reduce((acc, [key, attr]) => {
103
+ acc[key] = attr.description;
104
+ return acc;
105
+ }, {});
106
+
107
+ const defaultValueByParam = Object.entries(urlParameters).reduce(
108
+ (acc, [key, attr]) => {
109
+ acc[key] = attr.defaultValue;
110
+ return acc;
111
+ },
112
+ {},
113
+ );
114
+
115
+ const urlParamsContent = generateAttributesTable(
116
+ wc,
117
+ params,
118
+ booleanParams,
119
+ booleanTrueByDefaultParams,
120
+ descriptionByParam,
121
+ defaultValueByParam,
122
+ reloadParams,
123
+ );
124
+ if (urlParamsContent) {
125
+ const elt = document.querySelector("#urlParameters");
126
+ if (elt) {
127
+ elt.innerHTML = urlParamsContent;
128
+ }
72
129
  } else {
73
- document.querySelector("#eventsDoc").remove();
130
+ document.querySelector("#urlParamtersDoc")?.remove();
74
131
  }
75
132
 
133
+ /* Build HTML */
134
+
76
135
  document.querySelector("#code").innerHTML = generateCodeText(
77
136
  wc,
78
137
  attrs,
@@ -85,7 +144,7 @@ function onLoad(wc, attributes, events, pkgSrc) {
85
144
  pkgSrc,
86
145
  );
87
146
  });
88
- applyPermalinkParameters(wc);
147
+ applyPermalinkParameters(wc, attributes);
89
148
  evts.forEach((eventName) => {
90
149
  wc.addEventListener(eventName, (event) => {
91
150
  console.log(`${eventName} event`, event);
@@ -93,7 +152,7 @@ function onLoad(wc, attributes, events, pkgSrc) {
93
152
  });
94
153
  }
95
154
 
96
- function applyPermalinkParameters(wc) {
155
+ function applyPermalinkParameters(wc, attributes) {
97
156
  const params = new URLSearchParams(window.location.search);
98
157
 
99
158
  // Apply fullscreen mode
@@ -126,20 +185,26 @@ function applyPermalinkParameters(wc) {
126
185
  }
127
186
 
128
187
  // Apply all url parameters as attribute of the web component and fill the input fields.
129
- params.forEach((value, key) => {
130
- wc.setAttribute(key, value);
131
- const input = document.querySelector(`[name=${key}]`);
132
- if (input) {
133
- if (input.type === "checkbox") {
134
- input.checked = value !== "false";
135
- } else {
136
- input.value = value;
188
+ if (!doNotApplyAttributesUrlParameters) {
189
+ params.forEach((value, key) => {
190
+ if (!(key in attributes)) {
191
+ return;
137
192
  }
138
- }
139
- });
193
+ wc.setAttribute(key, value);
194
+
195
+ const input = document.querySelector(`[name=${key}]`);
196
+ if (input) {
197
+ if (input.type === "checkbox") {
198
+ input.checked = value !== "false";
199
+ } else {
200
+ input.value = value;
201
+ }
202
+ }
203
+ });
204
+ }
140
205
 
141
206
  // Get an apikey if there is none defined
142
- if (!wc.getAttribute("apikey")) {
207
+ if (!wc.getAttribute("apikey") && !attributes.apikey.defaultValue) {
143
208
  fetch("https://backend.developer.geops.io/publickey")
144
209
  .then((response) => {
145
210
  return response.json();
@@ -183,7 +248,11 @@ function generateAttributesTable(
183
248
  const defaultChecked = booleanTrueByDefault.includes(key)
184
249
  ? "checked"
185
250
  : "";
186
- const currValue = wc.getAttribute(key);
251
+ let currValue = wc.getAttribute(key);
252
+ const isUrlParameters = reloadAttrs?.includes(key);
253
+ if (isUrlParameters) {
254
+ currValue = new URLSearchParams(window.location.search).get(key);
255
+ }
187
256
  let checked = currValue === "true" ? "checked" : "";
188
257
  if (currValue !== "true" && currValue !== "false") {
189
258
  checked = defaultChecked;
@@ -193,28 +262,31 @@ function generateAttributesTable(
193
262
  <td class="border px-4 py-2">${key}</td>
194
263
  <!--td class="border px-4 py-2"></td>
195
264
  <td class="border px-4 py-2"></td-->
196
- <td class="border px-4 py-2">
197
- <div class="flex gap-4">
265
+ <td class="border px-4 py-2 space-y-2">
198
266
  ${
199
267
  isBoolean
200
268
  ? `<input
201
269
  type="checkbox"
202
- class="border"
270
+ id="${key}"
271
+ class="border mr-4 cursor-pointer inline-block"
203
272
  name="${key}"
204
273
  ${checked ? "checked" : ""}
205
274
  onchange="document.querySelector('${wc.localName}').setAttribute('${key}', this.checked);onAttributeUpdate(document.querySelector('${wc.localName}'),this.name, this.checked, '${reloadAttrs.join(",")}');"
206
275
  />`
207
276
  : `
208
- <input
209
- type="text"
210
- class="border"
211
- name="${key}"
212
- value="${wc.getAttribute(key) || defaultValueByAttr[key] || ""}"
213
- />
214
- <button class="border p-2 bg-black hover:bg-gray-700 text-white" onclick="document.querySelector('${wc.localName}').setAttribute('${key}', this.previousElementSibling.value);onAttributeUpdate(document.querySelector('${wc.localName}'),this.previousElementSibling.name, this.previousElementSibling.value, '${reloadAttrs.join(",")}');">Update</button>`
277
+ <div class="flex gap-4 mb-2">
278
+ <input
279
+ type="text"
280
+ class="border px-2"
281
+ name="${key}"
282
+ placeholder="${defaultValueByAttr[key] || ""}"
283
+ value="${wc.getAttribute(key) || defaultValueByAttr[key] || ""}"
284
+ />
285
+ <button class="border cursor-pointer p-2 bg-black hover:bg-gray-700 text-white" onclick="document.querySelector('${wc.localName}').setAttribute('${key}', this.previousElementSibling.value);onAttributeUpdate(document.querySelector('${wc.localName}'),this.previousElementSibling.name, this.previousElementSibling.value, '${reloadAttrs.join(",")}');">Update</button>
286
+ </div>`
215
287
  }
216
- </div>
217
- ${descriptionByAttr[key] ? `<div class="pt-2">${descriptionByAttr[key]}</div>` : ``}
288
+
289
+ ${descriptionByAttr[key] ? `<label for="${key}" class="cursor-pointer">${descriptionByAttr[key]}</label>` : ``}
218
290
  </td>
219
291
  </tr>
220
292
  `;
@@ -334,10 +406,12 @@ function onAttributeUpdate(wc, key, value, reloadAttrs) {
334
406
  window.location.reload();
335
407
  } else {
336
408
  wc.setAttribute(key, value);
337
- window.history.replaceState(
338
- {},
339
- "",
340
- `${window.location.pathname}?${params}`,
341
- );
409
+ if (!doNotApplyAttributesUrlParameters) {
410
+ window.history.replaceState(
411
+ {},
412
+ "",
413
+ `${window.location.pathname}?${params}`,
414
+ );
415
+ }
342
416
  }
343
417
  }
package/index.html CHANGED
@@ -34,7 +34,7 @@
34
34
  <body class="p-8">
35
35
  <!-- tailwind hack to add class used in docutils -->
36
36
  <div
37
- class="absolute inset-0 flex h-full w-full table-auto gap-4 flex-col border bg-black p-0 px-4 py-2 pt-2 text-white hover:bg-gray-700"
37
+ class="absolute inset-0 flex h-full w-full table-auto mr-4 gap-4 space-y-4 flex-col border bg-black p-0 px-4 py-2 pt-2 text-white hover:bg-gray-700"
38
38
  style="display: none"
39
39
  ></div>
40
40
  </script>
@@ -48,26 +48,38 @@
48
48
  id="code"
49
49
  class="overflow-auto rounded bg-slate-800 p-4 text-slate-200"
50
50
  ></pre>
51
-
52
51
  <geops-mobility
53
52
  id="map"
54
53
  class="block h-128 w-full resize overflow-hidden rounded-[16px] border"
55
54
  ></geops-mobility>
56
55
 
57
- <br />
58
- <div id="attributesDoc">
56
+ <div id="attributesDoc" class="space-y-4">
59
57
  <h2 class="text-xl font-bold">Attributes</h2>
58
+
59
+ <pre class="rounded bg-slate-800 p-4 text-slate-200">
60
+ // Modify an attribute
61
+ document.getElementById('map').setAttribute("zoom", "15");
62
+ </pre
63
+ >
60
64
  <div id="attributes"></div>
61
65
  </div>
62
- <div id="eventsDoc">
66
+ <div id="eventsDoc" class="space-y-4">
63
67
  <h2 class="text-xl font-bold">Events</h2>
64
68
  <pre class="rounded bg-slate-800 p-4 text-slate-200">
69
+ // Listen to an event
65
70
  document.getElementById('map').addEventListener('mwc:attribute', (event) => {
66
71
  console.log('Display last data received:', event.data);
67
- });</pre
72
+ });
73
+ </pre
68
74
  >
69
75
  <div id="events"></div>
70
76
  </div>
77
+
78
+ <div id="urlParametersDoc" class="space-y-4">
79
+ <h2 class="text-xl font-bold">Documentation URL parameters</h2>
80
+ <p>The following parameters are only used by this documentation webpage.</p>
81
+ <div id="urlParameters"></div>
82
+ </div>
71
83
  <br />
72
84
  <br />
73
85
  <h1 class="text-xl font-bold">More mobility web components</h1>
@@ -88,24 +100,39 @@ document.getElementById('map').addEventListener('mwc:attribute', (event) => {
88
100
  const events = window.MobilityMapEvents;
89
101
 
90
102
  // Add page parameters
91
- attributes.fullscreen = {
92
- type: "boolean",
93
- defaultValue: "false",
94
- description: `Load the page in fullscreen mode.`,
95
- reload: true,
96
- public: false,
97
- };
103
+ const urlParameters = {
104
+ fullscreen: {
105
+ type: "boolean",
106
+ defaultValue: "false",
107
+ description: `Load the map in fullscreen mode.`,
108
+ public: true,
109
+ },
110
+ noapply: {
111
+ type: "boolean",
112
+ defaultValue: "false",
113
+ description:
114
+ "Will not apply web component attributes defined as url parameters. Useful to test the permalink functionality of the web component.",
115
+ public: true,
116
+ },
117
+
118
+ debug: {
119
+ type: "boolean",
120
+ defaultValue: "false",
121
+ description:
122
+ "Displays debug information for vehicles when true, use only for debugging.",
123
+ public: true,
124
+ },
98
125
 
99
- attributes.debug = {
100
- type: "boolean",
101
- defaultValue: "false",
102
- description:
103
- "Displays debug information for vehicles when true, use only for debugging.",
104
- reload: true,
105
- public: false,
126
+ private: {
127
+ type: "boolean",
128
+ defaultValue: "false",
129
+ description:
130
+ "Displays all private attributes, if there are some, use only for development purpose.",
131
+ public: true,
132
+ },
106
133
  };
107
134
 
108
- onLoad(wc, attributes, events, pkgSrc);
135
+ onLoad(wc, attributes, events, pkgSrc, urlParameters);
109
136
  });
110
137
  </script>
111
138
  </body>