import { Color } from '@ionic/core'; import { TextMetadata } from '../../atoms/text/types'; import { TitleMetadata } from '../../atoms/title/types'; import { ButtonMetadata } from '../../types'; /** * Tipos de contenido soportados en el componente val-article */ export type ArticleContentType = 'title' | 'subtitle' | 'text' | 'paragraph' | 'quote' | 'highlight' | 'code' | 'note' | 'command' | 'list' | 'button' | 'separator' | 'image' | 'video' | 'custom'; /** * Configuración de espaciado entre elementos */ export interface ArticleSpacing { /** Espaciado superior */ top?: 'none' | 'small' | 'medium' | 'large' | 'xlarge'; /** Espaciado inferior */ bottom?: 'none' | 'small' | 'medium' | 'large' | 'xlarge'; /** Espaciado lateral */ horizontal?: 'none' | 'small' | 'medium' | 'large' | 'xlarge'; } /** * Configuración base para cualquier elemento del artículo */ export interface BaseArticleElement { /** Tipo de elemento */ type: ArticleContentType; /** ID único del elemento (opcional) */ id?: string; /** Clases CSS adicionales */ cssClass?: string; /** Configuración de espaciado */ spacing?: ArticleSpacing; /** Elemento visible condicionalmente */ visible?: boolean; } /** * Elemento de título */ export interface ArticleTitleElement extends BaseArticleElement { type: 'title'; props: TitleMetadata; } /** * Elemento de subtítulo */ export interface ArticleSubtitleElement extends BaseArticleElement { type: 'subtitle'; props: TitleMetadata; } /** * Elemento de texto/párrafo */ export interface ArticleTextElement extends BaseArticleElement { type: 'text' | 'paragraph'; props: TextMetadata; } /** * Elemento de cita */ export interface ArticleQuoteElement extends BaseArticleElement { type: 'quote'; props: TextMetadata & { /** Autor de la cita */ author?: string; /** Fuente de la cita */ source?: string; /** Color del nombre del autor */ authorColor?: Color; /** Alineación del texto */ alignment?: 'left' | 'center' | 'right'; /** Mostrar comillas decorativas */ showQuoteMark?: boolean; }; } /** * Elemento de texto destacado */ export interface ArticleHighlightElement extends BaseArticleElement { type: 'highlight'; props: TextMetadata & { /** Color de fondo del highlight */ backgroundColor?: Color; /** Esquinas redondeadas */ rounded?: boolean; }; } /** * Elemento de código */ export interface ArticleCodeElement extends BaseArticleElement { type: 'code'; props: { /** Código a mostrar */ code: string; /** Lenguaje de programación */ language?: string; /** Mostrar números de línea */ showLineNumbers?: boolean; /** Tema del código */ theme?: 'light' | 'dark'; }; } /** * Elemento de nota destacada */ export interface ArticleNoteElement extends BaseArticleElement { type: 'note'; props: { /** Texto principal de la nota. Puede contener ``/`` si `allowPartialBold` está activo. */ text: string; /** Prefijo en negrita (ej: "Nota:"). Pasa `''` (string vacío) para suprimir el prefijo. */ prefix?: string; /** Color de fondo */ color?: Color; /** Color del texto */ textColor?: Color; /** Tamaño del texto */ size?: 'small' | 'medium' | 'large' | 'xlarge'; /** Esquinas redondeadas */ rounded?: boolean; /** Padding personalizado */ padding?: string; /** Renderiza ``/`` inline en `text` via innerHTML. Default `false`. */ allowPartialBold?: boolean; /** Procesa URLs y `[text](url)` en `text`. Default `false`. */ processLinks?: boolean; /** Compact mode — inline-block fit-content, padding reducido, sin left-border. */ compact?: boolean; /** Alineación del texto. Default `'left'`. */ align?: 'left' | 'center' | 'right'; }; } /** * Elemento de comando de terminal */ export interface ArticleCommandElement extends BaseArticleElement { type: 'command'; props: { /** Líneas de comando */ lines: Array<{ /** Texto del comando */ text: string; /** Tipo de línea */ type?: 'normal' | 'command' | 'success' | 'error'; }>; /** Mostrar botón de copiar */ showCopyButton?: boolean; /** Lenguaje (opcional) */ language?: string; }; } /** * Elemento de lista */ export interface ArticleListElement extends BaseArticleElement { type: 'list'; props: { /** Elementos de la lista */ items: Array<{ /** Texto del elemento */ text: string; /** Configuración de contenido reactivo */ contentKey?: string; contentClass?: string; contentFallback?: string; contentInterpolation?: Record; }>; /** Tipo de lista */ listType?: 'unordered' | 'ordered' | 'checklist'; /** Color de los elementos */ color?: Color; }; } /** * Elemento de botón */ export interface ArticleButtonElement extends BaseArticleElement { type: 'button'; props: ButtonMetadata & { /** Alineación del botón */ alignment?: 'left' | 'center' | 'right'; }; } /** * Elemento separador */ export interface ArticleSeparatorElement extends BaseArticleElement { type: 'separator'; props: { /** Tipo de separador */ style?: 'line' | 'dots' | 'space'; /** Color del separador */ color?: Color; /** Grosor del separador */ thickness?: 'thin' | 'medium' | 'thick'; }; } /** * Elemento de imagen */ export interface ArticleImageElement extends BaseArticleElement { type: 'image'; props: { /** URL de la imagen */ src: string; /** Texto alternativo */ alt: string; /** Título de la imagen */ title?: string; /** Leyenda de la imagen */ caption?: string; /** Configuración de contenido reactivo para caption */ captionContentKey?: string; captionContentClass?: string; captionContentFallback?: string; /** Alineación de la imagen */ alignment?: 'left' | 'center' | 'right'; /** Ancho máximo */ maxWidth?: string; /** Imagen con bordes redondeados */ rounded?: boolean; /** Tamaño de la imagen */ size?: 'small' | 'medium' | 'large' | 'xlarge'; /** Modo preview (click para ampliar) */ preview?: boolean; }; } /** * Elemento de video */ export interface ArticleVideoElement extends BaseArticleElement { type: 'video'; props: { /** URL del video */ src: string; /** Imagen de poster */ poster?: string; /** Título del video */ title?: string; /** Controles visibles */ controls?: boolean; /** Reproducción automática */ autoplay?: boolean; /** Silenciado por defecto */ muted?: boolean; /** Ancho máximo */ maxWidth?: string; }; } /** * Elemento personalizado */ export interface ArticleCustomElement extends BaseArticleElement { type: 'custom'; props: { /** Contenido HTML personalizado */ htmlContent?: string; /** Clase de componente personalizado */ componentClass?: any; /** Props para el componente personalizado */ componentProps?: any; }; } /** * Unión de todos los tipos de elementos posibles */ export type ArticleElement = ArticleTitleElement | ArticleSubtitleElement | ArticleTextElement | ArticleQuoteElement | ArticleHighlightElement | ArticleCodeElement | ArticleNoteElement | ArticleCommandElement | ArticleListElement | ArticleButtonElement | ArticleSeparatorElement | ArticleImageElement | ArticleVideoElement | ArticleCustomElement; /** * Configuración del artículo completo */ export interface ArticleMetadata { /** Elementos del artículo */ elements: ArticleElement[]; /** Padding interno del contenedor article */ containerSpacing?: ArticleSpacing; /** Override global de spacing para elementos (prioridad sobre spacing por tipo) */ elementSpacing?: ArticleSpacing; /** @deprecated Usar elementSpacing en su lugar */ defaultSpacing?: ArticleSpacing; /** Ancho máximo del artículo */ maxWidth?: string; /** Centrar el artículo */ centered?: boolean; /** Tema del artículo */ theme?: 'light' | 'dark' | 'auto'; /** Clases CSS adicionales */ cssClass?: string; } /** * Configuración de espaciado predefinida */ export declare const ARTICLE_SPACING: { readonly NONE: ArticleSpacing; readonly SMALL: ArticleSpacing; readonly MEDIUM: ArticleSpacing; readonly LARGE: ArticleSpacing; readonly XLARGE: ArticleSpacing; readonly TITLE: ArticleSpacing; readonly SUBTITLE: ArticleSpacing; readonly PARAGRAPH: ArticleSpacing; readonly QUOTE: ArticleSpacing; readonly CODE: ArticleSpacing; readonly NOTE: ArticleSpacing; readonly COMMAND: ArticleSpacing; readonly LIST: ArticleSpacing; readonly BUTTON: ArticleSpacing; readonly IMAGE: ArticleSpacing; readonly SEPARATOR: ArticleSpacing; }; /** * Función helper para crear elementos de artículo de forma fácil */ export declare class ArticleBuilder { private elements; /** * Añade un título al artículo */ title(props: TitleMetadata, options?: Partial): ArticleBuilder; /** * Añade un subtítulo al artículo */ subtitle(props: TitleMetadata, options?: Partial): ArticleBuilder; /** * Añade un párrafo al artículo */ paragraph(props: TextMetadata, options?: Partial): ArticleBuilder; /** * Añade una cita al artículo */ quote(props: ArticleQuoteElement['props'], options?: Partial): ArticleBuilder; /** * Añade código al artículo */ code(code: string, language?: string, options?: Partial): ArticleBuilder; /** * Añade una lista al artículo */ list(items: ArticleListElement['props']['items'], listType?: ArticleListElement['props']['listType'], options?: Partial): ArticleBuilder; /** * Añade un botón al artículo */ button(props: ButtonMetadata, alignment?: 'left' | 'center' | 'right', options?: Partial): ArticleBuilder; /** * Añade un separador al artículo */ separator(style?: 'line' | 'dots' | 'space', options?: Partial): ArticleBuilder; /** * Añade una imagen al artículo */ image(src: string, alt: string, caption?: string, options?: Partial): ArticleBuilder; /** * Añade una nota destacada al artículo */ note(text: string, prefix?: string, color?: Color, options?: Partial): ArticleBuilder; /** * Añade un comando de terminal al artículo * Acepta un string simple o un array de comandos */ command(command: string | string[], options?: Partial): ArticleBuilder; /** * Construye el artículo final */ build(config?: Partial): ArticleMetadata; /** * Resetea el builder para crear un nuevo artículo */ clear(): ArticleBuilder; }