diff --git a/projects/cdk/directives/index.ts b/projects/cdk/directives/index.ts index ce0ad6c1b083..bbd7a9c6764e 100644 --- a/projects/cdk/directives/index.ts +++ b/projects/cdk/directives/index.ts @@ -9,6 +9,7 @@ export * from '@taiga-ui/cdk/directives/focus-trap'; export * from '@taiga-ui/cdk/directives/for'; export * from '@taiga-ui/cdk/directives/high-dpi'; export * from '@taiga-ui/cdk/directives/hovered'; +export * from '@taiga-ui/cdk/directives/input-mode'; export * from '@taiga-ui/cdk/directives/item'; export * from '@taiga-ui/cdk/directives/let'; export * from '@taiga-ui/cdk/directives/media'; diff --git a/projects/cdk/directives/input-mode/index.ts b/projects/cdk/directives/input-mode/index.ts new file mode 100644 index 000000000000..bf795beaabd5 --- /dev/null +++ b/projects/cdk/directives/input-mode/index.ts @@ -0,0 +1 @@ +export * from './input-mode.directive'; diff --git a/projects/cdk/directives/input-mode/input-mode.directive.ts b/projects/cdk/directives/input-mode/input-mode.directive.ts new file mode 100644 index 000000000000..bdda10761d7b --- /dev/null +++ b/projects/cdk/directives/input-mode/input-mode.directive.ts @@ -0,0 +1,26 @@ +import {Directive, inject, Input} from '@angular/core'; +import {TUI_IS_IOS} from '@taiga-ui/cdk/tokens'; +import {tuiInjectElement} from '@taiga-ui/cdk/utils'; + +/** + * Scrolls input into view on iOS, so it doesn't get covered by virtual keyboard + */ +@Directive({ + standalone: true, + selector: 'input[tuiInputMode]', +}) +export class TuiInputMode { + private readonly el = tuiInjectElement(); + private readonly ios = inject(TUI_IS_IOS); + + @Input() + set tuiInputMode(mode: string) { + const {inputMode} = this.el; + + this.el.inputMode = mode; + + if (inputMode === 'none' && this.ios && this.el.matches(':focus')) { + this.el.scrollIntoView(); + } + } +} diff --git a/projects/cdk/directives/input-mode/ng-package.json b/projects/cdk/directives/input-mode/ng-package.json new file mode 100644 index 000000000000..bebf62dcb5e5 --- /dev/null +++ b/projects/cdk/directives/input-mode/ng-package.json @@ -0,0 +1,5 @@ +{ + "lib": { + "entryFile": "index.ts" + } +} diff --git a/projects/experimental/components/input-phone-international/input-phone-international.component.ts b/projects/experimental/components/input-phone-international/input-phone-international.component.ts index 0fc41ff39129..3292dadd4ccb 100644 --- a/projects/experimental/components/input-phone-international/input-phone-international.component.ts +++ b/projects/experimental/components/input-phone-international/input-phone-international.component.ts @@ -17,8 +17,11 @@ import { import {takeUntilDestroyed, toObservable, toSignal} from '@angular/core/rxjs-interop'; import {FormsModule} from '@angular/forms'; import {MaskitoDirective} from '@maskito/angular'; -import {type MaskitoOptions, maskitoTransform} from '@maskito/core'; -import {maskitoInitialCalibrationPlugin} from '@maskito/core'; +import { + maskitoInitialCalibrationPlugin, + type MaskitoOptions, + maskitoTransform, +} from '@maskito/core'; import {maskitoGetCountryFromNumber, maskitoPhoneOptionsGenerator} from '@maskito/phone'; import {tuiAsControl, TuiControl} from '@taiga-ui/cdk/classes'; import {CHAR_PLUS, EMPTY_QUERY, TUI_DEFAULT_MATCHER} from '@taiga-ui/cdk/constants'; @@ -27,6 +30,7 @@ import { TuiAutoFocus, tuiAutoFocusOptionsProvider, } from '@taiga-ui/cdk/directives/auto-focus'; +import {TuiInputMode} from '@taiga-ui/cdk/directives/input-mode'; import {tuiFallbackValueProvider} from '@taiga-ui/cdk/tokens'; import {tuiInjectElement, tuiIsInputEvent} from '@taiga-ui/cdk/utils/dom'; import {tuiDirectiveBinding} from '@taiga-ui/cdk/utils/miscellaneous'; @@ -87,9 +91,8 @@ const NOT_FORM_CONTROL_SYMBOLS = /[^+\d]/g; tuiFallbackValueProvider(''), tuiAutoFocusOptionsProvider({preventScroll: true}), ], - hostDirectives: [MaskitoDirective, TuiWithTextfield], + hostDirectives: [MaskitoDirective, TuiWithTextfield, TuiInputMode], host: { - '[attr.inputmode]': 'open() ? "none" : "numeric"', '[attr.readonly]': 'readOnly() || null', '[disabled]': 'disabled()', '[value]': 'masked()', @@ -125,6 +128,12 @@ export class TuiInputPhoneInternational extends TuiControl { maskitoTransform(this.value(), this.mask() || {mask: /.*/}) || this.el.value, ); + protected readonly inputMode = tuiDirectiveBinding( + TuiInputMode, + 'tuiInputMode', + computed(() => (this.open() ? 'none' : 'numeric')), + ); + protected readonly filtered = computed(() => this.countries() .map((iso) => ({ diff --git a/projects/experimental/components/input-phone-international/input-phone-international.style.less b/projects/experimental/components/input-phone-international/input-phone-international.style.less index c2de87e9914a..9f87a6182c05 100644 --- a/projects/experimental/components/input-phone-international/input-phone-international.style.less +++ b/projects/experimental/components/input-phone-international/input-phone-international.style.less @@ -6,6 +6,10 @@ border-end-start-radius: 0; inline-size: calc(100% - var(--t-offset)); + tui-root:has(tui-dropdown-mobile) & { + caret-color: transparent; + } + & + label { padding-left: var(--t-offset); }