aside and main logic

This commit is contained in:
Nate Kelley 2025-08-15 16:57:37 -06:00
parent 4418f7c2c4
commit a13aa3e831
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
7 changed files with 23 additions and 6 deletions

View File

@ -54,6 +54,8 @@ export const AppLayout: React.FC<
leftChildren={sidebar}
rightChildren={PageContent}
initialLayout={initialLayout}
leftPanelElement="aside"
rightPanelElement="main"
/>
);
};

View File

@ -145,6 +145,8 @@ const AppSplitterBase = forwardRef<
leftChildren,
rightChildren,
defaultLayout,
leftPanelElement = 'div',
rightPanelElement = 'div',
leftPanelMinSize = 0,
rightPanelMinSize = 0,
leftPanelMaxSize,
@ -646,6 +648,7 @@ const AppSplitterBase = forwardRef<
width={isVertical ? leftSize : 'auto'}
height={!isVertical ? leftSize : 'auto'}
hidden={leftHidden}
as={leftPanelElement}
>
{leftChildren}
</Panel>
@ -664,6 +667,7 @@ const AppSplitterBase = forwardRef<
width={isVertical ? rightSize : 'auto'}
height={!isVertical ? rightSize : 'auto'}
hidden={rightHidden}
as={rightPanelElement}
>
{rightChildren}
</Panel>

View File

@ -1,6 +1,7 @@
export type PanelSize = `${number}px` | `${number}%` | 'auto' | number;
type PanelSizeWithAuto = Exclude<PanelSize, 'auto'>;
export type LayoutSize = ['auto', PanelSizeWithAuto] | [PanelSizeWithAuto, 'auto'];
export type PanelElement = 'aside' | 'div' | 'main';
export interface IAppSplitterProps {
/** Content to display in the left panel */
@ -102,6 +103,12 @@ export interface IAppSplitterProps {
/** Additional CSS classes for the right panel */
rightPanelClassName?: string;
/** HTML element type for the left panel. Defaults to 'div' */
leftPanelElement?: PanelElement;
/** HTML element type for the right panel. Defaults to 'div' */
rightPanelElement?: PanelElement;
}
/**

View File

@ -2,6 +2,7 @@
import React from 'react';
import { cn } from '@/lib/classMerge';
import type { PanelElement } from './AppSplitter.types';
interface IPanelProps {
children: React.ReactNode;
@ -12,10 +13,11 @@ interface IPanelProps {
className?: string;
hidden?: boolean;
style?: React.CSSProperties;
as?: PanelElement;
}
export const Panel: React.FC<IPanelProps> = React.memo(
({ children, width, height, minSize, maxSize, className, hidden, style }) => {
({ children, width, height, minSize, maxSize, className, hidden, style, as = 'div' }) => {
if (hidden) return null;
const panelStyle: React.CSSProperties = {
@ -26,18 +28,19 @@ export const Panel: React.FC<IPanelProps> = React.memo(
...(maxSize !== undefined && { maxWidth: `${maxSize}px`, maxHeight: `${maxSize}px` }),
};
const Component = as;
return (
<div
<Component
className={cn(
'panel overflow-hidden',
// When we have a specific width or height, we should not grow/shrink
width !== 'auto' || height !== 'auto' ? 'flex-shrink-0 flex-grow-0' : 'flex-1',
className
)}
style={panelStyle}
>
{children}
</div>
</Component>
);
}
);

View File

@ -2,7 +2,7 @@ import type React from 'react';
import { SidebarPrimary } from '@/components/features/sidebars/SidebarPrimary';
import { AppLayout, type LayoutSize } from '@/components/ui/layouts/AppLayout';
export const PRIMARY_APP_LAYOUT_ID = 'app-layout';
export const PRIMARY_APP_LAYOUT_ID = 'primary-sidebar';
const DEFAULT_LAYOUT: LayoutSize = ['230px', 'auto'];

View File

@ -23,7 +23,7 @@ function RouteComponent() {
<AppSplitter
preserveSide="right"
defaultLayout={['50%', 'auto']}
autoSaveId="test0"
autoSaveId={layoutId}
leftChildren={<div>Left</div>}
rightChildren={<RightPanel />}
initialLayout={initialLayout}

View File

@ -32,6 +32,7 @@ export const Route = createFileRoute('/app')({
},
component: () => {
const { initialLayout } = Route.useLoaderData();
return (
<AppProviders>
<PrimaryAppLayout initialLayout={initialLayout}>