cinqcinqdev-seo 1.0.5 → 1.0.6
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/dist/module.json
CHANGED
|
@@ -1220,29 +1220,37 @@ export const DEFAULT_SECTIONS = {
|
|
|
1220
1220
|
}
|
|
1221
1221
|
}
|
|
1222
1222
|
};
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1223
|
+
const _shadowMap = {
|
|
1224
|
+
sm: "0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.08)",
|
|
1225
|
+
md: "0 4px 6px rgba(0,0,0,.1),0 2px 4px rgba(0,0,0,.06)",
|
|
1226
|
+
lg: "0 10px 15px rgba(0,0,0,.1),0 4px 6px rgba(0,0,0,.05)",
|
|
1227
|
+
xl: "0 20px 25px rgba(0,0,0,.12)",
|
|
1228
|
+
"2xl": "0 25px 50px rgba(0,0,0,.25)"
|
|
1229
|
+
};
|
|
1230
|
+
const _buildStyleCss = (s, id) => {
|
|
1227
1231
|
const parts = [];
|
|
1228
1232
|
const titleSels = `${id} h1,${id} h2,${id} h3,${id} h4`;
|
|
1229
1233
|
const tr = [];
|
|
1230
|
-
if (s.titleFontSize) tr.push(`font-size:${s.titleFontSize}
|
|
1234
|
+
if (s.titleFontSize) tr.push(`font-size:${s.titleFontSize}rem !important`);
|
|
1231
1235
|
if (s.titleFontWeight) tr.push(`font-weight:${s.titleFontWeight} !important`);
|
|
1232
1236
|
if (s.titleFontStyle) tr.push(`font-style:${s.titleFontStyle} !important`);
|
|
1233
1237
|
if (s.titleTextDecoration) tr.push(`text-decoration:${s.titleTextDecoration} !important`);
|
|
1234
1238
|
if (s.titleColor) tr.push(`color:${s.titleColor} !important`);
|
|
1235
1239
|
if (tr.length) parts.push(`${titleSels}{${tr.join(";")}}`);
|
|
1236
1240
|
const bodySels = `${id} p,${id} li`;
|
|
1237
|
-
const
|
|
1238
|
-
if (s.bodyFontSize)
|
|
1239
|
-
if (s.bodyFontWeight)
|
|
1240
|
-
if (s.bodyColor)
|
|
1241
|
-
if (
|
|
1241
|
+
const br = [];
|
|
1242
|
+
if (s.bodyFontSize) br.push(`font-size:${s.bodyFontSize}rem !important`);
|
|
1243
|
+
if (s.bodyFontWeight) br.push(`font-weight:${s.bodyFontWeight} !important`);
|
|
1244
|
+
if (s.bodyColor) br.push(`color:${s.bodyColor} !important`);
|
|
1245
|
+
if (br.length) parts.push(`${bodySels}{${br.join(";")}}`);
|
|
1242
1246
|
const gr = [];
|
|
1243
1247
|
if (s.lineHeight) gr.push(`line-height:${s.lineHeight}`);
|
|
1244
1248
|
if (s.letterSpacing) gr.push(`letter-spacing:${s.letterSpacing}em`);
|
|
1245
1249
|
if (gr.length) parts.push(`${id}{${gr.join(";")}}`);
|
|
1250
|
+
const lay = [];
|
|
1251
|
+
if (s.maxWidth) lay.push(`max-width:${s.maxWidth}px;margin-left:auto;margin-right:auto`);
|
|
1252
|
+
if (s.translateX || s.translateY) lay.push(`transform:translate(${s.translateX || 0}px,${s.translateY || 0}px)`);
|
|
1253
|
+
if (lay.length) parts.push(`${id}{${lay.join(";")}}`);
|
|
1246
1254
|
const sp = [];
|
|
1247
1255
|
if (s.paddingTop) sp.push(`padding-top:${s.paddingTop}px`);
|
|
1248
1256
|
if (s.paddingBottom) sp.push(`padding-bottom:${s.paddingBottom}px`);
|
|
@@ -1253,19 +1261,29 @@ export const computeBlockCss = (props, blockId) => {
|
|
|
1253
1261
|
if (sp.length) parts.push(`${id}{${sp.join(";")}}`);
|
|
1254
1262
|
const bl = [];
|
|
1255
1263
|
if (s.opacity !== "" && s.opacity != null) bl.push(`opacity:${s.opacity}`);
|
|
1256
|
-
|
|
1257
|
-
sm: "0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.08)",
|
|
1258
|
-
md: "0 4px 6px rgba(0,0,0,.1),0 2px 4px rgba(0,0,0,.06)",
|
|
1259
|
-
lg: "0 10px 15px rgba(0,0,0,.1),0 4px 6px rgba(0,0,0,.05)",
|
|
1260
|
-
xl: "0 20px 25px rgba(0,0,0,.12)",
|
|
1261
|
-
"2xl": "0 25px 50px rgba(0,0,0,.25)"
|
|
1262
|
-
};
|
|
1263
|
-
if (s.boxShadow && s.boxShadow !== "none") bl.push(`box-shadow:${shadowMap[s.boxShadow] || s.boxShadow}`);
|
|
1264
|
+
if (s.boxShadow && s.boxShadow !== "none") bl.push(`box-shadow:${_shadowMap[s.boxShadow] || s.boxShadow}`);
|
|
1264
1265
|
if (s.borderWidth) bl.push(`border-width:${s.borderWidth}px`);
|
|
1265
1266
|
if (s.borderColor) bl.push(`border-color:${s.borderColor}`);
|
|
1266
1267
|
if (s.borderStyle && s.borderStyle !== "none") bl.push(`border-style:${s.borderStyle}`);
|
|
1267
1268
|
if (s.borderRadius) bl.push(`border-radius:${s.borderRadius}px`);
|
|
1268
1269
|
if (bl.length) parts.push(`${id}{${bl.join(";")}}`);
|
|
1270
|
+
return parts.join("");
|
|
1271
|
+
};
|
|
1272
|
+
export const computeBlockCss = (props, blockId) => {
|
|
1273
|
+
if (!props) return "";
|
|
1274
|
+
const s = props._style || {};
|
|
1275
|
+
const id = `[data-block-id="${blockId}"]`;
|
|
1276
|
+
const parts = [];
|
|
1277
|
+
const desktopCss = _buildStyleCss(s, id);
|
|
1278
|
+
if (desktopCss) parts.push(desktopCss);
|
|
1279
|
+
if (s.tablet && Object.values(s.tablet).some(Boolean)) {
|
|
1280
|
+
const css = _buildStyleCss(s.tablet, id);
|
|
1281
|
+
if (css) parts.push(`@media(max-width:1024px){${css}}`);
|
|
1282
|
+
}
|
|
1283
|
+
if (s.mobile && Object.values(s.mobile).some(Boolean)) {
|
|
1284
|
+
const css = _buildStyleCss(s.mobile, id);
|
|
1285
|
+
if (css) parts.push(`@media(max-width:640px){${css}}`);
|
|
1286
|
+
}
|
|
1269
1287
|
if (props.customCss) parts.push(`${id}{${props.customCss}}`);
|
|
1270
1288
|
return parts.join("");
|
|
1271
1289
|
};
|
|
@@ -94,14 +94,23 @@ const showAddModal = ref(false);
|
|
|
94
94
|
const sectionSearch = ref("");
|
|
95
95
|
const selectedFieldGroup = ref("contenu");
|
|
96
96
|
const styleSection = ref("typo");
|
|
97
|
+
const styleBreakpoint = ref("desktop");
|
|
97
98
|
const getStyle = (key) => {
|
|
98
|
-
|
|
99
|
+
const style = page.value?.content[selectedBlockIndex.value]?.props?._style;
|
|
100
|
+
if (!style) return "";
|
|
101
|
+
if (styleBreakpoint.value === "desktop") return style[key] ?? "";
|
|
102
|
+
return style[styleBreakpoint.value]?.[key] ?? "";
|
|
99
103
|
};
|
|
100
104
|
const setStyle = (key, value) => {
|
|
101
105
|
const props = page.value?.content[selectedBlockIndex.value]?.props;
|
|
102
106
|
if (!props) return;
|
|
103
107
|
if (!props._style) props._style = {};
|
|
104
|
-
|
|
108
|
+
if (styleBreakpoint.value === "desktop") {
|
|
109
|
+
props._style[key] = value;
|
|
110
|
+
} else {
|
|
111
|
+
if (!props._style[styleBreakpoint.value]) props._style[styleBreakpoint.value] = {};
|
|
112
|
+
props._style[styleBreakpoint.value][key] = value;
|
|
113
|
+
}
|
|
105
114
|
trigger();
|
|
106
115
|
};
|
|
107
116
|
const SECTION_GROUPS = [
|
|
@@ -935,6 +944,49 @@ const savePage = async () => {
|
|
|
935
944
|
<!-- ── STYLE PANEL (when Style tab active) ──────────────────── -->
|
|
936
945
|
<div v-if="selectedFieldGroup === 'style'" class="mb-6 space-y-3">
|
|
937
946
|
|
|
947
|
+
<!-- Breakpoint switcher -->
|
|
948
|
+
<div class="flex gap-1 bg-gray-100 rounded-xl p-1">
|
|
949
|
+
<button v-for="bp in [{ v: 'desktop', l: '\u{1F5A5} Desktop' }, { v: 'tablet', l: '\u2B1B Tablet' }, { v: 'mobile', l: '\u{1F4F1} Mobile' }]" :key="bp.v"
|
|
950
|
+
@click="styleBreakpoint = bp.v"
|
|
951
|
+
:class="['flex-1 py-1.5 rounded-lg text-[7px] font-black uppercase tracking-wide transition-all', styleBreakpoint === bp.v ? 'bg-white shadow text-[#3d35ff]' : 'text-gray-400 hover:text-gray-600']">
|
|
952
|
+
{{ bp.l }}
|
|
953
|
+
</button>
|
|
954
|
+
</div>
|
|
955
|
+
|
|
956
|
+
<!-- Layout -->
|
|
957
|
+
<div class="border border-gray-100 rounded-2xl overflow-hidden">
|
|
958
|
+
<button @click="styleSection = styleSection === 'layout' ? '' : 'layout'"
|
|
959
|
+
class="w-full flex items-center justify-between px-4 py-3 bg-gray-50 hover:bg-gray-100 transition-colors">
|
|
960
|
+
<span class="text-[9px] font-black uppercase tracking-widest text-gray-700">⊞ Layout</span>
|
|
961
|
+
<svg :class="['w-3 h-3 text-gray-400 transition-transform', styleSection === 'layout' ? 'rotate-180' : '']" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M19 9l-7 7-7-7"/></svg>
|
|
962
|
+
</button>
|
|
963
|
+
<div v-show="styleSection === 'layout'" class="p-4 space-y-3">
|
|
964
|
+
<div>
|
|
965
|
+
<label class="text-[7px] font-black uppercase text-gray-400 block mb-1">Max Width (px)</label>
|
|
966
|
+
<div class="flex items-center gap-1 bg-gray-50 rounded-xl ring-1 ring-gray-100 overflow-hidden px-2">
|
|
967
|
+
<input type="number" :value="getStyle('maxWidth')" @input="setStyle('maxWidth', $event.target.value)" min="0" max="3000" step="10" placeholder="—" class="flex-1 bg-transparent py-2.5 text-[10px] font-mono outline-none w-0" />
|
|
968
|
+
<span class="text-[8px] text-gray-300 shrink-0">px</span>
|
|
969
|
+
</div>
|
|
970
|
+
</div>
|
|
971
|
+
<div class="flex gap-2">
|
|
972
|
+
<div class="flex-1">
|
|
973
|
+
<label class="text-[7px] font-black uppercase text-gray-400 block mb-1">Position X (px)</label>
|
|
974
|
+
<div class="flex items-center gap-1 bg-gray-50 rounded-xl ring-1 ring-gray-100 overflow-hidden px-2">
|
|
975
|
+
<input type="number" :value="getStyle('translateX')" @input="setStyle('translateX', $event.target.value)" step="1" placeholder="0" class="flex-1 bg-transparent py-2.5 text-[10px] font-mono outline-none w-0" />
|
|
976
|
+
<span class="text-[8px] text-gray-300 shrink-0">px</span>
|
|
977
|
+
</div>
|
|
978
|
+
</div>
|
|
979
|
+
<div class="flex-1">
|
|
980
|
+
<label class="text-[7px] font-black uppercase text-gray-400 block mb-1">Position Y (px)</label>
|
|
981
|
+
<div class="flex items-center gap-1 bg-gray-50 rounded-xl ring-1 ring-gray-100 overflow-hidden px-2">
|
|
982
|
+
<input type="number" :value="getStyle('translateY')" @input="setStyle('translateY', $event.target.value)" step="1" placeholder="0" class="flex-1 bg-transparent py-2.5 text-[10px] font-mono outline-none w-0" />
|
|
983
|
+
<span class="text-[8px] text-gray-300 shrink-0">px</span>
|
|
984
|
+
</div>
|
|
985
|
+
</div>
|
|
986
|
+
</div>
|
|
987
|
+
</div>
|
|
988
|
+
</div>
|
|
989
|
+
|
|
938
990
|
<!-- Typography -->
|
|
939
991
|
<div class="border border-gray-100 rounded-2xl overflow-hidden">
|
|
940
992
|
<button @click="styleSection = styleSection === 'typo' ? '' : 'typo'"
|
|
@@ -948,10 +1000,10 @@ const savePage = async () => {
|
|
|
948
1000
|
<p class="text-[8px] font-black uppercase tracking-widest text-[#3d35ff]/60 mb-2">Title (h1–h4)</p>
|
|
949
1001
|
<div class="flex gap-2 mb-2">
|
|
950
1002
|
<div class="flex-1">
|
|
951
|
-
<label class="text-[7px] font-black uppercase text-gray-400 block mb-1">Size (
|
|
1003
|
+
<label class="text-[7px] font-black uppercase text-gray-400 block mb-1">Size (rem)</label>
|
|
952
1004
|
<div class="flex items-center gap-1 bg-gray-50 rounded-xl ring-1 ring-gray-100 overflow-hidden px-2">
|
|
953
|
-
<input type="number" :value="getStyle('titleFontSize')" @input="setStyle('titleFontSize', $event.target.value)" min="
|
|
954
|
-
<span class="text-[8px] text-gray-300 shrink-0">
|
|
1005
|
+
<input type="number" :value="getStyle('titleFontSize')" @input="setStyle('titleFontSize', $event.target.value)" min="0.1" max="20" step="0.1" placeholder="—" class="flex-1 bg-transparent py-2.5 text-[10px] font-mono outline-none w-0" />
|
|
1006
|
+
<span class="text-[8px] text-gray-300 shrink-0">rem</span>
|
|
955
1007
|
</div>
|
|
956
1008
|
</div>
|
|
957
1009
|
<div class="flex-1">
|
|
@@ -983,10 +1035,10 @@ const savePage = async () => {
|
|
|
983
1035
|
<p class="text-[8px] font-black uppercase tracking-widest text-[#3d35ff]/60 mb-2">Body (p, li)</p>
|
|
984
1036
|
<div class="flex gap-2 mb-2">
|
|
985
1037
|
<div class="flex-1">
|
|
986
|
-
<label class="text-[7px] font-black uppercase text-gray-400 block mb-1">Size (
|
|
1038
|
+
<label class="text-[7px] font-black uppercase text-gray-400 block mb-1">Size (rem)</label>
|
|
987
1039
|
<div class="flex items-center gap-1 bg-gray-50 rounded-xl ring-1 ring-gray-100 px-2">
|
|
988
|
-
<input type="number" :value="getStyle('bodyFontSize')" @input="setStyle('bodyFontSize', $event.target.value)" min="
|
|
989
|
-
<span class="text-[8px] text-gray-300 shrink-0">
|
|
1040
|
+
<input type="number" :value="getStyle('bodyFontSize')" @input="setStyle('bodyFontSize', $event.target.value)" min="0.1" max="10" step="0.1" placeholder="—" class="flex-1 bg-transparent py-2.5 text-[10px] font-mono outline-none w-0" />
|
|
1041
|
+
<span class="text-[8px] text-gray-300 shrink-0">rem</span>
|
|
990
1042
|
</div>
|
|
991
1043
|
</div>
|
|
992
1044
|
<div class="flex-1">
|