@grasco/profile-picture 0.2.5 → 0.2.6
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.
- package/dist/angular.cjs +1 -1
- package/dist/angular.cjs.map +1 -1
- package/dist/angular.js +1 -1
- package/dist/angular.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +1 -1
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +1 -1
- package/dist/react.js.map +1 -1
- package/dist/standalone.standalone.js +1 -1
- package/dist/standalone.standalone.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/svelte.cjs +1 -1
- package/dist/svelte.cjs.map +1 -1
- package/dist/svelte.js +1 -1
- package/dist/svelte.js.map +1 -1
- package/dist/vue.cjs +1 -1
- package/dist/vue.cjs.map +1 -1
- package/dist/vue.js +1 -1
- package/dist/vue.js.map +1 -1
- package/package.json +1 -1
package/dist/angular.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/loadStyles.ts","../src/core/types.ts","../src/core/utils.ts","../src/core/styles.ts","../src/core/ProfilePicture.ts","../src/core/ProfilePictureGroup.ts","../src/wrappers/angular/index.ts","../src/angular.ts"],"names":["LINK_ID","loaded","loadScheduled","loadStyles","scheduleStyleInjection","cb","injectStyleLink","cssUrl","getCssUrl","link","metaUrl","currentScript","scriptUrl","SIZE_MAP","PRESENCE_COLORS","SHADOW_MAP","DEFAULTS","RADIUS_MAP","GROUP_DEFAULTS","cn","classes","isHexColor","color","getInitials","text","words","getInitialsFontSize","containerSize","getBadgeSize","avatarSize","hasContent","size","scaled","fontSize","getPresenceSize","thickness","baseSize","formatBadgeContent","content","max","createConicGradient","colors","i","start","end","hashString","str","hash","char","createProgressRingGradient","progress","filledColor","emptyColor","progressDeg","generateAvatarGradient","name","gradients","index","CLOUDY_PALETTES","blendHex","hex","base","ratio","parse","h","c","b","mix","generateCloudyGradient","seed","palette","edge0","edge1","edge2","h2","h3","x1","y1","x2","y2","x3","y3","getGroupAvatarSize","calculateAvatarCounts","total","showAddButton","effectiveMax","visible","hidden","calculateStackPosition","overlap","_direction","spacing","step","calculateStackZIndex","direction","calculateGroupWidth","count","formatCounterText","getCdnSizeLabel","pixelSize","constructCdnUrl","baseUrl","extCustomerId","sizeLabel","imageMode","hostname","cleanBaseUrl","filename","getVariantClasses","variant","getBorderClasses","width","getBackgroundStyles","bgColor","bgGradient","getShadowStyles","shadow","keyframes","allKeyframes","baseStyles","componentStyles","shimmerStyles","getGlowShadow","intensity","r","g","groupKeyframes","groupBaseStyles","groupStyles","_ProfilePicture","LitElement","url","instance","style","value","sizeValue","changedProperties","extCustomerIdChanged","cdnParamsChanged","event","bg","borderStyles","shadowStyles","glow","glowStyles","glowColor","interactive","isInteractive","nothing","placeholderClass","html","styleMap","hasExplicitBg","gradient","iconSize","hasCdnConfig","imageSrc","zoomStyle","ring","ringWidth","ringGap","totalOffset","ringColor","hasProgress","radius","presence","offset","badge","position","hasIcon","hasAnyContent","badgeSize","textColor","borderRadius","icon","posOffset","positionStyles","container","tabIndex","__decorateClass","property","state","ProfilePicture","groupStylesInjected","injectGroupStyles","ProfilePictureGroup","children","child","el","getPropOrAttr","propName","attrName","actualAttrName","propValue","borderWidthValue","borderWidth","v","attr","user","render","hiddenUsers","rect","gap","dropdownWidth","dropdownHeight","viewportWidth","viewportHeight","spaceBelow","spaceAbove","spaceRight","spaceLeft","openDirection","left","top","bottom","target","handler","zIndex","rotation","e","containerRect","relativeLeft","relativeTop","relativeBottom","isTop","hasImage","status","counter","showCounter","visibleUsers","elementCount","containerWidth","counterPosition","addButtonPosition","setCdnBaseUrl","getCdnBaseUrl"],"mappings":"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AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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","file":"angular.cjs","sourcesContent":["/**\n * Idempotent CSS loader for @grasco/profile-picture\n *\n * Auto-injects the component's CSS via <link> tag when the module is imported.\n * Uses relative URL detection to find styles.css in the same directory as the JS file.\n *\n * Idempotency is guaranteed through 4 layers:\n * 1. Module-level flag - prevents multiple calls in same bundle\n * 2. ID check - prevents duplicates across bundles\n * 3. href pattern check - catches manually added links\n * 4. SSR guard - prevents errors in Node.js\n *\n * SSR Hydration Safety:\n * Style injection is deferred using requestIdleCallback (with setTimeout fallback)\n * to avoid DOM mutations during React/framework hydration, which would cause\n * hydration mismatch errors.\n */\n\nconst LINK_ID = \"grasco-profile-picture-styles\";\n\nlet loaded = false;\nlet loadScheduled = false;\n\n/**\n * Load the component's CSS stylesheet\n * Safe to call multiple times - will only inject once\n * Defers injection to avoid SSR hydration mismatch\n */\nexport function loadStyles(): void {\n // Skip if already loaded (module-level)\n if (loaded) {\n return;\n }\n\n // Skip if SSR (no document)\n if (typeof document === \"undefined\") {\n return;\n }\n\n // Skip if link already exists by ID (idempotency across bundles)\n if (document.getElementById(LINK_ID)) {\n loaded = true;\n return;\n }\n\n // Check if any link already points to our CSS (by href pattern)\n const existingLink = document.querySelector(\n 'link[href*=\"profile-picture\"][href$=\"styles.css\"]'\n );\n if (existingLink) {\n loaded = true;\n return;\n }\n\n // Schedule deferred injection (after hydration completes)\n if (!loadScheduled) {\n loadScheduled = true;\n scheduleStyleInjection();\n }\n}\n\n/**\n * Schedule style injection after hydration using requestIdleCallback\n * Falls back to setTimeout for browsers without requestIdleCallback support\n */\nfunction scheduleStyleInjection(): void {\n const defer =\n typeof requestIdleCallback !== \"undefined\"\n ? requestIdleCallback\n : (cb: () => void) => setTimeout(cb, 1);\n\n defer(() => injectStyleLink());\n}\n\n/**\n * Actually inject the <link> tag into the document head\n */\nfunction injectStyleLink(): void {\n // Re-check conditions in case something changed\n if (loaded || typeof document === \"undefined\") {\n return;\n }\n\n if (document.getElementById(LINK_ID)) {\n loaded = true;\n return;\n }\n\n // Get CSS URL relative to current script\n const cssUrl = getCssUrl();\n if (!cssUrl) {\n return;\n }\n\n // Inject link tag\n const link = document.createElement(\"link\");\n link.id = LINK_ID;\n link.rel = \"stylesheet\";\n link.href = cssUrl;\n document.head.appendChild(link);\n\n loaded = true;\n}\n\n/**\n * Get the CSS file URL based on the current script's location\n */\nfunction getCssUrl(): string | null {\n // Allow custom override via global variable\n if (\n typeof window !== \"undefined\" &&\n (window as unknown as Record<string, string>).__GRASCO_PROFILE_PICTURE_CSS__\n ) {\n return (window as unknown as Record<string, string>)\n .__GRASCO_PROFILE_PICTURE_CSS__;\n }\n\n // Try import.meta.url first (ESM - most reliable for bundlers)\n try {\n const metaUrl = import.meta.url;\n if (metaUrl) {\n const basePath = metaUrl.substring(0, metaUrl.lastIndexOf(\"/\") + 1);\n return `${basePath}styles.css`;\n }\n } catch {\n // import.meta.url not available\n }\n\n // Fallback: Get current script URL\n const currentScript = document.currentScript as HTMLScriptElement | null;\n if (currentScript?.src) {\n const scriptUrl = new URL(currentScript.src);\n const basePath = scriptUrl.href.substring(\n 0,\n scriptUrl.href.lastIndexOf(\"/\") + 1\n );\n return `${basePath}dist/styles.css`;\n }\n\n return null;\n}\n","/**\n * Profile Picture Component - Type Definitions\n * Apple-inspired design system with modern 2025 aesthetics\n */\n\n// ─── Size System (Apple 8pt Grid) ─────────────────────────────────────────────\nexport type Size = \"2xs\" | \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\" | \"3xl\";\n\n// Size presets in pixels (following 8pt grid)\nexport const SIZE_MAP: Record<Size, number> = {\n \"2xs\": 20, // Inline, compact UI\n xs: 24, // Small avatars, lists\n sm: 32, // Default list items\n md: 40, // Navigation, headers\n lg: 48, // Profile sections\n xl: 64, // Profile pages\n \"2xl\": 80, // Hero sections\n \"3xl\": 120, // Profile modals\n};\n\n// ─── Visual Variants ──────────────────────────────────────────────────────────\nexport type Variant = \"circle\" | \"rounded\" | \"squircle\" | \"square\";\n\n// ─── Positioning ──────────────────────────────────────────────────────────────\nexport type Position =\n | \"top-left\"\n | \"top-center\"\n | \"top-right\"\n | \"bottom-left\"\n | \"bottom-center\"\n | \"bottom-right\";\n\n// ─── Loading & Performance ────────────────────────────────────────────────────\nexport type LoadingStrategy = \"lazy\" | \"eager\";\nexport type PlaceholderType =\n | \"shimmer\"\n | \"pulse\"\n | \"blur\"\n | \"skeleton\"\n | \"none\";\n\nexport type FallbackMode = \"initials\" | \"gradient\";\nexport type ImageMode = \"transparent\" | \"original\";\n\n// ─── Presence / Status System ─────────────────────────────────────────────────\nexport type PresenceStatus = \"online\" | \"away\" | \"busy\" | \"offline\" | \"dnd\";\n\nexport interface PresenceConfig {\n /** Current status */\n status: PresenceStatus;\n /** Show animated ring */\n animate?: boolean;\n /** Ring thickness (1-3) */\n thickness?: 1 | 2 | 3;\n}\n\n// Status colors (Apple-inspired)\nexport const PRESENCE_COLORS: Record<PresenceStatus, string> = {\n online: \"#30D158\", // Apple Green\n away: \"#FFD60A\", // Apple Yellow\n busy: \"#FF453A\", // Apple Red\n offline: \"#8E8E93\", // Apple Gray\n dnd: \"#FF453A\", // Apple Red (Do Not Disturb)\n};\n\n// ─── Badge Configuration ──────────────────────────────────────────────────────\nexport interface BadgeConfig {\n /** Badge content (text, number, or empty for dot) */\n content?: string | number;\n /** Position of the badge */\n position?: Position;\n /** Text/icon color */\n color?: string;\n /** Background color */\n bgColor?: string;\n /** Border radius (CSS value, e.g., \"8px\", \"50%\", \"9999px\") */\n borderRadius?: string;\n /** Enable pulse animation */\n pulse?: boolean;\n /** Enable glow effect */\n glow?: boolean;\n /** Max value to display (shows 99+ if exceeded) */\n max?: number;\n /** Icon to display before content (emoji, Unicode symbol, or text) */\n icon?: string;\n}\n\n// ─── Glow Effect ──────────────────────────────────────────────────────────────\nexport interface GlowConfig {\n /** Glow color (defaults to border or bg color) */\n color?: string;\n /** Intensity (0-1) */\n intensity?: number;\n /** Animate the glow */\n animate?: boolean;\n}\n\n// ─── Ring Effect (like Instagram stories) ────────────────────────────────────\nexport interface RingConfig {\n /** Show ring */\n show: boolean;\n /** Ring color or gradient */\n color?: string;\n /** Gradient colors for multi-color ring */\n gradient?: string[];\n /** Ring width */\n width?: number;\n /** Gap between ring and avatar */\n gap?: number;\n /** Animate (rotate for gradient) */\n animate?: boolean;\n /** Progress percentage (0-100) for partial fill ring */\n progress?: number;\n /** Color for unfilled portion when progress is set (defaults to gray) */\n emptyColor?: string;\n}\n\n// ─── Interactive States ───────────────────────────────────────────────────────\nexport interface InteractionConfig {\n /** Enable hover effects */\n hoverable?: boolean;\n /** Enable press/click effects */\n pressable?: boolean;\n /** Show focus ring on focus */\n focusable?: boolean;\n /** Cursor style */\n cursor?: \"pointer\" | \"default\" | \"zoom-in\";\n}\n\n// ─── Shadow Presets ───────────────────────────────────────────────────────────\nexport type ShadowPreset = \"none\" | \"sm\" | \"md\" | \"lg\" | \"glow\";\n\nexport const SHADOW_MAP: Record<ShadowPreset, string> = {\n none: \"none\",\n sm: \"0 1px 2px 0 rgba(0, 0, 0, 0.05)\",\n md: \"0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1)\",\n lg: \"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1)\",\n glow: \"0 0 20px 0 rgba(99, 102, 241, 0.3)\",\n};\n\n// ─── Animation Presets ────────────────────────────────────────────────────────\nexport type AnimationPreset = \"none\" | \"fade\" | \"scale\" | \"slide\" | \"bounce\";\n\n// ─── Default Values ───────────────────────────────────────────────────────────\nexport const DEFAULTS = {\n size: \"md\" as Size,\n variant: \"circle\" as Variant,\n loading: \"lazy\" as LoadingStrategy,\n placeholder: \"shimmer\" as PlaceholderType,\n borderWidth: 2 as const,\n borderColor: \"#ffffff\",\n placeholderColor: \"#f3f4f6\",\n shadow: \"sm\" as ShadowPreset,\n animation: \"fade\" as AnimationPreset,\n imageMode: \"original\" as ImageMode,\n zoom: 1.2,\n} as const;\n\n// ─── CSS Custom Properties (for theming) ──────────────────────────────────────\nexport const CSS_VARS = {\n \"--pp-transition-duration\": \"200ms\",\n \"--pp-transition-timing\": \"cubic-bezier(0.4, 0, 0.2, 1)\",\n \"--pp-spring-timing\": \"cubic-bezier(0.34, 1.56, 0.64, 1)\",\n \"--pp-hover-scale\": \"1.05\",\n \"--pp-press-scale\": \"0.95\",\n \"--pp-focus-ring-color\": \"rgba(99, 102, 241, 0.5)\",\n \"--pp-focus-ring-width\": \"3px\",\n \"--pp-skeleton-base\": \"#e5e7eb\",\n \"--pp-skeleton-shine\": \"#f3f4f6\",\n} as const;\n\n// ─── Border Radius Presets ────────────────────────────────────────────────────\nexport const RADIUS_MAP: Record<Variant, string> = {\n circle: \"9999px\",\n rounded: \"12px\",\n squircle: \"30%\", // iOS app icon style\n square: \"0px\",\n};\n\n// ─── Full Component Props Interface ───────────────────────────────────────────\n/**\n * Base props interface shared across all framework wrappers.\n * This ensures type consistency between React, Vue, Svelte, and Angular.\n */\nexport interface ProfilePictureProps {\n // Core\n /** Image source URL */\n src?: string;\n /** Alt text for accessibility and fallback initials */\n alt?: string;\n /** External customer ID for CDN image loading */\n extCustomerId?: string;\n /** CDN image mode: 'transparent' for transparent background, 'original' for original background */\n imageMode?: ImageMode;\n\n // Sizing\n /** Predefined size or custom pixel value */\n size?: Size | number;\n\n // Visual\n /** Shape variant */\n variant?: Variant;\n /** Shadow preset */\n shadow?: ShadowPreset;\n\n // Border\n /** Enable border */\n border?: boolean;\n /** Border width in pixels */\n borderWidth?: 1 | 2 | 3 | 4 | 5 | 6 | 8;\n /** Border color (CSS color value) */\n borderColor?: string;\n\n // Rotation\n /** Rotation angle in degrees */\n rotation?: number;\n\n // Zoom\n /** Zoom level for the image (default: 1.4). Values > 1 zoom in, keeping the image within the crop zone */\n zoom?: number;\n\n // Background\n /** Background color (CSS color value) */\n bgColor?: string;\n /** Background gradient (CSS gradient value) */\n bgGradient?: string;\n\n // Effects\n /** Glow effect configuration */\n glow?: GlowConfig;\n /** Ring effect configuration (Instagram-style) */\n ring?: RingConfig;\n /** Presence indicator configuration */\n presence?: PresenceConfig;\n\n // Overlays\n /** Badge configuration */\n badge?: BadgeConfig;\n\n // Loading\n /** Loading strategy */\n loading?: LoadingStrategy;\n /** Placeholder type while loading */\n placeholder?: PlaceholderType;\n /** Placeholder background color */\n placeholderColor?: string;\n\n // Fallback\n /** Custom fallback text (overrides initials from alt) */\n fallback?: string;\n /** Fallback display mode: 'initials' shows letters, 'gradient' shows cloudy gradient */\n fallbackMode?: FallbackMode;\n\n // Interaction\n /** Interactive behavior configuration */\n interactive?: InteractionConfig;\n}\n\n// ─── Profile Picture Group Types ─────────────────────────────────────────────\n\n/** Direction for stacking avatars */\nexport type StackDirection = \"ltr\" | \"rtl\";\n\n/** Tooltip position relative to avatar */\nexport type TooltipPosition = \"top\" | \"bottom\" | \"left\" | \"right\";\n\n/** Tooltip configuration */\nexport interface TooltipConfig {\n /** Enable/disable tooltip (default: true) */\n enabled?: boolean;\n /** Position of tooltip relative to avatar */\n position?: TooltipPosition;\n /** Delay before showing tooltip in ms (default: 300) */\n delay?: number;\n}\n\n/** User data extracted from profile-picture elements */\nexport interface GroupUserData {\n /** User ID from data-user-id attribute */\n id?: string;\n /** User name from alt attribute */\n name: string;\n /** Image source URL */\n src?: string;\n /** External customer ID for CDN image loading */\n extCustomerId?: string;\n /** Presence status from data-status attribute */\n status?: PresenceStatus;\n /** Reference to the profile-picture element */\n element: HTMLElement;\n /** Index in the group */\n index: number;\n\n // ─── Profile Picture Props (passed through from slotted elements) ──────────\n /** Visual variant (circle, rounded, squircle, square) */\n variant?: Variant;\n /** Shadow preset */\n shadow?: ShadowPreset;\n /** Show border */\n border?: boolean;\n /** Border width (1-8) */\n borderWidth?: 1 | 2 | 3 | 4 | 5 | 6 | 8;\n /** Border color */\n borderColor?: string;\n /** Background color */\n bgColor?: string;\n /** Background gradient */\n bgGradient?: string;\n /** CDN image mode */\n imageMode?: ImageMode;\n /** Zoom level */\n zoom?: number;\n /** Loading strategy */\n loading?: LoadingStrategy;\n /** Placeholder type */\n placeholder?: PlaceholderType;\n /** Placeholder color */\n placeholderColor?: string;\n /** Custom fallback text */\n fallback?: string;\n /** Fallback mode */\n fallbackMode?: FallbackMode;\n /** Glow config */\n glow?: GlowConfig;\n /** Ring config */\n ring?: RingConfig;\n /** Badge config */\n badge?: BadgeConfig;\n /** Interactive config */\n interactive?: InteractionConfig;\n}\n\n/** Dropdown configuration for overflow users */\nexport interface DropdownConfig {\n /** Max height of dropdown in px (default: 280) */\n maxHeight?: number;\n /** Show presence indicator dots (default: true) */\n showPresence?: boolean;\n /** Dropdown position (default: 'bottom') */\n position?: \"bottom\" | \"top\";\n}\n\n/** Profile Picture Group Props */\nexport interface ProfilePictureGroupProps {\n /** Maximum visible avatars before showing counter (default: 4) */\n max?: number;\n /** Stack direction - ltr shows first on left (default: 'ltr') */\n direction?: StackDirection;\n /** Overlap amount as percentage 0-1 (default: 0.3) */\n overlap?: number;\n /** Avatar size - inherited by children (default: 'md') */\n size?: Size | number;\n /** Spacing between avatars in px (overrides overlap calculation) */\n spacing?: number;\n /** Tooltip configuration */\n tooltip?: TooltipConfig;\n /** Dropdown configuration for overflow users */\n dropdown?: DropdownConfig;\n /** Show add button (default: false) */\n showAddButton?: boolean;\n /** Add button label for accessibility */\n addButtonLabel?: string;\n /** Enable hover lift animation (default: true) */\n animated?: boolean;\n}\n\n/** Group component defaults */\nexport const GROUP_DEFAULTS = {\n max: 4,\n direction: \"ltr\" as StackDirection,\n overlap: 0.3,\n size: \"md\" as Size,\n tooltipDelay: 300,\n dropdownMaxHeight: 280,\n animated: true,\n} as const;\n","/**\n * Profile Picture Component - Utility Functions\n * Apple-inspired design system utilities\n */\n\nimport type { Size, Variant } from \"./types\";\nimport { RADIUS_MAP, SIZE_MAP } from \"./types\";\n\n/**\n * Resolve size to pixel value\n */\nexport function resolveSize(size: Size | number): number {\n if (typeof size === \"number\") {\n return size;\n }\n return SIZE_MAP[size] ?? SIZE_MAP.md;\n}\n\n/**\n * Merge class names, filtering out falsy values\n */\nexport function cn(...classes: (string | undefined | null | false)[]): string {\n return classes.filter(Boolean).join(\" \");\n}\n\n/**\n * Check if a color value is a hex code\n */\nexport function isHexColor(color: string): boolean {\n return /^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/.test(color);\n}\n\n/**\n * Check if a value is a CSS color (not a Tailwind class)\n */\nexport function isCssColor(value: string): boolean {\n if (isHexColor(value)) {\n return true;\n }\n if (/^(rgb|hsl|oklch|oklab|lab|lch)a?\\s*\\(/.test(value)) {\n return true;\n }\n if (value.includes(\"gradient\")) {\n return true;\n }\n const namedColors = [\n \"transparent\",\n \"currentColor\",\n \"inherit\",\n \"white\",\n \"black\",\n ];\n return namedColors.includes(value.toLowerCase());\n}\n\n/**\n * Generate initials from alt text for fallback\n * Apple-style: Single letter for single word, two letters for multiple\n */\nexport function getInitials(text: string): string {\n const cleaned = text.trim().replace(/[^\\w\\s]/g, \"\");\n const words = cleaned.split(/\\s+/).filter(Boolean);\n\n if (words.length === 0) {\n return \"?\";\n }\n if (words.length === 1) {\n return words[0].slice(0, 1).toUpperCase();\n }\n return (words[0][0] + (words.at(-1)?.[0] ?? \"\")).toUpperCase();\n}\n\n/**\n * Get border radius value for variant\n */\nexport function getRadius(variant: Variant): string {\n return RADIUS_MAP[variant];\n}\n\n/**\n * Calculate optimal font size for initials based on container size\n */\nexport function getInitialsFontSize(containerSize: number): number {\n return Math.round(containerSize * 0.38);\n}\n\n/**\n * Calculate badge size relative to avatar size\n * Uses non-linear scaling to maintain visual balance:\n * - XL (64px) is the reference: ~33% ratio looks good\n * - Small avatars: proportionally smaller badges with reasonable minimums\n * - Large avatars: caps prevent oversized badges\n */\nexport function getBadgeSize(\n avatarSize: number,\n hasContent: boolean\n): { size: number; fontSize: number } {\n // Reference: XL (64px) avatar with content badge = 20px (31%)\n // Use diminishing ratio for larger sizes\n let size: number;\n\n if (hasContent) {\n // Badge with content: min 14px, max 24px\n // Scale: 31% ratio but capped\n const scaled = Math.round(avatarSize * 0.31);\n size = Math.min(24, Math.max(14, scaled));\n } else {\n // Dot badge: min 8px, max 14px\n // Scale: 22% ratio but capped\n const scaled = Math.round(avatarSize * 0.22);\n size = Math.min(14, Math.max(8, scaled));\n }\n\n // Font size: 55% of badge for better readability at small sizes\n const fontSize = Math.max(9, Math.round(size * 0.55));\n return { size, fontSize };\n}\n\n/**\n * Calculate presence indicator size\n * Uses capped scaling to maintain visual balance:\n * - Reference: XL (64px) with thickness 2 = 14px (~22%)\n * - Small avatars: min 8px for visibility\n * - Large avatars: max 18px to prevent oversizing\n */\nexport function getPresenceSize(\n avatarSize: number,\n thickness: 1 | 2 | 3\n): number {\n // Base size: 20% ratio, capped between 8-16px\n const baseSize = Math.min(16, Math.max(8, Math.round(avatarSize * 0.2)));\n // Add thickness adjustment (0, 2, or 4 pixels)\n return Math.min(18, baseSize + (thickness - 1) * 2);\n}\n\n/**\n * Format badge content (e.g., 99+ for large numbers)\n */\nexport function formatBadgeContent(\n content: string | number,\n max?: number\n): string {\n if (typeof content === \"string\") {\n return content;\n }\n if (max && content > max) {\n return `${max}+`;\n }\n return content.toString();\n}\n\n/**\n * Generate a gradient from colors array for ring effect\n */\nexport function createConicGradient(colors: string[]): string {\n if (colors.length === 0) {\n return \"transparent\";\n }\n if (colors.length === 1) {\n return colors[0];\n }\n\n const stops = colors.map((color, i) => {\n const start = (i / colors.length) * 360;\n const end = ((i + 1) / colors.length) * 360;\n return `${color} ${start}deg ${end}deg`;\n });\n\n return `conic-gradient(${stops.join(\", \")})`;\n}\n\n/**\n * Get contrast color for text on background\n * Returns white or black based on background luminance\n */\nexport function getContrastColor(bgColor: string): string {\n // Extract RGB values from hex\n if (!isHexColor(bgColor)) {\n return \"#ffffff\";\n }\n\n const hex = bgColor.replace(\"#\", \"\");\n const r = Number.parseInt(hex.slice(0, 2), 16);\n const g = Number.parseInt(hex.slice(2, 4), 16);\n const b = Number.parseInt(hex.slice(4, 6), 16);\n\n // Calculate relative luminance\n const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;\n\n return luminance > 0.5 ? \"#000000\" : \"#ffffff\";\n}\n\n/**\n * Clamp a number between min and max\n */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\n/**\n * Generate a stable hash from string for consistent random colors\n */\nexport function hashString(str: string): number {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash &= hash;\n }\n return Math.abs(hash);\n}\n\n/**\n * Create a progress ring gradient using conic gradient\n * @param progress Progress percentage (0-100)\n * @param filledColor Color for filled portion\n * @param emptyColor Color for empty portion\n * @returns CSS conic gradient string\n */\nexport function createProgressRingGradient(\n progress: number,\n filledColor: string,\n emptyColor: string\n): string {\n // Clamp progress to 0-100\n const clampedProgress = Math.max(0, Math.min(100, progress));\n // Convert percentage to degrees (start from top, go clockwise)\n // 0% = 0deg (top), 100% = 360deg (full circle)\n const progressDeg = (clampedProgress / 100) * 360;\n // Create conic gradient starting from top (270deg offset to start at 12 o'clock)\n // Then go clockwise: filled color from 0% to progress%, empty color from progress% to 100%\n return `conic-gradient(from 270deg, ${filledColor} 0deg ${progressDeg}deg, ${emptyColor} ${progressDeg}deg 360deg)`;\n}\n\n/**\n * Generate a gradient from name for fallback backgrounds\n */\nexport function generateAvatarGradient(name: string): string {\n const gradients = [\n \"linear-gradient(135deg, #667eea 0%, #764ba2 100%)\",\n \"linear-gradient(135deg, #f093fb 0%, #f5576c 100%)\",\n \"linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)\",\n \"linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)\",\n \"linear-gradient(135deg, #fa709a 0%, #fee140 100%)\",\n \"linear-gradient(135deg, #a8edea 0%, #fed6e3 100%)\",\n \"linear-gradient(135deg, #d299c2 0%, #fef9d7 100%)\",\n \"linear-gradient(135deg, #89f7fe 0%, #66a6ff 100%)\",\n \"linear-gradient(135deg, #cd9cf2 0%, #f6f3ff 100%)\",\n \"linear-gradient(135deg, #fddb92 0%, #d1fdff 100%)\",\n ];\n\n const index = hashString(name) % gradients.length;\n return gradients[index];\n}\n\n/**\n * Curated 3-color pastel palettes for cloudy gradient fallback.\n * Each palette creates an organic, watercolor-like effect when\n * layered as overlapping radial gradients.\n */\nexport const CLOUDY_PALETTES: [string, string, string][] = [\n [\"#f4a261\", \"#e76f51\", \"#d4a5a5\"], // Warm sunset\n [\"#f2a9b0\", \"#e07a5f\", \"#d4c4a8\"], // Soft coral rose\n [\"#c9b1d0\", \"#e8a0bf\", \"#f0d1ce\"], // Dusty mauve\n [\"#89c2d9\", \"#a3c4bc\", \"#d5c6e0\"], // Ocean mist\n [\"#f7c59f\", \"#f2a07b\", \"#efcfe3\"], // Warm peach\n [\"#b5a7d5\", \"#d4a5c9\", \"#f0c3d7\"], // Lavender dream\n [\"#7ec8c8\", \"#6a9fb5\", \"#c2b5d6\"], // Cool teal\n [\"#f0b3ba\", \"#d4a5c9\", \"#c9d1d9\"], // Blush pink\n [\"#e8b960\", \"#d4956a\", \"#c9a5b8\"], // Amber cloud\n [\"#a7c4a0\", \"#c9d4a5\", \"#e0c9b1\"], // Sage pastel\n [\"#c4819b\", \"#d9a5b8\", \"#b5aed4\"], // Berry soft\n [\"#f0c27f\", \"#e0a87c\", \"#d4b5c9\"], // Golden hour\n];\n\n/**\n * Blend a hex color toward a base color by a given ratio (0 = original, 1 = base).\n * Returns a fully opaque hex color — no transparency involved.\n */\nfunction blendHex(hex: string, base: string, ratio: number): string {\n const parse = (h: string) => [\n Number.parseInt(h.slice(1, 3), 16),\n Number.parseInt(h.slice(3, 5), 16),\n Number.parseInt(h.slice(5, 7), 16),\n ];\n const c = parse(hex);\n const b = parse(base);\n const mix = (i: number) =>\n Math.round(c[i] + (b[i] - c[i]) * ratio)\n .toString(16)\n .padStart(2, \"0\");\n return `#${mix(0)}${mix(1)}${mix(2)}`;\n}\n\n/**\n * Generate a cloudy, organic multi-layer radial gradient from a seed string.\n * Uses 3 overlapping radial-gradient layers with soft edges.\n * All colors are fully opaque — fades blend toward a light neutral base\n * instead of using transparency.\n * Deterministic: same seed always produces the same gradient.\n */\nexport function generateCloudyGradient(seed: string): string {\n const hash = hashString(seed);\n const palette = CLOUDY_PALETTES[hash % CLOUDY_PALETTES.length];\n\n // Light neutral base that colors fade into (warm off-white)\n const base = \"#f5f0eb\";\n\n // Pre-blend each palette color toward the base at 85% ratio for the edge color\n const edge0 = blendHex(palette[0], base, 0.85);\n const edge1 = blendHex(palette[1], base, 0.85);\n const edge2 = blendHex(palette[2], base, 0.85);\n\n // Derive unique positions from hash variations\n const h2 = hashString(seed + \"pos1\");\n const h3 = hashString(seed + \"pos2\");\n\n // Positions range from 20-80% to keep blobs within bounds\n const x1 = 20 + (hash % 61);\n const y1 = 20 + ((hash >> 4) % 61);\n const x2 = 20 + (h2 % 61);\n const y2 = 20 + ((h2 >> 4) % 61);\n const x3 = 20 + (h3 % 61);\n const y3 = 20 + ((h3 >> 4) % 61);\n\n return [\n `radial-gradient(circle at ${x1}% ${y1}%, ${palette[0]} 0%, ${edge0} 70%)`,\n `radial-gradient(circle at ${x2}% ${y2}%, ${palette[1]} 0%, ${edge1} 70%)`,\n `radial-gradient(circle at ${x3}% ${y3}%, ${palette[2]} 0%, ${edge2} 70%)`,\n ].join(\", \");\n}\n\n/**\n * Apply will-change optimization for animations\n */\nexport function getWillChangeProperty(\n hasAnimation: boolean,\n hasHover: boolean\n): string | undefined {\n if (!(hasAnimation || hasHover)) {\n return undefined;\n }\n const properties: string[] = [];\n if (hasAnimation) {\n properties.push(\"opacity\");\n }\n if (hasHover) {\n properties.push(\"transform\");\n }\n return properties.join(\", \");\n}\n\n/**\n * Check if user prefers reduced motion\n */\nexport function prefersReducedMotion(): boolean {\n if (typeof window === \"undefined\") {\n return false;\n }\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n}\n\n// ─── Profile Picture Group Utilities ─────────────────────────────────────────\n\nimport type { GroupUserData, PresenceStatus, StackDirection } from \"./types\";\nimport { GROUP_DEFAULTS } from \"./types\";\n\n/**\n * Calculate the pixel size for group avatars\n */\nexport function getGroupAvatarSize(size: Size | number): number {\n if (typeof size === \"number\") {\n return size;\n }\n return SIZE_MAP[size] ?? SIZE_MAP[GROUP_DEFAULTS.size];\n}\n\n/**\n * Calculate visible and hidden avatar counts\n */\nexport function calculateAvatarCounts(\n total: number,\n max: number,\n showAddButton: boolean\n): { visible: number; hidden: number; showCounter: boolean } {\n const effectiveMax = showAddButton ? max - 1 : max;\n\n if (total <= effectiveMax) {\n return { visible: total, hidden: 0, showCounter: false };\n }\n\n // Show (max - 1) avatars + counter\n const visible = effectiveMax - 1;\n const hidden = total - visible;\n return { visible, hidden, showCounter: true };\n}\n\n/**\n * Calculate position offset for stacked avatars\n */\nexport function calculateStackPosition(\n index: number,\n avatarSize: number,\n overlap: number,\n _direction: StackDirection,\n spacing?: number\n): number {\n const step = spacing ?? avatarSize * (1 - overlap);\n const offset = index * step;\n\n // For RTL, we need to reverse the positioning\n // This is handled at the component level by reversing the order\n return offset;\n}\n\n/**\n * Calculate z-index for stacked avatars\n * First avatar (index 0) has highest z-index to appear on top\n */\nexport function calculateStackZIndex(\n index: number,\n total: number,\n direction: StackDirection\n): number {\n if (direction === \"ltr\") {\n // LTR: First item on top (highest z-index)\n return total - index;\n }\n // RTL: Last item on top\n return index + 1;\n}\n\n/**\n * Calculate the total width of the stacked group\n */\nexport function calculateGroupWidth(\n count: number,\n avatarSize: number,\n overlap: number,\n spacing?: number\n): number {\n if (count === 0) {\n return 0;\n }\n if (count === 1) {\n return avatarSize;\n }\n\n const step = spacing ?? avatarSize * (1 - overlap);\n return avatarSize + step * (count - 1);\n}\n\n/**\n * Extract user data from a profile-picture element\n */\nexport function extractUserData(\n element: HTMLElement,\n index: number\n): GroupUserData {\n return {\n id: element.getAttribute(\"data-user-id\") ?? undefined,\n name: element.getAttribute(\"alt\") ?? `User ${index + 1}`,\n src: element.getAttribute(\"src\") ?? undefined,\n status:\n (element.getAttribute(\"data-status\") as PresenceStatus) ?? undefined,\n element,\n index,\n };\n}\n\n/**\n * Extract all user data from child profile-picture elements\n */\nexport function extractAllUserData(container: HTMLElement): GroupUserData[] {\n const children = container.querySelectorAll(\"profile-picture\");\n return Array.from(children).map((el, index) =>\n extractUserData(el as HTMLElement, index)\n );\n}\n\n/**\n * Get initials for counter display (e.g., \"+5\")\n */\nexport function formatCounterText(count: number): string {\n if (count > 99) {\n return \"+99\";\n }\n return `+${count}`;\n}\n\n/**\n * Calculate tooltip position relative to avatar\n */\nexport function calculateTooltipPosition(\n avatarRect: DOMRect,\n tooltipWidth: number,\n tooltipHeight: number,\n position: \"top\" | \"bottom\" | \"left\" | \"right\" = \"top\",\n gap = 8\n): { top: number; left: number } {\n const { top, left, width, height } = avatarRect;\n const centerX = left + width / 2;\n const centerY = top + height / 2;\n\n switch (position) {\n case \"top\":\n return {\n top: top - tooltipHeight - gap,\n left: centerX - tooltipWidth / 2,\n };\n case \"bottom\":\n return {\n top: top + height + gap,\n left: centerX - tooltipWidth / 2,\n };\n case \"left\":\n return {\n top: centerY - tooltipHeight / 2,\n left: left - tooltipWidth - gap,\n };\n case \"right\":\n return {\n top: centerY - tooltipHeight / 2,\n left: left + width + gap,\n };\n }\n}\n\n/**\n * Clamp tooltip position within viewport\n */\nexport function clampTooltipPosition(\n position: { top: number; left: number },\n tooltipWidth: number,\n tooltipHeight: number,\n padding = 8\n): { top: number; left: number } {\n const viewport = {\n width: typeof window !== \"undefined\" ? window.innerWidth : 1920,\n height: typeof window !== \"undefined\" ? window.innerHeight : 1080,\n };\n\n return {\n top: clamp(\n position.top,\n padding,\n viewport.height - tooltipHeight - padding\n ),\n left: clamp(\n position.left,\n padding,\n viewport.width - tooltipWidth - padding\n ),\n };\n}\n\n/**\n * Get CDN size label from pixel size (rounds up to next available size)\n * CDN sizes: 80, 120, 240, 480, 960\n */\nexport function getCdnSizeLabel(\n pixelSize: number\n): \"80\" | \"120\" | \"240\" | \"480\" | \"960\" {\n if (pixelSize <= 80) {\n return \"120\";\n }\n if (pixelSize <= 120) {\n return \"240\";\n }\n if (pixelSize <= 240) {\n return \"480\";\n }\n if (pixelSize <= 480) {\n return \"960\";\n }\n return \"960\";\n}\n\n/**\n * Construct CDN URL for profile picture\n * Format: {baseUrl}/api/profile-picture/cdn/{extId}_{size}_{imageMode}.webp?hostname={hostname}\n * @param imageMode - \"transparent\" for transparent background, \"original\" for original background\n */\nexport function constructCdnUrl(\n baseUrl: string,\n extCustomerId: string,\n sizeLabel: \"80\" | \"120\" | \"240\" | \"480\" | \"960\",\n imageMode: \"transparent\" | \"original\",\n hostname: string\n): string {\n // Remove trailing slash from baseUrl\n const cleanBaseUrl = baseUrl.endsWith(\"/\") ? baseUrl.slice(0, -1) : baseUrl;\n\n // Construct filename: {extId}_{size}_{imageMode}.webp\n const filename = `${extCustomerId}_${sizeLabel}_${imageMode}.webp`;\n\n // Construct full URL with hostname query parameter\n return `${cleanBaseUrl}/api/profile-picture/cdn/${filename}?hostname=${hostname}`;\n}\n","/**\n * Profile Picture Component - Styles & Animations\n * Apple-inspired design system with modern 2025 aesthetics\n */\n\nimport type { ShadowPreset, Variant } from \"./types\";\nimport { RADIUS_MAP, SHADOW_MAP } from \"./types\";\nimport { isHexColor } from \"./utils\";\n\n/**\n * Get variant-specific border radius styles\n */\nexport function getVariantStyles(variant: Variant): Record<string, string> {\n return { borderRadius: RADIUS_MAP[variant] };\n}\n\n/**\n * Get variant classes (Tailwind)\n */\nexport function getVariantClasses(variant: Variant): string {\n const variants: Record<Variant, string> = {\n circle: \"np:rounded-full\",\n rounded: \"np:rounded-xl\",\n squircle: \"np:rounded-[30%]\",\n square: \"np:rounded-none\",\n };\n return variants[variant];\n}\n\n/**\n * Get border styles\n */\nexport function getBorderClasses(\n width: 1 | 2 | 3 | 4 | 5 | 6 | 8,\n color: string\n): { className: string; style: Record<string, string> } {\n const widthClasses: Record<1 | 2 | 3 | 4 | 5 | 6 | 8, string> = {\n 1: \"np:border\",\n 2: \"np:border-2\",\n 3: \"np:border-[3px]\",\n 4: \"np:border-4\",\n 5: \"np:border-[5px]\",\n 6: \"np:border-[6px]\",\n 8: \"np:border-8\",\n };\n\n return {\n className: widthClasses[width],\n style: {\n borderColor: color,\n borderStyle: \"solid\",\n },\n };\n}\n\n/**\n * Get background styles (solid color or gradient)\n */\nexport function getBackgroundStyles(\n bgColor?: string,\n bgGradient?: string\n): { className: string; style?: Record<string, string> } {\n if (bgGradient) {\n return {\n className: \"\",\n style: { background: bgGradient },\n };\n }\n\n if (bgColor) {\n if (bgColor.includes(\"gradient\")) {\n return {\n className: \"\",\n style: { background: bgColor },\n };\n }\n return {\n className: \"\",\n style: { backgroundColor: bgColor },\n };\n }\n\n return { className: \"\", style: { backgroundColor: \"transparent\" } };\n}\n\n/**\n * Get shadow styles\n */\nexport function getShadowStyles(shadow: ShadowPreset): Record<string, string> {\n return { boxShadow: SHADOW_MAP[shadow] };\n}\n\n/**\n * CSS Keyframe animations - Apple-inspired, physics-based\n */\nexport const keyframes = {\n // Shimmer loading effect\n shimmer: `\n@keyframes pp-shimmer {\n 0% { transform: translateX(-100%); }\n 100% { transform: translateX(100%); }\n}`,\n\n // Pulse animation (gentle breathe effect)\n pulse: `\n@keyframes pp-pulse {\n 0%, 100% { opacity: 1; transform: scale(1); }\n 50% { opacity: 0.7; transform: scale(0.98); }\n}`,\n\n // Skeleton loading pulse\n skeleton: `\n@keyframes pp-skeleton {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n}`,\n\n // Badge bounce entrance\n badgeBounce: `\n@keyframes pp-badge-bounce {\n 0% { transform: scale(0) translateY(10px); opacity: 0; }\n 50% { transform: scale(1.2) translateY(-2px); }\n 100% { transform: scale(1) translateY(0); opacity: 1; }\n}`,\n\n // Ring rotation (for gradient rings)\n ringRotate: `\n@keyframes pp-ring-rotate {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n}`,\n\n // Presence indicator pulse\n presencePulse: `\n@keyframes pp-presence-pulse {\n 0%, 100% { box-shadow: 0 0 0 0 currentColor; }\n 50% { box-shadow: 0 0 0 4px transparent; }\n}`,\n\n // Glow animation\n glow: `\n@keyframes pp-glow {\n 0%, 100% { box-shadow: 0 0 20px 0 var(--pp-glow-color, rgba(99, 102, 241, 0.3)); }\n 50% { box-shadow: 0 0 30px 5px var(--pp-glow-color, rgba(99, 102, 241, 0.5)); }\n}`,\n\n // Fade in\n fadeIn: `\n@keyframes pp-fade-in {\n from { opacity: 0; }\n to { opacity: 1; }\n}`,\n\n // Scale in (spring-like)\n scaleIn: `\n@keyframes pp-scale-in {\n 0% { transform: scale(0.8); opacity: 0; }\n 50% { transform: scale(1.05); }\n 100% { transform: scale(1); opacity: 1; }\n}`,\n};\n\n/**\n * All keyframes combined for injection\n */\nexport const allKeyframes = Object.values(keyframes).join(\"\\n\");\n\n/**\n * Component base styles\n */\nexport const baseStyles = `\n/* Profile Picture Component Styles */\n.pp-container {\n --pp-transition-duration: 200ms;\n --pp-transition-timing: cubic-bezier(0.4, 0, 0.2, 1);\n --pp-spring-timing: cubic-bezier(0.34, 1.56, 0.64, 1);\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n user-select: none;\n -webkit-user-select: none;\n flex-shrink: 0;\n}\n\n/* Inner container for image clipping - allows badges/rings to overflow */\n/* Background is applied here (not on container) to prevent sub-pixel bleed-through */\n.pp-inner {\n position: absolute;\n inset: 0;\n overflow: hidden;\n border-radius: inherit;\n}\n\n/* Interactive states */\n.pp-interactive {\n cursor: pointer;\n transition: transform var(--pp-transition-duration) var(--pp-spring-timing),\n box-shadow var(--pp-transition-duration) var(--pp-transition-timing);\n}\n\n.pp-interactive:hover {\n transform: scale(1.05);\n}\n\n.pp-interactive:active {\n transform: scale(0.95);\n}\n\n.pp-interactive:focus-visible {\n outline: none;\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.5);\n}\n\n/* Image styles */\n.pp-image {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n object-fit: cover;\n transition: opacity var(--pp-transition-duration) var(--pp-transition-timing);\n}\n\n.pp-image-loading {\n opacity: 0;\n}\n\n.pp-image-loaded {\n opacity: 1;\n}\n\n/* Fallback styles */\n.pp-fallback {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n font-weight: 500;\n color: rgba(255, 255, 255, 0.9);\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);\n font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Segoe UI', Roboto, sans-serif;\n letter-spacing: 0.02em;\n}\n\n.pp-fallback-icon {\n color: rgba(156, 163, 175, 0.8);\n}\n\n/* Shimmer placeholder */\n.pp-shimmer {\n position: absolute;\n inset: 0;\n overflow: hidden;\n}\n\n.pp-shimmer::after {\n content: '';\n position: absolute;\n inset: 0;\n background: linear-gradient(\n 90deg,\n transparent 0%,\n rgba(255, 255, 255, 0.4) 50%,\n transparent 100%\n );\n animation: pp-shimmer 1.5s infinite;\n}\n\n/* Pulse placeholder */\n.pp-pulse {\n animation: pp-pulse 2s ease-in-out infinite;\n}\n\n/* Skeleton placeholder */\n.pp-skeleton {\n background: linear-gradient(90deg, #e5e7eb 0%, #f3f4f6 50%, #e5e7eb 100%);\n background-size: 200% 100%;\n animation: pp-skeleton 1.5s ease-in-out infinite;\n}\n\n/* Badge styles */\n.pp-badge {\n position: absolute;\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 600;\n font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', sans-serif;\n line-height: 1;\n animation: pp-badge-bounce 0.4s var(--pp-spring-timing);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);\n}\n\n.pp-badge-with-icon {\n gap: 4px;\n}\n\n.pp-badge-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n flex-shrink: 0;\n}\n\n.pp-badge-pulse {\n animation: pp-badge-bounce 0.4s var(--pp-spring-timing),\n pp-presence-pulse 2s ease-in-out infinite 0.4s;\n}\n\n.pp-badge-glow {\n box-shadow: 0 0 10px 2px var(--pp-badge-glow-color, currentColor);\n}\n\n/* Ring effect (Instagram-style) */\n.pp-ring {\n position: absolute;\n inset: -4px;\n border-radius: inherit;\n padding: 3px;\n background: var(--pp-ring-color, linear-gradient(45deg, #f09433, #e6683c, #dc2743, #cc2366, #bc1888));\n -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);\n mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);\n -webkit-mask-composite: xor;\n mask-composite: exclude;\n transition: background 0.3s ease;\n}\n\n.pp-ring-animated {\n animation: pp-ring-rotate 3s linear infinite;\n}\n\n.pp-ring-progress {\n /* Progress rings should not animate rotation */\n animation: none;\n}\n\n/* Presence indicator */\n.pp-presence {\n position: absolute;\n bottom: 0;\n right: 0;\n border-radius: 9999px;\n border: 2px solid white;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);\n}\n\n.pp-presence-animated {\n animation: pp-presence-pulse 2s ease-in-out infinite;\n}\n\n/* Glow effect */\n.pp-glow {\n animation: pp-glow 2s ease-in-out infinite;\n}\n\n/* Reduced motion support */\n@media (prefers-reduced-motion: reduce) {\n .pp-container,\n .pp-interactive,\n .pp-image,\n .pp-shimmer::after,\n .pp-pulse,\n .pp-skeleton,\n .pp-badge,\n .pp-ring-animated,\n .pp-presence-animated,\n .pp-glow {\n animation: none !important;\n transition: none !important;\n }\n}\n`;\n\n/**\n * All styles combined (keyframes + base styles)\n */\nexport const componentStyles = `${allKeyframes}\\n${baseStyles}`;\n\n/**\n * Shimmer styles for inline injection (legacy support)\n */\nexport const shimmerStyles = `\n@keyframes np-shimmer {\n 0% { background-position: -200% 0; }\n 100% { background-position: 200% 0; }\n}\n.np-shimmer {\n background: linear-gradient(90deg, transparent 0%, rgba(255,255,255,0.4) 50%, transparent 100%);\n background-size: 200% 100%;\n animation: np-shimmer 1.5s infinite;\n}\n`;\n\n/**\n * Generate glow shadow with custom color\n */\nexport function getGlowShadow(color: string, intensity = 0.3): string {\n if (isHexColor(color)) {\n // Convert hex to rgba\n const r = Number.parseInt(color.slice(1, 3), 16);\n const g = Number.parseInt(color.slice(3, 5), 16);\n const b = Number.parseInt(color.slice(5, 7), 16);\n return `0 0 20px 0 rgba(${r}, ${g}, ${b}, ${intensity})`;\n }\n return `0 0 20px 0 ${color}`;\n}\n\n/**\n * Get shimmer classes (legacy)\n */\nexport function getShimmerClasses(): string {\n return \"np-shimmer\";\n}\n\n// ─── Profile Picture Group Styles ────────────────────────────────────────────\n\n/**\n * Group component keyframe animations\n */\nexport const groupKeyframes = `\n@keyframes ppg-tooltip-in {\n from {\n opacity: 0;\n transform: translateX(-50%) translateY(4px) scale(0.96);\n }\n to {\n opacity: 1;\n transform: translateX(-50%) translateY(0) scale(1);\n }\n}\n\n@keyframes ppg-dropdown-in {\n from {\n opacity: 0;\n transform: translateY(-6px) scale(0.95);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n}\n\n@keyframes ppg-avatar-lift {\n from {\n transform: translateY(0) scale(1);\n }\n to {\n transform: translateY(-4px) scale(1.08);\n }\n}\n\n@keyframes ppg-modal-in {\n from {\n opacity: 0;\n transform: translate(-50%, -50%) scale(0.9);\n }\n to {\n opacity: 1;\n transform: translate(-50%, -50%) scale(1);\n }\n}\n\n@keyframes ppg-backdrop-in {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n`;\n\n/**\n * Group component base styles - Apple-inspired\n */\nexport const groupBaseStyles = `\n/* Profile Picture Group Container */\n.ppg-container {\n --ppg-transition: 200ms cubic-bezier(0.4, 0, 0.2, 1);\n --ppg-spring: 300ms cubic-bezier(0.34, 1.56, 0.64, 1);\n --ppg-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);\n --ppg-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.1);\n --ppg-shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.15);\n --ppg-radius: 12px;\n --ppg-counter-bg: #f5f5f7;\n --ppg-counter-text: #1d1d1f;\n --ppg-add-bg: #f5f5f7;\n --ppg-add-hover: #e8e8ed;\n --ppg-add-icon: #86868b;\n --ppg-border: rgba(0, 0, 0, 0.08);\n --ppg-tooltip-bg: rgba(29, 29, 31, 0.95);\n --ppg-tooltip-text: #ffffff;\n --ppg-dropdown-bg: #ffffff;\n --ppg-dropdown-hover: #f5f5f7;\n\n position: relative;\n display: inline-flex;\n align-items: center;\n isolation: isolate;\n}\n\n/* Avatar wrapper for positioning */\n.ppg-avatar-wrapper {\n position: absolute;\n top: 0;\n transition: transform var(--ppg-spring), z-index 0s;\n cursor: pointer;\n border-radius: 9999px;\n}\n\n.ppg-avatar-wrapper:focus-visible {\n outline: none;\n box-shadow: 0 0 0 3px rgba(0, 122, 255, 0.4);\n}\n\n/* Hover lift animation */\n.ppg-animated .ppg-avatar-wrapper:hover {\n z-index: 100 !important;\n animation: ppg-avatar-lift var(--ppg-spring) forwards;\n}\n\n.ppg-avatar-wrapper:hover {\n z-index: 100 !important;\n}\n\n/* Nested profile-picture styling */\n.ppg-avatar-wrapper profile-picture {\n display: block;\n width: 100%;\n height: 100%;\n border-radius: inherit;\n}\n\n/* Counter button */\n.ppg-counter {\n position: absolute;\n top: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 9999px;\n background: var(--ppg-counter-bg);\n color: var(--ppg-counter-text);\n font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Display', sans-serif;\n font-weight: 600;\n font-size: 13px;\n letter-spacing: -0.01em;\n cursor: pointer;\n border: none;\n box-shadow: 0 0 0 1.5px rgba(255, 255, 255, 0.95), var(--ppg-shadow-sm);\n transition: transform var(--ppg-spring), background-color var(--ppg-transition);\n user-select: none;\n -webkit-user-select: none;\n}\n\n.ppg-counter:hover {\n background: #ebebed;\n transform: scale(1.05);\n}\n\n.ppg-counter:active {\n transform: scale(0.98);\n}\n\n.ppg-counter:focus-visible {\n outline: none;\n box-shadow: 0 0 0 1.5px rgba(255, 255, 255, 0.95), 0 0 0 4px rgba(0, 122, 255, 0.4);\n}\n\n/* Add button */\n.ppg-add-button {\n position: absolute;\n top: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 9999px;\n background: var(--ppg-add-bg);\n border: 2px dashed var(--ppg-border);\n cursor: pointer;\n transition: all var(--ppg-spring);\n box-shadow: var(--ppg-shadow-sm);\n}\n\n.ppg-add-button:hover {\n background: var(--ppg-add-hover);\n border-color: rgba(0, 0, 0, 0.15);\n transform: scale(1.05);\n}\n\n.ppg-add-button:active {\n transform: scale(0.98);\n}\n\n.ppg-add-button:focus-visible {\n outline: none;\n box-shadow: 0 0 0 3px rgba(0, 122, 255, 0.4);\n}\n\n.ppg-add-icon {\n color: var(--ppg-add-icon);\n transition: color var(--ppg-transition);\n}\n\n.ppg-add-button:hover .ppg-add-icon {\n color: #1d1d1f;\n}\n\n/* Tooltip */\n.ppg-tooltip {\n position: absolute;\n z-index: 9999;\n padding: 6px 12px;\n background: var(--ppg-tooltip-bg);\n color: var(--ppg-tooltip-text);\n font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', sans-serif;\n font-size: 13px;\n font-weight: 500;\n border-radius: 8px;\n box-shadow: var(--ppg-shadow-lg);\n pointer-events: none;\n white-space: nowrap;\n transform: translateX(-50%);\n animation: ppg-tooltip-in 150ms ease-out forwards;\n backdrop-filter: blur(20px);\n -webkit-backdrop-filter: blur(20px);\n}\n\n.ppg-tooltip::after {\n content: '';\n position: absolute;\n width: 8px;\n height: 8px;\n background: inherit;\n transform: rotate(45deg);\n}\n\n.ppg-tooltip[data-position=\"top\"]::after {\n bottom: -4px;\n left: 50%;\n margin-left: -4px;\n}\n\n.ppg-tooltip[data-position=\"bottom\"]::after {\n top: -4px;\n left: 50%;\n margin-left: -4px;\n}\n\n/* Dropdown */\n.ppg-dropdown {\n position: absolute;\n z-index: 9998;\n right: 0;\n min-width: 220px;\n max-width: 300px;\n background: var(--ppg-dropdown-bg);\n border-radius: 14px;\n box-shadow:\n 0 4px 24px rgba(0, 0, 0, 0.12),\n 0 1px 4px rgba(0, 0, 0, 0.08),\n 0 0 0 1px var(--ppg-border);\n overflow: hidden;\n animation: ppg-dropdown-in 200ms cubic-bezier(0.32, 0.72, 0, 1) forwards;\n transform-origin: top right;\n backdrop-filter: blur(20px);\n -webkit-backdrop-filter: blur(20px);\n}\n\n.ppg-dropdown[data-position=\"bottom\"] {\n top: calc(100% + 10px);\n}\n\n.ppg-dropdown[data-position=\"top\"] {\n bottom: calc(100% + 10px);\n transform-origin: bottom right;\n}\n\n/* Modal style for mobile */\n.ppg-dropdown[data-position=\"modal\"] {\n transform-origin: center center;\n animation: ppg-modal-in 250ms cubic-bezier(0.32, 0.72, 0, 1) forwards;\n border-radius: 20px;\n}\n\n.ppg-backdrop-visible {\n background: rgba(0, 0, 0, 0.4);\n animation: ppg-backdrop-in 200ms ease-out forwards;\n}\n\n.ppg-dropdown-header {\n padding: 14px 16px 10px;\n font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;\n font-size: 11px;\n font-weight: 600;\n color: #86868b;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n background: linear-gradient(to bottom, rgba(0,0,0,0.02), transparent);\n}\n\n.ppg-dropdown-list {\n overflow-y: auto;\n padding: 6px;\n scrollbar-width: thin;\n scrollbar-color: rgba(0,0,0,0.2) transparent;\n}\n\n.ppg-dropdown-list::-webkit-scrollbar {\n width: 6px;\n}\n\n.ppg-dropdown-list::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.ppg-dropdown-list::-webkit-scrollbar-thumb {\n background: rgba(0,0,0,0.15);\n border-radius: 3px;\n}\n\n.ppg-dropdown-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n cursor: pointer;\n border-radius: 10px;\n transition: all 150ms ease;\n margin: 2px 0;\n}\n\n.ppg-dropdown-item:hover {\n background: var(--ppg-dropdown-hover);\n transform: translateX(2px);\n}\n\n.ppg-dropdown-item:focus-visible {\n outline: none;\n background: var(--ppg-dropdown-hover);\n box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.4);\n}\n\n.ppg-dropdown-item:active {\n transform: scale(0.98);\n}\n\n.ppg-dropdown-avatar {\n flex-shrink: 0;\n width: 36px;\n height: 36px;\n border-radius: 9999px;\n object-fit: cover;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n border: 2px solid rgba(255, 255, 255, 0.8);\n}\n\n.ppg-dropdown-avatar-fallback {\n flex-shrink: 0;\n width: 36px;\n height: 36px;\n border-radius: 9999px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Display', system-ui, sans-serif;\n font-size: 13px;\n font-weight: 600;\n color: white;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n border: 2px solid rgba(255, 255, 255, 0.3);\n}\n\n.ppg-dropdown-info {\n flex: 1;\n min-width: 0;\n padding-right: 4px;\n text-align: left;\n}\n\n.ppg-dropdown-name {\n font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;\n font-size: 14px;\n font-weight: 500;\n color: #1d1d1f;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n line-height: 1.3;\n text-align: left;\n}\n\n.ppg-dropdown-status {\n display: flex;\n align-items: center;\n gap: 5px;\n font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;\n font-size: 12px;\n color: #86868b;\n margin-top: 2px;\n line-height: 1.2;\n}\n\n.ppg-dropdown-presence {\n width: 7px;\n height: 7px;\n border-radius: 9999px;\n flex-shrink: 0;\n box-shadow: 0 0 0 1.5px var(--ppg-dropdown-bg);\n}\n\n.ppg-dropdown-presence[data-status=\"online\"] {\n background: #30D158;\n box-shadow: 0 0 0 1.5px var(--ppg-dropdown-bg), 0 0 6px rgba(48, 209, 88, 0.5);\n}\n\n.ppg-dropdown-presence[data-status=\"away\"] {\n background: #FFD60A;\n}\n\n.ppg-dropdown-presence[data-status=\"busy\"],\n.ppg-dropdown-presence[data-status=\"dnd\"] {\n background: #FF453A;\n}\n\n.ppg-dropdown-presence[data-status=\"offline\"] {\n background: #8E8E93;\n}\n\n/* Backdrop for dropdown */\n.ppg-backdrop {\n position: fixed;\n inset: 0;\n z-index: 9997;\n}\n\n/* Reduced motion */\n@media (prefers-reduced-motion: reduce) {\n .ppg-container,\n .ppg-avatar-wrapper,\n .ppg-counter,\n .ppg-add-button,\n .ppg-tooltip,\n .ppg-dropdown {\n animation: none !important;\n transition: none !important;\n }\n\n .ppg-animated .ppg-avatar-wrapper:hover {\n animation: none !important;\n transform: none !important;\n }\n}\n\n/* Dark mode support */\n@media (prefers-color-scheme: dark) {\n .ppg-container {\n --ppg-counter-bg: #2c2c2e;\n --ppg-counter-text: #ffffff;\n --ppg-add-bg: #2c2c2e;\n --ppg-add-hover: #3a3a3c;\n --ppg-add-icon: #98989d;\n --ppg-border: rgba(255, 255, 255, 0.1);\n --ppg-dropdown-bg: #2c2c2e;\n --ppg-dropdown-hover: #3a3a3c;\n }\n\n .ppg-avatar-wrapper profile-picture {\n box-shadow: 0 0 6px 1.5px rgb(28 28 30 / 16%), var(--ppg-shadow-sm);\n }\n\n .ppg-counter {\n box-shadow: 0 0 0 1.5px rgba(28, 28, 30, 0.95), var(--ppg-shadow-sm);\n }\n\n .ppg-counter:hover {\n background: #3a3a3c;\n }\n\n .ppg-dropdown {\n background: rgba(44, 44, 46, 0.95);\n box-shadow:\n 0 4px 24px rgba(0, 0, 0, 0.4),\n 0 1px 4px rgba(0, 0, 0, 0.2),\n 0 0 0 1px rgba(255, 255, 255, 0.08);\n }\n\n .ppg-dropdown-name {\n color: #ffffff;\n }\n\n .ppg-dropdown-header {\n color: #98989d;\n background: linear-gradient(to bottom, rgba(255,255,255,0.03), transparent);\n }\n\n .ppg-dropdown-avatar {\n border-color: rgba(255, 255, 255, 0.15);\n }\n\n .ppg-dropdown-avatar-fallback {\n border-color: rgba(255, 255, 255, 0.1);\n }\n\n .ppg-dropdown-list {\n scrollbar-color: rgba(255,255,255,0.35) transparent;\n }\n\n .ppg-dropdown-list::-webkit-scrollbar-thumb {\n background: rgba(255,255,255,0.35);\n }\n\n .ppg-dropdown-presence {\n box-shadow: 0 0 0 1.5px rgba(44, 44, 46, 0.95);\n }\n\n .ppg-dropdown-presence[data-status=\"online\"] {\n box-shadow: 0 0 0 1.5px rgba(44, 44, 46, 0.95), 0 0 6px rgba(48, 209, 88, 0.5);\n }\n}\n`;\n\n/**\n * All group styles combined\n */\nexport const groupStyles = `${groupKeyframes}\\n${groupBaseStyles}`;\n","/**\n * ProfilePicture Web Component\n * Apple-inspired design system with modern 2025 aesthetics\n *\n * A lightweight, framework-agnostic profile picture component\n * with advanced features: presence indicators, rings, and badges.\n */\n\nimport { html, LitElement, nothing } from \"lit\";\nimport { property, state } from \"lit/decorators.js\";\nimport { styleMap } from \"lit/directives/style-map.js\";\nimport {\n componentStyles,\n getBackgroundStyles,\n getBorderClasses,\n getGlowShadow,\n getShadowStyles,\n getVariantClasses,\n shimmerStyles,\n} from \"./styles\";\nimport type {\n BadgeConfig,\n GlowConfig,\n InteractionConfig,\n LoadingStrategy,\n PlaceholderType,\n Position,\n PresenceConfig,\n RingConfig,\n ShadowPreset,\n Size,\n Variant,\n} from \"./types\";\nimport { DEFAULTS, PRESENCE_COLORS, RADIUS_MAP, SIZE_MAP } from \"./types\";\nimport {\n cn,\n constructCdnUrl,\n createConicGradient,\n createProgressRingGradient,\n formatBadgeContent,\n generateAvatarGradient,\n generateCloudyGradient,\n getBadgeSize,\n getCdnSizeLabel,\n getInitials,\n getInitialsFontSize,\n getPresenceSize,\n} from \"./utils\";\n\nexport class ProfilePicture extends LitElement {\n private static stylesInjected = false;\n private static cdnBaseUrl = \"\";\n private static instances = new Set<ProfilePicture>();\n\n /**\n * Set global CDN base URL for all ProfilePicture instances\n * @example ProfilePicture.setCdnBaseUrl('https://api.example.com')\n */\n public static setCdnBaseUrl(url: string): void {\n ProfilePicture.cdnBaseUrl = url;\n // Notify all existing instances to reload if they have extCustomerId\n ProfilePicture.instances.forEach((instance) => {\n if (instance.extCustomerId && !instance.cdnImageUrl) {\n // Reset failure state (CDN base URL change = legitimate retry)\n instance.cdnLoadFailed = false;\n // Clear any scheduled retry\n if (instance.retryTimeoutId) {\n clearTimeout(instance.retryTimeoutId);\n instance.retryTimeoutId = undefined;\n }\n if (!instance.previousExtCustomerId) {\n instance.previousExtCustomerId = instance.extCustomerId;\n }\n instance.loadCdnImage();\n }\n });\n }\n\n /**\n * Get current CDN base URL\n */\n public static getCdnBaseUrl(): string {\n return ProfilePicture.cdnBaseUrl;\n }\n\n // Use Light DOM for Tailwind compatibility\n protected createRenderRoot() {\n ProfilePicture.injectStylesOnce();\n return this;\n }\n\n private static injectStylesOnce() {\n if (ProfilePicture.stylesInjected || typeof document === \"undefined\") {\n return;\n }\n\n // Defer style injection to avoid hydration mismatch in SSR frameworks\n const defer =\n typeof requestIdleCallback !== \"undefined\"\n ? requestIdleCallback\n : (cb: () => void) => setTimeout(cb, 1);\n\n defer(() => {\n // Re-check in case another instance already injected\n if (ProfilePicture.stylesInjected) {\n return;\n }\n const style = document.createElement(\"style\");\n style.textContent = componentStyles;\n document.head.appendChild(style);\n ProfilePicture.stylesInjected = true;\n });\n }\n\n // ─── Core Properties ────────────────────────────────────────────────────────\n @property({ type: String }) src = \"\";\n @property({ type: String }) alt = \"\";\n @property({ type: String, attribute: \"ext-customer-id\" })\n extCustomerId?: string;\n\n // ─── Sizing ─────────────────────────────────────────────────────────────────\n @property({ type: String }) size: Size | string = DEFAULTS.size;\n\n // ─── Visual Variant ─────────────────────────────────────────────────────────\n @property({ type: String }) variant: Variant = DEFAULTS.variant;\n\n // ─── Shadow ─────────────────────────────────────────────────────────────────\n @property({ type: String }) shadow: ShadowPreset = DEFAULTS.shadow;\n\n // ─── Border ─────────────────────────────────────────────────────────────────\n @property({ type: Boolean }) border = false;\n @property({ type: Number, attribute: \"border-width\" }) borderWidth:\n | 1\n | 2\n | 3\n | 4\n | 5\n | 6\n | 8 = DEFAULTS.borderWidth;\n @property({ type: String, attribute: \"border-color\" }) borderColor: string =\n DEFAULTS.borderColor;\n\n // ─── Rotation ───────────────────────────────────────────────────────────────\n @property({ type: Number }) rotation = 0;\n\n // ─── Zoom ─────────────────────────────────────────────────────────────────\n @property({ type: Number }) zoom: number = DEFAULTS.zoom;\n\n // ─── Background ─────────────────────────────────────────────────────────────\n @property({ type: String, attribute: \"bg-color\" }) bgColor?: string;\n @property({ type: String, attribute: \"bg-gradient\" }) bgGradient?: string;\n\n // ─── Ring Effect (Instagram-style) ──────────────────────────────────────────\n @property({\n type: Object,\n attribute: \"ring\",\n converter: {\n fromAttribute: (value: string | null): RingConfig | undefined => {\n if (!value) return undefined;\n try {\n return JSON.parse(value) as RingConfig;\n } catch {\n return undefined;\n }\n },\n toAttribute: (value: RingConfig | undefined): string | null => {\n return value ? JSON.stringify(value) : null;\n },\n },\n })\n ring?: RingConfig;\n\n // ─── Presence Indicator ─────────────────────────────────────────────────────\n @property({\n type: Object,\n attribute: \"presence\",\n converter: {\n fromAttribute: (value: string | null): PresenceConfig | undefined => {\n if (!value) return undefined;\n try {\n return JSON.parse(value) as PresenceConfig;\n } catch {\n return undefined;\n }\n },\n toAttribute: (value: PresenceConfig | undefined): string | null => {\n return value ? JSON.stringify(value) : null;\n },\n },\n })\n presence?: PresenceConfig;\n\n // ─── Glow Effect ────────────────────────────────────────────────────────────\n @property({\n type: Object,\n attribute: \"glow\",\n converter: {\n fromAttribute: (value: string | null): GlowConfig | undefined => {\n if (!value) return undefined;\n try {\n return JSON.parse(value) as GlowConfig;\n } catch {\n return undefined;\n }\n },\n toAttribute: (value: GlowConfig | undefined): string | null => {\n return value ? JSON.stringify(value) : null;\n },\n },\n })\n glow?: GlowConfig;\n\n // ─── Badge ──────────────────────────────────────────────────────────────────\n @property({\n type: Object,\n attribute: \"badge\",\n converter: {\n fromAttribute: (value: string | null): BadgeConfig | undefined => {\n if (!value) return undefined;\n try {\n return JSON.parse(value) as BadgeConfig;\n } catch {\n return undefined;\n }\n },\n toAttribute: (value: BadgeConfig | undefined): string | null => {\n return value ? JSON.stringify(value) : null;\n },\n },\n })\n badge?: BadgeConfig;\n\n // ─── Loading & Performance ──────────────────────────────────────────────────\n @property({ type: String }) loading: LoadingStrategy = DEFAULTS.loading;\n @property({ type: String }) placeholder: PlaceholderType =\n DEFAULTS.placeholder;\n @property({ type: String, attribute: \"placeholder-color\" })\n placeholderColor: string = DEFAULTS.placeholderColor;\n\n // ─── Fallback ───────────────────────────────────────────────────────────────\n @property({ type: String }) fallback?: string;\n\n // ─── Fallback Mode ────────────────────────────────────────────────────────\n @property({ type: String, attribute: \"fallback-mode\" })\n fallbackMode?: \"initials\" | \"gradient\";\n\n // ─── Image Mode ────────────────────────────────────────────────────────────\n @property({ type: String, attribute: \"image-mode\" })\n imageMode: \"transparent\" | \"original\" = \"original\";\n\n // ─── Interaction ────────────────────────────────────────────────────────────\n @property({\n type: Object,\n attribute: \"interactive\",\n converter: {\n fromAttribute: (value: string | null): InteractionConfig | undefined => {\n if (!value) return undefined;\n try {\n return JSON.parse(value) as InteractionConfig;\n } catch {\n return undefined;\n }\n },\n toAttribute: (value: InteractionConfig | undefined): string | null => {\n return value ? JSON.stringify(value) : null;\n },\n },\n })\n interactive?: InteractionConfig;\n\n // ─── Internal State ─────────────────────────────────────────────────────────\n @state() private isLoaded = false;\n @state() private hasError = false;\n @state() private cdnImageUrl?: string;\n @state() private cdnLoadFailed = false;\n private previousSrc = \"\";\n private previousExtCustomerId?: string;\n private retryTimeoutId?: ReturnType<typeof setTimeout>;\n private randomSeed = Math.random().toString(36).slice(2);\n private readonly RETRY_DELAY_MS = 30_000; // 30 seconds\n\n /**\n * Safely resolve an object property that may be a JSON string\n * (e.g., when React 19 sets it as a property instead of attribute,\n * bypassing Lit's fromAttribute converter).\n */\n private resolveObjectProp<T>(value: T | string | undefined): T | undefined {\n if (!value) return undefined;\n if (typeof value === \"string\") {\n try {\n return JSON.parse(value) as T;\n } catch {\n return undefined;\n }\n }\n return value;\n }\n\n private get pixelSize(): number {\n const sizeValue = this.size as Size | number;\n return typeof sizeValue === \"number\"\n ? sizeValue\n : (SIZE_MAP[sizeValue as Size] ?? SIZE_MAP[DEFAULTS.size]);\n }\n\n /**\n * Resolve the seed for cloudy gradient from available identifiers.\n * Priority: extCustomerId > alt > src > random instance seed\n */\n private get gradientSeed(): string {\n return this.extCustomerId || this.alt || this.src || this.randomSeed;\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n // Register this instance\n ProfilePicture.instances.add(this);\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n // Unregister this instance\n ProfilePicture.instances.delete(this);\n // Clear any scheduled retry\n if (this.retryTimeoutId) {\n clearTimeout(this.retryTimeoutId);\n this.retryTimeoutId = undefined;\n }\n }\n\n protected firstUpdated(): void {\n // Trigger CDN loading on initial render if extCustomerId is present\n if (this.extCustomerId && ProfilePicture.cdnBaseUrl) {\n this.previousExtCustomerId = this.extCustomerId;\n this.loadCdnImage();\n }\n }\n\n protected updated(changedProperties: Map<string, unknown>): void {\n super.updated(changedProperties);\n // Handle: CDN base URL set AFTER element creation\n // (previousExtCustomerId is only set when firstUpdated or willUpdate triggers a CDN load)\n if (\n this.extCustomerId &&\n ProfilePicture.cdnBaseUrl &&\n !this.cdnImageUrl &&\n !this.previousExtCustomerId\n ) {\n this.previousExtCustomerId = this.extCustomerId;\n this.cdnLoadFailed = false;\n this.loadCdnImage();\n }\n }\n\n protected willUpdate(changedProperties: Map<string, unknown>): void {\n if (changedProperties.has(\"src\") && this.src !== this.previousSrc) {\n this.isLoaded = false;\n this.hasError = false;\n this.previousSrc = this.src;\n }\n\n // Trigger CDN loading when relevant properties change\n const extCustomerIdChanged =\n changedProperties.has(\"extCustomerId\") &&\n this.extCustomerId !== this.previousExtCustomerId;\n const cdnParamsChanged =\n changedProperties.has(\"size\") || changedProperties.has(\"imageMode\");\n\n if (extCustomerIdChanged || (cdnParamsChanged && this.extCustomerId)) {\n this.previousExtCustomerId = this.extCustomerId;\n // Reset CDN state (property change = legitimate reload)\n this.cdnImageUrl = undefined;\n this.cdnLoadFailed = false;\n this.isLoaded = false;\n this.hasError = false;\n // Clear any scheduled retry\n if (this.retryTimeoutId) {\n clearTimeout(this.retryTimeoutId);\n this.retryTimeoutId = undefined;\n }\n // Start CDN loading\n this.loadCdnImage();\n }\n }\n\n private handleLoad() {\n this.isLoaded = true;\n this.dispatchEvent(\n new CustomEvent(\"load\", { bubbles: true, composed: true })\n );\n }\n\n private handleClick(event: MouseEvent) {\n const interactive = this.resolveObjectProp<InteractionConfig>(this.interactive);\n if (!interactive?.pressable) return;\n this.dispatchEvent(\n new CustomEvent(\"profile-picture-click\", {\n bubbles: true,\n composed: true,\n detail: {\n extCustomerId: this.extCustomerId,\n alt: this.alt,\n src: this.src,\n },\n })\n );\n }\n\n private handleKeyDown(event: KeyboardEvent) {\n const interactive = this.resolveObjectProp<InteractionConfig>(this.interactive);\n if (!interactive?.pressable) return;\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n this.handleClick(event as unknown as MouseEvent);\n }\n }\n\n private handleError() {\n // If CDN image failed, mark it and schedule retry\n if (this.cdnImageUrl && !this.cdnLoadFailed) {\n this.cdnLoadFailed = true;\n this.cdnImageUrl = undefined;\n\n // Dispatch CDN error event\n this.dispatchEvent(\n new CustomEvent(\"cdn-error\", {\n bubbles: true,\n composed: true,\n detail: { error: \"Image load failed\" },\n })\n );\n\n // Schedule a retry after delay\n if (this.retryTimeoutId) {\n clearTimeout(this.retryTimeoutId);\n }\n this.retryTimeoutId = setTimeout(() => {\n this.retryTimeoutId = undefined;\n if (this.extCustomerId && ProfilePicture.cdnBaseUrl) {\n this.cdnLoadFailed = false;\n this.hasError = false;\n this.isLoaded = false;\n this.loadCdnImage();\n }\n }, this.RETRY_DELAY_MS);\n\n // Don't mark hasError yet - fallback (src prop) may work\n return;\n }\n\n this.hasError = true;\n this.isLoaded = true;\n this.dispatchEvent(\n new CustomEvent(\"error\", { bubbles: true, composed: true })\n );\n }\n\n /**\n * Construct CDN URL for profile picture using ext-customer-id\n * Uses direct image src binding - browser handles redirects automatically\n */\n private loadCdnImage(): void {\n // Skip if no extCustomerId or no CDN base URL configured\n if (!(this.extCustomerId && ProfilePicture.cdnBaseUrl)) {\n this.cdnLoadFailed = true;\n return;\n }\n\n // Calculate CDN parameters\n const sizeLabel = getCdnSizeLabel(this.pixelSize);\n const hostname =\n typeof window !== \"undefined\" ? window.location.hostname : \"localhost\";\n\n // Set the CDN URL directly - browser will handle redirects via img src\n this.cdnImageUrl = constructCdnUrl(\n ProfilePicture.cdnBaseUrl,\n this.extCustomerId,\n sizeLabel,\n this.imageMode,\n hostname\n );\n }\n\n private getContainerStyles() {\n const bg = getBackgroundStyles(this.bgColor, this.bgGradient);\n const borderStyles = this.border\n ? getBorderClasses(this.borderWidth, this.borderColor)\n : null;\n const shadowStyles = getShadowStyles(this.shadow);\n\n // Handle glow effect\n const glow = this.resolveObjectProp<GlowConfig>(this.glow);\n let glowStyles: Record<string, string> = {};\n if (glow) {\n const glowColor = glow.color ?? this.borderColor ?? \"#6366f1\";\n glowStyles = {\n \"--pp-glow-color\": glowColor,\n boxShadow: getGlowShadow(glowColor, glow.intensity ?? 0.3),\n };\n }\n\n const interactive = this.resolveObjectProp<InteractionConfig>(this.interactive);\n const isInteractive =\n interactive?.hoverable || interactive?.pressable;\n\n return {\n classes: cn(\n \"pp-container\",\n getVariantClasses(this.variant),\n borderStyles?.className,\n isInteractive && \"pp-interactive\",\n glow?.animate && \"pp-glow\"\n ),\n styles: {\n width: `${this.pixelSize}px`,\n height: `${this.pixelSize}px`,\n borderRadius: RADIUS_MAP[this.variant],\n ...borderStyles?.style,\n ...shadowStyles,\n ...glowStyles,\n cursor:\n interactive?.cursor ?? (isInteractive ? \"pointer\" : \"default\"),\n transform: this.rotation ? `rotate(${this.rotation}deg)` : undefined,\n },\n // Background styles moved to .pp-inner to prevent sub-pixel bleed-through\n innerStyles: bg.style ?? {},\n innerClasses: bg.className,\n };\n }\n\n private renderPlaceholder() {\n if (this.isLoaded || this.placeholder === \"none\") {\n return nothing;\n }\n\n const placeholderClass = {\n shimmer: \"pp-shimmer\",\n pulse: \"pp-pulse\",\n skeleton: \"pp-skeleton\",\n blur: \"\",\n none: \"\",\n }[this.placeholder];\n\n return html`\n ${this.placeholder === \"shimmer\" ? html`<style>${shimmerStyles}</style>` : nothing}\n <div\n class=${cn(\"np:absolute np:inset-0\", placeholderClass)}\n style=${styleMap({\n backgroundColor: this.placeholderColor,\n borderRadius: \"inherit\",\n })}>\n </div>\n `;\n }\n\n private renderFallback() {\n // Check if an explicit background is set (bg-color or bg-gradient)\n // When set, the fallback should be transparent so .pp-inner's background shows through\n const hasExplicitBg = Boolean(this.bgColor || this.bgGradient);\n\n // Gradient mode: show cloudy gradient, no text\n if (this.fallbackMode === \"gradient\") {\n const gradient = generateCloudyGradient(this.gradientSeed);\n return html`\n <div\n class=\"pp-fallback np:absolute np:inset-0\"\n style=${styleMap({\n background: hasExplicitBg ? \"transparent\" : gradient,\n })}>\n </div>\n `;\n }\n\n // Use custom fallback text if provided\n if (this.fallback) {\n return html`\n <span\n class=\"pp-fallback\"\n style=${styleMap({ fontSize: `${getInitialsFontSize(this.pixelSize)}px` })}>\n ${this.fallback}\n </span>\n `;\n }\n\n // Generate initials from alt text\n if (this.alt) {\n const gradient = generateAvatarGradient(this.alt);\n return html`\n <div\n class=\"pp-fallback np:absolute np:inset-0\"\n style=${styleMap({\n background: hasExplicitBg ? \"transparent\" : gradient,\n fontSize: `${getInitialsFontSize(this.pixelSize)}px`,\n })}>\n ${getInitials(this.alt)}\n </div>\n `;\n }\n\n // Default user icon\n const iconSize = this.pixelSize * 0.5;\n return html`\n <svg\n class=\"pp-fallback-icon\"\n style=\"width: ${iconSize}px; height: ${iconSize}px;\"\n fill=\"currentColor\"\n viewBox=\"0 0 24 24\">\n <path d=\"M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z\" />\n </svg>\n `;\n }\n\n private renderImage() {\n // Determine image source with CDN priority:\n // 1. CDN URL (browser handles redirects automatically via img src)\n // 2. src prop (if CDN not configured or failed)\n // 3. Fallback component\n const hasCdnConfig = Boolean(\n this.extCustomerId && ProfilePicture.cdnBaseUrl\n );\n\n let imageSrc: string | undefined;\n if (this.cdnImageUrl) {\n // CDN URL set - browser will handle redirects\n imageSrc = this.cdnImageUrl;\n } else if (!hasCdnConfig || this.cdnLoadFailed) {\n // CDN not configured or failed - use src prop\n imageSrc = this.src;\n }\n\n // No image source available - show fallback\n if (this.hasError || !imageSrc) {\n return this.renderFallback();\n }\n\n const zoomStyle = this.zoom && this.zoom !== 1\n ? styleMap({ transform: `scale(${this.zoom})` })\n : nothing;\n\n return html`\n <img\n src=${imageSrc}\n alt=${this.alt}\n loading=${this.loading}\n decoding=\"async\"\n @load=${this.handleLoad}\n @error=${this.handleError}\n class=${cn(\"pp-image\", this.isLoaded ? \"pp-image-loaded\" : \"pp-image-loading\")}\n style=${zoomStyle}\n draggable=\"false\" />\n `;\n }\n\n private renderRing() {\n const ring = this.resolveObjectProp<RingConfig>(this.ring);\n if (!ring?.show) {\n return nothing;\n }\n\n const ringWidth = ring.width ?? 3;\n const ringGap = ring.gap ?? 3;\n const totalOffset = ringWidth + ringGap;\n\n let ringColor: string;\n const hasProgress = ring.progress !== undefined;\n\n if (hasProgress) {\n // Progress mode: partial fill ring\n const progress = ring.progress ?? 0;\n const filledColor = ring.color ?? \"#30D158\"; // Default green\n const emptyColor = ring.emptyColor ?? \"#8E8E93\"; // Default gray\n ringColor = createProgressRingGradient(progress, filledColor, emptyColor);\n } else if (ring.gradient && ring.gradient.length > 0) {\n // Multi-color gradient mode\n ringColor = createConicGradient(ring.gradient);\n } else {\n // Single color or default gradient\n ringColor =\n ring.color ??\n \"linear-gradient(45deg, #f09433, #e6683c, #dc2743, #cc2366, #bc1888)\";\n }\n\n return html`\n <div\n class=${cn(\n \"pp-ring\",\n ring.animate && !hasProgress && \"pp-ring-animated\",\n hasProgress && \"pp-ring-progress\"\n )}\n style=${styleMap({\n inset: `-${totalOffset}px`,\n padding: `${ringWidth}px`,\n background: ringColor,\n borderRadius: RADIUS_MAP[this.variant],\n })}>\n </div>\n `;\n }\n\n /**\n * Calculate the distance from the container edge to the avatar's visual corner point.\n * For a circle, this is the 45° point on the circumference.\n * Returns the inset in pixels where an indicator's CENTER should be placed.\n */\n private getCornerOffset(): number {\n const radius = this.pixelSize / 2;\n\n // For a circle, the 45° point from center is at (r*cos45, r*sin45)\n // Distance from container edge = r - r*cos(45°) = r * (1 - √2/2) ≈ r * 0.1464\n const variantInsetRatio: Record<Variant, number> = {\n circle: 1 - Math.SQRT2 / 2, // ~0.1464\n square: 0.0,\n rounded: 0.04,\n squircle: 0.08,\n };\n\n const ratio = variantInsetRatio[this.variant];\n return radius * ratio;\n }\n\n private renderPresence() {\n const presence = this.resolveObjectProp<PresenceConfig>(this.presence);\n if (!presence) {\n return nothing;\n }\n\n const thickness = presence.thickness ?? 2;\n const size = getPresenceSize(this.pixelSize, thickness);\n const color = PRESENCE_COLORS[presence.status];\n\n // Center the indicator on the avatar's corner point\n const cornerInset = this.getCornerOffset();\n const offset = cornerInset - size / 2;\n\n return html`\n <div\n class=${cn(\"pp-presence\", presence.animate && \"pp-presence-animated\")}\n style=${styleMap({\n width: `${size}px`,\n height: `${size}px`,\n backgroundColor: color,\n bottom: `${offset}px`,\n right: `${offset}px`,\n color,\n })}\n title=${presence.status}>\n </div>\n `;\n }\n\n private renderBadge() {\n const badge = this.resolveObjectProp<BadgeConfig>(this.badge);\n if (!badge) {\n return nothing;\n }\n\n const position = badge.position ?? \"bottom-right\";\n const hasContent = badge.content !== undefined;\n const hasIcon = badge.icon !== undefined;\n const hasAnyContent = hasContent || hasIcon;\n const { size: badgeSize, fontSize } = getBadgeSize(\n this.pixelSize,\n hasAnyContent\n );\n\n const bgColor = badge.bgColor ?? \"#22c55e\";\n const textColor = badge.color ?? \"#ffffff\";\n const borderRadius = badge.borderRadius ?? \"9999px\";\n\n // Format content (99+ for large numbers)\n const content =\n hasContent && badge.content !== undefined\n ? formatBadgeContent(badge.content, badge.max)\n : null;\n\n // Icon rendering\n const icon = hasIcon ? badge.icon : null;\n const iconSize = fontSize * 0.9; // Icon slightly smaller than text\n\n // Center the badge on the avatar's corner point\n const cornerInset = this.getCornerOffset();\n const offset = cornerInset - badgeSize / 2;\n const posOffset = `${offset}px`;\n\n const positionStyles: Record<Position, Record<string, string>> = {\n \"top-left\": { top: posOffset, left: posOffset },\n \"top-center\": {\n top: posOffset,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n },\n \"top-right\": { top: posOffset, right: posOffset },\n \"bottom-left\": { bottom: posOffset, left: posOffset },\n \"bottom-center\": {\n bottom: posOffset,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n },\n \"bottom-right\": { bottom: posOffset, right: posOffset },\n };\n\n return html`\n <div\n class=${cn(\n \"pp-badge\",\n badge.pulse && \"pp-badge-pulse\",\n badge.glow && \"pp-badge-glow\",\n hasIcon && \"pp-badge-with-icon\"\n )}\n style=${styleMap({\n width: hasAnyContent ? \"auto\" : `${badgeSize}px`,\n minWidth: `${badgeSize}px`,\n height: `${badgeSize}px`,\n padding: hasAnyContent ? \"0 6px\" : \"0\",\n fontSize: `${fontSize}px`,\n backgroundColor: bgColor,\n color: textColor,\n borderRadius,\n \"--pp-badge-glow-color\": bgColor,\n gap: hasIcon && hasContent ? \"4px\" : \"0\",\n ...positionStyles[position],\n })}>\n ${\n icon\n ? html`<span class=\"pp-badge-icon\" style=${styleMap({ fontSize: `${iconSize}px` })}>${icon}</span>`\n : nothing\n }\n ${content ?? nothing}\n </div>\n `;\n }\n\n render() {\n const container = this.getContainerStyles();\n\n const interactive = this.resolveObjectProp<InteractionConfig>(this.interactive);\n const tabIndex =\n interactive?.focusable || interactive?.pressable\n ? 0\n : undefined;\n\n return html`\n <div\n class=${container.classes}\n style=${styleMap(container.styles)}\n tabindex=${tabIndex ?? nothing}\n role=${interactive?.pressable ? \"button\" : nothing}\n aria-label=${this.alt || nothing}\n @click=${this.handleClick}\n @keydown=${this.handleKeyDown}\n data-profile-picture>\n\n <!-- Ring Effect (behind everything) -->\n ${this.renderRing()}\n\n <!-- Inner container for image clipping -->\n <div\n class=${cn(\"pp-inner\", container.innerClasses)}\n style=${styleMap({\n borderRadius: RADIUS_MAP[this.variant],\n ...container.innerStyles,\n })}>\n <!-- Placeholder -->\n ${this.renderPlaceholder()}\n\n <!-- Main Image or Fallback -->\n ${this.renderImage()}\n </div>\n\n <!-- Badge -->\n ${this.renderBadge()}\n\n <!-- Presence Indicator -->\n ${this.renderPresence()}\n </div>\n `;\n }\n}\n\n// Export types for TypeScript users\nexport type {\n BadgeConfig,\n FallbackMode,\n GlowConfig,\n ImageMode,\n InteractionConfig,\n LoadingStrategy,\n PlaceholderType,\n Position,\n PresenceConfig,\n PresenceStatus,\n RingConfig,\n ShadowPreset,\n Size,\n Variant,\n} from \"./types\";\n\n// Register custom element with guard to prevent duplicate registration during HMR\nif (!customElements.get(\"profile-picture\")) {\n customElements.define(\"profile-picture\", ProfilePicture);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"profile-picture\": ProfilePicture;\n }\n}\n\nexport default ProfilePicture;\n","/**\n * ProfilePictureGroup Web Component\n * Apple-inspired stacked avatar group with tooltips, counter, and dropdown\n *\n * A lightweight, framework-agnostic component for displaying\n * multiple profile pictures in a visually appealing stacked layout.\n */\n\nimport { html, LitElement, nothing, render } from \"lit\";\nimport { property, state } from \"lit/decorators.js\";\nimport { styleMap } from \"lit/directives/style-map.js\";\nimport { groupStyles } from \"./styles\";\nimport type {\n DropdownConfig,\n GroupUserData,\n Size,\n StackDirection,\n TooltipConfig,\n TooltipPosition,\n} from \"./types\";\nimport { GROUP_DEFAULTS } from \"./types\";\nimport {\n calculateAvatarCounts,\n calculateGroupWidth,\n calculateStackPosition,\n calculateStackZIndex,\n cn,\n formatCounterText,\n generateAvatarGradient,\n getGroupAvatarSize,\n getInitials,\n} from \"./utils\";\n\n// Inject group styles once\nlet groupStylesInjected = false;\nfunction injectGroupStyles() {\n if (groupStylesInjected || typeof document === \"undefined\") {\n return;\n }\n\n // Defer style injection to avoid hydration mismatch in SSR frameworks\n const defer =\n typeof requestIdleCallback !== \"undefined\"\n ? requestIdleCallback\n : (cb: () => void) => setTimeout(cb, 1);\n\n defer(() => {\n // Re-check in case another call already injected\n if (groupStylesInjected) {\n return;\n }\n const style = document.createElement(\"style\");\n style.textContent = groupStyles;\n document.head.appendChild(style);\n groupStylesInjected = true;\n });\n}\n\nexport class ProfilePictureGroup extends LitElement {\n // Use Light DOM for Tailwind compatibility\n protected createRenderRoot() {\n injectGroupStyles();\n return this;\n }\n\n // ─── Core Properties ────────────────────────────────────────────────────────\n @property({ type: Number }) max = GROUP_DEFAULTS.max;\n @property({ type: String }) direction: StackDirection =\n GROUP_DEFAULTS.direction;\n @property({ type: Number }) overlap = GROUP_DEFAULTS.overlap;\n @property({ type: String }) size: Size | string = GROUP_DEFAULTS.size;\n @property({ type: Number }) spacing?: number;\n @property({ type: Object }) tooltip?: TooltipConfig;\n @property({ type: Object }) dropdown?: DropdownConfig;\n @property({ type: Boolean, attribute: \"show-add-button\" }) showAddButton =\n false;\n @property({ type: String, attribute: \"add-button-label\" }) addButtonLabel =\n \"Add user\";\n @property({ type: Boolean }) animated = GROUP_DEFAULTS.animated;\n @property({ type: Number, attribute: \"rotation-amount\" }) rotationAmount = 0;\n\n // ─── Internal State ─────────────────────────────────────────────────────────\n @state() private users: GroupUserData[] = [];\n @state() private dropdownOpen = false;\n @state() private tooltipData: {\n user: GroupUserData;\n rect: DOMRect;\n } | null = null;\n private tooltipTimeout: number | null = null;\n private slotObserver: MutationObserver | null = null;\n\n // ─── Portal State ───────────────────────────────────────────────────────────\n private portalContainer: HTMLDivElement | null = null;\n private counterRef: HTMLButtonElement | null = null;\n\n private get pixelSize(): number {\n return getGroupAvatarSize(this.size as Size | number);\n }\n\n private get tooltipEnabled(): boolean {\n return this.tooltip?.enabled !== false;\n }\n\n private get tooltipPosition(): TooltipPosition {\n return this.tooltip?.position ?? \"top\";\n }\n\n private get tooltipDelay(): number {\n return this.tooltip?.delay ?? GROUP_DEFAULTS.tooltipDelay;\n }\n\n private get dropdownMaxHeight(): number {\n return this.dropdown?.maxHeight ?? GROUP_DEFAULTS.dropdownMaxHeight;\n }\n\n private get showPresence(): boolean {\n return this.dropdown?.showPresence !== false;\n }\n\n private get dropdownPosition(): \"top\" | \"bottom\" {\n return this.dropdown?.position ?? \"bottom\";\n }\n\n // ─── Lifecycle ──────────────────────────────────────────────────────────────\n\n connectedCallback() {\n super.connectedCallback();\n this.updateUsers();\n this.setupSlotObserver();\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.slotObserver?.disconnect();\n this.clearTooltipTimeout();\n this.destroyPortal();\n }\n\n private setupSlotObserver() {\n // Watch for child element changes\n this.slotObserver = new MutationObserver(() => {\n this.updateUsers();\n });\n\n this.slotObserver.observe(this, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [\n \"src\",\n \"alt\",\n \"ext-customer-id\",\n \"data-user-id\",\n \"data-status\",\n \"variant\",\n \"shadow\",\n \"border\",\n \"border-width\",\n \"border-color\",\n \"bg-color\",\n \"bg-gradient\",\n \"image-mode\",\n \"zoom\",\n \"loading\",\n \"placeholder\",\n \"placeholder-color\",\n \"fallback\",\n \"fallback-mode\",\n \"glow\",\n \"ring\",\n \"badge\",\n \"interactive\",\n ],\n });\n }\n\n private updateUsers() {\n // Only select direct children profile-picture elements (slotted content),\n // not the ones we render inside the ppg-container\n const children = Array.from(this.children).filter(\n (child) =>\n child.tagName.toLowerCase() === \"profile-picture\" &&\n child.getAttribute(\"slot\") !== \"internal\"\n );\n\n this.users = children.map((el, index) => {\n // Helper to read property or attribute (React may set properties instead of attributes)\n const getPropOrAttr = (\n propName: string,\n attrName?: string\n ): string | undefined => {\n const actualAttrName = attrName ?? propName;\n // Try property first (for React compatibility)\n const propValue = (el as unknown as Record<string, unknown>)[propName];\n if (propValue !== undefined && propValue !== null && propValue !== \"\") {\n return String(propValue);\n }\n // Fall back to attribute\n return el.getAttribute(actualAttrName) ?? undefined;\n };\n\n // Extract border-width as number\n const borderWidthValue = getPropOrAttr(\"borderWidth\", \"border-width\");\n const borderWidth = borderWidthValue\n ? (Number.parseInt(String(borderWidthValue), 10) as 1 | 2 | 3 | 4)\n : undefined;\n\n return {\n // Core data\n id: getPropOrAttr(\"dataUserId\", \"data-user-id\"),\n name: getPropOrAttr(\"alt\") ?? `User ${index + 1}`,\n src: getPropOrAttr(\"src\"),\n extCustomerId: getPropOrAttr(\"extCustomerId\", \"ext-customer-id\"),\n status: getPropOrAttr(\"dataStatus\", \"data-status\") as\n | GroupUserData[\"status\"]\n | undefined,\n element: el as HTMLElement,\n index,\n\n // Profile picture props (passed through from slotted elements)\n variant: getPropOrAttr(\"variant\") as\n | GroupUserData[\"variant\"]\n | undefined,\n shadow: getPropOrAttr(\"shadow\") as GroupUserData[\"shadow\"] | undefined,\n border: Boolean(\n (el as unknown as Record<string, unknown>).border ??\n el.hasAttribute(\"border\")\n ),\n borderWidth,\n borderColor: getPropOrAttr(\"borderColor\", \"border-color\"),\n bgColor: getPropOrAttr(\"bgColor\", \"bg-color\"),\n bgGradient: getPropOrAttr(\"bgGradient\", \"bg-gradient\"),\n imageMode: getPropOrAttr(\"imageMode\", \"image-mode\") as\n | GroupUserData[\"imageMode\"]\n | undefined,\n zoom: (() => {\n const v = getPropOrAttr(\"zoom\");\n return v ? Number(v) : undefined;\n })(),\n loading: getPropOrAttr(\"loading\") as\n | GroupUserData[\"loading\"]\n | undefined,\n placeholder: getPropOrAttr(\"placeholder\") as\n | GroupUserData[\"placeholder\"]\n | undefined,\n placeholderColor: getPropOrAttr(\"placeholderColor\", \"placeholder-color\"),\n fallback: getPropOrAttr(\"fallback\"),\n fallbackMode: getPropOrAttr(\"fallbackMode\", \"fallback-mode\") as\n | GroupUserData[\"fallbackMode\"]\n | undefined,\n glow: (() => {\n const v = (el as unknown as Record<string, unknown>).glow;\n if (v && typeof v === \"object\") return v as GroupUserData[\"glow\"];\n const attr = el.getAttribute(\"glow\");\n if (attr) try { return JSON.parse(attr) as GroupUserData[\"glow\"]; } catch { /* ignore */ }\n return undefined;\n })(),\n ring: (() => {\n const v = (el as unknown as Record<string, unknown>).ring;\n if (v && typeof v === \"object\") return v as GroupUserData[\"ring\"];\n const attr = el.getAttribute(\"ring\");\n if (attr) try { return JSON.parse(attr) as GroupUserData[\"ring\"]; } catch { /* ignore */ }\n return undefined;\n })(),\n badge: (() => {\n const v = (el as unknown as Record<string, unknown>).badge;\n if (v && typeof v === \"object\") return v as GroupUserData[\"badge\"];\n const attr = el.getAttribute(\"badge\");\n if (attr) try { return JSON.parse(attr) as GroupUserData[\"badge\"]; } catch { /* ignore */ }\n return undefined;\n })(),\n interactive: (() => {\n const v = (el as unknown as Record<string, unknown>).interactive;\n if (v && typeof v === \"object\") return v as GroupUserData[\"interactive\"];\n const attr = el.getAttribute(\"interactive\");\n if (attr) try { return JSON.parse(attr) as GroupUserData[\"interactive\"]; } catch { /* ignore */ }\n return undefined;\n })(),\n };\n });\n\n // Hide ALL slotted elements since we're rendering our own\n for (const user of this.users) {\n if (user.element) {\n user.element.style.display = \"none\";\n }\n }\n }\n\n // ─── Portal Management ──────────────────────────────────────────────────────\n\n private createPortal() {\n if (this.portalContainer) {\n return;\n }\n\n this.portalContainer = document.createElement(\"div\");\n this.portalContainer.className = \"ppg-portal\";\n this.portalContainer.style.cssText =\n \"position: fixed; z-index: 99999; pointer-events: none;\";\n document.body.appendChild(this.portalContainer);\n\n // Lock body scroll\n document.body.style.overflow = \"hidden\";\n }\n\n private destroyPortal() {\n if (this.portalContainer) {\n render(nothing, this.portalContainer);\n this.portalContainer.remove();\n this.portalContainer = null;\n\n // Restore body scroll\n document.body.style.overflow = \"\";\n }\n }\n\n private updatePortalContent(hiddenUsers: GroupUserData[]) {\n if (!(this.portalContainer && this.counterRef)) {\n return;\n }\n\n const rect = this.counterRef.getBoundingClientRect();\n const gap = 10;\n const dropdownWidth = 280;\n const dropdownHeight = Math.min(\n this.dropdownMaxHeight + 60, // header + padding\n hiddenUsers.length * 56 + 60 // estimate item height\n );\n\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n const isMobile = viewportWidth < 480;\n\n // Mobile: centered modal style\n if (isMobile) {\n const content = html`\n <div\n class=\"ppg-backdrop ppg-backdrop-visible\"\n style=\"pointer-events: auto; background: rgba(0,0,0,0.5);\"\n @click=${this.handleBackdropClick}\n aria-hidden=\"true\"\n ></div>\n <div\n class=\"ppg-dropdown ppg-dropdown-modal\"\n style=${styleMap({\n position: \"fixed\",\n pointerEvents: \"auto\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n width: \"calc(100vw - 32px)\",\n maxWidth: \"320px\",\n maxHeight: \"70vh\",\n })}\n data-position=\"modal\"\n role=\"menu\"\n aria-label=\"Hidden users\"\n >\n <div class=\"ppg-dropdown-header\">\n ${hiddenUsers.length} more\n </div>\n <div\n class=\"ppg-dropdown-list\"\n style=${styleMap({\n maxHeight: \"calc(70vh - 60px)\",\n })}\n >\n ${hiddenUsers.map((user) => this.renderDropdownItem(user))}\n </div>\n </div>\n `;\n render(content, this.portalContainer);\n return;\n }\n\n // Desktop: smart positioning\n const spaceBelow = viewportHeight - rect.bottom - gap;\n const spaceAbove = rect.top - gap;\n const spaceRight = viewportWidth - rect.left;\n const spaceLeft = rect.right;\n\n // Determine vertical position\n let openDirection: \"bottom\" | \"top\" = this.dropdownPosition;\n if (\n openDirection === \"bottom\" &&\n spaceBelow < dropdownHeight &&\n spaceAbove > spaceBelow\n ) {\n openDirection = \"top\";\n } else if (\n openDirection === \"top\" &&\n spaceAbove < dropdownHeight &&\n spaceBelow > spaceAbove\n ) {\n openDirection = \"bottom\";\n }\n\n // Determine horizontal position\n let left: number;\n if (spaceRight >= dropdownWidth) {\n // Align to left edge of counter\n left = rect.left;\n } else if (spaceLeft >= dropdownWidth) {\n // Align to right edge of counter\n left = rect.right - dropdownWidth;\n } else {\n // Center in viewport\n left = (viewportWidth - dropdownWidth) / 2;\n }\n\n // Clamp to viewport bounds\n left = Math.max(8, Math.min(left, viewportWidth - dropdownWidth - 8));\n\n const top = openDirection === \"bottom\" ? rect.bottom + gap : undefined;\n const bottom =\n openDirection === \"top\" ? viewportHeight - rect.top + gap : undefined;\n\n const content = html`\n <div\n class=\"ppg-backdrop\"\n style=\"pointer-events: auto;\"\n @click=${this.handleBackdropClick}\n aria-hidden=\"true\"\n ></div>\n <div\n class=\"ppg-dropdown ppg-dropdown-portal\"\n style=${styleMap({\n position: \"fixed\",\n pointerEvents: \"auto\",\n top: top !== undefined ? `${top}px` : \"auto\",\n bottom: bottom !== undefined ? `${bottom}px` : \"auto\",\n left: `${left}px`,\n width: `${dropdownWidth}px`,\n })}\n data-position=${openDirection}\n role=\"menu\"\n aria-label=\"Hidden users\"\n >\n <div class=\"ppg-dropdown-header\">\n ${hiddenUsers.length} more\n </div>\n <div\n class=\"ppg-dropdown-list\"\n style=${styleMap({\n maxHeight: `${this.dropdownMaxHeight}px`,\n })}\n >\n ${hiddenUsers.map((user) => this.renderDropdownItem(user))}\n </div>\n </div>\n `;\n\n render(content, this.portalContainer);\n }\n\n // ─── Event Handlers ─────────────────────────────────────────────────────────\n\n private handleAvatarClick(user: GroupUserData) {\n this.dispatchEvent(\n new CustomEvent(\"avatar-click\", {\n detail: { user },\n bubbles: true,\n composed: true,\n })\n );\n }\n\n private handleAvatarHover(user: GroupUserData, event: MouseEvent) {\n if (!this.tooltipEnabled) {\n return;\n }\n\n this.clearTooltipTimeout();\n const target = event.currentTarget as HTMLElement;\n\n this.tooltipTimeout = window.setTimeout(() => {\n this.tooltipData = {\n user,\n rect: target.getBoundingClientRect(),\n };\n }, this.tooltipDelay);\n\n this.dispatchEvent(\n new CustomEvent(\"avatar-hover\", {\n detail: { user },\n bubbles: true,\n composed: true,\n })\n );\n }\n\n private handleAvatarLeave() {\n this.clearTooltipTimeout();\n this.tooltipData = null;\n }\n\n private clearTooltipTimeout() {\n if (this.tooltipTimeout) {\n window.clearTimeout(this.tooltipTimeout);\n this.tooltipTimeout = null;\n }\n }\n\n private handleCounterClick(hiddenUsers: GroupUserData[]) {\n this.dropdownOpen = !this.dropdownOpen;\n\n if (this.dropdownOpen) {\n this.createPortal();\n this.updatePortalContent(hiddenUsers);\n } else {\n this.destroyPortal();\n }\n\n this.dispatchEvent(\n new CustomEvent(\"counter-click\", {\n detail: { hiddenUsers, open: this.dropdownOpen },\n bubbles: true,\n composed: true,\n })\n );\n }\n\n private readonly handleBackdropClick = () => {\n this.dropdownOpen = false;\n this.destroyPortal();\n };\n\n private handleDropdownItemClick(user: GroupUserData) {\n this.dropdownOpen = false;\n this.destroyPortal();\n\n this.dispatchEvent(\n new CustomEvent(\"dropdown-item-click\", {\n detail: { user },\n bubbles: true,\n composed: true,\n })\n );\n }\n\n private handleAddClick() {\n this.dispatchEvent(\n new CustomEvent(\"add-click\", {\n bubbles: true,\n composed: true,\n })\n );\n }\n\n private handleKeyDown(event: KeyboardEvent, handler: () => void) {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n handler();\n }\n }\n\n // ─── Rendering ──────────────────────────────────────────────────────────────\n\n private renderAvatar(user: GroupUserData, index: number, total: number) {\n const position = calculateStackPosition(\n index,\n this.pixelSize,\n this.overlap,\n this.direction,\n this.spacing\n );\n const zIndex = calculateStackZIndex(index, total, this.direction);\n\n // Use user's variant or default to circle for groups\n const variant = user.variant ?? \"circle\";\n // Use user's shadow or default to none for cleaner stacking\n const shadow = user.shadow ?? \"none\";\n // Calculate alternating rotation\n const rotation = this.rotationAmount\n ? index % 2 === 0\n ? -this.rotationAmount\n : this.rotationAmount\n : 0;\n\n return html`\n <div\n class=\"ppg-avatar-wrapper\"\n style=${styleMap({\n left: `${position}px`,\n zIndex: String(zIndex),\n width: `${this.pixelSize}px`,\n height: `${this.pixelSize}px`,\n })}\n tabindex=\"0\"\n role=\"button\"\n aria-label=${user.name}\n @click=${() => this.handleAvatarClick(user)}\n @mouseenter=${(e: MouseEvent) => this.handleAvatarHover(user, e)}\n @mouseleave=${this.handleAvatarLeave}\n @keydown=${(e: KeyboardEvent) =>\n this.handleKeyDown(e, () => this.handleAvatarClick(user))}\n >\n ${this.renderProfilePicture(user, variant, shadow, rotation)}\n </div>\n `;\n }\n\n private renderProfilePicture(\n user: GroupUserData,\n variant: string,\n shadow: string,\n rotation: number\n ) {\n // Build the profile-picture element with only defined attributes\n // This avoids passing empty strings which might override defaults\n // Default to white background when wrapped in group\n return html`\n <profile-picture\n .src=${user.src || undefined}\n .alt=${user.name}\n .size=${this.pixelSize}\n .variant=${variant}\n .shadow=${shadow}\n .rotation=${rotation}\n .extCustomerId=${user.extCustomerId}\n ?border=${user.border}\n .borderWidth=${user.border ? (user.borderWidth ?? 2) : 2}\n .borderColor=${user.border ? (user.borderColor ?? \"#ffffff\") : \"#ffffff\"}\n .bgColor=${user.bgGradient ? undefined : (user.bgColor || undefined)}\n .bgGradient=${user.bgGradient ?? undefined}\n .imageMode=${user.imageMode ?? \"original\"}\n .zoom=${user.zoom ?? undefined}\n .loading=${user.loading ?? undefined}\n .placeholder=${user.placeholder ?? undefined}\n .placeholderColor=${user.placeholderColor ?? undefined}\n .fallback=${user.fallback ?? undefined}\n .fallbackMode=${user.fallbackMode ?? undefined}\n .glow=${user.glow ?? undefined}\n .ring=${user.ring ?? undefined}\n .badge=${user.badge ?? undefined}\n .interactive=${user.interactive ?? undefined}\n data-user-id=${user.id ?? \"\"}\n data-status=${user.status ?? \"\"}\n ></profile-picture>\n `;\n }\n\n private renderCounter(\n count: number,\n position: number,\n hiddenUsers: GroupUserData[]\n ) {\n return html`\n <button\n class=\"ppg-counter\"\n style=${styleMap({\n left: `${position}px`,\n width: `${this.pixelSize}px`,\n height: `${this.pixelSize}px`,\n zIndex: \"1\",\n })}\n aria-label=${`${count} more users`}\n aria-expanded=${this.dropdownOpen}\n aria-haspopup=\"true\"\n @click=${() => this.handleCounterClick(hiddenUsers)}\n >\n ${formatCounterText(count)}\n </button>\n `;\n }\n\n private renderAddButton(position: number) {\n const iconSize = Math.round(this.pixelSize * 0.4);\n\n return html`\n <button\n class=\"ppg-add-button\"\n style=${styleMap({\n left: `${position}px`,\n width: `${this.pixelSize}px`,\n height: `${this.pixelSize}px`,\n zIndex: \"1\",\n })}\n aria-label=${this.addButtonLabel}\n @click=${this.handleAddClick}\n >\n <svg\n class=\"ppg-add-icon\"\n width=${iconSize}\n height=${iconSize}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"></line>\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"></line>\n </svg>\n </button>\n `;\n }\n\n private renderTooltip() {\n if (!this.tooltipData) {\n return nothing;\n }\n\n const { user, rect } = this.tooltipData;\n const gap = 8;\n\n // Get container position for relative calculation\n const containerRect = this.getBoundingClientRect();\n\n // Calculate position relative to container\n const relativeLeft = rect.left - containerRect.left + rect.width / 2;\n const relativeTop = rect.top - containerRect.top;\n const relativeBottom = rect.bottom - containerRect.top;\n\n const isTop = this.tooltipPosition === \"top\";\n\n return html`\n <div\n class=\"ppg-tooltip\"\n style=${styleMap({\n top: isTop ? \"auto\" : `${relativeBottom + gap}px`,\n bottom: isTop\n ? `${containerRect.height - relativeTop + gap}px`\n : \"auto\",\n left: `${relativeLeft}px`,\n })}\n data-position=${this.tooltipPosition}\n role=\"tooltip\"\n >\n ${user.name}\n </div>\n `;\n }\n\n private renderDropdownItem(user: GroupUserData) {\n const gradient = generateAvatarGradient(user.name);\n const hasImage = user.src || user.extCustomerId;\n\n return html`\n <div\n class=\"ppg-dropdown-item\"\n role=\"menuitem\"\n tabindex=\"0\"\n @click=${() => this.handleDropdownItemClick(user)}\n @keydown=${(e: KeyboardEvent) =>\n this.handleKeyDown(e, () => this.handleDropdownItemClick(user))}\n >\n ${\n hasImage\n ? html`<profile-picture\n class=\"ppg-dropdown-avatar\"\n .src=${user.src || undefined}\n .alt=${user.name}\n .extCustomerId=${user.extCustomerId}\n .size=${40}\n variant=\"circle\"\n shadow=\"none\"\n ></profile-picture>`\n : html`<div\n class=\"ppg-dropdown-avatar-fallback\"\n style=${styleMap({ background: gradient })}\n >\n ${getInitials(user.name)}\n </div>`\n }\n <div class=\"ppg-dropdown-info\">\n <div class=\"ppg-dropdown-name\">${user.name}</div>\n ${\n this.showPresence && user.status\n ? html`\n <div class=\"ppg-dropdown-status\">\n <span\n class=\"ppg-dropdown-presence\"\n data-status=${user.status}\n ></span>\n ${this.formatStatus(user.status)}\n </div>\n `\n : nothing\n }\n </div>\n </div>\n `;\n }\n\n private formatStatus(status: string): string {\n const labels: Record<string, string> = {\n online: \"Online\",\n away: \"Away\",\n busy: \"Busy\",\n offline: \"Offline\",\n dnd: \"Do not disturb\",\n };\n return labels[status] ?? status;\n }\n\n protected updated(changedProperties: Map<PropertyKey, unknown>) {\n super.updated(changedProperties);\n\n // Update counter ref after render\n const counter = this.querySelector(\".ppg-counter\") as HTMLButtonElement;\n if (counter) {\n this.counterRef = counter;\n }\n\n // Update portal content if dropdown is open\n if (this.dropdownOpen && this.portalContainer) {\n const { visible } = calculateAvatarCounts(\n this.users.length,\n this.max,\n this.showAddButton\n );\n const hiddenUsers = this.users.slice(visible);\n this.updatePortalContent(hiddenUsers);\n }\n }\n\n render() {\n const { visible, hidden, showCounter } = calculateAvatarCounts(\n this.users.length,\n this.max,\n this.showAddButton\n );\n\n // Determine which users to show\n const visibleUsers =\n this.direction === \"ltr\"\n ? this.users.slice(0, visible)\n : this.users.slice(0, visible).reverse();\n\n const hiddenUsers = this.users.slice(visible);\n\n // Calculate element count for width\n let elementCount = visible;\n if (showCounter) {\n elementCount++;\n }\n if (this.showAddButton) {\n elementCount++;\n }\n\n const containerWidth = calculateGroupWidth(\n elementCount,\n this.pixelSize,\n this.overlap,\n this.spacing\n );\n\n // Calculate positions for counter and add button\n const counterPosition = showCounter\n ? calculateStackPosition(\n visible,\n this.pixelSize,\n this.overlap,\n this.direction,\n this.spacing\n )\n : 0;\n\n const addButtonPosition = calculateStackPosition(\n visible + (showCounter ? 1 : 0),\n this.pixelSize,\n this.overlap,\n this.direction,\n this.spacing\n );\n\n return html`\n <div\n class=${cn(\"ppg-container\", this.animated && \"ppg-animated\")}\n style=${styleMap({\n width: `${containerWidth}px`,\n height: `${this.pixelSize}px`,\n })}\n role=\"group\"\n aria-label=\"User avatars\"\n >\n <!-- Hidden slot for original children -->\n <slot style=\"display: none;\"></slot>\n\n <!-- Visible avatars -->\n ${visibleUsers.map((user, index) =>\n this.renderAvatar(user, index, visible)\n )}\n\n <!-- Counter -->\n ${showCounter ? this.renderCounter(hidden, counterPosition, hiddenUsers) : nothing}\n\n <!-- Add button -->\n ${this.showAddButton ? this.renderAddButton(addButtonPosition) : nothing}\n\n <!-- Tooltip -->\n ${this.renderTooltip()}\n </div>\n `;\n }\n}\n\n// Export types for TypeScript users\nexport type {\n DropdownConfig,\n GroupUserData,\n ProfilePictureGroupProps,\n StackDirection,\n TooltipConfig,\n TooltipPosition,\n} from \"./types\";\n\n// Register custom element with guard to prevent duplicate registration during HMR\nif (!customElements.get(\"profile-picture-group\")) {\n customElements.define(\"profile-picture-group\", ProfilePictureGroup);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"profile-picture-group\": ProfilePictureGroup;\n }\n}\n\nexport default ProfilePictureGroup;\n","/**\n * Angular wrapper for ProfilePicture Web Component\n *\n * The component is a standard Web Component and works natively with Angular.\n * No wrapper needed - just import to register the custom element.\n *\n * @example\n * ```typescript\n * import '@grasco/profile-picture/angular';\n * import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';\n * import type { RingConfig, BadgeConfig } from '@grasco/profile-picture/angular';\n *\n * @Component({\n * selector: 'app-example',\n * template: `\n * <profile-picture\n * [attr.src]=\"avatarUrl\"\n * size=\"lg\"\n * variant=\"circle\"\n * border\n * border-color=\"white\"\n * bg-color=\"#f3f4f6\"\n * [attr.ring]=\"ringJson\"\n * [attr.badge]=\"badgeJson\"\n * (load)=\"onImageLoad()\"\n * (error)=\"onImageError()\"\n * (profile-picture-click)=\"onAvatarClick($event)\">\n * </profile-picture>\n * `,\n * standalone: true,\n * schemas: [CUSTOM_ELEMENTS_SCHEMA] // Required for custom elements\n * })\n * export class ExampleComponent {\n * avatarUrl = 'https://example.com/avatar.png';\n *\n * ring: RingConfig = { show: true, color: '#ff5722' };\n * badge: BadgeConfig = { content: 3, position: 'bottom-right', pulse: true };\n *\n * get ringJson() { return JSON.stringify(this.ring); }\n * get badgeJson() { return JSON.stringify(this.badge); }\n *\n * onImageLoad() {\n * console.log('Image loaded');\n * }\n *\n * onImageError() {\n * console.error('Image failed to load');\n * }\n * }\n * ```\n *\n * Note: Add CUSTOM_ELEMENTS_SCHEMA to your component's schemas array.\n *\n * For property binding:\n * - Use [attr.property]=\"value\" for object/array properties (ring, badge, etc.)\n * - Use property=\"value\" for string/primitive properties\n * - Use (event)=\"handler()\" for events (load, error, cdn-error)\n */\n\n// Import and register the web components\nimport { ProfilePicture as CoreProfilePictureElement } from \"../../core/ProfilePicture\";\nimport \"../../core/ProfilePictureGroup\";\n\n/**\n * Set global CDN base URL for all ProfilePicture instances\n * @example setCdnBaseUrl('https://api.example.com')\n */\nexport function setCdnBaseUrl(url: string): void {\n CoreProfilePictureElement.setCdnBaseUrl(url);\n}\n\n/**\n * Get current CDN base URL\n */\nexport function getCdnBaseUrl(): string {\n return CoreProfilePictureElement.getCdnBaseUrl();\n}\n\n// Re-export all types for TypeScript users\nexport type {\n // ProfilePicture types\n BadgeConfig,\n // ProfilePictureGroup types\n DropdownConfig,\n FallbackMode,\n GlowConfig,\n GroupUserData,\n ImageMode,\n InteractionConfig,\n LoadingStrategy,\n PlaceholderType,\n Position,\n PresenceConfig,\n PresenceStatus,\n ProfilePictureGroupProps,\n ProfilePictureProps,\n RingConfig,\n ShadowPreset,\n Size,\n StackDirection,\n TooltipConfig,\n TooltipPosition,\n Variant,\n} from \"../../core/types\";\n","/**\n * Angular entry point\n */\n\n// Auto-load styles when module is imported\nimport { loadStyles } from \"./core/loadStyles\";\n\nloadStyles();\n\nexport * from \"./wrappers/angular\";\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/core/loadStyles.ts","../src/core/types.ts","../src/core/utils.ts","../src/core/styles.ts","../src/core/ProfilePicture.ts","../src/core/ProfilePictureGroup.ts","../src/wrappers/angular/index.ts","../src/angular.ts"],"names":["LINK_ID","loaded","loadScheduled","loadStyles","scheduleStyleInjection","cb","injectStyleLink","cssUrl","getCssUrl","link","metaUrl","currentScript","scriptUrl","SIZE_MAP","PRESENCE_COLORS","SHADOW_MAP","DEFAULTS","RADIUS_MAP","GROUP_DEFAULTS","cn","classes","isHexColor","color","getInitials","text","words","getInitialsFontSize","containerSize","getBadgeSize","avatarSize","hasContent","size","scaled","fontSize","getPresenceSize","thickness","baseSize","formatBadgeContent","content","max","createConicGradient","colors","i","start","end","hashString","str","hash","char","createProgressRingGradient","progress","filledColor","emptyColor","progressDeg","generateAvatarGradient","name","gradients","index","CLOUDY_PALETTES","blendHex","hex","base","ratio","parse","h","c","b","mix","generateCloudyGradient","seed","palette","edge0","edge1","edge2","h2","h3","x1","y1","x2","y2","x3","y3","getGroupAvatarSize","calculateAvatarCounts","total","showAddButton","effectiveMax","visible","hidden","calculateStackPosition","overlap","_direction","spacing","step","calculateStackZIndex","direction","calculateGroupWidth","count","formatCounterText","getCdnSizeLabel","pixelSize","constructCdnUrl","baseUrl","extCustomerId","sizeLabel","imageMode","hostname","cleanBaseUrl","filename","getVariantClasses","variant","getBorderClasses","width","getBackgroundStyles","bgColor","bgGradient","getShadowStyles","shadow","keyframes","allKeyframes","baseStyles","componentStyles","shimmerStyles","getGlowShadow","intensity","r","g","groupKeyframes","groupBaseStyles","groupStyles","_ProfilePicture","LitElement","url","instance","style","value","sizeValue","changedProperties","extCustomerIdChanged","cdnParamsChanged","event","bg","borderStyles","shadowStyles","glow","glowStyles","glowColor","interactive","isInteractive","nothing","placeholderClass","html","styleMap","hasExplicitBg","gradient","iconSize","hasCdnConfig","imageSrc","zoomStyle","ring","ringWidth","ringGap","totalOffset","ringColor","hasProgress","radius","presence","offset","badge","position","hasIcon","hasAnyContent","badgeSize","textColor","borderRadius","icon","posOffset","positionStyles","container","tabIndex","__decorateClass","property","state","ProfilePicture","groupStylesInjected","injectGroupStyles","ProfilePictureGroup","children","child","el","getPropOrAttr","propName","attrName","actualAttrName","propValue","borderWidthValue","borderWidth","v","attr","user","render","hiddenUsers","rect","gap","dropdownWidth","dropdownHeight","viewportWidth","viewportHeight","spaceBelow","spaceAbove","spaceRight","spaceLeft","openDirection","left","top","bottom","target","handler","zIndex","rotation","e","containerRect","relativeLeft","relativeTop","relativeBottom","isTop","hasImage","status","counter","showCounter","visibleUsers","elementCount","containerWidth","counterPosition","addButtonPosition","setCdnBaseUrl","getCdnBaseUrl"],"mappings":"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AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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","file":"angular.cjs","sourcesContent":["/**\n * Idempotent CSS loader for @grasco/profile-picture\n *\n * Auto-injects the component's CSS via <link> tag when the module is imported.\n * Uses relative URL detection to find styles.css in the same directory as the JS file.\n *\n * Idempotency is guaranteed through 4 layers:\n * 1. Module-level flag - prevents multiple calls in same bundle\n * 2. ID check - prevents duplicates across bundles\n * 3. href pattern check - catches manually added links\n * 4. SSR guard - prevents errors in Node.js\n *\n * SSR Hydration Safety:\n * Style injection is deferred using requestIdleCallback (with setTimeout fallback)\n * to avoid DOM mutations during React/framework hydration, which would cause\n * hydration mismatch errors.\n */\n\nconst LINK_ID = \"grasco-profile-picture-styles\";\n\nlet loaded = false;\nlet loadScheduled = false;\n\n/**\n * Load the component's CSS stylesheet\n * Safe to call multiple times - will only inject once\n * Defers injection to avoid SSR hydration mismatch\n */\nexport function loadStyles(): void {\n // Skip if already loaded (module-level)\n if (loaded) {\n return;\n }\n\n // Skip if SSR (no document)\n if (typeof document === \"undefined\") {\n return;\n }\n\n // Skip if link already exists by ID (idempotency across bundles)\n if (document.getElementById(LINK_ID)) {\n loaded = true;\n return;\n }\n\n // Check if any link already points to our CSS (by href pattern)\n const existingLink = document.querySelector(\n 'link[href*=\"profile-picture\"][href$=\"styles.css\"]'\n );\n if (existingLink) {\n loaded = true;\n return;\n }\n\n // Schedule deferred injection (after hydration completes)\n if (!loadScheduled) {\n loadScheduled = true;\n scheduleStyleInjection();\n }\n}\n\n/**\n * Schedule style injection after hydration using requestIdleCallback\n * Falls back to setTimeout for browsers without requestIdleCallback support\n */\nfunction scheduleStyleInjection(): void {\n const defer =\n typeof requestIdleCallback !== \"undefined\"\n ? requestIdleCallback\n : (cb: () => void) => setTimeout(cb, 1);\n\n defer(() => injectStyleLink());\n}\n\n/**\n * Actually inject the <link> tag into the document head\n */\nfunction injectStyleLink(): void {\n // Re-check conditions in case something changed\n if (loaded || typeof document === \"undefined\") {\n return;\n }\n\n if (document.getElementById(LINK_ID)) {\n loaded = true;\n return;\n }\n\n // Get CSS URL relative to current script\n const cssUrl = getCssUrl();\n if (!cssUrl) {\n return;\n }\n\n // Inject link tag\n const link = document.createElement(\"link\");\n link.id = LINK_ID;\n link.rel = \"stylesheet\";\n link.href = cssUrl;\n document.head.appendChild(link);\n\n loaded = true;\n}\n\n/**\n * Get the CSS file URL based on the current script's location\n */\nfunction getCssUrl(): string | null {\n // Allow custom override via global variable\n if (\n typeof window !== \"undefined\" &&\n (window as unknown as Record<string, string>).__GRASCO_PROFILE_PICTURE_CSS__\n ) {\n return (window as unknown as Record<string, string>)\n .__GRASCO_PROFILE_PICTURE_CSS__;\n }\n\n // Try import.meta.url first (ESM - most reliable for bundlers)\n try {\n const metaUrl = import.meta.url;\n if (metaUrl) {\n const basePath = metaUrl.substring(0, metaUrl.lastIndexOf(\"/\") + 1);\n return `${basePath}styles.css`;\n }\n } catch {\n // import.meta.url not available\n }\n\n // Fallback: Get current script URL\n const currentScript = document.currentScript as HTMLScriptElement | null;\n if (currentScript?.src) {\n const scriptUrl = new URL(currentScript.src);\n const basePath = scriptUrl.href.substring(\n 0,\n scriptUrl.href.lastIndexOf(\"/\") + 1\n );\n return `${basePath}dist/styles.css`;\n }\n\n return null;\n}\n","/**\n * Profile Picture Component - Type Definitions\n * Apple-inspired design system with modern 2025 aesthetics\n */\n\n// ─── Size System (Apple 8pt Grid) ─────────────────────────────────────────────\nexport type Size = \"2xs\" | \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\" | \"3xl\";\n\n// Size presets in pixels (following 8pt grid)\nexport const SIZE_MAP: Record<Size, number> = {\n \"2xs\": 20, // Inline, compact UI\n xs: 24, // Small avatars, lists\n sm: 32, // Default list items\n md: 40, // Navigation, headers\n lg: 48, // Profile sections\n xl: 64, // Profile pages\n \"2xl\": 80, // Hero sections\n \"3xl\": 120, // Profile modals\n};\n\n// ─── Visual Variants ──────────────────────────────────────────────────────────\nexport type Variant = \"circle\" | \"rounded\" | \"squircle\" | \"square\";\n\n// ─── Positioning ──────────────────────────────────────────────────────────────\nexport type Position =\n | \"top-left\"\n | \"top-center\"\n | \"top-right\"\n | \"bottom-left\"\n | \"bottom-center\"\n | \"bottom-right\";\n\n// ─── Loading & Performance ────────────────────────────────────────────────────\nexport type LoadingStrategy = \"lazy\" | \"eager\";\nexport type PlaceholderType =\n | \"shimmer\"\n | \"pulse\"\n | \"blur\"\n | \"skeleton\"\n | \"none\";\n\nexport type FallbackMode = \"initials\" | \"gradient\";\nexport type ImageMode = \"transparent\" | \"original\";\n\n// ─── Presence / Status System ─────────────────────────────────────────────────\nexport type PresenceStatus = \"online\" | \"away\" | \"busy\" | \"offline\" | \"dnd\";\n\nexport interface PresenceConfig {\n /** Current status */\n status: PresenceStatus;\n /** Show animated ring */\n animate?: boolean;\n /** Ring thickness (1-3) */\n thickness?: 1 | 2 | 3;\n}\n\n// Status colors (Apple-inspired)\nexport const PRESENCE_COLORS: Record<PresenceStatus, string> = {\n online: \"#30D158\", // Apple Green\n away: \"#FFD60A\", // Apple Yellow\n busy: \"#FF453A\", // Apple Red\n offline: \"#8E8E93\", // Apple Gray\n dnd: \"#FF453A\", // Apple Red (Do Not Disturb)\n};\n\n// ─── Badge Configuration ──────────────────────────────────────────────────────\nexport interface BadgeConfig {\n /** Badge content (text, number, or empty for dot) */\n content?: string | number;\n /** Position of the badge */\n position?: Position;\n /** Text/icon color */\n color?: string;\n /** Background color */\n bgColor?: string;\n /** Border radius (CSS value, e.g., \"8px\", \"50%\", \"9999px\") */\n borderRadius?: string;\n /** Enable pulse animation */\n pulse?: boolean;\n /** Enable glow effect */\n glow?: boolean;\n /** Max value to display (shows 99+ if exceeded) */\n max?: number;\n /** Icon to display before content (emoji, Unicode symbol, or text) */\n icon?: string;\n}\n\n// ─── Glow Effect ──────────────────────────────────────────────────────────────\nexport interface GlowConfig {\n /** Glow color (defaults to border or bg color) */\n color?: string;\n /** Intensity (0-1) */\n intensity?: number;\n /** Animate the glow */\n animate?: boolean;\n}\n\n// ─── Ring Effect (like Instagram stories) ────────────────────────────────────\nexport interface RingConfig {\n /** Show ring */\n show: boolean;\n /** Ring color or gradient */\n color?: string;\n /** Gradient colors for multi-color ring */\n gradient?: string[];\n /** Ring width */\n width?: number;\n /** Gap between ring and avatar */\n gap?: number;\n /** Animate (rotate for gradient) */\n animate?: boolean;\n /** Progress percentage (0-100) for partial fill ring */\n progress?: number;\n /** Color for unfilled portion when progress is set (defaults to gray) */\n emptyColor?: string;\n}\n\n// ─── Interactive States ───────────────────────────────────────────────────────\nexport interface InteractionConfig {\n /** Enable hover effects */\n hoverable?: boolean;\n /** Enable press/click effects */\n pressable?: boolean;\n /** Show focus ring on focus */\n focusable?: boolean;\n /** Cursor style */\n cursor?: \"pointer\" | \"default\" | \"zoom-in\";\n}\n\n// ─── Shadow Presets ───────────────────────────────────────────────────────────\nexport type ShadowPreset = \"none\" | \"sm\" | \"md\" | \"lg\" | \"glow\";\n\nexport const SHADOW_MAP: Record<ShadowPreset, string> = {\n none: \"none\",\n sm: \"0 1px 2px 0 rgba(0, 0, 0, 0.05)\",\n md: \"0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1)\",\n lg: \"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1)\",\n glow: \"0 0 20px 0 rgba(99, 102, 241, 0.3)\",\n};\n\n// ─── Animation Presets ────────────────────────────────────────────────────────\nexport type AnimationPreset = \"none\" | \"fade\" | \"scale\" | \"slide\" | \"bounce\";\n\n// ─── Default Values ───────────────────────────────────────────────────────────\nexport const DEFAULTS = {\n size: \"md\" as Size,\n variant: \"circle\" as Variant,\n loading: \"lazy\" as LoadingStrategy,\n placeholder: \"shimmer\" as PlaceholderType,\n borderWidth: 2 as const,\n borderColor: \"#ffffff\",\n placeholderColor: \"#f3f4f6\",\n shadow: \"sm\" as ShadowPreset,\n animation: \"fade\" as AnimationPreset,\n imageMode: \"original\" as ImageMode,\n zoom: 1.2,\n} as const;\n\n// ─── CSS Custom Properties (for theming) ──────────────────────────────────────\nexport const CSS_VARS = {\n \"--pp-transition-duration\": \"200ms\",\n \"--pp-transition-timing\": \"cubic-bezier(0.4, 0, 0.2, 1)\",\n \"--pp-spring-timing\": \"cubic-bezier(0.34, 1.56, 0.64, 1)\",\n \"--pp-hover-scale\": \"1.05\",\n \"--pp-press-scale\": \"0.95\",\n \"--pp-focus-ring-color\": \"rgba(99, 102, 241, 0.5)\",\n \"--pp-focus-ring-width\": \"3px\",\n \"--pp-skeleton-base\": \"#e5e7eb\",\n \"--pp-skeleton-shine\": \"#f3f4f6\",\n} as const;\n\n// ─── Border Radius Presets ────────────────────────────────────────────────────\nexport const RADIUS_MAP: Record<Variant, string> = {\n circle: \"9999px\",\n rounded: \"12px\",\n squircle: \"30%\", // iOS app icon style\n square: \"0px\",\n};\n\n// ─── Full Component Props Interface ───────────────────────────────────────────\n/**\n * Base props interface shared across all framework wrappers.\n * This ensures type consistency between React, Vue, Svelte, and Angular.\n */\nexport interface ProfilePictureProps {\n // Core\n /** Image source URL */\n src?: string;\n /** Alt text for accessibility and fallback initials */\n alt?: string;\n /** External customer ID for CDN image loading */\n extCustomerId?: string;\n /** CDN image mode: 'transparent' for transparent background, 'original' for original background */\n imageMode?: ImageMode;\n\n // Sizing\n /** Predefined size or custom pixel value */\n size?: Size | number;\n\n // Visual\n /** Shape variant */\n variant?: Variant;\n /** Shadow preset */\n shadow?: ShadowPreset;\n\n // Border\n /** Enable border */\n border?: boolean;\n /** Border width in pixels */\n borderWidth?: 1 | 2 | 3 | 4 | 5 | 6 | 8;\n /** Border color (CSS color value) */\n borderColor?: string;\n\n // Rotation\n /** Rotation angle in degrees */\n rotation?: number;\n\n // Zoom\n /** Zoom level for the image (default: 1.4). Values > 1 zoom in, keeping the image within the crop zone */\n zoom?: number;\n\n // Background\n /** Background color (CSS color value) */\n bgColor?: string;\n /** Background gradient (CSS gradient value) */\n bgGradient?: string;\n\n // Effects\n /** Glow effect configuration */\n glow?: GlowConfig;\n /** Ring effect configuration (Instagram-style) */\n ring?: RingConfig;\n /** Presence indicator configuration */\n presence?: PresenceConfig;\n\n // Overlays\n /** Badge configuration */\n badge?: BadgeConfig;\n\n // Loading\n /** Loading strategy */\n loading?: LoadingStrategy;\n /** Placeholder type while loading */\n placeholder?: PlaceholderType;\n /** Placeholder background color */\n placeholderColor?: string;\n\n // Fallback\n /** Custom fallback text (overrides initials from alt) */\n fallback?: string;\n /** Fallback display mode: 'initials' shows letters, 'gradient' shows cloudy gradient */\n fallbackMode?: FallbackMode;\n\n // Interaction\n /** Interactive behavior configuration */\n interactive?: InteractionConfig;\n}\n\n// ─── Profile Picture Group Types ─────────────────────────────────────────────\n\n/** Direction for stacking avatars */\nexport type StackDirection = \"ltr\" | \"rtl\";\n\n/** Tooltip position relative to avatar */\nexport type TooltipPosition = \"top\" | \"bottom\" | \"left\" | \"right\";\n\n/** Tooltip configuration */\nexport interface TooltipConfig {\n /** Enable/disable tooltip (default: true) */\n enabled?: boolean;\n /** Position of tooltip relative to avatar */\n position?: TooltipPosition;\n /** Delay before showing tooltip in ms (default: 300) */\n delay?: number;\n}\n\n/** User data extracted from profile-picture elements */\nexport interface GroupUserData {\n /** User ID from data-user-id attribute */\n id?: string;\n /** User name from alt attribute */\n name: string;\n /** Image source URL */\n src?: string;\n /** External customer ID for CDN image loading */\n extCustomerId?: string;\n /** Presence status from data-status attribute */\n status?: PresenceStatus;\n /** Reference to the profile-picture element */\n element: HTMLElement;\n /** Index in the group */\n index: number;\n\n // ─── Profile Picture Props (passed through from slotted elements) ──────────\n /** Visual variant (circle, rounded, squircle, square) */\n variant?: Variant;\n /** Shadow preset */\n shadow?: ShadowPreset;\n /** Show border */\n border?: boolean;\n /** Border width (1-8) */\n borderWidth?: 1 | 2 | 3 | 4 | 5 | 6 | 8;\n /** Border color */\n borderColor?: string;\n /** Background color */\n bgColor?: string;\n /** Background gradient */\n bgGradient?: string;\n /** CDN image mode */\n imageMode?: ImageMode;\n /** Zoom level */\n zoom?: number;\n /** Loading strategy */\n loading?: LoadingStrategy;\n /** Placeholder type */\n placeholder?: PlaceholderType;\n /** Placeholder color */\n placeholderColor?: string;\n /** Custom fallback text */\n fallback?: string;\n /** Fallback mode */\n fallbackMode?: FallbackMode;\n /** Glow config */\n glow?: GlowConfig;\n /** Ring config */\n ring?: RingConfig;\n /** Badge config */\n badge?: BadgeConfig;\n /** Interactive config */\n interactive?: InteractionConfig;\n}\n\n/** Dropdown configuration for overflow users */\nexport interface DropdownConfig {\n /** Max height of dropdown in px (default: 280) */\n maxHeight?: number;\n /** Show presence indicator dots (default: true) */\n showPresence?: boolean;\n /** Dropdown position (default: 'bottom') */\n position?: \"bottom\" | \"top\";\n}\n\n/** Profile Picture Group Props */\nexport interface ProfilePictureGroupProps {\n /** Maximum visible avatars before showing counter (default: 4) */\n max?: number;\n /** Stack direction - ltr shows first on left (default: 'ltr') */\n direction?: StackDirection;\n /** Overlap amount as percentage 0-1 (default: 0.3) */\n overlap?: number;\n /** Avatar size - inherited by children (default: 'md') */\n size?: Size | number;\n /** Spacing between avatars in px (overrides overlap calculation) */\n spacing?: number;\n /** Tooltip configuration */\n tooltip?: TooltipConfig;\n /** Dropdown configuration for overflow users */\n dropdown?: DropdownConfig;\n /** Show add button (default: false) */\n showAddButton?: boolean;\n /** Add button label for accessibility */\n addButtonLabel?: string;\n /** Enable hover lift animation (default: true) */\n animated?: boolean;\n}\n\n/** Group component defaults */\nexport const GROUP_DEFAULTS = {\n max: 4,\n direction: \"ltr\" as StackDirection,\n overlap: 0.3,\n size: \"md\" as Size,\n tooltipDelay: 300,\n dropdownMaxHeight: 280,\n animated: true,\n} as const;\n","/**\n * Profile Picture Component - Utility Functions\n * Apple-inspired design system utilities\n */\n\nimport type { Size, Variant } from \"./types\";\nimport { RADIUS_MAP, SIZE_MAP } from \"./types\";\n\n/**\n * Resolve size to pixel value\n */\nexport function resolveSize(size: Size | number): number {\n if (typeof size === \"number\") {\n return size;\n }\n return SIZE_MAP[size] ?? SIZE_MAP.md;\n}\n\n/**\n * Merge class names, filtering out falsy values\n */\nexport function cn(...classes: (string | undefined | null | false)[]): string {\n return classes.filter(Boolean).join(\" \");\n}\n\n/**\n * Check if a color value is a hex code\n */\nexport function isHexColor(color: string): boolean {\n return /^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/.test(color);\n}\n\n/**\n * Check if a value is a CSS color (not a Tailwind class)\n */\nexport function isCssColor(value: string): boolean {\n if (isHexColor(value)) {\n return true;\n }\n if (/^(rgb|hsl|oklch|oklab|lab|lch)a?\\s*\\(/.test(value)) {\n return true;\n }\n if (value.includes(\"gradient\")) {\n return true;\n }\n const namedColors = [\n \"transparent\",\n \"currentColor\",\n \"inherit\",\n \"white\",\n \"black\",\n ];\n return namedColors.includes(value.toLowerCase());\n}\n\n/**\n * Generate initials from alt text for fallback\n * Apple-style: Single letter for single word, two letters for multiple\n */\nexport function getInitials(text: string): string {\n const cleaned = text.trim().replace(/[^\\w\\s]/g, \"\");\n const words = cleaned.split(/\\s+/).filter(Boolean);\n\n if (words.length === 0) {\n return \"?\";\n }\n if (words.length === 1) {\n return words[0].slice(0, 1).toUpperCase();\n }\n return (words[0][0] + (words.at(-1)?.[0] ?? \"\")).toUpperCase();\n}\n\n/**\n * Get border radius value for variant\n */\nexport function getRadius(variant: Variant): string {\n return RADIUS_MAP[variant];\n}\n\n/**\n * Calculate optimal font size for initials based on container size\n */\nexport function getInitialsFontSize(containerSize: number): number {\n return Math.round(containerSize * 0.38);\n}\n\n/**\n * Calculate badge size relative to avatar size\n * Uses non-linear scaling to maintain visual balance:\n * - XL (64px) is the reference: ~33% ratio looks good\n * - Small avatars: proportionally smaller badges with reasonable minimums\n * - Large avatars: caps prevent oversized badges\n */\nexport function getBadgeSize(\n avatarSize: number,\n hasContent: boolean\n): { size: number; fontSize: number } {\n // Reference: XL (64px) avatar with content badge = 20px (31%)\n // Use diminishing ratio for larger sizes\n let size: number;\n\n if (hasContent) {\n // Badge with content: min 14px, max 24px\n // Scale: 31% ratio but capped\n const scaled = Math.round(avatarSize * 0.31);\n size = Math.min(24, Math.max(14, scaled));\n } else {\n // Dot badge: min 8px, max 14px\n // Scale: 22% ratio but capped\n const scaled = Math.round(avatarSize * 0.22);\n size = Math.min(14, Math.max(8, scaled));\n }\n\n // Font size: 55% of badge for better readability at small sizes\n const fontSize = Math.max(9, Math.round(size * 0.55));\n return { size, fontSize };\n}\n\n/**\n * Calculate presence indicator size\n * Uses capped scaling to maintain visual balance:\n * - Reference: XL (64px) with thickness 2 = 14px (~22%)\n * - Small avatars: min 8px for visibility\n * - Large avatars: max 18px to prevent oversizing\n */\nexport function getPresenceSize(\n avatarSize: number,\n thickness: 1 | 2 | 3\n): number {\n // Base size: 20% ratio, capped between 8-16px\n const baseSize = Math.min(16, Math.max(8, Math.round(avatarSize * 0.2)));\n // Add thickness adjustment (0, 2, or 4 pixels)\n return Math.min(18, baseSize + (thickness - 1) * 2);\n}\n\n/**\n * Format badge content (e.g., 99+ for large numbers)\n */\nexport function formatBadgeContent(\n content: string | number,\n max?: number\n): string {\n if (typeof content === \"string\") {\n return content;\n }\n if (max && content > max) {\n return `${max}+`;\n }\n return content.toString();\n}\n\n/**\n * Generate a gradient from colors array for ring effect\n */\nexport function createConicGradient(colors: string[]): string {\n if (colors.length === 0) {\n return \"transparent\";\n }\n if (colors.length === 1) {\n return colors[0];\n }\n\n const stops = colors.map((color, i) => {\n const start = (i / colors.length) * 360;\n const end = ((i + 1) / colors.length) * 360;\n return `${color} ${start}deg ${end}deg`;\n });\n\n return `conic-gradient(${stops.join(\", \")})`;\n}\n\n/**\n * Get contrast color for text on background\n * Returns white or black based on background luminance\n */\nexport function getContrastColor(bgColor: string): string {\n // Extract RGB values from hex\n if (!isHexColor(bgColor)) {\n return \"#ffffff\";\n }\n\n const hex = bgColor.replace(\"#\", \"\");\n const r = Number.parseInt(hex.slice(0, 2), 16);\n const g = Number.parseInt(hex.slice(2, 4), 16);\n const b = Number.parseInt(hex.slice(4, 6), 16);\n\n // Calculate relative luminance\n const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;\n\n return luminance > 0.5 ? \"#000000\" : \"#ffffff\";\n}\n\n/**\n * Clamp a number between min and max\n */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\n/**\n * Generate a stable hash from string for consistent random colors\n */\nexport function hashString(str: string): number {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash &= hash;\n }\n return Math.abs(hash);\n}\n\n/**\n * Create a progress ring gradient using conic gradient\n * @param progress Progress percentage (0-100)\n * @param filledColor Color for filled portion\n * @param emptyColor Color for empty portion\n * @returns CSS conic gradient string\n */\nexport function createProgressRingGradient(\n progress: number,\n filledColor: string,\n emptyColor: string\n): string {\n // Clamp progress to 0-100\n const clampedProgress = Math.max(0, Math.min(100, progress));\n // Convert percentage to degrees (start from top, go clockwise)\n // 0% = 0deg (top), 100% = 360deg (full circle)\n const progressDeg = (clampedProgress / 100) * 360;\n // Create conic gradient starting from top (270deg offset to start at 12 o'clock)\n // Then go clockwise: filled color from 0% to progress%, empty color from progress% to 100%\n return `conic-gradient(from 270deg, ${filledColor} 0deg ${progressDeg}deg, ${emptyColor} ${progressDeg}deg 360deg)`;\n}\n\n/**\n * Generate a gradient from name for fallback backgrounds\n */\nexport function generateAvatarGradient(name: string): string {\n const gradients = [\n \"linear-gradient(135deg, #667eea 0%, #764ba2 100%)\",\n \"linear-gradient(135deg, #f093fb 0%, #f5576c 100%)\",\n \"linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)\",\n \"linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)\",\n \"linear-gradient(135deg, #fa709a 0%, #fee140 100%)\",\n \"linear-gradient(135deg, #a8edea 0%, #fed6e3 100%)\",\n \"linear-gradient(135deg, #d299c2 0%, #fef9d7 100%)\",\n \"linear-gradient(135deg, #89f7fe 0%, #66a6ff 100%)\",\n \"linear-gradient(135deg, #cd9cf2 0%, #f6f3ff 100%)\",\n \"linear-gradient(135deg, #fddb92 0%, #d1fdff 100%)\",\n ];\n\n const index = hashString(name) % gradients.length;\n return gradients[index];\n}\n\n/**\n * Curated 3-color pastel palettes for cloudy gradient fallback.\n * Each palette creates an organic, watercolor-like effect when\n * layered as overlapping radial gradients.\n */\nexport const CLOUDY_PALETTES: [string, string, string][] = [\n [\"#f4a261\", \"#e76f51\", \"#d4a5a5\"], // Warm sunset\n [\"#f2a9b0\", \"#e07a5f\", \"#d4c4a8\"], // Soft coral rose\n [\"#c9b1d0\", \"#e8a0bf\", \"#f0d1ce\"], // Dusty mauve\n [\"#89c2d9\", \"#a3c4bc\", \"#d5c6e0\"], // Ocean mist\n [\"#f7c59f\", \"#f2a07b\", \"#efcfe3\"], // Warm peach\n [\"#b5a7d5\", \"#d4a5c9\", \"#f0c3d7\"], // Lavender dream\n [\"#7ec8c8\", \"#6a9fb5\", \"#c2b5d6\"], // Cool teal\n [\"#f0b3ba\", \"#d4a5c9\", \"#c9d1d9\"], // Blush pink\n [\"#e8b960\", \"#d4956a\", \"#c9a5b8\"], // Amber cloud\n [\"#a7c4a0\", \"#c9d4a5\", \"#e0c9b1\"], // Sage pastel\n [\"#c4819b\", \"#d9a5b8\", \"#b5aed4\"], // Berry soft\n [\"#f0c27f\", \"#e0a87c\", \"#d4b5c9\"], // Golden hour\n];\n\n/**\n * Blend a hex color toward a base color by a given ratio (0 = original, 1 = base).\n * Returns a fully opaque hex color — no transparency involved.\n */\nfunction blendHex(hex: string, base: string, ratio: number): string {\n const parse = (h: string) => [\n Number.parseInt(h.slice(1, 3), 16),\n Number.parseInt(h.slice(3, 5), 16),\n Number.parseInt(h.slice(5, 7), 16),\n ];\n const c = parse(hex);\n const b = parse(base);\n const mix = (i: number) =>\n Math.round(c[i] + (b[i] - c[i]) * ratio)\n .toString(16)\n .padStart(2, \"0\");\n return `#${mix(0)}${mix(1)}${mix(2)}`;\n}\n\n/**\n * Generate a cloudy, organic multi-layer radial gradient from a seed string.\n * Uses 3 overlapping radial-gradient layers with soft edges.\n * All colors are fully opaque — fades blend toward a light neutral base\n * instead of using transparency.\n * Deterministic: same seed always produces the same gradient.\n */\nexport function generateCloudyGradient(seed: string): string {\n const hash = hashString(seed);\n const palette = CLOUDY_PALETTES[hash % CLOUDY_PALETTES.length];\n\n // Light neutral base that colors fade into (warm off-white)\n const base = \"#f5f0eb\";\n\n // Pre-blend each palette color toward the base at 85% ratio for the edge color\n const edge0 = blendHex(palette[0], base, 0.85);\n const edge1 = blendHex(palette[1], base, 0.85);\n const edge2 = blendHex(palette[2], base, 0.85);\n\n // Derive unique positions from hash variations\n const h2 = hashString(seed + \"pos1\");\n const h3 = hashString(seed + \"pos2\");\n\n // Positions range from 20-80% to keep blobs within bounds\n const x1 = 20 + (hash % 61);\n const y1 = 20 + ((hash >> 4) % 61);\n const x2 = 20 + (h2 % 61);\n const y2 = 20 + ((h2 >> 4) % 61);\n const x3 = 20 + (h3 % 61);\n const y3 = 20 + ((h3 >> 4) % 61);\n\n return [\n `radial-gradient(circle at ${x1}% ${y1}%, ${palette[0]} 0%, ${edge0} 70%)`,\n `radial-gradient(circle at ${x2}% ${y2}%, ${palette[1]} 0%, ${edge1} 70%)`,\n `radial-gradient(circle at ${x3}% ${y3}%, ${palette[2]} 0%, ${edge2} 70%)`,\n ].join(\", \");\n}\n\n/**\n * Apply will-change optimization for animations\n */\nexport function getWillChangeProperty(\n hasAnimation: boolean,\n hasHover: boolean\n): string | undefined {\n if (!(hasAnimation || hasHover)) {\n return undefined;\n }\n const properties: string[] = [];\n if (hasAnimation) {\n properties.push(\"opacity\");\n }\n if (hasHover) {\n properties.push(\"transform\");\n }\n return properties.join(\", \");\n}\n\n/**\n * Check if user prefers reduced motion\n */\nexport function prefersReducedMotion(): boolean {\n if (typeof window === \"undefined\") {\n return false;\n }\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n}\n\n// ─── Profile Picture Group Utilities ─────────────────────────────────────────\n\nimport type { GroupUserData, PresenceStatus, StackDirection } from \"./types\";\nimport { GROUP_DEFAULTS } from \"./types\";\n\n/**\n * Calculate the pixel size for group avatars\n */\nexport function getGroupAvatarSize(size: Size | number): number {\n if (typeof size === \"number\") {\n return size;\n }\n return SIZE_MAP[size] ?? SIZE_MAP[GROUP_DEFAULTS.size];\n}\n\n/**\n * Calculate visible and hidden avatar counts\n */\nexport function calculateAvatarCounts(\n total: number,\n max: number,\n showAddButton: boolean\n): { visible: number; hidden: number; showCounter: boolean } {\n const effectiveMax = showAddButton ? max - 1 : max;\n\n if (total <= effectiveMax) {\n return { visible: total, hidden: 0, showCounter: false };\n }\n\n // Show (max - 1) avatars + counter\n const visible = effectiveMax - 1;\n const hidden = total - visible;\n return { visible, hidden, showCounter: true };\n}\n\n/**\n * Calculate position offset for stacked avatars\n */\nexport function calculateStackPosition(\n index: number,\n avatarSize: number,\n overlap: number,\n _direction: StackDirection,\n spacing?: number\n): number {\n const step = spacing ?? avatarSize * (1 - overlap);\n const offset = index * step;\n\n // For RTL, we need to reverse the positioning\n // This is handled at the component level by reversing the order\n return offset;\n}\n\n/**\n * Calculate z-index for stacked avatars\n * First avatar (index 0) has highest z-index to appear on top\n */\nexport function calculateStackZIndex(\n index: number,\n total: number,\n direction: StackDirection\n): number {\n if (direction === \"ltr\") {\n // LTR: First item on top (highest z-index)\n return total - index;\n }\n // RTL: Last item on top\n return index + 1;\n}\n\n/**\n * Calculate the total width of the stacked group\n */\nexport function calculateGroupWidth(\n count: number,\n avatarSize: number,\n overlap: number,\n spacing?: number\n): number {\n if (count === 0) {\n return 0;\n }\n if (count === 1) {\n return avatarSize;\n }\n\n const step = spacing ?? avatarSize * (1 - overlap);\n return avatarSize + step * (count - 1);\n}\n\n/**\n * Extract user data from a profile-picture element\n */\nexport function extractUserData(\n element: HTMLElement,\n index: number\n): GroupUserData {\n return {\n id: element.getAttribute(\"data-user-id\") ?? undefined,\n name: element.getAttribute(\"alt\") ?? `User ${index + 1}`,\n src: element.getAttribute(\"src\") ?? undefined,\n status:\n (element.getAttribute(\"data-status\") as PresenceStatus) ?? undefined,\n element,\n index,\n };\n}\n\n/**\n * Extract all user data from child profile-picture elements\n */\nexport function extractAllUserData(container: HTMLElement): GroupUserData[] {\n const children = container.querySelectorAll(\"profile-picture\");\n return Array.from(children).map((el, index) =>\n extractUserData(el as HTMLElement, index)\n );\n}\n\n/**\n * Get initials for counter display (e.g., \"+5\")\n */\nexport function formatCounterText(count: number): string {\n if (count > 99) {\n return \"+99\";\n }\n return `+${count}`;\n}\n\n/**\n * Calculate tooltip position relative to avatar\n */\nexport function calculateTooltipPosition(\n avatarRect: DOMRect,\n tooltipWidth: number,\n tooltipHeight: number,\n position: \"top\" | \"bottom\" | \"left\" | \"right\" = \"top\",\n gap = 8\n): { top: number; left: number } {\n const { top, left, width, height } = avatarRect;\n const centerX = left + width / 2;\n const centerY = top + height / 2;\n\n switch (position) {\n case \"top\":\n return {\n top: top - tooltipHeight - gap,\n left: centerX - tooltipWidth / 2,\n };\n case \"bottom\":\n return {\n top: top + height + gap,\n left: centerX - tooltipWidth / 2,\n };\n case \"left\":\n return {\n top: centerY - tooltipHeight / 2,\n left: left - tooltipWidth - gap,\n };\n case \"right\":\n return {\n top: centerY - tooltipHeight / 2,\n left: left + width + gap,\n };\n }\n}\n\n/**\n * Clamp tooltip position within viewport\n */\nexport function clampTooltipPosition(\n position: { top: number; left: number },\n tooltipWidth: number,\n tooltipHeight: number,\n padding = 8\n): { top: number; left: number } {\n const viewport = {\n width: typeof window !== \"undefined\" ? window.innerWidth : 1920,\n height: typeof window !== \"undefined\" ? window.innerHeight : 1080,\n };\n\n return {\n top: clamp(\n position.top,\n padding,\n viewport.height - tooltipHeight - padding\n ),\n left: clamp(\n position.left,\n padding,\n viewport.width - tooltipWidth - padding\n ),\n };\n}\n\n/**\n * Get CDN size label from pixel size (rounds up to next available size)\n * CDN sizes: 80, 120, 240, 480, 960\n */\nexport function getCdnSizeLabel(\n pixelSize: number\n): \"80\" | \"120\" | \"240\" | \"480\" | \"960\" {\n if (pixelSize <= 80) {\n return \"120\";\n }\n if (pixelSize <= 120) {\n return \"240\";\n }\n if (pixelSize <= 240) {\n return \"480\";\n }\n if (pixelSize <= 480) {\n return \"960\";\n }\n return \"960\";\n}\n\n/**\n * Construct CDN URL for profile picture\n * Format: {baseUrl}/api/profile-picture/cdn/{extId}_{size}_{imageMode}.webp?hostname={hostname}\n * @param imageMode - \"transparent\" for transparent background, \"original\" for original background\n */\nexport function constructCdnUrl(\n baseUrl: string,\n extCustomerId: string,\n sizeLabel: \"80\" | \"120\" | \"240\" | \"480\" | \"960\",\n imageMode: \"transparent\" | \"original\",\n hostname: string\n): string {\n // Remove trailing slash from baseUrl\n const cleanBaseUrl = baseUrl.endsWith(\"/\") ? baseUrl.slice(0, -1) : baseUrl;\n\n // Construct filename: {extId}_{size}_{imageMode}.webp\n const filename = `${extCustomerId}_${sizeLabel}_${imageMode}.webp`;\n\n // Construct full URL with hostname query parameter\n return `${cleanBaseUrl}/profile-picture/cdn/${filename}?hostname=${hostname}`;\n}\n","/**\n * Profile Picture Component - Styles & Animations\n * Apple-inspired design system with modern 2025 aesthetics\n */\n\nimport type { ShadowPreset, Variant } from \"./types\";\nimport { RADIUS_MAP, SHADOW_MAP } from \"./types\";\nimport { isHexColor } from \"./utils\";\n\n/**\n * Get variant-specific border radius styles\n */\nexport function getVariantStyles(variant: Variant): Record<string, string> {\n return { borderRadius: RADIUS_MAP[variant] };\n}\n\n/**\n * Get variant classes (Tailwind)\n */\nexport function getVariantClasses(variant: Variant): string {\n const variants: Record<Variant, string> = {\n circle: \"np:rounded-full\",\n rounded: \"np:rounded-xl\",\n squircle: \"np:rounded-[30%]\",\n square: \"np:rounded-none\",\n };\n return variants[variant];\n}\n\n/**\n * Get border styles\n */\nexport function getBorderClasses(\n width: 1 | 2 | 3 | 4 | 5 | 6 | 8,\n color: string\n): { className: string; style: Record<string, string> } {\n const widthClasses: Record<1 | 2 | 3 | 4 | 5 | 6 | 8, string> = {\n 1: \"np:border\",\n 2: \"np:border-2\",\n 3: \"np:border-[3px]\",\n 4: \"np:border-4\",\n 5: \"np:border-[5px]\",\n 6: \"np:border-[6px]\",\n 8: \"np:border-8\",\n };\n\n return {\n className: widthClasses[width],\n style: {\n borderColor: color,\n borderStyle: \"solid\",\n },\n };\n}\n\n/**\n * Get background styles (solid color or gradient)\n */\nexport function getBackgroundStyles(\n bgColor?: string,\n bgGradient?: string\n): { className: string; style?: Record<string, string> } {\n if (bgGradient) {\n return {\n className: \"\",\n style: { background: bgGradient },\n };\n }\n\n if (bgColor) {\n if (bgColor.includes(\"gradient\")) {\n return {\n className: \"\",\n style: { background: bgColor },\n };\n }\n return {\n className: \"\",\n style: { backgroundColor: bgColor },\n };\n }\n\n return { className: \"\", style: { backgroundColor: \"transparent\" } };\n}\n\n/**\n * Get shadow styles\n */\nexport function getShadowStyles(shadow: ShadowPreset): Record<string, string> {\n return { boxShadow: SHADOW_MAP[shadow] };\n}\n\n/**\n * CSS Keyframe animations - Apple-inspired, physics-based\n */\nexport const keyframes = {\n // Shimmer loading effect\n shimmer: `\n@keyframes pp-shimmer {\n 0% { transform: translateX(-100%); }\n 100% { transform: translateX(100%); }\n}`,\n\n // Pulse animation (gentle breathe effect)\n pulse: `\n@keyframes pp-pulse {\n 0%, 100% { opacity: 1; transform: scale(1); }\n 50% { opacity: 0.7; transform: scale(0.98); }\n}`,\n\n // Skeleton loading pulse\n skeleton: `\n@keyframes pp-skeleton {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n}`,\n\n // Badge bounce entrance\n badgeBounce: `\n@keyframes pp-badge-bounce {\n 0% { transform: scale(0) translateY(10px); opacity: 0; }\n 50% { transform: scale(1.2) translateY(-2px); }\n 100% { transform: scale(1) translateY(0); opacity: 1; }\n}`,\n\n // Ring rotation (for gradient rings)\n ringRotate: `\n@keyframes pp-ring-rotate {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n}`,\n\n // Presence indicator pulse\n presencePulse: `\n@keyframes pp-presence-pulse {\n 0%, 100% { box-shadow: 0 0 0 0 currentColor; }\n 50% { box-shadow: 0 0 0 4px transparent; }\n}`,\n\n // Glow animation\n glow: `\n@keyframes pp-glow {\n 0%, 100% { box-shadow: 0 0 20px 0 var(--pp-glow-color, rgba(99, 102, 241, 0.3)); }\n 50% { box-shadow: 0 0 30px 5px var(--pp-glow-color, rgba(99, 102, 241, 0.5)); }\n}`,\n\n // Fade in\n fadeIn: `\n@keyframes pp-fade-in {\n from { opacity: 0; }\n to { opacity: 1; }\n}`,\n\n // Scale in (spring-like)\n scaleIn: `\n@keyframes pp-scale-in {\n 0% { transform: scale(0.8); opacity: 0; }\n 50% { transform: scale(1.05); }\n 100% { transform: scale(1); opacity: 1; }\n}`,\n};\n\n/**\n * All keyframes combined for injection\n */\nexport const allKeyframes = Object.values(keyframes).join(\"\\n\");\n\n/**\n * Component base styles\n */\nexport const baseStyles = `\n/* Profile Picture Component Styles */\n.pp-container {\n --pp-transition-duration: 200ms;\n --pp-transition-timing: cubic-bezier(0.4, 0, 0.2, 1);\n --pp-spring-timing: cubic-bezier(0.34, 1.56, 0.64, 1);\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n user-select: none;\n -webkit-user-select: none;\n flex-shrink: 0;\n}\n\n/* Inner container for image clipping - allows badges/rings to overflow */\n/* Background is applied here (not on container) to prevent sub-pixel bleed-through */\n.pp-inner {\n position: absolute;\n inset: 0;\n overflow: hidden;\n border-radius: inherit;\n}\n\n/* Interactive states */\n.pp-interactive {\n cursor: pointer;\n transition: transform var(--pp-transition-duration) var(--pp-spring-timing),\n box-shadow var(--pp-transition-duration) var(--pp-transition-timing);\n}\n\n.pp-interactive:hover {\n transform: scale(1.05);\n}\n\n.pp-interactive:active {\n transform: scale(0.95);\n}\n\n.pp-interactive:focus-visible {\n outline: none;\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.5);\n}\n\n/* Image styles */\n.pp-image {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n object-fit: cover;\n transition: opacity var(--pp-transition-duration) var(--pp-transition-timing);\n}\n\n.pp-image-loading {\n opacity: 0;\n}\n\n.pp-image-loaded {\n opacity: 1;\n}\n\n/* Fallback styles */\n.pp-fallback {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n font-weight: 500;\n color: rgba(255, 255, 255, 0.9);\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);\n font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Segoe UI', Roboto, sans-serif;\n letter-spacing: 0.02em;\n}\n\n.pp-fallback-icon {\n color: rgba(156, 163, 175, 0.8);\n}\n\n/* Shimmer placeholder */\n.pp-shimmer {\n position: absolute;\n inset: 0;\n overflow: hidden;\n}\n\n.pp-shimmer::after {\n content: '';\n position: absolute;\n inset: 0;\n background: linear-gradient(\n 90deg,\n transparent 0%,\n rgba(255, 255, 255, 0.4) 50%,\n transparent 100%\n );\n animation: pp-shimmer 1.5s infinite;\n}\n\n/* Pulse placeholder */\n.pp-pulse {\n animation: pp-pulse 2s ease-in-out infinite;\n}\n\n/* Skeleton placeholder */\n.pp-skeleton {\n background: linear-gradient(90deg, #e5e7eb 0%, #f3f4f6 50%, #e5e7eb 100%);\n background-size: 200% 100%;\n animation: pp-skeleton 1.5s ease-in-out infinite;\n}\n\n/* Badge styles */\n.pp-badge {\n position: absolute;\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 600;\n font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', sans-serif;\n line-height: 1;\n animation: pp-badge-bounce 0.4s var(--pp-spring-timing);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);\n}\n\n.pp-badge-with-icon {\n gap: 4px;\n}\n\n.pp-badge-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n flex-shrink: 0;\n}\n\n.pp-badge-pulse {\n animation: pp-badge-bounce 0.4s var(--pp-spring-timing),\n pp-presence-pulse 2s ease-in-out infinite 0.4s;\n}\n\n.pp-badge-glow {\n box-shadow: 0 0 10px 2px var(--pp-badge-glow-color, currentColor);\n}\n\n/* Ring effect (Instagram-style) */\n.pp-ring {\n position: absolute;\n inset: -4px;\n border-radius: inherit;\n padding: 3px;\n background: var(--pp-ring-color, linear-gradient(45deg, #f09433, #e6683c, #dc2743, #cc2366, #bc1888));\n -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);\n mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);\n -webkit-mask-composite: xor;\n mask-composite: exclude;\n transition: background 0.3s ease;\n}\n\n.pp-ring-animated {\n animation: pp-ring-rotate 3s linear infinite;\n}\n\n.pp-ring-progress {\n /* Progress rings should not animate rotation */\n animation: none;\n}\n\n/* Presence indicator */\n.pp-presence {\n position: absolute;\n bottom: 0;\n right: 0;\n border-radius: 9999px;\n border: 2px solid white;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);\n}\n\n.pp-presence-animated {\n animation: pp-presence-pulse 2s ease-in-out infinite;\n}\n\n/* Glow effect */\n.pp-glow {\n animation: pp-glow 2s ease-in-out infinite;\n}\n\n/* Reduced motion support */\n@media (prefers-reduced-motion: reduce) {\n .pp-container,\n .pp-interactive,\n .pp-image,\n .pp-shimmer::after,\n .pp-pulse,\n .pp-skeleton,\n .pp-badge,\n .pp-ring-animated,\n .pp-presence-animated,\n .pp-glow {\n animation: none !important;\n transition: none !important;\n }\n}\n`;\n\n/**\n * All styles combined (keyframes + base styles)\n */\nexport const componentStyles = `${allKeyframes}\\n${baseStyles}`;\n\n/**\n * Shimmer styles for inline injection (legacy support)\n */\nexport const shimmerStyles = `\n@keyframes np-shimmer {\n 0% { background-position: -200% 0; }\n 100% { background-position: 200% 0; }\n}\n.np-shimmer {\n background: linear-gradient(90deg, transparent 0%, rgba(255,255,255,0.4) 50%, transparent 100%);\n background-size: 200% 100%;\n animation: np-shimmer 1.5s infinite;\n}\n`;\n\n/**\n * Generate glow shadow with custom color\n */\nexport function getGlowShadow(color: string, intensity = 0.3): string {\n if (isHexColor(color)) {\n // Convert hex to rgba\n const r = Number.parseInt(color.slice(1, 3), 16);\n const g = Number.parseInt(color.slice(3, 5), 16);\n const b = Number.parseInt(color.slice(5, 7), 16);\n return `0 0 20px 0 rgba(${r}, ${g}, ${b}, ${intensity})`;\n }\n return `0 0 20px 0 ${color}`;\n}\n\n/**\n * Get shimmer classes (legacy)\n */\nexport function getShimmerClasses(): string {\n return \"np-shimmer\";\n}\n\n// ─── Profile Picture Group Styles ────────────────────────────────────────────\n\n/**\n * Group component keyframe animations\n */\nexport const groupKeyframes = `\n@keyframes ppg-tooltip-in {\n from {\n opacity: 0;\n transform: translateX(-50%) translateY(4px) scale(0.96);\n }\n to {\n opacity: 1;\n transform: translateX(-50%) translateY(0) scale(1);\n }\n}\n\n@keyframes ppg-dropdown-in {\n from {\n opacity: 0;\n transform: translateY(-6px) scale(0.95);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n}\n\n@keyframes ppg-avatar-lift {\n from {\n transform: translateY(0) scale(1);\n }\n to {\n transform: translateY(-4px) scale(1.08);\n }\n}\n\n@keyframes ppg-modal-in {\n from {\n opacity: 0;\n transform: translate(-50%, -50%) scale(0.9);\n }\n to {\n opacity: 1;\n transform: translate(-50%, -50%) scale(1);\n }\n}\n\n@keyframes ppg-backdrop-in {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n`;\n\n/**\n * Group component base styles - Apple-inspired\n */\nexport const groupBaseStyles = `\n/* Profile Picture Group Container */\n.ppg-container {\n --ppg-transition: 200ms cubic-bezier(0.4, 0, 0.2, 1);\n --ppg-spring: 300ms cubic-bezier(0.34, 1.56, 0.64, 1);\n --ppg-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);\n --ppg-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.1);\n --ppg-shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.15);\n --ppg-radius: 12px;\n --ppg-counter-bg: #f5f5f7;\n --ppg-counter-text: #1d1d1f;\n --ppg-add-bg: #f5f5f7;\n --ppg-add-hover: #e8e8ed;\n --ppg-add-icon: #86868b;\n --ppg-border: rgba(0, 0, 0, 0.08);\n --ppg-tooltip-bg: rgba(29, 29, 31, 0.95);\n --ppg-tooltip-text: #ffffff;\n --ppg-dropdown-bg: #ffffff;\n --ppg-dropdown-hover: #f5f5f7;\n\n position: relative;\n display: inline-flex;\n align-items: center;\n isolation: isolate;\n}\n\n/* Avatar wrapper for positioning */\n.ppg-avatar-wrapper {\n position: absolute;\n top: 0;\n transition: transform var(--ppg-spring), z-index 0s;\n cursor: pointer;\n border-radius: 9999px;\n}\n\n.ppg-avatar-wrapper:focus-visible {\n outline: none;\n box-shadow: 0 0 0 3px rgba(0, 122, 255, 0.4);\n}\n\n/* Hover lift animation */\n.ppg-animated .ppg-avatar-wrapper:hover {\n z-index: 100 !important;\n animation: ppg-avatar-lift var(--ppg-spring) forwards;\n}\n\n.ppg-avatar-wrapper:hover {\n z-index: 100 !important;\n}\n\n/* Nested profile-picture styling */\n.ppg-avatar-wrapper profile-picture {\n display: block;\n width: 100%;\n height: 100%;\n border-radius: inherit;\n}\n\n/* Counter button */\n.ppg-counter {\n position: absolute;\n top: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 9999px;\n background: var(--ppg-counter-bg);\n color: var(--ppg-counter-text);\n font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Display', sans-serif;\n font-weight: 600;\n font-size: 13px;\n letter-spacing: -0.01em;\n cursor: pointer;\n border: none;\n box-shadow: 0 0 0 1.5px rgba(255, 255, 255, 0.95), var(--ppg-shadow-sm);\n transition: transform var(--ppg-spring), background-color var(--ppg-transition);\n user-select: none;\n -webkit-user-select: none;\n}\n\n.ppg-counter:hover {\n background: #ebebed;\n transform: scale(1.05);\n}\n\n.ppg-counter:active {\n transform: scale(0.98);\n}\n\n.ppg-counter:focus-visible {\n outline: none;\n box-shadow: 0 0 0 1.5px rgba(255, 255, 255, 0.95), 0 0 0 4px rgba(0, 122, 255, 0.4);\n}\n\n/* Add button */\n.ppg-add-button {\n position: absolute;\n top: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 9999px;\n background: var(--ppg-add-bg);\n border: 2px dashed var(--ppg-border);\n cursor: pointer;\n transition: all var(--ppg-spring);\n box-shadow: var(--ppg-shadow-sm);\n}\n\n.ppg-add-button:hover {\n background: var(--ppg-add-hover);\n border-color: rgba(0, 0, 0, 0.15);\n transform: scale(1.05);\n}\n\n.ppg-add-button:active {\n transform: scale(0.98);\n}\n\n.ppg-add-button:focus-visible {\n outline: none;\n box-shadow: 0 0 0 3px rgba(0, 122, 255, 0.4);\n}\n\n.ppg-add-icon {\n color: var(--ppg-add-icon);\n transition: color var(--ppg-transition);\n}\n\n.ppg-add-button:hover .ppg-add-icon {\n color: #1d1d1f;\n}\n\n/* Tooltip */\n.ppg-tooltip {\n position: absolute;\n z-index: 9999;\n padding: 6px 12px;\n background: var(--ppg-tooltip-bg);\n color: var(--ppg-tooltip-text);\n font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', sans-serif;\n font-size: 13px;\n font-weight: 500;\n border-radius: 8px;\n box-shadow: var(--ppg-shadow-lg);\n pointer-events: none;\n white-space: nowrap;\n transform: translateX(-50%);\n animation: ppg-tooltip-in 150ms ease-out forwards;\n backdrop-filter: blur(20px);\n -webkit-backdrop-filter: blur(20px);\n}\n\n.ppg-tooltip::after {\n content: '';\n position: absolute;\n width: 8px;\n height: 8px;\n background: inherit;\n transform: rotate(45deg);\n}\n\n.ppg-tooltip[data-position=\"top\"]::after {\n bottom: -4px;\n left: 50%;\n margin-left: -4px;\n}\n\n.ppg-tooltip[data-position=\"bottom\"]::after {\n top: -4px;\n left: 50%;\n margin-left: -4px;\n}\n\n/* Dropdown */\n.ppg-dropdown {\n position: absolute;\n z-index: 9998;\n right: 0;\n min-width: 220px;\n max-width: 300px;\n background: var(--ppg-dropdown-bg);\n border-radius: 14px;\n box-shadow:\n 0 4px 24px rgba(0, 0, 0, 0.12),\n 0 1px 4px rgba(0, 0, 0, 0.08),\n 0 0 0 1px var(--ppg-border);\n overflow: hidden;\n animation: ppg-dropdown-in 200ms cubic-bezier(0.32, 0.72, 0, 1) forwards;\n transform-origin: top right;\n backdrop-filter: blur(20px);\n -webkit-backdrop-filter: blur(20px);\n}\n\n.ppg-dropdown[data-position=\"bottom\"] {\n top: calc(100% + 10px);\n}\n\n.ppg-dropdown[data-position=\"top\"] {\n bottom: calc(100% + 10px);\n transform-origin: bottom right;\n}\n\n/* Modal style for mobile */\n.ppg-dropdown[data-position=\"modal\"] {\n transform-origin: center center;\n animation: ppg-modal-in 250ms cubic-bezier(0.32, 0.72, 0, 1) forwards;\n border-radius: 20px;\n}\n\n.ppg-backdrop-visible {\n background: rgba(0, 0, 0, 0.4);\n animation: ppg-backdrop-in 200ms ease-out forwards;\n}\n\n.ppg-dropdown-header {\n padding: 14px 16px 10px;\n font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;\n font-size: 11px;\n font-weight: 600;\n color: #86868b;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n background: linear-gradient(to bottom, rgba(0,0,0,0.02), transparent);\n}\n\n.ppg-dropdown-list {\n overflow-y: auto;\n padding: 6px;\n scrollbar-width: thin;\n scrollbar-color: rgba(0,0,0,0.2) transparent;\n}\n\n.ppg-dropdown-list::-webkit-scrollbar {\n width: 6px;\n}\n\n.ppg-dropdown-list::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.ppg-dropdown-list::-webkit-scrollbar-thumb {\n background: rgba(0,0,0,0.15);\n border-radius: 3px;\n}\n\n.ppg-dropdown-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n cursor: pointer;\n border-radius: 10px;\n transition: all 150ms ease;\n margin: 2px 0;\n}\n\n.ppg-dropdown-item:hover {\n background: var(--ppg-dropdown-hover);\n transform: translateX(2px);\n}\n\n.ppg-dropdown-item:focus-visible {\n outline: none;\n background: var(--ppg-dropdown-hover);\n box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.4);\n}\n\n.ppg-dropdown-item:active {\n transform: scale(0.98);\n}\n\n.ppg-dropdown-avatar {\n flex-shrink: 0;\n width: 36px;\n height: 36px;\n border-radius: 9999px;\n object-fit: cover;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n border: 2px solid rgba(255, 255, 255, 0.8);\n}\n\n.ppg-dropdown-avatar-fallback {\n flex-shrink: 0;\n width: 36px;\n height: 36px;\n border-radius: 9999px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Display', system-ui, sans-serif;\n font-size: 13px;\n font-weight: 600;\n color: white;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n border: 2px solid rgba(255, 255, 255, 0.3);\n}\n\n.ppg-dropdown-info {\n flex: 1;\n min-width: 0;\n padding-right: 4px;\n text-align: left;\n}\n\n.ppg-dropdown-name {\n font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;\n font-size: 14px;\n font-weight: 500;\n color: #1d1d1f;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n line-height: 1.3;\n text-align: left;\n}\n\n.ppg-dropdown-status {\n display: flex;\n align-items: center;\n gap: 5px;\n font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;\n font-size: 12px;\n color: #86868b;\n margin-top: 2px;\n line-height: 1.2;\n}\n\n.ppg-dropdown-presence {\n width: 7px;\n height: 7px;\n border-radius: 9999px;\n flex-shrink: 0;\n box-shadow: 0 0 0 1.5px var(--ppg-dropdown-bg);\n}\n\n.ppg-dropdown-presence[data-status=\"online\"] {\n background: #30D158;\n box-shadow: 0 0 0 1.5px var(--ppg-dropdown-bg), 0 0 6px rgba(48, 209, 88, 0.5);\n}\n\n.ppg-dropdown-presence[data-status=\"away\"] {\n background: #FFD60A;\n}\n\n.ppg-dropdown-presence[data-status=\"busy\"],\n.ppg-dropdown-presence[data-status=\"dnd\"] {\n background: #FF453A;\n}\n\n.ppg-dropdown-presence[data-status=\"offline\"] {\n background: #8E8E93;\n}\n\n/* Backdrop for dropdown */\n.ppg-backdrop {\n position: fixed;\n inset: 0;\n z-index: 9997;\n}\n\n/* Reduced motion */\n@media (prefers-reduced-motion: reduce) {\n .ppg-container,\n .ppg-avatar-wrapper,\n .ppg-counter,\n .ppg-add-button,\n .ppg-tooltip,\n .ppg-dropdown {\n animation: none !important;\n transition: none !important;\n }\n\n .ppg-animated .ppg-avatar-wrapper:hover {\n animation: none !important;\n transform: none !important;\n }\n}\n\n/* Dark mode support */\n@media (prefers-color-scheme: dark) {\n .ppg-container {\n --ppg-counter-bg: #2c2c2e;\n --ppg-counter-text: #ffffff;\n --ppg-add-bg: #2c2c2e;\n --ppg-add-hover: #3a3a3c;\n --ppg-add-icon: #98989d;\n --ppg-border: rgba(255, 255, 255, 0.1);\n --ppg-dropdown-bg: #2c2c2e;\n --ppg-dropdown-hover: #3a3a3c;\n }\n\n .ppg-avatar-wrapper profile-picture {\n box-shadow: 0 0 6px 1.5px rgb(28 28 30 / 16%), var(--ppg-shadow-sm);\n }\n\n .ppg-counter {\n box-shadow: 0 0 0 1.5px rgba(28, 28, 30, 0.95), var(--ppg-shadow-sm);\n }\n\n .ppg-counter:hover {\n background: #3a3a3c;\n }\n\n .ppg-dropdown {\n background: rgba(44, 44, 46, 0.95);\n box-shadow:\n 0 4px 24px rgba(0, 0, 0, 0.4),\n 0 1px 4px rgba(0, 0, 0, 0.2),\n 0 0 0 1px rgba(255, 255, 255, 0.08);\n }\n\n .ppg-dropdown-name {\n color: #ffffff;\n }\n\n .ppg-dropdown-header {\n color: #98989d;\n background: linear-gradient(to bottom, rgba(255,255,255,0.03), transparent);\n }\n\n .ppg-dropdown-avatar {\n border-color: rgba(255, 255, 255, 0.15);\n }\n\n .ppg-dropdown-avatar-fallback {\n border-color: rgba(255, 255, 255, 0.1);\n }\n\n .ppg-dropdown-list {\n scrollbar-color: rgba(255,255,255,0.35) transparent;\n }\n\n .ppg-dropdown-list::-webkit-scrollbar-thumb {\n background: rgba(255,255,255,0.35);\n }\n\n .ppg-dropdown-presence {\n box-shadow: 0 0 0 1.5px rgba(44, 44, 46, 0.95);\n }\n\n .ppg-dropdown-presence[data-status=\"online\"] {\n box-shadow: 0 0 0 1.5px rgba(44, 44, 46, 0.95), 0 0 6px rgba(48, 209, 88, 0.5);\n }\n}\n`;\n\n/**\n * All group styles combined\n */\nexport const groupStyles = `${groupKeyframes}\\n${groupBaseStyles}`;\n","/**\n * ProfilePicture Web Component\n * Apple-inspired design system with modern 2025 aesthetics\n *\n * A lightweight, framework-agnostic profile picture component\n * with advanced features: presence indicators, rings, and badges.\n */\n\nimport { html, LitElement, nothing } from \"lit\";\nimport { property, state } from \"lit/decorators.js\";\nimport { styleMap } from \"lit/directives/style-map.js\";\nimport {\n componentStyles,\n getBackgroundStyles,\n getBorderClasses,\n getGlowShadow,\n getShadowStyles,\n getVariantClasses,\n shimmerStyles,\n} from \"./styles\";\nimport type {\n BadgeConfig,\n GlowConfig,\n InteractionConfig,\n LoadingStrategy,\n PlaceholderType,\n Position,\n PresenceConfig,\n RingConfig,\n ShadowPreset,\n Size,\n Variant,\n} from \"./types\";\nimport { DEFAULTS, PRESENCE_COLORS, RADIUS_MAP, SIZE_MAP } from \"./types\";\nimport {\n cn,\n constructCdnUrl,\n createConicGradient,\n createProgressRingGradient,\n formatBadgeContent,\n generateAvatarGradient,\n generateCloudyGradient,\n getBadgeSize,\n getCdnSizeLabel,\n getInitials,\n getInitialsFontSize,\n getPresenceSize,\n} from \"./utils\";\n\nexport class ProfilePicture extends LitElement {\n private static stylesInjected = false;\n private static cdnBaseUrl = \"\";\n private static instances = new Set<ProfilePicture>();\n\n /**\n * Set global CDN base URL for all ProfilePicture instances\n * @example ProfilePicture.setCdnBaseUrl('https://api.example.com')\n */\n public static setCdnBaseUrl(url: string): void {\n ProfilePicture.cdnBaseUrl = url;\n // Notify all existing instances to reload if they have extCustomerId\n ProfilePicture.instances.forEach((instance) => {\n if (instance.extCustomerId && !instance.cdnImageUrl) {\n // Reset failure state (CDN base URL change = legitimate retry)\n instance.cdnLoadFailed = false;\n // Clear any scheduled retry\n if (instance.retryTimeoutId) {\n clearTimeout(instance.retryTimeoutId);\n instance.retryTimeoutId = undefined;\n }\n if (!instance.previousExtCustomerId) {\n instance.previousExtCustomerId = instance.extCustomerId;\n }\n instance.loadCdnImage();\n }\n });\n }\n\n /**\n * Get current CDN base URL\n */\n public static getCdnBaseUrl(): string {\n return ProfilePicture.cdnBaseUrl;\n }\n\n // Use Light DOM for Tailwind compatibility\n protected createRenderRoot() {\n ProfilePicture.injectStylesOnce();\n return this;\n }\n\n private static injectStylesOnce() {\n if (ProfilePicture.stylesInjected || typeof document === \"undefined\") {\n return;\n }\n\n // Defer style injection to avoid hydration mismatch in SSR frameworks\n const defer =\n typeof requestIdleCallback !== \"undefined\"\n ? requestIdleCallback\n : (cb: () => void) => setTimeout(cb, 1);\n\n defer(() => {\n // Re-check in case another instance already injected\n if (ProfilePicture.stylesInjected) {\n return;\n }\n const style = document.createElement(\"style\");\n style.textContent = componentStyles;\n document.head.appendChild(style);\n ProfilePicture.stylesInjected = true;\n });\n }\n\n // ─── Core Properties ────────────────────────────────────────────────────────\n @property({ type: String }) src = \"\";\n @property({ type: String }) alt = \"\";\n @property({ type: String, attribute: \"ext-customer-id\" })\n extCustomerId?: string;\n\n // ─── Sizing ─────────────────────────────────────────────────────────────────\n @property({ type: String }) size: Size | string = DEFAULTS.size;\n\n // ─── Visual Variant ─────────────────────────────────────────────────────────\n @property({ type: String }) variant: Variant = DEFAULTS.variant;\n\n // ─── Shadow ─────────────────────────────────────────────────────────────────\n @property({ type: String }) shadow: ShadowPreset = DEFAULTS.shadow;\n\n // ─── Border ─────────────────────────────────────────────────────────────────\n @property({ type: Boolean }) border = false;\n @property({ type: Number, attribute: \"border-width\" }) borderWidth:\n | 1\n | 2\n | 3\n | 4\n | 5\n | 6\n | 8 = DEFAULTS.borderWidth;\n @property({ type: String, attribute: \"border-color\" }) borderColor: string =\n DEFAULTS.borderColor;\n\n // ─── Rotation ───────────────────────────────────────────────────────────────\n @property({ type: Number }) rotation = 0;\n\n // ─── Zoom ─────────────────────────────────────────────────────────────────\n @property({ type: Number }) zoom: number = DEFAULTS.zoom;\n\n // ─── Background ─────────────────────────────────────────────────────────────\n @property({ type: String, attribute: \"bg-color\" }) bgColor?: string;\n @property({ type: String, attribute: \"bg-gradient\" }) bgGradient?: string;\n\n // ─── Ring Effect (Instagram-style) ──────────────────────────────────────────\n @property({\n type: Object,\n attribute: \"ring\",\n converter: {\n fromAttribute: (value: string | null): RingConfig | undefined => {\n if (!value) return undefined;\n try {\n return JSON.parse(value) as RingConfig;\n } catch {\n return undefined;\n }\n },\n toAttribute: (value: RingConfig | undefined): string | null => {\n return value ? JSON.stringify(value) : null;\n },\n },\n })\n ring?: RingConfig;\n\n // ─── Presence Indicator ─────────────────────────────────────────────────────\n @property({\n type: Object,\n attribute: \"presence\",\n converter: {\n fromAttribute: (value: string | null): PresenceConfig | undefined => {\n if (!value) return undefined;\n try {\n return JSON.parse(value) as PresenceConfig;\n } catch {\n return undefined;\n }\n },\n toAttribute: (value: PresenceConfig | undefined): string | null => {\n return value ? JSON.stringify(value) : null;\n },\n },\n })\n presence?: PresenceConfig;\n\n // ─── Glow Effect ────────────────────────────────────────────────────────────\n @property({\n type: Object,\n attribute: \"glow\",\n converter: {\n fromAttribute: (value: string | null): GlowConfig | undefined => {\n if (!value) return undefined;\n try {\n return JSON.parse(value) as GlowConfig;\n } catch {\n return undefined;\n }\n },\n toAttribute: (value: GlowConfig | undefined): string | null => {\n return value ? JSON.stringify(value) : null;\n },\n },\n })\n glow?: GlowConfig;\n\n // ─── Badge ──────────────────────────────────────────────────────────────────\n @property({\n type: Object,\n attribute: \"badge\",\n converter: {\n fromAttribute: (value: string | null): BadgeConfig | undefined => {\n if (!value) return undefined;\n try {\n return JSON.parse(value) as BadgeConfig;\n } catch {\n return undefined;\n }\n },\n toAttribute: (value: BadgeConfig | undefined): string | null => {\n return value ? JSON.stringify(value) : null;\n },\n },\n })\n badge?: BadgeConfig;\n\n // ─── Loading & Performance ──────────────────────────────────────────────────\n @property({ type: String }) loading: LoadingStrategy = DEFAULTS.loading;\n @property({ type: String }) placeholder: PlaceholderType =\n DEFAULTS.placeholder;\n @property({ type: String, attribute: \"placeholder-color\" })\n placeholderColor: string = DEFAULTS.placeholderColor;\n\n // ─── Fallback ───────────────────────────────────────────────────────────────\n @property({ type: String }) fallback?: string;\n\n // ─── Fallback Mode ────────────────────────────────────────────────────────\n @property({ type: String, attribute: \"fallback-mode\" })\n fallbackMode?: \"initials\" | \"gradient\";\n\n // ─── Image Mode ────────────────────────────────────────────────────────────\n @property({ type: String, attribute: \"image-mode\" })\n imageMode: \"transparent\" | \"original\" = \"original\";\n\n // ─── Interaction ────────────────────────────────────────────────────────────\n @property({\n type: Object,\n attribute: \"interactive\",\n converter: {\n fromAttribute: (value: string | null): InteractionConfig | undefined => {\n if (!value) return undefined;\n try {\n return JSON.parse(value) as InteractionConfig;\n } catch {\n return undefined;\n }\n },\n toAttribute: (value: InteractionConfig | undefined): string | null => {\n return value ? JSON.stringify(value) : null;\n },\n },\n })\n interactive?: InteractionConfig;\n\n // ─── Internal State ─────────────────────────────────────────────────────────\n @state() private isLoaded = false;\n @state() private hasError = false;\n @state() private cdnImageUrl?: string;\n @state() private cdnLoadFailed = false;\n private previousSrc = \"\";\n private previousExtCustomerId?: string;\n private retryTimeoutId?: ReturnType<typeof setTimeout>;\n private randomSeed = Math.random().toString(36).slice(2);\n private readonly RETRY_DELAY_MS = 30_000; // 30 seconds\n\n /**\n * Safely resolve an object property that may be a JSON string\n * (e.g., when React 19 sets it as a property instead of attribute,\n * bypassing Lit's fromAttribute converter).\n */\n private resolveObjectProp<T>(value: T | string | undefined): T | undefined {\n if (!value) return undefined;\n if (typeof value === \"string\") {\n try {\n return JSON.parse(value) as T;\n } catch {\n return undefined;\n }\n }\n return value;\n }\n\n private get pixelSize(): number {\n const sizeValue = this.size as Size | number;\n return typeof sizeValue === \"number\"\n ? sizeValue\n : (SIZE_MAP[sizeValue as Size] ?? SIZE_MAP[DEFAULTS.size]);\n }\n\n /**\n * Resolve the seed for cloudy gradient from available identifiers.\n * Priority: extCustomerId > alt > src > random instance seed\n */\n private get gradientSeed(): string {\n return this.extCustomerId || this.alt || this.src || this.randomSeed;\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n // Register this instance\n ProfilePicture.instances.add(this);\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n // Unregister this instance\n ProfilePicture.instances.delete(this);\n // Clear any scheduled retry\n if (this.retryTimeoutId) {\n clearTimeout(this.retryTimeoutId);\n this.retryTimeoutId = undefined;\n }\n }\n\n protected firstUpdated(): void {\n // Trigger CDN loading on initial render if extCustomerId is present\n if (this.extCustomerId && ProfilePicture.cdnBaseUrl) {\n this.previousExtCustomerId = this.extCustomerId;\n this.loadCdnImage();\n }\n }\n\n protected updated(changedProperties: Map<string, unknown>): void {\n super.updated(changedProperties);\n // Handle: CDN base URL set AFTER element creation\n // (previousExtCustomerId is only set when firstUpdated or willUpdate triggers a CDN load)\n if (\n this.extCustomerId &&\n ProfilePicture.cdnBaseUrl &&\n !this.cdnImageUrl &&\n !this.previousExtCustomerId\n ) {\n this.previousExtCustomerId = this.extCustomerId;\n this.cdnLoadFailed = false;\n this.loadCdnImage();\n }\n }\n\n protected willUpdate(changedProperties: Map<string, unknown>): void {\n if (changedProperties.has(\"src\") && this.src !== this.previousSrc) {\n this.isLoaded = false;\n this.hasError = false;\n this.previousSrc = this.src;\n }\n\n // Trigger CDN loading when relevant properties change\n const extCustomerIdChanged =\n changedProperties.has(\"extCustomerId\") &&\n this.extCustomerId !== this.previousExtCustomerId;\n const cdnParamsChanged =\n changedProperties.has(\"size\") || changedProperties.has(\"imageMode\");\n\n if (extCustomerIdChanged || (cdnParamsChanged && this.extCustomerId)) {\n this.previousExtCustomerId = this.extCustomerId;\n // Reset CDN state (property change = legitimate reload)\n this.cdnImageUrl = undefined;\n this.cdnLoadFailed = false;\n this.isLoaded = false;\n this.hasError = false;\n // Clear any scheduled retry\n if (this.retryTimeoutId) {\n clearTimeout(this.retryTimeoutId);\n this.retryTimeoutId = undefined;\n }\n // Start CDN loading\n this.loadCdnImage();\n }\n }\n\n private handleLoad() {\n this.isLoaded = true;\n this.dispatchEvent(\n new CustomEvent(\"load\", { bubbles: true, composed: true })\n );\n }\n\n private handleClick(event: MouseEvent) {\n const interactive = this.resolveObjectProp<InteractionConfig>(this.interactive);\n if (!interactive?.pressable) return;\n this.dispatchEvent(\n new CustomEvent(\"profile-picture-click\", {\n bubbles: true,\n composed: true,\n detail: {\n extCustomerId: this.extCustomerId,\n alt: this.alt,\n src: this.src,\n },\n })\n );\n }\n\n private handleKeyDown(event: KeyboardEvent) {\n const interactive = this.resolveObjectProp<InteractionConfig>(this.interactive);\n if (!interactive?.pressable) return;\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n this.handleClick(event as unknown as MouseEvent);\n }\n }\n\n private handleError() {\n // If CDN image failed, mark it and schedule retry\n if (this.cdnImageUrl && !this.cdnLoadFailed) {\n this.cdnLoadFailed = true;\n this.cdnImageUrl = undefined;\n\n // Dispatch CDN error event\n this.dispatchEvent(\n new CustomEvent(\"cdn-error\", {\n bubbles: true,\n composed: true,\n detail: { error: \"Image load failed\" },\n })\n );\n\n // Schedule a retry after delay\n if (this.retryTimeoutId) {\n clearTimeout(this.retryTimeoutId);\n }\n this.retryTimeoutId = setTimeout(() => {\n this.retryTimeoutId = undefined;\n if (this.extCustomerId && ProfilePicture.cdnBaseUrl) {\n this.cdnLoadFailed = false;\n this.hasError = false;\n this.isLoaded = false;\n this.loadCdnImage();\n }\n }, this.RETRY_DELAY_MS);\n\n // Don't mark hasError yet - fallback (src prop) may work\n return;\n }\n\n this.hasError = true;\n this.isLoaded = true;\n this.dispatchEvent(\n new CustomEvent(\"error\", { bubbles: true, composed: true })\n );\n }\n\n /**\n * Construct CDN URL for profile picture using ext-customer-id\n * Uses direct image src binding - browser handles redirects automatically\n */\n private loadCdnImage(): void {\n // Skip if no extCustomerId or no CDN base URL configured\n if (!(this.extCustomerId && ProfilePicture.cdnBaseUrl)) {\n this.cdnLoadFailed = true;\n return;\n }\n\n // Calculate CDN parameters\n const sizeLabel = getCdnSizeLabel(this.pixelSize);\n const hostname =\n typeof window !== \"undefined\" ? window.location.hostname : \"localhost\";\n\n // Set the CDN URL directly - browser will handle redirects via img src\n this.cdnImageUrl = constructCdnUrl(\n ProfilePicture.cdnBaseUrl,\n this.extCustomerId,\n sizeLabel,\n this.imageMode,\n hostname\n );\n }\n\n private getContainerStyles() {\n const bg = getBackgroundStyles(this.bgColor, this.bgGradient);\n const borderStyles = this.border\n ? getBorderClasses(this.borderWidth, this.borderColor)\n : null;\n const shadowStyles = getShadowStyles(this.shadow);\n\n // Handle glow effect\n const glow = this.resolveObjectProp<GlowConfig>(this.glow);\n let glowStyles: Record<string, string> = {};\n if (glow) {\n const glowColor = glow.color ?? this.borderColor ?? \"#6366f1\";\n glowStyles = {\n \"--pp-glow-color\": glowColor,\n boxShadow: getGlowShadow(glowColor, glow.intensity ?? 0.3),\n };\n }\n\n const interactive = this.resolveObjectProp<InteractionConfig>(this.interactive);\n const isInteractive =\n interactive?.hoverable || interactive?.pressable;\n\n return {\n classes: cn(\n \"pp-container\",\n getVariantClasses(this.variant),\n borderStyles?.className,\n isInteractive && \"pp-interactive\",\n glow?.animate && \"pp-glow\"\n ),\n styles: {\n width: `${this.pixelSize}px`,\n height: `${this.pixelSize}px`,\n borderRadius: RADIUS_MAP[this.variant],\n ...borderStyles?.style,\n ...shadowStyles,\n ...glowStyles,\n cursor:\n interactive?.cursor ?? (isInteractive ? \"pointer\" : \"default\"),\n transform: this.rotation ? `rotate(${this.rotation}deg)` : undefined,\n },\n // Background styles moved to .pp-inner to prevent sub-pixel bleed-through\n innerStyles: bg.style ?? {},\n innerClasses: bg.className,\n };\n }\n\n private renderPlaceholder() {\n if (this.isLoaded || this.placeholder === \"none\") {\n return nothing;\n }\n\n const placeholderClass = {\n shimmer: \"pp-shimmer\",\n pulse: \"pp-pulse\",\n skeleton: \"pp-skeleton\",\n blur: \"\",\n none: \"\",\n }[this.placeholder];\n\n return html`\n ${this.placeholder === \"shimmer\" ? html`<style>${shimmerStyles}</style>` : nothing}\n <div\n class=${cn(\"np:absolute np:inset-0\", placeholderClass)}\n style=${styleMap({\n backgroundColor: this.placeholderColor,\n borderRadius: \"inherit\",\n })}>\n </div>\n `;\n }\n\n private renderFallback() {\n // Check if an explicit background is set (bg-color or bg-gradient)\n // When set, the fallback should be transparent so .pp-inner's background shows through\n const hasExplicitBg = Boolean(this.bgColor || this.bgGradient);\n\n // Gradient mode: show cloudy gradient, no text\n if (this.fallbackMode === \"gradient\") {\n const gradient = generateCloudyGradient(this.gradientSeed);\n return html`\n <div\n class=\"pp-fallback np:absolute np:inset-0\"\n style=${styleMap({\n background: hasExplicitBg ? \"transparent\" : gradient,\n })}>\n </div>\n `;\n }\n\n // Use custom fallback text if provided\n if (this.fallback) {\n return html`\n <span\n class=\"pp-fallback\"\n style=${styleMap({ fontSize: `${getInitialsFontSize(this.pixelSize)}px` })}>\n ${this.fallback}\n </span>\n `;\n }\n\n // Generate initials from alt text\n if (this.alt) {\n const gradient = generateAvatarGradient(this.alt);\n return html`\n <div\n class=\"pp-fallback np:absolute np:inset-0\"\n style=${styleMap({\n background: hasExplicitBg ? \"transparent\" : gradient,\n fontSize: `${getInitialsFontSize(this.pixelSize)}px`,\n })}>\n ${getInitials(this.alt)}\n </div>\n `;\n }\n\n // Default user icon\n const iconSize = this.pixelSize * 0.5;\n return html`\n <svg\n class=\"pp-fallback-icon\"\n style=\"width: ${iconSize}px; height: ${iconSize}px;\"\n fill=\"currentColor\"\n viewBox=\"0 0 24 24\">\n <path d=\"M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z\" />\n </svg>\n `;\n }\n\n private renderImage() {\n // Determine image source with CDN priority:\n // 1. CDN URL (browser handles redirects automatically via img src)\n // 2. src prop (if CDN not configured or failed)\n // 3. Fallback component\n const hasCdnConfig = Boolean(\n this.extCustomerId && ProfilePicture.cdnBaseUrl\n );\n\n let imageSrc: string | undefined;\n if (this.cdnImageUrl) {\n // CDN URL set - browser will handle redirects\n imageSrc = this.cdnImageUrl;\n } else if (!hasCdnConfig || this.cdnLoadFailed) {\n // CDN not configured or failed - use src prop\n imageSrc = this.src;\n }\n\n // No image source available - show fallback\n if (this.hasError || !imageSrc) {\n return this.renderFallback();\n }\n\n const zoomStyle = this.zoom && this.zoom !== 1\n ? styleMap({ transform: `scale(${this.zoom})` })\n : nothing;\n\n return html`\n <img\n src=${imageSrc}\n alt=${this.alt}\n loading=${this.loading}\n decoding=\"async\"\n @load=${this.handleLoad}\n @error=${this.handleError}\n class=${cn(\"pp-image\", this.isLoaded ? \"pp-image-loaded\" : \"pp-image-loading\")}\n style=${zoomStyle}\n draggable=\"false\" />\n `;\n }\n\n private renderRing() {\n const ring = this.resolveObjectProp<RingConfig>(this.ring);\n if (!ring?.show) {\n return nothing;\n }\n\n const ringWidth = ring.width ?? 3;\n const ringGap = ring.gap ?? 3;\n const totalOffset = ringWidth + ringGap;\n\n let ringColor: string;\n const hasProgress = ring.progress !== undefined;\n\n if (hasProgress) {\n // Progress mode: partial fill ring\n const progress = ring.progress ?? 0;\n const filledColor = ring.color ?? \"#30D158\"; // Default green\n const emptyColor = ring.emptyColor ?? \"#8E8E93\"; // Default gray\n ringColor = createProgressRingGradient(progress, filledColor, emptyColor);\n } else if (ring.gradient && ring.gradient.length > 0) {\n // Multi-color gradient mode\n ringColor = createConicGradient(ring.gradient);\n } else {\n // Single color or default gradient\n ringColor =\n ring.color ??\n \"linear-gradient(45deg, #f09433, #e6683c, #dc2743, #cc2366, #bc1888)\";\n }\n\n return html`\n <div\n class=${cn(\n \"pp-ring\",\n ring.animate && !hasProgress && \"pp-ring-animated\",\n hasProgress && \"pp-ring-progress\"\n )}\n style=${styleMap({\n inset: `-${totalOffset}px`,\n padding: `${ringWidth}px`,\n background: ringColor,\n borderRadius: RADIUS_MAP[this.variant],\n })}>\n </div>\n `;\n }\n\n /**\n * Calculate the distance from the container edge to the avatar's visual corner point.\n * For a circle, this is the 45° point on the circumference.\n * Returns the inset in pixels where an indicator's CENTER should be placed.\n */\n private getCornerOffset(): number {\n const radius = this.pixelSize / 2;\n\n // For a circle, the 45° point from center is at (r*cos45, r*sin45)\n // Distance from container edge = r - r*cos(45°) = r * (1 - √2/2) ≈ r * 0.1464\n const variantInsetRatio: Record<Variant, number> = {\n circle: 1 - Math.SQRT2 / 2, // ~0.1464\n square: 0.0,\n rounded: 0.04,\n squircle: 0.08,\n };\n\n const ratio = variantInsetRatio[this.variant];\n return radius * ratio;\n }\n\n private renderPresence() {\n const presence = this.resolveObjectProp<PresenceConfig>(this.presence);\n if (!presence) {\n return nothing;\n }\n\n const thickness = presence.thickness ?? 2;\n const size = getPresenceSize(this.pixelSize, thickness);\n const color = PRESENCE_COLORS[presence.status];\n\n // Center the indicator on the avatar's corner point\n const cornerInset = this.getCornerOffset();\n const offset = cornerInset - size / 2;\n\n return html`\n <div\n class=${cn(\"pp-presence\", presence.animate && \"pp-presence-animated\")}\n style=${styleMap({\n width: `${size}px`,\n height: `${size}px`,\n backgroundColor: color,\n bottom: `${offset}px`,\n right: `${offset}px`,\n color,\n })}\n title=${presence.status}>\n </div>\n `;\n }\n\n private renderBadge() {\n const badge = this.resolveObjectProp<BadgeConfig>(this.badge);\n if (!badge) {\n return nothing;\n }\n\n const position = badge.position ?? \"bottom-right\";\n const hasContent = badge.content !== undefined;\n const hasIcon = badge.icon !== undefined;\n const hasAnyContent = hasContent || hasIcon;\n const { size: badgeSize, fontSize } = getBadgeSize(\n this.pixelSize,\n hasAnyContent\n );\n\n const bgColor = badge.bgColor ?? \"#22c55e\";\n const textColor = badge.color ?? \"#ffffff\";\n const borderRadius = badge.borderRadius ?? \"9999px\";\n\n // Format content (99+ for large numbers)\n const content =\n hasContent && badge.content !== undefined\n ? formatBadgeContent(badge.content, badge.max)\n : null;\n\n // Icon rendering\n const icon = hasIcon ? badge.icon : null;\n const iconSize = fontSize * 0.9; // Icon slightly smaller than text\n\n // Center the badge on the avatar's corner point\n const cornerInset = this.getCornerOffset();\n const offset = cornerInset - badgeSize / 2;\n const posOffset = `${offset}px`;\n\n const positionStyles: Record<Position, Record<string, string>> = {\n \"top-left\": { top: posOffset, left: posOffset },\n \"top-center\": {\n top: posOffset,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n },\n \"top-right\": { top: posOffset, right: posOffset },\n \"bottom-left\": { bottom: posOffset, left: posOffset },\n \"bottom-center\": {\n bottom: posOffset,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n },\n \"bottom-right\": { bottom: posOffset, right: posOffset },\n };\n\n return html`\n <div\n class=${cn(\n \"pp-badge\",\n badge.pulse && \"pp-badge-pulse\",\n badge.glow && \"pp-badge-glow\",\n hasIcon && \"pp-badge-with-icon\"\n )}\n style=${styleMap({\n width: hasAnyContent ? \"auto\" : `${badgeSize}px`,\n minWidth: `${badgeSize}px`,\n height: `${badgeSize}px`,\n padding: hasAnyContent ? \"0 6px\" : \"0\",\n fontSize: `${fontSize}px`,\n backgroundColor: bgColor,\n color: textColor,\n borderRadius,\n \"--pp-badge-glow-color\": bgColor,\n gap: hasIcon && hasContent ? \"4px\" : \"0\",\n ...positionStyles[position],\n })}>\n ${\n icon\n ? html`<span class=\"pp-badge-icon\" style=${styleMap({ fontSize: `${iconSize}px` })}>${icon}</span>`\n : nothing\n }\n ${content ?? nothing}\n </div>\n `;\n }\n\n render() {\n const container = this.getContainerStyles();\n\n const interactive = this.resolveObjectProp<InteractionConfig>(this.interactive);\n const tabIndex =\n interactive?.focusable || interactive?.pressable\n ? 0\n : undefined;\n\n return html`\n <div\n class=${container.classes}\n style=${styleMap(container.styles)}\n tabindex=${tabIndex ?? nothing}\n role=${interactive?.pressable ? \"button\" : nothing}\n aria-label=${this.alt || nothing}\n @click=${this.handleClick}\n @keydown=${this.handleKeyDown}\n data-profile-picture>\n\n <!-- Ring Effect (behind everything) -->\n ${this.renderRing()}\n\n <!-- Inner container for image clipping -->\n <div\n class=${cn(\"pp-inner\", container.innerClasses)}\n style=${styleMap({\n borderRadius: RADIUS_MAP[this.variant],\n ...container.innerStyles,\n })}>\n <!-- Placeholder -->\n ${this.renderPlaceholder()}\n\n <!-- Main Image or Fallback -->\n ${this.renderImage()}\n </div>\n\n <!-- Badge -->\n ${this.renderBadge()}\n\n <!-- Presence Indicator -->\n ${this.renderPresence()}\n </div>\n `;\n }\n}\n\n// Export types for TypeScript users\nexport type {\n BadgeConfig,\n FallbackMode,\n GlowConfig,\n ImageMode,\n InteractionConfig,\n LoadingStrategy,\n PlaceholderType,\n Position,\n PresenceConfig,\n PresenceStatus,\n RingConfig,\n ShadowPreset,\n Size,\n Variant,\n} from \"./types\";\n\n// Register custom element with guard to prevent duplicate registration during HMR\nif (!customElements.get(\"profile-picture\")) {\n customElements.define(\"profile-picture\", ProfilePicture);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"profile-picture\": ProfilePicture;\n }\n}\n\nexport default ProfilePicture;\n","/**\n * ProfilePictureGroup Web Component\n * Apple-inspired stacked avatar group with tooltips, counter, and dropdown\n *\n * A lightweight, framework-agnostic component for displaying\n * multiple profile pictures in a visually appealing stacked layout.\n */\n\nimport { html, LitElement, nothing, render } from \"lit\";\nimport { property, state } from \"lit/decorators.js\";\nimport { styleMap } from \"lit/directives/style-map.js\";\nimport { groupStyles } from \"./styles\";\nimport type {\n DropdownConfig,\n GroupUserData,\n Size,\n StackDirection,\n TooltipConfig,\n TooltipPosition,\n} from \"./types\";\nimport { GROUP_DEFAULTS } from \"./types\";\nimport {\n calculateAvatarCounts,\n calculateGroupWidth,\n calculateStackPosition,\n calculateStackZIndex,\n cn,\n formatCounterText,\n generateAvatarGradient,\n getGroupAvatarSize,\n getInitials,\n} from \"./utils\";\n\n// Inject group styles once\nlet groupStylesInjected = false;\nfunction injectGroupStyles() {\n if (groupStylesInjected || typeof document === \"undefined\") {\n return;\n }\n\n // Defer style injection to avoid hydration mismatch in SSR frameworks\n const defer =\n typeof requestIdleCallback !== \"undefined\"\n ? requestIdleCallback\n : (cb: () => void) => setTimeout(cb, 1);\n\n defer(() => {\n // Re-check in case another call already injected\n if (groupStylesInjected) {\n return;\n }\n const style = document.createElement(\"style\");\n style.textContent = groupStyles;\n document.head.appendChild(style);\n groupStylesInjected = true;\n });\n}\n\nexport class ProfilePictureGroup extends LitElement {\n // Use Light DOM for Tailwind compatibility\n protected createRenderRoot() {\n injectGroupStyles();\n return this;\n }\n\n // ─── Core Properties ────────────────────────────────────────────────────────\n @property({ type: Number }) max = GROUP_DEFAULTS.max;\n @property({ type: String }) direction: StackDirection =\n GROUP_DEFAULTS.direction;\n @property({ type: Number }) overlap = GROUP_DEFAULTS.overlap;\n @property({ type: String }) size: Size | string = GROUP_DEFAULTS.size;\n @property({ type: Number }) spacing?: number;\n @property({ type: Object }) tooltip?: TooltipConfig;\n @property({ type: Object }) dropdown?: DropdownConfig;\n @property({ type: Boolean, attribute: \"show-add-button\" }) showAddButton =\n false;\n @property({ type: String, attribute: \"add-button-label\" }) addButtonLabel =\n \"Add user\";\n @property({ type: Boolean }) animated = GROUP_DEFAULTS.animated;\n @property({ type: Number, attribute: \"rotation-amount\" }) rotationAmount = 0;\n\n // ─── Internal State ─────────────────────────────────────────────────────────\n @state() private users: GroupUserData[] = [];\n @state() private dropdownOpen = false;\n @state() private tooltipData: {\n user: GroupUserData;\n rect: DOMRect;\n } | null = null;\n private tooltipTimeout: number | null = null;\n private slotObserver: MutationObserver | null = null;\n\n // ─── Portal State ───────────────────────────────────────────────────────────\n private portalContainer: HTMLDivElement | null = null;\n private counterRef: HTMLButtonElement | null = null;\n\n private get pixelSize(): number {\n return getGroupAvatarSize(this.size as Size | number);\n }\n\n private get tooltipEnabled(): boolean {\n return this.tooltip?.enabled !== false;\n }\n\n private get tooltipPosition(): TooltipPosition {\n return this.tooltip?.position ?? \"top\";\n }\n\n private get tooltipDelay(): number {\n return this.tooltip?.delay ?? GROUP_DEFAULTS.tooltipDelay;\n }\n\n private get dropdownMaxHeight(): number {\n return this.dropdown?.maxHeight ?? GROUP_DEFAULTS.dropdownMaxHeight;\n }\n\n private get showPresence(): boolean {\n return this.dropdown?.showPresence !== false;\n }\n\n private get dropdownPosition(): \"top\" | \"bottom\" {\n return this.dropdown?.position ?? \"bottom\";\n }\n\n // ─── Lifecycle ──────────────────────────────────────────────────────────────\n\n connectedCallback() {\n super.connectedCallback();\n this.updateUsers();\n this.setupSlotObserver();\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.slotObserver?.disconnect();\n this.clearTooltipTimeout();\n this.destroyPortal();\n }\n\n private setupSlotObserver() {\n // Watch for child element changes\n this.slotObserver = new MutationObserver(() => {\n this.updateUsers();\n });\n\n this.slotObserver.observe(this, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [\n \"src\",\n \"alt\",\n \"ext-customer-id\",\n \"data-user-id\",\n \"data-status\",\n \"variant\",\n \"shadow\",\n \"border\",\n \"border-width\",\n \"border-color\",\n \"bg-color\",\n \"bg-gradient\",\n \"image-mode\",\n \"zoom\",\n \"loading\",\n \"placeholder\",\n \"placeholder-color\",\n \"fallback\",\n \"fallback-mode\",\n \"glow\",\n \"ring\",\n \"badge\",\n \"interactive\",\n ],\n });\n }\n\n private updateUsers() {\n // Only select direct children profile-picture elements (slotted content),\n // not the ones we render inside the ppg-container\n const children = Array.from(this.children).filter(\n (child) =>\n child.tagName.toLowerCase() === \"profile-picture\" &&\n child.getAttribute(\"slot\") !== \"internal\"\n );\n\n this.users = children.map((el, index) => {\n // Helper to read property or attribute (React may set properties instead of attributes)\n const getPropOrAttr = (\n propName: string,\n attrName?: string\n ): string | undefined => {\n const actualAttrName = attrName ?? propName;\n // Try property first (for React compatibility)\n const propValue = (el as unknown as Record<string, unknown>)[propName];\n if (propValue !== undefined && propValue !== null && propValue !== \"\") {\n return String(propValue);\n }\n // Fall back to attribute\n return el.getAttribute(actualAttrName) ?? undefined;\n };\n\n // Extract border-width as number\n const borderWidthValue = getPropOrAttr(\"borderWidth\", \"border-width\");\n const borderWidth = borderWidthValue\n ? (Number.parseInt(String(borderWidthValue), 10) as 1 | 2 | 3 | 4)\n : undefined;\n\n return {\n // Core data\n id: getPropOrAttr(\"dataUserId\", \"data-user-id\"),\n name: getPropOrAttr(\"alt\") ?? `User ${index + 1}`,\n src: getPropOrAttr(\"src\"),\n extCustomerId: getPropOrAttr(\"extCustomerId\", \"ext-customer-id\"),\n status: getPropOrAttr(\"dataStatus\", \"data-status\") as\n | GroupUserData[\"status\"]\n | undefined,\n element: el as HTMLElement,\n index,\n\n // Profile picture props (passed through from slotted elements)\n variant: getPropOrAttr(\"variant\") as\n | GroupUserData[\"variant\"]\n | undefined,\n shadow: getPropOrAttr(\"shadow\") as GroupUserData[\"shadow\"] | undefined,\n border: Boolean(\n (el as unknown as Record<string, unknown>).border ??\n el.hasAttribute(\"border\")\n ),\n borderWidth,\n borderColor: getPropOrAttr(\"borderColor\", \"border-color\"),\n bgColor: getPropOrAttr(\"bgColor\", \"bg-color\"),\n bgGradient: getPropOrAttr(\"bgGradient\", \"bg-gradient\"),\n imageMode: getPropOrAttr(\"imageMode\", \"image-mode\") as\n | GroupUserData[\"imageMode\"]\n | undefined,\n zoom: (() => {\n const v = getPropOrAttr(\"zoom\");\n return v ? Number(v) : undefined;\n })(),\n loading: getPropOrAttr(\"loading\") as\n | GroupUserData[\"loading\"]\n | undefined,\n placeholder: getPropOrAttr(\"placeholder\") as\n | GroupUserData[\"placeholder\"]\n | undefined,\n placeholderColor: getPropOrAttr(\"placeholderColor\", \"placeholder-color\"),\n fallback: getPropOrAttr(\"fallback\"),\n fallbackMode: getPropOrAttr(\"fallbackMode\", \"fallback-mode\") as\n | GroupUserData[\"fallbackMode\"]\n | undefined,\n glow: (() => {\n const v = (el as unknown as Record<string, unknown>).glow;\n if (v && typeof v === \"object\") return v as GroupUserData[\"glow\"];\n const attr = el.getAttribute(\"glow\");\n if (attr) try { return JSON.parse(attr) as GroupUserData[\"glow\"]; } catch { /* ignore */ }\n return undefined;\n })(),\n ring: (() => {\n const v = (el as unknown as Record<string, unknown>).ring;\n if (v && typeof v === \"object\") return v as GroupUserData[\"ring\"];\n const attr = el.getAttribute(\"ring\");\n if (attr) try { return JSON.parse(attr) as GroupUserData[\"ring\"]; } catch { /* ignore */ }\n return undefined;\n })(),\n badge: (() => {\n const v = (el as unknown as Record<string, unknown>).badge;\n if (v && typeof v === \"object\") return v as GroupUserData[\"badge\"];\n const attr = el.getAttribute(\"badge\");\n if (attr) try { return JSON.parse(attr) as GroupUserData[\"badge\"]; } catch { /* ignore */ }\n return undefined;\n })(),\n interactive: (() => {\n const v = (el as unknown as Record<string, unknown>).interactive;\n if (v && typeof v === \"object\") return v as GroupUserData[\"interactive\"];\n const attr = el.getAttribute(\"interactive\");\n if (attr) try { return JSON.parse(attr) as GroupUserData[\"interactive\"]; } catch { /* ignore */ }\n return undefined;\n })(),\n };\n });\n\n // Hide ALL slotted elements since we're rendering our own\n for (const user of this.users) {\n if (user.element) {\n user.element.style.display = \"none\";\n }\n }\n }\n\n // ─── Portal Management ──────────────────────────────────────────────────────\n\n private createPortal() {\n if (this.portalContainer) {\n return;\n }\n\n this.portalContainer = document.createElement(\"div\");\n this.portalContainer.className = \"ppg-portal\";\n this.portalContainer.style.cssText =\n \"position: fixed; z-index: 99999; pointer-events: none;\";\n document.body.appendChild(this.portalContainer);\n\n // Lock body scroll\n document.body.style.overflow = \"hidden\";\n }\n\n private destroyPortal() {\n if (this.portalContainer) {\n render(nothing, this.portalContainer);\n this.portalContainer.remove();\n this.portalContainer = null;\n\n // Restore body scroll\n document.body.style.overflow = \"\";\n }\n }\n\n private updatePortalContent(hiddenUsers: GroupUserData[]) {\n if (!(this.portalContainer && this.counterRef)) {\n return;\n }\n\n const rect = this.counterRef.getBoundingClientRect();\n const gap = 10;\n const dropdownWidth = 280;\n const dropdownHeight = Math.min(\n this.dropdownMaxHeight + 60, // header + padding\n hiddenUsers.length * 56 + 60 // estimate item height\n );\n\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n const isMobile = viewportWidth < 480;\n\n // Mobile: centered modal style\n if (isMobile) {\n const content = html`\n <div\n class=\"ppg-backdrop ppg-backdrop-visible\"\n style=\"pointer-events: auto; background: rgba(0,0,0,0.5);\"\n @click=${this.handleBackdropClick}\n aria-hidden=\"true\"\n ></div>\n <div\n class=\"ppg-dropdown ppg-dropdown-modal\"\n style=${styleMap({\n position: \"fixed\",\n pointerEvents: \"auto\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n width: \"calc(100vw - 32px)\",\n maxWidth: \"320px\",\n maxHeight: \"70vh\",\n })}\n data-position=\"modal\"\n role=\"menu\"\n aria-label=\"Hidden users\"\n >\n <div class=\"ppg-dropdown-header\">\n ${hiddenUsers.length} more\n </div>\n <div\n class=\"ppg-dropdown-list\"\n style=${styleMap({\n maxHeight: \"calc(70vh - 60px)\",\n })}\n >\n ${hiddenUsers.map((user) => this.renderDropdownItem(user))}\n </div>\n </div>\n `;\n render(content, this.portalContainer);\n return;\n }\n\n // Desktop: smart positioning\n const spaceBelow = viewportHeight - rect.bottom - gap;\n const spaceAbove = rect.top - gap;\n const spaceRight = viewportWidth - rect.left;\n const spaceLeft = rect.right;\n\n // Determine vertical position\n let openDirection: \"bottom\" | \"top\" = this.dropdownPosition;\n if (\n openDirection === \"bottom\" &&\n spaceBelow < dropdownHeight &&\n spaceAbove > spaceBelow\n ) {\n openDirection = \"top\";\n } else if (\n openDirection === \"top\" &&\n spaceAbove < dropdownHeight &&\n spaceBelow > spaceAbove\n ) {\n openDirection = \"bottom\";\n }\n\n // Determine horizontal position\n let left: number;\n if (spaceRight >= dropdownWidth) {\n // Align to left edge of counter\n left = rect.left;\n } else if (spaceLeft >= dropdownWidth) {\n // Align to right edge of counter\n left = rect.right - dropdownWidth;\n } else {\n // Center in viewport\n left = (viewportWidth - dropdownWidth) / 2;\n }\n\n // Clamp to viewport bounds\n left = Math.max(8, Math.min(left, viewportWidth - dropdownWidth - 8));\n\n const top = openDirection === \"bottom\" ? rect.bottom + gap : undefined;\n const bottom =\n openDirection === \"top\" ? viewportHeight - rect.top + gap : undefined;\n\n const content = html`\n <div\n class=\"ppg-backdrop\"\n style=\"pointer-events: auto;\"\n @click=${this.handleBackdropClick}\n aria-hidden=\"true\"\n ></div>\n <div\n class=\"ppg-dropdown ppg-dropdown-portal\"\n style=${styleMap({\n position: \"fixed\",\n pointerEvents: \"auto\",\n top: top !== undefined ? `${top}px` : \"auto\",\n bottom: bottom !== undefined ? `${bottom}px` : \"auto\",\n left: `${left}px`,\n width: `${dropdownWidth}px`,\n })}\n data-position=${openDirection}\n role=\"menu\"\n aria-label=\"Hidden users\"\n >\n <div class=\"ppg-dropdown-header\">\n ${hiddenUsers.length} more\n </div>\n <div\n class=\"ppg-dropdown-list\"\n style=${styleMap({\n maxHeight: `${this.dropdownMaxHeight}px`,\n })}\n >\n ${hiddenUsers.map((user) => this.renderDropdownItem(user))}\n </div>\n </div>\n `;\n\n render(content, this.portalContainer);\n }\n\n // ─── Event Handlers ─────────────────────────────────────────────────────────\n\n private handleAvatarClick(user: GroupUserData) {\n this.dispatchEvent(\n new CustomEvent(\"avatar-click\", {\n detail: { user },\n bubbles: true,\n composed: true,\n })\n );\n }\n\n private handleAvatarHover(user: GroupUserData, event: MouseEvent) {\n if (!this.tooltipEnabled) {\n return;\n }\n\n this.clearTooltipTimeout();\n const target = event.currentTarget as HTMLElement;\n\n this.tooltipTimeout = window.setTimeout(() => {\n this.tooltipData = {\n user,\n rect: target.getBoundingClientRect(),\n };\n }, this.tooltipDelay);\n\n this.dispatchEvent(\n new CustomEvent(\"avatar-hover\", {\n detail: { user },\n bubbles: true,\n composed: true,\n })\n );\n }\n\n private handleAvatarLeave() {\n this.clearTooltipTimeout();\n this.tooltipData = null;\n }\n\n private clearTooltipTimeout() {\n if (this.tooltipTimeout) {\n window.clearTimeout(this.tooltipTimeout);\n this.tooltipTimeout = null;\n }\n }\n\n private handleCounterClick(hiddenUsers: GroupUserData[]) {\n this.dropdownOpen = !this.dropdownOpen;\n\n if (this.dropdownOpen) {\n this.createPortal();\n this.updatePortalContent(hiddenUsers);\n } else {\n this.destroyPortal();\n }\n\n this.dispatchEvent(\n new CustomEvent(\"counter-click\", {\n detail: { hiddenUsers, open: this.dropdownOpen },\n bubbles: true,\n composed: true,\n })\n );\n }\n\n private readonly handleBackdropClick = () => {\n this.dropdownOpen = false;\n this.destroyPortal();\n };\n\n private handleDropdownItemClick(user: GroupUserData) {\n this.dropdownOpen = false;\n this.destroyPortal();\n\n this.dispatchEvent(\n new CustomEvent(\"dropdown-item-click\", {\n detail: { user },\n bubbles: true,\n composed: true,\n })\n );\n }\n\n private handleAddClick() {\n this.dispatchEvent(\n new CustomEvent(\"add-click\", {\n bubbles: true,\n composed: true,\n })\n );\n }\n\n private handleKeyDown(event: KeyboardEvent, handler: () => void) {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n handler();\n }\n }\n\n // ─── Rendering ──────────────────────────────────────────────────────────────\n\n private renderAvatar(user: GroupUserData, index: number, total: number) {\n const position = calculateStackPosition(\n index,\n this.pixelSize,\n this.overlap,\n this.direction,\n this.spacing\n );\n const zIndex = calculateStackZIndex(index, total, this.direction);\n\n // Use user's variant or default to circle for groups\n const variant = user.variant ?? \"circle\";\n // Use user's shadow or default to none for cleaner stacking\n const shadow = user.shadow ?? \"none\";\n // Calculate alternating rotation\n const rotation = this.rotationAmount\n ? index % 2 === 0\n ? -this.rotationAmount\n : this.rotationAmount\n : 0;\n\n return html`\n <div\n class=\"ppg-avatar-wrapper\"\n style=${styleMap({\n left: `${position}px`,\n zIndex: String(zIndex),\n width: `${this.pixelSize}px`,\n height: `${this.pixelSize}px`,\n })}\n tabindex=\"0\"\n role=\"button\"\n aria-label=${user.name}\n @click=${() => this.handleAvatarClick(user)}\n @mouseenter=${(e: MouseEvent) => this.handleAvatarHover(user, e)}\n @mouseleave=${this.handleAvatarLeave}\n @keydown=${(e: KeyboardEvent) =>\n this.handleKeyDown(e, () => this.handleAvatarClick(user))}\n >\n ${this.renderProfilePicture(user, variant, shadow, rotation)}\n </div>\n `;\n }\n\n private renderProfilePicture(\n user: GroupUserData,\n variant: string,\n shadow: string,\n rotation: number\n ) {\n // Build the profile-picture element with only defined attributes\n // This avoids passing empty strings which might override defaults\n // Default to white background when wrapped in group\n return html`\n <profile-picture\n .src=${user.src || undefined}\n .alt=${user.name}\n .size=${this.pixelSize}\n .variant=${variant}\n .shadow=${shadow}\n .rotation=${rotation}\n .extCustomerId=${user.extCustomerId}\n ?border=${user.border}\n .borderWidth=${user.border ? (user.borderWidth ?? 2) : 2}\n .borderColor=${user.border ? (user.borderColor ?? \"#ffffff\") : \"#ffffff\"}\n .bgColor=${user.bgGradient ? undefined : (user.bgColor || undefined)}\n .bgGradient=${user.bgGradient ?? undefined}\n .imageMode=${user.imageMode ?? \"original\"}\n .zoom=${user.zoom ?? undefined}\n .loading=${user.loading ?? undefined}\n .placeholder=${user.placeholder ?? undefined}\n .placeholderColor=${user.placeholderColor ?? undefined}\n .fallback=${user.fallback ?? undefined}\n .fallbackMode=${user.fallbackMode ?? undefined}\n .glow=${user.glow ?? undefined}\n .ring=${user.ring ?? undefined}\n .badge=${user.badge ?? undefined}\n .interactive=${user.interactive ?? undefined}\n data-user-id=${user.id ?? \"\"}\n data-status=${user.status ?? \"\"}\n ></profile-picture>\n `;\n }\n\n private renderCounter(\n count: number,\n position: number,\n hiddenUsers: GroupUserData[]\n ) {\n return html`\n <button\n class=\"ppg-counter\"\n style=${styleMap({\n left: `${position}px`,\n width: `${this.pixelSize}px`,\n height: `${this.pixelSize}px`,\n zIndex: \"1\",\n })}\n aria-label=${`${count} more users`}\n aria-expanded=${this.dropdownOpen}\n aria-haspopup=\"true\"\n @click=${() => this.handleCounterClick(hiddenUsers)}\n >\n ${formatCounterText(count)}\n </button>\n `;\n }\n\n private renderAddButton(position: number) {\n const iconSize = Math.round(this.pixelSize * 0.4);\n\n return html`\n <button\n class=\"ppg-add-button\"\n style=${styleMap({\n left: `${position}px`,\n width: `${this.pixelSize}px`,\n height: `${this.pixelSize}px`,\n zIndex: \"1\",\n })}\n aria-label=${this.addButtonLabel}\n @click=${this.handleAddClick}\n >\n <svg\n class=\"ppg-add-icon\"\n width=${iconSize}\n height=${iconSize}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"></line>\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"></line>\n </svg>\n </button>\n `;\n }\n\n private renderTooltip() {\n if (!this.tooltipData) {\n return nothing;\n }\n\n const { user, rect } = this.tooltipData;\n const gap = 8;\n\n // Get container position for relative calculation\n const containerRect = this.getBoundingClientRect();\n\n // Calculate position relative to container\n const relativeLeft = rect.left - containerRect.left + rect.width / 2;\n const relativeTop = rect.top - containerRect.top;\n const relativeBottom = rect.bottom - containerRect.top;\n\n const isTop = this.tooltipPosition === \"top\";\n\n return html`\n <div\n class=\"ppg-tooltip\"\n style=${styleMap({\n top: isTop ? \"auto\" : `${relativeBottom + gap}px`,\n bottom: isTop\n ? `${containerRect.height - relativeTop + gap}px`\n : \"auto\",\n left: `${relativeLeft}px`,\n })}\n data-position=${this.tooltipPosition}\n role=\"tooltip\"\n >\n ${user.name}\n </div>\n `;\n }\n\n private renderDropdownItem(user: GroupUserData) {\n const gradient = generateAvatarGradient(user.name);\n const hasImage = user.src || user.extCustomerId;\n\n return html`\n <div\n class=\"ppg-dropdown-item\"\n role=\"menuitem\"\n tabindex=\"0\"\n @click=${() => this.handleDropdownItemClick(user)}\n @keydown=${(e: KeyboardEvent) =>\n this.handleKeyDown(e, () => this.handleDropdownItemClick(user))}\n >\n ${\n hasImage\n ? html`<profile-picture\n class=\"ppg-dropdown-avatar\"\n .src=${user.src || undefined}\n .alt=${user.name}\n .extCustomerId=${user.extCustomerId}\n .size=${40}\n variant=\"circle\"\n shadow=\"none\"\n ></profile-picture>`\n : html`<div\n class=\"ppg-dropdown-avatar-fallback\"\n style=${styleMap({ background: gradient })}\n >\n ${getInitials(user.name)}\n </div>`\n }\n <div class=\"ppg-dropdown-info\">\n <div class=\"ppg-dropdown-name\">${user.name}</div>\n ${\n this.showPresence && user.status\n ? html`\n <div class=\"ppg-dropdown-status\">\n <span\n class=\"ppg-dropdown-presence\"\n data-status=${user.status}\n ></span>\n ${this.formatStatus(user.status)}\n </div>\n `\n : nothing\n }\n </div>\n </div>\n `;\n }\n\n private formatStatus(status: string): string {\n const labels: Record<string, string> = {\n online: \"Online\",\n away: \"Away\",\n busy: \"Busy\",\n offline: \"Offline\",\n dnd: \"Do not disturb\",\n };\n return labels[status] ?? status;\n }\n\n protected updated(changedProperties: Map<PropertyKey, unknown>) {\n super.updated(changedProperties);\n\n // Update counter ref after render\n const counter = this.querySelector(\".ppg-counter\") as HTMLButtonElement;\n if (counter) {\n this.counterRef = counter;\n }\n\n // Update portal content if dropdown is open\n if (this.dropdownOpen && this.portalContainer) {\n const { visible } = calculateAvatarCounts(\n this.users.length,\n this.max,\n this.showAddButton\n );\n const hiddenUsers = this.users.slice(visible);\n this.updatePortalContent(hiddenUsers);\n }\n }\n\n render() {\n const { visible, hidden, showCounter } = calculateAvatarCounts(\n this.users.length,\n this.max,\n this.showAddButton\n );\n\n // Determine which users to show\n const visibleUsers =\n this.direction === \"ltr\"\n ? this.users.slice(0, visible)\n : this.users.slice(0, visible).reverse();\n\n const hiddenUsers = this.users.slice(visible);\n\n // Calculate element count for width\n let elementCount = visible;\n if (showCounter) {\n elementCount++;\n }\n if (this.showAddButton) {\n elementCount++;\n }\n\n const containerWidth = calculateGroupWidth(\n elementCount,\n this.pixelSize,\n this.overlap,\n this.spacing\n );\n\n // Calculate positions for counter and add button\n const counterPosition = showCounter\n ? calculateStackPosition(\n visible,\n this.pixelSize,\n this.overlap,\n this.direction,\n this.spacing\n )\n : 0;\n\n const addButtonPosition = calculateStackPosition(\n visible + (showCounter ? 1 : 0),\n this.pixelSize,\n this.overlap,\n this.direction,\n this.spacing\n );\n\n return html`\n <div\n class=${cn(\"ppg-container\", this.animated && \"ppg-animated\")}\n style=${styleMap({\n width: `${containerWidth}px`,\n height: `${this.pixelSize}px`,\n })}\n role=\"group\"\n aria-label=\"User avatars\"\n >\n <!-- Hidden slot for original children -->\n <slot style=\"display: none;\"></slot>\n\n <!-- Visible avatars -->\n ${visibleUsers.map((user, index) =>\n this.renderAvatar(user, index, visible)\n )}\n\n <!-- Counter -->\n ${showCounter ? this.renderCounter(hidden, counterPosition, hiddenUsers) : nothing}\n\n <!-- Add button -->\n ${this.showAddButton ? this.renderAddButton(addButtonPosition) : nothing}\n\n <!-- Tooltip -->\n ${this.renderTooltip()}\n </div>\n `;\n }\n}\n\n// Export types for TypeScript users\nexport type {\n DropdownConfig,\n GroupUserData,\n ProfilePictureGroupProps,\n StackDirection,\n TooltipConfig,\n TooltipPosition,\n} from \"./types\";\n\n// Register custom element with guard to prevent duplicate registration during HMR\nif (!customElements.get(\"profile-picture-group\")) {\n customElements.define(\"profile-picture-group\", ProfilePictureGroup);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"profile-picture-group\": ProfilePictureGroup;\n }\n}\n\nexport default ProfilePictureGroup;\n","/**\n * Angular wrapper for ProfilePicture Web Component\n *\n * The component is a standard Web Component and works natively with Angular.\n * No wrapper needed - just import to register the custom element.\n *\n * @example\n * ```typescript\n * import '@grasco/profile-picture/angular';\n * import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';\n * import type { RingConfig, BadgeConfig } from '@grasco/profile-picture/angular';\n *\n * @Component({\n * selector: 'app-example',\n * template: `\n * <profile-picture\n * [attr.src]=\"avatarUrl\"\n * size=\"lg\"\n * variant=\"circle\"\n * border\n * border-color=\"white\"\n * bg-color=\"#f3f4f6\"\n * [attr.ring]=\"ringJson\"\n * [attr.badge]=\"badgeJson\"\n * (load)=\"onImageLoad()\"\n * (error)=\"onImageError()\"\n * (profile-picture-click)=\"onAvatarClick($event)\">\n * </profile-picture>\n * `,\n * standalone: true,\n * schemas: [CUSTOM_ELEMENTS_SCHEMA] // Required for custom elements\n * })\n * export class ExampleComponent {\n * avatarUrl = 'https://example.com/avatar.png';\n *\n * ring: RingConfig = { show: true, color: '#ff5722' };\n * badge: BadgeConfig = { content: 3, position: 'bottom-right', pulse: true };\n *\n * get ringJson() { return JSON.stringify(this.ring); }\n * get badgeJson() { return JSON.stringify(this.badge); }\n *\n * onImageLoad() {\n * console.log('Image loaded');\n * }\n *\n * onImageError() {\n * console.error('Image failed to load');\n * }\n * }\n * ```\n *\n * Note: Add CUSTOM_ELEMENTS_SCHEMA to your component's schemas array.\n *\n * For property binding:\n * - Use [attr.property]=\"value\" for object/array properties (ring, badge, etc.)\n * - Use property=\"value\" for string/primitive properties\n * - Use (event)=\"handler()\" for events (load, error, cdn-error)\n */\n\n// Import and register the web components\nimport { ProfilePicture as CoreProfilePictureElement } from \"../../core/ProfilePicture\";\nimport \"../../core/ProfilePictureGroup\";\n\n/**\n * Set global CDN base URL for all ProfilePicture instances\n * @example setCdnBaseUrl('https://api.example.com')\n */\nexport function setCdnBaseUrl(url: string): void {\n CoreProfilePictureElement.setCdnBaseUrl(url);\n}\n\n/**\n * Get current CDN base URL\n */\nexport function getCdnBaseUrl(): string {\n return CoreProfilePictureElement.getCdnBaseUrl();\n}\n\n// Re-export all types for TypeScript users\nexport type {\n // ProfilePicture types\n BadgeConfig,\n // ProfilePictureGroup types\n DropdownConfig,\n FallbackMode,\n GlowConfig,\n GroupUserData,\n ImageMode,\n InteractionConfig,\n LoadingStrategy,\n PlaceholderType,\n Position,\n PresenceConfig,\n PresenceStatus,\n ProfilePictureGroupProps,\n ProfilePictureProps,\n RingConfig,\n ShadowPreset,\n Size,\n StackDirection,\n TooltipConfig,\n TooltipPosition,\n Variant,\n} from \"../../core/types\";\n","/**\n * Angular entry point\n */\n\n// Auto-load styles when module is imported\nimport { loadStyles } from \"./core/loadStyles\";\n\nloadStyles();\n\nexport * from \"./wrappers/angular\";\n"]}
|