@opensite/ui 2.9.0 → 2.9.2

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.
Files changed (51) hide show
  1. package/dist/carousel-feature-badge.cjs +4 -3
  2. package/dist/carousel-feature-badge.d.cts +1 -1
  3. package/dist/carousel-feature-badge.d.ts +1 -1
  4. package/dist/carousel-feature-badge.js +4 -3
  5. package/dist/carousel-scrolling-feature-showcase.cjs +47 -38
  6. package/dist/carousel-scrolling-feature-showcase.js +47 -38
  7. package/dist/registry.cjs +454 -265
  8. package/dist/registry.js +454 -265
  9. package/dist/testimonials-grid-add-review.cjs +578 -39
  10. package/dist/testimonials-grid-add-review.d.cts +26 -26
  11. package/dist/testimonials-grid-add-review.d.ts +26 -26
  12. package/dist/testimonials-grid-add-review.js +577 -38
  13. package/dist/testimonials-images-helpful.cjs +85 -74
  14. package/dist/testimonials-images-helpful.js +85 -74
  15. package/dist/testimonials-list-verified.cjs +1 -0
  16. package/dist/testimonials-list-verified.js +1 -0
  17. package/dist/testimonials-logo-cards.cjs +8 -5
  18. package/dist/testimonials-logo-cards.js +8 -5
  19. package/dist/testimonials-masonry-grid.cjs +87 -11
  20. package/dist/testimonials-masonry-grid.d.cts +14 -1
  21. package/dist/testimonials-masonry-grid.d.ts +14 -1
  22. package/dist/testimonials-masonry-grid.js +88 -12
  23. package/dist/testimonials-mini-dividers.cjs +438 -26
  24. package/dist/testimonials-mini-dividers.js +434 -22
  25. package/dist/testimonials-minimal-numbered.cjs +1 -1
  26. package/dist/testimonials-minimal-numbered.js +1 -1
  27. package/dist/testimonials-parallax-number.cjs +1 -1
  28. package/dist/testimonials-parallax-number.js +1 -1
  29. package/dist/testimonials-quote-carousel.cjs +39 -37
  30. package/dist/testimonials-quote-carousel.d.cts +5 -1
  31. package/dist/testimonials-quote-carousel.d.ts +5 -1
  32. package/dist/testimonials-quote-carousel.js +39 -37
  33. package/dist/testimonials-scrolling-columns.cjs +438 -8
  34. package/dist/testimonials-scrolling-columns.js +436 -6
  35. package/dist/testimonials-simple-grid.cjs +82 -6
  36. package/dist/testimonials-simple-grid.d.cts +14 -1
  37. package/dist/testimonials-simple-grid.d.ts +14 -1
  38. package/dist/testimonials-simple-grid.js +83 -7
  39. package/dist/testimonials-stats-header.cjs +88 -8
  40. package/dist/testimonials-stats-header.d.cts +14 -1
  41. package/dist/testimonials-stats-header.d.ts +14 -1
  42. package/dist/testimonials-stats-header.js +89 -9
  43. package/dist/testimonials-twitter-cards.cjs +150 -25
  44. package/dist/testimonials-twitter-cards.d.cts +14 -1
  45. package/dist/testimonials-twitter-cards.d.ts +14 -1
  46. package/dist/testimonials-twitter-cards.js +151 -26
  47. package/dist/testimonials-wall-compact.cjs +529 -50
  48. package/dist/testimonials-wall-compact.d.cts +14 -1
  49. package/dist/testimonials-wall-compact.d.ts +14 -1
  50. package/dist/testimonials-wall-compact.js +526 -44
  51. package/package.json +1 -1
@@ -980,6 +980,102 @@ var SocialLinkIcon = React__namespace.forwardRef(
980
980
  }
981
981
  );
982
982
  SocialLinkIcon.displayName = "SocialLinkIcon";
