-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Angular support for icon table column (#1448)
## π€¨ Rationale Part of #1013 ## π©βπ» Implementation - Created directive, module, and tests for `nimble-table-column-icon`, `nimble-mapping-icon`, and `nimble-mapping-spinner`. - Added icon column to example app. ## π§ͺ Testing Wrote standard tests for Angular directives. ## β Checklist - [x] I have updated the project documentation to reflect my changes or determined no changes are needed.
- Loading branch information
Showing
19 changed files
with
1,275 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 6 additions & 0 deletions
6
angular-workspace/projects/ni/nimble-angular/mapping/icon/ng-package.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"$schema": "../../../../../../node_modules/ng-packagr/ng-package.schema.json", | ||
"lib": { | ||
"entryFile": "public-api.ts" | ||
} | ||
} |
49 changes: 49 additions & 0 deletions
49
angular-workspace/projects/ni/nimble-angular/mapping/icon/nimble-mapping-icon.directive.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { Directive, ElementRef, Input, Renderer2 } from '@angular/core'; | ||
import { type MappingIcon, mappingIconTag } from '@ni/nimble-components/dist/esm/mapping/icon'; | ||
import type { MappingKey } from '@ni/nimble-components/dist/esm/mapping/base/types'; | ||
import type { IconSeverity } from '@ni/nimble-components/dist/esm/icon-base/types'; | ||
|
||
export type { MappingIcon }; | ||
export { mappingIconTag }; | ||
|
||
/** | ||
* Directive to provide Angular integration for the mapping icon element used by the icon column. | ||
*/ | ||
@Directive({ | ||
selector: 'nimble-mapping-icon' | ||
}) | ||
export class NimbleMappingIconDirective { | ||
public get key(): MappingKey | undefined { | ||
return this.elementRef.nativeElement.key; | ||
} | ||
|
||
@Input() public set key(value: MappingKey | undefined) { | ||
this.renderer.setProperty(this.elementRef.nativeElement, 'key', value); | ||
} | ||
|
||
public get text(): string | undefined { | ||
return this.elementRef.nativeElement.text; | ||
} | ||
|
||
@Input() public set text(value: string | undefined) { | ||
this.renderer.setProperty(this.elementRef.nativeElement, 'text', value); | ||
} | ||
|
||
public get icon(): string | undefined { | ||
return this.elementRef.nativeElement.icon; | ||
} | ||
|
||
@Input() public set icon(value: string | undefined) { | ||
this.renderer.setProperty(this.elementRef.nativeElement, 'icon', value); | ||
} | ||
|
||
public get severity(): IconSeverity { | ||
return this.elementRef.nativeElement.severity; | ||
} | ||
|
||
@Input() public set severity(value: IconSeverity) { | ||
this.renderer.setProperty(this.elementRef.nativeElement, 'severity', value); | ||
} | ||
|
||
public constructor(protected readonly renderer: Renderer2, protected readonly elementRef: ElementRef<MappingIcon>) {} | ||
} |
12 changes: 12 additions & 0 deletions
12
angular-workspace/projects/ni/nimble-angular/mapping/icon/nimble-mapping-icon.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { NgModule } from '@angular/core'; | ||
import { CommonModule } from '@angular/common'; | ||
import { NimbleMappingIconDirective } from './nimble-mapping-icon.directive'; | ||
|
||
import '@ni/nimble-components/dist/esm/mapping/icon'; | ||
|
||
@NgModule({ | ||
declarations: [NimbleMappingIconDirective], | ||
imports: [CommonModule], | ||
exports: [NimbleMappingIconDirective] | ||
}) | ||
export class NimbleMappingIconModule { } |
2 changes: 2 additions & 0 deletions
2
angular-workspace/projects/ni/nimble-angular/mapping/icon/public-api.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './nimble-mapping-icon.directive'; | ||
export * from './nimble-mapping-icon.module'; |
251 changes: 251 additions & 0 deletions
251
...space/projects/ni/nimble-angular/mapping/icon/tests/nimble-mapping-icon.directive.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,251 @@ | ||
import { Component, ElementRef, ViewChild } from '@angular/core'; | ||
import { ComponentFixture, TestBed } from '@angular/core/testing'; | ||
import { IconSeverity } from '@ni/nimble-angular'; | ||
import { NimbleTableModule } from '../../../table/nimble-table.module'; | ||
import { NimbleTableColumnIconModule } from '../../../table-column/icon/nimble-table-column-icon.module'; | ||
import { NimbleMappingIconDirective, type MappingIcon } from '../nimble-mapping-icon.directive'; | ||
import { NimbleMappingIconModule } from '../nimble-mapping-icon.module'; | ||
|
||
describe('NimbleMappingIcon', () => { | ||
describe('module', () => { | ||
beforeEach(() => { | ||
TestBed.configureTestingModule({ | ||
imports: [NimbleMappingIconModule] | ||
}); | ||
}); | ||
|
||
it('custom element is defined', () => { | ||
expect(customElements.get('nimble-mapping-text')).not.toBeUndefined(); | ||
}); | ||
}); | ||
|
||
describe('with template string values', () => { | ||
@Component({ | ||
template: ` | ||
<nimble-table> | ||
<nimble-table-column-icon key-type="boolean"> | ||
<nimble-mapping-icon | ||
#mapping | ||
key="false" | ||
text="nope" | ||
icon="nimble-icon-xmark" | ||
severity="error" | ||
> | ||
</nimble-mapping-icon> | ||
</nimble-table-column-icon> | ||
</nimble-table> | ||
` | ||
}) | ||
class TestHostComponent { | ||
@ViewChild('mapping', { read: NimbleMappingIconDirective }) public directive: NimbleMappingIconDirective; | ||
@ViewChild('mapping', { read: ElementRef }) public elementRef: ElementRef<MappingIcon>; | ||
} | ||
|
||
let fixture: ComponentFixture<TestHostComponent>; | ||
let directive: NimbleMappingIconDirective; | ||
let nativeElement: MappingIcon; | ||
beforeEach(() => { | ||
TestBed.configureTestingModule({ | ||
declarations: [TestHostComponent], | ||
imports: [NimbleMappingIconModule, NimbleTableColumnIconModule, NimbleTableModule] | ||
}); | ||
|
||
fixture = TestBed.createComponent(TestHostComponent); | ||
fixture.detectChanges(); | ||
directive = fixture.componentInstance.directive; | ||
nativeElement = fixture.componentInstance.elementRef.nativeElement; | ||
}); | ||
|
||
it('will use template string values for key', () => { | ||
expect(directive.key).toBe('false'); | ||
expect(nativeElement.key).toBe('false'); | ||
}); | ||
|
||
it('will use template string values for text', () => { | ||
expect(directive.text).toBe('nope'); | ||
expect(nativeElement.text).toBe('nope'); | ||
}); | ||
|
||
it('will use template string values for icon', () => { | ||
expect(directive.icon).toBe('nimble-icon-xmark'); | ||
expect(nativeElement.icon).toBe('nimble-icon-xmark'); | ||
}); | ||
|
||
it('will use template string values for severity', () => { | ||
expect(directive.severity).toBe('error'); | ||
expect(nativeElement.severity).toBe('error'); | ||
}); | ||
}); | ||
|
||
describe('with property bound values', () => { | ||
@Component({ | ||
template: ` | ||
<nimble-table> | ||
<nimble-table-column-icon key-type="boolean"> | ||
<nimble-mapping-icon | ||
#mapping | ||
[key]="key" | ||
[text]="text" | ||
[icon]="icon" | ||
[severity]="severity" | ||
> | ||
</nimble-mapping-icon> | ||
</nimble-table-column-icon> | ||
</nimble-table> | ||
` | ||
}) | ||
class TestHostComponent { | ||
@ViewChild('mapping', { read: NimbleMappingIconDirective }) public directive: NimbleMappingIconDirective; | ||
@ViewChild('mapping', { read: ElementRef }) public elementRef: ElementRef<MappingIcon>; | ||
public key = false; | ||
public text = 'nope'; | ||
public icon = 'nimble-icon-xmark'; | ||
public severity: IconSeverity = IconSeverity.error; | ||
} | ||
|
||
let fixture: ComponentFixture<TestHostComponent>; | ||
let directive: NimbleMappingIconDirective; | ||
let nativeElement: MappingIcon; | ||
beforeEach(() => { | ||
TestBed.configureTestingModule({ | ||
declarations: [TestHostComponent], | ||
imports: [NimbleMappingIconModule, NimbleTableColumnIconModule, NimbleTableModule] | ||
}); | ||
|
||
fixture = TestBed.createComponent(TestHostComponent); | ||
fixture.detectChanges(); | ||
directive = fixture.componentInstance.directive; | ||
nativeElement = fixture.componentInstance.elementRef.nativeElement; | ||
}); | ||
|
||
it('can be configured with property binding for key', () => { | ||
expect(directive.key).toBeFalse(); | ||
expect(nativeElement.key).toBeFalse(); | ||
|
||
fixture.componentInstance.key = true; | ||
fixture.detectChanges(); | ||
|
||
expect(directive.key).toBeTrue(); | ||
expect(nativeElement.key).toBeTrue(); | ||
}); | ||
|
||
it('can be configured with property binding for text', () => { | ||
expect(directive.text).toBe('nope'); | ||
expect(nativeElement.text).toBe('nope'); | ||
|
||
fixture.componentInstance.text = 'yep'; | ||
fixture.detectChanges(); | ||
|
||
expect(directive.text).toBe('yep'); | ||
expect(nativeElement.text).toBe('yep'); | ||
}); | ||
|
||
it('can be configured with property binding for icon', () => { | ||
expect(directive.icon).toBe('nimble-icon-xmark'); | ||
expect(nativeElement.icon).toBe('nimble-icon-xmark'); | ||
|
||
fixture.componentInstance.icon = 'nimble-icon-check'; | ||
fixture.detectChanges(); | ||
|
||
expect(directive.icon).toBe('nimble-icon-check'); | ||
expect(nativeElement.icon).toBe('nimble-icon-check'); | ||
}); | ||
|
||
it('can be configured with property binding for severity', () => { | ||
expect(directive.severity).toBe('error'); | ||
expect(nativeElement.severity).toBe('error'); | ||
|
||
fixture.componentInstance.severity = IconSeverity.success; | ||
fixture.detectChanges(); | ||
|
||
expect(directive.severity).toBe('success'); | ||
expect(nativeElement.severity).toBe('success'); | ||
}); | ||
}); | ||
|
||
describe('with attribute bound values', () => { | ||
@Component({ | ||
template: ` | ||
<nimble-table> | ||
<nimble-table-column-icon key-type="boolean"> | ||
<nimble-mapping-icon | ||
#mapping | ||
[attr.key]="key" | ||
[attr.text]="text" | ||
[attr.icon]="icon" | ||
[attr.severity]="severity" | ||
> | ||
</nimble-mapping-icon> | ||
</nimble-table-column-icon> | ||
</nimble-table> | ||
` | ||
}) | ||
class TestHostComponent { | ||
@ViewChild('mapping', { read: NimbleMappingIconDirective }) public directive: NimbleMappingIconDirective; | ||
@ViewChild('mapping', { read: ElementRef }) public elementRef: ElementRef<MappingIcon>; | ||
public key = false; | ||
public text = 'nope'; | ||
public icon = 'nimble-icon-xmark'; | ||
public severity: IconSeverity = IconSeverity.error; | ||
} | ||
|
||
let fixture: ComponentFixture<TestHostComponent>; | ||
let directive: NimbleMappingIconDirective; | ||
let nativeElement: MappingIcon; | ||
beforeEach(() => { | ||
TestBed.configureTestingModule({ | ||
declarations: [TestHostComponent], | ||
imports: [NimbleMappingIconModule, NimbleTableColumnIconModule, NimbleTableModule] | ||
}); | ||
|
||
fixture = TestBed.createComponent(TestHostComponent); | ||
fixture.detectChanges(); | ||
directive = fixture.componentInstance.directive; | ||
nativeElement = fixture.componentInstance.elementRef.nativeElement; | ||
}); | ||
|
||
it('can be configured with attribute binding for key', () => { | ||
expect(directive.key).toBe('false'); | ||
expect(nativeElement.key).toBe('false'); | ||
|
||
fixture.componentInstance.key = true; | ||
fixture.detectChanges(); | ||
|
||
expect(directive.key).toBe('true'); | ||
expect(nativeElement.key).toBe('true'); | ||
}); | ||
|
||
it('can be configured with attribute binding for text', () => { | ||
expect(directive.text).toBe('nope'); | ||
expect(nativeElement.text).toBe('nope'); | ||
|
||
fixture.componentInstance.text = 'yep'; | ||
fixture.detectChanges(); | ||
|
||
expect(directive.text).toBe('yep'); | ||
expect(nativeElement.text).toBe('yep'); | ||
}); | ||
|
||
it('can be configured with property binding for icon', () => { | ||
expect(directive.icon).toBe('nimble-icon-xmark'); | ||
expect(nativeElement.icon).toBe('nimble-icon-xmark'); | ||
|
||
fixture.componentInstance.icon = 'nimble-icon-check'; | ||
fixture.detectChanges(); | ||
|
||
expect(directive.icon).toBe('nimble-icon-check'); | ||
expect(nativeElement.icon).toBe('nimble-icon-check'); | ||
}); | ||
|
||
it('can be configured with property binding for severity', () => { | ||
expect(directive.severity).toBe('error'); | ||
expect(nativeElement.severity).toBe('error'); | ||
|
||
fixture.componentInstance.severity = IconSeverity.success; | ||
fixture.detectChanges(); | ||
|
||
expect(directive.severity).toBe('success'); | ||
expect(nativeElement.severity).toBe('success'); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.