@deneb-ui/ui 2.0.0
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 +182 -0
- package/dist/EditableBox.d.ts +56 -0
- package/dist/EditableBox.js +113 -0
- package/dist/EditableCard.d.ts +48 -0
- package/dist/EditableCard.js +85 -0
- package/dist/EditableContactForm.d.ts +11 -0
- package/dist/EditableContactForm.js +146 -0
- package/dist/EditableDialog.d.ts +25 -0
- package/dist/EditableDialog.js +145 -0
- package/dist/EditableFAQAccordion.d.ts +19 -0
- package/dist/EditableFAQAccordion.js +62 -0
- package/dist/EditableFooter.d.ts +31 -0
- package/dist/EditableFooter.js +330 -0
- package/dist/EditableGrid.d.ts +40 -0
- package/dist/EditableGrid.js +39 -0
- package/dist/EditableHero.d.ts +27 -0
- package/dist/EditableHero.js +154 -0
- package/dist/EditableImage.d.ts +13 -0
- package/dist/EditableImage.js +38 -0
- package/dist/EditableList.d.ts +33 -0
- package/dist/EditableList.js +19 -0
- package/dist/EditableNavbar.d.ts +28 -0
- package/dist/EditableNavbar.js +178 -0
- package/dist/EditablePricingCard.d.ts +31 -0
- package/dist/EditablePricingCard.js +93 -0
- package/dist/EditableProductCard.d.ts +60 -0
- package/dist/EditableProductCard.js +116 -0
- package/dist/EditableSection.d.ts +35 -0
- package/dist/EditableSection.js +34 -0
- package/dist/EditableServiceCard.d.ts +38 -0
- package/dist/EditableServiceCard.js +28 -0
- package/dist/EditableTestimonialCard.d.ts +17 -0
- package/dist/EditableTestimonialCard.js +46 -0
- package/dist/EditableText.d.ts +117 -0
- package/dist/EditableText.js +319 -0
- package/dist/SiteDataProvider.d.ts +61 -0
- package/dist/SiteDataProvider.js +316 -0
- package/dist/ThemeStyles.d.ts +46 -0
- package/dist/ThemeStyles.js +181 -0
- package/dist/business/BusinessHours.d.ts +20 -0
- package/dist/business/BusinessHours.js +109 -0
- package/dist/business/index.d.ts +1 -0
- package/dist/business/index.js +17 -0
- package/dist/contact/ContactActions.d.ts +24 -0
- package/dist/contact/ContactActions.js +30 -0
- package/dist/contact/ContactButton.d.ts +15 -0
- package/dist/contact/ContactButton.js +94 -0
- package/dist/contact/EmailButton.d.ts +6 -0
- package/dist/contact/EmailButton.js +12 -0
- package/dist/contact/PhoneButton.d.ts +6 -0
- package/dist/contact/PhoneButton.js +12 -0
- package/dist/contact/WhatsAppButton.d.ts +6 -0
- package/dist/contact/WhatsAppButton.js +13 -0
- package/dist/contact/index.d.ts +5 -0
- package/dist/contact/index.js +21 -0
- package/dist/core/DenebAction.d.ts +19 -0
- package/dist/core/DenebAction.js +107 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.js +17 -0
- package/dist/index.d.ts +61 -0
- package/dist/index.js +106 -0
- package/dist/location/Address.d.ts +14 -0
- package/dist/location/Address.js +26 -0
- package/dist/location/LocationCard.d.ts +20 -0
- package/dist/location/LocationCard.js +41 -0
- package/dist/location/LocationLink.d.ts +18 -0
- package/dist/location/LocationLink.js +23 -0
- package/dist/location/MapEmbed.d.ts +18 -0
- package/dist/location/MapEmbed.js +30 -0
- package/dist/location/MapLink.d.ts +13 -0
- package/dist/location/MapLink.js +63 -0
- package/dist/location/index.d.ts +5 -0
- package/dist/location/index.js +21 -0
- package/dist/social/SocialButton.d.ts +11 -0
- package/dist/social/SocialButton.js +112 -0
- package/dist/social/SocialLinks.d.ts +14 -0
- package/dist/social/SocialLinks.js +42 -0
- package/dist/social/index.d.ts +2 -0
- package/dist/social/index.js +18 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +17 -0
- package/dist/utils/urls.d.ts +32 -0
- package/dist/utils/urls.js +91 -0
- package/package.json +41 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { BoxSpacing } from './EditableBox';
|
|
3
|
+
export interface EditableSectionProps extends React.HTMLAttributes<HTMLElement> {
|
|
4
|
+
as?: React.ElementType;
|
|
5
|
+
/**
|
|
6
|
+
* Required fivora design section identifier (e.g. 'home-hero', 'home-introduction', 'home-features').
|
|
7
|
+
* Automatically sets `data-design-section` to satisfy strict Fivora validator rules.
|
|
8
|
+
*/
|
|
9
|
+
name: string;
|
|
10
|
+
/**
|
|
11
|
+
* Vertical section padding ('none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' or custom CSS).
|
|
12
|
+
*/
|
|
13
|
+
padding?: BoxSpacing;
|
|
14
|
+
/**
|
|
15
|
+
* Background color or CSS variable.
|
|
16
|
+
*/
|
|
17
|
+
bg?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Text color for the section.
|
|
20
|
+
*/
|
|
21
|
+
color?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Max width for the section container content.
|
|
24
|
+
*/
|
|
25
|
+
maxWidth?: string | number;
|
|
26
|
+
/**
|
|
27
|
+
* Section border style.
|
|
28
|
+
*/
|
|
29
|
+
border?: string | boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* EditableSection standardizes section spacing and automatically applies the required
|
|
33
|
+
* `data-design-section` marker for 100% fivora contract compliance.
|
|
34
|
+
*/
|
|
35
|
+
export declare function EditableSection({ as: Component, name, padding, bg, color, maxWidth, border, className, style, children, ...props }: EditableSectionProps): React.JSX.Element;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EditableSection = EditableSection;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const SECTION_PADDING_MAP = {
|
|
6
|
+
none: '0',
|
|
7
|
+
xs: '1.5rem 0',
|
|
8
|
+
sm: '2.5rem 0',
|
|
9
|
+
md: '4rem 0',
|
|
10
|
+
lg: '6rem 0',
|
|
11
|
+
xl: '8rem 0',
|
|
12
|
+
'2xl': '10rem 0',
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* EditableSection standardizes section spacing and automatically applies the required
|
|
16
|
+
* `data-design-section` marker for 100% fivora contract compliance.
|
|
17
|
+
*/
|
|
18
|
+
function EditableSection({ as: Component = 'section', name, padding = 'lg', bg, color, maxWidth, border, className = '', style, children, ...props }) {
|
|
19
|
+
const resolvedPadding = padding !== undefined ? (SECTION_PADDING_MAP[String(padding)] || String(padding)) : undefined;
|
|
20
|
+
const resolvedBorder = border === true
|
|
21
|
+
? '1px solid var(--border-color, rgba(226, 232, 240, 0.8))'
|
|
22
|
+
: typeof border === 'string'
|
|
23
|
+
? border
|
|
24
|
+
: undefined;
|
|
25
|
+
const sectionStyle = {
|
|
26
|
+
...(resolvedPadding ? { padding: resolvedPadding } : {}),
|
|
27
|
+
...(bg ? { background: bg } : {}),
|
|
28
|
+
...(color ? { color } : {}),
|
|
29
|
+
...(maxWidth !== undefined ? { maxWidth, marginLeft: 'auto', marginRight: 'auto' } : {}),
|
|
30
|
+
...(resolvedBorder ? { borderBottom: resolvedBorder } : {}),
|
|
31
|
+
...style,
|
|
32
|
+
};
|
|
33
|
+
return ((0, jsx_runtime_1.jsx)(Component, { "data-design-section": name, className: `editable-section ${className}`.trim(), style: sectionStyle, ...props, children: children }));
|
|
34
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface ServiceItem {
|
|
3
|
+
id?: string | number;
|
|
4
|
+
name?: string;
|
|
5
|
+
title?: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
imageUrl?: string;
|
|
8
|
+
image?: string;
|
|
9
|
+
features?: unknown[];
|
|
10
|
+
[key: string]: unknown;
|
|
11
|
+
}
|
|
12
|
+
export interface EditableServiceCardProps extends React.HTMLAttributes<HTMLElement> {
|
|
13
|
+
/**
|
|
14
|
+
* The item path, e.g. "services[0]".
|
|
15
|
+
*/
|
|
16
|
+
itemPath: string;
|
|
17
|
+
/**
|
|
18
|
+
* The service data object.
|
|
19
|
+
*/
|
|
20
|
+
service: ServiceItem;
|
|
21
|
+
/**
|
|
22
|
+
* Fallback image URL if image is missing.
|
|
23
|
+
*/
|
|
24
|
+
imageFallback?: string;
|
|
25
|
+
/**
|
|
26
|
+
* HTML wrapper tag (default: 'article').
|
|
27
|
+
*/
|
|
28
|
+
as?: React.ElementType;
|
|
29
|
+
/**
|
|
30
|
+
* Text/content alignment for the card ('left' | 'center' | 'right').
|
|
31
|
+
*/
|
|
32
|
+
align?: 'left' | 'center' | 'right';
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* EditableServiceCard standardizes service presentation across Home and Services pages.
|
|
36
|
+
* Supports service name, description, image, and repeatable features checklist.
|
|
37
|
+
*/
|
|
38
|
+
export declare function EditableServiceCard({ itemPath, service, imageFallback, as: Component, align, className, style, children, ...props }: EditableServiceCardProps): React.JSX.Element;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EditableServiceCard = EditableServiceCard;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const EditableText_1 = require("./EditableText");
|
|
6
|
+
const EditableImage_1 = require("./EditableImage");
|
|
7
|
+
/**
|
|
8
|
+
* EditableServiceCard standardizes service presentation across Home and Services pages.
|
|
9
|
+
* Supports service name, description, image, and repeatable features checklist.
|
|
10
|
+
*/
|
|
11
|
+
function EditableServiceCard({ itemPath, service, imageFallback = '/placeholder.svg', as: Component = 'article', align = 'left', className = '', style, children, ...props }) {
|
|
12
|
+
const name = String(service?.name || service?.title || '');
|
|
13
|
+
const description = String(service?.description || '');
|
|
14
|
+
const imageUrl = String(service?.imageUrl || service?.image || '');
|
|
15
|
+
const features = Array.isArray(service?.features) ? service.features : [];
|
|
16
|
+
const mergedStyle = {
|
|
17
|
+
textAlign: align,
|
|
18
|
+
...style,
|
|
19
|
+
};
|
|
20
|
+
return ((0, jsx_runtime_1.jsxs)(Component, { "data-preview-item-path": itemPath, className: `editable-service-card ${className}`.trim(), style: mergedStyle, ...props, children: [(imageUrl || service?.imageUrl !== undefined || service?.image !== undefined) && ((0, jsx_runtime_1.jsx)("div", { className: "service-card-image-wrap", children: (0, jsx_runtime_1.jsx)(EditableImage_1.EditableImage, { id: `${itemPath}.imageUrl`, "data-preview-field-path": `${itemPath}.imageUrl`, src: imageUrl, fallbackSrc: imageFallback, alt: name, className: "service-card-image" }) })), (0, jsx_runtime_1.jsxs)("div", { className: "service-card-body", children: [(0, jsx_runtime_1.jsx)(EditableText_1.EditableText, { as: "h2", id: `${itemPath}.name`, "data-preview-field-path": `${itemPath}.name`, defaultValue: name, className: "service-card-title" }), (0, jsx_runtime_1.jsx)(EditableText_1.EditableText, { as: "p", id: `${itemPath}.description`, "data-preview-field-path": `${itemPath}.description`, defaultValue: description, className: "service-card-description" }), (features.length > 0 || Array.isArray(service?.features)) && ((0, jsx_runtime_1.jsx)("ul", { "data-preview-list-path": `${itemPath}.features`, className: "service-card-features", children: features.map((feature, featureIndex) => {
|
|
21
|
+
const featureText = typeof feature === 'string'
|
|
22
|
+
? feature
|
|
23
|
+
: typeof feature?.title === 'string'
|
|
24
|
+
? feature.title
|
|
25
|
+
: String(feature ?? '');
|
|
26
|
+
return ((0, jsx_runtime_1.jsx)("li", { "data-preview-item-path": `${itemPath}.features[${featureIndex}]`, children: (0, jsx_runtime_1.jsx)(EditableText_1.EditableText, { id: `${itemPath}.features[${featureIndex}]`, "data-preview-field-path": `${itemPath}.features[${featureIndex}]`, defaultValue: featureText }) }, featureIndex));
|
|
27
|
+
}) })), children] })] }));
|
|
28
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface TestimonialItem {
|
|
3
|
+
id?: string | number;
|
|
4
|
+
quote?: string;
|
|
5
|
+
author?: string;
|
|
6
|
+
role?: string;
|
|
7
|
+
company?: string;
|
|
8
|
+
avatar?: string;
|
|
9
|
+
rating?: number;
|
|
10
|
+
[key: string]: unknown;
|
|
11
|
+
}
|
|
12
|
+
export interface EditableTestimonialCardProps extends React.HTMLAttributes<HTMLElement> {
|
|
13
|
+
itemPath: string;
|
|
14
|
+
item: TestimonialItem;
|
|
15
|
+
as?: React.ElementType;
|
|
16
|
+
}
|
|
17
|
+
export declare function EditableTestimonialCard({ itemPath, item, as: Component, className, style, ...props }: EditableTestimonialCardProps): React.JSX.Element;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EditableTestimonialCard = EditableTestimonialCard;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const EditableText_1 = require("./EditableText");
|
|
6
|
+
const EditableImage_1 = require("./EditableImage");
|
|
7
|
+
function EditableTestimonialCard({ itemPath, item, as: Component = 'div', className = '', style, ...props }) {
|
|
8
|
+
const quote = String(item?.quote || 'Exceptional quality and service. Highly recommended!');
|
|
9
|
+
const author = String(item?.author || 'Customer Name');
|
|
10
|
+
const role = String(item?.role || item?.company || 'Verified Buyer');
|
|
11
|
+
const avatar = String(item?.avatar || '');
|
|
12
|
+
const rating = Number(item?.rating || 5);
|
|
13
|
+
const cardStyle = {
|
|
14
|
+
backgroundColor: '#ffffff',
|
|
15
|
+
border: '1px solid #f1f5f9',
|
|
16
|
+
borderRadius: '16px',
|
|
17
|
+
padding: '2rem',
|
|
18
|
+
boxShadow: '0 4px 20px -2px rgba(0, 0, 0, 0.04)',
|
|
19
|
+
display: 'flex',
|
|
20
|
+
flexDirection: 'column',
|
|
21
|
+
justifyContent: 'space-between',
|
|
22
|
+
transition: 'transform 0.2s ease, box-shadow 0.2s ease',
|
|
23
|
+
...style,
|
|
24
|
+
};
|
|
25
|
+
return ((0, jsx_runtime_1.jsxs)(Component, { "data-preview-item-path": itemPath, style: cardStyle, className: `editable-testimonial-card ${className}`.trim(), ...props, children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { style: { display: 'flex', gap: '3px', marginBottom: '1.25rem' }, children: [...Array(5)].map((_, i) => ((0, jsx_runtime_1.jsx)("svg", { width: "18", height: "18", viewBox: "0 0 20 20", fill: i < rating ? '#f59e0b' : '#e2e8f0', "data-preview-static": "testimonial-star", children: (0, jsx_runtime_1.jsx)("path", { d: "M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" }) }, i))) }), (0, jsx_runtime_1.jsx)(EditableText_1.EditableText, { as: "p", id: `${itemPath}.quote`, defaultValue: quote, style: {
|
|
26
|
+
fontSize: '1rem',
|
|
27
|
+
lineHeight: 1.6,
|
|
28
|
+
color: 'var(--page-text, #334155)',
|
|
29
|
+
fontStyle: 'italic',
|
|
30
|
+
marginBottom: '1.5rem',
|
|
31
|
+
} })] }), (0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', alignItems: 'center', gap: '0.875rem' }, children: [(0, jsx_runtime_1.jsx)(EditableImage_1.EditableImage, { id: `${itemPath}.avatar`, src: avatar, alt: author, style: {
|
|
32
|
+
width: '44px',
|
|
33
|
+
height: '44px',
|
|
34
|
+
borderRadius: '9999px',
|
|
35
|
+
objectFit: 'cover',
|
|
36
|
+
} }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(EditableText_1.EditableText, { as: "h4", id: `${itemPath}.author`, defaultValue: author, style: {
|
|
37
|
+
fontSize: '0.95rem',
|
|
38
|
+
fontWeight: 700,
|
|
39
|
+
color: 'var(--heading-color, #0f172a)',
|
|
40
|
+
lineHeight: 1.2,
|
|
41
|
+
} }), (0, jsx_runtime_1.jsx)(EditableText_1.EditableText, { as: "p", id: `${itemPath}.role`, defaultValue: role, style: {
|
|
42
|
+
fontSize: '0.825rem',
|
|
43
|
+
color: 'var(--muted-text, #64748b)',
|
|
44
|
+
marginTop: '0.125rem',
|
|
45
|
+
} })] })] })] }));
|
|
46
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export type TextSemanticColor = 'primary' | 'secondary' | 'accent' | 'heading' | 'text' | 'muted' | 'white' | 'dark' | 'inherit' | 'initial';
|
|
3
|
+
export type TextColor = TextSemanticColor | (string & {});
|
|
4
|
+
export type TextSize = 'xs' | 'sm' | 'base' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl' | '6xl' | '7xl' | '8xl' | 'hero' | (string & {});
|
|
5
|
+
export type TextWeight = 'thin' | 'extralight' | 'light' | 'normal' | 'medium' | 'semibold' | 'bold' | 'extrabold' | 'black' | number | (string & {});
|
|
6
|
+
export type TextLineHeight = 'none' | 'tight' | 'snug' | 'normal' | 'relaxed' | 'loose' | number | (string & {});
|
|
7
|
+
export type TextLetterSpacing = 'tighter' | 'tight' | 'normal' | 'wide' | 'wider' | 'widest' | (string & {});
|
|
8
|
+
export type TextVariant = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'lead' | 'eyebrow' | 'caption' | 'badge';
|
|
9
|
+
export declare const SIZE_MAP: Record<string, string>;
|
|
10
|
+
export declare const WEIGHT_MAP: Record<string, number | string>;
|
|
11
|
+
export declare const LINE_HEIGHT_MAP: Record<string, number | string>;
|
|
12
|
+
export declare const LETTER_SPACING_MAP: Record<string, string>;
|
|
13
|
+
export declare const COLOR_MAP: Record<string, string>;
|
|
14
|
+
export declare const VARIANT_DEFAULTS: Record<TextVariant, {
|
|
15
|
+
as: React.ElementType;
|
|
16
|
+
size?: TextSize;
|
|
17
|
+
weight?: TextWeight;
|
|
18
|
+
lineHeight?: TextLineHeight;
|
|
19
|
+
transform?: 'uppercase' | 'lowercase' | 'capitalize' | 'none';
|
|
20
|
+
letterSpacing?: TextLetterSpacing;
|
|
21
|
+
color?: TextColor;
|
|
22
|
+
fontFamily?: string;
|
|
23
|
+
}>;
|
|
24
|
+
export declare const FONT_FAMILY_MAP: Record<string, string>;
|
|
25
|
+
export interface EditableTextProps extends React.HTMLAttributes<HTMLElement> {
|
|
26
|
+
/**
|
|
27
|
+
* Field path in siteData (e.g. "home.heroTitle").
|
|
28
|
+
*/
|
|
29
|
+
id?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Explicit fivora visual editing attribute for strict static analysis.
|
|
32
|
+
*/
|
|
33
|
+
'data-preview-field-path'?: string;
|
|
34
|
+
defaultValue?: string;
|
|
35
|
+
as?: React.ElementType;
|
|
36
|
+
/**
|
|
37
|
+
* Semantic typography variant providing instant preset styles (h1-h6, p, lead, eyebrow, caption, badge).
|
|
38
|
+
*/
|
|
39
|
+
variant?: TextVariant;
|
|
40
|
+
/**
|
|
41
|
+
* Text color: preset tokens ('primary' | 'secondary' | 'accent' | 'heading' | 'text' | 'muted' | 'white' | 'dark')
|
|
42
|
+
* or any valid CSS color string (hex, rgb, hsl, or CSS variable).
|
|
43
|
+
*/
|
|
44
|
+
color?: TextColor;
|
|
45
|
+
/**
|
|
46
|
+
* Font size preset ('xs' | 'sm' | 'base' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl' | '6xl' | '7xl' | '8xl' | 'hero')
|
|
47
|
+
* or any custom CSS size string (e.g. '2.5rem', '32px', 'clamp(1.5rem, 3vw, 3rem)').
|
|
48
|
+
*/
|
|
49
|
+
size?: TextSize;
|
|
50
|
+
/**
|
|
51
|
+
* Font weight ('thin' | 'light' | 'normal' | 'medium' | 'semibold' | 'bold' | 'extrabold' | 'black' | number).
|
|
52
|
+
*/
|
|
53
|
+
weight?: TextWeight;
|
|
54
|
+
/**
|
|
55
|
+
* Line height preset ('none' | 'tight' | 'snug' | 'normal' | 'relaxed' | 'loose') or number / CSS string.
|
|
56
|
+
*/
|
|
57
|
+
lineHeight?: TextLineHeight;
|
|
58
|
+
/**
|
|
59
|
+
* Text alignment ('left' | 'center' | 'right' | 'justify').
|
|
60
|
+
*/
|
|
61
|
+
align?: 'left' | 'center' | 'right' | 'justify';
|
|
62
|
+
/**
|
|
63
|
+
* Text transform ('uppercase' | 'lowercase' | 'capitalize' | 'none').
|
|
64
|
+
*/
|
|
65
|
+
transform?: 'uppercase' | 'lowercase' | 'capitalize' | 'none';
|
|
66
|
+
/**
|
|
67
|
+
* Letter spacing / tracking preset ('tighter' | 'tight' | 'normal' | 'wide' | 'wider' | 'widest') or custom CSS string.
|
|
68
|
+
*/
|
|
69
|
+
letterSpacing?: TextLetterSpacing;
|
|
70
|
+
/**
|
|
71
|
+
* Font family: 'heading' | 'body' or custom CSS font-family string.
|
|
72
|
+
*/
|
|
73
|
+
fontFamily?: 'heading' | 'body' | (string & {});
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* EditableText provides full typography controls (color, size, weight, line-height, alignment, transform, variants)
|
|
77
|
+
* alongside strict Fivora visual editing bindings.
|
|
78
|
+
*/
|
|
79
|
+
export declare function EditableText({ id, 'data-preview-field-path': previewFieldPath, defaultValue, children, as: ComponentOverride, variant, color, size, weight, lineHeight, align, transform, letterSpacing, fontFamily, style, ...props }: EditableTextProps): React.JSX.Element;
|
|
80
|
+
export interface EditableHeadingProps extends Omit<EditableTextProps, 'variant'> {
|
|
81
|
+
level?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
82
|
+
}
|
|
83
|
+
export declare function EditableHeading({ level, as, ...props }: EditableHeadingProps): React.JSX.Element;
|
|
84
|
+
export interface EditableParagraphProps extends Omit<EditableTextProps, 'variant'> {
|
|
85
|
+
lead?: boolean;
|
|
86
|
+
}
|
|
87
|
+
export declare function EditableParagraph({ lead, as, ...props }: EditableParagraphProps): React.JSX.Element;
|
|
88
|
+
export declare function EditableLead({ as, ...props }: Omit<EditableTextProps, 'variant'>): React.JSX.Element;
|
|
89
|
+
export interface EditableBadgeProps extends Omit<EditableTextProps, 'variant'> {
|
|
90
|
+
badgeVariant?: 'primary' | 'secondary' | 'accent' | 'outline' | 'glass' | 'glow';
|
|
91
|
+
}
|
|
92
|
+
export declare function EditableBadge({ as, badgeVariant, className, style, ...props }: EditableBadgeProps): React.JSX.Element;
|
|
93
|
+
export interface EditableQuoteProps extends Omit<EditableTextProps, 'variant'> {
|
|
94
|
+
cite?: string;
|
|
95
|
+
}
|
|
96
|
+
export declare function EditableQuote({ as, cite, className, style, ...props }: EditableQuoteProps): React.JSX.Element;
|
|
97
|
+
export interface EditableLinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
|
|
98
|
+
id?: string;
|
|
99
|
+
'data-preview-field-path'?: string;
|
|
100
|
+
targetPage?: string;
|
|
101
|
+
defaultValue?: string;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* EditableLink enforces Fivora's strict selected-page contract:
|
|
105
|
+
* - Injects data-target-page on wrapper
|
|
106
|
+
* - Omits rendering if targetPage is not in requirements.requiredPages
|
|
107
|
+
*/
|
|
108
|
+
export declare function EditableLink({ id, 'data-preview-field-path': previewFieldPath, targetPage, defaultValue, href, children, className, ...props }: EditableLinkProps): React.JSX.Element;
|
|
109
|
+
export interface EditableButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
110
|
+
id?: string;
|
|
111
|
+
'data-preview-field-path'?: string;
|
|
112
|
+
defaultValue?: string;
|
|
113
|
+
targetPage?: string;
|
|
114
|
+
btnVariant?: 'primary' | 'secondary' | 'accent' | 'outline' | 'ghost' | 'glass';
|
|
115
|
+
size?: 'sm' | 'md' | 'lg';
|
|
116
|
+
}
|
|
117
|
+
export declare function EditableButton({ id, 'data-preview-field-path': previewFieldPath, defaultValue, targetPage, btnVariant, size, children, className, style, ...props }: EditableButtonProps): React.JSX.Element;
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FONT_FAMILY_MAP = exports.VARIANT_DEFAULTS = exports.COLOR_MAP = exports.LETTER_SPACING_MAP = exports.LINE_HEIGHT_MAP = exports.WEIGHT_MAP = exports.SIZE_MAP = void 0;
|
|
4
|
+
exports.EditableText = EditableText;
|
|
5
|
+
exports.EditableHeading = EditableHeading;
|
|
6
|
+
exports.EditableParagraph = EditableParagraph;
|
|
7
|
+
exports.EditableLead = EditableLead;
|
|
8
|
+
exports.EditableBadge = EditableBadge;
|
|
9
|
+
exports.EditableQuote = EditableQuote;
|
|
10
|
+
exports.EditableLink = EditableLink;
|
|
11
|
+
exports.EditableButton = EditableButton;
|
|
12
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
13
|
+
const SiteDataProvider_1 = require("./SiteDataProvider");
|
|
14
|
+
exports.SIZE_MAP = {
|
|
15
|
+
xs: '0.75rem',
|
|
16
|
+
sm: '0.875rem',
|
|
17
|
+
base: '1rem',
|
|
18
|
+
md: '1rem',
|
|
19
|
+
lg: '1.125rem',
|
|
20
|
+
xl: '1.25rem',
|
|
21
|
+
'2xl': '1.5rem',
|
|
22
|
+
'3xl': '1.875rem',
|
|
23
|
+
'4xl': '2.25rem',
|
|
24
|
+
'5xl': '3rem',
|
|
25
|
+
'6xl': '3.75rem',
|
|
26
|
+
'7xl': '4.5rem',
|
|
27
|
+
'8xl': '6rem',
|
|
28
|
+
hero: 'clamp(2.25rem, 5vw, 4rem)',
|
|
29
|
+
};
|
|
30
|
+
exports.WEIGHT_MAP = {
|
|
31
|
+
thin: 100,
|
|
32
|
+
extralight: 200,
|
|
33
|
+
light: 300,
|
|
34
|
+
normal: 400,
|
|
35
|
+
medium: 500,
|
|
36
|
+
semibold: 600,
|
|
37
|
+
bold: 700,
|
|
38
|
+
extrabold: 800,
|
|
39
|
+
black: 900,
|
|
40
|
+
};
|
|
41
|
+
exports.LINE_HEIGHT_MAP = {
|
|
42
|
+
none: 1,
|
|
43
|
+
tight: 1.15,
|
|
44
|
+
snug: 1.3,
|
|
45
|
+
normal: 1.5,
|
|
46
|
+
relaxed: 1.625,
|
|
47
|
+
loose: 2,
|
|
48
|
+
};
|
|
49
|
+
exports.LETTER_SPACING_MAP = {
|
|
50
|
+
tighter: '-0.05em',
|
|
51
|
+
tight: '-0.025em',
|
|
52
|
+
normal: '0em',
|
|
53
|
+
wide: '0.025em',
|
|
54
|
+
wider: '0.05em',
|
|
55
|
+
widest: '0.1em',
|
|
56
|
+
};
|
|
57
|
+
exports.COLOR_MAP = {
|
|
58
|
+
primary: 'var(--brand-color, #2563eb)',
|
|
59
|
+
secondary: 'var(--brand-secondary, #0f172a)',
|
|
60
|
+
accent: 'var(--brand-accent, #14b8a6)',
|
|
61
|
+
heading: 'var(--heading-color, var(--brand-secondary, #0f172a))',
|
|
62
|
+
text: 'var(--page-text, #0f172a)',
|
|
63
|
+
muted: 'var(--muted-text, #64748b)',
|
|
64
|
+
white: '#ffffff',
|
|
65
|
+
dark: '#0f172a',
|
|
66
|
+
inherit: 'inherit',
|
|
67
|
+
initial: 'initial',
|
|
68
|
+
};
|
|
69
|
+
exports.VARIANT_DEFAULTS = {
|
|
70
|
+
h1: { as: 'h1', size: '4xl', weight: 'bold', lineHeight: 'tight', color: 'heading', fontFamily: 'var(--heading-font)' },
|
|
71
|
+
h2: { as: 'h2', size: '3xl', weight: 'bold', lineHeight: 'tight', color: 'heading', fontFamily: 'var(--heading-font)' },
|
|
72
|
+
h3: { as: 'h3', size: '2xl', weight: 'semibold', lineHeight: 'snug', color: 'heading', fontFamily: 'var(--heading-font)' },
|
|
73
|
+
h4: { as: 'h4', size: 'xl', weight: 'semibold', lineHeight: 'snug', color: 'heading', fontFamily: 'var(--heading-font)' },
|
|
74
|
+
h5: { as: 'h5', size: 'lg', weight: 'medium', lineHeight: 'normal', color: 'heading', fontFamily: 'var(--heading-font)' },
|
|
75
|
+
h6: { as: 'h6', size: 'base', weight: 'medium', lineHeight: 'normal', color: 'heading', fontFamily: 'var(--heading-font)' },
|
|
76
|
+
p: { as: 'p', size: 'base', weight: 'normal', lineHeight: 'normal', color: 'text' },
|
|
77
|
+
lead: { as: 'p', size: 'lg', weight: 'normal', lineHeight: 'relaxed', color: 'muted' },
|
|
78
|
+
eyebrow: { as: 'span', size: 'xs', weight: 'bold', transform: 'uppercase', letterSpacing: 'wider', color: 'primary' },
|
|
79
|
+
caption: { as: 'span', size: 'xs', weight: 'normal', lineHeight: 'normal', color: 'muted' },
|
|
80
|
+
badge: { as: 'span', size: 'xs', weight: 'semibold', lineHeight: 'none', color: 'primary' },
|
|
81
|
+
};
|
|
82
|
+
exports.FONT_FAMILY_MAP = {
|
|
83
|
+
'Editorial Serif': "'Playfair Display', Georgia, 'Times New Roman', serif",
|
|
84
|
+
'Plus Jakarta Sans': "'Plus Jakarta Sans', system-ui, sans-serif",
|
|
85
|
+
'Inter': "'Inter', system-ui, sans-serif",
|
|
86
|
+
'Playfair Display': "'Playfair Display', Georgia, serif",
|
|
87
|
+
'Outfit': "'Outfit', system-ui, sans-serif",
|
|
88
|
+
'Cormorant Garamond': "'Cormorant Garamond', Georgia, serif",
|
|
89
|
+
'Montserrat': "'Montserrat', system-ui, sans-serif",
|
|
90
|
+
'System Sans': "system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
|
|
91
|
+
heading: 'var(--heading-font, Inter, sans-serif)',
|
|
92
|
+
body: 'var(--body-font, Inter, sans-serif)',
|
|
93
|
+
};
|
|
94
|
+
function toCssUnit(value) {
|
|
95
|
+
if (value === undefined || value === null || value === '')
|
|
96
|
+
return undefined;
|
|
97
|
+
const str = String(value).trim();
|
|
98
|
+
if (!str)
|
|
99
|
+
return undefined;
|
|
100
|
+
if (/^-?\d+(\.\d+)?$/.test(str)) {
|
|
101
|
+
return `${str}px`;
|
|
102
|
+
}
|
|
103
|
+
return str;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* EditableText provides full typography controls (color, size, weight, line-height, alignment, transform, variants)
|
|
107
|
+
* alongside strict Fivora visual editing bindings.
|
|
108
|
+
*/
|
|
109
|
+
function EditableText({ id, 'data-preview-field-path': previewFieldPath, defaultValue, children, as: ComponentOverride, variant, color, size, weight, lineHeight, align, transform, letterSpacing, fontFamily, style, ...props }) {
|
|
110
|
+
const path = previewFieldPath || id;
|
|
111
|
+
const content = children !== undefined ? children : defaultValue;
|
|
112
|
+
const dynamicStyle = (0, SiteDataProvider_1.useFieldStyle)(path);
|
|
113
|
+
const variantDefaults = variant ? exports.VARIANT_DEFAULTS[variant] : undefined;
|
|
114
|
+
const Component = ComponentOverride || variantDefaults?.as || 'span';
|
|
115
|
+
const effectiveColor = color || variantDefaults?.color;
|
|
116
|
+
const effectiveSize = size || variantDefaults?.size;
|
|
117
|
+
const effectiveWeight = weight || variantDefaults?.weight;
|
|
118
|
+
const effectiveLineHeight = lineHeight || variantDefaults?.lineHeight;
|
|
119
|
+
const effectiveTransform = transform || variantDefaults?.transform;
|
|
120
|
+
const effectiveLetterSpacing = letterSpacing || variantDefaults?.letterSpacing;
|
|
121
|
+
const effectiveFontFamily = fontFamily || variantDefaults?.fontFamily;
|
|
122
|
+
const resolvedColor = effectiveColor ? (exports.COLOR_MAP[effectiveColor] || effectiveColor) : undefined;
|
|
123
|
+
const resolvedSize = effectiveSize ? (exports.SIZE_MAP[effectiveSize] || effectiveSize) : undefined;
|
|
124
|
+
const resolvedWeight = effectiveWeight !== undefined ? (exports.WEIGHT_MAP[String(effectiveWeight)] || effectiveWeight) : undefined;
|
|
125
|
+
const resolvedLineHeight = effectiveLineHeight !== undefined ? (exports.LINE_HEIGHT_MAP[String(effectiveLineHeight)] || effectiveLineHeight) : undefined;
|
|
126
|
+
const resolvedLetterSpacing = effectiveLetterSpacing
|
|
127
|
+
? (exports.LETTER_SPACING_MAP[effectiveLetterSpacing] || effectiveLetterSpacing)
|
|
128
|
+
: undefined;
|
|
129
|
+
const resolvedFontFamily = effectiveFontFamily
|
|
130
|
+
? (exports.FONT_FAMILY_MAP[effectiveFontFamily] || effectiveFontFamily)
|
|
131
|
+
: undefined;
|
|
132
|
+
// Dynamic visual editor overrides
|
|
133
|
+
const dynamicColor = dynamicStyle?.color
|
|
134
|
+
? (exports.COLOR_MAP[String(dynamicStyle.color)] || String(dynamicStyle.color))
|
|
135
|
+
: undefined;
|
|
136
|
+
const dynamicSize = dynamicStyle?.fontSize !== undefined && dynamicStyle?.fontSize !== ''
|
|
137
|
+
? (exports.SIZE_MAP[String(dynamicStyle.fontSize)] || toCssUnit(dynamicStyle.fontSize))
|
|
138
|
+
: undefined;
|
|
139
|
+
const dynamicLineHeight = dynamicStyle?.lineHeight !== undefined && dynamicStyle?.lineHeight !== ''
|
|
140
|
+
? (exports.LINE_HEIGHT_MAP[String(dynamicStyle.lineHeight)] || dynamicStyle.lineHeight)
|
|
141
|
+
: undefined;
|
|
142
|
+
const dynamicFontFamily = dynamicStyle?.fontFamily
|
|
143
|
+
? (exports.FONT_FAMILY_MAP[String(dynamicStyle.fontFamily)] || String(dynamicStyle.fontFamily))
|
|
144
|
+
: undefined;
|
|
145
|
+
const dynamicAlign = dynamicStyle?.textAlign;
|
|
146
|
+
const dynamicMarginTop = toCssUnit(dynamicStyle?.spacingTop);
|
|
147
|
+
const dynamicMarginBottom = toCssUnit(dynamicStyle?.spacingBottom);
|
|
148
|
+
const dynamicMarginLeft = toCssUnit(dynamicStyle?.spacingLeft);
|
|
149
|
+
const dynamicMarginRight = toCssUnit(dynamicStyle?.spacingRight);
|
|
150
|
+
const typographyStyle = {
|
|
151
|
+
...(resolvedColor ? { color: resolvedColor } : {}),
|
|
152
|
+
...(resolvedSize ? { fontSize: resolvedSize } : {}),
|
|
153
|
+
...(resolvedWeight ? { fontWeight: resolvedWeight } : {}),
|
|
154
|
+
...(resolvedLineHeight ? { lineHeight: resolvedLineHeight } : {}),
|
|
155
|
+
...(align ? { textAlign: align } : {}),
|
|
156
|
+
...(effectiveTransform ? { textTransform: effectiveTransform } : {}),
|
|
157
|
+
...(resolvedLetterSpacing ? { letterSpacing: resolvedLetterSpacing } : {}),
|
|
158
|
+
...(resolvedFontFamily ? { fontFamily: resolvedFontFamily } : {}),
|
|
159
|
+
...style,
|
|
160
|
+
// Visual editor overrides take highest precedence:
|
|
161
|
+
...(dynamicColor ? { color: dynamicColor } : {}),
|
|
162
|
+
...(dynamicSize ? { fontSize: dynamicSize } : {}),
|
|
163
|
+
...(dynamicLineHeight ? { lineHeight: dynamicLineHeight } : {}),
|
|
164
|
+
...(dynamicAlign ? { textAlign: dynamicAlign } : {}),
|
|
165
|
+
...(dynamicFontFamily ? { fontFamily: dynamicFontFamily } : {}),
|
|
166
|
+
...(dynamicMarginTop !== undefined ? { marginTop: dynamicMarginTop } : {}),
|
|
167
|
+
...(dynamicMarginBottom !== undefined ? { marginBottom: dynamicMarginBottom } : {}),
|
|
168
|
+
...(dynamicMarginLeft !== undefined ? { marginLeft: dynamicMarginLeft } : {}),
|
|
169
|
+
...(dynamicMarginRight !== undefined ? { marginRight: dynamicMarginRight } : {}),
|
|
170
|
+
};
|
|
171
|
+
return ((0, jsx_runtime_1.jsx)(Component, { "data-preview-field-path": path, style: typographyStyle, ...props, children: content }));
|
|
172
|
+
}
|
|
173
|
+
function EditableHeading({ level = 2, as, ...props }) {
|
|
174
|
+
const variant = `h${level}`;
|
|
175
|
+
const headingTag = (as || `h${level}`);
|
|
176
|
+
return (0, jsx_runtime_1.jsx)(EditableText, { variant: variant, as: headingTag, ...props });
|
|
177
|
+
}
|
|
178
|
+
function EditableParagraph({ lead = false, as = 'p', ...props }) {
|
|
179
|
+
return (0, jsx_runtime_1.jsx)(EditableText, { variant: lead ? 'lead' : 'p', as: as, ...props });
|
|
180
|
+
}
|
|
181
|
+
function EditableLead({ as = 'p', ...props }) {
|
|
182
|
+
return (0, jsx_runtime_1.jsx)(EditableText, { variant: "lead", as: as, ...props });
|
|
183
|
+
}
|
|
184
|
+
function EditableBadge({ as = 'span', badgeVariant = 'primary', className = '', style, ...props }) {
|
|
185
|
+
const badgeStyles = {
|
|
186
|
+
primary: {
|
|
187
|
+
backgroundColor: 'rgba(37, 99, 235, 0.1)',
|
|
188
|
+
color: 'var(--brand-color, #2563eb)',
|
|
189
|
+
border: '1px solid rgba(37, 99, 235, 0.2)',
|
|
190
|
+
},
|
|
191
|
+
secondary: {
|
|
192
|
+
backgroundColor: 'rgba(15, 23, 42, 0.08)',
|
|
193
|
+
color: 'var(--brand-secondary, #0f172a)',
|
|
194
|
+
border: '1px solid rgba(15, 23, 42, 0.15)',
|
|
195
|
+
},
|
|
196
|
+
accent: {
|
|
197
|
+
backgroundColor: 'rgba(20, 184, 166, 0.12)',
|
|
198
|
+
color: 'var(--brand-accent, #14b8a6)',
|
|
199
|
+
border: '1px solid rgba(20, 184, 166, 0.25)',
|
|
200
|
+
},
|
|
201
|
+
outline: {
|
|
202
|
+
backgroundColor: 'transparent',
|
|
203
|
+
color: 'var(--page-text, #0f172a)',
|
|
204
|
+
border: '1px solid currentColor',
|
|
205
|
+
},
|
|
206
|
+
glass: {
|
|
207
|
+
backgroundColor: 'rgba(255, 255, 255, 0.2)',
|
|
208
|
+
backdropFilter: 'blur(8px)',
|
|
209
|
+
WebkitBackdropFilter: 'blur(8px)',
|
|
210
|
+
color: 'var(--page-text, #0f172a)',
|
|
211
|
+
border: '1px solid rgba(255, 255, 255, 0.3)',
|
|
212
|
+
},
|
|
213
|
+
glow: {
|
|
214
|
+
backgroundColor: 'rgba(37, 99, 235, 0.15)',
|
|
215
|
+
color: 'var(--brand-color, #2563eb)',
|
|
216
|
+
boxShadow: '0 0 12px rgba(37, 99, 235, 0.35)',
|
|
217
|
+
border: '1px solid rgba(37, 99, 235, 0.3)',
|
|
218
|
+
},
|
|
219
|
+
};
|
|
220
|
+
const defaultBadgeLayout = {
|
|
221
|
+
display: 'inline-flex',
|
|
222
|
+
alignItems: 'center',
|
|
223
|
+
gap: '0.375rem',
|
|
224
|
+
padding: '0.25rem 0.75rem',
|
|
225
|
+
borderRadius: '9999px',
|
|
226
|
+
fontSize: '0.75rem',
|
|
227
|
+
fontWeight: 600,
|
|
228
|
+
letterSpacing: '0.025em',
|
|
229
|
+
lineHeight: 1,
|
|
230
|
+
...(badgeStyles[badgeVariant] || badgeStyles.primary),
|
|
231
|
+
...style,
|
|
232
|
+
};
|
|
233
|
+
return ((0, jsx_runtime_1.jsx)(EditableText, { variant: "badge", as: as, style: defaultBadgeLayout, className: `editable-badge ${className}`.trim(), ...props }));
|
|
234
|
+
}
|
|
235
|
+
function EditableQuote({ as = 'blockquote', cite, className = '', style, ...props }) {
|
|
236
|
+
const quoteStyle = {
|
|
237
|
+
fontStyle: 'italic',
|
|
238
|
+
borderLeft: '3px solid var(--brand-color, #2563eb)',
|
|
239
|
+
paddingLeft: '1.25rem',
|
|
240
|
+
margin: '1.5rem 0',
|
|
241
|
+
color: 'var(--muted-text, #64748b)',
|
|
242
|
+
...style,
|
|
243
|
+
};
|
|
244
|
+
return ((0, jsx_runtime_1.jsx)(EditableText, { as: as, style: quoteStyle, className: `editable-quote ${className}`.trim(), ...(cite ? { cite } : {}), ...props }));
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* EditableLink enforces Fivora's strict selected-page contract:
|
|
248
|
+
* - Injects data-target-page on wrapper
|
|
249
|
+
* - Omits rendering if targetPage is not in requirements.requiredPages
|
|
250
|
+
*/
|
|
251
|
+
function EditableLink({ id, 'data-preview-field-path': previewFieldPath, targetPage, defaultValue, href = '#', children, className = '', ...props }) {
|
|
252
|
+
const path = previewFieldPath || id;
|
|
253
|
+
const content = children !== undefined ? children : defaultValue;
|
|
254
|
+
const linkEl = ((0, jsx_runtime_1.jsx)("a", { href: href, className: `editable-link ${className}`.trim(), ...props, children: path ? ((0, jsx_runtime_1.jsx)("span", { "data-preview-field-path": path, children: content })) : (content) }));
|
|
255
|
+
if (targetPage) {
|
|
256
|
+
return (0, jsx_runtime_1.jsx)("span", { "data-target-page": targetPage, children: linkEl });
|
|
257
|
+
}
|
|
258
|
+
return linkEl;
|
|
259
|
+
}
|
|
260
|
+
function EditableButton({ id, 'data-preview-field-path': previewFieldPath, defaultValue, targetPage, btnVariant = 'primary', size = 'md', children, className = '', style, ...props }) {
|
|
261
|
+
const path = previewFieldPath || id;
|
|
262
|
+
const content = children !== undefined ? children : defaultValue;
|
|
263
|
+
const sizeStyles = {
|
|
264
|
+
sm: { padding: '0.375rem 0.875rem', fontSize: '0.875rem', borderRadius: '6px' },
|
|
265
|
+
md: { padding: '0.625rem 1.25rem', fontSize: '1rem', borderRadius: '8px' },
|
|
266
|
+
lg: { padding: '0.875rem 1.75rem', fontSize: '1.125rem', borderRadius: '12px' },
|
|
267
|
+
};
|
|
268
|
+
const variantStyles = {
|
|
269
|
+
primary: {
|
|
270
|
+
backgroundColor: 'var(--brand-color, #2563eb)',
|
|
271
|
+
color: '#ffffff',
|
|
272
|
+
border: 'none',
|
|
273
|
+
boxShadow: '0 4px 14px 0 rgba(37, 99, 235, 0.35)',
|
|
274
|
+
},
|
|
275
|
+
secondary: {
|
|
276
|
+
backgroundColor: 'var(--brand-secondary, #0f172a)',
|
|
277
|
+
color: '#ffffff',
|
|
278
|
+
border: 'none',
|
|
279
|
+
},
|
|
280
|
+
accent: {
|
|
281
|
+
backgroundColor: 'var(--brand-accent, #14b8a6)',
|
|
282
|
+
color: '#ffffff',
|
|
283
|
+
border: 'none',
|
|
284
|
+
},
|
|
285
|
+
outline: {
|
|
286
|
+
backgroundColor: 'transparent',
|
|
287
|
+
color: 'var(--page-text, #0f172a)',
|
|
288
|
+
border: '1.5px solid currentColor',
|
|
289
|
+
},
|
|
290
|
+
ghost: {
|
|
291
|
+
backgroundColor: 'transparent',
|
|
292
|
+
color: 'var(--page-text, #0f172a)',
|
|
293
|
+
border: 'none',
|
|
294
|
+
},
|
|
295
|
+
glass: {
|
|
296
|
+
backgroundColor: 'rgba(255, 255, 255, 0.25)',
|
|
297
|
+
backdropFilter: 'blur(12px)',
|
|
298
|
+
WebkitBackdropFilter: 'blur(12px)',
|
|
299
|
+
color: 'var(--page-text, #0f172a)',
|
|
300
|
+
border: '1px solid rgba(255, 255, 255, 0.4)',
|
|
301
|
+
},
|
|
302
|
+
};
|
|
303
|
+
const baseStyle = {
|
|
304
|
+
display: 'inline-flex',
|
|
305
|
+
alignItems: 'center',
|
|
306
|
+
justifyContent: 'center',
|
|
307
|
+
fontWeight: 600,
|
|
308
|
+
cursor: 'pointer',
|
|
309
|
+
transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)',
|
|
310
|
+
...sizeStyles[size],
|
|
311
|
+
...variantStyles[btnVariant],
|
|
312
|
+
...style,
|
|
313
|
+
};
|
|
314
|
+
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) }));
|
|
315
|
+
if (targetPage) {
|
|
316
|
+
return (0, jsx_runtime_1.jsx)("span", { "data-target-page": targetPage, children: buttonEl });
|
|
317
|
+
}
|
|
318
|
+
return buttonEl;
|
|
319
|
+
}
|