/
githubmirror
/
angular
Обзор
Документация
Войти
/
githubmirror
/
angular
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
packages/elements/test/slots_spec.ts
161 строка
5 KB
Matthieu Riegler
refactor(core): remove `ComponentFactoryResolver` usages
13 апр 2026, 16:00
13 апр 2026, 16:00
df9eed4
Код
Авторство
О чём код?
/** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.dev/license */ import { Component, destroyPlatform, EventEmitter, Input, NgModule, Output, reflectComponentType, ViewEncapsulation, } from '@angular/core'; import {BrowserModule, platformBrowser} from '@angular/platform-browser'; import {createCustomElement, NgElement} from '../src/create-custom-element'; describe('slots', () => { let testContainer: HTMLDivElement; beforeAll((done) => { testContainer = document.createElement('div'); document.body.appendChild(testContainer); destroyPlatform(); platformBrowser() .bootstrapModule(TestModule) .then((ref) => { const injector = ref.injector; testElements.forEach((comp) => { const compType = reflectComponentType(comp)!; customElements.define(compType.selector, createCustomElement(comp, {injector})); }); }) .then(done, done.fail); }); afterAll(() => { destroyPlatform(); testContainer.remove(); (testContainer as any) = null; }); it('should use slots to project content', () => { const tpl = `<default-slot-el><span class="projected"></span></default-slot-el>`; testContainer.innerHTML = tpl; const testEl = testContainer.querySelector('default-slot-el')!; const content = testContainer.querySelector('span.projected')!; const slot = testEl.shadowRoot!.querySelector('slot')!; const assignedNodes = slot.assignedNodes(); expect(assignedNodes[0]).toBe(content); }); it('should use a named slot to project content', () => { const tpl = `<named-slot-el><span class="projected" slot="header"></span></named-slot-el>`; testContainer.innerHTML = tpl; const testEl = testContainer.querySelector('named-slot-el')!; const content = testContainer.querySelector('span.projected')!; const slot = testEl.shadowRoot!.querySelector('slot[name=header]') as HTMLSlotElement; const assignedNodes = slot.assignedNodes(); expect(assignedNodes[0]).toBe(content); }); it('should use named slots to project content', () => { const tpl = ` <named-slots-el> <span class="projected-header" slot="header"></span> <span class="projected-body" slot="body"></span> </named-slots-el>`; testContainer.innerHTML = tpl; const testEl = testContainer.querySelector('named-slots-el')!; const headerContent = testContainer.querySelector('span.projected-header')!; const bodyContent = testContainer.querySelector('span.projected-body')!; const headerSlot = testEl.shadowRoot!.querySelector('slot[name=header]') as HTMLSlotElement; const bodySlot = testEl.shadowRoot!.querySelector('slot[name=body]') as HTMLSlotElement; expect(headerContent.assignedSlot).toBe(headerSlot); expect(bodyContent.assignedSlot).toBe(bodySlot); }); it('should listen to slotchange events', (done) => { const templateEl = document.createElement('template'); const tpl = ` <slot-events-el> <span class="projected">Content</span> </slot-events-el>`; templateEl.innerHTML = tpl; const template = templateEl.content.cloneNode(true) as DocumentFragment; const testEl = template.querySelector('slot-events-el')! as NgElement & SlotEventsComponent; testEl.addEventListener('slotEventsChange', (e) => { expect(testEl.slotEvents.length).toEqual(1); done(); }); testContainer.appendChild(template); expect(testEl.slotEvents.length).toEqual(0); }); }); // Helpers @Component({ selector: 'default-slot-el', template: '<div class="slotparent"><slot></slot></div>', encapsulation: ViewEncapsulation.ShadowDom, standalone: false, }) class DefaultSlotComponent { constructor() {} } @Component({ selector: 'named-slot-el', template: '<div class="slotparent"><slot name="header"></slot></div>', encapsulation: ViewEncapsulation.ShadowDom, standalone: false, }) class NamedSlotComponent { constructor() {} } @Component({ selector: 'named-slots-el', template: '<div class="slotparent"><slot name="header"></slot><slot name="body"></slot></div>', encapsulation: ViewEncapsulation.ShadowDom, standalone: false, }) class NamedSlotsComponent { constructor() {} } @Component({ selector: 'slot-events-el', template: '<slot (slotchange)="onSlotChange($event)"></slot>', encapsulation: ViewEncapsulation.ShadowDom, standalone: false, }) class SlotEventsComponent { @Input() slotEvents: Event[] = []; @Output() slotEventsChange = new EventEmitter(); constructor() {} onSlotChange(event: Event) { this.slotEvents.push(event); this.slotEventsChange.emit(event); } } const testElements = [ DefaultSlotComponent, NamedSlotComponent, NamedSlotsComponent, SlotEventsComponent, ]; @NgModule({imports: [BrowserModule], declarations: testElements}) class TestModule { ngDoBootstrap() {} }