Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | 1x 1x 1x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 19x 19x 15x 26x 26x 433x 433x 433x 433x 433x 433x 433x | /** * Copyright (c) Siemens 2016 - 2025 * SPDX-License-Identifier: MIT */ import { booleanAttribute, computed, Directive, ElementRef, HostListener, inject, input, Renderer2, signal } from '@angular/core'; import { SI_FORM_ITEM_CONTROL } from '@siemens/element-ng/form'; const eventMap = new Map<string, 'insert' | 'delete' | 'paste'>([ ['insertText', 'insert'], ['insertFromPaste', 'paste'], ['deleteContentBackward', 'delete'] ]); export interface AddrInputEvent { type?: 'insert' | 'delete' | 'paste'; pos: number; change: string | null; value?: string | null; previous?: string | null; } /** * Base directive for ip address input fields. */ @Directive({ selector: 'input[siIpInput]', providers: [ { provide: SI_FORM_ITEM_CONTROL, useExisting: SiIpInputDirective } ], host: { '[id]': 'id()', '[disabled]': 'disabled() || null' } }) export abstract class SiIpInputDirective { private static idCounter = 0; protected readonly elementRef = inject(ElementRef<HTMLInputElement>); protected readonly renderer = inject(Renderer2); protected readonly inputEl = this.elementRef.nativeElement; /** * @defaultValue * ``` * `si-ip-input-${SiIpInputDirective.idCounter++}` * ``` */ readonly id = input(`si-ip-input-${SiIpInputDirective.idCounter++}`); /** * Enable CIDR (Classless Inter-Domain Routing) notation. * @defaultValue false */ readonly cidr = input(false, { transform: booleanAttribute }); /** * Whether the ip address input is disabled. * @defaultValue false */ // eslint-disable-next-line @angular-eslint/no-input-rename readonly disabledInput = input(false, { alias: 'disabled' }); private readonly disabledNgControl = signal(false); protected readonly disabled = computed(() => this.disabledInput() || this.disabledNgControl()); protected onTouched: () => void = () => {}; protected onChange: (value: any) => void = () => {}; protected value?: string | null = ''; registerOnChange(fn: any): void { this.onChange = fn; } registerOnTouched(fn: () => void): void { this.onTouched = fn; } setDisabledState(isDisabled: boolean): void { this.disabledNgControl.set(isDisabled); } writeValue(value?: string | null): void { this.value = value; this.renderer.setProperty(this.inputEl, 'value', value ?? ''); } @HostListener('input', ['$event']) protected onInput(e: Event): void { const el = e.target as HTMLInputElement; const selStart = el.selectionStart ?? 0; const { inputType, data } = e as InputEvent; const len = data?.length ?? 0; this.maskInput({ value: el.value, type: eventMap.get(inputType), change: data, pos: selStart - len, previous: this.value }); this.value = el.value; this.onChange(this.value); } @HostListener('blur') protected blur(): void { this.onTouched(); } abstract maskInput(e: AddrInputEvent): void; } |