@nordhealth/components 3.11.0 → 3.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- import{E as t}from"./EventController-d99ebeef.js";import{L as s}from"./LightDismissController-11ae4745.js";import{S as e}from"./ScrollbarController-773c79f4.js";import"./ShortcutController-87615e31.js";import"./tinykeys.module-84e6cc41.js";const i=(t,s)=>{if(s){const s=t.getAttribute("inert");null!==s&&t.setAttribute("data-n-inert",s),t.setAttribute("inert","")}else{const s=t.getAttribute("data-n-inert");null!==s?(t.setAttribute("inert",s),t.removeAttribute("data-n-inert")):t.removeAttribute("inert")}};function o(t,s){let e=t.nextElementSibling;for(;e;)i(e,s),e=e.nextElementSibling;for(e=t.previousElementSibling;e;)i(e,s),e=e.previousElementSibling;t.parentElement&&t.parentElement!==document.body&&o(t.parentElement,s)}class n{constructor(t){this.host=t,t.addController(this)}hostDisconnected(){this.release()}trap(){o(this.host,!0)}release(){o(this.host,!1)}}class r{constructor(i,o){this.host=i,this.trackLastButton=t=>{const s=t.target;"button"===s.localName&&(this.lastButton=s)},this.polyfillSubmitter=t=>{t.submitter=this.lastButton},this.handleTransitionEnd=t=>{this.options.isOpen()||t.target!==this.host||this.scrollBar.unlockScroll()},this.handleLightDismiss=t=>{this.host.contains(t.target)&&this.options.onDismiss(t)},this.handleSubmit=t=>{this.lastButton=void 0;const s=t.target,e=t.submitter,i="dialog"===s.method,o="dialog"===s.getAttribute("method");o&&!i&&t.preventDefault(),(o||i)&&this.options.close(null==e?void 0:e.value)},i.addController(this),this.options=o,this.scrollBar=new e(i),this.focusTrap=new n(i),this.events=new t(i),this.lightDismiss=new s(i,{isOpen:o.isOpen,isDismissible:t=>t!==o.dialog(),onDismiss:this.handleLightDismiss})}hostConnected(){window.SubmitEvent||(this.events.listen(this.host,"click",this.trackLastButton,!0),this.events.listen(this.host,"submit",this.polyfillSubmitter,!0)),this.events.listen(this.host,"transitionend",this.handleTransitionEnd),this.events.listen(this.host,"submit",this.handleSubmit)}hostDisconnected(){r.openModals.remove(this)}block(){var t;null===(t=r.openModals.top)||void 0===t||t.focusTrap.release(),r.openModals.push(this),this.scrollBar.lockScroll(),this.trigger=document.activeElement;(this.host.querySelector("[autofocus]")||this.host).focus(),this.focusTrap.trap()}unblock(){var t,s;r.openModals.top===this&&(r.openModals.pop(),this.options.backdrop().scrollTop=0,this.focusTrap.release(),null===(t=this.trigger)||void 0===t||t.focus(),this.trigger=void 0,null===(s=r.openModals.top)||void 0===s||s.focusTrap.trap())}}r.openModals=new class{constructor(){this.items=[]}get length(){return this.items.length}get top(){return this.items[this.length-1]}push(t){this.items.push(t)}pop(){return this.items.pop()}remove(t){const s=this.items.indexOf(t);-1!==s&&this.items.splice(s,1)}};export{r as ModalController};
1
+ import{E as t}from"./EventController-d99ebeef.js";import{L as s}from"./LightDismissController-11ae4745.js";import{S as e}from"./ScrollbarController-773c79f4.js";import"./ShortcutController-87615e31.js";import"./tinykeys.module-84e6cc41.js";function i(t,s){t.forEach((t=>((t,s)=>{if(s){const s=t.getAttribute("inert");null!==s&&t.setAttribute("data-n-inert",s),t.setAttribute("inert","")}else{const s=t.getAttribute("data-n-inert");null!==s?(t.setAttribute("inert",s),t.removeAttribute("data-n-inert")):t.removeAttribute("inert")}})(t,s)))}function o(t){const s=[];let e=t.nextElementSibling;for(;e;)s.push(e),e=e.nextElementSibling;for(e=t.previousElementSibling;e;)s.push(e),e=e.previousElementSibling;return t.parentElement&&t.parentElement!==document.body&&s.push(...o(t.parentElement)),s}class n{constructor(t){this.host=t,this.inertElements=[],t.addController(this)}hostDisconnected(){this.release()}trap(){const t=o(this.host);i(t,!0),this.inertElements=t}release(){i(this.inertElements,!1),this.inertElements=[]}}class r{constructor(i,o){this.host=i,this.trackLastButton=t=>{const s=t.target;"button"===s.localName&&(this.lastButton=s)},this.polyfillSubmitter=t=>{t.submitter=this.lastButton},this.handleTransitionEnd=t=>{this.options.isOpen()||t.target!==this.host||this.scrollBar.unlockScroll()},this.handleLightDismiss=t=>{this.host.contains(t.target)&&this.options.onDismiss(t)},this.handleSubmit=t=>{this.lastButton=void 0;const s=t.target,e=t.submitter,i="dialog"===s.method,o="dialog"===s.getAttribute("method");o&&!i&&t.preventDefault(),(o||i)&&this.options.close(null==e?void 0:e.value)},i.addController(this),this.options=o,this.scrollBar=new e(i),this.focusTrap=new n(i),this.events=new t(i),this.lightDismiss=new s(i,{isOpen:o.isOpen,isDismissible:t=>t!==o.dialog(),onDismiss:this.handleLightDismiss})}hostConnected(){window.SubmitEvent||(this.events.listen(this.host,"click",this.trackLastButton,!0),this.events.listen(this.host,"submit",this.polyfillSubmitter,!0)),this.events.listen(this.host,"transitionend",this.handleTransitionEnd),this.events.listen(this.host,"submit",this.handleSubmit)}hostDisconnected(){r.openModals.remove(this)}block(){var t;null===(t=r.openModals.top)||void 0===t||t.focusTrap.release(),r.openModals.push(this),this.scrollBar.lockScroll(),this.trigger=document.activeElement;(this.host.querySelector("[autofocus]")||this.host).focus(),this.focusTrap.trap()}unblock(){var t,s;r.openModals.top===this&&(r.openModals.pop(),this.options.backdrop().scrollTop=0,this.focusTrap.release(),null===(t=this.trigger)||void 0===t||t.focus(),this.trigger=void 0,null===(s=r.openModals.top)||void 0===s||s.focusTrap.trap())}}r.openModals=new class{constructor(){this.items=[]}get length(){return this.items.length}get top(){return this.items[this.length-1]}push(t){this.items.push(t)}pop(){return this.items.pop()}remove(t){const s=this.items.indexOf(t);-1!==s&&this.items.splice(s,1)}};export{r as ModalController};
2
2
  //# sourceMappingURL=ModalController.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ModalController.js","sources":["../src/common/inert.ts","../src/common/controllers/FocusTrapController.ts","../src/modal/ModalController.ts"],"sourcesContent":["const setInertAttribute = (element: Element, enabled: boolean) => {\n if (enabled) {\n const current = element.getAttribute(\"inert\")\n\n // store previous value\n if (current !== null) {\n element.setAttribute(\"data-n-inert\", current)\n }\n\n element.setAttribute(\"inert\", \"\")\n } else {\n const current = element.getAttribute(\"data-n-inert\")\n\n // restore previous value if necessary\n if (current !== null) {\n element.setAttribute(\"inert\", current)\n element.removeAttribute(\"data-n-inert\")\n } else {\n element.removeAttribute(\"inert\")\n }\n }\n}\n\nexport function inertAround(element: Element, enabled: boolean) {\n let next = element.nextElementSibling\n\n while (next) {\n setInertAttribute(next, enabled)\n next = next.nextElementSibling\n }\n\n next = element.previousElementSibling\n\n while (next) {\n setInertAttribute(next, enabled)\n next = next.previousElementSibling\n }\n\n if (element.parentElement && element.parentElement !== document.body) {\n inertAround(element.parentElement, enabled)\n }\n}\n","import { ReactiveController, ReactiveControllerHost } from \"lit\"\nimport { inertAround } from \"../../common/inert.js\"\n\nexport class FocusTrapController implements ReactiveController {\n constructor(private host: ReactiveControllerHost & HTMLElement) {\n host.addController(this)\n }\n\n hostDisconnected() {\n this.release()\n }\n\n trap() {\n inertAround(this.host, true)\n }\n\n release() {\n inertAround(this.host, false)\n }\n}\n","/* eslint-disable max-classes-per-file */\nimport { ReactiveController, ReactiveControllerHost } from \"lit\"\nimport { EventController } from \"../common/controllers/EventController.js\"\nimport { FocusTrapController } from \"../common/controllers/FocusTrapController.js\"\nimport { LightDismissController, LightDismissOptions } from \"../common/controllers/LightDismissController.js\"\nimport { ScrollbarController } from \"../common/controllers/ScrollbarController.js\"\n\nclass Stack<T> {\n private items: T[] = []\n\n get length() {\n return this.items.length\n }\n\n get top(): T | undefined {\n return this.items[this.length - 1]\n }\n\n push(item: T) {\n this.items.push(item)\n }\n\n pop() {\n return this.items.pop()\n }\n\n remove(item: T) {\n const index = this.items.indexOf(item)\n\n if (index !== -1) {\n this.items.splice(index, 1)\n }\n }\n}\n\nconst isButton = (element: Element): element is HTMLButtonElement => element.localName === \"button\"\n\ntype ModalControllerOptions = {\n isOpen: LightDismissOptions[\"isOpen\"]\n onDismiss: LightDismissOptions[\"onDismiss\"]\n close: (returnValue?: string) => void\n backdrop: () => HTMLElement\n dialog: () => HTMLElement\n}\n\nexport class ModalController implements ReactiveController {\n private static openModals = new Stack<ModalController>()\n\n private scrollBar: ScrollbarController\n private focusTrap: FocusTrapController\n private lightDismiss: LightDismissController\n private events: EventController\n private options: ModalControllerOptions\n\n private trigger?: HTMLElement\n private lastButton?: HTMLButtonElement\n\n constructor(private host: ReactiveControllerHost & HTMLElement, options: ModalControllerOptions) {\n host.addController(this)\n this.options = options\n\n this.scrollBar = new ScrollbarController(host)\n this.focusTrap = new FocusTrapController(host)\n this.events = new EventController(host)\n this.lightDismiss = new LightDismissController(host, {\n isOpen: options.isOpen,\n isDismissible: node => node !== options.dialog(),\n onDismiss: this.handleLightDismiss,\n })\n }\n\n hostConnected() {\n // if submit event is not supported, let's do a basic polyfill\n if (!window.SubmitEvent) {\n this.events.listen(this.host, \"click\", this.trackLastButton, true)\n this.events.listen(this.host, \"submit\", this.polyfillSubmitter, true)\n }\n\n this.events.listen(this.host, \"transitionend\", this.handleTransitionEnd)\n this.events.listen(this.host, \"submit\", this.handleSubmit)\n }\n\n hostDisconnected(): void {\n ModalController.openModals.remove(this)\n }\n\n block() {\n // if there is already a modal open, release its focus trap\n ModalController.openModals.top?.focusTrap.release()\n\n // add this modal to the stack of open modals\n ModalController.openModals.push(this)\n\n // hide scrollbar and prevent scroll on body\n this.scrollBar.lockScroll()\n\n // store the element that was focused prior to modal opening\n this.trigger = document.activeElement as HTMLElement\n\n // handle initial (auto)focus\n const focusTarget = this.host.querySelector<HTMLElement>(\"[autofocus]\") || this.host\n focusTarget.focus()\n\n // finally, we should enable the focus trap\n this.focusTrap.trap()\n }\n\n unblock() {\n // it does not make sense to unblock a modal if it is not the top-most modal\n if (ModalController.openModals.top !== this) {\n return\n }\n\n ModalController.openModals.pop()\n\n // ensure modal is scrolled to top ready for re-open\n this.options.backdrop().scrollTop = 0\n\n // we need to release the focus trap...\n this.focusTrap.release()\n\n // ...before we can return focus to the trigger\n this.trigger?.focus()\n this.trigger = undefined\n\n // if there are still modals open, enable the next modal's focus trap\n ModalController.openModals.top?.focusTrap.trap()\n }\n\n /**\n * capture the last button clicked, so that we can polyfill `submitter` property in submit event\n */\n private trackLastButton = (e: Event) => {\n const target = e.target as HTMLElement\n\n if (isButton(target)) {\n this.lastButton = target\n }\n }\n\n private polyfillSubmitter = (e: Event) => {\n // @ts-expect-error submitter is readonly, but this is only called if SubmitEvent is not supported\n e.submitter = this.lastButton\n }\n\n private handleTransitionEnd = (e: TransitionEvent) => {\n // scrollbar should only be restored when the modal has transitioned,\n // that way we avoid awkward double scrollbars.\n if (!this.options.isOpen() && e.target === this.host) {\n this.scrollBar.unlockScroll()\n }\n }\n\n private handleLightDismiss = (e: Event) => {\n if (this.host.contains(e.target as Node)) {\n this.options.onDismiss(e)\n }\n }\n\n private handleSubmit = (e: SubmitEvent) => {\n this.lastButton = undefined\n\n const target = e.target as HTMLFormElement\n const submitter = e.submitter as HTMLButtonElement\n\n const isDialogProperty = target.method === \"dialog\"\n const isDialogAttr = target.getAttribute(\"method\") === \"dialog\"\n\n // if they mismatch, it means \"dialog\" method is not supported,\n // so we should polyfill the fact it does not do a full submit\n if (isDialogAttr && !isDialogProperty) {\n e.preventDefault()\n }\n\n if (isDialogAttr || isDialogProperty) {\n this.options.close(submitter?.value)\n }\n }\n}\n"],"names":["setInertAttribute","element","enabled","current","getAttribute","setAttribute","removeAttribute","inertAround","next","nextElementSibling","previousElementSibling","parentElement","document","body","FocusTrapController","constructor","host","this","addController","hostDisconnected","release","trap","ModalController","options","trackLastButton","e","target","localName","lastButton","polyfillSubmitter","submitter","handleTransitionEnd","isOpen","scrollBar","unlockScroll","handleLightDismiss","contains","onDismiss","handleSubmit","undefined","isDialogProperty","method","isDialogAttr","preventDefault","close","value","ScrollbarController","focusTrap","events","EventController","lightDismiss","LightDismissController","isDismissible","node","dialog","hostConnected","window","SubmitEvent","listen","openModals","remove","block","_a","top","push","lockScroll","trigger","activeElement","querySelector","focus","unblock","pop","backdrop","scrollTop","_b","items","length","item","index","indexOf","splice"],"mappings":"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"}
