diff --git a/packages/core/src/components.d.ts b/packages/core/src/components.d.ts index 3e79316e4..1d9734b31 100644 --- a/packages/core/src/components.d.ts +++ b/packages/core/src/components.d.ts @@ -201,11 +201,13 @@ export namespace Components { } interface AtomModal { "alertType"?: 'alert' | 'error'; + "canDismiss"?: boolean; "disablePrimaryButton": boolean; "disableSecondaryButton": boolean; "hasDivider": boolean; "hasFooter": boolean; "headerTitle": string; + "idName"?: string; "isOpen": boolean; "primaryButtonText"?: string; "progress"?: number; @@ -935,11 +937,13 @@ declare namespace LocalJSX { } interface AtomModal { "alertType"?: 'alert' | 'error'; + "canDismiss"?: boolean; "disablePrimaryButton"?: boolean; "disableSecondaryButton"?: boolean; "hasDivider"?: boolean; "hasFooter"?: boolean; "headerTitle"?: string; + "idName"?: string; "isOpen"?: boolean; "onAtomCloseClick"?: (event: AtomModalCustomEvent) => void; "onAtomDidDismiss"?: (event: AtomModalCustomEvent) => void; diff --git a/packages/core/src/components/modal/modal.spec.ts b/packages/core/src/components/modal/modal.spec.ts index e8bc593fd..5637419fc 100644 --- a/packages/core/src/components/modal/modal.spec.ts +++ b/packages/core/src/components/modal/modal.spec.ts @@ -82,6 +82,7 @@ describe('atom-modal', () => { expect(page.root?.innerHTML).not.toContain('isopen') }) + it('should render modal opened if is open is set to true', async () => { page = await newSpecPage({ components: [AtomModal], @@ -146,6 +147,7 @@ describe('atom-modal', () => { expect(spyPrimary).toHaveBeenCalled() expect(spySecondary).toHaveBeenCalled() }) + it('should render progress bar when progress is passed even if it is zero', async () => { await page.setContent(` @@ -172,6 +174,7 @@ describe('atom-modal', () => { '' ) }) + it('should emit atomIsOpenChange when is open changes', async () => { const isOpenChangeSpy = jest.fn() @@ -185,4 +188,43 @@ describe('atom-modal', () => { expect(isOpenChangeSpy).toHaveBeenCalled() expect(isOpenChangeSpy.mock.calls[0][0].detail).toBe(true) }) + + it('should render not can close modal when prop.canDismiss is set to true', async () => { + page = await newSpecPage({ + components: [AtomModal], + html: ` + + Modal content + + `, + }) + + expect(page.root?.innerHTML).toContain('candismiss') + }) + + it('should render not can close modal when prop.canDismiss is set to false', async () => { + page = await newSpecPage({ + components: [AtomModal], + html: ` + + Modal content + + `, + }) + + expect(page.root?.innerHTML).not.toContain('candismiss') + }) + + it('should render the modal with the specified id when the idName prop is set', async () => { + page = await newSpecPage({ + components: [AtomModal], + html: ` + + Modal content + + `, + }) + + expect(page.root?.innerHTML).toContain('modal-id') + }) }) diff --git a/packages/core/src/components/modal/modal.tsx b/packages/core/src/components/modal/modal.tsx index defcaaf81..c87a66623 100644 --- a/packages/core/src/components/modal/modal.tsx +++ b/packages/core/src/components/modal/modal.tsx @@ -18,6 +18,7 @@ type AlertType = Record<'alert' | 'error', { icon: IconProps; color: string }> scoped: true, }) export class AtomModal { + @Prop() idName?: string @Prop() trigger?: string @Prop() headerTitle = '' @Prop() primaryButtonText?: string @@ -29,6 +30,7 @@ export class AtomModal { @Prop() disablePrimaryButton = false @Prop() disableSecondaryButton = false @Prop({ mutable: true }) isOpen = false + @Prop({ mutable: true }) canDismiss?: boolean @Event() atomCloseClick: EventEmitter @Event() atomDidDismiss: EventEmitter @@ -88,6 +90,7 @@ export class AtomModal { aria-describedby='atom-modal__content' ref={(el) => (this.modal = el as HTMLIonModalElement)} trigger={this.trigger} + id={this.idName} class={{ 'atom-modal': true, 'atom-modal--progress': !!this.progress, @@ -96,6 +99,7 @@ export class AtomModal { onDidDismiss={this.handleDidDismiss} onDidPresent={this.handleDidPresent} isOpen={this.isOpen} + canDismiss={this.canDismiss} part='modal' >
diff --git a/packages/core/src/components/modal/stories/modal.args.ts b/packages/core/src/components/modal/stories/modal.args.ts index 0895f3982..8bd150075 100644 --- a/packages/core/src/components/modal/stories/modal.args.ts +++ b/packages/core/src/components/modal/stories/modal.args.ts @@ -29,6 +29,13 @@ export const ModalStoryArgs = { category: Category.PROPERTIES, }, }, + id: { + control: 'text', + description: 'The id of the modal', + table: { + category: Category.PROPERTIES, + }, + }, hasDivider: { control: 'boolean', description: 'if true, a divider will be added on the header and footer', @@ -104,6 +111,14 @@ export const ModalStoryArgs = { category: Category.PROPERTIES, }, }, + canDismiss: { + control: 'boolean', + description: + 'If true, the modal can be dismissed by clicking outside the modal. Default is true', + table: { + category: Category.PROPERTIES, + }, + }, atomCloseClick: { action: 'atomCloseClick', description: @@ -227,4 +242,5 @@ export const ModalComponentArgs = { disableSecondaryButton: false, disablePrimaryButton: false, isOpen: false, + canDismiss: true, } diff --git a/packages/core/src/components/modal/stories/modal.core.stories.tsx b/packages/core/src/components/modal/stories/modal.core.stories.tsx index ccc849f1d..b2a4175ba 100644 --- a/packages/core/src/components/modal/stories/modal.core.stories.tsx +++ b/packages/core/src/components/modal/stories/modal.core.stories.tsx @@ -24,6 +24,8 @@ const createModal = (args) => { disable-secondary-button="${args.disableSecondaryButton}" disable-primary-button="${args.disablePrimaryButton}" is-open="${args.isOpen}" + can-dismiss="${args.canDismiss}" + id="${args.id}" >
Custom Header

Modal Content

@@ -63,7 +65,7 @@ export const Alert: StoryObj = { }, } -export const Error: StoryObj = { +export const ErrorModal: StoryObj = { render: (args) => createModal(args), args: { ...ModalComponentArgs, diff --git a/packages/core/src/components/modal/stories/modal.react.stories.tsx b/packages/core/src/components/modal/stories/modal.react.stories.tsx index 99b716785..24ea81764 100644 --- a/packages/core/src/components/modal/stories/modal.react.stories.tsx +++ b/packages/core/src/components/modal/stories/modal.react.stories.tsx @@ -23,6 +23,8 @@ const createModal = (args) => ( disablePrimaryButton={args.disablePrimaryButton} disableSecondaryButton={args.disableSecondaryButton} isOpen={args.isOpen} + canDismiss={args.canDismiss} + id={args.id} >
Custom Header

Modal Content

@@ -61,7 +63,7 @@ export const Alert: StoryObj = { }, } -export const Error: StoryObj = { +export const ErrorModal: StoryObj = { render: (args) => createModal(args), args: { ...ModalComponentArgs, diff --git a/packages/core/src/components/modal/stories/modal.vue.stories.tsx b/packages/core/src/components/modal/stories/modal.vue.stories.tsx index c638a5fdc..8d6e5527a 100644 --- a/packages/core/src/components/modal/stories/modal.vue.stories.tsx +++ b/packages/core/src/components/modal/stories/modal.vue.stories.tsx @@ -26,6 +26,8 @@ const createModal = (args, themeColor = 'light') => ({ disable-primary-button="${args.disablePrimaryButton}" disable-secondary-button="${args.disableSecondaryButton}" is-open="${args.isOpen}" + can-dismiss="${args.canDismiss}" + id="${args.id}" >
Custom Header

Modal Content

@@ -65,7 +67,7 @@ export const Alert: StoryObj = { }, } -export const Error: StoryObj = { +export const ErrorModal: StoryObj = { render: (args) => createModal(args), args: { ...ModalComponentArgs,