<seva-member-directory>
The <seva-member-directory> component renders a trigger button and a modal overlay that displays a searchable, alphabetically indexed member directory.
Overview
Section titled “Overview”When opened, the modal fetches the organization’s member directory from the API and displays members grouped by last-name initial with an alphabetical sidebar for quick navigation. A real-time search bar filters members by first or last name. If the user is not authenticated, the modal shows a sign-in prompt with an embedded <seva-auth> form.
This is a modal component — it self-manages authentication from localStorage and does not require a glue script to propagate auth tokens. See Inline vs. modal components for details.
Quick Example
Section titled “Quick Example”<script type="module" src="YOUR_COMPONENTS_URL/seva-member-directory.js"></script>
<seva-member-directory tenant-slug="my-club" api-url="https://api.seva.tools"></seva-member-directory>The component renders its own trigger button labeled “Member Directory”. You can also open the modal programmatically by calling openModal() on the element.
Note: Unlike
<seva-my-profile>and<seva-my-registrations>, this component does not have aseva:open-member-directoryevent. Use the built-in trigger button or callopenModal()directly.
Attributes
Section titled “Attributes”| Attribute | Type | Default | Description |
|---|---|---|---|
tenant-slug | string | '' | Required. Your organization’s tenant slug. |
api-url | string | 'https://api.seva.tools' | Base URL of the Seva API. |
theme | 'light' | 'dark' | 'light' | Color theme. |
auth-token | string | null | Session token. Modal components typically self-manage this from localStorage, so you rarely need to set it manually. |
Events emitted
Section titled “Events emitted”| Event | Effect |
|---|---|
seva:signed-out | Dispatched on document if the API returns 401/403 while loading the directory. Other Seva components listening for this event will clear their auth state. |
Events listened for
Section titled “Events listened for”The component listens on document for:
| Event | Effect |
|---|---|
seva:authenticated | Stores the token, loads the directory. |
seva:signed-out | Clears auth state and member data. |
Note: There is no
seva:open-member-directoryevent. To open the modal programmatically, callelement.openModal()instead. See Opening the modal below.
UI features
Section titled “UI features”Real-time search
Section titled “Real-time search”A search bar at the top filters members by first or last name as you type. The search is case-insensitive and matches partial names. A member count updates to reflect the filtered results.
Alphabetical sidebar
Section titled “Alphabetical sidebar”A vertical sidebar on the right displays letters A–Z and # (for members whose last name doesn’t start with a letter). Letters with matching members are highlighted; others are dimmed.
- Click a letter to scroll to that section.
- Click and drag along the sidebar to scroll rapidly through the directory.
Member groups
Section titled “Member groups”Members are grouped by the first letter of their last name. Each group has a letter heading followed by member cards.
Member cards
Section titled “Member cards”Each member card shows:
- Initials avatar — First letters of first and last name in a circle.
- Full name
- Email — Linked as
mailto:. - Phone — Linked as
tel:.
Opening the modal
Section titled “Opening the modal”The modal can be opened in two ways:
- Built-in trigger button — The component renders a “Member Directory” button automatically.
- Direct method call — Call
openModal()on the element:document.querySelector("seva-member-directory").openModal();
There is no document-level custom event to open this modal (unlike profile and registrations). If you need a custom trigger button:
<button onclick="document.querySelector('seva-member-directory').openModal()"> Browse Members</button>Error handling
Section titled “Error handling”- 401 Unauthorized — Session expired. Auth state is cleared and
seva:signed-outis dispatched. - 404 Not Found — The organization has not enabled the member directory, or the user is not a member. The message displayed is: “Member directory is not available for this organization.”
Key types
Section titled “Key types”interface DirectoryMember { id: string; firstName: string | null; lastName: string | null; email: string | null; phone: string | null; membershipTypeName: string | null; membershipTypeId: string | null;}
interface DirectoryResponse { members: DirectoryMember[]; membershipTypes: DirectoryMembershipType[];}Full Example
Section titled “Full Example”<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Member Directory</title> <script type="module" src="YOUR_COMPONENTS_URL/seva-member-directory.js" ></script> <style> body { font-family: system-ui, sans-serif; max-width: 400px; margin: 2rem auto; } </style> </head> <body> <h1>Our Members</h1>
<seva-member-directory tenant-slug="my-club" api-url="https://api.seva.tools" > </seva-member-directory>
<!-- Or use a custom trigger --> <button onclick="document.querySelector('seva-member-directory').openModal()" > Browse Members </button> </body></html>