Early bird: 30% off Dashral ProSee pricing

Dashral

Share PanelPro

A Share button that widens into its share panel: invite by email with a role, change each person's role, set who can open the link and copy it.

Installation

When to use

  • Sharing a document, a board or a project with people: invite, roles and the link in one place, without leaving the page.
  • Where roles matter: each person's role, and the link's access, is picked in a step inside the same panel.

When not to use

  • Only a link to copy: a Copy Button is one click.
  • Managing a whole team's members and permissions: that's a settings page.

Usage

Share Panel with your own data: a whole component you can paste as a page.

example.tsx
"use client"

import { SharePanel } from "@/components/dashral/pro/share-panel"

import { useState } from "react"

const team = [
  { id: "maya", name: "Maya Lindqvist", email: "maya@halcyon.studio", role: "editor", owner: true },
  { id: "leo", name: "Leo Hart", email: "leo@halcyon.studio", role: "viewer" },
]

export default function DocumentHeader() {
  const [people, setPeople] = useState(team)
  const [access, setAccess] = useState("restricted")
  return (
    <SharePanel
      title="Q3 roadmap"
      people={people}
      onPeopleChange={setPeople}
      onInvite={async (emails, role) => console.log("invite", emails, role)}
      access={{ value: access, onValueChange: setAccess }}
      link="https://example.com/d/q3-roadmap"
    />
  )
}

API reference

SharePanel

A Share button that widens into a share panel: invite by email with a role, change or remove each person's role, set who can open the link and copy it. Roles are picked in a step that slides into the same panel.

PropTypeDefault
titlestring

What's shared, for the panel's heading ("Share “Q3 roadmap”").

—
peopleSharePerson[]

The people with access (controlled), or the start of them.

—
defaultPeopleSharePerson[][]
onPeopleChange(people: SharePerson[]) => void—
onInvite(emails: string[], role: string) => void | Promise<void>

Called on Invite with the emails and their role; may return a promise (a spinner shows meanwhile).

—
rolesShareRole[]sample
defaultRolestring

The role an invite starts with; the first role by default.

—
access{ value: string; onValueChange: (value: string) => void; options?: ShareAccessOption[] }

Who else can open it, by link.

—
linkstring

The link Copy link copies.

—
labelstring

The button's words; "Share" by default.

"Share"
side"bottom" | "top""bottom"
align"start" | "end""end"
widthnumber

The panel's width, in px (never wider than the screen).

400
classNamestring—
classNamesSharePanelClassNames—

type SharePerson

PropTypeDefault
idstring—
namestring—
emailstring—
avatarstring—
rolestring

A role's value; the owner's is shown as "Owner" and can't be changed.

—
ownerboolean—
pendingboolean

Invited, not joined yet.

—

type ShareRole

PropTypeDefault
valuestring—
labelstring—
descriptionstring—

type ShareAccessOption

PropTypeDefault
valuestring—
labelstring—
descriptionstring—
iconReact.ReactNode—

type SharePanelClassNames

PropTypeDefault
rootstring—
buttonstring—
panelstring—

Keyboard

KeysAction
EnterIn the email field: make a chip; with nothing typed, invite
,orSpaceMake a chip too; a paste of several makes several
BackspaceIn an empty email field: take the last chip back
↑or↓Along the people's roles and the link's access; through a step's options
HomeorEndThe first or last option in a step
←In a step: back, the focus where it was
EscBack from a step, or close; the focus returns to Share

Accessibility

  • The panel is a dialog (aria-modal) named "Share “<title>”"; each role button is named with its person ("Leo Hart: Can edit").
  • A step's options are menu item radios with aria-checked; Remove access is its own item after a line.
  • Copy link announces "Link copied" in a live region; people invited are marked Invited.

Motion

  • The button widens into the panel (0.42 s) and, closing, shrinks back while the two crossfade.
  • People invited slide into the list; a step slides in as the panel reshapes to it; Copy link's words swap for Copied, then back.
  • Smooth tweens on [0.4, 0, 0.2, 1], never springs, except the small press. With reduced motion it only fades.