diff --git a/README.md b/README.md index b8a2fbd..f51f944 100644 --- a/README.md +++ b/README.md @@ -604,9 +604,6 @@ Modifying the very first example from above for TypeScript, it would look like the following. ```tsx -/* @jsxImportSource solid-js */ -// ^ Alternatively, configure this in tsconfig.json instead of per-file. - import {createSignal} from 'solid-js' import {div} from '@lume/element/dist/type-helpers.js' @@ -643,7 +640,6 @@ The main differences from plain JS are > `` element then we need to use the `menu()` helper like follows. ```tsx -/* @jsxImportSource solid-js */ import {createSignal} from 'solid-js' import {menu} from '@lume/element/dist/type-helpers.js' @@ -663,7 +659,6 @@ type `HTMLDivElement` despite the fact that at runtime we will be have an `HTMLMenuElement` instance. ```tsx -/* @jsxImportSource solid-js */ import {div, button} from '@lume/element/dist/type-helpers.js' // GOOD. @@ -680,8 +675,6 @@ following to have the proper types, but note that the following is also not type safe: ```tsx -/* @jsxImportSource solid-js */ - // GOOD. const el = (...) as any as HTMLMenuElement @@ -695,33 +688,41 @@ const el2 = (...) as any as HTMLDivElement ### With Solid JSX To give your Custom Elements type checking for use with DOM APIs, and type -checking in Solid JSX, we can add the element type definition to `JSX.IntrinsicElements`: +checking in Solid JSX, we can add the element type definition to +`JSX.IntrinsicElements`. We can use the `ElementAttributes` helper to specify +which attributes/properties should be exposed in the JSX type: ```tsx -/* @jsxImportSource solid-js */ - -// We already use @jsxImportSource above, but if you need to reference JSX -// anywhere in non-JSX parts of the code, you also need to import it from -// solid-js: -import {Element, element, stringAttribute, numberAttribute, /*...,*/ JSX} from 'solid-js' - -// Define the attributes that your element accepts -export interface CoolElementAttributes extends JSX.HTMLAttributes { - 'cool-type'?: 'beans' | 'hair' - 'cool-factor'?: number - // ^ NOTE: These should be dash-case versions of your class's attribute properties. -} +import type {ElementAttributes} from '@lume/element' +import {Element, element, stringAttribute, numberAttribute} from '@lume/element' + +// List the properties that should be picked from the class type for JSX props. +// Note! Make sure that the properties listed are either decorated with +// attribute decorators, or that they are on* event properties. +export type CoolElementAttributes = 'coolType' | 'coolFactor' | 'oncoolness' @element('cool-element') -class CoolElement extends Element { +export class CoolElement extends Element { @stringAttribute coolType: 'beans' | 'hair' = 'beans' @numberAttribute coolFactor = 100 // ^ NOTE: These are the camelCase equivalents of the attributes defined above. + // Define the event prop by defining a method with the event name prefixed with 'on'. + oncoolness: ((event: SomeEvent) => void) | null = null + + // This property will not appear in the JSX types because it is not listed in + // the CoolElementAttributes that are passed to ElementAttributes below. + notJsxProp = 123 + // ... Define your class as described above. ... } -export {CoolElement} +/** This an event that our element emits. */ +class SomeEvent extends Event { + constructor() { + super('someevent', {...}) + } +} // Add your element to the list of known HTML elements. This makes it possible // for browser APIs to have the expected return type. For example, the return @@ -732,36 +733,14 @@ declare global { } } -// Also register the element name in the JSX types for TypeScript to recognize -// the element as a valid JSX tag. -declare module 'solid-js' { - namespace JSX { - interface IntrinsicElements { - 'cool-element': CoolElementAttributes - } - } -} -``` - -> :bulb:**TIP:** -> -> To make code less redundant, use the `ElementAttributes` helper to -> pluck the types of properties directly from your custom element class for the -> attribute types: - -```ts -import type {ElementAttributes} from '@lume/element' - -// This definition is now shorter than before, automatically maps the property -// names to dash-case, and automatically picks up the property types from the -// class. -export type CoolElementAttributes = ElementAttributes - // The same as before: declare module 'solid-js' { namespace JSX { interface IntrinsicElements { - 'cool-element': CoolElementAttributes + // This automatically maps the property names from camelCase to dash-case, + // automatically picks up the property types from the class, and also + // defines additional types for attr:, prop:, and bool: prefixed props. + 'cool-element': ElementAttributes } } } @@ -772,8 +751,11 @@ Now when you use `` in Solid JSX, it will be type checked: ```jsx return ( ) ``` @@ -794,16 +776,7 @@ Defining the types of custom elements for React JSX is similar as for Solid JSX ``` ```ts -import type {HTMLAttributes} from 'react' - -// Define the attributes that your element accepts, almost the same as before: -export interface CoolElementAttributes extends HTMLAttributes { - coolType?: 'beans' | 'hair' - coolFactor?: number - // ^ NOTE: These are the names of the class's properties verbatim, not - // dash-cased as with Solid. React works differently than Solid's: it will - // map the exact prop name to the JS property. -} +import type {ReactElementAttributes} from '@lume/element/dist/react.js' // Add your element to the list of known HTML elements, like before. declare global { @@ -832,14 +805,15 @@ declare global { ```ts import type {ReactElementAttributes} from '@lume/element/dist/react' -// This definition is now shorter than before, and automatically maps the property names to dash-case. -export type CoolElementAttributes = ReactElementAttributes +// ... same as before ... -// The same as before: -declare global { +declare module 'react' { namespace JSX { interface IntrinsicElements { - 'cool-element': CoolElementAttributes + // Similar as before, with ReactElementAttributes instead of + // ElementAttributes, and props will remain camelCase, not mapped to + // dash-case: + 'cool-element': ReactElementAttributes } } } @@ -850,8 +824,11 @@ Now when you use `` in React JSX, it will be type checked: ```jsx return ( ) ``` @@ -860,8 +837,7 @@ return ( > You may want to define React JSX types for your elements in separate files, and > have only React users import those files if they need the types, and similar if you make > JSX types for Vue, Svelte, etc (we don't have helpers for those other fameworks -> yet, but you can manually augment JSX as in the examples above on a -> per-framework basis, contributions welcome!). +> yet, but you can manually augment JSX in that case, contributions welcome!). ### With Preact JSX @@ -884,6 +860,8 @@ layer: } ``` +The rest is the same. + ## API ### `Element` @@ -1664,6 +1642,34 @@ element's style sheet into the `ShadowRoot` conflicts with how DOM is created in `ShadowRoot` content, or etc, then the user may want to place the stylesheet somewhere else). +#### `dispatchEventWithCall(event)` + +This is similar to `dispatchEvent()`, but useful for dispatching a non-builtin +event and causing any `on*` method for that event to also be called if it +exists. + +With builtin events, for example, when the builtin `click` event is dispatched, +the element's `.onclick()` method is called automatically if it exists. Now we +can achieve the same behavior with custom events, so that for example +`dispatchEventWithCall(new Event('myevent'))` will also cause `.onmyevent()` +to be called if it exists. + +Note, avoid calling this method with an event that is not a custom event, or +you'll trigger the respective builtin `on*` method twice. + +```ts +import {element, Element} from '@lume/element' + +@element('my-el') +class MyEl extends Element { + onfoo: ((event: Event) => void) | null = null +} + +const el = new MyEl() +el.onfoo = () => console.log('foo') +el.dispatchEventWithCall(new Event('foo')) // logs "foo" +``` + ### Decorators Using decorators (if available in your build, or natively in your JS engine) diff --git a/dist/LumeElement.d.ts b/dist/LumeElement.d.ts index 868ee48..8760ffa 100644 --- a/dist/LumeElement.d.ts +++ b/dist/LumeElement.d.ts @@ -204,23 +204,70 @@ type Template = TemplateContent | (() => TemplateContent); * let coolEl = * ``` */ -export type ElementAttributes, SetterTypePrefix>, AdditionalProperties extends object = {}> = Omit, SelectedProperties | keyof AdditionalProperties | 'onerror'> & { +export type ElementAttributes, SetterTypePrefix>, AdditionalProperties extends object = {}> = Omit, SelectedProperties | keyof AdditionalProperties | 'onerror'> & { onerror?: ((error: ErrorEvent) => void) | null; -} & Partial, SetterTypePrefix>, SelectedProperties>>>> & AdditionalProperties; +} & Partial>>>>> & Partial>, never>> & Partial>>>>> & Partial>>>>>> & Partial, SelectedProperties>>>> & PrefixProps<'bool:', DashCasedProps, SelectedProperties>>>>> & PrefixProps<'prop:', WithBooleanStringValues, SelectedProperties>>>> & PrefixProps<'attr:', DashCasedProps, SelectedProperties>>>>>> & Partial, SelectedProperties>>>> & PrefixProps<'prop:', WithNumberStringValues, SelectedProperties>>>> & PrefixProps<'attr:', DashCasedProps, SelectedProperties>>>>>> & Partial>> & Partial>>> & AdditionalProperties; +type RemapSetters = RemoveSetterPrefixes, SetterTypePrefix>; +type NonOnProps> = Pick, OmitFromUnion>>; +export type NonEventProps, SetterTypePrefix>> = NonOnProps & NonFunctionsOnly>; +export type EventProps = Pick>>; +export type NonBooleanProps = Omit>; +export type BooleanProps = { + [K in keyof T as T[K] extends boolean | 'true' | 'false' ? K : never]: T[K]; +}; +export type NonNumberProps = Omit>; +export type NumberProps = { + [K in keyof T as T[K] extends number ? K : never]: T[K]; +}; +export type FunctionsOnly = { + [K in keyof T as NonNullable extends (...args: any[]) => any ? K : never]: T[K]; +}; +export type NonFunctionsOnly = { + [K in keyof T as ((...args: any[]) => any) extends NonNullable ? never : K]: T[K]; +}; /** * Make all non-string properties union with |string because they can all * receive string values from string attributes like opacity="0.5" (those values * are converted to the types of values they should be, f.e. reading a * `@numberAttribute` property always returns a `number`) */ -export type WithStringValues = { - [Property in keyof Type]: PickFromUnion extends never ? // if the type does not include a type assignable to string - Type[Property] | string : Type[Property]; +export type WithStringValues = { + [K in keyof T]: PickFromUnion extends never ? // if the type does not include a type assignable to string + T[K] | string : T[K]; +}; +export type WithBooleanStringValues = { + [K in keyof T]: T[K] | 'true' | 'false'; +}; +export type AsBooleanStringValues = { + [K in keyof T]: 'true' | 'false'; +}; +export type AsBooleanValues = { + [K in keyof T]: boolean; +}; +export type WithNumberStringValues = { + [K in keyof T]: T[K] | `${number}`; +}; +export type AsNumberStringValues = { + [K in keyof T]: `${number}`; +}; +export type AsValues = { + [K in keyof T]: V; +}; +type AsStringValues = { + [K in keyof T]: PickFromUnion extends never ? string : T[K]; }; type StringKeysOnly = OmitFromUnion; -type OmitFromUnion = T extends TypeToOmit ? never : T; +export type OmitFromUnion = T extends TypeToOmit ? never : T; type PickFromUnion = T extends TypeToPick ? T : never; -export type RemovePrefixes = { +export type EventKeys = T extends `on${infer _}` ? T : never; +type AddDelimitersToEventKeys = { + [K in keyof T as K extends string ? AddDelimiters : never]: T[K]; +}; +type AddDelimiters = T extends `${'on'}${infer Right}` ? `${'on'}${Delimiter}${Right}` : T; +type PrefixProps = { + [K in keyof T as K extends string ? `${Prefix}${K}` : K]: T[K]; +}; +export type RemoveSetterPrefixes = { [K in keyof T as K extends string ? RemovePrefix : K]: T[K]; }; type RemovePrefix = T extends `${Prefix}${infer Rest}` ? Rest : T; diff --git a/dist/LumeElement.d.ts.map b/dist/LumeElement.d.ts.map index 25b7cc4..ca33084 100644 --- a/dist/LumeElement.d.ts.map +++ b/dist/LumeElement.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"LumeElement.d.ts","sourceRoot":"","sources":["../src/LumeElement.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"LumeElement.d.ts","sourceRoot":"","sources":["../src/LumeElement.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/attribute.d.ts b/dist/attribute.d.ts index 551974b..3734644 100644 --- a/dist/attribute.d.ts +++ b/dist/attribute.d.ts @@ -1,20 +1,22 @@ import './metadata-shim.js'; import type { ElementCtor } from './element.js'; export declare const __classFinishers: ((Class: ElementCtor) => void)[]; -/** The `@attribute` decorator currently works only on fields, getters, and setters. */ -type AttributeDecoratorContext = ClassFieldDecoratorContext | ClassGetterDecoratorContext | ClassSetterDecoratorContext; +type AttributeDecoratorContext = ClassFieldDecoratorContext | ClassGetterDecoratorContext | ClassSetterDecoratorContext | ClassAccessorDecoratorContext; /** * A decorator that when used on a property or accessor causes an HTML attribute * with the same name (but dash-cased instead of camelCased) to be mapped to the * decorated property. For example, if the `@attribute` decorator is used on a * property called `firstName`, then an attribute called `first-name` will be * mapped to the property. Any time that the attribute value changes (f.e. with - * `el.setAttribute`), the attribute value will propgate to the property a - * trigger an update. + * `el.setAttribute`), the attribute value will propgate to the property which + * triggers reactivity. * * The decorated property is backed by a Solid.js signal, thus useful in effects * or templates. * + * The `@attribute` decorator is only for public fields, getters, setters, and + * auto accessors. + * * Example: * * ```js diff --git a/dist/attribute.d.ts.map b/dist/attribute.d.ts.map index ef5bad7..dc3bee0 100644 --- a/dist/attribute.d.ts.map +++ b/dist/attribute.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"attribute.d.ts","sourceRoot":"","sources":["../src/attribute.ts"],"names":[],"mappings":"AAAA,OAAO,oBAAoB,CAAA;AAG3B,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,cAAc,CAAA;AAG7C,eAAO,MAAM,gBAAgB,EAAE,CAAC,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC,EAAO,CAAA;AAEpE,uFAAuF;AACvF,KAAK,yBAAyB,CAAC,IAAI,GAAG,OAAO,EAAE,KAAK,GAAG,OAAO,IAC3D,0BAA0B,CAAC,IAAI,EAAE,KAAK,CAAC,GACvC,2BAA2B,CAAC,IAAI,EAAE,KAAK,CAAC,GACxC,2BAA2B,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;AAE3C;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,yBAAyB,GAAG,GAAG,CAAA;AAClF,wBAAgB,SAAS,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,yBAAyB,KAAK,GAAG,CAAA;yBAAlG,SAAS;;;;;AAUzB;;;;GAIG;AACH,eAAO,MAAM,QAAQ,WAAY,OAAO,WAAW,yBAAyB,SAG3E,CAAA;AAoDD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,gBAAgB,EAAE,gBAAgB,GAAG,GAAG,CA8B7G;AAGD,eAAO,MAAM,mBAAmB,eAA8B,CAAA;AA2C9D;;;GAGG;AACH,MAAM,MAAM,gBAAgB,CAAC,CAAC,GAAG,GAAG,IAAI;IAOvC,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,KAAK,MAAM,GAAG,IAAI,CAAA;IAEpC;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,CAAC,CAAA;IAEpC;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,EAAE,CAAC,CAAA;CACX,CAAA;AAED,KAAK,aAAa,CAAC,CAAC,IAAI,MAAM,gBAAgB,CAAC,CAAC,CAAC,CAAA;AAwBjD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,yBAAyB,OAEjF;AAwBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,yBAAyB,OAEjF;AAwBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,yBAAyB,OAElF"} \ No newline at end of file +{"version":3,"file":"attribute.d.ts","sourceRoot":"","sources":["../src/attribute.ts"],"names":[],"mappings":"AAAA,OAAO,oBAAoB,CAAA;AAG3B,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,cAAc,CAAA;AAG7C,eAAO,MAAM,gBAAgB,EAAE,CAAC,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC,EAAO,CAAA;AAEpE,KAAK,yBAAyB,CAAC,IAAI,GAAG,OAAO,EAAE,KAAK,GAAG,OAAO,IAC3D,0BAA0B,CAAC,IAAI,EAAE,KAAK,CAAC,GACvC,2BAA2B,CAAC,IAAI,EAAE,KAAK,CAAC,GACxC,2BAA2B,CAAC,IAAI,EAAE,KAAK,CAAC,GACxC,6BAA6B,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;AAE7C;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,yBAAyB,GAAG,GAAG,CAAA;AAClF,wBAAgB,SAAS,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,yBAAyB,KAAK,GAAG,CAAA;yBAAlG,SAAS;;;;;AAUzB;;;;GAIG;AACH,eAAO,MAAM,QAAQ,WAAY,OAAO,WAAW,yBAAyB,SAG3E,CAAA;AAuDD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,gBAAgB,EAAE,gBAAgB,GAAG,GAAG,CA8B7G;AAGD,eAAO,MAAM,mBAAmB,eAA8B,CAAA;AA2C9D;;;GAGG;AACH,MAAM,MAAM,gBAAgB,CAAC,CAAC,GAAG,GAAG,IAAI;IAOvC,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,KAAK,MAAM,GAAG,IAAI,CAAA;IAEpC;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,CAAC,CAAA;IAEpC;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,EAAE,CAAC,CAAA;CACX,CAAA;AAED,KAAK,aAAa,CAAC,CAAC,IAAI,MAAM,gBAAgB,CAAC,CAAC,CAAC,CAAA;AAwBjD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,yBAAyB,OAEjF;AAwBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,yBAAyB,OAEjF;AAwBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,yBAAyB,OAElF"} \ No newline at end of file diff --git a/dist/attribute.js b/dist/attribute.js index c68d3fc..e44c71f 100644 --- a/dist/attribute.js +++ b/dist/attribute.js @@ -31,7 +31,6 @@ function handleAttributeDecoration(value, context, attributeHandler = {}) { throw new Error('@attribute is not supported on private fields yet.'); if (isStatic) throw new Error('@attribute is not supported on static fields.'); - // TODO decorate on prototype? Or decorate on instance? __classFinishers.push((Class) => __setUpAttribute(Class, name, attributeHandler)); if (kind === 'field') { const signalInitializer = useSignal ? signal(value, context) : (v) => v; @@ -50,10 +49,18 @@ function handleAttributeDecoration(value, context, attributeHandler = {}) { } else if (kind === 'getter' || kind === 'setter') { if (useSignal) - signal(value, context); + return signal(value, context); + } + else if (kind === 'accessor') { + context.addInitializer(function () { + if (!('default' in attributeHandler)) + attributeHandler.default = this[name]; + }); + if (useSignal) + return signal(value, context); } else { - throw new Error('@attribute is only for use on fields, getters, and setters. Auto accessor support is coming next if there is demand for it.'); + throw new Error('@attribute is only for use on fields, getters/setters, and auto accessors.'); } return undefined; // shush TS } diff --git a/dist/attribute.js.map b/dist/attribute.js.map index e2d645a..1d28884 100644 --- a/dist/attribute.js.map +++ b/dist/attribute.js.map @@ -1 +1 @@ -{"version":3,"file":"attribute.js","sourceRoot":"","sources":["../src/attribute.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"attribute.js","sourceRoot":"","sources":["../src/attribute.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/element.d.ts.map b/dist/element.d.ts.map index f4b1bbb..b00c8bc 100644 --- a/dist/element.d.ts.map +++ b/dist/element.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"element.d.ts","sourceRoot":"","sources":["../src/element.ts"],"names":[],"mappings":"AAAA,OAAO,oBAAoB,CAAA;AAG3B,OAAO,EAAC,OAAO,EAAE,KAAK,mBAAmB,EAAC,MAAM,kBAAkB,CAAA;AAElE,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,8BAA8B,CAAA;AAGhE,KAAK,eAAe,GAAG;IACtB,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC7B,yBAAyB,CAAC,EAAE,mBAAmB,CAAA;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,eAAe,CAAA;CAC1B,CAAA;AACD,MAAM,MAAM,WAAW,GAAG,OAAO,OAAO,GAAG,eAAe,CAAA;AAI1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AACH,wBAAgB,OAAO,CACtB,OAAO,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,OAAO,GAClB,CAAC,CAAC,SAAS,cAAc,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,qBAAqB,KAAK,CAAC,CAAA;AAC1F,wBAAgB,OAAO,CAAC,CAAC,SAAS,cAAc,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,CAAC,CAAA"} \ No newline at end of file +{"version":3,"file":"element.d.ts","sourceRoot":"","sources":["../src/element.ts"],"names":[],"mappings":"AAAA,OAAO,oBAAoB,CAAA;AAG3B,OAAO,EAAC,OAAO,EAAE,KAAK,mBAAmB,EAAC,MAAM,kBAAkB,CAAA;AAElE,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,8BAA8B,CAAA;AAIhE,KAAK,eAAe,GAAG;IACtB,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC7B,yBAAyB,CAAC,EAAE,mBAAmB,CAAA;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,eAAe,CAAA;CAC1B,CAAA;AACD,MAAM,MAAM,WAAW,GAAG,OAAO,OAAO,GAAG,eAAe,CAAA;AAI1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AACH,wBAAgB,OAAO,CACtB,OAAO,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,OAAO,GAClB,CAAC,CAAC,SAAS,cAAc,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,qBAAqB,KAAK,CAAC,CAAA;AAC1F,wBAAgB,OAAO,CAAC,CAAC,SAAS,cAAc,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,CAAC,CAAA"} \ No newline at end of file diff --git a/dist/element.js b/dist/element.js index 897c14f..c5f9602 100644 --- a/dist/element.js +++ b/dist/element.js @@ -3,6 +3,7 @@ import { untrack } from 'solid-js'; import { reactive, signalify } from 'classy-solid'; import { Element } from './LumeElement.js'; import { __classFinishers, __setUpAttribute, __attributesToProps } from './attribute.js'; +import { __eventSetter, eventFields } from './event.js'; const isAttributeHandler = Symbol('isAttributeHandler'); export function element(tagNameOrClass, autoDefineOrContext) { let tagName = ''; @@ -185,6 +186,25 @@ function applyElementDecoration(Class, context, tagName, autoDefine) { set: newSetter, }); } + const meta = metadata; + // Set up event fields (accessors and getters/setters are handled in the @event decorator directly). + if (Object.hasOwn(meta, eventFields)) { + for (const name of meta[eventFields]) { + const eventName = name.replace(/^on/, ''); + const desc = Object.getOwnPropertyDescriptor(this, name); + if (desc.get || desc.set) + throw new Error('@event is not supported on properties with getters/setters yet. Use the @event decorator on a field that is not converted to a getter/setter by anything else.'); + let value = desc.value; + const get = () => value; + const set = (v) => (value = v); + Object.defineProperty(this, name, { + enumerable: true, + configurable: true, + get, + set: __eventSetter(name, eventName, get, set), + }); + } + } }); } } diff --git a/dist/element.js.map b/dist/element.js.map index df96788..585baca 100644 --- a/dist/element.js.map +++ b/dist/element.js.map @@ -1 +1 @@ -{"version":3,"file":"element.js","sourceRoot":"","sources":["../src/element.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"element.js","sourceRoot":"","sources":["../src/element.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/event.d.ts b/dist/event.d.ts new file mode 100644 index 0000000..5b090ae --- /dev/null +++ b/dist/event.d.ts @@ -0,0 +1,26 @@ +type EventDecoratorContext = ClassFieldDecoratorContext | ClassGetterDecoratorContext | ClassSetterDecoratorContext | ClassAccessorDecoratorContext; +export declare const eventFields: unique symbol; +export type EventMetadata = { + [eventFields]: Set; +}; +/** + * A decorator that when used on an accessor causes an event listener to be + * registered for events with the same name (but without the "on" prefix) on + * the element. For example, if the `@event` decorator is used on a property + * called `onexpand`, then an event listener for the `expand` event will be + * registered on the element using the assigned handler. + * + * This is useful because: + * + * - seeing the `@event` properties in the class definition serves as a + * reference as to which events the element will emit. + * - types for `on*` JSX props are derived from the types of these properties + * (f.e. when using ElementAttributes or ReactElementAttributes to define JSX + * types). + * - it gives new custom elements feature parity with the `on*` event properties + * that builtin elements have. + */ +export declare function event(value: T, context: EventDecoratorContext): any; +export declare function __eventSetter(name: string, eventName: string, get: (() => EventListener | null) | null, set: (handler: EventListener | null) => void): (this: Element, handler: EventListener | null) => void; +export {}; +//# sourceMappingURL=event.d.ts.map \ No newline at end of file diff --git a/dist/event.d.ts.map b/dist/event.d.ts.map new file mode 100644 index 0000000..9fe63d6 --- /dev/null +++ b/dist/event.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../src/event.ts"],"names":[],"mappings":"AAAA,KAAK,qBAAqB,GACvB,0BAA0B,GAC1B,2BAA2B,GAC3B,2BAA2B,GAC3B,6BAA6B,CAAA;AAEhC,eAAO,MAAM,WAAW,eAAwB,CAAA;AAEhD,MAAM,MAAM,aAAa,GAAG;IAAC,CAAC,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAAC,CAAA;AAExD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,qBAAqB,GAAG,GAAG,CAoDtE;AAED,wBAAgB,aAAa,CAC5B,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,IAAI,EACxC,GAAG,EAAE,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,KAAK,IAAI,UAErB,OAAO,WAAW,aAAa,GAAG,IAAI,UAU7D"} \ No newline at end of file diff --git a/dist/event.js b/dist/event.js new file mode 100644 index 0000000..c1d0b93 --- /dev/null +++ b/dist/event.js @@ -0,0 +1,83 @@ +export const eventFields = Symbol('eventFields'); +/** + * A decorator that when used on an accessor causes an event listener to be + * registered for events with the same name (but without the "on" prefix) on + * the element. For example, if the `@event` decorator is used on a property + * called `onexpand`, then an event listener for the `expand` event will be + * registered on the element using the assigned handler. + * + * This is useful because: + * + * - seeing the `@event` properties in the class definition serves as a + * reference as to which events the element will emit. + * - types for `on*` JSX props are derived from the types of these properties + * (f.e. when using ElementAttributes or ReactElementAttributes to define JSX + * types). + * - it gives new custom elements feature parity with the `on*` event properties + * that builtin elements have. + */ +export function event(value, context) { + const { name, kind, private: isPrivate } = context; + const metadata = context.metadata; + if (typeof name === 'symbol') + throw new Error('Cannot currently use symbols as event names.'); + if (isPrivate) + throw new Error('Cannot use private field names as event names.'); + const eventName = name.replace(/^on/, ''); + if (kind === 'field') { + if (!Object.hasOwn(metadata, eventFields)) + metadata[eventFields] = new Set(); + metadata[eventFields].add(name); + return function (handler) { + if (handler) + this.addEventListener(eventName, handler); + return handler; + }; + } + else if (kind === 'getter' || kind === 'setter') { + if (kind === 'getter') + return value; + else { + const set = value; + let setCalled = false; + context.addInitializer(function () { + queueMicrotask(() => { + if (typeof this[name] === 'function' && !setCalled) + console.warn(`@event decorator: initial value for ${name} was not handled. Start the initial value as null, then set it to the desired handler in your constructor instead.`); + }); + }); + const setter = __eventSetter(name, eventName, null, set); + return function (handler) { + setCalled = true; + setter.call(this, handler); + }; + } + } + else if (kind === 'accessor') { + const { get, set } = value; + return { + init: function (handler) { + if (handler) + this.addEventListener(eventName, handler); + return handler; + }, + get, + set: __eventSetter(name, eventName, get, set), + }; + } + else + throw new Error('Use @event on a field, getter/setter, or accessor.'); +} +export function __eventSetter(name, eventName, get, set) { + return function (handler) { + if (handler && typeof handler !== 'function') + throw new Error('Event handlers must be functions.'); + const previousHandler = get ? get.call(this) : this[name]; + if (previousHandler) + this.removeEventListener(eventName, previousHandler); + if (handler) + this.addEventListener(eventName, handler); + set.call(this, handler); + }; +} +//# sourceMappingURL=event.js.map \ No newline at end of file diff --git a/dist/event.js.map b/dist/event.js.map new file mode 100644 index 0000000..5933b0b --- /dev/null +++ b/dist/event.js.map @@ -0,0 +1 @@ +{"version":3,"file":"event.js","sourceRoot":"","sources":["../src/event.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/event.test.d.ts b/dist/event.test.d.ts new file mode 100644 index 0000000..2cfff88 --- /dev/null +++ b/dist/event.test.d.ts @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=event.test.d.ts.map \ No newline at end of file diff --git a/dist/event.test.d.ts.map b/dist/event.test.d.ts.map new file mode 100644 index 0000000..b8fcfd4 --- /dev/null +++ b/dist/event.test.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"event.test.d.ts","sourceRoot":"","sources":["../src/event.test.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/dist/event.test.js.map b/dist/event.test.js.map new file mode 100644 index 0000000..cbdf751 --- /dev/null +++ b/dist/event.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"event.test.js","sourceRoot":"","sources":["../src/event.test.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/index.d.ts b/dist/index.d.ts index 4024092..9a1e6a7 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -2,6 +2,7 @@ export * from './LumeElement.js'; export * from './attribute.js'; export * from './element.js'; export * from './css.js'; +export * from './event.js'; export { identityTemplateTag, camelCaseToDash, dashCaseToCamelCase, type CamelCasedProps, type DashCasedProps, } from './utils.js'; export type { JSX } from './jsx-runtime.js'; export declare const version = "0.14.0"; diff --git a/dist/index.d.ts.map b/dist/index.d.ts.map index 117cd6d..e5cffed 100644 --- a/dist/index.d.ts.map +++ b/dist/index.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAA;AAChC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,cAAc,CAAA;AAC5B,cAAc,UAAU,CAAA;AACxB,OAAO,EACN,mBAAmB,EACnB,eAAe,EACf,mBAAmB,EACnB,KAAK,eAAe,EACpB,KAAK,cAAc,GACnB,MAAM,YAAY,CAAA;AACnB,YAAY,EAAC,GAAG,EAAC,MAAM,kBAAkB,CAAA;AAEzC,eAAO,MAAM,OAAO,WAAW,CAAA"} \ No newline at end of file +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAA;AAChC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,cAAc,CAAA;AAC5B,cAAc,UAAU,CAAA;AACxB,cAAc,YAAY,CAAA;AAC1B,OAAO,EACN,mBAAmB,EACnB,eAAe,EACf,mBAAmB,EACnB,KAAK,eAAe,EACpB,KAAK,cAAc,GACnB,MAAM,YAAY,CAAA;AACnB,YAAY,EAAC,GAAG,EAAC,MAAM,kBAAkB,CAAA;AAEzC,eAAO,MAAM,OAAO,WAAW,CAAA"} \ No newline at end of file diff --git a/dist/index.js b/dist/index.js index a35068e..93700c6 100644 --- a/dist/index.js +++ b/dist/index.js @@ -2,6 +2,7 @@ export * from './LumeElement.js'; export * from './attribute.js'; export * from './element.js'; export * from './css.js'; +export * from './event.js'; export { identityTemplateTag, camelCaseToDash, dashCaseToCamelCase, } from './utils.js'; export const version = '0.14.0'; //# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/index.js.map b/dist/index.js.map index d1ff396..9c4fb1d 100644 --- a/dist/index.js.map +++ b/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAA;AAChC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,cAAc,CAAA;AAC5B,cAAc,UAAU,CAAA;AACxB,OAAO,EACN,mBAAmB,EACnB,eAAe,EACf,mBAAmB,GAGnB,MAAM,YAAY,CAAA;AAGnB,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,CAAA"} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAA;AAChC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,cAAc,CAAA;AAC5B,cAAc,UAAU,CAAA;AACxB,cAAc,YAAY,CAAA;AAC1B,OAAO,EACN,mBAAmB,EACnB,eAAe,EACf,mBAAmB,GAGnB,MAAM,YAAY,CAAA;AAGnB,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,CAAA"} \ No newline at end of file diff --git a/dist/jsx-types-react.test.d.ts b/dist/jsx-types-react.test.d.ts index 135e9f6..f5e04d9 100644 --- a/dist/jsx-types-react.test.d.ts +++ b/dist/jsx-types-react.test.d.ts @@ -1,15 +1,60 @@ +import { Element } from './LumeElement.js'; import type { ReactElementAttributes } from './react.js'; -declare class SomeElement extends HTMLElement { +type SomeElementAttributes = 'someProp' | 'someBoolean' | 'otherProp' | 'onsomeevent' | 'onnotanevent' | 'someNumber'; +/** + * Note, decorators are not required for defining JSX types, but we are using + * decorators here to show the best practice: + * + * You want to select *only* properties decorated with attribute decorators and + * on* event properties. Technically the JSX types will work if you select + * any plain properties, but it won't be type safe because the JSX types + * will include string types, which the decorators are responsible for + * converting into the non-string values. + * + * To have well-defined, consistent, and interoperable elements, you always want + * properties that are paired with attributes. Otherwise you'll have elements + * that don't work well in plain HTML, and that require plain JS to operate, and + * that can also make them more difficult to use in some non-custom-element + * frameworks where they will need to be referenced for manipulation in JS + * instead of in declarative templates. When all properties are mapped to + * attributes, it makes them capable of always receiving data from HTML sent + * from a server, for example HTML with any language on a backend. + * + * In rare cases, having a JS property that is not paired with an attribute is + * needed, but strive to avoid this. An example where this might be inevitable + * is when wrapping a non-custom-element framework component in a custom + * element, where the non-custom-element component accepts only special types of + * objects via its props, and those objects are not representable as strings (or + * it would be difficult to do so). But even in these cases, an approach is to + * map a set of attribute properties to those special objects instead of + * accepting (or as alternative to accepting) the special objects. + */ +declare class SomeElement extends Element { + #private; someProp: 'true' | 'false' | boolean; + ignoredBoolean: boolean; + someBoolean: boolean; + /** + * This is a getter/setter whose getter always returns number, but whose + * setter can accept a specific non-number value which is coerced into a + * number. + */ get otherProp(): number; set otherProp(_: this['__set__otherProp']); /** do not use this property, its only for JSX types */ __set__otherProp: number | 'foo'; + onsomeevent: ((event: SomeEvent) => void) | null; + onnotanevent: number; + ignoredNumber: number; + someNumber: number; +} +declare class SomeEvent extends Event { + foo: number; } declare module 'react' { namespace JSX { interface IntrinsicElements { - 'some-element': ReactElementAttributes; + 'some-element': ReactElementAttributes; } } } diff --git a/dist/jsx-types-react.test.d.ts.map b/dist/jsx-types-react.test.d.ts.map index 2f39cb6..84f7306 100644 --- a/dist/jsx-types-react.test.d.ts.map +++ b/dist/jsx-types-react.test.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"jsx-types-react.test.d.ts","sourceRoot":"","sources":["../src/jsx-types-react.test.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,sBAAsB,EAAC,MAAM,YAAY,CAAA;AAEtD,cAAM,WAAY,SAAQ,WAAW;IACpC,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAO;IAE3C,IAAI,SAAS,IAAI,MAAM,CAEtB;IACD,IAAI,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,kBAAkB,CAAC,EAAI;IAE7C,uDAAuD;IACvD,gBAAgB,EAAG,MAAM,GAAG,KAAK,CAAA;CACjC;AAID,OAAO,QAAQ,OAAO,CAAC;IACtB,UAAU,GAAG,CAAC;QACb,UAAU,iBAAiB;YAC1B,cAAc,EAAE,sBAAsB,CAAC,WAAW,EAAE,UAAU,GAAG,WAAW,CAAC,CAAA;SAC7E;KACD;CACD"} \ No newline at end of file +{"version":3,"file":"jsx-types-react.test.d.ts","sourceRoot":"","sources":["../src/jsx-types-react.test.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAC,OAAO,EAAC,MAAM,kBAAkB,CAAA;AACxC,OAAO,KAAK,EAAC,sBAAsB,EAAC,MAAM,YAAY,CAAA;AAEtD,KAAK,qBAAqB,GAAG,UAAU,GAAG,aAAa,GAAG,WAAW,GAAG,aAAa,GAAG,cAAc,GAAG,YAAY,CAAA;AAErH;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,cACM,WAAY,SAAQ,OAAO;;IACrB,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAO;IAEtD,cAAc,UAAQ;IAEJ,WAAW,UAAO;IAIpC;;;;OAIG;IACH,IAAe,SAAS,IAAI,MAAM,CAEjC;IACD,IAAe,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,kBAAkB,CAAC,EAGnD;IAED,uDAAuD;IACvD,gBAAgB,EAAG,MAAM,GAAG,KAAK,CAAA;IAE1B,WAAW,EAAE,CAAC,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC,GAAG,IAAI,CAAO;IAE9D,YAAY,SAAM;IAElB,aAAa,SAAI;IAEA,UAAU,SAAM;CACjC;AAID,cAAM,SAAU,SAAQ,KAAK;IAC5B,GAAG,SAAI;CACP;AAED,OAAO,QAAQ,OAAO,CAAC;IACtB,UAAU,GAAG,CAAC;QACb,UAAU,iBAAiB;YAC1B,cAAc,EAAE,sBAAsB,CAAC,WAAW,EAAE,qBAAqB,CAAC,CAAA;SAC1E;KACD;CACD"} \ No newline at end of file diff --git a/dist/jsx-types-react.test.jsx b/dist/jsx-types-react.test.jsx index 633c3a6..4e4896b 100644 --- a/dist/jsx-types-react.test.jsx +++ b/dist/jsx-types-react.test.jsx @@ -1,18 +1,152 @@ /* @jsxImportSource react */ -class SomeElement extends HTMLElement { - someProp = true; - get otherProp() { - return 0; +var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) { + var useValue = arguments.length > 2; + for (var i = 0; i < initializers.length; i++) { + value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); } - set otherProp(_) { } - /** do not use this property, its only for JSX types */ - __set__otherProp; -} + return useValue ? value : void 0; +}; +var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { + function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } + var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; + var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; + var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); + var _, done = false; + for (var i = decorators.length - 1; i >= 0; i--) { + var context = {}; + for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; + for (var p in contextIn.access) context.access[p] = contextIn.access[p]; + context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; + var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); + if (kind === "accessor") { + if (result === void 0) continue; + if (result === null || typeof result !== "object") throw new TypeError("Object expected"); + if (_ = accept(result.get)) descriptor.get = _; + if (_ = accept(result.set)) descriptor.set = _; + if (_ = accept(result.init)) initializers.unshift(_); + } + else if (_ = accept(result)) { + if (kind === "field") initializers.unshift(_); + else descriptor[key] = _; + } + } + if (target) Object.defineProperty(target, contextIn.name, descriptor); + done = true; +}; +import { attribute, booleanAttribute, numberAttribute } from './attribute.js'; +import { element } from './element.js'; +import { event } from './event.js'; +import { Element } from './LumeElement.js'; +/** + * Note, decorators are not required for defining JSX types, but we are using + * decorators here to show the best practice: + * + * You want to select *only* properties decorated with attribute decorators and + * on* event properties. Technically the JSX types will work if you select + * any plain properties, but it won't be type safe because the JSX types + * will include string types, which the decorators are responsible for + * converting into the non-string values. + * + * To have well-defined, consistent, and interoperable elements, you always want + * properties that are paired with attributes. Otherwise you'll have elements + * that don't work well in plain HTML, and that require plain JS to operate, and + * that can also make them more difficult to use in some non-custom-element + * frameworks where they will need to be referenced for manipulation in JS + * instead of in declarative templates. When all properties are mapped to + * attributes, it makes them capable of always receiving data from HTML sent + * from a server, for example HTML with any language on a backend. + * + * In rare cases, having a JS property that is not paired with an attribute is + * needed, but strive to avoid this. An example where this might be inevitable + * is when wrapping a non-custom-element framework component in a custom + * element, where the non-custom-element component accepts only special types of + * objects via its props, and those objects are not representable as strings (or + * it would be difficult to do so). But even in these cases, an approach is to + * map a set of attribute properties to those special objects instead of + * accepting (or as alternative to accepting) the special objects. + */ +let SomeElement = (() => { + let _classDecorators = [element('some-element-react-jsx')]; + let _classDescriptor; + let _classExtraInitializers = []; + let _classThis; + let _classSuper = Element; + let _instanceExtraInitializers = []; + let _someProp_decorators; + let _someProp_initializers = []; + let _someProp_extraInitializers = []; + let _someBoolean_decorators; + let _someBoolean_initializers = []; + let _someBoolean_extraInitializers = []; + let _get_otherProp_decorators; + let _set_otherProp_decorators; + let _onsomeevent_decorators; + let _onsomeevent_initializers = []; + let _onsomeevent_extraInitializers = []; + let _someNumber_decorators; + let _someNumber_initializers = []; + let _someNumber_extraInitializers = []; + var SomeElement = class extends _classSuper { + static { _classThis = this; } + static { + const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; + _someProp_decorators = [attribute]; + _someBoolean_decorators = [booleanAttribute]; + _get_otherProp_decorators = [attribute]; + _set_otherProp_decorators = [attribute]; + _onsomeevent_decorators = [event]; + _someNumber_decorators = [numberAttribute]; + __esDecorate(this, null, _get_otherProp_decorators, { kind: "getter", name: "otherProp", static: false, private: false, access: { has: obj => "otherProp" in obj, get: obj => obj.otherProp }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate(this, null, _set_otherProp_decorators, { kind: "setter", name: "otherProp", static: false, private: false, access: { has: obj => "otherProp" in obj, set: (obj, value) => { obj.otherProp = value; } }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate(null, null, _someProp_decorators, { kind: "field", name: "someProp", static: false, private: false, access: { has: obj => "someProp" in obj, get: obj => obj.someProp, set: (obj, value) => { obj.someProp = value; } }, metadata: _metadata }, _someProp_initializers, _someProp_extraInitializers); + __esDecorate(null, null, _someBoolean_decorators, { kind: "field", name: "someBoolean", static: false, private: false, access: { has: obj => "someBoolean" in obj, get: obj => obj.someBoolean, set: (obj, value) => { obj.someBoolean = value; } }, metadata: _metadata }, _someBoolean_initializers, _someBoolean_extraInitializers); + __esDecorate(null, null, _onsomeevent_decorators, { kind: "field", name: "onsomeevent", static: false, private: false, access: { has: obj => "onsomeevent" in obj, get: obj => obj.onsomeevent, set: (obj, value) => { obj.onsomeevent = value; } }, metadata: _metadata }, _onsomeevent_initializers, _onsomeevent_extraInitializers); + __esDecorate(null, null, _someNumber_decorators, { kind: "field", name: "someNumber", static: false, private: false, access: { has: obj => "someNumber" in obj, get: obj => obj.someNumber, set: (obj, value) => { obj.someNumber = value; } }, metadata: _metadata }, _someNumber_initializers, _someNumber_extraInitializers); + __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers); + SomeElement = _classThis = _classDescriptor.value; + if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); + __runInitializers(_classThis, _classExtraInitializers); + } + someProp = (__runInitializers(this, _instanceExtraInitializers), __runInitializers(this, _someProp_initializers, true)); + ignoredBoolean = (__runInitializers(this, _someProp_extraInitializers), false); + someBoolean = __runInitializers(this, _someBoolean_initializers, true); + #otherProp = (__runInitializers(this, _someBoolean_extraInitializers), 0); + /** + * This is a getter/setter whose getter always returns number, but whose + * setter can accept a specific non-number value which is coerced into a + * number. + */ + get otherProp() { + return this.#otherProp; + } + set otherProp(_) { + // Here you would need custom logic to coerce "foo" into a number, for example. + this.#otherProp = _; + } + /** do not use this property, its only for JSX types */ + __set__otherProp; + onsomeevent = __runInitializers(this, _onsomeevent_initializers, null); + onnotanevent = (__runInitializers(this, _onsomeevent_extraInitializers), 123); + ignoredNumber = 0; + someNumber = __runInitializers(this, _someNumber_initializers, 123); + constructor() { + super(...arguments); + __runInitializers(this, _someNumber_extraInitializers); + } + }; + return SomeElement = _classThis; +})(); SomeElement; +class SomeEvent extends Event { + foo = 0; +} describe('JSX types with ReactElementAttributes', () => { it('derives JSX types from classes', () => { ; <> + {/* Ensure common element attributes still work. */} + event.button} aria-hidden="true" className="foo" style={{ color: 'red' }}/> + @@ -25,8 +159,53 @@ describe('JSX types with ReactElementAttributes', () => { {/* @ts-expect-error foo doesn't exist. TypeScript will only check existence of properties without dashes */} + + {/* @ts-expect-error `ignoredBoolean` was not selected, not available in JSX */} + + + + + + + + {/* @ts-expect-error good, only booleans and boolean strings allowed, no strings */} + + {/* @ts-expect-error good, only booleans allowed */} + + + event.foo}/> + {/* @ts-expect-error on:-prefixed event props are not for React */} + event}/> + {/* @ts-expect-error wrong event type */} + event}/> + + {/* This is fine in React, it will set the JS property to the given value instead of adding an event listener if the value is not a function. */} + + {/* @ts-expect-error good, boolean is not valid */} + + {/* @ts-expect-error good, event handler is not valid (although at runtime React will listen for "notanevent") */} + e}/> + + {/* @ts-expect-error `ignoredNumber` was not selected, not available in JSX */} + + + + {/* @ts-expect-error good, `false` is not a number */} + + + + + + + + + {/* @ts-expect-error good, "0z1010" is not a number string */} + + {/* @ts-expect-error good, "blah" is not a number string */} + + {/* @ts-expect-error good, "1.blah" is not a number string */} + ; }); }); -export {}; //# sourceMappingURL=jsx-types-react.test.jsx.map \ No newline at end of file diff --git a/dist/jsx-types-react.test.jsx.map b/dist/jsx-types-react.test.jsx.map index e2fb448..305d48e 100644 --- a/dist/jsx-types-react.test.jsx.map +++ b/dist/jsx-types-react.test.jsx.map @@ -1 +1 @@ -{"version":3,"file":"jsx-types-react.test.jsx","sourceRoot":"","sources":["../src/jsx-types-react.test.tsx"],"names":[],"mappings":"AAAA,4BAA4B;AAI5B,MAAM,WAAY,SAAQ,WAAW;IACpC,QAAQ,GAA+B,IAAI,CAAA;IAE3C,IAAI,SAAS;QACZ,OAAO,CAAC,CAAA;IACT,CAAC;IACD,IAAI,SAAS,CAAC,CAA2B,IAAG,CAAC;IAE7C,uDAAuD;IACvD,gBAAgB,CAAiB;CACjC;AAED,WAAW,CAAA;AAUX,QAAQ,CAAC,uCAAuC,EAAE,GAAG,EAAE;IACtD,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACzC,CAAC;QAAA,EACA;GAAA,CAAC,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,EAC9C;GAAA,CAAC,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,EAC9C;GAAA,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,EAC9C;GAAA,CAAC,8CAA8C,CAC/C;GAAA,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,EAC5B;GAAA,CAAC,8CAA8C,CAC/C;GAAA,CAAC,YAAY,CAAC,SAAS,CAAC,MAAM,EAE9B;;GAAA,CAAC,mSAAmS,CACpS;GAAA,CAAC,YAAY,CAAC,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,EAChD;GAAA,CAAC,2GAA2G,CAC5G;GAAA,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAC1B;EAAA,GAAG,CAAA;IACJ,CAAC,CAAC,CAAA;AACH,CAAC,CAAC,CAAA"} \ No newline at end of file +{"version":3,"file":"jsx-types-react.test.jsx","sourceRoot":"","sources":["../src/jsx-types-react.test.tsx"],"names":[],"mappings":"AAAA,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAE5B,OAAO,EAAC,SAAS,EAAE,gBAAgB,EAAE,eAAe,EAAC,MAAM,gBAAgB,CAAA;AAC3E,OAAO,EAAC,OAAO,EAAC,MAAM,cAAc,CAAA;AACpC,OAAO,EAAC,KAAK,EAAC,MAAM,YAAY,CAAA;AAChC,OAAO,EAAC,OAAO,EAAC,MAAM,kBAAkB,CAAA;AAKxC;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;IAEG,WAAW;4BADhB,OAAO,CAAC,wBAAwB,CAAC;;;;sBACR,OAAO;;;;;;;;;;;;;;;;2BAAf,SAAQ,WAAO;;;;oCAC/B,SAAS;uCAIT,gBAAgB;yCAShB,SAAS;yCAGT,SAAS;uCAQT,KAAK;sCAML,eAAe;YAjBL,kLAAI,SAAS,6DAEvB;YACU,6LAAI,SAAS,wEAGvB;YAnBU,0KAAA,QAAQ,6BAAR,QAAQ,2FAAmC;YAIpC,mLAAA,WAAW,6BAAX,WAAW,iGAAO;YAoB7B,mLAAA,WAAW,6BAAX,WAAW,iGAA4C;YAM7C,gLAAA,UAAU,6BAAV,UAAU,+FAAM;YA/BlC,6KAgCC;;;YAhCK,uDAAW;;QACL,QAAQ,IADd,mDAAW,kDACkC,IAAI,GAAA;QAEtD,cAAc,0DAAG,KAAK,EAAA;QAEJ,WAAW,sDAAG,IAAI,EAAA;QAEpC,UAAU,6DAAG,CAAC,EAAA;QAEd;;;;WAIG;QACQ,IAAI,SAAS;YACvB,OAAO,IAAI,CAAC,UAAU,CAAA;QACvB,CAAC;QACU,IAAI,SAAS,CAAC,CAA2B;YACnD,+EAA+E;YAC/E,IAAI,CAAC,UAAU,GAAG,CAAW,CAAA;QAC9B,CAAC;QAED,uDAAuD;QACvD,gBAAgB,CAAiB;QAE1B,WAAW,sDAAwC,IAAI,EAAA;QAE9D,YAAY,6DAAG,GAAG,EAAA;QAElB,aAAa,GAAG,CAAC,CAAA;QAEA,UAAU,qDAAG,GAAG,EAAA;;;;;;;;AAGlC,WAAW,CAAA;AAEX,MAAM,SAAU,SAAQ,KAAK;IAC5B,GAAG,GAAG,CAAC,CAAA;CACP;AAUD,QAAQ,CAAC,uCAAuC,EAAE,GAAG,EAAE;IACtD,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACzC,CAAC;QAAA,EACA;GAAA,CAAC,kDAAkD,CACnD;GAAA,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAC,KAAK,EAAE,KAAK,EAAC,CAAC,EAEvG;;GAAA,CAAC,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,EAC9C;GAAA,CAAC,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,EAC9C;GAAA,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,EAC9C;GAAA,CAAC,8CAA8C,CAC/C;GAAA,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,EAC5B;GAAA,CAAC,8CAA8C,CAC/C;GAAA,CAAC,YAAY,CAAC,SAAS,CAAC,MAAM,EAE9B;;GAAA,CAAC,mSAAmS,CACpS;GAAA,CAAC,YAAY,CAAC,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,EAChD;GAAA,CAAC,2GAA2G,CAC5G;GAAA,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAEzB;;GAAA,CAAC,8EAA8E,CAC/E;GAAA,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,EAElC;;GAAA,CAAC,YAAY,CAAC,WAAW,EACzB;GAAA,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,EAChC;GAAA,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,EACjC;GAAA,CAAC,YAAY,CAAC,WAAW,CAAC,MAAM,EAChC;GAAA,CAAC,YAAY,CAAC,WAAW,CAAC,OAAO,EACjC;GAAA,CAAC,kFAAkF,CACnF;GAAA,CAAC,YAAY,CAAC,WAAW,CAAC,MAAM,EAChC;GAAA,CAAC,kDAAkD,CACnD;GAAA,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,EAE/B;;GAAA,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC,KAAgB,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAC3D;GAAA,CAAC,iEAAiE,CAClE;GAAA,CAAC,YAAY,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,KAAgB,EAAE,EAAE,CAAC,KAAK,CAAC,EACxD;GAAA,CAAC,uCAAuC,CACxC;GAAA,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC,KAAiB,EAAE,EAAE,CAAC,KAAK,CAAC,EAExD;;GAAA,CAAC,+IAA+I,CAChJ;GAAA,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,EAChC;GAAA,CAAC,iDAAiD,CAClD;GAAA,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,EACjC;GAAA,CAAC,gHAAgH,CACjH;GAAA,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,CAAC,CAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,EAE5C;;GAAA,CAAC,6EAA6E,CAC9E;GAAA,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,EAEjC;;GAAA,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,EAC9B;GAAA,CAAC,oDAAoD,CACrD;GAAA,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,EAChC;GAAA,CAAC,YAAY,CAAC,UAAU,CAAC,KAAK,EAC9B;GAAA,CAAC,YAAY,CAAC,UAAU,CAAC,MAAM,EAC/B;GAAA,CAAC,YAAY,CAAC,UAAU,CAAC,MAAM,EAC/B;GAAA,CAAC,YAAY,CAAC,UAAU,CAAC,MAAM,EAC/B;GAAA,CAAC,YAAY,CAAC,UAAU,CAAC,OAAO,EAChC;GAAA,CAAC,YAAY,CAAC,UAAU,CAAC,QAAQ,EACjC;GAAA,CAAC,YAAY,CAAC,UAAU,CAAC,QAAQ,EACjC;GAAA,CAAC,4DAA4D,CAC7D;GAAA,CAAC,YAAY,CAAC,UAAU,CAAC,QAAQ,EACjC;GAAA,CAAC,0DAA0D,CAC3D;GAAA,CAAC,YAAY,CAAC,UAAU,CAAC,MAAM,EAC/B;GAAA,CAAC,4DAA4D,CAC7D;GAAA,CAAC,YAAY,CAAC,UAAU,CAAC,QAAQ,EAClC;EAAA,GAAG,CAAA;IACJ,CAAC,CAAC,CAAA;AACH,CAAC,CAAC,CAAA"} \ No newline at end of file diff --git a/dist/jsx-types-solid.test.d.ts b/dist/jsx-types-solid.test.d.ts index 3df1786..bae5f00 100644 --- a/dist/jsx-types-solid.test.d.ts +++ b/dist/jsx-types-solid.test.d.ts @@ -1,15 +1,55 @@ -import type { ElementAttributes } from './LumeElement.js'; -declare class SomeElement extends HTMLElement { +import { Element, type ElementAttributes } from './LumeElement.js'; +type SomeElementAttributes = 'someProp' | 'someBoolean' | 'otherProp' | 'onsomeevent' | 'onnotanevent' | 'someNumber'; +/** + * Note, decorators are not required for defining JSX types, but we are using + * decorators here to show the best practice: + * + * You want to select *only* properties decorated with attribute decorators and + * on* event properties. Technically the JSX types will work if you select + * any plain properties, but it won't be type safe because the JSX types + * will include string types, which the decorators are responsible for + * converting into the non-string values. + * + * To have well-defined, consistent, and interoperable elements, you always want + * properties that are paired with attributes. Otherwise you'll have elements + * that don't work well in plain HTML, and that require plain JS to operate, and + * that can also make them more difficult to use in some non-custom-element + * frameworks where they will need to be referenced for manipulation in JS + * instead of in declarative templates. When all properties are mapped to + * attributes, it makes them capable of always receiving data from HTML sent + * from a server, for example HTML with any language on a backend. + * + * In rare cases, having a JS property that is not paired with an attribute is + * needed, but strive to avoid this. An example where this might be inevitable + * is when wrapping a non-custom-element framework component in a custom + * element, where the non-custom-element component accepts only special types of + * objects via its props, and those objects are not representable as strings (or + * it would be difficult to do so). But even in these cases, an approach is to + * map a set of attribute properties to those special objects instead of + * accepting (or as alternative to accepting) the special objects. + */ +declare class SomeElement extends Element { + #private; someProp: 'true' | 'false' | boolean; + ignoredBoolean: boolean; + someBoolean: boolean; + /** This is a getter/setter whose getter always returns number, but whose setter can accept a specific non-number value which is coerced into a number. */ get otherProp(): number; set otherProp(_: this['__set__otherProp']); /** do not use this property, its only for JSX types */ __set__otherProp: number | 'foo'; + onsomeevent: ((event: SomeEvent) => void) | null; + onnotanevent: number; + ignoredNumber: number; + someNumber: number; +} +declare class SomeEvent extends Event { + foo: number; } declare module 'solid-js' { namespace JSX { interface IntrinsicElements { - 'some-element': ElementAttributes; + 'some-element': ElementAttributes; } } } diff --git a/dist/jsx-types-solid.test.d.ts.map b/dist/jsx-types-solid.test.d.ts.map index 7e97015..e685767 100644 --- a/dist/jsx-types-solid.test.d.ts.map +++ b/dist/jsx-types-solid.test.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"jsx-types-solid.test.d.ts","sourceRoot":"","sources":["../src/jsx-types-solid.test.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,kBAAkB,CAAA;AAEvD,cAAM,WAAY,SAAQ,WAAW;IACpC,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAO;IAE3C,IAAI,SAAS,IAAI,MAAM,CAEtB;IACD,IAAI,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,kBAAkB,CAAC,EAAI;IAE7C,uDAAuD;IACvD,gBAAgB,EAAG,MAAM,GAAG,KAAK,CAAA;CACjC;AAID,OAAO,QAAQ,UAAU,CAAC;IACzB,UAAU,GAAG,CAAC;QACb,UAAU,iBAAiB;YAC1B,cAAc,EAAE,iBAAiB,CAAC,WAAW,EAAE,UAAU,GAAG,WAAW,CAAC,CAAA;SACxE;KACD;CACD"} \ No newline at end of file +{"version":3,"file":"jsx-types-solid.test.d.ts","sourceRoot":"","sources":["../src/jsx-types-solid.test.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAC,OAAO,EAAE,KAAK,iBAAiB,EAAC,MAAM,kBAAkB,CAAA;AAEhE,KAAK,qBAAqB,GAAG,UAAU,GAAG,aAAa,GAAG,WAAW,GAAG,aAAa,GAAG,cAAc,GAAG,YAAY,CAAA;AAErH;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,cACM,WAAY,SAAQ,OAAO;;IACrB,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAO;IAEtD,cAAc,UAAQ;IAEJ,WAAW,UAAO;IAIpC,0JAA0J;IAC1J,IAAe,SAAS,IAAI,MAAM,CAEjC;IACD,IAAe,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,kBAAkB,CAAC,EAEnD;IAED,uDAAuD;IACvD,gBAAgB,EAAG,MAAM,GAAG,KAAK,CAAA;IAE1B,WAAW,EAAE,CAAC,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC,GAAG,IAAI,CAAO;IAE9D,YAAY,SAAM;IAElB,aAAa,SAAI;IAEA,UAAU,SAAM;CACjC;AAID,cAAM,SAAU,SAAQ,KAAK;IAC5B,GAAG,SAAI;CACP;AAED,OAAO,QAAQ,UAAU,CAAC;IACzB,UAAU,GAAG,CAAC;QACb,UAAU,iBAAiB;YAC1B,cAAc,EAAE,iBAAiB,CAAC,WAAW,EAAE,qBAAqB,CAAC,CAAA;SACrE;KACD;CACD"} \ No newline at end of file diff --git a/dist/jsx-types-solid.test.jsx b/dist/jsx-types-solid.test.jsx index edf139c..2d97905 100644 --- a/dist/jsx-types-solid.test.jsx +++ b/dist/jsx-types-solid.test.jsx @@ -1,18 +1,147 @@ /* @jsxImportSource solid-js */ -class SomeElement extends HTMLElement { - someProp = true; - get otherProp() { - return 0; +var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) { + var useValue = arguments.length > 2; + for (var i = 0; i < initializers.length; i++) { + value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); } - set otherProp(_) { } - /** do not use this property, its only for JSX types */ - __set__otherProp; -} + return useValue ? value : void 0; +}; +var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { + function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } + var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; + var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; + var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); + var _, done = false; + for (var i = decorators.length - 1; i >= 0; i--) { + var context = {}; + for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; + for (var p in contextIn.access) context.access[p] = contextIn.access[p]; + context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; + var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); + if (kind === "accessor") { + if (result === void 0) continue; + if (result === null || typeof result !== "object") throw new TypeError("Object expected"); + if (_ = accept(result.get)) descriptor.get = _; + if (_ = accept(result.set)) descriptor.set = _; + if (_ = accept(result.init)) initializers.unshift(_); + } + else if (_ = accept(result)) { + if (kind === "field") initializers.unshift(_); + else descriptor[key] = _; + } + } + if (target) Object.defineProperty(target, contextIn.name, descriptor); + done = true; +}; +import { attribute, booleanAttribute, numberAttribute } from './attribute.js'; +import { element } from './element.js'; +import { event } from './event.js'; +import { Element } from './LumeElement.js'; +/** + * Note, decorators are not required for defining JSX types, but we are using + * decorators here to show the best practice: + * + * You want to select *only* properties decorated with attribute decorators and + * on* event properties. Technically the JSX types will work if you select + * any plain properties, but it won't be type safe because the JSX types + * will include string types, which the decorators are responsible for + * converting into the non-string values. + * + * To have well-defined, consistent, and interoperable elements, you always want + * properties that are paired with attributes. Otherwise you'll have elements + * that don't work well in plain HTML, and that require plain JS to operate, and + * that can also make them more difficult to use in some non-custom-element + * frameworks where they will need to be referenced for manipulation in JS + * instead of in declarative templates. When all properties are mapped to + * attributes, it makes them capable of always receiving data from HTML sent + * from a server, for example HTML with any language on a backend. + * + * In rare cases, having a JS property that is not paired with an attribute is + * needed, but strive to avoid this. An example where this might be inevitable + * is when wrapping a non-custom-element framework component in a custom + * element, where the non-custom-element component accepts only special types of + * objects via its props, and those objects are not representable as strings (or + * it would be difficult to do so). But even in these cases, an approach is to + * map a set of attribute properties to those special objects instead of + * accepting (or as alternative to accepting) the special objects. + */ +let SomeElement = (() => { + let _classDecorators = [element('some-element-solid-jsx')]; + let _classDescriptor; + let _classExtraInitializers = []; + let _classThis; + let _classSuper = Element; + let _instanceExtraInitializers = []; + let _someProp_decorators; + let _someProp_initializers = []; + let _someProp_extraInitializers = []; + let _someBoolean_decorators; + let _someBoolean_initializers = []; + let _someBoolean_extraInitializers = []; + let _get_otherProp_decorators; + let _set_otherProp_decorators; + let _onsomeevent_decorators; + let _onsomeevent_initializers = []; + let _onsomeevent_extraInitializers = []; + let _someNumber_decorators; + let _someNumber_initializers = []; + let _someNumber_extraInitializers = []; + var SomeElement = class extends _classSuper { + static { _classThis = this; } + static { + const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; + _someProp_decorators = [attribute]; + _someBoolean_decorators = [booleanAttribute]; + _get_otherProp_decorators = [attribute]; + _set_otherProp_decorators = [attribute]; + _onsomeevent_decorators = [event]; + _someNumber_decorators = [numberAttribute]; + __esDecorate(this, null, _get_otherProp_decorators, { kind: "getter", name: "otherProp", static: false, private: false, access: { has: obj => "otherProp" in obj, get: obj => obj.otherProp }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate(this, null, _set_otherProp_decorators, { kind: "setter", name: "otherProp", static: false, private: false, access: { has: obj => "otherProp" in obj, set: (obj, value) => { obj.otherProp = value; } }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate(null, null, _someProp_decorators, { kind: "field", name: "someProp", static: false, private: false, access: { has: obj => "someProp" in obj, get: obj => obj.someProp, set: (obj, value) => { obj.someProp = value; } }, metadata: _metadata }, _someProp_initializers, _someProp_extraInitializers); + __esDecorate(null, null, _someBoolean_decorators, { kind: "field", name: "someBoolean", static: false, private: false, access: { has: obj => "someBoolean" in obj, get: obj => obj.someBoolean, set: (obj, value) => { obj.someBoolean = value; } }, metadata: _metadata }, _someBoolean_initializers, _someBoolean_extraInitializers); + __esDecorate(null, null, _onsomeevent_decorators, { kind: "field", name: "onsomeevent", static: false, private: false, access: { has: obj => "onsomeevent" in obj, get: obj => obj.onsomeevent, set: (obj, value) => { obj.onsomeevent = value; } }, metadata: _metadata }, _onsomeevent_initializers, _onsomeevent_extraInitializers); + __esDecorate(null, null, _someNumber_decorators, { kind: "field", name: "someNumber", static: false, private: false, access: { has: obj => "someNumber" in obj, get: obj => obj.someNumber, set: (obj, value) => { obj.someNumber = value; } }, metadata: _metadata }, _someNumber_initializers, _someNumber_extraInitializers); + __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers); + SomeElement = _classThis = _classDescriptor.value; + if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); + __runInitializers(_classThis, _classExtraInitializers); + } + someProp = (__runInitializers(this, _instanceExtraInitializers), __runInitializers(this, _someProp_initializers, true)); + ignoredBoolean = (__runInitializers(this, _someProp_extraInitializers), false); + someBoolean = __runInitializers(this, _someBoolean_initializers, true); + #otherProp = (__runInitializers(this, _someBoolean_extraInitializers), 0); + /** This is a getter/setter whose getter always returns number, but whose setter can accept a specific non-number value which is coerced into a number. */ + get otherProp() { + return this.#otherProp; + } + set otherProp(_) { + this.#otherProp = _; // here you would coerce "foo" into a number, for example. + } + /** do not use this property, its only for JSX types */ + __set__otherProp; + onsomeevent = __runInitializers(this, _onsomeevent_initializers, null); + onnotanevent = (__runInitializers(this, _onsomeevent_extraInitializers), 123); + ignoredNumber = 0; + someNumber = __runInitializers(this, _someNumber_initializers, 123); + constructor() { + super(...arguments); + __runInitializers(this, _someNumber_extraInitializers); + } + }; + return SomeElement = _classThis; +})(); SomeElement; +class SomeEvent extends Event { + foo = 0; +} describe('JSX types with ElementAttributes', () => { it('derives JSX types from classes', () => { ; <> + {/* Ensure common element attributes still work. */} + event.button} aria-hidden="true" class="foo" style="color: red"/> + @@ -21,12 +150,176 @@ describe('JSX types with ElementAttributes', () => { {/* @ts-expect-error good, 'blah' is invalid */} + + + + {/* @ts-expect-error good, number is invalid */} + + {/* @ts-expect-error good, someProp JSX is not valid, has to be dash-cased version of the JS prop, or use the prop: prefix */} + + {/* @ts-expect-error good, 'blah' is invalid */} + + {/* Additionally TypeScript will allow unknown dash-case props (the attr: can be used here to tell Solid to set the element attributes instead of the JS properties) */} + {/* @ts-expect-error string types can be checked, here an invalid string type */} + + + + + + + {/* @ts-expect-error good, "blah" is not valid */} + + {/* @ts-expect-error good, "blah" is not valid */} + + + + + + + {/* @ts-expect-error good, "blah" is not valid */} + + {/* @ts-expect-error good, "blah" is not valid */} + + + + + {/* @ts-expect-error good, only booleans are allowed when using `bool:` */} + + {/* @ts-expect-error good, only booleans are allowed when using `bool:` */} + + {/* @ts-expect-error good, "blah" is not valid */} + + {/* @ts-expect-error good, "blah" is not valid */} + + + + + {/* @ts-expect-error good, only the strings "false" and "false" are allowed in attribute form */} + + {/* @ts-expect-error good, only the strings "false" and "false" are allowed in attribute form */} + + {/* @ts-expect-error good, "blah" is not valid */} + + {/* @ts-expect-error good, "blah" is not valid */} + + + {/* @ts-expect-error `ignoredBoolean` was not selected, not available in JSX */} + + + + + + + {/* @ts-expect-error good, "blah" is not valid */} + + {/* @ts-expect-error good, "blah" is not valid */} + + + + + + + {/* @ts-expect-error good, "blah" is not valid */} + + {/* @ts-expect-error good, "blah" is not valid */} + + + + + {/* @ts-expect-error good, only booleans are allowed when using `bool:` */} + + {/* @ts-expect-error good, only booleans are allowed when using `bool:` */} + + {/* @ts-expect-error good, "blah" is not valid */} + + {/* @ts-expect-error good, "blah" is not valid */} + + + + + {/* @ts-expect-error good, only the strings "false" and "false" are allowed in attribute form */} + + {/* @ts-expect-error good, only the strings "false" and "false" are allowed in attribute form */} + + {/* @ts-expect-error good, "blah" is not valid */} + + {/* @ts-expect-error good, "blah" is not valid */} + + {/* @ts-expect-error foo doesn't exist. TypeScript will only check existence of properties without dashes */} + + event.foo}/> + event.foo}/> + {/* @ts-expect-error wrong event type */} + event}/> + {/* @ts-expect-error wrong event type */} + event}/> + + {/* @ts-expect-error the property cannot be used like this, as Solid will try to pass the number to addEventListener, so we make it error with `never`. Use prop: or attr: instead. */} + + {/* @ts-expect-error only strings can be assigned to attributes */} + + + + + {/* @ts-expect-error `ignoredNumber` was not selected, not available in JSX */} + + + + {/* @ts-expect-error good, `false` is not a number */} + + + + + + + + + {/* @ts-expect-error good, "0z1010" is not a number string */} + + {/* @ts-expect-error good, "blah" is not a number string */} + + {/* @ts-expect-error good, "1.blah" is not a number string */} + + + + {/* @ts-expect-error good, `false` is not a number */} + + + + + + + + + {/* @ts-expect-error good, "0z1010" is not a number string */} + + {/* @ts-expect-error good, "blah" is not a number string */} + + {/* @ts-expect-error good, "1.blah" is not a number string */} + + + {/* @ts-expect-error good, attribute accepts only strings */} + + {/* @ts-expect-error good, `false` is not a number string */} + + + + + + + + + {/* @ts-expect-error good, "0z1010" is not a number string */} + + {/* @ts-expect-error good, "blah" is not a number string */} + + {/* @ts-expect-error good, "1.blah" is not a number string */} + ; }); }); -export {}; //# sourceMappingURL=jsx-types-solid.test.jsx.map \ No newline at end of file diff --git a/dist/jsx-types-solid.test.jsx.map b/dist/jsx-types-solid.test.jsx.map index bd4d335..0dc89a2 100644 --- a/dist/jsx-types-solid.test.jsx.map +++ b/dist/jsx-types-solid.test.jsx.map @@ -1 +1 @@ -{"version":3,"file":"jsx-types-solid.test.jsx","sourceRoot":"","sources":["../src/jsx-types-solid.test.tsx"],"names":[],"mappings":"AAAA,+BAA+B;AAI/B,MAAM,WAAY,SAAQ,WAAW;IACpC,QAAQ,GAA+B,IAAI,CAAA;IAE3C,IAAI,SAAS;QACZ,OAAO,CAAC,CAAA;IACT,CAAC;IACD,IAAI,SAAS,CAAC,CAA2B,IAAG,CAAC;IAE7C,uDAAuD;IACvD,gBAAgB,CAAiB;CACjC;AAED,WAAW,CAAA;AAUX,QAAQ,CAAC,kCAAkC,EAAE,GAAG,EAAE;IACjD,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACzC,CAAC;QAAA,EACA;GAAA,CAAC,YAAY,CAAC,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,EAChD;GAAA,CAAC,YAAY,CAAC,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,EAChD;GAAA,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,EAChD;GAAA,CAAC,8CAA8C,CAC/C;GAAA,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,EAC7B;GAAA,CAAC,8CAA8C,CAC/C;GAAA,CAAC,YAAY,CAAC,UAAU,CAAC,MAAM,EAE/B;;GAAA,CAAC,sKAAsK,CACvK;GAAA,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,EAC1D;GAAA,CAAC,2GAA2G,CAC5G;GAAA,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAC1B;EAAA,GAAG,CAAA;IACJ,CAAC,CAAC,CAAA;AACH,CAAC,CAAC,CAAA"} \ No newline at end of file +{"version":3,"file":"jsx-types-solid.test.jsx","sourceRoot":"","sources":["../src/jsx-types-solid.test.tsx"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/react.d.ts b/dist/react.d.ts index d87c077..bb28244 100644 --- a/dist/react.d.ts +++ b/dist/react.d.ts @@ -1,13 +1,13 @@ import type { HTMLAttributes as ReactHTMLAttributes, DetailedHTMLProps as ReactDetailedHTMLProps } from 'react'; -import type { RemoveAccessors, RemovePrefixes, SetterTypePrefix, WithStringValues } from './LumeElement.js'; +import type { BooleanProps, EventProps, FunctionsOnly, NonBooleanProps, NonEventProps, NonNumberProps, NumberProps, RemoveAccessors, RemoveSetterPrefixes, SetterTypePrefix, WithBooleanStringValues, WithNumberStringValues, WithStringValues } from './LumeElement.js'; /** * Similar to ElementAttributes, but for defining element attribute types for * React JSX. See LUME Element's [TypeScript * docs](https://docs.lume.io/#/guide/making-elements?id=typescript) for * details. */ -export type ReactElementAttributes, SetterTypePrefix>, AdditionalProperties extends object = {}> = Omit, ElementType>, SelectedProperties | keyof AdditionalProperties> & { +export type ReactElementAttributes, SetterTypePrefix>, AdditionalProperties extends object = {}> = Omit, El>, SelectedProperties | keyof AdditionalProperties> & { /** The 'has' attribute from the 'element-behaviors' package. If element-behaviors is installed and imported (it is if you're using `lume` 3D elements) then this specifies which behaviors to instantiate on the given element. */ has?: string; -} & Partial, SetterTypePrefix>, SelectedProperties>>> & AdditionalProperties; +} & Partial>>>> & Partial>> & Partial>>> & Partial>>> & AdditionalProperties; //# sourceMappingURL=react.d.ts.map \ No newline at end of file diff --git a/dist/react.d.ts.map b/dist/react.d.ts.map index c33566f..efb3ae8 100644 --- a/dist/react.d.ts.map +++ b/dist/react.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,cAAc,IAAI,mBAAmB,EAAE,iBAAiB,IAAI,sBAAsB,EAAC,MAAM,OAAO,CAAA;AAC7G,OAAO,KAAK,EAAC,eAAe,EAAE,cAAc,EAAE,gBAAgB,EAAE,gBAAgB,EAAC,MAAM,kBAAkB,CAAA;AAGzG;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,CACjC,WAAW,SAAS,WAAW,EAC/B,kBAAkB,SAAS,MAAM,cAAc,CAAC,eAAe,CAAC,WAAW,CAAC,EAAE,gBAAgB,CAAC,EAC/F,oBAAoB,SAAS,MAAM,GAAG,EAAE,IACrC,IAAI,CACN,sBAAsB,CAAC,mBAAmB,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC,EACrE,kBAAkB,GAAG,MAAM,oBAAoB,CAC/C,GAEC;IACD,mOAAmO;IACnO,GAAG,CAAC,EAAE,MAAM,CAAA;CACZ,GAEC,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,WAAW,CAAC,EAAE,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAEnH,oBAAoB,CAAA"} \ No newline at end of file +{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,cAAc,IAAI,mBAAmB,EAAE,iBAAiB,IAAI,sBAAsB,EAAC,MAAM,OAAO,CAAA;AAC7G,OAAO,KAAK,EACX,YAAY,EACZ,UAAU,EACV,aAAa,EACb,eAAe,EACf,aAAa,EACb,cAAc,EACd,WAAW,EACX,eAAe,EACf,oBAAoB,EACpB,gBAAgB,EAChB,uBAAuB,EACvB,sBAAsB,EACtB,gBAAgB,EAChB,MAAM,kBAAkB,CAAA;AAGzB;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,CACjC,EAAE,EACF,kBAAkB,SAAS,MAAM,oBAAoB,CAAC,eAAe,CAAC,EAAE,CAAC,EAAE,gBAAgB,CAAC,EAC5F,oBAAoB,SAAS,MAAM,GAAG,EAAE,IAEtC,IAAI,CACL,sBAAsB,CAAC,mBAAmB,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EACnD,kBAAkB,GAAG,MAAM,oBAAoB,CAC/C,GAEC;IACD,mOAAmO;IACnO,GAAG,CAAC,EAAE,MAAM,CAAA;CACZ,GAEC,OAAO,CAAC,gBAAgB,CAAC,cAAc,CAAC,eAAe,CAAC,aAAa,CAAC,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,GAGjG,OAAO,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAE1D,OAAO,CAAC,uBAAuB,CAAC,YAAY,CAAC,aAAa,CAAC,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC,GAErF,OAAO,CAAC,sBAAsB,CAAC,WAAW,CAAC,aAAa,CAAC,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC,GAEnF,oBAAoB,CAAA"} \ No newline at end of file diff --git a/src/LumeElement.ts b/src/LumeElement.ts index 7fa0013..0651428 100644 --- a/src/LumeElement.ts +++ b/src/LumeElement.ts @@ -502,52 +502,126 @@ type Template = TemplateContent | (() => TemplateContent) * ``` */ export type ElementAttributes< - ElementType extends HTMLElement, - SelectedProperties extends keyof RemovePrefixes, SetterTypePrefix>, + El, + SelectedProperties extends keyof RemoveSetterPrefixes, SetterTypePrefix>, AdditionalProperties extends object = {}, -> = Omit< - JSX.HTMLAttributes, - SelectedProperties | keyof AdditionalProperties | 'onerror' -> - & { - // Fixes the onerror JSX prop type (https://github.com/microsoft/TypeScript-DOM-lib-generator/issues/1821) - onerror?: ((error: ErrorEvent) => void) | null - } +> = + // Any props inherited from HTMLElement except for any that we will override from the custom element subclass or AdditionalProperties + & Omit< + JSX.HTMLAttributes, + SelectedProperties | keyof AdditionalProperties | 'onerror' + > + // Fixes the onerror JSX prop type (https://github.com/microsoft/TypeScript-DOM-lib-generator/issues/1821) + & { onerror?: ((error: ErrorEvent) => void) | null } + + // All non-'on' non-boolean properties + & Partial< DashCasedProps< WithStringValues< NonNumberProps< NonBooleanProps< NonOnProps > > > > > + + // All 'on' properties that are not functions, they will always error when not prefixed with prop: or attr: + & Partial>, never>> + + // All non-event properties that are not boolean, prefixed with prop: + & Partial< PrefixProps<'prop:', WithStringValues< NonNumberProps< NonBooleanProps< NonEventProps > > > > > + + // All non-event properties that are not boolean, prefixed with attr: + & Partial< PrefixProps<'attr:', DashCasedProps< AsStringValues< NonNumberProps< NonBooleanProps< NonEventProps > > > > > > + + // Boolean attributes + & Partial< + DashCasedProps< WithBooleanStringValues< BooleanProps< Pick, SelectedProperties> > > > + & PrefixProps<'bool:', DashCasedProps< AsBooleanValues< BooleanProps< Pick, SelectedProperties> > > > > + & PrefixProps<'prop:', WithBooleanStringValues< BooleanProps< Pick, SelectedProperties> > > > + & PrefixProps<'attr:', DashCasedProps< AsBooleanStringValues< BooleanProps< Pick, SelectedProperties> > > > > + > + // Number attributes & Partial< - DashCasedProps< - WithStringValues< - Pick< - RemovePrefixes, SetterTypePrefix>, - SelectedProperties - > - > - > + DashCasedProps< WithNumberStringValues< NumberProps< Pick, SelectedProperties> > > > + & PrefixProps<'prop:', WithNumberStringValues< NumberProps< Pick, SelectedProperties> > > > + & PrefixProps<'attr:', DashCasedProps< AsNumberStringValues< NumberProps< Pick, SelectedProperties> > > > > > + // Pick the `on*` event handler types from the element type, without string values (only functions) + & Partial>> + // Also map `on*` event handler types to `on:*` prop types for JSX + & Partial>>> + & AdditionalProperties +// This maps __set__foo, replacing any existing `get foo` type, so that the JSX prop type will be that of the specified setter type instead of the getter type. +type RemapSetters = RemoveSetterPrefixes, SetterTypePrefix> + +type NonOnProps> = Pick, OmitFromUnion>> + +export type NonEventProps, SetterTypePrefix>> = + // All non-'on' properties + NonOnProps & + // All 'on' properties that are not functions + NonFunctionsOnly> + +export type EventProps = Pick>> + +export type NonBooleanProps = Omit> + +export type BooleanProps = {[K in keyof T as T[K] extends boolean | 'true' | 'false' ? K : never]: T[K]} + +export type NonNumberProps = Omit> + +export type NumberProps = {[K in keyof T as T[K] extends number ? K : never]: T[K]} + +export type FunctionsOnly = {[K in keyof T as NonNullable extends (...args: any[]) => any ? K : never]: T[K]} + +export type NonFunctionsOnly = { + [K in keyof T as ((...args: any[]) => any) extends NonNullable ? never : K]: T[K] +} + /** * Make all non-string properties union with |string because they can all * receive string values from string attributes like opacity="0.5" (those values * are converted to the types of values they should be, f.e. reading a * `@numberAttribute` property always returns a `number`) */ -export type WithStringValues = { - // [Property in keyof Type]: NonNullable extends string ? Type[Property] : Type[Property] | string - [Property in keyof Type]: PickFromUnion extends never +export type WithStringValues = { + [K in keyof T]: PickFromUnion extends never + ? // if the type does not include a type assignable to string + T[K] | string + : // otherwise it does + T[K] +} + +export type WithBooleanStringValues = {[K in keyof T]: T[K] | 'true' | 'false'} +export type AsBooleanStringValues = {[K in keyof T]: 'true' | 'false'} +export type AsBooleanValues = {[K in keyof T]: boolean} +export type WithNumberStringValues = {[K in keyof T]: T[K] | `${number}`} +export type AsNumberStringValues = {[K in keyof T]: `${number}`} +export type AsValues = {[K in keyof T]: V} + +type AsStringValues = { + [K in keyof T]: PickFromUnion extends never ? // if the type does not include a type assignable to string - Type[Property] | string + string : // otherwise it does - Type[Property] + T[K] } type StringKeysOnly = OmitFromUnion -type OmitFromUnion = T extends TypeToOmit ? never : T +export type OmitFromUnion = T extends TypeToOmit ? never : T type PickFromUnion = T extends TypeToPick ? T : never -export type RemovePrefixes = { +export type EventKeys = T extends `on${infer _}` ? T : never + +type AddDelimitersToEventKeys = { + [K in keyof T as K extends string ? AddDelimiters : never]: T[K] +} + +type AddDelimiters = T extends `${'on'}${infer Right}` + ? `${'on'}${Delimiter}${Right}` + : T + +type PrefixProps = {[K in keyof T as K extends string ? `${Prefix}${K}` : K]: T[K]} + +export type RemoveSetterPrefixes = { [K in keyof T as K extends string ? RemovePrefix : K]: T[K] } @@ -559,8 +633,6 @@ export type RemoveAccessors = { type SetterTypeKeysFor = keyof PrefixPick -type PrefixPick = { - [K in keyof T as K extends `${Prefix}${string}` ? K : never]: T[K] -} +type PrefixPick = {[K in keyof T as K extends `${Prefix}${string}` ? K : never]: T[K]} export type SetterTypePrefix = '__set__' diff --git a/src/attribute.ts b/src/attribute.ts index 0771ab0..b813a6e 100644 --- a/src/attribute.ts +++ b/src/attribute.ts @@ -6,11 +6,11 @@ import type {PropKey} from 'classy-solid/dist/decorators/types.js' export const __classFinishers: ((Class: ElementCtor) => void)[] = [] -/** The `@attribute` decorator currently works only on fields, getters, and setters. */ type AttributeDecoratorContext = | ClassFieldDecoratorContext | ClassGetterDecoratorContext | ClassSetterDecoratorContext + | ClassAccessorDecoratorContext /** * A decorator that when used on a property or accessor causes an HTML attribute @@ -18,12 +18,15 @@ type AttributeDecoratorContext = * decorated property. For example, if the `@attribute` decorator is used on a * property called `firstName`, then an attribute called `first-name` will be * mapped to the property. Any time that the attribute value changes (f.e. with - * `el.setAttribute`), the attribute value will propgate to the property a - * trigger an update. + * `el.setAttribute`), the attribute value will propgate to the property which + * triggers reactivity. * * The decorated property is backed by a Solid.js signal, thus useful in effects * or templates. * + * The `@attribute` decorator is only for public fields, getters, setters, and + * auto accessors. + * * Example: * * ```js @@ -70,7 +73,6 @@ function handleAttributeDecoration( if (isPrivate) throw new Error('@attribute is not supported on private fields yet.') if (isStatic) throw new Error('@attribute is not supported on static fields.') - // TODO decorate on prototype? Or decorate on instance? __classFinishers.push((Class: ElementCtor) => __setUpAttribute(Class, name, attributeHandler)) if (kind === 'field') { @@ -90,11 +92,15 @@ function handleAttributeDecoration( return initialValue } } else if (kind === 'getter' || kind === 'setter') { - if (useSignal) signal(value, context) + if (useSignal) return signal(value, context) + } else if (kind === 'accessor') { + context.addInitializer(function (this: any) { + if (!('default' in attributeHandler)) attributeHandler.default = this[name] + }) + + if (useSignal) return signal(value, context) } else { - throw new Error( - '@attribute is only for use on fields, getters, and setters. Auto accessor support is coming next if there is demand for it.', - ) + throw new Error('@attribute is only for use on fields, getters/setters, and auto accessors.') } return undefined // shush TS diff --git a/src/element.ts b/src/element.ts index 9934587..a6b521c 100644 --- a/src/element.ts +++ b/src/element.ts @@ -5,6 +5,7 @@ import {Element, type AttributeHandlerMap} from './LumeElement.js' import {__classFinishers, __setUpAttribute, __attributesToProps, type AttributeHandler} from './attribute.js' import type {AnyConstructor} from 'lowclass/dist/Constructor.js' import type {DecoratedValue, PropKey} from 'classy-solid/dist/decorators/types.js' +import {__eventSetter, eventFields, type EventMetadata} from './event.js' type PossibleStatics = { observedAttributes?: string[] @@ -310,6 +311,33 @@ function applyElementDecoration( set: newSetter, }) } + + const meta = metadata as EventMetadata + + // Set up event fields (accessors and getters/setters are handled in the @event decorator directly). + if (Object.hasOwn(meta, eventFields)) { + for (const name of meta[eventFields]) { + const eventName = name.replace(/^on/, '') + + const desc = Object.getOwnPropertyDescriptor(this, name)! + + if (desc.get || desc.set) + throw new Error( + '@event is not supported on properties with getters/setters yet. Use the @event decorator on a field that is not converted to a getter/setter by anything else.', + ) + + let value = desc.value as EventListener | null + const get = () => value + const set = (v: EventListener | null) => (value = v) + + Object.defineProperty(this, name, { + enumerable: true, + configurable: true, + get, + set: __eventSetter(name, eventName, get, set), + }) + } + } }) } } diff --git a/src/event.test.ts b/src/event.test.ts new file mode 100644 index 0000000..f22f670 --- /dev/null +++ b/src/event.test.ts @@ -0,0 +1,153 @@ +import {element} from './element.js' +import {event} from './event.js' +import {Element} from './LumeElement.js' + +describe('@event', () => { + it.only('registers event listeners when assigned to event-named properties', () => { + let testEvent: Event | null = null + const ontestevent = (e: Event) => (testEvent = e) + + let otherEvent: Event | null = null + const onotherevent = (e: Event) => (otherEvent = e) + + let anotherEvent: Event | null = null + const onanother = (e: Event) => (anotherEvent = e) + + let yetanotherEvent: Event | null = null + const onyetanother = (e: Event) => (yetanotherEvent = e) + + let onemoreEvent: Event | null = null + const ononemore = (e: Event) => (onemoreEvent = e) + + let lastoneEvent: Event | null = null + const onlastone = (e: Event) => (lastoneEvent = e) + + @element('event-listeners') + class MyEl extends Element { + @event accessor ontestevent = ontestevent + + @event accessor onotherevent: ((event: Event) => void) | null = null + + #onanother: EventListener | null = onanother + + @event get onanother() { + return this.#onanother + } + @event set onanother(v: EventListener | null) { + this.#onanother = v + } + + #onyetanother: EventListener | null = null + + @event get onyetanother() { + return this.#onyetanother + } + @event set onyetanother(v: EventListener | null) { + this.#onyetanother = v + } + + @event ononemore: EventListener | null = ononemore + + @event onlastone: EventListener | null = null + + override connectedCallback() { + super.connectedCallback() + + this.dispatchEvent(new Event('testevent')) + this.dispatchEvent(new Event('otherevent')) + this.dispatchEvent(new Event('another')) + this.dispatchEvent(new Event('yetanother')) + this.dispatchEvent(new Event('onemore')) + this.dispatchEvent(new Event('lastone')) + } + } + + const el = new MyEl() + + el.onotherevent = onotherevent + el.onyetanother = onyetanother + el.onlastone = onlastone + + document.body.append(el) + + expect(testEvent).toBeInstanceOf(Event) + expect(otherEvent).toBeInstanceOf(Event) + expect(String(anotherEvent)).toBe('null') + expect(yetanotherEvent).toBeInstanceOf(Event) + expect(onemoreEvent).toBeInstanceOf(Event) + expect(lastoneEvent).toBeInstanceOf(Event) + + testEvent = null + otherEvent = null + anotherEvent = null + yetanotherEvent = null + onemoreEvent = null + lastoneEvent = null + + el.dispatchEvent(new Event('testevent')) + el.dispatchEvent(new Event('otherevent')) + el.dispatchEvent(new Event('another')) + el.dispatchEvent(new Event('yetanother')) + el.dispatchEvent(new Event('onemore')) + el.dispatchEvent(new Event('lastone')) + + expect(testEvent).toBeInstanceOf(Event) + expect(otherEvent).toBeInstanceOf(Event) + expect(String(anotherEvent)).toBe('null') + expect(yetanotherEvent).toBeInstanceOf(Event) + expect(onemoreEvent).toBeInstanceOf(Event) + expect(lastoneEvent).toBeInstanceOf(Event) + + testEvent = null + otherEvent = null + anotherEvent = null + yetanotherEvent = null + onemoreEvent = null + lastoneEvent = null + + let testEvent2: Event | null = null + const ontestevent2 = (e: Event) => (testEvent2 = e) + el.ontestevent = ontestevent2 + + let otherEvent2: Event | null = null + const onotherevent2 = (e: Event) => (otherEvent2 = e) + el.onotherevent = onotherevent2 + + let anotherEvent2: Event | null = null + const onanother2 = (e: Event) => (anotherEvent2 = e) + el.onanother = onanother2 + + let yetanotherEvent2: Event | null = null + const onyetanother2 = (e: Event) => (yetanotherEvent2 = e) + el.onyetanother = onyetanother2 + + let onemoreEvent2: Event | null = null + const ononemore2 = (e: Event) => (onemoreEvent2 = e) + el.ononemore = ononemore2 + + let lastoneEvent2: Event | null = null + const onlastone2 = (e: Event) => (lastoneEvent2 = e) + el.onlastone = onlastone2 + + el.dispatchEvent(new Event('testevent')) + el.dispatchEvent(new Event('otherevent')) + el.dispatchEvent(new Event('another')) + el.dispatchEvent(new Event('yetanother')) + el.dispatchEvent(new Event('onemore')) + el.dispatchEvent(new Event('lastone')) + + expect(String(testEvent)).toBe('null') + expect(String(otherEvent)).toBe('null') + expect(String(anotherEvent)).toBe('null') + expect(String(yetanotherEvent)).toBe('null') + expect(String(onemoreEvent)).toBe('null') + expect(String(lastoneEvent)).toBe('null') + + expect(testEvent2).toBeInstanceOf(Event) + expect(otherEvent2).toBeInstanceOf(Event) + expect(anotherEvent2).toBeInstanceOf(Event) + expect(yetanotherEvent2).toBeInstanceOf(Event) + expect(onemoreEvent2).toBeInstanceOf(Event) + expect(lastoneEvent2).toBeInstanceOf(Event) + }) +}) diff --git a/src/event.ts b/src/event.ts new file mode 100644 index 0000000..c36fe7e --- /dev/null +++ b/src/event.ts @@ -0,0 +1,98 @@ +type EventDecoratorContext = + | ClassFieldDecoratorContext + | ClassGetterDecoratorContext + | ClassSetterDecoratorContext + | ClassAccessorDecoratorContext + +export const eventFields = Symbol('eventFields') + +export type EventMetadata = {[eventFields]: Set} + +/** + * A decorator that when used on an accessor causes an event listener to be + * registered for events with the same name (but without the "on" prefix) on + * the element. For example, if the `@event` decorator is used on a property + * called `onexpand`, then an event listener for the `expand` event will be + * registered on the element using the assigned handler. + * + * This is useful because: + * + * - seeing the `@event` properties in the class definition serves as a + * reference as to which events the element will emit. + * - types for `on*` JSX props are derived from the types of these properties + * (f.e. when using ElementAttributes or ReactElementAttributes to define JSX + * types). + * - it gives new custom elements feature parity with the `on*` event properties + * that builtin elements have. + */ +export function event(value: T, context: EventDecoratorContext): any { + const {name, kind, private: isPrivate} = context + const metadata = context.metadata as EventMetadata + + if (typeof name === 'symbol') throw new Error('Cannot currently use symbols as event names.') + if (isPrivate) throw new Error('Cannot use private field names as event names.') + + const eventName = name.replace(/^on/, '') + + if (kind === 'field') { + if (!Object.hasOwn(metadata, eventFields)) metadata[eventFields] = new Set() + + metadata[eventFields].add(name) + + return function (this: Element, handler: EventListener | null) { + if (handler) this.addEventListener(eventName, handler) + return handler + } + } else if (kind === 'getter' || kind === 'setter') { + if (kind === 'getter') return value as () => EventListener | null + else { + const set = value as (v: EventListener | null) => void + let setCalled = false + + context.addInitializer(function (this: any) { + queueMicrotask(() => { + if (typeof this[name] === 'function' && !setCalled) + console.warn( + `@event decorator: initial value for ${name} was not handled. Start the initial value as null, then set it to the desired handler in your constructor instead.`, + ) + }) + }) + + const setter = __eventSetter(name, eventName, null, set) + + return function (this: Element, handler: EventListener | null) { + setCalled = true + setter.call(this, handler) + } + } + } else if (kind === 'accessor') { + const {get, set} = value as {get: () => EventListener | null; set: (v: EventListener | null) => void} + + return { + init: function (this: Element, handler: EventListener | null) { + if (handler) this.addEventListener(eventName, handler) + return handler + }, + get, + set: __eventSetter(name, eventName, get, set), + } + } else throw new Error('Use @event on a field, getter/setter, or accessor.') +} + +export function __eventSetter( + name: string, + eventName: string, + get: (() => EventListener | null) | null, + set: (handler: EventListener | null) => void, +) { + return function (this: Element, handler: EventListener | null) { + if (handler && typeof handler !== 'function') throw new Error('Event handlers must be functions.') + + const previousHandler = get ? get.call(this) : ((this as any)[name] as EventListener | null) + + if (previousHandler) this.removeEventListener(eventName, previousHandler) + if (handler) this.addEventListener(eventName, handler) + + set.call(this, handler) + } +} diff --git a/src/index.ts b/src/index.ts index 3d9ece3..cca84a8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,7 @@ export * from './LumeElement.js' export * from './attribute.js' export * from './element.js' export * from './css.js' +export * from './event.js' export { identityTemplateTag, camelCaseToDash, diff --git a/src/jsx-types-react.test.tsx b/src/jsx-types-react.test.tsx index d8bc68a..75b9d10 100644 --- a/src/jsx-types-react.test.tsx +++ b/src/jsx-types-react.test.tsx @@ -1,25 +1,86 @@ /* @jsxImportSource react */ +import {attribute, booleanAttribute, numberAttribute} from './attribute.js' +import {element} from './element.js' +import {event} from './event.js' +import {Element} from './LumeElement.js' import type {ReactElementAttributes} from './react.js' -class SomeElement extends HTMLElement { - someProp: 'true' | 'false' | boolean = true +type SomeElementAttributes = 'someProp' | 'someBoolean' | 'otherProp' | 'onsomeevent' | 'onnotanevent' | 'someNumber' - get otherProp(): number { - return 0 +/** + * Note, decorators are not required for defining JSX types, but we are using + * decorators here to show the best practice: + * + * You want to select *only* properties decorated with attribute decorators and + * on* event properties. Technically the JSX types will work if you select + * any plain properties, but it won't be type safe because the JSX types + * will include string types, which the decorators are responsible for + * converting into the non-string values. + * + * To have well-defined, consistent, and interoperable elements, you always want + * properties that are paired with attributes. Otherwise you'll have elements + * that don't work well in plain HTML, and that require plain JS to operate, and + * that can also make them more difficult to use in some non-custom-element + * frameworks where they will need to be referenced for manipulation in JS + * instead of in declarative templates. When all properties are mapped to + * attributes, it makes them capable of always receiving data from HTML sent + * from a server, for example HTML with any language on a backend. + * + * In rare cases, having a JS property that is not paired with an attribute is + * needed, but strive to avoid this. An example where this might be inevitable + * is when wrapping a non-custom-element framework component in a custom + * element, where the non-custom-element component accepts only special types of + * objects via its props, and those objects are not representable as strings (or + * it would be difficult to do so). But even in these cases, an approach is to + * map a set of attribute properties to those special objects instead of + * accepting (or as alternative to accepting) the special objects. + */ +@element('some-element-react-jsx') +class SomeElement extends Element { + @attribute someProp: 'true' | 'false' | boolean = true + + ignoredBoolean = false + + @booleanAttribute someBoolean = true + + #otherProp = 0 + + /** + * This is a getter/setter whose getter always returns number, but whose + * setter can accept a specific non-number value which is coerced into a + * number. + */ + @attribute get otherProp(): number { + return this.#otherProp + } + @attribute set otherProp(_: this['__set__otherProp']) { + // Here you would need custom logic to coerce "foo" into a number, for example. + this.#otherProp = _ as number } - set otherProp(_: this['__set__otherProp']) {} /** do not use this property, its only for JSX types */ __set__otherProp!: number | 'foo' + + @event onsomeevent: ((event: SomeEvent) => void) | null = null + + onnotanevent = 123 + + ignoredNumber = 0 + + @numberAttribute someNumber = 123 } SomeElement +class SomeEvent extends Event { + foo = 0 +} + declare module 'react' { namespace JSX { interface IntrinsicElements { - 'some-element': ReactElementAttributes + 'some-element': ReactElementAttributes } } } @@ -27,6 +88,9 @@ declare module 'react' { describe('JSX types with ReactElementAttributes', () => { it('derives JSX types from classes', () => { ;<> + {/* Ensure common element attributes still work. */} + event.button} aria-hidden="true" className="foo" style={{color: 'red'}} /> + @@ -39,6 +103,52 @@ describe('JSX types with ReactElementAttributes', () => { {/* @ts-expect-error foo doesn't exist. TypeScript will only check existence of properties without dashes */} + + {/* @ts-expect-error `ignoredBoolean` was not selected, not available in JSX */} + + + + + + + + {/* @ts-expect-error good, only booleans and boolean strings allowed, no strings */} + + {/* @ts-expect-error good, only booleans allowed */} + + + event.foo} /> + {/* @ts-expect-error on:-prefixed event props are not for React */} + event} /> + {/* @ts-expect-error wrong event type */} + event} /> + + {/* This is fine in React, it will set the JS property to the given value instead of adding an event listener if the value is not a function. */} + + {/* @ts-expect-error good, boolean is not valid */} + + {/* @ts-expect-error good, event handler is not valid (although at runtime React will listen for "notanevent") */} + e} /> + + {/* @ts-expect-error `ignoredNumber` was not selected, not available in JSX */} + + + + {/* @ts-expect-error good, `false` is not a number */} + + + + + + + + + {/* @ts-expect-error good, "0z1010" is not a number string */} + + {/* @ts-expect-error good, "blah" is not a number string */} + + {/* @ts-expect-error good, "1.blah" is not a number string */} + }) }) diff --git a/src/jsx-types-solid.test.tsx b/src/jsx-types-solid.test.tsx index 913556f..1032ecf 100644 --- a/src/jsx-types-solid.test.tsx +++ b/src/jsx-types-solid.test.tsx @@ -1,25 +1,80 @@ /* @jsxImportSource solid-js */ -import type {ElementAttributes} from './LumeElement.js' +import {attribute, booleanAttribute, numberAttribute} from './attribute.js' +import {element} from './element.js' +import {event} from './event.js' +import {Element, type ElementAttributes} from './LumeElement.js' -class SomeElement extends HTMLElement { - someProp: 'true' | 'false' | boolean = true +type SomeElementAttributes = 'someProp' | 'someBoolean' | 'otherProp' | 'onsomeevent' | 'onnotanevent' | 'someNumber' - get otherProp(): number { - return 0 +/** + * Note, decorators are not required for defining JSX types, but we are using + * decorators here to show the best practice: + * + * You want to select *only* properties decorated with attribute decorators and + * on* event properties. Technically the JSX types will work if you select + * any plain properties, but it won't be type safe because the JSX types + * will include string types, which the decorators are responsible for + * converting into the non-string values. + * + * To have well-defined, consistent, and interoperable elements, you always want + * properties that are paired with attributes. Otherwise you'll have elements + * that don't work well in plain HTML, and that require plain JS to operate, and + * that can also make them more difficult to use in some non-custom-element + * frameworks where they will need to be referenced for manipulation in JS + * instead of in declarative templates. When all properties are mapped to + * attributes, it makes them capable of always receiving data from HTML sent + * from a server, for example HTML with any language on a backend. + * + * In rare cases, having a JS property that is not paired with an attribute is + * needed, but strive to avoid this. An example where this might be inevitable + * is when wrapping a non-custom-element framework component in a custom + * element, where the non-custom-element component accepts only special types of + * objects via its props, and those objects are not representable as strings (or + * it would be difficult to do so). But even in these cases, an approach is to + * map a set of attribute properties to those special objects instead of + * accepting (or as alternative to accepting) the special objects. + */ +@element('some-element-solid-jsx') +class SomeElement extends Element { + @attribute someProp: 'true' | 'false' | boolean = true + + ignoredBoolean = false + + @booleanAttribute someBoolean = true + + #otherProp = 0 + + /** This is a getter/setter whose getter always returns number, but whose setter can accept a specific non-number value which is coerced into a number. */ + @attribute get otherProp(): number { + return this.#otherProp + } + @attribute set otherProp(_: this['__set__otherProp']) { + this.#otherProp = _ as number // here you would coerce "foo" into a number, for example. } - set otherProp(_: this['__set__otherProp']) {} /** do not use this property, its only for JSX types */ __set__otherProp!: number | 'foo' + + @event onsomeevent: ((event: SomeEvent) => void) | null = null + + onnotanevent = 123 + + ignoredNumber = 0 + + @numberAttribute someNumber = 123 } SomeElement +class SomeEvent extends Event { + foo = 0 +} + declare module 'solid-js' { namespace JSX { interface IntrinsicElements { - 'some-element': ElementAttributes + 'some-element': ElementAttributes } } } @@ -27,6 +82,9 @@ declare module 'solid-js' { describe('JSX types with ElementAttributes', () => { it('derives JSX types from classes', () => { ;<> + {/* Ensure common element attributes still work. */} + event.button} aria-hidden="true" class="foo" style="color: red" /> + @@ -35,10 +93,175 @@ describe('JSX types with ElementAttributes', () => { {/* @ts-expect-error good, 'blah' is invalid */} + + + + {/* @ts-expect-error good, number is invalid */} + + {/* @ts-expect-error good, someProp JSX is not valid, has to be dash-cased version of the JS prop, or use the prop: prefix */} + + {/* @ts-expect-error good, 'blah' is invalid */} + + {/* Additionally TypeScript will allow unknown dash-case props (the attr: can be used here to tell Solid to set the element attributes instead of the JS properties) */} + {/* @ts-expect-error string types can be checked, here an invalid string type */} + + + + + + + {/* @ts-expect-error good, "blah" is not valid */} + + {/* @ts-expect-error good, "blah" is not valid */} + + + + + + + {/* @ts-expect-error good, "blah" is not valid */} + + {/* @ts-expect-error good, "blah" is not valid */} + + + + + {/* @ts-expect-error good, only booleans are allowed when using `bool:` */} + + {/* @ts-expect-error good, only booleans are allowed when using `bool:` */} + + {/* @ts-expect-error good, "blah" is not valid */} + + {/* @ts-expect-error good, "blah" is not valid */} + + + + + {/* @ts-expect-error good, only the strings "false" and "false" are allowed in attribute form */} + + {/* @ts-expect-error good, only the strings "false" and "false" are allowed in attribute form */} + + {/* @ts-expect-error good, "blah" is not valid */} + + {/* @ts-expect-error good, "blah" is not valid */} + + + {/* @ts-expect-error `ignoredBoolean` was not selected, not available in JSX */} + + + + + + + {/* @ts-expect-error good, "blah" is not valid */} + + {/* @ts-expect-error good, "blah" is not valid */} + + + + + + + {/* @ts-expect-error good, "blah" is not valid */} + + {/* @ts-expect-error good, "blah" is not valid */} + + + + + {/* @ts-expect-error good, only booleans are allowed when using `bool:` */} + + {/* @ts-expect-error good, only booleans are allowed when using `bool:` */} + + {/* @ts-expect-error good, "blah" is not valid */} + + {/* @ts-expect-error good, "blah" is not valid */} + + + + + {/* @ts-expect-error good, only the strings "false" and "false" are allowed in attribute form */} + + {/* @ts-expect-error good, only the strings "false" and "false" are allowed in attribute form */} + + {/* @ts-expect-error good, "blah" is not valid */} + + {/* @ts-expect-error good, "blah" is not valid */} + + {/* @ts-expect-error foo doesn't exist. TypeScript will only check existence of properties without dashes */} + + event.foo} /> + event.foo} /> + {/* @ts-expect-error wrong event type */} + event} /> + {/* @ts-expect-error wrong event type */} + event} /> + + {/* @ts-expect-error the property cannot be used like this, as Solid will try to pass the number to addEventListener, so we make it error with `never`. Use prop: or attr: instead. */} + + {/* @ts-expect-error only strings can be assigned to attributes */} + + + + + {/* @ts-expect-error `ignoredNumber` was not selected, not available in JSX */} + + + + {/* @ts-expect-error good, `false` is not a number */} + + + + + + + + + {/* @ts-expect-error good, "0z1010" is not a number string */} + + {/* @ts-expect-error good, "blah" is not a number string */} + + {/* @ts-expect-error good, "1.blah" is not a number string */} + + + + {/* @ts-expect-error good, `false` is not a number */} + + + + + + + + + {/* @ts-expect-error good, "0z1010" is not a number string */} + + {/* @ts-expect-error good, "blah" is not a number string */} + + {/* @ts-expect-error good, "1.blah" is not a number string */} + + + {/* @ts-expect-error good, attribute accepts only strings */} + + {/* @ts-expect-error good, `false` is not a number string */} + + + + + + + + + {/* @ts-expect-error good, "0z1010" is not a number string */} + + {/* @ts-expect-error good, "blah" is not a number string */} + + {/* @ts-expect-error good, "1.blah" is not a number string */} + }) }) diff --git a/src/react.ts b/src/react.ts index 11e59d0..95bce8d 100644 --- a/src/react.ts +++ b/src/react.ts @@ -1,5 +1,19 @@ import type {HTMLAttributes as ReactHTMLAttributes, DetailedHTMLProps as ReactDetailedHTMLProps} from 'react' -import type {RemoveAccessors, RemovePrefixes, SetterTypePrefix, WithStringValues} from './LumeElement.js' +import type { + BooleanProps, + EventProps, + FunctionsOnly, + NonBooleanProps, + NonEventProps, + NonNumberProps, + NumberProps, + RemoveAccessors, + RemoveSetterPrefixes, + SetterTypePrefix, + WithBooleanStringValues, + WithNumberStringValues, + WithStringValues, +} from './LumeElement.js' // prettier-ignore /** @@ -9,11 +23,12 @@ import type {RemoveAccessors, RemovePrefixes, SetterTypePrefix, WithStringValues * details. */ export type ReactElementAttributes< - ElementType extends HTMLElement, - SelectedProperties extends keyof RemovePrefixes, SetterTypePrefix>, + El, + SelectedProperties extends keyof RemoveSetterPrefixes, SetterTypePrefix>, AdditionalProperties extends object = {}, -> = Omit< - ReactDetailedHTMLProps, ElementType>, +> = + & Omit< + ReactDetailedHTMLProps, El>, SelectedProperties | keyof AdditionalProperties > @@ -22,6 +37,13 @@ export type ReactElementAttributes< has?: string } - & Partial, SetterTypePrefix>, SelectedProperties>>> + & Partial>>>> + + // Pick the `onfoo` event handler types from the element type, without string values + & Partial>> + + & Partial>>> + + & Partial>>> & AdditionalProperties