@import '../shared-styles/index';

$formfield-margin-bottom: nx-spacer(m);
$margin-to-message: nx-spacer(3xs);

.nx-formfield {
  display: block;
  //default theme is white and gets overwritten depending of the focus, error state or given modifiers
  color: v(formfield-input-color);

  nx-message {
    margin-top: nx-spacer(xs);
  }

  &:has(nx-password-toggle) {
    input::-ms-reveal {
      display: none;
    }
  }
}

.nx-formfield__wrapper {
  padding-bottom: v(formfield-bottom-padding);
  padding-top: v(formfield-label-height);

  @include media-breakpoint-response(mobile) {
    padding-bottom: v(formfield-mobile-bottom-padding);
  }
}

.nx-formfield__row {
  min-height: v(formfield-control-height);
  background-color: v(formfield-background-color);
  display: flex;
  align-items: stretch;
  width: 100%;

  // IE hack: IE has problems with align-items: stretch
  // and min-heights, but this trick does it nicely.
  // I tried it first to have it on the flexfield, but for some reason
  // the after element doesn't respect the border-box and adds up the borders
  // resulting in wrong heights. Using the __row container now for the min-height
  // of the inner element works fine :)
  &:after {
    content: '';
    font-size: 0;
    display: block;
    min-height: inherit;
  }
}

// Flex Layout of prefix, input, postfix
.nx-formfield__flexfield {
  @include type-style(formfield-control);
  align-items: stretch;
  flex-direction: column;
  display: inline-flex;
  width: 100%;
  position: relative;
  min-width: 0;
  flex: 0 1 auto;
}

.nx-formfield__input-container {
  display: flex;
  border-bottom: v(formfield-border-width) solid v(formfield-border-color);
  height: v(formfield-control-height);
  flex: auto;
  padding: v(formfield-input-padding);
}

.nx-formfield__input {
  position: relative;
  flex: auto;
  min-width: 0;
  display: flex;
  text-align: left;

  [dir='rtl'] & {
    text-align: right;
  }
}

.nx-formfield__label-holder {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;

  [dir='rtl'] & {
    right: 0;
    left: auto;
  }
}

.nx-formfield__label {
  @include type-style(formfield-placeholder-label);
  color: v(formfield-label-color);
  display: block;
  position: absolute;
  left: 0;
  pointer-events: none;
  width: 100%;
  white-space: nowrap;
  text-overflow: ellipsis;
  overflow: hidden;
  transform-origin: 0 0;

  text-size-adjust: 100%;
  text-align: left;

  [dir='rtl'] & {
    right: 0;
    left: auto;
    text-align: right;
  }

  .optional {
    font-weight: nx-font-weight(regular);
    &::after {
      content: ':';
      margin-right: 4px;
    }
  }
}

.nx-formfield__appendix,
.nx-formfield__prefix,
.nx-formfield__suffix {
  align-items: center;
  flex: none;
  white-space: nowrap;
  color: v(formfield-control-color);

  // ensure auto sized icons get 24px and don't inherit 20px from the base font size of this component
  nx-icon.nx-icon--auto {
    font-size: v(formfield-icon-size);
  }

  nx-icon {
    display: block;
  }
}

.nx-formfield__prefix,
.nx-formfield__suffix {
  display: inline-flex;
}

.nx-formfield__appendix {
  height: v(formfield-control-height);
  margin-left: nx-spacer(2xs);
  display: flex;
  border-bottom-style: solid;
  border-bottom-color: transparent;
  border-bottom-width: v(formfield-border-width);
  padding: v(formfield-input-padding);

  [dir='rtl'] & {
    margin-right: nx-spacer(2xs);
    margin-left: initial;
  }
}

.nx-formfield__prefix {
  margin-right: nx-spacer(2xs);

  [dir='rtl'] & {
    margin-right: initial;
    margin-left: nx-spacer(2xs);
  }
}

.nx-formfield__suffix {
  margin-left: nx-spacer(2xs);

  [dir='rtl'] & {
    margin-right: nx-spacer(2xs);
    margin-left: initial;
  }
}

// Hints
.nx-formfield__hints {
  color: v(formfield-hint-color);
  @include type-style(formfield-hint);
  padding-top: v(formfield-hint-spacing);
  text-align: right;

  [dir='rtl'] & {
    text-align: left;
  }
}

