
Web Bileşenleri (Web Components) ile Çerçeve Bağımsız Tasarım
Diyarbakır Yazılım
16.08.2026
#Yazılım#Teknoloji#Topluluk
Bir design system yalnızca bugünkü uygulamayı değil, birkaç yıl sonra ortaya çıkacak yeni ürünleri ve yeni teknoloji tercihlerini de taşıyabilmelidir. React ile başlayan bir organizasyon zaman içinde Vue, Angular, Svelte, server-side templating veya yalnızca HTML kullanan farklı uygulamalar geliştirebilir. Web Components tam bu noktada, kullanıcı arayüzü bileşenlerini belirli bir framework yerine doğrudan web platformunun standartları üzerine kurma seçeneği sunar. Bununla birlikte çerçeve bağımsız tasarım, tek bir component yazıp hiçbir uyarlama yapmadan bütün teknoloji yığınlarında kusursuz çalışacağı anlamına gelmez. Bu rehberde Custom Elements, Shadow DOM, slot yapıları, framework adaptörleri, SSR, accessibility, paketleme, test ve design system yönetişimini gerçek proje kararları üzerinden ele alacağız.
Web Components Nedir?
Web Components, geliştiricilerin tarayıcı tarafından tanınan özel HTML elementleri oluşturmasına imkân veren bir grup web standardıdır. Bu yaklaşımda bir kullanıcı arayüzü parçası yalnızca framework içindeki bir component olarak değil, doğrudan HTML elementi gibi kullanılabilir. Örneğin bir tasarım sistemi kendi <ds-button> veya <ds-dialog> elementlerini tanımlayabilir. Bu elementler JavaScript properties, HTML attributes, events, slots ve CSS tabanlı tema sözleşmeleri üzerinden dış dünyayla iletişim kurabilir. En önemli avantaj, component contract'ının belirli bir frontend framework'ünün yaşam döngüsüne doğrudan bağımlı olmamasıdır.
Web Components Bir Framework müdür?
Web Components bir JavaScript framework'ü değildir. React veya Vue gibi uygulama state'i, routing, data fetching ve sayfa composition modeli sunmaz. Bunun yerine browser platformuna ait düşük seviyeli component standartları sağlar. Bu standartların üzerinde vanilla JavaScript ile çalışmak veya Lit gibi yardımcı kütüphanelerden yararlanmak mümkündür. Dolayısıyla Web Components uygulama framework'ünün yerine geçmekten çok, framework'ler arasında kullanılabilecek ortak bir UI component katmanı oluşturur.
Web Components Hangi Web Standartlarından Oluşur?
Web Components denildiğinde genellikle Custom Elements, Shadow DOM, HTML Templates ve Slots birlikte değerlendirilir. Bu standartların her biri farklı bir sorumluluğu çözer. Custom Elements özel HTML elementleri tanımlarken Shadow DOM component'ın iç DOM ve stil sınırlarını oluşturabilir. Template ve slot mekanizmaları ise tekrar kullanılabilir markup ile içerik composition ihtiyacını destekler. Bir design system bütün bu araçları kullanmak zorunda değildir ve ihtiyaçlara göre yalnızca gerekli olan parçalar seçilebilir.
Custom Elements
Custom Elements tarayıcıya yeni HTML elementleri tanıtmayı sağlar. Geliştirici belirli bir isimle JavaScript class'ını kaydeder ve bu element daha sonra normal HTML içinde kullanılabilir. Element kendi lifecycle callback'lerine, properties ve event davranışlarına sahip olabilir. Custom element isimlerinin en az bir tire içermesi gerekir ve bu kural gelecekte native HTML elementleriyle isim çakışmasını azaltır. Design system açısından Custom Elements framework bağımsız public API'nin temelini oluşturur.
Shadow DOM
Shadow DOM component'ın iç DOM ağacını dış document yapısından belirli ölçüde ayırır. Component içindeki CSS kuralları varsayılan olarak dışarı taşmaz ve dış sayfadaki selector'lar da içerideki elementleri doğrudan hedefleyemez. Bu izolasyon özellikle birçok uygulamada kullanılan design system component'larında style çakışmalarını azaltır. Buna rağmen theme, accessibility, SSR ve üçüncü taraf entegrasyonları açısından ek tasarım kararları gerektirir. Bu nedenle Shadow DOM güçlü bir araçtır fakat her component için zorunlu tercih değildir.
HTML Templates
<template> elementi başlangıçta render edilmeyen tekrar kullanılabilir HTML parçaları tanımlamaya imkân verir. Template içeriği JavaScript üzerinden kopyalanarak component DOM'una eklenebilir. Bu yöntem vanilla Web Components geliştirirken markup yapısını string birleştirmelerine göre daha düzenli tutabilir. Template içerisinde stil ve slot tanımları da bulunabilir. Lit gibi araçlar declarative template yaklaşımını farklı bir API üzerinden sağladığı için her projede doğrudan HTML Template kullanılması gerekmez.
Slots
Slots consumer tarafından verilen light DOM içeriğinin component içerisindeki belirli noktalara yerleştirilmesini sağlar. Bu model React children veya Vue slots yaklaşımına benzer bir composition yeteneği sunar. Default slot tek bir genel içerik alanı sağlarken named slot farklı bölgelerin ayrı ayrı doldurulmasına imkân verir. Slot kullanımı component API'sini çok sayıda content prop ile doldurmak yerine HTML tabanlı composition'a yaklaştırabilir. Ancak çok fazla named slot eklemek de component contract'ını zorlaştırabileceği için sınırlı ve anlamlı slot yüzeyi tercih edilmelidir.
Framework Component ile Web Component Arasındaki Fark
Framework component çoğunlukla ilgili framework'ün rendering, state ve lifecycle sisteminin içinde çalışır. Web Component ise browser'ın Custom Elements lifecycle modelini ve standart DOM API'lerini kullanır. React component doğrudan Vue template içinde kullanılamazken custom element çoğu framework tarafından normal bir DOM elementi olarak tüketilebilir. Buna rağmen event binding, object property aktarımı ve form entegrasyonu gibi konularda framework'e özel ayrıntılar ortaya çıkabilir. Bu yüzden Web Components framework bağımsızlığı sağlar fakat consumer entegrasyonunun tamamen sıfır maliyetli olacağını garanti etmez.
Browser-Native Component Ne Anlama Gelir?
Browser-native component ifadesi component modelinin tarayıcının tanıdığı standart API'ler üzerine kurulmasını anlatır. Component çalışmak için mutlaka React runtime veya başka bir application framework istemez. Kullanıcı custom element script'ini yükledikten sonra elementi doğrudan HTML içerisinde kullanabilir. Bu durum özellikle uzun ömürlü design system'lerde teknoloji yaşam döngüsünü component sözleşmesinden ayırmaya yardımcı olur. Bununla birlikte component geliştirme deneyimini kolaylaştırmak için build araçları veya küçük runtime kütüphaneleri yine kullanılabilir.
Çerçeve Bağımsız (Framework-Agnostic) Tasarım Nedir?
Framework-agnostic tasarım, component contract'ını tek bir uygulama framework'ünün özel kavramlarından mümkün olduğunca bağımsız tutmayı hedefler. Kullanıcı arayüzü API'si HTML attributes, JavaScript properties, DOM events, slots ve CSS değişkenleri gibi web platformu araçlarıyla ifade edilir. Böylece design system aynı anda farklı frontend yığınlarında kullanılabilir. Amaç framework kullanımını ortadan kaldırmak değildir ve uygulamalar kendi state, routing veya data fetching araçlarını kullanmaya devam edebilir. Asıl kazanç, design system'ın uygulama framework'ünün değişim hızından daha bağımsız bir yaşam döngüsüne sahip olmasıdır.
Framework Lock-In Nedir?
Framework lock-in, yeniden kullanılabilir kodun belirli bir framework API'sine yoğun biçimde bağlanması nedeniyle başka teknolojiye geçiş maliyetinin yükselmesidir. Design system React hooks, React Context veya framework-specific render pattern'lerine doğrudan bağımlıysa başka consumer'lar aynı component'ı doğal biçimde kullanamaz. Bunun sonucu genellikle ikinci bir component library oluşturmak veya kapsamlı wrapper katmanları geliştirmek olur. Lock-in her zaman kötü değildir çünkü tek framework kullanan organizasyonda daha hızlı geliştirme sağlayabilir. Önemli olan bağımlılığın bilinçli seçilmesi ve uzun vadeli ürün çeşitliliğine uygun olup olmadığının değerlendirilmesidir.
React'e Bağımlı Bir Component Library'nin Maliyeti
React'e özel component library tek React uygulamasında oldukça verimli olabilir. Sorun organizasyonda Vue, Angular veya server-rendered farklı ürünler ortaya çıktığında başlar. Aynı Button, Dialog ve FormField davranışlarını diğer teknoloji yığınları için yeniden geliştirmek gerekebilir. Accessibility düzeltmeleri ve design token güncellemeleri birden fazla implementation üzerinde sürdürülür. Framework bağımsız component tabanı bu tekrar maliyetini azaltabilir fakat bunun karşılığında Web Components API tasarımına ve entegrasyon testlerine yatırım gerekir.
Framework Değiştiğinde Design System'e Ne Olur?
Design system framework'e doğrudan bağlıysa framework migration UI katmanını da etkiler. Yeni uygulama bütün component'ları yeniden yazmak veya bir bridge kullanmak zorunda kalabilir. Web platformu tabanlı component contract'ında ise application framework değişirken temel custom element'lar aynı kalabilir. Yalnızca framework adapter veya integration helper güncellenebilir. Bu ayrım büyük organizasyonlarda framework migration maliyetini belirgin biçimde azaltabilecek bir mimari avantaj sağlar.
“Write Once, Use Anywhere” Gerçekte Ne Kadar Mümkün?
Tek kaynak kodla birçok framework'te aynı component'ı kullanmak gerçekçi bir hedeftir fakat her entegrasyon tamamen aynı davranmaz. Primitive string ve boolean attributes genellikle kolay çalışır. Object properties, custom events, forms ve SSR gibi alanlarda framework adaptasyonu gerekebilir. Ayrıca framework'lerin rendering ve hydration davranışları custom element lifecycle'ıyla farklı şekillerde etkileşebilir. Bu nedenle daha doğru hedef, tek component implementation'ı ve gerektiğinde küçük consumer adaptörleri kullanmaktır.
Web Components Neden Design System İçin Uygundur?
Design system'ın ömrü çoğu zaman onu kullanan tek bir uygulamadan daha uzundur. Bu nedenle component contract'ını web standartlarına dayandırmak uzun vadeli teknik esneklik sağlayabilir. Aynı primitive component farklı framework ve legacy uygulamalarda kullanılabilir. Shadow DOM veya kontrollü CSS API'leri style izolasyonu sağlar. Böyle bir model özellikle birçok ürün ve farklı frontend ekibi bulunan organizasyonlarda güçlü değer üretir.
Web Standartlarına Dayalı Olması
Web Components browser standartları üzerine kurulur. Component API'si DOM, HTML ve CSS kavramlarıyla ifade edilebilir. Bu durum framework-specific API değişimlerinden etkilenme alanını küçültür. Web platformu yine gelişir fakat backward compatibility yaklaşımı güçlüdür. Design system'ın temel sözleşmesini uzun vadeli standartlara bağlamak maintenance planlamasını kolaylaştırabilir.
Framework'ten Bağımsız Kullanım
Custom element normal HTML tag'i gibi kullanılabilir. React, Vue, Angular veya vanilla HTML consumer aynı temel element ismini görebilir. Framework'ler event veya property binding için farklı syntax kullansa da underlying component aynı kalır. Bu durum aynı component'ın birden fazla implementasyonunu sürdürme ihtiyacını azaltır. En yüksek fayda farklı teknoloji kullanan ürün sayısı arttıkça ortaya çıkar.
CSS ve DOM Encapsulation
Shadow DOM component'ın internal CSS ve DOM yapısını dış uygulamadan ayırabilir. Böylece consumer'daki global selector'lar component'ın görünümünü beklenmedik biçimde değiştirmez. Component library de kendi style kurallarını sayfanın geri kalanına sızdırmaz. Public CSS Custom Properties veya CSS Parts kontrollü tema alanı açabilir. Bu model design system'ın farklı uygulamalarda daha öngörülebilir görünmesini sağlar.
Uzun Vadeli Bakım Kolaylığı
Tek implementation bakım maliyetini azaltabilir. Accessibility düzeltmesi bütün consumer'lara yeni package sürümüyle ulaşabilir. Component API framework migration nedeniyle sürekli yeniden tasarlanmak zorunda kalmaz. Yine de browser standardına dayanmak bakım ihtiyacını ortadan kaldırmaz. Versioning, testing, deprecation ve documentation süreçleri aynı şekilde gereklidir.
Farklı Takımlarda Aynı UI API'sini Kullanmak
Bir ekip React, başka bir ekip Angular kullanıyor olabilir. Web Component tabanlı design system iki ekibe de aynı <ds-button> veya <ds-dialog> contract'ını sunabilir. Bu durum dokümantasyon ve accessibility davranışının ortaklaşmasını kolaylaştırır. Takımlar framework'e özel application logic geliştirmeye devam eder. Ortak UI dili organizasyon genelinde daha tutarlı hale gelir.
Legacy Uygulamalara Entegrasyon
Legacy uygulamalar modern framework'e geçmeden yeni design system component'larını kullanabilir. Custom element script'i sayfaya eklendikten sonra component doğrudan markup içinde yer alabilir. Bu özellik büyük rewrite yerine aşamalı modernizasyon için faydalıdır. Yeni ve eski ekranlar aynı tasarım token'larını kullanmaya başlayabilir. Böylece design system migration, application rewrite projesine bağlı kalmadan ilerleyebilir.
Web Components Gerçekten Tamamen Framework-Agnostic mi?
Web Components component katmanında güçlü framework bağımsızlığı sunar fakat bütün uygulama mimarisini framework bağımsız hale getirmez. Routing, state management, data fetching ve server rendering çoğu zaman uygulama katmanının sorumluluğunda kalır. Custom element farklı framework'lerde çalışsa bile her framework property ve event integration'ını farklı syntax ile ifade edebilir. Bu ayrım doğru yapılmadığında design system application framework'ünün sorumluluklarını taşımaya başlayabilir. Sağlıklı yaklaşım framework bağımsızlığı hedefini component boundary ile sınırlı ve açık biçimde tanımlamaktır.
Component Katmanı ile Application Katmanını Ayırmak
Component katmanı Button, Tabs, Dialog ve FormField gibi tekrar kullanılabilir UI davranışlarını sağlayabilir. Application katmanı ise kullanıcı akışı, routing, authorization ve data orchestration gibi görevleri yönetir. Design system'ın bu iki seviyeyi karıştırması framework bağımsızlığını azaltır. Component mümkün olduğunca dışarıdan verilen data ve events üzerinden çalışmalıdır. Application business context'i component'ın public API'sine yalnızca gerekli semantic bilgilerle yansıtılmalıdır.
Server-Side Templating Problemi
Server-side HTML üretildiğinde custom element'ın JavaScript'i yüklenmeden önce sayfada yalnızca element markup'ı bulunabilir. Shadow DOM içeriği client tarafında oluşturuluyorsa ilk render sırasında farklı görünüm oluşabilir. Declarative Shadow DOM bu alanda önemli bir araçtır fakat bütün rendering altyapılarının entegrasyonu aynı değildir. Component library SSR strategy'sini açık biçimde tanımlamalıdır. Consumer framework'ün server rendering davranışı ayrıca integration testleriyle doğrulanmalıdır.
Data Fetching Kimin Sorumluluğunda?
Design system component'ının doğrudan backend endpoint çağrısı yapması genellikle iyi bir sınır değildir. Data fetching uygulamanın veya domain katmanının sorumluluğunda kalabilir. Component gerekli veriyi property üzerinden alır ve kullanıcı interaction'ını event olarak bildirir. Böylece API ve authentication bağımlılığı design system'a taşınmaz. Bazı domain-level application component'larda farklı karar verilebilir fakat primitive design system katmanı mümkün olduğunca data transport'tan bağımsız tutulmalıdır.
Global State Nerede Yönetilmeli?
Global state'in Web Component library içinde saklanması consumer uygulamalar için gizli bağımlılık oluşturabilir. Uygulama zaten kendi state management çözümüne sahip olabilir. Design system primitive'leri çoğunlukla controlled veya local internal state ile çalışmalıdır. Global theme gibi sınırlı bilgiler CSS Custom Properties üzerinden doğal biçimde aktarılabilir. Business state'in framework veya application katmanında tutulması daha temiz bir ayrım sağlar.
Components Arası Orchestration
Birden fazla component'ın birlikte yürüttüğü business akış application seviyesinde koordine edilmelidir. Örneğin checkout dialog açılması, payment state ve redirect davranışı design system Dialog component'ının görevi değildir. Dialog açılma ve kapanma contract'ını sağlar. Consumer event'leri dinleyerek sonraki business kararını verir. Bu ayrım component'ın farklı uygulamalarda tekrar kullanılmasını kolaylaştırır.
Framework Bağımsızlığının Gerçek Sınırları
Framework bağımsızlığı public component API seviyesinde güçlü biçimde sağlanabilir. Buna karşılık rendering, hydration, form integration ve custom event binding consumer framework'üne göre değişebilir. Framework adapter package'ları bu farklılıkları gizlemek için kullanılabilir. Bu adapter'lar temel component implementation'ını çoğaltmamalıdır. Başarı ölçütü sıfır framework kodu değil, framework bağımlılığının küçük ve değiştirilebilir bir sınırda tutulmasıdır.
Web Component Mimarisi Nasıl Tasarlanmalı?
Web Component mimarisinde bütün UI parçalarını aynı seviyede ele almak yerine primitive, composite ve application component ayrımı yapılabilir. Primitive component'lar düşük seviyeli interaction ve visual davranışı sağlar. Composite component'lar primitive'leri belirli bir reusable pattern içinde birleştirir. Application component'lar ise business bağlamına yaklaşır ve çoğu zaman design system çekirdeğinin dışında tutulması daha sağlıklıdır. Bu katmanlama framework bağımsızlığının nerede gerekli olduğunu açık hale getirir.
Primitive Component
Primitive component düşük seviyeli tekrar kullanılabilir UI davranışını temsil eder. Domain bilgisi taşımaz ve mümkün olduğunca native HTML semantic'lerini kullanır. Public API küçük tutulur. Accessibility davranışı primitive seviyesinde çözüldüğünde bütün consumer'lara aktarılır. Button, Input ve Badge bu kategori için uygun örneklerdir.
Button
Button custom element oluşturulurken mümkün olduğunca native button davranışından yararlanılmalıdır. Component variant ve size gibi design system özellikleri ekleyebilir. Disabled, focus ve keyboard davranışı doğru çalışmalıdır. Click event'ini gereksiz custom event ile yeniden üretmek yerine native davranış korunabilir. Böylece component daha öngörülebilir ve erişilebilir kalır.
Input
Input bileşeni native form davranışları nedeniyle Button'a göre daha fazla dikkat gerektirir. Label ilişkisi, validation ve form submission doğru çalışmalıdır. Form-Associated Custom Elements ve ElementInternals bu ihtiyaçların bir kısmını çözebilir. Input component business validation rule taşımamalıdır. Tasarım sistemi stil, accessibility ve temel interaction contract'ına odaklanmalıdır.
Badge
Badge çoğunlukla görsel durum göstergesi olarak kullanılabilir. Component semantic anlamı kendisi tahmin etmemelidir. Variant'lar success, warning veya neutral gibi sınırlı seçenekler sunabilir. Consumer içeriği slot üzerinden sağlayabilir. Çok basit bir span yeterliyse custom element oluşturmanın gerçekten değer üretip üretmediği ayrıca sorgulanmalıdır.
Composite Component
Composite component birden fazla primitive veya interaction davranışını ortak pattern içinde birleştirir. Accordion, Tabs ve Dialog bu seviyede değerlendirilebilir. Accessibility davranışı daha kapsamlı hale gelir. Component iç state taşıyabilir fakat business state'e bağlanmamalıdır. Public API slots, properties ve events üzerinden consumer'a açık bir contract sunmalıdır.
Accordion
Accordion başlık ile içerik alanı arasında expand ve collapse davranışı sağlar. Keyboard interaction ve aria-expanded gibi semantic bilgiler doğru yönetilmelidir. İçerik slot üzerinden verilebilir. Tekli veya çoklu açılma davranışı public property ile kontrol edilebilir. Component domain içeriğini bilmeden reusable interaction sunmalıdır.
Tabs
Tabs component aktif panel, keyboard navigation ve semantic role davranışını yönetir. Consumer tab başlığı ve content'i slot veya child custom element yapısıyla sağlayabilir. Arrow key hareketi accessibility standardına göre tasarlanmalıdır. Controlled API gerekirse selected value property üzerinden sunulabilir. Component page routing veya business navigation kararını kendi içinde vermemelidir.
Dialog
Dialog focus management ve modal interaction açısından önemli bir reusable component'tır. Native <dialog> elementi uygun olduğunda temel olarak kullanılabilir. Design system bunun üzerine token ve contract ekleyebilir. Açılma ve kapanma olayları consumer'a bildirilebilir. Business action butonlarının içeriği slot üzerinden sağlanarak component'ın genel kalması korunabilir.
Application Component
Application component belirli bir ürün veya business domain'e daha yakın çalışır. Örneğin CheckoutSummary veya UserPermissionEditor application component olarak değerlendirilebilir. Bu component'ların framework bağımsız olması her zaman ekonomik değildir. Birden fazla uygulamada gerçek reuse ihtiyacı yoksa ilgili application framework'ü içinde geliştirmek daha basit olabilir. Design system çekirdeği ile application component library ayrı release ve ownership modeline sahip olabilir.
Business Logic Design System İçinde Olmalı mı?
Genel olarak business logic design system çekirdeğinin içinde bulunmamalıdır. Tasarım sistemi interaction, styling, accessibility ve reusable UI contract'ına odaklanmalıdır. Sipariş indirimi, kullanıcı yetkisi veya ödeme kuralları gibi davranışlar application veya domain katmanında kalmalıdır. Böylece design system farklı business bağlamlarında kullanılabilir. İstisna olarak bütün ürünlerde gerçekten ortak olan workflow pattern'leri ayrı application component package'ında ele alınabilir.
“Dumb Component” Yaklaşımı
Dumb component terimi component'ın business kararlar yerine aldığı input'u render etmesi ve kullanıcı interaction'ını dışarı bildirmesi yaklaşımını anlatır. Bu model framework bağımsız component'larda güçlü sonuç verir. Component backend'e gitmez ve global application store'a doğrudan erişmez. Properties ve slots üzerinden data alır, events üzerinden intent bildirir. Böylece application orchestration component'ın dışında kalır.
Custom Elements Nasıl Çalışır?
Custom Elements API tarayıcıya özel HTML elementleri tanımlamak için kullanılır. Geliştirici genellikle HTMLElement sınıfından türeyen bir class oluşturur. Daha sonra bu class belirli bir custom element ismiyle browser registry'ye kaydedilir. Element DOM'a eklendiğinde lifecycle callback'leri üzerinden initialization yapılabilir. Component'ın public API'si attributes, properties ve events üzerinden tasarlanabilir.
HTMLElement Sınıfını Genişletmek
Autonomous custom element oluşturmanın yaygın yolu HTMLElement sınıfını extend etmektir. Class içinde constructor ve lifecycle callback'leri tanımlanabilir. DOM kurulumu çoğu zaman constructor yerine connectedCallback veya kontrollü initialization fonksiyonlarında ele alınır. Shadow root gerekiyorsa class içinde attachShadow çağrısı yapılabilir. Element davranışı browser'ın standart DOM lifecycle'ıyla uyumlu kalır.
customElements.define()
customElements.define() element ismiyle constructor class'ını browser registry'ye kaydeder. Aynı isim ikinci kez tanımlanamaz. Library birden fazla kez yüklenebileceği için registration strategy dikkatli tasarlanmalıdır. Bazı kütüphaneler element daha önce kayıtlı mı diye kontrol eder. Package bazlı import ve side-effect registration yaklaşımı distribution tasarımının parçası olmalıdır.
Custom Element İsimlendirme Kuralları
Custom element isimlerinde en az bir tire bulunmalıdır. Bu kural browser'ın custom element ile gelecekte eklenebilecek native HTML elementlerini ayırmasına yardımcı olur. Design system için kısa fakat ayırt edici prefix kullanmak yaygın yaklaşımdır. İsimler semantic ve kararlı olmalıdır. Package veya marka değişikliği nedeniyle element ismini değiştirmek büyük breaking change oluşturabileceği için başlangıçta dikkatli karar verilmelidir.
Prefix Kullanımı
Prefix organizasyon veya design system kimliğini element isminde görünür hale getirir. <dy-button> gibi bir yapı isim çakışmasını azaltabilir. Çok uzun prefix markup okunabilirliğini düşürebilir. Prefix gelecekte birden fazla ürün tarafından kullanılabilecek kadar genel seçilmelidir. Element isimleri public API olduğu için değiştirilmesi kolay değildir.
İsim Çakışmalarını Önleme
Browser custom element registry sayfa seviyesinde global çalışır. İki library aynı custom element ismini tanımlamaya çalışırsa problem oluşur. Ayırt edici prefix kullanımı bu riski azaltır. Micro-frontend sistemlerinde farklı sürümlerin aynı element ismini tanımlaması ayrıca planlanmalıdır. Library loading strategy ve version governance bu nedenle önemlidir.
Lifecycle Callback'leri
Custom element lifecycle callback'leri element'ın DOM yaşam döngüsündeki belirli aşamalarda çalışır. Initialization, cleanup ve attribute değişimlerini yönetmek için kullanılabilir. Callback'lerin idempotent olması önemlidir çünkü element DOM'a birden fazla kez bağlanabilir. Event listener veya observer ekleniyorsa disconnect sırasında temizlenmelidir. Lifecycle kodunun büyümesi durumunda helper veya reactive library kullanımı değerlendirilebilir.
constructor()
Constructor element instance oluşturulduğunda çağrılır. Temel property initialization ve shadow root oluşturma burada yapılabilir. DOM tree ile ilgili bazı işlemleri connectedCallback aşamasına bırakmak daha güvenlidir. Constructor içinde ağır iş yapmak element creation maliyetini yükseltir. Component'ın henüz document'a bağlı olmadığı unutulmamalıdır.
connectedCallback()
connectedCallback element document'a bağlandığında çağrılır. Render, listener registration veya observer başlatma için uygun yerdir. Callback element her yeniden bağlandığında tekrar çalışabilir. Bu nedenle duplicate listener oluşmasını engellemek gerekir. Cleanup işlemleri disconnectedCallback ile eşleştirilmelidir.
disconnectedCallback()
disconnectedCallback element DOM'dan ayrıldığında çağrılır. Global event listener, timer ve observer temizliği burada yapılmalıdır. Cleanup yapılmazsa memory leak veya görünmez component'ın çalışmaya devam etmesi gibi sorunlar oluşabilir. Reusable design system component'ı farklı framework lifecycle'larında sık mount ve unmount edilebilir. Bu nedenle cleanup davranışı framework entegrasyon testlerinin parçası olmalıdır.
attributeChangedCallback()
attributeChangedCallback gözlemlenen bir attribute değiştiğinde çağrılır. Bunun için static observedAttributes listesi tanımlanır. String attribute değeri gerekli tipe dönüştürülmelidir. Her property'yi attribute üzerinden taşımaya çalışmak doğru değildir. Karmaşık object ve array verileri JavaScript properties üzerinden yönetmek daha uygundur.
adoptedCallback()
adoptedCallback element başka bir document'a taşındığında çağrılabilir. Günlük uygulamalarda diğer lifecycle callback'lerine göre daha az kullanılır. iframe veya farklı document context'lerinde çalışan özel senaryolar için önemli olabilir. Design system implementasyonu kullanmıyorsa callback eklemeye gerek yoktur. Public component API gereksiz lifecycle davranışlarıyla ağırlaştırılmamalıdır.
Component API'si Nasıl Tasarlanmalı?
Web Component API tasarımı framework bağımsızlığının en kritik bölümüdür. Consumer'ın component ile nasıl veri paylaşacağı attributes ve properties üzerinden açıkça belirlenmelidir. Events kullanıcı interaction'ını dışarı bildirirken slots içerik composition'ı sağlar. Primitive değerler ile object ve array gibi karmaşık değerler aynı mekanizma üzerinden zorla taşınmamalıdır. Küçük ve öngörülebilir public API uzun vadeli backward compatibility yönetimini kolaylaştırır.
Attributes
Attributes HTML markup içinde string tabanlı configuration sağlar. Variant, size veya disabled gibi basit değerler için uygundur. Server-rendered HTML içinde kolayca ifade edilebilir. Attribute değerleri JavaScript property tipleriyle otomatik olarak aynı değildir. Component parse ve reflection davranışını açık biçimde tanımlamalıdır.
JavaScript Properties
JavaScript properties object, array ve callback benzeri değerleri doğrudan element instance'ına aktarmayı sağlar. DOM string serialization sınırlamasına bağlı değildir. React veya Vue consumer gerektiğinde element property'sine değer atayabilir. Property change'in render'ı nasıl tetikleyeceği component implementation tarafından yönetilir. Reactive helper kütüphaneleri bu süreci kolaylaştırabilir.
Attribute ve Property Arasındaki Fark
Attribute HTML markup'ın parçasıdır ve temel olarak string değer taşır. Property ise JavaScript object üzerindeki gerçek runtime değerdir. Bazı property'ler attribute'a reflect edilebilir fakat bütün değerler için bu gerekli değildir. Object'i JSON stringify ederek attribute üzerinden taşımak çoğu durumda gereksiz maliyet ve API sorunu oluşturur. Component dokümantasyonu hangi alanın attribute, hangisinin property olduğunu açıkça göstermelidir.
Primitive Veri Aktarımı
String, number ve boolean gibi basit değerler attribute veya property üzerinden taşınabilir. Server rendering ihtiyacı varsa attribute güçlü avantaj sağlar. Number değeri string attribute'tan parse edilmelidir. Boolean attribute HTML semantic'lerine uygun tasarlanmalıdır. Varsayılan değerler ve invalid input davranışı dokümante edilmelidir.
Object ve Array Aktarımı
Object ve array verileri JavaScript property üzerinden geçirmek daha doğal bir contract oluşturur. JSON attribute kullanımı escaping, serialization ve büyük payload sorunları yaratabilir. Consumer element instance'ına doğrudan object atayabilir. Reactive update gerekiyorsa property setter veya library mekanizması render'ı tetikleyebilir. Framework wrapper bu property binding detayını daha kolay hale getirebilir.
Boolean Attribute Tasarımı
HTML'de boolean attribute varlığı true anlamına gelir. disabled="false" yazılması attribute var olduğu için beklenmeyen davranış oluşturabilir. Native semantic'lere yakın API seçmek consumer hatalarını azaltır. Eğer üç durum gerekiyorsa boolean attribute yerine enum benzeri string property tercih edilebilir. Design system documentation gerçek markup örnekleri göstermelidir.
Public API'yi Küçük Tutmak
Her public property gelecekte desteklenmesi gereken contract haline gelir. Çok fazla configuration component'ın implementation detaylarını consumer'a açabilir. Composition ile çözülebilecek alanlar slots üzerinden verilebilir. Internal styling için sınırsız CSS variable sunmak da benzer maintenance yükü oluşturur. Küçük API component'ın anlaşılmasını, test edilmesini ve versioning yönetimini kolaylaştırır.
Web Components'te Event Tasarımı
Events Web Component ile consumer uygulama arasındaki ana iletişim yollarından biridir. Component kullanıcı intent'ini veya önemli state değişikliğini DOM event olarak yayınlayabilir. CustomEvent detail alanı ek veri taşımayı sağlar. Event'ın bubbles ve composed seçenekleri özellikle Shadow DOM sınırlarında önemlidir. Event isimleri framework'lerde nasıl dinleneceği düşünülerek kararlı ve semantic biçimde tasarlanmalıdır.
CustomEvent Kullanımı
CustomEvent component'a özgü event oluşturmayı sağlar. Event dispatchEvent() ile element üzerinden yayınlanabilir. Native event zaten ihtiyacı karşılıyorsa yeni custom event üretmek gerekli değildir. Örneğin Button native click davranışını koruyabilir. Custom event daha çok selected-change veya value-change gibi component'a özgü anlam taşıyan durumlarda kullanılabilir.
Event İsimlendirme
Event isimleri davranışı açık biçimde anlatmalıdır. Consumer event'ın ne zaman yayınlandığını isimden anlayabilmelidir. Framework ve HTML attribute syntax ile uyum düşünülmelidir. Organization genelinde naming convention belirlemek design system documentation'ını kolaylaştırır. Event isimlerini sonradan değiştirmek consumer kodunu kıracağı için public API kararı olarak ele alınmalıdır.
detail ile Veri Aktarma
CustomEvent detail property event ile ek data taşır. Selection component seçilen değeri burada sağlayabilir. Detail object mümkün olduğunca küçük ve stable olmalıdır. Internal state'in tamamını dışarı açmak gereksiz coupling oluşturur. Public event payload type TypeScript declaration içinde dokümante edilebilir.
bubbles Ne İşe Yarar?
bubbles true olduğunda event DOM ağacında üst elementlere doğru ilerler. Bu davranış event delegation ve parent-level listener için faydalıdır. Her event'ın bubble etmesi gerekmez. Consumer'ın component üzerinde doğrudan dinlemesi yeterliyse daha sınırlı behavior seçilebilir. Event contract documentation bubbles davranışını açıkça belirtmelidir.
composed Neden Önemlidir?
composed event'ın Shadow DOM boundary dışına çıkıp çıkamayacağını belirler. Shadow root içinde oluşturulan custom event consumer uygulamaya ulaşacaksa çoğu zaman composed ayarının değerlendirilmesi gerekir. Yanlış değer consumer'ın event'i hiç görememesine neden olabilir. Her internal event dışarı çıkmamalıdır. Public ve internal event ayrımı component architecture'ın parçasıdır.
Shadow DOM Boundary'den Event Geçirmek
Public interaction event'ı Shadow DOM içinde oluştuğunda consumer'ın custom element üzerinde dinleyebilmesi beklenebilir. Event bubbles ve composed ayarları bu davranışı belirler. Retargeting nedeniyle event target bilgisi consumer tarafında farklı görünebilir. Public payload için detail kullanmak internal DOM yapısına bağımlılığı azaltır. Böylece component markup değişse bile event contract korunabilir.
Framework'lerin Custom Event'leri Dinlemesi
Modern framework'lerin çoğu custom element event'lerini destekler fakat syntax ve type integration farklı olabilir. Vue ve Angular template event binding üzerinden doğal bir deneyim sunabilir. React tarafında sürüm ve kullanım modeline göre wrapper veya ref yaklaşımı değerlendirilebilir. Framework adapter bu farkları consumer'dan gizleyebilir. Design system en az desteklediği framework'ler için integration testleri çalıştırmalıdır.
Shadow DOM Nedir?
Shadow DOM bir element içinde kapsüllenmiş ayrı DOM ağacı oluşturur. Bu yapı component'ın internal markup ve styling detaylarını consumer'dan ayırabilir. Design system açısından en büyük faydası global CSS çakışmalarını azaltmasıdır. Bununla birlikte accessibility, SSR, debugging ve üçüncü taraf araçlarla entegrasyon üzerinde etkileri vardır. Shadow DOM kullanımı varsayılan refleks değil, component ihtiyacına göre verilmiş bilinçli karar olmalıdır.
Style Encapsulation Nasıl Çalışır?
Shadow root içinde tanımlanan CSS selector'ları normal şartlarda dış document'a uygulanmaz. Dış sayfadaki global class selector'ları da shadow tree içindeki elementleri doğrudan seçemez. Component böylece consumer stylesheet değişikliklerinden daha iyi korunur. Public theme alanı CSS Custom Properties veya ::part() gibi araçlarla açılabilir. İzolasyon tam stil bağımsızlığı anlamına gelmez çünkü inherited değerler ve CSS custom properties boundary üzerinden geçebilir.
DOM Encapsulation
Shadow DOM internal element yapısını doğrudan document selector'larından ayırır. Consumer component içindeki button veya div elemanlarını querySelector ile normal document üzerinden seçemez. Bu durum implementation detaylarını korur. Buna karşılık test ve third-party tooling için shadow root üzerinden özel erişim gerekebilir. Public davranış internal DOM query yerine properties, methods, events ve slots üzerinden sunulmalıdır.
Open Shadow DOM
Open shadow root element.shadowRoot üzerinden JavaScript erişimine izin verir. Debugging ve test açısından daha kolaydır. Consumer isterse internal DOM'a erişebilir fakat bunun public contract olmadığı dokümante edilmelidir. Çoğu design system open mode tercih edebilir. Encapsulation erişimi tamamen engellemekten çok API sınırını ifade eder.
Closed Shadow DOM
Closed shadow root doğrudan element.shadowRoot erişimini kapatır. Bu durum internal yapıyı daha güçlü gizliyor gibi görünse de debugging ve test maliyetini artırabilir. Consumer yine farklı yollarla davranışı etkileyebilir. Güvenlik sınırı olarak görülmemelidir. Design system için closed mode ancak açık ve güçlü bir gerekçe varsa tercih edilmelidir.
Shadow DOM Ne Zaman Kullanılmalı?
Global CSS çakışma riski yüksek reusable component'larda Shadow DOM önemli değer sağlar. Design system farklı uygulamalarda çalışıyorsa izolasyon daha da faydalıdır. Dialog, Tabs veya kompleks primitive'lerde internal markup contract'ını korumaya yardımcı olur. Public theme surface önceden tasarlanmalıdır. Consumer'ın internal DOM'a yoğun entegrasyon ihtiyacı varsa Light DOM daha uygun olabilir.
Shadow DOM Ne Zaman Kullanılmamalı?
Basit semantic wrapper için Shadow DOM gereksiz olabilir. Consumer'ın içeriği global layout veya typography sistemiyle doğal biçimde styla etmesi gerekiyorsa Light DOM daha rahat olabilir. Third-party library internal DOM erişimi bekliyorsa entegrasyon zorlaşabilir. SSR altyapısı Shadow DOM yaklaşımını desteklemiyorsa ek maliyet oluşabilir. Karar component bazında verilmelidir.
Light DOM vs Shadow DOM
Light DOM browser'ın normal document ağacında çalışan component yapısını ifade eder. Shadow DOM ise ayrı kapsüllenmiş ağaç oluşturur. İki model arasında tek bir doğru tercih yoktur. Styling, accessibility, SSR ve integration beklentileri birlikte değerlendirilmelidir. Aynı design system bazı component'larda Shadow DOM, bazı component'larda Light DOM kullanabilir.
Styling
Light DOM global CSS ile kolayca style edilebilir. Bu esneklik aynı zamanda style çakışması riskini yükseltir. Shadow DOM izolasyon sağlar fakat tema API'si tasarlamayı gerektirir. CSS Custom Properties iki yaklaşım arasında ortak tema mekanizması sunabilir. Component'ın consumer tarafından ne kadar özelleştirileceği seçimde önemli kriterdir.
Accessibility
Modern browser'lar Shadow DOM içeriğini accessibility tree içinde ele alabilir. Buna rağmen label ilişkileri ve focus davranışı dikkatli test edilmelidir. Light DOM bazı semantic ilişkilerde daha basit olabilir. Native HTML kullanımı iki modelde de öncelikli olmalıdır. Screen reader testleri gerçek davranışı doğrulamalıdır.
Debugging
Light DOM normal DevTools ağacında daha doğrudan görünür. Shadow DOM ise ayrı root altında incelenir. Open shadow root debugging'i kolaylaştırır. Component library internal structure değiştikçe consumer'ın debug deneyimi etkilenebilir. İyi documentation internal DOM'a ihtiyaç duyma oranını azaltır.
SSR
Light DOM server-side HTML üretiminde daha basit olabilir. Shadow DOM için Declarative Shadow DOM kullanılabilir. Hydration ve style yükleme stratejisi ayrıca tasarlanmalıdır. Framework ve hosting ortamının desteği doğrulanmalıdır. SSR requirement yüksekse component prototipi erken aşamada server ortamında test edilmelidir.
Third-Party Integration
Bazı third-party araçlar internal DOM elementlerine doğrudan erişmek isteyebilir. Shadow DOM bu erişimi zorlaştırabilir. Light DOM daha uyumlu olabilir. Bunun yerine component library gerekli integration point'leri public methods veya parts üzerinden sunabilir. Third-party gereksinimi architecture kararından önce belirlenmelidir.
Slots ile Component Composition
Slots Web Components dünyasında content composition için temel araçtır. Consumer'ın verdiği light DOM içeriği component'ın shadow template'i içinde belirli noktalara yerleştirilebilir. Bu yaklaşım content prop'ları çoğaltmadan esnek markup sağlar. Default ve named slot seçenekleri farklı kullanım alanlarını destekler. Slot API küçük tutulduğunda component kullanımı HTML'e yakın ve anlaşılır kalır.
Default Slot
Default slot ismi verilmemiş child content'i kabul eder. Button label veya Card body için doğal seçenek olabilir. Consumer normal HTML içeriğini custom element içine yazar. Component slot içeriğinin business anlamını bilmez. Bu kullanım composition için en düşük maliyetli slot modelidir.
Named Slots
Named slot header, footer veya actions gibi belirli component bölgelerini tanımlar. Consumer child element'e slot attribute ekleyerek ilgili bölgeyi doldurur. Bu yapı çok sayıda content property yerine declarative HTML sağlar. Named slot sayısı arttıkça component API'si ağırlaşabilir. Yalnızca stabil ve anlamlı bölgeler public slot olarak sunulmalıdır.
Light DOM Content Projection
Slot'a verilen içerik Light DOM'da consumer tarafında bulunmaya devam eder. Shadow DOM içindeki slot yalnızca bu içeriğin render konumunu belirler. Consumer child content üzerinde kendi event veya semantic davranışını sürdürebilir. Styling sınırları Shadow DOM kurallarından etkilenir. Bu model component ile consumer arasında güçlü bir composition contract oluşturur.
slotchange Event
slotchange slot'a atanan node listesi değiştiğinde çalışır. Component slot içeriğine göre internal state veya layout güncellemek isteyebilir. Event gereksiz sık hesaplama yapmak için kullanılmamalıdır. Assigned elements API üzerinden gerçek child'lar incelenebilir. Slot içeriğinin internal DOM detayına aşırı bağımlı olması reuse'u azaltabilir.
Slot API'sini Gereğinden Fazla Karmaşıklaştırmamak
Her bölgeyi ayrı named slot yapmak kullanım deneyimini zorlaştırabilir. Consumer hangi slot'un hangi kombinasyonda geçerli olduğunu öğrenmek zorunda kalır. Basit component'ta default slot ve birkaç property yeterli olabilir. Büyük composition ihtiyacında compound custom elements değerlendirilebilir. Public slot yüzeyi gerçek kullanım örneklerinden türetilmelidir.
Framework-Agnostic Styling Nasıl Yapılır?
Framework bağımsız design system için styling sözleşmesi JavaScript framework'ünden bağımsız olmalıdır. Component internal CSS kendi package'ı içinde yönetilebilir. Design Tokens ve CSS Custom Properties consumer'a theme kontrolü sağlar. Shadow DOM kullanıldığında :host, ::part() ve ::slotted() gibi araçlar önem kazanır. Modern CSS özellikleri framework olmadan güçlü styling architecture kurmayı mümkün hale getirir.
Component Styles
Component styles ilgili custom element'ın görünüm ve interaction durumlarını tanımlar. Stil component'ın own package'ında tutulabilir. Shadow DOM kullanılıyorsa scoped behavior doğal olarak elde edilir. Light DOM component'larda naming veya @scope gibi yöntemler değerlendirilebilir. Global reset'e aşırı bağımlı component'lar farklı consumer uygulamalarda beklenmeyen sonuç üretebilir.
CSS Custom Properties
CSS Custom Properties runtime'da miras alınabilen tema değerleri sağlar. Consumer root seviyesinde token değiştirerek component görünümünü etkileyebilir. Shadow DOM boundary üzerinden geçebilmeleri onları Web Components için özellikle faydalı kılar. Public ve internal variable ayrımı yapılmalıdır. Her internal style değerini public variable yapmak component contract'ını gereksiz büyütür.
Design Tokens
Design Tokens renk, typography, spacing ve diğer tasarım kararlarını ortak isimler altında toplar. Token'lar CSS Custom Properties, JSON veya build output olarak dağıtılabilir. Framework bağımsız component ve framework-specific uygulamalar aynı kaynak token setini kullanabilir. Semantic token isimleri marka değişikliklerini kolaylaştırır. Token governance design system'ın görsel tutarlılığında temel rol oynar.
Color Tokens
Color token raw renk yerine semantic anlam ifade etmelidir. --color-action-primary gibi isim consumer'a kullanım bağlamını anlatır. Dark mode veya farklı marka theme'i aynı semantic token'ı farklı değerle sağlayabilir. Component doğrudan hex değer kullanmaz. Contrast gereksinimleri token tasarımının parçası olmalıdır.
Typography Tokens
Typography token font family, size, weight ve line height kararlarını standardize eder. Component rastgele değer seçmek yerine semantic text style kullanır. Heading ve body sistemleri ortaklaşır. Farklı marka fontları token katmanında değiştirilebilir. Çok fazla typography token oluşturmak kullanım kararını zorlaştırabileceği için sınırlı sistem tercih edilmelidir.
Spacing Tokens
Spacing token layout boşluklarını sınırlı scale üzerinde tanımlar. Component padding ve gap değerleri bu token'lardan gelir. Tasarım ve geliştirme ekipleri aynı ölçü sistemini kullanır. Responsive variation gerekiyorsa token veya container strategy uygulanabilir. Rastgele pixel değerlerinin azalması görsel tutarlılığı artırır.
Radius ve Elevation Tokens
Radius ve elevation token yüzeylerin görsel hiyerarşisini standartlaştırır. Card, Dialog ve Popover aynı temel değerleri kullanabilir. Tema veya marka farkı token seviyesinde yönetilebilir. Box shadow kullanımının performans ve görsel etkisi de düşünülmelidir. Semantic isimler component'ın belirli raw değere bağlanmasını önler.
:host
:host Shadow DOM içinden custom element'ın kendisini style etmeyi sağlar. Display, box sizing veya default typography gibi host-level kurallar burada tanımlanabilir. Consumer host element üzerine normal CSS property de uygulayabilir. Component sizing davranışı açık olmalıdır. Host style'ın parent layout ile nasıl etkileştiği documentation içinde gösterilmelidir.
:host()
:host() host element belirli selector condition'ını karşıladığında style uygulamayı sağlar. Attribute tabanlı variant styling için kullanılabilir. Örneğin :host([disabled]) disabled görünümünü yönetebilir. Public attribute ile style contract arasında tutarlılık sağlar. Çok fazla host selector component CSS'ini zorlaştırabileceği için variant sistemi sınırlı tutulmalıdır.
::part()
::part() Shadow DOM içindeki belirli internal elementlerin consumer tarafından style edilmesine izin verir. Component internal node'a part ismi verir ve consumer bu public part üzerinden style yazabilir. Bu yöntem internal DOM yapısını tamamen açmadan kontrollü customization sağlar. Part isimleri public API olduğu için versioning kapsamında değerlendirilmelidir. Her internal element'e part vermek encapsulation avantajını azaltır.
::slotted()
::slotted() slot üzerinden gelen doğrudan elementleri shadow stylesheet içinden sınırlı biçimde style etmeyi sağlar. Deep descendant styling sağlamaz. Component default content presentation için kullanabilir. Consumer style beklentileriyle çatışmaması gerekir. Slot content üzerinde fazla kontrol kurmak composition esnekliğini azaltabilir.
@scope
@scope belirli DOM alanında CSS selector kapsamını sınırlamaya yardımcı olan modern CSS yaklaşımıdır. Light DOM component'larda Shadow DOM kullanmadan style sınırı oluşturma seçeneklerinden biri olabilir. Browser desteği hedef kitleye göre doğrulanmalıdır. Build pipeline gerektiğinde fallback strategy sağlayabilir. Bu özellik Light DOM design system architecture'larında giderek daha değerli hale gelebilir.
CSS Cascade Layers
CSS Cascade Layers stil kaynaklarının önceliğini daha kontrollü yönetmeyi sağlar. Reset, tokens, components ve overrides gibi katmanlar tanımlanabilir. Framework bağımsız styling contract'ında global style sırasını daha öngörülebilir hale getirir. Shadow DOM kullanılsa bile host-level veya shared styles için faydalı olabilir. Layer naming design system ve consumer arasında açık şekilde belgelenmelidir.
Themeable Web Components Nasıl Tasarlanır?
Themeable component consumer'ın tasarım sistemini kontrollü biçimde özelleştirmesine izin verir. Public CSS variables theme API'nin temelini oluşturabilir. Internal variables implementation detaylarını taşır ve dış contract olarak kabul edilmez. Dark mode, multi-brand ve white-label ürünler semantic token yaklaşımıyla yönetilebilir. Amaç consumer'a her CSS değerini değiştirme özgürlüğü vermek değil desteklenen tema yüzeyini açık biçimde tanımlamaktır.
Public CSS Variables
Public CSS variable consumer'ın değiştirmesine izin verilen tema noktasıdır. İsimler semantic ve versioned contract gibi ele alınmalıdır. Örneğin primary action background veya component radius public olabilir. Default değer component veya global token katmanından gelir. Public variable sayısı arttıkça compatibility yükü de büyür.
Internal CSS Variables
Internal variables component CSS'ini organize etmek için kullanılabilir. Consumer tarafından kullanılacağı garanti edilmez. Naming convention public variable'lardan ayrılabilir. Refactoring sırasında internal variable rahatça değiştirilebilir. Dokümantasyonda yalnızca desteklenen public theme variables gösterilmelidir.
Default Token Değerleri
Component consumer theme sağlamasa bile anlamlı default görünüm üretmelidir. CSS var fallback değerleri kullanılabilir. Default token design system'ın ana theme'ini temsil eder. Consumer yalnızca değiştirmek istediği semantic değerleri override eder. Bu yaklaşım kullanım başlangıcını kolaylaştırır.
Dark Mode
Dark mode semantic token değerlerinin alternatif set ile değiştirilmesi üzerinden yönetilebilir. Component içinde her renk için ayrı dark selector yazmak gereksiz tekrar üretir. Root theme attribute veya prefers-color-scheme kullanılabilir. Component token tüketir ve theme kaynağını bilmez. Contrast ve focus visibility dark mode için ayrıca test edilmelidir.
Multiple Brands
Birden fazla marka aynı component structure'ını kullanıp farklı token setleri sağlayabilir. Color, typography ve radius marka seviyesinde değişebilir. Component logic yeniden yazılmaz. Semantic token coverage yetersizse marka ihtiyaçları yeni token gerektirebilir. Multi-brand desteği ilk günden gerekiyorsa token architecture başlangıçta buna uygun tasarlanmalıdır.
White-Label Products
White-label ürünlerde müşteriye göre kapsamlı tema değişikliği gerekebilir. Public token seti bu ihtiyacı destekleyebilir. Component internal layout'un sınırsız değişmesine izin vermek bakım maliyetini artırır. Desteklenen customization seviyeleri açık paketler halinde sunulabilir. Theme API ile custom CSS injection arasındaki sınır net olmalıdır.
Consumer'ın Component'i Bozmasını Önlemek
Consumer'a her internal element için CSS erişimi vermek component contract'ını zayıflatır. Public CSS variables ve sınırlı CSS Parts daha güvenli customization sağlar. Layout-critical değerler internal tutulabilir. Design system dokümantasyonu desteklenen tema seçeneklerini açıkça belirtmelidir. Escape hatch gerekiyorsa bunun compatibility garantisi ayrıca tanımlanmalıdır.
İlk Framework-Agnostic Web Component'imizi Oluşturalım
İlk component örneğinde küçük bir custom button tasarlamak temel Web Components kavramlarını anlamak için yeterlidir. Component property, attribute, event ve styling sınırlarını gösterebilir. Native button semantic'ini içeride kullanmak accessibility açısından avantaj sağlar. Shadow DOM ile internal style korunabilir. Örnek üretim sisteminin bütün gereksinimlerini kapsamaz fakat public API kararlarını görünür hale getirir.
Component API'sini Belirlemek
Önce component'ın dış dünyaya sunacağı contract yazılmalıdır. variant ve disabled attribute olarak tanımlanabilir. Label default slot üzerinden alınabilir. Native click davranışı korunur ve gereksiz custom event üretilmez. API'yi implementation'dan önce düşünmek component'ın gereksiz özelliklerle büyümesini engeller.
Custom Element Class Oluşturmak
Component class'ı HTMLElement'den türetilebilir. Constructor içinde shadow root hazırlanabilir. DOM kurulumu ayrı render fonksiyonunda tutulabilir. Lifecycle callback yalnızca gerekli setup ve cleanup işlerini yapmalıdır. Bu yapı component büyüdükçe kodun daha kolay ayrıştırılmasını sağlar.
Template Oluşturmak
Template içinde native button ve slot kullanılabilir. Shadow DOM style kuralları aynı template veya stylesheet yaklaşımıyla eklenebilir. Native button keyboard semantic'ini hazır sağlar. Slot label content'ini consumer'dan alır. Internal markup public contract olmadığı için gelecekte değiştirilebilir.
Property Eklemek
Disabled gibi değer için property getter ve setter tanımlanabilir. Setter attribute reflection yapabilir. Attribute değişikliği render state'ini güncelleyebilir. Property ile attribute davranışının çift yönlü sonsuz döngü oluşturmamasına dikkat edilmelidir. Reactive library bu boilerplate'in bir kısmını azaltabilir.
State Yönetmek
Primitive component internal UI state taşıyabilir. Örneğin pressed veya loading state yalnızca component davranışına ait olabilir. Business state component içine alınmamalıdır. Controlled state gerekiyorsa property üzerinden consumer tarafından yönetilebilir. State değişimi yalnızca gerekli DOM bölgesini güncellemelidir.
Event Emit Etmek
Native interaction zaten anlamlı event üretiyorsa bunu korumak en iyi seçenek olabilir. Yeni semantic event gerekiyorsa CustomEvent kullanılabilir. Event payload küçük tutulmalıdır. Bubbles ve composed seçenekleri consumer kullanımına göre belirlenir. Event TypeScript type tanımı documentation içinde yer almalıdır.
Styling Eklemek
Shadow stylesheet component'ın default görünümünü sağlayabilir. Tasarım token'ları CSS Custom Properties üzerinden alınabilir. Focus-visible style accessibility için açıkça tanımlanmalıdır. Consumer host element width veya layout davranışını kontrol edebilir. Internal style'ın global CSS reset'e bağımlı olmaması tercih edilir.
Theme API'si Oluşturmak
Component public CSS variables üzerinden belirli tema noktalarını açabilir. Örneğin action color veya radius semantic token'dan gelebilir. Consumer marka theme'i root seviyesinde sağlayabilir. Component özel override gerekiyorsa local CSS variable set edilebilir. Public theme surface documentation ve versioning kapsamına alınmalıdır.
Component'i Register Etmek
Son adım class'ı customElements registry'ye kaydetmektir. Registration side effect package import sırasında veya ayrı define fonksiyonuyla yapılabilir. Büyük library'de component bazlı registration tree-shaking için daha iyi sonuç verebilir. Aynı element'ın iki kez define edilmesi engellenmelidir. Distribution modeli bu kararın consumer deneyimini nasıl etkilediğini düşünmelidir.
class DsButton extends HTMLElement {
static get observedAttributes() {
return ['variant', 'disabled'];
}
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
connectedCallback() {
this.render();
}
attributeChangedCallback() {
this.render();
}
render() {
const disabled = this.hasAttribute('disabled');
const variant = this.getAttribute('variant') || 'primary';
this.shadowRoot.innerHTML = `
<style>
:host {
display: inline-block;
}
button {
border: 0;
border-radius: var(--ds-button-radius, 8px);
padding: 10px 16px;
background: var(--ds-button-bg, #1f5eff);
color: var(--ds-button-color, #fff);
cursor: pointer;
}
button:focus-visible {
outline: 3px solid var(--ds-focus-color, #111);
outline-offset: 2px;
}
button:disabled {
opacity: .5;
cursor: not-allowed;
}
</style>
<button
type="button"
data-variant="${variant}"
${disabled ? 'disabled' : ''}
>
<slot></slot>
</button>
`;
}
}
if (!customElements.get('ds-button')) {
customElements.define('ds-button', DsButton);
}
Vanilla Web Components mı Lit mi?
Web Components geliştirmek için yalnızca browser API'leri kullanılabilir veya Lit gibi küçük yardımcı kütüphanelerden yararlanılabilir. Vanilla yaklaşım dependency sayısını azaltır ve platform API'lerini doğrudan kullanmayı öğretir. Component sayısı büyüdükçe reactive properties, declarative templates ve update lifecycle için tekrar eden kod artabilir. Lit bu alanlarda daha düzenli developer experience sağlar. Seçim framework bağımsızlığı ile development ergonomisi arasında yanlış bir ikilem olarak görülmemelidir çünkü Lit ile üretilen çıktı yine custom element contract'ı sunabilir.
Vanilla Web Components Avantajları
Vanilla yaklaşım doğrudan browser standartlarına dayanır. Ek runtime dependency gerektirmez. Geliştirici Custom Elements ve Shadow DOM davranışını daha net görür. Küçük component setlerinde build sistemi oldukça sade tutulabilir. Uzun vadeli dependency riski minimum seviyede kalabilir.
Vanilla Web Components Dezavantajları
Reactive property ve template update için daha fazla manuel kod gerekebilir. DOM diffing veya efficient update strategy geliştiricinin sorumluluğundadır. Lifecycle boilerplate component sayısıyla büyür. Team-level coding convention ihtiyacı artar. Büyük design system'de ortak base class veya yardımcı katman geliştirmek yerine olgun küçük bir library kullanmak daha ekonomik olabilir.
Lit Ne Sağlar?
Lit Web Components üzerine declarative rendering ve reactive property modeli sağlayan hafif bir kütüphanedir. Custom element standardını değiştirmek yerine onu daha kullanışlı bir developer API ile sarar. Template syntax ve update lifecycle vanilla boilerplate'i azaltır. Library consumer yine custom element kullanır. Bu nedenle Lit kullanmak design system'ı React veya Vue gibi application framework'üne bağlamakla aynı şey değildir.
Reactive Properties
Lit property değişikliklerini otomatik izleyerek render update sürecini yönetir. Attribute reflection ve type conversion için configuration sunabilir. Manuel setter boilerplate azalır. Public property contract yine dikkatli tasarlanmalıdır. Reactive olması her internal değerin public yapılması gerektiği anlamına gelmez.
Declarative Templates
Lit template syntax DOM'u string innerHTML yaklaşımına göre daha güvenli ve okunabilir biçimde tanımlar. Dynamic property ve event binding declarative şekilde ifade edilir. Update sırasında gerekli DOM parçaları yönetilir. Component code markup ile davranış arasında açık bağ kurar. Template API'si design system geliştiricilerinin ortak pattern kullanmasını kolaylaştırır.
Lifecycle
Lit standard custom element lifecycle üzerine ek reactive update lifecycle sağlar. Property değişimlerinden sonra controlled render süreci çalışır. firstUpdated veya updated benzeri hook'lar belirli ihtiyaçlarda kullanılabilir. Lifecycle logic yine mümkün olduğunca küçük tutulmalıdır. Business orchestration component lifecycle içine taşınmamalıdır.
Scoped Styling
Lit component styles'i shadow root içinde kolay tanımlamaya yardımcı olur. Static styles browser tarafından optimize edilebilir. CSS Custom Properties tema için kullanılabilir. Shadow DOM istemeyen component'larda farklı render root stratejileri değerlendirilebilir. Styling contract her durumda design system seviyesinde açık kalmalıdır.
Stencil Ne Sağlar?
Stencil compiler tabanlı component geliştirme yaklaşımı sunar ve Web Components çıktısı üretebilir. TypeScript, JSX benzeri syntax ve component metadata gibi özellikler sağlar. Framework binding üretimi bazı organizasyonlar için önemli avantajdır. Build pipeline daha fazla tooling içerir. Seçim yapılırken runtime, compiler bağımlılığı ve team experience birlikte değerlendirilmelidir.
FAST Ne Sağlar?
FAST Web Components tabanlı component geliştirme ve design system araçları sunar. Reactive template ve styling ihtiyaçlarını çözen bir yapı sağlar. Belirli enterprise kullanım senaryolarında güçlü olabilir. Library seçiminde yalnızca feature listesine değil maintenance ve ekip uyumuna da bakılmalıdır. Public custom element API'sinin library abstraction'ından bağımsız ve anlaşılır kalması önemlidir.
Hangi Yaklaşım Ne Zaman Tercih Edilmeli?
Birkaç basit component için vanilla yaklaşım yeterli olabilir. Orta ve büyük design system'de Lit gibi araç reactive ve template boilerplate'ini azaltabilir. Framework wrapper üretimi yoğun ihtiyaçsa compiler tabanlı alternatifler değerlendirilebilir. Seçim yaparken bundle impact, team experience, SSR gereksinimi ve maintenance modeli düşünülmelidir. En önemli kriter consumer'ın gördüğü Web Component contract'ının stabil kalmasıdır.
Web Components ve React
React uygulamaları custom element'ları normal DOM elementlerine benzer biçimde kullanabilir. String attributes ve children benzeri içerikler genellikle doğal çalışır. Object property ve custom events için kullanım şekli React sürümü ve tercih edilen integration modeline göre ele alınmalıdır. Design system küçük bir React adapter package sunarak native component'ı React developer experience'ına yaklaştırabilir. Adapter temel implementation'ı tekrar etmemeli, yalnızca binding ve types kolaylığı sağlamalıdır.
React İçinde Custom Element Kullanmak
Custom element JSX içinde kendi tag ismiyle kullanılabilir. Attributes JSX üzerinden verilebilir. Children slot content olarak aktarılabilir. Client bundle component registration kodunu yüklemelidir. SSR kullanılan uygulamalarda custom element'ın server ve hydration davranışı ayrıca test edilmelidir.
Property Aktarımı
Primitive değerler attribute üzerinden aktarılabilir. Object ve array gibi veriler property contract gerektirir. React adapter ref üzerinden property atamasını consumer'dan gizleyebilir. Modern entegrasyon davranışı desteklenen React sürümleriyle test edilmelidir. Public documentation hem native kullanım hem wrapper kullanım örneği sunabilir.
Custom Events
Custom events React entegrasyonunda dikkat isteyen alanlardan biridir. Native event sisteminden farklı isimler veya payload'lar wrapper gerektirebilir. Adapter event listener ekleyip React callback prop'una dönüştürebilir. Cleanup doğru yapılmalıdır. Event contract Web Component tarafında framework'ten bağımsız kalmalıdır.
TypeScript
TypeScript custom element tag'leri ve event payload'ları için ek declaration gerektirebilir. Design system generated typings sunabilir. React wrapper props daha doğal editor autocomplete sağlayabilir. Custom Elements Manifest bu tooling üretiminde veri kaynağı olabilir. Type declaration component source ile birlikte güncel tutulmalıdır.
Wrapper Component Ne Zaman Gerekir?
Wrapper her Web Component için zorunlu değildir. Basit attribute ve slot kullanan component doğrudan kullanılabilir. Property, custom event veya form integration yoğunlaştığında wrapper developer experience'ı geliştirebilir. Wrapper ayrıca React'e özgü naming veya ref davranışını uyarlayabilir. Wrapper code minimum tutulmalı ve business logic içermemelidir.
Web Components ve Vue
Vue custom element'larla doğal DOM tabanlı entegrasyon kurabilir. Template içinde custom tag kullanılabilir. Property binding ve event syntax Vue geliştiricileri için tanıdıktır. Compiler custom element'ın Vue component olmadığını bilmelidir. Design system Vue adapter sunabilir fakat çoğu component için doğrudan kullanım yeterli olabilir.
Vue Template İçinde Custom Elements
Custom element Vue template içinde normal tag gibi yazılabilir. Slot content doğrudan child markup üzerinden aktarılabilir. Vue compiler bazı tag'leri custom element olarak işaretlemek için configuration isteyebilir. Bu ayar merkezi project config içinde yapılmalıdır. Story veya örnek uygulama integration davranışını doğrulayabilir.
Property ve Attribute Binding
Vue binding syntax primitive ve dynamic değerleri aktarabilir. Object property binding ihtiyacı component contract'a göre test edilmelidir. Attribute reflection gereksiz object serialization için kullanılmamalıdır. Wrapper yalnızca gerçek binding sorunu varsa eklenebilir. Consumer'a hangi alanların property olduğu documentation içinde gösterilmelidir.
Custom Events
Vue event binding custom element events için kullanılabilir. Event isimlendirme convention'ı template syntax ile uyumlu seçilmelidir. CustomEvent detail payload handler tarafından okunabilir. TypeScript için wrapper veya declaration helper sağlanabilir. Event integration framework test suite içinde doğrulanmalıdır.
Compiler Configuration
Vue compiler hangi tag'lerin custom element olduğunu bilmelidir. Prefix tabanlı configuration pratik çözüm sağlar. Örneğin belirli ds- prefix'i custom element olarak işaretlenebilir. Bu ayar bütün design system elementlerini kapsar. Setup documentation consumer onboarding'in önemli parçasıdır.
Web Components ve Angular
Angular template sistemi custom element'larla kullanılabilir fakat proje configuration ve type checking davranışı dikkatli ele alınmalıdır. Properties ve events Angular binding syntax ile bağlanabilir. Form controls için custom element'ın form-associated behavior'ı ayrıca önem kazanır. Wrapper veya directive daha doğal Angular API'si sağlayabilir. Design system bu entegrasyonu gerçek Angular consumer uygulamasıyla düzenli test etmelidir.
Angular Template Entegrasyonu
Custom element Angular template içinde kullanılabilir. Angular compiler custom element schema veya uygun configuration üzerinden elementi kabul etmelidir. Attributes template syntax ile verilir. Slot içerikleri normal child markup olarak yazılabilir. Build ve SSR setup desteklenen Angular sürümüyle doğrulanmalıdır.
Properties
Angular property binding custom element property'lerine veri aktarabilir. Object ve array değerleri için bu yaklaşım faydalıdır. Attribute ile property farkı documentation içinde açıkça gösterilmelidir. Component reactive update'i kendi tarafında yönetir. Angular change detection ile custom element lifecycle arasında gizli shared state oluşturulmamalıdır.
Events
Angular event binding custom events ile çalışabilir. Event payload CustomEvent detail üzerinden alınabilir. Naming convention Angular template kullanımını zorlaştırmamalıdır. Wrapper output tanımlayarak daha güçlü typing sunabilir. Her event için wrapper oluşturmak gerekli değildir.
Forms ile Kullanım
Angular forms custom input component'larda daha fazla integration gerektirebilir. Form-Associated Custom Elements native form contract'ını güçlendirebilir. Bazı projeler Angular ControlValueAccessor wrapper kullanmayı tercih edebilir. Bu wrapper application framework adapter katmanında tutulmalıdır. Design system temel input davranışını yine browser standardına yakın tasarlamalıdır.
Wrapper Oluşturmanın Avantajları
Angular wrapper type-safe inputs ve outputs sağlayabilir. Forms integration daha doğal hale getirilebilir. Consumer'ın custom event detail veya element property detayını bilmesi gerekmez. Wrapper generation otomatikleştirilebilir. Ancak wrapper'ın temel Web Component davranışını yeniden implement etmemesi önemlidir.
Web Components ve Svelte
Svelte custom element'ları normal DOM tag'leri gibi tüketebilir. Property ve event behavior desteklenen sürümle birlikte test edilmelidir. Ayrıca Svelte kendi component'larını custom element output olarak üretme seçeneği de sunabilir. Bu özellik design system geliştirme stratejilerinden biri olabilir. Yine de public API'nin browser standardına uygunluğu compiler convenience'tan daha önemli olmalıdır.
Native Custom Element Kullanımı
Svelte template içinde custom element doğrudan kullanılabilir. Attributes ve slot content normal markup ile sağlanır. Object property aktarımı framework behavior'ına göre doğrulanmalıdır. Custom element registration bundle başlangıcında yapılmalıdır. SSR kullanılan Svelte uygulamalarında server output test edilmelidir.
Event İletişimi
CustomEvent component interaction'ını Svelte uygulamaya aktarabilir. Event detail payload handler içinde okunur. Bubbles ve composed davranışı Shadow DOM kullanımına göre ayarlanır. Framework adapter gerekmeden kullanım mümkün olabilir. TypeScript event typing için ek helper sağlanabilir.
Svelte ile Web Component Üretmek
Svelte belirli configuration ile component'ı custom element olarak compile edebilir. Bu yaklaşım Svelte developer experience'ı ile Web Component distribution hedefini birleştirebilir. Üretilen output'un size, lifecycle ve SSR davranışı değerlendirilmelidir. Design system source teknolojiye bağlansa bile consumer API custom element olabilir. Uzun vadeli tooling bağımlılığı yine architecture kararının parçasıdır.
Aynı Component'i React, Vue, Angular ve Vanilla JS'de Kullanmak
Framework-agnostic design system'ın gerçek testi aynı component'ın farklı consumer uygulamalarda tutarlı davranmasıdır. Ortak HTML API'si element ismi ve attributes üzerinden görünür olur. JavaScript properties karmaşık verileri taşır. Custom events interaction contract'ını sağlar. Framework adapter'ları yalnızca ergonomi ve typing desteği ekleyerek tek source implementation modelini koruyabilir.
Ortak HTML API'si
Bütün consumer'lar aynı custom element tag'ini kullanır. Variant veya disabled gibi attributes aynı anlamı taşır. Slot isimleri framework'e göre değişmez. Bu durum documentation'ın büyük bölümünü ortaklaştırır. Framework-specific sayfalar yalnızca integration syntax farklarını açıklar.
Ortak Property API'si
Element instance üzerindeki JavaScript properties bütün framework'ler için aynı semantic contract'ı taşır. Consumer binding syntax farklı olabilir. Object ve array values bu katmanda güvenli biçimde aktarılır. Property isimleri framework naming convention uğruna farklılaştırılmamalıdır. Adapter gerektiğinde framework prop adını aynı underlying property'ye bağlayabilir.
Ortak Event API'si
Component aynı CustomEvent'i bütün consumer'lara yayınlar. Event name ve detail payload framework'ten bağımsızdır. React adapter bunu callback prop'una çevirebilir. Vue veya Angular template doğrudan dinleyebilir. Integration test aynı interaction'ın bütün consumer'larda doğru çalıştığını doğrular.
Framework'e Özel Wrapper Katmanı
Wrapper temel component implementation'ını tekrar yazmamalıdır. Binding, typings ve framework-specific form integration gibi küçük farkları çözmelidir. Package olarak ayrı yayınlanabilir. Consumer native component kullanmak isterse buna da izin verilmelidir. Wrapper'lar generated tooling ile üretilebiliyorsa maintenance maliyeti daha da düşebilir.
Tek Kaynak Kod, Birden Fazla Consumer
Tek kaynak modelinin en büyük avantajı bug fix ve accessibility improvement'ın bütün consumer'lara yayılmasıdır. Release yine consumer package update gerektirebilir. Framework adapter sürümleri temel component version ile uyumlu tutulmalıdır. Cross-framework test matrix değişiklik öncesinde çalıştırılabilir. Bu yaklaşım farklı UI implementasyonlarını paralel sürdürme maliyetini önemli ölçüde azaltabilir.
Web Components ile Form Bileşenleri
Form component'ları Web Components tarafında en dikkatli tasarlanması gereken alanlardan biridir. Native input elementleri browser'ın form, validation ve accessibility davranışlarıyla derin biçimde bütünleşmiştir. Custom element bu davranışları yeniden üretmeye çalıştığında beklenmeyen eksikler oluşabilir. Form-Associated Custom Elements ve ElementInternals native form modeline daha iyi bağlanmayı sağlar. Yine de native element yeterliyse onu custom element içinde temel olarak kullanmak çoğu zaman daha güvenlidir.
Custom Input Oluşturmanın Zorlukları
Custom input yalnızca text value saklamak değildir. Form submission, reset, disabled state, validation ve label semantics birlikte çalışmalıdır. Browser autofill ve mobile keyboard davranışları da düşünülmelidir. Native input üzerine styling wrapper geliştirmek çoğu durumda daha güvenli olabilir. Tam custom behavior yalnızca gerçek interaction ihtiyacı varsa tercih edilmelidir.
Form-Associated Custom Elements
Form-associated custom element native form ile daha doğrudan çalışabilir. Class üzerinde form association etkinleştirilir. ElementInternals üzerinden value ve validity yönetilebilir. Bu model custom control'ün form submission'a katılmasını sağlar. Browser support hedef ortamla birlikte doğrulanmalıdır.
ElementInternals
ElementInternals custom element'a form ve accessibility bağlantıları için ek API sunar. Form value set edilebilir. Validity state yönetilebilir. Bazı ARIA ilişkileri internal seviyede ifade edilebilir. API kullanımı gerçek browser ve assistive technology testleriyle doğrulanmalıdır.
Form Value
Custom control kendi value'sunu form submission sistemine iletmelidir. ElementInternals setFormValue bu iş için kullanılabilir. Property ile form value arasında tutarlılık korunmalıdır. Reset davranışı test edilmelidir. Consumer'ın hidden input gibi workaround kullanmasına gerek kalmaması hedeflenmelidir.
Validation
Validation native constraint modeline mümkün olduğunca uyumlu tasarlanmalıdır. Required veya custom validity davranışı desteklenebilir. Business validation component içine gömülmemelidir. Component invalid state'i semantic ve görsel olarak gösterebilir. Form library integration ayrıca test edilmelidir.
Disabled State
Disabled state interaction'ı gerçekten durdurmalıdır. Yalnızca opacity düşürmek yeterli değildir. Form submission ve keyboard behavior native beklentiye uygun olmalıdır. Host attribute internal control'e yansıtılabilir. Disabled state framework wrapper içinde farklı logic üretmemelidir.
Label İlişkileri
Label ile custom element ilişkisi accessibility açısından kritiktir. Native label association davranışı form-associated custom elements ile değerlendirilebilir. Shadow DOM içindeki internal input'un label bağlantısı dikkatli tasarlanmalıdır. Visible label ve accessible name aynı anlamı taşımalıdır. Screen reader testleri bu davranışı doğrulamalıdır.
Web Components ve Erişilebilirlik
Web Components accessibility için engel değildir fakat component author'a önemli sorumluluk yükler. Native HTML elementlerini temel almak en güvenli başlangıçtır. Keyboard, focus ve semantic davranış component seviyesinde çözülürse bütün consumer uygulamalar aynı kaliteyi kazanır. Shadow DOM accessibility tree davranışı gerçek assistive technology ile test edilmelidir. Erişilebilirlik component tamamlandıktan sonra eklenen bir kontrol değil public API tasarımının parçası olmalıdır.
Native HTML'yi Önceliklendirmek
Native button, input, select ve dialog birçok interaction davranışını tarayıcıdan hazır alır. Bunları div ve custom JavaScript ile yeniden üretmek daha fazla hata riski oluşturur. Web Component native elementi sararak design system styling ve API sağlayabilir. Böylece browser semantic'leri korunur. Custom interaction yalnızca native seçenek ihtiyacı karşılamıyorsa geliştirilmelidir.
Semantic HTML
Internal template gerçek semantic elementleri kullanmalıdır. Heading, list ve button rolleri gereksiz ARIA ile taklit edilmemelidir. Semantic markup screen reader ve keyboard davranışına sağlam temel sağlar. Slot content'in semantic bağlamı da düşünülmelidir. Component documentation consumer'ın doğru markup kullanmasına yardımcı olmalıdır.
Keyboard Navigation
Custom interactive component klavye ile tamamen kullanılabilir olmalıdır. Tabs ve Menu gibi widget'ların beklenen arrow key davranışları bulunur. Focus sırası doğal DOM akışını mümkün olduğunca korumalıdır. Keyboard testleri otomatik E2E suite içine eklenebilir. Sadece mouse ile test edilen component production-ready kabul edilmemelidir.
Focus Management
Dialog veya popover açıldığında focus doğru alana taşınmalıdır. Kapanışta önceki interaction noktasına geri dönmek gerekir. Shadow DOM focus davranışını daha dikkatli test etmeyi gerektirebilir. Focus-visible style design token ile tutarlı olmalıdır. Programmatic focus public method olarak sunulacaksa contract açık biçimde dokümante edilmelidir.
ARIA
ARIA yalnızca native semantics yeterli olmadığında kullanılmalıdır. Yanlış role kullanımı accessibility deneyimini bozabilir. State değişiklikleri aria-expanded veya aria-selected gibi attributes ile yansıtılabilir. Component internal ARIA detaylarını consumer'dan gizleyebilir. Buna rağmen consumer'ın sağlaması gereken label gibi bilgiler public API'de açıkça belirtilmelidir.
Shadow DOM ve Accessibility Tree
Browser accessibility tree Shadow DOM içindeki semantic node'ları işleyebilir. Buna rağmen cross-boundary label ve description ilişkileri dikkat gerektirir. Native elementlerin kullanılması riskleri azaltır. Browser ve screen reader kombinasyonları arasında davranış farklılıkları görülebilir. Design system destek matrisine göre gerçek cihaz testleri planlanmalıdır.
Screen Reader Testleri
Otomatik accessibility scanner bütün screen reader deneyimini doğrulayamaz. En kritik component'lar NVDA, VoiceOver veya organizasyonun desteklediği diğer araçlarla test edilmelidir. Announced name, role ve state kontrol edilir. Dynamic content değişiklikleri ayrıca dinlenmelidir. Bulgular component seviyesinde düzeltildiğinde bütün uygulamalar fayda sağlar.
Accessible Component API Tasarlamak
Component API consumer'ın accessible kullanım oluşturmasını kolaylaştırmalıdır. Label zorunluysa açık property veya slot sağlanmalıdır. Geçersiz kullanım mümkünse development warning üretilebilir. Default markup semantic olmalıdır. Accessibility documentation kullanım örneklerinin doğal parçası olarak sunulmalıdır.
SSR ile Web Components Kullanılabilir mi?
Web Components server-side rendering ile kullanılabilir fakat integration strategy baştan düşünülmelidir. Custom element tag'leri server HTML içinde üretilebilir. Sorun internal Shadow DOM ve client upgrade aşamasında ortaya çıkar. Declarative Shadow DOM internal markup'ın server tarafından gönderilmesini sağlayabilir. Hydration ve framework server rendering davranışı gerçek production stack ile birlikte test edilmelidir.
Server-Side Rendering Problemi
Client-only Web Component ilk HTML'de yalnızca boş custom tag olarak bulunabilir. JavaScript yüklenene kadar kullanıcı içeriği görmeyebilir. Bu durum first content render ve layout üzerinde olumsuz etki yaratabilir. Server markup veya fallback content stratejisi kullanılabilir. Critical component'lar SSR beklentisine göre tasarlanmalıdır.
Declarative Shadow DOM
Declarative Shadow DOM shadow tree'nin HTML içinde declarative şekilde gönderilmesini sağlar. Browser server output'u parse ederken shadow root oluşturabilir. Bu yaklaşım JavaScript çalışmadan önce component içeriğinin görünmesini kolaylaştırır. Server rendering pipeline component template üretebilmelidir. Tooling ve browser desteği hedef ortamla doğrulanmalıdır.
Hydration
Hydration server-rendered markup'a client behavior ekleme sürecidir. Web Component library mevcut DOM'u tekrar oluşturmak yerine adopt edebilmelidir. Yanlış hydration duplicate content veya layout shift oluşturabilir. Lit gibi araçların SSR çözümü kullanılacaksa version uyumu kontrol edilmelidir. Integration test gerçek server output ve client bundle birlikte çalıştırılmalıdır.
Flash of Unstyled Content Problemi
Component JavaScript veya style geç yüklenirse kullanıcı kısa süre unstyled content görebilir. Critical CSS veya Declarative Shadow DOM bu etkiyi azaltabilir. Custom element not-defined selector üzerinden geçici fallback davranışı tasarlanabilir. Layout dimension önceden belirlemek shift riskini azaltır. Performance ölçümü gerçek network koşullarında yapılmalıdır.
SSR Framework'leriyle Entegrasyon
Her SSR framework custom element ve hydration konusunda farklı runtime davranışına sahiptir. Bu nedenle yalnızca browser-level unit test yeterli değildir. Framework-specific fixture uygulamalar oluşturmak güçlü bir kalite yaklaşımıdır. Next.js, Nuxt ve Astro gibi ortamlarda server output, events ve hydration test edilmelidir. Support matrix documentation içinde açıkça gösterilmelidir.
Next.js
Next.js içinde Web Components client registration ve server rendering stratejisi birlikte ele alınmalıdır. Client-only component gerekiyorsa boundary doğru seçilmelidir. SSR edilen markup ile custom element upgrade uyumu test edilmelidir. React wrapper event ve property ergonomisi sağlayabilir. Design system package server-safe import davranışına sahip olmalıdır.
Nuxt
Nuxt Vue tabanlı SSR ortamında custom element compiler configuration gerektirebilir. Server rendering sırasında element markup'ı üretilebilir. Client registration hydration öncesinde doğru sırada gerçekleşmelidir. Vue integration test fixture'ı bu davranışı doğrulayabilir. Theme token'larının server output'ta hazır olması FOUC riskini azaltır.
Astro
Astro HTML ağırlıklı rendering yaklaşımı nedeniyle Web Components için doğal bir consumer olabilir. Custom element scripts ihtiyaç duyulan sayfalarda yüklenebilir. Islands yaklaşımı component JavaScript maliyetini sınırlamaya yardımcı olabilir. Declarative Shadow DOM veya client upgrade strategy kullanılabilir. Vanilla HTML consumer testleri Astro benzeri ortamlar için değerli sinyal sağlar.
Web Components ile Micro-Frontend Mimarisi
Micro-frontend sistemlerinde farklı ekipler ve framework'ler aynı sayfada birlikte çalışabilir. Web Components bu sınırlar arasında standart DOM tabanlı contract sağlayabilir. Her micro-frontend kendi framework'ünü kullanırken dışarı custom element sunabilir. Events ve properties uygulamalar arası entegrasyonu mümkün hale getirir. Bununla birlikte global state, version ve shared dependency yönetimi Web Components kullanmakla otomatik olarak çözülmez.
Micro-Frontend Nedir?
Micro-frontend büyük frontend ürününü bağımsız ekip ve deployment sınırlarına ayıran organizasyonel ve teknik yaklaşımdır. Her bölüm farklı release cycle'a sahip olabilir. Framework seçimi ekip bazında değişebilir. Bu bağımsızlığın build, observability ve UX maliyeti vardır. Küçük ekiplerde micro-frontend çoğu zaman gereksizdir.
Web Components Neden Uygundur?
Custom element farklı framework'lerin anlayabildiği ortak browser contract'ı sunar. React micro-frontend Angular host içinde custom element olarak expose edilebilir. Element properties ve events integration boundary oluşturur. Framework internals dışarı sızmaz. Bu model teknoloji bağımsızlığı isteyen büyük organizasyonlarda faydalıdır.
Framework Sınırlarını Component API'siyle Ayırmak
Micro-frontend internal state veya framework store'unu dışarı açmamalıdır. Host ile communication public properties ve events üzerinden yapılabilir. Contract versioned ve dokümante edilmelidir. Büyük object graph paylaşımı coupling'i artırır. Boundary business capability seviyesinde net tutulmalıdır.
Events ile Uygulamalar Arası İletişim
Custom events micro-frontend intent ve state değişikliklerini host'a bildirebilir. Event isimleri global namespace içinde çakışmamalıdır. Payload contract küçük ve versioned olmalıdır. Her state değişimini global event bus'a çevirmek yeni coupling oluşturur. Integration yalnızca gerçekten uygulamalar arası gereken mesajlarla sınırlandırılmalıdır.
Global State Problemi
Farklı micro-frontend'lerin tek global store paylaşması bağımsızlığı azaltabilir. Web Components bu problemi kendiliğinden çözmez. URL, browser storage veya explicit events gibi daha gevşek contract'lar değerlendirilebilir. Shared session bilgisi minimal interface üzerinden sağlanabilir. State ownership organizasyon sınırlarıyla uyumlu olmalıdır.
Shared Dependencies
Micro-frontend'ler aynı framework veya library sürümünü paylaşmak isteyebilir. Web Component boundary bu ihtiyacı azaltabilir fakat runtime duplication yine oluşabilir. Shared dependency strategy build sistemi tarafından yönetilir. Design system custom element bundle'ı tek kez yüklenebilir. Version compatibility ve caching düşünülmelidir.
Versiyon Çakışmaları
Custom element registry aynı isim için iki farklı constructor tanımlanmasına izin vermez. Aynı sayfada design system'ın iki farklı major sürümünü çalıştırmak bu nedenle sorun oluşturabilir. Prefix veya versioned element names teknik çözüm olabilir fakat markup contract'ını ağırlaştırır. Daha sağlıklı yaklaşım host seviyesinde version alignment sağlamaktır. Micro-frontend release governance design system upgrade cadence'ini koordine etmelidir.
Framework-Agnostic Design System Repository Mimarisi
Repository yapısı component çekirdeğini framework adapter'larından ayırmalıdır. Components ve tokens ortak kaynak olarak yönetilebilir. React veya Vue adapter package'ları yalnızca consumer ergonomisi sağlar. Documentation ve tests ayrı fakat aynı version lifecycle içinde bulunabilir. Monorepo bu paketler arası coordinated change için güçlü seçenek sunar.
Monorepo mu Multi-Repo mu?
Monorepo component, token ve adapter değişikliklerini tek pull request içinde yapmayı kolaylaştırır. Cross-package tests aynı commit üzerinde çalışabilir. Multi-repo bağımsız ownership ve permission ihtiyaçlarında avantaj sunabilir. Package sayısı azsa monorepo genellikle daha basit coordination sağlar. Organizasyonel sınırlar teknik repository tercihinden önce değerlendirilmelidir.
packages/components
Bu package temel Web Components implementation'ını içerir. Framework-specific kod burada bulunmamalıdır. Custom Elements Manifest ve TypeScript declarations bu package'tan üretilebilir. Component bazlı entry point'ler tree-shaking için hazırlanabilir. Public API'nin ana kaynağı bu katmandır.
packages/tokens
Tokens package renk, typography ve spacing gibi tasarım değerlerini taşır. CSS, JSON veya platform-specific output üretebilir. Component package semantic token'ları tüketir. Framework consumer'lar da aynı token setini doğrudan kullanabilir. Token release'i component release'inden bağımsız veya coordinated biçimde yönetilebilir.
packages/react
React package custom element'lar için wrapper ve typings sağlayabilir. Temel style veya behavior yeniden implement edilmemelidir. Property ve event binding burada uyarlanabilir. Package components package'ına peer veya direct dependency olarak bağlanabilir. Version uyumu release tooling ile kontrol edilmelidir.
packages/vue
Vue package gerekli configuration helper veya wrapper'ları sağlayabilir. Çoğu element doğrudan kullanılabiliyorsa package küçük kalmalıdır. Type integration ve plugin registration gibi ergonomik yardımcılar eklenebilir. Component logic tekrar edilmemelidir. Consumer isterse wrapper package olmadan native custom element kullanabilmelidir.
docs
Docs component API ve usage guidance içerir. Framework-specific code examples aynı sayfada tab veya ayrı bölüm olarak gösterilebilir. Accessibility ve design guidance implementation detayından ayrı anlatılmalıdır. Documentation build Custom Elements Manifest verisini kullanabilir. Her release ile docs otomatik güncellenmelidir.
tests
Tests package veya klasörü browser, accessibility ve framework integration fixture'larını içerebilir. React, Vue, Angular ve vanilla consumer örnekleri gerçek build çalıştırmalıdır. Shared test helpers tekrar eden setup'ı azaltabilir. Test environment production kullanımını mümkün olduğunca yansıtmalıdır. Cross-framework regression design system release confidence'ını artırır.
Component Dokümantasyonu Nasıl Tasarlanmalı?
Web Component documentation yalnızca birkaç code snippet'ten oluşmamalıdır. Consumer'ın properties, attributes, events, slots ve styling API'sini açıkça görebilmesi gerekir. Bunun yanında component'ın ne zaman kullanılması ve hangi durumda başka pattern tercih edilmesi gerektiği açıklanmalıdır. Otomatik metadata üretimi documentation güncelliğini artırır. Storybook veya özel documentation sitesi canlı örnek ve interaction testleri için kullanılabilir.
Implementation Documentation
Implementation documentation component'ın teknik contract'ını açıklar. Properties ve attributes ayrı listelenmelidir. Event payload ve slot isimleri type bilgileriyle gösterilebilir. CSS Custom Properties ve Parts customization sınırını belirtir. Bu bilgi mümkün olduğunca source metadata'dan otomatik üretilebilir.
Properties
Her public property adı, tipi ve default değeriyle belgelenmelidir. Read-only veya mutable davranış belirtilmelidir. Object property için örnek JavaScript kullanımı gösterilebilir. Attribute ile reflect ilişkisi varsa açıklanmalıdır. Internal properties documentation'a public API olarak eklenmemelidir.
Attributes
Attributes HTML kullanımını gösterir. Boolean attribute semantics özellikle açıklanmalıdır. Allowed string values listelenebilir. Invalid value durumunda component davranışı belirtilmelidir. Server-rendered kullanım örnekleri attribute contract'ını anlamayı kolaylaştırır.
Slots
Default ve named slots ayrı gösterilmelidir. Slot içine beklenen semantic content açıklanmalıdır. Zorunlu veya optional slot bilgisi verilebilir. Component slot eksik olduğunda fallback content sağlıyorsa bu davranış belirtilmelidir. Slot API mümkün olduğunca küçük tutulmalıdır.
Events
Event adı, ne zaman yayınlandığı ve payload tipi belgelenmelidir. Bubbles ve composed davranışı özellikle Web Components için değerlidir. Cancelable event varsa consumer'ın nasıl engelleyeceği açıklanmalıdır. Framework-specific listener örnekleri eklenebilir. Event contract breaking change yönetimine dahil edilmelidir.
CSS Custom Properties
Yalnızca public customization variables listelenmelidir. Default değer ve semantic amaç açıklanmalıdır. Variable'ın component'ın hangi bölümünü etkilediği gösterilebilir. Internal variables dokümana eklenmemelidir. Theme token ile component-level override farkı açıklanmalıdır.
CSS Parts
CSS Parts consumer'a kontrollü internal styling noktaları sunar. Her part adı ve hedeflediği bölüm belirtilmelidir. Part kullanımının hangi seviyede desteklendiği açıklanmalıdır. Internal markup değişse bile part contract korunmalıdır. Gereksiz part export edilmemelidir.
Usage Documentation
Teknik API component'ın doğru kullanılacağını tek başına anlatmaz. Usage documentation product ve UX bağlamını açıklar. Ne zaman kullanılmalı ve ne zaman kullanılmamalı soruları cevaplanmalıdır. Do ve Don't örnekleri yanlış pattern'leri görünür hale getirir. Bu içerik designer ve developer tarafından ortak hazırlanabilir.
Ne Zaman Kullanılmalı?
Component'ın çözmeyi hedeflediği kullanıcı ihtiyacı açıklanmalıdır. Örneğin Dialog kritik kısa interaction için önerilebilir. Uygun içerik uzunluğu veya action sayısı belirtilebilir. Accessibility gereksinimleri kullanım rehberine dahil edilmelidir. Consumer yalnızca component var olduğu için onu seçmemelidir.
Ne Zaman Kullanılmamalı?
Alternatif pattern'lerin daha iyi olduğu durumlar gösterilmelidir. Uzun form için Dialog yerine ayrı page önerilebilir. Badge interaktif button yerine kullanılmamalıdır. Bu guidance component misuse oranını azaltır. Design system yalnızca teknik library değil ürün karar yardımcısı haline gelir.
Do / Don't Örnekleri
Do ve Don't görsel karşılaştırma ile kullanım farkını hızlı anlatır. Örnekler gerçek product senaryolarına dayanmalıdır. Sadece estetik tercih değil accessibility ve interaction nedenleri açıklanmalıdır. Kod örneği gerektiğinde eklenebilir. Kuralların arkasındaki gerekçe kullanıcıların yeni durumlara uyarlama yapmasını kolaylaştırır.
Custom Elements Manifest
Custom Elements Manifest component metadata'sını makine tarafından okunabilir formatta ifade etmeye yardımcı olur. Properties, attributes, events ve slots gibi bilgiler tooling tarafından kullanılabilir. Documentation generation ve IDE entegrasyonu güçlenir. Framework wrapper generation için de veri kaynağı olabilir. Manifest source ile aynı CI sürecinde güncellenmelidir.
JSDoc'tan Otomatik Dokümantasyon
JSDoc yorumları source ile documentation arasındaki mesafeyi azaltabilir. Build tool metadata çıkararak API tabloları üretebilir. Manual dokümantasyon yalnızca kullanım guidance'ına odaklanabilir. Code change sırasında stale documentation riski azalır. Yorumların da code review standardına dahil edilmesi gerekir.
Storybook veya Dokümantasyon Sitesi
Storybook component state'lerini izole biçimde göstermeye uygundur. Özel documentation sitesi daha geniş brand ve design guidance sunabilir. İki yaklaşım birlikte de kullanılabilir. Canlı Web Component demo'ları framework bağımsız behavior'ı göstermelidir. Documentation build production package ile aynı source'u kullanmalıdır.
Web Components Nasıl Test Edilir?
Web Components test stratejisi yalnızca class method unit testlerinden oluşmamalıdır. Gerçek browser DOM behavior, Shadow DOM, events ve accessibility birlikte doğrulanmalıdır. Playwright gibi browser test araçları framework integration ve keyboard davranışı için güçlü sonuç verir. Visual regression design system değişikliklerinin ürünlere etkisini erken gösterir. React, Vue, Angular ve vanilla consumer fixture'ları framework bağımsızlık iddiasını sürekli test eder.
Unit Tests
Pure helper ve state transformation logic unit test ile hızlı doğrulanabilir. Component internal implementation'a aşırı bağlı testlerden kaçınılmalıdır. Public property ve method davranışı önceliklendirilebilir. DOM behavior için browser tabanlı test daha güvenilir olabilir. Unit suite küçük ve hızlı feedback sağlamalıdır.
DOM Tests
DOM test custom element'ın gerçek render çıktısını ve lifecycle davranışını doğrular. Shadow root, slot assignment ve attributes incelenebilir. Browser environment kullanmak platform behavior'ına daha yakın sonuç verir. Public contract üzerinden assertion yapılmalıdır. Internal DOM'a yapılan testler yalnızca gerçekten önemli implementation invariants için kullanılmalıdır.
Playwright E2E Tests
Playwright component'ı gerçek browser'da kullanıcı gibi test etmeyi sağlar. Click, keyboard ve focus interaction doğrulanabilir. Framework fixture uygulamalar da aynı araçla test edilebilir. Browser çeşitliliği destek matrisine göre seçilebilir. Critical component behavior için yüksek güven sağlar.
Accessibility Tests
Otomatik accessibility engine yaygın semantic hataları yakalayabilir. Her story veya component fixture üzerinde scan çalıştırılabilir. Otomasyon screen reader kullanımının yerini tamamen tutmaz. Critical interaction'lar manuel review gerektirebilir. Regression test geçmişte düzeltilen erişilebilirlik hatalarının geri gelmesini önler.
Keyboard Tests
Keyboard tests Tab, Enter, Space ve arrow key davranışlarını doğrular. Focus sırası ve restore behavior kontrol edilir. Mouse event testleri keyboard accessibility için yeterli değildir. Tabs ve Dialog gibi composite component'larda bu testler zorunlu kabul edilebilir. Test expected WAI-ARIA interaction pattern'iyle uyumlu olmalıdır.
Visual Regression Tests
Visual regression component'ın farklı state ve theme'lerde screenshot karşılaştırmasını yapar. Dark mode ve multiple brand testleri eklenebilir. Shadow DOM style isolation regression'ları kolayca fark edilir. Dynamic content stabilize edilmelidir. Küçük pixel noise ile gerçek design hatasını ayıran review süreci kurulmalıdır.
Framework Integration Tests
Framework integration tests component'ın gerçek consumer stack içinde çalıştığını doğrular. Property binding, custom events ve SSR farklılıkları burada ortaya çıkar. Her desteklenen framework için küçük fixture app yeterli olabilir. Test matrix bütün design system package release'lerinde çalıştırılmalıdır. Böylece framework bağımsızlık teorik değil sürekli ölçülen bir kalite özelliği olur.
React Consumer
React fixture custom element registration ve rendering'i doğrular. Object property ve custom event senaryoları test edilir. Wrapper package varsa aynı davranış ayrıca kontrol edilir. TypeScript build compile test olarak kullanılabilir. SSR destekleniyorsa server ve hydration akışı eklenmelidir.
Vue Consumer
Vue fixture compiler custom element configuration ile çalışmalıdır. Attribute ve property binding test edilir. Custom event handler payload doğrulanır. Slot content ve theme davranışı kontrol edilir. Nuxt desteği varsa ayrı SSR fixture düşünülebilir.
Angular Consumer
Angular fixture template compilation ve schema configuration'ı doğrular. Property ve event binding test edilir. Form component varsa Angular forms integration eklenir. Wrapper package kullanılıyorsa typing ve ControlValueAccessor davranışı kontrol edilir. Production build'in tree-shaking sonucu da izlenebilir.
Vanilla HTML Consumer
Vanilla HTML fixture design system'ın framework dependency taşımadığını gösteren en temel testtir. Script import edildikten sonra component doğrudan HTML ile çalışmalıdır. Attributes, slots ve native events doğrulanır. CDN distribution varsa aynı fixture CDN build ile çalıştırılabilir. Bu consumer mümkün olduğunca basit tutulmalıdır.
Web Component Library Nasıl Paketlenir?
Package tasarımı consumer'ın yalnızca kullandığı component kodunu alabilmesini sağlamalıdır. ES Modules modern browser ve bundler ekosistemi için doğal temel sunar. package.json exports public entry point'leri sınırlar. TypeScript declarations editor ve framework adapter tooling'ini güçlendirir. CSS distribution ve source maps development deneyiminin bir parçası olarak planlanmalıdır.
ES Modules
ES Modules browser ve modern bundler tarafından doğal desteklenir. Component bazlı import path tanımlamak kolaydır. Static import graph tree-shaking için avantaj sağlar. Package side effect davranışı açık olmalıdır. Legacy module format ihtiyacı gerçek consumer gereksinimine göre değerlendirilmelidir.
package.json exports
Exports alanı consumer'ın hangi package yollarına erişebileceğini tanımlar. Internal file deep import'ları engellenebilir. Main entry ve component-level entry point'ler ayrı sunulabilir. Types path'leri aynı contract'a bağlanmalıdır. Public exports değişikliği semantic versioning açısından önemlidir.
Component Bazlı Import
Consumer yalnızca kullandığı component'ı import edebilmelidir. import '@design-system/button' benzeri entry point registration yapabilir. Büyük all-components bundle zorunlu olmamalıdır. Bu yaklaşım initial bundle size'ı azaltır. Documentation global registration ve component-level import farkını göstermelidir.
Tree-Shaking
Tree-shaking kullanılmayan exports'un build'den çıkarılmasını sağlar. Side-effect registration bu davranışı etkileyebilir. Package structure bundler'larla test edilmelidir. Bir consumer yalnızca Button kullanırken bütün library'nin bundle'a girmediği doğrulanmalıdır. Bundle-size regression test release pipeline'a eklenebilir.
TypeScript Definitions
TypeScript declaration public properties, methods ve event payload'ları ifade etmelidir. Custom element tag map extension IDE autocomplete sağlayabilir. Framework adapter ayrı props types sunabilir. Generated declarations source API ile senkron tutulmalıdır. Type breaking change normal API breaking change gibi ele alınmalıdır.
Source Maps
Source maps consumer'ın debug sırasında original source'u görmesini kolaylaştırır. Production distribution size üzerinde etkisi hosting modeline göre değerlendirilmelidir. Package registry source maps sunabilir. Internal proprietary source policy varsa ayrıca karar gerekir. Open source design system için debugging deneyimini önemli ölçüde iyileştirebilir.
CSS Distribution
Shadow DOM component'larda styles component bundle içinde taşınabilir. Global tokens veya fonts ayrı CSS package olarak dağıtılabilir. Consumer'ın hangi CSS dosyasını yüklemesi gerektiği açık olmalıdır. Duplicate global style import önlenmelidir. CDN ve bundler consumer'ları için uygun entry point sağlanabilir.
Web Components Nasıl Dağıtılır?
Web Component library npm package, private registry veya CDN üzerinden dağıtılabilir. Distribution modeli organizasyon ve consumer çeşitliliğine göre seçilmelidir. Package consumer bundler kullanıyorsa component-level imports güçlü seçenek sunar. Vanilla HTML uygulamalar için CDN build kullanım kolaylığı sağlayabilir. Semantic versioning ve breaking change politikası bütün dağıtım kanallarında tutarlı olmalıdır.
npm Package
npm package açık kaynak veya internal library dağıtımında yaygın yöntemdir. Consumer dependency version'ını package manifest içinde kontrol eder. ESM ve types aynı package üzerinden sağlanabilir. Release automation ve provenance güvenliği değerlendirilebilir. Changelog yeni sürüm etkisini açıkça anlatmalıdır.
Private Registry
Private registry şirket içi design system dağıtımına erişim kontrolü sağlar. Authentication developer experience'ı bozmayacak şekilde yönetilmelidir. CI publish yetkileri minimum tutulmalıdır. Package retention ve deprecation policy tanımlanabilir. Birden fazla uygulama aynı registry üzerinden versioned component alır.
CDN
CDN bundler kullanmayan uygulamalar için doğrudan script import kolaylığı sağlar. ESM URL üzerinden component yüklenebilir. Version URL içinde pin edilmelidir. Latest gibi hareketli alias production'da beklenmeyen breaking change yaratabilir. Cache policy ve integrity yaklaşımı değerlendirilmelidir.
Bundle vs Individual Components
Tek bundle başlangıç entegrasyonunu kolaylaştırır. Büyük library'de kullanılmayan component'ların da indirilmesine neden olabilir. Individual component entry point performance açısından daha kontrollüdür. Her iki dağıtım biçimi birlikte sunulabilir. Consumer documentation hangi durumda hangisinin uygun olduğunu açıklamalıdır.
Semantic Versioning
Semantic versioning component contract değişikliklerini consumer'a anlatır. Patch bug fix, minor backward-compatible feature ve major breaking change için kullanılabilir. Public properties, events, slots ve CSS Parts versioning kapsamındadır. Behavior değişiklikleri de yalnızca type değişikliğine bakılmadan değerlendirilmelidir. Otomatik release tooling bu süreci destekleyebilir.
Breaking Changes
Event adı değiştirmek veya slot kaldırmak breaking change oluşturur. CSS Custom Property veya Part contract'ı da consumer styling'i kırabilir. Deprecation dönemi geçişi kolaylaştırır. Migration guide örneklerle yeni API'yi göstermelidir. Büyük organizasyonda codemod veya automated usage scan faydalı olabilir.
Design System'de Performans Nasıl Korunur?
Framework bağımsız component modeli otomatik olarak yüksek performans garantisi vermez. Her custom element'ın kendi runtime ve style maliyeti vardır. Lazy loading, dynamic import ve tree-shaking doğru kullanıldığında initial bundle azaltılabilir. Component sayısını gereksiz büyütmemek de önemli optimizasyon yöntemidir. Event listener cleanup ve render stratejisi uzun süre açık kalan uygulamalarda kaynak kullanımını etkiler.
Framework Runtime Maliyetinden Kaçınmak
Vanilla veya küçük Web Component library'si büyük application framework runtime'ını component package'a taşımak zorunda değildir. Bu durum cross-framework distribution için bundle avantajı sağlayabilir. Buna rağmen kullanılan helper library'nin size etkisi ölçülmelidir. Her component kendi runtime kopyasını bundle etmemelidir. Shared dependency packaging strategy dikkatli yapılmalıdır.
Lazy Loading
Nadiren kullanılan Dialog veya DatePicker component'ı ihtiyaç anında yüklenebilir. Browser custom element definition geç geldiğinde markup sonradan upgrade edilebilir. Loading state ve FOUC davranışı düşünülmelidir. Critical above-the-fold component'larda eager loading daha uygun olabilir. Gerçek kullanıcı metric'leri karar vermeye yardımcı olur.
Dynamic Imports
Dynamic import component kodunu route veya interaction anında yüklemeyi sağlar. Registry helper gerekli modülü import edebilir. Aynı component'ın tekrar yüklenmemesi için module cache doğal olarak yardımcı olur. Error handling ve offline behavior planlanmalıdır. Çok küçük component'ları ayrı network request'e bölmek ters etki yaratabilir.
Tree-Shaking
Package ESM ve doğru side-effect metadata sağladığında bundler kullanılmayan kodu çıkarabilir. Registration file yapısı bu süreci etkiler. All-components entry point opsiyonel tutulabilir. Consumer bundle analyzer ile gerçek sonucu kontrol etmelidir. Design system CI örnek app bundle size'ını izleyebilir.
Bundle-Size Budget
Her component için gzip veya brotli budget belirlenebilir. Büyük dependency eklendiğinde CI uyarı verebilir. Budget mutlak sayıdan çok trend izlemek için değerlidir. Accessibility veya güvenlik özelliği sırf birkaç byte için kaldırılmamalıdır. Performance kararları kullanıcı etkisine göre dengelenmelidir.
Gereksiz Component Oluşturmamak
Her span veya layout wrapper custom element olmak zorunda değildir. Custom element lifecycle ve abstraction maliyeti taşır. Native HTML yeterliyse doğrudan kullanılmalıdır. Design system component sayısını başarı metriği olarak görmemelidir. Az fakat güçlü primitive set çoğu zaman daha sürdürülebilir olur.
Event Listener Cleanup
Window veya document listener'ları disconnect sırasında kaldırılmalıdır. Aksi durumda component DOM'dan silinse bile callback çalışmaya devam edebilir. Bound function reference cleanup için saklanmalıdır. Observer ve timers aynı şekilde temizlenmelidir. Memory leak testleri yoğun mount ve unmount senaryolarında yapılabilir.
Web Components'te Sık Yapılan Hatalar
Web Components güçlü browser API'leri sunduğu için her UI problemine custom element ile yaklaşmak cazip gelebilir. Fakat en yaygın hatalardan biri native HTML'nin zaten çözdüğü davranışları yeniden geliştirmektir. Devasa component API'leri ve global state bağımlılığı framework bağımsızlık avantajını azaltır. Shadow DOM veya custom event kullanımı da ihtiyaçtan bağımsız otomatik tercih olmamalıdır. Design system standardı component sayısından çok contract kalitesiyle değerlendirilmelidir.
Her Şeyi Web Component Yapmak
Basit layout wrapper veya tek yerde kullanılan application view custom element gerektirmeyebilir. Her element registry'ye eklenen public abstraction haline gelir. Component lifecycle ve testing maliyeti oluşur. Native HTML ile framework-local component seçenekleri her zaman masada tutulmalıdır. Web Component gerçek cross-framework reuse veya encapsulation ihtiyacı olduğunda daha değerlidir.
Native HTML'yi Yeniden İcat Etmek
Div üzerine click listener ekleyip Button davranışını sıfırdan yapmak accessibility hatası üretir. Native element keyboard, form ve semantic desteğini hazır sağlar. Custom element native primitive'i sarabilir. Browser davranışı mümkün olduğunca korunmalıdır. Tasarım sistemi farklı görünüm eklerken platformun temel davranışlarını kaybetmemelidir.
Devasa Component API'leri Oluşturmak
Yirmiden fazla property alan component consumer için zor anlaşılır hale gelir. Birçok kombinasyon test edilmek zorundadır. Composition ve slots API'yi küçültebilir. Farklı kullanım senaryoları ayrı component'lara bölünebilir. Public API büyümesi design review ve API review gerektirmelidir.
Business Logic'i Design System'e Taşımak
Design system backend endpoint veya domain workflow bilmeye başladığında reuse azalır. Farklı uygulamalar aynı business assumption'ı paylaşmak zorunda kalır. Component daha zor test edilir. Application data property olarak verilmeli ve intent events ile dışarı bildirilmelidir. Business orchestration consumer tarafında kalmalıdır.
Global State'e Bağımlı Component'ler
Component global singleton store bekliyorsa vanilla HTML consumer onu kolay kullanamaz. Framework-independent contract bozulur. Theme gibi global bilgiler CSS üzerinden taşınabilir. Business state property veya event sınırında yönetilmelidir. Component'ın çalışması için gizli initialization adımları minimumda tutulmalıdır.
Attribute ve Property'yi Karıştırmak
Object data'yı JSON attribute olarak taşımak kırılgan API oluşturabilir. Boolean attributes HTML semantic'ine aykırı kullanıldığında beklenmeyen sonuç çıkar. Documentation iki kavramı açık ayırmalıdır. Property reflection yalnızca gerekli değerlerde yapılmalıdır. Integration test framework binding davranışını doğrulamalıdır.
Custom Events'i Yanlış Tasarlamak
Internal state değişikliklerinin tamamını public event yapmak API yüzeyini büyütür. Event payload internal DOM referansları taşımamalıdır. Bubbles ve composed seçenekleri consumer ihtiyacına göre belirlenmelidir. Native event yeterliyse custom event eklenmemelidir. Event isimleri semantic ve stable olmalıdır.
Accessibility'yi Sonradan Eklemek
Component API erişilebilirlik düşünülmeden tasarlandığında sonradan label veya keyboard desteği eklemek breaking değişiklik gerektirebilir. Native semantic ilk aşamada seçilmelidir. Focus behavior component tasarımının parçası olmalıdır. Automated ve manual test birlikte planlanmalıdır. Accessibility release öncesi son checkbox olarak ele alınmamalıdır.
Shadow DOM'u Körü Körüne Kullanmak
Shadow DOM güçlü encapsulation sağlar fakat bütün component'larda gerekli değildir. Light DOM styling veya third-party integration ihtiyacı daha önemli olabilir. SSR yaklaşımı etkilenebilir. Team her component için isolation gereksinimini değerlendirmelidir. Design system tek bir global kural yerine açık decision criteria sunabilir.
Event Listener'ları Temizlememek
Global listener cleanup yapılmazsa memory leak oluşabilir. Component tekrar mount edildiğinde duplicate event handler eklenebilir. disconnectedCallback veya library lifecycle kullanılmalıdır. Observer ve timers da cleanup kapsamındadır. Automated stress test uzun süre çalışan uygulamalarda bu sorunları ortaya çıkarabilir.
Web Components Ne Zaman Kullanılmamalı?
Web Components her frontend projesi için otomatik doğru seçim değildir. Tek framework ve tek küçük uygulamada framework-native component library daha hızlı geliştirilebilir. Sadece bir business ekranında kullanılacak component için framework bağımsız abstraction gereksiz olabilir. Native HTML zaten ihtiyacı karşılıyorsa custom element oluşturmak ek maintenance üretir. Framework bağımsızlığının gerçek business gereksinimi olup olmadığı karar öncesinde açıkça sorulmalıdır.
Tek Framework ve Tek Uygulamadan Oluşan Küçük Projeler
Küçük React veya Vue projesinde Web Component platform yatırımı gereksiz olabilir. Framework-native component API ekibin mevcut bilgisine daha yakındır. Cross-framework reuse ihtiyacı bulunmaz. Build, wrapper ve integration testing maliyeti değer üretmeyebilir. Proje büyüdüğünde architecture yeniden değerlendirilebilir.
Yalnızca Uygulamaya Özgü Business Component'ler
CheckoutFlow gibi belirli application state'e yoğun bağlı component'ın framework bağımsız olması zorunlu değildir. Component aynı uygulama içinde kalabilir. Business logic framework store ve router ile doğal entegrasyon kullanabilir. Design system primitive'leri içeride yine Web Components olabilir. Framework bağımsızlık doğru katmanda uygulanmalıdır.
Native HTML'nin Yeterli Olduğu Durumlar
Basit button veya heading kullanımı için her zaman custom wrapper gerekmez. Native element design token CSS class veya style ile yeterli olabilir. Component abstraction gerçek behavior veya consistency değeri sağlamalıdır. Gereksiz wrapper markup ve maintenance oluşturur. Platformun sunduğu primitive'ler design system'ın ilk seçenekleri arasında bulunmalıdır.
Framework-Specific API'lere Aşırı Bağımlı Component'ler
Component React Context veya Angular service gibi framework contract'larına derin bağlıysa Web Component wrapper gerçek bağımsızlık sağlamaz. Internal dependency yine application framework runtime'ını ister. Bu durumda framework-native component daha açık ve dürüst architecture olabilir. Alternatif olarak business orchestration dışarı çıkarılarak primitive component ayrıştırılabilir. Zorla custom element üretmek teknik borcu başka katmana taşır.
Framework Bağımsızlığının Gerçek Bir Gereksinim Olmadığı Projeler
Architecture gelecekte belki farklı framework kullanılır varsayımıyla gereksiz maliyet üretmemelidir. Organizasyon uzun süre tek stack standardına sahipse framework library daha ekonomik olabilir. Web Components seçimi somut consumer çeşitliliği veya legacy integration ihtiyacına dayanmalıdır. Decision record gerekçeyi kaydedebilir. Teknoloji değişirse yeni karar verilebilir.
Web Components mi Framework Component'leri mi?
Web Components ile framework component'ları birbirinin mutlak alternatifi değildir. Design system primitive'leri custom element olabilirken application component'ları React veya Vue içinde geliştirilebilir. Web Components cross-framework reuse ve browser-level contract sunar. Framework component'ları application state ve framework ecosystem integration'ında daha doğal developer experience sağlayabilir. Hybrid yaklaşım çoğu büyük organizasyon için pratik bir denge oluşturur.
Web Components vs React Components
React component'lar React state ve rendering modeline doğal biçimde bağlanır. Web Components ise daha geniş consumer setine hitap eder. Tek React uygulamasında React component daha hızlı geliştirilebilir. Birden fazla framework ve legacy consumer olduğunda Web Components avantaj kazanır. React wrapper iki dünyanın ergonomisini birleştirebilir.
Web Components vs Vue Components
Vue component'lar template, reactive state ve composables ile güçlü entegrasyon sağlar. Custom elements daha bağımsız distribution contract'ı sunar. Vue-only product için native Vue component mantıklı olabilir. Organization-wide design system için Web Component core tercih edilebilir. Vue adapter gerekirse typing ve plugin ergonomisi sağlar.
Web Components vs Angular Components
Angular component'lar dependency injection ve forms sistemiyle doğal entegrasyon sunar. Web Components Angular dışındaki consumer'lara da erişir. Angular ağırlıklı tek organizasyonda framework-native design system yeterli olabilir. Farklı framework'ler aynı UI standardını paylaşacaksa custom element core daha esnek hale gelir. Angular wrapper form ve type integration'ını iyileştirebilir.
Web Components vs Svelte Components
Svelte component'lar compile-time optimize developer experience sunar. Native Svelte app içinde kullanımı oldukça rahattır. Web Components distribution standardını framework sınırının dışına çıkarır. Svelte custom element output yaklaşımı iki modeli birleştirebilir. Consumer çeşitliliği ve bundle sonucu karar üzerinde belirleyicidir.
Design System İçin Hangisi Daha Mantıklı?
Birden fazla frontend framework ve uzun design system ömrü varsa Web Components güçlü adaydır. Tek framework standardı varsa native library daha basit olabilir. Accessibility, SSR ve integration requirements prototip ile test edilmelidir. Ekibin Web Platform yetkinliği de hesaba katılmalıdır. Karar yalnızca teknoloji trendine değil toplam bakım modeline dayanmalıdır.
Hybrid Yaklaşım
Hybrid model design system core'u Web Components olarak tutabilir. React, Vue ve Angular adapter package'ları ergonomi sağlar. Application-specific component'lar kendi framework'ünde kalır. Bu yapı framework bağımsızlığı gereken alanı sınırlar. Böylece her problem custom element'a dönüştürülmeden ortak UI yatırımı korunur.
Open Source ve İşbirliği ile Web Component Design System Geliştirmek
Açık kaynak yaklaşımı design system API'sinin farklı consumer beklentileriyle sınanmasını sağlar. Contribution ve RFC süreçleri component kararlarını tek ekibin tercihinden çıkarır. Accessibility ve API review release kalitesini güçlendirir. Deprecation politikası community consumer'larının upgrade planlamasını kolaylaştırır. İyi governance açık katkıyı engellemeden public contract'ın istikrarlı kalmasını sağlar.
Component Governance
Her yeni component design system'a otomatik olarak eklenmemelidir. Kullanım alanı ve gerçek reuse ihtiyacı değerlendirilmelidir. Component owner veya maintainer belirlenir. API ve accessibility standardı review edilir. Governance amacı component sayısını büyütmek değil sürdürülebilir ortak yapı kurmaktır.
Contribution Guidelines
Contribution guide local setup, test ve review beklentilerini açıklar. Yeni component proposal için gereken bilgiler belirtilir. Public API değişikliğinde RFC istenebilir. Accessibility test checklist eklenebilir. Yeni contributor birkaç adımda projeyi çalıştırabilmelidir.
RFC Süreci
RFC büyük API veya architecture değişikliklerini kod yazılmadan önce tartışmayı sağlar. Consumer ihtiyaçları ve alternatifler yazılır. Framework integration etkisi değerlendirilir. Karar repository içinde kalıcı kayıt olur. Küçük bug fix için RFC gerektirmek süreci gereksiz yavaşlatabilir.
GitHub Issues
Issue component bug ve feature taleplerinin görünür backlog'unu sağlar. Template gerekli reproduction ve browser bilgisini isteyebilir. Component request gerçek usage examples içermelidir. Maintainer priority ve status bilgisi paylaşabilir. Community aynı probleme duplicate issue açmadan katkı yapabilir.
Pull Request Review
Pull request implementation ile public contract'ı birlikte değerlendirmelidir. Tests ve docs aynı değişiklikte güncellenmelidir. Bundle size ve browser compatibility gerektiğinde kontrol edilir. Review feedback açık ve uygulanabilir olmalıdır. Merge yalnızca kod çalıştığı için değil component standardı karşılandığında yapılmalıdır.
Accessibility Review
Interactive component accessibility review'dan geçmelidir. Keyboard ve screen reader behavior doğrulanır. Native semantic kullanımına bakılır. Focus ve contrast test edilir. Bulgular component release edilmeden önce düzeltilmelidir.
Component API Review
API review public properties, events, slots ve styling surface'i inceler. Gereksiz prop veya CSS part azaltılabilir. Naming diğer component'larla tutarlı olmalıdır. Framework consumer'larda binding kolaylığı değerlendirilir. API stabil hale gelmeden geniş adoption teşvik edilmemelidir.
Deprecation Politikası
Public component kaldırılmadan önce alternatif sunulmalıdır. Deprecation warning ve documentation migration yolu göstermelidir. Bir veya birkaç release grace period verilebilir. Major version'da removal yapılabilir. Usage telemetry veya code search kalan consumer'ları bulmaya yardımcı olur.
Community-Driven Component Geliştirme
Community farklı kullanım senaryolarını design system'a taşır. Tek ürünün ihtiyacına göre aşırı optimize API riski azalır. Contributor'lar docs, tests ve examples ile katkı sağlayabilir. Maintainer yine consistency ve quality sorumluluğunu taşır. Açık karar kayıtları yeni katılımcıların geçmiş gerekçeleri anlamasını kolaylaştırır.
Framework-Agnostic Design System İçin Önerilen Mimari
Sağlam framework-agnostic design system tek package içinde bütün sorumlulukları karıştırmamalıdır. Design Tokens görsel kararları, primitive Web Components temel UI davranışını ve composite component'lar reusable interaction pattern'lerini taşır. Framework adapters yalnızca integration ergonomisine odaklanır. Application component katmanı business bağlamını design system çekirdeğinden ayırır. Documentation ve quality-gate katmanları bütün yapının sürdürülebilirliğini sağlar.
Design Tokens Katmanı
Token katmanı renk, typography, spacing ve diğer temel tasarım değerlerini tanımlar. Framework ve component implementation'ından bağımsız tutulur. CSS ve farklı platform output'ları üretilebilir. Semantic naming multi-brand desteğini kolaylaştırır. Token governance designer ve developer collaboration'ıyla yönetilmelidir.
Primitive Web Components Katmanı
Primitive katman Button, Input, Badge ve benzeri temel component'ları içerir. Native HTML semantic'lerini temel alır. Public API küçük ve framework bağımsızdır. Accessibility burada çözülür. Composite component'lar bu primitive'leri tekrar kullanabilir.
Composite Components Katmanı
Composite katman Tabs, Accordion ve Dialog gibi daha büyük interaction pattern'lerini içerir. Primitive component'ları birleştirir. Internal state taşıyabilir fakat application business state'ine bağlanmaz. Slots ve events composition contract'ını oluşturur. Accessibility interaction pattern'i component tarafından merkezi uygulanır.
Framework Adapters Katmanı
Adapter package React, Vue veya Angular consumer ergonomisini iyileştirir. Property ve event binding kolaylaştırılır. Framework-specific forms veya type integration burada çözülür. Temel UI implementation tekrar edilmez. Adapter package kaldırıldığında core component normal HTML içinde çalışmaya devam etmelidir.
Application Components Katmanı
Application component'lar business domain'e daha yakın reusable parçaları içerir. Framework bağımsızlık ihtiyacı gerçek consumer sayısına göre değerlendirilir. Bazıları Web Components olabilir, bazıları framework-native kalabilir. Design system primitive'lerini kullanırlar. Bu katman çekirdek component package'ından ayrı ownership taşıyabilir.
Documentation Katmanı
Documentation teknik API ile usage guidance'ı birleştirir. Custom Elements Manifest'ten otomatik metadata alınabilir. Framework integration örnekleri aynı component sayfasında gösterilebilir. Accessibility ve theme guidance canlı demo ile desteklenir. Docs her package release'iyle birlikte yayınlanmalıdır.
Test ve Quality-Gate Katmanı
Quality gate unit, browser, accessibility ve framework integration testlerini kapsar. Bundle-size budget ve visual regression eklenebilir. API metadata değişikliği breaking-change review tetikleyebilir. CI bütün desteklenen consumer fixture'larını çalıştırır. Bu katman framework bağımsızlık vaadini sürekli doğrulayan sistemdir.
Web Components Design System Checklist
Production-ready Web Components design system için yalnızca component'ların browser'da render olması yeterli değildir. Public API, styling, accessibility ve framework compatibility ayrı ayrı doğrulanmalıdır. Distribution ve versioning strategy consumer ekiplerin güvenle upgrade yapabilmesini sağlamalıdır. Checklist release öncesinde ortak kalite standardı oluşturur. Otomatik kontrol edilebilen maddeler mümkün olduğunca CI sürecine taşınmalıdır.
Component API
Her component'ın public contract'ı documentation içinde görünür olmalıdır. Attribute ve property farkları açıklanmalıdır. Events ile slots aynı API yüzeyinin parçası kabul edilmelidir. Internal implementation detayları public contract'a sızmamalıdır. API review release sürecinin zorunlu adımı olabilir.
Attributes Tanımlı mı?
Public attributes listelenmelidir. Type ve allowed values belirtilmelidir. Boolean semantics doğru kullanılmalıdır. Default davranış açıklanmalıdır. Attribute change'in component state'e nasıl yansıdığı test edilmelidir.
Properties Tanımlı mı?
Object ve array gibi değerler için properties açıkça tanımlanmalıdır. TypeScript declaration bulunmalıdır. Attribute reflection gerekiyorsa documentation bunu göstermelidir. Internal property dışarı export edilmemelidir. Property change reactive render ile doğrulanmalıdır.
Events Dokümante mi?
Her event adı ve yayınlanma zamanı yazılmalıdır. CustomEvent detail type açıklanmalıdır. Bubbles ve composed davranışı belirtilmelidir. Framework-specific listener örnekleri gösterilebilir. Breaking event değişiklikleri semantic versioning kapsamına alınmalıdır.
Slots Dokümante mi?
Default ve named slots açıkça listelenmelidir. Expected semantic content anlatılmalıdır. Fallback davranışı varsa belirtilmelidir. Slot API gereksiz geniş olmamalıdır. Story örnekleri farklı slot kombinasyonlarını gösterebilir.
Styling
Component styling design token sistemine bağlı olmalıdır. Public tema yüzeyi internal CSS'ten ayrılmalıdır. Shadow DOM kullanımı component bazında gerekçelendirilmelidir. Consumer'ın hangi alanları değiştirebileceği açık olmalıdır. Styling regression visual testlerle korunabilir.
Design Tokens Kullanılıyor mu?
Raw color ve spacing değerleri minimumda tutulmalıdır. Semantic token kullanımı marka ve theme desteğini kolaylaştırır. Component token fallback değerlerine sahip olabilir. Token source merkezi yönetilmelidir. Token değişiklikleri visual regression testlerinden geçmelidir.
Theme API'si Var mı?
Theme ihtiyacı varsa public CSS Custom Properties tanımlanmalıdır. Dark mode ve brand theme aynı semantic contract'ı kullanmalıdır. Consumer customization sınırı açık olmalıdır. Default theme component'ı tek başına kullanılabilir hale getirmelidir. Theme değişimi runtime'da test edilmelidir.
CSS Parts Gerekli mi?
Consumer'ın internal bölüm üzerinde style ihtiyacı gerçekten var mı değerlendirilmelidir. CSS Custom Property yeterliyse part eklemek gerekli olmayabilir. Part isimleri public API haline gelir. Internal DOM refactor part contract'ını korumalıdır. Az ve anlamlı part tercih edilmelidir.
Accessibility
Accessibility checklist yalnızca automated scanner sonucuna dayanmaz. Keyboard, focus ve screen reader davranışı birlikte test edilmelidir. Native HTML kullanımı kontrol edilmelidir. Component'ın accessible name üretme contract'ı açık olmalıdır. Kritik sorunlar release blocker olarak değerlendirilmelidir.
Keyboard Çalışıyor mu?
Interactive component mouse olmadan kullanılabilmelidir. Tab ve arrow key davranışları beklenen pattern'e uymalıdır. Escape veya Enter interaction gerekli olduğunda test edilmelidir. Disabled element doğru biçimde atlanmalıdır. Playwright keyboard tests regression koruması sağlar.
Focus Görünür mü?
Keyboard kullanıcısı focus konumunu her zaman görebilmelidir. Focus-visible style contrast açısından yeterli olmalıdır. Shadow DOM focus behavior gerçek browser'da test edilmelidir. Dialog kapanışında focus geri dönmelidir. Tema değişiklikleri focus style'ı görünmez hale getirmemelidir.
Screen Reader Testi Yapıldı mı?
Component name, role ve state doğru okunmalıdır. Dynamic state değişiklikleri gerektiğinde duyurulmalıdır. Label ilişkileri doğrulanmalıdır. En kritik browser ve screen reader kombinasyonları support matrix'e göre seçilmelidir. Bulgular documentation içinde bilinen sınırlama olarak bırakılmamalı, mümkün olduğunca component seviyesinde çözülmelidir.
Framework Uyumluluğu
Framework-agnostic iddia gerçek consumer build'leriyle doğrulanmalıdır. Her framework'te property, event ve slots test edilmelidir. SSR gereksinimi varsa server fixture eklenmelidir. Wrapper package'lar core behavior ile uyumlu kalmalıdır. Integration failures release öncesinde görülmelidir.
React Test Edildi mi?
React fixture custom element render ve registration'ı doğrulamalıdır. Property binding ve custom events test edilmelidir. Wrapper varsa aynı test contract'ı uygulanabilir. TypeScript build hata vermemelidir. SSR kullanılıyorsa hydration senaryosu ayrıca çalıştırılmalıdır.
Vue Test Edildi mi?
Vue custom element compiler configuration test ortamında gerçek şekilde kullanılmalıdır. Property ve event binding doğrulanmalıdır. Named slot behavior test edilmelidir. Type integration kontrol edilebilir. Nuxt consumer destekleniyorsa server render ayrıca doğrulanmalıdır.
Angular Test Edildi mi?
Angular template compilation custom element ile başarılı olmalıdır. Properties ve events beklenen biçimde çalışmalıdır. Form component'lar forms integration testinden geçmelidir. Wrapper varsa input ve output types doğrulanmalıdır. Production build bundle size ayrıca gözlemlenebilir.
Vanilla HTML Test Edildi mi?
Vanilla consumer framework dependency olmadığını kanıtlar. Element script import edildikten sonra markup doğrudan çalışmalıdır. Theme ve events framework olmadan test edilmelidir. CDN build varsa aynı fixture kullanılabilir. Bu test design system'ın platform-level contract'ını korur.
Distribution
Distribution package'ın farklı consumer build sistemlerinde güvenilir kullanılmasını sağlamalıdır. ESM modern temel olarak sunulabilir. TypeScript types public API ile birlikte yayınlanmalıdır. Semantic versioning upgrade riskini anlatır. Tree-shaking consumer'ın yalnızca kullandığı component maliyetini taşımasını sağlamalıdır.
ESM Desteği
Package ES Module entry point sunmalıdır. Browser ve bundler testleri yapılmalıdır. Component-level import desteklenebilir. Side effect registration davranışı açık olmalıdır. CDN consumer için doğrudan ESM URL sağlanabilir.
TypeScript Types
Declarations package ile aynı sürümde yayınlanmalıdır. Custom element tag ve event payload'ları type-safe hale getirilebilir. Framework wrappers kendi props types'ını sunabilir. Generated type dosyaları CI'da source API ile karşılaştırılabilir. Type breaking changes major release gerektirebilir.
Semantic Versioning
Release türü public contract değişimine göre belirlenmelidir. Slot veya event kaldırılması major değişikliktir. Yeni optional property minor olabilir. Bug fix patch olarak yayınlanabilir. Changelog consumer'a değişikliğin gerçek etkisini açıklamalıdır.
Tree-Shaking
Consumer bir component kullandığında bütün library bundle'a girmemelidir. ESM graph ve side effects ayarları test edilmelidir. Component entry point'ler ayrı export edilebilir. CI örnek consumer bundle'ını ölçebilir. Regression budget beklenmeyen package büyümesini erken gösterir.
Sık Sorulan Sorular
Web Components hakkında en sık sorulan sorular framework ilişkisi, Shadow DOM, SSR ve performans etrafında toplanır. Bu soruların ortak noktası Web Components'in application framework yerine geçen bir çözüm olarak görülmesidir. Gerçekte Web Components daha çok browser seviyesinde reusable component contract'ı sağlar. Uygulama state'i, routing ve data orchestration farklı katmanlarda kalabilir. Aşağıdaki yanıtlar teknoloji seçiminde temel ayrımları netleştirir.
Web Components Nedir?
Web Components özel HTML elementleri oluşturmayı sağlayan web standartları grubudur. Custom Elements temel kayıt ve lifecycle modelini sunar. Shadow DOM isteğe bağlı DOM ve style izolasyonu sağlar. Slots içerik composition'ını destekler. Bu yaklaşım aynı UI component'ının farklı frontend framework'lerinde kullanılmasını mümkün hale getirebilir.
Web Components Bir JavaScript Framework'ü müdür?
Hayır, Web Components bir JavaScript framework'ü değildir. Routing veya application state management sağlamaz. Browser'ın native DOM ve component API'lerini sunar. React veya Vue ile birlikte kullanılabilir. Lit gibi yardımcı kütüphaneler Web Components geliştirmeyi kolaylaştırabilir.
Web Components React'in Yerini Alır mı?
Web Components React'in bütün application framework rolünü üstlenmez. React state, rendering ve application composition için kullanılabilir. Web Components design system veya cross-framework UI sınırı sağlayabilir. React uygulama custom element'ları consumer olarak kullanabilir. İki teknoloji aynı architecture içinde birlikte çalışabilir.
Web Components React ile Kullanılabilir mi?
Evet, custom element'lar React uygulamalarında kullanılabilir. Basit attributes ve child content oldukça doğaldır. Object properties veya custom events için integration strategy gerekebilir. React adapter developer experience'ı iyileştirebilir. Core component yine framework'ten bağımsız kalır.
Web Components Vue ve Angular ile Çalışır mı?
Evet, Vue ve Angular custom element'ları tüketebilir. Framework configuration ve binding syntax farklıdır. Properties ve custom events integration testleriyle doğrulanmalıdır. Angular forms veya Vue compiler için ek setup gerekebilir. Design system bu farkları documentation ve adapters ile kolaylaştırabilir.
Shadow DOM Kullanmak Zorunlu mu?
Hayır, custom element Shadow DOM olmadan da çalışabilir. Light DOM component'lar global CSS ve third-party tools ile daha kolay entegre olabilir. Shadow DOM style isolation gerektiğinde güçlü avantaj sağlar. SSR ve styling beklentileri karar üzerinde etkilidir. Aynı design system her component için aynı seçimi yapmak zorunda değildir.
Web Components SEO İçin Uygun mu?
Web Components SEO açısından otomatik olarak olumsuz değildir. Arama motorunun ilk HTML ve render edilen içeriğe erişebilmesi önemlidir. Client-only internal content yerine SSR veya anlamlı light DOM content kullanılabilir. Declarative Shadow DOM server rendering seçeneklerini geliştirebilir. SEO kritik sayfalarda gerçek crawler ve rendered HTML davranışı test edilmelidir.
Web Components SSR ile Çalışır mı?
Evet, ancak server ve hydration strategy doğru tasarlanmalıdır. Custom element markup server tarafından üretilebilir. Declarative Shadow DOM internal shadow content'in server output'a eklenmesini sağlar. Framework ve component library'nin SSR integration'ı birlikte doğrulanmalıdır. Client upgrade sırasında duplicate rendering önlenmelidir.
Lit Kullanmak Zorunlu mu?
Hayır, Web Components yalnızca browser API'leriyle geliştirilebilir. Lit reactive properties ve declarative templates ile development deneyimini kolaylaştırır. Küçük component seti vanilla yaklaşımı tercih edebilir. Büyük design system Lit kullanımından fayda görebilir. Consumer API her iki durumda da custom element olarak tasarlanabilir.
Web Components Performanslı mı?
Web Components performansı implementation ve distribution stratejisine bağlıdır. Büyük framework runtime zorunluluğu bulunmaması avantaj olabilir. Buna rağmen ağır component logic veya gereksiz bundle performansı düşürür. Tree-shaking ve lazy loading uygulanabilir. Gerçek kullanıcı metric'leri ve bundle budget üzerinden değerlendirme yapılmalıdır.
Web Components Design System İçin İyi Bir Seçim mi?
Birden fazla framework, legacy uygulama veya uzun ömürlü UI platformu varsa güçlü seçim olabilir. Tek küçük framework uygulamasında ek yatırım gereksiz kalabilir. Accessibility ve SSR ihtiyaçları prototip üzerinden doğrulanmalıdır. Component API web platformu standartlarına yakın tutulmalıdır. Karar organizasyonun gerçek consumer çeşitliliğine göre verilmelidir.
Web Components Gerçekten Framework-Agnostic mi?
Component contract seviyesinde büyük ölçüde framework bağımsız olabilir. Application state ve routing yine framework'e bağlı kalabilir. Property, event ve SSR entegrasyonunda framework-specific adapter gerekebilir. Bu durum framework bağımsızlık hedefini geçersiz kılmaz. Amaç framework bağımlılığını core UI implementation'dan küçük adapter katmanına taşımaktır.
Sonuç: Framework'lerden Değil Web Platformundan Başlayan Bir Design System Tasarlamak
Web Components uzun ömürlü design system'lar için component contract'ını belirli bir frontend framework'ünden ayırmanın güçlü yollarından biridir. Custom Elements ortak HTML API'si, Shadow DOM kontrollü isolation, slots composition ve CSS Custom Properties tema desteği sağlayabilir. Başarılı bir mimaride business logic design system çekirdeğine taşınmaz, framework adapter'ları küçük tutulur ve accessibility native HTML üzerinden baştan çözülür. SSR, forms ve framework integration gibi alanlar ayrıca test edildiğinde aynı component kaynağı React, Vue, Angular, Svelte ve vanilla uygulamalara hizmet edebilir. Web platformu, reusable UI mimarisinin en uzun ömürlü ortak paydası olarak değerlendirildiğinde teknoloji değişimlerinin design system üzerindeki maliyeti daha yönetilebilir hale gelir.
Design system geliştirirken hedef bütün uygulamaları aynı framework'e zorlamak değil, ortak kullanıcı deneyimini güçlü ve anlaşılır sözleşmeler üzerinden paylaşmak olmalıdır. Primitive component'lar mümkün olduğunca küçük tutulmalı, composite component'lar gerçek interaction pattern'lerini çözmeli ve application-level business davranışları ilgili ürün ekiplerinde kalmalıdır. Design Tokens, Custom Elements Manifest, browser testleri ve semantic versioning bu yapının zaman içinde güvenilir kalmasına yardımcı olur. Framework bağımsızlığını gerçek ürün ve ekip ihtiyaçlarıyla birlikte değerlendirmek gereksiz abstraction yatırımını da önler. Web Components, frontend architecture ve açık kaynak yazılım çalışmaları üzerine Diyarbakır Yazılım Topluluğu içeriklerini takip etmek için https://www.diyarbakiryazilim.com.tr adresini ziyaret edebilirsiniz.
share: