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

9.3 KiB

@suaveplan/drive-react-sharing - React UI for @suaveplan/drive-sharing: ShareDialog, PartitionBadge, FileAccessList components and useSharing hook wired to the real sharing engine.

Summary

React-tier UI surface for @suaveplan/drive-sharing. Three controlled components plus a real-engine-backed hook.

Documentation tree

- [file-access-list](./src/components/file-access-list/file-access-list.md) — _(no submodules)_- [partition-badge](./src/components/partition-badge/partition-badge.md) — _(no submodules)_- [partition-badge](./src/components/partition-badge/partition-badge.md) — _(no submodules)_- [share-dialog](./src/components/share-dialog/share-dialog.md) — _(no submodules)_- [share-dialog](./src/components/share-dialog/share-dialog.md) — _(no submodules)_- [use-sharing](./src/hooks/use-sharing/use-sharing.md) — _(no submodules)_- [use-sharing](./src/hooks/use-sharing/use-sharing.md) — _(no submodules)_- [otel](./src/otel/instruments.md) — _(no submodules)_- [instruments](./src/otel/instruments.md) — _(no submodules)_- [error-codes](./src/error-codes.md) — `@suaveplan/drive-react-sharing` raises every failure as a `DriveReactSharingError` — a `SuaveplanError` subclass with…

Install

bun add @suaveplan/drive-react-sharing @suaveplan/drive-sharing

Peer deps: react ^18 || ^19, react-dom ^18 || ^19.

Quick start

import {
    GrantManager,
    InMemoryPartitionStore,
    KeyRing,
    PartitionManager,
    TokenManager,
    userId,
} from "@suaveplan/drive-sharing";
import {
    ShareDialog,
    useSharing,
} from "@suaveplan/drive-react-sharing";
import { useState } from "react";

const partitions = new PartitionManager({
    store: new InMemoryPartitionStore(),
    keyRing: new KeyRing(),
});
const grants = new GrantManager();
const tokens = new TokenManager();

function Trigger({ partitionId }: { partitionId: string }) {
    const sharing = useSharing({
        partitionId,
        grantorId: userId("me"),
        partitions,
        grants,
        tokens,
    });
    const [open, setOpen] = useState(false);
    return (
        <>
            <button type="button" onClick={() => setOpen(true)}>Share</button>
            <ShareDialog
                open={open}
                recipients={sharing.recipients}
                loading={sharing.loading}
                errorMessage={sharing.error?.message}
                onAdd={(id, perm) => sharing.addRecipient(id, perm)}
                onRemove={(id) => sharing.removeRecipient(id)}
                onClose={() => setOpen(false)}
            />
        </>
    );
}

Components

Component Purpose Docs
<ShareDialog /> Modal share UI with add form + revoke per row src/components/share-dialog/share-dialog.md
<PartitionBadge /> Inline badge: classification + encryption indicator src/components/partition-badge/partition-badge.md
<FileAccessList /> Read-only access list with optional revoke src/components/file-access-list/file-access-list.md

Hook

Hook Purpose Docs
useSharing(options) Live-engine binding for recipient state + add/remove/update/refresh actions src/hooks/use-sharing/use-sharing.md

Accessibility

  • <ShareDialog /> renders role="dialog" with aria-modal="true" and aria-labelledby pointing at the title heading. Focus moves to the recipient input on open; ESC and backdrop click both close.
  • <FileAccessList /> renders a semantic <ul role="list"> with one <li role="listitem"> per recipient. Revoke is a native <button> with aria-label including the recipient identifier. Delete and Backspace fire revoke directly when the button is focused.
  • <PartitionBadge /> renders role="status" and an aria-label describing the partition type plus encryption state. The padlock SVG is marked aria-hidden="true".

OTel

useSharing emits three counters:

  • drive.react.sharing.recipients_added_total{permission}
  • drive.react.sharing.recipients_removed_total
  • drive.react.sharing.permissions_updated_total{permission}

Type consolidation

Main shipped three overlapping permission aliases (SharePermission / AccessPermission / SharingPermission). imports SharePermission directly from @suaveplan/drive-sharing and re-exports it as the single canonical name. Aliases were not ported.