UNPKG

@coreui/vue-pro

Version:

UI Components Library for Vue.js

282 lines (264 loc) 10.1 kB
import { computed, defineComponent, h, PropType, ref, watch } from 'vue' import { CFormInput } from '../form/' import { CTableFoot, CTableHead, CTableHeaderCell, CTableRow } from '../table/' import { getColumnKey, getColumnLabel, getColumnGroups, getColumns, getColumnSorterState, getColumnValues, getTableHeaderCellProps, getTableHeaderCellStyles, } from './utils' import type { Column, ColumnFilter, ColumnFilterValue, Item, Sorter, SorterValue } from './types' const CSmartTableHead = defineComponent({ name: 'CSmartTableHead', props: { as: { type: String, default: 'head', }, columnFilter: [Boolean, Object] as PropType<boolean | ColumnFilter>, columnFilterValue: Object as PropType<ColumnFilterValue>, columnSorter: [Boolean, Object] as PropType<boolean | Sorter>, columns: { type: Array as PropType<(Column | string)[]>, default: () => [], }, items: { type: Array as PropType<Item[]>, default: () => [], }, selectable: Boolean, selectAll: [Boolean, Object] as PropType<boolean | { external?: boolean }>, selectedAll: [Boolean, String], showGroups: { type: Boolean, default: true, }, sorterState: { type: Array as PropType<SorterValue[]>, default: () => [], } }, emits: ['customFilterChange', 'filterInput', 'filterChange', 'selectAllChecked', 'sortClick'], setup(props, { slots, emit }) { const selectedAll = ref() const seleactAllCheckboxRef = ref<HTMLInputElement>() const columns = computed(() => getColumns(props.columns)) const groups = computed(() => getColumnGroups(props.columns)) watch( () => props.selectedAll, () => { selectedAll.value = props.selectedAll }, { immediate: true, }, ) watch([selectedAll, seleactAllCheckboxRef], () => { if (seleactAllCheckboxRef.value && props.selectedAll === true) { seleactAllCheckboxRef.value.indeterminate = false seleactAllCheckboxRef.value.checked = true return } if (seleactAllCheckboxRef.value && props.selectedAll === 'indeterminate') { seleactAllCheckboxRef.value.checked = false seleactAllCheckboxRef.value.indeterminate = true return } if (seleactAllCheckboxRef.value) { seleactAllCheckboxRef.value.indeterminate = false seleactAllCheckboxRef.value.checked = false } }) const columnSorterIcon = (column: Column | string) => { if (getColumnSorterState(getColumnKey(column), props.sorterState) === 0) { return h( 'span', { class: 'opacity-25 float-end me-1' }, slots.sortingIcon && slots.sortingIcon(), ) } if (getColumnSorterState(getColumnKey(column), props.sorterState) === 'asc') { return h( 'span', { class: 'float-end me-1' }, slots.sortingIconAscending && slots.sortingIconAscending(), ) } if (getColumnSorterState(getColumnKey(column), props.sorterState) === 'desc') { return h( 'span', { class: 'float-end me-1' }, slots.sortingIconDescending && slots.sortingIconDescending(), ) } return } return () => h( props.as === 'head' ? CTableHead : CTableFoot, {}, { default: () => [ props.showGroups && groups.value && groups.value.length > 0 && groups.value.map((row) => [ h(CTableRow, {}, () => [ props.selectable && h(CTableHeaderCell), row.map((cell) => h( CTableHeaderCell, { colspan: cell.colspan, ...getTableHeaderCellProps(cell), }, () => cell.label, ), ), ]), ]), h( CTableRow, {}, { default: () => [ props.selectable && h(CTableHeaderCell, {}, () => h('input', { class: 'form-check-input', type: 'checkbox', ref: seleactAllCheckboxRef, onClick: () => { if (selectedAll.value !== 'reset') { selectedAll.value = 'reset' } else { selectedAll.value = '' } emit('selectAllChecked') }, }), ), columns.value.map((column, index: number) => { const isSortable = props.columnSorter && (typeof column === 'object' ? column.sorter === undefined ? true : column.sorter : true) return h( CTableHeaderCell, { ...getTableHeaderCellProps(column), style: getTableHeaderCellStyles(column, props.columnSorter), ...(isSortable && { tabindex: 0, onClick: () => emit('sortClick', getColumnKey(column), index), onKeydown: (event: KeyboardEvent) => { if (event.key === 'Enter') { emit('sortClick', getColumnKey(column), index) } if (event.key === 'ArrowUp') { event.preventDefault() emit('sortClick', getColumnKey(column), index, 'asc') } if (event.key === 'ArrowDown') { event.preventDefault() emit('sortClick', getColumnKey(column), index, 'desc') } }, }), }, { default: () => [ h( 'div', { class: 'd-inline', }, getColumnLabel(column), ), props.columnSorter && (typeof column === 'object' ? typeof column.sorter === 'undefined' ? true : column.sorter : true) && columnSorterIcon(column), ], }, ) }), ], }, ), props.columnFilter && h( CTableRow, {}, { default: () => [ props.selectable && h(CTableHeaderCell), columns.value.map((column: Column | string) => { return h( CTableHeaderCell, { ...getTableHeaderCellProps(column), }, { default: () => ( typeof column === 'object' ? column.filter === undefined ? true : column.filter : true ) ? typeof column !== 'string' && typeof column.filter === 'function' ? column.filter( getColumnValues(props.items, getColumnKey(column)), (value: any) => { emit('customFilterChange', getColumnKey(column), value) }, ) : h(CFormInput, { size: 'sm', onInput: (event: Event) => { emit( 'filterInput', getColumnKey(column), (event.target as HTMLInputElement).value, ) }, onChange: (event: Event) => { emit( 'filterChange', getColumnKey(column), (event.target as HTMLInputElement).value, ) }, 'aria-label': `column name: '${getColumnLabel( column, )}' filter input`, ...(props.columnFilterValue && props.columnFilterValue[getColumnKey(column)] && { value: props.columnFilterValue[getColumnKey(column)], }), }) : '', }, ) }), ], }, ), ], }, ) }, }) export { CSmartTableHead }