File

src/app/shared/components/dropdown/dropdown.component.ts

Description

Component for a dropdown menu.

Metadata

Index

Properties
Methods
Inputs
Outputs

Constructor

constructor(ga: GoogleAnalyticsService)

Creates an instance of dropdown component.

Parameters :
Name Type Optional Description
ga GoogleAnalyticsService No

Analytics service

Inputs

label
Type : string

What the component is selecting for.

options
Type : string[]

Choices displayed in the dropdown menu.

selection
Type : string

Current option selected.

Outputs

selectionChange
Type : EventEmitter

Emits the new selected option when selection is changed.

Methods

selectionChanged
selectionChanged(value: string)

Updates the selected value.

Parameters :
Name Type Optional Description
value string No

The value that has been selected

Returns : void
toggleOptions
toggleOptions()

Controls fade-in effect after dropdown menu opens

Returns : void

Properties

optionsVisible
Type : string
Default value : 'invisible'

Determines if menu contents are visible (used for fade-in effect).

import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
import { GoogleAnalyticsService } from 'ngx-google-analytics';

/**
 * Component for a dropdown menu.
 */
@Component({
  selector: 'ccf-dropdown',
  templateUrl: './dropdown.component.html',
  styleUrls: ['./dropdown.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class DropdownComponent {
  /**
   * What the component is selecting for.
   */
  @Input() label!: string;

  /**
   * Choices displayed in the dropdown menu.
   */
  @Input() options!: string[];

  /**
   * Current option selected.
   */
  @Input() selection!: string;

  /**
   * Emits the new selected option when selection is changed.
   */
  @Output() readonly selectionChange = new EventEmitter<string>();

  /**
   * Determines if menu contents are visible (used for fade-in effect).
   */
  optionsVisible = 'invisible';

  /**
   * Creates an instance of dropdown component.
   *
   * @param ga Analytics service
   */
  constructor(private readonly ga: GoogleAnalyticsService) {}

  /**
   * Controls fade-in effect after dropdown menu opens
   */
  toggleOptions(): void {
    this.optionsVisible = this.optionsVisible === 'visible' ? 'invisible' : 'visible';
  }

  /**
   * Updates the selected value.
   *
   * @param value The value that has been selected
   */
  selectionChanged(value: string): void {
    this.selection = value;
    this.ga.event('selection_change', 'dropdown', `${this.label}:${value}`);
    this.selectionChange.emit(value);
  }
}
<div class="ccf-dropdown wrapper">
  <mat-form-field class="dropdown-form-field" subscriptSizing="dynamic">
    <div class="label">
      {{ label }}
    </div>
    <mat-select
      class="selected-value"
      [value]="selection"
      (selectionChange)="selectionChanged($event.value)"
      disableOptionCentering="true"
      panelClass="option-panel"
      (openedChange)="toggleOptions()"
      disableRipple="true"
      hideSingleSelectionIndicator="true"
    >
      <mat-option *ngFor="let option of options" [value]="option">
        <div class="{{ optionsVisible }}">
          {{ option }}
        </div>
      </mat-option>
    </mat-select>
  </mat-form-field>
</div>

./dropdown.component.scss

@keyframes slideInHorizontalDropdown {
  from {
    width: 0;
  }
  to {
    width: 9.85rem;
  }
}

@keyframes fadeIn {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

.dropdown-form-field {
  width: 100%;
  height: 3rem;

  ::ng-deep .mat-mdc-text-field-wrapper {
    padding-left: 0.25rem;
    padding-right: 0.25rem;

    .mat-mdc-form-field-flex {
      .mat-mdc-form-field-infix {
        font-size: 0.875rem;
        border: none;

        .label {
          height: 19.25px;
        }

        mat-select {
          font-size: 1rem;
          font-weight: bold;

          .mat-mdc-select-arrow-wrapper {
            position: relative;
            bottom: 0.25rem;
            right: 0.25rem;
          }
        }
      }
    }

    .mdc-line-ripple::before {
      border-bottom-width: 2px;
    }
  }
}

.visible {
  animation: fadeIn 0.3s;
  transition-delay: 0.275s;
  animation-delay: 0.275s;
}

.invisible {
  opacity: 0;
}

::ng-deep .option-panel {
  animation: slideInHorizontalDropdown 0.3s;
  animation-fill-mode: forwards;
  flex-grow: 1;
  padding: 0 !important;

  mat-option {
    border-bottom-width: 1px;
    border-bottom-style: solid;
    padding-left: 1em;
    font-size: 16px;
  }

  :last-child {
    border-bottom: none;
  }
}

::ng-deep .cdk-overlay-pane {
  min-width: 0rem !important;
}

::ng-deep .ccf-dropdown {
  .mat-select-arrow-wrapper {
    transform: translatey(-0.5em);
  }
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""