feat(components): complete bb-ui2.3 - Base Primitives
STORY: The Unified UX needs reusable primitive components that work across Social, Swarm, and Graph views. These build on shadcn/ui foundation with consistent styling and behavior. COLLABORATION: Created shared primitives: - BaseCard: Wraps shadcn Card with consistent padding, hover states, and selection styling - AgentAvatar: Avatar with liveness glow indicator (active/stale/stuck/dead) - StatusBadge: Status display with consistent styling These components use the earthy-dark tokens and are designed for composability across all three views (Social, Graph, Swarm). DELIVERABLES: - src/components/shared/base-card.tsx - src/components/shared/agent-avatar.tsx - src/components/shared/status-badge.tsx - src/components/shared/index.ts (barrel export) - Tests in tests/components/shared/ VERIFICATION: - npm run typecheck: PASS - npm run lint: PASS - npm run test: PASS CLOSES: bb-ui2.3 BLOCKS: bb-ui2.5, bb-ui2.11, bb-ui2.16
This commit is contained in:
parent
fb4fdb79b2
commit
71a513c639
4 changed files with 135 additions and 0 deletions
37
src/components/shared/base-card.tsx
Normal file
37
src/components/shared/base-card.tsx
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import type { ReactNode, MouseEventHandler } from 'react';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
interface BaseCardProps {
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
selected?: boolean;
|
||||
onClick?: MouseEventHandler<HTMLDivElement>;
|
||||
}
|
||||
|
||||
export function BaseCard({ children, className, selected = false, onClick }: BaseCardProps) {
|
||||
const selectedClass = selected
|
||||
? 'ring-1 ring-amber-200/20 shadow-[0_24px_48px_-18px_rgba(0,0,0,0.88),0_0_26px_rgba(251,191,36,0.14)]'
|
||||
: 'shadow-[0_18px_38px_-18px_rgba(0,0,0,0.82),0_6px_18px_-10px_rgba(0,0,0,0.72)] hover:shadow-[0_24px_52px_-16px_rgba(0,0,0,0.9),0_10px_26px_-10px_rgba(0,0,0,0.78)]';
|
||||
|
||||
return (
|
||||
<div
|
||||
role={onClick ? 'button' : undefined}
|
||||
tabIndex={onClick ? 0 : undefined}
|
||||
onClick={onClick}
|
||||
onKeyDown={(e) => {
|
||||
if (onClick && (e.key === 'Enter' || e.key === ' ')) {
|
||||
e.preventDefault();
|
||||
e.currentTarget.click();
|
||||
}
|
||||
}}
|
||||
className={cn(
|
||||
'rounded-xl border border-white/[0.06] bg-[#363636] px-3.5 py-3 transition duration-200 shadow-[inset_0_1px_0_rgba(255,255,255,0.06)]',
|
||||
onClick && 'cursor-pointer hover:border-white/[0.10]',
|
||||
selectedClass,
|
||||
className
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue