// this style sheet contains shared styles for the input and textarea
// that needs to be shared between OnyxInput and OnyxTextarea
@use "layers";
@use "density.scss";

@mixin invalid($formElement) {
  &:not(.onyx-form-element-suppress-invalid) {
    &.onyx-form-element--touched-invalid:has(
        #{$formElement}:user-invalid,
        #{$formElement}--touched:invalid
      ),
    &.onyx-form-element--immediate-invalid:has(#{$formElement}:invalid) {
      @content;
    }
  }
}

@mixin success($formElement) {
  &:has(.onyx-form-element__success-message) {
    @content;
  }
}

@mixin define-shared-styles($base-selector, $vertical-padding) {
  --border-color: var(--onyx-color-component-border-neutral);
  --border-radius: var(--onyx-radius-sm);
  --hover-border-color: var(--onyx-color-component-border-primary-hover);
  --selection-color: var(--onyx-color-base-primary-200);
  --caret-color: var(--onyx-color-component-cta-default);
  --background-color: var(--onyx-color-base-background-blank);
  --outline-color: var(--onyx-color-component-focus-primary);
  --outline-style: none;
  --button-color: var(--onyx-color-text-icons-neutral-soft);
  --border-radius: var(--onyx-radius-sm);
  --border-style: solid;
  --padding-horizontal: var(--onyx-density-sm);

  &__wrapper {
    border-radius: var(--border-radius);
    border: var(--onyx-1px-in-rem) var(--border-style) var(--border-color);
    background-color: var(--background-color);
    color: var(--onyx-color-text-icons-neutral-medium);

    outline: var(--onyx-outline-width) var(--outline-style) var(--outline-color);

    display: flex;
    align-items: center;
    gap: var(--onyx-density-xs);

    font-size: var(--onyx-font-size-md);
    line-height: var(--onyx-font-line-height-md);
    padding: $vertical-padding var(--padding-horizontal);
    height: calc(1lh + 2 * #{$vertical-padding});

    #{$base-selector}__native {
      color: var(--onyx-color-text-icons-neutral-intense);
    }

    &:has(#{$base-selector}__native:read-write):hover {
      --border-color: var(--hover-border-color, var(--onyx-color-component-border-primary-hover));
      --button-color: var(--button-hover-color, var(--onyx-color-text-icons-primary-medium));
    }

    &:has(#{$base-selector}__native:enabled:focus, #{$base-selector}__native--show-focus) {
      --border-color: var(--focus-border-color, var(--onyx-color-component-border-primary-hover));
      --outline-style: solid;

      &:has(#{$base-selector}__native:read-write) {
        --button-color: var(--button-focus-color, var(--onyx-color-text-icons-primary-intense));
      }
    }

    // :read-only is valid for readonly and disabled state so we put shared styles for both states here
    &:has(#{$base-selector}__native:read-only) {
      --selection-color: var(--onyx-color-base-neutral-200);
      --caret-color: var(--onyx-color-base-neutral-700);
      --background-color: var(--onyx-color-base-background-tinted);
    }

    // styles for readonly but NOT disabled
    &:has(#{$base-selector}__native:enabled:read-only) {
      &:hover {
        --border-color: var(--onyx-color-component-border-neutral-hover);
      }

      &:has(#{$base-selector}__native:focus, #{$base-selector}__native--show-focus) {
        --border-color: var(--onyx-color-component-border-neutral);
        --outline-color: var(--onyx-color-component-focus-neutral);
      }
    }

    &:has(#{$base-selector}__native:read-write) {
      &:has(#{get-autofill-selectors("#{$base-selector}__native")}) {
        background-color: var(--onyx-color-base-warning-100);
      }
    }

    // hide success check icon when input is focussed
    &:focus-within,
    &:has(#{$base-selector}__native--show-focus) {
      #{$base-selector}__check-icon {
        display: none;
      }
    }
  }

  &__separator {
    // should have full height, but not overlap actual border
    --onyx-separator-min-size: calc(
      1lh + 2 * var(--onyx-input-padding-vertical) - 2 * var(--onyx-1px-in-rem)
    );
    $margin: calc(var(--onyx-density-sm) - var(--onyx-density-xs));

    &--leading {
      margin-left: $margin;
    }
    &--trailing {
      margin-right: $margin;
    }
  }

  &__loading {
    color: var(--onyx-color-text-icons-primary-intense);
  }

  &__button {
    all: initial;
    display: flex;
    color: var(--button-color);

    &:enabled {
      cursor: pointer;
    }

    &:focus-visible {
      outline: var(--onyx-outline-width) solid var(--outline-color);
      border-radius: var(--onyx-radius-sm);
      --button-color: var(--button-focus-color, var(--onyx-color-text-icons-primary-intense));
    }
  }

  @include success(#{$base-selector}__native) {
    --message-display: none;
    --border-color: var(--onyx-color-component-border-success);
    --outline-color: var(--onyx-color-component-focus-success);
    --selection-color: var(--onyx-color-base-success-200);
    --caret-color: var(--onyx-color-base-neutral-900);
    --focus-border-color: var(--onyx-color-component-border-success);
    --hover-border-color: var(--onyx-color-component-border-success-hover);
    --button-hover-color: var(--onyx-color-text-icons-success-medium);
    --button-focus-color: var(--onyx-color-text-icons-success-intense);
  }

  @include invalid(#{$base-selector}__native) {
    --error-message-display: inline-flex;
    --message-display: none;
    --success-message-display: none;
    --border-color: var(--onyx-color-component-border-danger);
    --outline-color: var(--onyx-color-component-focus-danger);
    --selection-color: var(--onyx-color-base-danger-200);
    --caret-color: var(--onyx-color-base-neutral-900);
    --focus-border-color: var(--onyx-color-component-border-danger);
    --hover-border-color: var(--onyx-color-component-border-danger-hover);
    --button-hover-color: var(--onyx-color-text-icons-danger-medium);
    --button-focus-color: var(--onyx-color-text-icons-danger-intense);
  }

  &__native {
    // reset native input styles so they are inherited from the parent
    border: none;
    border-radius: inherit;
    background-color: transparent;
    color: inherit;
    width: 100%;
    outline: none;
    font-family: inherit;
    font-size: inherit;
    line-height: inherit;
    padding: 0;
    height: 100%;
    caret-color: var(--caret-color);

    &::placeholder {
      color: var(--onyx-color-text-icons-neutral-soft);
      font-weight: var(--onyx-font-weight-regular);
      opacity: 1;
    }

    &::selection {
      background: var(--selection-color);
    }

    #{get-autofill-selectors("&")} {
      background-color: transparent;
      -webkit-text-fill-color: var(--onyx-color-text-icons-neutral-intense);

      // many browsers use "!important" to set the autofill background so we need this
      // transition workaround to make the background transparent
      transition: background-color calc(infinity * 1s);
    }
  }

  &:has(&__native:disabled) {
    .onyx-form-element__label {
      color: var(--onyx-color-text-icons-neutral-soft);
    }

    #{$base-selector} {
      &__wrapper {
        color: var(--onyx-color-text-icons-neutral-soft);
      }
    }
  }
}

@mixin define-skeleton-styles($height) {
  $adjustment: var(--skeleton-label-density-adjustment, 0rem);

  display: flex;
  flex-direction: column;
  gap: calc(var(--onyx-density-3xs) + $adjustment);
  line-height: var(--onyx-font-line-height-md);

  &__label {
    width: var(--onyx-density-3xl);
    height: calc(1.25rem - $adjustment);
  }

  &__input {
    width: 17rem;
    max-width: 100%;
    height: $height;
  }

  @include density.compact {
    // the skeleton gap would be 0 in compact density so we shrink the label size a bit and increase the gap so it does not look off
    --skeleton-label-density-adjustment: var(--onyx-spacing-5xs);
  }
}

/**
* Gets a comma separated CSS selector for the input autofill.
* Includes default browser selectors as well as some specific selectors e.g. for certain password managers.
*/
@function get-autofill-selectors($prefix: "") {
  $output: "";
  $selectors: (":autofill", "[data-test-autofill]", "[data-com-onepassword-filled]");

  @each $selector in $selectors {
    $prefixed-selector: $prefix + $selector;

    @if $output == "" {
      $output: $prefixed-selector;
    } @else {
      $output: $output + ", " + $prefixed-selector;
    }
  }

  @return $output;
}
