✨ feat(vscode): 代码阅读页面画链式调用卡片:竖轨道、小链、收起的闭包和合成的表
链的各步排在值下面的竖轨道上,方法一列对齐、轨道线是函数色淡到 35%;实参是链的缩进成空心点小链,注释挂在步骤下;收起的闭包是能点的小框,点开那一步才画挂着的子块(折叠 id 记在属性行下面);跳到定义、查找、高度估算、只看改动都算上链里的字和步骤下的子块
This commit is contained in:
1 parent
ee595f3da9
commit
1956879aa1
13 files changed
+531
-47
No files matched your search
@@ -5,7 +5,9 @@ import type { Highlight, OccurrenceStyle } from './occurrences'
|
||||
import type { Placement } from './placement'
|
||||
import type { ReadableStore } from './store'
|
||||
import type { GroupStyle, Inline, Segment, SegmentGroup, ShownName } from './types'
|
||||
import { ChevronDown, ChevronRight } from 'lucide-react'
|
||||
import { createContext, memo, useContext, useState } from 'react'
|
||||
import { ChainFoldContext } from './chainFold'
|
||||
import { sameShownName, shownName } from './displayNames'
|
||||
import { KIND_ICON_COMPONENTS } from './kindIcons'
|
||||
import { isCurrent, segmentOccurrence, sourceOf } from './occurrences'
|
||||
@@ -106,6 +108,7 @@ const GROUP_ICONS: Record<GroupStyle, LucideIcon | undefined> = {
|
||||
branch: undefined,
|
||||
tag: undefined,
|
||||
classes: undefined,
|
||||
fold: undefined,
|
||||
}
|
||||
|
||||
/** 框自己的颜色,暗色、亮色两个都写在 style 上,CSS 按主题挑一个(见 .cr-group[data-colored])。 */
|
||||
@@ -120,6 +123,8 @@ function groupColor(group: SegmentGroup): CSSProperties | undefined {
|
||||
function GroupBox({ group }: { group: SegmentGroup }): ReactElement {
|
||||
if (group.style === 'classes')
|
||||
return <ClassesChip group={group} />
|
||||
if (group.style === 'fold')
|
||||
return <FoldChip group={group} />
|
||||
const Icon = GROUP_ICONS[group.style]
|
||||
return (
|
||||
<span className="cr-group" data-style={group.style} data-colored={group.color ? '' : undefined} style={groupColor(group)}>
|
||||
@@ -134,6 +139,33 @@ function GroupBox({ group }: { group: SegmentGroup }): ReactElement {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 链式调用卡片里收起来的闭包、async 块(「闭包 |app| · 37 句」):前面一个折叠箭头,点它展开、收起这一步下面挂着的子块
|
||||
* (开关是所在那一步给的,见 [ChainFoldContext]);不在链的某一步里时只是一个小框。
|
||||
*/
|
||||
function FoldChip({ group }: { group: SegmentGroup }): ReactElement {
|
||||
const fold = useContext(ChainFoldContext)
|
||||
const Chevron = fold?.open ? ChevronDown : ChevronRight
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className="cr-group"
|
||||
data-style="fold"
|
||||
data-open={fold?.open ? '' : undefined}
|
||||
aria-expanded={fold?.open ?? false}
|
||||
aria-label={`${fold?.open ? '收起' : '展开'}${group.label}`}
|
||||
disabled={!fold}
|
||||
onClick={fold?.onToggle}
|
||||
>
|
||||
<span className="cr-group-head">
|
||||
<Chevron size={12} strokeWidth={2} aria-hidden />
|
||||
{group.label}
|
||||
</span>
|
||||
<SegmentText segments={group.segments} />
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
/** 收起来的一串类名(「样式 N 个类」):悬停看全部类名,点一下在它下面弹出、盖住后面的字,再点收起。 */
|
||||
function ClassesChip({ group }: { group: SegmentGroup }): ReactElement {
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
Reference in new issue
Block a user