Форматирование текста

Отображение текста в Slim Select | JavaScript library строится вокруг данных, передаваемых в массиве опций. Каждая опция описывается объектом, где минимальный набор включает поля text и value. Именно text определяет визуальное представление элемента в списке и в выбранном состоянии, если не задано кастомное форматирование.

new SlimSelect({
  select: '#select',
  data: [
    { text: 'JavaScript', value: 'js' },
    { text: 'TypeScript', value: 'ts' }
  ]
});

Поле text интерпретируется как строка отображения без дополнительной обработки, если не используется HTML-режим или кастомный рендер.


Базовое текстовое представление и ограничения поля text

Поле text в стандартной конфигурации воспринимается как plain text. Любые HTML-теги, переданные в строке, не должны рассматриваться как разметка в корректной реализации, поскольку это может привести к XSS-уязвимостям при небезопасной вставке.

Структура данных:

{
  text: 'Option label',
  value: 'option_value'
}

Дополнительные поля игнорируются движком отображения, если не подключены кастомные шаблоны.


HTML-форматирование внутри опций

Для расширенного форматирования используется поддержка HTML-строк в text или специализированные рендер-функции. При включении HTML-режима появляется возможность вставлять разметку, включая иконки, выделения, цветовые маркеры.

Пример HTML в text:

{
  text: '<span class="label">JavaScript</span> <small>ES6+</small>',
  value: 'js'
}

При таком подходе визуальная структура формируется напрямую через HTML, но требует строгого контроля входных данных.

Типичные элементы форматирования:

  • <strong> для выделения
  • <em> для акцента
  • <span> для стилизации через CSS
  • inline-иконки через <img> или SVG

Кастомные шаблоны отображения опций

Гибкий способ форматирования реализуется через функции рендера. Slim Select | JavaScript library позволяет переопределять отображение каждой опции через callback-функции.

new SlimSelect({
  select: '#select',
  renderOption: (data) => {
    return `
      <div class="option-item">
        <strong>${data.text}</strong>
        <span class="muted">${data.value}</span>
      </div>
    `;
  }
});

Такой подход разделяет данные и представление, позволяя строить сложные UI-компоненты внутри dropdown.

Ключевые возможности кастомного рендера:

  • добавление HTML-структуры любой сложности
  • использование условного форматирования
  • динамическое отображение меток
  • интеграция с иконками и статусами

Форматирование выбранного значения

Отдельное внимание уделяется отображению выбранного элемента. В стандартной конфигурации выбранное значение наследует text, но часто требуется иной формат отображения.

Пример кастомизации выбранного значения:

new SlimSelect({
  select: '#select',
  renderSelection: (data) => {
    return `
      <div class="selected-item">
        <span class="title">${data.text}</span>
        <span class="code">[${data.value}]</span>
      </div>
    `;
  }
});

Это позволяет:

  • отделить отображение списка и выбранного состояния
  • сокращать текст в выбранном состоянии
  • добавлять вспомогательные метки

Группировка и форматирование заголовков

При использовании групп опций структура расширяется до вложенных элементов. Заголовки групп формируются через отдельные объекты с признаком группы.

{
  label: 'Frontend',
  options: [
    { text: 'React', value: 'react' },
    { text: 'Vue', value: 'vue' }
  ]
}

Форматирование заголовков групп обычно реализуется через CSS, но возможно и через кастомный рендер:

renderGroupLabel: (data) => {
  return `<div class="group-title">${data.label}</div>`;
}

Группы часто используют:

  • визуальное разделение категорий
  • закрепление заголовков
  • стилизацию фона и отступов

Подсветка и форматирование результатов поиска

Встроенный поиск в Slim Select | JavaScript library может быть расширен подсветкой совпадений. Хотя базовая библиотека не навязывает форматирование, его реализуют через модификацию отображаемого текста.

Пример подсветки:

renderOption: (data) => {
  const query = data.search || '';
  const highlighted = data.text.replace(
    new RegExp(query, 'gi'),
    (match) => `<mark>${match}</mark>`
  );

  return `<div>${highlighted}</div>`;
}

Основные техники:

  • подсветка совпадающих символов
  • изменение веса шрифта для релевантных частей
  • скрытие второстепенного текста при поиске

Использование иконок и сложных структур

Форматирование текста часто дополняется визуальными элементами. Внутри опций можно комбинировать текст и графику.

{
  text: 'GitHub',
  value: 'github',
  icon: '/icons/github.svg'
}

Рендер:

renderOption: (data) => {
  return `
    <div class="option-with-icon">
      <img src="${data.icon}" />
      <span>${data.text}</span>
    </div>
  `;
}

Такая структура используется для:

  • брендов и сервисов
  • статусов (success, error, warning)
  • языков программирования с логотипами

Контроль HTML и безопасность отображения

При использовании HTML-форматирования в Slim Select | JavaScript library критическим становится контроль входных данных. Любой пользовательский текст, попадающий в renderOption или text, должен быть экранирован.

Типичные риски:

  • внедрение <script>
  • подмена атрибутов HTML
  • инъекция событий (onclick, onerror)

Подходы к защите:

  • экранирование символов <, >, &
  • запрет inline-обработчиков событий
  • использование только доверенных источников данных
  • разделение данных и HTML-структуры

Стилизация текста через CSS-классы

Форматирование часто выносится из HTML в CSS, что упрощает поддержку интерфейса.

.option-item {
  display: flex;
  justify-content: space-between;
}

.option-item strong {
  font-weight: 600;
}

.option-item .muted {
  color: #888;
  font-size: 12px;
}

Преимущества такого подхода:

  • единая система дизайна
  • переиспользуемость стилей
  • упрощение логики рендера

Комбинированные структуры отображения

На практике форматирование редко ограничивается одной техникой. В Slim Select | JavaScript library часто комбинируются:

  • HTML-разметка
  • кастомные рендер-функции
  • CSS-модули
  • иконки и бейджи
  • подсветка поиска

Пример комплексной опции:

renderOption: (data) => {
  return `
    <div class="row">
      <img class="icon" src="${data.icon}" />
      <div class="content">
        <div class="title">${data.text}</div>
        <div class="subtitle">${data.value}</div>
      </div>
      <span class="badge">${data.type}</span>
    </div>
  `;
}

Такой подход позволяет превращать обычный dropdown в полноценный UI-компонент с многоуровневой визуальной структурой.