import type { ReactElement } from 'react' import type { Inline, PropertyItem, PropertyRow } from './types' import { ChevronDown, ChevronRight } from 'lucide-react' import { Fragment } from 'react' import { inlineText } from './segments' import { SegmentText } from './SegmentText' import { subRowsLayout, tableCells, tableTemplate } from './subRows' import { TextPreview } from './TextPreview' import { propertyItemId, propertyRowId } from './viewState' /** 列表子行里除最后一列以外各列的宽度(字典的键),最后一列占满剩下的;编辑区窄时按比例收,不把最后一列挤没 */ const CELL_WIDTHS = ['min(150px, 28%)', 'min(220px, 38%)'] function gridTemplate(count: number): string { const fixed = Array.from({ length: count - 1 }, (_, i) => CELL_WIDTHS[i] ?? CELL_WIDTHS[CELL_WIDTHS.length - 1]) return [...fixed, 'minmax(0, 1fr)'].join(' ') } /** 眼下折叠着哪些属性行、子行,点折叠箭头时切换哪个。 */ interface Folding { collapsed: ReadonlySet onToggleFold: (id: string) => void } /** * 子行的第一列(字典的键):带下一层的子行前面是折叠箭头(图标、大小、颜色同属性行的),点箭头或这一列切换; * 同一层里不带下一层的子行在同样的位置留空,第一列才对得齐。 */ function ItemHead({ id, cell, foldable, folding }: { id: string, cell: Inline[], foldable: boolean, folding: Folding }): ReactElement { if (!foldable) { return (

) } const folded = folding.collapsed.has(id) const Chevron = folded ? ChevronRight : ChevronDown return ( ) } /** * 展开在一行或一个子行(parentId)下面的一层子行:左边一条竖线,每个子行几列对齐。 * 带下一层的子行(字典 / 对象的值又是字典 / 对象),下一层展开在它下面、再往右缩进一层,默认展开。 */ function PropertyItems({ parentId, items, folding }: { parentId: string, items: PropertyItem[], folding: Folding }): ReactElement { const nested = items.some(item => (item.items?.length ?? 0) > 0) return (
{items.map((item, index) => { const id = propertyItemId(parentId, index) const children = item.items ?? [] return (
{item.cells.map((cell, i) => i === 0 && nested ? 0} folding={folding} /> : (

))}
{children.length > 0 && !folding.collapsed.has(id) && }
) })}
) } /** * 给了列名的子行(输入参数、数据表的字段)排成表格:第一行是表头(列名),下面每个子行一行;外框圆角,格子之间、行之间一条分隔线。 * 列宽按整列的内容定(见 tableTemplate),最后一列分剩下的,长了在格子里换行。 */ function PropertyTable({ parentId, columns, items }: { parentId: string, columns: string[], items: PropertyItem[] }): ReactElement { return (
{columns.map((name, i) => {name})}
{items.map((item, index) => (
{tableCells(item, columns).map((cell, i) => (

))}
))}
) } /** * 函数、类、枚举、导入、常量、变量块和库规则的卡片的预览:属性名一列对齐,值按词性着色;输入参数、导入项、字典 / 对象的值下面展开子行, * 给了列名的(输入参数、数据表的字段)排成表格,没给的排成列表。 */ export function PropertyGrid({ blockId, rows, collapsed, onToggleFold }: { blockId: string rows: PropertyRow[] collapsed: ReadonlySet onToggleFold: (id: string) => void }): ReactElement { return (
{rows.map((row, index) => { const layout = subRowsLayout(row) const id = propertyRowId(blockId, index) const folded = collapsed.has(id) const Chevron = folded ? ChevronRight : ChevronDown return (
{layout ? ( ) : {row.label}}
{!folded && layout === 'table' && } {!folded && layout === 'list' && }
) })}
) }