@deneb-ui/ui 2.0.120 → 2.0.121

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.
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ export type DenebImageAspectRatio = 'square' | '1/1' | 'video' | '16/9' | 'portrait' | '3/4' | '4/3' | '2/3' | '21/9' | (string & {});
3
+ export type DenebImageRadius = 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full' | (string & {});
4
+ export declare const DEFAULT_IMAGE_FALLBACK_SVG = "data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"600\" height=\"400\" viewBox=\"0 0 600 400\" fill=\"none\"><rect width=\"600\" height=\"400\" fill=\"%23f1f5f9\"/><path d=\"M250 180a30 30 0 100-60 30 30 0 000 60zM170 300l80-90 60 70 70-100 90 120H170z\" fill=\"%23cbd5e1\"/></svg>";
5
+ export interface DenebImageProps extends Omit<React.ImgHTMLAttributes<HTMLImageElement>, 'src'> {
6
+ id?: string;
7
+ 'data-preview-field-path'?: string;
8
+ src?: string | null;
9
+ fallbackSrc?: string;
10
+ aspectRatio?: DenebImageAspectRatio;
11
+ radius?: DenebImageRadius;
12
+ fit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down';
13
+ hoverZoom?: boolean;
14
+ }
15
+ /**
16
+ * Universal auto-resolving image component for DENEB & Fivora templates.
17
+ *
18
+ * - Automatically prepends NEXT_PUBLIC_SITE_BASE_PATH to local assets
19
+ * - Preserves remote URLs (https://..., http://..., data:...)
20
+ * - Safely guards against empty string ("") triggers
21
+ * - Gracefully falls back to fallbackSrc or placeholder on error or missing src
22
+ */
23
+ export declare function DenebImage({ id, 'data-preview-field-path': previewFieldPath, src, fallbackSrc, alt, aspectRatio, radius, fit, hoverZoom, style, className, onError, ...props }: DenebImageProps): React.JSX.Element;
24
+ export { DenebImage as SafeImage };
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_IMAGE_FALLBACK_SVG = void 0;
4
+ exports.DenebImage = DenebImage;
5
+ exports.SafeImage = DenebImage;
6
+ const jsx_runtime_1 = require("react/jsx-runtime");
7
+ const react_1 = require("react");
8
+ const utils_1 = require("./utils");
9
+ const ASPECT_MAP = {
10
+ square: '1 / 1',
11
+ '1/1': '1 / 1',
12
+ video: '16 / 9',
13
+ '16/9': '16 / 9',
14
+ portrait: '3 / 4',
15
+ '3/4': '3 / 4',
16
+ '4/3': '4 / 3',
17
+ '2/3': '2 / 3',
18
+ '21/9': '21 / 9',
19
+ };
20
+ const RADIUS_MAP = {
21
+ none: '0px',
22
+ sm: '4px',
23
+ md: '8px',
24
+ lg: '12px',
25
+ xl: '16px',
26
+ '2xl': '24px',
27
+ full: '9999px',
28
+ };
29
+ exports.DEFAULT_IMAGE_FALLBACK_SVG = 'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="600" height="400" viewBox="0 0 600 400" fill="none"><rect width="600" height="400" fill="%23f1f5f9"/><path d="M250 180a30 30 0 100-60 30 30 0 000 60zM170 300l80-90 60 70 70-100 90 120H170z" fill="%23cbd5e1"/></svg>';
30
+ /**
31
+ * Universal auto-resolving image component for DENEB & Fivora templates.
32
+ *
33
+ * - Automatically prepends NEXT_PUBLIC_SITE_BASE_PATH to local assets
34
+ * - Preserves remote URLs (https://..., http://..., data:...)
35
+ * - Safely guards against empty string ("") triggers
36
+ * - Gracefully falls back to fallbackSrc or placeholder on error or missing src
37
+ */
38
+ function DenebImage({ id, 'data-preview-field-path': previewFieldPath, src, fallbackSrc = exports.DEFAULT_IMAGE_FALLBACK_SVG, alt = '', aspectRatio, radius, fit = 'cover', hoverZoom = false, style, className = '', onError, ...props }) {
39
+ const [hasError, setHasError] = (0, react_1.useState)(false);
40
+ const path = previewFieldPath || id;
41
+ const resolvedAspect = aspectRatio ? (ASPECT_MAP[aspectRatio] || aspectRatio) : undefined;
42
+ const resolvedRadius = radius ? (RADIUS_MAP[radius] || radius) : undefined;
43
+ const combinedStyle = {
44
+ ...(resolvedAspect ? { aspectRatio: resolvedAspect } : {}),
45
+ ...(resolvedRadius ? { borderRadius: resolvedRadius } : {}),
46
+ ...(fit ? { objectFit: fit } : {}),
47
+ ...(hoverZoom ? { transition: 'transform 0.3s cubic-bezier(0.4, 0, 0.2, 1)' } : {}),
48
+ ...style,
49
+ };
50
+ const rawSrc = hasError || !src || (typeof src === 'string' && src.trim() === '')
51
+ ? fallbackSrc
52
+ : src;
53
+ const finalSrc = typeof rawSrc === 'string' ? (0, utils_1.withBasePath)(rawSrc) : rawSrc;
54
+ return ((0, jsx_runtime_1.jsx)("img", { "data-preview-field-path": path, src: finalSrc, alt: alt, style: combinedStyle, className: `deneb-image ${hoverZoom ? 'hover:scale-105' : ''} ${className}`.trim(), onError: (e) => {
55
+ if (!hasError && fallbackSrc && finalSrc !== (0, utils_1.withBasePath)(fallbackSrc)) {
56
+ setHasError(true);
57
+ }
58
+ onError?.(e);
59
+ }, ...props }));
60
+ }
@@ -1,6 +1,7 @@
1
1
  import React, { type ReactNode } from 'react';
