Templates
Templates personalizados usando apenas emojis e CSS, sem dependências externas. Customize a aparência dos itens no dropdown e na seleção.
Países com Bandeiras e Códigos
Emojis de bandeiras nativas + badges com códigos de país.
Ver código
HTML
<select id="countries"></select>
JavaScript
const countriesData = [
{ id: 'us', text: 'United States', flag: '🇺🇸', code: 'US' },
{ id: 'br', text: 'Brazil', flag: '🇧🇷', code: 'BR' },
{ id: 'uk', text: 'United Kingdom', flag: '🇬🇧', code: 'UK' },
{ id: 'fr', text: 'France', flag: '🇫🇷', code: 'FR' },
{ id: 'de', text: 'Germany', flag: '🇩🇪', code: 'DE' }
];
new VanillaSmartSelect('#countries', {
data: countriesData,
placeholder: 'Selecione um país...',
allowClear: true,
templateResult: (item) => {
const div = document.createElement('div');
div.style.display = 'flex';
div.style.alignItems = 'center';
div.style.gap = '10px';
div.innerHTML = `
<span style="font-size: 24px;">${item.flag}</span>
<span style="font-weight: 500; flex: 1;">${item.text}</span>
<span style="background: #e9ecef; padding: 2px 8px; border-radius: 3px;
font-size: 11px; font-weight: 600;">${item.code}</span>
`;
return div;
},
templateSelection: (item) => {
return `${item.flag} ${item.text} (${item.code})`;
}
});
Usuários com Avatares Emoji
Avatares coloridos com gradientes + informações de cargo.
Ver código
HTML
<select id="users"></select>
JavaScript
const usersData = [
{ id: 1, text: 'Ana Silva', role: 'Gerente de Projetos', emoji: '👩💼' },
{ id: 2, text: 'Carlos Santos', role: 'Desenvolvedor Senior', emoji: '👨💻' },
{ id: 3, text: 'Maria Oliveira', role: 'Designer UX/UI', emoji: '👩🎨' },
{ id: 4, text: 'João Costa', role: 'Analista de Dados', emoji: '👨🔬' },
{ id: 5, text: 'Paula Ferreira', role: 'Product Manager', emoji: '👩🚀' }
];
new VanillaSmartSelect('#users', {
data: usersData,
placeholder: 'Selecione um usuário...',
allowClear: true,
templateResult: (item) => {
const div = document.createElement('div');
div.style.display = 'flex';
div.style.alignItems = 'center';
div.style.gap = '12px';
div.innerHTML = `
<div style="font-size: 32px; width: 40px; height: 40px; display: flex;
align-items: center; justify-content: center;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 50%;">${item.emoji}</div>
<div>
<div style="font-weight: 500;">${item.text}</div>
<div style="font-size: 12px; color: #666;">${item.role}</div>
</div>
`;
return div;
},
templateSelection: (item) => {
return `${item.emoji} ${item.text}`;
}
});
Templates Diferentes: Dropdown vs Seleção
Demonstra como usar templates detalhados no dropdown e simplificados na seleção.
Ver código
HTML
<select id="employees"></select>
JavaScript
const employeesData = [
{ id: 1, text: 'Sarah Connor', role: 'Engineering Manager', department: 'Engineering', emoji: '👩💼' },
{ id: 2, text: 'Kyle Reese', role: 'Senior Developer', department: 'Engineering', emoji: '👨💻' },
{ id: 3, text: 'Miles Dyson', role: 'Tech Lead', department: 'Research', emoji: '👨🔬' },
{ id: 4, text: 'John Connor', role: 'Product Manager', department: 'Product', emoji: '👨🚀' }
];
new VanillaSmartSelect('#employees', {
data: employeesData,
placeholder: 'Selecione um funcionário...',
allowClear: true,
// Template detalhado para o dropdown
templateResult: (item) => {
const div = document.createElement('div');
div.style.display = 'flex';
div.style.alignItems = 'center';
div.style.gap = '12px';
div.innerHTML = `
<div style="width: 40px; height: 40px; display: flex; align-items: center;
justify-content: center; font-size: 24px; border-radius: 50%;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);">
${item.emoji}
</div>
<div>
<div style="font-weight: 500;">${item.text}</div>
<div style="font-size: 12px; color: #666;">
${item.role} • ${item.department}
</div>
</div>
`;
return div;
},
// Template simplificado para o item selecionado (apenas nome)
templateSelection: (item) => {
return item.text;
}
});
✅ Flexibilidade: Use
templateResult para mostrar informações detalhadas no dropdown
e templateSelection para manter a seleção limpa e compacta.
Produtos com Ícones e Preços
Ícones emoji + nome, categoria e preço formatado.
Ver código
HTML
<select id="products"></select>
JavaScript
const productsData = [
{ id: 1, text: 'Notebook Pro', category: 'Eletrônicos', price: 4299.90, icon: '💻', color: '#007bff' },
{ id: 2, text: 'Mouse Wireless', category: 'Periféricos', price: 89.90, icon: '🖱️', color: '#28a745' },
{ id: 3, text: 'Teclado Mecânico', category: 'Periféricos', price: 349.90, icon: '⌨️', color: '#17a2b8' },
{ id: 4, text: 'Monitor 4K 27"', category: 'Eletrônicos', price: 1899.90, icon: '🖥️', color: '#6f42c1' },
{ id: 5, text: 'Webcam HD', category: 'Acessórios', price: 299.90, icon: '📹', color: '#fd7e14' }
];
new VanillaSmartSelect('#products', {
data: productsData,
placeholder: 'Selecione um produto...',
allowClear: true,
templateResult: (item) => {
const div = document.createElement('div');
div.style.display = 'flex';
div.style.alignItems = 'center';
div.style.gap = '12px';
div.innerHTML = `
<div style="width: 40px; height: 40px; display: flex; align-items: center;
justify-content: center; border-radius: 8px; font-size: 24px;
background: ${item.color}20; color: ${item.color};">
${item.icon}
</div>
<div style="flex: 1;">
<div style="font-weight: 500;">${item.text}</div>
<div style="font-size: 12px; color: #666;">${item.category}</div>
</div>
<div style="font-weight: 600; color: #007bff;">
R$ ${item.price.toFixed(2).replace('.', ',')}
</div>
`;
return div;
},
templateSelection: (item) => {
return `${item.icon} ${item.text} - R$ ${item.price.toFixed(2).replace('.', ',')}`;
}
});
Tasks com Status (Multi-Select)
Multi-select com ícones de status e badges coloridos.
Ver código
HTML
<select id="tasks" multiple></select>
JavaScript
const tasksData = [
{ id: 1, text: 'Atualizar documentação', status: 'active', statusText: 'Em andamento', icon: '📝' },
{ id: 2, text: 'Corrigir bug #123', status: 'active', statusText: 'Em andamento', icon: '🐛' },
{ id: 3, text: 'Revisar pull request', status: 'pending', statusText: 'Pendente', icon: '👀' },
{ id: 4, text: 'Deploy em produção', status: 'pending', statusText: 'Pendente', icon: '🚀' },
{ id: 5, text: 'Implementar feature X', status: 'completed', statusText: 'Concluído', icon: '✅' }
];
const statusColors = {
active: { bg: '#d4edda', text: '#155724' },
pending: { bg: '#fff3cd', text: '#856404' },
completed: { bg: '#cce5ff', text: '#004085' },
cancelled: { bg: '#f8d7da', text: '#721c24' }
};
new VanillaSmartSelect('#tasks', {
data: tasksData,
placeholder: 'Selecione as tasks...',
multiple: true,
maximumSelectionLength: 4,
templateResult: (item) => {
const div = document.createElement('div');
div.style.display = 'flex';
div.style.alignItems = 'center';
div.style.justifyContent = 'space-between';
div.style.gap = '12px';
const colors = statusColors[item.status];
div.innerHTML = `
<span style="font-size: 20px;">${item.icon}</span>
<span style="flex: 1;">${item.text}</span>
<span style="padding: 3px 10px; border-radius: 12px; font-size: 11px;
font-weight: 600; background: ${colors.bg}; color: ${colors.text};">
${item.statusText}
</span>
`;
return div;
},
templateSelection: (item) => {
return `${item.icon} ${item.text} - ${item.statusText}`;
}
});
Categorias com Contadores
Template simplificado na seleção, detalhado no dropdown.
Ver código
HTML
<select id="categories"></select>
JavaScript
const categoriesData = [
{ id: 1, text: 'Documentos', icon: '📄', count: 127 },
{ id: 2, text: 'Imagens', icon: '🖼️', count: 543 },
{ id: 3, text: 'Vídeos', icon: '🎬', count: 89 },
{ id: 4, text: 'Músicas', icon: '🎵', count: 234 },
{ id: 5, text: 'Planilhas', icon: '📊', count: 67 }
];
new VanillaSmartSelect('#categories', {
data: categoriesData,
placeholder: 'Selecione uma categoria...',
allowClear: true,
templateResult: (item) => {
const div = document.createElement('div');
div.style.display = 'flex';
div.style.alignItems = 'center';
div.style.gap = '10px';
div.innerHTML = `
<span style="font-size: 24px;">${item.icon}</span>
<div style="flex: 1;">
<span style="font-weight: 500;">${item.text}</span>
<span style="font-size: 11px; color: #666; background: #e9ecef;
padding: 2px 6px; border-radius: 10px; margin-left: 8px;">
${item.count} itens
</span>
</div>
`;
return div;
},
templateSelection: (item) => {
return `${item.icon} ${item.text}`;
}
});
Como Funcionam os Templates
📋 Conceitos Principais:
- templateResult: Controla a aparência dos itens no dropdown (lista suspensa)
- templateSelection: Controla a aparência do item selecionado (campo de seleção)
- Retorno: Pode retornar string HTML ou elemento DOM (createElement)
- Emojis nativos: Funcionam em todos os navegadores modernos, sem imagens externas
- CSS inline: Estilos aplicados diretamente nos elementos para simplicidade
Técnicas e Boas Práticas
📋 Dicas para Templates Eficientes:
- createElement vs innerHTML: Use
createElementpara maior segurança e performance - Fallback de dados: Sempre verifique se propriedades existem antes de usar
- CSS inline vs classes: Inline é mais simples para exemplos, classes são melhores para produção
- Performance: Templates são renderizados para cada item visível - evite operações pesadas
- Teste com volume: Verifique performance com 100+ itens no select
- Mantenha simples na seleção: templateSelection deve ser conciso
- Detalhes no dropdown: templateResult pode ter mais informações e elementos visuais
📌 Recomendações de Acessibilidade:
- Contraste: Mantenha contraste adequado entre texto e fundo (WCAG AA)
- Tamanhos consistentes: Use tamanhos consistentes de ícones e elementos visuais
- Use emojis nativos: Funcionam bem em leitores de tela e não dependem de recursos externos
- Mobile responsive: Templates devem funcionar bem em telas pequenas
- Loading states: Forneça feedback visual para carregamento de dados remotos