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:
- DOM üzerinden —
<html>elementine yazılandata-liva-*öznitelikleri ve--liva-ui-scaleCSS değişkeni.@dataliva/livalib/index.cssiçindeki kurallar bunları okur; ayrı bir CSS import'u gerekmez. - 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.
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.
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.
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şen | Okunan tercih | Ezilen prop |
|---|---|---|
| LivaDataGrid, LivaTreeList | gridDensity, zebraRows | gridSize, rowAlternationEnabled |
| LivaPivotGrid | gridDensity | gridSize |
| LivaButton, LivaIconButton, LivaTabPanel | controlSize | size |
| LivaLayout | menuPosition | layoutPosition |
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
| Ayar | Tip | Varsayılan |
|---|---|---|
gridDensity | 'auto' | 'xxs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'auto' |
zebraRows | 'auto' | 'on' | 'off' | 'auto' |
fontScale | number (0.85 – 1.4; panel 0.05 adımla değiştirir) | 1 |
highContrast | boolean | false |
reduceMotion | boolean | false (bkz. not) |
focusHighlight | boolean | false |
boldText | boolean | false |
underlineLinks | boolean | false |
fontFamily | 'default' | 'system' | 'readable' | 'mono' | 'default' |
textSpacing | 'default' | 'comfortable' | 'wide' | 'default' |
rowHover | boolean | false |
columnLines | boolean | false |
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şken | Etkisi |
|---|---|---|
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. |
highContrast | data-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. |
reduceMotion | data-liva-motion="reduced" | Tüm animasyon ve geçişlerin süresi 1 ms'ye iner, yumuşak kaydırma kapanır. |
focusHighlight | data-liva-focus="strong" | :focus-visible öğelere 3px birincil renk halkası; odaklı grid hücresi, editör ve butonlara gölge. |
boldText | data-liva-bold="on" | Metin 600, tablo başlıkları 800 kalınlığa çıkar. |
underlineLinks | data-liva-links="underline" | Bağlantıların (a, .dx-link) altı çizilir. |
fontFamily | data-liva-font | Yalnızca cihazda yüklü yazı tipleri: system (system-ui, Segoe UI…), readable (Atkinson Hyperlegible, Verdana…), mono (Cascadia Mono, Consolas…). İndirme yapılmaz. |
textSpacing | data-liva-spacing | Harf 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. |
rowHover | data-liva-rowhover="on" | DataGrid/TreeList'te imlecin üzerindeki satır birincil renkle boyanır. |
columnLines | data-liva-gridlines="on" | DataGrid/TreeList hücreleri dikey çizgiyle ayrılır. |
controlSize | data-liva-control | Uygulamadaki 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. |
menuPosition | data-liva-menu | Menü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,
fontScale0.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
storageolayıyla bu sekmeye de yansır. localStorageyazı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>
storageKeydeğiştiğinde yeni anahtardaki kayıt okunur ve uygulanır (anahtarda kayıt yoksa varsayılanlar; işletim sistemi "hareketi azalt" diyorsareduceMotionaçık).initialverilirse geçerli tercihlerin üzerine birleştirilir ve kazanır (sunucu, yerel kaydı ezer). AncakinitiallocalStorage'a yazılmaz veonChange'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ğerisetLivaAccessibilityile uygulanmalıdır (bu yolonChange'i tetikler; aşağıdaki örnekte olduğu gibi geri yazmayı bir bayrakla engelleyin).onChangeher gerçek değişiklikte, localStorage'a yazıldıktan sonra çağrılır; aynı değer tekrar yazılırsa,initialuygulanı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,initialveyaonChangedeğiştiğinde depoyu yeniden yapılandırır. Her render'da yeni birinitialnesnesi 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;initialveonChangereferanslarını sabit tutun. - Yapılandırma modül düzeyinde tektir: en son yapılan yapılandırma geçerlidir,
onChangeverilmeyen 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 birconfigureLivaAccessibilityç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.
LivaAccessibilityPanel
| Prop | Tip | Varsayılan |
|---|---|---|
i18n | LivaAccessibilityI18n | — (yerleşik Türkçe metinler) |
showPreview | boolean | true |
showHeader | boolean | true |
onClose | () => void | — (verilirse başlığa kapat butonu eklenir) |
className | string | '' |
LivaAccessibilityPopup
| Prop | Tip | Varsayılan |
|---|---|---|
visible | boolean | — (zorunlu) |
onHiding | () => void | — (zorunlu; kapat butonu ve dışarı tıklama) |
i18n | LivaAccessibilityI18n | — |
showPreview | boolean | true |
width | number | string | 'min(980px, 95vw)' |
height | number | string | 'auto' |
LivaAccessibilityProvider
| Prop | Tip | Varsayılan |
|---|---|---|
storageKey | string | — (verilmezse geçerli anahtar korunur; başlangıçta 'liva:accessibility') |
initial | Partial<LivaAccessibilitySettings> | null | — |
onChange | (settings: LivaAccessibilitySettings) => void | — |
children | ReactNode | — |
Provider kendine ait bir DOM öğesi eklemez, children'ı olduğu gibi çizer;
yalnızca configureLivaAccessibility çağrısını bir effect'e sarar.
useLivaAccessibility — dönen değer
| Alan | Tip | Açıklama |
|---|---|---|
settings | LivaAccessibilitySettings | Güncel tercihler. Referans, değer değişmedikçe sabittir. |
update | (patch: Partial<LivaAccessibilitySettings>) => void | Bir ya da birkaç tercihi günceller; değer normalize edilir. |
reset | () => void | Tüm tercihleri varsayılana döndürür (kaydeder, onChange'i tetikler). |
isCustomized | boolean | Varsayılandan sapan bir tercih var mı. |
LivaAccessibilityI18n
Tüm alanlar isteğe bağlı string'dir (previewRows hariç: string[]);
verilmeyenler yerleşik Türkçe metinle doldurulur.
| Bölüm | Anahtarlar |
|---|---|
| Başlık | title, description, reset, close (kapat butonunun etiketi) |
| Tablolar | tablesSection, tablesSectionHint, density, densityHint, densityAuto, densityXxs, densityXs, densitySm, densityMd, densityLg, densityXl, zebra, zebraHint, rowHover, rowHoverHint, columnLines, columnLinesHint |
| Okunabilirlik | readabilitySection, readabilitySectionHint, fontScale, fontScaleHint, decreaseFont, increaseFont, boldText, boldTextHint, underlineLinks, underlineLinksHint, fontFamily, fontFamilyHint, fontFamilyDefault, fontFamilySystem, fontFamilyReadable, fontFamilyMono, textSpacing, textSpacingHint, textSpacingDefault, textSpacingComfortable, textSpacingWide |
| Butonlar ve sekmeler | controlsSection, controlsSectionHint, controlSize, controlSizeHint, controlSample |
| Görünüm ve hareket | visionSection, visionSectionHint, menuPosition, menuPositionHint, menuPositionAuto, menuPositionSide, menuPositionHeader, highContrast, highContrastHint, reduceMotion, reduceMotionHint, focusHighlight, focusHighlightHint |
| Önizleme | previewTitle, previewHint, previewColumnCode, previewColumnName, previewColumnAmount, previewRows, previewTextTitle, previewText, previewLink, previewControlsTitle, previewTabActive, previewTabOther, previewButtonPrimary, previewButtonSecondary |
| Üç durumlu seçim | stateAuto, stateOn, stateOff |
Yoğunluk etiketleri (densityAuto … densityXl) hem tablo yoğunluğu hem de
düğme/sekme boyutu seçeneklerinde kullanılır.
Depo yardımcıları
| Ad | İmza | Açıklama |
|---|---|---|
getLivaAccessibility | () => LivaAccessibilitySettings | Güncel tercihler. |
setLivaAccessibility | (patch: Partial<LivaAccessibilitySettings>) => void | Kısmi güncelleme; kaydeder ve onChange'i çağırır. |
resetLivaAccessibility | () => void | Varsayılanlara döndürür. |
subscribeLivaAccessibility | (listener: () => void) => () => void | Değişiklik aboneliği; aboneliği kaldıran fonksiyonu döner. Yalnızca gerçek değişimde çağrılır. |
getLivaAccessibilityServerSnapshot | () => LivaAccessibilitySettings | SSR anlık görüntüsü (her zaman varsayılanlar); useSyncExternalStore için. |
configureLivaAccessibility | (config: LivaAccessibilityConfig) => void | { storageKey?, onChange?, initial? } — Provider'ın kullandığı yapılandırma. |
normalizeAccessibilitySettings | (raw: Partial<LivaAccessibilitySettings> | null | undefined) => LivaAccessibilitySettings | Dışarıdan (sunucu, localStorage) gelen ham veriyi geçerli ayara çevirir. |
LIVA_ACCESSIBILITY_STORAGE_KEY | 'liva:accessibility' | Varsayılan localStorage anahtarı. |
LIVA_ACCESSIBILITY_DEFAULTS | LivaAccessibilitySettings | Fabrika ayarları (dondurulmuş nesne). |
Çözümleyici hook'lar
| Ad | İmza | Açıklama |
|---|---|---|
useLivaGridSize | <T extends string>(fallback: T, supported?: readonly T[]) => T | gridDensity auto ise fallback, değilse tercih. Tercih supported listesinde yoksa listenin ilk elemanı döner. |
useLivaRowAlternation | (fallback: boolean) => boolean | zebraRows auto ise fallback, değilse on/off. |
useLivaControlSize | (fallback?: LivaControlSize | LivaLegacyControlSize) => LivaControlSize | undefined | controlSize auto ise prop (eski adlar çevrilir), değilse tercih. |
useLivaControlSizeClass | (fallback?: LivaControlSize | LivaLegacyControlSize) => string | Yukarıdakinin sonucunu doğrudan sınıf adına çevirir. |
livaControlSizeClass | (size: LivaControlSize | undefined) => string | 'liva-ctl-sized liva-ctl-size-<boyut>' ya da ''. |
resolveLivaControlSize | (size: LivaControlSize | LivaLegacyControlSize | undefined) => LivaControlSize | undefined | small/medium/large → sm/md/lg. |
useLivaMenuPosition | (fallback: 'side' | 'header') => 'side' | 'header' | menuPosition auto ise fallback, değilse tercih. LivaLayout bunu kendi içinde çağırır. |
Tipler ve sabitler
| Ad | Değer |
|---|---|
LivaGridSize | 'xxs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' |
LivaGridDensity | 'auto' | LivaGridSize |
LivaControlSize | 'xxs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' |
LivaControlDensity | 'auto' | LivaControlSize |
LivaLegacyControlSize | 'small' | 'medium' | 'large' |
LivaTriState | 'auto' | 'on' | 'off' |
LivaFontFamily | 'default' | 'system' | 'readable' | 'mono' |
LivaTextSpacing | 'default' | 'comfortable' | 'wide' |
LivaMenuPosition | 'auto' | 'side' | 'header' |
LivaAccessibilitySettings | Tercihler tablosundaki 14 alan |
LivaAccessibilityConfig | { storageKey?: string; onChange?: (next) => void; initial?: Partial<LivaAccessibilitySettings> | null } |
UseLivaAccessibilityResult | useLivaAccessibility dönüş tipi |
LIVA_FONT_SCALE_MIN / LIVA_FONT_SCALE_MAX / LIVA_FONT_SCALE_STEP | 0.85 / 1.4 / 0.05 |
LIVA_GRID_SIZES / LIVA_GRID_DENSITIES | Boyut listesi / başına 'auto' eklenmiş hali |
LIVA_CONTROL_SIZES / LIVA_CONTROL_DENSITIES | Boyut listesi / başına 'auto' eklenmiş hali |
LIVA_FONT_FAMILIES, LIVA_TEXT_SPACINGS, LIVA_MENU_POSITIONS | İlgili tiplerin tüm değerleri |
Ayrıca LivaAccessibilityPanelProps, LivaAccessibilityPopupProps ve
LivaAccessibilityProviderProps tipleri dışa açıktır.