I have been looking for an example where someone mounts a React component to a lovelace web component, but could not find any clean examples. So I made my own.
I have come up with a POC that mounts a React component to a web component’s shadow root.
The other issue is the repeated rendering when hass or config is changed. This can be solved very easily now with @preact/signals-react.
Pros:
React based Lovelace Card
Build the component with modern TS/TSX/JS/JSX
No need for HASS connectors - hass consumed directly from Home Assistant
Highly configurable
Use any other npm libraries
Cons:
Requires build step.
No direct pipelines (yet).
Can’t use Radix UI (because they use document.documentElement to deal with dark mode ).
I’d like to hear comments and thoughts about this!
I would like to know if you’ve found a way to live preview your card during development, similar to how we develop a classic React app. Perhaps simulate a config file outside of the Home Assistant instance? Also, if we update the .js file located in /local/www, how can we easily update the card?
I haven’t been working on this, got put on a major project this year so all my personal projects have been dragged down lately
That aside, I haven’t found a fix for the stale js file, but what HACS does is include a cache breaker hash for each imported resource. If you’re keen to make some progress, I’m guessing that will be the direction eventually.
As for having a local version of the script, you could mock the value of the hass and config signal and replace it wherever required. Since it’s a signal, it’s gonna work no matter what updates it.
You can find the signals in utilities/registerCard.ts, might have to export the signals individually.
Edit: @Nycco sorry not sure why the post wasn’t replied to your comment.
I managed to get past the cache problem using the browser’s inspector mode and a hard reload.
Regarding the local version, it’s quite easy to export the hass and config signal, but I don’t know how I can preview the project locally with the ‘npm run dev’ command, for example.
You’d need to mount the app’s custom element on a page.
Currently it’s being registered as a custom element in registerCard.ts so you could make use of that and register the app as a custom component, then just consume it in the body of a html file.
Will need some tweaking to make it happen.
TL;DR;
createReactCard.tsx - Creates a custom element.
registerCard.ts - Sets up signals and registers the custom element (see web component).
Load the bundle in a page using a script tag, then place <react-card> somewhere in your html file.
Last question do you think there’s a way to get the Material Design icon of HA into the custom card? To use the icon property in the YAML custom card config.
Home Assistant loads icons on the dashboard using the <ha-icon icon="mdi:something" class="icon" > custom element. You won’t be able to load the icons when testing locally, but you can definitely use them in the app and have them load on the dashboard. (I think, not sure if there are any caveats)