@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.
Files changed (84) hide show
  1. package/README.md +182 -0
  2. package/dist/EditableBox.d.ts +56 -0
  3. package/dist/EditableBox.js +113 -0
  4. package/dist/EditableCard.d.ts +48 -0
  5. package/dist/EditableCard.js +85 -0
  6. package/dist/EditableContactForm.d.ts +11 -0
  7. package/dist/EditableContactForm.js +146 -0
  8. package/dist/EditableDialog.d.ts +25 -0
  9. package/dist/EditableDialog.js +145 -0
  10. package/dist/EditableFAQAccordion.d.ts +19 -0
  11. package/dist/EditableFAQAccordion.js +62 -0
  12. package/dist/EditableFooter.d.ts +31 -0
  13. package/dist/EditableFooter.js +330 -0
  14. package/dist/EditableGrid.d.ts +40 -0
  15. package/dist/EditableGrid.js +39 -0
  16. package/dist/EditableHero.d.ts +27 -0
  17. package/dist/EditableHero.js +154 -0
  18. package/dist/EditableImage.d.ts +13 -0
  19. package/dist/EditableImage.js +38 -0
  20. package/dist/EditableList.d.ts +33 -0
  21. package/dist/EditableList.js +19 -0
  22. package/dist/EditableNavbar.d.ts +28 -0
  23. package/dist/EditableNavbar.js +178 -0
  24. package/dist/EditablePricingCard.d.ts +31 -0
  25. package/dist/EditablePricingCard.js +93 -0
  26. package/dist/EditableProductCard.d.ts +60 -0
  27. package/dist/EditableProductCard.js +116 -0
  28. package/dist/EditableSection.d.ts +35 -0
  29. package/dist/EditableSection.js +34 -0
  30. package/dist/EditableServiceCard.d.ts +38 -0
  31. package/dist/EditableServiceCard.js +28 -0
  32. package/dist/EditableTestimonialCard.d.ts +17 -0
  33. package/dist/EditableTestimonialCard.js +46 -0
  34. package/dist/EditableText.d.ts +117 -0
  35. package/dist/EditableText.js +319 -0
  36. package/dist/SiteDataProvider.d.ts +61 -0
  37. package/dist/SiteDataProvider.js +316 -0
  38. package/dist/ThemeStyles.d.ts +46 -0
  39. package/dist/ThemeStyles.js +181 -0
  40. package/dist/business/BusinessHours.d.ts +20 -0
  41. package/dist/business/BusinessHours.js +109 -0
  42. package/dist/business/index.d.ts +1 -0
  43. package/dist/business/index.js +17 -0
  44. package/dist/contact/ContactActions.d.ts +24 -0
  45. package/dist/contact/ContactActions.js +30 -0
  46. package/dist/contact/ContactButton.d.ts +15 -0
  47. package/dist/contact/ContactButton.js +94 -0
  48. package/dist/contact/EmailButton.d.ts +6 -0
  49. package/dist/contact/EmailButton.js +12 -0
  50. package/dist/contact/PhoneButton.d.ts +6 -0
  51. package/dist/contact/PhoneButton.js +12 -0
  52. package/dist/contact/WhatsAppButton.d.ts +6 -0
  53. package/dist/contact/WhatsAppButton.js +13 -0
  54. package/dist/contact/index.d.ts +5 -0
  55. package/dist/contact/index.js +21 -0
  56. package/dist/core/DenebAction.d.ts +19 -0
  57. package/dist/core/DenebAction.js +107 -0
  58. package/dist/core/index.d.ts +1 -0
  59. package/dist/core/index.js +17 -0
  60. package/dist/index.d.ts +61 -0
  61. package/dist/index.js +106 -0
  62. package/dist/location/Address.d.ts +14 -0
  63. package/dist/location/Address.js +26 -0
  64. package/dist/location/LocationCard.d.ts +20 -0
  65. package/dist/location/LocationCard.js +41 -0
  66. package/dist/location/LocationLink.d.ts +18 -0
  67. package/dist/location/LocationLink.js +23 -0
  68. package/dist/location/MapEmbed.d.ts +18 -0
  69. package/dist/location/MapEmbed.js +30 -0
  70. package/dist/location/MapLink.d.ts +13 -0
  71. package/dist/location/MapLink.js +63 -0
  72. package/dist/location/index.d.ts +5 -0
  73. package/dist/location/index.js +21 -0
  74. package/dist/social/SocialButton.d.ts +11 -0
  75. package/dist/social/SocialButton.js +112 -0
  76. package/dist/social/SocialLinks.d.ts +14 -0
  77. package/dist/social/SocialLinks.js +42 -0
  78. package/dist/social/index.d.ts +2 -0
  79. package/dist/social/index.js +18 -0
  80. package/dist/utils/index.d.ts +1 -0
  81. package/dist/utils/index.js +17 -0
  82. package/dist/utils/urls.d.ts +32 -0
  83. package/dist/utils/urls.js +91 -0
  84. package/package.json +41 -0
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.BusinessHours = BusinessHours;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const react_1 = require("react");
7
+ const DAYS_OF_WEEK = [
8
+ 'monday',
9
+ 'tuesday',
10
+ 'wednesday',
11
+ 'thursday',
12
+ 'friday',
13
+ 'saturday',
14
+ 'sunday',
15
+ ];
16
+ function formatTime(timeStr) {
17
+ if (!timeStr)
18
+ return '';
19
+ const clean = timeStr.trim();
20
+ // If already contains AM/PM
21
+ if (/am|pm/i.test(clean))
22
+ return clean;
23
+ const [hourStr, minStr = '00'] = clean.split(':');
24
+ const hour = parseInt(hourStr, 10);
25
+ if (isNaN(hour))
26
+ return clean;
27
+ const ampm = hour >= 12 ? 'PM' : 'AM';
28
+ const formattedHour = hour % 12 === 0 ? 12 : hour % 12;
29
+ return `${formattedHour}:${minStr.padStart(2, '0')} ${ampm}`;
30
+ }
31
+ /**
32
+ * BusinessHours component displaying weekly operating schedule with live Open/Closed status.
33
+ */
34
+ function BusinessHours({ hours, title = 'Business Hours', fieldPath = 'common.business.hours', showStatusBadge = true, compact = false, className = '', style, }) {
35
+ // Determine current day and status
36
+ const currentStatus = (0, react_1.useMemo)(() => {
37
+ if (!hours)
38
+ return null;
39
+ const now = new Date();
40
+ const dayIndex = (now.getDay() + 6) % 7; // Convert 0(Sun)-6(Sat) to 0(Mon)-6(Sun)
41
+ const todayName = DAYS_OF_WEEK[dayIndex];
42
+ const todaySched = hours[todayName];
43
+ if (!todaySched)
44
+ return { todayName, isOpen: false };
45
+ if (typeof todaySched === 'string') {
46
+ if (/closed/i.test(todaySched))
47
+ return { todayName, isOpen: false };
48
+ return { todayName, isOpen: true };
49
+ }
50
+ if (todaySched.closed || !todaySched.open || !todaySched.close) {
51
+ return { todayName, isOpen: false };
52
+ }
53
+ const currentMinutes = now.getHours() * 60 + now.getMinutes();
54
+ const [openH = '0', openM = '0'] = todaySched.open.split(':');
55
+ const [closeH = '0', closeM = '0'] = todaySched.close.split(':');
56
+ const openMinutes = parseInt(openH, 10) * 60 + parseInt(openM, 10);
57
+ const closeMinutes = parseInt(closeH, 10) * 60 + parseInt(closeM, 10);
58
+ const isOpen = currentMinutes >= openMinutes && currentMinutes < closeMinutes;
59
+ return { todayName, isOpen };
60
+ }, [hours]);
61
+ if (!hours)
62
+ return null;
63
+ const containerStyles = {
64
+ padding: compact ? '1rem' : '1.5rem',
65
+ borderRadius: '0.75rem',
66
+ border: '1px solid var(--color-border, #e2e8f0)',
67
+ backgroundColor: 'var(--color-surface, #ffffff)',
68
+ ...style,
69
+ };
70
+ return ((0, jsx_runtime_1.jsxs)("div", { className: `deneb-business-hours ${className}`.trim(), style: containerStyles, children: [(0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '1rem' }, children: [(0, jsx_runtime_1.jsx)("h4", { style: { margin: 0, fontSize: '1.1rem', fontWeight: 600, color: 'var(--color-text, #0f172a)' }, children: (0, jsx_runtime_1.jsx)("span", { "data-preview-static": "business-hours-title", children: title }) }), showStatusBadge && currentStatus && ((0, jsx_runtime_1.jsxs)("span", { "data-preview-static": "business-hours-status", style: {
71
+ display: 'inline-flex',
72
+ alignItems: 'center',
73
+ gap: '0.35rem',
74
+ padding: '0.2rem 0.6rem',
75
+ borderRadius: '9999px',
76
+ fontSize: '0.75rem',
77
+ fontWeight: 600,
78
+ backgroundColor: currentStatus.isOpen ? '#ecfdf5' : '#f1f5f9',
79
+ color: currentStatus.isOpen ? '#059669' : '#64748b',
80
+ }, children: [(0, jsx_runtime_1.jsx)("span", { style: {
81
+ width: '6px',
82
+ height: '6px',
83
+ borderRadius: '50%',
84
+ backgroundColor: currentStatus.isOpen ? '#10b981' : '#94a3b8',
85
+ } }), currentStatus.isOpen ? 'Open Now' : 'Closed'] }))] }), (0, jsx_runtime_1.jsx)("div", { style: { display: 'flex', flexDirection: 'column', gap: compact ? '0.35rem' : '0.5rem' }, children: DAYS_OF_WEEK.map((day) => {
86
+ const sched = hours[day];
87
+ const isToday = currentStatus?.todayName === day;
88
+ const dayLabel = day.charAt(0).toUpperCase() + day.slice(1);
89
+ let scheduleText = 'Closed';
90
+ if (sched) {
91
+ if (typeof sched === 'string') {
92
+ scheduleText = sched;
93
+ }
94
+ else if (!sched.closed && sched.open && sched.close) {
95
+ scheduleText = `${formatTime(sched.open)} – ${formatTime(sched.close)}`;
96
+ }
97
+ }
98
+ return ((0, jsx_runtime_1.jsxs)("div", { style: {
99
+ display: 'flex',
100
+ justifyContent: 'space-between',
101
+ padding: '0.25rem 0.5rem',
102
+ borderRadius: '0.25rem',
103
+ fontSize: '0.875rem',
104
+ backgroundColor: isToday ? 'var(--color-secondary, #f8fafc)' : 'transparent',
105
+ fontWeight: isToday ? 600 : 400,
106
+ color: isToday ? 'var(--color-primary, #0f172a)' : 'var(--color-text-muted, #475569)',
107
+ }, children: [(0, jsx_runtime_1.jsx)("span", { "data-preview-static": "business-hours-day", children: dayLabel }), (0, jsx_runtime_1.jsx)("span", { "data-preview-field-path": `${fieldPath}.${day}`, children: scheduleText })] }, day));
108
+ }) })] }));
109
+ }
@@ -0,0 +1 @@
1
+ export * from './BusinessHours';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./BusinessHours"), exports);
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ export interface ContactActionsProps {
3
+ phone?: string | null;
4
+ whatsapp?: string | null;
5
+ email?: string | null;
6
+ phoneFieldPath?: string;
7
+ whatsappFieldPath?: string;
8
+ emailFieldPath?: string;
9
+ labels?: {
10
+ phone?: string;
11
+ whatsapp?: string;
12
+ email?: string;
13
+ };
14
+ size?: 'sm' | 'md' | 'lg';
15
+ layout?: 'row' | 'column' | 'wrap';
16
+ className?: string;
17
+ style?: React.CSSProperties;
18
+ }
19
+ /**
20
+ * Smart container that automatically renders available contact channels.
21
+ * When a merchant adds phone, WhatsApp, or email in site-data.json,
22
+ * the corresponding action button appears automatically with zero template code changes.
23
+ */
24
+ export declare function ContactActions({ phone, whatsapp, email, phoneFieldPath, whatsappFieldPath, emailFieldPath, labels, size, layout, className, style, }: ContactActionsProps): React.JSX.Element | null;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.ContactActions = ContactActions;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const WhatsAppButton_1 = require("./WhatsAppButton");
7
+ const PhoneButton_1 = require("./PhoneButton");
8
+ const EmailButton_1 = require("./EmailButton");
9
+ /**
10
+ * Smart container that automatically renders available contact channels.
11
+ * When a merchant adds phone, WhatsApp, or email in site-data.json,
12
+ * the corresponding action button appears automatically with zero template code changes.
13
+ */
14
+ function ContactActions({ phone, whatsapp, email, phoneFieldPath = 'common.business.phone', whatsappFieldPath = 'common.business.whatsapp', emailFieldPath = 'common.business.email', labels = {}, size = 'md', layout = 'row', className = '', style, }) {
15
+ const hasPhone = Boolean(phone && phone.trim());
16
+ const hasWhatsApp = Boolean(whatsapp && whatsapp.trim());
17
+ const hasEmail = Boolean(email && email.trim());
18
+ if (!hasPhone && !hasWhatsApp && !hasEmail) {
19
+ return null;
20
+ }
21
+ const layoutStyles = {
22
+ display: 'flex',
23
+ flexDirection: layout === 'column' ? 'column' : 'row',
24
+ flexWrap: layout === 'wrap' || layout === 'row' ? 'wrap' : 'nowrap',
25
+ alignItems: 'center',
26
+ gap: '0.75rem',
27
+ ...style,
28
+ };
29
+ return ((0, jsx_runtime_1.jsxs)("div", { className: `deneb-contact-actions deneb-layout-${layout} ${className}`.trim(), style: layoutStyles, children: [hasPhone && ((0, jsx_runtime_1.jsx)(PhoneButton_1.PhoneButton, { value: phone, fieldPath: phoneFieldPath, label: labels.phone || 'Call Us', size: size })), hasWhatsApp && ((0, jsx_runtime_1.jsx)(WhatsAppButton_1.WhatsAppButton, { value: whatsapp, fieldPath: whatsappFieldPath, label: labels.whatsapp || 'Chat on WhatsApp', size: size })), hasEmail && ((0, jsx_runtime_1.jsx)(EmailButton_1.EmailButton, { value: email, fieldPath: emailFieldPath, label: labels.email || 'Email Us', size: size }))] }));
30
+ }
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ export type ContactType = 'whatsapp' | 'phone' | 'email' | 'contact-form' | 'custom';
3
+ export interface ContactButtonProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
4
+ type?: ContactType;
5
+ value?: string | null;
6
+ label?: React.ReactNode;
7
+ fieldPath?: string;
8
+ targetPage?: string;
9
+ variant?: 'primary' | 'secondary' | 'outline' | 'ghost' | 'whatsapp';
10
+ size?: 'sm' | 'md' | 'lg';
11
+ icon?: React.ReactNode;
12
+ message?: string;
13
+ subject?: string;
14
+ }
15
+ export declare function ContactButton({ type, value, href, label, children, fieldPath, targetPage, variant, size, icon, message, subject, className, style, ...rest }: ContactButtonProps): React.JSX.Element | null;
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.ContactButton = ContactButton;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const urls_1 = require("../utils/urls");
7
+ function ContactButton({ type = 'whatsapp', value, href, label, children, fieldPath, targetPage, variant, size = 'md', icon, message, subject, className = '', style, ...rest }) {
8
+ // If no fieldPath and no value/href/label/children, do not render broken button
9
+ if (!fieldPath && !value && !href && !children && !label) {
10
+ return null;
11
+ }
12
+ let resolvedHref = href || '#';
13
+ let shouldOpenNewTab = false;
14
+ let defaultIcon = null;
15
+ let resolvedVariant = variant || 'primary';
16
+ switch (type) {
17
+ case 'whatsapp':
18
+ resolvedHref = (0, urls_1.createWhatsAppUrl)(value || href, message);
19
+ shouldOpenNewTab = true;
20
+ if (!variant)
21
+ resolvedVariant = 'whatsapp';
22
+ defaultIcon = ((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: "M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z" }) }));
23
+ break;
24
+ case 'phone':
25
+ resolvedHref = (0, urls_1.createPhoneUrl)(value || href);
26
+ shouldOpenNewTab = false;
27
+ defaultIcon = ((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" }) }));
28
+ break;
29
+ case 'email':
30
+ resolvedHref = (0, urls_1.createEmailUrl)(value || href, subject);
31
+ shouldOpenNewTab = false;
32
+ defaultIcon = ((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)("rect", { width: "20", height: "16", x: "2", y: "4", rx: "2" }), (0, jsx_runtime_1.jsx)("path", { d: "m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7" })] }));
33
+ break;
34
+ case 'contact-form':
35
+ resolvedHref = value || href || '#contact-form';
36
+ defaultIcon = ((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: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }), (0, jsx_runtime_1.jsx)("polyline", { points: "14 2 14 8 20 8" }), (0, jsx_runtime_1.jsx)("line", { x1: "16", x2: "8", y1: "13", y2: "13" }), (0, jsx_runtime_1.jsx)("line", { x1: "16", x2: "8", y1: "17", y2: "17" }), (0, jsx_runtime_1.jsx)("polyline", { points: "10 9 9 9 8 9" })] }));
37
+ break;
38
+ default:
39
+ resolvedHref = value || href || '#';
40
+ break;
41
+ }
42
+ const baseStyles = {
43
+ display: 'inline-flex',
44
+ alignItems: 'center',
45
+ justifyContent: 'center',
46
+ gap: '0.5rem',
47
+ fontWeight: 500,
48
+ textDecoration: 'none',
49
+ transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)',
50
+ cursor: 'pointer',
51
+ borderRadius: '0.5rem',
52
+ ...style,
53
+ };
54
+ const sizeStyles = {
55
+ sm: { fontSize: '0.875rem', padding: '0.4rem 0.75rem' },
56
+ md: { fontSize: '0.95rem', padding: '0.6rem 1.25rem' },
57
+ lg: { fontSize: '1.05rem', padding: '0.75rem 1.6rem' },
58
+ };
59
+ const variantStyles = {
60
+ primary: {
61
+ backgroundColor: 'var(--color-primary, #0f172a)',
62
+ color: '#ffffff',
63
+ boxShadow: '0 1px 2px rgba(0,0,0,0.05)',
64
+ },
65
+ secondary: {
66
+ backgroundColor: 'var(--color-secondary, #f1f5f9)',
67
+ color: 'var(--color-text, #0f172a)',
68
+ },
69
+ outline: {
70
+ backgroundColor: 'transparent',
71
+ border: '1px solid var(--color-border, #e2e8f0)',
72
+ color: 'var(--color-text, #0f172a)',
73
+ },
74
+ ghost: {
75
+ backgroundColor: 'transparent',
76
+ color: 'var(--color-text, #0f172a)',
77
+ },
78
+ whatsapp: {
79
+ backgroundColor: '#25D366',
80
+ color: '#ffffff',
81
+ boxShadow: '0 2px 4px rgba(37, 211, 102, 0.2)',
82
+ },
83
+ };
84
+ const mergedStyles = {
85
+ ...baseStyles,
86
+ ...sizeStyles[size],
87
+ ...variantStyles[resolvedVariant],
88
+ };
89
+ const buttonElement = ((0, jsx_runtime_1.jsxs)("a", { href: resolvedHref, "data-preview-field-path": fieldPath, target: shouldOpenNewTab ? '_blank' : undefined, rel: shouldOpenNewTab ? 'noopener noreferrer' : undefined, className: `deneb-contact-btn deneb-contact-${type} ${className}`.trim(), style: mergedStyles, ...rest, children: [icon !== undefined ? icon : defaultIcon, children || label] }));
90
+ if (targetPage) {
91
+ return ((0, jsx_runtime_1.jsx)("span", { "data-target-page": targetPage, style: { display: 'inline-block' }, children: buttonElement }));
92
+ }
93
+ return buttonElement;
94
+ }
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { ContactButtonProps } from './ContactButton';
3
+ export interface EmailButtonProps extends Omit<ContactButtonProps, 'type'> {
4
+ emailAddress?: string | null;
5
+ }
6
+ export declare function EmailButton({ emailAddress, value, label, fieldPath, variant, subject, ...rest }: EmailButtonProps): React.JSX.Element | null;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.EmailButton = EmailButton;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const ContactButton_1 = require("./ContactButton");
7
+ function EmailButton({ emailAddress, value, label = 'Email Us', fieldPath = 'common.business.email', variant = 'secondary', subject, ...rest }) {
8
+ const email = emailAddress || value;
9
+ if (!email && !fieldPath)
10
+ return null;
11
+ return ((0, jsx_runtime_1.jsx)(ContactButton_1.ContactButton, { type: "email", value: email, label: label, fieldPath: fieldPath, variant: variant, subject: subject, ...rest }));
12
+ }
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { ContactButtonProps } from './ContactButton';
3
+ export interface PhoneButtonProps extends Omit<ContactButtonProps, 'type'> {
4
+ phoneNumber?: string | null;
5
+ }
6
+ export declare function PhoneButton({ phoneNumber, value, label, fieldPath, variant, ...rest }: PhoneButtonProps): React.JSX.Element | null;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.PhoneButton = PhoneButton;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const ContactButton_1 = require("./ContactButton");
7
+ function PhoneButton({ phoneNumber, value, label = 'Call Us', fieldPath = 'common.business.phone', variant = 'primary', ...rest }) {
8
+ const number = phoneNumber || value;
9
+ if (!number && !fieldPath)
10
+ return null;
11
+ return ((0, jsx_runtime_1.jsx)(ContactButton_1.ContactButton, { type: "phone", value: number, label: label, fieldPath: fieldPath, variant: variant, ...rest }));
12
+ }
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { ContactButtonProps } from './ContactButton';
3
+ export interface WhatsAppButtonProps extends Omit<ContactButtonProps, 'type'> {
4
+ phoneNumber?: string | null;
5
+ }
6
+ export declare function WhatsAppButton({ phoneNumber, value, label, fieldPath, variant, message, ...rest }: WhatsAppButtonProps): React.JSX.Element | null;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.WhatsAppButton = WhatsAppButton;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const ContactButton_1 = require("./ContactButton");
7
+ function WhatsAppButton({ phoneNumber, value, label = 'Chat on WhatsApp', fieldPath = 'common.business.whatsapp', variant = 'whatsapp', message, ...rest }) {
8
+ const number = phoneNumber || value;
9
+ // Don't render if no number and no fieldPath configured
10
+ if (!number && !fieldPath)
11
+ return null;
12
+ return ((0, jsx_runtime_1.jsx)(ContactButton_1.ContactButton, { type: "whatsapp", value: number, label: label, fieldPath: fieldPath, variant: variant, message: message, ...rest }));
13
+ }
@@ -0,0 +1,5 @@
1
+ export * from './ContactButton';
2
+ export * from './WhatsAppButton';
3
+ export * from './PhoneButton';
4
+ export * from './EmailButton';
5
+ export * from './ContactActions';
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./ContactButton"), exports);
18
+ __exportStar(require("./WhatsAppButton"), exports);
19
+ __exportStar(require("./PhoneButton"), exports);
20
+ __exportStar(require("./EmailButton"), exports);
21
+ __exportStar(require("./ContactActions"), exports);
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ export type DenebActionType = 'whatsapp' | 'phone' | 'email' | 'location' | 'page' | 'external' | 'custom';
3
+ export interface DenebActionProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
4
+ type?: DenebActionType;
5
+ value?: string | null;
6
+ fieldPath?: string;
7
+ targetPage?: string;
8
+ label?: React.ReactNode;
9
+ children?: React.ReactNode;
10
+ openInNewTab?: boolean;
11
+ variant?: 'primary' | 'secondary' | 'outline' | 'ghost' | 'link';
12
+ size?: 'sm' | 'md' | 'lg';
13
+ icon?: React.ReactNode;
14
+ }
15
+ export declare function DenebAction({ type, value, href, fieldPath, targetPage, label, children, openInNewTab, variant, size, icon, className, style, ...rest }: DenebActionProps): React.JSX.Element | null;
16
+ /**
17
+ * Smart action link alias
18
+ */
19
+ export declare const ActionLink: typeof DenebAction;
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.ActionLink = void 0;
5
+ exports.DenebAction = DenebAction;
6
+ const jsx_runtime_1 = require("react/jsx-runtime");
7
+ const urls_1 = require("../utils/urls");
8
+ function DenebAction({ type = 'custom', value, href, fieldPath, targetPage, label, children, openInNewTab, variant = 'primary', size = 'md', icon, className = '', style, ...rest }) {
9
+ // Derive destination URL
10
+ let resolvedHref = href || value || '#';
11
+ let shouldOpenNewTab = openInNewTab;
12
+ switch (type) {
13
+ case 'whatsapp':
14
+ resolvedHref = (0, urls_1.createWhatsAppUrl)(value || href);
15
+ if (shouldOpenNewTab === undefined)
16
+ shouldOpenNewTab = true;
17
+ break;
18
+ case 'phone':
19
+ resolvedHref = (0, urls_1.createPhoneUrl)(value || href);
20
+ if (shouldOpenNewTab === undefined)
21
+ shouldOpenNewTab = false;
22
+ break;
23
+ case 'email':
24
+ resolvedHref = (0, urls_1.createEmailUrl)(value || href);
25
+ if (shouldOpenNewTab === undefined)
26
+ shouldOpenNewTab = false;
27
+ break;
28
+ case 'location':
29
+ resolvedHref = (0, urls_1.createMapUrl)(value || href);
30
+ if (shouldOpenNewTab === undefined)
31
+ shouldOpenNewTab = true;
32
+ break;
33
+ case 'external':
34
+ if (shouldOpenNewTab === undefined)
35
+ shouldOpenNewTab = true;
36
+ break;
37
+ case 'page':
38
+ if (shouldOpenNewTab === undefined)
39
+ shouldOpenNewTab = false;
40
+ break;
41
+ default:
42
+ break;
43
+ }
44
+ // If no valid destination could be generated and no children/label, don't render empty broken link
45
+ if (!resolvedHref && !children && !label) {
46
+ return null;
47
+ }
48
+ const baseStyles = {
49
+ display: 'inline-flex',
50
+ alignItems: 'center',
51
+ justifyContent: 'center',
52
+ gap: '0.5rem',
53
+ fontWeight: 500,
54
+ textDecoration: 'none',
55
+ transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)',
56
+ cursor: 'pointer',
57
+ borderRadius: '0.5rem',
58
+ ...style,
59
+ };
60
+ const sizeStyles = {
61
+ sm: { fontSize: '0.875rem', padding: '0.4rem 0.75rem' },
62
+ md: { fontSize: '0.95rem', padding: '0.6rem 1.2rem' },
63
+ lg: { fontSize: '1.05rem', padding: '0.75rem 1.6rem' },
64
+ };
65
+ const variantStyles = {
66
+ primary: {
67
+ backgroundColor: 'var(--color-primary, #0f172a)',
68
+ color: '#ffffff',
69
+ boxShadow: '0 1px 2px rgba(0,0,0,0.05)',
70
+ },
71
+ secondary: {
72
+ backgroundColor: 'var(--color-secondary, #f1f5f9)',
73
+ color: 'var(--color-text, #0f172a)',
74
+ },
75
+ outline: {
76
+ backgroundColor: 'transparent',
77
+ border: '1px solid var(--color-border, #e2e8f0)',
78
+ color: 'var(--color-text, #0f172a)',
79
+ },
80
+ ghost: {
81
+ backgroundColor: 'transparent',
82
+ color: 'var(--color-text, #0f172a)',
83
+ },
84
+ link: {
85
+ backgroundColor: 'transparent',
86
+ color: 'var(--color-primary, #2563eb)',
87
+ padding: 0,
88
+ textDecoration: 'underline',
89
+ borderRadius: 0,
90
+ },
91
+ };
92
+ const mergedStyles = {
93
+ ...baseStyles,
94
+ ...(variant !== 'link' ? sizeStyles[size] : {}),
95
+ ...variantStyles[variant],
96
+ };
97
+ const linkElement = ((0, jsx_runtime_1.jsxs)("a", { href: resolvedHref, "data-preview-field-path": fieldPath, target: shouldOpenNewTab ? '_blank' : undefined, rel: shouldOpenNewTab ? 'noopener noreferrer' : undefined, className: `deneb-action deneb-action-${type} deneb-action-${variant} ${className}`.trim(), style: mergedStyles, ...rest, children: [icon && (0, jsx_runtime_1.jsx)("span", { className: "deneb-action-icon", children: icon }), children || label] }));
98
+ // If targetPage is provided, wrap in span with data-target-page for platform route-pruning compliance
99
+ if (targetPage) {
100
+ return ((0, jsx_runtime_1.jsx)("span", { "data-target-page": targetPage, style: { display: 'inline-block' }, children: linkElement }));
101
+ }
102
+ return linkElement;
103
+ }
104
+ /**
105
+ * Smart action link alias
106
+ */
107
+ exports.ActionLink = DenebAction;
@@ -0,0 +1 @@
1
+ export * from './DenebAction';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./DenebAction"), exports);
@@ -0,0 +1,61 @@
1
+ /**
2
+ * DENEB UI — The Visual-First React Framework for High-Converting Storefronts
3
+ * Created by Chamika Gayashan (CEE G)
4
+ */
5
+ export * from './EditableText';
6
+ export * from './EditableImage';
7
+ export * from './EditableList';
8
+ export * from './EditableBox';
9
+ export * from './EditableGrid';
10
+ export * from './EditableSection';
11
+ export * from './EditableProductCard';
12
+ export * from './EditableServiceCard';
13
+ export * from './EditableCard';
14
+ export * from './EditablePricingCard';
15
+ export * from './EditableTestimonialCard';
16
+ export * from './EditableFAQAccordion';
17
+ export * from './EditableContactForm';
18
+ export * from './EditableNavbar';
19
+ export * from './EditableFooter';
20
+ export * from './EditableHero';
21
+ export * from './EditableDialog';
22
+ export * from './ThemeStyles';
23
+ export * from './SiteDataProvider';
24
+ export * from './utils';
25
+ export * from './core';
26
+ export * from './contact';
27
+ export * from './location';
28
+ export * from './social';
29
+ export * from './business';
30
+ export { EditableButton as Button } from './EditableText';
31
+ export { EditableCard as Card } from './EditableCard';
32
+ export { EditableDialog as Dialog } from './EditableDialog';
33
+ export { EditableText as Text } from './EditableText';
34
+ export { EditableHeading as Heading } from './EditableText';
35
+ export { EditableParagraph as Paragraph } from './EditableText';
36
+ export { EditableBadge as Badge } from './EditableText';
37
+ export { EditableQuote as Quote } from './EditableText';
38
+ export { EditableImage as Image } from './EditableImage';
39
+ export { EditableGrid as Grid } from './EditableGrid';
40
+ export { EditableSection as Section } from './EditableSection';
41
+ export { EditableBox as Box } from './EditableBox';
42
+ export { EditableList as List } from './EditableList';
43
+ export { EditableProductCard as ProductCard } from './EditableProductCard';
44
+ export { EditableServiceCard as ServiceCard } from './EditableServiceCard';
45
+ export { EditablePricingCard as PricingCard } from './EditablePricingCard';
46
+ export { EditableTestimonialCard as TestimonialCard } from './EditableTestimonialCard';
47
+ export { EditableFAQAccordion as Accordion, EditableFAQAccordion as FAQ } from './EditableFAQAccordion';
48
+ export { EditableContactForm as ContactForm } from './EditableContactForm';
49
+ export { EditableNavbar as Navbar, EditableNavbar as Header } from './EditableNavbar';
50
+ export { EditableFooter as Footer } from './EditableFooter';
51
+ export { EditableHeroCentered as Hero, EditableHeroSplit as HeroSplit } from './EditableHero';
52
+ /**
53
+ * DENEB UI Framework Metadata
54
+ * Developed by Chamika Gayashan (CEE G)
55
+ */
56
+ export declare const DENEB_FRAMEWORK_NAME = "DENEB UI";
57
+ export declare const DENEB_FRAMEWORK_VERSION = "2.0.0";
58
+ export declare const DENEB_AUTHOR = "Chamika Gayashan (CEE G)";
59
+ export declare const CEEG_FRAMEWORK_NAME = "DENEB UI";
60
+ export declare const CEEG_FRAMEWORK_VERSION = "2.0.0";
61
+ export declare const CEEG_AUTHOR = "Chamika Gayashan (CEE G)";