import { ComponentType, getElementBounds, Group } from '../../jsx'; import { ItemDesc, ItemIcon, ItemIconCircle, ItemLabel } from '../components'; import { FlexLayout } from '../layouts'; import { getItemProps } from '../utils'; import { registerItem } from './registry'; import type { BaseItemProps } from './types'; export interface SimpleItemProps extends BaseItemProps { width?: number; height?: number; gap?: number; showIcon?: boolean; iconSize?: number; iconType?: 'default' | 'circle'; usePaletteColor?: boolean; } export const SimpleItem: ComponentType = (props) => { const [ { indexes, datum, width = 200, height, gap = 4, showIcon = true, iconSize = 30, iconType = 'default', positionH = 'normal', positionV = 'normal', usePaletteColor = false, themeColors, }, restProps, ] = getItemProps(props, [ 'width', 'height', 'gap', 'showIcon', 'iconSize', 'iconType', 'usePaletteColor', ]); const { label, desc, icon } = datum; const getTextAlign = (position: string) => { return position === 'normal' ? 'left' : position === 'flipped' ? 'right' : 'center'; }; const textAlign = getTextAlign(positionH); const labelColor = usePaletteColor ? themeColors.colorPrimary : themeColors.colorText; // ItemDesc 的默认参数(用于计算行数) const descFontSize = 14; const descLineHeight = 1.4; const labelContent = ( {label} ); const labelBounds = getElementBounds(labelContent); const iconContent = showIcon ? ( iconType === 'circle' ? ( ) : ( ) ) : null; if (!showIcon || !icon) { // 计算 desc 的可用高度和行数 const descHeight = height ? Math.max(0, height - labelBounds.height - gap) : undefined; const descLineNumber = descHeight ? descHeight <= 60 ? 1 : Math.floor(descHeight / (descLineHeight * descFontSize)) : 2; const labelY = height ? positionV === 'middle' ? (height - labelBounds.height - (descHeight || 0) - gap) / 2 : positionV === 'flipped' ? height - labelBounds.height - (descHeight || 0) - gap : 0 : 0; return ( {label} {desc} ); } if (positionH === 'center') { // 计算 desc 的可用高度和行数 const iconHeight = showIcon && icon ? iconSize : 0; const descHeight = height ? Math.max(0, height - labelBounds.height - iconHeight - gap * 2) : undefined; const descLineNumber = descHeight ? descHeight <= 60 ? 1 : Math.floor(descHeight / (descLineHeight * descFontSize)) : 2; const contentHeight = labelBounds.height + (descHeight || 0) + gap; const labelY = height ? positionV === 'middle' ? (height - contentHeight - iconHeight - gap) / 2 : positionV === 'flipped' ? height - contentHeight - iconHeight - gap : 0 : 0; return ( {positionV === 'flipped' ? ( <> {label} {desc} {iconContent} ) : ( <> {iconContent} {label} {desc} )} ); } const iconBounds = getElementBounds(iconContent); const textWidth = Math.max(width - iconBounds.width - gap, 0); // 计算 desc 的可用高度和行数 const descHeight = height ? Math.max(0, height - labelBounds.height - gap) : undefined; const descLineNumber = descHeight ? descHeight <= 60 ? 1 : Math.floor(descHeight / (descLineHeight * descFontSize)) : 2; const labelY = height ? positionV === 'middle' ? (height - labelBounds.height - (descHeight || 0) - gap) / 2 : positionV === 'flipped' ? height - labelBounds.height - (descHeight || 0) - gap : 0 : 0; return ( {positionH === 'flipped' ? ( <> {label} {desc} {iconContent} ) : ( <> {iconContent} {label} {desc} )} ); function getDescVerticalAlign(positionV: string, hasIcon: boolean) { return 'top'; // if (positionV === 'normal') return 'top'; // if (positionV === 'flipped') return 'bottom'; return hasIcon ? 'middle' : 'top'; } function getIconVerticalAlign(positionV: string) { if (positionV === 'normal') return 'flex-start'; if (positionV === 'flipped') return 'flex-end'; return 'center'; } }; registerItem('simple', { component: SimpleItem, composites: ['icon', 'label', 'desc'], });