İçeriğe geç
Docs

Studio Arayüzü

Tecof Studio arayüzü — kanvas, paneller, Inspector sekmeleri, düzenleme/önizleme modları, otomatik kayıt, canlı katılım ve TecofEditor prop’larının tamamı.

Son güncelleme:

Tecof Studio, sayfayı gerçek tasarım genişliğinde bir iframe kanvasında gösterir; bileşenleri sürükle-bırak ile ekler, Inspector’dan düzenler ve taslağı backend’e kaydeder. Bu sayfa arayüzün parçalarını ve TecofEditor prop’larını anlatır.

Arayüz#

BölgeNe yapar
Üst çubukGeri al / yinele, Düzenleme ↔ Önizleme modu, Masaüstü / Tablet / Mobil görünüm ve masaüstü genişliği, düzenlenen dil, kılavuz ızgarası (G), boyutlandırma (R) ve boşluk tutamaçları (B), yardım, sol/sağ paneli aç-kapa
Sol panelBileşen kütüphanesi (kategoriler, varsa önizleme görselleri), sayfa şablonları ve katman ağacı
KanvasHost CSS’inden yalıtılmış iframe; seçim, hover, sürükleme ve satır içi metin düzenleme
Sağ panel (Inspector)Seçim yokken Sayfa ve Tema sekmeleri; bir düğüm seçiliyken İçerik, Stil ve Etkileşimler
Komut paleti (⌘K)Eylemler, bileşen ekleme ve (yapılandırıldıysa) AI ile bölüm üretme

Kanvas#

  • Gerçek genişlikte kanvas. Masaüstü görünümü seçilen tasarım genişliğinde (1280 / 1440 / 1680 / 1920 px ya da özel; varsayılan 1440) çizilir ve alana sığması için ölçeklenir. Tablet 768, mobil 375 px’tir. Üst çubuktaki çip etkin genişliği ve ölçek yüzdesini gösterir.
  • Düzenleme modu. Tıklama düğümü seçer, çift tıklama satır içi metin düzenlemeyi başlatır, sürükleme düğümü taşır. Bağlantı, buton ve formların tarayıcı davranışı (gezinme, gönderme) bilerek engellenir.
  • Önizleme modu. Editör çerçeveleri gizlenir; sayfa ziyaretçinin gördüğü gibi çalışır.
  • Satır içi düzenleme. Metne çift tıklayın; Enter kaydeder, Esc vazgeçer. Bileşenler düzenlenebilir metni data-tecof-prop="propAdı" (çok dilli için ek olarak data-tecof-lang) ile işaretleyebilir; işaret yoksa metin eşleştirmesine düşülür.
  • Kanvastan panele odak. Bir öğeye tıklamak Inspector’da İçerik sekmesini açar ve ilgili alana kaydırıp kısa bir vurgu yapar.
  • Boşluk görünümü. Hover’da padding (yeşil) ve margin (amber) devtools tarzında gösterilir.
  • Dayanıklılık. Render hatası veren bir bileşen kanvası düşürmez; düğüm bazlı error boundary yalnız o düğümü izole eder ve prop düzelince kendiliğinden toparlar.
  • Dokunmatik sürükle-bırak. Tablet ve telefonda bir bileşene, palet bloğuna ya da katman satırına ~300 ms basılı tutup sürükleyin; fare ise HTML5 sürükle-bırak yolunu kullanır.

Array kartları (data-tecof-item)#

Bir bileşen type: "array" prop’unu kendi render’ında map’liyorsa (slot kullanmadan) kartları editöre tanıtabilir:

TSX
{services.map((s, i) => (
  <li key={i} data-tecof-item={`services:${i}`}>
    <h3 data-tecof-item-prop="title">{s.title}</h3>
    <p data-tecof-item-prop="description">{s.description}</p>
  </li>
))}

Kart hover çerçevesi alır, tıklama Inspector’da o satırı açar, çift tıklama satır alanını yerinde düzenler (tek geri al adımı). Satır kayıt anında silinmiş ya da taşınmışsa yazım sessizce iptal edilir; yanlış satıra yazılmaz.

Etkileşimli kontroller (registerOverlayPortal)#

Düzenleme modunda kanvas her tıklamayı editöre yönlendirir. Sekme başlığı, slider oku ya da akordeon gibi kontrollerin düzenlerken de çalışması gerekiyorsa elemanı puck.registerOverlayPortal ile işaretleyin (React ref callback’i olarak, null’a dayanıklı):

