@deneb-ui/ui 2.0.22 → 2.0.24
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/README.md +77 -155
- package/dist/DenebComponentStyles.d.ts +6 -0
- package/dist/DenebComponentStyles.js +84 -0
- package/dist/EditableCard.js +5 -1
- package/dist/EditableContactForm.js +1 -1
- package/dist/EditableFilterSidebar.js +12 -11
- package/dist/EditableFooter.js +1 -1
- package/dist/EditableGrid.js +15 -12
- package/dist/EditableNavbar.js +32 -19
- package/dist/EditablePricingCard.js +1 -1
- package/dist/EditableProductCard.js +4 -4
- package/dist/EditableProductDetail.js +2 -2
- package/dist/EditableProductGrid.js +1 -1
- package/dist/EditableSection.js +7 -10
- package/dist/EditableText.d.ts +1 -1
- package/dist/EditableText.js +8 -33
- package/dist/ResponsiveBaseStyles.d.ts +7 -0
- package/dist/ResponsiveBaseStyles.js +136 -0
- package/dist/SiteDataProvider.d.ts +2 -0
- package/dist/SiteDataProvider.js +22 -4
- package/dist/StickyMobileBar.js +1 -1
- package/dist/ThemeStyles.js +2 -1
- package/dist/TrustBadges.js +1 -1
- package/dist/contact/FloatingContactWidget.js +3 -2
- package/dist/fonts/FontLoader.d.ts +13 -0
- package/dist/fonts/FontLoader.js +43 -0
- package/dist/fonts/useDenebFonts.d.ts +6 -0
- package/dist/fonts/useDenebFonts.js +29 -0
- package/dist/hooks/useComponentStyle.d.ts +8 -0
- package/dist/hooks/useComponentStyle.js +46 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +33 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/responsive.d.ts +33 -0
- package/dist/utils/responsive.js +100 -0
- package/package.json +21 -8
- package/scripts/setup-fonts.cjs +26 -0
|
@@ -49,17 +49,17 @@ function EditableProductCard({ itemPath, product, cardVariant = 'modern-glass',
|
|
|
49
49
|
borderRadius: '14px',
|
|
50
50
|
overflow: 'hidden',
|
|
51
51
|
display: 'flex',
|
|
52
|
-
flexDirection: '
|
|
53
|
-
alignItems: '
|
|
52
|
+
flexDirection: 'column',
|
|
53
|
+
alignItems: 'stretch',
|
|
54
54
|
},
|
|
55
55
|
};
|
|
56
56
|
return ((0, jsx_runtime_1.jsxs)(Component, { "data-preview-item-path": itemPath, style: {
|
|
57
57
|
...variantStyles[cardVariant],
|
|
58
58
|
...style,
|
|
59
|
-
}, className: `editable-product-card group ${className}`.trim(), ...props, children: [(0, jsx_runtime_1.jsxs)("div", { style: {
|
|
59
|
+
}, className: `editable-product-card group ${isHorizontal ? 'is-horizontal' : ''} ${className}`.trim(), ...props, children: [(0, jsx_runtime_1.jsxs)("div", { className: "deneb-product-card-media", style: {
|
|
60
60
|
position: 'relative',
|
|
61
61
|
overflow: 'hidden',
|
|
62
|
-
width: isHorizontal ? '
|
|
62
|
+
width: isHorizontal ? '100%' : '100%',
|
|
63
63
|
flexShrink: 0,
|
|
64
64
|
}, children: [(0, jsx_runtime_1.jsx)(EditableImage_1.EditableImage, { id: `${itemPath}.imageUrl`, src: imageUrl, fallbackSrc: imageFallback, alt: name, aspectRatio: isHorizontal ? 'square' : '4/3', fit: "cover", hoverZoom: true, style: { width: '100%', height: '100%', display: 'block' } }), badge && ((0, jsx_runtime_1.jsx)("div", { style: { position: 'absolute', top: '10px', left: '10px', zIndex: 10 }, children: (0, jsx_runtime_1.jsx)(EditableText_2.EditableBadge, { id: `${itemPath}.badge`, defaultValue: badge, badgeVariant: "primary" }) }))] }), (0, jsx_runtime_1.jsxs)("div", { style: {
|
|
65
65
|
padding: '1.25rem',
|
|
@@ -42,11 +42,11 @@ function EditableProductDetail({ sectionPath = 'product', product, sizes = ['40'
|
|
|
42
42
|
const resolvedWhatsappUrl = whatsappUrl || (product.whatsappNumber
|
|
43
43
|
? (0, urls_1.createWhatsAppUrl)(product.whatsappNumber, product.whatsappMessage || `Hi, I would like to order ${name} (${selectedSize}, ${selectedColor}) - ${price}`)
|
|
44
44
|
: '');
|
|
45
|
-
return ((0, jsx_runtime_1.jsx)("section", { "data-preview-page-key": sectionPath, className: `editable-product-detail max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12 ${className}`.trim(), style: style, ...props, children: (0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-1 lg:grid-cols-12 gap-12 lg:gap-16 items-start", children: [(0, jsx_runtime_1.jsxs)("div", { className: "lg:col-span-7 flex flex-col-reverse md:flex-row gap-4", children: [images.length > 1 && ((0, jsx_runtime_1.jsx)("div", { className: "flex md:flex-col gap-3 overflow-x-auto md:overflow-y-auto max-h-[580px] pb-2 md:pb-0 scrollbar-none", children: images.map((img, idx) => ((0, jsx_runtime_1.jsx)("button", { type: "button", onClick: () => setActiveImage(img), className: `w-20 h-20 sm:w-24 sm:h-24 rounded-2xl overflow-hidden border-2 transition-all duration-200 flex-shrink-0 bg-slate-900/40 p-2 ${activeImage === img
|
|
45
|
+
return ((0, jsx_runtime_1.jsx)("section", { "data-preview-page-key": sectionPath, className: `editable-product-detail max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12 ${className}`.trim(), style: style, ...props, children: (0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-1 lg:grid-cols-12 gap-12 lg:gap-16 items-start", children: [(0, jsx_runtime_1.jsxs)("div", { className: "lg:col-span-7 flex flex-col-reverse md:flex-row gap-4", children: [images.length > 1 && ((0, jsx_runtime_1.jsx)("div", { className: "deneb-product-detail-gallery flex md:flex-col gap-3 overflow-x-auto md:overflow-y-auto max-h-[580px] pb-2 md:pb-0 scrollbar-none", children: images.map((img, idx) => ((0, jsx_runtime_1.jsx)("button", { type: "button", onClick: () => setActiveImage(img), className: `w-20 h-20 sm:w-24 sm:h-24 rounded-2xl overflow-hidden border-2 transition-all duration-200 flex-shrink-0 bg-slate-900/40 p-2 ${activeImage === img
|
|
46
46
|
? 'border-brand-primary scale-98 shadow-md'
|
|
47
47
|
: 'border-slate-800/80 opacity-60 hover:opacity-100 hover:border-slate-700'}`, children: (0, jsx_runtime_1.jsx)("img", { src: (0, utils_1.withBasePath)(img), alt: "", className: "w-full h-full object-contain" }) }, idx))) })), (0, jsx_runtime_1.jsxs)("div", { className: "relative flex-1 aspect-square rounded-3xl bg-gradient-to-b from-slate-900/50 to-slate-950/80 border border-slate-800/80 p-8 flex items-center justify-center overflow-hidden group", children: [badge && ((0, jsx_runtime_1.jsx)("span", { "data-preview-field-path": `${sectionPath}.badge`, className: "absolute top-6 left-6 z-10 px-3.5 py-1 text-xs font-black tracking-wider uppercase rounded-full bg-lime-400 text-slate-950 shadow-lg", children: badge })), (0, jsx_runtime_1.jsx)("img", { "data-preview-field-path": `${sectionPath}.featuredImage`, src: (0, utils_1.withBasePath)(activeImage), alt: name, className: "w-full h-full object-contain transition-transform duration-500 group-hover:scale-105" })] })] }), (0, jsx_runtime_1.jsx)("div", { className: "lg:col-span-5 flex flex-col justify-between", children: (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h1", { "data-preview-field-path": `${sectionPath}.name`, className: "text-3xl sm:text-4xl font-extrabold tracking-tight text-white leading-tight", children: name }), (0, jsx_runtime_1.jsxs)("div", { className: "mt-4 flex items-baseline gap-3", children: [(0, jsx_runtime_1.jsx)("span", { "data-preview-field-path": `${sectionPath}.price`, className: "text-3xl font-black text-lime-400 tracking-tight", children: price }), product.originalPrice ? ((0, jsx_runtime_1.jsx)("span", { className: "text-lg font-medium text-slate-500 line-through", children: String(product.originalPrice) })) : null] }), description && ((0, jsx_runtime_1.jsx)("p", { "data-preview-field-path": `${sectionPath}.description`, className: "mt-6 text-base text-slate-300 leading-relaxed", children: description })), colors.length > 0 && ((0, jsx_runtime_1.jsxs)("div", { className: "mt-8", children: [(0, jsx_runtime_1.jsxs)("span", { className: "block text-xs font-bold uppercase tracking-wider text-slate-400 mb-3", children: ["Color \u2014 ", (0, jsx_runtime_1.jsx)("span", { className: "text-white", children: selectedColor })] }), (0, jsx_runtime_1.jsx)("div", { className: "flex gap-3", children: colors.map((c) => ((0, jsx_runtime_1.jsx)("button", { type: "button", onClick: () => setSelectedColor(c.name), className: `w-9 h-9 rounded-full border-2 transition-all p-0.5 ${selectedColor === c.name
|
|
48
48
|
? 'border-lime-400 ring-2 ring-lime-400/30 scale-105'
|
|
49
|
-
: 'border-slate-700 hover:border-slate-500'}`, style: { backgroundColor: c.hex }, title: c.name, "aria-label": c.name }, c.name))) })] })), sizes.length > 0 && ((0, jsx_runtime_1.jsxs)("div", { className: "mt-8", children: [(0, jsx_runtime_1.jsx)("span", { className: "block text-xs font-bold uppercase tracking-wider text-slate-400 mb-3", children: "Select Size" }), (0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-4 sm:grid-cols-7 gap-2", children: sizes.map((s) => ((0, jsx_runtime_1.jsx)("button", { type: "button", onClick: () => setSelectedSize(s), className: `py-2.5 rounded-xl font-bold text-sm transition-all duration-150 ${selectedSize === s
|
|
49
|
+
: 'border-slate-700 hover:border-slate-500'}`, style: { backgroundColor: c.hex }, title: c.name, "aria-label": c.name }, c.name))) })] })), sizes.length > 0 && ((0, jsx_runtime_1.jsxs)("div", { className: "mt-8", children: [(0, jsx_runtime_1.jsx)("span", { className: "block text-xs font-bold uppercase tracking-wider text-slate-400 mb-3", children: "Select Size" }), (0, jsx_runtime_1.jsx)("div", { className: "deneb-product-detail-sizes grid grid-cols-4 sm:grid-cols-7 gap-2", children: sizes.map((s) => ((0, jsx_runtime_1.jsx)("button", { type: "button", onClick: () => setSelectedSize(s), className: `py-2.5 rounded-xl font-bold text-sm transition-all duration-150 ${selectedSize === s
|
|
50
50
|
? 'bg-white text-slate-950 shadow-md font-extrabold scale-102'
|
|
51
51
|
: 'bg-slate-900/60 text-slate-300 border border-slate-800 hover:bg-slate-800 hover:text-white'}`, children: s }, s))) })] })), (0, jsx_runtime_1.jsxs)("div", { className: "mt-8 flex flex-col gap-3", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", onClick: () => onAddToSelection?.(product, selectedSize, selectedColor), className: "w-full py-4 px-6 rounded-2xl font-black text-sm uppercase tracking-wider bg-lime-400 text-slate-950 hover:bg-lime-300 active:scale-98 transition-all duration-150 shadow-lg shadow-lime-400/20 flex items-center justify-center gap-2", children: (0, jsx_runtime_1.jsx)("span", { "data-preview-field-path": `${sectionPath}.addToSelectionLabel`, children: addToSelectionLabel }) }), resolvedWhatsappUrl && ((0, jsx_runtime_1.jsxs)("a", { href: resolvedWhatsappUrl, target: "_blank", rel: "noopener noreferrer", className: "w-full py-3.5 px-6 rounded-2xl font-bold text-sm bg-emerald-600/20 text-emerald-400 hover:bg-emerald-600/30 border border-emerald-500/30 transition-all duration-150 flex items-center justify-center gap-2", children: [(0, jsx_runtime_1.jsx)("svg", { className: "w-5 h-5 fill-current", viewBox: "0 0 24 24", children: (0, jsx_runtime_1.jsx)("path", { d: "M17.472 14.382c-.301-.15-1.78-.879-2.056-.98-.276-.1-.477-.15-.678.15-.201.3-.78 0.98-.956 1.18-.175.2-.351.226-.652.075-.301-.15-1.272-.469-2.423-1.496-.896-.799-1.501-1.787-1.677-2.088-.175-.301-.019-.464.132-.614.136-.135.301-.351.452-.527.15-.176.201-.301.301-.502.1-.2.05-.376-.025-.527-.075-.15-.678-1.635-.93-2.242-.244-.592-.493-.512-.678-.521-.175-.009-.376-.009-.577-.009-.201 0-.527.075-.803.376-.276.301-1.054 1.03-1.054 2.512 0 1.482 1.079 2.912 1.23 3.113.15.201 2.124 3.243 5.145 4.548.718.311 1.279.497 1.716.636.722.23 1.378.197 1.898.12.579-.087 1.78-.728 2.03-1.431.251-.703.251-1.305.176-1.431-.075-.126-.276-.201-.577-.351zM12.004 2C6.48 2 2 6.48 2 12c0 1.82.49 3.52 1.34 4.99L2 22l5.14-1.35c1.42.78 3.04 1.22 4.86 1.22 5.52 0 10-4.48 10-10S17.524 2 12.004 2z" }) }), (0, jsx_runtime_1.jsx)("span", { children: "Order Directly via WhatsApp" })] }))] }), (0, jsx_runtime_1.jsxs)("div", { className: "mt-10 border-t border-slate-800/80 pt-6", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex gap-6 border-b border-slate-800 pb-3 mb-4", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", onClick: () => setActiveTab('specs'), className: `text-sm font-bold tracking-wide transition-colors ${activeTab === 'specs' ? 'text-lime-400' : 'text-slate-400 hover:text-slate-200'}`, children: (0, jsx_runtime_1.jsx)("span", { "data-preview-field-path": `${sectionPath}.specsTitle`, children: specsTitle }) }), (0, jsx_runtime_1.jsx)("button", { type: "button", onClick: () => setActiveTab('shipping'), className: `text-sm font-bold tracking-wide transition-colors ${activeTab === 'shipping' ? 'text-lime-400' : 'text-slate-400 hover:text-slate-200'}`, children: (0, jsx_runtime_1.jsx)("span", { "data-preview-field-path": `${sectionPath}.shippingTitle`, children: shippingTitle }) })] }), activeTab === 'specs' ? ((0, jsx_runtime_1.jsx)("div", { className: "space-y-3", children: product.specs && product.specs.length > 0 ? (product.specs.map((spec, i) => ((0, jsx_runtime_1.jsxs)("div", { className: "flex justify-between text-xs py-1 border-b border-slate-900", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-slate-400 font-medium", children: spec.label }), (0, jsx_runtime_1.jsx)("span", { className: "text-slate-200 font-semibold", children: spec.value })] }, i)))) : ((0, jsx_runtime_1.jsxs)("div", { className: "text-xs text-slate-400 space-y-2", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex justify-between py-1 border-b border-slate-800/50", children: [(0, jsx_runtime_1.jsx)("span", { children: "Upper Material" }), (0, jsx_runtime_1.jsx)("span", { className: "text-slate-200 font-semibold", children: "Engineered breathable mesh" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex justify-between py-1 border-b border-slate-800/50", children: [(0, jsx_runtime_1.jsx)("span", { children: "Midsole Technology" }), (0, jsx_runtime_1.jsx)("span", { className: "text-slate-200 font-semibold", children: "Dual-density responsive foam" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex justify-between py-1 border-b border-slate-800/50", children: [(0, jsx_runtime_1.jsx)("span", { children: "Outsole Grip" }), (0, jsx_runtime_1.jsx)("span", { className: "text-slate-200 font-semibold", children: "High-abrasion tactical rubber" })] })] })) })) : ((0, jsx_runtime_1.jsxs)("div", { className: "text-xs text-slate-300 space-y-3 leading-relaxed", children: [(0, jsx_runtime_1.jsx)("p", { "data-preview-field-path": `${sectionPath}.shippingSummary`, children: shippingSummary }), (0, jsx_runtime_1.jsx)("p", { "data-preview-field-path": `${sectionPath}.shippingReturns`, className: "text-slate-400", children: shippingReturns })] }))] })] }) })] }) }));
|
|
52
52
|
}
|
|
@@ -38,7 +38,7 @@ function EditableProductGrid({ sectionPath = 'home', title = 'Featured Collectio
|
|
|
38
38
|
return ((0, jsx_runtime_1.jsx)("button", { type: "button", onClick: () => setActiveCategory(cat), className: `px-4 py-2 rounded-xl text-xs font-bold transition-all duration-200 ${isActive
|
|
39
39
|
? 'bg-white text-slate-950 shadow-md scale-102 font-extrabold'
|
|
40
40
|
: 'bg-slate-900/60 text-slate-400 hover:text-white border border-slate-800/80 hover:bg-slate-850'}`, children: cat }, cat));
|
|
41
|
-
}) }))] }), filteredProducts.length > 0 ? ((0, jsx_runtime_1.jsx)("div", { className: `grid ${gridColClasses} gap-6 sm:gap-8`, children: filteredProducts.map((product, idx) => {
|
|
41
|
+
}) }))] }), filteredProducts.length > 0 ? ((0, jsx_runtime_1.jsx)("div", { className: `deneb-product-grid grid ${gridColClasses} gap-6 sm:gap-8`, children: filteredProducts.map((product, idx) => {
|
|
42
42
|
const itemPath = `${sectionPath}.${cardPrefix}${idx + 1}`;
|
|
43
43
|
return ((0, jsx_runtime_1.jsxs)("div", { className: "relative group", children: [(0, jsx_runtime_1.jsx)(EditableProductCard_1.EditableProductCard, { itemPath: itemPath, product: product, cardVariant: cardVariant, className: "h-full" }), onQuickView && ((0, jsx_runtime_1.jsx)("div", { className: "absolute top-4 right-4 z-20 opacity-0 group-hover:opacity-100 transition-opacity duration-200", children: (0, jsx_runtime_1.jsx)("button", { type: "button", onClick: () => onQuickView(product, itemPath), className: "p-2.5 rounded-xl bg-slate-950/80 backdrop-blur-md text-white hover:bg-lime-400 hover:text-slate-950 shadow-lg transition-all active:scale-95", title: "Quick View", "aria-label": `Quick View ${product.name || product.title}`, children: (0, jsx_runtime_1.jsxs)("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: [(0, jsx_runtime_1.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 12a3 3 0 11-6 0 3 3 0 016 0z" }), (0, jsx_runtime_1.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" })] }) }) }))] }, product.id || idx));
|
|
44
44
|
}) })) : (
|
package/dist/EditableSection.js
CHANGED
|
@@ -2,15 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.EditableSection = EditableSection;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
sm: '2.5rem 0',
|
|
9
|
-
md: '4rem 0',
|
|
10
|
-
lg: '6rem 0',
|
|
11
|
-
xl: '8rem 0',
|
|
12
|
-
'2xl': '10rem 0',
|
|
13
|
-
};
|
|
5
|
+
const useComponentStyle_1 = require("./hooks/useComponentStyle");
|
|
6
|
+
const responsive_1 = require("./utils/responsive");
|
|
7
|
+
const SECTION_PADDING_MAP = responsive_1.RESPONSIVE_SECTION_PADDING;
|
|
14
8
|
/**
|
|
15
9
|
* EditableSection standardizes section spacing and automatically applies the required
|
|
16
10
|
* `data-design-section` marker for 100% fivora contract compliance.
|
|
@@ -22,13 +16,16 @@ function EditableSection({ as: Component = 'section', name, padding = 'lg', bg,
|
|
|
22
16
|
: typeof border === 'string'
|
|
23
17
|
? border
|
|
24
18
|
: undefined;
|
|
19
|
+
const stylePath = `${name}.section`;
|
|
20
|
+
const { cssVars: styleVars } = (0, useComponentStyle_1.useComponentStyle)(stylePath, 'section');
|
|
25
21
|
const sectionStyle = {
|
|
26
22
|
...(resolvedPadding ? { padding: resolvedPadding } : {}),
|
|
27
23
|
...(bg ? { background: bg } : {}),
|
|
28
24
|
...(color ? { color } : {}),
|
|
29
25
|
...(maxWidth !== undefined ? { maxWidth, marginLeft: 'auto', marginRight: 'auto' } : {}),
|
|
30
26
|
...(resolvedBorder ? { borderBottom: resolvedBorder } : {}),
|
|
27
|
+
...styleVars,
|
|
31
28
|
...style,
|
|
32
29
|
};
|
|
33
|
-
return ((0, jsx_runtime_1.jsx)(Component, { "data-design-section": name, className: `editable-section ${className}`.trim(), style: sectionStyle, ...props, children: children }));
|
|
30
|
+
return ((0, jsx_runtime_1.jsx)(Component, { "data-design-section": name, "data-preview-style-target": stylePath, "data-preview-style-type": "section", className: `deneb-section editable-section ${className}`.trim(), style: sectionStyle, ...props, children: children }));
|
|
34
31
|
}
|
package/dist/EditableText.d.ts
CHANGED
|
@@ -81,7 +81,7 @@ export interface EditableTextProps extends React.HTMLAttributes<HTMLElement> {
|
|
|
81
81
|
* EditableText provides full typography controls (color, size, weight, line-height, alignment, transform, variants)
|
|
82
82
|
* alongside strict Fivora visual editing bindings.
|
|
83
83
|
*/
|
|
84
|
-
export declare function EditableText({ id, 'data-preview-field-path': previewFieldPath, defaultValue, placeholder, children, as: ComponentOverride, variant, color, size, weight, lineHeight, align, transform, letterSpacing, fontFamily, style, ...props }: EditableTextProps): React.JSX.Element;
|
|
84
|
+
export declare function EditableText({ id, 'data-preview-field-path': previewFieldPath, defaultValue, placeholder, children, as: ComponentOverride, variant, color, size, weight, lineHeight, align, transform, letterSpacing, fontFamily, style, className, ...props }: EditableTextProps): React.JSX.Element;
|
|
85
85
|
export interface EditableHeadingProps extends Omit<EditableTextProps, 'variant'> {
|
|
86
86
|
level?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
87
87
|
}
|
package/dist/EditableText.js
CHANGED
|
@@ -10,7 +10,7 @@ exports.EditableQuote = EditableQuote;
|
|
|
10
10
|
exports.EditableLink = EditableLink;
|
|
11
11
|
exports.EditableButton = EditableButton;
|
|
12
12
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
13
|
-
const
|
|
13
|
+
const useComponentStyle_1 = require("./hooks/useComponentStyle");
|
|
14
14
|
exports.SIZE_MAP = {
|
|
15
15
|
xs: '0.75rem',
|
|
16
16
|
sm: '0.875rem',
|
|
@@ -106,7 +106,7 @@ function toCssUnit(value) {
|
|
|
106
106
|
* EditableText provides full typography controls (color, size, weight, line-height, alignment, transform, variants)
|
|
107
107
|
* alongside strict Fivora visual editing bindings.
|
|
108
108
|
*/
|
|
109
|
-
function EditableText({ id, 'data-preview-field-path': previewFieldPath, defaultValue, placeholder, children, as: ComponentOverride, variant, color, size, weight, lineHeight, align, transform, letterSpacing, fontFamily, style, ...props }) {
|
|
109
|
+
function EditableText({ id, 'data-preview-field-path': previewFieldPath, defaultValue, placeholder, children, as: ComponentOverride, variant, color, size, weight, lineHeight, align, transform, letterSpacing, fontFamily, style, className = '', ...props }) {
|
|
110
110
|
const path = previewFieldPath || id;
|
|
111
111
|
const rawContent = children !== undefined ? children : defaultValue;
|
|
112
112
|
const isContentEmpty = rawContent === undefined ||
|
|
@@ -114,7 +114,7 @@ function EditableText({ id, 'data-preview-field-path': previewFieldPath, default
|
|
|
114
114
|
(typeof rawContent === 'string' && rawContent.trim() === '');
|
|
115
115
|
const isPlaceholderActive = isContentEmpty && Boolean(placeholder);
|
|
116
116
|
const displayContent = isPlaceholderActive ? placeholder : rawContent;
|
|
117
|
-
const
|
|
117
|
+
const { cssVars: styleVars } = (0, useComponentStyle_1.useComponentStyle)(path, 'text');
|
|
118
118
|
const variantDefaults = variant ? exports.VARIANT_DEFAULTS[variant] : undefined;
|
|
119
119
|
const Component = ComponentOverride || variantDefaults?.as || 'span';
|
|
120
120
|
const effectiveColor = color || variantDefaults?.color;
|
|
@@ -134,24 +134,6 @@ function EditableText({ id, 'data-preview-field-path': previewFieldPath, default
|
|
|
134
134
|
const resolvedFontFamily = effectiveFontFamily
|
|
135
135
|
? (exports.FONT_FAMILY_MAP[effectiveFontFamily] || effectiveFontFamily)
|
|
136
136
|
: undefined;
|
|
137
|
-
// Dynamic visual editor overrides
|
|
138
|
-
const dynamicColor = dynamicStyle?.color
|
|
139
|
-
? (exports.COLOR_MAP[String(dynamicStyle.color)] || String(dynamicStyle.color))
|
|
140
|
-
: undefined;
|
|
141
|
-
const dynamicSize = dynamicStyle?.fontSize !== undefined && dynamicStyle?.fontSize !== ''
|
|
142
|
-
? (exports.SIZE_MAP[String(dynamicStyle.fontSize)] || toCssUnit(dynamicStyle.fontSize))
|
|
143
|
-
: undefined;
|
|
144
|
-
const dynamicLineHeight = dynamicStyle?.lineHeight !== undefined && dynamicStyle?.lineHeight !== ''
|
|
145
|
-
? (exports.LINE_HEIGHT_MAP[String(dynamicStyle.lineHeight)] || dynamicStyle.lineHeight)
|
|
146
|
-
: undefined;
|
|
147
|
-
const dynamicFontFamily = dynamicStyle?.fontFamily
|
|
148
|
-
? (exports.FONT_FAMILY_MAP[String(dynamicStyle.fontFamily)] || String(dynamicStyle.fontFamily))
|
|
149
|
-
: undefined;
|
|
150
|
-
const dynamicAlign = dynamicStyle?.textAlign;
|
|
151
|
-
const dynamicMarginTop = toCssUnit(dynamicStyle?.spacingTop);
|
|
152
|
-
const dynamicMarginBottom = toCssUnit(dynamicStyle?.spacingBottom);
|
|
153
|
-
const dynamicMarginLeft = toCssUnit(dynamicStyle?.spacingLeft);
|
|
154
|
-
const dynamicMarginRight = toCssUnit(dynamicStyle?.spacingRight);
|
|
155
137
|
const typographyStyle = {
|
|
156
138
|
// Minimum dimensions ensure empty/placeholder elements never collapse to 0x0 and remain 100% clickable in Fivora
|
|
157
139
|
minHeight: '1.2em',
|
|
@@ -166,19 +148,10 @@ function EditableText({ id, 'data-preview-field-path': previewFieldPath, default
|
|
|
166
148
|
...(effectiveTransform ? { textTransform: effectiveTransform } : {}),
|
|
167
149
|
...(resolvedLetterSpacing ? { letterSpacing: resolvedLetterSpacing } : {}),
|
|
168
150
|
...(resolvedFontFamily ? { fontFamily: resolvedFontFamily } : {}),
|
|
151
|
+
...styleVars,
|
|
169
152
|
...style,
|
|
170
|
-
// Visual editor overrides take highest precedence:
|
|
171
|
-
...(dynamicColor ? { color: dynamicColor } : {}),
|
|
172
|
-
...(dynamicSize ? { fontSize: dynamicSize } : {}),
|
|
173
|
-
...(dynamicLineHeight ? { lineHeight: dynamicLineHeight } : {}),
|
|
174
|
-
...(dynamicAlign ? { textAlign: dynamicAlign } : {}),
|
|
175
|
-
...(dynamicFontFamily ? { fontFamily: dynamicFontFamily } : {}),
|
|
176
|
-
...(dynamicMarginTop !== undefined ? { marginTop: dynamicMarginTop } : {}),
|
|
177
|
-
...(dynamicMarginBottom !== undefined ? { marginBottom: dynamicMarginBottom } : {}),
|
|
178
|
-
...(dynamicMarginLeft !== undefined ? { marginLeft: dynamicMarginLeft } : {}),
|
|
179
|
-
...(dynamicMarginRight !== undefined ? { marginRight: dynamicMarginRight } : {}),
|
|
180
153
|
};
|
|
181
|
-
return ((0, jsx_runtime_1.jsx)(Component, { "data-preview-field-path": path, "data-preview-placeholder": isPlaceholderActive ? 'true' : undefined, style: typographyStyle, ...props, children: displayContent }));
|
|
154
|
+
return ((0, jsx_runtime_1.jsx)(Component, { "data-preview-field-path": path, "data-preview-style-target": path, "data-preview-style-type": "text", "data-preview-placeholder": isPlaceholderActive ? 'true' : undefined, className: `deneb-text ${className}`.trim(), style: typographyStyle, ...props, children: displayContent }));
|
|
182
155
|
}
|
|
183
156
|
function EditableHeading({ level = 2, as, ...props }) {
|
|
184
157
|
const variant = `h${level}`;
|
|
@@ -270,6 +243,7 @@ function EditableLink({ id, 'data-preview-field-path': previewFieldPath, targetP
|
|
|
270
243
|
function EditableButton({ id, 'data-preview-field-path': previewFieldPath, defaultValue, targetPage, btnVariant = 'primary', size = 'md', children, className = '', style, ...props }) {
|
|
271
244
|
const path = previewFieldPath || id;
|
|
272
245
|
const content = children !== undefined ? children : defaultValue;
|
|
246
|
+
const { cssVars: styleVars } = (0, useComponentStyle_1.useComponentStyle)(path, 'button');
|
|
273
247
|
const sizeStyles = {
|
|
274
248
|
sm: { padding: '0.375rem 0.875rem', fontSize: '0.875rem', borderRadius: '6px' },
|
|
275
249
|
md: { padding: '0.625rem 1.25rem', fontSize: '1rem', borderRadius: '8px' },
|
|
@@ -319,9 +293,10 @@ function EditableButton({ id, 'data-preview-field-path': previewFieldPath, defau
|
|
|
319
293
|
transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)',
|
|
320
294
|
...sizeStyles[size],
|
|
321
295
|
...variantStyles[btnVariant],
|
|
296
|
+
...styleVars,
|
|
322
297
|
...style,
|
|
323
298
|
};
|
|
324
|
-
const buttonEl = ((0, jsx_runtime_1.jsx)("button", { style: baseStyle, className: `editable-btn ${className}`.trim(), ...props, children: path ? ((0, jsx_runtime_1.jsx)("span", { "data-preview-field-path": path, children: content })) : (content) }));
|
|
299
|
+
const buttonEl = ((0, jsx_runtime_1.jsx)("button", { "data-preview-style-target": path, "data-preview-style-type": "button", style: baseStyle, className: `deneb-btn editable-btn ${className}`.trim(), ...props, children: path ? ((0, jsx_runtime_1.jsx)("span", { "data-preview-field-path": path, children: content })) : (content) }));
|
|
325
300
|
if (targetPage) {
|
|
326
301
|
return (0, jsx_runtime_1.jsx)("span", { "data-target-page": targetPage, children: buttonEl });
|
|
327
302
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Injects viewport-aware CSS for all DENEB UI components.
|
|
4
|
+
* Works without Tailwind — every template gets mobile / tablet / desktop behavior
|
|
5
|
+
* when this is mounted once (included automatically by ThemeStyles).
|
|
6
|
+
*/
|
|
7
|
+
export declare function ResponsiveBaseStyles(): React.JSX.Element;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ResponsiveBaseStyles = ResponsiveBaseStyles;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
/**
|
|
6
|
+
* Injects viewport-aware CSS for all DENEB UI components.
|
|
7
|
+
* Works without Tailwind — every template gets mobile / tablet / desktop behavior
|
|
8
|
+
* when this is mounted once (included automatically by ThemeStyles).
|
|
9
|
+
*/
|
|
10
|
+
function ResponsiveBaseStyles() {
|
|
11
|
+
const css = `
|
|
12
|
+
/* ── Breakpoints: mobile <768 | tablet 768–1023 | desktop ≥1024 ── */
|
|
13
|
+
|
|
14
|
+
/* Navbar: hide desktop nav + compact header on mobile */
|
|
15
|
+
.deneb-desktop-nav { display: none !important; }
|
|
16
|
+
.deneb-mobile-toggle { display: flex !important; }
|
|
17
|
+
.deneb-header-cta { display: none !important; }
|
|
18
|
+
|
|
19
|
+
@media (min-width: 768px) {
|
|
20
|
+
.deneb-desktop-nav { display: flex !important; }
|
|
21
|
+
.deneb-mobile-toggle { display: none !important; }
|
|
22
|
+
.deneb-header-cta { display: inline-flex !important; }
|
|
23
|
+
.deneb-mobile-drawer { display: none !important; }
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@media (max-width: 767px) {
|
|
27
|
+
.deneb-site-title { font-size: 1rem !important; max-width: 9rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
28
|
+
.deneb-logo { height: 32px !important; max-width: 100px !important; }
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/* Responsive grid columns via data attributes */
|
|
32
|
+
.editable-grid[data-deneb-responsive-cols="true"] {
|
|
33
|
+
grid-template-columns: repeat(var(--deneb-cols, 1), minmax(0, 1fr));
|
|
34
|
+
}
|
|
35
|
+
@media (min-width: 640px) {
|
|
36
|
+
.editable-grid[data-deneb-responsive-cols="true"] {
|
|
37
|
+
grid-template-columns: repeat(var(--deneb-cols-tablet, 2), minmax(0, 1fr));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
@media (min-width: 1024px) {
|
|
41
|
+
.editable-grid[data-deneb-responsive-cols="true"] {
|
|
42
|
+
grid-template-columns: repeat(var(--deneb-cols-desktop, 3), minmax(0, 1fr));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* Horizontal product card stacks on mobile */
|
|
47
|
+
.editable-product-card.is-horizontal { flex-direction: column !important; }
|
|
48
|
+
.editable-product-card.is-horizontal .deneb-product-card-media { width: 100% !important; }
|
|
49
|
+
@media (min-width: 640px) {
|
|
50
|
+
.editable-product-card.is-horizontal { flex-direction: row !important; align-items: center !important; }
|
|
51
|
+
.editable-product-card.is-horizontal .deneb-product-card-media { width: 38% !important; }
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* Card padding scales down on small screens */
|
|
55
|
+
.editable-pricing-card,
|
|
56
|
+
.editable-testimonial-card {
|
|
57
|
+
padding: clamp(1.25rem, 4vw, 2.5rem) clamp(1rem, 3vw, 2rem) !important;
|
|
58
|
+
}
|
|
59
|
+
.editable-pricing-card .deneb-pricing-amount {
|
|
60
|
+
font-size: clamp(2rem, 6vw, 2.75rem) !important;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/* Dialog: tighter padding on phones */
|
|
64
|
+
.deneb-dialog-portal { padding: clamp(0.5rem, 3vw, 1rem) !important; }
|
|
65
|
+
.deneb-dialog-content { padding: clamp(1.25rem, 4vw, 2rem) !important; border-radius: clamp(12px, 3vw, 20px) !important; }
|
|
66
|
+
.deneb-dialog-content h2 { font-size: clamp(1.1rem, 4vw, 1.35rem) !important; }
|
|
67
|
+
|
|
68
|
+
/* Floating contact: prevent popup overflow */
|
|
69
|
+
.deneb-contact-popup {
|
|
70
|
+
width: min(18rem, calc(100vw - 2rem)) !important;
|
|
71
|
+
max-width: calc(100vw - 2rem) !important;
|
|
72
|
+
}
|
|
73
|
+
@media (max-width: 479px) {
|
|
74
|
+
.deneb-floating-contact { bottom: 1rem !important; right: 1rem !important; left: auto !important; }
|
|
75
|
+
.deneb-floating-contact.deneb-floating-left { left: 1rem !important; right: auto !important; }
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* Filter sidebar: collapsible on mobile, always visible on tablet+ */
|
|
79
|
+
.deneb-filter-mobile-toggle { display: flex; width: 100%; align-items: center; justify-content: space-between; }
|
|
80
|
+
@media (min-width: 768px) {
|
|
81
|
+
.deneb-filter-mobile-toggle { display: none !important; }
|
|
82
|
+
.deneb-filter-sidebar-panel { display: block !important; }
|
|
83
|
+
}
|
|
84
|
+
@media (max-width: 767px) {
|
|
85
|
+
.deneb-filter-sidebar-panel { display: none; }
|
|
86
|
+
.deneb-filter-sidebar-panel.is-open { display: block; }
|
|
87
|
+
.deneb-filter-sidebar .deneb-filter-size-grid { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/* Contact actions: stack on mobile when row layout */
|
|
91
|
+
@media (max-width: 639px) {
|
|
92
|
+
.deneb-contact-actions.deneb-layout-row {
|
|
93
|
+
flex-direction: column !important;
|
|
94
|
+
align-items: stretch !important;
|
|
95
|
+
}
|
|
96
|
+
.deneb-contact-actions.deneb-layout-row > * { width: 100%; }
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/* Contact form title */
|
|
100
|
+
.deneb-contact-form-title { font-size: clamp(1.25rem, 4vw, 1.75rem) !important; }
|
|
101
|
+
|
|
102
|
+
/* Product detail: size grid on xs */
|
|
103
|
+
@media (max-width: 479px) {
|
|
104
|
+
.deneb-product-detail-sizes { grid-template-columns: repeat(3, minmax(0, 1fr)) !important; }
|
|
105
|
+
.deneb-product-detail-gallery { max-height: 420px !important; }
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/* Footer / trust badges / product grid fallbacks when Tailwind is absent */
|
|
109
|
+
@media (max-width: 639px) {
|
|
110
|
+
.deneb-footer-grid { grid-template-columns: 1fr !important; }
|
|
111
|
+
.deneb-trust-grid { grid-template-columns: 1fr !important; }
|
|
112
|
+
.deneb-product-grid { grid-template-columns: 1fr !important; }
|
|
113
|
+
}
|
|
114
|
+
@media (min-width: 640px) and (max-width: 1023px) {
|
|
115
|
+
.deneb-footer-grid { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
|
|
116
|
+
.deneb-trust-grid { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
|
|
117
|
+
.deneb-product-grid { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
|
|
118
|
+
}
|
|
119
|
+
@media (min-width: 1024px) {
|
|
120
|
+
.deneb-footer-grid { grid-template-columns: repeat(4, minmax(0, 1fr)) !important; }
|
|
121
|
+
.deneb-trust-grid { grid-template-columns: repeat(4, minmax(0, 1fr)) !important; }
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/* Sticky mobile bar: hide on desktop */
|
|
125
|
+
.deneb-sticky-mobile-bar { display: flex; }
|
|
126
|
+
@media (min-width: 1024px) {
|
|
127
|
+
.deneb-sticky-mobile-bar { display: none !important; }
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/* Dialog animations */
|
|
131
|
+
@keyframes deneb-fade-in { from { opacity: 0; } to { opacity: 1; } }
|
|
132
|
+
@keyframes deneb-zoom-in { from { opacity: 0; transform: scale(0.96); } to { opacity: 1; transform: scale(1); } }
|
|
133
|
+
@keyframes deneb-pop { from { opacity: 0; transform: translateY(8px) scale(0.96); } to { opacity: 1; transform: translateY(0) scale(1); } }
|
|
134
|
+
`;
|
|
135
|
+
return (0, jsx_runtime_1.jsx)("style", { "data-deneb-responsive": "true", dangerouslySetInnerHTML: { __html: css } });
|
|
136
|
+
}
|
|
@@ -9,6 +9,7 @@ export declare const DENEB_PREVIEW_FOCUS_MESSAGE = "DENEB_PREVIEW_FOCUS_PAGE";
|
|
|
9
9
|
export declare const PREVIEW_FOCUS_MESSAGE = "FIVORA_PREVIEW_FOCUS_PAGE";
|
|
10
10
|
export declare const LEGACY_PREVIEW_FOCUS_MESSAGE: string;
|
|
11
11
|
export declare const PREVIEW_FIELD_ATTRIBUTE = "data-preview-field-path";
|
|
12
|
+
export { STYLE_PATCH_MESSAGE, DENEB_STYLE_PATCH_MESSAGE } from '@deneb-ui/core';
|
|
12
13
|
export type GenericRecord = Record<string, unknown>;
|
|
13
14
|
export type SiteData = {
|
|
14
15
|
project?: {
|
|
@@ -25,6 +26,7 @@ export type SiteData = {
|
|
|
25
26
|
requiredPages?: string[] | null;
|
|
26
27
|
} | null;
|
|
27
28
|
content?: GenericRecord | null;
|
|
29
|
+
styles?: GenericRecord | null;
|
|
28
30
|
[key: string]: unknown;
|
|
29
31
|
};
|
|
30
32
|
export declare const SiteDataContext: React.Context<SiteData>;
|
package/dist/SiteDataProvider.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
'use client';
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.DenebDataContext = exports.useDenebData = exports.DenebDataProvider = exports.SiteDataContext = 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.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;
|
|
5
5
|
exports.isRecord = isRecord;
|
|
6
6
|
exports.mergeSiteData = mergeSiteData;
|
|
7
7
|
exports.normalizeOrigin = normalizeOrigin;
|
|
@@ -17,6 +17,10 @@ exports.getFieldStyle = getFieldStyle;
|
|
|
17
17
|
exports.useFieldStyle = useFieldStyle;
|
|
18
18
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
19
19
|
const react_1 = require("react");
|
|
20
|
+
const core_1 = require("@deneb-ui/core");
|
|
21
|
+
const DenebComponentStyles_1 = require("./DenebComponentStyles");
|
|
22
|
+
const FontLoader_1 = require("./fonts/FontLoader");
|
|
23
|
+
const ResponsiveBaseStyles_1 = require("./ResponsiveBaseStyles");
|
|
20
24
|
exports.DENEB_PREVIEW_DATA_MESSAGE = 'DENEB_PREVIEW_SITE_DATA';
|
|
21
25
|
exports.PREVIEW_DATA_MESSAGE = 'FIVORA_PREVIEW_SITE_DATA';
|
|
22
26
|
const PREVIOUS_PREVIEW_PREFIX = `${['MARKET', 'PLACE'].join('')}_PREVIEW_`;
|
|
@@ -30,6 +34,9 @@ exports.DENEB_PREVIEW_FOCUS_MESSAGE = 'DENEB_PREVIEW_FOCUS_PAGE';
|
|
|
30
34
|
exports.PREVIEW_FOCUS_MESSAGE = 'FIVORA_PREVIEW_FOCUS_PAGE';
|
|
31
35
|
exports.LEGACY_PREVIEW_FOCUS_MESSAGE = previousPreviewMessage('FOCUS_PAGE');
|
|
32
36
|
exports.PREVIEW_FIELD_ATTRIBUTE = 'data-preview-field-path';
|
|
37
|
+
var core_2 = require("@deneb-ui/core");
|
|
38
|
+
Object.defineProperty(exports, "STYLE_PATCH_MESSAGE", { enumerable: true, get: function () { return core_2.STYLE_PATCH_MESSAGE; } });
|
|
39
|
+
Object.defineProperty(exports, "DENEB_STYLE_PATCH_MESSAGE", { enumerable: true, get: function () { return core_2.DENEB_STYLE_PATCH_MESSAGE; } });
|
|
33
40
|
const PARENT_ORIGIN_KEY = '__FIVORA_PREVIEW_PARENT_ORIGIN__';
|
|
34
41
|
const LEGACY_PARENT_ORIGIN_KEY = previousPreviewStorageKey('PARENT_ORIGIN');
|
|
35
42
|
const SITE_DATA_CACHE_KEY = '__FIVORA_PREVIEW_SITE_DATA_CACHE__';
|
|
@@ -50,7 +57,7 @@ function mergeSiteData(current, incoming) {
|
|
|
50
57
|
for (const key of Object.keys(incoming)) {
|
|
51
58
|
// Parent preview always sends complete content/media snapshots. Replacing
|
|
52
59
|
// them wholesale avoids deep-cloning large collections on every keystroke.
|
|
53
|
-
if (key === 'content' || key === 'media') {
|
|
60
|
+
if (key === 'content' || key === 'media' || key === 'styles') {
|
|
54
61
|
next[key] = incoming[key];
|
|
55
62
|
continue;
|
|
56
63
|
}
|
|
@@ -200,7 +207,9 @@ function SiteDataProvider({ children, initialSiteData, fallbackSiteData, }) {
|
|
|
200
207
|
const isFocus = event.data.type === exports.DENEB_PREVIEW_FOCUS_MESSAGE ||
|
|
201
208
|
event.data.type === exports.PREVIEW_FOCUS_MESSAGE ||
|
|
202
209
|
event.data.type === exports.LEGACY_PREVIEW_FOCUS_MESSAGE;
|
|
203
|
-
|
|
210
|
+
const isStylePatch = event.data.type === core_1.STYLE_PATCH_MESSAGE ||
|
|
211
|
+
event.data.type === core_1.DENEB_STYLE_PATCH_MESSAGE;
|
|
212
|
+
if (!isData && !isFocus && !isStylePatch) {
|
|
204
213
|
return;
|
|
205
214
|
}
|
|
206
215
|
// Pin the first concrete parent origin when referrer was suppressed.
|
|
@@ -225,6 +234,15 @@ function SiteDataProvider({ children, initialSiteData, fallbackSiteData, }) {
|
|
|
225
234
|
applyIncomingSiteData(event.data.siteData);
|
|
226
235
|
return;
|
|
227
236
|
}
|
|
237
|
+
if (isStylePatch) {
|
|
238
|
+
const targetPath = typeof event.data.targetPath === 'string' ? event.data.targetPath : '';
|
|
239
|
+
const styleType = typeof event.data.styleType === 'string' ? event.data.styleType : 'text';
|
|
240
|
+
const properties = isRecord(event.data.properties) ? event.data.properties : {};
|
|
241
|
+
if (targetPath) {
|
|
242
|
+
(0, core_1.patchStyleByPath)(targetPath, styleType, properties);
|
|
243
|
+
}
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
228
246
|
if (isFocus) {
|
|
229
247
|
const fieldPath = typeof event.data.fieldPath === 'string' ? event.data.fieldPath : '';
|
|
230
248
|
if (!fieldPath)
|
|
@@ -248,7 +266,7 @@ function SiteDataProvider({ children, initialSiteData, fallbackSiteData, }) {
|
|
|
248
266
|
return () => window.removeEventListener('message', onMessage);
|
|
249
267
|
}, []);
|
|
250
268
|
const value = (0, react_1.useMemo)(() => siteData, [siteData]);
|
|
251
|
-
return ((0, jsx_runtime_1.
|
|
269
|
+
return ((0, jsx_runtime_1.jsxs)(exports.SiteDataContext.Provider, { value: value, children: [(0, jsx_runtime_1.jsx)(FontLoader_1.FontLoader, {}), (0, jsx_runtime_1.jsx)(ResponsiveBaseStyles_1.ResponsiveBaseStyles, {}), (0, jsx_runtime_1.jsx)(DenebComponentStyles_1.DenebComponentStyles, {}), children] }));
|
|
252
270
|
}
|
|
253
271
|
function useSiteData() {
|
|
254
272
|
return (0, react_1.useContext)(exports.SiteDataContext);
|
package/dist/StickyMobileBar.js
CHANGED
|
@@ -70,7 +70,7 @@ function StickyMobileBar({ fieldPath, actions, showOnDesktop = false, className
|
|
|
70
70
|
return ((0, jsx_runtime_1.jsx)("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: (0, jsx_runtime_1.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M13 10V3L4 14h7v7l9-11h-7z" }) }));
|
|
71
71
|
}
|
|
72
72
|
};
|
|
73
|
-
return ((0, jsx_runtime_1.jsx)("aside", { className: `fixed bottom-0 left-0 right-0 z-50 p-2 sm:p-3 transition-transform duration-300 ${showOnDesktop ? 'block' : 'lg:hidden'} ${className}`, "data-preview-field-path": fieldPath, style: {
|
|
73
|
+
return ((0, jsx_runtime_1.jsx)("aside", { className: `deneb-sticky-mobile-bar fixed bottom-0 left-0 right-0 z-50 p-2 sm:p-3 transition-transform duration-300 ${showOnDesktop ? 'block' : 'lg:hidden'} ${className}`, "data-preview-field-path": fieldPath, style: {
|
|
74
74
|
backgroundColor: 'rgba(255, 255, 255, 0.92)',
|
|
75
75
|
backdropFilter: 'blur(12px)',
|
|
76
76
|
WebkitBackdropFilter: 'blur(12px)',
|
package/dist/ThemeStyles.js
CHANGED
|
@@ -5,6 +5,7 @@ exports.getCategoryTheme = getCategoryTheme;
|
|
|
5
5
|
exports.getThemeCssProperties = getThemeCssProperties;
|
|
6
6
|
exports.ThemeStyles = ThemeStyles;
|
|
7
7
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const ResponsiveBaseStyles_1 = require("./ResponsiveBaseStyles");
|
|
8
9
|
/**
|
|
9
10
|
* Pre-configured, high-converting theme presets tailored for different business categories.
|
|
10
11
|
* Allows developers and AI agents to instantly generate distinct designs without copy-pasting styles.
|
|
@@ -177,5 +178,5 @@ function ThemeStyles({ theme, defaultPrimary = '#2563eb', defaultSecondary = '#0
|
|
|
177
178
|
${cssLines}
|
|
178
179
|
}
|
|
179
180
|
`;
|
|
180
|
-
return (0, jsx_runtime_1.jsx)("style", { dangerouslySetInnerHTML: { __html: css } });
|
|
181
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(ResponsiveBaseStyles_1.ResponsiveBaseStyles, {}), (0, jsx_runtime_1.jsx)("style", { dangerouslySetInnerHTML: { __html: css } })] }));
|
|
181
182
|
}
|
package/dist/TrustBadges.js
CHANGED
|
@@ -60,7 +60,7 @@ function TrustBadges({ fieldPath = 'content.trustBadges', title, subtitle, badge
|
|
|
60
60
|
};
|
|
61
61
|
return ((0, jsx_runtime_1.jsxs)("section", { className: `w-full py-8 my-4 ${className}`, "data-preview-field-path": fieldPath, style: style, children: [(title || subtitle) && ((0, jsx_runtime_1.jsxs)("div", { className: "text-center mb-8", children: [title && ((0, jsx_runtime_1.jsx)("h3", { className: "text-xl sm:text-2xl font-bold tracking-tight text-slate-900", children: title })), subtitle && ((0, jsx_runtime_1.jsx)("p", { className: "mt-1 text-sm text-slate-600 max-w-xl mx-auto", children: subtitle }))] })), (0, jsx_runtime_1.jsx)("div", { className: variant === 'inline'
|
|
62
62
|
? 'flex flex-wrap items-center justify-around gap-6'
|
|
63
|
-
: 'grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 sm:gap-6', children: badges.map((badge) => ((0, jsx_runtime_1.jsxs)("div", { className: `flex items-start gap-4 p-5 rounded-2xl transition-all duration-200 hover:-translate-y-0.5 ${variant === 'cards'
|
|
63
|
+
: 'deneb-trust-grid grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 sm:gap-6', children: badges.map((badge) => ((0, jsx_runtime_1.jsxs)("div", { className: `flex items-start gap-4 p-5 rounded-2xl transition-all duration-200 hover:-translate-y-0.5 ${variant === 'cards'
|
|
64
64
|
? 'bg-white border border-slate-200/80 shadow-sm hover:shadow-md'
|
|
65
65
|
: 'bg-transparent'}`, children: [(0, jsx_runtime_1.jsx)("div", { className: "flex-shrink-0 p-2.5 rounded-xl bg-slate-50 border border-slate-100 flex items-center justify-center", children: renderIcon(badge) }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h4", { className: "text-sm font-semibold text-slate-900 leading-tight", children: badge.title }), (0, jsx_runtime_1.jsx)("p", { className: "mt-1 text-xs text-slate-500 leading-relaxed", children: badge.description })] })] }, badge.id))) })] }));
|
|
66
66
|
}
|
|
@@ -56,7 +56,8 @@ function FloatingContactWidget({ fieldPath = 'contact', defaultPhone, defaultWha
|
|
|
56
56
|
position: 'absolute',
|
|
57
57
|
bottom: '4.25rem',
|
|
58
58
|
[isRight ? 'right' : 'left']: '0',
|
|
59
|
-
width: '18rem',
|
|
59
|
+
width: 'min(18rem, calc(100vw - 2rem))',
|
|
60
|
+
maxWidth: 'calc(100vw - 2rem)',
|
|
60
61
|
backgroundColor: '#ffffff',
|
|
61
62
|
borderRadius: '1rem',
|
|
62
63
|
boxShadow: '0 20px 25px -5px rgba(0, 0, 0, 0.15), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',
|
|
@@ -64,5 +65,5 @@ function FloatingContactWidget({ fieldPath = 'contact', defaultPhone, defaultWha
|
|
|
64
65
|
overflow: 'hidden',
|
|
65
66
|
animation: 'deneb-pop 0.2s cubic-bezier(0.16, 1, 0.3, 1)',
|
|
66
67
|
};
|
|
67
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: `deneb-floating-contact fixed z-50 bottom-6 ${isRight ? 'right-6' : 'left-6'} ${className}`, style: containerStyle, "data-preview-field-path": fieldPath, children: [isOpen && ((0, jsx_runtime_1.jsxs)("div", { className: "deneb-contact-popup absolute bottom-16 bg-white rounded-2xl shadow-2xl border border-slate-200 w-72 overflow-hidden text-slate-800", style: menuStyle, children: [(0, jsx_runtime_1.jsxs)("div", { className: "bg-slate-900 text-white p-4 flex items-center justify-between", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h4", { className: "font-bold text-sm leading-tight text-white", children: storeName }), (0, jsx_runtime_1.jsxs)("p", { className: "text-xs text-emerald-400 font-medium flex items-center gap-1.5 mt-0.5", children: [(0, jsx_runtime_1.jsx)("span", { className: "w-2 h-2 rounded-full bg-emerald-400 animate-pulse" }), "Online & Ready to Help"] })] }), (0, jsx_runtime_1.jsx)("button", { type: "button", onClick: () => setIsOpen(false), className: "text-slate-400 hover:text-white p-1 rounded transition-colors", "aria-label": "Close contact drawer", children: (0, jsx_runtime_1.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", children: [(0, jsx_runtime_1.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), (0, jsx_runtime_1.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "p-3 space-y-2 text-sm bg-slate-50", children: [hasWhatsApp && ((0, jsx_runtime_1.jsxs)("a", { href: (0, urls_1.createWhatsAppUrl)(whatsapp, defaultMessage), target: "_blank", rel: "noopener noreferrer", className: "flex items-center gap-3 p-2.5 rounded-xl bg-white border border-slate-200/80 hover:border-emerald-400 hover:shadow-sm transition-all text-slate-800", "data-preview-field-path": `${fieldPath}.whatsapp`, children: [(0, jsx_runtime_1.jsx)("div", { className: "w-9 h-9 rounded-lg bg-emerald-50 text-emerald-600 flex items-center justify-center flex-shrink-0", children: (0, jsx_runtime_1.jsx)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", children: (0, jsx_runtime_1.jsx)("path", { d: "M12.031 6.172c-3.181 0-5.767 2.586-5.768 5.766-.001 1.298.38 2.27 1.019 3.287l-.582 2.128 2.182-.573c.978.58 1.911.928 3.145.929 3.178 0 5.767-2.587 5.768-5.766.001-3.187-2.575-5.77-5.764-5.771zm3.392 8.244c-.144.405-.837.774-1.17.824-.312.045-.694.062-1.116-.073-.266-.086-.61-.225-1.047-.417-1.854-.814-3.056-2.695-3.15-2.819-.092-.124-.755-.999-.755-1.907 0-.909.479-1.353.649-1.536.17-.183.371-.23.495-.23.124 0 .248.002.355.008.113.006.265-.043.414.316.155.372.531 1.296.577 1.39.046.094.077.204.015.328-.061.124-.092.202-.184.31-.092.108-.195.241-.278.324-.093.093-.19.195-.082.381.109.186.483.797 1.037 1.289.713.633 1.314.829 1.501.922.186.093.295.078.404-.047.11-.124.467-.543.591-.729.124-.186.248-.155.418-.093.17.062 1.082.51 1.268.603.186.093.31.14.356.217.046.077.046.449-.098.854z" }) }) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 min-w-0", children: [(0, jsx_runtime_1.jsx)("div", { className: "font-semibold text-slate-900 text-xs", children: "Chat on WhatsApp" }), (0, jsx_runtime_1.jsx)("div", { className: "text-[11px] text-slate-500 truncate", children: whatsapp })] })] })), hasPhone && ((0, jsx_runtime_1.jsxs)("a", { href: (0, urls_1.createPhoneUrl)(phone), className: "flex items-center gap-3 p-2.5 rounded-xl bg-white border border-slate-200/80 hover:border-blue-400 hover:shadow-sm transition-all text-slate-800", "data-preview-field-path": `${fieldPath}.phone`, children: [(0, jsx_runtime_1.jsx)("div", { className: "w-9 h-9 rounded-lg bg-blue-50 text-blue-600 flex items-center justify-center flex-shrink-0", children: (0, jsx_runtime_1.jsx)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: (0, jsx_runtime_1.jsx)("path", { d: "M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z" }) }) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 min-w-0", children: [(0, jsx_runtime_1.jsx)("div", { className: "font-semibold text-slate-900 text-xs", children: "Direct Call" }), (0, jsx_runtime_1.jsx)("div", { className: "text-[11px] text-slate-500 truncate", children: phone })] })] })), hasEmail && ((0, jsx_runtime_1.jsxs)("a", { href: (0, urls_1.createEmailUrl)(email, `Inquiry: ${storeName}`), className: "flex items-center gap-3 p-2.5 rounded-xl bg-white border border-slate-200/80 hover:border-purple-400 hover:shadow-sm transition-all text-slate-800", "data-preview-field-path": `${fieldPath}.email`, children: [(0, jsx_runtime_1.jsx)("div", { className: "w-9 h-9 rounded-lg bg-purple-50 text-purple-600 flex items-center justify-center flex-shrink-0", children: (0, jsx_runtime_1.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("path", { d: "M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z" }), (0, jsx_runtime_1.jsx)("polyline", { points: "22,6 12,13 2,6" })] }) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 min-w-0", children: [(0, jsx_runtime_1.jsx)("div", { className: "font-semibold text-slate-900 text-xs", children: "Send Email" }), (0, jsx_runtime_1.jsx)("div", { className: "text-[11px] text-slate-500 truncate", children: email })] })] }))] })] })), (0, jsx_runtime_1.jsx)("button", { type: "button", onClick: () => setIsOpen(!isOpen), style: bubbleStyle, className: "deneb-bubble hover:scale-105 active:scale-95 flex items-center justify-center focus:outline-none", "aria-label": "Toggle contact channels", children: isOpen ? ((0, jsx_runtime_1.jsxs)("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), (0, jsx_runtime_1.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] })) : ((0, jsx_runtime_1.jsx)("svg", { width: "28", height: "28", viewBox: "0 0 24 24", fill: "currentColor", children: (0, jsx_runtime_1.jsx)("path", { d: "M12.031 6.172c-3.181 0-5.767 2.586-5.768 5.766-.001 1.298.38 2.27 1.019 3.287l-.582 2.128 2.182-.573c.978.58 1.911.928 3.145.929 3.178 0 5.767-2.587 5.768-5.766.001-3.187-2.575-5.77-5.764-5.771zm3.392 8.244c-.144.405-.837.774-1.17.824-.312.045-.694.062-1.116-.073-.266-.086-.61-.225-1.047-.417-1.854-.814-3.056-2.695-3.15-2.819-.092-.124-.755-.999-.755-1.907 0-.909.479-1.353.649-1.536.17-.183.371-.23.495-.23.124 0 .248.002.355.008.113.006.265-.043.414.316.155.372.531 1.296.577 1.39.046.094.077.204.015.328-.061.124-.092.202-.184.31-.092.108-.195.241-.278.324-.093.093-.19.195-.082.381.109.186.483.797 1.037 1.289.713.633 1.314.829 1.501.922.186.093.295.078.404-.047.11-.124.467-.543.591-.729.124-.186.248-.155.418-.093.17.062 1.082.51 1.268.603.186.093.31.14.356.217.046.077.046.449-.098.854z" }) })) })] }));
|
|
68
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: `deneb-floating-contact fixed z-50 bottom-6 ${isRight ? 'right-6 deneb-floating-right' : 'left-6 deneb-floating-left'} ${className}`, style: containerStyle, "data-preview-field-path": fieldPath, children: [isOpen && ((0, jsx_runtime_1.jsxs)("div", { className: "deneb-contact-popup absolute bottom-16 bg-white rounded-2xl shadow-2xl border border-slate-200 w-72 overflow-hidden text-slate-800", style: menuStyle, children: [(0, jsx_runtime_1.jsxs)("div", { className: "bg-slate-900 text-white p-4 flex items-center justify-between", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h4", { className: "font-bold text-sm leading-tight text-white", children: storeName }), (0, jsx_runtime_1.jsxs)("p", { className: "text-xs text-emerald-400 font-medium flex items-center gap-1.5 mt-0.5", children: [(0, jsx_runtime_1.jsx)("span", { className: "w-2 h-2 rounded-full bg-emerald-400 animate-pulse" }), "Online & Ready to Help"] })] }), (0, jsx_runtime_1.jsx)("button", { type: "button", onClick: () => setIsOpen(false), className: "text-slate-400 hover:text-white p-1 rounded transition-colors", "aria-label": "Close contact drawer", children: (0, jsx_runtime_1.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", children: [(0, jsx_runtime_1.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), (0, jsx_runtime_1.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "p-3 space-y-2 text-sm bg-slate-50", children: [hasWhatsApp && ((0, jsx_runtime_1.jsxs)("a", { href: (0, urls_1.createWhatsAppUrl)(whatsapp, defaultMessage), target: "_blank", rel: "noopener noreferrer", className: "flex items-center gap-3 p-2.5 rounded-xl bg-white border border-slate-200/80 hover:border-emerald-400 hover:shadow-sm transition-all text-slate-800", "data-preview-field-path": `${fieldPath}.whatsapp`, children: [(0, jsx_runtime_1.jsx)("div", { className: "w-9 h-9 rounded-lg bg-emerald-50 text-emerald-600 flex items-center justify-center flex-shrink-0", children: (0, jsx_runtime_1.jsx)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", children: (0, jsx_runtime_1.jsx)("path", { d: "M12.031 6.172c-3.181 0-5.767 2.586-5.768 5.766-.001 1.298.38 2.27 1.019 3.287l-.582 2.128 2.182-.573c.978.58 1.911.928 3.145.929 3.178 0 5.767-2.587 5.768-5.766.001-3.187-2.575-5.77-5.764-5.771zm3.392 8.244c-.144.405-.837.774-1.17.824-.312.045-.694.062-1.116-.073-.266-.086-.61-.225-1.047-.417-1.854-.814-3.056-2.695-3.15-2.819-.092-.124-.755-.999-.755-1.907 0-.909.479-1.353.649-1.536.17-.183.371-.23.495-.23.124 0 .248.002.355.008.113.006.265-.043.414.316.155.372.531 1.296.577 1.39.046.094.077.204.015.328-.061.124-.092.202-.184.31-.092.108-.195.241-.278.324-.093.093-.19.195-.082.381.109.186.483.797 1.037 1.289.713.633 1.314.829 1.501.922.186.093.295.078.404-.047.11-.124.467-.543.591-.729.124-.186.248-.155.418-.093.17.062 1.082.51 1.268.603.186.093.31.14.356.217.046.077.046.449-.098.854z" }) }) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 min-w-0", children: [(0, jsx_runtime_1.jsx)("div", { className: "font-semibold text-slate-900 text-xs", children: "Chat on WhatsApp" }), (0, jsx_runtime_1.jsx)("div", { className: "text-[11px] text-slate-500 truncate", children: whatsapp })] })] })), hasPhone && ((0, jsx_runtime_1.jsxs)("a", { href: (0, urls_1.createPhoneUrl)(phone), className: "flex items-center gap-3 p-2.5 rounded-xl bg-white border border-slate-200/80 hover:border-blue-400 hover:shadow-sm transition-all text-slate-800", "data-preview-field-path": `${fieldPath}.phone`, children: [(0, jsx_runtime_1.jsx)("div", { className: "w-9 h-9 rounded-lg bg-blue-50 text-blue-600 flex items-center justify-center flex-shrink-0", children: (0, jsx_runtime_1.jsx)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: (0, jsx_runtime_1.jsx)("path", { d: "M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z" }) }) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 min-w-0", children: [(0, jsx_runtime_1.jsx)("div", { className: "font-semibold text-slate-900 text-xs", children: "Direct Call" }), (0, jsx_runtime_1.jsx)("div", { className: "text-[11px] text-slate-500 truncate", children: phone })] })] })), hasEmail && ((0, jsx_runtime_1.jsxs)("a", { href: (0, urls_1.createEmailUrl)(email, `Inquiry: ${storeName}`), className: "flex items-center gap-3 p-2.5 rounded-xl bg-white border border-slate-200/80 hover:border-purple-400 hover:shadow-sm transition-all text-slate-800", "data-preview-field-path": `${fieldPath}.email`, children: [(0, jsx_runtime_1.jsx)("div", { className: "w-9 h-9 rounded-lg bg-purple-50 text-purple-600 flex items-center justify-center flex-shrink-0", children: (0, jsx_runtime_1.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("path", { d: "M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z" }), (0, jsx_runtime_1.jsx)("polyline", { points: "22,6 12,13 2,6" })] }) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 min-w-0", children: [(0, jsx_runtime_1.jsx)("div", { className: "font-semibold text-slate-900 text-xs", children: "Send Email" }), (0, jsx_runtime_1.jsx)("div", { className: "text-[11px] text-slate-500 truncate", children: email })] })] }))] })] })), (0, jsx_runtime_1.jsx)("button", { type: "button", onClick: () => setIsOpen(!isOpen), style: bubbleStyle, className: "deneb-bubble hover:scale-105 active:scale-95 flex items-center justify-center focus:outline-none", "aria-label": "Toggle contact channels", children: isOpen ? ((0, jsx_runtime_1.jsxs)("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), (0, jsx_runtime_1.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] })) : ((0, jsx_runtime_1.jsx)("svg", { width: "28", height: "28", viewBox: "0 0 24 24", fill: "currentColor", children: (0, jsx_runtime_1.jsx)("path", { d: "M12.031 6.172c-3.181 0-5.767 2.586-5.768 5.766-.001 1.298.38 2.27 1.019 3.287l-.582 2.128 2.182-.573c.978.58 1.911.928 3.145.929 3.178 0 5.767-2.587 5.768-5.766.001-3.187-2.575-5.77-5.764-5.771zm3.392 8.244c-.144.405-.837.774-1.17.824-.312.045-.694.062-1.116-.073-.266-.086-.61-.225-1.047-.417-1.854-.814-3.056-2.695-3.15-2.819-.092-.124-.755-.999-.755-1.907 0-.909.479-1.353.649-1.536.17-.183.371-.23.495-.23.124 0 .248.002.355.008.113.006.265-.043.414.316.155.372.531 1.296.577 1.39.046.094.077.204.015.328-.061.124-.092.202-.184.31-.092.108-.195.241-.278.324-.093.093-.19.195-.082.381.109.186.483.797 1.037 1.289.713.633 1.314.829 1.501.922.186.093.295.078.404-.047.11-.124.467-.543.591-.729.124-.186.248-.155.418-.093.17.062 1.082.51 1.268.603.186.093.31.14.356.217.046.077.046.449-.098.854z" }) })) })] }));
|
|
68
69
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export declare const DENEB_FONTS_LINK_ID = "deneb-google-fonts";
|
|
3
|
+
export interface FontLoaderProps {
|
|
4
|
+
/** Additional font ids to preload beyond site-data discovery */
|
|
5
|
+
fontIds?: string[];
|
|
6
|
+
/** Use Google Fonts CDN (default in preview). Set false when `deneb fonts install` CSS is present */
|
|
7
|
+
useGoogleCdn?: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Dynamically loads Google Fonts used by the active site-data theme + style tree.
|
|
11
|
+
* In production, pair with `deneb fonts install` which writes self-hosted @fontsource CSS.
|
|
12
|
+
*/
|
|
13
|
+
export declare function FontLoader({ fontIds, useGoogleCdn }: FontLoaderProps): React.JSX.Element | null;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.DENEB_FONTS_LINK_ID = void 0;
|
|
5
|
+
exports.FontLoader = FontLoader;
|
|
6
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
7
|
+
const react_1 = require("react");
|
|
8
|
+
const useDenebFonts_1 = require("./useDenebFonts");
|
|
9
|
+
exports.DENEB_FONTS_LINK_ID = 'deneb-google-fonts';
|
|
10
|
+
/**
|
|
11
|
+
* Dynamically loads Google Fonts used by the active site-data theme + style tree.
|
|
12
|
+
* In production, pair with `deneb fonts install` which writes self-hosted @fontsource CSS.
|
|
13
|
+
*/
|
|
14
|
+
function FontLoader({ fontIds = [], useGoogleCdn = true }) {
|
|
15
|
+
const { googleStylesheetUrl, cssVariables, fontIds: activeFontIds } = (0, useDenebFonts_1.useDenebFonts)(fontIds);
|
|
16
|
+
const loadedUrl = (0, react_1.useRef)(null);
|
|
17
|
+
const enableCdn = useGoogleCdn;
|
|
18
|
+
(0, react_1.useEffect)(() => {
|
|
19
|
+
if (!enableCdn || !googleStylesheetUrl || typeof document === 'undefined')
|
|
20
|
+
return;
|
|
21
|
+
const selfHosted = getComputedStyle(document.documentElement)
|
|
22
|
+
.getPropertyValue('--deneb-fonts-selfhosted')
|
|
23
|
+
.trim();
|
|
24
|
+
if (selfHosted === '1')
|
|
25
|
+
return;
|
|
26
|
+
if (loadedUrl.current === googleStylesheetUrl)
|
|
27
|
+
return;
|
|
28
|
+
let link = document.getElementById(exports.DENEB_FONTS_LINK_ID);
|
|
29
|
+
if (!link) {
|
|
30
|
+
link = document.createElement('link');
|
|
31
|
+
link.id = exports.DENEB_FONTS_LINK_ID;
|
|
32
|
+
link.rel = 'stylesheet';
|
|
33
|
+
document.head.appendChild(link);
|
|
34
|
+
}
|
|
35
|
+
link.href = googleStylesheetUrl;
|
|
36
|
+
loadedUrl.current = googleStylesheetUrl;
|
|
37
|
+
}, [enableCdn, googleStylesheetUrl]);
|
|
38
|
+
if (Object.keys(cssVariables).length === 0)
|
|
39
|
+
return null;
|
|
40
|
+
return ((0, jsx_runtime_1.jsx)("style", { "data-deneb-font-vars": true, "data-deneb-font-count": activeFontIds.length, children: `:root { ${Object.entries(cssVariables)
|
|
41
|
+
.map(([key, value]) => `${key}: ${value};`)
|
|
42
|
+
.join(' ')} }` }));
|
|
43
|
+
}
|