Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 1675bd7

Browse filesBrowse files
committed
refactor(table): signal inputs, host bindings, cleanup, tests
1 parent 994ecc3 commit 1675bd7
Copy full SHA for 1675bd7

File tree

Expand file treeCollapse file tree

2 files changed

+152
-50
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+152
-50
lines changed
+95-3Lines changed: 95 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,113 @@
1-
import { TestBed } from '@angular/core/testing';
2-
import { ElementRef, Renderer2 } from '@angular/core';
1+
import { Component, DebugElement, ElementRef, Renderer2 } from '@angular/core';
2+
import { ComponentFixture, TestBed } from '@angular/core/testing';
3+
import { By } from '@angular/platform-browser';
34

45
import { TableDirective } from './table.directive';
6+
import { Colors } from '../coreui.types';
7+
import { TableActiveDirective } from './table-active.directive';
8+
9+
@Component({
10+
template: `
11+
<table
12+
cTable
13+
[align]="align"
14+
[borderColor]="borderColor"
15+
[bordered]="bordered"
16+
[borderless]="borderless"
17+
[caption]="caption"
18+
[color]="color"
19+
[hover]="hover"
20+
[small]="small"
21+
[striped]="striped"
22+
[stripedColumns]="stripedColumns"
23+
[responsive]="true"
24+
></table>
25+
`,
26+
imports: [TableDirective]
27+
})
28+
class TestComponent {
29+
align: 'bottom' | 'middle' | 'top' = 'middle';
30+
borderColor: Colors = 'primary';
31+
bordered: boolean = true;
32+
borderless: boolean = false;
33+
caption = 'top' as const;
34+
color: Colors = 'secondary';
35+
hover: boolean = true;
36+
small: boolean = true;
37+
striped: boolean = true;
38+
stripedColumns: boolean = true;
39+
}
540

641
class MockElementRef extends ElementRef {}
742

843
describe('TableDirective', () => {
44+
let component: TestComponent;
45+
let fixture: ComponentFixture<TestComponent>;
46+
let debugElement: DebugElement;
47+
let directive: TableDirective;
48+
949
beforeEach(() => {
1050
TestBed.configureTestingModule({
51+
imports: [TestComponent],
1152
providers: [Renderer2, { provide: ElementRef, useClass: MockElementRef }]
1253
});
54+
fixture = TestBed.createComponent(TestComponent);
55+
debugElement = fixture.debugElement.query(By.directive(TableDirective));
56+
directive = debugElement.injector.get(TableDirective);
57+
component = fixture.componentInstance;
58+
fixture.detectChanges();
1359
});
1460

1561
it('should create an instance', () => {
62+
expect(directive).toBeTruthy();
1663
TestBed.runInInjectionContext(() => {
17-
const directive = new TableDirective();
64+
const directive = new TableActiveDirective();
1865
expect(directive).toBeTruthy();
1966
});
2067
});
68+
69+
it('should apply align input', () => {
70+
expect(directive.align()).toBe('middle');
71+
});
72+
73+
it('should apply borderColor input', () => {
74+
expect(directive.borderColor()).toBe('primary');
75+
});
76+
77+
it('should apply bordered input', () => {
78+
expect(directive.bordered()).toBe(true);
79+
});
80+
81+
it('should apply borderless input', () => {
82+
expect(directive.borderless()).toBe(false);
83+
});
84+
85+
it('should apply caption input', () => {
86+
expect(directive.caption()).toBe('top');
87+
});
88+
89+
it('should apply color input', () => {
90+
expect(directive.color()).toBe('secondary');
91+
});
92+
93+
it('should have responsive wrapper', () => {
94+
const parentElement = debugElement.nativeElement.parentElement;
95+
const classes = parentElement.classList;
96+
expect(classes).toContain('table-responsive');
97+
});
98+
99+
it('should apply correct host classes', () => {
100+
const classes = debugElement.nativeElement.classList;
101+
102+
expect(classes).toContain('table');
103+
expect(classes).toContain('align-middle');
104+
expect(classes).toContain('caption-top');
105+
expect(classes).toContain('border-primary');
106+
expect(classes).toContain('table-bordered');
107+
expect(classes).toContain('table-secondary');
108+
expect(classes).toContain('table-hover');
109+
expect(classes).toContain('table-sm');
110+
expect(classes).toContain('table-striped');
111+
expect(classes).toContain('table-striped-columns');
112+
});
21113
});
+57-47Lines changed: 57 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,115 +1,125 @@
1-
import { booleanAttribute, Directive, ElementRef, HostBinding, inject, Input, OnInit, Renderer2 } from '@angular/core';
1+
import { booleanAttribute, computed, Directive, effect, ElementRef, inject, input, Renderer2 } from '@angular/core';
22
import { Breakpoints, Colors } from '../coreui.types';
3-
import { ITable } from './table.type';
43

