Material 3 Web Components definitions for SolidJS

Struggling with integrating the official Material 3 Web Components into SolidJS. Visit this link for more information.

The main hurdle has been encountering typescript errors despite being able to see the components on the page.

In my index.tsx, I've imported the necessary js files as follows:

import '@material/web/button/filled-button.js';
import '@material/web/button/outlined-button.js';
import '@material/web/checkbox/checkbox.js';
import '@material/web/tabs/tabs.js';
import '@material/web/tabs/secondary-tab.js';
import '@material/web/tabs/primary-tab.js';

The issue arises when using Web Component instances, causing type errors:

<md-tabs>
  <md-primary-tab>Birds</md-primary-tab>
  <md-secondary-tab>Cats</md-secondary-tab>
  <md-secondary-tab>Dogs</md-secondary-tab>
</md-tabs>

To work around this, I attempted a solution involving any, but that's not ideal:

declare module "solid-js" {
  namespace JSX {
    interface IntrinsicElements {
      "md-tabs": any
    }
  }
}

The Material 3 Web Components come with .d.ts files, but incorporating these declarations into SolidJS has proven challenging. Attempts like

/// <reference types="@material/web/all" />
didn't yield results.

I also tried the following approach:

import { MdTabs } from "@material/web/tabs/tabs.js";
import { MdPrimaryTab } from "@material/web/tabs/primary-tab";
import { MdSecondaryTab } from "@material/web/tabs/secondary-tab.js";

declare module "solid-js" {
  namespace JSX {
    interface IntrinsicElements {
      "md-tabs": MdTabs,
      'md-primary-tab': MdPrimaryTab,
      'md-secondary-tab': MdSecondaryTab
    }
  }
}

However, errors persist for md-primary-tab and md-secondary-tab (no error for md-tabs). The specific error message includes:

Type 'import("c:/Users/USER/dev/sstart/node_modules/solid-js/types/jsx").JSX.Element' is not assignable to type 'Element'.
  Type 'undefined' is not assignable to type 'Element'.ts(2322)
This JSX tag's 'children' prop expects type 'HTMLCollection' which requires multiple children, but only a single child was provided.ts(2745)

A workaround involves the following solution, though it still feels somewhat hacky:

