@gambito-corp/mbs-library
Version:
Librería de componentes React reutilizables - Sistema de diseño modular y escalable
157 lines (129 loc) • 4.17 kB
JavaScript
import { INPUT_VARIANTS, INPUT_SIZES, VALIDATION_PATTERNS } from './Input.constants.js';
/**
* Genera las clases BEM para el componente Input
*/
export const getInputBEMClasses = ({
variant = 'default',
size = 'medium',
fullWidth = true,
disabled = false,
readOnly = false,
hasIconLeft = false,
hasIconRight = false,
className = ''
}) => {
const base = 'input';
const mods = [];
// Variante
if (variant !== 'default') {
mods.push(`${base}--${variant}`);
}
// Tamaño
if (size !== 'medium') {
mods.push(`${base}--${size}`);
}
// Estados
if (fullWidth) mods.push(`${base}--full`);
if (disabled) mods.push(`${base}--disabled`);
if (readOnly) mods.push(`${base}--readonly`);
if (hasIconLeft) mods.push(`${base}--with-icon-left`);
if (hasIconRight) mods.push(`${base}--with-icon-right`);
return [base, ...mods, className].filter(Boolean).join(' ');
};
/**
* Genera clases BEM para el contenedor
*/
export const getInputContainerBEMClasses = (fullWidth = true) => {
const base = 'input-container';
const mods = [];
if (fullWidth) mods.push(`${base}--full`);
return [base, ...mods].filter(Boolean).join(' ');
};
/**
* Genera clases BEM para el wrapper
*/
export const getInputWrapperBEMClasses = () => {
return 'input__wrapper';
};
/**
* Genera clases BEM para iconos
*/
export const getInputIconBEMClasses = (position = 'left', clickable = false) => {
const base = 'input__icon';
const mods = [];
mods.push(`${base}--${position}`);
if (clickable) mods.push(`${base}--clickable`);
return [base, ...mods].filter(Boolean).join(' ');
};
/**
* Genera clases BEM para etiquetas
*/
export const getInputLabelBEMClasses = (required = false) => {
const base = 'input__label';
const mods = [];
if (required) mods.push(`${base}--required`);
return [base, ...mods].filter(Boolean).join(' ');
};
/**
* Genera clases BEM para mensajes
*/
export const getInputMessageBEMClasses = (type = 'default') => {
const base = 'input__message';
const mods = [];
if (type !== 'default') mods.push(`${base}--${type}`);
return [base, ...mods].filter(Boolean).join(' ');
};
/**
* Valida un input según su tipo
*/
export const validateInput = (value, type = 'text', required = false) => {
const result = {
isValid: true,
message: ''
};
if (required && (!value || value.trim() === '')) {
result.isValid = false;
result.message = 'Este campo es requerido';
return result;
}
if (!value || value.trim() === '') {
return result;
}
const validation = VALIDATION_PATTERNS[type];
if (validation && !validation.pattern.test(value)) {
result.isValid = false;
result.message = validation.message;
}
return result;
};
/**
* Obtiene el icono apropiado para un tipo de input
*/
export const getIconForInputType = (type) => {
const iconMap = {
email: 'envelope',
password: 'lock',
search: 'search',
tel: 'phone',
url: 'link',
text: 'font',
number: 'hashtag'
};
return iconMap[type] || null;
};
/**
* Formatea el valor según el tipo de input
*/
export const formatInputValue = (value, type) => {
if (!value) return value;
switch (type) {
case 'tel':
return value.replace(/\D/g, '').replace(/(\d{3})(\d{3})(\d{4})/, '($1) $2-$3');
case 'number':
return value.replace(/[^\d.-]/g, '');
case 'email':
return value.toLowerCase().trim();
default:
return value;
}
};