@opensite/ui 2.8.8 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/about-culture-tabs.cjs +174 -174
- package/dist/about-culture-tabs.js +174 -174
- package/dist/about-developer-profile.cjs +200 -200
- package/dist/about-developer-profile.js +198 -198
- package/dist/about-developer-story.cjs +142 -142
- package/dist/about-developer-story.js +142 -142
- package/dist/about-mission-dual-image.cjs +142 -142
- package/dist/about-mission-dual-image.js +142 -142
- package/dist/about-mission-features.cjs +142 -142
- package/dist/about-mission-features.js +142 -142
- package/dist/about-network-spotlight.cjs +142 -142
- package/dist/about-network-spotlight.js +142 -142
- package/dist/about-story-expertise.cjs +142 -142
- package/dist/about-story-expertise.js +142 -142
- package/dist/about-streamline-team.cjs +142 -142
- package/dist/about-streamline-team.js +142 -142
- package/dist/carousel-feature-badge.cjs +162 -42
- package/dist/carousel-feature-badge.d.cts +14 -1
- package/dist/carousel-feature-badge.d.ts +14 -1
- package/dist/carousel-feature-badge.js +163 -43
- package/dist/community-initiatives.cjs +142 -142
- package/dist/community-initiatives.js +142 -142
- package/dist/components.cjs +723 -1378
- package/dist/components.d.cts +0 -2
- package/dist/components.d.ts +0 -2
- package/dist/components.js +633 -1287
- package/dist/contact-map.cjs +14 -1083
- package/dist/contact-map.d.cts +13 -3
- package/dist/contact-map.d.ts +13 -3
- package/dist/contact-map.js +14 -1083
- package/dist/cta-feature-checklist.cjs +142 -142
- package/dist/cta-feature-checklist.js +142 -142
- package/dist/faq-numbered-grid.cjs +142 -142
- package/dist/faq-numbered-grid.js +142 -142
- package/dist/feature-animated-carousel.cjs +142 -142
- package/dist/feature-animated-carousel.js +142 -142
- package/dist/feature-bento-utilities.cjs +142 -142
- package/dist/feature-bento-utilities.js +142 -142
- package/dist/feature-capabilities-grid.cjs +142 -142
- package/dist/feature-capabilities-grid.js +142 -142
- package/dist/feature-category-image-cards.cjs +142 -142
- package/dist/feature-category-image-cards.js +142 -142
- package/dist/feature-icon-grid-bordered.cjs +142 -142
- package/dist/feature-icon-grid-bordered.js +142 -142
- package/dist/feature-icon-grid-muted.cjs +142 -142
- package/dist/feature-icon-grid-muted.js +142 -142
- package/dist/feature-numbered-cards.cjs +142 -142
- package/dist/feature-numbered-cards.js +142 -142
- package/dist/feature-three-column-values.cjs +142 -142
- package/dist/feature-three-column-values.js +142 -142
- package/dist/hero-ad-campaign-expert.cjs +142 -142
- package/dist/hero-ad-campaign-expert.js +142 -142
- package/dist/hero-adaptable-product-grid.cjs +142 -142
- package/dist/hero-adaptable-product-grid.js +142 -142
- package/dist/hero-agency-animated-images.cjs +142 -142
- package/dist/hero-agency-animated-images.js +142 -142
- package/dist/hero-announcement-badge.cjs +142 -142
- package/dist/hero-announcement-badge.js +142 -142
- package/dist/hero-badge-image-split.cjs +142 -142
- package/dist/hero-badge-image-split.js +142 -142
- package/dist/hero-business-carousel-dots.cjs +142 -142
- package/dist/hero-business-carousel-dots.js +142 -142
- package/dist/hero-business-operations-mosaic.cjs +142 -142
- package/dist/hero-business-operations-mosaic.js +142 -142
- package/dist/hero-conversation-intelligence.cjs +142 -142
- package/dist/hero-conversation-intelligence.js +142 -142
- package/dist/hero-creative-studio-stacked.cjs +142 -142
- package/dist/hero-creative-studio-stacked.js +142 -142
- package/dist/hero-crm-streamlined.cjs +142 -142
- package/dist/hero-crm-streamlined.js +142 -142
- package/dist/hero-customer-support-layered.cjs +142 -142
- package/dist/hero-customer-support-layered.js +142 -142
- package/dist/hero-design-showcase-logos.cjs +142 -142
- package/dist/hero-design-showcase-logos.js +142 -142
- package/dist/hero-design-system-3d.cjs +142 -142
- package/dist/hero-design-system-3d.js +142 -142
- package/dist/hero-developer-tools-code.cjs +142 -142
- package/dist/hero-developer-tools-code.js +142 -142
- package/dist/hero-digital-agency-fullscreen.cjs +142 -142
- package/dist/hero-digital-agency-fullscreen.js +142 -142
- package/dist/hero-ecommerce-product-showcase.cjs +174 -174
- package/dist/hero-ecommerce-product-showcase.js +174 -174
- package/dist/hero-event-registration.cjs +142 -142
- package/dist/hero-event-registration.js +142 -142
- package/dist/hero-fullscreen-background-image.cjs +142 -142
- package/dist/hero-fullscreen-background-image.js +142 -142
- package/dist/hero-gradient-avatars-rating.cjs +142 -142
- package/dist/hero-gradient-avatars-rating.js +142 -142
- package/dist/hero-gradient-client-focused.cjs +142 -142
- package/dist/hero-gradient-client-focused.js +142 -142
- package/dist/hero-hiring-animated-text.cjs +142 -142
- package/dist/hero-hiring-animated-text.js +142 -142
- package/dist/hero-image-left-content.cjs +142 -142
- package/dist/hero-image-left-content.js +142 -142
- package/dist/hero-innovation-image-grid.cjs +142 -142
- package/dist/hero-innovation-image-grid.js +142 -142
- package/dist/hero-mental-health-team.cjs +142 -142
- package/dist/hero-mental-health-team.js +142 -142
- package/dist/hero-minimal-centered-dark.cjs +174 -174
- package/dist/hero-minimal-centered-dark.js +174 -174
- package/dist/hero-presentation-platform-video.cjs +142 -142
- package/dist/hero-presentation-platform-video.js +142 -142
- package/dist/hero-product-showcase-floating.cjs +174 -174
- package/dist/hero-product-showcase-floating.js +174 -174
- package/dist/hero-shared-inbox-layered.cjs +142 -142
- package/dist/hero-shared-inbox-layered.js +142 -142
- package/dist/hero-software-growth-video-dialog.cjs +142 -142
- package/dist/hero-software-growth-video-dialog.js +142 -142
- package/dist/hero-spiral-pattern-cards.cjs +174 -174
- package/dist/hero-spiral-pattern-cards.js +174 -174
- package/dist/hero-split-geometric-shapes.cjs +142 -142
- package/dist/hero-split-geometric-shapes.js +142 -142
- package/dist/hero-startup-launch-cta.cjs +174 -174
- package/dist/hero-startup-launch-cta.js +174 -174
- package/dist/hero-stats-social-proof.cjs +174 -174
- package/dist/hero-stats-social-proof.js +174 -174
- package/dist/hero-task-timer-animated.cjs +142 -142
- package/dist/hero-task-timer-animated.js +142 -142
- package/dist/hero-testimonial-image-grid.cjs +142 -142
- package/dist/hero-testimonial-image-grid.js +142 -142
- package/dist/hero-therapy-testimonial-grid.cjs +142 -142
- package/dist/hero-therapy-testimonial-grid.js +142 -142
- package/dist/hero-ui-library-showcase.cjs +142 -142
- package/dist/hero-ui-library-showcase.js +142 -142
- package/dist/hero-video-background-dark.cjs +174 -174
- package/dist/hero-video-background-dark.js +174 -174
- package/dist/hero-video-dialog-gradient.cjs +142 -142
- package/dist/hero-video-dialog-gradient.js +142 -142
- package/dist/hero-video-overlay-stars.cjs +142 -142
- package/dist/hero-video-overlay-stars.js +142 -142
- package/dist/hero-welcome-asymmetric-images.cjs +142 -142
- package/dist/hero-welcome-asymmetric-images.js +142 -142
- package/dist/index.cjs +725 -1380
- package/dist/index.d.cts +0 -2
- package/dist/index.d.ts +0 -2
- package/dist/index.js +634 -1288
- package/dist/registry.cjs +2201 -2827
- package/dist/registry.js +948 -1574
- package/dist/testimonials-masonry-grid.cjs +142 -142
- package/dist/testimonials-masonry-grid.js +142 -142
- package/dist/testimonials-stats-header.cjs +159 -159
- package/dist/testimonials-stats-header.js +159 -159
- package/package.json +4 -7
- package/dist/geo-map.cjs +0 -1117
- package/dist/geo-map.d.cts +0 -92
- package/dist/geo-map.d.ts +0 -92
- package/dist/geo-map.js +0 -1095
package/dist/index.js
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import * as
|
|
3
|
-
import
|
|
2
|
+
import * as React4 from 'react';
|
|
3
|
+
import React4__default, { useId, useRef, useEffect, useMemo, useCallback, useState } from 'react';
|
|
4
4
|
import { clsx } from 'clsx';
|
|
5
5
|
import { twMerge } from 'tailwind-merge';
|
|
6
6
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
7
|
-
import { MapLibre } from '@page-speed/maps';
|
|
8
|
-
import { cva } from 'class-variance-authority';
|
|
9
|
-
import { Icon } from '@page-speed/icon';
|
|
10
|
-
import { Img } from '@page-speed/img';
|
|
11
7
|
import { AnimatePresence, motion } from 'framer-motion';
|
|
12
8
|
import { useOnClickOutside } from '@opensite/hooks/useOnClickOutside';
|
|
13
9
|
import { AnimatePresence as AnimatePresence$1, motion as motion$1 } from 'motion/react';
|
|
10
|
+
import { Img } from '@page-speed/img';
|
|
14
11
|
import { Slot } from '@radix-ui/react-slot';
|
|
12
|
+
import { cva } from 'class-variance-authority';
|
|
15
13
|
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
14
|
+
import { Icon } from '@page-speed/icon';
|
|
16
15
|
import { usePlatformFromUrl } from '@opensite/hooks/usePlatformFromUrl';
|
|
17
16
|
import * as TabsPrimitive from '@radix-ui/react-tabs';
|
|
18
17
|
import { FormEngine } from '@page-speed/forms/integration';
|
|
@@ -121,7 +120,7 @@ var maxWidthStyles = {
|
|
|
121
120
|
"4xl": "max-w-[1536px]",
|
|
122
121
|
full: "max-w-full"
|
|
123
122
|
};
|
|
124
|
-
var Container =
|
|
123
|
+
var Container = React4__default.forwardRef(
|
|
125
124
|
({ children, maxWidth = "xl", className, as = "div", ...props }, ref) => {
|
|
126
125
|
const Component = as;
|
|
127
126
|
return /* @__PURE__ */ jsx(
|
|
@@ -427,7 +426,7 @@ var spacingStyles = {
|
|
|
427
426
|
};
|
|
428
427
|
var predefinedSpacings = ["none", "sm", "md", "lg", "xl", "hero"];
|
|
429
428
|
var isPredefinedSpacing = (spacing) => predefinedSpacings.includes(spacing);
|
|
430
|
-
var Section =
|
|
429
|
+
var Section = React4__default.forwardRef(
|
|
431
430
|
({
|
|
432
431
|
id,
|
|
433
432
|
title,
|
|
@@ -488,1145 +487,65 @@ var Section = React6__default.forwardRef(
|
|
|
488
487
|
}
|
|
489
488
|
);
|
|
490
489
|
Section.displayName = "Section";
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
const
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
const phoneRegex = /^[\s\+\-\(\)]*\d[\d\s\-\(\)\.]*\d[\s\-]*(x|ext\.?|extension)?[\s\-]*\d*$/i;
|
|
524
|
-
return phoneRegex.test(trimmed);
|
|
525
|
-
}
|
|
526
|
-
function isInternalUrl(href) {
|
|
527
|
-
if (typeof window === "undefined") {
|
|
528
|
-
return href.startsWith("/") && !href.startsWith("//");
|
|
529
|
-
}
|
|
530
|
-
const trimmed = href.trim();
|
|
531
|
-
if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
|
|
532
|
-
return true;
|
|
533
|
-
}
|
|
534
|
-
try {
|
|
535
|
-
const url = new URL(trimmed, window.location.href);
|
|
536
|
-
const currentOrigin = window.location.origin;
|
|
537
|
-
const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
|
|
538
|
-
return normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin);
|
|
539
|
-
} catch {
|
|
540
|
-
return false;
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
function toRelativePath(href) {
|
|
544
|
-
if (typeof window === "undefined") {
|
|
545
|
-
return href;
|
|
546
|
-
}
|
|
547
|
-
const trimmed = href.trim();
|
|
548
|
-
if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
|
|
549
|
-
return trimmed;
|
|
550
|
-
}
|
|
551
|
-
try {
|
|
552
|
-
const url = new URL(trimmed, window.location.href);
|
|
553
|
-
const currentOrigin = window.location.origin;
|
|
554
|
-
const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
|
|
555
|
-
if (normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin)) {
|
|
556
|
-
return url.pathname + url.search + url.hash;
|
|
557
|
-
}
|
|
558
|
-
} catch {
|
|
559
|
-
}
|
|
560
|
-
return trimmed;
|
|
561
|
-
}
|
|
562
|
-
function useNavigation({
|
|
563
|
-
href,
|
|
564
|
-
onClick
|
|
565
|
-
} = {}) {
|
|
566
|
-
const linkType = React6.useMemo(() => {
|
|
567
|
-
if (!href || href.trim() === "") {
|
|
568
|
-
return onClick ? "none" : "none";
|
|
569
|
-
}
|
|
570
|
-
const trimmed = href.trim();
|
|
571
|
-
if (trimmed.toLowerCase().startsWith("mailto:") || isEmail(trimmed)) {
|
|
572
|
-
return "mailto";
|
|
573
|
-
}
|
|
574
|
-
if (trimmed.toLowerCase().startsWith("tel:") || isPhoneNumber(trimmed)) {
|
|
575
|
-
return "tel";
|
|
576
|
-
}
|
|
577
|
-
if (isInternalUrl(trimmed)) {
|
|
578
|
-
return "internal";
|
|
579
|
-
}
|
|
580
|
-
try {
|
|
581
|
-
new URL(trimmed, typeof window !== "undefined" ? window.location.href : "http://localhost");
|
|
582
|
-
return "external";
|
|
583
|
-
} catch {
|
|
584
|
-
return "internal";
|
|
585
|
-
}
|
|
586
|
-
}, [href, onClick]);
|
|
587
|
-
const normalizedHref = React6.useMemo(() => {
|
|
588
|
-
if (!href || href.trim() === "") {
|
|
589
|
-
return void 0;
|
|
590
|
-
}
|
|
591
|
-
const trimmed = href.trim();
|
|
592
|
-
switch (linkType) {
|
|
593
|
-
case "tel":
|
|
594
|
-
return normalizePhoneNumber(trimmed);
|
|
595
|
-
case "mailto":
|
|
596
|
-
return normalizeEmail(trimmed);
|
|
597
|
-
case "internal":
|
|
598
|
-
return toRelativePath(trimmed);
|
|
599
|
-
case "external":
|
|
600
|
-
return trimmed;
|
|
601
|
-
default:
|
|
602
|
-
return trimmed;
|
|
603
|
-
}
|
|
604
|
-
}, [href, linkType]);
|
|
605
|
-
const target = React6.useMemo(() => {
|
|
606
|
-
switch (linkType) {
|
|
607
|
-
case "external":
|
|
608
|
-
return "_blank";
|
|
609
|
-
case "internal":
|
|
610
|
-
return "_self";
|
|
611
|
-
case "mailto":
|
|
612
|
-
case "tel":
|
|
613
|
-
return void 0;
|
|
614
|
-
default:
|
|
615
|
-
return void 0;
|
|
490
|
+
var sizeStyles = {
|
|
491
|
+
sm: "max-w-md",
|
|
492
|
+
md: "max-w-2xl",
|
|
493
|
+
lg: "max-w-4xl",
|
|
494
|
+
xl: "max-w-5xl",
|
|
495
|
+
full: "max-w-7xl",
|
|
496
|
+
compact: "max-w-[700px]"
|
|
497
|
+
};
|
|
498
|
+
var dialogTransition = {
|
|
499
|
+
duration: 0.35,
|
|
500
|
+
ease: [0.16, 1, 0.3, 1]
|
|
501
|
+
};
|
|
502
|
+
function AnimatedDialog({
|
|
503
|
+
open,
|
|
504
|
+
onOpenChange,
|
|
505
|
+
title,
|
|
506
|
+
eyebrow,
|
|
507
|
+
description,
|
|
508
|
+
children,
|
|
509
|
+
header,
|
|
510
|
+
footer,
|
|
511
|
+
size = "lg",
|
|
512
|
+
className,
|
|
513
|
+
contentClassName,
|
|
514
|
+
featuredMediaHeader
|
|
515
|
+
}) {
|
|
516
|
+
const titleId = useId();
|
|
517
|
+
const descriptionId = useId();
|
|
518
|
+
const containerRef = useRef(null);
|
|
519
|
+
useOnClickOutside(containerRef, () => {
|
|
520
|
+
if (open) {
|
|
521
|
+
onOpenChange(false);
|
|
616
522
|
}
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
if (
|
|
620
|
-
return
|
|
523
|
+
});
|
|
524
|
+
useEffect(() => {
|
|
525
|
+
if (!open) {
|
|
526
|
+
return;
|
|
621
527
|
}
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
const isInternal = linkType === "internal";
|
|
626
|
-
const shouldUseRouter = isInternal && typeof normalizedHref === "string" && normalizedHref.startsWith("/");
|
|
627
|
-
const handleClick = React6.useCallback(
|
|
628
|
-
(event) => {
|
|
629
|
-
if (onClick) {
|
|
630
|
-
try {
|
|
631
|
-
onClick(event);
|
|
632
|
-
} catch (error) {
|
|
633
|
-
console.error("Error in user onClick handler:", error);
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
if (event.defaultPrevented) {
|
|
637
|
-
return;
|
|
528
|
+
const onKeyDown = (event) => {
|
|
529
|
+
if (event.key === "Escape") {
|
|
530
|
+
onOpenChange(false);
|
|
638
531
|
}
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
[onClick, shouldUseRouter, normalizedHref]
|
|
657
|
-
);
|
|
658
|
-
return {
|
|
659
|
-
linkType,
|
|
660
|
-
normalizedHref,
|
|
661
|
-
target,
|
|
662
|
-
rel,
|
|
663
|
-
isExternal,
|
|
664
|
-
isInternal,
|
|
665
|
-
shouldUseRouter,
|
|
666
|
-
handleClick
|
|
667
|
-
};
|
|
668
|
-
}
|
|
669
|
-
var baseStyles = [
|
|
670
|
-
// Layout
|
|
671
|
-
"inline-flex items-center justify-center gap-2 whitespace-nowrap shrink-0",
|
|
672
|
-
// Typography - using CSS variables with sensible defaults
|
|
673
|
-
"font-[var(--button-font-family,inherit)]",
|
|
674
|
-
"font-[var(--button-font-weight,500)]",
|
|
675
|
-
"tracking-[var(--button-letter-spacing,0)]",
|
|
676
|
-
"leading-[var(--button-line-height,1.25)]",
|
|
677
|
-
"[text-transform:var(--button-text-transform,none)]",
|
|
678
|
-
"text-sm",
|
|
679
|
-
// Border radius
|
|
680
|
-
"rounded-[var(--button-radius,var(--radius,0.375rem))]",
|
|
681
|
-
// Smooth transition - using [transition:...] to set full shorthand property (not just transition-property)
|
|
682
|
-
"[transition:var(--button-transition,all_250ms_cubic-bezier(0.4,0,0.2,1))]",
|
|
683
|
-
// Box shadow (master level) - using [box-shadow:...] for complex multi-value shadows
|
|
684
|
-
"[box-shadow:var(--button-shadow,none)]",
|
|
685
|
-
"hover:[box-shadow:var(--button-shadow-hover,var(--button-shadow,none))]",
|
|
686
|
-
// Disabled state
|
|
687
|
-
"disabled:pointer-events-none disabled:opacity-50",
|
|
688
|
-
// SVG handling
|
|
689
|
-
"[&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0",
|
|
690
|
-
// Focus styles
|
|
691
|
-
"outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
|
692
|
-
// Invalid state
|
|
693
|
-
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive"
|
|
694
|
-
].join(" ");
|
|
695
|
-
var buttonVariants = cva(baseStyles, {
|
|
696
|
-
variants: {
|
|
697
|
-
variant: {
|
|
698
|
-
// Default (Primary) variant - full customization
|
|
699
|
-
default: [
|
|
700
|
-
"bg-[var(--button-default-bg,hsl(var(--primary)))]",
|
|
701
|
-
"text-[var(--button-default-fg,hsl(var(--primary-foreground)))]",
|
|
702
|
-
"border-[length:var(--button-default-border-width,0px)]",
|
|
703
|
-
"border-[color:var(--button-default-border,transparent)]",
|
|
704
|
-
"[box-shadow:var(--button-default-shadow,var(--button-shadow,none))]",
|
|
705
|
-
"hover:bg-[var(--button-default-hover-bg,hsl(var(--primary)/0.9))]",
|
|
706
|
-
"hover:text-[var(--button-default-hover-fg,var(--button-default-fg,hsl(var(--primary-foreground))))]",
|
|
707
|
-
"hover:border-[color:var(--button-default-hover-border,var(--button-default-border,transparent))]",
|
|
708
|
-
"hover:[box-shadow:var(--button-default-shadow-hover,var(--button-shadow-hover,var(--button-default-shadow,var(--button-shadow,none))))]"
|
|
709
|
-
].join(" "),
|
|
710
|
-
// Destructive variant - full customization
|
|
711
|
-
destructive: [
|
|
712
|
-
"bg-[var(--button-destructive-bg,hsl(var(--destructive)))]",
|
|
713
|
-
"text-[var(--button-destructive-fg,white)]",
|
|
714
|
-
"border-[length:var(--button-destructive-border-width,0px)]",
|
|
715
|
-
"border-[color:var(--button-destructive-border,transparent)]",
|
|
716
|
-
"[box-shadow:var(--button-destructive-shadow,var(--button-shadow,none))]",
|
|
717
|
-
"hover:bg-[var(--button-destructive-hover-bg,hsl(var(--destructive)/0.9))]",
|
|
718
|
-
"hover:text-[var(--button-destructive-hover-fg,var(--button-destructive-fg,white))]",
|
|
719
|
-
"hover:border-[color:var(--button-destructive-hover-border,var(--button-destructive-border,transparent))]",
|
|
720
|
-
"hover:[box-shadow:var(--button-destructive-shadow-hover,var(--button-shadow-hover,var(--button-destructive-shadow,var(--button-shadow,none))))]",
|
|
721
|
-
"focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40",
|
|
722
|
-
"dark:bg-destructive/60"
|
|
723
|
-
].join(" "),
|
|
724
|
-
// Outline variant - full customization with proper border handling
|
|
725
|
-
outline: [
|
|
726
|
-
"bg-[var(--button-outline-bg,hsl(var(--background)))]",
|
|
727
|
-
"text-[var(--button-outline-fg,inherit)]",
|
|
728
|
-
"border-[length:var(--button-outline-border-width,1px)]",
|
|
729
|
-
"border-[color:var(--button-outline-border,hsl(var(--border)))]",
|
|
730
|
-
"[box-shadow:var(--button-outline-shadow,var(--button-shadow,0_1px_2px_0_rgb(0_0_0/0.05)))]",
|
|
731
|
-
"hover:bg-[var(--button-outline-hover-bg,hsl(var(--accent)))]",
|
|
732
|
-
"hover:text-[var(--button-outline-hover-fg,hsl(var(--accent-foreground)))]",
|
|
733
|
-
"hover:border-[color:var(--button-outline-hover-border,var(--button-outline-border,hsl(var(--border))))]",
|
|
734
|
-
"hover:[box-shadow:var(--button-outline-shadow-hover,var(--button-shadow-hover,var(--button-outline-shadow,var(--button-shadow,none))))]",
|
|
735
|
-
"dark:bg-input/30 dark:border-input dark:hover:bg-input/50"
|
|
736
|
-
].join(" "),
|
|
737
|
-
// Secondary variant - full customization
|
|
738
|
-
secondary: [
|
|
739
|
-
"bg-[var(--button-secondary-bg,hsl(var(--secondary)))]",
|
|
740
|
-
"text-[var(--button-secondary-fg,hsl(var(--secondary-foreground)))]",
|
|
741
|
-
"border-[length:var(--button-secondary-border-width,0px)]",
|
|
742
|
-
"border-[color:var(--button-secondary-border,transparent)]",
|
|
743
|
-
"[box-shadow:var(--button-secondary-shadow,var(--button-shadow,none))]",
|
|
744
|
-
"hover:bg-[var(--button-secondary-hover-bg,hsl(var(--secondary)/0.8))]",
|
|
745
|
-
"hover:text-[var(--button-secondary-hover-fg,var(--button-secondary-fg,hsl(var(--secondary-foreground))))]",
|
|
746
|
-
"hover:border-[color:var(--button-secondary-hover-border,var(--button-secondary-border,transparent))]",
|
|
747
|
-
"hover:[box-shadow:var(--button-secondary-shadow-hover,var(--button-shadow-hover,var(--button-secondary-shadow,var(--button-shadow,none))))]"
|
|
748
|
-
].join(" "),
|
|
749
|
-
// Ghost variant - full customization
|
|
750
|
-
ghost: [
|
|
751
|
-
"bg-[var(--button-ghost-bg,transparent)]",
|
|
752
|
-
"text-[var(--button-ghost-fg,inherit)]",
|
|
753
|
-
"border-[length:var(--button-ghost-border-width,0px)]",
|
|
754
|
-
"border-[color:var(--button-ghost-border,transparent)]",
|
|
755
|
-
"[box-shadow:var(--button-ghost-shadow,var(--button-shadow,none))]",
|
|
756
|
-
"hover:bg-[var(--button-ghost-hover-bg,hsl(var(--accent)))]",
|
|
757
|
-
"hover:text-[var(--button-ghost-hover-fg,hsl(var(--accent-foreground)))]",
|
|
758
|
-
"hover:border-[color:var(--button-ghost-hover-border,var(--button-ghost-border,transparent))]",
|
|
759
|
-
"hover:[box-shadow:var(--button-ghost-shadow-hover,var(--button-shadow-hover,var(--button-ghost-shadow,var(--button-shadow,none))))]",
|
|
760
|
-
"dark:hover:bg-accent/50"
|
|
761
|
-
].join(" "),
|
|
762
|
-
// Link variant - full customization
|
|
763
|
-
link: [
|
|
764
|
-
"bg-[var(--button-link-bg,transparent)]",
|
|
765
|
-
"text-[var(--button-link-fg,hsl(var(--primary)))]",
|
|
766
|
-
"border-[length:var(--button-link-border-width,0px)]",
|
|
767
|
-
"border-[color:var(--button-link-border,transparent)]",
|
|
768
|
-
"[box-shadow:var(--button-link-shadow,none)]",
|
|
769
|
-
"hover:bg-[var(--button-link-hover-bg,transparent)]",
|
|
770
|
-
"hover:text-[var(--button-link-hover-fg,var(--button-link-fg,hsl(var(--primary))))]",
|
|
771
|
-
"hover:[box-shadow:var(--button-link-shadow-hover,none)]",
|
|
772
|
-
"underline-offset-4 hover:underline"
|
|
773
|
-
].join(" ")
|
|
774
|
-
},
|
|
775
|
-
size: {
|
|
776
|
-
default: [
|
|
777
|
-
"h-[var(--button-height-md,2.25rem)]",
|
|
778
|
-
"px-[var(--button-padding-x-md,1rem)]",
|
|
779
|
-
"py-[var(--button-padding-y-md,0.5rem)]",
|
|
780
|
-
"has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
|
|
781
|
-
].join(" "),
|
|
782
|
-
sm: [
|
|
783
|
-
"h-[var(--button-height-sm,2rem)]",
|
|
784
|
-
"px-[var(--button-padding-x-sm,0.75rem)]",
|
|
785
|
-
"py-[var(--button-padding-y-sm,0.25rem)]",
|
|
786
|
-
"gap-1.5",
|
|
787
|
-
"has-[>svg]:px-[calc(var(--button-padding-x-sm,0.75rem)*0.83)]"
|
|
788
|
-
].join(" "),
|
|
789
|
-
md: [
|
|
790
|
-
"h-[var(--button-height-md,2.25rem)]",
|
|
791
|
-
"px-[var(--button-padding-x-md,1rem)]",
|
|
792
|
-
"py-[var(--button-padding-y-md,0.5rem)]",
|
|
793
|
-
"has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
|
|
794
|
-
].join(" "),
|
|
795
|
-
lg: [
|
|
796
|
-
"h-[var(--button-height-lg,2.5rem)]",
|
|
797
|
-
"px-[var(--button-padding-x-lg,1.5rem)]",
|
|
798
|
-
"py-[var(--button-padding-y-lg,0.5rem)]",
|
|
799
|
-
"has-[>svg]:px-[calc(var(--button-padding-x-lg,1.5rem)*0.67)]"
|
|
800
|
-
].join(" "),
|
|
801
|
-
icon: "size-[var(--button-height-md,2.25rem)]",
|
|
802
|
-
"icon-sm": "size-[var(--button-height-sm,2rem)]",
|
|
803
|
-
"icon-lg": "size-[var(--button-height-lg,2.5rem)]"
|
|
804
|
-
}
|
|
805
|
-
},
|
|
806
|
-
defaultVariants: {
|
|
807
|
-
variant: "default",
|
|
808
|
-
size: "default"
|
|
809
|
-
}
|
|
810
|
-
});
|
|
811
|
-
var Pressable = React6.forwardRef(
|
|
812
|
-
({
|
|
813
|
-
children,
|
|
814
|
-
className,
|
|
815
|
-
href,
|
|
816
|
-
onClick,
|
|
817
|
-
variant,
|
|
818
|
-
size,
|
|
819
|
-
asButton = false,
|
|
820
|
-
fallbackComponentType = "span",
|
|
821
|
-
componentType,
|
|
822
|
-
"aria-label": ariaLabel,
|
|
823
|
-
"aria-describedby": ariaDescribedby,
|
|
824
|
-
id,
|
|
825
|
-
...props
|
|
826
|
-
}, ref) => {
|
|
827
|
-
const navigation = useNavigation({ href, onClick });
|
|
828
|
-
const {
|
|
829
|
-
normalizedHref,
|
|
830
|
-
target,
|
|
831
|
-
rel,
|
|
832
|
-
linkType,
|
|
833
|
-
isInternal,
|
|
834
|
-
isExternal,
|
|
835
|
-
handleClick
|
|
836
|
-
} = navigation;
|
|
837
|
-
const shouldRenderLink = normalizedHref && linkType !== "none";
|
|
838
|
-
const shouldRenderButton = !shouldRenderLink && onClick;
|
|
839
|
-
const effectiveComponentType = componentType || (shouldRenderLink ? "a" : shouldRenderButton ? "button" : fallbackComponentType);
|
|
840
|
-
const finalComponentType = isInternal && shouldRenderLink ? "a" : effectiveComponentType;
|
|
841
|
-
const shouldApplyButtonStyles = asButton || variant || size;
|
|
842
|
-
const combinedClassName = cn(
|
|
843
|
-
shouldApplyButtonStyles && buttonVariants({ variant, size }),
|
|
844
|
-
className
|
|
845
|
-
);
|
|
846
|
-
const dataProps = Object.fromEntries(
|
|
847
|
-
Object.entries(props).filter(([key]) => key.startsWith("data-"))
|
|
848
|
-
);
|
|
849
|
-
const buttonDataAttributes = shouldApplyButtonStyles ? {
|
|
850
|
-
"data-slot": "button",
|
|
851
|
-
"data-variant": variant ?? "default",
|
|
852
|
-
"data-size": size ?? "default"
|
|
853
|
-
} : {};
|
|
854
|
-
const commonProps = {
|
|
855
|
-
className: combinedClassName,
|
|
856
|
-
onClick: handleClick,
|
|
857
|
-
"aria-label": ariaLabel,
|
|
858
|
-
"aria-describedby": ariaDescribedby,
|
|
859
|
-
id,
|
|
860
|
-
...dataProps,
|
|
861
|
-
...buttonDataAttributes
|
|
862
|
-
};
|
|
863
|
-
if (finalComponentType === "a" && shouldRenderLink) {
|
|
864
|
-
return /* @__PURE__ */ jsx(
|
|
865
|
-
"a",
|
|
866
|
-
{
|
|
867
|
-
ref,
|
|
868
|
-
href: normalizedHref,
|
|
869
|
-
target,
|
|
870
|
-
rel,
|
|
871
|
-
...commonProps,
|
|
872
|
-
...props,
|
|
873
|
-
children
|
|
874
|
-
}
|
|
875
|
-
);
|
|
876
|
-
}
|
|
877
|
-
if (finalComponentType === "button") {
|
|
878
|
-
return /* @__PURE__ */ jsx(
|
|
879
|
-
"button",
|
|
880
|
-
{
|
|
881
|
-
ref,
|
|
882
|
-
type: props.type || "button",
|
|
883
|
-
...commonProps,
|
|
884
|
-
...props,
|
|
885
|
-
children
|
|
886
|
-
}
|
|
887
|
-
);
|
|
888
|
-
}
|
|
889
|
-
if (finalComponentType === "div") {
|
|
890
|
-
return /* @__PURE__ */ jsx(
|
|
891
|
-
"div",
|
|
892
|
-
{
|
|
893
|
-
ref,
|
|
894
|
-
...commonProps,
|
|
895
|
-
children
|
|
896
|
-
}
|
|
897
|
-
);
|
|
898
|
-
}
|
|
899
|
-
return /* @__PURE__ */ jsx(
|
|
900
|
-
"span",
|
|
901
|
-
{
|
|
902
|
-
ref,
|
|
903
|
-
...commonProps,
|
|
904
|
-
children
|
|
905
|
-
}
|
|
906
|
-
);
|
|
907
|
-
}
|
|
908
|
-
);
|
|
909
|
-
Pressable.displayName = "Pressable";
|
|
910
|
-
var DEFAULT_ICON_API_KEY = "au382bi7fsh96w9h9xlrnat2jglx";
|
|
911
|
-
var DynamicIcon = React6.memo(function DynamicIcon2({
|
|
912
|
-
apiKey,
|
|
913
|
-
...props
|
|
914
|
-
}) {
|
|
915
|
-
return /* @__PURE__ */ jsx(Icon, { ...props, apiKey: apiKey ?? DEFAULT_ICON_API_KEY });
|
|
916
|
-
});
|
|
917
|
-
DynamicIcon.displayName = "DynamicIcon";
|
|
918
|
-
var PANEL_POSITION_CLASS = {
|
|
919
|
-
"top-left": "left-4 top-4",
|
|
920
|
-
"top-right": "right-4 top-4",
|
|
921
|
-
"bottom-left": "bottom-4 left-4",
|
|
922
|
-
"bottom-right": "bottom-4 right-4"
|
|
923
|
-
};
|
|
924
|
-
var DEFAULT_VIEW_STATE = {
|
|
925
|
-
latitude: 39.5,
|
|
926
|
-
longitude: -98.35,
|
|
927
|
-
zoom: 3
|
|
928
|
-
};
|
|
929
|
-
var VIDEO_FILE_EXTENSION_REGEX = /\.(mp4|webm|ogg|mov|m4v|m3u8)(\?.*)?$/i;
|
|
930
|
-
function resolveMediaType(item) {
|
|
931
|
-
if (item.type) {
|
|
932
|
-
return item.type;
|
|
933
|
-
}
|
|
934
|
-
return VIDEO_FILE_EXTENSION_REGEX.test(item.src) ? "video" : "image";
|
|
935
|
-
}
|
|
936
|
-
function normalizeId(value, fallback) {
|
|
937
|
-
if (value === null || value === void 0 || value === "") {
|
|
938
|
-
return fallback;
|
|
939
|
-
}
|
|
940
|
-
return String(value);
|
|
941
|
-
}
|
|
942
|
-
function buildClusterCenter(markers) {
|
|
943
|
-
if (!markers.length) {
|
|
944
|
-
return null;
|
|
945
|
-
}
|
|
946
|
-
const total = markers.reduce(
|
|
947
|
-
(accumulator, marker) => ({
|
|
948
|
-
latitude: accumulator.latitude + marker.latitude,
|
|
949
|
-
longitude: accumulator.longitude + marker.longitude
|
|
950
|
-
}),
|
|
951
|
-
{ latitude: 0, longitude: 0 }
|
|
952
|
-
);
|
|
953
|
-
return {
|
|
954
|
-
latitude: total.latitude / markers.length,
|
|
955
|
-
longitude: total.longitude / markers.length
|
|
956
|
-
};
|
|
957
|
-
}
|
|
958
|
-
function resolveActionKey(action, index) {
|
|
959
|
-
if (typeof action.label === "string" && action.label.trim().length > 0) {
|
|
960
|
-
return `label:${action.label}:${index}`;
|
|
961
|
-
}
|
|
962
|
-
if (action.href) {
|
|
963
|
-
return `href:${action.href}:${index}`;
|
|
964
|
-
}
|
|
965
|
-
return `action:${index}`;
|
|
966
|
-
}
|
|
967
|
-
function MarkerActions({ actions }) {
|
|
968
|
-
if (!actions || actions.length === 0) {
|
|
969
|
-
return null;
|
|
970
|
-
}
|
|
971
|
-
return /* @__PURE__ */ jsx("div", { className: "mt-4 flex flex-wrap gap-2", children: actions.map((action, index) => {
|
|
972
|
-
const {
|
|
973
|
-
label,
|
|
974
|
-
icon,
|
|
975
|
-
iconAfter,
|
|
976
|
-
children,
|
|
977
|
-
href,
|
|
978
|
-
onClick,
|
|
979
|
-
className: actionClassName,
|
|
980
|
-
variant,
|
|
981
|
-
size,
|
|
982
|
-
asButton,
|
|
983
|
-
...rest
|
|
984
|
-
} = action;
|
|
985
|
-
return /* @__PURE__ */ jsx(
|
|
986
|
-
Pressable,
|
|
987
|
-
{
|
|
988
|
-
href,
|
|
989
|
-
onClick,
|
|
990
|
-
variant: variant ?? (index === 0 ? "default" : "outline"),
|
|
991
|
-
size: size ?? "sm",
|
|
992
|
-
asButton: asButton ?? true,
|
|
993
|
-
className: cn("inline-flex items-center gap-2", actionClassName),
|
|
994
|
-
...rest,
|
|
995
|
-
children: children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
996
|
-
icon,
|
|
997
|
-
label,
|
|
998
|
-
iconAfter
|
|
999
|
-
] })
|
|
1000
|
-
},
|
|
1001
|
-
resolveActionKey(action, index)
|
|
1002
|
-
);
|
|
1003
|
-
}) });
|
|
1004
|
-
}
|
|
1005
|
-
function MarkerMediaCarousel({
|
|
1006
|
-
mediaItems,
|
|
1007
|
-
optixFlowConfig
|
|
1008
|
-
}) {
|
|
1009
|
-
const [activeIndex, setActiveIndex] = React6.useState(0);
|
|
1010
|
-
const totalItems = mediaItems.length;
|
|
1011
|
-
const mediaResetKey = React6.useMemo(
|
|
1012
|
-
() => mediaItems.map((item, index) => {
|
|
1013
|
-
const itemId = normalizeId(item.id, `media-${index}`);
|
|
1014
|
-
return `${itemId}:${item.src}:${item.type ?? ""}:${item.poster ?? ""}`;
|
|
1015
|
-
}).join("|"),
|
|
1016
|
-
[mediaItems]
|
|
1017
|
-
);
|
|
1018
|
-
const activeItemIndex = Math.min(activeIndex, Math.max(0, totalItems - 1));
|
|
1019
|
-
React6.useEffect(() => {
|
|
1020
|
-
setActiveIndex(0);
|
|
1021
|
-
}, [mediaResetKey]);
|
|
1022
|
-
return /* @__PURE__ */ jsxs("div", { className: "relative border-b border-border/60 bg-muted/40", children: [
|
|
1023
|
-
/* @__PURE__ */ jsx("div", { className: "relative aspect-video w-full overflow-hidden", children: mediaItems.map((item, index) => {
|
|
1024
|
-
const isActive = index === activeItemIndex;
|
|
1025
|
-
const mediaType = resolveMediaType(item);
|
|
1026
|
-
return /* @__PURE__ */ jsx(
|
|
1027
|
-
"div",
|
|
1028
|
-
{
|
|
1029
|
-
"aria-hidden": !isActive,
|
|
1030
|
-
className: cn(
|
|
1031
|
-
"absolute inset-0 transition-opacity duration-500 ease-in-out",
|
|
1032
|
-
isActive ? "opacity-100 z-[1]" : "opacity-0 z-0 pointer-events-none"
|
|
1033
|
-
),
|
|
1034
|
-
children: mediaType === "video" ? /* @__PURE__ */ jsx(
|
|
1035
|
-
"video",
|
|
1036
|
-
{
|
|
1037
|
-
className: "h-full w-full object-cover",
|
|
1038
|
-
controls: isActive,
|
|
1039
|
-
preload: "metadata",
|
|
1040
|
-
poster: item.poster,
|
|
1041
|
-
tabIndex: isActive ? 0 : -1,
|
|
1042
|
-
children: /* @__PURE__ */ jsx("source", { src: item.src })
|
|
1043
|
-
}
|
|
1044
|
-
) : /* @__PURE__ */ jsx(
|
|
1045
|
-
Img,
|
|
1046
|
-
{
|
|
1047
|
-
src: item.src,
|
|
1048
|
-
alt: item.alt ?? "Map marker media",
|
|
1049
|
-
className: "h-full w-full object-cover",
|
|
1050
|
-
loading: "eager",
|
|
1051
|
-
optixFlowConfig
|
|
1052
|
-
}
|
|
1053
|
-
)
|
|
1054
|
-
},
|
|
1055
|
-
normalizeId(item.id, `media-slide-${index}`)
|
|
1056
|
-
);
|
|
1057
|
-
}) }),
|
|
1058
|
-
totalItems > 1 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1059
|
-
/* @__PURE__ */ jsx(
|
|
1060
|
-
"button",
|
|
1061
|
-
{
|
|
1062
|
-
type: "button",
|
|
1063
|
-
"aria-label": "Show previous media",
|
|
1064
|
-
className: "absolute left-4 top-1/2 inline-flex size-10 -translate-y-1/2 items-center justify-center rounded-2xl bg-card text-card-foreground shadow-lg border-4 border-black hover:border-white hover:bg-black hover:text-white transition-all duration-500 z-[2]",
|
|
1065
|
-
onClick: () => {
|
|
1066
|
-
setActiveIndex(
|
|
1067
|
-
(current) => (current - 1 + totalItems) % totalItems
|
|
1068
|
-
);
|
|
1069
|
-
},
|
|
1070
|
-
children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/arrow-left", size: 18 })
|
|
1071
|
-
}
|
|
1072
|
-
),
|
|
1073
|
-
/* @__PURE__ */ jsx(
|
|
1074
|
-
"button",
|
|
1075
|
-
{
|
|
1076
|
-
type: "button",
|
|
1077
|
-
"aria-label": "Show next media",
|
|
1078
|
-
className: "absolute right-4 top-1/2 inline-flex size-10 -translate-y-1/2 items-center justify-center rounded-2xl bg-card text-card-foreground shadow-lg border-4 border-black hover:border-white hover:bg-black hover:text-white transition-all duration-500 z-[2]",
|
|
1079
|
-
onClick: () => {
|
|
1080
|
-
setActiveIndex((current) => (current + 1) % totalItems);
|
|
1081
|
-
},
|
|
1082
|
-
children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/arrow-right", size: 18 })
|
|
1083
|
-
}
|
|
1084
|
-
),
|
|
1085
|
-
/* @__PURE__ */ jsx("div", { className: "absolute bottom-2 left-1/2 flex -translate-x-1/2 items-center gap-1.5 z-[2]", children: mediaItems.map((item, index) => /* @__PURE__ */ jsx(
|
|
1086
|
-
"button",
|
|
1087
|
-
{
|
|
1088
|
-
type: "button",
|
|
1089
|
-
"aria-label": `Show media item ${index + 1}`,
|
|
1090
|
-
className: cn(
|
|
1091
|
-
"h-2 rounded-full transition-all duration-300",
|
|
1092
|
-
index === activeItemIndex ? "w-6 bg-card" : "w-2 bg-card opacity-50 hover:opacity-100"
|
|
1093
|
-
),
|
|
1094
|
-
onClick: () => setActiveIndex(index)
|
|
1095
|
-
},
|
|
1096
|
-
normalizeId(item.id, `media-dot-${index}`)
|
|
1097
|
-
)) })
|
|
1098
|
-
] }) : null
|
|
1099
|
-
] });
|
|
1100
|
-
}
|
|
1101
|
-
function getMarkerTitle(marker, markerIndex) {
|
|
1102
|
-
if (marker.title !== void 0 && marker.title !== null) {
|
|
1103
|
-
return marker.title;
|
|
1104
|
-
}
|
|
1105
|
-
if (marker.label !== void 0 && marker.label !== null) {
|
|
1106
|
-
return marker.label;
|
|
1107
|
-
}
|
|
1108
|
-
return `Location ${markerIndex + 1}`;
|
|
1109
|
-
}
|
|
1110
|
-
function GeoMap({
|
|
1111
|
-
className,
|
|
1112
|
-
mapWrapperClassName,
|
|
1113
|
-
mapClassName,
|
|
1114
|
-
panelClassName,
|
|
1115
|
-
panelPosition = "top-left",
|
|
1116
|
-
stadiaApiKey = "",
|
|
1117
|
-
mapStyle = "osm-bright",
|
|
1118
|
-
styleUrl,
|
|
1119
|
-
mapLibreCssHref,
|
|
1120
|
-
markers = [],
|
|
1121
|
-
clusters = [],
|
|
1122
|
-
viewState,
|
|
1123
|
-
defaultViewState,
|
|
1124
|
-
onViewStateChange,
|
|
1125
|
-
onMapClick,
|
|
1126
|
-
onMarkerDrag,
|
|
1127
|
-
showNavigationControl = true,
|
|
1128
|
-
showGeolocateControl = false,
|
|
1129
|
-
navigationControlPosition = "top-right",
|
|
1130
|
-
geolocateControlPosition = "top-left",
|
|
1131
|
-
flyToOptions,
|
|
1132
|
-
markerFocusZoom = 14,
|
|
1133
|
-
clusterFocusZoom = 5,
|
|
1134
|
-
selectedMarkerId,
|
|
1135
|
-
initialSelectedMarkerId,
|
|
1136
|
-
onSelectionChange,
|
|
1137
|
-
clearSelectionOnMapClick = true,
|
|
1138
|
-
mapChildren,
|
|
1139
|
-
optixFlowConfig
|
|
1140
|
-
}) {
|
|
1141
|
-
const normalizedStandaloneMarkers = React6.useMemo(
|
|
1142
|
-
() => markers.map((marker, index) => ({
|
|
1143
|
-
...marker,
|
|
1144
|
-
id: normalizeId(marker.id, `marker-${index}`)
|
|
1145
|
-
})),
|
|
1146
|
-
[markers]
|
|
1147
|
-
);
|
|
1148
|
-
const normalizedClusters = React6.useMemo(() => {
|
|
1149
|
-
const results = [];
|
|
1150
|
-
clusters.forEach((cluster, clusterIndex) => {
|
|
1151
|
-
const clusterId = normalizeId(cluster.id, `cluster-${clusterIndex}`);
|
|
1152
|
-
const normalizedClusterMarkers = cluster.markers.map(
|
|
1153
|
-
(marker, markerIndex) => ({
|
|
1154
|
-
...marker,
|
|
1155
|
-
id: normalizeId(marker.id, `${clusterId}-marker-${markerIndex}`),
|
|
1156
|
-
clusterId
|
|
1157
|
-
})
|
|
1158
|
-
);
|
|
1159
|
-
const clusterCenter = cluster.latitude !== void 0 && cluster.longitude !== void 0 ? { latitude: cluster.latitude, longitude: cluster.longitude } : buildClusterCenter(normalizedClusterMarkers);
|
|
1160
|
-
if (!clusterCenter) {
|
|
1161
|
-
return;
|
|
1162
|
-
}
|
|
1163
|
-
results.push({
|
|
1164
|
-
...cluster,
|
|
1165
|
-
id: clusterId,
|
|
1166
|
-
latitude: clusterCenter.latitude,
|
|
1167
|
-
longitude: clusterCenter.longitude,
|
|
1168
|
-
markers: normalizedClusterMarkers
|
|
1169
|
-
});
|
|
1170
|
-
});
|
|
1171
|
-
return results;
|
|
1172
|
-
}, [clusters]);
|
|
1173
|
-
const markerLookup = React6.useMemo(() => {
|
|
1174
|
-
const lookup = /* @__PURE__ */ new Map();
|
|
1175
|
-
normalizedStandaloneMarkers.forEach((marker) => {
|
|
1176
|
-
lookup.set(marker.id, marker);
|
|
1177
|
-
});
|
|
1178
|
-
normalizedClusters.forEach((cluster) => {
|
|
1179
|
-
cluster.markers.forEach((marker) => {
|
|
1180
|
-
lookup.set(marker.id, marker);
|
|
1181
|
-
});
|
|
1182
|
-
});
|
|
1183
|
-
return lookup;
|
|
1184
|
-
}, [normalizedClusters, normalizedStandaloneMarkers]);
|
|
1185
|
-
const clusterLookup = React6.useMemo(() => {
|
|
1186
|
-
const lookup = /* @__PURE__ */ new Map();
|
|
1187
|
-
normalizedClusters.forEach((cluster) => {
|
|
1188
|
-
lookup.set(cluster.id, cluster);
|
|
1189
|
-
});
|
|
1190
|
-
return lookup;
|
|
1191
|
-
}, [normalizedClusters]);
|
|
1192
|
-
const firstCoordinate = React6.useMemo(() => {
|
|
1193
|
-
if (normalizedStandaloneMarkers.length > 0) {
|
|
1194
|
-
const firstStandaloneMarker = normalizedStandaloneMarkers[0];
|
|
1195
|
-
return {
|
|
1196
|
-
latitude: firstStandaloneMarker.latitude,
|
|
1197
|
-
longitude: firstStandaloneMarker.longitude
|
|
1198
|
-
};
|
|
1199
|
-
}
|
|
1200
|
-
if (normalizedClusters.length > 0) {
|
|
1201
|
-
const firstCluster = normalizedClusters[0];
|
|
1202
|
-
return {
|
|
1203
|
-
latitude: firstCluster.latitude,
|
|
1204
|
-
longitude: firstCluster.longitude
|
|
1205
|
-
};
|
|
1206
|
-
}
|
|
1207
|
-
return {
|
|
1208
|
-
latitude: DEFAULT_VIEW_STATE.latitude,
|
|
1209
|
-
longitude: DEFAULT_VIEW_STATE.longitude
|
|
1210
|
-
};
|
|
1211
|
-
}, [normalizedClusters, normalizedStandaloneMarkers]);
|
|
1212
|
-
const [uncontrolledViewState, setUncontrolledViewState] = React6.useState({
|
|
1213
|
-
latitude: defaultViewState?.latitude ?? firstCoordinate.latitude,
|
|
1214
|
-
longitude: defaultViewState?.longitude ?? firstCoordinate.longitude,
|
|
1215
|
-
zoom: defaultViewState?.zoom ?? DEFAULT_VIEW_STATE.zoom
|
|
1216
|
-
});
|
|
1217
|
-
const isControlledViewState = viewState !== void 0;
|
|
1218
|
-
const resolvedViewState = isControlledViewState ? viewState : uncontrolledViewState;
|
|
1219
|
-
const applyViewState = React6.useCallback(
|
|
1220
|
-
(nextState) => {
|
|
1221
|
-
if (!isControlledViewState) {
|
|
1222
|
-
setUncontrolledViewState((current) => {
|
|
1223
|
-
const next = { ...current, ...nextState };
|
|
1224
|
-
const hasChanged = current.latitude !== next.latitude || current.longitude !== next.longitude || current.zoom !== next.zoom;
|
|
1225
|
-
return hasChanged ? next : current;
|
|
1226
|
-
});
|
|
1227
|
-
}
|
|
1228
|
-
onViewStateChange?.(nextState);
|
|
1229
|
-
},
|
|
1230
|
-
[isControlledViewState, onViewStateChange]
|
|
1231
|
-
);
|
|
1232
|
-
const [selection, setSelection] = React6.useState(() => {
|
|
1233
|
-
if (initialSelectedMarkerId !== void 0 && initialSelectedMarkerId !== null) {
|
|
1234
|
-
return {
|
|
1235
|
-
type: "marker",
|
|
1236
|
-
markerId: String(initialSelectedMarkerId)
|
|
1237
|
-
};
|
|
1238
|
-
}
|
|
1239
|
-
return { type: "none" };
|
|
1240
|
-
});
|
|
1241
|
-
React6.useEffect(() => {
|
|
1242
|
-
if (selectedMarkerId === void 0 || selectedMarkerId === null) {
|
|
1243
|
-
return;
|
|
1244
|
-
}
|
|
1245
|
-
setSelection({
|
|
1246
|
-
type: "marker",
|
|
1247
|
-
markerId: String(selectedMarkerId)
|
|
1248
|
-
});
|
|
1249
|
-
}, [selectedMarkerId]);
|
|
1250
|
-
const selectedMarker = selection.markerId ? markerLookup.get(selection.markerId) : void 0;
|
|
1251
|
-
const selectedCluster = selection.clusterId ? clusterLookup.get(selection.clusterId) : void 0;
|
|
1252
|
-
React6.useEffect(() => {
|
|
1253
|
-
if (selection.type === "marker" && selection.markerId && !selectedMarker) {
|
|
1254
|
-
setSelection({ type: "none" });
|
|
1255
|
-
onSelectionChange?.({ type: "none" });
|
|
1256
|
-
}
|
|
1257
|
-
}, [onSelectionChange, selectedMarker, selection]);
|
|
1258
|
-
const emitSelectionChange = React6.useCallback(
|
|
1259
|
-
(nextSelection) => {
|
|
1260
|
-
if (nextSelection.type === "none") {
|
|
1261
|
-
onSelectionChange?.({ type: "none" });
|
|
1262
|
-
return;
|
|
1263
|
-
}
|
|
1264
|
-
if (nextSelection.type === "marker") {
|
|
1265
|
-
const parentCluster = nextSelection.marker.clusterId ? clusterLookup.get(nextSelection.marker.clusterId) : void 0;
|
|
1266
|
-
onSelectionChange?.({
|
|
1267
|
-
type: "marker",
|
|
1268
|
-
marker: nextSelection.marker,
|
|
1269
|
-
cluster: parentCluster
|
|
1270
|
-
});
|
|
1271
|
-
return;
|
|
1272
|
-
}
|
|
1273
|
-
onSelectionChange?.({
|
|
1274
|
-
type: "cluster",
|
|
1275
|
-
cluster: nextSelection.cluster
|
|
1276
|
-
});
|
|
1277
|
-
},
|
|
1278
|
-
[clusterLookup, onSelectionChange]
|
|
1279
|
-
);
|
|
1280
|
-
const selectMarker = React6.useCallback(
|
|
1281
|
-
(marker) => {
|
|
1282
|
-
setSelection({
|
|
1283
|
-
type: "marker",
|
|
1284
|
-
markerId: marker.id,
|
|
1285
|
-
clusterId: marker.clusterId
|
|
1286
|
-
});
|
|
1287
|
-
applyViewState({
|
|
1288
|
-
latitude: marker.latitude,
|
|
1289
|
-
longitude: marker.longitude,
|
|
1290
|
-
zoom: markerFocusZoom
|
|
1291
|
-
});
|
|
1292
|
-
emitSelectionChange({ type: "marker", marker });
|
|
1293
|
-
},
|
|
1294
|
-
[applyViewState, emitSelectionChange, markerFocusZoom]
|
|
1295
|
-
);
|
|
1296
|
-
const selectCluster = React6.useCallback(
|
|
1297
|
-
(cluster) => {
|
|
1298
|
-
setSelection({
|
|
1299
|
-
type: "cluster",
|
|
1300
|
-
clusterId: cluster.id
|
|
1301
|
-
});
|
|
1302
|
-
applyViewState({
|
|
1303
|
-
latitude: cluster.latitude,
|
|
1304
|
-
longitude: cluster.longitude,
|
|
1305
|
-
zoom: clusterFocusZoom
|
|
1306
|
-
});
|
|
1307
|
-
emitSelectionChange({ type: "cluster", cluster });
|
|
1308
|
-
},
|
|
1309
|
-
[applyViewState, clusterFocusZoom, emitSelectionChange]
|
|
1310
|
-
);
|
|
1311
|
-
const clearSelection = React6.useCallback(() => {
|
|
1312
|
-
setSelection({ type: "none" });
|
|
1313
|
-
emitSelectionChange({ type: "none" });
|
|
1314
|
-
}, [emitSelectionChange]);
|
|
1315
|
-
const mapMarkers = React6.useMemo(() => {
|
|
1316
|
-
const resolvedMarkers = [];
|
|
1317
|
-
normalizedClusters.forEach((cluster) => {
|
|
1318
|
-
const isSelected = selection.type === "cluster" && selection.clusterId === cluster.id;
|
|
1319
|
-
resolvedMarkers.push({
|
|
1320
|
-
id: `cluster-pin:${cluster.id}`,
|
|
1321
|
-
latitude: cluster.latitude,
|
|
1322
|
-
longitude: cluster.longitude,
|
|
1323
|
-
element: () => {
|
|
1324
|
-
const customMarkerElement = cluster.markerElement;
|
|
1325
|
-
const markerBody = typeof customMarkerElement === "function" ? customMarkerElement({
|
|
1326
|
-
isSelected,
|
|
1327
|
-
count: cluster.markers.length
|
|
1328
|
-
}) : customMarkerElement;
|
|
1329
|
-
return /* @__PURE__ */ jsx(
|
|
1330
|
-
"button",
|
|
1331
|
-
{
|
|
1332
|
-
type: "button",
|
|
1333
|
-
className: "group cursor-pointer",
|
|
1334
|
-
onClick: (event) => {
|
|
1335
|
-
event.preventDefault();
|
|
1336
|
-
event.stopPropagation();
|
|
1337
|
-
selectCluster(cluster);
|
|
1338
|
-
},
|
|
1339
|
-
"aria-label": `View ${cluster.markers.length} clustered locations`,
|
|
1340
|
-
children: markerBody ?? /* @__PURE__ */ jsx(
|
|
1341
|
-
"span",
|
|
1342
|
-
{
|
|
1343
|
-
className: cn(
|
|
1344
|
-
"inline-flex min-h-10 min-w-10 items-center justify-center rounded-full border-2 border-white px-2 text-xs font-semibold text-white shadow-lg transition-transform duration-200 group-hover:scale-105",
|
|
1345
|
-
isSelected && "ring-4 ring-primary/30",
|
|
1346
|
-
cluster.pinClassName
|
|
1347
|
-
),
|
|
1348
|
-
style: {
|
|
1349
|
-
backgroundColor: cluster.pinColor ?? "var(--foreground)"
|
|
1350
|
-
},
|
|
1351
|
-
children: cluster.markers.length
|
|
1352
|
-
}
|
|
1353
|
-
)
|
|
1354
|
-
}
|
|
1355
|
-
);
|
|
1356
|
-
}
|
|
1357
|
-
});
|
|
1358
|
-
});
|
|
1359
|
-
normalizedStandaloneMarkers.forEach((marker) => {
|
|
1360
|
-
const isSelected = selection.type === "marker" && selection.markerId === marker.id;
|
|
1361
|
-
const customMarkerElement = marker.markerElement;
|
|
1362
|
-
resolvedMarkers.push({
|
|
1363
|
-
id: marker.id,
|
|
1364
|
-
latitude: marker.latitude,
|
|
1365
|
-
longitude: marker.longitude,
|
|
1366
|
-
draggable: marker.draggable,
|
|
1367
|
-
element: () => {
|
|
1368
|
-
const markerBody = typeof customMarkerElement === "function" ? customMarkerElement({ isSelected }) : customMarkerElement;
|
|
1369
|
-
return /* @__PURE__ */ jsx(
|
|
1370
|
-
"button",
|
|
1371
|
-
{
|
|
1372
|
-
type: "button",
|
|
1373
|
-
className: "group cursor-pointer",
|
|
1374
|
-
onClick: (event) => {
|
|
1375
|
-
event.preventDefault();
|
|
1376
|
-
event.stopPropagation();
|
|
1377
|
-
selectMarker(marker);
|
|
1378
|
-
},
|
|
1379
|
-
"aria-label": typeof marker.title === "string" ? `View ${marker.title}` : "View location details",
|
|
1380
|
-
children: markerBody ?? /* @__PURE__ */ jsx(
|
|
1381
|
-
"span",
|
|
1382
|
-
{
|
|
1383
|
-
className: cn(
|
|
1384
|
-
"inline-flex h-4 w-4 rounded-full border-2 border-white shadow-md transition-transform duration-200 group-hover:scale-110",
|
|
1385
|
-
isSelected && "h-5 w-5 ring-4 ring-primary/30",
|
|
1386
|
-
marker.pinClassName
|
|
1387
|
-
),
|
|
1388
|
-
style: {
|
|
1389
|
-
backgroundColor: marker.pinColor ?? "#f43f5e"
|
|
1390
|
-
}
|
|
1391
|
-
}
|
|
1392
|
-
)
|
|
1393
|
-
}
|
|
1394
|
-
);
|
|
1395
|
-
}
|
|
1396
|
-
});
|
|
1397
|
-
});
|
|
1398
|
-
return resolvedMarkers;
|
|
1399
|
-
}, [
|
|
1400
|
-
normalizedClusters,
|
|
1401
|
-
normalizedStandaloneMarkers,
|
|
1402
|
-
selectCluster,
|
|
1403
|
-
selectMarker,
|
|
1404
|
-
selection
|
|
1405
|
-
]);
|
|
1406
|
-
const renderMarkerPanel = () => {
|
|
1407
|
-
if (selectedMarker) {
|
|
1408
|
-
const markerMediaItems = selectedMarker.mediaItems ?? [];
|
|
1409
|
-
return /* @__PURE__ */ jsxs(
|
|
1410
|
-
"div",
|
|
1411
|
-
{
|
|
1412
|
-
className: cn(
|
|
1413
|
-
"relative w-[min(24rem,calc(100vw-2rem))] overflow-hidden rounded-xl border border-border bg-card text-card-foreground shadow-2xl",
|
|
1414
|
-
panelClassName
|
|
1415
|
-
),
|
|
1416
|
-
children: [
|
|
1417
|
-
/* @__PURE__ */ jsx(
|
|
1418
|
-
"button",
|
|
1419
|
-
{
|
|
1420
|
-
type: "button",
|
|
1421
|
-
"aria-label": "Close marker details",
|
|
1422
|
-
className: "\n flex size-12 items-center justify-center rounded-bl-lg rounded-br-0 rounded-t-0 bg-black text-white transition-all duration-500 absolute top-0 right-0 z-10 cursor-pointer ring-4 ring-white\n",
|
|
1423
|
-
onClick: clearSelection,
|
|
1424
|
-
children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/x", size: 20 })
|
|
1425
|
-
}
|
|
1426
|
-
),
|
|
1427
|
-
markerMediaItems.length > 0 ? /* @__PURE__ */ jsx(
|
|
1428
|
-
MarkerMediaCarousel,
|
|
1429
|
-
{
|
|
1430
|
-
mediaItems: markerMediaItems,
|
|
1431
|
-
optixFlowConfig
|
|
1432
|
-
}
|
|
1433
|
-
) : null,
|
|
1434
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-2 p-4", children: [
|
|
1435
|
-
/* @__PURE__ */ jsx("div", { className: "flex items-start justify-between gap-3", children: /* @__PURE__ */ jsxs("div", { className: "min-w-0 space-y-1", children: [
|
|
1436
|
-
selectedMarker.eyebrow ? /* @__PURE__ */ jsx("p", { className: "text-xs font-semibold uppercase tracking-wide", children: selectedMarker.eyebrow }) : null,
|
|
1437
|
-
/* @__PURE__ */ jsx("div", { className: "text-base font-semibold leading-tight", children: selectedMarker.title ?? selectedMarker.label ?? "Location" })
|
|
1438
|
-
] }) }),
|
|
1439
|
-
selectedMarker.summary ? /* @__PURE__ */ jsx("div", { className: "text-sm leading-relaxed", children: selectedMarker.summary }) : null,
|
|
1440
|
-
selectedMarker.locationLine ? /* @__PURE__ */ jsxs("div", { className: "flex flex-row items-center justify-start text-sm gap-2", children: [
|
|
1441
|
-
/* @__PURE__ */ jsx(
|
|
1442
|
-
DynamicIcon,
|
|
1443
|
-
{
|
|
1444
|
-
name: "lucide:map-pin",
|
|
1445
|
-
className: "opacity-50",
|
|
1446
|
-
size: 18
|
|
1447
|
-
}
|
|
1448
|
-
),
|
|
1449
|
-
typeof selectedMarker.locationLine === "string" ? /* @__PURE__ */ jsx(
|
|
1450
|
-
Pressable,
|
|
1451
|
-
{
|
|
1452
|
-
href: selectedMarker.locationUrl,
|
|
1453
|
-
className: cn(
|
|
1454
|
-
"transition-all duration-500",
|
|
1455
|
-
"font-medium opacity-75 hover:opacity-100",
|
|
1456
|
-
selectedMarker.locationUrl ? "underline underline-offset-4" : ""
|
|
1457
|
-
),
|
|
1458
|
-
children: selectedMarker.locationLine
|
|
1459
|
-
}
|
|
1460
|
-
) : selectedMarker.locationLine
|
|
1461
|
-
] }) : null,
|
|
1462
|
-
selectedMarker.hoursLine ? /* @__PURE__ */ jsxs("div", { className: "flex flex-row items-center justify-start text-sm gap-2", children: [
|
|
1463
|
-
/* @__PURE__ */ jsx(
|
|
1464
|
-
DynamicIcon,
|
|
1465
|
-
{
|
|
1466
|
-
name: "lucide:clock",
|
|
1467
|
-
className: "opacity-50",
|
|
1468
|
-
size: 18
|
|
1469
|
-
}
|
|
1470
|
-
),
|
|
1471
|
-
typeof selectedMarker.hoursLine === "string" ? /* @__PURE__ */ jsx("div", { className: "font-medium", children: selectedMarker.hoursLine }) : selectedMarker.hoursLine
|
|
1472
|
-
] }) : null,
|
|
1473
|
-
selectedMarker.markerContentComponent ? /* @__PURE__ */ jsx("div", { className: "relative", children: selectedMarker.markerContentComponent }) : null,
|
|
1474
|
-
/* @__PURE__ */ jsx(MarkerActions, { actions: selectedMarker.actions })
|
|
1475
|
-
] })
|
|
1476
|
-
]
|
|
1477
|
-
}
|
|
1478
|
-
);
|
|
1479
|
-
}
|
|
1480
|
-
if (selectedCluster) {
|
|
1481
|
-
return /* @__PURE__ */ jsxs(
|
|
1482
|
-
"div",
|
|
1483
|
-
{
|
|
1484
|
-
className: cn(
|
|
1485
|
-
"relative w-[min(24rem,calc(100vw-2rem))] overflow-hidden rounded-xl border border-border bg-card text-card-foreground p-4 shadow-2xl",
|
|
1486
|
-
panelClassName
|
|
1487
|
-
),
|
|
1488
|
-
children: [
|
|
1489
|
-
/* @__PURE__ */ jsx(
|
|
1490
|
-
"button",
|
|
1491
|
-
{
|
|
1492
|
-
type: "button",
|
|
1493
|
-
"aria-label": "Close cluster details",
|
|
1494
|
-
className: "flex size-8 items-center justify-center rounded-full border border-border bg-card text-card-foreground transition hover:bg-muted hover:text-foreground absolute top-2 right-2 z-10",
|
|
1495
|
-
onClick: clearSelection,
|
|
1496
|
-
children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/x", size: 20 })
|
|
1497
|
-
}
|
|
1498
|
-
),
|
|
1499
|
-
/* @__PURE__ */ jsx("div", { className: "mb-3 flex items-start justify-between gap-3", children: /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
1500
|
-
selectedCluster.label ? /* @__PURE__ */ jsx("p", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: selectedCluster.label }) : null,
|
|
1501
|
-
/* @__PURE__ */ jsx("div", { className: "text-base font-semibold leading-tight text-foreground", children: selectedCluster.title ?? "Clustered Locations" }),
|
|
1502
|
-
/* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: selectedCluster.summary ?? `${selectedCluster.markers.length} location${selectedCluster.markers.length === 1 ? "" : "s"} in this cluster.` })
|
|
1503
|
-
] }) }),
|
|
1504
|
-
/* @__PURE__ */ jsx("div", { className: "max-h-56 space-y-2 overflow-y-auto pr-1", children: selectedCluster.markers.map((marker, markerIndex) => /* @__PURE__ */ jsxs(
|
|
1505
|
-
"button",
|
|
1506
|
-
{
|
|
1507
|
-
type: "button",
|
|
1508
|
-
className: "w-full rounded-lg border border-border/60 p-3 text-left transition hover:border-border hover:bg-muted/50",
|
|
1509
|
-
onClick: () => selectMarker(marker),
|
|
1510
|
-
children: [
|
|
1511
|
-
/* @__PURE__ */ jsx("div", { className: "line-clamp-1 text-sm font-semibold text-foreground", children: getMarkerTitle(marker, markerIndex) }),
|
|
1512
|
-
marker.summary ? /* @__PURE__ */ jsx("div", { className: "mt-1 line-clamp-2 text-xs text-muted-foreground", children: marker.summary }) : null
|
|
1513
|
-
]
|
|
1514
|
-
},
|
|
1515
|
-
marker.id
|
|
1516
|
-
)) })
|
|
1517
|
-
]
|
|
1518
|
-
}
|
|
1519
|
-
);
|
|
1520
|
-
}
|
|
1521
|
-
return null;
|
|
1522
|
-
};
|
|
1523
|
-
return /* @__PURE__ */ jsxs(
|
|
1524
|
-
"div",
|
|
1525
|
-
{
|
|
1526
|
-
className: cn(
|
|
1527
|
-
"relative overflow-hidden rounded-2xl border border-border bg-background",
|
|
1528
|
-
className
|
|
1529
|
-
),
|
|
1530
|
-
children: [
|
|
1531
|
-
/* @__PURE__ */ jsx("div", { className: cn("h-[520px] w-full", mapWrapperClassName), children: /* @__PURE__ */ jsx(
|
|
1532
|
-
MapLibre,
|
|
1533
|
-
{
|
|
1534
|
-
stadiaApiKey,
|
|
1535
|
-
mapStyle,
|
|
1536
|
-
styleUrl,
|
|
1537
|
-
mapLibreCssHref,
|
|
1538
|
-
viewState: resolvedViewState,
|
|
1539
|
-
onViewStateChange: applyViewState,
|
|
1540
|
-
markers: mapMarkers,
|
|
1541
|
-
onClick: (coord) => {
|
|
1542
|
-
onMapClick?.(coord);
|
|
1543
|
-
if (clearSelectionOnMapClick) {
|
|
1544
|
-
clearSelection();
|
|
1545
|
-
}
|
|
1546
|
-
},
|
|
1547
|
-
onMarkerDrag,
|
|
1548
|
-
showNavigationControl,
|
|
1549
|
-
showGeolocateControl,
|
|
1550
|
-
navigationControlPosition,
|
|
1551
|
-
geolocateControlPosition,
|
|
1552
|
-
flyToOptions,
|
|
1553
|
-
className: cn("h-full w-full", mapClassName),
|
|
1554
|
-
children: mapChildren
|
|
1555
|
-
}
|
|
1556
|
-
) }),
|
|
1557
|
-
selection.type !== "none" ? /* @__PURE__ */ jsx(
|
|
1558
|
-
"div",
|
|
1559
|
-
{
|
|
1560
|
-
className: cn(
|
|
1561
|
-
"pointer-events-none absolute z-20",
|
|
1562
|
-
PANEL_POSITION_CLASS[panelPosition]
|
|
1563
|
-
),
|
|
1564
|
-
children: /* @__PURE__ */ jsx("div", { className: "pointer-events-auto", children: renderMarkerPanel() })
|
|
1565
|
-
}
|
|
1566
|
-
) : null
|
|
1567
|
-
]
|
|
1568
|
-
}
|
|
1569
|
-
);
|
|
1570
|
-
}
|
|
1571
|
-
var sizeStyles = {
|
|
1572
|
-
sm: "max-w-md",
|
|
1573
|
-
md: "max-w-2xl",
|
|
1574
|
-
lg: "max-w-4xl",
|
|
1575
|
-
xl: "max-w-5xl",
|
|
1576
|
-
full: "max-w-7xl",
|
|
1577
|
-
compact: "max-w-[700px]"
|
|
1578
|
-
};
|
|
1579
|
-
var dialogTransition = {
|
|
1580
|
-
duration: 0.35,
|
|
1581
|
-
ease: [0.16, 1, 0.3, 1]
|
|
1582
|
-
};
|
|
1583
|
-
function AnimatedDialog({
|
|
1584
|
-
open,
|
|
1585
|
-
onOpenChange,
|
|
1586
|
-
title,
|
|
1587
|
-
eyebrow,
|
|
1588
|
-
description,
|
|
1589
|
-
children,
|
|
1590
|
-
header,
|
|
1591
|
-
footer,
|
|
1592
|
-
size = "lg",
|
|
1593
|
-
className,
|
|
1594
|
-
contentClassName,
|
|
1595
|
-
featuredMediaHeader
|
|
1596
|
-
}) {
|
|
1597
|
-
const titleId = useId();
|
|
1598
|
-
const descriptionId = useId();
|
|
1599
|
-
const containerRef = useRef(null);
|
|
1600
|
-
useOnClickOutside(containerRef, () => {
|
|
1601
|
-
if (open) {
|
|
1602
|
-
onOpenChange(false);
|
|
1603
|
-
}
|
|
1604
|
-
});
|
|
1605
|
-
useEffect(() => {
|
|
1606
|
-
if (!open) {
|
|
1607
|
-
return;
|
|
1608
|
-
}
|
|
1609
|
-
const onKeyDown = (event) => {
|
|
1610
|
-
if (event.key === "Escape") {
|
|
1611
|
-
onOpenChange(false);
|
|
1612
|
-
}
|
|
1613
|
-
};
|
|
1614
|
-
const previousOverflow = document.body.style.overflow;
|
|
1615
|
-
document.body.style.overflow = "hidden";
|
|
1616
|
-
window.addEventListener("keydown", onKeyDown);
|
|
1617
|
-
return () => {
|
|
1618
|
-
document.body.style.overflow = previousOverflow;
|
|
1619
|
-
window.removeEventListener("keydown", onKeyDown);
|
|
1620
|
-
};
|
|
1621
|
-
}, [open, onOpenChange]);
|
|
1622
|
-
return /* @__PURE__ */ jsx(AnimatePresence, { children: open ? /* @__PURE__ */ jsxs("div", { className: "fixed inset-0 z-50 h-screen overflow-y-auto", children: [
|
|
1623
|
-
/* @__PURE__ */ jsx(
|
|
1624
|
-
motion.div,
|
|
1625
|
-
{
|
|
1626
|
-
initial: { opacity: 0 },
|
|
1627
|
-
animate: { opacity: 1, transition: dialogTransition },
|
|
1628
|
-
exit: { opacity: 0, transition: dialogTransition },
|
|
1629
|
-
className: "fixed inset-0 h-full w-full bg-foreground/80 backdrop-blur-lg"
|
|
532
|
+
};
|
|
533
|
+
const previousOverflow = document.body.style.overflow;
|
|
534
|
+
document.body.style.overflow = "hidden";
|
|
535
|
+
window.addEventListener("keydown", onKeyDown);
|
|
536
|
+
return () => {
|
|
537
|
+
document.body.style.overflow = previousOverflow;
|
|
538
|
+
window.removeEventListener("keydown", onKeyDown);
|
|
539
|
+
};
|
|
540
|
+
}, [open, onOpenChange]);
|
|
541
|
+
return /* @__PURE__ */ jsx(AnimatePresence, { children: open ? /* @__PURE__ */ jsxs("div", { className: "fixed inset-0 z-50 h-screen overflow-y-auto", children: [
|
|
542
|
+
/* @__PURE__ */ jsx(
|
|
543
|
+
motion.div,
|
|
544
|
+
{
|
|
545
|
+
initial: { opacity: 0 },
|
|
546
|
+
animate: { opacity: 1, transition: dialogTransition },
|
|
547
|
+
exit: { opacity: 0, transition: dialogTransition },
|
|
548
|
+
className: "fixed inset-0 h-full w-full bg-foreground/80 backdrop-blur-lg"
|
|
1630
549
|
}
|
|
1631
550
|
),
|
|
1632
551
|
/* @__PURE__ */ jsxs(
|
|
@@ -1925,10 +844,10 @@ var ImageSlider = ({
|
|
|
1925
844
|
optixFlowConfig
|
|
1926
845
|
}) => {
|
|
1927
846
|
const hasImages = images.length > 0;
|
|
1928
|
-
const [currentIndex, setCurrentIndex] =
|
|
847
|
+
const [currentIndex, setCurrentIndex] = React4.useState(
|
|
1929
848
|
() => normalizeIndex(startIndex, images.length)
|
|
1930
849
|
);
|
|
1931
|
-
const handleNext =
|
|
850
|
+
const handleNext = React4.useCallback(() => {
|
|
1932
851
|
if (!hasImages) return;
|
|
1933
852
|
setCurrentIndex((prevIndex) => {
|
|
1934
853
|
const nextIndex = prevIndex + 1 >= images.length ? 0 : prevIndex + 1;
|
|
@@ -1936,7 +855,7 @@ var ImageSlider = ({
|
|
|
1936
855
|
return nextIndex;
|
|
1937
856
|
});
|
|
1938
857
|
}, [hasImages, images.length, onSlideChange]);
|
|
1939
|
-
const handlePrevious =
|
|
858
|
+
const handlePrevious = React4.useCallback(() => {
|
|
1940
859
|
if (!hasImages) return;
|
|
1941
860
|
setCurrentIndex((prevIndex) => {
|
|
1942
861
|
const nextIndex = prevIndex - 1 < 0 ? images.length - 1 : prevIndex - 1;
|
|
@@ -1944,11 +863,11 @@ var ImageSlider = ({
|
|
|
1944
863
|
return nextIndex;
|
|
1945
864
|
});
|
|
1946
865
|
}, [hasImages, images.length, onSlideChange]);
|
|
1947
|
-
|
|
866
|
+
React4.useEffect(() => {
|
|
1948
867
|
if (!hasImages) return;
|
|
1949
868
|
setCurrentIndex(normalizeIndex(startIndex, images.length));
|
|
1950
869
|
}, [startIndex, images.length, hasImages]);
|
|
1951
|
-
|
|
870
|
+
React4.useEffect(() => {
|
|
1952
871
|
if (!enableKeyboard || !hasImages) return;
|
|
1953
872
|
const handleKeyDown = (event) => {
|
|
1954
873
|
if (event.key === "ArrowRight") {
|
|
@@ -1962,7 +881,7 @@ var ImageSlider = ({
|
|
|
1962
881
|
window.removeEventListener("keydown", handleKeyDown);
|
|
1963
882
|
};
|
|
1964
883
|
}, [enableKeyboard, handleNext, handlePrevious, hasImages]);
|
|
1965
|
-
|
|
884
|
+
React4.useEffect(() => {
|
|
1966
885
|
if (!autoplay || images.length < 2) return;
|
|
1967
886
|
const interval = window.setInterval(handleNext, autoplayIntervalMs);
|
|
1968
887
|
return () => window.clearInterval(interval);
|
|
@@ -2033,8 +952,150 @@ var ImageSlider = ({
|
|
|
2033
952
|
) : null
|
|
2034
953
|
]
|
|
2035
954
|
}
|
|
2036
|
-
);
|
|
2037
|
-
};
|
|
955
|
+
);
|
|
956
|
+
};
|
|
957
|
+
var baseStyles = [
|
|
958
|
+
// Layout
|
|
959
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap shrink-0",
|
|
960
|
+
// Typography - using CSS variables with sensible defaults
|
|
961
|
+
"font-[var(--button-font-family,inherit)]",
|
|
962
|
+
"font-[var(--button-font-weight,500)]",
|
|
963
|
+
"tracking-[var(--button-letter-spacing,0)]",
|
|
964
|
+
"leading-[var(--button-line-height,1.25)]",
|
|
965
|
+
"[text-transform:var(--button-text-transform,none)]",
|
|
966
|
+
"text-sm",
|
|
967
|
+
// Border radius
|
|
968
|
+
"rounded-[var(--button-radius,var(--radius,0.375rem))]",
|
|
969
|
+
// Smooth transition - using [transition:...] to set full shorthand property (not just transition-property)
|
|
970
|
+
"[transition:var(--button-transition,all_250ms_cubic-bezier(0.4,0,0.2,1))]",
|
|
971
|
+
// Box shadow (master level) - using [box-shadow:...] for complex multi-value shadows
|
|
972
|
+
"[box-shadow:var(--button-shadow,none)]",
|
|
973
|
+
"hover:[box-shadow:var(--button-shadow-hover,var(--button-shadow,none))]",
|
|
974
|
+
// Disabled state
|
|
975
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
|
976
|
+
// SVG handling
|
|
977
|
+
"[&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0",
|
|
978
|
+
// Focus styles
|
|
979
|
+
"outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
|
980
|
+
// Invalid state
|
|
981
|
+
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive"
|
|
982
|
+
].join(" ");
|
|
983
|
+
var buttonVariants = cva(baseStyles, {
|
|
984
|
+
variants: {
|
|
985
|
+
variant: {
|
|
986
|
+
// Default (Primary) variant - full customization
|
|
987
|
+
default: [
|
|
988
|
+
"bg-[var(--button-default-bg,hsl(var(--primary)))]",
|
|
989
|
+
"text-[var(--button-default-fg,hsl(var(--primary-foreground)))]",
|
|
990
|
+
"border-[length:var(--button-default-border-width,0px)]",
|
|
991
|
+
"border-[color:var(--button-default-border,transparent)]",
|
|
992
|
+
"[box-shadow:var(--button-default-shadow,var(--button-shadow,none))]",
|
|
993
|
+
"hover:bg-[var(--button-default-hover-bg,hsl(var(--primary)/0.9))]",
|
|
994
|
+
"hover:text-[var(--button-default-hover-fg,var(--button-default-fg,hsl(var(--primary-foreground))))]",
|
|
995
|
+
"hover:border-[color:var(--button-default-hover-border,var(--button-default-border,transparent))]",
|
|
996
|
+
"hover:[box-shadow:var(--button-default-shadow-hover,var(--button-shadow-hover,var(--button-default-shadow,var(--button-shadow,none))))]"
|
|
997
|
+
].join(" "),
|
|
998
|
+
// Destructive variant - full customization
|
|
999
|
+
destructive: [
|
|
1000
|
+
"bg-[var(--button-destructive-bg,hsl(var(--destructive)))]",
|
|
1001
|
+
"text-[var(--button-destructive-fg,white)]",
|
|
1002
|
+
"border-[length:var(--button-destructive-border-width,0px)]",
|
|
1003
|
+
"border-[color:var(--button-destructive-border,transparent)]",
|
|
1004
|
+
"[box-shadow:var(--button-destructive-shadow,var(--button-shadow,none))]",
|
|
1005
|
+
"hover:bg-[var(--button-destructive-hover-bg,hsl(var(--destructive)/0.9))]",
|
|
1006
|
+
"hover:text-[var(--button-destructive-hover-fg,var(--button-destructive-fg,white))]",
|
|
1007
|
+
"hover:border-[color:var(--button-destructive-hover-border,var(--button-destructive-border,transparent))]",
|
|
1008
|
+
"hover:[box-shadow:var(--button-destructive-shadow-hover,var(--button-shadow-hover,var(--button-destructive-shadow,var(--button-shadow,none))))]",
|
|
1009
|
+
"focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40",
|
|
1010
|
+
"dark:bg-destructive/60"
|
|
1011
|
+
].join(" "),
|
|
1012
|
+
// Outline variant - full customization with proper border handling
|
|
1013
|
+
outline: [
|
|
1014
|
+
"bg-[var(--button-outline-bg,hsl(var(--background)))]",
|
|
1015
|
+
"text-[var(--button-outline-fg,inherit)]",
|
|
1016
|
+
"border-[length:var(--button-outline-border-width,1px)]",
|
|
1017
|
+
"border-[color:var(--button-outline-border,hsl(var(--border)))]",
|
|
1018
|
+
"[box-shadow:var(--button-outline-shadow,var(--button-shadow,0_1px_2px_0_rgb(0_0_0/0.05)))]",
|
|
1019
|
+
"hover:bg-[var(--button-outline-hover-bg,hsl(var(--accent)))]",
|
|
1020
|
+
"hover:text-[var(--button-outline-hover-fg,hsl(var(--accent-foreground)))]",
|
|
1021
|
+
"hover:border-[color:var(--button-outline-hover-border,var(--button-outline-border,hsl(var(--border))))]",
|
|
1022
|
+
"hover:[box-shadow:var(--button-outline-shadow-hover,var(--button-shadow-hover,var(--button-outline-shadow,var(--button-shadow,none))))]",
|
|
1023
|
+
"dark:bg-input/30 dark:border-input dark:hover:bg-input/50"
|
|
1024
|
+
].join(" "),
|
|
1025
|
+
// Secondary variant - full customization
|
|
1026
|
+
secondary: [
|
|
1027
|
+
"bg-[var(--button-secondary-bg,hsl(var(--secondary)))]",
|
|
1028
|
+
"text-[var(--button-secondary-fg,hsl(var(--secondary-foreground)))]",
|
|
1029
|
+
"border-[length:var(--button-secondary-border-width,0px)]",
|
|
1030
|
+
"border-[color:var(--button-secondary-border,transparent)]",
|
|
1031
|
+
"[box-shadow:var(--button-secondary-shadow,var(--button-shadow,none))]",
|
|
1032
|
+
"hover:bg-[var(--button-secondary-hover-bg,hsl(var(--secondary)/0.8))]",
|
|
1033
|
+
"hover:text-[var(--button-secondary-hover-fg,var(--button-secondary-fg,hsl(var(--secondary-foreground))))]",
|
|
1034
|
+
"hover:border-[color:var(--button-secondary-hover-border,var(--button-secondary-border,transparent))]",
|
|
1035
|
+
"hover:[box-shadow:var(--button-secondary-shadow-hover,var(--button-shadow-hover,var(--button-secondary-shadow,var(--button-shadow,none))))]"
|
|
1036
|
+
].join(" "),
|
|
1037
|
+
// Ghost variant - full customization
|
|
1038
|
+
ghost: [
|
|
1039
|
+
"bg-[var(--button-ghost-bg,transparent)]",
|
|
1040
|
+
"text-[var(--button-ghost-fg,inherit)]",
|
|
1041
|
+
"border-[length:var(--button-ghost-border-width,0px)]",
|
|
1042
|
+
"border-[color:var(--button-ghost-border,transparent)]",
|
|
1043
|
+
"[box-shadow:var(--button-ghost-shadow,var(--button-shadow,none))]",
|
|
1044
|
+
"hover:bg-[var(--button-ghost-hover-bg,hsl(var(--accent)))]",
|
|
1045
|
+
"hover:text-[var(--button-ghost-hover-fg,hsl(var(--accent-foreground)))]",
|
|
1046
|
+
"hover:border-[color:var(--button-ghost-hover-border,var(--button-ghost-border,transparent))]",
|
|
1047
|
+
"hover:[box-shadow:var(--button-ghost-shadow-hover,var(--button-shadow-hover,var(--button-ghost-shadow,var(--button-shadow,none))))]",
|
|
1048
|
+
"dark:hover:bg-accent/50"
|
|
1049
|
+
].join(" "),
|
|
1050
|
+
// Link variant - full customization
|
|
1051
|
+
link: [
|
|
1052
|
+
"bg-[var(--button-link-bg,transparent)]",
|
|
1053
|
+
"text-[var(--button-link-fg,hsl(var(--primary)))]",
|
|
1054
|
+
"border-[length:var(--button-link-border-width,0px)]",
|
|
1055
|
+
"border-[color:var(--button-link-border,transparent)]",
|
|
1056
|
+
"[box-shadow:var(--button-link-shadow,none)]",
|
|
1057
|
+
"hover:bg-[var(--button-link-hover-bg,transparent)]",
|
|
1058
|
+
"hover:text-[var(--button-link-hover-fg,var(--button-link-fg,hsl(var(--primary))))]",
|
|
1059
|
+
"hover:[box-shadow:var(--button-link-shadow-hover,none)]",
|
|
1060
|
+
"underline-offset-4 hover:underline"
|
|
1061
|
+
].join(" ")
|
|
1062
|
+
},
|
|
1063
|
+
size: {
|
|
1064
|
+
default: [
|
|
1065
|
+
"h-[var(--button-height-md,2.25rem)]",
|
|
1066
|
+
"px-[var(--button-padding-x-md,1rem)]",
|
|
1067
|
+
"py-[var(--button-padding-y-md,0.5rem)]",
|
|
1068
|
+
"has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
|
|
1069
|
+
].join(" "),
|
|
1070
|
+
sm: [
|
|
1071
|
+
"h-[var(--button-height-sm,2rem)]",
|
|
1072
|
+
"px-[var(--button-padding-x-sm,0.75rem)]",
|
|
1073
|
+
"py-[var(--button-padding-y-sm,0.25rem)]",
|
|
1074
|
+
"gap-1.5",
|
|
1075
|
+
"has-[>svg]:px-[calc(var(--button-padding-x-sm,0.75rem)*0.83)]"
|
|
1076
|
+
].join(" "),
|
|
1077
|
+
md: [
|
|
1078
|
+
"h-[var(--button-height-md,2.25rem)]",
|
|
1079
|
+
"px-[var(--button-padding-x-md,1rem)]",
|
|
1080
|
+
"py-[var(--button-padding-y-md,0.5rem)]",
|
|
1081
|
+
"has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
|
|
1082
|
+
].join(" "),
|
|
1083
|
+
lg: [
|
|
1084
|
+
"h-[var(--button-height-lg,2.5rem)]",
|
|
1085
|
+
"px-[var(--button-padding-x-lg,1.5rem)]",
|
|
1086
|
+
"py-[var(--button-padding-y-lg,0.5rem)]",
|
|
1087
|
+
"has-[>svg]:px-[calc(var(--button-padding-x-lg,1.5rem)*0.67)]"
|
|
1088
|
+
].join(" "),
|
|
1089
|
+
icon: "size-[var(--button-height-md,2.25rem)]",
|
|
1090
|
+
"icon-sm": "size-[var(--button-height-sm,2rem)]",
|
|
1091
|
+
"icon-lg": "size-[var(--button-height-lg,2.5rem)]"
|
|
1092
|
+
}
|
|
1093
|
+
},
|
|
1094
|
+
defaultVariants: {
|
|
1095
|
+
variant: "default",
|
|
1096
|
+
size: "default"
|
|
1097
|
+
}
|
|
1098
|
+
});
|
|
2038
1099
|
function Button({
|
|
2039
1100
|
className,
|
|
2040
1101
|
variant = "default",
|
|
@@ -2078,127 +1139,412 @@ function CardHeader({ className, ...props }) {
|
|
|
2078
1139
|
),
|
|
2079
1140
|
...props
|
|
2080
1141
|
}
|
|
2081
|
-
);
|
|
2082
|
-
}
|
|
2083
|
-
function CardTitle({ className, ...props }) {
|
|
2084
|
-
return /* @__PURE__ */ jsx(
|
|
2085
|
-
"div",
|
|
2086
|
-
{
|
|
2087
|
-
"data-slot": "card-title",
|
|
2088
|
-
className: cn("leading-none font-semibold", className),
|
|
2089
|
-
...props
|
|
1142
|
+
);
|
|
1143
|
+
}
|
|
1144
|
+
function CardTitle({ className, ...props }) {
|
|
1145
|
+
return /* @__PURE__ */ jsx(
|
|
1146
|
+
"div",
|
|
1147
|
+
{
|
|
1148
|
+
"data-slot": "card-title",
|
|
1149
|
+
className: cn("leading-none font-semibold", className),
|
|
1150
|
+
...props
|
|
1151
|
+
}
|
|
1152
|
+
);
|
|
1153
|
+
}
|
|
1154
|
+
function CardDescription({ className, ...props }) {
|
|
1155
|
+
return /* @__PURE__ */ jsx(
|
|
1156
|
+
"div",
|
|
1157
|
+
{
|
|
1158
|
+
"data-slot": "card-description",
|
|
1159
|
+
className: cn("text-muted-foreground text-sm", className),
|
|
1160
|
+
...props
|
|
1161
|
+
}
|
|
1162
|
+
);
|
|
1163
|
+
}
|
|
1164
|
+
function CardContent({ className, ...props }) {
|
|
1165
|
+
return /* @__PURE__ */ jsx(
|
|
1166
|
+
"div",
|
|
1167
|
+
{
|
|
1168
|
+
"data-slot": "card-content",
|
|
1169
|
+
className: cn("px-6", className),
|
|
1170
|
+
...props
|
|
1171
|
+
}
|
|
1172
|
+
);
|
|
1173
|
+
}
|
|
1174
|
+
function CardFooter({ className, ...props }) {
|
|
1175
|
+
return /* @__PURE__ */ jsx(
|
|
1176
|
+
"div",
|
|
1177
|
+
{
|
|
1178
|
+
"data-slot": "card-footer",
|
|
1179
|
+
className: cn("flex items-center px-6 [.border-t]:pt-6", className),
|
|
1180
|
+
...props
|
|
1181
|
+
}
|
|
1182
|
+
);
|
|
1183
|
+
}
|
|
1184
|
+
var badgeVariants = cva(
|
|
1185
|
+
"inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
|
|
1186
|
+
{
|
|
1187
|
+
variants: {
|
|
1188
|
+
variant: {
|
|
1189
|
+
default: "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
|
|
1190
|
+
secondary: "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
|
|
1191
|
+
destructive: "border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
|
1192
|
+
outline: "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground"
|
|
1193
|
+
}
|
|
1194
|
+
},
|
|
1195
|
+
defaultVariants: {
|
|
1196
|
+
variant: "default"
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
);
|
|
1200
|
+
function Badge({
|
|
1201
|
+
className,
|
|
1202
|
+
variant,
|
|
1203
|
+
asChild = false,
|
|
1204
|
+
...props
|
|
1205
|
+
}) {
|
|
1206
|
+
const Comp = asChild ? Slot : "span";
|
|
1207
|
+
return /* @__PURE__ */ jsx(
|
|
1208
|
+
Comp,
|
|
1209
|
+
{
|
|
1210
|
+
"data-slot": "badge",
|
|
1211
|
+
className: cn(badgeVariants({ variant }), className),
|
|
1212
|
+
...props
|
|
1213
|
+
}
|
|
1214
|
+
);
|
|
1215
|
+
}
|
|
1216
|
+
function Popover({
|
|
1217
|
+
...props
|
|
1218
|
+
}) {
|
|
1219
|
+
return /* @__PURE__ */ jsx(PopoverPrimitive.Root, { "data-slot": "popover", ...props });
|
|
1220
|
+
}
|
|
1221
|
+
function PopoverTrigger({
|
|
1222
|
+
...props
|
|
1223
|
+
}) {
|
|
1224
|
+
return /* @__PURE__ */ jsx(PopoverPrimitive.Trigger, { "data-slot": "popover-trigger", ...props });
|
|
1225
|
+
}
|
|
1226
|
+
function PopoverContent({
|
|
1227
|
+
className,
|
|
1228
|
+
align = "center",
|
|
1229
|
+
sideOffset = 4,
|
|
1230
|
+
...props
|
|
1231
|
+
}) {
|
|
1232
|
+
return /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
|
|
1233
|
+
PopoverPrimitive.Content,
|
|
1234
|
+
{
|
|
1235
|
+
"data-slot": "popover-content",
|
|
1236
|
+
align,
|
|
1237
|
+
sideOffset,
|
|
1238
|
+
className: cn(
|
|
1239
|
+
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden",
|
|
1240
|
+
className
|
|
1241
|
+
),
|
|
1242
|
+
...props
|
|
1243
|
+
}
|
|
1244
|
+
) });
|
|
1245
|
+
}
|
|
1246
|
+
var DEFAULT_ICON_API_KEY = "au382bi7fsh96w9h9xlrnat2jglx";
|
|
1247
|
+
var DynamicIcon = React4.memo(function DynamicIcon2({
|
|
1248
|
+
apiKey,
|
|
1249
|
+
...props
|
|
1250
|
+
}) {
|
|
1251
|
+
return /* @__PURE__ */ jsx(Icon, { ...props, apiKey: apiKey ?? DEFAULT_ICON_API_KEY });
|
|
1252
|
+
});
|
|
1253
|
+
DynamicIcon.displayName = "DynamicIcon";
|
|
1254
|
+
function StarRating({
|
|
1255
|
+
rating,
|
|
1256
|
+
size = 18,
|
|
1257
|
+
className
|
|
1258
|
+
}) {
|
|
1259
|
+
return /* @__PURE__ */ jsx("div", { className: cn("flex items-center gap-0.5", className), children: [1, 2, 3, 4, 5].map((star) => /* @__PURE__ */ jsx(
|
|
1260
|
+
DynamicIcon,
|
|
1261
|
+
{
|
|
1262
|
+
name: "icon-park-solid/star",
|
|
1263
|
+
size,
|
|
1264
|
+
className: cn(
|
|
1265
|
+
star <= rating ? "fill-primary text-primary" : "fill-muted text-muted"
|
|
1266
|
+
)
|
|
1267
|
+
},
|
|
1268
|
+
star
|
|
1269
|
+
)) });
|
|
1270
|
+
}
|
|
1271
|
+
function normalizePhoneNumber(input) {
|
|
1272
|
+
const trimmed = input.trim();
|
|
1273
|
+
if (trimmed.toLowerCase().startsWith("tel:")) {
|
|
1274
|
+
return trimmed;
|
|
1275
|
+
}
|
|
1276
|
+
const match = trimmed.match(/^[\s\+\-\(\)]*(\d[\d\s\-\(\)\.]*\d)[\s\-]*(x|ext\.?|extension)?[\s\-]*(\d+)?$/i);
|
|
1277
|
+
if (match) {
|
|
1278
|
+
const mainNumber = match[1].replace(/[\s\-\(\)\.]/g, "");
|
|
1279
|
+
const extension = match[3];
|
|
1280
|
+
const normalized = mainNumber.length >= 10 && !trimmed.startsWith("+") ? `+${mainNumber}` : mainNumber;
|
|
1281
|
+
const withExtension = extension ? `${normalized};ext=${extension}` : normalized;
|
|
1282
|
+
return `tel:${withExtension}`;
|
|
1283
|
+
}
|
|
1284
|
+
const cleaned = trimmed.replace(/[\s\-\(\)\.]/g, "");
|
|
1285
|
+
return `tel:${cleaned}`;
|
|
1286
|
+
}
|
|
1287
|
+
function normalizeEmail(input) {
|
|
1288
|
+
const trimmed = input.trim();
|
|
1289
|
+
if (trimmed.toLowerCase().startsWith("mailto:")) {
|
|
1290
|
+
return trimmed;
|
|
1291
|
+
}
|
|
1292
|
+
return `mailto:${trimmed}`;
|
|
1293
|
+
}
|
|
1294
|
+
function isEmail(input) {
|
|
1295
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
1296
|
+
return emailRegex.test(input.trim());
|
|
1297
|
+
}
|
|
1298
|
+
function isPhoneNumber(input) {
|
|
1299
|
+
const trimmed = input.trim();
|
|
1300
|
+
if (trimmed.toLowerCase().startsWith("tel:")) {
|
|
1301
|
+
return true;
|
|
1302
|
+
}
|
|
1303
|
+
const phoneRegex = /^[\s\+\-\(\)]*\d[\d\s\-\(\)\.]*\d[\s\-]*(x|ext\.?|extension)?[\s\-]*\d*$/i;
|
|
1304
|
+
return phoneRegex.test(trimmed);
|
|
1305
|
+
}
|
|
1306
|
+
function isInternalUrl(href) {
|
|
1307
|
+
if (typeof window === "undefined") {
|
|
1308
|
+
return href.startsWith("/") && !href.startsWith("//");
|
|
1309
|
+
}
|
|
1310
|
+
const trimmed = href.trim();
|
|
1311
|
+
if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
|
|
1312
|
+
return true;
|
|
1313
|
+
}
|
|
1314
|
+
try {
|
|
1315
|
+
const url = new URL(trimmed, window.location.href);
|
|
1316
|
+
const currentOrigin = window.location.origin;
|
|
1317
|
+
const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
|
|
1318
|
+
return normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin);
|
|
1319
|
+
} catch {
|
|
1320
|
+
return false;
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
function toRelativePath(href) {
|
|
1324
|
+
if (typeof window === "undefined") {
|
|
1325
|
+
return href;
|
|
1326
|
+
}
|
|
1327
|
+
const trimmed = href.trim();
|
|
1328
|
+
if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
|
|
1329
|
+
return trimmed;
|
|
1330
|
+
}
|
|
1331
|
+
try {
|
|
1332
|
+
const url = new URL(trimmed, window.location.href);
|
|
1333
|
+
const currentOrigin = window.location.origin;
|
|
1334
|
+
const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
|
|
1335
|
+
if (normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin)) {
|
|
1336
|
+
return url.pathname + url.search + url.hash;
|
|
1337
|
+
}
|
|
1338
|
+
} catch {
|
|
1339
|
+
}
|
|
1340
|
+
return trimmed;
|
|
1341
|
+
}
|
|
1342
|
+
function useNavigation({
|
|
1343
|
+
href,
|
|
1344
|
+
onClick
|
|
1345
|
+
} = {}) {
|
|
1346
|
+
const linkType = React4.useMemo(() => {
|
|
1347
|
+
if (!href || href.trim() === "") {
|
|
1348
|
+
return onClick ? "none" : "none";
|
|
1349
|
+
}
|
|
1350
|
+
const trimmed = href.trim();
|
|
1351
|
+
if (trimmed.toLowerCase().startsWith("mailto:") || isEmail(trimmed)) {
|
|
1352
|
+
return "mailto";
|
|
1353
|
+
}
|
|
1354
|
+
if (trimmed.toLowerCase().startsWith("tel:") || isPhoneNumber(trimmed)) {
|
|
1355
|
+
return "tel";
|
|
1356
|
+
}
|
|
1357
|
+
if (isInternalUrl(trimmed)) {
|
|
1358
|
+
return "internal";
|
|
1359
|
+
}
|
|
1360
|
+
try {
|
|
1361
|
+
new URL(trimmed, typeof window !== "undefined" ? window.location.href : "http://localhost");
|
|
1362
|
+
return "external";
|
|
1363
|
+
} catch {
|
|
1364
|
+
return "internal";
|
|
1365
|
+
}
|
|
1366
|
+
}, [href, onClick]);
|
|
1367
|
+
const normalizedHref = React4.useMemo(() => {
|
|
1368
|
+
if (!href || href.trim() === "") {
|
|
1369
|
+
return void 0;
|
|
1370
|
+
}
|
|
1371
|
+
const trimmed = href.trim();
|
|
1372
|
+
switch (linkType) {
|
|
1373
|
+
case "tel":
|
|
1374
|
+
return normalizePhoneNumber(trimmed);
|
|
1375
|
+
case "mailto":
|
|
1376
|
+
return normalizeEmail(trimmed);
|
|
1377
|
+
case "internal":
|
|
1378
|
+
return toRelativePath(trimmed);
|
|
1379
|
+
case "external":
|
|
1380
|
+
return trimmed;
|
|
1381
|
+
default:
|
|
1382
|
+
return trimmed;
|
|
1383
|
+
}
|
|
1384
|
+
}, [href, linkType]);
|
|
1385
|
+
const target = React4.useMemo(() => {
|
|
1386
|
+
switch (linkType) {
|
|
1387
|
+
case "external":
|
|
1388
|
+
return "_blank";
|
|
1389
|
+
case "internal":
|
|
1390
|
+
return "_self";
|
|
1391
|
+
case "mailto":
|
|
1392
|
+
case "tel":
|
|
1393
|
+
return void 0;
|
|
1394
|
+
default:
|
|
1395
|
+
return void 0;
|
|
1396
|
+
}
|
|
1397
|
+
}, [linkType]);
|
|
1398
|
+
const rel = React4.useMemo(() => {
|
|
1399
|
+
if (linkType === "external") {
|
|
1400
|
+
return "noopener noreferrer";
|
|
2090
1401
|
}
|
|
1402
|
+
return void 0;
|
|
1403
|
+
}, [linkType]);
|
|
1404
|
+
const isExternal = linkType === "external";
|
|
1405
|
+
const isInternal = linkType === "internal";
|
|
1406
|
+
const shouldUseRouter = isInternal && typeof normalizedHref === "string" && normalizedHref.startsWith("/");
|
|
1407
|
+
const handleClick = React4.useCallback(
|
|
1408
|
+
(event) => {
|
|
1409
|
+
if (onClick) {
|
|
1410
|
+
try {
|
|
1411
|
+
onClick(event);
|
|
1412
|
+
} catch (error) {
|
|
1413
|
+
console.error("Error in user onClick handler:", error);
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
if (event.defaultPrevented) {
|
|
1417
|
+
return;
|
|
1418
|
+
}
|
|
1419
|
+
if (shouldUseRouter && normalizedHref && event.button === 0 && // left-click only
|
|
1420
|
+
!event.metaKey && !event.altKey && !event.ctrlKey && !event.shiftKey) {
|
|
1421
|
+
if (typeof window !== "undefined") {
|
|
1422
|
+
const handler = window.__opensiteNavigationHandler;
|
|
1423
|
+
if (typeof handler === "function") {
|
|
1424
|
+
try {
|
|
1425
|
+
const handled = handler(normalizedHref, event.nativeEvent || event);
|
|
1426
|
+
if (handled !== false) {
|
|
1427
|
+
event.preventDefault();
|
|
1428
|
+
}
|
|
1429
|
+
} catch (error) {
|
|
1430
|
+
console.error("Error in navigation handler:", error);
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1435
|
+
},
|
|
1436
|
+
[onClick, shouldUseRouter, normalizedHref]
|
|
2091
1437
|
);
|
|
1438
|
+
return {
|
|
1439
|
+
linkType,
|
|
1440
|
+
normalizedHref,
|
|
1441
|
+
target,
|
|
1442
|
+
rel,
|
|
1443
|
+
isExternal,
|
|
1444
|
+
isInternal,
|
|
1445
|
+
shouldUseRouter,
|
|
1446
|
+
handleClick
|
|
1447
|
+
};
|
|
2092
1448
|
}
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
1449
|
+
var Pressable = React4.forwardRef(
|
|
1450
|
+
({
|
|
1451
|
+
children,
|
|
1452
|
+
className,
|
|
1453
|
+
href,
|
|
1454
|
+
onClick,
|
|
1455
|
+
variant,
|
|
1456
|
+
size,
|
|
1457
|
+
asButton = false,
|
|
1458
|
+
fallbackComponentType = "span",
|
|
1459
|
+
componentType,
|
|
1460
|
+
"aria-label": ariaLabel,
|
|
1461
|
+
"aria-describedby": ariaDescribedby,
|
|
1462
|
+
id,
|
|
1463
|
+
...props
|
|
1464
|
+
}, ref) => {
|
|
1465
|
+
const navigation = useNavigation({ href, onClick });
|
|
1466
|
+
const {
|
|
1467
|
+
normalizedHref,
|
|
1468
|
+
target,
|
|
1469
|
+
rel,
|
|
1470
|
+
linkType,
|
|
1471
|
+
isInternal,
|
|
1472
|
+
isExternal,
|
|
1473
|
+
handleClick
|
|
1474
|
+
} = navigation;
|
|
1475
|
+
const shouldRenderLink = normalizedHref && linkType !== "none";
|
|
1476
|
+
const shouldRenderButton = !shouldRenderLink && onClick;
|
|
1477
|
+
const effectiveComponentType = componentType || (shouldRenderLink ? "a" : shouldRenderButton ? "button" : fallbackComponentType);
|
|
1478
|
+
const finalComponentType = isInternal && shouldRenderLink ? "a" : effectiveComponentType;
|
|
1479
|
+
const shouldApplyButtonStyles = asButton || variant || size;
|
|
1480
|
+
const combinedClassName = cn(
|
|
1481
|
+
shouldApplyButtonStyles && buttonVariants({ variant, size }),
|
|
1482
|
+
className
|
|
1483
|
+
);
|
|
1484
|
+
const dataProps = Object.fromEntries(
|
|
1485
|
+
Object.entries(props).filter(([key]) => key.startsWith("data-"))
|
|
1486
|
+
);
|
|
1487
|
+
const buttonDataAttributes = shouldApplyButtonStyles ? {
|
|
1488
|
+
"data-slot": "button",
|
|
1489
|
+
"data-variant": variant ?? "default",
|
|
1490
|
+
"data-size": size ?? "default"
|
|
1491
|
+
} : {};
|
|
1492
|
+
const commonProps = {
|
|
1493
|
+
className: combinedClassName,
|
|
1494
|
+
onClick: handleClick,
|
|
1495
|
+
"aria-label": ariaLabel,
|
|
1496
|
+
"aria-describedby": ariaDescribedby,
|
|
1497
|
+
id,
|
|
1498
|
+
...dataProps,
|
|
1499
|
+
...buttonDataAttributes
|
|
1500
|
+
};
|
|
1501
|
+
if (finalComponentType === "a" && shouldRenderLink) {
|
|
1502
|
+
return /* @__PURE__ */ jsx(
|
|
1503
|
+
"a",
|
|
1504
|
+
{
|
|
1505
|
+
ref,
|
|
1506
|
+
href: normalizedHref,
|
|
1507
|
+
target,
|
|
1508
|
+
rel,
|
|
1509
|
+
...commonProps,
|
|
1510
|
+
...props,
|
|
1511
|
+
children
|
|
1512
|
+
}
|
|
1513
|
+
);
|
|
2100
1514
|
}
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
1515
|
+
if (finalComponentType === "button") {
|
|
1516
|
+
return /* @__PURE__ */ jsx(
|
|
1517
|
+
"button",
|
|
1518
|
+
{
|
|
1519
|
+
ref,
|
|
1520
|
+
type: props.type || "button",
|
|
1521
|
+
...commonProps,
|
|
1522
|
+
...props,
|
|
1523
|
+
children
|
|
1524
|
+
}
|
|
1525
|
+
);
|
|
2110
1526
|
}
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
1527
|
+
if (finalComponentType === "div") {
|
|
1528
|
+
return /* @__PURE__ */ jsx(
|
|
1529
|
+
"div",
|
|
1530
|
+
{
|
|
1531
|
+
ref,
|
|
1532
|
+
...commonProps,
|
|
1533
|
+
children
|
|
1534
|
+
}
|
|
1535
|
+
);
|
|
2120
1536
|
}
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
variant: {
|
|
2128
|
-
default: "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
|
|
2129
|
-
secondary: "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
|
|
2130
|
-
destructive: "border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
|
2131
|
-
outline: "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground"
|
|
1537
|
+
return /* @__PURE__ */ jsx(
|
|
1538
|
+
"span",
|
|
1539
|
+
{
|
|
1540
|
+
ref,
|
|
1541
|
+
...commonProps,
|
|
1542
|
+
children
|
|
2132
1543
|
}
|
|
2133
|
-
|
|
2134
|
-
defaultVariants: {
|
|
2135
|
-
variant: "default"
|
|
2136
|
-
}
|
|
1544
|
+
);
|
|
2137
1545
|
}
|
|
2138
1546
|
);
|
|
2139
|
-
|
|
2140
|
-
className,
|
|
2141
|
-
variant,
|
|
2142
|
-
asChild = false,
|
|
2143
|
-
...props
|
|
2144
|
-
}) {
|
|
2145
|
-
const Comp = asChild ? Slot : "span";
|
|
2146
|
-
return /* @__PURE__ */ jsx(
|
|
2147
|
-
Comp,
|
|
2148
|
-
{
|
|
2149
|
-
"data-slot": "badge",
|
|
2150
|
-
className: cn(badgeVariants({ variant }), className),
|
|
2151
|
-
...props
|
|
2152
|
-
}
|
|
2153
|
-
);
|
|
2154
|
-
}
|
|
2155
|
-
function Popover({
|
|
2156
|
-
...props
|
|
2157
|
-
}) {
|
|
2158
|
-
return /* @__PURE__ */ jsx(PopoverPrimitive.Root, { "data-slot": "popover", ...props });
|
|
2159
|
-
}
|
|
2160
|
-
function PopoverTrigger({
|
|
2161
|
-
...props
|
|
2162
|
-
}) {
|
|
2163
|
-
return /* @__PURE__ */ jsx(PopoverPrimitive.Trigger, { "data-slot": "popover-trigger", ...props });
|
|
2164
|
-
}
|
|
2165
|
-
function PopoverContent({
|
|
2166
|
-
className,
|
|
2167
|
-
align = "center",
|
|
2168
|
-
sideOffset = 4,
|
|
2169
|
-
...props
|
|
2170
|
-
}) {
|
|
2171
|
-
return /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
|
|
2172
|
-
PopoverPrimitive.Content,
|
|
2173
|
-
{
|
|
2174
|
-
"data-slot": "popover-content",
|
|
2175
|
-
align,
|
|
2176
|
-
sideOffset,
|
|
2177
|
-
className: cn(
|
|
2178
|
-
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden",
|
|
2179
|
-
className
|
|
2180
|
-
),
|
|
2181
|
-
...props
|
|
2182
|
-
}
|
|
2183
|
-
) });
|
|
2184
|
-
}
|
|
2185
|
-
function StarRating({
|
|
2186
|
-
rating,
|
|
2187
|
-
size = 18,
|
|
2188
|
-
className
|
|
2189
|
-
}) {
|
|
2190
|
-
return /* @__PURE__ */ jsx("div", { className: cn("flex items-center gap-0.5", className), children: [1, 2, 3, 4, 5].map((star) => /* @__PURE__ */ jsx(
|
|
2191
|
-
DynamicIcon,
|
|
2192
|
-
{
|
|
2193
|
-
name: "icon-park-solid/star",
|
|
2194
|
-
size,
|
|
2195
|
-
className: cn(
|
|
2196
|
-
star <= rating ? "fill-primary text-primary" : "fill-muted text-muted"
|
|
2197
|
-
)
|
|
2198
|
-
},
|
|
2199
|
-
star
|
|
2200
|
-
)) });
|
|
2201
|
-
}
|
|
1547
|
+
Pressable.displayName = "Pressable";
|
|
2202
1548
|
var BUTTON_SIZES = {
|
|
2203
1549
|
sm: { buttonSize: "size-8", iconSize: 16 },
|
|
2204
1550
|
md: { buttonSize: "size-10", iconSize: 20 },
|
|
@@ -2290,7 +1636,7 @@ var platformIconMap = {
|
|
|
2290
1636
|
dribbble: "cib/dribbble",
|
|
2291
1637
|
unknown: "icon-park-solid/circular-connection"
|
|
2292
1638
|
};
|
|
2293
|
-
var SocialLinkIcon =
|
|
1639
|
+
var SocialLinkIcon = React4.forwardRef(
|
|
2294
1640
|
({
|
|
2295
1641
|
platformName,
|
|
2296
1642
|
label,
|
|
@@ -2304,16 +1650,16 @@ var SocialLinkIcon = React6.forwardRef(
|
|
|
2304
1650
|
...pressableProps
|
|
2305
1651
|
}, ref) => {
|
|
2306
1652
|
const platform = usePlatformFromUrl(href);
|
|
2307
|
-
const smartPlatformName =
|
|
1653
|
+
const smartPlatformName = React4.useMemo(() => {
|
|
2308
1654
|
return platform || platformName;
|
|
2309
1655
|
}, [platform, platformName]);
|
|
2310
|
-
const iconName =
|
|
1656
|
+
const iconName = React4.useMemo(() => {
|
|
2311
1657
|
return iconNameOverride || platformIconMap[smartPlatformName];
|
|
2312
1658
|
}, [iconNameOverride, smartPlatformName]);
|
|
2313
|
-
const accessibleLabel =
|
|
1659
|
+
const accessibleLabel = React4.useMemo(() => {
|
|
2314
1660
|
return label || platformName;
|
|
2315
1661
|
}, [label, platformName]);
|
|
2316
|
-
const icon =
|
|
1662
|
+
const icon = React4.useMemo(() => {
|
|
2317
1663
|
return /* @__PURE__ */ jsx(
|
|
2318
1664
|
DynamicIcon,
|
|
2319
1665
|
{
|
|
@@ -2393,12 +1739,12 @@ function TextInner({ as, className, children, ...props }, ref) {
|
|
|
2393
1739
|
const Component = as || "span";
|
|
2394
1740
|
return /* @__PURE__ */ jsx(Component, { ref, className: cn(className), ...props, children });
|
|
2395
1741
|
}
|
|
2396
|
-
var Text =
|
|
1742
|
+
var Text = React4.forwardRef(TextInner);
|
|
2397
1743
|
Text.displayName = "Text";
|
|
2398
1744
|
function isContentTextItem(item) {
|
|
2399
|
-
return item !== null && typeof item === "object" && !
|
|
1745
|
+
return item !== null && typeof item === "object" && !React4.isValidElement(item) && "_type" in item && item._type === "text";
|
|
2400
1746
|
}
|
|
2401
|
-
var ContentGroup =
|
|
1747
|
+
var ContentGroup = React4.forwardRef(
|
|
2402
1748
|
({ items, className, children, ...props }, ref) => {
|
|
2403
1749
|
const hasContent = items && items.length > 0;
|
|
2404
1750
|
if (!hasContent) {
|
|
@@ -2411,10 +1757,10 @@ var ContentGroup = React6.forwardRef(
|
|
|
2411
1757
|
return /* @__PURE__ */ jsx(Text, { ...textProps }, idx);
|
|
2412
1758
|
}
|
|
2413
1759
|
const reactNode = item;
|
|
2414
|
-
if (
|
|
2415
|
-
return
|
|
1760
|
+
if (React4.isValidElement(reactNode)) {
|
|
1761
|
+
return React4.cloneElement(reactNode, { key: reactNode.key ?? idx });
|
|
2416
1762
|
}
|
|
2417
|
-
return /* @__PURE__ */ jsx(
|
|
1763
|
+
return /* @__PURE__ */ jsx(React4.Fragment, { children: reactNode }, idx);
|
|
2418
1764
|
}),
|
|
2419
1765
|
children
|
|
2420
1766
|
] });
|
|
@@ -2939,7 +2285,7 @@ function AboutExpandableValues({
|
|
|
2939
2285
|
pattern,
|
|
2940
2286
|
patternOpacity
|
|
2941
2287
|
}) {
|
|
2942
|
-
const [expandedValue, setExpandedValue] =
|
|
2288
|
+
const [expandedValue, setExpandedValue] = React4.useState(null);
|
|
2943
2289
|
const toggleExpand = useCallback((id) => {
|
|
2944
2290
|
setExpandedValue((prev) => prev === id ? null : id);
|
|
2945
2291
|
}, []);
|
|
@@ -3175,7 +2521,7 @@ function CommunityInitiatives({
|
|
|
3175
2521
|
pattern,
|
|
3176
2522
|
patternOpacity
|
|
3177
2523
|
}) {
|
|
3178
|
-
const [activeCategory, setActiveCategory] =
|
|
2524
|
+
const [activeCategory, setActiveCategory] = React4.useState(
|
|
3179
2525
|
categories?.[0]?.id || ""
|
|
3180
2526
|
);
|
|
3181
2527
|
const currentCategory = categories?.find((category) => category.id === activeCategory) || categories?.[0];
|
|
@@ -3439,7 +2785,7 @@ function AboutCultureTabs({
|
|
|
3439
2785
|
patternOpacity
|
|
3440
2786
|
}) {
|
|
3441
2787
|
const resolvedAspects = aspects ?? [];
|
|
3442
|
-
const [activeTab, setActiveTab] =
|
|
2788
|
+
const [activeTab, setActiveTab] = React4.useState(
|
|
3443
2789
|
resolvedAspects[0]?.id || ""
|
|
3444
2790
|
);
|
|
3445
2791
|
const headerItems = useMemo(() => {
|
|
@@ -3972,7 +3318,7 @@ function BannerDeliveryCountdown({
|
|
|
3972
3318
|
}, [prefixText, timerContent, middleText, deliveryDateContent]);
|
|
3973
3319
|
return /* @__PURE__ */ jsx(Section, { background, spacing: "none", className: cn("bg-accent text-accent-foreground", className), children: /* @__PURE__ */ jsx("div", { className: cn("container py-2.5", containerClassName), children: /* @__PURE__ */ jsx("div", { className: cn("flex flex-wrap items-center justify-center gap-3 text-sm", contentClassName), children: /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2", messageClassName), children: [
|
|
3974
3320
|
iconContent,
|
|
3975
|
-
messageParts.length > 0 && /* @__PURE__ */ jsx("span", { children: messageParts.map((part, index) => /* @__PURE__ */ jsxs(
|
|
3321
|
+
messageParts.length > 0 && /* @__PURE__ */ jsx("span", { children: messageParts.map((part, index) => /* @__PURE__ */ jsxs(React4.Fragment, { children: [
|
|
3976
3322
|
index > 0 ? " " : null,
|
|
3977
3323
|
part
|
|
3978
3324
|
] }, index)) })
|
|
@@ -5243,8 +4589,8 @@ var BrandAttribution = ({
|
|
|
5243
4589
|
}
|
|
5244
4590
|
const { prefix = "", anchorText, href, suffix = "" } = options[optionIndex];
|
|
5245
4591
|
const ContainerEl = variant;
|
|
5246
|
-
const [trackedHref, setTrackedHref] =
|
|
5247
|
-
|
|
4592
|
+
const [trackedHref, setTrackedHref] = React4.useState(href);
|
|
4593
|
+
React4.useEffect(() => {
|
|
5248
4594
|
setTrackedHref(buildTrackedHref(href));
|
|
5249
4595
|
}, [href]);
|
|
5250
4596
|
return /* @__PURE__ */ jsxs(ContainerEl, { className: containerClassName, children: [
|
|
@@ -5364,7 +4710,7 @@ function FooterSocialNewsletter({
|
|
|
5364
4710
|
patternOpacity,
|
|
5365
4711
|
optixFlowConfig
|
|
5366
4712
|
}) {
|
|
5367
|
-
const renderForm =
|
|
4713
|
+
const renderForm = React4.useMemo(() => {
|
|
5368
4714
|
if (!formEngineSetup) return null;
|
|
5369
4715
|
const action = {
|
|
5370
4716
|
variant: "default",
|
|
@@ -5653,7 +4999,7 @@ function FooterSimpleCentered({
|
|
|
5653
4999
|
]);
|
|
5654
5000
|
const bottomLinksContent = useMemo(() => {
|
|
5655
5001
|
if (!bottomLinks || bottomLinks.length === 0) return null;
|
|
5656
|
-
return bottomLinks.map((link, idx) => /* @__PURE__ */ jsx(
|
|
5002
|
+
return bottomLinks.map((link, idx) => /* @__PURE__ */ jsx(React4.Fragment, { children: /* @__PURE__ */ jsx(
|
|
5657
5003
|
Pressable,
|
|
5658
5004
|
{
|
|
5659
5005
|
href: link.href,
|
|
@@ -7000,7 +6346,7 @@ function FooterNewsletterMinimal({
|
|
|
7000
6346
|
buttonAction,
|
|
7001
6347
|
formSlot
|
|
7002
6348
|
}) {
|
|
7003
|
-
const navLinksContent =
|
|
6349
|
+
const navLinksContent = React4.useMemo(() => {
|
|
7004
6350
|
if (!navLinks || navLinks.length === 0) return null;
|
|
7005
6351
|
return navLinks.map((item, idx) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
|
|
7006
6352
|
Pressable,
|
|
@@ -7011,7 +6357,7 @@ function FooterNewsletterMinimal({
|
|
|
7011
6357
|
}
|
|
7012
6358
|
) }, idx));
|
|
7013
6359
|
}, [navLinks, navLinkClassName]);
|
|
7014
|
-
const socialLinksContent =
|
|
6360
|
+
const socialLinksContent = React4.useMemo(() => {
|
|
7015
6361
|
if (!socialLinks || socialLinks.length === 0) return null;
|
|
7016
6362
|
return socialLinks.map((item, idx) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
|
|
7017
6363
|
SocialLinkIcon,
|
|
@@ -7027,7 +6373,7 @@ function FooterNewsletterMinimal({
|
|
|
7027
6373
|
}
|
|
7028
6374
|
) }, idx));
|
|
7029
6375
|
}, [socialLinks, socialLinkClassName]);
|
|
7030
|
-
const footerLinksContent =
|
|
6376
|
+
const footerLinksContent = React4.useMemo(() => {
|
|
7031
6377
|
if (!footerLinks || footerLinks.length === 0) return null;
|
|
7032
6378
|
return footerLinks.map((item) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
|
|
7033
6379
|
Pressable,
|
|
@@ -7041,7 +6387,7 @@ function FooterNewsletterMinimal({
|
|
|
7041
6387
|
}
|
|
7042
6388
|
) }, item.label));
|
|
7043
6389
|
}, [footerLinks, footerLinkClassName]);
|
|
7044
|
-
const renderForm =
|
|
6390
|
+
const renderForm = React4.useMemo(() => {
|
|
7045
6391
|
if (formSlot) return formSlot;
|
|
7046
6392
|
if (!formEngineSetup) return null;
|
|
7047
6393
|
const defaultButtonAction = {
|
|
@@ -7598,4 +6944,4 @@ var useResponsiveLayout = ({
|
|
|
7598
6944
|
return { responsiveClassName };
|
|
7599
6945
|
};
|
|
7600
6946
|
|
|
7601
|
-
export { AboutCultureTabs, AboutExpandableValues, AboutMissionPrinciples, AboutSplitHero, AlternatingBlocks, AnimatedDialog, Badge, BannerAnnouncementDismissible, BannerCountdownSale, BannerDeliveryCountdown, BannerEventPromo, BannerFloatingOffer, BannerGdprRights, BannerPrivacyNotice, BannerPromoCta, BannerSocialFollow, BannerSurveyIncentive, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CarouselPagination, CommunityInitiatives, Container, DynamicIcon, FooterAnimatedSocial, FooterBackgroundCard, FooterBrandDescription, FooterContactCard, FooterCtaBanner, FooterCtaSocial, FooterLinksGrid, FooterNavSocial, FooterNewsletterGrid, FooterNewsletterMinimal, FooterSimpleCentered, FooterSocialApps, FooterSocialNewsletter,
|
|
6947
|
+
export { AboutCultureTabs, AboutExpandableValues, AboutMissionPrinciples, AboutSplitHero, AlternatingBlocks, AnimatedDialog, Badge, BannerAnnouncementDismissible, BannerCountdownSale, BannerDeliveryCountdown, BannerEventPromo, BannerFloatingOffer, BannerGdprRights, BannerPrivacyNotice, BannerPromoCta, BannerSocialFollow, BannerSurveyIncentive, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CarouselPagination, CommunityInitiatives, Container, DynamicIcon, FooterAnimatedSocial, FooterBackgroundCard, FooterBrandDescription, FooterContactCard, FooterCtaBanner, FooterCtaSocial, FooterLinksGrid, FooterNavSocial, FooterNewsletterGrid, FooterNewsletterMinimal, FooterSimpleCentered, FooterSocialApps, FooterSocialNewsletter, ImageSlider, MediaHoverCtas, PageHeroBanner, PaymentPlatformIcon, Popover, PopoverContent, PopoverTrigger, Pressable, Section, SocialLinkIcon, StarRating, cn, getAccentColor, getBorderColor, getNestedCardBg, getNestedCardTextColor, getTextColor, useNavigation, useResponsiveLayout };
|