Angular 텍스트 강조 지시문 개요

    IgxTextHighlightDirective 그리고 IgxTextHighlightService Ignite UI for Angular 에서는 텍스트의 일부를 강조 표시하는 데 사용되며, 대소문자를 구분하는 검색 옵션을 제공하고 정확히 일치하는 항목만 강조 표시합니다. 이를 통해 개발자는 이미 강조 표시된 부분이 될 수 있는 활성 강조 표시를 유지할 수 있습니다.

    Angular Text Highlight Directive Example

    Getting Started with Ignite UI for Angular Text Highlight Directive

    Ignite UI for Angular 텍스트 강조 표시 지시문을 시작하려면 먼저 Ignite UI for Angular 설치해야 합니다. 기존 Angular 애플리케이션에서 다음 명령을 입력합니다.

    ng add igniteui-angular
    

    Ignite UI for Angular에 대한 전체 소개를 보려면 시작하기 항목을 읽어보세요.

    다음 단계는 IgxTextHighlightModule 당신의 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 {}
    

    또는 16.0.0부터 IgxTextHighlightDirective 독립형 종속성으로 가져올 수 있습니다.

    // 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) {}
    }
    

    이제 Ignite UI for Angular 텍스트 강조 표시 모듈 또는 지시문을 가져왔으므로 사용을 igxTextHighlight 시작할 수 있습니다.

    Using the Angular Text Highlight Directive

    텍스트의 다른 부분을 강조 표시하는 데 사용할 수 있는 검색 상자를 만들어 보겠습니다. Ignite UI for Angular 사용하겠습니다. 입력 그룹 여기에는 명확한 일치 항목 찾기, 다음 찾기, 이전 찾기 버튼, 검색에서 대소문자 구분 여부를 지정하는 버튼이 포함된 텍스트 입력을 추가할 구성 요소입니다. 또한 우리가 찾은 일치 항목 수에 대한 레이블도 있습니다.

    <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>
    

    그런 다음 텍스트와 IgxTextHighlight 지시문이 포함된 div를 추가합니다. 입력된 값을 div의 텍스트에 바인딩해야 하므로 div의 텍스트에도 보간법을 사용합니다.

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

    먼저 구성 요소의 .ts 파일에서 구성 요소 템플릿의 바인딩에 사용되는 다음 필드를 추가해야 합니다.

    @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;
        }
    }
    

    그런 다음 사용자가 검색 상자에 입력한 텍스트에 강조 표시를 적용하고 활성 강조 표시를 이동할 수 있도록 다음 메서드를 추가해야 합니다.

    @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();
            }
        }
    }
    

    샘플이 올바르게 구성되면 최종 결과는 다음과 같습니다.

    Search across multiple elements

    igxTextHighlight 사용하면 하나의 활성 하이라이트를 모두 공유하는 여러 요소를 검색할 수 있습니다. 이는 여러 TextHighlight 지시어에 걸쳐 동일한 groupName 값을 사용하여 수행됩니다. 샘플을 설정하기 위해 이전 샘플의 검색 상자를 재사용하지만 이번에는 두 개의 div 요소를 추가하겠습니다. column​ ​row 입력은 요소가 여러 개 있고 이 경우 두 번째 div의 행 값이 다를 때 유용합니다.

    <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>
    

    .ts 파일에는 텍스트 강조 표시 지시문의 각 값 입력에 바인딩된 firstParagraphsecondParagraph 필드가 있습니다. 또한 이제 ViewChild 대신 ViewChildren을 사용하여 템플릿의 모든 하이라이트를 가져옵니다.

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

    .ts 파일의 나머지 모든 코드는 find 메소드를 제외하고 단일 요소 예제와 동일합니다. 이제 여러 요소가 있으므로 이 메서드를 변경해야 하지만 페이지에 있는 TextHighlight 지시어 수에 관계없이 코드를 사용할 수 있습니다.

    @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

    IgxTextHighlight 지시어는 주어진 문자열의 모든 발생에 대한 색상과 배경을 변경하는 방식으로 스타일을 지정할 수 있습니다. 시작하려면 모든 테마 기능과 구성 요소 믹스인이 있는 index 파일을 가져와야 합니다.

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

    가장 간단한 접근 방식에 따라, highlight-theme 확장하고 $resting-background, $resting-color, $active-background$active-color 매개변수를 허용하는 새로운 테마를 생성합니다.

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

    $resting-background$resting-color 매개변수는 $active-background$active-color 매개변수에 따라 스타일이 지정되는 활성 강조표시 문자열을 제외하고 강조표시된 모든 항목에 적용됩니다.

    마지막 단계는 새로 생성된 테마를 포함하는 것입니다.

    $legacy-support​ ​true로 설정된 경우 다음과 같은 구성 요소 테마를 포함합니다.

    @include highlight($dark-highlight);
    
    Note

    구성 요소가 Emulated ViewEncapsulation을 사용하는 경우::ng-deep 사용하여 이 캡슐화를 침투해야 합니다.

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

    $legacy-support​ ​false (기본값)로 설정된 경우 다음과 같은 구성 요소 CSS 변수를 포함합니다.

    @include css-vars($dark-highlight);
    
    Note

    기본적으로 $legacy-support​ ​false로 설정되어 있습니다.

    Custom styles

    강조 표시된 텍스트 부분에 더욱 풍부한 스타일을 제공하고 싶다고 가정해 보겠습니다. 이를 위해 IgxTextHighlight 지시문의 cssClassactiveCssClass 입력을 활용할 수 있습니다. 이러한 클래스를 highlight-theme의 스타일과 결합하여 사용자에게 멋진 경험을 제공할 수 있습니다!

    우리가 해야 할 일은 일부 속성이 포함된 몇 개의 CSS 클래스를 만들고 위의 입력을 사용하여 이를 연결하는 것입니다.

    <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);
    }
    

    앞서 언급했듯이 테마와 결합할 수도 있습니다.

    :host {
        ::ng-deep {
           @include highlight($dark-highlight);
            
           // cssClass
           .custom-highlight {
                border: 1px solid #FFCD0F;
           }
            
            // activeCssClass
           .custom-active-highlight {
                box-shadow: 0 0 3px 0 rgba(0,0,0,0.75);
            }
       }
    }
    

    Demo

    API References

    TextHighlight 지시문의 API에 대한 자세한 내용은 다음 링크를 참조하세요.

    사용된 추가 구성요소:

    Additional Resources

    우리 커뮤니티는 활동적이며 항상 새로운 아이디어를 환영합니다.