@opensite/ui 2.8.5 → 2.8.7
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-developer-profile.cjs +17 -10
- package/dist/about-developer-profile.js +17 -10
- package/dist/article-chapters-author.cjs +17 -10
- package/dist/article-chapters-author.js +17 -10
- package/dist/carousel-animated-sections.cjs +79 -25
- package/dist/carousel-animated-sections.d.cts +7 -2
- package/dist/carousel-animated-sections.d.ts +7 -2
- package/dist/carousel-animated-sections.js +79 -25
- package/dist/carousel-gallery-thumbnails.cjs +79 -25
- package/dist/carousel-gallery-thumbnails.d.cts +7 -2
- package/dist/carousel-gallery-thumbnails.d.ts +7 -2
- package/dist/carousel-gallery-thumbnails.js +79 -25
- package/dist/carousel-portfolio-hero.cjs +79 -25
- package/dist/carousel-portfolio-hero.d.cts +7 -2
- package/dist/carousel-portfolio-hero.d.ts +7 -2
- package/dist/carousel-portfolio-hero.js +79 -25
- package/dist/components.cjs +35 -10
- package/dist/components.d.cts +29 -2
- package/dist/components.d.ts +29 -2
- package/dist/components.js +35 -11
- package/dist/footer-accordion-social.cjs +17 -10
- package/dist/footer-accordion-social.js +17 -10
- package/dist/footer-animated-social.cjs +17 -10
- package/dist/footer-animated-social.js +17 -10
- package/dist/footer-brand-description.cjs +17 -10
- package/dist/footer-brand-description.js +17 -10
- package/dist/footer-brand-links-contact.cjs +17 -10
- package/dist/footer-brand-links-contact.js +17 -10
- package/dist/footer-comprehensive-links.cjs +17 -10
- package/dist/footer-comprehensive-links.js +17 -10
- package/dist/footer-contact-card.cjs +17 -10
- package/dist/footer-contact-card.js +17 -10
- package/dist/footer-cta-banner.cjs +17 -10
- package/dist/footer-cta-banner.js +17 -10
- package/dist/footer-cta-social.cjs +17 -10
- package/dist/footer-cta-social.js +17 -10
- package/dist/footer-info-cards-accordion.cjs +17 -10
- package/dist/footer-info-cards-accordion.js +17 -10
- package/dist/footer-nav-social.cjs +17 -10
- package/dist/footer-nav-social.js +17 -10
- package/dist/footer-newsletter-contact.cjs +17 -10
- package/dist/footer-newsletter-contact.js +17 -10
- package/dist/footer-newsletter-grid.cjs +17 -10
- package/dist/footer-newsletter-grid.js +17 -10
- package/dist/footer-newsletter-minimal.cjs +17 -10
- package/dist/footer-newsletter-minimal.js +17 -10
- package/dist/footer-social-apps.cjs +17 -10
- package/dist/footer-social-apps.js +17 -10
- package/dist/footer-social-newsletter.cjs +17 -10
- package/dist/footer-social-newsletter.js +17 -10
- package/dist/footer-split-image-accordion.cjs +17 -10
- package/dist/footer-split-image-accordion.js +17 -10
- package/dist/hero-badge-shadow-overlay.cjs +1 -1
- package/dist/hero-badge-shadow-overlay.js +1 -1
- package/dist/hero-coming-soon-countdown.cjs +17 -10
- package/dist/hero-coming-soon-countdown.js +17 -10
- package/dist/hero-video-background-dark.cjs +78 -16
- package/dist/hero-video-background-dark.d.cts +7 -2
- package/dist/hero-video-background-dark.d.ts +7 -2
- package/dist/hero-video-background-dark.js +78 -16
- package/dist/index.cjs +35 -10
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +35 -11
- package/dist/link-page-bento-layout.cjs +17 -10
- package/dist/link-page-bento-layout.js +17 -10
- package/dist/link-page-grid-cards.cjs +17 -10
- package/dist/link-page-grid-cards.js +17 -10
- package/dist/link-page-minimal-profile.cjs +17 -10
- package/dist/link-page-minimal-profile.js +17 -10
- package/dist/link-page-newsletter-social.cjs +17 -10
- package/dist/link-page-newsletter-social.js +17 -10
- package/dist/link-tree-block.cjs +17 -10
- package/dist/link-tree-block.js +17 -10
- package/dist/navbar-fullscreen-menu.cjs +17 -10
- package/dist/navbar-fullscreen-menu.js +17 -10
- package/dist/navbar-transparent-overlay.cjs +17 -10
- package/dist/navbar-transparent-overlay.js +17 -10
- package/dist/registry.cjs +1398 -851
- package/dist/registry.js +1398 -851
- package/dist/social-link-icon.cjs +17 -10
- package/dist/social-link-icon.d.cts +5 -0
- package/dist/social-link-icon.d.ts +5 -0
- package/dist/social-link-icon.js +17 -10
- package/dist/testimonials-animated-split.cjs +5 -5
- package/dist/testimonials-animated-split.js +5 -5
- package/dist/testimonials-bento-grid.cjs +48 -56
- package/dist/testimonials-bento-grid.js +48 -56
- package/dist/testimonials-carousel-image.cjs +608 -96
- package/dist/testimonials-carousel-image.d.cts +26 -2
- package/dist/testimonials-carousel-image.d.ts +26 -2
- package/dist/testimonials-carousel-image.js +609 -97
- package/dist/testimonials-centered-avatars.cjs +89 -62
- package/dist/testimonials-centered-avatars.d.cts +5 -1
- package/dist/testimonials-centered-avatars.d.ts +5 -1
- package/dist/testimonials-centered-avatars.js +89 -62
- package/dist/testimonials-company-logo.cjs +6 -6
- package/dist/testimonials-company-logo.js +6 -6
- package/dist/testimonials-grid-add-review.cjs +51 -29
- package/dist/testimonials-grid-add-review.js +51 -29
- package/dist/testimonials-images-helpful.cjs +181 -160
- package/dist/testimonials-images-helpful.d.cts +9 -1
- package/dist/testimonials-images-helpful.d.ts +9 -1
- package/dist/testimonials-images-helpful.js +181 -159
- package/dist/testimonials-list-verified.cjs +63 -44
- package/dist/testimonials-list-verified.d.cts +5 -1
- package/dist/testimonials-list-verified.d.ts +5 -1
- package/dist/testimonials-list-verified.js +64 -45
- package/dist/testimonials-logo-cards.cjs +53 -29
- package/dist/testimonials-logo-cards.d.cts +5 -1
- package/dist/testimonials-logo-cards.d.ts +5 -1
- package/dist/testimonials-logo-cards.js +53 -29
- package/dist/testimonials-marquee.cjs +524 -102
- package/dist/testimonials-marquee.d.cts +5 -1
- package/dist/testimonials-marquee.d.ts +5 -1
- package/dist/testimonials-marquee.js +525 -100
- package/dist/testimonials-mini-dividers.cjs +120 -83
- package/dist/testimonials-mini-dividers.d.cts +10 -6
- package/dist/testimonials-mini-dividers.d.ts +10 -6
- package/dist/testimonials-mini-dividers.js +120 -83
- package/dist/testimonials-minimal-numbered.cjs +7 -6
- package/dist/testimonials-minimal-numbered.d.cts +5 -1
- package/dist/testimonials-minimal-numbered.d.ts +5 -1
- package/dist/testimonials-minimal-numbered.js +7 -6
- package/dist/testimonials-parallax-number.cjs +14 -8
- package/dist/testimonials-parallax-number.js +14 -8
- package/dist/testimonials-scrolling-columns.cjs +97 -13
- package/dist/testimonials-scrolling-columns.js +97 -13
- package/dist/testimonials-simple-grid.cjs +513 -68
- package/dist/testimonials-simple-grid.d.cts +9 -5
- package/dist/testimonials-simple-grid.d.ts +9 -5
- package/dist/testimonials-simple-grid.js +510 -62
- package/dist/testimonials-slider-minimal.cjs +604 -90
- package/dist/testimonials-slider-minimal.d.cts +17 -1
- package/dist/testimonials-slider-minimal.d.ts +17 -1
- package/dist/testimonials-slider-minimal.js +598 -81
- package/dist/testimonials-split-image.cjs +452 -17
- package/dist/testimonials-split-image.js +448 -13
- package/dist/testimonials-twitter-cards.cjs +26 -14
- package/dist/testimonials-twitter-cards.js +26 -14
- package/package.json +11 -1
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import
|
|
2
|
+
import * as React3 from 'react';
|
|
3
|
+
import React3__default, { useCallback, useMemo } from 'react';
|
|
3
4
|
import { clsx } from 'clsx';
|
|
4
5
|
import { twMerge } from 'tailwind-merge';
|
|
5
6
|
import * as AvatarPrimitive from '@radix-ui/react-avatar';
|
|
6
7
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
8
|
+
import { cva } from 'class-variance-authority';
|
|
7
9
|
|
|
8
10
|
// components/blocks/testimonials/testimonials-simple-grid.tsx
|
|
9
11
|
function cn(...inputs) {
|
|
@@ -54,19 +56,6 @@ function AvatarFallback({
|
|
|
54
56
|
}
|
|
55
57
|
);
|
|
56
58
|
}
|
|
57
|
-
function Card({ className, ...props }) {
|
|
58
|
-
return /* @__PURE__ */ jsx(
|
|
59
|
-
"div",
|
|
60
|
-
{
|
|
61
|
-
"data-slot": "card",
|
|
62
|
-
className: cn(
|
|
63
|
-
"bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm",
|
|
64
|
-
className
|
|
65
|
-
),
|
|
66
|
-
...props
|
|
67
|
-
}
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
59
|
function CardContent({ className, ...props }) {
|
|
71
60
|
return /* @__PURE__ */ jsx(
|
|
72
61
|
"div",
|
|
@@ -86,7 +75,7 @@ var maxWidthStyles = {
|
|
|
86
75
|
"4xl": "max-w-[1536px]",
|
|
87
76
|
full: "max-w-full"
|
|
88
77
|
};
|
|
89
|
-
var Container =
|
|
78
|
+
var Container = React3__default.forwardRef(
|
|
90
79
|
({ children, maxWidth = "xl", className, as = "div", ...props }, ref) => {
|
|
91
80
|
const Component = as;
|
|
92
81
|
return /* @__PURE__ */ jsx(
|
|
@@ -392,7 +381,7 @@ var spacingStyles = {
|
|
|
392
381
|
};
|
|
393
382
|
var predefinedSpacings = ["none", "sm", "md", "lg", "xl", "hero"];
|
|
394
383
|
var isPredefinedSpacing = (spacing) => predefinedSpacings.includes(spacing);
|
|
395
|
-
var Section =
|
|
384
|
+
var Section = React3__default.forwardRef(
|
|
396
385
|
({
|
|
397
386
|
id,
|
|
398
387
|
title,
|
|
@@ -453,6 +442,424 @@ var Section = React.forwardRef(
|
|
|
453
442
|
}
|
|
454
443
|
);
|
|
455
444
|
Section.displayName = "Section";
|
|
445
|
+
function normalizePhoneNumber(input) {
|
|
446
|
+
const trimmed = input.trim();
|
|
447
|
+
if (trimmed.toLowerCase().startsWith("tel:")) {
|
|
448
|
+
return trimmed;
|
|
449
|
+
}
|
|
450
|
+
const match = trimmed.match(/^[\s\+\-\(\)]*(\d[\d\s\-\(\)\.]*\d)[\s\-]*(x|ext\.?|extension)?[\s\-]*(\d+)?$/i);
|
|
451
|
+
if (match) {
|
|
452
|
+
const mainNumber = match[1].replace(/[\s\-\(\)\.]/g, "");
|
|
453
|
+
const extension = match[3];
|
|
454
|
+
const normalized = mainNumber.length >= 10 && !trimmed.startsWith("+") ? `+${mainNumber}` : mainNumber;
|
|
455
|
+
const withExtension = extension ? `${normalized};ext=${extension}` : normalized;
|
|
456
|
+
return `tel:${withExtension}`;
|
|
457
|
+
}
|
|
458
|
+
const cleaned = trimmed.replace(/[\s\-\(\)\.]/g, "");
|
|
459
|
+
return `tel:${cleaned}`;
|
|
460
|
+
}
|
|
461
|
+
function normalizeEmail(input) {
|
|
462
|
+
const trimmed = input.trim();
|
|
463
|
+
if (trimmed.toLowerCase().startsWith("mailto:")) {
|
|
464
|
+
return trimmed;
|
|
465
|
+
}
|
|
466
|
+
return `mailto:${trimmed}`;
|
|
467
|
+
}
|
|
468
|
+
function isEmail(input) {
|
|
469
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
470
|
+
return emailRegex.test(input.trim());
|
|
471
|
+
}
|
|
472
|
+
function isPhoneNumber(input) {
|
|
473
|
+
const trimmed = input.trim();
|
|
474
|
+
if (trimmed.toLowerCase().startsWith("tel:")) {
|
|
475
|
+
return true;
|
|
476
|
+
}
|
|
477
|
+
const phoneRegex = /^[\s\+\-\(\)]*\d[\d\s\-\(\)\.]*\d[\s\-]*(x|ext\.?|extension)?[\s\-]*\d*$/i;
|
|
478
|
+
return phoneRegex.test(trimmed);
|
|
479
|
+
}
|
|
480
|
+
function isInternalUrl(href) {
|
|
481
|
+
if (typeof window === "undefined") {
|
|
482
|
+
return href.startsWith("/") && !href.startsWith("//");
|
|
483
|
+
}
|
|
484
|
+
const trimmed = href.trim();
|
|
485
|
+
if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
|
|
486
|
+
return true;
|
|
487
|
+
}
|
|
488
|
+
try {
|
|
489
|
+
const url = new URL(trimmed, window.location.href);
|
|
490
|
+
const currentOrigin = window.location.origin;
|
|
491
|
+
const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
|
|
492
|
+
return normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin);
|
|
493
|
+
} catch {
|
|
494
|
+
return false;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
function toRelativePath(href) {
|
|
498
|
+
if (typeof window === "undefined") {
|
|
499
|
+
return href;
|
|
500
|
+
}
|
|
501
|
+
const trimmed = href.trim();
|
|
502
|
+
if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
|
|
503
|
+
return trimmed;
|
|
504
|
+
}
|
|
505
|
+
try {
|
|
506
|
+
const url = new URL(trimmed, window.location.href);
|
|
507
|
+
const currentOrigin = window.location.origin;
|
|
508
|
+
const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
|
|
509
|
+
if (normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin)) {
|
|
510
|
+
return url.pathname + url.search + url.hash;
|
|
511
|
+
}
|
|
512
|
+
} catch {
|
|
513
|
+
}
|
|
514
|
+
return trimmed;
|
|
515
|
+
}
|
|
516
|
+
function useNavigation({
|
|
517
|
+
href,
|
|
518
|
+
onClick
|
|
519
|
+
} = {}) {
|
|
520
|
+
const linkType = React3.useMemo(() => {
|
|
521
|
+
if (!href || href.trim() === "") {
|
|
522
|
+
return onClick ? "none" : "none";
|
|
523
|
+
}
|
|
524
|
+
const trimmed = href.trim();
|
|
525
|
+
if (trimmed.toLowerCase().startsWith("mailto:") || isEmail(trimmed)) {
|
|
526
|
+
return "mailto";
|
|
527
|
+
}
|
|
528
|
+
if (trimmed.toLowerCase().startsWith("tel:") || isPhoneNumber(trimmed)) {
|
|
529
|
+
return "tel";
|
|
530
|
+
}
|
|
531
|
+
if (isInternalUrl(trimmed)) {
|
|
532
|
+
return "internal";
|
|
533
|
+
}
|
|
534
|
+
try {
|
|
535
|
+
new URL(trimmed, typeof window !== "undefined" ? window.location.href : "http://localhost");
|
|
536
|
+
return "external";
|
|
537
|
+
} catch {
|
|
538
|
+
return "internal";
|
|
539
|
+
}
|
|
540
|
+
}, [href, onClick]);
|
|
541
|
+
const normalizedHref = React3.useMemo(() => {
|
|
542
|
+
if (!href || href.trim() === "") {
|
|
543
|
+
return void 0;
|
|
544
|
+
}
|
|
545
|
+
const trimmed = href.trim();
|
|
546
|
+
switch (linkType) {
|
|
547
|
+
case "tel":
|
|
548
|
+
return normalizePhoneNumber(trimmed);
|
|
549
|
+
case "mailto":
|
|
550
|
+
return normalizeEmail(trimmed);
|
|
551
|
+
case "internal":
|
|
552
|
+
return toRelativePath(trimmed);
|
|
553
|
+
case "external":
|
|
554
|
+
return trimmed;
|
|
555
|
+
default:
|
|
556
|
+
return trimmed;
|
|
557
|
+
}
|
|
558
|
+
}, [href, linkType]);
|
|
559
|
+
const target = React3.useMemo(() => {
|
|
560
|
+
switch (linkType) {
|
|
561
|
+
case "external":
|
|
562
|
+
return "_blank";
|
|
563
|
+
case "internal":
|
|
564
|
+
return "_self";
|
|
565
|
+
case "mailto":
|
|
566
|
+
case "tel":
|
|
567
|
+
return void 0;
|
|
568
|
+
default:
|
|
569
|
+
return void 0;
|
|
570
|
+
}
|
|
571
|
+
}, [linkType]);
|
|
572
|
+
const rel = React3.useMemo(() => {
|
|
573
|
+
if (linkType === "external") {
|
|
574
|
+
return "noopener noreferrer";
|
|
575
|
+
}
|
|
576
|
+
return void 0;
|
|
577
|
+
}, [linkType]);
|
|
578
|
+
const isExternal = linkType === "external";
|
|
579
|
+
const isInternal = linkType === "internal";
|
|
580
|
+
const shouldUseRouter = isInternal && typeof normalizedHref === "string" && normalizedHref.startsWith("/");
|
|
581
|
+
const handleClick = React3.useCallback(
|
|
582
|
+
(event) => {
|
|
583
|
+
if (onClick) {
|
|
584
|
+
try {
|
|
585
|
+
onClick(event);
|
|
586
|
+
} catch (error) {
|
|
587
|
+
console.error("Error in user onClick handler:", error);
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
if (event.defaultPrevented) {
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
if (shouldUseRouter && normalizedHref && event.button === 0 && // left-click only
|
|
594
|
+
!event.metaKey && !event.altKey && !event.ctrlKey && !event.shiftKey) {
|
|
595
|
+
if (typeof window !== "undefined") {
|
|
596
|
+
const handler = window.__opensiteNavigationHandler;
|
|
597
|
+
if (typeof handler === "function") {
|
|
598
|
+
try {
|
|
599
|
+
const handled = handler(normalizedHref, event.nativeEvent || event);
|
|
600
|
+
if (handled !== false) {
|
|
601
|
+
event.preventDefault();
|
|
602
|
+
}
|
|
603
|
+
} catch (error) {
|
|
604
|
+
console.error("Error in navigation handler:", error);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
},
|
|
610
|
+
[onClick, shouldUseRouter, normalizedHref]
|
|
611
|
+
);
|
|
612
|
+
return {
|
|
613
|
+
linkType,
|
|
614
|
+
normalizedHref,
|
|
615
|
+
target,
|
|
616
|
+
rel,
|
|
617
|
+
isExternal,
|
|
618
|
+
isInternal,
|
|
619
|
+
shouldUseRouter,
|
|
620
|
+
handleClick
|
|
621
|
+
};
|
|
622
|
+
}
|
|
623
|
+
var baseStyles = [
|
|
624
|
+
// Layout
|
|
625
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap shrink-0",
|
|
626
|
+
// Typography - using CSS variables with sensible defaults
|
|
627
|
+
"font-[var(--button-font-family,inherit)]",
|
|
628
|
+
"font-[var(--button-font-weight,500)]",
|
|
629
|
+
"tracking-[var(--button-letter-spacing,0)]",
|
|
630
|
+
"leading-[var(--button-line-height,1.25)]",
|
|
631
|
+
"[text-transform:var(--button-text-transform,none)]",
|
|
632
|
+
"text-sm",
|
|
633
|
+
// Border radius
|
|
634
|
+
"rounded-[var(--button-radius,var(--radius,0.375rem))]",
|
|
635
|
+
// Smooth transition - using [transition:...] to set full shorthand property (not just transition-property)
|
|
636
|
+
"[transition:var(--button-transition,all_250ms_cubic-bezier(0.4,0,0.2,1))]",
|
|
637
|
+
// Box shadow (master level) - using [box-shadow:...] for complex multi-value shadows
|
|
638
|
+
"[box-shadow:var(--button-shadow,none)]",
|
|
639
|
+
"hover:[box-shadow:var(--button-shadow-hover,var(--button-shadow,none))]",
|
|
640
|
+
// Disabled state
|
|
641
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
|
642
|
+
// SVG handling
|
|
643
|
+
"[&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0",
|
|
644
|
+
// Focus styles
|
|
645
|
+
"outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
|
646
|
+
// Invalid state
|
|
647
|
+
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive"
|
|
648
|
+
].join(" ");
|
|
649
|
+
var buttonVariants = cva(baseStyles, {
|
|
650
|
+
variants: {
|
|
651
|
+
variant: {
|
|
652
|
+
// Default (Primary) variant - full customization
|
|
653
|
+
default: [
|
|
654
|
+
"bg-[var(--button-default-bg,hsl(var(--primary)))]",
|
|
655
|
+
"text-[var(--button-default-fg,hsl(var(--primary-foreground)))]",
|
|
656
|
+
"border-[length:var(--button-default-border-width,0px)]",
|
|
657
|
+
"border-[color:var(--button-default-border,transparent)]",
|
|
658
|
+
"[box-shadow:var(--button-default-shadow,var(--button-shadow,none))]",
|
|
659
|
+
"hover:bg-[var(--button-default-hover-bg,hsl(var(--primary)/0.9))]",
|
|
660
|
+
"hover:text-[var(--button-default-hover-fg,var(--button-default-fg,hsl(var(--primary-foreground))))]",
|
|
661
|
+
"hover:border-[color:var(--button-default-hover-border,var(--button-default-border,transparent))]",
|
|
662
|
+
"hover:[box-shadow:var(--button-default-shadow-hover,var(--button-shadow-hover,var(--button-default-shadow,var(--button-shadow,none))))]"
|
|
663
|
+
].join(" "),
|
|
664
|
+
// Destructive variant - full customization
|
|
665
|
+
destructive: [
|
|
666
|
+
"bg-[var(--button-destructive-bg,hsl(var(--destructive)))]",
|
|
667
|
+
"text-[var(--button-destructive-fg,white)]",
|
|
668
|
+
"border-[length:var(--button-destructive-border-width,0px)]",
|
|
669
|
+
"border-[color:var(--button-destructive-border,transparent)]",
|
|
670
|
+
"[box-shadow:var(--button-destructive-shadow,var(--button-shadow,none))]",
|
|
671
|
+
"hover:bg-[var(--button-destructive-hover-bg,hsl(var(--destructive)/0.9))]",
|
|
672
|
+
"hover:text-[var(--button-destructive-hover-fg,var(--button-destructive-fg,white))]",
|
|
673
|
+
"hover:border-[color:var(--button-destructive-hover-border,var(--button-destructive-border,transparent))]",
|
|
674
|
+
"hover:[box-shadow:var(--button-destructive-shadow-hover,var(--button-shadow-hover,var(--button-destructive-shadow,var(--button-shadow,none))))]",
|
|
675
|
+
"focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40",
|
|
676
|
+
"dark:bg-destructive/60"
|
|
677
|
+
].join(" "),
|
|
678
|
+
// Outline variant - full customization with proper border handling
|
|
679
|
+
outline: [
|
|
680
|
+
"bg-[var(--button-outline-bg,hsl(var(--background)))]",
|
|
681
|
+
"text-[var(--button-outline-fg,inherit)]",
|
|
682
|
+
"border-[length:var(--button-outline-border-width,1px)]",
|
|
683
|
+
"border-[color:var(--button-outline-border,hsl(var(--border)))]",
|
|
684
|
+
"[box-shadow:var(--button-outline-shadow,var(--button-shadow,0_1px_2px_0_rgb(0_0_0/0.05)))]",
|
|
685
|
+
"hover:bg-[var(--button-outline-hover-bg,hsl(var(--accent)))]",
|
|
686
|
+
"hover:text-[var(--button-outline-hover-fg,hsl(var(--accent-foreground)))]",
|
|
687
|
+
"hover:border-[color:var(--button-outline-hover-border,var(--button-outline-border,hsl(var(--border))))]",
|
|
688
|
+
"hover:[box-shadow:var(--button-outline-shadow-hover,var(--button-shadow-hover,var(--button-outline-shadow,var(--button-shadow,none))))]",
|
|
689
|
+
"dark:bg-input/30 dark:border-input dark:hover:bg-input/50"
|
|
690
|
+
].join(" "),
|
|
691
|
+
// Secondary variant - full customization
|
|
692
|
+
secondary: [
|
|
693
|
+
"bg-[var(--button-secondary-bg,hsl(var(--secondary)))]",
|
|
694
|
+
"text-[var(--button-secondary-fg,hsl(var(--secondary-foreground)))]",
|
|
695
|
+
"border-[length:var(--button-secondary-border-width,0px)]",
|
|
696
|
+
"border-[color:var(--button-secondary-border,transparent)]",
|
|
697
|
+
"[box-shadow:var(--button-secondary-shadow,var(--button-shadow,none))]",
|
|
698
|
+
"hover:bg-[var(--button-secondary-hover-bg,hsl(var(--secondary)/0.8))]",
|
|
699
|
+
"hover:text-[var(--button-secondary-hover-fg,var(--button-secondary-fg,hsl(var(--secondary-foreground))))]",
|
|
700
|
+
"hover:border-[color:var(--button-secondary-hover-border,var(--button-secondary-border,transparent))]",
|
|
701
|
+
"hover:[box-shadow:var(--button-secondary-shadow-hover,var(--button-shadow-hover,var(--button-secondary-shadow,var(--button-shadow,none))))]"
|
|
702
|
+
].join(" "),
|
|
703
|
+
// Ghost variant - full customization
|
|
704
|
+
ghost: [
|
|
705
|
+
"bg-[var(--button-ghost-bg,transparent)]",
|
|
706
|
+
"text-[var(--button-ghost-fg,inherit)]",
|
|
707
|
+
"border-[length:var(--button-ghost-border-width,0px)]",
|
|
708
|
+
"border-[color:var(--button-ghost-border,transparent)]",
|
|
709
|
+
"[box-shadow:var(--button-ghost-shadow,var(--button-shadow,none))]",
|
|
710
|
+
"hover:bg-[var(--button-ghost-hover-bg,hsl(var(--accent)))]",
|
|
711
|
+
"hover:text-[var(--button-ghost-hover-fg,hsl(var(--accent-foreground)))]",
|
|
712
|
+
"hover:border-[color:var(--button-ghost-hover-border,var(--button-ghost-border,transparent))]",
|
|
713
|
+
"hover:[box-shadow:var(--button-ghost-shadow-hover,var(--button-shadow-hover,var(--button-ghost-shadow,var(--button-shadow,none))))]",
|
|
714
|
+
"dark:hover:bg-accent/50"
|
|
715
|
+
].join(" "),
|
|
716
|
+
// Link variant - full customization
|
|
717
|
+
link: [
|
|
718
|
+
"bg-[var(--button-link-bg,transparent)]",
|
|
719
|
+
"text-[var(--button-link-fg,hsl(var(--primary)))]",
|
|
720
|
+
"border-[length:var(--button-link-border-width,0px)]",
|
|
721
|
+
"border-[color:var(--button-link-border,transparent)]",
|
|
722
|
+
"[box-shadow:var(--button-link-shadow,none)]",
|
|
723
|
+
"hover:bg-[var(--button-link-hover-bg,transparent)]",
|
|
724
|
+
"hover:text-[var(--button-link-hover-fg,var(--button-link-fg,hsl(var(--primary))))]",
|
|
725
|
+
"hover:[box-shadow:var(--button-link-shadow-hover,none)]",
|
|
726
|
+
"underline-offset-4 hover:underline"
|
|
727
|
+
].join(" ")
|
|
728
|
+
},
|
|
729
|
+
size: {
|
|
730
|
+
default: [
|
|
731
|
+
"h-[var(--button-height-md,2.25rem)]",
|
|
732
|
+
"px-[var(--button-padding-x-md,1rem)]",
|
|
733
|
+
"py-[var(--button-padding-y-md,0.5rem)]",
|
|
734
|
+
"has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
|
|
735
|
+
].join(" "),
|
|
736
|
+
sm: [
|
|
737
|
+
"h-[var(--button-height-sm,2rem)]",
|
|
738
|
+
"px-[var(--button-padding-x-sm,0.75rem)]",
|
|
739
|
+
"py-[var(--button-padding-y-sm,0.25rem)]",
|
|
740
|
+
"gap-1.5",
|
|
741
|
+
"has-[>svg]:px-[calc(var(--button-padding-x-sm,0.75rem)*0.83)]"
|
|
742
|
+
].join(" "),
|
|
743
|
+
md: [
|
|
744
|
+
"h-[var(--button-height-md,2.25rem)]",
|
|
745
|
+
"px-[var(--button-padding-x-md,1rem)]",
|
|
746
|
+
"py-[var(--button-padding-y-md,0.5rem)]",
|
|
747
|
+
"has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
|
|
748
|
+
].join(" "),
|
|
749
|
+
lg: [
|
|
750
|
+
"h-[var(--button-height-lg,2.5rem)]",
|
|
751
|
+
"px-[var(--button-padding-x-lg,1.5rem)]",
|
|
752
|
+
"py-[var(--button-padding-y-lg,0.5rem)]",
|
|
753
|
+
"has-[>svg]:px-[calc(var(--button-padding-x-lg,1.5rem)*0.67)]"
|
|
754
|
+
].join(" "),
|
|
755
|
+
icon: "size-[var(--button-height-md,2.25rem)]",
|
|
756
|
+
"icon-sm": "size-[var(--button-height-sm,2rem)]",
|
|
757
|
+
"icon-lg": "size-[var(--button-height-lg,2.5rem)]"
|
|
758
|
+
}
|
|
759
|
+
},
|
|
760
|
+
defaultVariants: {
|
|
761
|
+
variant: "default",
|
|
762
|
+
size: "default"
|
|
763
|
+
}
|
|
764
|
+
});
|
|
765
|
+
var Pressable = React3.forwardRef(
|
|
766
|
+
({
|
|
767
|
+
children,
|
|
768
|
+
className,
|
|
769
|
+
href,
|
|
770
|
+
onClick,
|
|
771
|
+
variant,
|
|
772
|
+
size,
|
|
773
|
+
asButton = false,
|
|
774
|
+
fallbackComponentType = "span",
|
|
775
|
+
componentType,
|
|
776
|
+
"aria-label": ariaLabel,
|
|
777
|
+
"aria-describedby": ariaDescribedby,
|
|
778
|
+
id,
|
|
779
|
+
...props
|
|
780
|
+
}, ref) => {
|
|
781
|
+
const navigation = useNavigation({ href, onClick });
|
|
782
|
+
const {
|
|
783
|
+
normalizedHref,
|
|
784
|
+
target,
|
|
785
|
+
rel,
|
|
786
|
+
linkType,
|
|
787
|
+
isInternal,
|
|
788
|
+
handleClick
|
|
789
|
+
} = navigation;
|
|
790
|
+
const shouldRenderLink = normalizedHref && linkType !== "none";
|
|
791
|
+
const shouldRenderButton = !shouldRenderLink && onClick;
|
|
792
|
+
const effectiveComponentType = componentType || (shouldRenderLink ? "a" : shouldRenderButton ? "button" : fallbackComponentType);
|
|
793
|
+
const finalComponentType = isInternal && shouldRenderLink ? "a" : effectiveComponentType;
|
|
794
|
+
const shouldApplyButtonStyles = asButton || variant || size;
|
|
795
|
+
const combinedClassName = cn(
|
|
796
|
+
shouldApplyButtonStyles && buttonVariants({ variant, size }),
|
|
797
|
+
className
|
|
798
|
+
);
|
|
799
|
+
const dataProps = Object.fromEntries(
|
|
800
|
+
Object.entries(props).filter(([key]) => key.startsWith("data-"))
|
|
801
|
+
);
|
|
802
|
+
const buttonDataAttributes = shouldApplyButtonStyles ? {
|
|
803
|
+
"data-slot": "button",
|
|
804
|
+
"data-variant": variant ?? "default",
|
|
805
|
+
"data-size": size ?? "default"
|
|
806
|
+
} : {};
|
|
807
|
+
const commonProps = {
|
|
808
|
+
className: combinedClassName,
|
|
809
|
+
onClick: handleClick,
|
|
810
|
+
"aria-label": ariaLabel,
|
|
811
|
+
"aria-describedby": ariaDescribedby,
|
|
812
|
+
id,
|
|
813
|
+
...dataProps,
|
|
814
|
+
...buttonDataAttributes
|
|
815
|
+
};
|
|
816
|
+
if (finalComponentType === "a" && shouldRenderLink) {
|
|
817
|
+
return /* @__PURE__ */ jsx(
|
|
818
|
+
"a",
|
|
819
|
+
{
|
|
820
|
+
ref,
|
|
821
|
+
href: normalizedHref,
|
|
822
|
+
target,
|
|
823
|
+
rel,
|
|
824
|
+
...commonProps,
|
|
825
|
+
...props,
|
|
826
|
+
children
|
|
827
|
+
}
|
|
828
|
+
);
|
|
829
|
+
}
|
|
830
|
+
if (finalComponentType === "button") {
|
|
831
|
+
return /* @__PURE__ */ jsx(
|
|
832
|
+
"button",
|
|
833
|
+
{
|
|
834
|
+
ref,
|
|
835
|
+
type: props.type || "button",
|
|
836
|
+
...commonProps,
|
|
837
|
+
...props,
|
|
838
|
+
children
|
|
839
|
+
}
|
|
840
|
+
);
|
|
841
|
+
}
|
|
842
|
+
if (finalComponentType === "div") {
|
|
843
|
+
return /* @__PURE__ */ jsx(
|
|
844
|
+
"div",
|
|
845
|
+
{
|
|
846
|
+
ref,
|
|
847
|
+
...commonProps,
|
|
848
|
+
children
|
|
849
|
+
}
|
|
850
|
+
);
|
|
851
|
+
}
|
|
852
|
+
return /* @__PURE__ */ jsx(
|
|
853
|
+
"span",
|
|
854
|
+
{
|
|
855
|
+
ref,
|
|
856
|
+
...commonProps,
|
|
857
|
+
children
|
|
858
|
+
}
|
|
859
|
+
);
|
|
860
|
+
}
|
|
861
|
+
);
|
|
862
|
+
Pressable.displayName = "Pressable";
|
|
456
863
|
function TestimonialsSimpleGrid({
|
|
457
864
|
testimonials,
|
|
458
865
|
testimonialsSlot,
|
|
@@ -463,6 +870,7 @@ function TestimonialsSimpleGrid({
|
|
|
463
870
|
headerClassName,
|
|
464
871
|
headingClassName,
|
|
465
872
|
descriptionClassName,
|
|
873
|
+
cardContentClassName,
|
|
466
874
|
gridClassName,
|
|
467
875
|
cardClassName,
|
|
468
876
|
quoteClassName,
|
|
@@ -473,17 +881,11 @@ function TestimonialsSimpleGrid({
|
|
|
473
881
|
pattern,
|
|
474
882
|
patternOpacity
|
|
475
883
|
}) {
|
|
476
|
-
const gridCols = {
|
|
477
|
-
2: "sm:grid-cols-2",
|
|
478
|
-
3: "sm:grid-cols-2 lg:grid-cols-3",
|
|
479
|
-
4: "sm:grid-cols-2 lg:grid-cols-4"
|
|
480
|
-
};
|
|
481
|
-
const effectiveColumns = columns || 3;
|
|
482
884
|
const getAuthorName = useCallback((testimonial) => {
|
|
483
885
|
if (typeof testimonial.author === "string") return testimonial.author;
|
|
484
886
|
return "";
|
|
485
887
|
}, []);
|
|
486
|
-
|
|
888
|
+
useCallback(
|
|
487
889
|
(testimonial) => {
|
|
488
890
|
return testimonial.avatarSrc || testimonial.avatar?.src;
|
|
489
891
|
},
|
|
@@ -498,53 +900,89 @@ function TestimonialsSimpleGrid({
|
|
|
498
900
|
return /* @__PURE__ */ jsx(
|
|
499
901
|
"div",
|
|
500
902
|
{
|
|
501
|
-
className: cn(
|
|
903
|
+
className: cn(
|
|
904
|
+
"grid gap-4 md:gap-6 lg:gap-8 md:grid-cols-2 lg:grid-cols-3",
|
|
905
|
+
gridClassName
|
|
906
|
+
),
|
|
502
907
|
children: testimonials.map((testimonial, index) => {
|
|
503
908
|
const authorName = getAuthorName(testimonial);
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
909
|
+
return /* @__PURE__ */ jsx(
|
|
910
|
+
Pressable,
|
|
911
|
+
{
|
|
912
|
+
href: testimonial.linkConfig?.href,
|
|
913
|
+
className: cn(
|
|
914
|
+
"bg-card text-card-foreground",
|
|
915
|
+
"flex flex-col gap-6",
|
|
916
|
+
testimonial.linkConfig?.href ? "cursor-pointer hover:bg-black hover:text-white transition-all duration-500" : "",
|
|
917
|
+
"rounded-2xl py-0 shadow-xl group",
|
|
918
|
+
"ring-4 ring-ring",
|
|
919
|
+
cardClassName
|
|
920
|
+
),
|
|
921
|
+
children: /* @__PURE__ */ jsxs(
|
|
922
|
+
CardContent,
|
|
923
|
+
{
|
|
924
|
+
className: cn(
|
|
925
|
+
"px-0 h-full flex flex-col-reverse items-stretch justify-between gap-12",
|
|
926
|
+
cardContentClassName
|
|
927
|
+
),
|
|
928
|
+
children: [
|
|
929
|
+
/* @__PURE__ */ jsx(
|
|
930
|
+
"div",
|
|
931
|
+
{
|
|
932
|
+
className: cn(
|
|
933
|
+
"flex items-center justify-between",
|
|
934
|
+
authorClassName
|
|
935
|
+
),
|
|
936
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
|
|
937
|
+
/* @__PURE__ */ jsxs(Avatar, { className: "relative flex shrink-0 size-24 border-t-4 border-r-4 border-primary rounded-tr-xl rounded-tl-none rounded-br-none rounded-bl-none shadow-xl", children: [
|
|
938
|
+
/* @__PURE__ */ jsx(
|
|
939
|
+
AvatarImage,
|
|
940
|
+
{
|
|
941
|
+
src: testimonial.avatarSrc,
|
|
942
|
+
alt: authorName
|
|
943
|
+
}
|
|
944
|
+
),
|
|
945
|
+
/* @__PURE__ */ jsx(AvatarFallback, { children: getInitials(authorName) })
|
|
946
|
+
] }),
|
|
947
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1 pt-2 pr-6 pb-2", children: [
|
|
948
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-0", children: [
|
|
949
|
+
testimonial.author && (typeof testimonial.author === "string" ? /* @__PURE__ */ jsx("p", { className: "text-lg font-semibold leading-relaxed", children: testimonial.author }) : testimonial.author),
|
|
950
|
+
testimonial.role && (typeof testimonial.role === "string" ? /* @__PURE__ */ jsx("p", { className: "text-base", children: testimonial.role }) : testimonial.role)
|
|
951
|
+
] }),
|
|
952
|
+
testimonial.linkConfig?.href && /* @__PURE__ */ jsx(
|
|
953
|
+
Pressable,
|
|
954
|
+
{
|
|
955
|
+
href: testimonial.linkConfig.href,
|
|
956
|
+
className: cn(
|
|
957
|
+
"text-base transition-all duration-300",
|
|
958
|
+
"underline underline-offset-4",
|
|
959
|
+
testimonial.linkConfig.className
|
|
960
|
+
),
|
|
961
|
+
children: testimonial.linkConfig.label
|
|
962
|
+
}
|
|
963
|
+
)
|
|
964
|
+
] })
|
|
965
|
+
] })
|
|
966
|
+
}
|
|
967
|
+
),
|
|
968
|
+
/* @__PURE__ */ jsx("div", { className: "pt-6 md: pt-8 px-6 md:px-8", children: testimonial.quote && (typeof testimonial.quote === "string" ? /* @__PURE__ */ jsx("p", { className: "text-sm leading-relaxed", children: testimonial.quote }) : testimonial.quote) })
|
|
969
|
+
]
|
|
970
|
+
}
|
|
971
|
+
)
|
|
972
|
+
},
|
|
973
|
+
index
|
|
974
|
+
);
|
|
534
975
|
})
|
|
535
976
|
}
|
|
536
977
|
);
|
|
537
978
|
}, [
|
|
538
979
|
testimonialsSlot,
|
|
539
|
-
gridCols,
|
|
540
|
-
effectiveColumns,
|
|
541
980
|
gridClassName,
|
|
542
981
|
testimonials,
|
|
543
982
|
cardClassName,
|
|
544
|
-
|
|
983
|
+
cardContentClassName,
|
|
545
984
|
authorClassName,
|
|
546
985
|
getAuthorName,
|
|
547
|
-
getAvatarSrc,
|
|
548
986
|
getInitials
|
|
549
987
|
]);
|
|
550
988
|
return /* @__PURE__ */ jsxs(
|
|
@@ -560,19 +998,29 @@ function TestimonialsSimpleGrid({
|
|
|
560
998
|
/* @__PURE__ */ jsxs(
|
|
561
999
|
"div",
|
|
562
1000
|
{
|
|
563
|
-
className: cn(
|
|
1001
|
+
className: cn(
|
|
1002
|
+
"mx-auto mb-12 max-w-full md:max-w-2xl text-center",
|
|
1003
|
+
headerClassName
|
|
1004
|
+
),
|
|
564
1005
|
children: [
|
|
565
1006
|
heading && (typeof heading === "string" ? /* @__PURE__ */ jsx(
|
|
566
1007
|
"h2",
|
|
567
1008
|
{
|
|
568
1009
|
className: cn(
|
|
569
|
-
"text-
|
|
1010
|
+
"text-pretty text-3xl md:text-4xl lg:text-6xl",
|
|
1011
|
+
"font-semibold tracking-tight",
|
|
570
1012
|
headingClassName
|
|
571
1013
|
),
|
|
572
1014
|
children: heading
|
|
573
1015
|
}
|
|
574
|
-
) :
|
|
575
|
-
description && (typeof description === "string" ? /* @__PURE__ */ jsx(
|
|
1016
|
+
) : heading),
|
|
1017
|
+
description && (typeof description === "string" ? /* @__PURE__ */ jsx(
|
|
1018
|
+
"p",
|
|
1019
|
+
{
|
|
1020
|
+
className: cn("mt-4 text-lg text-balance", descriptionClassName),
|
|
1021
|
+
children: description
|
|
1022
|
+
}
|
|
1023
|
+
) : description)
|
|
576
1024
|
]
|
|
577
1025
|
}
|
|
578
1026
|
),
|