@opensite/ui 2.9.0 → 2.9.2
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/carousel-feature-badge.cjs +4 -3
- package/dist/carousel-feature-badge.d.cts +1 -1
- package/dist/carousel-feature-badge.d.ts +1 -1
- package/dist/carousel-feature-badge.js +4 -3
- package/dist/carousel-scrolling-feature-showcase.cjs +47 -38
- package/dist/carousel-scrolling-feature-showcase.js +47 -38
- package/dist/registry.cjs +454 -265
- package/dist/registry.js +454 -265
- package/dist/testimonials-grid-add-review.cjs +578 -39
- package/dist/testimonials-grid-add-review.d.cts +26 -26
- package/dist/testimonials-grid-add-review.d.ts +26 -26
- package/dist/testimonials-grid-add-review.js +577 -38
- package/dist/testimonials-images-helpful.cjs +85 -74
- package/dist/testimonials-images-helpful.js +85 -74
- package/dist/testimonials-list-verified.cjs +1 -0
- package/dist/testimonials-list-verified.js +1 -0
- package/dist/testimonials-logo-cards.cjs +8 -5
- package/dist/testimonials-logo-cards.js +8 -5
- package/dist/testimonials-masonry-grid.cjs +87 -11
- package/dist/testimonials-masonry-grid.d.cts +14 -1
- package/dist/testimonials-masonry-grid.d.ts +14 -1
- package/dist/testimonials-masonry-grid.js +88 -12
- package/dist/testimonials-mini-dividers.cjs +438 -26
- package/dist/testimonials-mini-dividers.js +434 -22
- package/dist/testimonials-minimal-numbered.cjs +1 -1
- package/dist/testimonials-minimal-numbered.js +1 -1
- package/dist/testimonials-parallax-number.cjs +1 -1
- package/dist/testimonials-parallax-number.js +1 -1
- package/dist/testimonials-quote-carousel.cjs +39 -37
- package/dist/testimonials-quote-carousel.d.cts +5 -1
- package/dist/testimonials-quote-carousel.d.ts +5 -1
- package/dist/testimonials-quote-carousel.js +39 -37
- package/dist/testimonials-scrolling-columns.cjs +438 -8
- package/dist/testimonials-scrolling-columns.js +436 -6
- package/dist/testimonials-simple-grid.cjs +82 -6
- package/dist/testimonials-simple-grid.d.cts +14 -1
- package/dist/testimonials-simple-grid.d.ts +14 -1
- package/dist/testimonials-simple-grid.js +83 -7
- package/dist/testimonials-stats-header.cjs +88 -8
- package/dist/testimonials-stats-header.d.cts +14 -1
- package/dist/testimonials-stats-header.d.ts +14 -1
- package/dist/testimonials-stats-header.js +89 -9
- package/dist/testimonials-twitter-cards.cjs +150 -25
- package/dist/testimonials-twitter-cards.d.cts +14 -1
- package/dist/testimonials-twitter-cards.d.ts +14 -1
- package/dist/testimonials-twitter-cards.js +151 -26
- package/dist/testimonials-wall-compact.cjs +529 -50
- package/dist/testimonials-wall-compact.d.cts +14 -1
- package/dist/testimonials-wall-compact.d.ts +14 -1
- package/dist/testimonials-wall-compact.js +526 -44
- package/package.json +1 -1
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import * as
|
|
3
|
-
import
|
|
2
|
+
import * as React4 from 'react';
|
|
3
|
+
import React4__default, { useCallback, useMemo } from 'react';
|
|
4
4
|
import { clsx } from 'clsx';
|
|
5
5
|
import { twMerge } from 'tailwind-merge';
|
|
6
6
|
import { Icon } from '@page-speed/icon';
|
|
7
7
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
8
8
|
import * as AvatarPrimitive from '@radix-ui/react-avatar';
|
|
9
|
+
import { cva } from 'class-variance-authority';
|
|
9
10
|
|
|
10
11
|
// components/blocks/testimonials/testimonials-mini-dividers.tsx
|
|
11
12
|
function cn(...inputs) {
|
|
12
13
|
return twMerge(clsx(inputs));
|
|
13
14
|
}
|
|
14
15
|
var DEFAULT_ICON_API_KEY = "au382bi7fsh96w9h9xlrnat2jglx";
|
|
15
|
-
var DynamicIcon =
|
|
16
|
+
var DynamicIcon = React4.memo(function DynamicIcon2({
|
|
16
17
|
apiKey,
|
|
17
18
|
...props
|
|
18
19
|
}) {
|
|
@@ -90,7 +91,7 @@ var maxWidthStyles = {
|
|
|
90
91
|
"4xl": "max-w-[1536px]",
|
|
91
92
|
full: "max-w-full"
|
|
92
93
|
};
|
|
93
|
-
var Container =
|
|
94
|
+
var Container = React4__default.forwardRef(
|
|
94
95
|
({ children, maxWidth = "xl", className, as = "div", ...props }, ref) => {
|
|
95
96
|
const Component = as;
|
|
96
97
|
return /* @__PURE__ */ jsx(
|
|
@@ -396,7 +397,7 @@ var spacingStyles = {
|
|
|
396
397
|
};
|
|
397
398
|
var predefinedSpacings = ["none", "sm", "md", "lg", "xl", "hero"];
|
|
398
399
|
var isPredefinedSpacing = (spacing) => predefinedSpacings.includes(spacing);
|
|
399
|
-
var Section =
|
|
400
|
+
var Section = React4__default.forwardRef(
|
|
400
401
|
({
|
|
401
402
|
id,
|
|
402
403
|
title,
|
|
@@ -457,6 +458,424 @@ var Section = React__default.forwardRef(
|
|
|
457
458
|
}
|
|
458
459
|
);
|
|
459
460
|
Section.displayName = "Section";
|
|
461
|
+
var baseStyles = [
|
|
462
|
+
// Layout
|
|
463
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap shrink-0",
|
|
464
|
+
// Typography - using CSS variables with sensible defaults
|
|
465
|
+
"font-[var(--button-font-family,inherit)]",
|
|
466
|
+
"font-[var(--button-font-weight,500)]",
|
|
467
|
+
"tracking-[var(--button-letter-spacing,0)]",
|
|
468
|
+
"leading-[var(--button-line-height,1.25)]",
|
|
469
|
+
"[text-transform:var(--button-text-transform,none)]",
|
|
470
|
+
"text-sm",
|
|
471
|
+
// Border radius
|
|
472
|
+
"rounded-[var(--button-radius,var(--radius,0.375rem))]",
|
|
473
|
+
// Smooth transition - using [transition:...] to set full shorthand property (not just transition-property)
|
|
474
|
+
"[transition:var(--button-transition,all_250ms_cubic-bezier(0.4,0,0.2,1))]",
|
|
475
|
+
// Box shadow (master level) - using [box-shadow:...] for complex multi-value shadows
|
|
476
|
+
"[box-shadow:var(--button-shadow,none)]",
|
|
477
|
+
"hover:[box-shadow:var(--button-shadow-hover,var(--button-shadow,none))]",
|
|
478
|
+
// Disabled state
|
|
479
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
|
480
|
+
// SVG handling
|
|
481
|
+
"[&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0",
|
|
482
|
+
// Focus styles
|
|
483
|
+
"outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
|
484
|
+
// Invalid state
|
|
485
|
+
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive"
|
|
486
|
+
].join(" ");
|
|
487
|
+
var buttonVariants = cva(baseStyles, {
|
|
488
|
+
variants: {
|
|
489
|
+
variant: {
|
|
490
|
+
// Default (Primary) variant - full customization
|
|
491
|
+
default: [
|
|
492
|
+
"bg-[var(--button-default-bg,hsl(var(--primary)))]",
|
|
493
|
+
"text-[var(--button-default-fg,hsl(var(--primary-foreground)))]",
|
|
494
|
+
"border-[length:var(--button-default-border-width,0px)]",
|
|
495
|
+
"border-[color:var(--button-default-border,transparent)]",
|
|
496
|
+
"[box-shadow:var(--button-default-shadow,var(--button-shadow,none))]",
|
|
497
|
+
"hover:bg-[var(--button-default-hover-bg,hsl(var(--primary)/0.9))]",
|
|
498
|
+
"hover:text-[var(--button-default-hover-fg,var(--button-default-fg,hsl(var(--primary-foreground))))]",
|
|
499
|
+
"hover:border-[color:var(--button-default-hover-border,var(--button-default-border,transparent))]",
|
|
500
|
+
"hover:[box-shadow:var(--button-default-shadow-hover,var(--button-shadow-hover,var(--button-default-shadow,var(--button-shadow,none))))]"
|
|
501
|
+
].join(" "),
|
|
502
|
+
// Destructive variant - full customization
|
|
503
|
+
destructive: [
|
|
504
|
+
"bg-[var(--button-destructive-bg,hsl(var(--destructive)))]",
|
|
505
|
+
"text-[var(--button-destructive-fg,white)]",
|
|
506
|
+
"border-[length:var(--button-destructive-border-width,0px)]",
|
|
507
|
+
"border-[color:var(--button-destructive-border,transparent)]",
|
|
508
|
+
"[box-shadow:var(--button-destructive-shadow,var(--button-shadow,none))]",
|
|
509
|
+
"hover:bg-[var(--button-destructive-hover-bg,hsl(var(--destructive)/0.9))]",
|
|
510
|
+
"hover:text-[var(--button-destructive-hover-fg,var(--button-destructive-fg,white))]",
|
|
511
|
+
"hover:border-[color:var(--button-destructive-hover-border,var(--button-destructive-border,transparent))]",
|
|
512
|
+
"hover:[box-shadow:var(--button-destructive-shadow-hover,var(--button-shadow-hover,var(--button-destructive-shadow,var(--button-shadow,none))))]",
|
|
513
|
+
"focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40",
|
|
514
|
+
"dark:bg-destructive/60"
|
|
515
|
+
].join(" "),
|
|
516
|
+
// Outline variant - full customization with proper border handling
|
|
517
|
+
outline: [
|
|
518
|
+
"bg-[var(--button-outline-bg,hsl(var(--background)))]",
|
|
519
|
+
"text-[var(--button-outline-fg,inherit)]",
|
|
520
|
+
"border-[length:var(--button-outline-border-width,1px)]",
|
|
521
|
+
"border-[color:var(--button-outline-border,hsl(var(--border)))]",
|
|
522
|
+
"[box-shadow:var(--button-outline-shadow,var(--button-shadow,0_1px_2px_0_rgb(0_0_0/0.05)))]",
|
|
523
|
+
"hover:bg-[var(--button-outline-hover-bg,hsl(var(--accent)))]",
|
|
524
|
+
"hover:text-[var(--button-outline-hover-fg,hsl(var(--accent-foreground)))]",
|
|
525
|
+
"hover:border-[color:var(--button-outline-hover-border,var(--button-outline-border,hsl(var(--border))))]",
|
|
526
|
+
"hover:[box-shadow:var(--button-outline-shadow-hover,var(--button-shadow-hover,var(--button-outline-shadow,var(--button-shadow,none))))]",
|
|
527
|
+
"dark:bg-input/30 dark:border-input dark:hover:bg-input/50"
|
|
528
|
+
].join(" "),
|
|
529
|
+
// Secondary variant - full customization
|
|
530
|
+
secondary: [
|
|
531
|
+
"bg-[var(--button-secondary-bg,hsl(var(--secondary)))]",
|
|
532
|
+
"text-[var(--button-secondary-fg,hsl(var(--secondary-foreground)))]",
|
|
533
|
+
"border-[length:var(--button-secondary-border-width,0px)]",
|
|
534
|
+
"border-[color:var(--button-secondary-border,transparent)]",
|
|
535
|
+
"[box-shadow:var(--button-secondary-shadow,var(--button-shadow,none))]",
|
|
536
|
+
"hover:bg-[var(--button-secondary-hover-bg,hsl(var(--secondary)/0.8))]",
|
|
537
|
+
"hover:text-[var(--button-secondary-hover-fg,var(--button-secondary-fg,hsl(var(--secondary-foreground))))]",
|
|
538
|
+
"hover:border-[color:var(--button-secondary-hover-border,var(--button-secondary-border,transparent))]",
|
|
539
|
+
"hover:[box-shadow:var(--button-secondary-shadow-hover,var(--button-shadow-hover,var(--button-secondary-shadow,var(--button-shadow,none))))]"
|
|
540
|
+
].join(" "),
|
|
541
|
+
// Ghost variant - full customization
|
|
542
|
+
ghost: [
|
|
543
|
+
"bg-[var(--button-ghost-bg,transparent)]",
|
|
544
|
+
"text-[var(--button-ghost-fg,inherit)]",
|
|
545
|
+
"border-[length:var(--button-ghost-border-width,0px)]",
|
|
546
|
+
"border-[color:var(--button-ghost-border,transparent)]",
|
|
547
|
+
"[box-shadow:var(--button-ghost-shadow,var(--button-shadow,none))]",
|
|
548
|
+
"hover:bg-[var(--button-ghost-hover-bg,hsl(var(--accent)))]",
|
|
549
|
+
"hover:text-[var(--button-ghost-hover-fg,hsl(var(--accent-foreground)))]",
|
|
550
|
+
"hover:border-[color:var(--button-ghost-hover-border,var(--button-ghost-border,transparent))]",
|
|
551
|
+
"hover:[box-shadow:var(--button-ghost-shadow-hover,var(--button-shadow-hover,var(--button-ghost-shadow,var(--button-shadow,none))))]",
|
|
552
|
+
"dark:hover:bg-accent/50"
|
|
553
|
+
].join(" "),
|
|
554
|
+
// Link variant - full customization
|
|
555
|
+
link: [
|
|
556
|
+
"bg-[var(--button-link-bg,transparent)]",
|
|
557
|
+
"text-[var(--button-link-fg,hsl(var(--primary)))]",
|
|
558
|
+
"border-[length:var(--button-link-border-width,0px)]",
|
|
559
|
+
"border-[color:var(--button-link-border,transparent)]",
|
|
560
|
+
"[box-shadow:var(--button-link-shadow,none)]",
|
|
561
|
+
"hover:bg-[var(--button-link-hover-bg,transparent)]",
|
|
562
|
+
"hover:text-[var(--button-link-hover-fg,var(--button-link-fg,hsl(var(--primary))))]",
|
|
563
|
+
"hover:[box-shadow:var(--button-link-shadow-hover,none)]",
|
|
564
|
+
"underline-offset-4 hover:underline"
|
|
565
|
+
].join(" ")
|
|
566
|
+
},
|
|
567
|
+
size: {
|
|
568
|
+
default: [
|
|
569
|
+
"h-[var(--button-height-md,2.25rem)]",
|
|
570
|
+
"px-[var(--button-padding-x-md,1rem)]",
|
|
571
|
+
"py-[var(--button-padding-y-md,0.5rem)]",
|
|
572
|
+
"has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
|
|
573
|
+
].join(" "),
|
|
574
|
+
sm: [
|
|
575
|
+
"h-[var(--button-height-sm,2rem)]",
|
|
576
|
+
"px-[var(--button-padding-x-sm,0.75rem)]",
|
|
577
|
+
"py-[var(--button-padding-y-sm,0.25rem)]",
|
|
578
|
+
"gap-1.5",
|
|
579
|
+
"has-[>svg]:px-[calc(var(--button-padding-x-sm,0.75rem)*0.83)]"
|
|
580
|
+
].join(" "),
|
|
581
|
+
md: [
|
|
582
|
+
"h-[var(--button-height-md,2.25rem)]",
|
|
583
|
+
"px-[var(--button-padding-x-md,1rem)]",
|
|
584
|
+
"py-[var(--button-padding-y-md,0.5rem)]",
|
|
585
|
+
"has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
|
|
586
|
+
].join(" "),
|
|
587
|
+
lg: [
|
|
588
|
+
"h-[var(--button-height-lg,2.5rem)]",
|
|
589
|
+
"px-[var(--button-padding-x-lg,1.5rem)]",
|
|
590
|
+
"py-[var(--button-padding-y-lg,0.5rem)]",
|
|
591
|
+
"has-[>svg]:px-[calc(var(--button-padding-x-lg,1.5rem)*0.67)]"
|
|
592
|
+
].join(" "),
|
|
593
|
+
icon: "size-[var(--button-height-md,2.25rem)]",
|
|
594
|
+
"icon-sm": "size-[var(--button-height-sm,2rem)]",
|
|
595
|
+
"icon-lg": "size-[var(--button-height-lg,2.5rem)]"
|
|
596
|
+
}
|
|
597
|
+
},
|
|
598
|
+
defaultVariants: {
|
|
599
|
+
variant: "default",
|
|
600
|
+
size: "default"
|
|
601
|
+
}
|
|
602
|
+
});
|
|
603
|
+
function normalizePhoneNumber(input) {
|
|
604
|
+
const trimmed = input.trim();
|
|
605
|
+
if (trimmed.toLowerCase().startsWith("tel:")) {
|
|
606
|
+
return trimmed;
|
|
607
|
+
}
|
|
608
|
+
const match = trimmed.match(/^[\s\+\-\(\)]*(\d[\d\s\-\(\)\.]*\d)[\s\-]*(x|ext\.?|extension)?[\s\-]*(\d+)?$/i);
|
|
609
|
+
if (match) {
|
|
610
|
+
const mainNumber = match[1].replace(/[\s\-\(\)\.]/g, "");
|
|
611
|
+
const extension = match[3];
|
|
612
|
+
const normalized = mainNumber.length >= 10 && !trimmed.startsWith("+") ? `+${mainNumber}` : mainNumber;
|
|
613
|
+
const withExtension = extension ? `${normalized};ext=${extension}` : normalized;
|
|
614
|
+
return `tel:${withExtension}`;
|
|
615
|
+
}
|
|
616
|
+
const cleaned = trimmed.replace(/[\s\-\(\)\.]/g, "");
|
|
617
|
+
return `tel:${cleaned}`;
|
|
618
|
+
}
|
|
619
|
+
function normalizeEmail(input) {
|
|
620
|
+
const trimmed = input.trim();
|
|
621
|
+
if (trimmed.toLowerCase().startsWith("mailto:")) {
|
|
622
|
+
return trimmed;
|
|
623
|
+
}
|
|
624
|
+
return `mailto:${trimmed}`;
|
|
625
|
+
}
|
|
626
|
+
function isEmail(input) {
|
|
627
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
628
|
+
return emailRegex.test(input.trim());
|
|
629
|
+
}
|
|
630
|
+
function isPhoneNumber(input) {
|
|
631
|
+
const trimmed = input.trim();
|
|
632
|
+
if (trimmed.toLowerCase().startsWith("tel:")) {
|
|
633
|
+
return true;
|
|
634
|
+
}
|
|
635
|
+
const phoneRegex = /^[\s\+\-\(\)]*\d[\d\s\-\(\)\.]*\d[\s\-]*(x|ext\.?|extension)?[\s\-]*\d*$/i;
|
|
636
|
+
return phoneRegex.test(trimmed);
|
|
637
|
+
}
|
|
638
|
+
function isInternalUrl(href) {
|
|
639
|
+
if (typeof window === "undefined") {
|
|
640
|
+
return href.startsWith("/") && !href.startsWith("//");
|
|
641
|
+
}
|
|
642
|
+
const trimmed = href.trim();
|
|
643
|
+
if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
|
|
644
|
+
return true;
|
|
645
|
+
}
|
|
646
|
+
try {
|
|
647
|
+
const url = new URL(trimmed, window.location.href);
|
|
648
|
+
const currentOrigin = window.location.origin;
|
|
649
|
+
const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
|
|
650
|
+
return normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin);
|
|
651
|
+
} catch {
|
|
652
|
+
return false;
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
function toRelativePath(href) {
|
|
656
|
+
if (typeof window === "undefined") {
|
|
657
|
+
return href;
|
|
658
|
+
}
|
|
659
|
+
const trimmed = href.trim();
|
|
660
|
+
if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
|
|
661
|
+
return trimmed;
|
|
662
|
+
}
|
|
663
|
+
try {
|
|
664
|
+
const url = new URL(trimmed, window.location.href);
|
|
665
|
+
const currentOrigin = window.location.origin;
|
|
666
|
+
const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
|
|
667
|
+
if (normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin)) {
|
|
668
|
+
return url.pathname + url.search + url.hash;
|
|
669
|
+
}
|
|
670
|
+
} catch {
|
|
671
|
+
}
|
|
672
|
+
return trimmed;
|
|
673
|
+
}
|
|
674
|
+
function useNavigation({
|
|
675
|
+
href,
|
|
676
|
+
onClick
|
|
677
|
+
} = {}) {
|
|
678
|
+
const linkType = React4.useMemo(() => {
|
|
679
|
+
if (!href || href.trim() === "") {
|
|
680
|
+
return onClick ? "none" : "none";
|
|
681
|
+
}
|
|
682
|
+
const trimmed = href.trim();
|
|
683
|
+
if (trimmed.toLowerCase().startsWith("mailto:") || isEmail(trimmed)) {
|
|
684
|
+
return "mailto";
|
|
685
|
+
}
|
|
686
|
+
if (trimmed.toLowerCase().startsWith("tel:") || isPhoneNumber(trimmed)) {
|
|
687
|
+
return "tel";
|
|
688
|
+
}
|
|
689
|
+
if (isInternalUrl(trimmed)) {
|
|
690
|
+
return "internal";
|
|
691
|
+
}
|
|
692
|
+
try {
|
|
693
|
+
new URL(trimmed, typeof window !== "undefined" ? window.location.href : "http://localhost");
|
|
694
|
+
return "external";
|
|
695
|
+
} catch {
|
|
696
|
+
return "internal";
|
|
697
|
+
}
|
|
698
|
+
}, [href, onClick]);
|
|
699
|
+
const normalizedHref = React4.useMemo(() => {
|
|
700
|
+
if (!href || href.trim() === "") {
|
|
701
|
+
return void 0;
|
|
702
|
+
}
|
|
703
|
+
const trimmed = href.trim();
|
|
704
|
+
switch (linkType) {
|
|
705
|
+
case "tel":
|
|
706
|
+
return normalizePhoneNumber(trimmed);
|
|
707
|
+
case "mailto":
|
|
708
|
+
return normalizeEmail(trimmed);
|
|
709
|
+
case "internal":
|
|
710
|
+
return toRelativePath(trimmed);
|
|
711
|
+
case "external":
|
|
712
|
+
return trimmed;
|
|
713
|
+
default:
|
|
714
|
+
return trimmed;
|
|
715
|
+
}
|
|
716
|
+
}, [href, linkType]);
|
|
717
|
+
const target = React4.useMemo(() => {
|
|
718
|
+
switch (linkType) {
|
|
719
|
+
case "external":
|
|
720
|
+
return "_blank";
|
|
721
|
+
case "internal":
|
|
722
|
+
return "_self";
|
|
723
|
+
case "mailto":
|
|
724
|
+
case "tel":
|
|
725
|
+
return void 0;
|
|
726
|
+
default:
|
|
727
|
+
return void 0;
|
|
728
|
+
}
|
|
729
|
+
}, [linkType]);
|
|
730
|
+
const rel = React4.useMemo(() => {
|
|
731
|
+
if (linkType === "external") {
|
|
732
|
+
return "noopener noreferrer";
|
|
733
|
+
}
|
|
734
|
+
return void 0;
|
|
735
|
+
}, [linkType]);
|
|
736
|
+
const isExternal = linkType === "external";
|
|
737
|
+
const isInternal = linkType === "internal";
|
|
738
|
+
const shouldUseRouter = isInternal && typeof normalizedHref === "string" && normalizedHref.startsWith("/");
|
|
739
|
+
const handleClick = React4.useCallback(
|
|
740
|
+
(event) => {
|
|
741
|
+
if (onClick) {
|
|
742
|
+
try {
|
|
743
|
+
onClick(event);
|
|
744
|
+
} catch (error) {
|
|
745
|
+
console.error("Error in user onClick handler:", error);
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
if (event.defaultPrevented) {
|
|
749
|
+
return;
|
|
750
|
+
}
|
|
751
|
+
if (shouldUseRouter && normalizedHref && event.button === 0 && // left-click only
|
|
752
|
+
!event.metaKey && !event.altKey && !event.ctrlKey && !event.shiftKey) {
|
|
753
|
+
if (typeof window !== "undefined") {
|
|
754
|
+
const handler = window.__opensiteNavigationHandler;
|
|
755
|
+
if (typeof handler === "function") {
|
|
756
|
+
try {
|
|
757
|
+
const handled = handler(normalizedHref, event.nativeEvent || event);
|
|
758
|
+
if (handled !== false) {
|
|
759
|
+
event.preventDefault();
|
|
760
|
+
}
|
|
761
|
+
} catch (error) {
|
|
762
|
+
console.error("Error in navigation handler:", error);
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
},
|
|
768
|
+
[onClick, shouldUseRouter, normalizedHref]
|
|
769
|
+
);
|
|
770
|
+
return {
|
|
771
|
+
linkType,
|
|
772
|
+
normalizedHref,
|
|
773
|
+
target,
|
|
774
|
+
rel,
|
|
775
|
+
isExternal,
|
|
776
|
+
isInternal,
|
|
777
|
+
shouldUseRouter,
|
|
778
|
+
handleClick
|
|
779
|
+
};
|
|
780
|
+
}
|
|
781
|
+
var Pressable = React4.forwardRef(
|
|
782
|
+
({
|
|
783
|
+
children,
|
|
784
|
+
className,
|
|
785
|
+
href,
|
|
786
|
+
onClick,
|
|
787
|
+
variant,
|
|
788
|
+
size,
|
|
789
|
+
asButton = false,
|
|
790
|
+
fallbackComponentType = "span",
|
|
791
|
+
componentType,
|
|
792
|
+
"aria-label": ariaLabel,
|
|
793
|
+
"aria-describedby": ariaDescribedby,
|
|
794
|
+
id,
|
|
795
|
+
...props
|
|
796
|
+
}, ref) => {
|
|
797
|
+
const navigation = useNavigation({ href, onClick });
|
|
798
|
+
const {
|
|
799
|
+
normalizedHref,
|
|
800
|
+
target,
|
|
801
|
+
rel,
|
|
802
|
+
linkType,
|
|
803
|
+
isInternal,
|
|
804
|
+
handleClick
|
|
805
|
+
} = navigation;
|
|
806
|
+
const shouldRenderLink = normalizedHref && linkType !== "none";
|
|
807
|
+
const shouldRenderButton = !shouldRenderLink && onClick;
|
|
808
|
+
const effectiveComponentType = componentType || (shouldRenderLink ? "a" : shouldRenderButton ? "button" : fallbackComponentType);
|
|
809
|
+
const finalComponentType = isInternal && shouldRenderLink ? "a" : effectiveComponentType;
|
|
810
|
+
const shouldApplyButtonStyles = asButton || variant || size;
|
|
811
|
+
const combinedClassName = cn(
|
|
812
|
+
shouldApplyButtonStyles && buttonVariants({ variant, size }),
|
|
813
|
+
className
|
|
814
|
+
);
|
|
815
|
+
const dataProps = Object.fromEntries(
|
|
816
|
+
Object.entries(props).filter(([key]) => key.startsWith("data-"))
|
|
817
|
+
);
|
|
818
|
+
const buttonDataAttributes = shouldApplyButtonStyles ? {
|
|
819
|
+
"data-slot": "button",
|
|
820
|
+
"data-variant": variant ?? "default",
|
|
821
|
+
"data-size": size ?? "default"
|
|
822
|
+
} : {};
|
|
823
|
+
const commonProps = {
|
|
824
|
+
className: combinedClassName,
|
|
825
|
+
onClick: handleClick,
|
|
826
|
+
"aria-label": ariaLabel,
|
|
827
|
+
"aria-describedby": ariaDescribedby,
|
|
828
|
+
id,
|
|
829
|
+
...dataProps,
|
|
830
|
+
...buttonDataAttributes
|
|
831
|
+
};
|
|
832
|
+
if (finalComponentType === "a" && shouldRenderLink) {
|
|
833
|
+
return /* @__PURE__ */ jsx(
|
|
834
|
+
"a",
|
|
835
|
+
{
|
|
836
|
+
ref,
|
|
837
|
+
href: normalizedHref,
|
|
838
|
+
target,
|
|
839
|
+
rel,
|
|
840
|
+
...commonProps,
|
|
841
|
+
...props,
|
|
842
|
+
children
|
|
843
|
+
}
|
|
844
|
+
);
|
|
845
|
+
}
|
|
846
|
+
if (finalComponentType === "button") {
|
|
847
|
+
return /* @__PURE__ */ jsx(
|
|
848
|
+
"button",
|
|
849
|
+
{
|
|
850
|
+
ref,
|
|
851
|
+
type: props.type || "button",
|
|
852
|
+
...commonProps,
|
|
853
|
+
...props,
|
|
854
|
+
children
|
|
855
|
+
}
|
|
856
|
+
);
|
|
857
|
+
}
|
|
858
|
+
if (finalComponentType === "div") {
|
|
859
|
+
return /* @__PURE__ */ jsx(
|
|
860
|
+
"div",
|
|
861
|
+
{
|
|
862
|
+
ref,
|
|
863
|
+
...commonProps,
|
|
864
|
+
children
|
|
865
|
+
}
|
|
866
|
+
);
|
|
867
|
+
}
|
|
868
|
+
return /* @__PURE__ */ jsx(
|
|
869
|
+
"span",
|
|
870
|
+
{
|
|
871
|
+
ref,
|
|
872
|
+
...commonProps,
|
|
873
|
+
children
|
|
874
|
+
}
|
|
875
|
+
);
|
|
876
|
+
}
|
|
877
|
+
);
|
|
878
|
+
Pressable.displayName = "Pressable";
|
|
460
879
|
function TestimonialsMiniDividers({
|
|
461
880
|
testimonials,
|
|
462
881
|
testimonialsSlot,
|
|
@@ -523,11 +942,13 @@ function TestimonialsMiniDividers({
|
|
|
523
942
|
const authorName = getAuthorName(testimonial);
|
|
524
943
|
const avatarSrc = getAvatarSrc(testimonial);
|
|
525
944
|
return /* @__PURE__ */ jsxs(
|
|
526
|
-
|
|
945
|
+
Pressable,
|
|
527
946
|
{
|
|
947
|
+
href: testimonial.linkConfig?.href,
|
|
528
948
|
className: cn(
|
|
529
|
-
"group flex flex-col gap-4 border-t border-dashed p-
|
|
949
|
+
"group flex flex-col gap-4 border-t border-dashed p-6 lg:p-8",
|
|
530
950
|
index % 3 === 1 && "md:border-x md:border-dashed",
|
|
951
|
+
testimonial.linkConfig?.href ? "transition-all duration-500 hover:opacity-75 cursor-pointer" : "",
|
|
531
952
|
itemClassName
|
|
532
953
|
),
|
|
533
954
|
children: [
|
|
@@ -538,24 +959,15 @@ function TestimonialsMiniDividers({
|
|
|
538
959
|
] }),
|
|
539
960
|
/* @__PURE__ */ jsxs("div", { className: cn("min-w-0", authorClassName), children: [
|
|
540
961
|
testimonial.author && (typeof testimonial.author === "string" ? /* @__PURE__ */ jsx("p", { className: "truncate font-medium", children: testimonial.author }) : testimonial.author),
|
|
541
|
-
testimonial.role && (typeof testimonial.role === "string" ? /* @__PURE__ */ jsx("p", { className: "truncate text-sm
|
|
962
|
+
testimonial.role && (typeof testimonial.role === "string" ? /* @__PURE__ */ jsx("p", { className: "truncate text-sm", children: testimonial.role }) : testimonial.role)
|
|
542
963
|
] })
|
|
543
964
|
] }),
|
|
544
965
|
testimonial.rating != null && /* @__PURE__ */ jsx(StarRating, { rating: testimonial.rating }),
|
|
545
|
-
testimonial.quote && (typeof testimonial.quote === "string" ? /* @__PURE__ */ jsxs(
|
|
546
|
-
"
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
quoteClassName
|
|
551
|
-
),
|
|
552
|
-
children: [
|
|
553
|
-
"\u201C",
|
|
554
|
-
testimonial.quote,
|
|
555
|
-
"\u201D"
|
|
556
|
-
]
|
|
557
|
-
}
|
|
558
|
-
) : /* @__PURE__ */ jsx("div", { className: cn("text-sm", quoteClassName), children: testimonial.quote }))
|
|
966
|
+
testimonial.quote && (typeof testimonial.quote === "string" ? /* @__PURE__ */ jsxs("p", { className: cn("text-sm leading-relaxed", quoteClassName), children: [
|
|
967
|
+
"\u201C",
|
|
968
|
+
testimonial.quote,
|
|
969
|
+
"\u201D"
|
|
970
|
+
] }) : testimonial.quote)
|
|
559
971
|
]
|
|
560
972
|
},
|
|
561
973
|
index
|
|
@@ -473,7 +473,7 @@ function TestimonialsMinimalNumbered({
|
|
|
473
473
|
authorClassName,
|
|
474
474
|
navigationClassName,
|
|
475
475
|
background,
|
|
476
|
-
spacing = "
|
|
476
|
+
spacing = "xl",
|
|
477
477
|
containerClassName = "w-full px-6 sm:px-6 md:px-8 lg:px-0 max-w-full md:max-w-lg min-h-70dvh h-70dvh flex flex-col items-center justify-center",
|
|
478
478
|
pattern,
|
|
479
479
|
patternOpacity
|
|
@@ -451,7 +451,7 @@ function TestimonialsMinimalNumbered({
|
|
|
451
451
|
authorClassName,
|
|
452
452
|
navigationClassName,
|
|
453
453
|
background,
|
|
454
|
-
spacing = "
|
|
454
|
+
spacing = "xl",
|
|
455
455
|
containerClassName = "w-full px-6 sm:px-6 md:px-8 lg:px-0 max-w-full md:max-w-lg min-h-70dvh h-70dvh flex flex-col items-center justify-center",
|
|
456
456
|
pattern,
|
|
457
457
|
patternOpacity
|