@sudobility/building_blocks 0.0.13 → 0.0.15

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/index.js CHANGED
@@ -117,8 +117,7 @@ const LanguageSelector = ({
117
117
  "absolute right-0 mt-2 w-48 py-1 z-50",
118
118
  "bg-white dark:bg-gray-800",
119
119
  "border border-gray-200 dark:border-gray-700",
120
- "rounded-lg shadow-lg",
121
- "max-h-64 overflow-y-auto"
120
+ "rounded-lg shadow-lg"
122
121
  ),
123
122
  role: "listbox",
124
123
  "aria-label": "Languages",
@@ -186,8 +185,7 @@ const LanguageSelector = ({
186
185
  "absolute left-0 right-0 mt-1 py-1 z-50",
187
186
  "bg-white dark:bg-gray-800",
188
187
  "border border-gray-200 dark:border-gray-700",
189
- "rounded-md shadow-lg",
190
- "max-h-64 overflow-y-auto"
188
+ "rounded-md shadow-lg"
191
189
  ),
192
190
  role: "listbox",
193
191
  "aria-label": "Languages",
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/utils/index.ts","../src/constants/languages.ts","../src/components/topbar/language-selector.tsx","../src/components/topbar/app-topbar.tsx","../src/components/topbar/app-topbar-with-firebase-auth.tsx","../src/components/topbar/app-topbar-with-wallet.tsx","../src/components/breadcrumbs/app-breadcrumbs.tsx","../src/components/footer/app-footer.tsx","../src/components/footer/app-footer-for-home-page.tsx","../src/components/layout/app-page-layout.tsx","../src/components/settings/appearance-settings.tsx"],"sourcesContent":["import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\n/**\n * Merge class names with Tailwind CSS classes.\n * Combines clsx for conditional classes and tailwind-merge for deduplication.\n */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","export interface LanguageConfig {\n code: string;\n name: string;\n flag: string;\n}\n\n/**\n * Default set of 16 supported languages with their flags.\n * Apps can override this list by passing their own languages prop.\n */\nexport const DEFAULT_LANGUAGES: LanguageConfig[] = [\n { code: 'en', name: 'English', flag: '🇺🇸' },\n { code: 'ar', name: 'العربية', flag: '🇸🇦' },\n { code: 'de', name: 'Deutsch', flag: '🇩🇪' },\n { code: 'es', name: 'Español', flag: '🇪🇸' },\n { code: 'fr', name: 'Français', flag: '🇫🇷' },\n { code: 'it', name: 'Italiano', flag: '🇮🇹' },\n { code: 'ja', name: '日本語', flag: '🇯🇵' },\n { code: 'ko', name: '한국어', flag: '🇰🇷' },\n { code: 'pt', name: 'Português', flag: '🇵🇹' },\n { code: 'ru', name: 'Русский', flag: '🇷🇺' },\n { code: 'sv', name: 'Svenska', flag: '🇸🇪' },\n { code: 'th', name: 'ไทย', flag: '🇹🇭' },\n { code: 'uk', name: 'Українська', flag: '🇺🇦' },\n { code: 'vi', name: 'Tiếng Việt', flag: '🇻🇳' },\n { code: 'zh', name: '简体中文', flag: '🇨🇳' },\n { code: 'zh-hant', name: '繁體中文', flag: '🇹🇼' },\n];\n\n/**\n * Languages that use right-to-left text direction.\n */\nexport const RTL_LANGUAGES = ['ar'];\n\n/**\n * Check if a language code is RTL.\n */\nexport function isRTL(languageCode: string): boolean {\n return RTL_LANGUAGES.includes(languageCode);\n}\n","import React, {\n useState,\n useCallback,\n useMemo,\n useRef,\n useEffect,\n} from 'react';\nimport { ChevronDownIcon } from '@heroicons/react/24/outline';\nimport { cn } from '../../utils';\nimport {\n DEFAULT_LANGUAGES,\n type LanguageConfig,\n} from '../../constants/languages';\n\nexport interface LanguageSelectorProps {\n /** Available languages (defaults to 16 built-in languages) */\n languages?: LanguageConfig[];\n /** Current language code */\n currentLanguage?: string;\n /** Language change handler */\n onLanguageChange?: (languageCode: string) => void;\n /** Variant: 'compact' for topbar, 'full' for settings */\n variant?: 'compact' | 'full';\n /** Custom className */\n className?: string;\n /** Label text for full variant */\n label?: string;\n /** Helper text for full variant */\n helperText?: string;\n}\n\n/**\n * LanguageSelector component with dropdown for switching languages.\n * Uses default 16 languages if none provided.\n */\nexport const LanguageSelector: React.FC<LanguageSelectorProps> = ({\n languages = DEFAULT_LANGUAGES,\n currentLanguage = 'en',\n onLanguageChange,\n variant = 'compact',\n className,\n label = 'Language',\n helperText = 'Select your preferred language',\n}) => {\n const [isOpen, setIsOpen] = useState(false);\n const dropdownRef = useRef<HTMLDivElement>(null);\n\n // Sort languages alphabetically by name\n const sortedLanguages = useMemo(\n () => [...languages].sort((a, b) => a.name.localeCompare(b.name)),\n [languages]\n );\n\n const currentLang = useMemo(\n () => languages.find(lang => lang.code === currentLanguage) || languages[0],\n [languages, currentLanguage]\n );\n\n const handleLanguageChange = useCallback(\n (langCode: string) => {\n if (langCode !== currentLanguage) {\n onLanguageChange?.(langCode);\n }\n setIsOpen(false);\n },\n [currentLanguage, onLanguageChange]\n );\n\n // Close dropdown when clicking outside\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (\n dropdownRef.current &&\n !dropdownRef.current.contains(event.target as Node)\n ) {\n setIsOpen(false);\n }\n };\n\n if (isOpen) {\n document.addEventListener('mousedown', handleClickOutside);\n return () =>\n document.removeEventListener('mousedown', handleClickOutside);\n }\n }, [isOpen]);\n\n // Close dropdown on escape\n useEffect(() => {\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n setIsOpen(false);\n }\n };\n\n if (isOpen) {\n document.addEventListener('keydown', handleEscape);\n return () => document.removeEventListener('keydown', handleEscape);\n }\n }, [isOpen]);\n\n if (variant === 'compact') {\n return (\n <div ref={dropdownRef} className={cn('relative', className)}>\n <button\n onClick={() => setIsOpen(!isOpen)}\n className={cn(\n 'flex items-center gap-2 px-3 py-2 h-10 rounded-lg',\n 'hover:bg-gray-100 dark:hover:bg-gray-700',\n 'transition-colors'\n )}\n aria-label='Select language'\n aria-expanded={isOpen}\n aria-haspopup='listbox'\n >\n <span className='text-lg leading-none'>{currentLang?.flag}</span>\n <span className='hidden sm:block text-sm font-medium text-gray-700 dark:text-gray-300'>\n {currentLang?.name}\n </span>\n <ChevronDownIcon\n className={cn(\n 'h-4 w-4 text-gray-500 dark:text-gray-400 transition-transform',\n isOpen && 'rotate-180'\n )}\n />\n </button>\n\n {isOpen && (\n <div\n className={cn(\n 'absolute right-0 mt-2 w-48 py-1 z-50',\n 'bg-white dark:bg-gray-800',\n 'border border-gray-200 dark:border-gray-700',\n 'rounded-lg shadow-lg',\n 'max-h-64 overflow-y-auto'\n )}\n role='listbox'\n aria-label='Languages'\n >\n {sortedLanguages.map(lang => (\n <button\n key={lang.code}\n onClick={() => handleLanguageChange(lang.code)}\n className={cn(\n 'w-full flex items-center gap-3 px-3 py-2 text-left',\n 'hover:bg-gray-100 dark:hover:bg-gray-700',\n 'transition-colors',\n lang.code === currentLanguage &&\n 'bg-gray-100 dark:bg-gray-700 font-medium'\n )}\n role='option'\n aria-selected={lang.code === currentLanguage}\n >\n <span className='text-lg leading-none'>{lang.flag}</span>\n <span className='text-sm text-gray-700 dark:text-gray-300'>\n {lang.name}\n </span>\n </button>\n ))}\n </div>\n )}\n </div>\n );\n }\n\n // Full variant for settings pages\n return (\n <div ref={dropdownRef} className={cn('space-y-2', className)}>\n <label className='text-sm font-medium text-gray-700 dark:text-gray-300 flex items-center gap-2'>\n <span>{label}</span>\n </label>\n\n <div className='relative'>\n <button\n onClick={() => setIsOpen(!isOpen)}\n className={cn(\n 'flex items-center justify-between w-full px-3 py-2 text-left',\n 'bg-white dark:bg-gray-800',\n 'border border-gray-300 dark:border-gray-600',\n 'rounded-md',\n 'hover:bg-gray-50 dark:hover:bg-gray-700',\n 'transition-colors'\n )}\n aria-expanded={isOpen}\n aria-haspopup='listbox'\n >\n <div className='flex items-center gap-2'>\n <span className='text-lg leading-none'>{currentLang?.flag}</span>\n <span className='text-sm text-gray-700 dark:text-gray-300'>\n {currentLang?.name}\n </span>\n </div>\n <ChevronDownIcon\n className={cn(\n 'h-4 w-4 text-gray-500 dark:text-gray-400 transition-transform',\n isOpen && 'rotate-180'\n )}\n />\n </button>\n\n {isOpen && (\n <div\n className={cn(\n 'absolute left-0 right-0 mt-1 py-1 z-50',\n 'bg-white dark:bg-gray-800',\n 'border border-gray-200 dark:border-gray-700',\n 'rounded-md shadow-lg',\n 'max-h-64 overflow-y-auto'\n )}\n role='listbox'\n aria-label='Languages'\n >\n {sortedLanguages.map(lang => (\n <button\n key={lang.code}\n onClick={() => handleLanguageChange(lang.code)}\n className={cn(\n 'w-full flex items-center gap-3 px-3 py-2 text-left',\n 'hover:bg-gray-100 dark:hover:bg-gray-700',\n 'transition-colors',\n lang.code === currentLanguage &&\n 'bg-gray-100 dark:bg-gray-700 font-medium'\n )}\n role='option'\n aria-selected={lang.code === currentLanguage}\n >\n <span className='text-lg leading-none'>{lang.flag}</span>\n <span className='text-sm text-gray-700 dark:text-gray-300'>\n {lang.name}\n </span>\n </button>\n ))}\n </div>\n )}\n </div>\n\n {helperText && (\n <p className='text-xs text-gray-500 dark:text-gray-400'>{helperText}</p>\n )}\n </div>\n );\n};\n\nexport default LanguageSelector;\n","import React, { useMemo, type ComponentType, type ReactNode } from 'react';\nimport {\n Topbar,\n TopbarProvider,\n TopbarLeft,\n TopbarCenter,\n TopbarRight,\n TopbarLogo,\n TopbarNavigation,\n TopbarActions,\n TopbarMobileContent,\n Logo,\n type TopbarNavItem,\n} from '@sudobility/components';\nimport { cn } from '../../utils';\nimport {\n LanguageSelector,\n type LanguageSelectorProps,\n} from './language-selector';\nimport type {\n MenuItemConfig,\n LogoConfig,\n LanguageConfig,\n LinkComponentProps,\n} from '../../types';\nimport { DEFAULT_LANGUAGES } from '../../constants/languages';\n\nexport interface AppTopBarProps {\n /** Logo configuration */\n logo: LogoConfig;\n\n /** Navigation menu items */\n menuItems: MenuItemConfig[];\n\n /** Available languages for selector (defaults to 16 built-in languages) */\n languages?: LanguageConfig[];\n\n /** Current language code */\n currentLanguage?: string;\n\n /** Language change handler */\n onLanguageChange?: (languageCode: string) => void;\n\n /** Hide language selector */\n hideLanguageSelector?: boolean;\n\n /** Language selector props override */\n languageSelectorProps?: Partial<LanguageSelectorProps>;\n\n /** Breakpoint to collapse navigation to hamburger menu */\n collapseBelow?: 'sm' | 'md' | 'lg' | 'xl';\n\n /** Render prop for account/auth section (right side of topbar) */\n renderAccountSection?: () => ReactNode;\n\n /** Render prop for center section (e.g., search bar) - shown on desktop */\n renderCenterSection?: () => ReactNode;\n\n /** Render prop for mobile-specific content (e.g., mobile search) - shown below main topbar on mobile */\n renderMobileContent?: () => ReactNode;\n\n /** Custom Link component for navigation (for react-router-dom, Next.js, etc.) */\n LinkComponent?: ComponentType<LinkComponentProps>;\n\n /** Optional sticky positioning */\n sticky?: boolean;\n\n /** Optional variant */\n variant?: 'default' | 'app';\n\n /** Mobile menu label for accessibility */\n mobileMenuLabel?: string;\n\n /** Custom className for topbar */\n className?: string;\n\n /** z-index level */\n zIndex?: 'default' | 'highest' | 'high';\n\n /** Aria label for navigation */\n ariaLabel?: string;\n}\n\n/**\n * Default Link component that renders a plain anchor tag.\n * Apps should provide their own LinkComponent for router integration.\n */\nconst DefaultLinkComponent: ComponentType<LinkComponentProps> = ({\n href,\n className,\n children,\n onClick,\n}) => (\n <a href={href} className={className} onClick={onClick}>\n {children}\n </a>\n);\n\n/**\n * AppTopBar - Base topbar component for Sudobility apps.\n *\n * Features:\n * - Logo with app name on the left\n * - Navigation menu items with icons\n * - Language selector\n * - Render prop for center section (e.g., search bar)\n * - Render prop for account/auth section\n * - Render prop for mobile-specific content\n * - Responsive with hamburger menu on mobile\n * - Dark mode support\n */\nexport const AppTopBar: React.FC<AppTopBarProps> = ({\n logo,\n menuItems,\n languages = DEFAULT_LANGUAGES,\n currentLanguage = 'en',\n onLanguageChange,\n hideLanguageSelector = false,\n languageSelectorProps,\n collapseBelow = 'lg',\n renderAccountSection,\n renderCenterSection,\n renderMobileContent,\n LinkComponent = DefaultLinkComponent,\n sticky = true,\n variant = 'default',\n mobileMenuLabel = 'Menu',\n className,\n zIndex = 'highest',\n ariaLabel = 'Main navigation',\n}) => {\n // Filter menu items that should be shown\n const visibleMenuItems = useMemo(\n () => menuItems.filter(item => item.show !== false),\n [menuItems]\n );\n\n // Convert MenuItemConfig to TopbarNavItem\n const navItems: TopbarNavItem[] = useMemo(\n () =>\n visibleMenuItems.map(item => ({\n id: item.id,\n label: item.label,\n icon: item.icon,\n href: item.href,\n })),\n [visibleMenuItems]\n );\n\n // Wrapper to adapt LinkComponent to TopbarNavigation expected interface\n const LinkWrapper: ComponentType<{\n href: string;\n className?: string;\n children: ReactNode;\n }> = useMemo(\n () =>\n ({ href, className, children }) => (\n <LinkComponent href={href} className={className}>\n {children}\n </LinkComponent>\n ),\n [LinkComponent]\n );\n\n const handleLogoClick = () => {\n logo.onClick?.();\n };\n\n return (\n <TopbarProvider variant={variant} sticky={sticky}>\n <Topbar\n variant={variant}\n sticky={sticky}\n zIndex={zIndex}\n aria-label={ariaLabel}\n className={cn(className)}\n >\n <TopbarLeft>\n <TopbarNavigation\n items={navItems}\n collapseBelow={collapseBelow}\n LinkComponent={LinkWrapper}\n mobileMenuLabel={mobileMenuLabel}\n >\n <TopbarLogo onClick={handleLogoClick} size='md'>\n <Logo\n size='md'\n logoSrc={logo.src}\n logoText={logo.appName}\n logoAlt={logo.alt || logo.appName}\n showText={true}\n />\n </TopbarLogo>\n </TopbarNavigation>\n </TopbarLeft>\n\n {renderCenterSection && (\n <TopbarCenter>{renderCenterSection()}</TopbarCenter>\n )}\n\n <TopbarRight>\n <TopbarActions gap='md'>\n {!hideLanguageSelector && (\n <LanguageSelector\n languages={languages}\n currentLanguage={currentLanguage}\n onLanguageChange={onLanguageChange}\n variant='compact'\n {...languageSelectorProps}\n />\n )}\n {renderAccountSection?.()}\n </TopbarActions>\n </TopbarRight>\n\n {renderMobileContent && (\n <TopbarMobileContent>{renderMobileContent()}</TopbarMobileContent>\n )}\n </Topbar>\n </TopbarProvider>\n );\n};\n\nexport default AppTopBar;\n","import React, { type ReactNode, type ComponentType } from 'react';\nimport { AppTopBar, type AppTopBarProps } from './app-topbar';\nimport { cn } from '../../utils';\nimport { GRADIENT_CLASSES } from '@sudobility/design';\n\n/**\n * Auth menu item for the authenticated user dropdown.\n * This matches the AuthMenuItem interface from @sudobility/auth-components.\n */\nexport interface AuthMenuItem {\n /** Unique identifier */\n id: string;\n /** Display label */\n label: string;\n /** Icon element (typically a small SVG) */\n icon?: ReactNode;\n /** Click handler */\n onClick?: () => void;\n /** Show divider after this item */\n dividerAfter?: boolean;\n}\n\n/**\n * Props for the AuthAction component from @sudobility/auth-components.\n */\nexport interface AuthActionProps {\n /** Avatar size in pixels */\n avatarSize?: number;\n /** Dropdown alignment */\n dropdownAlign?: 'left' | 'right';\n /** Login button click handler */\n onLoginClick?: () => void;\n /** Menu items for authenticated user dropdown */\n menuItems?: AuthMenuItem[];\n /** Custom login button text */\n loginButtonText?: string;\n /** Custom className for login button */\n loginButtonClassName?: string;\n}\n\nexport interface AppTopBarWithFirebaseAuthProps extends Omit<\n AppTopBarProps,\n 'renderAccountSection'\n> {\n /**\n * AuthAction component from @sudobility/auth-components.\n * This is passed as a prop to avoid hard dependency on auth-components.\n */\n AuthActionComponent: ComponentType<AuthActionProps>;\n\n /** Additional menu items for authenticated users */\n authenticatedMenuItems?: AuthMenuItem[];\n\n /** Login button click handler */\n onLoginClick?: () => void;\n\n /** Avatar size in pixels */\n avatarSize?: number;\n\n /** Dropdown alignment */\n dropdownAlign?: 'left' | 'right';\n\n /** Custom login button text */\n loginButtonText?: string;\n\n /** Custom login button className */\n loginButtonClassName?: string;\n}\n\n/**\n * AppTopBarWithFirebaseAuth - TopBar with Firebase authentication integration.\n *\n * This component wraps AppTopBar and provides the AuthAction component\n * from @sudobility/auth-components for the account section.\n *\n * Note: The AuthAction component must be passed as a prop to avoid\n * hard dependency on @sudobility/auth-components.\n *\n * @example\n * ```tsx\n * import { AuthAction } from '@sudobility/auth-components';\n *\n * <AppTopBarWithFirebaseAuth\n * logo={{ src: '/logo.png', appName: 'My App' }}\n * menuItems={[...]}\n * AuthActionComponent={AuthAction}\n * onLoginClick={() => navigate('/login')}\n * authenticatedMenuItems={[\n * { id: 'dashboard', label: 'Dashboard', onClick: () => navigate('/dashboard') },\n * ]}\n * />\n * ```\n */\nexport const AppTopBarWithFirebaseAuth: React.FC<\n AppTopBarWithFirebaseAuthProps\n> = ({\n AuthActionComponent,\n authenticatedMenuItems = [],\n onLoginClick,\n avatarSize = 32,\n dropdownAlign = 'right',\n loginButtonText,\n loginButtonClassName,\n ...topBarProps\n}) => {\n const renderAccountSection = () => (\n <AuthActionComponent\n avatarSize={avatarSize}\n dropdownAlign={dropdownAlign}\n onLoginClick={onLoginClick}\n menuItems={authenticatedMenuItems}\n loginButtonText={loginButtonText}\n loginButtonClassName={cn(\n GRADIENT_CLASSES.headerButton,\n loginButtonClassName\n )}\n />\n );\n\n return (\n <AppTopBar {...topBarProps} renderAccountSection={renderAccountSection} />\n );\n};\n\nexport default AppTopBarWithFirebaseAuth;\n","import React, { type ReactNode, type ComponentType } from 'react';\nimport { AppTopBar, type AppTopBarProps } from './app-topbar';\nimport { cn } from '../../utils';\nimport { GRADIENT_CLASSES } from '@sudobility/design';\n\n/**\n * Wallet menu item for the connected wallet dropdown.\n */\nexport interface WalletMenuItem {\n /** Unique identifier */\n id: string;\n /** Display label */\n label: string;\n /** Icon component */\n icon?: ComponentType<{ className?: string }>;\n /** Click handler */\n onClick: () => void;\n /** Whether this is a separator */\n separator?: boolean;\n}\n\n/**\n * Auth status enum matching @sudobility/types.\n */\nexport enum AuthStatus {\n DISCONNECTED = 'disconnected',\n CONNECTED = 'connected',\n VERIFIED = 'verified',\n}\n\n/**\n * Chain type enum matching @sudobility/types.\n */\nexport enum ChainType {\n EVM = 'evm',\n SOLANA = 'solana',\n}\n\n/**\n * Props for the WalletDropdownMenu component from @sudobility/web3-components.\n */\nexport interface WalletDropdownMenuProps {\n walletAddress: string;\n authStatus: AuthStatus | string;\n chainType: ChainType | string | 'unknown';\n menuItems: WalletMenuItem[];\n avatar?: string;\n displayName?: string;\n statusLabels?: {\n verified?: string;\n connected?: string;\n disconnected?: string;\n };\n}\n\nexport interface AppTopBarWithWalletProps extends Omit<\n AppTopBarProps,\n 'renderAccountSection'\n> {\n /**\n * WalletDropdownMenu component from @sudobility/web3-components.\n * This is passed as a prop to avoid hard dependency on web3-components.\n */\n WalletDropdownMenuComponent?: ComponentType<WalletDropdownMenuProps>;\n\n /** Whether wallet is connected */\n isConnected: boolean;\n\n /** Connected wallet address */\n walletAddress?: string;\n\n /** Authentication status */\n authStatus?: AuthStatus | string;\n\n /** Chain type (EVM, Solana, etc.) */\n chainType?: ChainType | string | 'unknown';\n\n /** Connect button click handler */\n onConnect: () => void;\n\n /** Disconnect handler */\n onDisconnect: () => Promise<void>;\n\n /** Custom menu items for wallet dropdown */\n walletMenuItems?: WalletMenuItem[];\n\n /** Connect button content (default: \"Connect Wallet\") */\n connectButtonContent?: ReactNode;\n\n /** Connect button className (supports gradient classes from @sudobility/design) */\n connectButtonClassName?: string;\n\n /** Use gradient styling for connect button */\n useGradientButton?: boolean;\n\n /** Optional user avatar */\n avatar?: string;\n\n /** Optional display name */\n displayName?: string;\n\n /** Custom status labels */\n statusLabels?: {\n verified?: string;\n connected?: string;\n disconnected?: string;\n };\n}\n\n/**\n * Default connect button when WalletDropdownMenuComponent is not provided\n * or when wallet is not connected.\n */\nconst DefaultConnectButton: React.FC<{\n onClick: () => void;\n content?: ReactNode;\n className?: string;\n useGradient?: boolean;\n}> = ({ onClick, content = 'Connect Wallet', className, useGradient }) => (\n <button\n onClick={onClick}\n className={cn(\n useGradient\n ? GRADIENT_CLASSES.headerButton\n : 'px-4 py-2 text-sm font-medium rounded-lg bg-blue-600 text-white hover:bg-blue-700 transition-colors',\n className\n )}\n >\n {content}\n </button>\n);\n\n/**\n * Simple fallback wallet display when WalletDropdownMenuComponent is not provided.\n */\nconst FallbackWalletDisplay: React.FC<{\n walletAddress: string;\n onDisconnect: () => Promise<void>;\n}> = ({ walletAddress, onDisconnect }) => {\n const truncatedAddress = `${walletAddress.slice(0, 6)}...${walletAddress.slice(-4)}`;\n\n return (\n <div className='flex items-center gap-2'>\n <span className='text-sm font-medium text-gray-700 dark:text-gray-300'>\n {truncatedAddress}\n </span>\n <button\n onClick={() => onDisconnect()}\n className='text-xs text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200'\n >\n Disconnect\n </button>\n </div>\n );\n};\n\n/**\n * AppTopBarWithWallet - TopBar with wallet connection integration.\n *\n * This component wraps AppTopBar and provides wallet connection UI\n * for the account section. Uses WalletDropdownMenu from @sudobility/web3-components\n * when provided.\n *\n * @example\n * ```tsx\n * import { WalletDropdownMenu } from '@sudobility/web3-components';\n *\n * <AppTopBarWithWallet\n * logo={{ src: '/logo.png', appName: 'My App' }}\n * menuItems={[...]}\n * WalletDropdownMenuComponent={WalletDropdownMenu}\n * isConnected={isConnected}\n * walletAddress={walletAddress}\n * authStatus={authStatus}\n * chainType={chainType}\n * onConnect={() => navigate('/connect')}\n * onDisconnect={handleDisconnect}\n * walletMenuItems={[\n * { id: 'copy', label: 'Copy Address', icon: ClipboardIcon, onClick: handleCopy },\n * { id: 'disconnect', label: 'Disconnect', icon: LogoutIcon, onClick: handleDisconnect },\n * ]}\n * />\n * ```\n */\nexport const AppTopBarWithWallet: React.FC<AppTopBarWithWalletProps> = ({\n WalletDropdownMenuComponent,\n isConnected,\n walletAddress,\n authStatus = AuthStatus.DISCONNECTED,\n chainType = 'unknown',\n onConnect,\n onDisconnect,\n walletMenuItems = [],\n connectButtonContent,\n connectButtonClassName,\n useGradientButton = true,\n avatar,\n displayName,\n statusLabels,\n ...topBarProps\n}) => {\n const renderAccountSection = () => {\n // Not connected - show connect button\n if (!isConnected || !walletAddress) {\n return (\n <DefaultConnectButton\n onClick={onConnect}\n content={connectButtonContent}\n className={connectButtonClassName}\n useGradient={useGradientButton}\n />\n );\n }\n\n // Connected with WalletDropdownMenu component\n if (WalletDropdownMenuComponent) {\n return (\n <WalletDropdownMenuComponent\n walletAddress={walletAddress}\n authStatus={authStatus}\n chainType={chainType}\n menuItems={walletMenuItems}\n avatar={avatar}\n displayName={displayName}\n statusLabels={statusLabels}\n />\n );\n }\n\n // Connected without WalletDropdownMenu - fallback display\n return (\n <FallbackWalletDisplay\n walletAddress={walletAddress}\n onDisconnect={onDisconnect}\n />\n );\n };\n\n return (\n <AppTopBar {...topBarProps} renderAccountSection={renderAccountSection} />\n );\n};\n\nexport default AppTopBarWithWallet;\n","import React, { type ComponentType } from 'react';\nimport { BreadcrumbSection } from '@sudobility/components';\nimport { CalendarDaysIcon } from '@heroicons/react/24/outline';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../../utils';\nimport type {\n BreadcrumbItem,\n ShareConfig,\n TalkToFounderConfig,\n LinkComponentProps,\n} from '../../types';\n\nconst breadcrumbContainerVariants = cva('border-b', {\n variants: {\n variant: {\n default: 'bg-white dark:bg-gray-800 border-gray-200 dark:border-gray-700',\n transparent: 'bg-transparent border-transparent',\n subtle:\n 'bg-gray-50 dark:bg-gray-900/50 border-gray-200 dark:border-gray-700',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n});\n\nexport interface AppBreadcrumbsProps extends VariantProps<\n typeof breadcrumbContainerVariants\n> {\n /** Breadcrumb items */\n items: BreadcrumbItem[];\n\n /** Share configuration (shows social share buttons on right) */\n shareConfig?: ShareConfig;\n\n /** Talk to founder button configuration */\n talkToFounder?: TalkToFounderConfig;\n\n /** Custom Link component */\n LinkComponent?: ComponentType<LinkComponentProps>;\n\n /** Custom className for the container */\n className?: string;\n\n /** Custom className for the inner content */\n contentClassName?: string;\n}\n\n/**\n * Default Talk to Founder button.\n */\nconst TalkToFounderButton: React.FC<{\n config: TalkToFounderConfig;\n}> = ({ config }) => {\n const IconComponent = config.icon || CalendarDaysIcon;\n const buttonText = config.buttonText || 'Talk to Founder';\n\n return (\n <a\n href={config.meetingUrl}\n target='_blank'\n rel='noopener noreferrer'\n className={cn(\n 'inline-flex items-center gap-2 px-3 py-1.5',\n 'text-sm font-medium',\n 'text-blue-600 dark:text-blue-400',\n 'hover:text-blue-700 dark:hover:text-blue-300',\n 'bg-blue-50 dark:bg-blue-900/20',\n 'hover:bg-blue-100 dark:hover:bg-blue-900/30',\n 'rounded-full',\n 'border border-blue-200 dark:border-blue-800',\n 'transition-colors'\n )}\n >\n <IconComponent className='h-4 w-4' />\n <span>{buttonText}</span>\n </a>\n );\n};\n\n/**\n * AppBreadcrumbs - Breadcrumb navigation with social share and \"Talk to Founder\" button.\n *\n * Features:\n * - Breadcrumb trail with links\n * - Social share buttons on the right\n * - Optional \"Talk to Founder\" meeting button\n * - Always renders at max-w-7xl width\n * - Dark mode support\n *\n * @example\n * ```tsx\n * <AppBreadcrumbs\n * items={[\n * { label: 'Home', href: '/' },\n * { label: 'Products', href: '/products' },\n * { label: 'Widget', current: true },\n * ]}\n * shareConfig={{\n * title: 'Check out this widget',\n * description: 'Amazing widget for your needs',\n * hashtags: ['widget', 'product'],\n * }}\n * talkToFounder={{\n * meetingUrl: 'https://calendly.com/founder/30min',\n * buttonText: 'Book a call',\n * }}\n * />\n * ```\n */\nexport const AppBreadcrumbs: React.FC<AppBreadcrumbsProps> = ({\n items,\n shareConfig,\n talkToFounder,\n variant = 'default',\n className,\n contentClassName,\n}) => {\n // Don't render if no items or only home\n if (!items || items.length === 0) {\n return null;\n }\n\n return (\n <div className={cn(breadcrumbContainerVariants({ variant }), className)}>\n <div className={cn('max-w-7xl mx-auto px-4 py-3', contentClassName)}>\n <div className='flex items-center justify-between gap-4'>\n {/* Breadcrumb trail */}\n <div className='flex-1 min-w-0'>\n <BreadcrumbSection items={items} shareConfig={shareConfig} />\n </div>\n\n {/* Right side: Talk to Founder + Share (if shareConfig, share is handled by BreadcrumbSection) */}\n {talkToFounder && (\n <div className='flex items-center gap-3 flex-shrink-0'>\n <TalkToFounderButton config={talkToFounder} />\n </div>\n )}\n </div>\n </div>\n </div>\n );\n};\n\nexport default AppBreadcrumbs;\n","import React, { type ComponentType } from 'react';\nimport {\n Footer as FooterContainer,\n FooterCompact,\n FooterCompactLeft,\n FooterCompactRight,\n FooterVersion,\n FooterCopyright,\n} from '@sudobility/components';\nimport { cn } from '../../utils';\nimport type {\n StatusIndicatorConfig,\n LinkComponentProps,\n FooterLinkItem,\n} from '../../types';\n\n/**\n * Props for the SystemStatusIndicator component from @sudobility/devops-components.\n */\nexport interface SystemStatusIndicatorProps {\n statusPageUrl: string;\n apiEndpoint?: string;\n refreshInterval?: number;\n size?: 'sm' | 'md' | 'lg';\n version?: string;\n isNetworkOnline?: boolean;\n}\n\nexport interface AppFooterProps {\n /** App version string */\n version?: string;\n\n /** Copyright year or range (e.g., \"2025\" or \"2025-2026\") */\n copyrightYear?: string;\n\n /** Company name */\n companyName: string;\n\n /** Company URL (optional - creates a link if provided) */\n companyUrl?: string;\n\n /** Rights text (e.g., \"All rights reserved\") */\n rightsText?: string;\n\n /** Status indicator config (optional) */\n statusIndicator?: StatusIndicatorConfig;\n\n /**\n * SystemStatusIndicator component from @sudobility/devops-components.\n * Pass this to enable status indicator functionality.\n */\n StatusIndicatorComponent?: ComponentType<SystemStatusIndicatorProps>;\n\n /** Right-side links (e.g., Privacy, Terms) */\n links?: FooterLinkItem[];\n\n /** Custom Link component */\n LinkComponent?: ComponentType<LinkComponentProps>;\n\n /** Sticky positioning (sticks to bottom of viewport) */\n sticky?: boolean;\n\n /** Network online status (for status indicator) */\n isNetworkOnline?: boolean;\n\n /** Custom className */\n className?: string;\n}\n\n/**\n * Default link component that renders a plain anchor.\n */\nconst DefaultLinkComponent: ComponentType<LinkComponentProps> = ({\n href,\n className,\n children,\n onClick,\n}) => (\n <a href={href} className={className} onClick={onClick}>\n {children}\n </a>\n);\n\n/**\n * Helper to get copyright year or range.\n */\nfunction getCopyrightYear(startYear = 2025): string {\n const currentYear = new Date().getFullYear();\n if (currentYear === startYear) {\n return String(startYear);\n } else if (currentYear > startYear) {\n return `${startYear}-${currentYear}`;\n }\n return String(startYear);\n}\n\n/**\n * AppFooter - Compact footer for app pages.\n *\n * Features:\n * - Version display\n * - Copyright with company name\n * - System status indicator (optional)\n * - Right-side links (Privacy, Terms, etc.)\n * - Sticky positioning option\n * - Dark mode support\n *\n * @example\n * ```tsx\n * import { SystemStatusIndicator } from '@sudobility/devops-components';\n *\n * <AppFooter\n * version=\"1.0.0\"\n * companyName=\"Sudobility Inc.\"\n * companyUrl=\"/\"\n * rightsText=\"All rights reserved\"\n * statusIndicator={{\n * statusPageUrl: 'https://status.example.com',\n * apiEndpoint: 'https://status.example.com/api/v1/status',\n * }}\n * StatusIndicatorComponent={SystemStatusIndicator}\n * links={[\n * { label: 'Privacy', href: '/privacy' },\n * { label: 'Terms', href: '/terms' },\n * ]}\n * sticky\n * />\n * ```\n */\nexport const AppFooter: React.FC<AppFooterProps> = ({\n version,\n copyrightYear,\n companyName,\n companyUrl,\n rightsText = 'All rights reserved',\n statusIndicator,\n StatusIndicatorComponent,\n links = [],\n LinkComponent = DefaultLinkComponent,\n sticky = true,\n isNetworkOnline = true,\n className,\n}) => {\n const year = copyrightYear || getCopyrightYear();\n\n const companyLink = companyUrl ? (\n <LinkComponent\n href={companyUrl}\n className='text-blue-400 hover:text-blue-300 transition-colors'\n >\n {companyName}\n </LinkComponent>\n ) : undefined;\n\n return (\n <FooterContainer\n variant='compact'\n sticky={sticky}\n className={cn(className)}\n >\n <FooterCompact>\n <FooterCompactLeft>\n {version && <FooterVersion version={version} />}\n <FooterCopyright\n year={year}\n companyName={companyName}\n rightsText={rightsText}\n companyLink={companyLink}\n />\n {statusIndicator && StatusIndicatorComponent && (\n <StatusIndicatorComponent\n statusPageUrl={statusIndicator.statusPageUrl}\n apiEndpoint={statusIndicator.apiEndpoint}\n refreshInterval={statusIndicator.refreshInterval || 60000}\n size='sm'\n version={version}\n isNetworkOnline={isNetworkOnline}\n />\n )}\n </FooterCompactLeft>\n <FooterCompactRight>\n {links.map((link, index) => (\n <React.Fragment key={link.href || index}>\n {link.onClick ? (\n <button\n onClick={link.onClick}\n className='text-gray-400 hover:text-white transition-colors'\n >\n {link.label}\n </button>\n ) : (\n <LinkComponent\n href={link.href}\n className='text-gray-400 hover:text-white transition-colors'\n >\n {link.label}\n </LinkComponent>\n )}\n </React.Fragment>\n ))}\n </FooterCompactRight>\n </FooterCompact>\n </FooterContainer>\n );\n};\n\nexport default AppFooter;\n","import React, { type ComponentType } from 'react';\nimport {\n Logo,\n Footer as FooterContainer,\n FooterGrid,\n FooterBrand,\n FooterLinkSection,\n FooterLink,\n FooterBottom,\n FooterVersion,\n FooterCopyright,\n FooterSocialLinks,\n} from '@sudobility/components';\nimport { cn } from '../../utils';\nimport type {\n StatusIndicatorConfig,\n LinkComponentProps,\n FooterLinkSection as FooterLinkSectionConfig,\n SocialLinksConfig,\n} from '../../types';\nimport type { SystemStatusIndicatorProps } from './app-footer';\n\nexport interface AppFooterForHomePageProps {\n /** App logo configuration */\n logo: {\n /** Logo image src (optional - if not provided, uses Logo component) */\n src?: string;\n /** App name */\n appName: string;\n };\n\n /** Footer link sections (columns of links) */\n linkSections: FooterLinkSectionConfig[];\n\n /** Social media links */\n socialLinks?: SocialLinksConfig;\n\n /** System status indicator configuration */\n statusIndicator?: StatusIndicatorConfig;\n\n /**\n * SystemStatusIndicator component from @sudobility/devops-components.\n * Pass this to enable status indicator functionality.\n */\n StatusIndicatorComponent?: ComponentType<SystemStatusIndicatorProps>;\n\n /** App version string */\n version?: string;\n\n /** Copyright year or range */\n copyrightYear?: string;\n\n /** Company name for copyright */\n companyName: string;\n\n /** Company link URL (optional) */\n companyUrl?: string;\n\n /** Footer description text (below logo) */\n description?: string;\n\n /** Rights text (e.g., \"All rights reserved\") */\n rightsText?: string;\n\n /** Custom Link component */\n LinkComponent?: ComponentType<LinkComponentProps>;\n\n /** Network online status (for status indicator) */\n isNetworkOnline?: boolean;\n\n /** Custom className */\n className?: string;\n\n /** Number of columns for link grid (default: auto based on section count) */\n gridColumns?: 2 | 3 | 4 | 5;\n}\n\n/**\n * Default link component that renders a plain anchor.\n */\nconst DefaultLinkComponent: ComponentType<LinkComponentProps> = ({\n href,\n className,\n children,\n onClick,\n}) => (\n <a href={href} className={className} onClick={onClick}>\n {children}\n </a>\n);\n\n/**\n * Helper to get copyright year or range.\n */\nfunction getCopyrightYear(startYear = 2025): string {\n const currentYear = new Date().getFullYear();\n if (currentYear === startYear) {\n return String(startYear);\n } else if (currentYear > startYear) {\n return `${startYear}-${currentYear}`;\n }\n return String(startYear);\n}\n\n/**\n * Get grid columns class based on section count.\n */\nfunction getGridColumnsClass(sectionCount: number, explicit?: number): string {\n const cols = explicit || Math.min(sectionCount, 4);\n switch (cols) {\n case 2:\n return 'md:grid-cols-2';\n case 3:\n return 'md:grid-cols-3';\n case 4:\n return 'md:grid-cols-4';\n case 5:\n return 'md:grid-cols-5';\n default:\n return 'md:grid-cols-4';\n }\n}\n\n/**\n * AppFooterForHomePage - Full footer for home/landing pages.\n *\n * Features:\n * - Multiple link sections in a grid\n * - Logo and brand description\n * - Social media links\n * - System status indicator (optional)\n * - Version and copyright\n * - Dark mode support\n *\n * @example\n * ```tsx\n * import { SystemStatusIndicator } from '@sudobility/devops-components';\n *\n * <AppFooterForHomePage\n * logo={{ appName: 'My App' }}\n * linkSections={[\n * {\n * title: 'Product',\n * links: [\n * { label: 'Features', href: '/features' },\n * { label: 'Pricing', href: '/pricing' },\n * ],\n * },\n * {\n * title: 'Company',\n * links: [\n * { label: 'About', href: '/about' },\n * { label: 'Contact', href: '/contact' },\n * ],\n * },\n * ]}\n * socialLinks={{\n * twitterUrl: 'https://twitter.com/myapp',\n * discordUrl: 'https://discord.gg/myapp',\n * }}\n * statusIndicator={{\n * statusPageUrl: 'https://status.example.com',\n * }}\n * StatusIndicatorComponent={SystemStatusIndicator}\n * version=\"1.0.0\"\n * companyName=\"Sudobility Inc.\"\n * description=\"Building the future of web3 communication\"\n * />\n * ```\n */\nexport const AppFooterForHomePage: React.FC<AppFooterForHomePageProps> = ({\n logo,\n linkSections,\n socialLinks,\n statusIndicator,\n StatusIndicatorComponent,\n version,\n copyrightYear,\n companyName,\n companyUrl,\n description,\n rightsText = 'All rights reserved',\n LinkComponent = DefaultLinkComponent,\n isNetworkOnline = true,\n className,\n gridColumns,\n}) => {\n const year = copyrightYear || getCopyrightYear();\n const gridClass = getGridColumnsClass(linkSections.length, gridColumns);\n\n const companyLink = companyUrl ? (\n <LinkComponent\n href={companyUrl}\n className='text-blue-400 hover:text-blue-300 transition-colors'\n >\n {companyName}\n </LinkComponent>\n ) : undefined;\n\n return (\n <FooterContainer variant='full' className={cn(className)}>\n <FooterGrid className={gridClass}>\n {linkSections.map((section, sectionIndex) => (\n <FooterLinkSection\n key={section.title || sectionIndex}\n title={section.title}\n >\n {section.links.map((link, linkIndex) => (\n <FooterLink key={link.href || linkIndex}>\n {link.onClick ? (\n <button onClick={link.onClick} className='text-left'>\n {link.label}\n </button>\n ) : (\n <LinkComponent href={link.href}>{link.label}</LinkComponent>\n )}\n </FooterLink>\n ))}\n </FooterLinkSection>\n ))}\n </FooterGrid>\n\n <FooterBottom>\n <FooterBrand\n description={description}\n className='flex flex-col items-center'\n >\n <LinkComponent\n href='/'\n className='text-white hover:opacity-80 transition-opacity'\n >\n {logo.src ? (\n <img\n src={logo.src}\n alt={logo.appName}\n className='h-8 object-contain'\n />\n ) : (\n <Logo size='md' showText={true} logoText={logo.appName} />\n )}\n </LinkComponent>\n </FooterBrand>\n {version && <FooterVersion version={version} />}\n <FooterCopyright\n year={year}\n companyName={companyName}\n rightsText={rightsText}\n companyLink={companyLink}\n />\n {statusIndicator && StatusIndicatorComponent && (\n <StatusIndicatorComponent\n statusPageUrl={statusIndicator.statusPageUrl}\n apiEndpoint={statusIndicator.apiEndpoint}\n refreshInterval={statusIndicator.refreshInterval || 60000}\n size='sm'\n version={version}\n isNetworkOnline={isNetworkOnline}\n />\n )}\n </FooterBottom>\n\n {socialLinks && (\n <div className='flex justify-center mt-4'>\n <FooterSocialLinks\n twitterUrl={socialLinks.twitterUrl}\n discordUrl={socialLinks.discordUrl}\n linkedinUrl={socialLinks.linkedinUrl}\n githubUrl={socialLinks.githubUrl}\n redditUrl={socialLinks.redditUrl}\n farcasterUrl={socialLinks.farcasterUrl}\n telegramUrl={socialLinks.telegramUrl}\n />\n </div>\n )}\n </FooterContainer>\n );\n};\n\nexport default AppFooterForHomePage;\n","import React, { type ReactNode } from 'react';\nimport { LayoutProvider } from '@sudobility/components';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../../utils';\nimport {\n AppBreadcrumbs,\n type AppBreadcrumbsProps,\n} from '../breadcrumbs/app-breadcrumbs';\nimport type { MaxWidth, ContentPadding, BackgroundVariant } from '../../types';\n\nconst layoutVariants = cva('min-h-screen flex flex-col', {\n variants: {\n background: {\n default: 'bg-gray-50 dark:bg-gray-900',\n white: 'bg-white dark:bg-gray-900',\n gradient:\n 'bg-gradient-to-br from-gray-50 to-blue-50 dark:from-gray-900 dark:to-gray-800',\n },\n },\n defaultVariants: {\n background: 'default',\n },\n});\n\nconst maxWidthClasses: Record<MaxWidth, string> = {\n sm: 'max-w-sm',\n md: 'max-w-md',\n lg: 'max-w-lg',\n xl: 'max-w-xl',\n '2xl': 'max-w-2xl',\n '4xl': 'max-w-4xl',\n '7xl': 'max-w-7xl',\n full: 'max-w-full',\n};\n\nconst paddingClasses: Record<ContentPadding, string> = {\n none: '',\n sm: 'px-4 sm:px-6 py-6',\n md: 'px-4 py-8',\n lg: 'px-4 py-12',\n};\n\nexport interface AppPageLayoutProps extends VariantProps<\n typeof layoutVariants\n> {\n /** Page content */\n children: ReactNode;\n\n /** TopBar slot - pass an AppTopBar variant or custom component */\n topBar: ReactNode;\n\n /** Breadcrumbs configuration (optional) */\n breadcrumbs?: AppBreadcrumbsProps;\n\n /** Footer slot - pass an AppFooter variant or custom component */\n footer?: ReactNode;\n\n /** Max width for content area (default: '7xl') */\n maxWidth?: MaxWidth;\n\n /** Content padding (default: 'md') */\n contentPadding?: ContentPadding;\n\n /** Background variant */\n background?: BackgroundVariant;\n\n /** Layout mode for LayoutProvider */\n layoutMode?: 'standard';\n\n /** Custom className for the layout container */\n className?: string;\n\n /** Custom className for the content area */\n contentClassName?: string;\n\n /** Custom className for the main element */\n mainClassName?: string;\n}\n\n/**\n * AppPageLayout - Layout wrapper combining TopBar, Breadcrumbs, Content, and Footer.\n *\n * Features:\n * - Flexible slots for TopBar and Footer\n * - Optional breadcrumbs with share and \"Talk to Founder\"\n * - Configurable content max-width and padding\n * - Background variants\n * - Dark mode support\n * - Sticky footer behavior\n *\n * @example\n * ```tsx\n * <AppPageLayout\n * topBar={\n * <AppTopBarWithFirebaseAuth\n * logo={{ src: '/logo.png', appName: 'My App' }}\n * menuItems={menuItems}\n * AuthActionComponent={AuthAction}\n * onLoginClick={() => navigate('/login')}\n * />\n * }\n * breadcrumbs={{\n * items: breadcrumbItems,\n * shareConfig: { title: 'Page', description: 'Description', hashtags: [] },\n * }}\n * footer={\n * <AppFooter\n * version=\"1.0.0\"\n * companyName=\"My Company\"\n * links={[{ label: 'Privacy', href: '/privacy' }]}\n * />\n * }\n * maxWidth=\"7xl\"\n * background=\"default\"\n * >\n * <h1>Page Content</h1>\n * </AppPageLayout>\n * ```\n */\nexport const AppPageLayout: React.FC<AppPageLayoutProps> = ({\n children,\n topBar,\n breadcrumbs,\n footer,\n maxWidth = '7xl',\n contentPadding = 'md',\n background = 'default',\n layoutMode = 'standard',\n className,\n contentClassName,\n mainClassName,\n}) => {\n return (\n <LayoutProvider mode={layoutMode}>\n <div className={cn(layoutVariants({ background }), className)}>\n {/* Header Section */}\n <header>{topBar}</header>\n\n {/* Breadcrumb Section */}\n {breadcrumbs && breadcrumbs.items && breadcrumbs.items.length > 0 && (\n <AppBreadcrumbs {...breadcrumbs} />\n )}\n\n {/* Main Content */}\n <main className={cn('flex-1 overflow-auto', mainClassName)}>\n <div\n className={cn(\n 'mx-auto',\n maxWidthClasses[maxWidth],\n paddingClasses[contentPadding],\n contentClassName\n )}\n >\n {children}\n </div>\n </main>\n\n {/* Footer */}\n {footer && <footer>{footer}</footer>}\n </div>\n </LayoutProvider>\n );\n};\n\nexport default AppPageLayout;\n","import React from 'react';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Label,\n} from '@sudobility/components';\nimport { textVariants } from '@sudobility/design';\n\n/**\n * Theme options for appearance settings.\n */\nexport enum Theme {\n LIGHT = 'light',\n DARK = 'dark',\n SYSTEM = 'system',\n}\n\n/**\n * Font size options for appearance settings.\n */\nexport enum FontSize {\n SMALL = 'small',\n MEDIUM = 'medium',\n LARGE = 'large',\n}\n\n/**\n * Translation keys used by AppearanceSettings.\n * Provide a translation function to customize labels.\n */\nexport interface AppearanceSettingsTranslations {\n heading: string;\n description: string;\n themeLabel: string;\n themeSelectPlaceholder: string;\n themeLight: string;\n themeDark: string;\n themeSystem: string;\n themeDescription: string;\n fontSizeLabel: string;\n fontSizeSelectPlaceholder: string;\n fontSizeSmall: string;\n fontSizeMedium: string;\n fontSizeLarge: string;\n fontSizeDescription: string;\n infoHeading: string;\n infoDescription: string;\n}\n\nconst defaultTranslations: AppearanceSettingsTranslations = {\n heading: 'Appearance',\n description: 'Customize the look and feel of the application.',\n themeLabel: 'Theme',\n themeSelectPlaceholder: 'Select theme',\n themeLight: 'Light',\n themeDark: 'Dark',\n themeSystem: 'System',\n themeDescription: 'Choose your preferred color theme.',\n fontSizeLabel: 'Font Size',\n fontSizeSelectPlaceholder: 'Select font size',\n fontSizeSmall: 'Small',\n fontSizeMedium: 'Medium',\n fontSizeLarge: 'Large',\n fontSizeDescription: 'Adjust the text size for better readability.',\n infoHeading: 'About Settings',\n infoDescription:\n 'Your appearance preferences are saved locally and will be applied automatically on your next visit.',\n};\n\nexport interface AppearanceSettingsProps {\n /** Current theme value */\n theme: Theme | string;\n\n /** Current font size value */\n fontSize: FontSize | string;\n\n /** Callback when theme changes */\n onThemeChange: (theme: Theme) => void;\n\n /** Callback when font size changes */\n onFontSizeChange: (fontSize: FontSize) => void;\n\n /**\n * Optional translation function.\n * If provided, will be called with a key from AppearanceSettingsTranslations.\n * Falls back to default English strings if not provided.\n */\n t?: (key: string, fallback?: string) => string;\n\n /** Optional className for the container */\n className?: string;\n\n /** Whether to show the information box at the bottom */\n showInfoBox?: boolean;\n}\n\n/**\n * AppearanceSettings - A reusable component for theme and font size settings.\n *\n * This component can be used across different apps to provide consistent\n * appearance customization options.\n *\n * @example\n * ```tsx\n * // Basic usage with useTheme hook\n * const { theme, fontSize, setTheme, setFontSize } = useTheme();\n *\n * <AppearanceSettings\n * theme={theme}\n * fontSize={fontSize}\n * onThemeChange={setTheme}\n * onFontSizeChange={setFontSize}\n * />\n *\n * // With i18n translation\n * const { t } = useTranslation('settings');\n *\n * <AppearanceSettings\n * theme={theme}\n * fontSize={fontSize}\n * onThemeChange={setTheme}\n * onFontSizeChange={setFontSize}\n * t={(key, fallback) => t(`appearance.${key}`, fallback)}\n * />\n * ```\n */\nexport const AppearanceSettings: React.FC<AppearanceSettingsProps> = ({\n theme,\n fontSize,\n onThemeChange,\n onFontSizeChange,\n t,\n className,\n showInfoBox = true,\n}) => {\n // Helper to get translated string with fallback\n const getText = (key: keyof AppearanceSettingsTranslations): string => {\n const fallback = defaultTranslations[key];\n return t ? t(key, fallback) : fallback;\n };\n\n return (\n <div className={className}>\n <div className='space-y-6'>\n <div>\n <h2 className={`${textVariants.heading.h4()} mb-2`}>\n {getText('heading')}\n </h2>\n <p\n className={`${textVariants.body.sm()} text-gray-600 dark:text-gray-400`}\n >\n {getText('description')}\n </p>\n </div>\n\n <div className='space-y-6'>\n {/* Theme Setting */}\n <div className='space-y-2'>\n <Label\n htmlFor='theme-select'\n className={textVariants.label.default()}\n >\n {getText('themeLabel')}\n </Label>\n <Select\n value={theme}\n onValueChange={(value: string) => onThemeChange(value as Theme)}\n >\n <SelectTrigger id='theme-select'>\n <SelectValue placeholder={getText('themeSelectPlaceholder')} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={Theme.LIGHT}>\n {getText('themeLight')}\n </SelectItem>\n <SelectItem value={Theme.DARK}>\n {getText('themeDark')}\n </SelectItem>\n <SelectItem value={Theme.SYSTEM}>\n {getText('themeSystem')}\n </SelectItem>\n </SelectContent>\n </Select>\n <p\n className={`${textVariants.body.xs()} text-gray-500 dark:text-gray-400`}\n >\n {getText('themeDescription')}\n </p>\n </div>\n\n {/* Font Size Setting */}\n <div className='space-y-2'>\n <Label\n htmlFor='font-size-select'\n className={textVariants.label.default()}\n >\n {getText('fontSizeLabel')}\n </Label>\n <Select\n value={fontSize}\n onValueChange={(value: string) =>\n onFontSizeChange(value as FontSize)\n }\n >\n <SelectTrigger id='font-size-select'>\n <SelectValue\n placeholder={getText('fontSizeSelectPlaceholder')}\n />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={FontSize.SMALL}>\n {getText('fontSizeSmall')}\n </SelectItem>\n <SelectItem value={FontSize.MEDIUM}>\n {getText('fontSizeMedium')}\n </SelectItem>\n <SelectItem value={FontSize.LARGE}>\n {getText('fontSizeLarge')}\n </SelectItem>\n </SelectContent>\n </Select>\n <p\n className={`${textVariants.body.xs()} text-gray-500 dark:text-gray-400`}\n >\n {getText('fontSizeDescription')}\n </p>\n </div>\n </div>\n\n {/* Information Box */}\n {showInfoBox && (\n <div className='bg-blue-50 dark:bg-blue-900/20 rounded-lg p-4 border border-blue-200 dark:border-blue-800'>\n <h4 className='text-sm font-medium text-blue-900 dark:text-blue-100 mb-2'>\n {getText('infoHeading')}\n </h4>\n <p className='text-sm text-blue-700 dark:text-blue-300'>\n {getText('infoDescription')}\n </p>\n </div>\n )}\n </div>\n </div>\n );\n};\n\nexport default AppearanceSettings;\n"],"names":["DefaultLinkComponent","className","AuthStatus","ChainType","getCopyrightYear","FooterContainer","Theme","FontSize"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/utils/index.ts","../src/constants/languages.ts","../src/components/topbar/language-selector.tsx","../src/components/topbar/app-topbar.tsx","../src/components/topbar/app-topbar-with-firebase-auth.tsx","../src/components/topbar/app-topbar-with-wallet.tsx","../src/components/breadcrumbs/app-breadcrumbs.tsx","../src/components/footer/app-footer.tsx","../src/components/footer/app-footer-for-home-page.tsx","../src/components/layout/app-page-layout.tsx","../src/components/settings/appearance-settings.tsx"],"sourcesContent":["import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\n/**\n * Merge class names with Tailwind CSS classes.\n * Combines clsx for conditional classes and tailwind-merge for deduplication.\n */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","export interface LanguageConfig {\n code: string;\n name: string;\n flag: string;\n}\n\n/**\n * Default set of 16 supported languages with their flags.\n * Apps can override this list by passing their own languages prop.\n */\nexport const DEFAULT_LANGUAGES: LanguageConfig[] = [\n { code: 'en', name: 'English', flag: '🇺🇸' },\n { code: 'ar', name: 'العربية', flag: '🇸🇦' },\n { code: 'de', name: 'Deutsch', flag: '🇩🇪' },\n { code: 'es', name: 'Español', flag: '🇪🇸' },\n { code: 'fr', name: 'Français', flag: '🇫🇷' },\n { code: 'it', name: 'Italiano', flag: '🇮🇹' },\n { code: 'ja', name: '日本語', flag: '🇯🇵' },\n { code: 'ko', name: '한국어', flag: '🇰🇷' },\n { code: 'pt', name: 'Português', flag: '🇵🇹' },\n { code: 'ru', name: 'Русский', flag: '🇷🇺' },\n { code: 'sv', name: 'Svenska', flag: '🇸🇪' },\n { code: 'th', name: 'ไทย', flag: '🇹🇭' },\n { code: 'uk', name: 'Українська', flag: '🇺🇦' },\n { code: 'vi', name: 'Tiếng Việt', flag: '🇻🇳' },\n { code: 'zh', name: '简体中文', flag: '🇨🇳' },\n { code: 'zh-hant', name: '繁體中文', flag: '🇹🇼' },\n];\n\n/**\n * Languages that use right-to-left text direction.\n */\nexport const RTL_LANGUAGES = ['ar'];\n\n/**\n * Check if a language code is RTL.\n */\nexport function isRTL(languageCode: string): boolean {\n return RTL_LANGUAGES.includes(languageCode);\n}\n","import React, {\n useState,\n useCallback,\n useMemo,\n useRef,\n useEffect,\n} from 'react';\nimport { ChevronDownIcon } from '@heroicons/react/24/outline';\nimport { cn } from '../../utils';\nimport {\n DEFAULT_LANGUAGES,\n type LanguageConfig,\n} from '../../constants/languages';\n\nexport interface LanguageSelectorProps {\n /** Available languages (defaults to 16 built-in languages) */\n languages?: LanguageConfig[];\n /** Current language code */\n currentLanguage?: string;\n /** Language change handler */\n onLanguageChange?: (languageCode: string) => void;\n /** Variant: 'compact' for topbar, 'full' for settings */\n variant?: 'compact' | 'full';\n /** Custom className */\n className?: string;\n /** Label text for full variant */\n label?: string;\n /** Helper text for full variant */\n helperText?: string;\n}\n\n/**\n * LanguageSelector component with dropdown for switching languages.\n * Uses default 16 languages if none provided.\n */\nexport const LanguageSelector: React.FC<LanguageSelectorProps> = ({\n languages = DEFAULT_LANGUAGES,\n currentLanguage = 'en',\n onLanguageChange,\n variant = 'compact',\n className,\n label = 'Language',\n helperText = 'Select your preferred language',\n}) => {\n const [isOpen, setIsOpen] = useState(false);\n const dropdownRef = useRef<HTMLDivElement>(null);\n\n // Sort languages alphabetically by name\n const sortedLanguages = useMemo(\n () => [...languages].sort((a, b) => a.name.localeCompare(b.name)),\n [languages]\n );\n\n const currentLang = useMemo(\n () => languages.find(lang => lang.code === currentLanguage) || languages[0],\n [languages, currentLanguage]\n );\n\n const handleLanguageChange = useCallback(\n (langCode: string) => {\n if (langCode !== currentLanguage) {\n onLanguageChange?.(langCode);\n }\n setIsOpen(false);\n },\n [currentLanguage, onLanguageChange]\n );\n\n // Close dropdown when clicking outside\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (\n dropdownRef.current &&\n !dropdownRef.current.contains(event.target as Node)\n ) {\n setIsOpen(false);\n }\n };\n\n if (isOpen) {\n document.addEventListener('mousedown', handleClickOutside);\n return () =>\n document.removeEventListener('mousedown', handleClickOutside);\n }\n }, [isOpen]);\n\n // Close dropdown on escape\n useEffect(() => {\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n setIsOpen(false);\n }\n };\n\n if (isOpen) {\n document.addEventListener('keydown', handleEscape);\n return () => document.removeEventListener('keydown', handleEscape);\n }\n }, [isOpen]);\n\n if (variant === 'compact') {\n return (\n <div ref={dropdownRef} className={cn('relative', className)}>\n <button\n onClick={() => setIsOpen(!isOpen)}\n className={cn(\n 'flex items-center gap-2 px-3 py-2 h-10 rounded-lg',\n 'hover:bg-gray-100 dark:hover:bg-gray-700',\n 'transition-colors'\n )}\n aria-label='Select language'\n aria-expanded={isOpen}\n aria-haspopup='listbox'\n >\n <span className='text-lg leading-none'>{currentLang?.flag}</span>\n <span className='hidden sm:block text-sm font-medium text-gray-700 dark:text-gray-300'>\n {currentLang?.name}\n </span>\n <ChevronDownIcon\n className={cn(\n 'h-4 w-4 text-gray-500 dark:text-gray-400 transition-transform',\n isOpen && 'rotate-180'\n )}\n />\n </button>\n\n {isOpen && (\n <div\n className={cn(\n 'absolute right-0 mt-2 w-48 py-1 z-50',\n 'bg-white dark:bg-gray-800',\n 'border border-gray-200 dark:border-gray-700',\n 'rounded-lg shadow-lg'\n )}\n role='listbox'\n aria-label='Languages'\n >\n {sortedLanguages.map(lang => (\n <button\n key={lang.code}\n onClick={() => handleLanguageChange(lang.code)}\n className={cn(\n 'w-full flex items-center gap-3 px-3 py-2 text-left',\n 'hover:bg-gray-100 dark:hover:bg-gray-700',\n 'transition-colors',\n lang.code === currentLanguage &&\n 'bg-gray-100 dark:bg-gray-700 font-medium'\n )}\n role='option'\n aria-selected={lang.code === currentLanguage}\n >\n <span className='text-lg leading-none'>{lang.flag}</span>\n <span className='text-sm text-gray-700 dark:text-gray-300'>\n {lang.name}\n </span>\n </button>\n ))}\n </div>\n )}\n </div>\n );\n }\n\n // Full variant for settings pages\n return (\n <div ref={dropdownRef} className={cn('space-y-2', className)}>\n <label className='text-sm font-medium text-gray-700 dark:text-gray-300 flex items-center gap-2'>\n <span>{label}</span>\n </label>\n\n <div className='relative'>\n <button\n onClick={() => setIsOpen(!isOpen)}\n className={cn(\n 'flex items-center justify-between w-full px-3 py-2 text-left',\n 'bg-white dark:bg-gray-800',\n 'border border-gray-300 dark:border-gray-600',\n 'rounded-md',\n 'hover:bg-gray-50 dark:hover:bg-gray-700',\n 'transition-colors'\n )}\n aria-expanded={isOpen}\n aria-haspopup='listbox'\n >\n <div className='flex items-center gap-2'>\n <span className='text-lg leading-none'>{currentLang?.flag}</span>\n <span className='text-sm text-gray-700 dark:text-gray-300'>\n {currentLang?.name}\n </span>\n </div>\n <ChevronDownIcon\n className={cn(\n 'h-4 w-4 text-gray-500 dark:text-gray-400 transition-transform',\n isOpen && 'rotate-180'\n )}\n />\n </button>\n\n {isOpen && (\n <div\n className={cn(\n 'absolute left-0 right-0 mt-1 py-1 z-50',\n 'bg-white dark:bg-gray-800',\n 'border border-gray-200 dark:border-gray-700',\n 'rounded-md shadow-lg'\n )}\n role='listbox'\n aria-label='Languages'\n >\n {sortedLanguages.map(lang => (\n <button\n key={lang.code}\n onClick={() => handleLanguageChange(lang.code)}\n className={cn(\n 'w-full flex items-center gap-3 px-3 py-2 text-left',\n 'hover:bg-gray-100 dark:hover:bg-gray-700',\n 'transition-colors',\n lang.code === currentLanguage &&\n 'bg-gray-100 dark:bg-gray-700 font-medium'\n )}\n role='option'\n aria-selected={lang.code === currentLanguage}\n >\n <span className='text-lg leading-none'>{lang.flag}</span>\n <span className='text-sm text-gray-700 dark:text-gray-300'>\n {lang.name}\n </span>\n </button>\n ))}\n </div>\n )}\n </div>\n\n {helperText && (\n <p className='text-xs text-gray-500 dark:text-gray-400'>{helperText}</p>\n )}\n </div>\n );\n};\n\nexport default LanguageSelector;\n","import React, { useMemo, type ComponentType, type ReactNode } from 'react';\nimport {\n Topbar,\n TopbarProvider,\n TopbarLeft,\n TopbarCenter,\n TopbarRight,\n TopbarLogo,\n TopbarNavigation,\n TopbarActions,\n TopbarMobileContent,\n Logo,\n type TopbarNavItem,\n} from '@sudobility/components';\nimport { cn } from '../../utils';\nimport {\n LanguageSelector,\n type LanguageSelectorProps,\n} from './language-selector';\nimport type {\n MenuItemConfig,\n LogoConfig,\n LanguageConfig,\n LinkComponentProps,\n} from '../../types';\nimport { DEFAULT_LANGUAGES } from '../../constants/languages';\n\nexport interface AppTopBarProps {\n /** Logo configuration */\n logo: LogoConfig;\n\n /** Navigation menu items */\n menuItems: MenuItemConfig[];\n\n /** Available languages for selector (defaults to 16 built-in languages) */\n languages?: LanguageConfig[];\n\n /** Current language code */\n currentLanguage?: string;\n\n /** Language change handler */\n onLanguageChange?: (languageCode: string) => void;\n\n /** Hide language selector */\n hideLanguageSelector?: boolean;\n\n /** Language selector props override */\n languageSelectorProps?: Partial<LanguageSelectorProps>;\n\n /** Breakpoint to collapse navigation to hamburger menu */\n collapseBelow?: 'sm' | 'md' | 'lg' | 'xl';\n\n /** Render prop for account/auth section (right side of topbar) */\n renderAccountSection?: () => ReactNode;\n\n /** Render prop for center section (e.g., search bar) - shown on desktop */\n renderCenterSection?: () => ReactNode;\n\n /** Render prop for mobile-specific content (e.g., mobile search) - shown below main topbar on mobile */\n renderMobileContent?: () => ReactNode;\n\n /** Custom Link component for navigation (for react-router-dom, Next.js, etc.) */\n LinkComponent?: ComponentType<LinkComponentProps>;\n\n /** Optional sticky positioning */\n sticky?: boolean;\n\n /** Optional variant */\n variant?: 'default' | 'app';\n\n /** Mobile menu label for accessibility */\n mobileMenuLabel?: string;\n\n /** Custom className for topbar */\n className?: string;\n\n /** z-index level */\n zIndex?: 'default' | 'highest' | 'high';\n\n /** Aria label for navigation */\n ariaLabel?: string;\n}\n\n/**\n * Default Link component that renders a plain anchor tag.\n * Apps should provide their own LinkComponent for router integration.\n */\nconst DefaultLinkComponent: ComponentType<LinkComponentProps> = ({\n href,\n className,\n children,\n onClick,\n}) => (\n <a href={href} className={className} onClick={onClick}>\n {children}\n </a>\n);\n\n/**\n * AppTopBar - Base topbar component for Sudobility apps.\n *\n * Features:\n * - Logo with app name on the left\n * - Navigation menu items with icons\n * - Language selector\n * - Render prop for center section (e.g., search bar)\n * - Render prop for account/auth section\n * - Render prop for mobile-specific content\n * - Responsive with hamburger menu on mobile\n * - Dark mode support\n */\nexport const AppTopBar: React.FC<AppTopBarProps> = ({\n logo,\n menuItems,\n languages = DEFAULT_LANGUAGES,\n currentLanguage = 'en',\n onLanguageChange,\n hideLanguageSelector = false,\n languageSelectorProps,\n collapseBelow = 'lg',\n renderAccountSection,\n renderCenterSection,\n renderMobileContent,\n LinkComponent = DefaultLinkComponent,\n sticky = true,\n variant = 'default',\n mobileMenuLabel = 'Menu',\n className,\n zIndex = 'highest',\n ariaLabel = 'Main navigation',\n}) => {\n // Filter menu items that should be shown\n const visibleMenuItems = useMemo(\n () => menuItems.filter(item => item.show !== false),\n [menuItems]\n );\n\n // Convert MenuItemConfig to TopbarNavItem\n const navItems: TopbarNavItem[] = useMemo(\n () =>\n visibleMenuItems.map(item => ({\n id: item.id,\n label: item.label,\n icon: item.icon,\n href: item.href,\n })),\n [visibleMenuItems]\n );\n\n // Wrapper to adapt LinkComponent to TopbarNavigation expected interface\n const LinkWrapper: ComponentType<{\n href: string;\n className?: string;\n children: ReactNode;\n }> = useMemo(\n () =>\n ({ href, className, children }) => (\n <LinkComponent href={href} className={className}>\n {children}\n </LinkComponent>\n ),\n [LinkComponent]\n );\n\n const handleLogoClick = () => {\n logo.onClick?.();\n };\n\n return (\n <TopbarProvider variant={variant} sticky={sticky}>\n <Topbar\n variant={variant}\n sticky={sticky}\n zIndex={zIndex}\n aria-label={ariaLabel}\n className={cn(className)}\n >\n <TopbarLeft>\n <TopbarNavigation\n items={navItems}\n collapseBelow={collapseBelow}\n LinkComponent={LinkWrapper}\n mobileMenuLabel={mobileMenuLabel}\n >\n <TopbarLogo onClick={handleLogoClick} size='md'>\n <Logo\n size='md'\n logoSrc={logo.src}\n logoText={logo.appName}\n logoAlt={logo.alt || logo.appName}\n showText={true}\n />\n </TopbarLogo>\n </TopbarNavigation>\n </TopbarLeft>\n\n {renderCenterSection && (\n <TopbarCenter>{renderCenterSection()}</TopbarCenter>\n )}\n\n <TopbarRight>\n <TopbarActions gap='md'>\n {!hideLanguageSelector && (\n <LanguageSelector\n languages={languages}\n currentLanguage={currentLanguage}\n onLanguageChange={onLanguageChange}\n variant='compact'\n {...languageSelectorProps}\n />\n )}\n {renderAccountSection?.()}\n </TopbarActions>\n </TopbarRight>\n\n {renderMobileContent && (\n <TopbarMobileContent>{renderMobileContent()}</TopbarMobileContent>\n )}\n </Topbar>\n </TopbarProvider>\n );\n};\n\nexport default AppTopBar;\n","import React, { type ReactNode, type ComponentType } from 'react';\nimport { AppTopBar, type AppTopBarProps } from './app-topbar';\nimport { cn } from '../../utils';\nimport { GRADIENT_CLASSES } from '@sudobility/design';\n\n/**\n * Auth menu item for the authenticated user dropdown.\n * This matches the AuthMenuItem interface from @sudobility/auth-components.\n */\nexport interface AuthMenuItem {\n /** Unique identifier */\n id: string;\n /** Display label */\n label: string;\n /** Icon element (typically a small SVG) */\n icon?: ReactNode;\n /** Click handler */\n onClick?: () => void;\n /** Show divider after this item */\n dividerAfter?: boolean;\n}\n\n/**\n * Props for the AuthAction component from @sudobility/auth-components.\n */\nexport interface AuthActionProps {\n /** Avatar size in pixels */\n avatarSize?: number;\n /** Dropdown alignment */\n dropdownAlign?: 'left' | 'right';\n /** Login button click handler */\n onLoginClick?: () => void;\n /** Menu items for authenticated user dropdown */\n menuItems?: AuthMenuItem[];\n /** Custom login button text */\n loginButtonText?: string;\n /** Custom className for login button */\n loginButtonClassName?: string;\n}\n\nexport interface AppTopBarWithFirebaseAuthProps extends Omit<\n AppTopBarProps,\n 'renderAccountSection'\n> {\n /**\n * AuthAction component from @sudobility/auth-components.\n * This is passed as a prop to avoid hard dependency on auth-components.\n */\n AuthActionComponent: ComponentType<AuthActionProps>;\n\n /** Additional menu items for authenticated users */\n authenticatedMenuItems?: AuthMenuItem[];\n\n /** Login button click handler */\n onLoginClick?: () => void;\n\n /** Avatar size in pixels */\n avatarSize?: number;\n\n /** Dropdown alignment */\n dropdownAlign?: 'left' | 'right';\n\n /** Custom login button text */\n loginButtonText?: string;\n\n /** Custom login button className */\n loginButtonClassName?: string;\n}\n\n/**\n * AppTopBarWithFirebaseAuth - TopBar with Firebase authentication integration.\n *\n * This component wraps AppTopBar and provides the AuthAction component\n * from @sudobility/auth-components for the account section.\n *\n * Note: The AuthAction component must be passed as a prop to avoid\n * hard dependency on @sudobility/auth-components.\n *\n * @example\n * ```tsx\n * import { AuthAction } from '@sudobility/auth-components';\n *\n * <AppTopBarWithFirebaseAuth\n * logo={{ src: '/logo.png', appName: 'My App' }}\n * menuItems={[...]}\n * AuthActionComponent={AuthAction}\n * onLoginClick={() => navigate('/login')}\n * authenticatedMenuItems={[\n * { id: 'dashboard', label: 'Dashboard', onClick: () => navigate('/dashboard') },\n * ]}\n * />\n * ```\n */\nexport const AppTopBarWithFirebaseAuth: React.FC<\n AppTopBarWithFirebaseAuthProps\n> = ({\n AuthActionComponent,\n authenticatedMenuItems = [],\n onLoginClick,\n avatarSize = 32,\n dropdownAlign = 'right',\n loginButtonText,\n loginButtonClassName,\n ...topBarProps\n}) => {\n const renderAccountSection = () => (\n <AuthActionComponent\n avatarSize={avatarSize}\n dropdownAlign={dropdownAlign}\n onLoginClick={onLoginClick}\n menuItems={authenticatedMenuItems}\n loginButtonText={loginButtonText}\n loginButtonClassName={cn(\n GRADIENT_CLASSES.headerButton,\n loginButtonClassName\n )}\n />\n );\n\n return (\n <AppTopBar {...topBarProps} renderAccountSection={renderAccountSection} />\n );\n};\n\nexport default AppTopBarWithFirebaseAuth;\n","import React, { type ReactNode, type ComponentType } from 'react';\nimport { AppTopBar, type AppTopBarProps } from './app-topbar';\nimport { cn } from '../../utils';\nimport { GRADIENT_CLASSES } from '@sudobility/design';\n\n/**\n * Wallet menu item for the connected wallet dropdown.\n */\nexport interface WalletMenuItem {\n /** Unique identifier */\n id: string;\n /** Display label */\n label: string;\n /** Icon component */\n icon?: ComponentType<{ className?: string }>;\n /** Click handler */\n onClick: () => void;\n /** Whether this is a separator */\n separator?: boolean;\n}\n\n/**\n * Auth status enum matching @sudobility/types.\n */\nexport enum AuthStatus {\n DISCONNECTED = 'disconnected',\n CONNECTED = 'connected',\n VERIFIED = 'verified',\n}\n\n/**\n * Chain type enum matching @sudobility/types.\n */\nexport enum ChainType {\n EVM = 'evm',\n SOLANA = 'solana',\n}\n\n/**\n * Props for the WalletDropdownMenu component from @sudobility/web3-components.\n */\nexport interface WalletDropdownMenuProps {\n walletAddress: string;\n authStatus: AuthStatus | string;\n chainType: ChainType | string | 'unknown';\n menuItems: WalletMenuItem[];\n avatar?: string;\n displayName?: string;\n statusLabels?: {\n verified?: string;\n connected?: string;\n disconnected?: string;\n };\n}\n\nexport interface AppTopBarWithWalletProps extends Omit<\n AppTopBarProps,\n 'renderAccountSection'\n> {\n /**\n * WalletDropdownMenu component from @sudobility/web3-components.\n * This is passed as a prop to avoid hard dependency on web3-components.\n */\n WalletDropdownMenuComponent?: ComponentType<WalletDropdownMenuProps>;\n\n /** Whether wallet is connected */\n isConnected: boolean;\n\n /** Connected wallet address */\n walletAddress?: string;\n\n /** Authentication status */\n authStatus?: AuthStatus | string;\n\n /** Chain type (EVM, Solana, etc.) */\n chainType?: ChainType | string | 'unknown';\n\n /** Connect button click handler */\n onConnect: () => void;\n\n /** Disconnect handler */\n onDisconnect: () => Promise<void>;\n\n /** Custom menu items for wallet dropdown */\n walletMenuItems?: WalletMenuItem[];\n\n /** Connect button content (default: \"Connect Wallet\") */\n connectButtonContent?: ReactNode;\n\n /** Connect button className (supports gradient classes from @sudobility/design) */\n connectButtonClassName?: string;\n\n /** Use gradient styling for connect button */\n useGradientButton?: boolean;\n\n /** Optional user avatar */\n avatar?: string;\n\n /** Optional display name */\n displayName?: string;\n\n /** Custom status labels */\n statusLabels?: {\n verified?: string;\n connected?: string;\n disconnected?: string;\n };\n}\n\n/**\n * Default connect button when WalletDropdownMenuComponent is not provided\n * or when wallet is not connected.\n */\nconst DefaultConnectButton: React.FC<{\n onClick: () => void;\n content?: ReactNode;\n className?: string;\n useGradient?: boolean;\n}> = ({ onClick, content = 'Connect Wallet', className, useGradient }) => (\n <button\n onClick={onClick}\n className={cn(\n useGradient\n ? GRADIENT_CLASSES.headerButton\n : 'px-4 py-2 text-sm font-medium rounded-lg bg-blue-600 text-white hover:bg-blue-700 transition-colors',\n className\n )}\n >\n {content}\n </button>\n);\n\n/**\n * Simple fallback wallet display when WalletDropdownMenuComponent is not provided.\n */\nconst FallbackWalletDisplay: React.FC<{\n walletAddress: string;\n onDisconnect: () => Promise<void>;\n}> = ({ walletAddress, onDisconnect }) => {\n const truncatedAddress = `${walletAddress.slice(0, 6)}...${walletAddress.slice(-4)}`;\n\n return (\n <div className='flex items-center gap-2'>\n <span className='text-sm font-medium text-gray-700 dark:text-gray-300'>\n {truncatedAddress}\n </span>\n <button\n onClick={() => onDisconnect()}\n className='text-xs text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200'\n >\n Disconnect\n </button>\n </div>\n );\n};\n\n/**\n * AppTopBarWithWallet - TopBar with wallet connection integration.\n *\n * This component wraps AppTopBar and provides wallet connection UI\n * for the account section. Uses WalletDropdownMenu from @sudobility/web3-components\n * when provided.\n *\n * @example\n * ```tsx\n * import { WalletDropdownMenu } from '@sudobility/web3-components';\n *\n * <AppTopBarWithWallet\n * logo={{ src: '/logo.png', appName: 'My App' }}\n * menuItems={[...]}\n * WalletDropdownMenuComponent={WalletDropdownMenu}\n * isConnected={isConnected}\n * walletAddress={walletAddress}\n * authStatus={authStatus}\n * chainType={chainType}\n * onConnect={() => navigate('/connect')}\n * onDisconnect={handleDisconnect}\n * walletMenuItems={[\n * { id: 'copy', label: 'Copy Address', icon: ClipboardIcon, onClick: handleCopy },\n * { id: 'disconnect', label: 'Disconnect', icon: LogoutIcon, onClick: handleDisconnect },\n * ]}\n * />\n * ```\n */\nexport const AppTopBarWithWallet: React.FC<AppTopBarWithWalletProps> = ({\n WalletDropdownMenuComponent,\n isConnected,\n walletAddress,\n authStatus = AuthStatus.DISCONNECTED,\n chainType = 'unknown',\n onConnect,\n onDisconnect,\n walletMenuItems = [],\n connectButtonContent,\n connectButtonClassName,\n useGradientButton = true,\n avatar,\n displayName,\n statusLabels,\n ...topBarProps\n}) => {\n const renderAccountSection = () => {\n // Not connected - show connect button\n if (!isConnected || !walletAddress) {\n return (\n <DefaultConnectButton\n onClick={onConnect}\n content={connectButtonContent}\n className={connectButtonClassName}\n useGradient={useGradientButton}\n />\n );\n }\n\n // Connected with WalletDropdownMenu component\n if (WalletDropdownMenuComponent) {\n return (\n <WalletDropdownMenuComponent\n walletAddress={walletAddress}\n authStatus={authStatus}\n chainType={chainType}\n menuItems={walletMenuItems}\n avatar={avatar}\n displayName={displayName}\n statusLabels={statusLabels}\n />\n );\n }\n\n // Connected without WalletDropdownMenu - fallback display\n return (\n <FallbackWalletDisplay\n walletAddress={walletAddress}\n onDisconnect={onDisconnect}\n />\n );\n };\n\n return (\n <AppTopBar {...topBarProps} renderAccountSection={renderAccountSection} />\n );\n};\n\nexport default AppTopBarWithWallet;\n","import React, { type ComponentType } from 'react';\nimport { BreadcrumbSection } from '@sudobility/components';\nimport { CalendarDaysIcon } from '@heroicons/react/24/outline';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../../utils';\nimport type {\n BreadcrumbItem,\n ShareConfig,\n TalkToFounderConfig,\n LinkComponentProps,\n} from '../../types';\n\nconst breadcrumbContainerVariants = cva('border-b', {\n variants: {\n variant: {\n default: 'bg-white dark:bg-gray-800 border-gray-200 dark:border-gray-700',\n transparent: 'bg-transparent border-transparent',\n subtle:\n 'bg-gray-50 dark:bg-gray-900/50 border-gray-200 dark:border-gray-700',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n});\n\nexport interface AppBreadcrumbsProps extends VariantProps<\n typeof breadcrumbContainerVariants\n> {\n /** Breadcrumb items */\n items: BreadcrumbItem[];\n\n /** Share configuration (shows social share buttons on right) */\n shareConfig?: ShareConfig;\n\n /** Talk to founder button configuration */\n talkToFounder?: TalkToFounderConfig;\n\n /** Custom Link component */\n LinkComponent?: ComponentType<LinkComponentProps>;\n\n /** Custom className for the container */\n className?: string;\n\n /** Custom className for the inner content */\n contentClassName?: string;\n}\n\n/**\n * Default Talk to Founder button.\n */\nconst TalkToFounderButton: React.FC<{\n config: TalkToFounderConfig;\n}> = ({ config }) => {\n const IconComponent = config.icon || CalendarDaysIcon;\n const buttonText = config.buttonText || 'Talk to Founder';\n\n return (\n <a\n href={config.meetingUrl}\n target='_blank'\n rel='noopener noreferrer'\n className={cn(\n 'inline-flex items-center gap-2 px-3 py-1.5',\n 'text-sm font-medium',\n 'text-blue-600 dark:text-blue-400',\n 'hover:text-blue-700 dark:hover:text-blue-300',\n 'bg-blue-50 dark:bg-blue-900/20',\n 'hover:bg-blue-100 dark:hover:bg-blue-900/30',\n 'rounded-full',\n 'border border-blue-200 dark:border-blue-800',\n 'transition-colors'\n )}\n >\n <IconComponent className='h-4 w-4' />\n <span>{buttonText}</span>\n </a>\n );\n};\n\n/**\n * AppBreadcrumbs - Breadcrumb navigation with social share and \"Talk to Founder\" button.\n *\n * Features:\n * - Breadcrumb trail with links\n * - Social share buttons on the right\n * - Optional \"Talk to Founder\" meeting button\n * - Always renders at max-w-7xl width\n * - Dark mode support\n *\n * @example\n * ```tsx\n * <AppBreadcrumbs\n * items={[\n * { label: 'Home', href: '/' },\n * { label: 'Products', href: '/products' },\n * { label: 'Widget', current: true },\n * ]}\n * shareConfig={{\n * title: 'Check out this widget',\n * description: 'Amazing widget for your needs',\n * hashtags: ['widget', 'product'],\n * }}\n * talkToFounder={{\n * meetingUrl: 'https://calendly.com/founder/30min',\n * buttonText: 'Book a call',\n * }}\n * />\n * ```\n */\nexport const AppBreadcrumbs: React.FC<AppBreadcrumbsProps> = ({\n items,\n shareConfig,\n talkToFounder,\n variant = 'default',\n className,\n contentClassName,\n}) => {\n // Don't render if no items or only home\n if (!items || items.length === 0) {\n return null;\n }\n\n return (\n <div className={cn(breadcrumbContainerVariants({ variant }), className)}>\n <div className={cn('max-w-7xl mx-auto px-4 py-3', contentClassName)}>\n <div className='flex items-center justify-between gap-4'>\n {/* Breadcrumb trail */}\n <div className='flex-1 min-w-0'>\n <BreadcrumbSection items={items} shareConfig={shareConfig} />\n </div>\n\n {/* Right side: Talk to Founder + Share (if shareConfig, share is handled by BreadcrumbSection) */}\n {talkToFounder && (\n <div className='flex items-center gap-3 flex-shrink-0'>\n <TalkToFounderButton config={talkToFounder} />\n </div>\n )}\n </div>\n </div>\n </div>\n );\n};\n\nexport default AppBreadcrumbs;\n","import React, { type ComponentType } from 'react';\nimport {\n Footer as FooterContainer,\n FooterCompact,\n FooterCompactLeft,\n FooterCompactRight,\n FooterVersion,\n FooterCopyright,\n} from '@sudobility/components';\nimport { cn } from '../../utils';\nimport type {\n StatusIndicatorConfig,\n LinkComponentProps,\n FooterLinkItem,\n} from '../../types';\n\n/**\n * Props for the SystemStatusIndicator component from @sudobility/devops-components.\n */\nexport interface SystemStatusIndicatorProps {\n statusPageUrl: string;\n apiEndpoint?: string;\n refreshInterval?: number;\n size?: 'sm' | 'md' | 'lg';\n version?: string;\n isNetworkOnline?: boolean;\n}\n\nexport interface AppFooterProps {\n /** App version string */\n version?: string;\n\n /** Copyright year or range (e.g., \"2025\" or \"2025-2026\") */\n copyrightYear?: string;\n\n /** Company name */\n companyName: string;\n\n /** Company URL (optional - creates a link if provided) */\n companyUrl?: string;\n\n /** Rights text (e.g., \"All rights reserved\") */\n rightsText?: string;\n\n /** Status indicator config (optional) */\n statusIndicator?: StatusIndicatorConfig;\n\n /**\n * SystemStatusIndicator component from @sudobility/devops-components.\n * Pass this to enable status indicator functionality.\n */\n StatusIndicatorComponent?: ComponentType<SystemStatusIndicatorProps>;\n\n /** Right-side links (e.g., Privacy, Terms) */\n links?: FooterLinkItem[];\n\n /** Custom Link component */\n LinkComponent?: ComponentType<LinkComponentProps>;\n\n /** Sticky positioning (sticks to bottom of viewport) */\n sticky?: boolean;\n\n /** Network online status (for status indicator) */\n isNetworkOnline?: boolean;\n\n /** Custom className */\n className?: string;\n}\n\n/**\n * Default link component that renders a plain anchor.\n */\nconst DefaultLinkComponent: ComponentType<LinkComponentProps> = ({\n href,\n className,\n children,\n onClick,\n}) => (\n <a href={href} className={className} onClick={onClick}>\n {children}\n </a>\n);\n\n/**\n * Helper to get copyright year or range.\n */\nfunction getCopyrightYear(startYear = 2025): string {\n const currentYear = new Date().getFullYear();\n if (currentYear === startYear) {\n return String(startYear);\n } else if (currentYear > startYear) {\n return `${startYear}-${currentYear}`;\n }\n return String(startYear);\n}\n\n/**\n * AppFooter - Compact footer for app pages.\n *\n * Features:\n * - Version display\n * - Copyright with company name\n * - System status indicator (optional)\n * - Right-side links (Privacy, Terms, etc.)\n * - Sticky positioning option\n * - Dark mode support\n *\n * @example\n * ```tsx\n * import { SystemStatusIndicator } from '@sudobility/devops-components';\n *\n * <AppFooter\n * version=\"1.0.0\"\n * companyName=\"Sudobility Inc.\"\n * companyUrl=\"/\"\n * rightsText=\"All rights reserved\"\n * statusIndicator={{\n * statusPageUrl: 'https://status.example.com',\n * apiEndpoint: 'https://status.example.com/api/v1/status',\n * }}\n * StatusIndicatorComponent={SystemStatusIndicator}\n * links={[\n * { label: 'Privacy', href: '/privacy' },\n * { label: 'Terms', href: '/terms' },\n * ]}\n * sticky\n * />\n * ```\n */\nexport const AppFooter: React.FC<AppFooterProps> = ({\n version,\n copyrightYear,\n companyName,\n companyUrl,\n rightsText = 'All rights reserved',\n statusIndicator,\n StatusIndicatorComponent,\n links = [],\n LinkComponent = DefaultLinkComponent,\n sticky = true,\n isNetworkOnline = true,\n className,\n}) => {\n const year = copyrightYear || getCopyrightYear();\n\n const companyLink = companyUrl ? (\n <LinkComponent\n href={companyUrl}\n className='text-blue-400 hover:text-blue-300 transition-colors'\n >\n {companyName}\n </LinkComponent>\n ) : undefined;\n\n return (\n <FooterContainer\n variant='compact'\n sticky={sticky}\n className={cn(className)}\n >\n <FooterCompact>\n <FooterCompactLeft>\n {version && <FooterVersion version={version} />}\n <FooterCopyright\n year={year}\n companyName={companyName}\n rightsText={rightsText}\n companyLink={companyLink}\n />\n {statusIndicator && StatusIndicatorComponent && (\n <StatusIndicatorComponent\n statusPageUrl={statusIndicator.statusPageUrl}\n apiEndpoint={statusIndicator.apiEndpoint}\n refreshInterval={statusIndicator.refreshInterval || 60000}\n size='sm'\n version={version}\n isNetworkOnline={isNetworkOnline}\n />\n )}\n </FooterCompactLeft>\n <FooterCompactRight>\n {links.map((link, index) => (\n <React.Fragment key={link.href || index}>\n {link.onClick ? (\n <button\n onClick={link.onClick}\n className='text-gray-400 hover:text-white transition-colors'\n >\n {link.label}\n </button>\n ) : (\n <LinkComponent\n href={link.href}\n className='text-gray-400 hover:text-white transition-colors'\n >\n {link.label}\n </LinkComponent>\n )}\n </React.Fragment>\n ))}\n </FooterCompactRight>\n </FooterCompact>\n </FooterContainer>\n );\n};\n\nexport default AppFooter;\n","import React, { type ComponentType } from 'react';\nimport {\n Logo,\n Footer as FooterContainer,\n FooterGrid,\n FooterBrand,\n FooterLinkSection,\n FooterLink,\n FooterBottom,\n FooterVersion,\n FooterCopyright,\n FooterSocialLinks,\n} from '@sudobility/components';\nimport { cn } from '../../utils';\nimport type {\n StatusIndicatorConfig,\n LinkComponentProps,\n FooterLinkSection as FooterLinkSectionConfig,\n SocialLinksConfig,\n} from '../../types';\nimport type { SystemStatusIndicatorProps } from './app-footer';\n\nexport interface AppFooterForHomePageProps {\n /** App logo configuration */\n logo: {\n /** Logo image src (optional - if not provided, uses Logo component) */\n src?: string;\n /** App name */\n appName: string;\n };\n\n /** Footer link sections (columns of links) */\n linkSections: FooterLinkSectionConfig[];\n\n /** Social media links */\n socialLinks?: SocialLinksConfig;\n\n /** System status indicator configuration */\n statusIndicator?: StatusIndicatorConfig;\n\n /**\n * SystemStatusIndicator component from @sudobility/devops-components.\n * Pass this to enable status indicator functionality.\n */\n StatusIndicatorComponent?: ComponentType<SystemStatusIndicatorProps>;\n\n /** App version string */\n version?: string;\n\n /** Copyright year or range */\n copyrightYear?: string;\n\n /** Company name for copyright */\n companyName: string;\n\n /** Company link URL (optional) */\n companyUrl?: string;\n\n /** Footer description text (below logo) */\n description?: string;\n\n /** Rights text (e.g., \"All rights reserved\") */\n rightsText?: string;\n\n /** Custom Link component */\n LinkComponent?: ComponentType<LinkComponentProps>;\n\n /** Network online status (for status indicator) */\n isNetworkOnline?: boolean;\n\n /** Custom className */\n className?: string;\n\n /** Number of columns for link grid (default: auto based on section count) */\n gridColumns?: 2 | 3 | 4 | 5;\n}\n\n/**\n * Default link component that renders a plain anchor.\n */\nconst DefaultLinkComponent: ComponentType<LinkComponentProps> = ({\n href,\n className,\n children,\n onClick,\n}) => (\n <a href={href} className={className} onClick={onClick}>\n {children}\n </a>\n);\n\n/**\n * Helper to get copyright year or range.\n */\nfunction getCopyrightYear(startYear = 2025): string {\n const currentYear = new Date().getFullYear();\n if (currentYear === startYear) {\n return String(startYear);\n } else if (currentYear > startYear) {\n return `${startYear}-${currentYear}`;\n }\n return String(startYear);\n}\n\n/**\n * Get grid columns class based on section count.\n */\nfunction getGridColumnsClass(sectionCount: number, explicit?: number): string {\n const cols = explicit || Math.min(sectionCount, 4);\n switch (cols) {\n case 2:\n return 'md:grid-cols-2';\n case 3:\n return 'md:grid-cols-3';\n case 4:\n return 'md:grid-cols-4';\n case 5:\n return 'md:grid-cols-5';\n default:\n return 'md:grid-cols-4';\n }\n}\n\n/**\n * AppFooterForHomePage - Full footer for home/landing pages.\n *\n * Features:\n * - Multiple link sections in a grid\n * - Logo and brand description\n * - Social media links\n * - System status indicator (optional)\n * - Version and copyright\n * - Dark mode support\n *\n * @example\n * ```tsx\n * import { SystemStatusIndicator } from '@sudobility/devops-components';\n *\n * <AppFooterForHomePage\n * logo={{ appName: 'My App' }}\n * linkSections={[\n * {\n * title: 'Product',\n * links: [\n * { label: 'Features', href: '/features' },\n * { label: 'Pricing', href: '/pricing' },\n * ],\n * },\n * {\n * title: 'Company',\n * links: [\n * { label: 'About', href: '/about' },\n * { label: 'Contact', href: '/contact' },\n * ],\n * },\n * ]}\n * socialLinks={{\n * twitterUrl: 'https://twitter.com/myapp',\n * discordUrl: 'https://discord.gg/myapp',\n * }}\n * statusIndicator={{\n * statusPageUrl: 'https://status.example.com',\n * }}\n * StatusIndicatorComponent={SystemStatusIndicator}\n * version=\"1.0.0\"\n * companyName=\"Sudobility Inc.\"\n * description=\"Building the future of web3 communication\"\n * />\n * ```\n */\nexport const AppFooterForHomePage: React.FC<AppFooterForHomePageProps> = ({\n logo,\n linkSections,\n socialLinks,\n statusIndicator,\n StatusIndicatorComponent,\n version,\n copyrightYear,\n companyName,\n companyUrl,\n description,\n rightsText = 'All rights reserved',\n LinkComponent = DefaultLinkComponent,\n isNetworkOnline = true,\n className,\n gridColumns,\n}) => {\n const year = copyrightYear || getCopyrightYear();\n const gridClass = getGridColumnsClass(linkSections.length, gridColumns);\n\n const companyLink = companyUrl ? (\n <LinkComponent\n href={companyUrl}\n className='text-blue-400 hover:text-blue-300 transition-colors'\n >\n {companyName}\n </LinkComponent>\n ) : undefined;\n\n return (\n <FooterContainer variant='full' className={cn(className)}>\n <FooterGrid className={gridClass}>\n {linkSections.map((section, sectionIndex) => (\n <FooterLinkSection\n key={section.title || sectionIndex}\n title={section.title}\n >\n {section.links.map((link, linkIndex) => (\n <FooterLink key={link.href || linkIndex}>\n {link.onClick ? (\n <button onClick={link.onClick} className='text-left'>\n {link.label}\n </button>\n ) : (\n <LinkComponent href={link.href}>{link.label}</LinkComponent>\n )}\n </FooterLink>\n ))}\n </FooterLinkSection>\n ))}\n </FooterGrid>\n\n <FooterBottom>\n <FooterBrand\n description={description}\n className='flex flex-col items-center'\n >\n <LinkComponent\n href='/'\n className='text-white hover:opacity-80 transition-opacity'\n >\n {logo.src ? (\n <img\n src={logo.src}\n alt={logo.appName}\n className='h-8 object-contain'\n />\n ) : (\n <Logo size='md' showText={true} logoText={logo.appName} />\n )}\n </LinkComponent>\n </FooterBrand>\n {version && <FooterVersion version={version} />}\n <FooterCopyright\n year={year}\n companyName={companyName}\n rightsText={rightsText}\n companyLink={companyLink}\n />\n {statusIndicator && StatusIndicatorComponent && (\n <StatusIndicatorComponent\n statusPageUrl={statusIndicator.statusPageUrl}\n apiEndpoint={statusIndicator.apiEndpoint}\n refreshInterval={statusIndicator.refreshInterval || 60000}\n size='sm'\n version={version}\n isNetworkOnline={isNetworkOnline}\n />\n )}\n </FooterBottom>\n\n {socialLinks && (\n <div className='flex justify-center mt-4'>\n <FooterSocialLinks\n twitterUrl={socialLinks.twitterUrl}\n discordUrl={socialLinks.discordUrl}\n linkedinUrl={socialLinks.linkedinUrl}\n githubUrl={socialLinks.githubUrl}\n redditUrl={socialLinks.redditUrl}\n farcasterUrl={socialLinks.farcasterUrl}\n telegramUrl={socialLinks.telegramUrl}\n />\n </div>\n )}\n </FooterContainer>\n );\n};\n\nexport default AppFooterForHomePage;\n","import React, { type ReactNode } from 'react';\nimport { LayoutProvider } from '@sudobility/components';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../../utils';\nimport {\n AppBreadcrumbs,\n type AppBreadcrumbsProps,\n} from '../breadcrumbs/app-breadcrumbs';\nimport type { MaxWidth, ContentPadding, BackgroundVariant } from '../../types';\n\nconst layoutVariants = cva('min-h-screen flex flex-col', {\n variants: {\n background: {\n default: 'bg-gray-50 dark:bg-gray-900',\n white: 'bg-white dark:bg-gray-900',\n gradient:\n 'bg-gradient-to-br from-gray-50 to-blue-50 dark:from-gray-900 dark:to-gray-800',\n },\n },\n defaultVariants: {\n background: 'default',\n },\n});\n\nconst maxWidthClasses: Record<MaxWidth, string> = {\n sm: 'max-w-sm',\n md: 'max-w-md',\n lg: 'max-w-lg',\n xl: 'max-w-xl',\n '2xl': 'max-w-2xl',\n '4xl': 'max-w-4xl',\n '7xl': 'max-w-7xl',\n full: 'max-w-full',\n};\n\nconst paddingClasses: Record<ContentPadding, string> = {\n none: '',\n sm: 'px-4 sm:px-6 py-6',\n md: 'px-4 py-8',\n lg: 'px-4 py-12',\n};\n\nexport interface AppPageLayoutProps extends VariantProps<\n typeof layoutVariants\n> {\n /** Page content */\n children: ReactNode;\n\n /** TopBar slot - pass an AppTopBar variant or custom component */\n topBar: ReactNode;\n\n /** Breadcrumbs configuration (optional) */\n breadcrumbs?: AppBreadcrumbsProps;\n\n /** Footer slot - pass an AppFooter variant or custom component */\n footer?: ReactNode;\n\n /** Max width for content area (default: '7xl') */\n maxWidth?: MaxWidth;\n\n /** Content padding (default: 'md') */\n contentPadding?: ContentPadding;\n\n /** Background variant */\n background?: BackgroundVariant;\n\n /** Layout mode for LayoutProvider */\n layoutMode?: 'standard';\n\n /** Custom className for the layout container */\n className?: string;\n\n /** Custom className for the content area */\n contentClassName?: string;\n\n /** Custom className for the main element */\n mainClassName?: string;\n}\n\n/**\n * AppPageLayout - Layout wrapper combining TopBar, Breadcrumbs, Content, and Footer.\n *\n * Features:\n * - Flexible slots for TopBar and Footer\n * - Optional breadcrumbs with share and \"Talk to Founder\"\n * - Configurable content max-width and padding\n * - Background variants\n * - Dark mode support\n * - Sticky footer behavior\n *\n * @example\n * ```tsx\n * <AppPageLayout\n * topBar={\n * <AppTopBarWithFirebaseAuth\n * logo={{ src: '/logo.png', appName: 'My App' }}\n * menuItems={menuItems}\n * AuthActionComponent={AuthAction}\n * onLoginClick={() => navigate('/login')}\n * />\n * }\n * breadcrumbs={{\n * items: breadcrumbItems,\n * shareConfig: { title: 'Page', description: 'Description', hashtags: [] },\n * }}\n * footer={\n * <AppFooter\n * version=\"1.0.0\"\n * companyName=\"My Company\"\n * links={[{ label: 'Privacy', href: '/privacy' }]}\n * />\n * }\n * maxWidth=\"7xl\"\n * background=\"default\"\n * >\n * <h1>Page Content</h1>\n * </AppPageLayout>\n * ```\n */\nexport const AppPageLayout: React.FC<AppPageLayoutProps> = ({\n children,\n topBar,\n breadcrumbs,\n footer,\n maxWidth = '7xl',\n contentPadding = 'md',\n background = 'default',\n layoutMode = 'standard',\n className,\n contentClassName,\n mainClassName,\n}) => {\n return (\n <LayoutProvider mode={layoutMode}>\n <div className={cn(layoutVariants({ background }), className)}>\n {/* Header Section */}\n <header>{topBar}</header>\n\n {/* Breadcrumb Section */}\n {breadcrumbs && breadcrumbs.items && breadcrumbs.items.length > 0 && (\n <AppBreadcrumbs {...breadcrumbs} />\n )}\n\n {/* Main Content */}\n <main className={cn('flex-1 overflow-auto', mainClassName)}>\n <div\n className={cn(\n 'mx-auto',\n maxWidthClasses[maxWidth],\n paddingClasses[contentPadding],\n contentClassName\n )}\n >\n {children}\n </div>\n </main>\n\n {/* Footer */}\n {footer && <footer>{footer}</footer>}\n </div>\n </LayoutProvider>\n );\n};\n\nexport default AppPageLayout;\n","import React from 'react';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Label,\n} from '@sudobility/components';\nimport { textVariants } from '@sudobility/design';\n\n/**\n * Theme options for appearance settings.\n */\nexport enum Theme {\n LIGHT = 'light',\n DARK = 'dark',\n SYSTEM = 'system',\n}\n\n/**\n * Font size options for appearance settings.\n */\nexport enum FontSize {\n SMALL = 'small',\n MEDIUM = 'medium',\n LARGE = 'large',\n}\n\n/**\n * Translation keys used by AppearanceSettings.\n * Provide a translation function to customize labels.\n */\nexport interface AppearanceSettingsTranslations {\n heading: string;\n description: string;\n themeLabel: string;\n themeSelectPlaceholder: string;\n themeLight: string;\n themeDark: string;\n themeSystem: string;\n themeDescription: string;\n fontSizeLabel: string;\n fontSizeSelectPlaceholder: string;\n fontSizeSmall: string;\n fontSizeMedium: string;\n fontSizeLarge: string;\n fontSizeDescription: string;\n infoHeading: string;\n infoDescription: string;\n}\n\nconst defaultTranslations: AppearanceSettingsTranslations = {\n heading: 'Appearance',\n description: 'Customize the look and feel of the application.',\n themeLabel: 'Theme',\n themeSelectPlaceholder: 'Select theme',\n themeLight: 'Light',\n themeDark: 'Dark',\n themeSystem: 'System',\n themeDescription: 'Choose your preferred color theme.',\n fontSizeLabel: 'Font Size',\n fontSizeSelectPlaceholder: 'Select font size',\n fontSizeSmall: 'Small',\n fontSizeMedium: 'Medium',\n fontSizeLarge: 'Large',\n fontSizeDescription: 'Adjust the text size for better readability.',\n infoHeading: 'About Settings',\n infoDescription:\n 'Your appearance preferences are saved locally and will be applied automatically on your next visit.',\n};\n\nexport interface AppearanceSettingsProps {\n /** Current theme value */\n theme: Theme | string;\n\n /** Current font size value */\n fontSize: FontSize | string;\n\n /** Callback when theme changes */\n onThemeChange: (theme: Theme) => void;\n\n /** Callback when font size changes */\n onFontSizeChange: (fontSize: FontSize) => void;\n\n /**\n * Optional translation function.\n * If provided, will be called with a key from AppearanceSettingsTranslations.\n * Falls back to default English strings if not provided.\n */\n t?: (key: string, fallback?: string) => string;\n\n /** Optional className for the container */\n className?: string;\n\n /** Whether to show the information box at the bottom */\n showInfoBox?: boolean;\n}\n\n/**\n * AppearanceSettings - A reusable component for theme and font size settings.\n *\n * This component can be used across different apps to provide consistent\n * appearance customization options.\n *\n * @example\n * ```tsx\n * // Basic usage with useTheme hook\n * const { theme, fontSize, setTheme, setFontSize } = useTheme();\n *\n * <AppearanceSettings\n * theme={theme}\n * fontSize={fontSize}\n * onThemeChange={setTheme}\n * onFontSizeChange={setFontSize}\n * />\n *\n * // With i18n translation\n * const { t } = useTranslation('settings');\n *\n * <AppearanceSettings\n * theme={theme}\n * fontSize={fontSize}\n * onThemeChange={setTheme}\n * onFontSizeChange={setFontSize}\n * t={(key, fallback) => t(`appearance.${key}`, fallback)}\n * />\n * ```\n */\nexport const AppearanceSettings: React.FC<AppearanceSettingsProps> = ({\n theme,\n fontSize,\n onThemeChange,\n onFontSizeChange,\n t,\n className,\n showInfoBox = true,\n}) => {\n // Helper to get translated string with fallback\n const getText = (key: keyof AppearanceSettingsTranslations): string => {\n const fallback = defaultTranslations[key];\n return t ? t(key, fallback) : fallback;\n };\n\n return (\n <div className={className}>\n <div className='space-y-6'>\n <div>\n <h2 className={`${textVariants.heading.h4()} mb-2`}>\n {getText('heading')}\n </h2>\n <p\n className={`${textVariants.body.sm()} text-gray-600 dark:text-gray-400`}\n >\n {getText('description')}\n </p>\n </div>\n\n <div className='space-y-6'>\n {/* Theme Setting */}\n <div className='space-y-2'>\n <Label\n htmlFor='theme-select'\n className={textVariants.label.default()}\n >\n {getText('themeLabel')}\n </Label>\n <Select\n value={theme}\n onValueChange={(value: string) => onThemeChange(value as Theme)}\n >\n <SelectTrigger id='theme-select'>\n <SelectValue placeholder={getText('themeSelectPlaceholder')} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={Theme.LIGHT}>\n {getText('themeLight')}\n </SelectItem>\n <SelectItem value={Theme.DARK}>\n {getText('themeDark')}\n </SelectItem>\n <SelectItem value={Theme.SYSTEM}>\n {getText('themeSystem')}\n </SelectItem>\n </SelectContent>\n </Select>\n <p\n className={`${textVariants.body.xs()} text-gray-500 dark:text-gray-400`}\n >\n {getText('themeDescription')}\n </p>\n </div>\n\n {/* Font Size Setting */}\n <div className='space-y-2'>\n <Label\n htmlFor='font-size-select'\n className={textVariants.label.default()}\n >\n {getText('fontSizeLabel')}\n </Label>\n <Select\n value={fontSize}\n onValueChange={(value: string) =>\n onFontSizeChange(value as FontSize)\n }\n >\n <SelectTrigger id='font-size-select'>\n <SelectValue\n placeholder={getText('fontSizeSelectPlaceholder')}\n />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={FontSize.SMALL}>\n {getText('fontSizeSmall')}\n </SelectItem>\n <SelectItem value={FontSize.MEDIUM}>\n {getText('fontSizeMedium')}\n </SelectItem>\n <SelectItem value={FontSize.LARGE}>\n {getText('fontSizeLarge')}\n </SelectItem>\n </SelectContent>\n </Select>\n <p\n className={`${textVariants.body.xs()} text-gray-500 dark:text-gray-400`}\n >\n {getText('fontSizeDescription')}\n </p>\n </div>\n </div>\n\n {/* Information Box */}\n {showInfoBox && (\n <div className='bg-blue-50 dark:bg-blue-900/20 rounded-lg p-4 border border-blue-200 dark:border-blue-800'>\n <h4 className='text-sm font-medium text-blue-900 dark:text-blue-100 mb-2'>\n {getText('infoHeading')}\n </h4>\n <p className='text-sm text-blue-700 dark:text-blue-300'>\n {getText('infoDescription')}\n </p>\n </div>\n )}\n </div>\n </div>\n );\n};\n\nexport default AppearanceSettings;\n"],"names":["DefaultLinkComponent","className","AuthStatus","ChainType","getCopyrightYear","FooterContainer","Theme","FontSize"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sudobility/building_blocks",
3
- "version": "0.0.13",
3
+ "version": "0.0.15",
4
4
  "description": "Higher-level shared UI building blocks for Sudobility apps",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -33,7 +33,7 @@
33
33
  },
34
34
  "peerDependencies": {
35
35
  "@heroicons/react": "^2.0.0",
36
- "@sudobility/components": "^4.0.132",
36
+ "@sudobility/components": "^4.0.134",
37
37
  "@sudobility/design": "^1.1.17",
38
38
  "class-variance-authority": "^0.7.0",
39
39
  "clsx": "^2.0.0",
@@ -61,7 +61,7 @@
61
61
  "devDependencies": {
62
62
  "@eslint/js": "^9.38.0",
63
63
  "@heroicons/react": "^2.2.0",
64
- "@sudobility/components": "^4.0.132",
64
+ "@sudobility/components": "^4.0.134",
65
65
  "@sudobility/design": "^1.1.17",
66
66
  "@testing-library/dom": "^10.4.1",
67
67
  "@testing-library/jest-dom": "^6.9.1",