3.6 KiB
<ShareDialog />
(no submodules)
Purpose
<ShareDialog /> renders the modal sharing UI for a partition. It
exposes a recipients list, an add-recipient form (text input plus
permission select), and a revoke button per row. The component is
controlled — open, recipients, loading, and errorMessage are
all owned by the parent. Wire it to useSharing for live engine
integration or hand it static props in Storybook.
Features
- Controlled
openprop — rendersnullwhen closed so callers can conditionally mount. - Focus moves to the recipient input on open.
- ESC key closes the dialog. Backdrop click also closes; clicks inside the dialog do NOT close (stopPropagation).
- ARIA:
role="dialog",aria-modal="true",aria-labelledbytied to the title heading. Error region usesrole="alert". - Recipient list reuses the same
data-grant-idrow contract as<FileAccessList />. - Localisable: pass
labelsto override every string. Permission options localise individually.
Usage: Basic Example
import { ShareDialog } from "@suaveplan/drive-react-sharing";
import { useState } from "react";
function Trigger() {
const sharing = useSharing(/* ... */);
const [open, setOpen] = useState(false);
return (
<>
<button type="button" onClick={() => setOpen(true)}>Share</button>
<ShareDialog
open={open}
recipients={sharing.recipients}
onAdd={(id, p) => sharing.addRecipient(id, p)}
onRemove={(id) => sharing.removeRecipient(id)}
onClose={() => setOpen(false)}
/>
</>
);
}
Usage: Advanced Example
Custom labels for a localised application:
<ShareDialog
open={open}
recipients={sharing.recipients}
loading={sharing.loading}
errorMessage={sharing.error?.message}
defaultPermission="write"
onAdd={(id, p) => sharing.addRecipient(id, p)}
onRemove={(id) => sharing.removeRecipient(id)}
onClose={() => setOpen(false)}
labels={{
title: "Partager",
add: "Ajouter",
revoke: "Révoquer",
empty: "Aucun destinataire",
permissionOptions: {
read: "Lecture",
write: "Écriture",
delete: "Suppression",
share: "Partage",
admin: "Administrateur",
},
}}
/>;
API Reference
ShareDialogProps:open: boolean— required.recipients: readonly ShareRecipient[]— required.onAdd(recipientId, permission): void | Promise<void>— required.onRemove(grantId): void | Promise<void>— required.onClose(): void— required.title?: string— overrideslabels.title.loading?: boolean— disables interactive controls.errorMessage?: string— rendersrole="alert"banner.defaultPermission?: SharePermission— initial select value.labels?: Partial<ShareDialogLabels>— string overrides.
ShareDialogLabels— exported interface; permission options override individually.
Implementation Notes
The dialog is intentionally a controlled component because the open
state is usually tied to other UI in the parent (an avatar stack, a
"Share" button, a routing flag). Storybook can drive the entire surface
with mocked callbacks. The error region is rendered only when
errorMessage is a non-empty string — passing an undefined or
zero-length string hides it. The submit button is disabled when the
recipient draft is empty so users cannot accidentally fire onAdd
with whitespace.