feat: self-portaling DetailPanel via AppShell portal target
Some checks failed
Build & Publish / publish (push) Failing after 50s
Some checks failed
Build & Publish / publish (push) Failing after 50s
DetailPanel now uses createPortal to render itself into #cameleer-detail-panel-root, a div that AppShell places as a direct sibling of .main in the top-level flex row. This means pages can render <DetailPanel> anywhere in their JSX and it automatically appears at the correct layout position. AppShell's detail prop is deprecated and ignored — the portal handles positioning automatically. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@cameleer/design-system",
|
||||
"version": "0.1.3",
|
||||
"version": "0.1.5",
|
||||
"type": "module",
|
||||
"main": "./dist/index.es.js",
|
||||
"module": "./dist/index.es.js",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useState, type ReactNode } from 'react'
|
||||
import { createPortal } from 'react-dom'
|
||||
import styles from './DetailPanel.module.css'
|
||||
|
||||
interface Tab {
|
||||
@@ -22,7 +23,7 @@ export function DetailPanel({ open, onClose, title, tabs, children, actions, cla
|
||||
|
||||
const activeContent = tabs?.find((t) => t.value === activeTab)?.content
|
||||
|
||||
return (
|
||||
const panel = (
|
||||
<aside
|
||||
className={`${styles.panel} ${open ? styles.open : ''} ${className ?? ''}`}
|
||||
aria-hidden={!open}
|
||||
@@ -65,4 +66,8 @@ export function DetailPanel({ open, onClose, title, tabs, children, actions, cla
|
||||
)}
|
||||
</aside>
|
||||
)
|
||||
|
||||
// Portal to AppShell level if target exists, otherwise render in place
|
||||
const portalTarget = document.getElementById('cameleer-detail-panel-root')
|
||||
return portalTarget ? createPortal(panel, portalTarget) : panel
|
||||
}
|
||||
|
||||
@@ -4,17 +4,18 @@ import type { ReactNode } from 'react'
|
||||
interface AppShellProps {
|
||||
sidebar: ReactNode
|
||||
children: ReactNode
|
||||
/** @deprecated DetailPanel now portals itself automatically. This prop is ignored. */
|
||||
detail?: ReactNode
|
||||
}
|
||||
|
||||
export function AppShell({ sidebar, children, detail }: AppShellProps) {
|
||||
export function AppShell({ sidebar, children }: AppShellProps) {
|
||||
return (
|
||||
<div className={styles.app}>
|
||||
{sidebar}
|
||||
<div className={styles.main}>
|
||||
{children}
|
||||
</div>
|
||||
{detail}
|
||||
<div id="cameleer-detail-panel-root" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user