Skip to content

Commit

Permalink
Update sort.mdx
Browse files Browse the repository at this point in the history
  • Loading branch information
dragomano committed Apr 21, 2024
1 parent 7a5bdc5 commit 4e2a46e
Showing 1 changed file with 130 additions and 39 deletions.
169 changes: 130 additions & 39 deletions src/content/docs/plugins/sort.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -76,42 +76,42 @@ Alpine.start();

## Использование

Основным API для использования этого плагина является директива `x-sort`. Добавив `x-sort` к элементу, его дочерние элементы становятся сортируемыми - то есть вы можете перетаскивать их мышью, и они будут менять положение.
Основным API для использования этого плагина является директива `x-sort`. Добавив `x-sort` к элементу, его дочерние элементы, имеющие атрибут `x-sort:item`, становятся сортируемыми - то есть вы можете перетаскивать их мышью, и они будут менять положение.

```html live "x-sort"
<div x-data>
<ul x-sort>
<li>кошка</li>
<li>мышка</li>
<li>собака</li>
<li x-sort:item>кошка</li>
<li x-sort:item>мышка</li>
<li x-sort:item>собака</li>
</ul>
</div>
```

## Обработчики сортировки

Можно реагировать на изменения сортировки, передавая функцию-обработчик `x-sort` и добавляя ключи к каждому элементу с помощью `x-sort:key`. Вот пример простой функции-обработчика, которая показывает диалоговое окно с изменённым ключом элемента и его новой позицией:
Можно реагировать на изменения сортировки, передавая функцию-обработчик `x-sort` и добавляя ключи к каждому элементу с помощью `x-sort:item`. Вот пример простой функции-обработчика, которая показывает диалоговое окно с изменённым ключом элемента и его новой позицией:

```html live "x-sort:key"
```html live "x-sort:item"
<div x-data>
<ul x-sort="alert($key + ' - ' + $position)">
<li x-sort:key="1">кошка</li>
<li x-sort:key="2">мышка</li>
<li x-sort:key="3">собака</li>
<ul x-sort="alert($item + ' - ' + $position)">
<li x-sort:item="1">кошка</li>
<li x-sort:item="2">мышка</li>
<li x-sort:item="3">собака</li>
</ul>
</div>
```

Обработчик `x-sort` будет вызываться каждый раз, когда порядок сортировки элементов изменится. Магия `$key` будет содержать ключ отсортированного элемента (полученный из `x-sort:key`), а `$position` будет содержать новую позицию элемента (с индексом `0`).
Обработчик `x-sort` будет вызываться каждый раз, когда порядок сортировки элементов изменится. Магия `$item` будет содержать ключ отсортированного элемента (полученный из `x-sort:item`), а `$position` будет содержать новую позицию элемента (с индексом `0`).

Вы также можете передать функцию-обработчик в `x-sort`, и эта функция получит `key` и `position` в качестве первого и второго параметра:
Вы также можете передать функцию-обработчик в `x-sort`, и эта функция получит `item` и `position` в качестве первого и второго параметров:

```html {1}
<div x-data="{ handle: (key, position) => { ... } }">
<div x-data="{ handle: (item, position) => { ... } }">
<ul x-sort="handle">
<li x-sort:key="1">лиса</li>
<li x-sort:key="2">волк</li>
<li x-sort:key="3">медведь</li>
<li x-sort:item="1">лиса</li>
<li x-sort:item="2">волк</li>
<li x-sort:item="3">медведь</li>
</ul>
</div>
```
Expand All @@ -120,43 +120,43 @@ Alpine.start();

## Сортировка групп

Этот плагин позволяет перетаскивать элементы из одного сортируемого списка `x-sort` в другой, добавляя соответствующий модификатор `.group` в оба списка:
Этот плагин позволяет перетаскивать элементы из одного сортируемого списка `x-sort` в другой, добавляя соответствующее значение `x-sort:group` в оба списка:

```html live "x-sort.group"
<div x-data>
<ul x-sort.group.todos>
<li x-sort:key="1">кошка</li>
<li x-sort:key="2">мышка</li>
<li x-sort:key="3">собака</li>
<ul x-sort x-sort:group="todos">
<li x-sort:item="1">кошка</li>
<li x-sort:item="2">мышка</li>
<li x-sort:item="3">собака</li>
</ul>
<ol x-sort.group.todos>
<li x-sort:key="1">енот</li>
<li x-sort:key="2">ласка</li>
<li x-sort:key="3">хорёк</li>
<ol x-sort x-sort:group="todos">
<li x-sort:item="1">енот</li>
<li x-sort:item="2">ласка</li>
<li x-sort:item="3">хорёк</li>
</ol>
</div>
```

Поскольку оба приведённых выше сортируемых списка используют одно и то же имя группы (`todos`), можно перетаскивать элементы из одного списка в другой.

:::note
При использовании обработчиков сортировки типа `x-sort="handle"` и перетаскивании элемента из одной группы в другую будет вызван только обработчик списков назначения с ключом и новой позицией.
При использовании обработчиков сортировки типа `x-sort="handle"` и перетаскивании элемента из одной группы в другую будет вызван только обработчик списка назначения с ключом и новой позицией.
:::

## Держатели для перетаскивания

По умолчанию каждый дочерний элемент `x-sort` можно перетаскивать, щёлкая и перетаскивая в любом месте внутри него. Однако вы можете назначить более мелкий и конкретный элемент в качестве «держателя для перетаскивания», чтобы с остальными элементами можно было взаимодействовать как обычно, а на перетаскивание мыши реагировал только держатель:
По умолчанию каждый дочерний элемент `x-sort:item` можно перетаскивать, щёлкая и перетаскивая в любом месте внутри него. Однако вы можете назначить более мелкий и конкретный элемент в качестве «держателя для перетаскивания», чтобы с остальными элементами можно было взаимодействовать как обычно, а на перетаскивание мыши реагировал только держатель:

```html live "x-sort:handle"
<div x-data>
<ul x-sort class="list-none">
<li>
<li x-sort:item>
<span x-sort:handle> 🦊 </span>лиса
</li>
<li>
<li x-sort:item>
<span x-sort:handle> 🐺 </span>волк
</li>
<li>
<li x-sort:item>
<span x-sort:handle> 🐻 </span>медведь
</li>
</ul>
Expand All @@ -176,9 +176,9 @@ Alpine.start();
```html live "x-sort.ghost"
<div x-data>
<ul x-sort.ghost>
<li>бурундук</li>
<li>капибара</li>
<li>муравьед</li>
<li x-sort:item>бурундук</li>
<li x-sort:item>капибара</li>
<li x-sort:item>муравьед</li>
</ul>
</div>
```
Expand All @@ -199,9 +199,86 @@ Alpine.start();

<div x-data>
<ul x-sort.ghost>
<li>гиена</li>
<li>шакал</li>
<li>койот</li>
<li x-sort:item>гиена</li>
<li x-sort:item>шакал</li>
<li x-sort:item>койот</li>
</ul>
</div>
```

## Класс `sorting` на элементе `body`

Пока элемент перетаскивается, Alpine автоматически добавит класс `.sorting` к элементу `<body>` страницы.

Это полезно для стилизации любого элемента на странице условно, используя только CSS.

Например, вы можете иметь предупреждение, которое отображается только во время сортировки элементов пользователем:

```html
<div id="sort-warning">
Функциональность страницы при сортировке ограничена
</div>
```

Чтобы показать это только при сортировке, используйте CSS-селектор `body.sorting`:

```css "body.sorting"
#sort-warning {
display: none;
}

body.sorting #sort-warning {
display: block;
}
```

## Баг с CSS-свойством `hover`

В настоящее время существует [баг в Chrome и Safari](https://issues.chromium.org/issues/41129937) (не в Firefox), который вызывает проблемы с наведением стилей.

Рассмотрим HTML, где каждый элемент списка оформляется по-разному в зависимости от состояния наведения (здесь мы используем класс `.hover` от Tailwind для условного добавления рамки):

```html
<div x-sort>
<div x-sort:item class="hover:border">страус</div>
<div x-sort:item class="hover:border">курица</div>
<div x-sort:item class="hover:border">павлин</div>
</div>
```

Если вы перетащите один из элементов в списке ниже, то увидите, что эффект наведения будет ошибочно применен к любому элементу на месте исходного:

```html live
<div x-data>
<ul x-sort class="flex flex-col items-start">
<li x-sort:item class="hover:border border-black">страус</li>
<li x-sort:item class="hover:border border-black">курица</li>
<li x-sort:item class="hover:border border-black">павлин</li>
</ul>
</div>
```

Чтобы исправить это, используйте класс `.sorting`, применяемый к `body` при сортировке, чтобы ограничить эффект `hover`, который будет применяться только тогда, когда у `body` не будет класса `.sorting`.

Вот как вы можете сделать это прямо в строке, используя произвольные варианты Tailwind:


```html
<div x-sort>
<div x-sort:item class="[body:not(.sorting)_&]:hover:border">страус</div>
<div x-sort:item class="[body:not(.sorting)_&]:hover:border">курица</div>
<div x-sort:item class="[body:not(.sorting)_&]:hover:border">павлин</div>
</div>
```

Теперь вы можете видеть, что эффект наведения применяется только к перетаскиваемому элементу, а не к остальным в списке.

```html live
<div x-data>
<ul x-sort class="flex flex-col items-start">
<li x-sort:item class="[body:not(.sorting)_&]:hover:border border-black">индюк</li>
<li x-sort:item class="[body:not(.sorting)_&]:hover:border border-black">гусь</li>
<li x-sort:item class="[body:not(.sorting)_&]:hover:border border-black">утка</li>
</ul>
</div>
```
Expand All @@ -213,13 +290,27 @@ Alpine выбирает разумные настройки по умолчан
```html live "x-sort:config"
<div x-data>
<ul x-sort x-sort:config="{ filter: '.no-drag', ghostClass: 'text-yellow-500' }">
<li>суррикат</li>
<li class="no-drag">норка (не перетаскивается)</li>
<li>белка</li>
<li x-sort:item>суррикат</li>
<li x-sort:item class="no-drag">норка (не перетаскивается)</li>
<li x-sort:item>белка</li>
</ul>
</div>
```

```html live "animation: 0"
<div x-data>
<ul x-sort x-sort:config="{ animation: 0 }">
<li x-sort:item>суррикат</li>
<li x-sort:item>норка</li>
<li x-sort:item>белка</li>
</ul>
</div>
```

:::note
Любые переданные параметры конфигурации будут перезаписывать дефолтные значения Alpine. В случае с `animation` это нормально, однако помните, что перезапись `handle`, `group`, `filter`, `onSort`, `onStart` или `onEnd` может нарушить функциональность.
:::

import { LinkCard } from '@astrojs/starlight/components';

<LinkCard title="Полный список опций <strong>SortableJS</strong>" href="https://github.com/SortableJS/Sortable?tab=readme-ov-file#options" />

0 comments on commit 4e2a46e

Please sign in to comment.