diff --git a/docs/vue-builder-examples.md b/docs/vue-builder-examples.md deleted file mode 100644 index d32a2f1..0000000 --- a/docs/vue-builder-examples.md +++ /dev/null @@ -1,695 +0,0 @@ -# Ejemplos de Builder Vue - Producción - -Colección de ejemplos reales de archivos `builder.vue` implementados en producción. Cada ejemplo incluye el código completo y notas sobre decisiones de diseño importantes. - ---- - -## Ejemplo 1: Banner Slideshow - -### Descripción -Banner hero con slideshow de imágenes o video de fondo, overlay configurable, textos principales (pretítulo, título, subtítulo) y botón de llamada a la acción. - -### Características principales -- **5 tabs organizados**: Configuración, Imágenes, Textos, Enlaces, Colores -- **Selector imagen/video**: Toggle con iconos que alterna entre imagen y video con `v-show` -- **Overlay completo**: Tipo (sin degradado/con degradado), color y opacidad agrupados en tab Imágenes -- **Colorpickers**: Para overlay y color de texto general con textfield oculto -- **Toggles con iconos**: Sombra (X/check), tipo imagen (foto/video), tipo overlay (cuadrado/degradado) -- **Logo adicional**: Upload de logo que se superpone al banner -- **Configuraciones globales**: Posición texto, sombra, container, altura banner - -### Decisiones de diseño clave - -1. **Selector imagen/video como primer campo del tab Imágenes**: El toggle de tipo de fondo está al inicio del tab Imágenes, antes de los uploads, según la regla 10.1 -2. **v-show en uploads**: - - Upload de imágenes: `v-show="data.tipodeimagen && data.tipodeimagen.newValues.builder_custom.value == ''"` - - Upload de video: `v-show="data.tipodeimagen && data.tipodeimagen.newValues.builder_custom.value == '1'"` - - NUNCA quitar estos `v-show`, son esenciales -3. **Grupo overlay en tab Imágenes**: El grupo completo (tipo + color + opacidad) está en Imágenes, NO en Colores, porque afecta directamente al fondo visual (regla 10.2) -4. **Radio borde en tab Enlaces**: Campo que afecta al botón va en el tab del enlace, no en Configuración (regla 10.3) -5. **Recuerda con HTML escapado**: El campo título incluye un "Recuerda" con etiquetas HTML escapadas (`<span>`) para guiar al usuario -6. **Color del texto en tab Colores**: El color general del texto va en su propio tab, no mezclado con el overlay - -### Tabs configurados - -```javascript -tabsConfig: [ - { id: "configuracion", label: "Configuración", color: "#f59e0b", icon: '...' }, - { id: "imagenes", label: "Imágenes", color: "#10b981", icon: '...' }, - { id: "textos", label: "Textos", color: "#3b82f6", icon: '...' }, - { id: "enlaces", label: "Enlaces", color: "#ef4444", icon: '...' }, - { id: "colores", label: "Colores", color: "#8b5cf6", icon: '...' } -] -``` - -### Componentes utilizados -- `acai-vue-tabs` - Sistema de tabs con storage-key y apply-theme-styles -- `acai-vue-selectv2` - Selectores (algunos con `:toggle-icons`) -- `acai-vue-textfield` - Campos de texto simple (pretítulo, subtítulo) -- `acai-vue-title` - Encabezado principal con placeholder -- `acai-vue-linkv2` - Enlaces con `:show_text="true"` -- `acai-vue-upload` - Uploads de imagen/video/logo con todas las props necesarias -- `acai-vue-colorpicker` - Pickers de color con textfield oculto asociado - -### Iconos con toggle - -```javascript -iconosSombra: { - '': '...(icon-tabler-x)', - '1': '...(icon-tabler-check)' -}, -iconosTipoImagen: { - '': '...(icon-tabler-photo)', - '1': '...(icon-tabler-video)' -}, -iconosOverlay: { - '': '...(icon-tabler-square)', - '1': '...(icon-tabler-gradient)' -} -``` - -### Código completo - -```vue - - - - - -``` - ---- - -## Ejemplo 2: [Módulo de texto genérico] - -```vue - - - -``` \ No newline at end of file diff --git a/docs/vue-builder-rules.md b/docs/vue-builder-rules.md deleted file mode 100644 index 846e5cc..0000000 --- a/docs/vue-builder-rules.md +++ /dev/null @@ -1,484 +0,0 @@ - -# Reglas CMS-VUE - -Aplica estas reglas ÚNICAMENTE cuando el usuario incluya "cms-vue" o "CMS-VUE" (en cualquier combinación de mayúsculas/minúsculas) en su mensaje. Ejemplos válidos: "dame el cms-vue", "cms-vue personalizado", "crea el CMS-VUE", "necesito el cms-vue de este módulo". Si el mensaje NO contiene "cms-vue", ignora completamente estas instrucciones. - ---- - -## 1. Estructura general: Tabs (`acai-vue-tabs`) - -- Analiza el HTML proporcionado para determinar cuántos tabs son necesarios y cómo nombrarlos. -- Tabs base comunes: **Configuración**, **Imágenes**, **Textos**, **Bloques** (records), **Enlaces**, **Colores**. -- Añade tabs adicionales si el módulo lo requiere (ej: "Formulario", "Video", "Overlay", "Slider", etc.). -- Si un tab solo tendría 1 campo, evalúa fusionarlo con otro tab relacionado. -- Cada tab tiene su propio `id`, `label`, `color` e `icon` (SVG inline). -- SVG dentro del template usan `:style="{ color: color }"` para heredar el color del tab. -- Textos descriptivos claros y orientados al usuario final del CMS. -- Usa `storage-key` único: `'nombre-modulo-tabs-' + (section_id || 'default')`. -- Siempre añade `:apply-theme-styles="true"`. -- **IMPORTANTE:** La prop para pasar los tabs es `:tabs` (NO `:tabs-config`). -- **IMPORTANTE:** Siempre añadir `v-if="data"` en el `` para evitar renderizar antes de que los datos estén listos. - -### Template de cada tab: -```html - -``` - ---- - -## 2. Colorpicker según contexto - -### 2.1 En tab "Colores" (campos generales de color de texto/fondo) -Siempre con SVG + título + descripción + colorpicker + textfield oculto: -```html -
-
-
- ... -

