How to get text content of slot?

3.7k views Asked by At

We can have stencilJS element with slot as below

<my-component>123</my-component>

I'm trying to get the value of 123 from my render method itself, wondering if that is possible?

@Component({ tag: 'my-component' })
export class MyComponent {
  render() {
    return (
      <div><slot /></div>
    )
  }
}

I would like to do some string formatting on 123 instead of rendering slot directly

2

There are 2 answers

3
Jakub Zavazal On

import { Element } from '@stencil/core';

@Component({ tag: 'my-component' })
export class MyComponent {
  /**
   * Reference to host element
   */
  @Element() host: HTMLElement;

  componentWillRender() {
    console.log(this.host.innerHTML)
  }
  
  render() {
    return (
      <div><slot /></div>
    )
  }
}

0
Alexander On

In web components, the content inside of it is part of the main DOM, too. This content is not going to show if you don't use slots; but, the content is going to project next to the #shadow-root anyway (check it using the chrome developer tools in the "elements" section).

enter image description here

So, if you do not want to show the content using default slots, you can use the property decorator @Element() and declare a property of type HTMLElement:

Then, you can access to the content via innerHTML or innerText.

Finally, you can format the content. Check the code snippet bellow:

import { Component, Element, h } from "@stencil/core";
@Component({
    tag: 'my-component',
    styleUrl: 'my-component.css',
    shadow: true
})

export class MyComponent {
    @Element() element: HTMLElement;

    formatContent(content: any) {
        if ( isNaN(content)){
            // Your format here
            return content;
        } else {
            return content + '.00';
        }
    }
    render() {
        return [
            // Commented slot tag
            // <slot></slot>,
            <div> {this.formatContent(this.element.innerHTML)} </div>
        ];
    }
}

Using three times the web component with 2 strings and a number as a entry data, the result should be:

My text
My text 2
123.00