@opensite/ui 1.2.2 → 1.2.4
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/auto-scroll-carousel.cjs +2 -2
- package/dist/auto-scroll-carousel.js +2 -2
- package/dist/blur-vignette-grid.cjs +13 -17
- package/dist/blur-vignette-grid.d.cts +2 -2
- package/dist/blur-vignette-grid.d.ts +2 -2
- package/dist/blur-vignette-grid.js +13 -17
- package/dist/carousel-gradient-text.cjs +8 -10
- package/dist/carousel-gradient-text.js +8 -10
- package/dist/carousel-icon-sidebar.cjs +48 -29
- package/dist/carousel-icon-sidebar.js +48 -29
- package/dist/carousel-scale-focus.cjs +27 -1
- package/dist/carousel-scale-focus.js +27 -1
- package/dist/carousel-tabs-content.cjs +46 -36
- package/dist/carousel-tabs-content.js +46 -36
- package/dist/expandable-case-study-cards.cjs +1 -0
- package/dist/expandable-case-study-cards.js +1 -0
- package/dist/feature-capabilities-grid.cjs +525 -54
- package/dist/feature-capabilities-grid.d.cts +4 -0
- package/dist/feature-capabilities-grid.d.ts +4 -0
- package/dist/feature-capabilities-grid.js +525 -54
- package/dist/feature-card-grid-linked.cjs +40 -35
- package/dist/feature-card-grid-linked.d.cts +9 -1
- package/dist/feature-card-grid-linked.d.ts +9 -1
- package/dist/feature-card-grid-linked.js +40 -35
- package/dist/feature-carousel-progress.cjs +129 -56
- package/dist/feature-carousel-progress.d.cts +13 -1
- package/dist/feature-carousel-progress.d.ts +13 -1
- package/dist/feature-carousel-progress.js +129 -56
- package/dist/feature-checklist-image.cjs +61 -105
- package/dist/feature-checklist-image.d.cts +1 -1
- package/dist/feature-checklist-image.d.ts +1 -1
- package/dist/feature-checklist-image.js +61 -105
- package/dist/feature-icon-grid-bordered.cjs +457 -35
- package/dist/feature-icon-grid-bordered.d.cts +4 -0
- package/dist/feature-icon-grid-bordered.d.ts +4 -0
- package/dist/feature-icon-grid-bordered.js +457 -35
- package/dist/feature-numbered-cards.cjs +519 -35
- package/dist/feature-numbered-cards.d.cts +18 -2
- package/dist/feature-numbered-cards.d.ts +18 -2
- package/dist/feature-numbered-cards.js +520 -36
- package/dist/feature-split-image.cjs +1 -1
- package/dist/feature-split-image.js +1 -1
- package/dist/masonry-motion-grid.cjs +2 -2
- package/dist/masonry-motion-grid.js +2 -2
- package/dist/registry.cjs +10264 -9952
- package/dist/registry.js +10262 -9950
- package/dist/testimonial-carousel-cards.cjs +28 -8
- package/dist/testimonial-carousel-cards.d.cts +8 -0
- package/dist/testimonial-carousel-cards.d.ts +8 -0
- package/dist/testimonial-carousel-cards.js +28 -8
- package/package.json +1 -1
|
@@ -6,6 +6,7 @@ var clsx = require('clsx');
|
|
|
6
6
|
var tailwindMerge = require('tailwind-merge');
|
|
7
7
|
var jsxRuntime = require('react/jsx-runtime');
|
|
8
8
|
var img = require('@page-speed/img');
|
|
9
|
+
var classVarianceAuthority = require('class-variance-authority');
|
|
9
10
|
|
|
10
11
|
function _interopNamespace(e) {
|
|
11
12
|
if (e && e.__esModule) return e;
|
|
@@ -511,11 +512,431 @@ var Section = React__namespace.default.forwardRef(
|
|
|
511
512
|
}
|
|
512
513
|
);
|
|
513
514
|
Section.displayName = "Section";
|
|
515
|
+
var baseStyles = [
|
|
516
|
+
// Layout
|
|
517
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap shrink-0",
|
|
518
|
+
// Typography - using CSS variables with sensible defaults
|
|
519
|
+
"font-[var(--button-font-family,inherit)]",
|
|
520
|
+
"font-[var(--button-font-weight,500)]",
|
|
521
|
+
"tracking-[var(--button-letter-spacing,0)]",
|
|
522
|
+
"leading-[var(--button-line-height,1.25)]",
|
|
523
|
+
"[text-transform:var(--button-text-transform,none)]",
|
|
524
|
+
"text-sm",
|
|
525
|
+
// Border radius
|
|
526
|
+
"rounded-[var(--button-radius,var(--radius,0.375rem))]",
|
|
527
|
+
// Smooth transition - using [transition:...] to set full shorthand property (not just transition-property)
|
|
528
|
+
"[transition:var(--button-transition,all_250ms_cubic-bezier(0.4,0,0.2,1))]",
|
|
529
|
+
// Box shadow (master level) - using [box-shadow:...] for complex multi-value shadows
|
|
530
|
+
"[box-shadow:var(--button-shadow,none)]",
|
|
531
|
+
"hover:[box-shadow:var(--button-shadow-hover,var(--button-shadow,none))]",
|
|
532
|
+
// Disabled state
|
|
533
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
|
534
|
+
// SVG handling
|
|
535
|
+
"[&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0",
|
|
536
|
+
// Focus styles
|
|
537
|
+
"outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
|
538
|
+
// Invalid state
|
|
539
|
+
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive"
|
|
540
|
+
].join(" ");
|
|
541
|
+
var buttonVariants = classVarianceAuthority.cva(baseStyles, {
|
|
542
|
+
variants: {
|
|
543
|
+
variant: {
|
|
544
|
+
// Default (Primary) variant - full customization
|
|
545
|
+
default: [
|
|
546
|
+
"bg-[var(--button-default-bg,hsl(var(--primary)))]",
|
|
547
|
+
"text-[var(--button-default-fg,hsl(var(--primary-foreground)))]",
|
|
548
|
+
"border-[length:var(--button-default-border-width,0px)]",
|
|
549
|
+
"border-[color:var(--button-default-border,transparent)]",
|
|
550
|
+
"[box-shadow:var(--button-default-shadow,var(--button-shadow,none))]",
|
|
551
|
+
"hover:bg-[var(--button-default-hover-bg,hsl(var(--primary)/0.9))]",
|
|
552
|
+
"hover:text-[var(--button-default-hover-fg,var(--button-default-fg,hsl(var(--primary-foreground))))]",
|
|
553
|
+
"hover:border-[color:var(--button-default-hover-border,var(--button-default-border,transparent))]",
|
|
554
|
+
"hover:[box-shadow:var(--button-default-shadow-hover,var(--button-shadow-hover,var(--button-default-shadow,var(--button-shadow,none))))]"
|
|
555
|
+
].join(" "),
|
|
556
|
+
// Destructive variant - full customization
|
|
557
|
+
destructive: [
|
|
558
|
+
"bg-[var(--button-destructive-bg,hsl(var(--destructive)))]",
|
|
559
|
+
"text-[var(--button-destructive-fg,white)]",
|
|
560
|
+
"border-[length:var(--button-destructive-border-width,0px)]",
|
|
561
|
+
"border-[color:var(--button-destructive-border,transparent)]",
|
|
562
|
+
"[box-shadow:var(--button-destructive-shadow,var(--button-shadow,none))]",
|
|
563
|
+
"hover:bg-[var(--button-destructive-hover-bg,hsl(var(--destructive)/0.9))]",
|
|
564
|
+
"hover:text-[var(--button-destructive-hover-fg,var(--button-destructive-fg,white))]",
|
|
565
|
+
"hover:border-[color:var(--button-destructive-hover-border,var(--button-destructive-border,transparent))]",
|
|
566
|
+
"hover:[box-shadow:var(--button-destructive-shadow-hover,var(--button-shadow-hover,var(--button-destructive-shadow,var(--button-shadow,none))))]",
|
|
567
|
+
"focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40",
|
|
568
|
+
"dark:bg-destructive/60"
|
|
569
|
+
].join(" "),
|
|
570
|
+
// Outline variant - full customization with proper border handling
|
|
571
|
+
outline: [
|
|
572
|
+
"bg-[var(--button-outline-bg,hsl(var(--background)))]",
|
|
573
|
+
"text-[var(--button-outline-fg,inherit)]",
|
|
574
|
+
"border-[length:var(--button-outline-border-width,1px)]",
|
|
575
|
+
"border-[color:var(--button-outline-border,hsl(var(--border)))]",
|
|
576
|
+
"[box-shadow:var(--button-outline-shadow,var(--button-shadow,0_1px_2px_0_rgb(0_0_0/0.05)))]",
|
|
577
|
+
"hover:bg-[var(--button-outline-hover-bg,hsl(var(--accent)))]",
|
|
578
|
+
"hover:text-[var(--button-outline-hover-fg,hsl(var(--accent-foreground)))]",
|
|
579
|
+
"hover:border-[color:var(--button-outline-hover-border,var(--button-outline-border,hsl(var(--border))))]",
|
|
580
|
+
"hover:[box-shadow:var(--button-outline-shadow-hover,var(--button-shadow-hover,var(--button-outline-shadow,var(--button-shadow,none))))]",
|
|
581
|
+
"dark:bg-input/30 dark:border-input dark:hover:bg-input/50"
|
|
582
|
+
].join(" "),
|
|
583
|
+
// Secondary variant - full customization
|
|
584
|
+
secondary: [
|
|
585
|
+
"bg-[var(--button-secondary-bg,hsl(var(--secondary)))]",
|
|
586
|
+
"text-[var(--button-secondary-fg,hsl(var(--secondary-foreground)))]",
|
|
587
|
+
"border-[length:var(--button-secondary-border-width,0px)]",
|
|
588
|
+
"border-[color:var(--button-secondary-border,transparent)]",
|
|
589
|
+
"[box-shadow:var(--button-secondary-shadow,var(--button-shadow,none))]",
|
|
590
|
+
"hover:bg-[var(--button-secondary-hover-bg,hsl(var(--secondary)/0.8))]",
|
|
591
|
+
"hover:text-[var(--button-secondary-hover-fg,var(--button-secondary-fg,hsl(var(--secondary-foreground))))]",
|
|
592
|
+
"hover:border-[color:var(--button-secondary-hover-border,var(--button-secondary-border,transparent))]",
|
|
593
|
+
"hover:[box-shadow:var(--button-secondary-shadow-hover,var(--button-shadow-hover,var(--button-secondary-shadow,var(--button-shadow,none))))]"
|
|
594
|
+
].join(" "),
|
|
595
|
+
// Ghost variant - full customization
|
|
596
|
+
ghost: [
|
|
597
|
+
"bg-[var(--button-ghost-bg,transparent)]",
|
|
598
|
+
"text-[var(--button-ghost-fg,inherit)]",
|
|
599
|
+
"border-[length:var(--button-ghost-border-width,0px)]",
|
|
600
|
+
"border-[color:var(--button-ghost-border,transparent)]",
|
|
601
|
+
"[box-shadow:var(--button-ghost-shadow,var(--button-shadow,none))]",
|
|
602
|
+
"hover:bg-[var(--button-ghost-hover-bg,hsl(var(--accent)))]",
|
|
603
|
+
"hover:text-[var(--button-ghost-hover-fg,hsl(var(--accent-foreground)))]",
|
|
604
|
+
"hover:border-[color:var(--button-ghost-hover-border,var(--button-ghost-border,transparent))]",
|
|
605
|
+
"hover:[box-shadow:var(--button-ghost-shadow-hover,var(--button-shadow-hover,var(--button-ghost-shadow,var(--button-shadow,none))))]",
|
|
606
|
+
"dark:hover:bg-accent/50"
|
|
607
|
+
].join(" "),
|
|
608
|
+
// Link variant - full customization
|
|
609
|
+
link: [
|
|
610
|
+
"bg-[var(--button-link-bg,transparent)]",
|
|
611
|
+
"text-[var(--button-link-fg,hsl(var(--primary)))]",
|
|
612
|
+
"border-[length:var(--button-link-border-width,0px)]",
|
|
613
|
+
"border-[color:var(--button-link-border,transparent)]",
|
|
614
|
+
"[box-shadow:var(--button-link-shadow,none)]",
|
|
615
|
+
"hover:bg-[var(--button-link-hover-bg,transparent)]",
|
|
616
|
+
"hover:text-[var(--button-link-hover-fg,var(--button-link-fg,hsl(var(--primary))))]",
|
|
617
|
+
"hover:[box-shadow:var(--button-link-shadow-hover,none)]",
|
|
618
|
+
"underline-offset-4 hover:underline"
|
|
619
|
+
].join(" ")
|
|
620
|
+
},
|
|
621
|
+
size: {
|
|
622
|
+
default: [
|
|
623
|
+
"h-[var(--button-height-md,2.25rem)]",
|
|
624
|
+
"px-[var(--button-padding-x-md,1rem)]",
|
|
625
|
+
"py-[var(--button-padding-y-md,0.5rem)]",
|
|
626
|
+
"has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
|
|
627
|
+
].join(" "),
|
|
628
|
+
sm: [
|
|
629
|
+
"h-[var(--button-height-sm,2rem)]",
|
|
630
|
+
"px-[var(--button-padding-x-sm,0.75rem)]",
|
|
631
|
+
"py-[var(--button-padding-y-sm,0.25rem)]",
|
|
632
|
+
"gap-1.5",
|
|
633
|
+
"has-[>svg]:px-[calc(var(--button-padding-x-sm,0.75rem)*0.83)]"
|
|
634
|
+
].join(" "),
|
|
635
|
+
md: [
|
|
636
|
+
"h-[var(--button-height-md,2.25rem)]",
|
|
637
|
+
"px-[var(--button-padding-x-md,1rem)]",
|
|
638
|
+
"py-[var(--button-padding-y-md,0.5rem)]",
|
|
639
|
+
"has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
|
|
640
|
+
].join(" "),
|
|
641
|
+
lg: [
|
|
642
|
+
"h-[var(--button-height-lg,2.5rem)]",
|
|
643
|
+
"px-[var(--button-padding-x-lg,1.5rem)]",
|
|
644
|
+
"py-[var(--button-padding-y-lg,0.5rem)]",
|
|
645
|
+
"has-[>svg]:px-[calc(var(--button-padding-x-lg,1.5rem)*0.67)]"
|
|
646
|
+
].join(" "),
|
|
647
|
+
icon: "size-[var(--button-height-md,2.25rem)]",
|
|
648
|
+
"icon-sm": "size-[var(--button-height-sm,2rem)]",
|
|
649
|
+
"icon-lg": "size-[var(--button-height-lg,2.5rem)]"
|
|
650
|
+
}
|
|
651
|
+
},
|
|
652
|
+
defaultVariants: {
|
|
653
|
+
variant: "default",
|
|
654
|
+
size: "default"
|
|
655
|
+
}
|
|
656
|
+
});
|
|
657
|
+
function normalizePhoneNumber(input) {
|
|
658
|
+
const trimmed = input.trim();
|
|
659
|
+
if (trimmed.toLowerCase().startsWith("tel:")) {
|
|
660
|
+
return trimmed;
|
|
661
|
+
}
|
|
662
|
+
const match = trimmed.match(/^[\s\+\-\(\)]*(\d[\d\s\-\(\)\.]*\d)[\s\-]*(x|ext\.?|extension)?[\s\-]*(\d+)?$/i);
|
|
663
|
+
if (match) {
|
|
664
|
+
const mainNumber = match[1].replace(/[\s\-\(\)\.]/g, "");
|
|
665
|
+
const extension = match[3];
|
|
666
|
+
const normalized = mainNumber.length >= 10 && !trimmed.startsWith("+") ? `+${mainNumber}` : mainNumber;
|
|
667
|
+
const withExtension = extension ? `${normalized};ext=${extension}` : normalized;
|
|
668
|
+
return `tel:${withExtension}`;
|
|
669
|
+
}
|
|
670
|
+
const cleaned = trimmed.replace(/[\s\-\(\)\.]/g, "");
|
|
671
|
+
return `tel:${cleaned}`;
|
|
672
|
+
}
|
|
673
|
+
function normalizeEmail(input) {
|
|
674
|
+
const trimmed = input.trim();
|
|
675
|
+
if (trimmed.toLowerCase().startsWith("mailto:")) {
|
|
676
|
+
return trimmed;
|
|
677
|
+
}
|
|
678
|
+
return `mailto:${trimmed}`;
|
|
679
|
+
}
|
|
680
|
+
function isEmail(input) {
|
|
681
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
682
|
+
return emailRegex.test(input.trim());
|
|
683
|
+
}
|
|
684
|
+
function isPhoneNumber(input) {
|
|
685
|
+
const trimmed = input.trim();
|
|
686
|
+
if (trimmed.toLowerCase().startsWith("tel:")) {
|
|
687
|
+
return true;
|
|
688
|
+
}
|
|
689
|
+
const phoneRegex = /^[\s\+\-\(\)]*\d[\d\s\-\(\)\.]*\d[\s\-]*(x|ext\.?|extension)?[\s\-]*\d*$/i;
|
|
690
|
+
return phoneRegex.test(trimmed);
|
|
691
|
+
}
|
|
692
|
+
function isInternalUrl(href) {
|
|
693
|
+
if (typeof window === "undefined") {
|
|
694
|
+
return href.startsWith("/") && !href.startsWith("//");
|
|
695
|
+
}
|
|
696
|
+
const trimmed = href.trim();
|
|
697
|
+
if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
|
|
698
|
+
return true;
|
|
699
|
+
}
|
|
700
|
+
try {
|
|
701
|
+
const url = new URL(trimmed, window.location.href);
|
|
702
|
+
const currentOrigin = window.location.origin;
|
|
703
|
+
const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
|
|
704
|
+
return normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin);
|
|
705
|
+
} catch {
|
|
706
|
+
return false;
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
function toRelativePath(href) {
|
|
710
|
+
if (typeof window === "undefined") {
|
|
711
|
+
return href;
|
|
712
|
+
}
|
|
713
|
+
const trimmed = href.trim();
|
|
714
|
+
if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
|
|
715
|
+
return trimmed;
|
|
716
|
+
}
|
|
717
|
+
try {
|
|
718
|
+
const url = new URL(trimmed, window.location.href);
|
|
719
|
+
const currentOrigin = window.location.origin;
|
|
720
|
+
const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
|
|
721
|
+
if (normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin)) {
|
|
722
|
+
return url.pathname + url.search + url.hash;
|
|
723
|
+
}
|
|
724
|
+
} catch {
|
|
725
|
+
}
|
|
726
|
+
return trimmed;
|
|
727
|
+
}
|
|
728
|
+
function useNavigation({
|
|
729
|
+
href,
|
|
730
|
+
onClick
|
|
731
|
+
} = {}) {
|
|
732
|
+
const linkType = React__namespace.useMemo(() => {
|
|
733
|
+
if (!href || href.trim() === "") {
|
|
734
|
+
return onClick ? "none" : "none";
|
|
735
|
+
}
|
|
736
|
+
const trimmed = href.trim();
|
|
737
|
+
if (trimmed.toLowerCase().startsWith("mailto:") || isEmail(trimmed)) {
|
|
738
|
+
return "mailto";
|
|
739
|
+
}
|
|
740
|
+
if (trimmed.toLowerCase().startsWith("tel:") || isPhoneNumber(trimmed)) {
|
|
741
|
+
return "tel";
|
|
742
|
+
}
|
|
743
|
+
if (isInternalUrl(trimmed)) {
|
|
744
|
+
return "internal";
|
|
745
|
+
}
|
|
746
|
+
try {
|
|
747
|
+
new URL(trimmed, typeof window !== "undefined" ? window.location.href : "http://localhost");
|
|
748
|
+
return "external";
|
|
749
|
+
} catch {
|
|
750
|
+
return "internal";
|
|
751
|
+
}
|
|
752
|
+
}, [href, onClick]);
|
|
753
|
+
const normalizedHref = React__namespace.useMemo(() => {
|
|
754
|
+
if (!href || href.trim() === "") {
|
|
755
|
+
return void 0;
|
|
756
|
+
}
|
|
757
|
+
const trimmed = href.trim();
|
|
758
|
+
switch (linkType) {
|
|
759
|
+
case "tel":
|
|
760
|
+
return normalizePhoneNumber(trimmed);
|
|
761
|
+
case "mailto":
|
|
762
|
+
return normalizeEmail(trimmed);
|
|
763
|
+
case "internal":
|
|
764
|
+
return toRelativePath(trimmed);
|
|
765
|
+
case "external":
|
|
766
|
+
return trimmed;
|
|
767
|
+
default:
|
|
768
|
+
return trimmed;
|
|
769
|
+
}
|
|
770
|
+
}, [href, linkType]);
|
|
771
|
+
const target = React__namespace.useMemo(() => {
|
|
772
|
+
switch (linkType) {
|
|
773
|
+
case "external":
|
|
774
|
+
return "_blank";
|
|
775
|
+
case "internal":
|
|
776
|
+
return "_self";
|
|
777
|
+
case "mailto":
|
|
778
|
+
case "tel":
|
|
779
|
+
return void 0;
|
|
780
|
+
default:
|
|
781
|
+
return void 0;
|
|
782
|
+
}
|
|
783
|
+
}, [linkType]);
|
|
784
|
+
const rel = React__namespace.useMemo(() => {
|
|
785
|
+
if (linkType === "external") {
|
|
786
|
+
return "noopener noreferrer";
|
|
787
|
+
}
|
|
788
|
+
return void 0;
|
|
789
|
+
}, [linkType]);
|
|
790
|
+
const isExternal = linkType === "external";
|
|
791
|
+
const isInternal = linkType === "internal";
|
|
792
|
+
const shouldUseRouter = isInternal && typeof normalizedHref === "string" && normalizedHref.startsWith("/");
|
|
793
|
+
const handleClick = React__namespace.useCallback(
|
|
794
|
+
(event) => {
|
|
795
|
+
if (onClick) {
|
|
796
|
+
try {
|
|
797
|
+
onClick(event);
|
|
798
|
+
} catch (error) {
|
|
799
|
+
console.error("Error in user onClick handler:", error);
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
if (event.defaultPrevented) {
|
|
803
|
+
return;
|
|
804
|
+
}
|
|
805
|
+
if (shouldUseRouter && normalizedHref && event.button === 0 && // left-click only
|
|
806
|
+
!event.metaKey && !event.altKey && !event.ctrlKey && !event.shiftKey) {
|
|
807
|
+
if (typeof window !== "undefined") {
|
|
808
|
+
const handler = window.__opensiteNavigationHandler;
|
|
809
|
+
if (typeof handler === "function") {
|
|
810
|
+
try {
|
|
811
|
+
const handled = handler(normalizedHref, event.nativeEvent || event);
|
|
812
|
+
if (handled !== false) {
|
|
813
|
+
event.preventDefault();
|
|
814
|
+
}
|
|
815
|
+
} catch (error) {
|
|
816
|
+
console.error("Error in navigation handler:", error);
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
},
|
|
822
|
+
[onClick, shouldUseRouter, normalizedHref]
|
|
823
|
+
);
|
|
824
|
+
return {
|
|
825
|
+
linkType,
|
|
826
|
+
normalizedHref,
|
|
827
|
+
target,
|
|
828
|
+
rel,
|
|
829
|
+
isExternal,
|
|
830
|
+
isInternal,
|
|
831
|
+
shouldUseRouter,
|
|
832
|
+
handleClick
|
|
833
|
+
};
|
|
834
|
+
}
|
|
835
|
+
var Pressable = React__namespace.forwardRef(
|
|
836
|
+
({
|
|
837
|
+
children,
|
|
838
|
+
className,
|
|
839
|
+
href,
|
|
840
|
+
onClick,
|
|
841
|
+
variant,
|
|
842
|
+
size,
|
|
843
|
+
asButton = false,
|
|
844
|
+
fallbackComponentType = "span",
|
|
845
|
+
componentType,
|
|
846
|
+
"aria-label": ariaLabel,
|
|
847
|
+
"aria-describedby": ariaDescribedby,
|
|
848
|
+
id,
|
|
849
|
+
...props
|
|
850
|
+
}, ref) => {
|
|
851
|
+
const navigation = useNavigation({ href, onClick });
|
|
852
|
+
const {
|
|
853
|
+
normalizedHref,
|
|
854
|
+
target,
|
|
855
|
+
rel,
|
|
856
|
+
linkType,
|
|
857
|
+
isInternal,
|
|
858
|
+
handleClick
|
|
859
|
+
} = navigation;
|
|
860
|
+
const shouldRenderLink = normalizedHref && linkType !== "none";
|
|
861
|
+
const shouldRenderButton = !shouldRenderLink && onClick;
|
|
862
|
+
const effectiveComponentType = componentType || (shouldRenderLink ? "a" : shouldRenderButton ? "button" : fallbackComponentType);
|
|
863
|
+
const finalComponentType = isInternal && shouldRenderLink ? "a" : effectiveComponentType;
|
|
864
|
+
const shouldApplyButtonStyles = asButton || variant || size;
|
|
865
|
+
const combinedClassName = cn(
|
|
866
|
+
shouldApplyButtonStyles && buttonVariants({ variant, size }),
|
|
867
|
+
className
|
|
868
|
+
);
|
|
869
|
+
const dataProps = Object.fromEntries(
|
|
870
|
+
Object.entries(props).filter(([key]) => key.startsWith("data-"))
|
|
871
|
+
);
|
|
872
|
+
const buttonDataAttributes = shouldApplyButtonStyles ? {
|
|
873
|
+
"data-slot": "button",
|
|
874
|
+
"data-variant": variant ?? "default",
|
|
875
|
+
"data-size": size ?? "default"
|
|
876
|
+
} : {};
|
|
877
|
+
const commonProps = {
|
|
878
|
+
className: combinedClassName,
|
|
879
|
+
onClick: handleClick,
|
|
880
|
+
"aria-label": ariaLabel,
|
|
881
|
+
"aria-describedby": ariaDescribedby,
|
|
882
|
+
id,
|
|
883
|
+
...dataProps,
|
|
884
|
+
...buttonDataAttributes
|
|
885
|
+
};
|
|
886
|
+
if (finalComponentType === "a" && shouldRenderLink) {
|
|
887
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
888
|
+
"a",
|
|
889
|
+
{
|
|
890
|
+
ref,
|
|
891
|
+
href: normalizedHref,
|
|
892
|
+
target,
|
|
893
|
+
rel,
|
|
894
|
+
...commonProps,
|
|
895
|
+
...props,
|
|
896
|
+
children
|
|
897
|
+
}
|
|
898
|
+
);
|
|
899
|
+
}
|
|
900
|
+
if (finalComponentType === "button") {
|
|
901
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
902
|
+
"button",
|
|
903
|
+
{
|
|
904
|
+
ref,
|
|
905
|
+
type: props.type || "button",
|
|
906
|
+
...commonProps,
|
|
907
|
+
...props,
|
|
908
|
+
children
|
|
909
|
+
}
|
|
910
|
+
);
|
|
911
|
+
}
|
|
912
|
+
if (finalComponentType === "div") {
|
|
913
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
914
|
+
"div",
|
|
915
|
+
{
|
|
916
|
+
ref,
|
|
917
|
+
...commonProps,
|
|
918
|
+
children
|
|
919
|
+
}
|
|
920
|
+
);
|
|
921
|
+
}
|
|
922
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
923
|
+
"span",
|
|
924
|
+
{
|
|
925
|
+
ref,
|
|
926
|
+
...commonProps,
|
|
927
|
+
children
|
|
928
|
+
}
|
|
929
|
+
);
|
|
930
|
+
}
|
|
931
|
+
);
|
|
932
|
+
Pressable.displayName = "Pressable";
|
|
514
933
|
function FeatureNumberedCards({
|
|
934
|
+
title,
|
|
935
|
+
description,
|
|
515
936
|
features,
|
|
516
937
|
featuresSlot,
|
|
517
938
|
className,
|
|
518
|
-
containerClassName,
|
|
939
|
+
containerClassName = "px-6 sm:px-6 md:mx-6 lg:px-8",
|
|
519
940
|
cardsWrapperClassName,
|
|
520
941
|
cardClassName,
|
|
521
942
|
titleClassName,
|
|
@@ -524,7 +945,7 @@ function FeatureNumberedCards({
|
|
|
524
945
|
badgeClassName,
|
|
525
946
|
optixFlowConfig,
|
|
526
947
|
background,
|
|
527
|
-
spacing,
|
|
948
|
+
spacing = "py-6 md:py-32",
|
|
528
949
|
pattern,
|
|
529
950
|
patternOpacity,
|
|
530
951
|
patternClassName
|
|
@@ -568,32 +989,61 @@ function FeatureNumberedCards({
|
|
|
568
989
|
},
|
|
569
990
|
[]
|
|
570
991
|
);
|
|
992
|
+
const actionsContent = React.useCallback(
|
|
993
|
+
(args) => {
|
|
994
|
+
if (args?.actionsSlot) return args.actionsSlot;
|
|
995
|
+
if (!args?.actions || args.actions.length === 0) return null;
|
|
996
|
+
return args.actions.map((action, index) => {
|
|
997
|
+
const {
|
|
998
|
+
label,
|
|
999
|
+
icon,
|
|
1000
|
+
iconAfter,
|
|
1001
|
+
children,
|
|
1002
|
+
className: actionClassName,
|
|
1003
|
+
...pressableProps
|
|
1004
|
+
} = action;
|
|
1005
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1006
|
+
Pressable,
|
|
1007
|
+
{
|
|
1008
|
+
asButton: true,
|
|
1009
|
+
className: actionClassName,
|
|
1010
|
+
...pressableProps,
|
|
1011
|
+
children: children ?? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1012
|
+
icon,
|
|
1013
|
+
label,
|
|
1014
|
+
iconAfter
|
|
1015
|
+
] })
|
|
1016
|
+
},
|
|
1017
|
+
index
|
|
1018
|
+
);
|
|
1019
|
+
});
|
|
1020
|
+
},
|
|
1021
|
+
[]
|
|
1022
|
+
);
|
|
1023
|
+
const cardImg = React.useCallback((feature) => {
|
|
1024
|
+
if (!feature.image || !feature.imageSlot) return null;
|
|
1025
|
+
if (feature.imageSlot) return feature.imageSlot;
|
|
1026
|
+
const imageAlt = feature.imageAlt || (typeof feature.title === "string" ? feature.title : "Feature image");
|
|
1027
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden h-full w-full rounded-t-lg rounded-b-none md:rounded-t-none md:rounded-l-none md:rounded-r-lg", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1028
|
+
img.Img,
|
|
1029
|
+
{
|
|
1030
|
+
src: feature.image,
|
|
1031
|
+
alt: imageAlt,
|
|
1032
|
+
className: "h-full w-full object-cover",
|
|
1033
|
+
loading: "lazy",
|
|
1034
|
+
optixFlowConfig
|
|
1035
|
+
}
|
|
1036
|
+
) });
|
|
1037
|
+
}, []);
|
|
571
1038
|
const featuresContent = React.useMemo(() => {
|
|
572
1039
|
if (featuresSlot) return featuresSlot;
|
|
573
1040
|
if (!features || features.length === 0) return null;
|
|
574
1041
|
return features.map((feature, index) => {
|
|
575
|
-
const imageAlt = feature.imageAlt || (typeof feature.title === "string" ? feature.title : "Feature image");
|
|
576
|
-
const renderImage = () => {
|
|
577
|
-
if (feature.imageSlot) return feature.imageSlot;
|
|
578
|
-
if (feature.image) {
|
|
579
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
580
|
-
img.Img,
|
|
581
|
-
{
|
|
582
|
-
src: feature.image,
|
|
583
|
-
alt: imageAlt,
|
|
584
|
-
className: "h-full w-full object-cover rounded-tr-lg rounded-tl-lg md:rounded-tl-0 rounded-br-0 md:rounded-br-lg",
|
|
585
|
-
loading: "lazy",
|
|
586
|
-
optixFlowConfig
|
|
587
|
-
}
|
|
588
|
-
);
|
|
589
|
-
}
|
|
590
|
-
return null;
|
|
591
|
-
};
|
|
592
1042
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
593
1043
|
"div",
|
|
594
1044
|
{
|
|
595
1045
|
className: cn(
|
|
596
|
-
"grid rounded-lg border md:grid-cols-2",
|
|
1046
|
+
"grid rounded-lg border md:grid-cols-2 bg-background text-foreground",
|
|
597
1047
|
cardClassName,
|
|
598
1048
|
feature.className
|
|
599
1049
|
),
|
|
@@ -602,7 +1052,7 @@ function FeatureNumberedCards({
|
|
|
602
1052
|
"div",
|
|
603
1053
|
{
|
|
604
1054
|
className: cn(
|
|
605
|
-
"flex flex-col px-
|
|
1055
|
+
"flex flex-col px-4 py-4 lg:px-8 lg:py-12 xl:px-12 xl:py-20",
|
|
606
1056
|
feature.contentClassName
|
|
607
1057
|
),
|
|
608
1058
|
children: [
|
|
@@ -610,7 +1060,7 @@ function FeatureNumberedCards({
|
|
|
610
1060
|
"h3",
|
|
611
1061
|
{
|
|
612
1062
|
className: cn(
|
|
613
|
-
"mb-3 text-
|
|
1063
|
+
"mb-3 text-lg font-medium sm:mb-5 md:text-xl lg:text-2xl",
|
|
614
1064
|
titleClassName
|
|
615
1065
|
),
|
|
616
1066
|
children: feature.title
|
|
@@ -619,7 +1069,7 @@ function FeatureNumberedCards({
|
|
|
619
1069
|
"div",
|
|
620
1070
|
{
|
|
621
1071
|
className: cn(
|
|
622
|
-
"mb-3 text-
|
|
1072
|
+
"mb-3 text-lg font-medium sm:mb-5 md:text-xl lg:text-2xl",
|
|
623
1073
|
titleClassName
|
|
624
1074
|
),
|
|
625
1075
|
children: feature.title
|
|
@@ -653,7 +1103,14 @@ function FeatureNumberedCards({
|
|
|
653
1103
|
),
|
|
654
1104
|
children: renderChecklistItems(feature)
|
|
655
1105
|
}
|
|
656
|
-
) : null
|
|
1106
|
+
) : null,
|
|
1107
|
+
actionsContent({
|
|
1108
|
+
actions: feature.actions,
|
|
1109
|
+
actionsSlot: feature.actionsSlot
|
|
1110
|
+
}) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center flex-wrap gap-4 md:gap-2", children: actionsContent({
|
|
1111
|
+
actions: feature.actions,
|
|
1112
|
+
actionsSlot: feature.actionsSlot
|
|
1113
|
+
}) })
|
|
657
1114
|
]
|
|
658
1115
|
}
|
|
659
1116
|
),
|
|
@@ -665,7 +1122,7 @@ function FeatureNumberedCards({
|
|
|
665
1122
|
feature.imageWrapperClassName
|
|
666
1123
|
),
|
|
667
1124
|
children: [
|
|
668
|
-
|
|
1125
|
+
cardImg(feature),
|
|
669
1126
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
670
1127
|
"span",
|
|
671
1128
|
{
|
|
@@ -704,16 +1161,43 @@ function FeatureNumberedCards({
|
|
|
704
1161
|
patternClassName,
|
|
705
1162
|
className,
|
|
706
1163
|
containerClassName,
|
|
707
|
-
children: /* @__PURE__ */ jsxRuntime.
|
|
708
|
-
"div",
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
1164
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col space-y-6 md:space-y-16", children: [
|
|
1165
|
+
title || description ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
1166
|
+
title && (typeof title === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1167
|
+
"h2",
|
|
1168
|
+
{
|
|
1169
|
+
className: cn(
|
|
1170
|
+
"text-xl font-medium tracking-tight md:text-2xl lg:text-3xl text-balance",
|
|
1171
|
+
titleClassName
|
|
1172
|
+
),
|
|
1173
|
+
children: title
|
|
1174
|
+
}
|
|
1175
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: titleClassName, children: title })),
|
|
1176
|
+
description && (typeof description === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1177
|
+
"p",
|
|
1178
|
+
{
|
|
1179
|
+
className: cn("max-w-lg text-balance", descriptionClassName),
|
|
1180
|
+
children: description
|
|
1181
|
+
}
|
|
1182
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
1183
|
+
"div",
|
|
1184
|
+
{
|
|
1185
|
+
className: cn("max-w-lg text-balance", descriptionClassName),
|
|
1186
|
+
children: description
|
|
1187
|
+
}
|
|
1188
|
+
))
|
|
1189
|
+
] }) : null,
|
|
1190
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1191
|
+
"div",
|
|
1192
|
+
{
|
|
1193
|
+
className: cn(
|
|
1194
|
+
"space-y-4 md:space-y-10 rounded-lg border-none md:border p-0 md:p-10",
|
|
1195
|
+
cardsWrapperClassName
|
|
1196
|
+
),
|
|
1197
|
+
children: featuresContent
|
|
1198
|
+
}
|
|
1199
|
+
)
|
|
1200
|
+
] })
|
|
717
1201
|
}
|
|
718
1202
|
);
|
|
719
1203
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { f as SectionBackground, g as SectionSpacing, t as PatternName } from './community-initiatives-Bz_A5vLU.cjs';
|
|
3
|
-
import { O as OptixFlowConfig } from './blocks-Cohq4eio.cjs';
|
|
3
|
+
import { A as ActionConfig, O as OptixFlowConfig } from './blocks-Cohq4eio.cjs';
|
|
4
4
|
import 'react/jsx-runtime';
|
|
5
5
|
import 'class-variance-authority';
|
|
6
6
|
import './button-variants-lRElsmTc.cjs';
|
|
@@ -65,8 +65,24 @@ interface FeatureNumberedCardsItem {
|
|
|
65
65
|
* Additional CSS classes for the image wrapper
|
|
66
66
|
*/
|
|
67
67
|
imageWrapperClassName?: string;
|
|
68
|
+
/**
|
|
69
|
+
* Array of action configurations for CTA buttons
|
|
70
|
+
*/
|
|
71
|
+
actions?: ActionConfig[];
|
|
72
|
+
/**
|
|
73
|
+
* Custom slot for rendering actions (overrides actions array)
|
|
74
|
+
*/
|
|
75
|
+
actionsSlot?: React.ReactNode;
|
|
68
76
|
}
|
|
69
77
|
interface FeatureNumberedCardsProps {
|
|
78
|
+
/**
|
|
79
|
+
* Feature title content
|
|
80
|
+
*/
|
|
81
|
+
title?: React.ReactNode;
|
|
82
|
+
/**
|
|
83
|
+
* Feature description content
|
|
84
|
+
*/
|
|
85
|
+
description?: React.ReactNode;
|
|
70
86
|
/**
|
|
71
87
|
* Array of numbered feature cards
|
|
72
88
|
*/
|
|
@@ -154,6 +170,6 @@ interface FeatureNumberedCardsProps {
|
|
|
154
170
|
* />
|
|
155
171
|
* ```
|
|
156
172
|
*/
|
|
157
|
-
declare function FeatureNumberedCards({ features, featuresSlot, className, containerClassName, cardsWrapperClassName, cardClassName, titleClassName, descriptionClassName, checklistClassName, badgeClassName, optixFlowConfig, background, spacing, pattern, patternOpacity, patternClassName, }: FeatureNumberedCardsProps): React.JSX.Element;
|
|
173
|
+
declare function FeatureNumberedCards({ title, description, features, featuresSlot, className, containerClassName, cardsWrapperClassName, cardClassName, titleClassName, descriptionClassName, checklistClassName, badgeClassName, optixFlowConfig, background, spacing, pattern, patternOpacity, patternClassName, }: FeatureNumberedCardsProps): React.JSX.Element;
|
|
158
174
|
|
|
159
175
|
export { FeatureNumberedCards, type FeatureNumberedCardsProps };
|