@vite-mf-monorepo/ui 0.0.2
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/CHANGELOG.md +262 -0
- package/dist/Button/index.d.ts +25 -0
- package/dist/Button/index.js +4 -0
- package/dist/Button/index.js.map +1 -0
- package/dist/Card/index.d.ts +10 -0
- package/dist/Card/index.js +3 -0
- package/dist/Card/index.js.map +1 -0
- package/dist/Icon/index.d.ts +13 -0
- package/dist/Icon/index.js +3 -0
- package/dist/Icon/index.js.map +1 -0
- package/dist/chunk-IXEILQNO.js +85 -0
- package/dist/chunk-IXEILQNO.js.map +1 -0
- package/dist/chunk-YKNVY2QQ.js +23 -0
- package/dist/chunk-YKNVY2QQ.js.map +1 -0
- package/dist/chunk-Z3E2P4JR.js +120 -0
- package/dist/chunk-Z3E2P4JR.js.map +1 -0
- package/dist/index.css +1313 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.ts +472 -0
- package/dist/index.js +1514 -0
- package/dist/index.js.map +1 -0
- package/package.json +78 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/Avatar/Avatar.tsx","../src/Badge/Badge.tsx","../src/IconButton/IconButton.tsx","../src/Image/Image.tsx","../src/Skeleton/Skeleton.tsx","../src/HeroImage/HeroImage.tsx","../src/Modal/Modal.tsx","../src/Rating/CircleRating.tsx","../src/Rating/StarsRating.tsx","../src/Rating/Rating.tsx","../src/Typography/Typography.tsx","../src/MovieCard/MovieCard.tsx","../src/TrailerCard/TrailerCard.tsx","../src/Carousel/CarouselCounter.tsx","../src/Carousel/CarouselError.tsx","../src/Carousel/CarouselNavigation.tsx","../src/Carousel/CarouselPagination.tsx","../src/Carousel/Carousel.tsx","../src/Carousel/CarouselItem.tsx","../src/Carousel/CarouselLoading.tsx","../src/Tabs/TabsContext.tsx","../src/Tabs/TabsListContext.tsx","../src/Tabs/TabsList.tsx","../src/Tabs/TabsPanel.tsx","../src/Tabs/TabsTrigger.tsx","../src/Tabs/Tabs.tsx","../src/Talent/Talent.tsx","../src/Spinner/Spinner.tsx"],"names":["clsx","sizeMap","jsxs","jsx","useState","Fragment","useRef","useEffect","useCallback","createContext","useContext"],"mappings":"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","file":"index.js","sourcesContent":["import clsx from 'clsx'\nimport { useState } from 'react'\n\nimport { Icon } from '../Icon'\n\nimport type { ComponentProps, FC } from 'react'\n\nexport type AvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl'\n\nexport interface AvatarProps extends Omit<ComponentProps<'img'>, 'src'> {\n /** Image source URL */\n src?: string | null\n /** Alt text for the image */\n alt: string\n /** Size of the avatar */\n size?: AvatarSize\n /** Fallback initials to display when no image */\n initials?: string\n /** For testing purposes */\n testId?: string\n}\n\nconst sizeMap: Record<\n AvatarSize,\n { container: string; icon: number; text: string }\n> = {\n xs: { container: 'ui:h-6 ui:w-6', icon: 12, text: 'ui:text-xs' },\n sm: { container: 'ui:h-8 ui:w-8', icon: 16, text: 'ui:text-sm' },\n md: { container: 'ui:h-10 ui:w-10', icon: 20, text: 'ui:text-base' },\n lg: { container: 'ui:h-12 ui:w-12', icon: 24, text: 'ui:text-lg' },\n xl: { container: 'ui:h-16 ui:w-16', icon: 32, text: 'ui:text-xl' },\n '2xl': { container: 'ui:h-24 ui:w-24', icon: 48, text: 'ui:text-2xl' },\n '3xl': { container: 'ui:h-32 ui:w-32', icon: 64, text: 'ui:text-3xl' },\n}\n\nconst Avatar: FC<AvatarProps> = ({\n className,\n src,\n alt,\n size = 'md',\n initials,\n testId,\n ...rest\n}) => {\n const [hasError, setHasError] = useState(false)\n const { container, icon, text } = sizeMap[size]\n\n const showImage = src && !hasError\n const showInitials = !showImage && initials\n const showFallback = !showImage && !initials\n\n const handleError = () => {\n setHasError(true)\n }\n\n return (\n <div\n className={clsx(\n 'ui:relative ui:inline-flex ui:items-center ui:justify-center ui:overflow-hidden ui:rounded-full',\n 'ui:bg-muted ui:text-muted-foreground',\n container,\n className\n )}\n >\n {showImage && (\n <img\n src={src}\n alt={alt}\n onError={handleError}\n className=\"ui:h-full ui:w-full ui:object-cover\"\n data-testid={testId}\n {...rest}\n />\n )}\n {showInitials && (\n <span className={clsx('ui:font-medium ui:uppercase', text)}>\n {initials.slice(0, 2)}\n </span>\n )}\n {showFallback && (\n <Icon name=\"User\" size={icon as 16 | 20 | 24 | 32 | 48 | 64} />\n )}\n </div>\n )\n}\n\nexport default Avatar\n","import clsx from 'clsx'\n\nimport { Icon } from '../Icon'\n\nimport type { IconName } from '../Icon'\nimport type { FC, ReactNode } from 'react'\n\nexport type BadgeVariant = 'default' | 'secondary' | 'outline' | 'destructive'\nexport type BadgeSize = 'sm' | 'md' | 'lg'\n\nexport interface BadgeProps {\n /** Badge content */\n children: ReactNode\n /** Visual variant */\n variant?: BadgeVariant\n /** Size */\n size?: BadgeSize\n /** Optional icon (left) */\n icon?: IconName\n /** Custom text color class (overrides variant color) */\n textClassName?: string\n /** Additional class name */\n className?: string\n}\n\nconst sizeMap: Record<\n BadgeSize,\n { padding: string; text: string; iconSize: 16 }\n> = {\n sm: { padding: 'ui:px-2 ui:py-0.5', text: 'ui:text-xs', iconSize: 16 },\n md: { padding: 'ui:px-2.5 ui:py-0.5', text: 'ui:text-sm', iconSize: 16 },\n lg: { padding: 'ui:px-3 ui:py-1', text: 'ui:text-sm', iconSize: 16 },\n}\n\nconst Badge: FC<BadgeProps> = ({\n children,\n variant = 'default',\n size = 'md',\n icon,\n textClassName,\n className,\n}) => {\n const { padding, text, iconSize } = sizeMap[size]\n\n return (\n <span\n className={clsx(\n 'ui:inline-flex ui:items-center ui:gap-1 ui:rounded-full ui:font-medium',\n padding,\n text,\n {\n 'ui:bg-primary': variant === 'default',\n 'ui:text-primary-foreground': variant === 'default' && !textClassName,\n 'ui:bg-secondary': variant === 'secondary',\n 'ui:text-secondary-foreground':\n variant === 'secondary' && !textClassName,\n 'ui:border ui:border-input ui:bg-transparent': variant === 'outline',\n 'ui:bg-destructive': variant === 'destructive',\n 'ui:text-destructive-foreground':\n variant === 'destructive' && !textClassName,\n },\n textClassName,\n className\n )}\n >\n {icon && <Icon name={icon} size={iconSize} />}\n {children}\n </span>\n )\n}\n\nexport default Badge\n","import clsx from 'clsx'\n\nimport { Icon } from '../Icon'\n\nimport type { IconName, IconSize } from '../Icon'\nimport type { ButtonHTMLAttributes, FC } from 'react'\n\nexport interface IconButtonProps\n extends ButtonHTMLAttributes<HTMLButtonElement> {\n /** Icon name to display */\n icon: IconName\n /** Visual variant of the button */\n variant?: 'primary' | 'secondary' | 'ghost' | 'outline'\n /** Size of the button */\n size?: 'sm' | 'md' | 'lg'\n /** Accessible label for screen readers */\n 'aria-label': string\n}\n\nconst sizeMap: Record<'sm' | 'md' | 'lg', { button: string; icon: IconSize }> =\n {\n sm: { button: 'ui:h-8 ui:w-8', icon: 16 },\n md: { button: 'ui:h-10 ui:w-10', icon: 20 },\n lg: { button: 'ui:h-12 ui:w-12', icon: 24 },\n }\n\nconst IconButton: FC<IconButtonProps> = ({\n className,\n icon,\n variant = 'ghost',\n size = 'md',\n disabled,\n ...rest\n}) => {\n const { button: buttonSize, icon: iconSize } = sizeMap[size]\n\n return (\n <button\n className={clsx(\n 'ui:inline-flex ui:items-center ui:justify-center ui:cursor-pointer ui:rounded-full ui:transition-colors',\n 'ui:focus:outline-none ui:focus:ring-2 ui:focus:ring-ring ui:focus:ring-offset-2',\n 'ui:disabled:pointer-events-none ui:disabled:opacity-50',\n {\n 'ui:bg-primary ui:text-primary-foreground ui:hover:bg-primary/90':\n variant === 'primary',\n 'ui:bg-secondary ui:text-secondary-foreground ui:hover:bg-secondary/80':\n variant === 'secondary',\n 'ui:hover:bg-accent ui:hover:text-accent-foreground':\n variant === 'ghost',\n 'ui:border ui:border-input ui:bg-background ui:hover:bg-accent ui:hover:text-accent-foreground':\n variant === 'outline',\n },\n buttonSize,\n className\n )}\n disabled={disabled}\n {...rest}\n >\n <Icon name={icon} size={iconSize} />\n </button>\n )\n}\n\nexport default IconButton\n","import { getBlurDataUrl } from '@vite-mf-monorepo/shared'\nimport clsx from 'clsx'\nimport { useCallback, useEffect, useRef, useState } from 'react'\n\nimport { Icon } from '../Icon'\n\nimport type { FC, ImgHTMLAttributes, ReactNode } from 'react'\n\nexport type ImageState = 'loading' | 'loaded' | 'error'\n\nexport type AspectRatio = '2/3' | '16/9' | '1/1' | '4/3' | '3/2'\n\nexport type ImageLoading = 'lazy' | 'eager'\n\nexport interface ImageProps\n extends Omit<ImgHTMLAttributes<HTMLImageElement>, 'placeholder'> {\n /** Image source URL */\n src: string\n /** Alt text for accessibility */\n alt: string\n /** Pre-generated blur data URL (base64) */\n blurDataUrl?: string\n /** Auto-generate blur placeholder from src using Canvas API */\n autoBlur?: boolean\n /** Size of blur canvas (smaller = more blur). Default: 16 */\n blurSize?: number\n /** JPEG quality for blur (0-1). Default: 0.3 */\n blurQuality?: number\n /** Aspect ratio of the image container */\n aspectRatio?: AspectRatio | (string & {})\n /** Fallback content when image fails to load */\n fallback?: ReactNode\n /** Callback when image loads successfully */\n onLoad?: () => void\n /** Callback when image fails to load */\n onError?: () => void\n /** Load strategy: 'lazy' waits for viewport visibility, 'eager' loads immediately. Default: 'eager' */\n loading?: ImageLoading\n}\n\nconst Image: FC<ImageProps> = ({\n src,\n alt,\n blurDataUrl,\n autoBlur = false,\n blurSize = 16,\n blurQuality = 0.3,\n aspectRatio = '2/3',\n fallback,\n className,\n onLoad,\n onError,\n loading = 'eager',\n ...rest\n}) => {\n const imgRef = useRef<HTMLImageElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n const [state, setState] = useState<ImageState>('loading')\n const [generatedBlur, setGeneratedBlur] = useState<string | undefined>(\n undefined\n )\n const [blurReady, setBlurReady] = useState(!autoBlur || !!blurDataUrl)\n const [isVisible, setIsVisible] = useState(loading === 'eager')\n\n const effectiveBlur = blurDataUrl ?? generatedBlur\n\n // Lazy load with IntersectionObserver\n useEffect(() => {\n if (loading === 'eager' || !containerRef.current) {\n return\n }\n\n const observer = new IntersectionObserver(\n ([entry]) => {\n if (entry.isIntersecting) {\n setIsVisible(true)\n observer.unobserve(entry.target)\n }\n },\n { rootMargin: '50px' }\n )\n\n observer.observe(containerRef.current)\n\n return () => {\n observer.disconnect()\n }\n }, [loading])\n\n useEffect(() => {\n if (!autoBlur || blurDataUrl) {\n setBlurReady(true)\n return\n }\n\n setBlurReady(false)\n\n getBlurDataUrl(src, blurSize, blurQuality)\n .then((base64) => {\n setGeneratedBlur(base64)\n setBlurReady(true)\n })\n .catch(() => {\n setBlurReady(true)\n })\n }, [autoBlur, src, blurDataUrl, blurSize, blurQuality])\n\n useEffect(() => {\n setState('loading')\n setGeneratedBlur(undefined)\n\n // Check if image is already loaded from cache\n if (imgRef.current?.complete && imgRef.current.naturalHeight !== 0) {\n setState('loaded')\n }\n }, [src])\n\n const handleLoad = useCallback(() => {\n setState('loaded')\n onLoad?.()\n }, [onLoad])\n\n const handleError = useCallback(() => {\n setState('error')\n onError?.()\n }, [onError])\n\n const defaultFallback = (\n <div className=\"ui:flex ui:h-full ui:w-full ui:items-center ui:justify-center ui:bg-muted\">\n <Icon\n name=\"Photo\"\n size={48}\n className=\"ui:text-muted-foreground\"\n aria-hidden=\"true\"\n />\n </div>\n )\n\n return (\n <div\n ref={containerRef}\n className={clsx('ui:relative ui:overflow-hidden ui:bg-muted', className)}\n style={aspectRatio ? { aspectRatio } : undefined}\n data-state={state}\n >\n {state === 'error' ? (\n (fallback ?? defaultFallback)\n ) : (\n <>\n {effectiveBlur && state === 'loading' && (\n <img\n src={effectiveBlur}\n alt=\"\"\n aria-hidden=\"true\"\n className=\"ui:absolute ui:inset-0 ui:h-full ui:w-full ui:scale-105 ui:object-cover\"\n />\n )}\n\n {blurReady && isVisible && (\n <img\n ref={imgRef}\n src={src}\n alt={alt}\n onLoad={handleLoad}\n onError={handleError}\n className={clsx(\n 'ui:absolute ui:inset-0 ui:h-full ui:w-full ui:object-cover ui:transition-opacity ui:duration-300',\n state === 'loaded' ? 'ui:opacity-100' : 'ui:opacity-0'\n )}\n {...rest}\n />\n )}\n </>\n )}\n </div>\n )\n}\n\nexport default Image\n","import clsx from 'clsx'\n\nimport type { ComponentProps, FC } from 'react'\n\nexport interface SkeletonProps extends ComponentProps<'div'> {\n /** Shape variant */\n variant?: 'rectangle' | 'circle' | 'line'\n /** Width (Tailwind class or custom value) */\n width?: string\n /** Height (Tailwind class or custom value) */\n height?: string\n /** Aspect ratio (e.g., \"2/3\", \"16/9\", \"1/1\") */\n aspectRatio?: string\n /** Apply rounded corners (default: true for rectangle/line, always true for circle) */\n rounded?: boolean\n}\n\n/**\n * Skeleton - Atomic loading placeholder component\n *\n * Composable primitive for building loading states with shimmer effect.\n */\nconst Skeleton: FC<SkeletonProps> = ({\n variant = 'rectangle',\n width,\n height,\n aspectRatio,\n rounded = true,\n className,\n ...rest\n}) => {\n return (\n <div\n className={clsx(\n 'ui:relative ui:overflow-hidden ui:bg-muted',\n 'ui-skeleton-shimmer',\n {\n 'ui:rounded-lg': variant === 'rectangle' && rounded,\n 'ui:rounded-full': variant === 'circle',\n 'ui:rounded': variant === 'line' && rounded,\n },\n width,\n height,\n className\n )}\n style={aspectRatio ? { aspectRatio } : undefined}\n {...rest}\n />\n )\n}\n\nexport default Skeleton\n","import { getOptimizedImageUrl } from '@vite-mf-monorepo/shared'\nimport { useState } from 'react'\n\nimport { Skeleton } from '../Skeleton'\n\nimport type { FC } from 'react'\n\nexport interface HeroImageProps {\n /** Backdrop path from TMDB API */\n backdropPath?: string | null\n /** Alt text for the image */\n title?: string | null\n}\n\n/**\n * HeroImage component for displaying optimized backdrop images with responsive sources\n * and gradient overlay. Used in hero sections across the application.\n */\nconst HeroImage: FC<HeroImageProps> = ({ backdropPath, title }) => {\n const [loading, setLoading] = useState(true)\n\n const backdropPathMobile = backdropPath\n ? getOptimizedImageUrl(backdropPath, 'w300', 60)\n : undefined\n\n const backdropPathTablet = backdropPath\n ? getOptimizedImageUrl(backdropPath, 'w300', 60)\n : undefined\n\n const backdropPathDesktop = backdropPath\n ? getOptimizedImageUrl(backdropPath, 'w780', 60)\n : undefined\n\n const backdropPathUltraWide = backdropPath\n ? getOptimizedImageUrl(backdropPath, 'w1280', 60)\n : undefined\n\n return (\n <>\n {loading && (\n <Skeleton\n data-testid=\"hero-image-skeleton\"\n variant=\"rectangle\"\n width=\"ui:relative ui:w-full ui:h-full ui:hero-height ui:z-0\"\n aspectRatio=\"21/9\"\n rounded={false}\n />\n )}\n <picture>\n {backdropPathMobile && (\n <source media=\"(max-width: 639px)\" srcSet={backdropPathMobile} />\n )}\n {backdropPathTablet && (\n <source media=\"(max-width: 1023px)\" srcSet={backdropPathTablet} />\n )}\n {backdropPathDesktop && (\n <source media=\"(max-width: 1535px)\" srcSet={backdropPathDesktop} />\n )}\n {backdropPathUltraWide && (\n <source media=\"(min-width: 1536px)\" srcSet={backdropPathUltraWide} />\n )}\n {backdropPathMobile && (\n <img\n src={backdropPathMobile}\n fetchPriority=\"high\"\n onLoad={() => {\n setLoading(false)\n }}\n alt={title ?? 'Unknown'}\n className=\"ui:relative ui:h-full ui:w-full ui:object-cover ui:object-center ui:z-0\"\n />\n )}\n </picture>\n {/* Gradient Overlay */}\n <div className=\"ui:absolute ui:inset-0 ui:bg-gradient-to-t ui:from-black/80 ui:via-black/40 ui:to-transparent ui:z-1 ui:top-0 ui:left-0 ui:right-0 ui:bottom-0\" />\n </>\n )\n}\n\nexport default HeroImage\n","import clsx from 'clsx'\nimport { useEffect, useRef } from 'react'\n\nimport type { FC, MouseEvent, ReactNode } from 'react'\n\nexport interface ModalProps {\n /** Whether the modal is open */\n isOpen: boolean\n /** Callback when modal should close (ESC key, backdrop click) */\n onClose: () => void\n /** Modal content */\n children: ReactNode\n /** Accessible label for screen readers (required) */\n 'aria-label': string\n /** Additional class name for the dialog element */\n className?: string\n /** Optional callback for backdrop click. Falls back to onClose if not provided. */\n onOverlayClick?: () => void\n}\n\nconst Modal: FC<ModalProps> = ({\n isOpen,\n onClose,\n children,\n 'aria-label': ariaLabel,\n className,\n onOverlayClick,\n}) => {\n const ref = useRef<HTMLDialogElement>(null)\n\n /**\n * Effect: Opens or closes the native <dialog> element and locks body scroll.\n * - showModal() places dialog in the top layer (above all MFE remotes, no z-index needed).\n * - Scroll lock is manual — <dialog> does not lock scroll natively.\n * - Cleanup restores overflow in case the component unmounts while open.\n */\n useEffect(() => {\n const dialog = ref.current\n if (!dialog) return\n\n if (isOpen) {\n dialog.showModal()\n document.body.style.overflow = 'hidden'\n } else {\n dialog.close()\n document.body.style.overflow = ''\n }\n\n return () => {\n document.body.style.overflow = ''\n }\n }, [isOpen])\n\n /**\n * Closes the modal when clicking the <dialog> element itself (the backdrop area).\n * e.target === ref.current only when clicking outside the dialog content,\n * since content clicks bubble up to a child, not to the dialog element directly.\n */\n const handleClick = (e: MouseEvent<HTMLDialogElement>) => {\n if (e.target === ref.current) (onOverlayClick ?? onClose)()\n }\n\n /**\n * Syncs the native ESC key close event (fired by the browser on <dialog>)\n * with the onClose callback, so parent state stays in sync.\n */\n const handleClose = () => {\n onClose()\n }\n\n return (\n <dialog\n ref={ref}\n aria-label={ariaLabel}\n aria-modal=\"true\"\n onClick={handleClick}\n onClose={handleClose}\n className={clsx(\n 'ui:backdrop:bg-black/80',\n 'ui:bg-transparent ui:border-0 ui:p-0',\n 'ui:max-w-none ui:max-h-none ui:w-full ui:h-full',\n className\n )}\n >\n {children}\n </dialog>\n )\n}\n\nexport default Modal\n","import clsx from 'clsx'\n\nimport type { RatingSize } from './Rating'\nimport type { FC } from 'react'\n\nconst circleSizeMap: Record<\n RatingSize,\n { size: number; stroke: number; fontSize: string }\n> = {\n sm: { size: 32, stroke: 3, fontSize: 'ui:text-xs' },\n md: { size: 48, stroke: 4, fontSize: 'ui:text-sm' },\n lg: { size: 64, stroke: 5, fontSize: 'ui:text-base' },\n}\n\nconst getColorClass = (percent: number): string => {\n if (percent >= 70) return 'ui:text-green-600'\n if (percent >= 40) return 'ui:text-amber-600'\n return 'ui:text-red-500'\n}\n\nexport interface CircleRatingProps {\n /** Percentage value (0-100) for the progress ring */\n percent: number\n /** Size of the rating circle */\n size: RatingSize\n /** Whether to display the numeric value in the center */\n showValue: boolean\n /** The actual rating value (used for display) */\n value: number\n /** Maximum rating value (used for display formatting) */\n max: number\n /** Custom class for the background track circle */\n trackClassName?: string\n}\n\nconst CircleRating: FC<CircleRatingProps> = ({\n percent,\n size,\n showValue,\n value,\n max,\n trackClassName,\n}) => {\n const { size: svgSize, stroke, fontSize } = circleSizeMap[size]\n const radius = (svgSize - stroke) / 2\n const circumference = 2 * Math.PI * radius\n const offset = circumference - (percent / 100) * circumference\n\n return (\n <div className=\"ui:relative ui:inline-flex ui:items-center ui:justify-center\">\n <svg width={svgSize} height={svgSize} className=\"ui:-rotate-90\">\n <circle\n cx={svgSize / 2}\n cy={svgSize / 2}\n r={radius}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={stroke}\n className={trackClassName ?? 'ui:text-gray-200'}\n />\n <circle\n cx={svgSize / 2}\n cy={svgSize / 2}\n r={radius}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={stroke}\n strokeLinecap=\"round\"\n strokeDasharray={circumference}\n strokeDashoffset={offset}\n className={clsx(\n 'ui:transition-all ui:duration-500',\n getColorClass(percent)\n )}\n />\n </svg>\n {showValue && (\n <span\n className={clsx(\n 'ui:absolute ui:font-bold',\n fontSize,\n getColorClass(percent)\n )}\n >\n {max === 100 ? Math.round(percent) : value.toFixed(1)}\n </span>\n )}\n </div>\n )\n}\n\nexport default CircleRating\n","import clsx from 'clsx'\n\nimport { Icon } from '../Icon'\n\nimport type { IconSize } from '../Icon'\nimport type { RatingSize } from './Rating'\nimport type { FC } from 'react'\n\nconst starsSizeMap: Record<RatingSize, IconSize> = {\n sm: 16,\n md: 20,\n lg: 24,\n}\n\nexport interface StarsRatingProps {\n /** Percentage value (0-100) for the star fill */\n percent: number\n /** Size of the stars */\n size: RatingSize\n /** Whether to display the numeric value next to stars */\n showValue: boolean\n /** The actual rating value (used for display) */\n value: number\n /** Maximum rating value (used for display formatting) */\n max: number\n}\n\nconst StarsRating: FC<StarsRatingProps> = ({\n percent,\n size,\n showValue,\n value,\n max,\n}) => {\n const iconSize = starsSizeMap[size]\n\n return (\n <div className=\"ui:inline-flex ui:items-center ui:gap-1\">\n <div className=\"ui:relative\">\n {/* Empty stars */}\n <div className=\"ui:flex ui:text-gray-300\">\n {[1, 2, 3, 4, 5].map((i) => (\n <Icon key={i} name=\"Star\" size={iconSize} />\n ))}\n </div>\n {/* Filled stars with clip */}\n <div\n className=\"ui:absolute ui:inset-0 ui:flex ui:text-yellow-400\"\n style={{ clipPath: `inset(0 ${String(100 - percent)}% 0 0)` }}\n >\n {[1, 2, 3, 4, 5].map((i) => (\n <Icon key={i} name=\"Star\" size={iconSize} />\n ))}\n </div>\n </div>\n {showValue && (\n <span\n className={clsx(\n 'ui:font-medium ui:text-muted-foreground',\n size === 'sm' && 'ui:text-xs',\n size === 'md' && 'ui:text-sm',\n size === 'lg' && 'ui:text-base'\n )}\n >\n {max === 100 ? (value / 10).toFixed(1) : value.toFixed(1)}\n </span>\n )}\n </div>\n )\n}\n\nexport default StarsRating\n","import clsx from 'clsx'\n\nimport CircleRating from './CircleRating'\nimport StarsRating from './StarsRating'\n\nimport type { FC } from 'react'\n\nexport type RatingVariant = 'circle' | 'stars'\nexport type RatingSize = 'sm' | 'md' | 'lg'\n\nexport interface RatingProps {\n /** Rating value (0-10 by default, or 0-100 if max=100) */\n value: number\n /** Maximum value (default: 10 for TMDB scores) */\n max?: number\n /** Visual variant */\n variant?: RatingVariant\n /** Size of the rating */\n size?: RatingSize\n /** Show the numeric value */\n showValue?: boolean\n /** Custom class for the background track circle (circle variant only) */\n trackClassName?: string\n /** Additional class name */\n className?: string\n}\n\nconst Rating: FC<RatingProps> = ({\n value,\n max = 10,\n variant = 'circle',\n size = 'md',\n showValue = true,\n trackClassName,\n className,\n}) => {\n const clampedValue = Math.max(0, Math.min(value, max))\n const percent = (clampedValue / max) * 100\n\n return (\n <div className={clsx('ui:inline-flex', className)}>\n {variant === 'circle' ? (\n <CircleRating\n percent={percent}\n size={size}\n showValue={showValue}\n value={clampedValue}\n max={max}\n trackClassName={trackClassName}\n />\n ) : (\n <StarsRating\n percent={percent}\n size={size}\n showValue={showValue}\n value={clampedValue}\n max={max}\n />\n )}\n </div>\n )\n}\n\nexport default Rating\n","import clsx from 'clsx'\nimport { createElement } from 'react'\n\nimport type { ElementType, FC, HTMLAttributes, ReactNode } from 'react'\n\nexport type TypographyVariant =\n | 'h1'\n | 'h2'\n | 'h3'\n | 'h4'\n | 'h5'\n | 'h6'\n | 'body'\n | 'body-sm'\n | 'body-lg'\n | 'lead'\n | 'caption'\n | 'caption-xs'\n | 'label'\n | 'muted'\n | 'blockquote'\n\nexport interface TypographyProps extends HTMLAttributes<HTMLElement> {\n /** Visual style variant */\n variant: TypographyVariant\n /** Override semantic HTML tag */\n as?: ElementType\n /** Additional CSS classes */\n className?: string\n /** Content */\n children: ReactNode\n}\n\nconst variantStyles: Record<TypographyVariant, string> = {\n h1: 'ui:font-roboto ui:text-xl ui:sm:text-2xl ui:md:text-3xl ui:lg:text-4xl ui:font-bold ui:leading-tight ui:text-foreground',\n h2: 'ui:font-roboto ui:text-lg ui:sm:text-xl ui:md:text-2xl ui:lg:text-3xl ui:font-bold ui:leading-tight ui:text-foreground',\n h3: 'ui:font-roboto ui:text-base ui:sm:text-lg ui:md:text-xl ui:lg:text-2xl ui:font-semibold ui:leading-snug ui:text-foreground',\n h4: 'ui:font-roboto ui:text-sm ui:sm:text-base ui:md:text-lg ui:lg:text-xl ui:font-semibold ui:leading-snug ui:text-foreground',\n h5: 'ui:font-roboto ui:text-sm ui:sm:text-base ui:md:text-lg ui:font-medium ui:leading-normal ui:text-foreground',\n h6: 'ui:font-roboto ui:text-xs ui:sm:text-sm ui:md:text-base ui:font-medium ui:leading-normal ui:text-foreground',\n body: 'ui:font-inter ui:text-xs ui:sm:text-sm ui:md:text-base ui:leading-relaxed ui:text-foreground',\n 'body-sm':\n 'ui:font-inter ui:text-xs ui:sm:text-sm ui:leading-relaxed ui:text-foreground',\n 'body-lg':\n 'ui:font-inter ui:text-sm ui:sm:text-base ui:md:text-lg ui:leading-relaxed ui:text-foreground',\n lead: 'ui:font-inter ui:text-sm ui:sm:text-base ui:md:text-lg ui:lg:text-xl ui:leading-relaxed ui:text-muted-foreground',\n caption: 'ui:font-inter ui:text-xs ui:sm:text-sm ui:text-muted-foreground',\n 'caption-xs': 'ui:font-inter ui:text-xs ui:text-muted-foreground',\n label:\n 'ui:font-inter ui:text-xs ui:sm:text-sm ui:font-medium ui:text-foreground',\n muted: 'ui:font-inter ui:text-xs ui:sm:text-sm ui:text-muted-foreground',\n blockquote:\n 'ui:font-inter ui:text-xs ui:sm:text-sm ui:md:text-base ui:border-l-4 ui:border-border ui:pl-4 ui:italic ui:text-muted-foreground',\n}\n\nconst variantToTag: Record<TypographyVariant, ElementType> = {\n h1: 'h1',\n h2: 'h2',\n h3: 'h3',\n h4: 'h4',\n h5: 'h5',\n h6: 'h6',\n body: 'p',\n 'body-sm': 'p',\n 'body-lg': 'p',\n lead: 'p',\n caption: 'span',\n 'caption-xs': 'span',\n label: 'label',\n muted: 'p',\n blockquote: 'blockquote',\n}\n\nconst Typography: FC<TypographyProps> = ({\n variant,\n as,\n className,\n children,\n ...rest\n}) => {\n const Component = as ?? variantToTag[variant]\n\n return createElement(\n Component,\n { className: clsx(variantStyles[variant], className), ...rest },\n children\n )\n}\n\nexport default Typography\n","import clsx from 'clsx'\nimport { Link } from 'react-router-dom'\n\nimport { Card } from '../Card'\nimport { Image } from '../Image'\nimport { Rating } from '../Rating'\nimport { Typography } from '../Typography'\n\nimport type { MovieCardProps } from './MovieCard.types'\nimport type { FC } from 'react'\n\nconst MovieCard: FC<MovieCardProps> = ({\n id,\n title,\n posterUrl,\n voteAverage,\n year,\n className,\n imageLoading = 'lazy',\n as = 'card',\n ...rest\n}) => {\n // Extract conditional props based on 'as' variant\n const to = 'to' in rest ? rest.to : undefined\n const onClick = 'onClick' in rest ? rest.onClick : undefined\n\n // Determine if card should be interactive\n const isInteractive = as === 'link' || as === 'button'\n\n const cardContent = (\n <Card\n variant=\"ghost\"\n className={clsx(\n 'ui:group ui:relative ui:flex ui:flex-col ui:overflow-hidden',\n isInteractive && [\n 'ui:cursor-pointer',\n 'ui:transition-transform ui:duration-200',\n 'hover:ui:scale-[1.02]',\n ],\n className\n )}\n onClick={as === 'button' ? onClick : undefined}\n data-testid={`movie-card-${String(id)}`}\n >\n {/* Poster */}\n <div className=\"ui:relative ui:aspect-[2/3] ui:w-full ui:overflow-hidden ui:rounded-md ui:bg-gray-200\">\n <Image\n src={posterUrl}\n alt={title}\n loading={imageLoading}\n aspectRatio={undefined}\n className=\"ui:h-full ui:w-full ui:object-cover\"\n />\n {/* Rating badge */}\n <div className=\"ui:absolute ui:bottom-2 ui:right-2 ui:flex ui:items-center ui:justify-center ui:rounded-full ui:bg-white/80 ui:p-1\">\n <Rating\n value={voteAverage}\n size=\"sm\"\n variant=\"circle\"\n trackClassName=\"ui:text-gray-200\"\n className=\"ui:drop-shadow\"\n />\n </div>\n </div>\n\n {/* Content */}\n <div className=\"ui:mt-2 ui:flex ui:flex-col ui:gap-0.5 ui:px-1\">\n <Typography\n variant=\"label\"\n as=\"h3\"\n className=\"ui:line-clamp-2\"\n title={title}\n >\n {title}\n </Typography>\n {year && (\n <Typography\n variant=\"caption-xs\"\n className=\"ui:[.media-section:nth-of-type(odd)_&]:text-badge-foreground\"\n >\n {year}\n </Typography>\n )}\n </div>\n </Card>\n )\n\n if (as === 'link' && to) {\n return (\n <Link to={to} className=\"ui:block ui:no-underline ui:text-inherit\">\n {cardContent}\n </Link>\n )\n }\n\n return cardContent\n}\n\nexport default MovieCard\n","import clsx from 'clsx'\nimport { useState } from 'react'\n\nimport { Button } from '../Button'\nimport { Modal } from '../Modal'\n\nimport type { FC } from 'react'\n\nexport interface TrailerCardProps {\n /** YouTube video ID */\n videoKey: string\n /** Trailer title/name */\n title: string\n /** Video type (Trailer, Clip, Featurette, etc.) */\n type?: string\n /** Additional className for the card */\n className?: string\n}\n\nconst TrailerCard: FC<TrailerCardProps> = ({\n videoKey,\n title,\n type = 'Trailer',\n className,\n}) => {\n const [isPlaying, setIsPlaying] = useState(false)\n\n const thumbnailUrl = `https://img.youtube.com/vi/${videoKey}/hqdefault.jpg`\n\n return (\n <>\n {/* Thumbnail card with play button overlay */}\n <button\n className={clsx(\n 'ui:group ui:relative ui:flex ui:aspect-video ui:w-full ui:cursor-pointer ui:overflow-hidden ui:rounded-lg ui:bg-gray-200',\n 'ui:transition-transform ui:duration-200 hover:ui:scale-[1.02]',\n className\n )}\n onClick={() => {\n setIsPlaying(true)\n }}\n tabIndex={0}\n aria-label={`Play ${title}`}\n >\n {/* Thumbnail image */}\n <img\n src={thumbnailUrl}\n alt={title}\n className=\"ui:h-full ui:w-full ui:object-cover\"\n loading=\"lazy\"\n />\n\n {/* Play button overlay */}\n <div className=\"ui:absolute ui:inset-0 ui:flex ui:items-center ui:justify-center ui:bg-black/30 ui:opacity-0 ui:transition-opacity ui:duration-200 group-hover:ui:opacity-100\">\n <div className=\"ui:flex ui:items-center ui:justify-center ui:h-16 ui:w-16 ui:rounded-full ui:bg-white/90\">\n <span className=\"ui:text-2xl ui:ml-1\">▶</span>\n </div>\n </div>\n\n {/* Type badge */}\n {type && (\n <div className=\"ui:absolute ui:bottom-2 ui:left-2 ui:rounded ui:bg-black/80 ui:px-2 ui:py-1 ui:text-xs ui:font-semibold ui:text-white\">\n {type}\n </div>\n )}\n </button>\n\n {/* Modal with YouTube embed */}\n <Modal\n isOpen={isPlaying}\n onClose={() => {\n setIsPlaying(false)\n }}\n aria-label={`Play ${title}`}\n >\n {/* Inner wrapper: flex centering — must NOT be on <dialog> itself to preserve display:none when closed */}\n <div className=\"ui:flex ui:h-full ui:w-full ui:items-center ui:justify-center ui:p-4\">\n {/* Close button */}\n <Button\n icon=\"XMark\"\n size=\"sm\"\n variant=\"ghost\"\n iconPosition=\"left\"\n onClick={() => {\n setIsPlaying(false)\n }}\n className=\"ui:absolute ui:top-4 ui:right-4 ui:text-white hover:ui:bg-white/10 ui:z-10 ui:focus:border-none\"\n aria-label=\"Close video\"\n >\n Close video\n </Button>\n\n {/* Responsive 16:9 iframe container */}\n {isPlaying && (\n <iframe\n className=\"ui:w-full ui:max-w-4xl ui:aspect-video ui:rounded-lg\"\n src={`https://www.youtube.com/embed/${videoKey}`}\n title={title}\n allow=\"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture\"\n allowFullScreen\n />\n )}\n </div>\n </Modal>\n </>\n )\n}\n\nexport default TrailerCard\n","import clsx from 'clsx'\n\nimport type { FC } from 'react'\n\nexport interface CarouselCounterProps {\n /** Current index (0-based) — displayed as 1-based */\n current: number\n /** Total number of items */\n total: number\n /** Additional class name */\n className?: string\n}\n\n/**\n * Counter for Carousel lightbox variant.\n * Displays current position as \"3 / 20\" (1-indexed).\n */\nconst CarouselCounter: FC<CarouselCounterProps> = ({\n current,\n total,\n className,\n}) => {\n return (\n <div\n className={clsx(\n 'ui:bg-black/50 ui:rounded-full ui:px-3 ui:py-1',\n 'ui:text-white/90 ui:text-sm ui:font-medium ui:tabular-nums',\n className\n )}\n >\n {current + 1} / {total}\n </div>\n )\n}\n\nexport default CarouselCounter\n","import { Icon } from '../Icon'\n\nimport type { FC } from 'react'\n\nexport interface CarouselErrorProps {\n message?: string\n}\n\nconst CarouselError: FC<CarouselErrorProps> = ({\n message = 'Failed to load data',\n}) => {\n return (\n <div className=\"ui:flex ui:flex-col ui:items-center ui:justify-center ui:gap-3 ui:rounded-lg ui:border ui:border-red-200 ui:bg-red-50 ui:p-8 ui:text-center\">\n <Icon name=\"ExclamationTriangle\" size={48} className=\"ui:text-red-500\" />\n <div className=\"ui:flex ui:flex-col ui:gap-1\">\n <p className=\"ui:text-sm ui:font-semibold ui:text-red-900\">\n Failed to fetch data\n </p>\n <p className=\"ui:text-sm ui:text-red-700\">{message}</p>\n </div>\n </div>\n )\n}\n\nexport default CarouselError\n","import clsx from 'clsx'\n\nimport { IconButton } from '../IconButton'\n\nimport type { FC } from 'react'\n\n/** Position mode for navigation buttons */\nexport type CarouselNavigationPosition = 'inline' | 'sides' | 'sides-inset'\n\nexport interface CarouselNavigationProps {\n /** Callback for previous button */\n onPrev: () => void\n /** Callback for next button */\n onNext: () => void\n /** Whether previous is disabled */\n canPrev: boolean\n /** Whether next is disabled */\n canNext: boolean\n /** Button size */\n size?: 'sm' | 'md'\n /** Position mode */\n position?: CarouselNavigationPosition\n /** Icon button visual variant — ghost for lightbox (white arrows on dark bg) */\n iconVariant?: 'secondary' | 'ghost'\n /** Additional class name */\n className?: string\n}\n\n/**\n * Navigation buttons for Carousel (previous/next).\n * - inline: side by side (for bottom-right layout)\n * - sides: absolute, centered on the carousel edges (overhangs container — standard carousel)\n * - sides-inset: absolute, inside the container with padding (lightbox, fullscreen contexts)\n */\nconst CarouselNavigation: FC<CarouselNavigationProps> = ({\n onPrev,\n onNext,\n canPrev,\n canNext,\n size = 'sm',\n position = 'inline',\n iconVariant = 'secondary',\n className,\n}) => {\n if (position === 'sides') {\n return (\n <>\n <div className=\"ui:absolute ui:left-0 ui:top-1/2 ui:-translate-x-1/2 ui:-translate-y-1/2\">\n <IconButton\n icon=\"ChevronLeft\"\n variant={iconVariant}\n size={size}\n onClick={onPrev}\n disabled={!canPrev}\n aria-label=\"Previous\"\n />\n </div>\n <div className=\"ui:absolute ui:right-0 ui:top-1/2 ui:-translate-y-1/2 ui:translate-x-1/2\">\n <IconButton\n icon=\"ChevronRight\"\n variant={iconVariant}\n size={size}\n onClick={onNext}\n disabled={!canNext}\n aria-label=\"Next\"\n />\n </div>\n </>\n )\n }\n\n if (position === 'sides-inset') {\n return (\n <>\n <div className=\"ui:absolute ui:left-4 ui:top-1/2 ui:-translate-y-1/2 ui:z-10 ui:text-white\">\n <IconButton\n icon=\"ChevronLeft\"\n variant={iconVariant}\n size={size}\n onClick={onPrev}\n disabled={!canPrev}\n aria-label=\"Previous\"\n className=\"ui:bg-white/20 ui:hover:bg-white/55\"\n />\n </div>\n <div className=\"ui:absolute ui:right-4 ui:top-1/2 ui:-translate-y-1/2 ui:z-10 ui:text-white\">\n <IconButton\n icon=\"ChevronRight\"\n variant={iconVariant}\n size={size}\n onClick={onNext}\n disabled={!canNext}\n aria-label=\"Next\"\n className=\"ui:bg-white/20 ui:hover:bg-white/55\"\n />\n </div>\n </>\n )\n }\n\n return (\n <div className={clsx('ui:flex ui:gap-2', className)}>\n <IconButton\n icon=\"ChevronLeft\"\n variant={iconVariant}\n size={size}\n onClick={onPrev}\n disabled={!canPrev}\n aria-label=\"Previous\"\n />\n <IconButton\n icon=\"ChevronRight\"\n variant={iconVariant}\n size={size}\n onClick={onNext}\n disabled={!canNext}\n aria-label=\"Next\"\n />\n </div>\n )\n}\n\nexport default CarouselNavigation\n","import clsx from 'clsx'\n\nimport type { FC } from 'react'\n\nexport interface CarouselPaginationProps {\n /** Total number of items */\n total: number\n /** Current active index */\n current: number\n /** Use light colors (for dark backgrounds) */\n light?: boolean\n /** Additional class name */\n className?: string\n}\n\n/**\n * Pagination dots for Carousel.\n * Active dot is displayed as a capsule (wider), inactive dots are circles.\n * Supports light mode for dark backgrounds (white dots).\n */\nconst CarouselPagination: FC<CarouselPaginationProps> = ({\n total,\n current,\n light = false,\n className,\n}) => {\n if (total === 0) return null\n\n return (\n <div className={clsx('ui:flex ui:items-center ui:gap-2', className)}>\n {Array.from({ length: total }).map((_, index) => (\n <div\n key={index}\n aria-hidden=\"true\"\n className={clsx(\n 'ui:rounded-full ui:transition-all ui:duration-300',\n index === current\n ? clsx('ui:h-2 ui:w-6', light ? 'ui:bg-white' : 'ui:bg-primary')\n : clsx(\n 'ui:h-2 ui:w-2',\n light\n ? 'ui:bg-white/50 hover:ui:bg-white/70'\n : 'ui:bg-gray-400 hover:ui:bg-gray-500'\n )\n )}\n />\n ))}\n </div>\n )\n}\n\nexport default CarouselPagination\n","import clsx from 'clsx'\nimport {\n useCallback,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react'\n\nimport CarouselCounter from './CarouselCounter'\nimport CarouselError from './CarouselError'\nimport CarouselNavigation from './CarouselNavigation'\nimport CarouselPagination from './CarouselPagination'\n\nimport type { FC, ReactNode } from 'react'\n\n/** Carousel visual variant */\nexport type CarouselVariant = 'standard' | 'hero' | 'lightbox'\n\n/** Arrow position for navigation buttons */\nexport type CarouselArrowPosition = 'sides' | 'bottom-right'\n\nexport interface CarouselProps {\n /** Carousel items */\n children?: ReactNode\n /** Visual variant */\n variant?: CarouselVariant\n /** Show pagination dots (ignored for lightbox — counter is shown instead) */\n showPagination?: boolean\n /** Show navigation arrows */\n showArrows?: boolean\n /** Arrow position */\n arrowPosition?: CarouselArrowPosition\n /** Gap between items in pixels */\n gap?: number\n /** Additional class name */\n className?: string\n /** Class name for the hero controls container (pagination + arrows) — use to constrain width/padding */\n heroControlsClassName?: string\n /** Error message to display instead of carousel content */\n errorMessage?: string\n /** Apply rounded corners to viewport */\n rounded?: boolean\n /**\n * Initial scroll index — jumps to this item on mount without animation.\n * Use with key={index} on Carousel for URL-based navigation (lightbox).\n */\n initialIndex?: number\n /**\n * Override internal prev navigation (e.g. navigate to previous URL in lightbox).\n * When provided, replaces internal scrollPrev.\n */\n onPrev?: () => void\n /**\n * Override internal next navigation (e.g. navigate to next URL in lightbox).\n * When provided, replaces internal scrollNext.\n */\n onNext?: () => void\n /**\n * When true, all internal scroll transitions are instant (no smooth animation).\n * Use for lightbox with URL-based navigation where the Carousel remounts each time.\n */\n disableAnimation?: boolean\n /**\n * When true, user-initiated wheel/trackpad scroll is blocked on the container,\n * and currentIndex is driven entirely by initialIndex (no scroll tracking).\n * Use for URL-driven carousels (lightbox) to avoid scroll/resize desync.\n */\n disableScroll?: boolean\n}\n\n/**\n * Carousel component with horizontal scroll, pagination, and navigation.\n * Supports three variants:\n * - standard: multi-items horizontal scroll\n * - hero: single panoramic item with snap\n * - lightbox: single item per view, ghost arrows, counter (for PhotoViewer)\n */\nconst Carousel: FC<CarouselProps> = ({\n children,\n variant = 'standard',\n showPagination = true,\n showArrows = true,\n arrowPosition = 'sides',\n gap = 16,\n className,\n heroControlsClassName,\n errorMessage,\n rounded = true,\n initialIndex,\n onPrev,\n onNext,\n disableAnimation = false,\n disableScroll = false,\n}) => {\n const scrollRef = useRef<HTMLDivElement>(null)\n const [totalPositions, setTotalPositions] = useState(1)\n\n /**\n * Internal scroll-tracked index — updated by handleScroll on every scroll event.\n * Only used when disableScroll=false (scroll-driven mode).\n */\n const [scrollIndex, setScrollIndex] = useState(initialIndex ?? 0)\n\n /**\n * Effective current index.\n * - disableScroll=true → driven by initialIndex prop (URL-driven, no scroll tracking)\n * - disableScroll=false → driven by scroll events via scrollIndex state\n * This separation prevents ResizeObserver/snap drift from corrupting the index\n * in URL-driven carousels (lightbox).\n */\n const currentIndex = disableScroll ? (initialIndex ?? 0) : scrollIndex\n\n const isHero = variant === 'hero'\n const isLightbox = variant === 'lightbox'\n /** Hero and lightbox both use container width for per-item scroll calculation */\n const isFullWidth = isHero || isLightbox\n\n /**\n * Calculates the total number of scroll positions based on container and item dimensions.\n * For hero/lightbox: positions = number of items (one per slide).\n * For standard: positions = ceil(maxScrollLeft / itemWidth) + 1.\n */\n const calculatePositions = useCallback(() => {\n const container = scrollRef.current\n if (!container) return\n\n const items = container.children\n\n if (isFullWidth) {\n setTotalPositions(items.length)\n return\n }\n\n const firstItem = items[0] as HTMLElement | undefined\n if (!firstItem) {\n setTotalPositions(1)\n return\n }\n\n const itemWidth = firstItem.offsetWidth\n const maxScrollLeft = container.scrollWidth - container.offsetWidth\n\n if (maxScrollLeft <= 0) {\n setTotalPositions(1)\n } else if (itemWidth > 0) {\n const positions = Math.round(maxScrollLeft / (itemWidth + gap)) + 1\n setTotalPositions(Math.max(1, positions))\n }\n }, [gap, isFullWidth])\n\n /**\n * Effect: Recalculates positions when children or calculatePositions function changes.\n */\n useEffect(() => {\n calculatePositions()\n }, [children, calculatePositions])\n\n /**\n * Effect: Sets up ResizeObserver to recalculate positions on viewport/container resize.\n */\n useEffect(() => {\n const container = scrollRef.current\n if (!container) return\n\n const resizeObserver = new ResizeObserver(() => {\n calculatePositions()\n })\n\n resizeObserver.observe(container)\n return () => {\n resizeObserver.disconnect()\n }\n }, [calculatePositions])\n\n /**\n * Effect: Jumps to initialIndex on mount (no animation).\n * Consumed by lightbox via key={index} remounting — refs avoid stale closure.\n */\n const initialScrollRef = useRef({\n index: initialIndex ?? 0,\n isFullWidth,\n gap,\n })\n\n useLayoutEffect(() => {\n const { index, isFullWidth: fw, gap: g } = initialScrollRef.current\n if (index <= 0) return\n const container = scrollRef.current\n if (!container) return\n const firstItem = container.children[0] as HTMLElement | undefined\n const itemWidth = fw ? container.offsetWidth : (firstItem?.offsetWidth ?? 0)\n // Override CSS scroll-behavior: smooth — jump must be instant before first paint\n container.style.scrollBehavior = 'auto'\n container.scrollLeft = index * (itemWidth + (fw ? 0 : g))\n container.style.scrollBehavior = ''\n }, [])\n\n /**\n * Effect: Tracks scroll position to update currentIndex.\n * Skipped entirely when disableScroll=true (currentIndex comes from initialIndex).\n */\n const handleScroll = useCallback(() => {\n const container = scrollRef.current\n if (!container) return\n\n const scrollLeft = container.scrollLeft\n const firstItem = container.children[0] as HTMLElement | undefined\n const itemWidth = isFullWidth\n ? container.offsetWidth\n : (firstItem?.offsetWidth ?? 0)\n\n if (itemWidth > 0) {\n const index = Math.round(scrollLeft / (itemWidth + gap))\n setScrollIndex(Math.min(index, totalPositions - 1))\n }\n }, [gap, isFullWidth, totalPositions])\n\n /**\n * Effect: Attaches scroll listener to update scrollIndex.\n * Skipped when disableScroll=true — currentIndex is driven by initialIndex prop instead.\n */\n useEffect(() => {\n if (disableScroll) return\n const container = scrollRef.current\n if (!container) return\n\n container.addEventListener('scroll', handleScroll)\n return () => {\n container.removeEventListener('scroll', handleScroll)\n }\n }, [disableScroll, handleScroll])\n\n /**\n * Effect: Blocks wheel/trackpad scroll when disableScroll=true.\n * Uses preventDefault on wheel events — must be non-passive to work.\n */\n useEffect(() => {\n if (!disableScroll) return\n const container = scrollRef.current\n if (!container) return\n\n const preventScroll = (e: WheelEvent) => {\n e.preventDefault()\n }\n\n container.addEventListener('wheel', preventScroll, { passive: false })\n return () => {\n container.removeEventListener('wheel', preventScroll)\n }\n }, [disableScroll])\n\n /**\n * Scrolls to a specific position index with smooth animation.\n */\n const scrollTo = useCallback(\n (index: number) => {\n const container = scrollRef.current\n if (!container) return\n\n const firstItem = container.children[0] as HTMLElement | undefined\n const itemWidth = isFullWidth\n ? container.offsetWidth\n : (firstItem?.offsetWidth ?? 0)\n\n const isLastPosition = index === totalPositions - 1\n const scrollLeft = isLastPosition\n ? container.scrollWidth - container.offsetWidth\n : index * (itemWidth + gap)\n\n container.scrollTo({\n left: scrollLeft,\n behavior: disableAnimation ? 'auto' : 'smooth',\n })\n },\n [gap, isFullWidth, totalPositions, disableAnimation]\n )\n\n /** Scrolls to the previous position (internal fallback when onPrev is not provided) */\n const scrollPrev = useCallback(() => {\n if (currentIndex > 0) {\n scrollTo(currentIndex - 1)\n }\n }, [currentIndex, scrollTo])\n\n /** Scrolls to the next position (internal fallback when onNext is not provided) */\n const scrollNext = useCallback(() => {\n if (currentIndex < totalPositions - 1) {\n scrollTo(currentIndex + 1)\n }\n }, [currentIndex, totalPositions, scrollTo])\n\n /** Effective prev handler: external callback takes priority over internal scroll */\n const handlePrev = onPrev ?? scrollPrev\n /** Effective next handler: external callback takes priority over internal scroll */\n const handleNext = onNext ?? scrollNext\n\n /**\n * Refs that always point to the latest handlePrev/handleNext.\n * Allows the keyboard effect to use a stable listener (empty deps) without stale closures.\n */\n const handlePrevRef = useRef(handlePrev)\n const handleNextRef = useRef(handleNext)\n useEffect(() => {\n handlePrevRef.current = handlePrev\n handleNextRef.current = handleNext\n })\n\n /**\n * Effect: Keyboard navigation — ArrowLeft/ArrowRight trigger prev/next.\n * Listens on document so it works in lightbox (fullscreen) without requiring focus.\n */\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'ArrowLeft') handlePrevRef.current()\n if (e.key === 'ArrowRight') handleNextRef.current()\n }\n document.addEventListener('keydown', handleKeyDown)\n return () => {\n document.removeEventListener('keydown', handleKeyDown)\n }\n }, [])\n\n if (errorMessage) {\n return <CarouselError message={errorMessage} />\n }\n\n const canScrollPrev = currentIndex > 0\n const canScrollNext = currentIndex < totalPositions - 1\n const showControls = totalPositions > 1\n\n return (\n <div className={clsx('ui:relative', isLightbox && 'ui:h-full', className)}>\n {/* Scroll container */}\n <div\n ref={scrollRef}\n className={clsx(\n 'ui:flex ui:overflow-x-auto ui:scroll-smooth ui:scrollbar-none',\n isFullWidth && 'ui:snap-x ui:snap-mandatory',\n isLightbox && 'ui:h-full',\n rounded && 'ui:rounded-lg ui:overflow-hidden'\n )}\n style={{ gap: `${String(gap)}px` }}\n >\n {children}\n </div>\n\n {/* Standard: Arrows on sides */}\n {showControls &&\n showArrows &&\n arrowPosition === 'sides' &&\n !isHero &&\n !isLightbox && (\n <CarouselNavigation\n onPrev={handlePrev}\n onNext={handleNext}\n canPrev={canScrollPrev}\n canNext={canScrollNext}\n size=\"md\"\n position=\"sides\"\n />\n )}\n\n {/* Hero: single container — pagination centered, arrows right-aligned */}\n {showControls && isHero && (showPagination || showArrows) && (\n <div\n className={clsx(\n 'ui:absolute ui:bottom-4 ui:left-1/2 ui:-translate-x-1/2 ui:w-full ui:z-10 ui:flex ui:items-end',\n heroControlsClassName\n )}\n >\n <div className=\"ui:flex-1\" />\n {showPagination && (\n <CarouselPagination\n total={totalPositions}\n current={currentIndex}\n light\n />\n )}\n <div className=\"ui:flex-1 ui:flex ui:justify-end\">\n {showArrows && (\n <CarouselNavigation\n onPrev={handlePrev}\n onNext={handleNext}\n canPrev={canScrollPrev}\n canNext={canScrollNext}\n size=\"sm\"\n />\n )}\n </div>\n </div>\n )}\n\n {/* Standard: Pagination + Arrows below */}\n {showControls &&\n !isHero &&\n !isLightbox &&\n ((showArrows && arrowPosition === 'bottom-right') || showPagination) ? (\n <div\n className={clsx(\n 'ui:mt-4 ui:flex ui:items-center',\n arrowPosition === 'bottom-right'\n ? 'ui:justify-end ui:gap-4'\n : 'ui:justify-center'\n )}\n >\n {showPagination && (\n <CarouselPagination total={totalPositions} current={currentIndex} />\n )}\n {showArrows && arrowPosition === 'bottom-right' && (\n <CarouselNavigation\n onPrev={handlePrev}\n onNext={handleNext}\n canPrev={canScrollPrev}\n canNext={canScrollNext}\n size=\"sm\"\n />\n )}\n </div>\n ) : null}\n\n {/* Lightbox: Counter top-right, ghost arrows on sides */}\n {showControls && isLightbox && (\n <div className=\"ui:absolute ui:top-4 ui:right-4 ui:z-10\">\n <CarouselCounter current={currentIndex} total={totalPositions} />\n </div>\n )}\n {showControls && isLightbox && showArrows && (\n <CarouselNavigation\n onPrev={handlePrev}\n onNext={handleNext}\n canPrev={canScrollPrev}\n canNext={canScrollNext}\n size=\"md\"\n position=\"sides-inset\"\n iconVariant=\"ghost\"\n />\n )}\n </div>\n )\n}\n\nexport default Carousel\n","import clsx from 'clsx'\n\nimport type { FC, HTMLAttributes } from 'react'\n\nexport interface CarouselItemProps extends HTMLAttributes<HTMLDivElement> {\n /** Whether this is a hero item (full width with snap) */\n isHero?: boolean\n /** Whether this is a lightbox item (full width with snap, same layout as hero) */\n isLightbox?: boolean\n}\n\n/**\n * Wrapper for individual carousel items.\n * For hero and lightbox variants, items take full width and snap to center.\n */\nconst CarouselItem: FC<CarouselItemProps> = ({\n children,\n isHero = false,\n isLightbox = false,\n className,\n ...rest\n}) => {\n return (\n <div\n className={clsx(\n 'ui:flex-shrink-0',\n (isHero || isLightbox) && 'ui:w-full ui:snap-center',\n isLightbox && 'ui:flex ui:items-center ui:justify-center ui:h-full',\n className\n )}\n {...rest}\n >\n {children}\n </div>\n )\n}\n\nexport default CarouselItem\n","import Skeleton from '../Skeleton/Skeleton'\n\nimport type { FC } from 'react'\n\nexport interface CarouselLoadingProps {\n /** Number of skeleton cards to display */\n count?: number\n /** Width of each card in pixels */\n cardWidth?: number\n /** Height of each card in pixels */\n cardHeight?: number\n /** Show skeleton for title */\n showTitle?: boolean\n /** Show skeleton for subtitle/date */\n showSubtitle?: boolean\n /** Apply rounded corners to skeleton */\n rounded?: boolean\n}\n\n/**\n * CarouselLoading - Loading state for carousel with skeleton cards\n *\n * Displays a horizontal scrollable list of skeleton placeholders\n * matching the structure of MovieCard components.\n */\nconst CarouselLoading: FC<CarouselLoadingProps> = ({\n count = 6,\n cardWidth = 150,\n cardHeight = 225,\n showTitle = true,\n showSubtitle = true,\n rounded = true,\n}) => {\n return (\n <div className=\"ui:overflow-x-auto ui:flex ui:gap-4\">\n {Array.from({ length: count }).map((_, i) => (\n <div\n key={i}\n style={{ width: cardWidth, minWidth: cardWidth, maxWidth: cardWidth }}\n >\n <div style={{ width: cardWidth, height: cardHeight }}>\n <Skeleton\n variant=\"rectangle\"\n width=\"ui:w-full\"\n height=\"ui:h-full\"\n rounded={rounded}\n />\n </div>\n {(showTitle || showSubtitle) && (\n <div\n style={{\n marginTop: 8,\n display: 'flex',\n flexDirection: 'column',\n gap: 8,\n }}\n >\n {showTitle && (\n <div style={{ width: cardWidth, height: 16 }}>\n <Skeleton\n variant=\"line\"\n width=\"ui:w-full\"\n height=\"ui:h-full\"\n />\n </div>\n )}\n {showSubtitle && (\n <div style={{ width: cardWidth * 0.75, height: 12 }}>\n <Skeleton\n variant=\"line\"\n width=\"ui:w-full\"\n height=\"ui:h-full\"\n />\n </div>\n )}\n </div>\n )}\n </div>\n ))}\n </div>\n )\n}\n\nexport default CarouselLoading\n","import { createContext, useContext } from 'react'\n\nimport type { TabsVariant } from './Tabs'\n\ninterface TabsContextValue {\n /** Currently active tab value */\n value: string\n /** Change active tab */\n onValueChange: (value: string) => void\n /** Visual variant */\n variant: TabsVariant\n /** Optional prefix for ID generation */\n prefix?: string\n}\n\nexport const TabsContext = createContext<TabsContextValue | undefined>(\n undefined\n)\n\nexport const useTabsContext = () => {\n const context = useContext(TabsContext)\n if (!context) {\n throw new Error('Tabs compound components must be used within <Tabs>')\n }\n return context\n}\n","import { createContext, useContext } from 'react'\n\ninterface TabsListContextValue {\n /** Register a trigger with its value and disabled state */\n registerTrigger: (value: string, disabled?: boolean) => void\n /** Unregister a trigger */\n unregisterTrigger: (value: string) => void\n /** Get all registered trigger values */\n getTriggers: () => string[]\n /** Check if a trigger is disabled */\n isDisabled: (value: string) => boolean\n}\n\nexport const TabsListContext = createContext<TabsListContextValue | undefined>(\n undefined\n)\n\nexport const useTabsListContext = () => {\n const context = useContext(TabsListContext)\n if (!context) {\n throw new Error('TabsTrigger must be used within <Tabs.List>')\n }\n return context\n}\n","import clsx from 'clsx'\nimport { useRef } from 'react'\n\nimport { useTabsContext } from './TabsContext'\nimport { TabsListContext } from './TabsListContext'\n\nimport type { FC, HTMLAttributes } from 'react'\n\nexport type TabsListProps = HTMLAttributes<HTMLDivElement>\n\nconst TabsList: FC<TabsListProps> = ({ className, children, ...rest }) => {\n const { variant } = useTabsContext()\n const triggersRef = useRef<string[]>([])\n const disabledRef = useRef<Set<string>>(new Set())\n\n const registerTrigger = (value: string, disabled?: boolean) => {\n if (!triggersRef.current.includes(value)) {\n triggersRef.current.push(value)\n }\n if (disabled) {\n disabledRef.current.add(value)\n } else {\n disabledRef.current.delete(value)\n }\n }\n\n const unregisterTrigger = (value: string) => {\n triggersRef.current = triggersRef.current.filter((v) => v !== value)\n disabledRef.current.delete(value)\n }\n\n const getTriggers = () => triggersRef.current\n const isDisabled = (value: string) => disabledRef.current.has(value)\n\n return (\n <TabsListContext.Provider\n value={{ registerTrigger, unregisterTrigger, getTriggers, isDisabled }}\n >\n <div\n className={clsx(\n 'ui:flex ui:gap-1',\n variant === 'underline' && 'ui:border-b ui:border-border',\n variant === 'pills' &&\n 'ui:[.media-section:nth-of-type(odd)_&]:bg-white ui:bg-muted ui:p-1 ui:rounded-lg ui:w-fit',\n className\n )}\n role=\"tablist\"\n {...rest}\n >\n {children}\n </div>\n </TabsListContext.Provider>\n )\n}\n\nexport default TabsList\n","import clsx from 'clsx'\n\nimport { useTabsContext } from './TabsContext'\n\nimport type { FC, HTMLAttributes, ReactNode } from 'react'\n\nexport interface TabsPanelProps extends HTMLAttributes<HTMLDivElement> {\n /** Value that identifies this panel (must match a Tabs.Trigger value) */\n value: string\n /** Panel content */\n children: ReactNode\n}\n\n/**\n * Tabpanel for Tabs component.\n * Automatically hidden/shown based on active tab value.\n * Provides proper ARIA attributes for accessibility.\n */\nconst TabsPanel: FC<TabsPanelProps> = ({ value, children, ...rest }) => {\n const { value: activeValue, prefix } = useTabsContext()\n const isActive = value === activeValue\n\n const getTabId = (val: string) =>\n prefix ? `tab-${prefix}-${val}` : `tab-${val}`\n const getTabPanelId = (val: string) =>\n prefix ? `tabpanel-${prefix}-${val}` : `tabpanel-${val}`\n\n return (\n <div\n role=\"tabpanel\"\n id={getTabPanelId(value)}\n aria-labelledby={getTabId(value)}\n hidden={!isActive}\n {...rest}\n className={clsx('ui:mt-4', rest.className)}\n >\n {children}\n </div>\n )\n}\n\nexport default TabsPanel\n","import clsx from 'clsx'\nimport { useEffect } from 'react'\n\nimport { useTabsContext } from './TabsContext'\nimport { useTabsListContext } from './TabsListContext'\n\nimport type { ButtonHTMLAttributes, FC, KeyboardEvent, ReactNode } from 'react'\n\nexport interface TabsTriggerProps\n extends ButtonHTMLAttributes<HTMLButtonElement> {\n /** Value that identifies this tab */\n value: string\n /** Optional icon component */\n icon?: ReactNode\n}\n\nconst TabsTrigger: FC<TabsTriggerProps> = ({\n value,\n icon,\n disabled,\n className,\n children,\n ...rest\n}) => {\n const {\n value: activeValue,\n onValueChange,\n variant,\n prefix,\n } = useTabsContext()\n const { registerTrigger, unregisterTrigger, getTriggers, isDisabled } =\n useTabsListContext()\n\n const isActive = value === activeValue\n\n const getTabId = (val: string) =>\n prefix ? `tab-${prefix}-${val}` : `tab-${val}`\n const getTabPanelId = (val: string) =>\n prefix ? `tabpanel-${prefix}-${val}` : `tabpanel-${val}`\n\n useEffect(() => {\n registerTrigger(value, disabled)\n return () => {\n unregisterTrigger(value)\n }\n }, [value, disabled, registerTrigger, unregisterTrigger])\n\n const handleClick = () => {\n if (!disabled) {\n onValueChange(value)\n }\n }\n\n const findNextEnabledTab = (\n triggers: string[],\n startIndex: number,\n direction: 1 | -1\n ): number => {\n const length = triggers.length\n let index = startIndex\n\n for (let i = 0; i < length; i++) {\n index = (index + direction + length) % length\n if (!isDisabled(triggers[index])) {\n return index\n }\n }\n return startIndex\n }\n\n const handleKeyDown = (event: KeyboardEvent<HTMLButtonElement>) => {\n if (disabled) return\n\n const triggers = getTriggers()\n const currentIndex = triggers.indexOf(value)\n let newIndex = currentIndex\n\n switch (event.key) {\n case 'ArrowLeft':\n event.preventDefault()\n newIndex = findNextEnabledTab(triggers, currentIndex, -1)\n break\n case 'ArrowRight':\n event.preventDefault()\n newIndex = findNextEnabledTab(triggers, currentIndex, 1)\n break\n case 'Home':\n event.preventDefault()\n newIndex = 0\n while (newIndex < triggers.length && isDisabled(triggers[newIndex])) {\n newIndex++\n }\n break\n case 'End':\n event.preventDefault()\n newIndex = triggers.length - 1\n while (newIndex >= 0 && isDisabled(triggers[newIndex])) {\n newIndex--\n }\n break\n default:\n return\n }\n\n const newValue = triggers[newIndex]\n if (newValue && newValue !== value) {\n onValueChange(newValue)\n }\n }\n\n return (\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={isActive ? 'true' : 'false'}\n aria-controls={getTabPanelId(value)}\n id={getTabId(value)}\n tabIndex={isActive ? 0 : -1}\n disabled={disabled}\n className={clsx(\n 'ui:px-4 ui:py-2 ui:font-roboto ui:text-sm ui:font-medium',\n 'ui:flex ui:items-center ui:gap-2',\n 'ui:transition-colors ui:duration-200',\n 'focus-visible:ui:outline-none focus-visible:ui:ring-2 focus-visible:ui:ring-ring focus-visible:ui:ring-offset-2',\n !disabled && 'ui:cursor-pointer',\n variant === 'underline' && [\n 'ui:relative ui:border-b-2 ui:border-transparent ui:-mb-px',\n isActive\n ? 'ui:text-primary ui:border-primary'\n : 'ui:text-foreground hover:ui:text-foreground',\n disabled &&\n 'ui:text-muted-foreground/50 ui:cursor-not-allowed hover:ui:text-muted-foreground/50',\n ],\n variant === 'pills' && [\n 'ui:rounded-md',\n isActive\n ? 'ui:bg-primary ui:shadow-sm'\n : 'ui:text-foreground hover:ui:text-foreground',\n disabled &&\n 'ui:text-muted-foreground/50 ui:cursor-not-allowed hover:ui:text-muted-foreground/50',\n ],\n className\n )}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n {...rest}\n >\n {icon && icon}\n {children}\n </button>\n )\n}\n\nexport default TabsTrigger\n","import clsx from 'clsx'\nimport { useState } from 'react'\n\nimport { TabsContext } from './TabsContext'\nimport TabsList from './TabsList'\nimport TabsPanel from './TabsPanel'\nimport TabsTrigger from './TabsTrigger'\n\nimport type { FC, HTMLAttributes } from 'react'\n\n/** Tabs visual variant */\nexport type TabsVariant = 'underline' | 'pills'\n\nexport interface TabsProps extends HTMLAttributes<HTMLDivElement> {\n /** Default active tab value (uncontrolled) */\n defaultValue?: string\n /** Controlled active tab value */\n value?: string\n /** Callback when tab changes */\n onValueChange?: (value: string) => void\n /** Visual variant */\n variant?: TabsVariant\n /** Optional prefix for ID generation (e.g., \"popular\" generates ids: popular-{value}) */\n prefix?: string\n}\n\n/**\n * Tabs component for navigation between content sections.\n * Implements ARIA tabs pattern for accessibility.\n * Supports underline and pills variants.\n * Uses Compound Component pattern.\n */\nconst Tabs: FC<TabsProps> & {\n List: typeof TabsList\n Trigger: typeof TabsTrigger\n Panel: typeof TabsPanel\n} = ({\n defaultValue = '',\n value,\n onValueChange,\n variant = 'underline',\n prefix,\n className,\n children,\n ...rest\n}) => {\n const [internalValue, setInternalValue] = useState(defaultValue)\n\n const activeValue = value ?? internalValue\n const isControlled = value !== undefined\n\n const handleValueChange = (newValue: string) => {\n if (!isControlled) {\n setInternalValue(newValue)\n }\n onValueChange?.(newValue)\n }\n\n return (\n <TabsContext.Provider\n value={{\n value: activeValue,\n onValueChange: handleValueChange,\n variant,\n prefix,\n }}\n >\n <div className={clsx('ui:w-full', className)} {...rest}>\n {children}\n </div>\n </TabsContext.Provider>\n )\n}\n\nTabs.List = TabsList\nTabs.Trigger = TabsTrigger\nTabs.Panel = TabsPanel\n\nexport default Tabs\n","import clsx from 'clsx'\n\nimport { Avatar } from '../Avatar'\nimport { Typography } from '../Typography'\n\nimport type { AvatarSize } from '../Avatar'\nimport type { FC, HTMLAttributes } from 'react'\n\nexport interface TalentProps extends HTMLAttributes<HTMLDivElement> {\n /** Full name of the talent (actor, director, writer, etc.) */\n name?: string\n /** Role or job title (e.g., \"Director\", \"Screenplay\", \"Character Name\") */\n role?: string\n /** Optional profile image URL */\n imageSrc?: string\n /** Layout variant - vertical for crew/cast cards, horizontal for lists */\n variant?: 'vertical' | 'horizontal'\n /** Avatar size */\n size?: AvatarSize\n}\n\nconst Talent: FC<TalentProps> = ({\n name,\n role,\n imageSrc,\n variant = 'vertical',\n size = 'lg',\n className,\n ...rest\n}) => {\n return (\n <div\n className={clsx(\n 'ui:flex ui:items-center',\n {\n 'ui:flex-col ui:text-center ui:gap-3': variant === 'vertical',\n 'ui:flex-row ui:gap-4': variant === 'horizontal',\n },\n className\n )}\n data-testid=\"talent\"\n {...rest}\n >\n <Avatar\n testId=\"avatar\"\n src={imageSrc}\n alt={name ?? 'Unknown'}\n size={size}\n />\n <div\n className={clsx({ 'ui:flex ui:flex-col': variant === 'horizontal' })}\n >\n <Typography\n variant=\"body\"\n className=\"ui:font-semibold ui:text-foreground\"\n >\n {name ?? 'Unknown'}\n </Typography>\n <Typography\n variant=\"caption\"\n className=\"ui:text-muted-foreground ui:[.media-section:nth-of-type(odd)_&]:text-badge-foreground\"\n >\n {role ?? 'N/A'}\n </Typography>\n </div>\n </div>\n )\n}\n\nexport default Talent\n","import clsx from 'clsx'\n\nimport type { FC } from 'react'\n\nexport interface SpinnerProps {\n className?: string\n}\n\nconst Spinner: FC<SpinnerProps> = ({ className }) => {\n return (\n <div\n role=\"status\"\n aria-label=\"Loading\"\n className={clsx(\n 'ui:size-12 ui:rounded-full ui:border-4 ui:border-white/20 ui:border-t-white ui:animate-spin',\n className\n )}\n />\n )\n}\n\nexport default Spinner\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vite-mf-monorepo/ui",
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"description": "Design system components for vite-mf-monorepo",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "restricted"
|
|
8
|
+
},
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"module": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"import": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"default": "./dist/index.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"./*": {
|
|
20
|
+
"import": {
|
|
21
|
+
"types": "./dist/*/index.d.ts",
|
|
22
|
+
"default": "./dist/*/index.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"./styles.css": "./dist/index.css"
|
|
26
|
+
},
|
|
27
|
+
"sideEffects": [
|
|
28
|
+
"*.css"
|
|
29
|
+
],
|
|
30
|
+
"files": [
|
|
31
|
+
"dist"
|
|
32
|
+
],
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build:css": "tailwindcss -i ./src/styles.css -o ./dist/styles.css",
|
|
35
|
+
"build:js": "tsup",
|
|
36
|
+
"build": "pnpm build:css && pnpm build:js",
|
|
37
|
+
"dev": "tsup --watch",
|
|
38
|
+
"test": "vitest run",
|
|
39
|
+
"test:watch": "vitest",
|
|
40
|
+
"lint": "eslint . --max-warnings 0",
|
|
41
|
+
"typecheck": "tsc --noEmit",
|
|
42
|
+
"local-release:patch": "pnpm build && ./publish-local.sh patch",
|
|
43
|
+
"local-release:minor": "pnpm build && ./publish-local.sh minor",
|
|
44
|
+
"local-release:major": "pnpm build && ./publish-local.sh major",
|
|
45
|
+
"release:patch": "pnpm build && ./publish.sh patch",
|
|
46
|
+
"release:minor": "pnpm build && ./publish.sh minor",
|
|
47
|
+
"release:major": "pnpm build && ./publish.sh major"
|
|
48
|
+
},
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"react": "catalog:",
|
|
51
|
+
"react-dom": "catalog:",
|
|
52
|
+
"react-router-dom": "catalog:"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@tailwindcss/postcss": "catalog:",
|
|
56
|
+
"@testing-library/jest-dom": "catalog:",
|
|
57
|
+
"@testing-library/react": "catalog:",
|
|
58
|
+
"@testing-library/user-event": "catalog:",
|
|
59
|
+
"@types/react": "catalog:",
|
|
60
|
+
"@types/react-dom": "catalog:",
|
|
61
|
+
"@vitejs/plugin-react": "catalog:",
|
|
62
|
+
"@vitest/coverage-v8": "catalog:",
|
|
63
|
+
"autoprefixer": "catalog:",
|
|
64
|
+
"conventional-changelog": "catalog:",
|
|
65
|
+
"jsdom": "catalog:",
|
|
66
|
+
"postcss": "catalog:",
|
|
67
|
+
"react-router-dom": "catalog:",
|
|
68
|
+
"tailwindcss": "catalog:",
|
|
69
|
+
"tsup": "catalog:",
|
|
70
|
+
"typescript": "catalog:",
|
|
71
|
+
"vitest": "catalog:"
|
|
72
|
+
},
|
|
73
|
+
"dependencies": {
|
|
74
|
+
"@heroicons/react": "^2.2.0",
|
|
75
|
+
"@vite-mf-monorepo/shared": "workspace:*",
|
|
76
|
+
"clsx": "catalog:"
|
|
77
|
+
}
|
|
78
|
+
}
|