Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(design)!: change daffStatusMixin to a directive #2941

Merged
merged 1 commit into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 7 additions & 9 deletions libs/design/button/src/button/button.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,17 +207,15 @@ describe('@daffodil/design/button | DaffButtonComponent', () => {
});
});

describe('using the status property of a button', () => {
it('should not set a default status', () => {
expect(component.status).toBeFalsy();
});
it('should take status as an input', () => {
wrapper.status = 'warn';
fixture.detectChanges();

it('should add the class of the defined status to the host element', () => {
wrapper.status = 'warn';
fixture.detectChanges();
expect(de.nativeElement.classList.contains('daff-warn')).toEqual(true);
});

expect(de.nativeElement.classList.contains('daff-warn')).toEqual(true);
});
it('should not set a default status', () => {
expect(component.status).toBeFalsy();
});

describe('using the tabindex property of a button', () => {
Expand Down
13 changes: 8 additions & 5 deletions libs/design/button/src/button/button.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@ import {
DaffSuffixable,
daffPrefixableMixin,
daffSuffixableMixin,
DaffStatusable,
daffStatusMixin,
DaffArticleEncapsulatedDirective,
DaffStatusableDirective,
} from '@daffodil/design';

import { DaffButtonSizableDirective } from './button-sizable.directive';
Expand All @@ -43,7 +42,7 @@ class DaffButtonBase{
constructor(public _elementRef: ElementRef, public _renderer: Renderer2) {}
}

const _daffButtonBase = daffPrefixableMixin(daffSuffixableMixin(daffColorMixin(daffStatusMixin((DaffButtonBase)))));
const _daffButtonBase = daffPrefixableMixin(daffSuffixableMixin(daffColorMixin((DaffButtonBase))));

export type DaffButtonType = 'daff-button' | 'daff-stroked-button' | 'daff-raised-button' | 'daff-flat-button' | 'daff-icon-button' | 'daff-underline-button' | undefined;

Expand Down Expand Up @@ -78,20 +77,24 @@ enum DaffButtonTypeEnum {
styleUrls: ['./button.component.scss'],
//todo(damienwebdev): remove once decorators hit stage 3 - https://github.com/microsoft/TypeScript/issues/7342
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: ['color', 'status'],
inputs: ['color'],
hostDirectives: [
{ directive: DaffArticleEncapsulatedDirective },
{
directive: DaffButtonSizableDirective,
inputs: ['size'],
},
{
directive: DaffStatusableDirective,
inputs: ['status'],
},
],
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class DaffButtonComponent
extends _daffButtonBase
implements OnInit, DaffPrefixable, DaffSuffixable, DaffColorable, DaffStatusable {
implements OnInit, DaffPrefixable, DaffSuffixable, DaffColorable {

private buttonType: DaffButtonType;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<daff-notification [status]="statusControl.value">
<fa-icon *ngIf="statusControl.value === 'success'" daffPrefix [icon]="faCheck" [fixedWidth]="true"></fa-icon>
<fa-icon *ngIf="statusControl.value === 'warn'" daffPrefix [icon]="faExclamation" [fixedWidth]="true"></fa-icon>
<fa-icon *ngIf="statusControl.value === 'error'" daffPrefix [icon]="faExclamation" [fixedWidth]="true"></fa-icon>
<fa-icon *ngIf="statusControl.value === 'danger'" daffPrefix [icon]="faExclamation" [fixedWidth]="true"></fa-icon>
<div daffNotificationTitle>Title</div>
<div daffNotificationSubtitle>This is the subtitle with information</div>
</daff-notification>

<select [formControl]="statusControl">
<option value="success">Success</option>
<option value="warn">Warn</option>
<option value="error">Error</option>
<option value="danger">Danger</option>
</select>
2 changes: 1 addition & 1 deletion libs/design/notification/src/notification-theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
}
}

&.daff-error {
&.daff-danger {
background: theming.daff-color(theming.$daff-red, 10);
border: 1px solid theming.daff-color(theming.$daff-red, 20);
color: theming.daff-text-contrast(theming.daff-color(theming.$daff-red, 10));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import {
Component,
ContentChild,
DebugElement,
Input,
ViewChild,
} from '@angular/core';
import {
waitForAsync,
Expand All @@ -18,7 +15,6 @@ import {
DaffNotificationComponent,
DaffNotificationOrientation,
} from './notification.component';
import { DaffNotificationActionsDirective } from '../notification-actions/notification-actions.directive';

@Component ({
template: `
Expand Down Expand Up @@ -133,17 +129,11 @@ describe('@daffodil/design/notification | DaffNotificationComponent', () => {
});
});

describe('using the status property of a notification', () => {
it('should not set a default status', () => {
expect(component.status).toBeFalsy();
});

it('should add the class of the defined status to the host element', () => {
wrapper.status = 'warn';
fixture.detectChanges();
it('should take status as an input', () => {
wrapper.status = 'warn';
fixture.detectChanges();

expect(de.nativeElement.classList.contains('daff-warn')).toEqual(true);
});
expect(de.nativeElement.classList.contains('daff-warn')).toEqual(true);
});

describe('setting the orientation of a notification', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,12 @@ import {
DaffArticleEncapsulatedDirective,
DaffPrefixable,
DaffPrefixDirective,
DaffStatusable,
DaffStatusableDirective,
DaffStatusEnum,
daffStatusMixin,
} from '@daffodil/design';

import { DaffNotificationActionsDirective } from '../notification-actions/notification-actions.directive';

/**
* An _elementRef is needed for the core mixins
*/
class DaffNotificationBase {
constructor(public _elementRef: ElementRef, public _renderer: Renderer2) {}
}

const _daffNotificationBase = daffStatusMixin(DaffNotificationBase);

export type DaffNotificationOrientation = 'horizontal' | 'vertical';

enum DaffNotificationOrientationEnum {
Expand All @@ -47,18 +37,17 @@ enum DaffNotificationOrientationEnum {
selector: 'daff-notification',
templateUrl: './notification.component.html',
styleUrls: ['./notification.component.scss'],
// todo(damienwebdev): remove once decorators hit stage 3 - https://github.com/microsoft/TypeScript/issues/7342
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: ['status'],
hostDirectives: [{
directive: DaffArticleEncapsulatedDirective,
}],
hostDirectives: [
{ directive: DaffArticleEncapsulatedDirective },
{
directive: DaffStatusableDirective,
inputs: ['status'],
},
],
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class DaffNotificationComponent
extends _daffNotificationBase
implements DaffPrefixable, DaffStatusable {
export class DaffNotificationComponent implements DaffPrefixable {
faTimes = faTimes;

@ContentChild(DaffPrefixDirective) _prefix: DaffPrefixDirective;
Expand All @@ -74,7 +63,7 @@ export class DaffNotificationComponent
* Sets role to status on all other instances.
*/
@HostBinding('attr.role') get role() {
return this.status === DaffStatusEnum.Warn || this.status === DaffStatusEnum.Danger ? 'alert' : 'status';
return this.statusDirective.status === DaffStatusEnum.Warn || this.statusDirective.status === DaffStatusEnum.Danger ? 'alert' : 'status';
};

@HostBinding('class.vertical') get verticalOrientation() {
Expand All @@ -88,6 +77,8 @@ export class DaffNotificationComponent
/** Whether or not a notification is closable */
@Input() @HostBinding('class.dismissible') dismissible = false;

constructor(private statusDirective: DaffStatusableDirective) {}

private _orientation: DaffNotificationOrientation = DaffNotificationOrientationEnum.Vertical;

@Input()
Expand All @@ -103,13 +94,6 @@ export class DaffNotificationComponent
}
};

constructor(
private elementRef: ElementRef,
private renderer: Renderer2,
) {
super(elementRef, renderer);
}

/**
* Output event triggered when the close icon is clicked.
*/
Expand Down
2 changes: 1 addition & 1 deletion libs/design/src/core/statusable/public_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ export {
DaffStatus,
DaffStatusEnum,
} from './statusable';
export { daffStatusMixin } from './statusable-mixin';
export { DaffStatusableDirective } from './statusable.directive';
55 changes: 0 additions & 55 deletions libs/design/src/core/statusable/statusable-mixin.ts

This file was deleted.

86 changes: 86 additions & 0 deletions libs/design/src/core/statusable/statusable.directive.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import {
Component,
DebugElement,
} from '@angular/core';
import {
waitForAsync,
ComponentFixture,
TestBed,
} from '@angular/core/testing';
import { By } from '@angular/platform-browser';

import { DaffStatus } from './statusable';
import { DaffStatusableDirective } from './statusable.directive';

@Component({
template: `
<div daffStatusable [status]="status"></div>`,
})

class WrapperComponent {
status: DaffStatus;
}

describe('@daffodil/design | DaffStatusableDirective', () => {
let wrapper: WrapperComponent;
let de: DebugElement;
let fixture: ComponentFixture<WrapperComponent>;
let directive: DaffStatusableDirective;

beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [
WrapperComponent,
],
imports: [
DaffStatusableDirective,
],
})
.compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(WrapperComponent);
wrapper = fixture.componentInstance;
de = fixture.debugElement.query(By.css('[daffStatusable]'));

directive = de.injector.get(DaffStatusableDirective);
fixture.detectChanges();
});

it('should create', () => {
expect(wrapper).toBeTruthy();
expect(directive).toBeTruthy();
});

it('should take status as an input', () => {
expect(directive.status).toEqual(wrapper.status);
});

it('should add a class of .daff-warn to the host element if status is set to warn', () => {
wrapper.status = 'warn';
fixture.detectChanges();

expect(directive.class).toEqual(jasmine.objectContaining({
'daff-warn': true,
}));
});

it('should add a class of .daff-danger to the host element if status is set to danger', () => {
wrapper.status = 'danger';
fixture.detectChanges();

expect(directive.class).toEqual(jasmine.objectContaining({
'daff-danger': true,
}));
});

it('should add a class of .daff-success to the host element if status is set to success', () => {
wrapper.status = 'success';
fixture.detectChanges();

expect(directive.class).toEqual(jasmine.objectContaining({
'daff-success': true,
}));
});
});
Loading
Loading