Panel
Komponent som används för att kunna visa fördjupande information eller ge plats för sekundära verktyg som till exempel filter, utan att behöva navigera bort från huvudinnehållet. Panelen används som en sekundär yta, inte som en tillfällig dialog, och visas till höger om huvudinnehållet.
import { Layout, LayoutContent, Main, Panel } from '@midas-ds/layout'
import { useState } from 'react'
import { Button } from '@midas-ds/components'
function App() {
const [isOpen, setIsOpen] = useState(false)
return (
<Layout>
<LayoutContent>
<Main>
<Button onPress={() => setIsOpen(true)}>Öppna panel</Button>
</Main>
<Panel
id='detaljer'
title='Detaljer'
isOpen={isOpen}
onOpenChange={setIsOpen}
>
{/* Panelinnehåll */}
</Panel>
</LayoutContent>
</Layout>
)
}
Användning
- Standardbeteendet för
panelBehaviorärreplaceoch detta rekommenderas för de flesta fall. Vi vill undvika att en ny panel läggs ovanpå en tidigare panel, eftersom det gör att användaren måste stänga flera paneler efter varandra för att komma till ursprungsläget.
Använd Panel för:
- Situationer användaren behöver stödjande information eller verktyg utan att lämna huvudinnehållet.
Använd inte Panel för:
- Navigering eller för innehåll som kräver en egen sida.
Varianter
Komponenten finns i två olika varianter. overlay där panelen lägger sig ovanför huvudinnehållet och push som ligger i samma nivå som huvudinnehållet och trycker ihop innehållet. Välj variant, overaly eller push baserat på vad som fungerar bäst utifrån användningssituationen, innehållshierarkin och användningsflödet.
overlaypassar bäst när panelens innehåll behöver få tillfälligt fokus jämfört med huvudinnehållet.pushpassar bäst när panelens innehåll behöver vara tillgängligt under längre tid, i mer ihållande flöden. Det kan dock vara lämpligt att växla tilloverlayvid smalare brytpunkter som en del i en responsiv design.
Implementation
Panel med egna åtgärder
Använd actions-propen för att lägga till egna knappar i panelens header, till höger om titeln och till vänster om stängknappen.
import { Layout, LayoutContent, Main, Panel } from '@midas-ds/layout'
import { Button } from '@midas-ds/components'
import { Ellipsis } from 'lucide-react'
import { useState } from 'react'
function App() {
const [isOpen, setIsOpen] = useState(false)
return (
<Layout>
<LayoutContent>
<Main>
<Button onPress={() => setIsOpen(true)}>Öppna panel</Button>
</Main>
<Panel
id='detaljer'
title='Detaljer'
isOpen={isOpen}
onOpenChange={setIsOpen}
actions={
<Button
variant='icon'
size='medium'
aria-label='Fler alternativ'
>
<Ellipsis size={20} />
</Button>
}
>
{/* Panelinnehåll */}
</Panel>
</LayoutContent>
</Layout>
)
}
Flera paneler med PanelProvider
När du har flera paneler som kan öppnas och stängas oberoende av varandra, använd PanelProvider och usePanels-hooken.
import { Layout, LayoutContent, Main, PanelProvider, PanelRegion, usePanels } from '@midas-ds/layout'
import { Button } from '@midas-ds/components'
function PanelControls() {
const { addPanel, closePanel } = usePanels()
return (
<>
<Button onPress={() => addPanel({ id: 'panel-a', title: 'Panel A' })}>Öppna Panel A</Button>
<Button onPress={() => addPanel({ id: 'panel-b', title: 'Panel B' })}>Öppna Panel B</Button>
</>
)
}
function App() {
return (
<PanelProvider>
<Layout>
<LayoutContent>
<Main>
<PanelControls />
</Main>
<PanelRegion />
</LayoutContent>
</Layout>
</PanelProvider>
)
}
<PanelProvider panelBehavior='replace'> {/* replace | bring-to-front | pop-to */}
Byt innehåll utan animation
Använd ett stabilt id när du anropar addPanel för att uppdatera panelinnehållet på plats utan att animera om. React känner igen id:t och uppdaterar titel och innehåll direkt.
import { Layout, LayoutContent, Main, PanelProvider, PanelRegion, usePanels } from '@midas-ds/layout'
const items = [
{ id: '1', name: 'Ansökan #1042', status: 'Inlämnad' },
{ id: '2', name: 'Ansökan #1043', status: 'Under granskning' },
{ id: '3', name: 'Ansökan #1044', status: 'Beviljad' },
]
function ItemList() {
const { addPanel } = usePanels()
return (
<ul>
{items.map(item => (
<li key={item.id}>
<button
onClick={() =>
addPanel({
id: 'detail', // same id every time → no re-animation
title: item.name,
children: <p>Status: {item.status}</p>,
})
}
>
{item.name}
</button>
</li>
))}
</ul>
)
}
function App() {
return (
<PanelProvider panelBehavior='replace'>
<Layout>
<LayoutContent>
<Main>
<ItemList />
</Main>
<PanelRegion />
</LayoutContent>
</Layout>
</PanelProvider>
)
}
API
Panel
| Name | Type | Default | Description |
|---|---|---|---|
id * | string | - | Required unique id used to manage panel state. |
title * | string | - | Panel title displayed in the header. |
isOpen | boolean | - | Controlled open state. |
defaultOpen | boolean | - | Uncontrolled initial open state. |
promoting | boolean | - | |
actions | ReactNode | - | Custom actions rendered in the panel header, to the right of the title. |
PanelProvider
| Name | Type | Default | Description |
|---|---|---|---|
defaultPanels | PanelItem[] | [] | Panels to open on mount. |
panelBehavior | PanelBehavior | replace | Behaviour when opening a panel that is already open.
Showing one panel at a time is recommended. |
panelVariant | PanelVariant | overlay | How the panel is displayed relative to the main content.
|
usePanels
Hook för att komma åt PanelContext och hantera panelernas tillstånd programmatiskt.
const { panels, addPanel, closePanel, removePanel } = usePanels()
| Name | Type | Default | Description |
|---|---|---|---|
panels * | PanelItem[] | - | The current list of panels. |
panelVariant * | PanelVariant | - | The active panel variant inherited from |
addPanel * | (panel: Omit<PanelItem, "isOpen" | "defaultOpen">) => void | - | Opens or activates a panel. If a panel with the same id exists, it is updated in place. |
closePanel * | (id: string) => void | - | Closes a panel, triggering the exit animation. |
removePanel * | (id: string) => void | - | Permanently removes a panel from state. |
resetPromoting * | (id: string) => void | - |