Nombre : Descripción.

-
-

Nota : valor por defecto.

-
- -
-
- -
-
-
-``` - -### 2.2 Colorpicker en otros tabs (ej: color del overlay en tab Imágenes) -Misma estructura con SVG + título + descripción + colorpicker + textfield oculto, pero usando el `color` del tab donde se encuentre. Se coloca junto a los campos relacionados (ver regla 10.2). - -### 2.3 Dentro de `` (sin icono ni descripción) -Se coloca debajo del campo al que corresponde: -- Nota con `mt-4` si campo anterior es `textfield` o `title`. -- Nota con `mt-3` si campo anterior es `textbox` o `wysiwyg`. -- Colorpicker siempre con `mt-1`. -```html -

Nota : color por defecto (#hex).

-
- -
-
- -
-``` - -### 2.4 Campos tipo `list` para colores -Se usan como `` con icono y nota. El componente detecta automáticamente si las opciones son colores y muestra el modo color selector con swatches. No llevan colorpicker ni textfield oculto. - -### 2.5 Extraer color por defecto -Del HTML: `style="color: {{ campo ? campo : '#HEX' }}"` → usar `#HEX`. Si no hay color, usar `#111827` (textos) o `transparent` (fondos). - ---- - -## 3. Campos: estructura en tabs - -### Fuera de records: -```html -
-
-
- ... -

Nombre : Descripción.

-
-

Nota : info adicional.

-
- -
-
-
-``` - -### Dentro de records: -```html -
-
- ... -

Nombre : Descripción.

-
-
- -
-
-``` - ---- - -## 4. Nombres de campos (`:field`) - -- Construir uniendo palabras del `data-field-label` en minúsculas sin espacios. -- Eliminar acentos: á→a, é→e, í→i, ó→o, ú→u, ñ→(eliminar). -- Ejemplos: `Color del título` → `colordeltitulo`, `Valoración` → `valoracion`, `Tamaño` → `tamao`. - ---- - -## 5. Upload de imágenes - -### General: -```html - -``` - -### En records: -```html - -``` - ---- - -## 6. Componentes y URLs - -Solo incluir los que se usen. Los componentes personalizados (tabs, selectv2) se cargan desde impulse; los estándar desde cocosolution: - -```javascript -// ── Componentes personalizados (impulse) ── -'acai-vue-tabs': httpVueLoader('https://impulse.webserver2.plandeweb.com/template/estandar/css/builder-acaivuetabsv2.vue?timestamp=' + new Date().getTime()), -'acai-vue-selectv2': httpVueLoader('https://impulse.webserver2.plandeweb.com/template/estandar/css/builder-acaivueselect-v2.vue?timestamp=' + new Date().getTime()), - -// ── Componentes estándar (cocosolution) ── -'acai-vue-colorpicker': httpVueLoader('https://cms.cocosolution.com/lib/plugins/builder_saas/tpl/componentes/builder-acaivuecolorpicker.vue?timestamp=' + new Date().getTime()), -'acai-vue-upload': httpVueLoader('https://cms.cocosolution.com/lib/plugins/builder_saas/tpl/componentes/builder-acaivueupload.vue?timestamp=' + new Date().getTime()), -'acai-vue-records': httpVueLoader('https://cms.cocosolution.com/lib/plugins/builder_saas/tpl/componentes/builder-acaivuerecords.vue?timestamp=' + new Date().getTime()), -'acai-vue-title': httpVueLoader('https://cms.cocosolution.com/lib/plugins/builder_saas/tpl/componentes/builder-acaivuetitle.vue?timestamp=' + new Date().getTime()), -'acai-vue-wysiwyg': httpVueLoader('https://cms.cocosolution.com/lib/plugins/builder_saas/tpl/componentes/builder-acaivuewysiwyg.vue?timestamp=' + new Date().getTime()), -'acai-vue-linkv2': httpVueLoader('https://cms.cocosolution.com/lib/plugins/builder_saas/tpl/componentes/builder-acaivuelinkv2.vue?timestamp=' + new Date().getTime()), -'acai-vue-textbox': httpVueLoader('https://cms.cocosolution.com/lib/plugins/builder_saas/tpl/componentes/builder-acaivuetextbox.vue?timestamp=' + new Date().getTime()), -'acai-vue-textfield': httpVueLoader('https://cms.cocosolution.com/lib/plugins/builder_saas/tpl/componentes/builder-acaivuetextfield.vue?timestamp=' + new Date().getTime()), -'acai-vue-datepicker': httpVueLoader('https://cms.cocosolution.com/lib/plugins/builder_saas/tpl/componentes/builder-acaivuedatepicker.vue?timestamp=' + new Date().getTime()), -``` - -**IMPORTANTE:** `acai-vue-list` ha sido reemplazado por `acai-vue-selectv2` en todos los VUEs. NO usar `acai-vue-list` en nuevos VUEs. - ---- - -## 7. Mapeo HTML → Vue - -| `data-field-type` | Componente | -|---|---| -| `textfield` | `acai-vue-textfield` | -| `headfield` | `acai-vue-title` | -| `wysiwyg` | `acai-vue-wysiwyg` | -| `textbox` | `acai-vue-textbox` | -| `list` | `acai-vue-selectv2` | -| `upload` / `uploadMulti` | `acai-vue-upload` | -| `linkv2` | `acai-vue-linkv2` (siempre con `:show_text="true"`) | -| `multiv2` | `acai-vue-records` | -| `textfield` (usado como fecha) | `acai-vue-datepicker` + `acai-vue-textfield` oculto | - ---- - -## 8. Script base - -```javascript -module.exports = { - props: ["active", "section_id"], - data() { - return { - data: null, - builder: null, - idiomas: IDIOMAS, - tabsConfig: [ /* tabs */ ], - // iconos para toggles (solo si hay campos de 2 opciones con iconos) - // iconosNombreCampo: { '': '...', '1': '...' } - }; - }, - components: { /* solo los usados */ }, - mounted() { this.$emit("child-mounted"); }, - methods: { saveData() { this.$emit("save-data"); } }, -}; -``` - ---- - -## 9. Decisión de tabs según contenido HTML y contexto semántico - -### 9.1 Organización contextual (PRIORITARIA) - -**IMPORTANTE:** Primero analizar el **nombre del campo** para determinar su contexto semántico, independientemente del tipo. Un campo `list` llamado "tipo de imagen" debe ir en el tab **Imágenes**, no en Configuración. - -#### Keywords para tab Imágenes: -Campos que contengan: `imagen`, `photo`, `video`, `fondo`, `background`, `logo`, `icono`, `icon` - -**Ejemplos:** -- ✅ "tipo de imagen" (list) → **Imágenes** -- ✅ "video de fondo" (list) → **Imágenes** -- ✅ "logo principal" (upload) → **Imágenes** - -#### Keywords para tab Enlaces: -Campos que contengan: `enlace`, `link`, `boton`, `button`, `url`, `href` - -**Ejemplos:** -- ✅ "texto del botón" (textfield) → **Enlaces** -- ✅ "url externa" (textfield) → **Enlaces** -- ✅ "estilo del enlace" (list) → **Enlaces** - -#### Keywords para tab Textos: -Campos que contengan: `titulo`, `title`, `texto`, `text`, `descripcion`, `description`, `contenido`, `content`, `label`, `etiqueta` - -**Ejemplos:** -- ✅ "título principal" (headfield) → **Textos** -- ✅ "descripción corta" (textfield) → **Textos** - -### 9.2 Organización por tipo (fallback) - -Si el nombre del campo **no** coincide con ninguna keyword, usar el tipo: - -| Tipo | Tab | -|---|---| -| `headfield`, `textfield`, `textbox`, `wysiwyg` | Textos | -| `upload`, `image` | Imágenes | -| `linkv2` | Enlaces | -| `list`, `select` (sin contexto) | Configuración | -| `multiv2` (records) | Bloques | -| Otros campos de configuración | Configuración | - ---- - -## 10. Reglas especiales - -### 10.1 Selector imagen/video con v-show -Cuando el HTML tenga un campo `list` con opciones tipo `"|Imagen,1|Video"`: -- El selector "Tipo de fondo" va en el tab **Imágenes** como **primer campo** (encima de los uploads). -- Se renderiza como toggle con iconos (foto/vídeo) usando `acai-vue-selectv2` con `:toggle-icons`. -- Usa el icono `icon-tabler-photo-video`: -```html - -``` -- El upload de **imágenes** lleva: `v-show="data.tipodeimagen && data.tipodeimagen.newValues.builder_custom.value == ''"` (visible cuando es imagen o vacío). -- El upload de **video** lleva: `v-show="data.tipodeimagen && data.tipodeimagen.newValues.builder_custom.value == '1'"` (visible cuando es video). -- **NUNCA quitar estos `v-show`**, son esenciales para mostrar uno u otro según la selección. -- Iconos del toggle: -```javascript -iconosTipoImagen: { - '': '', - '1': '' -} -``` - -### 10.2 Grupo overlay (tipo + color + opacidad) -Cuando el HTML contenga campos de overlay (tipo de overlay, color del overlay, opacidad del overlay): -- Los tres campos van **juntos** en el tab **Imágenes**, **debajo** de la imagen/video sobre la que se aplica el overlay. -- El orden es: tipo de overlay → color del overlay (colorpicker) → opacidad del overlay. -- El **color del overlay NO va en el tab Colores**, va en Imágenes junto al resto del grupo overlay. -- El tipo de overlay (2 opciones: Sin degradado / Con degradado) se renderiza como toggle con iconos: -```javascript -iconosOverlay: { - '': '', - '1': '' -} -``` - -### 10.3 Campos que afectan al enlace -Los campos `list` que modifican propiedades del botón de enlace (radio borde, estilo, etc.) van en el tab **Enlaces**, debajo del campo `linkv2` al que afectan. NO van en Configuración ni en Imágenes. - -### 10.4 Tabs base: definición fija de id, label, color e icono -Los tabs base siempre usan la siguiente definición fija. Este es el orden por defecto; solo se incluyen los tabs que el módulo necesite. Tabs adicionales (ej: "Formulario", "Video") se crean con id, label, color e icono nuevos. - -```javascript -{ id: "configuracion", label: "Configuración", color: "#f59e0b", icon: '' }, - -{ id: "imagenes", label: "Imágenes", color: "#10b981", icon: '' }, - -{ id: "textos", label: "Textos", color: "#3b82f6", icon: '' }, - -{ id: "bloques", label: "Bloques", color: "#ec4899", icon: '' }, - -{ id: "enlaces", label: "Enlaces", color: "#ef4444", icon: '' }, - -{ id: "colores", label: "Colores", color: "#8b5cf6", icon: '' }, -``` - -### 10.5 Campos globales que afectan al multi van DENTRO del tab Bloques -Los campos `list` o `textfield` generales (no de records) que afectan visualmente a los elementos del multi (ej: radio de borde de los bloques, alineación del texto de los bloques, diseño del enlace de los bloques) deben colocarse **dentro del tab Bloques**, en la zona **superior**, ANTES del bloque descriptivo "Bloques del multi" y del ``. Estos campos NO van en Configuración ni en otros tabs, ya que pertenecen conceptualmente a los bloques. - -### 10.6 Bloque descriptivo "Bloques del multi" antes de acai-vue-records -Siempre añadir un bloque descriptivo con el icono `icon-tabler-stack-2` y el texto "Bloques del multi : Personaliza los bloques del multi." justo antes de ``: -```html - -
-
-
- -

Bloques del multi : Personaliza los bloques del multi.

-
-
-
-``` - -### 10.7 Slot de acai-vue-records: NO desestructurar `color` -El slot de `` NUNCA debe desestructurar `color`. Siempre usar: -```html -