// Foundation for Sites
// https://get.foundation
// Licensed under MIT Open Source

////
/// @group button
////

/// Font family for button elements.
/// @type Font
$button-font-family: inherit !default;

/// Font weight for button elements.
/// Ignored if null (default)
/// @type Font-Weight
$button-font-weight: null !default;

/// Padding inside buttons.
/// @type List
$button-padding: 0.85em 1em !default;

/// Margin around buttons.
/// @type List
$button-margin: 0 0 $global-margin 0 !default;

/// Default fill for buttons. Can either be `solid` or `hollow`.
/// @type Keyword
$button-fill: solid !default;

/// Default background color for buttons.
/// @type Color
$button-background: $primary-color !default;

/// Background color on hover for buttons.
/// @type Color
$button-background-hover: scale-color($button-background, $lightness: -15%) !default;

/// Font color for buttons.
/// @type List
$button-color: $white !default;

/// Alternative font color for buttons.
/// @type List
$button-color-alt: $black !default;

/// Border radius for buttons, defaulted to global-radius.
/// @type Number
$button-radius: $global-radius !default;

/// Border for buttons, transparent by default
/// @type List
$button-border: 1px solid transparent !default;

/// Border width for hollow outline buttons
/// @type Number
$button-hollow-border-width: 1px !default;

/// Sizes for buttons.
/// @type Map
$button-sizes: (
  tiny: 0.6rem,
  small: 0.75rem,
  default: 0.9rem,
  large: 1.25rem,
) !default;

/// Coloring classes. A map of classes to output in your CSS, like `.secondary`, `.success`, and so on.
/// @type Map
$button-palette: $foundation-palette !default;

/// opacity for a disabled button.
/// @type List
$button-opacity-disabled: 0.25 !default;

/// Background color lightness on hover for buttons.
/// @type Number
$button-background-hover-lightness: -20% !default;

/// Color lightness on hover for hollow buttons.
/// @type Number
$button-hollow-hover-lightness: -50% !default;

// Internal: flip from margin-right to margin-left for defaults
@if $global-text-direction == 'rtl' {
  $button-margin: 0 0 $global-margin $global-margin !default;
}

/// transitions for buttons.
/// @type List
$button-transition: background-color 0.25s ease-out, color 0.25s ease-out !default;

/// Additional responsive classes for .expanded
/// @type Boolean
$button-responsive-expanded: false !default;

// TODO: Document button-base() mixin
@mixin button-base {
  @include disable-mouse-outline;
  display: inline-block;
  vertical-align: middle;
  margin: $button-margin;

  @if (type-of($button-padding) == 'map') {
    @each $size, $padding in $button-padding {
      @include breakpoint($size) {
        padding: $padding;
      }
    }
  }
  @else {
    padding: $button-padding;
  }

  border: $button-border;
  border-radius: $button-radius;
  transition: $button-transition;
  font-family: $button-font-family;
  font-size: map-get($button-sizes, default);
  font-weight: $button-font-weight;
  -webkit-appearance: none; // sass-lint:disable-line no-vendor-prefixes
  line-height: 1;
  text-align: center;
  cursor: pointer;
}

/// Expands a button to make it full-width.
/// @param {Boolean} $expand [true] - Set to `true` to enable the expand behavior. Set to `false` to reverse this behavior.
@mixin button-expand($expand: true) {
  @if $expand {
    display: block;
    width: 100%;
    margin-right: 0;
    margin-left: 0;
  }
  @else {
    display: inline-block;
    width: auto;
    margin: $button-margin;
  }
}

/// Sets the base styles of a hollow or clear button filling according to `$fill`.
/// See mixin `button-fill-style` for the filling styles.
/// @param {Keyword} $fill [$button-fill] - Type of filling between `hollow` and `clear`. `solid` has no effects.
@mixin button-fill(
  $fill: $button-fill
) {
  @if $fill == hollow {
    @include button-hollow;
  }
  @else if $fill == clear {
    @include button-clear;
  }
}

