svelte icon indicating copy to clipboard operation
svelte copied to clipboard

[feat] add html typings

Open dummdidumm opened this issue 3 years ago • 14 comments

This adds typings for HTML elements and their attributes. It's supposed to be used by the new transformation in language-tools.

Open questions:

  • should the event typings be onclick: ... or "on:click": ... or onclick: string, "on:click": ...? The first option is how it was transformed/dealt with in language-tools previously.
  • where should this be exposed? import { .. } from 'svelte' or sth like import { ... } from 'svelte/html'?

Before submitting the PR, please make sure you do the following

  • [x] It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
  • [x] Prefix your PR title with [feat], [fix], [chore], or [docs].
  • [x] This message body should clearly illustrate what problems it solves.
  • [ ] Ideally, include a test that fails without this PR but passes with it.

Tests

  • [ ] Run the tests with npm test and lint the project with npm run lint

dummdidumm avatar Jul 01 '22 13:07 dummdidumm

Vote for on:event, if there aren't technical difficulties. And svelte/html. Also, we can probably consider https://github.com/sveltejs/language-tools/issues/684 if we bump the minimal typescript version in svelte 4?

jasonlyu123 avatar Jul 02 '22 02:07 jasonlyu123

agree with exporting from svelte/html instead of svelte.

what would user see whether we use onclick or on:click?

tanhauhau avatar Jul 03 '22 16:07 tanhauhau

Right now the : is removed by language tools, so on:click becomes onclick for the purpose of typing. The transformation is roughly this: <div onclick={foo} /> --> createElement('div', { "onclick": foo }); If we do the typings like on:click, we wouldn't need to remove the colon in language-tools.

dummdidumm avatar Jul 03 '22 16:07 dummdidumm

Thought about the addition of : some more, I've also written down a roadmap towards the end goal, the new transformation (https://github.com/sveltejs/language-tools/issues/1552). I'm not sure anymore if we should use the colons since Svelte Native and Svelte NodeGUI both use the onX event typings. I'm not sure we can coordinate this bump in a way that works for users in a seamless way.

dummdidumm avatar Jul 06 '22 10:07 dummdidumm

  • should the event typings be onclick: ... or "on:click": ... or onclick: string, "on:click": ...? The first option is how it was transformed/dealt with in language-tools previously.

