✨ feat(vscode): 代码阅读的输入参数排成带表头和边框的表格

This commit is contained in:
cruldra committed 2026-09-26 16:15:59 +08:00
1 parent 6416cdf714
commit 83adefdf5e
10 files changed
+197 -24

No files matched your search

@@ -4,13 +4,14 @@ import { ChevronDown, ChevronRight } from 'lucide-react'
import { Fragment } from 'react'
import { inlineText } from './segments'
import { SegmentText } from './SegmentText'
import { subRowsLayout, tableCells } from './subRows'
import { TextPreview } from './TextPreview'
import { propertyItemId, propertyRowId } from './viewState'
/** 子行里除最后一列以外各列的宽度(参数的名称、类型,字典的键),最后一列占满剩下的;编辑区窄时按比例收,不把最后一列挤没 */
/** 子行里除最后一列以外各列的宽度(参数表格的名称、类型列,字典的键),最后一列占满剩下的;编辑区窄时按比例收,不把最后一列挤没 */
const CELL_WIDTHS = ['min(150px, 28%)', 'min(220px, 38%)']
function columns(count: number): string {
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(' ')
}
@@ -74,7 +75,7 @@ function PropertyItems({ parentId, items, folding }: { parentId: string, items:
<div
className="cr-prop-item grid gap-x-3"
data-id={id}
style={{ gridTemplateColumns: columns(item.cells.length) }}
style={{ gridTemplateColumns: gridTemplate(item.cells.length) }}
>
{item.cells.map((cell, i) => i === 0 && nested
? <ItemHead key={i} id={id} cell={cell} foldable={children.length > 0} folding={folding} />
@@ -93,7 +94,36 @@ function PropertyItems({ parentId, items, folding }: { parentId: string, items:
)
}
/** 函数、类、导入、常量、变量块的预览:属性名一列对齐,值按词性着色;输入参数、导入项、字典 / 对象的值下面展开子行。 */
/**
* 给了列名的子行(输入参数)排成表格:第一行是表头(列名),下面每个子行一行;外框圆角,格子之间、行之间一条分隔线。
* 列宽同列表的子行,最后一列占满剩下的,长了在格子里换行。
*/
function PropertyTable({ parentId, columns, items }: { parentId: string, columns: string[], items: PropertyItem[] }): ReactElement {
const template = { gridTemplateColumns: gridTemplate(columns.length) }
return (
<div className="pl-[5px]">
<div className="cr-table" role="table">
<div className="cr-table-head grid" role="row" style={template}>
{columns.map((name, i) => <span key={i} className="cr-table-cell" role="columnheader">{name}</span>)}
</div>
{items.map((item, index) => (
<div key={index} className="cr-table-row grid" role="row" data-id={propertyItemId(parentId, index)} style={template}>
{tableCells(item, columns).map((cell, i) => (
<p key={i} className="cr-table-cell cr-code min-w-0" role="cell">
<SegmentText segments={cell} />
</p>
))}
</div>
))}
</div>
</div>
)
}
/**
* 函数、类、导入、常量、变量块的预览:属性名一列对齐,值按词性着色;输入参数、导入项、字典 / 对象的值下面展开子行,
* 翻译插件给了列名的(输入参数)排成表格,没给的排成列表。
*/
export function PropertyGrid({ blockId, rows, collapsed, onToggleFold }: {
blockId: string
rows: PropertyRow[]
@@ -103,14 +133,14 @@ export function PropertyGrid({ blockId, rows, collapsed, onToggleFold }: {
return (
<div className="flex flex-col gap-[3px]">
{rows.map((row, index) => {
const items = row.items ?? []
const layout = subRowsLayout(row)
const id = propertyRowId(blockId, index)
const folded = collapsed.has(id)
const Chevron = folded ? ChevronRight : ChevronDown
return (
<Fragment key={index}>
<div className="cr-prop-row flex gap-3" data-id={id}>
{items.length > 0
{layout
? (
<button
type="button"
@@ -126,7 +156,8 @@ export function PropertyGrid({ blockId, rows, collapsed, onToggleFold }: {
: <span className="cr-prop-label flex h-5 w-[76px] shrink-0 items-center">{row.label}</span>}
<TextPreview text={row.value} className="min-w-0 flex-1" />
</div>
{items.length > 0 && !folded && <PropertyItems parentId={id} items={items} folding={{ collapsed, onToggleFold }} />}
{!folded && layout === 'table' && <PropertyTable parentId={id} columns={row.columns ?? []} items={row.items ?? []} />}
{!folded && layout === 'list' && <PropertyItems parentId={id} items={row.items ?? []} folding={{ collapsed, onToggleFold }} />}
</Fragment>
)
})}