From 0fd3a669c7ea27dffef622e125be73208c9a1353 Mon Sep 17 00:00:00 2001 From: mathuo <6710312+mathuo@users.noreply.github.com> Date: Sat, 27 Jan 2024 19:21:09 +0000 Subject: [PATCH] test --- .../docs/sandboxes/demo-dockview/src/app.tsx | 4 +- .../floatinggroup-dockview/src/app.tsx | 4 +- .../popoutgroup-dockview/package.json | 5 +- .../popoutgroup-dockview/src/app.tsx | 99 ++++++++++++++----- .../popoutgroup-dockview/src/popover.tsx | 61 ++++++++++++ 5 files changed, 144 insertions(+), 29 deletions(-) create mode 100644 packages/docs/sandboxes/popoutgroup-dockview/src/popover.tsx diff --git a/packages/docs/sandboxes/demo-dockview/src/app.tsx b/packages/docs/sandboxes/demo-dockview/src/app.tsx index 79885e0bf..975f3f6be 100644 --- a/packages/docs/sandboxes/demo-dockview/src/app.tsx +++ b/packages/docs/sandboxes/demo-dockview/src/app.tsx @@ -87,7 +87,7 @@ const RightControls = (props: IDockviewHeaderActionsProps) => { ); const [isPopout, setIsPopout] = React.useState( - 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 () => { diff --git a/packages/docs/sandboxes/floatinggroup-dockview/src/app.tsx b/packages/docs/sandboxes/floatinggroup-dockview/src/app.tsx index e3c066bbd..c90e32cec 100644 --- a/packages/docs/sandboxes/floatinggroup-dockview/src/app.tsx +++ b/packages/docs/sandboxes/floatinggroup-dockview/src/app.tsx @@ -255,13 +255,13 @@ const LeftComponent = (props: IDockviewHeaderActionsProps) => { const RightComponent = (props: IDockviewHeaderActionsProps) => { const [floating, setFloating] = React.useState( - 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'); } ); diff --git a/packages/docs/sandboxes/popoutgroup-dockview/package.json b/packages/docs/sandboxes/popoutgroup-dockview/package.json index 9a533bff7..9b8601416 100644 --- a/packages/docs/sandboxes/popoutgroup-dockview/package.json +++ b/packages/docs/sandboxes/popoutgroup-dockview/package.json @@ -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", @@ -29,4 +30,4 @@ "not ie <= 11", "not op_mini all" ] -} +} \ No newline at end of file diff --git a/packages/docs/sandboxes/popoutgroup-dockview/src/app.tsx b/packages/docs/sandboxes/popoutgroup-dockview/src/app.tsx index df732b7c0..57fe7e8be 100644 --- a/packages/docs/sandboxes/popoutgroup-dockview/src/app.tsx +++ b/packages/docs/sandboxes/popoutgroup-dockview/src/app.tsx @@ -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( + 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(false); + return (
- {props.params.title} + + {!reset && } + {props.api.title}
); }, @@ -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', }); } diff --git a/packages/docs/sandboxes/popoutgroup-dockview/src/popover.tsx b/packages/docs/sandboxes/popoutgroup-dockview/src/popover.tsx new file mode 100644 index 000000000..3b0b8d1f4 --- /dev/null +++ b/packages/docs/sandboxes/popoutgroup-dockview/src/popover.tsx @@ -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 ( + <> + + {renderLayer( + + {isOpen && ( + +
  • Item 1
  • +
  • Item 2
  • +
  • Item 3
  • +
  • Item 4
  • + +
    + )} +
    + )} + + ); +}