@opensite/ui 2.3.9 → 2.4.1

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.
@@ -872,6 +872,43 @@ function Badge({
872
872
  }
873
873
  );
874
874
  }
875
+ function TextInner({ as, className, children, ...props }, ref) {
876
+ const Component = as || "span";
877
+ return /* @__PURE__ */ jsx(Component, { ref, className: cn(className), ...props, children });
878
+ }
879
+ var Text = React.forwardRef(TextInner);
880
+ Text.displayName = "Text";
881
+ function isContentTextItem(item) {
882
+ return item !== null && typeof item === "object" && !React.isValidElement(item) && "_type" in item && item._type === "text";
883
+ }
884
+ var ContentGroup = React.forwardRef(
885
+ ({ items, className, children, ...props }, ref) => {
886
+ const hasContent = items && items.length > 0;
887
+ if (!hasContent) {
888
+ return null;
889
+ }
890
+ return /* @__PURE__ */ jsxs("div", { ref, className: cn(className), ...props, children: [
891
+ items.map((item, idx) => {
892
+ if (isContentTextItem(item)) {
893
+ const { _type, ...textProps } = item;
894
+ return /* @__PURE__ */ jsx(Text, { ...textProps }, idx);
895
+ }
896
+ const reactNode = item;
897
+ if (React.isValidElement(reactNode)) {
898
+ return React.cloneElement(reactNode, { key: reactNode.key ?? idx });
899
+ }
900
+ return /* @__PURE__ */ jsx(React.Fragment, { children: reactNode }, idx);
901
+ }),
902
+ children
903
+ ] });
904
+ }
905
+ );
906
+ ContentGroup.displayName = "ContentGroup";
907
+ var ASPECT_RATIO_CLASSES = {
908
+ square: "aspect-square",
909
+ horizontal: "aspect-video",
910
+ vertical: "aspect-[3/4]"
911
+ };
875
912
  function FeatureImageCardsThreeColumn({
876
913
  title,
877
914
  description,
@@ -889,7 +926,8 @@ function FeatureImageCardsThreeColumn({
889
926
  background,
890
927
  pattern,
891
928
  patternOpacity,
892
- patternClassName
929
+ patternClassName,
930
+ cardAspectRatios = { desktop: "vertical", mobile: "square" }
893
931
  }) {
894
932
  const renderImage = useCallback(
895
933
  (card, imageAlt) => {
@@ -900,7 +938,7 @@ function FeatureImageCardsThreeColumn({
900
938
  {
901
939
  src: card.imageSrc,
902
940
  alt: imageAlt,
903
- className: "h-full max-h-[450px] min-h-80 w-full rounded-xl object-cover object-center",
941
+ className: "absolute inset-0 h-full w-full rounded-xl object-cover object-center",
904
942
  loading: "lazy",
905
943
  optixFlowConfig
906
944
  }
@@ -919,77 +957,149 @@ function FeatureImageCardsThreeColumn({
919
957
  },
920
958
  []
921
959
  );
960
+ const renderCardBadge = useCallback(
961
+ (card) => {
962
+ return card.badgeText || card.avatarSrc || card.icon || card.iconName ? /* @__PURE__ */ jsxs(
963
+ Badge,
964
+ {
965
+ variant: "default",
966
+ className: cn("py-1 px-3 gap-2", card.badgeClassName),
967
+ children: [
968
+ renderBadgeIcon(card),
969
+ card.badgeText
970
+ ]
971
+ }
972
+ ) : null;
973
+ },
974
+ [renderBadgeIcon]
975
+ );
976
+ const cardHasTextContent = useCallback(
977
+ (card) => {
978
+ const hasBadge = !!(card.badgeText || card.avatarSrc || card.icon || card.iconName);
979
+ return hasBadge || !!card.title || !!card.subtitle || !!card.linkText;
980
+ },
981
+ []
982
+ );
983
+ const renderCardText = useCallback(
984
+ (card) => {
985
+ if (!cardHasTextContent(card)) {
986
+ return null;
987
+ }
988
+ const cardBadge = renderCardBadge(card);
989
+ return /* @__PURE__ */ jsxs("div", { className: "absolute top-0 flex h-full w-full flex-col justify-between p-4 md:p-6", children: [
990
+ cardBadge || /* @__PURE__ */ jsx("div", {}),
991
+ card.title || card.subtitle || card.linkText ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-start gap-4 md:gap-6 text-white", children: [
992
+ card.title || card.subtitle ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-start gap-2 md:gap-4", children: [
993
+ card.title && (typeof card.title === "string" ? /* @__PURE__ */ jsx(
994
+ "h3",
995
+ {
996
+ className: cn(
997
+ "text-lg md:text-xl font-semibold",
998
+ card.titleClassName
999
+ ),
1000
+ children: card.title
1001
+ }
1002
+ ) : card.title),
1003
+ card.subtitle && (typeof card.subtitle === "string" ? /* @__PURE__ */ jsx(
1004
+ "p",
1005
+ {
1006
+ className: cn(
1007
+ "text-base font-normal",
1008
+ card.subtitleClassName
1009
+ ),
1010
+ children: card.subtitle
1011
+ }
1012
+ ) : card.subtitle)
1013
+ ] }) : null,
1014
+ card.linkText && /* @__PURE__ */ jsxs(
1015
+ "div",
1016
+ {
1017
+ className: cn(
1018
+ "font-bold text-xs uppercase flex items-center gap-2",
1019
+ card.linkClassName
1020
+ ),
1021
+ children: [
1022
+ card.linkText,
1023
+ /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/arrow-up-right", size: 18 })
1024
+ ]
1025
+ }
1026
+ )
1027
+ ] }) : null
1028
+ ] });
1029
+ },
1030
+ [cardHasTextContent, renderCardBadge]
1031
+ );
922
1032
  const cardsContent = useMemo(() => {
923
1033
  if (cardsSlot) return cardsSlot;
924
1034
  if (!cards || cards.length === 0) return null;
925
1035
  return cards.map((card, index) => {
926
1036
  const imageAlt = card.imageAlt || (typeof card.title === "string" ? card.title : "Card image");
1037
+ const mobileAspectClass = ASPECT_RATIO_CLASSES[cardAspectRatios.mobile];
1038
+ const desktopAspectClass = `md:${ASPECT_RATIO_CLASSES[cardAspectRatios.desktop]}`;
927
1039
  return /* @__PURE__ */ jsxs(
928
1040
  Pressable,
929
1041
  {
930
1042
  href: card.link,
931
1043
  onClick: card.onClick,
932
1044
  className: cn(
933
- "group relative overflow-hidden rounded-xl",
1045
+ "group relative overflow-hidden rounded-2xl shadow-xl",
1046
+ mobileAspectClass,
1047
+ desktopAspectClass,
934
1048
  cardClassName,
935
1049
  card.className
936
1050
  ),
937
1051
  children: [
938
1052
  renderImage(card, imageAlt),
939
- /* @__PURE__ */ jsx("div", { className: "absolute top-0 right-0 bottom-0 left-0 translate-y-10 md:translate-y-20 rounded-xl bg-linear-to-t from-black to-transparent transition-transform duration-300 group-hover:translate-y-0" }),
940
- /* @__PURE__ */ jsxs("div", { className: "absolute top-0 flex h-full w-full flex-col justify-between p-4 md:p-6", children: [
941
- (card.badgeText || card.avatarSrc || card.icon || card.iconName) && /* @__PURE__ */ jsxs(
942
- Badge,
943
- {
944
- variant: "default",
945
- className: cn("py-1 px-4", card.badgeClassName),
946
- children: [
947
- renderBadgeIcon(card),
948
- card.badgeText
949
- ]
950
- }
951
- ),
952
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 md:gap-4", children: [
953
- card.title && (typeof card.title === "string" ? /* @__PURE__ */ jsx(
954
- "h3",
955
- {
956
- className: cn(
957
- "text-lg md:text-xl font-semibold",
958
- card.titleClassName
959
- ),
960
- children: card.title
961
- }
962
- ) : /* @__PURE__ */ jsx(
963
- "div",
964
- {
965
- className: cn(
966
- "text-lg md:text-xl font-semibold",
967
- card.titleClassName
968
- ),
969
- children: card.title
970
- }
971
- )),
972
- card.linkText && card.link && /* @__PURE__ */ jsxs(
973
- "div",
974
- {
975
- className: cn(
976
- "font-bold text-xs uppercase flex items-center gap-2",
977
- card.linkClassName
978
- ),
979
- children: [
980
- card.linkText,
981
- /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/arrow-up-right", size: 18 })
982
- ]
983
- }
984
- )
985
- ] })
986
- ] })
1053
+ cardHasTextContent(card) && /* @__PURE__ */ jsx("div", { className: "absolute top-0 right-0 bottom-0 left-0 translate-y-10 md:translate-y-20 rounded-xl bg-linear-to-t from-black to-transparent transition-transform duration-300 group-hover:translate-y-0" }),
1054
+ renderCardText(card)
987
1055
  ]
988
1056
  },
989
1057
  index
990
1058
  );
991
1059
  });