54
@Directive({
65
selector: 'table[cTable]',
7-
host: { class: 'table' }
6+
exportAs: 'cTable',
7+
host: {
8+
class: 'table',
9+
'[class]': 'hostClasses()'
10+
}
811
})
9-
export class TableDirective implements ITable, OnInit {
12+
export class TableDirective {
1013
readonly #renderer = inject(Renderer2);
1114
readonly #hostElement = inject(ElementRef);
1215

1316
/**
1417
* Set the vertical alignment.
15-
* @type string
18+
* @return string
1619
* @values 'bottom' | 'middle' | 'top'
1720
*/
18-
@Input() align?: 'bottom' | 'middle' | 'top';
21+
readonly align = input<'bottom' | 'middle' | 'top'>();
1922

2023
/**
2124
* Sets the border color of the component to one of CoreUI’s themed colors.
22-
* @type Colors
25+
* @return Colors
2326
*/
24-
@Input() borderColor?: Colors;
27+
readonly borderColor = input<Colors>();
2528

2629
/**
2730
* Add borders on all sides of the table and cells.
28-
* @type boolean
31+
* @return boolean
2932
*/
30-
@Input({ transform: booleanAttribute }) bordered: string | boolean = false;
33+
readonly bordered = input(false, { transform: booleanAttribute });
3134

3235
/**
3336
* Remove borders on all sides of the table and cells.
34-
* @type boolean
37+
* @return boolean
3538
*/
36-
@Input({ transform: booleanAttribute }) borderless: string | boolean = false;
39+
readonly borderless = input(false, { transform: booleanAttribute });
3740

3841
/**
3942
* Put the `<caption>` on the top of the table.
43+
* @return 'top'
4044
* @values 'top'
4145
*/
42-
@Input() caption?: 'top';
46+
readonly caption = input<'top'>();
4347

4448
/**
4549
* Sets the color context of the component to one of CoreUI’s themed colors.
46-
* @type Colors
50+
* @return Colors
4751
*/
48-
@Input() color?: Colors;
52+
readonly color = input<Colors>();
4953

5054
/**
5155
* Enable a hover state on table rows within table body.
52-
* @type boolean
56+
* @return boolean
5357
*/
54-
@Input({ transform: booleanAttribute }) hover: string | boolean = false;
58+
readonly hover = input(false, { transform: booleanAttribute });
5559

5660
/**
5761
* Make table responsive across all viewports or pick a maximum breakpoint with which to have a responsive table up to.
58-
* @type: {boolean | 'sm' | 'md' | 'lg' | 'xl' | 'xxl'}
62+
* @values: {boolean | 'sm' | 'md' | 'lg' | 'xl' | 'xxl'}
5963
*/
60-
@Input() responsive?: boolean | Omit<Breakpoints, 'xs'>;
64+
readonly responsive = input<boolean | Omit<Breakpoints, 'xs'>>();
6165

6266
/**
6367
* Make table more compact by cutting all cell `padding` in half.
64-
* @type boolean
68+
* @return boolean
6569
*/
66-
@Input({ transform: booleanAttribute }) small: string | boolean = false;
70+
readonly small = input(false, { transform: booleanAttribute });
6771

6872
/**
6973
* Add zebra-striping to any table row within the table body.
70-
* @type boolean
74+
* @return boolean
7175
*/
72-
@Input({ transform: booleanAttribute }) striped: string | boolean = false;
76+
readonly striped = input(false, { transform: booleanAttribute });
7377

7478
/**
7579
* Add zebra-striping to any table column.
76-
* @type boolean
80+
* @return boolean
7781
* @since 4.2.4
7882
*/
79-
@Input({ transform: booleanAttribute }) stripedColumns: string | boolean = false;
83+
readonly stripedColumns = input(false, { transform: booleanAttribute });
84+
85+
readonly hostClasses = computed(() => {
86+
const align = this.align();
87+
const caption = this.caption();
88+
const borderColor = this.borderColor();
89+
const bordered = this.bordered();
90+
const borderless = this.borderless();
91+
const color = this.color();
92+
const hover = this.hover();
93+
const small = this.small();
94+
const striped = this.striped();
95+
const stripedColumns = this.stripedColumns();
8096

81-
@HostBinding('class')
82-
get hostClasses(): any {
8397
return {
8498
table: true,
85-
[`align-${this.align}`]: !!this.align,
86-
[`caption-${this.caption}`]: !!this.caption,
87-
[`border-${this.borderColor}`]: !!this.borderColor,
88-
'table-bordered': this.bordered,
89-
'table-borderless': this.borderless,
90-
[`table-${this.color}`]: !!this.color,
91-
'table-hover': this.hover,
92-
'table-sm': this.small,
93-
'table-striped': this.striped,
94-
'table-striped-columns': this.stripedColumns
99+
[`align-${align}`]: !!align,
100+
[`caption-${caption}`]: !!caption,
101+
[`border-${borderColor}`]: !!borderColor,
102+
'table-bordered': bordered,
103+
'table-borderless': borderless,
104+
[`table-${color}`]: !!color,
105+
'table-hover': hover,
106+
'table-sm': small,
107+
'table-striped': striped,
108+
'table-striped-columns': stripedColumns
95109
};
96-
}
110+
});
97111

98-
ngOnInit(): void {
99-
this.setResponsiveWrapper();
100-
}
101-
102-
// todo
103-
setResponsiveWrapper(): void {
104-
if (!!this.responsive) {
112+
readonly #responsiveWrapperEffect = effect(() => {
113+
const responsive = this.responsive();
114+
if (!!responsive) {
105115
const nativeElement: HTMLElement = this.#hostElement.nativeElement;
106116
const wrapper = this.#renderer.createElement('div');
107-
const className = this.responsive === true ? 'table-responsive' : `table-responsive-${this.responsive}`;
117+
const className = responsive === true ? 'table-responsive' : `table-responsive-${responsive}`;
108118
this.#renderer.addClass(wrapper, className);
109119
const parentNode = this.#renderer.parentNode(nativeElement);
110120
this.#renderer.appendChild(parentNode, wrapper);
111121
this.#renderer.insertBefore(parentNode, wrapper, nativeElement);
112122
this.#renderer.appendChild(wrapper, nativeElement);
113123
}
114-
}
124+
});
115125
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.