@use '../core/style/layout-common';
@use './m3-list';
@use '../core/tokens/token-utils';
@use './list-item-hcm-indicator';
@use './list-inherited-structure';

$fallbacks: m3-list.get-tokens();

@include list-inherited-structure.private-list-inherited-structural-styles;

// Add additional slots for the MDC list tokens, needed in Angular Material.
// MDC allows focus and hover colors to take precedence over disabled color. We add the disabled
// color here with higher specificity so that the disabled color takes precedence.
// TODO(mmalerba): Dicuss with MDC whether to change this in their code.
.mdc-list-item.mdc-list-item--disabled .mdc-list-item__primary-text {
  color: token-utils.slot(list-list-item-disabled-label-text-color, $fallbacks);
}

// We don't use MDC's state layer since it's tied in with their ripple. Instead we emit slots
// for our own state layer.
// TODO(mmalerba): Consider using MDC's ripple & state layer.
.mdc-list-item:hover::before {
  background-color: token-utils.slot(list-list-item-hover-state-layer-color, $fallbacks);
  opacity: token-utils.slot(list-list-item-hover-state-layer-opacity, $fallbacks);
}
.mdc-list-item.mdc-list-item--disabled::before {
  background-color: token-utils.slot(list-list-item-disabled-state-layer-color, $fallbacks);
  opacity: token-utils.slot(list-list-item-disabled-state-layer-opacity, $fallbacks);
}
.mdc-list-item:focus::before {
  background-color: token-utils.slot(list-list-item-focus-state-layer-color, $fallbacks);
  opacity: token-utils.slot(list-list-item-focus-state-layer-opacity, $fallbacks);
}

// Apply the disabled opacity to the checkbox/radio indicators.
// TODO(mmalerba): We should probably stop doing this and allow the checkbox/radio to decide
//  what their disabled state looks like. This is done for now to avoid screenshot diffs.
.mdc-list-item--disabled {
  .mdc-radio,
  .mdc-checkbox {
    opacity: token-utils.slot(list-list-item-disabled-label-text-opacity, $fallbacks);
  }
}

// In Angular Material we put the avatar class directly on the .mdc-list-item__start element,
// rather than nested inside it, so we need to emit avatar slots ourselves.
// TODO(mmalerba): We should try to change MDC's recommended DOM or change ours to match their
//  recommendation.
.mdc-list-item--with-leading-avatar .mat-mdc-list-item-avatar {
  border-radius: token-utils.slot(list-list-item-leading-avatar-shape, $fallbacks);
  background-color: token-utils.slot(list-list-item-leading-avatar-color, $fallbacks);
}

// Set font-size of leading icon to same value as its width and height. Ensure icon scales to
// "list-item-leading-icon-size" token. In Angular Material, the icon is on the same element as
// ".mdc-list-item__start", rather than a child of ".mdc-list-item__start".
.mat-mdc-list-item-icon {
  font-size: token-utils.slot(list-list-item-leading-icon-size, $fallbacks);
}

a.mdc-list-item--activated {
  // Improve accessibility for Window High Contrast Mode (HCM) by adding an idicator on active
  // links.
  @include list-item-hcm-indicator.private-high-contrast-list-item-indicator();
}

// MDC expects the list element to be a `<ul>`, since we use `<mat-list>` instead we need to
// explicitly set `display: block`
.mat-mdc-list-base {
  display: block;

  // MDC sets `pointer-events: none` on these elements,
  // even though we allowed interactive content in them.
  .mdc-list-item__start,
  .mdc-list-item__end,
  .mdc-list-item__content {
    pointer-events: auto;
  }
}

.mat-mdc-list-item,
.mat-mdc-list-option {
  // MDC expects that the list items are always `<li>`, since we actually use `<button>` in some
  // cases, we need to make sure it expands to fill the available width.
  width: 100%;
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;

  &:not(.mat-mdc-list-item-interactive) {
    cursor: default;
  }

  // MDC doesn't have list dividers, so we use mat-divider and style appropriately.
  // TODO(devversion): check if we can use the MDC dividers.
  .mat-divider-inset {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
  }

  .mat-mdc-list-item-avatar ~ .mat-divider-inset {
    margin-left: 72px;

    [dir='rtl'] & {
      margin-right: 72px;
    }
  }
}

// MDC's hover and focus state styles are included with their ripple which we don't use.
// Instead we add the focus, hover and selected styles ourselves using this pseudo-element
.mat-mdc-list-item-interactive::before {
  @include layout-common.fill();
  content: '';
  opacity: 0;
  pointer-events: none;

  // This comes up in some internal implementations.
  border-radius: inherit;
}

// The MDC-based list items already use the `::before` pseudo element for the standard
// focus/selected/hover state. Hence, we need to have a separate list-item spanning
// element that can be used for strong focus indicators.
.mat-mdc-list-item {
  > .mat-focus-indicator {
    @include layout-common.fill();
    pointer-events: none;
  }

  // For list items, render the focus indicator when the parent
  // listem item is focused.
  &:focus > .mat-focus-indicator::before {
    content: '';
  }
}

.mat-mdc-list-item.mdc-list-item--with-three-lines {
  .mat-mdc-list-item-line.mdc-list-item__secondary-text {
    white-space: nowrap;
    line-height: normal;
  }

  // Unscoped content can wrap if the list item has acquired three lines. MDC implements
  // this functionality for secondary text but there is no proper text ellipsis when
  // text overflows the third line. These styles ensure the overflow is handled properly.
  // TODO: Move this to the MDC list once it drops IE11 support.
  .mat-mdc-list-item-unscoped-content.mdc-list-item__secondary-text {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
  }
}

// MDC doesn't account for button being used as a list item. We override some of
// the default button styles here so that they look right when used as a list
// item.
mat-action-list button {
  background: none;
  color: inherit;
  border: none;
  font: inherit;
  outline: inherit;
  -webkit-tap-highlight-color: transparent;
  text-align: start;

  &::-moz-focus-inner {
    border: 0;
  }
}

.mdc-list-item--with-leading-icon .mdc-list-item__start {
  margin-inline-start: token-utils.slot(list-list-item-leading-icon-start-space, $fallbacks);
  margin-inline-end: token-utils.slot(list-list-item-leading-icon-end-space, $fallbacks);
}

.mat-mdc-nav-list .mat-mdc-list-item {
  border-radius: token-utils.slot(list-active-indicator-shape, $fallbacks);
  --mat-focus-indicator-border-radius: #{token-utils.slot(list-active-indicator-shape, $fallbacks)};

  &.mdc-list-item--activated {
    background-color: token-utils.slot(list-active-indicator-color, $fallbacks);
  }
}
