core/split-view/split-view.component.ts

Description

A responsive split view layout component with automatic selection management and resizable panes.

Basic usage

Example :
export class MyComponent {
  items: Device[] = [];
  selectedItem?: Device;

  onSelectionChange(item: Device | null) {
    this.selectedItem = item || undefined;
  }
}
Example :
<c8y-sv (selectionChange)="onSelectionChange($event)">
  <c8y-sv-list [title]="'Devices'">
    <c8y-sv-header-actions>
      <button class="btn btn-primary">Add Device</button>
    </c8y-sv-header-actions>

    @for (item of items; track item.id) {
      <c8y-li [c8ySvListItem]="item">
        {{ item.name }}
      </c8y-li>
    }

    <c8y-sv-footer>
      Total: {{ items.length }}
    </c8y-sv-footer>
  </c8y-sv-list>

  <c8y-sv-details
    emptyStateIcon="c8y-devices"
    emptyStateTitle="No device selected"
    emptyStateSubtitle="Select a device to view details">
    @if (selectedItem) {
      <c8y-sv-extra-header>
        <c8y-icon-panel [sections]="sections"></c8y-icon-panel>
      </c8y-sv-extra-header>
    }

    @if (selectedItem) {
      <h3>{{ selectedItem.name }}</h3>
      <p>{{ selectedItem.description }}</p>
    }
  </c8y-sv-details>
</c8y-sv>

Router-Outlet integration

For components using Angular router:

Example :
<c8y-sv>
  <c8y-alarms-list>...</c8y-alarms-list>

  <c8y-sv-details (backClick)="handleBackClick()">
    <router-outlet></router-outlet>
  </c8y-sv-details>
</c8y-sv>
Example :
async handleBackClick(): Promise<void> {
  await this.alarmsViewService.closeDetailsView(this.activatedRoute);
}

Resizable configuration

Example :
<c8y-sv
  [isResizable]="true"
  [resizableBreakpoint]="991"
  [resizableConfig]="{
    trackId: 'my-split-view',
    leftColumnWidth: '40%',
    collapseThreshold: 320,
    collapsible: false
  }"
  [initialSelection]="items[0]"
  (selectionChange)="onSelectionChange($event)">
  <!-- content -->
</c8y-sv>

List-Only mode

Omit <c8y-sv-details> for a simple list view:

Example :
<c8y-sv>
  <c8y-sv-list [title]="'Items'">
    @for (item of items; track item.id) {
      <c8y-li>{{ item.name }}</c8y-li>
    }
  </c8y-sv-list>
</c8y-sv>

Implements

OnInit OnDestroy

Example

Metadata

Relationships

<div
  [attr.aria-label]="'Split view interface' | translate"
  tabindex="-1"
  role="main"
  [ngClass]="getContainerClasses()"
  data-cy="c8y-sv"
>
  @if (shouldUseResizableGrid) {
    <c8y-resizable-grid
      [collapseThreshold]="effectiveResizableConfig.collapseThreshold"
      [collapsible]="effectiveResizableConfig.collapsible"
      [leftColumnWidth]="effectiveResizableConfig.leftColumnWidth"
      [trackId]="effectiveResizableConfig.trackId"
    >
      <div left-pane>
        <ng-container *ngTemplateOutlet="listContent"></ng-container>
      </div>
      <div right-pane>
        <ng-container *ngTemplateOutlet="detailsContent"></ng-container>
      </div>
    </c8y-resizable-grid>
  } @else {
    <ng-container *ngTemplateOutlet="listContent"></ng-container>
    <ng-container *ngTemplateOutlet="detailsContent"></ng-container>
    @if (showDefaultRouterOutlet && !hasProjectedDetails) {
      <router-outlet class="d-contents"></router-outlet>
    }
  }

  <ng-template #listContent>
    <ng-content select=":not(c8y-sv-details)"></ng-content>
  </ng-template>

  <ng-template #detailsContent>
    @if (hasProjectedDetails) {
      <ng-content select="c8y-sv-details"></ng-content>
    }
  </ng-template>
</div>

results matching ""

    No results matching ""