import { default as ts } from 'typescript'; import { JsxContext } from './types.ts'; /** * By default, when we see a `key=""` prop, we convert it like this: * ```tsx * // before: *
* // after: * keyed('value', html`
`); * ``` * * However, when mapping over items, if key was provided, using `repeat()` Lit * directive is better for performance as that directive can track when items * change order. * * Without repeat, calling `keyed()` inside of `.map()` is going to be quite * expensive when a single item is added to the top - that will destroy each * element below it and re-create it. * * When key wasn't provided, we assume that the order of items is static or that * modifying the item dom node is cheaper than getting the key and reordering. * * We could have the Stencil to Lit codemod do the `.map()` to `repeat()` * conversion in cases when the map was given an arrow function with a JSX * element with a key, however, some issues with that: * * - For people coming from Stencil or React, it would be confusing to see * `repeat()` in the code rather than the familiar `.map()`. * - People may not know when to use which, or forget and use `.map()` with a * `key` inside. * - Since many JSX frameworks handle `key` inside a `.map()` correctly, if in * the future we move from Lit, it would be nice to have the `key` prop * already in the source code. * * Thus, instead of doing the conversion in the codemod, I am doing it at build * time in the _JSX to lit-html_ transformer. * * If we were to do this in the codemod, the same code would have to be written * anyway, but here we get ongoing benefit of having code always using the * correct, performant pattern. * * We are only replacing `.map()` with `repeat()` if the map JSX element has a * key prop. There may be some more complex patterns where key was used that we * can't yet detect - those may have worse performance, but the developer can * always call `repeat()` manually. * * @see https://github.com/lit/lit.dev/issues/1351 */ export declare function maybeInsertRepeatCall(context: JsxContext, node: ts.CallExpression): ts.CallExpression; export declare const unwrapExpression: (expression: T) => T | ts.Expression; export declare const isLiftedKey: (name: ts.JsxAttributeName, context: JsxContext) => boolean;