/*
 * Utilities
 */

@import '../../components/space/style/space-mixins.scss';

@mixin defaultDropShadow() {
  box-shadow: var(--shadow-default);
}

// Uses html:not([data-whatintent='touch'] )
// classes on <html> element
// based on js touch device test
@mixin hover() {
  html:not([data-whatintent='touch']) &:hover {
    &[disabled] {
      cursor: not-allowed;
    }
    &:not([disabled]) {
      @content;
    }
  }
}
@mixin active() {
  &:active,
  html:not([data-whatintent='touch']) &:active {
    &[disabled] {
      cursor: not-allowed;
    }
    // stylelint-disable-next-line
    &:not([disabled]) {
      @content;
    }
  }
}

@mixin focus-visible() {
  html:not([data-whatintent='touch']) &:focus-visible {
    &[disabled] {
      cursor: not-allowed;
    }
    // stylelint-disable-next-line
    &:not([disabled]) {
      @content;
    }
  }
}

@mixin focus() {
  &:focus,
  html:not([data-whatintent='touch']) &:focus {
    &[disabled] {
      cursor: not-allowed;
    }
    // stylelint-disable-next-line
    &:not([disabled]) {
      @content;
    }
  }
}

@mixin whatInput($whatinput: null) {
  html[data-whatinput='#{$whatinput}'] & {
    @content;
  }
}
@mixin whatInputNot($whatinput: null) {
  html:not([data-whatinput='#{$whatinput}']) & {
    @content;
  }
}

@mixin focusRing(
  $whatinput: null,
  $color: null,
  $inset: null,
  $extendShadow: null
) {
  outline: none;

  @if $whatinput == null {
    $whatinput: 'keyboard';
  }
  @if $color == null {
    $color: var(--focus-ring-color);
  }

  @if $whatinput == 'always' {
    @include fakeBorder(
      $color,
      var(--focus-ring-width),
      $inset,
      $extendShadow: $extendShadow
    );
  } @else {
    @include whatInput($whatinput) {
      @include fakeBorder(
        $color,
        var(--focus-ring-width),
        $inset,
        $extendShadow: $extendShadow
      );
    }
  }
}

@mixin removeFocusRing($whatinput: null, $replace: none) {
  outline: initial;

  @if $whatinput == null {
    box-shadow: $replace;
  }

  html[data-whatinput='#{$whatinput}'] & {
    box-shadow: $replace;
  }
}

@mixin fakeBorder(
  $color: null,
  $width: null /* 1px */,
  $inset: null,
  $important: null,
  $extendShadow: null
) {
  @if $width == null {
    $width: 0.0625rem;
  }

  --border-color: #{$color};
  --border-width: #{$width};

  // we use !important, cause we have no changes to select the selector right
  // in some cases we have another state where we use box-shadow
  // but with important, we take care of that we actually can use use it
  box-shadow: (
      $inset 0 0 0 var(--border-width) var(--border-color),
      $extendShadow
    )
    $important;

  @if $color != null {
    border-color: transparent;
  }
}

