From 08a1bd974699b54316660c7d6d862dfa5b0da6d2 Mon Sep 17 00:00:00 2001 From: Olivier Terral Date: Fri, 10 Oct 2025 11:10:29 +0200 Subject: [PATCH 1/5] feat: add lines attribute --- src/LayoutState/LayoutState.tsx | 5 +++ .../LinesNetworkPlanLayerHighlight.tsx | 42 +++++++++---------- src/MobilityMap/MobilityMap.tsx | 16 +++++-- src/MobilityMap/MobilityMapAttributes.ts | 5 +++ src/OverlayDetails/OverlayDetails.tsx | 2 + src/utils/hooks/useMapContext.tsx | 2 + 6 files changed, 48 insertions(+), 24 deletions(-) diff --git a/src/LayoutState/LayoutState.tsx b/src/LayoutState/LayoutState.tsx index 78abfad3..484d4593 100644 --- a/src/LayoutState/LayoutState.tsx +++ b/src/LayoutState/LayoutState.tsx @@ -122,6 +122,7 @@ function LayoutState() { setStationId(null); setTrainId(null); setFeaturesInfos(null); + setLinesIds(null); } }, [ isSearchOpen, @@ -141,6 +142,7 @@ function LayoutState() { setStationId(null); setTrainId(null); setFeaturesInfos(null); + setLinesIds(null); } }, [ isShareMenuOpen, @@ -160,6 +162,7 @@ function LayoutState() { setFeaturesInfos(null); setTrainId(null); setStationId(null); + setLinesIds(null); setIsShareMenuOpen(false); } }, [ @@ -180,6 +183,7 @@ function LayoutState() { setIsSearchOpen(false); setFeaturesInfos(null); setTrainId(null); + setLinesIds(null); setIsShareMenuOpen(false); setStationId(null); } @@ -223,6 +227,7 @@ function LayoutState() { setIsSearchOpen(false); setTrainId(null); setIsShareMenuOpen(false); + setLinesIds(null); } }, [ setFeaturesInfos, diff --git a/src/LinesNetworkPlanLayerHighlight/LinesNetworkPlanLayerHighlight.tsx b/src/LinesNetworkPlanLayerHighlight/LinesNetworkPlanLayerHighlight.tsx index 3ea06a49..98e6ffc3 100644 --- a/src/LinesNetworkPlanLayerHighlight/LinesNetworkPlanLayerHighlight.tsx +++ b/src/LinesNetworkPlanLayerHighlight/LinesNetworkPlanLayerHighlight.tsx @@ -12,8 +12,15 @@ import useMapContext from "../utils/hooks/useMapContext"; import type { MaplibreStyleLayerOptions } from "mobility-toolbox-js/ol/layers/MaplibreStyleLayer"; function LinesNetworkPlanLayerHighlight(props: MaplibreStyleLayerOptions) { - const { baseLayer, featuresInfos, linesNetworkPlanLayer, map } = - useMapContext(); + const { + baseLayer, + featuresInfos, + lines, + linesIds, + linesNetworkPlanLayer, + map, + setLinesIds, + } = useMapContext(); const layer = useMemo(() => { if (!baseLayer) { @@ -42,7 +49,7 @@ function LinesNetworkPlanLayerHighlight(props: MaplibreStyleLayerOptions) { }, [map, layer]); useEffect(() => { - if (!layer || !featuresInfos || !linesNetworkPlanLayer) { + if (!layer || !featuresInfos?.length || !linesNetworkPlanLayer) { return; } const features = @@ -50,11 +57,6 @@ function LinesNetworkPlanLayerHighlight(props: MaplibreStyleLayerOptions) { return featuresInfo.layer === linesNetworkPlanLayer; })?.features || []; - if (features?.length) { - layer.setVisible(true); - } else { - layer.setVisible(false); - } const ids = [ ...new Set( (features || []).map((f) => { @@ -62,26 +64,24 @@ function LinesNetworkPlanLayerHighlight(props: MaplibreStyleLayerOptions) { }), ), ]; + setLinesIds(ids); + }, [featuresInfos, layer, linesNetworkPlanLayer, setLinesIds]); - try { - highlightLinesNetworkPlan(ids, baseLayer); - } catch (e) { - // eslint-disable-next-line no-console - console.error("Error setting filter for highlight layer", e); + useEffect(() => { + if (!layer || !baseLayer?.loaded) { + return; + } + if (linesIds?.length) { + highlightLinesNetworkPlan(linesIds, baseLayer); + layer.setVisible(true); } - return () => { layer?.setVisible(false); // Reset the filter highlightLinesNetworkPlan(undefined, baseLayer); }; - }, [ - baseLayer, - baseLayer?.mapLibreMap, - featuresInfos, - layer, - linesNetworkPlanLayer, - ]); + }, [baseLayer, baseLayer?.loaded, layer, lines, linesIds]); + return null; } diff --git a/src/MobilityMap/MobilityMap.tsx b/src/MobilityMap/MobilityMap.tsx index b7cebb24..414a670c 100644 --- a/src/MobilityMap/MobilityMap.tsx +++ b/src/MobilityMap/MobilityMap.tsx @@ -87,6 +87,8 @@ function MobilityMap(props: MobilityMapProps) { const [map, setMap] = useState(); const [stationId, setStationId] = useState(); const [trainId, setTrainId] = useState(); + const [linesIds, setLinesIds] = useState(); + const [featuresInfos, setFeaturesInfos] = useState< LayerGetFeatureInfoResponse[] >([]); @@ -101,7 +103,7 @@ function MobilityMap(props: MobilityMapProps) { const [previewNotifications, setPreviewNotifications] = useState(); - const { lang, layers } = props; + const { lang, layers, lines } = props; // Apply initial visibility of layers useInitialLayersVisiblity(map, layers); @@ -136,6 +138,7 @@ function MobilityMap(props: MobilityMapProps) { isSearchOpen, isShareMenuOpen, isTracking, + linesIds, linesNetworkPlanLayer, map, mapsetLayer, @@ -169,6 +172,7 @@ function MobilityMap(props: MobilityMapProps) { setIsSearchOpen, setIsShareMenuOpen, setIsTracking, + setLinesIds, setLinesNetworkPlanLayer, setMap, setMapsetLayer, @@ -195,7 +199,6 @@ function MobilityMap(props: MobilityMapProps) { featuresInfos, featuresInfosHovered, hasDetails, - hasStations, hasGeolocation, hasLayerTree, hasLnp, @@ -206,6 +209,7 @@ function MobilityMap(props: MobilityMapProps) { hasRealtime, hasSearch, hasShare, + hasStations, hasToolbar, isEmbed, isExportMenuOpen, @@ -215,10 +219,11 @@ function MobilityMap(props: MobilityMapProps) { isSearchOpen, isShareMenuOpen, isTracking, + linesIds, linesNetworkPlanLayer, map, - notificationsLayer, mapsetLayer, + notificationsLayer, permalinkUrlSearchParams, previewNotifications, realtimeLayer, @@ -234,6 +239,11 @@ function MobilityMap(props: MobilityMapProps) { useEffect(() => { i18n.locale(lang); }, [lang]); + + useEffect(() => { + setLinesIds(lines?.split(",")); + }, [lines]); + return ( {/* There is a bug in tailwindcss@4 , variables are not imported in the shadow dom diff --git a/src/MobilityMap/MobilityMapAttributes.ts b/src/MobilityMap/MobilityMapAttributes.ts index b2e7755a..def6f643 100644 --- a/src/MobilityMap/MobilityMapAttributes.ts +++ b/src/MobilityMap/MobilityMapAttributes.ts @@ -32,6 +32,7 @@ export type MobilityMapAttributeName = | "layers" | "layersconfig" | "layertree" + | "lines" | "lnp" | "mapset" | "mapsetbbox" @@ -152,6 +153,10 @@ where: public: true, type: "boolean", }, + lines: { + description: `A comma separated list of line ids to highlight on the linesnetworkplan layer. The line ids are the original_line_id property of the lines in the network plan.
Ex: S1,RE10,RE1.`, + public: false, + }, lnp: { defaultValue: "false", description: `Add the linesnetworkplans layer to the map. This layer will display lines network plans on the map.`, diff --git a/src/OverlayDetails/OverlayDetails.tsx b/src/OverlayDetails/OverlayDetails.tsx index 9bc88e06..f855789f 100644 --- a/src/OverlayDetails/OverlayDetails.tsx +++ b/src/OverlayDetails/OverlayDetails.tsx @@ -16,6 +16,7 @@ function OverlayDetails() { realtimeLayer, selectedFeature, setFeaturesInfos, + setLinesIds, setStationId, setTrainId, stationId, @@ -51,6 +52,7 @@ function OverlayDetails() { setFeaturesInfos(null); setTrainId(null); setStationId(null); + setLinesIds(null); }} /> void; setIsShareMenuOpen: (isShareMenuOpen: boolean) => void; setIsTracking: (isTracking: boolean) => void; + setLinesIds: (linesIds: string[]) => void; setLinesNetworkPlanLayer: (layer?: MaplibreStyleLayer) => void; setMap: (map?: Map) => void; setMapsetLayer: (mapsetLayer?: MapsetLayer) => void; From b703a0fa06a9de6ee647ce2edb3e082037abc131 Mon Sep 17 00:00:00 2001 From: Olivier Terral Date: Fri, 10 Oct 2025 14:06:18 +0200 Subject: [PATCH 2/5] fix: fix demo --- docutils.js | 103 ++++++++++++++++++++++++- index.html | 130 +++++++------------------------- src/LayoutState/LayoutState.tsx | 6 ++ 3 files changed, 135 insertions(+), 104 deletions(-) diff --git a/docutils.js b/docutils.js index 38120cc6..04b1bebd 100644 --- a/docutils.js +++ b/docutils.js @@ -1,4 +1,97 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ +function onLoad(wc, attributes, events, pkgSrc) { + /* Show private attributes for dev purpose */ + const showPrivate = + new URLSearchParams(window.location.search).get("private") === "true"; + + /* Attributes */ + const attrs = Object.keys(attributes); + const booleanAttrs = Object.entries(attributes) + .filter(([, attr]) => attr.type === "boolean") + .map(([key]) => key); + const booleanTrueByDefault = booleanAttrs.filter( + (key) => attributes[key].defaultValue === "true", + ); + const reloadAttrs = Object.entries(attributes) + .filter(([key, attr]) => !!attr.reload) + .map(([key]) => key); + + const descriptionByAttr = Object.entries(attributes) + .filter(([key, attr]) => { + if (showPrivate) { + return true; + } + return attr.public; + }) + .reduce((acc, [key, attr]) => { + acc[key] = attr.description; + return acc; + }, {}); + + const defaultValueByAttr = Object.entries(attributes).reduce( + (acc, [key, attr]) => { + acc[key] = attr.defaultValue; + return acc; + }, + {}, + ); + + /* Events */ + const evts = Object.keys(events); + const descriptionByEvent = Object.entries(events) + .filter(([key, attr]) => { + if (showPrivate) { + return true; + } + return attr.public; + }) + .reduce((acc, [key, attr]) => { + acc[key] = attr.description; + return acc; + }, {}); + + /* Build HTML */ + const attrsContent = generateAttributesTable( + wc, + attrs, + booleanAttrs, + booleanTrueByDefault, + descriptionByAttr, + defaultValueByAttr, + reloadAttrs, + ); + if (attrsContent) { + document.querySelector("#attributes").innerHTML = attrsContent; + } else { + document.querySelector("#attributesDoc").remove(); + } + + const evtsContent = generateEventsTable(wc, evts, descriptionByEvent); + if (evtsContent) { + document.querySelector("#events").innerHTML = evtsContent; + } else { + document.querySelector("#eventsDoc").remove(); + } + + document.querySelector("#code").innerHTML = generateCodeText( + wc, + attrs, + pkgSrc, + ); + wc.addEventListener("mwc:attribute", (event) => { + document.querySelector("#code").innerHTML = generateCodeText( + wc, + attrs, + pkgSrc, + ); + }); + applyPermalinkParameters(wc); + evts.forEach((eventName) => { + wc.addEventListener(eventName, (event) => { + console.log(`${eventName} event`, event); + }); + }); +} + function applyPermalinkParameters(wc) { const params = new URLSearchParams(window.location.search); @@ -68,6 +161,9 @@ function generateAttributesTable( defaultValueByAttr = {}, reloadAttrs = [], ) { + if (!attrs?.length) { + return null; + } let innerHMTL = ` @@ -139,7 +235,7 @@ function generateCodeText( let codeText = ""; codeText = `<script\n\ttype="module"\n\tsrc="${pkgSrc}"> </script> -<${wc.localName}\n\tid="map"\n\tstyle="display:block;width:100%;height:500px;border:1px solid #e5e7eb;border-radius:16px;"`; +<${wc.localName}${wc.id ? '\n\tid="' + wc.id + '"' : ""}\n\tstyle="display:block;width:100%;height:500px;border:1px solid #e5e7eb;border-radius:16px;"`; attrs.forEach((key) => { const attributeValue = wc.getAttribute(key); @@ -166,6 +262,9 @@ function generateCodeText( // Generates a HTML table with all events of a web component function generateEventsTable(wc, events, descriptionByEvent = {}) { + if (!events?.length) { + return null; + } let innerHMTL = `
diff --git a/index.html b/index.html index 1ddc6bc5..e9b46187 100644 --- a/index.html +++ b/index.html @@ -46,19 +46,24 @@

Usage example

>
-

Attributes

-
-

Events

-
+      
+

Attributes

+
+
+
+

Events

+
 document.getElementById('map').addEventListener('mwc:attribute', (event) => {
   console.log('Display last data received:', event.data);
 });
-
+ > +
+


More mobility web components

@@ -74,141 +79,62 @@

More mobility web components

const pkgSrc = "https://www.unpkg.com/@geops/mobility-web-component"; const wc = document.querySelector("geops-mobility"); - window.addEventListener("load", () => { const attributes = window.MobilityMapAttributes; const events = window.MobilityMapEvents || { "mwc:selectedfeature": { description: "Event fired when a feature is selected on the map. The event data contains the selected feature in GeoJSON format.", - public:true - }, + public: true, + }, "mwc:stopssearchselect": { description: "Only when search attribute is 'true'. Event fired when a stop is selected in the stops search results. The event data contains the selected stop.", - public:true - - }, + public: true, + }, "mwc:attribute": { description: "Event fired when an web component's attribute is changed. The event data contains the list of all attributes and their values.", - public:true - - }, + public: true, + }, "mwc:singleclick": { description: "Event fired when the map is clicked. The event data contains the map coordinates in EPSG:3857 and the pixel coordinates.", - public:true - - }, + public: true, + }, "mwc:permalink": { description: "Event fired when the map's state changes. The event data contains the permalink URL search parameters as string.", - public:true - - }, + public: true, + }, "mwc:messageready": { description: "Only if the web-component is embedded in an iframe. Message event fired when the web component is ready to receive messages from parent window.", - public:true - }, + public: true, + }, }; - - // Add special parameters attributes.fullscreen = { type: "boolean", defaultValue: "false", description: `Load the page in fullscreen mode.`, reload: true, - public:false, + public: false, }; attributes.debug = { type: "boolean", defaultValue: "false", - description: "Displays debug information for vehicles when true, use only for debugging.", + description: + "Displays debug information for vehicles when true, use only for debugging.", reload: true, - public:false, + public: false, }; - /* Show private attributes for dev purpose */ - const showPrivate = new URLSearchParams(window.location.search).get("private") === "true"; - - /* Attributes */ - const attrs = Object.keys(attributes); - const booleanAttrs = Object.entries(attributes) - .filter(([, attr]) => attr.type === "boolean") - .map(([key]) => key); - const booleanTrueByDefault = booleanAttrs.filter( - (key) => attributes[key].defaultValue === "true", - ); - const reloadAttrs = Object.entries(attributes) - .filter(([key, attr]) => !!attr.reload) - .map(([key]) => key); - - const descriptionByAttr = Object.entries(attributes).filter(([key, attr]) => { - if (showPrivate) { - return true; - } - return attr.public; - }).reduce((acc, [key, attr]) => { - acc[key] = attr.description; - return acc; - }, {}); - - const defaultValueByAttr = Object.entries(attributes).reduce((acc, [key, attr]) => { - acc[key] = attr.defaultValue; - return acc; - }, {}); - /* Events */ - const evts = Object.keys(events); - const descriptionByEvent = Object.entries(events).filter(([key, attr]) => { - if (showPrivate) { - return true; - } - return attr.public; - }).reduce((acc, [key, attr]) => { - acc[key] = attr.description; - return acc; - }, {}); - - document.querySelector("#attributes").innerHTML = - generateAttributesTable( - wc, - attrs, - booleanAttrs, - booleanTrueByDefault, - descriptionByAttr, - defaultValueByAttr, - reloadAttrs, - ); - document.querySelector("#events").innerHTML = generateEventsTable( - wc, - evts, - descriptionByEvent, - ); - document.querySelector("#code").innerHTML = generateCodeText( - wc, - attrs, - pkgSrc, - ); - wc.addEventListener("mwc:attribute", (event) => { - document.querySelector("#code").innerHTML = generateCodeText( - wc, - attrs, - pkgSrc, - ); - }); - applyPermalinkParameters(wc); - evts.forEach((eventName) => { - wc.addEventListener(eventName, (event) => { - console.log(`${eventName} event`, event); - }); - }); + onLoad(wc, attributes, events, pkgSrc); }); diff --git a/src/LayoutState/LayoutState.tsx b/src/LayoutState/LayoutState.tsx index 484d4593..f83d4c05 100644 --- a/src/LayoutState/LayoutState.tsx +++ b/src/LayoutState/LayoutState.tsx @@ -49,6 +49,7 @@ function LayoutState() { setIsOverlayOpen, setIsSearchOpen, setIsShareMenuOpen, + setLinesIds, setStationId, setTrainId, share, @@ -130,6 +131,7 @@ function LayoutState() { setIsExportMenuOpen, setIsLayerTreeOpen, setIsShareMenuOpen, + setLinesIds, setStationId, setTrainId, ]); @@ -150,6 +152,7 @@ function LayoutState() { setIsExportMenuOpen, setIsLayerTreeOpen, setIsSearchOpen, + setLinesIds, setStationId, setTrainId, ]); @@ -172,6 +175,7 @@ function LayoutState() { setIsLayerTreeOpen, setIsSearchOpen, setIsShareMenuOpen, + setLinesIds, setStationId, setTrainId, ]); @@ -194,6 +198,7 @@ function LayoutState() { setIsLayerTreeOpen, setIsSearchOpen, setIsShareMenuOpen, + setLinesIds, setStationId, setTrainId, ]); @@ -235,6 +240,7 @@ function LayoutState() { setIsLayerTreeOpen, setIsSearchOpen, setIsShareMenuOpen, + setLinesIds, setTrainId, stationId, ]); From f1fe7d4faebaa564e63a336b71e49cd5741fb10b Mon Sep 17 00:00:00 2001 From: Olivier Terral Date: Fri, 10 Oct 2025 14:22:27 +0200 Subject: [PATCH 3/5] docs: improve docs --- index.html | 37 ++----------------------- search.html | 72 ++++++++----------------------------------------- src/indexDoc.ts | 23 +++++++++++++--- 3 files changed, 33 insertions(+), 99 deletions(-) diff --git a/index.html b/index.html index e9b46187..f73940ae 100644 --- a/index.html +++ b/index.html @@ -81,41 +81,9 @@

More mobility web components

window.addEventListener("load", () => { const attributes = window.MobilityMapAttributes; - const events = window.MobilityMapEvents || { - "mwc:selectedfeature": { - description: - "Event fired when a feature is selected on the map. The event data contains the selected feature in GeoJSON format.", - public: true, - }, - "mwc:stopssearchselect": { - description: - "Only when search attribute is 'true'. Event fired when a stop is selected in the stops search results. The event data contains the selected stop.", - public: true, - }, - "mwc:attribute": { - description: - "Event fired when an web component's attribute is changed. The event data contains the list of all attributes and their values.", - public: true, - }, - "mwc:singleclick": { - description: - "Event fired when the map is clicked. The event data contains the map coordinates in EPSG:3857 and the pixel coordinates.", - public: true, - }, - "mwc:permalink": { - description: - "Event fired when the map's state changes. The event data contains the permalink URL search parameters as string.", - public: true, - }, - "mwc:messageready": { - description: - "Only if the web-component is embedded in an iframe. Message event fired when the web component is ready to receive messages from parent window.", + const events = window.MobilityMapEvents; - public: true, - }, - }; - - // Add special parameters + // Add page parameters attributes.fullscreen = { type: "boolean", defaultValue: "false", @@ -133,7 +101,6 @@

More mobility web components

public: false, }; - onLoad(wc, attributes, events, pkgSrc); }); diff --git a/search.html b/search.html index 1911b2bf..67d3f38a 100644 --- a/search.html +++ b/search.html @@ -58,6 +58,7 @@

Usage example


 
       More mobility web components
 
       window.addEventListener("load", () => {
 
+        const attributes = window.MobilitySearchAttributes;
+        const events = window.MobilitySearchEvents;
+ const descriptionByEvent = {
+          "mwc:stopssearchselect":
+            "Only when search attribute is 'true'. Event fired when a stop is selected in the stops search results. The event data contains the selected stop.",
+          "mwc:attribute":
+            "Event fired when an web component's attribute is changed. The event data contains the list of all attributes and their values.",
+        };
+
         // Add special parameters
         window.MobilityMapAttributes.fullscreen = {
           type: "boolean",
@@ -93,67 +103,7 @@ 

More mobility web components

reload: true, }; - /* Attributes */ - const attrs = Object.keys(MobilitySearchAttributes); - const booleanAttrs = Object.entries(MobilitySearchAttributes) - .filter(([, attr]) => attr.type === "boolean") - .map(([key]) => key); - const booleanTrueByDefault = booleanAttrs.filter( - (key) => MobilitySearchAttributes[key].defaultValue === "true", - ); - const reloadAttrs = Object.entries(MobilitySearchAttributes) - .filter(([key, attr]) => !!attr.reload) - .map(([key]) => key); - - const descriptionByAttr = Object.entries(MobilitySearchAttributes).reduce((acc, [key, attr]) => { - acc[key] = attr.description; - return acc; - }, {}); - - /* Events */ - const events = [ - "mwc:stopssearchselect", - "mwc:attribute", - ]; - const descriptionByEvent = { - "mwc:stopssearchselect": - "Only when search attribute is 'true'. Event fired when a stop is selected in the stops search results. The event data contains the selected stop.", - "mwc:attribute": - "Event fired when an web component's attribute is changed. The event data contains the list of all attributes and their values.", - }; - - document.querySelector("#attributes").innerHTML = - generateAttributesTable( - wc, - attrs, - booleanAttrs, - booleanTrueByDefault, - descriptionByAttr, - reloadAttrs, - ); - document.querySelector("#events").innerHTML = generateEventsTable( - wc, - events, - descriptionByEvent, - ); - document.querySelector("#code").innerHTML = generateCodeText( - wc, - attrs, - pkgSrc, - ); - wc.addEventListener("mwc:attribute", (event) => { - document.querySelector("#code").innerHTML = generateCodeText( - wc, - attrs, - pkgSrc, - ); - }); - applyPermalinkParameters(wc); - events.forEach((eventName) => { - wc.addEventListener(eventName, (event) => { - console.log(`${eventName} event`, event); - }); - }); + onLoad(wc, attributes, events, pkgSrc); }); diff --git a/src/indexDoc.ts b/src/indexDoc.ts index 60313852..78eca892 100644 --- a/src/indexDoc.ts +++ b/src/indexDoc.ts @@ -1,13 +1,30 @@ // This file contains what we need to build the documentation in the index.html file import MobilityMapAttributes from "./MobilityMap/MobilityMapAttributes"; +import MobilityMapEvents from "./MobilityMap/MobilityMapEvents"; import MobilitySearchAttributes from "./MobilitySearch/MobilitySearchAttributes"; +import MobilitySearchEvents from "./MobilitySearch/MobilitySearchEvents"; + +declare global { + interface Window { + MobilityMapAttributes?: typeof MobilityMapAttributes; + MobilityMapEvents?: typeof MobilityMapEvents; + MobilitySearchAttributes?: typeof MobilitySearchAttributes; + MobilitySearchEvents?: typeof MobilitySearchEvents; + } +} if (typeof window !== "undefined") { - // @ts-expect-error it's wanted window.MobilityMapAttributes = MobilityMapAttributes; - // @ts-expect-error it's wanted + window.MobilityMapEvents = MobilityMapEvents; + window.MobilitySearchAttributes = MobilitySearchAttributes; + window.MobilitySearchEvents = MobilitySearchEvents; } -export default { MobilityMapAttributes, MobilitySearchAttributes }; +export default { + MobilityMapAttributes, + MobilityMapEvents, + MobilitySearchAttributes, + MobilitySearchEvents, +}; From f9fb0af7154af121bf0105a75c5b01eb77757d64 Mon Sep 17 00:00:00 2001 From: Olivier Terral Date: Fri, 10 Oct 2025 14:23:01 +0200 Subject: [PATCH 4/5] docs: improve docs --- src/MobilityMap/MobilityMapEvents.ts | 53 ++++++++++++++++++++++ src/MobilitySearch/MobilitySearchEvents.ts | 21 +++++++++ 2 files changed, 74 insertions(+) create mode 100644 src/MobilityMap/MobilityMapEvents.ts create mode 100644 src/MobilitySearch/MobilitySearchEvents.ts diff --git a/src/MobilityMap/MobilityMapEvents.ts b/src/MobilityMap/MobilityMapEvents.ts new file mode 100644 index 00000000..d9677757 --- /dev/null +++ b/src/MobilityMap/MobilityMapEvents.ts @@ -0,0 +1,53 @@ +export interface WebComponentEventDoc { + description: string; + public?: boolean; +} + +export type MobilityMapEventName = + | "mwc:attribute" + | "mwc:messageready" + | "mwc:permalink" + | "mwc:selectedfeature" + | "mwc:singleclick" + | "mwc:stopssearchselect"; + +export type MobilityMapEvents = Record< + MobilityMapEventName, + WebComponentEventDoc +>; + +const attrs: MobilityMapEvents = { + "mwc:attribute": { + description: + "Event fired when an web component's attribute is changed. The event data contains the list of all attributes and their values.", + public: true, + }, + "mwc:messageready": { + description: + "Only if the web-component is embedded in an iframe. Message event fired when the web component is ready to receive messages from parent window.", + + public: true, + }, + "mwc:permalink": { + description: + "Event fired when the map's state changes. The event data contains the permalink URL search parameters as string.", + public: true, + }, + "mwc:selectedfeature": { + description: + "Event fired when a feature is selected on the map. The event data contains the selected feature in GeoJSON format.", + public: true, + }, + "mwc:singleclick": { + description: + "Event fired when the map is clicked. The event data contains the map coordinates in EPSG:3857 and the pixel coordinates.", + public: true, + }, + "mwc:stopssearchselect": { + description: + "Only when search attribute is 'true'. Event fired when a stop is selected in the stops search results. The event data contains the selected stop.", + public: true, + }, +}; + +export default attrs; diff --git a/src/MobilitySearch/MobilitySearchEvents.ts b/src/MobilitySearch/MobilitySearchEvents.ts new file mode 100644 index 00000000..0de3d8f9 --- /dev/null +++ b/src/MobilitySearch/MobilitySearchEvents.ts @@ -0,0 +1,21 @@ +import MobilityMapEvents from "../MobilityMap/MobilityMapEvents"; + +import type { WebComponentEventDoc } from "../MobilityMap/MobilityMapEvents"; + +export type MobilitySearchEventName = "mwc:attribute" | "mwc:stopssearchselect"; + +export type MobilitySearchAttributes = Record< + MobilitySearchEventName, + WebComponentEventDoc +>; + +const attrs: MobilitySearchAttributes = { + "mwc:attribute": MobilityMapEvents["mwc:attribute"], + "mwc:stopssearchselect": { + description: + "Event fired when a stop is selected in the stops search results. The event data contains the selected stop.", + public: true, + }, +}; + +export default attrs; From ecefe6607d5430baf7964aeadf36f0660416c9f1 Mon Sep 17 00:00:00 2001 From: Olivier Terral Date: Fri, 10 Oct 2025 14:24:00 +0200 Subject: [PATCH 5/5] docs: improve docs --- docutils.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docutils.js b/docutils.js index 04b1bebd..74034519 100644 --- a/docutils.js +++ b/docutils.js @@ -208,8 +208,7 @@ function generateAttributesTable( type="text" class="border" name="${key}" - value="${wc.getAttribute(key) || ""}" - placeholder="${defaultValueByAttr[key] || ""}" + value="${wc.getAttribute(key) || defaultValueByAttr[key] || ""}" /> ` }