# LivaForm
Package: @dataliva/livalib
Description: @dataliva/livalib form bileşeni ve form item bileşenleri.

DevExtreme'in Form bileşeni üzerine kurulu form kabuğu. `LivaFormItem`
bileşenleri `editorType` değerine göre Liva editörlerine (`LivaTextBox`,
`LivaNumberBox`, `LivaSwitch`...) eşlenir. `form` prop'una bir `useForm`
örneği verildiğinde `formData`, `isSaving` ve `errors` durumları otomatik
olarak bağlanır; kaydetme sırasında alanlar iskelet (skeleton) görünümüne geçer.

```tsx
import {
  LivaForm,
  LivaFormItem,
  LivaFormGroupItem,
  LivaFormButtonItem,
  LivaFormSaveAndCancelButtons,
  LivaTabFormItem,
  useForm,
} from "@dataliva/livalib";
```

## Temel kullanım

Form durumu `useForm` ile kurulur ve `form` prop'u üzerinden bağlanır.
Aşağıdaki örnekte kaydetme, 800 ms'lik sahte bir gecikmeyle simüle edilir;
başarılı kayıtta bildirim yerine basit bir durum mesajı gösterilir. Buton
davranışları `saveButtonProps.onClick` ve `cancelButtonProps.onClick` ile verilir.

```tsx
const form = useForm<KayitFormu>({
  initialValues: { adSoyad: "", eposta: "", yas: 25, aktif: true },
  onSave: async () => {
    await new Promise((res) => setTimeout(res, 800)); // sahte API çağrısı
  },
});
```

**Örnek — Temel kayıt formu:**

```tsx
<div style={{ width: "100%", maxWidth: 420 }}>
  <LivaForm form={form}>
    <LivaFormItem dataField="adSoyad" editorType="dxTextBox" label={{ text: "Ad Soyad", location: "top" }} />
    <LivaFormItem dataField="eposta" editorType="dxTextBox" label={{ text: "E-posta", location: "top" }} />
    <LivaFormItem dataField="yas" editorType="dxNumberBox" label={{ text: "Yaş", location: "top" }} />
    <LivaFormItem dataField="aktif" editorType="dxSwitch" label={{ text: "Aktif", location: "top" }} />
    <LivaFormSaveAndCancelButtons
      saveButtonProps={{
        text: "Kaydet",
        loading: form.isSaving,
        onClick: async () => {
          const basarili = await form.onSave();
          if (basarili) setMesaj((form.formData.adSoyad || "Kayıt") + " kaydedildi.");
        },
      }}
      cancelButtonProps={{
        text: "Sıfırla",
        onClick: () => {
          form.resetForm();
          setMesaj("");
        },
      }}
    />
  </LivaForm>
  {mesaj && <p style={{ marginTop: 12, color: "#16a34a" }}>{mesaj}</p>}
</div>
```

## Gruplu form

`LivaFormGroupItem`, alanları `caption` başlıklı gruplar halinde toplar;
`colCount` ile sütun düzeni kurulur. `useForm` yerine düz bir nesne de
`formData` prop'u ile verilebilir — DevExtreme, düzenlenen alanları bu
nesnenin üzerine yazar.

**Örnek — LivaFormGroupItem ile gruplu form:**

```tsx
<div style={{ width: "100%" }}>
  <LivaForm formData={kisi} colCount={2}>
    <LivaFormGroupItem caption="Kişisel Bilgiler">
      <LivaFormItem dataField="ad" label={{ text: "Ad", location: "top" }} />
      <LivaFormItem dataField="soyad" label={{ text: "Soyad", location: "top" }} />
    </LivaFormGroupItem>
    <LivaFormGroupItem caption="İletişim">
      <LivaFormItem dataField="eposta" label={{ text: "E-posta", location: "top" }} />
      <LivaFormItem dataField="telefon" label={{ text: "Telefon", location: "top" }} />
    </LivaFormGroupItem>
  </LivaForm>
</div>
```

## Prop'lar

### LivaForm

| Prop | Tip | Varsayılan |
|------|------|---------|
| `form` | `UseFormReturn<any>` | — |
| `formData` | `any` | — |
| `loading` | `boolean` | `false` |
| `showColonAfterLabel` | `boolean` | `false` |
| `trackUnsavedChanges` | `boolean` | `true` |

Ayrıca DevExtreme `IFormOptions`'tan gelen tüm prop'lar (ör. `colCount`,
`labelLocation`, `onFieldDataChanged`). `form` verildiğinde `formData`,
`loading` ve hata durumları `useForm` örneğinden okunur.

### LivaFormItem

| Prop | Tip | Varsayılan |
|------|------|---------|
| `dataField` | `string` | — |
| `editorType` | `FormItemComponent \| 'dxFileBox' \| 'dxAvatarBox' \| 'dxPasswordBox' \| 'dxDropdownBox' \| 'dxPhoneBox'` | `'dxTextBox'` |
| `editorOptions` | `Record<string, any>` | — |
| `label` | `{ text?, location?, alignment?, showColon?, visible?, helpText?, template? }` | — |

Liva editörlerine eşlenen `editorType` değerleri: `dxTextBox`, `dxPasswordBox`,
`dxNumberBox`, `dxDateBox`, `dxTextArea`, `dxSelectBox`, `dxCheckBox`,
`dxSwitch`, `dxRadioGroup`, `dxTagBox`, `dxHtmlEditor`, `dxFileBox`,
`dxAvatarBox`, `dxDropdownBox`, `dxPhoneBox`.

### LivaFormGroupItem

| Prop | Tip | Varsayılan |
|------|------|---------|
| `caption` | `string` | — |
| `colCount` | `number` | — |
| `colSpan` | `number` | — |

Ayrıca DevExtreme `IGroupItemProps`'tan gelen tüm prop'lar.

### LivaFormButtonItem

Form içine buton yerleştirir; `LivaButton` ile aynı prop'ları alır
(ör. `text`, `type`, `variant`, `loading`, `onClick`, `width`).

### LivaFormSaveAndCancelButtons

| Prop | Tip | Varsayılan |
|------|------|---------|
| `saveButtonProps` | `LivaFormButtonItemProps` | `{ text: 'Save', type: 'default' }` |
| `cancelButtonProps` | `LivaFormButtonItemProps` | `{ text: 'Cancel', type: 'normal' }` |
| `onSave` | `() => void` | — |
| `onCancel` | `() => void` | — |

Tıklama davranışlarını `saveButtonProps.onClick` ve
`cancelButtonProps.onClick` ile verin.

### LivaTabFormItem

Sekmeli form bölümü oluşturur; DevExtreme `ITabbedItemProps`'tan gelen tüm
prop'ları alır (ör. `tabs`, `tabPanelOptions`).
