@nuralyui/dropdown 0.0.20 → 0.0.21

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/bundle.js CHANGED
@@ -22,9 +22,7 @@ import{css as o,LitElement as t,nothing as n,html as i}from"lit";import{property
22
22
  }
23
23
 
24
24
  .dropdown__panel {
25
- position: absolute;
26
- top: 100%;
27
- left: 0;
25
+ position: fixed;
28
26
  z-index: var(--nuraly-dropdown-z-index, 9999);
29
27
  background: var(--nuraly-color-dropdown-background, #ffffff);
30
28
  border: var(--nuraly-dropdown-border-width, 1px) solid var(--nuraly-color-dropdown-border, #e0e0e0);
@@ -34,40 +32,47 @@ import{css as o,LitElement as t,nothing as n,html as i}from"lit";import{property
34
32
  max-width: var(--nuraly-dropdown-max-width, 20rem);
35
33
  max-height: var(--nuraly-dropdown-max-height, 200px);
36
34
  overflow: auto;
35
+ /* Use display none to fully hide when closed */
36
+ display: none;
37
37
  /* Use opacity and visibility for smooth animations */
38
38
  opacity: 0;
39
39
  visibility: hidden;
40
40
  transform: translateY(-8px);
41
- transition: all var(--nuraly-dropdown-animation-duration, 0.15s) var(--nuraly-dropdown-animation-timing, ease);
41
+ transition: opacity var(--nuraly-dropdown-animation-duration, 0.15s) var(--nuraly-dropdown-animation-timing, ease),
42
+ visibility var(--nuraly-dropdown-animation-duration, 0.15s) var(--nuraly-dropdown-animation-timing, ease),
43
+ transform var(--nuraly-dropdown-animation-duration, 0.15s) var(--nuraly-dropdown-animation-timing, ease);
42
44
  /* Ensure proper containment */
43
45
  box-sizing: border-box;
44
46
  /* Create new stacking context to prevent layering issues */
45
47
  isolation: isolate;
46
48
  /* Force above other elements */
47
49
  transform-origin: top center;
50
+ /* Prevent clipping by overflow containers */
51
+ pointer-events: none;
48
52
  }
49
53
 
50
54
  .dropdown__panel--open {
55
+ display: block;
51
56
  opacity: 1;
52
57
  visibility: visible;
53
58
  transform: translateY(0);
59
+ pointer-events: auto;
54
60
  }
55
61
 
56
62
  /* Alternative attribute-based selector (like select component) */
57
63
  :host([open]) .dropdown__panel {
64
+ display: block;
58
65
  opacity: 1;
59
66
  visibility: visible;
60
67
  transform: translateY(0);
68
+ pointer-events: auto;
61
69
  }
62
70
 
63
- /* Placement variants */
71
+ /* Placement variants - transform origin adjustments */
64
72
  .dropdown__panel--top,
65
73
  .dropdown__panel--top-start,
66
74
  .dropdown__panel--top-end {
67
- top: auto;
68
- bottom: 100%;
69
- margin-bottom: 1px;
70
- margin-top: 0;
75
+ transform-origin: bottom center;
71
76
  transform: translateY(8px);
72
77
  }
73
78
 
@@ -77,16 +82,10 @@ import{css as o,LitElement as t,nothing as n,html as i}from"lit";import{property
77
82
  transform: translateY(0);
78
83
  }
79
84
 
80
- .dropdown__panel--bottom-end,
81
- .dropdown__panel--top-end {
82
- left: auto;
83
- right: 0;
84
- }
85
-
85
+ .dropdown__panel--bottom,
86
86
  .dropdown__panel--bottom-start,
87
- .dropdown__panel--top-start {
88
- left: 0;
89
- right: auto;
87
+ .dropdown__panel--bottom-end {
88
+ transform-origin: top center;
90
89
  }
91
90
 
92
91
  /* Size variants */
@@ -348,7 +347,7 @@ import{css as o,LitElement as t,nothing as n,html as i}from"lit";import{property
348
347
  box-shadow: var(--nuraly-dropdown-shadow, 0 2px 6px rgba(0, 0, 0, 0.15));
349
348
  min-width: var(--nuraly-dropdown-min-width, 10rem);
350
349
  max-width: var(--nuraly-dropdown-max-width, 20rem);
351
- max-height: var(--nuraly-dropdown-max-height, 200px);
350
+ max-height: var(--nuraly-dropdown-max-height, auto);
352
351
  overflow: auto;
353
352
  box-sizing: border-box;
354
353
  animation: fadeInSubmenu 0.15s ease;
@@ -446,19 +445,19 @@ import{css as o,LitElement as t,nothing as n,html as i}from"lit";import{property
446
445
  display: none !important;
447
446
  }
448
447
 
449
- `;class p{constructor(o){this._host=o,this._host.addController(this)}get host(){return this._host}hostConnected(){}hostDisconnected(){}hostUpdate(){}hostUpdated(){}requestUpdate(){this._host.requestUpdate()}dispatchEvent(o){return this._host.dispatchEvent(o)}handleError(o,t){console.error(`Dropdown Controller Error in ${t}:`,o)}findElement(o){var t;return null===(t=this._host.shadowRoot)||void 0===t?void 0:t.querySelector(o)}findElements(o){var t;return null===(t=this._host.shadowRoot)||void 0===t?void 0:t.querySelectorAll(o)}}class h extends p{constructor(o){super(o),this._isOpen=!1,this._position={top:0,left:0,width:0,placement:"bottom"},this._triggerElement=null,this._dropdownElement=null,this._outsideClickHandler=null,this._keydownHandler=null,this._hoverTimer=null,this._triggerClickHandler=null,this._triggerHoverHandler=null,this._triggerLeaveHandler=null,this._triggerFocusHandler=null,this._triggerBlurHandler=null,this._scrollHandler=null,this._resizeHandler=null,this._isOpen=o.open}get isOpen(){return this._isOpen}get position(){return Object.assign({},this._position)}hostConnected(){}hostUpdated(){this._isOpen!==this.host.open&&(this._isOpen=this.host.open),this._triggerElement||this.setupTriggerListeners()}hostDisconnected(){this.cleanup()}open(){try{this._isOpen||this.host.disabled||(this._isOpen=!0,this.host.open=!0,this.requestUpdate(),setTimeout((()=>{this.calculatePosition(),this.setupEventListeners()}),10),this.dispatchEvent(new CustomEvent("nr-dropdown-open",{bubbles:!0,composed:!0,detail:{dropdown:this.host}})))}catch(o){this.handleError(o,"open")}}close(){try{this._isOpen&&(this.removeEventListeners(),this._isOpen=!1,this.host.open=!1,this.requestUpdate(),this.dispatchEvent(new CustomEvent("nr-dropdown-close",{bubbles:!0,composed:!0,detail:{dropdown:this.host}})))}catch(o){this.handleError(o,"close")}}toggle(){try{this._isOpen?this.close():this.open()}catch(o){this.handleError(o,"toggle")}}removeTriggerListeners(){this._triggerElement&&(this._triggerClickHandler&&(this._triggerElement.removeEventListener("click",this._triggerClickHandler),this._triggerClickHandler=null),this._triggerHoverHandler&&(this._triggerElement.removeEventListener("mouseenter",this._triggerHoverHandler),this._triggerHoverHandler=null),this._triggerLeaveHandler&&(this._triggerElement.removeEventListener("mouseleave",this._triggerLeaveHandler),this._triggerLeaveHandler=null),this._triggerFocusHandler&&(this._triggerElement.removeEventListener("focusin",this._triggerFocusHandler),this._triggerFocusHandler=null),this._triggerBlurHandler&&(this._triggerElement.removeEventListener("focusout",this._triggerBlurHandler),this._triggerBlurHandler=null))}findDropdownElements(){this._dropdownElement=this.findElement(".dropdown__panel"),this._triggerElement=this.findElement(".dropdown__trigger")}setupTriggerListeners(){if(this.findDropdownElements(),this._triggerElement)switch(this.removeTriggerListeners(),this.host.trigger){case"click":this._triggerClickHandler=this.handleTriggerClick.bind(this),this._triggerElement.addEventListener("click",this._triggerClickHandler);break;case"hover":this._triggerHoverHandler=this.handleTriggerHover.bind(this),this._triggerLeaveHandler=this.handleTriggerLeave.bind(this),this._triggerElement.addEventListener("mouseenter",this._triggerHoverHandler),this._triggerElement.addEventListener("mouseleave",this._triggerLeaveHandler);break;case"focus":this._triggerFocusHandler=this.handleTriggerFocus.bind(this),this._triggerBlurHandler=this.handleTriggerBlur.bind(this),this._triggerElement.addEventListener("focusin",this._triggerFocusHandler),this._triggerElement.addEventListener("focusout",this._triggerBlurHandler)}}setupEventListeners(){this.host.closeOnOutsideClick&&(this._outsideClickHandler=this.handleOutsideClick.bind(this),document.addEventListener("click",this._outsideClickHandler,!0)),this.host.closeOnEscape&&(this._keydownHandler=this.handleKeydown.bind(this),document.addEventListener("keydown",this._keydownHandler)),this._scrollHandler=this.handleScroll.bind(this),this._resizeHandler=this.handleResize.bind(this),window.addEventListener("scroll",this._scrollHandler,!0),window.addEventListener("resize",this._resizeHandler)}removeEventListeners(){this._outsideClickHandler&&(document.removeEventListener("click",this._outsideClickHandler,!0),this._outsideClickHandler=null),this._keydownHandler&&(document.removeEventListener("keydown",this._keydownHandler),this._keydownHandler=null),this._scrollHandler&&(window.removeEventListener("scroll",this._scrollHandler,!0),this._scrollHandler=null),this._resizeHandler&&(window.removeEventListener("resize",this._resizeHandler),this._resizeHandler=null)}handleTriggerClick(){this.host.disabled||this.toggle()}handleTriggerHover(){this.host.disabled||(this._hoverTimer&&clearTimeout(this._hoverTimer),this._hoverTimer=window.setTimeout((()=>{this.open()}),this.host.delay))}handleTriggerLeave(){this._hoverTimer&&(clearTimeout(this._hoverTimer),this._hoverTimer=null),setTimeout((()=>{this.isHoveringDropdown()||this.close()}),100)}handleTriggerFocus(){this.host.disabled||this.open()}handleTriggerBlur(){setTimeout((()=>{this.isDropdownFocused()||this.close()}),100)}handleOutsideClick(o){var t,n;const i=o.target;if(null===(t=this._triggerElement)||void 0===t?void 0:t.contains(i))return;if(i.closest(".dropdown__panel"))return;if(null===(n=this._dropdownElement)||void 0===n?void 0:n.contains(i))return;if(i.closest("nr-dropdown"))return;if(i.closest(".dropdown__custom-content"))return;if(["INPUT","BUTTON","TEXTAREA","SELECT","A"].includes(i.tagName)){if(i.closest(".dropdown__panel"))return}i.closest(".dropdown")||i.closest('[class*="dropdown"]')||this.host.closeOnOutsideClick&&this.close()}handleKeydown(o){"Escape"===o.key&&this.close()}handleScroll(){}handleResize(){this._isOpen&&this.calculatePosition()}calculatePosition(){var o;try{if(this._dropdownElement&&this._triggerElement||this.findDropdownElements(),!this._dropdownElement||!this._triggerElement)return;const t=this._triggerElement.getBoundingClientRect(),n=((null===(o=window.visualViewport)||void 0===o?void 0:o.height)||window.innerHeight)-t.bottom,i=t.top,e=200,r=this.determineOptimalPlacement(e,i,n);this.applyPlacement(r)}catch(o){this.handleError(o,"calculatePosition")}}determineOptimalPlacement(o,t,n){return n>=o?"bottom":t>=o||t>n?"top":"bottom"}applyPlacement(o){this._dropdownElement&&(this._dropdownElement.classList.remove("dropdown__panel--top","dropdown__panel--bottom"),this._dropdownElement.classList.add(`dropdown__panel--${o}`),this._position.placement=o)}isHoveringDropdown(){var o;return(null===(o=this._dropdownElement)||void 0===o?void 0:o.matches(":hover"))||!1}isDropdownFocused(){var o;const t=document.activeElement;if(!t)return!1;if(null===(o=this._dropdownElement)||void 0===o?void 0:o.contains(t))return!0;if(t.closest(".dropdown__custom-content"))return!0;if(["INPUT","BUTTON","TEXTAREA","SELECT","A"].includes(t.tagName)){if(t.closest(".dropdown__panel"))return!0}return!1}handleItemClick(o){this.dispatchEvent(new CustomEvent("nr-dropdown-item-click",{bubbles:!0,composed:!0,detail:{item:o,dropdown:this.host}})),this.host.autoClose&&this.close()}cleanup(){this.removeEventListeners(),this.removeTriggerListeners(),this._hoverTimer&&(clearTimeout(this._hoverTimer),this._hoverTimer=null)}}
448
+ `;class p{constructor(o){this._host=o,this._host.addController(this)}get host(){return this._host}hostConnected(){}hostDisconnected(){}hostUpdate(){}hostUpdated(){}requestUpdate(){this._host.requestUpdate()}dispatchEvent(o){return this._host.dispatchEvent(o)}handleError(o,t){console.error(`Dropdown Controller Error in ${t}:`,o)}findElement(o){var t;return null===(t=this._host.shadowRoot)||void 0===t?void 0:t.querySelector(o)}findElements(o){var t;return null===(t=this._host.shadowRoot)||void 0===t?void 0:t.querySelectorAll(o)}}class h extends p{constructor(o){super(o),this._isOpen=!1,this._position={top:0,left:0,width:0,placement:"bottom"},this._triggerElement=null,this._dropdownElement=null,this._outsideClickHandler=null,this._keydownHandler=null,this._hoverTimer=null,this._triggerClickHandler=null,this._triggerHoverHandler=null,this._triggerLeaveHandler=null,this._triggerFocusHandler=null,this._triggerBlurHandler=null,this._scrollHandler=null,this._resizeHandler=null,this._isOpen=o.open}get isOpen(){return this._isOpen}get position(){return Object.assign({},this._position)}hostConnected(){}hostUpdated(){this._isOpen!==this.host.open&&(this._isOpen=this.host.open),this._triggerElement||this.setupTriggerListeners()}hostDisconnected(){this.cleanup()}open(){try{this._isOpen||this.host.disabled||(this._isOpen=!0,this.host.open=!0,this.requestUpdate(),setTimeout(()=>{this.calculatePosition(),this.setupEventListeners()},10),this.dispatchEvent(new CustomEvent("nr-dropdown-open",{bubbles:!0,composed:!0,detail:{dropdown:this.host}})))}catch(o){this.handleError(o,"open")}}close(){try{this._isOpen&&(this.removeEventListeners(),this._isOpen=!1,this.host.open=!1,this.requestUpdate(),this.dispatchEvent(new CustomEvent("nr-dropdown-close",{bubbles:!0,composed:!0,detail:{dropdown:this.host}})))}catch(o){this.handleError(o,"close")}}toggle(){try{this._isOpen?this.close():this.open()}catch(o){this.handleError(o,"toggle")}}removeTriggerListeners(){this._triggerElement&&(this._triggerClickHandler&&(this._triggerElement.removeEventListener("click",this._triggerClickHandler),this._triggerClickHandler=null),this._triggerHoverHandler&&(this._triggerElement.removeEventListener("mouseenter",this._triggerHoverHandler),this._triggerHoverHandler=null),this._triggerLeaveHandler&&(this._triggerElement.removeEventListener("mouseleave",this._triggerLeaveHandler),this._triggerLeaveHandler=null),this._triggerFocusHandler&&(this._triggerElement.removeEventListener("focusin",this._triggerFocusHandler),this._triggerFocusHandler=null),this._triggerBlurHandler&&(this._triggerElement.removeEventListener("focusout",this._triggerBlurHandler),this._triggerBlurHandler=null))}findDropdownElements(){this._dropdownElement=this.findElement(".dropdown__panel"),this._triggerElement=this.findElement(".dropdown__trigger")}setupTriggerListeners(){if(this.findDropdownElements(),this._triggerElement)switch(this.removeTriggerListeners(),this.host.trigger){case"click":this._triggerClickHandler=this.handleTriggerClick.bind(this),this._triggerElement.addEventListener("click",this._triggerClickHandler);break;case"hover":this._triggerHoverHandler=this.handleTriggerHover.bind(this),this._triggerLeaveHandler=this.handleTriggerLeave.bind(this),this._triggerElement.addEventListener("mouseenter",this._triggerHoverHandler),this._triggerElement.addEventListener("mouseleave",this._triggerLeaveHandler);break;case"focus":this._triggerFocusHandler=this.handleTriggerFocus.bind(this),this._triggerBlurHandler=this.handleTriggerBlur.bind(this),this._triggerElement.addEventListener("focusin",this._triggerFocusHandler),this._triggerElement.addEventListener("focusout",this._triggerBlurHandler)}}setupEventListeners(){this.host.closeOnOutsideClick&&(this._outsideClickHandler=this.handleOutsideClick.bind(this),document.addEventListener("click",this._outsideClickHandler,!0)),this.host.closeOnEscape&&(this._keydownHandler=this.handleKeydown.bind(this),document.addEventListener("keydown",this._keydownHandler)),this._scrollHandler=this.handleScroll.bind(this),this._resizeHandler=this.handleResize.bind(this),window.addEventListener("scroll",this._scrollHandler,!0),window.addEventListener("resize",this._resizeHandler)}removeEventListeners(){this._outsideClickHandler&&(document.removeEventListener("click",this._outsideClickHandler,!0),this._outsideClickHandler=null),this._keydownHandler&&(document.removeEventListener("keydown",this._keydownHandler),this._keydownHandler=null),this._scrollHandler&&(window.removeEventListener("scroll",this._scrollHandler,!0),this._scrollHandler=null),this._resizeHandler&&(window.removeEventListener("resize",this._resizeHandler),this._resizeHandler=null)}handleTriggerClick(){this.host.disabled||this.toggle()}handleTriggerHover(){this.host.disabled||(this._hoverTimer&&clearTimeout(this._hoverTimer),this._hoverTimer=window.setTimeout(()=>{this.open()},this.host.delay))}handleTriggerLeave(){this._hoverTimer&&(clearTimeout(this._hoverTimer),this._hoverTimer=null),setTimeout(()=>{this.isHoveringDropdown()||this.close()},100)}handleTriggerFocus(){this.host.disabled||this.open()}handleTriggerBlur(){setTimeout(()=>{this.isDropdownFocused()||this.close()},100)}handleOutsideClick(o){var t,n,i,e;if(!this.host.closeOnOutsideClick)return;const r=o.target;if(null===(t=this._triggerElement)||void 0===t?void 0:t.contains(r))return;if(null===(n=this._dropdownElement)||void 0===n?void 0:n.contains(r))return;const d=o.composedPath();for(const o of d){if(o===this._dropdownElement)return;if(o instanceof Element&&(null===(i=this._dropdownElement)||void 0===i?void 0:i.contains(o)))return}let s=r;for(;s;){const o=s.getRootNode();if(!(o instanceof ShadowRoot&&o.host))break;if(null===(e=this._dropdownElement)||void 0===e?void 0:e.contains(o.host))return;s=o.host}this.close()}handleKeydown(o){"Escape"===o.key&&this.close()}handleScroll(){this._isOpen&&this.calculatePosition()}handleResize(){this._isOpen&&this.calculatePosition()}calculatePosition(){var o,t;try{if(this._dropdownElement&&this._triggerElement||this.findDropdownElements(),!this._dropdownElement||!this._triggerElement)return;const n=this._triggerElement.getBoundingClientRect(),i=this._dropdownElement.getBoundingClientRect(),e=(null===(o=window.visualViewport)||void 0===o?void 0:o.height)||window.innerHeight,r=(null===(t=window.visualViewport)||void 0===t?void 0:t.width)||window.innerWidth,d=e-n.bottom,s=n.top,a=r-n.right,l=n.left,p=i.height||200,h=i.width||300,c=this.determineOptimalPlacement(p,s,d),u=this.determineHorizontalPlacement(h,l,a);let w,m;w="bottom"===c?n.bottom+this.host.offset:n.top-p-this.host.offset,m="left"===u?n.right-h:n.left,m=Math.max(8,Math.min(m,r-h-8)),w=Math.max(8,Math.min(w,e-p-8)),this._dropdownElement.style.top=`${w}px`,this._dropdownElement.style.left=`${m}px`,this.applyPlacement(c,u)}catch(o){this.handleError(o,"calculatePosition")}}determineOptimalPlacement(o,t,n){return n>=o?"bottom":t>=o||t>n?"top":"bottom"}determineHorizontalPlacement(o,t,n){const i=this.host.placement;if(i.includes("left")||i.includes("right")){if(i.includes("left")&&t>=o)return"left";if(i.includes("right")&&n>=o)return"right"}return n>=o?"right":t>=o?"left":n>t?"right":"left"}applyPlacement(o,t){this._dropdownElement&&(this._dropdownElement.classList.remove("dropdown__panel--top","dropdown__panel--bottom","dropdown__panel--left-aligned","dropdown__panel--right-aligned"),this._dropdownElement.classList.add(`dropdown__panel--${o}`),"left"===t?this._dropdownElement.classList.add("dropdown__panel--right-aligned"):"right"===t&&this._dropdownElement.classList.add("dropdown__panel--left-aligned"),this._position.placement=o)}isHoveringDropdown(){var o;return(null===(o=this._dropdownElement)||void 0===o?void 0:o.matches(":hover"))||!1}isDropdownFocused(){var o;const t=document.activeElement;if(!t)return!1;if(null===(o=this._dropdownElement)||void 0===o?void 0:o.contains(t))return!0;if(t.closest(".dropdown__custom-content"))return!0;if(["INPUT","BUTTON","TEXTAREA","SELECT","A"].includes(t.tagName)){if(t.closest(".dropdown__panel"))return!0}return!1}handleItemClick(o,t){this.dispatchEvent(new CustomEvent("nr-dropdown-item-click",{bubbles:!0,composed:!0,detail:{item:o,dropdown:this.host,originalEvent:t}})),this.host.autoClose&&this.close()}cleanup(){this.removeEventListeners(),this.removeTriggerListeners(),this._hoverTimer&&(clearTimeout(this._hoverTimer),this._hoverTimer=null)}}
450
449
  /**
451
450
  * @license
452
451
  * Copyright 2023 Nuraly, Laabidi Aymen
453
452
  * SPDX-License-Identifier: MIT
454
- */var c=function(o,t,n,i){for(var e,r=arguments.length,d=r<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,n):i,s=o.length-1;s>=0;s--)(e=o[s])&&(d=(r<3?e(d):r>3?e(t,n,d):e(t,n))||d);return r>3&&d&&Object.defineProperty(t,n,d),d};let u=class extends(a(t)){constructor(){super(...arguments),this.requiredComponents=["nr-icon"],this.items=[],this.open=!1,this.placement="bottom",this.trigger="hover",this.size="medium",this.animation="fade",this.disabled=!1,this.arrow=!1,this.autoClose=!1,this.closeOnOutsideClick=!0,this.closeOnEscape=!0,this.offset=4,this.delay=50,this.maxHeight="300px",this.minWidth="auto",this.cascadeDirection="auto",this.cascadeDelay=50,this.cascadeOnHover=!0,this.dropdownController=new h(this),this.openSubmenus=new Set,this.submenuTimers=new Map,this.handleDropdownPanelClick=o=>{o.stopPropagation()},this.handleItemClick=o=>{o.disabled||(o.options&&o.options.length>0||o.customContent?this.toggleSubmenu(o.id):this.dropdownController.handleItemClick(o))},this.handleItemHover=o=>{var t;if(((null===(t=o.options)||void 0===t?void 0:t.length)||o.customContent)&&(this.clearSubmenuTimer(o.id),this.cascadeOnHover)){const t=window.setTimeout((()=>{this.showSubmenu(o.id)}),this.cascadeDelay);this.submenuTimers.set(o.id,t)}},this.handleItemLeave=o=>{var t;if(!(null===(t=o.options)||void 0===t?void 0:t.length)&&!o.customContent)return;this.clearSubmenuTimer(o.id);const n=window.setTimeout((()=>{this.hideSubmenu(o.id)}),100);this.submenuTimers.set(`hide-${o.id}`,n)},this.handleSubmenuEnter=o=>{this.clearSubmenuTimer(`hide-${o}`)},this.handleSubmenuLeave=o=>{const t=window.setTimeout((()=>{this.hideSubmenu(o)}),100);this.submenuTimers.set(`hide-${o}`,t)}}connectedCallback(){super.connectedCallback(),this.updateCascadingAttribute()}updated(o){super.updated(o),o.has("items")&&this.updateCascadingAttribute()}disconnectedCallback(){super.disconnectedCallback()}firstUpdated(){}updateCascadingAttribute(){this.items.some((o=>o.options&&o.options.length>0||!!o.customContent))?this.setAttribute("has-cascading",""):this.removeAttribute("has-cascading")}clearSubmenuTimer(o){const t=this.submenuTimers.get(o);t&&(clearTimeout(t),this.submenuTimers.delete(o))}toggleSubmenu(o){this.openSubmenus.has(o)?this.hideSubmenu(o):this.showSubmenu(o)}showSubmenu(o){this.openSubmenus.add(o),this.requestUpdate()}hideSubmenu(o){this.openSubmenus.delete(o),this.requestUpdate()}show(){this.dropdownController.open()}hide(){this.dropdownController.close()}toggle(){this.dropdownController.toggle()}renderItems(){return this.items.length?i`
453
+ */var c=function(o,t,n,i){for(var e,r=arguments.length,d=r<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,n):i,s=o.length-1;s>=0;s--)(e=o[s])&&(d=(r<3?e(d):r>3?e(t,n,d):e(t,n))||d);return r>3&&d&&Object.defineProperty(t,n,d),d};let u=class extends(a(t)){constructor(){super(...arguments),this.requiredComponents=["nr-icon"],this.items=[],this.open=!1,this.placement="bottom",this.trigger="hover",this.size="medium",this.animation="fade",this.disabled=!1,this.arrow=!1,this.autoClose=!1,this.closeOnOutsideClick=!0,this.closeOnEscape=!0,this.offset=4,this.delay=50,this.maxHeight="300px",this.minWidth="auto",this.cascadeDirection="auto",this.cascadeDelay=50,this.cascadeOnHover=!0,this.dropdownController=new h(this),this.openSubmenus=new Set,this.submenuTimers=new Map,this.handleDropdownPanelClick=o=>{o.stopPropagation()},this.handleItemClick=(o,t)=>{o.disabled||(o.options&&o.options.length>0||o.customContent?this.toggleSubmenu(o.id):this.dropdownController.handleItemClick(o,t))},this.handleItemHover=o=>{var t;if(((null===(t=o.options)||void 0===t?void 0:t.length)||o.customContent)&&(this.clearSubmenuTimer(o.id),this.cascadeOnHover)){const t=window.setTimeout(()=>{this.showSubmenu(o.id)},this.cascadeDelay);this.submenuTimers.set(o.id,t)}},this.handleItemLeave=o=>{var t;if(!(null===(t=o.options)||void 0===t?void 0:t.length)&&!o.customContent)return;this.clearSubmenuTimer(o.id);const n=window.setTimeout(()=>{this.hideSubmenu(o.id)},100);this.submenuTimers.set(`hide-${o.id}`,n)},this.handleSubmenuEnter=o=>{this.clearSubmenuTimer(`hide-${o}`)},this.handleSubmenuLeave=o=>{const t=window.setTimeout(()=>{this.hideSubmenu(o)},100);this.submenuTimers.set(`hide-${o}`,t)}}connectedCallback(){super.connectedCallback(),this.updateCascadingAttribute()}updated(o){super.updated(o),o.has("items")&&this.updateCascadingAttribute()}disconnectedCallback(){super.disconnectedCallback()}firstUpdated(){}updateCascadingAttribute(){this.items.some(o=>o.options&&o.options.length>0||!!o.customContent)?this.setAttribute("has-cascading",""):this.removeAttribute("has-cascading")}clearSubmenuTimer(o){const t=this.submenuTimers.get(o);t&&(clearTimeout(t),this.submenuTimers.delete(o))}toggleSubmenu(o){this.openSubmenus.has(o)?this.hideSubmenu(o):this.showSubmenu(o)}showSubmenu(o){this.openSubmenus.add(o),this.requestUpdate()}hideSubmenu(o){this.openSubmenus.delete(o),this.requestUpdate()}show(){this.dropdownController.open()}hide(){this.dropdownController.close()}toggle(){this.dropdownController.toggle()}renderItems(){return this.items.length?i`
455
454
  <div class="dropdown__items">
456
- ${this.items.map((o=>{if(o.divider)return i`<div class="dropdown__divider"></div>`;const t=!!(o.options&&o.options.length>0)||!!o.customContent,e=t&&this.openSubmenus.has(o.id);return i`
455
+ ${this.items.map(o=>{if(o.divider)return i`<div class="dropdown__divider"></div>`;const t=!!(o.options&&o.options.length>0)||!!o.customContent,e=t&&this.openSubmenus.has(o.id);return i`
457
456
  <div class="dropdown__item-container ${d({"dropdown__item-container--has-submenu":t})}">
458
457
  <button
459
458
  class="dropdown__item ${d({"dropdown__item--disabled":!!o.disabled,"dropdown__item--has-submenu":t})}"
460
459
  ?disabled="${o.disabled}"
461
- @click="${()=>this.handleItemClick(o)}"
460
+ @click="${t=>this.handleItemClick(o,t)}"
462
461
  @mouseenter="${()=>t&&this.handleItemHover(o)}"
463
462
  @mouseleave="${()=>t&&this.handleItemLeave(o)}"
464
463
  >
@@ -477,22 +476,22 @@ import{css as o,LitElement as t,nothing as n,html as i}from"lit";import{property
477
476
  </div>
478
477
  `:i`
479
478
  <div class="dropdown__items">
480
- ${o.options.map((o=>o.divider?i`<div class="dropdown__divider"></div>`:i`
479
+ ${o.options.map(o=>o.divider?i`<div class="dropdown__divider"></div>`:i`
481
480
  <button
482
481
  class="dropdown__item ${d({"dropdown__item--disabled":!!o.disabled})}"
483
482
  ?disabled="${o.disabled}"
484
- @click="${()=>this.handleItemClick(o)}"
483
+ @click="${t=>this.handleItemClick(o,t)}"
485
484
  >
486
485
  ${o.icon?i`<nr-icon name="${o.icon}" class="dropdown__item-icon"></nr-icon>`:n}
487
486
  <span class="dropdown__item-label">${o.label}</span>
488
487
  </button>
489
- `))}
488
+ `)}
490
489
  </div>
491
490
  `}
492
491
  </div>
493
492
  `:n}
494
493
  </div>
495
- `}))}
494
+ `})}
496
495
  </div>
497
496
  `:n}render(){const o={dropdown__panel:!0,"dropdown__panel--open":this.open,[`dropdown__panel--${this.size}`]:!0,[`dropdown__panel--${this.animation}`]:!0,[`dropdown__panel--${this.placement}`]:!0,"dropdown__panel--with-arrow":this.arrow},t={maxHeight:this.maxHeight,minWidth:this.minWidth};return i`
498
497
  <div class="dropdown">
@@ -89,6 +89,7 @@ export declare class NrDropdownElement extends NrDropdownElement_base {
89
89
  cascadeDirection: 'right' | 'left' | 'auto';
90
90
  cascadeDelay: number;
91
91
  cascadeOnHover: boolean;
92
+ allowOverflow: boolean;
92
93
  private dropdownController;
93
94
  private openSubmenus;
94
95
  private submenuTimers;
@@ -111,7 +112,7 @@ export declare class NrDropdownElement extends NrDropdownElement_base {
111
112
  hide(): void;
112
113
  toggle(): void;
113
114
  private renderItems;
114
- render(): import("lit").TemplateResult<1>;
115
+ render(): import("lit-html").TemplateResult<1>;
115
116
  }
116
117
  export {};
117
118
  //# sourceMappingURL=dropdown.component.d.ts.map
@@ -100,20 +100,21 @@ let NrDropdownElement = class NrDropdownElement extends NuralyUIBaseMixin(LitEle
100
100
  this.cascadeDirection = 'auto';
101
101
  this.cascadeDelay = 50;
102
102
  this.cascadeOnHover = true;
103
+ this.allowOverflow = false;
103
104
  this.dropdownController = new NrDropdownController(this);
104
105
  this.openSubmenus = new Set();
105
106
  this.submenuTimers = new Map();
106
107
  this.handleDropdownPanelClick = (e) => {
107
108
  e.stopPropagation();
108
109
  };
109
- this.handleItemClick = (item) => {
110
+ this.handleItemClick = (item, e) => {
110
111
  if (item.disabled)
111
112
  return;
112
113
  if ((item.options && item.options.length > 0) || item.customContent) {
113
114
  this.toggleSubmenu(item.id);
114
115
  return;
115
116
  }
116
- this.dropdownController.handleItemClick(item);
117
+ this.dropdownController.handleItemClick(item, e);
117
118
  };
118
119
  this.handleItemHover = (item) => {
119
120
  var _a;
@@ -224,7 +225,7 @@ let NrDropdownElement = class NrDropdownElement extends NuralyUIBaseMixin(LitEle
224
225
  'dropdown__item--has-submenu': hasSubmenu
225
226
  })}"
226
227
  ?disabled="${item.disabled}"
227
- @click="${() => this.handleItemClick(item)}"
228
+ @click="${(e) => this.handleItemClick(item, e)}"
228
229
  @mouseenter="${() => hasSubmenu && this.handleItemHover(item)}"
229
230
  @mouseleave="${() => hasSubmenu && this.handleItemLeave(item)}"
230
231
  >
@@ -258,7 +259,7 @@ let NrDropdownElement = class NrDropdownElement extends NuralyUIBaseMixin(LitEle
258
259
  'dropdown__item--disabled': !!subItem.disabled
259
260
  })}"
260
261
  ?disabled="${subItem.disabled}"
261
- @click="${() => this.handleItemClick(subItem)}"
262
+ @click="${(e) => this.handleItemClick(subItem, e)}"
262
263
  >
263
264
  ${subItem.icon ? html `<nr-icon name="${subItem.icon}" class="dropdown__item-icon"></nr-icon>` : nothing}
264
265
  <span class="dropdown__item-label">${subItem.label}</span>
@@ -368,6 +369,9 @@ __decorate([
368
369
  __decorate([
369
370
  property({ type: Boolean, attribute: 'cascade-on-hover' })
370
371
  ], NrDropdownElement.prototype, "cascadeOnHover", void 0);
372
+ __decorate([
373
+ property({ type: Boolean, attribute: 'allow-overflow' })
374
+ ], NrDropdownElement.prototype, "allowOverflow", void 0);
371
375
  NrDropdownElement = __decorate([
372
376
  customElement('nr-dropdown')
373
377
  ], NrDropdownElement);
@@ -1 +1 @@
1
- {"version":3,"file":"dropdown.component.js","sourceRoot":"","sources":["../../../src/components/dropdown/dropdown.component.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2023 Nuraly, Laabidi Aymen\n * SPDX-License-Identifier: MIT\n */\n\nimport { html, LitElement, nothing } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { styles } from './dropdown.style';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { styleMap } from 'lit/directives/style-map.js';\nimport { NuralyUIBaseMixin } from '@nuralyui/common/mixins';\nimport { NrDropdownController } from './controllers/dropdown.controller.js';\n\nimport {\n DropdownPlacement,\n DropdownTrigger,\n DropdownSize,\n DropdownAnimation,\n DropdownItem\n} from './dropdown.types.js';\n\n/**\n * # Dropdown Component\n * \n * A versatile dropdown component that provides floating panel functionality with customizable triggers,\n * content, and positioning. Supports both predefined item lists and custom slot content with\n * cascading submenus and interactive elements.\n * \n * ## Features\n * - Multiple trigger modes (hover, click, focus, manual)\n * - Flexible positioning with auto-placement\n * - Cascading submenus with custom content support\n * - Interactive elements (forms, buttons) within dropdowns\n * - Keyboard navigation and accessibility\n * - Customizable animations and styling\n * - Event delegation and outside click detection\n * \n * ## Usage\n * ```html\n * <!-- Basic dropdown with slot content -->\n * <nr-dropdown trigger=\"hover\">\n * <button slot=\"trigger\">Menu</button>\n * <div slot=\"content\">\n * <p>Custom content here</p>\n * </div>\n * </nr-dropdown>\n * \n * <!-- Dropdown with predefined items -->\n * <nr-dropdown \n * .items=\"${items}\" \n * placement=\"bottom-start\"\n * trigger=\"click\">\n * <button slot=\"trigger\">Menu</button>\n * </nr-dropdown>\n * \n * <!-- Hover dropdown with custom positioning -->\n * <nr-dropdown \n * trigger=\"hover\" \n * placement=\"top\"\n * size=\"large\">\n * <span slot=\"trigger\">Hover me</span>\n * <div slot=\"content\">Tooltip content</div>\n * </nr-dropdown>\n * ```\n * \n * @element nr-dropdown\n * @fires nr-dropdown-open - Fired when dropdown opens\n * @fires nr-dropdown-close - Fired when dropdown closes\n * @fires nr-dropdown-item-click - Fired when dropdown item is clicked\n * \n * @slot trigger - Element that triggers the dropdown\n * @slot content - Custom content for the dropdown panel\n * @slot header - Optional header content\n * @slot footer - Optional footer content\n * \n * @cssproperty --dropdown-background - Background color of dropdown panel\n * @cssproperty --dropdown-border - Border of dropdown panel\n * @cssproperty --dropdown-shadow - Shadow of dropdown panel\n * @cssproperty --dropdown-border-radius - Border radius of dropdown panel\n * @cssproperty --dropdown-max-width - Maximum width of dropdown panel\n * @cssproperty --dropdown-min-width - Minimum width of dropdown panel\n * @cssproperty --dropdown-max-height - Maximum height of dropdown panel\n */\n@customElement('nr-dropdown')\nexport class NrDropdownElement extends NuralyUIBaseMixin(LitElement) {\n static override styles = styles;\n\n override requiredComponents = ['nr-icon'];\n\n @property({ type: Array }) items: DropdownItem[] = [];\n @property({ type: Boolean, reflect: true }) open = false;\n @property({ type: String }) placement: DropdownPlacement = DropdownPlacement.Bottom;\n @property({ type: String }) trigger: DropdownTrigger = DropdownTrigger.Hover;\n @property({ type: String }) size: DropdownSize = DropdownSize.Medium;\n @property({ type: String }) animation: DropdownAnimation = DropdownAnimation.Fade;\n @property({ type: Boolean }) disabled = false;\n @property({ type: Boolean }) arrow = false;\n @property({ type: Boolean, attribute: 'auto-close' }) autoClose = false;\n @property({ type: Boolean, attribute: 'close-on-outside-click' }) closeOnOutsideClick = true;\n @property({ type: Boolean, attribute: 'close-on-escape' }) closeOnEscape = true;\n @property({ type: Number }) offset = 4;\n @property({ type: Number }) delay = 50;\n @property({ type: String, attribute: 'max-height' }) maxHeight = '300px';\n @property({ type: String, attribute: 'min-width' }) minWidth = 'auto';\n @property({ type: String, attribute: 'cascade-direction' }) cascadeDirection: 'right' | 'left' | 'auto' = 'auto';\n @property({ type: Number, attribute: 'cascade-delay' }) cascadeDelay = 50;\n @property({ type: Boolean, attribute: 'cascade-on-hover' }) cascadeOnHover = true;\n\n private dropdownController = new NrDropdownController(this);\n private openSubmenus = new Set<string>();\n private submenuTimers = new Map<string, number>();\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.updateCascadingAttribute();\n }\n\n override updated(changedProperties: Map<string, any>): void {\n super.updated(changedProperties);\n if (changedProperties.has('items')) {\n this.updateCascadingAttribute();\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n }\n\n override firstUpdated(): void {\n }\n\n private updateCascadingAttribute(): void {\n const hasCascading = this.items.some(item => \n (item.options && item.options.length > 0) || !!item.customContent\n );\n if (hasCascading) {\n this.setAttribute('has-cascading', '');\n } else {\n this.removeAttribute('has-cascading');\n }\n }\n\n private handleDropdownPanelClick = (e: Event): void => {\n e.stopPropagation();\n };\n\n private handleItemClick = (item: DropdownItem): void => {\n if (item.disabled) return;\n\n if ((item.options && item.options.length > 0) || item.customContent) {\n this.toggleSubmenu(item.id);\n return;\n }\n\n this.dropdownController.handleItemClick(item);\n };\n\n private handleItemHover = (item: DropdownItem): void => {\n if (!item.options?.length && !item.customContent) return;\n\n this.clearSubmenuTimer(item.id);\n\n if (this.cascadeOnHover) {\n const timer = window.setTimeout(() => {\n this.showSubmenu(item.id);\n }, this.cascadeDelay);\n this.submenuTimers.set(item.id, timer);\n }\n };\n\n private handleItemLeave = (item: DropdownItem): void => {\n if (!item.options?.length && !item.customContent) return;\n\n this.clearSubmenuTimer(item.id);\n\n const timer = window.setTimeout(() => {\n this.hideSubmenu(item.id);\n }, 100);\n this.submenuTimers.set(`hide-${item.id}`, timer);\n };\n\n private handleSubmenuEnter = (itemId: string): void => {\n this.clearSubmenuTimer(`hide-${itemId}`);\n };\n\n private handleSubmenuLeave = (itemId: string): void => {\n const timer = window.setTimeout(() => {\n this.hideSubmenu(itemId);\n }, 100);\n this.submenuTimers.set(`hide-${itemId}`, timer);\n };\n\n private clearSubmenuTimer(key: string): void {\n const timer = this.submenuTimers.get(key);\n if (timer) {\n clearTimeout(timer);\n this.submenuTimers.delete(key);\n }\n }\n\n private toggleSubmenu(itemId: string): void {\n if (this.openSubmenus.has(itemId)) {\n this.hideSubmenu(itemId);\n } else {\n this.showSubmenu(itemId);\n }\n }\n\n private showSubmenu(itemId: string): void {\n this.openSubmenus.add(itemId);\n this.requestUpdate();\n }\n\n private hideSubmenu(itemId: string): void {\n this.openSubmenus.delete(itemId);\n this.requestUpdate();\n }\n\n show(): void {\n this.dropdownController.open();\n }\n\n hide(): void {\n this.dropdownController.close();\n }\n\n toggle(): void {\n this.dropdownController.toggle();\n }\n\n private renderItems(): unknown {\n if (!this.items.length) return nothing;\n\n return html`\n <div class=\"dropdown__items\">\n ${this.items.map(item => {\n if (item.divider) {\n return html`<div class=\"dropdown__divider\"></div>`;\n }\n\n const hasSubmenu = !!(item.options && item.options.length > 0) || !!item.customContent;\n const isSubmenuOpen = hasSubmenu && this.openSubmenus.has(item.id);\n\n return html`\n <div class=\"dropdown__item-container ${classMap({\n 'dropdown__item-container--has-submenu': hasSubmenu\n })}\">\n <button\n class=\"dropdown__item ${classMap({\n 'dropdown__item--disabled': !!item.disabled,\n 'dropdown__item--has-submenu': hasSubmenu\n })}\"\n ?disabled=\"${item.disabled}\"\n @click=\"${() => this.handleItemClick(item)}\"\n @mouseenter=\"${() => hasSubmenu && this.handleItemHover(item)}\"\n @mouseleave=\"${() => hasSubmenu && this.handleItemLeave(item)}\"\n >\n ${item.icon ? html`<nr-icon name=\"${item.icon}\" class=\"dropdown__item-icon\"></nr-icon>` : nothing}\n <span class=\"dropdown__item-label\">${item.label}</span>\n ${hasSubmenu ? html`<nr-icon name=\"chevron-right\" class=\"dropdown__submenu-arrow\"></nr-icon>` : nothing}\n </button>\n \n ${hasSubmenu && isSubmenuOpen ? html`\n <div class=\"dropdown__submenu ${classMap({\n 'dropdown__submenu--right': this.cascadeDirection === 'right' || this.cascadeDirection === 'auto',\n 'dropdown__submenu--left': this.cascadeDirection === 'left'\n })}\"\n @mouseenter=\"${() => this.handleSubmenuEnter(item.id)}\"\n @mouseleave=\"${() => this.handleSubmenuLeave(item.id)}\">\n ${item.customContent ? html`\n <div class=\"dropdown__custom-content\">\n ${typeof item.customContent === 'string' \n ? html`<div .innerHTML=\"${item.customContent}\"></div>`\n : item.customContent\n }\n </div>\n ` : html`\n <div class=\"dropdown__items\">\n ${item.options!.map(subItem => {\n if (subItem.divider) {\n return html`<div class=\"dropdown__divider\"></div>`;\n }\n \n return html`\n <button\n class=\"dropdown__item ${classMap({\n 'dropdown__item--disabled': !!subItem.disabled\n })}\"\n ?disabled=\"${subItem.disabled}\"\n @click=\"${() => this.handleItemClick(subItem)}\"\n >\n ${subItem.icon ? html`<nr-icon name=\"${subItem.icon}\" class=\"dropdown__item-icon\"></nr-icon>` : nothing}\n <span class=\"dropdown__item-label\">${subItem.label}</span>\n </button>\n `;\n })}\n </div>\n `}\n </div>\n ` : nothing}\n </div>\n `;\n })}\n </div>\n `;\n }\n\n override render() {\n const panelClasses = {\n 'dropdown__panel': true,\n 'dropdown__panel--open': this.open,\n [`dropdown__panel--${this.size}`]: true,\n [`dropdown__panel--${this.animation}`]: true,\n [`dropdown__panel--${this.placement}`]: true,\n 'dropdown__panel--with-arrow': this.arrow\n };\n\n const panelStyles = {\n maxHeight: this.maxHeight,\n minWidth: this.minWidth\n };\n\n return html`\n <div class=\"dropdown\">\n <div class=\"dropdown__trigger\">\n <slot name=\"trigger\"></slot>\n </div>\n \n <div \n class=\"${classMap(panelClasses)}\"\n style=\"${styleMap(panelStyles)}\"\n @click=\"${this.handleDropdownPanelClick}\"\n >\n ${this.arrow ? html`<div class=\"dropdown__arrow\"></div>` : nothing}\n \n <slot name=\"header\"></slot>\n \n <div class=\"dropdown__content\">\n <slot name=\"content\">${this.renderItems()}</slot>\n </div>\n \n <slot name=\"footer\"></slot>\n </div>\n </div>\n `;\n }\n}"]}
1
+ {"version":3,"file":"dropdown.component.js","sourceRoot":"","sources":["../../../../src/components/dropdown/dropdown.component.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2023 Nuraly, Laabidi Aymen\n * SPDX-License-Identifier: MIT\n */\n\nimport { html, LitElement, nothing } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { styles } from './dropdown.style';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { styleMap } from 'lit/directives/style-map.js';\nimport { NuralyUIBaseMixin } from '@nuralyui/common/mixins';\nimport { NrDropdownController } from './controllers/dropdown.controller.js';\n\nimport {\n DropdownPlacement,\n DropdownTrigger,\n DropdownSize,\n DropdownAnimation,\n DropdownItem\n} from './dropdown.types.js';\n\n/**\n * # Dropdown Component\n * \n * A versatile dropdown component that provides floating panel functionality with customizable triggers,\n * content, and positioning. Supports both predefined item lists and custom slot content with\n * cascading submenus and interactive elements.\n * \n * ## Features\n * - Multiple trigger modes (hover, click, focus, manual)\n * - Flexible positioning with auto-placement\n * - Cascading submenus with custom content support\n * - Interactive elements (forms, buttons) within dropdowns\n * - Keyboard navigation and accessibility\n * - Customizable animations and styling\n * - Event delegation and outside click detection\n * \n * ## Usage\n * ```html\n * <!-- Basic dropdown with slot content -->\n * <nr-dropdown trigger=\"hover\">\n * <button slot=\"trigger\">Menu</button>\n * <div slot=\"content\">\n * <p>Custom content here</p>\n * </div>\n * </nr-dropdown>\n * \n * <!-- Dropdown with predefined items -->\n * <nr-dropdown \n * .items=\"${items}\" \n * placement=\"bottom-start\"\n * trigger=\"click\">\n * <button slot=\"trigger\">Menu</button>\n * </nr-dropdown>\n * \n * <!-- Hover dropdown with custom positioning -->\n * <nr-dropdown \n * trigger=\"hover\" \n * placement=\"top\"\n * size=\"large\">\n * <span slot=\"trigger\">Hover me</span>\n * <div slot=\"content\">Tooltip content</div>\n * </nr-dropdown>\n * ```\n * \n * @element nr-dropdown\n * @fires nr-dropdown-open - Fired when dropdown opens\n * @fires nr-dropdown-close - Fired when dropdown closes\n * @fires nr-dropdown-item-click - Fired when dropdown item is clicked\n * \n * @slot trigger - Element that triggers the dropdown\n * @slot content - Custom content for the dropdown panel\n * @slot header - Optional header content\n * @slot footer - Optional footer content\n * \n * @cssproperty --dropdown-background - Background color of dropdown panel\n * @cssproperty --dropdown-border - Border of dropdown panel\n * @cssproperty --dropdown-shadow - Shadow of dropdown panel\n * @cssproperty --dropdown-border-radius - Border radius of dropdown panel\n * @cssproperty --dropdown-max-width - Maximum width of dropdown panel\n * @cssproperty --dropdown-min-width - Minimum width of dropdown panel\n * @cssproperty --dropdown-max-height - Maximum height of dropdown panel\n */\n@customElement('nr-dropdown')\nexport class NrDropdownElement extends NuralyUIBaseMixin(LitElement) {\n static override styles = styles;\n\n override requiredComponents = ['nr-icon'];\n\n @property({ type: Array }) items: DropdownItem[] = [];\n @property({ type: Boolean, reflect: true }) open = false;\n @property({ type: String }) placement: DropdownPlacement = DropdownPlacement.Bottom;\n @property({ type: String }) trigger: DropdownTrigger = DropdownTrigger.Hover;\n @property({ type: String }) size: DropdownSize = DropdownSize.Medium;\n @property({ type: String }) animation: DropdownAnimation = DropdownAnimation.Fade;\n @property({ type: Boolean }) disabled = false;\n @property({ type: Boolean }) arrow = false;\n @property({ type: Boolean, attribute: 'auto-close' }) autoClose = false;\n @property({ type: Boolean, attribute: 'close-on-outside-click' }) closeOnOutsideClick = true;\n @property({ type: Boolean, attribute: 'close-on-escape' }) closeOnEscape = true;\n @property({ type: Number }) offset = 4;\n @property({ type: Number }) delay = 50;\n @property({ type: String, attribute: 'max-height' }) maxHeight = '300px';\n @property({ type: String, attribute: 'min-width' }) minWidth = 'auto';\n @property({ type: String, attribute: 'cascade-direction' }) cascadeDirection: 'right' | 'left' | 'auto' = 'auto';\n @property({ type: Number, attribute: 'cascade-delay' }) cascadeDelay = 50;\n @property({ type: Boolean, attribute: 'cascade-on-hover' }) cascadeOnHover = true;\n @property({ type: Boolean, attribute: 'allow-overflow' }) allowOverflow = false;\n\n private dropdownController = new NrDropdownController(this);\n private openSubmenus = new Set<string>();\n private submenuTimers = new Map<string, number>();\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.updateCascadingAttribute();\n }\n\n override updated(changedProperties: Map<string, any>): void {\n super.updated(changedProperties);\n if (changedProperties.has('items')) {\n this.updateCascadingAttribute();\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n }\n\n override firstUpdated(): void {\n }\n\n private updateCascadingAttribute(): void {\n const hasCascading = this.items.some(item => \n (item.options && item.options.length > 0) || !!item.customContent\n );\n if (hasCascading) {\n this.setAttribute('has-cascading', '');\n } else {\n this.removeAttribute('has-cascading');\n }\n }\n\n private handleDropdownPanelClick = (e: Event): void => {\n e.stopPropagation();\n };\n\n private handleItemClick = (item: DropdownItem, e?: MouseEvent): void => {\n if (item.disabled) return;\n\n if ((item.options && item.options.length > 0) || item.customContent) {\n this.toggleSubmenu(item.id);\n return;\n }\n\n this.dropdownController.handleItemClick(item, e);\n };\n\n private handleItemHover = (item: DropdownItem): void => {\n if (!item.options?.length && !item.customContent) return;\n\n this.clearSubmenuTimer(item.id);\n\n if (this.cascadeOnHover) {\n const timer = window.setTimeout(() => {\n this.showSubmenu(item.id);\n }, this.cascadeDelay);\n this.submenuTimers.set(item.id, timer);\n }\n };\n\n private handleItemLeave = (item: DropdownItem): void => {\n if (!item.options?.length && !item.customContent) return;\n\n this.clearSubmenuTimer(item.id);\n\n const timer = window.setTimeout(() => {\n this.hideSubmenu(item.id);\n }, 100);\n this.submenuTimers.set(`hide-${item.id}`, timer);\n };\n\n private handleSubmenuEnter = (itemId: string): void => {\n this.clearSubmenuTimer(`hide-${itemId}`);\n };\n\n private handleSubmenuLeave = (itemId: string): void => {\n const timer = window.setTimeout(() => {\n this.hideSubmenu(itemId);\n }, 100);\n this.submenuTimers.set(`hide-${itemId}`, timer);\n };\n\n private clearSubmenuTimer(key: string): void {\n const timer = this.submenuTimers.get(key);\n if (timer) {\n clearTimeout(timer);\n this.submenuTimers.delete(key);\n }\n }\n\n private toggleSubmenu(itemId: string): void {\n if (this.openSubmenus.has(itemId)) {\n this.hideSubmenu(itemId);\n } else {\n this.showSubmenu(itemId);\n }\n }\n\n private showSubmenu(itemId: string): void {\n this.openSubmenus.add(itemId);\n this.requestUpdate();\n }\n\n private hideSubmenu(itemId: string): void {\n this.openSubmenus.delete(itemId);\n this.requestUpdate();\n }\n\n show(): void {\n this.dropdownController.open();\n }\n\n hide(): void {\n this.dropdownController.close();\n }\n\n toggle(): void {\n this.dropdownController.toggle();\n }\n\n private renderItems(): unknown {\n if (!this.items.length) return nothing;\n\n return html`\n <div class=\"dropdown__items\">\n ${this.items.map(item => {\n if (item.divider) {\n return html`<div class=\"dropdown__divider\"></div>`;\n }\n\n const hasSubmenu = !!(item.options && item.options.length > 0) || !!item.customContent;\n const isSubmenuOpen = hasSubmenu && this.openSubmenus.has(item.id);\n\n return html`\n <div class=\"dropdown__item-container ${classMap({\n 'dropdown__item-container--has-submenu': hasSubmenu\n })}\">\n <button\n class=\"dropdown__item ${classMap({\n 'dropdown__item--disabled': !!item.disabled,\n 'dropdown__item--has-submenu': hasSubmenu\n })}\"\n ?disabled=\"${item.disabled}\"\n @click=\"${(e: MouseEvent) => this.handleItemClick(item, e)}\"\n @mouseenter=\"${() => hasSubmenu && this.handleItemHover(item)}\"\n @mouseleave=\"${() => hasSubmenu && this.handleItemLeave(item)}\"\n >\n ${item.icon ? html`<nr-icon name=\"${item.icon}\" class=\"dropdown__item-icon\"></nr-icon>` : nothing}\n <span class=\"dropdown__item-label\">${item.label}</span>\n ${hasSubmenu ? html`<nr-icon name=\"chevron-right\" class=\"dropdown__submenu-arrow\"></nr-icon>` : nothing}\n </button>\n \n ${hasSubmenu && isSubmenuOpen ? html`\n <div class=\"dropdown__submenu ${classMap({\n 'dropdown__submenu--right': this.cascadeDirection === 'right' || this.cascadeDirection === 'auto',\n 'dropdown__submenu--left': this.cascadeDirection === 'left'\n })}\"\n @mouseenter=\"${() => this.handleSubmenuEnter(item.id)}\"\n @mouseleave=\"${() => this.handleSubmenuLeave(item.id)}\">\n ${item.customContent ? html`\n <div class=\"dropdown__custom-content\">\n ${typeof item.customContent === 'string' \n ? html`<div .innerHTML=\"${item.customContent}\"></div>`\n : item.customContent\n }\n </div>\n ` : html`\n <div class=\"dropdown__items\">\n ${item.options!.map(subItem => {\n if (subItem.divider) {\n return html`<div class=\"dropdown__divider\"></div>`;\n }\n \n return html`\n <button\n class=\"dropdown__item ${classMap({\n 'dropdown__item--disabled': !!subItem.disabled\n })}\"\n ?disabled=\"${subItem.disabled}\"\n @click=\"${(e: MouseEvent) => this.handleItemClick(subItem, e)}\"\n >\n ${subItem.icon ? html`<nr-icon name=\"${subItem.icon}\" class=\"dropdown__item-icon\"></nr-icon>` : nothing}\n <span class=\"dropdown__item-label\">${subItem.label}</span>\n </button>\n `;\n })}\n </div>\n `}\n </div>\n ` : nothing}\n </div>\n `;\n })}\n </div>\n `;\n }\n\n override render() {\n const panelClasses = {\n 'dropdown__panel': true,\n 'dropdown__panel--open': this.open,\n [`dropdown__panel--${this.size}`]: true,\n [`dropdown__panel--${this.animation}`]: true,\n [`dropdown__panel--${this.placement}`]: true,\n 'dropdown__panel--with-arrow': this.arrow\n };\n\n const panelStyles = {\n maxHeight: this.maxHeight,\n minWidth: this.minWidth\n };\n\n return html`\n <div class=\"dropdown\">\n <div class=\"dropdown__trigger\">\n <slot name=\"trigger\"></slot>\n </div>\n \n <div \n class=\"${classMap(panelClasses)}\"\n style=\"${styleMap(panelStyles)}\"\n @click=\"${this.handleDropdownPanelClick}\"\n >\n ${this.arrow ? html`<div class=\"dropdown__arrow\"></div>` : nothing}\n \n <slot name=\"header\"></slot>\n \n <div class=\"dropdown__content\">\n <slot name=\"content\">${this.renderItems()}</slot>\n </div>\n \n <slot name=\"footer\"></slot>\n </div>\n </div>\n `;\n }\n}"]}
package/dropdown.style.js CHANGED
@@ -23,9 +23,7 @@ export const styles = css `
23
23
  }
24
24
 
25
25
  .dropdown__panel {
26
- position: absolute;
27
- top: 100%;
28
- left: 0;
26
+ position: fixed;
29
27
  z-index: var(--nuraly-dropdown-z-index, 9999);
30
28
  background: var(--nuraly-color-dropdown-background, #ffffff);
31
29
  border: var(--nuraly-dropdown-border-width, 1px) solid var(--nuraly-color-dropdown-border, #e0e0e0);
@@ -35,59 +33,60 @@ export const styles = css `
35
33
  max-width: var(--nuraly-dropdown-max-width, 20rem);
36
34
  max-height: var(--nuraly-dropdown-max-height, 200px);
37
35
  overflow: auto;
36
+ /* Use display none to fully hide when closed */
37
+ display: none;
38
38
  /* Use opacity and visibility for smooth animations */
39
39
  opacity: 0;
40
40
  visibility: hidden;
41
41
  transform: translateY(-8px);
42
- transition: all var(--nuraly-dropdown-animation-duration, 0.15s) var(--nuraly-dropdown-animation-timing, ease);
42
+ transition: opacity var(--nuraly-dropdown-animation-duration, 0.15s) var(--nuraly-dropdown-animation-timing, ease),
43
+ visibility var(--nuraly-dropdown-animation-duration, 0.15s) var(--nuraly-dropdown-animation-timing, ease),
44
+ transform var(--nuraly-dropdown-animation-duration, 0.15s) var(--nuraly-dropdown-animation-timing, ease);
43
45
  /* Ensure proper containment */
44
46
  box-sizing: border-box;
45
47
  /* Create new stacking context to prevent layering issues */
46
48
  isolation: isolate;
47
49
  /* Force above other elements */
48
50
  transform-origin: top center;
51
+ /* Prevent clipping by overflow containers */
52
+ pointer-events: none;
49
53
  }
50
54
 
51
55
  .dropdown__panel--open {
56
+ display: block;
52
57
  opacity: 1;
53
58
  visibility: visible;
54
- transform: translateY(0);
59
+ transform: none;
60
+ pointer-events: auto;
55
61
  }
56
62
 
57
63
  /* Alternative attribute-based selector (like select component) */
58
64
  :host([open]) .dropdown__panel {
65
+ display: block;
59
66
  opacity: 1;
60
67
  visibility: visible;
61
- transform: translateY(0);
68
+ transform: none;
69
+ pointer-events: auto;
62
70
  }
63
71
 
64
- /* Placement variants */
72
+ /* Placement variants - transform origin adjustments */
65
73
  .dropdown__panel--top,
66
74
  .dropdown__panel--top-start,
67
75
  .dropdown__panel--top-end {
68
- top: auto;
69
- bottom: 100%;
70
- margin-bottom: 1px;
71
- margin-top: 0;
76
+ transform-origin: bottom center;
72
77
  transform: translateY(8px);
73
78
  }
74
79
 
75
80
  .dropdown__panel--top.dropdown__panel--open,
76
81
  .dropdown__panel--top-start.dropdown__panel--open,
77
82
  .dropdown__panel--top-end.dropdown__panel--open {
78
- transform: translateY(0);
79
- }
80
-
81
- .dropdown__panel--bottom-end,
82
- .dropdown__panel--top-end {
83
- left: auto;
84
- right: 0;
83
+ transform: none;
85
84
  }
86
85
 
86
+ .dropdown__panel--bottom,
87
87
  .dropdown__panel--bottom-start,
88
- .dropdown__panel--top-start {
89
- left: 0;
90
- right: auto;
88
+ .dropdown__panel--bottom-end {
89
+ transform-origin: top center;
91
90
  }
92
91
 
93
92
  /* Size variants */
@@ -156,7 +155,7 @@ export const styles = css `
156
155
  .dropdown__panel--slide.dropdown__panel--open {
157
156
  opacity: 1;
158
157
  visibility: visible;
159
- transform: translateY(0);
158
+ transform: none;
160
159
  }
161
160
 
162
161
  /* For top-positioned dropdowns, slide direction is reversed */
@@ -182,7 +181,7 @@ export const styles = css `
182
181
  .dropdown__panel--scale.dropdown__panel--open {
183
182
  opacity: 1;
184
183
  visibility: visible;
185
- transform: scale(1) translateY(0);
184
+ transform: none;
186
185
  }
187
186
 
188
187
  /* For top-positioned scale dropdowns */
@@ -195,7 +194,7 @@ export const styles = css `
195
194
  .dropdown__panel--scale.dropdown__panel--top.dropdown__panel--open,
196
195
  .dropdown__panel--scale.dropdown__panel--top-start.dropdown__panel--open,
197
196
  .dropdown__panel--scale.dropdown__panel--top-end.dropdown__panel--open {
198
- transform: scale(1) translateY(0);
197
+ transform: none;
199
198
  }
200
199
 
201
200
  /* Arrow */
@@ -349,7 +348,7 @@ export const styles = css `
349
348
  box-shadow: var(--nuraly-dropdown-shadow, 0 2px 6px rgba(0, 0, 0, 0.15));
350
349
  min-width: var(--nuraly-dropdown-min-width, 10rem);
351
350
  max-width: var(--nuraly-dropdown-max-width, 20rem);
352
- max-height: var(--nuraly-dropdown-max-height, 200px);
351
+ max-height: var(--nuraly-dropdown-max-height, auto);
353
352
  overflow: auto;
354
353
  box-sizing: border-box;
355
354
  animation: fadeInSubmenu 0.15s ease;
@@ -442,6 +441,16 @@ export const styles = css `
442
441
  pointer-events: none;
443
442
  }
444
443
 
444
+ /* Allow overflow for nested dropdowns/selects */
445
+ :host([allow-overflow]) .dropdown__panel {
446
+ overflow: visible !important;
447
+ max-height: none !important;
448
+ }
449
+
450
+ :host([allow-overflow]) .dropdown__content {
451
+ overflow: visible !important;
452
+ }
453
+
445
454
  /* Hidden state */
446
455
  [hidden] {
447
456
  display: none !important;
@@ -1 +1 @@
1
- {"version":3,"file":"dropdown.style.js","sourceRoot":"","sources":["../../../src/components/dropdown/dropdown.style.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgcxB,CAAC","sourcesContent":["import { css } from 'lit';\n\nexport const styles = css`\n :host {\n display: inline-block;\n position: relative;\n color: var(--nuraly-color-text);\n font-family: var(--nuraly-dropdown-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif);\n }\n\n .dropdown {\n position: relative;\n display: inline-block;\n }\n\n .dropdown__trigger {\n display: inline-block;\n cursor: pointer;\n }\n\n .dropdown__trigger:focus-within {\n outline: var(--nuraly-focus-outline, 2px solid #0f62fe);\n outline-offset: var(--nuraly-focus-outline-offset, 1px);\n }\n\n .dropdown__panel {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: var(--nuraly-dropdown-z-index, 9999);\n background: var(--nuraly-color-dropdown-background, #ffffff);\n border: var(--nuraly-dropdown-border-width, 1px) solid var(--nuraly-color-dropdown-border, #e0e0e0);\n border-radius: var(--nuraly-dropdown-border-radius, 6px);\n box-shadow: var(--nuraly-dropdown-shadow, 0 2px 6px rgba(0, 0, 0, 0.15));\n min-width: var(--nuraly-dropdown-min-width, 10rem);\n max-width: var(--nuraly-dropdown-max-width, 20rem);\n max-height: var(--nuraly-dropdown-max-height, 200px);\n overflow: auto;\n /* Use opacity and visibility for smooth animations */\n opacity: 0;\n visibility: hidden;\n transform: translateY(-8px);\n transition: all var(--nuraly-dropdown-animation-duration, 0.15s) var(--nuraly-dropdown-animation-timing, ease);\n /* Ensure proper containment */\n box-sizing: border-box;\n /* Create new stacking context to prevent layering issues */\n isolation: isolate;\n /* Force above other elements */\n transform-origin: top center;\n }\n\n .dropdown__panel--open {\n opacity: 1;\n visibility: visible;\n transform: translateY(0);\n }\n\n /* Alternative attribute-based selector (like select component) */\n :host([open]) .dropdown__panel {\n opacity: 1;\n visibility: visible;\n transform: translateY(0);\n }\n\n /* Placement variants */\n .dropdown__panel--top,\n .dropdown__panel--top-start,\n .dropdown__panel--top-end {\n top: auto;\n bottom: 100%;\n margin-bottom: 1px;\n margin-top: 0;\n transform: translateY(8px);\n }\n\n .dropdown__panel--top.dropdown__panel--open,\n .dropdown__panel--top-start.dropdown__panel--open,\n .dropdown__panel--top-end.dropdown__panel--open {\n transform: translateY(0);\n }\n\n .dropdown__panel--bottom-end,\n .dropdown__panel--top-end {\n left: auto;\n right: 0;\n }\n\n .dropdown__panel--bottom-start,\n .dropdown__panel--top-start {\n left: 0;\n right: auto;\n }\n\n /* Size variants */\n .dropdown__panel--small {\n font-size: var(--nuraly-dropdown-small-font-size, 0.75rem);\n }\n\n .dropdown__panel--medium {\n font-size: var(--nuraly-dropdown-font-size, 0.875rem);\n }\n\n .dropdown__panel--large {\n font-size: var(--nuraly-dropdown-large-font-size, 1rem);\n }\n\n /* Animation variants */\n \n /* No animation - instant show/hide */\n .dropdown__panel--none {\n transition: none;\n }\n\n .dropdown__panel--none:not(.dropdown__panel--open) {\n opacity: 0;\n visibility: hidden;\n transform: none;\n }\n\n .dropdown__panel--none.dropdown__panel--open {\n opacity: 1;\n visibility: visible;\n transform: none;\n }\n\n /* Fade animation - opacity only */\n .dropdown__panel--fade {\n transition: opacity var(--nuraly-dropdown-animation-duration, 0.15s) var(--nuraly-dropdown-animation-timing, ease),\n visibility var(--nuraly-dropdown-animation-duration, 0.15s) var(--nuraly-dropdown-animation-timing, ease);\n }\n\n .dropdown__panel--fade:not(.dropdown__panel--open) {\n opacity: 0;\n visibility: hidden;\n transform: none;\n }\n\n .dropdown__panel--fade.dropdown__panel--open {\n opacity: 1;\n visibility: visible;\n transform: none;\n }\n\n /* Slide animation - slide down/up with opacity */\n .dropdown__panel--slide {\n transition: opacity var(--nuraly-dropdown-animation-duration, 0.15s) var(--nuraly-dropdown-animation-timing, ease),\n visibility var(--nuraly-dropdown-animation-duration, 0.15s) var(--nuraly-dropdown-animation-timing, ease),\n transform var(--nuraly-dropdown-animation-duration, 0.15s) var(--nuraly-dropdown-animation-timing, ease);\n }\n\n .dropdown__panel--slide:not(.dropdown__panel--open) {\n opacity: 0;\n visibility: hidden;\n transform: translateY(-12px);\n }\n\n .dropdown__panel--slide.dropdown__panel--open {\n opacity: 1;\n visibility: visible;\n transform: translateY(0);\n }\n\n /* For top-positioned dropdowns, slide direction is reversed */\n .dropdown__panel--slide.dropdown__panel--top:not(.dropdown__panel--open),\n .dropdown__panel--slide.dropdown__panel--top-start:not(.dropdown__panel--open),\n .dropdown__panel--slide.dropdown__panel--top-end:not(.dropdown__panel--open) {\n transform: translateY(12px);\n }\n\n /* Scale animation - scale and opacity */\n .dropdown__panel--scale {\n transition: opacity var(--nuraly-dropdown-animation-duration, 0.15s) var(--nuraly-dropdown-animation-timing, ease),\n visibility var(--nuraly-dropdown-animation-duration, 0.15s) var(--nuraly-dropdown-animation-timing, ease),\n transform var(--nuraly-dropdown-animation-duration, 0.15s) cubic-bezier(0.25, 0.46, 0.45, 0.94);\n }\n\n .dropdown__panel--scale:not(.dropdown__panel--open) {\n opacity: 0;\n visibility: hidden;\n transform: scale(0.9) translateY(-8px);\n }\n\n .dropdown__panel--scale.dropdown__panel--open {\n opacity: 1;\n visibility: visible;\n transform: scale(1) translateY(0);\n }\n\n /* For top-positioned scale dropdowns */\n .dropdown__panel--scale.dropdown__panel--top:not(.dropdown__panel--open),\n .dropdown__panel--scale.dropdown__panel--top-start:not(.dropdown__panel--open),\n .dropdown__panel--scale.dropdown__panel--top-end:not(.dropdown__panel--open) {\n transform: scale(0.9) translateY(8px);\n }\n\n .dropdown__panel--scale.dropdown__panel--top.dropdown__panel--open,\n .dropdown__panel--scale.dropdown__panel--top-start.dropdown__panel--open,\n .dropdown__panel--scale.dropdown__panel--top-end.dropdown__panel--open {\n transform: scale(1) translateY(0);\n }\n\n /* Arrow */\n .dropdown__arrow {\n position: absolute;\n width: 0;\n height: 0;\n border: var(--nuraly-dropdown-arrow-size) solid transparent;\n border-bottom-color: var(--nuraly-dropdown-background);\n top: calc(-1 * var(--nuraly-dropdown-arrow-size) * 2);\n left: 50%;\n transform: translateX(-50%);\n }\n\n .dropdown__arrow::before {\n content: '';\n position: absolute;\n width: 0;\n height: 0;\n border: calc(var(--nuraly-dropdown-arrow-size) + 1px) solid transparent;\n border-bottom-color: var(--nuraly-dropdown-border-color);\n top: calc(-1 * var(--nuraly-dropdown-arrow-size) - 1px);\n left: calc(-1 * var(--nuraly-dropdown-arrow-size) - 1px);\n }\n\n /* Content areas */\n .dropdown__content {\n overflow: auto;\n }\n\n .dropdown__items {\n display: flex;\n flex-direction: column;\n margin: 0;\n padding: 0;\n list-style: none;\n overflow: visible; /* Allow submenus to extend outside */\n }\n\n .dropdown__item {\n display: flex;\n align-items: center;\n gap: var(--nuraly-dropdown-item-gap);\n padding: var(--nuraly-dropdown-item-padding);\n background: var(--nuraly-color-dropdown-item-background);\n border: none;\n color: var(--nuraly-color-dropdown-item-text);\n cursor: pointer;\n text-align: left;\n width: 100%;\n min-height: var(--nuraly-dropdown-item-min-height);\n transition: var(--nuraly-dropdown-item-transition);\n font-size: inherit;\n font-family: inherit;\n line-height: var(--nuraly-dropdown-item-line-height);\n position: relative;\n }\n\n .dropdown__item:hover:not(.dropdown__item--disabled) {\n background: var(--nuraly-color-dropdown-item-background-hover);\n color: var(--nuraly-color-dropdown-item-text-hover);\n }\n\n .dropdown__item:focus {\n outline: none;\n background: var(--nuraly-color-dropdown-item-background-focus);\n color: var(--nuraly-color-dropdown-item-text-focus);\n }\n\n .dropdown__item:focus-visible {\n outline: 2px solid var(--nuraly-focus-color, #0f62fe);\n outline-offset: -2px;\n background: var(--nuraly-color-dropdown-item-background-focus);\n color: var(--nuraly-color-dropdown-item-text-focus);\n }\n\n .dropdown__item:active:not(.dropdown__item--disabled) {\n background: var(--nuraly-color-dropdown-item-background-active);\n color: var(--nuraly-color-dropdown-item-text-active);\n }\n\n .dropdown__item--disabled {\n opacity: var(--nuraly-dropdown-item-disabled-opacity, 0.5);\n cursor: not-allowed;\n pointer-events: none;\n }\n\n .dropdown__item-icon {\n flex-shrink: 0;\n width: var(--nuraly-dropdown-item-icon-size);\n height: var(--nuraly-dropdown-item-icon-size);\n }\n\n .dropdown__item-label {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .dropdown__divider {\n height: 1px;\n background: var(--nuraly-dropdown-divider-color);\n margin: var(--nuraly-dropdown-divider-margin);\n }\n\n /* Cascading dropdown styles */\n .dropdown__item-container {\n position: relative;\n }\n\n /* Allow submenus to overflow when dropdown has cascading items */\n :host([has-cascading]) .dropdown__panel {\n overflow: visible !important;\n max-height: none !important; /* Remove height restriction for cascading */\n }\n\n :host([has-cascading]) .dropdown__items {\n overflow: visible !important;\n }\n\n /* For cascading dropdowns, we need to handle scrolling differently */\n :host([has-cascading]) .dropdown__content {\n overflow: visible !important;\n }\n\n .dropdown__item--has-submenu {\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n\n .dropdown__submenu-arrow {\n margin-left: auto;\n font-size: 0.75em;\n opacity: 0.6;\n transition: transform 0.15s ease;\n }\n\n .dropdown__item--has-submenu:hover .dropdown__submenu-arrow {\n opacity: 1;\n }\n\n .dropdown__submenu {\n position: absolute;\n top: 0;\n z-index: calc(var(--nuraly-dropdown-z-index, 9999) + 1);\n background: var(--nuraly-color-dropdown-background, #ffffff);\n border: var(--nuraly-dropdown-border-width, 1px) solid var(--nuraly-color-dropdown-border, #e0e0e0);\n border-radius: var(--nuraly-dropdown-border-radius, 6px);\n box-shadow: var(--nuraly-dropdown-shadow, 0 2px 6px rgba(0, 0, 0, 0.15));\n min-width: var(--nuraly-dropdown-min-width, 10rem);\n max-width: var(--nuraly-dropdown-max-width, 20rem);\n max-height: var(--nuraly-dropdown-max-height, 200px);\n overflow: auto;\n box-sizing: border-box;\n animation: fadeInSubmenu 0.15s ease;\n /* Ensure submenu is visible */\n opacity: 1;\n visibility: visible;\n pointer-events: auto;\n }\n\n .dropdown__custom-content {\n padding: var(--nuraly-dropdown-item-padding, 8px 12px);\n max-width: 100%;\n box-sizing: border-box;\n }\n\n /* Custom content styling */\n .dropdown__custom-content h3,\n .dropdown__custom-content h4 {\n margin: 0 0 8px 0;\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--nuraly-color-text-primary);\n }\n\n .dropdown__custom-content p {\n margin: 0 0 8px 0;\n font-size: 0.75rem;\n color: var(--nuraly-color-text-secondary);\n line-height: 1.4;\n }\n\n .dropdown__custom-content button,\n .dropdown__custom-content input,\n .dropdown__custom-content select {\n width: 100%;\n margin-bottom: 8px;\n }\n\n .dropdown__custom-content button:last-child,\n .dropdown__custom-content input:last-child,\n .dropdown__custom-content p:last-child {\n margin-bottom: 0;\n }\n\n .dropdown__submenu--right {\n left: 100%;\n margin-left: 4px;\n }\n\n .dropdown__submenu--left {\n right: 100%;\n margin-right: 4px;\n }\n\n @keyframes fadeInSubmenu {\n from {\n opacity: 0;\n transform: translateX(-8px);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n }\n\n .dropdown__submenu--left {\n animation-name: fadeInSubmenuLeft;\n }\n\n @keyframes fadeInSubmenuLeft {\n from {\n opacity: 0;\n transform: translateX(8px);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n }\n\n /* Focus styles for accessibility */\n :host(:focus-within) .dropdown__trigger {\n outline: var(--nuraly-dropdown-focus-outline);\n outline-offset: var(--nuraly-dropdown-focus-offset);\n }\n\n /* Disabled state */\n :host([disabled]) {\n opacity: var(--nuraly-dropdown-disabled-opacity, 0.5);\n pointer-events: none;\n }\n\n /* Hidden state */\n [hidden] {\n display: none !important;\n }\n\n`;"]}
1
+ {"version":3,"file":"dropdown.style.js","sourceRoot":"","sources":["../../../../src/components/dropdown/dropdown.style.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAycxB,CAAC","sourcesContent":["import { css } from 'lit';\n\nexport const styles = css`\n :host {\n display: inline-block;\n position: relative;\n color: var(--nuraly-color-text);\n font-family: var(--nuraly-dropdown-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif);\n }\n\n .dropdown {\n position: relative;\n display: inline-block;\n }\n\n .dropdown__trigger {\n display: inline-block;\n cursor: pointer;\n }\n\n .dropdown__trigger:focus-within {\n outline: var(--nuraly-focus-outline, 2px solid #0f62fe);\n outline-offset: var(--nuraly-focus-outline-offset, 1px);\n }\n\n .dropdown__panel {\n position: fixed;\n z-index: var(--nuraly-dropdown-z-index, 9999);\n background: var(--nuraly-color-dropdown-background, #ffffff);\n border: var(--nuraly-dropdown-border-width, 1px) solid var(--nuraly-color-dropdown-border, #e0e0e0);\n border-radius: var(--nuraly-dropdown-border-radius, 6px);\n box-shadow: var(--nuraly-dropdown-shadow, 0 2px 6px rgba(0, 0, 0, 0.15));\n min-width: var(--nuraly-dropdown-min-width, 10rem);\n max-width: var(--nuraly-dropdown-max-width, 20rem);\n max-height: var(--nuraly-dropdown-max-height, 200px);\n overflow: auto;\n /* Use display none to fully hide when closed */\n display: none;\n /* Use opacity and visibility for smooth animations */\n opacity: 0;\n visibility: hidden;\n transform: translateY(-8px);\n transition: opacity var(--nuraly-dropdown-animation-duration, 0.15s) var(--nuraly-dropdown-animation-timing, ease),\n visibility var(--nuraly-dropdown-animation-duration, 0.15s) var(--nuraly-dropdown-animation-timing, ease),\n transform var(--nuraly-dropdown-animation-duration, 0.15s) var(--nuraly-dropdown-animation-timing, ease);\n /* Ensure proper containment */\n box-sizing: border-box;\n /* Create new stacking context to prevent layering issues */\n isolation: isolate;\n /* Force above other elements */\n transform-origin: top center;\n /* Prevent clipping by overflow containers */\n pointer-events: none;\n }\n\n .dropdown__panel--open {\n display: block;\n opacity: 1;\n visibility: visible;\n transform: none;\n pointer-events: auto;\n }\n\n /* Alternative attribute-based selector (like select component) */\n :host([open]) .dropdown__panel {\n display: block;\n opacity: 1;\n visibility: visible;\n transform: none;\n pointer-events: auto;\n }\n\n /* Placement variants - transform origin adjustments */\n .dropdown__panel--top,\n .dropdown__panel--top-start,\n .dropdown__panel--top-end {\n transform-origin: bottom center;\n transform: translateY(8px);\n }\n\n .dropdown__panel--top.dropdown__panel--open,\n .dropdown__panel--top-start.dropdown__panel--open,\n .dropdown__panel--top-end.dropdown__panel--open {\n transform: none;\n }\n\n .dropdown__panel--bottom,\n .dropdown__panel--bottom-start,\n .dropdown__panel--bottom-end {\n transform-origin: top center;\n }\n\n /* Size variants */\n .dropdown__panel--small {\n font-size: var(--nuraly-dropdown-small-font-size, 0.75rem);\n }\n\n .dropdown__panel--medium {\n font-size: var(--nuraly-dropdown-font-size, 0.875rem);\n }\n\n .dropdown__panel--large {\n font-size: var(--nuraly-dropdown-large-font-size, 1rem);\n }\n\n /* Animation variants */\n \n /* No animation - instant show/hide */\n .dropdown__panel--none {\n transition: none;\n }\n\n .dropdown__panel--none:not(.dropdown__panel--open) {\n opacity: 0;\n visibility: hidden;\n transform: none;\n }\n\n .dropdown__panel--none.dropdown__panel--open {\n opacity: 1;\n visibility: visible;\n transform: none;\n }\n\n /* Fade animation - opacity only */\n .dropdown__panel--fade {\n transition: opacity var(--nuraly-dropdown-animation-duration, 0.15s) var(--nuraly-dropdown-animation-timing, ease),\n visibility var(--nuraly-dropdown-animation-duration, 0.15s) var(--nuraly-dropdown-animation-timing, ease);\n }\n\n .dropdown__panel--fade:not(.dropdown__panel--open) {\n opacity: 0;\n visibility: hidden;\n transform: none;\n }\n\n .dropdown__panel--fade.dropdown__panel--open {\n opacity: 1;\n visibility: visible;\n transform: none;\n }\n\n /* Slide animation - slide down/up with opacity */\n .dropdown__panel--slide {\n transition: opacity var(--nuraly-dropdown-animation-duration, 0.15s) var(--nuraly-dropdown-animation-timing, ease),\n visibility var(--nuraly-dropdown-animation-duration, 0.15s) var(--nuraly-dropdown-animation-timing, ease),\n transform var(--nuraly-dropdown-animation-duration, 0.15s) var(--nuraly-dropdown-animation-timing, ease);\n }\n\n .dropdown__panel--slide:not(.dropdown__panel--open) {\n opacity: 0;\n visibility: hidden;\n transform: translateY(-12px);\n }\n\n .dropdown__panel--slide.dropdown__panel--open {\n opacity: 1;\n visibility: visible;\n transform: none;\n }\n\n /* For top-positioned dropdowns, slide direction is reversed */\n .dropdown__panel--slide.dropdown__panel--top:not(.dropdown__panel--open),\n .dropdown__panel--slide.dropdown__panel--top-start:not(.dropdown__panel--open),\n .dropdown__panel--slide.dropdown__panel--top-end:not(.dropdown__panel--open) {\n transform: translateY(12px);\n }\n\n /* Scale animation - scale and opacity */\n .dropdown__panel--scale {\n transition: opacity var(--nuraly-dropdown-animation-duration, 0.15s) var(--nuraly-dropdown-animation-timing, ease),\n visibility var(--nuraly-dropdown-animation-duration, 0.15s) var(--nuraly-dropdown-animation-timing, ease),\n transform var(--nuraly-dropdown-animation-duration, 0.15s) cubic-bezier(0.25, 0.46, 0.45, 0.94);\n }\n\n .dropdown__panel--scale:not(.dropdown__panel--open) {\n opacity: 0;\n visibility: hidden;\n transform: scale(0.9) translateY(-8px);\n }\n\n .dropdown__panel--scale.dropdown__panel--open {\n opacity: 1;\n visibility: visible;\n transform: none;\n }\n\n /* For top-positioned scale dropdowns */\n .dropdown__panel--scale.dropdown__panel--top:not(.dropdown__panel--open),\n .dropdown__panel--scale.dropdown__panel--top-start:not(.dropdown__panel--open),\n .dropdown__panel--scale.dropdown__panel--top-end:not(.dropdown__panel--open) {\n transform: scale(0.9) translateY(8px);\n }\n\n .dropdown__panel--scale.dropdown__panel--top.dropdown__panel--open,\n .dropdown__panel--scale.dropdown__panel--top-start.dropdown__panel--open,\n .dropdown__panel--scale.dropdown__panel--top-end.dropdown__panel--open {\n transform: none;\n }\n\n /* Arrow */\n .dropdown__arrow {\n position: absolute;\n width: 0;\n height: 0;\n border: var(--nuraly-dropdown-arrow-size) solid transparent;\n border-bottom-color: var(--nuraly-dropdown-background);\n top: calc(-1 * var(--nuraly-dropdown-arrow-size) * 2);\n left: 50%;\n transform: translateX(-50%);\n }\n\n .dropdown__arrow::before {\n content: '';\n position: absolute;\n width: 0;\n height: 0;\n border: calc(var(--nuraly-dropdown-arrow-size) + 1px) solid transparent;\n border-bottom-color: var(--nuraly-dropdown-border-color);\n top: calc(-1 * var(--nuraly-dropdown-arrow-size) - 1px);\n left: calc(-1 * var(--nuraly-dropdown-arrow-size) - 1px);\n }\n\n /* Content areas */\n .dropdown__content {\n overflow: auto;\n }\n\n .dropdown__items {\n display: flex;\n flex-direction: column;\n margin: 0;\n padding: 0;\n list-style: none;\n overflow: visible; /* Allow submenus to extend outside */\n }\n\n .dropdown__item {\n display: flex;\n align-items: center;\n gap: var(--nuraly-dropdown-item-gap);\n padding: var(--nuraly-dropdown-item-padding);\n background: var(--nuraly-color-dropdown-item-background);\n border: none;\n color: var(--nuraly-color-dropdown-item-text);\n cursor: pointer;\n text-align: left;\n width: 100%;\n min-height: var(--nuraly-dropdown-item-min-height);\n transition: var(--nuraly-dropdown-item-transition);\n font-size: inherit;\n font-family: inherit;\n line-height: var(--nuraly-dropdown-item-line-height);\n position: relative;\n }\n\n .dropdown__item:hover:not(.dropdown__item--disabled) {\n background: var(--nuraly-color-dropdown-item-background-hover);\n color: var(--nuraly-color-dropdown-item-text-hover);\n }\n\n .dropdown__item:focus {\n outline: none;\n background: var(--nuraly-color-dropdown-item-background-focus);\n color: var(--nuraly-color-dropdown-item-text-focus);\n }\n\n .dropdown__item:focus-visible {\n outline: 2px solid var(--nuraly-focus-color, #0f62fe);\n outline-offset: -2px;\n background: var(--nuraly-color-dropdown-item-background-focus);\n color: var(--nuraly-color-dropdown-item-text-focus);\n }\n\n .dropdown__item:active:not(.dropdown__item--disabled) {\n background: var(--nuraly-color-dropdown-item-background-active);\n color: var(--nuraly-color-dropdown-item-text-active);\n }\n\n .dropdown__item--disabled {\n opacity: var(--nuraly-dropdown-item-disabled-opacity, 0.5);\n cursor: not-allowed;\n pointer-events: none;\n }\n\n .dropdown__item-icon {\n flex-shrink: 0;\n width: var(--nuraly-dropdown-item-icon-size);\n height: var(--nuraly-dropdown-item-icon-size);\n }\n\n .dropdown__item-label {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .dropdown__divider {\n height: 1px;\n background: var(--nuraly-dropdown-divider-color);\n margin: var(--nuraly-dropdown-divider-margin);\n }\n\n /* Cascading dropdown styles */\n .dropdown__item-container {\n position: relative;\n }\n\n /* Allow submenus to overflow when dropdown has cascading items */\n :host([has-cascading]) .dropdown__panel {\n overflow: visible !important;\n max-height: none !important; /* Remove height restriction for cascading */\n }\n\n :host([has-cascading]) .dropdown__items {\n overflow: visible !important;\n }\n\n /* For cascading dropdowns, we need to handle scrolling differently */\n :host([has-cascading]) .dropdown__content {\n overflow: visible !important;\n }\n\n .dropdown__item--has-submenu {\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n\n .dropdown__submenu-arrow {\n margin-left: auto;\n font-size: 0.75em;\n opacity: 0.6;\n transition: transform 0.15s ease;\n }\n\n .dropdown__item--has-submenu:hover .dropdown__submenu-arrow {\n opacity: 1;\n }\n\n .dropdown__submenu {\n position: absolute;\n top: 0;\n z-index: calc(var(--nuraly-dropdown-z-index, 9999) + 1);\n background: var(--nuraly-color-dropdown-background, #ffffff);\n border: var(--nuraly-dropdown-border-width, 1px) solid var(--nuraly-color-dropdown-border, #e0e0e0);\n border-radius: var(--nuraly-dropdown-border-radius, 6px);\n box-shadow: var(--nuraly-dropdown-shadow, 0 2px 6px rgba(0, 0, 0, 0.15));\n min-width: var(--nuraly-dropdown-min-width, 10rem);\n max-width: var(--nuraly-dropdown-max-width, 20rem);\n max-height: var(--nuraly-dropdown-max-height, auto);\n overflow: auto;\n box-sizing: border-box;\n animation: fadeInSubmenu 0.15s ease;\n /* Ensure submenu is visible */\n opacity: 1;\n visibility: visible;\n pointer-events: auto;\n }\n\n .dropdown__custom-content {\n padding: var(--nuraly-dropdown-item-padding, 8px 12px);\n max-width: 100%;\n box-sizing: border-box;\n }\n\n /* Custom content styling */\n .dropdown__custom-content h3,\n .dropdown__custom-content h4 {\n margin: 0 0 8px 0;\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--nuraly-color-text-primary);\n }\n\n .dropdown__custom-content p {\n margin: 0 0 8px 0;\n font-size: 0.75rem;\n color: var(--nuraly-color-text-secondary);\n line-height: 1.4;\n }\n\n .dropdown__custom-content button,\n .dropdown__custom-content input,\n .dropdown__custom-content select {\n width: 100%;\n margin-bottom: 8px;\n }\n\n .dropdown__custom-content button:last-child,\n .dropdown__custom-content input:last-child,\n .dropdown__custom-content p:last-child {\n margin-bottom: 0;\n }\n\n .dropdown__submenu--right {\n left: 100%;\n margin-left: 4px;\n }\n\n .dropdown__submenu--left {\n right: 100%;\n margin-right: 4px;\n }\n\n @keyframes fadeInSubmenu {\n from {\n opacity: 0;\n transform: translateX(-8px);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n }\n\n .dropdown__submenu--left {\n animation-name: fadeInSubmenuLeft;\n }\n\n @keyframes fadeInSubmenuLeft {\n from {\n opacity: 0;\n transform: translateX(8px);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n }\n\n /* Focus styles for accessibility */\n :host(:focus-within) .dropdown__trigger {\n outline: var(--nuraly-dropdown-focus-outline);\n outline-offset: var(--nuraly-dropdown-focus-offset);\n }\n\n /* Disabled state */\n :host([disabled]) {\n opacity: var(--nuraly-dropdown-disabled-opacity, 0.5);\n pointer-events: none;\n }\n\n /* Allow overflow for nested dropdowns/selects */\n :host([allow-overflow]) .dropdown__panel {\n overflow: visible !important;\n max-height: none !important;\n }\n\n :host([allow-overflow]) .dropdown__content {\n overflow: visible !important;\n }\n\n /* Hidden state */\n [hidden] {\n display: none !important;\n }\n\n`;"]}
@@ -1 +1 @@
1
- {"version":3,"file":"dropdown.types.js","sourceRoot":"","sources":["../../../src/components/dropdown/dropdown.types.ts"],"names":[],"mappings":"","sourcesContent":["import { TemplateResult } from 'lit';\n\n/**\n * Dropdown placement options\n */\nexport const enum DropdownPlacement {\n Bottom = 'bottom',\n Top = 'top',\n BottomStart = 'bottom-start',\n BottomEnd = 'bottom-end',\n TopStart = 'top-start',\n TopEnd = 'top-end',\n Auto = 'auto'\n}\n\n/**\n * Dropdown trigger events\n */\nexport const enum DropdownTrigger {\n Click = 'click',\n Hover = 'hover',\n Focus = 'focus',\n Manual = 'manual'\n}\n\n/**\n * Dropdown size variants\n */\nexport const enum DropdownSize {\n Small = 'small',\n Medium = 'medium',\n Large = 'large'\n}\n\n/**\n * Dropdown animation types\n */\nexport const enum DropdownAnimation {\n None = 'none',\n Fade = 'fade',\n Slide = 'slide',\n Scale = 'scale'\n}\n\n/**\n * Dropdown item configuration\n */\nexport interface DropdownItem {\n id: string;\n label: string;\n value?: any;\n icon?: string;\n disabled?: boolean;\n divider?: boolean;\n options?: DropdownItem[]; // Cascading submenu items (use either this OR customContent)\n customContent?: string | TemplateResult; // Custom HTML string or Lit template for interactive submenu\n additionalData?: any;\n}\n\n/**\n * Dropdown position information\n */\nexport interface DropdownPosition {\n top: number;\n left: number;\n width: number;\n height?: number;\n placement: DropdownPlacement;\n}\n\n/**\n * Dropdown configuration\n */\nexport interface DropdownConfig {\n placement?: DropdownPlacement;\n trigger?: DropdownTrigger;\n size?: DropdownSize;\n animation?: DropdownAnimation;\n disabled?: boolean;\n arrow?: boolean;\n autoClose?: boolean;\n closeOnEscape?: boolean;\n closeOnOutsideClick?: boolean;\n offset?: number;\n delay?: number;\n maxHeight?: string;\n minWidth?: string;\n items?: DropdownItem[];\n}\n\n// Legacy interfaces for backward compatibility - will be deprecated\nexport interface IOption extends DropdownItem {\n label: string;\n value?: string;\n disabled?: boolean;\n icon?: string;\n children?: IOption[];\n additionalData?: any;\n}\n\nexport const enum TriggerMode {\n Click = 'click',\n Hover = 'hover',\n}\n\nexport const enum DropDownDirection {\n Right = 'right',\n Left = 'left',\n}\n"]}
1
+ {"version":3,"file":"dropdown.types.js","sourceRoot":"","sources":["../../../../src/components/dropdown/dropdown.types.ts"],"names":[],"mappings":"","sourcesContent":["import { TemplateResult } from 'lit';\n\n/**\n * Dropdown placement options\n */\nexport const enum DropdownPlacement {\n Bottom = 'bottom',\n Top = 'top',\n BottomStart = 'bottom-start',\n BottomEnd = 'bottom-end',\n TopStart = 'top-start',\n TopEnd = 'top-end',\n Auto = 'auto'\n}\n\n/**\n * Dropdown trigger events\n */\nexport const enum DropdownTrigger {\n Click = 'click',\n Hover = 'hover',\n Focus = 'focus',\n Manual = 'manual'\n}\n\n/**\n * Dropdown size variants\n */\nexport const enum DropdownSize {\n Small = 'small',\n Medium = 'medium',\n Large = 'large'\n}\n\n/**\n * Dropdown animation types\n */\nexport const enum DropdownAnimation {\n None = 'none',\n Fade = 'fade',\n Slide = 'slide',\n Scale = 'scale'\n}\n\n/**\n * Dropdown item configuration\n */\nexport interface DropdownItem {\n id: string;\n label: string;\n value?: any;\n icon?: string;\n disabled?: boolean;\n divider?: boolean;\n options?: DropdownItem[]; // Cascading submenu items (use either this OR customContent)\n customContent?: string | TemplateResult; // Custom HTML string or Lit template for interactive submenu\n additionalData?: any;\n}\n\n/**\n * Dropdown position information\n */\nexport interface DropdownPosition {\n top: number;\n left: number;\n width: number;\n height?: number;\n placement: DropdownPlacement;\n}\n\n/**\n * Dropdown configuration\n */\nexport interface DropdownConfig {\n placement?: DropdownPlacement;\n trigger?: DropdownTrigger;\n size?: DropdownSize;\n animation?: DropdownAnimation;\n disabled?: boolean;\n arrow?: boolean;\n autoClose?: boolean;\n closeOnEscape?: boolean;\n closeOnOutsideClick?: boolean;\n offset?: number;\n delay?: number;\n maxHeight?: string;\n minWidth?: string;\n items?: DropdownItem[];\n}\n\n// Legacy interfaces for backward compatibility - will be deprecated\nexport interface IOption extends DropdownItem {\n label: string;\n value?: string;\n disabled?: boolean;\n icon?: string;\n children?: IOption[];\n additionalData?: any;\n}\n\nexport const enum TriggerMode {\n Click = 'click',\n Hover = 'hover',\n}\n\nexport const enum DropDownDirection {\n Right = 'right',\n Left = 'left',\n}\n"]}
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/dropdown/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC","sourcesContent":["export * from './dropdown.component.js';\nexport * from './dropdown.types.js';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/dropdown/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC","sourcesContent":["export * from './dropdown.component.js';\nexport * from './dropdown.types.js';\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuralyui/dropdown",
3
- "version": "0.0.20",
3
+ "version": "0.0.21",
4
4
  "description": "Dropdown component for NuralyUI",
5
5
  "main": "index.js",
6
6
  "type": "module",
package/react.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"react.js","sourceRoot":"","sources":["../../../src/components/dropdown/react.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE5D,MAAM,CAAC,MAAM,UAAU,GAAG,eAAe,CAAC;IACxC,OAAO,EAAE,aAAa;IACtB,YAAY,EAAE,iBAAiB;IAC/B,KAAK,EAAE,KAAK;IACZ,MAAM,EAAE;QACN,kBAAkB,EAAE,gBAAgB;QACpC,mBAAmB,EAAE,iBAAiB;QACtC,wBAAwB,EAAE,qBAAqB;KAChD;CACF,CAAC,CAAC","sourcesContent":["import { createComponent } from '@lit-labs/react';\nimport * as React from 'react';\nimport { NrDropdownElement } from './dropdown.component.js';\n\nexport const NrDropdown = createComponent({\n tagName: 'nr-dropdown',\n elementClass: NrDropdownElement,\n react: React,\n events: {\n 'nr-dropdown-open': 'onDropdownOpen',\n 'nr-dropdown-close': 'onDropdownClose',\n 'nr-dropdown-item-click': 'onDropdownItemClick'\n },\n});\n"]}
1
+ {"version":3,"file":"react.js","sourceRoot":"","sources":["../../../../src/components/dropdown/react.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE5D,MAAM,CAAC,MAAM,UAAU,GAAG,eAAe,CAAC;IACxC,OAAO,EAAE,aAAa;IACtB,YAAY,EAAE,iBAAiB;IAC/B,KAAK,EAAE,KAAK;IACZ,MAAM,EAAE;QACN,kBAAkB,EAAE,gBAAgB;QACpC,mBAAmB,EAAE,iBAAiB;QACtC,wBAAwB,EAAE,qBAAqB;KAChD;CACF,CAAC,CAAC","sourcesContent":["import { createComponent } from '@lit-labs/react';\nimport * as React from 'react';\nimport { NrDropdownElement } from './dropdown.component.js';\n\nexport const NrDropdown = createComponent({\n tagName: 'nr-dropdown',\n elementClass: NrDropdownElement,\n react: React,\n events: {\n 'nr-dropdown-open': 'onDropdownOpen',\n 'nr-dropdown-close': 'onDropdownClose',\n 'nr-dropdown-item-click': 'onDropdownItemClick'\n },\n});\n"]}