2
2
  import type { ProductItem } from './EditableProductCard';
3
3
  import type { ServiceItem } from './EditableServiceCard';
4
+ import { withBasePath, resolveAsset } from './utils';
4
5
  export declare const DENEB_PREVIEW_DATA_MESSAGE = "DENEB_PREVIEW_SITE_DATA";
5
6
  export declare const PREVIEW_DATA_MESSAGE = "FIVORA_PREVIEW_SITE_DATA";
6
7
  export declare const LEGACY_PREVIEW_DATA_MESSAGE: string;
@@ -90,6 +91,11 @@ export declare function useSiteData<T = SiteData>(): T;
90
91
  export declare function contentObject(value: unknown): GenericRecord;
91
92
  export declare function contentText(value: unknown): string;
92
93
  export declare function contentList<Item = unknown>(value: unknown): Item[];
94
+ /**
95
+ * Safely extracts an image URL from siteData and ensures subpath base path is applied.
96
+ */
97
+ export declare function contentImage(value: unknown, fallback?: string): string;
98
+ export { withBasePath, resolveAsset };
93
99
  export declare function contentNumber(value: unknown, fallback?: number): number;
94
100
  export declare function parseFieldPath(path: string): Array<string | number>;
95
101
  export declare function getFieldStyle(content: unknown, path?: string): GenericRecord | null;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  'use client';
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.DUMMY_PREVIEW_SHOP_NAME = exports.DUMMY_PREVIEW_ADDRESS = exports.DUMMY_PREVIEW_EMAIL = exports.DUMMY_PREVIEW_WHATSAPP = exports.DUMMY_PREVIEW_PHONE = exports.DenebDataContext = exports.useDenebData = exports.DenebDataProvider = exports.SiteDataContext = exports.DENEB_STYLE_PATCH_MESSAGE = exports.STYLE_PATCH_MESSAGE = exports.PREVIEW_FIELD_ATTRIBUTE = exports.LEGACY_PREVIEW_FOCUS_MESSAGE = exports.PREVIEW_FOCUS_MESSAGE = exports.DENEB_PREVIEW_FOCUS_MESSAGE = exports.LEGACY_PREVIEW_READY_MESSAGE = exports.PREVIEW_READY_MESSAGE = exports.DENEB_PREVIEW_READY_MESSAGE = exports.LEGACY_PREVIEW_DATA_MESSAGE = exports.PREVIEW_DATA_MESSAGE = exports.DENEB_PREVIEW_DATA_MESSAGE = void 0;
4
+ exports.DUMMY_PREVIEW_SHOP_NAME = exports.DUMMY_PREVIEW_ADDRESS = exports.DUMMY_PREVIEW_EMAIL = exports.DUMMY_PREVIEW_WHATSAPP = exports.DUMMY_PREVIEW_PHONE = exports.DenebDataContext = exports.useDenebData = exports.DenebDataProvider = exports.resolveAsset = exports.withBasePath = exports.SiteDataContext = exports.DENEB_STYLE_PATCH_MESSAGE = exports.STYLE_PATCH_MESSAGE = exports.PREVIEW_FIELD_ATTRIBUTE = exports.LEGACY_PREVIEW_FOCUS_MESSAGE = exports.PREVIEW_FOCUS_MESSAGE = exports.DENEB_PREVIEW_FOCUS_MESSAGE = exports.LEGACY_PREVIEW_READY_MESSAGE = exports.PREVIEW_READY_MESSAGE = exports.DENEB_PREVIEW_READY_MESSAGE = exports.LEGACY_PREVIEW_DATA_MESSAGE = exports.PREVIEW_DATA_MESSAGE = exports.DENEB_PREVIEW_DATA_MESSAGE = void 0;
5
5
  exports.isRecord = isRecord;
