@opensite/ui 3.6.5 → 3.6.6

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
@@ -52987,8 +52987,52 @@ function HeroGridPatternEfficiency({
52987
52987
  }
52988
52988
  );
52989
52989
  }
52990
+ var SIZE_CLASSES = {
52991
+ sm: "max-h-6 sm:max-h-7",
52992
+ md: "max-h-8 sm:max-h-9 lg:max-h-10",
52993
+ lg: "max-h-10 sm:max-h-12 lg:max-h-14",
52994
+ xl: "max-h-12 sm:max-h-14 lg:max-h-16"
52995
+ };
52996
+ var BrandLogo = ({
52997
+ logo,
52998
+ logoSlot: logoSlot2,
52999
+ logoClassName,
53000
+ size = "md",
53001
+ optixFlowConfig
53002
+ }) => {
53003
+ if (logoSlot2) return /* @__PURE__ */ jsx(Fragment, { children: logoSlot2 });
53004
+ if (!logo || !logo.src) return null;
53005
+ const imgElement = /* @__PURE__ */ jsx(
53006
+ Img,
53007
+ {
53008
+ src: logo.src,
53009
+ className: cn(
53010
+ "w-auto object-contain",
53011
+ SIZE_CLASSES[size],
53012
+ logo.className
53013
+ ),
53014
+ alt: logo.alt || "Logo",
53015
+ optixFlowConfig,
53016
+ loading: "eager"
53017
+ }
53018
+ );
53019
+ if (logo.url) {
53020
+ return /* @__PURE__ */ jsx(
53021
+ Pressable,
53022
+ {
53023
+ href: logo.url,
53024
+ className: cn("flex items-center", logoClassName),
53025
+ children: imgElement
53026
+ }
53027
+ );
53028
+ }
53029
+ return /* @__PURE__ */ jsx("div", { className: cn("flex items-center", logoClassName), children: imgElement });
53030
+ };
52990
53031
  function HeroDashedBorderFeatures({
52991
53032
  sectionId = "hero-dashed-border-features",
53033
+ logo,
53034
+ logoSlot: logoSlot2,
53035
+ logoClassName,
52992
53036
  badgeText,
52993
53037
  announcementText,
52994
53038
  announcementHref,
@@ -53000,7 +53044,7 @@ function HeroDashedBorderFeatures({
53000
53044
  features,
53001
53045
  featuresSlot,
53002
53046
  background,
53003
- spacing = "xl",
53047
+ spacing = "hero",
53004
53048
  pattern,
53005
53049
  patternOpacity,
53006
53050
  className,
@@ -53073,14 +53117,18 @@ function HeroDashedBorderFeatures({
53073
53117
  Pressable,
53074
53118
  {
53075
53119
  className: cn(
53076
- "flex items-center gap-6 border-t border-dashed p-4 font-medium md:justify-center lg:p-10 lg:text-lg",
53120
+ "flex items-center gap-6 border-t border-dashed p-4 md:justify-center lg:p-10 ",
53121
+ feature.href ? "cursor-pointer bg-transparent transition-colors duration-300 hover:bg-card hover:text-card-foreground" : "",
53077
53122
  index === 1 && "md:border-x",
53078
53123
  index === 2 ? "border-b" : "md:border-b"
53079
53124
  ),
53080
53125
  href: feature.href,
53081
53126
  children: [
53082
- /* @__PURE__ */ jsx("span", { className: "flex size-10 shrink-0 items-center justify-center rounded-md text-sm lg:size-12 lg:text-base bg-card text-card-foreground", children: feature.icon ? feature.icon : feature.iconName ? /* @__PURE__ */ jsx(DynamicIcon, { name: feature.iconName || "lucide/check", size: 20 }) : null }),
53083
- feature.title
53127
+ feature.icon || feature.iconName ? /* @__PURE__ */ jsx("span", { className: "flex size-10 shrink-0 items-center justify-center rounded-md text-sm lg:size-12 lg:text-base bg-card text-card-foreground", children: /* @__PURE__ */ jsx(DynamicIcon, { name: feature.icon || feature.iconName, size: 20 }) }) : null,
53128
+ feature.title || feature.description ? /* @__PURE__ */ jsxs("div", { className: "text-left flex flex-col gap-1", children: [
53129
+ feature.title ? /* @__PURE__ */ jsx("div", { className: "font-medium text-base md:text-lg line-clamp-2", children: feature.title }) : null,
53130
+ feature.description ? typeof feature.description === "string" && feature.description?.length > 0 ? /* @__PURE__ */ jsx("div", { className: "text-sm md:text-base opacity-70 text-balance line-clamp-1", children: feature.description }) : feature.description : null
53131
+ ] }) : null
53084
53132
  ]
53085
53133
  },
53086
53134
  index
@@ -53097,6 +53145,7 @@ function HeroDashedBorderFeatures({
53097
53145
  className: cn("relative flex items-center justify-center", className),
53098
53146
  containerClassName,
53099
53147
  children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
53148
+ (logo || logoSlot2) && /* @__PURE__ */ jsx("div", { className: cn("mb-6", logoClassName), children: /* @__PURE__ */ jsx(BrandLogo, { logo, logoSlot: logoSlot2, size: "lg" }) }),
53100
53149
  /* @__PURE__ */ jsx(
53101
53150
  "div",
53102
53151
  {
@@ -53110,12 +53159,12 @@ function HeroDashedBorderFeatures({
53110
53159
  "h1",
53111
53160
  {
53112
53161
  className: cn(
53113
- "my-4 mb-6 text-center text-3xl font-semibold lg:text-8xl",
53162
+ "my-4 mb-6 text-center text-3xl font-semibold lg:text-8xl leading-tight",
53114
53163
  headingClassName
53115
53164
  ),
53116
53165
  children: heading
53117
53166
  }
53118
- ) : /* @__PURE__ */ jsx("div", { className: headingClassName, children: heading })),
53167
+ ) : heading),
53119
53168
  description && (typeof description === "string" ? /* @__PURE__ */ jsx(
53120
53169
  "p",
53121
53170
  {
@@ -53125,7 +53174,7 @@ function HeroDashedBorderFeatures({
53125
53174
  ),
53126
53175
  children: description
53127
53176
  }
53128
- ) : /* @__PURE__ */ jsx("div", { className: descriptionClassName, children: description })),
53177
+ ) : description),
53129
53178
  renderActions
53130
53179
  ] })
53131
53180
  }
@@ -53191,13 +53240,17 @@ function HeroDesignCarouselPortfolio({
53191
53240
  const renderLogo = useMemo(() => {
53192
53241
  if (logoSlot2) return logoSlot2;
53193
53242
  if (!logo) return null;
53194
- const logoSrc = typeof logo.src === "string" ? logo.src : logo.src.light;
53243
+ const logoConfig = {
53244
+ src: typeof logo.src === "string" ? logo.src : logo.src.light,
53245
+ alt: logo.alt,
53246
+ className: logo.className,
53247
+ url: logo.href
53248
+ };
53195
53249
  return /* @__PURE__ */ jsx(
53196
- Img,
53250
+ BrandLogo,
53197
53251
  {
53198
- src: logoSrc,
53199
- className: cn("object-contain w-auto h-12 lg:h-16", logo.className),
53200
- alt: logo.alt,
53252
+ logo: logoConfig,
53253
+ size: "xl",
53201
53254
  optixFlowConfig
53202
53255
  }
53203
53256
  );
@@ -55841,6 +55894,9 @@ function HeroDesignShowcaseLogos({
55841
55894
  }
55842
55895
  function HeroVideoOverlayStars({
55843
55896
  sectionId = "hero-video-overlay-stars",
55897
+ logo,
55898
+ logoSlot: logoSlot2,
55899
+ logoClassName,
55844
55900
  heading,
55845
55901
  actions,
55846
55902
  actionsSlot,
@@ -55904,6 +55960,7 @@ function HeroVideoOverlayStars({
55904
55960
  containerClassName,
55905
55961
  children: [
55906
55962
  /* @__PURE__ */ jsx("div", { className: "relative z-10 flex size-full", children: /* @__PURE__ */ jsxs("div", { className: "m-auto flex max-w-100 flex-col items-center gap-9 sm:max-w-125 md:max-w-200 text-center", children: [
55963
+ (logo || logoSlot2) && /* @__PURE__ */ jsx("div", { className: cn("mb-2 flex justify-center", logoClassName), children: /* @__PURE__ */ jsx(BrandLogo, { logo, logoSlot: logoSlot2, size: "lg" }) }),
55907
55964
  /* @__PURE__ */ jsxs("div", { className: cn("flex w-full flex-col gap-8", contentClassName), children: [
55908
55965
  heading && (typeof heading === "string" ? /* @__PURE__ */ jsx(
55909
55966
  "h1",
@@ -117149,13 +117206,16 @@ var HERO_BLOCK_CONTRACTS = {
117149
117206
  "hero-dashed-border-features": {
117150
117207
  exampleUsage: `
117151
117208
  <HeroDashedBorderFeatures
117209
+ logo={{ src: "https://cdn.ing/assets/i/r/287634/e4cmvu8nbwoqy2qer90t4gpap0ed/logo-light.png", alt: "Brand Logo" }}
117152
117210
  heading="Features that make a difference"
117153
117211
  description="Discover the powerful capabilities that set us apart."
117154
117212
  badgeText="New Features"
117213
+ announcementText="Latest innovations"
117214
+ announcementHref="#"
117155
117215
  features={[
117156
- { icon: null, title: "Lightning Fast", description: "Optimized for speed", href: "#" },
117157
- { icon: null, title: "Secure by Default", description: "Enterprise-grade security", href: "#" },
117158
- { icon: null, title: "AI-Powered", description: "Smart automation", href: "#" },
117216
+ { iconName: "lucide/zap", title: "Lightning Fast", description: "Optimized for speed", href: "#" },
117217
+ { iconName: "lucide/shield", title: "Secure by Default", description: "Enterprise-grade security", href: "#" },
117218
+ { iconName: "lucide/sparkles", title: "AI-Powered", description: "Smart automation", href: "#" },
117159
117219
  ]}
117160
117220
  actions={[
117161
117221
  { label: "Explore Features", href: "#", variant: "default" },
@@ -117163,25 +117223,32 @@ var HERO_BLOCK_CONTRACTS = {
117163
117223
  ]}
117164
117224
  />
117165
117225
  `.trim(),
117166
- importantUsageNotes: "Supply exactly 3 'features' objects. Do not exceed 50 characters for 'heading'. Do not exceed 130 characters for 'description'. If you supply multiple 'actions', use 'default' for the first and 'outline' for the second. This is a text/icon hero \u2014 no images required.",
117226
+ importantUsageNotes: "The optional 'logo' prop accepts a LogoConfig object and renders via the BrandLogo component \u2014 it must be a brand logo image, NEVER a photo or hero image. Supply exactly 3 'features' objects. Do not exceed 50 characters for 'heading'. Do not exceed 130 characters for 'description'. If you supply multiple 'actions', use 'default' for the first and 'outline' for the second.",
117167
117227
  usageRequirements: {
117168
117228
  requiredProps: ["heading", "features"],
117169
117229
  propConstraints: {
117170
117230
  heading: { required: true, maxLength: 50 },
117171
117231
  description: { maxLength: 130 },
117172
117232
  features: { required: true, count: 3, minItems: 2, maxItems: 4 },
117173
- actions: { maxItems: 2, pinnedValues: { "0.variant": "default", "1.variant": "outline" } }
117233
+ actions: { maxItems: 2, pinnedValues: { "0.variant": "default", "1.variant": "outline" } },
117234
+ "logo.src": { note: "LOGO MEDIA ONLY. Must be a brand logo image (SVG, PNG, WebP). Never use a photo, hero image, or video asset." }
117174
117235
  },
117175
- mediaSlots: {}
117236
+ mediaSlots: {
117237
+ "logo.src": logoSlot("logo.src", "Brand logo rendered via BrandLogo component above the dashed border content.", false)
117238
+ },
117239
+ notes: ["The logo prop is optional. When provided, the BrandLogo component renders it above the announcement badge with responsive sizing."]
117176
117240
  },
117177
117241
  exampleProps: {
117242
+ logo: { src: "https://cdn.ing/assets/i/r/287634/e4cmvu8nbwoqy2qer90t4gpap0ed/logo-light.png", alt: "Brand Logo" },
117178
117243
  heading: "Features that make a difference",
117179
117244
  description: "Discover the powerful capabilities that set us apart.",
117180
117245
  badgeText: "New Features",
117246
+ announcementText: "Latest innovations",
117247
+ announcementHref: "#",
117181
117248
  features: [
117182
- { title: "Lightning Fast", description: "Optimized for speed", href: "#" },
117183
- { title: "Secure by Default", description: "Enterprise-grade security", href: "#" },
117184
- { title: "AI-Powered", description: "Smart automation", href: "#" }
117249
+ { iconName: "lucide/zap", title: "Lightning Fast", description: "Optimized for speed", href: "#" },
117250
+ { iconName: "lucide/shield", title: "Secure by Default", description: "Enterprise-grade security", href: "#" },
117251
+ { iconName: "lucide/sparkles", title: "AI-Powered", description: "Smart automation", href: "#" }
117185
117252
  ],
117186
117253
  actions: [
117187
117254
  { label: "Explore Features", href: "#", variant: "default" },
@@ -117195,12 +117262,13 @@ var HERO_BLOCK_CONTRACTS = {
117195
117262
  "hero-design-carousel-portfolio": {
117196
117263
  exampleUsage: `
117197
117264
  <HeroDesignCarouselPortfolio
117265
+ logo={{ src: "https://cdn.ing/assets/i/r/287634/e4cmvu8nbwoqy2qer90t4gpap0ed/logo-light.png", alt: "Brand Logo" }}
117198
117266
  heading="Design portfolio that speaks volumes"
117199
117267
  description="Showcase your best work with beautiful, interactive carousels."
117200
117268
  features={[
117201
- { title: "Strategic Focus", description: "Aligning work with your goals." },
117202
- { title: "Rapid Execution", description: "Agile methodology for fast delivery." },
117203
- { title: "Human-Centered", description: "Design for people first." },
117269
+ { iconName: "lucide/target", title: "Strategic Focus", description: "Aligning work with your goals." },
117270
+ { iconName: "lucide/zap", title: "Rapid Execution", description: "Agile methodology for fast delivery." },
117271
+ { iconName: "lucide/heart", title: "Human-Centered", description: "Design for people first." },
117204
117272
  ]}
117205
117273
  carouselImages={[
117206
117274
  { src: "${HERO_EXAMPLE_IMAGE_URL}", alt: "Design 1" },
@@ -117214,7 +117282,7 @@ var HERO_BLOCK_CONTRACTS = {
117214
117282
  ]}
117215
117283
  />
117216
117284
  `.trim(),
117217
- importantUsageNotes: `Supply exactly 4 carousel images. Supply exactly 3 'features' objects. Do not exceed 50 characters for 'heading'. Do not exceed 130 characters for 'description'. If you supply multiple 'actions', use 'default' for the first and 'outline' for the second. ${HERO_MEDIA_NOTE}`,
117285
+ importantUsageNotes: `The 'logo' prop renders via BrandLogo and must be a brand logo image (SVG, PNG, WebP) \u2014 NEVER a photo or hero image. The AI Agent must use a real brand logo asset here, not an image placeholder. Supply exactly 4 carousel images for the portfolio. Supply exactly 3 'features'. ${HERO_MEDIA_NOTE}`,
117218
117286
  usageRequirements: {
117219
117287
  requiredProps: ["heading", "carouselImages", "features"],
117220
117288
  propConstraints: {
@@ -117222,21 +117290,23 @@ var HERO_BLOCK_CONTRACTS = {
117222
117290
  description: { maxLength: 130 },
117223
117291
  carouselImages: { required: true, count: 4, minItems: 3, maxItems: 5 },
117224
117292
  features: { required: true, count: 3, minItems: 3, maxItems: 3 },
117225
- actions: { maxItems: 2, pinnedValues: { "0.variant": "default", "1.variant": "outline" } }
117293
+ actions: { maxItems: 2, pinnedValues: { "0.variant": "default", "1.variant": "outline" } },
117294
+ "logo.src": { note: "LOGO MEDIA ONLY. Must be a brand logo image. Never use a photo, hero image, or video asset." }
117226
117295
  },
117227
117296
  mediaSlots: {
117228
117297
  "carouselImages[]": imageSlot("carouselImages[]", "Portfolio showcase images for the carousel.", ["feature", "hero"], "medium", true),
117229
- "logo.src": logoSlot("logo.src", "Optional brand or client logo.")
117298
+ "logo.src": logoSlot("logo.src", "Brand logo rendered via BrandLogo component above the features and heading.", false)
117230
117299
  },
117231
117300
  requiresSiteCapabilities: heroCapabilities("media_library")
117232
117301
  },
117233
117302
  exampleProps: {
117303
+ logo: { src: "https://cdn.ing/assets/i/r/287634/e4cmvu8nbwoqy2qer90t4gpap0ed/logo-light.png", alt: "Brand Logo" },
117234
117304
  heading: "Design portfolio that speaks volumes",
117235
117305
  description: "Showcase your best work with beautiful, interactive carousels.",
117236
117306
  features: [
117237
- { title: "Strategic Focus", description: "Aligning work with your goals." },
117238
- { title: "Rapid Execution", description: "Agile methodology for fast delivery." },
117239
- { title: "Human-Centered", description: "Design for people first." }
117307
+ { iconName: "lucide/target", title: "Strategic Focus", description: "Aligning work with your goals." },
117308
+ { iconName: "lucide/zap", title: "Rapid Execution", description: "Agile methodology for fast delivery." },
117309
+ { iconName: "lucide/heart", title: "Human-Centered", description: "Design for people first." }
117240
117310
  ],
117241
117311
  carouselImages: Array(4).fill({ src: HERO_EXAMPLE_IMAGE_URL, alt: "Design" }),
117242
117312
  actions: [
@@ -118023,6 +118093,7 @@ var HERO_BLOCK_CONTRACTS = {
118023
118093
  "hero-video-overlay-stars": {
118024
118094
  exampleUsage: `
118025
118095
  <HeroVideoOverlayStars
118096
+ logo={{ src: "https://cdn.ing/assets/i/r/287634/e4cmvu8nbwoqy2qer90t4gpap0ed/logo-light.png", alt: "Brand Logo" }}
118026
118097
  heading="Trusted by thousands"
118027
118098
  description="Our solution is designed to streamline your business operations."
118028
118099
  actions={[{ label: "Try It Free", href: "#" }]}
@@ -118035,21 +118106,24 @@ var HERO_BLOCK_CONTRACTS = {
118035
118106
  trust={{ starCount: 5, message: "Trusted by 2,500+ customers" }}
118036
118107
  />
118037
118108
  `.trim(),
118038
- importantUsageNotes: `Only use when you have a real video asset. The 'backgroundVideo.video' prop requires masterPlaylistUrl and fallbackSrc. Only supply real 'trust.message' \u2014 do not fabricate review counts. Do not exceed 40 characters for 'heading'. ${HERO_MEDIA_NOTE}`,
118109
+ importantUsageNotes: `The optional 'logo' prop renders via BrandLogo centered above the heading \u2014 it must be a brand logo image, NEVER a photo. Only use when you have a real video asset. The 'backgroundVideo.video' prop requires masterPlaylistUrl and fallbackSrc. Only supply real 'trust.message' \u2014 do not fabricate review counts. ${HERO_MEDIA_NOTE}`,
118039
118110
  usageRequirements: {
118040
118111
  requiredProps: ["heading", "backgroundVideo"],
118041
118112
  propConstraints: {
118042
118113
  heading: { required: true, maxLength: 40 },
118043
118114
  description: { maxLength: 130 },
118044
118115
  backgroundVideo: { required: true, note: "Must contain a valid video with masterPlaylistUrl and fallbackSrc." },
118045
- "trust.message": { note: "Must be real trust/review data. Do not fabricate." }
118116
+ "trust.message": { note: "Must be real trust/review data. Do not fabricate." },
118117
+ "logo.src": { note: "LOGO MEDIA ONLY. Must be a brand logo image. Never use a photo, hero image, or video asset." }
118046
118118
  },
118047
118119
  mediaSlots: {
118048
- "backgroundVideo.video": videoMediaSlot("backgroundVideo.video")
118120
+ "backgroundVideo.video": videoMediaSlot("backgroundVideo.video"),
118121
+ "logo.src": logoSlot("logo.src", "Brand logo rendered via BrandLogo centered above the heading on the video overlay.", false)
118049
118122
  },
118050
118123
  requiresSiteCapabilities: heroCapabilities("media_library", "reviews_or_testimonials")
118051
118124
  },
118052
118125
  exampleProps: {
118126
+ logo: { src: "https://cdn.ing/assets/i/r/287634/e4cmvu8nbwoqy2qer90t4gpap0ed/logo-light.png", alt: "Brand Logo" },
118053
118127
  heading: "Trusted by thousands",
118054
118128
  description: "Our solution is designed to streamline your business operations.",
118055
118129
  backgroundVideo: { video: EXAMPLE_VIDEO_1 },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opensite/ui",
3
- "version": "3.6.5",
3
+ "version": "3.6.6",
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",
@@ -3006,6 +3006,11 @@
3006
3006
  "import": "./dist/brand-attribution.js",
3007
3007
  "require": "./dist/brand-attribution.cjs"
3008
3008
  },
3009
+ "./components/brand-logo": {
3010
+ "types": "./dist/brand-logo.d.ts",
3011
+ "import": "./dist/brand-logo.js",
3012
+ "require": "./dist/brand-logo.cjs"
3013
+ },
3009
3014
  "./components/breadcrumb": {
3010
3015
  "types": "./dist/breadcrumb.d.ts",
3011
3016
  "import": "./dist/breadcrumb.js",