Using web components in react with only a CDN

Viewed 862

I have a customer who has a whole library of ui elements they want us to use. They have these javascript and css files hosted on a CDN. I have no access to the source code. The only thing i have is a set of script tags for my index.html file.

<script type="module" crossorigin="anonymous" cross src="https://design.customerName.no/assets/DesignSystemName.esm.min.js"></script>
<script nomodule src="https://design.customerName.no/assets/DesignSystemName.es5.min.js"></script>

<script type="module" crossorigin="anonymous" src="https://design.customerName.no/assets/DesignSystemName-webcomponents/DesignSystemName-webcomponents.esm.js"></script>
<script nomodule src="https://design.customerName.no/assets/DesignSystemName-webcomponents/DesignSystemName-webcomponents.js"></script>

Now i want to use certain WebComponents from this library in my react code. So far the only way i have been able to use them is to simply write pure html as a string and inject that html into a react component. like so

import React from 'react';
    
const body = `
  <webcomponent-tab-panel titles="title1, title2">
    <span slot="title1">
      <h2 class="align-center">title2</h2>
    </span>

    <span slot="title2">
      <h2 class="align-center">title2</h2>
    </span>
  </webcomponent-tab-panel>
`

const Steps = () => {
  return (
    <div dangerouslySetInnerHTML={{__html: body}} />
  )
}

export default Steps;

It works for now, but i feel like there should be a better way to do this. Does anyone have experience using webcomponents from a CDN like this?

2 Answers

I found a workaround. Im working with TypeScript. so when i tried to use the webcomponents in JSX it wouldnt find it on the JSX.intrinsicelements type. I made a types.d.ts file where i added the webcomponents to the JSX namespace.

like so

declare namespace JSX{
  interface IntrinsicElements{
    "WebComponent-Name": React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>
  }
}

React.createElement will allow you to write custom elements like <webcomponent-tab-panel {...props}/> in JSX. Since react will treat lowercase tags as not react components but html.

Related