${escapeHtml(value === true ? 'Enabled' : value === false ? 'Disabled' : value || 'Click to add content')}
diff --git a/Modules/Content/Resources/views/admin/form.blade.php b/Modules/Content/Resources/views/admin/form.blade.php
index 16fd829..dbec35c 100644
--- a/Modules/Content/Resources/views/admin/form.blade.php
+++ b/Modules/Content/Resources/views/admin/form.blade.php
@@ -105,6 +105,10 @@
function normaliseNode(node) {
node.id ||= uid();
node.type ||= 'field';
+ node.styles ||= { desktop: {}, tablet: {}, mobile: {} };
+ node.styles.desktop ||= {};
+ node.styles.tablet ||= {};
+ node.styles.mobile ||= {};
if (node.type === 'columns') {
node.columns ||= [{ children: [] }, { children: [] }];
node.columns.forEach(column => {
@@ -127,6 +131,51 @@
layout.forEach(normaliseNode);
let selectedId = layout[0]?.id || null;
let dragId = null;
+ let activeBreakpoint = 'desktop';
+
+
+ const styleDefaults = {
+ width: '', minHeight: '', textAlign: '', paddingTop: '', paddingRight: '', paddingBottom: '', paddingLeft: '',
+ marginTop: '', marginRight: '', marginBottom: '', marginLeft: '', backgroundColor: '', color: '',
+ borderColor: '', borderWidth: '', borderRadius: '', display: '', alignItems: '', justifyContent: ''
+ };
+
+ function resolvedStyles(node) {
+ const desktop = node.styles?.desktop || {};
+ const tablet = node.styles?.tablet || {};
+ const mobile = node.styles?.mobile || {};
+ if (activeBreakpoint === 'desktop') return { ...styleDefaults, ...desktop };
+ if (activeBreakpoint === 'tablet') return { ...styleDefaults, ...desktop, ...tablet };
+ return { ...styleDefaults, ...desktop, ...tablet, ...mobile };
+ }
+
+ function cssValue(value, unit = 'px') {
+ if (value === '' || value === null || value === undefined) return '';
+ if (typeof value === 'number' || /^-?\d+(\.\d+)?$/.test(String(value))) return `${value}${unit}`;
+ return String(value);
+ }
+
+ function nodeStyle(node) {
+ const s = resolvedStyles(node);
+ const declarations = {
+ width: s.width, minHeight: cssValue(s.minHeight), textAlign: s.textAlign,
+ paddingTop: cssValue(s.paddingTop), paddingRight: cssValue(s.paddingRight),
+ paddingBottom: cssValue(s.paddingBottom), paddingLeft: cssValue(s.paddingLeft),
+ marginTop: cssValue(s.marginTop), marginRight: cssValue(s.marginRight),
+ marginBottom: cssValue(s.marginBottom), marginLeft: cssValue(s.marginLeft),
+ backgroundColor: s.backgroundColor, color: s.color, borderColor: s.borderColor,
+ borderWidth: cssValue(s.borderWidth), borderRadius: cssValue(s.borderRadius),
+ borderStyle: s.borderWidth ? 'solid' : '', display: s.display, alignItems: s.alignItems,
+ justifyContent: s.justifyContent
+ };
+ return Object.entries(declarations).filter(([, value]) => value !== '').map(([key, value]) => `${key.replace(/[A-Z]/g, m => '-' + m.toLowerCase())}:${value}`).join(';');
+ }
+
+ function responsiveBadge(node) {
+ const hasTablet = Object.values(node.styles?.tablet || {}).some(value => value !== '');
+ const hasMobile = Object.values(node.styles?.mobile || {}).some(value => value !== '');
+ return `${hasTablet ? 'T' : ''}${hasMobile ? 'M' : ''}`;
+ }
const library = document.getElementById('builder-library');
const layoutLibrary = document.getElementById('layout-library');
@@ -217,12 +266,12 @@
if (node.type === 'field') {
const definition = schema[node.key] || {};
const value = data[node.key];
- return ` ${escapeHtml(value === true ? 'Enabled' : value === false ? 'Disabled' : value || 'Click to add content')} ${escapeHtml(value === true ? 'Enabled' : value === false ? 'Disabled' : value || 'Click to add content')}
Drag components using their cards. Drop them into sections, containers, columns, or the page root.