glint icon indicating copy to clipboard operation
glint copied to clipboard

[main] No type information for elements, custom-elements

Open NullVoxPopuli opened this issue 11 months ago • 4 comments

Example:

const ApplicationRoot: TOC<{ Element: null }> = <template>
  {{pageTitle "ExampleTsEmber"}}

  <custom-element />
    ^ hovering here: no type information
  <a></a>
   ^ hovering here: no type information
</template>;

export const Test: TOC<{}> = <template><ApplicationRoot /></template>;
                                        ^ hovering here: we see type information

now, it could be expected that custom-elements don't have type information, but the regular elements have known types, props, etc.

We also need a way to define custom-elements.

I briefly thought about the "loose mode" template registry:

declare module '@glint/environment-ember-loose/registry' {
  export default interface Registry extends PageTitle {
    'custom-element': ComponentLike<{ Element: HTMLDivElement }>;
  }
}

but:

  1. I'm not using loose mode
  2. custom-elements are not ComponentLike, so I'm not sure what I would provide for their type there

an example from @trusktr:

declare module 'whatever-framework' {
    interface WhateverInterface {
        'my-el': WhateverFrameworkElementAttributes<MyEl, MyElAttributes>
    }
}

maybe we can add this to support custom elements:

import { CustomElementLike } from '@glint/template';

declare module '@glint/core/custom-elements-registry' {
  export default interface Registry {
     'my-el': CustomElementLike<HTMLAnchorElement, MyAttributes>
  }
}

?

NullVoxPopuli avatar Mar 06 '25 00:03 NullVoxPopuli

Hey @NullVoxPopuli do you think the best path here is to avoid using custom elements or do you think there might be a fix in the future? Considering v2 got rid of loose mode.

We have some custom elements that are actually web components, but others that were just used to decorate the markup unfortunately. However, considering it is valid HTML it does seem important to support somehow? Would it not be correct to say custom elements extend HTMLElement?

LucasHillDex avatar Oct 31 '25 15:10 LucasHillDex

oh actually -- this is possible now -- I just need to document it.

if you do:

import '@glint/template';

declare global {
  interface GlintHtmlElementAttributesMap {
    'your-custom-element': {
      ['my-prop']: number;
      ['my-value']: string;
    } & GlobalHTMLAttributes;
  }
}

that should get you type-checking custom elements

NullVoxPopuli avatar Oct 31 '25 19:10 NullVoxPopuli

actually, it does look like there is a bug -- I have a failing test in #1016 with the above declaration merge -- and I would expect that when throwing the type for your custom element in that interface that you'd get type-checking.

I'll fix this, standby

NullVoxPopuli avatar Oct 31 '25 19:10 NullVoxPopuli

Fix is here https://github.com/typed-ember/glint/pull/1016 -- just one failing bit left

Also adds docs for how to add the custom elements (WIP)

NullVoxPopuli avatar Nov 04 '25 12:11 NullVoxPopuli