mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-29 21:51:59 +02:00
Move portal to shared ui lib
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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}
|
||||
>
|
||||
<div className="absolute inset-0 pointer-events-none">
|
||||
<div
|
||||
style={environmentBgStyle}
|
||||
className="absolute inset-0 opacity-[0.07]"
|
||||
/>
|
||||
<div style={environmentBgStyle} className="absolute inset-0 opacity-[0.07]" />
|
||||
<div
|
||||
style={environmentBgStyle}
|
||||
className="absolute left-0 right-0 -bottom-[1px] h-[1px] opacity-20"
|
||||
@@ -132,7 +127,15 @@ export function Workspace() {
|
||||
'grid grid-rows-[auto_1fr]',
|
||||
)}
|
||||
>
|
||||
<HeaderSize hideControls size="lg" className="border-transparent flex items-center" osType={osType} hideWindowControls={settings.hideWindowControls} useNativeTitlebar={settings.useNativeTitlebar} interfaceScale={settings.interfaceScale}>
|
||||
<HeaderSize
|
||||
hideControls
|
||||
size="lg"
|
||||
className="border-transparent flex items-center"
|
||||
osType={osType}
|
||||
hideWindowControls={settings.hideWindowControls}
|
||||
useNativeTitlebar={settings.useNativeTitlebar}
|
||||
interfaceScale={settings.interfaceScale}
|
||||
>
|
||||
<SidebarActions />
|
||||
</HeaderSize>
|
||||
<ErrorBoundary name="Sidebar (Floating)">
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 (
|
||||
<div className={classNames(className, 'relative w-full h-full overflow-hidden')}>
|
||||
{children}
|
||||
{!hidden && (
|
||||
<>
|
||||
<div
|
||||
className="absolute inset-0 bg-black/50 z-20 transition-opacity"
|
||||
onClick={() => onHiddenChange?.(true)}
|
||||
/>
|
||||
<div
|
||||
style={{ width: floatingWidth }}
|
||||
className="absolute top-0 left-0 bottom-0 z-20 animate-slide-in-left"
|
||||
>
|
||||
{sidebar}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
style={styles}
|
||||
|
||||
@@ -8,10 +8,16 @@ export function usePortal(name: string) {
|
||||
}
|
||||
|
||||
function getOrCreatePortal(name: string) {
|
||||
const portalContainer = document.getElementById(PORTAL_CONTAINER_ID) as HTMLDivElement;
|
||||
let portalContainer = document.getElementById(PORTAL_CONTAINER_ID);
|
||||
if (!portalContainer) {
|
||||
portalContainer = document.createElement('div');
|
||||
portalContainer.id = PORTAL_CONTAINER_ID;
|
||||
document.body.appendChild(portalContainer);
|
||||
}
|
||||
|
||||
let existing = portalContainer.querySelector(`:scope > [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;
|
||||
@@ -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";
|
||||
|
||||
Reference in New Issue
Block a user