This commit is contained in:
mathuo 2024-01-27 19:21:09 +00:00
parent a24dd21ca2
commit 0fd3a669c7
No known key found for this signature in database
GPG Key ID: C6EEDEFD6CA07281
5 changed files with 144 additions and 29 deletions

View File

@ -87,7 +87,7 @@ const RightControls = (props: IDockviewHeaderActionsProps) => {
);
const [isPopout, setIsPopout] = React.useState<boolean>(
props.api.location === 'popout'
props.api.location.type === 'popout'
);
React.useEffect(() => {
@ -96,7 +96,7 @@ const RightControls = (props: IDockviewHeaderActionsProps) => {
});
const disposable2 = props.api.onDidLocationChange(() => {
setIsPopout(props.api.location === 'popout');
setIsPopout(props.api.location.type === 'popout');
});
return () => {

View File

@ -255,13 +255,13 @@ const LeftComponent = (props: IDockviewHeaderActionsProps) => {
const RightComponent = (props: IDockviewHeaderActionsProps) => {
const [floating, setFloating] = React.useState<boolean>(
props.api.location === 'floating'
props.api.location.type === 'floating'
);
React.useEffect(() => {
const disposable = props.group.api.onDidLocationChange(
(event) => {
setFloating(event.location === 'floating');
setFloating(event.location.type === 'floating');
}
);

View File

@ -9,7 +9,8 @@
"dependencies": {
"dockview": "*",
"react": "^18.2.0",
"react-dom": "^18.2.0"
"react-dom": "^18.2.0",
"react-laag": "^2.0.5"
},
"devDependencies": {
"@types/react": "^18.0.28",

View File

@ -5,12 +5,53 @@ import {
IDockviewHeaderActionsProps,
IDockviewPanelProps,
SerializedDockview,
DockviewPanelApi,
DockviewGroupLocation,
} from 'dockview';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { Icon } from './utils';
import { PopoverMenu } from './popover';
function usePopoutWindowContext(api: DockviewPanelApi): Window {
const [location, setLocation] = React.useState<DockviewGroupLocation>(
api.location
);
React.useEffect(() => {
const disposable = api.onDidLocationChange((event) => {
setLocation(event.location);
});
return () => {
disposable.dispose();
};
});
const windowContext = React.useMemo(() => {
if (location.type === 'popout') {
return location.getWindow();
}
return window;
}, [location]);
return windowContext;
}
const components = {
default: (props: IDockviewPanelProps<{ title: string }>) => {
const windowContext = usePopoutWindowContext(props.api);
React.useEffect(() => {
setTimeout(() => {
const a = windowContext.document.createElement('div');
a.className = 'aaa';
windowContext.document.body.appendChild(a);
}, 5000);
}, [windowContext]);
const [reset, setReset] = React.useState<boolean>(false);
return (
<div
style={{
@ -19,7 +60,19 @@ const components = {
background: 'var(--dv-group-view-background-color)',
}}
>
{props.params.title}
<button
onClick={() => {
console.log(windowContext);
setReset(true);
setTimeout(() => {
setReset(false);
}, 2000);
}}
>
Print
</button>
{!reset && <PopoverMenu api={props.api} />}
{props.api.title}
</div>
);
},
@ -31,31 +84,31 @@ function loadDefaultLayout(api: DockviewApi) {
component: 'default',
});
api.addPanel({
id: 'panel_2',
component: 'default',
});
// api.addPanel({
// id: 'panel_2',
// component: 'default',
// });
api.addPanel({
id: 'panel_3',
component: 'default',
});
// api.addPanel({
// id: 'panel_3',
// component: 'default',
// });
api.addPanel({
id: 'panel_4',
component: 'default',
});
// api.addPanel({
// id: 'panel_4',
// component: 'default',
// });
api.addPanel({
id: 'panel_5',
component: 'default',
position: { direction: 'right' },
});
// api.addPanel({
// id: 'panel_5',
// component: 'default',
// position: { direction: 'right' },
// });
api.addPanel({
id: 'panel_6',
component: 'default',
});
// api.addPanel({
// id: 'panel_6',
// component: 'default',
// });
}
let panelCount = 0;
@ -223,7 +276,7 @@ const RightComponent = (props: IDockviewHeaderActionsProps) => {
const group = props.containerApi.addGroup();
props.group.api.moveTo({ group });
} else {
props.containerApi.addPopoutGroup(props.group, {
const window = props.containerApi.addPopoutGroup(props.group, {
popoutUrl: '/popout/index.html',
});
}

View File

@ -0,0 +1,61 @@
import { useLayer, Arrow } from 'react-laag';
import { motion, AnimatePresence } from 'framer-motion';
import * as React from 'react';
import { DockviewPanelApi } from 'dockview';
export function PopoverMenu(props: { api: DockviewPanelApi }) {
const [isOpen, setOpen] = React.useState(false);
// helper function to close the menu
function close() {
setOpen(false);
}
const _window =
props.api.location.type === 'popout'
? props.api.location.getWindow()
: undefined;
const { renderLayer, triggerProps, layerProps, arrowProps } = useLayer({
isOpen,
onOutsideClick: close, // close the menu when the user clicks outside
onDisappear: close, // close the menu when the menu gets scrolled out of sight
overflowContainer: false, // keep the menu positioned inside the container
auto: true, // automatically find the best placement
placement: 'top-end', // we prefer to place the menu "top-end"
triggerOffset: 12, // keep some distance to the trigger
containerOffset: 16, // give the menu some room to breath relative to the container
arrowOffset: 16, // let the arrow have some room to breath also,
environment: _window,
container: _window
? () => {
const el = _window.document.body;
Object.setPrototypeOf(el, HTMLElement.prototype);
return el;
}
: undefined,
// container: props.window.document.body
});
// Again, we're using framer-motion for the transition effect
return (
<>
<button {...triggerProps} onClick={() => setOpen(!isOpen)}>
{isOpen ? 'Hide' : 'Show'}
</button>
{renderLayer(
<AnimatePresence>
{isOpen && (
<motion.ul {...layerProps}>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<Arrow {...arrowProps} />
</motion.ul>
)}
</AnimatePresence>
)}
</>
);
}