/// Sets the visual styles of a solid/hollow/clear button filling according to `$fill`.
/// See mixins `button-style`, `button-hollow-style` and `button-clear-style` for effects of visual styling parameters.
/// @param {Keyword} $fill [$button-fill] - Type of filling between `hollow` and `clear`.
/// @param {Color} $background [$button-background] - -
/// @param {Color} $background-hover [$button-background-hover] - -
/// @param {Color} $color [$button-color] - -
@mixin button-fill-style(
  $fill: $button-fill,
  $background: $button-background,
  $background-hover: $button-background-hover,
  $color: $button-color
) {
  @if $fill == solid {
    @include button-style($background, $background-hover, $color);
  }
  @else if $fill == hollow {
    @include button-hollow-style($background);
  }
  @else if $fill == clear {
    @include button-clear-style($background);
  }
}

/// Sets the visual style of a button.
/// @param {Color} $background [$button-background] - Background color of the button.
/// @param {Color} $background-hover [$button-background-hover] - Background color of the button on hover. Set to `auto` to have the mixin automatically generate a hover color.
/// @param {Color} $color [$button-color] - Text color of the button. Set to `auto` to automatically generate a color based on the background color.
@mixin button-style(
  $background: $button-background,
  $background-hover: $button-background-hover,
  $color: $button-color,
  $background-hover-lightness: $button-background-hover-lightness
) {
  @if $color == auto {
    $color: color-pick-contrast($background, ($button-color, $button-color-alt));
  }

  @if $background-hover == auto {
    $background-hover: scale-color($background, $lightness: $background-hover-lightness);
  }

  // Default and disabled states
  &,
  &.disabled, &[disabled],
  &.disabled:hover, &[disabled]:hover,
  &.disabled:focus, &[disabled]:focus {
    background-color: $background;
    color: $color;
  }

  &:hover, &:focus {
    background-color: $background-hover;
    color: $color;
  }
}

/// Sets the base styles of a hollow button.
/// See mixin `button-hollow-style` for the filling styles.
@mixin button-hollow {
  &, &.disabled, &[disabled] {
    &, &:hover, &:focus {
      background-color: transparent;
    }
  }
}

/// Sets the visual style of a hollow button.
/// @param {Color} $color [$button-background] - Text and border color of the button.
/// @param {Color} $hover-lightness [$button-hollow-hover-lightness] - Color lightness on hover.
/// @param {Color} $border-width [$button-hollow-border-width] - Border width of the button.
@mixin button-hollow-style(
  $color: $button-background,
  $hover-lightness: $button-hollow-hover-lightness,
  $border-width: $button-hollow-border-width
) {
  $color-hover: scale-color($color, $lightness: $hover-lightness);

  // Default and disabled states
  &,
  &.disabled, &[disabled],
  &.disabled:hover, &[disabled]:hover,
  &.disabled:focus, &[disabled]:focus {
    border: $border-width solid $color;
    color: $color;
  }

  &:hover, &:focus {
    border-color: $color-hover;
    color: $color-hover;
  }
}

/// Sets the base styles of a clear button.
/// See mixin `button-clear-style` for the filling styles.
@mixin button-clear {
  &, &.disabled, &[disabled] {
    &, &:hover, &:focus {
      border-color: transparent;
      background-color: transparent;
    }
  }
}

/// Sets the visual style of a clear button.
/// @param {Color} $color [$button-background] - Text color of the button.
/// @param {Color} $hover-lightness [$button-hollow-hover-lightness] - Color lightness on hover.
@mixin button-clear-style(
  $color: $button-background,
  $hover-lightness: $button-hollow-hover-lightness
) {
  $color-hover: scale-color($color, $lightness: $hover-lightness);

  // Default and disabled states
  &,
  &.disabled, &[disabled],
  &.disabled:hover, &[disabled]:hover,
  &.disabled:focus, &[disabled]:focus {
    color: $color;
  }

  &:hover, &:focus {
    color: $color-hover;
  }
}

