LivaDocsv1.1.2

Erişilebilirlik

Kullanıcı düzeyinde, uygulamanın tamamında geçerli görünüm tercihleri: tablo satır yoğunluğu, satır renklendirme, yazı boyutu ve tipi, metin aralığı, yüksek kontrast, hareketi azaltma, belirgin odak halkası, düğme ve sekme boyutu, menünün yeri. Tercihler tek bir depoda (store) tutulur, localStorage'a yazılır ve iki yoldan uygulanır:

  1. DOM üzerinden — <html> elementine yazılan data-liva-* öznitelikleri ve --liva-ui-scale CSS değişkeni. @dataliva/livalib/index.css içindeki kurallar bunları okur; ayrı bir CSS import'u gerekmez.
  2. Bileşen prop'ları üzerinden — tablo yoğunluğu, satır renklendirme, düğme/sekme boyutu ve menü yeri DevExtreme'e CSS ile değil prop ile geçtiği için ilgili Liva bileşenleri bu değerleri doğrudan depodan okur.

Depo bir sağlayıcıya (provider) bağımlı değildir: livalib import edildiği anda kayıtlı tercihi okur ve <html>'e uygular. LivaAccessibilityProvider yalnızca kullanıcıya özel anahtar, sunucudan gelen başlangıç değeri ya da sunucuya yazma gerektiğinde kullanılır.

import {
  LivaAccessibilityPanel,
  LivaAccessibilityPopup,
  LivaAccessibilityProvider,
  useLivaAccessibility,
} from "@dataliva/livalib";

Not: Tercihler document.documentElement üzerine yazıldığı için bu sayfadaki örneklerde yaptığınız değişiklikler dokümantasyon sitesinin tamamına uygulanır (bu sitenin kendi metinleri Liva/DevExtreme değişkenlerini kullanmadığından her ayar burada görünür bir fark yaratmayabilir). Örnekler sitenin kendi kaydına dokunmasın diye ayrı bir storageKey ile çalışır ve sayfadan ayrıldığınızda tercihler varsayılana döner. Sayfadaki üç örnek aynı depoyu paylaşır; birinde yapılan değişiklik diğerlerine anında yansır.

Ayar paneli

LivaAccessibilityPanel ayar ekranının kendisidir; bir rotaya (ör. /settings/accessibility) ya da kendi pencerenize gömülür. Dört kart (Tablolar, Okunabilirlik, Butonlar ve sekmeler, Görünüm ve hareket) ile canlı bir önizleme bölümü içerir. Her değişiklik anında uygulanır ve kaydedilir; ayrıca bir "Kaydet" adımı yoktur. Panel yerleşimini kapsayıcısının genişliğine göre (container query) ayarlar: dar bir kapsayıcıda kartlar tek sütuna iner.

Başlık şeridindeki "Varsayılanlara dön" butonu yalnızca varsayılandan sapan bir tercih varken etkindir.

Ayar paneli
Önizleme yükleniyor…

showHeader={false} başlık şeridini — ve onunla birlikte "Varsayılanlara dön" butonunu — kaldırır; bu durumda sıfırlamayı sayfanızın kendi araç çubuğuna useLivaAccessibility().reset ile koyabilirsiniz. showPreview={false} sağdaki önizlemeyi gizler; dar bir pencereye gömerken kullanışlıdır.

const { reset, isCustomized } = useLivaAccessibility();

<button type="button" onClick={reset} disabled={!isCustomized}>
  Varsayılanlara dön
</button>
<LivaAccessibilityPanel showHeader={false} showPreview={false} />

Popup

LivaAccessibilityPopup paneli hazır bir LivaPopup içinde açar. Pencerenin kendi başlığı kapalıdır; başlık şeridi ve kapat butonu panelden gelir (kapat butonu onHiding'i çağırır). Pencere dışına tıklanınca kapanır, içerik 78vh'yi aşarsa pencerenin içinde kayar.

Panelin tüm metinleri i18n ile değiştirilebilir; verilmeyen anahtarlar yerleşik Türkçe metinlerle doldurulur. Varsayılan açıklama ("Buradaki tercihler bu tarayıcıda, tüm ekranlarda geçerli olur.") yalnızca yerel kayıt için doğrudur — tercihleri sunucuya da yazıyorsanız description anahtarını değiştirin.

Popup ve i18n
Önizleme yükleniyor…

Hook ve Liva bileşenlerinin tepkisi

useLivaAccessibility() provider gerektirmez; güncel tercihleri, kısmi güncelleme yapan update, her şeyi varsayılana döndüren reset ve varsayılandan sapan bir tercih olup olmadığını söyleyen isCustomized döner. Kendi ayar kontrollerinizi bununla kurabilirsiniz.

Aşağıdaki tablo ekranın kendi prop'larıyla verilmiştir: gridSize="xs", rowAlternationEnabled={false}; alttaki butonlar size="sm". "Varsayılan" (auto) seçiliyken bu prop'lar geçerlidir. Başka bir değer seçtiğinizde tercih prop'u ezer — tablo seçilen yoğunluğa geçer, renklendirme açılır ya da kapanır, sayfadaki tüm butonlar seçilen boyuta geçer.

useLivaAccessibility ve Liva bileşenlerinin tepkisi
Önizleme yükleniyor…

auto sözleşmesi

gridDensity, zebraRows, controlSize ve menuPosition aynı kurala uyar: auto ekranın/bileşenin kendi prop'unu korur; başka bir değer seçilince prop yok sayılır ve tercih uygulama genelinde geçerli olur.

BileşenOkunan tercihEzilen prop
LivaDataGrid, LivaTreeListgridDensity, zebraRowsgridSize, rowAlternationEnabled
LivaPivotGridgridDensitygridSize
LivaButton, LivaIconButton, LivaTabPanelcontrolSizesize
LivaLayoutmenuPositionlayoutPosition

LivaButton ve LivaIconButton'ın eski size değerleri ('small', 'medium', 'large') sm, md, lg karşılığına çevrilir. md temanın kendi ölçüsüyle (32px yükseklik, 20px ikon) aynıdır. Diğer tercihler (yazı boyutu, kontrast, satır vurgusu, sütun çizgileri…) prop değil, aşağıdaki CSS kuralları üzerinden uygulanır.

Tercihler

AyarTipVarsayılan
gridDensity'auto' | 'xxs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl''auto'
zebraRows'auto' | 'on' | 'off''auto'
fontScalenumber (0.85 – 1.4; panel 0.05 adımla değiştirir)1
highContrastbooleanfalse
reduceMotionbooleanfalse (bkz. not)
focusHighlightbooleanfalse
boldTextbooleanfalse
underlineLinksbooleanfalse
fontFamily'default' | 'system' | 'readable' | 'mono''default'
textSpacing'default' | 'comfortable' | 'wide''default'
rowHoverbooleanfalse
columnLinesbooleanfalse
controlSize'auto' | 'xxs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl''auto'
menuPosition'auto' | 'side' | 'header''auto'

Not: Henüz hiç tercih kaydedilmemişse ve işletim sistemi "hareketi azalt" diyorsa (prefers-reduced-motion: reduce), ilk açılış reduceMotion: true ile başlar.

DOM ve CSS karşılıkları

Tercihler <html> elementine aşağıdaki özniteliklerle yazılır; değer varsayılandayken öznitelik kaldırılır. Kütüphanenin kuralları html[data-liva-…] seçicileriyle çalıştığı için DevExtreme temasının kurallarından daha özgüldür; aynı öznitelikleri kendi CSS'inizde kanca olarak kullanabilirsiniz.

AyarÖznitelik / değişkenEtkisi
fontScale--liva-ui-scale (her zaman), data-liva-text-scale (≠ 1 iken)body, DevExtreme bileşenleri, editörler ve buton metinleri 14px × ölçek olur; --dx-font-size* değişkenleri ile editör ve buton içeriğinin en küçük yüksekliği de ölçeklenir. Tablo CSS modülleri yazı boyutlarını aynı çarpanla hesaplar.
highContrastdata-liva-contrast="high"Kenarlık ve ayraçlar koyulaşır; DataGrid/TreeList/PivotGrid başlıkları kalınlaşır, editör çerçeveleri 2px olur.
reduceMotiondata-liva-motion="reduced"Tüm animasyon ve geçişlerin süresi 1 ms'ye iner, yumuşak kaydırma kapanır.
focusHighlightdata-liva-focus="strong":focus-visible öğelere 3px birincil renk halkası; odaklı grid hücresi, editör ve butonlara gölge.
boldTextdata-liva-bold="on"Metin 600, tablo başlıkları 800 kalınlığa çıkar.
underlineLinksdata-liva-links="underline"Bağlantıların (a, .dx-link) altı çizilir.
fontFamilydata-liva-fontYalnızca cihazda yüklü yazı tipleri: system (system-ui, Segoe UI…), readable (Atkinson Hyperlegible, Verdana…), mono (Cascadia Mono, Consolas…). İndirme yapılmaz.
textSpacingdata-liva-spacingHarf ve kelime aralığı body'ye, satır yüksekliği paragraf, liste, etiket ve buton metinlerine uygulanır; tablo satır yüksekliği bilerek etkilenmez.
rowHoverdata-liva-rowhover="on"DataGrid/TreeList'te imlecin üzerindeki satır birincil renkle boyanır.
columnLinesdata-liva-gridlines="on"DataGrid/TreeList hücreleri dikey çizgiyle ayrılır.
controlSizedata-liva-controlUygulamadaki tüm DevExtreme butonları ve sekmeleri (Liva bileşeni olsun olmasın) seçilen ölçüye geçer. Tablo satırı ve editör içindeki butonlarda yalnızca ikon boyutu değişir.
menuPositiondata-liva-menuMenünün yerini LivaLayout kendi içinde çözer (useLivaMenuPosition); öznitelik yalnızca uygulamanın kendi CSS'i için kancadır.

gridDensity ve zebraRows için öznitelik yazılmaz; bu iki tercih yalnızca bileşen prop'ları yoluyla uygulanır.

Not: Yazı boyutu kuralları temanın 14px tabanını varsayar ve body'ye calc(14px * var(--liva-ui-scale)) yazar. Uygulamanızın taban yazı boyutu 14px değilse (bu dokümantasyon sitesinde olduğu gibi) ölçek ilk kez değiştirildiğinde metinler beklenenden farklı boyutlanabilir.

Kalıcılık ve sunucuyla eşitleme

Tercihler localStorage'da JSON olarak, liva:accessibility anahtarında (LIVA_ACCESSIBILITY_STORAGE_KEY) saklanır:

  • Okunan kayıt her zaman normalize edilir: bilinmeyen değerler varsayılana düşer, fontScale 0.85 – 1.4 aralığına sıkıştırılıp iki ondalığa yuvarlanır. Bozuk JSON varsayılanlarla açılır.
  • Başka bir sekmede yapılan değişiklik storage olayıyla bu sekmeye de yansır.
  • localStorage yazılamıyorsa (gizli sekme, dolu kota) tercih yalnızca o oturum için geçerli olur.

Aynı tarayıcıyı birden fazla kullanıcı paylaşıyorsa ya da tercihler hesapla birlikte taşınacaksa LivaAccessibilityProvider kullanılır:

import { LivaAccessibilityProvider } from "@dataliva/livalib";

<LivaAccessibilityProvider
  storageKey={`liva:accessibility:${userId}`}
  initial={serverSettings}   // sabit referans — useMemo / state
  onChange={saveToServer}    // sabit referans — useCallback
>
  <App />
</LivaAccessibilityProvider>
  • storageKey değiştiğinde yeni anahtardaki kayıt okunur ve uygulanır (anahtarda kayıt yoksa varsayılanlar; işletim sistemi "hareketi azalt" diyorsa reduceMotion açık).
  • initial verilirse geçerli tercihlerin üzerine birleştirilir ve kazanır (sunucu, yerel kaydı ezer). Ancak initial localStorage'a yazılmaz ve onChange'i tetiklemez; bir sonraki açılışta sunucu cevabı gelene kadar eski yerel değer görünür. Yerel kopyanın da tazelenmesi isteniyorsa sunucu değeri setLivaAccessibility ile uygulanmalıdır (bu yol onChange'i tetikler; aşağıdaki örnekte olduğu gibi geri yazmayı bir bayrakla engelleyin).
  • onChange her gerçek değişiklikte, localStorage'a yazıldıktan sonra çağrılır; aynı değer tekrar yazılırsa, initial uygulanırken, anahtar değişirken ya da değişiklik başka bir sekmeden geldiğinde çağrılmaz. Paneldeki yazı boyutu kaydırıcısı sürüklenirken sık çağrılabileceği için sunucu isteğini debounce edin.
  • Provider, storageKey, initial veya onChange değiştiğinde depoyu yeniden yapılandırır. Her render'da yeni bir initial nesnesi verilirse Provider her yeniden çizildiğinde bu değerler tekrar uygulanır ve kullanıcının sonradan yaptığı değişiklikleri ekranda geri alır; initial ve onChange referanslarını sabit tutun.
  • Yapılandırma modül düzeyinde tektir: en son yapılan yapılandırma geçerlidir, onChange verilmeyen bir yapılandırma önceki işleyiciyi kaldırır ve Provider unmount olduğunda ayarlar geri alınmaz. Uygulamada tek bir Provider (ya da tek bir configureLivaAccessibility çağrısı) kullanın.

Provider yerine configureLivaAccessibility doğrudan da çağrılabilir. LivaBudget tercihleri bu yolla kullanıcı hesabına (sunucu tablosu) bağlar; özetle:

import {
  LIVA_ACCESSIBILITY_STORAGE_KEY,
  configureLivaAccessibility,
  setLivaAccessibility,
  type LivaAccessibilitySettings,
} from "@dataliva/livalib";

useEffect(() => {
  if (!userId) return;
  const controller = new AbortController();
  let timer: ReturnType<typeof setTimeout> | undefined;
  let pending: LivaAccessibilitySettings | null = null;
  let applyingServerValue = false;

  const flush = () => {
    clearTimeout(timer);
    if (pending) void saveToServer(pending);
    pending = null;
  };

  configureLivaAccessibility({
    storageKey: `${LIVA_ACCESSIBILITY_STORAGE_KEY}:${userId}`,
    onChange: (next) => {
      if (applyingServerValue) return; // sunucudan geleni geri yazma
      pending = next;
      clearTimeout(timer);
      timer = setTimeout(flush, 800); // kaydırıcı sürüklenirken tek istek
    },
  });

  void fetchFromServer(controller.signal)
    .then((server) => {
      if (!server || controller.signal.aborted) return;
      applyingServerValue = true;
      try {
        // initial yerine set: yerel kopya da tazelenir
        setLivaAccessibility(server as Partial<LivaAccessibilitySettings>);
      } finally {
        applyingServerValue = false;
      }
    })
    .catch(() => {
      /* ağ hatası: yerel tercih geçerli kalır */
    });

  return () => {
    controller.abort();
    flush(); // oturum kapanırken bekleyen kayıt kaybolmasın
    configureLivaAccessibility({ onChange: undefined });
  };
}, [userId]);

Kendi bileşenlerinizde

Liva bileşenlerinin kullandığı çözümleyiciler dışa açıktır; kendi tablo ya da buton sarmalayıcılarınızı aynı sözleşmeye bağlamak için kullanabilirsiniz.

import { Button } from "devextreme-react/button";
import { useLivaControlSizeClass, type LivaControlSize } from "@dataliva/livalib";

function ToolbarButton({ size, text }: { size?: LivaControlSize; text: string }) {
  // Tercih "auto" ise prop'taki boyut, değilse kullanıcının seçtiği boyut;
  // ikisi de yoksa "" (tema varsayılanı).
  const sizeClass = useLivaControlSizeClass(size);
  return <Button text={text} className={sizeClass} />;
}

useLivaControlSizeClass "liva-ctl-sized liva-ctl-size-<boyut>" sınıflarını döner; bu sınıflar .dx-button ve .dx-tabs için global CSS token'larını (--liva-ctl-h, --liva-ctl-font…) açar. Kullanıcı bir boyut seçtiğinde html[data-liva-control] kuralları zaten tüm DevExtreme butonlarını kapsadığından sınıf yalnızca "bileşenin kendi boyutu" durumunda fark yaratır.

React dışından (ör. bir servis ya da test) depoya getLivaAccessibility, setLivaAccessibility, resetLivaAccessibility ve subscribeLivaAccessibility ile erişilir. Tüm yardımcıların listesi Props sekmesindedir.