6
6
  exports.isDarkColor = isDarkColor;
7
7
  exports.syncThemeToDocument = syncThemeToDocument;
@@ -14,6 +14,7 @@ exports.useSiteData = useSiteData;
14
14
  exports.contentObject = contentObject;
15
15
  exports.contentText = contentText;
16
16
  exports.contentList = contentList;
17
+ exports.contentImage = contentImage;
17
18
  exports.contentNumber = contentNumber;
18
19
  exports.parseFieldPath = parseFieldPath;
19
20
  exports.getFieldStyle = getFieldStyle;
@@ -38,6 +39,9 @@ const DenebComponentStyles_1 = require("./DenebComponentStyles");
38
39
  const FontLoader_1 = require("./fonts/FontLoader");
39
40
  const ResponsiveBaseStyles_1 = require("./ResponsiveBaseStyles");
40
41
  const ThemeStyles_1 = require("./ThemeStyles");
42
+ const utils_1 = require("./utils");
43
+ Object.defineProperty(exports, "withBasePath", { enumerable: true, get: function () { return utils_1.withBasePath; } });
44
+ Object.defineProperty(exports, "resolveAsset", { enumerable: true, get: function () { return utils_1.resolveAsset; } });
41
45
  exports.DENEB_PREVIEW_DATA_MESSAGE = 'DENEB_PREVIEW_SITE_DATA';
42
46
  exports.PREVIEW_DATA_MESSAGE = 'FIVORA_PREVIEW_SITE_DATA';
43
47
  const PREVIOUS_PREVIEW_PREFIX = `${['MARKET', 'PLACE'].join('')}_PREVIEW_`;
@@ -649,6 +653,13 @@ function contentText(value) {
649
653
  function contentList(value) {
650
654
  return Array.isArray(value) ? value : [];
651
655
  }
656
+ /**
657
+ * Safely extracts an image URL from siteData and ensures subpath base path is applied.
658
+ */
659
+ function contentImage(value, fallback = '') {
660
+ const val = typeof value === 'string' && value.trim() ? value.trim() : fallback;
661
+ return (0, utils_1.withBasePath)(val);
662
+ }
652
663
  function contentNumber(value, fallback = 0) {
653
664
  return typeof value === 'number' && !Number.isNaN(value) ? value : fallback;
654
665
  }
package/dist/index.d.ts CHANGED
@@ -5,6 +5,7 @@
5
5
  export * from './PreviewField';
6
6
  export * from './EditableText';
7
7
  export * from './EditableImage';
8
+ export * from './DenebImage';
8
9
  export * from './EditableIcon';
9
10
  export * from './EditableMap';
10
11
  export * from './EditableList';
@@ -69,6 +70,7 @@ export { EditableParagraph as Paragraph } from './EditableText';
69
70
  export { EditableBadge as Badge } from './EditableText';
70
71
  export { EditableQuote as Quote } from './EditableText';
71
72
  export { EditableImage as Image } from './EditableImage';
73
+ export { DenebImage, DenebImage as SafeImage } from './DenebImage';
72
74
  export { EditableMap as Map } from './EditableMap';
73
75
  export { EditableGrid as Grid } from './EditableGrid';
74
76
  export { EditableSection as Section } from './EditableSection';
package/dist/index.js CHANGED
@@ -18,11 +18,12 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
18
18
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
19
19
  };
