@wavelengthusaf/web-components 1.15.0 → 1.17.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.
@@ -5662,6 +5662,108 @@ var WavelengthFileDropZone = class extends HTMLElement {
5662
5662
  };
5663
5663
  customElements.define("wavelength-file-drop-zone", WavelengthFileDropZone);
5664
5664
 
5665
+ // src/web-components/wavelength-confirmation-modal.template.html
5666
+ var wavelength_confirmation_modal_template_default = '<style>\n :host([show="true"]) {\n display: block;\n position: fixed;\n z-index: 1300;\n inset: 0;\n }\n :host(:not([show="true"])) {\n display: none;\n}\n\n\n dialog::backdrop {\nbackground-color: rgba(0, 0, 0, 0.5);\n-webkit-tap-highlight-color: transparent;\n}\n\n dialog {\n box-sizing: border-box;\n position: relative;\n background-color: var(--background-color, #fff);\n border-radius: 1rem;\n color: var(--text-color, #000);\n box-shadow:\n 0 0.6875rem 0.9375rem -0.4375rem rgba(0, 0, 0, 0.2),\n 0 1.5rem 2.375rem 3px rgba(0, 0, 0, 0.14),\n 0 0.5625rem 2.875rem 0.5rem rgba(0, 0, 0, 0.12);\n padding: 2rem;\n overflow: auto;\n font-family: var(--font-family, "Roboto", "Helvetica", "Arial", "sans-serif");\n outline: 0;\n border: none;\n}\n/* Ensure the dialog appears above the backdrop */\n.backdrop + dialog.modal-dialog {\n position: fixed;\n inset: 0;\n margin: auto;\n}\n\n .modal-title {\n margin: 0;\n font-size: 1.75rem;\n font-weight: 500;\n padding: 0;\n margin-bottom: 1rem;\n }\n\n .modal-dialog {\n margin: 0;\n font-size: 1rem;\n line-height: 1.2;\n font-weight: 400;\n min-height: 3.75rem;\n }\n\n .modal-actions {\n position: absolute;\n bottom: 1rem;\n right: 1rem;\n display: flex;\n flex-direction: row;\n gap: 0.5rem;\n }\n\n /* Internal Button Styles imitating WavelengthStyledButton */\n .modal-actions wavelength-button {\n min-width: 6.5625rem;\n }\n</style>\n\n<div class="backdrop" id="backdrop"></div>\n<dialog class="modal-dialog" id="dialog-element">\n <p class="modal-title" id="title-element"></p>\n <p class="modal-dialog" id="dialog-content"></p>\n <div class="modal-actions">\n <wavelength-button id="cancel-button" variant="outlined" color-one="rgba(0, 0, 0, 0.87)" padding="0.375rem 1rem" font-size="0.875rem" width="6.5625rem"></wavelength-button>\n <wavelength-button id="submit-button" variant="contained" color-one="#1A8083" color-two="#FFFFFF" padding="0.375rem 1rem" font-size="0.875rem" width="6.5625rem"></wavelength-button>\n </div>\n</dialog>\n';
5667
+
5668
+ // src/web-components/wavelength-confirmation-modal.ts
5669
+ var WavelengthConfirmationModal = class extends HTMLElement {
5670
+ static get observedAttributes() {
5671
+ return ["show", "width", "height", "font-family", "text-color", "background-color", "title-text", "dialog-text", "submit-text", "cancel-text"];
5672
+ }
5673
+ constructor() {
5674
+ super();
5675
+ const shadow = this.attachShadow({ mode: "open" });
5676
+ shadow.innerHTML = wavelength_confirmation_modal_template_default;
5677
+ this.elements = {
5678
+ backdrop: shadow.getElementById("backdrop"),
5679
+ dialog: shadow.getElementById("dialog-element"),
5680
+ titleElement: shadow.getElementById("title-element"),
5681
+ contentElement: shadow.getElementById("dialog-content"),
5682
+ cancelButton: shadow.getElementById("cancel-button"),
5683
+ submitButton: shadow.getElementById("submit-button")
5684
+ };
5685
+ this.elements.dialog.addEventListener("close", () => {
5686
+ if (this.getAttribute("show") !== "false") {
5687
+ this.setAttribute("show", "false");
5688
+ }
5689
+ this.dispatchEvent(new CustomEvent("close", { bubbles: true, composed: true }));
5690
+ });
5691
+ this.elements.dialog.addEventListener("click", (e) => {
5692
+ const rect = this.elements.dialog.getBoundingClientRect();
5693
+ const isInDialog = rect.top <= e.clientY && e.clientY <= rect.top + rect.height && rect.left <= e.clientX && e.clientX <= rect.left + rect.width;
5694
+ if (!isInDialog) {
5695
+ this.elements.dialog.close();
5696
+ }
5697
+ });
5698
+ this.elements.cancelButton.addEventListener("click", () => {
5699
+ this.elements.dialog.close();
5700
+ this.dispatchEvent(new CustomEvent("cancel", { bubbles: true, composed: true }));
5701
+ });
5702
+ this.elements.submitButton.addEventListener("click", () => {
5703
+ this.dispatchEvent(new CustomEvent("submit", { bubbles: true, composed: true }));
5704
+ });
5705
+ }
5706
+ connectedCallback() {
5707
+ this.updateStyling();
5708
+ this.updateContent();
5709
+ }
5710
+ attributeChangedCallback(name, oldValue, newValue) {
5711
+ if (oldValue === newValue) return;
5712
+ if (name === "title-text" || name === "dialog-text" || name === "submit-text" || name === "cancel-text") {
5713
+ this.updateContent();
5714
+ } else if (name === "show") {
5715
+ if (newValue === "true") {
5716
+ if (!this.elements.dialog.open) {
5717
+ this.elements.dialog.showModal();
5718
+ }
5719
+ } else {
5720
+ if (this.elements.dialog.open) {
5721
+ this.elements.dialog.close();
5722
+ }
5723
+ }
5724
+ } else {
5725
+ this.updateStyling();
5726
+ }
5727
+ }
5728
+ updateContent() {
5729
+ const titleText = this.getAttribute("title-text") || "";
5730
+ const dialogText = this.getAttribute("dialog-text") || "";
5731
+ const submitText = this.getAttribute("submit-text") || "Submit";
5732
+ const cancelText = this.getAttribute("cancel-text") || "Cancel";
5733
+ this.elements.titleElement.textContent = titleText;
5734
+ this.elements.contentElement.textContent = dialogText;
5735
+ this.elements.submitButton.textContent = submitText;
5736
+ this.elements.cancelButton.textContent = cancelText;
5737
+ }
5738
+ updateStyling() {
5739
+ const width = this.getAttribute("width") || "28.1875rem";
5740
+ const height = this.getAttribute("height") || "16rem";
5741
+ const fontFamily = this.getAttribute("font-family") || "";
5742
+ const textColor = this.getAttribute("text-color") || "";
5743
+ const backgroundColor = this.getAttribute("background-color") || "";
5744
+ this.elements.dialog.style.width = width;
5745
+ this.elements.dialog.style.height = height;
5746
+ if (fontFamily) {
5747
+ this.style.setProperty("--font-family", fontFamily);
5748
+ } else {
5749
+ this.style.removeProperty("--font-family");
5750
+ }
5751
+ if (textColor) {
5752
+ this.style.setProperty("--text-color", textColor);
5753
+ } else {
5754
+ this.style.removeProperty("--text-color");
5755
+ }
5756
+ if (backgroundColor) {
5757
+ this.style.setProperty("--background-color", backgroundColor);
5758
+ } else {
5759
+ this.style.removeProperty("--background-color");
5760
+ }
5761
+ }
5762
+ };
5763
+ if (!customElements.get("wavelength-confirmation-modal")) {
5764
+ customElements.define("wavelength-confirmation-modal", WavelengthConfirmationModal);
5765
+ }
5766
+
5665
5767
  // src/web-components/wavelength-dropdown.ts
