import React, { useEffect, useLayoutEffect, useRef, useState } from 'react';
import { isEqual, truncate } from 'lodash';
import { RecordInstance, AttributeField } from 'wdk-client/Utils/WdkModel';
import { safeHtml, wrappable } from 'wdk-client/Utils/ComponentUtils';
import { Tooltip } from '@veupathdb/components/lib/components/widgets/Tooltip';
import { useIsRefOverflowingHorizontally } from 'wdk-client/Hooks/Overflow';
interface AttributeCellProps {
attribute: AttributeField;
recordInstance: RecordInstance;
}
function AttributeCell(props: AttributeCellProps) {
const { attribute, recordInstance } = props;
const attributeValue = recordInstance.attributes[attribute.name];
const key = typeof attributeValue === 'string' ? attributeValue : attributeValue?.displayText || attributeValue?.url || '';
return ;
}
function AttributeCellInner({
attribute,
recordInstance,
}: AttributeCellProps) {
const value = recordInstance.attributes[attribute.name];
const defaultStyleSpec: React.CSSProperties = {
whiteSpace: 'nowrap',
maxWidth: `${attribute.truncateTo}ch`,
};
const ref = useRef(null);
const [ styleSpec, setStyleSpec ] = useState(defaultStyleSpec);
const isOverflowing = useIsRefOverflowingHorizontally(ref);
useLayoutEffect(() => {
if (!ref.current) return;
if (
ref.current.innerText.length > attribute.truncateTo &&
isEqual(styleSpec, defaultStyleSpec) &&
isOverflowing
) {
setStyleSpec({
...defaultStyleSpec,
overflow: 'hidden',
textOverflow: 'ellipsis',
})
}
});
useEffect(() => {
setStyleSpec(defaultStyleSpec)
}, [value]);
if (value == null) return null;
if (typeof value === 'string') {
const cellContent =
safeHtml(value, {
style: styleSpec,
ref,
}, 'div');
return !('overflow' in styleSpec) ? cellContent : {cellContent}
}
const { url, displayText } = value;
const display = displayText || url;
const truncatedDisplay = truncateValue(display, attribute.truncateTo);
return (
);
}
export default wrappable(AttributeCell);
function truncateValue(value: string, length: number) {
return length ? truncate(value, { length }) : value;
}