20
20
  Object.defineProperty(exports, "__esModule", { value: true });
21
- exports.TestimonialCard = exports.PricingCard = exports.ServiceCard = exports.GoogleFeedback = exports.CustomerReviews = exports.ProductDetail = exports.ProductShowcase = exports.ProductGrid = exports.EntityCard = exports.ListingCard = exports.UniversalCard = exports.VehicleCard = exports.ProductCard = exports.List = exports.Box = exports.Section = exports.Grid = exports.Map = exports.Image = exports.Quote = exports.Badge = exports.Paragraph = exports.Heading = exports.Text = exports.Dialog = exports.Card = exports.Button = exports.collectStyleTargetsFromHtml = exports.validateStyleTree = exports.styleToCssVariables = exports.patchStyleByPath = exports.patchElementStyle = exports.STYLE_TYPE_ATTRIBUTE = exports.STYLE_TARGET_ATTRIBUTE = exports.DENEB_STYLE_PATCH_MESSAGE = exports.STYLE_PATCH_MESSAGE = exports.formatResponsiveFontSize = exports.resolveInstallableFont = exports.normalizeFontId = exports.lookupFontDefinition = exports.listFontsByCategory = exports.collectFontIdsFromSiteData = exports.buildGoogleFontsStylesheetUrl = exports.DENEB_GOOGLE_FONT_COUNT = exports.DENEB_FONT_REGISTRY = exports.useDenebFonts = exports.DENEB_FONTS_LINK_ID = exports.FontLoader = exports.DenebComponentStyles = exports.ResponsiveBaseStyles = void 0;
22
- exports.generateThemeVariables = exports.mergeVisualCustomizationIntoTheme = exports.customizationToTheme = exports.parseVisualCustomization = exports.normalizeHexColor = exports.toHexColor = exports.getAutoContrastTextColor = exports.isDarkColor = exports.FONT_PAIRINGS = exports.GLOBAL_FONT_OPTIONS = exports.THEME_PALETTES = exports.DENEB_AUTHOR = exports.DENEB_FRAMEWORK_VERSION = exports.DENEB_FRAMEWORK_NAME = exports.AdditionalPagesNav = exports.PlatformAdditionalPages = exports.TestimonialCarousel = exports.BookingModal = exports.BeforeAfterSlider = exports.FilterSidebar = exports.CartDrawer = exports.CategoryPills = exports.AnnouncementBar = exports.HeroSplit = exports.Hero = exports.Footer = exports.Header = exports.Navbar = exports.ContactForm = exports.FAQ = exports.Accordion = exports.Testimonials = exports.TestimonialSection = void 0;
21
+ exports.ServiceCard = exports.GoogleFeedback = exports.CustomerReviews = exports.ProductDetail = exports.ProductShowcase = exports.ProductGrid = exports.EntityCard = exports.ListingCard = exports.UniversalCard = exports.VehicleCard = exports.ProductCard = exports.List = exports.Box = exports.Section = exports.Grid = exports.Map = exports.SafeImage = exports.DenebImage = exports.Image = exports.Quote = exports.Badge = exports.Paragraph = exports.Heading = exports.Text = exports.Dialog = exports.Card = exports.Button = exports.collectStyleTargetsFromHtml = exports.validateStyleTree = exports.styleToCssVariables = exports.patchStyleByPath = exports.patchElementStyle = exports.STYLE_TYPE_ATTRIBUTE = exports.STYLE_TARGET_ATTRIBUTE = exports.DENEB_STYLE_PATCH_MESSAGE = exports.STYLE_PATCH_MESSAGE = exports.formatResponsiveFontSize = exports.resolveInstallableFont = exports.normalizeFontId = exports.lookupFontDefinition = exports.listFontsByCategory = exports.collectFontIdsFromSiteData = exports.buildGoogleFontsStylesheetUrl = exports.DENEB_GOOGLE_FONT_COUNT = exports.DENEB_FONT_REGISTRY = exports.useDenebFonts = exports.DENEB_FONTS_LINK_ID = exports.FontLoader = exports.DenebComponentStyles = exports.ResponsiveBaseStyles = void 0;
22
+ exports.generateThemeVariables = exports.mergeVisualCustomizationIntoTheme = exports.customizationToTheme = exports.parseVisualCustomization = exports.normalizeHexColor = exports.toHexColor = exports.getAutoContrastTextColor = exports.isDarkColor = exports.FONT_PAIRINGS = exports.GLOBAL_FONT_OPTIONS = exports.THEME_PALETTES = exports.DENEB_AUTHOR = exports.DENEB_FRAMEWORK_VERSION = exports.DENEB_FRAMEWORK_NAME = exports.AdditionalPagesNav = exports.PlatformAdditionalPages = exports.TestimonialCarousel = exports.BookingModal = exports.BeforeAfterSlider = exports.FilterSidebar = exports.CartDrawer = exports.CategoryPills = exports.AnnouncementBar = exports.HeroSplit = exports.Hero = exports.Footer = exports.Header = exports.Navbar = exports.ContactForm = exports.FAQ = exports.Accordion = exports.Testimonials = exports.TestimonialSection = exports.TestimonialCard = exports.PricingCard = void 0;
23
23
  __exportStar(require("./PreviewField"), exports);
