UNPKG

@etsoo/materialui

Version:

TypeScript Material-UI Implementation

110 lines (109 loc) 4.67 kB
import { jsx as _jsx } from "react/jsx-runtime"; import { css } from "@emotion/css"; import { ScrollerList } from "@etsoo/react"; import { Utils } from "@etsoo/shared"; import React from "react"; import { GridUtils } from "./GridUtils"; import { listCacheKeyGenerator, useListCacheInitLoad } from "./uses/useListCacheInitLoad"; import Box from "@mui/material/Box"; // Scroll bar size const scrollbarSize = 16; // Selected class name const selectedClassName = "ScrollerListEx-Selected"; const createGridStyle = (alternatingColors, selectedColor) => { return css({ "& .ScrollerListEx-Selected": { backgroundColor: selectedColor }, "& .ScrollerListEx-Row0:not(.ScrollerListEx-Selected)": { backgroundColor: alternatingColors[0] }, "& .ScrollerListEx-Row1:not(.ScrollerListEx-Selected)": { backgroundColor: alternatingColors[1] }, "@media (min-width: 800px)": { "::-webkit-scrollbar": { width: scrollbarSize, height: scrollbarSize, backgroundColor: "#f6f6f6" }, "::-webkit-scrollbar-thumb": { backgroundColor: "rgba(0,0,0,0.4)", borderRadius: "2px" }, "::-webkit-scrollbar-track-piece:start": { background: "transparent" }, "::-webkit-scrollbar-track-piece:end": { background: "transparent" } } }); }; /** * Default styles for item renderer */ export const ScrollerListExItemDefaultStyles = { height: `calc(100% - 16px)`, /** * default rowHeight is 150px when 16px margin top/bottom */ marginTop: "8px", marginBottom: "8px", overflow: "auto" }; /** * Extended ScrollerList * @param props Props * @returns Component */ export function ScrollerListEx(props) { // Selected item ref const selectedItem = React.useRef(null); const onMouseDown = (div, data) => { // Destruct const [selectedDiv, selectedData] = selectedItem.current ?? []; if (selectedData != null && selectedData[idField] === data[idField]) return; selectedDiv?.classList.remove(selectedClassName); div.classList.add(selectedClassName); selectedItem.current = [div, data]; if (onSelectChange) onSelectChange([data]); }; const isSelected = (data) => { const [_, selectedData] = selectedItem.current ?? []; const selected = selectedData && data && selectedData[idField] === data[idField] ? true : false; return selected; }; // Destruct const { alternatingColors = [undefined, undefined], className, cacheKey, cacheMinutes = 15, idField = "id", itemRenderer = ({ data }) => (_jsx(Box, { component: "pre", sx: ScrollerListExItemDefaultStyles, children: JSON.stringify(data) })), onClick, onDoubleClick, onUpdateRows, onSelectChange, rowHeight = 150, selectedColor = "#edf4fb", ...rest } = props; // Init handler const initHandler = useListCacheInitLoad(cacheKey, cacheMinutes); const onUpdateRowsHandler = React.useCallback((rows, state, reset) => { GridUtils.getUpdateRowsHandler(cacheKey)?.(rows, state); onUpdateRows?.(rows, state, reset); if (cacheKey && reset) { sessionStorage.removeItem(listCacheKeyGenerator(cacheKey)); } }, [onUpdateRows, cacheKey]); // Layout return (_jsx(ScrollerList, { className: Utils.mergeClasses("ScrollerListEx-Body", className, createGridStyle(alternatingColors, selectedColor)), idField: idField, onRowsRendered: cacheKey ? (visibleRows) => sessionStorage.setItem(listCacheKeyGenerator(cacheKey), JSON.stringify(visibleRows)) : undefined, onInitLoad: initHandler, onUpdateRows: onUpdateRowsHandler, rowComponent: (cellProps) => { const { index, style, items } = cellProps; const data = items[index]; const selected = isSelected(data); const rowClass = `ScrollerListEx-Row${index % 2}${selected ? ` ${selectedClassName}` : ""}`; // Child const child = itemRenderer({ index, data, style, selected }); return (_jsx("div", { className: rowClass, style: style, onMouseDown: (event) => onMouseDown(event.currentTarget, data), onClick: (event) => onClick && onClick(event, data), onDoubleClick: (event) => onDoubleClick && onDoubleClick(event, data), children: child })); }, rowHeight: rowHeight, ...rest })); }