cinqcinqdev-seo 0.1.69 → 0.1.71

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
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": ">=3.0.0"
6
6
  },
7
- "version": "0.1.69",
7
+ "version": "0.1.71",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "1.0.2",
10
10
  "unbuild": "unknown"
@@ -1,8 +1,11 @@
1
1
  <template>
2
2
  <section ref="sectionEl" class="relative overflow-hidden" :dir="textDirection" :style="[{ backgroundColor: bgColor, color: textColor }, spacingStyle]">
3
3
 
4
+ <!-- Gradient overlay (all layouts) -->
5
+ <div v-if="showOverlay && !['fullscreen','parallax','video','magazine'].includes(layout)" class="absolute inset-0 pointer-events-none" style="z-index:1" :style="overlayStyle"></div>
6
+
4
7
  <!-- CENTERED -->
5
- <div v-if="layout === 'centered'" class="px-6 md:px-12 pt-20 pb-16 text-center">
8
+ <div v-if="layout === 'centered'" class="relative px-6 md:px-12 pt-20 pb-16 text-center" style="z-index:2">
6
9
  <div :class="[containerClass]">
7
10
  <span v-if="badge" :class="['inline-flex items-center gap-1.5 text-[10px] font-bold tracking-[0.4em] uppercase px-4 py-1.5 rounded-full border mb-8', ac()]" :style="[{ borderColor: ca(textColor, '30'), color: ca(textColor, '80') }, as_(0)]">
8
11
  <span class="w-1.5 h-1.5 rounded-full inline-block" :style="{ backgroundColor: ca(textColor, '60') }"></span>{{ badge }}
@@ -55,7 +58,7 @@
55
58
  <div class="absolute inset-0">
56
59
  <img v-if="image" :src="image" class="w-full h-full object-cover" />
57
60
  <div v-else class="w-full h-full" :style="{ backgroundColor: ca(textColor, '08') }"></div>
58
- <div class="absolute inset-0" :style="{ background: `linear-gradient(to top, ${bgColor} 20%, ${ca(bgColor, 'cc')} 40%, ${ca(bgColor, '44')} 65%, transparent 100%)` }"></div>
61
+ <div v-if="showOverlay" class="absolute inset-0" :style="overlayStyle"></div>
59
62
  </div>
60
63
  <div :class="[containerClass, 'relative z-10 w-full px-6 md:px-12 pb-14']">
61
64
  <span v-if="badge" :class="['inline-block text-[9px] font-black uppercase tracking-[0.5em] opacity-40 mb-4', ac()]" :style="as_(0)">{{ badge }}</span>
@@ -89,7 +92,7 @@
89
92
  <!-- PARALLAX -->
90
93
  <div v-else-if="layout === 'parallax'" class="relative min-h-[90vh] flex flex-col justify-end">
91
94
  <div class="absolute inset-0" :style="{ backgroundImage: image ? `url(${image})` : undefined, backgroundSize: 'cover', backgroundPosition: 'center', backgroundAttachment: 'fixed', backgroundColor: !image ? ca(textColor, '08') : undefined }"></div>
92
- <div class="absolute inset-0" :style="{ background: `linear-gradient(to top, ${bgColor} 20%, ${ca(bgColor, 'cc')} 45%, ${ca(bgColor, '22')} 70%, transparent 100%)` }"></div>
95
+ <div v-if="showOverlay" class="absolute inset-0" :style="overlayStyle"></div>
93
96
  <div :class="[containerClass, 'relative z-10 w-full px-6 md:px-12 pb-16']">
94
97
  <span v-if="badge" :class="['inline-block text-[9px] font-black uppercase tracking-[0.5em] opacity-40 mb-4', ac()]" :style="as_(0)">{{ badge }}</span>
95
98
  <component :is="titleTag" :class="['font-black uppercase tracking-tighter leading-[0.88] mb-6', ac()]" :style="[{ fontSize: 'clamp(3rem,8vw,7rem)' }, as_(badge ? 1 : 0)]">{{ title }}</component>
@@ -105,7 +108,7 @@
105
108
  <div class="absolute inset-0 overflow-hidden">
106
109
  <video v-if="videoUrl" :src="videoUrl" autoplay muted loop playsinline class="absolute inset-0 w-full h-full object-cover" />
