@use '@material/textfield' as mdc-textfield;
@use '../core/tokens/m2/mat/form-field' as tokens-mat-form-field;
@use '../core/tokens/token-utils';

// Mixin that includes the density styles for form fields. MDC provides their own density
// styles for MDC text-field which we cannot use. MDC relies on input elements to stretch
// vertically when the height is reduced as per density scale. This doesn't work for our
// form field since we support custom form field controls without a fixed height. Instead, we
// provide spacing that makes arbitrary controls align as specified in the Material Design
// specification. In order to support density, we need to adjust the vertical spacing to be
// based on the density scale.
@mixin private-text-field-density-overrides() {
  @include token-utils.use-tokens(
    tokens-mat-form-field.$prefix, tokens-mat-form-field.get-token-slots()) {
    $height: token-utils.get-token-variable(container-height);

    .mat-mdc-form-field-infix {
      // We add a minimum height to the infix container to ensure that custom controls have the
      // same default vertical space as text-field inputs (with respect to the vertical padding).
      min-height: var(#{$height});

      @include token-utils.create-token-slot(padding-top,
        filled-with-label-container-padding-top);
      @include token-utils.create-token-slot(padding-bottom,
        filled-with-label-container-padding-bottom);

      .mdc-text-field--outlined &,
      .mdc-text-field--no-label & {
        @include token-utils.create-token-slot(padding-top, container-vertical-padding);
        @include token-utils.create-token-slot(padding-bottom, container-vertical-padding);
      }
    }

    // By default, MDC aligns the label using percentage. This will be overwritten based
    // on whether a textarea is used. This is not possible in our implementation of the
    // form-field because we do not know what type of form-field control is set up. Hence
    // we always use a fixed position for the label. This does not have any implications.
    .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .mat-mdc-floating-label {
      top: calc(var(#{$height}) / 2);
    }

    // We need to conditionally hide the floating label based on the height of the form field.
    .mdc-text-field--filled .mat-mdc-floating-label {
      display: var(#{token-utils.get-token-variable(filled-label-display)}, block);
    }

    // For the outline appearance, we re-create the active floating label transform. This is
    // necessary because the transform for docked floating labels can be updated to account for
    // the width of prefix container.
    .mat-mdc-text-field-wrapper.mdc-text-field--outlined .mdc-notched-outline--upgraded
    .mdc-floating-label--float-above {
      // Needs to be in a string form to work around an internal check that incorrectly flags this
      // interpolation in `calc` as unnecessary. If we don't have it, Sass won't evaluate it.
      $translate: 'calc(#{mdc-textfield.get-outlined-label-position-y(var(#{$height}))} * -1)';
      --mat-mdc-form-field-label-transform: translateY(#{$translate})
        scale(var(--mat-mdc-form-field-floating-label-scale, 0.75));
      transform: var(--mat-mdc-form-field-label-transform);
    }
  }
}
