62 lines
1.9 KiB
TypeScript
62 lines
1.9 KiB
TypeScript
|
import { Component, JSX, Show } from 'solid-js'
|
|||
|
import { SortField, useTableSort } from '../context/sort'
|
|||
|
import { useI18n } from '../intl/i18n'
|
|||
|
import styles from '../styles/Table.module.css'
|
|||
|
|
|||
|
/**
|
|||
|
* Свойства компонента SortableHeader
|
|||
|
*/
|
|||
|
interface SortableHeaderProps {
|
|||
|
field: SortField
|
|||
|
children: JSX.Element
|
|||
|
allowedFields?: SortField[]
|
|||
|
class?: string
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Компонент сортируемого заголовка таблицы
|
|||
|
* Отображает заголовок с возможностью сортировки при клике
|
|||
|
*/
|
|||
|
const SortableHeader: Component<SortableHeaderProps> = (props) => {
|
|||
|
const { handleSort, getSortIcon, sortState, isFieldAllowed } = useTableSort()
|
|||
|
const { tr } = useI18n()
|
|||
|
|
|||
|
const isActive = () => sortState().field === props.field
|
|||
|
const isAllowed = () => isFieldAllowed(props.field, props.allowedFields)
|
|||
|
|
|||
|
const handleClick = () => {
|
|||
|
if (isAllowed()) {
|
|||
|
handleSort(props.field, props.allowedFields)
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return (
|
|||
|
<th
|
|||
|
class={`${styles.sortableHeader} ${props.class || ''} ${!isAllowed() ? styles.disabledHeader : ''}`}
|
|||
|
data-active={isActive()}
|
|||
|
onClick={handleClick}
|
|||
|
onKeyDown={(e) => {
|
|||
|
if ((e.key === 'Enter' || e.key === ' ') && isAllowed()) {
|
|||
|
e.preventDefault()
|
|||
|
handleClick()
|
|||
|
}
|
|||
|
}}
|
|||
|
tabindex={isAllowed() ? 0 : -1}
|
|||
|
data-sort={isActive() ? (sortState().direction === 'asc' ? 'ascending' : 'descending') : 'none'}
|
|||
|
style={{
|
|||
|
cursor: isAllowed() ? 'pointer' : 'not-allowed',
|
|||
|
opacity: isAllowed() ? 1 : 0.6
|
|||
|
}}
|
|||
|
>
|
|||
|
<span class={styles.headerContent}>
|
|||
|
{typeof props.children === 'string' ? tr(props.children as string) : props.children}
|
|||
|
<Show when={isAllowed()}>
|
|||
|
<span class={styles.sortIcon}>{getSortIcon(props.field)}</span>
|
|||
|
</Show>
|
|||
|
</span>
|
|||
|
</th>
|
|||
|
)
|
|||
|
}
|
|||
|
|
|||
|
export default SortableHeader
|