diff --git a/projects/ion/src/lib/core/types/input.ts b/projects/ion/src/lib/core/types/input.ts index 0052fcb30..5ba0af863 100644 --- a/projects/ion/src/lib/core/types/input.ts +++ b/projects/ion/src/lib/core/types/input.ts @@ -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' | 'email'; @@ -13,8 +14,8 @@ export interface IonInputProps { valid?: boolean; invalid?: boolean; inputButton?: boolean; - inputIconButton?: boolean; clickButton?: EventEmitter; + inputButtonConfig?: IonButtonProps; value?: string; clearButton?: boolean; inputType?: InputType; diff --git a/projects/ion/src/lib/icon/mock/list-icons.module.ts b/projects/ion/src/lib/icon/mock/list-icons.module.ts index 67238337e..5136c0bf2 100644 --- a/projects/ion/src/lib/icon/mock/list-icons.module.ts +++ b/projects/ion/src/lib/icon/mock/list-icons.module.ts @@ -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 {} diff --git a/projects/ion/src/lib/input/input.component.html b/projects/ion/src/lib/input/input.component.html index 20355f173..a95754725 100644 --- a/projects/ion/src/lib/input/input.component.html +++ b/projects/ion/src/lib/input/input.component.html @@ -1,12 +1,13 @@ -
+
- - + [label]="inputButtonConfig.label" + [type]="inputButtonConfig.type" + [disabled]="inputButtonConfig.disabled" + [loading]="inputButtonConfig.loading" + [iconType]="inputButtonConfig.iconType" + [id]="inputButtonConfig.id" + [size]="inputButtonConfig.size" + (ionOnClick)="handleClick()" + >
diff --git a/projects/ion/src/lib/input/input.component.scss b/projects/ion/src/lib/input/input.component.scss index a04207077..f82506b36 100644 --- a/projects/ion/src/lib/input/input.component.scss +++ b/projects/ion/src/lib/input/input.component.scss @@ -10,42 +10,16 @@ border-color: $border; outline: $outline; } + .input-container { display: flex; line-height: 0; width: 100%; - - &__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; - } - } } .input { + position: relative; + z-index: 2; display: flex; align-items: center; gap: spacing(1); @@ -178,15 +152,13 @@ } } -.inputButton { - border-radius: 8px 0px 0px 8px; - padding: spacing(1) spacing(1.5); -} - .clearButton { + cursor: pointer; border: none; border-radius: 8px; padding: 0; + background-color: $neutral-1; + display: flex; &:hover { background-color: $primary-1; @@ -199,13 +171,46 @@ } } -.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: spacing(1) spacing(1.5); + 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: spacing(1) !important; + } + } +} diff --git a/projects/ion/src/lib/input/input.component.spec.ts b/projects/ion/src/lib/input/input.component.spec.ts index f0d094b0b..cee13579f 100644 --- a/projects/ion/src/lib/input/input.component.spec.ts +++ b/projects/ion/src/lib/input/input.component.spec.ts @@ -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'; @@ -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(); }); diff --git a/projects/ion/src/lib/input/input.component.ts b/projects/ion/src/lib/input/input.component.ts index 0b05916f9..8e0f369f2 100644 --- a/projects/ion/src/lib/input/input.component.ts +++ b/projects/ion/src/lib/input/input.component.ts @@ -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', @@ -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; diff --git a/projects/ion/src/lib/picker/date-picker/date-picker-input/date-picker-input.component.html b/projects/ion/src/lib/picker/date-picker/date-picker-input/date-picker-input.component.html index 9c8775098..4569f915d 100644 --- a/projects/ion/src/lib/picker/date-picker/date-picker-input/date-picker-input.component.html +++ b/projects/ion/src/lib/picker/date-picker/date-picker-input/date-picker-input.component.html @@ -4,7 +4,8 @@ [placeholder]="placeholder" [iconInput]="date ? '' : 'calendar'" iconDirection="right" - [inputIconButton]="!!date" + [inputButton]="!!date" + [inputButtonConfig]="clearButtonConfig" [readonly]="true" (clickButton)="clearDateValue()" > diff --git a/projects/ion/src/lib/picker/date-picker/date-picker-input/date-picker-input.component.spec.ts b/projects/ion/src/lib/picker/date-picker/date-picker-input/date-picker-input.component.spec.ts index 8a0b8d6d1..5599dad7e 100644 --- a/projects/ion/src/lib/picker/date-picker/date-picker-input/date-picker-input.component.spec.ts +++ b/projects/ion/src/lib/picker/date-picker/date-picker-input/date-picker-input.component.spec.ts @@ -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, @@ -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(''); }); diff --git a/projects/ion/src/lib/picker/date-picker/date-picker-input/date-picker-input.component.ts b/projects/ion/src/lib/picker/date-picker/date-picker-input/date-picker-input.component.ts index fff2b8cc1..8bfc9eebd 100644 --- a/projects/ion/src/lib/picker/date-picker/date-picker-input/date-picker-input.component.ts +++ b/projects/ion/src/lib/picker/date-picker/date-picker-input/date-picker-input.component.ts @@ -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(); diff --git a/stories/Input.stories.ts b/stories/Input.stories.ts index 587beaacb..e7b09ae92 100644 --- a/stories/Input.stories.ts +++ b/stories/Input.stories.ts @@ -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({});