2

I would like to add actions in the header of the accordion component. The only problem is that if you click the action, the accordion will state chnages between collapsed and expanded.

example:

<nb-accordion>
  <nb-accordion-item #primaryItem expanded="true">
    <nb-accordion-item-header>
      Dashboard
      <nb-actions size="small">
        <nb-action icon="search">Search</nb-action>
        <nb-action icon="star"></nb-action>
        <nb-action icon="star" status="warning"></nb-action>
      </nb-actions>
    </nb-accordion-item-header>
    <nb-accordion-item-body>
      item content
    </nb-accordion-item-body>
  </nb-accordion-item>
</nb-accordion>

Looks like this: enter image description here

I can see in the api that there is a collapsedChange event, but this emits after the change.

AM i out of luck here? IS there a way to intercept and cancel the collapse event?

thanks in advance

J King
  • 4,108
  • 10
  • 53
  • 103

3 Answers3

1

so seems I'm the only one looking for this. So I built my own custom card to deliver me the functionality I want. you can take this and use it in your own angular project. its a collapsible card with header and footer sections as well as a section for adding actions.

car component:

<nb-card accent="{{accentColor}}" status="{{statusColor}}">
  <nb-card-header>
    <span class="float-left card-title">
      <ng-content select="[slot=title]"></ng-content>
    </span>
    <nb-actions size="small" class="float-right">
      <nb-action><button type="button" status="basic" nbButton size="small" (click)="toggleExpand()">
          <nb-icon icon="{{expandedIcon}}"></nb-icon>{{ expandedText }}
        </button></nb-action>
      <!-- icon="{{expandedIcon}}" -->
    </nb-actions>
    <span class="float-right" *ngIf="hasActions">
      <ng-content select="[slot=actions]"></ng-content>
    </span>
  </nb-card-header>
  <nb-card-body *ngIf="expandedState" class="content-body">
    <ng-content select="[slot=body]"></ng-content>
  </nb-card-body>
  <nb-card-footer *ngIf="expandedState && hasFooter">
    <ng-content select="[slot=footer]"></ng-content>
  </nb-card-footer>
</nb-card>

component .ts

import { Component, OnInit, Input } from '@angular/core';

@Component({
  selector: 'app-content-card',
  templateUrl: './content-card.component.html',
  styleUrls: ['./content-card.component.scss'],
})
export class ContentCardComponent implements OnInit {
  // STATUS OPTIONS: basic, primary, info, success, warning, danger, control
  // ACCENT OPTIONS: basic, primary, info, success, warning, danger, control

  @Input() hasActions: boolean;
  @Input() hasFooter: boolean;
  @Input() accentColor: string;
  @Input() statusColor: string;

  public readonly upIcon = 'arrowhead-up-outline';
  public readonly downIcon = 'arrowhead-down-outline';
  public readonly hideText = 'hide';
  public readonly showText = 'show';

  public expandedState = true;
  public expandedText: string;
  public expandedIcon: string;

  constructor() {}

  ngOnInit() {
    this.expandedIcon = this.upIcon;
    this.expandedText = this.hideText;
  }

  public toggleExpand(): void {
    this.expandedState = !this.expandedState;
    if (this.expandedState) {
      this.expandedIcon = this.upIcon;
      this.expandedText = this.hideText;
    } else {
      this.expandedIcon = this.downIcon;
      this.expandedText = this.showText;
    }
  }
}

component .scss

.float-right {
  float: right;
}

.float-left {
  float: left;
}
J King
  • 4,108
  • 10
  • 53
  • 103
0

Sorry if this is a little late - I ran into the same issue and in short, no there is no API or direct way to stop the accordion item from firing the expand/collapse whenever you click anywhere in the header component. The reason is because nebular is attaching a click event to all rendered html children of the accordion header that will fire the expand/collapse event. You can actually see the attached event if you inspect your elements and look at the attached event listeners.

One hacky way is the attempt to remove the attached event.

A second hacky way to get around this and the one I used was to fire the toggle for the accordion a second time after clicking. The end result is that the user does not see the accordion expand (since an expand + collapse = no ui change):

component.html

<nb-accordion>
  <nb-accordion-item #primaryItem expanded="true" *ngFor="let item in items; let i = index;">
    <nb-accordion-item-header>
      Dashboard
      <nb-actions size="small">
        <nb-action icon="search" (click)="cancelAccordionToggle(i)">Search</nb-action>
        <nb-action icon="star" (click)="cancelAccordionToggle(i)"></nb-action>
        <nb-action icon="star" status="warning" (click)="cancelAccordionToggle(i)"></nb-action>
      </nb-actions>
    </nb-accordion-item-header>
    <nb-accordion-item-body>
      item content
    </nb-accordion-item-body>
  </nb-accordion-item>
</nb-accordion>

component.ts

// use the following hack for accordian so action items do not trigger toggle
  @ViewChildren(NbAccordionItemComponent) listItems: QueryList<NbAccordionItemComponent>;
  cancelAccordionToggle(index: number) {
    const listItem: NbAccordionItemComponent = this.listItems.toArray()[index];
    listItem.toggle();
  }

If you don't want hack it like this, the alternative solution is to make your own like you did.

CodeCheshire
  • 710
  • 1
  • 8
  • 27
0

I added the following to my nbButton inside of <nb-accordion-item-header>

(click)="$event.stopPropagation()" and it worked for me.