TSX
render: ({ puck, tabs }) => (
  <div>
    {tabs.map((tab, i) => (
      <button key={i} ref={puck.registerOverlayPortal} onClick={() => setActive(i)}>
        {tab.title}
      </button>
    ))}
  </div>
)

İşaretli eleman ve alt elemanları seçim, çift tıklama ve sürükleme işleyicilerinden muaf tutulur. router.push gibi JS yönlendirmeleri tarayıcı davranışı olmadığı için engellenemez; bu tür bileşenler editMode / puck.isEditing değerine bakmalıdır.

puck alanıTipAçıklama
registerOverlayPortal(el: HTMLElement | null) => () => voidElemanı düzenleme modunda canlı bırakır
isEditingbooleanDüzenleme modunda mı (editMode prop’u ile aynı)
dragRef(el: HTMLElement | null) => voidYalnız inline bileşenlerde sürükleme tutamacı
renderDropZone(opts) => ReactNodeSlot’u elle çizmek için (bkz. Slotlar)

Inspector#

  • İçerik. Bileşenin alanları. Kapsayıcı bir düğüm seçildiğinde bölümün kendi alanlarının yanında tüm alt elementlerin alanları da girintili, katlanabilir gruplar hâlinde listelenir. Bileşen fieldsGroups tanımlarsa alanlar akordeon gruplarına ayrılır. variants tanımlıysa varyant çipleri görünür.
  • Stil. Görsel stil editörü: kırılım ve durum bazlı token’lar, sayfalar arası stil uygulama. Bkz. Stil editörü.
  • Etkileşimler. Tetikleyici → eylem kuralları (click / hover → scrollTo, toggleClass, show, hide, toggle). Kurallar düğümün _interactions prop’unda saklanır ve yayında TecofRender tarafından çalıştırılır.
  • Sayfa / Tema. Seçim yokken sayfa geneli (config.root.fields) ve canlı tema düzenleyici. Bkz. Canlı tema.

Katmanlar#

Katman ağacında her satırda kilit ve gizle düğmeleri vardır (_locked / _hidden). Kilitli düğüm seçilebilir ama taşınamaz, silinemez ve alanları salt okunur olur. Gizli düğüm editörde soluk görünür; önizlemede ve yayında hiç render edilmez.

Ortak bileşenler (symbol)#

Bir bölüm ortak bileşene dönüştürülünce aynı sharedComponentId değerini taşıyan tüm örnekler tek kaynaktan beslenir: bir örnekte yapılan değişiklik diğerlerine canlı yansır. Örneğe özel alanlar _symbolOverrides ile ayrılır. Kayıtta backend örneği referansa indirger ve okurken asıl kayıttan çözer; ortak bileşen silinirken referanslar önce sayfalara gerçek içerik olarak yazılır, içerik kaybolmaz. Ortak bileşenler kanvasta mor rozetle işaretlenir.

Canlı katılım#

Aynı sayfayı aynı anda açan başka bir ekip üyesi üst çubukta görünür. Amaç eşzamanlı düzenleme değil çakışma uyarısıdır: iki kişi aynı taslağı kaydederse son kaydeden diğerinin işini ezer. Bağlantı yalnız editörde ve accessToken varken açılır; kimlik bilgisi sunucuda token’dan çözülür.

AI ile bölüm üretme#

config.ai tanımlıysa komut paletinde AI ile bölüm üret görünür. Kütüphane bileşen kataloğundan istemi kurar ve modelin yanıtını savunmacı biçimde doğrular (uydurma tip reddi, id temizliği, derinlik sınırı); LLM çağrısını host yapar:

TypeScript
export const editorConfig: StudioConfig = {
  components,
  ai: {
    complete: async ({ system, prompt }) => {
      const res = await fetch("/api/ai/section", { method: "POST", body: JSON.stringify({ system, prompt }) });
      return res.text(); // modelin ham metni: JSON bölüm yükünü içermeli
    },
  },
};

config.ai yoksa AI arayüzü hiç görünmez.

Revizyon önizlemesi#

Editör adresine ?revision=<id> eklenirse taslak yerine o revizyonun anlık görüntüsü açılır ve editör salt okunur olur (kaydetme ve içe aktarma kilitlenir; iframe’de kayıt isteği puck:saveError döner).

