mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[ACS-8159][ADF] Dynamic chip list - add rounding property, clear styles (#9767)
* [ACS-8054] dynamic chip list refactor * [ACS-8054] dynamic chip list refactor * [ACS-8054] dynamic chip list refactor * [ACS-8054] dynamic chip list refactor * [ACS-8054] update documentation and tests * [ACS-8159] update documentation and style * [ACS-8159] update branch * [ACS-8159] update branch
This commit is contained in:
@@ -18,6 +18,7 @@ This component shows dynamic list of chips which render depending on free space.
|
|||||||
[chips]="chips"
|
[chips]="chips"
|
||||||
[limitChipsDisplayed]="true"
|
[limitChipsDisplayed]="true"
|
||||||
[showDelete]="true"
|
[showDelete]="true"
|
||||||
|
[roundUpChips]="true"
|
||||||
(displayNext)="onDisplayNext()"
|
(displayNext)="onDisplayNext()"
|
||||||
(removedChip)="onRemovedChip($event)">
|
(removedChip)="onRemovedChip($event)">
|
||||||
</adf-dynamic-chip-list>
|
</adf-dynamic-chip-list>
|
||||||
@@ -27,12 +28,14 @@ This component shows dynamic list of chips which render depending on free space.
|
|||||||
|
|
||||||
### Properties
|
### Properties
|
||||||
|
|
||||||
| Name | Type | Default value | Description |
|
| Name | Type | Default value | Description |
|
||||||
|---------------------|---------------------------------------------------------------------------------|---------------|---------------------------------------------|
|
|---------------------|---------------------------------------------------------------------------------|---------------|----------------------------------------------------------------|
|
||||||
| limitChipsDisplayed | `boolean` | false | Should limit number of chips displayed. |
|
| limitChipsDisplayed | `boolean` | false | Should limit number of chips displayed. |
|
||||||
| showDelete | `boolean` | true | Show delete button. |
|
| showDelete | `boolean` | true | Show delete button. |
|
||||||
| pagination | [`Pagination`](../../../lib/js-api/src/api/content-rest-api/docs/Pagination.md) | | Provide if you want to use paginated chips. |
|
| roundUpChips | `boolean` | false | Round up chips increasing the border radius of a chip to 20px. |
|
||||||
| chips | [`Chip`](../../../lib/core/src/lib/dynamic-chip-list/chip.ts)`[]` | | List of chips to display. |
|
| pagination | [`Pagination`](../../../lib/js-api/src/api/content-rest-api/docs/Pagination.md) | | Provide if you want to use paginated chips. |
|
||||||
|
| chips | [`Chip`](../../../lib/core/src/lib/dynamic-chip-list/chip.ts)`[]` | | List of chips to display. |
|
||||||
|
|
||||||
|
|
||||||
### Events
|
### Events
|
||||||
|
|
||||||
|
@@ -17,11 +17,11 @@
|
|||||||
|
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { HighlightDirective } from './highlight.directive';
|
import { HighlightDirective } from './highlight.directive';
|
||||||
import { LogoutDirective } from './logout.directive';
|
|
||||||
import { UploadDirective } from './upload.directive';
|
|
||||||
import { TooltipCardDirective } from './tooltip-card/tooltip-card.directive';
|
|
||||||
import { TooltipCardComponent } from './tooltip-card/tooltip-card.component';
|
|
||||||
import { InfiniteSelectScrollDirective } from './infinite-select-scroll.directive';
|
import { InfiniteSelectScrollDirective } from './infinite-select-scroll.directive';
|
||||||
|
import { LogoutDirective } from './logout.directive';
|
||||||
|
import { TooltipCardComponent } from './tooltip-card/tooltip-card.component';
|
||||||
|
import { TooltipCardDirective } from './tooltip-card/tooltip-card.directive';
|
||||||
|
import { UploadDirective } from './upload.directive';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [HighlightDirective, LogoutDirective, UploadDirective, TooltipCardDirective, TooltipCardComponent, InfiniteSelectScrollDirective],
|
imports: [HighlightDirective, LogoutDirective, UploadDirective, TooltipCardDirective, TooltipCardComponent, InfiniteSelectScrollDirective],
|
||||||
|
@@ -1,39 +1,36 @@
|
|||||||
<div
|
<div #nodeListContainer
|
||||||
class="adf-dynamic-chip-list-container"
|
class="adf-dynamic-chip-list-container"
|
||||||
[class.adf-dynamic-chip-list-flex-column]="limitChipsDisplayed && (!calculationsDone || columnFlexDirection)"
|
[class.adf-dynamic-chip-list-flex-column]="limitChipsDisplayed && (!calculationsDone || columnFlexDirection)"
|
||||||
[class.adf-dynamic-chip-list-button-in-next-line]="moveLoadMoreButtonToNextRow"
|
[class.adf-dynamic-chip-list-button-in-next-line]="moveLoadMoreButtonToNextRow"
|
||||||
[class.adf-dynamic-chip-list-paginated]="paginationData"
|
[class.adf-dynamic-chip-list-paginated]="paginationData">
|
||||||
#nodeListContainer>
|
<mat-chip-list [class.adf-dynamic-chip-list-full-width]="limitChipsDisplayed && !calculationsDone"
|
||||||
<mat-chip-list
|
role="listbox"
|
||||||
[class.adf-dynamic-chip-list-full-width]="limitChipsDisplayed && !calculationsDone"
|
[attr.aria-label]="'METADATA.BASIC.TAGS' | translate">
|
||||||
role="listbox"
|
<mat-chip *ngFor="let chip of chipsToDisplay; let idx = index"
|
||||||
[attr.aria-label]="'METADATA.BASIC.TAGS' | translate">
|
class="adf-dynamic-chip-list-chip"
|
||||||
<mat-chip
|
[style.border-radius]="roundUpChips ? '20px' : '10px'"
|
||||||
class="adf-dynamic-chip-list-chip"
|
[style.font-weight]="'bold'"
|
||||||
*ngFor="let chip of chipsToDisplay; let idx = index"
|
(removed)="removedChip.emit(chip.id)">
|
||||||
(removed)="removedChip.emit(chip.id)">
|
|
||||||
<span id="adf-dynamic-chip-list-chip-name-{{ idx }}">{{ chip.name }}</span>
|
<span id="adf-dynamic-chip-list-chip-name-{{ idx }}">{{ chip.name }}</span>
|
||||||
<mat-icon
|
<mat-icon *ngIf="showDelete"
|
||||||
*ngIf="showDelete"
|
id="adf-dynamic-chip-list-delete-{{ chip.name }}"
|
||||||
id="adf-dynamic-chip-list-delete-{{ chip.name }}"
|
class="adf-dynamic-chip-list-delete-icon"
|
||||||
class="adf-dynamic-chip-list-delete-icon"
|
matChipRemove>
|
||||||
matChipRemove>
|
close
|
||||||
cancel
|
|
||||||
</mat-icon>
|
</mat-icon>
|
||||||
</mat-chip>
|
</mat-chip>
|
||||||
</mat-chip-list>
|
</mat-chip-list>
|
||||||
<button
|
<button data-automation-id="adf-dynamic-chip-list-view-more-button"
|
||||||
data-automation-id="adf-dynamic-chip-list-view-more-button"
|
class="adf-dynamic-chip-list-view-more-button"
|
||||||
mat-button
|
mat-button
|
||||||
[hidden]="!limitChipsDisplayed"
|
[hidden]="!limitChipsDisplayed"
|
||||||
[style.left.px]="viewMoreButtonLeftOffset"
|
[style.left.px]="viewMoreButtonLeftOffset"
|
||||||
[style.top.px]="viewMoreButtonTop"
|
[style.top.px]="viewMoreButtonTop"
|
||||||
class="adf-dynamic-chip-list-view-more-button"
|
[class.adf-dynamic-chip-list-hidden-btn]="!calculationsDone"
|
||||||
[class.adf-dynamic-chip-list-hidden-btn]="!calculationsDone"
|
(click)="displayNextChips($event)">
|
||||||
(click)="displayNextChips($event)">
|
|
||||||
{{
|
{{
|
||||||
paginationData ? ('DYNAMIC_CHIP_LIST.LOAD_MORE' | translate) :
|
paginationData ? ('DYNAMIC_CHIP_LIST.LOAD_MORE' | translate) :
|
||||||
('TAG_NODE_LIST.VIEW_MORE' | translate: { count: undisplayedChipsCount})
|
('TAG_NODE_LIST.VIEW_MORE' | translate: { count: undisplayedChipsCount })
|
||||||
}}
|
}}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
padding-bottom: 12px;
|
padding-bottom: 12px;
|
||||||
|
|
||||||
.adf-dynamic-chip-list-view-more-button {
|
.adf-dynamic-chip-list-view-more-button {
|
||||||
color: var(--adf-theme-foreground-text-color-054);
|
margin-left: 5px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
||||||
&[hidden] {
|
&[hidden] {
|
||||||
@@ -64,19 +64,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.adf-dynamic-chip-list-chip {
|
.adf-dynamic-chip-list-chip {
|
||||||
color: var(--theme-primary-color-default-contrast);
|
|
||||||
background-color: var(--theme-primary-color);
|
|
||||||
height: auto;
|
height: auto;
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
}
|
padding: 6px 11px;
|
||||||
|
|
||||||
.adf-dynamic-chip-list-delete-icon {
|
|
||||||
font-size: var(--theme-title-font-size);
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
display: inline-block;
|
|
||||||
fill: currentcolor;
|
|
||||||
height: 20px;
|
|
||||||
width: 20px;
|
|
||||||
color: var(--theme-primary-color-default-contrast);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -15,9 +15,10 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
|
|
||||||
import { Chip, CoreTestingModule, DynamicChipListComponent } from '@alfresco/adf-core';
|
import { Chip, CoreTestingModule, DynamicChipListComponent } from '@alfresco/adf-core';
|
||||||
import { SimpleChange } from '@angular/core';
|
import { SimpleChange } from '@angular/core';
|
||||||
|
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
|
|
||||||
describe('DynamicChipListComponent', () => {
|
describe('DynamicChipListComponent', () => {
|
||||||
let chips: Chip[] = [
|
let chips: Chip[] = [
|
||||||
@@ -132,6 +133,19 @@ describe('DynamicChipListComponent', () => {
|
|||||||
expect(deleteButton).not.toBeNull();
|
expect(deleteButton).not.toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should round up chips if roundUpChips is true', async () => {
|
||||||
|
component.roundUpChips = true;
|
||||||
|
|
||||||
|
component.ngOnChanges({
|
||||||
|
chips: new SimpleChange(undefined, component.chips, true)
|
||||||
|
});
|
||||||
|
fixture.detectChanges();
|
||||||
|
await fixture.whenStable();
|
||||||
|
|
||||||
|
const chip = fixture.debugElement.query(By.css('.adf-dynamic-chip-list-chip'));
|
||||||
|
expect(getComputedStyle(chip.nativeElement).borderRadius).toBe('20px');
|
||||||
|
});
|
||||||
|
|
||||||
it('should not render view more button by default', async () => {
|
it('should not render view more button by default', async () => {
|
||||||
component.ngOnChanges({
|
component.ngOnChanges({
|
||||||
chips: new SimpleChange(undefined, component.chips, true)
|
chips: new SimpleChange(undefined, component.chips, true)
|
||||||
|
@@ -15,6 +15,8 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { Pagination } from '@alfresco/js-api';
|
||||||
|
import { NgForOf, NgIf } from '@angular/common';
|
||||||
import {
|
import {
|
||||||
AfterViewInit,
|
AfterViewInit,
|
||||||
ChangeDetectorRef,
|
ChangeDetectorRef,
|
||||||
@@ -32,18 +34,22 @@ import {
|
|||||||
ViewChildren,
|
ViewChildren,
|
||||||
ViewEncapsulation
|
ViewEncapsulation
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
|
import { MatChip, MatChipsModule } from '@angular/material/chips';
|
||||||
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { Subject } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
import { MatChip } from '@angular/material/chips';
|
|
||||||
import { Chip } from './chip';
|
import { Chip } from './chip';
|
||||||
import { Pagination } from '@alfresco/js-api';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This component shows dynamic list of chips which render depending on free space.
|
* This component shows dynamic list of chips which render depending on free space.
|
||||||
*/
|
*/
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'adf-dynamic-chip-list',
|
selector: 'adf-dynamic-chip-list',
|
||||||
|
standalone: true,
|
||||||
templateUrl: './dynamic-chip-list.component.html',
|
templateUrl: './dynamic-chip-list.component.html',
|
||||||
styleUrls: ['./dynamic-chip-list.component.scss'],
|
styleUrls: ['./dynamic-chip-list.component.scss'],
|
||||||
|
imports: [MatChipsModule, TranslateModule, NgForOf, MatIconModule, NgIf, MatButtonModule],
|
||||||
encapsulation: ViewEncapsulation.None
|
encapsulation: ViewEncapsulation.None
|
||||||
})
|
})
|
||||||
export class DynamicChipListComponent implements OnChanges, OnInit, AfterViewInit, OnDestroy {
|
export class DynamicChipListComponent implements OnChanges, OnInit, AfterViewInit, OnDestroy {
|
||||||
@@ -64,6 +70,10 @@ export class DynamicChipListComponent implements OnChanges, OnInit, AfterViewIni
|
|||||||
@Input()
|
@Input()
|
||||||
limitChipsDisplayed = false;
|
limitChipsDisplayed = false;
|
||||||
|
|
||||||
|
/** Round up chips */
|
||||||
|
@Input()
|
||||||
|
roundUpChips = false;
|
||||||
|
|
||||||
/** Emitted when button for view more is clicked. */
|
/** Emitted when button for view more is clicked. */
|
||||||
@Output()
|
@Output()
|
||||||
displayNext = new EventEmitter<void>();
|
displayNext = new EventEmitter<void>();
|
||||||
@@ -166,20 +176,24 @@ export class DynamicChipListComponent implements OnChanges, OnInit, AfterViewIni
|
|||||||
const chips = this.matChips.toArray();
|
const chips = this.matChips.toArray();
|
||||||
let lastIndex = 0;
|
let lastIndex = 0;
|
||||||
do {
|
do {
|
||||||
chipsWidth = Math.max(chips.reduce((width, val, index) => {
|
chipsWidth = Math.max(
|
||||||
width += val._elementRef.nativeElement.getBoundingClientRect().width + chipMargin;
|
chips.reduce((width, val, index) => {
|
||||||
const availableSpace = index && index === chips.length - 1 || !this.paginationData ? containerWidth - viewMoreBtnWidth : containerWidth;
|
width += val._elementRef.nativeElement.getBoundingClientRect().width + chipMargin;
|
||||||
if (availableSpace >= width) {
|
const availableSpace =
|
||||||
chipsToDisplay = (this.paginationData ? chipsToDisplay : index) + 1;
|
(index && index === chips.length - 1) || !this.paginationData ? containerWidth - viewMoreBtnWidth : containerWidth;
|
||||||
lastIndex++;
|
if (availableSpace >= width) {
|
||||||
this.viewMoreButtonLeftOffset = width;
|
chipsToDisplay = (this.paginationData ? chipsToDisplay : index) + 1;
|
||||||
this.viewMoreButtonLeftOffsetBeforeFlexDirection = width;
|
lastIndex++;
|
||||||
}
|
this.viewMoreButtonLeftOffset = width;
|
||||||
return width;
|
this.viewMoreButtonLeftOffsetBeforeFlexDirection = width;
|
||||||
}, 0), chipsWidth);
|
}
|
||||||
|
return width;
|
||||||
|
}, 0),
|
||||||
|
chipsWidth
|
||||||
|
);
|
||||||
chips.splice(0, lastIndex);
|
chips.splice(0, lastIndex);
|
||||||
lastIndex = 0;
|
lastIndex = 0;
|
||||||
} while ((chips.length || chipsToDisplay < this.matChips.length && this.matChips.length) && this.paginationData);
|
} while ((chips.length || (chipsToDisplay < this.matChips.length && this.matChips.length)) && this.paginationData);
|
||||||
this.arrangeElements(containerWidth, chipsWidth, viewMoreBtnWidth, chipsToDisplay, viewMoreButton);
|
this.arrangeElements(containerWidth, chipsWidth, viewMoreBtnWidth, chipsToDisplay, viewMoreButton);
|
||||||
this.calculationsDone = true;
|
this.calculationsDone = true;
|
||||||
}
|
}
|
||||||
@@ -189,11 +203,17 @@ export class DynamicChipListComponent implements OnChanges, OnInit, AfterViewIni
|
|||||||
return parseInt(chipStyles.marginLeft, 10) + parseInt(chipStyles.marginRight, 10);
|
return parseInt(chipStyles.marginLeft, 10) + parseInt(chipStyles.marginRight, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
private arrangeElements(containerWidth: number, chipsWidth: number, viewMoreBtnWidth: number, chipsToDisplay: number,
|
private arrangeElements(
|
||||||
viewMoreButton: HTMLButtonElement): void {
|
containerWidth: number,
|
||||||
if ((containerWidth - chipsWidth - viewMoreBtnWidth) <= 0) {
|
chipsWidth: number,
|
||||||
|
viewMoreBtnWidth: number,
|
||||||
|
chipsToDisplay: number,
|
||||||
|
viewMoreButton: HTMLButtonElement
|
||||||
|
): void {
|
||||||
|
if (containerWidth - chipsWidth - viewMoreBtnWidth <= 0) {
|
||||||
const chip = this.paginationData ? this.matChips.last : this.matChips.first;
|
const chip = this.paginationData ? this.matChips.last : this.matChips.first;
|
||||||
const hasNotEnoughSpaceForMoreButton = (containerWidth < (chip?._elementRef.nativeElement.offsetWidth + chip?._elementRef.nativeElement.offsetLeft + viewMoreBtnWidth));
|
const hasNotEnoughSpaceForMoreButton =
|
||||||
|
containerWidth < chip?._elementRef.nativeElement.offsetWidth + chip?._elementRef.nativeElement.offsetLeft + viewMoreBtnWidth;
|
||||||
this.columnFlexDirection = chipsToDisplay === 1 && !this.paginationData && hasNotEnoughSpaceForMoreButton;
|
this.columnFlexDirection = chipsToDisplay === 1 && !this.paginationData && hasNotEnoughSpaceForMoreButton;
|
||||||
this.moveLoadMoreButtonToNextRow = this.paginationData && hasNotEnoughSpaceForMoreButton;
|
this.moveLoadMoreButtonToNextRow = this.paginationData && hasNotEnoughSpaceForMoreButton;
|
||||||
this.undisplayedChipsCount = this.chipsToDisplay.length - chipsToDisplay;
|
this.undisplayedChipsCount = this.chipsToDisplay.length - chipsToDisplay;
|
||||||
|
@@ -17,21 +17,9 @@
|
|||||||
|
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { DynamicChipListComponent } from './dynamic-chip-list.component';
|
import { DynamicChipListComponent } from './dynamic-chip-list.component';
|
||||||
import { MatChipsModule } from '@angular/material/chips';
|
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
|
||||||
import { CommonModule } from '@angular/common';
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [DynamicChipListComponent],
|
imports: [DynamicChipListComponent],
|
||||||
imports: [
|
|
||||||
MatChipsModule,
|
|
||||||
MatIconModule,
|
|
||||||
MatButtonModule,
|
|
||||||
TranslateModule,
|
|
||||||
CommonModule
|
|
||||||
],
|
|
||||||
exports: [DynamicChipListComponent]
|
exports: [DynamicChipListComponent]
|
||||||
})
|
})
|
||||||
export class DynamicChipListModule {}
|
export class DynamicChipListModule {}
|
||||||
|
Reference in New Issue
Block a user