diff --git a/types/react-bootstrap-table-next/index.d.ts b/types/react-bootstrap-table-next/index.d.ts new file mode 100644 index 0000000000..ea52a41660 --- /dev/null +++ b/types/react-bootstrap-table-next/index.d.ts @@ -0,0 +1,456 @@ +// Type definitions for react-bootstrap-table-next 4.0 +// Project: https://github.com/react-bootstrap-table/react-bootstrap-table2#readme +// Definitions by: Wlad Meixner +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 3.0 + +// documentation taken from https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/table-props.html + +import { CSSProperties, ReactElement, SyntheticEvent, Component } from 'react'; + +export const ROW_SELECT_SINGLE = 'radio'; +export const ROW_SELECT_MULTIPLE = 'checkbox'; +export const ROW_SELECT_DISABLED = 'ROW_SELECT_DISABLED'; +export const CHECKBOX_STATUS_INDETERMINATE = 'indeterminate'; +export const CHECKBOX_STATUS_CHECKED = 'checked'; +export const CHECKBOX_STATUS_UNCHECKED = 'unchecked'; +export const FILTERS_POSITION_INLINE = 'inline'; +export const FILTERS_POSITION_TOP = 'top'; +export const FILTERS_POSITION_BOTTOM = 'bottom'; + +export type RowSelectionType = typeof ROW_SELECT_SINGLE | typeof ROW_SELECT_MULTIPLE | typeof ROW_SELECT_DISABLED; +export type TableCheckboxStatus = + | typeof CHECKBOX_STATUS_INDETERMINATE + | typeof CHECKBOX_STATUS_CHECKED + | typeof CHECKBOX_STATUS_UNCHECKED; +export type FilterPosition = + | typeof FILTERS_POSITION_INLINE + | typeof FILTERS_POSITION_TOP + | typeof FILTERS_POSITION_BOTTOM; + +/** + * Table change event types + */ +export type TableChangeType = 'filter' | 'pagination' | 'sort' | 'cellEdit'; + +/** + * Used to specify the text alignment for a column. + */ +export type CellAlignment = ('left' | 'center' | 'right' | 'start' | 'end') | string; + +/** + * Filter comparators used for table filters + */ +declare enum FilterComparator { + LIKE = 'LIKE', + EQ = '=', + NE = '!=', + GT = '>', + GE = '>=', + LT = '<', + LE = '<=', +} + +/** + * Sort Order values. 'asc' = ascending, 'desc' = descending. + */ +export type SortOrder = 'asc' | 'desc'; + +export type ColumnSortFunc = ( + a: T[E], + b: T[E], + order: 'asc' | 'desc', + dataField: any, + rowA: T, + rowB: T, +) => number; + +export interface TableChangeState { + page: number; + sizePerPage: number; + sortField: string; + sortOrder: 'asc' | 'desc'; + filters: { [key: string]: { filterVal: any; filterType: 'TEXT'; comparator: any } }; + data: T[]; + cellEdit: { + rowId: string; + dataField: any; + newValue: any; + }; +} + +export type HeaderFormatter = ( + column: ColumnDescription, + colIndex: number, + components: { + sortElement: JSX.Element; + filterElement: JSX.Element; + }, +) => JSX.Element | string | number | React.ReactText; + +export type ColumnFormatter = ( + cell: C, + row: R, + rowIndex: number, + formatExtraData: E, +) => JSX.Element | string | boolean | React.ReactText; + +export interface ColumnDescription { + /** + * If set the column will not use cell values + */ + isDummyField?: boolean; + dataField: any; + formatter?: ColumnFormatter; + hidden?: boolean; + /** + * Column header field + */ + text: string; + sort?: boolean; + sortFunc?: ColumnSortFunc; + searchable?: boolean; + align?: CellAlignment; + headerStyle?: React.CSSProperties | (() => React.CSSProperties); + + tooltipDataField?: string; + editable?: boolean | ((cell: any, row: T, rowIndex: number, colIndex: number) => boolean); + editor?: { type: string; options?: [{ value: string; label: string }] }; + filter?: boolean | TableColumnFilterProps; + filterValue?: (cell: T[keyof T], row: T) => string; + headerAlign?: CellAlignment; + headerFormatter?: HeaderFormatter; + formatExtraData?: { + tooltipFormatter?: (row: T) => JSX.Element; + } & E; + width?: number; + footer?: + | boolean + | number + | string + | ((columnData: any, column: ColumnDescription, columnIndex: number) => string); + footerFormatter?: (column: ColumnDescription, columnIndex: number) => void; + footerClasses?: string | ((column: ColumnDescription, columnIndex: number) => string); + footerStyle?: React.CSSProperties; + footerTitle?: boolean; + footerEvents?: { onClick: (e: any, column: ColumnDescription, columnIndex: number) => void }; + footerAlign?: CellAlignment | ((column: ColumnDescription, colIndex: number) => CellAlignment); +} + +/** + * Generic row event handler + */ +export type RowEventHandler = (e: SyntheticEvent, row: T, rowIndex: number) => void; + +/** + * Row level event handlers + */ +export type RowEventHandlerProps = Partial<{ + onClick: RowEventHandler; + onDoubleClick: RowEventHandler; + onMouseEnter: RowEventHandler; + onMouseLeave: RowEventHandler; + onContextMenu: RowEventHandler; +}>; + +/** + * Table change callback method + */ +export type TableChangeHandler = (type: TableChangeType, newState: TableChangeState) => void; + +/** + * All possible pagination options handled by the pagination plugin + * + * Consult [documentation](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/pagination-props.html) + */ +export type PaginationOptions = Partial<{ + custom: boolean; + /** + * Specify the current page. It's necessary when remote is enabled + */ + page: number; + /** + * Specify the size per page. It's necessary when remote is enabled + */ + sizePerPage: number; + /** + * Total data size. It's necessary when remote is enabled + */ + totalSize: number; + /** + * first page will be 0, default is 1 + */ + pageStartIndex: number; + /** + * the pagination bar size, default is 5 + */ + paginationSize: number; + /** + * display pagination information + */ + showTotal: boolean; + /** + * A numeric array is also available: [5, 10]. the purpose of above example is custom the text + */ + sizePerPageList: number[] | Array<{ text: string; value: number }>; + /** + * hide the going to first and last page button + */ + withFirstAndLast: boolean; + /** + * always show the next and previous page button + */ + alwaysShowAllBtns: boolean; + /** + * the text of first page button + */ + firstPageText: string; + /** + * the text of previous page button + */ + prePageText: string; + /** + * the text of next page button + */ + nextPageText: string; + /** + * the text of last page button + */ + lastPageText: string; + /** + * the title of next page button + */ + nextPageTitle: string; + /** + * the title of previous page button + */ + prePageTitle: string; + /** + * the title of first page button + */ + firstPageTitle: string; + /** + * the title of last page button + */ + lastPageTitle: string; + /** + * hide the size per page dropdown + */ + hideSizePerPage: boolean; + /** + * hide pagination bar when only one page, default is false + */ + hidePageListOnlyOnePage: boolean; + /** + * callback function when page was changing + */ + onPageChange: (page: number, sizePerPage: number) => void; + /** + * callback function when page size was changing + */ + onSizePerPageChange: (page: number, sizePerPage: number) => void; + /** + * custom the pagination total + */ + paginationTotalRenderer: (from: number, to: number, size: number) => JSX.Element; +}>; + +export interface SelectRowProps { + mode: RowSelectionType; + clickToSelect?: boolean; + clickToExpand?: boolean; + clickToEdit?: boolean; + hideSelectAll?: boolean; + selected?: Array; + onSelect?: (row: T, isSelected: boolean, rowIndex: number, e: SyntheticEvent) => void | boolean; + /** + * This callback function will be called when select/unselect all and it only work when you configure selectRow.mode as checkbox. + */ + onSelectAll?: (isSelect: boolean, rows: T[], e: React.SyntheticEvent) => void | number[]; + style?: ((row: T, rowIndex: number) => CSSProperties | undefined) | CSSProperties; + classes?: ((row: T, rowIndex: number) => string | undefined) | string; + nonSelectable?: number[]; + nonSelectableStyle?: ((row: T, rowIndex: number) => CSSProperties | undefined) | CSSProperties; + nonSelectableClasses?: ((row: T, rowIndex: number) => string | undefined) | string; + bgColor?: string; + hideSelectColumn?: boolean; + selectionRenderer?: ReactElement<{ mode: string; checked: boolean; disabled: boolean }>; + selectionHeaderRenderer?: ReactElement<{ mode: string; checked: boolean; indeterminate: boolean }>; + headerColumnStyle?: ((status: TableCheckboxStatus) => CSSProperties | undefined) | CSSProperties; + selectColumnStyle?: + | ((props: { + checked: boolean; + disabled: boolean; + rowIndex: number; + rowKey: string; + }) => CSSProperties | undefined) + | CSSProperties; + selectColumnPosition?: 'left' | 'right'; +} + +export interface BootstrapTableRef { + table: { + props: { + data: T[]; + }; + }; + selectionContext?: { + selected?: any[]; + }; + rowExpandContext?: { + state: { + expanded?: any[]; + }; + }; + paginationContext?: { + currPage: number; + currSizePerPage: number; + }; + sortContext?: { + state: { + sortColumn: ColumnDescription; + sortOrder: SortOrder; + }; + }; + filterContext?: { + currFilters: any; + }; + cellEditContext?: { + startEditing: (rowIndex: number, columnIndex: number) => void; + }; +} + +export interface BootstrapTableProps { + /** + * Tells react-bootstrap-table2 which column is unique. + */ + keyField: string; + /** + * Provides data for your table. It accepts a single Array object. + */ + data: any[]; + columns: ColumnDescription[]; + bootstrap4?: boolean; + remote?: boolean | Partial<{ pagination: boolean; filter: boolean; sort: boolean; cellEdit: boolean }>; + noDataIndication?: () => JSX.Element | JSX.Element | string; + striped?: boolean; + bordered?: boolean; + hover?: boolean; + tabIndexCell?: boolean; + id?: string; + classes?: string; + headerClasses?: string; + bodyClasses?: string; + wrapperClasses?: string; + headerWrapperClasses?: string; + condensed?: boolean; + /** + * Same as HTML caption tag, you can set it as String or a React JSX. + */ + caption?: JSX.Element | string; + pagination?: { options?: PaginationOptions }; + filter?: unknown; + cellEdit?: any; + selectRow?: SelectRowProps; + expandRow?: ExpandRowProps; + parentClassName?: string | ((isExpand: boolean, row: T, rowIndex: number) => string); + rowStyle?: ((row: T, rowIndex: number) => CSSProperties) | CSSProperties; + rowEvents?: RowEventHandlerProps; + rowClasses?: ((row: T, rowIndex: number) => string) | string; + filtersClasses?: string; + filterPosition?: FilterPosition; + footerClasses?: string; + defaultSorted?: [{ dataField: any; order: SortOrder }]; + sort?: { + dataField?: any; + order: SortOrder; + sortFunc?: any; + sortCaret?: any; + }; + defaultSortDirection?: SortOrder; + overlay?: any; + onTableChange?: TableChangeHandler; + onSort?: any; + onFilter?: any; + onExternalFilter?: any; + /** + * This callback function will be called only when data size change by search/filter etc. + */ + onDataSizeChange?: (props: { dataSize: number }) => void; + search?: SearchProps | boolean; +} + +declare class BootstrapTable extends Component> {} +export default BootstrapTable; + +/** + * Search props + * + * Consult [documentation](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/search-props.html) + */ +export interface SearchProps { + placeholder?: string; + searchText?: string; + defaultSearch?: string; + /* custom search method, return true if matched and false if not */ + onColumnMatch?: (searchProps: { searchText: string; value: any; column: any; row: T }) => boolean; +} + +export interface ExpandColumnRendererProps { + expanded: boolean; + rowKey: string; + expandable: boolean; +} + +export interface ExpandHeaderColumnRenderer { + isAnyExpands: boolean; +} + +export interface ExpandRowProps { + renderer: (row: T, rowIndex: number) => JSX.Element; + expanded?: number[]; + onExpand?: (row: T, isExpand: boolean, rowIndex: number, e: SyntheticEvent) => void; + onExpandAll: (isExpandAll: boolean, results: number[], e: SyntheticEvent) => void; + nonExpandable: number[]; + showExpandColumn?: boolean; + onlyOneExpanding?: boolean; + expandByColumnOnly?: boolean; + expandColumnRenderer: ReactElement; + expandHeaderColumnRenderer: ReactElement; + expandColumnPosition: 'left' | 'right'; + className: string | ((isExpand: boolean, row: T, rowIndex: number) => string); +} + +export type TableColumnFilterProps = Partial<{ + id: string; + /** + * custom the input placeholder + */ + placeholder: string; + /** + * custom classname on input + */ + className: string; + /** + * default filtering value + */ + defaultValue: any; + + /** + * your custom styles on input + */ + style: React.CSSProperties; + /** + * how long will trigger filtering after user typing, default is 500 ms + */ + delay: number; + /* + * export filter function to allow users to access filter method externally. + */ + getFilter: (filter: FT) => void; + + /** + * Register a listener which will be called when column filter being triggered. If you return an array value, react-bootstrap-table2 will adopt this value as the final filtered result. + */ + onFilter: (filterValue: FT) => void | T[]; +}>; diff --git a/types/react-bootstrap-table-next/react-bootstrap-table-next-tests.tsx b/types/react-bootstrap-table-next/react-bootstrap-table-next-tests.tsx new file mode 100644 index 0000000000..6fd665fbf4 --- /dev/null +++ b/types/react-bootstrap-table-next/react-bootstrap-table-next-tests.tsx @@ -0,0 +1,182 @@ +import * as React from 'react'; +import { render } from 'react-dom'; +import BootstrapTable, { + ColumnFormatter, + CellAlignment, + HeaderFormatter, + ColumnDescription, + RowSelectionType, + ROW_SELECT_SINGLE, +} from 'react-bootstrap-table-next'; + +interface Product { + id: number; + name: string; + price?: number; + quality?: number; + inStockStatus?: number; + sales?: number; +} +const products: Product[] = [ + { + id: 1, + name: 'Item name 1', + price: 100, + }, + { + id: 2, + name: 'Item name 2', + price: 100, + }, +]; + +const priceHeaderFormatter: HeaderFormatter = (column, colIndex, components) => { + return ( +
+ {column.text} + {components.sortElement} + {components.filterElement} +
+ ); +}; + +const priceFormatter: ColumnFormatter = (cell, row, rowIndex) => { + return ( + + {rowIndex} - {cell} + + ); +}; + +const productColumns: Array> = [ + { dataField: 'id', align: 'center', sort: true, text: 'Product ID' }, + { dataField: 'name', align: 'center', sort: true, text: 'Product Name' }, + { + isDummyField: true, + dataField: '', + sort: true, + text: 'Product Name', + }, + { + dataField: 'price', + sort: true, + formatter: priceFormatter, + text: 'Product Price', + headerFormatter: priceHeaderFormatter, + }, + /** + * test optional dataField for dummyFields + */ + { + isDummyField: true, + dataField: '', + sort: true, + formatter: priceFormatter, + text: 'Product Price', + headerFormatter: priceHeaderFormatter, + }, +]; + +/** + * Basic table test with custom header and cell formatters + */ +render( + , + document.getElementById('app'), +); + +/** + * Inline untyped columns test + */ +render( + Dummy Field, + text: 'Dummy Columns', + }, + { + dataField: 'price', + sort: true, + formatter: priceFormatter, + text: 'Product Price', + headerFormatter: priceHeaderFormatter, + }, + /** + * test optional dataField for dummyFields + */ + { + isDummyField: true, + dataField: '', + sort: true, + formatter: priceFormatter, + text: 'Product Price', + headerFormatter: priceHeaderFormatter, + }, + ]} + />, + document.getElementById('app'), +); + +/** + * Basic table with custom data indicator and caption + */ +render( +
No data available
} + caption={Amazing table} + columns={productColumns} + />, + document.getElementById('app'), +); + +/** + * Basic table with custom data indicator and caption + */ +render( + , + document.getElementById('app'), +); + +/** + * Event handling table test + */ +render( + { + typeof row.inStockStatus === 'number'; + }, + onDoubleClick: (e, row, rowIndex) => {}, + onMouseEnter: (e, row, rowIndex) => {}, + onMouseLeave: (e, row, rowIndex) => {}, + }} + keyField="id" + columns={productColumns} + />, + document.getElementById('app'), +); diff --git a/types/react-bootstrap-table-next/tsconfig.json b/types/react-bootstrap-table-next/tsconfig.json new file mode 100644 index 0000000000..304705fd21 --- /dev/null +++ b/types/react-bootstrap-table-next/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6", + "dom" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictFunctionTypes": true, + "strictNullChecks": true, + "baseUrl": "../", + "jsx": "react", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "react-bootstrap-table-next-tests.tsx" + ] +} diff --git a/types/react-bootstrap-table-next/tslint.json b/types/react-bootstrap-table-next/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/react-bootstrap-table-next/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" } diff --git a/types/react-bootstrap-table2-filter/index.d.ts b/types/react-bootstrap-table2-filter/index.d.ts new file mode 100644 index 0000000000..921891e088 --- /dev/null +++ b/types/react-bootstrap-table2-filter/index.d.ts @@ -0,0 +1,148 @@ +// Type definitions for react-bootstrap-table2-filter 1.3 +// Project: https://github.com/react-bootstrap-table/react-bootstrap-table2#readme +// Definitions by: Wlad Meixner +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 3.0 + +// documentation taken from https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/table-props.html + +import { TableColumnFilterProps, ColumnDescription } from 'react-bootstrap-table-next'; +import { CSSProperties, SyntheticEvent } from 'react'; + +export enum FILTER_TYPES { + TEXT = 'TEXT', + SELECT = 'SELECT', + MULTISELECT = 'MULTISELECT', + NUMBER = 'NUMBER', + DATE = 'DATE', +} + +/** + * Filter comparators used for table filters + */ +export enum Comparator { + LIKE = 'LIKE', + EQ = '=', + NE = '!=', + GT = '>', + GE = '>=', + LT = '<', + LE = '<=', +} + +export type TextFilterProps = TableColumnFilterProps & + Partial<{ + /** + * default is false, and true will only work when comparator is LIKE + */ + caseSensitive: boolean; + comparator: Comparator; + /** + * on filter element click event + */ + onClick?: (e: SyntheticEvent) => void; + }>; +/** + * text column filter + * @param props text filter options + */ +export function textFilter(props?: Partial): TableColumnFilterProps; + +/** + * select filter option type + */ +export type SelectFilterOptions = { [index: string]: string } | Array<{ value: number; label: string }>; + +export type SelectFilterProps = TableColumnFilterProps & { + options: SelectFilterOptions | ((column: ColumnDescription) => SelectFilterOptions); + comparator?: Comparator; + /** + * When the default unset selection is hidden from dropdown + */ + withoutEmptyOption?: boolean; +}; + +/** + * single select column filter + * @param props Select filter options + */ +export function selectFilter(props: Partial): TableColumnFilterProps; + +/** + * Datatype that can be used as the multiselect filter option + */ +export interface MultiSelectFilterOptions { + [index: string]: string; +} +/** + * Multi Select filter options + */ +export type MultiSelectFilterProps = TableColumnFilterProps & { + options: MultiSelectFilterOptions | (() => MultiSelectFilterOptions); + comparator?: Comparator; + /** + * When set the default selection is hidden from dropdown + */ + withoutEmptyOption?: boolean; +}; + +/** + * multiSelectFilter adds multi select filtering to a column + * @param props filter options + */ +export function multiSelectFilter(props: Partial): TableColumnFilterProps; + +/** + * Number filter configuration options + */ +export type NumberFilterProps = TableColumnFilterProps & { + options?: number[]; + comparators?: Comparator[]; + /** + * When set to true comparator dropdown does not show a "no selection" option + */ + withoutEmptyComparatorOption?: boolean; + withoutEmptyNumberOption?: boolean; + comparatorClassName?: string; + numberClassName?: string; + comparatorStyle?: CSSProperties; + numberStyle?: CSSProperties; + defaultValue?: { number: number; comparator: Comparator }; +}; + +export function numberFilter(props: Partial): TableColumnFilterProps; + +/** + * Date filter options + */ +export interface DateFilter extends TableColumnFilterProps { + withoutEmptyComparatorOption?: boolean; + defaultValue?: { + date: Date; + comparator: Comparator; + }; + comparator?: Comparator[]; + comparatorClassName?: string; + dateClassName?: string; + comparatorStyle?: CSSProperties; + dateStyle?: CSSProperties; +} + +export function dateFilter(props: DateFilter): TableColumnFilterProps; + +/** + * Custom filter + */ +export interface CustomFilterProps { + type?: string | FILTER_TYPES; + comparator?: Comparator; + caseSensitive?: boolean; +} + +export function customFilter(props: CustomFilterProps): TableColumnFilterProps; + +/** + * declaration for table filter sub module + */ +declare function filterFactory(): unknown; +export default filterFactory; diff --git a/types/react-bootstrap-table2-filter/react-bootstrap-table2-filter-tests.tsx b/types/react-bootstrap-table2-filter/react-bootstrap-table2-filter-tests.tsx new file mode 100644 index 0000000000..55a3136392 --- /dev/null +++ b/types/react-bootstrap-table2-filter/react-bootstrap-table2-filter-tests.tsx @@ -0,0 +1,267 @@ +import * as React from 'react'; +import BootstrapTable, { ColumnDescription, ColumnFormatter, HeaderFormatter } from 'react-bootstrap-table-next'; +import filterFactory, { + Comparator, + multiSelectFilter, + numberFilter, + selectFilter, + textFilter, +} from 'react-bootstrap-table2-filter'; +import { render } from 'react-dom'; + +// examples partially taken from https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/table-props.html +interface Product { + id: number; + name: string; + price?: number; + quality?: number; + inStockStatus?: number; + sales?: number; +} + +const products: Product[] = [ + { + id: 1, + name: 'Item name 1', + price: 100, + quality: 0, + }, + { + id: 2, + name: 'Item name 2', + price: 100, + quality: 1, + }, +]; + +const priceHeaderFormatter: HeaderFormatter = (column, colIndex, components) => { + return ( +
+ {column.text} + {components.sortElement} + {components.filterElement} +
+ ); +}; + +const priceFormatter: ColumnFormatter = (cell, row, rowIndex) => { + return ( + + {rowIndex} - {cell} + + ); +}; + +let priceFilter: any; + +const productColumns: Array> = [ + { dataField: 'id', align: 'center', sort: true, text: 'Product ID' }, + { dataField: 'name', align: 'center', sort: true, text: 'Product Name' }, + { + isDummyField: true, + dataField: '', + sort: true, + text: 'Product Name', + }, + { + dataField: 'price', + sort: true, + formatter: priceFormatter, + text: 'Product Price', + headerFormatter: priceHeaderFormatter, + filter: numberFilter({ + options: [2100, 2103, 2105], // if options defined, will render number select instead of number input + delay: 600, // how long will trigger filtering after user typing, default is 500 ms + placeholder: 'custom placeholder', // placeholder for number input + withoutEmptyComparatorOption: true, // dont render empty option for comparator + withoutEmptyNumberOption: true, // dont render empty option for number select if it is defined + comparators: [Comparator.EQ, Comparator.GT, Comparator.LT], // Custom the comparators + style: { display: 'inline-grid' }, // custom the style on number filter + className: 'custom-numberfilter-class', // custom the class on number filter + comparatorStyle: { backgroundColor: 'antiquewhite' }, // custom the style on comparator select + comparatorClassName: 'custom-comparator-class', // custom the class on comparator select + numberStyle: { backgroundColor: 'cadetblue', margin: '0px' }, // custom the style on number input/select + numberClassName: 'custom-number-class', // custom the class on ber input/select + defaultValue: { number: 2103, comparator: Comparator.GT }, // default value + getFilter: filter => { + // priceFilter was assigned once the component has been mounted. + priceFilter = filter; + }, + onFilter: filterValue => {}, + }), + }, + { + isDummyField: true, + dataField: '', + sort: true, + formatter: priceFormatter, + text: 'Product Price', + headerFormatter: priceHeaderFormatter, + }, +]; + +/** + * Number filter test + */ +render( + , + document.getElementById('app'), +); + +/** + * Options as Object + */ +const selectOptionsObject: { [index: number]: string } = { + 0: 'good', + 1: 'Bad', + 2: 'unknown', +}; + +/** + * Options as Array + */ +const selectOptionsList = [ + { value: 0, label: 'good' }, + { value: 1, label: 'Bad' }, + { value: 2, label: 'unknown' }, +]; + +/** + * Options as Function + */ +const selectOptionsCreator = (column: ColumnDescription) => [ + { value: 0, label: 'good' }, + { value: 1, label: 'Bad' }, + { value: 2, label: 'unknown' }, +]; + +render( + selectOptionsObject[cell], + filter: selectFilter({ + options: selectOptionsObject, + className: 'test-classname', + withoutEmptyOption: true, + defaultValue: 2, + comparator: Comparator.LIKE, // default is Comparator.EQ + style: { backgroundColor: 'pink' }, + getFilter: filter => { + // qualityFilter was assigned once the component has been mounted. + }, + onFilter: filterValue => {}, + }), + }, + ]} + filter={filterFactory()} + />, + document.getElementById('app'), +); +let qualityFilter: any; +render( + cell, + align: 'center', + sort: true, + text: 'Product Name', + }, + { + dataField: 'quality', + text: 'Product Quailty', + formatter: (cell: number, row, rowIndex, formatExtraData) => selectOptionsObject[cell], + filter: multiSelectFilter({ + options: selectOptionsObject, + className: 'test-classname', + withoutEmptyOption: true, + defaultValue: [0, 2], + comparator: Comparator.LIKE, // default is Comparator.EQ + style: { backgroundColor: 'pink' }, + getFilter: filter => { + // qualityFilter was assigned once the component has been mounted. + qualityFilter = filter; + }, + onFilter: filterValue => { + console.log(filterValue); + }, + }), + }, + ]} + filter={filterFactory()} + />, + document.getElementById('app'), +); + +/** + * Single select column test + */ +const selectColumns = [ + { + dataField: 'quality', + text: 'Product Quailty', + formatter: (cell: number) => { + const found = selectOptionsList.find(val => val.value === cell); + return found ? found.value : ''; + }, + filter: selectFilter({ + options: selectOptionsList, + className: 'test-classname', + withoutEmptyOption: true, + defaultValue: 2, + comparator: Comparator.LIKE, // default is Comparator.EQ + style: { backgroundColor: 'pink' }, + getFilter: filter => { + // qualityFilter was assigned once the component has been mounted. + qualityFilter = filter; + }, + onFilter: filterValue => {}, + }), + }, +]; +render( + , + document.getElementById('app'), +); + +/** + * Text filter test + */ +const textColumns = [ + { + dataField: 'id', + text: 'Product ID', + }, + { + dataField: 'name', + text: 'Product Name', + filter: textFilter({ + placeholder: 'My Custom PlaceHolder', // custom the input placeholder + className: 'my-custom-text-filter', // custom classname on input + defaultValue: 'test', // default filtering value + comparator: Comparator.EQ, // default is Comparator.LIKE + caseSensitive: true, // default is false, and true will only work when comparator is LIKE + style: { backgroundColor: 'yellow' }, // your custom inline styles on input + delay: 1000, // how long will trigger filtering after user typing, default is 500 ms + onClick: e => console.log(e), + }), + }, + { + dataField: 'price', + text: 'Product Price', + filter: textFilter(), + }, +]; + +; diff --git a/types/react-bootstrap-table2-filter/tsconfig.json b/types/react-bootstrap-table2-filter/tsconfig.json new file mode 100644 index 0000000000..37927f62f5 --- /dev/null +++ b/types/react-bootstrap-table2-filter/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6", + "dom" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictFunctionTypes": true, + "strictNullChecks": true, + "baseUrl": "../", + "jsx": "react", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "react-bootstrap-table2-filter-tests.tsx" + ] +} diff --git a/types/react-bootstrap-table2-filter/tslint.json b/types/react-bootstrap-table2-filter/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/react-bootstrap-table2-filter/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" } diff --git a/types/react-bootstrap-table2-paginator/index.d.ts b/types/react-bootstrap-table2-paginator/index.d.ts new file mode 100644 index 0000000000..d6659ba11b --- /dev/null +++ b/types/react-bootstrap-table2-paginator/index.d.ts @@ -0,0 +1,49 @@ +// Type definitions for react-bootstrap-table2-paginator 2.1 +// Project: https://github.com/react-bootstrap-table/react-bootstrap-table2#readme +// Definitions by: Wlad Meixner +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 3.0 + +// documentation taken from https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/table-props.html + +import { PaginationOptions, BootstrapTableProps } from 'react-bootstrap-table-next'; + +export interface PaginationCtxOptions { + options?: PaginationOptions; +} + +/** + * declaration for table pagination sub module and factory + */ +declare function paginationFactory(options: PaginationOptions): PaginationCtxOptions; + +export default paginationFactory; + +interface PaginationChildProps extends PaginationOptions { + tableId?: string; + bootstrap4?: boolean; +} + +/** + * Pagination context provider + */ +export function PaginationProvider(props: { + pagination?: PaginationOptions; + children: (childProps: { + paginationProps: PaginationChildProps; + paginationTableProps: BootstrapTableProps; + }) => React.ReactElement | null; +}): React.ReactElement | null; + +export const PaginationTotalStandalone: React.FC; +export const PaginationListStandalone: React.FC; + +export interface SizePerPageDropdownStandaloneProps extends PaginationChildProps { + open?: boolean; + hidden?: boolean; + btnContextual?: boolean; + variation?: 'dropdown' | 'dropup'; + className?: string; +} + +export const SizePerPageDropdownStandalone: React.FC; diff --git a/types/react-bootstrap-table2-paginator/react-bootstrap-table2-paginator-tests.tsx b/types/react-bootstrap-table2-paginator/react-bootstrap-table2-paginator-tests.tsx new file mode 100644 index 0000000000..1c155625ec --- /dev/null +++ b/types/react-bootstrap-table2-paginator/react-bootstrap-table2-paginator-tests.tsx @@ -0,0 +1,91 @@ +import * as React from 'react'; +import BootstrapTable, { + CellAlignment, + ColumnDescription, + HeaderFormatter, + ColumnFormatter, +} from 'react-bootstrap-table-next'; +import paginationFactory from 'react-bootstrap-table2-paginator'; +import { render } from 'react-dom'; + +interface Product { + id: number; + name: string; + price?: number; + quality?: number; + inStockStatus?: number; + sales?: number; +} + +const products: Product[] = [ + { + id: 1, + name: 'Item name 1', + price: 100, + }, + { + id: 2, + name: 'Item name 2', + price: 100, + }, +]; + +const priceHeaderFormatter: HeaderFormatter = (column, colIndex, components) => { + return ( +
+ {column.text} + {components.sortElement} + {components.filterElement} +
+ ); +}; + +const priceFormatter: ColumnFormatter = (cell, row, rowIndex) => { + return ( + + {rowIndex} - {cell} + + ); +}; + +const productColumns: Array> = [ + { dataField: 'id', align: 'center', sort: true, text: 'Product ID' }, + { dataField: 'name', align: 'center', sort: true, text: 'Product Name' }, + { + isDummyField: true, + dataField: '', + sort: true, + text: 'Product Name', + }, + { + dataField: 'price', + sort: true, + formatter: priceFormatter, + text: 'Product Price', + headerFormatter: priceHeaderFormatter, + }, + /** + * test optional dataField for dummyFields + */ + { + isDummyField: true, + dataField: '', + sort: true, + formatter: priceFormatter, + text: 'Product Price', + headerFormatter: priceHeaderFormatter, + }, +]; + +/** + * pagination test + */ +render( + , + document.getElementById('app'), +); diff --git a/types/react-bootstrap-table2-paginator/tsconfig.json b/types/react-bootstrap-table2-paginator/tsconfig.json new file mode 100644 index 0000000000..50b213fe72 --- /dev/null +++ b/types/react-bootstrap-table2-paginator/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6", + "dom" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictFunctionTypes": true, + "strictNullChecks": true, + "baseUrl": "../", + "jsx": "react", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "react-bootstrap-table2-paginator-tests.tsx" + ] +} diff --git a/types/react-bootstrap-table2-paginator/tslint.json b/types/react-bootstrap-table2-paginator/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/react-bootstrap-table2-paginator/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" } diff --git a/types/react-bootstrap-table2-toolkit/index.d.ts b/types/react-bootstrap-table2-toolkit/index.d.ts new file mode 100644 index 0000000000..2ba73d55bb --- /dev/null +++ b/types/react-bootstrap-table2-toolkit/index.d.ts @@ -0,0 +1,120 @@ +// Type definitions for react-bootstrap-table2-toolkit 2.1 +// Project: https://github.com/react-bootstrap-table/react-bootstrap-table2#readme +// Definitions by: Wlad Meixner +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 3.0 + +// documentation taken from https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/table-props.html + +import { CSSProperties, ReactNode } from 'react'; +import { ColumnDescription } from 'react-bootstrap-table-next'; + +/** + * declaration for table toolkit sub module + */ +export interface InjectedSearchProps { + searchText: string; + onSearch: (val: string) => void; + onClear: () => void; +} + +export interface SearchMatchProps { + searchText: string; + value: string; + column: ColumnDescription; + row: T; +} + +export interface TableSearchProps { + searchFormatted?: boolean; + defaultSearch?: string; + placeholder?: string; + onColumnMatch?: (props: SearchMatchProps) => void; + customMatchFunc?: (props: SearchMatchProps) => boolean; +} + +export interface TableToolkitProps { + bootstrap4?: boolean; + search?: TableSearchProps | boolean; + keyField: keyof T | string; + data: T[]; + ref?: any; + columns: Array>; + children: (props: ToolkitContextType) => JSX.Element; +} + +export interface ToolkitContextType { + searchProps: InjectedSearchProps; + csvProps: { + onExport: () => void; + }; + columnToggleProps: { + columns: ColumnDescription[]; + /** + * array of toggled columns + */ + toggles: boolean[]; + onColumnToggle: (dataField: string) => void; + }; + baseProps: { + /** + * table key field + */ + keyField: any; + columns: ColumnDescription[]; + data: any[]; + bootstrap4?: boolean; + }; +} + +export interface ToggleListProps { + columns: ColumnDescription[]; + /** + * array of toggled columns + */ + toggles: boolean[]; + onColumnToggle: (dataField: string) => void; + btnClassName?: string; + className?: string; + contextual?: string; +} + +export namespace ColumnToggle { + function ToggleList(props: ToggleListProps): React.ReactElement | null; +} + +export interface ExportCSVButtonProps { + children: ReactNode; + onExport: () => void; + style?: CSSProperties; + className?: string; +} + +export namespace CSVExport { + function ToggleList(props: ExportCSVButtonProps): React.ReactElement | null; +} + +export interface SearchBarProps { + onSearch: (searchText: string) => void; + className?: string; + placeholder?: string; + style?: CSSProperties; + delay?: number; + searchText?: string; + tableId?: string; +} +export interface ClearSearchButtonProps { + onClear?: () => void; + className?: string; + text?: string; +} + +export namespace Search { + function SearchBar(props: SearchBarProps): React.ReactElement | null; + function ClearSearchButton(props: ExportCSVButtonProps): React.ReactElement | null; +} + +export const ToolkitContext: React.Context; + +declare function ToolkitProvider(props: TableToolkitProps): React.ReactElement | null; +export default ToolkitProvider; diff --git a/types/react-bootstrap-table2-toolkit/react-bootstrap-table2-toolkit-tests.tsx b/types/react-bootstrap-table2-toolkit/react-bootstrap-table2-toolkit-tests.tsx new file mode 100644 index 0000000000..9812c33e7e --- /dev/null +++ b/types/react-bootstrap-table2-toolkit/react-bootstrap-table2-toolkit-tests.tsx @@ -0,0 +1,104 @@ +import * as React from 'react'; +import BootstrapTable, { + CellAlignment, + ColumnDescription, + HeaderFormatter, + ColumnFormatter, +} from 'react-bootstrap-table-next'; +import paginationFactory from 'react-bootstrap-table2-paginator'; +import { render } from 'react-dom'; +import ToolkitProvider, { InjectedSearchProps } from 'react-bootstrap-table2-toolkit'; + +interface Product { + id: number; + name: string; + price?: number; + quality?: number; + inStockStatus?: number; + sales?: number; +} + +const products: Product[] = [ + { + id: 1, + name: 'Item name 1', + price: 100, + }, + { + id: 2, + name: 'Item name 2', + price: 100, + }, +]; + +const priceHeaderFormatter: HeaderFormatter = (column, colIndex, components) => { + return ( +
+ {column.text} + {components.sortElement} + {components.filterElement} +
+ ); +}; + +const priceFormatter: ColumnFormatter = (cell, row, rowIndex) => { + return ( + + {rowIndex} - {cell} + + ); +}; + +const productColumns: Array> = [ + { dataField: 'id', align: 'center', sort: true, text: 'Product ID' }, + { dataField: 'name', align: 'center', sort: true, text: 'Product Name' }, + { + isDummyField: true, + dataField: '', + sort: true, + text: 'Product Name', + }, + { + dataField: 'price', + sort: true, + formatter: priceFormatter, + text: 'Product Price', + headerFormatter: priceHeaderFormatter, + }, + /** + * test optional dataField for dummyFields + */ + { + isDummyField: true, + dataField: '', + sort: true, + formatter: priceFormatter, + text: 'Product Price', + headerFormatter: priceHeaderFormatter, + }, +]; + +/** + * Toolkit with custom search test test + */ + +const CustomSearch = (props: InjectedSearchProps) => { + return ( + + props.onSearch(e.currentTarget.value)} /> + + + ); +}; + +render( + + {({ baseProps, searchProps }) => ( + <> + + + + )} + , + document.getElementById('app'), +); diff --git a/types/react-bootstrap-table2-toolkit/tsconfig.json b/types/react-bootstrap-table2-toolkit/tsconfig.json new file mode 100644 index 0000000000..ae2322dc06 --- /dev/null +++ b/types/react-bootstrap-table2-toolkit/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6", + "dom" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictFunctionTypes": true, + "strictNullChecks": true, + "baseUrl": "../", + "jsx": "react", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "react-bootstrap-table2-toolkit-tests.tsx" + ] +} diff --git a/types/react-bootstrap-table2-toolkit/tslint.json b/types/react-bootstrap-table2-toolkit/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/react-bootstrap-table2-toolkit/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" }