Skip to content

Commit

Permalink
feat(addon-commerce): InputCardGroup add inputs option
Browse files Browse the repository at this point in the history
  • Loading branch information
waterplea committed Dec 19, 2024
1 parent 08f924d commit f554b65
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,18 @@ export class TuiInputCardGroup
() => !!this.value()?.card && this.interactive(),
);

/**
* @deprecated use 'placeholder' instead
*/
@Input()
public exampleText = this.options.exampleText;

@Input()
public placeholder = this.options.exampleText;

@Input()
public inputs = this.options.inputs;

@Input()
public cardValidator: TuiBooleanHandler<string> = this.options.cardValidator;

Expand Down Expand Up @@ -219,7 +228,11 @@ export class TuiInputCardGroup
}

public focusExpire(): void {
this.inputExpire?.nativeElement.focus({preventScroll: true});
if (this.inputs.expire) {
this.inputExpire?.nativeElement.focus({preventScroll: true});
} else {
this.inputCVC?.nativeElement.focus({preventScroll: true});
}
}

public focusCVC(): void {
Expand Down Expand Up @@ -292,7 +305,7 @@ export class TuiInputCardGroup
}

protected get cvcPrefilled(): boolean {
return !!this.cvc.match(TUI_NON_DIGIT_REGEXP);
return !this.inputs.cvc || !!this.cvc.match(TUI_NON_DIGIT_REGEXP);
}

protected get cardFocusable(): boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,17 @@ import {tuiDefaultCardValidator} from '@taiga-ui/addon-commerce/constants';
import type {TuiBooleanHandler} from '@taiga-ui/cdk/types';
import {tuiCreateToken, tuiProvideOptions} from '@taiga-ui/cdk/utils/miscellaneous';

export interface TuiCardInputs {
cvc: boolean;
expire: boolean;
}

export interface TuiInputCardGroupOptions extends TuiInputCardOptions {
readonly cardValidator: TuiBooleanHandler<string>;
readonly exampleText: string;
readonly exampleTextCVC: string;
readonly cvcHidden: boolean;
readonly inputs: TuiCardInputs;
}

