UNPKG

@etsoo/materialui

Version:

TypeScript Material-UI Implementation

231 lines (230 loc) 8.58 kB
import { createElement as _createElement } from "react"; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import React from "react"; import { MUGlobal } from "./MUGlobal"; import { useCurrentBreakpoint } from "./useCurrentBreakpoint"; import { GridDataFormat } from "./GridDataFormat"; import { useRequiredAppContext } from "./app/ReactApp"; import Grid from "@mui/material/Grid"; import Typography from "@mui/material/Typography"; function formatItemData(app, fieldData) { if (fieldData == null) return undefined; if (typeof fieldData === "string") return fieldData; if (fieldData instanceof Date) return app.formatDate(fieldData, "d"); if (Array.isArray(fieldData)) return fieldData.join(", "); return `${fieldData}`; } function getResp(singleRow) { const size = typeof singleRow === "object" ? singleRow : singleRow === "medium" ? ViewPageSize.medium : singleRow === "large" ? ViewPageSize.large : singleRow === true ? ViewPageSize.line : singleRow === false ? ViewPageSize.smallLine : ViewPageSize.small; return size; } function addLabelEnd(label) { return label + ":"; } function getItemField(app, field, data) { // Item data and label let itemData, itemLabel, gridProps = {}, size, isHorizontal; if (Array.isArray(field)) { const [fieldData, fieldType, renderProps, singleRow = "small"] = field; itemData = GridDataFormat(data[fieldData], fieldType, renderProps); itemLabel = addLabelEnd(app.get(fieldData) ?? fieldData); size = getResp(singleRow); gridProps = { size }; } else if (typeof field === "object") { // Destruct const { data: fieldData, dataType, label: fieldLabel, renderProps, singleRow = "default", horizontal, ...rest } = field; // Horizontal or not isHorizontal = horizontal; // Size size = getResp(singleRow); gridProps = { ...rest, size }; // Field data if (typeof fieldData === "function") itemData = fieldData(data); else if (dataType == null) itemData = formatItemData(app, data[fieldData]); else itemData = GridDataFormat(data[fieldData], dataType, renderProps); // Field label itemLabel = fieldLabel === "" ? undefined : fieldLabel == null && typeof fieldData === "string" ? addLabelEnd(app.get(fieldData) ?? fieldData) : typeof fieldLabel === "function" ? fieldLabel(data) : fieldLabel != null ? addLabelEnd(app.get(fieldLabel) ?? fieldLabel) : undefined; } else { // Single field format itemData = formatItemData(app, data[field]); itemLabel = addLabelEnd(app.get(field) ?? field); size = ViewPageSize.small; gridProps = { size }; } return [itemData, itemLabel, gridProps, size, isHorizontal]; } function getItemSize(bp, size) { const v = size[bp]; if (v != null) return v; const index = breakpoints.indexOf(bp); for (let i = index; i >= 0; i--) { const v = size[breakpoints[i]]; if (v != null) return v; } return 12; } const breakpoints = ["xs", "sm", "md", "lg", "xl"]; /** * View page grid item size */ export var ViewPageSize; (function (ViewPageSize) { ViewPageSize.large = { xs: 12, sm: 12, md: 9, lg: 6, xl: 4 }; ViewPageSize.medium = { xs: 12, sm: 12, md: 6, lg: 4, xl: 3 }; ViewPageSize.line = { xs: 12, sm: 12, md: 12, lg: 12, xl: 12 }; ViewPageSize.small = { xs: 6, sm: 6, md: 4, lg: 3, xl: 2 }; ViewPageSize.smallLine = { xs: 12, sm: 6, md: 4, lg: 3, xl: 2 }; function matchSize(size) { return Object.fromEntries(Object.entries(size).map(([key, value]) => [ key, value == null ? undefined : value === 12 ? 12 : 12 - value ])); } ViewPageSize.matchSize = matchSize; })(ViewPageSize || (ViewPageSize = {})); /** * View page grid item * @param props Props * @returns Result */ export function ViewPageGridItem(props) { // Destruct const { data, label, singleRow, horizontal = false, ...gridProps } = props; // Default options let options = {}; if (gridProps.size == null) { options = getResp(singleRow ?? "small"); } else if (singleRow != null) { options = getResp(singleRow ?? "small"); } // Layout return (_jsxs(Grid, { ...gridProps, ...options, children: [label != null && (_jsx(Typography, { variant: "caption", component: horizontal ? "span" : "div", children: label })), typeof data === "object" ? (data) : horizontal ? (_jsx(Typography, { variant: "subtitle2", component: "span", marginLeft: 0.5, children: data })) : (_jsx(Typography, { variant: "subtitle2", children: data }))] })); } export function ViewContainer(props) { // Global app const app = useRequiredAppContext(); // Destruct const { data, fields, gridRef, leftContainer, leftContainerLines = 3, leftContainerProps = {}, refresh, spacing = MUGlobal.half(MUGlobal.pagePaddings) } = props; // Left container const { size = ViewPageSize.smallLine, ...leftContainerPropsRest } = leftContainerProps; // Current breakpoint const bp = useCurrentBreakpoint(); // Create fields const fieldIndexRef = React.useRef(0); const createFields = React.useCallback((data, maxItems = 0) => { let validItems = 0; const items = []; let i = fieldIndexRef.current; for (; i < fields.length; i++) { const field = fields[i]; let oneSize; let oneItem; if (typeof field === "function") { // Most flexible way, do whatever you want const createdResult = field(data, refresh); if (createdResult == null || createdResult === "") continue; if (Array.isArray(createdResult)) { const [created, size] = createdResult; oneSize = size; oneItem = created; } else { oneSize = ViewPageSize.line; oneItem = createdResult; } } else { const [itemData, itemLabel, gridProps, size, horizontal] = getItemField(app, field, data); // Some callback function may return '' instead of undefined if (itemData == null || itemData === "") continue; oneSize = size; oneItem = (_createElement(ViewPageGridItem, { ...gridProps, key: i, data: itemData, label: itemLabel, horizontal: horizontal })); } // Max lines if (maxItems > 0) { const itemSize = getItemSize(bp, oneSize); if (maxItems < validItems + itemSize) { fieldIndexRef.current = i; break; } else { items.push(oneItem); validItems += itemSize; } } else { items.push(oneItem); } } if (maxItems === 0) { fieldIndexRef.current = 0; } else { fieldIndexRef.current = i; } return items; }, [app, fields, data, bp]); let leftResult; // Layout return (_jsxs(Grid, { container: true, justifyContent: "left", className: "ET-ViewContainer", ref: gridRef, spacing: spacing, children: [leftContainer && (leftResult = leftContainer(data)) != null && (_jsxs(React.Fragment, { children: [_jsx(Grid, { container: true, className: "ET-ViewPage-LeftContainer", spacing: spacing, size: size, ...leftContainerPropsRest, children: leftResult }), _jsx(Grid, { container: true, className: "ET-ViewPage-LeftOthers", spacing: spacing, size: ViewPageSize.matchSize(size), children: createFields(data, leftContainerLines * (12 - getItemSize(bp, size))) })] })), createFields(data)] })); }