From 995220ba7e01b20c8208d39243030a1d15be04bb Mon Sep 17 00:00:00 2001 From: Manon Carbonnel Date: Thu, 28 Sep 2023 14:53:32 +0200 Subject: [PATCH] fix(modal): closed in Storybook on window location change --- .../components/osds-modal/core/controller.ts | 33 ------------------- .../src/components/osds-modal/osds-modal.tsx | 30 +++++++++-------- .../modal/src/docs/osds-modal/usage.mdx | 17 +++++++++- .../modal/modal.web-components.stories.ts | 19 +++++++++++ 4 files changed, 51 insertions(+), 48 deletions(-) delete mode 100644 packages/components/modal/src/components/osds-modal/core/controller.ts diff --git a/packages/components/modal/src/components/osds-modal/core/controller.ts b/packages/components/modal/src/components/osds-modal/core/controller.ts deleted file mode 100644 index 0ece50f547..0000000000 --- a/packages/components/modal/src/components/osds-modal/core/controller.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { OsdsModal } from '../osds-modal'; - -/** - * common controller logic for cmpnt component used by the different implementations. - * it contains all the glue between framework implementation and the third party service. - */ -class OdsModalController { - - protected component: OsdsModal; - - constructor(component: OsdsModal) { - this.component = component; - } - - close() { - this.component.masked = true; - } - - open() { - this.component.masked = false; - } - - /** - * Attributes validation documentation - */ - validateAttributes(): void { - return; - } -} - -export { - OdsModalController -}; diff --git a/packages/components/modal/src/components/osds-modal/osds-modal.tsx b/packages/components/modal/src/components/osds-modal/osds-modal.tsx index 375c7a316c..88c2bf53ae 100644 --- a/packages/components/modal/src/components/osds-modal/osds-modal.tsx +++ b/packages/components/modal/src/components/osds-modal/osds-modal.tsx @@ -1,10 +1,9 @@ import type { OdsModalAttribute } from './interfaces/attributes'; import { ODS_THEME_COLOR_INTENT, ODS_THEME_TYPOGRAPHY_SIZE } from '@ovhcloud/ods-common-theming'; -import { Component, Element, Host, Method, Prop, h } from '@stencil/core'; +import { Component, Element, Host, Method, Prop, Watch, h } from '@stencil/core'; import { DEFAULT_ATTRIBUTE } from './constants/default-attributes'; import { ODS_ICON_NAME, ODS_ICON_SIZE } from '@ovhcloud/ods-component-icon'; import { ODS_TEXT_LEVEL } from '@ovhcloud/ods-component-text'; -import { OdsModalController } from './core/controller'; import { OdsModalMethod } from './interfaces/methods'; /** @@ -16,7 +15,6 @@ import { OdsModalMethod } from './interfaces/methods'; shadow: true }) export class OsdsModal implements OdsModalAttribute, OdsModalMethod { - controller: OdsModalController = new OdsModalController(this); @Element() el!: HTMLElement; /** @see OdsModalAttributes.color */ @@ -36,7 +34,7 @@ export class OsdsModal implements OdsModalAttribute, OdsModalMethod { */ @Method() async close(): Promise { - this.controller.close(); + this.masked = true; } /** @@ -44,23 +42,27 @@ export class OsdsModal implements OdsModalAttribute, OdsModalMethod { */ @Method() async open(): Promise { - this.controller.open(); + this.masked = false; } - componentWillRender(): void { - document.body.appendChild(this.el); + @Watch('masked') + watchOpenedStateHandler(masked: boolean) { const directChildren = Array.from(document.body.children); - for (const child of directChildren) { - if (child !== this.el && child.nodeName !== 'SCRIPT') { - if (!this.masked) { - child.setAttribute('inert', ''); - } else { - child.removeAttribute('inert'); - } + const filteredChildren = directChildren.filter(child => child !== this.el && child.nodeName !== 'SCRIPT'); + + for (const child of filteredChildren) { + if (!masked) { + child.setAttribute('inert', ''); + } else { + child.removeAttribute('inert'); } } } + componentWillLoad(): void { + document.body.appendChild(this.el); + } + render() { const { diff --git a/packages/components/modal/src/docs/osds-modal/usage.mdx b/packages/components/modal/src/docs/osds-modal/usage.mdx index dc3f3a8baa..ec49c693e4 100644 --- a/packages/components/modal/src/docs/osds-modal/usage.mdx +++ b/packages/components/modal/src/docs/osds-modal/usage.mdx @@ -5,7 +5,22 @@ import GenericStyle from '@ovhcloud/ods-common-core/docs/generic-style.mdx'; ## Usage ### Default -Modal + +export const buttonTrigger = () => { + setTimeout(() => { + const toggleModal = document.getElementById('toggle-modal'); + const modal = document.getElementById('modal-doc'); + toggleModal.addEventListener('click', () => { + modal.open(); + }); + }, 0); +}; + +Toggle modal + +Modal + +<>{ buttonTrigger() } ```html Modal diff --git a/packages/storybook/stories/components/modal/modal.web-components.stories.ts b/packages/storybook/stories/components/modal/modal.web-components.stories.ts index b851e74475..8d03fd3315 100644 --- a/packages/storybook/stories/components/modal/modal.web-components.stories.ts +++ b/packages/storybook/stories/components/modal/modal.web-components.stories.ts @@ -59,6 +59,7 @@ const TemplateDefault = (args:any) => { const modal = document.querySelector('osds-modal'); if (modal) { modal.open(); + locationChangeTrigger(); } } @@ -69,9 +70,27 @@ const TemplateDefault = (args:any) => { } } + const locationChangeTrigger = () => { + setTimeout(() => { + let prevUrl = window.location.href; + const interval = setInterval(() => { + const currUrl = window.location.href; + if (currUrl !== prevUrl) { + prevUrl = currUrl; + const modals = document.getElementsByTagName('osds-modal'); + for (let i = 0; i < modals.length; i++) { + modals[i].close(); + } + clearInterval(interval); + } + }, 100); + }, 0); + }; + return html` + ${locationChangeTrigger()} ${unsafeHTML(args.content)}