@deneb-ui/ui 2.0.124 → 2.0.126

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 CHANGED
@@ -735,6 +735,63 @@ export function FullStorefrontDemo() {
735
735
 
736
736
  ---
737
737
 
738
+ ## EditableBox container styles
739
+
740
+ Use `stylePath` to give a container its own card style target without treating
741
+ its child text as a single content field. Contact starter cards use
742
+ `contact.informationCard` and `contact.formCard` in both templates. For example,
743
+ `styles['contact.informationCard'] = { backgroundColor: '#f0fdf4', paddingTop: 0,
744
+ paddingBottom: 24, paddingLeft: 24, paddingRight: 24, marginTop: 8, gap: 16 }`.
745
+ These are root `styles` entries, not new content fields. Unedited boxes retain
746
+ their existing props and class-based appearance. Saved styles override defaults;
747
+ legacy content-suffix spacing remains supported. Gap affects a box's direct
748
+ flex/grid children, not a nested form's internal spacing.
749
+
750
+ In Local Lab, select the card's empty background/padding area to target its
751
+ container. Text remains independently editable. Test background, each padding
752
+ edge (including zero), margins, and flex/grid gap, then save/reload. The bridge
753
+ forwards card style metadata; actual Inspector controls depend on the connected
754
+ Fivora editor. Run `node scripts/box-editing.test.cjs` after building core/UI.
755
+
756
+ ## Footer headings and contact icons
757
+
758
+ Built-in `EditableIcon` glyphs with a `fieldPath` now use an HTML span as their
759
+ editing boundary, matching the existing custom-icon branches. The SVG remains
760
+ inside it with its original size and SVG attributes; the field and icon-picker
761
+ markers occur only on the wrapper. This lets HTML-based editor selection resolve
762
+ clicks on SVG paths to the icon field rather than a neighboring text field.
763
+ Icons without a `fieldPath` continue to render a bare SVG.
764
+
765
+ `Footer` reuses `EditableText` for `common.footerExploreHeading` and
766
+ `common.footerContactHeading`, including text style targets. It reuses
767
+ `EditableIcon` for `common.footerEmailIcon`, `common.footerPhoneIcon`, and
768
+ `common.footerLocationIcon`. These are content-relative paths under
769
+ `content.common`; default icon names are `mail`, `phone`, and `map-pin`.
770
+ The starter schemas declare the icons as text with `control: 'icon-picker'`.
771
+ Contact icons appear alongside their corresponding nonempty contact values.
772
+ Missing fields retain the original headings/icons; blank headings remain
773
+ editable through placeholders. Verify heading text/typography and icon selection
774
+ in the Lab, then save/reload. Contact values and destinations are independent
775
+ of icon selection.
776
+
777
+ ## Footer newsletter description
778
+
779
+ The newsletter also exposes `content.common.newsletterSubscribeLabel` and
780
+ `content.common.newsletterEmailPlaceholder`. The button label reuses
781
+ `EditableText`; the email input uses the existing input-placeholder field binding
782
+ pattern. The visitor's entered email remains separate from the editable
783
+ placeholder. Both starter schemas declare these as text fields. Original copy
784
+ is the fallback when fields are missing; blank placeholder values are preserved.
785
+ Verify edits and save/reload in Local Lab, plus newsletter submission in Preview.
786
+
787
+ `Footer` / `EditableFooter` reuses `EditableText` for
788
+ `content.common.newsletterDescription`. Its field and text style target are
789
+ `common.newsletterDescription`; saved typography lives at
790
+ `styles['common.newsletterDescription']`. Missing data uses the original copy;
791
+ an empty string keeps an editable placeholder. Both starter templates declare
792
+ the field as a textarea. With newsletters enabled, edit the paragraph in the
793
+ Lab, save, and reload to verify persistence.
794
+
738
795
  ## Authors
739
796
 
740
797
  Created and maintained by **[Chamika Gayashan](https://github.com/chamikathereal)** and **[Induranga Kawishwara](https://github.com/Induranga-kawishwara)**.
@@ -5,6 +5,8 @@ export type BoxSpacing = 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | (st
5
5
  export type BoxAspectRatio = '1/1' | '16/9' | '4/3' | '3/4' | '9/16' | '2/3' | '3/2' | 'square' | 'video' | 'portrait' | 'landscape' | (string & {});
6
6
  export interface EditableBoxProps extends React.HTMLAttributes<HTMLElement> {
7
7
  as?: React.ElementType;
8
+ /** Independent container style target; does not mark child content as one text field. */
9
+ stylePath?: string;
8
10
  /**
9
11
  * Field path or item path in siteData.
10
12
  */
@@ -53,4 +55,4 @@ export interface EditableBoxProps extends React.HTMLAttributes<HTMLElement> {
53
55
  * EditableBox is a flexible, smart container ("div-like") component with built-in
54
56
  * width/height resizing, aspect-ratio controls, and auto-balancing for fivora cards.
55
57
  */
56
- export declare function EditableBox({ as: Component, id, 'data-preview-field-path': previewFieldPath, 'data-preview-item-path': previewItemPath, 'data-preview-static': previewStatic, width, minWidth, maxWidth, height, minHeight, maxHeight, aspectRatio, balance, grow, shrink, padding, margin, bg, color, radius, shadow, border, display, direction, wrap, align, justify, gap, overflow, style, children, className, ...props }: EditableBoxProps): React.JSX.Element;
58
+ export declare function EditableBox({ as: Component, stylePath, id, 'data-preview-field-path': previewFieldPath, 'data-preview-item-path': previewItemPath, 'data-preview-static': previewStatic, width, minWidth, maxWidth, height, minHeight, maxHeight, aspectRatio, balance, grow, shrink, padding, margin, bg, color, radius, shadow, border, display, direction, wrap, align, justify, gap, overflow, style, children, className, ...props }: EditableBoxProps): React.JSX.Element;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.EditableBox = EditableBox;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const SiteDataProvider_1 = require("./SiteDataProvider");
6
+ const useComponentStyle_1 = require("./hooks/useComponentStyle");
6
7
  const RADIUS_MAP = {
7
8
  none: '0px',
8
9
  sm: '4px',
@@ -46,7 +47,7 @@ const ASPECT_MAP = {
46
47
  * EditableBox is a flexible, smart container ("div-like") component with built-in
47
48
  * width/height resizing, aspect-ratio controls, and auto-balancing for fivora cards.
48
49
  */
49
- function EditableBox({ as: Component = 'div', id, 'data-preview-field-path': previewFieldPath, 'data-preview-item-path': previewItemPath, 'data-preview-static': previewStatic, width, minWidth, maxWidth, height, minHeight, maxHeight, aspectRatio, balance, grow, shrink, padding, margin, bg, color, radius, shadow, border, display, direction, wrap, align, justify, gap, overflow, style, children, className = '', ...props }) {
50
+ function EditableBox({ as: Component = 'div', stylePath, id, 'data-preview-field-path': previewFieldPath, 'data-preview-item-path': previewItemPath, 'data-preview-static': previewStatic, width, minWidth, maxWidth, height, minHeight, maxHeight, aspectRatio, balance, grow, shrink, padding, margin, bg, color, radius, shadow, border, display, direction, wrap, align, justify, gap, overflow, style, children, className = '', ...props }) {
50
51
  const resolvedRadius = radius !== undefined ? (RADIUS_MAP[String(radius)] || String(radius)) : undefined;
51
52
  const resolvedShadow = shadow ? (SHADOW_MAP[shadow] || shadow) : undefined;
52
53
  const resolvedPadding = padding !== undefined ? (SPACING_MAP[String(padding)] || String(padding)) : undefined;
@@ -72,6 +73,24 @@ function EditableBox({ as: Component = 'div', id, 'data-preview-field-path': pre
72
73
  ? border
73
74
  : undefined;
74
75
  const path = previewFieldPath || id || previewItemPath;
76
+ const effectiveStylePath = stylePath ?? path;
77
+ const { cssVars } = (0, useComponentStyle_1.useComponentStyle)(effectiveStylePath, 'card');
78
+ const variables = cssVars;
79
+ const containerStyle = {};
80
+ // Only set persisted values: unedited CSS classes and existing props keep their defaults.
81
+ const bindings = {
82
+ backgroundColor: '--deneb-card-bg',
83
+ paddingTop: '--deneb-card-pt', paddingBottom: '--deneb-card-pb',
84
+ paddingLeft: '--deneb-card-pl', paddingRight: '--deneb-card-pr',
85
+ marginTop: '--deneb-card-margin-top', marginBottom: '--deneb-card-margin-bottom',
86
+ marginLeft: '--deneb-card-margin-left', marginRight: '--deneb-card-margin-right',
87
+ gap: '--deneb-card-gap',
88
+ };
89
+ for (const [property, variable] of Object.entries(bindings)) {
90
+ if (variables[variable] !== undefined) {
91
+ Object.assign(containerStyle, { [property]: `var(${variable})` });
92
+ }
93
+ }
75
94
  const dynamicStyle = (0, SiteDataProvider_1.useFieldStyle)(path);
76
95
  const dynamicMarginTop = dynamicStyle?.spacingTop !== undefined && dynamicStyle?.spacingTop !== '' ? `${dynamicStyle.spacingTop}px` : undefined;
77
96
  const dynamicMarginBottom = dynamicStyle?.spacingBottom !== undefined && dynamicStyle?.spacingBottom !== '' ? `${dynamicStyle.spacingBottom}px` : undefined;
@@ -108,6 +127,8 @@ function EditableBox({ as: Component = 'div', id, 'data-preview-field-path': pre
108
127
  ...(dynamicMarginLeft ? { marginLeft: dynamicMarginLeft } : {}),
109
128
  ...(dynamicMarginRight ? { marginRight: dynamicMarginRight } : {}),
110
129
  ...(dynamicStyle?.color ? { color: String(dynamicStyle.color) } : {}),
130
+ ...cssVars,
131
+ ...containerStyle,
111
132
  };
112
- return ((0, jsx_runtime_1.jsx)(Component, { "data-preview-field-path": previewFieldPath || id, "data-preview-item-path": previewItemPath, "data-preview-static": previewStatic, className: `editable-box ${className}`.trim(), style: boxStyle, ...props, children: children }));
133
+ return ((0, jsx_runtime_1.jsx)(Component, { "data-preview-field-path": previewFieldPath || id, "data-preview-item-path": previewItemPath, "data-preview-static": previewStatic, "data-preview-style-target": effectiveStylePath, "data-preview-style-type": effectiveStylePath ? 'card' : undefined, className: `editable-box ${className}`.trim(), style: boxStyle, ...props, children: children }));
113
134
  }
@@ -7,6 +7,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
7
7
  const react_1 = require("react");
8
8
  const SiteDataProvider_1 = require("./SiteDataProvider");
9
9
  const EditableText_1 = require("./EditableText");
10
+ const EditableIcon_1 = require("./EditableIcon");
10
11
  const DEFAULT_FOOTER_PAGES = [
11
12
  { id: 'home', label: 'Home', route: '/' },
12
13
  { id: 'about_us', label: 'About', route: '/about_us' },
@@ -226,14 +227,9 @@ function EditableFooter({ defaultLinks = DEFAULT_FOOTER_PAGES, links, basePath =
226
227
  textDecoration: 'none',
227
228
  transition: 'all 0.15s ease',
228
229
  }, className: "w-8 h-8 rounded-lg bg-slate-900 border border-slate-800 flex items-center justify-center text-slate-400 hover:text-white hover:border-slate-700 hover:bg-slate-800 transition-all", children: iconConfig.icon }, platformKey));
229
- }) })] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h4", { "data-preview-static": "footer-explore-heading", style: {
230
- fontSize: '0.8125rem',
231
- fontWeight: 700,
232
- textTransform: 'uppercase',
233
- letterSpacing: '0.08em',
234
- color: '#f1f5f9',
230
+ }) })] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(EditableText_1.EditableText, { as: "h4", fieldPath: "common.footerExploreHeading", defaultValue: common.footerExploreHeading ?? 'Explore', placeholder: "Add a navigation heading", size: "0.8125rem", weight: 700, transform: "uppercase", letterSpacing: "0.08em", color: "#f1f5f9", style: {
235
231
  marginBottom: '1.25rem',
236
- }, className: "text-xs font-bold uppercase tracking-wider text-slate-200 mb-5", children: "Explore" }), (0, jsx_runtime_1.jsx)("ul", { style: {
232
+ }, className: "text-xs font-bold uppercase tracking-wider text-slate-200 mb-5" }), (0, jsx_runtime_1.jsx)("ul", { style: {
237
233
  listStyle: 'none',
238
234
  padding: 0,
239
235
  margin: 0,
@@ -265,20 +261,15 @@ function EditableFooter({ defaultLinks = DEFAULT_FOOTER_PAGES, links, basePath =
265
261
  }
266
262
  // Unselected route marker fallback (visible for strict schema coverage without route link)
267
263
  return ((0, jsx_runtime_1.jsx)("li", { className: "unavailable", children: (0, jsx_runtime_1.jsx)("span", { "data-target-page": link.id, children: (0, jsx_runtime_1.jsx)("span", { "data-preview-field-path": `common.navLabels.${link.id}`, children: label }) }) }, link.id));
268
- }) })] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h4", { "data-preview-static": "footer-contact-heading", style: {
269
- fontSize: '0.8125rem',
270
- fontWeight: 700,
271
- textTransform: 'uppercase',
272
- letterSpacing: '0.08em',
273
- color: '#f1f5f9',
264
+ }) })] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(EditableText_1.EditableText, { as: "h4", fieldPath: "common.footerContactHeading", defaultValue: common.footerContactHeading ?? 'Contact & Support', placeholder: "Add a contact heading", size: "0.8125rem", weight: 700, transform: "uppercase", letterSpacing: "0.08em", color: "#f1f5f9", style: {
274
265
  marginBottom: '1.25rem',
275
- }, className: "text-xs font-bold uppercase tracking-wider text-slate-200 mb-5", children: "Contact & Support" }), (0, jsx_runtime_1.jsxs)("div", { style: {
266
+ }, className: "text-xs font-bold uppercase tracking-wider text-slate-200 mb-5" }), (0, jsx_runtime_1.jsxs)("div", { style: {
276
267
  display: 'flex',
277
268
  flexDirection: 'column',
278
269
  gap: '0.875rem',
279
270
  fontSize: '0.875rem',
280
271
  color: '#94a3b8',
281
- }, className: "flex flex-col gap-3.5 text-sm text-slate-400", children: [emailContact && ((0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', alignItems: 'center', gap: '0.5rem' }, children: [(0, jsx_runtime_1.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "text-slate-500", 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" })] }), (0, jsx_runtime_1.jsx)("a", { href: `mailto:${emailContact}`, "data-preview-field-path": "contact.email", className: "hover:text-white transition-colors", style: { color: 'inherit', textDecoration: 'none' }, children: emailContact })] })), phone && ((0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', alignItems: 'center', gap: '0.5rem' }, children: [(0, jsx_runtime_1.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "text-slate-500", 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.jsx)("a", { href: `tel:${phone}`, "data-preview-field-path": "contact.phone", className: "hover:text-white transition-colors", style: { color: 'inherit', textDecoration: 'none' }, children: phone })] })), address && ((0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', alignItems: 'flex-start', gap: '0.5rem' }, children: [(0, jsx_runtime_1.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "text-slate-500 mt-0.5", children: [(0, jsx_runtime_1.jsx)("path", { d: "M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z" }), (0, jsx_runtime_1.jsx)("circle", { cx: "12", cy: "10", r: "3" })] }), (0, jsx_runtime_1.jsx)("span", { "data-preview-field-path": "contact.address", children: address })] })), hasContact && ((0, jsx_runtime_1.jsx)("div", { style: { marginTop: '0.5rem' }, children: (0, jsx_runtime_1.jsxs)("a", { href: whatsappHref, target: "_blank", rel: "noopener noreferrer", "data-preview-field-path": "contact.whatsapp", "aria-label": "Direct message on WhatsApp", style: {
272
+ }, className: "flex flex-col gap-3.5 text-sm text-slate-400", children: [emailContact && ((0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', alignItems: 'center', gap: '0.5rem' }, children: [(0, jsx_runtime_1.jsx)(EditableIcon_1.EditableIcon, { name: "mail", fieldPath: "common.footerEmailIcon", size: 14, className: "text-slate-500" }), (0, jsx_runtime_1.jsx)("a", { href: `mailto:${emailContact}`, "data-preview-field-path": "contact.email", className: "hover:text-white transition-colors", style: { color: 'inherit', textDecoration: 'none' }, children: emailContact })] })), phone && ((0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', alignItems: 'center', gap: '0.5rem' }, children: [(0, jsx_runtime_1.jsx)(EditableIcon_1.EditableIcon, { name: "phone", fieldPath: "common.footerPhoneIcon", size: 14, className: "text-slate-500" }), (0, jsx_runtime_1.jsx)("a", { href: `tel:${phone}`, "data-preview-field-path": "contact.phone", className: "hover:text-white transition-colors", style: { color: 'inherit', textDecoration: 'none' }, children: phone })] })), address && ((0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', alignItems: 'flex-start', gap: '0.5rem' }, children: [(0, jsx_runtime_1.jsx)(EditableIcon_1.EditableIcon, { name: "map-pin", fieldPath: "common.footerLocationIcon", size: 14, className: "text-slate-500 mt-0.5" }), (0, jsx_runtime_1.jsx)("span", { "data-preview-field-path": "contact.address", children: address })] })), hasContact && ((0, jsx_runtime_1.jsx)("div", { style: { marginTop: '0.5rem' }, children: (0, jsx_runtime_1.jsxs)("a", { href: whatsappHref, target: "_blank", rel: "noopener noreferrer", "data-preview-field-path": "contact.whatsapp", "aria-label": "Direct message on WhatsApp", style: {
282
273
  display: 'inline-flex',
283
274
  alignItems: 'center',
284
275
  gap: '0.375rem',
@@ -298,12 +289,9 @@ function EditableFooter({ defaultLinks = DEFAULT_FOOTER_PAGES, links, basePath =
298
289
  letterSpacing: '0.08em',
299
290
  color: '#f1f5f9',
300
291
  marginBottom: '1rem',
301
- }, className: "text-xs font-bold uppercase tracking-wider text-slate-200 mb-4", children: footerHeading }), showNewsletter && ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-3", children: [(0, jsx_runtime_1.jsx)("p", { "data-preview-static": "newsletter-description", style: {
302
- fontSize: '0.8125rem',
303
- color: '#94a3b8',
304
- lineHeight: 1.5,
292
+ }, className: "text-xs font-bold uppercase tracking-wider text-slate-200 mb-4", children: footerHeading }), showNewsletter && ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-3", children: [(0, jsx_runtime_1.jsx)(EditableText_1.EditableText, { as: "p", fieldPath: "common.newsletterDescription", defaultValue: common.newsletterDescription ?? 'Join our exclusive community for releases, updates, and special perks.', placeholder: "Add a newsletter description", size: "0.8125rem", color: "#94a3b8", lineHeight: 1.5, style: {
305
293
  margin: 0,
