Map component draft work
initial commit of directory for gcds-map component
Dynamically render layers based on passed props
Add gcds-map-layer, update gcds-map to use it. Update index.html with example map. Need to figure out how to get a storybook together.
Update gcds-map.stories.tsx
Add dependency on @maps4html/mapml
Updates for gcds-map
Remove dep on npm @maps4html/mapml
Summary | Résumé
1-3 sentence description of the changed you're proposing, including a link to a GitHub Issue # or Trello card if applicable.
Description en 1 à 3 phrases de la modification proposée, avec un lien vers le problème (« issue ») GitHub ou la fiche Trello, le cas échéant.
Test instructions | Instructions pour tester la modification
Sequential steps (1., 2., 3., ...) that describe how to test this change. This will help a developer test things out without too much detective work. Also, include any environmental setup steps that aren't in the normal README steps and/or any time-based elements that this requires.
Étapes consécutives (1., 2., 3., …) qui décrivent la façon de tester la modification. Elles aideront les développeurs à faire des tests sans avoir à jouer au détective. Veuillez aussi inclure toutes les étapes de configuration de l’environnement qui ne font pas partie des étapes normales dans le fichier README et tout élément temporel requis.
Hey @prushforth. Thanks for the PR to add more context to the email.
I took a look at the code this afternoon and there seems to be some other issues with the current code that are not mentioned. It appears with the current setup all the gcds packages won't build, mainly the @cdssnc/gcds-components-react-ssr package, so we will have to find an alternative for importing the needed files.
I made some modifications to the gcds-map.tsx file to try something different. Now I don't know if this is the best way forward, that is something we can discuss all together, but it will hopefully let you continue with setting up storybook. See code below:
import { Component, Element, h, Prop, Host } from '@stencil/core';
// import 'https://cdn.jsdelivr.net/npm/@maps4html/mapml/dist/mapml-viewer.js'; // Import mapml-viewer
@Component({
tag: 'gcds-map',
styleUrl: 'gcds-map.css',
shadow: true,
})
export class GcdsMap {
@Element() el: HTMLElement;
// <mapml-viewer> attributes
@Prop() lat: number;
@Prop() lon: number;
@Prop() zoom: number;
@Prop() projection: string = 'OSMTILE'; // Default projection
@Prop() controls: boolean = true;
@Prop() controlslist: string;
// Add width and height props to allow setting dimensions at design time
@Prop() width: string = '100%'; // Allow setting width of the map
@Prop() height: string = '400px'; // Allow setting height of the map
componentDidLoad() {
// Apply width and height as CSS variables
this.el.style.setProperty('--map-width', this.width);
this.el.style.setProperty('--map-height', this.height);
// Handle <layer-> readiness once the map is rendered
this.handleLayerReady();
}
handleLayerReady() {
// Wait for the 'layer-' custom element to be defined
customElements.whenDefined('layer-').then(() => {
// Find all <layer-> elements inside the mapml-viewer
const layers = Array.from(this.el.shadowRoot.querySelectorAll('layer-'));
layers.forEach(layer => {
// Now we know the <layer-> element is fully defined, call whenReady()
(layer as any).whenReady().then(() => {
// Check for <map-extent> in the layer's shadow DOM and add 'checked' attribute
// this is necessary only for geogratis MapML resources, but harmless
// otherwise (unless someone wanted to have an unchecked sublayer, for
// some reason (it is possible, but maybe not useful).
const mapExtent = layer.shadowRoot?.querySelector('map-extent');
if (mapExtent && !mapExtent.hasAttribute('checked')) {
mapExtent.setAttribute('checked', 'true');
}
});
});
});
}
render() {
// Find the <gcds-map-layer> children inside the light DOM
const layers = Array.from(this.el.querySelectorAll('gcds-map-layer'));
return (
<Host>
<mapml-viewer
lat={this.lat}
lon={this.lon}
zoom={this.zoom}
projection={this.projection}
controls={this.controls ? true : undefined}
controlslist={this.controlslist} // Pass the controlslist to mapml-viewer
>
{layers.map(layer => (
<layer-
label={layer.getAttribute('label')}
src={layer.getAttribute('src')}
checked={
layer.getAttribute('checked') === 'true' ? 'checked' : undefined
}
opacity={layer.getAttribute('opacity')} // Pass the opacity to the <layer-> element
></layer->
))}
</mapml-viewer>
<script type="module" src="https://cdn.jsdelivr.net/npm/@maps4html/mapml/dist/mapml-viewer.js"></script>
</Host>
);
}
}
I mainly just added a Host element around the rendered code and made the js files import through a
To get storybook, it now should be just trying to match how we have it setup with our components. Matching the properties on Meta and using Canvas over Story.
Hopefully this helps!
hi @ethanWallace and thank you I'm certain this will unblock me. I will take a closer look tomorrow!
Closing in favour of going with #759