diff --git a/projects/portal/src/index.html b/projects/portal/src/index.html index acb5cb0bb5..a948aaaac2 100644 --- a/projects/portal/src/index.html +++ b/projects/portal/src/index.html @@ -197,6 +197,7 @@

+ diff --git a/projects/ui/src/lib/components/po-search/enum/po-search-filter-mode.enum.ts b/projects/ui/src/lib/components/po-search/enum/po-search-filter-mode.enum.ts index 17824803da..c427944b5b 100644 --- a/projects/ui/src/lib/components/po-search/enum/po-search-filter-mode.enum.ts +++ b/projects/ui/src/lib/components/po-search/enum/po-search-filter-mode.enum.ts @@ -3,7 +3,7 @@ * * @description * - * Define o tipo de busca usado no po-multiselect. + * Define o tipo de busca usado no po-search. */ export enum PoSearchFilterMode { /** Verifica se o texto *inicia* com o valor pesquisado. */ diff --git a/projects/ui/src/lib/components/po-search/index.ts b/projects/ui/src/lib/components/po-search/index.ts index 0986a9393c..2f9ad82470 100644 --- a/projects/ui/src/lib/components/po-search/index.ts +++ b/projects/ui/src/lib/components/po-search/index.ts @@ -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'; diff --git a/projects/ui/src/lib/components/po-search/literals/po-search-literals-default.ts b/projects/ui/src/lib/components/po-search/literals/po-search-literals-default.ts new file mode 100644 index 0000000000..277929b3c3 --- /dev/null +++ b/projects/ui/src/lib/components/po-search/literals/po-search-literals-default.ts @@ -0,0 +1,20 @@ +import { PoSearchLiterals } from './po-search-literals'; + +export const poSearchLiteralsDefault = { + en: { + search: 'Search', + clean: 'Clean' + }, + es: { + search: 'Buscar', + clean: 'limpiar' + }, + pt: { + search: 'Pesquisar', + clean: 'Apagar' + }, + ru: { + search: 'Поиск', + clean: 'чистый' + } +}; diff --git a/projects/ui/src/lib/components/po-search/literals/po-search-literals.ts b/projects/ui/src/lib/components/po-search/literals/po-search-literals.ts index b5eb073f8b..016ecd3ab6 100644 --- a/projects/ui/src/lib/components/po-search/literals/po-search-literals.ts +++ b/projects/ui/src/lib/components/po-search/literals/po-search-literals.ts @@ -6,7 +6,18 @@ export interface PoSearchLiterals { * * @description * - * search: Texto exibido no *placeholder* do filtro do componente menu. + * search: Texto exibido no *placeholder* do filtro do componente `po-search`. */ search?: string; + + /** + * @usedBy PoSearchComponent + * + * @optional + * + * @description + * + * search: Texto usado no leitor de tela para acessibilidade. + */ + clean?: string; } diff --git a/projects/ui/src/lib/components/po-search/po-search-base.component.spec.ts b/projects/ui/src/lib/components/po-search/po-search-base.component.spec.ts index 7e6ea14cf4..1e09bc84ea 100644 --- a/projects/ui/src/lib/components/po-search/po-search-base.component.spec.ts +++ b/projects/ui/src/lib/components/po-search/po-search-base.component.spec.ts @@ -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); + }); + }); }); diff --git a/projects/ui/src/lib/components/po-search/po-search-base.component.ts b/projects/ui/src/lib/components/po-search/po-search-base.component.ts index 2ec1f4d76d..d0b9c1d68e 100644 --- a/projects/ui/src/lib/components/po-search/po-search-base.component.ts +++ b/projects/ui/src/lib/components/po-search/po-search-base.component.ts @@ -1,21 +1,187 @@ -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 { - @Input({ alias: 'p-disabled', transform: convertToBoolean }) disabled?: boolean; + private _literals?: PoSearchLiterals; + private _ariaLabel?: string; + private language: string; - @Input('p-loading') loading: boolean; + /** + * @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 + * + * Lista de itens que serão utilizados para pesquisa + */ @Input('p-items') items: Array = []; + /** + * @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 = []; - @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; + /** + * @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. + * + * ``` + * + * + * ``` + * + * > 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 = 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>(); + /** + * @optional + * + * @description + * + * Pode ser informada uma função que será disparada quando houver alterações nos filtros. + */ @Output('p-filter') filter: EventEmitter = new EventEmitter(); + + constructor(languageService: PoLanguageService) { + this.language = languageService.getShortLanguage(); + } } diff --git a/projects/ui/src/lib/components/po-search/po-search-filter-mode.enum.ts b/projects/ui/src/lib/components/po-search/po-search-filter-mode.enum.ts deleted file mode 100644 index ac0870791e..0000000000 --- a/projects/ui/src/lib/components/po-search/po-search-filter-mode.enum.ts +++ /dev/null @@ -1,15 +0,0 @@ -/** - * @usedBy PoSearchComponent - * - * @description - * - * Define o tipo de busca usado no po-seach. - */ -export enum PoFilterMode { - /** Verifica se o texto *inicia* com o valor pesquisado. */ - startsWith, - /** Verifica se o texto *contém* o valor pesquisado. */ - contains, - /** Verifica se o texto *finaliza* com o valor pesquisado. */ - endsWith -} diff --git a/projects/ui/src/lib/components/po-search/po-search.component.html b/projects/ui/src/lib/components/po-search/po-search.component.html index f6eb7b38e3..5bb831edbd 100644 --- a/projects/ui/src/lib/components/po-search/po-search.component.html +++ b/projects/ui/src/lib/components/po-search/po-search.component.html @@ -1,12 +1,14 @@ -