1
+ {"version":3,"file":"ModalController.js","sources":["../src/common/inert.ts","../src/common/controllers/FocusTrapController.ts","../src/modal/ModalController.ts"],"sourcesContent":["/**\n * Set or remove the `inert` attribute on an element.\n *\n * @param element The element to set or remove the `inert` attribute on.\n * @param enabled Whether to set or remove the `inert` attribute.\n */\nconst setInertAttribute = (element: Element, enabled: boolean) => {\n if (enabled) {\n const current = element.getAttribute(\"inert\")\n\n // store previous value\n if (current !== null) {\n element.setAttribute(\"data-n-inert\", current)\n }\n\n element.setAttribute(\"inert\", \"\")\n } else {\n const current = element.getAttribute(\"data-n-inert\")\n\n // restore previous value if necessary\n if (current !== null) {\n element.setAttribute(\"inert\", current)\n element.removeAttribute(\"data-n-inert\")\n } else {\n element.removeAttribute(\"inert\")\n }\n }\n}\n\n/**\n * Set or remove the `inert` attribute on all given elements.\n *\n * @param elements The elements to set or remove the `inert` attribute on.\n * @param enabled Whether to set or remove the `inert` attribute.\n */\nexport function setInertAttributes(elements: Element[], enabled: boolean) {\n elements.forEach(element => setInertAttribute(element, enabled))\n}\n\n/**\n * Get all siblings of an element, including the siblings of its parents.\n * Use this to find all elements that should be inert when a modal is open.\n * And then use `setInertAttributes` to set or remove the `inert` attribute\n * on all of them.\n */\nexport function getElementsAround(element: Element): Element[] {\n const elements = []\n let next = element.nextElementSibling\n\n while (next) {\n elements.push(next)\n next = next.nextElementSibling\n }\n\n next = element.previousElementSibling\n\n while (next) {\n elements.push(next)\n next = next.previousElementSibling\n }\n\n if (element.parentElement && element.parentElement !== document.body) {\n elements.push(...getElementsAround(element.parentElement))\n }\n\n return elements\n}\n","import { ReactiveController, ReactiveControllerHost } from \"lit\"\nimport { getElementsAround, setInertAttributes } from \"../../common/inert.js\"\n\nexport class FocusTrapController implements ReactiveController {\n private inertElements: Element[] = []\n\n constructor(private host: ReactiveControllerHost & HTMLElement) {\n host.addController(this)\n }\n\n hostDisconnected() {\n this.release()\n }\n\n trap() {\n const elements = getElementsAround(this.host)\n\n setInertAttributes(elements, true)\n this.inertElements = elements\n }\n\n release() {\n setInertAttributes(this.inertElements, false)\n this.inertElements = []\n }\n}\n","/* eslint-disable max-classes-per-file */\nimport { ReactiveController, ReactiveControllerHost } from \"lit\"\nimport { EventController } from \"../common/controllers/EventController.js\"\nimport { FocusTrapController } from \"../common/controllers/FocusTrapController.js\"\nimport { LightDismissController, LightDismissOptions } from \"../common/controllers/LightDismissController.js\"\nimport { ScrollbarController } from \"../common/controllers/ScrollbarController.js\"\n\nclass Stack<T> {\n private items: T[] = []\n\n get length() {\n return this.items.length\n }\n\n get top(): T | undefined {\n return this.items[this.length - 1]\n }\n\n push(item: T) {\n this.items.push(item)\n }\n\n pop() {\n return this.items.pop()\n }\n\n remove(item: T) {\n const index = this.items.indexOf(item)\n\n if (index !== -1) {\n this.items.splice(index, 1)\n }\n }\n}\n\nconst isButton = (element: Element): element is HTMLButtonElement => element.localName === \"button\"\n\ntype ModalControllerOptions = {\n isOpen: LightDismissOptions[\"isOpen\"]\n onDismiss: LightDismissOptions[\"onDismiss\"]\n close: (returnValue?: string) => void\n backdrop: () => HTMLElement\n dialog: () => HTMLElement\n}\n\nexport class ModalController implements ReactiveController {\n private static openModals = new Stack<ModalController>()\n\n private scrollBar: ScrollbarController\n private focusTrap: FocusTrapController\n private lightDismiss: LightDismissController\n private events: EventController\n private options: ModalControllerOptions\n\n private trigger?: HTMLElement\n private lastButton?: HTMLButtonElement\n\n constructor(private host: ReactiveControllerHost & HTMLElement, options: ModalControllerOptions) {\n host.addController(this)\n this.options = options\n\n this.scrollBar = new ScrollbarController(host)\n this.focusTrap = new FocusTrapController(host)\n this.events = new EventController(host)\n this.lightDismiss = new LightDismissController(host, {\n isOpen: options.isOpen,\n isDismissible: node => node !== options.dialog(),\n onDismiss: this.handleLightDismiss,\n })\n }\n\n hostConnected() {\n // if submit event is not supported, let's do a basic polyfill\n if (!window.SubmitEvent) {\n this.events.listen(this.host, \"click\", this.trackLastButton, true)\n this.events.listen(this.host, \"submit\", this.polyfillSubmitter, true)\n }\n\n this.events.listen(this.host, \"transitionend\", this.handleTransitionEnd)\n this.events.listen(this.host, \"submit\", this.handleSubmit)\n }\n\n hostDisconnected(): void {\n ModalController.openModals.remove(this)\n }\n\n block() {\n // if there is already a modal open, release its focus trap\n ModalController.openModals.top?.focusTrap.release()\n\n // add this modal to the stack of open modals\n ModalController.openModals.push(this)\n\n // hide scrollbar and prevent scroll on body\n this.scrollBar.lockScroll()\n\n // store the element that was focused prior to modal opening\n this.trigger = document.activeElement as HTMLElement\n\n // handle initial (auto)focus\n const focusTarget = this.host.querySelector<HTMLElement>(\"[autofocus]\") || this.host\n focusTarget.focus()\n\n // finally, we should enable the focus trap\n this.focusTrap.trap()\n }\n\n unblock() {\n // it does not make sense to unblock a modal if it is not the top-most modal\n if (ModalController.openModals.top !== this) {\n return\n }\n\n ModalController.openModals.pop()\n\n // ensure modal is scrolled to top ready for re-open\n this.options.backdrop().scrollTop = 0\n\n // we need to release the focus trap...\n this.focusTrap.release()\n\n // ...before we can return focus to the trigger\n this.trigger?.focus()\n this.trigger = undefined\n\n // if there are still modals open, enable the next modal's focus trap\n ModalController.openModals.top?.focusTrap.trap()\n }\n\n /**\n * capture the last button clicked, so that we can polyfill `submitter` property in submit event\n */\n private trackLastButton = (e: Event) => {\n const target = e.target as HTMLElement\n\n if (isButton(target)) {\n this.lastButton = target\n }\n }\n\n private polyfillSubmitter = (e: Event) => {\n // @ts-expect-error submitter is readonly, but this is only called if SubmitEvent is not supported\n e.submitter = this.lastButton\n }\n\n private handleTransitionEnd = (e: TransitionEvent) => {\n // scrollbar should only be restored when the modal has transitioned,\n // that way we avoid awkward double scrollbars.\n if (!this.options.isOpen() && e.target === this.host) {\n this.scrollBar.unlockScroll()\n }\n }\n\n private handleLightDismiss = (e: Event) => {\n if (this.host.contains(e.target as Node)) {\n this.options.onDismiss(e)\n }\n }\n\n private handleSubmit = (e: SubmitEvent) => {\n this.lastButton = undefined\n\n const target = e.target as HTMLFormElement\n const submitter = e.submitter as HTMLButtonElement\n\n const isDialogProperty = target.method === \"dialog\"\n const isDialogAttr = target.getAttribute(\"method\") === \"dialog\"\n\n // if they mismatch, it means \"dialog\" method is not supported,\n // so we should polyfill the fact it does not do a full submit\n if (isDialogAttr && !isDialogProperty) {\n e.preventDefault()\n }\n\n if (isDialogAttr || isDialogProperty) {\n this.options.close(submitter?.value)\n }\n }\n}\n"],"names":["setInertAttributes","elements","enabled","forEach","element","current","getAttribute","setAttribute","removeAttribute","setInertAttribute","getElementsAround","next","nextElementSibling","push","previousElementSibling","parentElement","document","body","FocusTrapController","constructor","host","this","inertElements","addController","hostDisconnected","release","trap","ModalController","options","trackLastButton","e","target","localName","lastButton","polyfillSubmitter","submitter","handleTransitionEnd","isOpen","scrollBar","unlockScroll","handleLightDismiss","contains","onDismiss","handleSubmit","undefined","isDialogProperty","method","isDialogAttr","preventDefault","close","value","ScrollbarController","focusTrap","events","EventController","lightDismiss","LightDismissController","isDismissible","node","dialog","hostConnected","window","SubmitEvent","listen","openModals","remove","block","_a","top","lockScroll","trigger","activeElement","querySelector","focus","unblock","pop","backdrop","scrollTop","_b","items","length","item","index","indexOf","splice"],"mappings":"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"}