@vite-mf-monorepo/ui 0.2.0 → 0.3.0
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/chunk-JPJYJLAP.js +38 -0
- package/dist/chunk-JPJYJLAP.js.map +1 -0
- package/dist/index.js +27 -55
- package/dist/index.js.map +1 -1
- package/dist/next/index.d.ts +9 -1
- package/dist/next/index.js +36 -1
- package/dist/next/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import clsx from 'clsx';
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
// src/Skeleton/Skeleton.tsx
|
|
5
|
+
function Skeleton({
|
|
6
|
+
variant = "rectangle",
|
|
7
|
+
width,
|
|
8
|
+
height,
|
|
9
|
+
aspectRatio,
|
|
10
|
+
rounded = true,
|
|
11
|
+
className,
|
|
12
|
+
...rest
|
|
13
|
+
}) {
|
|
14
|
+
return /* @__PURE__ */ jsx(
|
|
15
|
+
"div",
|
|
16
|
+
{
|
|
17
|
+
className: clsx(
|
|
18
|
+
"ui:relative ui:overflow-hidden ui:bg-muted",
|
|
19
|
+
"ui-skeleton-shimmer",
|
|
20
|
+
{
|
|
21
|
+
"ui:rounded-lg": variant === "rectangle" && rounded,
|
|
22
|
+
"ui:rounded-full": variant === "circle",
|
|
23
|
+
"ui:rounded": variant === "line" && rounded
|
|
24
|
+
},
|
|
25
|
+
width,
|
|
26
|
+
height,
|
|
27
|
+
className
|
|
28
|
+
),
|
|
29
|
+
style: aspectRatio ? { aspectRatio } : void 0,
|
|
30
|
+
...rest
|
|
31
|
+
}
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
var Skeleton_default = Skeleton;
|
|
35
|
+
|
|
36
|
+
export { Skeleton_default };
|
|
37
|
+
//# sourceMappingURL=chunk-JPJYJLAP.js.map
|
|
38
|
+
//# sourceMappingURL=chunk-JPJYJLAP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/Skeleton/Skeleton.tsx"],"names":[],"mappings":";;;;AAsBA,SAAS,QAAA,CAAS;AAAA,EAChB,OAAA,GAAU,WAAA;AAAA,EACV,KAAA;AAAA,EACA,MAAA;AAAA,EACA,WAAA;AAAA,EACA,OAAA,GAAU,IAAA;AAAA,EACV,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAA4B;AAC1B,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,IAAA;AAAA,QACT,4CAAA;AAAA,QACA,qBAAA;AAAA,QACA;AAAA,UACE,eAAA,EAAiB,YAAY,WAAA,IAAe,OAAA;AAAA,UAC5C,mBAAmB,OAAA,KAAY,QAAA;AAAA,UAC/B,YAAA,EAAc,YAAY,MAAA,IAAU;AAAA,SACtC;AAAA,QACA,KAAA;AAAA,QACA,MAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,KAAA,EAAO,WAAA,GAAc,EAAE,WAAA,EAAY,GAAI,MAAA;AAAA,MACtC,GAAG;AAAA;AAAA,GACN;AAEJ;AAEA,IAAO,gBAAA,GAAQ","file":"chunk-JPJYJLAP.js","sourcesContent":["import clsx from 'clsx'\n\nimport type { ComponentProps } 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 */\nfunction Skeleton({\n variant = 'rectangle',\n width,\n height,\n aspectRatio,\n rounded = true,\n className,\n ...rest\n}: Readonly<SkeletonProps>) {\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"]}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import './chunk-Y5GP5OWN.js';
|
|
2
|
+
import { Skeleton_default } from './chunk-JPJYJLAP.js';
|
|
3
|
+
export { Skeleton_default as Skeleton } from './chunk-JPJYJLAP.js';
|
|
2
4
|
export { MovieCard_default as MovieCard } from './chunk-5NW3IDX2.js';
|
|
3
5
|
import { Button_default } from './chunk-WYIIOTWJ.js';
|
|
4
6
|
export { Button_default as Button } from './chunk-WYIIOTWJ.js';
|
|
@@ -8,7 +10,7 @@ import './chunk-FDLKS7BI.js';
|
|
|
8
10
|
export { Card_default as Card } from './chunk-JI3OVXCK.js';
|
|
9
11
|
import { Icon_default } from './chunk-JHRISQQJ.js';
|
|
10
12
|
export { Icon_default as Icon } from './chunk-JHRISQQJ.js';
|
|
11
|
-
import
|
|
13
|
+
import clsx8 from 'clsx';
|
|
12
14
|
import { createContext, useState, useRef, useEffect, useCallback, useLayoutEffect, useContext } from 'react';
|
|
13
15
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
14
16
|
import { getOptimizedImageUrl } from '@vite-mf-monorepo/shared';
|
|
@@ -42,7 +44,7 @@ function Avatar({
|
|
|
42
44
|
return /* @__PURE__ */ jsxs(
|
|
43
45
|
"div",
|
|
44
46
|
{
|
|
45
|
-
className:
|
|
47
|
+
className: clsx8(
|
|
46
48
|
"ui:relative ui:inline-flex ui:items-center ui:justify-center ui:overflow-hidden ui:rounded-full",
|
|
47
49
|
"ui:bg-muted ui:text-muted-foreground",
|
|
48
50
|
container,
|
|
@@ -60,7 +62,7 @@ function Avatar({
|
|
|
60
62
|
...rest
|
|
61
63
|
}
|
|
62
64
|
),
|
|
63
|
-
showInitials && /* @__PURE__ */ jsx("span", { className:
|
|
65
|
+
showInitials && /* @__PURE__ */ jsx("span", { className: clsx8("ui:font-medium ui:uppercase", text), children: initials.slice(0, 2) }),
|
|
64
66
|
showFallback && /* @__PURE__ */ jsx(Icon_default, { name: "User", size: icon })
|
|
65
67
|
]
|
|
66
68
|
}
|
|
@@ -84,7 +86,7 @@ function Badge({
|
|
|
84
86
|
return /* @__PURE__ */ jsxs(
|
|
85
87
|
"span",
|
|
86
88
|
{
|
|
87
|
-
className:
|
|
89
|
+
className: clsx8(
|
|
88
90
|
"ui:inline-flex ui:items-center ui:gap-1 ui:rounded-full ui:font-medium",
|
|
89
91
|
padding,
|
|
90
92
|
text,
|
|
@@ -125,7 +127,7 @@ function IconButton({
|
|
|
125
127
|
return /* @__PURE__ */ jsx(
|
|
126
128
|
"button",
|
|
127
129
|
{
|
|
128
|
-
className:
|
|
130
|
+
className: clsx8(
|
|
129
131
|
"ui:inline-flex ui:items-center ui:justify-center ui:cursor-pointer ui:rounded-full ui:transition-colors",
|
|
130
132
|
"ui:focus:outline-none ui:focus:ring-2 ui:focus:ring-ring ui:focus:ring-offset-2",
|
|
131
133
|
"ui:disabled:pointer-events-none ui:disabled:opacity-50",
|
|
@@ -145,36 +147,6 @@ function IconButton({
|
|
|
145
147
|
);
|
|
146
148
|
}
|
|
147
149
|
var IconButton_default = IconButton;
|
|
148
|
-
function Skeleton({
|
|
149
|
-
variant = "rectangle",
|
|
150
|
-
width,
|
|
151
|
-
height,
|
|
152
|
-
aspectRatio,
|
|
153
|
-
rounded = true,
|
|
154
|
-
className,
|
|
155
|
-
...rest
|
|
156
|
-
}) {
|
|
157
|
-
return /* @__PURE__ */ jsx(
|
|
158
|
-
"div",
|
|
159
|
-
{
|
|
160
|
-
className: clsx9(
|
|
161
|
-
"ui:relative ui:overflow-hidden ui:bg-muted",
|
|
162
|
-
"ui-skeleton-shimmer",
|
|
163
|
-
{
|
|
164
|
-
"ui:rounded-lg": variant === "rectangle" && rounded,
|
|
165
|
-
"ui:rounded-full": variant === "circle",
|
|
166
|
-
"ui:rounded": variant === "line" && rounded
|
|
167
|
-
},
|
|
168
|
-
width,
|
|
169
|
-
height,
|
|
170
|
-
className
|
|
171
|
-
),
|
|
172
|
-
style: aspectRatio ? { aspectRatio } : void 0,
|
|
173
|
-
...rest
|
|
174
|
-
}
|
|
175
|
-
);
|
|
176
|
-
}
|
|
177
|
-
var Skeleton_default = Skeleton;
|
|
178
150
|
function HeroImage({ backdropPath, title }) {
|
|
179
151
|
const [loading, setLoading] = useState(true);
|
|
180
152
|
const backdropPathMobile = backdropPath ? getOptimizedImageUrl(backdropPath, "w300", 60) : void 0;
|
|
@@ -251,7 +223,7 @@ function Modal({
|
|
|
251
223
|
"aria-modal": "true",
|
|
252
224
|
onClick: handleClick,
|
|
253
225
|
onClose: handleClose,
|
|
254
|
-
className:
|
|
226
|
+
className: clsx8(
|
|
255
227
|
"ui:backdrop:bg-black/80",
|
|
256
228
|
"ui:bg-transparent ui:border-0 ui:p-0",
|
|
257
229
|
"ui:max-w-none ui:max-h-none ui:w-full ui:h-full",
|
|
@@ -274,7 +246,7 @@ function TrailerCard({
|
|
|
274
246
|
/* @__PURE__ */ jsxs(
|
|
275
247
|
"button",
|
|
276
248
|
{
|
|
277
|
-
className:
|
|
249
|
+
className: clsx8(
|
|
278
250
|
"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",
|
|
279
251
|
"ui:transition-transform ui:duration-200 hover:ui:scale-[1.02]",
|
|
280
252
|
className
|
|
@@ -347,7 +319,7 @@ function CarouselCounter({
|
|
|
347
319
|
return /* @__PURE__ */ jsxs(
|
|
348
320
|
"div",
|
|
349
321
|
{
|
|
350
|
-
className:
|
|
322
|
+
className: clsx8(
|
|
351
323
|
"ui:bg-black/50 ui:rounded-full ui:px-3 ui:py-1",
|
|
352
324
|
"ui:text-white/90 ui:text-sm ui:font-medium ui:tabular-nums",
|
|
353
325
|
className
|
|
@@ -437,7 +409,7 @@ function CarouselNavigation({
|
|
|
437
409
|
) })
|
|
438
410
|
] });
|
|
439
411
|
}
|
|
440
|
-
return /* @__PURE__ */ jsxs("div", { className:
|
|
412
|
+
return /* @__PURE__ */ jsxs("div", { className: clsx8("ui:flex ui:gap-2", className), children: [
|
|
441
413
|
/* @__PURE__ */ jsx(
|
|
442
414
|
IconButton_default,
|
|
443
415
|
{
|
|
@@ -470,13 +442,13 @@ function CarouselPagination({
|
|
|
470
442
|
className
|
|
471
443
|
}) {
|
|
472
444
|
if (total === 0) return null;
|
|
473
|
-
return /* @__PURE__ */ jsx("div", { className:
|
|
445
|
+
return /* @__PURE__ */ jsx("div", { className: clsx8("ui:flex ui:items-center ui:gap-2", className), children: Array.from({ length: total }).map((_, index) => /* @__PURE__ */ jsx(
|
|
474
446
|
"div",
|
|
475
447
|
{
|
|
476
448
|
"aria-hidden": "true",
|
|
477
|
-
className:
|
|
449
|
+
className: clsx8(
|
|
478
450
|
"ui:rounded-full ui:transition-all ui:duration-300",
|
|
479
|
-
index === current ?
|
|
451
|
+
index === current ? clsx8("ui:h-2 ui:w-6", light ? "ui:bg-white" : "ui:bg-primary") : clsx8(
|
|
480
452
|
"ui:h-2 ui:w-2",
|
|
481
453
|
light ? "ui:bg-white/50 hover:ui:bg-white/70" : "ui:bg-gray-400 hover:ui:bg-gray-500"
|
|
482
454
|
)
|
|
@@ -643,12 +615,12 @@ function Carousel({
|
|
|
643
615
|
const canScrollPrev = currentIndex > 0;
|
|
644
616
|
const canScrollNext = currentIndex < totalPositions - 1;
|
|
645
617
|
const showControls = totalPositions > 1;
|
|
646
|
-
return /* @__PURE__ */ jsxs("div", { className:
|
|
618
|
+
return /* @__PURE__ */ jsxs("div", { className: clsx8("ui:relative", isLightbox && "ui:h-full", className), children: [
|
|
647
619
|
/* @__PURE__ */ jsx(
|
|
648
620
|
"div",
|
|
649
621
|
{
|
|
650
622
|
ref: scrollRef,
|
|
651
|
-
className:
|
|
623
|
+
className: clsx8(
|
|
652
624
|
"ui:flex ui:overflow-x-auto ui:scroll-smooth ui:scrollbar-none",
|
|
653
625
|
isFullWidth && "ui:snap-x ui:snap-mandatory",
|
|
654
626
|
isLightbox && "ui:h-full",
|
|
@@ -672,7 +644,7 @@ function Carousel({
|
|
|
672
644
|
showControls && isHero && (showPagination || showArrows) && /* @__PURE__ */ jsxs(
|
|
673
645
|
"div",
|
|
674
646
|
{
|
|
675
|
-
className:
|
|
647
|
+
className: clsx8(
|
|
676
648
|
"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",
|
|
677
649
|
heroControlsClassName
|
|
678
650
|
),
|
|
@@ -702,7 +674,7 @@ function Carousel({
|
|
|
702
674
|
showControls && !isHero && !isLightbox && (showArrows && arrowPosition === "bottom-right" || showPagination) ? /* @__PURE__ */ jsxs(
|
|
703
675
|
"div",
|
|
704
676
|
{
|
|
705
|
-
className:
|
|
677
|
+
className: clsx8(
|
|
706
678
|
"ui:mt-4 ui:flex ui:items-center",
|
|
707
679
|
arrowPosition === "bottom-right" ? "ui:justify-end ui:gap-4" : "ui:justify-center"
|
|
708
680
|
),
|
|
@@ -747,7 +719,7 @@ function CarouselItem({
|
|
|
747
719
|
return /* @__PURE__ */ jsx(
|
|
748
720
|
"div",
|
|
749
721
|
{
|
|
750
|
-
className:
|
|
722
|
+
className: clsx8(
|
|
751
723
|
"ui:flex-shrink-0",
|
|
752
724
|
(isHero || isLightbox) && "ui:w-full ui:snap-center",
|
|
753
725
|
isLightbox && "ui:flex ui:items-center ui:justify-center ui:h-full",
|
|
@@ -863,7 +835,7 @@ function TabsList({ className, children, ...rest }) {
|
|
|
863
835
|
children: /* @__PURE__ */ jsx(
|
|
864
836
|
"div",
|
|
865
837
|
{
|
|
866
|
-
className:
|
|
838
|
+
className: clsx8(
|
|
867
839
|
"ui:flex ui:gap-1",
|
|
868
840
|
variant === "underline" && "ui:border-b ui:border-border",
|
|
869
841
|
variant === "pills" && "ui:[.media-section:nth-of-type(odd)_&]:bg-white ui:bg-muted ui:p-1 ui:rounded-lg ui:w-fit",
|
|
@@ -891,7 +863,7 @@ function TabsPanel({ value, children, ...rest }) {
|
|
|
891
863
|
"aria-labelledby": getTabId(value),
|
|
892
864
|
hidden: !isActive,
|
|
893
865
|
...rest,
|
|
894
|
-
className:
|
|
866
|
+
className: clsx8("ui:mt-4", rest.className),
|
|
895
867
|
children
|
|
896
868
|
}
|
|
897
869
|
);
|
|
@@ -983,7 +955,7 @@ function TabsTrigger({
|
|
|
983
955
|
id: getTabId(value),
|
|
984
956
|
tabIndex: isActive ? 0 : -1,
|
|
985
957
|
disabled,
|
|
986
|
-
className:
|
|
958
|
+
className: clsx8(
|
|
987
959
|
"ui:px-4 ui:py-2 ui:font-roboto ui:text-sm ui:font-medium",
|
|
988
960
|
"ui:flex ui:items-center ui:gap-2",
|
|
989
961
|
"ui:transition-colors ui:duration-200",
|
|
@@ -1040,7 +1012,7 @@ function Tabs({
|
|
|
1040
1012
|
variant,
|
|
1041
1013
|
prefix
|
|
1042
1014
|
},
|
|
1043
|
-
children: /* @__PURE__ */ jsx("div", { className:
|
|
1015
|
+
children: /* @__PURE__ */ jsx("div", { className: clsx8("ui:w-full", className), ...rest, children })
|
|
1044
1016
|
}
|
|
1045
1017
|
);
|
|
1046
1018
|
}
|
|
@@ -1060,7 +1032,7 @@ function Talent({
|
|
|
1060
1032
|
return /* @__PURE__ */ jsxs(
|
|
1061
1033
|
"div",
|
|
1062
1034
|
{
|
|
1063
|
-
className:
|
|
1035
|
+
className: clsx8(
|
|
1064
1036
|
"ui:flex ui:items-center",
|
|
1065
1037
|
{
|
|
1066
1038
|
"ui:flex-col ui:text-center ui:gap-3": variant === "vertical",
|
|
@@ -1083,7 +1055,7 @@ function Talent({
|
|
|
1083
1055
|
/* @__PURE__ */ jsxs(
|
|
1084
1056
|
"div",
|
|
1085
1057
|
{
|
|
1086
|
-
className:
|
|
1058
|
+
className: clsx8({ "ui:flex ui:flex-col": variant === "horizontal" }),
|
|
1087
1059
|
children: [
|
|
1088
1060
|
/* @__PURE__ */ jsx(
|
|
1089
1061
|
Typography_default,
|
|
@@ -1115,7 +1087,7 @@ function Spinner({ className }) {
|
|
|
1115
1087
|
{
|
|
1116
1088
|
role: "status",
|
|
1117
1089
|
"aria-label": "Loading",
|
|
1118
|
-
className:
|
|
1090
|
+
className: clsx8(
|
|
1119
1091
|
"ui:size-12 ui:rounded-full ui:border-4 ui:border-white/20 ui:border-t-white ui:animate-spin",
|
|
1120
1092
|
className
|
|
1121
1093
|
)
|
|
@@ -1124,6 +1096,6 @@ function Spinner({ className }) {
|
|
|
1124
1096
|
}
|
|
1125
1097
|
var Spinner_default = Spinner;
|
|
1126
1098
|
|
|
1127
|
-
export { Avatar_default as Avatar, Badge_default as Badge, Carousel_default as Carousel, CarouselCounter_default as CarouselCounter, CarouselItem_default as CarouselItem, CarouselLoading_default as CarouselLoading, CarouselNavigation_default as CarouselNavigation, CarouselPagination_default as CarouselPagination, HeroImage_default as HeroImage, IconButton_default as IconButton, Modal_default as Modal,
|
|
1099
|
+
export { Avatar_default as Avatar, Badge_default as Badge, Carousel_default as Carousel, CarouselCounter_default as CarouselCounter, CarouselItem_default as CarouselItem, CarouselLoading_default as CarouselLoading, CarouselNavigation_default as CarouselNavigation, CarouselPagination_default as CarouselPagination, HeroImage_default as HeroImage, IconButton_default as IconButton, Modal_default as Modal, Spinner_default as Spinner, Tabs_default as Tabs, Talent_default as Talent, TrailerCard_default as TrailerCard };
|
|
1128
1100
|
//# sourceMappingURL=index.js.map
|
|
1129
1101
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/Avatar/Avatar.tsx","../src/Badge/Badge.tsx","../src/IconButton/IconButton.tsx","../src/Skeleton/Skeleton.tsx","../src/HeroImage/HeroImage.tsx","../src/Modal/Modal.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","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 } 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\nfunction Avatar({\n className,\n src,\n alt,\n size = 'md',\n initials,\n testId,\n ...rest\n}: Readonly<AvatarProps>) {\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 { 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\nfunction Badge({\n children,\n variant = 'default',\n size = 'md',\n icon,\n textClassName,\n className,\n}: Readonly<BadgeProps>) {\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 } 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\nfunction IconButton({\n className,\n icon,\n variant = 'ghost',\n size = 'md',\n disabled,\n ...rest\n}: Readonly<IconButtonProps>) {\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 clsx from 'clsx'\n\nimport type { ComponentProps } 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 */\nfunction Skeleton({\n variant = 'rectangle',\n width,\n height,\n aspectRatio,\n rounded = true,\n className,\n ...rest\n}: Readonly<SkeletonProps>) {\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\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 */\nfunction HeroImage({ backdropPath, title }: Readonly<HeroImageProps>) {\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 { 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\nfunction Modal({\n isOpen,\n onClose,\n children,\n 'aria-label': ariaLabel,\n className,\n onOverlayClick,\n}: Readonly<ModalProps>) {\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'\nimport { useState } from 'react'\n\nimport { Button } from '../Button'\nimport { Modal } from '../Modal'\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\nfunction TrailerCard({\n videoKey,\n title,\n type = 'Trailer',\n className,\n}: Readonly<TrailerCardProps>) {\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\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 */\nfunction CarouselCounter({\n current,\n total,\n className,\n}: Readonly<CarouselCounterProps>) {\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\nexport interface CarouselErrorProps {\n message?: string\n}\n\nfunction CarouselError({\n message = 'Failed to load data',\n}: Readonly<CarouselErrorProps>) {\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\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 */\nfunction CarouselNavigation({\n onPrev,\n onNext,\n canPrev,\n canNext,\n size = 'sm',\n position = 'inline',\n iconVariant = 'secondary',\n className,\n}: Readonly<CarouselNavigationProps>) {\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\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 */\nfunction CarouselPagination({\n total,\n current,\n light = false,\n className,\n}: Readonly<CarouselPaginationProps>) {\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 { 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 */\nfunction Carousel({\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}: Readonly<CarouselProps>) {\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 { 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 */\nfunction CarouselItem({\n children,\n isHero = false,\n isLightbox = false,\n className,\n ...rest\n}: Readonly<CarouselItemProps>) {\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\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 */\nfunction CarouselLoading({\n count = 6,\n cardWidth = 150,\n cardHeight = 225,\n showTitle = true,\n showSubtitle = true,\n rounded = true,\n}: Readonly<CarouselLoadingProps>) {\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 { HTMLAttributes } from 'react'\n\nexport type TabsListProps = HTMLAttributes<HTMLDivElement>\n\nfunction TabsList({ className, children, ...rest }: Readonly<TabsListProps>) {\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 { 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 */\nfunction TabsPanel({ value, children, ...rest }: Readonly<TabsPanelProps>) {\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, 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\nfunction TabsTrigger({\n value,\n icon,\n disabled,\n className,\n children,\n ...rest\n}: Readonly<TabsTriggerProps>) {\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 { 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 */\nfunction Tabs({\n defaultValue = '',\n value,\n onValueChange,\n variant = 'underline',\n prefix,\n className,\n children,\n ...rest\n}: Readonly<TabsProps>) {\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 { 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\nfunction Talent({\n name,\n role,\n imageSrc,\n variant = 'vertical',\n size = 'lg',\n className,\n ...rest\n}: Readonly<TalentProps>) {\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\nexport interface SpinnerProps {\n className?: string\n}\n\nfunction Spinner({ className }: Readonly<SpinnerProps>) {\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"]}
|
|
1
|
+
{"version":3,"sources":["../src/Avatar/Avatar.tsx","../src/Badge/Badge.tsx","../src/IconButton/IconButton.tsx","../src/HeroImage/HeroImage.tsx","../src/Modal/Modal.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","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 } 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\nfunction Avatar({\n className,\n src,\n alt,\n size = 'md',\n initials,\n testId,\n ...rest\n}: Readonly<AvatarProps>) {\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 { 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\nfunction Badge({\n children,\n variant = 'default',\n size = 'md',\n icon,\n textClassName,\n className,\n}: Readonly<BadgeProps>) {\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 } 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\nfunction IconButton({\n className,\n icon,\n variant = 'ghost',\n size = 'md',\n disabled,\n ...rest\n}: Readonly<IconButtonProps>) {\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 { getOptimizedImageUrl } from '@vite-mf-monorepo/shared'\nimport { useState } from 'react'\n\nimport { Skeleton } from '../Skeleton'\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 */\nfunction HeroImage({ backdropPath, title }: Readonly<HeroImageProps>) {\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 { 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\nfunction Modal({\n isOpen,\n onClose,\n children,\n 'aria-label': ariaLabel,\n className,\n onOverlayClick,\n}: Readonly<ModalProps>) {\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'\nimport { useState } from 'react'\n\nimport { Button } from '../Button'\nimport { Modal } from '../Modal'\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\nfunction TrailerCard({\n videoKey,\n title,\n type = 'Trailer',\n className,\n}: Readonly<TrailerCardProps>) {\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\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 */\nfunction CarouselCounter({\n current,\n total,\n className,\n}: Readonly<CarouselCounterProps>) {\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\nexport interface CarouselErrorProps {\n message?: string\n}\n\nfunction CarouselError({\n message = 'Failed to load data',\n}: Readonly<CarouselErrorProps>) {\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\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 */\nfunction CarouselNavigation({\n onPrev,\n onNext,\n canPrev,\n canNext,\n size = 'sm',\n position = 'inline',\n iconVariant = 'secondary',\n className,\n}: Readonly<CarouselNavigationProps>) {\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\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 */\nfunction CarouselPagination({\n total,\n current,\n light = false,\n className,\n}: Readonly<CarouselPaginationProps>) {\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 { 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 */\nfunction Carousel({\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}: Readonly<CarouselProps>) {\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 { 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 */\nfunction CarouselItem({\n children,\n isHero = false,\n isLightbox = false,\n className,\n ...rest\n}: Readonly<CarouselItemProps>) {\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\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 */\nfunction CarouselLoading({\n count = 6,\n cardWidth = 150,\n cardHeight = 225,\n showTitle = true,\n showSubtitle = true,\n rounded = true,\n}: Readonly<CarouselLoadingProps>) {\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 { HTMLAttributes } from 'react'\n\nexport type TabsListProps = HTMLAttributes<HTMLDivElement>\n\nfunction TabsList({ className, children, ...rest }: Readonly<TabsListProps>) {\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 { 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 */\nfunction TabsPanel({ value, children, ...rest }: Readonly<TabsPanelProps>) {\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, 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\nfunction TabsTrigger({\n value,\n icon,\n disabled,\n className,\n children,\n ...rest\n}: Readonly<TabsTriggerProps>) {\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 { 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 */\nfunction Tabs({\n defaultValue = '',\n value,\n onValueChange,\n variant = 'underline',\n prefix,\n className,\n children,\n ...rest\n}: Readonly<TabsProps>) {\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 { 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\nfunction Talent({\n name,\n role,\n imageSrc,\n variant = 'vertical',\n size = 'lg',\n className,\n ...rest\n}: Readonly<TalentProps>) {\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\nexport interface SpinnerProps {\n className?: string\n}\n\nfunction Spinner({ className }: Readonly<SpinnerProps>) {\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/dist/next/index.d.ts
CHANGED
|
@@ -26,6 +26,14 @@ type NextButtonProps = NextButtonAsButton | NextButtonAsLink;
|
|
|
26
26
|
|
|
27
27
|
declare function Button(props: Readonly<NextButtonProps>): react_jsx_runtime.JSX.Element;
|
|
28
28
|
|
|
29
|
+
interface NextHeroImageProps {
|
|
30
|
+
/** Backdrop path from TMDB API (e.g. "/abc123.jpg") */
|
|
31
|
+
backdropPath?: string | null;
|
|
32
|
+
/** Alt text for the image */
|
|
33
|
+
title?: string | null;
|
|
34
|
+
}
|
|
35
|
+
declare function HeroImage({ backdropPath, title }: Readonly<NextHeroImageProps>): react_jsx_runtime.JSX.Element;
|
|
36
|
+
|
|
29
37
|
interface NextMovieCardAsLink extends MovieCardBaseProps {
|
|
30
38
|
/** Render as Next.js Link */
|
|
31
39
|
as: 'link';
|
|
@@ -37,4 +45,4 @@ type NextMovieCardProps = MovieCardAsCard | NextMovieCardAsLink | MovieCardAsBut
|
|
|
37
45
|
|
|
38
46
|
declare function MovieCard({ id, title, posterUrl, voteAverage, year, className, imageLoading, as, ...rest }: Readonly<NextMovieCardProps>): react_jsx_runtime.JSX.Element;
|
|
39
47
|
|
|
40
|
-
export { Button, MovieCard, MovieCardAsButton, MovieCardAsCard, MovieCardBaseProps, type NextButtonAsButton, type NextButtonAsLink, type NextButtonProps, type NextMovieCardAsLink, type NextMovieCardProps };
|
|
48
|
+
export { Button, HeroImage, MovieCard, MovieCardAsButton, MovieCardAsCard, MovieCardBaseProps, type NextButtonAsButton, type NextButtonAsLink, type NextButtonProps, type NextHeroImageProps, type NextMovieCardAsLink, type NextMovieCardProps };
|
package/dist/next/index.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import { Skeleton_default } from '../chunk-JPJYJLAP.js';
|
|
1
2
|
import { getMovieCardLinkClasses, MovieCardContent } from '../chunk-JDBRVX5O.js';
|
|
2
3
|
import { getButtonClasses, iconSizeMap, getButtonDisabledClasses } from '../chunk-FDLKS7BI.js';
|
|
3
4
|
import '../chunk-JI3OVXCK.js';
|
|
4
5
|
import { Icon_default } from '../chunk-JHRISQQJ.js';
|
|
5
6
|
import Link from 'next/link';
|
|
6
7
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
8
|
+
import Image from 'next/image';
|
|
9
|
+
import { useState } from 'react';
|
|
7
10
|
|
|
8
11
|
function Button(props) {
|
|
9
12
|
const {
|
|
@@ -45,6 +48,38 @@ function Button(props) {
|
|
|
45
48
|
return /* @__PURE__ */ jsx("button", { className: getButtonDisabledClasses(classes), ...buttonProps, children: content });
|
|
46
49
|
}
|
|
47
50
|
var Button_default = Button;
|
|
51
|
+
function HeroImage({ backdropPath, title }) {
|
|
52
|
+
const [loading, setLoading] = useState(true);
|
|
53
|
+
const src = backdropPath ? `https://image.tmdb.org/t/p/original${backdropPath}` : void 0;
|
|
54
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
55
|
+
loading && /* @__PURE__ */ jsx(
|
|
56
|
+
Skeleton_default,
|
|
57
|
+
{
|
|
58
|
+
"data-testid": "hero-image-skeleton",
|
|
59
|
+
variant: "rectangle",
|
|
60
|
+
width: "ui:relative ui:w-full ui:h-full ui:hero-height ui:z-0",
|
|
61
|
+
aspectRatio: "21/9",
|
|
62
|
+
rounded: false
|
|
63
|
+
}
|
|
64
|
+
),
|
|
65
|
+
src && /* @__PURE__ */ jsx(
|
|
66
|
+
Image,
|
|
67
|
+
{
|
|
68
|
+
src,
|
|
69
|
+
alt: title ?? "Unknown",
|
|
70
|
+
fill: true,
|
|
71
|
+
priority: true,
|
|
72
|
+
sizes: "100vw",
|
|
73
|
+
className: "ui:relative ui:h-full ui:w-full ui:object-cover ui:object-center ui:z-0",
|
|
74
|
+
onLoad: () => {
|
|
75
|
+
setLoading(false);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
),
|
|
79
|
+
/* @__PURE__ */ jsx("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" })
|
|
80
|
+
] });
|
|
81
|
+
}
|
|
82
|
+
var HeroImage_default = HeroImage;
|
|
48
83
|
function MovieCard({
|
|
49
84
|
id,
|
|
50
85
|
title,
|
|
@@ -80,6 +115,6 @@ function MovieCard({
|
|
|
80
115
|
}
|
|
81
116
|
var MovieCard_default = MovieCard;
|
|
82
117
|
|
|
83
|
-
export { Button_default as Button, MovieCard_default as MovieCard };
|
|
118
|
+
export { Button_default as Button, HeroImage_default as HeroImage, MovieCard_default as MovieCard };
|
|
84
119
|
//# sourceMappingURL=index.js.map
|
|
85
120
|
//# sourceMappingURL=index.js.map
|
package/dist/next/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/next/Button/Button.tsx","../../src/next/MovieCard/MovieCard.tsx"],"names":["_","_v","_s","_i","_ip","_c","_ch","jsx","Link"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/next/Button/Button.tsx","../../src/next/HeroImage/HeroImage.tsx","../../src/next/MovieCard/MovieCard.tsx"],"names":["_","_v","_s","_i","_ip","_c","_ch","jsxs","Fragment","jsx","Link"],"mappings":"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","file":"index.js","sourcesContent":["import Link from 'next/link'\n\nimport {\n getButtonClasses,\n getButtonDisabledClasses,\n iconSizeMap,\n} from '../../Button/Button.utils'\nimport { Icon } from '../../Icon'\n\nimport type { NextButtonProps } from './Button.types'\n\nfunction Button(props: Readonly<NextButtonProps>) {\n const {\n variant = 'primary',\n size = 'md',\n icon,\n iconPosition = 'left',\n className,\n children,\n } = props\n\n const classes = getButtonClasses({ variant, size, iconPosition, className })\n\n const content = (\n <>\n {icon && <Icon name={icon} size={iconSizeMap[size]} />}\n {children}\n </>\n )\n\n if (props.as === 'link') {\n const {\n as: _,\n variant: _v,\n size: _s,\n icon: _i,\n iconPosition: _ip,\n className: _c,\n children: _ch,\n ...linkProps\n } = props\n\n return (\n <Link className={classes} {...linkProps}>\n {content}\n </Link>\n )\n }\n\n const {\n as: _,\n variant: _v,\n size: _s,\n icon: _i,\n iconPosition: _ip,\n className: _c,\n children: _ch,\n ...buttonProps\n } = props\n\n return (\n <button className={getButtonDisabledClasses(classes)} {...buttonProps}>\n {content}\n </button>\n )\n}\n\nexport default Button\n","import Image from 'next/image'\nimport { useState } from 'react'\n\nimport { Skeleton } from '../../Skeleton'\n\nexport interface NextHeroImageProps {\n /** Backdrop path from TMDB API (e.g. \"/abc123.jpg\") */\n backdropPath?: string | null\n /** Alt text for the image */\n title?: string | null\n}\n\nfunction HeroImage({ backdropPath, title }: Readonly<NextHeroImageProps>) {\n const [loading, setLoading] = useState(true)\n\n const src = backdropPath\n ? `https://image.tmdb.org/t/p/original${backdropPath}`\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 {src && (\n <Image\n src={src}\n alt={title ?? 'Unknown'}\n fill\n priority\n sizes=\"100vw\"\n className=\"ui:relative ui:h-full ui:w-full ui:object-cover ui:object-center ui:z-0\"\n onLoad={() => {\n setLoading(false)\n }}\n />\n )}\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 Link from 'next/link'\n\nimport { getMovieCardLinkClasses } from '../../MovieCard/MovieCard.utils'\nimport MovieCardContent from '../../MovieCard/MovieCardContent'\n\nimport type { NextMovieCardProps } from './MovieCard.types'\n\nfunction MovieCard({\n id,\n title,\n posterUrl,\n voteAverage,\n year,\n className,\n imageLoading = 'lazy',\n as = 'card',\n ...rest\n}: Readonly<NextMovieCardProps>) {\n const href = 'href' in rest ? rest.href : undefined\n const onClick = 'onClick' in rest ? rest.onClick : undefined\n\n const isInteractive = as === 'link' || as === 'button'\n\n const cardContent = (\n <MovieCardContent\n id={id}\n title={title}\n posterUrl={posterUrl}\n voteAverage={voteAverage}\n year={year}\n className={className}\n imageLoading={imageLoading}\n isInteractive={isInteractive}\n onClick={as === 'button' ? onClick : undefined}\n />\n )\n\n if (as === 'link' && href) {\n return (\n <Link href={href} className={getMovieCardLinkClasses()}>\n {cardContent}\n </Link>\n )\n }\n\n return cardContent\n}\n\nexport default MovieCard\n"]}
|