-
Notifications
You must be signed in to change notification settings - Fork 212
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(search): implementa animaliaDS e externaliza para uso no portal
Implementa AnimaliaDS e externaliza para uso no portal Fixes DTHFUI-7501
- Loading branch information
Showing
19 changed files
with
812 additions
and
69 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
export * from './po-search.component'; | ||
export * from './po-search.module'; | ||
export * from './po-search-filter-mode.enum'; | ||
export * from './enum/po-search-filter-mode.enum'; | ||
export * from './literals/po-search-literals'; |
20 changes: 20 additions & 0 deletions
20
projects/ui/src/lib/components/po-search/literals/po-search-literals-default.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { PoSearchLiterals } from './po-search-literals'; | ||
|
||
export const poSearchLiteralsDefault = { | ||
en: <PoSearchLiterals>{ | ||
search: 'Search', | ||
clean: 'Clean' | ||
}, | ||
es: <PoSearchLiterals>{ | ||
search: 'Buscar', | ||
clean: 'limpiar' | ||
}, | ||
pt: <PoSearchLiterals>{ | ||
search: 'Pesquisar', | ||
clean: 'Apagar' | ||
}, | ||
ru: <PoSearchLiterals>{ | ||
search: 'Поиск', | ||
clean: 'чистый' | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
42 changes: 41 additions & 1 deletion
42
projects/ui/src/lib/components/po-search/po-search-base.component.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,53 @@ | ||
import { PoSearchBaseComponent } from './po-search-base.component'; | ||
import { PoLanguageService } from '../../services/po-language/po-language.service'; | ||
import { poSearchLiteralsDefault } from './literals/po-search-literals-default'; | ||
import { poLocaleDefault } from '../../services/po-language/po-language.constant'; | ||
import * as Utils from '../../utils/util'; | ||
|
||
describe('PoSearchBaseComponent', () => { | ||
let component: PoSearchBaseComponent; | ||
|
||
beforeEach(() => { | ||
component = new PoSearchBaseComponent(); | ||
component = new PoSearchBaseComponent(new PoLanguageService()); | ||
}); | ||
|
||
it('should create an instance', () => { | ||
expect(component).toBeTruthy(); | ||
}); | ||
|
||
describe('Properties:', () => { | ||
it('label: should set label when is setted', () => { | ||
component.ariaLabel = 'Search'; | ||
|
||
expect(component.ariaLabel).toBe('Search'); | ||
}); | ||
|
||
it('label: should concat label with literals', () => { | ||
component.ariaLabel = 'label button'; | ||
expect(component.ariaLabel).toBe('label button Search'); | ||
}); | ||
|
||
it('should be set `literals` with browser language if `literals` is `undefined`', () => { | ||
component['language'] = Utils.browserLanguage(); | ||
component.literals = undefined; | ||
|
||
expect(component.literals).toEqual(poSearchLiteralsDefault[Utils.browserLanguage()]); | ||
}); | ||
|
||
it('should be in portuguese if browser is set with `pt`.', () => { | ||
component['language'] = 'pt'; | ||
|
||
component.literals = {}; | ||
|
||
expect(component.literals).toEqual(poSearchLiteralsDefault[poLocaleDefault]); | ||
}); | ||
|
||
it('should be in english if browser is set with `en`.', () => { | ||
component['language'] = 'en'; | ||
|
||
component.literals = {}; | ||
|
||
expect(component.literals).toEqual(poSearchLiteralsDefault.en); | ||
}); | ||
}); | ||
}); |
183 changes: 180 additions & 3 deletions
183
projects/ui/src/lib/components/po-search/po-search-base.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,198 @@ | ||
import { PoFilterMode } from './po-search-filter-mode.enum'; | ||
import { PoLanguageService } from '../../services/po-language/po-language.service'; | ||
import { poLocaleDefault } from '../../services/po-language/po-language.constant'; | ||
|
||
import { Directive, EventEmitter, Input, Output } from '@angular/core'; | ||
import { Directive, EventEmitter, Input, Output, TemplateRef } from '@angular/core'; | ||
import { convertToBoolean } from '../../utils/util'; | ||
import { PoSearchLiterals } from './literals/po-search-literals'; | ||
import { poSearchLiteralsDefault } from './literals/po-search-literals-default'; | ||
import { PoSearchFilterMode } from './enum/po-search-filter-mode.enum'; | ||
|
||
/** | ||
* @description | ||
* | ||
* O componente search, também conhecido como barra de pesquisa, é utilizado para ajudar os usuários a localizar um determinado conteúdo | ||
* | ||
* Normalmente localizado no canto superior direito, junto com o ícone de lupa, uma vez que este ícone é amplamente reconhecido. | ||
* | ||
* Portanto, é de extrema importância que, ao utilizar este componente, as pessoas responsáveis por seu desenvolvimento considerem os seguintes critérios. | ||
* | ||
* #### Boas práticas | ||
* | ||
* Foram estruturados os padrões de usabilidade para auxiliar na utilização do componente e garantir uma boa experiência aos usuários. Por isso, é muito importante que ao utilizar este componente, as pessoas que o projetarem devem levar em consideração os seguintes critérios: | ||
* - Utilize labels para apresentar resultados que estão sendo exibidos e apresente os resultados mais relevantes primeiro. | ||
* - Exiba uma mensagem clara quando não forem encontrados resultados para busca e sempre que possível ofereça outras sugestões de busca. | ||
* - Mantenha o texto original no campo de input, que facilita a ação do usuário caso queira fazer uma nova busca com alguma modificação na pesquisa. | ||
* - Caso seja possível detectar um erro de digitação, mostre os resultados para a palavra "corrigida", isso evita a frustração de não obter resultados e não força o usuário a realizar uma nova busca. | ||
* - Quando apropriado, destaque os termos da busca nos resultados. | ||
* - A entrada do campo de pesquisa deve caber em uma linha. Não use entradas de pesquisa de várias linhas. | ||
* - Recomenda-se ter apenas uma pesquisa por página. Se você precisar de várias pesquisas, rotule-as claramente para indicar sua finalidade. | ||
* - Se possível, forneça sugestões de pesquisa, seja em um helptext ou sugestão de pesquisa que é um autocomplete. Isso ajuda os usuários a encontrar o que estão procurando, especialmente se os itens pesquisáveis forem complexos. | ||
* | ||
* #### Acessibilidade tratada no componente | ||
* | ||
* Algumas diretrizes de acessibilidade já são tratadas no componente, internamente, e não podem ser alteradas pelo proprietário do conteúdo. São elas: | ||
* | ||
* - Permitir a interação via teclado (2.1.1: Keyboard (A)); | ||
* - Alteração entre os estados precisa ser indicada por mais de um elemento além da cor (1.4.1: Use of Color); | ||
*/ | ||
@Directive() | ||
export class PoSearchBaseComponent { | ||
private _literals?: PoSearchLiterals; | ||
private _ariaLabel?: string; | ||
private language: string; | ||
|
||
/** | ||
* @optional | ||
* | ||
* @description | ||
* | ||
* Desabilita o po-search e não permite que o usuário interaja com o mesmo. | ||
* | ||
* @default `false` | ||
*/ | ||
@Input({ alias: 'p-disabled', transform: convertToBoolean }) disabled?: boolean; | ||
|
||
/** | ||
* @optional | ||
* | ||
* @description | ||
* | ||
* Exibe um ícone de carregamento à esquerda do label do botão. | ||
* | ||
* @default `false` | ||
*/ | ||
@Input('p-loading') loading: boolean; | ||
|
||
/** | ||
* @optional | ||
* | ||
* @description | ||
* | ||
* Lista de itens que serão utilizados para pesquisa | ||
*/ | ||
@Input('p-items') items: Array<any> = []; | ||
|
||
/** | ||
* @optional | ||
* | ||
* @description | ||
* | ||
* Define um aria-label para o po-search. | ||
* | ||
* > Devido o componente não possuir uma label assim como outros campos de texto, o `aria-label` é utilizado para acessibilidade. | ||
*/ | ||
@Input('p-aria-label') set ariaLabel(value: string) { | ||
this._ariaLabel = value; | ||
|
||
if (value !== this.literals.search) { | ||
this._ariaLabel = `${this._ariaLabel} ${this.literals.search}`; | ||
} | ||
} | ||
|
||
get ariaLabel(): string { | ||
return this._ariaLabel; | ||
} | ||
|
||
/** | ||
* @optional | ||
* | ||
* @description | ||
* | ||
* Deve ser informado o nome da propriedade do objeto que será utilizado para a conversão dos itens apresentados na lista do componente (p-items), esta propriedade será responsável pelo texto de apresentação de cada item da lista. | ||
*/ | ||
@Input('p-filter-keys') filterKeys: Array<any> = []; | ||
|
||
@Input('p-filter-type') filterType: PoFilterMode = PoFilterMode.startsWith; | ||
/** | ||
* @optional | ||
* | ||
* @description | ||
* | ||
* Deve ser informado o nome da propriedade do objeto que será utilizado para a conversão dos itens apresentados na lista do componente (p-items), esta propriedade será responsável pelo texto de apresentação de cada item da lista. | ||
*/ | ||
@Input('p-icon') icon: string | TemplateRef<void>; | ||
|
||
/** | ||
* @optional | ||
* | ||
* @description | ||
* | ||
* Objeto com as literais usadas no `po-search`. | ||
* | ||
* Para utilizar basta passar a literal que deseja customizar: | ||
* | ||
* ``` | ||
* const customLiterals: PoSearchLiterals = { | ||
* search: 'Pesquisar', | ||
* clean: 'Limpar', | ||
* }; | ||
* ``` | ||
* | ||
* E para carregar a literal customizada, basta apenas passar o objeto para o componente. | ||
* | ||
* ``` | ||
* <po-search | ||
* [p-literals]="customLiterals"> | ||
* </po-search> | ||
* ``` | ||
* | ||
* > O objeto padrão de literais será traduzido de acordo com o idioma do | ||
* [`PoI18nService`](/documentation/po-i18n) ou do browser. | ||
*/ | ||
@Input('p-literals') set literals(value: PoSearchLiterals) { | ||
if (value instanceof Object && !(value instanceof Array)) { | ||
this._literals = { | ||
...poSearchLiteralsDefault[poLocaleDefault], | ||
...poSearchLiteralsDefault[this.language], | ||
...value | ||
}; | ||
} else { | ||
this._literals = poSearchLiteralsDefault[this.language]; | ||
} | ||
} | ||
|
||
get literals() { | ||
return this._literals || poSearchLiteralsDefault[this.language]; | ||
} | ||
|
||
/** | ||
* @optional | ||
* | ||
* @description | ||
* | ||
* Define o modo de pesquisa utilizado no campo de busca, quando habilitado. Valores definidos no enum: PoSearchFilterMode | ||
* | ||
* @default `startsWith` | ||
*/ | ||
@Input('p-filter-type') filterType: PoSearchFilterMode = PoSearchFilterMode.startsWith; | ||
|
||
/** | ||
* @optional | ||
* | ||
* @description | ||
* | ||
* Evento disparado ao alterar valor do model. | ||
*/ | ||
@Output('p-change-model') changeModel: EventEmitter<any> = new EventEmitter(); | ||
|
||
/** | ||
* @optional | ||
* | ||
* @description | ||
* | ||
* Pode ser informada uma função que será disparada quando houver alterações no input. | ||
*/ | ||
@Output('p-filtered-items-change') filteredItemsChange = new EventEmitter<Array<any>>(); | ||
|
||
/** | ||
* @optional | ||
* | ||
* @description | ||
* | ||
* Pode ser informada uma função que será disparada quando houver alterações nos filtros. | ||
*/ | ||
@Output('p-filter') filter: EventEmitter<any> = new EventEmitter<any>(); | ||
|
||
constructor(languageService: PoLanguageService) { | ||
this.language = languageService.getShortLanguage(); | ||
} | ||
} |
15 changes: 0 additions & 15 deletions
15
projects/ui/src/lib/components/po-search/po-search-filter-mode.enum.ts
This file was deleted.
Oops, something went wrong.
20 changes: 15 additions & 5 deletions
20
projects/ui/src/lib/components/po-search/po-search.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,30 @@ | ||
<div class="po-search"> | ||
<div class="po-search" [class.po-search-disabled]="disabled"> | ||
<div class="po-search-icon"> | ||
<po-icon *ngIf="!loading" p-icon="po-icon-search"></po-icon> | ||
<po-loading-icon *ngIf="loading" p-size="sm"></po-loading-icon> | ||
<po-icon *ngIf="!loading" [p-icon]="icon ? icon : 'po-icon-search'"></po-icon> | ||
<po-loading-icon *ngIf="loading && !disabled" p-neutral-color></po-loading-icon> | ||
</div> | ||
|
||
<input | ||
#poSearchInput | ||
type="text" | ||
class="po-search-input" | ||
[ariaLabel]="ariaLabel" | ||
[class.po-search-icon-right]="!!poSearchInput.value && !disabled" | ||
[disabled]="disabled" | ||
[placeholder]="literals.search" | ||
(blur)="onBlur()" | ||
(focus)="onFocus()" | ||
(input)="onSearchChange($event.target.value)" | ||
/> | ||
|
||
<div *ngIf="!!poSearchInput.value && !disabled" class="po-search-clean" [tabindex]="!disabled ? 0 : -1"> | ||
<po-clean [p-element-ref]="poSearchInput" (p-change-event)="clearSearch()"></po-clean> | ||
<div *ngIf="!!poSearchInput.value && !disabled" class="po-search-container-clean"> | ||
<button | ||
class="po-search-clean" | ||
[ariaLabel]="literals.clean" | ||
(click)="clearSearch()" | ||
(keydown.enter)="clearSearch()" | ||
> | ||
<po-icon p-icon="po-icon-clear-content"></po-icon> | ||
</button> | ||
</div> | ||
</div> |
Oops, something went wrong.