@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 framerMotion = require('framer-motion');
|
|
|
6
6
|
var clsx = require('clsx');
|
|
7
7
|
var tailwindMerge = require('tailwind-merge');
|
|
8
8
|
var jsxRuntime = require('react/jsx-runtime');
|
|
9
|
+
var classVarianceAuthority = require('class-variance-authority');
|
|
9
10
|
|
|
10
11
|
function _interopNamespace(e) {
|
|
11
12
|
if (e && e.__esModule) return e;
|
|
@@ -31,32 +32,6 @@ var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
|
31
32
|
function cn(...inputs) {
|
|
32
33
|
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
33
34
|
}
|
|
34
|
-
function getTextColor(parentBg, variant = "default", options) {
|
|
35
|
-
const isDark = parentBg === "dark" || parentBg === "secondary" || parentBg === "primary";
|
|
36
|
-
if (isDark) {
|
|
37
|
-
switch (variant) {
|
|
38
|
-
case "default":
|
|
39
|
-
return "text-foreground";
|
|
40
|
-
case "muted":
|
|
41
|
-
return "text-foreground/80";
|
|
42
|
-
case "subtle":
|
|
43
|
-
return "text-foreground/60";
|
|
44
|
-
case "accent":
|
|
45
|
-
return "text-accent-foreground";
|
|
46
|
-
}
|
|
47
|
-
} else {
|
|
48
|
-
switch (variant) {
|
|
49
|
-
case "default":
|
|
50
|
-
return "text-foreground";
|
|
51
|
-
case "muted":
|
|
52
|
-
return "text-muted-foreground";
|
|
53
|
-
case "subtle":
|
|
54
|
-
return "text-muted-foreground/70";
|
|
55
|
-
case "accent":
|
|
56
|
-
return "text-primary";
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
35
|
var svgCache = /* @__PURE__ */ new Map();
|
|
61
36
|
function DynamicIcon({
|
|
62
37
|
name,
|
|
@@ -188,16 +163,6 @@ function CardHeader({ className, ...props }) {
|
|
|
188
163
|
}
|
|
189
164
|
);
|
|
190
165
|
}
|
|
191
|
-
function CardTitle({ className, ...props }) {
|
|
192
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
193
|
-
"div",
|
|
194
|
-
{
|
|
195
|
-
"data-slot": "card-title",
|
|
196
|
-
className: cn("leading-none font-semibold", className),
|
|
197
|
-
...props
|
|
198
|
-
}
|
|
199
|
-
);
|
|
200
|
-
}
|
|
201
166
|
function CardContent({ className, ...props }) {
|
|
202
167
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
203
168
|
"div",
|
|
@@ -583,6 +548,424 @@ var Section = React__namespace.default.forwardRef(
|
|
|
583
548
|
}
|
|
584
549
|
);
|
|
585
550
|
Section.displayName = "Section";
|
|
551
|
+
var baseStyles = [
|
|
552
|
+
// Layout
|
|
553
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap shrink-0",
|
|
554
|
+
// Typography - using CSS variables with sensible defaults
|
|
555
|
+
"font-[var(--button-font-family,inherit)]",
|
|
556
|
+
"font-[var(--button-font-weight,500)]",
|
|
557
|
+
"tracking-[var(--button-letter-spacing,0)]",
|
|
558
|
+
"leading-[var(--button-line-height,1.25)]",
|
|
559
|
+
"[text-transform:var(--button-text-transform,none)]",
|
|
560
|
+
"text-sm",
|
|
561
|
+
// Border radius
|
|
562
|
+
"rounded-[var(--button-radius,var(--radius,0.375rem))]",
|
|
563
|
+
// Smooth transition - using [transition:...] to set full shorthand property (not just transition-property)
|
|
564
|
+
"[transition:var(--button-transition,all_250ms_cubic-bezier(0.4,0,0.2,1))]",
|
|
565
|
+
// Box shadow (master level) - using [box-shadow:...] for complex multi-value shadows
|
|
566
|
+
"[box-shadow:var(--button-shadow,none)]",
|
|
567
|
+
"hover:[box-shadow:var(--button-shadow-hover,var(--button-shadow,none))]",
|
|
568
|
+
// Disabled state
|
|
569
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
|
570
|
+
// SVG handling
|
|
571
|
+
"[&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0",
|
|
572
|
+
// Focus styles
|
|
573
|
+
"outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
|
574
|
+
// Invalid state
|
|
575
|
+
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive"
|
|
576
|
+
].join(" ");
|
|
577
|
+
var buttonVariants = classVarianceAuthority.cva(baseStyles, {
|
|
578
|
+
variants: {
|
|
579
|
+
variant: {
|
|
580
|
+
// Default (Primary) variant - full customization
|
|
581
|
+
default: [
|
|
582
|
+
"bg-[var(--button-default-bg,hsl(var(--primary)))]",
|
|
583
|
+
"text-[var(--button-default-fg,hsl(var(--primary-foreground)))]",
|
|
584
|
+
"border-[length:var(--button-default-border-width,0px)]",
|
|
585
|
+
"border-[color:var(--button-default-border,transparent)]",
|
|
586
|
+
"[box-shadow:var(--button-default-shadow,var(--button-shadow,none))]",
|
|
587
|
+
"hover:bg-[var(--button-default-hover-bg,hsl(var(--primary)/0.9))]",
|
|
588
|
+
"hover:text-[var(--button-default-hover-fg,var(--button-default-fg,hsl(var(--primary-foreground))))]",
|
|
589
|
+
"hover:border-[color:var(--button-default-hover-border,var(--button-default-border,transparent))]",
|
|
590
|
+
"hover:[box-shadow:var(--button-default-shadow-hover,var(--button-shadow-hover,var(--button-default-shadow,var(--button-shadow,none))))]"
|
|
591
|
+
].join(" "),
|
|
592
|
+
// Destructive variant - full customization
|
|
593
|
+
destructive: [
|
|
594
|
+
"bg-[var(--button-destructive-bg,hsl(var(--destructive)))]",
|
|
595
|
+
"text-[var(--button-destructive-fg,white)]",
|
|
596
|
+
"border-[length:var(--button-destructive-border-width,0px)]",
|
|
597
|
+
"border-[color:var(--button-destructive-border,transparent)]",
|
|
598
|
+
"[box-shadow:var(--button-destructive-shadow,var(--button-shadow,none))]",
|
|
599
|
+
"hover:bg-[var(--button-destructive-hover-bg,hsl(var(--destructive)/0.9))]",
|
|
600
|
+
"hover:text-[var(--button-destructive-hover-fg,var(--button-destructive-fg,white))]",
|
|
601
|
+
"hover:border-[color:var(--button-destructive-hover-border,var(--button-destructive-border,transparent))]",
|
|
602
|
+
"hover:[box-shadow:var(--button-destructive-shadow-hover,var(--button-shadow-hover,var(--button-destructive-shadow,var(--button-shadow,none))))]",
|
|
603
|
+
"focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40",
|
|
604
|
+
"dark:bg-destructive/60"
|
|
605
|
+
].join(" "),
|
|
606
|
+
// Outline variant - full customization with proper border handling
|
|
607
|
+
outline: [
|
|
608
|
+
"bg-[var(--button-outline-bg,hsl(var(--background)))]",
|
|
609
|
+
"text-[var(--button-outline-fg,inherit)]",
|
|
610
|
+
"border-[length:var(--button-outline-border-width,1px)]",
|
|
611
|
+
"border-[color:var(--button-outline-border,hsl(var(--border)))]",
|
|
612
|
+
"[box-shadow:var(--button-outline-shadow,var(--button-shadow,0_1px_2px_0_rgb(0_0_0/0.05)))]",
|
|
613
|
+
"hover:bg-[var(--button-outline-hover-bg,hsl(var(--accent)))]",
|
|
614
|
+
"hover:text-[var(--button-outline-hover-fg,hsl(var(--accent-foreground)))]",
|
|
615
|
+
"hover:border-[color:var(--button-outline-hover-border,var(--button-outline-border,hsl(var(--border))))]",
|
|
616
|
+
"hover:[box-shadow:var(--button-outline-shadow-hover,var(--button-shadow-hover,var(--button-outline-shadow,var(--button-shadow,none))))]",
|
|
617
|
+
"dark:bg-input/30 dark:border-input dark:hover:bg-input/50"
|
|
618
|
+
].join(" "),
|
|
619
|
+
// Secondary variant - full customization
|
|
620
|
+
secondary: [
|
|
621
|
+
"bg-[var(--button-secondary-bg,hsl(var(--secondary)))]",
|
|
622
|
+
"text-[var(--button-secondary-fg,hsl(var(--secondary-foreground)))]",
|
|
623
|
+
"border-[length:var(--button-secondary-border-width,0px)]",
|
|
624
|
+
"border-[color:var(--button-secondary-border,transparent)]",
|
|
625
|
+
"[box-shadow:var(--button-secondary-shadow,var(--button-shadow,none))]",
|
|
626
|
+
"hover:bg-[var(--button-secondary-hover-bg,hsl(var(--secondary)/0.8))]",
|
|
627
|
+
"hover:text-[var(--button-secondary-hover-fg,var(--button-secondary-fg,hsl(var(--secondary-foreground))))]",
|
|
628
|
+
"hover:border-[color:var(--button-secondary-hover-border,var(--button-secondary-border,transparent))]",
|
|
629
|
+
"hover:[box-shadow:var(--button-secondary-shadow-hover,var(--button-shadow-hover,var(--button-secondary-shadow,var(--button-shadow,none))))]"
|
|
630
|
+
].join(" "),
|
|
631
|
+
// Ghost variant - full customization
|
|
632
|
+
ghost: [
|
|
633
|
+
"bg-[var(--button-ghost-bg,transparent)]",
|
|
634
|
+
"text-[var(--button-ghost-fg,inherit)]",
|
|
635
|
+
"border-[length:var(--button-ghost-border-width,0px)]",
|
|
636
|
+
"border-[color:var(--button-ghost-border,transparent)]",
|
|
637
|
+
"[box-shadow:var(--button-ghost-shadow,var(--button-shadow,none))]",
|
|
638
|
+
"hover:bg-[var(--button-ghost-hover-bg,hsl(var(--accent)))]",
|
|
639
|
+
"hover:text-[var(--button-ghost-hover-fg,hsl(var(--accent-foreground)))]",
|
|
640
|
+
"hover:border-[color:var(--button-ghost-hover-border,var(--button-ghost-border,transparent))]",
|
|
641
|
+
"hover:[box-shadow:var(--button-ghost-shadow-hover,var(--button-shadow-hover,var(--button-ghost-shadow,var(--button-shadow,none))))]",
|
|
642
|
+
"dark:hover:bg-accent/50"
|
|
643
|
+
].join(" "),
|
|
644
|
+
// Link variant - full customization
|
|
645
|
+
link: [
|
|
646
|
+
"bg-[var(--button-link-bg,transparent)]",
|
|
647
|
+
"text-[var(--button-link-fg,hsl(var(--primary)))]",
|
|
648
|
+
"border-[length:var(--button-link-border-width,0px)]",
|
|
649
|
+
"border-[color:var(--button-link-border,transparent)]",
|
|
650
|
+
"[box-shadow:var(--button-link-shadow,none)]",
|
|
651
|
+
"hover:bg-[var(--button-link-hover-bg,transparent)]",
|
|
652
|
+
"hover:text-[var(--button-link-hover-fg,var(--button-link-fg,hsl(var(--primary))))]",
|
|
653
|
+
"hover:[box-shadow:var(--button-link-shadow-hover,none)]",
|
|
654
|
+
"underline-offset-4 hover:underline"
|
|
655
|
+
].join(" ")
|
|
656
|
+
},
|
|
657
|
+
size: {
|
|
658
|
+
default: [
|
|
659
|
+
"h-[var(--button-height-md,2.25rem)]",
|
|
660
|
+
"px-[var(--button-padding-x-md,1rem)]",
|
|
661
|
+
"py-[var(--button-padding-y-md,0.5rem)]",
|
|
662
|
+
"has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
|
|
663
|
+
].join(" "),
|
|
664
|
+
sm: [
|
|
665
|
+
"h-[var(--button-height-sm,2rem)]",
|
|
666
|
+
"px-[var(--button-padding-x-sm,0.75rem)]",
|
|
667
|
+
"py-[var(--button-padding-y-sm,0.25rem)]",
|
|
668
|
+
"gap-1.5",
|
|
669
|
+
"has-[>svg]:px-[calc(var(--button-padding-x-sm,0.75rem)*0.83)]"
|
|
670
|
+
].join(" "),
|
|
671
|
+
md: [
|
|
672
|
+
"h-[var(--button-height-md,2.25rem)]",
|
|
673
|
+
"px-[var(--button-padding-x-md,1rem)]",
|
|
674
|
+
"py-[var(--button-padding-y-md,0.5rem)]",
|
|
675
|
+
"has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
|
|
676
|
+
].join(" "),
|
|
677
|
+
lg: [
|
|
678
|
+
"h-[var(--button-height-lg,2.5rem)]",
|
|
679
|
+
"px-[var(--button-padding-x-lg,1.5rem)]",
|
|
680
|
+
"py-[var(--button-padding-y-lg,0.5rem)]",
|
|
681
|
+
"has-[>svg]:px-[calc(var(--button-padding-x-lg,1.5rem)*0.67)]"
|
|
682
|
+
].join(" "),
|
|
683
|
+
icon: "size-[var(--button-height-md,2.25rem)]",
|
|
684
|
+
"icon-sm": "size-[var(--button-height-sm,2rem)]",
|
|
685
|
+
"icon-lg": "size-[var(--button-height-lg,2.5rem)]"
|
|
686
|
+
}
|
|
687
|
+
},
|
|
688
|
+
defaultVariants: {
|
|
689
|
+
variant: "default",
|
|
690
|
+
size: "default"
|
|
691
|
+
}
|
|
692
|
+
});
|
|
693
|
+
function normalizePhoneNumber(input) {
|
|
694
|
+
const trimmed = input.trim();
|
|
695
|
+
if (trimmed.toLowerCase().startsWith("tel:")) {
|
|
696
|
+
return trimmed;
|
|
697
|
+
}
|
|
698
|
+
const match = trimmed.match(/^[\s\+\-\(\)]*(\d[\d\s\-\(\)\.]*\d)[\s\-]*(x|ext\.?|extension)?[\s\-]*(\d+)?$/i);
|
|
699
|
+
if (match) {
|
|
700
|
+
const mainNumber = match[1].replace(/[\s\-\(\)\.]/g, "");
|
|
701
|
+
const extension = match[3];
|
|
702
|
+
const normalized = mainNumber.length >= 10 && !trimmed.startsWith("+") ? `+${mainNumber}` : mainNumber;
|
|
703
|
+
const withExtension = extension ? `${normalized};ext=${extension}` : normalized;
|
|
704
|
+
return `tel:${withExtension}`;
|
|
705
|
+
}
|
|
706
|
+
const cleaned = trimmed.replace(/[\s\-\(\)\.]/g, "");
|
|
707
|
+
return `tel:${cleaned}`;
|
|
708
|
+
}
|
|
709
|
+
function normalizeEmail(input) {
|
|
710
|
+
const trimmed = input.trim();
|
|
711
|
+
if (trimmed.toLowerCase().startsWith("mailto:")) {
|
|
712
|
+
return trimmed;
|
|
713
|
+
}
|
|
714
|
+
return `mailto:${trimmed}`;
|
|
715
|
+
}
|
|
716
|
+
function isEmail(input) {
|
|
717
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
718
|
+
return emailRegex.test(input.trim());
|
|
719
|
+
}
|
|
720
|
+
function isPhoneNumber(input) {
|
|
721
|
+
const trimmed = input.trim();
|
|
722
|
+
if (trimmed.toLowerCase().startsWith("tel:")) {
|
|
723
|
+
return true;
|
|
724
|
+
}
|
|
725
|
+
const phoneRegex = /^[\s\+\-\(\)]*\d[\d\s\-\(\)\.]*\d[\s\-]*(x|ext\.?|extension)?[\s\-]*\d*$/i;
|
|
726
|
+
return phoneRegex.test(trimmed);
|
|
727
|
+
}
|
|
728
|
+
function isInternalUrl(href) {
|
|
729
|
+
if (typeof window === "undefined") {
|
|
730
|
+
return href.startsWith("/") && !href.startsWith("//");
|
|
731
|
+
}
|
|
732
|
+
const trimmed = href.trim();
|
|
733
|
+
if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
|
|
734
|
+
return true;
|
|
735
|
+
}
|
|
736
|
+
try {
|
|
737
|
+
const url = new URL(trimmed, window.location.href);
|
|
738
|
+
const currentOrigin = window.location.origin;
|
|
739
|
+
const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
|
|
740
|
+
return normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin);
|
|
741
|
+
} catch {
|
|
742
|
+
return false;
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
function toRelativePath(href) {
|
|
746
|
+
if (typeof window === "undefined") {
|
|
747
|
+
return href;
|
|
748
|
+
}
|
|
749
|
+
const trimmed = href.trim();
|
|
750
|
+
if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
|
|
751
|
+
return trimmed;
|
|
752
|
+
}
|
|
753
|
+
try {
|
|
754
|
+
const url = new URL(trimmed, window.location.href);
|
|
755
|
+
const currentOrigin = window.location.origin;
|
|
756
|
+
const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
|
|
757
|
+
if (normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin)) {
|
|
758
|
+
return url.pathname + url.search + url.hash;
|
|
759
|
+
}
|
|
760
|
+
} catch {
|
|
761
|
+
}
|
|
762
|
+
return trimmed;
|
|
763
|
+
}
|
|
764
|
+
function useNavigation({
|
|
765
|
+
href,
|
|
766
|
+
onClick
|
|
767
|
+
} = {}) {
|
|
768
|
+
const linkType = React__namespace.useMemo(() => {
|
|
769
|
+
if (!href || href.trim() === "") {
|
|
770
|
+
return onClick ? "none" : "none";
|
|
771
|
+
}
|
|
772
|
+
const trimmed = href.trim();
|
|
773
|
+
if (trimmed.toLowerCase().startsWith("mailto:") || isEmail(trimmed)) {
|
|
774
|
+
return "mailto";
|
|
775
|
+
}
|
|
776
|
+
if (trimmed.toLowerCase().startsWith("tel:") || isPhoneNumber(trimmed)) {
|
|
777
|
+
return "tel";
|
|
778
|
+
}
|
|
779
|
+
if (isInternalUrl(trimmed)) {
|
|
780
|
+
return "internal";
|
|
781
|
+
}
|
|
782
|
+
try {
|
|
783
|
+
new URL(trimmed, typeof window !== "undefined" ? window.location.href : "http://localhost");
|
|
784
|
+
return "external";
|
|
785
|
+
} catch {
|
|
786
|
+
return "internal";
|
|
787
|
+
}
|
|
788
|
+
}, [href, onClick]);
|
|
789
|
+
const normalizedHref = React__namespace.useMemo(() => {
|
|
790
|
+
if (!href || href.trim() === "") {
|
|
791
|
+
return void 0;
|
|
792
|
+
}
|
|
793
|
+
const trimmed = href.trim();
|
|
794
|
+
switch (linkType) {
|
|
795
|
+
case "tel":
|
|
796
|
+
return normalizePhoneNumber(trimmed);
|
|
797
|
+
case "mailto":
|
|
798
|
+
return normalizeEmail(trimmed);
|
|
799
|
+
case "internal":
|
|
800
|
+
return toRelativePath(trimmed);
|
|
801
|
+
case "external":
|
|
802
|
+
return trimmed;
|
|
803
|
+
default:
|
|
804
|
+
return trimmed;
|
|
805
|
+
}
|
|
806
|
+
}, [href, linkType]);
|
|
807
|
+
const target = React__namespace.useMemo(() => {
|
|
808
|
+
switch (linkType) {
|
|
809
|
+
case "external":
|
|
810
|
+
return "_blank";
|
|
811
|
+
case "internal":
|
|
812
|
+
return "_self";
|
|
813
|
+
case "mailto":
|
|
814
|
+
case "tel":
|
|
815
|
+
return void 0;
|
|
816
|
+
default:
|
|
817
|
+
return void 0;
|
|
818
|
+
}
|
|
819
|
+
}, [linkType]);
|
|
820
|
+
const rel = React__namespace.useMemo(() => {
|
|
821
|
+
if (linkType === "external") {
|
|
822
|
+
return "noopener noreferrer";
|
|
823
|
+
}
|
|
824
|
+
return void 0;
|
|
825
|
+
}, [linkType]);
|
|
826
|
+
const isExternal = linkType === "external";
|
|
827
|
+
const isInternal = linkType === "internal";
|
|
828
|
+
const shouldUseRouter = isInternal && typeof normalizedHref === "string" && normalizedHref.startsWith("/");
|
|
829
|
+
const handleClick = React__namespace.useCallback(
|
|
830
|
+
(event) => {
|
|
831
|
+
if (onClick) {
|
|
832
|
+
try {
|
|
833
|
+
onClick(event);
|
|
834
|
+
} catch (error) {
|
|
835
|
+
console.error("Error in user onClick handler:", error);
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
if (event.defaultPrevented) {
|
|
839
|
+
return;
|
|
840
|
+
}
|
|
841
|
+
if (shouldUseRouter && normalizedHref && event.button === 0 && // left-click only
|
|
842
|
+
!event.metaKey && !event.altKey && !event.ctrlKey && !event.shiftKey) {
|
|
843
|
+
if (typeof window !== "undefined") {
|
|
844
|
+
const handler = window.__opensiteNavigationHandler;
|
|
845
|
+
if (typeof handler === "function") {
|
|
846
|
+
try {
|
|
847
|
+
const handled = handler(normalizedHref, event.nativeEvent || event);
|
|
848
|
+
if (handled !== false) {
|
|
849
|
+
event.preventDefault();
|
|
850
|
+
}
|
|
851
|
+
} catch (error) {
|
|
852
|
+
console.error("Error in navigation handler:", error);
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
},
|
|
858
|
+
[onClick, shouldUseRouter, normalizedHref]
|
|
859
|
+
);
|
|
860
|
+
return {
|
|
861
|
+
linkType,
|
|
862
|
+
normalizedHref,
|
|
863
|
+
target,
|
|
864
|
+
rel,
|
|
865
|
+
isExternal,
|
|
866
|
+
isInternal,
|
|
867
|
+
shouldUseRouter,
|
|
868
|
+
handleClick
|
|
869
|
+
};
|
|
870
|
+
}
|
|
871
|
+
var Pressable = React__namespace.forwardRef(
|
|
872
|
+
({
|
|
873
|
+
children,
|
|
874
|
+
className,
|
|
875
|
+
href,
|
|
876
|
+
onClick,
|
|
877
|
+
variant,
|
|
878
|
+
size,
|
|
879
|
+
asButton = false,
|
|
880
|
+
fallbackComponentType = "span",
|
|
881
|
+
componentType,
|
|
882
|
+
"aria-label": ariaLabel,
|
|
883
|
+
"aria-describedby": ariaDescribedby,
|
|
884
|
+
id,
|
|
885
|
+
...props
|
|
886
|
+
}, ref) => {
|
|
887
|
+
const navigation = useNavigation({ href, onClick });
|
|
888
|
+
const {
|
|
889
|
+
normalizedHref,
|
|
890
|
+
target,
|
|
891
|
+
rel,
|
|
892
|
+
linkType,
|
|
893
|
+
isInternal,
|
|
894
|
+
handleClick
|
|
895
|
+
} = navigation;
|
|
896
|
+
const shouldRenderLink = normalizedHref && linkType !== "none";
|
|
897
|
+
const shouldRenderButton = !shouldRenderLink && onClick;
|
|
898
|
+
const effectiveComponentType = componentType || (shouldRenderLink ? "a" : shouldRenderButton ? "button" : fallbackComponentType);
|
|
899
|
+
const finalComponentType = isInternal && shouldRenderLink ? "a" : effectiveComponentType;
|
|
900
|
+
const shouldApplyButtonStyles = asButton || variant || size;
|
|
901
|
+
const combinedClassName = cn(
|
|
902
|
+
shouldApplyButtonStyles && buttonVariants({ variant, size }),
|
|
903
|
+
className
|
|
904
|
+
);
|
|
905
|
+
const dataProps = Object.fromEntries(
|
|
906
|
+
Object.entries(props).filter(([key]) => key.startsWith("data-"))
|
|
907
|
+
);
|
|
908
|
+
const buttonDataAttributes = shouldApplyButtonStyles ? {
|
|
909
|
+
"data-slot": "button",
|
|
910
|
+
"data-variant": variant ?? "default",
|
|
911
|
+
"data-size": size ?? "default"
|
|
912
|
+
} : {};
|
|
913
|
+
const commonProps = {
|
|
914
|
+
className: combinedClassName,
|
|
915
|
+
onClick: handleClick,
|
|
916
|
+
"aria-label": ariaLabel,
|
|
917
|
+
"aria-describedby": ariaDescribedby,
|
|
918
|
+
id,
|
|
919
|
+
...dataProps,
|
|
920
|
+
...buttonDataAttributes
|
|
921
|
+
};
|
|
922
|
+
if (finalComponentType === "a" && shouldRenderLink) {
|
|
923
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
924
|
+
"a",
|
|
925
|
+
{
|
|
926
|
+
ref,
|
|
927
|
+
href: normalizedHref,
|
|
928
|
+
target,
|
|
929
|
+
rel,
|
|
930
|
+
...commonProps,
|
|
931
|
+
...props,
|
|
932
|
+
children
|
|
933
|
+
}
|
|
934
|
+
);
|
|
935
|
+
}
|
|
936
|
+
if (finalComponentType === "button") {
|
|
937
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
938
|
+
"button",
|
|
939
|
+
{
|
|
940
|
+
ref,
|
|
941
|
+
type: props.type || "button",
|
|
942
|
+
...commonProps,
|
|
943
|
+
...props,
|
|
944
|
+
children
|
|
945
|
+
}
|
|
946
|
+
);
|
|
947
|
+
}
|
|
948
|
+
if (finalComponentType === "div") {
|
|
949
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
950
|
+
"div",
|
|
951
|
+
{
|
|
952
|
+
ref,
|
|
953
|
+
...commonProps,
|
|
954
|
+
children
|
|
955
|
+
}
|
|
956
|
+
);
|
|
957
|
+
}
|
|
958
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
959
|
+
"span",
|
|
960
|
+
{
|
|
961
|
+
ref,
|
|
962
|
+
...commonProps,
|
|
963
|
+
children
|
|
964
|
+
}
|
|
965
|
+
);
|
|
966
|
+
}
|
|
967
|
+
);
|
|
968
|
+
Pressable.displayName = "Pressable";
|
|
586
969
|
function FeatureCapabilitiesGrid({
|
|
587
970
|
eyebrow,
|
|
588
971
|
heading,
|
|
@@ -600,11 +983,14 @@ function FeatureCapabilitiesGrid({
|
|
|
600
983
|
patternOpacity,
|
|
601
984
|
patternClassName
|
|
602
985
|
}) {
|
|
603
|
-
const renderItemIcon = React__namespace.useCallback(
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
986
|
+
const renderItemIcon = React__namespace.useCallback(
|
|
987
|
+
(item) => {
|
|
988
|
+
if (item.icon) return item.icon;
|
|
989
|
+
if (item.iconName) return /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: item.iconName, size: 20 });
|
|
990
|
+
return null;
|
|
991
|
+
},
|
|
992
|
+
[]
|
|
993
|
+
);
|
|
608
994
|
const itemsContent = React.useMemo(() => {
|
|
609
995
|
if (itemsSlot) return itemsSlot;
|
|
610
996
|
if (!items || items.length === 0) return null;
|
|
@@ -613,7 +999,11 @@ function FeatureCapabilitiesGrid({
|
|
|
613
999
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
614
1000
|
Card,
|
|
615
1001
|
{
|
|
616
|
-
className: cn(
|
|
1002
|
+
className: cn(
|
|
1003
|
+
"group relative overflow-visible border-border/10 bg-background/5 p-0 transition-colors duration-300 hover:border-border/20",
|
|
1004
|
+
cardClassName,
|
|
1005
|
+
item.className
|
|
1006
|
+
),
|
|
617
1007
|
children: [
|
|
618
1008
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-none absolute inset-0 opacity-0 transition-opacity duration-300 group-hover:opacity-100", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -inset-px rounded-xl bg-linear-to-br from-background/10 via-background/5 to-transparent" }) }),
|
|
619
1009
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-none absolute inset-0 rounded-xl bg-linear-to-tr from-background/0 to-background/0 transition-colors group-hover:from-background/3 group-hover:to-background/6" }),
|
|
@@ -624,13 +1014,59 @@ function FeatureCapabilitiesGrid({
|
|
|
624
1014
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -right-2 -bottom-2 h-3 w-3 bg-background" })
|
|
625
1015
|
] }),
|
|
626
1016
|
/* @__PURE__ */ jsxRuntime.jsxs(CardHeader, { className: "relative z-10 flex flex-row items-start gap-3 p-6", children: [
|
|
627
|
-
iconContent && /* @__PURE__ */ jsxRuntime.jsx(
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
1017
|
+
iconContent && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1018
|
+
"div",
|
|
1019
|
+
{
|
|
1020
|
+
className: cn(
|
|
1021
|
+
"flex h-10 w-10 items-center justify-center rounded-xl border border-border/15 bg-background/5",
|
|
1022
|
+
item.iconClassName
|
|
1023
|
+
),
|
|
1024
|
+
children: iconContent
|
|
1025
|
+
}
|
|
1026
|
+
),
|
|
1027
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1028
|
+
Pressable,
|
|
1029
|
+
{
|
|
1030
|
+
href: item.href,
|
|
1031
|
+
className: "flex-1 h-full flex items-center",
|
|
1032
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1033
|
+
item.title && (typeof item.title === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1034
|
+
"h3",
|
|
1035
|
+
{
|
|
1036
|
+
className: cn("text-lg font-medium", item.titleClassName),
|
|
1037
|
+
children: item.title
|
|
1038
|
+
}
|
|
1039
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
1040
|
+
"div",
|
|
1041
|
+
{
|
|
1042
|
+
className: cn("text-lg font-medium", item.titleClassName),
|
|
1043
|
+
children: item.title
|
|
1044
|
+
}
|
|
1045
|
+
)),
|
|
1046
|
+
item.badge && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1047
|
+
"span",
|
|
1048
|
+
{
|
|
1049
|
+
className: cn(
|
|
1050
|
+
"rounded-full border border-border/20 px-2 py-0.5 text-[10px] leading-none",
|
|
1051
|
+
item.badgeClassName
|
|
1052
|
+
),
|
|
1053
|
+
children: item.badge
|
|
1054
|
+
}
|
|
1055
|
+
)
|
|
1056
|
+
] })
|
|
1057
|
+
}
|
|
1058
|
+
)
|
|
632
1059
|
] }),
|
|
633
|
-
item.description && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1060
|
+
item.description && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1061
|
+
CardContent,
|
|
1062
|
+
{
|
|
1063
|
+
className: cn(
|
|
1064
|
+
"relative z-10 px-6 pb-6 text-sm",
|
|
1065
|
+
item.descriptionClassName
|
|
1066
|
+
),
|
|
1067
|
+
children: item.description
|
|
1068
|
+
}
|
|
1069
|
+
),
|
|
634
1070
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
635
1071
|
framerMotion.motion.div,
|
|
636
1072
|
{
|
|
@@ -646,7 +1082,7 @@ function FeatureCapabilitiesGrid({
|
|
|
646
1082
|
);
|
|
647
1083
|
});
|
|
648
1084
|
}, [itemsSlot, items, cardClassName, renderItemIcon]);
|
|
649
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
1085
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
650
1086
|
Section,
|
|
651
1087
|
{
|
|
652
1088
|
background,
|
|
@@ -656,11 +1092,46 @@ function FeatureCapabilitiesGrid({
|
|
|
656
1092
|
patternClassName,
|
|
657
1093
|
className,
|
|
658
1094
|
containerClassName,
|
|
659
|
-
children: [
|
|
660
|
-
eyebrow
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
1095
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col space-y-6 md:space-y-16", children: [
|
|
1096
|
+
eyebrow || heading ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
|
|
1097
|
+
eyebrow && (typeof eyebrow === "string" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("text-xs tracking-widest", eyebrowClassName), children: eyebrow }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
1098
|
+
"div",
|
|
1099
|
+
{
|
|
1100
|
+
className: cn("text-xs tracking-widest", eyebrowClassName),
|
|
1101
|
+
children: eyebrow
|
|
1102
|
+
}
|
|
1103
|
+
)),
|
|
1104
|
+
heading && (typeof heading === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1105
|
+
"h2",
|
|
1106
|
+
{
|
|
1107
|
+
className: cn(
|
|
1108
|
+
"mt-3 text-4xl font-semibold tracking-tight sm:text-5xl",
|
|
1109
|
+
headingClassName
|
|
1110
|
+
),
|
|
1111
|
+
children: heading
|
|
1112
|
+
}
|
|
1113
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
1114
|
+
"div",
|
|
1115
|
+
{
|
|
1116
|
+
className: cn(
|
|
1117
|
+
"mt-3 text-4xl font-semibold tracking-tight sm:text-5xl",
|
|
1118
|
+
headingClassName
|
|
1119
|
+
),
|
|
1120
|
+
children: heading
|
|
1121
|
+
}
|
|
1122
|
+
))
|
|
1123
|
+
] }) : null,
|
|
1124
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1125
|
+
"div",
|
|
1126
|
+
{
|
|
1127
|
+
className: cn(
|
|
1128
|
+
"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3",
|
|
1129
|
+
gridClassName
|
|
1130
|
+
),
|
|
1131
|
+
children: itemsContent
|
|
1132
|
+
}
|
|
1133
|
+
)
|
|
1134
|
+
] })
|
|
664
1135
|
}
|
|
665
1136
|
);
|
|
666
1137
|
}
|