/*
* Checkbox component
*
*/

@import '../../../style/core/utilities.scss';

:root {
  --checkbox-width--medium: 1.5rem;
  --checkbox-height--medium: 1.5rem;
}

.dnb-checkbox {
  --checkbox-border-radius: 0.25rem;
  --checkbox-gfx-border-radius__indeterminate: 0.125rem;
  --checkbox-width--large: 2rem;
  --checkbox-height--large: 2rem;
  --checkbox-gfx-height__indeterminate: 0.625rem;
  --checkbox-gfx-width__indeterminate: 0.625rem;
  --checkbox-gfx-height__indeterminate--large: 0.875rem;
  --checkbox-gfx-width__indeterminate--large: 0.875rem;
  // Normal state
  --checkbox-border-width: 0.09375rem;
  --checkbox-color-gfx-on: black;
  --checkbox-color-gfx-off: white;
  --checkbox-color-background-on: white;
  --checkbox-color-background-off: white;
  --checkbox-color-border-on: black;
  --checkbox-color-border-off: black;
  // Disabled state
  --checkbox-border-width--disabled: 0.125rem;
  --checkbox-color-gfx--disabled: grey;
  --checkbox-color-background-on--disabled: lightgrey;
  --checkbox-color-background-off--disabled: lightgrey;
  --checkbox-color-border-on--disabled: grey;
  --checkbox-color-border-off--disabled: grey;
  --checkbox-color-gfx__indeterminate--disabled: grey;
  // Active state
  --checkbox-color-background--active: lightgrey;
  --checkbox-color-border--active: transparent;
  // Hover state
  --checkbox-border-width--hover: 0.125rem;
  --checkbox-color-gfx--hover: grey;
  --checkbox-color-background--hover: white;
  --checkbox-color-border-on--hover: grey;
  --checkbox-color-border-off--hover: grey;
  // Focus state
  --checkbox-color-gfx--focus: grey;
  --checkbox-color-background--focus: lightgrey;
  // Error state
  --checkbox-border-width--error: 0.125rem;
  --checkbox-color-gfx--error: lavenderblush;
  --checkbox-color-gfx--error-contrast: red;
  --checkbox-color-background-on--error: red;
  --checkbox-color-background--error-contrast: lavenderblush;
  --checkbox-color-border--error: red;
  --checkbox-color-gfx-indeterminate--error: red;
  --checkbox-color-gfx--error--hover: red;
  --checkbox-color-background--error--hover: lavenderblush;
  --checkbox-color-border--error--hover: red;
  // Indeterminate state
  --checkbox-color-background-indeterminate: grey;
  --checkbox-color-gfx-indeterminate: darkgray;
  // Indeterminate Active state
  --checkbox-color-background-indeterminate--active: grey;
  --checkbox-color-border-indeterminate--active: white;
  --checkbox-color-gfx-indeterminate--active: white;

  // Bounding box
  --checkbox-bounding--medium: 1.75, 1.75;

  display: inline-flex;
  flex-direction: column;

  font-size: var(--font-size-small);
  line-height: var(--line-height-basis);

  &__inner {
    display: inline-flex;
    flex-direction: column;
    align-self: center;
  }

  &__shell {
    user-select: none; // Safari / Touch fix
    position: relative;

    display: flex;
    align-items: center;
    justify-content: center;

    width: var(--checkbox-width--medium);
    height: var(--checkbox-height--medium);
  }

  &--large &__shell {
    width: var(--checkbox-width--large);
    height: var(--checkbox-height--large);
  }

  &__button {
    display: inline-block;

    border: var(--checkbox-border-width) solid transparent;
  }

  &__focus {
    display: none;

    @include focusRing();
  }

  &__focus,
  &__button {
    position: relative;
    z-index: 4;

    width: calc(var(--checkbox-width--medium) - 0.25rem);
    height: calc(var(--checkbox-height--medium) - 0.25rem);

    border-radius: var(--checkbox-border-radius);

    .dnb-checkbox--large & {
      width: var(--checkbox-width--large);
      height: var(--checkbox-height--large);

      border-radius: var(--checkbox-border-radius);
    }
  }

  &__gfx {
    position: absolute;
    z-index: 5;

    top: auto;
    left: auto;

    // width: var(--checkbox-width--medium); // old svg size
    // height: var(--checkbox-height--medium); // old svg size
    width: calc(var(--checkbox-width--medium) - 0.5rem);
    height: calc(var(--checkbox-height--medium) - 0.5rem);

    shape-rendering: geometricprecision;
    transition:
      opacity 200ms ease-out,
      transform 200ms ease-out;
  }

  &--large {
    line-height: var(--checkbox-height--large);
  }

  &--large &__gfx {
    width: calc(var(--checkbox-width--large) - 0.5rem);
    height: calc(var(--checkbox-height--large) - 0.5rem);
  }

  &__input {
    opacity: 0;

    position: absolute;
    top: auto;
    left: auto;
    z-index: 6;

    width: var(--checkbox-width--medium);
    height: var(--checkbox-height--medium);

    margin: 0;
    padding: 0;

    border: 0;

    // Larger bounding box
    transform: scale(var(--checkbox-bounding--medium));
  }

  &--large &__input {
    width: var(--checkbox-width--large);
    height: var(--checkbox-height--large);

    // reset scale
    transform: scale(1);
  }

  &__input:not([disabled]) {
    cursor: pointer;
  }

  .dnb-form-label {
    margin-bottom: 0;
    margin-right: 0;
    margin-left: 0;
  }

  &__order {
    display: inline-flex;
    align-items: baseline;
  }

  &__suffix {
    order: 4;
  }

  &--label-position-left &__order {
    .dnb-checkbox__inner {
      order: 2;
    }

    .dnb-form-label {
      order: 1;
      padding-right: 0.5rem;
    }

    .dnb-form-status {
      order: 3;
      margin-top: 0.5rem;
    }
  }

  &--label-position-right &__order {
    .dnb-checkbox__inner {
      order: 1;
    }

    .dnb-form-label {
      order: 2;
      padding-left: 0.5rem;
    }

    & + .dnb-form-status {
      order: 3;

      // in case the status did not wrap, we want to have the status on the same line
      vertical-align: top;

      margin-top: 0.5rem;
    }
  }

  /*
   * Color scheme
   */

  // stylelint-disable no-descending-specificity
  // We prioritize categorization and readability over specificity here

  /** Normal state **/

  // On
  &__input:checked ~ &__gfx,
  &__input[data-checked='true'] ~ &__gfx {
    opacity: 1;
    transform: scale(1);
    color: var(--checkbox-color-gfx-on);
  }

  &__input:checked ~ &__button,
  &__input[data-checked='true'] ~ &__button {
    background-color: var(--checkbox-color-background-on);
    border-color: var(--checkbox-color-border-on);
  }

  // Off
  &__input:not(:checked):not([data-checked='true']) ~ &__gfx {
    opacity: 0;
    transform: scale(0.8);
    // Needed during transition
    color: var(--checkbox-color-gfx-off);
  }

  &__input:not(:checked):not([data-checked='true']) ~ &__button {
    background-color: var(--checkbox-color-background-off);
    border-color: var(--checkbox-color-border-off);

    transition: background-color 100ms ease-out;
  }

  // Show the icon when indeterminate is true
  &__input ~ &__indeterminate {
    position: absolute;
    z-index: 5;

    width: var(--checkbox-gfx-width__indeterminate);
    height: var(--checkbox-gfx-height__indeterminate);

    transform: scale(0.85);
    opacity: 0;

    background-color: var(--checkbox-color-gfx-indeterminate);
    border-radius: var(--checkbox-gfx-border-radius__indeterminate);

    transition:
      opacity 200ms ease-out,
      transform 200ms ease-out;
  }

  &__input:indeterminate ~ &__indeterminate {
    transform: scale(1);
    opacity: 1;
  }

  &__input:indeterminate:checked ~ &__button {
    background-color: transparent;
    border-color: var(--checkbox-color-border-off);
  }
  &__input:indeterminate:hover ~ &__gfx,
  &__input:indeterminate:checked ~ &__gfx,
  &__input:indeterminate:checked:hover ~ &__gfx {
    color: transparent;
  }

  &--large &__input:indeterminate ~ &__indeterminate {
    width: var(--checkbox-gfx-width__indeterminate--large);
    height: var(--checkbox-gfx-height__indeterminate--large);
  }

  /** Disabled state **/

  // General
  &__input[disabled]:checked ~ &__button {
    border-width: var(--checkbox-border-width--disabled);
  }

  // On
  &__input[disabled]:checked ~ &__button,
  &__input[disabled][data-checked='true'] ~ &__button {
    background-color: var(--checkbox-color-background-on--disabled);
    border-color: var(--checkbox-color-border-on--disabled);
  }

  &__input[disabled]:checked ~ &__gfx,
  &__input[disabled][data-checked='true'] ~ &__gfx {
    color: var(--checkbox-color-gfx--disabled);
  }

  // Off
  &__input[disabled]:not(:checked):not([data-checked='true']) ~ &__button {
    border-color: var(--checkbox-color-border-off--disabled);
    background-color: var(--checkbox-color-background-off--disabled);
  }

  // indeterminate
  &__input[disabled]:indeterminate ~ &__indeterminate {
    background-color: var(--checkbox-color-gfx__indeterminate--disabled);
  }

  &__input[disabled]:indeterminate ~ &__gfx {
    // hide check gfx
    color: transparent;
  }

  /** Active state **/

  // General
  &__input:not([disabled]):active ~ &__button {
    background-color: var(--checkbox-color-background--active);
    border-color: var(--checkbox-color-border--active);
  }

  // On
  &__input:not([disabled]):checked:active ~ &__gfx,
  &__input:not([disabled])[data-checked='true']:active ~ &__gfx {
    color: var(--checkbox-color-gfx-on);
  }

  // Indeterminate
  &__input:not([disabled]):indeterminate:active ~ &__button {
    background-color: var(
      --checkbox-color-background-indeterminate--active
    );
    border-color: var(--checkbox-color-border-indeterminate--active);
  }

  &__input:not([disabled]):indeterminate:active ~ &__indeterminate {
    background-color: var(--checkbox-color-gfx-indeterminate--active);
  }

  /** Hover state **/

  // General
  &__input:not([disabled]):not(:active):hover ~ &__button {
    border-color: var(--checkbox-color-border-off--hover);
    background-color: var(--checkbox-color-background--hover);
    border-width: var(--checkbox-border-width--hover);
  }

  &__input:hover ~ &__gfx {
    color: var(--checkbox-color-gfx--hover);
  }

  // On
  &__input:not([disabled]):checked:hover ~ &__button,
  &__input:not([disabled])[data-checked='true']:hover ~ &__button {
    border: var(--checkbox-border-width--hover) solid
      var(--checkbox-color-border-on--hover);
  }

  /** Focus state **/

  // General
  &__input:not([disabled]):focus-visible ~ &__button {
    html[data-whatinput='keyboard'] & {
      border: none;
      background-color: var(--checkbox-color-background--focus);
    }
  }

  &__input:not([disabled]):focus-visible ~ &__gfx {
    html[data-whatinput='keyboard'] & {
      color: var(--checkbox-color-gfx--focus);
    }
  }

  &__input:not([disabled]):focus-visible ~ &__button &__focus,
  &__input:not([disabled]):active ~ &__button &__focus {
    display: block;
  }

  &__input:not([disabled]):focus-visible ~ &__indeterminate {
    background-color: var(--checkbox-color-gfx--focus);
  }

  /** Error state **/

  // General
  &__status--error &__input:not([disabled]):not(:active) ~ &__button {
    border: none;
  }

  &__status--error
    &__input:not([disabled]):not(:active)
    ~ &__button
    &__focus {
    display: block;
    @include fakeBorder(
      var(--checkbox-color-border--error),
      var(--checkbox-border-width--error)
    );
  }

  &__status--error &__input:not([disabled]):hover ~ &__button {
    &[data-checked='true'] {
      // Needed during transition
      border-color: var(--checkbox-color-border--error--hover);
    }

    background-color: var(--checkbox-color-background--error--hover);
  }

  &__status--error &__input:not([disabled]):hover ~ &__gfx {
    color: var(--checkbox-color-gfx--error--hover);
  }

  &__status--error
    &__input:not([disabled]):not(:active):not(:hover)
    ~ &__gfx {
    color: var(--checkbox-color-gfx--error);
  }

  &__status--error &__input:not([disabled]):focus ~ &__button,
  &__status--error &__input:not([disabled]):focus:hover ~ &__button {
    html[data-whatinput='keyboard'] & {
      border: none;
      background-color: var(--checkbox-color-background--error-contrast);
      @include fakeBorder(
        var(--checkbox-color-border--error),
        calc(var(--checkbox-border-width--hover))
      );
    }
  }

  &__status--error &__input:not([disabled]):focus:hover ~ &__gfx {
    html[data-whatinput='keyboard'] & {
      color: var(--checkbox-color-gfx--error-contrast);
    }
  }

  // On
  &__status--error
    &__input:not([disabled]):not(:active):not(:hover):checked
    ~ &__button,
  &__status--error
    &__input:not([disabled]):not(:active):not(:hover)[data-checked='true']
    ~ &__button {
    background-color: var(--checkbox-color-background-on--error);
  }

  &__status--error
    &__input:indeterminate:not([disabled]):not(:active):not(:hover)
    ~ &__gfx {
    // used for animation
    color: var(--checkbox-color-gfx--error-contrast);
    background-color: var(--checkbox-color-gfx--error-contrast);
    border-radius: var(--checkbox-border-radius);
  }

  &__status--error
    &__input:indeterminate:not(:active):not(:hover)
    ~ &__indeterminate {
    background-color: var(--checkbox-color-gfx-indeterminate--error);
  }

  &__status--error &__input:not(:indeterminate) ~ &__indeterminate {
    // used for animation
    background-color: var(--checkbox-color-gfx-indeterminate--error);
  }

  &__status--error
    &__input:indeterminate:hover:not(:active)
    ~ &__indeterminate {
    background-color: var(--checkbox-color-gfx--error--hover);
  }

  &__status--error &__input:not([disabled]):not(:active):hover ~ &__gfx {
    color: var(--checkbox-color-gfx--error--hover);
  }

  &.dnb-skeleton &__input[disabled] ~ &__button {
    &::before {
      border-radius: 0;
    }

    border-color: var(--skeleton-color);
  }

  &.dnb-skeleton &__input[disabled] ~ &__gfx {
    color: var(--skeleton-color);
  }

  &.dnb-skeleton &__input[disabled] ~ &__indeterminate {
    background-color: var(--skeleton-color);
  }

  // stylelint-enable no-descending-specificity
}
