[AC-1088] Truncating collection names on Groups table (#5236)

* [AC-1088] Set no-wrap to 'select all' column on groups table

* [AC-1088] Using EllipsisPipe on GroupsComponent to truncate group names

* [AC-1088] Reverted using no-wrap on column header

* [AC-1088] Removed truncateCollectionNames

* [AC-1088] Added 'truncate' option to badge and badge-list components

* [AC-1088] Truncating collection names on groups component

* [AC-1088] Marked EllipsisPipe as deprecated

* [AC-1088] Removed EllipsisPipe from GroupsComponent

* [AC-1088] Added badge truncate to storybook stories

* [AC-1088] Setting badge css requirements for truncate

* [AC-1088] Added storybook stories for truncated badges

* [AC-1088] Set badges truncate default value to true

* [AC-1088] Set badges to use class tw-inline-block and tw-align-text-top

* [AC-1088] Set title on each badge list item if truncated

* [AC-1088] Set title on badge if truncated

* [AC-1088] Removed duplicate truncate on badge-list component

* [AC-1088] Swapped setting badge title from ngAfterContentInit to HostBinding

* [AC-1088] Configured badge stories to have the truncate option

* [AC-1088] Fixed badges tooltip to not include commas added for screen readers on badge lists

* [AC-1088] Added lengthy text to single badge on storybook

* [AC-1088] In badge-list moved the commas out from the badges

* [AC-1088] Removed irrelevant comment and moved the text align class next to other font classes
This commit is contained in:
Rui Tomé 2023-06-12 10:56:03 +01:00 committed by GitHub
parent f436e97c29
commit 0ab982038c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 42 additions and 10 deletions

View File

@ -3,6 +3,9 @@ import { Pipe, PipeTransform } from "@angular/core";
@Pipe({ @Pipe({
name: "ellipsis", name: "ellipsis",
}) })
/**
* @deprecated Use the tailwind class 'tw-truncate' instead
*/
export class EllipsisPipe implements PipeTransform { export class EllipsisPipe implements PipeTransform {
transform(value: string, limit = 25, completeWords = false, ellipsis = "...") { transform(value: string, limit = 25, completeWords = false, ellipsis = "...") {
if (value.length <= limit) { if (value.length <= limit) {

View File

@ -1,8 +1,10 @@
<div class="tw-inline-flex tw-gap-2"> <div class="tw-inline-flex tw-gap-2">
<span *ngFor="let item of filteredItems; let last = last" bitBadge [badgeType]="badgeType"> <ng-container *ngFor="let item of filteredItems; let last = last">
<span bitBadge [badgeType]="badgeType" [truncate]="truncate">
{{ item }} {{ item }}
<span class="tw-sr-only" *ngIf="!last || isFiltered">, </span>
</span> </span>
<span class="tw-sr-only" *ngIf="!last || isFiltered">, </span>
</ng-container>
<span *ngIf="isFiltered" bitBadge [badgeType]="badgeType"> <span *ngIf="isFiltered" bitBadge [badgeType]="badgeType">
{{ "plusNMore" | i18n : (items.length - filteredItems.length).toString() }} {{ "plusNMore" | i18n : (items.length - filteredItems.length).toString() }}
</span> </span>

View File

@ -14,6 +14,7 @@ export class BadgeListComponent implements OnChanges {
@Input() badgeType: BadgeTypes = "primary"; @Input() badgeType: BadgeTypes = "primary";
@Input() items: string[] = []; @Input() items: string[] = [];
@Input() truncate = true;
@Input() @Input()
get maxItems(): number | undefined { get maxItems(): number | undefined {

View File

@ -29,6 +29,7 @@ export default {
], ],
args: { args: {
badgeType: "primary", badgeType: "primary",
truncate: false,
}, },
parameters: { parameters: {
design: { design: {
@ -44,7 +45,7 @@ export const Default: Story = {
render: (args) => ({ render: (args) => ({
props: args, props: args,
template: ` template: `
<bit-badge-list [badgeType]="badgeType" [maxItems]="maxItems" [items]="items"></bit-badge-list> <bit-badge-list [badgeType]="badgeType" [maxItems]="maxItems" [items]="items" [truncate]="truncate"></bit-badge-list>
`, `,
}), }),
@ -52,5 +53,16 @@ export const Default: Story = {
badgeType: "info", badgeType: "info",
maxItems: 3, maxItems: 3,
items: ["Badge 1", "Badge 2", "Badge 3", "Badge 4", "Badge 5"], items: ["Badge 1", "Badge 2", "Badge 3", "Badge 4", "Badge 5"],
truncate: false,
},
};
export const Truncated: Story = {
...Default,
args: {
badgeType: "info",
maxItems: 3,
items: ["Badge 1", "Badge 2 containing lengthy text", "Badge 3", "Badge 4", "Badge 5"],
truncate: true,
}, },
}; };

View File

@ -26,11 +26,12 @@ const hoverStyles: Record<BadgeTypes, string[]> = {
export class BadgeDirective { export class BadgeDirective {
@HostBinding("class") get classList() { @HostBinding("class") get classList() {
return [ return [
"tw-inline", "tw-inline-block",
"tw-py-0.5", "tw-py-0.5",
"tw-px-1.5", "tw-px-1.5",
"tw-font-bold", "tw-font-bold",
"tw-text-center", "tw-text-center",
"tw-align-text-top",
"!tw-text-contrast", "!tw-text-contrast",
"tw-rounded", "tw-rounded",
"tw-border-none", "tw-border-none",
@ -44,14 +45,19 @@ export class BadgeDirective {
"focus:tw-ring-primary-700", "focus:tw-ring-primary-700",
] ]
.concat(styles[this.badgeType]) .concat(styles[this.badgeType])
.concat(this.hasHoverEffects ? hoverStyles[this.badgeType] : []); .concat(this.hasHoverEffects ? hoverStyles[this.badgeType] : [])
.concat(this.truncate ? ["tw-truncate", "tw-max-w-40"] : []);
}
@HostBinding("attr.title") get title() {
return this.truncate ? this.el.nativeElement.textContent.trim() : null;
} }
@Input() badgeType: BadgeTypes = "primary"; @Input() badgeType: BadgeTypes = "primary";
@Input() truncate = true;
private hasHoverEffects = false; private hasHoverEffects = false;
constructor(el: ElementRef<Element>) { constructor(private el: ElementRef<HTMLElement>) {
this.hasHoverEffects = el?.nativeElement?.nodeName != "SPAN"; this.hasHoverEffects = el?.nativeElement?.nodeName != "SPAN";
} }
} }

View File

@ -14,6 +14,7 @@ export default {
], ],
args: { args: {
badgeType: "primary", badgeType: "primary",
truncate: false,
}, },
parameters: { parameters: {
design: { design: {
@ -29,11 +30,11 @@ export const Primary: Story = {
render: (args) => ({ render: (args) => ({
props: args, props: args,
template: ` template: `
<span class="tw-text-main">Span </span><span bitBadge [badgeType]="badgeType">Badge</span> <span class="tw-text-main">Span </span><span bitBadge [badgeType]="badgeType" [truncate]="truncate">Badge containing lengthy text</span>
<br><br> <br><br>
<span class="tw-text-main">Link </span><a href="#" bitBadge [badgeType]="badgeType">Badge</a> <span class="tw-text-main">Link </span><a href="#" bitBadge [badgeType]="badgeType" [truncate]="truncate">Badge</a>
<br><br> <br><br>
<span class="tw-text-main">Button </span><button bitBadge [badgeType]="badgeType">Badge</button> <span class="tw-text-main">Button </span><button bitBadge [badgeType]="badgeType" [truncate]="truncate">Badge</button>
`, `,
}), }),
}; };
@ -72,3 +73,10 @@ export const Info: Story = {
badgeType: "info", badgeType: "info",
}, },
}; };
export const Truncated: Story = {
...Primary,
args: {
truncate: true,
},
};