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 124 125 126 127 128 129 | 1x 1x 1x 38x 38x 38x 38x 38x 38x 38x 38x 38x 38x 38x 42x 42x 38x 76x 76x 461x 461x 461x 461x 461x 461x 2x 2x | /**
* 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;
this.maskInput({
value: el.value,
type: eventMap.get(inputType),
change: data,
pos: selStart,
previous: this.value
});
this.value = el.value;
this.onChange(this.value);
}
/** @internal */
@HostListener('blur')
protected blur(): void {
this.leaveInput();
this.onTouched();
}
/**
* Allow to adjust the input value when leaving the input field.
*/
protected leaveInput(): void {}
/**
* Enforce a format on user input.
*/
protected abstract maskInput(e: AddrInputEvent): void;
}
|