Coloriginz Design Systemshadcn custom registry

@col/confirm-dialog

Versie: 1.0.0 Toegevoegd: 2026-08-06

Herkomst

growerportal2 heeft dit drie keer met de hand geschreven: src/components/layout/user-management.tsx (regel 444-465, gebruiker verwijderen), src/features/fust/components/fust-settings.tsx (regel 840-864, fusttype/transporteur verwijderen) en src/features/fust/components/fust-pickups.tsx (regel 476-544, pickup als afgeleverd bevestigen — rijkere body met een itemlijst, maar hetzelfde annuleren/bevestigen-skelet en dezelfde saving-discipline). voorraadbeheer's src/app/(dashboard)/admin/employees/page.tsx gebruikt kaal window.confirm() voor wachtwoord-reset en heractivering — geen component, en de reden dat dit item niet alleen de drie kopieën samenvoegt maar ook het gat vult dat window.confirm() achterlaat (geen eigen styling, geen loading-status, blokkerend in plaats van async-vriendelijk). KCB's src/components/settings/user-management.tsx bevestigt hetzelfde gat vanuit een rij-actiemenu (handleDelete, regel 135) — ook daar een kaal confirm(). Het rij-actiemenu zelf valt buiten dit item; alleen hoe de bevestiging wordt afgehandeld is relevant.

Alle drie de growerportal2-kopieën sluiten de dialoog niet onvoorwaardelijk bij een klik op bevestigen — ze zetten hun dialoog-state pas op gesloten ná een geslaagd antwoord (res.ok / ok), in de try-tak, niet in finally. Dat patroon is de kern van dit item; zie Bewuste keuzes.

Waarvoor

Een bevestigingsdialoog met titel, optionele beschrijving, annuleren- en bevestigen-knop — voor een verwijderactie of een andere onomkeerbare stap. Pak het wanneer een klik direct een schadelijk gevolg heeft en een korte "weet je het zeker?" de kans op een ongeluk verkleint.

Gebruik het niet als de bevestiging eigen inhoud nodig heeft buiten titel/beschrijving — zoals fust-pickups.tsx's afleverbevestiging, die een bewerkbare itemlijst in de dialoog toont. Dit component heeft geen kinderen-slot; het is titel, beschrijving en twee knoppen, niets meer. Een dialoog met eigen body-inhoud blijft bespoke, gebouwd met de kale Dialog-primitives.

Wat je app moet leveren

Niets structureels — een presentatiecomponent, volledig controlled, alle tekst via props. Geen backend-contract.

import { ConfirmDialog } from '@/components/confirm-dialog'

const [open, setOpen] = useState(false)
const [saving, setSaving] = useState(false)

async function handleConfirm() {
  setSaving(true)
  try {
    const res = await fetch(`/api/users/${id}`, { method: 'DELETE' })
    if (res.ok) {
      toast.success('Verwijderd')
      setOpen(false)
    } else {
      toast.error('Verwijderen mislukt')
    }
  } catch {
    toast.error('Verwijderen mislukt')
  } finally {
    setSaving(false)
  }
}

<ConfirmDialog
  open={open}
  onOpenChange={setOpen}
  title="Gebruiker verwijderen?"
  description="Dit kan niet ongedaan worden gemaakt."
  confirmLabel="Verwijderen"
  cancelLabel="Annuleren"
  destructive
  loading={saving}
  onConfirm={handleConfirm}
/>
function ConfirmDialog(props: {
  open: boolean
  onOpenChange: (open: boolean) => void
  title: string
  description?: string
  confirmLabel: string
  cancelLabel: string
  destructive?: boolean
  loading?: boolean
  onConfirm: () => void
}): JSX.Element
Prop Verplicht Opmerking
open / onOpenChange ja volledig controlled, geen interne staat, geen trigger-prop — zie Bewuste keuzes
title ja —
description — weglaten toont alleen de titel; zie Bewuste keuzes voor wanneer dat verstandig is
confirmLabel / cancelLabel ja geen standaardtekst — geen vertaalsysteem in dit item, elke aanroeper geeft zijn eigen taal mee
destructive — confirm-knop krijgt variant="destructive" in plaats van "default"
loading — door de aanroeper beheerd (dezelfde saving-state als de bronapps). Schakelt de confirm-knop uit en toont er een spinner vóór confirmLabel op. Annuleren, Escape, een overlay-klik en de close-knop blijven altijd werken — zie Bewuste keuzes
onConfirm ja vuurt bij een klik op bevestigen; sluit de dialoog niet zelf — zie Bewuste keuzes

Bestanden

Bestand Landt in Soort
confirm-dialog.tsx components/confirm-dialog.tsx beheerd

registryDependencies: dialog, button. Geen cssVars.

Gebruikt door

App Sinds versie Opmerkingen
— Nog niet vanuit dit item geïnstalleerd.

growerportal2 heeft drie eigen kopieën (zie Herkomst), voorraadbeheer en KCB gebruiken kaal window.confirm(). Voeg hier een regel toe zodra een app is overgezet.

Bewuste keuzes

Bekende beperkingen