Перетаскивание
<sf-sortable> — часть редактора страниц: список, элементы которого можно
переставлять, переносить в другие списки той же группы и копировать из
библиотеки. Работает мышью, пером, касанием и клавиатурой. Компонент только
сообщает намерение; DOM и данные меняет приложение.
Пример
Применение
Элементы и ручки
Элементы списка — потомки с data-sf-sortable-item="<id>"; id приходит в
событиях. Ручка data-sf-sortable-handle внутри элемента ограничивает
перетаскивание и служит целью касания; без ручки перетаскивается весь
элемент. Элементы, добавленные в список позже, становятся перетаскиваемыми
сами. Код компонента загрузчик Framework подключает по требованию, когда на
странице появляется sf-sortable.
orientation="horizontal" говорит, что элементы стоят в строку: место
вставки при перетаскивании указателем считается по горизонтали. Раскладку
списка задают классы, а не этот атрибут.
При перетаскивании указателем элемент по умолчанию поднимается из списка, а
на месте, куда он встанет, открывается контур его размера; соседние элементы
расступаются (preview="silhouette"). preview="line" вместо этого рисует
на месте вставки тонкую линию и оставляет список как есть. В списке, который
переносится в сетку (например, поля в две колонки), контур занимает одну
ячейку в порядке чтения. Перемещение с клавиатуры и внешние цели всегда
показывают линию.
Группы и библиотека
group — имя группы списка по шаблону ^[a-z][a-z0-9-]{0,31}$. Элементы
переносятся между списками одной группы; accepts перечисляет через пробел
дополнительные группы, которые список принимает.
mode="copy" превращает список в библиотеку: элемент остаётся на месте, а в
событии приходит mode: 'copy'. В библиотеку ничего не бросают. На холст
редактора копия попадает через атрибут accepts у
оверлея редактора.
Событие sf-sortable-intent
Когда пользователь отпускает элемент, список-получатель отправляет
sf-sortable-intent с event.detail:
| Поле | Содержимое |
|---|---|
item |
id элемента из data-sf-sortable-item |
from |
id исходного списка, а без id — его group |
to |
id списка-получателя, а без id — его group |
index |
итоговая позиция в списке-получателе |
mode |
move или copy |
index — уже итоговая позиция, поэтому приложению не нужно пересчитывать её
после удаления элемента из исходного списка. Если приложение отклонило
изменение, ничего менять не нужно: компонент сам DOM не трогает.
sf-sortable-state сообщает о сеансе: {state, item}, где state —
picked, когда элемент взят, dropped или cancelled, когда сеанс
закончился.
document.addEventListener('sf-sortable-intent', (event) => {
const {item, from, to, index, mode} = event.detail;
// Применить к своей модели с ожидаемой ревизией; при отказе ничего не менять.
});
Внешние цели
Сеанс перетаскивания общий для всех Smart-компонентов страницы. Цель, которая
не является списком, подключается через
SF.Sortable.registerSortableDropTarget({resolve, drop}): resolve(x, y, session) возвращает место под указателем или null, drop(session, descriptor) отправляет намерение. Вызов возвращает функцию, которая
отключает цель. Так к сеансу подключён оверлей редактора.
Колонки таблицы: SF.Sortable.attach
Ячейки шапки таблицы нельзя обернуть в <sf-sortable>, а колонка переезжает
вместе с ячейками всех строк. Для этого SF.Sortable.attach(container, options)
даёт то же перетаскивание указателем любому контейнеру и возвращает функцию,
которая его отключает. Объект SF.Sortable появляется вместе со скриптом
sf-sortable, поэтому дождитесь его: await SF.whenDefined('sf-sortable').
await SF.whenDefined('sf-sortable');
const detach = SF.Sortable.attach(table.tHead.rows[0], {
items: 'th[data-key]',
extent: table,
cellsOf: (th) => [...table.rows].map((row) => row.cells[th.cellIndex]),
groupOf: (th) => (th.dataset.pinned ? 'pinned' : 'loose'),
canStart: (event) => !event.target.closest('.resizer'),
label: 'Колонки',
onIntent: ({item, index, group}) => saveColumnOrder(item, index, group),
});
| Параметр | Что задаёт |
|---|---|
items |
селектор перетаскиваемых элементов внутри контейнера; обязателен |
extent |
элемент, во всю высоту которого встаёт контур (таблица); по умолчанию контейнер |
cellsOf |
ячейки, которые приглушаются вместе с колонкой; по умолчанию сам элемент |
groupOf |
группа элемента: элемент переставляется только среди своей группы |
canStart |
можно ли начать перетаскивание с этого нажатия |
preview |
column (по умолчанию) — контур шириной в колонку; line — тонкая линия |
label |
имя списка для объявлений |
onIntent |
получает {item, from, index, group}: index — место среди элементов той же группы без перетаскиваемого |
Пока колонку тянут, она приглушена во всех строках, а на её будущем месте
стоит пунктирный контур. Клик, которым заканчивается перетаскивание, до
заголовка не доходит, поэтому сортировка по клику от отпускания не
срабатывает. Порядок применяет приложение в onIntent. Перестановку с
клавиатуры даёт обычный <sf-sortable>, например список колонок в настройках
таблицы.
Доступность
- Задайте списку
label— имя, которое звучит в объявлениях, например «Нужно сделать». Без него используетсяaria-labelили имя группы. - Элементы становятся фокусируемыми и получают описание с инструкцией. Имя
элемента — его
aria-labelили видимый текст без частей сaria-hidden="true", поэтому значок ручки помечайтеaria-hidden. SpaceилиEnterберут элемент, стрелки вверх и вниз меняют позицию, влево и вправо переводят в соседний список или на внешнюю цель,SpaceилиEnterкладут,EscapeилиTabотменяют.- Каждый шаг объявляется на языке страницы через живую область.
- У краёв прокручиваемой области во время перетаскивания включается автопрокрутка.
Справочник API
Раздел собран из манифеста компонента выпуска ui-106d5901f8c3 и обновляется вместе с выпуском. Чтобы исправить описание, исправьте манифест.
Каждому атрибуту соответствует свойство элемента с тем же именем в camelCase: search-placeholder — searchPlaceholder. Свойство атрибута template называется templateName.
| Тег | <sf-sortable> |
| Назначение | Список с перетаскиванием для изменения порядка, переноса между списками и копирования из библиотеки мышью, пером, касанием и с клавиатуры; только сообщает о намерении. |
| Контракт | smart.sortable, версия 1.0.0 |
| Поставка | выпуск Framework ui-106d5901f8c3 |
| Жизненный цикл | экспериментальный: API может меняться между выпусками |
| Готовность | работает в сценарии студии, продуктовой приёмки нет |
| Заготовка до прихода кода | нет: атрибут data-sf-skeleton не пишется; своего скелетона при загрузке данных нет (Заготовка до прихода кода) |
Атрибуты
group—string, значения: шаблон^[a-z][a-z0-9-]{0,31}$.accepts—string, по умолчанию пусто.mode—string, по умолчаниюmove, значения:move,copy.orientation—string, по умолчаниюvertical, значения:vertical,horizontal.label—string, по умолчанию пусто.preview—string, по умолчаниюsilhouette, значения:silhouette,line. Как перетаскивание указателем показывает, куда встанет пункт: silhouette поднимает пункт из списка и открывает на его будущем месте контур его размера, а список расступается; line рисует там тонкую линию и не трогает список. Перемещение с клавиатуры и внешние цели всегда показывают линию; в списке, который переносится в сетку, контур занимает одну ячейку в порядке чтения.
Методы
Публичных методов нет.
События
Все события приходят на сам элемент и всплывают. Общие события базового элемента перечислены в главе Жизненный цикл → Этапы.
sf-sortable-intent—detail:{ item: string, from: string, to: string, index: integer, mode: any }. Пользователь отпустил перетаскиваемый элемент; хост применяет или отклоняет изменение.sf-sortable-state—detail:{ state?: any, item?: string }. Сеанс перетаскивания начался (элемент взят) или закончился (отпущен, отменён).
Доступность
- Доступное имя: рекомендуется.
- Клавиши:
Space,Enter,ArrowUp,ArrowDown,ArrowLeft,ArrowRight,Escape,Tab. - Фокус: Элементы становятся фокусируемыми и описывают инструкции. Space или Enter берёт элемент, стрелки перемещают его внутри списка и в другие принимающие списки или внешние цели, Space или Enter отпускает, Escape или Tab отменяет. Каждый шаг объявляется в вежливой живой области на языке страницы.
Минимальная разметка
<sf-sortable id="sections" group="sections" label="Sections"><div data-sf-sortable-item="s1">Section 1</div><div data-sf-sortable-item="s2">Section 2</div></sf-sortable>
Источник
simai/ui@106d5901f8c3b4f23131ce0e7ede5dbd8abfe4f4:distr/smart/sortablesimai/ui@106d5901f8c3b4f23131ce0e7ede5dbd8abfe4f4:distr/rule/rule.json#name=cl-sortable
См. также
- Оверлей редактора — холст, на который попадают элементы библиотеки.
- Перенос блоков и секций — как редактор страниц применяет перенос.