cinqcinqdev-seo 1.0.14 → 1.0.15
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
|
@@ -502,13 +502,34 @@ const seoTree = computed(() => {
|
|
|
502
502
|
const selectedCMSConfig = computed(
|
|
503
503
|
() => selectedBlockIndex.value !== null ? CMS_COMPONENTS[page.value?.content[selectedBlockIndex.value]?.type] : null
|
|
504
504
|
);
|
|
505
|
+
const _getPanelFields = (panel) => {
|
|
506
|
+
const cfg = selectedCMSConfig.value;
|
|
507
|
+
if (!cfg?.fields || selectedBlockIndex.value === null) return [];
|
|
508
|
+
const props = page.value?.content[selectedBlockIndex.value]?.props ?? {};
|
|
509
|
+
return Object.entries(cfg.fields).filter(([key]) => STYLE_PANEL_MAP[key] === panel).filter(([, f]) => !f.showIf || f.showIf(props)).map(([key, f]) => ({ key, ...f }));
|
|
510
|
+
};
|
|
511
|
+
const colorSectionFields = computed(() => _getPanelFields("colors"));
|
|
512
|
+
const typoSectionFields = computed(() => _getPanelFields("typo"));
|
|
513
|
+
const effectsSectionFields = computed(() => _getPanelFields("effects"));
|
|
514
|
+
const STYLE_PANEL_MAP = {
|
|
515
|
+
bgColor: "colors",
|
|
516
|
+
textColor: "colors",
|
|
517
|
+
overlayColor: "colors",
|
|
518
|
+
highlightColor: "colors",
|
|
519
|
+
textSize: "typo",
|
|
520
|
+
titleSize: "typo",
|
|
521
|
+
overlay: "effects",
|
|
522
|
+
overlayDirection: "effects",
|
|
523
|
+
overlayStrength: "effects"
|
|
524
|
+
};
|
|
505
525
|
const CONTENT_FIELD_TYPES = ["text", "textarea", "image", "list", "richtext"];
|
|
506
526
|
const visibleFields = computed(() => {
|
|
507
527
|
const cfg = selectedCMSConfig.value;
|
|
508
528
|
if (!cfg?.fields) return {};
|
|
509
529
|
const props = page.value?.content[selectedBlockIndex.value]?.props ?? {};
|
|
510
530
|
return Object.fromEntries(
|
|
511
|
-
Object.entries(cfg.fields).filter(([, f]) => {
|
|
531
|
+
Object.entries(cfg.fields).filter(([key, f]) => {
|
|
532
|
+
if (STYLE_PANEL_MAP[key]) return false;
|
|
512
533
|
const isContent = CONTENT_FIELD_TYPES.includes(f.type);
|
|
513
534
|
if (selectedFieldGroup.value === "contenu" ? !isContent : isContent) return false;
|
|
514
535
|
if (typeof f.showIf === "function" && !f.showIf(props)) return false;
|
|
@@ -1168,6 +1189,30 @@ const savePage = async () => {
|
|
|
1168
1189
|
</div>
|
|
1169
1190
|
</div>
|
|
1170
1191
|
</div>
|
|
1192
|
+
<!-- Section color props (bgColor, textColor, overlayColor…) from block schema -->
|
|
1193
|
+
<template v-if="colorSectionFields.length">
|
|
1194
|
+
<div class="border-t border-gray-100 pt-3 space-y-3">
|
|
1195
|
+
<p class="text-[8px] font-black uppercase tracking-widest text-[#3d35ff]/60">Section Colors</p>
|
|
1196
|
+
<div v-for="f in colorSectionFields" :key="f.key">
|
|
1197
|
+
<label class="text-[7px] font-black uppercase text-gray-400 block mb-1">{{ f.label }}</label>
|
|
1198
|
+
<div class="flex items-center gap-1.5 bg-gray-50 rounded-xl ring-1 ring-gray-100 px-2 py-1.5">
|
|
1199
|
+
<input type="color" :value="page.content[selectedBlockIndex].props[f.key] || '#000000'" @input="page.content[selectedBlockIndex].props[f.key] = $event.target.value;
|
|
1200
|
+
trigger()" class="w-5 h-5 rounded cursor-pointer border-0 bg-transparent p-0" />
|
|
1201
|
+
<input :value="page.content[selectedBlockIndex].props[f.key]" @input="page.content[selectedBlockIndex].props[f.key] = $event.target.value;
|
|
1202
|
+
trigger()" placeholder="inherit" class="flex-1 bg-transparent text-[9px] font-mono outline-none w-0" />
|
|
1203
|
+
<button v-if="page.content[selectedBlockIndex].props[f.key]" @click="page.content[selectedBlockIndex].props[f.key] = '';
|
|
1204
|
+
trigger()" class="text-gray-300 hover:text-gray-500 text-[10px] shrink-0">✕</button>
|
|
1205
|
+
</div>
|
|
1206
|
+
<div class="flex flex-wrap gap-1 mt-1.5">
|
|
1207
|
+
<button v-for="c in ['#ffffff', '#000000', '#3d35ff', ...brandColors]" :key="c"
|
|
1208
|
+
@click="page.content[selectedBlockIndex].props[f.key] = c;
|
|
1209
|
+
trigger()"
|
|
1210
|
+
:title="c" :style="{ background: c }"
|
|
1211
|
+
:class="['w-4 h-4 rounded-full border transition-all', page.content[selectedBlockIndex].props[f.key] === c ? 'border-[#3d35ff] scale-110 shadow-sm' : 'border-black/10 hover:scale-110']" />
|
|
1212
|
+
</div>
|
|
1213
|
+
</div>
|
|
1214
|
+
</div>
|
|
1215
|
+
</template>
|
|
1171
1216
|
</div>
|
|
1172
1217
|
</div>
|
|
1173
1218
|
|
|
@@ -1179,6 +1224,22 @@ const savePage = async () => {
|
|
|
1179
1224
|
<svg :class="['w-3 h-3 text-gray-400 transition-transform', styleSection === 'typo' ? '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>
|
|
1180
1225
|
</button>
|
|
1181
1226
|
<div v-show="styleSection === 'typo'" class="p-4 space-y-4">
|
|
1227
|
+
<!-- Section typography props (textSize, titleSize) from block schema -->
|
|
1228
|
+
<template v-if="typoSectionFields.length">
|
|
1229
|
+
<div v-for="f in typoSectionFields" :key="f.key">
|
|
1230
|
+
<p class="text-[8px] font-black uppercase tracking-widest text-[#3d35ff]/60 mb-2">{{ f.label }}</p>
|
|
1231
|
+
<div class="grid grid-cols-3 gap-1.5">
|
|
1232
|
+
<button v-for="opt in f.options" :key="opt.value"
|
|
1233
|
+
@click="page.content[selectedBlockIndex].props[f.key] = opt.value;
|
|
1234
|
+
trigger()"
|
|
1235
|
+
:class="['py-2 px-1 rounded-xl border-2 text-center transition-all', page.content[selectedBlockIndex].props[f.key] === opt.value ? 'border-[#3d35ff] bg-blue-50/50 text-[#3d35ff]' : 'border-gray-100 text-gray-400 hover:border-gray-200']">
|
|
1236
|
+
<span class="text-base block mb-0.5">{{ opt.icon }}</span>
|
|
1237
|
+
<span class="text-[7px] font-black uppercase">{{ opt.label }}</span>
|
|
1238
|
+
</button>
|
|
1239
|
+
</div>
|
|
1240
|
+
</div>
|
|
1241
|
+
<div class="border-t border-gray-100 pt-1"></div>
|
|
1242
|
+
</template>
|
|
1182
1243
|
<!-- Title row -->
|
|
1183
1244
|
<div>
|
|
1184
1245
|
<p class="text-[8px] font-black uppercase tracking-widest text-[#3d35ff]/60 mb-2">Title (h1–h4)</p>
|
|
@@ -1406,7 +1467,31 @@ const savePage = async () => {
|
|
|
1406
1467
|
</div>
|
|
1407
1468
|
|
|
1408
1469
|
<!-- Empty state -->
|
|
1409
|
-
<p v-if="!activeEffects.length" class="text-[8px] text-gray-300 text-center py-3">No effects applied</p>
|
|
1470
|
+
<p v-if="!activeEffects.length && !effectsSectionFields.length" class="text-[8px] text-gray-300 text-center py-3">No effects applied</p>
|
|
1471
|
+
|
|
1472
|
+
<!-- Section effects (overlay, direction, strength) from block schema -->
|
|
1473
|
+
<template v-if="effectsSectionFields.length">
|
|
1474
|
+
<div v-for="f in effectsSectionFields" :key="f.key" class="rounded-xl border border-gray-100 overflow-hidden">
|
|
1475
|
+
<div class="px-3 py-2 bg-gray-50">
|
|
1476
|
+
<p class="text-[8px] font-black uppercase tracking-widest text-gray-700">{{ f.label }}</p>
|
|
1477
|
+
</div>
|
|
1478
|
+
<div class="p-3">
|
|
1479
|
+
<div v-if="f.type === 'cards'" class="grid grid-cols-3 gap-1.5">
|
|
1480
|
+
<button v-for="opt in f.options" :key="opt.value"
|
|
1481
|
+
@click="page.content[selectedBlockIndex].props[f.key] = opt.value;
|
|
1482
|
+
trigger()"
|
|
1483
|
+
:class="['py-2 px-1 rounded-xl border-2 text-center transition-all', page.content[selectedBlockIndex].props[f.key] === opt.value ? 'border-[#3d35ff] bg-blue-50/50 text-[#3d35ff]' : 'border-gray-100 text-gray-400 hover:border-gray-200']">
|
|
1484
|
+
<span class="text-sm block mb-0.5">{{ opt.icon }}</span>
|
|
1485
|
+
<span class="text-[7px] font-black uppercase">{{ opt.label }}</span>
|
|
1486
|
+
</button>
|
|
1487
|
+
</div>
|
|
1488
|
+
<select v-else-if="f.type === 'select'" :value="page.content[selectedBlockIndex].props[f.key]" @change="page.content[selectedBlockIndex].props[f.key] = $event.target.value;
|
|
1489
|
+
trigger()" class="w-full bg-gray-50 rounded-xl p-2 text-[9px] font-bold ring-1 ring-gray-100 outline-none">
|
|
1490
|
+
<option v-for="opt in f.options" :key="opt.value" :value="opt.value">{{ opt.label }}</option>
|
|
1491
|
+
</select>
|
|
1492
|
+
</div>
|
|
1493
|
+
</div>
|
|
1494
|
+
</template>
|
|
1410
1495
|
|
|
1411
1496
|
<!-- Add effect -->
|
|
1412
1497
|
<div v-if="showEffectDropdown" class="fixed inset-0 z-[5]" @click="showEffectDropdown = false" />
|