✨ feat(vscode): 代码阅读块悬停高亮
This commit is contained in:
1 parent
f6eb07a91d
commit
72d33032f0
2 files changed
+45
-16
No files matched your search
@@ -36,19 +36,22 @@ export interface BlockTreeState {
|
|||||||
onToggleFold: (id: string) => void
|
onToggleFold: (id: string) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 一层代码块:左边一条竖线标出这一层,每块的子块紧跟在它下面、再往右缩进一层。 */
|
/**
|
||||||
export function BlockLevel({ blocks, tree }: { blocks: BlockView[], tree: BlockTreeState }): ReactElement {
|
* 一层代码块:左边一条竖线标出这一层,每块的子块紧跟在它下面、再往右缩进一层。
|
||||||
|
* kind 是这一层所属块的种类(顶层没有),悬停那个块时竖线换成它的颜色。
|
||||||
|
*/
|
||||||
|
export function BlockLevel({ blocks, kind, tree }: { blocks: BlockView[], kind?: BlockKind, tree: BlockTreeState }): ReactElement {
|
||||||
return (
|
return (
|
||||||
<div className="flex gap-2">
|
<div className="cr-level flex gap-2" data-kind={kind}>
|
||||||
<div className="flex w-3 shrink-0 justify-center">
|
<div className="flex w-3 shrink-0 justify-center">
|
||||||
<div className="w-px bg-[var(--vscode-editorIndentGuide-background1)]" />
|
<div className="cr-guide w-px" />
|
||||||
</div>
|
</div>
|
||||||
<div className="flex min-w-0 flex-1 flex-col gap-2">
|
<div className="flex min-w-0 flex-1 flex-col gap-2">
|
||||||
{blocks.map(block => (
|
{blocks.map(block => (
|
||||||
<Fragment key={block.id}>
|
<Fragment key={block.id}>
|
||||||
<BlockCard block={block} tree={tree} />
|
<BlockCard block={block} tree={tree} />
|
||||||
{block.children.length > 0 && !tree.collapsed.has(block.id) && (
|
{block.children.length > 0 && !tree.collapsed.has(block.id) && (
|
||||||
<BlockLevel blocks={block.children} tree={tree} />
|
<BlockLevel blocks={block.children} kind={block.kind} tree={tree} />
|
||||||
)}
|
)}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -52,21 +52,27 @@ body.vscode-high-contrast-light {
|
|||||||
--cr-kind-comment: #008000;
|
--cr-kind-comment: #008000;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 种类颜色:同一类语义共用一个颜色,标签文字区分具体是哪种 */
|
/* 种类颜色:同一类语义共用一个颜色,标签文字区分具体是哪种。卡片取自己的种类,子层取所属块的种类 */
|
||||||
.cr-block[data-kind="import"] { --kind: var(--cr-kind-import); }
|
[data-kind="import"] { --kind: var(--cr-kind-import); }
|
||||||
.cr-block[data-kind="function"] { --kind: var(--cr-kind-function); }
|
[data-kind="function"] { --kind: var(--cr-kind-function); }
|
||||||
.cr-block:is([data-kind="class"], [data-kind="type"]) { --kind: var(--cr-kind-type); }
|
:is([data-kind="class"], [data-kind="type"]) { --kind: var(--cr-kind-type); }
|
||||||
.cr-block:is([data-kind="field"], [data-kind="const"], [data-kind="variable"]) { --kind: var(--cr-kind-data); }
|
:is([data-kind="field"], [data-kind="const"], [data-kind="variable"]) { --kind: var(--cr-kind-data); }
|
||||||
.cr-block:is([data-kind="if"], [data-kind="else"]) { --kind: var(--cr-kind-branch); }
|
:is([data-kind="if"], [data-kind="else"]) { --kind: var(--cr-kind-branch); }
|
||||||
.cr-block[data-kind="loop"] { --kind: var(--cr-kind-loop); }
|
[data-kind="loop"] { --kind: var(--cr-kind-loop); }
|
||||||
.cr-block:is([data-kind="try"], [data-kind="catch"], [data-kind="finally"]) { --kind: var(--cr-kind-error); }
|
:is([data-kind="try"], [data-kind="catch"], [data-kind="finally"]) { --kind: var(--cr-kind-error); }
|
||||||
.cr-block[data-kind="return"] { --kind: var(--cr-kind-return); }
|
[data-kind="return"] { --kind: var(--cr-kind-return); }
|
||||||
.cr-block[data-kind="statement"] { --kind: var(--cr-kind-statement); }
|
[data-kind="statement"] { --kind: var(--cr-kind-statement); }
|
||||||
.cr-block[data-kind="comment"] { --kind: var(--cr-kind-comment); }
|
[data-kind="comment"] { --kind: var(--cr-kind-comment); }
|
||||||
|
|
||||||
|
/* 卡片和它的子层是相邻兄弟,:hover 只落在鼠标下最里面那张卡片上,父卡片不跟着亮 */
|
||||||
.cr-block {
|
.cr-block {
|
||||||
background: color-mix(in srgb, var(--kind) 7%, transparent);
|
background: color-mix(in srgb, var(--kind) 7%, transparent);
|
||||||
border: 1px solid color-mix(in srgb, var(--kind) 35%, transparent);
|
border: 1px solid color-mix(in srgb, var(--kind) 35%, transparent);
|
||||||
|
transition: background-color 100ms ease-out, border-color 100ms ease-out;
|
||||||
|
}
|
||||||
|
.cr-block:hover {
|
||||||
|
background: color-mix(in srgb, var(--kind) 14%, transparent);
|
||||||
|
border-color: var(--kind);
|
||||||
}
|
}
|
||||||
.cr-block[data-kind="comment"] {
|
.cr-block[data-kind="comment"] {
|
||||||
border-style: dashed;
|
border-style: dashed;
|
||||||
@@ -75,6 +81,26 @@ body.vscode-high-contrast-light {
|
|||||||
background: var(--vscode-editor-background);
|
background: var(--vscode-editor-background);
|
||||||
border-color: var(--vscode-focusBorder);
|
border-color: var(--vscode-focusBorder);
|
||||||
}
|
}
|
||||||
|
.cr-block[data-editing]:hover {
|
||||||
|
background: color-mix(in srgb, var(--kind) 7%, var(--vscode-editor-background));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 层级竖线:悬停一个块时,它子层的竖线换成它的种类色,标出这个块管到哪里为止 */
|
||||||
|
.cr-guide {
|
||||||
|
background: var(--vscode-editorIndentGuide-background1);
|
||||||
|
transition: background-color 100ms ease-out;
|
||||||
|
}
|
||||||
|
.cr-block:hover + .cr-level > * > .cr-guide {
|
||||||
|
background: var(--kind);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.cr-block,
|
||||||
|
.cr-guide {
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.cr-badge {
|
.cr-badge {
|
||||||
color: var(--kind);
|
color: var(--kind);
|
||||||
background: color-mix(in srgb, var(--kind) 18%, transparent);
|
background: color-mix(in srgb, var(--kind) 18%, transparent);
|
||||||
|
|||||||
Reference in new issue
Block a user