UNPKG

carbon-components-angular

Version:
469 lines (465 loc) 17.3 kB
/** * * carbon-angular v0.0.0 | table.component.d.ts * * Copyright 2014, 2025 IBM * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { ApplicationRef, OnInit, EventEmitter, ElementRef, AfterViewInit, TemplateRef, OnDestroy } from "@angular/core"; import { Subscription, Observable } from "rxjs"; import { TableModel } from "./table-model.class"; import { TableItem } from "./table-item.class"; import { I18n, Overridable } from "carbon-components-angular/i18n"; import { DataGridInteractionModel } from "./data-grid-interaction-model.class"; import { TableRowSize } from "./table.types"; import * as i0 from "@angular/core"; /** * Build your table with this component by extending things that differ from default. * * [See demo](../../?path=/story/components-table--basic) * * Instead of the usual write-your-own-html approach you had with `<table>`, * carbon table uses model-view-controller approach. * * Here, you create a view (with built-in controller) and provide it a model. * Changes you make to the model are reflected in the view. Provide same model you use * in the table to the `<cds-pagination>` components. * They provide a different view over the same data. * * ## Basic usage * * ```html * <cds-table [model]="model"></cds-table> * ``` * * ```typescript * public model = new TableModel(); * * this.model.data = [ * [new TableItem({data: "asdf"}), new TableItem({data: "qwer"})], * [new TableItem({data: "csdf"}), new TableItem({data: "zwer"})], * [new TableItem({data: "bsdf"}), new TableItem({data: "swer"})], * [new TableItem({data: "csdf"}), new TableItem({data: "twer"})] * ]; * ``` * * ## Customization * * If you have custom data in your table, you need a way to display it. You can do that * by providing a template to `TableItem`. * * ```html * <ng-template #customTableItemTemplate let-data="data"> * <a [routerLink]="data.link">{{data.name}} {{data.surname}}</a> * </ng-template> * ``` * * ```typescript * customTableItemTemplate: TemplateRef<any>; * * this.customModel.data = [ * [new TableItem({data: "asdf"}), new TableItem({data: {name: "Lessy", link: "/table"}, template: this.customTableItemTemplate})], * [new TableItem({data: "csdf"}), new TableItem({data: "swer"})], * [new TableItem({data: "bsdf"}), new TableItem({data: {name: "Alice", surname: "Bob"}, template: this.customTableItemTemplate})], * [new TableItem({data: "csdf"}), new TableItem({data: "twer"})], * ]; * ``` * * ### Sorting and filtering * * In case you need custom sorting and/or filtering you should subclass `TableHeaderItem` * and override needed functions. * * ```typescript * class FilterableHeaderItem extends TableHeaderItem { * // custom filter function * filter(item: TableItem): boolean { * if (typeof item.data === "string" && item.data.toLowerCase().indexOf(this.filterData.data.toLowerCase()) >= 0 || * item.data.name && item.data.name.toLowerCase().indexOf(this.filterData.data.toLowerCase()) >= 0 || * item.data.surname && item.data.surname.toLowerCase().indexOf(this.filterData.data.toLowerCase()) >= 0) { * return false; * } * return true; * } * * set filterCount(n) {} * get filterCount() { * return (this.filterData && this.filterData.data && this.filterData.data.length > 0) ? 1 : 0; * } * * // used for custom sorting * compare(one: TableItem, two: TableItem) { * const stringOne = (one.data.name || one.data.surname || one.data).toLowerCase(); * const stringTwo = (two.data.name || two.data.surname || two.data).toLowerCase(); * * if (stringOne > stringTwo) { * return 1; * } else if (stringOne < stringTwo) { * return -1; * } else { * return 0; * } * } * } * ``` * * If you want to do your sorting on the backend or query for sorted data as a result of user * clicking the table header, check table [`sort`](#sort) output documentation * * See `TableHeaderItem` class for more information. * * ## No data template * * When table has no data to show, it can show a message you provide it instead. * * ```html * <cds-table [model]="model">No data.</cds-table> * ``` * * ... will show `No data.` message, but you can get creative and provide any template you want * to replace table's default `tbody`. * * ## Use pagination as table footer * * ```html * <cds-pagination [model]="model" (selectPage)="selectPage($event)"></cds-pagination> * ``` * * `selectPage()` function should fetch the data from backend, create new `data`, apply it to `model.data`, * and update `model.currentPage`. * * If the data your server returns is a two dimensional array of objects, it would look something like this: * * ```typescript * selectPage(page) { * this.getPage(page).then((data: Array<Array<any>>) => { * // set the data and update page * this.model.data = this.prepareData(data); * this.model.currentPage = page; * }); * } * * protected prepareData(data: Array<Array<any>>) { * // create new data from the service data * let newData = []; * data.forEach(dataRow => { * let row = []; * dataRow.forEach(dataElement => { * row.push(new TableItem({ * data: dataElement, * template: typeof dataElement === "string" ? undefined : this.paginationTableItemTemplate * // your template can handle all the data types so you don't have to conditionally set it * // you can also set different templates for different columns based on index * })); * }); * newData.push(row); * }); * return newData; * } * ``` */ export declare class Table implements OnInit, AfterViewInit, OnDestroy { protected elementRef: ElementRef; protected applicationRef: ApplicationRef; protected i18n: I18n; /** * Creates a skeleton model with a row and column count specified by the user * * Example: * * ```typescript * this.model = Table.skeletonModel(5, 5); * ``` */ static skeletonModel(rowCount: number, columnCount: number): TableModel; static setTabIndex(element: HTMLElement, index: -1 | 0): void; static focus(element: HTMLElement): void; /** * Id of the table header title element */ ariaLabelledby: string; /** * Id of the table header description element */ ariaDescribedby: string; /** * `TableModel` with data the table is to display. */ set model(m: TableModel); get model(): TableModel; /** * Size of the table rows. */ size: TableRowSize; /** * Set to `true` for a loading table. */ skeleton: boolean; /** * Set to `true` for a data grid with keyboard interactions. */ set isDataGrid(value: boolean); /** * Setting sortable to false will disable all headers including headers which are sortable. Is is * possible to set the sortable state on the header item to disable/enable sorting for only some headers. */ sortable: boolean; noBorder: boolean; /** * Set to `true` to show expansion toggle when table consists of row expansions */ showExpandAllToggle: boolean; get isDataGrid(): boolean; /** * Controls whether to show the selection checkboxes column or not. */ showSelectionColumn: boolean; /** * Controls whether to enable multiple or single row selection. */ enableSingleSelect: boolean; /** * Distance (in px) from the bottom that view has to reach before * `scrollLoad` event is emitted. */ scrollLoadDistance: number; /** * @todo - Enable column resize when Carbon officially supports feature * Set to `true` to enable users to resize columns. * * Works for columns with width set in pixels. * */ /** * @todo - Enable columns drag & drop when Carbon officially supports feature * Set to `true` to enable users to drag and drop columns. * * Changing the column order in table changes table model. Be aware of it when you add additional data * to the model. * */ set expandButtonAriaLabel(value: string | Observable<string>); get expandButtonAriaLabel(): string | Observable<string>; set sortDescendingLabel(value: string | Observable<string>); get sortDescendingLabel(): string | Observable<string>; set sortAscendingLabel(value: string | Observable<string>); get sortAscendingLabel(): string | Observable<string>; /** * Expects an object that contains some or all of: * ``` * { * "FILTER": "Filter", * "END_OF_DATA": "You've reached the end of your content", * "SCROLL_TOP": "Scroll to top", * "CHECKBOX_HEADER": "Select all rows", * "CHECKBOX_ROW": "Select row" * } * ``` */ set translations(value: any); /** * Set to `false` to remove table rows (zebra) stripes. */ striped: boolean; /** * Allows table content to scroll horizontally */ tableContent: boolean; /** * Set to `true` to stick the header to the top of the table */ stickyHeader: boolean; /** * Set footer template to customize what is displayed in the tfoot section of the table */ footerTemplate: TemplateRef<any>; /** * Used to populate the row selection checkbox label with a useful value if set. * * Example: * ``` * <cds-table [selectionLabelColumn]="0"></cds-table> * <!-- results in aria-label="Select first column value" * (where "first column value" is the value of the first column in the row --> * ``` */ selectionLabelColumn: number; /** * Emits an index of the column that wants to be sorted. * * If no observers are provided (default), table will attempt to do a simple sort of the data loaded * into the model. * * If an observer is provided, table will not attempt any sorting of its own and it is up to the observer * to sort the table. This is what you typically want if you're using a backend query to get the sorted * data or want to sort data across multiple pages. * * Usage: * * ```typescript * @Component({ * selector: "app-table", * template: ` * <cds-table * [model]="model" * (sort)="simpleSort($event)"> * No data. * </cds-table> * ` * }) * export class TableApp implements OnInit, OnChanges { * @Input() model = new TableModel(); * * ngOnInit() { * this.model.header = [ * new TableHeaderItem({ data: "Name" }), * new TableHeaderItem({ data: "hwer" }) * ]; * * this.model.data = [ * [new TableItem({ data: "Name 1" }), new TableItem({ data: "qwer" })], * [new TableItem({ data: "Name 3" }), new TableItem({ data: "zwer" })], * [new TableItem({ data: "Name 2" }), new TableItem({ data: "swer" })], * [new TableItem({ data: "Name 4" }), new TableItem({data: "twer"})], * [new TableItem({ data: "Name 5" }), new TableItem({data: "twer"})], * [new TableItem({ data: "Name 6" }), new TableItem({data: "twer"})] * ]; * } * * simpleSort(index: number) { * // this function does a simple sort, which is the default for the table and if that's * // all you want, you don't need to do this. * * // here you can query your backend and update the model.data based on the result * if (this.model.header[index].sorted) { * // if already sorted flip sorting direction * this.model.header[index].ascending = this.model.header[index].descending; * } * this.model.sort(index); * } * } * ``` */ sort: EventEmitter<number>; /** * Emits if all rows are selected. * * @param model */ selectAll: EventEmitter<Object>; /** * Emits if all rows are deselected. * * @param model */ deselectAll: EventEmitter<Object>; /** * Emits if a single row is selected. * * @param ({model: this.model, selectedRowIndex: index}) */ selectRow: EventEmitter<Object>; /** * Emits if a single row is deselected. * * @param ({model: this.model, deselectedRowIndex: index}) */ deselectRow: EventEmitter<Object>; /** * Emits if a row item excluding expandButtons, checkboxes, or radios is clicked. */ rowClick: EventEmitter<number>; /** * Emits when table requires more data to be loaded. */ scrollLoad: EventEmitter<TableModel>; /** * Controls if all checkboxes are viewed as selected. */ selectAllCheckbox: boolean; /** * Controls the indeterminate state of the header checkbox. */ selectAllCheckboxSomeSelected: boolean; get noData(): boolean; isColumnDragging: boolean; columnDraggedHoverIndex: number; columnDraggedPosition: string; protected _model: TableModel; protected _isDataGrid: boolean; protected isViewReady: boolean; protected subscriptions: Subscription; protected positionSubscription: Subscription; protected interactionModel: DataGridInteractionModel; protected interactionPositionSubscription: Subscription; protected _expandButtonAriaLabel: Overridable; protected _sortDescendingLabel: Overridable; protected _sortAscendingLabel: Overridable; protected _checkboxHeaderLabel: Overridable; protected _checkboxRowLabel: Overridable; protected _endOfDataText: Overridable; protected _scrollTopText: Overridable; protected _filterTitle: Overridable; protected columnResizeWidth: number; protected columnResizeMouseX: number; protected mouseMoveSubscription: Subscription; protected mouseUpSubscription: Subscription; /** * Creates an instance of Table. */ constructor(elementRef: ElementRef, applicationRef: ApplicationRef, i18n: I18n); ngOnInit(): void; ngAfterViewInit(): void; ngOnDestroy(): void; enableDataGridInteractions(): void; disableDataGridInteractions(): void; onSelectAll(): void; onDeselectAll(): void; onSelectRow(event: any): void; onRowClick(index: number): void; updateSelectAllCheckbox(): void; resetTabIndex(newTabIndex?: number): void; columnResizeStart(event: any, column: any): void; columnResizeProgress(event: any, column: any): void; columnResizeEnd(event: any, column: any): void; /** * Triggered when the user scrolls on the `<tbody>` element. * Emits the `scrollLoad` event. */ onScroll(event: any): void; columnDragStart(event: any, columnIndex: any): void; columnDragEnd(event: any, columnIndex: any): void; columnDragEnter(event: any, position: any, columnIndex: any): void; columnDragLeave(event: any, position: any, columnIndex: any): void; columnDragover(event: any, position: any, columnIndex: any): void; columnDrop(event: any, position: any, columnIndex: any): void; doSort(index: number): void; /** * Triggered when the user scrolls on the `<tbody>` element. * Emits the `scrollLoad` event. */ scrollToTop(event: any): void; getSelectionLabelValue(row: TableItem[]): { value: any; }; getExpandButtonAriaLabel(): Observable<string>; getSortDescendingLabel(): Observable<string>; getSortAscendingLabel(): Observable<string>; getCheckboxHeaderLabel(): Observable<string>; getCheckboxRowLabel(): Observable<string>; getEndOfDataText(): Observable<string>; getScrollTopText(): Observable<string>; getFilterTitle(): Observable<string>; static ɵfac: i0.ɵɵFactoryDeclaration<Table, never>; static ɵcmp: i0.ɵɵComponentDeclaration<Table, "cds-table, ibm-table", never, { "ariaLabelledby": "ariaLabelledby"; "ariaDescribedby": "ariaDescribedby"; "model": "model"; "size": "size"; "skeleton": "skeleton"; "isDataGrid": "isDataGrid"; "sortable": "sortable"; "noBorder": "noBorder"; "showExpandAllToggle": "showExpandAllToggle"; "showSelectionColumn": "showSelectionColumn"; "enableSingleSelect": "enableSingleSelect"; "scrollLoadDistance": "scrollLoadDistance"; "expandButtonAriaLabel": "expandButtonAriaLabel"; "sortDescendingLabel": "sortDescendingLabel"; "sortAscendingLabel": "sortAscendingLabel"; "translations": "translations"; "striped": "striped"; "stickyHeader": "stickyHeader"; "footerTemplate": "footerTemplate"; "selectionLabelColumn": "selectionLabelColumn"; }, { "sort": "sort"; "selectAll": "selectAll"; "deselectAll": "deselectAll"; "selectRow": "selectRow"; "deselectRow": "deselectRow"; "rowClick": "rowClick"; "scrollLoad": "scrollLoad"; }, never, ["*"], false>; }