UNPKG

ar-design

Version:

AR Design is a (react | nextjs) ui library.

168 lines (167 loc) 11.1 kB
import React, { Fragment, memo, useEffect, useRef, useState } from "react"; import { ARIcon } from "../../../icons"; import Checkbox from "../../../form/checkbox"; import Editable from "./Editable"; import { useTranslation } from "../../../../libs/core/application/hooks"; function TBody({ data, columns, refs, methods, states, config }) { // refs const _hasMeasured = useRef(false); const _tBodyTR = useRef([]); const _tHeadTH = useRef([]); // states const [triggerForRender, setTriggerForRender] = useState(false); const [rowHeights, setRowHeights] = useState([]); // variables const _subrowSelector = config.subrow?.selector ?? "subitems"; const _subrowButton = config.subrow?.button ?? true; // hooks const { t } = useTranslation(String(config.locale ?? "tr")); // methods const renderRow = (item, index, deph, parentKey = "") => { const id = methods.trackBy?.(item) ?? index.toString(); const key = parentKey ? `${parentKey}.${id}` : id; const isHasSubitems = _subrowSelector in item; return (React.createElement(Fragment, { key: `row-${index}` }, React.createElement("tr", { ref: (element) => { _tBodyTR.current[index] = element; }, ...(methods.rowBackgroundColor ? { style: { backgroundColor: methods.rowBackgroundColor(item) } } : {}), ...(methods.onDnD && data.length > 1 ? { className: "draggable", draggable: true } : {}) }, methods.selections && (React.createElement("td", { ref: (element) => { _tHeadTH.current[index] = element; }, className: "flex justify-content-center sticky-left", style: { display: "flex", alignItems: "center", height: rowHeights[index] ?? 0 }, "data-sticky-position": "left" }, React.createElement(Checkbox, { key: Date.now(), ref: (element) => { if (!element) return; refs._checkboxItems.current[index] = element; }, variant: "filled", color: "green", checked: refs._selectionItems.current.some((selectionItem) => methods.trackBy?.(selectionItem) === methods.trackBy?.(item)), onChange: (event) => { const key = methods.trackBy?.(item); if (event.target.checked) { if (!refs._selectionItems.current.some((_item) => methods.trackBy?.(_item) === key)) { refs._selectionItems.current = [...refs._selectionItems.current, item]; } } else { refs._selectionItems.current = refs._selectionItems.current.filter((_item) => methods.trackBy?.(_item) !== key); } methods.selections?.(refs._selectionItems.current); setTriggerForRender((prev) => !prev); } }))), isHasSubitems && _subrowButton ? (React.createElement("td", null, item[_subrowSelector] && (React.createElement("div", { className: "subitem-open-button-wrapper" }, React.createElement("span", { className: `subitem-open-button ${(states.showSubitems.get[key] && "opened") ?? ""}`, onClick: () => { states.showSubitems.set((prev) => ({ ...prev, [`${key}`]: !prev[`${key}`], })); } }))))) : isHasSubitems && _subrowButton ? (React.createElement("td", { style: { width: 0, minWidth: 0 } })) : null, columns.map((column, cIndex) => { return renderCell({ item, column, index, cIndex, depth: deph * (config.isTreeView ? 1.75 : 0), level: 0, height: rowHeights[index] ?? 0, }); })), states.showSubitems.get[key] && item[_subrowSelector] && (React.createElement(SubitemList, { items: item[_subrowSelector], columns: columns, index: index, depth: 1.5, parentKey: key })))); }; const renderCell = ({ item, column, index, cIndex, depth, level, height = 0, isSubrows = false }) => { let render; // `column.key` bir string ise if (typeof column.key !== "object") render = column.render ? column.render(item) : item[column.key]; // `column.key` bir nesne ise ve `nestedKey` mevcutsa else if (typeof column.key === "object") { const _item = item[column.key.field]; if (_item && typeof _item === "object") { render = column.render ? column.render(item) : _item[column.key.nestedKey]; } } else render = null; const _className = []; if (column.config?.alignContent) _className.push(`align-content-${column.config.alignContent}`); if (column.config?.sticky) _className.push(`sticky-${column.config.sticky}`); if (column.config?.textWrap) _className.push(`text-${column.config.textWrap}`); return (React.createElement("td", { key: `cell-${index}-${cIndex}`, className: _className.join(" "), style: { ...(column.config?.sticky ? { height } : {}), ...(column.config?.width ? { width: column.config.width, minWidth: column.config.width, maxWidth: column.config.width } : {}), }, "data-sticky-position": column.config?.sticky }, React.createElement("div", { style: { paddingLeft: cIndex === (methods.selections ? 1 : 0) ? `${depth == 0 ? 1 : depth}rem` : "" }, className: "table-cell" }, config.isTreeView && cIndex === 0 && (React.createElement(React.Fragment, null, isSubrows && Array.from({ length: level }).map((_, i) => { if (i > 0) i *= 1.655; return (React.createElement("div", { key: `last-before-${i}`, style: { left: `${i + 0.65}rem` }, className: "last-before" })); }), React.createElement("div", { className: "before" }))), React.isValidElement(render) ? (render) : column.editable && methods.onEditable ? (React.createElement(Editable, { c: column, item: item, trackByValue: methods.trackBy?.(item) ?? "", onEditable: methods.onEditable, config: config })) : (React.createElement("span", null, render)), config.isTreeView && cIndex === 0 && (React.createElement("div", { className: "after" }, React.createElement("div", { className: "circle" })))))); }; const SubitemList = ({ items, columns, index, depth, level = 1, parentKey = "" }) => { if (config.subrow?.render) { return (React.createElement("tr", { className: `subrow-item ${_subrowButton ? "type-b" : "type-a"}`, "data-level": level }, _subrowButton && React.createElement("td", { style: { ...config.subrow.render.styles, width: 0, minWidth: 0 } }), React.createElement("td", { colSpan: columns.length || 1, style: { ...config.subrow.render.styles, padding: "7.5px 7.5px 7.5px 0" } }, config.subrow?.render.element(items) ?? React.createElement(React.Fragment, null)))); } return items.map((subitem, subindex) => { const id = methods.trackBy?.(subitem) ?? subindex.toString(); const key = `${parentKey}.${id}`; const _subitem = subitem[_subrowSelector]; const isHasSubitems = _subrowSelector in subitem; return (React.createElement(Fragment, { key: `subitem-${index}-${subindex}-${Math.random()}` }, React.createElement("tr", { className: `subrow-item ${_subrowButton ? "type-b" : "type-a"}`, "data-level": level }, isHasSubitems && _subrowButton ? (React.createElement("td", null, React.createElement("div", { className: "subitem-open-button-wrapper" }, React.createElement("span", { className: `${(states.showSubitems.get[key] && "opened") ?? ""} ${!_subitem && "passive"}`, onClick: () => { if (!_subitem) return; states.showSubitems.set((prev) => ({ ...prev, [key]: !prev[key], })); } })))) : !isHasSubitems && _subrowButton ? (React.createElement("td", { style: { width: 0, minWidth: 0 } })) : null, !config.subrow?.render ? (columns.map((column, cIndex) => renderCell({ item: subitem, column, index, cIndex, depth: depth * (config.isTreeView ? 2.25 : 1.75), level, height: 0, isSubrows: true, }))) : (React.createElement("td", { colSpan: columns.length || 1 }, config.subrow?.render.element(items) ?? React.createElement(React.Fragment, null)))), states.showSubitems.get[key] && _subitem && (React.createElement(SubitemList, { items: _subitem, columns: columns, index: subindex, depth: depth + 0.75, level: level + 1, parentKey: key })))); }); }; // useEffects useEffect(() => { if (_hasMeasured.current) return; if (!data || data.length === 0) return; const heights = _tBodyTR.current.map((el) => (el ? el.getBoundingClientRect().height : 0)); setRowHeights(heights); setTriggerForRender((prev) => !prev); _hasMeasured.current = true; }, [data]); useEffect(() => { if (Array.isArray(refs._checkboxItems.current) && refs._checkboxItems.current.length > 0) { const allChecked = refs._checkboxItems.current.every((item) => item?.checked === true); states.setSelectAll.set(allChecked); } }, [triggerForRender]); return data.length > 0 ? (data.map((item, index) => React.createElement(React.Fragment, { key: index }, renderRow(item, index, 1)))) : (React.createElement("tr", null, React.createElement("td", { colSpan: columns.length || 1 }, React.createElement("div", { className: "no-item" }, React.createElement(ARIcon, { icon: "Inbox-Fill", fill: "var(--gray-300)", size: 64, style: { position: "relative", zIndex: 1 } }), React.createElement("span", null, t("Table.Body.NoData.Text")))))); } export default memo(TBody);