# Mesdan (مسدان)

[![NPM Version](https://img.shields.io/npm/v/mesdan.svg)](https://www.npmjs.com/package/mesdan)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![React](https://img.shields.io/badge/react-%3E%3D18-blue.svg)](https://reactjs.org/)

_Mesdan_ kelimesi tuş (touch) takımı yani **keyboard** demektir.

İşbu menba Latin hurufatlı mesdanları kullanarak Osmanlı Türkçesi yazabilmek için hazırlanmıştır.
Kancaya tanıtılan `<textarea>` ya `<input>` unsurlarının idâresini ele alıp yazma, silme, belleme (copy), koparma (cut), yerleme (paste) ilh.
amelleri Osmanlı Türkçesiyle çalışacak şekilde îfâ eder.

---

<details>
<summary><strong>Click here for the English version</strong></summary>

# Mesdan (مسدان)

The word _Mesdan_ is an old Turkish word for **keyboard**.

This React hook is designed to facilitate writing Ottoman Turkish text using a standard Latin keyboard. It takes control of a given `<textarea>` or `<input>` element to ensure that actions like typing, deleting, copying, cutting, and pasting work correctly for the Ottoman script.

</details>

---

## Kurma (Installation)

```bash
npm install mesdan
# ya / or
yarn add mesdan
```

## Temel Kullanım (Basic Usage)

`useMesdan` kancasını unsura (component) dahil edin ve dönen `metin` ile `metinSahasıİması` değerlerini alâkalı unsura tanıtın.

- `metin`: Unsurun `value` hassasına verilecek olan metindir.
- `metinSahasıİması`: Unsurun `ref` hassasına verilecek olan delîldir.

```tsx
import React from 'react';
import { useMesdan } from 'mesdan';

const TemelMesdan = () => {
  const { metin, metinSahasıİması } = useMesdan<HTMLInputElement>({
    ibtidaiMetin: '',
    tekSatırMı: true, // `true` ise <input>, `false` ise <textarea>
  });

  return (
    <input
      ref={metinSahasıİması}
      dir="rtl"
      value={metin}
      onChange={() => {}} // Kanca metni kendi idare ettiği için boş bırakılabilir
    />
  );
};

export default TemelMesdan;
```

> **Şerh:** `onChange` vaqası (event) kanca tarafından dâhilen idare edildiği için boş bırakılabilir. React, `value` hassası olan unsurlarda bir `onChange` ameli beklediği için ekledik ama lâzım değil.

## Kancanın Hassaları (Hook Props)

`useMesdan` kancası bir nesne (object) alır. İşte bu nesnenin alabileceği hassalar:

| Hususiyet (Prop)     | Nev (Type)                    | Mecburi mi? (Required?) | İzah (Description)                                                                                                                               |
| -------------------- | ----------------------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `ibtidaiMetin`       | `string`                      | Yo (No)                 | Metin sahasının ilk değeridir. Varsayılan (default) `''`.                                                                                        |
| `tekSatırMı`         | `boolean`                     | He (Yes)                | `true` ise tek satırlı (`<input>`) gibi çalışır ve `Enter` tuşuna basılınca `aramaTalepEdilince` amelini tetikler. `false` ise yeni satır ekler. |
| `latiniMi`           | `boolean`                     | Yo (No)                 | `true` ise kanca âtıl hale gelir ve Alfabe ile yazmağa başlar. Varsayılan `false`.                                                               |
| `aramaTalepEdilince` | `() => void`                  | Yo (No)                 | `tekSatırMı` `true` iken `Enter` tuşuna basıldığında koşulan ameldir.                                                                            |
| `metin`              | `string`                      | Yo (No)                 | Kancanın idâresini harice verir. `tayinMetin` ile beraber kullanılır.                                                                            |
| `tayinMetin`         | `(yeniMetin: string) => void` | Yo (No)                 | Kancanın idâresini harice verir. `metin` ile beraber kullanılır.                                                                                 |

## Kancanın Vâsılatı (Return Values)

Kanca, dört unsurdan müteşekkil bir dizi (array) vâsıl eder:

```ts
type MesdanCevabı<T> = {
  metinSahasıİması: RefObject<T | null>;
  metin: string;
  tebdilMetin: (yeniMetin: string) => void;
  latiniMi: boolean;
  tebdilLatiniMi: (latiniMi: boolean) => void;
};
```

1.  **`metinSahasıİması`** (`RefObject`):
    `input` veya `textarea` unsuruna banılacak olan `ref`. (ba-mak => bağlamak, rapt etmek)

2.  **`metin`** (`string`):
    Metin sahasının cârî değeri.

3.  **`tebdilMetin`** (`(yeniMetin: string) => void`):
    Metni haricen (programmatically) değiştirir.

4.  **`latiniMi`** (`boolean`):
    Kancanın o anki yazım haletini gösterir (false Elifba, true Alfabe).

5.  **`tebdilLatiniMi`** (`(latiniMi: boolean) => void`):
    Haleti Elifba ile Alfabe değiştirmek için kullanılır.

## İleri Seviye Kullanım Misâlleri (Advanced Usage Examples)

### 1. Çok Satırlı Metin Sahası (`<textarea>`)

`tekSatırMı` hassasını `false` yaparak adid satırlı metin girişi sağlayabilirsiniz. Bu halde `Enter` mesine basmak yeni bir satır ekler.

```tsx
import { useMesdan } from 'mesdan';

const AdidSatırlıMesdan = () => {
  const { metin, metinSahasıİması } = useMesdan<HTMLTextAreaElement>({
    ibtidaiMetin: '',
    tekSatırMı: false,
  });

  return <textarea ref={metinSahasıİması} dir="rtl" value={metin} onChange={() => {}} rows={5} />;
};
```

### 2. Hâriçten İdâreli Unsur (Controlled Component)

Metin vaziyetini (state) kancanın hâricinden idâre etmek isterseniz, `metin` ve `tayinMetin` hassalarını kullanabilirsiniz.

```tsx
import { useState } from 'react';
import { useMesdan } from 'mesdan';

const HariçtenİdareliMesdan = () => {
  const [hariciMetin, tayinHariciMetin] = useState('');

  const { metinSahasıİması } = useMesdan<HTMLInputElement>({
    tekSatırMı: true,

    metin: hariciMetin,
    tayinMetin: tayinHariciMetin,
  });

  return (
    <div>
      <input ref={metinSahasıİması} dir="rtl" value={hariciMetin} onChange={() => {}} />
      <button onClick={() => tayinHariciMetin('')}>Metni İmhâ Et</button>
      <p>Hârici Metin: {hariciMetin}</p>
    </div>
  );
};
```

### 3. Yazım Haletini Zirleme (Toggling Input Mode)

Kullanıcının Elifba ve Alfabe yazım arasında geçiş yapmasını sağlamak için `tebdilLatiniMi` amelini kullanabilirsiniz.

```tsx
import { useState } from 'react';
import { useMesdan } from 'mesdan';

const LisanZirliMesdan = () => {
  const { metin, metinSahasıİması, latiniMi, tebdilLatiniMi } = useMesdan<HTMLInputElement>({
    ibtidaiMetin: '',
    tekSatırMı: true,
    latiniMi: latiniMi,
  });

  const ifaZir = () => {
    tebdilLatiniMi(!latiniMi);
  };

  return (
    <div>
      <input
        ref={metinSahasıİması}
        value={metin}
        onChange={() => {}}
        dir={latiniMi ? 'ltr' : 'rtl'}
        placeholder={latiniMi ? 'Alfabe ile yaz...' : 'الفبا ايله‌ ياز...'}
      />
      <button onClick={ifaZir}>{latiniMi ? "Elifba'ya geç" : "Alfabe'ye geç"}</button>
    </div>
  );
};
```

### 4. Metni Haricen Değiştirme (Programmatically Setting Text)

`tebdilMetin` fonksiyonu ile metni bir vaqaya (event) bağlı olarak değiştirebilirsiniz.

```tsx
import { useMesdan } from 'mesdan';

const HariçtenMetinTebdilliMesdan = () => {
  const { metin, metinSahasıİması, tebdilMetin } = useMesdan<HTMLTextAreaElement>({
    tekSatırMı: false,
  });

  return (
    <div>
      <textarea ref={metinSahasıİması} dir="rtl" value={metin} onChange={() => {}} rows={5} />
      <button onClick={() => tebdilMetin('السلام عليكم')}>Selam Ver</button>
    </div>
  );
};
```

## Lexical İlâvesi: OsmaniMesdanEki

`mesdan` menbaı, [Lexical](https://lexical.dev/) zengin metingeri (rich text editor) ile Osmanî Türkçe yazmayı kolaylaştıran bir ilâve (plugin) de sunmaktadır. `OsmaniMesdanEki`, metingerin içine yerleştirildiğinde Latin hurufatlı mesdanlardan Osmanî Türkçe yazma imkânı sağlar.

Bu ilâveyi kullanmak için azîmenizde Lexical'in kurulu olması gerekir.

### Lexical ile Kullanım

`OsmaniMesdanEki` ilâvesi bir unsur (component) olup, `LexicalComposer` unsurunun içine yerleştirilmelidir. Herhangi bir görünür unsur oluşturmaz; bunun yerine metingerin hâline erişerek mesdan vaqalarını takip ve idâre eder.

Aşağıda Lexical metingerinin temel bir misâli verilmiştir:

```tsx
import { LexicalComposer } from '@lexical/react/LexicalComposer';
import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin';
import { ContentEditable } from '@lexical/react/LexicalContentEditable';
import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin';
import LexicalErrorBoundary from '@lexical/react/LexicalErrorBoundary';

import { OsmaniMesdanEki } from 'mesdan';

const tarz = {};

const iptidaiAyarlar = {
  namespace: 'OsmaniEditor',
  theme: tarz,
  onError: (hata: Error) => console.error(hata),
};

const LexicalMetigeri = () => {
  return (
    <LexicalComposer initialConfig={ibdaiAyarlar}>
      <div className="editor-container" style={{ position: 'relative' }}>
        <RichTextPlugin
          contentEditable={
            <ContentEditable
              dir="rtl"
              style={{
                border: '1px solid #ccc',
                minHeight: '150px',
                padding: '10px',
                direction: 'rtl',
                textAlign: 'right',
              }}
            />
          }
          placeholder={
            <div
              style={{
                position: 'absolute',
                top: '10px',
                right: '10px',
                color: '#aaa',
                pointerEvents: 'none',
              }}
            >
              الفبا ايله‌ ياز...
            </div>
          }
          ErrorBoundary={LexicalErrorBoundary}
        />

        <HistoryPlugin />
        <OsmaniMesdanEki />
      </div>
    </LexicalComposer>
  );
};

export default LexicalMetigeri;
```

#### Îzah (Explanation)

1.  **`LexicalComposer`**: Bütün Lexical metingeri bu unsur ile sarmalanmalıdır.
2.  **`ContentEditable`**: Kullanıcının metin girdiği asıl sahadır. Osmanî metin için `dir="rtl"` ve alâkalı CSS hassalarını (`direction`, `textAlign`) eklemek, doğru bir yazım tecrübesi için elzemdir.
3.  **`OsmaniMesdanEki`**: Bu ilâveyi `LexicalComposer`'ın herhangi bir yerine yerleştirmeniz kâfidir.

## Anahtar Kelimeler (Keywords)

osmanlıca, türkçe, türki, osmani, turkish, elifba, keyboard, tercüme, ottoman, latini, react, hook

## Ruhsat (License)

Bu menba MIT Ruhsatlıdır.
