Skip to content

Commit

Permalink
feat(kit): ItemsWithMore add side option (#9363)
Browse files Browse the repository at this point in the history
Co-authored-by: taiga-family-bot <[email protected]>
  • Loading branch information
waterplea and taiga-family-bot authored Oct 7, 2024
1 parent b5c4156 commit 47d7178
Show file tree
Hide file tree
Showing 11 changed files with 216 additions and 78 deletions.
4 changes: 1 addition & 3 deletions projects/core/components/data-list/data-list.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,6 @@ export class TuiDataListComponent<T>
}

private get elements(): readonly HTMLElement[] {
return Array.from(
this.el.querySelectorAll('a[tuiOption],button[tuiOption],input'),
);
return Array.from(this.el.querySelectorAll('a,button,input'));
}
}
1 change: 1 addition & 0 deletions projects/core/components/data-list/data-list.style.less
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ tui-data-list {
cursor: default;
}

&:hover,
&:focus-within,
&._with-dropdown {
background-color: var(--tui-background-neutral-1);
Expand Down
1 change: 1 addition & 0 deletions projects/core/styles/components/icon.less
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ tui-icon {
block-size: 1em;
font-size: 1.5rem;
flex-shrink: 0;
border: 0 solid transparent;
vertical-align: middle;
box-sizing: border-box;
mask: var(--t-icon-bg) no-repeat center/contain;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<tui-items-with-more
side="start"
[itemsLimit]="3"
>
<ng-container *ngFor="let item of items; let first = first">
<ng-container *tuiItem>
<tui-icon
*ngIf="!first"
icon="@tui.chevron-right"
[style.border-width.rem]="0.25"
[style.opacity]="0.25"
/>
<button
appearance="flat"
size="xs"
tuiButton
type="button"
>
{{ item }}
</button>
</ng-container>
</ng-container>
<ng-template
let-index
tuiMore
>
<button
appearance="flat"
iconStart="@tui.ellipsis"
size="xs"
tuiDropdownOpen
tuiIconButton
type="button"
[tuiDropdown]="dropdown"
>
More
</button>
<ng-template #dropdown>
<tui-data-list size="s">
<ng-container *ngFor="let item of items; let i = index">
<button
*ngIf="i < index"
tuiOption
type="button"
>
{{ item }}
</button>
</ng-container>
</tui-data-list>
</ng-template>
</ng-template>
</tui-items-with-more>
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {NgForOf, NgIf} from '@angular/common';
import {Component, inject} from '@angular/core';
import {changeDetection} from '@demo/emulate/change-detection';
import {encapsulation} from '@demo/emulate/encapsulation';
import {TuiButton, TuiDataList, TuiDropdown, TuiIcon, TuiLink} from '@taiga-ui/core';
import {TuiItemsWithMore} from '@taiga-ui/kit';

@Component({
standalone: true,
imports: [
NgForOf,
NgIf,
TuiButton,
TuiDataList,
TuiDropdown,
TuiIcon,
TuiItemsWithMore,
TuiLink,
],
templateUrl: './index.html',
encapsulation,
changeDetection,
})
export default class Page {
protected readonly items = inject<readonly string[]>('Pythons' as any);
}
76 changes: 41 additions & 35 deletions projects/demo/src/modules/components/items-with-more/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,17 @@
type="components"
>
<ng-template pageTab>
<div class="tui-space_bottom-3">Component to hide overflown items behind custom content.</div>
<p>Component to hide overflown items behind custom content.</p>

<tui-doc-example
id="base"
heading="Basic"
[component]="1 | tuiComponent"
[content]="1 | tuiExample: 'html'"
[fullsize]="true"
>
<tui-notification class="tui-space_bottom-3">
Resize the screen to see extra items disappear
</tui-notification>
</tui-doc-example>
<tui-notification>Resize the screen to see extra items disappear</tui-notification>

<tui-doc-example
id="dropdown"
heading="Dropdown"
[component]="2 | tuiComponent"
[content]="2 | tuiExample"
*ngFor="let example of examples; let index = index"
[component]="index + 1 | tuiComponent"
[content]="index + 1 | tuiExample"
[fullsize]="true"
[heading]="example"
[id]="example | tuiKebab"
/>
</ng-template>

Expand All @@ -32,6 +23,7 @@
<tui-items-with-more
[itemsLimit]="itemsLimit"
[required]="required"
[side]="side"
>
<ng-container *ngFor="let item of items">
<tui-chip
Expand All @@ -41,39 +33,53 @@
{{ item }}
</tui-chip>
</ng-container>
<span *tuiMore>and now for something completely different!</span>
<span
*tuiMore
class="tui-space_right-2"
>
and now !
</span>
</tui-items-with-more>
</tui-doc-demo>
<p>
Use
<code>tuiItem</code>
<code>Item</code>
directive for each item
</p>
<p>
Use
<code>tuiMore</code>
<code>More</code>
directive for "See more" content
</p>
<tui-doc-documentation>
<ng-template
documentationPropertyMode="input"
documentationPropertyName="itemsLimit"
documentationPropertyType="number"
[documentationPropertyValues]="itemsLimitVariants"
[(documentationPropertyValue)]="itemsLimit"
<table tuiDocAPI>
<tr
name="[itemsLimit]"
tuiDocAPIItem
type="number"
[items]="itemsLimitVariants"
[(value)]="itemsLimit"
>
Artificial limit on visible items
</ng-template>
<ng-template
documentationPropertyMode="input"
documentationPropertyName="required"
documentationPropertyType="number"
[documentationPropertyValues]="requiredVariants"
[(documentationPropertyValue)]="required"
</tr>
<tr
name="[required]"
tuiDocAPIItem
type="number"
[items]="requiredVariants"
[(value)]="required"
>
Index of an item that must remain visible
</ng-template>
</tui-doc-documentation>
</tr>
<tr
name="[side]"
tuiDocAPIItem
type="number"
[items]="sideVariants"
[(value)]="side"
>
Side of the "See more" content
</tr>
</table>
</ng-template>

<tui-setup *pageTab />
Expand Down
7 changes: 3 additions & 4 deletions projects/demo/src/modules/components/items-with-more/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,12 @@ import {TuiChip, TuiItemsWithMore} from '@taiga-ui/kit';
changeDetection,
})
export default class Page {
protected readonly examples = ['Basic', 'Dropdown', 'Side'];
protected readonly items = inject<readonly string[]>('Pythons' as any);

protected readonly requiredVariants = [-1, 2, 4];

protected readonly itemsLimitVariants = [Infinity, 4, 2];

protected readonly sideVariants = ['start', 'end'] as const;
protected side: 'end' | 'start' = this.sideVariants[1];
protected required = this.requiredVariants[0]!;

protected itemsLimit = this.itemsLimitVariants[0]!;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ import {
inject,
TemplateRef,
} from '@angular/core';
import {toSignal} from '@angular/core/rxjs-interop';
import {
MutationObserverService,
WA_MUTATION_OBSERVER_INIT,
} from '@ng-web-apis/mutation-observer';
import {ResizeObserverService} from '@ng-web-apis/resize-observer';
import {EMPTY_QUERY} from '@taiga-ui/cdk/constants';
import {TuiItem} from '@taiga-ui/cdk/directives/item';
import {TuiLet} from '@taiga-ui/cdk/directives/let';
import type {TuiContext} from '@taiga-ui/cdk/types';

import {TuiItemsWithMoreDirective} from './items-with-more.directive';
Expand All @@ -25,7 +25,7 @@ import {TuiMore} from './more.directive';
@Component({
standalone: true,
selector: 'tui-items-with-more',
imports: [AsyncPipe, NgForOf, NgIf, NgTemplateOutlet, TuiLet],
imports: [AsyncPipe, NgForOf, NgIf, NgTemplateOutlet],
templateUrl: './items-with-more.template.html',
styleUrls: ['./items-with-more.style.less'],
changeDetection: ChangeDetectionStrategy.OnPush,
Expand All @@ -45,7 +45,7 @@ import {TuiMore} from './more.directive';
hostDirectives: [
{
directive: TuiItemsWithMoreDirective,
inputs: ['itemsLimit', 'required'],
inputs: ['itemsLimit', 'required', 'side'],
},
],
})
Expand All @@ -57,5 +57,25 @@ export class TuiItemsWithMoreComponent {
protected readonly more?: TemplateRef<TuiContext<number>>;

protected readonly directive = inject(TuiItemsWithMoreDirective);
protected readonly lastVisibleIndex$ = inject(TuiItemsWithMoreService);
protected readonly lastIndex = toSignal(inject(TuiItemsWithMoreService), {
initialValue: 0,
});

protected get isMoreHidden(): boolean {
const {side} = this.directive;

return (
(this.lastIndex() >= this.items.length - 1 && side === 'end') ||
(!this.lastIndex() && side === 'start')
);
}

protected isHidden(index: number): boolean {
const {side, required} = this.directive;

return (
(index > this.lastIndex() && index !== required && side === 'end') ||
(index < this.lastIndex() && index !== required && side === 'start')
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ export class TuiItemsWithMoreDirective implements OnChanges {
@Input()
public required = -1;

@Input()
public side: 'end' | 'start' = 'end';

// TODO: refactor to signal inputs after Angular update
public readonly change$ = new Subject<void>();

Expand Down
Loading

0 comments on commit 47d7178

Please sign in to comment.