107
110
  <div v-else class="w-full h-full" :style="{ backgroundColor: ca(textColor, '10') }"></div>
108
- <div class="absolute inset-0" :style="{ background: `linear-gradient(to top, ${bgColor} 15%, ${ca(bgColor, 'bb')} 40%, ${ca(bgColor, '33')} 65%, transparent 100%)` }"></div>
111
+ <div v-if="showOverlay" class="absolute inset-0" :style="overlayStyle"></div>
109
112
  </div>
110
113
  <div :class="[containerClass, 'relative z-10 w-full px-6 md:px-12 pb-14']">
111
114
  <span v-if="badge" :class="['inline-block text-[9px] font-black uppercase tracking-[0.5em] opacity-40 mb-4', ac()]" :style="as_(0)">{{ badge }}</span>
@@ -123,7 +126,8 @@
123
126
  <div :class="['col-span-12 md:col-span-7 relative overflow-hidden min-h-[360px] md:min-h-0', cardRound, ac()]" :style="as_(0)">
124
127
  <img v-if="image" :src="image" class="absolute inset-0 w-full h-full object-cover" />
125
128
  <div v-else class="absolute inset-0" :style="{ backgroundColor: ca(textColor, '10') }"></div>
126
- <div class="absolute inset-0 flex flex-col justify-end p-8 md:p-10" :style="{ background: `linear-gradient(to top, ${bgColor}ee 15%, ${ca(bgColor, '88')} 45%, transparent 85%)` }">
129
+ <div v-if="showOverlay" class="absolute inset-0" :style="overlayStyle"></div>
130
+ <div class="absolute inset-0 flex flex-col justify-end p-8 md:p-10" style="z-index:1">
127
131
  <span v-if="badge" class="text-[9px] font-black uppercase tracking-[0.5em] mb-3" :style="{ opacity: 0.5 }">{{ badge }}</span>
128
132
  <component :is="titleTag" class="font-black uppercase tracking-tighter leading-[0.88]" :style="{ fontSize: 'clamp(2rem,4vw,3.5rem)' }">{{ title }}</component>
129
133
  </div>
@@ -188,7 +192,11 @@ const props = defineProps({
188
192
  paddingTop: { type: String, default: "" },
189
193
  paddingBottom: { type: String, default: "" },
190
194
  marginTop: { type: String, default: "" },
191
- marginBottom: { type: String, default: "" }
195
+ marginBottom: { type: String, default: "" },
196
+ overlay: { type: String, default: "auto" },
197
+ overlayDirection: { type: String, default: "to top" },
198
+ overlayStrength: { type: String, default: "medium" },
199
+ overlayColor: { type: String, default: "" }
192
200
  });
193
201
  const sectionEl = ref(null);
194
202
  const isVisible = ref(false);
@@ -217,6 +225,21 @@ const as_ = (n) => {
217
225
  if (!isVisible.value || props.animation === "none" || props.animation === "typewriter" || props.animation === "float") return {};
218
226
  return { animationDelay: `${n * 0.1}s`, animationFillMode: "both" };
219
227
  };
228
+ const showOverlay = computed(() => {
229
+ if (props.overlay === "off") return false;
230
+ if (props.overlay === "on") return true;
231
+ return ["fullscreen", "parallax", "video", "magazine"].includes(props.layout);
232
+ });
233
+ const overlayStyle = computed(() => {
234
+ const dir = props.overlayDirection || "to top";
235
+ const c = props.overlayColor || props.bgColor;
236
+ const stops = {
237
+ light: `linear-gradient(${dir}, ${ca(c, "99")} 0%, ${ca(c, "44")} 40%, transparent 70%)`,
238
+ medium: `linear-gradient(${dir}, ${c} 15%, ${ca(c, "cc")} 40%, ${ca(c, "44")} 65%, transparent 100%)`,
239
+ strong: `linear-gradient(${dir}, ${c} 35%, ${ca(c, "ee")} 55%, ${ca(c, "88")} 75%, transparent 100%)`
240
+ };
241
+ return { background: stops[props.overlayStrength] || stops.medium };
242
+ });
220
243
  const cardRound = computed(() => ({ sharp: "rounded-xl", rounded: "rounded-3xl", pill: "rounded-[40px]" })[props.radius] || "rounded-3xl");
