@use "../../core/settings" as *;
@use "../../core/tools" as *;
@use "../../core/helpers" as *;
@forward "../../core/objects/input-wrapper";
@forward "../error-message";
@forward "../hint";
@forward "../label";

////
/// Input component
///
/// @group components/input
////

@include nhsuk-exports("nhsuk/components/input") {
  .nhsuk-input {
    box-sizing: border-box;

    width: 100%;
    height: nhsuk-px-to-rem(40px);
    margin-top: 0;
    padding: nhsuk-px-to-rem(nhsuk-spacing(1));
    // Setting any background-color makes text invisible when changing colours
    // to dark backgrounds in Firefox (https://bugzil.la/1335476). As
    // background-color and color need to always be set together, color should
    // not be set either
    border: $nhsuk-border-width-form-element solid $nhsuk-input-border-colour;
    border-radius: 0;

    // Disable inner shadow and remove rounded corners
    appearance: none;

    @include nhsuk-font($size: 19);

    // Increase left padding with prefix
    .nhsuk-input-wrapper:has(.nhsuk-input-wrapper__prefix) & {
      padding-left: nhsuk-px-to-rem(nhsuk-spacing(1) + $nhsuk-border-width-form-element);
    }

    // Increase right padding with suffix
    .nhsuk-input-wrapper:has(.nhsuk-input-wrapper__suffix) &:not([type="search"]) {
      padding-right: nhsuk-px-to-rem(nhsuk-spacing(1) + $nhsuk-border-width-form-element);
    }

    &:focus {
      @include nhsuk-focused-input;
    }

    &:disabled {
      opacity: 0.5;
      color: inherit;
      background-color: transparent;
      cursor: not-allowed;
    }

    &::placeholder {
      opacity: 1; // Fixes low contrast of placeholder text in firefox
      color: nhsuk-colour("grey-1");
    }

    // Hide input clear button (IE)
    &::-ms-clear {
      display: none;
    }
  }

  // Reset custom appearance
  .nhsuk-input[type="number"],
  .nhsuk-input[type="search"] {
    appearance: textfield;
  }

  // Hide input icons and buttons (Webkit, Blink)
  .nhsuk-input[type="number"]::-webkit-inner-spin-button,
  .nhsuk-input[type="number"]::-webkit-outer-spin-button,
  .nhsuk-input[type="search"]::-webkit-search-decoration,
  .nhsuk-input[type="search"]::-webkit-search-results-button,
  .nhsuk-input[type="search"]::-webkit-search-results-decoration {
    display: none;
  }

  // Only hide cancel button when placeholder would be shown
  .nhsuk-input[type="search"]:placeholder-shown::-webkit-search-cancel-button {
    display: none;
  }

  // Note: This is a non-standard CSS feature and will not do anything in Firefox
  // https://bugzilla.mozilla.org/show_bug.cgi?id=1417753
  .nhsuk-input[type="search"]::-webkit-search-cancel-button {
    align-self: center;

    width: nhsuk-px-to-rem($nhsuk-icon-size);
    height: nhsuk-px-to-rem($nhsuk-icon-size);
    margin: 0;

    pointer-events: auto;

    opacity: 1;

    background: nhsuk-image-url("nhsuk-icon-cross.svg") no-repeat;
    background-size: nhsuk-px-to-rem($nhsuk-icon-size) nhsuk-px-to-rem($nhsuk-icon-size);

    cursor: pointer;

    appearance: none;

    // Where possible use the cross as a mask instead. This lets us use
    // currentcolor, increasing the contrast of the image and matching the
    // user's prefered foreground colour in e.g. forced colors mode.
    // We test for `mask-position` rather than `mask-image` because of a false
    // positive in Edge 17.
    @supports (mask-position: initial) {
      background: currentcolor;
      mask: nhsuk-image-url("nhsuk-icon-cross.svg") no-repeat;
      mask-size: nhsuk-px-to-rem($nhsuk-icon-size) nhsuk-px-to-rem($nhsuk-icon-size);

      // currentcolor doesn't seem to be computed correctly in forced colors
      // mode so force the background color to match the system link color
      // (matching the text in the link)
      @media screen and (forced-colors: active), (-ms-high-contrast: active) {
        background: ButtonText;
      }
    }
  }

  .nhsuk-input--error {
    border-color: $nhsuk-error-colour;
  }

  // Large inputs

  .nhsuk-input--large {
    height: nhsuk-px-to-rem(48px);
    padding-right: nhsuk-px-to-rem(nhsuk-spacing(2));
    padding-left: nhsuk-px-to-rem(nhsuk-spacing(2));
    @include nhsuk-font($size: 22);

    // Increase left padding with prefix
    .nhsuk-input-wrapper:has(.nhsuk-input-wrapper__prefix) & {
      padding-left: nhsuk-px-to-rem(nhsuk-spacing(2) + $nhsuk-border-width-form-element);
    }

    // Increase right padding with suffix
    .nhsuk-input-wrapper:has(.nhsuk-input-wrapper__suffix) &:not([type="search"]) {
      padding-right: nhsuk-px-to-rem(nhsuk-spacing(2) + $nhsuk-border-width-form-element);
    }

    @include nhsuk-media-query($from: tablet) {
      height: nhsuk-px-to-rem(60px);
    }
  }

  .nhsuk-input--large[type="search"]::-webkit-search-cancel-button {
    width: nhsuk-px-to-rem($nhsuk-icon-size-large);
    height: nhsuk-px-to-rem($nhsuk-icon-size-large);
    background-size: nhsuk-px-to-rem($nhsuk-icon-size-large) nhsuk-px-to-rem($nhsuk-icon-size-large);

    @supports (mask-position: initial) {
      mask-size: nhsuk-px-to-rem($nhsuk-icon-size-large) nhsuk-px-to-rem($nhsuk-icon-size-large);
    }
  }

  // Codes and sequences

  .nhsuk-input--code {
    @include nhsuk-font-code;
    font-size-adjust: none;
    word-spacing: 0;
  }

  // The ex measurements are based on the number of W's that can fit inside the input
  // Extra space is left on the right hand side to allow for the Safari prefill icon
  // Linear regression estimation based on visual tests: y = 1.76 + 1.81x

  .nhsuk-input--width-30 {
    max-width: 56ex + 3ex;
  }

  .nhsuk-input--width-20 {
    max-width: 38ex + 3ex;
  }

  .nhsuk-input--width-10 {
    max-width: 20ex + 3ex;
  }

  .nhsuk-input--width-5 {
    max-width: 10.8ex;
  }

  .nhsuk-input--width-4 {
    max-width: 9ex;
  }

  .nhsuk-input--width-3 {
    max-width: 7.2ex;
  }

  .nhsuk-input--width-2 {
    max-width: 5.4ex;
  }

  .nhsuk-input-wrapper__prefix,
  .nhsuk-input-wrapper__suffix,
  // Deprecated, to be removed in v11.0
  .nhsuk-input__prefix,
  .nhsuk-input__suffix {
    box-sizing: border-box;

    // Use flexbox to align text within the prefix and suffix
    display: flex;

    flex: 0 0 auto;
    align-items: center;
    justify-content: center;

    min-width: nhsuk-px-to-rem(40px);
    height: nhsuk-px-to-rem(40px);
    padding: nhsuk-px-to-rem(nhsuk-spacing(1)) nhsuk-px-to-rem(nhsuk-spacing(2));

    border: $nhsuk-border-width-form-element solid $nhsuk-input-border-colour;

    background-color: nhsuk-colour("grey-4");

    text-align: center;
    white-space: nowrap;
    // Emphasise non-editable status of prefixes and suffixes
    cursor: default;

    @include nhsuk-font($size: 19);

    // Split prefix/suffix onto separate lines on narrow screens
    @include nhsuk-media-query($until: mobile) {
      display: block;
      height: 100%;
      white-space: normal;
    }
  }

  .nhsuk-input-wrapper--large .nhsuk-input-wrapper__prefix,
  .nhsuk-input-wrapper--large .nhsuk-input-wrapper__suffix {
    @include nhsuk-media-query($from: mobile) {
      height: nhsuk-px-to-rem(52px);
      padding-right: nhsuk-px-to-rem(nhsuk-spacing(3));
      padding-left: nhsuk-px-to-rem(nhsuk-spacing(3));
      @include nhsuk-font($size: 22);
    }

    @include nhsuk-media-query($from: tablet) {
      height: nhsuk-px-to-rem(56px + $nhsuk-button-shadow-size);
    }
  }

  .nhsuk-input-wrapper__prefix,
  // Deprecated, to be removed in v11.0
  .nhsuk-input__prefix {
    @include nhsuk-media-query($until: mobile) {
      border-bottom-width: 0;

      // Remove top margin when preceded by a prefix
      + .nhsuk-input {
        margin-top: 0;
      }
    }

    @include nhsuk-media-query($from: mobile) {
      margin-left: nhsuk-spacing(2);
      border-right-width: 0;

      &:first-child {
        margin-left: 0;
      }

      // Remove left margin when preceded by a prefix
      + .nhsuk-input {
        margin-left: 0;
      }
    }
  }

  // Split prefix/suffix onto separate lines on narrow screens
  .nhsuk-input-wrapper__suffix,
  // Deprecated, to be removed in v11.0
  .nhsuk-input__suffix {
    @include nhsuk-media-query($until: mobile) {
      border-top-width: 0;
    }

    @include nhsuk-media-query($from: mobile) {
      border-left-width: 0;
    }
  }
}
