...
/Using Custom Components in Stencil Applications
Using Custom Components in Stencil Applications
Learn how to implement a custom image-gallery-component Stencil component and preview it in a Stencil application.
The image gallery component
Let’s implement a custom image gallery component and use it in a Stencil application.
image-gallery-component.tsx
This component will be used to perform the following tasks:
- Retrieve remote JSON data and parse it for rendering
- Listen for selected images and render the captured data to the DOM
- Create a new
<mi-image>
component to display each image and its data
Although it is a little more involved than our image-component.tsx
file, the functionality is relatively lightweight to implement thanks to both the Stencil API methods and the Fetch API that we’ll be making use of.
In the src/components/image-gallery-component/image-gallery-component.tsx
component class, make the following amendments (highlighted):
/*** ImageGalleryComponent** This class generates an image gallery of thumbnails (using the <mi-image> component) and a* 'writeable' panel for rendering selected image information to*/import { Component, Host, h, Listen, Prop, State } from '@stencil/core';@Component({tag: 'mi-gallery',styleUrl: 'image-gallery-component.css',shadow: true,})export class ImageGalleryComponent {@Prop() items: Array<any>;@State() heading: string;@State() description: string;/*** Uses Stencil's componentWillLoad lifecycle hook to trigger a call to* a remote URL - using the Fetch API - to retrieve/parse JSON data that* will be used to populate each <mi-image> component with*/componentWillLoad(): Promise<any> {return fetch('https://masteringionic.com/project-examples/technologies/images.json').then(response => response.json()).then(data => {console.dir(data);this.items = data.items;}).catch(error => {console.dir(error);});}/*** Listens for broadcasts through the onSelection event (that was declared in the <mi-image>)* component*/@Listen('selection', { capture: true })write(ev) {// Here we update the state properties that we defined earlier - assigning them the// broadcast image name and descriptionthis.heading = ev.detail.heading;this.description = ev.detail.description;}/*** Renders a component tree consisting of the <mi-image> web components with data assigned, via* looping through the items array, to their title, image and description attributes as well as* an information panel where the heading and descriptive content of a selected image are displayed*/render() {return (<Host><section class="panel"><section class="gallery">{ this.items.map((item: any) =><section class="image"><mi-image heading={ item.name } image={ item.image } description={ item.description }></mi-image></section>)}</section><section class="information"><h2>{ this.heading }</h2><p>{ this.description }</p></section></section></Host>);}}
Let’s break this down in a little more detail to understand what is happening at each stage of the component logic.
We begin, as is standard for all TypeScript classes, with importing the necessary modules that we’ll be using, especially the State module (which allows internal data to be modified within the component, but disallows ...