export const TUI_INPUT_CARD_GROUP_DEFAULT_OPTIONS: TuiInputCardGroupOptions = {
Expand All @@ -18,6 +24,7 @@ export const TUI_INPUT_CARD_GROUP_DEFAULT_OPTIONS: TuiInputCardGroupOptions = {
exampleText: '0000 0000 0000 0000',
exampleTextCVC: '000',
cvcHidden: true,
inputs: {cvc: true, expire: true},
};

export const TUI_INPUT_CARD_GROUP_OPTIONS = tuiCreateToken(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@
color: var(--tui-text-tertiary);
}

&_prefilled::placeholder {
color: var(--tui-text-primary);
}

&:-webkit-autofill {
-webkit-text-fill-color: var(--tui-text-primary) !important;
caret-color: var(--tui-text-primary) !important;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
[maskito]="maskCard"
[ngModel]="formattedCard"
[ngModelOptions]="{standalone: true}"
[placeholder]="cardPrefilled ? '' : exampleText"
[placeholder]="cardPrefilled ? '' : placeholder || exampleText"
[readOnly]="readOnly()"
[tabIndex]="cardFocusable ? 0 : -1"
(focus)="(0)"
Expand Down Expand Up @@ -66,18 +66,19 @@
automation-id="tui-input-card-group__expire"
inputmode="numeric"
maxlength="5"
placeholder="00/00"
translate="no"
class="t-input"
[attr.id]="id + '_expire'"
[attr.name]="autocomplete ? 'ccexpiryyear' : null"
[autocomplete]="autocomplete ? 'cc-exp' : 'off'"
[class.t-input_inert]="!expireFocusable"
[class.t-input_prefilled]="!inputs.expire"
[disabled]="disabled()"
[maskito]="maskExpire"
[ngModel]="expire"
[ngModelOptions]="{standalone: true}"
[readOnly]="readOnly()"
[placeholder]="inputs.expire ? '00/00' : '••/••'"
[readOnly]="readOnly() || !inputs.expire"
[tabIndex]="expireFocusable ? 0 : -1"
(focus)="(0)"
(ngModelChange)="onExpireChange($event)"
Expand Down
2 changes: 1 addition & 1 deletion projects/addon-doc/components/api/api-item.template.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
tuiTextfieldSize="m"
class="t-input"
[content]="content"
[tuiTextfieldCleaner]="type.includes('null')"
[tuiTextfieldCleaner]="type.includes('null') || type.includes('PolymorpheusContent')"
>
<select
placeholder="null"
Expand Down
132 changes: 79 additions & 53 deletions projects/demo/src/modules/components/input-card-group/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,19 @@
</ng-template>

<ng-template pageTab>
<tui-doc-demo [control]="control">
<tui-doc-demo [control]="formControl">
<ng-template>
<tui-input-card-group
[autocomplete]="autocomplete"
[codeLength]="codeLength"
[exampleText]="exampleText"
[formControl]="control"
[formControl]="formControl"
[icon]="icon"
[invalid]="pseudoInvalid"
[readOnly]="readOnly"
(binChange)="documentationPropertyBinChange.emitEvent($event)"
[id]="id"
[inputs]="inputs"
[invalid]="control.invalid"
[placeholder]="placeholder"
[readOnly]="control.readonly"
[tuiDisabled]="control.disabled"
/>
</ng-template>
</tui-doc-demo>
Expand All @@ -51,60 +53,84 @@
</tui-thumbnail-card>
</ng-template>

<tui-doc-documentation>
<ng-template
documentationPropertyName="disabled"
documentationPropertyType="boolean"
[(documentationPropertyValue)]="disabled"
<table tuiDocAPI>
<tr
name="[autocomplete]"
tuiDocAPIItem
type="boolean"
[(value)]="autocomplete"
>
Disabled state (use
<code>formControl.disable()</code>
)
</ng-template>
<ng-template
documentationPropertyMode="input"
documentationPropertyName="autocomplete"
documentationPropertyType="boolean"
[(documentationPropertyValue)]="autocomplete"
Browser autofill
</tr>
<tr
name="[cardValidator]"
tuiDocAPIItem
type="TuiBooleanHandler<string>"
>
Browser autocomplete of card
</ng-template>
<ng-template
documentationPropertyMode="input"
documentationPropertyName="icon"
documentationPropertyType="PolymorpheusContent"
[documentationPropertyValues]="getContentVariants(template)"
[(documentationPropertyValue)]="iconSelected"
Custom card validator for moving focus to the next field
</tr>
<tr
name="[codeLength]"
tuiDocAPIItem
type="3 | 4"
[items]="codeLengthVariants"
[(value)]="codeLength"
>
SVG card icon
</ng-template>
<ng-template
documentationPropertyMode="input"
documentationPropertyName="exampleText"
documentationPropertyType="string"
[(documentationPropertyValue)]="exampleText"
Code length
</tr>
<tr
name="[icon]"
tuiDocAPIItem
type="PolymorpheusContent"
[items]="getContentVariants(template)"
[(value)]="iconSelected"
>
An example of input
</ng-template>
<ng-template
documentationPropertyMode="input"
documentationPropertyName="codeLength"
documentationPropertyType="3 | 4"
[documentationPropertyValues]="codeLengthVariants"
[(documentationPropertyValue)]="codeLength"
Custom card icon
</tr>
<tr
name="[id]"
tuiDocAPIItem
type="string"
[id]="id"
>
Code length
</ng-template>
<ng-template
#documentationPropertyBinChange="documentationProperty"
documentationPropertyMode="output"
documentationPropertyName="binChange"
documentationPropertyType="string | null"
<code>id</code>
attribute for input tags (adds
<code>_card</code>
,
<code>_expire</code>
and
<code>_cvc</code>
accordingly). Auto-generated when not provided.
</tr>
<tr
name="[inputs]"
tuiDocAPIItem
type="TuiCardInputs"
[items]="inputsVariants"
[(value)]="inputs"
>
Toggle availability of inputs
</tr>
<tr
name="[placeholder]"
tuiDocAPIItem
type="string"
[(value)]="placeholder"
>
Placeholder
</tr>
<tr
name="(binChange)"
tuiDocAPIItem
type="string | null"
>
BIN value (card first 6 symbols)
</ng-template>
</tui-doc-documentation>
<inherited-documentation />
</tr>
<tbody
#control
tuiDocControl
></tbody>
</table>
</ng-template>

<tui-setup *pageTab />
Expand Down
55 changes: 24 additions & 31 deletions projects/demo/src/modules/components/input-card-group/index.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,33 @@
import {Component} from '@angular/core';
import {Component, inject} from '@angular/core';
import {FormControl, ReactiveFormsModule} from '@angular/forms';
import {TuiDocControl} from '@demo/components/control';
import {changeDetection} from '@demo/emulate/change-detection';
import {TuiDemo} from '@demo/utils';
import type {TuiCard} from '@taiga-ui/addon-commerce';
import {
TUI_INPUT_CARD_GROUP_OPTIONS,
type TuiCard,
type TuiCardInputs,
} from '@taiga-ui/addon-commerce';
import {TuiInputCardGroup, TuiThumbnailCard} from '@taiga-ui/addon-commerce';
import {tuiIsString, tuiProvide} from '@taiga-ui/cdk';
import {tuiIsString} from '@taiga-ui/cdk';
import type {PolymorpheusContent} from '@taiga-ui/polymorpheus';

import {ABSTRACT_PROPS_ACCESSOR} from '../abstract/abstract-props-accessor';
import {InheritedDocumentation} from '../abstract/inherited-documentation';
import {AbstractExampleTuiInteractive} from '../abstract/interactive';

@Component({
standalone: true,
imports: [
InheritedDocumentation,
ReactiveFormsModule,
TuiDemo,
TuiInputCardGroup,
TuiThumbnailCard,
TuiDocControl,
],
templateUrl: './index.html',
styleUrls: ['./index.less'],
changeDetection,
providers: [tuiProvide(ABSTRACT_PROPS_ACCESSOR, PageComponent)],
})
export default class PageComponent extends AbstractExampleTuiInteractive {
export default class PageComponent {
private readonly options = inject(TUI_INPUT_CARD_GROUP_OPTIONS);

protected readonly examples = [
'With validation',
'With saved cards',
Expand All @@ -42,44 +44,35 @@ export default class PageComponent extends AbstractExampleTuiInteractive {
};

protected iconVariants: readonly string[] = Object.keys(this.cards);

protected iconSelected: PolymorpheusContent = null;

protected autocomplete = false;

protected exampleText = '0000 0000 0000 0000';
protected id = '';
protected autocomplete = this.options.autocomplete;
protected placeholder = this.options.exampleText;

protected readonly codeLengthVariants = [3, 4] as const;

protected codeLength: 3 | 4 = this.codeLengthVariants[0];

protected pseudoInvalid: boolean | null = null;
protected readonly inputsVariants: readonly TuiCardInputs[] = [
{cvc: true, expire: true},
{cvc: false, expire: true},
{cvc: false, expire: false},
{cvc: true, expire: false},
];

protected readOnly = false;
protected inputs = this.options.inputs;

protected control = new FormControl<TuiCard | null>(null);
protected formControl = new FormControl<TuiCard | null>(null);

protected get icon(): PolymorpheusContent {
return tuiIsString(this.iconSelected)
? this.cards[this.iconSelected]
: this.iconSelected;
}

protected get disabled(): boolean {
return this.control.disabled;
}

protected set disabled(value: boolean) {
if (value) {
this.control.disable();
} else {
this.control.enable();
}
}

protected getContentVariants(
template: PolymorpheusContent,
): readonly PolymorpheusContent[] | null {
): readonly PolymorpheusContent[] {
return [...this.iconVariants, template];
}
}

0 comments on commit f554b65

Please sign in to comment.