Klarhimmel UI

App, invite form

App, invite form preview

Install

npx shadcn add @klarhimmel/app-team-invite

Usage

import { Theme } from '@/components/klarhimmel/theme/style';
import { BlockSurface } from '@/components/klarhimmel/blocks/surface';
import AppTeamInvite from '@/components/klarhimmel/blocks/app-team-invite';

export default function Section() {
  return (
    <Theme theme="brand">
      <BlockSurface>
        <AppTeamInvite props={{
          "eyebrow": "Team",
          "title": "Invite a colleague",
          "description": "They get an email with a link that is valid for seven days.",
          "emailLabel": "Email address",
          "emailHint": "Use their work email.",
          "sample": "",
          "roleLabel": "Role",
          "roles": [
            "Admin",
            "Member",
            "Viewer"
          ],
          "active": "Member",
          "actions": {
            "send": "Send invite",
            "sending": "Sending…"
          },
          "state": "idle",
          "messages": {
            "sent": "Invite sent. It shows under pending invites.",
            "error": "We could not send the invite. Check the address and try again.",
            "emailError": "Enter an email address like name@example.com."
          }
        }} />
      </BlockSurface>
    </Theme>
  );
}

Install

Import

import Block from '@/components/klarhimmel/blocks/app-team-invite';
Also called
  • app/team-invite
About
Invite someone: an email field with a hint, a role select and a send button, with four states (idle, sending, sent, error with the field marked and described). Never submits.
Category
Interface sections for signed-in products.

Notes

When to use it

A small form to invite one person by email and role. Use `app-team-pending` after it to show invites not yet accepted and `app-team-members` for those who have joined; this block only collects the address.

Writing for it

- The emailLabel and roleLabel are required, 40 characters each. Use the hint (120) for a rule people get wrong, such as work email only. - roles takes 2 to 5 names of at most 20 characters. active must be one of them, since it sets what the select starts on. - messages.emailError (120) is shown under the field and should show the format, as in name@example.com. The sent message should say where the invite shows up next.

Watch out for

The form checks only the shape of the address with a simple pattern, and it never posts anywhere. sample is the starting value and is usually left empty, so a filled sample appears as if the person had typed it.

Usage

The block in a page, with its default content (long lists shortened). Every prop is in the table below.

section.tsx
import { Theme } from '@/components/klarhimmel/theme/style';
import { BlockSurface } from '@/components/klarhimmel/blocks/surface';
import AppTeamInvite from '@/components/klarhimmel/blocks/app-team-invite';

export default function Section() {
  return (
    <Theme theme="brand">
      <BlockSurface>
        <AppTeamInvite props={{
          "eyebrow": "Team",
          "title": "Invite a colleague",
          "description": "They get an email with a link that is valid for seven days.",
          "emailLabel": "Email address",
          "emailHint": "Use their work email.",
          "sample": "",
          "roleLabel": "Role",
          "roles": [
            "Admin",
            "Member",
            "Viewer"
          ],
          "active": "Member",
          "actions": {
            "send": "Send invite",
            "sending": "Sending…"
          },
          "state": "idle",
          "messages": {
            "sent": "Invite sent. It shows under pending invites.",
            "error": "We could not send the invite. Check the address and try again.",
            "emailError": "Enter an email address like name@example.com."
          }
        }} />
      </BlockSurface>
    </Theme>
  );
}

Props

The type, default and text limit of every prop. On a real page, over-limit text is kept and checkSections flags it (Installation, Check a page before you ship); this live preview shows the default until it fits. The panel above edits all props.

PropTypeDefaultDescription
eyebrowstring'Team'Text, up to 60 characters. Optional; empty is not rendered.
titlestring'Invite a colleague'Text, up to 120 characters.
descriptionstring'They get an email with a link that …'Text, up to 300 characters. Optional; empty is not rendered.
emailLabelstring'Email address'Text, up to 40 characters.
emailHintstring'Use their work email.'Text, up to 120 characters. Optional; empty is not rendered.
samplestring''Text, up to 60 characters.
roleLabelstring'Role'Text, up to 40 characters.
rolesstring[]3 itemsList of 2 to 5.
activestring'Member'Text, up to 20 characters.
actions{ send, sending }{…}Fields: send, sending.
state'idle' | 'sending' | 'sent' | 'error''idle'One of 'idle', 'sending', 'sent', 'error'.
messages{ sent, error, emailError }{…}Fields: sent, error, emailError.
headingLevel'1' | '2'-One of '1', '2'. Optional; empty is not rendered.