Skip to content

Commit aa5162a

Browse files
committed
refactor(pagination): signal inputs, host bindings, cleanup, tests
1 parent 187663d commit aa5162a

File tree

6 files changed

+96
-67
lines changed

6 files changed

+96
-67
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
- refactor(header): signal inputs, host bindings, cleanup, tests
1313
- refactor(theme.directive): signal inputs, host bindings, cleanup, tests
1414
- refactor(offcanvas): signal inputs, host bindings, cleanup, tests
15+
- refactor(pagination): signal inputs, host bindings, cleanup, tests
1516
- test(accordion): coverage
1617
- test(element-ref): update
1718
- test(backdrop): coverage

projects/coreui-angular/src/lib/pagination/page-item/page-item.component.spec.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ describe('PaginationItemComponent', () => {
99
beforeEach(async () => {
1010
await TestBed.configureTestingModule({
1111
imports: [PageItemComponent]
12-
})
13-
.compileComponents();
12+
}).compileComponents();
1413
});
1514

1615
beforeEach(() => {
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,60 @@
1+
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
2+
import { Component, ComponentRef, DebugElement, input, Renderer2 } from '@angular/core';
3+
import { provideRouter, RouterLink } from '@angular/router';
4+
5+
import { PageLinkDirective } from '../page-link/page-link.directive';
6+
import { PageItemComponent } from './page-item.component';
17
import { PageItemDirective } from './page-item.directive';
2-
import { TestBed } from '@angular/core/testing';
3-
import { Renderer2 } from '@angular/core';
8+
import { By } from '@angular/platform-browser';
9+
10+
@Component({
11+
selector: 'c-test',
12+
imports: [PageItemComponent, PageLinkDirective, PageItemComponent, PageLinkDirective, RouterLink],
13+
template: `
14+
<c-page-item [disabled]="disabled()">
15+
<a cPageLink [routerLink]="[]">Previous</a>
16+
</c-page-item>
17+
`
18+
})
19+
export class TestComponent {
20+
readonly disabled = input(false);
21+
}
422

523
describe('PageItemDirective', () => {
24+
let component: TestComponent;
25+
let componentRef: ComponentRef<TestComponent>;
26+
let fixture: ComponentFixture<TestComponent>;
27+
let debugElement: DebugElement;
28+
629
beforeEach(() => {
730
TestBed.configureTestingModule({
8-
providers: [Renderer2]
9-
});
31+
imports: [TestComponent],
32+
providers: [Renderer2, provideRouter([])]
33+
}).compileComponents();
34+
35+
fixture = TestBed.createComponent(TestComponent);
36+
component = fixture.componentInstance;
37+
componentRef = fixture.componentRef;
38+
debugElement = fixture.debugElement.query(By.directive(PageLinkDirective));
1039
});
40+
1141
it('should create an instance', () => {
1242
TestBed.runInInjectionContext(() => {
1343
const directive = new PageItemDirective();
1444
expect(directive).toBeTruthy();
1545
});
1646
});
47+
48+
it('should toggle disable state for the component', fakeAsync(() => {
49+
expect(debugElement.nativeElement.getAttribute('aria-disabled')).toBeNull();
50+
expect(debugElement.nativeElement.getAttribute('tabindex')).toBeNull();
51+
componentRef.setInput('disabled', true);
52+
tick();
53+
fixture.detectChanges();
54+
expect(debugElement.nativeElement.getAttribute('aria-disabled')).toBe('true');
55+
expect(debugElement.nativeElement.getAttribute('tabindex')).toBe('-1');
56+
componentRef.setInput('disabled', false);
57+
tick();
58+
fixture.detectChanges();
59+
}));
1760
});
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,58 @@
1-
import {
2-
AfterContentInit,
3-
ContentChild,
4-
Directive,
5-
ElementRef,
6-
HostBinding,
7-
inject,
8-
Input,
9-
OnChanges,
10-
Renderer2,
11-
SimpleChanges
12-
} from '@angular/core';
1+
import { computed, contentChild, Directive, effect, ElementRef, inject, input, Renderer2 } from '@angular/core';
132

143
import { PageLinkDirective } from '../page-link/page-link.directive';
154

