import '@material/mwc-icon-button-toggle'; import type {Cash} from 'cash-dom'; import type { Children, Vnode, VnodeDOM } from 'mithril'; import Component from '../Component'; import Mdi from '../Mdi'; declare global { namespace JSX { interface IntrinsicElements { TableColumn: TableColumn; } } } type Attributes = { type?: 'numeric' | 'checkbox', id?: string, sortable?: boolean, filterable?: boolean, }; export default class TableColumn extends Component { view(vnode: Vnode) { this.attrs.addClassNames('mdc-data-table__header-cell', { [`mdc-data-table__header-cell--${this.attrs.get( 'type' ) as string}`]: this.attrs.has('type') }); let {children}: {children?: Children} = vnode; if (this.attrs.has('sortable')) { this.attrs.addClassNames('mdc-data-table__header-cell--with-sort'); this.attrs .put('aria-sort', 'none') .put('data-column-id', this.attrs.get('id')); children = (
 
{children}
); } if (( (!children || (Array.isArray(children) && children.length === 0)) && this.attrs.get('type') === 'checkbox' )) { children = ; } if (this.attrs.get('type') !== 'checkbox' && this.attrs.has('filterable')) { children = ( <> {children}
); } return ( {children} ); } oncreate(vnode: VnodeDOM) { super.oncreate(vnode); if (this.attrs.get('type') === 'checkbox') { const checkbox = $(this.element).children( '.mdc-data-table__header-row-checkbox' ); checkbox.on('change', this.onCheckboxClicked.bind(this)); } // Handle click on a column (add arrows) const observer = new MutationObserver(this.onClassChanged.bind(this)); observer.observe(this.element, { attributes: true, attributeFilter: ['class'] }); $(this.element) .find('.mdc-data-table__filter-textfield') .on('input', this.onFilterInput.bind(this)); } onCheckboxClicked(event: Event) { const row: Cash = $(this.element) .closest('table') .find('tbody tr[checkable]'); const selectedClass = 'mdc-data-table__row--selected'; const checkbox = event.target as HTMLInputElement; row.toggleClass(selectedClass, checkbox.checked); row.find('mwc-checkbox').prop('checked', checkbox.checked); } onClassChanged(mutations: MutationRecord[]) { for (const mutation of mutations) { const {classList} = mutation.target as HTMLElement; const ascendingClass = 'mdc-data-table__header-cell--sorted'; const descendingClass = 'mdc-data-table__header-cell--sorted-descending'; const onValue = classList.contains(descendingClass); const button: Cash = $(this.element).find('mwc-icon-button-toggle'); button.prop('on', onValue); if ( classList.contains(ascendingClass) || classList.contains(descendingClass) ) { $(this.element).css('cursor', 'auto'); button.show(); } else if ( !classList.contains(ascendingClass) && !classList.contains(descendingClass) ) { $(this.element).css('cursor', 'pointer'); button.hide(); } } } onFilterInput(event: InputEvent) { const index = $(this.element).index(); const rows: Cash = $(this.element).closest('table').find('tbody tr'); const {value} = event.target as HTMLInputElement; rows.hide(); rows .filter( (index_, element) => $(element) .find(`td:nth-child(${index + 1})`) .text() .search(value) !== -1 ) .show(); } }