@avenue-ticketing/ui 0.4.0 → 0.5.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.
Files changed (73) hide show
  1. package/dist/react/avatar.d.ts +42 -0
  2. package/dist/react/avatar.js +159 -0
  3. package/dist/react/avatar.js.map +1 -0
  4. package/dist/react/badge.d.ts +12 -0
  5. package/dist/react/badge.js +35 -1
  6. package/dist/react/badge.js.map +1 -1
  7. package/dist/react/button.d.ts +1 -1
  8. package/dist/react/button.js +3 -3
  9. package/dist/react/button.js.map +1 -1
  10. package/dist/react/calendar.d.ts +13 -0
  11. package/dist/react/calendar.js +4639 -0
  12. package/dist/react/calendar.js.map +1 -0
  13. package/dist/react/card.d.ts +11 -0
  14. package/dist/react/card.js +113 -0
  15. package/dist/react/card.js.map +1 -0
  16. package/dist/react/checkbox.d.ts +11 -0
  17. package/dist/react/checkbox.js +131 -0
  18. package/dist/react/checkbox.js.map +1 -0
  19. package/dist/react/datetime-picker.d.ts +21 -0
  20. package/dist/react/datetime-picker.js +6124 -0
  21. package/dist/react/datetime-picker.js.map +1 -0
  22. package/dist/react/dialog.js +1 -1
  23. package/dist/react/dialog.js.map +1 -1
  24. package/dist/react/dropdown.d.ts +26 -9
  25. package/dist/react/dropdown.js +194 -96
  26. package/dist/react/dropdown.js.map +1 -1
  27. package/dist/react/input.d.ts +7 -0
  28. package/dist/react/input.js +15 -2
  29. package/dist/react/input.js.map +1 -1
  30. package/dist/react/pagination.d.ts +28 -0
  31. package/dist/react/pagination.js +262 -0
  32. package/dist/react/pagination.js.map +1 -0
  33. package/dist/react/popover.d.ts +76 -0
  34. package/dist/react/popover.js +564 -0
  35. package/dist/react/popover.js.map +1 -0
  36. package/dist/react/scroll-header.js +13 -1
  37. package/dist/react/scroll-header.js.map +1 -1
  38. package/dist/react/scroll-wheel.d.ts +45 -0
  39. package/dist/react/scroll-wheel.js +557 -0
  40. package/dist/react/scroll-wheel.js.map +1 -0
  41. package/dist/react/select.d.ts +62 -0
  42. package/dist/react/select.js +889 -0
  43. package/dist/react/select.js.map +1 -0
  44. package/dist/react/sheet.js +1 -1
  45. package/dist/react/sheet.js.map +1 -1
  46. package/dist/react/switch.d.ts +38 -0
  47. package/dist/react/switch.js +117 -0
  48. package/dist/react/switch.js.map +1 -0
  49. package/dist/react/table-pagination.d.ts +15 -0
  50. package/dist/react/table-pagination.js +1153 -0
  51. package/dist/react/table-pagination.js.map +1 -0
  52. package/dist/react/table-view/column-menu.d.ts +15 -0
  53. package/dist/react/table-view/column-menu.js +918 -0
  54. package/dist/react/table-view/column-menu.js.map +1 -0
  55. package/dist/react/table-view/index.d.ts +70 -0
  56. package/dist/react/table-view/index.js +2155 -0
  57. package/dist/react/table-view/index.js.map +1 -0
  58. package/dist/react/table.d.ts +86 -0
  59. package/dist/react/table.js +414 -0
  60. package/dist/react/table.js.map +1 -0
  61. package/dist/react/tabs.d.ts +9 -3
  62. package/dist/react/tabs.js +204 -48
  63. package/dist/react/tabs.js.map +1 -1
  64. package/dist/react/textarea.d.ts +6 -0
  65. package/dist/react/textarea.js +33 -0
  66. package/dist/react/textarea.js.map +1 -0
  67. package/dist/react/time-picker.d.ts +22 -0
  68. package/dist/react/time-picker.js +856 -0
  69. package/dist/react/time-picker.js.map +1 -0
  70. package/dist/react/tooltip.d.ts +45 -0
  71. package/dist/react/tooltip.js +540 -0
  72. package/dist/react/tooltip.js.map +1 -0
  73. package/package.json +1 -1
