@opensite/ui 3.3.1 → 3.3.3

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.
@@ -34,36 +34,6 @@ var React__namespace = /*#__PURE__*/_interopNamespace(React);
34
34
  function cn(...inputs) {
35
35
  return tailwindMerge.twMerge(clsx.clsx(inputs));
36
36
  }
37
- function getNestedCardBg(parentBg, variant = "muted", options) {
38
- const isDark = parentBg === "dark" || parentBg === "secondary" || parentBg === "primary";
39
- if (isDark) {
40
- switch (variant) {
41
- case "muted":
42
- return "bg-background";
43
- case "card":
44
- return "bg-card";
45
- case "accent":
46
- return "bg-accent";
47
- case "subtle":
48
- return "bg-background/50";
49
- }
50
- } else {
51
- switch (variant) {
52
- case "muted":
53
- return "bg-muted";
54
- case "card":
55
- return "bg-card";
56
- case "accent":
57
- return "bg-accent";
58
- case "subtle":
59
- return "bg-muted/50";
60
- }
61
- }
62
- }
63
- function getNestedCardTextColor(parentBg, options) {
64
- const isDark = parentBg === "dark" || parentBg === "secondary" || parentBg === "primary";
65
- return isDark ? "text-foreground" : "";
66
- }
67
37
  var badgeVariants = classVarianceAuthority.cva(
68
38
  "inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
69
39
  {
@@ -480,6 +450,70 @@ var Section = React__namespace.default.forwardRef(
480
450
  }
481
451
  );
482
452
  Section.displayName = "Section";
453
+ var MOBILE_CLASSES = {
454
+ "fit-left": "items-start md:items-center",
455
+ "fit-center": "items-center",
456
+ "fit-right": "items-end md:items-center",
457
+ "full-left": "items-stretch md:items-center",
458
+ "full-center": "items-stretch md:items-center",
459
+ "full-right": "items-stretch md:items-center"
460
+ };
461
+ function BlockActions({
462
+ mobileConfig,
463
+ actionsClassName,
464
+ verticalSpacing = "mt-4 md:mt-8",
465
+ actions,
466
+ actionsSlot
467
+ }) {
468
+ const width = mobileConfig?.width ?? "full";
469
+ const position = mobileConfig?.position ?? "center";
470
+ const mobileLayoutClass = MOBILE_CLASSES[`${width}-${position}`];
471
+ if (actionsSlot) {
472
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { children: actionsSlot });
473
+ } else if (actions && actions?.length > 0) {
474
+ return /* @__PURE__ */ jsxRuntime.jsx(
475
+ "div",
476
+ {
477
+ className: cn(
478
+ "flex flex-col md:flex-row flex-wrap gap-4",
479
+ mobileLayoutClass,
480
+ actionsClassName,
481
+ verticalSpacing
482
+ ),
483
+ children: actions.map((action, index) => /* @__PURE__ */ jsxRuntime.jsx(ActionComponent, { action }, index))
484
+ }
485
+ );
486
+ } else {
487
+ return null;
488
+ }
489
+ }
490
+ function ActionComponent({ action }) {
491
+ const {
492
+ label,
493
+ icon,
494
+ iconAfter,
495
+ children,
496
+ href,
497
+ onClick,
498
+ className: actionClassName,
499
+ ...pressableProps
500
+ } = action;
501
+ return /* @__PURE__ */ jsxRuntime.jsx(
502
+ pressable.Pressable,
503
+ {
504
+ href,
505
+ onClick,
506
+ asButton: action.asButton ?? true,
507
+ className: actionClassName,
508
+ ...pressableProps,
509
+ children: children ?? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
510
+ icon,
511
+ label,
512
+ iconAfter
513
+ ] })
514
+ }
515
+ );
516
+ }
483
517
  function StatsGrowthTimeline({
484
518
  sectionId = "stats-growth-timeline",
485
519
  badge,
@@ -496,6 +530,7 @@ function StatsGrowthTimeline({
496
530
  futureSlot,
497
531
  actions,
498
532
  actionsSlot,
533
+ actionsClassName,
499
534
  background,
500
535
  pattern,
501
536
  patternOpacity,
@@ -542,19 +577,18 @@ function StatsGrowthTimeline({
542
577
  "div",
543
578
  {
544
579
  className: cn(
545
- "mb-4 inline-flex h-9 w-20 items-center justify-center rounded-full text-sm font-semibold",
546
- getNestedCardBg(background, "muted"),
547
- getNestedCardTextColor(background)
580
+ "bg-muted text-muted-foreground",
581
+ "mb-4 inline-flex h-fit py-2 w-fit px-4 items-center justify-center rounded-full text-sm font-semibold"
548
582
  ),
549
583
  children: milestone.year
550
584
  }
551
585
  ),
552
- milestone.title && (typeof milestone.title === "string" ? /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "mb-2 text-xl font-bold", children: milestone.title }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2", children: milestone.title })),
553
- milestone.description && (typeof milestone.description === "string" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-4 text-muted-foreground", children: milestone.description }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-4", children: milestone.description })),
586
+ milestone.title && (typeof milestone.title === "string" ? /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "mb-2 text-xl font-bold", children: milestone.title }) : milestone.title),
587
+ milestone.description && (typeof milestone.description === "string" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-4 text-muted-foreground", children: milestone.description }) : milestone.description),
554
588
  milestone.metric && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4 rounded-lg border bg-background p-4 shadow-sm", children: [
555
589
  renderMilestoneIcon(milestone),
556
590
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
557
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-3xl font-bold text-primary", children: milestone.metric.value }),
591
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-2xl font-bold text-primary", children: milestone.metric.value }),
558
592
  milestone.metric.label && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-muted-foreground", children: milestone.metric.label })
559
593
  ] })
