Files
starter-e2e-mrf7gcl3/packages/components/src/Panel.tsx
2026-07-10 19:24:06 +02:00

49 lines
1.5 KiB
TypeScript

import React from 'react'
import { Card, Group, Stack, Text, Title } from '@mantine/core'
export interface PanelProps {
/** Optional panel heading. */
title?: React.ReactNode
/** Optional sub-text under the heading. */
description?: React.ReactNode
/** Right-aligned header actions. */
actions?: React.ReactNode
/** Panel body. */
children: React.ReactNode
/** Remove inner padding (e.g. for a flush table). */
noPadding?: boolean
}
// A bordered content section with an optional titled header. The workhorse
// container — group related content into Panels instead of loose Cards.
export function Panel({ title, description, actions, children, noPadding }: PanelProps) {
return (
<Card withBorder radius="lg" padding={noPadding ? 0 : 'lg'}>
{title || actions ? (
<Group
justify="space-between"
align="flex-end"
wrap="nowrap"
p={noPadding ? 'lg' : 0}
pb={noPadding ? 'sm' : 'md'}
>
<Stack gap={2} style={{ minWidth: 0 }}>
{title ? (
<Title order={2} fz={16} fw={620} style={{ letterSpacing: '-0.02em' }}>
{title}
</Title>
) : null}
{description ? (
<Text c="dimmed" size="xs">
{description}
</Text>
) : null}
</Stack>
{actions ? <div style={{ flexShrink: 0 }}>{actions}</div> : null}
</Group>
) : null}
{children}
</Card>
)
}