Skip to content

Commit 44112b7

Browse files
authored
feat(design): convert modal component to standalone (#3131)
1 parent 1a0d1f5 commit 44112b7

23 files changed

+285
-94
lines changed

apps/design-land/src/app/modal/modal.component.spec.ts

+2-5
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ import {
44
TestBed,
55
} from '@angular/core/testing';
66

7-
import { DaffModalModule } from '@daffodil/design/modal';
8-
97
import { DesignLandModalComponent } from './modal.component';
108

119
describe('DesignLandModalComponent', () => {
@@ -14,9 +12,8 @@ describe('DesignLandModalComponent', () => {
1412

1513
beforeEach(waitForAsync(() => {
1614
TestBed.configureTestingModule({
17-
declarations: [ DesignLandModalComponent ],
18-
imports: [
19-
DaffModalModule,
15+
declarations: [
16+
DesignLandModalComponent,
2017
],
2118
})
2219
.compileComponents();

libs/design/modal/README.md

+41
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,47 @@ Modal is a dynamically rendered element that floats above the rest of a page's c
44
## Basic Modal
55
<design-land-example-viewer-container example="basic-modal"></design-land-example-viewer-container>
66

7+
## Usage
8+
9+
### Within a standalone component
10+
To use modal in a standalone component, import `DAFF_MODAL_COMPONENTS` directly into your custom component:
11+
12+
```ts
13+
@Component({
14+
selector: 'custom-component',
15+
templateUrl: './custom-component.component.html',
16+
standalone: true,
17+
imports: [
18+
DAFF_MODAL_COMPONENTS,
19+
],
20+
})
21+
export class CustomComponent {}
22+
```
23+
24+
### Within a module (deprecated)
25+
To use modal in a module, import `DaffModalModule` into your custom module:
26+
27+
```ts
28+
import { NgModule } from '@angular/core';
29+
30+
import { DaffModalModule } from '@daffodil/design/modal';
31+
32+
@NgModule({
33+
declarations: [
34+
CustomComponent,
35+
],
36+
exports: [
37+
CustomComponent,
38+
],
39+
imports: [
40+
DaffModalModule,
41+
],
42+
})
43+
export class CustomComponentModule { }
44+
```
45+
46+
> This method is deprecated. It's recommended to update all custom components to standalone.
47+
748
## Supported Content Types
849
A modal includes minimally pre-styled components and directives to help structure the content in your modal.
950

libs/design/modal/examples/src/basic-modal/basic-modal.component.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
import { DAFF_BUTTON_COMPONENTS } from '@daffodil/design/button';
77
import {
88
DaffModalComponent,
9-
DaffModalModule,
9+
DAFF_MODAL_COMPONENTS,
1010
DaffModalService,
1111
} from '@daffodil/design/modal';
1212

@@ -20,7 +20,10 @@ import { BasicModalContentComponent } from './modal-content.component';
2020
standalone: true,
2121
imports: [
2222
DAFF_BUTTON_COMPONENTS,
23-
DaffModalModule,
23+
DAFF_MODAL_COMPONENTS,
24+
],
25+
providers: [
26+
DaffModalService,
2427
],
2528
})
2629
export class BasicModalComponent {

libs/design/modal/examples/src/basic-modal/modal-content.component.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,19 @@ import {
33
Component,
44
} from '@angular/core';
55

6-
import { DaffButtonModule } from '@daffodil/design/button';
7-
import { DaffModalModule } from '@daffodil/design/modal';
6+
import { DAFF_BUTTON_COMPONENTS } from '@daffodil/design/button';
7+
import { DAFF_MODAL_COMPONENTS } from '@daffodil/design/modal';
88

99
@Component({
1010
// eslint-disable-next-line @angular-eslint/component-selector
1111
selector: 'basic-modal-content',
1212
templateUrl: './modal-content.component.html',
1313
changeDetection: ChangeDetectionStrategy.OnPush,
1414
standalone: true,
15-
imports: [DaffModalModule, DaffButtonModule],
15+
imports: [
16+
DAFF_MODAL_COMPONENTS,
17+
DAFF_BUTTON_COMPONENTS,
18+
],
1619
})
1720
export class BasicModalContentComponent {
1821

Original file line numberDiff line numberDiff line change
@@ -1,31 +1,61 @@
1+
import {
2+
Component,
3+
DebugElement,
4+
} from '@angular/core';
15
import {
26
waitForAsync,
37
ComponentFixture,
48
TestBed,
59
} from '@angular/core/testing';
10+
import { By } from '@angular/platform-browser';
611

712
import { DaffModalActionsComponent } from './modal-actions.component';
813

14+
@Component({
15+
template: `
16+
<daff-modal-actions>
17+
<button>Close</button>
18+
<button>Save</button>
19+
</daff-modal-actions>
20+
`,
21+
standalone: true,
22+
imports: [
23+
DaffModalActionsComponent,
24+
],
25+
})
26+
class WrapperComponent {}
27+
928
describe('@daffodil/design/modal | DaffModalActionsComponent', () => {
29+
let wrapper: WrapperComponent;
30+
let fixture: ComponentFixture<WrapperComponent>;
1031
let component: DaffModalActionsComponent;
11-
let fixture: ComponentFixture<DaffModalActionsComponent>;
32+
let de: DebugElement;
1233

1334
beforeEach(waitForAsync(() => {
1435
TestBed.configureTestingModule({
15-
declarations: [
16-
DaffModalActionsComponent,
36+
imports: [
37+
WrapperComponent,
1738
],
1839
})
1940
.compileComponents();
2041
}));
2142

2243
beforeEach(() => {
23-
fixture = TestBed.createComponent(DaffModalActionsComponent);
24-
component = fixture.componentInstance;
44+
fixture = TestBed.createComponent(WrapperComponent);
45+
wrapper = fixture.componentInstance;
46+
47+
de = fixture.debugElement.query(By.css('daff-modal-actions'));
48+
component = de.componentInstance;
2549
fixture.detectChanges();
2650
});
2751

2852
it('should create', () => {
29-
expect(component).toBeTruthy();
53+
expect(wrapper).toBeTruthy();
54+
});
55+
56+
it('should add a class of "daff-modal-actions" to the host element', () => {
57+
expect(de.classes).toEqual(jasmine.objectContaining({
58+
'daff-modal-actions': true,
59+
}));
3060
});
3161
});

libs/design/modal/src/modal-actions/modal-actions.component.ts

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
selector: 'daff-modal-actions',
99
template: '<ng-content></ng-content>',
1010
changeDetection: ChangeDetectionStrategy.OnPush,
11+
standalone: true,
1112
})
1213
export class DaffModalActionsComponent {
1314
@HostBinding('class.daff-modal-actions') class = true;

libs/design/modal/src/modal-close/modal-close.directive.spec.ts

+8-5
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ import { DaffModalService } from '../service/modal.service';
1616
template: `
1717
<button daffModalClose></button>
1818
`,
19+
standalone: true,
20+
imports: [
21+
DaffModalCloseDirective,
22+
],
23+
providers: [
24+
DaffModalService,
25+
],
1926
})
2027
class WrapperComponent {}
2128

@@ -26,13 +33,9 @@ describe('@daffodil/design/modal | DaffModalCloseDirective', () => {
2633

2734
beforeEach(waitForAsync(() => {
2835
TestBed.configureTestingModule({
29-
declarations: [
30-
DaffModalCloseDirective,
36+
imports: [
3137
WrapperComponent,
3238
],
33-
providers: [
34-
DaffModalService,
35-
],
3639
})
3740
.compileComponents();
3841
}));

libs/design/modal/src/modal-close/modal-close.directive.ts

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { DaffModalService } from '../service/modal.service';
1616
*/
1717
@Directive({
1818
selector: 'button[daffModalClose]',
19+
standalone: true,
1920
})
2021

2122
export class DaffModalCloseDirective {
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,60 @@
1+
import {
2+
Component,
3+
DebugElement,
4+
} from '@angular/core';
15
import {
26
waitForAsync,
37
ComponentFixture,
48
TestBed,
59
} from '@angular/core/testing';
10+
import { By } from '@angular/platform-browser';
611

712
import { DaffModalContentComponent } from './modal-content.component';
813

14+
@Component({
15+
template: `
16+
<daff-modal-content>
17+
Content
18+
</daff-modal-content>
19+
`,
20+
standalone: true,
21+
imports: [
22+
DaffModalContentComponent,
23+
],
24+
})
25+
class WrapperComponent {}
26+
927
describe('@daffodil/design/modal | DaffModalContentComponent', () => {
28+
let wrapper: WrapperComponent;
29+
let fixture: ComponentFixture<WrapperComponent>;
1030
let component: DaffModalContentComponent;
11-
let fixture: ComponentFixture<DaffModalContentComponent>;
31+
let de: DebugElement;
1232

1333
beforeEach(waitForAsync(() => {
1434
TestBed.configureTestingModule({
15-
declarations: [
16-
DaffModalContentComponent,
35+
imports: [
36+
WrapperComponent,
1737
],
1838
})
1939
.compileComponents();
2040
}));
2141

2242
beforeEach(() => {
23-
fixture = TestBed.createComponent(DaffModalContentComponent);
24-
component = fixture.componentInstance;
43+
fixture = TestBed.createComponent(WrapperComponent);
44+
wrapper = fixture.componentInstance;
45+
46+
de = fixture.debugElement.query(By.css('daff-modal-content'));
47+
component = de.componentInstance;
2548
fixture.detectChanges();
2649
});
2750

2851
it('should create', () => {
29-
expect(component).toBeTruthy();
52+
expect(wrapper).toBeTruthy();
53+
});
54+
55+
it('should add a class of "daff-modal-content" to the host element', () => {
56+
expect(de.classes).toEqual(jasmine.objectContaining({
57+
'daff-modal-content': true,
58+
}));
3059
});
3160
});

libs/design/modal/src/modal-content/modal-content.component.ts

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
selector: 'daff-modal-content',
99
template: '<ng-content></ng-content>',
1010
changeDetection: ChangeDetectionStrategy.OnPush,
11+
standalone: true,
1112
})
1213
export class DaffModalContentComponent {
1314
@HostBinding('class.daff-modal-content') class = true;

libs/design/modal/src/modal-header/modal-header.component.spec.ts

+17-2
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,17 @@ import {
1010
import { By } from '@angular/platform-browser';
1111

1212
import { DaffModalHeaderComponent } from './modal-header.component';
13+
import { DaffModalService } from '../service/modal.service';
1314

1415
@Component ({
1516
template: `<daff-modal-header [dismissible]="dismissible"></daff-modal-header>`,
17+
standalone: true,
18+
imports: [
19+
DaffModalHeaderComponent,
20+
],
21+
providers: [
22+
DaffModalService,
23+
],
1624
})
1725

1826
class WrapperComponent {
@@ -27,8 +35,7 @@ describe('@daffodil/design/modal | DaffModalHeaderComponent', () => {
2735

2836
beforeEach(waitForAsync(() => {
2937
TestBed.configureTestingModule({
30-
declarations: [
31-
DaffModalHeaderComponent,
38+
imports: [
3239
WrapperComponent,
3340
],
3441
})
@@ -59,5 +66,13 @@ describe('@daffodil/design/modal | DaffModalHeaderComponent', () => {
5966
it('should be set to true by default', () => {
6067
expect(component.dismissible).toBe(true);
6168
});
69+
70+
it('should hide the close button if dismissible is false', () => {
71+
wrapper.dismissible = false;
72+
fixture.detectChanges();
73+
74+
expect(component.dismissible).toBe(false);
75+
expect(fixture.debugElement.query(By.css('.daff-modal-header__dismiss-button'))).toBeFalsy();
76+
});
6277
});
6378
});

libs/design/modal/src/modal-header/modal-header.component.ts

+13
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,30 @@
1+
import { NgIf } from '@angular/common';
12
import {
23
Component,
34
ViewEncapsulation,
45
HostBinding,
56
ChangeDetectionStrategy,
67
Input,
78
} from '@angular/core';
9+
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
810
import { faXmark } from '@fortawesome/free-solid-svg-icons';
911

12+
import { DAFF_BUTTON_COMPONENTS } from '@daffodil/design/button';
13+
14+
import { DaffModalCloseDirective } from '../modal-close/modal-close.directive';
15+
1016
@Component({
1117
selector: 'daff-modal-header',
1218
templateUrl: './modal-header.component.html',
1319
encapsulation: ViewEncapsulation.None,
1420
changeDetection: ChangeDetectionStrategy.OnPush,
21+
standalone: true,
22+
imports: [
23+
NgIf,
24+
DAFF_BUTTON_COMPONENTS,
25+
FaIconComponent,
26+
DaffModalCloseDirective,
27+
],
1528
})
1629
export class DaffModalHeaderComponent {
1730
faXmark = faXmark;

0 commit comments

Comments
 (0)