@opensite/ui 3.0.7 → 3.0.8

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/registry.js CHANGED
@@ -5,6 +5,7 @@ import { twMerge } from 'tailwind-merge';
5
5
  import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
6
6
  import { Img } from '@page-speed/img';
7
7
  import { motion as motion$1, AnimatePresence as AnimatePresence$1 } from 'motion/react';
8
+ import * as AspectRatioPrimitive from '@radix-ui/react-aspect-ratio';
8
9
  import { Slot } from '@radix-ui/react-slot';
9
10
  import { cva } from 'class-variance-authority';
10
11
  import * as PopoverPrimitive from '@radix-ui/react-popover';
@@ -23,7 +24,6 @@ import Autoplay from 'embla-carousel-autoplay';
23
24
  import * as ProgressPrimitive from '@radix-ui/react-progress';
24
25
  import * as AvatarPrimitive from '@radix-ui/react-avatar';
25
26
  import AutoScroll3 from 'embla-carousel-auto-scroll';
26
- import * as AspectRatioPrimitive from '@radix-ui/react-aspect-ratio';
27
27
  import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
28
28
  import * as LabelPrimitive from '@radix-ui/react-label';
29
29
  import { SocialShare } from '@page-speed/social-share';
@@ -832,6 +832,174 @@ var ImageSlider = ({
832
832
  }
833
833
  );
834
834
  };