165
@Directive({
176
selector: '[cPageItem]',
18-
host: { class: 'page-item' }
7+
host: {
8+
class: 'page-item',
9+
'[class]': 'hostClasses()',
10+
'[attr.aria-current]': 'ariaCurrent()'
11+
}
1912
})
20-
export class PageItemDirective implements AfterContentInit, OnChanges {
13+
export class PageItemDirective {
2114
readonly #renderer = inject(Renderer2);
2215

2316
/**
2417
* Toggle the active state for the component.
25-
* @type boolean
18+
* @return boolean
2619
*/
27-
@Input() active?: boolean;
20+
readonly active = input<boolean>();
21+
2822
/**
2923
* Toggle the disabled state for the component.
30-
* @type boolean
24+
* @return boolean
3125
*/
32-
@Input() disabled?: boolean;
26+
readonly disabled = input<boolean>();
3327

34-
@HostBinding('attr.aria-current')
35-
get ariaCurrent(): string | null {
36-
return this.active ? 'page' : null;
37-
}
28+
readonly ariaCurrent = computed(() => {
29+
return this.active() ? 'page' : null;
30+
});
3831

39-
@HostBinding('class')
40-
get hostClasses(): any {
32+
readonly hostClasses = computed(() => {
4133
return {
4234
'page-item': true,
43-
disabled: this.disabled,
44-
active: this.active
45-
};
46-
}
47-
48-
@ContentChild(PageLinkDirective, { read: ElementRef }) pageLinkElementRef!: ElementRef;
35+
disabled: this.disabled(),
36+
active: this.active()
37+
} as Record<string, boolean>;
38+
});
4939

50-
ngAfterContentInit(): void {
51-
this.setAttributes();
52-
}
40+
readonly pageLinkElementRef = contentChild(PageLinkDirective, { read: ElementRef });
5341

54-
ngOnChanges(changes: SimpleChanges): void {
55-
if (changes['disabled']) {
56-
this.setAttributes();
57-
}
58-
}
59-
60-
setAttributes(): void {
61-
if (!this.pageLinkElementRef) {
42+
readonly pageLinkElementRefEffect = effect(() => {
43+
const pageLinkElementRef = this.pageLinkElementRef();
44+
const disabled = this.disabled();
45+
if (!pageLinkElementRef) {
6246
return;
6347
}
64-
const pageLinkElement = this.pageLinkElementRef.nativeElement;
48+
const pageLinkElement = pageLinkElementRef.nativeElement;
6549

66-
if (this.disabled) {
50+
if (disabled) {
6751
this.#renderer.setAttribute(pageLinkElement, 'aria-disabled', 'true');
6852
this.#renderer.setAttribute(pageLinkElement, 'tabindex', '-1');
6953
} else {
7054
this.#renderer.removeAttribute(pageLinkElement, 'aria-disabled');
7155
this.#renderer.removeAttribute(pageLinkElement, 'tabindex');
7256
}
73-
}
57+
});
7458
}
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
<ul [ngClass]="paginationClass">
1+
<ul [ngClass]="paginationClass()">
22
<ng-content />
33
</ul>
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,39 @@
1-
import { Component, HostBinding, Input } from '@angular/core';
1+
import { Component, computed, input } from '@angular/core';
22
import { NgClass } from '@angular/common';
33

44
@Component({
5-
selector: 'c-pagination',
6-
templateUrl: './pagination.component.html',
7-
imports: [NgClass]
5+
selector: 'c-pagination',
6+
templateUrl: './pagination.component.html',
7+
imports: [NgClass],
8+
host: {
9+
'[attr.role]': 'role()'
10+
}
811
})
912
export class PaginationComponent {
10-
1113
/**
1214
* Set the alignment of pagination components.
1315
* @values 'start', 'center', 'end'
1416
*/
15-
@Input() align: 'start' | 'center' | 'end' | '' = '';
17+
readonly align = input<'start' | 'center' | 'end' | ''>('');
1618
/**
1719
* Size the component small or large.
1820
* @values 'sm', 'lg'
1921
*/
20-
@Input() size?: 'sm' | 'lg';
22+
readonly size = input<'sm' | 'lg'>();
2123
/**
2224
* Default role for pagination. [docs]
23-
* @type string
25+
* @return string
2426
* @default 'navigation'
2527
*/
26-
@HostBinding('attr.role')
27-
@Input() role = 'navigation';
28+
readonly role = input<string>('navigation');
2829

29-
get paginationClass(): any {
30+
readonly paginationClass = computed(() => {
31+
const size = this.size();
32+
const align = this.align();
3033
return {
3134
pagination: true,
32-
[`pagination-${this.size}`]: !!this.size,
33-
[`justify-content-${this.align}`]: !!this.align
34-
};
35-
}
36-
35+
[`pagination-${size}`]: !!size,
36+
[`justify-content-${align}`]: !!align
37+
} as Record<string, boolean>;
38+
});
3739
}

0 commit comments

Comments
 (0)