221
244
  const containerClass = computed(() => ({ narrow: "max-w-3xl mx-auto", normal: "max-w-6xl mx-auto", wide: "max-w-7xl mx-auto", full: "max-w-full" })[props.contentWidth] || "max-w-6xl mx-auto");
222
245
  const bodyClass = computed(() => ({ sm: "text-xs", md: "text-sm", lg: "text-base" })[props.textSize] || "text-sm");
@@ -103,10 +103,15 @@ export const DEFAULT_SECTIONS = {
103
103
  paddingTop: "",
104
104
  paddingBottom: "",
105
105
  marginTop: "",
106
- marginBottom: ""
106
+ marginBottom: "",
107
+ overlay: "auto",
108
+ overlayDirection: "to top",
109
+ overlayStrength: "medium",
110
+ overlayColor: ""
107
111
  },
108
112
  groups: [
109
113
  { key: "design", label: "Design" },
114
+ { key: "overlay", label: "Overlay" },
110
115
  { key: "animation", label: "Animation" }
111
116
  ],
112
117
  fields: {
@@ -137,6 +142,25 @@ export const DEFAULT_SECTIONS = {
137
142
  textDirection: { type: "cards", label: "Direction", group: "design", options: directionOptions },
138
143
  contentWidth: { type: "cards", label: "Content Width", group: "design", options: contentWidthOptions },
139
144
  textSize: { type: "cards", label: "Text Size", group: "design", options: textSizeOptions },
145
+ overlay: { type: "cards", label: "Gradient Overlay", group: "overlay", options: [
146
+ { value: "auto", label: "Auto", icon: "\u2B24" },
147
+ { value: "on", label: "On", icon: "\u2713" },
148
+ { value: "off", label: "Off", icon: "\u2715" }
149
+ ] },
150
+ overlayColor: { type: "color", label: "Couleur du gradient", group: "overlay", showIf: (p) => p.overlay !== "off" },
151
+ overlayDirection: { type: "select", label: "Direction", group: "overlay", showIf: (p) => p.overlay !== "off", options: [
152
+ { value: "to top", label: "Bas \u2192 Haut" },
153
+ { value: "to bottom", label: "Haut \u2192 Bas" },
154
+ { value: "to right", label: "Gauche \u2192 Droite" },
155
+ { value: "to left", label: "Droite \u2192 Gauche" },
156
+ { value: "to bottom right", label: "Diagonal \u2198" },
157
+ { value: "to bottom left", label: "Diagonal \u2199" }
158
+ ] },
159
+ overlayStrength: { type: "cards", label: "Intensit\xE9", group: "overlay", showIf: (p) => p.overlay !== "off", options: [
160
+ { value: "light", label: "L\xE9ger", icon: "\u25CB" },
161
+ { value: "medium", label: "Moyen", icon: "\u25D1" },
162
+ { value: "strong", label: "Fort", icon: "\u25CF" }
163
+ ] },
140
164
  animation: { type: "cards", label: "Animation", group: "animation", options: animationOptions },
141
165
  paddingTop: { type: "select", label: "Padding Top", options: paddingOptions },
142
166
  paddingBottom: { type: "select", label: "Padding Bottom", options: paddingOptions },
@@ -381,10 +381,13 @@ const CONTENT_FIELD_TYPES = ["text", "textarea", "image", "list", "richtext"];
381
381
  const visibleFields = computed(() => {
382
382
  const cfg = selectedCMSConfig.value;
383
383
  if (!cfg?.fields) return {};
384
+ const props = page.value?.content[selectedBlockIndex.value]?.props ?? {};
384
385
  return Object.fromEntries(
385
386
  Object.entries(cfg.fields).filter(([, f]) => {
386
387
  const isContent = CONTENT_FIELD_TYPES.includes(f.type);
387
- return selectedFieldGroup.value === "contenu" ? isContent : !isContent;
388
+ if (selectedFieldGroup.value === "contenu" ? !isContent : isContent) return false;
389
+ if (typeof f.showIf === "function" && !f.showIf(props)) return false;
390
+ return true;
388
391
  })
389
392
  );
390
393
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cinqcinqdev-seo",
3
- "version": "0.1.69",
3
+ "version": "0.1.71",
4
4
  "description": "A reusable Nuxt 3 admin CMS module with visual page editor powered by Supabase",
5
5
  "license": "MIT",
6
6
  "module": "./dist/module.mjs",