.nx-formfield-hint {
  display: block;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}

// Messages
.nx-formfield__message {
  margin-top: v(formfield-message-gap);
}

// States
.nx-formfield.is-focused {
  .nx-formfield__label {
    text-overflow: ellipsis;
  }
}

.nx-formfield.is-focused:not(.nx-formfield--negative):not(.has-error) {
  color: v(formfield-active-color);

  // overwrite with white to maintain contrast
  &.nx-formfield--negative {
    color: v(negative);
  }
}

.nx-formfield.is-focused:not(.has-outline) {
  .nx-formfield__input-container {
    border-bottom-color: v(formfield-active-border-bottom-color);
    position: relative;

    &:after {
      content: '';
      position: absolute;
      left: 0;
      bottom: calc(v(formfield-active-border-width) * -1 + v(formfield-border-width));
      border-radius: v(formfield-active-border-radius);
      height: v(formfield-active-border-width);
      background-color: v(formfield-active-border-color);
      width: 100%;
    }
  }

  &.nx-formfield--negative {
    .nx-formfield__input-container {
      &:after {
        background-color: v(negative);
      }
    }
  }

  &.has-error {
    .nx-formfield__input-container {
      &:after {
        background-color: v(danger);
      }
    }
  }
}

// direct needs a hover color for border-bottom line
.nx-formfield:not(.nx-formfield--negative):not(.has-error):not(.is-disabled):not(.is-focused):not(
    .has-outline
  ):not(.is-readonly) {
  .nx-formfield__row:hover .nx-formfield__input-container {
    border-bottom-color: v(formfield-hover-border-color);
  }
}

// focus style for outline formfield
.nx-formfield.is-focused:not(.nx-formfield--negative).has-outline {
  .nx-formfield__input-container {
    border-color: v(formfield-outline-active-border-color);
    @include formfield-outline-focus-styles;
  }

  &.has-error {
    .nx-formfield__input-container {
      border-bottom-color: v(danger);
    }
  }
}

