Files
2026-05-27 23:47:53 +01:00

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 open prop — renders null when 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-labelledby tied to the title heading. Error region uses role="alert".
  • Recipient list reuses the same data-grant-id row contract as <FileAccessList />.
  • Localisable: pass labels to 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 — overrides labels.title.
    • loading?: boolean — disables interactive controls.
    • errorMessage?: string — renders role="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.