Store portal elements as state instead of refs (#1212)

i ❤️ dan abramov
This commit is contained in:
Brendan Allan 2023-08-13 10:27:42 -07:00 committed by GitHub
parent c86a728a1a
commit a74e9aa341
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 29 additions and 36 deletions

View file

@ -1,18 +1,18 @@
import { PropsWithChildren, RefObject, createContext, useContext, useRef } from 'react';
import { PropsWithChildren, createContext, useContext, useState } from 'react';
interface QuickPreviewContext {
ref: RefObject<HTMLDivElement>;
ref: HTMLDivElement | null;
}
const QuickPreviewContext = createContext<QuickPreviewContext | null>(null);
export const QuickPreviewContextProvider = ({ children }: PropsWithChildren) => {
const ref = useRef<HTMLDivElement>(null);
const [ref, setRef] = useState<HTMLDivElement | null>(null);
return (
<QuickPreviewContext.Provider value={{ ref }}>
{children}
<div ref={ref} />
<div ref={setRef} />
</QuickPreviewContext.Provider>
);
};

View file

@ -172,8 +172,7 @@ export default memo(
)}
</div>
{quickPreviewCtx.ref.current &&
createPortal(<QuickPreview />, quickPreviewCtx.ref.current)}
{quickPreviewCtx.ref && createPortal(<QuickPreview />, quickPreviewCtx.ref)}
</>
);
}

View file

@ -1,21 +1,21 @@
import { RefObject, createContext, useContext, useRef } from 'react';
import { createContext, useContext, useState } from 'react';
import { Outlet } from 'react-router';
import TopBar from '.';
interface TopBarContext {
left: RefObject<HTMLDivElement>;
right: RefObject<HTMLDivElement>;
left: HTMLDivElement | null;
right: HTMLDivElement | null;
}
const TopBarContext = createContext<TopBarContext | null>(null);
export const Component = () => {
const left = useRef<HTMLDivElement>(null);
const right = useRef<HTMLDivElement>(null);
const [left, setLeft] = useState<HTMLDivElement | null>(null);
const [right, setRight] = useState<HTMLDivElement | null>(null);
return (
<TopBarContext.Provider value={{ left, right }}>
<TopBar leftRef={left} rightRef={right} />
<TopBar leftRef={setLeft} rightRef={setRight} />
<Outlet />
</TopBarContext.Provider>
);

View file

@ -2,17 +2,13 @@ import { ReactNode } from 'react';
import { createPortal } from 'react-dom';
import { useTopBarContext } from './Layout';
interface Props {
left?: ReactNode;
right?: ReactNode;
}
export const TopBarPortal = ({ left, right }: Props) => {
export const TopBarPortal = (props: { left?: ReactNode; right?: ReactNode }) => {
const ctx = useTopBarContext();
return (
<>
{left && ctx.left.current && createPortal(left, ctx.left.current)}
{right && ctx.right.current && createPortal(right, ctx.right.current)}
{props.left && ctx.left && createPortal(props.left, ctx.left)}
{props.right && ctx.right && createPortal(props.right, ctx.right)}
</>
);
};

View file

@ -1,33 +1,31 @@
import { RefObject } from 'react';
import { Ref } from 'react';
import { NavigationButtons } from './NavigationButtons';
import SearchBar from './SearchBar';
export const TOP_BAR_HEIGHT = 46;
interface Props {
leftRef?: RefObject<HTMLDivElement>;
rightRef?: RefObject<HTMLDivElement>;
leftRef?: Ref<HTMLDivElement>;
rightRef?: Ref<HTMLDivElement>;
}
const TopBar = (props: Props) => {
return (
<div
data-tauri-drag-region
className="
const TopBar = (props: Props) => (
<div
data-tauri-drag-region
className="
duration-250 top-bar-blur absolute left-0 top-0 z-50 flex
h-[46px] w-full flex-row items-center justify-center overflow-hidden
border-b border-sidebar-divider bg-app/90 px-3.5
transition-[background-color,border-color] ease-out
"
>
<div data-tauri-drag-region className="flex flex-1 flex-row items-center">
<NavigationButtons />
<div ref={props.leftRef} />
</div>
<SearchBar />
<div className="flex-1" ref={props.rightRef} />
>
<div data-tauri-drag-region className="flex flex-1 flex-row items-center">
<NavigationButtons />
<div ref={props.leftRef} />
</div>
);
};
<SearchBar />
<div className="flex-1" ref={props.rightRef} />
</div>
);
export default TopBar;