@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);
    -webkit-text-fill-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);
    }

    &.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 {
        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:not(.nx-formfield--negative):not(.has-error) .nx-formfield__input-container {
        border-bottom-color: highlight;
    }

    .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);
    }
}