983
+ function TextInner({ as, className, children, ...props }, ref) {
984
+ const Component = as || "span";
985
+ return /* @__PURE__ */ jsxRuntime.jsx(Component, { ref, className: cn(className), ...props, children });
986
+ }
987
+ var Text = React__namespace.forwardRef(TextInner);
988
+ Text.displayName = "Text";
989
+ function isContentTextItem(item) {
990
+ return item !== null && typeof item === "object" && !React__namespace.isValidElement(item) && "_type" in item && item._type === "text";
991
+ }
992
+ var ContentGroup = React__namespace.forwardRef(
993
+ ({ items, className, children, ...props }, ref) => {
994
+ const hasContent = items && items.length > 0;
995
+ if (!hasContent) {
996
+ return null;
997
+ }
998
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: cn(className), ...props, children: [
999
+ items.map((item, idx) => {
1000
+ if (isContentTextItem(item)) {
1001
+ const { _type, ...textProps } = item;
1002
+ return /* @__PURE__ */ jsxRuntime.jsx(Text, { ...textProps }, idx);
1003
+ }
1004
+ const reactNode = item;
1005
+ if (React__namespace.isValidElement(reactNode)) {
1006
+ return React__namespace.cloneElement(reactNode, { key: reactNode.key ?? idx });
1007
+ }
1008
+ return /* @__PURE__ */ jsxRuntime.jsx(React__namespace.Fragment, { children: reactNode }, idx);
1009
+ }),
1010
+ children
1011
+ ] });
1012
+ }
1013
+ );
1014
+ ContentGroup.displayName = "ContentGroup";
1015
+ var MOBILE_CLASSES = {
1016
+ "fit-left": "items-start md:items-center",
1017
+ "fit-center": "items-center",
1018
+ "fit-right": "items-end md:items-center",
1019
+ "full-left": "items-stretch md:items-center",
1020
+ "full-center": "items-stretch md:items-center",
1021
+ "full-right": "items-stretch md:items-center"
1022
+ };
1023
+ function BlockActions({
1024
+ mobileConfig,
1025
+ actionsClassName,
1026
+ verticalSpacing = "mt-4 md:mt-8",
1027
+ actions,
1028
+ actionsSlot
1029
+ }) {
1030
+ const width = mobileConfig?.width ?? "full";
1031
+ const position = mobileConfig?.position ?? "center";
1032
+ const mobileLayoutClass = MOBILE_CLASSES[`${width}-${position}`];
1033
+ if (actionsSlot) {
1034
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { children: actionsSlot });
1035
+ } else if (actions && actions?.length > 0) {
1036
+ return /* @__PURE__ */ jsxRuntime.jsx(
1037
+ "div",
1038
+ {
1039
+ className: cn(
1040
+ "flex flex-col md:flex-row flex-wrap gap-4",
1041
+ mobileLayoutClass,
1042
+ actionsClassName,
1043
+ verticalSpacing
1044
+ ),
1045
+ children: actions.map((action, index) => /* @__PURE__ */ jsxRuntime.jsx(ActionComponent, { action }, index))
1046
+ }
1047
+ );
1048
+ } else {
1049
+ return null;
1050
+ }
1051
+ }
1052
+ function ActionComponent({ action }) {
1053
+ const {
1054
+ label,
1055
+ icon,
1056
+ iconAfter,
1057
+ children,
1058
+ href,
1059
+ onClick,
1060
+ className: actionClassName,
1061
+ ...pressableProps
1062
+ } = action;
1063
+ return /* @__PURE__ */ jsxRuntime.jsx(
1064
+ Pressable,
1065
+ {
1066
+ href,
1067
+ onClick,
1068
+ asButton: action.asButton ?? true,
1069
+ className: actionClassName,
1070
+ ...pressableProps,
1071
+ children: children ?? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1072
+ icon,
1073
+ label,
1074
+ iconAfter
1075
+ ] })
1076
+ }
1077
+ );
1078
+ }
983
1079
  function TestimonialsTwitterCards({
984
1080
  testimonials,
985
1081
  testimonialsSlot,
@@ -997,7 +1093,10 @@ function TestimonialsTwitterCards({
997
1093
  spacing = "lg",
998
1094
  containerClassName = "px-6 sm:px-6 md:px-8 lg:px-8",
999
1095
  pattern,
1000
- patternOpacity
1096
+ patternOpacity,
1097
+ actions,
1098
+ actionsSlot,
1099
+ actionsClassName
1001
1100
  }) {
1002
1101
  const getAuthorName = React.useCallback(
1003
1102
  (testimonial) => {
@@ -1096,6 +1195,41 @@ function TestimonialsTwitterCards({
1096
1195
  getAuthorName,
1097
1196
  getInitials
1098
1197
  ]);
1198
+ const contentItems = React.useMemo(() => {
1199
+ const items = [];
1200
+ if (heading) {
1201
+ if (typeof heading === "string") {
1202
+ items.push({
1203
+ _type: "text",
1204
+ as: "h2",
1205
+ className: cn(
1206
+ "text-pretty text-3xl md:text-4xl lg:text-6xl",
1207
+ "font-semibold tracking-tight",
1208
+ headingClassName
1209
+ ),
1210
+ children: heading
1211
+ });
1212
+ } else {
1213
+ items.push(heading);
1214
+ }
1215
+ }
1216
+ if (description) {
1217
+ if (typeof description === "string") {
1218
+ items.push({
1219
+ _type: "text",
1220
+ as: "p",
1221
+ className: cn(
1222
+ "max-w-full md:max-w-md text-lg text-balance",
1223
+ descriptionClassName
1224
+ ),
1225
+ children: description
1226
+ });
1227
+ } else {
1228
+ items.push(description);
1229
+ }
1230
+ }
1231
+ return items;
1232
+ }, [heading, headingClassName, description, descriptionClassName]);
1099
1233
  return /* @__PURE__ */ jsxRuntime.jsxs(
1100
1234
  Section,
1101
1235
  {
@@ -1106,36 +1240,27 @@ function TestimonialsTwitterCards({
1106
1240
  className,
1107
1241
  containerClassName,
1108
1242
  children: [
1109
- /* @__PURE__ */ jsxRuntime.jsxs(
1110
- "div",
1243
+ /* @__PURE__ */ jsxRuntime.jsx(
1244
+ ContentGroup,
1111
1245
  {
1246
+ items: contentItems,
1112
1247
  className: cn(
1248
+ "flex flex-col items-center",
1113
1249
  "mx-auto mb-12 max-w-full md:max-w-2xl text-center",
1114
1250
  headerClassName
1115
- ),
1116
- children: [
1117
- heading && (typeof heading === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
1118
- "h2",
1119
- {
1120
- className: cn(
1121
- "text-pretty text-3xl md:text-4xl lg:text-6xl",
1122
- "font-semibold tracking-tight",
1123
- headingClassName
1124
- ),
1125
- children: heading
1126
- }
1127
- ) : heading),
1128
- description && (typeof description === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
1129
- "p",
1130
- {
1131
- className: cn("mt-4 text-lg text-balance", descriptionClassName),
1132
- children: description
1133
- }
1134
- ) : description)
1135
- ]
1251
+ )
1136
1252
  }
1137
1253
  ),
1138
- renderedTestimonials
1254
+ renderedTestimonials,
1255
+ /* @__PURE__ */ jsxRuntime.jsx(
1256
+ BlockActions,
1257
+ {
1258
+ actions,
1259
+ actionsSlot,
1260
+ actionsClassName: cn("mt-8 md:mt-12 justify-center", actionsClassName),
1261
+ mobileConfig: { width: "full", position: "center" }
1262
+ }
1263
+ )
1139
1264
  ]
1140
1265
  }
1141
1266
  );
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { S as SectionBackground, s as SectionSpacing, t as PatternName } from './community-initiatives-B8KCpwXH.cjs';
3
+ import { ActionConfig } from '@page-speed/maps/components/geo-map';
3
4
  import './blocks-BtDAbw8d.cjs';
4
5
  import 'class-variance-authority';
5
6
  import './button-variants-8mtEHxev.cjs';
@@ -104,6 +105,18 @@ interface TestimonialsTwitterCardsProps {
104
105
  * Additional CSS classes for the container
105
106
  */
106
107
  containerClassName?: string;
108
+ /**
109
+ * Array of action configurations for CTA buttons
110
+ */
111
+ actions?: ActionConfig[];
112
+ /**
113
+ * Custom slot for rendering actions (overrides actions array)
114
+ */
115
+ actionsSlot?: React.ReactNode;
116
+ /**
117
+ * Additional CSS classes for the actions container
118
+ */
119
+ actionsClassName?: string;
107
120
  }
108
121
  /**
109
122
  * TestimonialsTwitterCards - A grid of social testimonial cards featuring
@@ -144,6 +157,6 @@ interface TestimonialsTwitterCardsProps {
144
157
  * />
145
158
  * ```
146
159
  */
147
- declare function TestimonialsTwitterCards({ testimonials, testimonialsSlot, heading, description, className, headerClassName, headingClassName, descriptionClassName, gridClassName, cardClassName, cardContentClassName, authorClassName, background, spacing, containerClassName, pattern, patternOpacity, }: TestimonialsTwitterCardsProps): React.JSX.Element;
160
+ declare function TestimonialsTwitterCards({ testimonials, testimonialsSlot, heading, description, className, headerClassName, headingClassName, descriptionClassName, gridClassName, cardClassName, cardContentClassName, authorClassName, background, spacing, containerClassName, pattern, patternOpacity, actions, actionsSlot, actionsClassName, }: TestimonialsTwitterCardsProps): React.JSX.Element;
148
161
 
149
162
  export { TestimonialsTwitterCards, type TestimonialsTwitterCardsProps, type TwitterTestimonialItem };
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { S as SectionBackground, s as SectionSpacing, t as PatternName } from './community-initiatives-rTRuDt0r.js';
3
+ import { ActionConfig } from '@page-speed/maps/components/geo-map';
3
4
  import './blocks-BlWXj9GI.js';
4
5
  import 'class-variance-authority';
5
6
  import './button-variants-8mtEHxev.js';
@@ -104,6 +105,18 @@ interface TestimonialsTwitterCardsProps {
104
105
  * Additional CSS classes for the container
105
106
  */
106
107
  containerClassName?: string;
108
+ /**
109
+ * Array of action configurations for CTA buttons
110
+ */
111
+ actions?: ActionConfig[];
112
+ /**
113
+ * Custom slot for rendering actions (overrides actions array)
114
+ */
115
+ actionsSlot?: React.ReactNode;
116
+ /**
117
+ * Additional CSS classes for the actions container
118
+ */
119
+ actionsClassName?: string;
107
120
  }
108
121
  /**
109
122
  * TestimonialsTwitterCards - A grid of social testimonial cards featuring
@@ -144,6 +157,6 @@ interface TestimonialsTwitterCardsProps {
144
157
  * />
145
158
  * ```
146
159
  */
147
- declare function TestimonialsTwitterCards({ testimonials, testimonialsSlot, heading, description, className, headerClassName, headingClassName, descriptionClassName, gridClassName, cardClassName, cardContentClassName, authorClassName, background, spacing, containerClassName, pattern, patternOpacity, }: TestimonialsTwitterCardsProps): React.JSX.Element;
160
+ declare function TestimonialsTwitterCards({ testimonials, testimonialsSlot, heading, description, className, headerClassName, headingClassName, descriptionClassName, gridClassName, cardClassName, cardContentClassName, authorClassName, background, spacing, containerClassName, pattern, patternOpacity, actions, actionsSlot, actionsClassName, }: TestimonialsTwitterCardsProps): React.JSX.Element;
148
161
 
149
162
  export { TestimonialsTwitterCards, type TestimonialsTwitterCardsProps, type TwitterTestimonialItem };
@@ -4,7 +4,7 @@ import React__default, { useCallback, useMemo } from 'react';
4
4
  import { clsx } from 'clsx';
5
5
  import { twMerge } from 'tailwind-merge';
6
6
  import * as AvatarPrimitive from '@radix-ui/react-avatar';
7
- import { jsx, jsxs } from 'react/jsx-runtime';
7
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
8
8
  import { cva } from 'class-variance-authority';
9
9
  import { Icon } from '@page-speed/icon';
10
10
  import { usePlatformFromUrl } from '@opensite/hooks/usePlatformFromUrl';
@@ -958,6 +958,102 @@ var SocialLinkIcon = React.forwardRef(
958
958
  }
959
959
  );
960
960
  SocialLinkIcon.displayName = "SocialLinkIcon";
961
+ function TextInner({ as, className, children, ...props }, ref) {
962
+ const Component = as || "span";
963
+ return /* @__PURE__ */ jsx(Component, { ref, className: cn(className), ...props, children });
964
+ }
965
+ var Text = React.forwardRef(TextInner);
966
+ Text.displayName = "Text";
967
+ function isContentTextItem(item) {
968
+ return item !== null && typeof item === "object" && !React.isValidElement(item) && "_type" in item && item._type === "text";
969
+ }
970
+ var ContentGroup = React.forwardRef(
971
+ ({ items, className, children, ...props }, ref) => {
972
+ const hasContent = items && items.length > 0;
973
+ if (!hasContent) {
974
+ return null;
975
+ }
976
+ return /* @__PURE__ */ jsxs("div", { ref, className: cn(className), ...props, children: [
977
+ items.map((item, idx) => {
978
+ if (isContentTextItem(item)) {
979
+ const { _type, ...textProps } = item;
980
+ return /* @__PURE__ */ jsx(Text, { ...textProps }, idx);
981
+ }
982
+ const reactNode = item;
983
+ if (React.isValidElement(reactNode)) {
984
+ return React.cloneElement(reactNode, { key: reactNode.key ?? idx });
985
+ }
986
+ return /* @__PURE__ */ jsx(React.Fragment, { children: reactNode }, idx);
987
+ }),
988
+ children
989
+ ] });
990
+ }
991
+ );
992
+ ContentGroup.displayName = "ContentGroup";
993
+ var MOBILE_CLASSES = {
994
+ "fit-left": "items-start md:items-center",
995
+ "fit-center": "items-center",
996
+ "fit-right": "items-end md:items-center",
997
+ "full-left": "items-stretch md:items-center",
998
+ "full-center": "items-stretch md:items-center",
999
+ "full-right": "items-stretch md:items-center"
1000
+ };
1001
+ function BlockActions({
1002
+ mobileConfig,
1003
+ actionsClassName,
1004
+ verticalSpacing = "mt-4 md:mt-8",
1005
+ actions,
1006
+ actionsSlot
1007
+ }) {
1008
+ const width = mobileConfig?.width ?? "full";
1009
+ const position = mobileConfig?.position ?? "center";
1010
+ const mobileLayoutClass = MOBILE_CLASSES[`${width}-${position}`];
1011
+ if (actionsSlot) {
1012
+ return /* @__PURE__ */ jsx("div", { children: actionsSlot });
1013
+ } else if (actions && actions?.length > 0) {
1014
+ return /* @__PURE__ */ jsx(
1015
+ "div",
1016
+ {
1017
+ className: cn(
1018
+ "flex flex-col md:flex-row flex-wrap gap-4",
1019
+ mobileLayoutClass,
1020
+ actionsClassName,
1021
+ verticalSpacing
1022
+ ),
1023
+ children: actions.map((action, index) => /* @__PURE__ */ jsx(ActionComponent, { action }, index))
1024
+ }
1025
+ );
1026
+ } else {
1027
+ return null;
1028
+ }
1029
+ }
1030
+ function ActionComponent({ action }) {
1031
+ const {
1032
+ label,
1033
+ icon,
1034
+ iconAfter,
1035
+ children,
1036
+ href,
1037
+ onClick,
1038
+ className: actionClassName,
1039
+ ...pressableProps
1040
+ } = action;
1041
+ return /* @__PURE__ */ jsx(
1042
+ Pressable,
1043
+ {
1044
+ href,
1045
+ onClick,
1046
+ asButton: action.asButton ?? true,
1047
+ className: actionClassName,
1048
+ ...pressableProps,
1049
+ children: children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
1050
+ icon,
1051
+ label,
1052
+ iconAfter
1053
+ ] })
1054
+ }
1055
+ );
1056
+ }
961
1057
  function TestimonialsTwitterCards({
962
1058
  testimonials,
963
1059
  testimonialsSlot,
@@ -975,7 +1071,10 @@ function TestimonialsTwitterCards({
975
1071
  spacing = "lg",
976
1072
  containerClassName = "px-6 sm:px-6 md:px-8 lg:px-8",
977
1073
  pattern,
978
- patternOpacity
1074
+ patternOpacity,
1075
+ actions,
1076
+ actionsSlot,
1077
+ actionsClassName
979
1078
  }) {
980
1079
  const getAuthorName = useCallback(
981
1080
  (testimonial) => {
@@ -1074,6 +1173,41 @@ function TestimonialsTwitterCards({
1074
1173
  getAuthorName,
1075
1174
  getInitials
1076
1175
  ]);
1176
+ const contentItems = useMemo(() => {
1177
+ const items = [];
1178
+ if (heading) {
1179
+ if (typeof heading === "string") {
1180
+ items.push({
1181
+ _type: "text",
1182
+ as: "h2",
1183
+ className: cn(
1184
+ "text-pretty text-3xl md:text-4xl lg:text-6xl",
1185
+ "font-semibold tracking-tight",
1186
+ headingClassName
1187
+ ),
1188
+ children: heading
1189
+ });
1190
+ } else {
1191
+ items.push(heading);
1192
+ }
1193
+ }
1194
+ if (description) {
1195
+ if (typeof description === "string") {
1196
+ items.push({
1197
+ _type: "text",
1198
+ as: "p",
1199
+ className: cn(
1200
+ "max-w-full md:max-w-md text-lg text-balance",
1201
+ descriptionClassName
1202
+ ),
1203
+ children: description
1204
+ });
1205
+ } else {
1206
+ items.push(description);
1207
+ }
1208
+ }
1209
+ return items;
1210
+ }, [heading, headingClassName, description, descriptionClassName]);
1077
1211
  return /* @__PURE__ */ jsxs(
1078
1212
  Section,
1079
1213
  {
@@ -1084,36 +1218,27 @@ function TestimonialsTwitterCards({
1084
1218
  className,
1085
1219
  containerClassName,
1086
1220
  children: [
1087
- /* @__PURE__ */ jsxs(
1088
- "div",
1221
+ /* @__PURE__ */ jsx(
1222
+ ContentGroup,
1089
1223
  {
1224
+ items: contentItems,
1090
1225
  className: cn(
1226
+ "flex flex-col items-center",
1091
1227
  "mx-auto mb-12 max-w-full md:max-w-2xl text-center",
1092
1228
  headerClassName
1093
- ),
1094
- children: [
1095
- heading && (typeof heading === "string" ? /* @__PURE__ */ jsx(
1096
- "h2",
1097
- {
1098
- className: cn(
1099
- "text-pretty text-3xl md:text-4xl lg:text-6xl",
1100
- "font-semibold tracking-tight",
1101
- headingClassName
1102
- ),
1103
- children: heading
1104
- }
1105
- ) : heading),
1106
- description && (typeof description === "string" ? /* @__PURE__ */ jsx(
1107
- "p",
1108
- {
1109
- className: cn("mt-4 text-lg text-balance", descriptionClassName),
1110
- children: description
1111
- }
1112
- ) : description)
1113
- ]
1229
+ )
1114
1230
  }
1115
1231
  ),
1116
- renderedTestimonials
1232
+ renderedTestimonials,
1233
+ /* @__PURE__ */ jsx(
1234
+ BlockActions,
1235
+ {
1236
+ actions,
1237
+ actionsSlot,
1238
+ actionsClassName: cn("mt-8 md:mt-12 justify-center", actionsClassName),
1239
+ mobileConfig: { width: "full", position: "center" }
1240
+ }
1241
+ )
1117
1242
  ]
1118
1243
  }
1119
1244
  );