TenantSwitcher

A dropdown selector for switching between tenant organizations in multi-tenant applications. Displays current tenant and allows quick switching.

Installation

typescript
import { TenantSwitcher } from '@happyvertical/smrt-tenancy/svelte';

Basic Usage

Simple tenant switcher with callback handling.

Current tenant: tenant_1

svelte
<script lang="ts">
  import { TenantSwitcher } from '@happyvertical/smrt-tenancy/svelte';

  let currentTenantId = $state('tenant_1');

  const tenants = new Map([
    ['tenant_1', { id: 'tenant_1', name: 'Acme Corporation', slug: 'acme' }],
    ['tenant_2', { id: 'tenant_2', name: 'TechStart Inc', slug: 'techstart' }],
  ]);

  const memberships = [
    { tenantId: 'tenant_1', role: 'admin' },
    { tenantId: 'tenant_2', role: 'member' },
  ];
</script>

<TenantSwitcher
  {memberships}
  {tenants}
  currentTenantId={currentTenantId}
  onchange={(id) => (currentTenantId = id)}
/>

Props

PropTypeDefaultDescription
memberships *Membership[]-User's tenant memberships with role info
tenants *Map<string, Tenant>-Map of tenant ID to tenant data
currentTenantId *string-ID of currently selected tenant
onchange (tenantId: string) => void-Callback when tenant is switched

TypeScript

typescript
import type { Membership, Tenant } from '@happyvertical/smrt-users';

interface Props {
  memberships: Membership[];
  tenants: Map<string, Tenant>;
  currentTenantId: string;
  onchange?: (tenantId: string) => void;
}

Integration with smrt-tenancy

Complete example with tenant context switching:

typescript
<script lang="ts">
  import { TenantSwitcher } from '@happyvertical/smrt-tenancy/svelte';
  import { TenantContext } from '@happyvertical/smrt-tenancy';
  import type { Membership, Tenant } from '@happyvertical/smrt-users';

  let tenants = $state<Map<string, Tenant>>(new Map());
  let memberships = $state<Membership[]>([]);
  let currentTenantId = $state('');

  // Load user's tenants
  onMount(async () => {
    const membershipCollection = await MembershipsCollection.create({ db });
    memberships = await membershipCollection.list({
      where: { userId: currentUser.id, status: 'active' }
    });

    const tenantCollection = await TenantsCollection.create({ db });
    for (const m of memberships) {
      const tenant = await tenantCollection.get(m.tenantId);
      if (tenant) tenants.set(tenant.id, tenant);
    }

    currentTenantId = TenantContext.getCurrentTenantId();
  });

  async function handleTenantChange(tenantId: string) {
    await TenantContext.setTenant(tenantId);
    window.location.href = '/' + tenantId + '/dashboard';
  }
</script>

<TenantSwitcher
  {memberships}
  {tenants}
  {currentTenantId}
  onchange={handleTenantChange}
/>

Use Cases

  • Application header for quick tenant switching
  • Sidebar navigation tenant selector
  • Admin dashboard with multi-tenant access
  • SaaS applications with workspace/organization switching
  • User settings page showing available tenants

Accessibility

TenantSwitcher follows accessibility best practices:

  • Keyboard navigation (Tab, Enter, Arrow keys)
  • ARIA labels for screen readers
  • Focus indicators on all interactive elements
  • Escape key to close dropdown
  • Proper role attributes (menu, menuitem)