835
+ function AspectRatio({
836
+ ...props
837
+ }) {
838
+ return /* @__PURE__ */ jsx(AspectRatioPrimitive.Root, { "data-slot": "aspect-ratio", ...props });
839
+ }
840
+ var DEFAULT_DEVICE_ASPECT_RATIOS = {
841
+ desktop: "square",
842
+ mobile: "square"
843
+ };
844
+ var DEFAULT_MEDIA_CLASS_NAME = "size-full object-cover";
845
+ var DEFAULT_FRAME_CLASS_NAME = "overflow-hidden";
846
+ var DEFAULT_BREAKPOINT = "lg";
847
+ var BREAKPOINT_VISIBILITY_CLASSES = {
848
+ sm: {
849
+ desktop: "hidden sm:block",
850
+ mobile: "sm:hidden"
851
+ },
852
+ md: {
853
+ desktop: "hidden md:block",
854
+ mobile: "md:hidden"
855
+ },
856
+ lg: {
857
+ desktop: "hidden lg:block",
858
+ mobile: "lg:hidden"
859
+ },
860
+ xl: {
861
+ desktop: "hidden xl:block",
862
+ mobile: "xl:hidden"
863
+ },
864
+ "2xl": {
865
+ desktop: "hidden 2xl:block",
866
+ mobile: "2xl:hidden"
867
+ }
868
+ };
869
+ var MEDIA_ASPECT_RATIOS = {
870
+ square: 1,
871
+ horizontal: 16 / 9,
872
+ vertical: 355 / 520
873
+ };
874
+ function resolveAspectRatio(ratio, fallback) {
875
+ const resolvedRatio = ratio ?? fallback;
876
+ if (typeof resolvedRatio === "number" && Number.isFinite(resolvedRatio) && resolvedRatio > 0) {
877
+ return resolvedRatio;
878
+ }
879
+ return MEDIA_ASPECT_RATIOS[resolvedRatio];
880
+ }
881
+ function hasRenderableMedia(mediaItem) {
882
+ return Boolean(mediaItem?.image?.src || mediaItem?.video?.src);
883
+ }
884
+ function renderMediaElement({
885
+ mediaItem,
886
+ optixFlowConfig,
887
+ mediaClassName,
888
+ imageClassName,
889
+ videoClassName
890
+ }) {
891
+ if (!hasRenderableMedia(mediaItem)) {
892
+ return null;
893
+ }
894
+ if (mediaItem.video?.src) {
895
+ const { className: inlineVideoClassName, poster, ...videoProps } = mediaItem.video;
896
+ const posterFallback = poster ?? (typeof mediaItem.image?.src === "string" ? mediaItem.image.src : void 0);
897
+ return /* @__PURE__ */ jsx(
898
+ "video",
899
+ {
900
+ ...videoProps,
901
+ poster: posterFallback,
902
+ className: cn(
903
+ DEFAULT_MEDIA_CLASS_NAME,
904
+ mediaClassName,
905
+ videoClassName,
906
+ inlineVideoClassName
907
+ )
908
+ }
909
+ );
910
+ }
911
+ if (mediaItem.image?.src) {
912
+ const { className: inlineImageClassName, alt, src, ...imageProps } = mediaItem.image;
913
+ return /* @__PURE__ */ jsx(
914
+ Img,
915
+ {
916
+ ...imageProps,
917
+ src,
918
+ alt: alt ?? "",
919
+ className: cn(
920
+ DEFAULT_MEDIA_CLASS_NAME,
921
+ mediaClassName,
922
+ imageClassName,
923
+ inlineImageClassName
924
+ ),
925
+ optixFlowConfig
926
+ }
927
+ );
928
+ }
929
+ return null;
930
+ }
931
+ function MediaAspectRatio({
932
+ containerClassName,
933
+ mobileClassName,
934
+ desktopClassName,
935
+ frameClassName,
936
+ mobileFrameClassName,
937
+ desktopFrameClassName,
938
+ mediaClassName,
939
+ imageClassName,
940
+ videoClassName,
941
+ mediaItem,
942
+ optixFlowConfig,
943
+ deviceAspectRatios = DEFAULT_DEVICE_ASPECT_RATIOS,
944
+ breakpoint = DEFAULT_BREAKPOINT
945
+ }) {
946
+ if (!hasRenderableMedia(mediaItem)) {
947
+ return null;
948
+ }
949
+ const ratios = {
950
+ desktop: resolveAspectRatio(
951
+ deviceAspectRatios.desktop,
952
+ DEFAULT_DEVICE_ASPECT_RATIOS.desktop
953
+ ),
954
+ mobile: resolveAspectRatio(
955
+ deviceAspectRatios.mobile,
956
+ DEFAULT_DEVICE_ASPECT_RATIOS.mobile
957
+ )
958
+ };
959
+ const sharedFrameClassName = cn(
960
+ DEFAULT_FRAME_CLASS_NAME,
961
+ frameClassName,
962
+ mediaItem.containerClassName
963
+ );
964
+ const visibilityClasses = BREAKPOINT_VISIBILITY_CLASSES[breakpoint];
965
+ return /* @__PURE__ */ jsxs("div", { className: containerClassName, "data-slot": "media-aspect-ratio", children: [
966
+ /* @__PURE__ */ jsx("div", { className: cn("relative", visibilityClasses.mobile, mobileClassName), children: /* @__PURE__ */ jsx(
967
+ AspectRatio,
968
+ {
969
+ ratio: ratios.mobile,
970
+ className: cn(sharedFrameClassName, mobileFrameClassName),
971
+ children: renderMediaElement({
972
+ mediaItem,
973
+ optixFlowConfig,
974
+ mediaClassName,
975
+ imageClassName,
976
+ videoClassName
977
+ })
978
+ }
979
+ ) }),
980
+ /* @__PURE__ */ jsx(
981
+ "div",
982
+ {
983
+ className: cn(visibilityClasses.desktop, desktopClassName),
984
+ style: { aspectRatio: String(ratios.desktop) },
985
+ children: /* @__PURE__ */ jsx(
986
+ "div",
987
+ {
988
+ className: cn("size-full", sharedFrameClassName, desktopFrameClassName),
989
+ "data-slot": "media-aspect-ratio-frame",
990
+ children: renderMediaElement({
991
+ mediaItem,
992
+ optixFlowConfig,
993
+ mediaClassName,
994
+ imageClassName,
995
+ videoClassName
996
+ })
997
+ }
998
+ )
999
+ }
1000
+ )
1001
+ ] });
1002
+ }
835
1003
  function Card({ className, ...props }) {
836
1004
  return /* @__PURE__ */ jsx(
837
1005
  "div",
@@ -36580,11 +36748,6 @@ function BlogHorizontalCards({
36580
36748
  }
36581
36749
  );
36582
36750
  }
36583
- function AspectRatio({
36584
- ...props
36585
- }) {
36586
- return /* @__PURE__ */ jsx(AspectRatioPrimitive.Root, { "data-slot": "aspect-ratio", ...props });
36587
- }
36588
36751
  function Breadcrumb({ ...props }) {
36589
36752
  return /* @__PURE__ */ jsx("nav", { "aria-label": "breadcrumb", "data-slot": "breadcrumb", ...props });
36590
36753
  }
@@ -52971,7 +53134,7 @@ function HeroPremiumSplitAvatars({
52971
53134
  image,
52972
53135
  imageSlot,
52973
53136
  className,
52974
- spacing = "pt-28 pb-8 md:pt-32 md:pb-32",
53137
+ spacing = "hero",
52975
53138
  containerClassName = "px-6 sm:px-6 md:px-8 lg:px-8",
52976
53139
  background,
52977
53140
  pattern,
@@ -52980,8 +53143,15 @@ function HeroPremiumSplitAvatars({
52980
53143
  headingClassName,
52981
53144
  descriptionClassName,
52982
53145
  imageClassName,
52983
- optixFlowConfig
53146
+ optixFlowConfig,
53147
+ mediaAspectRatios = { desktop: "vertical", mobile: "vertical" },
53148
+ directionConfig = { desktop: "mediaRight", mobile: "mediaBottom" }
52984
53149
  }) {
53150
+ const responsiveClassName = useMemo(() => {
53151
+ const desktopOrder = directionConfig.desktop === "mediaRight" ? "md:flex-row" : "md:flex-row-reverse";
53152
+ const mobileOrder = directionConfig.mobile === "mediaTop" ? "flex-col-reverse" : "flex-col";
53153
+ return `${mobileOrder} ${desktopOrder}`;
53154
+ }, [directionConfig.desktop, directionConfig.mobile]);
52985
53155
  const renderBrand = useMemo(() => {
52986
53156
  if (brandSlot) return brandSlot;
52987
53157
  return /* @__PURE__ */ jsxs("h1", { className: "text-4xl ", children: [
@@ -53029,19 +53199,31 @@ function HeroPremiumSplitAvatars({
53029
53199
  if (imageSlot) return imageSlot;
53030
53200
  if (!image) return null;
53031
53201
  return /* @__PURE__ */ jsx(
53032
- Img,
53033
- {
53034
- src: image.src,
53035
- alt: image.alt,
53036
- className: cn(
53037
- "h-full w-full md:w-1/2 object-cover block rounded-xl shadow-xl",
53038
- imageClassName,
53039
- image.className
53040
- ),
53041
- optixFlowConfig
53202
+ MediaAspectRatio,
53203
+ {
53204
+ breakpoint: "md",
53205
+ containerClassName: "relative flex w-full justify-center md:w-1/2",
53206
+ mobileClassName: "w-full",
53207
+ desktopClassName: "w-full max-h-[70dvh]",
53208
+ frameClassName: "rounded-xl shadow-xl",
53209
+ imageClassName: cn("block", imageClassName),
53210
+ mediaItem: {
53211
+ image: {
53212
+ ...image,
53213
+ loading: "eager"
53214
+ }
53215
+ },
53216
+ optixFlowConfig,
53217
+ deviceAspectRatios: mediaAspectRatios
53042
53218
  }
53043
53219
  );
53044
- }, [imageSlot, image, imageClassName, optixFlowConfig]);
53220
+ }, [
53221
+ imageSlot,
53222
+ image,
53223
+ imageClassName,
53224
+ optixFlowConfig,
53225
+ mediaAspectRatios
53226
+ ]);
53045
53227
  return /* @__PURE__ */ jsx(
53046
53228
  Section,
53047
53229
  {
@@ -53052,27 +53234,36 @@ function HeroPremiumSplitAvatars({
53052
53234
  patternOpacity,
53053
53235
  className: cn("relative flex items-center justify-center", className),
53054
53236
  containerClassName,
53055
- children: /* @__PURE__ */ jsxs("div", { className: "relative flex w-full flex-col md:flex-row gap-8 md:gap-20", children: [
53056
- /* @__PURE__ */ jsx("div", { className: "flex w-full items-center justify-center lg:w-1/2", children: /* @__PURE__ */ jsxs(
53057
- "div",
53058
- {
53059
- className: cn(
53060
- "my-10 flex w-full flex-col gap-6 md:gap-24",
53061
- contentClassName
53062
- ),
53063
- children: [
53064
- renderBrand,
53065
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 md:gap-8", children: [
53066
- heading && (typeof heading === "string" ? /* @__PURE__ */ jsx("h2", { className: cn("text-4xl lg:text-6xl", headingClassName), children: heading }) : /* @__PURE__ */ jsx("h2", { className: cn("text-4xl lg:text-6xl", headingClassName), children: heading })),
53067
- description && (typeof description === "string" ? /* @__PURE__ */ jsx("p", { className: cn("mt-2.5 lg:text-xl", descriptionClassName), children: description }) : /* @__PURE__ */ jsx("div", { className: descriptionClassName, children: description })),
53068
- renderAction
53069
- ] }),
53070
- renderAvatars
53071
- ]
53072
- }
53073
- ) }),
53074
- renderImage
53075
- ] })
53237
+ children: /* @__PURE__ */ jsxs(
53238
+ "div",
53239
+ {
53240
+ className: cn(
53241
+ "relative flex w-full gap-8 md:gap-20",
53242
+ responsiveClassName
53243
+ ),
53244
+ children: [
53245
+ /* @__PURE__ */ jsx("div", { className: "flex w-full items-center justify-center lg:w-1/2", children: /* @__PURE__ */ jsxs(
53246
+ "div",
53247
+ {
53248
+ className: cn(
53249
+ "my-10 flex w-full flex-col gap-6 md:gap-24",
53250
+ contentClassName
53251
+ ),
53252
+ children: [
53253
+ renderBrand,
53254
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 md:gap-8", children: [
53255
+ heading && (typeof heading === "string" ? /* @__PURE__ */ jsx("h2", { className: cn("text-4xl lg:text-6xl", headingClassName), children: heading }) : /* @__PURE__ */ jsx("h2", { className: cn("text-4xl lg:text-6xl", headingClassName), children: heading })),
53256
+ description && (typeof description === "string" ? /* @__PURE__ */ jsx("p", { className: cn("mt-2.5 lg:text-xl", descriptionClassName), children: description }) : /* @__PURE__ */ jsx("div", { className: descriptionClassName, children: description })),
53257
+ renderAction
53258
+ ] }),
53259
+ renderAvatars
53260
+ ]
53261
+ }
53262
+ ) }),
53263
+ renderImage
53264
+ ]
53265
+ }
53266
+ )
53076
53267
  }
53077
53268
  );
53078
53269
  }
@@ -53912,11 +54103,6 @@ function HeroAiPoweredCarousel({
53912
54103
  }
53913
54104
  );
53914
54105
  }
53915
- var ASPECT_RATIOS = {
53916
- square: 1,
53917
- horizontal: 16 / 9,
53918
- vertical: 355 / 520
53919
- };
53920
54106
  function HeroAdCampaignExpert({
53921
54107
  sectionId = "hero-ad-campaign-expert",
53922
54108
  heading,
@@ -53995,36 +54181,6 @@ function HeroAdCampaignExpert({
53995
54181
  descriptionClassName,
53996
54182
  renderActions
53997
54183
  ]);
53998
- const hasMedia = mediaItem?.image || mediaItem?.video;
53999
- const renderMedia = useMemo(() => {
54000
- if (!mediaItem) return null;
54001
- const { image, video } = mediaItem;
54002
- if (video) {
54003
- const { src, className: videoClassName, ...videoRest } = video;
54004
- return /* @__PURE__ */ jsx(
54005
- "video",
54006
- {
54007
- src,
54008
- className: cn("size-full object-cover", videoClassName),
54009
- ...videoRest
54010
- }
54011
- );
54012
- }
54013
- if (image) {
54014
- const { src, alt, className: imgClassName, ...imgRest } = image;
54015
- return /* @__PURE__ */ jsx(
54016
- Img,
54017
- {
54018
- src,
54019
- alt,
54020
- className: cn("size-full object-cover", imgClassName),
54021
- optixFlowConfig,
54022
- ...imgRest
54023
- }
54024
- );
54025
- }
54026
- return null;
54027
- }, [mediaItem, optixFlowConfig]);
54028
54184
  return /* @__PURE__ */ jsx(
54029
54185
  Section,
54030
54186
  {
@@ -54053,38 +54209,18 @@ function HeroAdCampaignExpert({
54053
54209
  )
54054
54210
  }
54055
54211
  ),
54056
- hasMedia && /* @__PURE__ */ jsxs("div", { className: cn("relative flex w-full justify-center lg:w-1/2"), children: [
54057
- /* @__PURE__ */ jsx("div", { className: "relative h-auto w-[80%] max-w-[355px] lg:hidden", children: /* @__PURE__ */ jsx(
54058
- AspectRatio,
54059
- {
54060
- ratio: ASPECT_RATIOS[mediaAspectRatios.mobile],
54061
- className: cn(
54062
- "rounded-xl shadow-2xl overflow-hidden",
54063
- mediaItem?.containerClassName
54064
- ),
54065
- children: renderMedia
54066
- }
54067
- ) }),
54068
- /* @__PURE__ */ jsx(
54069
- "div",
54070
- {
54071
- className: "hidden lg:block max-h-[70dvh] w-auto",
54072
- style: {
54073
- aspectRatio: ASPECT_RATIOS[mediaAspectRatios.desktop]
54074
- },
54075
- children: /* @__PURE__ */ jsx(
54076
- "div",
54077
- {
54078
- className: cn(
54079
- "size-full rounded-xl shadow-2xl overflow-hidden",
54080
- mediaItem?.containerClassName
54081
- ),
54082
- children: renderMedia
54083
- }
54084
- )
54085
- }
54086
- )
54087
- ] })
54212
+ /* @__PURE__ */ jsx(
54213
+ MediaAspectRatio,
54214
+ {
54215
+ containerClassName: "relative flex w-full justify-center lg:w-1/2",
54216
+ desktopClassName: "max-h-[70dvh] w-auto",
54217
+ mobileClassName: "h-auto w-[80%] max-w-[355px]",
54218
+ frameClassName: "rounded-xl shadow-2xl",
54219
+ mediaItem,
54220
+ optixFlowConfig,
54221
+ deviceAspectRatios: mediaAspectRatios
54222
+ }
54223
+ )
54088
54224
  ]
54089
54225
  }
54090
54226
  ) })