TecofEditor prop’ları#

PropTipVarsayılanAçıklama
pageIdstringzorunluDüzenlenecek sayfanın backend kimliği
configStudioConfigzorunluYayınla aynı bileşen kaydı
accessTokenstring?—Kayıt ve yazma isteklerinde Authorization başlığı (panelin verdiği JWT)
hostOriginstring?'*'iframe’e gömülü kullanımda izin verilen üst pencere origin’i; gelen ve giden postMessage bu origin’e kısıtlanır
autoSaveboolean?falseDüzenlemeler durulunca taslağı otomatik kaydet
autoSaveDelaynumber?2000Otomatik kayıt bekleme süresi (ms)
warnOnUnsavedChangesboolean?trueKaydedilmemiş değişiklik varken tarayıcının yerel beforeunload uyarısı
onChange(data) => void—~300 ms debounce’lu değişiklik bildirimi
onSave(data) => void—Başarılı taslak kaydından sonra
onLanguageChange(code: string) => void—Aktif düzenleme dili ilk çözüldüğünde ve her değiştiğinde
panelUrlstring?https://app.tecof.comAlanlardaki “Panelde yönet / Panelde ekle” bağlantılarının kökü (yeni sekmede açılır)
classNamestring?—Studio kök elemanına ek sınıf
overrides, plugins——Ayrılmış; şu an kullanılmıyor

onLanguageChange sözleşmesi: merchant bilgisi gelmeden boş dil ("") gönderilmez, aynı kod art arda iki kez gönderilmez ve her render’da yeni fonksiyon verseniz de ek çağrı olmaz. Tema bunu kendi i18n sağlayıcısına bağlayarak kanvas içeriğini o dilde gösterebilir; editör arayüzü Türkçe kalır. Kanvastaki bileşenler aynı dili useActiveLanguage() ile okuyabilir (Studio dışında null döner).

components/EditorClient.tsx
"use client";

import { useState } from "react";
import { NextIntlClientProvider, useMessages } from "next-intl";
import { TecofEditor } from "@tecof/theme-editor";
import { editorConfig } from "@/app/editor-config";

export default function EditorClient({ pageId, accessToken }: { pageId: string; accessToken?: string }) {
  const messages = useMessages();
  const [canvasLocale, setCanvasLocale] = useState("tr");
  return (
    <NextIntlClientProvider locale={canvasLocale} messages={messages}>
      <TecofEditor pageId={pageId} config={editorConfig} accessToken={accessToken} onLanguageChange={setCanvasLocale} />
    </NextIntlClientProvider>
  );
}

Pencereler ve onaylar#

Editördeki her pencere (ayarlar, yardım, bölüm ekleme, seçiciler, onaylar) aynı kabuğu kullanır: StudioDrawer (Radix Dialog, modal={false}; içinden açılan renk/ikon/CMS popover’ları tıklanabilir kalır). Host eklentileri aynı kabuğu ve onay kuyruğunu kullanabilir:

TSX
import { StudioDrawer, studioDialog } from "@tecof/theme-editor";

const ok = await studioDialog.confirm({
  title: "Ortak bileşeni sil",
  description: "Bu bileşeni kullanan tüm sayfalar etkilenir.",
  confirmLabel: "Sil",
  danger: true,
});
await studioDialog.alert({ title: "İçe aktarma tamamlandı" });
StudioDrawer prop’uAçıklama
open / onOpenChangeAçıklık durumu
titleBaşlık (zorunlu; erişilebilirlik için de kullanılır)
description, iconAlt başlık ve rozet ikonu
tonedefault · primary · danger
sizesm 400 · md 560 · lg 820 · xl 1180 px (varsayılan md)
busyİş sürerken kapatma yollarını kilitler
footer, headerActions, hideClose, elevated, inertAlt eylem satırı, baş satırı kontrolleri, X’i gizle, başka drawer’ın üstünde aç, etkileşimi kapat

Bir drawer açıkken Studio’nun genel kısayolları (Delete, ⌘Z, G / R / B …) çalışmaz; denetim isStudioDrawerOpen() ile yapılır.

Performans#

Monaco (kod), TipTap (zengin metin) ve FilePond/Doka (medya) gibi ağır alanlar ayrı chunk’lara bölünüp ihtiyaç anında yüklenir. Bileşen kütüphanesindeki önizleme görselleri tembel yüklenir.