UNPKG

@etsoo/materialui

Version:

TypeScript Material-UI Implementation

217 lines (195 loc) 5.52 kB
import { NumberUtils } from "@etsoo/shared"; import { ListItemButtonProps } from "@mui/material/ListItemButton"; import { Breakpoint, Theme } from "@mui/material/styles"; import { Link } from "react-router"; /** * Mouse event handler with data */ export type MouseEventWithDataHandler<T> = ( event: React.MouseEvent<HTMLDivElement>, data: T ) => void; /** * MUGlobal for global configurations */ export class MUGlobal { /** * Search field shrink */ static searchFieldShrink: boolean = true; /** * Search field size */ static searchFieldSize: "small" | "medium" = "small"; /** * Search field variant */ static searchFieldVariant: "standard" | "filled" | "outlined" = "outlined"; /** * Input field shrink */ static inputFieldShrink: boolean = true; /** * Input field size */ static inputFieldSize: "small" | "medium" = "medium"; /** * Input field variant */ static inputFieldVariant: "standard" | "filled" | "outlined" = "outlined"; /** * TextField variant */ static textFieldVariant: "standard" | "filled" | "outlined" = "filled"; /** * Page default paddings */ static pagePaddings = { xs: 2, sm: 3 }; /** * Get menu item props * @param path Current path * @param href Item's href * @returns Props */ static getMenuItem(path: string, href: string) { let selected = false; if (path === href) { // Exact match, most common case selected = true; } else if (href.endsWith("*")) { href = href.slice(0, -1); selected = path.startsWith(href); } else if (href.endsWith("/all")) { selected = path.startsWith(href.slice(0, -3)); } return { component: Link, selected, to: href, sx: { ...(selected && { ".MuiListItemIcon-root": { color: (theme) => theme.palette.primary.main } }) } } as ListItemButtonProps; } /** * Update object number properties with half of it * @param input Input object * @returns Updated object */ static half(input: object) { const newObj = { ...input }; Object.entries(newObj).forEach(([key, value]) => { if (typeof value === "number") { Reflect.set(newObj, key, value / 2.0); } }); return newObj; } /** * Reverse object number properties, like 5 to -5 * @param input Input object * @returns Updated object */ static reverse(input: object) { const newObj = { ...input }; Object.entries(newObj).forEach(([key, value]) => { if (typeof value === "number") { Reflect.set(newObj, key, -value); } }); return newObj; } /** * Update object number properties with adjustment * @param input Input object * @param adjust Adjust value or new size object * @param field Specific field * @returns Updated object */ static increase(input: object, adjust: number | object, field?: string) { const newObj = { ...input }; Object.entries(newObj).forEach(([key, value]) => { if (typeof value === "number") { if (field == null || field === key) { const adjustValue = typeof adjust === "number" ? adjust : Reflect.get(adjust, key); if (adjustValue == null || typeof adjustValue !== "number") return; Reflect.set(newObj, key, value + adjustValue); } } }); return newObj; } /** * Adjust size with theme update * @param size Base size * @param adjust Adjustment * @param updateFunc Theme update function * @returns Updated object */ static adjustWithTheme( size: number, adjust: object, updateFunc: (value: number) => string ) { const newObj = { ...adjust }; Object.entries(newObj).forEach(([key, value]) => { if (typeof value === "number") { const newValue = NumberUtils.parseWithUnit(updateFunc(value)); if (newValue != null) { Reflect.set(newObj, key, `${size - newValue[0]}${newValue[1]}`); } } }); return newObj; } /** * Break points defined */ static breakpoints = ["xs", "sm", "md", "lg", "xl"] as const; /** * Get multple medias theme space * Responsive values and Breakpoints as an object * xs = theme.breakpoints.up('xs') * https://mui.com/system/basics/ * @param spaces Spaces * @param theme Theme * @returns Result */ static getSpace(spaces: object, theme: Theme) { const start = this.breakpoints.length - 1; for (let i = start; i >= 0; i--) { const key = this.breakpoints[i]; const value = Reflect.get(spaces, key); if (typeof value === "number") { const mediaRaw = theme.breakpoints.up(key as Breakpoint); const mediaQuery = mediaRaw.substring(mediaRaw.indexOf("(")); if (window.matchMedia(mediaQuery).matches) { let space = parseInt(theme.spacing(value), 10); if (isNaN(space)) space = 8 * value; return space; } } } return 0; } /** * Update object number properties with theme * @param input Input object * @param updateFunc Theme update function * @returns Updated object */ static updateWithTheme(input: {}, updateFunc: (value: number) => string) { const newObj = { ...input }; Object.entries(newObj).forEach(([key, value]) => { if (typeof value === "number") { Reflect.set(newObj, key, updateFunc(value)); } }); return newObj; } }