import { isNumber, isUndefined } from 'lodash';
import React, { useEffect, useRef } from 'react';
import { getClassName } from '@react-devui/utils';
import { useContextRequired } from '../../hooks';
import { usePrefixConfig } from '../root';
import { DTableContext } from './Table';
const ZINDEX_CONFIG = {
top: 5,
right: 2,
bottom: 5,
left: 2,
};
export interface DCellProps extends React.TdHTMLAttributes<HTMLTableCellElement> {
dTag: 'th' | 'td';
dWidth: number | string | undefined;
dFixed:
| {
top?: number | string;
right?: number | string;
bottom?: number | string;
left?: number | string;
}
| undefined;
dAlign: 'left' | 'right' | 'center';
dEllipsis: boolean;
dNowrap: boolean;
}
export function DCell(props: DCellProps): JSX.Element | null {
const {
children,
dTag,
dWidth,
dFixed,
dAlign,
dEllipsis,
dNowrap,
...restProps
} = props;
const dPrefix = usePrefixConfig();
const { gFixed, gEllipsis } = useContextRequired(DTableContext);
const cellRef = useRef<HTMLTableCellElement>(null);
const ellipsis = gEllipsis || dEllipsis;
let fixedLeft = false;
let fixedRight = false;
let fixedStyle = {};
if (dFixed) {
fixedStyle = {
...dFixed,
position: 'sticky',
zIndex: (dTag === 'th' ? 1 : 0) + Object.keys(dFixed).reduce((previous, current) => previous + ZINDEX_CONFIG[current], 0),
};
if ('left' in dFixed) {
fixedLeft = true;
}
if ('right' in dFixed) {
fixedRight = true;
}
}
useEffect(() => {
if (cellRef.current && cellRef.current.parentElement) {
let showShadow = false;
if (fixedLeft && gFixed.includes('left')) {
const elsL = cellRef.current.parentElement.querySelectorAll(`.${dPrefix}table__cell--fixed-left`);
if (elsL.item(elsL.length - 1) === cellRef.current) {
showShadow = true;
}
}
if (fixedRight && gFixed.includes('right')) {
const elsR = cellRef.current.parentElement.querySelectorAll(`.${dPrefix}table__cell--fixed-right`);
if (elsR.item(0) === cellRef.current) {
showShadow = true;
}
}
cellRef.current.classList.toggle(`${dPrefix}table__cell--fixed-shadow`, showShadow);
}
});
return React.createElement(
dTag,
{
...restProps,
ref: cellRef,
className: getClassName(restProps.className, `${dPrefix}table__cell`, `${dPrefix}table__cell--${dAlign}`, {
[`${dPrefix}table__cell--fixed-left`]: fixedLeft,
[`${dPrefix}table__cell--fixed-right`]: fixedRight,
[`${dPrefix}table__cell--ellipsis`]: ellipsis,
[`${dPrefix}table__cell--nowrap`]: dNowrap,
}),
style: {
...restProps.style,
...fixedStyle,
width: isUndefined(dWidth) ? undefined : dWidth,
},
},
<div
className={`${dPrefix}table__cell-content`}
style={{
width: isUndefined(dWidth)
? undefined
: `calc(${dWidth + (isNumber(dWidth) ? 'px' : '')} - var(--${dPrefix}table-padding-size) * 2)`,
}}
>
{children}
</div>
);
}