From cc504e0a1c8512cce6a89285769650bab34057aa Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Thu, 12 Mar 2026 14:28:15 -0700 Subject: [PATCH] Move portal to shared ui lib --- apps/yaak-client/components/Toasts.tsx | 2 +- apps/yaak-client/components/Workspace.tsx | 19 ++++++++------ apps/yaak-client/components/core/Dialog.tsx | 2 +- apps/yaak-client/components/core/Dropdown.tsx | 2 +- apps/yaak-client/components/core/Tooltip.tsx | 2 +- .../ui/src}/components/Overlay.tsx | 0 .../ui/src}/components/Portal.tsx | 0 packages/ui/src/components/SidebarLayout.tsx | 26 +++++++++++++++++++ .../ui/src}/hooks/usePortal.ts | 10 +++++-- packages/ui/src/index.ts | 3 +++ 10 files changed, 52 insertions(+), 14 deletions(-) rename {apps/yaak-client => packages/ui/src}/components/Overlay.tsx (100%) rename {apps/yaak-client => packages/ui/src}/components/Portal.tsx (100%) rename {apps/yaak-client => packages/ui/src}/hooks/usePortal.ts (61%) diff --git a/apps/yaak-client/components/Toasts.tsx b/apps/yaak-client/components/Toasts.tsx index 65cef54b..fe499f31 100644 --- a/apps/yaak-client/components/Toasts.tsx +++ b/apps/yaak-client/components/Toasts.tsx @@ -4,7 +4,7 @@ import type { ReactNode } from 'react'; import { hideToast, toastsAtom } from '../lib/toast'; import { Toast, type ToastProps } from './core/Toast'; import { ErrorBoundary } from './ErrorBoundary'; -import { Portal } from './Portal'; +import { Portal } from '@yaakapp-internal/ui'; export type ToastInstance = { id: string; diff --git a/apps/yaak-client/components/Workspace.tsx b/apps/yaak-client/components/Workspace.tsx index 1012aaca..ce0f62f1 100644 --- a/apps/yaak-client/components/Workspace.tsx +++ b/apps/yaak-client/components/Workspace.tsx @@ -1,5 +1,6 @@ import { type } from '@tauri-apps/plugin-os'; import { settingsAtom, workspacesAtom } from '@yaakapp-internal/models'; +import { HeaderSize, Overlay, SidebarLayout } from '@yaakapp-internal/ui'; import classNames from 'classnames'; import { useAtomValue } from 'jotai'; import * as m from 'motion/react-m'; @@ -39,15 +40,12 @@ import { HStack } from './core/Stacks'; import { ErrorBoundary } from './ErrorBoundary'; import { FolderLayout } from './FolderLayout'; import { GrpcConnectionLayout } from './GrpcConnectionLayout'; -import { HeaderSize, SidebarLayout } from '@yaakapp-internal/ui'; import { HttpRequestLayout } from './HttpRequestLayout'; -import { Overlay } from './Overlay'; import Sidebar from './Sidebar'; import { SidebarActions } from './SidebarActions'; import { WebsocketRequestLayout } from './WebsocketRequestLayout'; import { WorkspaceHeader } from './WorkspaceHeader'; -const head = { gridArea: 'head' }; const body = { gridArea: 'body' }; export function Workspace() { @@ -85,10 +83,7 @@ export function Workspace() { interfaceScale={settings.interfaceScale} >
-
+
- + diff --git a/apps/yaak-client/components/core/Dialog.tsx b/apps/yaak-client/components/core/Dialog.tsx index 455e0358..0dc9c416 100644 --- a/apps/yaak-client/components/core/Dialog.tsx +++ b/apps/yaak-client/components/core/Dialog.tsx @@ -2,7 +2,7 @@ import classNames from 'classnames'; import * as m from 'motion/react-m'; import type { ReactNode } from 'react'; import { useMemo } from 'react'; -import { Overlay } from '../Overlay'; +import { Overlay } from '@yaakapp-internal/ui'; import { Heading } from './Heading'; import { IconButton } from './IconButton'; import type { DialogSize } from '@yaakapp-internal/plugins'; diff --git a/apps/yaak-client/components/core/Dropdown.tsx b/apps/yaak-client/components/core/Dropdown.tsx index 1c289492..e014d799 100644 --- a/apps/yaak-client/components/core/Dropdown.tsx +++ b/apps/yaak-client/components/core/Dropdown.tsx @@ -32,7 +32,7 @@ import { generateId } from '../../lib/generateId'; import { getNodeText } from '../../lib/getNodeText'; import { jotaiStore } from '../../lib/jotai'; import { ErrorBoundary } from '../ErrorBoundary'; -import { Overlay } from '../Overlay'; +import { Overlay } from '@yaakapp-internal/ui'; import { Button } from './Button'; import { Hotkey } from './Hotkey'; import { Icon, LoadingIcon, type IconProps } from '@yaakapp-internal/ui'; diff --git a/apps/yaak-client/components/core/Tooltip.tsx b/apps/yaak-client/components/core/Tooltip.tsx index 563eb854..2174cc6c 100644 --- a/apps/yaak-client/components/core/Tooltip.tsx +++ b/apps/yaak-client/components/core/Tooltip.tsx @@ -2,7 +2,7 @@ import classNames from 'classnames'; import type { CSSProperties, KeyboardEvent, ReactNode } from 'react'; import { useRef, useState } from 'react'; import { generateId } from '../../lib/generateId'; -import { Portal } from '../Portal'; +import { Portal } from '@yaakapp-internal/ui'; export interface TooltipProps { children: ReactNode; diff --git a/apps/yaak-client/components/Overlay.tsx b/packages/ui/src/components/Overlay.tsx similarity index 100% rename from apps/yaak-client/components/Overlay.tsx rename to packages/ui/src/components/Overlay.tsx diff --git a/apps/yaak-client/components/Portal.tsx b/packages/ui/src/components/Portal.tsx similarity index 100% rename from apps/yaak-client/components/Portal.tsx rename to packages/ui/src/components/Portal.tsx diff --git a/packages/ui/src/components/SidebarLayout.tsx b/packages/ui/src/components/SidebarLayout.tsx index 70a6f26f..af4ad475 100644 --- a/packages/ui/src/components/SidebarLayout.tsx +++ b/packages/ui/src/components/SidebarLayout.tsx @@ -13,6 +13,8 @@ interface Props { onWidthChange: (width: number) => void; hidden?: boolean; onHiddenChange?: (hidden: boolean) => void; + floating?: boolean; + floatingWidth?: number; defaultWidth?: number; minWidth?: number; className?: string; @@ -25,6 +27,8 @@ export function SidebarLayout({ onWidthChange, hidden = false, onHiddenChange, + floating = false, + floatingWidth = 320, defaultWidth = 250, minWidth = 50, className, @@ -75,6 +79,28 @@ export function SidebarLayout({ onWidthChange(defaultWidth); }, [onWidthChange, defaultWidth]); + if (floating) { + return ( +
+ {children} + {!hidden && ( + <> +
onHiddenChange?.(true)} + /> +
+ {sidebar} +
+ + )} +
+ ); + } + return (
[data-portal-name="${name}"]`); if (!existing) { - const el: HTMLDivElement = document.createElement('div'); + const el = document.createElement('div'); el.setAttribute('data-portal-name', name); portalContainer.appendChild(el); existing = el; diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts index 04f167bc..b661e565 100644 --- a/packages/ui/src/index.ts +++ b/packages/ui/src/index.ts @@ -28,3 +28,6 @@ export type { SplitLayoutLayout, SlotProps } from "./components/SplitLayout"; export { Table, TableBody, TableHead, TableRow, TableCell, TruncatedWideTableCell, TableHeaderCell } from "./components/Table"; export { clamp } from "./lib/clamp"; export { useContainerSize } from "./hooks/useContainerSize"; +export { Overlay } from "./components/Overlay"; +export { Portal } from "./components/Portal"; +export { usePortal } from "./hooks/usePortal";