DocSpace-client/packages/shared/components/row/Row.tsx

215 lines
5.6 KiB
TypeScript

import React, { useRef } from "react";
import { isMobile } from "react-device-detect"; // TODO: isDesktop=true for IOS(Firefox & Safari)
import { isMobile as isMobileUtils } from "../../utils/device";
import { Checkbox } from "../checkbox";
import {
ContextMenuButton,
ContextMenuButtonDisplayType,
} from "../context-menu-button";
import { ContextMenu } from "../context-menu";
import { Loader, LoaderTypes } from "../loader";
import {
StyledOptionButton,
StyledContentElement,
StyledElement,
StyledCheckbox,
StyledContent,
StyledRow,
} from "./Row.styled";
import { RowProps } from "./Row.types";
const Row = (props: RowProps) => {
const {
checked,
children,
contentElement,
contextButtonSpacerWidth = "26px",
data,
element,
indeterminate,
onSelect,
onRowClick,
onContextClick,
getContextModel,
isRoom,
withoutBorder = false,
contextTitle,
badgesComponent,
isArchive,
mode = "default",
inProgress,
rowContextClose,
className,
} = props;
const cm = useRef<null | {
show: (e: React.MouseEvent | MouseEvent) => void;
hide: (
e:
| React.MouseEvent
| MouseEvent
| Event
| React.ChangeEvent<HTMLInputElement>,
) => void;
menuRef: { current: HTMLDivElement };
}>(null);
const row = useRef<null | HTMLDivElement>(null);
const renderCheckbox = Object.prototype.hasOwnProperty.call(props, "checked");
const renderElement = Object.prototype.hasOwnProperty.call(props, "element");
const renderContentElement = Object.prototype.hasOwnProperty.call(
props,
"contentElement",
);
const contextData = data?.contextOptions ? data : props;
const renderContext =
Object.prototype.hasOwnProperty.call(contextData, "contextOptions") &&
contextData &&
contextData.contextOptions &&
contextData.contextOptions.length > 0;
const changeCheckbox = () => {
onSelect?.(!checked, data);
};
const getOptions = () => {
onContextClick?.();
return contextData.contextOptions || [];
};
const onContextMenu = (e: React.MouseEvent) => {
onContextClick?.(e.button === 2);
if (!cm.current?.menuRef.current) {
if (row.current) row.current.click(); // TODO: need fix context menu to global
}
if (cm.current) cm.current.show(e);
};
let contextMenuHeader = {
title: "",
icon: "",
avatar: "",
color: "",
};
if (React.isValidElement(children) && children.props.item) {
contextMenuHeader = {
icon: children.props.item.icon,
avatar: children.props.item.avatar,
title: children.props.item.title
? children.props.item.title
: children.props.item.displayName || "",
color: children.props.item.logo?.color,
};
}
const onElementClick = () => {
if (!isMobile) return;
onSelect?.(true, data);
};
return (
<StyledRow
ref={row}
// {...rest}
mode={mode}
onContextMenu={onContextMenu}
withoutBorder={withoutBorder}
data-testid="row"
checked={checked}
className={className}
>
{inProgress ? (
<Loader
className="row-progress-loader"
type={LoaderTypes.oval}
size="16px"
/>
) : (
<>
{mode === "default" && renderCheckbox && (
<StyledCheckbox mode={mode} className="not-selectable">
<Checkbox
className="checkbox"
isChecked={checked}
isIndeterminate={indeterminate}
onChange={changeCheckbox}
/>
</StyledCheckbox>
)}
{mode === "modern" && renderCheckbox && renderElement && (
<StyledCheckbox
className="not-selectable styled-checkbox-container"
mode={mode}
>
<StyledElement
onClick={onElementClick}
className="styled-element"
>
{element}
</StyledElement>
<Checkbox
className="checkbox"
isChecked={checked}
isIndeterminate={indeterminate}
onChange={changeCheckbox}
/>
</StyledCheckbox>
)}
{mode === "default" && renderElement && (
<StyledElement onClick={onRowClick} className="styled-element">
{element}
</StyledElement>
)}
</>
)}
<StyledContent onClick={onRowClick} className="row_content">
{children}
</StyledContent>
<StyledOptionButton
className="row_context-menu-wrapper"
spacerWidth={contextButtonSpacerWidth}
>
{badgesComponent && badgesComponent}
{renderContentElement && (
<StyledContentElement>{contentElement}</StyledContentElement>
)}
{renderContext ? (
<ContextMenuButton
isFill
className="expandButton"
getData={getOptions}
directionX="right"
displayType={ContextMenuButtonDisplayType.toggle}
onClick={onContextMenu}
title={contextTitle}
/>
) : (
<div className="expandButton"> </div>
)}
<ContextMenu
getContextModel={getContextModel}
model={contextData.contextOptions || []}
ref={cm}
header={contextMenuHeader}
withBackdrop={isMobileUtils()}
onHide={rowContextClose}
isRoom={isRoom}
isArchive={isArchive}
/>
</StyledOptionButton>
</StyledRow>
);
};
export { Row };