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