import { h, createContext, type FunctionComponent } from 'preact' import { useCallback, useContext } from 'preact/hooks' import cn from 'classnames' import { camelCase } from 'lowline' import s from './table.module.scss' export type onSortByFunction = (column: string | null) => void | Promise const TableContext = createContext<{ sortBy: (e: Event) => void; sortedBy: [string, boolean?] } | null>(null) type TableProps = { className?: string defaultSort?: string onSortBy?: onSortByFunction sortedBy?: string } export const Table: FunctionComponent = ({ children, className, defaultSort = 'id', onSortBy, sortedBy, }) => { const sortBy = useCallback( (e: Event) => { e.preventDefault() // @ts-ignore const { sortBy } = e.currentTarget.dataset const newSortBy = sortBy === sortedBy ? '-' + sortBy : sortBy onSortBy?.(newSortBy === defaultSort ? null : newSortBy) }, [onSortBy, sortedBy], ) sortedBy ??= defaultSort const desc = sortedBy.startsWith('-') return ( {children}
) } export const Td: FunctionComponent<{ className?: string buttons?: boolean minimize?: boolean }> = ({ children, className, buttons, minimize }) => ( {buttons ?
{children}
: children} ) export const Th: FunctionComponent<{ children: string className?: string scope?: 'col' | 'row' | 'colgroup' | 'rowgroup' sort?: string | boolean }> = ({ children, className, scope, sort }) => { const column = typeof sort === 'string' ? sort : camelCase(children) const { sortBy, sortedBy } = useContext(TableContext)! return ( {sort ? ( {children}
) : ( children )} ) }