API referansı

@thefinder/react

Dosya yöneticisi arayüzü. Tek bağımlılığı react ve react-dom'dur (≥ 18, peer); stiller saf CSS'tir.

"use client";
import { TheFinder } from "@thefinder/react";
import "@thefinder/react/styles.css";

<div style={{ height: "100vh" }}>
  <TheFinder endpoint="/api/files" locale="tr" />
</div>

styles.css bir kez, uygulamanın herhangi bir yerinde içe aktarılmalıdır. Bileşen ebeveyninin yüksekliğini doldurur (height prop'u ile değiştirilebilir).

<TheFinder />#

Bağlantı#

PropTipAçıklama
endpointstringZorunlu. API adresi, örn. "/api/files"
headersRecord<string, string> \| () => Record<string, string>Her isteğe eklenecek başlıklar (örn. Authorization)
credentialsRequestCredentialsCross-origin API'de çerez için "include"
clientTheFinderClientKendi yapılandırdığınız istemci. Verilirse endpoint/headers/credentials yerine kullanılır.
onUnauthorized() => voidAPI 401 döndüğünde çağrılır, örn. giriş sayfasına yönlendirmek için

Görünüm#

PropTipVarsayılanAçıklama
localestringtarayıcı dili (tr ya da en)Hazır diller: "tr", "en". Başka bir dil için messages ile birlikte verin.
messagesPartial<Messages>—Çevirileri ezer ya da ekler. Eksik anahtarlar İngilizceden gelir.
theme"light" \| "dark" \| "auto""auto"auto işletim sistemini izler
skin"classic" \| "macos""classic"macos: Finder benzeri görünüm (mavi klasörler, trafik ışıkları, zebra satırlar, buzlu menüler). Açık ve koyu modda çalışır.
density"comfortable" \| "compact""comfortable"
settingsbooleantrueBaşlıkta tema, görünüm ve yoğunluk seçilen ayarlar menüsü. Kullanıcının seçimi persistKey altında saklanır ve prop'ları ezer; prop sonradan değişirse prop geçerli olur.
heightnumber \| string"100%"
className, style—Kök öğeye (.tf-root) eklenir
thumbnailsbooleantrueGörsellerde küçük resim gösterir

Başlangıç durumu#

PropTipVarsayılanAçıklama
initialFolderstringson klasör, yoksa ilk volume'ün köküİlk açılacak klasörün kimliği
rememberFolderbooleantrueKullanıcının en son açtığı klasörü tekrar aç (persistKey altında saklanır)
defaultViewPartial<Prefs>—Başlangıç tercihleri. Kullanıcının değiştirdikleri persistKey altında saklanır ve bunlardan önceliklidir.
persistKeystring \| false"thefinder"Tercihlerin saklanacağı localStorage anahtarı. false saklamaz.

Prefs:

AlanTipVarsayılan
view"grid" \| "list""grid"
sortKey"name" \| "size" \| "mtime" \| "kind""name"
sortDir1 \| -11
foldersFirstbooleantrue
detailsOpenbooleanfalse
sidebarWidthnumber232

Olaylar#

PropTipAçıklama
onOpen(entry) => boolean \| voidBir dosya açılırken çağrılır (çift tık, Enter). true döndürürseniz varsayılan davranış (önizleme, editör, indirme) çalışmaz.
onChange(event) => voidHer değişiklikten sonra çağrılır
editorsCustomEditor[]"Birlikte aç" menüsüne editör ekler. Bkz. Özel editörler.

onChange olayı: { type, entries?, ids? }. entries yeni ya da güncellenen öğeler, ids kaldırılan öğelerin kimlikleridir.

typeNe zaman
uploadBir dosya yüklendi
mkdir, mkfileKlasör / dosya oluşturuldu
renameYeniden adlandırıldı
rmSilindi ya da çöpe taşındı
restoreÇöpten ya da sürüm geçmişinden geri getirildi (dosya yeniden oluştu)
revertDosya eski bir sürüme döndürüldü
duplicateÇoğaltıldı
copy, moveYapıştırıldı ya da sürükle-bırakla taşındı
archive, extractZip oluşturuldu / açıldı
optimizeToplu görsel işleminde dosyalar yazıldı

Seçici modu#

Bu prop'lardan onSelect verildiğinde bileşen seçici gibi davranır: alt çubukta "Seç" düğmesi çıkar, dosyaya çift tıklamak onu seçer. Modal bir seçici için useFilePicker daha pratiktir.

PropTipAçıklama
onSelect(entries: Entry[]) => voidSeçilen dosyalarla çağrılır
selectLabelstringDüğme metni
onCancel() => voidVerilirse "Vazgeç" düğmesi görünür
multiplebooleanBirden çok dosya seçilebilir (varsayılan false)
acceptAcceptSeçilebilecek dosyalar. Diğerleri görünür ama seçilemez.
type Accept = string | string[] | ((entry: Entry) => boolean);
// "image/*"            MIME grubu
// ".pdf,.docx"         uzantılar
// ["image/png", ".svg"]
// (e) => e.size < 2_000_000

matchesAccept(entry, accept) aynı kuralı kendi kodunuzda uygulamak için dışa aktarılır. Klasörler hiçbir zaman eşleşmez.


Dosya seçici#

useFilePicker(options)#

const picker = useFilePicker({ endpoint: "/api/files", accept: "image/*" });

<button disabled={picker.isOpen} onClick={async () => {
  const files = await picker.open();
  if (files) setCover(files[0].url);
}}>Görsel seç</button>

Döner: { open(overrides?), isOpen }.

openFilePicker(options)#

React dışında (vanilla JS, Vue, zengin metin editörleri) aynı seçici. <body> sonuna bir <dialog> ekler, kapanınca kaldırır. React ve React DOM sayfada paketlenmiş olmalıdır.

import { openFilePicker } from "@thefinder/react";
import "@thefinder/react/styles.css";

const files = await openFilePicker({ endpoint: "/api/files", accept: ".pdf" });
if (files) input.value = files[0].url;

Sunucu tarafında (document yokken) hemen null döner.

FilePickerOptions#

<TheFinder /> prop'larının hepsi (onSelect, onCancel, height, style hariç) ve şunlar:

SeçenekVarsayılanAçıklama
absoluteUrlsfalseurl alanında tam adres (https://site/uploads/a.png) döner
persistKey"thefinder-picker"Seçicinin görünüm tercihleri ana dosya yöneticisinden ayrı saklanır
popupfalsetrue (ya da { width, height, title }) seçiciyi dialog yerine elFinder gibi ayrı bir tarayıcı penceresinde açar. Bkz. Ayrı pencere.

Seçici Escape ile, arka plana tıklayarak ya da "Vazgeç" düğmesiyle kapanır. Escape önce açık menü ya da pencereleri kapatır. Ayrı pencerede "Vazgeç" düğmesiyle ya da pencerenin kapat düğmesiyle kapanır.

PickedFile#

Entry ve ek olarak url: string. Volume'de url tanımlıysa bu adres ("/uploads/a.png"), değilse API'nin dosya adresi kullanılır. pickedUrl(entry, client, absolute?) aynı adresi kendi kodunuzda üretmek için dışa aktarılır.

Ayrı pencere#

theFinder, elFinder gibi ayrı bir tarayıcı penceresinde çalışabilir. Bunun için hiçbir şey servis etmeniz gerekmez: pencere, açan sayfanın kendi kodu ve stilleriyle içine çizdiği boş, aynı kökenli bir sayfadır; bu yüzden bütün prop'lar (özel editörler, headers, callback'ler) her zamanki gibi çalışır.

// Pencerede seçici: aynı promise, aynı sonuç.
const files = await openFilePicker({ endpoint: "/api/files", accept: "image/*", popup: true });
const picker = useFilePicker({ endpoint: "/api/files", popup: { width: 960, height: 640 } });

// Dosya yöneticisinin tamamı pencerede.
const finder = openFinderWindow({ endpoint: "/api/files" }, { title: "Dosyalar" });
await finder?.closed; // finder.window, finder.close()

openFinderWindow(props, options?) <TheFinder /> prop'larını (height hariç) ve { width = 1120, height = 720, title = "theFinder" } alır. { window, close, closed } döndürür; tarayıcı popup'ı engellerse null.


Özel editörler#

editors prop'u, eşleşen dosyalar için "Birlikte aç" menüsüne bir öğe ekler. Editör, dosya yöneticisinin içinde tam ekran açılır.

import type { CustomEditor } from "@thefinder/react";

const csvViewer: CustomEditor = {
  id: "csv",
  label: "Tablo olarak aç",
  match: (entry) => entry.name.toLowerCase().endsWith(".csv"),
  render: ({ entry, store, onClose }) => <CsvTable url={store.fileUrl(entry)} title={entry.name} onClose={onClose} />,
};

<TheFinder endpoint="/api/files" editors={[csvViewer]} />
AlanAçıklama
idBenzersiz kimlik
labelMenüde görünen ad
match(entry)Editörün bu dosya için sunulup sunulmayacağı
render({ entry, store, onClose })Editör içeriği. onClose editörü kapatır.

Editör içinden kullanışlı store üyeleri:

ÜyeAçıklama
store.clientBağlı TheFinderClient: getContent, putContent, putBlob…
store.fileUrl(entry)Dosyanın adresi (volume url'i ya da API adresi)
store.updateEntry(entry)Kaydettikten sonra listedeki boyut ve tarihi günceller
store.toast(message, kind?)Bildirim; kind: "info" \| "success" \| "error"
store.fail(error)Hatayı kullanıcıya uygun dilde bildirir
store.refresh()Geçerli klasörü yeniden yükler

Kaydetme örneği:

const { entry: saved } = await store.client.putContent(entry.id, text);
store.updateEntry(saved);
store.toast("Kaydedildi", "success");

Store ve hook'lar#

Bileşen, useSyncExternalStore üzerine kurulu küçük bir store (FinderStore) kullanır. Store'a yalnızca <TheFinder /> içinde render edilen bileşenlerden (örneğin özel editörler) erişilebilir.

Dışa aktarımAçıklama
useFinder()Bağlam: { store, t, locale, editors, pickMode, multiple, … }. <TheFinder> dışında çağrılırsa hata fırlatır.
useStore(selector)Store'un bir dilimine abone olur: const cwd = useStore((s) => s.cwd). Seçici, değişmeyen durum için aynı değeri dönmelidir.
FinderStoreStore sınıfı. Durumu store.getState(), değişiklikleri store.subscribe(fn) ile izlenir.
FinderStateDurum tipi: cwd, selection, entries, volumes, uploads, clipboard, searchQuery…
FinderPrefsPrefs tipi

Store metotları (open, select, upload, paste, remove…) arayüzün kendisi için yazılmıştır. Kullanılabilirler ama 0.x boyunca imzaları değişebilir.

i18n#

Dışa aktarımAçıklama
locales{ en, tr }: hazır mesaj paketleri
Messages, MessageKeyMesaj tipi ve anahtarları
createTranslator(locale, overrides?)(key, vars?) => string. {name} gibi yer tutucuları vars ile doldurur.

Yeni bir dil eklemek için tüm anahtarları çevirip verin; eksik kalanlar İngilizce görünür:

import { locales, type Messages } from "@thefinder/react";

const de: Partial<Messages> = { upload: "Hochladen", newFolder: "Neuer Ordner" /* ... */ };
<TheFinder endpoint="/api/files" locale="de" messages={de} />

Anahtarların tam listesi için locales.en nesnesine bakın.

İkonlar#

Arayüzün elle çizilmiş SVG ikonları kendi bileşenlerinizde de kullanılabilir:

BileşenProp'lar
<FileIcon entry={…} size={48} />Dosya türüne göre renkli ikon (entry: kind, name, mime yeterli)
<FolderIcon size={48} open={false} />Klasör
<Icon name="upload" size={16} />Arayüz ikonları; diğer SVG prop'larını da alır

Tema#

Tüm stiller @layer thefinder içindedir. Katman dışında yazdığınız her kural onları ezer, !important gerekmez. Kök öğe .tf-root'tur. data-theme (light, dark, auto), data-skin (classic, macos) ve data-density öznitelikleri taşır.

.tf-root {
  --tf-accent: #0f766e;
  --tf-radius: 4px;
  --tf-font: "Inter", system-ui, sans-serif;
}
.tf-root[data-theme="dark"] {
  --tf-bg: #101418;
}
DeğişkenAçıklama
--tf-font, --tf-monoYazı tipleri
--tf-accentVurgu rengi (seçim, birincil düğme, odak)
--tf-accent-textVurgu dolgusu üzerindeki metin
--tf-accent-inkNötr zemin üzerindeki vurgu metni (bağlantılar); kontrast için ayrı tutulur
--tf-accent-soft, --tf-accent-lineVurgunun açık dolgu ve çizgi tonları (varsayılan olarak --tf-accent'ten türetilir)
--tf-bg, --tf-surface, --tf-chrome, --tf-fieldArka plan, paneller, üst/alt çubuklar, giriş alanları
--tf-line, --tf-line-strongÇizgiler
--tf-text, --tf-text-2, --tf-text-3Metin, ikincil metin, soluk metin
--tf-hover, --tf-press, --tf-sel, --tf-sel-mutedÜzerine gelme, basma, seçim, odak dışı seçim
--tf-danger, --tf-success, --tf-warnDurum renkleri
--tf-folder-back, --tf-folder-front, --tf-page, --tf-page-lineKlasör ve dosya ikonları
--tf-code-bg, --tf-code-activeKod editörü zemini ve aktif satır
--tf-toast-bg, --tf-toast-textBildirimler
--tf-backdrop, --tf-shadow-pop, --tf-shadow-dialogModal arka planı ve gölgeler
--tf-radius, --tf-radius-lgKöşe yuvarlaklığı
--tf-header-h, --tf-toolbar-h, --tf-status-h, --tf-details-wÇubuk yükseklikleri ve ayrıntılar paneli genişliği
--tk-*Kod editörü sözdizimi renkleri (--tk-kw, --tk-str, --tk-com, --tk-num, --tk-fn, --tk-type, --tk-prop…)

Sınıfların hepsi tf- öneklidir. Değişken dışındaki sınıflar iç yapıdır ve küçük sürümlerde değişebilir.

Yeniden dışa aktarımlar#

createClient, TheFinderClient, ApiError, encodeId ve Entry, VolumeInfo tipleri @thefinder/core/client'tan aynen gelir.

Bu sayfa docs/api/tr/react.md dosyasından üretildi.