sdxc

Type to search, or start from one of these:

Modal

A pre-animated preset of Dialog.

or press ⌘I

Invite members

They will get an email with a link that expires in seven days.

Separate several addresses with commas.

View code
<Button commandfor="invite-modal" command="show-modal">Invite members</Button>
<p mix={[m(0), text("xs"), fg("neutral.muted")]}>
	or press <Keyboard>⌘I</Keyboard>
</p>

<Modal id="invite-modal" aria-labelledby="invite-modal-title" mix={[hotkey("mod+i")]}>
	<Modal.Header>
		<Modal.Title id="invite-modal-title">Invite members</Modal.Title>
		<Modal.Description>
			They will get an email with a link that expires in seven days.
		</Modal.Description>
	</Modal.Header>

	<form
		id="invite-form"
		method="post"
		action="/members/invite"
		mix={[vstack({ gap: 4, align: "stretch" })]}
	>
		<div mix={[vstack({ gap: 2, align: "stretch" })]}>
			<Label htmlFor="invite-emails">Email addresses</Label>
			<Input
				id="invite-emails"
				name="emails"
				type="text"
				placeholder="ana@example.com, sergio@example.com"
				aria-describedby="invite-emails-hint"
			/>
			<Description id="invite-emails-hint">Separate several addresses with commas.</Description>
		</div>

		<div mix={[vstack({ gap: 2, align: "stretch" })]}>
			<Label htmlFor="invite-note">Note</Label>
			<Input id="invite-note" name="note" placeholder="Optional message" />
		</div>
	</form>

	<Modal.Footer>
		<Button commandfor="invite-modal" command="close" color="neutral" variant="outline">
			Cancel
		</Button>
		<Button type="submit" form="invite-form">
			Send invites
		</Button>
	</Modal.Footer>

	{/* The corner close is positioned rather than laid out, so it sits last and opening
	    the panel lands on the first field instead of on a dismissal. */}
	<Modal.Close commandfor="invite-modal" aria-label="Close" />
</Modal>

Installation

An ordinary dependency: install it, import the theme once, and import the component where it is used.

npm add @sdxc/ui
import "@sdxc/ui/theme.css";

Usage

import { Modal } from "@sdxc/ui";

Renders Dialog with its panel's pop-in/pop-out motion pre-wired through mix, collapsing to an opacity-only fade under reduced motion. A mix passed to Modal layers alongside the built-in motion.

Examples

<Modal id="confirm-delete" aria-labelledby="confirm-delete-title">
	<Modal.Close commandfor="confirm-delete" aria-label={t("actions.close")} />
	<Modal.Header>
		<Modal.Title id="confirm-delete-title">{t("project.deleteTitle")}</Modal.Title>
		<Modal.Description>{t("project.deleteDescription")}</Modal.Description>
	</Modal.Header>
	<Modal.Footer>
		<Button commandfor="confirm-delete" command="close" color="danger">{t("actions.delete")}</Button>
	</Modal.Footer>
</Modal>

Props

Read from the component's own types, so every prop, every default and every allowed value is listed.

Also accepts everything in Dialog.Props.