feat(dockview): support dynamic Lucide icons via string in tab headers

This commit is contained in:
cfngc4594 2025-04-07 10:32:58 +08:00
parent 9a51c1547f
commit 3e5e2d2a62
3 changed files with 23 additions and 25 deletions

View File

@ -1,14 +1,5 @@
"use client"; "use client";
import {
BotIcon,
CircleCheckBigIcon,
FileTextIcon,
FlaskConicalIcon,
SquareCheckIcon,
SquarePenIcon,
TerminalIcon,
} from "lucide-react";
import { import {
Bot, Bot,
Code, Code,
@ -38,16 +29,16 @@ export default function ProblemPage() {
id: "Description", id: "Description",
component: "Description", component: "Description",
title: "Description", title: "Description",
params: { icon: FileTextIcon }, params: { icon: "FileTextIcon" },
}, },
{ {
id: "Solutions", id: "Solutions",
component: "Solutions", component: "Solutions",
title: "Solutions", title: "Solutions",
params: { icon: FlaskConicalIcon }, params: { icon: "FlaskConicalIcon" },
position: { position: {
referencePanel: "Description", referencePanel: "Description",
direction: "within" direction: "within",
}, },
inactive: true, inactive: true,
}, },
@ -55,10 +46,10 @@ export default function ProblemPage() {
id: "Submissions", id: "Submissions",
component: "Submissions", component: "Submissions",
title: "Submissions", title: "Submissions",
params: { icon: CircleCheckBigIcon }, params: { icon: "CircleCheckBigIcon" },
position: { position: {
referencePanel: "Solutions", referencePanel: "Solutions",
direction: "within" direction: "within",
}, },
inactive: true, inactive: true,
}, },
@ -66,40 +57,40 @@ export default function ProblemPage() {
id: "Code", id: "Code",
component: "Code", component: "Code",
title: "Code", title: "Code",
params: { icon: SquarePenIcon }, params: { icon: "SquarePenIcon" },
position: { position: {
referencePanel: "Submissions", referencePanel: "Submissions",
direction: "right" direction: "right",
}, },
}, },
{ {
id: "Bot", id: "Bot",
component: "Bot", component: "Bot",
title: "Bot", title: "Bot",
params: { icon: BotIcon }, params: { icon: "BotIcon" },
position: { position: {
referencePanel: "Code", referencePanel: "Code",
direction: "right" direction: "right",
}, },
}, },
{ {
id: "Testcase", id: "Testcase",
component: "Testcase", component: "Testcase",
title: "Testcase", title: "Testcase",
params: { icon: SquareCheckIcon }, params: { icon: "SquareCheckIcon" },
position: { position: {
referencePanel: "Code", referencePanel: "Code",
direction: "below" direction: "below",
}, },
}, },
{ {
id: "TestResult", id: "TestResult",
component: "TestResult", component: "TestResult",
title: "Test Result", title: "Test Result",
params: { icon: TerminalIcon }, params: { icon: "TerminalIcon" },
position: { position: {
referencePanel: "Testcase", referencePanel: "Testcase",
direction: "within" direction: "within",
}, },
inactive: true, inactive: true,
}, },

View File

@ -8,6 +8,7 @@ import type {
IDockviewPanelProps, IDockviewPanelProps,
} from "dockview"; } from "dockview";
import "@/styles/dockview.css"; import "@/styles/dockview.css";
import * as Icons from "lucide-react";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import type { LucideIcon } from "lucide-react"; import type { LucideIcon } from "lucide-react";
import { DockviewReact, themeAbyssSpaced } from "dockview"; import { DockviewReact, themeAbyssSpaced } from "dockview";
@ -21,9 +22,13 @@ interface DockviewProps {
} }
const DefaultTab = ( const DefaultTab = (
props: IDockviewPanelHeaderProps<{ icon?: LucideIcon }> props: IDockviewPanelHeaderProps<{ icon?: string }>
) => { ) => {
const { icon: Icon } = props.params; const { icon } = props.params;
const Icon =
icon && icon in Icons
? (Icons[icon as keyof typeof Icons] as LucideIcon)
: null;
return ( return (
<div className="flex items-center px-1 text-sm font-medium"> <div className="flex items-center px-1 text-sm font-medium">

View File

@ -42,6 +42,7 @@ export default function NewProblemDescriptionForm() {
description, description,
setData, setData,
} = useNewProblemStore(); } = useNewProblemStore();
const router = useRouter(); const router = useRouter();
const [dockApi, setDockApi] = useState<DockviewApi>(); const [dockApi, setDockApi] = useState<DockviewApi>();
@ -144,7 +145,7 @@ export default function NewProblemDescriptionForm() {
id: "MdxPreview", id: "MdxPreview",
component: "MdxPreview", component: "MdxPreview",
title: "Mdx Preview", title: "Mdx Preview",
params: { source: field.value }, params: { source: field.value, icon: "FileTextIcon" },
}, },
{ {
id: "MarkdownEditor", id: "MarkdownEditor",
@ -155,6 +156,7 @@ export default function NewProblemDescriptionForm() {
onChange: (value: string | undefined) => { onChange: (value: string | undefined) => {
field.onChange(value); field.onChange(value);
}, },
icon: "SquarePenIcon",
}, },
position: { position: {
referencePanel: "MdxPreview", referencePanel: "MdxPreview",