/**
 * Copyright IBM Corp. 2021, 2025
 * SPDX-License-Identifier: MPL-2.0
 */

// For an explanation of the ":focus/:focus-visible" states see:
// - https://github.com/hashicorp/design-system-components/issues/161
// - https://www.tpgi.com/focus-visible-and-backwards-compatibility/

@mixin hds-focus-ring-basic($color: action) {
  outline-style: solid; // used to avoid double outline+focus-ring in Safari (see https://github.com/hashicorp/design-system-components/issues/161#issuecomment-1031548656)
  outline-color: transparent;

  // default focus for browsers that still rely on ":focus"
  &:focus,
  &.mock-focus {
    box-shadow: var(--token-focus-ring-#{$color}-box-shadow);
  }
  // undo the previous declaration for browsers that support ":focus-visible" but wouldn't normally show default focus styles
  &:focus:not(:focus-visible) {
    box-shadow: none;
  }
  // set focus for browsers that support ":focus-visible"
  &:focus-visible {
    box-shadow: var(--token-focus-ring-#{$color}-box-shadow);
  }
  // remove the focus ring on "active + focused" state (by design)
  &:focus:active,
  &.mock-focus.mock-active {
    box-shadow: none;
  }
}

@mixin hds-focus-ring-with-pseudo-element(
  $top: 0,
  $right: 0,
  $bottom: 0,
  $left: 0,
  $radius: 5px,
  $color: action,
  $position: relative
) {
  position: $position;
  outline-style: solid; // used to avoid double outline+focus-ring in Safari (see https://github.com/hashicorp/design-system-components/issues/161#issuecomment-1031548656)
  outline-color: transparent;
  isolation: isolate; // used to create a new stacking context (needed to have the pseudo element below text/icon but not the parent container)

  &::before {
    position: absolute;
    top: $top;
    right: $right;
    bottom: $bottom;
    left: $left;
    z-index: -1;
    border-radius: $radius;
    content: "";
  }

  // default focus for browsers that still rely on ":focus"
  &:focus,
  &.mock-focus {
    &::before {
      box-shadow: var(--token-focus-ring-#{$color}-box-shadow);
    }
  }
  // undo the previous declaration for browsers that support ":focus-visible" but wouldn't normally show default focus styles
  &:focus:not(:focus-visible) {
    &::before {
      box-shadow: none;
    }
  }
  // set focus for browsers that support ":focus-visible"
  &:focus-visible {
    &::before {
      box-shadow: var(--token-focus-ring-#{$color}-box-shadow);
    }
  }
  // remove the focus ring on "active + focused" state (by design)
  &:focus:active,
  &.mock-focus.mock-active {
    &::before {
      box-shadow: none;
    }
  }
}

// This mixin is used for the _rare_ cases where we want the focus ring to be visible when the user clicks the element (not just if they focus it with a keyboard).
@mixin hds-focus-ring-with-pseudo-element-focus-always-visible(
  $top: 0,
  $right: 0,
  $bottom: 0,
  $left: 0,
  $radius: 5px,
  $color: action,
  $position: relative
) {
  position: $position;
  outline-style: solid; // used to avoid double outline+focus-ring in Safari (see https://github.com/hashicorp/design-system-components/issues/161#issuecomment-1031548656)
  outline-color: transparent;
  isolation: isolate; // used to create a new stacking context (needed to have the pseudo element below text/icon but not the parent container)

  &::before {
    position: absolute;
    top: $top;
    right: $right;
    bottom: $bottom;
    left: $left;
    z-index: -1;
    border-radius: $radius;
    content: "";
  }

  // default focus for browsers that still rely on ":focus"
  &:focus,
  &.mock-focus {
    &::before {
      box-shadow: var(--token-focus-ring-#{$color}-box-shadow);
    }
  }

  // remove the focus ring on "active + focused" state (by design)
  &:focus:active,
  &.mock-focus.mock-active {
    &::before {
      box-shadow: none;
    }
  }
}
