@nordhealth/components 1.1.1 → 1.1.2

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.
package/lib/Popout.js CHANGED
@@ -1,2 +1,2 @@
1
- import{_ as t,n as e}from"./query-assigned-elements-ef860822.js";import{r as o,s as i,$ as s}from"./lit-element-e382250e.js";import{e as n}from"./property-03f59dce.js";import{t as r}from"./state-70f38ceb.js";import{a,c as p,l,o as d,f as h,s as m,h as c}from"./positioning-763efb3a.js";import{L as u}from"./LightDismissController-a2645ae6.js";import{N as f}from"./events-731d0007.js";import{s as v}from"./Component-fa316972.js";import{D as g}from"./DirectionController-8b298382.js";import{o as b}from"./observe-a9c6dfb6.js";import"./EventController-d99ebeef.js";import"./ShortcutController-87615e31.js";import"./tinykeys.module-84e6cc41.js";const y=o`:host{position:fixed;pointer-events:none;z-index:var(--n-index-popout);left:var(--x);top:var(--y);font-size:var(--n-font-size-m);color:var(--n-color-text)}.n-popout{visibility:hidden;opacity:0;pointer-events:none;transition:transform var(--n-transition-slowly),opacity var(--n-transition-slowly),visibility var(--n-transition-slowly);transform:translateY(-10px) scale(.97);transform-origin:top left;will-change:transform,opacity,visibility;background:var(--n-color-surface);box-shadow:var(--n-box-shadow-popout);border-radius:var(--n-border-radius-s)}@media (max-width:35.9375em){:host{inline-size:100%;inset:0;inset-block-start:auto;font-size:var(--n-font-size-l)}.n-popout{transition:transform var(--n-transition-mobile),opacity var(--n-transition-mobile),visibility var(--n-transition-mobile);transform:translateY(100%);transform-origin:bottom center;border-radius:0}}.n-popout.top-end,.n-popout.top-start{transform:translateY(10px) scale(.97)}.n-popout.left-start{transform:translateX(10px) scale(.97)}.n-popout.left-end,.n-popout.top-end{transform-origin:bottom right}.n-popout.bottom-end,.n-popout.left-start{transform-origin:top right}.n-popout.left-end{transform:translateX(10px) scale(.97);transform-origin:bottom right}.n-popout.right-end,.n-popout.right-start{transform:translateX(-10px) scale(.97);transform-origin:bottom left}.n-popout.right-start{transform-origin:top left}.n-popout.top-start.is-rtl{transform-origin:top right}.n-popout.top-end.is-rtl{transform-origin:top left}.n-popout.bottom-start.is-rtl{transform-origin:bottom right}.n-popout.bottom-end.is-rtl{transform-origin:bottom left}.n-popout[aria-hidden=false]{transition-property:transform,opacity;visibility:visible;opacity:1;pointer-events:auto;transform:translateY(0) translateX(0) scale(1)}`;let w=class extends i{constructor(){super(...arguments),this.breakpoint="35.9375em",this.viewportObserver=new ResizeObserver((t=>{t.forEach((()=>{this.smallViewport=window.matchMedia(`(max-width: ${this.breakpoint})`).matches,this.smallViewport||(this.cleanupAutoUpdate=a(this.targetElement,this,this.updatePosition))}))})),this.dismiss=new u(this,{isOpen:()=>this.open,onDismiss:t=>this.hide("click"!==t.type),isDismissible:t=>t!==this&&t!==this.targetElement}),this.direction=new g(this),this.open=!1,this.smallViewport=!1,this.align="start",this.position="block-end",this.id="",this.updatePosition=async()=>{var t;const{x:e,y:o,placement:i,middlewareData:s}=await p(this.targetElement,this,{strategy:"fixed",placement:l(this.position,this.align,this.direction.dir),middleware:[d(8),h(),m({padding:8}),c()]});this.computedPosition=i,this.style.setProperty("--x",`${e}px`),this.style.setProperty("--y",`${o}px`),(null===(t=s.hide)||void 0===t?void 0:t.referenceHidden)&&this.hide()},this.toggleOpen=t=>{t.preventDefault(),this.open?this.hide(!1):this.smallViewport?this.show():this.updatePosition().then((()=>this.show()))}}show(){this.open||(this.open=!0,this.smallViewport=window.matchMedia(`(max-width: ${this.breakpoint})`).matches,this.viewportObserver.observe(document.documentElement),this.smallViewport||(this.cleanupAutoUpdate=a(this.targetElement,this,this.updatePosition)),this.updateComplete.then((()=>{this.dispatchEvent(new f("open"))})))}hide(t=!0){var e;this.open&&(this.open=!1,null===(e=this.cleanupAutoUpdate)||void 0===e||e.call(this),this.viewportObserver.unobserve(document.documentElement),this.dispatchEvent(new f("close")),t&&this.targetElement.focus({preventScroll:!0}))}firstUpdated(){this.smallViewport||this.updatePosition()}connectedCallback(){super.connectedCallback(),this.targetElement=this.getToggle(),this.targetElement.addEventListener("click",this.toggleOpen)}disconnectedCallback(){var t;super.disconnectedCallback(),null===(t=this.cleanupAutoUpdate)||void 0===t||t.call(this),this.viewportObserver.unobserve(document.documentElement),this.targetElement.removeAttribute("aria-expanded"),this.targetElement.removeEventListener("click",this.toggleOpen)}render(){return s`<div class="n-popout ${this.computedPosition} is-${this.direction.dir}" aria-hidden="${this.open?"false":"true"}"><slot></slot></div>`}handleIdChange(){this.id||console.warn("NORD: popout requires an id attribute and value")}handleOpenChange(){this.targetElement.setAttribute("aria-expanded",`${this.open}`)}getToggle(){const t=this.getRootNode().querySelector(`[aria-controls='${this.id}']`);return t instanceof HTMLSlotElement?t.assignedElements()[0]:t}};w.styles=[v,y],t([r()],w.prototype,"open",void 0),t([r()],w.prototype,"computedPosition",void 0),t([r()],w.prototype,"smallViewport",void 0),t([n({reflect:!0})],w.prototype,"align",void 0),t([n({reflect:!0})],w.prototype,"position",void 0),t([n({reflect:!0})],w.prototype,"id",void 0),t([b("id")],w.prototype,"handleIdChange",null),t([b("open")],w.prototype,"handleOpenChange",null),w=t([e("nord-popout")],w);var x=w;export{x as default};
1
+ import{_ as t,n as e}from"./query-assigned-elements-ef860822.js";import{r as o,s as i,$ as s}from"./lit-element-e382250e.js";import{e as n}from"./property-03f59dce.js";import{t as r}from"./state-70f38ceb.js";import{a,c as p,l,o as d,f as h,s as m,h as c}from"./positioning-763efb3a.js";import{L as u}from"./LightDismissController-a2645ae6.js";import{N as f}from"./events-731d0007.js";import{s as v}from"./Component-fa316972.js";import{D as g}from"./DirectionController-8b298382.js";import{o as b}from"./observe-a9c6dfb6.js";import"./EventController-d99ebeef.js";import"./ShortcutController-87615e31.js";import"./tinykeys.module-84e6cc41.js";const y=o`:host{position:fixed;pointer-events:none;z-index:var(--n-index-popout);left:var(--x);top:var(--y);font-size:var(--n-font-size-m);color:var(--n-color-text)}.n-popout{visibility:hidden;opacity:0;pointer-events:none;transition:transform var(--n-transition-slowly),opacity var(--n-transition-slowly),visibility var(--n-transition-slowly);transform:translateY(-10px) scale(.97);transform-origin:top left;will-change:transform,opacity,visibility;background:var(--n-color-surface);box-shadow:var(--n-box-shadow-popout);border-radius:var(--n-border-radius-s)}@media (max-width:35.9375em){:host{inline-size:100%;inset:0;inset-block-start:auto}.n-popout{transition:transform var(--n-transition-mobile),opacity var(--n-transition-mobile),visibility var(--n-transition-mobile);transform:translateY(100%);transform-origin:bottom center;border-radius:0}}.n-popout.top-end,.n-popout.top-start{transform:translateY(10px) scale(.97)}.n-popout.left-start{transform:translateX(10px) scale(.97)}.n-popout.left-end,.n-popout.top-end{transform-origin:bottom right}.n-popout.bottom-end,.n-popout.left-start{transform-origin:top right}.n-popout.left-end{transform:translateX(10px) scale(.97);transform-origin:bottom right}.n-popout.right-end,.n-popout.right-start{transform:translateX(-10px) scale(.97);transform-origin:bottom left}.n-popout.right-start{transform-origin:top left}.n-popout.top-start.is-rtl{transform-origin:top right}.n-popout.top-end.is-rtl{transform-origin:top left}.n-popout.bottom-start.is-rtl{transform-origin:bottom right}.n-popout.bottom-end.is-rtl{transform-origin:bottom left}.n-popout[aria-hidden=false]{transition-property:transform,opacity;visibility:visible;opacity:1;pointer-events:auto;transform:translateY(0) translateX(0) scale(1)}`;let w=class extends i{constructor(){super(...arguments),this.breakpoint="35.9375em",this.viewportObserver=new ResizeObserver((t=>{t.forEach((()=>{this.smallViewport=window.matchMedia(`(max-width: ${this.breakpoint})`).matches,this.smallViewport||(this.cleanupAutoUpdate=a(this.targetElement,this,this.updatePosition))}))})),this.dismiss=new u(this,{isOpen:()=>this.open,onDismiss:t=>this.hide("click"!==t.type),isDismissible:t=>t!==this&&t!==this.targetElement}),this.direction=new g(this),this.open=!1,this.smallViewport=!1,this.align="start",this.position="block-end",this.id="",this.updatePosition=async()=>{var t;const{x:e,y:o,placement:i,middlewareData:s}=await p(this.targetElement,this,{strategy:"fixed",placement:l(this.position,this.align,this.direction.dir),middleware:[d(8),h(),m({padding:8}),c()]});this.computedPosition=i,this.style.setProperty("--x",`${e}px`),this.style.setProperty("--y",`${o}px`),(null===(t=s.hide)||void 0===t?void 0:t.referenceHidden)&&this.hide()},this.toggleOpen=t=>{t.preventDefault(),this.open?this.hide(!1):this.smallViewport?this.show():this.updatePosition().then((()=>this.show()))}}show(){this.open||(this.open=!0,this.smallViewport=window.matchMedia(`(max-width: ${this.breakpoint})`).matches,this.viewportObserver.observe(document.documentElement),this.smallViewport||(this.cleanupAutoUpdate=a(this.targetElement,this,this.updatePosition)),this.updateComplete.then((()=>{this.dispatchEvent(new f("open"))})))}hide(t=!0){var e;this.open&&(this.open=!1,null===(e=this.cleanupAutoUpdate)||void 0===e||e.call(this),this.viewportObserver.unobserve(document.documentElement),this.dispatchEvent(new f("close")),t&&this.targetElement.focus({preventScroll:!0}))}firstUpdated(){this.smallViewport||this.updatePosition()}connectedCallback(){super.connectedCallback(),this.targetElement=this.getToggle(),this.targetElement.addEventListener("click",this.toggleOpen)}disconnectedCallback(){var t;super.disconnectedCallback(),null===(t=this.cleanupAutoUpdate)||void 0===t||t.call(this),this.viewportObserver.unobserve(document.documentElement),this.targetElement.removeAttribute("aria-expanded"),this.targetElement.removeEventListener("click",this.toggleOpen)}render(){return s`<div class="n-popout ${this.computedPosition} is-${this.direction.dir}" aria-hidden="${this.open?"false":"true"}"><slot></slot></div>`}handleIdChange(){this.id||console.warn("NORD: popout requires an id attribute and value")}handleOpenChange(){this.targetElement.setAttribute("aria-expanded",`${this.open}`)}getToggle(){const t=this.getRootNode().querySelector(`[aria-controls='${this.id}']`);return t instanceof HTMLSlotElement?t.assignedElements()[0]:t}};w.styles=[v,y],t([r()],w.prototype,"open",void 0),t([r()],w.prototype,"computedPosition",void 0),t([r()],w.prototype,"smallViewport",void 0),t([n({reflect:!0})],w.prototype,"align",void 0),t([n({reflect:!0})],w.prototype,"position",void 0),t([n({reflect:!0})],w.prototype,"id",void 0),t([b("id")],w.prototype,"handleIdChange",null),t([b("open")],w.prototype,"handleOpenChange",null),w=t([e("nord-popout")],w);var x=w;export{x as default};
2
2
  //# sourceMappingURL=Popout.js.map