@@ -0,0 +1,564 @@
1
+ import React, { useState, useRef, useCallback, useMemo, useEffect, useLayoutEffect } from 'react';
2
+ import { createPortal } from 'react-dom';
3
+ import { X } from 'lucide-react';
4
+ import { clsx } from 'clsx';
5
+ import { twMerge } from 'tailwind-merge';
6
+ import { jsxs, jsx } from 'react/jsx-runtime';
7
+
8
+ function cn(...inputs) {
9
+ return twMerge(clsx(inputs));
10
+ }
11
+ var POPOVER_MOBILE_SHEET_MAX_PX = 1024;
12
+ var POPOVER_MOBILE_SHEET_MOTION_MS = 175;
13
+ var POPOVER_MOBILE_SHEET_ENTRY_EASING = "cubic-bezier(0.85, 0, 0.15, 1)";
14
+ var POPOVER_MOBILE_SHEET_EXIT_EASING = "cubic-bezier(0.85, 0, 1, 0.15)";
15
+ var POPOVER_MOBILE_SHEET_SLIDE_ENTRANCE_OFFSET_DEFAULT_PX = 120;
16
+ function usePopoverIsMobile(breakpoint = 1025) {
17
+ const [isMobile, setIsMobile] = useState(false);
18
+ useEffect(() => {
19
+ const mq = window.matchMedia(`(max-width: ${breakpoint - 1}px)`);
20
+ setIsMobile(mq.matches);
21
+ const handler = (e) => setIsMobile(e.matches);
22
+ mq.addEventListener("change", handler);
23
+ return () => mq.removeEventListener("change", handler);
24
+ }, [breakpoint]);
25
+ return isMobile;
26
+ }
27
+ var PopoverContext = React.createContext(
28
+ void 0
29
+ );
30
+ function usePopover() {
31
+ const context = React.useContext(PopoverContext);
32
+ if (!context) {
33
+ throw new Error("Popover components must be used within a <Popover />");
34
+ }
35
+ return context;
36
+ }
37
+ var Popover = ({ children, open: controlledOpen, onOpenChange }) => {
38
+ const [internalOpen, setInternalOpen] = useState(false);
39
+ const isControlled = controlledOpen !== void 0;
40
+ const open = isControlled ? controlledOpen : internalOpen;
41
+ const triggerRef = useRef(null);
42
+ const setOpen = useCallback(
43
+ (value) => {
44
+ if (!isControlled) setInternalOpen(value);
45
+ onOpenChange?.(value);
46
+ },
47
+ [isControlled, onOpenChange]
48
+ );
49
+ return /* @__PURE__ */ jsx(PopoverContext.Provider, { value: { open, setOpen, triggerRef }, children });
50
+ };
51
+ var PopoverTrigger = ({ children, asChild }) => {
52
+ const { open, setOpen, triggerRef } = usePopover();
53
+ const handleClick = (e) => {
54
+ e.stopPropagation();
55
+ setOpen(!open);
56
+ };
57
+ if (asChild && React.isValidElement(children)) {
58
+ const child = children;
59
+ return React.cloneElement(child, {
60
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
61
+ ref: (el) => {
62
+ triggerRef.current = el;
63
+ },
64
+ onClick: (e) => {
65
+ child.props.onClick?.(e);
66
+ handleClick(e);
67
+ }
68
+ });
69
+ }
70
+ return /* @__PURE__ */ jsx(
71
+ "button",
72
+ {
73
+ type: "button",
74
+ ref: (el) => {
75
+ triggerRef.current = el;
76
+ },
77
+ onClick: handleClick,
78
+ children
79
+ }
80
+ );
81
+ };
82
+ var PopoverClose = ({ children, asChild }) => {
83
+ const { setOpen } = usePopover();
84
+ const handleClick = () => setOpen(false);
85
+ if (asChild && React.isValidElement(children)) {
86
+ const child = children;
87
+ return React.cloneElement(child, {
88
+ onClick: (e) => {
89
+ child.props.onClick?.(e);
90
+ handleClick();
91
+ }
92
+ });
93
+ }
94
+ return /* @__PURE__ */ jsx("button", { type: "button", onClick: handleClick, children });
95
+ };
96
+ function resolvePopoverMobileSheet(mobileOptions) {
97
+ return {
98
+ sheet: mobileOptions?.sheet ?? false,
99
+ title: mobileOptions?.title,
100
+ sheetExtraClassName: mobileOptions?.className,
101
+ contentClassName: mobileOptions?.contentClassName
102
+ };
103
+ }
104
+ var PopoverMobileClose = React.forwardRef(({ className, type = "button", ...props }, ref) => {
105
+ return /* @__PURE__ */ jsxs(
106
+ "button",
107
+ {
108
+ ref,
109
+ type,
110
+ className: cn(
111
+ "z-100 flex size-12 shrink-0 cursor-pointer items-center justify-center rounded-full transition-all hover:bg-secondary-background active:scale-[0.96]",
112
+ className
113
+ ),
114
+ ...props,
115
+ children: [
116
+ /* @__PURE__ */ jsx(X, { className: "size-5.5" }),
117
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
118
+ ]
119
+ }
120
+ );
121
+ });
122
+ PopoverMobileClose.displayName = "PopoverMobileClose";
123
+ function PopoverMobileBottomSheetPortal({
124
+ open,
125
+ isAnimating,
126
+ slideEntrance,
127
+ slideOffsetPx,
128
+ sheetTitle,
129
+ sheetExtraClassName,
130
+ contentClassName,
131
+ onRequestClose,
132
+ menuRef,
133
+ dismissOnBackdropPress = true,
134
+ children,
135
+ className,
136
+ style,
137
+ ...panelProps
138
+ }) {
139
+ const sheetMotion = open ? POPOVER_MOBILE_SHEET_ENTRY_EASING : POPOVER_MOBILE_SHEET_EXIT_EASING;
140
+ const sheetHiddenTransform = slideEntrance ? `translateY(${slideOffsetPx}px)` : "translateY(100%)";
141
+ return createPortal(
142
+ /* @__PURE__ */ jsxs("div", { className: "fixed inset-0 z-50 flex items-end justify-center p-0", children: [
143
+ /* @__PURE__ */ jsx(
144
+ "div",
145
+ {
146
+ className: cn(
147
+ "fixed inset-0 bg-black/40 dark:bg-black/60",
148
+ isAnimating ? "opacity-100" : "opacity-0"
149
+ ),
150
+ style: {
151
+ transitionProperty: "opacity",
152
+ transitionDuration: `${POPOVER_MOBILE_SHEET_MOTION_MS}ms`,
153
+ transitionTimingFunction: sheetMotion
154
+ },
155
+ onClick: dismissOnBackdropPress ? onRequestClose : void 0,
156
+ "aria-hidden": true
157
+ }
158
+ ),
159
+ /* @__PURE__ */ jsxs(
160
+ "div",
161
+ {
162
+ ...panelProps,
163
+ ref: menuRef,
164
+ className: cn(
165
+ // Panel chrome + padding rhythm matches `DropdownMobileBottomSheetPortal`.
166
+ "bg-background border-primary/10 relative z-10 flex w-full max-h-[min(90dvh,calc(100dvh-env(safe-area-inset-bottom,0px)))] flex-col overflow-hidden shadow-2xl outline-none",
167
+ "rounded-t-2xl rounded-b-none border-x-0 border-b-0 border-t",
168
+ sheetExtraClassName,
169
+ className
170
+ ),
171
+ style: {
172
+ transform: isAnimating ? "translateY(0)" : sheetHiddenTransform,
173
+ opacity: isAnimating ? 1 : 0,
174
+ transitionProperty: "transform, opacity",
175
+ transitionDuration: `${POPOVER_MOBILE_SHEET_MOTION_MS}ms`,
176
+ transitionTimingFunction: sheetMotion,
177
+ ...style
178
+ },
179
+ children: [
180
+ /* @__PURE__ */ jsxs(
181
+ "div",
182
+ {
183
+ className: cn(
184
+ "flex w-full shrink-0 items-center py-2 pl-4 pr-2",
185
+ sheetTitle ? "justify-between gap-3" : "justify-end"
186
+ ),
187
+ children: [
188
+ sheetTitle ? /* @__PURE__ */ jsx("p", { className: "text-foreground min-w-0 flex-1 truncate text-base font-semibold", children: sheetTitle }) : null,
189
+ /* @__PURE__ */ jsx(
190
+ PopoverMobileClose,
191
+ {
192
+ onClick: (e) => {
193
+ e.stopPropagation();
194
+ onRequestClose();
195
+ }
196
+ }
197
+ )
198
+ ]
199
+ }
200
+ ),
201
+ /* @__PURE__ */ jsx(
202
+ "div",
203
+ {
204
+ className: cn(
205
+ "min-h-0 flex-1 overflow-y-auto px-4 pt-3",
206
+ contentClassName,
207
+ "pb-[calc(5rem+env(safe-area-inset-bottom,0px))]"
208
+ ),
209
+ children
210
+ }
211
+ )
212
+ ]
213
+ }
214
+ )
215
+ ] }),
216
+ document.body
217
+ );
218
+ }
219
+ function computePosition(trigger, popover, side, align, offset, viewportPadding) {
220
+ const triggerRect = trigger.getBoundingClientRect();
221
+ const pw = popover.offsetWidth;
222
+ const ph = popover.offsetHeight;
223
+ const vw = window.innerWidth;
224
+ const vh = window.innerHeight;
225
+ let top = 0;
226
+ let left = 0;
227
+ let effectiveSide = side;
228
+ const place = (s) => {
229
+ switch (s) {
230
+ case "bottom":
231
+ top = triggerRect.bottom + offset;
232
+ break;
233
+ case "top":
234
+ top = triggerRect.top - ph - offset;
235
+ break;
236
+ case "right":
237
+ left = triggerRect.right + offset;
238
+ top = align === "start" ? triggerRect.top : align === "end" ? triggerRect.bottom - ph : triggerRect.top + triggerRect.height / 2 - ph / 2;
239
+ return;
240
+ case "left":
241
+ left = triggerRect.left - pw - offset;
242
+ top = align === "start" ? triggerRect.top : align === "end" ? triggerRect.bottom - ph : triggerRect.top + triggerRect.height / 2 - ph / 2;
243
+ return;
244
+ }
245
+ if (align === "start") left = triggerRect.left;
246
+ else if (align === "end") left = triggerRect.right - pw;
247
+ else left = triggerRect.left + triggerRect.width / 2 - pw / 2;
248
+ };
249
+ place(side);
250
+ const tryFlip = () => {
251
+ if (side === "bottom" && top + ph > vh - viewportPadding) {
252
+ const flipped = "top";
253
+ const newTop = triggerRect.top - ph - offset;
254
+ if (newTop >= viewportPadding) {
255
+ effectiveSide = flipped;
256
+ top = newTop;
257
+ }
258
+ } else if (side === "top" && top < viewportPadding) {
259
+ const flipped = "bottom";
260
+ const newTop = triggerRect.bottom + offset;
261
+ if (newTop + ph <= vh - viewportPadding) {
262
+ effectiveSide = flipped;
263
+ top = newTop;
264
+ }
265
+ } else if (side === "right" && left + pw > vw - viewportPadding) {
266
+ const flipped = "left";
267
+ const newLeft = triggerRect.left - pw - offset;
268
+ if (newLeft >= viewportPadding) {
269
+ effectiveSide = flipped;
270
+ left = newLeft;
271
+ }
272
+ } else if (side === "left" && left < viewportPadding) {
273
+ const flipped = "right";
274
+ const newLeft = triggerRect.right + offset;
275
+ if (newLeft + pw <= vw - viewportPadding) {
276
+ effectiveSide = flipped;
277
+ left = newLeft;
278
+ }
279
+ }
280
+ };
281
+ tryFlip();
282
+ left = Math.max(
283
+ viewportPadding,
284
+ Math.min(left, vw - pw - viewportPadding)
285
+ );
286
+ top = Math.max(
287
+ viewportPadding,
288
+ Math.min(top, vh - ph - viewportPadding)
289
+ );
290
+ return { top, left, side: effectiveSide };
291
+ }
292
+ var ARROW_SIZE = 6;
293
+ var PopoverContent = ({
294
+ children,
295
+ side = "bottom",
296
+ align = "center",
297
+ offset = 10,
298
+ showArrow = false,
299
+ closeOnClickOutside = true,
300
+ closeOnEscape = true,
301
+ duration = 80,
302
+ viewportPadding = 8,
303
+ container,
304
+ width = "auto",
305
+ mobileOptions,
306
+ slideEntrance = true,
307
+ slideEntranceOffsetPx: slideEntranceOffsetPxProp,
308
+ className,
309
+ style,
310
+ ...props
311
+ }) => {
312
+ const { open, setOpen, triggerRef } = usePopover();
313
+ const isMobile = usePopoverIsMobile(POPOVER_MOBILE_SHEET_MAX_PX + 1);
314
+ const resolvedMobile = useMemo(
315
+ () => resolvePopoverMobileSheet(mobileOptions),
316
+ [mobileOptions]
317
+ );
318
+ const sheetMode = isMobile && resolvedMobile.sheet;
319
+ const slideOffsetPx = useMemo(
320
+ () => slideEntranceOffsetPxProp ?? POPOVER_MOBILE_SHEET_SLIDE_ENTRANCE_OFFSET_DEFAULT_PX,
321
+ [slideEntranceOffsetPxProp]
322
+ );
323
+ const closeDuration = sheetMode ? POPOVER_MOBILE_SHEET_MOTION_MS : duration;
324
+ const [shouldRender, setShouldRender] = useState(false);
325
+ const [isAnimating, setIsAnimating] = useState(false);
326
+ const [position, setPosition] = useState({
327
+ top: -9999,
328
+ left: -9999,
329
+ side
330
+ });
331
+ const [triggerWidth, setTriggerWidth] = useState(0);
332
+ const popoverRef = useRef(null);
333
+ const closePopover = useCallback(() => setOpen(false), [setOpen]);
334
+ useEffect(() => {
335
+ if (open) {
336
+ setShouldRender(true);
337
+ } else {
338
+ setIsAnimating(false);
339
+ const timer = setTimeout(() => setShouldRender(false), closeDuration);
340
+ return () => clearTimeout(timer);
341
+ }
342
+ }, [open, closeDuration]);
343
+ useEffect(() => {
344
+ if (!shouldRender || !open) return;
345
+ let raf2 = 0;
346
+ const raf1 = requestAnimationFrame(() => {
347
+ raf2 = requestAnimationFrame(() => setIsAnimating(true));
348
+ });
349
+ return () => {
350
+ cancelAnimationFrame(raf1);
351
+ if (raf2) cancelAnimationFrame(raf2);
352
+ };
353
+ }, [shouldRender, open]);
354
+ useLayoutEffect(() => {
355
+ if (!shouldRender || !open || sheetMode || !triggerRef.current || !popoverRef.current)
356
+ return;
357
+ const update = () => {
358
+ if (!triggerRef.current || !popoverRef.current) return;
359
+ setTriggerWidth(triggerRef.current.getBoundingClientRect().width);
360
+ const pos = computePosition(
361
+ triggerRef.current,
362
+ popoverRef.current,
363
+ side,
364
+ align,
365
+ offset,
366
+ viewportPadding
367
+ );
368
+ setPosition(pos);
369
+ };
370
+ update();
371
+ window.addEventListener("resize", update);
372
+ window.addEventListener("scroll", update, true);
373
+ return () => {
374
+ window.removeEventListener("resize", update);
375
+ window.removeEventListener("scroll", update, true);
376
+ };
377
+ }, [shouldRender, open, sheetMode, side, align, offset, viewportPadding]);
378
+ useEffect(() => {
379
+ if (open && sheetMode) {
380
+ document.body.style.overflow = "hidden";
381
+ }
382
+ return () => {
383
+ document.body.style.overflow = "";
384
+ };
385
+ }, [open, sheetMode]);
386
+ useEffect(() => {
387
+ if (!open || !closeOnClickOutside || sheetMode) return;
388
+ const handler = (e) => {
389
+ const target = e.target;
390
+ if (popoverRef.current?.contains(target) || triggerRef.current?.contains(target))
391
+ return;
392
+ setOpen(false);
393
+ };
394
+ document.addEventListener("mousedown", handler);
395
+ return () => document.removeEventListener("mousedown", handler);
396
+ }, [open, closeOnClickOutside, sheetMode, setOpen, triggerRef]);
397
+ useEffect(() => {
398
+ if (!open || !closeOnEscape) return;
399
+ const handler = (e) => {
400
+ if (e.key === "Escape") setOpen(false);
401
+ };
402
+ window.addEventListener("keydown", handler);
403
+ return () => window.removeEventListener("keydown", handler);
404
+ }, [open, closeOnEscape, setOpen]);
405
+ if (!shouldRender) return null;
406
+ if (sheetMode && typeof document !== "undefined") {
407
+ return /* @__PURE__ */ jsx(
408
+ PopoverMobileBottomSheetPortal,
409
+ {
410
+ ...props,
411
+ open,
412
+ isAnimating,
413
+ slideEntrance,
414
+ slideOffsetPx,
415
+ sheetTitle: resolvedMobile.title,
416
+ sheetExtraClassName: resolvedMobile.sheetExtraClassName,
417
+ contentClassName: cn(resolvedMobile.contentClassName, className),
418
+ onRequestClose: closePopover,
419
+ dismissOnBackdropPress: closeOnClickOutside,
420
+ menuRef: popoverRef,
421
+ role: "dialog",
422
+ "aria-modal": "true",
423
+ tabIndex: -1,
424
+ className: void 0,
425
+ style,
426
+ "data-slot": "popover-content",
427
+ children
428
+ }
429
+ );
430
+ }
431
+ const transformOrigin = {
432
+ bottom: "top center",
433
+ top: "bottom center",
434
+ left: "right center",
435
+ right: "left center"
436
+ };
437
+ const hiddenTransform = {
438
+ bottom: "translateY(-6px) scale(0.97)",
439
+ top: "translateY(6px) scale(0.97)",
440
+ left: "translateX(6px) scale(0.97)",
441
+ right: "translateX(-6px) scale(0.97)"
442
+ };
443
+ const resolvedWidth = width === "trigger" ? triggerWidth : width === "auto" ? void 0 : width;
444
+ const arrowStyles = () => {
445
+ const base = {
446
+ position: "absolute",
447
+ width: 0,
448
+ height: 0,
449
+ pointerEvents: "none"
450
+ };
451
+ switch (position.side) {
452
+ case "bottom":
453
+ return {
454
+ ...base,
455
+ top: -ARROW_SIZE,
456
+ left: "50%",
457
+ transform: "translateX(-50%)",
458
+ borderLeft: `${ARROW_SIZE}px solid transparent`,
459
+ borderRight: `${ARROW_SIZE}px solid transparent`,
460
+ borderBottom: `${ARROW_SIZE}px solid var(--border)`
461
+ };
462
+ case "top":
463
+ return {
464
+ ...base,
465
+ bottom: -ARROW_SIZE,
466
+ left: "50%",
467
+ transform: "translateX(-50%)",
468
+ borderLeft: `${ARROW_SIZE}px solid transparent`,
469
+ borderRight: `${ARROW_SIZE}px solid transparent`,
470
+ borderTop: `${ARROW_SIZE}px solid var(--border)`
471
+ };
472
+ case "right":
473
+ return {
474
+ ...base,
475
+ left: -ARROW_SIZE,
476
+ top: "50%",
477
+ transform: "translateY(-50%)",
478
+ borderTop: `${ARROW_SIZE}px solid transparent`,
479
+ borderBottom: `${ARROW_SIZE}px solid transparent`,
480
+ borderRight: `${ARROW_SIZE}px solid var(--border)`
481
+ };
482
+ case "left":
483
+ return {
484
+ ...base,
485
+ right: -ARROW_SIZE,
486
+ top: "50%",
487
+ transform: "translateY(-50%)",
488
+ borderTop: `${ARROW_SIZE}px solid transparent`,
489
+ borderBottom: `${ARROW_SIZE}px solid transparent`,
490
+ borderLeft: `${ARROW_SIZE}px solid var(--border)`
491
+ };
492
+ }
493
+ };
494
+ const resolvedContainer = container !== void 0 ? container : typeof document !== "undefined" ? document.body : null;
495
+ if (!resolvedContainer) return null;
496
+ return createPortal(
497
+ /* @__PURE__ */ jsxs(
498
+ "div",
499
+ {
500
+ ...props,
501
+ ref: popoverRef,
502
+ className: cn(
503
+ "bg-background border-primary/10 fixed z-50 overflow-hidden rounded-xl border shadow-xl outline-none",
504
+ className
505
+ ),
506
+ "data-slot": "popover-content",
507
+ style: {
508
+ position: "fixed",
509
+ top: position.top,
510
+ left: position.left,
511
+ width: resolvedWidth,
512
+ transformOrigin: transformOrigin[position.side],
513
+ transform: isAnimating ? "none" : hiddenTransform[position.side],
514
+ opacity: isAnimating ? 1 : 0,
515
+ transition: `opacity ${duration}ms ease, transform ${duration}ms ease`,
516
+ ...style
517
+ },
518
+ children: [
519
+ showArrow && /* @__PURE__ */ jsx("div", { style: arrowStyles() }),
520
+ children
521
+ ]
522
+ }
523
+ ),
524
+ resolvedContainer
525
+ );
526
+ };
527
+ var PopoverHeader = ({
528
+ className,
529
+ ...props
530
+ }) => /* @__PURE__ */ jsx(
531
+ "div",
532
+ {
533
+ className: cn(
534
+ "border-primary/10 flex flex-col space-y-1 border-b px-4 py-3",
535
+ className
536
+ ),
537
+ ...props
538
+ }
539
+ );
540
+ var PopoverFooter = ({
541
+ className,
542
+ ...props
543
+ }) => /* @__PURE__ */ jsx(
544
+ "div",
545
+ {
546
+ className: cn(
547
+ "border-primary/10 flex flex-row justify-end gap-2 border-t px-4 py-3",
548
+ className
549
+ ),
550
+ ...props
551
+ }
552
+ );
553
+ var PopoverTitle = ({ className, ...props }) => /* @__PURE__ */ jsx(
554
+ "h4",
555
+ {
556
+ className: cn("text-primary text-sm leading-none font-semibold", className),
557
+ ...props
558
+ }
559
+ );
560
+ var PopoverDescription = ({ className, ...props }) => /* @__PURE__ */ jsx("p", { className: cn("text-muted-foreground text-xs", className), ...props });
561
+
562
+ export { Popover, PopoverClose, PopoverContent, PopoverDescription, PopoverFooter, PopoverHeader, PopoverMobileClose, PopoverTitle, PopoverTrigger };
563
+ //# sourceMappingURL=popover.js.map
564
+ //# sourceMappingURL=popover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/lib/utils.ts","../../src/react/popover.tsx"],"names":[],"mappings":"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","file":"popover.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","\"use client\";\nimport React, {\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { X } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\n\n/** Mobile popover as bottom sheet — same cutoff and motion as {@link DropdownContent}. */\nconst POPOVER_MOBILE_SHEET_MAX_PX = 1024;\nconst POPOVER_MOBILE_SHEET_MOTION_MS = 175;\nconst POPOVER_MOBILE_SHEET_ENTRY_EASING = \"cubic-bezier(0.85, 0, 0.15, 1)\";\nconst POPOVER_MOBILE_SHEET_EXIT_EASING = \"cubic-bezier(0.85, 0, 1, 0.15)\";\nconst POPOVER_MOBILE_SHEET_SLIDE_ENTRANCE_OFFSET_DEFAULT_PX = 120;\n\nfunction usePopoverIsMobile(breakpoint = 1025): boolean {\n const [isMobile, setIsMobile] = useState(false);\n useEffect(() => {\n const mq = window.matchMedia(`(max-width: ${breakpoint - 1}px)`);\n setIsMobile(mq.matches);\n const handler = (e: MediaQueryListEvent) => setIsMobile(e.matches);\n mq.addEventListener(\"change\", handler);\n return () => mq.removeEventListener(\"change\", handler);\n }, [breakpoint]);\n return isMobile;\n}\n\n//////////////////////////////////////////////// Context\n\ntype PopoverContextValue = {\n open: boolean;\n setOpen: (open: boolean) => void;\n triggerRef: React.RefObject<HTMLElement | null>;\n};\n\nconst PopoverContext = React.createContext<PopoverContextValue | undefined>(\n undefined,\n);\n\nfunction usePopover() {\n const context = React.useContext(PopoverContext);\n if (!context) {\n throw new Error(\"Popover components must be used within a <Popover />\");\n }\n return context;\n}\n\n//////////////////////////////////////////////// Main\n\nexport const Popover: React.FC<{\n children: React.ReactNode;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n}> = ({ children, open: controlledOpen, onOpenChange }) => {\n const [internalOpen, setInternalOpen] = useState(false);\n const isControlled = controlledOpen !== undefined;\n const open = isControlled ? controlledOpen : internalOpen;\n const triggerRef = useRef<HTMLElement | null>(null);\n\n const setOpen = useCallback(\n (value: boolean) => {\n if (!isControlled) setInternalOpen(value);\n onOpenChange?.(value);\n },\n [isControlled, onOpenChange],\n );\n\n return (\n <PopoverContext.Provider value={{ open, setOpen, triggerRef }}>\n {children}\n </PopoverContext.Provider>\n );\n};\n\n//////////////////////////////////////////////// Trigger\n\nexport const PopoverTrigger: React.FC<{\n children: React.ReactNode;\n asChild?: boolean;\n}> = ({ children, asChild }) => {\n const { open, setOpen, triggerRef } = usePopover();\n\n const handleClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n setOpen(!open);\n };\n\n if (asChild && React.isValidElement(children)) {\n const child = children as React.ReactElement<{\n onClick?: React.MouseEventHandler;\n ref?: React.Ref<unknown>;\n }>;\n return React.cloneElement(child, {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ref: (el: HTMLElement) => {\n triggerRef.current = el;\n },\n onClick: (e: React.MouseEvent) => {\n child.props.onClick?.(e);\n handleClick(e);\n },\n } as Partial<typeof child.props>);\n }\n\n return (\n <button\n type=\"button\"\n ref={(el) => {\n triggerRef.current = el;\n }}\n onClick={handleClick}\n >\n {children}\n </button>\n );\n};\n\n//////////////////////////////////////////////// Close\n\nexport const PopoverClose: React.FC<{\n children: React.ReactNode;\n asChild?: boolean;\n}> = ({ children, asChild }) => {\n const { setOpen } = usePopover();\n const handleClick = () => setOpen(false);\n\n if (asChild && React.isValidElement(children)) {\n const child = children as React.ReactElement<{\n onClick?: React.MouseEventHandler;\n }>;\n return React.cloneElement(child, {\n onClick: (e: React.MouseEvent) => {\n child.props.onClick?.(e);\n handleClick();\n },\n } as Partial<typeof child.props>);\n }\n\n return (\n <button type=\"button\" onClick={handleClick}>\n {children}\n </button>\n );\n};\n\n//////////////////////////////////////////////// Mobile sheet (popover-specific; mirrors dropdown behavior)\n\n/**\n * Narrow-viewport (≤1024px) bottom-sheet options for {@link PopoverContent}.\n * `className` merges onto the sheet panel root (after base sheet styles).\n */\nexport interface PopoverMobileSheetOptions {\n /** When `true`, use a bottom sheet on narrow viewports. Default `false`. */\n sheet?: boolean;\n title?: string;\n className?: string;\n contentClassName?: string;\n}\n\nfunction resolvePopoverMobileSheet(\n mobileOptions: PopoverMobileSheetOptions | undefined,\n) {\n return {\n sheet: mobileOptions?.sheet ?? false,\n title: mobileOptions?.title,\n sheetExtraClassName: mobileOptions?.className,\n contentClassName: mobileOptions?.contentClassName,\n };\n}\n\nexport interface PopoverMobileCloseProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement> {}\n\n/**\n * Dismiss control for the mobile bottom-sheet popover. Styling matches\n * {@link DialogCloseButton} (circular hit target, X icon).\n */\nexport const PopoverMobileClose = React.forwardRef<\n HTMLButtonElement,\n PopoverMobileCloseProps\n>(({ className, type = \"button\", ...props }, ref) => {\n return (\n <button\n ref={ref}\n type={type}\n className={cn(\n \"z-100 flex size-12 shrink-0 cursor-pointer items-center justify-center rounded-full transition-all hover:bg-secondary-background active:scale-[0.96]\",\n className,\n )}\n {...props}\n >\n <X className=\"size-5.5\" />\n <span className=\"sr-only\">Close</span>\n </button>\n );\n});\nPopoverMobileClose.displayName = \"PopoverMobileClose\";\n\ninterface PopoverMobileBottomSheetPortalProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n \"ref\"\n> {\n children: React.ReactNode;\n open: boolean;\n isAnimating: boolean;\n slideEntrance: boolean;\n slideOffsetPx: number;\n sheetTitle?: string;\n sheetExtraClassName?: string;\n contentClassName?: string;\n onRequestClose: () => void;\n menuRef: React.RefObject<HTMLDivElement | null>;\n /** When `false`, scrim taps do not close (matches `closeOnClickOutside={false}`). */\n dismissOnBackdropPress?: boolean;\n}\n\nfunction PopoverMobileBottomSheetPortal({\n open,\n isAnimating,\n slideEntrance,\n slideOffsetPx,\n sheetTitle,\n sheetExtraClassName,\n contentClassName,\n onRequestClose,\n menuRef,\n dismissOnBackdropPress = true,\n children,\n className,\n style,\n ...panelProps\n}: PopoverMobileBottomSheetPortalProps) {\n const sheetMotion = open\n ? POPOVER_MOBILE_SHEET_ENTRY_EASING\n : POPOVER_MOBILE_SHEET_EXIT_EASING;\n const sheetHiddenTransform = slideEntrance\n ? `translateY(${slideOffsetPx}px)`\n : \"translateY(100%)\";\n\n return createPortal(\n <div className=\"fixed inset-0 z-50 flex items-end justify-center p-0\">\n <div\n className={cn(\n \"fixed inset-0 bg-black/40 dark:bg-black/60\",\n isAnimating ? \"opacity-100\" : \"opacity-0\",\n )}\n style={{\n transitionProperty: \"opacity\",\n transitionDuration: `${POPOVER_MOBILE_SHEET_MOTION_MS}ms`,\n transitionTimingFunction: sheetMotion,\n }}\n onClick={dismissOnBackdropPress ? onRequestClose : undefined}\n aria-hidden\n />\n <div\n {...panelProps}\n ref={menuRef}\n className={cn(\n // Panel chrome + padding rhythm matches `DropdownMobileBottomSheetPortal`.\n \"bg-background border-primary/10 relative z-10 flex w-full max-h-[min(90dvh,calc(100dvh-env(safe-area-inset-bottom,0px)))] flex-col overflow-hidden shadow-2xl outline-none\",\n \"rounded-t-2xl rounded-b-none border-x-0 border-b-0 border-t\",\n sheetExtraClassName,\n className,\n )}\n style={{\n transform: isAnimating ? \"translateY(0)\" : sheetHiddenTransform,\n opacity: isAnimating ? 1 : 0,\n transitionProperty: \"transform, opacity\",\n transitionDuration: `${POPOVER_MOBILE_SHEET_MOTION_MS}ms`,\n transitionTimingFunction: sheetMotion,\n ...style,\n }}\n >\n <div\n className={cn(\n \"flex w-full shrink-0 items-center py-2 pl-4 pr-2\",\n sheetTitle ? \"justify-between gap-3\" : \"justify-end\",\n )}\n >\n {sheetTitle ? (\n <p className=\"text-foreground min-w-0 flex-1 truncate text-base font-semibold\">\n {sheetTitle}\n </p>\n ) : null}\n <PopoverMobileClose\n onClick={(e) => {\n e.stopPropagation();\n onRequestClose();\n }}\n />\n </div>\n <div\n className={cn(\n \"min-h-0 flex-1 overflow-y-auto px-4 pt-3\",\n contentClassName,\n \"pb-[calc(5rem+env(safe-area-inset-bottom,0px))]\",\n )}\n >\n {children}\n </div>\n </div>\n </div>,\n document.body,\n );\n}\n\n//////////////////////////////////////////////// Content\n\ntype Side = \"top\" | \"right\" | \"bottom\" | \"left\";\ntype Align = \"start\" | \"center\" | \"end\";\n\ninterface PopoverContentProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Which side of the trigger to render on */\n side?: Side;\n /** Alignment along the cross-axis */\n align?: Align;\n /** Gap between trigger and popover in px */\n offset?: number;\n /** Show a small arrow pointing to the trigger */\n showArrow?: boolean;\n /** Close when clicking outside */\n closeOnClickOutside?: boolean;\n /** Close when Escape key is pressed */\n closeOnEscape?: boolean;\n /** Animation duration in ms */\n duration?: number;\n /** Minimum distance from the viewport edge in px */\n viewportPadding?: number;\n /** Portal container – defaults to document.body */\n container?: HTMLElement | null;\n /** Width of the popover. 'trigger' matches the trigger width. */\n width?: \"auto\" | \"trigger\" | number;\n /**\n * Narrow-viewport (≤1024px) bottom sheet — same options as dropdown\n * `mobileOptions`, except `sheet` defaults to `false`.\n */\n mobileOptions?: PopoverMobileSheetOptions;\n /**\n * Mobile bottom sheet only. When `true` (default), panel motion matches Dialog\n * `slideEntrance`; when `false`, uses full `translateY(100%)`.\n */\n slideEntrance?: boolean;\n /** Mobile sheet only; defaults to 120px (same as dropdown / dialog full sheet). */\n slideEntranceOffsetPx?: number;\n}\n\ninterface Position {\n top: number;\n left: number;\n side: Side; // actual side after flip\n}\n\nfunction computePosition(\n trigger: HTMLElement,\n popover: HTMLElement,\n side: Side,\n align: Align,\n offset: number,\n viewportPadding: number,\n): Position {\n const triggerRect = trigger.getBoundingClientRect();\n /** Layout box — not affected by exit/enter `transform: scale()`, unlike `getBoundingClientRect()`. */\n const pw = popover.offsetWidth;\n const ph = popover.offsetHeight;\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n\n let top = 0;\n let left = 0;\n let effectiveSide: Side = side;\n\n /** Viewport-space coords — pairs with `position: fixed` on the portal root. */\n const place = (s: Side) => {\n switch (s) {\n case \"bottom\":\n top = triggerRect.bottom + offset;\n break;\n case \"top\":\n top = triggerRect.top - ph - offset;\n break;\n case \"right\":\n left = triggerRect.right + offset;\n top =\n align === \"start\"\n ? triggerRect.top\n : align === \"end\"\n ? triggerRect.bottom - ph\n : triggerRect.top + triggerRect.height / 2 - ph / 2;\n return;\n case \"left\":\n left = triggerRect.left - pw - offset;\n top =\n align === \"start\"\n ? triggerRect.top\n : align === \"end\"\n ? triggerRect.bottom - ph\n : triggerRect.top + triggerRect.height / 2 - ph / 2;\n return;\n }\n // horizontal alignment for top/bottom\n if (align === \"start\") left = triggerRect.left;\n else if (align === \"end\") left = triggerRect.right - pw;\n else left = triggerRect.left + triggerRect.width / 2 - pw / 2;\n };\n\n place(side);\n\n // ----- flip if overflowing viewport -----\n const tryFlip = () => {\n if (side === \"bottom\" && top + ph > vh - viewportPadding) {\n const flipped: Side = \"top\";\n const newTop = triggerRect.top - ph - offset;\n if (newTop >= viewportPadding) {\n effectiveSide = flipped;\n top = newTop;\n }\n } else if (side === \"top\" && top < viewportPadding) {\n const flipped: Side = \"bottom\";\n const newTop = triggerRect.bottom + offset;\n if (newTop + ph <= vh - viewportPadding) {\n effectiveSide = flipped;\n top = newTop;\n }\n } else if (side === \"right\" && left + pw > vw - viewportPadding) {\n const flipped: Side = \"left\";\n const newLeft = triggerRect.left - pw - offset;\n if (newLeft >= viewportPadding) {\n effectiveSide = flipped;\n left = newLeft;\n }\n } else if (side === \"left\" && left < viewportPadding) {\n const flipped: Side = \"right\";\n const newLeft = triggerRect.right + offset;\n if (newLeft + pw <= vw - viewportPadding) {\n effectiveSide = flipped;\n left = newLeft;\n }\n }\n };\n tryFlip();\n\n // ----- clamp to viewport -----\n left = Math.max(\n viewportPadding,\n Math.min(left, vw - pw - viewportPadding),\n );\n top = Math.max(\n viewportPadding,\n Math.min(top, vh - ph - viewportPadding),\n );\n\n return { top, left, side: effectiveSide };\n}\n\nconst ARROW_SIZE = 6;\n\nexport const PopoverContent: React.FC<PopoverContentProps> = ({\n children,\n side = \"bottom\",\n align = \"center\",\n offset = 10,\n showArrow = false,\n closeOnClickOutside = true,\n closeOnEscape = true,\n duration = 80,\n viewportPadding = 8,\n container,\n width = \"auto\",\n mobileOptions,\n slideEntrance = true,\n slideEntranceOffsetPx: slideEntranceOffsetPxProp,\n className,\n style,\n ...props\n}) => {\n const { open, setOpen, triggerRef } = usePopover();\n const isMobile = usePopoverIsMobile(POPOVER_MOBILE_SHEET_MAX_PX + 1);\n const resolvedMobile = useMemo(\n () => resolvePopoverMobileSheet(mobileOptions),\n [mobileOptions],\n );\n const sheetMode = isMobile && resolvedMobile.sheet;\n const slideOffsetPx = useMemo(\n () =>\n slideEntranceOffsetPxProp ??\n POPOVER_MOBILE_SHEET_SLIDE_ENTRANCE_OFFSET_DEFAULT_PX,\n [slideEntranceOffsetPxProp],\n );\n const closeDuration = sheetMode\n ? POPOVER_MOBILE_SHEET_MOTION_MS\n : duration;\n\n const [shouldRender, setShouldRender] = useState(false);\n const [isAnimating, setIsAnimating] = useState(false);\n const [position, setPosition] = useState<Position>({\n top: -9999,\n left: -9999,\n side,\n });\n const [triggerWidth, setTriggerWidth] = useState<number>(0);\n const popoverRef = useRef<HTMLDivElement>(null);\n\n const closePopover = useCallback(() => setOpen(false), [setOpen]);\n\n /** Same open/close sequencing as dropdown mobile sheet / `DialogContent`. */\n useEffect(() => {\n if (open) {\n setShouldRender(true);\n } else {\n setIsAnimating(false);\n const timer = setTimeout(() => setShouldRender(false), closeDuration);\n return () => clearTimeout(timer);\n }\n }, [open, closeDuration]);\n\n useEffect(() => {\n if (!shouldRender || !open) return;\n let raf2 = 0;\n const raf1 = requestAnimationFrame(() => {\n raf2 = requestAnimationFrame(() => setIsAnimating(true));\n });\n return () => {\n cancelAnimationFrame(raf1);\n if (raf2) cancelAnimationFrame(raf2);\n };\n }, [shouldRender, open]);\n\n // Position calculation – runs after render so the popover has dimensions.\n // Skip while `open` is false: panel still mounts for the exit animation, but\n // `getBoundingClientRect` on the root would reflect `scale()` and re-trigger a jump.\n useLayoutEffect(() => {\n if (\n !shouldRender ||\n !open ||\n sheetMode ||\n !triggerRef.current ||\n !popoverRef.current\n )\n return;\n\n const update = () => {\n if (!triggerRef.current || !popoverRef.current) return;\n setTriggerWidth(triggerRef.current.getBoundingClientRect().width);\n const pos = computePosition(\n triggerRef.current,\n popoverRef.current,\n side,\n align,\n offset,\n viewportPadding,\n );\n setPosition(pos);\n };\n\n update();\n window.addEventListener(\"resize\", update);\n window.addEventListener(\"scroll\", update, true);\n return () => {\n window.removeEventListener(\"resize\", update);\n window.removeEventListener(\"scroll\", update, true);\n };\n }, [shouldRender, open, sheetMode, side, align, offset, viewportPadding]);\n\n // Body scroll lock (mobile sheet)\n useEffect(() => {\n if (open && sheetMode) {\n document.body.style.overflow = \"hidden\";\n }\n return () => {\n document.body.style.overflow = \"\";\n };\n }, [open, sheetMode]);\n\n // Close on outside click (floating only — sheet uses scrim `dismissOnBackdropPress`)\n useEffect(() => {\n if (!open || !closeOnClickOutside || sheetMode) return;\n const handler = (e: MouseEvent) => {\n const target = e.target as Node;\n if (\n popoverRef.current?.contains(target) ||\n triggerRef.current?.contains(target)\n )\n return;\n setOpen(false);\n };\n document.addEventListener(\"mousedown\", handler);\n return () => document.removeEventListener(\"mousedown\", handler);\n }, [open, closeOnClickOutside, sheetMode, setOpen, triggerRef]);\n\n // Close on Escape\n useEffect(() => {\n if (!open || !closeOnEscape) return;\n const handler = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") setOpen(false);\n };\n window.addEventListener(\"keydown\", handler);\n return () => window.removeEventListener(\"keydown\", handler);\n }, [open, closeOnEscape, setOpen]);\n\n if (!shouldRender) return null;\n\n if (sheetMode && typeof document !== \"undefined\") {\n return (\n <PopoverMobileBottomSheetPortal\n {...props}\n open={open}\n isAnimating={isAnimating}\n slideEntrance={slideEntrance}\n slideOffsetPx={slideOffsetPx}\n sheetTitle={resolvedMobile.title}\n sheetExtraClassName={resolvedMobile.sheetExtraClassName}\n contentClassName={cn(resolvedMobile.contentClassName, className)}\n onRequestClose={closePopover}\n dismissOnBackdropPress={closeOnClickOutside}\n menuRef={popoverRef}\n role=\"dialog\"\n aria-modal=\"true\"\n tabIndex={-1}\n className={undefined}\n style={style}\n data-slot=\"popover-content\"\n >\n {children}\n </PopoverMobileBottomSheetPortal>\n );\n }\n\n // Animation direction by side\n const transformOrigin: Record<Side, string> = {\n bottom: \"top center\",\n top: \"bottom center\",\n left: \"right center\",\n right: \"left center\",\n };\n\n const hiddenTransform: Record<Side, string> = {\n bottom: \"translateY(-6px) scale(0.97)\",\n top: \"translateY(6px) scale(0.97)\",\n left: \"translateX(6px) scale(0.97)\",\n right: \"translateX(-6px) scale(0.97)\",\n };\n\n const resolvedWidth =\n width === \"trigger\" ? triggerWidth : width === \"auto\" ? undefined : width;\n\n // Arrow position relative to popover\n const arrowStyles = (): React.CSSProperties => {\n const base: React.CSSProperties = {\n position: \"absolute\",\n width: 0,\n height: 0,\n pointerEvents: \"none\",\n };\n switch (position.side) {\n case \"bottom\":\n return {\n ...base,\n top: -ARROW_SIZE,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n borderLeft: `${ARROW_SIZE}px solid transparent`,\n borderRight: `${ARROW_SIZE}px solid transparent`,\n borderBottom: `${ARROW_SIZE}px solid var(--border)`,\n };\n case \"top\":\n return {\n ...base,\n bottom: -ARROW_SIZE,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n borderLeft: `${ARROW_SIZE}px solid transparent`,\n borderRight: `${ARROW_SIZE}px solid transparent`,\n borderTop: `${ARROW_SIZE}px solid var(--border)`,\n };\n case \"right\":\n return {\n ...base,\n left: -ARROW_SIZE,\n top: \"50%\",\n transform: \"translateY(-50%)\",\n borderTop: `${ARROW_SIZE}px solid transparent`,\n borderBottom: `${ARROW_SIZE}px solid transparent`,\n borderRight: `${ARROW_SIZE}px solid var(--border)`,\n };\n case \"left\":\n return {\n ...base,\n right: -ARROW_SIZE,\n top: \"50%\",\n transform: \"translateY(-50%)\",\n borderTop: `${ARROW_SIZE}px solid transparent`,\n borderBottom: `${ARROW_SIZE}px solid transparent`,\n borderLeft: `${ARROW_SIZE}px solid var(--border)`,\n };\n }\n };\n\n const resolvedContainer =\n container !== undefined\n ? container\n : typeof document !== \"undefined\"\n ? document.body\n : null;\n\n if (!resolvedContainer) return null;\n\n return createPortal(\n <div\n {...props}\n ref={popoverRef}\n className={cn(\n \"bg-background border-primary/10 fixed z-50 overflow-hidden rounded-xl border shadow-xl outline-none\",\n className,\n )}\n data-slot=\"popover-content\"\n style={{\n position: \"fixed\",\n top: position.top,\n left: position.left,\n width: resolvedWidth,\n transformOrigin: transformOrigin[position.side],\n transform: isAnimating ? \"none\" : hiddenTransform[position.side],\n opacity: isAnimating ? 1 : 0,\n transition: `opacity ${duration}ms ease, transform ${duration}ms ease`,\n ...style,\n }}\n >\n {showArrow && <div style={arrowStyles()} />}\n {children}\n </div>,\n resolvedContainer,\n );\n};\n\n//////////////////////////////////////////////// Sub-components\n\nexport const PopoverHeader: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({\n className,\n ...props\n}) => (\n <div\n className={cn(\n \"border-primary/10 flex flex-col space-y-1 border-b px-4 py-3\",\n className,\n )}\n {...props}\n />\n);\n\nexport const PopoverFooter: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({\n className,\n ...props\n}) => (\n <div\n className={cn(\n \"border-primary/10 flex flex-row justify-end gap-2 border-t px-4 py-3\",\n className,\n )}\n {...props}\n />\n);\n\nexport const PopoverTitle: React.FC<\n React.HTMLAttributes<HTMLHeadingElement>\n> = ({ className, ...props }) => (\n <h4\n className={cn(\"text-primary text-sm leading-none font-semibold\", className)}\n {...props}\n />\n);\n\nexport const PopoverDescription: React.FC<\n React.HTMLAttributes<HTMLParagraphElement>\n> = ({ className, ...props }) => (\n <p className={cn(\"text-muted-foreground text-xs\", className)} {...props} />\n);\n"]}
@@ -158,7 +158,19 @@ var ScrollHeaderSticky = ({
158
158
  ...props,
159
159
  children
160
160
  }
161
- ) : /* @__PURE__ */ jsx("div", { className: stickyChromeBgClass, children: /* @__PURE__ */ jsx("div", { className: cn(stickyChromeBorderClass, className), ...props, children }) })
161
+ ) : /* @__PURE__ */ jsx("div", { className: stickyChromeBgClass, children: /* @__PURE__ */ jsx(
162
+ "div",
163
+ {
164
+ className: cn(
165
+ stickyChromeBorderClass,
166
+ "transition-[border-color] duration-300 motion-reduce:duration-0 motion-reduce:transition-none",
167
+ '[.scroll-header:not([data-scrolled="true"])_&]:border-b-transparent',
168
+ className
169
+ ),
170
+ ...props,
171
+ children
172
+ }
173
+ ) })
162
174
  }
163
175
  );
164
176
  };