306
- }, className: "text-xs text-slate-400 leading-relaxed", children: "Join our exclusive community for releases, updates, and special perks." }), subscribed ? ((0, jsx_runtime_1.jsx)("p", { "data-preview-static": "newsletter-success", style: {
294
+ }, className: "text-xs text-slate-400 leading-relaxed" }), subscribed ? ((0, jsx_runtime_1.jsx)("p", { "data-preview-static": "newsletter-success", style: {
307
295
  padding: '0.625rem 0.875rem',
308
296
  borderRadius: '8px',
309
297
  backgroundColor: 'rgba(34, 197, 94, 0.12)',
@@ -319,7 +307,7 @@ function EditableFooter({ defaultLinks = DEFAULT_FOOTER_PAGES, links, basePath =
319
307
  display: 'flex',
320
308
  alignItems: 'center',
321
309
  position: 'relative',
322
- }, children: (0, jsx_runtime_1.jsx)("input", { type: "email", required: true, "data-preview-static": "newsletter-input", placeholder: "Enter your email", value: email, onChange: (e) => setEmail(e.target.value), style: {
310
+ }, children: (0, jsx_runtime_1.jsx)("input", { type: "email", required: true, "data-preview-field-path": "common.newsletterEmailPlaceholder", placeholder: common.newsletterEmailPlaceholder ?? 'Enter your email', value: email, onChange: (e) => setEmail(e.target.value), style: {
323
311
  width: '100%',
324
312
  backgroundColor: '#0f172a', // slate-900
325
313
  border: '1px solid #1e293b', // slate-800
@@ -328,7 +316,7 @@ function EditableFooter({ defaultLinks = DEFAULT_FOOTER_PAGES, links, basePath =
328
316
  fontSize: '0.8125rem',
329
317
  color: '#ffffff',
330
318
  outline: 'none',
331
- }, className: "w-full bg-slate-900 border border-slate-800 rounded-lg px-3 py-2 text-xs text-white placeholder-slate-500 focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition-all" }) }), (0, jsx_runtime_1.jsxs)("button", { type: "submit", "data-preview-static": "newsletter-btn", style: {
319
+ }, className: "w-full bg-slate-900 border border-slate-800 rounded-lg px-3 py-2 text-xs text-white placeholder-slate-500 focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition-all" }) }), (0, jsx_runtime_1.jsxs)("button", { type: "submit", style: {
332
320
  backgroundColor: '#ffffff',
333
321
  color: '#0f172a',
334
322
  border: 'none',
@@ -338,7 +326,7 @@ function EditableFooter({ defaultLinks = DEFAULT_FOOTER_PAGES, links, basePath =
338
326
  fontWeight: 600,
339
327
  cursor: 'pointer',
340
328
  transition: 'background-color 0.15s ease',
341
- }, className: "bg-white text-slate-900 hover:bg-slate-200 rounded-lg px-3.5 py-2 text-xs font-semibold transition-colors flex items-center justify-center gap-1.5 shadow-sm", children: ["Subscribe", (0, jsx_runtime_1.jsx)("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: (0, jsx_runtime_1.jsx)("path", { d: "M5 12h14M12 5l7 7-7 7" }) })] })] }))] }))] })] }), (0, jsx_runtime_1.jsxs)("div", { style: {
329
+ }, className: "bg-white text-slate-900 hover:bg-slate-200 rounded-lg px-3.5 py-2 text-xs font-semibold transition-colors flex items-center justify-center gap-1.5 shadow-sm", children: [(0, jsx_runtime_1.jsx)(EditableText_1.EditableText, { as: "span", fieldPath: "common.newsletterSubscribeLabel", defaultValue: common.newsletterSubscribeLabel ?? 'Subscribe', placeholder: "Subscribe" }), (0, jsx_runtime_1.jsx)("svg", { "data-preview-static": "newsletter-submit-arrow", "aria-hidden": "true", width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: (0, jsx_runtime_1.jsx)("path", { d: "M5 12h14M12 5l7 7-7 7" }) })] })] }))] }))] })] }), (0, jsx_runtime_1.jsxs)("div", { style: {
342
330
  paddingTop: '2rem',
343
331
  borderTop: '1px solid rgba(255, 255, 255, 0.08)',
344
332
  display: 'flex',
@@ -233,17 +233,17 @@ const EditableIcon = ({ name = 'circle', fieldPath, size = 16, strokeWidth = 2,
233
233
  }
234
234
  // 3. Built-in SVG lookup
235
235
  const renderer = BUILTIN_ICONS[normalized] || BUILTIN_ICONS[fallback] || BUILTIN_ICONS.circle;
236
- return ((0, jsx_runtime_1.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: strokeWidth, strokeLinecap: "round", strokeLinejoin: "round", width: size, height: size, className: `deneb-editable-icon ${className}`, style: {
236
+ const svg = ((0, jsx_runtime_1.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: strokeWidth, strokeLinecap: "round", strokeLinejoin: "round", width: size, height: size, className: `deneb-editable-icon ${className}`, style: {
237
237
  display: 'inline-block',
238
238
  verticalAlign: 'middle',
239
239
  flexShrink: 0,
240
240
  ...style,
241
- }, "aria-hidden": !title, role: title ? 'img' : undefined, ...(fieldPath ? {
242
- 'data-preview-field-path': fieldPath,
243
- 'data-preview-control': 'icon-picker',
244
- 'data-preview-icon-type': 'lucide',
245
- 'data-preview-icon': activeName,
246
- } : {}), ...svgProps, children: [title && (0, jsx_runtime_1.jsx)("title", { children: title }), renderer({ strokeWidth })] }));
241
+ }, "aria-hidden": !title, role: title ? 'img' : undefined, ...svgProps, children: [title && (0, jsx_runtime_1.jsx)("title", { children: title }), renderer({ strokeWidth })] }));
242
+ if (!fieldPath)
243
+ return svg;
244
+ // Match the HTML selection target used by customIcon/iconMap above.
245
+ // SVG descendants bubble into this target even in HTMLElement-only bridges.
246
+ return ((0, jsx_runtime_1.jsx)("span", { "data-preview-field-path": fieldPath, "data-preview-control": "icon-picker", "data-preview-icon-type": "lucide", "data-preview-icon": activeName, style: { display: 'inline-flex', alignItems: 'center', flexShrink: 0, lineHeight: 1 }, children: svg }));
247
247
  };
248
248
  exports.EditableIcon = EditableIcon;
249
249
  // Aliases for developer convenience
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deneb-ui/ui",
3
- "version": "2.0.124",
3
+ "version": "2.0.126",
4
4
  "description": "Visual-first React component library for editable commerce storefronts. Built for Next.js and Fivora.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -50,7 +50,7 @@
50
50
  ],
51
51
  "license": "MIT",
52
52
  "dependencies": {
53
- "@deneb-ui/core": "^2.0.124"
53
+ "@deneb-ui/core": "^2.0.126"
54
54
  },
55
55
  "peerDependencies": {
56
56
  "react": "^18.0.0 || ^19.0.0",