@opensite/ui 2.8.7 → 2.8.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/about-culture-tabs.cjs +174 -174
- package/dist/about-culture-tabs.js +174 -174
- package/dist/about-developer-profile.cjs +200 -200
- package/dist/about-developer-profile.js +198 -198
- package/dist/about-developer-story.cjs +142 -142
- package/dist/about-developer-story.js +142 -142
- package/dist/about-mission-dual-image.cjs +142 -142
- package/dist/about-mission-dual-image.js +142 -142
- package/dist/about-mission-features.cjs +142 -142
- package/dist/about-mission-features.js +142 -142
- package/dist/about-network-spotlight.cjs +142 -142
- package/dist/about-network-spotlight.js +142 -142
- package/dist/about-story-expertise.cjs +142 -142
- package/dist/about-story-expertise.js +142 -142
- package/dist/about-streamline-team.cjs +142 -142
- package/dist/about-streamline-team.js +142 -142
- package/dist/carousel-icon-sidebar.cjs +5 -4
- package/dist/carousel-icon-sidebar.js +5 -4
- package/dist/community-initiatives.cjs +142 -142
- package/dist/community-initiatives.js +142 -142
- package/dist/components.cjs +723 -1364
- package/dist/components.d.cts +0 -2
- package/dist/components.d.ts +0 -2
- package/dist/components.js +633 -1273
- package/dist/contact-map.cjs +14 -1069
- package/dist/contact-map.d.cts +13 -3
- package/dist/contact-map.d.ts +13 -3
- package/dist/contact-map.js +14 -1069
- package/dist/cta-feature-checklist.cjs +142 -142
- package/dist/cta-feature-checklist.js +142 -142
- package/dist/faq-numbered-grid.cjs +142 -142
- package/dist/faq-numbered-grid.js +142 -142
- package/dist/feature-animated-carousel.cjs +142 -142
- package/dist/feature-animated-carousel.js +142 -142
- package/dist/feature-bento-utilities.cjs +142 -142
- package/dist/feature-bento-utilities.js +142 -142
- package/dist/feature-capabilities-grid.cjs +142 -142
- package/dist/feature-capabilities-grid.js +142 -142
- package/dist/feature-category-image-cards.cjs +142 -142
- package/dist/feature-category-image-cards.js +142 -142
- package/dist/feature-icon-grid-bordered.cjs +142 -142
- package/dist/feature-icon-grid-bordered.js +142 -142
- package/dist/feature-icon-grid-muted.cjs +142 -142
- package/dist/feature-icon-grid-muted.js +142 -142
- package/dist/feature-numbered-cards.cjs +142 -142
- package/dist/feature-numbered-cards.js +142 -142
- package/dist/feature-three-column-values.cjs +142 -142
- package/dist/feature-three-column-values.js +142 -142
- package/dist/hero-ad-campaign-expert.cjs +142 -142
- package/dist/hero-ad-campaign-expert.js +142 -142
- package/dist/hero-adaptable-product-grid.cjs +142 -142
- package/dist/hero-adaptable-product-grid.js +142 -142
- package/dist/hero-agency-animated-images.cjs +142 -142
- package/dist/hero-agency-animated-images.js +142 -142
- package/dist/hero-announcement-badge.cjs +142 -142
- package/dist/hero-announcement-badge.js +142 -142
- package/dist/hero-badge-image-split.cjs +142 -142
- package/dist/hero-badge-image-split.js +142 -142
- package/dist/hero-business-carousel-dots.cjs +142 -142
- package/dist/hero-business-carousel-dots.js +142 -142
- package/dist/hero-business-operations-mosaic.cjs +142 -142
- package/dist/hero-business-operations-mosaic.js +142 -142
- package/dist/hero-conversation-intelligence.cjs +142 -142
- package/dist/hero-conversation-intelligence.js +142 -142
- package/dist/hero-creative-studio-stacked.cjs +142 -142
- package/dist/hero-creative-studio-stacked.js +142 -142
- package/dist/hero-crm-streamlined.cjs +142 -142
- package/dist/hero-crm-streamlined.js +142 -142
- package/dist/hero-customer-support-layered.cjs +142 -142
- package/dist/hero-customer-support-layered.js +142 -142
- package/dist/hero-design-showcase-logos.cjs +142 -142
- package/dist/hero-design-showcase-logos.js +142 -142
- package/dist/hero-design-system-3d.cjs +142 -142
- package/dist/hero-design-system-3d.js +142 -142
- package/dist/hero-developer-tools-code.cjs +142 -142
- package/dist/hero-developer-tools-code.js +142 -142
- package/dist/hero-digital-agency-fullscreen.cjs +142 -142
- package/dist/hero-digital-agency-fullscreen.js +142 -142
- package/dist/hero-ecommerce-product-showcase.cjs +174 -174
- package/dist/hero-ecommerce-product-showcase.js +174 -174
- package/dist/hero-event-registration.cjs +142 -142
- package/dist/hero-event-registration.js +142 -142
- package/dist/hero-fullscreen-background-image.cjs +142 -142
- package/dist/hero-fullscreen-background-image.js +142 -142
- package/dist/hero-gradient-avatars-rating.cjs +142 -142
- package/dist/hero-gradient-avatars-rating.js +142 -142
- package/dist/hero-gradient-client-focused.cjs +142 -142
- package/dist/hero-gradient-client-focused.js +142 -142
- package/dist/hero-hiring-animated-text.cjs +142 -142
- package/dist/hero-hiring-animated-text.js +142 -142
- package/dist/hero-image-left-content.cjs +142 -142
- package/dist/hero-image-left-content.js +142 -142
- package/dist/hero-innovation-image-grid.cjs +142 -142
- package/dist/hero-innovation-image-grid.js +142 -142
- package/dist/hero-mental-health-team.cjs +142 -142
- package/dist/hero-mental-health-team.js +142 -142
- package/dist/hero-minimal-centered-dark.cjs +174 -174
- package/dist/hero-minimal-centered-dark.js +174 -174
- package/dist/hero-presentation-platform-video.cjs +142 -142
- package/dist/hero-presentation-platform-video.js +142 -142
- package/dist/hero-product-showcase-floating.cjs +174 -174
- package/dist/hero-product-showcase-floating.js +174 -174
- package/dist/hero-shared-inbox-layered.cjs +142 -142
- package/dist/hero-shared-inbox-layered.js +142 -142
- package/dist/hero-software-growth-video-dialog.cjs +142 -142
- package/dist/hero-software-growth-video-dialog.js +142 -142
- package/dist/hero-spiral-pattern-cards.cjs +174 -174
- package/dist/hero-spiral-pattern-cards.js +174 -174
- package/dist/hero-split-geometric-shapes.cjs +142 -142
- package/dist/hero-split-geometric-shapes.js +142 -142
- package/dist/hero-startup-launch-cta.cjs +174 -174
- package/dist/hero-startup-launch-cta.js +174 -174
- package/dist/hero-stats-social-proof.cjs +174 -174
- package/dist/hero-stats-social-proof.js +174 -174
- package/dist/hero-task-timer-animated.cjs +142 -142
- package/dist/hero-task-timer-animated.js +142 -142
- package/dist/hero-testimonial-image-grid.cjs +142 -142
- package/dist/hero-testimonial-image-grid.js +142 -142
- package/dist/hero-therapy-testimonial-grid.cjs +142 -142
- package/dist/hero-therapy-testimonial-grid.js +142 -142
- package/dist/hero-ui-library-showcase.cjs +142 -142
- package/dist/hero-ui-library-showcase.js +142 -142
- package/dist/hero-video-background-dark.cjs +174 -174
- package/dist/hero-video-background-dark.js +174 -174
- package/dist/hero-video-dialog-gradient.cjs +142 -142
- package/dist/hero-video-dialog-gradient.js +142 -142
- package/dist/hero-video-overlay-stars.cjs +142 -142
- package/dist/hero-video-overlay-stars.js +142 -142
- package/dist/hero-welcome-asymmetric-images.cjs +142 -142
- package/dist/hero-welcome-asymmetric-images.js +142 -142
- package/dist/index.cjs +725 -1366
- package/dist/index.d.cts +0 -2
- package/dist/index.d.ts +0 -2
- package/dist/index.js +634 -1274
- package/dist/registry.cjs +2371 -2915
- package/dist/registry.js +1120 -1664
- package/dist/testimonials-large-quote.cjs +74 -43
- package/dist/testimonials-large-quote.d.cts +5 -1
- package/dist/testimonials-large-quote.d.ts +5 -1
- package/dist/testimonials-large-quote.js +74 -43
- package/dist/testimonials-logo-cards.cjs +8 -2
- package/dist/testimonials-logo-cards.js +8 -2
- package/dist/testimonials-masonry-grid.cjs +486 -69
- package/dist/testimonials-masonry-grid.d.cts +5 -1
- package/dist/testimonials-masonry-grid.d.ts +5 -1
- package/dist/testimonials-masonry-grid.js +483 -63
- package/dist/testimonials-mini-dividers.cjs +2 -3
- package/dist/testimonials-mini-dividers.js +2 -3
- package/dist/testimonials-minimal-numbered.cjs +5 -4
- package/dist/testimonials-minimal-numbered.js +5 -4
- package/dist/testimonials-parallax-number.cjs +5 -4
- package/dist/testimonials-parallax-number.js +5 -4
- package/dist/testimonials-scrolling-columns.cjs +7 -12
- package/dist/testimonials-scrolling-columns.js +7 -12
- package/dist/testimonials-stats-header.cjs +528 -87
- package/dist/testimonials-stats-header.d.cts +39 -3
- package/dist/testimonials-stats-header.d.ts +39 -3
- package/dist/testimonials-stats-header.js +523 -82
- package/package.json +4 -7
- package/dist/geo-map.cjs +0 -1103
- package/dist/geo-map.d.cts +0 -92
- package/dist/geo-map.d.ts +0 -92
- package/dist/geo-map.js +0 -1081
package/dist/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,1130 +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
|
-
const activeMediaItem = mediaItems[activeItemIndex];
|
|
961
|
-
const mediaType = resolveMediaType(activeMediaItem);
|
|
962
|
-
return /* @__PURE__ */ jsxs("div", { className: "relative border-b border-border/60 bg-muted/40", children: [
|
|
963
|
-
/* @__PURE__ */ jsx("div", { className: "relative h-44 w-full overflow-hidden", children: mediaType === "video" ? /* @__PURE__ */ jsx(
|
|
964
|
-
"video",
|
|
965
|
-
{
|
|
966
|
-
className: "h-full w-full object-cover",
|
|
967
|
-
controls: true,
|
|
968
|
-
preload: "metadata",
|
|
969
|
-
poster: activeMediaItem.poster,
|
|
970
|
-
children: /* @__PURE__ */ jsx("source", { src: activeMediaItem.src })
|
|
971
|
-
}
|
|
972
|
-
) : /* @__PURE__ */ jsx(
|
|
973
|
-
Img,
|
|
974
|
-
{
|
|
975
|
-
src: activeMediaItem.src,
|
|
976
|
-
alt: activeMediaItem.alt ?? "Map marker media",
|
|
977
|
-
className: "h-full w-full object-cover",
|
|
978
|
-
loading: "eager",
|
|
979
|
-
optixFlowConfig
|
|
980
|
-
}
|
|
981
|
-
) }),
|
|
982
|
-
totalItems > 1 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
983
|
-
/* @__PURE__ */ jsx(
|
|
984
|
-
"button",
|
|
985
|
-
{
|
|
986
|
-
type: "button",
|
|
987
|
-
"aria-label": "Show previous media",
|
|
988
|
-
className: "absolute left-2 top-1/2 inline-flex size-8 -translate-y-1/2 items-center justify-center rounded-full bg-card text-card-foreground shadow-sm transition hover:bg-muted hover:text-muted-foreground",
|
|
989
|
-
onClick: () => {
|
|
990
|
-
setActiveIndex(
|
|
991
|
-
(current) => (current - 1 + totalItems) % totalItems
|
|
992
|
-
);
|
|
993
|
-
},
|
|
994
|
-
children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/arrow-left", size: 16 })
|
|
995
|
-
}
|
|
996
|
-
),
|
|
997
|
-
/* @__PURE__ */ jsx(
|
|
998
|
-
"button",
|
|
999
|
-
{
|
|
1000
|
-
type: "button",
|
|
1001
|
-
"aria-label": "Show next media",
|
|
1002
|
-
className: "absolute right-2 top-1/2 inline-flex h-8 w-8 -translate-y-1/2 items-center justify-center rounded-full bg-card text-card-foreground shadow-sm transition hover:bg-muted hover:text-muted-foreground",
|
|
1003
|
-
onClick: () => {
|
|
1004
|
-
setActiveIndex((current) => (current + 1) % totalItems);
|
|
1005
|
-
},
|
|
1006
|
-
children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/arrow-right", size: 16 })
|
|
1007
|
-
}
|
|
1008
|
-
),
|
|
1009
|
-
/* @__PURE__ */ jsx("div", { className: "absolute bottom-2 left-1/2 flex -translate-x-1/2 items-center gap-1.5", children: mediaItems.map((item, index) => /* @__PURE__ */ jsx(
|
|
1010
|
-
"button",
|
|
1011
|
-
{
|
|
1012
|
-
type: "button",
|
|
1013
|
-
"aria-label": `Show media item ${index + 1}`,
|
|
1014
|
-
className: cn(
|
|
1015
|
-
"h-2 rounded-full transition-all",
|
|
1016
|
-
index === activeItemIndex ? "w-6 bg-card" : "w-2 bg-card opacity-50 hover:opacity-100"
|
|
1017
|
-
),
|
|
1018
|
-
onClick: () => setActiveIndex(index)
|
|
1019
|
-
},
|
|
1020
|
-
normalizeId(item.id, `media-dot-${index}`)
|
|
1021
|
-
)) })
|
|
1022
|
-
] }) : null
|
|
1023
|
-
] });
|
|
1024
|
-
}
|
|
1025
|
-
function getMarkerTitle(marker, markerIndex) {
|
|
1026
|
-
if (marker.title !== void 0 && marker.title !== null) {
|
|
1027
|
-
return marker.title;
|
|
1028
|
-
}
|
|
1029
|
-
if (marker.label !== void 0 && marker.label !== null) {
|
|
1030
|
-
return marker.label;
|
|
1031
|
-
}
|
|
1032
|
-
return `Location ${markerIndex + 1}`;
|
|
1033
|
-
}
|
|
1034
|
-
function GeoMap({
|
|
1035
|
-
className,
|
|
1036
|
-
mapWrapperClassName,
|
|
1037
|
-
mapClassName,
|
|
1038
|
-
panelClassName,
|
|
1039
|
-
panelPosition = "top-left",
|
|
1040
|
-
stadiaApiKey = "",
|
|
1041
|
-
mapStyle = "osm-bright",
|
|
1042
|
-
styleUrl,
|
|
1043
|
-
mapLibreCssHref,
|
|
1044
|
-
markers = [],
|
|
1045
|
-
clusters = [],
|
|
1046
|
-
viewState,
|
|
1047
|
-
defaultViewState,
|
|
1048
|
-
onViewStateChange,
|
|
1049
|
-
onMapClick,
|
|
1050
|
-
onMarkerDrag,
|
|
1051
|
-
showNavigationControl = true,
|
|
1052
|
-
showGeolocateControl = false,
|
|
1053
|
-
navigationControlPosition = "top-right",
|
|
1054
|
-
geolocateControlPosition = "top-left",
|
|
1055
|
-
flyToOptions,
|
|
1056
|
-
markerFocusZoom = 14,
|
|
1057
|
-
clusterFocusZoom = 5,
|
|
1058
|
-
selectedMarkerId,
|
|
1059
|
-
initialSelectedMarkerId,
|
|
1060
|
-
onSelectionChange,
|
|
1061
|
-
clearSelectionOnMapClick = true,
|
|
1062
|
-
mapChildren,
|
|
1063
|
-
optixFlowConfig
|
|
1064
|
-
}) {
|
|
1065
|
-
const normalizedStandaloneMarkers = React6.useMemo(
|
|
1066
|
-
() => markers.map((marker, index) => ({
|
|
1067
|
-
...marker,
|
|
1068
|
-
id: normalizeId(marker.id, `marker-${index}`)
|
|
1069
|
-
})),
|
|
1070
|
-
[markers]
|
|
1071
|
-
);
|
|
1072
|
-
const normalizedClusters = React6.useMemo(() => {
|
|
1073
|
-
const results = [];
|
|
1074
|
-
clusters.forEach((cluster, clusterIndex) => {
|
|
1075
|
-
const clusterId = normalizeId(cluster.id, `cluster-${clusterIndex}`);
|
|
1076
|
-
const normalizedClusterMarkers = cluster.markers.map(
|
|
1077
|
-
(marker, markerIndex) => ({
|
|
1078
|
-
...marker,
|
|
1079
|
-
id: normalizeId(marker.id, `${clusterId}-marker-${markerIndex}`),
|
|
1080
|
-
clusterId
|
|
1081
|
-
})
|
|
1082
|
-
);
|
|
1083
|
-
const clusterCenter = cluster.latitude !== void 0 && cluster.longitude !== void 0 ? { latitude: cluster.latitude, longitude: cluster.longitude } : buildClusterCenter(normalizedClusterMarkers);
|
|
1084
|
-
if (!clusterCenter) {
|
|
1085
|
-
return;
|
|
1086
|
-
}
|
|
1087
|
-
results.push({
|
|
1088
|
-
...cluster,
|
|
1089
|
-
id: clusterId,
|
|
1090
|
-
latitude: clusterCenter.latitude,
|
|
1091
|
-
longitude: clusterCenter.longitude,
|
|
1092
|
-
markers: normalizedClusterMarkers
|
|
1093
|
-
});
|
|
1094
|
-
});
|
|
1095
|
-
return results;
|
|
1096
|
-
}, [clusters]);
|
|
1097
|
-
const markerLookup = React6.useMemo(() => {
|
|
1098
|
-
const lookup = /* @__PURE__ */ new Map();
|
|
1099
|
-
normalizedStandaloneMarkers.forEach((marker) => {
|
|
1100
|
-
lookup.set(marker.id, marker);
|
|
1101
|
-
});
|
|
1102
|
-
normalizedClusters.forEach((cluster) => {
|
|
1103
|
-
cluster.markers.forEach((marker) => {
|
|
1104
|
-
lookup.set(marker.id, marker);
|
|
1105
|
-
});
|
|
1106
|
-
});
|
|
1107
|
-
return lookup;
|
|
1108
|
-
}, [normalizedClusters, normalizedStandaloneMarkers]);
|
|
1109
|
-
const clusterLookup = React6.useMemo(() => {
|
|
1110
|
-
const lookup = /* @__PURE__ */ new Map();
|
|
1111
|
-
normalizedClusters.forEach((cluster) => {
|
|
1112
|
-
lookup.set(cluster.id, cluster);
|
|
1113
|
-
});
|
|
1114
|
-
return lookup;
|
|
1115
|
-
}, [normalizedClusters]);
|
|
1116
|
-
const firstCoordinate = React6.useMemo(() => {
|
|
1117
|
-
if (normalizedStandaloneMarkers.length > 0) {
|
|
1118
|
-
const firstStandaloneMarker = normalizedStandaloneMarkers[0];
|
|
1119
|
-
return {
|
|
1120
|
-
latitude: firstStandaloneMarker.latitude,
|
|
1121
|
-
longitude: firstStandaloneMarker.longitude
|
|
1122
|
-
};
|
|
1123
|
-
}
|
|
1124
|
-
if (normalizedClusters.length > 0) {
|
|
1125
|
-
const firstCluster = normalizedClusters[0];
|
|
1126
|
-
return {
|
|
1127
|
-
latitude: firstCluster.latitude,
|
|
1128
|
-
longitude: firstCluster.longitude
|
|
1129
|
-
};
|
|
1130
|
-
}
|
|
1131
|
-
return {
|
|
1132
|
-
latitude: DEFAULT_VIEW_STATE.latitude,
|
|
1133
|
-
longitude: DEFAULT_VIEW_STATE.longitude
|
|
1134
|
-
};
|
|
1135
|
-
}, [normalizedClusters, normalizedStandaloneMarkers]);
|
|
1136
|
-
const [uncontrolledViewState, setUncontrolledViewState] = React6.useState({
|
|
1137
|
-
latitude: defaultViewState?.latitude ?? firstCoordinate.latitude,
|
|
1138
|
-
longitude: defaultViewState?.longitude ?? firstCoordinate.longitude,
|
|
1139
|
-
zoom: defaultViewState?.zoom ?? DEFAULT_VIEW_STATE.zoom
|
|
1140
|
-
});
|
|
1141
|
-
const isControlledViewState = viewState !== void 0;
|
|
1142
|
-
const resolvedViewState = isControlledViewState ? viewState : uncontrolledViewState;
|
|
1143
|
-
const applyViewState = React6.useCallback(
|
|
1144
|
-
(nextState) => {
|
|
1145
|
-
if (!isControlledViewState) {
|
|
1146
|
-
setUncontrolledViewState((current) => {
|
|
1147
|
-
const next = { ...current, ...nextState };
|
|
1148
|
-
const hasChanged = current.latitude !== next.latitude || current.longitude !== next.longitude || current.zoom !== next.zoom;
|
|
1149
|
-
return hasChanged ? next : current;
|
|
1150
|
-
});
|
|
1151
|
-
}
|
|
1152
|
-
onViewStateChange?.(nextState);
|
|
1153
|
-
},
|
|
1154
|
-
[isControlledViewState, onViewStateChange]
|
|
1155
|
-
);
|
|
1156
|
-
const [selection, setSelection] = React6.useState(() => {
|
|
1157
|
-
if (initialSelectedMarkerId !== void 0 && initialSelectedMarkerId !== null) {
|
|
1158
|
-
return {
|
|
1159
|
-
type: "marker",
|
|
1160
|
-
markerId: String(initialSelectedMarkerId)
|
|
1161
|
-
};
|
|
1162
|
-
}
|
|
1163
|
-
return { type: "none" };
|
|
1164
|
-
});
|
|
1165
|
-
React6.useEffect(() => {
|
|
1166
|
-
if (selectedMarkerId === void 0 || selectedMarkerId === null) {
|
|
1167
|
-
return;
|
|
1168
|
-
}
|
|
1169
|
-
setSelection({
|
|
1170
|
-
type: "marker",
|
|
1171
|
-
markerId: String(selectedMarkerId)
|
|
1172
|
-
});
|
|
1173
|
-
}, [selectedMarkerId]);
|
|
1174
|
-
const selectedMarker = selection.markerId ? markerLookup.get(selection.markerId) : void 0;
|
|
1175
|
-
const selectedCluster = selection.clusterId ? clusterLookup.get(selection.clusterId) : void 0;
|
|
1176
|
-
React6.useEffect(() => {
|
|
1177
|
-
if (selection.type === "marker" && selection.markerId && !selectedMarker) {
|
|
1178
|
-
setSelection({ type: "none" });
|
|
1179
|
-
onSelectionChange?.({ type: "none" });
|
|
1180
|
-
}
|
|
1181
|
-
}, [onSelectionChange, selectedMarker, selection]);
|
|
1182
|
-
const emitSelectionChange = React6.useCallback(
|
|
1183
|
-
(nextSelection) => {
|
|
1184
|
-
if (nextSelection.type === "none") {
|
|
1185
|
-
onSelectionChange?.({ type: "none" });
|
|
1186
|
-
return;
|
|
1187
|
-
}
|
|
1188
|
-
if (nextSelection.type === "marker") {
|
|
1189
|
-
const parentCluster = nextSelection.marker.clusterId ? clusterLookup.get(nextSelection.marker.clusterId) : void 0;
|
|
1190
|
-
onSelectionChange?.({
|
|
1191
|
-
type: "marker",
|
|
1192
|
-
marker: nextSelection.marker,
|
|
1193
|
-
cluster: parentCluster
|
|
1194
|
-
});
|
|
1195
|
-
return;
|
|
1196
|
-
}
|
|
1197
|
-
onSelectionChange?.({
|
|
1198
|
-
type: "cluster",
|
|
1199
|
-
cluster: nextSelection.cluster
|
|
1200
|
-
});
|
|
1201
|
-
},
|
|
1202
|
-
[clusterLookup, onSelectionChange]
|
|
1203
|
-
);
|
|
1204
|
-
const selectMarker = React6.useCallback(
|
|
1205
|
-
(marker) => {
|
|
1206
|
-
setSelection({
|
|
1207
|
-
type: "marker",
|
|
1208
|
-
markerId: marker.id,
|
|
1209
|
-
clusterId: marker.clusterId
|
|
1210
|
-
});
|
|
1211
|
-
applyViewState({
|
|
1212
|
-
latitude: marker.latitude,
|
|
1213
|
-
longitude: marker.longitude,
|
|
1214
|
-
zoom: markerFocusZoom
|
|
1215
|
-
});
|
|
1216
|
-
emitSelectionChange({ type: "marker", marker });
|
|
1217
|
-
},
|
|
1218
|
-
[applyViewState, emitSelectionChange, markerFocusZoom]
|
|
1219
|
-
);
|
|
1220
|
-
const selectCluster = React6.useCallback(
|
|
1221
|
-
(cluster) => {
|
|
1222
|
-
setSelection({
|
|
1223
|
-
type: "cluster",
|
|
1224
|
-
clusterId: cluster.id
|
|
1225
|
-
});
|
|
1226
|
-
applyViewState({
|
|
1227
|
-
latitude: cluster.latitude,
|
|
1228
|
-
longitude: cluster.longitude,
|
|
1229
|
-
zoom: clusterFocusZoom
|
|
1230
|
-
});
|
|
1231
|
-
emitSelectionChange({ type: "cluster", cluster });
|
|
1232
|
-
},
|
|
1233
|
-
[applyViewState, clusterFocusZoom, emitSelectionChange]
|
|
1234
|
-
);
|
|
1235
|
-
const clearSelection = React6.useCallback(() => {
|
|
1236
|
-
setSelection({ type: "none" });
|
|
1237
|
-
emitSelectionChange({ type: "none" });
|
|
1238
|
-
}, [emitSelectionChange]);
|
|
1239
|
-
const mapMarkers = React6.useMemo(() => {
|
|
1240
|
-
const resolvedMarkers = [];
|
|
1241
|
-
normalizedClusters.forEach((cluster) => {
|
|
1242
|
-
const isSelected = selection.type === "cluster" && selection.clusterId === cluster.id;
|
|
1243
|
-
resolvedMarkers.push({
|
|
1244
|
-
id: `cluster-pin:${cluster.id}`,
|
|
1245
|
-
latitude: cluster.latitude,
|
|
1246
|
-
longitude: cluster.longitude,
|
|
1247
|
-
element: () => {
|
|
1248
|
-
const customMarkerElement = cluster.markerElement;
|
|
1249
|
-
const markerBody = typeof customMarkerElement === "function" ? customMarkerElement({
|
|
1250
|
-
isSelected,
|
|
1251
|
-
count: cluster.markers.length
|
|
1252
|
-
}) : customMarkerElement;
|
|
1253
|
-
return /* @__PURE__ */ jsx(
|
|
1254
|
-
"button",
|
|
1255
|
-
{
|
|
1256
|
-
type: "button",
|
|
1257
|
-
className: "group cursor-pointer",
|
|
1258
|
-
onClick: (event) => {
|
|
1259
|
-
event.preventDefault();
|
|
1260
|
-
event.stopPropagation();
|
|
1261
|
-
selectCluster(cluster);
|
|
1262
|
-
},
|
|
1263
|
-
"aria-label": `View ${cluster.markers.length} clustered locations`,
|
|
1264
|
-
children: markerBody ?? /* @__PURE__ */ jsx(
|
|
1265
|
-
"span",
|
|
1266
|
-
{
|
|
1267
|
-
className: cn(
|
|
1268
|
-
"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",
|
|
1269
|
-
isSelected && "ring-4 ring-primary/30",
|
|
1270
|
-
cluster.pinClassName
|
|
1271
|
-
),
|
|
1272
|
-
style: {
|
|
1273
|
-
backgroundColor: cluster.pinColor ?? "var(--foreground)"
|
|
1274
|
-
},
|
|
1275
|
-
children: cluster.markers.length
|
|
1276
|
-
}
|
|
1277
|
-
)
|
|
1278
|
-
}
|
|
1279
|
-
);
|
|
1280
|
-
}
|
|
1281
|
-
});
|
|
1282
|
-
});
|
|
1283
|
-
normalizedStandaloneMarkers.forEach((marker) => {
|
|
1284
|
-
const isSelected = selection.type === "marker" && selection.markerId === marker.id;
|
|
1285
|
-
const customMarkerElement = marker.markerElement;
|
|
1286
|
-
resolvedMarkers.push({
|
|
1287
|
-
id: marker.id,
|
|
1288
|
-
latitude: marker.latitude,
|
|
1289
|
-
longitude: marker.longitude,
|
|
1290
|
-
draggable: marker.draggable,
|
|
1291
|
-
element: () => {
|
|
1292
|
-
const markerBody = typeof customMarkerElement === "function" ? customMarkerElement({ isSelected }) : customMarkerElement;
|
|
1293
|
-
return /* @__PURE__ */ jsx(
|
|
1294
|
-
"button",
|
|
1295
|
-
{
|
|
1296
|
-
type: "button",
|
|
1297
|
-
className: "group cursor-pointer",
|
|
1298
|
-
onClick: (event) => {
|
|
1299
|
-
event.preventDefault();
|
|
1300
|
-
event.stopPropagation();
|
|
1301
|
-
selectMarker(marker);
|
|
1302
|
-
},
|
|
1303
|
-
"aria-label": typeof marker.title === "string" ? `View ${marker.title}` : "View location details",
|
|
1304
|
-
children: markerBody ?? /* @__PURE__ */ jsx(
|
|
1305
|
-
"span",
|
|
1306
|
-
{
|
|
1307
|
-
className: cn(
|
|
1308
|
-
"inline-flex h-4 w-4 rounded-full border-2 border-white shadow-md transition-transform duration-200 group-hover:scale-110",
|
|
1309
|
-
isSelected && "h-5 w-5 ring-4 ring-primary/30",
|
|
1310
|
-
marker.pinClassName
|
|
1311
|
-
),
|
|
1312
|
-
style: {
|
|
1313
|
-
backgroundColor: marker.pinColor ?? "#f43f5e"
|
|
1314
|
-
}
|
|
1315
|
-
}
|
|
1316
|
-
)
|
|
1317
|
-
}
|
|
1318
|
-
);
|
|
1319
|
-
}
|
|
1320
|
-
});
|
|
1321
|
-
});
|
|
1322
|
-
return resolvedMarkers;
|
|
1323
|
-
}, [
|
|
1324
|
-
normalizedClusters,
|
|
1325
|
-
normalizedStandaloneMarkers,
|
|
1326
|
-
selectCluster,
|
|
1327
|
-
selectMarker,
|
|
1328
|
-
selection
|
|
1329
|
-
]);
|
|
1330
|
-
const renderMarkerPanel = () => {
|
|
1331
|
-
if (selectedMarker) {
|
|
1332
|
-
const markerMediaItems = selectedMarker.mediaItems ?? [];
|
|
1333
|
-
return /* @__PURE__ */ jsxs(
|
|
1334
|
-
"div",
|
|
1335
|
-
{
|
|
1336
|
-
className: cn(
|
|
1337
|
-
"relative w-[min(24rem,calc(100vw-2rem))] overflow-hidden rounded-xl border border-border bg-card text-card-foreground shadow-2xl",
|
|
1338
|
-
panelClassName
|
|
1339
|
-
),
|
|
1340
|
-
children: [
|
|
1341
|
-
/* @__PURE__ */ jsx(
|
|
1342
|
-
"button",
|
|
1343
|
-
{
|
|
1344
|
-
type: "button",
|
|
1345
|
-
"aria-label": "Close marker details",
|
|
1346
|
-
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",
|
|
1347
|
-
onClick: clearSelection,
|
|
1348
|
-
children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/x", size: 16 })
|
|
1349
|
-
}
|
|
1350
|
-
),
|
|
1351
|
-
markerMediaItems.length > 0 ? /* @__PURE__ */ jsx(
|
|
1352
|
-
MarkerMediaCarousel,
|
|
1353
|
-
{
|
|
1354
|
-
mediaItems: markerMediaItems,
|
|
1355
|
-
optixFlowConfig
|
|
1356
|
-
}
|
|
1357
|
-
) : null,
|
|
1358
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-2 p-4", children: [
|
|
1359
|
-
/* @__PURE__ */ jsx("div", { className: "flex items-start justify-between gap-3", children: /* @__PURE__ */ jsxs("div", { className: "min-w-0 space-y-1", children: [
|
|
1360
|
-
selectedMarker.eyebrow ? /* @__PURE__ */ jsx("p", { className: "text-xs font-semibold uppercase tracking-wide", children: selectedMarker.eyebrow }) : null,
|
|
1361
|
-
/* @__PURE__ */ jsx("div", { className: "text-base font-semibold leading-tight", children: selectedMarker.title ?? selectedMarker.label ?? "Location" })
|
|
1362
|
-
] }) }),
|
|
1363
|
-
selectedMarker.summary ? /* @__PURE__ */ jsx("div", { className: "text-sm leading-relaxed", children: selectedMarker.summary }) : null,
|
|
1364
|
-
selectedMarker.locationLine ? /* @__PURE__ */ jsxs("div", { className: "flex flex-row items-center justify-start text-sm gap-2", children: [
|
|
1365
|
-
/* @__PURE__ */ jsx(
|
|
1366
|
-
DynamicIcon,
|
|
1367
|
-
{
|
|
1368
|
-
name: "lucide:map-pin",
|
|
1369
|
-
className: "opacity-50",
|
|
1370
|
-
size: 14
|
|
1371
|
-
}
|
|
1372
|
-
),
|
|
1373
|
-
typeof selectedMarker.locationLine === "string" ? /* @__PURE__ */ jsx(
|
|
1374
|
-
Pressable,
|
|
1375
|
-
{
|
|
1376
|
-
href: selectedMarker.locationUrl,
|
|
1377
|
-
className: cn(
|
|
1378
|
-
"transition-all duration-500",
|
|
1379
|
-
"font-medium opacity-75 hover:opacity-100",
|
|
1380
|
-
selectedMarker.locationUrl ? "underline underline-offset-4" : ""
|
|
1381
|
-
),
|
|
1382
|
-
children: selectedMarker.locationLine
|
|
1383
|
-
}
|
|
1384
|
-
) : selectedMarker.locationLine
|
|
1385
|
-
] }) : null,
|
|
1386
|
-
selectedMarker.hoursLine ? /* @__PURE__ */ jsxs("div", { className: "flex flex-row items-center justify-start text-sm gap-2", children: [
|
|
1387
|
-
/* @__PURE__ */ jsx(
|
|
1388
|
-
DynamicIcon,
|
|
1389
|
-
{
|
|
1390
|
-
name: "lucide:clock",
|
|
1391
|
-
className: "opacity-50",
|
|
1392
|
-
size: 14
|
|
1393
|
-
}
|
|
1394
|
-
),
|
|
1395
|
-
typeof selectedMarker.hoursLine === "string" ? /* @__PURE__ */ jsx("div", { className: "font-medium", children: selectedMarker.hoursLine }) : selectedMarker.hoursLine
|
|
1396
|
-
] }) : null,
|
|
1397
|
-
selectedMarker.markerContentComponent ? /* @__PURE__ */ jsx("div", { className: "relative", children: selectedMarker.markerContentComponent }) : null,
|
|
1398
|
-
/* @__PURE__ */ jsx(MarkerActions, { actions: selectedMarker.actions })
|
|
1399
|
-
] })
|
|
1400
|
-
]
|
|
1401
|
-
}
|
|
1402
|
-
);
|
|
1403
|
-
}
|
|
1404
|
-
if (selectedCluster) {
|
|
1405
|
-
return /* @__PURE__ */ jsxs(
|
|
1406
|
-
"div",
|
|
1407
|
-
{
|
|
1408
|
-
className: cn(
|
|
1409
|
-
"relative w-[min(24rem,calc(100vw-2rem))] overflow-hidden rounded-xl border border-border bg-card text-card-foreground p-4 shadow-2xl",
|
|
1410
|
-
panelClassName
|
|
1411
|
-
),
|
|
1412
|
-
children: [
|
|
1413
|
-
/* @__PURE__ */ jsx(
|
|
1414
|
-
"button",
|
|
1415
|
-
{
|
|
1416
|
-
type: "button",
|
|
1417
|
-
"aria-label": "Close cluster details",
|
|
1418
|
-
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",
|
|
1419
|
-
onClick: clearSelection,
|
|
1420
|
-
children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/x", size: 16 })
|
|
1421
|
-
}
|
|
1422
|
-
),
|
|
1423
|
-
/* @__PURE__ */ jsx("div", { className: "mb-3 flex items-start justify-between gap-3", children: /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
1424
|
-
selectedCluster.label ? /* @__PURE__ */ jsx("p", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: selectedCluster.label }) : null,
|
|
1425
|
-
/* @__PURE__ */ jsx("div", { className: "text-base font-semibold leading-tight text-foreground", children: selectedCluster.title ?? "Clustered Locations" }),
|
|
1426
|
-
/* @__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.` })
|
|
1427
|
-
] }) }),
|
|
1428
|
-
/* @__PURE__ */ jsx("div", { className: "max-h-56 space-y-2 overflow-y-auto pr-1", children: selectedCluster.markers.map((marker, markerIndex) => /* @__PURE__ */ jsxs(
|
|
1429
|
-
"button",
|
|
1430
|
-
{
|
|
1431
|
-
type: "button",
|
|
1432
|
-
className: "w-full rounded-lg border border-border/60 p-3 text-left transition hover:border-border hover:bg-muted/50",
|
|
1433
|
-
onClick: () => selectMarker(marker),
|
|
1434
|
-
children: [
|
|
1435
|
-
/* @__PURE__ */ jsx("div", { className: "line-clamp-1 text-sm font-semibold text-foreground", children: getMarkerTitle(marker, markerIndex) }),
|
|
1436
|
-
marker.summary ? /* @__PURE__ */ jsx("div", { className: "mt-1 line-clamp-2 text-xs text-muted-foreground", children: marker.summary }) : null
|
|
1437
|
-
]
|
|
1438
|
-
},
|
|
1439
|
-
marker.id
|
|
1440
|
-
)) })
|
|
1441
|
-
]
|
|
1442
|
-
}
|
|
1443
|
-
);
|
|
1444
|
-
}
|
|
1445
|
-
return null;
|
|
1446
|
-
};
|
|
1447
|
-
return /* @__PURE__ */ jsxs(
|
|
1448
|
-
"div",
|
|
1449
|
-
{
|
|
1450
|
-
className: cn(
|
|
1451
|
-
"relative overflow-hidden rounded-2xl border border-border bg-background",
|
|
1452
|
-
className
|
|
1453
|
-
),
|
|
1454
|
-
children: [
|
|
1455
|
-
/* @__PURE__ */ jsx("div", { className: cn("h-[520px] w-full", mapWrapperClassName), children: /* @__PURE__ */ jsx(
|
|
1456
|
-
MapLibre,
|
|
1457
|
-
{
|
|
1458
|
-
stadiaApiKey,
|
|
1459
|
-
mapStyle,
|
|
1460
|
-
styleUrl,
|
|
1461
|
-
mapLibreCssHref,
|
|
1462
|
-
viewState: resolvedViewState,
|
|
1463
|
-
onViewStateChange: applyViewState,
|
|
1464
|
-
markers: mapMarkers,
|
|
1465
|
-
onClick: (coord) => {
|
|
1466
|
-
onMapClick?.(coord);
|
|
1467
|
-
if (clearSelectionOnMapClick) {
|
|
1468
|
-
clearSelection();
|
|
1469
|
-
}
|
|
1470
|
-
},
|
|
1471
|
-
onMarkerDrag,
|
|
1472
|
-
showNavigationControl,
|
|
1473
|
-
showGeolocateControl,
|
|
1474
|
-
navigationControlPosition,
|
|
1475
|
-
geolocateControlPosition,
|
|
1476
|
-
flyToOptions,
|
|
1477
|
-
className: cn("h-full w-full", mapClassName),
|
|
1478
|
-
children: mapChildren
|
|
1479
|
-
}
|
|
1480
|
-
) }),
|
|
1481
|
-
selection.type !== "none" ? /* @__PURE__ */ jsx(
|
|
1482
|
-
"div",
|
|
1483
|
-
{
|
|
1484
|
-
className: cn(
|
|
1485
|
-
"pointer-events-none absolute z-20",
|
|
1486
|
-
PANEL_POSITION_CLASS[panelPosition]
|
|
1487
|
-
),
|
|
1488
|
-
children: /* @__PURE__ */ jsx("div", { className: "pointer-events-auto", children: renderMarkerPanel() })
|
|
1489
|
-
}
|
|
1490
|
-
) : null
|
|
1491
|
-
]
|
|
1492
|
-
}
|
|
1493
|
-
);
|
|
1494
|
-
}
|
|
1495
|
-
var sizeStyles = {
|
|
1496
|
-
sm: "max-w-md",
|
|
1497
|
-
md: "max-w-2xl",
|
|
1498
|
-
lg: "max-w-4xl",
|
|
1499
|
-
xl: "max-w-5xl",
|
|
1500
|
-
full: "max-w-7xl",
|
|
1501
|
-
compact: "max-w-[700px]"
|
|
1502
|
-
};
|
|
1503
|
-
var dialogTransition = {
|
|
1504
|
-
duration: 0.35,
|
|
1505
|
-
ease: [0.16, 1, 0.3, 1]
|
|
1506
|
-
};
|
|
1507
|
-
function AnimatedDialog({
|
|
1508
|
-
open,
|
|
1509
|
-
onOpenChange,
|
|
1510
|
-
title,
|
|
1511
|
-
eyebrow,
|
|
1512
|
-
description,
|
|
1513
|
-
children,
|
|
1514
|
-
header,
|
|
1515
|
-
footer,
|
|
1516
|
-
size = "lg",
|
|
1517
|
-
className,
|
|
1518
|
-
contentClassName,
|
|
1519
|
-
featuredMediaHeader
|
|
1520
|
-
}) {
|
|
1521
|
-
const titleId = useId();
|
|
1522
|
-
const descriptionId = useId();
|
|
1523
|
-
const containerRef = useRef(null);
|
|
1524
|
-
useOnClickOutside(containerRef, () => {
|
|
1525
|
-
if (open) {
|
|
1526
|
-
onOpenChange(false);
|
|
1527
|
-
}
|
|
1528
|
-
});
|
|
1529
|
-
useEffect(() => {
|
|
1530
|
-
if (!open) {
|
|
1531
|
-
return;
|
|
1532
|
-
}
|
|
1533
|
-
const onKeyDown = (event) => {
|
|
1534
|
-
if (event.key === "Escape") {
|
|
1535
|
-
onOpenChange(false);
|
|
1536
|
-
}
|
|
1537
|
-
};
|
|
1538
|
-
const previousOverflow = document.body.style.overflow;
|
|
1539
|
-
document.body.style.overflow = "hidden";
|
|
1540
|
-
window.addEventListener("keydown", onKeyDown);
|
|
1541
|
-
return () => {
|
|
1542
|
-
document.body.style.overflow = previousOverflow;
|
|
1543
|
-
window.removeEventListener("keydown", onKeyDown);
|
|
1544
|
-
};
|
|
1545
|
-
}, [open, onOpenChange]);
|
|
1546
|
-
return /* @__PURE__ */ jsx(AnimatePresence, { children: open ? /* @__PURE__ */ jsxs("div", { className: "fixed inset-0 z-50 h-screen overflow-y-auto", children: [
|
|
1547
|
-
/* @__PURE__ */ jsx(
|
|
1548
|
-
motion.div,
|
|
1549
|
-
{
|
|
1550
|
-
initial: { opacity: 0 },
|
|
1551
|
-
animate: { opacity: 1, transition: dialogTransition },
|
|
1552
|
-
exit: { opacity: 0, transition: dialogTransition },
|
|
1553
|
-
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"
|
|
1554
488
|
}
|
|
1555
489
|
),
|
|
1556
490
|
/* @__PURE__ */ jsxs(
|
|
@@ -1849,10 +783,10 @@ var ImageSlider = ({
|
|
|
1849
783
|
optixFlowConfig
|
|
1850
784
|
}) => {
|
|
1851
785
|
const hasImages = images.length > 0;
|
|
1852
|
-
const [currentIndex, setCurrentIndex] =
|
|
786
|
+
const [currentIndex, setCurrentIndex] = React4.useState(
|
|
1853
787
|
() => normalizeIndex(startIndex, images.length)
|
|
1854
788
|
);
|
|
1855
|
-
const handleNext =
|
|
789
|
+
const handleNext = React4.useCallback(() => {
|
|
1856
790
|
if (!hasImages) return;
|
|
1857
791
|
setCurrentIndex((prevIndex) => {
|
|
1858
792
|
const nextIndex = prevIndex + 1 >= images.length ? 0 : prevIndex + 1;
|
|
@@ -1860,7 +794,7 @@ var ImageSlider = ({
|
|
|
1860
794
|
return nextIndex;
|
|
1861
795
|
});
|
|
1862
796
|
}, [hasImages, images.length, onSlideChange]);
|
|
1863
|
-
const handlePrevious =
|
|
797
|
+
const handlePrevious = React4.useCallback(() => {
|
|
1864
798
|
if (!hasImages) return;
|
|
1865
799
|
setCurrentIndex((prevIndex) => {
|
|
1866
800
|
const nextIndex = prevIndex - 1 < 0 ? images.length - 1 : prevIndex - 1;
|
|
@@ -1868,11 +802,11 @@ var ImageSlider = ({
|
|
|
1868
802
|
return nextIndex;
|
|
1869
803
|
});
|
|
1870
804
|
}, [hasImages, images.length, onSlideChange]);
|
|
1871
|
-
|
|
805
|
+
React4.useEffect(() => {
|
|
1872
806
|
if (!hasImages) return;
|
|
1873
807
|
setCurrentIndex(normalizeIndex(startIndex, images.length));
|
|
1874
808
|
}, [startIndex, images.length, hasImages]);
|
|
1875
|
-
|
|
809
|
+
React4.useEffect(() => {
|
|
1876
810
|
if (!enableKeyboard || !hasImages) return;
|
|
1877
811
|
const handleKeyDown = (event) => {
|
|
1878
812
|
if (event.key === "ArrowRight") {
|
|
@@ -1886,7 +820,7 @@ var ImageSlider = ({
|
|
|
1886
820
|
window.removeEventListener("keydown", handleKeyDown);
|
|
1887
821
|
};
|
|
1888
822
|
}, [enableKeyboard, handleNext, handlePrevious, hasImages]);
|
|
1889
|
-
|
|
823
|
+
React4.useEffect(() => {
|
|
1890
824
|
if (!autoplay || images.length < 2) return;
|
|
1891
825
|
const interval = window.setInterval(handleNext, autoplayIntervalMs);
|
|
1892
826
|
return () => window.clearInterval(interval);
|
|
@@ -1957,8 +891,150 @@ var ImageSlider = ({
|
|
|
1957
891
|
) : null
|
|
1958
892
|
]
|
|
1959
893
|
}
|
|
1960
|
-
);
|
|
1961
|
-
};
|
|
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
|
+
});
|
|
1962
1038
|
function Button({
|
|
1963
1039
|
className,
|
|
1964
1040
|
variant = "default",
|
|
@@ -2002,127 +1078,411 @@ function CardHeader({ className, ...props }) {
|
|
|
2002
1078
|
),
|
|
2003
1079
|
...props
|
|
2004
1080
|
}
|
|
2005
|
-
);
|
|
2006
|
-
}
|
|
2007
|
-
function CardTitle({ className, ...props }) {
|
|
2008
|
-
return /* @__PURE__ */ jsx(
|
|
2009
|
-
"div",
|
|
2010
|
-
{
|
|
2011
|
-
"data-slot": "card-title",
|
|
2012
|
-
className: cn("leading-none font-semibold", className),
|
|
2013
|
-
...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";
|
|
2014
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]
|
|
2015
1376
|
);
|
|
1377
|
+
return {
|
|
1378
|
+
linkType,
|
|
1379
|
+
normalizedHref,
|
|
1380
|
+
target,
|
|
1381
|
+
rel,
|
|
1382
|
+
isExternal,
|
|
1383
|
+
isInternal,
|
|
1384
|
+
shouldUseRouter,
|
|
1385
|
+
handleClick
|
|
1386
|
+
};
|
|
2016
1387
|
}
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
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
|
+
);
|
|
2024
1452
|
}
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
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
|
+
);
|
|
2034
1464
|
}
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
1465
|
+
if (finalComponentType === "div") {
|
|
1466
|
+
return /* @__PURE__ */ jsx(
|
|
1467
|
+
"div",
|
|
1468
|
+
{
|
|
1469
|
+
ref,
|
|
1470
|
+
...commonProps,
|
|
1471
|
+
children
|
|
1472
|
+
}
|
|
1473
|
+
);
|
|
2044
1474
|
}
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
variant: {
|
|
2052
|
-
default: "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
|
|
2053
|
-
secondary: "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
|
|
2054
|
-
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",
|
|
2055
|
-
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
|
|
2056
1481
|
}
|
|
2057
|
-
|
|
2058
|
-
defaultVariants: {
|
|
2059
|
-
variant: "default"
|
|
2060
|
-
}
|
|
1482
|
+
);
|
|
2061
1483
|
}
|
|
2062
1484
|
);
|
|
2063
|
-
|
|
2064
|
-
className,
|
|
2065
|
-
variant,
|
|
2066
|
-
asChild = false,
|
|
2067
|
-
...props
|
|
2068
|
-
}) {
|
|
2069
|
-
const Comp = asChild ? Slot : "span";
|
|
2070
|
-
return /* @__PURE__ */ jsx(
|
|
2071
|
-
Comp,
|
|
2072
|
-
{
|
|
2073
|
-
"data-slot": "badge",
|
|
2074
|
-
className: cn(badgeVariants({ variant }), className),
|
|
2075
|
-
...props
|
|
2076
|
-
}
|
|
2077
|
-
);
|
|
2078
|
-
}
|
|
2079
|
-
function Popover({
|
|
2080
|
-
...props
|
|
2081
|
-
}) {
|
|
2082
|
-
return /* @__PURE__ */ jsx(PopoverPrimitive.Root, { "data-slot": "popover", ...props });
|
|
2083
|
-
}
|
|
2084
|
-
function PopoverTrigger({
|
|
2085
|
-
...props
|
|
2086
|
-
}) {
|
|
2087
|
-
return /* @__PURE__ */ jsx(PopoverPrimitive.Trigger, { "data-slot": "popover-trigger", ...props });
|
|
2088
|
-
}
|
|
2089
|
-
function PopoverContent({
|
|
2090
|
-
className,
|
|
2091
|
-
align = "center",
|
|
2092
|
-
sideOffset = 4,
|
|
2093
|
-
...props
|
|
2094
|
-
}) {
|
|
2095
|
-
return /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
|
|
2096
|
-
PopoverPrimitive.Content,
|
|
2097
|
-
{
|
|
2098
|
-
"data-slot": "popover-content",
|
|
2099
|
-
align,
|
|
2100
|
-
sideOffset,
|
|
2101
|
-
className: cn(
|
|
2102
|
-
"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",
|
|
2103
|
-
className
|
|
2104
|
-
),
|
|
2105
|
-
...props
|
|
2106
|
-
}
|
|
2107
|
-
) });
|
|
2108
|
-
}
|
|
2109
|
-
function StarRating({
|
|
2110
|
-
rating,
|
|
2111
|
-
size = 18,
|
|
2112
|
-
className
|
|
2113
|
-
}) {
|
|
2114
|
-
return /* @__PURE__ */ jsx("div", { className: cn("flex items-center gap-0.5", className), children: [1, 2, 3, 4, 5].map((star) => /* @__PURE__ */ jsx(
|
|
2115
|
-
DynamicIcon,
|
|
2116
|
-
{
|
|
2117
|
-
name: "icon-park-solid/star",
|
|
2118
|
-
size,
|
|
2119
|
-
className: cn(
|
|
2120
|
-
star <= rating ? "fill-primary text-primary" : "fill-muted text-muted"
|
|
2121
|
-
)
|
|
2122
|
-
},
|
|
2123
|
-
star
|
|
2124
|
-
)) });
|
|
2125
|
-
}
|
|
1485
|
+
Pressable.displayName = "Pressable";
|
|
2126
1486
|
var BUTTON_SIZES = {
|
|
2127
1487
|
sm: { buttonSize: "size-8", iconSize: 16 },
|
|
2128
1488
|
md: { buttonSize: "size-10", iconSize: 20 },
|
|
@@ -2214,7 +1574,7 @@ var platformIconMap = {
|
|
|
2214
1574
|
dribbble: "cib/dribbble",
|
|
2215
1575
|
unknown: "icon-park-solid/circular-connection"
|
|
2216
1576
|
};
|
|
2217
|
-
var SocialLinkIcon =
|
|
1577
|
+
var SocialLinkIcon = React4.forwardRef(
|
|
2218
1578
|
({
|
|
2219
1579
|
platformName,
|
|
2220
1580
|
label,
|
|
@@ -2228,16 +1588,16 @@ var SocialLinkIcon = React6.forwardRef(
|
|
|
2228
1588
|
...pressableProps
|
|
2229
1589
|
}, ref) => {
|
|
2230
1590
|
const platform = usePlatformFromUrl(href);
|
|
2231
|
-
const smartPlatformName =
|
|
1591
|
+
const smartPlatformName = React4.useMemo(() => {
|
|
2232
1592
|
return platform || platformName;
|
|
2233
1593
|
}, [platform, platformName]);
|
|
2234
|
-
const iconName =
|
|
1594
|
+
const iconName = React4.useMemo(() => {
|
|
2235
1595
|
return iconNameOverride || platformIconMap[smartPlatformName];
|
|
2236
1596
|
}, [iconNameOverride, smartPlatformName]);
|
|
2237
|
-
const accessibleLabel =
|
|
1597
|
+
const accessibleLabel = React4.useMemo(() => {
|
|
2238
1598
|
return label || platformName;
|
|
2239
1599
|
}, [label, platformName]);
|
|
2240
|
-
const icon =
|
|
1600
|
+
const icon = React4.useMemo(() => {
|
|
2241
1601
|
return /* @__PURE__ */ jsx(
|
|
2242
1602
|
DynamicIcon,
|
|
2243
1603
|
{
|
|
@@ -2317,12 +1677,12 @@ function TextInner({ as, className, children, ...props }, ref) {
|
|
|
2317
1677
|
const Component = as || "span";
|
|
2318
1678
|
return /* @__PURE__ */ jsx(Component, { ref, className: cn(className), ...props, children });
|
|
2319
1679
|
}
|
|
2320
|
-
var Text =
|
|
1680
|
+
var Text = React4.forwardRef(TextInner);
|
|
2321
1681
|
Text.displayName = "Text";
|
|
2322
1682
|
function isContentTextItem(item) {
|
|
2323
|
-
return item !== null && typeof item === "object" && !
|
|
1683
|
+
return item !== null && typeof item === "object" && !React4.isValidElement(item) && "_type" in item && item._type === "text";
|
|
2324
1684
|
}
|
|
2325
|
-
var ContentGroup =
|
|
1685
|
+
var ContentGroup = React4.forwardRef(
|
|
2326
1686
|
({ items, className, children, ...props }, ref) => {
|
|
2327
1687
|
const hasContent = items && items.length > 0;
|
|
2328
1688
|
if (!hasContent) {
|
|
@@ -2335,10 +1695,10 @@ var ContentGroup = React6.forwardRef(
|
|
|
2335
1695
|
return /* @__PURE__ */ jsx(Text, { ...textProps }, idx);
|
|
2336
1696
|
}
|
|
2337
1697
|
const reactNode = item;
|
|
2338
|
-
if (
|
|
2339
|
-
return
|
|
1698
|
+
if (React4.isValidElement(reactNode)) {
|
|
1699
|
+
return React4.cloneElement(reactNode, { key: reactNode.key ?? idx });
|
|
2340
1700
|
}
|
|
2341
|
-
return /* @__PURE__ */ jsx(
|
|
1701
|
+
return /* @__PURE__ */ jsx(React4.Fragment, { children: reactNode }, idx);
|
|
2342
1702
|
}),
|
|
2343
1703
|
children
|
|
2344
1704
|
] });
|
|
@@ -2863,7 +2223,7 @@ function AboutExpandableValues({
|
|
|
2863
2223
|
pattern,
|
|
2864
2224
|
patternOpacity
|
|
2865
2225
|
}) {
|
|
2866
|
-
const [expandedValue, setExpandedValue] =
|
|
2226
|
+
const [expandedValue, setExpandedValue] = React4.useState(null);
|
|
2867
2227
|
const toggleExpand = useCallback((id) => {
|
|
2868
2228
|
setExpandedValue((prev) => prev === id ? null : id);
|
|
2869
2229
|
}, []);
|
|
@@ -3099,7 +2459,7 @@ function CommunityInitiatives({
|
|
|
3099
2459
|
pattern,
|
|
3100
2460
|
patternOpacity
|
|
3101
2461
|
}) {
|
|
3102
|
-
const [activeCategory, setActiveCategory] =
|
|
2462
|
+
const [activeCategory, setActiveCategory] = React4.useState(
|
|
3103
2463
|
categories?.[0]?.id || ""
|
|
3104
2464
|
);
|
|
3105
2465
|
const currentCategory = categories?.find((category) => category.id === activeCategory) || categories?.[0];
|
|
@@ -3363,7 +2723,7 @@ function AboutCultureTabs({
|
|
|
3363
2723
|
patternOpacity
|
|
3364
2724
|
}) {
|
|
3365
2725
|
const resolvedAspects = aspects ?? [];
|
|
3366
|
-
const [activeTab, setActiveTab] =
|
|
2726
|
+
const [activeTab, setActiveTab] = React4.useState(
|
|
3367
2727
|
resolvedAspects[0]?.id || ""
|
|
3368
2728
|
);
|
|
3369
2729
|
const headerItems = useMemo(() => {
|
|
@@ -3896,7 +3256,7 @@ function BannerDeliveryCountdown({
|
|
|
3896
3256
|
}, [prefixText, timerContent, middleText, deliveryDateContent]);
|
|
3897
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: [
|
|
3898
3258
|
iconContent,
|
|
3899
|
-
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: [
|
|
3900
3260
|
index > 0 ? " " : null,
|
|
3901
3261
|
part
|
|
3902
3262
|
] }, index)) })
|
|
@@ -5167,8 +4527,8 @@ var BrandAttribution = ({
|
|
|
5167
4527
|
}
|
|
5168
4528
|
const { prefix = "", anchorText, href, suffix = "" } = options[optionIndex];
|
|
5169
4529
|
const ContainerEl = variant;
|
|
5170
|
-
const [trackedHref, setTrackedHref] =
|
|
5171
|
-
|
|
4530
|
+
const [trackedHref, setTrackedHref] = React4.useState(href);
|
|
4531
|
+
React4.useEffect(() => {
|
|
5172
4532
|
setTrackedHref(buildTrackedHref(href));
|
|
5173
4533
|
}, [href]);
|
|
5174
4534
|
return /* @__PURE__ */ jsxs(ContainerEl, { className: containerClassName, children: [
|
|
@@ -5288,7 +4648,7 @@ function FooterSocialNewsletter({
|
|
|
5288
4648
|
patternOpacity,
|
|
5289
4649
|
optixFlowConfig
|
|
5290
4650
|
}) {
|
|
5291
|
-
const renderForm =
|
|
4651
|
+
const renderForm = React4.useMemo(() => {
|
|
5292
4652
|
if (!formEngineSetup) return null;
|
|
5293
4653
|
const action = {
|
|
5294
4654
|
variant: "default",
|
|
@@ -5577,7 +4937,7 @@ function FooterSimpleCentered({
|
|
|
5577
4937
|
]);
|
|
5578
4938
|
const bottomLinksContent = useMemo(() => {
|
|
5579
4939
|
if (!bottomLinks || bottomLinks.length === 0) return null;
|
|
5580
|
-
return bottomLinks.map((link, idx) => /* @__PURE__ */ jsx(
|
|
4940
|
+
return bottomLinks.map((link, idx) => /* @__PURE__ */ jsx(React4.Fragment, { children: /* @__PURE__ */ jsx(
|
|
5581
4941
|
Pressable,
|
|
5582
4942
|
{
|
|
5583
4943
|
href: link.href,
|
|
@@ -6924,7 +6284,7 @@ function FooterNewsletterMinimal({
|
|
|
6924
6284
|
buttonAction,
|
|
6925
6285
|
formSlot
|
|
6926
6286
|
}) {
|
|
6927
|
-
const navLinksContent =
|
|
6287
|
+
const navLinksContent = React4.useMemo(() => {
|
|
6928
6288
|
if (!navLinks || navLinks.length === 0) return null;
|
|
6929
6289
|
return navLinks.map((item, idx) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
|
|
6930
6290
|
Pressable,
|
|
@@ -6935,7 +6295,7 @@ function FooterNewsletterMinimal({
|
|
|
6935
6295
|
}
|
|
6936
6296
|
) }, idx));
|
|
6937
6297
|
}, [navLinks, navLinkClassName]);
|
|
6938
|
-
const socialLinksContent =
|
|
6298
|
+
const socialLinksContent = React4.useMemo(() => {
|
|
6939
6299
|
if (!socialLinks || socialLinks.length === 0) return null;
|
|
6940
6300
|
return socialLinks.map((item, idx) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
|
|
6941
6301
|
SocialLinkIcon,
|
|
@@ -6951,7 +6311,7 @@ function FooterNewsletterMinimal({
|
|
|
6951
6311
|
}
|
|
6952
6312
|
) }, idx));
|
|
6953
6313
|
}, [socialLinks, socialLinkClassName]);
|
|
6954
|
-
const footerLinksContent =
|
|
6314
|
+
const footerLinksContent = React4.useMemo(() => {
|
|
6955
6315
|
if (!footerLinks || footerLinks.length === 0) return null;
|
|
6956
6316
|
return footerLinks.map((item) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
|
|
6957
6317
|
Pressable,
|
|
@@ -6965,7 +6325,7 @@ function FooterNewsletterMinimal({
|
|
|
6965
6325
|
}
|
|
6966
6326
|
) }, item.label));
|
|
6967
6327
|
}, [footerLinks, footerLinkClassName]);
|
|
6968
|
-
const renderForm =
|
|
6328
|
+
const renderForm = React4.useMemo(() => {
|
|
6969
6329
|
if (formSlot) return formSlot;
|
|
6970
6330
|
if (!formEngineSetup) return null;
|
|
6971
6331
|
const defaultButtonAction = {
|
|
@@ -7512,4 +6872,4 @@ function FooterNavSocial({
|
|
|
7512
6872
|
);
|
|
7513
6873
|
}
|
|
7514
6874
|
|
|
7515
|
-
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 };
|