Skip to content

Commit

Permalink
fix: ion input button
Browse files Browse the repository at this point in the history
  • Loading branch information
allan-chagas-brisa committed Oct 13, 2023
1 parent 130ccfe commit 512a986
Show file tree
Hide file tree
Showing 10 changed files with 128 additions and 90 deletions.
3 changes: 2 additions & 1 deletion projects/ion/src/lib/core/types/input.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { EventEmitter } from '@angular/core';
import { SafeAny } from '../../utils/safe-any';
import { IconDirection } from './icon';
import { IonButtonProps } from './button';

export type InputType = 'text' | 'password' | 'number';

Expand All @@ -13,8 +14,8 @@ export interface IonInputProps {
valid?: boolean;
invalid?: boolean;
inputButton?: boolean;
inputIconButton?: boolean;
clickButton?: EventEmitter<SafeAny>;
inputButtonConfig?: IonButtonProps;
value?: string;
clearButton?: boolean;
inputType?: InputType;
Expand Down
24 changes: 22 additions & 2 deletions projects/ion/src/lib/icon/mock/list-icons.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,30 @@ import { IonIconComponent } from '../icon.component';
import { IonInputComponent } from '../../input/input.component';
import { FormsModule } from '@angular/forms';
import { IonNotificationComponent } from '../../notification/component/notification.component';
import { IonButtonComponent } from '../../button/button.component';
import { IonBadgeComponent } from '../../badge/badge.component';
import { IonDropdownComponent } from '../../dropdown/dropdown.component';
import { IonNoDataComponent } from '../../no-data/no-data.component';

@NgModule({
declarations: [IonInputComponent, IonIconComponent, IonNotificationComponent],
declarations: [
IonInputComponent,
IonIconComponent,
IonNotificationComponent,
IonButtonComponent,
IonBadgeComponent,
IonDropdownComponent,
IonNoDataComponent,
],
imports: [CommonModule, FormsModule],
exports: [IonInputComponent, IonIconComponent, IonNotificationComponent],
exports: [
IonInputComponent,
IonIconComponent,
IonNotificationComponent,
IonButtonComponent,
IonBadgeComponent,
IonDropdownComponent,
IonNoDataComponent,
],
})
export class ListIconsMockModule {}
32 changes: 15 additions & 17 deletions projects/ion/src/lib/input/input.component.html
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
<div class="input-container">
<div
class="input-container"
[class.input-button]="inputButton && inputButtonConfig"
>
<div
data-testid="input-div"
class="input"
[class.disabled]="disabled"
[class.invalid]="invalid"
[class.valid]="valid"
[class.inputButton]="inputButton"
[class.IconButton]="inputIconButton"
>
<ion-icon
data-testid="icon-left"
Expand Down Expand Up @@ -59,21 +60,18 @@
<ion-icon type="close-rounded" size="18"></ion-icon>
</button>
</div>

<button
<ion-button
*ngIf="inputButton && inputButtonConfig"
data-testid="input-button"
*ngIf="inputButton"
(click)="handleClick()"
>
{{ button }}
</button>
<button
data-testid="inputIcon-button"
*ngIf="inputIconButton"
(click)="handleClick()"
>
<ion-icon type="close-solid"></ion-icon>
</button>
[label]="inputButtonConfig.label"
[type]="inputButtonConfig.type"
[disabled]="inputButtonConfig.disabled"
[loading]="inputButtonConfig.loading"
[iconType]="inputButtonConfig.iconType"
[id]="inputButtonConfig.id"
[size]="inputButtonConfig.size"
(ionOnClick)="handleClick()"
></ion-button>
</div>

<div class="errorMsg" *ngIf="invalid && errorMsg">
Expand Down
77 changes: 39 additions & 38 deletions projects/ion/src/lib/input/input.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
}

.input {
position: relative;
z-index: 2;
display: flex;
align-items: center;
gap: spacing(1);
Expand Down Expand Up @@ -149,40 +151,6 @@
}
}

.inputButton {
border-radius: 8px 0px 0px 8px;
padding: spacing(1) spacing(1.5);
}

button {
display: flex;
align-items: center;
border: 1px solid $neutral-5;
border-radius: 0px 8px 8px 0px;
background-color: $neutral-1;
padding: spacing(0.75) spacing(1.5);
margin-left: -1px;
color: $primary-6;
font-weight: 600;
cursor: pointer;

&:hover {
border-color: $primary-4;
}

&:focus-within {
@include add-colors($primary-5, 2px solid, $primary-2);
}

&:active {
@include add-colors($primary-5, 2px solid, $primary-2);
}

::ng-deep svg {
fill: $primary-6;
}
}

.clearButton {
border: none;
border-radius: 8px;
Expand All @@ -199,13 +167,46 @@ button {
}
}

.IconButton {
border-radius: 8px 0px 0px 8px;
}

.errorMsg {
p {
margin: 4px 0px 0px;
color: $negative-6;
}
}