declare module "solid-js" {
  namespace JSX {
    type MarriedWithChildren = {children:any} | {} | {class?:string, classList?:Record<string,boolean>
    interface IntrinsicElements {
      "md-tabs": MdTabs | MarriedWithChildren,
      'md-primary-tab': MdPrimaryTab | MarriedWithChildren,
      'md-secondary-tab': MdSecondaryTab | MarriedWithChildren
    }
  }
}

Answer №1

After experimenting, I came up with the following solution in global.d.ts

import "@material/web/all"

type WithAnyChildrenAndClasses = {children:any} | {} | {class?:string, classList?:Record<string,boolean>};

type SolidInterface = {
  [P in keyof HTMLElementTagNameMap]: HTMLElementTagNameMap[P] | WithAnyChildrenAndClasses;
};

declare module "solid-js" {
  namespace JSX {
    interface IntrinsicElements extends SolidInterface { }
  }
}

Update

A more effective solution can be found here:
https://github.com/shoelace-style/shoelace/discussions/770#discussioncomment-2852125

declare module 'solid-js' {
  namespace JSX {
    type ElementProps<T> = {
      // Include both the element's prefixed properties and attributes
      [K in keyof T]: Props<T[K]> & HTMLAttributes<T[K]>;
    }
    // Prefix all properties with `prop:` to match Solid's property setting syntax
    type Props<T> = {
      [K in keyof T as `prop:${string & K}`]?: T[K];
    }
    interface IntrinsicElements extends ElementProps<HTMLElementTagNameMap> {
    }
  }
}

PS
For utilizing the classList syntax, along with tailwind autocompletion like

<md-button classList={{"bg-blue-500":someSignal()}}></md-button>

insert the following in vscode/.settings.json

{
    "tailwindCSS.classAttributes": ["class", "classList", "className"]
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The property 'x' cannot be found on the data type 'true | Point'

I am dealing with a variable named ctx which can be either of type boolean or Point. Here is how Point is defined: type Point = { x: number y: number } In my React component, I have the following setup: const App = () => { const [ctx, toggleC ...

Trouble with accessing Dynamic StyleSheet properties based on type restrictions

I have successfully developed a functional component in React Native that supports both light and dark theme styles. const lightThemeOverrides = StyleSheet.create({ <light_override_styles_here> }); const styles = StyleSheet.create({ <styles_here&g ...

When attempting to utilize expo-av in a React-Native project on iOS, the recorded MP4 file encountered an issue when trying to submit it as form data for Open

I've been working tirelessly through the night, trying to record myself on my iPhone using expo-av to capture speech and then upload it to openai's transcriptions endpoint with the whisper-1 model. The recording is saved as an mp4 file, which I ...

Performing a series of Http Get requests in Angular 2 with an array that can

Seeking assistance with an Observable http sequence that involves making two dependent http calls to an api. The first call returns an Array of Urls, and the second call makes get requests for each url in the array and then returns the responses on the str ...

My goal is to prevent users from using the Backspace key within the input field

Let's say we want to prevent users from using the backspace key on an input field in this scenario. In our template, we pass the $event like so: <input (input)="onInput($event)"> Meanwhile, in our app.component.ts file, the function ...

Angular - Ensuring service completion before proceeding with navigation

I'm currently facing an issue where I need to populate data in a service before navigating, but the navigation is happening before the data is ready. Here's the code in my service: addToken(token) { this.cookieService.set( 'token', ...

Is there an issue with my approach to using TypeScript generics in classes?

class Some<AttributeType = { bar: string }> { foo(attrs: AttributeType) { if (attrs.bar) { console.log(attrs.bar) } } } Unable to run TypeScript code due to a specific error message: Property 'bar' d ...

Utilize Typescript to Invoke Functions of Different Components in Angular 2

Hello everyone, I am a newcomer to Angular 2 and I'm looking to utilize the value of one component in another component. This will help me populate data based on that particular value. In my setup, I have three Components - App.Component, Category.Co ...

Ways to switch up the titles on UploadThing

Recently, I started working with the UploadThing library and encountered a situation where I needed to personalize some names within the code. Here is what I have so far: Below is the snippet of code that I am currently using: "use client"; imp ...

Neglect variables that have not been declared (TypeScript)

Currently, I am working on developing a WebExtension using TypeScript that will be later compiled into JavaScript. This extension relies on one of the browser APIs offered by Firefox, specifically the extension API. An example of this is my use of the get ...

Arrange an array of integers and letters alphabetically in an Angular/Typescript environment

My Sorting Strategy I am attempting to organize an array in the following manner... 1 2 2(a) 2(b) 2(b) #AsimpleName 2(b) #NameWithN 3 4 4(a) ... ... using Angular 2. Snippet of My Code Component this.streetDetailRef = this.afDatabase.list('data/us ...

Is there a way for me to determine the value that has been assigned to a <li> key attribute in React using Jest and testing-library/react?

In my current project, I am using a combination of React with TypeScript and Jest along with Testing Library for testing purposes. I have a specific requirement to unit test some code where I need to ensure that the person.id is correctly set as the key at ...

Chart of commitments and potential outcomes

I am in the early stages of learning about promises and I am struggling to understand how to write code correctly. Here is an overview of what the program should do: Retrieve a list of item types (obtained through a promise) Loop through each item type to ...

What are the steps to create an object from an array?

Is it possible to create an object from an array in TypeScript? { A: {H: 10, W: 20, S: 30}} using the following data: [ { group: A, name: H, value: 10 }, { group: A, name: W, value: 20}, { group: A, name: S, value: 30} ] L ...

What steps can I take to ensure that the upper and left sections of a modal dialog remain accessible even when the size is reduced to the point of overflow?

One issue I'm facing is with a fixed-size modal dialog where part of the content gets cut off and becomes inaccessible when the window shrinks to cause an overflow. More specifically, when the window is narrowed horizontally, the left side is cut off ...

How to determine the presence of 'document' in Typecsript and NextJS

Incorporating NextJS means some server-side code rendering, which I can manage. However, I'm facing a challenge when trying to check for set cookies. I attempted: !!document && !!document.cookie as well as document !== undefined && ...

Creating an npm library using TypeScript model classes: A step-by-step guide

Currently, I am working on a large-scale web application that consists of multiple modules and repositories. Each module is being developed as an individual Angular project. These Angular projects have some shared UI components, services, and models which ...

What is the best way to determine the final letter of a column in a Google Sheet, starting from the first letter and using a set of

My current approach involves generating a single letter, but my code breaks if there is a large amount of data and it exceeds column Z. Here is the working code that will produce a, d: const countData = [1, 2, 3, 4].length; const initialLetter = 'A&a ...

The Type X is lacking essential properties found in Type Y, including length, pop, push, concat, and an additional 26 more properties. Code: [2740]

One interesting thing I have noticed is the Product interface: export interface Product{ code: string; description: string; type: string; } There is a service with a method that calls the product endpoint: public getProducts(): Observable<Product ...

Leveraging the Power of JavaScript within Angular 12

Currently, I am in the process of learning how to utilize Angular 12 and am attempting to create a sidenav. While I am aware that I can use angular material for this task, I would prefer not to incorporate the associated CSS. My goal is to integrate this ...