mirror of
https://github.com/cfngc4594/monaco-editor-lsp-next.git
synced 2025-05-18 23:42:24 +00:00
refactor(components): migrate DockView to dynamic panel/tab components with store-based API exposure and autoAdd flag
This commit is contained in:
parent
737965dc91
commit
56782b83fc
@ -8,28 +8,46 @@ 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 type { LucideIcon } from "lucide-react";
|
import type { LucideIcon } from "lucide-react";
|
||||||
|
import { useDockviewStore } from "@/stores/dockview";
|
||||||
|
import { useEffect, useMemo, useState } from "react";
|
||||||
import { DockviewReact, themeAbyssSpaced } from "dockview";
|
import { DockviewReact, themeAbyssSpaced } from "dockview";
|
||||||
|
|
||||||
|
interface PanelContent {
|
||||||
|
icon?: LucideIcon;
|
||||||
|
content?: React.ReactNode;
|
||||||
|
autoAdd?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
interface DockviewProps {
|
interface DockviewProps {
|
||||||
storageKey: string;
|
storageKey: string;
|
||||||
options: AddPanelOptions[];
|
options: AddPanelOptions<PanelContent>[];
|
||||||
components: Record<string, React.FunctionComponent<IDockviewPanelProps>>;
|
|
||||||
tabComponents?: Record<string, React.FunctionComponent<IDockviewPanelHeaderProps>>;
|
|
||||||
onApiReady?: (api: DockviewApi) => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const DefaultTab = (
|
export default function DockView({ storageKey, options }: DockviewProps) {
|
||||||
props: IDockviewPanelHeaderProps<{ icon?: string }>
|
const { setApi: _setApi } = useDockviewStore();
|
||||||
) => {
|
const [api, setApi] = useState<DockviewApi>();
|
||||||
const { icon } = props.params;
|
|
||||||
const Icon =
|
|
||||||
icon && icon in Icons
|
|
||||||
? (Icons[icon as keyof typeof Icons] as LucideIcon)
|
|
||||||
: null;
|
|
||||||
|
|
||||||
|
const { components, tabComponents } = useMemo(() => {
|
||||||
|
const components: Record<
|
||||||
|
string,
|
||||||
|
React.FunctionComponent<IDockviewPanelProps<PanelContent>>
|
||||||
|
> = {};
|
||||||
|
const tabComponents: Record<
|
||||||
|
string,
|
||||||
|
React.FunctionComponent<IDockviewPanelHeaderProps<PanelContent>>
|
||||||
|
> = {};
|
||||||
|
|
||||||
|
options.forEach((option) => {
|
||||||
|
const { id, params } = option;
|
||||||
|
|
||||||
|
components[id] = () => {
|
||||||
|
const content = params?.content;
|
||||||
|
return <>{content}</>;
|
||||||
|
};
|
||||||
|
|
||||||
|
tabComponents[id] = (props) => {
|
||||||
|
const Icon = params?.icon;
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center px-1 text-sm font-medium">
|
<div className="flex items-center px-1 text-sm font-medium">
|
||||||
{Icon && (
|
{Icon && (
|
||||||
@ -42,16 +60,11 @@ const DefaultTab = (
|
|||||||
{props.api.title}
|
{props.api.title}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
});
|
||||||
|
|
||||||
export default function DockView({
|
return { components, tabComponents };
|
||||||
storageKey,
|
}, [options]);
|
||||||
options,
|
|
||||||
components,
|
|
||||||
tabComponents,
|
|
||||||
onApiReady,
|
|
||||||
}: DockviewProps) {
|
|
||||||
const [api, setApi] = useState<DockviewApi>();
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!api) return;
|
if (!api) return;
|
||||||
@ -66,7 +79,7 @@ export default function DockView({
|
|||||||
|
|
||||||
const onReady = (event: DockviewReadyEvent) => {
|
const onReady = (event: DockviewReadyEvent) => {
|
||||||
setApi(event.api);
|
setApi(event.api);
|
||||||
onApiReady?.(event.api);
|
_setApi(event.api);
|
||||||
|
|
||||||
let success = false;
|
let success = false;
|
||||||
const serializedLayout = localStorage.getItem(storageKey);
|
const serializedLayout = localStorage.getItem(storageKey);
|
||||||
@ -84,6 +97,8 @@ export default function DockView({
|
|||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
options.forEach((option) => {
|
options.forEach((option) => {
|
||||||
|
const autoAdd = option.params?.autoAdd ?? true;
|
||||||
|
if (!autoAdd) return;
|
||||||
event.api.addPanel({ ...option });
|
event.api.addPanel({ ...option });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -94,7 +109,6 @@ export default function DockView({
|
|||||||
theme={themeAbyssSpaced}
|
theme={themeAbyssSpaced}
|
||||||
onReady={onReady}
|
onReady={onReady}
|
||||||
components={components}
|
components={components}
|
||||||
defaultTabComponent={DefaultTab}
|
|
||||||
tabComponents={tabComponents}
|
tabComponents={tabComponents}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user