import { TemplateResult } from 'lit';
import { DirectiveResult } from 'lit/directive.js';
import { HTMLElementTags, HTMLAttributes, GlobalEventHandlersCamelCase, SvgElementTags, DOMAttributes, AriaAttributes } from './generatedTypes.ts';
import { CustomAttributes } from './baseTypes.ts';
/**
* The "h" namespace is used to import JSX types for elements and attributes.
* It is imported in order to avoid conflicting global JSX issues.
*/
export declare namespace h {
export function h(sel: any, data?: any, text?: any): TemplateResult;
export type { LuminaJsx as JSX };
}
/**
* The references to this function are removed at build time.
*/
export declare const Fragment: (props: {
children?: JsxNode;
}) => TemplateResult;
/**
* @private
* The references to this function are removed at build time. You do not need
* to import it directly
*/
export declare function jsx(type: string, props: unknown, key?: unknown): JsxNode;
/**
* @private
* The references to this function are removed at build time. You do not need
* to import it directly
*/
export declare function jsxs(type: string, props: unknown, key?: unknown): JsxNode;
/**
* The JSX to lit-html conversion has a heuristic to determine whether a prop
* should be converted to a property or attribute at runtime. In cases where
* that heuristic is not sufficient, you can use the `bindAttribute()` function to
* explicitly tell the conversion to treat the prop as an attribute.
*
* This function call will be erased at build-time, thus it has no runtime
* impact. But that also means you should not call this function anywhere other
* than at the top level of a JSX prop value
*
* @example
* ```tsx
*
* ```
*
* Will be converted at build time into:
* ```ts
* html``
* ```
*
* @remarks
* If you often encounter cases where the JSX to lit-html incorrectly converts
* the prop to a property necessitating the use of `bindAttribute()`, please open
* an issue for Lumina.
*/
export declare const bindAttribute: (value: T) => T;
/**
* The JSX to lit-html conversion has a heuristic to determine whether a prop
* should be converted to a property, attribute or boolean attribute at runtime.
* In cases where that heuristic is not sufficient, you can use the
* `bindBooleanAttribute()` function to explicitly tell the conversion to treat the
* prop as a boolean attribute.
*
* This function call will be erased at build-time, thus it has no runtime
* impact. But that also means you should not call this function anywhere other
* than at the top level of a JSX prop value
*
* @see https://lit.dev/docs/templates/expressions/#boolean-attribute-expressions
*
* @example
* ```tsx
*
* ```
*
* Will be converted at build time into:
* ```ts
* html``
* ```
*
* @remarks
* If you often encounter cases where the JSX to lit-html incorrectly converts
* the prop necessitating the use of `bindBooleanAttribute()`, please open
* an issue for Lumina.
*/
export declare const bindBooleanAttribute: (value: T) => T;
/**
* The JSX to lit-html conversion has a heuristic to determine whether a prop
* should be converted to a property or attribute at runtime. In cases where
* that heuristic is not sufficient, you can use the `bindProperty()` function to
* explicitly tell the conversion to treat the prop as a property.
*
* This function call will be erased at build-time, thus it has no runtime
* impact. But that also means you should not call this function anywhere other
* than at the top level of a JSX prop value
*
* @example
* ```tsx
*
* ```
*
* Will be converted at build time into:
* ```ts
* html``
* ```
*
* @remarks
* If you often encounter cases where the JSX to lit-html incorrectly converts
* the prop to an attribute necessitating the use of `bindProperty()`, please open
* an issue for Lumina.
*
* @remarks
* This function is not named `property()` because that is already taken by
* Lit's \@property() decorator
*/
export declare const bindProperty: (value: T) => T;
/**
* The `bindEvent()` function lets you customize the event binding behavior by
* providing options like passive, capture, once and other options that you
* normally can provide to `addEventListener`
*
* This function call will be erased at build-time, thus it has no runtime
* impact.
*
* @example
* ```tsx
*
* ```tsx
*
* ```ts
* html``
* ```
*
* @remarks
* This function is a _JSX to lit-html_ adaptation of the Lit's event listener
* customization syntax.
* See https://lit.dev/docs/components/events/#event-options-decorator
*
*
* @remarks
* This function is not named `event` because there is a legacy `window.event`
* global that was interfering with auto-imports of this function.
*/
export declare const bindEvent: (descriptor: T | (AddEventListenerOptions & {
handleEvent: T;
})) => T;
export type JsxNode = DirectiveResult | JsxNodeArray | Node | TemplateResult | boolean | number | (NonNullable & string) | null | undefined;
interface JsxNodeArray extends Array {
}
/**
* By not requiring to have some sort of typings generation watcher to run
* in the background and generate types for the components based on the
* exposed properties, we improve developer experience a lot.
* (no need to run a watcher in the background, no need to commit an
* autogenerated file, fewer merge conflicts...)
*
* The trade-off is that we can't tell in TypeScript if component's public
* properties have a `@property()` decorator or not, so have to expose them
* all. To reduce the noise, we exclude some properties that we know are
* definitely not props (as they are coming from LitElement)
*
* An ESLint rule that mandates all properties to be private/protected or else
* to have a `@property()` decorator would mitigate the issue to a large
* extent.
*
* This does not impact the typings we publish - at build time we have all the
* information and can generate the typings that expose only the actual
* properties component declared.
*
* @remarks
* Do not exclude "manager" and "componentOnReady" since these properties are
* available both on lazy and non-lazy instance.
*/
type ExcludedProperties = "addController" | "attributeChangedCallback" | "connectedCallback" | "disconnectedCallback" | "el" | "hasUpdated" | "isUpdatePending" | "listen" | "load" | "loaded" | "removeController" | "render" | "renderOptions" | "renderRoot" | "requestUpdate" | "updateComplete" | "updated" | "willUpdate";
/**
* this.el property on a component only has the public properties of the
* component. All internal methods, properties, as well as LitElement methods
* are excluded. This type approximates what the public API of the component
* looks like.
*
* @example
* Usually, you don't need to use this type directly. If you have an
* `ArcgisCounter` element, you can get its el type by using
* `ArcgisCounter["el"]`
*
* @remarks
* By using Omit<>, TypeScript also "forgets" all private members of the
* passed in type, which is convenient for us.
*/
export type ToElement = Omit;
/**
* Utility type for getting the JSX prop types for a given component. In particular:
*
* - Excludes LitElement properties that should not be exposed to the end-user
* - Converts event .emit() properties into event callbacks
* - Replaces original HTMLElement property typings with the ones we provide for
* greater type-safety and control
* - For native events listeners, makes currentTarget equal to the component's
* HTML instance
*
* We mark all component properties as optional because there is no easy
* way for us to differentiate between public component properties and just
* regular members that don't have `@property()` decorator (presence or
* absence of decorator does not change the type). Thus, if we don't mark all
* properties as optional, TypeScript will force us to provide a value for all
* methods, and regular properties component may have.
*/
export type ToJsx = HTMLAttributes & Partial>> & RemapEvents;
/**
* From event emitters create event listener callbacks
*/
type RemapEvents = {
[Key in keyof Component as `on${Key & string}`]?: unknown extends Component[Key] ? never : Component[Key] extends {
emit: (...rest: never[]) => infer PayloadType;
} ? (event: PayloadType & {
currentTarget: Component["el"];
target: Component["el"];
}) => void : never;
};
/**
* This interface will be automatically extended in src/lumina.ts files to add
* typings for Stencil elements usages in Lumina. You do not need to manually
* extend this interface.
*
* @private
* @example
* ```ts
* import type { JSX as CalciteJSX } from "@esri/calcite-components/dist/types/components";
* import type { JSX as CommonComponentsJsx } from "@arcgis/common-components/dist/types/components";
*
* declare module "@arcgis/lumina" {
* interface ImportStencilElements
* extends CalciteJSX.IntrinsicElements,
* CommonComponentsJsx.IntrinsicElements {
* }
* }
* ```
*/
export interface ImportStencilElements {
}
/**
* Get the type of all events for a given component. Includes native DOM events
* and custom events.
*
* @example
* ```tsx
* render() {
* return ;
* }
* _handleViewClick(event: ToEvents["arcgisViewClick"]) {
* // event.detail
* // event.currentTarget
* }
* ```
*
* @remarks
* This helper is intended to be used on components defined within the same
* package. For external components, you can use
* `HTMLArcgisMapElement["arcgisViewClick"]` directly, without need for
* `ToEvents<>`.
*
* @remarks
* Alternative implementation of this type that is simpler, and potentially
* more performant, but looses "go to definition" information.
*
* ```tsx
* export type ToEvents = {
* [Key in keyof ToJsx as Key extends `on${infer EventName}`
* ? Uncapitalize
* : never]-?: ListenerToPayloadType[Key]>;
* };
*
* type ListenerToPayloadType = Listener extends (event: infer EventType) => unknown ? EventType : never;
* ```
*
* TypeScript issues that may fix this:
* - https://github.com/microsoft/TypeScript/issues/49909
* - https://github.com/microsoft/TypeScript/issues/50715
*/
export type ToEvents = GlobalEventTypes> & {
[Key in keyof Component as ListenerToPayloadType extends BaseEvent ? Key : never]-?: ListenerToPayloadType & {
currentTarget: MaybeEl;
target: MaybeEl;
};
};
type MaybeEl = Component extends {
el: unknown;
} ? Component["el"] : Component;
export interface TargetedEvent extends BaseEvent {
/**
* Returns any custom data event was created with.
*
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/CustomEvent/detail)
*/
readonly detail: Payload;
/**
* Returns the object whose event listener's callback is currently being invoked.
*
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/currentTarget)
*/
readonly currentTarget: Target;
/**
* Returns the object to which event is dispatched (its target).
*
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/target)
*/
readonly target: Target;
}
interface BaseEvent extends Omit {
/** @deprecated */
initCustomEvent(type: string, bubbles?: boolean, cancelable?: boolean, detail?: any): void;
}
/**
* From "GlobalEventHandlersCamelCase" extract event names and their payloads.
* Not using "HTMLElementEventMap" because that map has all events in lowercase.
*/
type GlobalEventTypes = {
[Key in keyof GlobalEventHandlersCamelCase as Key extends `on${infer EventName}` ? Uncapitalize : never]-?: Parameters[Key]>>[0];
};
type ListenerToPayloadType = unknown extends Listener ? void : Listener extends {
emit: (...rest: never[]) => infer PayloadType;
} ? PayloadType : Listener extends BaseEvent ? Listener : void;
/**
* Defined Lumina custom elements. This interface is used only for internal
* type-checking.
*/
export interface DeclareElements {
}
type ReMappedComponents = {
[Key in keyof Components]: Components[Key] extends {
el: unknown;
} ? ToJsx : never;
};
/**
* For common properties, add Lumina's types rather than use Stencil's types
*/
type ReMapStencilComponents = {
[Key in keyof Pick]: HTMLAttributes & ReMapStencilComponent;
};
type ReMapStencilComponent = {
[Key in keyof Component as FixupStencilEventCasing]: Component[Key];
};
type FixupStencilEventCasing = PropertyName extends `on${infer EventName}` ? `on${Uncapitalize}` : PropertyName;
/**
* These typings are based on dom-expressions typings:
* https://github.com/ryansolid/dom-expressions/blob/main/packages/dom-expressions/src/jsx.d.ts
*
* They in turn based the typings on Surplus and Inferno:
* - https://github.com/adamhaile/surplus/blob/master/index.d.ts
* - https://github.com/infernojs/inferno/blob/master/packages/inferno/src/core/types.ts
*
* Documentation about how to type JSX in TypeScript:
* https://www.typescriptlang.org/docs/handbook/jsx.html
*/
export declare namespace LuminaJsx {
export type Element = TemplateResult;
export type ElementType = JsxNode;
export interface ElementClass {
}
export interface ElementAttributesProperty {
}
export interface IntrinsicClassAttributes {
}
export interface ElementChildrenAttribute {
children: JsxNode;
}
export interface IntrinsicAttributes {
/**
* The `key` is a special attribute that can be set on any element.
*
* At build-time it is translated into the `keyed()` directive:
* https://lit.dev/docs/templates/directives/#keyed
*
* @remarks
* Unlike in React or Stencil, any JavaScript value is acceptable as a key
*/
key?: unknown;
}
export interface IntrinsicElements extends HTMLElementTags, SvgElementTags, ReMappedComponents, ReMapStencilComponents {
}
export type { CustomAttributes, DOMAttributes, HTMLAttributes, HTMLElementTags, SvgElementTags, AriaAttributes };
}
export {};