@nysds/nys-dropdownmenu 1.16.1 → 1.18.0
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/dist/nys-dropdownmenu.js +37 -29
- package/dist/nys-dropdownmenu.js.map +1 -1
- package/package.json +2 -2
package/dist/nys-dropdownmenu.js
CHANGED
|
@@ -5,15 +5,15 @@ import { property as a } from "lit/decorators.js";
|
|
|
5
5
|
* █ █ █ █▄▄▄█ ▀▀▀▄▄ █ █ ▀▀▀▄▄
|
|
6
6
|
* █ ▀█ █ █▄▄▄█ █▄▄▀ █▄▄▄█
|
|
7
7
|
*
|
|
8
|
-
* Dropdownmenu Component v1.
|
|
8
|
+
* Dropdownmenu Component v1.18.0
|
|
9
9
|
* Part of the New York State Design System
|
|
10
10
|
* Repository: https://github.com/its-hcd/nysds
|
|
11
11
|
* License: MIT
|
|
12
12
|
*/
|
|
13
|
-
const _ = ':host{--_nys-dropdownmenu-width: 180px;--_nys-dropdownmenu-height: 100%;--_nys-dropdownmenu-radius: var(--nys-radius-md, 4px);--_nys-dropdownmenu-border-width: var(--nys-border-width-sm, 1px);--_nys-dropdownmenu-border-color: var(--nys-color-neutral-100, #d0d0ce);--_nys-dropdownmenu-background-color: var(--nys-color-ink-reverse, #ffffff);--_nys-dropdownmenu-boxshadow-color-100: var( --nys-color-black-transparent-100, rgba(27, 27, 27, .1) );--_nys-dropdownmenu-boxshadow-color-50: var( --nys-color-black-transparent-50, rgba(27, 27, 27, .01) );--_nys-dropdownmenu-gap: var(--nys-space-2px, 2px);--_nys-dropdownmenu-padding: var(--nys-space-100, 8px);--_nys-dropdownmenu-font-size: var(--nys-font-size-ui-md, 16px);--_nys-dropdownmenu-font-weight: var(font-weight: 400);--_nys-dropdownmenu-line-height: var(--nys-font-lineheight-ui-md, 24px);--_nys-dropdownmenu-font-family: var( --nys-font-family-ui, var( --nys-font-family-sans, "Proxima Nova", "Helvetica Neue", "Helvetica", "Arial", sans-serif ) );--_nys-dropdownmenuitem-color: var(--nys-color-text, #1b1b1b);--_nys-dropdownmenuitem-gap: var(--nys-space-100, 8px);--_nys-dropdownmenuitem-padding: var(--nys-space-200, 16px) var(--nys-space-100, 8px);--_nys-dropdownmenuitem-border-radius: var(--nys-radius-md, 4px);--_nys-dropdownmenuitem-background-color: var(--nys-color-white, #ffffff);--_nys-dropdownmenuitem-background-color--hover: var( --nys-color-neutral-10, #f6f6f6 );--_nys-dropdownmenuitem-background-color--active: var( --nys-color-neutral-50, #ededed );--_nys-dropdownmenuitem-color--disabled: var( --nys-color-text-disabled, #bec0c1 );--_nys-dropdownmenuitem-outline-width: var(--nys-border-width-md, 2px);--_nys-dropdownmenuitem-outline-color: var(--nys-color-focus, #004dd1)}.nys-dropdownmenu{position:fixed;top:0;left:0;z-index:1776}.nys-dropdownmenu.active ul{display:flex}.nys-dropdownmenu ul{display:none;align-items:flex-start;flex-direction:column;gap:var(--_nys-dropdownmenu-gap);width:var(--_nys-dropdownmenu-width);height:var(--_nys-dropdownmenu-height);border-radius:var(--_nys-dropdownmenu-radius);border:var(--_nys-dropdownmenu-border-width) solid var(--_nys-dropdownmenu-border-color);background-color:var(--_nys-dropdownmenu-background-color);box-shadow:0 4px 6px -1px var(--_nys-dropdownmenu-boxshadow-color-100),0 4px 6px -1px var(--_nys-dropdownmenu-boxshadow-color-50);padding:var(--_nys-dropdownmenu-padding);font-family:var(--_nys-dropdownmenu-font-family);font-size:var(--_nys-dropdownmenu-font-size);font-weight:var(--_nys-dropdownmenu-font-weight);line-height:var(--_nys-dropdownmenu-line-height);overflow:hidden;margin:0}.nys-dropdownmenuitem{list-style:none;width:var(--_nys-dropdownmenu-width);padding:0;margin:0}.nys-dropdownmenuitem a,.nys-dropdownmenuitem button{display:flex;gap:var(--_nys-dropdownmenuitem-gap);padding:var(--_nys-dropdownmenuitem-padding);border-radius:var(--_nys-dropdownmenuitem-border-radius);background-color:var(--_nys-dropdownmenuitem-background-color);width:100%;box-sizing:border-box;text-decoration:none;text-wrap:wrap;color:var(--_nys-dropdownmenuitem-color);transition:.05s ease-in-out all;border:none;font-family:var(--_nys-dropdownmenu-font-family);font-size:var(--_nys-dropdownmenu-font-size);font-weight:var(--_nys-dropdownmenu-font-weight);line-height:var(--_nys-dropdownmenu-line-height);cursor:pointer}.nys-dropdownmenuitem a nys-icon,.nys-dropdownmenuitem button nys-icon{margin-top:2.5px}.nys-dropdownmenuitem a:hover:not(.disabled):not([aria-disabled=true]),.nys-dropdownmenuitem button:hover:not(.disabled):not([aria-disabled=true]){background-color:var(--_nys-dropdownmenuitem-background-color--hover)}.nys-dropdownmenuitem a:active:not(.disabled):not([aria-disabled=true]),.nys-dropdownmenuitem button:active:not(.disabled):not([aria-disabled=true]){background-color:var(--_nys-dropdownmenuitem-background-color--active)}.nys-dropdownmenuitem a:focus-visible:not(
|
|
13
|
+
const _ = ':host{--_nys-dropdownmenu-width: 180px;--_nys-dropdownmenu-height: 100%;--_nys-dropdownmenu-radius: var(--nys-radius-md, 4px);--_nys-dropdownmenu-border-width: var(--nys-border-width-sm, 1px);--_nys-dropdownmenu-border-color: var(--nys-color-neutral-100, #d0d0ce);--_nys-dropdownmenu-background-color: var(--nys-color-ink-reverse, #ffffff);--_nys-dropdownmenu-boxshadow-color-100: var( --nys-color-black-transparent-100, rgba(27, 27, 27, .1) );--_nys-dropdownmenu-boxshadow-color-50: var( --nys-color-black-transparent-50, rgba(27, 27, 27, .01) );--_nys-dropdownmenu-gap: var(--nys-space-2px, 2px);--_nys-dropdownmenu-padding: var(--nys-space-100, 8px);--_nys-dropdownmenu-font-size: var(--nys-font-size-ui-md, 16px);--_nys-dropdownmenu-font-weight: var(font-weight: 400);--_nys-dropdownmenu-line-height: var(--nys-font-lineheight-ui-md, 24px);--_nys-dropdownmenu-font-family: var( --nys-font-family-ui, var( --nys-font-family-sans, "Proxima Nova", "Helvetica Neue", "Helvetica", "Arial", sans-serif ) );--_nys-dropdownmenuitem-color: var(--nys-color-text, #1b1b1b);--_nys-dropdownmenuitem-gap: var(--nys-space-100, 8px);--_nys-dropdownmenuitem-padding: var(--nys-space-200, 16px) var(--nys-space-100, 8px);--_nys-dropdownmenuitem-border-radius: var(--nys-radius-md, 4px);--_nys-dropdownmenuitem-background-color: var(--nys-color-white, #ffffff);--_nys-dropdownmenuitem-background-color--hover: var( --nys-color-neutral-10, #f6f6f6 );--_nys-dropdownmenuitem-background-color--active: var( --nys-color-neutral-50, #ededed );--_nys-dropdownmenuitem-color--disabled: var( --nys-color-text-disabled, #bec0c1 );--_nys-dropdownmenuitem-outline-width: var(--nys-border-width-md, 2px);--_nys-dropdownmenuitem-outline-color: var(--nys-color-focus, #004dd1)}.nys-dropdownmenu{position:fixed;top:0;left:0;z-index:1776}.nys-dropdownmenu.active ul{display:flex}.nys-dropdownmenu ul{display:none;align-items:flex-start;flex-direction:column;gap:var(--_nys-dropdownmenu-gap);width:var(--_nys-dropdownmenu-width);height:var(--_nys-dropdownmenu-height);border-radius:var(--_nys-dropdownmenu-radius);border:var(--_nys-dropdownmenu-border-width) solid var(--_nys-dropdownmenu-border-color);background-color:var(--_nys-dropdownmenu-background-color);box-shadow:0 4px 6px -1px var(--_nys-dropdownmenu-boxshadow-color-100),0 4px 6px -1px var(--_nys-dropdownmenu-boxshadow-color-50);padding:var(--_nys-dropdownmenu-padding);font-family:var(--_nys-dropdownmenu-font-family);font-size:var(--_nys-dropdownmenu-font-size);font-weight:var(--_nys-dropdownmenu-font-weight);line-height:var(--_nys-dropdownmenu-line-height);overflow:hidden;margin:0}.nys-dropdownmenuitem{list-style:none;width:var(--_nys-dropdownmenu-width);padding:0;margin:0}.nys-dropdownmenuitem a,.nys-dropdownmenuitem button{display:flex;gap:var(--_nys-dropdownmenuitem-gap);padding:var(--_nys-dropdownmenuitem-padding);border-radius:var(--_nys-dropdownmenuitem-border-radius);background-color:var(--_nys-dropdownmenuitem-background-color);width:100%;box-sizing:border-box;text-decoration:none;text-wrap:wrap;color:var(--_nys-dropdownmenuitem-color);transition:.05s ease-in-out all;border:none;font-family:var(--_nys-dropdownmenu-font-family);font-size:var(--_nys-dropdownmenu-font-size);font-weight:var(--_nys-dropdownmenu-font-weight);line-height:var(--_nys-dropdownmenu-line-height);cursor:pointer}.nys-dropdownmenuitem a nys-icon,.nys-dropdownmenuitem button nys-icon{margin-top:2.5px}.nys-dropdownmenuitem a:hover:not(.disabled):not([aria-disabled=true]),.nys-dropdownmenuitem button:hover:not(.disabled):not([aria-disabled=true]){background-color:var(--_nys-dropdownmenuitem-background-color--hover)}.nys-dropdownmenuitem a:active:not(.disabled):not([aria-disabled=true]),.nys-dropdownmenuitem button:active:not(.disabled):not([aria-disabled=true]){background-color:var(--_nys-dropdownmenuitem-background-color--active)}.nys-dropdownmenuitem a:focus-visible:not(.disabled):not([aria-disabled=true]):not([focus-ring-false]),.nys-dropdownmenuitem button:focus-visible:not(.disabled):not([aria-disabled=true]):not([focus-ring-false]){position:relative;outline:var(--_nys-dropdownmenuitem-outline-width) solid var(--_nys-dropdownmenuitem-outline-color)}.nys-dropdownmenuitem a.disabled,.nys-dropdownmenuitem a[aria-disabled=true],.nys-dropdownmenuitem button.disabled,.nys-dropdownmenuitem button[aria-disabled=true]{color:var(--_nys-dropdownmenuitem-color--disabled);pointer-events:none;cursor:default}';
|
|
14
14
|
var v = Object.defineProperty, c = (h, e, t, n) => {
|
|
15
|
-
for (var o = void 0, i = h.length - 1,
|
|
16
|
-
(
|
|
15
|
+
for (var o = void 0, i = h.length - 1, s; i >= 0; i--)
|
|
16
|
+
(s = h[i]) && (o = s(e, t, o) || o);
|
|
17
17
|
return o && v(e, t, o), o;
|
|
18
18
|
};
|
|
19
19
|
let x = 0;
|
|
@@ -100,8 +100,8 @@ c([
|
|
|
100
100
|
], d.prototype, "divider");
|
|
101
101
|
customElements.get("nys-dropdownmenuitem") || customElements.define("nys-dropdownmenuitem", d);
|
|
102
102
|
var k = Object.defineProperty, f = (h, e, t, n) => {
|
|
103
|
-
for (var o = void 0, i = h.length - 1,
|
|
104
|
-
(
|
|
103
|
+
for (var o = void 0, i = h.length - 1, s; i >= 0; i--)
|
|
104
|
+
(s = h[i]) && (o = s(e, t, o) || o);
|
|
105
105
|
return o && k(e, t, o), o;
|
|
106
106
|
};
|
|
107
107
|
let E = 0;
|
|
@@ -111,10 +111,10 @@ const y = class y extends w {
|
|
|
111
111
|
* --------------------------------------------------------------------------
|
|
112
112
|
*/
|
|
113
113
|
constructor() {
|
|
114
|
-
super(), this.for = "", this.showDropdown = !1, this.position = null, this._trigger = null, this._menuElement = null, this._ariaTarget = null, this.GAP = 4, this._toggleDropdown = async () => {
|
|
114
|
+
super(), this.for = "", this.showDropdown = !1, this.position = null, this._trigger = null, this._menuElement = null, this._ariaTarget = null, this._lastFocusedIndex = 0, this.GAP = 4, this._toggleDropdown = async () => {
|
|
115
115
|
this.showDropdown = !this.showDropdown, this._ariaTarget?.setAttribute("aria-expanded", String(this.showDropdown)), this.showDropdown ? (window.addEventListener("scroll", this._handleWindowScroll, !0), window.addEventListener("resize", this._handleWindowResize), document.addEventListener("click", this._handleDocumentClick), this._menuElement = this.shadowRoot?.querySelector(
|
|
116
116
|
".nys-dropdownmenu"
|
|
117
|
-
), this._menuElement.addEventListener("keydown", this._handleMenuKeydown), await this.updateComplete, this._positionMenu(), this.
|
|
117
|
+
), this._menuElement.addEventListener("keydown", this._handleMenuKeydown), await this.updateComplete, this._positionMenu(), this._focusOnItem(this._lastFocusedIndex)) : (window.removeEventListener("scroll", this._handleWindowScroll, !0), window.removeEventListener("resize", this._handleWindowResize), document.removeEventListener("click", this._handleDocumentClick), this._menuElement.removeEventListener(
|
|
118
118
|
"keydown",
|
|
119
119
|
this._handleMenuKeydown
|
|
120
120
|
));
|
|
@@ -134,13 +134,13 @@ const y = class y extends w {
|
|
|
134
134
|
case "ArrowRight":
|
|
135
135
|
e.preventDefault();
|
|
136
136
|
const o = n < t.length - 1 ? n + 1 : 0;
|
|
137
|
-
t[o].focus();
|
|
137
|
+
this._lastFocusedIndex = o, t[o].focus();
|
|
138
138
|
break;
|
|
139
139
|
case "ArrowUp":
|
|
140
140
|
case "ArrowLeft":
|
|
141
141
|
e.preventDefault();
|
|
142
142
|
const i = n > 0 ? n - 1 : t.length - 1;
|
|
143
|
-
t[i].focus();
|
|
143
|
+
this._lastFocusedIndex = i, t[i].focus();
|
|
144
144
|
break;
|
|
145
145
|
case "Tab":
|
|
146
146
|
n >= t.length - 1 && !e.shiftKey && this._closeDropdown();
|
|
@@ -160,9 +160,7 @@ const y = class y extends w {
|
|
|
160
160
|
super.disconnectedCallback();
|
|
161
161
|
}
|
|
162
162
|
async firstUpdated() {
|
|
163
|
-
await this.updateComplete, this.applyInverseTransform(), this._connectTrigger(), this.
|
|
164
|
-
this._closeDropdown();
|
|
165
|
-
});
|
|
163
|
+
await this.updateComplete, this.applyInverseTransform(), this._connectTrigger(), this._handleMenuClick();
|
|
166
164
|
}
|
|
167
165
|
/**
|
|
168
166
|
* Functions
|
|
@@ -175,11 +173,11 @@ const y = class y extends w {
|
|
|
175
173
|
if (t) return t;
|
|
176
174
|
const n = (o) => {
|
|
177
175
|
for (const i of Array.from(o.querySelectorAll("*"))) {
|
|
178
|
-
const
|
|
179
|
-
if (
|
|
180
|
-
const
|
|
181
|
-
if (
|
|
182
|
-
const p = n(
|
|
176
|
+
const s = i.shadowRoot;
|
|
177
|
+
if (s) {
|
|
178
|
+
const r = s.getElementById(e);
|
|
179
|
+
if (r) return r;
|
|
180
|
+
const p = n(s);
|
|
183
181
|
if (p) return p;
|
|
184
182
|
}
|
|
185
183
|
}
|
|
@@ -202,10 +200,10 @@ const y = class y extends w {
|
|
|
202
200
|
(n) => n && !n.hasAttribute("disabled")
|
|
203
201
|
);
|
|
204
202
|
}
|
|
205
|
-
async
|
|
206
|
-
await new Promise((
|
|
207
|
-
const
|
|
208
|
-
|
|
203
|
+
async _focusOnItem(e = 0) {
|
|
204
|
+
await new Promise((o) => requestAnimationFrame(o));
|
|
205
|
+
const t = this._getMenuItems(), n = t[Math.min(e, t.length - 1)];
|
|
206
|
+
n && n.focus();
|
|
209
207
|
}
|
|
210
208
|
// In some iframes (like Storybook's) or embedded containers , parent elements may have CSS transforms applied, creating a new coordinate context.
|
|
211
209
|
// This function removes such transforms to prevent them from affecting tooltip positioning calculations.
|
|
@@ -261,7 +259,7 @@ const y = class y extends w {
|
|
|
261
259
|
};
|
|
262
260
|
}
|
|
263
261
|
_checkPositionFits(e, t, n) {
|
|
264
|
-
const o = n.width, i = n.height, [
|
|
262
|
+
const o = n.width, i = n.height, [s, r] = e.split("-"), p = s === "bottom" ? t.bottom >= i + this.GAP : t.top >= i + this.GAP, b = r === "start" ? t.end >= o : t.start >= o;
|
|
265
263
|
return p && b;
|
|
266
264
|
}
|
|
267
265
|
/**
|
|
@@ -272,7 +270,7 @@ const y = class y extends w {
|
|
|
272
270
|
* @param menuRect
|
|
273
271
|
*/
|
|
274
272
|
_findBestAlternative(e, t, n) {
|
|
275
|
-
const [o, i] = e.split("-"),
|
|
273
|
+
const [o, i] = e.split("-"), s = [
|
|
276
274
|
`${o === "bottom" ? "top" : "bottom"}-${i}`,
|
|
277
275
|
// Flip vertical
|
|
278
276
|
`${o}-${i === "start" ? "end" : "start"}`,
|
|
@@ -280,9 +278,9 @@ const y = class y extends w {
|
|
|
280
278
|
`${o === "bottom" ? "top" : "bottom"}-${i === "start" ? "end" : "start"}`
|
|
281
279
|
// Flip both
|
|
282
280
|
];
|
|
283
|
-
for (const
|
|
284
|
-
if (this._checkPositionFits(
|
|
285
|
-
return
|
|
281
|
+
for (const r of s)
|
|
282
|
+
if (this._checkPositionFits(r, t, n))
|
|
283
|
+
return r;
|
|
286
284
|
return this._findMostAvailableSpace(t);
|
|
287
285
|
}
|
|
288
286
|
_findMostAvailableSpace(e) {
|
|
@@ -299,12 +297,22 @@ const y = class y extends w {
|
|
|
299
297
|
if (!this._trigger || !this._menuElement)
|
|
300
298
|
return { top: 0, left: 0 };
|
|
301
299
|
const t = this._trigger.getBoundingClientRect(), n = this._menuElement.getBoundingClientRect(), [o, i] = e.split("-");
|
|
302
|
-
let
|
|
303
|
-
return o === "bottom" ?
|
|
300
|
+
let s = 0, r = 0;
|
|
301
|
+
return o === "bottom" ? s = t.bottom + this.GAP : s = t.top - n.height - this.GAP, i === "start" ? r = t.left : r = t.right - n.width, { top: s, left: r };
|
|
304
302
|
}
|
|
305
303
|
_applyPosition(e) {
|
|
306
304
|
this._menuElement && (this._menuElement.style.top = `${e.top}px`, this._menuElement.style.left = `${e.left}px`);
|
|
307
305
|
}
|
|
306
|
+
/**
|
|
307
|
+
* Event Handlers
|
|
308
|
+
* --------------------------------------------------------------------------
|
|
309
|
+
*/
|
|
310
|
+
_handleMenuClick() {
|
|
311
|
+
this.addEventListener("nys-click", (e) => {
|
|
312
|
+
const t = this._getMenuItems(), n = e.detail?.id, o = t.findIndex((i) => i.id === n);
|
|
313
|
+
o !== -1 && (this._lastFocusedIndex = o), this._closeDropdown();
|
|
314
|
+
});
|
|
315
|
+
}
|
|
308
316
|
render() {
|
|
309
317
|
return l`<div
|
|
310
318
|
class="nys-dropdownmenu ${this.showDropdown ? "active" : ""}"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nys-dropdownmenu.js","sources":["../src/nys-dropdownmenuitem.ts","../src/nys-dropdownmenu.ts"],"sourcesContent":["import { LitElement, html, unsafeCSS } from \"lit\";\nimport { property } from \"lit/decorators.js\";\n// @ts-ignore: SCSS module imported via bundler as inline\nimport styles from \"./nys-dropdownmenu.scss?inline\";\n\nlet dropdownMenuItemIdCounter = 0;\n\n/**\n * **Slotted component.** Displays an individual dropdown item within `nys-dropdown` with label.\n *\n * The `nys-dropdownitem` is used as customizable item within the dropdown so users don't have to raw code <ul>, <li>, <a href>\n * and have the benefit of default customization.\n *\n * @summary Dropdown item to display label and provide href link.\n * @element nys-dropdownmenuitem\n *\n * @example Basic item\n * ```html\n * <nys-dropdownmenuitem label=\"Edit\" link=\"/edit\"></nys-dropdownmenuitem>\n * ```\n *\n * @example Disabled item\n * ```html\n * <nys-dropdownmenuitem label=\"Delete\" link=\"/delete\" disabled></nys-dropdownmenuitem>\n * ```\n */\nexport class NysDropdownMenuItem extends LitElement {\n static styles = unsafeCSS(styles);\n static shadowRootOptions = {\n ...LitElement.shadowRootOptions,\n delegatesFocus: true,\n };\n\n @property({ type: String }) label = \"\";\n @property({ type: String }) href = \"\";\n @property({ type: Boolean, reflect: true }) disabled = false;\n @property({ type: String }) target = \"_self\";\n @property({ type: String }) prefixIcon = \"\";\n @property({ type: String }) divider = \"\";\n\n // Generate a unique ID if one is not provided\n connectedCallback() {\n super.connectedCallback();\n if (!this.id) {\n this.id = `nys-dropdownmenuitem-${Date.now()}-${dropdownMenuItemIdCounter++}`;\n }\n }\n\n private _handleClick(e: Event) {\n if (this.disabled) {\n e.preventDefault();\n return;\n }\n\n this.dispatchEvent(\n new CustomEvent(\"nys-click\", {\n bubbles: true,\n composed: true,\n detail: {\n id: this.id,\n label: this.label,\n ...(this.href && { href: this.href }),\n },\n }),\n );\n }\n\n render() {\n const isLink = !!this.href;\n\n return html`<li class=\"nys-dropdownmenuitem\" role=\"presentation\">\n ${isLink\n ? html` <a\n class=${this.disabled ? \"disabled\" : \"\"}\n href=${this.disabled ? \"\" : this.href}\n role=\"menuitem\"\n aria-disabled=\"${this.disabled ? \"true\" : \"false\"}\"\n aria-label=${this.label}\n tabindex=${this.disabled ? \"-1\" : \"0\"}\n @click=\"${this._handleClick}\"\n target=\"${this.target}\"\n >\n ${this.prefixIcon\n ? html`<nys-icon size=\"16\" name=${this.prefixIcon}></nys-icon>`\n : \"\"}\n ${this.label}</a\n >`\n : html`\n <button\n class=${this.disabled ? \"disabled\" : \"\"}\n type=\"button\"\n role=\"menuitem\"\n aria-disabled=\"${this.disabled ? \"true\" : \"false\"}\"\n aria-label=${this.label}\n tabindex=${this.disabled ? \"-1\" : \"0\"}\n ?disabled=${this.disabled}\n @click=\"${this._handleClick}\"\n >\n ${this.prefixIcon\n ? html`<nys-icon size=\"16\" name=${this.prefixIcon}></nys-icon>`\n : \"\"}\n ${this.label}\n </button>\n `}\n </li>`;\n }\n}\n\nif (!customElements.get(\"nys-dropdownmenuitem\")) {\n customElements.define(\"nys-dropdownmenuitem\", NysDropdownMenuItem);\n}\n","import { LitElement, html, unsafeCSS } from \"lit\";\nimport { property } from \"lit/decorators.js\";\nimport \"./nys-dropdownmenuitem\";\n// @ts-ignore: SCSS module imported via bundler as inline\nimport styles from \"./nys-dropdownmenu.scss?inline\";\n\nlet dropdownMenuIdCounter = 0;\n\n/**\n * Dropdown menus enable users to select an action from a list of options.\n * They’re commonly used to save space by grouping related actions, or to provide actions in a confined space.\n *\n * @summary Action menu with auto-positioning, keyboard support, and screen reader integration.\n * @element nys-dropdownmenu\n *\n * @example Basic dropdown\n * ```html\n * <button id=\"my-trigger\">Actions</button>\n * <nys-dropdownmenu for=\"my-trigger\">\n * <nys-dropdownmenuitem label=\"Edit\" link=\"/edit\"></nys-dropdownmenuitem>\n * <nys-dropdownmenuitem label=\"Delete\" link=\"/delete\"></nys-dropdownmenuitem>\n * </nys-dropdownmenu>\n * ```\n *\n * @example Positioned dropdown\n * ```html\n * <button id=\"settings-btn\">Settings</button>\n * <nys-dropdownmenu for=\"settings-btn\" position=\"top-start\">\n * <nys-dropdownmenuitem label=\"Profile\" link=\"/profile\"></nys-dropdownmenuitem>\n * <nys-dropdownmenuitem label=\"Logout\" link=\"/logout\"></nys-dropdownmenuitem>\n * </nys-dropdownmenu>\n * ```\n */\n\ntype Position = \"bottom-start\" | \"bottom-end\" | \"top-start\" | \"top-end\";\n\ninterface PositionCoordinates {\n top: number;\n left: number;\n}\n\ninterface SpaceAvailable {\n top: number;\n bottom: number;\n start: number;\n end: number;\n}\n\nexport class NysDropdownMenu extends LitElement {\n static styles = unsafeCSS(styles);\n\n @property({ type: String, reflect: true }) for = \"\";\n @property({ type: Boolean }) showDropdown = false;\n\n /**\n * Preferred position relative to trigger.\n * @default \"bottom-end\"\n */\n @property({ type: String, reflect: true }) position: Position | null = null;\n\n private _trigger: HTMLElement | null = null;\n private _menuElement: HTMLElement | null = null;\n private _ariaTarget: HTMLElement | null = null;\n private readonly GAP = 4;\n\n /**\n * Lifecycle Methods\n * --------------------------------------------------------------------------\n */\n\n constructor() {\n super();\n }\n\n // Generate a unique ID if one is not provided\n connectedCallback() {\n super.connectedCallback();\n\n if (!this.id) {\n this.id = `nys-dropdownmenu-${Date.now()}-${dropdownMenuIdCounter++}`;\n }\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n }\n\n async firstUpdated() {\n await this.updateComplete;\n this.applyInverseTransform();\n this._connectTrigger();\n\n this.addEventListener(\"nys-click\", () => {\n this._closeDropdown();\n });\n }\n /**\n * Functions\n * --------------------------------------------------------------------------\n */\n\n private _findTrigger() {\n const targetId = this.for;\n if (!targetId) return null;\n\n // lightDOM search\n let htmlElement = document.getElementById(targetId);\n if (htmlElement) return htmlElement;\n\n // Search recursively through shadow DOMs (e.g. for nys-label within other component's shadowDOM)\n const findInShadows = (root: ParentNode): HTMLElement | null => {\n for (const el of Array.from(root.querySelectorAll(\"*\"))) {\n const shadowElement = el.shadowRoot;\n if (shadowElement) {\n const found = shadowElement.getElementById(targetId);\n if (found) return found;\n\n const deeper = findInShadows(shadowElement);\n if (deeper) return deeper;\n }\n }\n return null;\n };\n\n return findInShadows(document);\n }\n\n private _connectTrigger() {\n const trigger = this._findTrigger();\n if (!trigger) return;\n\n this._trigger = trigger;\n\n const ariaTarget =\n trigger.tagName.toLowerCase() === \"nys-button\"\n ? (trigger.shadowRoot?.querySelector(\"button\") ?? trigger)\n : trigger;\n\n ariaTarget.setAttribute(\"aria-haspopup\", \"menu\");\n ariaTarget.setAttribute(\"aria-expanded\", \"false\");\n\n this._ariaTarget = ariaTarget;\n\n this._trigger.addEventListener(\"click\", this._toggleDropdown);\n this._trigger.addEventListener(\"keydown\", this._handleTriggerKeydown);\n }\n\n private _toggleDropdown = async () => {\n this.showDropdown = !this.showDropdown;\n\n this._ariaTarget?.setAttribute(\"aria-expanded\", String(this.showDropdown));\n\n if (this.showDropdown) {\n window.addEventListener(\"scroll\", this._handleWindowScroll, true);\n window.addEventListener(\"resize\", this._handleWindowResize);\n document.addEventListener(\"click\", this._handleDocumentClick);\n\n this._menuElement = this.shadowRoot?.querySelector(\n \".nys-dropdownmenu\",\n ) as HTMLElement | null;\n this._menuElement!.addEventListener(\"keydown\", this._handleMenuKeydown);\n\n await this.updateComplete;\n this._positionMenu();\n this._focusOnFirstItem();\n } else {\n window.removeEventListener(\"scroll\", this._handleWindowScroll, true);\n window.removeEventListener(\"resize\", this._handleWindowResize);\n document.removeEventListener(\"click\", this._handleDocumentClick);\n this._menuElement!.removeEventListener(\n \"keydown\",\n this._handleMenuKeydown,\n );\n }\n };\n\n private _closeDropdown() {\n this.showDropdown = false;\n this._ariaTarget?.setAttribute(\"aria-expanded\", \"false\");\n this._trigger?.focus();\n }\n\n private _getMenuItems(): HTMLElement[] {\n const slot = this.shadowRoot?.querySelector(\"slot\");\n const assigned = slot?.assignedElements({ flatten: true }) || [];\n\n return assigned.filter(\n (el) => el && !el.hasAttribute(\"disabled\"),\n ) as HTMLElement[];\n }\n\n private _handleDocumentClick = (event: MouseEvent) => {\n if (!this.showDropdown) return;\n\n const path = event?.composedPath();\n\n const clickedInsideMenu = path.includes(this);\n const clickedTrigger = this._trigger && path.includes(this._trigger);\n\n if (!clickedInsideMenu && !clickedTrigger) {\n this._closeDropdown();\n }\n };\n\n private async _focusOnFirstItem() {\n await new Promise((resolve) => requestAnimationFrame(resolve));\n const items = this._getMenuItems();\n if (items.length > 0) items[0].focus();\n }\n\n // In some iframes (like Storybook's) or embedded containers , parent elements may have CSS transforms applied, creating a new coordinate context.\n // This function removes such transforms to prevent them from affecting tooltip positioning calculations.\n private applyInverseTransform() {\n document.querySelectorAll('div[scale=\"1\"]').forEach((el) => {\n (el as HTMLElement).style.transform = \"none\";\n });\n }\n\n /**\n * Position Logic\n * --------------------------------------------------------------------------\n */\n\n /**\n * The controller function for positioning the dropdown menu.\n * The logic diverts to if user sets position or we auto position the dropdown menu\n */\n private _positionMenu() {\n if (!this._trigger) return;\n\n this._menuElement = this.shadowRoot?.querySelector(\n \".nys-dropdownmenu\",\n ) as HTMLElement | null;\n if (!this._menuElement) return;\n\n // Decide position based on user preference OR auto position if no position chosen\n const finalPosition = this.position\n ? this._setUserPosition(this.position)\n : this._autoPosition();\n\n // Apply the calculated position\n const coords = this._calculateCoordinates(finalPosition);\n this._applyPosition(coords);\n }\n\n private _setUserPosition(userPosition: Position): Position {\n const space = this._checkSpaceAvailable();\n const menuRect = this._menuElement!.getBoundingClientRect();\n\n const userPositionFits = this._checkPositionFits(\n userPosition,\n space,\n menuRect,\n );\n\n if (userPositionFits) {\n return userPosition;\n }\n\n // User position doesn't fit, find best alternative\n return this._findBestAlternative(userPosition, space, menuRect);\n }\n\n /**\n * Auto Positioning of the dropdown menu relies on the best surrounding space available\n * to select the desirable position.\n */\n private _autoPosition(): Position {\n const space = this._checkSpaceAvailable();\n const menuRect = this._menuElement!.getBoundingClientRect();\n\n const defaultPosition: Position = \"bottom-end\";\n\n if (this._checkPositionFits(defaultPosition, space, menuRect)) {\n return defaultPosition;\n }\n\n return this._findBestAlternative(defaultPosition, space, menuRect);\n }\n\n /**\n * Checks if the dropdown menu fits inside the viewport on the given side of the trigger.\n * Overrides user set position for auto-positioning if user's desire space is not available\n */\n private _checkSpaceAvailable(): SpaceAvailable {\n if (!this._trigger) {\n return { top: 0, bottom: 0, start: 0, end: 0 };\n }\n\n const triggerRect = this._trigger.getBoundingClientRect();\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n\n return {\n top: triggerRect.top,\n bottom: viewportHeight - triggerRect.bottom,\n start: triggerRect.left,\n end: viewportWidth - triggerRect.right,\n };\n }\n\n private _checkPositionFits(\n position: Position,\n space: SpaceAvailable,\n menuRect: DOMRect,\n ): boolean {\n const menuWidth = menuRect.width;\n const menuHeight = menuRect.height;\n\n const [vertical, horizontal] = position.split(\"-\") as [\n \"top\" | \"bottom\",\n \"start\" | \"end\",\n ];\n\n const verticalFits =\n vertical === \"bottom\"\n ? space.bottom >= menuHeight + this.GAP\n : space.top >= menuHeight + this.GAP;\n\n const horizontalFits =\n horizontal === \"start\"\n ? space.end >= menuWidth\n : space.start >= menuWidth;\n return verticalFits && horizontalFits;\n }\n\n /**\n * This position is called for when user's set position didn't fit OR auto positioning when default position doesn't fit\n * We look for the best alternative positions in order of preference base on the set position (e.g. bottom-start => bottom-end).\n * @param userPosition\n * @param space\n * @param menuRect\n */\n private _findBestAlternative(\n userPosition: Position,\n space: SpaceAvailable,\n menuRect: DOMRect,\n ): Position {\n const [vertical, horizontal] = userPosition.split(\"-\") as [\n \"top\" | \"bottom\",\n \"start\" | \"end\",\n ];\n\n const alternatives: Position[] = [\n `${vertical === \"bottom\" ? \"top\" : \"bottom\"}-${horizontal}`, // Flip vertical\n `${vertical}-${horizontal === \"start\" ? \"end\" : \"start\"}`, // Flip horizontal\n `${vertical === \"bottom\" ? \"top\" : \"bottom\"}-${horizontal === \"start\" ? \"end\" : \"start\"}`, // Flip both\n ];\n\n for (const altPosition of alternatives) {\n if (this._checkPositionFits(altPosition, space, menuRect)) {\n return altPosition;\n }\n }\n\n // Fallback: nothing fits, return position with most space\n return this._findMostAvailableSpace(space) as Position;\n }\n\n private _findMostAvailableSpace(space: SpaceAvailable): Position {\n const vertical = space.bottom >= space.top ? \"bottom\" : \"top\";\n const horizontal = space.start >= space.end ? \"start\" : \"end\";\n\n return `${vertical}-${horizontal}`;\n }\n\n /**\n * A valid ideal position has been chosen.\n * This function calculates the coordinate of the trigger to properly position the dropdown menu.\n * @param position\n * @returns\n */\n private _calculateCoordinates(position: Position): PositionCoordinates {\n if (!this._trigger || !this._menuElement) {\n return { top: 0, left: 0 };\n }\n\n const triggerRect = this._trigger.getBoundingClientRect();\n const menuRect = this._menuElement.getBoundingClientRect();\n\n const [vertical, horizontal] = position.split(\"-\") as [\n \"top\" | \"bottom\",\n \"start\" | \"end\",\n ];\n\n let top = 0;\n let left = 0;\n\n // Vertical position\n if (vertical === \"bottom\") {\n top = triggerRect.bottom + this.GAP;\n } else {\n top = triggerRect.top - menuRect.height - this.GAP;\n }\n\n // Horizontal position\n if (horizontal === \"start\") {\n left = triggerRect.left;\n } else {\n left = triggerRect.right - menuRect.width;\n }\n\n return { top, left };\n }\n\n private _applyPosition(coords: PositionCoordinates) {\n if (!this._menuElement) return;\n\n this._menuElement.style.top = `${coords.top}px`;\n this._menuElement.style.left = `${coords.left}px`;\n }\n\n /**\n * Event Handlers\n * --------------------------------------------------------------------------\n */\n\n private _handleTriggerKeydown = (event: KeyboardEvent) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n this._toggleDropdown();\n }\n\n if (event.key === \"Escape\" && this.showDropdown) {\n event.preventDefault();\n this._closeDropdown();\n }\n };\n\n private _handleMenuKeydown = (event: KeyboardEvent) => {\n const items = this._getMenuItems();\n const currentIndex = items.indexOf(document.activeElement as HTMLElement);\n\n switch (event.key) {\n case \"Escape\":\n event.preventDefault();\n this._closeDropdown();\n break;\n case \"ArrowDown\":\n case \"ArrowRight\":\n event.preventDefault();\n const nextIndex =\n currentIndex < items.length - 1 ? currentIndex + 1 : 0;\n items[nextIndex].focus();\n break;\n case \"ArrowUp\":\n case \"ArrowLeft\":\n event.preventDefault();\n const prevIndex =\n currentIndex > 0 ? currentIndex - 1 : items.length - 1;\n items[prevIndex].focus();\n break;\n case \"Tab\":\n if (currentIndex >= items.length - 1 && !event.shiftKey) {\n this._closeDropdown();\n }\n break;\n default:\n break;\n }\n };\n\n private _handleWindowResize = () => {\n if (this.showDropdown) {\n this._positionMenu();\n }\n };\n\n private _handleWindowScroll = () => {\n if (this.showDropdown) {\n this._positionMenu();\n }\n };\n\n render() {\n return html`<div\n class=\"nys-dropdownmenu ${this.showDropdown ? \"active\" : \"\"}\"\n for=${this.for}\n ?hidden=${!this.showDropdown}\n >\n <ul role=\"menu\">\n <slot></slot>\n </ul>\n </div>`;\n }\n}\n\nif (!customElements.get(\"nys-dropdownmenu\")) {\n customElements.define(\"nys-dropdownmenu\", NysDropdownMenu);\n}\n"],"names":["dropdownMenuItemIdCounter","_NysDropdownMenuItem","LitElement","isLink","html","unsafeCSS","styles","NysDropdownMenuItem","__decorateClass","property","dropdownMenuIdCounter","_NysDropdownMenu","event","path","clickedInsideMenu","clickedTrigger","items","currentIndex","nextIndex","prevIndex","targetId","htmlElement","findInShadows","root","el","shadowElement","found","deeper","trigger","ariaTarget","resolve","finalPosition","coords","userPosition","space","menuRect","defaultPosition","triggerRect","viewportWidth","viewportHeight","position","menuWidth","menuHeight","vertical","horizontal","verticalFits","horizontalFits","alternatives","altPosition","top","left","NysDropdownMenu"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"nys-dropdownmenu.js","sources":["../src/nys-dropdownmenuitem.ts","../src/nys-dropdownmenu.ts"],"sourcesContent":["import { LitElement, html, unsafeCSS } from \"lit\";\nimport { property } from \"lit/decorators.js\";\n// @ts-ignore: SCSS module imported via bundler as inline\nimport styles from \"./nys-dropdownmenu.scss?inline\";\n\nlet dropdownMenuItemIdCounter = 0;\n\n/**\n * **Slotted component.** Displays an individual dropdown item within `nys-dropdown` with label.\n *\n * The `nys-dropdownitem` is used as customizable item within the dropdown so users don't have to raw code <ul>, <li>, <a href>\n * and have the benefit of default customization.\n *\n * @summary Dropdown item to display label and provide href link.\n * @element nys-dropdownmenuitem\n *\n * @example Basic item\n * ```html\n * <nys-dropdownmenuitem label=\"Edit\" link=\"/edit\"></nys-dropdownmenuitem>\n * ```\n *\n * @example Disabled item\n * ```html\n * <nys-dropdownmenuitem label=\"Delete\" link=\"/delete\" disabled></nys-dropdownmenuitem>\n * ```\n */\nexport class NysDropdownMenuItem extends LitElement {\n static styles = unsafeCSS(styles);\n static shadowRootOptions = {\n ...LitElement.shadowRootOptions,\n delegatesFocus: true,\n };\n\n @property({ type: String }) label = \"\";\n @property({ type: String }) href = \"\";\n @property({ type: Boolean, reflect: true }) disabled = false;\n @property({ type: String }) target = \"_self\";\n @property({ type: String }) prefixIcon = \"\";\n @property({ type: String }) divider = \"\";\n\n // Generate a unique ID if one is not provided\n connectedCallback() {\n super.connectedCallback();\n if (!this.id) {\n this.id = `nys-dropdownmenuitem-${Date.now()}-${dropdownMenuItemIdCounter++}`;\n }\n }\n\n private _handleClick(e: Event) {\n if (this.disabled) {\n e.preventDefault();\n return;\n }\n\n this.dispatchEvent(\n new CustomEvent(\"nys-click\", {\n bubbles: true,\n composed: true,\n detail: {\n id: this.id,\n label: this.label,\n ...(this.href && { href: this.href }),\n },\n }),\n );\n }\n\n render() {\n const isLink = !!this.href;\n\n return html`<li class=\"nys-dropdownmenuitem\" role=\"presentation\">\n ${isLink\n ? html` <a\n class=${this.disabled ? \"disabled\" : \"\"}\n href=${this.disabled ? \"\" : this.href}\n role=\"menuitem\"\n aria-disabled=\"${this.disabled ? \"true\" : \"false\"}\"\n aria-label=${this.label}\n tabindex=${this.disabled ? \"-1\" : \"0\"}\n @click=\"${this._handleClick}\"\n target=\"${this.target}\"\n >\n ${this.prefixIcon\n ? html`<nys-icon size=\"16\" name=${this.prefixIcon}></nys-icon>`\n : \"\"}\n ${this.label}</a\n >`\n : html`\n <button\n class=${this.disabled ? \"disabled\" : \"\"}\n type=\"button\"\n role=\"menuitem\"\n aria-disabled=\"${this.disabled ? \"true\" : \"false\"}\"\n aria-label=${this.label}\n tabindex=${this.disabled ? \"-1\" : \"0\"}\n ?disabled=${this.disabled}\n @click=\"${this._handleClick}\"\n >\n ${this.prefixIcon\n ? html`<nys-icon size=\"16\" name=${this.prefixIcon}></nys-icon>`\n : \"\"}\n ${this.label}\n </button>\n `}\n </li>`;\n }\n}\n\nif (!customElements.get(\"nys-dropdownmenuitem\")) {\n customElements.define(\"nys-dropdownmenuitem\", NysDropdownMenuItem);\n}\n","import { LitElement, html, unsafeCSS } from \"lit\";\nimport { property } from \"lit/decorators.js\";\nimport \"./nys-dropdownmenuitem\";\n// @ts-ignore: SCSS module imported via bundler as inline\nimport styles from \"./nys-dropdownmenu.scss?inline\";\n\nlet dropdownMenuIdCounter = 0;\n\n/**\n * Dropdown menus enable users to select an action from a list of options.\n * They’re commonly used to save space by grouping related actions, or to provide actions in a confined space.\n *\n * @summary Action menu with auto-positioning, keyboard support, and screen reader integration.\n * @element nys-dropdownmenu\n *\n * @example Basic dropdown\n * ```html\n * <button id=\"my-trigger\">Actions</button>\n * <nys-dropdownmenu for=\"my-trigger\">\n * <nys-dropdownmenuitem label=\"Edit\" link=\"/edit\"></nys-dropdownmenuitem>\n * <nys-dropdownmenuitem label=\"Delete\" link=\"/delete\"></nys-dropdownmenuitem>\n * </nys-dropdownmenu>\n * ```\n *\n * @example Positioned dropdown\n * ```html\n * <button id=\"settings-btn\">Settings</button>\n * <nys-dropdownmenu for=\"settings-btn\" position=\"top-start\">\n * <nys-dropdownmenuitem label=\"Profile\" link=\"/profile\"></nys-dropdownmenuitem>\n * <nys-dropdownmenuitem label=\"Logout\" link=\"/logout\"></nys-dropdownmenuitem>\n * </nys-dropdownmenu>\n * ```\n */\n\ntype Position = \"bottom-start\" | \"bottom-end\" | \"top-start\" | \"top-end\";\n\ninterface PositionCoordinates {\n top: number;\n left: number;\n}\n\ninterface SpaceAvailable {\n top: number;\n bottom: number;\n start: number;\n end: number;\n}\n\nexport class NysDropdownMenu extends LitElement {\n static styles = unsafeCSS(styles);\n\n @property({ type: String, reflect: true }) for = \"\";\n @property({ type: Boolean }) showDropdown = false;\n\n /**\n * Preferred position relative to trigger.\n * @default \"bottom-end\"\n */\n @property({ type: String, reflect: true }) position: Position | null = null;\n\n private _trigger: HTMLElement | null = null;\n private _menuElement: HTMLElement | null = null;\n private _ariaTarget: HTMLElement | null = null;\n private _lastFocusedIndex: number = 0;\n private readonly GAP = 4;\n\n /**\n * Lifecycle Methods\n * --------------------------------------------------------------------------\n */\n\n constructor() {\n super();\n }\n\n // Generate a unique ID if one is not provided\n connectedCallback() {\n super.connectedCallback();\n\n if (!this.id) {\n this.id = `nys-dropdownmenu-${Date.now()}-${dropdownMenuIdCounter++}`;\n }\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n }\n\n async firstUpdated() {\n await this.updateComplete;\n this.applyInverseTransform();\n this._connectTrigger();\n this._handleMenuClick();\n }\n /**\n * Functions\n * --------------------------------------------------------------------------\n */\n\n private _findTrigger() {\n const targetId = this.for;\n if (!targetId) return null;\n\n // lightDOM search\n let htmlElement = document.getElementById(targetId);\n if (htmlElement) return htmlElement;\n\n // Search recursively through shadow DOMs (e.g. for nys-label within other component's shadowDOM)\n const findInShadows = (root: ParentNode): HTMLElement | null => {\n for (const el of Array.from(root.querySelectorAll(\"*\"))) {\n const shadowElement = el.shadowRoot;\n if (shadowElement) {\n const found = shadowElement.getElementById(targetId);\n if (found) return found;\n\n const deeper = findInShadows(shadowElement);\n if (deeper) return deeper;\n }\n }\n return null;\n };\n\n return findInShadows(document);\n }\n\n private _connectTrigger() {\n const trigger = this._findTrigger();\n if (!trigger) return;\n\n this._trigger = trigger;\n\n const ariaTarget =\n trigger.tagName.toLowerCase() === \"nys-button\"\n ? (trigger.shadowRoot?.querySelector(\"button\") ?? trigger)\n : trigger;\n\n ariaTarget.setAttribute(\"aria-haspopup\", \"menu\");\n ariaTarget.setAttribute(\"aria-expanded\", \"false\");\n\n this._ariaTarget = ariaTarget;\n\n this._trigger.addEventListener(\"click\", this._toggleDropdown);\n this._trigger.addEventListener(\"keydown\", this._handleTriggerKeydown);\n }\n\n private _toggleDropdown = async () => {\n this.showDropdown = !this.showDropdown;\n\n this._ariaTarget?.setAttribute(\"aria-expanded\", String(this.showDropdown));\n\n if (this.showDropdown) {\n window.addEventListener(\"scroll\", this._handleWindowScroll, true);\n window.addEventListener(\"resize\", this._handleWindowResize);\n document.addEventListener(\"click\", this._handleDocumentClick);\n\n this._menuElement = this.shadowRoot?.querySelector(\n \".nys-dropdownmenu\",\n ) as HTMLElement | null;\n this._menuElement!.addEventListener(\"keydown\", this._handleMenuKeydown);\n\n await this.updateComplete;\n this._positionMenu();\n this._focusOnItem(this._lastFocusedIndex);\n } else {\n window.removeEventListener(\"scroll\", this._handleWindowScroll, true);\n window.removeEventListener(\"resize\", this._handleWindowResize);\n document.removeEventListener(\"click\", this._handleDocumentClick);\n this._menuElement!.removeEventListener(\n \"keydown\",\n this._handleMenuKeydown,\n );\n }\n };\n\n private _closeDropdown() {\n this.showDropdown = false;\n this._ariaTarget?.setAttribute(\"aria-expanded\", \"false\");\n this._trigger?.focus();\n }\n\n private _getMenuItems(): HTMLElement[] {\n const slot = this.shadowRoot?.querySelector(\"slot\");\n const assigned = slot?.assignedElements({ flatten: true }) || [];\n\n return assigned.filter(\n (el) => el && !el.hasAttribute(\"disabled\"),\n ) as HTMLElement[];\n }\n\n private _handleDocumentClick = (event: MouseEvent) => {\n if (!this.showDropdown) return;\n\n const path = event?.composedPath();\n\n const clickedInsideMenu = path.includes(this);\n const clickedTrigger = this._trigger && path.includes(this._trigger);\n\n if (!clickedInsideMenu && !clickedTrigger) {\n this._closeDropdown();\n }\n };\n\n private async _focusOnItem(index: number = 0) {\n await new Promise((resolve) => requestAnimationFrame(resolve));\n const items = this._getMenuItems();\n const target = items[Math.min(index, items.length - 1)];\n if (!target) return;\n\n target.focus();\n }\n\n // In some iframes (like Storybook's) or embedded containers , parent elements may have CSS transforms applied, creating a new coordinate context.\n // This function removes such transforms to prevent them from affecting tooltip positioning calculations.\n private applyInverseTransform() {\n document.querySelectorAll('div[scale=\"1\"]').forEach((el) => {\n (el as HTMLElement).style.transform = \"none\";\n });\n }\n\n /**\n * Position Logic\n * --------------------------------------------------------------------------\n */\n\n /**\n * The controller function for positioning the dropdown menu.\n * The logic diverts to if user sets position or we auto position the dropdown menu\n */\n private _positionMenu() {\n if (!this._trigger) return;\n\n this._menuElement = this.shadowRoot?.querySelector(\n \".nys-dropdownmenu\",\n ) as HTMLElement | null;\n if (!this._menuElement) return;\n\n // Decide position based on user preference OR auto position if no position chosen\n const finalPosition = this.position\n ? this._setUserPosition(this.position)\n : this._autoPosition();\n\n // Apply the calculated position\n const coords = this._calculateCoordinates(finalPosition);\n this._applyPosition(coords);\n }\n\n private _setUserPosition(userPosition: Position): Position {\n const space = this._checkSpaceAvailable();\n const menuRect = this._menuElement!.getBoundingClientRect();\n\n const userPositionFits = this._checkPositionFits(\n userPosition,\n space,\n menuRect,\n );\n\n if (userPositionFits) {\n return userPosition;\n }\n\n // User position doesn't fit, find best alternative\n return this._findBestAlternative(userPosition, space, menuRect);\n }\n\n /**\n * Auto Positioning of the dropdown menu relies on the best surrounding space available\n * to select the desirable position.\n */\n private _autoPosition(): Position {\n const space = this._checkSpaceAvailable();\n const menuRect = this._menuElement!.getBoundingClientRect();\n\n const defaultPosition: Position = \"bottom-end\";\n\n if (this._checkPositionFits(defaultPosition, space, menuRect)) {\n return defaultPosition;\n }\n\n return this._findBestAlternative(defaultPosition, space, menuRect);\n }\n\n /**\n * Checks if the dropdown menu fits inside the viewport on the given side of the trigger.\n * Overrides user set position for auto-positioning if user's desire space is not available\n */\n private _checkSpaceAvailable(): SpaceAvailable {\n if (!this._trigger) {\n return { top: 0, bottom: 0, start: 0, end: 0 };\n }\n\n const triggerRect = this._trigger.getBoundingClientRect();\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n\n return {\n top: triggerRect.top,\n bottom: viewportHeight - triggerRect.bottom,\n start: triggerRect.left,\n end: viewportWidth - triggerRect.right,\n };\n }\n\n private _checkPositionFits(\n position: Position,\n space: SpaceAvailable,\n menuRect: DOMRect,\n ): boolean {\n const menuWidth = menuRect.width;\n const menuHeight = menuRect.height;\n\n const [vertical, horizontal] = position.split(\"-\") as [\n \"top\" | \"bottom\",\n \"start\" | \"end\",\n ];\n\n const verticalFits =\n vertical === \"bottom\"\n ? space.bottom >= menuHeight + this.GAP\n : space.top >= menuHeight + this.GAP;\n\n const horizontalFits =\n horizontal === \"start\"\n ? space.end >= menuWidth\n : space.start >= menuWidth;\n return verticalFits && horizontalFits;\n }\n\n /**\n * This position is called for when user's set position didn't fit OR auto positioning when default position doesn't fit\n * We look for the best alternative positions in order of preference base on the set position (e.g. bottom-start => bottom-end).\n * @param userPosition\n * @param space\n * @param menuRect\n */\n private _findBestAlternative(\n userPosition: Position,\n space: SpaceAvailable,\n menuRect: DOMRect,\n ): Position {\n const [vertical, horizontal] = userPosition.split(\"-\") as [\n \"top\" | \"bottom\",\n \"start\" | \"end\",\n ];\n\n const alternatives: Position[] = [\n `${vertical === \"bottom\" ? \"top\" : \"bottom\"}-${horizontal}`, // Flip vertical\n `${vertical}-${horizontal === \"start\" ? \"end\" : \"start\"}`, // Flip horizontal\n `${vertical === \"bottom\" ? \"top\" : \"bottom\"}-${horizontal === \"start\" ? \"end\" : \"start\"}`, // Flip both\n ];\n\n for (const altPosition of alternatives) {\n if (this._checkPositionFits(altPosition, space, menuRect)) {\n return altPosition;\n }\n }\n\n // Fallback: nothing fits, return position with most space\n return this._findMostAvailableSpace(space) as Position;\n }\n\n private _findMostAvailableSpace(space: SpaceAvailable): Position {\n const vertical = space.bottom >= space.top ? \"bottom\" : \"top\";\n const horizontal = space.start >= space.end ? \"start\" : \"end\";\n\n return `${vertical}-${horizontal}`;\n }\n\n /**\n * A valid ideal position has been chosen.\n * This function calculates the coordinate of the trigger to properly position the dropdown menu.\n * @param position\n * @returns\n */\n private _calculateCoordinates(position: Position): PositionCoordinates {\n if (!this._trigger || !this._menuElement) {\n return { top: 0, left: 0 };\n }\n\n const triggerRect = this._trigger.getBoundingClientRect();\n const menuRect = this._menuElement.getBoundingClientRect();\n\n const [vertical, horizontal] = position.split(\"-\") as [\n \"top\" | \"bottom\",\n \"start\" | \"end\",\n ];\n\n let top = 0;\n let left = 0;\n\n // Vertical position\n if (vertical === \"bottom\") {\n top = triggerRect.bottom + this.GAP;\n } else {\n top = triggerRect.top - menuRect.height - this.GAP;\n }\n\n // Horizontal position\n if (horizontal === \"start\") {\n left = triggerRect.left;\n } else {\n left = triggerRect.right - menuRect.width;\n }\n\n return { top, left };\n }\n\n private _applyPosition(coords: PositionCoordinates) {\n if (!this._menuElement) return;\n\n this._menuElement.style.top = `${coords.top}px`;\n this._menuElement.style.left = `${coords.left}px`;\n }\n\n /**\n * Event Handlers\n * --------------------------------------------------------------------------\n */\n\n private _handleMenuClick() {\n this.addEventListener(\"nys-click\", (e: Event) => {\n const items = this._getMenuItems();\n const targetCrumb = (e as CustomEvent).detail?.id;\n const index = items.findIndex((item) => item.id === targetCrumb);\n if (index !== -1) this._lastFocusedIndex = index;\n this._closeDropdown();\n });\n }\n\n private _handleTriggerKeydown = (event: KeyboardEvent) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n this._toggleDropdown();\n }\n\n if (event.key === \"Escape\" && this.showDropdown) {\n event.preventDefault();\n this._closeDropdown();\n }\n };\n\n private _handleMenuKeydown = (event: KeyboardEvent) => {\n const items = this._getMenuItems();\n const currentIndex = items.indexOf(document.activeElement as HTMLElement);\n\n switch (event.key) {\n case \"Escape\":\n event.preventDefault();\n this._closeDropdown();\n break;\n case \"ArrowDown\":\n case \"ArrowRight\":\n event.preventDefault();\n const nextIndex =\n currentIndex < items.length - 1 ? currentIndex + 1 : 0;\n this._lastFocusedIndex = nextIndex;\n items[nextIndex].focus();\n break;\n case \"ArrowUp\":\n case \"ArrowLeft\":\n event.preventDefault();\n const prevIndex =\n currentIndex > 0 ? currentIndex - 1 : items.length - 1;\n this._lastFocusedIndex = prevIndex;\n items[prevIndex].focus();\n break;\n case \"Tab\":\n if (currentIndex >= items.length - 1 && !event.shiftKey) {\n this._closeDropdown();\n }\n break;\n default:\n break;\n }\n };\n\n private _handleWindowResize = () => {\n if (this.showDropdown) {\n this._positionMenu();\n }\n };\n\n private _handleWindowScroll = () => {\n if (this.showDropdown) {\n this._positionMenu();\n }\n };\n\n render() {\n return html`<div\n class=\"nys-dropdownmenu ${this.showDropdown ? \"active\" : \"\"}\"\n for=${this.for}\n ?hidden=${!this.showDropdown}\n >\n <ul role=\"menu\">\n <slot></slot>\n </ul>\n </div>`;\n }\n}\n\nif (!customElements.get(\"nys-dropdownmenu\")) {\n customElements.define(\"nys-dropdownmenu\", NysDropdownMenu);\n}\n"],"names":["dropdownMenuItemIdCounter","_NysDropdownMenuItem","LitElement","isLink","html","unsafeCSS","styles","NysDropdownMenuItem","__decorateClass","property","dropdownMenuIdCounter","_NysDropdownMenu","event","path","clickedInsideMenu","clickedTrigger","items","currentIndex","nextIndex","prevIndex","targetId","htmlElement","findInShadows","root","el","shadowElement","found","deeper","trigger","ariaTarget","index","resolve","target","finalPosition","coords","userPosition","space","menuRect","defaultPosition","triggerRect","viewportWidth","viewportHeight","position","menuWidth","menuHeight","vertical","horizontal","verticalFits","horizontalFits","alternatives","altPosition","top","left","targetCrumb","item","NysDropdownMenu"],"mappings":";;;;;;;;;;;;;;;;;;AAKA,IAAIA,IAA4B;AAqBzB,MAAMC,IAAN,MAAMA,UAA4BC,EAAW;AAAA,EAA7C,cAAA;AAAA,UAAA,GAAA,SAAA,GAOuB,KAAA,QAAQ,IACR,KAAA,OAAO,IACS,KAAA,WAAW,IAC3B,KAAA,SAAS,SACT,KAAA,aAAa,IACb,KAAA,UAAU;AAAA,EAAA;AAAA;AAAA,EAGtC,oBAAoB;AAClB,UAAM,kBAAA,GACD,KAAK,OACR,KAAK,KAAK,wBAAwB,KAAK,KAAK,IAAIF,GAA2B;AAAA,EAE/E;AAAA,EAEQ,aAAa,GAAU;AAC7B,QAAI,KAAK,UAAU;AACjB,QAAE,eAAA;AACF;AAAA,IACF;AAEA,SAAK;AAAA,MACH,IAAI,YAAY,aAAa;AAAA,QAC3B,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ;AAAA,UACN,IAAI,KAAK;AAAA,UACT,OAAO,KAAK;AAAA,UACZ,GAAI,KAAK,QAAQ,EAAE,MAAM,KAAK,KAAA;AAAA,QAAK;AAAA,MACrC,CACD;AAAA,IAAA;AAAA,EAEL;AAAA,EAEA,SAAS;AACP,UAAMG,IAAS,CAAC,CAAC,KAAK;AAEtB,WAAOC;AAAA,QACHD,IACEC;AAAA,oBACU,KAAK,WAAW,aAAa,EAAE;AAAA,mBAChC,KAAK,WAAW,KAAK,KAAK,IAAI;AAAA;AAAA,6BAEpB,KAAK,WAAW,SAAS,OAAO;AAAA,yBACpC,KAAK,KAAK;AAAA,uBACZ,KAAK,WAAW,OAAO,GAAG;AAAA,sBAC3B,KAAK,YAAY;AAAA,sBACjB,KAAK,MAAM;AAAA;AAAA,cAEnB,KAAK,aACHA,6BAAgC,KAAK,UAAU,iBAC/C,EAAE;AAAA,cACJ,KAAK,KAAK;AAAA,eAEdA;AAAA;AAAA,sBAEY,KAAK,WAAW,aAAa,EAAE;AAAA;AAAA;AAAA,+BAGtB,KAAK,WAAW,SAAS,OAAO;AAAA,2BACpC,KAAK,KAAK;AAAA,yBACZ,KAAK,WAAW,OAAO,GAAG;AAAA,0BACzB,KAAK,QAAQ;AAAA,wBACf,KAAK,YAAY;AAAA;AAAA,gBAEzB,KAAK,aACHA,6BAAgC,KAAK,UAAU,iBAC/C,EAAE;AAAA,gBACJ,KAAK,KAAK;AAAA;AAAA,WAEf;AAAA;AAAA,EAET;AACF;AA/EEH,EAAO,SAASI,EAAUC,CAAM,GAChCL,EAAO,oBAAoB;AAAA,EACzB,GAAGC,EAAW;AAAA,EACd,gBAAgB;AAAA;AAJb,IAAMK,IAANN;AAOuBO,EAAA;AAAA,EAA3BC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GAPfF,EAOiB,WAAA,OAAA;AACAC,EAAA;AAAA,EAA3BC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GARfF,EAQiB,WAAA,MAAA;AACgBC,EAAA;AAAA,EAA3CC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GAT/BF,EASiC,WAAA,UAAA;AAChBC,EAAA;AAAA,EAA3BC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GAVfF,EAUiB,WAAA,QAAA;AACAC,EAAA;AAAA,EAA3BC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GAXfF,EAWiB,WAAA,YAAA;AACAC,EAAA;AAAA,EAA3BC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GAZfF,EAYiB,WAAA,SAAA;AAsEzB,eAAe,IAAI,sBAAsB,KAC5C,eAAe,OAAO,wBAAwBA,CAAmB;;;;;;ACvGnE,IAAIG,IAAwB;AA0CrB,MAAMC,IAAN,MAAMA,UAAwBT,EAAW;AAAA;AAAA;AAAA;AAAA;AAAA,EAuB9C,cAAc;AACZ,UAAA,GArByC,KAAA,MAAM,IACpB,KAAA,eAAe,IAMD,KAAA,WAA4B,MAEvE,KAAQ,WAA+B,MACvC,KAAQ,eAAmC,MAC3C,KAAQ,cAAkC,MAC1C,KAAQ,oBAA4B,GACpC,KAAiB,MAAM,GAiFvB,KAAQ,kBAAkB,YAAY;AACpC,WAAK,eAAe,CAAC,KAAK,cAE1B,KAAK,aAAa,aAAa,iBAAiB,OAAO,KAAK,YAAY,CAAC,GAErE,KAAK,gBACP,OAAO,iBAAiB,UAAU,KAAK,qBAAqB,EAAI,GAChE,OAAO,iBAAiB,UAAU,KAAK,mBAAmB,GAC1D,SAAS,iBAAiB,SAAS,KAAK,oBAAoB,GAE5D,KAAK,eAAe,KAAK,YAAY;AAAA,QACnC;AAAA,MAAA,GAEF,KAAK,aAAc,iBAAiB,WAAW,KAAK,kBAAkB,GAEtE,MAAM,KAAK,gBACX,KAAK,cAAA,GACL,KAAK,aAAa,KAAK,iBAAiB,MAExC,OAAO,oBAAoB,UAAU,KAAK,qBAAqB,EAAI,GACnE,OAAO,oBAAoB,UAAU,KAAK,mBAAmB,GAC7D,SAAS,oBAAoB,SAAS,KAAK,oBAAoB,GAC/D,KAAK,aAAc;AAAA,QACjB;AAAA,QACA,KAAK;AAAA,MAAA;AAAA,IAGX,GAiBA,KAAQ,uBAAuB,CAACU,MAAsB;AACpD,UAAI,CAAC,KAAK,aAAc;AAExB,YAAMC,IAAOD,GAAO,aAAA,GAEdE,IAAoBD,EAAK,SAAS,IAAI,GACtCE,IAAiB,KAAK,YAAYF,EAAK,SAAS,KAAK,QAAQ;AAEnE,MAAI,CAACC,KAAqB,CAACC,KACzB,KAAK,eAAA;AAAA,IAET,GAoOA,KAAQ,wBAAwB,CAACH,MAAyB;AACxD,OAAIA,EAAM,QAAQ,WAAWA,EAAM,QAAQ,SACzCA,EAAM,eAAA,GACN,KAAK,gBAAA,IAGHA,EAAM,QAAQ,YAAY,KAAK,iBACjCA,EAAM,eAAA,GACN,KAAK,eAAA;AAAA,IAET,GAEA,KAAQ,qBAAqB,CAACA,MAAyB;AACrD,YAAMI,IAAQ,KAAK,cAAA,GACbC,IAAeD,EAAM,QAAQ,SAAS,aAA4B;AAExE,cAAQJ,EAAM,KAAA;AAAA,QACZ,KAAK;AACH,UAAAA,EAAM,eAAA,GACN,KAAK,eAAA;AACL;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,UAAAA,EAAM,eAAA;AACN,gBAAMM,IACJD,IAAeD,EAAM,SAAS,IAAIC,IAAe,IAAI;AACvD,eAAK,oBAAoBC,GACzBF,EAAME,CAAS,EAAE,MAAA;AACjB;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,UAAAN,EAAM,eAAA;AACN,gBAAMO,IACJF,IAAe,IAAIA,IAAe,IAAID,EAAM,SAAS;AACvD,eAAK,oBAAoBG,GACzBH,EAAMG,CAAS,EAAE,MAAA;AACjB;AAAA,QACF,KAAK;AACH,UAAIF,KAAgBD,EAAM,SAAS,KAAK,CAACJ,EAAM,YAC7C,KAAK,eAAA;AAEP;AAAA,MAEA;AAAA,IAEN,GAEA,KAAQ,sBAAsB,MAAM;AAClC,MAAI,KAAK,gBACP,KAAK,cAAA;AAAA,IAET,GAEA,KAAQ,sBAAsB,MAAM;AAClC,MAAI,KAAK,gBACP,KAAK,cAAA;AAAA,IAET;AAAA,EA5ZA;AAAA;AAAA,EAGA,oBAAoB;AAClB,UAAM,kBAAA,GAED,KAAK,OACR,KAAK,KAAK,oBAAoB,KAAK,KAAK,IAAIF,GAAuB;AAAA,EAEvE;AAAA,EAEA,uBAAuB;AACrB,UAAM,qBAAA;AAAA,EACR;AAAA,EAEA,MAAM,eAAe;AACnB,UAAM,KAAK,gBACX,KAAK,sBAAA,GACL,KAAK,gBAAA,GACL,KAAK,iBAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,eAAe;AACrB,UAAMU,IAAW,KAAK;AACtB,QAAI,CAACA,EAAU,QAAO;AAGtB,QAAIC,IAAc,SAAS,eAAeD,CAAQ;AAClD,QAAIC,EAAa,QAAOA;AAGxB,UAAMC,IAAgB,CAACC,MAAyC;AAC9D,iBAAWC,KAAM,MAAM,KAAKD,EAAK,iBAAiB,GAAG,CAAC,GAAG;AACvD,cAAME,IAAgBD,EAAG;AACzB,YAAIC,GAAe;AACjB,gBAAMC,IAAQD,EAAc,eAAeL,CAAQ;AACnD,cAAIM,EAAO,QAAOA;AAElB,gBAAMC,IAASL,EAAcG,CAAa;AAC1C,cAAIE,EAAQ,QAAOA;AAAA,QACrB;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAEA,WAAOL,EAAc,QAAQ;AAAA,EAC/B;AAAA,EAEQ,kBAAkB;AACxB,UAAMM,IAAU,KAAK,aAAA;AACrB,QAAI,CAACA,EAAS;AAEd,SAAK,WAAWA;AAEhB,UAAMC,IACJD,EAAQ,QAAQ,YAAA,MAAkB,eAC7BA,EAAQ,YAAY,cAAc,QAAQ,KAAKA,IAChDA;AAEN,IAAAC,EAAW,aAAa,iBAAiB,MAAM,GAC/CA,EAAW,aAAa,iBAAiB,OAAO,GAEhD,KAAK,cAAcA,GAEnB,KAAK,SAAS,iBAAiB,SAAS,KAAK,eAAe,GAC5D,KAAK,SAAS,iBAAiB,WAAW,KAAK,qBAAqB;AAAA,EACtE;AAAA,EA+BQ,iBAAiB;AACvB,SAAK,eAAe,IACpB,KAAK,aAAa,aAAa,iBAAiB,OAAO,GACvD,KAAK,UAAU,MAAA;AAAA,EACjB;AAAA,EAEQ,gBAA+B;AAIrC,YAHa,KAAK,YAAY,cAAc,MAAM,GAC3B,iBAAiB,EAAE,SAAS,GAAA,CAAM,KAAK,CAAA,GAE9C;AAAA,MACd,CAACL,MAAOA,KAAM,CAACA,EAAG,aAAa,UAAU;AAAA,IAAA;AAAA,EAE7C;AAAA,EAeA,MAAc,aAAaM,IAAgB,GAAG;AAC5C,UAAM,IAAI,QAAQ,CAACC,MAAY,sBAAsBA,CAAO,CAAC;AAC7D,UAAMf,IAAQ,KAAK,cAAA,GACbgB,IAAShB,EAAM,KAAK,IAAIc,GAAOd,EAAM,SAAS,CAAC,CAAC;AACtD,IAAKgB,KAELA,EAAO,MAAA;AAAA,EACT;AAAA;AAAA;AAAA,EAIQ,wBAAwB;AAC9B,aAAS,iBAAiB,gBAAgB,EAAE,QAAQ,CAACR,MAAO;AACzD,MAAAA,EAAmB,MAAM,YAAY;AAAA,IACxC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWQ,gBAAgB;AAMtB,QALI,CAAC,KAAK,aAEV,KAAK,eAAe,KAAK,YAAY;AAAA,MACnC;AAAA,IAAA,GAEE,CAAC,KAAK,cAAc;AAGxB,UAAMS,IAAgB,KAAK,WACvB,KAAK,iBAAiB,KAAK,QAAQ,IACnC,KAAK,cAAA,GAGHC,IAAS,KAAK,sBAAsBD,CAAa;AACvD,SAAK,eAAeC,CAAM;AAAA,EAC5B;AAAA,EAEQ,iBAAiBC,GAAkC;AACzD,UAAMC,IAAQ,KAAK,qBAAA,GACbC,IAAW,KAAK,aAAc,sBAAA;AAQpC,WANyB,KAAK;AAAA,MAC5BF;AAAA,MACAC;AAAA,MACAC;AAAA,IAAA,IAIOF,IAIF,KAAK,qBAAqBA,GAAcC,GAAOC,CAAQ;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,gBAA0B;AAChC,UAAMD,IAAQ,KAAK,qBAAA,GACbC,IAAW,KAAK,aAAc,sBAAA,GAE9BC,IAA4B;AAElC,WAAI,KAAK,mBAAmBA,GAAiBF,GAAOC,CAAQ,IACnDC,IAGF,KAAK,qBAAqBA,GAAiBF,GAAOC,CAAQ;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,uBAAuC;AAC7C,QAAI,CAAC,KAAK;AACR,aAAO,EAAE,KAAK,GAAG,QAAQ,GAAG,OAAO,GAAG,KAAK,EAAA;AAG7C,UAAME,IAAc,KAAK,SAAS,sBAAA,GAC5BC,IAAgB,OAAO,YACvBC,IAAiB,OAAO;AAE9B,WAAO;AAAA,MACL,KAAKF,EAAY;AAAA,MACjB,QAAQE,IAAiBF,EAAY;AAAA,MACrC,OAAOA,EAAY;AAAA,MACnB,KAAKC,IAAgBD,EAAY;AAAA,IAAA;AAAA,EAErC;AAAA,EAEQ,mBACNG,GACAN,GACAC,GACS;AACT,UAAMM,IAAYN,EAAS,OACrBO,IAAaP,EAAS,QAEtB,CAACQ,GAAUC,CAAU,IAAIJ,EAAS,MAAM,GAAG,GAK3CK,IACJF,MAAa,WACTT,EAAM,UAAUQ,IAAa,KAAK,MAClCR,EAAM,OAAOQ,IAAa,KAAK,KAE/BI,IACJF,MAAe,UACXV,EAAM,OAAOO,IACbP,EAAM,SAASO;AACrB,WAAOI,KAAgBC;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,qBACNb,GACAC,GACAC,GACU;AACV,UAAM,CAACQ,GAAUC,CAAU,IAAIX,EAAa,MAAM,GAAG,GAK/Cc,IAA2B;AAAA,MAC/B,GAAGJ,MAAa,WAAW,QAAQ,QAAQ,IAAIC,CAAU;AAAA;AAAA,MACzD,GAAGD,CAAQ,IAAIC,MAAe,UAAU,QAAQ,OAAO;AAAA;AAAA,MACvD,GAAGD,MAAa,WAAW,QAAQ,QAAQ,IAAIC,MAAe,UAAU,QAAQ,OAAO;AAAA;AAAA,IAAA;AAGzF,eAAWI,KAAeD;AACxB,UAAI,KAAK,mBAAmBC,GAAad,GAAOC,CAAQ;AACtD,eAAOa;AAKX,WAAO,KAAK,wBAAwBd,CAAK;AAAA,EAC3C;AAAA,EAEQ,wBAAwBA,GAAiC;AAC/D,UAAMS,IAAWT,EAAM,UAAUA,EAAM,MAAM,WAAW,OAClDU,IAAaV,EAAM,SAASA,EAAM,MAAM,UAAU;AAExD,WAAO,GAAGS,CAAQ,IAAIC,CAAU;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,sBAAsBJ,GAAyC;AACrE,QAAI,CAAC,KAAK,YAAY,CAAC,KAAK;AAC1B,aAAO,EAAE,KAAK,GAAG,MAAM,EAAA;AAGzB,UAAMH,IAAc,KAAK,SAAS,sBAAA,GAC5BF,IAAW,KAAK,aAAa,sBAAA,GAE7B,CAACQ,GAAUC,CAAU,IAAIJ,EAAS,MAAM,GAAG;AAKjD,QAAIS,IAAM,GACNC,IAAO;AAGX,WAAIP,MAAa,WACfM,IAAMZ,EAAY,SAAS,KAAK,MAEhCY,IAAMZ,EAAY,MAAMF,EAAS,SAAS,KAAK,KAI7CS,MAAe,UACjBM,IAAOb,EAAY,OAEnBa,IAAOb,EAAY,QAAQF,EAAS,OAG/B,EAAE,KAAAc,GAAK,MAAAC,EAAA;AAAA,EAChB;AAAA,EAEQ,eAAelB,GAA6B;AAClD,IAAK,KAAK,iBAEV,KAAK,aAAa,MAAM,MAAM,GAAGA,EAAO,GAAG,MAC3C,KAAK,aAAa,MAAM,OAAO,GAAGA,EAAO,IAAI;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,mBAAmB;AACzB,SAAK,iBAAiB,aAAa,CAAC,MAAa;AAC/C,YAAMlB,IAAQ,KAAK,cAAA,GACbqC,IAAe,EAAkB,QAAQ,IACzCvB,IAAQd,EAAM,UAAU,CAACsC,MAASA,EAAK,OAAOD,CAAW;AAC/D,MAAIvB,MAAU,OAAI,KAAK,oBAAoBA,IAC3C,KAAK,eAAA;AAAA,IACP,CAAC;AAAA,EACH;AAAA,EA6DA,SAAS;AACP,WAAO1B;AAAA,gCACqB,KAAK,eAAe,WAAW,EAAE;AAAA,YACrD,KAAK,GAAG;AAAA,gBACJ,CAAC,KAAK,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMhC;AACF;AAjcEO,EAAO,SAASN,EAAUC,CAAM;AAD3B,IAAMiD,IAAN5C;AAGsCH,EAAA;AAAA,EAA1CC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GAH9B8C,EAGgC,WAAA,KAAA;AACd/C,EAAA;AAAA,EAA5BC,EAAS,EAAE,MAAM,QAAA,CAAS;AAAA,GAJhB8C,EAIkB,WAAA,cAAA;AAMc/C,EAAA;AAAA,EAA1CC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GAV9B8C,EAUgC,WAAA,UAAA;AA0bxC,eAAe,IAAI,kBAAkB,KACxC,eAAe,OAAO,oBAAoBA,CAAe;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nysds/nys-dropdownmenu",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.18.0",
|
|
4
4
|
"description": "The Dropdownmenu component from the NYS Design System.",
|
|
5
5
|
"module": "dist/nys-dropdownmenu.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"lit-analyze": "lit-analyzer '*.ts'"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@nysds/nys-icon": "^1.
|
|
26
|
+
"@nysds/nys-icon": "^1.18.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"lit": "^3.3.1",
|