/// Adds disabled styles to a button by fading the element and reseting the cursor.
/// @param {Number} $opacity [$button-opacity-disabled] - Opacity of the disabled button.
@mixin button-disabled(
  $opacity: $button-opacity-disabled
) {
  opacity: $button-opacity-disabled;
  cursor: not-allowed;
}

/// Adds a dropdown arrow to a button.
/// @param {Number} $size [0.4em] - Size of the arrow. We recommend using an `em` value so the triangle scales when used inside different sizes of buttons.
/// @param {Color} $color [white] - Color of the arrow.
/// @param {Number} $offset [$button-padding] - Distance between the arrow and the text of the button. Defaults to whatever the right padding of a button is.
@mixin button-dropdown(
  $size: 0.4em,
  $color: $white,
  $offset: get-side($button-padding, right)
) {
  &::after {
    @include css-triangle($size, $color, down);
    position: relative;
    top: 0.4em; // Aligns the arrow with the text of the button

    display: inline-block;
    float: #{$global-right};
    margin-#{$global-left}: $offset;
  }
}

/// Adds all styles for a button. For more granular control over styles, use the individual button mixins.
/// @param {Boolean} $expand [false] - Set to `true` to make the button full-width.
/// @param {Color} $background [$button-background] - Background color of the button.
/// @param {Color} $background-hover [$button-background-hover] - Background color of the button on hover. Set to `auto` to have the mixin automatically generate a hover color.
/// @param {Color} $color [$button-color] - Text color of the button. Set to `auto` to automatically generate a color based on the background color.
/// @param {Keyword} $style [solid] - Set to `hollow` to create a hollow button. The color defined in `$background` will be used as the primary color of the button.
@mixin button(
  $expand: false,
  $background: $button-background,
  $background-hover: $button-background-hover,
  $color: $button-color,
  $style: $button-fill
) {
  @include button-base;
  @include button-fill($style);
  @include button-fill-style($style, $background, $background-hover, $color);

  @if $expand {
    @include button-expand;
  }
}

@mixin foundation-button {
  .button {
    @include button($style: none);

    // Sizes
    @each $size, $value in map-remove($button-sizes, default) {
      &.#{$size} {
        font-size: $value;
      }
    }

    &.expanded { @include button-expand; }

    @if $button-responsive-expanded {
      @each $size in $breakpoint-classes {
        @include breakpoint(#{$size} only) {
          &.#{$size}-only-expanded {
            @include button-expand;
          }
        }
        @if $size != $-zf-zero-breakpoint {
          @include breakpoint(#{$size} down) {
            &.#{$size}-down-expanded {
              @include button-expand;
            }
          }

          @include breakpoint(#{$size}) {
            &.#{$size}-expanded {
              @include button-expand;
            }
          }
        }
      }
    }

    // Solid, hollow & clear styles
    @each $filling in (solid hollow clear) {
      $selector: if($button-fill == $filling, null, '.#{$filling}');

      &#{$selector} {
        @include button-fill($filling);
        @include button-fill-style($filling);

        @each $name, $color in $button-palette {
          &.#{$name} {
            @include button-fill-style($filling, $color, auto, auto);
          }
        }
      }
    }

    // Disabled state
    &.disabled, &[disabled] {
      @include button-disabled;
    }

    // Dropdown arrow
    &.dropdown {
      @include button-dropdown;

      @if $button-fill == hollow {
        &::after {
          border-top-color: $button-background;
        }
      }

      &.hollow, &.clear {
        &::after {
          border-top-color: $button-background;
        }

        @each $name, $color in $button-palette {
          &.#{$name} {
            &::after {
              border-top-color: $color;
            }
          }
        }
      }
    }

    // Button with dropdown arrow only
    &.arrow-only::after {
      top: -0.1em;
      float: none;
      margin-#{$global-left}: 0;
    }
  }

  a.button { // sass-lint:disable-line no-qualifying-elements
    &:hover,
    &:focus {
      text-decoration: none;
    }
  }
}