@@ -77,6 +77,6 @@ interface SocialLinkIconProps extends Omit<PressableProps, "children">, SocialLi
77
77
  * />
78
78
  * ```
79
79
  */
80
- declare const SocialLinkIcon: React.ForwardRefExoticComponent<SocialLinkIconProps & React.RefAttributes<HTMLButtonElement | HTMLAnchorElement | HTMLSpanElement>>;
80
+ declare const SocialLinkIcon: React.ForwardRefExoticComponent<SocialLinkIconProps & React.RefAttributes<HTMLAnchorElement | HTMLButtonElement | HTMLSpanElement>>;
81
81
 
82
82
  export { SocialLinkIcon, type SocialLinkIconDynamicIconProps, type SocialLinkIconProps };
@@ -77,6 +77,6 @@ interface SocialLinkIconProps extends Omit<PressableProps, "children">, SocialLi
77
77
  * />
78
78
  * ```
79
79
  */
80
- declare const SocialLinkIcon: React.ForwardRefExoticComponent<SocialLinkIconProps & React.RefAttributes<HTMLButtonElement | HTMLAnchorElement | HTMLSpanElement>>;
80
+ declare const SocialLinkIcon: React.ForwardRefExoticComponent<SocialLinkIconProps & React.RefAttributes<HTMLAnchorElement | HTMLButtonElement | HTMLSpanElement>>;
81
81
 
