Skip to content

Commit

Permalink
feat(modal): add new input to handle overlay click
Browse files Browse the repository at this point in the history
(cherry picked from commit eb4b4dd)
  • Loading branch information
elenagarrone committed Dec 18, 2024
1 parent 4fca5a7 commit e3cad52
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 31 deletions.
30 changes: 15 additions & 15 deletions projects/canopy-test-app/src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -513,20 +513,20 @@ <h3>Carousel item 3</h3>
<button lg-button type="submit" variant="primary-dark">Submit</button>
</form>

<!-- <lg-separator></lg-separator>-->
<!-- <lg-heading level="3">Modal</lg-heading>-->

<!-- <button lgModalTrigger="modal" lg-button type="button" variant="secondary-dark">Open modal</button>-->
<!-- <lg-modal id="modal">-->
<!-- <lg-modal-header [headingLevel]="3">Lorem ipsum</lg-modal-header>-->
<!-- <lg-modal-body>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</lg-modal-body>-->
<!-- <lg-modal-footer>-->
<!-- <lg-button-group>-->
<!-- <button lg-button lgMarginBottom="none" variant="primary-dark" type="button">Primary CTA</button>-->
<!-- <button lg-button lgMarginBottom="none" variant="secondary-dark" type="button">Cancel</button>-->
<!-- </lg-button-group>-->
<!-- </lg-modal-footer>-->
<!-- </lg-modal>-->
<lg-separator></lg-separator>
<lg-heading level="3">Modal</lg-heading>

<button lgModalTrigger="modal" lg-button type="button" variant="secondary-dark">Open modal</button>
<lg-modal id="modal" [closeOnOverlayClick]="true">
<lg-modal-header [headingLevel]="3">Lorem ipsum</lg-modal-header>
<lg-modal-body>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</lg-modal-body>
<lg-modal-footer>
<lg-button-group>
<button lg-button lgMarginBottom="none" variant="primary-dark" type="button">Primary CTA</button>
<button lg-button lgMarginBottom="none" variant="secondary-dark" type="button">Cancel</button>
</lg-button-group>
</lg-modal-footer>
</lg-modal>

<lg-separator></lg-separator>
<lg-heading level="3">List with Icons</lg-heading>
Expand Down Expand Up @@ -660,7 +660,7 @@ <h3>Carousel item 3</h3>
<lg-progress-header>
Thinking long term
</lg-progress-header>
</lg-progress-indicator>
</lg-progress-indicator>
</div>
<lg-separator></lg-separator>

Expand Down
2 changes: 2 additions & 0 deletions projects/canopy-test-app/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
LgInputModule,
LgLinkMenuModule,
LgListWithIconsModule,
LgModalModule,
LgMarginModule,
LgPaddingModule,
LgPageModule,
Expand Down Expand Up @@ -86,6 +87,7 @@ import { StoryContentComponent } from './story-content.component';
LgIconModule,
LgInputModule,
LgListWithIconsModule,
LgModalModule,
LgMarginModule,
LgPaddingModule,
LgPageModule,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ describe('LgCarouselComponent', () => {
expect(component.carouselItemCount).toBe(3);

expect(wrapperElement.attributes['style']).toBe(
'width: 300%; left: 0%; transition: left 0.5s ease 0s;',
'width: 300%; left: 0%; transition: left 0.5s;',
);
});

Expand Down
7 changes: 4 additions & 3 deletions projects/canopy/src/lib/modal/docs/guide.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,10 @@ Closing a modal dialogue on mobile can vary between each OS but in general tappi

#### Inputs

| Name | Description | Type | Default | Required |
|------|----------------------------|----------|-------------|----------|
| `id` | The unique id of the modal | `string` | `undefined` | Yes |
| Name | Description | Type | Default | Required |
|-----------------------|-------------------------------------------------------------------|-----------|-------------|----------|
| `id` | The unique id of the modal | `string` | `undefined` | Yes |
| `closeOnOverlayClick` | Determines if the modal should close when clicking on the overlay | `boolean` | `true` | No |

#### Outputs

Expand Down
17 changes: 16 additions & 1 deletion projects/canopy/src/lib/modal/docs/modal.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,20 @@ export default {
type: 'select',
},
},
closeOnOverlayClick: {
description: 'Whether the modal should close when the overlay is clicked.',
table: {
type: {
summary: 'boolean',
},
defaultValue: {
summary: true,
},
},
control: {
type: 'boolean',
},
},
id: {
table: {
disable: true,
Expand Down Expand Up @@ -114,7 +128,7 @@ export default {

const template = `
<button lgModalTrigger="modal-story" lg-button type="button" variant="secondary-dark">Open modal</button>
<lg-modal id="modal-story">
<lg-modal id="modal-story" closeOnOverlayClick="closeOnOverlayClick">
<lg-modal-header [headingLevel]="headingLevel">Lorem ipsum</lg-modal-header>
<lg-modal-body>
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Expand All @@ -139,6 +153,7 @@ standardSeparator.storyName = 'Modal';

standardSeparator.args = {
headingLevel: 2,
closeOnOverlayClick: true,
};

standardSeparator.parameters = {
Expand Down
16 changes: 12 additions & 4 deletions projects/canopy/src/lib/modal/modal.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,14 +188,22 @@ describe('LgModalComponent', () => {
});

describe('clicking on the modal overlay', () => {
it('should close the modal and emit an event', () => {
it('should close the modal and emit an event when closeOnOverlayClick is true', () => {
component.isOpen = true;
const closedEmitterSpy = spy(component.closedOverlayClick);

component.closeOnOverlayClick = true;
component.onOverlayClick();

verify(modalServiceMock.close(id)).once();
verify(closedEmitterSpy.emit()).once();

expect().nothing();
});

it('should not close the modal or emit an event when closeOnOverlayClick is false', () => {
component.isOpen = true;
component.closeOnOverlayClick = false;
component.onOverlayClick();

verify(modalServiceMock.close(id)).never();

expect().nothing();
});
Expand Down
17 changes: 10 additions & 7 deletions projects/canopy/src/lib/modal/modal.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export class LgModalComponent implements OnInit, AfterContentInit, OnDestroy {
private subscription: Subscription;
isOpen: boolean;
@Input() id: string;
@Input() closeOnOverlayClick = true;
@Output() open: EventEmitter<void> = new EventEmitter();
@Output() closed: EventEmitter<void> = new EventEmitter();
@Output() closedOverlayClick: EventEmitter<void> = new EventEmitter();
Expand All @@ -57,14 +58,16 @@ export class LgModalComponent implements OnInit, AfterContentInit, OnDestroy {
}

// onOverlayClick and onModalClick add the following functionality:
// clicking outside the modal closes the modal unless specified
// otherwise using closeOnOverlayClick.
// We specifically listen to the `mousedown` event because with
// the `click` event a user could click inside the modal and
// drag the mouse on the overlay causing the modal to close.
// clicking outside the modal closes the modal unless specified otherwise;
// using closeOnOverlayClick will disable the behaviour. We specifically listen
// to the `mousedown` event because with the `click` event a user could click
// inside the modal and drag the mouse on the overlay causing the modal to close.
@HostListener('mousedown') onOverlayClick(): void {
this.modalService.close(this.id);
this.closedOverlayClick.emit();
if (this.closeOnOverlayClick) {
this.modalService.close(this.id);

this.closedOverlayClick.emit();
}
}

ngOnInit(): void {
Expand Down

0 comments on commit e3cad52

Please sign in to comment.