package/lib/Popout.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Popout.js","sources":["../src/popout/Popout.ts"],"sourcesContent":["import { LitElement, html } from \"lit\"\nimport { customElement, property, state } from \"lit/decorators.js\"\nimport { computePosition, shift, offset, flip, hide, autoUpdate, Placement } from \"@floating-ui/dom\"\nimport { LightDismissController } from \"../common/controllers/LightDismissController.js\"\nimport { NordEvent } from \"../common/events.js\"\n\nimport componentStyle from \"../common/styles/Component.css\"\nimport style from \"./Popout.css\"\nimport { logicalToPhysical } from \"../common/positioning.js\"\nimport { DirectionController } from \"../common/controllers/DirectionController.js\"\nimport { observe } from \"../common/decorators/observe.js\"\n\n/**\n * Popouts are small overlays that open on demand. They let users access additional content and actions without cluttering the page.\n *\n * @status new\n * @category overlay\n * @slot - The popout content.\n */\n@customElement(\"nord-popout\")\nexport default class Popout extends LitElement {\n static styles = [componentStyle, style]\n\n private targetElement!: HTMLElement\n private cleanupAutoUpdate?: ReturnType<typeof autoUpdate>\n private breakpoint = \"35.9375em\"\n\n // Observe the browser window for resize events\n private viewportObserver = new ResizeObserver(entries => {\n entries.forEach(() => {\n // Update the viewport state\n this.smallViewport = window.matchMedia(`(max-width: ${this.breakpoint})`).matches\n\n // Ensure autoUpdate is ready when going from small to large viewports\n if (!this.smallViewport) {\n this.cleanupAutoUpdate = autoUpdate(this.targetElement, this, this.updatePosition)\n }\n })\n })\n\n /**\n * Handle dismissal of the popout, clicking outside the target button and popout.\n */\n private dismiss = new LightDismissController(this, {\n isOpen: () => this.open,\n onDismiss: e => this.hide(e.type !== \"click\"),\n isDismissible: node => node !== this && node !== this.targetElement,\n })\n\n private direction = new DirectionController(this)\n\n @state() private open = false\n\n @state() private computedPosition?: Placement\n\n @state() private smallViewport = false\n\n /**\n * Set the alignment of the popout in relation to the toggle depending on the position.\n * `start` will align the left of the popout to the left of the toggle.\n * `end` will align the right of the popout to the right of the toggle.\n * A popout with a set position of `inline-start` or `inline-end` will switch\n * `start` and `end` to the top and bottom of the popout respectively.\n */\n @property({ reflect: true }) align: \"start\" | \"end\" = \"start\"\n\n /**\n * Set the position of the popout in relation to the toggle.\n * Options follow logical properties.\n * `block-start` and `block-end` referring to top and bottom respectively,\n * `inline-start` and `inline-end` referring to left and right respectively.\n */\n @property({ reflect: true }) position: \"block-end\" | \"block-start\" | \"inline-start\" | \"inline-end\" = \"block-end\"\n\n /**\n * The id for the active element to reference via aria-controls.\n */\n @property({ reflect: true }) id: string = \"\"\n\n /**\n * Show the popout, moving focus to the calendar inside.\n */\n show() {\n if (this.open) {\n return\n }\n\n this.open = true\n\n // Check the viewport width on show and update the state\n this.smallViewport = window.matchMedia(`(max-width: ${this.breakpoint})`).matches\n\n // Observe the document element, ergo the browser width\n this.viewportObserver.observe(document.documentElement)\n\n if (!this.smallViewport) {\n this.cleanupAutoUpdate = autoUpdate(this.targetElement, this, this.updatePosition)\n }\n\n // we should only focus once the popout is visible after render is complete\n this.updateComplete.then(() => {\n /**\n * Dispatched when the popout is opened.\n */\n this.dispatchEvent(new NordEvent(\"open\"))\n })\n }\n\n /**\n * Hide the popout.\n * @param {boolean} moveFocusToButton prevent focus returning to the target\n * button. Default is true.\n */\n hide(moveFocusToButton = true) {\n if (!this.open) {\n return\n }\n\n this.open = false\n\n this.cleanupAutoUpdate?.()\n\n // Stop observing the browser width when the popout is hidden\n this.viewportObserver.unobserve(document.documentElement)\n\n /**\n * Dispatched when the popout is closed.\n */\n this.dispatchEvent(new NordEvent(\"close\"))\n\n if (moveFocusToButton) {\n this.targetElement.focus({ preventScroll: true })\n }\n }\n\n /**\n * Position the popout on load.\n */\n firstUpdated() {\n if (!this.smallViewport) {\n this.updatePosition()\n }\n }\n\n connectedCallback() {\n super.connectedCallback()\n\n this.targetElement = this.getToggle()\n this.targetElement.addEventListener(\"click\", this.toggleOpen)\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n\n this.cleanupAutoUpdate?.()\n\n // Ensure we've stopped observing the document element\n this.viewportObserver.unobserve(document.documentElement)\n\n this.targetElement.removeAttribute(\"aria-expanded\")\n this.targetElement.removeEventListener(\"click\", this.toggleOpen)\n }\n\n render() {\n return html`\n <div\n class=\"n-popout ${this.computedPosition} is-${this.direction.dir}\"\n aria-hidden=${this.open ? \"false\" : \"true\"}\n >\n <slot></slot>\n </div>\n `\n }\n\n @observe(\"id\")\n protected handleIdChange() {\n if (!this.id) {\n // eslint-disable-next-line no-console\n console.warn(\"NORD: popout requires an id attribute and value\")\n }\n }\n\n @observe(\"open\")\n protected handleOpenChange() {\n this.targetElement.setAttribute(\"aria-expanded\", `${this.open}`)\n }\n\n /**\n * Get the position of the element toggling the popout\n * and position the popout underneath it, taking into account the optional placement.\n */\n private updatePosition = async () => {\n const { x, y, placement, middlewareData } = await computePosition(this.targetElement, this, {\n strategy: \"fixed\",\n placement: logicalToPhysical(this.position, this.align, this.direction.dir),\n middleware: [\n offset(8),\n flip(),\n shift({\n padding: 8,\n }),\n hide(),\n ],\n })\n\n this.computedPosition = placement\n\n // use physical properties here since floating-ui\n // works exclusively in physical dimensions\n // we do all the mapping in logicalToPhysical\n this.style.setProperty(\"--x\", `${x}px`)\n this.style.setProperty(\"--y\", `${y}px`)\n\n if (middlewareData.hide?.referenceHidden) {\n this.hide()\n }\n }\n\n /**\n * Toggle the popout open or closed using state.\n * Updating the position to underneath the target button before the popout is opened.\n */\n private toggleOpen = (e: Event) => {\n e.preventDefault()\n if (this.open) {\n this.hide(false)\n } else if (!this.smallViewport) {\n this.updatePosition().then(() => this.show())\n } else {\n this.show()\n }\n }\n\n private getToggle() {\n const rootNode = this.getRootNode() as Document | ShadowRoot\n const toggle = <HTMLElement>rootNode.querySelector(`[aria-controls='${this.id}']`)\n\n if (toggle instanceof HTMLSlotElement) {\n return toggle.assignedElements()[0] as HTMLElement\n }\n\n return toggle\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"nord-popout\": Popout\n }\n}\n"],"names":["Popout","LitElement","constructor","this","breakpoint","viewportObserver","ResizeObserver","entries","forEach","smallViewport","window","matchMedia","matches","cleanupAutoUpdate","autoUpdate","targetElement","updatePosition","dismiss","LightDismissController","isOpen","open","onDismiss","e","hide","type","isDismissible","node","direction","DirectionController","align","position","id","async","x","y","placement","middlewareData","computePosition","strategy","logicalToPhysical","dir","middleware","offset","flip","shift","padding","computedPosition","style","setProperty","_a","referenceHidden","toggleOpen","preventDefault","show","then","observe","document","documentElement","updateComplete","dispatchEvent","NordEvent","moveFocusToButton","call","unobserve","focus","preventScroll","firstUpdated","connectedCallback","super","getToggle","addEventListener","disconnectedCallback","removeAttribute","removeEventListener","render","html","handleIdChange","console","warn","handleOpenChange","setAttribute","toggle","getRootNode","querySelector","HTMLSlotElement","assignedElements","styles","componentStyle","__decorate","state","prototype","property","reflect","customElement"],"mappings":"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"}
1
+ {"version":3,"file":"Popout.js","sources":["../src/popout/Popout.ts"],"sourcesContent":["import { LitElement, html } from \"lit\"\nimport { customElement, property, state } from \"lit/decorators.js\"\nimport { computePosition, shift, offset, flip, hide, autoUpdate, Placement } from \"@floating-ui/dom\"\nimport { LightDismissController } from \"../common/controllers/LightDismissController.js\"\nimport { NordEvent } from \"../common/events.js\"\n\nimport componentStyle from \"../common/styles/Component.css\"\nimport style from \"./Popout.css\"\nimport { logicalToPhysical } from \"../common/positioning.js\"\nimport { DirectionController } from \"../common/controllers/DirectionController.js\"\nimport { observe } from \"../common/decorators/observe.js\"\n\n/**\n * Popouts are small overlays that open on demand. They let users access additional content and actions without cluttering the page.\n *\n * @status new\n * @category overlay\n * @slot - The popout content.\n */\n@customElement(\"nord-popout\")\nexport default class Popout extends LitElement {\n static styles = [componentStyle, style]\n\n private targetElement!: HTMLElement\n private cleanupAutoUpdate?: ReturnType<typeof autoUpdate>\n private breakpoint = \"35.9375em\"\n\n // Observe the browser window for resize events\n private viewportObserver = new ResizeObserver(entries => {\n entries.forEach(() => {\n // Update the viewport state\n this.smallViewport = window.matchMedia(`(max-width: ${this.breakpoint})`).matches\n\n // Ensure autoUpdate is ready when going from small to large viewports\n if (!this.smallViewport) {\n this.cleanupAutoUpdate = autoUpdate(this.targetElement, this, this.updatePosition)\n }\n })\n })\n\n /**\n * Handle dismissal of the popout, clicking outside the target button and popout.\n */\n private dismiss = new LightDismissController(this, {\n isOpen: () => this.open,\n onDismiss: e => this.hide(e.type !== \"click\"),\n isDismissible: node => node !== this && node !== this.targetElement,\n })\n\n private direction = new DirectionController(this)\n\n @state() private open = false\n\n @state() private computedPosition?: Placement\n\n @state() private smallViewport = false\n\n /**\n * Set the alignment of the popout in relation to the toggle depending on the position.\n * `start` will align the left of the popout to the left of the toggle.\n * `end` will align the right of the popout to the right of the toggle.\n * A popout with a set position of `inline-start` or `inline-end` will switch\n * `start` and `end` to the top and bottom of the popout respectively.\n */\n @property({ reflect: true }) align: \"start\" | \"end\" = \"start\"\n\n /**\n * Set the position of the popout in relation to the toggle.\n * Options follow logical properties.\n * `block-start` and `block-end` referring to top and bottom respectively,\n * `inline-start` and `inline-end` referring to left and right respectively.\n */\n @property({ reflect: true }) position: \"block-end\" | \"block-start\" | \"inline-start\" | \"inline-end\" = \"block-end\"\n\n /**\n * The id for the active element to reference via aria-controls.\n */\n @property({ reflect: true }) id: string = \"\"\n\n /**\n * Show the popout, moving focus to the calendar inside.\n */\n show() {\n if (this.open) {\n return\n }\n\n this.open = true\n\n // Check the viewport width on show and update the state\n this.smallViewport = window.matchMedia(`(max-width: ${this.breakpoint})`).matches\n\n // Observe the document element, ergo the browser width\n this.viewportObserver.observe(document.documentElement)\n\n if (!this.smallViewport) {\n this.cleanupAutoUpdate = autoUpdate(this.targetElement, this, this.updatePosition)\n }\n\n // we should only focus once the popout is visible after render is complete\n this.updateComplete.then(() => {\n /**\n * Dispatched when the popout is opened.\n */\n this.dispatchEvent(new NordEvent(\"open\"))\n })\n }\n\n /**\n * Hide the popout.\n * @param {boolean} moveFocusToButton prevent focus returning to the target\n * button. Default is true.\n */\n hide(moveFocusToButton = true) {\n if (!this.open) {\n return\n }\n\n this.open = false\n\n this.cleanupAutoUpdate?.()\n\n // Stop observing the browser width when the popout is hidden\n this.viewportObserver.unobserve(document.documentElement)\n\n /**\n * Dispatched when the popout is closed.\n */\n this.dispatchEvent(new NordEvent(\"close\"))\n\n if (moveFocusToButton) {\n this.targetElement.focus({ preventScroll: true })\n }\n }\n\n /**\n * Position the popout on load.\n */\n firstUpdated() {\n if (!this.smallViewport) {\n this.updatePosition()\n }\n }\n\n connectedCallback() {\n super.connectedCallback()\n\n this.targetElement = this.getToggle()\n this.targetElement.addEventListener(\"click\", this.toggleOpen)\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n\n this.cleanupAutoUpdate?.()\n\n // Ensure we've stopped observing the document element\n this.viewportObserver.unobserve(document.documentElement)\n\n this.targetElement.removeAttribute(\"aria-expanded\")\n this.targetElement.removeEventListener(\"click\", this.toggleOpen)\n }\n\n render() {\n return html`\n <div\n class=\"n-popout ${this.computedPosition} is-${this.direction.dir}\"\n aria-hidden=${this.open ? \"false\" : \"true\"}\n >\n <slot></slot>\n </div>\n `\n }\n\n @observe(\"id\")\n protected handleIdChange() {\n if (!this.id) {\n // eslint-disable-next-line no-console\n console.warn(\"NORD: popout requires an id attribute and value\")\n }\n }\n\n @observe(\"open\")\n protected handleOpenChange() {\n this.targetElement.setAttribute(\"aria-expanded\", `${this.open}`)\n }\n\n /**\n * Get the position of the element toggling the popout\n * and position the popout underneath it, taking into account the optional placement.\n */\n private updatePosition = async () => {\n const { x, y, placement, middlewareData } = await computePosition(this.targetElement, this, {\n strategy: \"fixed\",\n placement: logicalToPhysical(this.position, this.align, this.direction.dir),\n middleware: [\n offset(8),\n flip(),\n shift({\n padding: 8,\n }),\n hide(),\n ],\n })\n\n this.computedPosition = placement\n\n // use physical properties here since floating-ui\n // works exclusively in physical dimensions\n // we do all the mapping in logicalToPhysical\n this.style.setProperty(\"--x\", `${x}px`)\n this.style.setProperty(\"--y\", `${y}px`)\n\n if (middlewareData.hide?.referenceHidden) {\n this.hide()\n }\n }\n\n /**\n * Toggle the popout open or closed using state.\n * Updating the position to underneath the target button before the popout is opened.\n */\n private toggleOpen = (e: Event) => {\n e.preventDefault()\n if (this.open) {\n this.hide(false)\n } else if (!this.smallViewport) {\n this.updatePosition().then(() => this.show())\n } else {\n this.show()\n }\n }\n\n private getToggle() {\n const rootNode = this.getRootNode() as Document | ShadowRoot\n const toggle = <HTMLElement>rootNode.querySelector(`[aria-controls='${this.id}']`)\n\n if (toggle instanceof HTMLSlotElement) {\n return toggle.assignedElements()[0] as HTMLElement\n }\n\n return toggle\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"nord-popout\": Popout\n }\n}\n"],"names":["Popout","LitElement","constructor","this","breakpoint","viewportObserver","ResizeObserver","entries","forEach","smallViewport","window","matchMedia","matches","cleanupAutoUpdate","autoUpdate","targetElement","updatePosition","dismiss","LightDismissController","isOpen","open","onDismiss","e","hide","type","isDismissible","node","direction","DirectionController","align","position","id","async","x","y","placement","middlewareData","computePosition","strategy","logicalToPhysical","dir","middleware","offset","flip","shift","padding","computedPosition","style","setProperty","_a","referenceHidden","toggleOpen","preventDefault","show","then","observe","document","documentElement","updateComplete","dispatchEvent","NordEvent","moveFocusToButton","call","unobserve","focus","preventScroll","firstUpdated","connectedCallback","super","getToggle","addEventListener","disconnectedCallback","removeAttribute","removeEventListener","render","html","handleIdChange","console","warn","handleOpenChange","setAttribute","toggle","getRootNode","querySelector","HTMLSlotElement","assignedElements","styles","componentStyle","__decorate","state","prototype","property","reflect","customElement"],"mappings":"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"}