import React, {
CSSProperties,
ThHTMLAttributes,
HTMLAttributes,
TableHTMLAttributes,
TdHTMLAttributes,
FC,
createContext,
useMemo,
useContext,
ReactNode,
} from 'react';
import classnames from 'classnames';
import { Icon } from './Icon';
/**
*
*/
const TableRowContext = createContext<{
header?: boolean;
hasActions?: boolean;
actionsPosition?: number;
sortable?: boolean;
}>({});
const TableContext = createContext<{ sortable?: boolean }>({});
/**
*
*/
export type TableHeaderProps = {
hasActions?: boolean;
actionsPosition?: number;
sortable?: boolean;
children?: ReactNode;
};
/**
*
*/
export const TableHeader: FC = (props) => {
const { hasActions, actionsPosition, sortable: sortable_, children } = props;
const { sortable: tableSortable } = useContext(TableContext);
const sortable = typeof sortable_ !== 'undefined' ? sortable_ : tableSortable;
const ctx = useMemo(
() => ({ header: true, hasActions, actionsPosition, sortable }),
[hasActions, actionsPosition, sortable]
);
return (
{children}
);
};
/**
*
*/
export const TableBody: FC<{ children?: ReactNode }> = ({ children }) => {
const ctx = useMemo(() => ({}), []);
return (
{React.Children.map(children, (child) => (
{child}
))}
);
};
/**
*
*/
export type TableRowProps = {
selected?: boolean;
style?: object;
} & HTMLAttributes;
/**
*
*/
export const TableRow: FC = (props) => {
const { className, selected, style: style_, children, ...rprops } = props;
const {
header,
hasActions,
actionsPosition = 0,
} = useContext(TableRowContext);
let newChildren = React.Children.toArray(children);
if (header && hasActions) {
newChildren = [
...newChildren.slice(0, actionsPosition),
,
...newChildren.slice(actionsPosition),
];
}
const rowClassName = classnames(
className,
header ? 'slds-line-height_reset' : 'slds-hint-parent'
);
const style = selected
? {
...style_,
backgroundColor: '#F8FCF5',
borderLeft: '2px solid #7db450',
}
: style_;
return (
{newChildren}
);
};
/**
*
*/
export type TableHeaderColumnProps = {
className?: string;
width?: string | number;
sortable?: boolean;
resizable?: boolean;
sortDir?: string;
sorted?: boolean;
align?: 'left' | 'center' | 'right';
onSort?: () => void;
} & ThHTMLAttributes;
/**
*
*/
export const TableHeaderColumn: FC = (props) => {
const {
sortable: sortable_,
resizable,
children,
className,
width,
sortDir,
onSort,
sorted,
align,
...pprops
} = props;
const { sortable: rowSortable } = useContext(TableRowContext);
const sortable = typeof sortable_ === 'undefined' ? rowSortable : sortable_;
const oClassNames = classnames(
className,
{
'slds-is-sortable': sortable,
'slds-is-resizable': resizable,
'slds-is-sorted': sorted,
},
align ? `slds-text-align_${align}` : undefined
);
const style = { minWidth: width || 'auto' };
const icon = sortDir === 'DESC' ? 'arrowdown' : 'arrowup';
const content = typeof children === 'string' ? children : undefined;
const cellContent = (
{children}
);
return (
{sortable ? (
{
e.preventDefault();
if (onSort) {
onSort();
}
}}
className='slds-th__action slds-text-link_reset'
>
Sort
{cellContent}
) : (
cellContent
)}
|
);
};
/**
*
*/
export type TableRowColumnProps = {
width?: string | number;
truncate?: boolean;
} & TdHTMLAttributes;
/**
*
*/
export const TableRowColumn: FC = (props) => {
const {
truncate = true,
className: oClassNames,
width,
children,
...pprops
} = props;
const style: CSSProperties = {};
if (width !== undefined) style.width = width;
if (!truncate) style.position = 'static';
const content = typeof children === 'string' ? children : undefined;
const cellContent = truncate ? (
{children}
) : (
children
);
return (
{cellContent}
|
);
};
/**
*
*/
export const TableRowColumnActions: FC<{ children?: ReactNode }> = (props) => (
{props.children}
);
/**
*
*/
export type TableProps = {
bordered?: boolean;
verticalBorders?: boolean;
noRowHover?: boolean;
striped?: boolean;
fixedLayout?: boolean;
sortable?: boolean;
autoWidth?: boolean;
} & TableHTMLAttributes;
/**
*
*/
export const Table: FC = (props) => {
const {
className,
bordered,
verticalBorders,
noRowHover,
striped,
fixedLayout,
autoWidth,
sortable,
children,
style: style_,
...rprops
} = props;
const tableClassNames = classnames(className, 'slds-table', {
'slds-table_bordered': bordered,
'slds-no-row-hover': noRowHover,
'slds-table_striped': striped,
'slds-table_fixed-layout': fixedLayout,
'slds-table_resizable-cols': sortable,
'slds-table_cell-buffer': !sortable,
'slds-table_col-bordered': verticalBorders,
});
const style: CSSProperties = { ...style_ };
if (autoWidth) {
style.width = 'auto';
}
const ctx = useMemo(() => ({ sortable }), [sortable]);
return (
);
};