560
594
  ] })
@@ -580,16 +614,15 @@ function StatsGrowthTimeline({
580
614
  "div",
581
615
  {
582
616
  className: cn(
583
- "mt-24 rounded-lg p-8",
584
- getNestedCardBg(background, "muted"),
585
- getNestedCardTextColor(background),
617
+ "p-6 md:p-12 bg-card text-card-foreground",
618
+ "mt-24 rounded-lg border border-border shadow-md",
586
619
  currentStatsClassName
587
620
  ),
588
621
  children: [
589
- currentStatsHeading && (typeof currentStatsHeading === "string" ? /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "mb-6 text-center text-2xl font-bold", children: currentStatsHeading }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-6 text-center", children: currentStatsHeading })),
622
+ currentStatsHeading && (typeof currentStatsHeading === "string" ? /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "mb-12 text-center text-4xl lg:text-5xl font-bold", children: currentStatsHeading }) : currentStatsHeading),
590
623
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 gap-8 md:grid-cols-4", children: currentStats.map((stat, index) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("text-center", stat.className), children: [
591
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2 text-3xl font-bold text-primary md:text-4xl", children: stat.value }),
592
- stat.label && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium text-muted-foreground", children: stat.label })
624
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-2xl font-semibold text-primary md:text-3xl xl:text-4xl", children: stat.value }),
625
+ stat.label && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium text-balance text-sm", children: stat.label })
593
626
  ] }, index)) })
594
627
  ]
595
628
  }
@@ -601,39 +634,29 @@ function StatsGrowthTimeline({
601
634
  currentStatsHeading,
602
635
  currentStatsClassName
603
636
  ]);
604
- const actionsContent = React.useMemo(() => {
605
- if (actionsSlot) return actionsSlot;
606
- if (!actions || actions.length === 0) return null;
607
- return actions.map((action, index) => /* @__PURE__ */ jsxRuntime.jsxs(
608
- pressable.Pressable,
609
- {
610
- href: action.href,
611
- onClick: action.onClick,
612
- variant: action.variant,
613
- className: "inline-flex items-center font-medium text-primary hover:underline",
614
- children: [
615
- action.label,
616
- /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/arrow-right", size: 16, className: "ml-2" })
617
- ]
618
- },
619
- index
620
- ));
621
- }, [actionsSlot, actions]);
622
637
  const futureContent = React.useMemo(() => {
623
638
  if (futureSlot) return futureSlot;
624
639
  if (!futureHeading && !futureDescription && (!actions || actions.length === 0))
625
640
  return null;
626
641
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("mt-16 text-center", futureClassName), children: [
627
642
  futureHeading && (typeof futureHeading === "string" ? /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "mb-4 text-2xl font-bold", children: futureHeading }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-4", children: futureHeading })),
628
- futureDescription && (typeof futureDescription === "string" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mx-auto mb-8 max-w-2xl text-muted-foreground", children: futureDescription }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto mb-8 max-w-2xl", children: futureDescription })),
629
- actionsContent
643
+ futureDescription && (typeof futureDescription === "string" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mx-auto mb-8 max-w-full md:max-w-lg text-balance", children: futureDescription }) : futureDescription),
644
+ /* @__PURE__ */ jsxRuntime.jsx(
645
+ BlockActions,
646
+ {
647
+ actions,
648
+ actionsSlot,
649
+ actionsClassName
650
+ }
651
+ )
630
652
  ] });