24
24
  __exportStar(require("./EditableText"), exports);
25
25
  __exportStar(require("./EditableImage"), exports);
26
+ __exportStar(require("./DenebImage"), exports);
26
27
  __exportStar(require("./EditableIcon"), exports);
27
28
  __exportStar(require("./EditableMap"), exports);
28
29
  __exportStar(require("./EditableList"), exports);
@@ -121,6 +122,9 @@ var EditableText_6 = require("./EditableText");
121
122
  Object.defineProperty(exports, "Quote", { enumerable: true, get: function () { return EditableText_6.EditableQuote; } });
122
123
  var EditableImage_1 = require("./EditableImage");
123
124
  Object.defineProperty(exports, "Image", { enumerable: true, get: function () { return EditableImage_1.EditableImage; } });
125
+ var DenebImage_1 = require("./DenebImage");
126
+ Object.defineProperty(exports, "DenebImage", { enumerable: true, get: function () { return DenebImage_1.DenebImage; } });
127
+ Object.defineProperty(exports, "SafeImage", { enumerable: true, get: function () { return DenebImage_1.DenebImage; } });
124
128
  var EditableMap_1 = require("./EditableMap");
125
129
  Object.defineProperty(exports, "Map", { enumerable: true, get: function () { return EditableMap_1.EditableMap; } });
126
130
  var EditableGrid_1 = require("./EditableGrid");
@@ -69,3 +69,8 @@ export declare function resolvePageRoute(pageKey: string, pages?: Array<{
69
69
  id: string;
70
70
  route: string;
71
71
  }>): string;
72
+ /**
73
+ * Resolves static assets with subpath prefix support.
74
+ * Canonical alias for `withBasePath`.
75
+ */
76
+ export declare const resolveAsset: typeof withBasePath;
@@ -4,6 +4,7 @@
4
4
  * Created by Chamika Gayashan & Induranga Kawishwara
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.resolveAsset = void 0;
7
8
  exports.createWhatsAppUrl = createWhatsAppUrl;
8
9
  exports.createPhoneUrl = createPhoneUrl;
9
10
  exports.createEmailUrl = createEmailUrl;
@@ -162,3 +163,8 @@ function resolvePageRoute(pageKey, pages) {
162
163
  const match = pages?.find((page) => page.id === pageKey);
163
164
  return match?.route ?? `/${pageKey.replace(/_/g, '/')}`;
164
165
  }
166
+ /**
167
+ * Resolves static assets with subpath prefix support.
168
+ * Canonical alias for `withBasePath`.
169
+ */
170
+ exports.resolveAsset = withBasePath;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deneb-ui/ui",
3
- "version": "2.0.120",
3
+ "version": "2.0.121",
4
4
  "description": "Visual-first React component library for editable commerce storefronts. Built for Next.js and Fivora.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -50,7 +50,7 @@
50
50
  ],
51
51
  "license": "MIT",
52
52
  "dependencies": {
53
- "@deneb-ui/core": "^2.0.120"
53
+ "@deneb-ui/core": "^2.0.121"
54
54
  },
55
55
  "peerDependencies": {
56
56
  "react": "^18.0.0 || ^19.0.0",