@vite-mf-monorepo/ui 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +262 -0
- package/dist/Button/index.d.ts +25 -0
- package/dist/Button/index.js +4 -0
- package/dist/Button/index.js.map +1 -0
- package/dist/Card/index.d.ts +10 -0
- package/dist/Card/index.js +3 -0
- package/dist/Card/index.js.map +1 -0
- package/dist/Icon/index.d.ts +13 -0
- package/dist/Icon/index.js +3 -0
- package/dist/Icon/index.js.map +1 -0
- package/dist/chunk-IXEILQNO.js +85 -0
- package/dist/chunk-IXEILQNO.js.map +1 -0
- package/dist/chunk-YKNVY2QQ.js +23 -0
- package/dist/chunk-YKNVY2QQ.js.map +1 -0
- package/dist/chunk-Z3E2P4JR.js +120 -0
- package/dist/chunk-Z3E2P4JR.js.map +1 -0
- package/dist/index.css +1313 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.ts +472 -0
- package/dist/index.js +1514 -0
- package/dist/index.js.map +1 -0
- package/package.json +78 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1514 @@
|
|
|
1
|
+
import { Button_default } from './chunk-IXEILQNO.js';
|
|
2
|
+
export { Button_default as Button } from './chunk-IXEILQNO.js';
|
|
3
|
+
import { Card_default } from './chunk-YKNVY2QQ.js';
|
|
4
|
+
export { Card_default as Card } from './chunk-YKNVY2QQ.js';
|
|
5
|
+
import { Icon_default } from './chunk-Z3E2P4JR.js';
|
|
6
|
+
export { Icon_default as Icon } from './chunk-Z3E2P4JR.js';
|
|
7
|
+
import clsx15 from 'clsx';
|
|
8
|
+
import { createContext, useState, useRef, useEffect, useCallback, createElement, useLayoutEffect, useContext } from 'react';
|
|
9
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
10
|
+
import { getBlurDataUrl, getOptimizedImageUrl } from '@vite-mf-monorepo/shared';
|
|
11
|
+
import { Link } from 'react-router-dom';
|
|
12
|
+
|
|
13
|
+
var sizeMap = {
|
|
14
|
+
xs: { container: "ui:h-6 ui:w-6", icon: 12, text: "ui:text-xs" },
|
|
15
|
+
sm: { container: "ui:h-8 ui:w-8", icon: 16, text: "ui:text-sm" },
|
|
16
|
+
md: { container: "ui:h-10 ui:w-10", icon: 20, text: "ui:text-base" },
|
|
17
|
+
lg: { container: "ui:h-12 ui:w-12", icon: 24, text: "ui:text-lg" },
|
|
18
|
+
xl: { container: "ui:h-16 ui:w-16", icon: 32, text: "ui:text-xl" },
|
|
19
|
+
"2xl": { container: "ui:h-24 ui:w-24", icon: 48, text: "ui:text-2xl" },
|
|
20
|
+
"3xl": { container: "ui:h-32 ui:w-32", icon: 64, text: "ui:text-3xl" }
|
|
21
|
+
};
|
|
22
|
+
var Avatar = ({
|
|
23
|
+
className,
|
|
24
|
+
src,
|
|
25
|
+
alt,
|
|
26
|
+
size = "md",
|
|
27
|
+
initials,
|
|
28
|
+
testId,
|
|
29
|
+
...rest
|
|
30
|
+
}) => {
|
|
31
|
+
const [hasError, setHasError] = useState(false);
|
|
32
|
+
const { container, icon, text } = sizeMap[size];
|
|
33
|
+
const showImage = src && !hasError;
|
|
34
|
+
const showInitials = !showImage && initials;
|
|
35
|
+
const showFallback = !showImage && !initials;
|
|
36
|
+
const handleError = () => {
|
|
37
|
+
setHasError(true);
|
|
38
|
+
};
|
|
39
|
+
return /* @__PURE__ */ jsxs(
|
|
40
|
+
"div",
|
|
41
|
+
{
|
|
42
|
+
className: clsx15(
|
|
43
|
+
"ui:relative ui:inline-flex ui:items-center ui:justify-center ui:overflow-hidden ui:rounded-full",
|
|
44
|
+
"ui:bg-muted ui:text-muted-foreground",
|
|
45
|
+
container,
|
|
46
|
+
className
|
|
47
|
+
),
|
|
48
|
+
children: [
|
|
49
|
+
showImage && /* @__PURE__ */ jsx(
|
|
50
|
+
"img",
|
|
51
|
+
{
|
|
52
|
+
src,
|
|
53
|
+
alt,
|
|
54
|
+
onError: handleError,
|
|
55
|
+
className: "ui:h-full ui:w-full ui:object-cover",
|
|
56
|
+
"data-testid": testId,
|
|
57
|
+
...rest
|
|
58
|
+
}
|
|
59
|
+
),
|
|
60
|
+
showInitials && /* @__PURE__ */ jsx("span", { className: clsx15("ui:font-medium ui:uppercase", text), children: initials.slice(0, 2) }),
|
|
61
|
+
showFallback && /* @__PURE__ */ jsx(Icon_default, { name: "User", size: icon })
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
var Avatar_default = Avatar;
|
|
67
|
+
var sizeMap2 = {
|
|
68
|
+
sm: { padding: "ui:px-2 ui:py-0.5", text: "ui:text-xs", iconSize: 16 },
|
|
69
|
+
md: { padding: "ui:px-2.5 ui:py-0.5", text: "ui:text-sm", iconSize: 16 },
|
|
70
|
+
lg: { padding: "ui:px-3 ui:py-1", text: "ui:text-sm", iconSize: 16 }
|
|
71
|
+
};
|
|
72
|
+
var Badge = ({
|
|
73
|
+
children,
|
|
74
|
+
variant = "default",
|
|
75
|
+
size = "md",
|
|
76
|
+
icon,
|
|
77
|
+
textClassName,
|
|
78
|
+
className
|
|
79
|
+
}) => {
|
|
80
|
+
const { padding, text, iconSize } = sizeMap2[size];
|
|
81
|
+
return /* @__PURE__ */ jsxs(
|
|
82
|
+
"span",
|
|
83
|
+
{
|
|
84
|
+
className: clsx15(
|
|
85
|
+
"ui:inline-flex ui:items-center ui:gap-1 ui:rounded-full ui:font-medium",
|
|
86
|
+
padding,
|
|
87
|
+
text,
|
|
88
|
+
{
|
|
89
|
+
"ui:bg-primary": variant === "default",
|
|
90
|
+
"ui:text-primary-foreground": variant === "default" && !textClassName,
|
|
91
|
+
"ui:bg-secondary": variant === "secondary",
|
|
92
|
+
"ui:text-secondary-foreground": variant === "secondary" && !textClassName,
|
|
93
|
+
"ui:border ui:border-input ui:bg-transparent": variant === "outline",
|
|
94
|
+
"ui:bg-destructive": variant === "destructive",
|
|
95
|
+
"ui:text-destructive-foreground": variant === "destructive" && !textClassName
|
|
96
|
+
},
|
|
97
|
+
textClassName,
|
|
98
|
+
className
|
|
99
|
+
),
|
|
100
|
+
children: [
|
|
101
|
+
icon && /* @__PURE__ */ jsx(Icon_default, { name: icon, size: iconSize }),
|
|
102
|
+
children
|
|
103
|
+
]
|
|
104
|
+
}
|
|
105
|
+
);
|
|
106
|
+
};
|
|
107
|
+
var Badge_default = Badge;
|
|
108
|
+
var sizeMap3 = {
|
|
109
|
+
sm: { button: "ui:h-8 ui:w-8", icon: 16 },
|
|
110
|
+
md: { button: "ui:h-10 ui:w-10", icon: 20 },
|
|
111
|
+
lg: { button: "ui:h-12 ui:w-12", icon: 24 }
|
|
112
|
+
};
|
|
113
|
+
var IconButton = ({
|
|
114
|
+
className,
|
|
115
|
+
icon,
|
|
116
|
+
variant = "ghost",
|
|
117
|
+
size = "md",
|
|
118
|
+
disabled,
|
|
119
|
+
...rest
|
|
120
|
+
}) => {
|
|
121
|
+
const { button: buttonSize, icon: iconSize } = sizeMap3[size];
|
|
122
|
+
return /* @__PURE__ */ jsx(
|
|
123
|
+
"button",
|
|
124
|
+
{
|
|
125
|
+
className: clsx15(
|
|
126
|
+
"ui:inline-flex ui:items-center ui:justify-center ui:cursor-pointer ui:rounded-full ui:transition-colors",
|
|
127
|
+
"ui:focus:outline-none ui:focus:ring-2 ui:focus:ring-ring ui:focus:ring-offset-2",
|
|
128
|
+
"ui:disabled:pointer-events-none ui:disabled:opacity-50",
|
|
129
|
+
{
|
|
130
|
+
"ui:bg-primary ui:text-primary-foreground ui:hover:bg-primary/90": variant === "primary",
|
|
131
|
+
"ui:bg-secondary ui:text-secondary-foreground ui:hover:bg-secondary/80": variant === "secondary",
|
|
132
|
+
"ui:hover:bg-accent ui:hover:text-accent-foreground": variant === "ghost",
|
|
133
|
+
"ui:border ui:border-input ui:bg-background ui:hover:bg-accent ui:hover:text-accent-foreground": variant === "outline"
|
|
134
|
+
},
|
|
135
|
+
buttonSize,
|
|
136
|
+
className
|
|
137
|
+
),
|
|
138
|
+
disabled,
|
|
139
|
+
...rest,
|
|
140
|
+
children: /* @__PURE__ */ jsx(Icon_default, { name: icon, size: iconSize })
|
|
141
|
+
}
|
|
142
|
+
);
|
|
143
|
+
};
|
|
144
|
+
var IconButton_default = IconButton;
|
|
145
|
+
var Image = ({
|
|
146
|
+
src,
|
|
147
|
+
alt,
|
|
148
|
+
blurDataUrl,
|
|
149
|
+
autoBlur = false,
|
|
150
|
+
blurSize = 16,
|
|
151
|
+
blurQuality = 0.3,
|
|
152
|
+
aspectRatio = "2/3",
|
|
153
|
+
fallback,
|
|
154
|
+
className,
|
|
155
|
+
onLoad,
|
|
156
|
+
onError,
|
|
157
|
+
loading = "eager",
|
|
158
|
+
...rest
|
|
159
|
+
}) => {
|
|
160
|
+
const imgRef = useRef(null);
|
|
161
|
+
const containerRef = useRef(null);
|
|
162
|
+
const [state, setState] = useState("loading");
|
|
163
|
+
const [generatedBlur, setGeneratedBlur] = useState(
|
|
164
|
+
void 0
|
|
165
|
+
);
|
|
166
|
+
const [blurReady, setBlurReady] = useState(!autoBlur || !!blurDataUrl);
|
|
167
|
+
const [isVisible, setIsVisible] = useState(loading === "eager");
|
|
168
|
+
const effectiveBlur = blurDataUrl ?? generatedBlur;
|
|
169
|
+
useEffect(() => {
|
|
170
|
+
if (loading === "eager" || !containerRef.current) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
const observer = new IntersectionObserver(
|
|
174
|
+
([entry]) => {
|
|
175
|
+
if (entry.isIntersecting) {
|
|
176
|
+
setIsVisible(true);
|
|
177
|
+
observer.unobserve(entry.target);
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
{ rootMargin: "50px" }
|
|
181
|
+
);
|
|
182
|
+
observer.observe(containerRef.current);
|
|
183
|
+
return () => {
|
|
184
|
+
observer.disconnect();
|
|
185
|
+
};
|
|
186
|
+
}, [loading]);
|
|
187
|
+
useEffect(() => {
|
|
188
|
+
if (!autoBlur || blurDataUrl) {
|
|
189
|
+
setBlurReady(true);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
setBlurReady(false);
|
|
193
|
+
getBlurDataUrl(src, blurSize, blurQuality).then((base64) => {
|
|
194
|
+
setGeneratedBlur(base64);
|
|
195
|
+
setBlurReady(true);
|
|
196
|
+
}).catch(() => {
|
|
197
|
+
setBlurReady(true);
|
|
198
|
+
});
|
|
199
|
+
}, [autoBlur, src, blurDataUrl, blurSize, blurQuality]);
|
|
200
|
+
useEffect(() => {
|
|
201
|
+
setState("loading");
|
|
202
|
+
setGeneratedBlur(void 0);
|
|
203
|
+
if (imgRef.current?.complete && imgRef.current.naturalHeight !== 0) {
|
|
204
|
+
setState("loaded");
|
|
205
|
+
}
|
|
206
|
+
}, [src]);
|
|
207
|
+
const handleLoad = useCallback(() => {
|
|
208
|
+
setState("loaded");
|
|
209
|
+
onLoad?.();
|
|
210
|
+
}, [onLoad]);
|
|
211
|
+
const handleError = useCallback(() => {
|
|
212
|
+
setState("error");
|
|
213
|
+
onError?.();
|
|
214
|
+
}, [onError]);
|
|
215
|
+
const defaultFallback = /* @__PURE__ */ jsx("div", { className: "ui:flex ui:h-full ui:w-full ui:items-center ui:justify-center ui:bg-muted", children: /* @__PURE__ */ jsx(
|
|
216
|
+
Icon_default,
|
|
217
|
+
{
|
|
218
|
+
name: "Photo",
|
|
219
|
+
size: 48,
|
|
220
|
+
className: "ui:text-muted-foreground",
|
|
221
|
+
"aria-hidden": "true"
|
|
222
|
+
}
|
|
223
|
+
) });
|
|
224
|
+
return /* @__PURE__ */ jsx(
|
|
225
|
+
"div",
|
|
226
|
+
{
|
|
227
|
+
ref: containerRef,
|
|
228
|
+
className: clsx15("ui:relative ui:overflow-hidden ui:bg-muted", className),
|
|
229
|
+
style: aspectRatio ? { aspectRatio } : void 0,
|
|
230
|
+
"data-state": state,
|
|
231
|
+
children: state === "error" ? fallback ?? defaultFallback : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
232
|
+
effectiveBlur && state === "loading" && /* @__PURE__ */ jsx(
|
|
233
|
+
"img",
|
|
234
|
+
{
|
|
235
|
+
src: effectiveBlur,
|
|
236
|
+
alt: "",
|
|
237
|
+
"aria-hidden": "true",
|
|
238
|
+
className: "ui:absolute ui:inset-0 ui:h-full ui:w-full ui:scale-105 ui:object-cover"
|
|
239
|
+
}
|
|
240
|
+
),
|
|
241
|
+
blurReady && isVisible && /* @__PURE__ */ jsx(
|
|
242
|
+
"img",
|
|
243
|
+
{
|
|
244
|
+
ref: imgRef,
|
|
245
|
+
src,
|
|
246
|
+
alt,
|
|
247
|
+
onLoad: handleLoad,
|
|
248
|
+
onError: handleError,
|
|
249
|
+
className: clsx15(
|
|
250
|
+
"ui:absolute ui:inset-0 ui:h-full ui:w-full ui:object-cover ui:transition-opacity ui:duration-300",
|
|
251
|
+
state === "loaded" ? "ui:opacity-100" : "ui:opacity-0"
|
|
252
|
+
),
|
|
253
|
+
...rest
|
|
254
|
+
}
|
|
255
|
+
)
|
|
256
|
+
] })
|
|
257
|
+
}
|
|
258
|
+
);
|
|
259
|
+
};
|
|
260
|
+
var Image_default = Image;
|
|
261
|
+
var Skeleton = ({
|
|
262
|
+
variant = "rectangle",
|
|
263
|
+
width,
|
|
264
|
+
height,
|
|
265
|
+
aspectRatio,
|
|
266
|
+
rounded = true,
|
|
267
|
+
className,
|
|
268
|
+
...rest
|
|
269
|
+
}) => {
|
|
270
|
+
return /* @__PURE__ */ jsx(
|
|
271
|
+
"div",
|
|
272
|
+
{
|
|
273
|
+
className: clsx15(
|
|
274
|
+
"ui:relative ui:overflow-hidden ui:bg-muted",
|
|
275
|
+
"ui-skeleton-shimmer",
|
|
276
|
+
{
|
|
277
|
+
"ui:rounded-lg": variant === "rectangle" && rounded,
|
|
278
|
+
"ui:rounded-full": variant === "circle",
|
|
279
|
+
"ui:rounded": variant === "line" && rounded
|
|
280
|
+
},
|
|
281
|
+
width,
|
|
282
|
+
height,
|
|
283
|
+
className
|
|
284
|
+
),
|
|
285
|
+
style: aspectRatio ? { aspectRatio } : void 0,
|
|
286
|
+
...rest
|
|
287
|
+
}
|
|
288
|
+
);
|
|
289
|
+
};
|
|
290
|
+
var Skeleton_default = Skeleton;
|
|
291
|
+
var HeroImage = ({ backdropPath, title }) => {
|
|
292
|
+
const [loading, setLoading] = useState(true);
|
|
293
|
+
const backdropPathMobile = backdropPath ? getOptimizedImageUrl(backdropPath, "w300", 60) : void 0;
|
|
294
|
+
const backdropPathTablet = backdropPath ? getOptimizedImageUrl(backdropPath, "w300", 60) : void 0;
|
|
295
|
+
const backdropPathDesktop = backdropPath ? getOptimizedImageUrl(backdropPath, "w780", 60) : void 0;
|
|
296
|
+
const backdropPathUltraWide = backdropPath ? getOptimizedImageUrl(backdropPath, "w1280", 60) : void 0;
|
|
297
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
298
|
+
loading && /* @__PURE__ */ jsx(
|
|
299
|
+
Skeleton_default,
|
|
300
|
+
{
|
|
301
|
+
"data-testid": "hero-image-skeleton",
|
|
302
|
+
variant: "rectangle",
|
|
303
|
+
width: "ui:relative ui:w-full ui:h-full ui:hero-height ui:z-0",
|
|
304
|
+
aspectRatio: "21/9",
|
|
305
|
+
rounded: false
|
|
306
|
+
}
|
|
307
|
+
),
|
|
308
|
+
/* @__PURE__ */ jsxs("picture", { children: [
|
|
309
|
+
backdropPathMobile && /* @__PURE__ */ jsx("source", { media: "(max-width: 639px)", srcSet: backdropPathMobile }),
|
|
310
|
+
backdropPathTablet && /* @__PURE__ */ jsx("source", { media: "(max-width: 1023px)", srcSet: backdropPathTablet }),
|
|
311
|
+
backdropPathDesktop && /* @__PURE__ */ jsx("source", { media: "(max-width: 1535px)", srcSet: backdropPathDesktop }),
|
|
312
|
+
backdropPathUltraWide && /* @__PURE__ */ jsx("source", { media: "(min-width: 1536px)", srcSet: backdropPathUltraWide }),
|
|
313
|
+
backdropPathMobile && /* @__PURE__ */ jsx(
|
|
314
|
+
"img",
|
|
315
|
+
{
|
|
316
|
+
src: backdropPathMobile,
|
|
317
|
+
fetchPriority: "high",
|
|
318
|
+
onLoad: () => {
|
|
319
|
+
setLoading(false);
|
|
320
|
+
},
|
|
321
|
+
alt: title ?? "Unknown",
|
|
322
|
+
className: "ui:relative ui:h-full ui:w-full ui:object-cover ui:object-center ui:z-0"
|
|
323
|
+
}
|
|
324
|
+
)
|
|
325
|
+
] }),
|
|
326
|
+
/* @__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" })
|
|
327
|
+
] });
|
|
328
|
+
};
|
|
329
|
+
var HeroImage_default = HeroImage;
|
|
330
|
+
var Modal = ({
|
|
331
|
+
isOpen,
|
|
332
|
+
onClose,
|
|
333
|
+
children,
|
|
334
|
+
"aria-label": ariaLabel,
|
|
335
|
+
className,
|
|
336
|
+
onOverlayClick
|
|
337
|
+
}) => {
|
|
338
|
+
const ref = useRef(null);
|
|
339
|
+
useEffect(() => {
|
|
340
|
+
const dialog = ref.current;
|
|
341
|
+
if (!dialog) return;
|
|
342
|
+
if (isOpen) {
|
|
343
|
+
dialog.showModal();
|
|
344
|
+
document.body.style.overflow = "hidden";
|
|
345
|
+
} else {
|
|
346
|
+
dialog.close();
|
|
347
|
+
document.body.style.overflow = "";
|
|
348
|
+
}
|
|
349
|
+
return () => {
|
|
350
|
+
document.body.style.overflow = "";
|
|
351
|
+
};
|
|
352
|
+
}, [isOpen]);
|
|
353
|
+
const handleClick = (e) => {
|
|
354
|
+
if (e.target === ref.current) (onOverlayClick ?? onClose)();
|
|
355
|
+
};
|
|
356
|
+
const handleClose = () => {
|
|
357
|
+
onClose();
|
|
358
|
+
};
|
|
359
|
+
return /* @__PURE__ */ jsx(
|
|
360
|
+
"dialog",
|
|
361
|
+
{
|
|
362
|
+
ref,
|
|
363
|
+
"aria-label": ariaLabel,
|
|
364
|
+
"aria-modal": "true",
|
|
365
|
+
onClick: handleClick,
|
|
366
|
+
onClose: handleClose,
|
|
367
|
+
className: clsx15(
|
|
368
|
+
"ui:backdrop:bg-black/80",
|
|
369
|
+
"ui:bg-transparent ui:border-0 ui:p-0",
|
|
370
|
+
"ui:max-w-none ui:max-h-none ui:w-full ui:h-full",
|
|
371
|
+
className
|
|
372
|
+
),
|
|
373
|
+
children
|
|
374
|
+
}
|
|
375
|
+
);
|
|
376
|
+
};
|
|
377
|
+
var Modal_default = Modal;
|
|
378
|
+
var circleSizeMap = {
|
|
379
|
+
sm: { size: 32, stroke: 3, fontSize: "ui:text-xs" },
|
|
380
|
+
md: { size: 48, stroke: 4, fontSize: "ui:text-sm" },
|
|
381
|
+
lg: { size: 64, stroke: 5, fontSize: "ui:text-base" }
|
|
382
|
+
};
|
|
383
|
+
var getColorClass = (percent) => {
|
|
384
|
+
if (percent >= 70) return "ui:text-green-600";
|
|
385
|
+
if (percent >= 40) return "ui:text-amber-600";
|
|
386
|
+
return "ui:text-red-500";
|
|
387
|
+
};
|
|
388
|
+
var CircleRating = ({
|
|
389
|
+
percent,
|
|
390
|
+
size,
|
|
391
|
+
showValue,
|
|
392
|
+
value,
|
|
393
|
+
max,
|
|
394
|
+
trackClassName
|
|
395
|
+
}) => {
|
|
396
|
+
const { size: svgSize, stroke, fontSize } = circleSizeMap[size];
|
|
397
|
+
const radius = (svgSize - stroke) / 2;
|
|
398
|
+
const circumference = 2 * Math.PI * radius;
|
|
399
|
+
const offset = circumference - percent / 100 * circumference;
|
|
400
|
+
return /* @__PURE__ */ jsxs("div", { className: "ui:relative ui:inline-flex ui:items-center ui:justify-center", children: [
|
|
401
|
+
/* @__PURE__ */ jsxs("svg", { width: svgSize, height: svgSize, className: "ui:-rotate-90", children: [
|
|
402
|
+
/* @__PURE__ */ jsx(
|
|
403
|
+
"circle",
|
|
404
|
+
{
|
|
405
|
+
cx: svgSize / 2,
|
|
406
|
+
cy: svgSize / 2,
|
|
407
|
+
r: radius,
|
|
408
|
+
fill: "none",
|
|
409
|
+
stroke: "currentColor",
|
|
410
|
+
strokeWidth: stroke,
|
|
411
|
+
className: trackClassName ?? "ui:text-gray-200"
|
|
412
|
+
}
|
|
413
|
+
),
|
|
414
|
+
/* @__PURE__ */ jsx(
|
|
415
|
+
"circle",
|
|
416
|
+
{
|
|
417
|
+
cx: svgSize / 2,
|
|
418
|
+
cy: svgSize / 2,
|
|
419
|
+
r: radius,
|
|
420
|
+
fill: "none",
|
|
421
|
+
stroke: "currentColor",
|
|
422
|
+
strokeWidth: stroke,
|
|
423
|
+
strokeLinecap: "round",
|
|
424
|
+
strokeDasharray: circumference,
|
|
425
|
+
strokeDashoffset: offset,
|
|
426
|
+
className: clsx15(
|
|
427
|
+
"ui:transition-all ui:duration-500",
|
|
428
|
+
getColorClass(percent)
|
|
429
|
+
)
|
|
430
|
+
}
|
|
431
|
+
)
|
|
432
|
+
] }),
|
|
433
|
+
showValue && /* @__PURE__ */ jsx(
|
|
434
|
+
"span",
|
|
435
|
+
{
|
|
436
|
+
className: clsx15(
|
|
437
|
+
"ui:absolute ui:font-bold",
|
|
438
|
+
fontSize,
|
|
439
|
+
getColorClass(percent)
|
|
440
|
+
),
|
|
441
|
+
children: max === 100 ? Math.round(percent) : value.toFixed(1)
|
|
442
|
+
}
|
|
443
|
+
)
|
|
444
|
+
] });
|
|
445
|
+
};
|
|
446
|
+
var CircleRating_default = CircleRating;
|
|
447
|
+
var starsSizeMap = {
|
|
448
|
+
sm: 16,
|
|
449
|
+
md: 20,
|
|
450
|
+
lg: 24
|
|
451
|
+
};
|
|
452
|
+
var StarsRating = ({
|
|
453
|
+
percent,
|
|
454
|
+
size,
|
|
455
|
+
showValue,
|
|
456
|
+
value,
|
|
457
|
+
max
|
|
458
|
+
}) => {
|
|
459
|
+
const iconSize = starsSizeMap[size];
|
|
460
|
+
return /* @__PURE__ */ jsxs("div", { className: "ui:inline-flex ui:items-center ui:gap-1", children: [
|
|
461
|
+
/* @__PURE__ */ jsxs("div", { className: "ui:relative", children: [
|
|
462
|
+
/* @__PURE__ */ jsx("div", { className: "ui:flex ui:text-gray-300", children: [1, 2, 3, 4, 5].map((i) => /* @__PURE__ */ jsx(Icon_default, { name: "Star", size: iconSize }, i)) }),
|
|
463
|
+
/* @__PURE__ */ jsx(
|
|
464
|
+
"div",
|
|
465
|
+
{
|
|
466
|
+
className: "ui:absolute ui:inset-0 ui:flex ui:text-yellow-400",
|
|
467
|
+
style: { clipPath: `inset(0 ${String(100 - percent)}% 0 0)` },
|
|
468
|
+
children: [1, 2, 3, 4, 5].map((i) => /* @__PURE__ */ jsx(Icon_default, { name: "Star", size: iconSize }, i))
|
|
469
|
+
}
|
|
470
|
+
)
|
|
471
|
+
] }),
|
|
472
|
+
showValue && /* @__PURE__ */ jsx(
|
|
473
|
+
"span",
|
|
474
|
+
{
|
|
475
|
+
className: clsx15(
|
|
476
|
+
"ui:font-medium ui:text-muted-foreground",
|
|
477
|
+
size === "sm" && "ui:text-xs",
|
|
478
|
+
size === "md" && "ui:text-sm",
|
|
479
|
+
size === "lg" && "ui:text-base"
|
|
480
|
+
),
|
|
481
|
+
children: max === 100 ? (value / 10).toFixed(1) : value.toFixed(1)
|
|
482
|
+
}
|
|
483
|
+
)
|
|
484
|
+
] });
|
|
485
|
+
};
|
|
486
|
+
var StarsRating_default = StarsRating;
|
|
487
|
+
var Rating = ({
|
|
488
|
+
value,
|
|
489
|
+
max = 10,
|
|
490
|
+
variant = "circle",
|
|
491
|
+
size = "md",
|
|
492
|
+
showValue = true,
|
|
493
|
+
trackClassName,
|
|
494
|
+
className
|
|
495
|
+
}) => {
|
|
496
|
+
const clampedValue = Math.max(0, Math.min(value, max));
|
|
497
|
+
const percent = clampedValue / max * 100;
|
|
498
|
+
return /* @__PURE__ */ jsx("div", { className: clsx15("ui:inline-flex", className), children: variant === "circle" ? /* @__PURE__ */ jsx(
|
|
499
|
+
CircleRating_default,
|
|
500
|
+
{
|
|
501
|
+
percent,
|
|
502
|
+
size,
|
|
503
|
+
showValue,
|
|
504
|
+
value: clampedValue,
|
|
505
|
+
max,
|
|
506
|
+
trackClassName
|
|
507
|
+
}
|
|
508
|
+
) : /* @__PURE__ */ jsx(
|
|
509
|
+
StarsRating_default,
|
|
510
|
+
{
|
|
511
|
+
percent,
|
|
512
|
+
size,
|
|
513
|
+
showValue,
|
|
514
|
+
value: clampedValue,
|
|
515
|
+
max
|
|
516
|
+
}
|
|
517
|
+
) });
|
|
518
|
+
};
|
|
519
|
+
var Rating_default = Rating;
|
|
520
|
+
var variantStyles = {
|
|
521
|
+
h1: "ui:font-roboto ui:text-xl ui:sm:text-2xl ui:md:text-3xl ui:lg:text-4xl ui:font-bold ui:leading-tight ui:text-foreground",
|
|
522
|
+
h2: "ui:font-roboto ui:text-lg ui:sm:text-xl ui:md:text-2xl ui:lg:text-3xl ui:font-bold ui:leading-tight ui:text-foreground",
|
|
523
|
+
h3: "ui:font-roboto ui:text-base ui:sm:text-lg ui:md:text-xl ui:lg:text-2xl ui:font-semibold ui:leading-snug ui:text-foreground",
|
|
524
|
+
h4: "ui:font-roboto ui:text-sm ui:sm:text-base ui:md:text-lg ui:lg:text-xl ui:font-semibold ui:leading-snug ui:text-foreground",
|
|
525
|
+
h5: "ui:font-roboto ui:text-sm ui:sm:text-base ui:md:text-lg ui:font-medium ui:leading-normal ui:text-foreground",
|
|
526
|
+
h6: "ui:font-roboto ui:text-xs ui:sm:text-sm ui:md:text-base ui:font-medium ui:leading-normal ui:text-foreground",
|
|
527
|
+
body: "ui:font-inter ui:text-xs ui:sm:text-sm ui:md:text-base ui:leading-relaxed ui:text-foreground",
|
|
528
|
+
"body-sm": "ui:font-inter ui:text-xs ui:sm:text-sm ui:leading-relaxed ui:text-foreground",
|
|
529
|
+
"body-lg": "ui:font-inter ui:text-sm ui:sm:text-base ui:md:text-lg ui:leading-relaxed ui:text-foreground",
|
|
530
|
+
lead: "ui:font-inter ui:text-sm ui:sm:text-base ui:md:text-lg ui:lg:text-xl ui:leading-relaxed ui:text-muted-foreground",
|
|
531
|
+
caption: "ui:font-inter ui:text-xs ui:sm:text-sm ui:text-muted-foreground",
|
|
532
|
+
"caption-xs": "ui:font-inter ui:text-xs ui:text-muted-foreground",
|
|
533
|
+
label: "ui:font-inter ui:text-xs ui:sm:text-sm ui:font-medium ui:text-foreground",
|
|
534
|
+
muted: "ui:font-inter ui:text-xs ui:sm:text-sm ui:text-muted-foreground",
|
|
535
|
+
blockquote: "ui:font-inter ui:text-xs ui:sm:text-sm ui:md:text-base ui:border-l-4 ui:border-border ui:pl-4 ui:italic ui:text-muted-foreground"
|
|
536
|
+
};
|
|
537
|
+
var variantToTag = {
|
|
538
|
+
h1: "h1",
|
|
539
|
+
h2: "h2",
|
|
540
|
+
h3: "h3",
|
|
541
|
+
h4: "h4",
|
|
542
|
+
h5: "h5",
|
|
543
|
+
h6: "h6",
|
|
544
|
+
body: "p",
|
|
545
|
+
"body-sm": "p",
|
|
546
|
+
"body-lg": "p",
|
|
547
|
+
lead: "p",
|
|
548
|
+
caption: "span",
|
|
549
|
+
"caption-xs": "span",
|
|
550
|
+
label: "label",
|
|
551
|
+
muted: "p",
|
|
552
|
+
blockquote: "blockquote"
|
|
553
|
+
};
|
|
554
|
+
var Typography = ({
|
|
555
|
+
variant,
|
|
556
|
+
as,
|
|
557
|
+
className,
|
|
558
|
+
children,
|
|
559
|
+
...rest
|
|
560
|
+
}) => {
|
|
561
|
+
const Component = as ?? variantToTag[variant];
|
|
562
|
+
return createElement(
|
|
563
|
+
Component,
|
|
564
|
+
{ className: clsx15(variantStyles[variant], className), ...rest },
|
|
565
|
+
children
|
|
566
|
+
);
|
|
567
|
+
};
|
|
568
|
+
var Typography_default = Typography;
|
|
569
|
+
var MovieCard = ({
|
|
570
|
+
id,
|
|
571
|
+
title,
|
|
572
|
+
posterUrl,
|
|
573
|
+
voteAverage,
|
|
574
|
+
year,
|
|
575
|
+
className,
|
|
576
|
+
imageLoading = "lazy",
|
|
577
|
+
as = "card",
|
|
578
|
+
...rest
|
|
579
|
+
}) => {
|
|
580
|
+
const to = "to" in rest ? rest.to : void 0;
|
|
581
|
+
const onClick = "onClick" in rest ? rest.onClick : void 0;
|
|
582
|
+
const isInteractive = as === "link" || as === "button";
|
|
583
|
+
const cardContent = /* @__PURE__ */ jsxs(
|
|
584
|
+
Card_default,
|
|
585
|
+
{
|
|
586
|
+
variant: "ghost",
|
|
587
|
+
className: clsx15(
|
|
588
|
+
"ui:group ui:relative ui:flex ui:flex-col ui:overflow-hidden",
|
|
589
|
+
isInteractive && [
|
|
590
|
+
"ui:cursor-pointer",
|
|
591
|
+
"ui:transition-transform ui:duration-200",
|
|
592
|
+
"hover:ui:scale-[1.02]"
|
|
593
|
+
],
|
|
594
|
+
className
|
|
595
|
+
),
|
|
596
|
+
onClick: as === "button" ? onClick : void 0,
|
|
597
|
+
"data-testid": `movie-card-${String(id)}`,
|
|
598
|
+
children: [
|
|
599
|
+
/* @__PURE__ */ jsxs("div", { className: "ui:relative ui:aspect-[2/3] ui:w-full ui:overflow-hidden ui:rounded-md ui:bg-gray-200", children: [
|
|
600
|
+
/* @__PURE__ */ jsx(
|
|
601
|
+
Image_default,
|
|
602
|
+
{
|
|
603
|
+
src: posterUrl,
|
|
604
|
+
alt: title,
|
|
605
|
+
loading: imageLoading,
|
|
606
|
+
aspectRatio: void 0,
|
|
607
|
+
className: "ui:h-full ui:w-full ui:object-cover"
|
|
608
|
+
}
|
|
609
|
+
),
|
|
610
|
+
/* @__PURE__ */ jsx("div", { className: "ui:absolute ui:bottom-2 ui:right-2 ui:flex ui:items-center ui:justify-center ui:rounded-full ui:bg-white/80 ui:p-1", children: /* @__PURE__ */ jsx(
|
|
611
|
+
Rating_default,
|
|
612
|
+
{
|
|
613
|
+
value: voteAverage,
|
|
614
|
+
size: "sm",
|
|
615
|
+
variant: "circle",
|
|
616
|
+
trackClassName: "ui:text-gray-200",
|
|
617
|
+
className: "ui:drop-shadow"
|
|
618
|
+
}
|
|
619
|
+
) })
|
|
620
|
+
] }),
|
|
621
|
+
/* @__PURE__ */ jsxs("div", { className: "ui:mt-2 ui:flex ui:flex-col ui:gap-0.5 ui:px-1", children: [
|
|
622
|
+
/* @__PURE__ */ jsx(
|
|
623
|
+
Typography_default,
|
|
624
|
+
{
|
|
625
|
+
variant: "label",
|
|
626
|
+
as: "h3",
|
|
627
|
+
className: "ui:line-clamp-2",
|
|
628
|
+
title,
|
|
629
|
+
children: title
|
|
630
|
+
}
|
|
631
|
+
),
|
|
632
|
+
year && /* @__PURE__ */ jsx(
|
|
633
|
+
Typography_default,
|
|
634
|
+
{
|
|
635
|
+
variant: "caption-xs",
|
|
636
|
+
className: "ui:[.media-section:nth-of-type(odd)_&]:text-badge-foreground",
|
|
637
|
+
children: year
|
|
638
|
+
}
|
|
639
|
+
)
|
|
640
|
+
] })
|
|
641
|
+
]
|
|
642
|
+
}
|
|
643
|
+
);
|
|
644
|
+
if (as === "link" && to) {
|
|
645
|
+
return /* @__PURE__ */ jsx(Link, { to, className: "ui:block ui:no-underline ui:text-inherit", children: cardContent });
|
|
646
|
+
}
|
|
647
|
+
return cardContent;
|
|
648
|
+
};
|
|
649
|
+
var MovieCard_default = MovieCard;
|
|
650
|
+
var TrailerCard = ({
|
|
651
|
+
videoKey,
|
|
652
|
+
title,
|
|
653
|
+
type = "Trailer",
|
|
654
|
+
className
|
|
655
|
+
}) => {
|
|
656
|
+
const [isPlaying, setIsPlaying] = useState(false);
|
|
657
|
+
const thumbnailUrl = `https://img.youtube.com/vi/${videoKey}/hqdefault.jpg`;
|
|
658
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
659
|
+
/* @__PURE__ */ jsxs(
|
|
660
|
+
"button",
|
|
661
|
+
{
|
|
662
|
+
className: clsx15(
|
|
663
|
+
"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",
|
|
664
|
+
"ui:transition-transform ui:duration-200 hover:ui:scale-[1.02]",
|
|
665
|
+
className
|
|
666
|
+
),
|
|
667
|
+
onClick: () => {
|
|
668
|
+
setIsPlaying(true);
|
|
669
|
+
},
|
|
670
|
+
tabIndex: 0,
|
|
671
|
+
"aria-label": `Play ${title}`,
|
|
672
|
+
children: [
|
|
673
|
+
/* @__PURE__ */ jsx(
|
|
674
|
+
"img",
|
|
675
|
+
{
|
|
676
|
+
src: thumbnailUrl,
|
|
677
|
+
alt: title,
|
|
678
|
+
className: "ui:h-full ui:w-full ui:object-cover",
|
|
679
|
+
loading: "lazy"
|
|
680
|
+
}
|
|
681
|
+
),
|
|
682
|
+
/* @__PURE__ */ jsx("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", children: /* @__PURE__ */ jsx("div", { className: "ui:flex ui:items-center ui:justify-center ui:h-16 ui:w-16 ui:rounded-full ui:bg-white/90", children: /* @__PURE__ */ jsx("span", { className: "ui:text-2xl ui:ml-1", children: "\u25B6" }) }) }),
|
|
683
|
+
type && /* @__PURE__ */ jsx("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", children: type })
|
|
684
|
+
]
|
|
685
|
+
}
|
|
686
|
+
),
|
|
687
|
+
/* @__PURE__ */ jsx(
|
|
688
|
+
Modal_default,
|
|
689
|
+
{
|
|
690
|
+
isOpen: isPlaying,
|
|
691
|
+
onClose: () => {
|
|
692
|
+
setIsPlaying(false);
|
|
693
|
+
},
|
|
694
|
+
"aria-label": `Play ${title}`,
|
|
695
|
+
children: /* @__PURE__ */ jsxs("div", { className: "ui:flex ui:h-full ui:w-full ui:items-center ui:justify-center ui:p-4", children: [
|
|
696
|
+
/* @__PURE__ */ jsx(
|
|
697
|
+
Button_default,
|
|
698
|
+
{
|
|
699
|
+
icon: "XMark",
|
|
700
|
+
size: "sm",
|
|
701
|
+
variant: "ghost",
|
|
702
|
+
iconPosition: "left",
|
|
703
|
+
onClick: () => {
|
|
704
|
+
setIsPlaying(false);
|
|
705
|
+
},
|
|
706
|
+
className: "ui:absolute ui:top-4 ui:right-4 ui:text-white hover:ui:bg-white/10 ui:z-10 ui:focus:border-none",
|
|
707
|
+
"aria-label": "Close video",
|
|
708
|
+
children: "Close video"
|
|
709
|
+
}
|
|
710
|
+
),
|
|
711
|
+
isPlaying && /* @__PURE__ */ jsx(
|
|
712
|
+
"iframe",
|
|
713
|
+
{
|
|
714
|
+
className: "ui:w-full ui:max-w-4xl ui:aspect-video ui:rounded-lg",
|
|
715
|
+
src: `https://www.youtube.com/embed/${videoKey}`,
|
|
716
|
+
title,
|
|
717
|
+
allow: "accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
|
|
718
|
+
allowFullScreen: true
|
|
719
|
+
}
|
|
720
|
+
)
|
|
721
|
+
] })
|
|
722
|
+
}
|
|
723
|
+
)
|
|
724
|
+
] });
|
|
725
|
+
};
|
|
726
|
+
var TrailerCard_default = TrailerCard;
|
|
727
|
+
var CarouselCounter = ({
|
|
728
|
+
current,
|
|
729
|
+
total,
|
|
730
|
+
className
|
|
731
|
+
}) => {
|
|
732
|
+
return /* @__PURE__ */ jsxs(
|
|
733
|
+
"div",
|
|
734
|
+
{
|
|
735
|
+
className: clsx15(
|
|
736
|
+
"ui:bg-black/50 ui:rounded-full ui:px-3 ui:py-1",
|
|
737
|
+
"ui:text-white/90 ui:text-sm ui:font-medium ui:tabular-nums",
|
|
738
|
+
className
|
|
739
|
+
),
|
|
740
|
+
children: [
|
|
741
|
+
current + 1,
|
|
742
|
+
" / ",
|
|
743
|
+
total
|
|
744
|
+
]
|
|
745
|
+
}
|
|
746
|
+
);
|
|
747
|
+
};
|
|
748
|
+
var CarouselCounter_default = CarouselCounter;
|
|
749
|
+
var CarouselError = ({
|
|
750
|
+
message = "Failed to load data"
|
|
751
|
+
}) => {
|
|
752
|
+
return /* @__PURE__ */ jsxs("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", children: [
|
|
753
|
+
/* @__PURE__ */ jsx(Icon_default, { name: "ExclamationTriangle", size: 48, className: "ui:text-red-500" }),
|
|
754
|
+
/* @__PURE__ */ jsxs("div", { className: "ui:flex ui:flex-col ui:gap-1", children: [
|
|
755
|
+
/* @__PURE__ */ jsx("p", { className: "ui:text-sm ui:font-semibold ui:text-red-900", children: "Failed to fetch data" }),
|
|
756
|
+
/* @__PURE__ */ jsx("p", { className: "ui:text-sm ui:text-red-700", children: message })
|
|
757
|
+
] })
|
|
758
|
+
] });
|
|
759
|
+
};
|
|
760
|
+
var CarouselError_default = CarouselError;
|
|
761
|
+
var CarouselNavigation = ({
|
|
762
|
+
onPrev,
|
|
763
|
+
onNext,
|
|
764
|
+
canPrev,
|
|
765
|
+
canNext,
|
|
766
|
+
size = "sm",
|
|
767
|
+
position = "inline",
|
|
768
|
+
iconVariant = "secondary",
|
|
769
|
+
className
|
|
770
|
+
}) => {
|
|
771
|
+
if (position === "sides") {
|
|
772
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
773
|
+
/* @__PURE__ */ jsx("div", { className: "ui:absolute ui:left-0 ui:top-1/2 ui:-translate-x-1/2 ui:-translate-y-1/2", children: /* @__PURE__ */ jsx(
|
|
774
|
+
IconButton_default,
|
|
775
|
+
{
|
|
776
|
+
icon: "ChevronLeft",
|
|
777
|
+
variant: iconVariant,
|
|
778
|
+
size,
|
|
779
|
+
onClick: onPrev,
|
|
780
|
+
disabled: !canPrev,
|
|
781
|
+
"aria-label": "Previous"
|
|
782
|
+
}
|
|
783
|
+
) }),
|
|
784
|
+
/* @__PURE__ */ jsx("div", { className: "ui:absolute ui:right-0 ui:top-1/2 ui:-translate-y-1/2 ui:translate-x-1/2", children: /* @__PURE__ */ jsx(
|
|
785
|
+
IconButton_default,
|
|
786
|
+
{
|
|
787
|
+
icon: "ChevronRight",
|
|
788
|
+
variant: iconVariant,
|
|
789
|
+
size,
|
|
790
|
+
onClick: onNext,
|
|
791
|
+
disabled: !canNext,
|
|
792
|
+
"aria-label": "Next"
|
|
793
|
+
}
|
|
794
|
+
) })
|
|
795
|
+
] });
|
|
796
|
+
}
|
|
797
|
+
if (position === "sides-inset") {
|
|
798
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
799
|
+
/* @__PURE__ */ jsx("div", { className: "ui:absolute ui:left-4 ui:top-1/2 ui:-translate-y-1/2 ui:z-10 ui:text-white", children: /* @__PURE__ */ jsx(
|
|
800
|
+
IconButton_default,
|
|
801
|
+
{
|
|
802
|
+
icon: "ChevronLeft",
|
|
803
|
+
variant: iconVariant,
|
|
804
|
+
size,
|
|
805
|
+
onClick: onPrev,
|
|
806
|
+
disabled: !canPrev,
|
|
807
|
+
"aria-label": "Previous",
|
|
808
|
+
className: "ui:bg-white/20 ui:hover:bg-white/55"
|
|
809
|
+
}
|
|
810
|
+
) }),
|
|
811
|
+
/* @__PURE__ */ jsx("div", { className: "ui:absolute ui:right-4 ui:top-1/2 ui:-translate-y-1/2 ui:z-10 ui:text-white", children: /* @__PURE__ */ jsx(
|
|
812
|
+
IconButton_default,
|
|
813
|
+
{
|
|
814
|
+
icon: "ChevronRight",
|
|
815
|
+
variant: iconVariant,
|
|
816
|
+
size,
|
|
817
|
+
onClick: onNext,
|
|
818
|
+
disabled: !canNext,
|
|
819
|
+
"aria-label": "Next",
|
|
820
|
+
className: "ui:bg-white/20 ui:hover:bg-white/55"
|
|
821
|
+
}
|
|
822
|
+
) })
|
|
823
|
+
] });
|
|
824
|
+
}
|
|
825
|
+
return /* @__PURE__ */ jsxs("div", { className: clsx15("ui:flex ui:gap-2", className), children: [
|
|
826
|
+
/* @__PURE__ */ jsx(
|
|
827
|
+
IconButton_default,
|
|
828
|
+
{
|
|
829
|
+
icon: "ChevronLeft",
|
|
830
|
+
variant: iconVariant,
|
|
831
|
+
size,
|
|
832
|
+
onClick: onPrev,
|
|
833
|
+
disabled: !canPrev,
|
|
834
|
+
"aria-label": "Previous"
|
|
835
|
+
}
|
|
836
|
+
),
|
|
837
|
+
/* @__PURE__ */ jsx(
|
|
838
|
+
IconButton_default,
|
|
839
|
+
{
|
|
840
|
+
icon: "ChevronRight",
|
|
841
|
+
variant: iconVariant,
|
|
842
|
+
size,
|
|
843
|
+
onClick: onNext,
|
|
844
|
+
disabled: !canNext,
|
|
845
|
+
"aria-label": "Next"
|
|
846
|
+
}
|
|
847
|
+
)
|
|
848
|
+
] });
|
|
849
|
+
};
|
|
850
|
+
var CarouselNavigation_default = CarouselNavigation;
|
|
851
|
+
var CarouselPagination = ({
|
|
852
|
+
total,
|
|
853
|
+
current,
|
|
854
|
+
light = false,
|
|
855
|
+
className
|
|
856
|
+
}) => {
|
|
857
|
+
if (total === 0) return null;
|
|
858
|
+
return /* @__PURE__ */ jsx("div", { className: clsx15("ui:flex ui:items-center ui:gap-2", className), children: Array.from({ length: total }).map((_, index) => /* @__PURE__ */ jsx(
|
|
859
|
+
"div",
|
|
860
|
+
{
|
|
861
|
+
"aria-hidden": "true",
|
|
862
|
+
className: clsx15(
|
|
863
|
+
"ui:rounded-full ui:transition-all ui:duration-300",
|
|
864
|
+
index === current ? clsx15("ui:h-2 ui:w-6", light ? "ui:bg-white" : "ui:bg-primary") : clsx15(
|
|
865
|
+
"ui:h-2 ui:w-2",
|
|
866
|
+
light ? "ui:bg-white/50 hover:ui:bg-white/70" : "ui:bg-gray-400 hover:ui:bg-gray-500"
|
|
867
|
+
)
|
|
868
|
+
)
|
|
869
|
+
},
|
|
870
|
+
index
|
|
871
|
+
)) });
|
|
872
|
+
};
|
|
873
|
+
var CarouselPagination_default = CarouselPagination;
|
|
874
|
+
var Carousel = ({
|
|
875
|
+
children,
|
|
876
|
+
variant = "standard",
|
|
877
|
+
showPagination = true,
|
|
878
|
+
showArrows = true,
|
|
879
|
+
arrowPosition = "sides",
|
|
880
|
+
gap = 16,
|
|
881
|
+
className,
|
|
882
|
+
heroControlsClassName,
|
|
883
|
+
errorMessage,
|
|
884
|
+
rounded = true,
|
|
885
|
+
initialIndex,
|
|
886
|
+
onPrev,
|
|
887
|
+
onNext,
|
|
888
|
+
disableAnimation = false,
|
|
889
|
+
disableScroll = false
|
|
890
|
+
}) => {
|
|
891
|
+
const scrollRef = useRef(null);
|
|
892
|
+
const [totalPositions, setTotalPositions] = useState(1);
|
|
893
|
+
const [scrollIndex, setScrollIndex] = useState(initialIndex ?? 0);
|
|
894
|
+
const currentIndex = disableScroll ? initialIndex ?? 0 : scrollIndex;
|
|
895
|
+
const isHero = variant === "hero";
|
|
896
|
+
const isLightbox = variant === "lightbox";
|
|
897
|
+
const isFullWidth = isHero || isLightbox;
|
|
898
|
+
const calculatePositions = useCallback(() => {
|
|
899
|
+
const container = scrollRef.current;
|
|
900
|
+
if (!container) return;
|
|
901
|
+
const items = container.children;
|
|
902
|
+
if (isFullWidth) {
|
|
903
|
+
setTotalPositions(items.length);
|
|
904
|
+
return;
|
|
905
|
+
}
|
|
906
|
+
const firstItem = items[0];
|
|
907
|
+
if (!firstItem) {
|
|
908
|
+
setTotalPositions(1);
|
|
909
|
+
return;
|
|
910
|
+
}
|
|
911
|
+
const itemWidth = firstItem.offsetWidth;
|
|
912
|
+
const maxScrollLeft = container.scrollWidth - container.offsetWidth;
|
|
913
|
+
if (maxScrollLeft <= 0) {
|
|
914
|
+
setTotalPositions(1);
|
|
915
|
+
} else if (itemWidth > 0) {
|
|
916
|
+
const positions = Math.round(maxScrollLeft / (itemWidth + gap)) + 1;
|
|
917
|
+
setTotalPositions(Math.max(1, positions));
|
|
918
|
+
}
|
|
919
|
+
}, [gap, isFullWidth]);
|
|
920
|
+
useEffect(() => {
|
|
921
|
+
calculatePositions();
|
|
922
|
+
}, [children, calculatePositions]);
|
|
923
|
+
useEffect(() => {
|
|
924
|
+
const container = scrollRef.current;
|
|
925
|
+
if (!container) return;
|
|
926
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
927
|
+
calculatePositions();
|
|
928
|
+
});
|
|
929
|
+
resizeObserver.observe(container);
|
|
930
|
+
return () => {
|
|
931
|
+
resizeObserver.disconnect();
|
|
932
|
+
};
|
|
933
|
+
}, [calculatePositions]);
|
|
934
|
+
const initialScrollRef = useRef({
|
|
935
|
+
index: initialIndex ?? 0,
|
|
936
|
+
isFullWidth,
|
|
937
|
+
gap
|
|
938
|
+
});
|
|
939
|
+
useLayoutEffect(() => {
|
|
940
|
+
const { index, isFullWidth: fw, gap: g } = initialScrollRef.current;
|
|
941
|
+
if (index <= 0) return;
|
|
942
|
+
const container = scrollRef.current;
|
|
943
|
+
if (!container) return;
|
|
944
|
+
const firstItem = container.children[0];
|
|
945
|
+
const itemWidth = fw ? container.offsetWidth : firstItem?.offsetWidth ?? 0;
|
|
946
|
+
container.style.scrollBehavior = "auto";
|
|
947
|
+
container.scrollLeft = index * (itemWidth + (fw ? 0 : g));
|
|
948
|
+
container.style.scrollBehavior = "";
|
|
949
|
+
}, []);
|
|
950
|
+
const handleScroll = useCallback(() => {
|
|
951
|
+
const container = scrollRef.current;
|
|
952
|
+
if (!container) return;
|
|
953
|
+
const scrollLeft = container.scrollLeft;
|
|
954
|
+
const firstItem = container.children[0];
|
|
955
|
+
const itemWidth = isFullWidth ? container.offsetWidth : firstItem?.offsetWidth ?? 0;
|
|
956
|
+
if (itemWidth > 0) {
|
|
957
|
+
const index = Math.round(scrollLeft / (itemWidth + gap));
|
|
958
|
+
setScrollIndex(Math.min(index, totalPositions - 1));
|
|
959
|
+
}
|
|
960
|
+
}, [gap, isFullWidth, totalPositions]);
|
|
961
|
+
useEffect(() => {
|
|
962
|
+
if (disableScroll) return;
|
|
963
|
+
const container = scrollRef.current;
|
|
964
|
+
if (!container) return;
|
|
965
|
+
container.addEventListener("scroll", handleScroll);
|
|
966
|
+
return () => {
|
|
967
|
+
container.removeEventListener("scroll", handleScroll);
|
|
968
|
+
};
|
|
969
|
+
}, [disableScroll, handleScroll]);
|
|
970
|
+
useEffect(() => {
|
|
971
|
+
if (!disableScroll) return;
|
|
972
|
+
const container = scrollRef.current;
|
|
973
|
+
if (!container) return;
|
|
974
|
+
const preventScroll = (e) => {
|
|
975
|
+
e.preventDefault();
|
|
976
|
+
};
|
|
977
|
+
container.addEventListener("wheel", preventScroll, { passive: false });
|
|
978
|
+
return () => {
|
|
979
|
+
container.removeEventListener("wheel", preventScroll);
|
|
980
|
+
};
|
|
981
|
+
}, [disableScroll]);
|
|
982
|
+
const scrollTo = useCallback(
|
|
983
|
+
(index) => {
|
|
984
|
+
const container = scrollRef.current;
|
|
985
|
+
if (!container) return;
|
|
986
|
+
const firstItem = container.children[0];
|
|
987
|
+
const itemWidth = isFullWidth ? container.offsetWidth : firstItem?.offsetWidth ?? 0;
|
|
988
|
+
const isLastPosition = index === totalPositions - 1;
|
|
989
|
+
const scrollLeft = isLastPosition ? container.scrollWidth - container.offsetWidth : index * (itemWidth + gap);
|
|
990
|
+
container.scrollTo({
|
|
991
|
+
left: scrollLeft,
|
|
992
|
+
behavior: disableAnimation ? "auto" : "smooth"
|
|
993
|
+
});
|
|
994
|
+
},
|
|
995
|
+
[gap, isFullWidth, totalPositions, disableAnimation]
|
|
996
|
+
);
|
|
997
|
+
const scrollPrev = useCallback(() => {
|
|
998
|
+
if (currentIndex > 0) {
|
|
999
|
+
scrollTo(currentIndex - 1);
|
|
1000
|
+
}
|
|
1001
|
+
}, [currentIndex, scrollTo]);
|
|
1002
|
+
const scrollNext = useCallback(() => {
|
|
1003
|
+
if (currentIndex < totalPositions - 1) {
|
|
1004
|
+
scrollTo(currentIndex + 1);
|
|
1005
|
+
}
|
|
1006
|
+
}, [currentIndex, totalPositions, scrollTo]);
|
|
1007
|
+
const handlePrev = onPrev ?? scrollPrev;
|
|
1008
|
+
const handleNext = onNext ?? scrollNext;
|
|
1009
|
+
const handlePrevRef = useRef(handlePrev);
|
|
1010
|
+
const handleNextRef = useRef(handleNext);
|
|
1011
|
+
useEffect(() => {
|
|
1012
|
+
handlePrevRef.current = handlePrev;
|
|
1013
|
+
handleNextRef.current = handleNext;
|
|
1014
|
+
});
|
|
1015
|
+
useEffect(() => {
|
|
1016
|
+
const handleKeyDown = (e) => {
|
|
1017
|
+
if (e.key === "ArrowLeft") handlePrevRef.current();
|
|
1018
|
+
if (e.key === "ArrowRight") handleNextRef.current();
|
|
1019
|
+
};
|
|
1020
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
1021
|
+
return () => {
|
|
1022
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
1023
|
+
};
|
|
1024
|
+
}, []);
|
|
1025
|
+
if (errorMessage) {
|
|
1026
|
+
return /* @__PURE__ */ jsx(CarouselError_default, { message: errorMessage });
|
|
1027
|
+
}
|
|
1028
|
+
const canScrollPrev = currentIndex > 0;
|
|
1029
|
+
const canScrollNext = currentIndex < totalPositions - 1;
|
|
1030
|
+
const showControls = totalPositions > 1;
|
|
1031
|
+
return /* @__PURE__ */ jsxs("div", { className: clsx15("ui:relative", isLightbox && "ui:h-full", className), children: [
|
|
1032
|
+
/* @__PURE__ */ jsx(
|
|
1033
|
+
"div",
|
|
1034
|
+
{
|
|
1035
|
+
ref: scrollRef,
|
|
1036
|
+
className: clsx15(
|
|
1037
|
+
"ui:flex ui:overflow-x-auto ui:scroll-smooth ui:scrollbar-none",
|
|
1038
|
+
isFullWidth && "ui:snap-x ui:snap-mandatory",
|
|
1039
|
+
isLightbox && "ui:h-full",
|
|
1040
|
+
rounded && "ui:rounded-lg ui:overflow-hidden"
|
|
1041
|
+
),
|
|
1042
|
+
style: { gap: `${String(gap)}px` },
|
|
1043
|
+
children
|
|
1044
|
+
}
|
|
1045
|
+
),
|
|
1046
|
+
showControls && showArrows && arrowPosition === "sides" && !isHero && !isLightbox && /* @__PURE__ */ jsx(
|
|
1047
|
+
CarouselNavigation_default,
|
|
1048
|
+
{
|
|
1049
|
+
onPrev: handlePrev,
|
|
1050
|
+
onNext: handleNext,
|
|
1051
|
+
canPrev: canScrollPrev,
|
|
1052
|
+
canNext: canScrollNext,
|
|
1053
|
+
size: "md",
|
|
1054
|
+
position: "sides"
|
|
1055
|
+
}
|
|
1056
|
+
),
|
|
1057
|
+
showControls && isHero && (showPagination || showArrows) && /* @__PURE__ */ jsxs(
|
|
1058
|
+
"div",
|
|
1059
|
+
{
|
|
1060
|
+
className: clsx15(
|
|
1061
|
+
"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",
|
|
1062
|
+
heroControlsClassName
|
|
1063
|
+
),
|
|
1064
|
+
children: [
|
|
1065
|
+
/* @__PURE__ */ jsx("div", { className: "ui:flex-1" }),
|
|
1066
|
+
showPagination && /* @__PURE__ */ jsx(
|
|
1067
|
+
CarouselPagination_default,
|
|
1068
|
+
{
|
|
1069
|
+
total: totalPositions,
|
|
1070
|
+
current: currentIndex,
|
|
1071
|
+
light: true
|
|
1072
|
+
}
|
|
1073
|
+
),
|
|
1074
|
+
/* @__PURE__ */ jsx("div", { className: "ui:flex-1 ui:flex ui:justify-end", children: showArrows && /* @__PURE__ */ jsx(
|
|
1075
|
+
CarouselNavigation_default,
|
|
1076
|
+
{
|
|
1077
|
+
onPrev: handlePrev,
|
|
1078
|
+
onNext: handleNext,
|
|
1079
|
+
canPrev: canScrollPrev,
|
|
1080
|
+
canNext: canScrollNext,
|
|
1081
|
+
size: "sm"
|
|
1082
|
+
}
|
|
1083
|
+
) })
|
|
1084
|
+
]
|
|
1085
|
+
}
|
|
1086
|
+
),
|
|
1087
|
+
showControls && !isHero && !isLightbox && (showArrows && arrowPosition === "bottom-right" || showPagination) ? /* @__PURE__ */ jsxs(
|
|
1088
|
+
"div",
|
|
1089
|
+
{
|
|
1090
|
+
className: clsx15(
|
|
1091
|
+
"ui:mt-4 ui:flex ui:items-center",
|
|
1092
|
+
arrowPosition === "bottom-right" ? "ui:justify-end ui:gap-4" : "ui:justify-center"
|
|
1093
|
+
),
|
|
1094
|
+
children: [
|
|
1095
|
+
showPagination && /* @__PURE__ */ jsx(CarouselPagination_default, { total: totalPositions, current: currentIndex }),
|
|
1096
|
+
showArrows && arrowPosition === "bottom-right" && /* @__PURE__ */ jsx(
|
|
1097
|
+
CarouselNavigation_default,
|
|
1098
|
+
{
|
|
1099
|
+
onPrev: handlePrev,
|
|
1100
|
+
onNext: handleNext,
|
|
1101
|
+
canPrev: canScrollPrev,
|
|
1102
|
+
canNext: canScrollNext,
|
|
1103
|
+
size: "sm"
|
|
1104
|
+
}
|
|
1105
|
+
)
|
|
1106
|
+
]
|
|
1107
|
+
}
|
|
1108
|
+
) : null,
|
|
1109
|
+
showControls && isLightbox && /* @__PURE__ */ jsx("div", { className: "ui:absolute ui:top-4 ui:right-4 ui:z-10", children: /* @__PURE__ */ jsx(CarouselCounter_default, { current: currentIndex, total: totalPositions }) }),
|
|
1110
|
+
showControls && isLightbox && showArrows && /* @__PURE__ */ jsx(
|
|
1111
|
+
CarouselNavigation_default,
|
|
1112
|
+
{
|
|
1113
|
+
onPrev: handlePrev,
|
|
1114
|
+
onNext: handleNext,
|
|
1115
|
+
canPrev: canScrollPrev,
|
|
1116
|
+
canNext: canScrollNext,
|
|
1117
|
+
size: "md",
|
|
1118
|
+
position: "sides-inset",
|
|
1119
|
+
iconVariant: "ghost"
|
|
1120
|
+
}
|
|
1121
|
+
)
|
|
1122
|
+
] });
|
|
1123
|
+
};
|
|
1124
|
+
var Carousel_default = Carousel;
|
|
1125
|
+
var CarouselItem = ({
|
|
1126
|
+
children,
|
|
1127
|
+
isHero = false,
|
|
1128
|
+
isLightbox = false,
|
|
1129
|
+
className,
|
|
1130
|
+
...rest
|
|
1131
|
+
}) => {
|
|
1132
|
+
return /* @__PURE__ */ jsx(
|
|
1133
|
+
"div",
|
|
1134
|
+
{
|
|
1135
|
+
className: clsx15(
|
|
1136
|
+
"ui:flex-shrink-0",
|
|
1137
|
+
(isHero || isLightbox) && "ui:w-full ui:snap-center",
|
|
1138
|
+
isLightbox && "ui:flex ui:items-center ui:justify-center ui:h-full",
|
|
1139
|
+
className
|
|
1140
|
+
),
|
|
1141
|
+
...rest,
|
|
1142
|
+
children
|
|
1143
|
+
}
|
|
1144
|
+
);
|
|
1145
|
+
};
|
|
1146
|
+
var CarouselItem_default = CarouselItem;
|
|
1147
|
+
var CarouselLoading = ({
|
|
1148
|
+
count = 6,
|
|
1149
|
+
cardWidth = 150,
|
|
1150
|
+
cardHeight = 225,
|
|
1151
|
+
showTitle = true,
|
|
1152
|
+
showSubtitle = true,
|
|
1153
|
+
rounded = true
|
|
1154
|
+
}) => {
|
|
1155
|
+
return /* @__PURE__ */ jsx("div", { className: "ui:overflow-x-auto ui:flex ui:gap-4", children: Array.from({ length: count }).map((_, i) => /* @__PURE__ */ jsxs(
|
|
1156
|
+
"div",
|
|
1157
|
+
{
|
|
1158
|
+
style: { width: cardWidth, minWidth: cardWidth, maxWidth: cardWidth },
|
|
1159
|
+
children: [
|
|
1160
|
+
/* @__PURE__ */ jsx("div", { style: { width: cardWidth, height: cardHeight }, children: /* @__PURE__ */ jsx(
|
|
1161
|
+
Skeleton_default,
|
|
1162
|
+
{
|
|
1163
|
+
variant: "rectangle",
|
|
1164
|
+
width: "ui:w-full",
|
|
1165
|
+
height: "ui:h-full",
|
|
1166
|
+
rounded
|
|
1167
|
+
}
|
|
1168
|
+
) }),
|
|
1169
|
+
(showTitle || showSubtitle) && /* @__PURE__ */ jsxs(
|
|
1170
|
+
"div",
|
|
1171
|
+
{
|
|
1172
|
+
style: {
|
|
1173
|
+
marginTop: 8,
|
|
1174
|
+
display: "flex",
|
|
1175
|
+
flexDirection: "column",
|
|
1176
|
+
gap: 8
|
|
1177
|
+
},
|
|
1178
|
+
children: [
|
|
1179
|
+
showTitle && /* @__PURE__ */ jsx("div", { style: { width: cardWidth, height: 16 }, children: /* @__PURE__ */ jsx(
|
|
1180
|
+
Skeleton_default,
|
|
1181
|
+
{
|
|
1182
|
+
variant: "line",
|
|
1183
|
+
width: "ui:w-full",
|
|
1184
|
+
height: "ui:h-full"
|
|
1185
|
+
}
|
|
1186
|
+
) }),
|
|
1187
|
+
showSubtitle && /* @__PURE__ */ jsx("div", { style: { width: cardWidth * 0.75, height: 12 }, children: /* @__PURE__ */ jsx(
|
|
1188
|
+
Skeleton_default,
|
|
1189
|
+
{
|
|
1190
|
+
variant: "line",
|
|
1191
|
+
width: "ui:w-full",
|
|
1192
|
+
height: "ui:h-full"
|
|
1193
|
+
}
|
|
1194
|
+
) })
|
|
1195
|
+
]
|
|
1196
|
+
}
|
|
1197
|
+
)
|
|
1198
|
+
]
|
|
1199
|
+
},
|
|
1200
|
+
i
|
|
1201
|
+
)) });
|
|
1202
|
+
};
|
|
1203
|
+
var CarouselLoading_default = CarouselLoading;
|
|
1204
|
+
var TabsContext = createContext(
|
|
1205
|
+
void 0
|
|
1206
|
+
);
|
|
1207
|
+
var useTabsContext = () => {
|
|
1208
|
+
const context = useContext(TabsContext);
|
|
1209
|
+
if (!context) {
|
|
1210
|
+
throw new Error("Tabs compound components must be used within <Tabs>");
|
|
1211
|
+
}
|
|
1212
|
+
return context;
|
|
1213
|
+
};
|
|
1214
|
+
var TabsListContext = createContext(
|
|
1215
|
+
void 0
|
|
1216
|
+
);
|
|
1217
|
+
var useTabsListContext = () => {
|
|
1218
|
+
const context = useContext(TabsListContext);
|
|
1219
|
+
if (!context) {
|
|
1220
|
+
throw new Error("TabsTrigger must be used within <Tabs.List>");
|
|
1221
|
+
}
|
|
1222
|
+
return context;
|
|
1223
|
+
};
|
|
1224
|
+
var TabsList = ({ className, children, ...rest }) => {
|
|
1225
|
+
const { variant } = useTabsContext();
|
|
1226
|
+
const triggersRef = useRef([]);
|
|
1227
|
+
const disabledRef = useRef(/* @__PURE__ */ new Set());
|
|
1228
|
+
const registerTrigger = (value, disabled) => {
|
|
1229
|
+
if (!triggersRef.current.includes(value)) {
|
|
1230
|
+
triggersRef.current.push(value);
|
|
1231
|
+
}
|
|
1232
|
+
if (disabled) {
|
|
1233
|
+
disabledRef.current.add(value);
|
|
1234
|
+
} else {
|
|
1235
|
+
disabledRef.current.delete(value);
|
|
1236
|
+
}
|
|
1237
|
+
};
|
|
1238
|
+
const unregisterTrigger = (value) => {
|
|
1239
|
+
triggersRef.current = triggersRef.current.filter((v) => v !== value);
|
|
1240
|
+
disabledRef.current.delete(value);
|
|
1241
|
+
};
|
|
1242
|
+
const getTriggers = () => triggersRef.current;
|
|
1243
|
+
const isDisabled = (value) => disabledRef.current.has(value);
|
|
1244
|
+
return /* @__PURE__ */ jsx(
|
|
1245
|
+
TabsListContext.Provider,
|
|
1246
|
+
{
|
|
1247
|
+
value: { registerTrigger, unregisterTrigger, getTriggers, isDisabled },
|
|
1248
|
+
children: /* @__PURE__ */ jsx(
|
|
1249
|
+
"div",
|
|
1250
|
+
{
|
|
1251
|
+
className: clsx15(
|
|
1252
|
+
"ui:flex ui:gap-1",
|
|
1253
|
+
variant === "underline" && "ui:border-b ui:border-border",
|
|
1254
|
+
variant === "pills" && "ui:[.media-section:nth-of-type(odd)_&]:bg-white ui:bg-muted ui:p-1 ui:rounded-lg ui:w-fit",
|
|
1255
|
+
className
|
|
1256
|
+
),
|
|
1257
|
+
role: "tablist",
|
|
1258
|
+
...rest,
|
|
1259
|
+
children
|
|
1260
|
+
}
|
|
1261
|
+
)
|
|
1262
|
+
}
|
|
1263
|
+
);
|
|
1264
|
+
};
|
|
1265
|
+
var TabsList_default = TabsList;
|
|
1266
|
+
var TabsPanel = ({ value, children, ...rest }) => {
|
|
1267
|
+
const { value: activeValue, prefix } = useTabsContext();
|
|
1268
|
+
const isActive = value === activeValue;
|
|
1269
|
+
const getTabId = (val) => prefix ? `tab-${prefix}-${val}` : `tab-${val}`;
|
|
1270
|
+
const getTabPanelId = (val) => prefix ? `tabpanel-${prefix}-${val}` : `tabpanel-${val}`;
|
|
1271
|
+
return /* @__PURE__ */ jsx(
|
|
1272
|
+
"div",
|
|
1273
|
+
{
|
|
1274
|
+
role: "tabpanel",
|
|
1275
|
+
id: getTabPanelId(value),
|
|
1276
|
+
"aria-labelledby": getTabId(value),
|
|
1277
|
+
hidden: !isActive,
|
|
1278
|
+
...rest,
|
|
1279
|
+
className: clsx15("ui:mt-4", rest.className),
|
|
1280
|
+
children
|
|
1281
|
+
}
|
|
1282
|
+
);
|
|
1283
|
+
};
|
|
1284
|
+
var TabsPanel_default = TabsPanel;
|
|
1285
|
+
var TabsTrigger = ({
|
|
1286
|
+
value,
|
|
1287
|
+
icon,
|
|
1288
|
+
disabled,
|
|
1289
|
+
className,
|
|
1290
|
+
children,
|
|
1291
|
+
...rest
|
|
1292
|
+
}) => {
|
|
1293
|
+
const {
|
|
1294
|
+
value: activeValue,
|
|
1295
|
+
onValueChange,
|
|
1296
|
+
variant,
|
|
1297
|
+
prefix
|
|
1298
|
+
} = useTabsContext();
|
|
1299
|
+
const { registerTrigger, unregisterTrigger, getTriggers, isDisabled } = useTabsListContext();
|
|
1300
|
+
const isActive = value === activeValue;
|
|
1301
|
+
const getTabId = (val) => prefix ? `tab-${prefix}-${val}` : `tab-${val}`;
|
|
1302
|
+
const getTabPanelId = (val) => prefix ? `tabpanel-${prefix}-${val}` : `tabpanel-${val}`;
|
|
1303
|
+
useEffect(() => {
|
|
1304
|
+
registerTrigger(value, disabled);
|
|
1305
|
+
return () => {
|
|
1306
|
+
unregisterTrigger(value);
|
|
1307
|
+
};
|
|
1308
|
+
}, [value, disabled, registerTrigger, unregisterTrigger]);
|
|
1309
|
+
const handleClick = () => {
|
|
1310
|
+
if (!disabled) {
|
|
1311
|
+
onValueChange(value);
|
|
1312
|
+
}
|
|
1313
|
+
};
|
|
1314
|
+
const findNextEnabledTab = (triggers, startIndex, direction) => {
|
|
1315
|
+
const length = triggers.length;
|
|
1316
|
+
let index = startIndex;
|
|
1317
|
+
for (let i = 0; i < length; i++) {
|
|
1318
|
+
index = (index + direction + length) % length;
|
|
1319
|
+
if (!isDisabled(triggers[index])) {
|
|
1320
|
+
return index;
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
return startIndex;
|
|
1324
|
+
};
|
|
1325
|
+
const handleKeyDown = (event) => {
|
|
1326
|
+
if (disabled) return;
|
|
1327
|
+
const triggers = getTriggers();
|
|
1328
|
+
const currentIndex = triggers.indexOf(value);
|
|
1329
|
+
let newIndex = currentIndex;
|
|
1330
|
+
switch (event.key) {
|
|
1331
|
+
case "ArrowLeft":
|
|
1332
|
+
event.preventDefault();
|
|
1333
|
+
newIndex = findNextEnabledTab(triggers, currentIndex, -1);
|
|
1334
|
+
break;
|
|
1335
|
+
case "ArrowRight":
|
|
1336
|
+
event.preventDefault();
|
|
1337
|
+
newIndex = findNextEnabledTab(triggers, currentIndex, 1);
|
|
1338
|
+
break;
|
|
1339
|
+
case "Home":
|
|
1340
|
+
event.preventDefault();
|
|
1341
|
+
newIndex = 0;
|
|
1342
|
+
while (newIndex < triggers.length && isDisabled(triggers[newIndex])) {
|
|
1343
|
+
newIndex++;
|
|
1344
|
+
}
|
|
1345
|
+
break;
|
|
1346
|
+
case "End":
|
|
1347
|
+
event.preventDefault();
|
|
1348
|
+
newIndex = triggers.length - 1;
|
|
1349
|
+
while (newIndex >= 0 && isDisabled(triggers[newIndex])) {
|
|
1350
|
+
newIndex--;
|
|
1351
|
+
}
|
|
1352
|
+
break;
|
|
1353
|
+
default:
|
|
1354
|
+
return;
|
|
1355
|
+
}
|
|
1356
|
+
const newValue = triggers[newIndex];
|
|
1357
|
+
if (newValue && newValue !== value) {
|
|
1358
|
+
onValueChange(newValue);
|
|
1359
|
+
}
|
|
1360
|
+
};
|
|
1361
|
+
return /* @__PURE__ */ jsxs(
|
|
1362
|
+
"button",
|
|
1363
|
+
{
|
|
1364
|
+
type: "button",
|
|
1365
|
+
role: "tab",
|
|
1366
|
+
"aria-selected": isActive ? "true" : "false",
|
|
1367
|
+
"aria-controls": getTabPanelId(value),
|
|
1368
|
+
id: getTabId(value),
|
|
1369
|
+
tabIndex: isActive ? 0 : -1,
|
|
1370
|
+
disabled,
|
|
1371
|
+
className: clsx15(
|
|
1372
|
+
"ui:px-4 ui:py-2 ui:font-roboto ui:text-sm ui:font-medium",
|
|
1373
|
+
"ui:flex ui:items-center ui:gap-2",
|
|
1374
|
+
"ui:transition-colors ui:duration-200",
|
|
1375
|
+
"focus-visible:ui:outline-none focus-visible:ui:ring-2 focus-visible:ui:ring-ring focus-visible:ui:ring-offset-2",
|
|
1376
|
+
!disabled && "ui:cursor-pointer",
|
|
1377
|
+
variant === "underline" && [
|
|
1378
|
+
"ui:relative ui:border-b-2 ui:border-transparent ui:-mb-px",
|
|
1379
|
+
isActive ? "ui:text-primary ui:border-primary" : "ui:text-foreground hover:ui:text-foreground",
|
|
1380
|
+
disabled && "ui:text-muted-foreground/50 ui:cursor-not-allowed hover:ui:text-muted-foreground/50"
|
|
1381
|
+
],
|
|
1382
|
+
variant === "pills" && [
|
|
1383
|
+
"ui:rounded-md",
|
|
1384
|
+
isActive ? "ui:bg-primary ui:shadow-sm" : "ui:text-foreground hover:ui:text-foreground",
|
|
1385
|
+
disabled && "ui:text-muted-foreground/50 ui:cursor-not-allowed hover:ui:text-muted-foreground/50"
|
|
1386
|
+
],
|
|
1387
|
+
className
|
|
1388
|
+
),
|
|
1389
|
+
onClick: handleClick,
|
|
1390
|
+
onKeyDown: handleKeyDown,
|
|
1391
|
+
...rest,
|
|
1392
|
+
children: [
|
|
1393
|
+
icon && icon,
|
|
1394
|
+
children
|
|
1395
|
+
]
|
|
1396
|
+
}
|
|
1397
|
+
);
|
|
1398
|
+
};
|
|
1399
|
+
var TabsTrigger_default = TabsTrigger;
|
|
1400
|
+
var Tabs = ({
|
|
1401
|
+
defaultValue = "",
|
|
1402
|
+
value,
|
|
1403
|
+
onValueChange,
|
|
1404
|
+
variant = "underline",
|
|
1405
|
+
prefix,
|
|
1406
|
+
className,
|
|
1407
|
+
children,
|
|
1408
|
+
...rest
|
|
1409
|
+
}) => {
|
|
1410
|
+
const [internalValue, setInternalValue] = useState(defaultValue);
|
|
1411
|
+
const activeValue = value ?? internalValue;
|
|
1412
|
+
const isControlled = value !== void 0;
|
|
1413
|
+
const handleValueChange = (newValue) => {
|
|
1414
|
+
if (!isControlled) {
|
|
1415
|
+
setInternalValue(newValue);
|
|
1416
|
+
}
|
|
1417
|
+
onValueChange?.(newValue);
|
|
1418
|
+
};
|
|
1419
|
+
return /* @__PURE__ */ jsx(
|
|
1420
|
+
TabsContext.Provider,
|
|
1421
|
+
{
|
|
1422
|
+
value: {
|
|
1423
|
+
value: activeValue,
|
|
1424
|
+
onValueChange: handleValueChange,
|
|
1425
|
+
variant,
|
|
1426
|
+
prefix
|
|
1427
|
+
},
|
|
1428
|
+
children: /* @__PURE__ */ jsx("div", { className: clsx15("ui:w-full", className), ...rest, children })
|
|
1429
|
+
}
|
|
1430
|
+
);
|
|
1431
|
+
};
|
|
1432
|
+
Tabs.List = TabsList_default;
|
|
1433
|
+
Tabs.Trigger = TabsTrigger_default;
|
|
1434
|
+
Tabs.Panel = TabsPanel_default;
|
|
1435
|
+
var Tabs_default = Tabs;
|
|
1436
|
+
var Talent = ({
|
|
1437
|
+
name,
|
|
1438
|
+
role,
|
|
1439
|
+
imageSrc,
|
|
1440
|
+
variant = "vertical",
|
|
1441
|
+
size = "lg",
|
|
1442
|
+
className,
|
|
1443
|
+
...rest
|
|
1444
|
+
}) => {
|
|
1445
|
+
return /* @__PURE__ */ jsxs(
|
|
1446
|
+
"div",
|
|
1447
|
+
{
|
|
1448
|
+
className: clsx15(
|
|
1449
|
+
"ui:flex ui:items-center",
|
|
1450
|
+
{
|
|
1451
|
+
"ui:flex-col ui:text-center ui:gap-3": variant === "vertical",
|
|
1452
|
+
"ui:flex-row ui:gap-4": variant === "horizontal"
|
|
1453
|
+
},
|
|
1454
|
+
className
|
|
1455
|
+
),
|
|
1456
|
+
"data-testid": "talent",
|
|
1457
|
+
...rest,
|
|
1458
|
+
children: [
|
|
1459
|
+
/* @__PURE__ */ jsx(
|
|
1460
|
+
Avatar_default,
|
|
1461
|
+
{
|
|
1462
|
+
testId: "avatar",
|
|
1463
|
+
src: imageSrc,
|
|
1464
|
+
alt: name ?? "Unknown",
|
|
1465
|
+
size
|
|
1466
|
+
}
|
|
1467
|
+
),
|
|
1468
|
+
/* @__PURE__ */ jsxs(
|
|
1469
|
+
"div",
|
|
1470
|
+
{
|
|
1471
|
+
className: clsx15({ "ui:flex ui:flex-col": variant === "horizontal" }),
|
|
1472
|
+
children: [
|
|
1473
|
+
/* @__PURE__ */ jsx(
|
|
1474
|
+
Typography_default,
|
|
1475
|
+
{
|
|
1476
|
+
variant: "body",
|
|
1477
|
+
className: "ui:font-semibold ui:text-foreground",
|
|
1478
|
+
children: name ?? "Unknown"
|
|
1479
|
+
}
|
|
1480
|
+
),
|
|
1481
|
+
/* @__PURE__ */ jsx(
|
|
1482
|
+
Typography_default,
|
|
1483
|
+
{
|
|
1484
|
+
variant: "caption",
|
|
1485
|
+
className: "ui:text-muted-foreground ui:[.media-section:nth-of-type(odd)_&]:text-badge-foreground",
|
|
1486
|
+
children: role ?? "N/A"
|
|
1487
|
+
}
|
|
1488
|
+
)
|
|
1489
|
+
]
|
|
1490
|
+
}
|
|
1491
|
+
)
|
|
1492
|
+
]
|
|
1493
|
+
}
|
|
1494
|
+
);
|
|
1495
|
+
};
|
|
1496
|
+
var Talent_default = Talent;
|
|
1497
|
+
var Spinner = ({ className }) => {
|
|
1498
|
+
return /* @__PURE__ */ jsx(
|
|
1499
|
+
"div",
|
|
1500
|
+
{
|
|
1501
|
+
role: "status",
|
|
1502
|
+
"aria-label": "Loading",
|
|
1503
|
+
className: clsx15(
|
|
1504
|
+
"ui:size-12 ui:rounded-full ui:border-4 ui:border-white/20 ui:border-t-white ui:animate-spin",
|
|
1505
|
+
className
|
|
1506
|
+
)
|
|
1507
|
+
}
|
|
1508
|
+
);
|
|
1509
|
+
};
|
|
1510
|
+
var Spinner_default = Spinner;
|
|
1511
|
+
|
|
1512
|
+
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, Image_default as Image, Modal_default as Modal, MovieCard_default as MovieCard, Rating_default as Rating, Skeleton_default as Skeleton, Spinner_default as Spinner, Tabs_default as Tabs, Talent_default as Talent, TrailerCard_default as TrailerCard, Typography_default as Typography };
|
|
1513
|
+
//# sourceMappingURL=index.js.map
|
|
1514
|
+
//# sourceMappingURL=index.js.map
|