File

libs/ui/expansion-panel/src/lib/trigger/expansion-panel-trigger.component.ts

Description

Trigger to open/close a TsExpansionPanelComponent

Implements

OnDestroy FocusableOption

Example

<ts-expansion-panel>
   <ts-expansion-panel-trigger
     collapsedHeight="100px"
     expandedHeight="150px"
   >
     Panel trigger
   </ts-expansion-panel-trigger>

   Panel content
</ts-expansion-panel>

<example-url>https://getterminus.github.io/ui-demos-release/components/expansion-panel</example-url>

Metadata

changeDetection ChangeDetectionStrategy.OnPush
encapsulation ViewEncapsulation.None
exportAs tsExpansionPanelTrigger
host {
}
selector ts-expansion-panel-trigger
styleUrls ./expansion-panel-trigger.component.scss
templateUrl ./expansion-panel-trigger.component.html

Index

Properties
Methods
Inputs
Accessors

Constructor

constructor(panel: TsExpansionPanelComponent, elementRef: ElementRef, focusMonitor: FocusMonitor, changeDetectorRef: ChangeDetectorRef, defaultOptions?: TsExpansionPanelDefaultOptions)
Parameters :
Name Type Optional
panel TsExpansionPanelComponent No
elementRef ElementRef No
focusMonitor FocusMonitor No
changeDetectorRef ChangeDetectorRef No
defaultOptions TsExpansionPanelDefaultOptions Yes

Inputs

collapsedHeight
Type : string | undefined

Height of the trigger while the panel is collapsed

expandedHeight
Type : string | undefined

Height of the trigger while the panel is expanded

Methods

Public focus
focus(origin: FocusOrigin)

Focuses the panel trigger.

Implemented as a part of FocusableOption.

Parameters :
Name Type Optional Default value Description
origin FocusOrigin No 'program'
  • Origin of the action that triggered the focus.
Returns : void
Public keydown
keydown(event: KeyboardEvent)

Handle keydown event calling to toggle() if appropriate

Parameters :
Name Type Optional
event KeyboardEvent No
Returns : void
Public toggle
toggle()

Toggle the expanded state of the panel

Returns : void

Properties

Public panel
Type : TsExpansionPanelComponent
Decorators :
@Host()

Accessors

currentPanelExpandedState
getcurrentPanelExpandedState()

Determine the current expanded state string of the panel

Returns : string
isExpanded
getisExpanded()

Determine if the panel is currently expanded

Returns : boolean
isTransparent
getisTransparent()

Determine if current mode is transparent

Returns : boolean
disabled
getdisabled()

Whether the associated panel is disabled.

Implemented as a part of FocusableOption.

Returns : boolean
shouldShowToggle
getshouldShowToggle()

Gets whether the expand indicator should be shown.

Returns : boolean
import {
  FocusableOption,
  FocusMonitor,
  FocusOrigin,
} from '@angular/cdk/a11y';
import { hasModifierKey } from '@angular/cdk/keycodes';
import {
  ChangeDetectionStrategy,
  ChangeDetectorRef,
  Component,
  ElementRef,
  Host,
  Inject,
  Input,
  OnDestroy,
  Optional,
  ViewEncapsulation,
} from '@angular/core';
import {
  EMPTY,
  merge,
} from 'rxjs';
import { filter } from 'rxjs/operators';

import {
  KEYS,
  untilComponentDestroyed,
} from '@terminus/fe-utilities';

import { tsExpansionPanelAnimations } from '../panel/expansion-animations';
import {
  TS_EXPANSION_PANEL_DEFAULT_OPTIONS,
  TsExpansionPanelComponent,
  TsExpansionPanelDefaultOptions,
} from '../panel/expansion-panel.component';


/**
 * Trigger to open/close a {@link TsExpansionPanelComponent}
 *
 * @example
 * <ts-expansion-panel>
 *               <ts-expansion-panel-trigger
 *                 collapsedHeight="100px"
 *                 expandedHeight="150px"
 *               >
 *                 Panel trigger
 *               </ts-expansion-panel-trigger>
 *
 *               Panel content
 * </ts-expansion-panel>
 *
 * <example-url>https://getterminus.github.io/ui-demos-release/components/expansion-panel</example-url>
 */
