feat(ui): update panel lib, move gallery to percentages

This commit is contained in:
psychedelicious 2023-12-29 15:34:04 +11:00 committed by Kent Keirsey
parent 47b1fd4bce
commit 10fd4f6a61
7 changed files with 57 additions and 134 deletions

View File

@ -94,7 +94,7 @@
"react-icons": "^4.12.0",
"react-konva": "^18.2.10",
"react-redux": "^9.0.4",
"react-resizable-panels": "^0.0.55",
"react-resizable-panels": "^1.0.5",
"react-select": "5.7.7",
"react-textarea-autosize": "^8.5.3",
"react-use": "^17.4.2",

View File

@ -132,8 +132,8 @@ dependencies:
specifier: ^9.0.4
version: 9.0.4(@types/react@18.2.46)(react@18.2.0)(redux@5.0.1)
react-resizable-panels:
specifier: ^0.0.55
version: 0.0.55(react-dom@18.2.0)(react@18.2.0)
specifier: ^1.0.5
version: 1.0.5(react-dom@18.2.0)(react@18.2.0)
react-select:
specifier: 5.7.7
version: 5.7.7(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0)
@ -11199,8 +11199,8 @@ packages:
use-sidecar: 1.1.2(@types/react@18.2.46)(react@18.2.0)
dev: false
/react-resizable-panels@0.0.55(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-J/LTFzUEjJiqwSjVh8gjUXkQDA8MRPjARASfn++d2+KOgA+9UcRYUfE3QBJixer2vkk+ffQ4cq3QzWzzHgqYpQ==}
/react-resizable-panels@1.0.5(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-OP0whNQCko+f4BgoptGaeIc7StBRyeMeJ+8r/7rXACBDf9W5EcMWuM32hfqPDMenS2HFy/eZVi/r8XqK+ZIEag==}
peerDependencies:
react: ^16.14.0 || ^17.0.0 || ^18.0.0
react-dom: ^16.14.0 || ^17.0.0 || ^18.0.0

View File

