Skip to content

Commit

Permalink
fix(addon-commerce): InputCardGroup fix Safari autofill (#9198)
Browse files Browse the repository at this point in the history
Co-authored-by: taiga-family-bot <[email protected]>
  • Loading branch information
waterplea and taiga-family-bot authored Sep 26, 2024
1 parent 7daeeb6 commit 1f5dfa5
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
Output,
ViewChild,
} from '@angular/core';
import {toSignal} from '@angular/core/rxjs-interop';
import {takeUntilDestroyed, toSignal} from '@angular/core/rxjs-interop';
import {FormsModule} from '@angular/forms';
import {MaskitoDirective} from '@maskito/angular';
import {WaResizeObserver} from '@ng-web-apis/resize-observer';
Expand All @@ -30,6 +30,7 @@ import {TuiLet} from '@taiga-ui/cdk/directives/let';
import {tuiTypedFromEvent} from '@taiga-ui/cdk/observables';
import {TuiMapperPipe} from '@taiga-ui/cdk/pipes/mapper';
import {tuiInjectId} from '@taiga-ui/cdk/services';
import {TUI_IS_WEBKIT} from '@taiga-ui/cdk/tokens';
import type {TuiBooleanHandler} from '@taiga-ui/cdk/types';
import {tuiInjectElement, tuiIsElement, tuiIsInput} from '@taiga-ui/cdk/utils/dom';
import {tuiIsNativeFocused, tuiIsNativeFocusedIn} from '@taiga-ui/cdk/utils/focus';
Expand Down Expand Up @@ -58,7 +59,7 @@ import {TUI_COMMON_ICONS} from '@taiga-ui/core/tokens';
import {TuiChevron} from '@taiga-ui/kit/directives/chevron';
import type {PolymorpheusContent} from '@taiga-ui/polymorpheus';
import {PolymorpheusOutlet, PolymorpheusTemplate} from '@taiga-ui/polymorpheus';
import {map, merge} from 'rxjs';
import {EMPTY, map, merge, Subject, switchMap, timer} from 'rxjs';

import {TUI_INPUT_CARD_GROUP_OPTIONS} from './input-card-group.options';
import {TUI_INPUT_CARD_GROUP_TEXTS} from './input-card-group.providers';
Expand Down Expand Up @@ -122,6 +123,7 @@ export class TuiInputCardGroup
@ViewChild('inputCVC')
private readonly inputCVC?: ElementRef<HTMLInputElement>;

private readonly focus$ = new Subject<void>();
private expirePrefilled = false;
private readonly paymentSystems = inject(TUI_PAYMENT_SYSTEM_ICONS);
private readonly options = inject(TUI_INPUT_CARD_GROUP_OPTIONS);
Expand All @@ -144,6 +146,14 @@ export class TuiInputCardGroup
protected readonly icons = inject(TUI_COMMON_ICONS);
protected readonly texts = toSignal(inject(TUI_INPUT_CARD_GROUP_TEXTS));
protected readonly open = tuiDropdownOpen();
protected readonly $ = inject(TUI_IS_WEBKIT)
? this.focus$
.pipe(
switchMap(() => timer(100)),
takeUntilDestroyed(),
)
.subscribe(() => this.focusExpire())
: EMPTY;

protected readonly m = tuiAppearanceMode(this.mode);
protected readonly appearance = tuiAppearance(
Expand Down Expand Up @@ -234,8 +244,14 @@ export class TuiInputCardGroup

public clear(): void {
this.expirePrefilled = false;

[this.inputCVC, this.inputExpire, this.inputCard].forEach((e) => {
e?.nativeElement.focus();
e?.nativeElement.select();
e?.nativeElement.ownerDocument.execCommand('delete');
});

this.onChange(null);
this.focusCard();
}

public onResize(): void {
Expand Down Expand Up @@ -308,6 +324,8 @@ export class TuiInputCardGroup

if (this.cardValidator(this.card) && !value()?.expire && this.inputExpire) {
this.focusExpire();
// Safari autofill focus jerk workaround
this.focus$.next();
}
}

Expand Down
4 changes: 1 addition & 3 deletions projects/cdk/classes/control.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import type {Provider, Type} from '@angular/core';
import {
ChangeDetectorRef,
computed,
DestroyRef,
Directive,
inject,
Input,
Expand Down Expand Up @@ -40,7 +39,6 @@ export abstract class TuiControl<T> implements ControlValueAccessor {
private readonly internal = signal(this.fallback);

protected readonly control = inject(NgControl, {self: true});
protected readonly destroyRef = inject(DestroyRef);
protected readonly cdr = inject(ChangeDetectorRef);
protected readonly transformer = inject(TuiValueTransformer, FLAGS);

Expand Down Expand Up @@ -74,7 +72,7 @@ export abstract class TuiControl<T> implements ControlValueAccessor {
filter(Boolean),
distinctUntilChanged(),
switchMap((c) => merge(c.valueChanges, c.statusChanges)),
takeUntilDestroyed(this.destroyRef),
takeUntilDestroyed(),
)
.subscribe(() => this.update());
}
Expand Down
14 changes: 12 additions & 2 deletions projects/core/components/textfield/textfield.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,18 @@ export class TuiTextfieldBase<T> implements OnChanges {
}

public setValue(value: T | null): void {
this.el.value = value == null ? '' : this.textfield.stringify(value);
this.el.dispatchEvent(new Event('input', {bubbles: true}));
this.el.focus();
this.el.select();

if (value == null) {
this.el.ownerDocument.execCommand('delete');
} else {
this.el.ownerDocument.execCommand(
'insertText',
false,
this.textfield.stringify(value),
);
}
}
}

Expand Down
26 changes: 10 additions & 16 deletions projects/core/styles/components/textfield.less
Original file line number Diff line number Diff line change
Expand Up @@ -140,39 +140,35 @@ tui-textfield {

&:has(label:not(:empty)) {
.t-template,
input,
select {
input:defined,
select:defined {
padding-top: calc(var(--t-height) / 3);

&:not(:-webkit-autofill)::placeholder,
&::placeholder,
&._empty {
caret-color: var(--tui-text-primary);
color: transparent !important;
-webkit-text-fill-color: transparent !important;
color: transparent;
}
}
}

// TODO: Fallback until Safari 15.4
&._with-label {
.t-template,
input,
select {
input:defined,
select:defined {
padding-top: calc(var(--t-height) / 3);

&:not(:-webkit-autofill)::placeholder,
&::placeholder,
&._empty {
caret-color: var(--tui-text-primary);
color: transparent !important;
-webkit-text-fill-color: transparent !important;
color: transparent;
}
}
}

.t-template,
input:defined,
select:defined {
.fullsize(absolute, inset);
.fullsize();

appearance: none;
box-sizing: border-box;
Expand Down Expand Up @@ -233,9 +229,7 @@ tui-textfield {
.appearance-focus({
&::placeholder,
&._empty {
caret-color: var(--tui-text-primary);
color: transparent !important;
-webkit-text-fill-color: var(--tui-text-tertiary) !important;
color: var(--tui-text-tertiary);
}

& ~ label {
Expand Down
4 changes: 0 additions & 4 deletions projects/core/styles/theme/appearance/textfield.less
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@
caret-color: var(--tui-text-primary) !important;
box-shadow: 0 0 0 100rem var(--tui-service-autofill-background) inset !important;
transition: background-color 600000s 0s;

&::placeholder {
-webkit-text-fill-color: var(--tui-text-secondary);
}
}
}

Expand Down

0 comments on commit 1f5dfa5

Please sign in to comment.