82
82
  export { SocialLinkIcon, type SocialLinkIconDynamicIconProps, type SocialLinkIconProps };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opensite/ui",
3
- "version": "3.0.7",
3
+ "version": "3.0.8",
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",
@@ -3116,6 +3116,11 @@
3116
3116
  "import": "./dist/longform-content.js",
3117
3117
  "require": "./dist/longform-content.cjs"
3118
3118
  },
3119
+ "./components/media-aspect-ratio": {
3120
+ "types": "./dist/media-aspect-ratio.d.ts",
3121
+ "import": "./dist/media-aspect-ratio.js",
3122
+ "require": "./dist/media-aspect-ratio.cjs"
3123
+ },
3119
3124
  "./components/navbar-logo": {
3120
3125
  "types": "./dist/navbar-logo.d.ts",
3121
3126
  "import": "./dist/navbar-logo.js",
@@ -3416,7 +3421,7 @@
3416
3421
  "@opensite/hooks": "2.1.0",
3417
3422
  "@page-speed/forms": "0.8.2",
3418
3423
  "@page-speed/icon": "0.1.2",
3419
- "@page-speed/img": "0.4.7",
3424
+ "@page-speed/img": "0.4.8",
3420
3425
  "@page-speed/lightbox": "0.2.1",
3421
3426
  "@page-speed/maps": "0.2.4",
3422
3427
  "@page-speed/markdown-to-jsx": "0.0.5",