# LivaDNDBetweenGrids
Package: @dataliva/livalib
Description: @dataliva/livalib iki grid arasında sürükle-bırak bileşeni.

Yan yana iki DevExtreme DataGrid arasında satır taşımayı hazır olarak sunan
bileşen. Satır listeleri bileşenin içinde yönetilir: `dataSource` başlangıç
verisini belirler, sürükleme sonrası ekleme/çıkarma otomatik yapılır ve
taşınan kayıt `onLeftToRight` / `onRightToLeft` geri çağrılarıyla bildirilir.

```tsx
import {
  LivaDNDBetweenGrids,
  type DNDGridConfig,
  type DNDBetweenGridItem,
} from "@dataliva/livalib";
```

## İki grid arası sürükleme

Sol griddeki bir satırı tutup sağ gride bırakın (veya tersi). Her iki grid
de `DNDGridConfig` nesnesiyle tanımlanır; `columns` verilmezse `name` ve
`description` alanlarından oluşan varsayılan kolonlar kullanılır.

**Örnek — İki grid arası sürükleme:**

```tsx
const kolonlar = [
  { dataField: "name", caption: "Ad Soyad" },
  { dataField: "position", caption: "Pozisyon" },
];

<LivaDNDBetweenGrids
  group="aday-secim"
  leftGrid={{ id: "adaylar", title: "Adaylar", dataSource: adaylar, columns: kolonlar, height: 300 }}
  rightGrid={{ id: "secilenler", title: "Seçilenler", dataSource: secilenler, columns: kolonlar, height: 300 }}
/>
```

## Taşıma geri çağrıları

`onLeftToRight` ve `onRightToLeft`, taşınan kayıtları dizi olarak iletir;
seçim sonucunu kaydetmek veya sunucuya bildirmek için kullanılır. `gap`
prop'u iki grid arasındaki boşluğu ayarlar. Aynı sayfada birden fazla
örnek varsa `group` değerlerini farklılaştırarak sürüklemenin yalnızca
ilgili grid çifti içinde kalmasını sağlayın.

**Örnek — Taşıma geri çağrıları:**

```tsx
const [sonHareket, setSonHareket] = useState("Henüz taşıma yapılmadı");

<LivaDNDBetweenGrids
  group="aday-secim-2"
  gap={32}
  leftGrid={{ id: "adaylar", title: "Adaylar", dataSource: adaylar, columns: kolonlar, height: 280 }}
  rightGrid={{ id: "secilenler", title: "Seçilenler", dataSource: secilenler, columns: kolonlar, height: 280 }}
  onLeftToRight={(tasinanlar) => setSonHareket(String(tasinanlar[0].name) + " → Seçilenler")}
  onRightToLeft={(tasinanlar) => setSonHareket(String(tasinanlar[0].name) + " → Adaylar")}
/>
<p>Son hareket: {sonHareket}</p>
```

## DNDGridConfig

Her iki grid için kullanılan yapılandırma nesnesi:

| Alan | Tip | Varsayılan |
|------|------|---------|
| `id` | `string` | — |
| `title` | `string` | — |
| `dataSource` | `DNDBetweenGridItem[]` | — |
| `keyExpr` | `string` | `'id'` |
| `columns` | `IColumnProps[]` | `name` + `description` |
| `height` | `number \| string` | `400` |
| `showBorders` | `boolean` | `true` |
| `showRowLines` | `boolean` | `true` |
| `rowAlternationEnabled` | `boolean` | `true` |
| `hoverStateEnabled` | `boolean` | `true` |

## Prop'lar

| Prop | Tip | Varsayılan |
|------|------|---------|
| `leftGrid` | `DNDGridConfig` | — |
| `rightGrid` | `DNDGridConfig` | — |
| `group` | `string \| symbol` | `'dnd-between-grids'` |
| `onLeftToRight` | `(items: DNDBetweenGridItem[]) => void` | — |
| `onRightToLeft` | `(items: DNDBetweenGridItem[]) => void` | — |
| `containerHeight` | `number \| string` | `'auto'` |
| `gap` | `number \| string` | `20` |
| `className` | `string` | — |

`DNDBetweenGridItem`, `id` alanı zorunlu olmak üzere serbest alanlı bir
kayıt tipidir (`Record<string, any>`).
