Skip to content
kerfjsGitHub

ShareDialog

Invite people, set their roles, and choose who a link works for.

SourcePackage @kerf-js/veneer

Preview

tsx
import { state } from '@kerf-js/core'import {  Button,  PresenceStack,  ShareDialog,  Stack,  Toaster} from '@kerf-js/veneer'import type {  ShareLink,  ShareMember,  ShareRole} from '@kerf-js/veneer'import type { Peer, ShareContact } from '@kerf-js/veneer'export function Runbook() {  const open = state(false)  const members = state<ShareMember[]>(SHARE_MEMBERS)  const link = state<ShareLink>({    access: 'restricted',    role: 'viewer',  })  const invite = (emails: string[], role: ShareRole) => {    const added = emails.map((email) => ({      id: email,      name: email.split('@')[0]!,      email,      role,    }))    members.value = [...members.value, ...added]  }  const change = (    m: ShareMember,    role: ShareRole | null,  ) => {    members.value = role      ? members.value.map((x) =>          x.id === m.id ? { ...x, role } : x,        )      : members.value.filter((x) => x !== m)  }  return (    <>      <Stack        gap="related"        align="center"      >        <PresenceStack peers={members.value} />        <Button          icon="share"          onClick={() => (open.value = true)}        >          Share        </Button>      </Stack>      <ShareDialog        open={open}        title="Rollback runbook"        members={members}        people={SHARE_PEOPLE}        link={link}        url="https://kerf.dev/d/rollback-runbook"        onInvite={invite}        onRoleChange={change}        onLinkAccess={(v) => (link.value = v)}      />      <Toaster />    </>  )}const PEOPLE = [  {    id: 'mara',    name: 'Mara Lindqvist',    email: 'mara@kerf.dev',    role: 'Owner',    team: 'Platform',    initials: 'ML',  },  {    id: 'jun',    name: 'Jun Tanaka',    email: 'jun@kerf.dev',    role: 'Admin',    team: 'Platform',    initials: 'JT',  },  {    id: 'priya',    name: 'Priya Raman',    email: 'priya@kerf.dev',    role: 'Member',    team: 'Web',    initials: 'PR',  },  {    id: 'tomas',    name: 'Tomás Oliveira',    email: 'tomas@kerf.dev',    role: 'Member',    team: 'Web',    initials: 'TO',  },  {    id: 'lena',    name: 'Lena Fischer',    email: 'lena@kerf.dev',    role: 'Member',    team: 'Data',    initials: 'LF',  },  {    id: 'noor',    name: 'Noor Haddad',    email: 'noor@kerf.dev',    role: 'Viewer',    team: 'Data',    initials: 'NH',  },  {    id: 'sam',    name: 'Sam Okafor',    email: 'sam@kerf.dev',    role: 'Member',    team: 'Mobile',    initials: 'SO',  },  {    id: 'ines',    name: 'Inés Vidal',    email: 'ines@kerf.dev',    role: 'Viewer',    team: 'Mobile',    initials: 'IV',  },]const PEERS: Peer[] = PEOPLE.map((p, i) => ({  id: p.id,  name: p.name,  color: i + 1,}))const [  MARA,  JUN,  PRIYA,  TOMAS,  LENA,  NOOR,  SAM,  INES,] = PEERS as [  Peer,  Peer,  Peer,  Peer,  Peer,  Peer,  Peer,  Peer,]const SHARE_MEMBERS: ShareMember[] = [  { ...MARA, email: 'mara@kerf.dev', role: 'owner' },  { ...JUN, email: 'jun@kerf.dev', role: 'editor' },  { ...LENA, email: 'lena@kerf.dev', role: 'commenter' },]const SHARE_PEOPLE: ShareContact[] = [  { ...PRIYA, email: 'priya@kerf.dev' },  { ...TOMAS, email: 'tomas@kerf.dev' },  { ...SAM, email: 'sam@kerf.dev' },]

Installation

npm install @kerf-js/veneer

Usage

tsx
import { ShareDialog } from '@kerf-js/veneer'

Accessibility

  • This has no shortcuts of its own: controls inside it use Tab, Enter and Space as usual, and veneer's parts keep their roles and labels.

API Reference

PropTypeDefaultDescription
openState<boolean>—Whether it shows. You own this state.
titlestring—What is being shared.
membersLive<ShareMember[]>—Who has access.
peopleShareContact[]—People the invite field suggests. Any email works too.
linkLive<ShareLink>—The link's access and role.
urlstring—What Copy link writes.
EventTypeDefaultDescription
onInvite(emails: string[], role: ShareRole) => void—Called with the emails and role.
onRoleChange(m: ShareMember, role: ShareRole | null) => void—Called with a role, or null to remove the person.
onLinkAccess(link: ShareLink) => void—Called when the link changes.

RelatedInvite dialogPresence stack