.input-button {
&:has(.ion-btn-primary) .input {
border-right: none;

&:focus-within {
border-right: 1px solid $primary-5;
}
}

.input {
border-radius: 8px 0 0 8px;
}

::ng-deep button {
height: 100%;
padding: 8px 12px;
border-radius: 0 8px 8px 0;
border-left: none;
transition: none;

&.ion-btn-secondary {
border-color: $neutral-5;

&:hover {
border: 1px solid $primary-4;
}

&:active {
border: 1px solid $primary-5;
}
}
&.ion-remove-space {
padding: 8px !important;
}
}
}
47 changes: 26 additions & 21 deletions projects/ion/src/lib/input/input.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { SafeAny } from './../utils/safe-any';
import { CommonModule } from '@angular/common';
import { render, screen, fireEvent } from '@testing-library/angular';
import { render, screen, fireEvent, within } from '@testing-library/angular';
import userEvent from '@testing-library/user-event';
import { IonInputComponent } from './input.component';
import { FormsModule } from '@angular/forms';
Expand Down Expand Up @@ -62,41 +62,46 @@ describe('IonInputComponent', () => {
expect(document.getElementById('ion-icon-' + icon)).toBeTruthy();
});

it('should render button when informed', async () => {
await sut({ inputButton: true });
const button = screen.getByTestId('input-button');
fireEvent.click(button);
expect(button).toBeInTheDocument();
it('should not render the input button as default', async () => {
await sut();
const button = screen.queryByTestId('input-button');
expect(button).not.toBeInTheDocument();
});

it('should render input icon button when informed', async () => {
await sut({ inputIconButton: true });
const button = screen.getByTestId('inputIcon-button');
fireEvent.click(button);
expect(button).toBeInTheDocument();
it('should not render the input button if the button config is not informed', async () => {
await sut({ inputButton: true });
const button = screen.queryByTestId('input-button');
expect(button).not.toBeInTheDocument();
});

it('should emit an event when clicked input button', async () => {
const clickEvent = jest.fn();
it('should render button when informed', async () => {
await sut({
inputButton: true,
clickButton: {
emit: clickEvent,
} as SafeAny,
inputButtonConfig: {
iconType: 'pencil',
type: 'primary',
},
});
fireEvent.click(screen.getByTestId('input-button'));
expect(clickEvent).toHaveBeenCalled();
const button = screen.getByTestId('input-button');
fireEvent.click(button);
expect(button).toBeInTheDocument();
});

it('should emit an event when clicked input icon button', async () => {
it('should emit an event when clicked input button', async () => {
const clickEvent = jest.fn();
await sut({
inputIconButton: true,
inputButton: true,
inputButtonConfig: {
iconType: 'pencil',
type: 'primary',
},
clickButton: {
emit: clickEvent,
} as SafeAny,
});
fireEvent.click(screen.getByTestId('inputIcon-button'));
fireEvent.click(
within(screen.getByTestId('input-button')).getByRole('button')
);
expect(clickEvent).toHaveBeenCalled();
});

Expand Down
5 changes: 3 additions & 2 deletions projects/ion/src/lib/input/input.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { IconDirection, IconType } from '../core/types/icon';
import { InputType } from '../core/types/input';
import { IonButtonProps } from '../core/types';

@Component({
selector: 'ion-input',
Expand All @@ -16,8 +17,8 @@ export class IonInputComponent {
@Input() valid: boolean;
@Input() invalid: boolean;
@Input() errorMsg?: string;
@Input() inputButton? = false;
@Input() inputIconButton? = false;
@Input() inputButton = false;
@Input() inputButtonConfig?: IonButtonProps;
@Input() value = '';
@Input() inputType: InputType = 'text';
@Input() clearButton = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
[placeholder]="placeholder"
[iconInput]="date ? '' : 'calendar'"
iconDirection="right"
[inputIconButton]="!!date"
[inputButton]="!!date"
[inputButtonConfig]="clearButtonConfig"
[readonly]="true"
(clickButton)="clearDateValue()"
></ion-input>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { IonInputModule } from './../../../input/input.module';
import { IonButtonModule } from './../../../button/button.module';
import { render, screen, fireEvent } from '@testing-library/angular';
import { render, screen, fireEvent, within } from '@testing-library/angular';
import {
IonDatePickerInputComponent,
IonDatePickerInputComponentProps,
Expand Down Expand Up @@ -44,10 +44,10 @@ describe('IonDatePickerInputComponent', () => {
let input = await screen.getByTestId('input-element');
expect(input).toHaveValue(date);

const clearButton = await screen.findByTestId('inputIcon-button');
const clearButton = await screen.findByTestId('input-button');
expect(clearButton).toBeTruthy();

fireEvent.click(clearButton);
fireEvent.click(within(clearButton).getByRole('button'));
input = await screen.getByTestId('input-element');
expect(input).toHaveValue('');
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ export class IonDatePickerInputComponent {
@Input() placeholder? = 'Selecione a data';
@Output() clearDate = new EventEmitter();

public clearButtonConfig = {
iconType: 'close-solid',
type: 'secondary',
size: 'lg',
};

clearDateValue(): void {
this.date = '';
this.clearDate.emit();
Expand Down
15 changes: 10 additions & 5 deletions stories/Input.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,20 @@ leftWithIcon.args = {
export const inputButton = Template.bind({});
inputButton.args = {
inputButton: true,
iconDirection: 'left',
iconInput: 'filter',
inputButtonConfig: {
label: 'Button',
type: 'secondary',
},
};

export const inputIconButton = Template.bind({});
inputIconButton.args = {
inputIconButton: true,
iconDirection: 'left',
iconInput: 'filter',
inputButton: true,
inputButtonConfig: {
iconType: 'pencil',
size: 'md',
type: 'primary',
},
};

export const InputText = Template.bind({});
Expand Down

0 comments on commit 512a986

Please sign in to comment.