.nx-formfield.has-outline {
  @include type-style(formfield-outline-control);

  &.nx-formfield--type-textarea {
    .nx-formfield__input-container {
      height: auto;
    }
  }

  .nx-formfield__wrapper {
    padding-bottom: v(formfield-outline-bottom-padding);
    padding-top: v(formfield-outline-label-height);
  }

  .nx-formfield__row {
    min-height: v(formfield-outline-control-height);
  }

  .nx-formfield__flexfield {
    @include type-style(formfield-outline-control);
    padding: 0;
  }

  .nx-formfield__input-container {
    padding: v(formfield-outline-input-container-padding);
    border-width: v(formfield-border-width);
    border-color: v(formfield-outline-border-color);
    background-color: v(formfield-outline-background-color);
    border-style: solid;
    border-radius: v(formfield-outline-border-radius);
    height: v(formfield-outline-control-height);
    gap: v(formfield-outline-gap);
  }

  input,
  nx-dropdown .nx-dropdown__container,
  nx-multi-select .value {
    padding: 0 v(formfield-outline-spacing);
  }

  .nx-formfield__suffix {
    margin-right: v(formfield-outline-spacing);
    margin-left: 0;

    [dir='rtl'] & {
      margin-right: 0;
      margin-left: v(formfield-outline-spacing);
    }
  }

  .nx-formfield__prefix {
    margin-left: v(formfield-outline-spacing);
    margin-right: 0;

    [dir='rtl'] & {
      margin-right: v(formfield-outline-spacing);
      margin-left: 0;
    }
  }

  .nx-formfield__input textarea.nx-input {
    line-height: nx-line-height(2xs);
    padding: v(formfield-outline-spacing);
    min-height: v(formfield-outline-control-line-height);
  }

  .nx-formfield__appendix {
    height: v(formfield-outline-control-height);
    margin-left: nx-spacer(2xs);
    display: flex;
    border-top: v(formfield-border-width) solid transparent;
    border-bottom: v(formfield-border-width) solid transparent;
    padding: 0;

    [dir='rtl'] & {
      margin-left: initial;
      margin-right: nx-spacer(2xs);
    }
  }

  .nx-formfield__hints {
    text-align: left;
    @include type-style(formfield-outline-hint);
    padding: v(formfield-outline-hint-spacing);

    [dir='rtl'] & {
      text-align: right;
    }
  }

  input,
  textarea {
    @include input-placeholder {
      @include type-style(formfield-outline-input-native-placeholder);
      color: v(formfield-input-native-placeholder-color);
    }

    &::placeholder {
      opacity: 1;
    }
  }

  input {
    // to align the placeholder vertically inside the element on firefox the line height
    // needs to equal the element height.
    // the formfield-outline-control-height tokens are the outer element
    // so we need to take the border into account
    &::-moz-placeholder {
      line-height: calc(#{v(formfield-outline-control-height)} - 2 * #{v(formfield-border-width)});
    }
  }

  input:-webkit-autofill::first-line {
    @include type-style(formfield-outline-control);
  }
  .nx-formfield__label {
    flex-direction: row-reverse;
    display: flex;
    justify-content: flex-end;
  }
  .optional {
    margin-left: v(formfield-outline-optional-label-gap);
    @include type-style(formfield-outline-optional-label);
    font-weight: nx-font-weight(regular);

    &::before {
      content: '(';
    }

    &::after {
      content: ')';
    }
  }
}

.nx-formfield.has-outline.is-readonly:not(.is-disabled) {
  .nx-formfield__input-container {
    border-color: v(formfield-readonly-border-color);
    background-color: v(formfield-readonly-background-color);
  }
}

.nx-formfield:not(.has-outline).is-readonly:not(.is-disabled) {
  .nx-formfield__input-container {
    border-bottom-color: v(formfield-readonly-border-color);
  }
}

// Provide the floating behavior
.nx-formfield.is-floating {
  .nx-formfield__label {
    transform: translateY(v(formfield-floating-distance));
    @include type-style(formfield-label);
  }

  &.is-filled .nx-formfield__label {
    // Remove the transition when the input is filled
    transition: none;
  }
  .optional {
    font-weight: nx-font-weight(regular);
  }

  &.has-outline {
    .nx-formfield__label {
      padding-top: 0;
      transform: translateY(v(formfield-outline-floating-distance));
      @include type-style(formfield-outline-label);
    }

    .nx-formfield__prefix ~ .nx-formfield__input {
      .nx-formfield__label {
        padding: 0;
      }
    }

    .nx-formfield__input-container {
      position: relative;
    }

    .nx-formfield__input {
      position: unset;
    }
  }
}

// Prevent animation for always floating
.nx-formfield.is-auto-floating {
  .nx-formfield__label {
    transition:
      transform 0.15s ease-out,
      font-size 0.15s ease-out;
  }
}

// error styles (non-color changes)
.nx-formfield.has-error {
  &:not(.has-outline) {
    &:not(.is-floating) .nx-formfield__label {
      font-weight: v(formfield-error-input-font-weight);
    }

    .nx-formfield__prefix,
    .nx-formfield__suffix {
      font-weight: v(formfield-error-input-font-weight);
    }

    .nx-formfield__input input.nx-input {
      font-weight: v(formfield-error-input-font-weight);
    }
  }
}

// error styles (color changes)
.nx-formfield.has-error:not(.nx-formfield--negative) {
  color: v(danger);

  &:not(.has-outline) {
    .nx-formfield__prefix,
    .nx-formfield__suffix,
    .nx-formfield__label {
      color: v(danger);
    }
  }

  &:not(.is-focused) {
    .nx-formfield__input-container {
      border-bottom-color: v(danger);
    }
  }

  &.is-floating {
    .nx-formfield__label {
      color: v(formfield-label-color);
    }
  }

  &.has-outline {
    color: v(text-01);

    .nx-formfield__input-container {
      border-color: v(danger);
    }
  }
}

// Provide the disabled behavior
.nx-formfield.is-disabled {
  color: v(formfield-disabled-text-color);
  .nx-formfield__label {
    color: v(formfield-disabled-text-color);
  }
  cursor: not-allowed;

  .nx-formfield__hints {
    color: inherit;
  }

  .nx-formfield__input-container {
    border-bottom-color: v(formfield-disabled-border-color);
  }

  &.has-outline .nx-formfield__input-container {
    border-color: v(formfield-disabled-border-color);
    background-color: v(formfield-disabled-background-color);
  }

  &.has-outline {
    input,
    textarea {
      @include input-placeholder {
        color: v(formfield-input-native-placeholder-disabled-color);
      }
    }
  }

  nx-datepicker-toggle button {
    color: v(formfield-disabled-text-color);
  }
}

// Ellipsis for readonly and disabled
.nx-formfield.is-readonly,
.nx-formfield.is-disabled {
  input {
    text-overflow: ellipsis;
  }
}

.nx-formfield__tooltip {
  width: 100%;
  display: flex;
}

// Readonly color
.nx-formfield.is-readonly:not(.is-disabled) {
  nx-datepicker-toggle button {
    color: v(formfield-disabled-text-color);
  }
}

// Modifiers
.nx-formfield--negative {
  color: v(negative);

  .nx-formfield__hints {
    color: inherit;
  }

  // this has currently no effect on the outline elements, so the next block for .has-outline is needed
  .nx-formfield__input-container {
    border-color: v(negative);
  }

  &.has-outline .nx-formfield__input-container {
    border-color: v(negative);
  }

  .nx-formfield__appendix,
  .nx-formfield__prefix,
  .nx-formfield__suffix {
    color: v(negative);
  }

  .nx-formfield__label {
    color: v(negative);
  }
}

.nx-formfield--type-nx-dropdown,
.nx-formfield--type-nx-multi-select {
  .nx-formfield__label {
    width: calc(100% - #{v(formfield-icon-size)});
  }
}

.nx-formfield__input textarea.nx-input {
  vertical-align: bottom;
  min-height: v(formfield-control-line-height);
  resize: vertical;
}

// HIGH CONTRAST
@media screen and (forced-colors: active) {
  .nx-formfield__input-container,
  .nx-formfield.nx-formfield--negative .nx-formfield__input-container,
  // overwrite hover in chromium edge:
  .nx-formfield:not(.nx-formfield--negative):not(.has-error):not(.is-disabled):not(.is-focused):not(.has-outline)
      .nx-formfield__row:hover .nx-formfield__input-container,
  // overwrite error color
  .nx-formfield.has-error:not(.nx-formfield--negative) .nx-formfield__input-container,
  .nx-formfield.has-error:not(.nx-formfield--negative):not(.is-focused) .nx-formfield__input-container {
    border-bottom-color: buttonText;
  }

  .nx-formfield.has-outline {
    .nx-formfield__input-container {
      border-color: buttonText;
    }

    .nx-formfield__appendix {
      border-bottom-color: Canvas;
      border-top-color: Canvas;
    }
  }

  .nx-formfield.is-disabled {
    color: GrayText;
    -webkit-text-fill-color: GrayText;

    .nx-formfield__input-container {
      border-bottom-color: GrayText;
    }

    .nx-formfield__hints {
      color: CanvasText;
    }

    &.has-outline .nx-formfield__input-container {
      border-color: GrayText;
    }
  }

  .nx-formfield.is-focused:not(.has-outline) .nx-formfield__input-container,
  .nx-formfield.is-focused.has-error.nx-formfield.is-floating .nx-formfield__input-container,
  .nx-formfield.is-focused.nx-formfield--negative:not(.has-error) .nx-formfield__input-container {
    border-color: buttonText;
    &::after {
      background-color: buttonText;
    }
  }

  .nx-formfield:not(.nx-formfield--negative) {
    .nx-formfield__appendix nx-icon {
      color: inherit;
    }
  }
}

.nx-formfield--type-textarea {
  // the flexfield has left and right padding so that
  // controls don't have to be styled accordingly.
  // but the textarea should fill out the whole container and it will
  // bring its own padding so we need to reset it here
  .nx-formfield__flexfield {
    padding: 0;
  }

  .nx-formfield__input-container {
    height: auto;
  }
}

// overwrites default background color and font-size of autofilled input fields
input:-webkit-autofill {
  transition: background-color 5000s ease-in-out 0s;
  &::first-line {
    @include type-style(formfield-control);
    font-family: v(font-family);
    color: v(formfield-control-color);
  }
}
