import { IComponent } from '../module/component'; const OUTPUT_EMITTER = Symbol('outputEmitter'); export interface OutputEmitterRef { emit(value: T): void; [OUTPUT_EMITTER]: true; } export interface OutputOptions { alias?: string; } interface OutputFunction { (): OutputEmitterRef; (propertyName: string, component: IComponent, options?: OutputOptions): OutputEmitterRef; } function createOutputEmitter( propertyName: string, component: IComponent, options?: OutputOptions, ): OutputEmitterRef { const alias = options?.alias ?? propertyName; const emitter: OutputEmitterRef = { alias, component, options, emit: (value: T) => { const element = component._nativeElement; if (element) { const event = new CustomEvent(alias, { detail: value, bubbles: true, cancelable: true, }); element.dispatchEvent(event); } }, [OUTPUT_EMITTER]: true as const, }; return emitter; } function outputFn( propertyNameOrOptions?: string | OutputOptions, componentOrOptions?: IComponent | OutputOptions, options?: OutputOptions, ): OutputEmitterRef { if (typeof propertyNameOrOptions === 'string' && componentOrOptions && '_nativeElement' in (componentOrOptions as any)) { return createOutputEmitter( propertyNameOrOptions, componentOrOptions as IComponent, options, ); } return createOutputEmitter('', {} as IComponent, propertyNameOrOptions as OutputOptions); } export const output: OutputFunction = outputFn; export function createOutput( propertyName: string, component: IComponent, options?: OutputOptions, ): OutputEmitterRef { return createOutputEmitter(propertyName, component, options); } /** * Dekorator Output. * * Ten dekorator służy wyłącznie do zapewnienia poprawności typów w TypeScript * i jest podmieniany podczas kompilacji przez transformery. */ export function Output(bindingPropertyName?: string): PropertyDecorator { return (target: Object, propertyKey: string | symbol) => { }; }