@use 'variables';
@use 'vendor-prefixes';
@use 'private';
@use 'a11y';

// The Input element proper.
.mat-input-element {
  // Font needs to be inherited, because by default <input> has a system font.
  font: inherit;

  // The Material input should match whatever background it is above.
  background: transparent;

  // If background matches current background then so should the color for proper contrast
  color: currentColor;

  // By default, <input> has a padding, border, outline and a default width.
  border: none;
  outline: none;
  padding: 0;
  margin: 0;
  width: 100%;

  // Prevent textareas from being resized outside the form field.
  max-width: 100%;

  // Needed to make last line of the textarea line up with the baseline.
  vertical-align: bottom;

  // User agent stylesheets set the text-align of inputs explicitly to "start". Those can be
  // easily overwritten by targeting the input element using a simple CSS selector, but since
  // the text-align will be applied most of the time on the `mat-form-field` to also align the
  // placeholder, the alignment should be inherited here.
  text-align: inherit;

  // It's common for developers to set `box-sizing: border-box` on every element on the page.
  // Reset it to `content-box` since all of our styles are written with it in mind. `border-box`
  // can also cause unnecessary scrollbars on auto-resizing textareas (see #21560).
  box-sizing: content-box;

  // Undo the red box-shadow glow added by Firefox on invalid inputs.
  // See https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-ui-invalid
  &:-moz-ui-invalid {
    box-shadow: none;
  }

  // Remove IE's default clear and reveal icons.
  &::-ms-clear,
  &::-ms-reveal {
    display: none;
  }

  // Clear Safari's decorations for search fields.
  &,
  &::-webkit-search-cancel-button,
  &::-webkit-search-decoration,
  &::-webkit-search-results-button,
  &::-webkit-search-results-decoration {
    -webkit-appearance: none;
  }

  // Also clear Safari's autofill icons. Note that this can't be in the
  // same selector as the IE ones, otherwise Safari will ignore it.
  &::-webkit-contacts-auto-fill-button,
  &::-webkit-caps-lock-indicator,
  &::-webkit-credentials-auto-fill-button {
    visibility: hidden;
  }

  &[type='date'],
  &[type='datetime'],
  &[type='datetime-local'],
  &[type='month'],
  &[type='week'],
  &[type='time'] {
    // Due to the native input masking these inputs can be slightly taller than
    // the plain text inputs. We normalize it by resetting the line height.
    line-height: 1;

    // Fixes an issue on iOS where the following input types will collapse to 1px,
    // if they're empty, because we've overridden their background color.
    // See: https://stackoverflow.com/questions/18381594/input-type-date-appearance-in-safari-on-ios
    &::after {
      content: ' ';
      white-space: pre;
      width: 1px;
    }
  }

  // Reduce the size of the native buttons in a date/time input,
  // because they can increase the height of the input (see #13317).
  &::-webkit-inner-spin-button,
  &::-webkit-calendar-picker-indicator,
  &::-webkit-clear-button {
    font-size: 0.75em;
  }

  @include vendor-prefixes.input-placeholder {
    // Prevent users from being able to select the placeholder text. Most of the time this can't
    // happen, however it's possible to do it when clicking on a disabled input (see #13479).
    @include vendor-prefixes.user-select(none);

    &:-ms-input-placeholder {
      // fix IE11 not able to focus programmatically with css style -ms-user-select: none
      // see https://github.com/angular/components/issues/15093
      -ms-user-select: text;
    }

    // Delay the transition until the label has animated about a third of the way through, in
    // order to prevent the placeholder from overlapping for a split second.
    transition: color variables.$swift-ease-out-duration
      private.private-div(variables.$swift-ease-out-duration, 3)
      variables.$swift-ease-out-timing-function;
  }

  .mat-form-field-hide-placeholder & {
    // Note that we can't use something like visibility: hidden or
    // display: none, because IE ends up preventing the user from
    // focusing the input altogether.
    @include vendor-prefixes.input-placeholder {
      // Needs to be !important, because the placeholder will end up inheriting the
      // input color in IE, if the consumer overrides it with a higher specificity.
      color: transparent !important;

      // Overwrite browser specific CSS properties that can overwrite the `color` property.
      // Some developers seem to use this approach to easily overwrite the placeholder and
      // label color. See: https://github.com/angular/components/issues/12074
      -webkit-text-fill-color: transparent;

      // Remove the transition to prevent the placeholder
      // from overlapping when the label comes back down.
      transition: none;

      @include a11y.high-contrast(active, off) {
        // In high contrast mode the browser will render the
        // placeholder despite the `color: transparent` above.
        opacity: 0;
      }
    }
  }
}

// Prevents IE from always adding a scrollbar by default.
textarea.mat-input-element {
  // Only allow resizing along the Y axis.
  resize: vertical;
  overflow: auto;

  &.cdk-textarea-autosize {
    resize: none;
  }
}

textarea.mat-input-element {
  // The 2px padding prevents scrollbars from appearing on Chrome even when they aren't needed.
  // We also add a negative margin to negate the effect of the padding on the layout.
  padding: 2px 0;
  margin: -2px 0;
  resize: none;
}

// Remove the native select down arrow and replace it with material design arrow
select.mat-input-element {
  -moz-appearance: none;
  -webkit-appearance: none;
  position: relative;
  background-color: transparent;
  display: inline-flex;
  box-sizing: border-box;
  padding-top: 1em;
  top: -1em;
  margin-bottom: -1em;

  &::-ms-expand {
    display: none;
  }

  // The `outline: none` from `.mat-input-element` works on all browsers, however Firefox also
  // adds a special `focus-inner` which we have to disable explicitly. See:
  // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#Firefox
  &::-moz-focus-inner {
    border: 0;
  }

  &:not(:disabled) {
    cursor: pointer;
  }

  // As a part of its user agent styling, IE11 has a blue box inside each focused
  // `select` element which we have to reset. Note that this needs to be in its own
  // selector, because having it together with another one will cause other browsers
  // to ignore it.
  &::-ms-value {
    // We need to reset the `color` as well, because IE sets it to white.
    color: inherit;
    background: none;

    // IE and Edge in high contrast mode reset the color for a focused select to the same color
    // as the background, however this causes it blend in because we've reset the `background`
    // above. We have to add a more specific selector in order to ensure that it gets the
    // `color` from our theme instead.
    @include a11y.high-contrast(active, off) {
      .mat-focused & {
        color: inherit;
      }
    }
  }
}

.mat-form-field-type-mat-native-select {
  $arrow-size: 5px;

  .mat-form-field-infix::after {
    content: '';
    width: 0;
    height: 0;
    border-left: $arrow-size solid transparent;
    border-right: $arrow-size solid transparent;
    border-top: $arrow-size solid;
    position: absolute;
    top: 50%;
    right: 0;
    margin-top: private.private-div(-$arrow-size, 2);

    // Make the arrow non-clickable so the user can click on the form control under it.
    pointer-events: none;

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

  .mat-input-element {
    // The arrow is 2 * $arrow-size wide and we add one more width for some spacing.
    $padding: $arrow-size * 3;
    padding-right: $padding;

    [dir='rtl'] & {
      padding-right: 0;
      padding-left: $padding;
    }
  }

  // Ensure that long labels don't collide with the select arrow.
  .mat-form-field-label-wrapper {
    max-width: calc(100% - #{$arrow-size * 2});
  }

  &.mat-form-field-appearance-outline .mat-form-field-infix::after {
    margin-top: -$arrow-size;
  }

  &.mat-form-field-appearance-fill .mat-form-field-infix::after {
    margin-top: -$arrow-size * 2;
  }
}
