mesdan 1.0.3 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +201 -25
- package/package.json +1 -1
- package/teshir/kanca/use-mesdan.d.ts +3 -1
- package/teshir/kanca/use-mesdan.d.ts.map +1 -1
- package/teshir/kanca/use-mesdan.js +23 -13
- package/talimat-2.md +0 -297
package/README.md
CHANGED
|
@@ -1,42 +1,218 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Mesdan (مسدان)
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/mesdan)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://reactjs.org/)
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
_Mesdan_ kelimesi tuş (touch) takımı yani **keyboard** demektir.
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
İşbu menba Latin hurufatlı mesdanları kullanarak Osmanlı Türkçesi yazabilmek için hazırlanmıştır.
|
|
10
|
+
Kancaya tanıtılan `<textarea>` ya `<input>` unsurlarının idâresini ele alıp yazma, silme, belleme (copy), koparma (cut), yerleme (paste) ilh.
|
|
11
|
+
amelleri Osmanlı Türkçesiyle çalışacak şekilde îfâ eder.
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
---
|
|
12
14
|
|
|
15
|
+
<details>
|
|
16
|
+
<summary><strong>Click here for the English version</strong></summary>
|
|
17
|
+
|
|
18
|
+
# Mesdan (مسدان)
|
|
19
|
+
|
|
20
|
+
The word _Mesdan_ is an old Turkish word for **keyboard**.
|
|
21
|
+
|
|
22
|
+
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.
|
|
23
|
+
|
|
24
|
+
</details>
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Kurma (Installation)
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install mesdan
|
|
32
|
+
# ya / or
|
|
33
|
+
yarn add mesdan
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Temel Kullanım (Basic Usage)
|
|
37
|
+
|
|
38
|
+
`useMesdan` kancasını unsura (component) dahil edin ve dönen `metin` ile `metinSahasıİması` değerlerini alâkalı unsura tanıtın.
|
|
39
|
+
|
|
40
|
+
- `metin`: Unsurun `value` hassasına verilecek olan metindir.
|
|
41
|
+
- `metinSahasıİması`: Unsurun `ref` hassasına verilecek olan delîldir.
|
|
42
|
+
|
|
43
|
+
```tsx
|
|
44
|
+
import React from 'react';
|
|
45
|
+
import { useMesdan } from 'mesdan';
|
|
46
|
+
|
|
47
|
+
const TemelMesdan = () => {
|
|
48
|
+
const [metin, metinSahasıİması] = useMesdan<HTMLInputElement>({
|
|
49
|
+
ibtidaiMetin: '',
|
|
50
|
+
tekSatırMı: true, // `true` ise <input>, `false` ise <textarea>
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<input
|
|
55
|
+
ref={metinSahasıİması}
|
|
56
|
+
dir="rtl"
|
|
57
|
+
value={metin}
|
|
58
|
+
onChange={() => {}} // Kanca metni kendi idare ettiği için boş bırakılabilir
|
|
59
|
+
/>
|
|
60
|
+
);
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export default TemelMesdan;
|
|
13
64
|
```
|
|
14
|
-
|
|
65
|
+
|
|
66
|
+
> **Ş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.
|
|
67
|
+
|
|
68
|
+
## Kancanın Hassaları (Hook Props)
|
|
69
|
+
|
|
70
|
+
`useMesdan` kancası bir nesne (object) alır. İşte bu nesnenin alabileceği hassalar:
|
|
71
|
+
|
|
72
|
+
| Hususiyet (Prop) | Nev (Type) | Mecburi mi? (Required?) | İzah (Description) |
|
|
73
|
+
| -------------------- | ----------------------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
74
|
+
| `ibtidaiMetin` | `string` | Yo (No) | Metin sahasının ilk değeridir. Varsayılan (default) `''`. |
|
|
75
|
+
| `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. |
|
|
76
|
+
| `latiniMi` | `boolean` | Yo (No) | `true` ise kanca âtıl hale gelir ve Alfabe ile yazmağa başlar. Varsayılan `false`. |
|
|
77
|
+
| `aramaTalepEdilince` | `() => void` | Yo (No) | `tekSatırMı` `true` iken `Enter` tuşuna basıldığında koşulan ameldir. |
|
|
78
|
+
| `metin` | `string` | Yo (No) | Kancanın idâresini harice verir. `tayinMetin` ile beraber kullanılır. |
|
|
79
|
+
| `tayinMetin` | `(yeniMetin: string) => void` | Yo (No) | Kancanın idâresini harice verir. `metin` ile beraber kullanılır. |
|
|
80
|
+
|
|
81
|
+
## Kancanın Vâsılatı (Return Values)
|
|
82
|
+
|
|
83
|
+
Kanca, dört unsurdan müteşekkil bir dizi (array) döndürür:
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
type MesdanVasılatı<T> = [
|
|
87
|
+
metin: string,
|
|
88
|
+
metinSahasıİması: RefObject<T | null>,
|
|
89
|
+
tebdilMetin: (yeniMetin: string) => void,
|
|
90
|
+
tebdilLatiniMi: (latiniMi: boolean) => void,
|
|
91
|
+
];
|
|
15
92
|
```
|
|
16
93
|
|
|
17
|
-
|
|
94
|
+
1. **`metin`** (`string`):
|
|
95
|
+
Metin sahasının cârî değeri.
|
|
96
|
+
|
|
97
|
+
2. **`metinSahasıİması`** (`RefObject`):
|
|
98
|
+
`input` veya `textarea` unsuruna banılacak olan `ref`. (ba-mak => bağlamak, rapt etmek)
|
|
99
|
+
|
|
100
|
+
3. **`tebdilMetin`** (`(yeniMetin: string) => void`):
|
|
101
|
+
Metni haricen (programmatically) değiştirir.
|
|
102
|
+
|
|
103
|
+
4. **`tebdilLatiniMi`** (`(latiniMi: boolean) => void`):
|
|
104
|
+
Haleti Elifba ile Alfabe değiştirmek için kullanılır.
|
|
105
|
+
|
|
106
|
+
## İleri Seviye Kullanım Misâlleri (Advanced Usage Examples)
|
|
107
|
+
|
|
108
|
+
### 1. Çok Satırlı Metin Sahası (`<textarea>`)
|
|
18
109
|
|
|
110
|
+
`tekSatırMı` hassasını `false` yaparak adid satırlı metin girişi sağlayabilirsiniz. Bu halde `Enter` mesine basmak yeni bir satır ekler.
|
|
111
|
+
|
|
112
|
+
```tsx
|
|
113
|
+
import { useMesdan } from 'mesdan';
|
|
114
|
+
|
|
115
|
+
const AdidSatırlıMesdan = () => {
|
|
116
|
+
const [metin, metinSahasıİması] = useMesdan<HTMLTextAreaElement>({
|
|
117
|
+
ibtidaiMetin: '',
|
|
118
|
+
tekSatırMı: false,
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
return <textarea ref={metinSahasıİması} dir="rtl" value={metin} onChange={() => {}} rows={5} />;
|
|
122
|
+
};
|
|
19
123
|
```
|
|
20
|
-
|
|
21
|
-
|
|
124
|
+
|
|
125
|
+
### 2. Hâriçten İdâreli Unsur (Controlled Component)
|
|
126
|
+
|
|
127
|
+
Metin vaziyetini (state) kancanın hâricinden idâre etmek isterseniz, `metin` ve `tayinMetin` hassalarını kullanabilirsiniz.
|
|
128
|
+
|
|
129
|
+
```tsx
|
|
130
|
+
import { useState } from 'react';
|
|
131
|
+
import { useMesdan } from 'mesdan';
|
|
132
|
+
|
|
133
|
+
const HariçtenİdareliMesdan = () => {
|
|
134
|
+
const [hariciMetin, tayinHariciMetin] = useState('');
|
|
135
|
+
|
|
136
|
+
const [, metinSahasıİması] = useMesdan<HTMLInputElement>({
|
|
22
137
|
tekSatırMı: true,
|
|
138
|
+
|
|
139
|
+
metin: hariciMetin,
|
|
140
|
+
tayinMetin: tayinHariciMetin,
|
|
23
141
|
});
|
|
142
|
+
|
|
143
|
+
return (
|
|
144
|
+
<div>
|
|
145
|
+
<input ref={metinSahasıİması} dir="rtl" value={hariciMetin} onChange={() => {}} />
|
|
146
|
+
<button onClick={() => tayinHariciMetin('')}>Metni İmhâ Et</button>
|
|
147
|
+
<p>Hârici Metin: {hariciMetin}</p>
|
|
148
|
+
</div>
|
|
149
|
+
);
|
|
150
|
+
};
|
|
24
151
|
```
|
|
25
152
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
153
|
+
### 3. Yazım Haletini Zirleme (Toggling Input Mode)
|
|
154
|
+
|
|
155
|
+
Kullanıcının Elifba ve Alfabe yazım arasında geçiş yapmasını sağlamak için `tebdilLatiniMi` amelini kullanabilirsiniz.
|
|
156
|
+
|
|
157
|
+
```tsx
|
|
158
|
+
import { useState } from 'react';
|
|
159
|
+
import { useMesdan } from 'mesdan';
|
|
160
|
+
|
|
161
|
+
const LisanZirliMesdan = () => {
|
|
162
|
+
const [latiniMi, tayinLatiniMi] = useState(false);
|
|
32
163
|
|
|
164
|
+
const [metin, metinSahasıİması, , tebdilLatiniMi] = useMesdan<HTMLInputElement>({
|
|
165
|
+
ibtidaiMetin: '',
|
|
166
|
+
tekSatırMı: true,
|
|
167
|
+
latiniMi: latiniMi,
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
const ifaZir = () => {
|
|
171
|
+
const yeniHalet = !latiniMi;
|
|
172
|
+
tayinLatiniMi(yeniHalet);
|
|
173
|
+
tebdilLatiniMi(yeniHalet);
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
return (
|
|
177
|
+
<div>
|
|
178
|
+
<input
|
|
179
|
+
ref={metinSahasıİması}
|
|
180
|
+
value={metin}
|
|
181
|
+
onChange={() => {}}
|
|
182
|
+
dir={latiniMi ? 'ltr' : 'rtl'}
|
|
183
|
+
placeholder={latiniMi ? 'Alfabe ile yaz...' : 'الفبا ايله ياز...'}
|
|
184
|
+
/>
|
|
185
|
+
<button onClick={ifaZir}>{latiniMi ? "Elifba'ya geç" : "Alfabe'ye geç"}</button>
|
|
186
|
+
</div>
|
|
187
|
+
);
|
|
188
|
+
};
|
|
33
189
|
```
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
190
|
+
|
|
191
|
+
### 4. Metni Haricen Değiştirme (Programmatically Setting Text)
|
|
192
|
+
|
|
193
|
+
`tebdilMetin` fonksiyonu ile metni bir vaqaya (event) bağlı olarak değiştirebilirsiniz.
|
|
194
|
+
|
|
195
|
+
```tsx
|
|
196
|
+
import { useMesdan } from 'mesdan';
|
|
197
|
+
|
|
198
|
+
const HariçtenMetinTebdilliMesdan = () => {
|
|
199
|
+
const [metin, metinSahasıİması, tebdilMetin] = useMesdan<HTMLTextAreaElement>({
|
|
200
|
+
tekSatırMı: false,
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
return (
|
|
204
|
+
<div>
|
|
205
|
+
<textarea ref={metinSahasıİması} dir="rtl" value={metin} onChange={() => {}} rows={5} />
|
|
206
|
+
<button onClick={() => tebdilMetin('السلام عليكم')}>Selam Ver</button>
|
|
207
|
+
</div>
|
|
208
|
+
);
|
|
209
|
+
};
|
|
42
210
|
```
|
|
211
|
+
|
|
212
|
+
## Anahtar Kelimeler (Keywords)
|
|
213
|
+
|
|
214
|
+
osmanlıca, türkçe, türki, osmani, turkish, elifba, keyboard, tercüme, ottoman, latini, react, hook
|
|
215
|
+
|
|
216
|
+
## Ruhsat (License)
|
|
217
|
+
|
|
218
|
+
Bu menba MIT Ruhsatlıdır.
|
package/package.json
CHANGED
|
@@ -4,6 +4,8 @@ type MesdanHususları = {
|
|
|
4
4
|
tekSatırMı: boolean;
|
|
5
5
|
latiniMi?: boolean;
|
|
6
6
|
aramaTalepEdilince?: () => void;
|
|
7
|
+
metin?: string;
|
|
8
|
+
tayinMetin?: (yeniMetin: string) => void;
|
|
7
9
|
};
|
|
8
10
|
type MesdanCevabı<T> = [
|
|
9
11
|
metin: string,
|
|
@@ -11,6 +13,6 @@ type MesdanCevabı<T> = [
|
|
|
11
13
|
tebdilMetin: (yeniMetin: string) => void,
|
|
12
14
|
tebdilLatiniMi: (latiniMi: boolean) => void
|
|
13
15
|
];
|
|
14
|
-
export declare const useMesdan: <T extends HTMLInputElement | HTMLTextAreaElement>({ ibtidaiMetin, tekSatırMı, latiniMi: ibtidaiLatiniMi, aramaTalepEdilince, }: MesdanHususları) => MesdanCevabı<T>;
|
|
16
|
+
export declare const useMesdan: <T extends HTMLInputElement | HTMLTextAreaElement>({ ibtidaiMetin, tekSatırMı, latiniMi: ibtidaiLatiniMi, aramaTalepEdilince, metin: metinHarici, tayinMetin: tayinMetinHarici, }: MesdanHususları) => MesdanCevabı<T>;
|
|
15
17
|
export {};
|
|
16
18
|
//# sourceMappingURL=use-mesdan.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-mesdan.d.ts","sourceRoot":"","sources":["../../memba/kanca/use-mesdan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAA6D,MAAM,OAAO,CAAC;AAU7F,KAAK,eAAe,GAAG;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"use-mesdan.d.ts","sourceRoot":"","sources":["../../memba/kanca/use-mesdan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAA6D,MAAM,OAAO,CAAC;AAU7F,KAAK,eAAe,GAAG;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAEhC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1C,CAAC;AAEF,KAAK,YAAY,CAAC,CAAC,IAAI;IACrB,KAAK,EAAE,MAAM;IACb,gBAAgB,EAAE,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC;IACrC,WAAW,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI;IACxC,cAAc,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI;CAC5C,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,CAAC,SAAS,gBAAgB,GAAG,mBAAmB,kIAOvE,eAAe,KAAG,YAAY,CAAC,CAAC,CA4MlC,CAAC"}
|
|
@@ -3,9 +3,19 @@ import { harfBüyükMü } from '../aletler/harf-buyuk-mu';
|
|
|
3
3
|
import { hazırlaAlemMevkisini, hazırlaAlemMevkisiniMenzilli } from '../nev/alem-mevkisi';
|
|
4
4
|
import { TadiliMetinEmri } from '../nev/tadili-metin-emri';
|
|
5
5
|
import { Talimat_MetniTadilEt } from '../nuve/tadil-et-metni';
|
|
6
|
-
export const useMesdan = ({ ibtidaiMetin = '', tekSatırMı, latiniMi: ibtidaiLatiniMi = false, aramaTalepEdilince, }) => {
|
|
7
|
-
const [
|
|
8
|
-
const [
|
|
6
|
+
export const useMesdan = ({ ibtidaiMetin = '', tekSatırMı, latiniMi: ibtidaiLatiniMi = false, aramaTalepEdilince, metin: metinHarici, tayinMetin: tayinMetinHarici, }) => {
|
|
7
|
+
const [metinDahili, tayinMetinDahili] = useState(ibtidaiMetin);
|
|
8
|
+
const [latiniMi, tayinLatiniMi] = useState(ibtidaiLatiniMi);
|
|
9
|
+
const kontrollüMü = metinHarici !== undefined && tayinMetinHarici !== undefined;
|
|
10
|
+
const metin = kontrollüMü ? metinHarici : metinDahili;
|
|
11
|
+
const tayinMetin = useCallback((yeniMetin) => {
|
|
12
|
+
if (kontrollüMü) {
|
|
13
|
+
tayinMetinHarici(yeniMetin);
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
tayinMetinDahili(yeniMetin);
|
|
17
|
+
}
|
|
18
|
+
}, [kontrollüMü, tayinMetinHarici]);
|
|
9
19
|
const metinSahasıİması = useRef(null);
|
|
10
20
|
const alemMevkisiİması = useRef(hazırlaAlemMevkisini(ibtidaiMetin.length));
|
|
11
21
|
const aramaTalepEdilinceRef = useRef(aramaTalepEdilince);
|
|
@@ -64,7 +74,7 @@ export const useMesdan = ({ ibtidaiMetin = '', tekSatırMı, latiniMi: ibtidaiLa
|
|
|
64
74
|
}
|
|
65
75
|
const netice = await Talimat_MetniTadilEt(metinSahası, currentMetin, alemMevkisi, tadiliMetinEmri, mesHadisesi, true);
|
|
66
76
|
alemMevkisiİması.current = netice.alemMevkisiTadilSonrası;
|
|
67
|
-
|
|
77
|
+
tayinMetin(netice.metinTadilSonrası);
|
|
68
78
|
}, [tekSatırMı]);
|
|
69
79
|
const handlePaste = useCallback(async (hadise) => {
|
|
70
80
|
const metinSahası = metinSahasıİması.current;
|
|
@@ -75,7 +85,7 @@ export const useMesdan = ({ ibtidaiMetin = '', tekSatırMı, latiniMi: ibtidaiLa
|
|
|
75
85
|
const alemMevkisi = hazırlaAlemMevkisiniMenzilli(metinSahası.selectionStart || 0, metinSahası.selectionEnd || 0);
|
|
76
86
|
const netice = await Talimat_MetniTadilEt(metinSahası, currentMetin, alemMevkisi, TadiliMetinEmri.YERLE, { latiniHarf: '', shiftBasılıMı: false, altBasılıMı: false, capsLockBasılıMı: false }, true);
|
|
77
87
|
alemMevkisiİması.current = netice.alemMevkisiTadilSonrası;
|
|
78
|
-
|
|
88
|
+
tayinMetin(netice.metinTadilSonrası);
|
|
79
89
|
}, []);
|
|
80
90
|
const handleBeforeInput = useCallback((hadise) => {
|
|
81
91
|
const metinSahası = metinSahasıİması.current;
|
|
@@ -112,11 +122,11 @@ export const useMesdan = ({ ibtidaiMetin = '', tekSatırMı, latiniMi: ibtidaiLa
|
|
|
112
122
|
const alemMevkisi = hazırlaAlemMevkisiniMenzilli(alemMevkisiEvveli.current.baş, alemMevkisiEvveli.current.son);
|
|
113
123
|
const netice = await Talimat_MetniTadilEt(metinSahası, currentMetin, alemMevkisi, tadiliMetinEmri, mesHadisesi, false);
|
|
114
124
|
alemMevkisiİması.current = netice.alemMevkisiTadilSonrası;
|
|
115
|
-
|
|
125
|
+
tayinMetin(netice.metinTadilSonrası);
|
|
116
126
|
}, [tekSatırMı]);
|
|
117
127
|
useEffect(() => {
|
|
118
128
|
const metinSahası = metinSahasıİması.current;
|
|
119
|
-
if (!metinSahası ||
|
|
129
|
+
if (!metinSahası || latiniMi) {
|
|
120
130
|
if (metinSahası) {
|
|
121
131
|
metinSahası.setAttribute('spellcheck', 'true');
|
|
122
132
|
}
|
|
@@ -155,19 +165,19 @@ export const useMesdan = ({ ibtidaiMetin = '', tekSatırMı, latiniMi: ibtidaiLa
|
|
|
155
165
|
metinSahası.removeEventListener('keydown', keydownListener);
|
|
156
166
|
metinSahası.removeEventListener('paste', pasteListener);
|
|
157
167
|
};
|
|
158
|
-
}, [
|
|
168
|
+
}, [latiniMi, tekSatırMı]);
|
|
159
169
|
useLayoutEffect(() => {
|
|
160
170
|
const metinSahası = metinSahasıİması.current;
|
|
161
|
-
if (metinSahası && !
|
|
171
|
+
if (metinSahası && !latiniMi) {
|
|
162
172
|
const { başMevki, sonMevki } = alemMevkisiİması.current;
|
|
163
173
|
if (başMevki <= metinSahası.value.length && sonMevki <= metinSahası.value.length) {
|
|
164
174
|
metinSahası.setSelectionRange(başMevki, sonMevki);
|
|
165
175
|
}
|
|
166
176
|
}
|
|
167
|
-
}, [metin,
|
|
168
|
-
const
|
|
169
|
-
|
|
177
|
+
}, [metin, latiniMi]);
|
|
178
|
+
const tebdilMetin = useCallback((yeniMetin) => {
|
|
179
|
+
tayinMetin(yeniMetin);
|
|
170
180
|
alemMevkisiİması.current = hazırlaAlemMevkisini(yeniMetin.length);
|
|
171
181
|
}, []);
|
|
172
|
-
return [metin, metinSahasıİması,
|
|
182
|
+
return [metin, metinSahasıİması, tebdilMetin, tayinLatiniMi];
|
|
173
183
|
};
|
package/talimat-2.md
DELETED
|
@@ -1,297 +0,0 @@
|
|
|
1
|
-
Excellent! Setting up a local development workflow to test your NPM package is a crucial step before publishing. It allows you to use your `mesdan` hook in a real application (like one made with Create React App, Vite, or Next.js) as if it were installed from the registry.
|
|
2
|
-
|
|
3
|
-
Here are the best methods to do this, starting with the most common and recommended approach.
|
|
4
|
-
|
|
5
|
-
### Method 1: `npm link` (Recommended for Active Development)
|
|
6
|
-
|
|
7
|
-
This is the standard and most efficient way to test a local package. It works by creating a symbolic link (a "symlink," which is like a shortcut) between your consumer project's `node_modules` folder and your `mesdan` package's source code.
|
|
8
|
-
|
|
9
|
-
This means any changes you make in your `mesdan` project are **instantly** reflected in your test project (after you rebuild, of course), without needing to reinstall anything.
|
|
10
|
-
|
|
11
|
-
**Here's the step-by-step process:**
|
|
12
|
-
|
|
13
|
-
**Step 1: In your `mesdan` package directory**
|
|
14
|
-
|
|
15
|
-
1. **Build your package.** Your `package.json` has a `kur` script that compiles your TypeScript into JavaScript in the `teshir/` directory. This is the code that will actually be used by the other project.
|
|
16
|
-
```bash
|
|
17
|
-
# In your /path/to/mesdan project folder
|
|
18
|
-
npm run kur
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
2. **Register a global link.** This command tells NPM to create a global link on your computer that points to this project directory.
|
|
22
|
-
```bash
|
|
23
|
-
npm link
|
|
24
|
-
```
|
|
25
|
-
You should see a success message confirming the link was created for `mesdan@1.0.2`.
|
|
26
|
-
|
|
27
|
-
**Step 2: In your local test project (e.g., a Create React App)**
|
|
28
|
-
|
|
29
|
-
1. **Create a test project** if you don't have one.
|
|
30
|
-
```bash
|
|
31
|
-
# For example, using Vite (recommended for speed)
|
|
32
|
-
npm create vite@latest my-test-app -- --template react-ts
|
|
33
|
-
cd my-test-app
|
|
34
|
-
npm install
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
2. **Link the `mesdan` package.** This command creates a symlink inside `my-test-app/node_modules/` that points to the global link you created in Step 1.
|
|
38
|
-
```bash
|
|
39
|
-
# In your /path/to/my-test-app folder
|
|
40
|
-
npm link mesdan
|
|
41
|
-
```
|
|
42
|
-
Now, if you look inside `my-test-app/node_modules/`, you'll see that `mesdan` is a shortcut to your original project folder.
|
|
43
|
-
|
|
44
|
-
**Step 3: Use the hook in your test project**
|
|
45
|
-
|
|
46
|
-
Now you can import and use your hook just like any other package.
|
|
47
|
-
|
|
48
|
-
```tsx
|
|
49
|
-
// In my-test-app/src/App.tsx
|
|
50
|
-
|
|
51
|
-
import { useRef } from 'react';
|
|
52
|
-
import { useMesdan } from 'mesdan'; // It works!
|
|
53
|
-
|
|
54
|
-
function App() {
|
|
55
|
-
const inputRef = useRef<HTMLInputElement>(null);
|
|
56
|
-
|
|
57
|
-
const [metin, metinSahasıİması, tebdilMetin, tebdilLatiniMi] = useMesdan<HTMLInputElement>({
|
|
58
|
-
ibtidaiMetin: "",
|
|
59
|
-
tekSatırMı: true,
|
|
60
|
-
latiniMi: false,
|
|
61
|
-
aramaTalepEdilince: () => alert("Arama talep edildi!"),
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
return (
|
|
65
|
-
<div>
|
|
66
|
-
<h1>Mesdan Test Sahası</h1>
|
|
67
|
-
<p>Aşağıdaki sahaya Osmanî metin yazmayı deneyin:</p>
|
|
68
|
-
<input
|
|
69
|
-
ref={metinSahasıİması}
|
|
70
|
-
value={metin}
|
|
71
|
-
onChange={(e) => tebdilMetin(e.target.value)} // Controlled component
|
|
72
|
-
style={{ width: '300px', padding: '8px', direction: 'rtl', fontFamily: 'Amiri, serif', fontSize: '1.5rem' }}
|
|
73
|
-
/>
|
|
74
|
-
<hr />
|
|
75
|
-
<button onClick={() => tebdilLatiniMi(true)}>Latini Moda Geç</button>
|
|
76
|
-
<button onClick={() => tebdilLatiniMi(false)}>Osmanî Moda Geç</button>
|
|
77
|
-
</div>
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export default App;
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
#### ⚠️ Important Gotcha: The "Invalid Hook Call" Error
|
|
85
|
-
|
|
86
|
-
When using `npm link` with React libraries, you might encounter the dreaded "Invalid Hook Call" error. This happens because the symlink can cause your setup to have **two different copies of React** loaded: one from your test app's `node_modules` and another from your `mesdan` project's `node_modules`.
|
|
87
|
-
|
|
88
|
-
**The Fix:** Tell your `mesdan` project to use the `react` from your test project.
|
|
89
|
-
|
|
90
|
-
From within your `mesdan` project directory, run this command:
|
|
91
|
-
```bash
|
|
92
|
-
# In your /path/to/mesdan project folder
|
|
93
|
-
npm link ../my-test-app/node_modules/react
|
|
94
|
-
```
|
|
95
|
-
This creates a symlink inside `mesdan/node_modules/` pointing to the single React instance in your test app, resolving the conflict.
|
|
96
|
-
|
|
97
|
-
---
|
|
98
|
-
|
|
99
|
-
### Method 2: `npm pack` (The "Real-World Simulation")
|
|
100
|
-
|
|
101
|
-
This method is less convenient for rapid development but is an excellent way to do a final check before publishing. It creates a compressed `.tgz` file, which is the exact file that gets uploaded to the NPM registry.
|
|
102
|
-
|
|
103
|
-
1. **Build your `mesdan` project.**
|
|
104
|
-
```bash
|
|
105
|
-
# In /path/to/mesdan
|
|
106
|
-
npm run kur
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
2. **Pack it.**
|
|
110
|
-
```bash
|
|
111
|
-
# In /path/to/mesdan
|
|
112
|
-
npm pack
|
|
113
|
-
```
|
|
114
|
-
This will create a file named `mesdan-1.0.2.tgz` in your project's root directory.
|
|
115
|
-
|
|
116
|
-
3. **Install the file in your test project.**
|
|
117
|
-
```bash
|
|
118
|
-
# In /path/to/my-test-app
|
|
119
|
-
# Use a relative or absolute path to the .tgz file
|
|
120
|
-
npm install ../mesdan/mesdan-1.0.2.tgz
|
|
121
|
-
```
|
|
122
|
-
This will install the package just as if it came from NPM.
|
|
123
|
-
|
|
124
|
-
**Downside:** Every time you make a change to `mesdan`, you must re-build, re-pack, and re-install it in your test project.
|
|
125
|
-
|
|
126
|
-
---
|
|
127
|
-
|
|
128
|
-
### Summary and Recommendation
|
|
129
|
-
|
|
130
|
-
| Method | Pros | Cons | Best for... |
|
|
131
|
-
| :--- | :--- | :--- | :--- |
|
|
132
|
-
| **`npm link`** | **Instant updates** (after rebuild). Fast development cycle. | Can cause React duplication issues (but it's fixable). Requires cleanup (`npm unlink`). | **Active, day-to-day development and testing.** |
|
|
133
|
-
| **`npm pack`** | **Perfectly simulates** a real NPM installation. No weird dependency issues. | **Slow workflow.** Requires re-packing and re-installing for every change. | **Final sanity check** before you run `npm publish`. |
|
|
134
|
-
|
|
135
|
-
**My advice:**
|
|
136
|
-
Use **`npm link`** for your development. Just be ready to apply the fix for the "Invalid Hook Call" error if it appears. It's the most productive workflow by far. Then, before you publish a new version, use **`npm pack`** once as a final test to be 100% sure everything is configured correctly.
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
---------------------------------------------
|
|
140
|
-
|
|
141
|
-
Of course! This is a very common and essential workflow for package development. Your `tercefzar` project is the perfect "consumer" application to test your local `mesdan` hook.
|
|
142
|
-
|
|
143
|
-
The process involves uninstalling the version from NPM and then creating a symbolic link (`symlink`) to your local `mesdan` project folder. Here's the step-by-step guide using the recommended `npm link` method.
|
|
144
|
-
|
|
145
|
-
### Step 1: Prepare Your Local `mesdan` Package
|
|
146
|
-
|
|
147
|
-
First, go to the directory where you are developing the `mesdan` hook.
|
|
148
|
-
|
|
149
|
-
1. **Build the project:** Make sure your latest TypeScript changes are compiled into JavaScript in the `teshir/` directory. Your `kur` script handles this.
|
|
150
|
-
```bash
|
|
151
|
-
# Navigate to your mesdan project folder
|
|
152
|
-
cd /path/to/your/local/mesdan
|
|
153
|
-
|
|
154
|
-
# Run the build script
|
|
155
|
-
npm run kur
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
2. **Create a global link:** This command tells your computer to create a global "shortcut" to this specific project folder, making it available to be linked by other projects.
|
|
159
|
-
```bash
|
|
160
|
-
npm link
|
|
161
|
-
```
|
|
162
|
-
You should see a success message indicating that a global link for `mesdan` was created.
|
|
163
|
-
|
|
164
|
-
### Step 2: Update Your `tercefzar` Project
|
|
165
|
-
|
|
166
|
-
Now, go to your `tercefzar` project to remove the old package and link the new one.
|
|
167
|
-
|
|
168
|
-
1. **Uninstall the NPM version:** This removes the `mesdan` package from your `node_modules` and its entry from your `package-lock.json`.
|
|
169
|
-
```bash
|
|
170
|
-
# Navigate to your tercefzar project folder
|
|
171
|
-
cd /path/to/your/tercefzar
|
|
172
|
-
|
|
173
|
-
# Uninstall the package
|
|
174
|
-
npm uninstall mesdan
|
|
175
|
-
```
|
|
176
|
-
This step is crucial to avoid conflicts.
|
|
177
|
-
|
|
178
|
-
2. **Link to your local `mesdan`:** This command looks for the global link you created in Step 1 and creates a symlink inside `tercefzar/node_modules/` that points directly to your local `mesdan` project folder.
|
|
179
|
-
```bash
|
|
180
|
-
npm link mesdan
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
### Step 3: Verification and Development
|
|
184
|
-
|
|
185
|
-
1. **Check `node_modules`:** If you look inside `tercefzar/node_modules/`, you will now see that `mesdan` has a small arrow icon next to it (in many terminals and file explorers), indicating it's a symlink.
|
|
186
|
-
|
|
187
|
-
2. **Run your dev server:** Start your `tercefzar` application as usual.
|
|
188
|
-
```bash
|
|
189
|
-
# In the tercefzar folder
|
|
190
|
-
npm run çat
|
|
191
|
-
```
|
|
192
|
-
Your application will now be using the code directly from your local `/path/to/your/local/mesdan` folder.
|
|
193
|
-
|
|
194
|
-
### The Development Workflow From Now On
|
|
195
|
-
|
|
196
|
-
This is where `npm link` is so powerful. To test new changes:
|
|
197
|
-
|
|
198
|
-
1. Make any code changes you want in your `mesdan` project's source files (`.ts` files).
|
|
199
|
-
2. In the `mesdan` project terminal, **re-run your build script**.
|
|
200
|
-
```bash
|
|
201
|
-
# In the mesdan folder
|
|
202
|
-
npm run kur
|
|
203
|
-
```
|
|
204
|
-
3. Vite's development server in your `tercefzar` project will detect the changes in the linked `node_modules` directory and **automatically hot-reload** your application.
|
|
205
|
-
|
|
206
|
-
You **do not** need to run `npm link` again. The link is permanent until you break it.
|
|
207
|
-
|
|
208
|
-
### ⚠️ Important: Fixing the "Invalid Hook Call" Error
|
|
209
|
-
|
|
210
|
-
As mentioned previously, this setup can lead to an "Invalid Hook Call" error because you might have two copies of React—one in `tercefzar/node_modules` and one in `mesdan/node_modules`.
|
|
211
|
-
|
|
212
|
-
**To fix this proactively:**
|
|
213
|
-
Go back to your `mesdan` project folder and tell it to use the `react` from your `tercefzar` project.
|
|
214
|
-
|
|
215
|
-
```bash
|
|
216
|
-
# In your /path/to/your/local/mesdan folder
|
|
217
|
-
npm link ../tercefzar/node_modules/react
|
|
218
|
-
```
|
|
219
|
-
*(Adjust the relative path `../tercefzar` if your projects are in different locations)*.
|
|
220
|
-
|
|
221
|
-
This ensures both your hook and your application are using the exact same React instance.
|
|
222
|
-
|
|
223
|
-
### How to Revert Back to the NPM Version
|
|
224
|
-
|
|
225
|
-
When you're done with local development and want to go back to using the official package from the NPM registry:
|
|
226
|
-
|
|
227
|
-
1. **Unlink the local package** in your `tercefzar` project. The `--no-save` flag is important as it prevents `npm` from removing `mesdan` from your `package.json` dependencies.
|
|
228
|
-
```bash
|
|
229
|
-
# In the tercefzar folder
|
|
230
|
-
npm unlink --no-save mesdan
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
2. **Re-install the package** from the registry.
|
|
234
|
-
```bash
|
|
235
|
-
# In the tercefzar folder
|
|
236
|
-
npm install
|
|
237
|
-
```
|
|
238
|
-
This will read your `package.json` and pull the specified version of `mesdan` from NPM, restoring the original state.
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
-------------------------------------------
|
|
242
|
-
|
|
243
|
-
Excellent questions. This touches on the core behavior of `npm link` and how it interacts with `package.json` and the `node_modules` directory.
|
|
244
|
-
|
|
245
|
-
### Question 1: "mesdan not visible in package.json. How can we keep track of it?"
|
|
246
|
-
|
|
247
|
-
You are correct, `npm link` **does not** modify your `package.json`. This is by design.
|
|
248
|
-
|
|
249
|
-
The purpose of `npm link` is to create a temporary, local development setup. It's not meant to be a permanent dependency declaration. Your `package.json` should always reflect the dependencies that a user (or a CI/CD pipeline) would install from the NPM registry.
|
|
250
|
-
|
|
251
|
-
**How to keep track of linked packages:**
|
|
252
|
-
|
|
253
|
-
1. **The `ls` command with `-g`:** You can see all globally linked packages on your system.
|
|
254
|
-
```bash
|
|
255
|
-
npm ls -g --depth=0 --link=true
|
|
256
|
-
```
|
|
257
|
-
This command lists all packages that you have run `npm link` on *in their source directories*. It will show you that `mesdan` is available globally for linking.
|
|
258
|
-
|
|
259
|
-
2. **The `ls` command in your project:** Inside your `tercefzar` project, you can see which dependencies are symlinked.
|
|
260
|
-
```bash
|
|
261
|
-
npm ls
|
|
262
|
-
```
|
|
263
|
-
In the output tree, a linked package will be clearly marked, often with an arrow `->` pointing to the absolute path of its source code on your machine. For example:
|
|
264
|
-
```
|
|
265
|
-
tercefzar@0.0.1 /path/to/your/tercefzar
|
|
266
|
-
└── mesdan@1.0.2 -> /path/to/your/local/mesdan
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
3. **Check `node_modules` directly:** In your file explorer or using `ls -l node_modules` in the terminal, you will see that `mesdan` is a symbolic link, not a regular directory.
|
|
270
|
-
|
|
271
|
-
**In summary:** The "source of truth" for knowing a package is linked is the state of your `node_modules` directory, not `package.json`.
|
|
272
|
-
|
|
273
|
-
### Question 2: "What will happen if I run `npm install mesdan` without unlinking?"
|
|
274
|
-
|
|
275
|
-
This is a great "what-if" scenario. If you run `npm install mesdan` while the symlink is active, **npm will overwrite the symlink.**
|
|
276
|
-
|
|
277
|
-
Here's the sequence of events:
|
|
278
|
-
|
|
279
|
-
1. **npm sees `mesdan` in `package.json`:** Your `tercefzar` project's `package.json` still has `"mesdan": "^1.0.2"` listed as a dependency.
|
|
280
|
-
2. **npm checks `node_modules`:** It finds a folder (which is actually a symlink) named `mesdan`.
|
|
281
|
-
3. **npm replaces it:** npm will remove the existing symlink and install the `mesdan` package from the NPM registry, downloading the version specified in your `package.json` (or the latest compatible version).
|
|
282
|
-
4. **`package.json` and `package-lock.json` are updated:** The command will ensure your `package.json` and `package-lock.json` are consistent with the newly installed version from the registry.
|
|
283
|
-
|
|
284
|
-
**The outcome:** Your local development link is broken, and you are back to using the official published version of the package.
|
|
285
|
-
|
|
286
|
-
This is actually a very simple way to revert your setup. Instead of running `npm unlink --no-save mesdan` followed by `npm install`, you could just run `npm install` (or `npm install mesdan`), and it would effectively do the same thing: restore the dependency from the NPM registry.
|
|
287
|
-
|
|
288
|
-
### Recommended Workflow Summary
|
|
289
|
-
|
|
290
|
-
| Action | Command in `tercefzar` | What it Does | Effect on `package.json` |
|
|
291
|
-
| :--- | :--- | :--- | :--- |
|
|
292
|
-
| **Start Local Dev** | 1. `npm uninstall mesdan` <br> 2. `npm link mesdan` | Removes NPM version, creates symlink to local `mesdan`. | `mesdan` is removed from dependencies. |
|
|
293
|
-
| **A Better Start** | 1. `npm link mesdan` | *If `mesdan` is already in `package.json`*, this command just creates the link. No need to uninstall first. | No change. |
|
|
294
|
-
| **End Local Dev** | `npm unlink --no-save mesdan` | Removes the symlink but keeps the dependency listed in `package.json`. | No change. |
|
|
295
|
-
| **Restore from NPM** | `npm install` | Removes the symlink and installs the package from the NPM registry based on `package.json`. | No change. |
|
|
296
|
-
|
|
297
|
-
**Pro Tip:** To avoid accidentally removing the dependency from your `package.json`, it's often best to just run `npm link mesdan` to start. If it's already installed from NPM, the link will replace it. When you're done, running `npm install` is the most reliable way to restore everything to its "official" state based on your `package.json`.
|