631
653
  }, [
632
654
  futureSlot,
633
655
  futureHeading,
634
656
  futureDescription,
635
657
  futureClassName,
636
- actionsContent,
658
+ actionsSlot,
659
+ actionsClassName,
637
660
  actions
638
661
  ]);
639
662
  const hasHeaderContent = !!(badge || badgeSlot || heading || description);
@@ -670,7 +693,7 @@ function StatsGrowthTimeline({
670
693
  ),
671
694
  children: description
672
695
  }
673
- ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("mx-auto max-w-3xl", descriptionClassName), children: description }))
696
+ ) : description)
674
697
  ] }),
675
698
  milestonesContent,
676
699
  currentStatsContent,
@@ -126,6 +126,10 @@ interface StatsGrowthTimelineProps {
126
126
  * Custom slot for rendering actions (overrides actions array)
127
127
  */
128
128
  actionsSlot?: React.ReactNode;
129
+ /**
130
+ * Additional CSS classes for the actions container
131
+ */
132
+ actionsClassName?: string;
129
133
  /**
130
134
  * Background style for the section
131
135
  */
@@ -206,6 +210,6 @@ interface StatsGrowthTimelineProps {
206
210
  * />
207
211
  * ```
208
212
  */
209
- declare function StatsGrowthTimeline({ sectionId, badge, badgeSlot, heading, description, milestones, milestonesSlot, currentStats, currentStatsSlot, currentStatsHeading, futureHeading, futureDescription, futureSlot, actions, actionsSlot, background, pattern, patternOpacity, patternClassName, className, containerClassName, spacing, headerClassName, badgeClassName, headingClassName, descriptionClassName, timelineClassName, milestoneClassName, currentStatsClassName, futureClassName, }: StatsGrowthTimelineProps): react_jsx_runtime.JSX.Element;
213
+ declare function StatsGrowthTimeline({ sectionId, badge, badgeSlot, heading, description, milestones, milestonesSlot, currentStats, currentStatsSlot, currentStatsHeading, futureHeading, futureDescription, futureSlot, actions, actionsSlot, actionsClassName, background, pattern, patternOpacity, patternClassName, className, containerClassName, spacing, headerClassName, badgeClassName, headingClassName, descriptionClassName, timelineClassName, milestoneClassName, currentStatsClassName, futureClassName, }: StatsGrowthTimelineProps): react_jsx_runtime.JSX.Element;
210
214
 
211
215
  export { type CurrentStat, type Milestone, StatsGrowthTimeline, type StatsGrowthTimelineProps };
@@ -126,6 +126,10 @@ interface StatsGrowthTimelineProps {
126
126
  * Custom slot for rendering actions (overrides actions array)
127
127
  */
128
128
  actionsSlot?: React.ReactNode;
129
+ /**
130
+ * Additional CSS classes for the actions container
131
+ */
132
+ actionsClassName?: string;
129
133
  /**
130
134
  * Background style for the section
131
135
  */
@@ -206,6 +210,6 @@ interface StatsGrowthTimelineProps {
206
210
  * />
207
211
  * ```
208
212
  */
209
- declare function StatsGrowthTimeline({ sectionId, badge, badgeSlot, heading, description, milestones, milestonesSlot, currentStats, currentStatsSlot, currentStatsHeading, futureHeading, futureDescription, futureSlot, actions, actionsSlot, background, pattern, patternOpacity, patternClassName, className, containerClassName, spacing, headerClassName, badgeClassName, headingClassName, descriptionClassName, timelineClassName, milestoneClassName, currentStatsClassName, futureClassName, }: StatsGrowthTimelineProps): react_jsx_runtime.JSX.Element;
213
+ declare function StatsGrowthTimeline({ sectionId, badge, badgeSlot, heading, description, milestones, milestonesSlot, currentStats, currentStatsSlot, currentStatsHeading, futureHeading, futureDescription, futureSlot, actions, actionsSlot, actionsClassName, background, pattern, patternOpacity, patternClassName, className, containerClassName, spacing, headerClassName, badgeClassName, headingClassName, descriptionClassName, timelineClassName, milestoneClassName, currentStatsClassName, futureClassName, }: StatsGrowthTimelineProps): react_jsx_runtime.JSX.Element;
210
214
 
211
215
  export { type CurrentStat, type Milestone, StatsGrowthTimeline, type StatsGrowthTimelineProps };
@@ -5,7 +5,7 @@ import { clsx } from 'clsx';
5
5
  import { twMerge } from 'tailwind-merge';
6
6
  import { Slot } from '@radix-ui/react-slot';
7
7
  import { cva } from 'class-variance-authority';
8
- import { jsx, jsxs } from 'react/jsx-runtime';
8
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
9
9
  import { Icon } from '@page-speed/icon';
10
10
  import { Pressable } from '@page-speed/pressable';
11
11
 
@@ -13,36 +13,6 @@ import { Pressable } from '@page-speed/pressable';
13
13
  function cn(...inputs) {
14
14
  return twMerge(clsx(inputs));
15
15
  }
16
- function getNestedCardBg(parentBg, variant = "muted", options) {
17
- const isDark = parentBg === "dark" || parentBg === "secondary" || parentBg === "primary";
18
- if (isDark) {
19
- switch (variant) {
20
- case "muted":
21
- return "bg-background";
22
- case "card":
23
- return "bg-card";
24
- case "accent":
25
- return "bg-accent";
26
- case "subtle":
27
- return "bg-background/50";
28
- }
29
- } else {
30
- switch (variant) {
31
- case "muted":
32
- return "bg-muted";
33
- case "card":
34
- return "bg-card";
35
- case "accent":
36
- return "bg-accent";
37
- case "subtle":
38
- return "bg-muted/50";
39
- }
40
- }
41
- }
42
- function getNestedCardTextColor(parentBg, options) {
43
- const isDark = parentBg === "dark" || parentBg === "secondary" || parentBg === "primary";
44
- return isDark ? "text-foreground" : "";
45
- }
46
16
  var badgeVariants = cva(
47
17
  "inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
48
18
  {
@@ -459,6 +429,70 @@ var Section = React__default.forwardRef(
459
429
  }
460
430
  );
461
431
  Section.displayName = "Section";
432
+ var MOBILE_CLASSES = {
433
+ "fit-left": "items-start md:items-center",
434
+ "fit-center": "items-center",
435
+ "fit-right": "items-end md:items-center",
436
+ "full-left": "items-stretch md:items-center",
437
+ "full-center": "items-stretch md:items-center",
438
+ "full-right": "items-stretch md:items-center"
439
+ };
440
+ function BlockActions({
441
+ mobileConfig,
442
+ actionsClassName,
443
+ verticalSpacing = "mt-4 md:mt-8",
444
+ actions,
445
+ actionsSlot
446
+ }) {
447
+ const width = mobileConfig?.width ?? "full";
448
+ const position = mobileConfig?.position ?? "center";
449
+ const mobileLayoutClass = MOBILE_CLASSES[`${width}-${position}`];
450
+ if (actionsSlot) {
451
+ return /* @__PURE__ */ jsx("div", { children: actionsSlot });
452
+ } else if (actions && actions?.length > 0) {
453
+ return /* @__PURE__ */ jsx(
454
+ "div",
455
+ {
456
+ className: cn(
457
+ "flex flex-col md:flex-row flex-wrap gap-4",
458
+ mobileLayoutClass,
459
+ actionsClassName,
460
+ verticalSpacing
461
+ ),
462
+ children: actions.map((action, index) => /* @__PURE__ */ jsx(ActionComponent, { action }, index))
463
+ }
464
+ );
465
+ } else {
466
+ return null;
467
+ }
468
+ }
469
+ function ActionComponent({ action }) {
470
+ const {
471
+ label,
472
+ icon,
473
+ iconAfter,
474
+ children,
475
+ href,
476
+ onClick,
477
+ className: actionClassName,
478
+ ...pressableProps
479
+ } = action;
480
+ return /* @__PURE__ */ jsx(
481
+ Pressable,
482
+ {
483
+ href,
484
+ onClick,
485
+ asButton: action.asButton ?? true,
486
+ className: actionClassName,
487
+ ...pressableProps,
488
+ children: children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
489
+ icon,
490
+ label,
491
+ iconAfter
492
+ ] })
493
+ }
494
+ );
495
+ }
462
496
  function StatsGrowthTimeline({
463
497
  sectionId = "stats-growth-timeline",
464
498
  badge,
@@ -475,6 +509,7 @@ function StatsGrowthTimeline({
475
509
  futureSlot,
476
510
  actions,
477
511
  actionsSlot,
512
+ actionsClassName,
478
513
  background,
479
514
  pattern,
480
515
  patternOpacity,
@@ -521,19 +556,18 @@ function StatsGrowthTimeline({
521
556
  "div",
522
557
  {
523
558
  className: cn(
524
- "mb-4 inline-flex h-9 w-20 items-center justify-center rounded-full text-sm font-semibold",
525
- getNestedCardBg(background, "muted"),
526
- getNestedCardTextColor(background)
559
+ "bg-muted text-muted-foreground",
560
+ "mb-4 inline-flex h-fit py-2 w-fit px-4 items-center justify-center rounded-full text-sm font-semibold"
527
561
  ),
528
562
  children: milestone.year
529
563
  }
530
564
  ),
531
- milestone.title && (typeof milestone.title === "string" ? /* @__PURE__ */ jsx("h3", { className: "mb-2 text-xl font-bold", children: milestone.title }) : /* @__PURE__ */ jsx("div", { className: "mb-2", children: milestone.title })),
532
- milestone.description && (typeof milestone.description === "string" ? /* @__PURE__ */ jsx("p", { className: "mb-4 text-muted-foreground", children: milestone.description }) : /* @__PURE__ */ jsx("div", { className: "mb-4", children: milestone.description })),
565
+ milestone.title && (typeof milestone.title === "string" ? /* @__PURE__ */ jsx("h3", { className: "mb-2 text-xl font-bold", children: milestone.title }) : milestone.title),
566
+ milestone.description && (typeof milestone.description === "string" ? /* @__PURE__ */ jsx("p", { className: "mb-4 text-muted-foreground", children: milestone.description }) : milestone.description),
533
567
  milestone.metric && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4 rounded-lg border bg-background p-4 shadow-sm", children: [
534
568
  renderMilestoneIcon(milestone),
535
569
  /* @__PURE__ */ jsxs("div", { children: [
536
- /* @__PURE__ */ jsx("div", { className: "text-3xl font-bold text-primary", children: milestone.metric.value }),
570
+ /* @__PURE__ */ jsx("div", { className: "text-2xl font-bold text-primary", children: milestone.metric.value }),
537
571
  milestone.metric.label && /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground", children: milestone.metric.label })
538
572
  ] })
539
573
  ] })
@@ -559,16 +593,15 @@ function StatsGrowthTimeline({
559
593
  "div",
560
594
  {
561
595
  className: cn(
562
- "mt-24 rounded-lg p-8",
563
- getNestedCardBg(background, "muted"),
564
- getNestedCardTextColor(background),
596
+ "p-6 md:p-12 bg-card text-card-foreground",
597
+ "mt-24 rounded-lg border border-border shadow-md",
565
598
  currentStatsClassName
566
599
  ),
567
600
  children: [
568
- currentStatsHeading && (typeof currentStatsHeading === "string" ? /* @__PURE__ */ jsx("h3", { className: "mb-6 text-center text-2xl font-bold", children: currentStatsHeading }) : /* @__PURE__ */ jsx("div", { className: "mb-6 text-center", children: currentStatsHeading })),
601
+ currentStatsHeading && (typeof currentStatsHeading === "string" ? /* @__PURE__ */ jsx("h3", { className: "mb-12 text-center text-4xl lg:text-5xl font-bold", children: currentStatsHeading }) : currentStatsHeading),
569
602
  /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-8 md:grid-cols-4", children: currentStats.map((stat, index) => /* @__PURE__ */ jsxs("div", { className: cn("text-center", stat.className), children: [
570
- /* @__PURE__ */ jsx("div", { className: "mb-2 text-3xl font-bold text-primary md:text-4xl", children: stat.value }),
571
- stat.label && /* @__PURE__ */ jsx("p", { className: "font-medium text-muted-foreground", children: stat.label })
603
+ /* @__PURE__ */ jsx("div", { className: "text-2xl font-semibold text-primary md:text-3xl xl:text-4xl", children: stat.value }),
604
+ stat.label && /* @__PURE__ */ jsx("p", { className: "font-medium text-balance text-sm", children: stat.label })
572
605
  ] }, index)) })
