{"version":3,"file":"vue-float-menu.cjs","sources":["../src/utils/index.ts","../src/components/icons/MenuIcon.vue","../src/components/icons/MenuIcon.vue?vue&type=template&id=1b54617d&lang.js","../src/components/icons/XIcon.vue","../src/components/icons/XIcon.vue?vue&type=template&id=b39c2c48&lang.js","../src/components/icons/ChevRightIcon.vue","../src/components/icons/ChevRightIcon.vue?vue&type=template&id=42d56c4a&lang.js","../src/components/icons/PlusIcon.vue","../src/components/icons/PlusIcon.vue?vue&type=template&id=6bb92290&lang.js","../src/components/icons/MinusIcon.vue","../src/components/icons/MinusIcon.vue?vue&type=template&id=82ad6f58&lang.js","../src/types/index.ts","../src/components/composables/useTouchOptimizations.ts","../src/components/composables/useBundleOptimizations.ts","../src/components/Menu.vue","../src/components/composables/useMenuState.ts","../src/components/Menu.vue?vue&type=template&id=9bcc0be2&lang.js","../node_modules/.pnpm/style-inject@0.3.0/node_modules/style-inject/dist/style-inject.es.js","../src/components/props.ts","../src/components/index.vue","../src/components/index.vue?vue&type=template&id=47323bf2&lang.js","../src/index.ts","../src/components/composables/useAnimations.ts","../src/components/composables/usePerformanceOptimizations.ts","../src/components/composables/useErrorHandling.ts"],"sourcesContent":["import { Position, UtilsType } from '../types/index';\n\nconst utils: UtilsType = {\n  setupMenuOrientation: (head, content, headDimension, menuDimension) => {\n    const { top, bottom } = head.getBoundingClientRect();\n    const left = Math.round((content.clientWidth - headDimension) / 2);\n    const menuHeight = content.clientHeight;\n    let newOrientation = 'bottom';\n    const MENU_SPACING = 15;\n    let newMenuStyle = null;\n\n    // flip to bottom if there is not enough space on top\n    if (menuHeight > top) {\n      newMenuStyle = {\n        top: `${headDimension + MENU_SPACING}px`,\n        left: `-${left}px`,\n      };\n      newOrientation = 'top';\n    } else if (window.innerHeight - bottom < menuHeight) {\n      newMenuStyle = {\n        bottom: `${headDimension + MENU_SPACING}px`,\n        left: `-${left}px`,\n      };\n      newOrientation = 'bottom';\n    } else {\n      newMenuStyle = {\n        top: `${headDimension + MENU_SPACING}px`,\n        left: `-${left}px`,\n      };\n      newOrientation = 'top';\n    }\n\n    return Object.assign({}, newMenuStyle, {\n      'min-height': `${menuDimension.height}px`,\n      width: `${menuDimension.width}px`,\n      newOrientation,\n    });\n  },\n  setupMenuPosition: (element, position, flipOnEdges, menuContainer) => {\n    const { top, bottom, left, right } = element.getBoundingClientRect();\n    const { innerWidth: screenWidth, innerHeight: screenHeight } = window;\n    const menuContWidth = menuContainer.clientWidth;\n    const menuContHalfWidth = Math.ceil(menuContWidth / 2);\n    let newPosition: Position | null = null;\n\n    let flipMenu = false;\n    let reveal = false;\n\n    if (flipOnEdges) {\n      flipMenu = false;\n    }\n\n    // reposition if the menu head goes below the bottom of the viewport\n    if (bottom > screenHeight) {\n      newPosition = {\n        left: position.left,\n        top: position.top - (bottom - screenHeight),\n      };\n      reveal = true;\n    }\n\n    // reposition if the menu head goes above the bottom of the viewport\n    if (top < 0) {\n      newPosition = {\n        left: position.left,\n        top: position.top + Math.abs(top),\n      };\n      reveal = true;\n    }\n\n    // reposition if the menu head goes beyond the left side of the viewport\n    if (left < 0 || left < menuContHalfWidth) {\n      newPosition = {\n        left: menuContHalfWidth,\n        top: position.top,\n      };\n      reveal = true;\n    }\n\n    // reposition if the menu head goes beyond the right side of the viewport\n    if (right > screenWidth || screenWidth - right < menuContWidth) {\n      newPosition = {\n        left: screenWidth - menuContWidth,\n        top: position.top,\n      };\n\n      if (flipOnEdges) {\n        flipMenu = true;\n      }\n      reveal = true;\n    }\n\n    return {\n      position: newPosition,\n      flip: flipMenu,\n      reveal,\n    };\n  },\n  setupInitStyle: (position: string, dimension: number) => {\n    const MENU_HEAD_SPACING = 15;\n\n    let left = MENU_HEAD_SPACING,\n      top = MENU_HEAD_SPACING;\n    switch (position) {\n      case 'top left':\n        left = MENU_HEAD_SPACING;\n        top = MENU_HEAD_SPACING;\n        break;\n      case 'top right':\n        left = window.innerWidth - dimension - MENU_HEAD_SPACING;\n        top = MENU_HEAD_SPACING;\n        break;\n      case 'bottom left':\n        left = MENU_HEAD_SPACING;\n        top = window.innerHeight - dimension - MENU_HEAD_SPACING;\n        break;\n      case 'bottom right':\n        left = window.innerWidth - dimension - MENU_HEAD_SPACING;\n        top = window.innerHeight - dimension - MENU_HEAD_SPACING;\n    }\n\n    return {\n      left: `${left}px`,\n      top: `${top}px`,\n      width: `${dimension}px`,\n      height: `${dimension}px`,\n    };\n  },\n  detectDeviceType: () => {\n    const screenWidth = screen.width;\n    if (screenWidth <= 768) {\n      return 'mobile';\n    }\n    return 'desktop';\n  },\n};\n\nexport default utils;\n","<template>\n  <svg\n    xmlns=\"http://www.w3.org/2000/svg\"\n    width=\"50%\"\n    height=\"50%\"\n    viewBox=\"0 0 24 24\"\n    fill=\"none\"\n    stroke=\"currentColor\"\n    stroke-width=\"2\"\n    stroke-linecap=\"round\"\n    stroke-linejoin=\"round\"\n    class=\"feather feather-menu\"\n  >\n    <line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\" />\n    <line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\" />\n    <line x1=\"3\" y1=\"18\" x2=\"21\" y2=\"18\" />\n  </svg>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent } from 'vue';\n\nexport default defineComponent({\n  name: 'MenuIcon',\n});\n</script>\n","<template>\n  <svg\n    xmlns=\"http://www.w3.org/2000/svg\"\n    width=\"50%\"\n    height=\"50%\"\n    viewBox=\"0 0 24 24\"\n    fill=\"none\"\n    stroke=\"currentColor\"\n    stroke-width=\"2\"\n    stroke-linecap=\"round\"\n    stroke-linejoin=\"round\"\n    class=\"feather feather-menu\"\n  >\n    <line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\" />\n    <line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\" />\n    <line x1=\"3\" y1=\"18\" x2=\"21\" y2=\"18\" />\n  </svg>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent } from 'vue';\n\nexport default defineComponent({\n  name: 'MenuIcon',\n});\n</script>\n","<template>\n  <svg\n    xmlns=\"http://www.w3.org/2000/svg\"\n    width=\"24\"\n    height=\"24\"\n    viewBox=\"0 0 24 24\"\n    fill=\"none\"\n    stroke=\"currentColor\"\n    stroke-width=\"2\"\n    stroke-linecap=\"round\"\n    stroke-linejoin=\"round\"\n    class=\"feather feather-x\"\n  >\n    <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n    <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n  </svg>\n</template>\n\n<script lang=\"ts\">\nexport default {\n  name: 'XIcon',\n};\n</script>\n","<template>\n  <svg\n    xmlns=\"http://www.w3.org/2000/svg\"\n    width=\"24\"\n    height=\"24\"\n    viewBox=\"0 0 24 24\"\n    fill=\"none\"\n    stroke=\"currentColor\"\n    stroke-width=\"2\"\n    stroke-linecap=\"round\"\n    stroke-linejoin=\"round\"\n    class=\"feather feather-x\"\n  >\n    <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n    <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n  </svg>\n</template>\n\n<script lang=\"ts\">\nexport default {\n  name: 'XIcon',\n};\n</script>\n","<template>\n  <svg\n    xmlns=\"http://www.w3.org/2000/svg\"\n    width=\"24\"\n    height=\"24\"\n    viewBox=\"0 0 24 24\"\n    fill=\"none\"\n    stroke=\"currentColor\"\n    stroke-width=\"2\"\n    stroke-linecap=\"round\"\n    stroke-linejoin=\"round\"\n    class=\"feather feather-chevron-right\"\n  >\n    <polyline points=\"9 18 15 12 9 6\" />\n  </svg>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent } from 'vue';\n\nexport default defineComponent({\n  name: 'ChevronRightIcon',\n});\n</script>\n","<template>\n  <svg\n    xmlns=\"http://www.w3.org/2000/svg\"\n    width=\"24\"\n    height=\"24\"\n    viewBox=\"0 0 24 24\"\n    fill=\"none\"\n    stroke=\"currentColor\"\n    stroke-width=\"2\"\n    stroke-linecap=\"round\"\n    stroke-linejoin=\"round\"\n    class=\"feather feather-chevron-right\"\n  >\n    <polyline points=\"9 18 15 12 9 6\" />\n  </svg>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent } from 'vue';\n\nexport default defineComponent({\n  name: 'ChevronRightIcon',\n});\n</script>\n","<template>\n  <svg\n    xmlns=\"http://www.w3.org/2000/svg\"\n    width=\"24\"\n    height=\"24\"\n    viewBox=\"0 0 24 24\"\n    fill=\"none\"\n    stroke=\"currentColor\"\n    strokeWidth=\"2\"\n    strokeLinecap=\"round\"\n    strokeLinejoin=\"round\"\n    class=\"feather feather-plus\"\n  >\n    <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n    <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n  </svg>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent } from 'vue';\n\nexport default defineComponent({\n  name: 'PlusIcon',\n});\n</script>\n","<template>\n  <svg\n    xmlns=\"http://www.w3.org/2000/svg\"\n    width=\"24\"\n    height=\"24\"\n    viewBox=\"0 0 24 24\"\n    fill=\"none\"\n    stroke=\"currentColor\"\n    strokeWidth=\"2\"\n    strokeLinecap=\"round\"\n    strokeLinejoin=\"round\"\n    class=\"feather feather-plus\"\n  >\n    <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n    <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n  </svg>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent } from 'vue';\n\nexport default defineComponent({\n  name: 'PlusIcon',\n});\n</script>\n","<template>\n  <svg\n    xmlns=\"http://www.w3.org/2000/svg\"\n    width=\"24\"\n    height=\"24\"\n    viewBox=\"0 0 24 24\"\n    fill=\"none\"\n    stroke=\"currentColor\"\n    strokeWidth=\"2\"\n    strokeLinecap=\"round\"\n    strokeLinejoin=\"round\"\n    class=\"feather feather-minus\"\n  >\n    <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n  </svg>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent } from 'vue';\n\nexport default defineComponent({\n  name: 'PlusIcon',\n});\n</script>\n","<template>\n  <svg\n    xmlns=\"http://www.w3.org/2000/svg\"\n    width=\"24\"\n    height=\"24\"\n    viewBox=\"0 0 24 24\"\n    fill=\"none\"\n    stroke=\"currentColor\"\n    strokeWidth=\"2\"\n    strokeLinecap=\"round\"\n    strokeLinejoin=\"round\"\n    class=\"feather feather-minus\"\n  >\n    <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n  </svg>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent } from 'vue';\n\nexport default defineComponent({\n  name: 'PlusIcon',\n});\n</script>\n","export type Menu = {\n  items: MenuItem[];\n};\n\nexport type MenuItem = {\n  /**\n   * display name of the Menu item\n   *\n   * @type {string}\n   */\n  name?: string;\n  /**\n   * data for the sub menu\n   *\n   * @type {Menu}\n   */\n  subMenu?: Menu;\n  /**\n   * unique id (this is auto generated)\n   *\n   * @type {string}\n   */\n  id?: string;\n  /**\n   * flag to show the sub menu\n   *\n   * @type {boolean}\n   */\n  showSubMenu?: boolean;\n  /**\n   * used to highlight the selection. used for styling purpose.\n   *\n   * @type {boolean}\n   */\n  selected?: boolean;\n  /**\n   * disables the menu item. all interactions are disabled\n   *\n   * @type {boolean}\n   */\n  disabled?: boolean;\n\n  divider?: boolean;\n\n  iconSlot?: string;\n\n  /**\n   * Optional click handler for the menu item\n   *\n   * @type {() => void}\n   */\n  click?: () => void;\n};\n\nexport type Position = {\n  left: number;\n  top: number;\n};\n\nexport type SetupOrientation = (\n  head: HTMLElement,\n  content: HTMLElement,\n  headDimension: number,\n  menuDimension: { height: number; width: number }\n) => {\n  'min-height': string;\n  width: string;\n  newOrientation: string;\n};\n\nexport type SetupMenuPosition = (\n  element: HTMLElement,\n  position: Position,\n  flipOnEdges: boolean,\n  menuContainer: HTMLElement\n) => {\n  position: Position | null;\n  flip: boolean;\n  reveal: boolean;\n};\n\nexport type SetupInitStyle = (\n  dockPosition: string,\n  dimension: number\n) => {\n  left: string;\n  top: string;\n  width: string;\n  height: string;\n};\n\nexport type UtilsType = {\n  setupMenuOrientation: SetupOrientation;\n  setupMenuPosition: SetupMenuPosition;\n  setupInitStyle: SetupInitStyle;\n  detectDeviceType: () => string;\n};\nexport interface Theme {\n  /**\n   * targets the bg color of the menu head and selection highlight for sub menus.\n   *\n   * @type {string}\n   */\n  primary: string;\n\n  /**\n   * targets the text color\n   *\n   * @type {string}\n   */\n  textColor: string;\n\n  /**\n   * targets the background color of the menu\n   *\n   * @type {string}\n   */\n  menuBgColor: string;\n\n  /**\n   * targets the text color of the menu item when the item has a sub menu\n   *\n   * @type {string}\n   */\n  textSelectedColor: string;\n\n  hoverBackground: string;\n}\n\nexport const ThemeDefault = {\n  primary: '#4f46e5', // Modern indigo\n  textColor: '#374151', // Professional gray\n  menuBgColor: 'rgba(255, 255, 255, 0.95)', // Semi-transparent white\n  textSelectedColor: '#1f2937', // Dark gray for selected text\n  hoverBackground: 'rgba(79, 70, 229, 0.1)', // Light indigo for hover\n};\n\n// Bundle optimization types\nexport interface BundleOptimization {\n  memory?: {\n    used: number;\n    total: number;\n    limit: number;\n  };\n  isSlowNetwork?: boolean;\n  isDevelopment?: boolean;\n  isProduction?: boolean;\n}\n\n// Component instance type for Vue\nexport interface FloatMenuInstance {\n  toggleMenu: () => void;\n  closeMenu: () => void;\n  openMenu: () => void;\n  isMenuActive: () => boolean;\n}\n\n// Props interface for the component\nexport interface FloatMenuProps {\n  dimension?: number;\n  position?: string;\n  fixed?: boolean;\n  menuDimension?: { height: number; width: number };\n  menuData?: MenuItem[];\n  useCustomContent?: boolean;\n  onSelected?: (val: string) => void;\n  flipOnEdges?: boolean;\n  theme?: Theme;\n  preserveMenuPosition?: boolean;\n  menuStyle?: string;\n}\n","import { ref, computed, onMounted, onUnmounted } from 'vue';\n\nexport interface TouchEvent {\n  type: 'tap' | 'longpress' | 'swipe' | 'pinch';\n  target: HTMLElement;\n  startPosition: { x: number; y: number };\n  endPosition?: { x: number; y: number };\n  duration: number;\n  force?: number;\n}\n\nexport interface SwipeDirection {\n  direction: 'up' | 'down' | 'left' | 'right';\n  velocity: number;\n  distance: number;\n}\n\nexport const useTouchOptimizations = () => {\n  const isTouchDevice = ref(false);\n  const isLongPress = ref(false);\n  const touchStartTime = ref(0);\n  const touchStartPosition = ref({ x: 0, y: 0 });\n  const touchEndPosition = ref({ x: 0, y: 0 });\n\n  // Touch configuration\n  const LONG_PRESS_DURATION = 500; // ms\n  const TAP_THRESHOLD = 10; // pixels\n  const SWIPE_THRESHOLD = 50; // pixels\n  const SWIPE_VELOCITY_THRESHOLD = 0.3; // pixels per ms\n\n  // Device detection\n  const detectTouchDevice = () => {\n    return (\n      'ontouchstart' in window ||\n      navigator.maxTouchPoints > 0 ||\n      /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)\n    );\n  };\n\n  // Touch event handlers\n  const handleTouchStart = (\n    event: globalThis.TouchEvent,\n    callback?: (touchEvent: TouchEvent) => void\n  ) => {\n    const touch = event.touches[0];\n    touchStartTime.value = Date.now();\n    touchStartPosition.value = { x: touch.clientX, y: touch.clientY };\n    touchEndPosition.value = { x: touch.clientX, y: touch.clientY };\n\n    // Start long press detection\n    const longPressTimer = setTimeout(() => {\n      if (isLongPress.value) return;\n\n      isLongPress.value = true;\n      const touchEvent: TouchEvent = {\n        type: 'longpress',\n        target: event.target as HTMLElement,\n        startPosition: touchStartPosition.value,\n        duration: Date.now() - touchStartTime.value,\n        force: touch.force || 1,\n      };\n\n      callback?.(touchEvent);\n    }, LONG_PRESS_DURATION);\n\n    // Store timer for cleanup\n    (\n      event.target as HTMLElement & { _longPressTimer?: ReturnType<typeof setTimeout> }\n    )._longPressTimer = longPressTimer;\n  };\n\n  const handleTouchMove = (event: globalThis.TouchEvent) => {\n    const touch = event.touches[0];\n    touchEndPosition.value = { x: touch.clientX, y: touch.clientY };\n\n    // Calculate distance moved\n    const distance = Math.sqrt(\n      Math.pow(touchEndPosition.value.x - touchStartPosition.value.x, 2) +\n        Math.pow(touchEndPosition.value.y - touchStartPosition.value.y, 2)\n    );\n\n    // Cancel long press if moved too much\n    const target = event.target as HTMLElement & { _longPressTimer?: number };\n    if (distance > TAP_THRESHOLD && target._longPressTimer) {\n      clearTimeout(target._longPressTimer);\n      isLongPress.value = false;\n    }\n  };\n\n  const handleTouchEnd = (\n    event: globalThis.TouchEvent,\n    callback?: (touchEvent: TouchEvent) => void\n  ) => {\n    const touchEndTime = Date.now();\n    const duration = touchEndTime - touchStartTime.value;\n\n    // Clean up long press timer\n    const target = event.target as HTMLElement & { _longPressTimer?: number };\n    if (target._longPressTimer) {\n      clearTimeout(target._longPressTimer);\n    }\n\n    // Skip if this was a long press\n    if (isLongPress.value) {\n      isLongPress.value = false;\n      return;\n    }\n\n    const distance = Math.sqrt(\n      Math.pow(touchEndPosition.value.x - touchStartPosition.value.x, 2) +\n        Math.pow(touchEndPosition.value.y - touchStartPosition.value.y, 2)\n    );\n\n    const velocity = distance / duration;\n\n    let touchEvent: TouchEvent;\n\n    // Determine touch event type\n    if (distance < TAP_THRESHOLD) {\n      // Tap\n      touchEvent = {\n        type: 'tap',\n        target: event.target as HTMLElement,\n        startPosition: touchStartPosition.value,\n        endPosition: touchEndPosition.value,\n        duration,\n      };\n    } else if (distance > SWIPE_THRESHOLD && velocity > SWIPE_VELOCITY_THRESHOLD) {\n      // Swipe\n      touchEvent = {\n        type: 'swipe',\n        target: event.target as HTMLElement,\n        startPosition: touchStartPosition.value,\n        endPosition: touchEndPosition.value,\n        duration,\n      };\n    } else {\n      // Regular tap with some movement\n      touchEvent = {\n        type: 'tap',\n        target: event.target as HTMLElement,\n        startPosition: touchStartPosition.value,\n        endPosition: touchEndPosition.value,\n        duration,\n      };\n    }\n\n    callback?.(touchEvent);\n  };\n\n  // Swipe direction detection\n  const getSwipeDirection = (): SwipeDirection | null => {\n    const deltaX = touchEndPosition.value.x - touchStartPosition.value.x;\n    const deltaY = touchEndPosition.value.y - touchStartPosition.value.y;\n    const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);\n\n    if (distance < SWIPE_THRESHOLD) return null;\n\n    const duration = Date.now() - touchStartTime.value;\n    const velocity = distance / duration;\n\n    if (Math.abs(deltaX) > Math.abs(deltaY)) {\n      return {\n        direction: deltaX > 0 ? 'right' : 'left',\n        velocity,\n        distance,\n      };\n    } else {\n      return {\n        direction: deltaY > 0 ? 'down' : 'up',\n        velocity,\n        distance,\n      };\n    }\n  };\n\n  // Haptic feedback (if supported)\n  const triggerHapticFeedback = (intensity: 'light' | 'medium' | 'heavy' = 'light') => {\n    if ('vibrate' in navigator) {\n      const patterns = {\n        light: [10],\n        medium: [20],\n        heavy: [30],\n      };\n      navigator.vibrate(patterns[intensity]);\n    }\n  };\n\n  // Enhanced touch target sizing\n  const ensureTouchTarget = (element: HTMLElement, minSize: number = 44) => {\n    const rect = element.getBoundingClientRect();\n    const currentSize = Math.min(rect.width, rect.height);\n\n    if (currentSize < minSize) {\n      const padding = (minSize - currentSize) / 2;\n      element.style.padding = `${padding}px`;\n      element.style.minWidth = `${minSize}px`;\n      element.style.minHeight = `${minSize}px`;\n    }\n  };\n\n  // Touch-friendly menu orientation\n  const getOptimalMenuOrientation = (\n    menuElement: HTMLElement,\n    triggerElement: HTMLElement,\n    viewport: { width: number; height: number }\n  ) => {\n    const triggerRect = triggerElement.getBoundingClientRect();\n    const menuRect = menuElement.getBoundingClientRect();\n\n    // On mobile, prefer bottom orientation for easier thumb access\n    if (isTouchDevice.value && viewport.width < 768) {\n      const spaceBelow = viewport.height - triggerRect.bottom;\n      const spaceAbove = triggerRect.top;\n\n      // If there's enough space below, use bottom orientation\n      if (spaceBelow >= menuRect.height + 20) {\n        return 'bottom';\n      }\n      // Otherwise use top if there's space\n      else if (spaceAbove >= menuRect.height + 20) {\n        return 'top';\n      }\n      // Fallback to bottom with scrolling\n      else {\n        return 'bottom-scroll';\n      }\n    }\n\n    // Desktop logic remains the same\n    return triggerRect.top > viewport.height / 2 ? 'top' : 'bottom';\n  };\n\n  // Enhanced accessibility for touch\n  const enhanceAccessibility = (element: HTMLElement) => {\n    // Add touch-action for better performance\n    element.style.touchAction = 'manipulation';\n\n    // Ensure proper focus handling\n    if (!element.hasAttribute('tabindex')) {\n      element.setAttribute('tabindex', '0');\n    }\n\n    // Add ARIA labels for screen readers\n    if (!element.hasAttribute('aria-label') && !element.hasAttribute('aria-labelledby')) {\n      element.setAttribute('aria-label', 'Interactive menu item');\n    }\n\n    // Add role if not present\n    if (!element.hasAttribute('role')) {\n      element.setAttribute('role', 'button');\n    }\n  };\n\n  // Initialize touch optimizations\n  onMounted(() => {\n    isTouchDevice.value = detectTouchDevice();\n\n    // Add CSS class for touch devices\n    if (isTouchDevice.value) {\n      document.body.classList.add('touch-device');\n    }\n\n    // Add touch-friendly CSS\n    const style = document.createElement('style');\n    style.textContent = `\n      .touch-device .menu-list-item {\n        min-height: 44px !important;\n        padding: 12px 16px !important;\n        touch-action: manipulation;\n      }\n      \n      .touch-device .menu-head {\n        min-width: 44px !important;\n        min-height: 44px !important;\n        touch-action: manipulation;\n      }\n      \n      .touch-device .chev-icon {\n        min-width: 44px !important;\n        min-height: 44px !important;\n        display: flex !important;\n        align-items: center !important;\n        justify-content: center !important;\n      }\n      \n      @media (hover: none) and (pointer: coarse) {\n        .menu-list-item:hover {\n          background-color: transparent !important;\n        }\n        \n        .menu-list-item:active {\n          background-color: var(--hover-background) !important;\n          transform: scale(0.98) !important;\n        }\n      }\n    `;\n    document.head.appendChild(style);\n  });\n\n  onUnmounted(() => {\n    // Cleanup\n    document.body.classList.remove('touch-device');\n  });\n\n  return {\n    isTouchDevice: computed(() => isTouchDevice.value),\n    isLongPress: computed(() => isLongPress.value),\n    handleTouchStart,\n    handleTouchMove,\n    handleTouchEnd,\n    getSwipeDirection,\n    triggerHapticFeedback,\n    ensureTouchTarget,\n    getOptimalMenuOrientation,\n    enhanceAccessibility,\n  };\n};\n","import { computed, ref, onMounted } from 'vue';\n\n// Extend import.meta for Vite environment\ndeclare global {\n  interface ImportMeta {\n    env: {\n      DEV?: boolean;\n      PROD?: boolean;\n      [key: string]: unknown;\n    };\n  }\n}\n\nexport interface BundleOptimization {\n  lazyLoad: boolean;\n  treeShaking: boolean;\n  codesplitting: boolean;\n  compression: boolean;\n}\n\n// Extend the Performance interface to include memory\ninterface PerformanceWithMemory extends Performance {\n  memory?: {\n    usedJSHeapSize: number;\n    totalJSHeapSize: number;\n    jsHeapSizeLimit: number;\n  };\n}\n\n// Extend Navigator interface for connection\ninterface NavigatorWithConnection extends Navigator {\n  connection?: {\n    effectiveType?: string;\n  };\n}\n\nexport const useBundleOptimizations = () => {\n  const optimizations = ref<BundleOptimization>({\n    lazyLoad: true,\n    treeShaking: true,\n    codesplitting: true,\n    compression: true,\n  });\n\n  // Dynamic imports for better code splitting\n  const loadComponent = async (componentName: string) => {\n    try {\n      switch (componentName) {\n        case 'TouchOptimizations':\n          return await import('./useTouchOptimizations');\n        case 'Animations':\n          return await import('./useAnimations');\n        case 'Performance':\n          return await import('./usePerformanceOptimizations');\n        case 'ErrorHandling':\n          return await import('./useErrorHandling');\n        default:\n          throw new Error(`Unknown component: ${componentName}`);\n      }\n    } catch (error) {\n      console.warn(`Failed to load component ${componentName}:`, error);\n      return null;\n    }\n  };\n\n  // Lazy load composables based on feature detection\n  const loadComposablesConditionally = async () => {\n    const features = {\n      touchDevice: 'ontouchstart' in window || navigator.maxTouchPoints > 0,\n      reducedMotion: window.matchMedia('(prefers-reduced-motion: reduce)').matches,\n      modernBrowser: 'IntersectionObserver' in window && 'ResizeObserver' in window,\n      highPerformance: navigator.hardwareConcurrency && navigator.hardwareConcurrency >= 4,\n    };\n\n    const loadPromises = [];\n\n    // Only load touch optimizations on touch devices\n    if (features.touchDevice) {\n      loadPromises.push(loadComponent('TouchOptimizations'));\n    }\n\n    // Only load animations if motion is preferred\n    if (!features.reducedMotion) {\n      loadPromises.push(loadComponent('Animations'));\n    }\n\n    // Load performance optimizations on high-performance devices\n    if (features.highPerformance) {\n      loadPromises.push(loadComponent('Performance'));\n    }\n\n    // Always load accessibility and error handling\n    loadPromises.push(\n      loadComponent('Accessibility'),\n      loadComponent('ErrorHandling'),\n      loadComponent('KeyboardNavigation')\n    );\n\n    try {\n      await Promise.all(loadPromises);\n    } catch (error) {\n      console.warn('Some composables failed to load:', error);\n    }\n  };\n\n  // Bundle size analysis\n  const getBundleInfo = () => {\n    return {\n      // Estimate bundle sizes (in KB)\n      core: 12, // Core menu functionality\n      touchOptimizations: 3,\n      accessibility: 2,\n      animations: 2,\n      performance: 1.5,\n      errorHandling: 1,\n      keyboardNavigation: 1.5,\n      total: 23,\n    };\n  };\n\n  // Performance monitoring\n  const measurePerformance = (operationName: string, operation: () => void) => {\n    if ('performance' in window && performance.mark) {\n      const startMark = `${operationName}-start`;\n      const endMark = `${operationName}-end`;\n      const measureName = `${operationName}-duration`;\n\n      performance.mark(startMark);\n      operation();\n      performance.mark(endMark);\n\n      try {\n        performance.measure(measureName, startMark, endMark);\n        const measure = performance.getEntriesByName(measureName)[0];\n        console.debug(`${operationName} took ${measure.duration.toFixed(2)}ms`);\n      } catch (error) {\n        console.warn('Performance measurement failed:', error);\n      }\n    } else {\n      operation();\n    }\n  };\n\n  // Tree shaking helper - mark functions as used\n  const markAsUsed = (featureName: string) => {\n    if (import.meta.env?.DEV) {\n      console.debug(`Feature marked as used: ${featureName}`);\n    }\n  };\n\n  // Memory usage monitoring\n  const monitorMemoryUsage = () => {\n    const perf = performance as PerformanceWithMemory;\n    if ('memory' in perf && perf.memory) {\n      return {\n        used: perf.memory.usedJSHeapSize,\n        total: perf.memory.totalJSHeapSize,\n        limit: perf.memory.jsHeapSizeLimit,\n      };\n    }\n    return null;\n  };\n\n  // Code splitting strategies\n  const splitStrategy = computed(() => {\n    const userAgent = navigator.userAgent.toLowerCase();\n    const isMobile = /android|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(userAgent);\n    const nav = navigator as NavigatorWithConnection;\n    const isSlowConnection =\n      ('connection' in navigator && nav.connection?.effectiveType === 'slow-2g') ||\n      nav.connection?.effectiveType === '2g';\n\n    if (isMobile || isSlowConnection) {\n      return 'aggressive'; // More aggressive code splitting for mobile/slow connections\n    } else {\n      return 'standard'; // Standard code splitting for desktop\n    }\n  });\n\n  // Compression utilities\n  const enableCompression = () => {\n    // Enable gzip/brotli compression hints\n    if ('serviceWorker' in navigator) {\n      // Service worker can handle compression\n      return true;\n    }\n    return false;\n  };\n\n  // Resource preloading\n  const preloadCriticalResources = () => {\n    const criticalResources = [\n      { href: '/vue-float-menu.css', as: 'style' },\n      { href: '/vue-float-menu.js', as: 'script' },\n    ];\n\n    criticalResources.forEach((resource) => {\n      const link = document.createElement('link');\n      link.rel = 'preload';\n      link.href = resource.href;\n      link.as = resource.as;\n      document.head.appendChild(link);\n    });\n  };\n\n  onMounted(() => {\n    // Initialize optimizations\n    if (optimizations.value.lazyLoad) {\n      loadComposablesConditionally();\n    }\n\n    if (optimizations.value.compression) {\n      enableCompression();\n    }\n\n    // Preload critical resources in production\n    if (import.meta.env && !import.meta.env.DEV) {\n      preloadCriticalResources();\n    }\n  });\n\n  return {\n    optimizations: computed(() => optimizations.value),\n    loadComponent,\n    loadComposablesConditionally,\n    getBundleInfo,\n    measurePerformance,\n    markAsUsed,\n    monitorMemoryUsage,\n    splitStrategy,\n    enableCompression,\n    preloadCriticalResources,\n  };\n};\n","<template>\n  <div\n    ref=\"menuRef\"\n    class=\"menu-wrapper\"\n    role=\"menu\"\n    aria-label=\"Context menu\"\n    aria-orientation=\"vertical\"\n    tabindex=\"0\"\n    @keyup=\"handleKeyUpWithErrorHandling\"\n  >\n    <ul class=\"menu-list\" :style=\"themeStyles\">\n      <li\n        v-for=\"(\n          { id, selected, name, subMenu, showSubMenu, disabled, divider, iconSlot }, index\n        ) of menuItems\"\n        :key=\"id\"\n        :class=\"[\n          { 'sub-menu': subMenu, selected, disabled, flip, divider },\n          'menu-list-item',\n          menuStyle,\n        ]\"\n        :style=\"themeStyles\"\n        role=\"menuitem\"\n        :aria-setsize=\"menuItems.length\"\n        :aria-posinset=\"index + 1\"\n        :aria-haspopup=\"subMenu ? 'menu' : undefined\"\n        :aria-expanded=\"subMenu ? !!showSubMenu : undefined\"\n        :aria-disabled=\"!!disabled\"\n        :tabindex=\"-1\"\n        @mousedown=\"\n          handleMenuItemClickWithErrorHandling(\n            $event,\n            id || '',\n            name || '',\n            !!subMenu,\n            index,\n            !!disabled,\n            !!divider\n          )\n        \"\n        @mouseenter=\"!prefersReducedMotion && handleMouseEnter($event)\"\n        @mouseleave=\"!prefersReducedMotion && handleMouseLeave($event)\"\n      >\n        <template v-if=\"!divider\">\n          <div :class=\"menuItemClass\" @click=\"$event.stopPropagation()\">\n            <span v-if=\"iconSlot\" class=\"menu-item-icon\">\n              <slot :name=\"iconSlot\" />\n            </span>\n            <span :class=\"['name', { disabled }]\">{{ name }}</span>\n            <span\n              v-if=\"subMenu\"\n              :class=\"['chev-icon', { disabled, 'show-submenu': showSubMenu }, menuStyle]\"\n            >\n              <chev-right-icon v-if=\"!isAccordion\" />\n              <plus-icon v-if=\"subMenu && !showSubMenu && isAccordion\" />\n              <minus-icon v-if=\"subMenu && showSubMenu && isAccordion\" />\n            </span>\n          </div>\n          <transition\n            :name=\"!prefersReducedMotion ? 'submenu' : ''\"\n            :duration=\"animationDuration\"\n            @before-leave=\"handleBeforeTransitionLeave\"\n            @after-enter=\"handleAfterTransitionEnter\"\n          >\n            <div\n              v-if=\"!disabled && showSubMenu\"\n              :class=\"[subMenuClass, { 'accordion-submenu': isAccordion }]\"\n              :style=\"themeStyles\"\n              :data-submenu-id=\"id\"\n              role=\"menu\"\n              aria-label=\"Submenu\"\n            >\n              <component\n                :is=\"SubMenuComponent\"\n                :data=\"subMenu?.items || []\"\n                :on-selection=\"onSelection\"\n                :theme=\"theme\"\n                :on-close=\"handleSubmenuClose\"\n                :flip=\"flip\"\n                :menu-style=\"menuStyle\"\n              >\n                <template v-for=\"slot in Object.keys($slots)\" #[slot]=\"scope\">\n                  <slot :name=\"slot\" v-bind=\"scope\" />\n                </template>\n              </component>\n            </div>\n          </transition>\n        </template>\n        <template v-else>\n          <span class=\"menu-item-divider\" />\n        </template>\n      </li>\n    </ul>\n  </div>\n</template>\n\n<script lang=\"ts\">\nimport {\n  defineComponent,\n  PropType,\n  ref,\n  resolveComponent,\n  computed,\n  onMounted,\n  watch,\n  nextTick,\n} from 'vue';\nimport ChevRightIcon from './icons/ChevRightIcon.vue';\nimport PlusIcon from './icons/PlusIcon.vue';\nimport MinusIcon from './icons/MinusIcon.vue';\nimport { MenuItem, Theme, ThemeDefault } from '../types';\nimport { useMenuState } from './composables/useMenuState';\nimport { useTouchOptimizations } from './composables/useTouchOptimizations';\nimport { useBundleOptimizations } from './composables/useBundleOptimizations';\n\nexport default defineComponent({\n  name: 'FloatMenu',\n  components: {\n    ChevRightIcon,\n    PlusIcon,\n    MinusIcon,\n  },\n  props: {\n    data: {\n      type: Array as PropType<MenuItem[]>,\n      default: () => [],\n    },\n    flip: {\n      type: Boolean,\n      default: false,\n    },\n    onSelection: {\n      type: Function as PropType<(name: string, parent?: string) => void>,\n      default: null,\n    },\n    onClose: {\n      type: Function as PropType<(keyCodeUsed?: string) => void>,\n      default: null,\n      required: true,\n    },\n    theme: {\n      type: Object as PropType<Theme>,\n      required: false,\n      default: ThemeDefault,\n    },\n    menuStyle: {\n      type: String,\n      default: 'slide-out',\n      required: false,\n    },\n    isTouchDevice: {\n      type: Boolean,\n      default: false,\n    },\n  },\n  setup(props) {\n    // Bundle optimizations for performance\n    const { measurePerformance, markAsUsed } = useBundleOptimizations();\n\n    // Menu state management\n    const {\n      activeIndex,\n      menuItems,\n      toggleMenu,\n      selectMenuItem,\n      setActiveIndex,\n      closeAllSubMenus,\n      updateSelectedItem,\n    } = useMenuState(props.data);\n\n    // Reference to the menu element\n    const menuRef = ref<HTMLDivElement>();\n\n    // Resolve this component for usage in nested menus\n    const SubMenuComponent = resolveComponent('FloatMenu');\n\n    // Accessibility and animation preferences\n    const prefersReducedMotion = ref(false);\n\n    // Ensure the menu is focused when mounted for keyboard navigation\n    onMounted(() => {\n      const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');\n      prefersReducedMotion.value = mediaQuery.matches;\n\n      const handler = (e: MediaQueryListEvent) => {\n        prefersReducedMotion.value = e.matches;\n      };\n\n      mediaQuery.addEventListener('change', handler);\n\n      // Set focus on the menu when it mounts, with a slight delay to ensure it's ready\n      nextTick(() => {\n        if (menuRef.value) {\n          menuRef.value.focus();\n\n          // If there are menu items, select the first one for keyboard navigation\n          if (menuItems.value.length > 0) {\n            // Find first non-divider, non-disabled item\n            const firstItemIndex = menuItems.value.findIndex(\n              (item) => !item.divider && !item.disabled\n            );\n            if (firstItemIndex !== -1) {\n              setActiveIndex(firstItemIndex);\n            }\n          }\n        }\n      });\n    });\n\n    // Animation duration based on user preferences\n    const animationDuration = computed(() => {\n      return prefersReducedMotion.value ? 0 : 300;\n    });\n\n    // Touch optimizations (conditionally import only if needed)\n    const touchOptimizations = props.isTouchDevice\n      ? (() => {\n          const { triggerHapticFeedback } = useTouchOptimizations();\n          return { triggerHapticFeedback };\n        })()\n      : null;\n\n    // Enhanced menu item click handler with touch support\n    const handleMenuItemClickWithErrorHandling = (\n      event: MouseEvent | TouchEvent,\n      id: string,\n      name: string,\n      subMenu: boolean,\n      index: number,\n      disabled: boolean,\n      divider: boolean\n    ) => {\n      measurePerformance('menuItemClick', () => {\n        markAsUsed('menuItemClick');\n\n        try {\n          event.stopPropagation();\n          event.preventDefault();\n\n          if (disabled || divider) {\n            return;\n          }\n\n          // Provide haptic feedback on touch devices\n          if (props.isTouchDevice && touchOptimizations) {\n            touchOptimizations.triggerHapticFeedback('light');\n          }\n\n          setActiveIndex(index);\n\n          // For mouse clicks, always select the item and don't toggle submenus\n          if (!subMenu) {\n            selectMenuItem(name, id, subMenu, false, props.onSelection);\n          } else {\n            // For submenu items, toggle the submenu\n            toggleMenu(id, false);\n          }\n\n          // Direct style manipulation to remove any focus borders\n          const target = event.currentTarget as HTMLElement;\n          if (target) {\n            // Forcibly remove any focus indicators\n            target.style.outline = 'none';\n            target.style.border = 'none';\n\n            // Apply a setTimeout to ensure this persists after any CSS transitions\n            setTimeout(() => {\n              if (target && target.classList.contains('selected')) {\n                target.style.outline = 'none';\n                target.style.border = 'none';\n              }\n            }, 10);\n          }\n\n          // Announce selection for screen readers\n          if (!subMenu && name) {\n            // Create announcement for screen reader\n            const announcement = document.createElement('div');\n            announcement.setAttribute('aria-live', 'polite');\n            announcement.className = 'sr-only';\n            announcement.textContent = `Selected ${name}`;\n            document.body.appendChild(announcement);\n            setTimeout(() => document.body.removeChild(announcement), 1000);\n          }\n        } catch (error) {\n          console.error('Menu item click failed:', error);\n        }\n      });\n    };\n\n    // Enhanced keyboard navigation handler\n    const handleKeyUpWithErrorHandling = (event: KeyboardEvent) => {\n      try {\n        event.preventDefault();\n        event.stopPropagation();\n\n        const actvIndex = activeIndex.value;\n        const item = menuItems.value[actvIndex > -1 ? actvIndex : 0];\n        const keyCode = event.key;\n        const len = props.data.length;\n\n        switch (keyCode) {\n          case 'ArrowDown':\n            if (actvIndex < len - 1) {\n              let nextIndex = actvIndex + 1;\n\n              // Skip disabled items and dividers\n              while (\n                nextIndex < len &&\n                (menuItems.value[nextIndex]?.divider || menuItems.value[nextIndex]?.disabled)\n              ) {\n                nextIndex++;\n              }\n\n              // If we reached the end, loop back to the start\n              if (nextIndex >= len) {\n                nextIndex = 0;\n                // Skip disabled items and dividers at the beginning\n                while (\n                  nextIndex < actvIndex &&\n                  (menuItems.value[nextIndex]?.divider || menuItems.value[nextIndex]?.disabled)\n                ) {\n                  nextIndex++;\n                }\n              }\n\n              setActiveIndex(nextIndex);\n            } else if (actvIndex === len - 1) {\n              // Find first non-disabled, non-divider item\n              let nextIndex = 0;\n              while (\n                nextIndex < len &&\n                (menuItems.value[nextIndex]?.divider || menuItems.value[nextIndex]?.disabled)\n              ) {\n                nextIndex++;\n              }\n\n              // If all items are disabled, keep current selection\n              if (nextIndex >= len) {\n                nextIndex = actvIndex;\n              }\n\n              setActiveIndex(nextIndex);\n            }\n            break;\n\n          case 'ArrowUp':\n            if (actvIndex > 0) {\n              let prevIndex = actvIndex - 1;\n\n              // Skip disabled items and dividers\n              while (\n                prevIndex >= 0 &&\n                (menuItems.value[prevIndex]?.divider || menuItems.value[prevIndex]?.disabled)\n              ) {\n                prevIndex--;\n              }\n\n              // If we reached the beginning, loop to the end\n              if (prevIndex < 0) {\n                prevIndex = len - 1;\n                // Skip disabled items and dividers at the end\n                while (\n                  prevIndex > actvIndex &&\n                  (menuItems.value[prevIndex]?.divider || menuItems.value[prevIndex]?.disabled)\n                ) {\n                  prevIndex--;\n                }\n              }\n\n              setActiveIndex(prevIndex);\n            } else {\n              // Find last non-disabled, non-divider item\n              let prevIndex = len - 1;\n              while (\n                prevIndex >= 0 &&\n                (menuItems.value[prevIndex]?.divider || menuItems.value[prevIndex]?.disabled)\n              ) {\n                prevIndex--;\n              }\n\n              // If all items are disabled, keep current selection\n              if (prevIndex < 0) {\n                prevIndex = actvIndex;\n              }\n\n              setActiveIndex(prevIndex);\n            }\n            break;\n\n          case 'ArrowLeft':\n            // Skip disabled items\n            if (item?.disabled) {\n              break;\n            }\n\n            if (!props.flip) {\n              props.onClose('ArrowLeft');\n            } else if (item.subMenu) {\n              toggleMenu(item.id, true);\n            }\n            break;\n\n          case 'ArrowRight':\n            // Skip disabled items\n            if (item?.disabled) {\n              break;\n            }\n\n            if (!props.flip && item?.subMenu) {\n              toggleMenu(item.id || '', true);\n              // Focus handling for keyboard navigation\n              handleSubmenuOpen(item.id || '');\n            } else if (props.flip) {\n              props.onClose?.('ArrowRight');\n            }\n            break;\n\n          case 'Enter':\n            // Skip disabled items for Enter key actions\n            if (item?.disabled) {\n              break;\n            }\n\n            // Only select regular menu items with Enter, submenus should only use arrow keys\n            selectMenuItem(\n              item?.name,\n              item?.id || '',\n              Boolean(item?.subMenu),\n              false,\n              props.onSelection\n            );\n\n            // Announce selection for screen readers\n            if (item?.name) {\n              const announcement = document.createElement('div');\n              announcement.setAttribute('aria-live', 'polite');\n              announcement.className = 'sr-only';\n              announcement.textContent = `Selected ${item.name}`;\n              document.body.appendChild(announcement);\n              setTimeout(() => document.body.removeChild(announcement), 1000);\n            }\n            break;\n\n          case 'Escape':\n            // Announce menu closing for screen readers\n            const announcement = document.createElement('div');\n            announcement.setAttribute('aria-live', 'polite');\n            announcement.className = 'sr-only';\n            announcement.textContent = 'Menu closed';\n            document.body.appendChild(announcement);\n            setTimeout(() => document.body.removeChild(announcement), 1000);\n\n            props.onClose?.();\n            break;\n        }\n      } catch (error) {\n        console.error('Keyboard navigation failed:', error);\n      }\n    };\n\n    // Mouse interaction handlers with smooth animations\n    const handleMouseEnter = (event: MouseEvent) => {\n      if (!prefersReducedMotion.value) {\n        const target = event.currentTarget as HTMLElement;\n        if (target) {\n          target.style.transform = 'scale(1.02)';\n          target.style.transition = 'all 150ms cubic-bezier(0.25, 0.46, 0.45, 0.94)';\n          target.style.backgroundColor = 'var(--hover-background, rgba(0, 0, 0, 0.05))';\n        }\n      }\n    };\n\n    const handleMouseLeave = (event: MouseEvent) => {\n      if (!prefersReducedMotion.value) {\n        const target = event.currentTarget as HTMLElement;\n        if (target) {\n          target.style.transform = 'scale(1)';\n          target.style.transition = 'all 150ms cubic-bezier(0.25, 0.46, 0.45, 0.94)';\n          target.style.backgroundColor = '';\n        }\n      }\n    };\n\n    // Enhanced submenu focus handling for accessibility\n    const handleSubmenuOpen = (submenuId: string) => {\n      try {\n        // Allow time for the submenu to render\n        nextTick(() => {\n          // Find the submenu container\n          const submenu = document.querySelector(`[data-submenu-id=\"${submenuId}\"]`) as HTMLElement;\n          if (submenu) {\n            // Find the first non-disabled focusable item in the submenu\n            const firstItem = submenu.querySelector(\n              '[role=\"menuitem\"]:not([aria-disabled=\"true\"]):not(.divider)'\n            ) as HTMLElement;\n            if (firstItem) {\n              firstItem.focus();\n\n              // Announce submenu opening to screen readers\n              const announcement = document.createElement('div');\n              announcement.setAttribute('aria-live', 'polite');\n              announcement.className = 'sr-only';\n              announcement.textContent = 'Submenu opened';\n              document.body.appendChild(announcement);\n              setTimeout(() => document.body.removeChild(announcement), 1000);\n            }\n          }\n        });\n      } catch (error) {\n        console.error('Submenu focus handling failed:', error);\n      }\n    };\n\n    // Handle submenu close\n    const handleSubmenuClose = () => {\n      try {\n        // Find all open submenus\n        const openSubmenus = menuItems.value.filter((item) => item.showSubMenu);\n\n        // If there are open submenus, find their DOM elements\n        if (openSubmenus.length > 0) {\n          nextTick(() => {\n            // Start the animation by triggering the transition classes first\n            // This will ensure the CSS transitions run properly\n            closeAllSubMenus();\n\n            // Then focus the menu after everything is closed\n            setTimeout(() => {\n              if (menuRef.value) {\n                menuRef.value.focus();\n              }\n            }, 300); // Wait for the animation to finish\n          });\n        } else {\n          // If no open submenus, just focus the menu\n          if (menuRef.value) {\n            menuRef.value.focus();\n          }\n        }\n      } catch (error) {\n        console.error('Submenu close failed:', error);\n      }\n    };\n\n    // Enhanced submenu transitions\n    const handleBeforeTransitionLeave = (_el: Element) => {\n      try {\n        // Announce submenu closing to screen readers if needed\n        if (!prefersReducedMotion.value) {\n          const announcement = document.createElement('div');\n          announcement.setAttribute('aria-live', 'polite');\n          announcement.className = 'sr-only';\n          announcement.textContent = 'Submenu closing';\n          document.body.appendChild(announcement);\n          setTimeout(() => document.body.removeChild(announcement), 1000);\n        }\n      } catch (error) {\n        console.error('Submenu transition handling failed:', error);\n      }\n    };\n\n    const handleAfterTransitionEnter = (el: Element) => {\n      try {\n        // Focus the first non-disabled item in the submenu\n        nextTick(() => {\n          const firstItem = el.querySelector(\n            '[role=\"menuitem\"]:not([aria-disabled=\"true\"]):not(.divider)'\n          ) as HTMLElement;\n          if (firstItem) {\n            firstItem.focus();\n          }\n        });\n      } catch (error) {\n        console.error('Submenu transition handling failed:', error);\n      }\n    };\n\n    // Theme CSS variables (memoized for performance)\n    const themeStyles = computed(() => ({\n      '--background': props.theme.primary,\n      '--menu-background': props.theme.menuBgColor,\n      '--menu-text-color': props.theme.textColor,\n      '--text-selected-color': props.theme.textSelectedColor,\n      '--hover-background': props.theme.hoverBackground,\n    }));\n\n    // Computed classes\n    const subMenuClass = computed(() => `sub-menu-wrapper ${props.menuStyle}`);\n    const menuItemClass = computed(() => `menu-item-wrapper ${props.menuStyle}`);\n    const isAccordion = computed(() => props.menuStyle === 'accordion');\n\n    // Lifecycle hooks\n    onMounted(() => {\n      try {\n        // Focus the menu on mount for accessibility\n        if (menuRef.value) {\n          menuRef.value.focus();\n        }\n\n        // Set active index if first item is pre-selected\n        nextTick(() => {\n          const isFirstItemSelected = props.data[0]?.selected;\n          if (isFirstItemSelected) {\n            setActiveIndex(0);\n          }\n        });\n      } catch (error) {\n        console.error('Menu mount failed:', error);\n      }\n    });\n\n    // Watch activeIndex changes and update selected items\n    watch(activeIndex, (val) => {\n      updateSelectedItem(val);\n    });\n\n    return {\n      menuItems,\n      handleMenuItemClickWithErrorHandling,\n      SubMenuComponent,\n      themeStyles,\n      menuRef,\n      handleKeyUpWithErrorHandling,\n      activeIndex,\n      handleSubmenuClose,\n      subMenuClass,\n      menuItemClass,\n      isAccordion,\n      handleMouseEnter,\n      handleMouseLeave,\n      prefersReducedMotion,\n      animationDuration,\n      handleSubmenuOpen,\n      handleBeforeTransitionLeave,\n      handleAfterTransitionEnter,\n    };\n  },\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@use './Menu';\n@use './styles/accessibility';\n@use './styles/focused-items';\n\n/* Direct fix for the Edit menu item and other focused items */\n.menu-list-item {\n  &.selected,\n  &.highlight {\n    /* Remove all focus indicators when the item is already visually highlighted */\n    outline: none !important;\n    border: none !important;\n    box-shadow: none !important;\n\n    &:focus,\n    &:focus-visible {\n      outline: none !important;\n      border: none !important;\n      box-shadow: none !important;\n    }\n  }\n}\n</style>\n","import { ref, computed, unref } from 'vue';\nimport type { MenuItem } from '../../types';\n\n/**\n * Composable for menu state management\n * Provides a clean API for menu interactions and state\n */\nexport function useMenuState(data: MenuItem[]) {\n  // tracks the index of the selected menu item\n  const activeIndex = ref(-1);\n\n  // generate unique ids for the menu items\n  const menuItems = ref<MenuItem[]>(\n    data.map((item) =>\n      Object.assign({}, item, {\n        id: `menu-item-${Math.random().toString(16)}`,\n        showSubMenu: false,\n      })\n    )\n  );\n\n  // expands/collapses the submenu\n  const toggleMenu = (id?: string, selectFirstItem?: boolean) => {\n    const targetItem = menuItems.value.find((item) => item.id === id);\n    const wasOpen = targetItem?.showSubMenu;\n\n    // If closing target submenu, do it instantly\n    if (wasOpen) {\n      menuItems.value = menuItems.value.map((item) => {\n        if (item.id === id) {\n          return Object.assign({}, item, { showSubMenu: false });\n        }\n        return item;\n      });\n      return;\n    }\n\n    // First close any open submenus that are not the target\n    menuItems.value = menuItems.value.map((item) => {\n      if (item.id !== id && item.showSubMenu) {\n        return Object.assign({}, item, { showSubMenu: false });\n      }\n      return item;\n    });\n\n    // After a small delay, open the target submenu if it was closed\n    if (!wasOpen) {\n      setTimeout(() => {\n        menuItems.value = menuItems.value.map((item) =>\n          Object.assign({}, item, {\n            showSubMenu: item.id === id ? !item.showSubMenu : item.showSubMenu,\n            subMenu:\n              selectFirstItem && item.id === id\n                ? {\n                    items: item.subMenu?.items.map((x, index) =>\n                      Object.assign({}, x, {\n                        selected: index === 0,\n                      })\n                    ),\n                  }\n                : item.subMenu,\n          })\n        );\n      }, 50); // Small delay to ensure a smooth transition\n    }\n  };\n\n  const selectMenuItem = (\n    name?: string,\n    id?: string,\n    subMenu?: boolean,\n    selectFirstItem?: boolean,\n    onSelection?: (name: string) => void\n  ) => {\n    if (!subMenu) {\n      if (name && onSelection) {\n        onSelection(name);\n      }\n    } else {\n      toggleMenu(id, selectFirstItem);\n    }\n  };\n\n  const setActiveIndex = (index: number) => {\n    activeIndex.value = index;\n  };\n\n  const resetActiveIndex = () => {\n    activeIndex.value = -1;\n  };\n\n  const updateMenuItems = (newData: MenuItem[]) => {\n    menuItems.value = newData.map((item) =>\n      Object.assign({}, item, {\n        id: `menu-item-${Math.random().toString(16)}`,\n        showSubMenu: false,\n      })\n    );\n  };\n\n  const closeAllSubMenus = () => {\n    // Use a small delay to ensure the animation has time to run\n    setTimeout(() => {\n      menuItems.value = menuItems.value.map((item) => {\n        return Object.assign({}, item, {\n          showSubMenu: false,\n        });\n      });\n    }, 30); // Shorter delay for closing\n  };\n\n  const updateSelectedItem = (index: number) => {\n    menuItems.value = menuItems.value.map((item, i) => {\n      return Object.assign({}, item, {\n        selected: i === index,\n      });\n    });\n  };\n\n  return {\n    activeIndex: computed(() => unref(activeIndex)),\n    menuItems: computed(() => unref(menuItems)),\n    toggleMenu,\n    selectMenuItem,\n    setActiveIndex,\n    resetActiveIndex,\n    updateMenuItems,\n    closeAllSubMenus,\n    updateSelectedItem,\n  };\n}\n","<template>\n  <div\n    ref=\"menuRef\"\n    class=\"menu-wrapper\"\n    role=\"menu\"\n    aria-label=\"Context menu\"\n    aria-orientation=\"vertical\"\n    tabindex=\"0\"\n    @keyup=\"handleKeyUpWithErrorHandling\"\n  >\n    <ul class=\"menu-list\" :style=\"themeStyles\">\n      <li\n        v-for=\"(\n          { id, selected, name, subMenu, showSubMenu, disabled, divider, iconSlot }, index\n        ) of menuItems\"\n        :key=\"id\"\n        :class=\"[\n          { 'sub-menu': subMenu, selected, disabled, flip, divider },\n          'menu-list-item',\n          menuStyle,\n        ]\"\n        :style=\"themeStyles\"\n        role=\"menuitem\"\n        :aria-setsize=\"menuItems.length\"\n        :aria-posinset=\"index + 1\"\n        :aria-haspopup=\"subMenu ? 'menu' : undefined\"\n        :aria-expanded=\"subMenu ? !!showSubMenu : undefined\"\n        :aria-disabled=\"!!disabled\"\n        :tabindex=\"-1\"\n        @mousedown=\"\n          handleMenuItemClickWithErrorHandling(\n            $event,\n            id || '',\n            name || '',\n            !!subMenu,\n            index,\n            !!disabled,\n            !!divider\n          )\n        \"\n        @mouseenter=\"!prefersReducedMotion && handleMouseEnter($event)\"\n        @mouseleave=\"!prefersReducedMotion && handleMouseLeave($event)\"\n      >\n        <template v-if=\"!divider\">\n          <div :class=\"menuItemClass\" @click=\"$event.stopPropagation()\">\n            <span v-if=\"iconSlot\" class=\"menu-item-icon\">\n              <slot :name=\"iconSlot\" />\n            </span>\n            <span :class=\"['name', { disabled }]\">{{ name }}</span>\n            <span\n              v-if=\"subMenu\"\n              :class=\"['chev-icon', { disabled, 'show-submenu': showSubMenu }, menuStyle]\"\n            >\n              <chev-right-icon v-if=\"!isAccordion\" />\n              <plus-icon v-if=\"subMenu && !showSubMenu && isAccordion\" />\n              <minus-icon v-if=\"subMenu && showSubMenu && isAccordion\" />\n            </span>\n          </div>\n          <transition\n            :name=\"!prefersReducedMotion ? 'submenu' : ''\"\n            :duration=\"animationDuration\"\n            @before-leave=\"handleBeforeTransitionLeave\"\n            @after-enter=\"handleAfterTransitionEnter\"\n          >\n            <div\n              v-if=\"!disabled && showSubMenu\"\n              :class=\"[subMenuClass, { 'accordion-submenu': isAccordion }]\"\n              :style=\"themeStyles\"\n              :data-submenu-id=\"id\"\n              role=\"menu\"\n              aria-label=\"Submenu\"\n            >\n              <component\n                :is=\"SubMenuComponent\"\n                :data=\"subMenu?.items || []\"\n                :on-selection=\"onSelection\"\n                :theme=\"theme\"\n                :on-close=\"handleSubmenuClose\"\n                :flip=\"flip\"\n                :menu-style=\"menuStyle\"\n              >\n                <template v-for=\"slot in Object.keys($slots)\" #[slot]=\"scope\">\n                  <slot :name=\"slot\" v-bind=\"scope\" />\n                </template>\n              </component>\n            </div>\n          </transition>\n        </template>\n        <template v-else>\n          <span class=\"menu-item-divider\" />\n        </template>\n      </li>\n    </ul>\n  </div>\n</template>\n\n<script lang=\"ts\">\nimport {\n  defineComponent,\n  PropType,\n  ref,\n  resolveComponent,\n  computed,\n  onMounted,\n  watch,\n  nextTick,\n} from 'vue';\nimport ChevRightIcon from './icons/ChevRightIcon.vue';\nimport PlusIcon from './icons/PlusIcon.vue';\nimport MinusIcon from './icons/MinusIcon.vue';\nimport { MenuItem, Theme, ThemeDefault } from '../types';\nimport { useMenuState } from './composables/useMenuState';\nimport { useTouchOptimizations } from './composables/useTouchOptimizations';\nimport { useBundleOptimizations } from './composables/useBundleOptimizations';\n\nexport default defineComponent({\n  name: 'FloatMenu',\n  components: {\n    ChevRightIcon,\n    PlusIcon,\n    MinusIcon,\n  },\n  props: {\n    data: {\n      type: Array as PropType<MenuItem[]>,\n      default: () => [],\n    },\n    flip: {\n      type: Boolean,\n      default: false,\n    },\n    onSelection: {\n      type: Function as PropType<(name: string, parent?: string) => void>,\n      default: null,\n    },\n    onClose: {\n      type: Function as PropType<(keyCodeUsed?: string) => void>,\n      default: null,\n      required: true,\n    },\n    theme: {\n      type: Object as PropType<Theme>,\n      required: false,\n      default: ThemeDefault,\n    },\n    menuStyle: {\n      type: String,\n      default: 'slide-out',\n      required: false,\n    },\n    isTouchDevice: {\n      type: Boolean,\n      default: false,\n    },\n  },\n  setup(props) {\n    // Bundle optimizations for performance\n    const { measurePerformance, markAsUsed } = useBundleOptimizations();\n\n    // Menu state management\n    const {\n      activeIndex,\n      menuItems,\n      toggleMenu,\n      selectMenuItem,\n      setActiveIndex,\n      closeAllSubMenus,\n      updateSelectedItem,\n    } = useMenuState(props.data);\n\n    // Reference to the menu element\n    const menuRef = ref<HTMLDivElement>();\n\n    // Resolve this component for usage in nested menus\n    const SubMenuComponent = resolveComponent('FloatMenu');\n\n    // Accessibility and animation preferences\n    const prefersReducedMotion = ref(false);\n\n    // Ensure the menu is focused when mounted for keyboard navigation\n    onMounted(() => {\n      const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');\n      prefersReducedMotion.value = mediaQuery.matches;\n\n      const handler = (e: MediaQueryListEvent) => {\n        prefersReducedMotion.value = e.matches;\n      };\n\n      mediaQuery.addEventListener('change', handler);\n\n      // Set focus on the menu when it mounts, with a slight delay to ensure it's ready\n      nextTick(() => {\n        if (menuRef.value) {\n          menuRef.value.focus();\n\n          // If there are menu items, select the first one for keyboard navigation\n          if (menuItems.value.length > 0) {\n            // Find first non-divider, non-disabled item\n            const firstItemIndex = menuItems.value.findIndex(\n              (item) => !item.divider && !item.disabled\n            );\n            if (firstItemIndex !== -1) {\n              setActiveIndex(firstItemIndex);\n            }\n          }\n        }\n      });\n    });\n\n    // Animation duration based on user preferences\n    const animationDuration = computed(() => {\n      return prefersReducedMotion.value ? 0 : 300;\n    });\n\n    // Touch optimizations (conditionally import only if needed)\n    const touchOptimizations = props.isTouchDevice\n      ? (() => {\n          const { triggerHapticFeedback } = useTouchOptimizations();\n          return { triggerHapticFeedback };\n        })()\n      : null;\n\n    // Enhanced menu item click handler with touch support\n    const handleMenuItemClickWithErrorHandling = (\n      event: MouseEvent | TouchEvent,\n      id: string,\n      name: string,\n      subMenu: boolean,\n      index: number,\n      disabled: boolean,\n      divider: boolean\n    ) => {\n      measurePerformance('menuItemClick', () => {\n        markAsUsed('menuItemClick');\n\n        try {\n          event.stopPropagation();\n          event.preventDefault();\n\n          if (disabled || divider) {\n            return;\n          }\n\n          // Provide haptic feedback on touch devices\n          if (props.isTouchDevice && touchOptimizations) {\n            touchOptimizations.triggerHapticFeedback('light');\n          }\n\n          setActiveIndex(index);\n\n          // For mouse clicks, always select the item and don't toggle submenus\n          if (!subMenu) {\n            selectMenuItem(name, id, subMenu, false, props.onSelection);\n          } else {\n            // For submenu items, toggle the submenu\n            toggleMenu(id, false);\n          }\n\n          // Direct style manipulation to remove any focus borders\n          const target = event.currentTarget as HTMLElement;\n          if (target) {\n            // Forcibly remove any focus indicators\n            target.style.outline = 'none';\n            target.style.border = 'none';\n\n            // Apply a setTimeout to ensure this persists after any CSS transitions\n            setTimeout(() => {\n              if (target && target.classList.contains('selected')) {\n                target.style.outline = 'none';\n                target.style.border = 'none';\n              }\n            }, 10);\n          }\n\n          // Announce selection for screen readers\n          if (!subMenu && name) {\n            // Create announcement for screen reader\n            const announcement = document.createElement('div');\n            announcement.setAttribute('aria-live', 'polite');\n            announcement.className = 'sr-only';\n            announcement.textContent = `Selected ${name}`;\n            document.body.appendChild(announcement);\n            setTimeout(() => document.body.removeChild(announcement), 1000);\n          }\n        } catch (error) {\n          console.error('Menu item click failed:', error);\n        }\n      });\n    };\n\n    // Enhanced keyboard navigation handler\n    const handleKeyUpWithErrorHandling = (event: KeyboardEvent) => {\n      try {\n        event.preventDefault();\n        event.stopPropagation();\n\n        const actvIndex = activeIndex.value;\n        const item = menuItems.value[actvIndex > -1 ? actvIndex : 0];\n        const keyCode = event.key;\n        const len = props.data.length;\n\n        switch (keyCode) {\n          case 'ArrowDown':\n            if (actvIndex < len - 1) {\n              let nextIndex = actvIndex + 1;\n\n              // Skip disabled items and dividers\n              while (\n                nextIndex < len &&\n                (menuItems.value[nextIndex]?.divider || menuItems.value[nextIndex]?.disabled)\n              ) {\n                nextIndex++;\n              }\n\n              // If we reached the end, loop back to the start\n              if (nextIndex >= len) {\n                nextIndex = 0;\n                // Skip disabled items and dividers at the beginning\n                while (\n                  nextIndex < actvIndex &&\n                  (menuItems.value[nextIndex]?.divider || menuItems.value[nextIndex]?.disabled)\n                ) {\n                  nextIndex++;\n                }\n              }\n\n              setActiveIndex(nextIndex);\n            } else if (actvIndex === len - 1) {\n              // Find first non-disabled, non-divider item\n              let nextIndex = 0;\n              while (\n                nextIndex < len &&\n                (menuItems.value[nextIndex]?.divider || menuItems.value[nextIndex]?.disabled)\n              ) {\n                nextIndex++;\n              }\n\n              // If all items are disabled, keep current selection\n              if (nextIndex >= len) {\n                nextIndex = actvIndex;\n              }\n\n              setActiveIndex(nextIndex);\n            }\n            break;\n\n          case 'ArrowUp':\n            if (actvIndex > 0) {\n              let prevIndex = actvIndex - 1;\n\n              // Skip disabled items and dividers\n              while (\n                prevIndex >= 0 &&\n                (menuItems.value[prevIndex]?.divider || menuItems.value[prevIndex]?.disabled)\n              ) {\n                prevIndex--;\n              }\n\n              // If we reached the beginning, loop to the end\n              if (prevIndex < 0) {\n                prevIndex = len - 1;\n                // Skip disabled items and dividers at the end\n                while (\n                  prevIndex > actvIndex &&\n                  (menuItems.value[prevIndex]?.divider || menuItems.value[prevIndex]?.disabled)\n                ) {\n                  prevIndex--;\n                }\n              }\n\n              setActiveIndex(prevIndex);\n            } else {\n              // Find last non-disabled, non-divider item\n              let prevIndex = len - 1;\n              while (\n                prevIndex >= 0 &&\n                (menuItems.value[prevIndex]?.divider || menuItems.value[prevIndex]?.disabled)\n              ) {\n                prevIndex--;\n              }\n\n              // If all items are disabled, keep current selection\n              if (prevIndex < 0) {\n                prevIndex = actvIndex;\n              }\n\n              setActiveIndex(prevIndex);\n            }\n            break;\n\n          case 'ArrowLeft':\n            // Skip disabled items\n            if (item?.disabled) {\n              break;\n            }\n\n            if (!props.flip) {\n              props.onClose('ArrowLeft');\n            } else if (item.subMenu) {\n              toggleMenu(item.id, true);\n            }\n            break;\n\n          case 'ArrowRight':\n            // Skip disabled items\n            if (item?.disabled) {\n              break;\n            }\n\n            if (!props.flip && item?.subMenu) {\n              toggleMenu(item.id || '', true);\n              // Focus handling for keyboard navigation\n              handleSubmenuOpen(item.id || '');\n            } else if (props.flip) {\n              props.onClose?.('ArrowRight');\n            }\n            break;\n\n          case 'Enter':\n            // Skip disabled items for Enter key actions\n            if (item?.disabled) {\n              break;\n            }\n\n            // Only select regular menu items with Enter, submenus should only use arrow keys\n            selectMenuItem(\n              item?.name,\n              item?.id || '',\n              Boolean(item?.subMenu),\n              false,\n              props.onSelection\n            );\n\n            // Announce selection for screen readers\n            if (item?.name) {\n              const announcement = document.createElement('div');\n              announcement.setAttribute('aria-live', 'polite');\n              announcement.className = 'sr-only';\n              announcement.textContent = `Selected ${item.name}`;\n              document.body.appendChild(announcement);\n              setTimeout(() => document.body.removeChild(announcement), 1000);\n            }\n            break;\n\n          case 'Escape':\n            // Announce menu closing for screen readers\n            const announcement = document.createElement('div');\n            announcement.setAttribute('aria-live', 'polite');\n            announcement.className = 'sr-only';\n            announcement.textContent = 'Menu closed';\n            document.body.appendChild(announcement);\n            setTimeout(() => document.body.removeChild(announcement), 1000);\n\n            props.onClose?.();\n            break;\n        }\n      } catch (error) {\n        console.error('Keyboard navigation failed:', error);\n      }\n    };\n\n    // Mouse interaction handlers with smooth animations\n    const handleMouseEnter = (event: MouseEvent) => {\n      if (!prefersReducedMotion.value) {\n        const target = event.currentTarget as HTMLElement;\n        if (target) {\n          target.style.transform = 'scale(1.02)';\n          target.style.transition = 'all 150ms cubic-bezier(0.25, 0.46, 0.45, 0.94)';\n          target.style.backgroundColor = 'var(--hover-background, rgba(0, 0, 0, 0.05))';\n        }\n      }\n    };\n\n    const handleMouseLeave = (event: MouseEvent) => {\n      if (!prefersReducedMotion.value) {\n        const target = event.currentTarget as HTMLElement;\n        if (target) {\n          target.style.transform = 'scale(1)';\n          target.style.transition = 'all 150ms cubic-bezier(0.25, 0.46, 0.45, 0.94)';\n          target.style.backgroundColor = '';\n        }\n      }\n    };\n\n    // Enhanced submenu focus handling for accessibility\n    const handleSubmenuOpen = (submenuId: string) => {\n      try {\n        // Allow time for the submenu to render\n        nextTick(() => {\n          // Find the submenu container\n          const submenu = document.querySelector(`[data-submenu-id=\"${submenuId}\"]`) as HTMLElement;\n          if (submenu) {\n            // Find the first non-disabled focusable item in the submenu\n            const firstItem = submenu.querySelector(\n              '[role=\"menuitem\"]:not([aria-disabled=\"true\"]):not(.divider)'\n            ) as HTMLElement;\n            if (firstItem) {\n              firstItem.focus();\n\n              // Announce submenu opening to screen readers\n              const announcement = document.createElement('div');\n              announcement.setAttribute('aria-live', 'polite');\n              announcement.className = 'sr-only';\n              announcement.textContent = 'Submenu opened';\n              document.body.appendChild(announcement);\n              setTimeout(() => document.body.removeChild(announcement), 1000);\n            }\n          }\n        });\n      } catch (error) {\n        console.error('Submenu focus handling failed:', error);\n      }\n    };\n\n    // Handle submenu close\n    const handleSubmenuClose = () => {\n      try {\n        // Find all open submenus\n        const openSubmenus = menuItems.value.filter((item) => item.showSubMenu);\n\n        // If there are open submenus, find their DOM elements\n        if (openSubmenus.length > 0) {\n          nextTick(() => {\n            // Start the animation by triggering the transition classes first\n            // This will ensure the CSS transitions run properly\n            closeAllSubMenus();\n\n            // Then focus the menu after everything is closed\n            setTimeout(() => {\n              if (menuRef.value) {\n                menuRef.value.focus();\n              }\n            }, 300); // Wait for the animation to finish\n          });\n        } else {\n          // If no open submenus, just focus the menu\n          if (menuRef.value) {\n            menuRef.value.focus();\n          }\n        }\n      } catch (error) {\n        console.error('Submenu close failed:', error);\n      }\n    };\n\n    // Enhanced submenu transitions\n    const handleBeforeTransitionLeave = (_el: Element) => {\n      try {\n        // Announce submenu closing to screen readers if needed\n        if (!prefersReducedMotion.value) {\n          const announcement = document.createElement('div');\n          announcement.setAttribute('aria-live', 'polite');\n          announcement.className = 'sr-only';\n          announcement.textContent = 'Submenu closing';\n          document.body.appendChild(announcement);\n          setTimeout(() => document.body.removeChild(announcement), 1000);\n        }\n      } catch (error) {\n        console.error('Submenu transition handling failed:', error);\n      }\n    };\n\n    const handleAfterTransitionEnter = (el: Element) => {\n      try {\n        // Focus the first non-disabled item in the submenu\n        nextTick(() => {\n          const firstItem = el.querySelector(\n            '[role=\"menuitem\"]:not([aria-disabled=\"true\"]):not(.divider)'\n          ) as HTMLElement;\n          if (firstItem) {\n            firstItem.focus();\n          }\n        });\n      } catch (error) {\n        console.error('Submenu transition handling failed:', error);\n      }\n    };\n\n    // Theme CSS variables (memoized for performance)\n    const themeStyles = computed(() => ({\n      '--background': props.theme.primary,\n      '--menu-background': props.theme.menuBgColor,\n      '--menu-text-color': props.theme.textColor,\n      '--text-selected-color': props.theme.textSelectedColor,\n      '--hover-background': props.theme.hoverBackground,\n    }));\n\n    // Computed classes\n    const subMenuClass = computed(() => `sub-menu-wrapper ${props.menuStyle}`);\n    const menuItemClass = computed(() => `menu-item-wrapper ${props.menuStyle}`);\n    const isAccordion = computed(() => props.menuStyle === 'accordion');\n\n    // Lifecycle hooks\n    onMounted(() => {\n      try {\n        // Focus the menu on mount for accessibility\n        if (menuRef.value) {\n          menuRef.value.focus();\n        }\n\n        // Set active index if first item is pre-selected\n        nextTick(() => {\n          const isFirstItemSelected = props.data[0]?.selected;\n          if (isFirstItemSelected) {\n            setActiveIndex(0);\n          }\n        });\n      } catch (error) {\n        console.error('Menu mount failed:', error);\n      }\n    });\n\n    // Watch activeIndex changes and update selected items\n    watch(activeIndex, (val) => {\n      updateSelectedItem(val);\n    });\n\n    return {\n      menuItems,\n      handleMenuItemClickWithErrorHandling,\n      SubMenuComponent,\n      themeStyles,\n      menuRef,\n      handleKeyUpWithErrorHandling,\n      activeIndex,\n      handleSubmenuClose,\n      subMenuClass,\n      menuItemClass,\n      isAccordion,\n      handleMouseEnter,\n      handleMouseLeave,\n      prefersReducedMotion,\n      animationDuration,\n      handleSubmenuOpen,\n      handleBeforeTransitionLeave,\n      handleAfterTransitionEnter,\n    };\n  },\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@use './Menu';\n@use './styles/accessibility';\n@use './styles/focused-items';\n\n/* Direct fix for the Edit menu item and other focused items */\n.menu-list-item {\n  &.selected,\n  &.highlight {\n    /* Remove all focus indicators when the item is already visually highlighted */\n    outline: none !important;\n    border: none !important;\n    box-shadow: none !important;\n\n    &:focus,\n    &:focus-visible {\n      outline: none !important;\n      border: none !important;\n      box-shadow: none !important;\n    }\n  }\n}\n</style>\n","function styleInject(css, ref) {\n  if ( ref === void 0 ) ref = {};\n  var insertAt = ref.insertAt;\n\n  if (!css || typeof document === 'undefined') { return; }\n\n  var head = document.head || document.getElementsByTagName('head')[0];\n  var style = document.createElement('style');\n  style.type = 'text/css';\n\n  if (insertAt === 'top') {\n    if (head.firstChild) {\n      head.insertBefore(style, head.firstChild);\n    } else {\n      head.appendChild(style);\n    }\n  } else {\n    head.appendChild(style);\n  }\n\n  if (style.styleSheet) {\n    style.styleSheet.cssText = css;\n  } else {\n    style.appendChild(document.createTextNode(css));\n  }\n}\n\nexport default styleInject;\n","import { PropType } from 'vue';\n\nimport { MenuItem, Theme, ThemeDefault } from '../types';\n\nconst MenuProps = {\n  /**\n   * dimension of the menu head. sets both the width and height\n   *\n   * @type {number}\n   */\n  dimension: {\n    type: Number,\n    default: 45,\n  },\n\n  /**\n   * sets the initial position of the menu.\n   *\n   * @type {string}\n   */\n  position: {\n    type: String,\n    default: 'bottom right',\n  },\n\n  /**\n   * disables dragging and sets the position to fixed.\n   *\n   * @type {boolean}\n   */\n  fixed: {\n    type: Boolean,\n    default: false,\n  },\n\n  /**\n   * sets the height and width of the menu.\n   *\n   * @type {Object}\n   */\n  menuDimension: {\n    type: Object as PropType<{ height: number; width: number }>,\n    default: {\n      height: 250,\n      width: 250,\n    },\n  },\n\n  /**\n   * data to generate the menu. array of type MenuItem\n   *\n   * @type {array}\n   */\n  menuData: {\n    type: Array as PropType<MenuItem[]>,\n    default: [],\n  },\n  useCustomContent: {\n    type: Boolean,\n    default: false,\n  },\n\n  /**\n   * hook that gets called on selection of the menu item.\n   *\n   * @type {function}\n   */\n  onSelected: {\n    type: Function as PropType<(val: string) => void>,\n    default: null,\n  },\n\n  /**\n   * flips the content of the menu on the right edges of the screen\n   *\n   * @type {boolean}\n   */\n  flipOnEdges: {\n    type: Boolean,\n    default: false,\n  },\n\n  /**\n   * theme object.\n   *\n   * @type {boolean}\n   */\n  theme: {\n    type: Object as PropType<Theme>,\n    required: false,\n    default: ThemeDefault,\n  },\n\n  preserveMenuPosition: {\n    type: Boolean,\n    default: true,\n  },\n\n  menuStyle: {\n    type: String,\n    default: 'slide-out',\n    required: false,\n  },\n};\n\nexport default MenuProps;\n","<template>\n  <div\n    ref=\"menuHeadContainer\"\n    :class=\"[{ dragActive, 'touch-device': isTouchDevice }, 'menu-head-wrapper']\"\n    :style=\"style\"\n    @mousedown=\"handleDragStart\"\n    @mouseup=\"handleDragEnd\"\n    @mousemove=\"handleDragMove\"\n    @touchstart=\"handleEnhancedTouchStart\"\n    @touchend=\"handleEnhancedTouchEnd\"\n    @touchmove=\"handleEnhancedTouchMove\"\n  >\n    <div\n      ref=\"menuHead\"\n      tabindex=\"0\"\n      :class=\"[{ 'menu-active': menuActive, 'drag-active': dragActive }, 'menu-head']\"\n      :style=\"getTheme\"\n      draggable=\"false\"\n      aria-haspopup=\"menu\"\n      :aria-expanded=\"menuActive\"\n      aria-label=\"Menu\"\n      @click=\"toggleMenu\"\n      @keydown=\"handleKeyboardMenuActivation\"\n    >\n      <span class=\"menu-head-icon\">\n        <slot name=\"icon\" />\n        <slot />\n        <MenuIcon v-if=\"slotsEmpty\" />\n      </span>\n    </div>\n    <div\n      ref=\"menuContainer\"\n      :class=\"[{ 'menu-active': menuActive }, 'menu-container']\"\n      :style=\"menuCSS\"\n      draggable=\"false\"\n    >\n      <span class=\"close-btn\" @mousedown=\"handleCloseClick\" @touchstart=\"handleCloseClick\">\n        <XIcon />\n      </span>\n      <MenuComponent\n        v-if=\"menuActive\"\n        :data=\"menuData\"\n        :flip=\"flipMenu\"\n        :on-selection=\"handleMenuItemSelection\"\n        :theme=\"theme\"\n        :on-close=\"handleMenuClose\"\n        :menu-style=\"computedMenuStyle\"\n        :is-touch-device=\"isTouchDevice\"\n      >\n        <template v-for=\"slot in Object.keys($slots)\" #[slot]=\"scope\">\n          <slot :name=\"slot\" v-bind=\"scope\" />\n        </template>\n      </MenuComponent>\n    </div>\n  </div>\n</template>\n\n<script lang=\"ts\">\nimport { computed, defineComponent, nextTick, onMounted, onUnmounted, ref, unref } from 'vue';\nimport utils from '../utils';\nimport MenuIcon from './icons/MenuIcon.vue';\nimport XIcon from './icons/XIcon.vue';\nimport MenuComponent from './Menu.vue';\nimport Props from './props';\nimport { useTouchOptimizations } from './composables/useTouchOptimizations';\nimport { useBundleOptimizations } from './composables/useBundleOptimizations';\nimport type { Position } from '../types';\n\nexport default defineComponent({\n  name: 'FloatMenu',\n  components: {\n    MenuIcon,\n    MenuComponent,\n    XIcon,\n  },\n  props: Props,\n  setup(props, { slots }) {\n    // Bundle optimizations for performance\n    const { measurePerformance, markAsUsed } = useBundleOptimizations();\n\n    // Touch optimizations\n    const {\n      isTouchDevice,\n      handleTouchStart,\n      handleTouchMove,\n      handleTouchEnd,\n      getSwipeDirection,\n      triggerHapticFeedback,\n      ensureTouchTarget,\n    } = useTouchOptimizations();\n\n    // position of the circular menu head\n    const position = ref<Position | null>(null);\n\n    // tracks  the  last position of the menu head.\n    // this will be used when the menu head need to moved from the edges of the screen to a more optimal position\n    const previousPosition = ref<Position | null>(null);\n\n    // // reference to the circular menu head\n    const menuHead = ref();\n\n    const menuHeadContainer = ref();\n\n    // enables/disables menu\n    const menuActive = ref(false);\n\n    // reference to the menu container\n    const menuContainer = ref();\n\n    // generates style for the menu\n    const menuCSS = ref<{ 'min-height': string; width: string } | undefined>(undefined);\n\n    // local reference of the menu direction\n    const menuOrientation = ref('top');\n\n    // flip menu content\n    const flipMenu = ref(false);\n\n    // drag active\n    const dragActive = ref(false);\n    const dragStart = ref(false);\n\n    const isTouch = ref(window.ontouchstart !== undefined);\n\n    const moveEvent = computed(() => (unref(isTouch) ? 'touchmove' : 'mousemove'));\n\n    const computedMenuStyle = computed(() =>\n      unref(moveEvent) === 'touchmove' ? 'accordion' : props.menuStyle\n    );\n\n    const isRevealing = ref(false);\n\n    // compute the style\n    const style = computed(() => {\n      const pos = unref(position);\n\n      if (pos) {\n        return {\n          left: `${pos.left}px`,\n          top: `${pos.top}px`,\n          width: `${props.dimension}px`,\n          height: `${props.dimension}px`,\n        };\n      } else {\n        return {};\n      }\n    });\n\n    // Check if slots are empty\n    const slotsEmpty = computed(() => !Object.keys(slots).length);\n\n    // manages the orientation of the menu (top or bottom)\n    // when enough space is not available on either top or bottom, the menu is automatically flipped\n    const setupMenuOrientation = () => {\n      const menuContDOM = menuContainer.value;\n      const menuHeadDOM = menuHeadContainer.value;\n      const { dimension } = props;\n\n      if (!menuContDOM || !menuHeadDOM) {\n        return;\n      }\n\n      const newStyle = utils.setupMenuOrientation(\n        menuHeadDOM,\n        menuContDOM,\n        dimension,\n        props.menuDimension\n      );\n      menuOrientation.value = newStyle.newOrientation;\n      menuCSS.value = newStyle;\n    };\n\n    // manages the position of the menu head. make sure the menu stays within the screen bounds\n    const adjustFloatMenuPosition = (element: HTMLElement) => {\n      const positionRef = unref(position);\n\n      if (!positionRef) {\n        return;\n      }\n\n      if (menuContainer.value) {\n        const newPosition = utils.setupMenuPosition(\n          element,\n          positionRef,\n          props.flipOnEdges,\n          menuContainer.value\n        );\n        flipMenu.value = newPosition.flip;\n        isRevealing.value = newPosition.reveal;\n\n        if (newPosition.position) {\n          position.value = newPosition.position;\n        }\n      }\n    };\n\n    const onCloseMenu = (event: MouseEvent | TouchEvent) => {\n      if (menuActive.value) {\n        if (isRevealing.value) {\n          position.value = previousPosition.value;\n        }\n        const classes = Array.from((event.target as HTMLElement).classList);\n        if (classes.some((cls) => cls === 'sub-menu' || cls === 'disabled')) {\n          return;\n        }\n        menuActive.value = false;\n      }\n    };\n\n    // handler for window resize event\n    const onWindowResize = () => {\n      const intialStyle = utils.setupInitStyle(props.position, props.dimension);\n\n      position.value = {\n        left: Number(intialStyle.left.replace(/px/gi, '')),\n        top: Number(intialStyle.top.replace(/px/gi, '')),\n      };\n    };\n\n    const handleMove = (event: MouseEvent | TouchEvent) => {\n      let clientX = 0;\n      let clientY = 0;\n\n      if (event instanceof MouseEvent) {\n        clientX = event.clientX;\n        clientY = event.clientY;\n      } else if (event instanceof TouchEvent) {\n        clientX = event.touches[0].clientX;\n        clientY = event.touches[0].clientY;\n      }\n\n      if (dragActive.value) {\n        const top = clientY - Math.round(props.dimension / 2);\n\n        position.value = {\n          left: clientX - Math.round(props.dimension / 2),\n          top:\n            top > 0 && top < window.innerHeight - props.dimension\n              ? top\n              : top < 0\n              ? 0\n              : top - props.dimension,\n        };\n      }\n    };\n\n    onMounted(() => {\n      // setup the initial style on load\n      const intialStyle = utils.setupInitStyle(props.position, props.dimension);\n      const initPosition = {\n        left: Number(intialStyle.left.replace(/px/gi, '')),\n        top: Number(intialStyle.top.replace(/px/gi, '')),\n      };\n      position.value = initPosition;\n      previousPosition.value = initPosition;\n\n      // close the menu when clicked outside\n      window.addEventListener('click', onCloseMenu);\n\n      // attach handler for window resize event\n      window.addEventListener('resize', onWindowResize);\n\n      window.addEventListener(\n        'mouseup',\n        (event: MouseEvent) => {\n          const nodeName = (event.target as HTMLElement).nodeName;\n          const canStopDrag = nodeName === '#document' || nodeName === 'HTML';\n\n          if (canStopDrag) {\n            dragStart.value = false;\n            dragActive.value = false;\n            previousPosition.value = position.value;\n          }\n        },\n        { capture: true }\n      );\n\n      if (!props.fixed && menuHeadContainer.value) {\n        document.addEventListener(moveEvent.value, handleMove);\n      }\n    });\n\n    // cleanup\n    onUnmounted(() => {\n      window.removeEventListener('click', onCloseMenu);\n      window.removeEventListener('resize', onWindowResize);\n      document.removeEventListener(moveEvent.value, handleMove);\n    });\n\n    // open/close the menu\n    const toggleMenu = (event: MouseEvent | KeyboardEvent | TouchEvent) => {\n      measurePerformance('toggleMenu', () => {\n        markAsUsed('menuToggle');\n\n        if (dragActive.value) {\n          return;\n        }\n\n        event.stopPropagation();\n        event.preventDefault();\n\n        const classes = Array.from((event.target as HTMLElement).classList);\n\n        if (classes.some((cls) => cls === 'menu-list-item')) {\n          return;\n        }\n\n        if (!menuActive.value) {\n          // Clean up any existing state first\n          dragStart.value = false;\n          dragActive.value = false;\n\n          setupMenuOrientation();\n          adjustFloatMenuPosition(menuHead.value as HTMLElement);\n\n          const menuContainerEl = menuContainer.value;\n          if (menuContainerEl && menuContainerEl.getAnimations) {\n            // Cancel any lingering animations\n            menuContainerEl.getAnimations().forEach((anim: Animation) => anim.cancel());\n          }\n\n          // Set menu active\n          menuActive.value = true;\n\n          // Focus the menu container after it's been activated\n          nextTick(() => {\n            if (menuContainer.value) {\n              const menuElement = menuContainer.value.querySelector('.menu-wrapper');\n              if (menuElement) {\n                menuElement.focus();\n\n                // Announce menu opening to screen readers\n                const announcement = document.createElement('div');\n                announcement.setAttribute('aria-live', 'polite');\n                announcement.className = 'sr-only';\n                announcement.textContent = 'Menu opened';\n                document.body.appendChild(announcement);\n                setTimeout(() => document.body.removeChild(announcement), 1000);\n              }\n            }\n          });\n        } else {\n          menuActive.value = false;\n          if (isRevealing.value) {\n            position.value = previousPosition.value;\n          }\n        }\n\n        // No longer needed as we're setting menuActive directly above\n        // nextTick(() => {\n        //   menuActive.value = !menuActive.value;\n        // });\n      });\n    };\n\n    // close the menu from child component (./menu.vue)\n    const handleMenuClose = (keyCode?: string) => {\n      if (keyCode === 'ArrowLeft' || keyCode === 'ArrowRight') {\n        return;\n      }\n\n      // Get the menu container element\n      const menuContainerEl = menuContainer.value;\n\n      if (menuContainerEl) {\n        // Apply closing animation with Web Animation API\n        const animation = menuContainerEl.animate(\n          [\n            { opacity: 1, transform: 'scale(1)' },\n            { opacity: 0, transform: 'scale(0.95)' },\n          ],\n          {\n            duration: 250,\n            easing: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',\n            fill: 'forwards',\n          }\n        ); // Clean up any existing animations\n        if (menuContainerEl.getAnimations) {\n          const existingAnimations = menuContainerEl.getAnimations();\n          existingAnimations.forEach((anim: Animation) => {\n            if (anim !== animation) anim.cancel();\n          });\n        }\n\n        animation.onfinish = () => {\n          menuActive.value = false;\n          if (isRevealing.value) {\n            position.value = previousPosition.value;\n          }\n          // Reset menu state after animation\n          dragStart.value = false;\n          dragActive.value = false;\n\n          nextTick(() => {\n            if (menuHead.value) {\n              menuHead.value.focus();\n            }\n          });\n        };\n      } else {\n        // Fallback if container element isn't available\n        menuActive.value = false;\n        dragStart.value = false;\n        dragActive.value = false;\n        if (isRevealing.value) {\n          position.value = previousPosition.value;\n        }\n\n        nextTick(() => {\n          menuHead.value?.focus();\n        });\n      }\n    };\n\n    // handle close button click\n    const handleCloseClick = (event: MouseEvent | TouchEvent) => {\n      event.stopPropagation();\n      event.preventDefault();\n\n      // Provide haptic feedback for touch devices\n      if (isTouchDevice.value) {\n        triggerHapticFeedback('light');\n      }\n\n      handleMenuClose();\n    };\n\n    // handler for selection\n    const handleMenuItemSelection = (name: string) => {\n      measurePerformance('menuItemSelection', () => {\n        markAsUsed('menuItemSelection');\n\n        // Get the menu container element\n        const menuContainerEl = menuContainer.value;\n\n        if (menuContainerEl) {\n          // Apply closing animation with Web Animation API\n          const animation = menuContainerEl.animate(\n            [\n              { opacity: 1, transform: 'scale(1)' },\n              { opacity: 0, transform: 'scale(0.95)' },\n            ],\n            {\n              duration: 250,\n              easing: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',\n              fill: 'forwards',\n            }\n          );\n\n          animation.onfinish = () => {\n            menuActive.value = false;\n\n            if (props.onSelected) {\n              props.onSelected(name);\n            }\n          };\n        } else {\n          // Fallback if container element isn't available\n          menuActive.value = false;\n\n          if (props.onSelected) {\n            props.onSelected(name);\n          }\n        }\n      });\n    };\n\n    const getTheme = computed(() => ({\n      '--background': props.theme.primary,\n    }));\n\n    const handleDragStart = (event: MouseEvent | TouchEvent) => {\n      if (!isTouch.value) {\n        event.preventDefault();\n      }\n      dragStart.value = true;\n    };\n\n    const handleDragMove = () => {\n      if (dragStart.value) {\n        menuActive.value = false;\n        dragActive.value = true;\n      }\n    };\n\n    const handleDragEnd = (event: MouseEvent | TouchEvent) => {\n      let clientX: number, clientY: number;\n\n      if ('touches' in event && event.touches.length > 0) {\n        clientX = event.touches[0].clientX;\n        clientY = event.touches[0].clientY;\n      } else if ('changedTouches' in event && event.changedTouches.length > 0) {\n        clientX = event.changedTouches[0].clientX;\n        clientY = event.changedTouches[0].clientY;\n      } else {\n        clientX = (event as MouseEvent).clientX;\n        clientY = (event as MouseEvent).clientY;\n      }\n\n      if (dragActive.value) {\n        previousPosition.value = {\n          left: clientX - Math.round(props.dimension / 2),\n          top: clientY - Math.round(props.dimension / 2),\n        };\n        setTimeout(() => {\n          dragActive.value = false;\n        }, 100);\n      }\n      dragStart.value = false;\n    };\n\n    // Handle keyboard activation of menu (Space and Enter keys)\n    const handleKeyboardMenuActivation = (event: KeyboardEvent) => {\n      if (event.key === 'Enter' || event.key === ' ' || event.key === 'Space') {\n        event.preventDefault();\n        toggleMenu(event);\n      }\n    };\n\n    // Enhanced touch handlers\n    const handleEnhancedTouchStart = (event: TouchEvent) => {\n      handleTouchStart(event, (touchEvent) => {\n        if (touchEvent.type === 'longpress') {\n          // Long press activates the menu (same as click/tap)\n          triggerHapticFeedback('medium');\n          toggleMenu(event);\n        }\n      });\n\n      // Also handle normal drag functionality\n      handleDragStart(event);\n    };\n\n    const handleEnhancedTouchMove = (event: TouchEvent) => {\n      handleTouchMove(event);\n      handleDragMove();\n    };\n\n    const handleEnhancedTouchEnd = (event: TouchEvent) => {\n      handleTouchEnd(event, (touchEvent) => {\n        if (touchEvent.type === 'tap') {\n          // Tap activates the menu (same as click)\n          triggerHapticFeedback('light');\n          toggleMenu(event);\n        } else if (touchEvent.type === 'swipe') {\n          // Handle swipe gestures\n          const swipe = getSwipeDirection();\n          if (swipe && menuActive.value) {\n            // Use our enhanced swipe to close handler\n            handleSwipeToClose(swipe.direction);\n          }\n        }\n      });\n\n      // Also handle normal drag functionality\n      handleDragEnd(event);\n    };\n\n    // Enhanced swipe handling for menu closing\n    const handleSwipeToClose = (swipeDirection: string) => {\n      if (\n        menuActive.value &&\n        (swipeDirection === 'up' || swipeDirection === 'down' || swipeDirection === 'left')\n      ) {\n        const menuContainerEl = menuContainer.value;\n\n        if (menuContainerEl) {\n          // Determine animation based on swipe direction\n          const transformEnd =\n            swipeDirection === 'up'\n              ? 'translateY(-20px)'\n              : swipeDirection === 'down'\n              ? 'translateY(20px)'\n              : 'translateX(-20px)';\n\n          // Apply closing animation with Web Animation API\n          const animation = menuContainerEl.animate(\n            [\n              { opacity: 1, transform: 'scale(1)' },\n              { opacity: 0, transform: `scale(0.95) ${transformEnd}` },\n            ],\n            {\n              duration: 250,\n              easing: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',\n              fill: 'forwards',\n            }\n          );\n\n          animation.onfinish = () => {\n            menuActive.value = false;\n            if (isRevealing.value) {\n              position.value = previousPosition.value;\n            }\n\n            nextTick(() => {\n              menuHead.value?.focus();\n            });\n          };\n\n          // Provide haptic feedback\n          if (isTouchDevice.value) {\n            triggerHapticFeedback('light');\n          }\n\n          return true;\n        }\n      }\n\n      return false;\n    };\n\n    // Enhanced accessibility for touch devices\n    nextTick(() => {\n      if (menuHeadContainer.value) {\n        ensureTouchTarget(menuHeadContainer.value);\n      }\n    });\n\n    return {\n      // Expose refs\n      menuHead,\n      menuHeadContainer,\n      menuContainer,\n      position,\n      menuActive,\n      dragActive,\n      isTouchDevice,\n      slotsEmpty,\n      menuOrientation,\n      menuCSS,\n      flipMenu,\n      // Expose computed\n      style,\n      computedMenuStyle,\n      getTheme,\n      // Expose methods\n      toggleMenu,\n      handleMenuClose,\n      handleCloseClick,\n      handleMenuItemSelection,\n      handleDragStart,\n      handleDragMove,\n      handleDragEnd,\n      handleEnhancedTouchStart,\n      handleEnhancedTouchMove,\n      handleEnhancedTouchEnd,\n      handleKeyboardMenuActivation,\n      handleSwipeToClose,\n    };\n  },\n});\n</script>\n\n<style lang=\"scss\">\n@use './index';\n@use './styles/accessibility';\n\n/* Fix for double focus indicators */\n.menu-list-item {\n  &.selected,\n  &.highlight {\n    outline: none !important;\n    border: none !important;\n\n    &:focus,\n    &:focus-visible {\n      outline: none !important;\n      border: none !important;\n    }\n  }\n\n  /* Only apply focus style on non-selected/non-highlighted items */\n  &:not(.selected, .highlight):focus-visible {\n    outline: 2px solid #007bff;\n  }\n}\n</style>\n","<template>\n  <div\n    ref=\"menuHeadContainer\"\n    :class=\"[{ dragActive, 'touch-device': isTouchDevice }, 'menu-head-wrapper']\"\n    :style=\"style\"\n    @mousedown=\"handleDragStart\"\n    @mouseup=\"handleDragEnd\"\n    @mousemove=\"handleDragMove\"\n    @touchstart=\"handleEnhancedTouchStart\"\n    @touchend=\"handleEnhancedTouchEnd\"\n    @touchmove=\"handleEnhancedTouchMove\"\n  >\n    <div\n      ref=\"menuHead\"\n      tabindex=\"0\"\n      :class=\"[{ 'menu-active': menuActive, 'drag-active': dragActive }, 'menu-head']\"\n      :style=\"getTheme\"\n      draggable=\"false\"\n      aria-haspopup=\"menu\"\n      :aria-expanded=\"menuActive\"\n      aria-label=\"Menu\"\n      @click=\"toggleMenu\"\n      @keydown=\"handleKeyboardMenuActivation\"\n    >\n      <span class=\"menu-head-icon\">\n        <slot name=\"icon\" />\n        <slot />\n        <MenuIcon v-if=\"slotsEmpty\" />\n      </span>\n    </div>\n    <div\n      ref=\"menuContainer\"\n      :class=\"[{ 'menu-active': menuActive }, 'menu-container']\"\n      :style=\"menuCSS\"\n      draggable=\"false\"\n    >\n      <span class=\"close-btn\" @mousedown=\"handleCloseClick\" @touchstart=\"handleCloseClick\">\n        <XIcon />\n      </span>\n      <MenuComponent\n        v-if=\"menuActive\"\n        :data=\"menuData\"\n        :flip=\"flipMenu\"\n        :on-selection=\"handleMenuItemSelection\"\n        :theme=\"theme\"\n        :on-close=\"handleMenuClose\"\n        :menu-style=\"computedMenuStyle\"\n        :is-touch-device=\"isTouchDevice\"\n      >\n        <template v-for=\"slot in Object.keys($slots)\" #[slot]=\"scope\">\n          <slot :name=\"slot\" v-bind=\"scope\" />\n        </template>\n      </MenuComponent>\n    </div>\n  </div>\n</template>\n\n<script lang=\"ts\">\nimport { computed, defineComponent, nextTick, onMounted, onUnmounted, ref, unref } from 'vue';\nimport utils from '../utils';\nimport MenuIcon from './icons/MenuIcon.vue';\nimport XIcon from './icons/XIcon.vue';\nimport MenuComponent from './Menu.vue';\nimport Props from './props';\nimport { useTouchOptimizations } from './composables/useTouchOptimizations';\nimport { useBundleOptimizations } from './composables/useBundleOptimizations';\nimport type { Position } from '../types';\n\nexport default defineComponent({\n  name: 'FloatMenu',\n  components: {\n    MenuIcon,\n    MenuComponent,\n    XIcon,\n  },\n  props: Props,\n  setup(props, { slots }) {\n    // Bundle optimizations for performance\n    const { measurePerformance, markAsUsed } = useBundleOptimizations();\n\n    // Touch optimizations\n    const {\n      isTouchDevice,\n      handleTouchStart,\n      handleTouchMove,\n      handleTouchEnd,\n      getSwipeDirection,\n      triggerHapticFeedback,\n      ensureTouchTarget,\n    } = useTouchOptimizations();\n\n    // position of the circular menu head\n    const position = ref<Position | null>(null);\n\n    // tracks  the  last position of the menu head.\n    // this will be used when the menu head need to moved from the edges of the screen to a more optimal position\n    const previousPosition = ref<Position | null>(null);\n\n    // // reference to the circular menu head\n    const menuHead = ref();\n\n    const menuHeadContainer = ref();\n\n    // enables/disables menu\n    const menuActive = ref(false);\n\n    // reference to the menu container\n    const menuContainer = ref();\n\n    // generates style for the menu\n    const menuCSS = ref<{ 'min-height': string; width: string } | undefined>(undefined);\n\n    // local reference of the menu direction\n    const menuOrientation = ref('top');\n\n    // flip menu content\n    const flipMenu = ref(false);\n\n    // drag active\n    const dragActive = ref(false);\n    const dragStart = ref(false);\n\n    const isTouch = ref(window.ontouchstart !== undefined);\n\n    const moveEvent = computed(() => (unref(isTouch) ? 'touchmove' : 'mousemove'));\n\n    const computedMenuStyle = computed(() =>\n      unref(moveEvent) === 'touchmove' ? 'accordion' : props.menuStyle\n    );\n\n    const isRevealing = ref(false);\n\n    // compute the style\n    const style = computed(() => {\n      const pos = unref(position);\n\n      if (pos) {\n        return {\n          left: `${pos.left}px`,\n          top: `${pos.top}px`,\n          width: `${props.dimension}px`,\n          height: `${props.dimension}px`,\n        };\n      } else {\n        return {};\n      }\n    });\n\n    // Check if slots are empty\n    const slotsEmpty = computed(() => !Object.keys(slots).length);\n\n    // manages the orientation of the menu (top or bottom)\n    // when enough space is not available on either top or bottom, the menu is automatically flipped\n    const setupMenuOrientation = () => {\n      const menuContDOM = menuContainer.value;\n      const menuHeadDOM = menuHeadContainer.value;\n      const { dimension } = props;\n\n      if (!menuContDOM || !menuHeadDOM) {\n        return;\n      }\n\n      const newStyle = utils.setupMenuOrientation(\n        menuHeadDOM,\n        menuContDOM,\n        dimension,\n        props.menuDimension\n      );\n      menuOrientation.value = newStyle.newOrientation;\n      menuCSS.value = newStyle;\n    };\n\n    // manages the position of the menu head. make sure the menu stays within the screen bounds\n    const adjustFloatMenuPosition = (element: HTMLElement) => {\n      const positionRef = unref(position);\n\n      if (!positionRef) {\n        return;\n      }\n\n      if (menuContainer.value) {\n        const newPosition = utils.setupMenuPosition(\n          element,\n          positionRef,\n          props.flipOnEdges,\n          menuContainer.value\n        );\n        flipMenu.value = newPosition.flip;\n        isRevealing.value = newPosition.reveal;\n\n        if (newPosition.position) {\n          position.value = newPosition.position;\n        }\n      }\n    };\n\n    const onCloseMenu = (event: MouseEvent | TouchEvent) => {\n      if (menuActive.value) {\n        if (isRevealing.value) {\n          position.value = previousPosition.value;\n        }\n        const classes = Array.from((event.target as HTMLElement).classList);\n        if (classes.some((cls) => cls === 'sub-menu' || cls === 'disabled')) {\n          return;\n        }\n        menuActive.value = false;\n      }\n    };\n\n    // handler for window resize event\n    const onWindowResize = () => {\n      const intialStyle = utils.setupInitStyle(props.position, props.dimension);\n\n      position.value = {\n        left: Number(intialStyle.left.replace(/px/gi, '')),\n        top: Number(intialStyle.top.replace(/px/gi, '')),\n      };\n    };\n\n    const handleMove = (event: MouseEvent | TouchEvent) => {\n      let clientX = 0;\n      let clientY = 0;\n\n      if (event instanceof MouseEvent) {\n        clientX = event.clientX;\n        clientY = event.clientY;\n      } else if (event instanceof TouchEvent) {\n        clientX = event.touches[0].clientX;\n        clientY = event.touches[0].clientY;\n      }\n\n      if (dragActive.value) {\n        const top = clientY - Math.round(props.dimension / 2);\n\n        position.value = {\n          left: clientX - Math.round(props.dimension / 2),\n          top:\n            top > 0 && top < window.innerHeight - props.dimension\n              ? top\n              : top < 0\n              ? 0\n              : top - props.dimension,\n        };\n      }\n    };\n\n    onMounted(() => {\n      // setup the initial style on load\n      const intialStyle = utils.setupInitStyle(props.position, props.dimension);\n      const initPosition = {\n        left: Number(intialStyle.left.replace(/px/gi, '')),\n        top: Number(intialStyle.top.replace(/px/gi, '')),\n      };\n      position.value = initPosition;\n      previousPosition.value = initPosition;\n\n      // close the menu when clicked outside\n      window.addEventListener('click', onCloseMenu);\n\n      // attach handler for window resize event\n      window.addEventListener('resize', onWindowResize);\n\n      window.addEventListener(\n        'mouseup',\n        (event: MouseEvent) => {\n          const nodeName = (event.target as HTMLElement).nodeName;\n          const canStopDrag = nodeName === '#document' || nodeName === 'HTML';\n\n          if (canStopDrag) {\n            dragStart.value = false;\n            dragActive.value = false;\n            previousPosition.value = position.value;\n          }\n        },\n        { capture: true }\n      );\n\n      if (!props.fixed && menuHeadContainer.value) {\n        document.addEventListener(moveEvent.value, handleMove);\n      }\n    });\n\n    // cleanup\n    onUnmounted(() => {\n      window.removeEventListener('click', onCloseMenu);\n      window.removeEventListener('resize', onWindowResize);\n      document.removeEventListener(moveEvent.value, handleMove);\n    });\n\n    // open/close the menu\n    const toggleMenu = (event: MouseEvent | KeyboardEvent | TouchEvent) => {\n      measurePerformance('toggleMenu', () => {\n        markAsUsed('menuToggle');\n\n        if (dragActive.value) {\n          return;\n        }\n\n        event.stopPropagation();\n        event.preventDefault();\n\n        const classes = Array.from((event.target as HTMLElement).classList);\n\n        if (classes.some((cls) => cls === 'menu-list-item')) {\n          return;\n        }\n\n        if (!menuActive.value) {\n          // Clean up any existing state first\n          dragStart.value = false;\n          dragActive.value = false;\n\n          setupMenuOrientation();\n          adjustFloatMenuPosition(menuHead.value as HTMLElement);\n\n          const menuContainerEl = menuContainer.value;\n          if (menuContainerEl && menuContainerEl.getAnimations) {\n            // Cancel any lingering animations\n            menuContainerEl.getAnimations().forEach((anim: Animation) => anim.cancel());\n          }\n\n          // Set menu active\n          menuActive.value = true;\n\n          // Focus the menu container after it's been activated\n          nextTick(() => {\n            if (menuContainer.value) {\n              const menuElement = menuContainer.value.querySelector('.menu-wrapper');\n              if (menuElement) {\n                menuElement.focus();\n\n                // Announce menu opening to screen readers\n                const announcement = document.createElement('div');\n                announcement.setAttribute('aria-live', 'polite');\n                announcement.className = 'sr-only';\n                announcement.textContent = 'Menu opened';\n                document.body.appendChild(announcement);\n                setTimeout(() => document.body.removeChild(announcement), 1000);\n              }\n            }\n          });\n        } else {\n          menuActive.value = false;\n          if (isRevealing.value) {\n            position.value = previousPosition.value;\n          }\n        }\n\n        // No longer needed as we're setting menuActive directly above\n        // nextTick(() => {\n        //   menuActive.value = !menuActive.value;\n        // });\n      });\n    };\n\n    // close the menu from child component (./menu.vue)\n    const handleMenuClose = (keyCode?: string) => {\n      if (keyCode === 'ArrowLeft' || keyCode === 'ArrowRight') {\n        return;\n      }\n\n      // Get the menu container element\n      const menuContainerEl = menuContainer.value;\n\n      if (menuContainerEl) {\n        // Apply closing animation with Web Animation API\n        const animation = menuContainerEl.animate(\n          [\n            { opacity: 1, transform: 'scale(1)' },\n            { opacity: 0, transform: 'scale(0.95)' },\n          ],\n          {\n            duration: 250,\n            easing: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',\n            fill: 'forwards',\n          }\n        ); // Clean up any existing animations\n        if (menuContainerEl.getAnimations) {\n          const existingAnimations = menuContainerEl.getAnimations();\n          existingAnimations.forEach((anim: Animation) => {\n            if (anim !== animation) anim.cancel();\n          });\n        }\n\n        animation.onfinish = () => {\n          menuActive.value = false;\n          if (isRevealing.value) {\n            position.value = previousPosition.value;\n          }\n          // Reset menu state after animation\n          dragStart.value = false;\n          dragActive.value = false;\n\n          nextTick(() => {\n            if (menuHead.value) {\n              menuHead.value.focus();\n            }\n          });\n        };\n      } else {\n        // Fallback if container element isn't available\n        menuActive.value = false;\n        dragStart.value = false;\n        dragActive.value = false;\n        if (isRevealing.value) {\n          position.value = previousPosition.value;\n        }\n\n        nextTick(() => {\n          menuHead.value?.focus();\n        });\n      }\n    };\n\n    // handle close button click\n    const handleCloseClick = (event: MouseEvent | TouchEvent) => {\n      event.stopPropagation();\n      event.preventDefault();\n\n      // Provide haptic feedback for touch devices\n      if (isTouchDevice.value) {\n        triggerHapticFeedback('light');\n      }\n\n      handleMenuClose();\n    };\n\n    // handler for selection\n    const handleMenuItemSelection = (name: string) => {\n      measurePerformance('menuItemSelection', () => {\n        markAsUsed('menuItemSelection');\n\n        // Get the menu container element\n        const menuContainerEl = menuContainer.value;\n\n        if (menuContainerEl) {\n          // Apply closing animation with Web Animation API\n          const animation = menuContainerEl.animate(\n            [\n              { opacity: 1, transform: 'scale(1)' },\n              { opacity: 0, transform: 'scale(0.95)' },\n            ],\n            {\n              duration: 250,\n              easing: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',\n              fill: 'forwards',\n            }\n          );\n\n          animation.onfinish = () => {\n            menuActive.value = false;\n\n            if (props.onSelected) {\n              props.onSelected(name);\n            }\n          };\n        } else {\n          // Fallback if container element isn't available\n          menuActive.value = false;\n\n          if (props.onSelected) {\n            props.onSelected(name);\n          }\n        }\n      });\n    };\n\n    const getTheme = computed(() => ({\n      '--background': props.theme.primary,\n    }));\n\n    const handleDragStart = (event: MouseEvent | TouchEvent) => {\n      if (!isTouch.value) {\n        event.preventDefault();\n      }\n      dragStart.value = true;\n    };\n\n    const handleDragMove = () => {\n      if (dragStart.value) {\n        menuActive.value = false;\n        dragActive.value = true;\n      }\n    };\n\n    const handleDragEnd = (event: MouseEvent | TouchEvent) => {\n      let clientX: number, clientY: number;\n\n      if ('touches' in event && event.touches.length > 0) {\n        clientX = event.touches[0].clientX;\n        clientY = event.touches[0].clientY;\n      } else if ('changedTouches' in event && event.changedTouches.length > 0) {\n        clientX = event.changedTouches[0].clientX;\n        clientY = event.changedTouches[0].clientY;\n      } else {\n        clientX = (event as MouseEvent).clientX;\n        clientY = (event as MouseEvent).clientY;\n      }\n\n      if (dragActive.value) {\n        previousPosition.value = {\n          left: clientX - Math.round(props.dimension / 2),\n          top: clientY - Math.round(props.dimension / 2),\n        };\n        setTimeout(() => {\n          dragActive.value = false;\n        }, 100);\n      }\n      dragStart.value = false;\n    };\n\n    // Handle keyboard activation of menu (Space and Enter keys)\n    const handleKeyboardMenuActivation = (event: KeyboardEvent) => {\n      if (event.key === 'Enter' || event.key === ' ' || event.key === 'Space') {\n        event.preventDefault();\n        toggleMenu(event);\n      }\n    };\n\n    // Enhanced touch handlers\n    const handleEnhancedTouchStart = (event: TouchEvent) => {\n      handleTouchStart(event, (touchEvent) => {\n        if (touchEvent.type === 'longpress') {\n          // Long press activates the menu (same as click/tap)\n          triggerHapticFeedback('medium');\n          toggleMenu(event);\n        }\n      });\n\n      // Also handle normal drag functionality\n      handleDragStart(event);\n    };\n\n    const handleEnhancedTouchMove = (event: TouchEvent) => {\n      handleTouchMove(event);\n      handleDragMove();\n    };\n\n    const handleEnhancedTouchEnd = (event: TouchEvent) => {\n      handleTouchEnd(event, (touchEvent) => {\n        if (touchEvent.type === 'tap') {\n          // Tap activates the menu (same as click)\n          triggerHapticFeedback('light');\n          toggleMenu(event);\n        } else if (touchEvent.type === 'swipe') {\n          // Handle swipe gestures\n          const swipe = getSwipeDirection();\n          if (swipe && menuActive.value) {\n            // Use our enhanced swipe to close handler\n            handleSwipeToClose(swipe.direction);\n          }\n        }\n      });\n\n      // Also handle normal drag functionality\n      handleDragEnd(event);\n    };\n\n    // Enhanced swipe handling for menu closing\n    const handleSwipeToClose = (swipeDirection: string) => {\n      if (\n        menuActive.value &&\n        (swipeDirection === 'up' || swipeDirection === 'down' || swipeDirection === 'left')\n      ) {\n        const menuContainerEl = menuContainer.value;\n\n        if (menuContainerEl) {\n          // Determine animation based on swipe direction\n          const transformEnd =\n            swipeDirection === 'up'\n              ? 'translateY(-20px)'\n              : swipeDirection === 'down'\n              ? 'translateY(20px)'\n              : 'translateX(-20px)';\n\n          // Apply closing animation with Web Animation API\n          const animation = menuContainerEl.animate(\n            [\n              { opacity: 1, transform: 'scale(1)' },\n              { opacity: 0, transform: `scale(0.95) ${transformEnd}` },\n            ],\n            {\n              duration: 250,\n              easing: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',\n              fill: 'forwards',\n            }\n          );\n\n          animation.onfinish = () => {\n            menuActive.value = false;\n            if (isRevealing.value) {\n              position.value = previousPosition.value;\n            }\n\n            nextTick(() => {\n              menuHead.value?.focus();\n            });\n          };\n\n          // Provide haptic feedback\n          if (isTouchDevice.value) {\n            triggerHapticFeedback('light');\n          }\n\n          return true;\n        }\n      }\n\n      return false;\n    };\n\n    // Enhanced accessibility for touch devices\n    nextTick(() => {\n      if (menuHeadContainer.value) {\n        ensureTouchTarget(menuHeadContainer.value);\n      }\n    });\n\n    return {\n      // Expose refs\n      menuHead,\n      menuHeadContainer,\n      menuContainer,\n      position,\n      menuActive,\n      dragActive,\n      isTouchDevice,\n      slotsEmpty,\n      menuOrientation,\n      menuCSS,\n      flipMenu,\n      // Expose computed\n      style,\n      computedMenuStyle,\n      getTheme,\n      // Expose methods\n      toggleMenu,\n      handleMenuClose,\n      handleCloseClick,\n      handleMenuItemSelection,\n      handleDragStart,\n      handleDragMove,\n      handleDragEnd,\n      handleEnhancedTouchStart,\n      handleEnhancedTouchMove,\n      handleEnhancedTouchEnd,\n      handleKeyboardMenuActivation,\n      handleSwipeToClose,\n    };\n  },\n});\n</script>\n\n<style lang=\"scss\">\n@use './index';\n@use './styles/accessibility';\n\n/* Fix for double focus indicators */\n.menu-list-item {\n  &.selected,\n  &.highlight {\n    outline: none !important;\n    border: none !important;\n\n    &:focus,\n    &:focus-visible {\n      outline: none !important;\n      border: none !important;\n    }\n  }\n\n  /* Only apply focus style on non-selected/non-highlighted items */\n  &:not(.selected, .highlight):focus-visible {\n    outline: 2px solid #007bff;\n  }\n}\n</style>\n","import type { App } from 'vue';\nimport FloatMenuComponent from './components/index.vue';\n\n// Export the component directly\nexport const FloatMenu = FloatMenuComponent;\n\n// Export types separately\nexport type {\n  MenuItem,\n  Theme,\n  BundleOptimization,\n  FloatMenuProps,\n  FloatMenuInstance,\n} from './types';\n\n// Export theme default\nexport { ThemeDefault } from './types';\n\n// Vue plugin install function\nexport function install(app: App): void {\n  app.component('FloatMenu', FloatMenuComponent);\n}\n\n// Default export for Vue plugin usage\nexport default {\n  install,\n  FloatMenu: FloatMenuComponent,\n};\n","import { ref, computed, onMounted, onUnmounted } from 'vue';\n\n/**\n * Composable for enhanced animations and transitions\n * Includes reduced motion support and smooth animations\n */\nexport function useAnimations() {\n  const prefersReducedMotion = ref(false);\n  const animationQueue = ref<Array<() => void>>([]);\n  const isAnimating = ref(false);\n\n  // Check for reduced motion preference\n  onMounted(() => {\n    const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');\n    prefersReducedMotion.value = mediaQuery.matches;\n\n    const handler = (e: MediaQueryListEvent) => {\n      prefersReducedMotion.value = e.matches;\n    };\n\n    mediaQuery.addEventListener('change', handler);\n\n    onUnmounted(() => {\n      mediaQuery.removeEventListener('change', handler);\n    });\n  });\n\n  /**\n   * Get animation duration based on user preferences\n   */\n  const getAnimationDuration = (normalDuration: number, reducedDuration: number = 0) => {\n    return prefersReducedMotion.value ? reducedDuration : normalDuration;\n  };\n\n  /**\n   * Get transition timing function\n   */\n  const getTimingFunction = (\n    type: 'ease' | 'ease-in' | 'ease-out' | 'ease-in-out' | 'bounce' = 'ease-out'\n  ) => {\n    if (prefersReducedMotion.value) {\n      return 'ease';\n    }\n\n    const timingFunctions = {\n      ease: 'ease',\n      'ease-in': 'cubic-bezier(0.4, 0, 1, 1)',\n      'ease-out': 'cubic-bezier(0, 0, 0.2, 1)',\n      'ease-in-out': 'cubic-bezier(0.4, 0, 0.2, 1)',\n      bounce: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)',\n    };\n\n    return timingFunctions[type];\n  };\n\n  /**\n   * Animate element with smooth transitions\n   */\n  const animateElement = (\n    element: HTMLElement,\n    properties: Record<string, string | number>,\n    options: {\n      duration?: number;\n      delay?: number;\n      easing?: string;\n      onComplete?: () => void;\n    } = {}\n  ) => {\n    const {\n      duration = 300,\n      delay = 0,\n      easing = getTimingFunction('ease-out'),\n      onComplete,\n    } = options;\n\n    const finalDuration = getAnimationDuration(duration);\n\n    if (finalDuration === 0) {\n      // Apply styles immediately if reduced motion\n      Object.entries(properties).forEach(([prop, value]) => {\n        element.style.setProperty(prop, String(value));\n      });\n      onComplete?.();\n      return;\n    }\n\n    // Set transition\n    const transition = `all ${finalDuration}ms ${easing}`;\n    element.style.transition = transition;\n\n    // Apply delay if specified\n    if (delay > 0) {\n      setTimeout(() => applyStyles(), delay);\n    } else {\n      applyStyles();\n    }\n\n    function applyStyles() {\n      Object.entries(properties).forEach(([prop, value]) => {\n        element.style.setProperty(prop, String(value));\n      });\n\n      // Clean up after animation\n      if (onComplete) {\n        setTimeout(() => {\n          element.style.transition = '';\n          onComplete();\n        }, finalDuration);\n      }\n    }\n  };\n\n  /**\n   * Slide animation for menu items\n   */\n  const slideIn = (\n    element: HTMLElement,\n    direction: 'left' | 'right' | 'up' | 'down' = 'right',\n    duration: number = 200\n  ) => {\n    const transforms = {\n      left: 'translateX(-100%)',\n      right: 'translateX(100%)',\n      up: 'translateY(-100%)',\n      down: 'translateY(100%)',\n    };\n\n    // Set initial state\n    element.style.transform = transforms[direction];\n    element.style.opacity = '0';\n\n    // Animate to final state\n    requestAnimationFrame(() => {\n      animateElement(\n        element,\n        {\n          transform: 'translateX(0) translateY(0)',\n          opacity: '1',\n        },\n        {\n          duration: getAnimationDuration(duration),\n          easing: getTimingFunction('ease-out'),\n        }\n      );\n    });\n  };\n\n  /**\n   * Fade animation\n   */\n  const fadeIn = (element: HTMLElement, duration: number = 150) => {\n    element.style.opacity = '0';\n\n    requestAnimationFrame(() => {\n      animateElement(\n        element,\n        {\n          opacity: '1',\n        },\n        {\n          duration: getAnimationDuration(duration),\n          easing: getTimingFunction('ease-out'),\n        }\n      );\n    });\n  };\n\n  const fadeOut = (element: HTMLElement, duration: number = 150, onComplete?: () => void) => {\n    // Add a scale animation along with the fade for a more polished effect\n    animateElement(\n      element,\n      {\n        opacity: '0',\n        transform: 'scale(0.95)',\n      },\n      {\n        duration: getAnimationDuration(duration),\n        easing: getTimingFunction('ease-in'),\n        onComplete,\n      }\n    );\n  };\n\n  /**\n   * Scale animation for hover effects\n   */\n  const scaleAnimation = (element: HTMLElement, scale: number = 1.05, duration: number = 100) => {\n    animateElement(\n      element,\n      {\n        transform: `scale(${scale})`,\n      },\n      {\n        duration: getAnimationDuration(duration),\n        easing: getTimingFunction('ease-out'),\n      }\n    );\n  };\n\n  /**\n   * Reset scale animation\n   */\n  const resetScale = (element: HTMLElement, duration: number = 100) => {\n    animateElement(\n      element,\n      {\n        transform: 'scale(1)',\n      },\n      {\n        duration: getAnimationDuration(duration),\n        easing: getTimingFunction('ease-out'),\n      }\n    );\n  };\n\n  /**\n   * Ripple effect animation\n   */\n  const createRipple = (element: HTMLElement, event: MouseEvent) => {\n    if (prefersReducedMotion.value) return;\n\n    const rect = element.getBoundingClientRect();\n    const size = Math.max(rect.width, rect.height);\n    const x = event.clientX - rect.left - size / 2;\n    const y = event.clientY - rect.top - size / 2;\n\n    const ripple = document.createElement('span');\n    ripple.style.cssText = `\n      position: absolute;\n      border-radius: 50%;\n      background: rgba(255, 255, 255, 0.6);\n      pointer-events: none;\n      left: ${x}px;\n      top: ${y}px;\n      width: ${size}px;\n      height: ${size}px;\n      transform: scale(0);\n      animation: ripple 600ms ease-out;\n    `;\n\n    // Add ripple keyframes if not already added\n    if (!document.querySelector('#ripple-keyframes')) {\n      const style = document.createElement('style');\n      style.id = 'ripple-keyframes';\n      style.textContent = `\n        @keyframes ripple {\n          0% { transform: scale(0); opacity: 1; }\n          100% { transform: scale(1); opacity: 0; }\n        }\n      `;\n      document.head.appendChild(style);\n    }\n\n    element.style.position = 'relative';\n    element.style.overflow = 'hidden';\n    element.appendChild(ripple);\n\n    setTimeout(() => {\n      if (ripple.parentNode) {\n        ripple.parentNode.removeChild(ripple);\n      }\n    }, 600);\n  };\n\n  /**\n   * Queue animations for sequential execution\n   */\n  const queueAnimation = (animationFn: () => void) => {\n    animationQueue.value.push(animationFn);\n\n    if (!isAnimating.value) {\n      processQueue();\n    }\n  };\n\n  const processQueue = async () => {\n    if (animationQueue.value.length === 0) {\n      isAnimating.value = false;\n      return;\n    }\n\n    isAnimating.value = true;\n    const nextAnimation = animationQueue.value.shift();\n\n    if (nextAnimation) {\n      nextAnimation();\n      // Wait for animation to complete before processing next\n      setTimeout(processQueue, getAnimationDuration(100));\n    }\n  };\n\n  /**\n   * CSS transition classes for Vue transitions\n   */\n  const transitionClasses = computed(() => ({\n    'menu-enter-active': `transition-all duration-${getAnimationDuration(200)} ${getTimingFunction(\n      'ease-out'\n    )}`,\n    'menu-leave-active': `transition-all duration-${getAnimationDuration(150)} ${getTimingFunction(\n      'ease-in'\n    )}`,\n    'menu-enter-from': 'opacity-0 transform scale-95',\n    'menu-enter-to': 'opacity-100 transform scale-100',\n    'menu-leave-from': 'opacity-100 transform scale-100',\n    'menu-leave-to': 'opacity-0 transform scale-95',\n  }));\n\n  return {\n    prefersReducedMotion: computed(() => prefersReducedMotion.value),\n    getAnimationDuration,\n    getTimingFunction,\n    animateElement,\n    slideIn,\n    fadeIn,\n    fadeOut,\n    scaleAnimation,\n    resetScale,\n    createRipple,\n    queueAnimation,\n    transitionClasses,\n  };\n}\n","import { computed, ref, shallowRef } from 'vue';\nimport type { MenuItem } from '../../types';\n\n/**\n * Composable for performance optimizations\n * Includes memoization, lazy loading, and efficient reactivity\n */\nexport function usePerformanceOptimizations() {\n  // Use shallowRef for performance when deep reactivity is not needed\n  const memoCache = shallowRef(new Map<string, unknown>());\n\n  /**\n   * Memoize expensive computations\n   */\n  const memoize = <T extends (...args: unknown[]) => unknown>(\n    fn: T,\n    keyGenerator?: (...args: Parameters<T>) => string\n  ): T => {\n    return ((...args: Parameters<T>): ReturnType<T> => {\n      const key = keyGenerator ? keyGenerator(...args) : JSON.stringify(args);\n\n      if (memoCache.value.has(key)) {\n        return memoCache.value.get(key) as ReturnType<T>;\n      }\n\n      const result = fn(...args);\n      memoCache.value.set(key, result);\n      return result as ReturnType<T>;\n    }) as T;\n  };\n\n  /**\n   * Lazy load menu items for better initial performance\n   */\n  const useLazyMenuItems = (data: MenuItem[]) => {\n    const visibleItems = ref<MenuItem[]>([]);\n    const batchSize = 10;\n    const currentBatch = ref(0);\n\n    const loadNextBatch = () => {\n      const start = currentBatch.value * batchSize;\n      const end = start + batchSize;\n      const newItems = data.slice(start, end);\n\n      visibleItems.value.push(...newItems);\n      currentBatch.value++;\n    };\n\n    const loadAllItems = () => {\n      visibleItems.value = [...data];\n    };\n\n    const hasMoreItems = computed(() => {\n      return visibleItems.value.length < data.length;\n    });\n\n    // Load first batch immediately\n    if (data.length > 0) {\n      loadNextBatch();\n    }\n\n    return {\n      visibleItems,\n      loadNextBatch,\n      loadAllItems,\n      hasMoreItems,\n    };\n  };\n\n  /**\n   * Debounce function for performance\n   */\n  const debounce = <T extends (...args: unknown[]) => unknown>(\n    func: T,\n    wait: number\n  ): ((...args: Parameters<T>) => void) => {\n    let timeout: number;\n\n    return (...args: Parameters<T>) => {\n      clearTimeout(timeout);\n      timeout = window.setTimeout(() => func(...args), wait);\n    };\n  };\n\n  /**\n   * Throttle function for performance\n   */\n  const throttle = <T extends (...args: unknown[]) => unknown>(\n    func: T,\n    limit: number\n  ): ((...args: Parameters<T>) => void) => {\n    let inThrottle: boolean;\n\n    return (...args: Parameters<T>) => {\n      if (!inThrottle) {\n        func(...args);\n        inThrottle = true;\n        setTimeout(() => (inThrottle = false), limit);\n      }\n    };\n  };\n\n  /**\n   * Clear memoization cache\n   */\n  const clearCache = () => {\n    memoCache.value.clear();\n  };\n\n  /**\n   * Get cache size for debugging\n   */\n  const getCacheSize = () => {\n    return memoCache.value.size;\n  };\n\n  return {\n    memoize,\n    useLazyMenuItems,\n    debounce,\n    throttle,\n    clearCache,\n    getCacheSize,\n  };\n}\n","import { ref, computed } from 'vue';\nimport type { MenuItem, Theme } from '../../types';\n\ninterface ErrorInfo {\n  id: string;\n  message: string;\n  type: 'warning' | 'error' | 'info';\n  timestamp: Date;\n  context?: unknown;\n}\n\n/**\n * Composable for comprehensive error handling\n * Provides error tracking, logging, and user-friendly error messages\n */\nexport function useErrorHandling() {\n  const errors = ref<ErrorInfo[]>([]);\n  const maxErrors = 10; // Keep only the last 10 errors\n\n  /**\n   * Add a new error\n   */\n  const addError = (\n    message: string,\n    type: 'warning' | 'error' | 'info' = 'error',\n    context?: unknown\n  ) => {\n    const error: ErrorInfo = {\n      id: `error-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,\n      message,\n      type,\n      timestamp: new Date(),\n      context,\n    };\n\n    errors.value.unshift(error);\n\n    // Keep only the most recent errors\n    if (errors.value.length > maxErrors) {\n      errors.value = errors.value.slice(0, maxErrors);\n    }\n\n    // Log to console for debugging\n    if (type === 'error') {\n      console.error(message, context);\n    } else if (type === 'warning') {\n      console.warn(message, context);\n    } else {\n      console.info(message, context);\n    }\n\n    return error.id;\n  };\n\n  /**\n   * Remove an error by ID\n   */\n  const removeError = (id: string) => {\n    const index = errors.value.findIndex((error) => error.id === id);\n    if (index > -1) {\n      errors.value.splice(index, 1);\n    }\n  };\n\n  /**\n   * Clear all errors\n   */\n  const clearErrors = () => {\n    errors.value = [];\n  };\n\n  /**\n   * Clear errors of a specific type\n   */\n  const clearErrorsByType = (type: 'warning' | 'error' | 'info') => {\n    errors.value = errors.value.filter((error) => error.type !== type);\n  };\n\n  /**\n   * Try-catch wrapper with error handling\n   */\n  const tryAsync = async <T>(\n    asyncFn: () => Promise<T>,\n    errorMessage?: string,\n    onError?: (error: Error) => void\n  ): Promise<T | null> => {\n    try {\n      return await asyncFn();\n    } catch (error) {\n      const message =\n        errorMessage ||\n        `An error occurred: ${error instanceof Error ? error.message : 'Unknown error'}`;\n      addError(message, 'error', error);\n      onError?.(error instanceof Error ? error : new Error(String(error)));\n      return null;\n    }\n  };\n\n  /**\n   * Synchronous try-catch wrapper\n   */\n  const trySync = <T>(\n    syncFn: () => T,\n    errorMessage?: string,\n    onError?: (error: Error) => void\n  ): T | null => {\n    try {\n      return syncFn();\n    } catch (error) {\n      const message =\n        errorMessage ||\n        `An error occurred: ${error instanceof Error ? error.message : 'Unknown error'}`;\n      addError(message, 'error', error);\n      onError?.(error instanceof Error ? error : new Error(String(error)));\n      return null;\n    }\n  };\n\n  /**\n   * Validate menu data structure\n   */\n  const validateMenuData = (data: MenuItem[]): boolean => {\n    if (!Array.isArray(data)) {\n      addError('Menu data must be an array', 'error');\n      return false;\n    }\n\n    for (let i = 0; i < data.length; i++) {\n      const item = data[i];\n\n      if (!item || typeof item !== 'object') {\n        addError(`Menu item at index ${i} must be an object`, 'error');\n        return false;\n      }\n\n      if (!item.name && !item.divider) {\n        addError(`Menu item at index ${i} must have a name or be a divider`, 'error');\n        return false;\n      }\n\n      if (item.subMenu && !Array.isArray(item.subMenu.items)) {\n        addError(`Submenu items at index ${i} must be an array`, 'error');\n        return false;\n      }\n\n      // Recursively validate submenu items\n      if (item.subMenu?.items) {\n        const isValid = validateMenuData(item.subMenu.items);\n        if (!isValid) {\n          return false;\n        }\n      }\n    }\n\n    return true;\n  };\n\n  /**\n   * Validate theme object\n   */\n  const validateTheme = (theme: Theme): boolean => {\n    if (!theme || typeof theme !== 'object') {\n      addError('Theme must be an object', 'error');\n      return false;\n    }\n\n    const requiredProps = [\n      'primary',\n      'menuBgColor',\n      'textColor',\n      'textSelectedColor',\n      'hoverBackground',\n    ];\n\n    for (const prop of requiredProps) {\n      if (!(prop in theme)) {\n        addError(`Theme is missing required property: ${prop}`, 'warning');\n      }\n    }\n\n    return true;\n  };\n\n  /**\n   * Handle DOM errors gracefully\n   */\n  const handleDOMError = (error: Error, element?: HTMLElement) => {\n    addError(`DOM operation failed: ${error.message}`, 'error', {\n      error,\n      element: element?.tagName,\n    });\n  };\n\n  /**\n   * Handle keyboard event errors\n   */\n  const handleKeyboardError = (error: Error, keyCode?: string) => {\n    addError(`Keyboard navigation error: ${error.message}`, 'error', { error, keyCode });\n  };\n\n  /**\n   * Handle animation errors\n   */\n  const handleAnimationError = (error: Error, animationType?: string) => {\n    addError(`Animation error: ${error.message}`, 'warning', { error, animationType });\n  };\n\n  /**\n   * Get user-friendly error message\n   */\n  const getUserFriendlyMessage = (error: ErrorInfo): string => {\n    const friendlyMessages: Record<string, string> = {\n      'Menu data must be an array': 'Invalid menu configuration. Please check your menu data.',\n      'DOM operation failed': 'Interface error occurred. Please try again.',\n      'Keyboard navigation error': 'Navigation issue detected. Please use mouse or try again.',\n      'Animation error': 'Display issue occurred. Functionality is not affected.',\n    };\n\n    for (const [pattern, message] of Object.entries(friendlyMessages)) {\n      if (error.message.includes(pattern)) {\n        return message;\n      }\n    }\n\n    return 'An unexpected error occurred. Please try again.';\n  };\n\n  // Computed properties\n  const hasErrors = computed(() => errors.value.length > 0);\n  const errorCount = computed(() => errors.value.length);\n  const latestError = computed(() => errors.value[0] || null);\n  const errorsByType = computed(() => {\n    return {\n      errors: errors.value.filter((e) => e.type === 'error'),\n      warnings: errors.value.filter((e) => e.type === 'warning'),\n      info: errors.value.filter((e) => e.type === 'info'),\n    };\n  });\n\n  return {\n    errors: computed(() => errors.value),\n    hasErrors,\n    errorCount,\n    latestError,\n    errorsByType,\n    addError,\n    removeError,\n    clearErrors,\n    clearErrorsByType,\n    tryAsync,\n    trySync,\n    validateMenuData,\n    validateTheme,\n    handleDOMError,\n    handleKeyboardError,\n    handleAnimationError,\n    getUserFriendlyMessage,\n  };\n}\n"],"names":["utils","head","content","headDimension","menuDimension","top","bottom","getBoundingClientRect","left","Math","round","clientWidth","menuHeight","clientHeight","newOrientation","newMenuStyle","window","innerHeight","Object","assign","height","width","element","position","flipOnEdges","menuContainer","right","innerWidth","screenWidth","screenHeight","menuContWidth","menuContHalfWidth","ceil","newPosition","flipMenu","reveal","abs","flip","dimension","MENU_HEAD_SPACING","script$6","defineComponent","name","xmlns","viewBox","fill","stroke","class","_openBlock","openBlock","_createElementBlock","createElementBlock","_hoisted_1","_cache","_createElementVNode","createElementVNode","x1","y1","x2","y2","script$5","script$4","points","script$3","strokeWidth","strokeLinecap","strokeLinejoin","script$2","ThemeDefault","primary","textColor","menuBgColor","textSelectedColor","hoverBackground","useTouchOptimizations","isTouchDevice","ref","isLongPress","touchStartTime","touchStartPosition","x","y","touchEndPosition","onMounted","value","navigator","maxTouchPoints","test","userAgent","document","body","classList","add","style","createElement","textContent","appendChild","onUnmounted","remove","computed","handleTouchStart","event","callback","touch","touches","Date","now","clientX","clientY","longPressTimer","setTimeout","touchEvent","type","target","startPosition","duration","force","_longPressTimer","handleTouchMove","distance","sqrt","pow","clearTimeout","handleTouchEnd","velocity","endPosition","getSwipeDirection","deltaX","deltaY","direction","triggerHapticFeedback","intensity","patterns","light","medium","heavy","vibrate","ensureTouchTarget","minSize","rect","currentSize","min","padding","minWidth","minHeight","getOptimalMenuOrientation","menuElement","triggerElement","viewport","triggerRect","menuRect","spaceBelow","spaceAbove","enhanceAccessibility","touchAction","hasAttribute","setAttribute","useBundleOptimizations","optimizations","lazyLoad","treeShaking","codesplitting","compression","loadComponent","async","componentName","Promise","resolve","then","useTouchOptimizations$1","useAnimations$1","usePerformanceOptimizations$1","useErrorHandling$1","Error","error","loadComposablesConditionally","features","matchMedia","matches","hardwareConcurrency","loadPromises","push","all","splitStrategy","toLowerCase","isMobile","nav","isSlowConnection","connection","effectiveType","preloadCriticalResources","href","as","forEach","resource","link","rel","getBundleInfo","core","touchOptimizations","accessibility","animations","performance","errorHandling","keyboardNavigation","total","measurePerformance","operationName","operation","mark","startMark","endMark","measureName","measure","getEntriesByName","markAsUsed","featureName","undefined","monitorMemoryUsage","perf","memory","used","usedJSHeapSize","totalJSHeapSize","limit","jsHeapSizeLimit","enableCompression","script$1","components","ChevRightIcon","PlusIcon","MinusIcon","props","data","Array","default","Boolean","onSelection","Function","onClose","required","theme","menuStyle","String","setup","activeIndex","menuItems","toggleMenu","selectMenuItem","setActiveIndex","closeAllSubMenus","updateSelectedItem","map","item","id","random","toString","showSubMenu","selectFirstItem","targetItem","find","wasOpen","subMenu","items","index","selected","unref","resetActiveIndex","updateMenuItems","newData","i","useMenuState","menuRef","SubMenuComponent","resolveComponent","prefersReducedMotion","mediaQuery","addEventListener","e","nextTick","focus","length","firstItemIndex","findIndex","divider","disabled","animationDuration","handleSubmenuOpen","submenuId","submenu","querySelector","firstItem","announcement","className","removeChild","themeStyles","subMenuClass","menuItemClass","isAccordion","isFirstItemSelected","watch","val","handleMenuItemClickWithErrorHandling","stopPropagation","preventDefault","currentTarget","outline","border","contains","handleKeyUpWithErrorHandling","actvIndex","keyCode","key","len","nextIndex","prevIndex","handleSubmenuClose","filter","handleMouseEnter","transform","transition","backgroundColor","handleMouseLeave","handleBeforeTransitionLeave","_el","handleAfterTransitionEnter","el","styleInject","css","insertAt","getElementsByTagName","firstChild","insertBefore","styleSheet","cssText","createTextNode","role","tabindex","onKeyup","_ctx","args","_Fragment","Fragment","iconSlot","_normalizeClass","onMousedown","$event","onMouseenter","onMouseleave","_hoisted_4","onClick","_hoisted_2","_renderSlot","_createBlock","createBlock","_component_chev_right_icon","_component_plus_icon","_component_minus_icon","_createVNode","_Transition","onBeforeLeave","onAfterEnter","_resolveDynamicComponent","resolveDynamicComponent","_renderList","keys","$slots","slot","fn","_withCtx","scope","_mergeProps","mergeProps","MenuProps","Number","fixed","menuData","useCustomContent","onSelected","preserveMenuPosition","script","MenuIcon","MenuComponent","XIcon","Props","slots","previousPosition","menuHead","menuHeadContainer","menuActive","menuCSS","menuOrientation","dragActive","dragStart","isTouch","ontouchstart","moveEvent","computedMenuStyle","isRevealing","pos","slotsEmpty","onCloseMenu","from","some","cls","onWindowResize","intialStyle","replace","handleMove","MouseEvent","TouchEvent","initPosition","nodeName","capture","removeEventListener","menuContDOM","menuHeadDOM","newStyle","setupMenuOrientation","positionRef","adjustFloatMenuPosition","menuContainerEl","getAnimations","anim","cancel","handleMenuClose","animation","animate","opacity","easing","onfinish","getTheme","handleDragStart","handleDragMove","handleDragEnd","changedTouches","handleSwipeToClose","swipeDirection","transformEnd","handleCloseClick","handleMenuItemSelection","handleEnhancedTouchStart","handleEnhancedTouchMove","handleEnhancedTouchEnd","swipe","handleKeyboardMenuActivation","normalizeClass","onMouseup","onMousemove","onTouchstart","onTouchend","onTouchmove","draggable","onKeydown","_component_MenuIcon","_component_XIcon","_component_MenuComponent","renderSlot","_normalizeProps","_guardReactiveProps","FloatMenu","FloatMenuComponent","install","app","component","animationQueue","isAnimating","handler","getAnimationDuration","normalDuration","reducedDuration","getTimingFunction","ease","bounce","animateElement","properties","options","delay","onComplete","finalDuration","entries","prop","setProperty","applyStyles","processQueue","nextAnimation","shift","transitionClasses","slideIn","up","down","requestAnimationFrame","fadeIn","fadeOut","scaleAnimation","scale","resetScale","createRipple","size","max","ripple","overflow","parentNode","queueAnimation","animationFn","memoCache","shallowRef","Map","memoize","keyGenerator","JSON","stringify","has","get","result","set","useLazyMenuItems","visibleItems","currentBatch","loadNextBatch","start","end","newItems","slice","hasMoreItems","loadAllItems","debounce","func","wait","timeout","throttle","inThrottle","clearCache","clear","getCacheSize","errors","addError","message","context","substr","timestamp","unshift","validateMenuData","isArray","hasErrors","errorCount","latestError","errorsByType","warnings","info","removeError","splice","clearErrors","clearErrorsByType","tryAsync","asyncFn","errorMessage","onError","trySync","syncFn","validateTheme","requiredProps","handleDOMError","tagName","handleKeyboardError","handleAnimationError","animationType","getUserFriendlyMessage","friendlyMessages","pattern","includes"],"mappings":"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","x_google_ignoreList":[17]}