5666
5768
  var template5 = document.createElement("template");
5667
5769
  template5.innerHTML = `
@@ -5720,8 +5822,9 @@ template5.innerHTML = `
5720
5822
  margin: 0;
5721
5823
  padding: 0;
5722
5824
  list-style: none;
5723
- overflow-y: auto;
5825
+ overflow-y: auto;
5724
5826
  display: none;
5827
+ top: 100%;
5725
5828
  z-index: 10;
5726
5829
  box-shadow: 0px 5px 5px -3px rgba(0, 0, 0, 0.2), 0px 8px 10px 1px rgba(0, 0, 0, 0.14), 0px 3px 14px 2px rgba(0, 0, 0, 0.12);
5727
5830
  }
@@ -5778,8 +5881,15 @@ var WavelengthDropdown = class extends HTMLElement {
5778
5881
  this.parseOptionsAttribute();
5779
5882
  this.applyStyles();
5780
5883
  this.dropdownField.addEventListener("click", () => {
5781
- this.optionsList.classList.toggle("show");
5782
- this.arrow.classList.toggle("active");
5884
+ const isOpen = this.optionsList.classList.contains("show");
5885
+ if (!isOpen) {
5886
+ this.optionsList.classList.add("show");
5887
+ this.arrow.classList.add("active");
5888
+ requestAnimationFrame(() => this._positionDropdown());
5889
+ } else {
5890
+ this.optionsList.classList.remove("show");
5891
+ this.arrow.classList.remove("active");
5892
+ }
5783
5893
  });
5784
5894
  document.addEventListener("click", (e) => {
5785
5895
  if (!this.contains(e.target)) {
@@ -5788,6 +5898,22 @@ var WavelengthDropdown = class extends HTMLElement {
5788
5898
  }
5789
5899
  });
5790
5900
  }
5901
+ _positionDropdown() {
5902
+ const fieldRect = this.dropdownField.getBoundingClientRect();
5903
+ const listHeight = this.optionsList.offsetHeight;
5904
+ const viewportHeight = window.innerHeight;
5905
+ const spaceBelow = viewportHeight - fieldRect.bottom;
5906
+ const spaceAbove = fieldRect.top;
5907
+ if (spaceBelow < listHeight && spaceAbove > spaceBelow) {
5908
+ this.optionsList.style.top = "auto";
5909
+ this.optionsList.style.bottom = "100%";
5910
+ this.optionsList.style.maxHeight = `${spaceAbove - 8}px`;
5911
+ } else {
5912
+ this.optionsList.style.top = "100%";
5913
+ this.optionsList.style.bottom = "auto";
5914
+ this.optionsList.style.maxHeight = `${spaceBelow - 8}px`;
5915
+ }
5916
+ }
5791
5917
  attributeChangedCallback() {
5792
5918
  this.parseOptionsAttribute();
5793
5919
  this.setDefaultValue();
@@ -6957,6 +7083,265 @@ if (!customElements.get("wavelength-badge")) {
6957
7083
  customElements.define("wavelength-badge", WavelengthBadge);
6958
7084
  }
6959
7085
 
7086
+ // src/web-components/wavelength-dialog.template.html
7087
+ var wavelength_dialog_template_default = '<style>\n :host {\n /* \u2500\u2500 Customizable CSS variables \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n --box-color: white;\n --max-width: 500px;\n --max-height: 500px;\n --shadow: 0 6px 30px 5px rgba(0, 0, 0, 0.12), 0 16px 24px 2px rgba(0, 0, 0, 0.14), 0 8px 10px -5px rgba(0, 0, 0, 0.2);\n --font-family: Roboto, sans-serif;\n --font-size: 16px;\n --border-radius: 0.5rem;\n --border-color: #e5e7eb;\n --text-color: #111827;\n --left-btn-bg: #f3f4f6;\n --left-btn-color: #374151;\n --right-btn-bg: #2563eb;\n --right-btn-color: #ffffff;\n\n /* \u2500\u2500 Default: EMBEDDED MODE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n display: block;\n box-sizing: border-box;\n\n font-family: var(--font-family);\n font-size: var(--font-size);\n }\n\n dialog::backdrop {\n background: rgba(0, 0, 0, 0.35);\n }\n\n /* \u2500\u2500 Dialog card \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n dialog {\n flex-direction: column;\n padding: 0;\n margin: auto;\n position: relative;\n width: 100%;\n max-width: var(--max-width);\n max-height: min(var(--max-height), calc(100vh - 32px));\n box-sizing: border-box;\n overflow: hidden;\n\n background: var(--box-color);\n color: var(--text-color);\n border-radius: var(--border-radius);\n border: 1px solid var(--border-color, #e5e7eb);\n box-shadow: var(--shadow);\n outline: none;\n }\n dialog[open] {\n display: flex;\n }\n [hidden] {\n display: none !important;\n }\n /* \u2500\u2500 Header (title) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n .dialog-header {\n padding: 20px 24px 16px;\n font-weight: 600;\n font-size: 1.125rem;\n border-bottom: 1px solid var(--border-color, #e5e7eb);\n flex-shrink: 0;\n }\n\n /* \u2500\u2500 Content area \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n .dialog-content {\n flex: 1;\n overflow-y: auto;\n padding: 20px 24px;\n\n /* prevents weird flex collapse in non-overlay layouts */\n min-height: 0;\n border: none;\n outline: none;\n }\n\n /* \u2500\u2500 Footer (buttons) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n .dialog-footer {\n display: flex;\n justify-content: flex-end;\n gap: 10px;\n padding: 16px 24px 20px;\n border-top: 1px solid var(--border-color, #e5e7eb);\n flex-shrink: 0;\n }\n\n /* \u2500\u2500 Shared button base \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n .btn {\n padding: 8px 20px;\n border-radius: 6px;\n border: 1px solid transparent;\n cursor: pointer;\n font-size: 14px;\n font-weight: 500;\n font-family: inherit;\n line-height: 1.4;\n transition:\n opacity 0.15s ease,\n box-shadow 0.15s ease;\n }\n .btn:hover {\n opacity: 0.85;\n }\n .btn:active {\n opacity: 0.7;\n }\n .btn:focus-visible {\n outline: 2px solid var(--right-btn-bg);\n outline-offset: 2px;\n }\n\n /* \u2500\u2500 Cancel / left button \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n .btn-left {\n background: var(--left-btn-bg);\n color: var(--left-btn-color);\n border-color: var(--border-color);\n }\n\n /* \u2500\u2500 Confirm / right button \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n .btn-right {\n background: var(--right-btn-bg);\n color: var(--right-btn-color);\n }\n</style>\n\n<!-- Dialog card -->\n<dialog id="dialog">\n <!-- Title -->\n <header class="dialog-header" id="dialog-header">\n <span class="attr-title"></span>\n </header>\n\n <!-- Dev-supplied content via default slot -->\n <section class="dialog-content">\n <slot></slot>\n </section>\n\n <!-- Action buttons -->\n <footer class="dialog-footer" id="dialog-footer">\n <button class="btn btn-left" id="left-btn" type="button"></button>\n <button class="btn btn-right" id="right-btn" type="button"></button>\n </footer>\n</dialog>\n';
7088
+
7089
+ // src/web-components/wavelength-dialog.ts
7090
+ var _WavelengthDialog = class _WavelengthDialog extends HTMLElement {
7091
+ constructor() {
7092
+ super();
7093
+ this._onLeftClick = () => this._emit("wl-left-btn-click");
7094
+ this._onRightClick = () => this._emit("wl-right-btn-click");
7095
+ this.shadow = this.attachShadow({ mode: "open" });
7096
+ this.shadow.innerHTML = wavelength_dialog_template_default;
7097
+ this.elements = {
7098
+ dialog: this.shadow.querySelector("dialog"),
7099
+ header: this.shadow.querySelector("#dialog-header"),
7100
+ footer: this.shadow.querySelector("#dialog-footer"),
7101
+ leftBtn: this.shadow.querySelector("#left-btn"),
7102
+ rightBtn: this.shadow.querySelector("#right-btn"),
7103
+ titleSpan: this.shadow.querySelector(".attr-title")
7104
+ };
7105
+ }
7106
+ get dialogTitle() {
7107
+ return this.getAttribute("dialog-title");
7108
+ }
7109
+ set dialogTitle(value) {
7110
+ if (value === null) this.removeAttribute("dialog-title");
7111
+ else this.setAttribute("dialog-title", value);
7112
+ }
7113
+ get leftBtnLabel() {
7114
+ return this.getAttribute("left-btn-label");
7115
+ }
7116
+ set leftBtnLabel(value) {
7117
+ if (value === null) this.removeAttribute("left-btn-label");
7118
+ else this.setAttribute("left-btn-label", value);
7119
+ }
7120
+ get rightBtnLabel() {
7121
+ return this.getAttribute("right-btn-label");
7122
+ }
7123
+ set rightBtnLabel(value) {
7124
+ if (value === null) this.removeAttribute("right-btn-label");
7125
+ else this.setAttribute("right-btn-label", value);
7126
+ }
7127
+ get open() {
7128
+ return this.hasAttribute("open");
7129
+ }
7130
+ set open(value) {
7131
+ if (value) this.setAttribute("open", "");
7132
+ else this.removeAttribute("open");
7133
+ }
7134
+ get overlay() {
7135
+ return this.hasAttribute("overlay");
7136
+ }
7137
+ set overlay(value) {
7138
+ if (value) this.setAttribute("overlay", "");
7139
+ else this.removeAttribute("overlay");
7140
+ }
7141
+ static get observedAttributes() {
7142
+ return [..._WavelengthDialog.styleAttributes, "dialog-title", "left-btn-label", "right-btn-label", "overlay", "open"];
7143
+ }
7144
+ connectedCallback() {
7145
+ this.elements.leftBtn.addEventListener("click", this._onLeftClick);
7146
+ this.elements.rightBtn.addEventListener("click", this._onRightClick);
7147
+ this._syncStyles();
7148
+ this._syncContent();
7149
+ this._syncDialog();
7150
+ }
7151
+ disconnectedCallback() {
7152
+ _optionalChain([this, 'access', _101 => _101.elements, 'access', _102 => _102.leftBtn, 'optionalAccess', _103 => _103.removeEventListener, 'call', _104 => _104("click", this._onLeftClick)]);
7153
+ _optionalChain([this, 'access', _105 => _105.elements, 'access', _106 => _106.rightBtn, 'optionalAccess', _107 => _107.removeEventListener, 'call', _108 => _108("click", this._onRightClick)]);
7154
+ }
7155
+ attributeChangedCallback(name) {
7156
+ if (_WavelengthDialog.styleAttributes.includes(name)) {
7157
+ this._syncStyles();
7158
+ } else if (name === "dialog-title" || name === "left-btn-label" || name === "right-btn-label") {
7159
+ this._syncContent();
7160
+ } else if (name === "open" || name === "overlay") {
7161
+ this._syncDialog();
7162
+ }
7163
+ }
7164
+ _syncDialog() {
7165
+ if (!this.isConnected) return;
7166
+ const dialog = this.elements.dialog;
7167
+ const shouldBeOpen = this.hasAttribute("open");
7168
+ if (!shouldBeOpen) {
7169
+ if (dialog.open) dialog.close();
7170
+ return;
7171
+ }
7172
+ if (dialog.open) dialog.close();
7173
+ if (this.hasAttribute("overlay")) {
7174
+ dialog.showModal();
7175
+ } else {
7176
+ dialog.show();
7177
+ }
7178
+ }
7179
+ _emit(name) {
7180
+ this.dispatchEvent(new CustomEvent(name, { bubbles: true, composed: true }));
7181
+ }
7182
+ _syncStyles() {
7183
+ _WavelengthDialog.styleAttributes.forEach((attr) => {
7184
+ const value = this.getAttribute(attr);
7185
+ if (value !== null) {
7186
+ this.style.setProperty(`--${attr}`, value);
7187
+ } else {
7188
+ this.style.removeProperty(`--${attr}`);
7189
+ }
7190
+ });
7191
+ }
7192
+ _syncContent() {
7193
+ const { header, titleSpan, leftBtn, rightBtn, footer } = this.elements;
7194
+ const attrTitle = _optionalChain([this, 'access', _109 => _109.getAttribute, 'call', _110 => _110("dialog-title"), 'optionalAccess', _111 => _111.trim, 'call', _112 => _112()]) || "";
7195
+ header.hidden = !attrTitle;
7196
+ titleSpan.textContent = attrTitle;
7197
+ const leftLabel = this.getAttribute("left-btn-label");
7198
+ const rightLabel = this.getAttribute("right-btn-label");
7199
+ leftBtn.textContent = leftLabel || "";
7200
+ leftBtn.hidden = !leftLabel;
7201
+ rightBtn.textContent = rightLabel || "";
7202
+ rightBtn.hidden = !rightLabel;
7203
+ footer.hidden = !leftLabel && !rightLabel;
7204
+ }
7205
+ };
7206
+ _WavelengthDialog.styleAttributes = [
7207
+ "box-color",
7208
+ "max-width",
7209
+ "max-height",
7210
+ "shadow",
7211
+ "font-size",
7212
+ "font-family",
7213
+ "border-radius",
7214
+ "border-color",
7215
+ "text-color",
7216
+ "left-btn-bg",
7217
+ "left-btn-color",
7218
+ "right-btn-bg",
7219
+ "right-btn-color"
7220
+ ];
7221
+ var WavelengthDialog = _WavelengthDialog;
7222
+ if (!customElements.get("wavelength-dialog")) {
7223
+ customElements.define("wavelength-dialog", WavelengthDialog);
7224
+ }
7225
+
7226
+ // src/web-components/wavelength-popup-menu.template.html
7227
+ var wavelength_popup_menu_template_default = '<style>\n :host {\n display: inline-block;\n position: relative;\n --menu-offset-val: var(--menu-offset, 8px);\n\n --badge-bg: var(--color, #007bff);\n --badge-text: var(--badge-text-color, #fff);\n --badge-size: var(--icon-size, 24px);\n\n --card-bg: var(--card-background-color, #fff);\n --card-w: var(--card-width, 280px);\n }\n\n :host(:hover) {\n --badge-bg: var(--badge-hover-color, var(--color));\n cursor: pointer;\n }\n\n .wrapper {\n position: relative;\n display: inline-flex;\n align-items: center;\n }\n /* --- Dropdown --- */\n .dropdown {\n display: none;\n position: absolute;\n left: 50%;\n transform: translateX(-50%);\n z-index: 1000;\n width: max-content;\n opacity: 0;\n }\n\n :host([data-open]) .dropdown {\n display: flex;\n flex-direction: column;\n align-items: center;\n opacity: 1;\n }\n /* --- Direction --- */\n :host(:not([menu-direction])) .dropdown,\n :host([menu-direction="down"]) .dropdown {\n top: 100%;\n padding-top: var(--menu-offset-val);\n }\n :host([menu-direction="up"]) .dropdown {\n bottom: 100%;\n padding-bottom: var(--menu-offset-val);\n }\n :host([menu-direction="left"]) .dropdown {\n top: 50%;\n left: auto;\n right: 100%;\n transform: translateY(-50%);\n padding-right: var(--menu-offset-val);\n }\n :host([menu-direction="right"]) .dropdown {\n top: 50%;\n left: 100%;\n right: auto;\n transform: translateY(-50%);\n padding-left: var(--menu-offset-val);\n }\n /* --- Variant visibility --- */\n wavelength-menu,\n .card {\n display: none;\n }\n :host(:not([variant])) wavelength-menu,\n :host([variant="menu"]) wavelength-menu {\n display: block;\n }\n :host([variant="card"]) .card {\n display: block;\n }\n /* --- Card --- */\n .card {\n width: var(--card-w);\n background-color: var(--card-bg);\n padding: var(--card-padding, 16px);\n border-radius: var(--card-border-radius, 8px);\n box-shadow: var(--card-shadow, 0 4px 12px rgba(0, 0, 0, 0.15));\n }\n</style>\n<div class="wrapper">\n <wavelength-badge badge-color="var(--badge-bg)" badge-text-color="var(--badge-text)" badge-size="var(--badge-size)"> </wavelength-badge>\n\n <div class="dropdown">\n <wavelength-menu></wavelength-menu>\n\n <div class="card">\n <slot name="card-header"></slot>\n <slot name="card-body"></slot>\n <slot name="card-footer"></slot>\n </div>\n </div>\n</div>\n';
7228
+
7229
+ // src/web-components/wavelength-popup-menu.ts
7230
+ var WavelengthPopUpMenu = class extends StylingMixin(HTMLElement) {
7231
+ constructor() {
7232
+ super();
7233
+ this._isOpen = false;
7234
+ // --- Event handlers ---
7235
+ this._handleBadgeClick = (e) => {
7236
+ e.stopPropagation();
7237
+ this.isOpen = !this._isOpen;
7238
+ };
7239
+ this._handleMouseEnter = () => this.isOpen = true;
7240
+ this._handleMouseLeave = () => this.isOpen = false;
7241
+ this._handleMenuSelect = (e) => {
7242
+ this.dispatchEvent(
7243
+ new CustomEvent("wl-popup-menu-select", {
7244
+ detail: e.detail,
7245
+ bubbles: true,
7246
+ composed: true
7247
+ })
7248
+ );
7249
+ this.isOpen = false;
7250
+ };
7251
+ this._handleOutsideClick = (e) => {
7252
+ if (!this._isOpen) return;
7253
+ const path = e.composedPath();
7254
+ if (!path.includes(this)) {
7255
+ this.isOpen = false;
7256
+ }
7257
+ };
7258
+ this.shadow = this.attachShadow({ mode: "open" });
7259
+ this.shadow.innerHTML = wavelength_popup_menu_template_default;
7260
+ this._menu = this.shadow.querySelector("wavelength-menu");
7261
+ this._badge = this.shadow.querySelector("wavelength-badge");
7262
+ }
7263
+ static get observedAttributes() {
7264
+ return ["variant", "trigger", "menu-direction", "menu-items", "menu-offset", "badge-label"];
7265
+ }
7266
+ connectedCallback() {
7267
+ this._setupTrigger();
7268
+ this._syncMenuItems();
7269
+ }
7270
+ attributeChangedCallback(name, oldValue, newValue) {
7271
+ if (oldValue === newValue) return;
7272
+ switch (name) {
7273
+ case "trigger":
7274
+ this._setupTrigger();
7275
+ break;
7276
+ case "menu-items":
7277
+ this._syncMenuItems();
7278
+ break;
7279
+ case "badge-label":
7280
+ this._badge.setAttribute("badge-content", newValue || "");
7281
+ break;
7282
+ case "menu-offset": {
7283
+ const px = this._px("menu-offset");
7284
+ if (px) this.style.setProperty("--menu-offset", px);
7285
+ else this.style.removeProperty("--menu-offset");
7286
+ break;
7287
+ }
7288
+ }
7289
+ }
7290
+ disconnectedCallback() {
7291
+ this._cleanup();
7292
+ }
7293
+ // --- Props ---
7294
+ _px(attr) {
7295
+ const val = this.getAttribute(attr);
7296
+ if (!val) return null;
7297
+ return isNaN(Number(val)) ? val : `${val}px`;
7298
+ }
7299
+ _syncMenuItems() {
7300
+ const items = this.getAttribute("menu-items");
7301
+ if (items !== null) {
7302
+ this._menu.setAttribute("items", items);
7303
+ } else {
7304
+ this._menu.removeAttribute("items");
7305
+ }
7306
+ }
7307
+ // --- Open/close ---
7308
+ get isOpen() {
7309
+ return this._isOpen;
7310
+ }
7311
+ set isOpen(open) {
7312
+ if (this._isOpen === open) return;
7313
+ this._isOpen = open;
7314
+ this.toggleAttribute("open", open);
7315
+ this.toggleAttribute("data-open", open);
7316
+ }
7317
+ // --- Trigger ---
7318
+ _cleanup() {
7319
+ document.removeEventListener("click", this._handleOutsideClick);
7320
+ this._badge.removeEventListener("click", this._handleBadgeClick);
7321
+ this.removeEventListener("mouseenter", this._handleMouseEnter);
7322
+ this.removeEventListener("mouseleave", this._handleMouseLeave);
7323
+ this._menu.removeEventListener("wavelength-menu-select", this._handleMenuSelect);
7324
+ }
7325
+ _setupTrigger() {
7326
+ this._cleanup();
7327
+ document.addEventListener("click", this._handleOutsideClick);
7328
+ this._menu.addEventListener("wavelength-menu-select", this._handleMenuSelect);
7329
+ const trigger = this.getAttribute("trigger") || "click";
7330
+ if (trigger === "hover") {
7331
+ this.addEventListener("mouseenter", this._handleMouseEnter);
7332
+ this.addEventListener("mouseleave", this._handleMouseLeave);
7333
+ } else {
7334
+ this._badge.addEventListener("click", this._handleBadgeClick);
7335
+ }
7336
+ }
7337
+ };
7338
+ if (!customElements.get("wavelength-popup-menu")) {
7339
+ customElements.define("wavelength-popup-menu", WavelengthPopUpMenu);
7340
+ }
7341
+
7342
+
7343
+
7344
+
6960
7345
 
6961
7346
 
6962
7347
 
@@ -6983,7 +7368,7 @@ if (!customElements.get("wavelength-badge")) {
6983
7368
 
6984
7369
 
6985
7370
 
6986
- exports.BaseWavelengthInput = BaseWavelengthInput; exports.BaseWavelengthMultiSelectAutocomplete = BaseWavelengthMultiSelectAutocomplete; exports.ChildDataTable = ChildDataTable; exports.SampleComponent = SampleComponent; exports.WavelengthBadge = WavelengthBadge; exports.WavelengthBanner = WavelengthBanner; exports.WavelengthButton = WavelengthButton; exports.WavelengthCheckbox = WavelengthCheckbox; exports.WavelengthDatePicker = WavelengthDatePicker; exports.WavelengthDropdown = WavelengthDropdown; exports.WavelengthFileDropZone = WavelengthFileDropZone; exports.WavelengthForm = WavelengthForm; exports.WavelengthInput = WavelengthInput; exports.WavelengthManyPlanes = WavelengthManyPlanes; exports.WavelengthMenu = WavelengthMenu; exports.WavelengthMultiSelectAutocomplete = WavelengthMultiSelectAutocomplete; exports.WavelengthNavBar = WavelengthNavBar; exports.WavelengthNotificationPanel = WavelengthNotificationPanel; exports.WavelengthPagination = WavelengthPagination; exports.WavelengthPlaneTrail = WavelengthPlaneTrail; exports.WavelengthProgressBar = WavelengthProgressBar; exports.WavelengthSearch = WavelengthSearch; exports.WavelengthSnackbar = WavelengthSnackbar; exports.WavelengthSwitch = WavelengthSwitch; exports.WavelengthTitleBar = WavelengthTitleBar; exports.WavelengthToolTip = WavelengthToolTip;
7371
+ exports.BaseWavelengthInput = BaseWavelengthInput; exports.BaseWavelengthMultiSelectAutocomplete = BaseWavelengthMultiSelectAutocomplete; exports.ChildDataTable = ChildDataTable; exports.SampleComponent = SampleComponent; exports.WavelengthBadge = WavelengthBadge; exports.WavelengthBanner = WavelengthBanner; exports.WavelengthButton = WavelengthButton; exports.WavelengthCheckbox = WavelengthCheckbox; exports.WavelengthConfirmationModal = WavelengthConfirmationModal; exports.WavelengthDatePicker = WavelengthDatePicker; exports.WavelengthDialog = WavelengthDialog; exports.WavelengthDropdown = WavelengthDropdown; exports.WavelengthFileDropZone = WavelengthFileDropZone; exports.WavelengthForm = WavelengthForm; exports.WavelengthInput = WavelengthInput; exports.WavelengthManyPlanes = WavelengthManyPlanes; exports.WavelengthMenu = WavelengthMenu; exports.WavelengthMultiSelectAutocomplete = WavelengthMultiSelectAutocomplete; exports.WavelengthNavBar = WavelengthNavBar; exports.WavelengthNotificationPanel = WavelengthNotificationPanel; exports.WavelengthPagination = WavelengthPagination; exports.WavelengthPlaneTrail = WavelengthPlaneTrail; exports.WavelengthPopUpMenu = WavelengthPopUpMenu; exports.WavelengthProgressBar = WavelengthProgressBar; exports.WavelengthSearch = WavelengthSearch; exports.WavelengthSnackbar = WavelengthSnackbar; exports.WavelengthSwitch = WavelengthSwitch; exports.WavelengthTitleBar = WavelengthTitleBar; exports.WavelengthToolTip = WavelengthToolTip;
6987
7372
  /*! Bundled license information:
6988
7373
 
6989
7374
  react/cjs/react.production.min.js: