Kürtçe klavye

Açık kaynak · Kürtçe metin girişi · v0.4.0

Kürtçe klavye

Web'in her yerinde Kürtçe yazın

Soranî (Arap alfabesi) ve Kurmancî (Latin alfabesi) için gömülebilir sanal klavye. Tek widget, temelden doğru birleşik Unicode.

npm install kurdish-keyboard
yazı sistemi
2
düzen
3
çalışma zamanı bağımlılığı
0
doğrulanmış codepoint
55

Kurmancî, QWERTY + satır

ç ê î ş û için ek bir satırı olan QWERTY, soldan sağa.

Soranî

Unicode CLDR verisinden düzen, sağdan sola.

Neden

Tek harf, birçok kod

Web'deki Kürtçe metin, onlarca yıldır bozuk kodlamalarla dolu. Aynı görünen harflerin kodları farklıdır: ك ve ک, ي ve ی, ه ve ە. Bu durum aramayı, sıralamayı ve yazım denetimini sessizce bozar. Bu klavye yalnızca KRG Bilgi Teknolojileri Dairesi standardındaki, Unicode Karakter Veritabanı ile doğrulanmış birleşik codepoint'leri yazar. Bu yüzden onunla yazılan her metin temelden doğrudur.

Canlı demo

Bu bir screenshot değil. Bu, widget'ın kendisi.

Bu sayfadaki klavyeler görsel değildir. Gerçek pakettir ve CSS özel özellikleriyle tema verilmiştir. Bir düzen seçin ve yazın. ⇧ ikinci katmanı gösterir; Latin düzenleri ⇪ Caps Lock da ekler. Arrow tuşlarıyla tuşlar arasında gezinebilirsiniz ve screen-reader'lar da klavyeyi kullanabilir.

Özellikler

Bir Kürtçe girişin ihtiyaç duyduğu her şey

  1. Birleşik Unicode

    Temelden doğru.

    Widget yalnızca KRG standardı ve UCD ile doğrulanmış codepoint'leri yazabilir: her zaman ک, asla ك; her zaman ی, asla ي; ve ە, olduğu gibi ünlü olarak. Bozuk metin geçmişte kalır.

  2. İki yazı sistemi, üç düzen

    Sağdan sola ve soldan sağa, tek engine.

    Unicode CLDR verisinden üretilmiş bir Soranî düzeni ve topluluğun iki Kurmancî düzeni. setLayout() ile canlı geçiş yapın; yön, katmanlar ve Caps Lock kendiliğinden uyum sağlar.

  3. Mobil için yapıldı

    Widget'ın kendisi klavyedir.

    Alan başına inputmode="none" telefon klavyesini gizli tutar; yazma işini sabitlenmiş veya yüzen bir panel yapar. Dokunma hedefleri bir capability query ile 44px'e büyür, asla user-agent koklamayla değil.

  4. Rich text desteği

    Contenteditable ve editörler.

    Düz contenteditable ek ayar gerektirmeden çalışır. Lexical, ProseMirror ve Slate gibi framework editörleri küçük bir ekleme adaptörüyle bağlanır.

  5. Varsayılan olarak erişilebilir

    Roving tabindex, sesli adlar.

    WAI-ARIA klavye navigasyonu, görünür odak ve İngilizce ya da Kürtçe screen-reader label'ları; etiket dili çalışma zamanında (runtime) değiştirilebilir.

  6. Eski metin temizleyici

    On yılların ك ve ي temizliği.

    normalizeLegacy() eski, bozuk Soranî metni birleşik codepoint'lere dönüştürür ve klavyenin kullandığı aynı veri dosyasıyla çalışır. DOM gerektirmediği için Node'da ve CLI'larda da çalışır.

İlkeler

Nasıl yapıldı

  1. İcat değil, standart

    Codepoint'ler KRG birleşik klavye standardından, Soranî düzeni Unicode CLDR'den gelir. Standardın olduğu yerde hiçbir şey elle uydurulmaz.

  2. Kod değil, veri

    Düzenler, bir şemayla doğrulanan JSON dosyalarıdır. Engine bir düzenin adına asla bakmaz. Yeni bir düzen yeni veridir, yeni kod değil.

  3. Platform yeter

    Yazmak için setRangeText, telefonlar için inputmode, tema için custom property'ler. Sıfır çalışma zamanı bağımlılığı, ESM ve CJS, tree-shakable düzenler.

  4. Varsayılmış değil, doğrulanmış

    Her codepoint birincil kaynaklara karşı harf harf incelenir. Her sürümden önce çalıştırılabilir bir spec, yayımlanan paketi kanıtlar.

Rehber

Entegrasyon rehberi

Klavyeyi sitenize eklemek için gereken her şey. Her örnek, kodunun yanında canlı çalışır.

Hızlı başlangıç

Bağla, yaz, ayır

Düzen başına bir import, tek çağrı. Panel, alanın hemen ardından görünür. Bir tuş imlecin olduğu yere yazar, seçili metnin yerine geçer ve odağı alanda tutar. kb.detach() paneli kaldırır ve tüm side effect'leri geri alır.

import { KurdishKeyboard } from "kurdish-keyboard";
import "kurdish-keyboard/styles.css"; // optional, recommended
import { soraniLayout } from "kurdish-keyboard/layouts/sorani";

const kb = KurdishKeyboard.attachTo(document.querySelector("input"), {
  layout: soraniLayout,
});
// later: kb.detach()

Canlı

SeçenekTürVarsayılanNe yapar
layoutLayoutminimal panelGösterilecek düzen. Her yazı sistemi için birini import edin ya da kendi düzeninizi verin.
adapterInsertionAdapteryerleşikFramework editörleri için kendi ekleme yönteminiz. Aşağıdaki “Rich text” bölümüne bakın.
suppressNativebooleanfalseinputmode="none" ayarlar; böylece telefonlar kendi klavyelerini gizli tutar.
position'inline' | 'docked' | 'floating''inline'Panelin yeri. Aşağıdaki “Mobil” bölümüne bakın.
labelLanguage'en' | 'ku''en'Screen-reader label'larının dili (Shift, Space, …).

Düzenler

Üç düzen, canlı geçiş

Her düzenin kendi giriş noktası vardır; böylece yalnızca Soranî kullanan bir site Kurmancî verisini paketlemez. setLayout() canlı geçiş yapar: panel yeniden çizilir, yön sağdan sola ile soldan sağa arasında değişir, Shift ve Caps Lock sıfırlanır. Latin düzenlerinde ⇪ Caps Lock vardır; Shift her düzende tek bir tuş için çalışır.

Kendi düzeniniz: bir düzen plain veridir. Layout türü export edilir ve JSON, yayımlanmış şemayla doğrulanır. Tuşlar karakter değil dize yazar: CLDR'de Shift+و وو yazar. Doğrulanmış codepoint tablosu kurdish-keyboard/codepoints.json olarak gelir. Sağdan sola alanlar: panel kendi yönünü ayarlar, ama alanın dir değeri sizin işinizdir. Soranî alanları için dir="rtl" veya dir="auto" kullanın; unutursanız widget konsola bir log yazar.

import { soraniLayout } from "kurdish-keyboard/layouts/sorani";
import { kurmanjiPhonetic } from "kurdish-keyboard/layouts/kurmanji-phonetic";
import { kurmanjiOfficial } from "kurdish-keyboard/layouts/kurmanji-official";

kb.setLayout(kurmanjiPhonetic); // live swap, LTR
kb.setLayout(soraniLayout); // back to RTL

Canlı

Rich text

Contenteditable ve kendi adaptörünüz

Panel, contenteditable element'lere ek ayar gerektirmeden bağlanır. Yazma işi tarayıcının kendi düzenleme command'larıyla yapılır; böylece imleç, seçim ve input olayları gerçek tuş vuruşları gibi davranır. Tek kural: tuşlar yalnızca seçim bağlı element'in içindeyken çalışır. İmleç başka bir yerdeyse tuş hiçbir şey yapmaz; asla yanlış alana yazmaz.

Framework editörleri, örneğin Lexical, ProseMirror ve Slate, dışarıdan yapılan düzenlemeleri tasarım gereği geri alır. Bunlar için bir adapter verin. insertChar ve deleteBack zorunludur; insertLineBreak ve insertParagraph isteğe bağlıdır. Panel yalnızca adaptörün sağladığı işlemler için tuş gösterir: insertParagraph yoksa ¶ tuşu da yoktur. Birini sarmalamak isterseniz yerleşik adaptörler de dışa aktarılır (valueAdapter, contentEditableAdapter).

// Plain contenteditable: nothing new to learn
KurdishKeyboard.attachTo(document.querySelector("[contenteditable]"), {
  layout: soraniLayout,
});

// Lexical (e.g. Payload CMS): supply an editor-native adapter
import {
  $getSelection,
  DELETE_CHARACTER_COMMAND,
  INSERT_LINE_BREAK_COMMAND,
  INSERT_PARAGRAPH_COMMAND,
} from "lexical";

KurdishKeyboard.attachTo(editorRootElement, {
  layout: soraniLayout,
  adapter: {
    insertChar: (text) =>
      editor.update(() => $getSelection()?.insertText(text)),
    deleteBack: () => editor.dispatchCommand(DELETE_CHARACTER_COMMAND, true),
    insertLineBreak: () =>
      editor.dispatchCommand(INSERT_LINE_BREAK_COMMAND, false),
    insertParagraph: () =>
      editor.dispatchCommand(INSERT_PARAGRAPH_COMMAND, undefined),
  },
});

Canlı

Düzenlenebilir alan (Soranî)

Mobil

Klavyenin kendisi olun

suppressNative, inputmode="none" ayarlar. Bu, telefona “bu sayfanın kendi klavyesi var” demenin standart yoludur. Bedeli, o alanda telefonun otomatik düzeltmesini kaybetmektir; bu yüzden alan başına isteğe bağlıdır. docked paneli ekranın altına sabitler ve alanı görünür tutar; floating paneli köşeye yakın tutar. Dokunmatik screen'lerde dokunma hedefleri 44px'e büyür.

KurdishKeyboard.attachTo(field, {
  layout: soraniLayout,
  suppressNative: true,
  position: "docked", // or "floating"
});

Canlı

Bilgisayarda sabit paneli görürsünüz. Telefonda inputmode="none" telefon klavyesini de uzak tutar.

Tema

Özel özellikler, CSS-in-JS yok

Stil dosyasını bir kez import edin, sonra --kkb-* özelliklerini panelde veya herhangi bir üst öğede ayarlayın. Stil dosyası isteğe bağlıdır; widget onsuz da çalışır. Aşağıdaki iki klavye yalnızca özel özelliklerde farklıdır.

Dahili --_* özellikleri türetilmiş değerlerdir. Yalnızca herkese açık olanları değiştirin.

.theme-night {
  --kkb-key-bg: #1e293b;
  --kkb-key-color: #e2e8f0;
  --kkb-key-border: #334155;
  --kkb-pressed-bg: #334155;
  --kkb-focus-color: #38bdf8;
  --kkb-surface-bg: #1e293b;
}

Varsayılan

Koyu tema, yalnızca --kkb-* ile

ÖzellikVarsayılanBiçimlendirdiği
--kkb-gap4pxTuşlar ve satırlar arası boşluk
--kkb-key-size2.2rem · 44px dokunmatik ekranlardaEn küçük tuş genişliği ve yüksekliği
--kkb-key-font-size1.1rem · 1.3rem dokunmatik ekranlardaTuş etiketi boyutu
--kkb-key-bgButtonFaceTuş arka planı
--kkb-key-colorButtonTextTuş etiketi rengi
--kkb-key-borderButtonText 40%Tuş kenarlığı rengi
--kkb-key-radius4pxTuş köşe yarıçapı
--kkb-pressed-bg#cbdceeEtkin Shift ve Caps Lock arka planı
--kkb-focus-color#1a56a0Klavye odak halkası
--kkb-surface-bgCanvasSabitlenmiş veya yüzen panelin arka planı

Erişilebilirlik

Klavye gezinmesi, sesli adlar

Panel, WAI-ARIA roving tabindex desenini kullanan, default düğmelerden oluşan etiketli bir role="group" öğesidir. Tek bir Tab durağıdır. Ok tuşları tuşlar arasında görsel yönde hareket eder; bu yüzden sağdan sola panellerde yönleri terstir. Home ve End satırın başına ve sonuna atlar; Enter ve Space tuşa basar. Görünür bir işareti olmayan tuşlara ad verilir (Space, ZWNJ, ⇧ Shift, ⇪ Caps Lock). Yeniden render'dan sonra odak yerinde kalır ve :focus-visible en az 3:1 kontrastlı bir outline gösterir.

// at attach time…
KurdishKeyboard.attachTo(field, {
  layout: soraniLayout,
  labelLanguage: "ku",
});

// …or live
kb.setLabelLanguage("en");

Canlı

⇧ tuşu şunu söyler:

Panele girmek için Tab'a basın, sonra ok ya da arrow tuşlarını kullanın.

Eski metin

Eski metni temizleyin

normalizeLegacy() eski, bozuk Soranî metni (Arapça ك ve ي, ە yerine ه) birleşik codepoint'lere dönüştürür. Bu method klavyeyle aynı veri dosyasını kullanır. DOM gerektirmez; bu yüzden Node'da, worker'larda ve CLI'larda çalışır.

Önce bunu okuyun: girdinin Kürtçe olduğu varsayılır. ك→ک ve ي→ی her zaman uygulanır, bu yüzden gerçek Arapça alıntılar da değişir; başka dilleri kendiniz ayırın. ه→ە kuralı yalnızca konuma bakar: kelime sonundaki ه değişir (ZWNJ'den önce de); başka bir Arapça harften, tatvilden veya bir harekeden önceki ه değişmez. Kelime ortasındaki eski ünlüler bulunmaz ve sözlük kullanılmaz. Latin metin değişmez.

import { normalizeLegacy } from "kurdish-keyboard/normalize";

normalizeLegacy("كوردي"); // → "کوردی"
normalizeLegacy("ئێمه"); // → "ئێمە"

Canlı

Sonuç

CDN

Derleme adımı yok

Betik paketi global bir KurdishKeyboard nesnesi sağlar. Bu nesnenin attachTo metodu düzen adlarını ('sorani', 'kurmanji-phonetic', 'kurmanji-official') veya Layout nesnelerini alır; bilinmeyen bir ad, geçerli adların listesini içeren bir hata fırlatır. Nesnede ayrıca bir layouts listesi ve normalizeLegacy vardır. Bu paket tüm düzenleri içerir; bir bundler kullanıyorsanız modül (module) girişlerini kullanın.

<script src="https://unpkg.com/kurdish-keyboard"></script>
<script>
  KurdishKeyboard.attachTo(document.querySelector("input"), {
    layout: "sorani",
  });
</script>

Framework'ler

React, Vue, Svelte: wrapper gerekmez

Her ekleme, alanda bubbling bir input olayı (inputType: 'insertText') gönderir. Böylece framework bağlamaları değişikliği kullanıcı yazmış gibi görür. Mount sırasında bağlayın, unmount sırasında ayırın.

function KurdishInput() {
  const [value, setValue] = useState("");
  const ref = useRef(null);

  useEffect(() => {
    const kb = KurdishKeyboard.attachTo(ref.current, { layout: soraniLayout });
    return () => kb.detach();
  }, []);

  return (
    <input
      dir="rtl"
      ref={ref}
      value={value}
      onChange={(e) => setValue(e.target.value)}
    />
  );
}
<script setup>
const text = ref("");
const field = ref(null);
let kb;

onMounted(() => {
  kb = KurdishKeyboard.attachTo(field.value, { layout: soraniLayout });
});
onUnmounted(() => kb?.detach());
</script>

<template>
  <input dir="rtl" ref="field" v-model="text" />
</template>

<!-- Svelte: bind:value works the same way -->

Sınırlar

Neleri yapamaz ve neden

Bunlar miss olmuş özellikler değil, tarayıcı rule'larıdır.

Başka sitelerden gelen iframe'lere yazamaz
Aynı köken politikası (same-origin policy), başka bir kökenden gömülen sayfalara her türlü erişimi engeller.
Gerçek tuş vuruşları üretemez
Betikle üretilen klavye olaylarında isTrusted: false vardır ve tarayıcılar bu olayların etkisini yok sayar. Bu yüzden widget alanın değerini doğrudan setRangeText() ile değiştirir. Bu her yerde çalışır, parola alanlarında da.
suppressNative otomatik düzeltmeyi kapatır
inputmode="none" o alan için telefon klavyesinin tamamını kaldırır, otomatik düzeltme de buna dahildir. Mekanizma böyle çalışır; bu yüzden alan başına isteğe bağlıdır.
Framework editörleri bir adaptör gerektirir
Lexical, ProseMirror ve Slate kendi DOM'larını yönetir ve dışarıdan yapılan düzenlemeleri geri alır. Tarayıcı düzeyinde bir ekleme bunları güvenle yönetemez; adapter seçeneği bunlar içindir. Düz contenteditable ek ayar gerektirmeden çalışır.
Tarayıcı desteği
Yaklaşık son üç yılın evergreen tarayıcıları ve Safari 15.4+. Küçük bir kayıp var: varsayılan tuş kenarlığı color-mix() kullanır (Safari 16.2+). Eski tarayıcılar tuşları bu kenarlık olmadan gösterir; isterseniz --kkb-key-border değerini kendiniz ayarlayın. Hiçbir polyfill gönderilmez.

Edinin

Ücretsiz, bir klavyenin olması gerektiği gibi

Ücretsiz

MIT lisansı · katman yok, izleme yok, kilitlenme yok

npm install kurdish-keyboard

npm'de 0.4.0 sürümü ya da GitHub deposundan kurun.

GitHub'da görüntüle

Sorular

Siz sormadan yanıtlandı

Hangi tarayıcılar destekleniyor?
Son üç yılın evergreen tarayıcıları ve Safari 15.4+. Widget'ın kullandığı her tarayıcı API'si yaygın olarak desteklenir; bu yüzden hiçbir polyfill gönderilmez.
React, Vue veya Svelte ile çalışır mı?
Evet. Widget her eklemeden sonra bubbling bir input olayı gönderir; böylece framework bağlamaları değişikliği wrapper olmadan görür.
Her alana yazabilir mi?
Aynı sayfadaki her input, textarea veya contenteditable öğesine yazar; Rich text editörlerine de bir adaptörle yazar. Başka sitelerden gelen iframe'ler tarayıcı güvenliği nedeniyle engellenir.
Neden Arapça kef yazmıyor?
Kürtçe metinde ك yalnızca ک'ye benzer ve aramayı ve sıralamayı sessizce bozar. Bu yüzden widget her zaman ک yazar. Arapça adları yazmak için gerçek Arapça harfler Soranî Shift katmanındadır.
Kendi düzenimi yapabilir miyim?
Evet. Düzenler, yayımlanmış bir şemayla doğrulanan düz JSON'dur. Engine her geçerli düzeni olduğu gibi gösterir; bu yüzden bir community düzeni bir eklemedir, fork değil.