@ -5,7 +5,7 @@ import QueueControls from 'features/queue/components/QueueControls';
import ResizeHandle from 'features/ui/components/tabs/ResizeHandle';
import { usePanelStorage } from 'features/ui/hooks/usePanelStorage';
import type { CSSProperties } from 'react';
import { memo, useCallback, useRef, useState } from 'react';
import { memo, useCallback, useRef } from 'react';
import type { ImperativePanelGroupHandle } from 'react-resizable-panels';
import { Panel, PanelGroup } from 'react-resizable-panels';
@ -15,8 +15,6 @@ import WorkflowPanel from './workflow/WorkflowPanel';
const panelGroupStyles: CSSProperties = { height: '100%', width: '100%' };
const NodeEditorPanelGroup = () => {
const [isTopPanelCollapsed, setIsTopPanelCollapsed] = useState(false);
const [isBottomPanelCollapsed, setIsBottomPanelCollapsed] = useState(false);
const panelGroupRef = useRef<ImperativePanelGroupHandle>(null);
const panelStorage = usePanelStorage();
const handleDoubleClickHandle = useCallback(() => {
@ -37,31 +35,14 @@ const NodeEditorPanelGroup = () => {
style={panelGroupStyles}
storage={panelStorage}
>
<Panel
id="workflow"
collapsible
onCollapse={setIsTopPanelCollapsed}
minSize={25}
>
<Panel id="workflow" collapsible minSize={25}>
<WorkflowPanel />
</Panel>
<ResizeHandle
direction="vertical"
onDoubleClick={handleDoubleClickHandle}
collapsedDirection={
isTopPanelCollapsed
? 'top'
: isBottomPanelCollapsed
? 'bottom'
: undefined
}
/>
<Panel
id="inspector"
collapsible
onCollapse={setIsBottomPanelCollapsed}
minSize={25}
>
<Panel id="inspector" collapsible minSize={25}>
<InspectorPanel />
</Panel>
</PanelGroup>

View File

@ -1,27 +1,21 @@
import { Flex } from '@chakra-ui/layout';
import { Portal } from '@chakra-ui/portal';
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
import type { RefObject } from 'react';
import { memo, useCallback } from 'react';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import { MdPhotoLibrary } from 'react-icons/md';
import type { ImperativePanelHandle } from 'react-resizable-panels';
type Props = {
isGalleryCollapsed: boolean;
galleryPanelRef: RefObject<ImperativePanelHandle>;
expandGallery: () => void;
};
const FloatingGalleryButton = ({
isGalleryCollapsed,
galleryPanelRef,
expandGallery,
}: Props) => {
const { t } = useTranslation();
const handleShowGallery = useCallback(() => {
galleryPanelRef.current?.expand();
}, [galleryPanelRef]);
if (!isGalleryCollapsed) {
return null;
}
@ -38,7 +32,7 @@ const FloatingGalleryButton = ({
<InvIconButton
tooltip="Show Gallery (G)"
aria-label={t('accessibility.showGalleryPanel')}
onClick={handleShowGallery}
onClick={expandGallery}
icon={<MdPhotoLibrary />}
p={0}
px={3}

View File

@ -95,13 +95,10 @@ const enabledTabsSelector = createMemoizedSelector(
}
);
const SIDE_PANEL_MIN_SIZE_PX = 448;
const MAIN_PANEL_MIN_SIZE_PX = 448;
const GALLERY_PANEL_MIN_SIZE_PX = 360;
export const NO_GALLERY_TABS: InvokeTabName[] = ['modelManager', 'queue'];
export const NO_SIDE_PANEL_TABS: InvokeTabName[] = ['modelManager', 'queue'];
const panelStyles: CSSProperties = { height: '100%', width: '100%' };
const GALLERY_MIN_SIZE_PCT = 20
const InvokeTabs = () => {
const activeTabIndex = useAppSelector(activeTabIndexSelector);
@ -155,53 +152,18 @@ const InvokeTabs = () => {
[dispatch, enabledTabs]
);
const {
isCollapsed: isSidePanelCollapsed,
expand: expandSidePanel,
collapse: collapseSidePanel,
toggle: toggleSidePanel,
} = usePanel(SIDE_PANEL_MIN_SIZE_PX, 'pixels');
const {
ref: galleryPanelRef,
minSize: galleryPanelMinSize,
isCollapsed: isGalleryPanelCollapsed,
setIsCollapsed: setIsGalleryPanelCollapsed,
onCollapse: onCollapseGalleryPanel,
onExpand: onExpandGalleryPanel,
reset: resetGalleryPanel,
expand: expandGalleryPanel,
collapse: collapseGalleryPanel,
toggle: toggleGalleryPanel,
} = usePanel(GALLERY_PANEL_MIN_SIZE_PX, 'pixels');
} = usePanel(GALLERY_MIN_SIZE_PCT);
useHotkeys(
'f',
() => {
if (isGalleryPanelCollapsed || isSidePanelCollapsed) {
expandGalleryPanel();
expandSidePanel();
} else {
collapseSidePanel();
collapseGalleryPanel();
}
},
[dispatch, isGalleryPanelCollapsed, isSidePanelCollapsed]
);
useHotkeys(
['t', 'o'],
() => {
toggleSidePanel();
},
[dispatch]
);
useHotkeys(
'g',
() => {
toggleGalleryPanel();
},
[dispatch]
);
useHotkeys('g', toggleGalleryPanel, []);
const panelStorage = usePanelStorage();
@ -219,73 +181,47 @@ const InvokeTabs = () => {
{tabs}
<Spacer />
</InvTabList>
{!NO_SIDE_PANEL_TABS.includes(activeTabName) && (
<Flex h="full" w={434} flexShrink={0}>
{activeTabName === 'nodes' ? (
<NodeEditorPanelGroup />
) : (
<ParametersPanel />
)}
</Flex>
)}
<PanelGroup
id="app"
autoSaveId="app"
direction="horizontal"
style={panelStyles}
storage={panelStorage}
units="pixels"
>
{/* {!NO_SIDE_PANEL_TABS.includes(activeTabName) && (
<>
<Panel
order={0}
id="side"
ref={sidePanelRef}
defaultSize={sidePanelMinSize}
minSize={sidePanelMinSize}
onCollapse={setIsSidePanelCollapsed}
collapsible
>
{activeTabName === 'nodes' ? (
<NodeEditorPanelGroup />
) : (
<ParametersPanel />
)}
</Panel>
<ResizeHandle
onDoubleClick={resetSidePanel}
collapsedDirection={isSidePanelCollapsed ? 'left' : undefined}
/>
<FloatingSidePanelButtons
isSidePanelCollapsed={isSidePanelCollapsed}
sidePanelRef={sidePanelRef}
/>
</>
)} */}
<Panel id="main" order={1} minSize={MAIN_PANEL_MIN_SIZE_PX}>
<InvTabPanels style={panelStyles}>{tabPanels}</InvTabPanels>
<Panel id="main" order={0} minSize={50}>
<Flex w="full" h="full" gap={4}>
{!NO_SIDE_PANEL_TABS.includes(activeTabName) && (
<Flex h="full" w={434} flexShrink={0}>
{activeTabName === 'nodes' ? (
<NodeEditorPanelGroup />
) : (
<ParametersPanel />
)}
</Flex>
)}
<InvTabPanels w="full" h="full">
{tabPanels}
</InvTabPanels>
</Flex>
</Panel>
{!NO_GALLERY_TABS.includes(activeTabName) && (
<>
<ResizeHandle
onDoubleClick={resetGalleryPanel}
collapsedDirection={isGalleryPanelCollapsed ? 'right' : undefined}
/>
<ResizeHandle onDoubleClick={resetGalleryPanel} />
<Panel
id="gallery"
ref={galleryPanelRef}
order={2}
order={1}
defaultSize={galleryPanelMinSize}
minSize={galleryPanelMinSize}
onCollapse={setIsGalleryPanelCollapsed}
onCollapse={onCollapseGalleryPanel}
onExpand={onExpandGalleryPanel}
collapsible
>
<ImageGalleryContent />
</Panel>
<FloatingGalleryButton
isGalleryCollapsed={isGalleryPanelCollapsed}
galleryPanelRef={galleryPanelRef}
expandGallery={expandGalleryPanel}
/>
</>
)}

View File

@ -36,7 +36,6 @@ const ImageToImageTab = () => {
direction="horizontal"
style={panelGroupStyles}
storage={panelStorage}
units="percentages"
>
<Panel
id="imageTab.content.initImage"

View File

@ -1,16 +1,28 @@
import { useCallback, useRef, useState } from 'react';
import { flushSync } from 'react-dom';
import type { ImperativePanelHandle, Units } from 'react-resizable-panels';
import type {
ImperativePanelHandle,
PanelOnCollapse,
PanelOnExpand,
} from 'react-resizable-panels';
export const usePanel = (minSize: number, units: Units) => {
export const usePanel = (minSize: number) => {
const ref = useRef<ImperativePanelHandle>(null);
const [isCollapsed, setIsCollapsed] = useState(() =>
Boolean(ref.current?.getCollapsed())
Boolean(ref.current?.isCollapsed())
);
const onCollapse = useCallback<PanelOnCollapse>(() => {
setIsCollapsed(true);
}, []);
const onExpand = useCallback<PanelOnExpand>(() => {
setIsCollapsed(false);
}, []);
const toggle = useCallback(() => {
if (ref.current?.getCollapsed()) {
if (ref.current?.isCollapsed()) {
flushSync(() => {
ref.current?.expand();
});
@ -35,15 +47,16 @@ export const usePanel = (minSize: number, units: Units) => {
const reset = useCallback(() => {
flushSync(() => {
ref.current?.resize(minSize, units);
ref.current?.resize(minSize);
});
}, [minSize, units]);
}, [minSize]);
return {
ref,
minSize,
isCollapsed,
setIsCollapsed,
onCollapse,
onExpand,
reset,
toggle,
expand,