@mixin extendFocusRing(
  $first-color: null,
  $second-color: null,
  $width: 0.0625rem /*1px*/
) {
  $second: 0 0 0 calc(var(--focus-ring-width) + #{$width}) $second-color;
  box-shadow:
    0 0 0 $width $first-color,
    $second;
}

@mixin dummySpacing() {
  // we use "aria-hidden" SPAN to simulate a wider width for each tab
  .dnb-dummy {
    display: flex;
    flex-direction: column;

    height: 0;
    visibility: hidden;
    overflow: hidden;
  }
}

@mixin scrollbarAppearance() {
  // older iOS safari
  -webkit-overflow-scrolling: touch;

  // show scrollbar in IE & Edge
  -ms-overflow-style: auto;

  // NB: We have used "scrollbar-track-width: auto;" before,
  // first, it only effects Firefox.
  // But "thin" changes the behavior in Windows,
  // so it has no arrow buttons, and a weird "pressed" color.
  // Also, on macOS, it changes the scrollbar to be so small,
  // that e.g. the textarea resize grabber gets way smaller.

  scrollbar-color: var(--scrollbar-thumb-color, #888) transparent;

  @supports not (scrollbar-color: auto) {
    // stylelint-disable
    &::-webkit-scrollbar {
      &:vertical {
        width: var(--scrollbar-track-width, 0.5rem);
      }
      &:horizontal {
        height: var(--scrollbar-track-width, 0.5rem);
      }

      border-radius: var(--scrollbar-thumb-width, 0.5rem);
      background-color: var(--scrollbar-track-color, #eee);
    }
    &::-webkit-scrollbar-thumb {
      background-color: var(--scrollbar-thumb-color, #888);

      &:hover {
        background-color: var(--scrollbar-thumb-hover-color, #666);
      }

      border-radius: var(--scrollbar-thumb-width, 0.5rem);
    }
    // stylelint-enable
  }
}

@mixin scrollY($mode: scroll) {
  overflow-y: $mode;
  overscroll-behavior: contain;

  html:not([data-visual-test]) & {
    scroll-behavior: smooth;
  }

  @include scrollbarAppearance();
}

@mixin scrollX($mode: scroll) {
  overflow-x: $mode;
  overscroll-behavior: contain;

  html:not([data-visual-test]) & {
    scroll-behavior: smooth;
  }

  @include scrollbarAppearance();
}

@mixin hideScrollbar() {
  /* Hide scrollbar for Chrome, Safari */
  /* stylelint-disable-next-line */
  &::-webkit-scrollbar {
    display: none;
  }
  -ms-overflow-style: none; /* IE and Edge */
  scrollbar-width: none; /* Firefox */
}

// Edge fix
@mixin IS_EDGE() {
  @supports (-ms-ime-align: auto) {
    @content;
  }
}

// Firefox fix
@mixin IS_FF() {
  @-moz-document url-prefix() {
    @content;
  }
}

// Chrome fix
@mixin IS_CHROME() {
  @supports (-webkit-appearance: none) and
    (not (overflow: -webkit-marquee)) and (not (-ms-ime-align: auto)) and
    (not (-moz-appearance: none)) {
    @content;
  }
}

// Safari Mobile fix
@mixin IS_SAFARI_MOBILE() {
  @supports (-webkit-touch-callout: none) {
    @content;
  }
}

// Safari Desktop fix
@mixin IS_SAFARI_DESKTOP() {
  @supports (-webkit-appearance: none) and (stroke-color: transparent) and
    (not (-webkit-touch-callout: none)) {
    @content;
  }
}

$breakpoints: (
  'x-small': 25em /* not documented yet */,
  'small': 40em,
  'medium': 60em,
  'large': 72em,
  'x-large': 80em /* not documented yet */,
  'xx-large': 90em /* not documented yet */,
);
$breakpoint-offset: 0;

// Example usage:
// @include allAbove(medium){ styles go here.. }
// $offset and $list are needed to provide global customization options
@mixin allAbove($size, $offset: $breakpoint-offset, $list: $breakpoints) {
  @media screen and (min-width: (if(map-has-key($list, $size), map-get($list, $size), $size) + $offset + 0.00625)) {
    @content;
  }
}
@mixin allBelow($size, $offset: $breakpoint-offset, $list: $breakpoints) {
  @media screen and (max-width: (if(map-has-key($list, $size), map-get($list, $size), $size) + $offset)) {
    @content;
  }
}
@mixin allBetween(
  $fromSize,
  $toSize,
  $fromOffset: $breakpoint-offset,
  $toOffset: $breakpoint-offset
) {
  @include allBelow($toSize, $toOffset) {
    @include allAbove($fromSize, $fromOffset) {
      @content;
    }
  }
}

// Vertical alignment helper
@mixin alignmentHelper() {
  // Add a char to align the component
  &::before {
    content: '\200C'; // zero-width non-joiner
    @include alignmentHelperClass();
  }
}
@mixin alignmentHelperClass() {
  display: inline-block;
  width: 0;
  height: 0;

  font-size: var(--font-size-small);

  speak: none;
}

// Screen reader only helper
@mixin srOnly() {
  user-select: none !important;
  -webkit-touch-callout: none !important; // iOS
  pointer-events: none !important;

  position: absolute !important;

  clip-path: inset(50%) !important;
  max-width: 1px !important; // if less than 1px, Safari moves the focus-ring to another place
  max-height: 1px !important; // if less than 1px, Safari moves the focus-ring to another place

  overflow: hidden !important;
  white-space: nowrap !important; // NB: so NVDA not splits up text in multi line

  padding: 0 !important;
  margin: 0 !important;

  border: 0 !important;
}

@function str-replace($string, $search, $replace: '') {
  $index: string.index($string, $search);

  @if $index {
    @return str-slice($string, 1, $index - 1) + $replace +
      str-replace(
        str-slice($string, $index + str-length($search)),
        $search,
        $replace
      );
  }

  @return $string;
}

@mixin formLabelWrap() {
  @media screen and (max-width: 40em) {
    flex-wrap: wrap;
    & > .dnb-form-label {
      margin-bottom: 0.5rem;
      margin-top: 0.5rem;
    }
  }
}

@mixin fieldsetReset() {
  @include spaceReset();
  padding: 0;
  border: none;
}
