Slim Select предоставляет механизм кастомизации отображения опций
через шаблоны рендеринга, что позволяет внедрять иконки прямо в элементы
списка выбора. Основной подход заключается в использовании HTML-разметки
внутри text, innerHTML-ориентированных
конфигураций или через функции кастомного рендера
render.
Иконки в опциях обычно используются для визуального различения сущностей: типов данных, категорий, статусов, ролей или любых семантически значимых групп. В рамках Slim Select это реализуется без изменения базовой логики компонента — только на уровне отображения.
Наиболее простой способ добавить иконки — передать HTML непосредственно в текст опции.
new SlimSelect({
select: '#select',
data: [
{
text: '<span class="icon icon-user"></span> Пользователь',
value: 'user'
},
{
text: '<span class="icon icon-admin"></span> Администратор',
value: 'admin'
}
]
});
CSS-иконки:
.icon {
display: inline-block;
width: 16px;
height: 16px;
margin-right: 8px;
vertical-align: middle;
}
.icon-user {
background: url('/icons/user.svg') no-repeat center;
background-size: contain;
}
.icon-admin {
background: url('/icons/admin.svg') no-repeat center;
background-size: contain;
}
В таком подходе Slim Select просто вставляет HTML как есть, не выполняя его трансформацию. Это делает метод быстрым, но потенциально небезопасным при использовании внешних данных.
SVG-иконки обеспечивают более высокое качество отображения и гибкость стилизации.
data: [
{
text: `
<svg class="ss-icon" viewBox="0 0 24 24">
<path d="M12 2L2 7l10 5 10-5-10-5z"></path>
</svg>
Проект
`,
value: 'project'
}
]
.ss-icon {
width: 16px;
height: 16px;
margin-right: 6px;
vertical-align: middle;
fill: currentColor;
}
SVG позволяет управлять цветом через currentColor, что
удобно при адаптации под темы интерфейса.
Slim Select поддерживает расширенный рендеринг через
render, что даёт полный контроль над HTML опции.
new SlimSelect({
select: '#select',
data: [
{ text: 'Онлайн', value: 'online', icon: 'online' },
{ text: 'Оффлайн', value: 'offline', icon: 'offline' }
],
render: {
option: (data) => {
return `
<div class="option-item">
<span class="status-icon status-${data.icon}"></span>
<span>${data.text}</span>
</div>
`;
},
selected: (data) => {
return `
<div class="selected-item">
<span class="status-icon status-${data.icon}"></span>
<span>${data.text}</span>
</div>
`;
}
}
});
CSS:
.option-item,
.selected-item {
display: flex;
align-items: center;
gap: 8px;
}
.status-icon {
width: 10px;
height: 10px;
border-radius: 50%;
}
.status-online {
background-color: #2ecc71;
}
.status-offline {
background-color: #e74c3c;
}
Такой подход отделяет данные от представления и упрощает масштабирование интерфейса.
Slim Select не ограничивает использование сторонних иконочных систем. Часто применяются:
Пример с Font Awesome:
data: [
{
text: '<i class="fa fa-user"></i> Профиль',
value: 'profile'
},
{
text: '<i class="fa fa-cog"></i> Настройки',
value: 'settings'
}
]
Особенность подхода заключается в том, что библиотека иконок должна быть заранее подключена в проекте, иначе элементы не отобразятся.
Иконки часто определяются не статически, а через бизнес-логику.
const users = [
{ name: 'Алексей', role: 'admin' },
{ name: 'Ирина', role: 'editor' },
{ name: 'Павел', role: 'viewer' }
];
const data = users.map(user => {
let iconClass = '';
switch (user.role) {
case 'admin':
iconClass = 'icon-admin';
break;
case 'editor':
iconClass = 'icon-editor';
break;
default:
iconClass = 'icon-viewer';
}
return {
text: `<span class="${iconClass}"></span> ${user.name}`,
value: user.name
};
});
new SlimSelect({
select: '#select',
data
});
Такой подход позволяет централизованно управлять отображением ролей и статусов.
Более устойчивый подход — хранить иконку отдельно от текста, а не внедрять HTML в строку.
data: [
{
text: 'Документы',
value: 'docs',
icon: 'file'
},
{
text: 'Изображения',
value: 'images',
icon: 'image'
}
]
И рендер:
render: {
option: (data) => `
<div class="option">
<span class="icon icon-${data.icon}"></span>
<span>${data.text}</span>
</div>
`
}
Преимущество такого подхода — разделение логики данных и UI, что снижает связность компонентов.
Иконки могут отражать состояния элементов: активность, доступность, ошибки.
render: {
option: (data) => {
const disabledClass = data.disabled ? 'is-disabled' : '';
return `
<div class="option ${disabledClass}">
<span class="icon icon-${data.type}"></span>
<span>${data.text}</span>
${data.disabled ? '<span class="badge">недоступно</span>' : ''}
</div>
`;
}
}
.is-disabled {
opacity: 0.5;
}
.badge {
margin-left: auto;
font-size: 10px;
color: #999;
}
Внедрение HTML и иконок в опции увеличивает нагрузку на DOM-рендеринг, особенно при больших списках.
Ключевые моменты оптимизации:
При больших наборах данных предпочтительнее использовать упрощённые иконки (например, CSS-бейджи или символы), а не полноценные SVG-графики.
Slim Select часто используется в системах с тёмной и светлой темой, что требует адаптивных иконок.
.ss-dark .icon {
filter: invert(1);
}
.ss-light .icon {
filter: none;
}
Либо через currentColor:
.icon {
fill: currentColor;
color: inherit;
}
Такой подход обеспечивает автоматическую адаптацию без дублирования ресурсов.
Отображение выбранного значения требует отдельного рендера.
render: {
selected: (data) => `
<div class="selected">
<span class="icon icon-${data.icon}"></span>
<span>${data.text}</span>
</div>
`
}
Это позволяет поддерживать единый визуальный язык между списком и выбранным значением, сохраняя консистентность интерфейса.
При группировке опций иконки могут применяться как к группам, так и к отдельным элементам.
render: {
optgroup: (data) => `
<div class="optgroup">
<span class="group-icon icon-${data.icon}"></span>
<span>${data.label}</span>
</div>
`
}
Такой подход усиливает визуальную иерархию и облегчает навигацию по длинным спискам.