@use 'sass:list';
@use 'imports-default/imports' as colours;

// How far a default focus ring reaches beyond the border box: the outline sits at
// `outline-offset` and is itself `--ds-borderWidth-thin` wide, so the reach is twice that
// token. Components that clip their content use this to reserve room for a focus ring
// drawn on a descendant. Holds for the non-inset ring at the default offset multiplier.
$focusRingReach: calc(var(--ds-borderWidth-thin) * 2);

@mixin dsFocusStyles($focusInset, $focusBoxShadowColor, $focusOutlineColor, $inset, $offsetMultiplier) {
  $boxShadowWidth: var(--ds-borderWidth-thin);
  $outlineOffset: var(--ds-borderWidth-thin);

  @if $inset {
    $boxShadowWidth: var(--ds-borderWidth-thick);
    $outlineOffset: calc(var(--ds-borderWidth-thin) * -1);
  }

  box-shadow: #{$focusInset} 0 0 0 $boxShadowWidth $focusBoxShadowColor;
  outline: var(--ds-borderWidth-thin) solid $focusOutlineColor;
  outline-offset: calc($outlineOffset * $offsetMultiplier);
}

@mixin dsFocusRing($inverted: false, $inset: false, $focusVisible: true, $focusWithin: false, $offsetMultiplier: 1) {
  $focusOutlineColor: colours.$dsBorderColorBlack;
  $focusBoxShadowColor: colours.$dsBorderColorWhite;
  $focusInset: '';

  @if $inverted {
    $focusOutlineColor: colours.$dsBorderColorWhite;
    $focusBoxShadowColor: colours.$dsBorderColorBlack;
  }

  @if $inset {
    $focusInset: inset;
  }

  $selectors: ();

  @if $focusVisible {
    $selectors: list.append($selectors, ':focus-visible');
  }

  @if $focusWithin {
    $selectors: list.append($selectors, ':focus-within');
  }

  @each $selector in $selectors {
    &#{$selector} {
      @include dsFocusStyles($focusInset, $focusBoxShadowColor, $focusOutlineColor, $inset, $offsetMultiplier);
    }
  }
}