@Component({
  animations: [
    tsExpansionPanelAnimations.indicatorRotate,
    tsExpansionPanelAnimations.expansionTriggerHeight,
  ],
  selector: 'ts-expansion-panel-trigger',
  styleUrls: ['./expansion-panel-trigger.component.scss'],
  templateUrl: './expansion-panel-trigger.component.html',
  host: {
    'class': 'ts-expansion-panel__trigger',
    'role': 'button',
    '[attr.id]': 'panel.triggerId',
    '[attr.tabindex]': 'disabled ? -1 : 0',
    '[attr.aria-controls]': 'panel.id',
    '[attr.aria-expanded]': 'isExpanded',
    '[attr.aria-disabled]': 'panel.disabled',
    // eslint-disable-next-line @typescript-eslint/naming-convention
    '[class.ts-expansion-panel__trigger--expanded]': 'isExpanded',
    // eslint-disable-next-line @typescript-eslint/naming-convention
    '[class.ts-expansion-panel__trigger--transparent]': 'isTransparent',
    '(click)': 'toggle()',
    '(keydown)': 'keydown($event)',
    '[@expansionHeight]': `{
      value: currentPanelExpandedState,
      params: {
        collapsedHeight: collapsedHeight,
        expandedHeight: expandedHeight
      }
    }`,
  },
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
  exportAs: 'tsExpansionPanelTrigger',
})
export class TsExpansionPanelTriggerComponent implements OnDestroy, FocusableOption {
  /**
   * Determine the current expanded state string of the panel
   */
  public get currentPanelExpandedState(): string {
    return this.panel.currentExpandedState;
  }

  /**
   * Determine if the panel is currently expanded
   */
  public get isExpanded(): boolean {
    return this.panel.expanded;
  }

  /**
   * Determine if current mode is transparent
   */
  public get isTransparent(): boolean {
    return this.panel.transparentMode;
  }

  /**
   * Whether the associated panel is disabled.
   *
   * Implemented as a part of `FocusableOption`.
   */
  public get disabled(): boolean {
    return this.panel.disabled;
  }

  /** Gets whether the expand indicator should be shown. */
  public get shouldShowToggle(): boolean {
    return !this.panel.hideToggle && !this.panel.disabled;
  }

  /**
   * Height of the trigger while the panel is collapsed
   */
  @Input()
  public collapsedHeight: string | undefined;

  /**
   * Height of the trigger while the panel is expanded
   */
  @Input()
  public expandedHeight: string | undefined;


  constructor(
    @Host() public panel: TsExpansionPanelComponent,
    private elementRef: ElementRef,
    private focusMonitor: FocusMonitor,
    private changeDetectorRef: ChangeDetectorRef,
    @Inject(TS_EXPANSION_PANEL_DEFAULT_OPTIONS) @Optional() defaultOptions?: TsExpansionPanelDefaultOptions,
  ) {
    const accordionHideToggleChange =
      panel.accordion
        // NOTE: Underscore naming controlled by Material
        // eslint-disable-next-line no-underscore-dangle
        ? panel.accordion._stateChanges.pipe(filter(changes => !!changes.hideToggle))
        : EMPTY;

    // Since the toggle state depends on an @Input on the panel, we need to subscribe and trigger change detection manually.
    // eslint-disable-next-line deprecation/deprecation
    merge(
      panel.opened, panel.closed, accordionHideToggleChange,
      panel.inputChanges.pipe(filter(changes => !!(changes.hideToggle || changes.disabled))),
    ).pipe(
      untilComponentDestroyed(this),
    )
      .subscribe(() => this.changeDetectorRef.markForCheck());

    // Avoid focus being lost if the panel contained the focused element and was closed.
    panel.closed.pipe(
      filter(() => panel.contentContainsFocus),
      untilComponentDestroyed(this),
    ).subscribe(() => focusMonitor.focusVia(elementRef, 'program'));

    // Subscribe to trigger focus events
    focusMonitor.monitor(elementRef).subscribe(origin => {
      if (origin && panel.accordion) {
        panel.accordion.handleTriggerFocus(this);
      }
    });

    // Set the default options if they exist
    if (defaultOptions) {
      this.expandedHeight = defaultOptions.expandedHeight;
      this.collapsedHeight = defaultOptions.collapsedHeight;
    }
  }

  /**
   * Stop monitoring focus events
   */
  public ngOnDestroy(): void {
    this.focusMonitor.stopMonitoring(this.elementRef);
  }

  /**
   * Focuses the panel trigger.
   *
   * Implemented as a part of `FocusableOption`.
   *
   * @param origin - Origin of the action that triggered the focus.
   */
  public focus(origin: FocusOrigin = 'program'): void {
    this.focusMonitor.focusVia(this.elementRef, origin);
  }

  /**
   * Toggle the expanded state of the panel
   */
  public toggle(): void {
    this.panel.toggle();
  }

  /**
   * Handle keydown event calling to toggle() if appropriate
   *
   * @param event
   */
  public keydown(event: KeyboardEvent): void {
    const { code } = event;
    const isSelectionKey = (code === KEYS.SPACE.code) || (code === KEYS.ENTER.code);

    if (isSelectionKey) {
      // istanbul ignore else
      if (!hasModifierKey(event)) {
        event.preventDefault();
        this.toggle();
      }
    } else if (this.panel.accordion) {
      this.panel.accordion.handleTriggerKeydown(event);
    }
  }
}

result-matching ""

    No results matching ""