992
- }, [cardsSlot, cards, cardClassName, renderImage, renderBadgeIcon]);
1060
+ }, [
1061
+ cardsSlot,
1062
+ cards,
1063
+ cardClassName,
1064
+ cardAspectRatios,
1065
+ renderImage,
1066
+ cardHasTextContent,
1067
+ renderCardText
1068
+ ]);
1069
+ const contentItems = useMemo(() => {
1070
+ const items = [];
1071
+ if (title) {
1072
+ if (typeof title === "string") {
1073
+ items.push({
1074
+ _type: "text",
1075
+ as: "h2",
1076
+ className: cn(
1077
+ "text-3xl font-semibold text-balance md:text-4xl lg:text-5xl max-w-full md:max-w-md",
1078
+ title
1079
+ ),
1080
+ children: title
1081
+ });
1082
+ } else {
1083
+ items.push(title);
1084
+ }
1085
+ }
1086
+ if (description) {
1087
+ if (typeof description === "string") {
1088
+ items.push({
1089
+ _type: "text",
1090
+ as: "p",
1091
+ className: cn(
1092
+ "text-xl max-w-full md:max-w-md text-balance",
1093
+ descriptionClassName
1094
+ ),
1095
+ children: description
1096
+ });
1097
+ } else {
1098
+ items.push(description);
1099
+ }
1100
+ }
1101
+ return items;
1102
+ }, [title, titleClassName, description, descriptionClassName]);
993
1103
  return /* @__PURE__ */ jsx(
994
1104
  Section,
995
1105
  {
@@ -1001,34 +1111,16 @@ function FeatureImageCardsThreeColumn({
1001
1111
  className,
1002
1112
  containerClassName,
1003
1113
  children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col space-y-6 md:space-y-16", children: [
1004
- title || description ? /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-6 text-left", headerClassName), children: [
1005
- title && (typeof title === "string" ? /* @__PURE__ */ jsx(
1006
- "h2",
1007
- {
1008
- className: cn(
1009
- "text-2xl font-semibold text-balance md:text-3xl lg:text-4xl max-w-lg md:max-w-md",
1010
- titleClassName
1011
- ),
1012
- children: title
1013
- }
1014
- ) : /* @__PURE__ */ jsx(
1015
- "div",
1016
- {
1017
- className: cn(
1018
- "text-2xl font-semibold text-balance md:text-3xl lg:text-4xl max-w-lg md:max-w-md",
1019
- titleClassName
1020
- ),
1021
- children: title
1022
- }
1023
- )),
1024
- description && (typeof description === "string" ? /* @__PURE__ */ jsx("p", { className: cn("max-w-lg md:max-w-md", descriptionClassName), children: description }) : /* @__PURE__ */ jsx(
1025
- "div",
1026
- {
1027
- className: cn("max-w-lg md:max-w-md", descriptionClassName),
1028
- children: description
1029
- }
1030
- ))
1031
- ] }) : null,
1114
+ /* @__PURE__ */ jsx(
1115
+ ContentGroup,
1116
+ {
1117
+ items: contentItems,
1118
+ className: cn(
1119
+ "flex flex-col gap-2 text-left items-start",
1120
+ headerClassName
1121
+ )
1122
+ }
1123
+ ),
1032
1124
  /* @__PURE__ */ jsx(
1033
1125
  "div",
1034
1126
  {