@handled-ai/design-system 0.20.32 → 0.20.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -71,7 +71,7 @@ function SalesforceMark({ size = 13 }) {
|
|
|
71
71
|
);
|
|
72
72
|
}
|
|
73
73
|
function OwnerAvatar({ person, size = "sm" }) {
|
|
74
|
-
return /* @__PURE__ */ jsxs(Avatar, { size, className: "ring-background ring-
|
|
74
|
+
return /* @__PURE__ */ jsxs(Avatar, { size, className: "ring-background ring-1", children: [
|
|
75
75
|
person.avatarUrl ? /* @__PURE__ */ jsx(AvatarImage, { src: person.avatarUrl, alt: person.name }) : null,
|
|
76
76
|
/* @__PURE__ */ jsx(AvatarFallback, { className: "bg-muted text-muted-foreground text-[10px] font-medium uppercase", children: getInitials({ name: person.name, email: person.email }) })
|
|
77
77
|
] });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/owner-chips.tsx"],"sourcesContent":["\"use client\"\n\n/**\n * owner-chips.tsx — disambiguates the two ownership concepts operators kept\n * confusing on the case panel:\n *\n * 1. SIGNAL OWNER — Handled's OWN assignment. Who owns working this\n * signal/action inside Handled. Editable here (assign / reassign /\n * unassign). Replaces the ambiguous bare \"Unassigned\" chip.\n *\n * 2. ACCOUNT OWNER(S) — read-through from Salesforce. An account can carry\n * more than one (AE + RM). Informational + links out to Salesforce; never\n * assigned from inside Handled. Leads with the Salesforce mark.\n *\n * Account owner chips are read-only dropdowns. A single owner still opens a\n * small Salesforce-sourced details menu; multiple owners show stacked avatars\n * and a ×N badge before listing each owner with optional Salesforce links.\n *\n * Presentational only: data + handlers come from the consumer (the app).\n */\n\nimport * as React from \"react\"\nimport {\n ChevronDown,\n ChevronUp,\n Check,\n UserPlus,\n UserMinus,\n Info,\n ArrowUpRight,\n} from \"lucide-react\"\n\nimport { cn } from \"../lib/utils\"\nimport { getInitials } from \"../lib/user-display\"\nimport { BRAND_ICONS } from \"../lib/icons\"\nimport { Avatar, AvatarFallback, AvatarImage } from \"./avatar\"\nimport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n} from \"./dropdown-menu\"\n\nexport interface OwnerPerson {\n /** Stable id (profile id for signal owner; SF user id for account owner). */\n id?: string\n name: string\n email?: string\n /** e.g. \"Relationship Manager\", \"Account Executive\". */\n role?: string\n /** Avatar image; falls back to initials when absent. */\n avatarUrl?: string | null\n /** External link (Salesforce) for an account owner. */\n href?: string\n}\n\n/* ── shared bits ─────────────────────────────────────────────────────────── */\n\nfunction SalesforceMark({ size = 13 }: { size?: number }) {\n return (\n // eslint-disable-next-line @next/next/no-img-element\n <img\n src={BRAND_ICONS.salesforce}\n alt=\"Salesforce\"\n width={size}\n height={size}\n style={{ width: size, height: size, objectFit: \"contain\", display: \"block\" }}\n />\n )\n}\n\nfunction OwnerAvatar({ person, size = \"sm\" }: { person: OwnerPerson; size?: \"sm\" | \"default\" }) {\n return (\n <Avatar size={size} className=\"ring-background ring-2\">\n {person.avatarUrl ? <AvatarImage src={person.avatarUrl} alt={person.name} /> : null}\n <AvatarFallback className=\"bg-muted text-muted-foreground text-[10px] font-medium uppercase\">\n {getInitials({ name: person.name, email: person.email })}\n </AvatarFallback>\n </Avatar>\n )\n}\n\n// Component-owned compact sizing. Set directly here (not via consumer\n// className) because cn()/tailwind-merge can strip conflicting overrides.\nconst chipBase =\n \"inline-flex h-7 items-center gap-1 rounded-md border border-border bg-background px-2 text-[12px] \" +\n \"shadow-[0_1px_1px_rgba(0,0,0,0.03)]\"\n\n/* ── Signal owner (Handled assignment, editable) ─────────────────────────── */\n\nexport interface SignalOwnerChipProps {\n /** Current Handled assignee, or null when unassigned. */\n owner: OwnerPerson | null\n /** Operators the case can be assigned to (preloaded — no fetch on open). */\n assignableOwners?: OwnerPerson[]\n onAssign?: (owner: OwnerPerson) => void\n onUnassign?: () => void\n /** Read-only: render a static chip without the assignment menu. */\n disabled?: boolean\n className?: string\n}\n\nfunction SignalOwnerChip({\n owner,\n assignableOwners = [],\n onAssign,\n onUnassign,\n disabled,\n className,\n}: SignalOwnerChipProps) {\n const [open, setOpen] = React.useState(false)\n\n const value = (\n <>\n {owner ? (\n <OwnerAvatar person={owner} />\n ) : (\n <span className=\"text-muted-foreground inline-flex size-4 items-center justify-center\">\n <UserPlus size={12} />\n </span>\n )}\n <span className=\"text-muted-foreground text-[10px] font-medium tracking-wide uppercase\">\n Signal owner\n </span>\n <span className=\"bg-border/70 mx-0.5 h-3 w-px\" aria-hidden />\n <span className={cn(\"font-medium\", owner ? \"text-foreground\" : \"text-muted-foreground\")}>\n {owner ? owner.name : \"Unassigned\"}\n </span>\n </>\n )\n\n // Read-only or nothing to assign to: static chip.\n if (disabled || (!onAssign && !onUnassign)) {\n return (\n <span\n data-slot=\"signal-owner-chip\"\n data-empty={owner ? undefined : \"true\"}\n className={cn(chipBase, className)}\n title=\"Who owns this signal inside Handled\"\n >\n {value}\n </span>\n )\n }\n\n return (\n <DropdownMenu open={open} onOpenChange={setOpen}>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n data-slot=\"signal-owner-chip\"\n data-empty={owner ? undefined : \"true\"}\n className={cn(chipBase, \"hover:bg-muted cursor-pointer transition-colors\", className)}\n title=\"Who owns this signal inside Handled\"\n >\n {value}\n <span className=\"text-muted-foreground ml-0.5\">\n {open ? <ChevronUp size={12} /> : <ChevronDown size={12} />}\n </span>\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"w-64\">\n <DropdownMenuLabel className=\"flex flex-col gap-0.5\">\n <span className=\"text-[13px] font-semibold\">Assign signal owner</span>\n <span className=\"text-muted-foreground text-[11px] font-normal\">\n Who works this inside Handled, separate from the Salesforce account owner.\n </span>\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n {assignableOwners.map((o) => {\n const active = !!owner && (owner.id ? owner.id === o.id : owner.name === o.name)\n return (\n <DropdownMenuItem\n key={o.id ?? o.name}\n onSelect={() => onAssign?.(o)}\n className=\"gap-2\"\n >\n <OwnerAvatar person={o} size=\"default\" />\n <span className=\"flex min-w-0 flex-col\">\n <span className=\"truncate text-[13px] font-medium\">{o.name}</span>\n {o.role ? (\n <span className=\"text-muted-foreground truncate text-[11px]\">{o.role}</span>\n ) : null}\n </span>\n {active ? <Check size={14} className=\"text-foreground ml-auto\" /> : null}\n </DropdownMenuItem>\n )\n })}\n {owner && onUnassign ? (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuItem onSelect={() => onUnassign()} className=\"text-muted-foreground gap-2\">\n <UserMinus size={13} /> Unassign\n </DropdownMenuItem>\n </>\n ) : null}\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n\n/* ── Account owner(s) (Salesforce, read-through) ─────────────────────────── */\n\nexport interface AccountOwnerChipProps {\n /** Salesforce account owners (RM, AE, …). Empty -> renders nothing. */\n owners: OwnerPerson[]\n className?: string\n}\n\nfunction AccountOwnerSummary({ person }: { person: OwnerPerson }) {\n return (\n <span className=\"flex min-w-0 flex-col\">\n <span className=\"truncate text-[13px] font-medium\">{person.name}</span>\n {person.role ? (\n <span className=\"text-muted-foreground truncate text-[11px]\">{person.role}</span>\n ) : null}\n {person.email ? (\n <span className=\"text-muted-foreground truncate text-[11px]\">{person.email}</span>\n ) : null}\n </span>\n )\n}\n\nfunction AccountOwnerSalesforceLink({ person }: { person: OwnerPerson }) {\n if (!person.href) return null\n\n return (\n <DropdownMenuItem asChild className=\"p-0\">\n <a\n href={person.href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n data-account-owner-salesforce-link=\"true\"\n className=\"text-foreground focus:bg-accent focus:text-accent-foreground flex items-center gap-1.5 rounded-sm px-2 py-1.5 text-[12px] font-medium outline-hidden transition-colors\"\n title={`Open ${person.name} in Salesforce`}\n >\n <ArrowUpRight size={12} className=\"text-muted-foreground\" />\n Open in Salesforce\n </a>\n </DropdownMenuItem>\n )\n}\n\nfunction AccountOwnerRow({ person }: { person: OwnerPerson }) {\n return (\n <>\n <DropdownMenuItem\n disabled\n data-owner-row=\"true\"\n className=\"items-start gap-2 py-1.5 data-[disabled]:opacity-100\"\n >\n <OwnerAvatar person={person} size=\"default\" />\n <AccountOwnerSummary person={person} />\n </DropdownMenuItem>\n <AccountOwnerSalesforceLink person={person} />\n </>\n )\n}\n\nfunction SalesforceReadOnlyHelper() {\n return (\n <div role=\"presentation\" className=\"text-muted-foreground flex items-start gap-1.5 px-2 py-1.5 text-[11px]\">\n <Info size={12} className=\"mt-0.5 shrink-0\" />\n <span>Read-only from Salesforce. Manage owners in Salesforce.</span>\n </div>\n )\n}\n\nfunction AccountOwnerChip({ owners, className }: AccountOwnerChipProps) {\n const [open, setOpen] = React.useState(false)\n if (!owners.length) return null\n const multi = owners.length > 1\n\n if (!multi) {\n const only = owners[0]\n\n return (\n <DropdownMenu open={open} onOpenChange={setOpen}>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n data-slot=\"account-owner-chip\"\n className={cn(chipBase, \"hover:bg-muted cursor-pointer transition-colors\", className)}\n title={`Account owner in Salesforce — ${only.name}`}\n >\n <span className=\"inline-flex shrink-0 items-center\">\n <SalesforceMark />\n </span>\n <OwnerAvatar person={only} />\n <span className=\"text-foreground font-medium\">{only.name}</span>\n <span className=\"text-muted-foreground ml-0.5\">\n {open ? <ChevronUp size={12} /> : <ChevronDown size={12} />}\n </span>\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"w-72\">\n <DropdownMenuLabel className=\"flex items-center gap-1.5 text-[13px]\">\n <SalesforceMark />\n Account owner\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n <AccountOwnerRow person={only} />\n <DropdownMenuSeparator />\n <SalesforceReadOnlyHelper />\n </DropdownMenuContent>\n </DropdownMenu>\n )\n }\n\n // Multiple owners: stacked avatars + ×N + a menu listing each.\n return (\n <DropdownMenu open={open} onOpenChange={setOpen}>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n data-slot=\"account-owner-chip\"\n data-multi=\"true\"\n className={cn(chipBase, \"hover:bg-muted cursor-pointer transition-colors\", className)}\n title=\"Account owners in Salesforce\"\n >\n <span className=\"inline-flex shrink-0 items-center\">\n <SalesforceMark />\n </span>\n <span className=\"flex -space-x-2\">\n {owners.map((o) => (\n <OwnerAvatar key={o.id ?? o.name} person={o} />\n ))}\n </span>\n <span className=\"text-foreground font-medium\">Account owners</span>\n <span className=\"bg-muted text-muted-foreground rounded px-1 text-[10px] font-semibold tabular-nums\">\n ×{owners.length}\n </span>\n <span className=\"text-muted-foreground ml-0.5\">\n {open ? <ChevronUp size={12} /> : <ChevronDown size={12} />}\n </span>\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"w-72\">\n <DropdownMenuLabel className=\"flex items-center gap-1.5 text-[13px]\">\n <SalesforceMark />\n {owners.length} account owners\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n {owners.map((o) => (\n <AccountOwnerRow key={o.id ?? o.name} person={o} />\n ))}\n <DropdownMenuSeparator />\n <SalesforceReadOnlyHelper />\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n\n/* ── Convenience composite ──────────────────────────────────────────────── */\n\nexport interface OwnerChipsProps extends SignalOwnerChipProps {\n /** Salesforce account owners (read-through). */\n accountOwners?: OwnerPerson[]\n}\n\nfunction OwnerChips({ accountOwners = [], className, ...signal }: OwnerChipsProps) {\n return (\n <>\n <SignalOwnerChip {...signal} className={className} />\n <AccountOwnerChip owners={accountOwners} className={className} />\n </>\n )\n}\n\nexport { SignalOwnerChip, AccountOwnerChip, OwnerChips }\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/owner-chips.tsx"],"sourcesContent":["\"use client\"\n\n/**\n * owner-chips.tsx — disambiguates the two ownership concepts operators kept\n * confusing on the case panel:\n *\n * 1. SIGNAL OWNER — Handled's OWN assignment. Who owns working this\n * signal/action inside Handled. Editable here (assign / reassign /\n * unassign). Replaces the ambiguous bare \"Unassigned\" chip.\n *\n * 2. ACCOUNT OWNER(S) — read-through from Salesforce. An account can carry\n * more than one (AE + RM). Informational + links out to Salesforce; never\n * assigned from inside Handled. Leads with the Salesforce mark.\n *\n * Account owner chips are read-only dropdowns. A single owner still opens a\n * small Salesforce-sourced details menu; multiple owners show stacked avatars\n * and a ×N badge before listing each owner with optional Salesforce links.\n *\n * Presentational only: data + handlers come from the consumer (the app).\n */\n\nimport * as React from \"react\"\nimport {\n ChevronDown,\n ChevronUp,\n Check,\n UserPlus,\n UserMinus,\n Info,\n ArrowUpRight,\n} from \"lucide-react\"\n\nimport { cn } from \"../lib/utils\"\nimport { getInitials } from \"../lib/user-display\"\nimport { BRAND_ICONS } from \"../lib/icons\"\nimport { Avatar, AvatarFallback, AvatarImage } from \"./avatar\"\nimport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n} from \"./dropdown-menu\"\n\nexport interface OwnerPerson {\n /** Stable id (profile id for signal owner; SF user id for account owner). */\n id?: string\n name: string\n email?: string\n /** e.g. \"Relationship Manager\", \"Account Executive\". */\n role?: string\n /** Avatar image; falls back to initials when absent. */\n avatarUrl?: string | null\n /** External link (Salesforce) for an account owner. */\n href?: string\n}\n\n/* ── shared bits ─────────────────────────────────────────────────────────── */\n\nfunction SalesforceMark({ size = 13 }: { size?: number }) {\n return (\n // eslint-disable-next-line @next/next/no-img-element\n <img\n src={BRAND_ICONS.salesforce}\n alt=\"Salesforce\"\n width={size}\n height={size}\n style={{ width: size, height: size, objectFit: \"contain\", display: \"block\" }}\n />\n )\n}\n\nfunction OwnerAvatar({ person, size = \"sm\" }: { person: OwnerPerson; size?: \"sm\" | \"default\" }) {\n return (\n <Avatar size={size} className=\"ring-background ring-1\">\n {person.avatarUrl ? <AvatarImage src={person.avatarUrl} alt={person.name} /> : null}\n <AvatarFallback className=\"bg-muted text-muted-foreground text-[10px] font-medium uppercase\">\n {getInitials({ name: person.name, email: person.email })}\n </AvatarFallback>\n </Avatar>\n )\n}\n\n// Component-owned compact sizing. Set directly here (not via consumer\n// className) because cn()/tailwind-merge can strip conflicting overrides.\nconst chipBase =\n \"inline-flex h-7 items-center gap-1 rounded-md border border-border bg-background px-2 text-[12px] \" +\n \"shadow-[0_1px_1px_rgba(0,0,0,0.03)]\"\n\n/* ── Signal owner (Handled assignment, editable) ─────────────────────────── */\n\nexport interface SignalOwnerChipProps {\n /** Current Handled assignee, or null when unassigned. */\n owner: OwnerPerson | null\n /** Operators the case can be assigned to (preloaded — no fetch on open). */\n assignableOwners?: OwnerPerson[]\n onAssign?: (owner: OwnerPerson) => void\n onUnassign?: () => void\n /** Read-only: render a static chip without the assignment menu. */\n disabled?: boolean\n className?: string\n}\n\nfunction SignalOwnerChip({\n owner,\n assignableOwners = [],\n onAssign,\n onUnassign,\n disabled,\n className,\n}: SignalOwnerChipProps) {\n const [open, setOpen] = React.useState(false)\n\n const value = (\n <>\n {owner ? (\n <OwnerAvatar person={owner} />\n ) : (\n <span className=\"text-muted-foreground inline-flex size-4 items-center justify-center\">\n <UserPlus size={12} />\n </span>\n )}\n <span className=\"text-muted-foreground text-[10px] font-medium tracking-wide uppercase\">\n Signal owner\n </span>\n <span className=\"bg-border/70 mx-0.5 h-3 w-px\" aria-hidden />\n <span className={cn(\"font-medium\", owner ? \"text-foreground\" : \"text-muted-foreground\")}>\n {owner ? owner.name : \"Unassigned\"}\n </span>\n </>\n )\n\n // Read-only or nothing to assign to: static chip.\n if (disabled || (!onAssign && !onUnassign)) {\n return (\n <span\n data-slot=\"signal-owner-chip\"\n data-empty={owner ? undefined : \"true\"}\n className={cn(chipBase, className)}\n title=\"Who owns this signal inside Handled\"\n >\n {value}\n </span>\n )\n }\n\n return (\n <DropdownMenu open={open} onOpenChange={setOpen}>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n data-slot=\"signal-owner-chip\"\n data-empty={owner ? undefined : \"true\"}\n className={cn(chipBase, \"hover:bg-muted cursor-pointer transition-colors\", className)}\n title=\"Who owns this signal inside Handled\"\n >\n {value}\n <span className=\"text-muted-foreground ml-0.5\">\n {open ? <ChevronUp size={12} /> : <ChevronDown size={12} />}\n </span>\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"w-64\">\n <DropdownMenuLabel className=\"flex flex-col gap-0.5\">\n <span className=\"text-[13px] font-semibold\">Assign signal owner</span>\n <span className=\"text-muted-foreground text-[11px] font-normal\">\n Who works this inside Handled, separate from the Salesforce account owner.\n </span>\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n {assignableOwners.map((o) => {\n const active = !!owner && (owner.id ? owner.id === o.id : owner.name === o.name)\n return (\n <DropdownMenuItem\n key={o.id ?? o.name}\n onSelect={() => onAssign?.(o)}\n className=\"gap-2\"\n >\n <OwnerAvatar person={o} size=\"default\" />\n <span className=\"flex min-w-0 flex-col\">\n <span className=\"truncate text-[13px] font-medium\">{o.name}</span>\n {o.role ? (\n <span className=\"text-muted-foreground truncate text-[11px]\">{o.role}</span>\n ) : null}\n </span>\n {active ? <Check size={14} className=\"text-foreground ml-auto\" /> : null}\n </DropdownMenuItem>\n )\n })}\n {owner && onUnassign ? (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuItem onSelect={() => onUnassign()} className=\"text-muted-foreground gap-2\">\n <UserMinus size={13} /> Unassign\n </DropdownMenuItem>\n </>\n ) : null}\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n\n/* ── Account owner(s) (Salesforce, read-through) ─────────────────────────── */\n\nexport interface AccountOwnerChipProps {\n /** Salesforce account owners (RM, AE, …). Empty -> renders nothing. */\n owners: OwnerPerson[]\n className?: string\n}\n\nfunction AccountOwnerSummary({ person }: { person: OwnerPerson }) {\n return (\n <span className=\"flex min-w-0 flex-col\">\n <span className=\"truncate text-[13px] font-medium\">{person.name}</span>\n {person.role ? (\n <span className=\"text-muted-foreground truncate text-[11px]\">{person.role}</span>\n ) : null}\n {person.email ? (\n <span className=\"text-muted-foreground truncate text-[11px]\">{person.email}</span>\n ) : null}\n </span>\n )\n}\n\nfunction AccountOwnerSalesforceLink({ person }: { person: OwnerPerson }) {\n if (!person.href) return null\n\n return (\n <DropdownMenuItem asChild className=\"p-0\">\n <a\n href={person.href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n data-account-owner-salesforce-link=\"true\"\n className=\"text-foreground focus:bg-accent focus:text-accent-foreground flex items-center gap-1.5 rounded-sm px-2 py-1.5 text-[12px] font-medium outline-hidden transition-colors\"\n title={`Open ${person.name} in Salesforce`}\n >\n <ArrowUpRight size={12} className=\"text-muted-foreground\" />\n Open in Salesforce\n </a>\n </DropdownMenuItem>\n )\n}\n\nfunction AccountOwnerRow({ person }: { person: OwnerPerson }) {\n return (\n <>\n <DropdownMenuItem\n disabled\n data-owner-row=\"true\"\n className=\"items-start gap-2 py-1.5 data-[disabled]:opacity-100\"\n >\n <OwnerAvatar person={person} size=\"default\" />\n <AccountOwnerSummary person={person} />\n </DropdownMenuItem>\n <AccountOwnerSalesforceLink person={person} />\n </>\n )\n}\n\nfunction SalesforceReadOnlyHelper() {\n return (\n <div role=\"presentation\" className=\"text-muted-foreground flex items-start gap-1.5 px-2 py-1.5 text-[11px]\">\n <Info size={12} className=\"mt-0.5 shrink-0\" />\n <span>Read-only from Salesforce. Manage owners in Salesforce.</span>\n </div>\n )\n}\n\nfunction AccountOwnerChip({ owners, className }: AccountOwnerChipProps) {\n const [open, setOpen] = React.useState(false)\n if (!owners.length) return null\n const multi = owners.length > 1\n\n if (!multi) {\n const only = owners[0]\n\n return (\n <DropdownMenu open={open} onOpenChange={setOpen}>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n data-slot=\"account-owner-chip\"\n className={cn(chipBase, \"hover:bg-muted cursor-pointer transition-colors\", className)}\n title={`Account owner in Salesforce — ${only.name}`}\n >\n <span className=\"inline-flex shrink-0 items-center\">\n <SalesforceMark />\n </span>\n <OwnerAvatar person={only} />\n <span className=\"text-foreground font-medium\">{only.name}</span>\n <span className=\"text-muted-foreground ml-0.5\">\n {open ? <ChevronUp size={12} /> : <ChevronDown size={12} />}\n </span>\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"w-72\">\n <DropdownMenuLabel className=\"flex items-center gap-1.5 text-[13px]\">\n <SalesforceMark />\n Account owner\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n <AccountOwnerRow person={only} />\n <DropdownMenuSeparator />\n <SalesforceReadOnlyHelper />\n </DropdownMenuContent>\n </DropdownMenu>\n )\n }\n\n // Multiple owners: stacked avatars + ×N + a menu listing each.\n return (\n <DropdownMenu open={open} onOpenChange={setOpen}>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n data-slot=\"account-owner-chip\"\n data-multi=\"true\"\n className={cn(chipBase, \"hover:bg-muted cursor-pointer transition-colors\", className)}\n title=\"Account owners in Salesforce\"\n >\n <span className=\"inline-flex shrink-0 items-center\">\n <SalesforceMark />\n </span>\n <span className=\"flex -space-x-2\">\n {owners.map((o) => (\n <OwnerAvatar key={o.id ?? o.name} person={o} />\n ))}\n </span>\n <span className=\"text-foreground font-medium\">Account owners</span>\n <span className=\"bg-muted text-muted-foreground rounded px-1 text-[10px] font-semibold tabular-nums\">\n ×{owners.length}\n </span>\n <span className=\"text-muted-foreground ml-0.5\">\n {open ? <ChevronUp size={12} /> : <ChevronDown size={12} />}\n </span>\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"w-72\">\n <DropdownMenuLabel className=\"flex items-center gap-1.5 text-[13px]\">\n <SalesforceMark />\n {owners.length} account owners\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n {owners.map((o) => (\n <AccountOwnerRow key={o.id ?? o.name} person={o} />\n ))}\n <DropdownMenuSeparator />\n <SalesforceReadOnlyHelper />\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n\n/* ── Convenience composite ──────────────────────────────────────────────── */\n\nexport interface OwnerChipsProps extends SignalOwnerChipProps {\n /** Salesforce account owners (read-through). */\n accountOwners?: OwnerPerson[]\n}\n\nfunction OwnerChips({ accountOwners = [], className, ...signal }: OwnerChipsProps) {\n return (\n <>\n <SignalOwnerChip {...signal} className={className} />\n <AccountOwnerChip owners={accountOwners} className={className} />\n </>\n )\n}\n\nexport { SignalOwnerChip, AccountOwnerChip, OwnerChips }\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -109,6 +109,16 @@ describe("SignalOwnerChip", () => {
|
|
|
109
109
|
expect(cls).not.toContain("text-[13px]");
|
|
110
110
|
});
|
|
111
111
|
|
|
112
|
+
it("renders the owner avatar with a 1px ring (no thick ring overflow)", () => {
|
|
113
|
+
const { container } = render(<SignalOwnerChip owner={dana} />);
|
|
114
|
+
const avatar = container.querySelector('[data-slot="avatar"]')!;
|
|
115
|
+
const cls = avatar.className;
|
|
116
|
+
expect(cls).toContain("ring-background");
|
|
117
|
+
expect(cls).toContain("ring-1");
|
|
118
|
+
// The thick ring used to bleed past the chip border; it must be gone.
|
|
119
|
+
expect(cls).not.toContain("ring-2");
|
|
120
|
+
});
|
|
121
|
+
|
|
112
122
|
it("renders a static span (no button) when read-only / no handlers", () => {
|
|
113
123
|
const { container } = render(<SignalOwnerChip owner={dana} />);
|
|
114
124
|
const el = container.querySelector('[data-slot="signal-owner-chip"]');
|
|
@@ -73,7 +73,7 @@ function SalesforceMark({ size = 13 }: { size?: number }) {
|
|
|
73
73
|
|
|
74
74
|
function OwnerAvatar({ person, size = "sm" }: { person: OwnerPerson; size?: "sm" | "default" }) {
|
|
75
75
|
return (
|
|
76
|
-
<Avatar size={size} className="ring-background ring-
|
|
76
|
+
<Avatar size={size} className="ring-background ring-1">
|
|
77
77
|
{person.avatarUrl ? <AvatarImage src={person.avatarUrl} alt={person.name} /> : null}
|
|
78
78
|
<AvatarFallback className="bg-muted text-muted-foreground text-[10px] font-medium uppercase">
|
|
79
79
|
{getInitials({ name: person.name, email: person.email })}
|