@opensite/ui 2.8.7 → 2.8.9
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-icon-sidebar.cjs +5 -4
- package/dist/carousel-icon-sidebar.js +5 -4
- package/dist/community-initiatives.cjs +142 -142
- package/dist/community-initiatives.js +142 -142
- package/dist/components.cjs +723 -1364
- package/dist/components.d.cts +0 -2
- package/dist/components.d.ts +0 -2
- package/dist/components.js +633 -1273
- package/dist/contact-map.cjs +14 -1069
- package/dist/contact-map.d.cts +13 -3
- package/dist/contact-map.d.ts +13 -3
- package/dist/contact-map.js +14 -1069
- 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 -1366
- package/dist/index.d.cts +0 -2
- package/dist/index.d.ts +0 -2
- package/dist/index.js +634 -1274
- package/dist/registry.cjs +2371 -2915
- package/dist/registry.js +1120 -1664
- package/dist/testimonials-large-quote.cjs +74 -43
- package/dist/testimonials-large-quote.d.cts +5 -1
- package/dist/testimonials-large-quote.d.ts +5 -1
- package/dist/testimonials-large-quote.js +74 -43
- package/dist/testimonials-logo-cards.cjs +8 -2
- package/dist/testimonials-logo-cards.js +8 -2
- package/dist/testimonials-masonry-grid.cjs +486 -69
- package/dist/testimonials-masonry-grid.d.cts +5 -1
- package/dist/testimonials-masonry-grid.d.ts +5 -1
- package/dist/testimonials-masonry-grid.js +483 -63
- package/dist/testimonials-mini-dividers.cjs +2 -3
- package/dist/testimonials-mini-dividers.js +2 -3
- package/dist/testimonials-minimal-numbered.cjs +5 -4
- package/dist/testimonials-minimal-numbered.js +5 -4
- package/dist/testimonials-parallax-number.cjs +5 -4
- package/dist/testimonials-parallax-number.js +5 -4
- package/dist/testimonials-scrolling-columns.cjs +7 -12
- package/dist/testimonials-scrolling-columns.js +7 -12
- package/dist/testimonials-stats-header.cjs +528 -87
- package/dist/testimonials-stats-header.d.cts +39 -3
- package/dist/testimonials-stats-header.d.ts +39 -3
- package/dist/testimonials-stats-header.js +523 -82
- package/package.json +4 -7
- package/dist/geo-map.cjs +0 -1103
- package/dist/geo-map.d.cts +0 -92
- package/dist/geo-map.d.ts +0 -92
- package/dist/geo-map.js +0 -1081
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,1131 +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
|
-
const activeMediaItem = mediaItems[activeItemIndex];
|
|
1023
|
-
const mediaType = resolveMediaType(activeMediaItem);
|
|
1024
|
-
return /* @__PURE__ */ jsxs("div", { className: "relative border-b border-border/60 bg-muted/40", children: [
|
|
1025
|
-
/* @__PURE__ */ jsx("div", { className: "relative h-44 w-full overflow-hidden", children: mediaType === "video" ? /* @__PURE__ */ jsx(
|
|
1026
|
-
"video",
|
|
1027
|
-
{
|
|
1028
|
-
className: "h-full w-full object-cover",
|
|
1029
|
-
controls: true,
|
|
1030
|
-
preload: "metadata",
|
|
1031
|
-
poster: activeMediaItem.poster,
|
|
1032
|
-
children: /* @__PURE__ */ jsx("source", { src: activeMediaItem.src })
|
|
1033
|
-
}
|
|
1034
|
-
) : /* @__PURE__ */ jsx(
|
|
1035
|
-
Img,
|
|
1036
|
-
{
|
|
1037
|
-
src: activeMediaItem.src,
|
|
1038
|
-
alt: activeMediaItem.alt ?? "Map marker media",
|
|
1039
|
-
className: "h-full w-full object-cover",
|
|
1040
|
-
loading: "eager",
|
|
1041
|
-
optixFlowConfig
|
|
1042
|
-
}
|
|
1043
|
-
) }),
|
|
1044
|
-
totalItems > 1 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1045
|
-
/* @__PURE__ */ jsx(
|
|
1046
|
-
"button",
|
|
1047
|
-
{
|
|
1048
|
-
type: "button",
|
|
1049
|
-
"aria-label": "Show previous media",
|
|
1050
|
-
className: "absolute left-2 top-1/2 inline-flex size-8 -translate-y-1/2 items-center justify-center rounded-full bg-card text-card-foreground shadow-sm transition hover:bg-muted hover:text-muted-foreground",
|
|
1051
|
-
onClick: () => {
|
|
1052
|
-
setActiveIndex(
|
|
1053
|
-
(current) => (current - 1 + totalItems) % totalItems
|
|
1054
|
-
);
|
|
1055
|
-
},
|
|
1056
|
-
children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/arrow-left", size: 16 })
|
|
1057
|
-
}
|
|
1058
|
-
),
|
|
1059
|
-
/* @__PURE__ */ jsx(
|
|
1060
|
-
"button",
|
|
1061
|
-
{
|
|
1062
|
-
type: "button",
|
|
1063
|
-
"aria-label": "Show next media",
|
|
1064
|
-
className: "absolute right-2 top-1/2 inline-flex h-8 w-8 -translate-y-1/2 items-center justify-center rounded-full bg-card text-card-foreground shadow-sm transition hover:bg-muted hover:text-muted-foreground",
|
|
1065
|
-
onClick: () => {
|
|
1066
|
-
setActiveIndex((current) => (current + 1) % totalItems);
|
|
1067
|
-
},
|
|
1068
|
-
children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/arrow-right", size: 16 })
|
|
1069
|
-
}
|
|
1070
|
-
),
|
|
1071
|
-
/* @__PURE__ */ jsx("div", { className: "absolute bottom-2 left-1/2 flex -translate-x-1/2 items-center gap-1.5", children: mediaItems.map((item, index) => /* @__PURE__ */ jsx(
|
|
1072
|
-
"button",
|
|
1073
|
-
{
|
|
1074
|
-
type: "button",
|
|
1075
|
-
"aria-label": `Show media item ${index + 1}`,
|
|
1076
|
-
className: cn(
|
|
1077
|
-
"h-2 rounded-full transition-all",
|
|
1078
|
-
index === activeItemIndex ? "w-6 bg-card" : "w-2 bg-card opacity-50 hover:opacity-100"
|
|
1079
|
-
),
|
|
1080
|
-
onClick: () => setActiveIndex(index)
|
|
1081
|
-
},
|
|
1082
|
-
normalizeId(item.id, `media-dot-${index}`)
|
|
1083
|
-
)) })
|
|
1084
|
-
] }) : null
|
|
1085
|
-
] });
|
|
1086
|
-
}
|
|
1087
|
-
function getMarkerTitle(marker, markerIndex) {
|
|
1088
|
-
if (marker.title !== void 0 && marker.title !== null) {
|
|
1089
|
-
return marker.title;
|
|
1090
|
-
}
|
|
1091
|
-
if (marker.label !== void 0 && marker.label !== null) {
|
|
1092
|
-
return marker.label;
|
|
1093
|
-
}
|
|
1094
|
-
return `Location ${markerIndex + 1}`;
|
|
1095
|
-
}
|
|
1096
|
-
function GeoMap({
|
|
1097
|
-
className,
|
|
1098
|
-
mapWrapperClassName,
|
|
1099
|
-
mapClassName,
|
|
1100
|
-
panelClassName,
|
|
1101
|
-
panelPosition = "top-left",
|
|
1102
|
-
stadiaApiKey = "",
|
|
1103
|
-
mapStyle = "osm-bright",
|
|
1104
|
-
styleUrl,
|
|
1105
|
-
mapLibreCssHref,
|
|
1106
|
-
markers = [],
|
|
1107
|
-
clusters = [],
|
|
1108
|
-
viewState,
|
|
1109
|
-
defaultViewState,
|
|
1110
|
-
onViewStateChange,
|
|
1111
|
-
onMapClick,
|
|
1112
|
-
onMarkerDrag,
|
|
1113
|
-
showNavigationControl = true,
|
|
1114
|
-
showGeolocateControl = false,
|
|
1115
|
-
navigationControlPosition = "top-right",
|
|
1116
|
-
geolocateControlPosition = "top-left",
|
|
1117
|
-
flyToOptions,
|
|
1118
|
-
markerFocusZoom = 14,
|
|
1119
|
-
clusterFocusZoom = 5,
|
|
1120
|
-
selectedMarkerId,
|
|
1121
|
-
initialSelectedMarkerId,
|
|
1122
|
-
onSelectionChange,
|
|
1123
|
-
clearSelectionOnMapClick = true,
|
|
1124
|
-
mapChildren,
|
|
1125
|
-
optixFlowConfig
|
|
1126
|
-
}) {
|
|
1127
|
-
const normalizedStandaloneMarkers = React6.useMemo(
|
|
1128
|
-
() => markers.map((marker, index) => ({
|
|
1129
|
-
...marker,
|
|
1130
|
-
id: normalizeId(marker.id, `marker-${index}`)
|
|
1131
|
-
})),
|
|
1132
|
-
[markers]
|
|
1133
|
-
);
|
|
1134
|
-
const normalizedClusters = React6.useMemo(() => {
|
|
1135
|
-
const results = [];
|
|
1136
|
-
clusters.forEach((cluster, clusterIndex) => {
|
|
1137
|
-
const clusterId = normalizeId(cluster.id, `cluster-${clusterIndex}`);
|
|
1138
|
-
const normalizedClusterMarkers = cluster.markers.map(
|
|
1139
|
-
(marker, markerIndex) => ({
|
|
1140
|
-
...marker,
|
|
1141
|
-
id: normalizeId(marker.id, `${clusterId}-marker-${markerIndex}`),
|
|
1142
|
-
clusterId
|
|
1143
|
-
})
|
|
1144
|
-
);
|
|
1145
|
-
const clusterCenter = cluster.latitude !== void 0 && cluster.longitude !== void 0 ? { latitude: cluster.latitude, longitude: cluster.longitude } : buildClusterCenter(normalizedClusterMarkers);
|
|
1146
|
-
if (!clusterCenter) {
|
|
1147
|
-
return;
|
|
1148
|
-
}
|
|
1149
|
-
results.push({
|
|
1150
|
-
...cluster,
|
|
1151
|
-
id: clusterId,
|
|
1152
|
-
latitude: clusterCenter.latitude,
|
|
1153
|
-
longitude: clusterCenter.longitude,
|
|
1154
|
-
markers: normalizedClusterMarkers
|
|
1155
|
-
});
|
|
1156
|
-
});
|
|
1157
|
-
return results;
|
|
1158
|
-
}, [clusters]);
|
|
1159
|
-
const markerLookup = React6.useMemo(() => {
|
|
1160
|
-
const lookup = /* @__PURE__ */ new Map();
|
|
1161
|
-
normalizedStandaloneMarkers.forEach((marker) => {
|
|
1162
|
-
lookup.set(marker.id, marker);
|
|
1163
|
-
});
|
|
1164
|
-
normalizedClusters.forEach((cluster) => {
|
|
1165
|
-
cluster.markers.forEach((marker) => {
|
|
1166
|
-
lookup.set(marker.id, marker);
|
|
1167
|
-
});
|
|
1168
|
-
});
|
|
1169
|
-
return lookup;
|
|
1170
|
-
}, [normalizedClusters, normalizedStandaloneMarkers]);
|
|
1171
|
-
const clusterLookup = React6.useMemo(() => {
|
|
1172
|
-
const lookup = /* @__PURE__ */ new Map();
|
|
1173
|
-
normalizedClusters.forEach((cluster) => {
|
|
1174
|
-
lookup.set(cluster.id, cluster);
|
|
1175
|
-
});
|
|
1176
|
-
return lookup;
|
|
1177
|
-
}, [normalizedClusters]);
|
|
1178
|
-
const firstCoordinate = React6.useMemo(() => {
|
|
1179
|
-
if (normalizedStandaloneMarkers.length > 0) {
|
|
1180
|
-
const firstStandaloneMarker = normalizedStandaloneMarkers[0];
|
|
1181
|
-
return {
|
|
1182
|
-
latitude: firstStandaloneMarker.latitude,
|
|
1183
|
-
longitude: firstStandaloneMarker.longitude
|
|
1184
|
-
};
|
|
1185
|
-
}
|
|
1186
|
-
if (normalizedClusters.length > 0) {
|
|
1187
|
-
const firstCluster = normalizedClusters[0];
|
|
1188
|
-
return {
|
|
1189
|
-
latitude: firstCluster.latitude,
|
|
1190
|
-
longitude: firstCluster.longitude
|
|
1191
|
-
};
|
|
1192
|
-
}
|
|
1193
|
-
return {
|
|
1194
|
-
latitude: DEFAULT_VIEW_STATE.latitude,
|
|
1195
|
-
longitude: DEFAULT_VIEW_STATE.longitude
|
|
1196
|
-
};
|
|
1197
|
-
}, [normalizedClusters, normalizedStandaloneMarkers]);
|
|
1198
|
-
const [uncontrolledViewState, setUncontrolledViewState] = React6.useState({
|
|
1199
|
-
latitude: defaultViewState?.latitude ?? firstCoordinate.latitude,
|
|
1200
|
-
longitude: defaultViewState?.longitude ?? firstCoordinate.longitude,
|
|
1201
|
-
zoom: defaultViewState?.zoom ?? DEFAULT_VIEW_STATE.zoom
|
|
1202
|
-
});
|
|
1203
|
-
const isControlledViewState = viewState !== void 0;
|
|
1204
|
-
const resolvedViewState = isControlledViewState ? viewState : uncontrolledViewState;
|
|
1205
|
-
const applyViewState = React6.useCallback(
|
|
1206
|
-
(nextState) => {
|
|
1207
|
-
if (!isControlledViewState) {
|
|
1208
|
-
setUncontrolledViewState((current) => {
|
|
1209
|
-
const next = { ...current, ...nextState };
|
|
1210
|
-
const hasChanged = current.latitude !== next.latitude || current.longitude !== next.longitude || current.zoom !== next.zoom;
|
|
1211
|
-
return hasChanged ? next : current;
|
|
1212
|
-
});
|
|
1213
|
-
}
|
|
1214
|
-
onViewStateChange?.(nextState);
|
|
1215
|
-
},
|
|
1216
|
-
[isControlledViewState, onViewStateChange]
|
|
1217
|
-
);
|
|
1218
|
-
const [selection, setSelection] = React6.useState(() => {
|
|
1219
|
-
if (initialSelectedMarkerId !== void 0 && initialSelectedMarkerId !== null) {
|
|
1220
|
-
return {
|
|
1221
|
-
type: "marker",
|
|
1222
|
-
markerId: String(initialSelectedMarkerId)
|
|
1223
|
-
};
|
|
1224
|
-
}
|
|
1225
|
-
return { type: "none" };
|
|
1226
|
-
});
|
|
1227
|
-
React6.useEffect(() => {
|
|
1228
|
-
if (selectedMarkerId === void 0 || selectedMarkerId === null) {
|
|
1229
|
-
return;
|
|
1230
|
-
}
|
|
1231
|
-
setSelection({
|
|
1232
|
-
type: "marker",
|
|
1233
|
-
markerId: String(selectedMarkerId)
|
|
1234
|
-
});
|
|
1235
|
-
}, [selectedMarkerId]);
|
|
1236
|
-
const selectedMarker = selection.markerId ? markerLookup.get(selection.markerId) : void 0;
|
|
1237
|
-
const selectedCluster = selection.clusterId ? clusterLookup.get(selection.clusterId) : void 0;
|
|
1238
|
-
React6.useEffect(() => {
|
|
1239
|
-
if (selection.type === "marker" && selection.markerId && !selectedMarker) {
|
|
1240
|
-
setSelection({ type: "none" });
|
|
1241
|
-
onSelectionChange?.({ type: "none" });
|
|
1242
|
-
}
|
|
1243
|
-
}, [onSelectionChange, selectedMarker, selection]);
|
|
1244
|
-
const emitSelectionChange = React6.useCallback(
|
|
1245
|
-
(nextSelection) => {
|
|
1246
|
-
if (nextSelection.type === "none") {
|
|
1247
|
-
onSelectionChange?.({ type: "none" });
|
|
1248
|
-
return;
|
|
1249
|
-
}
|
|
1250
|
-
if (nextSelection.type === "marker") {
|
|
1251
|
-
const parentCluster = nextSelection.marker.clusterId ? clusterLookup.get(nextSelection.marker.clusterId) : void 0;
|
|
1252
|
-
onSelectionChange?.({
|
|
1253
|
-
type: "marker",
|
|
1254
|
-
marker: nextSelection.marker,
|
|
1255
|
-
cluster: parentCluster
|
|
1256
|
-
});
|
|
1257
|
-
return;
|
|
1258
|
-
}
|
|
1259
|
-
onSelectionChange?.({
|
|
1260
|
-
type: "cluster",
|
|
1261
|
-
cluster: nextSelection.cluster
|
|
1262
|
-
});
|
|
1263
|
-
},
|
|
1264
|
-
[clusterLookup, onSelectionChange]
|
|
1265
|
-
);
|
|
1266
|
-
const selectMarker = React6.useCallback(
|
|
1267
|
-
(marker) => {
|
|
1268
|
-
setSelection({
|
|
1269
|
-
type: "marker",
|
|
1270
|
-
markerId: marker.id,
|
|
1271
|
-
clusterId: marker.clusterId
|
|
1272
|
-
});
|
|
1273
|
-
applyViewState({
|
|
1274
|
-
latitude: marker.latitude,
|
|
1275
|
-
longitude: marker.longitude,
|
|
1276
|
-
zoom: markerFocusZoom
|
|
1277
|
-
});
|
|
1278
|
-
emitSelectionChange({ type: "marker", marker });
|
|
1279
|
-
},
|
|
1280
|
-
[applyViewState, emitSelectionChange, markerFocusZoom]
|
|
1281
|
-
);
|
|
1282
|
-
const selectCluster = React6.useCallback(
|
|
1283
|
-
(cluster) => {
|
|
1284
|
-
setSelection({
|
|
1285
|
-
type: "cluster",
|
|
1286
|
-
clusterId: cluster.id
|
|
1287
|
-
});
|
|
1288
|
-
applyViewState({
|
|
1289
|
-
latitude: cluster.latitude,
|
|
1290
|
-
longitude: cluster.longitude,
|
|
1291
|
-
zoom: clusterFocusZoom
|
|
1292
|
-
});
|
|
1293
|
-
emitSelectionChange({ type: "cluster", cluster });
|
|
1294
|
-
},
|
|
1295
|
-
[applyViewState, clusterFocusZoom, emitSelectionChange]
|
|
1296
|
-
);
|
|
1297
|
-
const clearSelection = React6.useCallback(() => {
|
|
1298
|
-
setSelection({ type: "none" });
|
|
1299
|
-
emitSelectionChange({ type: "none" });
|
|
1300
|
-
}, [emitSelectionChange]);
|
|
1301
|
-
const mapMarkers = React6.useMemo(() => {
|
|
1302
|
-
const resolvedMarkers = [];
|
|
1303
|
-
normalizedClusters.forEach((cluster) => {
|
|
1304
|
-
const isSelected = selection.type === "cluster" && selection.clusterId === cluster.id;
|
|
1305
|
-
resolvedMarkers.push({
|
|
1306
|
-
id: `cluster-pin:${cluster.id}`,
|
|
1307
|
-
latitude: cluster.latitude,
|
|
1308
|
-
longitude: cluster.longitude,
|
|
1309
|
-
element: () => {
|
|
1310
|
-
const customMarkerElement = cluster.markerElement;
|
|
1311
|
-
const markerBody = typeof customMarkerElement === "function" ? customMarkerElement({
|
|
1312
|
-
isSelected,
|
|
1313
|
-
count: cluster.markers.length
|
|
1314
|
-
}) : customMarkerElement;
|
|
1315
|
-
return /* @__PURE__ */ jsx(
|
|
1316
|
-
"button",
|
|
1317
|
-
{
|
|
1318
|
-
type: "button",
|
|
1319
|
-
className: "group cursor-pointer",
|
|
1320
|
-
onClick: (event) => {
|
|
1321
|
-
event.preventDefault();
|
|
1322
|
-
event.stopPropagation();
|
|
1323
|
-
selectCluster(cluster);
|
|
1324
|
-
},
|
|
1325
|
-
"aria-label": `View ${cluster.markers.length} clustered locations`,
|
|
1326
|
-
children: markerBody ?? /* @__PURE__ */ jsx(
|
|
1327
|
-
"span",
|
|
1328
|
-
{
|
|
1329
|
-
className: cn(
|
|
1330
|
-
"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",
|
|
1331
|
-
isSelected && "ring-4 ring-primary/30",
|
|
1332
|
-
cluster.pinClassName
|
|
1333
|
-
),
|
|
1334
|
-
style: {
|
|
1335
|
-
backgroundColor: cluster.pinColor ?? "var(--foreground)"
|
|
1336
|
-
},
|
|
1337
|
-
children: cluster.markers.length
|
|
1338
|
-
}
|
|
1339
|
-
)
|
|
1340
|
-
}
|
|
1341
|
-
);
|
|
1342
|
-
}
|
|
1343
|
-
});
|
|
1344
|
-
});
|
|
1345
|
-
normalizedStandaloneMarkers.forEach((marker) => {
|
|
1346
|
-
const isSelected = selection.type === "marker" && selection.markerId === marker.id;
|
|
1347
|
-
const customMarkerElement = marker.markerElement;
|
|
1348
|
-
resolvedMarkers.push({
|
|
1349
|
-
id: marker.id,
|
|
1350
|
-
latitude: marker.latitude,
|
|
1351
|
-
longitude: marker.longitude,
|
|
1352
|
-
draggable: marker.draggable,
|
|
1353
|
-
element: () => {
|
|
1354
|
-
const markerBody = typeof customMarkerElement === "function" ? customMarkerElement({ isSelected }) : customMarkerElement;
|
|
1355
|
-
return /* @__PURE__ */ jsx(
|
|
1356
|
-
"button",
|
|
1357
|
-
{
|
|
1358
|
-
type: "button",
|
|
1359
|
-
className: "group cursor-pointer",
|
|
1360
|
-
onClick: (event) => {
|
|
1361
|
-
event.preventDefault();
|
|
1362
|
-
event.stopPropagation();
|
|
1363
|
-
selectMarker(marker);
|
|
1364
|
-
},
|
|
1365
|
-
"aria-label": typeof marker.title === "string" ? `View ${marker.title}` : "View location details",
|
|
1366
|
-
children: markerBody ?? /* @__PURE__ */ jsx(
|
|
1367
|
-
"span",
|
|
1368
|
-
{
|
|
1369
|
-
className: cn(
|
|
1370
|
-
"inline-flex h-4 w-4 rounded-full border-2 border-white shadow-md transition-transform duration-200 group-hover:scale-110",
|
|
1371
|
-
isSelected && "h-5 w-5 ring-4 ring-primary/30",
|
|
1372
|
-
marker.pinClassName
|
|
1373
|
-
),
|
|
1374
|
-
style: {
|
|
1375
|
-
backgroundColor: marker.pinColor ?? "#f43f5e"
|
|
1376
|
-
}
|
|
1377
|
-
}
|
|
1378
|
-
)
|
|
1379
|
-
}
|
|
1380
|
-
);
|
|
1381
|
-
}
|
|
1382
|
-
});
|
|
1383
|
-
});
|
|
1384
|
-
return resolvedMarkers;
|
|
1385
|
-
}, [
|
|
1386
|
-
normalizedClusters,
|
|
1387
|
-
normalizedStandaloneMarkers,
|
|
1388
|
-
selectCluster,
|
|
1389
|
-
selectMarker,
|
|
1390
|
-
selection
|
|
1391
|
-
]);
|
|
1392
|
-
const renderMarkerPanel = () => {
|
|
1393
|
-
if (selectedMarker) {
|
|
1394
|
-
const markerMediaItems = selectedMarker.mediaItems ?? [];
|
|
1395
|
-
return /* @__PURE__ */ jsxs(
|
|
1396
|
-
"div",
|
|
1397
|
-
{
|
|
1398
|
-
className: cn(
|
|
1399
|
-
"relative w-[min(24rem,calc(100vw-2rem))] overflow-hidden rounded-xl border border-border bg-card text-card-foreground shadow-2xl",
|
|
1400
|
-
panelClassName
|
|
1401
|
-
),
|
|
1402
|
-
children: [
|
|
1403
|
-
/* @__PURE__ */ jsx(
|
|
1404
|
-
"button",
|
|
1405
|
-
{
|
|
1406
|
-
type: "button",
|
|
1407
|
-
"aria-label": "Close marker details",
|
|
1408
|
-
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",
|
|
1409
|
-
onClick: clearSelection,
|
|
1410
|
-
children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/x", size: 16 })
|
|
1411
|
-
}
|
|
1412
|
-
),
|
|
1413
|
-
markerMediaItems.length > 0 ? /* @__PURE__ */ jsx(
|
|
1414
|
-
MarkerMediaCarousel,
|
|
1415
|
-
{
|
|
1416
|
-
mediaItems: markerMediaItems,
|
|
1417
|
-
optixFlowConfig
|
|
1418
|
-
}
|
|
1419
|
-
) : null,
|
|
1420
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-2 p-4", children: [
|
|
1421
|
-
/* @__PURE__ */ jsx("div", { className: "flex items-start justify-between gap-3", children: /* @__PURE__ */ jsxs("div", { className: "min-w-0 space-y-1", children: [
|
|
1422
|
-
selectedMarker.eyebrow ? /* @__PURE__ */ jsx("p", { className: "text-xs font-semibold uppercase tracking-wide", children: selectedMarker.eyebrow }) : null,
|
|
1423
|
-
/* @__PURE__ */ jsx("div", { className: "text-base font-semibold leading-tight", children: selectedMarker.title ?? selectedMarker.label ?? "Location" })
|
|
1424
|
-
] }) }),
|
|
1425
|
-
selectedMarker.summary ? /* @__PURE__ */ jsx("div", { className: "text-sm leading-relaxed", children: selectedMarker.summary }) : null,
|
|
1426
|
-
selectedMarker.locationLine ? /* @__PURE__ */ jsxs("div", { className: "flex flex-row items-center justify-start text-sm gap-2", children: [
|
|
1427
|
-
/* @__PURE__ */ jsx(
|
|
1428
|
-
DynamicIcon,
|
|
1429
|
-
{
|
|
1430
|
-
name: "lucide:map-pin",
|
|
1431
|
-
className: "opacity-50",
|
|
1432
|
-
size: 14
|
|
1433
|
-
}
|
|
1434
|
-
),
|
|
1435
|
-
typeof selectedMarker.locationLine === "string" ? /* @__PURE__ */ jsx(
|
|
1436
|
-
Pressable,
|
|
1437
|
-
{
|
|
1438
|
-
href: selectedMarker.locationUrl,
|
|
1439
|
-
className: cn(
|
|
1440
|
-
"transition-all duration-500",
|
|
1441
|
-
"font-medium opacity-75 hover:opacity-100",
|
|
1442
|
-
selectedMarker.locationUrl ? "underline underline-offset-4" : ""
|
|
1443
|
-
),
|
|
1444
|
-
children: selectedMarker.locationLine
|
|
1445
|
-
}
|
|
1446
|
-
) : selectedMarker.locationLine
|
|
1447
|
-
] }) : null,
|
|
1448
|
-
selectedMarker.hoursLine ? /* @__PURE__ */ jsxs("div", { className: "flex flex-row items-center justify-start text-sm gap-2", children: [
|
|
1449
|
-
/* @__PURE__ */ jsx(
|
|
1450
|
-
DynamicIcon,
|
|
1451
|
-
{
|
|
1452
|
-
name: "lucide:clock",
|
|
1453
|
-
className: "opacity-50",
|
|
1454
|
-
size: 14
|
|
1455
|
-
}
|
|
1456
|
-
),
|
|
1457
|
-
typeof selectedMarker.hoursLine === "string" ? /* @__PURE__ */ jsx("div", { className: "font-medium", children: selectedMarker.hoursLine }) : selectedMarker.hoursLine
|
|
1458
|
-
] }) : null,
|
|
1459
|
-
selectedMarker.markerContentComponent ? /* @__PURE__ */ jsx("div", { className: "relative", children: selectedMarker.markerContentComponent }) : null,
|
|
1460
|
-
/* @__PURE__ */ jsx(MarkerActions, { actions: selectedMarker.actions })
|
|
1461
|
-
] })
|
|
1462
|
-
]
|
|
1463
|
-
}
|
|
1464
|
-
);
|
|
1465
|
-
}
|
|
1466
|
-
if (selectedCluster) {
|
|
1467
|
-
return /* @__PURE__ */ jsxs(
|
|
1468
|
-
"div",
|
|
1469
|
-
{
|
|
1470
|
-
className: cn(
|
|
1471
|
-
"relative w-[min(24rem,calc(100vw-2rem))] overflow-hidden rounded-xl border border-border bg-card text-card-foreground p-4 shadow-2xl",
|
|
1472
|
-
panelClassName
|
|
1473
|
-
),
|
|
1474
|
-
children: [
|
|
1475
|
-
/* @__PURE__ */ jsx(
|
|
1476
|
-
"button",
|
|
1477
|
-
{
|
|
1478
|
-
type: "button",
|
|
1479
|
-
"aria-label": "Close cluster details",
|
|
1480
|
-
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",
|
|
1481
|
-
onClick: clearSelection,
|
|
1482
|
-
children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/x", size: 16 })
|
|
1483
|
-
}
|
|
1484
|
-
),
|
|
1485
|
-
/* @__PURE__ */ jsx("div", { className: "mb-3 flex items-start justify-between gap-3", children: /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
1486
|
-
selectedCluster.label ? /* @__PURE__ */ jsx("p", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: selectedCluster.label }) : null,
|
|
1487
|
-
/* @__PURE__ */ jsx("div", { className: "text-base font-semibold leading-tight text-foreground", children: selectedCluster.title ?? "Clustered Locations" }),
|
|
1488
|
-
/* @__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.` })
|
|
1489
|
-
] }) }),
|
|
1490
|
-
/* @__PURE__ */ jsx("div", { className: "max-h-56 space-y-2 overflow-y-auto pr-1", children: selectedCluster.markers.map((marker, markerIndex) => /* @__PURE__ */ jsxs(
|
|
1491
|
-
"button",
|
|
1492
|
-
{
|
|
1493
|
-
type: "button",
|
|
1494
|
-
className: "w-full rounded-lg border border-border/60 p-3 text-left transition hover:border-border hover:bg-muted/50",
|
|
1495
|
-
onClick: () => selectMarker(marker),
|
|
1496
|
-
children: [
|
|
1497
|
-
/* @__PURE__ */ jsx("div", { className: "line-clamp-1 text-sm font-semibold text-foreground", children: getMarkerTitle(marker, markerIndex) }),
|
|
1498
|
-
marker.summary ? /* @__PURE__ */ jsx("div", { className: "mt-1 line-clamp-2 text-xs text-muted-foreground", children: marker.summary }) : null
|
|
1499
|
-
]
|
|
1500
|
-
},
|
|
1501
|
-
marker.id
|
|
1502
|
-
)) })
|
|
1503
|
-
]
|
|
1504
|
-
}
|
|
1505
|
-
);
|
|
1506
|
-
}
|
|
1507
|
-
return null;
|
|
1508
|
-
};
|
|
1509
|
-
return /* @__PURE__ */ jsxs(
|
|
1510
|
-
"div",
|
|
1511
|
-
{
|
|
1512
|
-
className: cn(
|
|
1513
|
-
"relative overflow-hidden rounded-2xl border border-border bg-background",
|
|
1514
|
-
className
|
|
1515
|
-
),
|
|
1516
|
-
children: [
|
|
1517
|
-
/* @__PURE__ */ jsx("div", { className: cn("h-[520px] w-full", mapWrapperClassName), children: /* @__PURE__ */ jsx(
|
|
1518
|
-
MapLibre,
|
|
1519
|
-
{
|
|
1520
|
-
stadiaApiKey,
|
|
1521
|
-
mapStyle,
|
|
1522
|
-
styleUrl,
|
|
1523
|
-
mapLibreCssHref,
|
|
1524
|
-
viewState: resolvedViewState,
|
|
1525
|
-
onViewStateChange: applyViewState,
|
|
1526
|
-
markers: mapMarkers,
|
|
1527
|
-
onClick: (coord) => {
|
|
1528
|
-
onMapClick?.(coord);
|
|
1529
|
-
if (clearSelectionOnMapClick) {
|
|
1530
|
-
clearSelection();
|
|
1531
|
-
}
|
|
1532
|
-
},
|
|
1533
|
-
onMarkerDrag,
|
|
1534
|
-
showNavigationControl,
|
|
1535
|
-
showGeolocateControl,
|
|
1536
|
-
navigationControlPosition,
|
|
1537
|
-
geolocateControlPosition,
|
|
1538
|
-
flyToOptions,
|
|
1539
|
-
className: cn("h-full w-full", mapClassName),
|
|
1540
|
-
children: mapChildren
|
|
1541
|
-
}
|
|
1542
|
-
) }),
|
|
1543
|
-
selection.type !== "none" ? /* @__PURE__ */ jsx(
|
|
1544
|
-
"div",
|
|
1545
|
-
{
|
|
1546
|
-
className: cn(
|
|
1547
|
-
"pointer-events-none absolute z-20",
|
|
1548
|
-
PANEL_POSITION_CLASS[panelPosition]
|
|
1549
|
-
),
|
|
1550
|
-
children: /* @__PURE__ */ jsx("div", { className: "pointer-events-auto", children: renderMarkerPanel() })
|
|
1551
|
-
}
|
|
1552
|
-
) : null
|
|
1553
|
-
]
|
|
1554
|
-
}
|
|
1555
|
-
);
|
|
1556
|
-
}
|
|
1557
|
-
var sizeStyles = {
|
|
1558
|
-
sm: "max-w-md",
|
|
1559
|
-
md: "max-w-2xl",
|
|
1560
|
-
lg: "max-w-4xl",
|
|
1561
|
-
xl: "max-w-5xl",
|
|
1562
|
-
full: "max-w-7xl",
|
|
1563
|
-
compact: "max-w-[700px]"
|
|
1564
|
-
};
|
|
1565
|
-
var dialogTransition = {
|
|
1566
|
-
duration: 0.35,
|
|
1567
|
-
ease: [0.16, 1, 0.3, 1]
|
|
1568
|
-
};
|
|
1569
|
-
function AnimatedDialog({
|
|
1570
|
-
open,
|
|
1571
|
-
onOpenChange,
|
|
1572
|
-
title,
|
|
1573
|
-
eyebrow,
|
|
1574
|
-
description,
|
|
1575
|
-
children,
|
|
1576
|
-
header,
|
|
1577
|
-
footer,
|
|
1578
|
-
size = "lg",
|
|
1579
|
-
className,
|
|
1580
|
-
contentClassName,
|
|
1581
|
-
featuredMediaHeader
|
|
1582
|
-
}) {
|
|
1583
|
-
const titleId = useId();
|
|
1584
|
-
const descriptionId = useId();
|
|
1585
|
-
const containerRef = useRef(null);
|
|
1586
|
-
useOnClickOutside(containerRef, () => {
|
|
1587
|
-
if (open) {
|
|
1588
|
-
onOpenChange(false);
|
|
1589
|
-
}
|
|
1590
|
-
});
|
|
1591
|
-
useEffect(() => {
|
|
1592
|
-
if (!open) {
|
|
1593
|
-
return;
|
|
1594
|
-
}
|
|
1595
|
-
const onKeyDown = (event) => {
|
|
1596
|
-
if (event.key === "Escape") {
|
|
1597
|
-
onOpenChange(false);
|
|
1598
|
-
}
|
|
1599
|
-
};
|
|
1600
|
-
const previousOverflow = document.body.style.overflow;
|
|
1601
|
-
document.body.style.overflow = "hidden";
|
|
1602
|
-
window.addEventListener("keydown", onKeyDown);
|
|
1603
|
-
return () => {
|
|
1604
|
-
document.body.style.overflow = previousOverflow;
|
|
1605
|
-
window.removeEventListener("keydown", onKeyDown);
|
|
1606
|
-
};
|
|
1607
|
-
}, [open, onOpenChange]);
|
|
1608
|
-
return /* @__PURE__ */ jsx(AnimatePresence, { children: open ? /* @__PURE__ */ jsxs("div", { className: "fixed inset-0 z-50 h-screen overflow-y-auto", children: [
|
|
1609
|
-
/* @__PURE__ */ jsx(
|
|
1610
|
-
motion.div,
|
|
1611
|
-
{
|
|
1612
|
-
initial: { opacity: 0 },
|
|
1613
|
-
animate: { opacity: 1, transition: dialogTransition },
|
|
1614
|
-
exit: { opacity: 0, transition: dialogTransition },
|
|
1615
|
-
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"
|
|
1616
549
|
}
|
|
1617
550
|
),
|
|
1618
551
|
/* @__PURE__ */ jsxs(
|
|
@@ -1911,10 +844,10 @@ var ImageSlider = ({
|
|
|
1911
844
|
optixFlowConfig
|
|
1912
845
|
}) => {
|
|
1913
846
|
const hasImages = images.length > 0;
|
|
1914
|
-
const [currentIndex, setCurrentIndex] =
|
|
847
|
+
const [currentIndex, setCurrentIndex] = React4.useState(
|
|
1915
848
|
() => normalizeIndex(startIndex, images.length)
|
|
1916
849
|
);
|
|
1917
|
-
const handleNext =
|
|
850
|
+
const handleNext = React4.useCallback(() => {
|
|
1918
851
|
if (!hasImages) return;
|
|
1919
852
|
setCurrentIndex((prevIndex) => {
|
|
1920
853
|
const nextIndex = prevIndex + 1 >= images.length ? 0 : prevIndex + 1;
|
|
@@ -1922,7 +855,7 @@ var ImageSlider = ({
|
|
|
1922
855
|
return nextIndex;
|
|
1923
856
|
});
|
|
1924
857
|
}, [hasImages, images.length, onSlideChange]);
|
|
1925
|
-
const handlePrevious =
|
|
858
|
+
const handlePrevious = React4.useCallback(() => {
|
|
1926
859
|
if (!hasImages) return;
|
|
1927
860
|
setCurrentIndex((prevIndex) => {
|
|
1928
861
|
const nextIndex = prevIndex - 1 < 0 ? images.length - 1 : prevIndex - 1;
|
|
@@ -1930,11 +863,11 @@ var ImageSlider = ({
|
|
|
1930
863
|
return nextIndex;
|
|
1931
864
|
});
|
|
1932
865
|
}, [hasImages, images.length, onSlideChange]);
|
|
1933
|
-
|
|
866
|
+
React4.useEffect(() => {
|
|
1934
867
|
if (!hasImages) return;
|
|
1935
868
|
setCurrentIndex(normalizeIndex(startIndex, images.length));
|
|
1936
869
|
}, [startIndex, images.length, hasImages]);
|
|
1937
|
-
|
|
870
|
+
React4.useEffect(() => {
|
|
1938
871
|
if (!enableKeyboard || !hasImages) return;
|
|
1939
872
|
const handleKeyDown = (event) => {
|
|
1940
873
|
if (event.key === "ArrowRight") {
|
|
@@ -1948,7 +881,7 @@ var ImageSlider = ({
|
|
|
1948
881
|
window.removeEventListener("keydown", handleKeyDown);
|
|
1949
882
|
};
|
|
1950
883
|
}, [enableKeyboard, handleNext, handlePrevious, hasImages]);
|
|
1951
|
-
|
|
884
|
+
React4.useEffect(() => {
|
|
1952
885
|
if (!autoplay || images.length < 2) return;
|
|
1953
886
|
const interval = window.setInterval(handleNext, autoplayIntervalMs);
|
|
1954
887
|
return () => window.clearInterval(interval);
|
|
@@ -2019,8 +952,150 @@ var ImageSlider = ({
|
|
|
2019
952
|
) : null
|
|
2020
953
|
]
|
|
2021
954
|
}
|
|
2022
|
-
);
|
|
2023
|
-
};
|
|
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
|
+
});
|
|
2024
1099
|
function Button({
|
|
2025
1100
|
className,
|
|
2026
1101
|
variant = "default",
|
|
@@ -2064,127 +1139,412 @@ function CardHeader({ className, ...props }) {
|
|
|
2064
1139
|
),
|
|
2065
1140
|
...props
|
|
2066
1141
|
}
|
|
2067
|
-
);
|
|
2068
|
-
}
|
|
2069
|
-
function CardTitle({ className, ...props }) {
|
|
2070
|
-
return /* @__PURE__ */ jsx(
|
|
2071
|
-
"div",
|
|
2072
|
-
{
|
|
2073
|
-
"data-slot": "card-title",
|
|
2074
|
-
className: cn("leading-none font-semibold", className),
|
|
2075
|
-
...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";
|
|
2076
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]
|
|
2077
1437
|
);
|
|
1438
|
+
return {
|
|
1439
|
+
linkType,
|
|
1440
|
+
normalizedHref,
|
|
1441
|
+
target,
|
|
1442
|
+
rel,
|
|
1443
|
+
isExternal,
|
|
1444
|
+
isInternal,
|
|
1445
|
+
shouldUseRouter,
|
|
1446
|
+
handleClick
|
|
1447
|
+
};
|
|
2078
1448
|
}
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
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
|
+
);
|
|
2086
1514
|
}
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
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
|
+
);
|
|
2096
1526
|
}
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
1527
|
+
if (finalComponentType === "div") {
|
|
1528
|
+
return /* @__PURE__ */ jsx(
|
|
1529
|
+
"div",
|
|
1530
|
+
{
|
|
1531
|
+
ref,
|
|
1532
|
+
...commonProps,
|
|
1533
|
+
children
|
|
1534
|
+
}
|
|
1535
|
+
);
|
|
2106
1536
|
}
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
variant: {
|
|
2114
|
-
default: "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
|
|
2115
|
-
secondary: "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
|
|
2116
|
-
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",
|
|
2117
|
-
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
|
|
2118
1543
|
}
|
|
2119
|
-
|
|
2120
|
-
defaultVariants: {
|
|
2121
|
-
variant: "default"
|
|
2122
|
-
}
|
|
1544
|
+
);
|
|
2123
1545
|
}
|
|
2124
1546
|
);
|
|
2125
|
-
|
|
2126
|
-
className,
|
|
2127
|
-
variant,
|
|
2128
|
-
asChild = false,
|
|
2129
|
-
...props
|
|
2130
|
-
}) {
|
|
2131
|
-
const Comp = asChild ? Slot : "span";
|
|
2132
|
-
return /* @__PURE__ */ jsx(
|
|
2133
|
-
Comp,
|
|
2134
|
-
{
|
|
2135
|
-
"data-slot": "badge",
|
|
2136
|
-
className: cn(badgeVariants({ variant }), className),
|
|
2137
|
-
...props
|
|
2138
|
-
}
|
|
2139
|
-
);
|
|
2140
|
-
}
|
|
2141
|
-
function Popover({
|
|
2142
|
-
...props
|
|
2143
|
-
}) {
|
|
2144
|
-
return /* @__PURE__ */ jsx(PopoverPrimitive.Root, { "data-slot": "popover", ...props });
|
|
2145
|
-
}
|
|
2146
|
-
function PopoverTrigger({
|
|
2147
|
-
...props
|
|
2148
|
-
}) {
|
|
2149
|
-
return /* @__PURE__ */ jsx(PopoverPrimitive.Trigger, { "data-slot": "popover-trigger", ...props });
|
|
2150
|
-
}
|
|
2151
|
-
function PopoverContent({
|
|
2152
|
-
className,
|
|
2153
|
-
align = "center",
|
|
2154
|
-
sideOffset = 4,
|
|
2155
|
-
...props
|
|
2156
|
-
}) {
|
|
2157
|
-
return /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
|
|
2158
|
-
PopoverPrimitive.Content,
|
|
2159
|
-
{
|
|
2160
|
-
"data-slot": "popover-content",
|
|
2161
|
-
align,
|
|
2162
|
-
sideOffset,
|
|
2163
|
-
className: cn(
|
|
2164
|
-
"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",
|
|
2165
|
-
className
|
|
2166
|
-
),
|
|
2167
|
-
...props
|
|
2168
|
-
}
|
|
2169
|
-
) });
|
|
2170
|
-
}
|
|
2171
|
-
function StarRating({
|
|
2172
|
-
rating,
|
|
2173
|
-
size = 18,
|
|
2174
|
-
className
|
|
2175
|
-
}) {
|
|
2176
|
-
return /* @__PURE__ */ jsx("div", { className: cn("flex items-center gap-0.5", className), children: [1, 2, 3, 4, 5].map((star) => /* @__PURE__ */ jsx(
|
|
2177
|
-
DynamicIcon,
|
|
2178
|
-
{
|
|
2179
|
-
name: "icon-park-solid/star",
|
|
2180
|
-
size,
|
|
2181
|
-
className: cn(
|
|
2182
|
-
star <= rating ? "fill-primary text-primary" : "fill-muted text-muted"
|
|
2183
|
-
)
|
|
2184
|
-
},
|
|
2185
|
-
star
|
|
2186
|
-
)) });
|
|
2187
|
-
}
|
|
1547
|
+
Pressable.displayName = "Pressable";
|
|
2188
1548
|
var BUTTON_SIZES = {
|
|
2189
1549
|
sm: { buttonSize: "size-8", iconSize: 16 },
|
|
2190
1550
|
md: { buttonSize: "size-10", iconSize: 20 },
|
|
@@ -2276,7 +1636,7 @@ var platformIconMap = {
|
|
|
2276
1636
|
dribbble: "cib/dribbble",
|
|
2277
1637
|
unknown: "icon-park-solid/circular-connection"
|
|
2278
1638
|
};
|
|
2279
|
-
var SocialLinkIcon =
|
|
1639
|
+
var SocialLinkIcon = React4.forwardRef(
|
|
2280
1640
|
({
|
|
2281
1641
|
platformName,
|
|
2282
1642
|
label,
|
|
@@ -2290,16 +1650,16 @@ var SocialLinkIcon = React6.forwardRef(
|
|
|
2290
1650
|
...pressableProps
|
|
2291
1651
|
}, ref) => {
|
|
2292
1652
|
const platform = usePlatformFromUrl(href);
|
|
2293
|
-
const smartPlatformName =
|
|
1653
|
+
const smartPlatformName = React4.useMemo(() => {
|
|
2294
1654
|
return platform || platformName;
|
|
2295
1655
|
}, [platform, platformName]);
|
|
2296
|
-
const iconName =
|
|
1656
|
+
const iconName = React4.useMemo(() => {
|
|
2297
1657
|
return iconNameOverride || platformIconMap[smartPlatformName];
|
|
2298
1658
|
}, [iconNameOverride, smartPlatformName]);
|
|
2299
|
-
const accessibleLabel =
|
|
1659
|
+
const accessibleLabel = React4.useMemo(() => {
|
|
2300
1660
|
return label || platformName;
|
|
2301
1661
|
}, [label, platformName]);
|
|
2302
|
-
const icon =
|
|
1662
|
+
const icon = React4.useMemo(() => {
|
|
2303
1663
|
return /* @__PURE__ */ jsx(
|
|
2304
1664
|
DynamicIcon,
|
|
2305
1665
|
{
|
|
@@ -2379,12 +1739,12 @@ function TextInner({ as, className, children, ...props }, ref) {
|
|
|
2379
1739
|
const Component = as || "span";
|
|
2380
1740
|
return /* @__PURE__ */ jsx(Component, { ref, className: cn(className), ...props, children });
|
|
2381
1741
|
}
|
|
2382
|
-
var Text =
|
|
1742
|
+
var Text = React4.forwardRef(TextInner);
|
|
2383
1743
|
Text.displayName = "Text";
|
|
2384
1744
|
function isContentTextItem(item) {
|
|
2385
|
-
return item !== null && typeof item === "object" && !
|
|
1745
|
+
return item !== null && typeof item === "object" && !React4.isValidElement(item) && "_type" in item && item._type === "text";
|
|
2386
1746
|
}
|
|
2387
|
-
var ContentGroup =
|
|
1747
|
+
var ContentGroup = React4.forwardRef(
|
|
2388
1748
|
({ items, className, children, ...props }, ref) => {
|
|
2389
1749
|
const hasContent = items && items.length > 0;
|
|
2390
1750
|
if (!hasContent) {
|
|
@@ -2397,10 +1757,10 @@ var ContentGroup = React6.forwardRef(
|
|
|
2397
1757
|
return /* @__PURE__ */ jsx(Text, { ...textProps }, idx);
|
|
2398
1758
|
}
|
|
2399
1759
|
const reactNode = item;
|
|
2400
|
-
if (
|
|
2401
|
-
return
|
|
1760
|
+
if (React4.isValidElement(reactNode)) {
|
|
1761
|
+
return React4.cloneElement(reactNode, { key: reactNode.key ?? idx });
|
|
2402
1762
|
}
|
|
2403
|
-
return /* @__PURE__ */ jsx(
|
|
1763
|
+
return /* @__PURE__ */ jsx(React4.Fragment, { children: reactNode }, idx);
|
|
2404
1764
|
}),
|
|
2405
1765
|
children
|
|
2406
1766
|
] });
|
|
@@ -2925,7 +2285,7 @@ function AboutExpandableValues({
|
|
|
2925
2285
|
pattern,
|
|
2926
2286
|
patternOpacity
|
|
2927
2287
|
}) {
|
|
2928
|
-
const [expandedValue, setExpandedValue] =
|
|
2288
|
+
const [expandedValue, setExpandedValue] = React4.useState(null);
|
|
2929
2289
|
const toggleExpand = useCallback((id) => {
|
|
2930
2290
|
setExpandedValue((prev) => prev === id ? null : id);
|
|
2931
2291
|
}, []);
|
|
@@ -3161,7 +2521,7 @@ function CommunityInitiatives({
|
|
|
3161
2521
|
pattern,
|
|
3162
2522
|
patternOpacity
|
|
3163
2523
|
}) {
|
|
3164
|
-
const [activeCategory, setActiveCategory] =
|
|
2524
|
+
const [activeCategory, setActiveCategory] = React4.useState(
|
|
3165
2525
|
categories?.[0]?.id || ""
|
|
3166
2526
|
);
|
|
3167
2527
|
const currentCategory = categories?.find((category) => category.id === activeCategory) || categories?.[0];
|
|
@@ -3425,7 +2785,7 @@ function AboutCultureTabs({
|
|
|
3425
2785
|
patternOpacity
|
|
3426
2786
|
}) {
|
|
3427
2787
|
const resolvedAspects = aspects ?? [];
|
|
3428
|
-
const [activeTab, setActiveTab] =
|
|
2788
|
+
const [activeTab, setActiveTab] = React4.useState(
|
|
3429
2789
|
resolvedAspects[0]?.id || ""
|
|
3430
2790
|
);
|
|
3431
2791
|
const headerItems = useMemo(() => {
|
|
@@ -3958,7 +3318,7 @@ function BannerDeliveryCountdown({
|
|
|
3958
3318
|
}, [prefixText, timerContent, middleText, deliveryDateContent]);
|
|
3959
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: [
|
|
3960
3320
|
iconContent,
|
|
3961
|
-
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: [
|
|
3962
3322
|
index > 0 ? " " : null,
|
|
3963
3323
|
part
|
|
3964
3324
|
] }, index)) })
|
|
@@ -5229,8 +4589,8 @@ var BrandAttribution = ({
|
|
|
5229
4589
|
}
|
|
5230
4590
|
const { prefix = "", anchorText, href, suffix = "" } = options[optionIndex];
|
|
5231
4591
|
const ContainerEl = variant;
|
|
5232
|
-
const [trackedHref, setTrackedHref] =
|
|
5233
|
-
|
|
4592
|
+
const [trackedHref, setTrackedHref] = React4.useState(href);
|
|
4593
|
+
React4.useEffect(() => {
|
|
5234
4594
|
setTrackedHref(buildTrackedHref(href));
|
|
5235
4595
|
}, [href]);
|
|
5236
4596
|
return /* @__PURE__ */ jsxs(ContainerEl, { className: containerClassName, children: [
|
|
@@ -5350,7 +4710,7 @@ function FooterSocialNewsletter({
|
|
|
5350
4710
|
patternOpacity,
|
|
5351
4711
|
optixFlowConfig
|
|
5352
4712
|
}) {
|
|
5353
|
-
const renderForm =
|
|
4713
|
+
const renderForm = React4.useMemo(() => {
|
|
5354
4714
|
if (!formEngineSetup) return null;
|
|
5355
4715
|
const action = {
|
|
5356
4716
|
variant: "default",
|
|
@@ -5639,7 +4999,7 @@ function FooterSimpleCentered({
|
|
|
5639
4999
|
]);
|
|
5640
5000
|
const bottomLinksContent = useMemo(() => {
|
|
5641
5001
|
if (!bottomLinks || bottomLinks.length === 0) return null;
|
|
5642
|
-
return bottomLinks.map((link, idx) => /* @__PURE__ */ jsx(
|
|
5002
|
+
return bottomLinks.map((link, idx) => /* @__PURE__ */ jsx(React4.Fragment, { children: /* @__PURE__ */ jsx(
|
|
5643
5003
|
Pressable,
|
|
5644
5004
|
{
|
|
5645
5005
|
href: link.href,
|
|
@@ -6986,7 +6346,7 @@ function FooterNewsletterMinimal({
|
|
|
6986
6346
|
buttonAction,
|
|
6987
6347
|
formSlot
|
|
6988
6348
|
}) {
|
|
6989
|
-
const navLinksContent =
|
|
6349
|
+
const navLinksContent = React4.useMemo(() => {
|
|
6990
6350
|
if (!navLinks || navLinks.length === 0) return null;
|
|
6991
6351
|
return navLinks.map((item, idx) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
|
|
6992
6352
|
Pressable,
|
|
@@ -6997,7 +6357,7 @@ function FooterNewsletterMinimal({
|
|
|
6997
6357
|
}
|
|
6998
6358
|
) }, idx));
|
|
6999
6359
|
}, [navLinks, navLinkClassName]);
|
|
7000
|
-
const socialLinksContent =
|
|
6360
|
+
const socialLinksContent = React4.useMemo(() => {
|
|
7001
6361
|
if (!socialLinks || socialLinks.length === 0) return null;
|
|
7002
6362
|
return socialLinks.map((item, idx) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
|
|
7003
6363
|
SocialLinkIcon,
|
|
@@ -7013,7 +6373,7 @@ function FooterNewsletterMinimal({
|
|
|
7013
6373
|
}
|
|
7014
6374
|
) }, idx));
|
|
7015
6375
|
}, [socialLinks, socialLinkClassName]);
|
|
7016
|
-
const footerLinksContent =
|
|
6376
|
+
const footerLinksContent = React4.useMemo(() => {
|
|
7017
6377
|
if (!footerLinks || footerLinks.length === 0) return null;
|
|
7018
6378
|
return footerLinks.map((item) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
|
|
7019
6379
|
Pressable,
|
|
@@ -7027,7 +6387,7 @@ function FooterNewsletterMinimal({
|
|
|
7027
6387
|
}
|
|
7028
6388
|
) }, item.label));
|
|
7029
6389
|
}, [footerLinks, footerLinkClassName]);
|
|
7030
|
-
const renderForm =
|
|
6390
|
+
const renderForm = React4.useMemo(() => {
|
|
7031
6391
|
if (formSlot) return formSlot;
|
|
7032
6392
|
if (!formEngineSetup) return null;
|
|
7033
6393
|
const defaultButtonAction = {
|
|
@@ -7584,4 +6944,4 @@ var useResponsiveLayout = ({
|
|
|
7584
6944
|
return { responsiveClassName };
|
|
7585
6945
|
};
|
|
7586
6946
|
|
|
7587
|
-
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 };
|