// Copyright (c) 2014, 2025, Oracle and/or its affiliates.  Licensed under The Universal Permissive License (UPL), Version 1.0 as shown at https://oss.oracle.com/licenses/upl/

// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// WARNING: do not directly import this file, instead import the
//          version in your base theme's directory,
//          for example alta/widgets/_oj.alta.menu.scss
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

@import "../../utilities/oj.utilities";

@if $includeMenuClasses != false  {
  @include module-include-once("common.menu") {

    /* menu */
    /* --------------------------------------------------------------- */

    oj-menu {
      display: none;
    }

    // defines the stacking context for the menu
    .oj-menu-layer {
      @extend .oj-component-layer;

        z-index: $popupZindex;

    }

    // top-level menu (component root node) and all submenus
    .oj-menu {
        @extend .oj-component-popup;
        list-style: none;
        padding-left: 0;
        padding-right: 0;

          color: $textColor;
          padding-top: $menuPadding;
          padding-bottom: $menuPadding;

        margin: 0;
        display: inline-block;
        white-space: nowrap;

        // prevent iOS from applying tap-highlight-color that's darker than the "pressed" color in the spec
        -webkit-tap-highlight-color: transparent;
    }

    // top-level menu (component root node) when displayed as a dropdown
    .oj-menu-dropdown {

        border: $menuBorderWidth solid $menuBorderColor;
        border-radius: $menuBorderRadius;
        background: $menuBgColor;
        font-size: $fontSize;

    }

    // top-level menu (component root node) when displayed as a sheet
    .oj-menu-sheet {
        border: 0;

          border-radius: $menuSheetBorderRadius;
          background: $menuSheetBgColor;
          font-size: $menuSheetFontSize;
          width: calc(100% - (2 * #{oj-add-unit-to-zero($menuSheetMarginHorizontal)}));

    }

    .oj-menu:focus {
        outline:none; // suppress native focus ring, e.g. desktop Chrome's blue outline
    }

    // top-level menu (component root node) but not submenus
    .oj-menu-dropdown.oj-component {

        @include oj-box-shadow($menuBoxShadow);        

    }

    // submenus but not top-level menu
    .oj-menu.oj-menu-submenu {
        // Needs to be fixed position so submenu is placed correctly including cases where parent menu has overflow-Y: auto (scrolls)
        position: fixed;

        @include oj-box-shadow($menuSubmenuBoxShadow);

    }

    .oj-menu-item {
        margin: 0;
        padding: 0;
        width: 100%;
        display: list-item;
    }

    // first item in a dropdown menu
    .oj-menu-dropdown .oj-menu-item:first-child,
    .oj-menu-dropdown .oj-menu-item:first-child > a {

        border-top-left-radius: $menuBorderRadius;
        border-top-right-radius: $menuBorderRadius;

    }

    // last item in a dropdown menu
    .oj-menu-dropdown .oj-menu-item:last-child,
    .oj-menu-dropdown .oj-menu-item:last-child > a {

        border-bottom-left-radius: $menuBorderRadius;
        border-bottom-right-radius: $menuBorderRadius;

    }

    // first item in a sheet menu
    .oj-menu-sheet .oj-menu-item:first-child,
    .oj-menu-sheet .oj-menu-item:first-child > a {

        border-top-left-radius: $menuSheetBorderRadius;
        border-top-right-radius: $menuSheetBorderRadius;

    }

    // last item in a sheet menu
    .oj-menu-sheet .oj-menu-item:last-child,
    .oj-menu-sheet .oj-menu-item:last-child > a {

        border-bottom-left-radius: $menuSheetBorderRadius;
        border-bottom-right-radius: $menuSheetBorderRadius;

    }

    // first item after a group divider in a sheet menu
    .oj-menu-sheet .oj-menu-item-after-divider,
    .oj-menu-sheet .oj-menu-item-after-divider > a {

        border-top-left-radius: $menuSheetItemGroupBorderRadius;
        border-top-right-radius: $menuSheetItemGroupBorderRadius;

    
    }

    // last item before a group divider in a sheet menu
    .oj-menu-sheet .oj-menu-item-before-divider,
    .oj-menu-sheet .oj-menu-item-before-divider > a {

        border-bottom-left-radius: $menuSheetItemGroupBorderRadius;
        border-bottom-right-radius: $menuSheetItemGroupBorderRadius;

    }

    // Horizontal divider between groups of menu items
    .oj-menu-divider {

        margin: $menuDividerMargin;

        height: 0;
        font-size: 0;
        line-height: 0;
        border-style: solid;
        display: list-item;
    }

    // Group divider in a dropdown menu
    .oj-menu-dropdown .oj-menu-divider {

        border-width: $menuDividerBorderWidth 0 0 0;
        border-color: $menuDividerBorderColor;

    }

    // Group divider in a sheet menu
    .oj-menu-sheet .oj-menu-divider {

        border-width: $menuSheetDividerBorderWidth 0 0 0;
        border-color: $menuSheetDividerBorderColor;

    }

    // > and (space) select the same anchors
    .oj-menu-item > a {
        @if ($themeTargetPlatform == ios) {
            padding: 0 calc(16px + (2 * #{$menuSubmenuIconPadding})) 0 calc(16px + (4 * #{$menuSubmenuIconPadding}));
        } @else {
        padding: 0 $menuTextToEdgePadding;
        }


      // relative positioning so that the absolutely positioned submenu icons are
      // positioned relative to the <a>
      position: relative;
      text-decoration: none;
      display: flex;
      align-items: center;

      font-weight: normal;
    }

    .oj-menu-dropdown .oj-menu-item > a {

        height: $menuItemLineHeight;
        line-height: $menuItemLineHeight;
        color: $menuItemTextColor;
        border-top-width: $menuItemTopBorderWidth;
        border-top-color: $menuItemBorderColor;
        border-top-style: solid;

    }

    .oj-menu-sheet .oj-menu-item > a {

        height: $menuItemLineHeight;
        line-height: $menuSheetItemLineHeight;
        background: $menuSheetItemBgColor;
        color: $menuSheetItemTextColor;
        border-top-width: $menuSheetItemTopBorderWidth;
        border-top-color: $menuSheetItemBorderColor;
        border-top-style: solid;

    }

    // last menu item
    .oj-menu-item:last-child > a {

        border-bottom-width: $menuItemBottomBorderWidth;
        border-bottom-color: transparent;
        border-bottom-style: solid;

    }

    // "Cancel" menu item
    .oj-menu-item-cancel > a {

        font-weight: $menuSheetItemCancelFontWeight;

    }

    /* For each menu and submenu, either oj-menu-icons or oj-menu-text-only is applied to the menu, depending on whether at
       least one menu item in the menu (excluding its "Cancel" menu item and submenus) has an icon (not submenu icon).
       These classes facilitate (say) leaving space for a column of icons iff at least one item has an icon, and doing so
       for each menu/submenu independently. */

    // need > rather than (space) to avoid matching the items of a submenu without icons whose ancestor menu has icons
    a.oj-menu-option-start-icon  {

        // leave space at start of item for icon plus spacing before/after it.  
        @include oj-ltr() {
            padding-left: calc(#{$menuIconToEdgePadding} + #{$menuIconSize} + #{$menuTextToIconPadding});
        }
        @include oj-rtl() {
            padding-right: calc(#{$menuIconToEdgePadding} + #{$menuIconSize} + #{$menuTextToIconPadding});
        }

    }
    
    a.oj-menu-option-end-icon {

        // leave space at start of item for icon plus spacing before/after it.
        @include oj-ltr() {
            padding-right: calc(#{$menuIconToEdgePadding} + #{$menuIconSize} + #{$menuTextToIconPadding});
        }
        @include oj-rtl() {
            padding-left: calc(#{$menuIconToEdgePadding} + #{$menuIconSize} + #{$menuTextToIconPadding});
        }

    }

    // need > rather than (space) to avoid matching the items of a submenu with icons whose ancestor menu lacks icons
    a.oj-menu-option-text-only  {
        // To work around WebKit/Apple platform bug 151657, we can't use display:flex for elements with selector
        // .oj-menu-item > a (see above), so we also can't use justify-content.
        // Use text-align instead to horizontally align text until Apple fixes their VoiceOver bug.
        // While this workaround remains necessary, the only non-null values supported for this variable are
        // "flex-start" and "center", which we map to their text-align equivalents null and "center" below.
        // justify-content: $menuTextOnlyJustifyContent;


          @if $menuTextOnlyJustifyContent == center {
              text-align: center; // see above comment
              // set menu item start padding same as end padding, so that centered text is really centered.
              @include oj-ltr() {
                  padding-left: calc(16px + (2 * #{$menuSubmenuIconPadding}));
              }
              @include oj-rtl() {
                  padding-right: calc(16px + (2 * #{$menuSubmenuIconPadding}));
              }
          } @else {
              text-align: initial;
              @include oj-ltr() {
                  padding-left: $menuTextToEdgePadding;
              }
              @include oj-rtl() {
                  padding-right: $menuTextToEdgePadding;
              }
          }

    }

    // If the Cancel menu item is present, then either show an icon in its icon span, or hide
    // its icon span, depending on whether at least one other item in the menu has an icon.
    // Cancel items and their icons only appear in sheet menus, which never have submenus,
    // so can use space operator rather than a long chain of > operators.
    .oj-menu-option-start-icon .oj-menu-cancel-icon {
        @extend .oj-fwk-icon-cross02;
    }

    .oj-menu-option-text-only .oj-menu-cancel-icon {
        display:none;
    }

    // need > rather than (space) to avoid selecting (suppressing the border of) menu items having
    // an ancestor menu item that follows a group divider
    .oj-menu-divider + .oj-menu-item > a {
        // In themes with borders between every menu item, don't put one immediately after a group divider
        border-top-width: 0;
    }

    @if ($themeTargetPlatform == android) {
      // oj-focus (or oj-focus-ancestor) is applied to a group divider whenever an adjacent menu item has the oj-focus 
      // (or oj-focus-ancestor) class
      .oj-menu-divider.oj-focus,
      .oj-menu-divider.oj-focus-ancestor {

          // In Android, focused items get a border, and the adjacent divider, if any, serves as that border.
          border-color: $menuItemBorderColorFocus;

      }
    }


    // The oj-focus-highlight class applies focus styling that may not be desirable
    // when the focus results from pointer interaction (touch or mouse), but which is
    // needed for accessibility when the focus occurs by a non-pointer mechanism, for
    // example keyboard or initial page load.
    // See also the $focusHighlightPolicy variable, which controls when this
    // class is set.  That variable affects multiple components, not just Menu.
    .oj-menu-item.oj-focus-highlight > a {

        @include oj-browser-focus-outline-approximation($textColor);        

    }

    // use > rather than (space) so that themers wanting to theme focus and focus-ancestor separately
    // don't have to contend with the fact that, whenever a submenu item is focused, our
    // "oj-focus-ancestor a" selector unintentionally selects the ".oj-focus > a" element too.
    .oj-menu-dropdown .oj-menu-item.oj-focus          > a,
    .oj-menu-dropdown .oj-menu-item.oj-focus-ancestor > a {

        background: $menuItemBgColorFocus;

    }

    // border before and after a focused (or focus-ancestor) item in a dropdown menu
    .oj-menu-dropdown .oj-menu-item.oj-focus                          > a,
    .oj-menu-dropdown .oj-menu-item.oj-focus-ancestor                 > a,
    .oj-menu-dropdown .oj-menu-item.oj-focus          + .oj-menu-item > a,
    .oj-menu-dropdown .oj-menu-item.oj-focus-ancestor + .oj-menu-item > a {

        border-top-color: $menuItemBorderColorFocus;        

    }

    // when the last menu item is focused, it needs a bottom border in themes that put borders on menu items,
    // and that have a space between that menu item and the bottom of the menu
    .oj-menu-dropdown .oj-menu-item:last-child.oj-focus          > a,
    .oj-menu-dropdown .oj-menu-item:last-child.oj-focus-ancestor > a {
      //TODO

        @if $menuItemBorderColor != null and $menuPadding {
            border-bottom-color: $menuItemBorderColorFocus;

      }
    }

    .oj-menu-sheet .oj-menu-item.oj-focus > a {

        background: $menuSheetItemBgColorFocus;        

    }

    // border before and after a focused (or focus-ancestor) item in a sheet menu
    .oj-menu-sheet .oj-menu-item.oj-focus                          > a,
    .oj-menu-sheet .oj-menu-item.oj-focus          + .oj-menu-item > a {

        border-top-color: $menuSheetItemBorderColorFocus;        

    }

    // when the last menu item is focused, it needs a bottom border in themes that put borders on menu items,
    // and that have a space between that menu item and the bottom of the menu
    .oj-menu-sheet .oj-menu-item:last-child.oj-focus          > a {
      // TODO

        @if $menuItemBorderColor != null and $menuPadding {
            border-bottom-color: $menuSheetItemBorderColorFocus;
        }

    }

    // disabled menu items can't have open submenus, so > and (space) are equivalent
    .oj-menu.oj-disabled .oj-menu-item > a,
    .oj-menu-item.oj-disabled > a {
        cursor: default;
    }

    // disabled menu items can't have open submenus, so > and (space) are equivalent
    .oj-menu-dropdown.oj-disabled .oj-menu-item > a,
    .oj-menu-dropdown .oj-menu-item.oj-disabled > a {

        color: $menuItemTextColorDisabled;         

    }

    // disabled menu items can't have open submenus, so > and (space) are equivalent
    .oj-menu-sheet.oj-disabled .oj-menu-item > a,
    .oj-menu-sheet .oj-menu-item.oj-disabled > a {  

        color: $menuSheetItemTextColorDisabled;         

    }

    /* menu item icons (not submenu icons) */

    .oj-menu-item-icon,
    .oj-menu-item-end-icon {

        color: $menuIconColor;


        // To work around WebKit/Apple platform bug 151657, we can't use display:flex for elements with selector
        // .oj-menu-item > a (see above), so we also can't use align-self.
        // Use transform instead to vertically center icon until Apple fixes their VoiceOver bug.
        // align-self: center;
        position: absolute;
        // END of replacement for align-self
    }

    .oj-menu-item-icon {

        // negative start margin so that (a) icon is shifted startward into the space left for it by the menu item's
        // start padding, and (b) total of icon's size, start margin, and end margin is 0, so that start edge of text
        // is in the same horiz location whether there's an icon or not, so text lines up across menu items with and
        // without icons.
        @include oj-ltr() {
            margin-left:   calc(0px - #{$menuIconSize} - #{$menuTextToIconPadding});
            margin-right:  $menuTextToIconPadding;
        }

        @include oj-rtl() {
            margin-right:  calc(0px - #{$menuIconSize} - #{$menuTextToIconPadding});
            margin-left:   $menuTextToIconPadding;
        }

    }
    
    .oj-menu-item-end-icon {

        @include oj-ltr() {
            right: 0;
            margin-right:   $menuTextToIconPadding;
            margin-left:   calc(0px - #{$menuIconSize} - #{$menuTextToIconPadding});
        }

        @include oj-rtl() {
            left: 0;
            margin-left:  $menuTextToIconPadding;
            margin-right:  calc(0px - #{$menuIconSize} - #{$menuTextToIconPadding});
        }

    }

    // menu item icons (not submenu icons)
    // Need extra specificity to overcome sizes in the icons themselves, e.g. iOS/Android want to
    // show 16px icons at 24px.
    .oj-menu-item .oj-menu-item-icon,
    .oj-menu-item .oj-menu-item-end-icon {

        font-size: $menuIconSize;        
      
    }

    .oj-menu.oj-disabled .oj-menu-item-icon,
    .oj-menu.oj-disabled .oj-menu-item-end-icon,
    .oj-menu-item.oj-disabled .oj-menu-item-icon,
    .oj-menu-item.oj-disabled .oj-menu-item-end-icon {

        color: $menuIconColorDisabled;
        opacity: $menuIconOpacityDisabled;

    }

    .oj-menu-submenu-icon {
      @extend .oj-fwk-icon-arrow03-end;

        @include oj-ltr() {
            right: $menuSubmenuIconPadding;
        }
        @include oj-rtl() {
            left: $menuSubmenuIconPadding;
        }

        color: $menuSubmenuIconColor;

        position: absolute;
        line-height: 1.8;
        height: auto;
    }

    // Applied to context menu launcher on devices that support touch.  Not for launcher of other popup menus, or menu itself.
    // See comments in baseComponent for details.
    .oj-menu-context-menu-launcher {
        // Prevent native context menu / callout from appearing in Mobile Safari.  Apparently needed only for links, whose native CM has "Open in New Tab", etc.
        // Per v1.1.0 Release Notes, WebKit bug 136685 breaks this in iOS8.1-8.2, but 7, 8.3, and Android Chrome are fine.  webkit.org/show_bug.cgi?id=136685
        -webkit-touch-callout: none;

        // In Mobile Safari and Android Chrome, prevents press-hold from selecting the text and showing the selection handles and (in Safari) the Copy/Define callout.
        // Per v1.1.0 Release Notes, in iOS7 only, this doesn't work well: the selection UI just appears for a neighboring region instead.  Not even setting the style
        // on the document helps, as the style seems not to inherit.  iOS8 and Android Chrome are fine.

          @include oj-user-select-property(none);

    }

    // High Contrast
    //--------------------------------------------
    .oj-hicontrast .oj-menu-item.oj-focus          > a,
    .oj-hicontrast .oj-menu-item.oj-focus-ancestor > a {
        outline: dotted 3px;
    }

    .oj-hicontrast .oj-menu-item.oj-focus.oj-disabled > a {
        outline: dotted 1px;
    }

    .oj-hicontrast .oj-menu-item.oj-disabled > a {
        border: dotted 1px;
    }
  }
}
