Zum Hauptinhalt springen

Modal

Die Modal-Komponente wird verwendet, um Inhalte in einem Overlay-Fenster anzuzeigen, das über der Hauptseite schwebt. Sie ist ideal für Dialoge, Formulare, Bestätigungen und andere Interaktionen, die die Aufmerksamkeit des Benutzers erfordern.

Import

import { Modal } from '@smolitux/core';

Verwendung

Einfaches Modal

import { useState } from 'react';
import { Modal, Button } from '@smolitux/core';

function Example() {
const [isOpen, setIsOpen] = useState(false);

return (
<>
<Button onClick={() => setIsOpen(true)}>Modal öffnen</Button>

<Modal
isOpen={isOpen}
onClose={() => setIsOpen(false)}
title="Beispiel-Modal"
>
<p>Dies ist der Inhalt des Modals.</p>
</Modal>
</>
);
}
<Modal
isOpen={isOpen}
onClose={() => setIsOpen(false)}
title="Bestätigung"
footer={
<div className="flex justify-end space-x-2">
<Button variant="outline" onClick={() => setIsOpen(false)}>Abbrechen</Button>
<Button variant="primary" onClick={handleConfirm}>Bestätigen</Button>
</div>
}
>
<p>Möchten Sie diese Aktion wirklich durchführen?</p>
</Modal>

Verschiedene Modal-Größen

<Modal
isOpen={isOpen}
onClose={() => setIsOpen(false)}
title="Kleines Modal"
size="sm"
>
<p>Dies ist ein kleines Modal.</p>
</Modal>

<Modal
isOpen={isOpen}
onClose={() => setIsOpen(false)}
title="Großes Modal"
size="lg"
>
<p>Dies ist ein großes Modal.</p>
</Modal>

<Modal
isOpen={isOpen}
onClose={() => setIsOpen(false)}
title="Vollbild-Modal"
size="full"
>
<p>Dies ist ein Vollbild-Modal.</p>
</Modal>
<Modal
isOpen={isOpen}
onClose={() => setIsOpen(false)}
title="Modal oben"
position="top"
>
<p>Dieses Modal erscheint am oberen Rand des Bildschirms.</p>
</Modal>

<Modal
isOpen={isOpen}
onClose={() => setIsOpen(false)}
title="Modal rechts"
position="right"
>
<p>Dieses Modal erscheint am rechten Rand des Bildschirms.</p>
</Modal>
<Modal
isOpen={isOpen}
onClose={() => setIsOpen(false)}
title="Neuen Benutzer erstellen"
footer={
<div className="flex justify-end space-x-2">
<Button variant="outline" onClick={() => setIsOpen(false)}>Abbrechen</Button>
<Button variant="primary" type="submit" form="user-form">Speichern</Button>
</div>
}
>
<form id="user-form" onSubmit={handleSubmit}>
<div className="space-y-4">
<Input label="Name" name="name" required />
<Input label="E-Mail" name="email" type="email" required />
<Select
label="Rolle"
name="role"
options={[
{ value: 'user', label: 'Benutzer' },
{ value: 'admin', label: 'Administrator' }
]}
/>
</div>
</form>
</Modal>

Props

PropTypStandardBeschreibung
isOpenboolean-Steuert die Sichtbarkeit des Modals
onClose() => void-Callback-Funktion, die aufgerufen wird, wenn das Modal geschlossen wird
titleReactNode-Der Titel des Modals (optional)
childrenReactNode-Der Inhalt des Modals
footerReactNode-Der Footer-Inhalt des Modals (optional)
size'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'full''md'Die Größe des Modals
position'center' | 'top' | 'right' | 'bottom' | 'left''center'Die Position des Modals
closeOnOverlayClickbooleantrueOb das Modal geschlossen werden soll, wenn auf den Overlay-Hintergrund geklickt wird
closeOnEscbooleantrueOb das Modal geschlossen werden soll, wenn die Escape-Taste gedrückt wird
classNamestring''Zusätzliche CSS-Klassen für das Modal
headerClassNamestring''Zusätzliche CSS-Klassen für den Header
bodyClassNamestring''Zusätzliche CSS-Klassen für den Body
footerClassNamestring''Zusätzliche CSS-Klassen für den Footer
overlayClassNamestring''Zusätzliche CSS-Klassen für das Overlay
idstring-ID für Barrierefreiheit
animatedbooleantrueOb das Modal beim Öffnen animiert werden soll
showCloseButtonbooleantrueOb das Modal einen Schließen-Button haben soll
shadowbooleantrueOb das Modal einen Schatten haben soll
roundedbooleantrueOb das Modal abgerundete Ecken haben soll
borderedbooleantrueOb das Modal einen Rahmen haben soll
initialFocusbooleantrueOb das Modal beim Öffnen fokussiert werden soll
restoreFocusbooleantrueOb das Modal beim Schließen den vorherigen Fokus wiederherstellen soll

Barrierefreiheit

Die Modal-Komponente ist für Barrierefreiheit optimiert:

  • Verwendet die richtige ARIA-Rolle (role="dialog")
  • Fokus-Management: Fokus wird beim Öffnen auf das Modal gesetzt und beim Schließen wiederhergestellt
  • Fokus-Falle: Der Fokus bleibt innerhalb des Modals, wenn es geöffnet ist
  • Tastaturnavigation: Schließen mit Escape-Taste
  • Screenreader-Unterstützung: Korrekte ARIA-Attribute

Beispiele

<Modal
isOpen={isOpen}
onClose={() => setIsOpen(false)}
headerClassName="bg-primary-500 text-white"
>
<div className="flex items-center">
<Icon name="star" className="mr-2" />
<h2 className="text-xl font-bold">Premium-Funktion</h2>
</div>
<div className="mt-4">
<p>Diese Funktion ist nur für Premium-Benutzer verfügbar.</p>
</div>
</Modal>
<Modal
isOpen={isOpen}
onClose={() => setIsOpen(false)}
title="Eintrag löschen"
size="sm"
footer={
<div className="flex justify-end space-x-2">
<Button variant="outline" onClick={() => setIsOpen(false)}>Abbrechen</Button>
<Button variant="danger" onClick={handleDelete}>Löschen</Button>
</div>
}
>
<p>Sind Sie sicher, dass Sie diesen Eintrag löschen möchten? Diese Aktion kann nicht rückgängig gemacht werden.</p>
</Modal>

Verschachteltes Modal

function NestedModalExample() {
const [isFirstOpen, setIsFirstOpen] = useState(false);
const [isSecondOpen, setIsSecondOpen] = useState(false);

return (
<>
<Button onClick={() => setIsFirstOpen(true)}>Erstes Modal öffnen</Button>

<Modal
isOpen={isFirstOpen}
onClose={() => setIsFirstOpen(false)}
title="Erstes Modal"
>
<p>Dies ist das erste Modal.</p>
<Button onClick={() => setIsSecondOpen(true)}>Zweites Modal öffnen</Button>

<Modal
isOpen={isSecondOpen}
onClose={() => setIsSecondOpen(false)}
title="Zweites Modal"
>
<p>Dies ist das zweite Modal, das über dem ersten schwebt.</p>
</Modal>
</Modal>
</>
);
}