Visão geral da diretiva de destaque de texto Angular

    O IgxTextHighlightDirective e IgxTextHighlightService no Ignite UI for Angular são usados para destacar partes de um texto, fornecendo opções para pesquisas com diferenciação de maiúsculas e minúsculas e para destacar apenas correspondências exatas. Eles permitem que o desenvolvedor mantenha um destaque ativo, que pode ser qualquer uma das partes já destacadas.

    Angular Text Highlight Directive Example

    Getting Started with Ignite UI for Angular Text Highlight Directive

    Para começar a usar a diretiva Ignite UI for Angular Text Highlight, primeiro você precisa instalar Ignite UI for Angular. Em um aplicativo Angular existente, digite o seguinte comando:

    ng add igniteui-angular
    

    Para obter uma introdução completa ao Ignite UI for Angular, leia o tópico de introdução.

    O próximo passo é importar o IgxTextHighlightModule no seu arquivo app.module.ts.

    // app.module.ts
    ...
    import { IgxTextHighlightModule } from 'igniteui-angular';
    // import { IgxTextHighlightModule } from '@infragistics/igniteui-angular'; for licensed package
    
    @NgModule({
        ...
        imports: [IgxTextHighlightModule],
        ...
    })
    export class AppModule {}
    

    Como alternativa, a partir da 16.0.0 você pode importar o IgxTextHighlightDirective como uma dependência autônoma.

    // home.component.ts
    
    import { IgxTextHighlightDirective, IgxTextHighlightService } from 'igniteui-angular';
    // import { IgxTextHighlightDirective, IgxTextHighlightService } from '@infragistics/igniteui-angular'; for licensed package
    
    @Component({
      selector: 'app-home',
      template: `
        <div
          igxTextHighlight
          [value]="html"
          [groupName]="'group1'"
          [containerClass]="'search-text'"
          class="search-text"
        >
          {{ html }}
        </div>
      `,
      styleUrls: ['home.component.scss'],
      standalone: true,
      imports: [IgxTextHighlightDirective],
    })
    export class HomeComponent {
      constructor(public textHighlightService: IgxTextHighlightService) {}
    }
    

    Agora que você importou o módulo ou a diretiva Ignite UI for Angular Text Highlight, você pode começar a usar o igxTextHighlight.

    Using the Angular Text Highlight Directive

    Vamos criar uma caixa de pesquisa que podemos usar para destacar diferentes partes do texto. Usaremos o componente InputGroup do Ignite UI for Angular no qual adicionaremos uma entrada de texto com botões para limpar correspondências, encontrar próximo, encontrar anterior e um botão para especificar se a pesquisa fará distinção entre maiúsculas e minúsculas ou não. Também tem um rótulo para quantas correspondências encontramos.

    <div class="search-container">
      <igx-input-group type="search" class="input-group">
        <igx-prefix>
          <igx-icon *ngIf="searchText.length == 0">search</igx-icon>
          <igx-icon *ngIf="searchText.length > 0" (click)="clearSearch()"
            >clear</igx-icon
          >
        </igx-prefix>
    
        <input
          #search1
          id="search1"
          igxInput
          placeholder="Search"
          autocomplete="off"
          [(ngModel)]="searchText"
          (ngModelChange)="onTextboxChange()"
          (keydown)="searchKeyDown($event)"/>
        <igx-suffix>
          <div class="caseSensitiveButton">
            <button
              igxIconButton="flat"
              igxRipple
              igxRippleCentered="true"
              (click)="updateSearch()"
              [style.background]="caseSensitive ? 'rgb(73, 180, 254)' : 'transparent'">
              <igx-icon class="caseSensitiveIcon" fontSet="material">text_fields</igx-icon>
            </button>
          </div>
          <ng-container *ngIf="searchText.length > 0">
            <span>
              <ng-container *ngIf="matchCount > 0">
                {{ index + 1 }} of {{ matchCount }} results
              </ng-container>
              <ng-container *ngIf="matchCount == 0"> No results </ng-container>
            </span>
          </ng-container>
    
          <div class="searchButtons">
            <button
              igxIconButton="flat"
              igxRipple
              igxRippleCentered="true"
              (click)="findPrev()"
              [disabled]="!canMoveHighlight">
              <igx-icon fontSet="material">navigate_before</igx-icon>
            </button>
            <button
              igIconButton="flat"
              igxRipple
              igxRippleCentered="true"
              (click)="findNext()"
              [disabled]="!canMoveHighlight">
              <igx-icon fontSet="material">navigate_next</igx-icon>
            </button>
          </div>
        </igx-suffix>
      </igx-input-group>
    </div>
    

    Então, adicionaremos um div com texto e a diretiva IgxTextHighlight. Note que, como precisamos vincular o valor de entrada ao texto no div, também usaremos interpolação para o texto do div.

    <div
      igxTextHighlight
      [value]="html"
      [groupName]="'group1'"
      [containerClass]="'search-text'"
      class="search-text">
       {{html}}
    </div>
    

    No arquivo .ts do nosso componente, primeiro precisamos adicionar os seguintes campos, que são usados para vinculações no modelo do nosso componente:

    @Component({
        ...
    })
    export class HomeComponent {
        public html = '...';
    
        @ViewChild(IgxTextHighlightDirective, {read: IgxTextHighlightDirective})
        public highlight: IgxTextHighlightDirective;
    
        public searchText: string = '';
        public matchCount: number = 0;
        public caseSensitive: boolean = false;
        public index: number = 0;
    
        public get canMoveHighlight() {
            return this.matchCount > 1;
        }
    }
    

    Então precisamos adicionar os seguintes métodos que permitirão ao usuário aplicar os destaques ao texto digitado na caixa de pesquisa e mover o destaque ativo.

    @Component({
        ...
    })
    export class HomeComponent {
        constructor(public textHighlightService: IgxTextHighlightService) {}
    
        public searchKeyDown(ev) {
            if (this.searchText) {
                if (ev.key === 'Enter' || ev.key === 'ArrowDown' || ev.key === 'ArrowRight') {
                    ev.preventDefault();
                    this.findNext();
                } else if (ev.key === 'ArrowUp' || ev.key === 'ArrowLeft') {
                    ev.preventDefault();
                    this.findPrev();
                }
            }
        }
    
        public onTextboxChange() {
            this.index = 0;
            this.find(0);
        }
    
        public updateSearch() {
            this.caseSensitive = !this.caseSensitive;
            this.find(0);
        }
    
        public clearSearch() {
            this.searchText = '';
            this.find(0);
        }
    
        private findNext() {
            this.find(1);
        }
    
        private findPrev() {
            this.find(-1);
        }
    
        private find(increment: number) {
            if (this.searchText) {
                this.matchCount = this.highlight.highlight(this.searchText, this.caseSensitive);
                this.index += increment;
    
                this.index = this.index < 0 ? this.matchCount - 1 : this.index;
                this.index = this.index > this.matchCount - 1 ? 0 : this.index;
    
                if (this.matchCount) {
                    this.textHighlightService.setActiveHighlight('group1', {
                        columnIndex: 0,
                        index: this.index,
                        page: 0,
                        rowIndex: 0
                    });
                }
            } else {
                this.highlight.clearHighlight();
            }
        }
    }
    

    Se a amostra estiver configurada corretamente, o resultado final deverá ser semelhante a este:

    Search across multiple elements

    O igxTextHighlight permite que você pesquise em vários elementos que compartilham um destaque ativo. Isso é feito tendo o mesmo valor groupName em várias diretivas TextHighlight. Para configurar o exemplo, reutilizaremos a caixa de pesquisa do exemplo anterior, mas desta vez adicionaremos dois elementos div. As entradas column e row são úteis quando você tem vários elementos e, no nosso caso, o segundo div tem um valor de linha diferente.

    <div
      igxTextHighlight
      [groupName]="'group1'"
      [row]="0"
      [containerClass]="'search-text'"
      [value]="firstParagraph"
      class="search-text">
       {{firstParagraph}}
    </div>
    <div
      igxTextHighlight
      [groupName]="'group1'"
      [row]="1"
      [containerClass]="'search-text'"
      [value]="secondParagraph"
      class="search-text">
       {{secondParagraph}}
    </div>
    

    No arquivo .ts, temos os campos firstParagraph e secondParagraph, que são vinculados às respectivas entradas de valor das diretivas de destaque de texto. Além disso, agora usaremos ViewChildren em vez de ViewChild para obter todos os destaques em nosso modelo.

    public firstParagraph = "...";
    
    public secondParagraph = "...";
    
    @ViewChildren(IgxTextHighlightDirective)
    public highlights;
    

    Todo o restante do código no arquivo .ts é idêntico ao exemplo de elemento único, com exceção do método find. Alterações nesse método são necessárias, pois agora temos vários elementos, mas o código ali pode ser usado independentemente do número de diretivas TextHighlight que você tem na sua página.

    @Component({
        ...
    })
    export class HomeComponent {
        constructor(public textHighlightService: IgxTextHighlightService) {}
    
        private find(increment: number) {
            if (this.searchText) {
                let count = 0;
                const matchesArray = [];
    
                this.highlights.forEach((h) => {
                    count += h.highlight(this.searchText, this.caseSensitive);
                    matchesArray.push(count);
                });
    
                this.matchCount = count;
    
                this.index += increment;
                this.index = this.index < 0 ? this.matchCount - 1 : this.index;
                this.index = this.index > this.matchCount - 1 ? 0 : this.index;
    
                if (this.matchCount) {
                    let row;
    
                    for (let i = 0; i < matchesArray.length; i++) {
                        if (this.index < matchesArray[i]) {
                            row = i;
                            break;
                        }
                    }
    
                    const actualIndex = row === 0 ? this.index : this.index - matchesArray[row - 1];
    
                    this.textHighlightService.setActiveHighlight('group1', {
                        index: actualIndex,
                        rowIndex: row
                    });
                }
            } else {
                this.highlights.forEach((h) => {
                    h.clearHighlight();
                });
                this.matchCount = 0;
            }
        }
    }
    

    Styles

    A diretiva IgxTextHighlight pode ser estilizada em termos de alteração da cor e do plano de fundo de todas as ocorrências da string fornecida. Para começar, precisamos importar o arquivo index, onde todas as funções do tema e mixins de componentes vivem:

    @use "igniteui-angular/theming" as *;
    
    // IMPORTANT: Prior to Ignite UI for Angular version 13 use:
    // @import '~igniteui-angular/lib/core/styles/themes/index';
    

    Seguindo a abordagem mais simples, criamos um novo tema que estende o highlight-theme e aceita os parâmetros $resting-background, $resting-color, $active-background e $active-color.

    $dark-highlight: highlight-theme(
      $resting-background: #ffcd0f,
      $resting-color: #292826,
      $active-background: #292826,
      $active-color: #ffcd0f,
    );
    

    Os parâmetros $resting-background e $resting-color serão aplicados a todas as ocorrências destacadas, exceto à string destacada ativa, que será estilizada com base nos parâmetros $active-background e $active-color.

    O último passo é incluir o tema recém-criado.

    :host {
      ::ng-deep {
        @include css-vars($dark-highlight);
      }
    }
    
    Note

    Se o componente estiver usando um Emulated ViewEncapsulation, é necessário penetrate nesse encapsulamento usando::ng-deep para aplicar os estilos.

    Custom styles

    Digamos que queremos fornecer um estilo ainda mais rico para nossas partes de texto destacadas. Para fazer isso, podemos aproveitar as entradas cssClass e activeCssClass da diretiva IgxTextHighlight. Podemos combinar essas classes com os estilos do highlight-theme e fornecer uma experiência incrível para nossos usuários!

    Tudo o que precisamos fazer é criar algumas classes CSS com algumas propriedades e anexá-las usando as entradas acima:

    <div
      igxTextHighlight
      [cssClass]="'custom-highlight'"
      [activeCssClass]="'custom-active-highlight'">
       {{html}}
    </div>
    
    // cssClass
    .custom-highlight {
      border: 1px solid #ffcd0f;
    }
    // activeCssClass
    .custom-active-highlight {
      box-shadow: 0 0 3px 0 rgba(0, 0, 0, 0.75);
    }
    

    Como mencionado anteriormente, podemos até combiná-los com um tema:

    :host {
      ::ng-deep {
        @include css-vars($dark-highlight);  
        
        .custom-highlight {
          border: 1px solid #ffcd0f;
        }  
    
        .custom-active-highlight {
          box-shadow: 0 0 3px 0 rgba(0,0,0, .5);
        }
      }
    }
    

    Demo

    API References

    Para obter informações mais detalhadas sobre a API da diretiva TextHighlight, consulte o seguinte link:

    Componentes adicionais que foram usados:

    Additional Resources

    Nossa comunidade é ativa e sempre acolhedora para novas ideias.