diff --git a/etc/lime-elements.api.md b/etc/lime-elements.api.md index 8a82844bb9..6351451e18 100644 --- a/etc/lime-elements.api.md +++ b/etc/lime-elements.api.md @@ -792,6 +792,7 @@ export namespace Components { "movableColumns": boolean; "page": number; "pageSize": number; + "paginationLocation": 'top' | 'bottom'; "selectable": boolean; "selection": object[]; "sortableColumns": boolean; @@ -2024,6 +2025,7 @@ export namespace JSX { "onSort"?: (event: LimelTableCustomEvent) => void; "page"?: number; "pageSize"?: number; + "paginationLocation"?: 'top' | 'bottom'; "selectable"?: boolean; "selection"?: object[]; "sortableColumns"?: boolean; diff --git a/package-lock.json b/package-lock.json index 93643cc1de..b9f1254b4b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,7 @@ "@types/lodash-es": "^4.17.12", "@types/react": "^19.1.10", "@types/react-dom": "^19.1.7", - "@types/tabulator-tables": "^4.9.4", + "@types/tabulator-tables": "^6.2.4", "codemirror": "^5.65.9", "cross-env": "^7.0.3", "dayjs": "^1.11.13", @@ -65,7 +65,7 @@ "shelljs": "0.10.0", "shx": "^0.4.0", "style-to-object": "^1.0.9", - "tabulator-tables": "^4.9.3", + "tabulator-tables": "^6.3.1", "typescript": "^4.9.5", "unified": "^11.0.5", "unist-util-visit": "^5.0.0" @@ -2874,10 +2874,11 @@ "dev": true }, "node_modules/@types/tabulator-tables": { - "version": "4.9.4", - "resolved": "https://registry.npmjs.org/@types/tabulator-tables/-/tabulator-tables-4.9.4.tgz", - "integrity": "sha512-yx8lZb15X+RP5a0ih6Fw5AaD/1m62+35ULMcm3TxQaheiH76lyBr2Zs20Wf7KNWsIGy1nwMmbjkCt6vjMczJQQ==", - "dev": true + "version": "6.2.4", + "resolved": "https://registry.npmjs.org/@types/tabulator-tables/-/tabulator-tables-6.2.4.tgz", + "integrity": "sha512-FT5OgxMHimUdlexGAMR+YZhR7A5i93a8ss323HMbVNlwcz9HDIwh4leGoAtLswdus96+q1I6LFMAGFBybA5pug==", + "dev": true, + "license": "MIT" }, "node_modules/@types/tern": { "version": "0.23.3", @@ -13679,10 +13680,11 @@ } }, "node_modules/tabulator-tables": { - "version": "4.9.3", - "resolved": "https://registry.npmjs.org/tabulator-tables/-/tabulator-tables-4.9.3.tgz", - "integrity": "sha512-iwwQqAEGGxlgrBpcmJJvMJrfjGLcCXOB3AOb/DGkXqBy1YKoYA36hIl7qXGp6Jo8dSkzFAlDT6pKLZgyhs9OnQ==", - "dev": true + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/tabulator-tables/-/tabulator-tables-6.3.1.tgz", + "integrity": "sha512-qFW7kfadtcaISQIibKAIy0f3eeIXUVi8242Vly1iJfMD79kfEGzfczNuPBN/80hDxHzQJXYbmJ8VipI40hQtfA==", + "dev": true, + "license": "MIT" }, "node_modules/tar-fs": { "version": "2.1.1", @@ -17298,9 +17300,9 @@ "dev": true }, "@types/tabulator-tables": { - "version": "4.9.4", - "resolved": "https://registry.npmjs.org/@types/tabulator-tables/-/tabulator-tables-4.9.4.tgz", - "integrity": "sha512-yx8lZb15X+RP5a0ih6Fw5AaD/1m62+35ULMcm3TxQaheiH76lyBr2Zs20Wf7KNWsIGy1nwMmbjkCt6vjMczJQQ==", + "version": "6.2.4", + "resolved": "https://registry.npmjs.org/@types/tabulator-tables/-/tabulator-tables-6.2.4.tgz", + "integrity": "sha512-FT5OgxMHimUdlexGAMR+YZhR7A5i93a8ss323HMbVNlwcz9HDIwh4leGoAtLswdus96+q1I6LFMAGFBybA5pug==", "dev": true }, "@types/tern": { @@ -25089,9 +25091,9 @@ } }, "tabulator-tables": { - "version": "4.9.3", - "resolved": "https://registry.npmjs.org/tabulator-tables/-/tabulator-tables-4.9.3.tgz", - "integrity": "sha512-iwwQqAEGGxlgrBpcmJJvMJrfjGLcCXOB3AOb/DGkXqBy1YKoYA36hIl7qXGp6Jo8dSkzFAlDT6pKLZgyhs9OnQ==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/tabulator-tables/-/tabulator-tables-6.3.1.tgz", + "integrity": "sha512-qFW7kfadtcaISQIibKAIy0f3eeIXUVi8242Vly1iJfMD79kfEGzfczNuPBN/80hDxHzQJXYbmJ8VipI40hQtfA==", "dev": true }, "tar-fs": { diff --git a/package.json b/package.json index 909d844a07..12bd4c3641 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "@types/lodash-es": "^4.17.12", "@types/react": "^19.1.10", "@types/react-dom": "^19.1.7", - "@types/tabulator-tables": "^4.9.4", + "@types/tabulator-tables": "^6.2.4", "codemirror": "^5.65.9", "cross-env": "^7.0.3", "dayjs": "^1.11.13", @@ -90,7 +90,7 @@ "shelljs": "0.10.0", "shx": "^0.4.0", "style-to-object": "^1.0.9", - "tabulator-tables": "^4.9.3", + "tabulator-tables": "^6.3.1", "typescript": "^4.9.5", "unified": "^11.0.5", "unist-util-visit": "^5.0.0" diff --git a/src/components/table/columns.ts b/src/components/table/columns.ts index 5d012f07b1..99f83ae802 100644 --- a/src/components/table/columns.ts +++ b/src/components/table/columns.ts @@ -1,5 +1,12 @@ import { Column, ColumnSorter, ColumnAggregatorFunction } from './table.types'; -import Tabulator from 'tabulator-tables'; +import { + CellComponent, + ColumnCalc, + ColumnComponent, + ColumnDefinition, + Formatter, + SorterFromTable, +} from 'tabulator-tables'; import { escape } from 'html-escaper'; import { ElementPool } from './element-pool'; import { pickBy, negate } from 'lodash-es'; @@ -15,8 +22,8 @@ export class ColumnDefinitionFactory { * @param column - config describing the column * @returns Tabulator column */ - public create(column: Column): Tabulator.ColumnDefinition { - const definition: Tabulator.ColumnDefinition = { + public create(column: Column): ColumnDefinition { + const definition: ColumnDefinition = { title: column.title, field: column.field, hozAlign: column.horizontalAlign, @@ -82,10 +89,7 @@ export const formatHeader = (column: Column) => (): string | HTMLElement => { * @param pool - pool to get custom components from * @returns Tabulator formatter */ -export function createFormatter( - column: Column, - pool: ElementPool -): Tabulator.Formatter { +export function createFormatter(column: Column, pool: ElementPool): Formatter { if (!column.component?.name) { return formatCell; } @@ -100,7 +104,7 @@ export function createFormatter( return formatCell; } - return (cell: Tabulator.CellComponent) => { + return (cell: CellComponent) => { const value = formatCell(cell, column); return createCustomComponent(cell, column, value, pool); @@ -126,10 +130,7 @@ function columnElementExists(column: Column) { * @param column - configuration for the current column * @returns the formatted value */ -export function formatCell( - cell: Tabulator.CellComponent, - column: Column -): string { +export function formatCell(cell: CellComponent, column: Column): string { const data = cell.getData(); let value = cell.getValue(); @@ -154,7 +155,7 @@ export function formatCell( * @returns custom component that renders a value in the table */ export function createCustomComponent( - cell: Tabulator.CellComponent, + cell: CellComponent, column: Column, value: string, pool: ElementPool @@ -233,10 +234,7 @@ function getEventName(eventListener: string): string { return eventListener.charAt(2).toLowerCase() + eventListener.slice(3); } -function createResizeObserver( - element: HTMLElement, - column: Tabulator.ColumnComponent -) { +function createResizeObserver(element: HTMLElement, column: ColumnComponent) { if (!('ResizeObserver' in window)) { return; } @@ -263,12 +261,6 @@ function createResizeObserver( }, RESIZE_TIMEOUT); } -// Tabulator seems to also have this `field` property, that does not appear on -// the interface for some reason -interface TabulatorSorter extends Tabulator.Sorter { - field: string; -} - /** * Create a column sorter from a tabulator sorter * @@ -277,7 +269,7 @@ interface TabulatorSorter extends Tabulator.Sorter { */ export const createColumnSorter = (columns: Column[]) => - (sorter: TabulatorSorter): ColumnSorter => { + (sorter: SorterFromTable): ColumnSorter => { const column = columns.find((col) => col.field === sorter.field); const direction = sorter.dir.toUpperCase() as 'ASC' | 'DESC'; @@ -291,7 +283,7 @@ export const createColumnSorter = * * @param column */ -export function getColumnAggregator(column: Column): Tabulator.ColumnCalc { +export function getColumnAggregator(column: Column): ColumnCalc { const aggregator = column.aggregator; if (isAggregatorFunction(aggregator)) { return (values: any[], data: object[]) => { diff --git a/src/components/table/examples/table-pagination.tsx b/src/components/table/examples/table-pagination.tsx new file mode 100644 index 0000000000..4e5b20d9bc --- /dev/null +++ b/src/components/table/examples/table-pagination.tsx @@ -0,0 +1,76 @@ +import { Component, h, Host, State } from '@stencil/core'; +import { + Column, + Option, + LimelSelectCustomEvent, +} from '@limetech/lime-elements'; +import { data, Bird } from './birds'; +import { capitalize } from 'lodash-es'; + +/** + * Pagination + * By specifying a `pageSize`, you can enable pagination for the table. + * + * Additionally, you can control the location of the pagination controls + * by setting the `paginationLocation` property to either `top` or `bottom`. + * + * @sourceFile birds.ts + */ +@Component({ + tag: 'limel-example-table-pagination', + styleUrl: 'table.scss', + shadow: true, +}) +export class TablePaginationExample { + @State() + private columns: Array> = [ + { title: 'Name', field: 'name' }, + { title: 'Binominal name', field: 'binominalName' }, + { title: 'Nest type', field: 'nest', formatter: capitalize }, + { title: 'Eggs per clutch', field: 'eggs', horizontalAlign: 'right' }, + { title: 'Origin', field: 'origin' }, + ]; + + @State() + private paginationLocation: 'top' | 'bottom' = 'bottom'; + + private readonly paginationLocationOptions: Option[] = [ + { text: 'Top', value: 'top' }, + { text: 'Bottom', value: 'bottom' }, + ]; + + private readonly pageSize = 5; + + render() { + return ( + + + + + + + ); + } + + private readonly getSelectedPaginationLocation = (): Option => { + return this.paginationLocationOptions.find( + (option) => option.value === this.paginationLocation + ); + }; + + private readonly handlePaginationLocationChange = ( + event: LimelSelectCustomEvent