/** * Box Component - Lynx 版 MUI Box * 一比一对应 MUI @mui/system Box * * 支持的系统属性: * - spacing: m, mt, mr, mb, ml, mx, my, p, pt, pr, pb, pl, px, py * - flexbox: display, flexDirection, flexWrap, justifyContent, alignItems, alignContent, order, flex, flexGrow, flexShrink, alignSelf * - sizing: width, height, minWidth, minHeight, maxWidth, maxHeight, boxSizing * - palette: color, bgcolor, backgroundColor * - positions: position, zIndex, top, right, bottom, left * - borders: border, borderTop, borderRight, borderBottom, borderLeft, borderColor, borderRadius * - shadows: boxShadow * - typography: fontFamily, fontSize, fontWeight, lineHeight, letterSpacing, textAlign */ import './Box.css' // ============================================= // Spacing 系统属性 - 对应 MUI spacing.js // ============================================= export const marginKeys = [ 'm', 'mt', 'mr', 'mb', 'ml', 'mx', 'my', 'margin', 'marginTop', 'marginRight', 'marginBottom', 'marginLeft', 'marginX', 'marginY', ] as const export const paddingKeys = [ 'p', 'pt', 'pr', 'pb', 'pl', 'px', 'py', 'padding', 'paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft', 'paddingX', 'paddingY', ] as const // ============================================= // Flexbox 系统属性 - 对应 MUI flexbox.js // ============================================= export const flexboxKeys = [ 'flexBasis', 'flexDirection', 'flexWrap', 'justifyContent', 'alignItems', 'alignContent', 'order', 'flex', 'flexGrow', 'flexShrink', 'alignSelf', 'justifyItems', 'justifySelf', ] as const // ============================================= // Sizing 系统属性 - 对应 MUI sizing.js // ============================================= export const sizingKeys = [ 'width', 'maxWidth', 'minWidth', 'height', 'maxHeight', 'minHeight', 'boxSizing', ] as const // ============================================= // Display 系统属性 - 对应 MUI display.js // ============================================= export const displayKeys = [ 'display', 'overflow', 'textOverflow', 'visibility', ] as const // ============================================= // Positions 系统属性 - 对应 MUI positions.js // ============================================= export const positionsKeys = [ 'position', 'zIndex', 'top', 'right', 'bottom', 'left', ] as const // ============================================= // Palette 系统属性 - 对应 MUI palette.js // ============================================= export const paletteKeys = [ 'color', 'bgcolor', 'backgroundColor', ] as const // ============================================= // Borders 系统属性 - 对应 MUI borders.js // ============================================= export const bordersKeys = [ 'border', 'borderTop', 'borderRight', 'borderBottom', 'borderLeft', 'borderColor', 'borderTopColor', 'borderRightColor', 'borderBottomColor', 'borderLeftColor', 'borderRadius', 'borderWidth', ] as const // ============================================= // Shadows 系统属性 - 对应 MUI shadows.js // ============================================= export const shadowsKeys = [ 'boxShadow', ] as const // ============================================= // Typography 系统属性 - 对应 MUI typography.js // ============================================= export const typographyKeys = [ 'fontFamily', 'fontSize', 'fontStyle', 'fontWeight', 'letterSpacing', 'lineHeight', 'textAlign', 'textTransform', ] as const // ============================================= // Grid 系统属性 - 对应 MUI cssGrid.js // ============================================= export const gridKeys = [ 'gap', 'columnGap', 'rowGap', 'gridColumn', 'gridRow', 'gridAutoFlow', 'gridAutoColumns', 'gridAutoRows', 'gridTemplateColumns', 'gridTemplateRows', 'gridTemplateAreas', 'gridArea', ] as const // ============================================= // BoxProps 类型定义 - 完整系统属性 // ============================================= export interface BoxProps { // Spacing - margin m?: number | string mt?: number | string mr?: number | string mb?: number | string ml?: number | string mx?: number | string my?: number | string margin?: number | string marginTop?: number | string marginRight?: number | string marginBottom?: number | string marginLeft?: number | string marginX?: number | string marginY?: number | string // Spacing - padding p?: number | string pt?: number | string pr?: number | string pb?: number | string pl?: number | string px?: number | string py?: number | string padding?: number | string paddingTop?: number | string paddingRight?: number | string paddingBottom?: number | string paddingLeft?: number | string paddingX?: number | string paddingY?: number | string // Flexbox flexBasis?: number | string flexDirection?: 'row' | 'column' | 'row-reverse' | 'column-reverse' flexWrap?: 'nowrap' | 'wrap' | 'wrap-reverse' justifyContent?: 'flex-start' | 'flex-end' | 'center' | 'space-between' | 'space-around' | 'space-evenly' alignItems?: 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'baseline' alignContent?: 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'space-between' | 'space-around' order?: number flex?: number | string flexGrow?: number flexShrink?: number alignSelf?: 'auto' | 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'baseline' justifyItems?: string justifySelf?: string // Sizing width?: number | string maxWidth?: number | string minWidth?: number | string height?: number | string maxHeight?: number | string minHeight?: number | string boxSizing?: 'border-box' | 'content-box' // Display display?: 'flex' | 'block' | 'inline' | 'inline-flex' | 'inline-block' | 'grid' | 'none' overflow?: 'visible' | 'hidden' | 'scroll' | 'auto' textOverflow?: 'clip' | 'ellipsis' visibility?: 'visible' | 'hidden' | 'collapse' // Positions position?: 'static' | 'relative' | 'absolute' | 'fixed' | 'sticky' zIndex?: number | string top?: number | string right?: number | string bottom?: number | string left?: number | string // Palette color?: string bgcolor?: string backgroundColor?: string // Borders border?: number | string borderTop?: number | string borderRight?: number | string borderBottom?: number | string borderLeft?: number | string borderColor?: string borderTopColor?: string borderRightColor?: string borderBottomColor?: string borderLeftColor?: string borderRadius?: number | string borderWidth?: number | string // Shadows boxShadow?: number | string // Typography fontFamily?: string fontSize?: number | string fontStyle?: string fontWeight?: number | string letterSpacing?: number | string lineHeight?: number | string textAlign?: 'left' | 'center' | 'right' | 'justify' textTransform?: 'none' | 'capitalize' | 'uppercase' | 'lowercase' // Grid gap?: number | string columnGap?: number | string rowGap?: number | string gridColumn?: string gridRow?: string gridAutoFlow?: string gridAutoColumns?: string gridAutoRows?: string gridTemplateColumns?: string gridTemplateRows?: string gridTemplateAreas?: string gridArea?: string // Other opacity?: number // Component component?: string // sx 系统属性 sx?: Record // 基础属性 children?: any className?: string style?: Record bindtap?: () => void } // ============================================= // 间距转换函数 - 对应 MUI spacing 系统 // ============================================= const spacingUnit = 8 function toSpacingValue(value: number | string | undefined): string | undefined { if (value === undefined) return undefined if (typeof value === 'string') return value return `${value * spacingUnit}px` } // ============================================= // Box 组件实现 // ============================================= export function Box(props: BoxProps) { const { // Display display, overflow, textOverflow, visibility, // Flexbox flexBasis, flexDirection, flexWrap, justifyContent, alignItems, alignContent, order, flex, flexGrow, flexShrink, alignSelf, justifyItems, justifySelf, // Spacing - padding p, pt, pr, pb, pl, px, py, padding, paddingTop, paddingRight, paddingBottom, paddingLeft, paddingX, paddingY, // Spacing - margin m, mt, mr, mb, ml, mx, my, margin, marginTop, marginRight, marginBottom, marginLeft, marginX, marginY, // Sizing width, maxWidth, minWidth, height, maxHeight, minHeight, boxSizing, // Positions position, zIndex, top, right, bottom, left, // Palette color, bgcolor, backgroundColor, // Borders border, borderTop, borderRight, borderBottom, borderLeft, borderColor, borderTopColor, borderRightColor, borderBottomColor, borderLeftColor, borderRadius, borderWidth, // Shadows boxShadow, // Typography fontFamily, fontSize, fontStyle, fontWeight, letterSpacing, lineHeight, textAlign, textTransform, // Grid gap, columnGap, rowGap, gridColumn, gridRow, gridAutoFlow, gridAutoColumns, gridAutoRows, gridTemplateColumns, gridTemplateRows, gridTemplateAreas, gridArea, // Other opacity, // sx sx, // Base className, children, style, component, ...restProps } = props // 计算样式 const computedStyle: Record = { // Display ...(display && { display }), ...(overflow && { overflow }), ...(textOverflow && { textOverflow }), ...(visibility && { visibility }), // Flexbox ...(flexBasis !== undefined && { flexBasis }), ...(flexDirection && { flexDirection }), ...(flexWrap && { flexWrap }), ...(justifyContent && { justifyContent }), ...(alignItems && { alignItems }), ...(alignContent && { alignContent }), ...(order !== undefined && { order }), ...(flex !== undefined && { flex }), ...(flexGrow !== undefined && { flexGrow }), ...(flexShrink !== undefined && { flexShrink }), ...(alignSelf && { alignSelf }), ...(justifyItems && { justifyItems }), ...(justifySelf && { justifySelf }), // Padding (shorthand first, then specific) ...(p !== undefined && { padding: toSpacingValue(p) }), ...(padding !== undefined && { padding: toSpacingValue(padding) }), ...(px !== undefined && { paddingLeft: toSpacingValue(px), paddingRight: toSpacingValue(px) }), ...(paddingX !== undefined && { paddingLeft: toSpacingValue(paddingX), paddingRight: toSpacingValue(paddingX) }), ...(py !== undefined && { paddingTop: toSpacingValue(py), paddingBottom: toSpacingValue(py) }), ...(paddingY !== undefined && { paddingTop: toSpacingValue(paddingY), paddingBottom: toSpacingValue(paddingY) }), ...(pt !== undefined && { paddingTop: toSpacingValue(pt) }), ...(paddingTop !== undefined && { paddingTop: toSpacingValue(paddingTop) }), ...(pr !== undefined && { paddingRight: toSpacingValue(pr) }), ...(paddingRight !== undefined && { paddingRight: toSpacingValue(paddingRight) }), ...(pb !== undefined && { paddingBottom: toSpacingValue(pb) }), ...(paddingBottom !== undefined && { paddingBottom: toSpacingValue(paddingBottom) }), ...(pl !== undefined && { paddingLeft: toSpacingValue(pl) }), ...(paddingLeft !== undefined && { paddingLeft: toSpacingValue(paddingLeft) }), // Margin (shorthand first, then specific) ...(m !== undefined && { margin: toSpacingValue(m) }), ...(margin !== undefined && { margin: toSpacingValue(margin) }), ...(mx !== undefined && { marginLeft: toSpacingValue(mx), marginRight: toSpacingValue(mx) }), ...(marginX !== undefined && { marginLeft: toSpacingValue(marginX), marginRight: toSpacingValue(marginX) }), ...(my !== undefined && { marginTop: toSpacingValue(my), marginBottom: toSpacingValue(my) }), ...(marginY !== undefined && { marginTop: toSpacingValue(marginY), marginBottom: toSpacingValue(marginY) }), ...(mt !== undefined && { marginTop: toSpacingValue(mt) }), ...(marginTop !== undefined && { marginTop: toSpacingValue(marginTop) }), ...(mr !== undefined && { marginRight: toSpacingValue(mr) }), ...(marginRight !== undefined && { marginRight: toSpacingValue(marginRight) }), ...(mb !== undefined && { marginBottom: toSpacingValue(mb) }), ...(marginBottom !== undefined && { marginBottom: toSpacingValue(marginBottom) }), ...(ml !== undefined && { marginLeft: toSpacingValue(ml) }), ...(marginLeft !== undefined && { marginLeft: toSpacingValue(marginLeft) }), // Sizing ...(width !== undefined && { width }), ...(maxWidth !== undefined && { maxWidth }), ...(minWidth !== undefined && { minWidth }), ...(height !== undefined && { height }), ...(maxHeight !== undefined && { maxHeight }), ...(minHeight !== undefined && { minHeight }), ...(boxSizing && { boxSizing }), // Positions ...(position && { position }), ...(zIndex !== undefined && { zIndex }), ...(top !== undefined && { top }), ...(right !== undefined && { right }), ...(bottom !== undefined && { bottom }), ...(left !== undefined && { left }), // Palette ...(color && { color }), ...(bgcolor && { backgroundColor: bgcolor }), ...(backgroundColor && { backgroundColor }), // Borders ...(border !== undefined && { border }), ...(borderTop !== undefined && { borderTop }), ...(borderRight !== undefined && { borderRight }), ...(borderBottom !== undefined && { borderBottom }), ...(borderLeft !== undefined && { borderLeft }), ...(borderColor && { borderColor }), ...(borderTopColor && { borderTopColor }), ...(borderRightColor && { borderRightColor }), ...(borderBottomColor && { borderBottomColor }), ...(borderLeftColor && { borderLeftColor }), ...(borderRadius !== undefined && { borderRadius }), ...(borderWidth !== undefined && { borderWidth }), // Shadows ...(boxShadow !== undefined && { boxShadow }), // Typography ...(fontFamily && { fontFamily }), ...(fontSize !== undefined && { fontSize }), ...(fontStyle && { fontStyle }), ...(fontWeight !== undefined && { fontWeight }), ...(letterSpacing !== undefined && { letterSpacing }), ...(lineHeight !== undefined && { lineHeight }), ...(textAlign && { textAlign }), ...(textTransform && { textTransform }), // Grid ...(gap !== undefined && { gap: toSpacingValue(gap) }), ...(columnGap !== undefined && { columnGap: toSpacingValue(columnGap) }), ...(rowGap !== undefined && { rowGap: toSpacingValue(rowGap) }), ...(gridColumn && { gridColumn }), ...(gridRow && { gridRow }), ...(gridAutoFlow && { gridAutoFlow }), ...(gridAutoColumns && { gridAutoColumns }), ...(gridAutoRows && { gridAutoRows }), ...(gridTemplateColumns && { gridTemplateColumns }), ...(gridTemplateRows && { gridTemplateRows }), ...(gridTemplateAreas && { gridTemplateAreas }), ...(gridArea && { gridArea }), // Other ...(opacity !== undefined && { opacity }), // sx 属性 (覆盖以上所有) ...sx, // 传入的 style (最高优先级) ...style, } return ( {children} ) } export default Box