Whichever one we go with, NativeScript events are unavoidably camelcase, and I think NodeGUI events can even lead with a capital letter (I can't remember). I know anything but all lowercase probably violates some policy in the DOM Level 0 Events spec, but if there's really no actual restriction on the Svelte side, it would really help out custom renderers if the event handlers were unrestrictive on casing. Beyond that, I think any format can work, but it's been such a long time since I worked on this that I'm afraid I can't remember whether on:click posed any more/less problems than onclick.

  • where should this be exposed? import { .. } from 'svelte' or sth like import { ... } from 'svelte/html'?

They seem to be module-based typings, rather than ambient (strictly speaking "script" typings) so they won't infect custom renderers with Web typings, right? If so, then anywhere is fine. If it's the only thing that's ever going to live insvelte/html and there'll never be a "svelte/native" or "svelte/nodegui" path in the npm package, then maybe just keep it as from "svelte".

shirakaba avatar Jul 06 '22 13:07 shirakaba

See https://github.com/sveltejs/language-tools/pull/1549#issuecomment-1176045813, I lean more and more towards no doing on:X typings because of the ecosystem breakage it would mean. It sucks but I think we have to pay the price of suboptimal decisions earlier on here.

Edit: I think I revert my earlier decision and go with the on:X approach. Reasons:

  • Fear of leaving people who enhanced the definitions behind: No problem as TypeScript allows us to transform these names (see https://github.com/sveltejs/language-tools/pull/1549#issuecomment-1176045813 for the code)
  • Fear of breaking NodeGUI and SvelteNative: Not a big problem as we can add fallback any typings so people don't get an error
  • Fear of breaking libraries: If they specify "this uses props from svelte2tsx" they export props "onclick" etc which are wrong anyway

dummdidumm avatar Jul 06 '22 15:07 dummdidumm

I don't have a strong opinion about this although I leaned toward on:event. The template-literal redirect looks impressive. Do this mean we would use the on:event in here but have the helper function in svelte2tsx redirect the old style?

jasonlyu123 avatar Jul 20 '22 06:07 jasonlyu123

The helper function could be used to migrate enhancements by users on the old namespace by doing something like interface HTMLAttributes extends EventsWithColon<svelte.JSX.HTMLAttributes>, so this wouldn't break for them. We would keep the old JSX namespace around but with empty interfaces.

dummdidumm avatar Jul 20 '22 12:07 dummdidumm

Just tried this out with the new transformation + the mentioned type transformation (onx -> on:x) for old JSX attributes - works like a charm! Marking this ready for review.

dummdidumm avatar Aug 15 '22 12:08 dummdidumm

Thanks for checking so thoroughly! I adjusted the typings for bindings, the related PR on language-tools is https://github.com/sveltejs/language-tools/pull/1596

dummdidumm avatar Aug 22 '22 13:08 dummdidumm

I'm a little uncomfortable having something called svelte/html also export types for <svelte:xxx> special elements and (to a lesser extent) directives like on:xxx and bind:xxx. Is there another name we can find for this that indicates that this isn't just for HTML types? svelte/template was the first thing I thought of, but I don't really like that. Are these types you're foreseeing anyone manually importing anywhere, or would it just be a language tools thing pretty much?

I also feel quite gross about having SvelteKit- and Sapper-specific types in the core Svelte repo. I assume this was done because it seemed like the least bad option? I don't think we have to worry about Sapper too much, but: There's no reasonably way to have the SvelteKit-specific types published in the SvelteKit package and for the language tools to pull in the types from both places?

Conduitry avatar Aug 26 '22 09:08 Conduitry

The idea was to have one place where we can put these typings and the whole ecosystem can draw from them: language-tools mainly, but also package authors who may want to use these typings for their type definitions. Currently there's svelte2tsx usage in the wild because of that (svelte.JSX.HTMLAttributes mainly) and it feels weird that people have to import type definitions from some package whose primarily job is to work under the hood. Also it's harder to guess the impact of breaking changes in svelte2tsx if people keep using it. The next best place that isn't a separate package (which we could do, but also feels kind of weird, but I could be persuaded to) is therefore Svelte itself.

We could call it html-typings which would be more accorately describing what this does.

dummdidumm avatar Aug 26 '22 11:08 dummdidumm

About kit-specific typing. Maybe we could use Module Augmentation in the kit to enhance the anchor attribute typing. And language server could load the fallback version if we detect the user using an old version of the kit.

// whatever the name it ends up with
declare module 'svelte/html-typings' {
  interface HTMLAnchorAttributes {
    'sveltekit:noscroll'?: true | undefined | null;
  }
}

// tell ts this file is a module
export {}

jasonlyu123 avatar Aug 26 '22 14:08 jasonlyu123

html-types rather than typings would be better because that's what it will be exporting...

raprocks avatar Sep 16 '22 19:09 raprocks

We decided on svelte/elements

dummdidumm avatar Dec 11 '22 19:12 dummdidumm

For some reason this "breaks" components that defined it's own typing for value

image

https://github.com/sveltejs/svelte/blob/7e6acbece31fbd68e2c07e37f3c849c405eb6983/elements/index.d.ts#L796-L798

https://github.com/rgossiaux/svelte-headlessui/blob/master/src/lib/components/listbox/ListboxOption.svelte#L1-L27

TPassThroughProps<TSlotProps, TAsProp, "li">

bugproof avatar Jan 18 '23 12:01 bugproof

Could you open a new issue at https://github.com/sveltejs/language-tools/issues with a code snippet reproducing the error? Thanks.

dummdidumm avatar Jan 18 '23 13:01 dummdidumm