| /** |
| * @license |
| * Copyright 2022 Google LLC |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| import {css, html, LitElement, TemplateResult} from 'lit'; |
| import {customElement, property, query} from 'lit/decorators.js'; |
| import {DependencyToken, provide} from './dependency'; |
| |
| /** |
| * Example usage: |
| * |
| * const providerElement = await fixture<DIProviderElement>( |
| * wrapInProvider( |
| * html`<my-element-to-test></my-element-to-test>`, |
| * myModelToken, |
| * myModel, |
| * ) |
| * ); |
| * const element = providerElement.element as MyElementToTest; |
| * |
| * For injecting multiple tokens, make nested calls to `wrapInProvider` such as: |
| * |
| * wrapInProvider(wrapInProvider(html`...`, token1, value1), token2, value2); |
| */ |
| export function wrapInProvider<T>( |
| template: TemplateResult, |
| token: DependencyToken<T>, |
| value: T |
| ) { |
| return html` |
| <di-provider-element .token=${token} .value=${value} |
| >${template}</di-provider-element |
| > |
| `; |
| } |
| |
| /** |
| * Use `.element` to get the wrapped element for assertions. |
| */ |
| @customElement('di-provider-element') |
| export class DIProviderElement extends LitElement { |
| @property({type: Object}) |
| token?: DependencyToken<unknown>; |
| |
| @property({type: Object}) |
| value?: unknown; |
| |
| get element() { |
| return this.slotElement.assignedElements()[0]; |
| } |
| |
| private isProvided = false; |
| |
| @query('slot') |
| private slotElement!: HTMLSlotElement; |
| |
| static override get styles() { |
| return css` |
| :host() { |
| display: contents; |
| } |
| `; |
| } |
| |
| /** Only calls `provide` even after reconnection. */ |
| override connectedCallback(): void { |
| super.connectedCallback(); |
| if (!this.token || this.isProvided) return; |
| this.isProvided = true; |
| provide(this, this.token, () => this.value); |
| } |
| |
| override render() { |
| return html`<slot></slot>`; |
| } |
| } |