@opensite/ui 2.8.8 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/about-culture-tabs.cjs +174 -174
- package/dist/about-culture-tabs.js +174 -174
- package/dist/about-developer-profile.cjs +200 -200
- package/dist/about-developer-profile.js +198 -198
- package/dist/about-developer-story.cjs +142 -142
- package/dist/about-developer-story.js +142 -142
- package/dist/about-mission-dual-image.cjs +142 -142
- package/dist/about-mission-dual-image.js +142 -142
- package/dist/about-mission-features.cjs +142 -142
- package/dist/about-mission-features.js +142 -142
- package/dist/about-network-spotlight.cjs +142 -142
- package/dist/about-network-spotlight.js +142 -142
- package/dist/about-story-expertise.cjs +142 -142
- package/dist/about-story-expertise.js +142 -142
- package/dist/about-streamline-team.cjs +142 -142
- package/dist/about-streamline-team.js +142 -142
- package/dist/carousel-feature-badge.cjs +162 -42
- package/dist/carousel-feature-badge.d.cts +14 -1
- package/dist/carousel-feature-badge.d.ts +14 -1
- package/dist/carousel-feature-badge.js +163 -43
- package/dist/community-initiatives.cjs +142 -142
- package/dist/community-initiatives.js +142 -142
- package/dist/components.cjs +723 -1378
- package/dist/components.d.cts +0 -2
- package/dist/components.d.ts +0 -2
- package/dist/components.js +633 -1287
- package/dist/contact-map.cjs +14 -1083
- package/dist/contact-map.d.cts +13 -3
- package/dist/contact-map.d.ts +13 -3
- package/dist/contact-map.js +14 -1083
- package/dist/cta-feature-checklist.cjs +142 -142
- package/dist/cta-feature-checklist.js +142 -142
- package/dist/faq-numbered-grid.cjs +142 -142
- package/dist/faq-numbered-grid.js +142 -142
- package/dist/feature-animated-carousel.cjs +142 -142
- package/dist/feature-animated-carousel.js +142 -142
- package/dist/feature-bento-utilities.cjs +142 -142
- package/dist/feature-bento-utilities.js +142 -142
- package/dist/feature-capabilities-grid.cjs +142 -142
- package/dist/feature-capabilities-grid.js +142 -142
- package/dist/feature-category-image-cards.cjs +142 -142
- package/dist/feature-category-image-cards.js +142 -142
- package/dist/feature-icon-grid-bordered.cjs +142 -142
- package/dist/feature-icon-grid-bordered.js +142 -142
- package/dist/feature-icon-grid-muted.cjs +142 -142
- package/dist/feature-icon-grid-muted.js +142 -142
- package/dist/feature-numbered-cards.cjs +142 -142
- package/dist/feature-numbered-cards.js +142 -142
- package/dist/feature-three-column-values.cjs +142 -142
- package/dist/feature-three-column-values.js +142 -142
- package/dist/hero-ad-campaign-expert.cjs +142 -142
- package/dist/hero-ad-campaign-expert.js +142 -142
- package/dist/hero-adaptable-product-grid.cjs +142 -142
- package/dist/hero-adaptable-product-grid.js +142 -142
- package/dist/hero-agency-animated-images.cjs +142 -142
- package/dist/hero-agency-animated-images.js +142 -142
- package/dist/hero-announcement-badge.cjs +142 -142
- package/dist/hero-announcement-badge.js +142 -142
- package/dist/hero-badge-image-split.cjs +142 -142
- package/dist/hero-badge-image-split.js +142 -142
- package/dist/hero-business-carousel-dots.cjs +142 -142
- package/dist/hero-business-carousel-dots.js +142 -142
- package/dist/hero-business-operations-mosaic.cjs +142 -142
- package/dist/hero-business-operations-mosaic.js +142 -142
- package/dist/hero-conversation-intelligence.cjs +142 -142
- package/dist/hero-conversation-intelligence.js +142 -142
- package/dist/hero-creative-studio-stacked.cjs +142 -142
- package/dist/hero-creative-studio-stacked.js +142 -142
- package/dist/hero-crm-streamlined.cjs +142 -142
- package/dist/hero-crm-streamlined.js +142 -142
- package/dist/hero-customer-support-layered.cjs +142 -142
- package/dist/hero-customer-support-layered.js +142 -142
- package/dist/hero-design-showcase-logos.cjs +142 -142
- package/dist/hero-design-showcase-logos.js +142 -142
- package/dist/hero-design-system-3d.cjs +142 -142
- package/dist/hero-design-system-3d.js +142 -142
- package/dist/hero-developer-tools-code.cjs +142 -142
- package/dist/hero-developer-tools-code.js +142 -142
- package/dist/hero-digital-agency-fullscreen.cjs +142 -142
- package/dist/hero-digital-agency-fullscreen.js +142 -142
- package/dist/hero-ecommerce-product-showcase.cjs +174 -174
- package/dist/hero-ecommerce-product-showcase.js +174 -174
- package/dist/hero-event-registration.cjs +142 -142
- package/dist/hero-event-registration.js +142 -142
- package/dist/hero-fullscreen-background-image.cjs +142 -142
- package/dist/hero-fullscreen-background-image.js +142 -142
- package/dist/hero-gradient-avatars-rating.cjs +142 -142
- package/dist/hero-gradient-avatars-rating.js +142 -142
- package/dist/hero-gradient-client-focused.cjs +142 -142
- package/dist/hero-gradient-client-focused.js +142 -142
- package/dist/hero-hiring-animated-text.cjs +142 -142
- package/dist/hero-hiring-animated-text.js +142 -142
- package/dist/hero-image-left-content.cjs +142 -142
- package/dist/hero-image-left-content.js +142 -142
- package/dist/hero-innovation-image-grid.cjs +142 -142
- package/dist/hero-innovation-image-grid.js +142 -142
- package/dist/hero-mental-health-team.cjs +142 -142
- package/dist/hero-mental-health-team.js +142 -142
- package/dist/hero-minimal-centered-dark.cjs +174 -174
- package/dist/hero-minimal-centered-dark.js +174 -174
- package/dist/hero-presentation-platform-video.cjs +142 -142
- package/dist/hero-presentation-platform-video.js +142 -142
- package/dist/hero-product-showcase-floating.cjs +174 -174
- package/dist/hero-product-showcase-floating.js +174 -174
- package/dist/hero-shared-inbox-layered.cjs +142 -142
- package/dist/hero-shared-inbox-layered.js +142 -142
- package/dist/hero-software-growth-video-dialog.cjs +142 -142
- package/dist/hero-software-growth-video-dialog.js +142 -142
- package/dist/hero-spiral-pattern-cards.cjs +174 -174
- package/dist/hero-spiral-pattern-cards.js +174 -174
- package/dist/hero-split-geometric-shapes.cjs +142 -142
- package/dist/hero-split-geometric-shapes.js +142 -142
- package/dist/hero-startup-launch-cta.cjs +174 -174
- package/dist/hero-startup-launch-cta.js +174 -174
- package/dist/hero-stats-social-proof.cjs +174 -174
- package/dist/hero-stats-social-proof.js +174 -174
- package/dist/hero-task-timer-animated.cjs +142 -142
- package/dist/hero-task-timer-animated.js +142 -142
- package/dist/hero-testimonial-image-grid.cjs +142 -142
- package/dist/hero-testimonial-image-grid.js +142 -142
- package/dist/hero-therapy-testimonial-grid.cjs +142 -142
- package/dist/hero-therapy-testimonial-grid.js +142 -142
- package/dist/hero-ui-library-showcase.cjs +142 -142
- package/dist/hero-ui-library-showcase.js +142 -142
- package/dist/hero-video-background-dark.cjs +174 -174
- package/dist/hero-video-background-dark.js +174 -174
- package/dist/hero-video-dialog-gradient.cjs +142 -142
- package/dist/hero-video-dialog-gradient.js +142 -142
- package/dist/hero-video-overlay-stars.cjs +142 -142
- package/dist/hero-video-overlay-stars.js +142 -142
- package/dist/hero-welcome-asymmetric-images.cjs +142 -142
- package/dist/hero-welcome-asymmetric-images.js +142 -142
- package/dist/index.cjs +725 -1380
- package/dist/index.d.cts +0 -2
- package/dist/index.d.ts +0 -2
- package/dist/index.js +634 -1288
- package/dist/registry.cjs +2201 -2827
- package/dist/registry.js +948 -1574
- package/dist/testimonials-masonry-grid.cjs +142 -142
- package/dist/testimonials-masonry-grid.js +142 -142
- package/dist/testimonials-stats-header.cjs +159 -159
- package/dist/testimonials-stats-header.js +159 -159
- package/package.json +4 -7
- package/dist/geo-map.cjs +0 -1117
- package/dist/geo-map.d.cts +0 -92
- package/dist/geo-map.d.ts +0 -92
- package/dist/geo-map.js +0 -1095
package/dist/components.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';
|
|
@@ -60,7 +59,7 @@ var maxWidthStyles = {
|
|
|
60
59
|
"4xl": "max-w-[1536px]",
|
|
61
60
|
full: "max-w-full"
|
|
62
61
|
};
|
|
63
|
-
var Container =
|
|
62
|
+
var Container = React4__default.forwardRef(
|
|
64
63
|
({ children, maxWidth = "xl", className, as = "div", ...props }, ref) => {
|
|
65
64
|
const Component = as;
|
|
66
65
|
return /* @__PURE__ */ jsx(
|
|
@@ -366,7 +365,7 @@ var spacingStyles = {
|
|
|
366
365
|
};
|
|
367
366
|
var predefinedSpacings = ["none", "sm", "md", "lg", "xl", "hero"];
|
|
368
367
|
var isPredefinedSpacing = (spacing) => predefinedSpacings.includes(spacing);
|
|
369
|
-
var Section =
|
|
368
|
+
var Section = React4__default.forwardRef(
|
|
370
369
|
({
|
|
371
370
|
id,
|
|
372
371
|
title,
|
|
@@ -427,1144 +426,65 @@ var Section = React6__default.forwardRef(
|
|
|
427
426
|
}
|
|
428
427
|
);
|
|
429
428
|
Section.displayName = "Section";
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
const
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
const phoneRegex = /^[\s\+\-\(\)]*\d[\d\s\-\(\)\.]*\d[\s\-]*(x|ext\.?|extension)?[\s\-]*\d*$/i;
|
|
463
|
-
return phoneRegex.test(trimmed);
|
|
464
|
-
}
|
|
465
|
-
function isInternalUrl(href) {
|
|
466
|
-
if (typeof window === "undefined") {
|
|
467
|
-
return href.startsWith("/") && !href.startsWith("//");
|
|
468
|
-
}
|
|
469
|
-
const trimmed = href.trim();
|
|
470
|
-
if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
|
|
471
|
-
return true;
|
|
472
|
-
}
|
|
473
|
-
try {
|
|
474
|
-
const url = new URL(trimmed, window.location.href);
|
|
475
|
-
const currentOrigin = window.location.origin;
|
|
476
|
-
const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
|
|
477
|
-
return normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin);
|
|
478
|
-
} catch {
|
|
479
|
-
return false;
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
function toRelativePath(href) {
|
|
483
|
-
if (typeof window === "undefined") {
|
|
484
|
-
return href;
|
|
485
|
-
}
|
|
486
|
-
const trimmed = href.trim();
|
|
487
|
-
if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
|
|
488
|
-
return trimmed;
|
|
489
|
-
}
|
|
490
|
-
try {
|
|
491
|
-
const url = new URL(trimmed, window.location.href);
|
|
492
|
-
const currentOrigin = window.location.origin;
|
|
493
|
-
const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
|
|
494
|
-
if (normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin)) {
|
|
495
|
-
return url.pathname + url.search + url.hash;
|
|
496
|
-
}
|
|
497
|
-
} catch {
|
|
498
|
-
}
|
|
499
|
-
return trimmed;
|
|
500
|
-
}
|
|
501
|
-
function useNavigation({
|
|
502
|
-
href,
|
|
503
|
-
onClick
|
|
504
|
-
} = {}) {
|
|
505
|
-
const linkType = React6.useMemo(() => {
|
|
506
|
-
if (!href || href.trim() === "") {
|
|
507
|
-
return onClick ? "none" : "none";
|
|
508
|
-
}
|
|
509
|
-
const trimmed = href.trim();
|
|
510
|
-
if (trimmed.toLowerCase().startsWith("mailto:") || isEmail(trimmed)) {
|
|
511
|
-
return "mailto";
|
|
512
|
-
}
|
|
513
|
-
if (trimmed.toLowerCase().startsWith("tel:") || isPhoneNumber(trimmed)) {
|
|
514
|
-
return "tel";
|
|
515
|
-
}
|
|
516
|
-
if (isInternalUrl(trimmed)) {
|
|
517
|
-
return "internal";
|
|
518
|
-
}
|
|
519
|
-
try {
|
|
520
|
-
new URL(trimmed, typeof window !== "undefined" ? window.location.href : "http://localhost");
|
|
521
|
-
return "external";
|
|
522
|
-
} catch {
|
|
523
|
-
return "internal";
|
|
524
|
-
}
|
|
525
|
-
}, [href, onClick]);
|
|
526
|
-
const normalizedHref = React6.useMemo(() => {
|
|
527
|
-
if (!href || href.trim() === "") {
|
|
528
|
-
return void 0;
|
|
529
|
-
}
|
|
530
|
-
const trimmed = href.trim();
|
|
531
|
-
switch (linkType) {
|
|
532
|
-
case "tel":
|
|
533
|
-
return normalizePhoneNumber(trimmed);
|
|
534
|
-
case "mailto":
|
|
535
|
-
return normalizeEmail(trimmed);
|
|
536
|
-
case "internal":
|
|
537
|
-
return toRelativePath(trimmed);
|
|
538
|
-
case "external":
|
|
539
|
-
return trimmed;
|
|
540
|
-
default:
|
|
541
|
-
return trimmed;
|
|
542
|
-
}
|
|
543
|
-
}, [href, linkType]);
|
|
544
|
-
const target = React6.useMemo(() => {
|
|
545
|
-
switch (linkType) {
|
|
546
|
-
case "external":
|
|
547
|
-
return "_blank";
|
|
548
|
-
case "internal":
|
|
549
|
-
return "_self";
|
|
550
|
-
case "mailto":
|
|
551
|
-
case "tel":
|
|
552
|
-
return void 0;
|
|
553
|
-
default:
|
|
554
|
-
return void 0;
|
|
429
|
+
var sizeStyles = {
|
|
430
|
+
sm: "max-w-md",
|
|
431
|
+
md: "max-w-2xl",
|
|
432
|
+
lg: "max-w-4xl",
|
|
433
|
+
xl: "max-w-5xl",
|
|
434
|
+
full: "max-w-7xl",
|
|
435
|
+
compact: "max-w-[700px]"
|
|
436
|
+
};
|
|
437
|
+
var dialogTransition = {
|
|
438
|
+
duration: 0.35,
|
|
439
|
+
ease: [0.16, 1, 0.3, 1]
|
|
440
|
+
};
|
|
441
|
+
function AnimatedDialog({
|
|
442
|
+
open,
|
|
443
|
+
onOpenChange,
|
|
444
|
+
title,
|
|
445
|
+
eyebrow,
|
|
446
|
+
description,
|
|
447
|
+
children,
|
|
448
|
+
header,
|
|
449
|
+
footer,
|
|
450
|
+
size = "lg",
|
|
451
|
+
className,
|
|
452
|
+
contentClassName,
|
|
453
|
+
featuredMediaHeader
|
|
454
|
+
}) {
|
|
455
|
+
const titleId = useId();
|
|
456
|
+
const descriptionId = useId();
|
|
457
|
+
const containerRef = useRef(null);
|
|
458
|
+
useOnClickOutside(containerRef, () => {
|
|
459
|
+
if (open) {
|
|
460
|
+
onOpenChange(false);
|
|
555
461
|
}
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
if (
|
|
559
|
-
return
|
|
462
|
+
});
|
|
463
|
+
useEffect(() => {
|
|
464
|
+
if (!open) {
|
|
465
|
+
return;
|
|
560
466
|
}
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
const isInternal = linkType === "internal";
|
|
565
|
-
const shouldUseRouter = isInternal && typeof normalizedHref === "string" && normalizedHref.startsWith("/");
|
|
566
|
-
const handleClick = React6.useCallback(
|
|
567
|
-
(event) => {
|
|
568
|
-
if (onClick) {
|
|
569
|
-
try {
|
|
570
|
-
onClick(event);
|
|
571
|
-
} catch (error) {
|
|
572
|
-
console.error("Error in user onClick handler:", error);
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
if (event.defaultPrevented) {
|
|
576
|
-
return;
|
|
467
|
+
const onKeyDown = (event) => {
|
|
468
|
+
if (event.key === "Escape") {
|
|
469
|
+
onOpenChange(false);
|
|
577
470
|
}
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
[onClick, shouldUseRouter, normalizedHref]
|
|
596
|
-
);
|
|
597
|
-
return {
|
|
598
|
-
linkType,
|
|
599
|
-
normalizedHref,
|
|
600
|
-
target,
|
|
601
|
-
rel,
|
|
602
|
-
isExternal,
|
|
603
|
-
isInternal,
|
|
604
|
-
shouldUseRouter,
|
|
605
|
-
handleClick
|
|
606
|
-
};
|
|
607
|
-
}
|
|
608
|
-
var baseStyles = [
|
|
609
|
-
// Layout
|
|
610
|
-
"inline-flex items-center justify-center gap-2 whitespace-nowrap shrink-0",
|
|
611
|
-
// Typography - using CSS variables with sensible defaults
|
|
612
|
-
"font-[var(--button-font-family,inherit)]",
|
|
613
|
-
"font-[var(--button-font-weight,500)]",
|
|
614
|
-
"tracking-[var(--button-letter-spacing,0)]",
|
|
615
|
-
"leading-[var(--button-line-height,1.25)]",
|
|
616
|
-
"[text-transform:var(--button-text-transform,none)]",
|
|
617
|
-
"text-sm",
|
|
618
|
-
// Border radius
|
|
619
|
-
"rounded-[var(--button-radius,var(--radius,0.375rem))]",
|
|
620
|
-
// Smooth transition - using [transition:...] to set full shorthand property (not just transition-property)
|
|
621
|
-
"[transition:var(--button-transition,all_250ms_cubic-bezier(0.4,0,0.2,1))]",
|
|
622
|
-
// Box shadow (master level) - using [box-shadow:...] for complex multi-value shadows
|
|
623
|
-
"[box-shadow:var(--button-shadow,none)]",
|
|
624
|
-
"hover:[box-shadow:var(--button-shadow-hover,var(--button-shadow,none))]",
|
|
625
|
-
// Disabled state
|
|
626
|
-
"disabled:pointer-events-none disabled:opacity-50",
|
|
627
|
-
// SVG handling
|
|
628
|
-
"[&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0",
|
|
629
|
-
// Focus styles
|
|
630
|
-
"outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
|
631
|
-
// Invalid state
|
|
632
|
-
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive"
|
|
633
|
-
].join(" ");
|
|
634
|
-
var buttonVariants = cva(baseStyles, {
|
|
635
|
-
variants: {
|
|
636
|
-
variant: {
|
|
637
|
-
// Default (Primary) variant - full customization
|
|
638
|
-
default: [
|
|
639
|
-
"bg-[var(--button-default-bg,hsl(var(--primary)))]",
|
|
640
|
-
"text-[var(--button-default-fg,hsl(var(--primary-foreground)))]",
|
|
641
|
-
"border-[length:var(--button-default-border-width,0px)]",
|
|
642
|
-
"border-[color:var(--button-default-border,transparent)]",
|
|
643
|
-
"[box-shadow:var(--button-default-shadow,var(--button-shadow,none))]",
|
|
644
|
-
"hover:bg-[var(--button-default-hover-bg,hsl(var(--primary)/0.9))]",
|
|
645
|
-
"hover:text-[var(--button-default-hover-fg,var(--button-default-fg,hsl(var(--primary-foreground))))]",
|
|
646
|
-
"hover:border-[color:var(--button-default-hover-border,var(--button-default-border,transparent))]",
|
|
647
|
-
"hover:[box-shadow:var(--button-default-shadow-hover,var(--button-shadow-hover,var(--button-default-shadow,var(--button-shadow,none))))]"
|
|
648
|
-
].join(" "),
|
|
649
|
-
// Destructive variant - full customization
|
|
650
|
-
destructive: [
|
|
651
|
-
"bg-[var(--button-destructive-bg,hsl(var(--destructive)))]",
|
|
652
|
-
"text-[var(--button-destructive-fg,white)]",
|
|
653
|
-
"border-[length:var(--button-destructive-border-width,0px)]",
|
|
654
|
-
"border-[color:var(--button-destructive-border,transparent)]",
|
|
655
|
-
"[box-shadow:var(--button-destructive-shadow,var(--button-shadow,none))]",
|
|
656
|
-
"hover:bg-[var(--button-destructive-hover-bg,hsl(var(--destructive)/0.9))]",
|
|
657
|
-
"hover:text-[var(--button-destructive-hover-fg,var(--button-destructive-fg,white))]",
|
|
658
|
-
"hover:border-[color:var(--button-destructive-hover-border,var(--button-destructive-border,transparent))]",
|
|
659
|
-
"hover:[box-shadow:var(--button-destructive-shadow-hover,var(--button-shadow-hover,var(--button-destructive-shadow,var(--button-shadow,none))))]",
|
|
660
|
-
"focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40",
|
|
661
|
-
"dark:bg-destructive/60"
|
|
662
|
-
].join(" "),
|
|
663
|
-
// Outline variant - full customization with proper border handling
|
|
664
|
-
outline: [
|
|
665
|
-
"bg-[var(--button-outline-bg,hsl(var(--background)))]",
|
|
666
|
-
"text-[var(--button-outline-fg,inherit)]",
|
|
667
|
-
"border-[length:var(--button-outline-border-width,1px)]",
|
|
668
|
-
"border-[color:var(--button-outline-border,hsl(var(--border)))]",
|
|
669
|
-
"[box-shadow:var(--button-outline-shadow,var(--button-shadow,0_1px_2px_0_rgb(0_0_0/0.05)))]",
|
|
670
|
-
"hover:bg-[var(--button-outline-hover-bg,hsl(var(--accent)))]",
|
|
671
|
-
"hover:text-[var(--button-outline-hover-fg,hsl(var(--accent-foreground)))]",
|
|
672
|
-
"hover:border-[color:var(--button-outline-hover-border,var(--button-outline-border,hsl(var(--border))))]",
|
|
673
|
-
"hover:[box-shadow:var(--button-outline-shadow-hover,var(--button-shadow-hover,var(--button-outline-shadow,var(--button-shadow,none))))]",
|
|
674
|
-
"dark:bg-input/30 dark:border-input dark:hover:bg-input/50"
|
|
675
|
-
].join(" "),
|
|
676
|
-
// Secondary variant - full customization
|
|
677
|
-
secondary: [
|
|
678
|
-
"bg-[var(--button-secondary-bg,hsl(var(--secondary)))]",
|
|
679
|
-
"text-[var(--button-secondary-fg,hsl(var(--secondary-foreground)))]",
|
|
680
|
-
"border-[length:var(--button-secondary-border-width,0px)]",
|
|
681
|
-
"border-[color:var(--button-secondary-border,transparent)]",
|
|
682
|
-
"[box-shadow:var(--button-secondary-shadow,var(--button-shadow,none))]",
|
|
683
|
-
"hover:bg-[var(--button-secondary-hover-bg,hsl(var(--secondary)/0.8))]",
|
|
684
|
-
"hover:text-[var(--button-secondary-hover-fg,var(--button-secondary-fg,hsl(var(--secondary-foreground))))]",
|
|
685
|
-
"hover:border-[color:var(--button-secondary-hover-border,var(--button-secondary-border,transparent))]",
|
|
686
|
-
"hover:[box-shadow:var(--button-secondary-shadow-hover,var(--button-shadow-hover,var(--button-secondary-shadow,var(--button-shadow,none))))]"
|
|
687
|
-
].join(" "),
|
|
688
|
-
// Ghost variant - full customization
|
|
689
|
-
ghost: [
|
|
690
|
-
"bg-[var(--button-ghost-bg,transparent)]",
|
|
691
|
-
"text-[var(--button-ghost-fg,inherit)]",
|
|
692
|
-
"border-[length:var(--button-ghost-border-width,0px)]",
|
|
693
|
-
"border-[color:var(--button-ghost-border,transparent)]",
|
|
694
|
-
"[box-shadow:var(--button-ghost-shadow,var(--button-shadow,none))]",
|
|
695
|
-
"hover:bg-[var(--button-ghost-hover-bg,hsl(var(--accent)))]",
|
|
696
|
-
"hover:text-[var(--button-ghost-hover-fg,hsl(var(--accent-foreground)))]",
|
|
697
|
-
"hover:border-[color:var(--button-ghost-hover-border,var(--button-ghost-border,transparent))]",
|
|
698
|
-
"hover:[box-shadow:var(--button-ghost-shadow-hover,var(--button-shadow-hover,var(--button-ghost-shadow,var(--button-shadow,none))))]",
|
|
699
|
-
"dark:hover:bg-accent/50"
|
|
700
|
-
].join(" "),
|
|
701
|
-
// Link variant - full customization
|
|
702
|
-
link: [
|
|
703
|
-
"bg-[var(--button-link-bg,transparent)]",
|
|
704
|
-
"text-[var(--button-link-fg,hsl(var(--primary)))]",
|
|
705
|
-
"border-[length:var(--button-link-border-width,0px)]",
|
|
706
|
-
"border-[color:var(--button-link-border,transparent)]",
|
|
707
|
-
"[box-shadow:var(--button-link-shadow,none)]",
|
|
708
|
-
"hover:bg-[var(--button-link-hover-bg,transparent)]",
|
|
709
|
-
"hover:text-[var(--button-link-hover-fg,var(--button-link-fg,hsl(var(--primary))))]",
|
|
710
|
-
"hover:[box-shadow:var(--button-link-shadow-hover,none)]",
|
|
711
|
-
"underline-offset-4 hover:underline"
|
|
712
|
-
].join(" ")
|
|
713
|
-
},
|
|
714
|
-
size: {
|
|
715
|
-
default: [
|
|
716
|
-
"h-[var(--button-height-md,2.25rem)]",
|
|
717
|
-
"px-[var(--button-padding-x-md,1rem)]",
|
|
718
|
-
"py-[var(--button-padding-y-md,0.5rem)]",
|
|
719
|
-
"has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
|
|
720
|
-
].join(" "),
|
|
721
|
-
sm: [
|
|
722
|
-
"h-[var(--button-height-sm,2rem)]",
|
|
723
|
-
"px-[var(--button-padding-x-sm,0.75rem)]",
|
|
724
|
-
"py-[var(--button-padding-y-sm,0.25rem)]",
|
|
725
|
-
"gap-1.5",
|
|
726
|
-
"has-[>svg]:px-[calc(var(--button-padding-x-sm,0.75rem)*0.83)]"
|
|
727
|
-
].join(" "),
|
|
728
|
-
md: [
|
|
729
|
-
"h-[var(--button-height-md,2.25rem)]",
|
|
730
|
-
"px-[var(--button-padding-x-md,1rem)]",
|
|
731
|
-
"py-[var(--button-padding-y-md,0.5rem)]",
|
|
732
|
-
"has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
|
|
733
|
-
].join(" "),
|
|
734
|
-
lg: [
|
|
735
|
-
"h-[var(--button-height-lg,2.5rem)]",
|
|
736
|
-
"px-[var(--button-padding-x-lg,1.5rem)]",
|
|
737
|
-
"py-[var(--button-padding-y-lg,0.5rem)]",
|
|
738
|
-
"has-[>svg]:px-[calc(var(--button-padding-x-lg,1.5rem)*0.67)]"
|
|
739
|
-
].join(" "),
|
|
740
|
-
icon: "size-[var(--button-height-md,2.25rem)]",
|
|
741
|
-
"icon-sm": "size-[var(--button-height-sm,2rem)]",
|
|
742
|
-
"icon-lg": "size-[var(--button-height-lg,2.5rem)]"
|
|
743
|
-
}
|
|
744
|
-
},
|
|
745
|
-
defaultVariants: {
|
|
746
|
-
variant: "default",
|
|
747
|
-
size: "default"
|
|
748
|
-
}
|
|
749
|
-
});
|
|
750
|
-
var Pressable = React6.forwardRef(
|
|
751
|
-
({
|
|
752
|
-
children,
|
|
753
|
-
className,
|
|
754
|
-
href,
|
|
755
|
-
onClick,
|
|
756
|
-
variant,
|
|
757
|
-
size,
|
|
758
|
-
asButton = false,
|
|
759
|
-
fallbackComponentType = "span",
|
|
760
|
-
componentType,
|
|
761
|
-
"aria-label": ariaLabel,
|
|
762
|
-
"aria-describedby": ariaDescribedby,
|
|
763
|
-
id,
|
|
764
|
-
...props
|
|
765
|
-
}, ref) => {
|
|
766
|
-
const navigation = useNavigation({ href, onClick });
|
|
767
|
-
const {
|
|
768
|
-
normalizedHref,
|
|
769
|
-
target,
|
|
770
|
-
rel,
|
|
771
|
-
linkType,
|
|
772
|
-
isInternal,
|
|
773
|
-
handleClick
|
|
774
|
-
} = navigation;
|
|
775
|
-
const shouldRenderLink = normalizedHref && linkType !== "none";
|
|
776
|
-
const shouldRenderButton = !shouldRenderLink && onClick;
|
|
777
|
-
const effectiveComponentType = componentType || (shouldRenderLink ? "a" : shouldRenderButton ? "button" : fallbackComponentType);
|
|
778
|
-
const finalComponentType = isInternal && shouldRenderLink ? "a" : effectiveComponentType;
|
|
779
|
-
const shouldApplyButtonStyles = asButton || variant || size;
|
|
780
|
-
const combinedClassName = cn(
|
|
781
|
-
shouldApplyButtonStyles && buttonVariants({ variant, size }),
|
|
782
|
-
className
|
|
783
|
-
);
|
|
784
|
-
const dataProps = Object.fromEntries(
|
|
785
|
-
Object.entries(props).filter(([key]) => key.startsWith("data-"))
|
|
786
|
-
);
|
|
787
|
-
const buttonDataAttributes = shouldApplyButtonStyles ? {
|
|
788
|
-
"data-slot": "button",
|
|
789
|
-
"data-variant": variant ?? "default",
|
|
790
|
-
"data-size": size ?? "default"
|
|
791
|
-
} : {};
|
|
792
|
-
const commonProps = {
|
|
793
|
-
className: combinedClassName,
|
|
794
|
-
onClick: handleClick,
|
|
795
|
-
"aria-label": ariaLabel,
|
|
796
|
-
"aria-describedby": ariaDescribedby,
|
|
797
|
-
id,
|
|
798
|
-
...dataProps,
|
|
799
|
-
...buttonDataAttributes
|
|
800
|
-
};
|
|
801
|
-
if (finalComponentType === "a" && shouldRenderLink) {
|
|
802
|
-
return /* @__PURE__ */ jsx(
|
|
803
|
-
"a",
|
|
804
|
-
{
|
|
805
|
-
ref,
|
|
806
|
-
href: normalizedHref,
|
|
807
|
-
target,
|
|
808
|
-
rel,
|
|
809
|
-
...commonProps,
|
|
810
|
-
...props,
|
|
811
|
-
children
|
|
812
|
-
}
|
|
813
|
-
);
|
|
814
|
-
}
|
|
815
|
-
if (finalComponentType === "button") {
|
|
816
|
-
return /* @__PURE__ */ jsx(
|
|
817
|
-
"button",
|
|
818
|
-
{
|
|
819
|
-
ref,
|
|
820
|
-
type: props.type || "button",
|
|
821
|
-
...commonProps,
|
|
822
|
-
...props,
|
|
823
|
-
children
|
|
824
|
-
}
|
|
825
|
-
);
|
|
826
|
-
}
|
|
827
|
-
if (finalComponentType === "div") {
|
|
828
|
-
return /* @__PURE__ */ jsx(
|
|
829
|
-
"div",
|
|
830
|
-
{
|
|
831
|
-
ref,
|
|
832
|
-
...commonProps,
|
|
833
|
-
children
|
|
834
|
-
}
|
|
835
|
-
);
|
|
836
|
-
}
|
|
837
|
-
return /* @__PURE__ */ jsx(
|
|
838
|
-
"span",
|
|
839
|
-
{
|
|
840
|
-
ref,
|
|
841
|
-
...commonProps,
|
|
842
|
-
children
|
|
843
|
-
}
|
|
844
|
-
);
|
|
845
|
-
}
|
|
846
|
-
);
|
|
847
|
-
Pressable.displayName = "Pressable";
|
|
848
|
-
var DEFAULT_ICON_API_KEY = "au382bi7fsh96w9h9xlrnat2jglx";
|
|
849
|
-
var DynamicIcon = React6.memo(function DynamicIcon2({
|
|
850
|
-
apiKey,
|
|
851
|
-
...props
|
|
852
|
-
}) {
|
|
853
|
-
return /* @__PURE__ */ jsx(Icon, { ...props, apiKey: apiKey ?? DEFAULT_ICON_API_KEY });
|
|
854
|
-
});
|
|
855
|
-
DynamicIcon.displayName = "DynamicIcon";
|
|
856
|
-
var PANEL_POSITION_CLASS = {
|
|
857
|
-
"top-left": "left-4 top-4",
|
|
858
|
-
"top-right": "right-4 top-4",
|
|
859
|
-
"bottom-left": "bottom-4 left-4",
|
|
860
|
-
"bottom-right": "bottom-4 right-4"
|
|
861
|
-
};
|
|
862
|
-
var DEFAULT_VIEW_STATE = {
|
|
863
|
-
latitude: 39.5,
|
|
864
|
-
longitude: -98.35,
|
|
865
|
-
zoom: 3
|
|
866
|
-
};
|
|
867
|
-
var VIDEO_FILE_EXTENSION_REGEX = /\.(mp4|webm|ogg|mov|m4v|m3u8)(\?.*)?$/i;
|
|
868
|
-
function resolveMediaType(item) {
|
|
869
|
-
if (item.type) {
|
|
870
|
-
return item.type;
|
|
871
|
-
}
|
|
872
|
-
return VIDEO_FILE_EXTENSION_REGEX.test(item.src) ? "video" : "image";
|
|
873
|
-
}
|
|
874
|
-
function normalizeId(value, fallback) {
|
|
875
|
-
if (value === null || value === void 0 || value === "") {
|
|
876
|
-
return fallback;
|
|
877
|
-
}
|
|
878
|
-
return String(value);
|
|
879
|
-
}
|
|
880
|
-
function buildClusterCenter(markers) {
|
|
881
|
-
if (!markers.length) {
|
|
882
|
-
return null;
|
|
883
|
-
}
|
|
884
|
-
const total = markers.reduce(
|
|
885
|
-
(accumulator, marker) => ({
|
|
886
|
-
latitude: accumulator.latitude + marker.latitude,
|
|
887
|
-
longitude: accumulator.longitude + marker.longitude
|
|
888
|
-
}),
|
|
889
|
-
{ latitude: 0, longitude: 0 }
|
|
890
|
-
);
|
|
891
|
-
return {
|
|
892
|
-
latitude: total.latitude / markers.length,
|
|
893
|
-
longitude: total.longitude / markers.length
|
|
894
|
-
};
|
|
895
|
-
}
|
|
896
|
-
function resolveActionKey(action, index) {
|
|
897
|
-
if (typeof action.label === "string" && action.label.trim().length > 0) {
|
|
898
|
-
return `label:${action.label}:${index}`;
|
|
899
|
-
}
|
|
900
|
-
if (action.href) {
|
|
901
|
-
return `href:${action.href}:${index}`;
|
|
902
|
-
}
|
|
903
|
-
return `action:${index}`;
|
|
904
|
-
}
|
|
905
|
-
function MarkerActions({ actions }) {
|
|
906
|
-
if (!actions || actions.length === 0) {
|
|
907
|
-
return null;
|
|
908
|
-
}
|
|
909
|
-
return /* @__PURE__ */ jsx("div", { className: "mt-4 flex flex-wrap gap-2", children: actions.map((action, index) => {
|
|
910
|
-
const {
|
|
911
|
-
label,
|
|
912
|
-
icon,
|
|
913
|
-
iconAfter,
|
|
914
|
-
children,
|
|
915
|
-
href,
|
|
916
|
-
onClick,
|
|
917
|
-
className: actionClassName,
|
|
918
|
-
variant,
|
|
919
|
-
size,
|
|
920
|
-
asButton,
|
|
921
|
-
...rest
|
|
922
|
-
} = action;
|
|
923
|
-
return /* @__PURE__ */ jsx(
|
|
924
|
-
Pressable,
|
|
925
|
-
{
|
|
926
|
-
href,
|
|
927
|
-
onClick,
|
|
928
|
-
variant: variant ?? (index === 0 ? "default" : "outline"),
|
|
929
|
-
size: size ?? "sm",
|
|
930
|
-
asButton: asButton ?? true,
|
|
931
|
-
className: cn("inline-flex items-center gap-2", actionClassName),
|
|
932
|
-
...rest,
|
|
933
|
-
children: children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
934
|
-
icon,
|
|
935
|
-
label,
|
|
936
|
-
iconAfter
|
|
937
|
-
] })
|
|
938
|
-
},
|
|
939
|
-
resolveActionKey(action, index)
|
|
940
|
-
);
|
|
941
|
-
}) });
|
|
942
|
-
}
|
|
943
|
-
function MarkerMediaCarousel({
|
|
944
|
-
mediaItems,
|
|
945
|
-
optixFlowConfig
|
|
946
|
-
}) {
|
|
947
|
-
const [activeIndex, setActiveIndex] = React6.useState(0);
|
|
948
|
-
const totalItems = mediaItems.length;
|
|
949
|
-
const mediaResetKey = React6.useMemo(
|
|
950
|
-
() => mediaItems.map((item, index) => {
|
|
951
|
-
const itemId = normalizeId(item.id, `media-${index}`);
|
|
952
|
-
return `${itemId}:${item.src}:${item.type ?? ""}:${item.poster ?? ""}`;
|
|
953
|
-
}).join("|"),
|
|
954
|
-
[mediaItems]
|
|
955
|
-
);
|
|
956
|
-
const activeItemIndex = Math.min(activeIndex, Math.max(0, totalItems - 1));
|
|
957
|
-
React6.useEffect(() => {
|
|
958
|
-
setActiveIndex(0);
|
|
959
|
-
}, [mediaResetKey]);
|
|
960
|
-
return /* @__PURE__ */ jsxs("div", { className: "relative border-b border-border/60 bg-muted/40", children: [
|
|
961
|
-
/* @__PURE__ */ jsx("div", { className: "relative aspect-video w-full overflow-hidden", children: mediaItems.map((item, index) => {
|
|
962
|
-
const isActive = index === activeItemIndex;
|
|
963
|
-
const mediaType = resolveMediaType(item);
|
|
964
|
-
return /* @__PURE__ */ jsx(
|
|
965
|
-
"div",
|
|
966
|
-
{
|
|
967
|
-
"aria-hidden": !isActive,
|
|
968
|
-
className: cn(
|
|
969
|
-
"absolute inset-0 transition-opacity duration-500 ease-in-out",
|
|
970
|
-
isActive ? "opacity-100 z-[1]" : "opacity-0 z-0 pointer-events-none"
|
|
971
|
-
),
|
|
972
|
-
children: mediaType === "video" ? /* @__PURE__ */ jsx(
|
|
973
|
-
"video",
|
|
974
|
-
{
|
|
975
|
-
className: "h-full w-full object-cover",
|
|
976
|
-
controls: isActive,
|
|
977
|
-
preload: "metadata",
|
|
978
|
-
poster: item.poster,
|
|
979
|
-
tabIndex: isActive ? 0 : -1,
|
|
980
|
-
children: /* @__PURE__ */ jsx("source", { src: item.src })
|
|
981
|
-
}
|
|
982
|
-
) : /* @__PURE__ */ jsx(
|
|
983
|
-
Img,
|
|
984
|
-
{
|
|
985
|
-
src: item.src,
|
|
986
|
-
alt: item.alt ?? "Map marker media",
|
|
987
|
-
className: "h-full w-full object-cover",
|
|
988
|
-
loading: "eager",
|
|
989
|
-
optixFlowConfig
|
|
990
|
-
}
|
|
991
|
-
)
|
|
992
|
-
},
|
|
993
|
-
normalizeId(item.id, `media-slide-${index}`)
|
|
994
|
-
);
|
|
995
|
-
}) }),
|
|
996
|
-
totalItems > 1 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
997
|
-
/* @__PURE__ */ jsx(
|
|
998
|
-
"button",
|
|
999
|
-
{
|
|
1000
|
-
type: "button",
|
|
1001
|
-
"aria-label": "Show previous media",
|
|
1002
|
-
className: "absolute left-4 top-1/2 inline-flex size-10 -translate-y-1/2 items-center justify-center rounded-2xl bg-card text-card-foreground shadow-lg border-4 border-black hover:border-white hover:bg-black hover:text-white transition-all duration-500 z-[2]",
|
|
1003
|
-
onClick: () => {
|
|
1004
|
-
setActiveIndex(
|
|
1005
|
-
(current) => (current - 1 + totalItems) % totalItems
|
|
1006
|
-
);
|
|
1007
|
-
},
|
|
1008
|
-
children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/arrow-left", size: 18 })
|
|
1009
|
-
}
|
|
1010
|
-
),
|
|
1011
|
-
/* @__PURE__ */ jsx(
|
|
1012
|
-
"button",
|
|
1013
|
-
{
|
|
1014
|
-
type: "button",
|
|
1015
|
-
"aria-label": "Show next media",
|
|
1016
|
-
className: "absolute right-4 top-1/2 inline-flex size-10 -translate-y-1/2 items-center justify-center rounded-2xl bg-card text-card-foreground shadow-lg border-4 border-black hover:border-white hover:bg-black hover:text-white transition-all duration-500 z-[2]",
|
|
1017
|
-
onClick: () => {
|
|
1018
|
-
setActiveIndex((current) => (current + 1) % totalItems);
|
|
1019
|
-
},
|
|
1020
|
-
children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/arrow-right", size: 18 })
|
|
1021
|
-
}
|
|
1022
|
-
),
|
|
1023
|
-
/* @__PURE__ */ jsx("div", { className: "absolute bottom-2 left-1/2 flex -translate-x-1/2 items-center gap-1.5 z-[2]", children: mediaItems.map((item, index) => /* @__PURE__ */ jsx(
|
|
1024
|
-
"button",
|
|
1025
|
-
{
|
|
1026
|
-
type: "button",
|
|
1027
|
-
"aria-label": `Show media item ${index + 1}`,
|
|
1028
|
-
className: cn(
|
|
1029
|
-
"h-2 rounded-full transition-all duration-300",
|
|
1030
|
-
index === activeItemIndex ? "w-6 bg-card" : "w-2 bg-card opacity-50 hover:opacity-100"
|
|
1031
|
-
),
|
|
1032
|
-
onClick: () => setActiveIndex(index)
|
|
1033
|
-
},
|
|
1034
|
-
normalizeId(item.id, `media-dot-${index}`)
|
|
1035
|
-
)) })
|
|
1036
|
-
] }) : null
|
|
1037
|
-
] });
|
|
1038
|
-
}
|
|
1039
|
-
function getMarkerTitle(marker, markerIndex) {
|
|
1040
|
-
if (marker.title !== void 0 && marker.title !== null) {
|
|
1041
|
-
return marker.title;
|
|
1042
|
-
}
|
|
1043
|
-
if (marker.label !== void 0 && marker.label !== null) {
|
|
1044
|
-
return marker.label;
|
|
1045
|
-
}
|
|
1046
|
-
return `Location ${markerIndex + 1}`;
|
|
1047
|
-
}
|
|
1048
|
-
function GeoMap({
|
|
1049
|
-
className,
|
|
1050
|
-
mapWrapperClassName,
|
|
1051
|
-
mapClassName,
|
|
1052
|
-
panelClassName,
|
|
1053
|
-
panelPosition = "top-left",
|
|
1054
|
-
stadiaApiKey = "",
|
|
1055
|
-
mapStyle = "osm-bright",
|
|
1056
|
-
styleUrl,
|
|
1057
|
-
mapLibreCssHref,
|
|
1058
|
-
markers = [],
|
|
1059
|
-
clusters = [],
|
|
1060
|
-
viewState,
|
|
1061
|
-
defaultViewState,
|
|
1062
|
-
onViewStateChange,
|
|
1063
|
-
onMapClick,
|
|
1064
|
-
onMarkerDrag,
|
|
1065
|
-
showNavigationControl = true,
|
|
1066
|
-
showGeolocateControl = false,
|
|
1067
|
-
navigationControlPosition = "top-right",
|
|
1068
|
-
geolocateControlPosition = "top-left",
|
|
1069
|
-
flyToOptions,
|
|
1070
|
-
markerFocusZoom = 14,
|
|
1071
|
-
clusterFocusZoom = 5,
|
|
1072
|
-
selectedMarkerId,
|
|
1073
|
-
initialSelectedMarkerId,
|
|
1074
|
-
onSelectionChange,
|
|
1075
|
-
clearSelectionOnMapClick = true,
|
|
1076
|
-
mapChildren,
|
|
1077
|
-
optixFlowConfig
|
|
1078
|
-
}) {
|
|
1079
|
-
const normalizedStandaloneMarkers = React6.useMemo(
|
|
1080
|
-
() => markers.map((marker, index) => ({
|
|
1081
|
-
...marker,
|
|
1082
|
-
id: normalizeId(marker.id, `marker-${index}`)
|
|
1083
|
-
})),
|
|
1084
|
-
[markers]
|
|
1085
|
-
);
|
|
1086
|
-
const normalizedClusters = React6.useMemo(() => {
|
|
1087
|
-
const results = [];
|
|
1088
|
-
clusters.forEach((cluster, clusterIndex) => {
|
|
1089
|
-
const clusterId = normalizeId(cluster.id, `cluster-${clusterIndex}`);
|
|
1090
|
-
const normalizedClusterMarkers = cluster.markers.map(
|
|
1091
|
-
(marker, markerIndex) => ({
|
|
1092
|
-
...marker,
|
|
1093
|
-
id: normalizeId(marker.id, `${clusterId}-marker-${markerIndex}`),
|
|
1094
|
-
clusterId
|
|
1095
|
-
})
|
|
1096
|
-
);
|
|
1097
|
-
const clusterCenter = cluster.latitude !== void 0 && cluster.longitude !== void 0 ? { latitude: cluster.latitude, longitude: cluster.longitude } : buildClusterCenter(normalizedClusterMarkers);
|
|
1098
|
-
if (!clusterCenter) {
|
|
1099
|
-
return;
|
|
1100
|
-
}
|
|
1101
|
-
results.push({
|
|
1102
|
-
...cluster,
|
|
1103
|
-
id: clusterId,
|
|
1104
|
-
latitude: clusterCenter.latitude,
|
|
1105
|
-
longitude: clusterCenter.longitude,
|
|
1106
|
-
markers: normalizedClusterMarkers
|
|
1107
|
-
});
|
|
1108
|
-
});
|
|
1109
|
-
return results;
|
|
1110
|
-
}, [clusters]);
|
|
1111
|
-
const markerLookup = React6.useMemo(() => {
|
|
1112
|
-
const lookup = /* @__PURE__ */ new Map();
|
|
1113
|
-
normalizedStandaloneMarkers.forEach((marker) => {
|
|
1114
|
-
lookup.set(marker.id, marker);
|
|
1115
|
-
});
|
|
1116
|
-
normalizedClusters.forEach((cluster) => {
|
|
1117
|
-
cluster.markers.forEach((marker) => {
|
|
1118
|
-
lookup.set(marker.id, marker);
|
|
1119
|
-
});
|
|
1120
|
-
});
|
|
1121
|
-
return lookup;
|
|
1122
|
-
}, [normalizedClusters, normalizedStandaloneMarkers]);
|
|
1123
|
-
const clusterLookup = React6.useMemo(() => {
|
|
1124
|
-
const lookup = /* @__PURE__ */ new Map();
|
|
1125
|
-
normalizedClusters.forEach((cluster) => {
|
|
1126
|
-
lookup.set(cluster.id, cluster);
|
|
1127
|
-
});
|
|
1128
|
-
return lookup;
|
|
1129
|
-
}, [normalizedClusters]);
|
|
1130
|
-
const firstCoordinate = React6.useMemo(() => {
|
|
1131
|
-
if (normalizedStandaloneMarkers.length > 0) {
|
|
1132
|
-
const firstStandaloneMarker = normalizedStandaloneMarkers[0];
|
|
1133
|
-
return {
|
|
1134
|
-
latitude: firstStandaloneMarker.latitude,
|
|
1135
|
-
longitude: firstStandaloneMarker.longitude
|
|
1136
|
-
};
|
|
1137
|
-
}
|
|
1138
|
-
if (normalizedClusters.length > 0) {
|
|
1139
|
-
const firstCluster = normalizedClusters[0];
|
|
1140
|
-
return {
|
|
1141
|
-
latitude: firstCluster.latitude,
|
|
1142
|
-
longitude: firstCluster.longitude
|
|
1143
|
-
};
|
|
1144
|
-
}
|
|
1145
|
-
return {
|
|
1146
|
-
latitude: DEFAULT_VIEW_STATE.latitude,
|
|
1147
|
-
longitude: DEFAULT_VIEW_STATE.longitude
|
|
1148
|
-
};
|
|
1149
|
-
}, [normalizedClusters, normalizedStandaloneMarkers]);
|
|
1150
|
-
const [uncontrolledViewState, setUncontrolledViewState] = React6.useState({
|
|
1151
|
-
latitude: defaultViewState?.latitude ?? firstCoordinate.latitude,
|
|
1152
|
-
longitude: defaultViewState?.longitude ?? firstCoordinate.longitude,
|
|
1153
|
-
zoom: defaultViewState?.zoom ?? DEFAULT_VIEW_STATE.zoom
|
|
1154
|
-
});
|
|
1155
|
-
const isControlledViewState = viewState !== void 0;
|
|
1156
|
-
const resolvedViewState = isControlledViewState ? viewState : uncontrolledViewState;
|
|
1157
|
-
const applyViewState = React6.useCallback(
|
|
1158
|
-
(nextState) => {
|
|
1159
|
-
if (!isControlledViewState) {
|
|
1160
|
-
setUncontrolledViewState((current) => {
|
|
1161
|
-
const next = { ...current, ...nextState };
|
|
1162
|
-
const hasChanged = current.latitude !== next.latitude || current.longitude !== next.longitude || current.zoom !== next.zoom;
|
|
1163
|
-
return hasChanged ? next : current;
|
|
1164
|
-
});
|
|
1165
|
-
}
|
|
1166
|
-
onViewStateChange?.(nextState);
|
|
1167
|
-
},
|
|
1168
|
-
[isControlledViewState, onViewStateChange]
|
|
1169
|
-
);
|
|
1170
|
-
const [selection, setSelection] = React6.useState(() => {
|
|
1171
|
-
if (initialSelectedMarkerId !== void 0 && initialSelectedMarkerId !== null) {
|
|
1172
|
-
return {
|
|
1173
|
-
type: "marker",
|
|
1174
|
-
markerId: String(initialSelectedMarkerId)
|
|
1175
|
-
};
|
|
1176
|
-
}
|
|
1177
|
-
return { type: "none" };
|
|
1178
|
-
});
|
|
1179
|
-
React6.useEffect(() => {
|
|
1180
|
-
if (selectedMarkerId === void 0 || selectedMarkerId === null) {
|
|
1181
|
-
return;
|
|
1182
|
-
}
|
|
1183
|
-
setSelection({
|
|
1184
|
-
type: "marker",
|
|
1185
|
-
markerId: String(selectedMarkerId)
|
|
1186
|
-
});
|
|
1187
|
-
}, [selectedMarkerId]);
|
|
1188
|
-
const selectedMarker = selection.markerId ? markerLookup.get(selection.markerId) : void 0;
|
|
1189
|
-
const selectedCluster = selection.clusterId ? clusterLookup.get(selection.clusterId) : void 0;
|
|
1190
|
-
React6.useEffect(() => {
|
|
1191
|
-
if (selection.type === "marker" && selection.markerId && !selectedMarker) {
|
|
1192
|
-
setSelection({ type: "none" });
|
|
1193
|
-
onSelectionChange?.({ type: "none" });
|
|
1194
|
-
}
|
|
1195
|
-
}, [onSelectionChange, selectedMarker, selection]);
|
|
1196
|
-
const emitSelectionChange = React6.useCallback(
|
|
1197
|
-
(nextSelection) => {
|
|
1198
|
-
if (nextSelection.type === "none") {
|
|
1199
|
-
onSelectionChange?.({ type: "none" });
|
|
1200
|
-
return;
|
|
1201
|
-
}
|
|
1202
|
-
if (nextSelection.type === "marker") {
|
|
1203
|
-
const parentCluster = nextSelection.marker.clusterId ? clusterLookup.get(nextSelection.marker.clusterId) : void 0;
|
|
1204
|
-
onSelectionChange?.({
|
|
1205
|
-
type: "marker",
|
|
1206
|
-
marker: nextSelection.marker,
|
|
1207
|
-
cluster: parentCluster
|
|
1208
|
-
});
|
|
1209
|
-
return;
|
|
1210
|
-
}
|
|
1211
|
-
onSelectionChange?.({
|
|
1212
|
-
type: "cluster",
|
|
1213
|
-
cluster: nextSelection.cluster
|
|
1214
|
-
});
|
|
1215
|
-
},
|
|
1216
|
-
[clusterLookup, onSelectionChange]
|
|
1217
|
-
);
|
|
1218
|
-
const selectMarker = React6.useCallback(
|
|
1219
|
-
(marker) => {
|
|
1220
|
-
setSelection({
|
|
1221
|
-
type: "marker",
|
|
1222
|
-
markerId: marker.id,
|
|
1223
|
-
clusterId: marker.clusterId
|
|
1224
|
-
});
|
|
1225
|
-
applyViewState({
|
|
1226
|
-
latitude: marker.latitude,
|
|
1227
|
-
longitude: marker.longitude,
|
|
1228
|
-
zoom: markerFocusZoom
|
|
1229
|
-
});
|
|
1230
|
-
emitSelectionChange({ type: "marker", marker });
|
|
1231
|
-
},
|
|
1232
|
-
[applyViewState, emitSelectionChange, markerFocusZoom]
|
|
1233
|
-
);
|
|
1234
|
-
const selectCluster = React6.useCallback(
|
|
1235
|
-
(cluster) => {
|
|
1236
|
-
setSelection({
|
|
1237
|
-
type: "cluster",
|
|
1238
|
-
clusterId: cluster.id
|
|
1239
|
-
});
|
|
1240
|
-
applyViewState({
|
|
1241
|
-
latitude: cluster.latitude,
|
|
1242
|
-
longitude: cluster.longitude,
|
|
1243
|
-
zoom: clusterFocusZoom
|
|
1244
|
-
});
|
|
1245
|
-
emitSelectionChange({ type: "cluster", cluster });
|
|
1246
|
-
},
|
|
1247
|
-
[applyViewState, clusterFocusZoom, emitSelectionChange]
|
|
1248
|
-
);
|
|
1249
|
-
const clearSelection = React6.useCallback(() => {
|
|
1250
|
-
setSelection({ type: "none" });
|
|
1251
|
-
emitSelectionChange({ type: "none" });
|
|
1252
|
-
}, [emitSelectionChange]);
|
|
1253
|
-
const mapMarkers = React6.useMemo(() => {
|
|
1254
|
-
const resolvedMarkers = [];
|
|
1255
|
-
normalizedClusters.forEach((cluster) => {
|
|
1256
|
-
const isSelected = selection.type === "cluster" && selection.clusterId === cluster.id;
|
|
1257
|
-
resolvedMarkers.push({
|
|
1258
|
-
id: `cluster-pin:${cluster.id}`,
|
|
1259
|
-
latitude: cluster.latitude,
|
|
1260
|
-
longitude: cluster.longitude,
|
|
1261
|
-
element: () => {
|
|
1262
|
-
const customMarkerElement = cluster.markerElement;
|
|
1263
|
-
const markerBody = typeof customMarkerElement === "function" ? customMarkerElement({
|
|
1264
|
-
isSelected,
|
|
1265
|
-
count: cluster.markers.length
|
|
1266
|
-
}) : customMarkerElement;
|
|
1267
|
-
return /* @__PURE__ */ jsx(
|
|
1268
|
-
"button",
|
|
1269
|
-
{
|
|
1270
|
-
type: "button",
|
|
1271
|
-
className: "group cursor-pointer",
|
|
1272
|
-
onClick: (event) => {
|
|
1273
|
-
event.preventDefault();
|
|
1274
|
-
event.stopPropagation();
|
|
1275
|
-
selectCluster(cluster);
|
|
1276
|
-
},
|
|
1277
|
-
"aria-label": `View ${cluster.markers.length} clustered locations`,
|
|
1278
|
-
children: markerBody ?? /* @__PURE__ */ jsx(
|
|
1279
|
-
"span",
|
|
1280
|
-
{
|
|
1281
|
-
className: cn(
|
|
1282
|
-
"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",
|
|
1283
|
-
isSelected && "ring-4 ring-primary/30",
|
|
1284
|
-
cluster.pinClassName
|
|
1285
|
-
),
|
|
1286
|
-
style: {
|
|
1287
|
-
backgroundColor: cluster.pinColor ?? "var(--foreground)"
|
|
1288
|
-
},
|
|
1289
|
-
children: cluster.markers.length
|
|
1290
|
-
}
|
|
1291
|
-
)
|
|
1292
|
-
}
|
|
1293
|
-
);
|
|
1294
|
-
}
|
|
1295
|
-
});
|
|
1296
|
-
});
|
|
1297
|
-
normalizedStandaloneMarkers.forEach((marker) => {
|
|
1298
|
-
const isSelected = selection.type === "marker" && selection.markerId === marker.id;
|
|
1299
|
-
const customMarkerElement = marker.markerElement;
|
|
1300
|
-
resolvedMarkers.push({
|
|
1301
|
-
id: marker.id,
|
|
1302
|
-
latitude: marker.latitude,
|
|
1303
|
-
longitude: marker.longitude,
|
|
1304
|
-
draggable: marker.draggable,
|
|
1305
|
-
element: () => {
|
|
1306
|
-
const markerBody = typeof customMarkerElement === "function" ? customMarkerElement({ isSelected }) : customMarkerElement;
|
|
1307
|
-
return /* @__PURE__ */ jsx(
|
|
1308
|
-
"button",
|
|
1309
|
-
{
|
|
1310
|
-
type: "button",
|
|
1311
|
-
className: "group cursor-pointer",
|
|
1312
|
-
onClick: (event) => {
|
|
1313
|
-
event.preventDefault();
|
|
1314
|
-
event.stopPropagation();
|
|
1315
|
-
selectMarker(marker);
|
|
1316
|
-
},
|
|
1317
|
-
"aria-label": typeof marker.title === "string" ? `View ${marker.title}` : "View location details",
|
|
1318
|
-
children: markerBody ?? /* @__PURE__ */ jsx(
|
|
1319
|
-
"span",
|
|
1320
|
-
{
|
|
1321
|
-
className: cn(
|
|
1322
|
-
"inline-flex h-4 w-4 rounded-full border-2 border-white shadow-md transition-transform duration-200 group-hover:scale-110",
|
|
1323
|
-
isSelected && "h-5 w-5 ring-4 ring-primary/30",
|
|
1324
|
-
marker.pinClassName
|
|
1325
|
-
),
|
|
1326
|
-
style: {
|
|
1327
|
-
backgroundColor: marker.pinColor ?? "#f43f5e"
|
|
1328
|
-
}
|
|
1329
|
-
}
|
|
1330
|
-
)
|
|
1331
|
-
}
|
|
1332
|
-
);
|
|
1333
|
-
}
|
|
1334
|
-
});
|
|
1335
|
-
});
|
|
1336
|
-
return resolvedMarkers;
|
|
1337
|
-
}, [
|
|
1338
|
-
normalizedClusters,
|
|
1339
|
-
normalizedStandaloneMarkers,
|
|
1340
|
-
selectCluster,
|
|
1341
|
-
selectMarker,
|
|
1342
|
-
selection
|
|
1343
|
-
]);
|
|
1344
|
-
const renderMarkerPanel = () => {
|
|
1345
|
-
if (selectedMarker) {
|
|
1346
|
-
const markerMediaItems = selectedMarker.mediaItems ?? [];
|
|
1347
|
-
return /* @__PURE__ */ jsxs(
|
|
1348
|
-
"div",
|
|
1349
|
-
{
|
|
1350
|
-
className: cn(
|
|
1351
|
-
"relative w-[min(24rem,calc(100vw-2rem))] overflow-hidden rounded-xl border border-border bg-card text-card-foreground shadow-2xl",
|
|
1352
|
-
panelClassName
|
|
1353
|
-
),
|
|
1354
|
-
children: [
|
|
1355
|
-
/* @__PURE__ */ jsx(
|
|
1356
|
-
"button",
|
|
1357
|
-
{
|
|
1358
|
-
type: "button",
|
|
1359
|
-
"aria-label": "Close marker details",
|
|
1360
|
-
className: "\n flex size-12 items-center justify-center rounded-bl-lg rounded-br-0 rounded-t-0 bg-black text-white transition-all duration-500 absolute top-0 right-0 z-10 cursor-pointer ring-4 ring-white\n",
|
|
1361
|
-
onClick: clearSelection,
|
|
1362
|
-
children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/x", size: 20 })
|
|
1363
|
-
}
|
|
1364
|
-
),
|
|
1365
|
-
markerMediaItems.length > 0 ? /* @__PURE__ */ jsx(
|
|
1366
|
-
MarkerMediaCarousel,
|
|
1367
|
-
{
|
|
1368
|
-
mediaItems: markerMediaItems,
|
|
1369
|
-
optixFlowConfig
|
|
1370
|
-
}
|
|
1371
|
-
) : null,
|
|
1372
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-2 p-4", children: [
|
|
1373
|
-
/* @__PURE__ */ jsx("div", { className: "flex items-start justify-between gap-3", children: /* @__PURE__ */ jsxs("div", { className: "min-w-0 space-y-1", children: [
|
|
1374
|
-
selectedMarker.eyebrow ? /* @__PURE__ */ jsx("p", { className: "text-xs font-semibold uppercase tracking-wide", children: selectedMarker.eyebrow }) : null,
|
|
1375
|
-
/* @__PURE__ */ jsx("div", { className: "text-base font-semibold leading-tight", children: selectedMarker.title ?? selectedMarker.label ?? "Location" })
|
|
1376
|
-
] }) }),
|
|
1377
|
-
selectedMarker.summary ? /* @__PURE__ */ jsx("div", { className: "text-sm leading-relaxed", children: selectedMarker.summary }) : null,
|
|
1378
|
-
selectedMarker.locationLine ? /* @__PURE__ */ jsxs("div", { className: "flex flex-row items-center justify-start text-sm gap-2", children: [
|
|
1379
|
-
/* @__PURE__ */ jsx(
|
|
1380
|
-
DynamicIcon,
|
|
1381
|
-
{
|
|
1382
|
-
name: "lucide:map-pin",
|
|
1383
|
-
className: "opacity-50",
|
|
1384
|
-
size: 18
|
|
1385
|
-
}
|
|
1386
|
-
),
|
|
1387
|
-
typeof selectedMarker.locationLine === "string" ? /* @__PURE__ */ jsx(
|
|
1388
|
-
Pressable,
|
|
1389
|
-
{
|
|
1390
|
-
href: selectedMarker.locationUrl,
|
|
1391
|
-
className: cn(
|
|
1392
|
-
"transition-all duration-500",
|
|
1393
|
-
"font-medium opacity-75 hover:opacity-100",
|
|
1394
|
-
selectedMarker.locationUrl ? "underline underline-offset-4" : ""
|
|
1395
|
-
),
|
|
1396
|
-
children: selectedMarker.locationLine
|
|
1397
|
-
}
|
|
1398
|
-
) : selectedMarker.locationLine
|
|
1399
|
-
] }) : null,
|
|
1400
|
-
selectedMarker.hoursLine ? /* @__PURE__ */ jsxs("div", { className: "flex flex-row items-center justify-start text-sm gap-2", children: [
|
|
1401
|
-
/* @__PURE__ */ jsx(
|
|
1402
|
-
DynamicIcon,
|
|
1403
|
-
{
|
|
1404
|
-
name: "lucide:clock",
|
|
1405
|
-
className: "opacity-50",
|
|
1406
|
-
size: 18
|
|
1407
|
-
}
|
|
1408
|
-
),
|
|
1409
|
-
typeof selectedMarker.hoursLine === "string" ? /* @__PURE__ */ jsx("div", { className: "font-medium", children: selectedMarker.hoursLine }) : selectedMarker.hoursLine
|
|
1410
|
-
] }) : null,
|
|
1411
|
-
selectedMarker.markerContentComponent ? /* @__PURE__ */ jsx("div", { className: "relative", children: selectedMarker.markerContentComponent }) : null,
|
|
1412
|
-
/* @__PURE__ */ jsx(MarkerActions, { actions: selectedMarker.actions })
|
|
1413
|
-
] })
|
|
1414
|
-
]
|
|
1415
|
-
}
|
|
1416
|
-
);
|
|
1417
|
-
}
|
|
1418
|
-
if (selectedCluster) {
|
|
1419
|
-
return /* @__PURE__ */ jsxs(
|
|
1420
|
-
"div",
|
|
1421
|
-
{
|
|
1422
|
-
className: cn(
|
|
1423
|
-
"relative w-[min(24rem,calc(100vw-2rem))] overflow-hidden rounded-xl border border-border bg-card text-card-foreground p-4 shadow-2xl",
|
|
1424
|
-
panelClassName
|
|
1425
|
-
),
|
|
1426
|
-
children: [
|
|
1427
|
-
/* @__PURE__ */ jsx(
|
|
1428
|
-
"button",
|
|
1429
|
-
{
|
|
1430
|
-
type: "button",
|
|
1431
|
-
"aria-label": "Close cluster details",
|
|
1432
|
-
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",
|
|
1433
|
-
onClick: clearSelection,
|
|
1434
|
-
children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/x", size: 20 })
|
|
1435
|
-
}
|
|
1436
|
-
),
|
|
1437
|
-
/* @__PURE__ */ jsx("div", { className: "mb-3 flex items-start justify-between gap-3", children: /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
1438
|
-
selectedCluster.label ? /* @__PURE__ */ jsx("p", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: selectedCluster.label }) : null,
|
|
1439
|
-
/* @__PURE__ */ jsx("div", { className: "text-base font-semibold leading-tight text-foreground", children: selectedCluster.title ?? "Clustered Locations" }),
|
|
1440
|
-
/* @__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.` })
|
|
1441
|
-
] }) }),
|
|
1442
|
-
/* @__PURE__ */ jsx("div", { className: "max-h-56 space-y-2 overflow-y-auto pr-1", children: selectedCluster.markers.map((marker, markerIndex) => /* @__PURE__ */ jsxs(
|
|
1443
|
-
"button",
|
|
1444
|
-
{
|
|
1445
|
-
type: "button",
|
|
1446
|
-
className: "w-full rounded-lg border border-border/60 p-3 text-left transition hover:border-border hover:bg-muted/50",
|
|
1447
|
-
onClick: () => selectMarker(marker),
|
|
1448
|
-
children: [
|
|
1449
|
-
/* @__PURE__ */ jsx("div", { className: "line-clamp-1 text-sm font-semibold text-foreground", children: getMarkerTitle(marker, markerIndex) }),
|
|
1450
|
-
marker.summary ? /* @__PURE__ */ jsx("div", { className: "mt-1 line-clamp-2 text-xs text-muted-foreground", children: marker.summary }) : null
|
|
1451
|
-
]
|
|
1452
|
-
},
|
|
1453
|
-
marker.id
|
|
1454
|
-
)) })
|
|
1455
|
-
]
|
|
1456
|
-
}
|
|
1457
|
-
);
|
|
1458
|
-
}
|
|
1459
|
-
return null;
|
|
1460
|
-
};
|
|
1461
|
-
return /* @__PURE__ */ jsxs(
|
|
1462
|
-
"div",
|
|
1463
|
-
{
|
|
1464
|
-
className: cn(
|
|
1465
|
-
"relative overflow-hidden rounded-2xl border border-border bg-background",
|
|
1466
|
-
className
|
|
1467
|
-
),
|
|
1468
|
-
children: [
|
|
1469
|
-
/* @__PURE__ */ jsx("div", { className: cn("h-[520px] w-full", mapWrapperClassName), children: /* @__PURE__ */ jsx(
|
|
1470
|
-
MapLibre,
|
|
1471
|
-
{
|
|
1472
|
-
stadiaApiKey,
|
|
1473
|
-
mapStyle,
|
|
1474
|
-
styleUrl,
|
|
1475
|
-
mapLibreCssHref,
|
|
1476
|
-
viewState: resolvedViewState,
|
|
1477
|
-
onViewStateChange: applyViewState,
|
|
1478
|
-
markers: mapMarkers,
|
|
1479
|
-
onClick: (coord) => {
|
|
1480
|
-
onMapClick?.(coord);
|
|
1481
|
-
if (clearSelectionOnMapClick) {
|
|
1482
|
-
clearSelection();
|
|
1483
|
-
}
|
|
1484
|
-
},
|
|
1485
|
-
onMarkerDrag,
|
|
1486
|
-
showNavigationControl,
|
|
1487
|
-
showGeolocateControl,
|
|
1488
|
-
navigationControlPosition,
|
|
1489
|
-
geolocateControlPosition,
|
|
1490
|
-
flyToOptions,
|
|
1491
|
-
className: cn("h-full w-full", mapClassName),
|
|
1492
|
-
children: mapChildren
|
|
1493
|
-
}
|
|
1494
|
-
) }),
|
|
1495
|
-
selection.type !== "none" ? /* @__PURE__ */ jsx(
|
|
1496
|
-
"div",
|
|
1497
|
-
{
|
|
1498
|
-
className: cn(
|
|
1499
|
-
"pointer-events-none absolute z-20",
|
|
1500
|
-
PANEL_POSITION_CLASS[panelPosition]
|
|
1501
|
-
),
|
|
1502
|
-
children: /* @__PURE__ */ jsx("div", { className: "pointer-events-auto", children: renderMarkerPanel() })
|
|
1503
|
-
}
|
|
1504
|
-
) : null
|
|
1505
|
-
]
|
|
1506
|
-
}
|
|
1507
|
-
);
|
|
1508
|
-
}
|
|
1509
|
-
var sizeStyles = {
|
|
1510
|
-
sm: "max-w-md",
|
|
1511
|
-
md: "max-w-2xl",
|
|
1512
|
-
lg: "max-w-4xl",
|
|
1513
|
-
xl: "max-w-5xl",
|
|
1514
|
-
full: "max-w-7xl",
|
|
1515
|
-
compact: "max-w-[700px]"
|
|
1516
|
-
};
|
|
1517
|
-
var dialogTransition = {
|
|
1518
|
-
duration: 0.35,
|
|
1519
|
-
ease: [0.16, 1, 0.3, 1]
|
|
1520
|
-
};
|
|
1521
|
-
function AnimatedDialog({
|
|
1522
|
-
open,
|
|
1523
|
-
onOpenChange,
|
|
1524
|
-
title,
|
|
1525
|
-
eyebrow,
|
|
1526
|
-
description,
|
|
1527
|
-
children,
|
|
1528
|
-
header,
|
|
1529
|
-
footer,
|
|
1530
|
-
size = "lg",
|
|
1531
|
-
className,
|
|
1532
|
-
contentClassName,
|
|
1533
|
-
featuredMediaHeader
|
|
1534
|
-
}) {
|
|
1535
|
-
const titleId = useId();
|
|
1536
|
-
const descriptionId = useId();
|
|
1537
|
-
const containerRef = useRef(null);
|
|
1538
|
-
useOnClickOutside(containerRef, () => {
|
|
1539
|
-
if (open) {
|
|
1540
|
-
onOpenChange(false);
|
|
1541
|
-
}
|
|
1542
|
-
});
|
|
1543
|
-
useEffect(() => {
|
|
1544
|
-
if (!open) {
|
|
1545
|
-
return;
|
|
1546
|
-
}
|
|
1547
|
-
const onKeyDown = (event) => {
|
|
1548
|
-
if (event.key === "Escape") {
|
|
1549
|
-
onOpenChange(false);
|
|
1550
|
-
}
|
|
1551
|
-
};
|
|
1552
|
-
const previousOverflow = document.body.style.overflow;
|
|
1553
|
-
document.body.style.overflow = "hidden";
|
|
1554
|
-
window.addEventListener("keydown", onKeyDown);
|
|
1555
|
-
return () => {
|
|
1556
|
-
document.body.style.overflow = previousOverflow;
|
|
1557
|
-
window.removeEventListener("keydown", onKeyDown);
|
|
1558
|
-
};
|
|
1559
|
-
}, [open, onOpenChange]);
|
|
1560
|
-
return /* @__PURE__ */ jsx(AnimatePresence, { children: open ? /* @__PURE__ */ jsxs("div", { className: "fixed inset-0 z-50 h-screen overflow-y-auto", children: [
|
|
1561
|
-
/* @__PURE__ */ jsx(
|
|
1562
|
-
motion.div,
|
|
1563
|
-
{
|
|
1564
|
-
initial: { opacity: 0 },
|
|
1565
|
-
animate: { opacity: 1, transition: dialogTransition },
|
|
1566
|
-
exit: { opacity: 0, transition: dialogTransition },
|
|
1567
|
-
className: "fixed inset-0 h-full w-full bg-foreground/80 backdrop-blur-lg"
|
|
471
|
+
};
|
|
472
|
+
const previousOverflow = document.body.style.overflow;
|
|
473
|
+
document.body.style.overflow = "hidden";
|
|
474
|
+
window.addEventListener("keydown", onKeyDown);
|
|
475
|
+
return () => {
|
|
476
|
+
document.body.style.overflow = previousOverflow;
|
|
477
|
+
window.removeEventListener("keydown", onKeyDown);
|
|
478
|
+
};
|
|
479
|
+
}, [open, onOpenChange]);
|
|
480
|
+
return /* @__PURE__ */ jsx(AnimatePresence, { children: open ? /* @__PURE__ */ jsxs("div", { className: "fixed inset-0 z-50 h-screen overflow-y-auto", children: [
|
|
481
|
+
/* @__PURE__ */ jsx(
|
|
482
|
+
motion.div,
|
|
483
|
+
{
|
|
484
|
+
initial: { opacity: 0 },
|
|
485
|
+
animate: { opacity: 1, transition: dialogTransition },
|
|
486
|
+
exit: { opacity: 0, transition: dialogTransition },
|
|
487
|
+
className: "fixed inset-0 h-full w-full bg-foreground/80 backdrop-blur-lg"
|
|
1568
488
|
}
|
|
1569
489
|
),
|
|
1570
490
|
/* @__PURE__ */ jsxs(
|
|
@@ -1863,10 +783,10 @@ var ImageSlider = ({
|
|
|
1863
783
|
optixFlowConfig
|
|
1864
784
|
}) => {
|
|
1865
785
|
const hasImages = images.length > 0;
|
|
1866
|
-
const [currentIndex, setCurrentIndex] =
|
|
786
|
+
const [currentIndex, setCurrentIndex] = React4.useState(
|
|
1867
787
|
() => normalizeIndex(startIndex, images.length)
|
|
1868
788
|
);
|
|
1869
|
-
const handleNext =
|
|
789
|
+
const handleNext = React4.useCallback(() => {
|
|
1870
790
|
if (!hasImages) return;
|
|
1871
791
|
setCurrentIndex((prevIndex) => {
|
|
1872
792
|
const nextIndex = prevIndex + 1 >= images.length ? 0 : prevIndex + 1;
|
|
@@ -1874,7 +794,7 @@ var ImageSlider = ({
|
|
|
1874
794
|
return nextIndex;
|
|
1875
795
|
});
|
|
1876
796
|
}, [hasImages, images.length, onSlideChange]);
|
|
1877
|
-
const handlePrevious =
|
|
797
|
+
const handlePrevious = React4.useCallback(() => {
|
|
1878
798
|
if (!hasImages) return;
|
|
1879
799
|
setCurrentIndex((prevIndex) => {
|
|
1880
800
|
const nextIndex = prevIndex - 1 < 0 ? images.length - 1 : prevIndex - 1;
|
|
@@ -1882,11 +802,11 @@ var ImageSlider = ({
|
|
|
1882
802
|
return nextIndex;
|
|
1883
803
|
});
|
|
1884
804
|
}, [hasImages, images.length, onSlideChange]);
|
|
1885
|
-
|
|
805
|
+
React4.useEffect(() => {
|
|
1886
806
|
if (!hasImages) return;
|
|
1887
807
|
setCurrentIndex(normalizeIndex(startIndex, images.length));
|
|
1888
808
|
}, [startIndex, images.length, hasImages]);
|
|
1889
|
-
|
|
809
|
+
React4.useEffect(() => {
|
|
1890
810
|
if (!enableKeyboard || !hasImages) return;
|
|
1891
811
|
const handleKeyDown = (event) => {
|
|
1892
812
|
if (event.key === "ArrowRight") {
|
|
@@ -1900,7 +820,7 @@ var ImageSlider = ({
|
|
|
1900
820
|
window.removeEventListener("keydown", handleKeyDown);
|
|
1901
821
|
};
|
|
1902
822
|
}, [enableKeyboard, handleNext, handlePrevious, hasImages]);
|
|
1903
|
-
|
|
823
|
+
React4.useEffect(() => {
|
|
1904
824
|
if (!autoplay || images.length < 2) return;
|
|
1905
825
|
const interval = window.setInterval(handleNext, autoplayIntervalMs);
|
|
1906
826
|
return () => window.clearInterval(interval);
|
|
@@ -1971,8 +891,150 @@ var ImageSlider = ({
|
|
|
1971
891
|
) : null
|
|
1972
892
|
]
|
|
1973
893
|
}
|
|
1974
|
-
);
|
|
1975
|
-
};
|
|
894
|
+
);
|
|
895
|
+
};
|
|
896
|
+
var baseStyles = [
|
|
897
|
+
// Layout
|
|
898
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap shrink-0",
|
|
899
|
+
// Typography - using CSS variables with sensible defaults
|
|
900
|
+
"font-[var(--button-font-family,inherit)]",
|
|
901
|
+
"font-[var(--button-font-weight,500)]",
|
|
902
|
+
"tracking-[var(--button-letter-spacing,0)]",
|
|
903
|
+
"leading-[var(--button-line-height,1.25)]",
|
|
904
|
+
"[text-transform:var(--button-text-transform,none)]",
|
|
905
|
+
"text-sm",
|
|
906
|
+
// Border radius
|
|
907
|
+
"rounded-[var(--button-radius,var(--radius,0.375rem))]",
|
|
908
|
+
// Smooth transition - using [transition:...] to set full shorthand property (not just transition-property)
|
|
909
|
+
"[transition:var(--button-transition,all_250ms_cubic-bezier(0.4,0,0.2,1))]",
|
|
910
|
+
// Box shadow (master level) - using [box-shadow:...] for complex multi-value shadows
|
|
911
|
+
"[box-shadow:var(--button-shadow,none)]",
|
|
912
|
+
"hover:[box-shadow:var(--button-shadow-hover,var(--button-shadow,none))]",
|
|
913
|
+
// Disabled state
|
|
914
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
|
915
|
+
// SVG handling
|
|
916
|
+
"[&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0",
|
|
917
|
+
// Focus styles
|
|
918
|
+
"outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
|
919
|
+
// Invalid state
|
|
920
|
+
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive"
|
|
921
|
+
].join(" ");
|
|
922
|
+
var buttonVariants = cva(baseStyles, {
|
|
923
|
+
variants: {
|
|
924
|
+
variant: {
|
|
925
|
+
// Default (Primary) variant - full customization
|
|
926
|
+
default: [
|
|
927
|
+
"bg-[var(--button-default-bg,hsl(var(--primary)))]",
|
|
928
|
+
"text-[var(--button-default-fg,hsl(var(--primary-foreground)))]",
|
|
929
|
+
"border-[length:var(--button-default-border-width,0px)]",
|
|
930
|
+
"border-[color:var(--button-default-border,transparent)]",
|
|
931
|
+
"[box-shadow:var(--button-default-shadow,var(--button-shadow,none))]",
|
|
932
|
+
"hover:bg-[var(--button-default-hover-bg,hsl(var(--primary)/0.9))]",
|
|
933
|
+
"hover:text-[var(--button-default-hover-fg,var(--button-default-fg,hsl(var(--primary-foreground))))]",
|
|
934
|
+
"hover:border-[color:var(--button-default-hover-border,var(--button-default-border,transparent))]",
|
|
935
|
+
"hover:[box-shadow:var(--button-default-shadow-hover,var(--button-shadow-hover,var(--button-default-shadow,var(--button-shadow,none))))]"
|
|
936
|
+
].join(" "),
|
|
937
|
+
// Destructive variant - full customization
|
|
938
|
+
destructive: [
|
|
939
|
+
"bg-[var(--button-destructive-bg,hsl(var(--destructive)))]",
|
|
940
|
+
"text-[var(--button-destructive-fg,white)]",
|
|
941
|
+
"border-[length:var(--button-destructive-border-width,0px)]",
|
|
942
|
+
"border-[color:var(--button-destructive-border,transparent)]",
|
|
943
|
+
"[box-shadow:var(--button-destructive-shadow,var(--button-shadow,none))]",
|
|
944
|
+
"hover:bg-[var(--button-destructive-hover-bg,hsl(var(--destructive)/0.9))]",
|
|
945
|
+
"hover:text-[var(--button-destructive-hover-fg,var(--button-destructive-fg,white))]",
|
|
946
|
+
"hover:border-[color:var(--button-destructive-hover-border,var(--button-destructive-border,transparent))]",
|
|
947
|
+
"hover:[box-shadow:var(--button-destructive-shadow-hover,var(--button-shadow-hover,var(--button-destructive-shadow,var(--button-shadow,none))))]",
|
|
948
|
+
"focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40",
|
|
949
|
+
"dark:bg-destructive/60"
|
|
950
|
+
].join(" "),
|
|
951
|
+
// Outline variant - full customization with proper border handling
|
|
952
|
+
outline: [
|
|
953
|
+
"bg-[var(--button-outline-bg,hsl(var(--background)))]",
|
|
954
|
+
"text-[var(--button-outline-fg,inherit)]",
|
|
955
|
+
"border-[length:var(--button-outline-border-width,1px)]",
|
|
956
|
+
"border-[color:var(--button-outline-border,hsl(var(--border)))]",
|
|
957
|
+
"[box-shadow:var(--button-outline-shadow,var(--button-shadow,0_1px_2px_0_rgb(0_0_0/0.05)))]",
|
|
958
|
+
"hover:bg-[var(--button-outline-hover-bg,hsl(var(--accent)))]",
|
|
959
|
+
"hover:text-[var(--button-outline-hover-fg,hsl(var(--accent-foreground)))]",
|
|
960
|
+
"hover:border-[color:var(--button-outline-hover-border,var(--button-outline-border,hsl(var(--border))))]",
|
|
961
|
+
"hover:[box-shadow:var(--button-outline-shadow-hover,var(--button-shadow-hover,var(--button-outline-shadow,var(--button-shadow,none))))]",
|
|
962
|
+
"dark:bg-input/30 dark:border-input dark:hover:bg-input/50"
|
|
963
|
+
].join(" "),
|
|
964
|
+
// Secondary variant - full customization
|
|
965
|
+
secondary: [
|
|
966
|
+
"bg-[var(--button-secondary-bg,hsl(var(--secondary)))]",
|
|
967
|
+
"text-[var(--button-secondary-fg,hsl(var(--secondary-foreground)))]",
|
|
968
|
+
"border-[length:var(--button-secondary-border-width,0px)]",
|
|
969
|
+
"border-[color:var(--button-secondary-border,transparent)]",
|
|
970
|
+
"[box-shadow:var(--button-secondary-shadow,var(--button-shadow,none))]",
|
|
971
|
+
"hover:bg-[var(--button-secondary-hover-bg,hsl(var(--secondary)/0.8))]",
|
|
972
|
+
"hover:text-[var(--button-secondary-hover-fg,var(--button-secondary-fg,hsl(var(--secondary-foreground))))]",
|
|
973
|
+
"hover:border-[color:var(--button-secondary-hover-border,var(--button-secondary-border,transparent))]",
|
|
974
|
+
"hover:[box-shadow:var(--button-secondary-shadow-hover,var(--button-shadow-hover,var(--button-secondary-shadow,var(--button-shadow,none))))]"
|
|
975
|
+
].join(" "),
|
|
976
|
+
// Ghost variant - full customization
|
|
977
|
+
ghost: [
|
|
978
|
+
"bg-[var(--button-ghost-bg,transparent)]",
|
|
979
|
+
"text-[var(--button-ghost-fg,inherit)]",
|
|
980
|
+
"border-[length:var(--button-ghost-border-width,0px)]",
|
|
981
|
+
"border-[color:var(--button-ghost-border,transparent)]",
|
|
982
|
+
"[box-shadow:var(--button-ghost-shadow,var(--button-shadow,none))]",
|
|
983
|
+
"hover:bg-[var(--button-ghost-hover-bg,hsl(var(--accent)))]",
|
|
984
|
+
"hover:text-[var(--button-ghost-hover-fg,hsl(var(--accent-foreground)))]",
|
|
985
|
+
"hover:border-[color:var(--button-ghost-hover-border,var(--button-ghost-border,transparent))]",
|
|
986
|
+
"hover:[box-shadow:var(--button-ghost-shadow-hover,var(--button-shadow-hover,var(--button-ghost-shadow,var(--button-shadow,none))))]",
|
|
987
|
+
"dark:hover:bg-accent/50"
|
|
988
|
+
].join(" "),
|
|
989
|
+
// Link variant - full customization
|
|
990
|
+
link: [
|
|
991
|
+
"bg-[var(--button-link-bg,transparent)]",
|
|
992
|
+
"text-[var(--button-link-fg,hsl(var(--primary)))]",
|
|
993
|
+
"border-[length:var(--button-link-border-width,0px)]",
|
|
994
|
+
"border-[color:var(--button-link-border,transparent)]",
|
|
995
|
+
"[box-shadow:var(--button-link-shadow,none)]",
|
|
996
|
+
"hover:bg-[var(--button-link-hover-bg,transparent)]",
|
|
997
|
+
"hover:text-[var(--button-link-hover-fg,var(--button-link-fg,hsl(var(--primary))))]",
|
|
998
|
+
"hover:[box-shadow:var(--button-link-shadow-hover,none)]",
|
|
999
|
+
"underline-offset-4 hover:underline"
|
|
1000
|
+
].join(" ")
|
|
1001
|
+
},
|
|
1002
|
+
size: {
|
|
1003
|
+
default: [
|
|
1004
|
+
"h-[var(--button-height-md,2.25rem)]",
|
|
1005
|
+
"px-[var(--button-padding-x-md,1rem)]",
|
|
1006
|
+
"py-[var(--button-padding-y-md,0.5rem)]",
|
|
1007
|
+
"has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
|
|
1008
|
+
].join(" "),
|
|
1009
|
+
sm: [
|
|
1010
|
+
"h-[var(--button-height-sm,2rem)]",
|
|
1011
|
+
"px-[var(--button-padding-x-sm,0.75rem)]",
|
|
1012
|
+
"py-[var(--button-padding-y-sm,0.25rem)]",
|
|
1013
|
+
"gap-1.5",
|
|
1014
|
+
"has-[>svg]:px-[calc(var(--button-padding-x-sm,0.75rem)*0.83)]"
|
|
1015
|
+
].join(" "),
|
|
1016
|
+
md: [
|
|
1017
|
+
"h-[var(--button-height-md,2.25rem)]",
|
|
1018
|
+
"px-[var(--button-padding-x-md,1rem)]",
|
|
1019
|
+
"py-[var(--button-padding-y-md,0.5rem)]",
|
|
1020
|
+
"has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
|
|
1021
|
+
].join(" "),
|
|
1022
|
+
lg: [
|
|
1023
|
+
"h-[var(--button-height-lg,2.5rem)]",
|
|
1024
|
+
"px-[var(--button-padding-x-lg,1.5rem)]",
|
|
1025
|
+
"py-[var(--button-padding-y-lg,0.5rem)]",
|
|
1026
|
+
"has-[>svg]:px-[calc(var(--button-padding-x-lg,1.5rem)*0.67)]"
|
|
1027
|
+
].join(" "),
|
|
1028
|
+
icon: "size-[var(--button-height-md,2.25rem)]",
|
|
1029
|
+
"icon-sm": "size-[var(--button-height-sm,2rem)]",
|
|
1030
|
+
"icon-lg": "size-[var(--button-height-lg,2.5rem)]"
|
|
1031
|
+
}
|
|
1032
|
+
},
|
|
1033
|
+
defaultVariants: {
|
|
1034
|
+
variant: "default",
|
|
1035
|
+
size: "default"
|
|
1036
|
+
}
|
|
1037
|
+
});
|
|
1976
1038
|
function Button({
|
|
1977
1039
|
className,
|
|
1978
1040
|
variant = "default",
|
|
@@ -2016,127 +1078,411 @@ function CardHeader({ className, ...props }) {
|
|
|
2016
1078
|
),
|
|
2017
1079
|
...props
|
|
2018
1080
|
}
|
|
2019
|
-
);
|
|
2020
|
-
}
|
|
2021
|
-
function CardTitle({ className, ...props }) {
|
|
2022
|
-
return /* @__PURE__ */ jsx(
|
|
2023
|
-
"div",
|
|
2024
|
-
{
|
|
2025
|
-
"data-slot": "card-title",
|
|
2026
|
-
className: cn("leading-none font-semibold", className),
|
|
2027
|
-
...props
|
|
1081
|
+
);
|
|
1082
|
+
}
|
|
1083
|
+
function CardTitle({ className, ...props }) {
|
|
1084
|
+
return /* @__PURE__ */ jsx(
|
|
1085
|
+
"div",
|
|
1086
|
+
{
|
|
1087
|
+
"data-slot": "card-title",
|
|
1088
|
+
className: cn("leading-none font-semibold", className),
|
|
1089
|
+
...props
|
|
1090
|
+
}
|
|
1091
|
+
);
|
|
1092
|
+
}
|
|
1093
|
+
function CardDescription({ className, ...props }) {
|
|
1094
|
+
return /* @__PURE__ */ jsx(
|
|
1095
|
+
"div",
|
|
1096
|
+
{
|
|
1097
|
+
"data-slot": "card-description",
|
|
1098
|
+
className: cn("text-muted-foreground text-sm", className),
|
|
1099
|
+
...props
|
|
1100
|
+
}
|
|
1101
|
+
);
|
|
1102
|
+
}
|
|
1103
|
+
function CardContent({ className, ...props }) {
|
|
1104
|
+
return /* @__PURE__ */ jsx(
|
|
1105
|
+
"div",
|
|
1106
|
+
{
|
|
1107
|
+
"data-slot": "card-content",
|
|
1108
|
+
className: cn("px-6", className),
|
|
1109
|
+
...props
|
|
1110
|
+
}
|
|
1111
|
+
);
|
|
1112
|
+
}
|
|
1113
|
+
function CardFooter({ className, ...props }) {
|
|
1114
|
+
return /* @__PURE__ */ jsx(
|
|
1115
|
+
"div",
|
|
1116
|
+
{
|
|
1117
|
+
"data-slot": "card-footer",
|
|
1118
|
+
className: cn("flex items-center px-6 [.border-t]:pt-6", className),
|
|
1119
|
+
...props
|
|
1120
|
+
}
|
|
1121
|
+
);
|
|
1122
|
+
}
|
|
1123
|
+
var badgeVariants = cva(
|
|
1124
|
+
"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",
|
|
1125
|
+
{
|
|
1126
|
+
variants: {
|
|
1127
|
+
variant: {
|
|
1128
|
+
default: "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
|
|
1129
|
+
secondary: "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
|
|
1130
|
+
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",
|
|
1131
|
+
outline: "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground"
|
|
1132
|
+
}
|
|
1133
|
+
},
|
|
1134
|
+
defaultVariants: {
|
|
1135
|
+
variant: "default"
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
);
|
|
1139
|
+
function Badge({
|
|
1140
|
+
className,
|
|
1141
|
+
variant,
|
|
1142
|
+
asChild = false,
|
|
1143
|
+
...props
|
|
1144
|
+
}) {
|
|
1145
|
+
const Comp = asChild ? Slot : "span";
|
|
1146
|
+
return /* @__PURE__ */ jsx(
|
|
1147
|
+
Comp,
|
|
1148
|
+
{
|
|
1149
|
+
"data-slot": "badge",
|
|
1150
|
+
className: cn(badgeVariants({ variant }), className),
|
|
1151
|
+
...props
|
|
1152
|
+
}
|
|
1153
|
+
);
|
|
1154
|
+
}
|
|
1155
|
+
function Popover({
|
|
1156
|
+
...props
|
|
1157
|
+
}) {
|
|
1158
|
+
return /* @__PURE__ */ jsx(PopoverPrimitive.Root, { "data-slot": "popover", ...props });
|
|
1159
|
+
}
|
|
1160
|
+
function PopoverTrigger({
|
|
1161
|
+
...props
|
|
1162
|
+
}) {
|
|
1163
|
+
return /* @__PURE__ */ jsx(PopoverPrimitive.Trigger, { "data-slot": "popover-trigger", ...props });
|
|
1164
|
+
}
|
|
1165
|
+
function PopoverContent({
|
|
1166
|
+
className,
|
|
1167
|
+
align = "center",
|
|
1168
|
+
sideOffset = 4,
|
|
1169
|
+
...props
|
|
1170
|
+
}) {
|
|
1171
|
+
return /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
|
|
1172
|
+
PopoverPrimitive.Content,
|
|
1173
|
+
{
|
|
1174
|
+
"data-slot": "popover-content",
|
|
1175
|
+
align,
|
|
1176
|
+
sideOffset,
|
|
1177
|
+
className: cn(
|
|
1178
|
+
"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",
|
|
1179
|
+
className
|
|
1180
|
+
),
|
|
1181
|
+
...props
|
|
1182
|
+
}
|
|
1183
|
+
) });
|
|
1184
|
+
}
|
|
1185
|
+
var DEFAULT_ICON_API_KEY = "au382bi7fsh96w9h9xlrnat2jglx";
|
|
1186
|
+
var DynamicIcon = React4.memo(function DynamicIcon2({
|
|
1187
|
+
apiKey,
|
|
1188
|
+
...props
|
|
1189
|
+
}) {
|
|
1190
|
+
return /* @__PURE__ */ jsx(Icon, { ...props, apiKey: apiKey ?? DEFAULT_ICON_API_KEY });
|
|
1191
|
+
});
|
|
1192
|
+
DynamicIcon.displayName = "DynamicIcon";
|
|
1193
|
+
function StarRating({
|
|
1194
|
+
rating,
|
|
1195
|
+
size = 18,
|
|
1196
|
+
className
|
|
1197
|
+
}) {
|
|
1198
|
+
return /* @__PURE__ */ jsx("div", { className: cn("flex items-center gap-0.5", className), children: [1, 2, 3, 4, 5].map((star) => /* @__PURE__ */ jsx(
|
|
1199
|
+
DynamicIcon,
|
|
1200
|
+
{
|
|
1201
|
+
name: "icon-park-solid/star",
|
|
1202
|
+
size,
|
|
1203
|
+
className: cn(
|
|
1204
|
+
star <= rating ? "fill-primary text-primary" : "fill-muted text-muted"
|
|
1205
|
+
)
|
|
1206
|
+
},
|
|
1207
|
+
star
|
|
1208
|
+
)) });
|
|
1209
|
+
}
|
|
1210
|
+
function normalizePhoneNumber(input) {
|
|
1211
|
+
const trimmed = input.trim();
|
|
1212
|
+
if (trimmed.toLowerCase().startsWith("tel:")) {
|
|
1213
|
+
return trimmed;
|
|
1214
|
+
}
|
|
1215
|
+
const match = trimmed.match(/^[\s\+\-\(\)]*(\d[\d\s\-\(\)\.]*\d)[\s\-]*(x|ext\.?|extension)?[\s\-]*(\d+)?$/i);
|
|
1216
|
+
if (match) {
|
|
1217
|
+
const mainNumber = match[1].replace(/[\s\-\(\)\.]/g, "");
|
|
1218
|
+
const extension = match[3];
|
|
1219
|
+
const normalized = mainNumber.length >= 10 && !trimmed.startsWith("+") ? `+${mainNumber}` : mainNumber;
|
|
1220
|
+
const withExtension = extension ? `${normalized};ext=${extension}` : normalized;
|
|
1221
|
+
return `tel:${withExtension}`;
|
|
1222
|
+
}
|
|
1223
|
+
const cleaned = trimmed.replace(/[\s\-\(\)\.]/g, "");
|
|
1224
|
+
return `tel:${cleaned}`;
|
|
1225
|
+
}
|
|
1226
|
+
function normalizeEmail(input) {
|
|
1227
|
+
const trimmed = input.trim();
|
|
1228
|
+
if (trimmed.toLowerCase().startsWith("mailto:")) {
|
|
1229
|
+
return trimmed;
|
|
1230
|
+
}
|
|
1231
|
+
return `mailto:${trimmed}`;
|
|
1232
|
+
}
|
|
1233
|
+
function isEmail(input) {
|
|
1234
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
1235
|
+
return emailRegex.test(input.trim());
|
|
1236
|
+
}
|
|
1237
|
+
function isPhoneNumber(input) {
|
|
1238
|
+
const trimmed = input.trim();
|
|
1239
|
+
if (trimmed.toLowerCase().startsWith("tel:")) {
|
|
1240
|
+
return true;
|
|
1241
|
+
}
|
|
1242
|
+
const phoneRegex = /^[\s\+\-\(\)]*\d[\d\s\-\(\)\.]*\d[\s\-]*(x|ext\.?|extension)?[\s\-]*\d*$/i;
|
|
1243
|
+
return phoneRegex.test(trimmed);
|
|
1244
|
+
}
|
|
1245
|
+
function isInternalUrl(href) {
|
|
1246
|
+
if (typeof window === "undefined") {
|
|
1247
|
+
return href.startsWith("/") && !href.startsWith("//");
|
|
1248
|
+
}
|
|
1249
|
+
const trimmed = href.trim();
|
|
1250
|
+
if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
|
|
1251
|
+
return true;
|
|
1252
|
+
}
|
|
1253
|
+
try {
|
|
1254
|
+
const url = new URL(trimmed, window.location.href);
|
|
1255
|
+
const currentOrigin = window.location.origin;
|
|
1256
|
+
const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
|
|
1257
|
+
return normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin);
|
|
1258
|
+
} catch {
|
|
1259
|
+
return false;
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
function toRelativePath(href) {
|
|
1263
|
+
if (typeof window === "undefined") {
|
|
1264
|
+
return href;
|
|
1265
|
+
}
|
|
1266
|
+
const trimmed = href.trim();
|
|
1267
|
+
if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
|
|
1268
|
+
return trimmed;
|
|
1269
|
+
}
|
|
1270
|
+
try {
|
|
1271
|
+
const url = new URL(trimmed, window.location.href);
|
|
1272
|
+
const currentOrigin = window.location.origin;
|
|
1273
|
+
const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
|
|
1274
|
+
if (normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin)) {
|
|
1275
|
+
return url.pathname + url.search + url.hash;
|
|
1276
|
+
}
|
|
1277
|
+
} catch {
|
|
1278
|
+
}
|
|
1279
|
+
return trimmed;
|
|
1280
|
+
}
|
|
1281
|
+
function useNavigation({
|
|
1282
|
+
href,
|
|
1283
|
+
onClick
|
|
1284
|
+
} = {}) {
|
|
1285
|
+
const linkType = React4.useMemo(() => {
|
|
1286
|
+
if (!href || href.trim() === "") {
|
|
1287
|
+
return onClick ? "none" : "none";
|
|
1288
|
+
}
|
|
1289
|
+
const trimmed = href.trim();
|
|
1290
|
+
if (trimmed.toLowerCase().startsWith("mailto:") || isEmail(trimmed)) {
|
|
1291
|
+
return "mailto";
|
|
1292
|
+
}
|
|
1293
|
+
if (trimmed.toLowerCase().startsWith("tel:") || isPhoneNumber(trimmed)) {
|
|
1294
|
+
return "tel";
|
|
1295
|
+
}
|
|
1296
|
+
if (isInternalUrl(trimmed)) {
|
|
1297
|
+
return "internal";
|
|
1298
|
+
}
|
|
1299
|
+
try {
|
|
1300
|
+
new URL(trimmed, typeof window !== "undefined" ? window.location.href : "http://localhost");
|
|
1301
|
+
return "external";
|
|
1302
|
+
} catch {
|
|
1303
|
+
return "internal";
|
|
1304
|
+
}
|
|
1305
|
+
}, [href, onClick]);
|
|
1306
|
+
const normalizedHref = React4.useMemo(() => {
|
|
1307
|
+
if (!href || href.trim() === "") {
|
|
1308
|
+
return void 0;
|
|
1309
|
+
}
|
|
1310
|
+
const trimmed = href.trim();
|
|
1311
|
+
switch (linkType) {
|
|
1312
|
+
case "tel":
|
|
1313
|
+
return normalizePhoneNumber(trimmed);
|
|
1314
|
+
case "mailto":
|
|
1315
|
+
return normalizeEmail(trimmed);
|
|
1316
|
+
case "internal":
|
|
1317
|
+
return toRelativePath(trimmed);
|
|
1318
|
+
case "external":
|
|
1319
|
+
return trimmed;
|
|
1320
|
+
default:
|
|
1321
|
+
return trimmed;
|
|
1322
|
+
}
|
|
1323
|
+
}, [href, linkType]);
|
|
1324
|
+
const target = React4.useMemo(() => {
|
|
1325
|
+
switch (linkType) {
|
|
1326
|
+
case "external":
|
|
1327
|
+
return "_blank";
|
|
1328
|
+
case "internal":
|
|
1329
|
+
return "_self";
|
|
1330
|
+
case "mailto":
|
|
1331
|
+
case "tel":
|
|
1332
|
+
return void 0;
|
|
1333
|
+
default:
|
|
1334
|
+
return void 0;
|
|
1335
|
+
}
|
|
1336
|
+
}, [linkType]);
|
|
1337
|
+
const rel = React4.useMemo(() => {
|
|
1338
|
+
if (linkType === "external") {
|
|
1339
|
+
return "noopener noreferrer";
|
|
2028
1340
|
}
|
|
1341
|
+
return void 0;
|
|
1342
|
+
}, [linkType]);
|
|
1343
|
+
const isExternal = linkType === "external";
|
|
1344
|
+
const isInternal = linkType === "internal";
|
|
1345
|
+
const shouldUseRouter = isInternal && typeof normalizedHref === "string" && normalizedHref.startsWith("/");
|
|
1346
|
+
const handleClick = React4.useCallback(
|
|
1347
|
+
(event) => {
|
|
1348
|
+
if (onClick) {
|
|
1349
|
+
try {
|
|
1350
|
+
onClick(event);
|
|
1351
|
+
} catch (error) {
|
|
1352
|
+
console.error("Error in user onClick handler:", error);
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
if (event.defaultPrevented) {
|
|
1356
|
+
return;
|
|
1357
|
+
}
|
|
1358
|
+
if (shouldUseRouter && normalizedHref && event.button === 0 && // left-click only
|
|
1359
|
+
!event.metaKey && !event.altKey && !event.ctrlKey && !event.shiftKey) {
|
|
1360
|
+
if (typeof window !== "undefined") {
|
|
1361
|
+
const handler = window.__opensiteNavigationHandler;
|
|
1362
|
+
if (typeof handler === "function") {
|
|
1363
|
+
try {
|
|
1364
|
+
const handled = handler(normalizedHref, event.nativeEvent || event);
|
|
1365
|
+
if (handled !== false) {
|
|
1366
|
+
event.preventDefault();
|
|
1367
|
+
}
|
|
1368
|
+
} catch (error) {
|
|
1369
|
+
console.error("Error in navigation handler:", error);
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
},
|
|
1375
|
+
[onClick, shouldUseRouter, normalizedHref]
|
|
2029
1376
|
);
|
|
1377
|
+
return {
|
|
1378
|
+
linkType,
|
|
1379
|
+
normalizedHref,
|
|
1380
|
+
target,
|
|
1381
|
+
rel,
|
|
1382
|
+
isExternal,
|
|
1383
|
+
isInternal,
|
|
1384
|
+
shouldUseRouter,
|
|
1385
|
+
handleClick
|
|
1386
|
+
};
|
|
2030
1387
|
}
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
1388
|
+
var Pressable = React4.forwardRef(
|
|
1389
|
+
({
|
|
1390
|
+
children,
|
|
1391
|
+
className,
|
|
1392
|
+
href,
|
|
1393
|
+
onClick,
|
|
1394
|
+
variant,
|
|
1395
|
+
size,
|
|
1396
|
+
asButton = false,
|
|
1397
|
+
fallbackComponentType = "span",
|
|
1398
|
+
componentType,
|
|
1399
|
+
"aria-label": ariaLabel,
|
|
1400
|
+
"aria-describedby": ariaDescribedby,
|
|
1401
|
+
id,
|
|
1402
|
+
...props
|
|
1403
|
+
}, ref) => {
|
|
1404
|
+
const navigation = useNavigation({ href, onClick });
|
|
1405
|
+
const {
|
|
1406
|
+
normalizedHref,
|
|
1407
|
+
target,
|
|
1408
|
+
rel,
|
|
1409
|
+
linkType,
|
|
1410
|
+
isInternal,
|
|
1411
|
+
handleClick
|
|
1412
|
+
} = navigation;
|
|
1413
|
+
const shouldRenderLink = normalizedHref && linkType !== "none";
|
|
1414
|
+
const shouldRenderButton = !shouldRenderLink && onClick;
|
|
1415
|
+
const effectiveComponentType = componentType || (shouldRenderLink ? "a" : shouldRenderButton ? "button" : fallbackComponentType);
|
|
1416
|
+
const finalComponentType = isInternal && shouldRenderLink ? "a" : effectiveComponentType;
|
|
1417
|
+
const shouldApplyButtonStyles = asButton || variant || size;
|
|
1418
|
+
const combinedClassName = cn(
|
|
1419
|
+
shouldApplyButtonStyles && buttonVariants({ variant, size }),
|
|
1420
|
+
className
|
|
1421
|
+
);
|
|
1422
|
+
const dataProps = Object.fromEntries(
|
|
1423
|
+
Object.entries(props).filter(([key]) => key.startsWith("data-"))
|
|
1424
|
+
);
|
|
1425
|
+
const buttonDataAttributes = shouldApplyButtonStyles ? {
|
|
1426
|
+
"data-slot": "button",
|
|
1427
|
+
"data-variant": variant ?? "default",
|
|
1428
|
+
"data-size": size ?? "default"
|
|
1429
|
+
} : {};
|
|
1430
|
+
const commonProps = {
|
|
1431
|
+
className: combinedClassName,
|
|
1432
|
+
onClick: handleClick,
|
|
1433
|
+
"aria-label": ariaLabel,
|
|
1434
|
+
"aria-describedby": ariaDescribedby,
|
|
1435
|
+
id,
|
|
1436
|
+
...dataProps,
|
|
1437
|
+
...buttonDataAttributes
|
|
1438
|
+
};
|
|
1439
|
+
if (finalComponentType === "a" && shouldRenderLink) {
|
|
1440
|
+
return /* @__PURE__ */ jsx(
|
|
1441
|
+
"a",
|
|
1442
|
+
{
|
|
1443
|
+
ref,
|
|
1444
|
+
href: normalizedHref,
|
|
1445
|
+
target,
|
|
1446
|
+
rel,
|
|
1447
|
+
...commonProps,
|
|
1448
|
+
...props,
|
|
1449
|
+
children
|
|
1450
|
+
}
|
|
1451
|
+
);
|
|
2038
1452
|
}
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
1453
|
+
if (finalComponentType === "button") {
|
|
1454
|
+
return /* @__PURE__ */ jsx(
|
|
1455
|
+
"button",
|
|
1456
|
+
{
|
|
1457
|
+
ref,
|
|
1458
|
+
type: props.type || "button",
|
|
1459
|
+
...commonProps,
|
|
1460
|
+
...props,
|
|
1461
|
+
children
|
|
1462
|
+
}
|
|
1463
|
+
);
|
|
2048
1464
|
}
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
1465
|
+
if (finalComponentType === "div") {
|
|
1466
|
+
return /* @__PURE__ */ jsx(
|
|
1467
|
+
"div",
|
|
1468
|
+
{
|
|
1469
|
+
ref,
|
|
1470
|
+
...commonProps,
|
|
1471
|
+
children
|
|
1472
|
+
}
|
|
1473
|
+
);
|
|
2058
1474
|
}
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
variant: {
|
|
2066
|
-
default: "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
|
|
2067
|
-
secondary: "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
|
|
2068
|
-
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",
|
|
2069
|
-
outline: "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground"
|
|
1475
|
+
return /* @__PURE__ */ jsx(
|
|
1476
|
+
"span",
|
|
1477
|
+
{
|
|
1478
|
+
ref,
|
|
1479
|
+
...commonProps,
|
|
1480
|
+
children
|
|
2070
1481
|
}
|
|
2071
|
-
|
|
2072
|
-
defaultVariants: {
|
|
2073
|
-
variant: "default"
|
|
2074
|
-
}
|
|
1482
|
+
);
|
|
2075
1483
|
}
|
|
2076
1484
|
);
|
|
2077
|
-
|
|
2078
|
-
className,
|
|
2079
|
-
variant,
|
|
2080
|
-
asChild = false,
|
|
2081
|
-
...props
|
|
2082
|
-
}) {
|
|
2083
|
-
const Comp = asChild ? Slot : "span";
|
|
2084
|
-
return /* @__PURE__ */ jsx(
|
|
2085
|
-
Comp,
|
|
2086
|
-
{
|
|
2087
|
-
"data-slot": "badge",
|
|
2088
|
-
className: cn(badgeVariants({ variant }), className),
|
|
2089
|
-
...props
|
|
2090
|
-
}
|
|
2091
|
-
);
|
|
2092
|
-
}
|
|
2093
|
-
function Popover({
|
|
2094
|
-
...props
|
|
2095
|
-
}) {
|
|
2096
|
-
return /* @__PURE__ */ jsx(PopoverPrimitive.Root, { "data-slot": "popover", ...props });
|
|
2097
|
-
}
|
|
2098
|
-
function PopoverTrigger({
|
|
2099
|
-
...props
|
|
2100
|
-
}) {
|
|
2101
|
-
return /* @__PURE__ */ jsx(PopoverPrimitive.Trigger, { "data-slot": "popover-trigger", ...props });
|
|
2102
|
-
}
|
|
2103
|
-
function PopoverContent({
|
|
2104
|
-
className,
|
|
2105
|
-
align = "center",
|
|
2106
|
-
sideOffset = 4,
|
|
2107
|
-
...props
|
|
2108
|
-
}) {
|
|
2109
|
-
return /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
|
|
2110
|
-
PopoverPrimitive.Content,
|
|
2111
|
-
{
|
|
2112
|
-
"data-slot": "popover-content",
|
|
2113
|
-
align,
|
|
2114
|
-
sideOffset,
|
|
2115
|
-
className: cn(
|
|
2116
|
-
"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",
|
|
2117
|
-
className
|
|
2118
|
-
),
|
|
2119
|
-
...props
|
|
2120
|
-
}
|
|
2121
|
-
) });
|
|
2122
|
-
}
|
|
2123
|
-
function StarRating({
|
|
2124
|
-
rating,
|
|
2125
|
-
size = 18,
|
|
2126
|
-
className
|
|
2127
|
-
}) {
|
|
2128
|
-
return /* @__PURE__ */ jsx("div", { className: cn("flex items-center gap-0.5", className), children: [1, 2, 3, 4, 5].map((star) => /* @__PURE__ */ jsx(
|
|
2129
|
-
DynamicIcon,
|
|
2130
|
-
{
|
|
2131
|
-
name: "icon-park-solid/star",
|
|
2132
|
-
size,
|
|
2133
|
-
className: cn(
|
|
2134
|
-
star <= rating ? "fill-primary text-primary" : "fill-muted text-muted"
|
|
2135
|
-
)
|
|
2136
|
-
},
|
|
2137
|
-
star
|
|
2138
|
-
)) });
|
|
2139
|
-
}
|
|
1485
|
+
Pressable.displayName = "Pressable";
|
|
2140
1486
|
var BUTTON_SIZES = {
|
|
2141
1487
|
sm: { buttonSize: "size-8", iconSize: 16 },
|
|
2142
1488
|
md: { buttonSize: "size-10", iconSize: 20 },
|
|
@@ -2228,7 +1574,7 @@ var platformIconMap = {
|
|
|
2228
1574
|
dribbble: "cib/dribbble",
|
|
2229
1575
|
unknown: "icon-park-solid/circular-connection"
|
|
2230
1576
|
};
|
|
2231
|
-
var SocialLinkIcon =
|
|
1577
|
+
var SocialLinkIcon = React4.forwardRef(
|
|
2232
1578
|
({
|
|
2233
1579
|
platformName,
|
|
2234
1580
|
label,
|
|
@@ -2242,16 +1588,16 @@ var SocialLinkIcon = React6.forwardRef(
|
|
|
2242
1588
|
...pressableProps
|
|
2243
1589
|
}, ref) => {
|
|
2244
1590
|
const platform = usePlatformFromUrl(href);
|
|
2245
|
-
const smartPlatformName =
|
|
1591
|
+
const smartPlatformName = React4.useMemo(() => {
|
|
2246
1592
|
return platform || platformName;
|
|
2247
1593
|
}, [platform, platformName]);
|
|
2248
|
-
const iconName =
|
|
1594
|
+
const iconName = React4.useMemo(() => {
|
|
2249
1595
|
return iconNameOverride || platformIconMap[smartPlatformName];
|
|
2250
1596
|
}, [iconNameOverride, smartPlatformName]);
|
|
2251
|
-
const accessibleLabel =
|
|
1597
|
+
const accessibleLabel = React4.useMemo(() => {
|
|
2252
1598
|
return label || platformName;
|
|
2253
1599
|
}, [label, platformName]);
|
|
2254
|
-
const icon =
|
|
1600
|
+
const icon = React4.useMemo(() => {
|
|
2255
1601
|
return /* @__PURE__ */ jsx(
|
|
2256
1602
|
DynamicIcon,
|
|
2257
1603
|
{
|
|
@@ -2331,12 +1677,12 @@ function TextInner({ as, className, children, ...props }, ref) {
|
|
|
2331
1677
|
const Component = as || "span";
|
|
2332
1678
|
return /* @__PURE__ */ jsx(Component, { ref, className: cn(className), ...props, children });
|
|
2333
1679
|
}
|
|
2334
|
-
var Text =
|
|
1680
|
+
var Text = React4.forwardRef(TextInner);
|
|
2335
1681
|
Text.displayName = "Text";
|
|
2336
1682
|
function isContentTextItem(item) {
|
|
2337
|
-
return item !== null && typeof item === "object" && !
|
|
1683
|
+
return item !== null && typeof item === "object" && !React4.isValidElement(item) && "_type" in item && item._type === "text";
|
|
2338
1684
|
}
|
|
2339
|
-
var ContentGroup =
|
|
1685
|
+
var ContentGroup = React4.forwardRef(
|
|
2340
1686
|
({ items, className, children, ...props }, ref) => {
|
|
2341
1687
|
const hasContent = items && items.length > 0;
|
|
2342
1688
|
if (!hasContent) {
|
|
@@ -2349,10 +1695,10 @@ var ContentGroup = React6.forwardRef(
|
|
|
2349
1695
|
return /* @__PURE__ */ jsx(Text, { ...textProps }, idx);
|
|
2350
1696
|
}
|
|
2351
1697
|
const reactNode = item;
|
|
2352
|
-
if (
|
|
2353
|
-
return
|
|
1698
|
+
if (React4.isValidElement(reactNode)) {
|
|
1699
|
+
return React4.cloneElement(reactNode, { key: reactNode.key ?? idx });
|
|
2354
1700
|
}
|
|
2355
|
-
return /* @__PURE__ */ jsx(
|
|
1701
|
+
return /* @__PURE__ */ jsx(React4.Fragment, { children: reactNode }, idx);
|
|
2356
1702
|
}),
|
|
2357
1703
|
children
|
|
2358
1704
|
] });
|
|
@@ -2877,7 +2223,7 @@ function AboutExpandableValues({
|
|
|
2877
2223
|
pattern,
|
|
2878
2224
|
patternOpacity
|
|
2879
2225
|
}) {
|
|
2880
|
-
const [expandedValue, setExpandedValue] =
|
|
2226
|
+
const [expandedValue, setExpandedValue] = React4.useState(null);
|
|
2881
2227
|
const toggleExpand = useCallback((id) => {
|
|
2882
2228
|
setExpandedValue((prev) => prev === id ? null : id);
|
|
2883
2229
|
}, []);
|
|
@@ -3113,7 +2459,7 @@ function CommunityInitiatives({
|
|
|
3113
2459
|
pattern,
|
|
3114
2460
|
patternOpacity
|
|
3115
2461
|
}) {
|
|
3116
|
-
const [activeCategory, setActiveCategory] =
|
|
2462
|
+
const [activeCategory, setActiveCategory] = React4.useState(
|
|
3117
2463
|
categories?.[0]?.id || ""
|
|
3118
2464
|
);
|
|
3119
2465
|
const currentCategory = categories?.find((category) => category.id === activeCategory) || categories?.[0];
|
|
@@ -3377,7 +2723,7 @@ function AboutCultureTabs({
|
|
|
3377
2723
|
patternOpacity
|
|
3378
2724
|
}) {
|
|
3379
2725
|
const resolvedAspects = aspects ?? [];
|
|
3380
|
-
const [activeTab, setActiveTab] =
|
|
2726
|
+
const [activeTab, setActiveTab] = React4.useState(
|
|
3381
2727
|
resolvedAspects[0]?.id || ""
|
|
3382
2728
|
);
|
|
3383
2729
|
const headerItems = useMemo(() => {
|
|
@@ -3910,7 +3256,7 @@ function BannerDeliveryCountdown({
|
|
|
3910
3256
|
}, [prefixText, timerContent, middleText, deliveryDateContent]);
|
|
3911
3257
|
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: [
|
|
3912
3258
|
iconContent,
|
|
3913
|
-
messageParts.length > 0 && /* @__PURE__ */ jsx("span", { children: messageParts.map((part, index) => /* @__PURE__ */ jsxs(
|
|
3259
|
+
messageParts.length > 0 && /* @__PURE__ */ jsx("span", { children: messageParts.map((part, index) => /* @__PURE__ */ jsxs(React4.Fragment, { children: [
|
|
3914
3260
|
index > 0 ? " " : null,
|
|
3915
3261
|
part
|
|
3916
3262
|
] }, index)) })
|
|
@@ -5181,8 +4527,8 @@ var BrandAttribution = ({
|
|
|
5181
4527
|
}
|
|
5182
4528
|
const { prefix = "", anchorText, href, suffix = "" } = options[optionIndex];
|
|
5183
4529
|
const ContainerEl = variant;
|
|
5184
|
-
const [trackedHref, setTrackedHref] =
|
|
5185
|
-
|
|
4530
|
+
const [trackedHref, setTrackedHref] = React4.useState(href);
|
|
4531
|
+
React4.useEffect(() => {
|
|
5186
4532
|
setTrackedHref(buildTrackedHref(href));
|
|
5187
4533
|
}, [href]);
|
|
5188
4534
|
return /* @__PURE__ */ jsxs(ContainerEl, { className: containerClassName, children: [
|
|
@@ -5302,7 +4648,7 @@ function FooterSocialNewsletter({
|
|
|
5302
4648
|
patternOpacity,
|
|
5303
4649
|
optixFlowConfig
|
|
5304
4650
|
}) {
|
|
5305
|
-
const renderForm =
|
|
4651
|
+
const renderForm = React4.useMemo(() => {
|
|
5306
4652
|
if (!formEngineSetup) return null;
|
|
5307
4653
|
const action = {
|
|
5308
4654
|
variant: "default",
|
|
@@ -5591,7 +4937,7 @@ function FooterSimpleCentered({
|
|
|
5591
4937
|
]);
|
|
5592
4938
|
const bottomLinksContent = useMemo(() => {
|
|
5593
4939
|
if (!bottomLinks || bottomLinks.length === 0) return null;
|
|
5594
|
-
return bottomLinks.map((link, idx) => /* @__PURE__ */ jsx(
|
|
4940
|
+
return bottomLinks.map((link, idx) => /* @__PURE__ */ jsx(React4.Fragment, { children: /* @__PURE__ */ jsx(
|
|
5595
4941
|
Pressable,
|
|
5596
4942
|
{
|
|
5597
4943
|
href: link.href,
|
|
@@ -6938,7 +6284,7 @@ function FooterNewsletterMinimal({
|
|
|
6938
6284
|
buttonAction,
|
|
6939
6285
|
formSlot
|
|
6940
6286
|
}) {
|
|
6941
|
-
const navLinksContent =
|
|
6287
|
+
const navLinksContent = React4.useMemo(() => {
|
|
6942
6288
|
if (!navLinks || navLinks.length === 0) return null;
|
|
6943
6289
|
return navLinks.map((item, idx) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
|
|
6944
6290
|
Pressable,
|
|
@@ -6949,7 +6295,7 @@ function FooterNewsletterMinimal({
|
|
|
6949
6295
|
}
|
|
6950
6296
|
) }, idx));
|
|
6951
6297
|
}, [navLinks, navLinkClassName]);
|
|
6952
|
-
const socialLinksContent =
|
|
6298
|
+
const socialLinksContent = React4.useMemo(() => {
|
|
6953
6299
|
if (!socialLinks || socialLinks.length === 0) return null;
|
|
6954
6300
|
return socialLinks.map((item, idx) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
|
|
6955
6301
|
SocialLinkIcon,
|
|
@@ -6965,7 +6311,7 @@ function FooterNewsletterMinimal({
|
|
|
6965
6311
|
}
|
|
6966
6312
|
) }, idx));
|
|
6967
6313
|
}, [socialLinks, socialLinkClassName]);
|
|
6968
|
-
const footerLinksContent =
|
|
6314
|
+
const footerLinksContent = React4.useMemo(() => {
|
|
6969
6315
|
if (!footerLinks || footerLinks.length === 0) return null;
|
|
6970
6316
|
return footerLinks.map((item) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
|
|
6971
6317
|
Pressable,
|
|
@@ -6979,7 +6325,7 @@ function FooterNewsletterMinimal({
|
|
|
6979
6325
|
}
|
|
6980
6326
|
) }, item.label));
|
|
6981
6327
|
}, [footerLinks, footerLinkClassName]);
|
|
6982
|
-
const renderForm =
|
|
6328
|
+
const renderForm = React4.useMemo(() => {
|
|
6983
6329
|
if (formSlot) return formSlot;
|
|
6984
6330
|
if (!formEngineSetup) return null;
|
|
6985
6331
|
const defaultButtonAction = {
|
|
@@ -7526,4 +6872,4 @@ function FooterNavSocial({
|
|
|
7526
6872
|
);
|
|
7527
6873
|
}
|
|
7528
6874
|
|
|
7529
|
-
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,
|
|
6875
|
+
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 };
|