573
606
  ]
574
607
  }
@@ -580,39 +613,29 @@ function StatsGrowthTimeline({
580
613
  currentStatsHeading,
581
614
  currentStatsClassName
582
615
  ]);
583
- const actionsContent = useMemo(() => {
584
- if (actionsSlot) return actionsSlot;
585
- if (!actions || actions.length === 0) return null;
586
- return actions.map((action, index) => /* @__PURE__ */ jsxs(
587
- Pressable,
588
- {
589
- href: action.href,
590
- onClick: action.onClick,
591
- variant: action.variant,
592
- className: "inline-flex items-center font-medium text-primary hover:underline",
593
- children: [
594
- action.label,
595
- /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/arrow-right", size: 16, className: "ml-2" })
596
- ]
597
- },
598
- index
599
- ));
600
- }, [actionsSlot, actions]);
601
616
  const futureContent = useMemo(() => {
602
617
  if (futureSlot) return futureSlot;
603
618
  if (!futureHeading && !futureDescription && (!actions || actions.length === 0))
604
619
  return null;
605
620
  return /* @__PURE__ */ jsxs("div", { className: cn("mt-16 text-center", futureClassName), children: [
606
621
  futureHeading && (typeof futureHeading === "string" ? /* @__PURE__ */ jsx("h3", { className: "mb-4 text-2xl font-bold", children: futureHeading }) : /* @__PURE__ */ jsx("div", { className: "mb-4", children: futureHeading })),
607
- futureDescription && (typeof futureDescription === "string" ? /* @__PURE__ */ jsx("p", { className: "mx-auto mb-8 max-w-2xl text-muted-foreground", children: futureDescription }) : /* @__PURE__ */ jsx("div", { className: "mx-auto mb-8 max-w-2xl", children: futureDescription })),
608
- actionsContent
622
+ futureDescription && (typeof futureDescription === "string" ? /* @__PURE__ */ jsx("p", { className: "mx-auto mb-8 max-w-full md:max-w-lg text-balance", children: futureDescription }) : futureDescription),
623
+ /* @__PURE__ */ jsx(
624
+ BlockActions,
625
+ {
626
+ actions,
627
+ actionsSlot,
628
+ actionsClassName
629
+ }
630
+ )
609
631
  ] });
610
632
  }, [
611
633
  futureSlot,
612
634
  futureHeading,
613
635
  futureDescription,
614
636
  futureClassName,
615
- actionsContent,
637
+ actionsSlot,
638
+ actionsClassName,
616
639
  actions
617
640
  ]);
618
641
  const hasHeaderContent = !!(badge || badgeSlot || heading || description);
@@ -649,7 +672,7 @@ function StatsGrowthTimeline({
649
672
  ),
650
673
  children: description
651
674
  }
652
- ) : /* @__PURE__ */ jsx("div", { className: cn("mx-auto max-w-3xl", descriptionClassName), children: description }))
675
+ ) : description)
653
676
  ] }),
654
677
  milestonesContent,
655
678
  currentStatsContent,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opensite/ui",
3
- "version": "3.3.1",
3
+ "version": "3.3.3",
4
4
  "description": "Foundational UI component library for OpenSite Semantic Site Builder with tree-shakable exports and abstract styling",
5
5
  "keywords": [
6
6
  "react",