Kuruluma başlayın
Belge menüsü

Arayüz bileşenleri

Devoplus One, sık kullanılan ekranlar için hazır bileşenler verir: liste (<one-table>), form (<one-form>), süzgeç çubuğu (<one-filter>), kişi seçici (<one-person-picker>), dosya yükleme (<one-file-upload>), grafik (<one-chart>), gösterge kartı (<one-stat>), aranabilir açılır liste (<one-select>), etiket girişi (<one-tag-input>), pencere (<one-dialog>), ipucu (<one-tooltip>), eylem menüsü (<one-menu>), avatar (<one-avatar>), sekmeler (<one-tabs>) ve akordeon (<one-accordion>). Rozet, anahtar, radyo grubu, ilerleme çubuğu ve yükleniyor göstergesi de /one-ui.css sınıfı olarak hazırdır. Bileşenler Devoplus görsel dilindedir, Portal'ın tema ve dil değişimini kendiliğinden izler, Türkçe ve İngilizce metin taşır, klavyeyle kullanılır ve platformun güvenlik kurallarına (satır içi betik yok, istek yalnız uygulamanın kendi adresine) uyar.

Ekranda bir liste, kayıt formu, süzgeç, kişi seçimi, dosya yükleme, grafik, açılır liste, etiket, pencere, ipucu, eylem menüsü, sekme, akordeon, rozet ya da anahtar gerekiyorsa önce bu bileşenleri ve sınıfları kullanın; aynı işi elle yazmayın. Elle yazılan tablo ya da form sıralama, sayfalama, doğrulama, erişilebilirlik ve dil desteğini çoğu zaman eksik bırakır. Uygulamayı yazan yapay zeka aracınız da bu kurala uyar (uygulama kuralları).

Sizin vereceğiniz kararlar iş kararlarıdır: listede hangi bilgiler görünsün, formda hangi alanlar zorunlu olsun, kişi seçicide kimler seçilebilsin. Bunların kolon ve alan tanımına çevrilmesi kodun işidir.

Hangi ekranda hangi bileşen

İstediğinizBileşenNot
"Taleplerin listesi", "kayıtları görmek", "tablo"<one-table src="/api/<varlık>">Sıralama, arama, sayfalama, satır seçimi hazır
"Listeyi Excel'e almak", "rapor indirmek"<one-table export="xlsx csv">Dosyayı sunucu üretir (aynı süzgeçle ?format=xlsx)
"Duruma / tarihe göre süzmek"<one-filter for="<tablo kimliği>">Metin, seçim, tarih, tarih aralığı, evet/hayır
"Yeni talep formu", "kaydı düzenlemek"<one-dialog> içinde <one-form action="/api/<varlık>">Form liste ekranına çizilmez, pencerede açılır; kaydedince pencere kendiliğinden kapanır
"Onaylayan kişiyi seçmek", "sorumlu atamak"<one-person-picker> (form alanında type: 'person')Sunucuda peopleSearchHandler + orgschema.read
"Belge / fotoğraf eklemek"<one-file-upload> (form alanında type: 'file')Dosya deposu açık olmalı (services.files)
"Aylık özet grafiği", "dağılım"<one-chart type="bar|line|area|pie|doughnut">Portaldaki grafiklerle aynı kütüphane (/one-charts.js); sayıları sunucu hesaplar
"Kaç tane açık", "toplam tutar", "özet bilgi"<one-stat> kartları (<div class="one-stat-grid"> içinde)Özet cümle olarak yazılmaz; her sayı bir kart
Satıra tıklayınca ayrıntı açılsın<one-table clickable> + rowclick olayıGörünüm değişince one.setRoute(yol)
"Listeden seçsin", "birden çok seçebilsin"<one-select> (multiple)Yazarak arar; sabit, küçük seçenek listesi için
"Etiket / anahtar kelime eklesin"<one-tag-input>Serbest metin etiketleri; isteğe bağlı öneri listesi
"Açılır pencerede düzenlesin"<one-dialog> + show()Portal da arka planı karartır
"Silsin" (her zaman onayla)one.remove(adres, { message })Önce onay sorar, kabulde DELETE gönderir; vazgeçilirse istek gitmez
"Pasife alsın"<one-form> alanı active (ya da confirmOff)Kayıt düzenlenirken açıktan kapalıya çevrilince form onay sorar
"Başka bir işlemden önce sorsun"one.confirm(...) ya da <one-dialog accept-label reject-label>Portal içinde Portal'ın onay penceresi açılır
"Kaydedildi yazsın"one.toast(...)Portal içinde Portal çizer
"Kısa açıklama / yardım"<one-tooltip text="...">Tetikleyici odaklanabilir olmalı
"Satır işlemleri (düzenle, sil gibi)"<one-menu compact> + select olayıTehlikeli işlem danger: true
"Kişinin fotoğrafı / baş harfleri"<one-avatar name="..." src="...">
"Bölümler halinde göster"<one-tabs> ya da <one-accordion>Sekme uygulama menüsü DEĞİLDİR
"Durumu renkli göster"<span class="one-badge one-badge-success">Durum metni de yazılır
"Açık/kapalı ayarı"<input type="checkbox" role="switch" class="one-switch">
"İlerleme / yükleniyor"<progress class="one-progress">, <span class="one-spinner">

Sayfaya ekleme

Sayfa dosyaları uygulamanın kendi adresinden yükler; bileşen betiği köprüden sonra gelir:

html
<link rel="stylesheet" href="/one-ui.css">
<one-filter for="talepler"></one-filter>
<one-table id="talepler" src="/api/requests" export="xlsx csv" clickable caption="Talepler"></one-table>
<script src="/one-bridge.js"></script>
<script src="/one-charts.js"></script>
<script src="/one-components.js"></script>
<script src="/shell.js"></script>

/one-charts.js portaldaki grafiklerle aynı grafik kütüphanesidir; köprüden sonra, bileşen betiğinden önce yüklenir. Yüklenmezse <one-chart> yedek çizimle görünür ve yayın kapısı uyarır.

Sunucu tarafında clientAssetResponse(pathname, request) bu dosyaların hepsini döndürür; ek kod gerekmez. Bileşen kullanılıp /one-components.js yüklenmezse yayın kapısı uyarır (bileşenler boş görünürdü).

Kolon, alan ve veri tanımları JavaScript özelliğidir (/shell.js içinde atanır), öznitelik değildir. Etiketler { tr, en } biçiminde iki dillidir. Bütün metinler düz metin olarak yazılır; HTML yorumlanmaz.

Liste: <one-table>

js
var table = document.getElementById('talepler')
table.columns = [
  { key: 'title', label: { tr: 'Başlık', en: 'Title' } },
  { key: 'requester', label: { tr: 'Talep eden', en: 'Requester' }, type: 'person' },
  { key: 'amount', label: { tr: 'Tutar', en: 'Amount' }, type: 'money' },
  { key: 'createdAt', label: { tr: 'Tarih', en: 'Date' }, type: 'date' },
  { key: 'status', label: { tr: 'Durum', en: 'Status' }, type: 'choice', options: [
    { value: 'open', label: { tr: 'Açık', en: 'Open' } },
    { value: 'closed', label: { tr: 'Kapalı', en: 'Closed' } },
  ] },
]
table.addEventListener('rowclick', function (e) { showDetail(e.detail.row) })
  • Uzak liste: src verilince bileşen GET <src>?limit=&cursor=&sort=&order=&q=&<alan>= ister ve { items, nextCursor } bekler (veri modeli ucunun sayfalı listesiyle aynı). Sonraki sayfa nextCursor'la gelir. Sayfa numaralı uç için paging="page" (page= gönderir, yanıttaki total sayfa sayısını verir).
  • Yerel veri: küçük ve sabit listelerde table.rows = [...]; sıralama, arama ve sayfalama tarayıcıda yapılır.
  • selectable (çoklu) ya da selectable="single" verilirse selectionchange olayı ve table.selection kullanılır.
  • export="xlsx csv" verilirse "Excel'e aktar" / "CSV olarak indir" düğmeleri çıkar; uç aynı süzgeç ve sırayla ?format=xlsx|csv isteğine dosya döndürmelidir (sayfalama yok). Dosya Portal'ın indirmesiyle kaydedilir.
  • Yükleniyor, boş ("Kayıt yok."; table.emptyText ile değişir), arama sonucu boş ve hata ("Liste getirilemedi." + Yeniden dene) durumları ayrı gösterilir; sunucunun hata metni (detail) olduğu gibi görünür.

Süzgeç: <one-filter>

js
document.querySelector('one-filter').fields = [
  { key: 'q', label: { tr: 'Ara', en: 'Search' }, type: 'text' },
  { key: 'status', label: { tr: 'Durum', en: 'Status' }, type: 'choice', options: table.columns[4].options },
  { key: 'createdAt', label: { tr: 'Oluşturma', en: 'Created' }, type: 'dateRange' },
]

for özniteliğindeki tabloya kendiliğinden bağlanır; ayrıca change olayı { values, params } yayar. Parametreler: metin için q, seçim ve evet/hayır için alan adı, tarih aralığı için <alan>From ve <alan>To (uç farklı ad bekliyorsa alanda fromParam / toParam). Başlangıç tarihi bitişten sonraysa süzgeç uygulanmaz ve ekranda uyarı gösterilir.

Form: <one-form>

js
var form = document.querySelector('one-form')
form.fields = [
  { key: 'title', label: { tr: 'Başlık', en: 'Title' }, type: 'text', required: true, maxLength: 120 },
  { key: 'description', label: { tr: 'Açıklama', en: 'Description' }, type: 'longText' },
  { key: 'amount', label: { tr: 'Tutar', en: 'Amount' }, type: 'money', min: 0 },
  { key: 'dueDate', label: { tr: 'Son tarih', en: 'Due date' }, type: 'date' },
  { key: 'approver', label: { tr: 'Onaylayan', en: 'Approver' }, type: 'person', required: true },
  { key: 'attachment', label: { tr: 'Belge', en: 'Document' }, type: 'file', accept: '.pdf,image/*' },
]
form.value = existingRecord          // düzenleme ekranında; yeni kayıtta atamayın
form.addEventListener('saved', function () { table.reload() })
  • Alan türleri: text, longText, number, money, date, datetime, boolean, choice, person, file (veri modelindeki türlerle aynı). Kurallar: required, minLength, maxLength, min, max, pattern, options, multiple, help, placeholder, readOnly.
  • action verilirse form değeri JSON olarak gönderilir (method POST / PUT / PATCH); sunucu doğrulama hatalarını RFC 9457 errors alanında döndürürse her ileti kendi alanının altında görünür. action yoksa formu siz gönderirsiniz: save olayını dinleyin (e.detail.value). Kaydı kendiniz gönderdiğinizde (action yok ya da save olayında preventDefault() çağırdınız) kayıt başarılı olunca gönderdiğiniz değeri forma geri atayın (form.value = e.detail.value); pencereyi kapatıyorsanız bunu close çağrısından önce yapın. Atanmazsa form kaydedilmemiş sayılır ve Portal, kullanıcı ayrılırken uyarmayı sürdürür. Kayıt başarısızsa atamayın: kullanıcının düzenlemesi korunur.
  • Kaydedilmemiş değişiklik Portal'a bildirilir (kullanıcı ayrılırken uyarılır); Vazgeç değişiklik varsa onay sorar.
  • Vekalet / Yerine Görüntüle oturumunda Kaydet kapalıdır ve nedeni yazılır. Uygulama bu oturumlarda yazmayı bilinçli olarak açtıysa (manifest actingSessions: "write") forma acting-write özniteliğini ekleyin.
  • Sunucu doğrulaması ZORUNLUDUR: tarayıcıdaki doğrulama kullanıcıya kolaylıktır, güvenlik sınırı değildir.

Ekleme ve düzenleme formu liste ekranına çizilmez; <one-dialog> penceresinin içine konur (aşağıda "Ekleme ve düzenleme penceresi").

Kişi seçici: <one-person-picker>

Bileşen uygulamanın kendi ucuna gider; ucu SDK hazırlar. Manifest scopes içinde orgschema.read olmalıdır.

ts
import { PEOPLE_SEARCH_PATH, peopleSearchHandler } from '@devoplus/one-sdk'
if (pathname === PEOPLE_SEARCH_PATH && method === 'GET') return peopleSearchHandler(request, env, ctx)

Sonuç yalnız ad, unvan ve departman taşır (e-posta ve telefon dönmez). Seçilen kişinin id'si organizasyon şeması kimliğidir; bildirim gönderirken toOrgUserIds alanına yazın. Kullanıcının kendi kimliğiyle (ctx.user.sub) karıştırmayın.

Dosya yükleme: <one-file-upload>

Varsayılan olarak POST /api/files ucuna yükler (yeni uygulama iskeletindeki uç). accept ve max-size (bayt) yüklemeden önce denetlenir; sunucu kendi sınırını yine uygular. Değer { key, name, size, contentType }'tır.

Grafik: <one-chart>

js
var chart = document.querySelector('one-chart')
chart.label = { tr: 'Aylık talepler', en: 'Monthly requests' }
chart.data = { labels: ['Ocak', 'Şubat'], series: [{ name: { tr: 'Açılan', en: 'Opened' }, values: [12, 30] }] }

Toplam, ortalama ve yüzde gibi değerleri sunucuda hesaplayın; grafik yalnız çizer. Grafik ekran okuyucuya veri tablosu olarak da okunur.

  • Türler: bar (çubuk), line (çizgi), area (dolgulu çizgi), pie (pasta), doughnut (halka). Pasta ve halka yalnız ilk seriyi çizer (gizli veri tablosu da yalnız onu gösterir); birden çok seri için bar ya da line kullanın. stacked çubukları üst üste, horizontal yatay çizer; size="sm" (220 px) ya da size="lg" (420 px) yüksekliği değiştirir (varsayılan 320 px); unit="adet" değerlerin yanına yazılır.
  • Grafik portaldaki grafiklerle aynı kütüphaneyle (/one-charts.js) çizilir; renkler ve yazı tipi Devoplus görsel dilinden gelir, tema değişince grafik yeniden çizilir.

Gösterge kartı: <one-stat>

Sayı ve durum özetleri (kaç kayıt açık, toplam tutar, süresi geçenler) cümle olarak yazılmaz; her sayı bir gösterge kartıdır. Kartlar one-stat-grid sınıflı bir kutuda dizilir ve dar ekranda alt alta geçer.

html
<div class="one-stat-grid">
  <one-stat id="aktif" label="Aktif poliçe" unit="adet"></one-stat>
  <one-stat id="suresiGecen" label="Süresi geçen" tone="danger"></one-stat>
  <one-stat id="prim" label="Toplam prim" format="money" delta-label="geçen aya göre" delta-polarity="up-good"></one-stat>
</div>
js
document.getElementById('aktif').value = ozet.aktif
document.getElementById('suresiGecen').value = ozet.suresiGecen
var prim = document.getElementById('prim')
prim.value = ozet.toplamPrim
prim.setAttribute('delta', String(ozet.primDegisimYuzde))   // 12.5 gösterilir: "+%12,5"
  • format: number (varsayılan), money (currency, varsayılan TRY), percent, text; decimals ondalık sayısı.
  • delta değişimi oklu simgeyle gösterir (delta-format="number" ile yüzde yerine sayı). Değişim varsayılan olarak nötr renktedir; artış iyiyse delta-polarity="up-good", azalış iyiyse down-good yazın (yeşil/kırmızı).
  • tone kartın vurgusunu verir: primary, success, warn, danger, info (yalnız anlamı olan kartta kullanın).
  • loading veri gelene kadar yükleniyor göstergesi çizer; değer yoksa kart "-" gösterir.
  • clickable kartı düğmeye çevirir ve select olayı yayar (ör. ilgili listeye süzgeçle gitmek için).
  • Etiketler iki dilliyse label, caption ve deltaLabel özelliklerine { tr, en } atayın.

Açılır liste: <one-select>

js
var city = document.querySelector('one-select')
city.options = [
  { value: 'ist', label: { tr: 'İstanbul', en: 'Istanbul' } },
  { value: 'ank', label: 'Ankara', description: 'Başkent' },
  { value: 'izm', label: 'İzmir', disabled: true },
]
city.value = 'ank'            // multiple ile dizi: ['ist', 'ank']
city.addEventListener('change', function (e) { console.log(e.detail.value) })

Yazınca Türkçe harf duyarsız süzer, ok tuşları ve Enter ile seçilir. Kişi seçmek için <one-person-picker>, uzak ve büyük listeler için <one-table> + <one-filter> kullanın; <one-select> en çok 200 seçeneği gösterir.

Etiket girişi: <one-tag-input>

js
var tags = document.querySelector('one-tag-input')
tags.suggestions = ['Bütçe', 'Bordro', 'İzin']   // isteğe bağlı
tags.value = ['Bütçe']

Enter ya da virgül etiket ekler; aynı etiket ikinci kez eklenmez; max (adet) ve max-length (karakter) sınırlarının nedeni kullanıcıya yazılır.

Pencere: <one-dialog>

html
<one-dialog id="duzenle" label="Talebi düzenle">
  <one-form action="/api/requests/42" method="PUT"></one-form>
  <button class="one-btn" type="button" data-one-close data-one-dialog-footer>Kapat</button>
</one-dialog>
js
var result = await document.getElementById('duzenle').show()   // '' = vazgeçildi
  • Pencere iframe'in görünen kısmında açılır; açıkken Portal da kendi ekranını karartır. Kullanıcı Portal'ın karartılmış alanına tıklarsa ya da Escape'e basarsa pencere "vazgeçildi" diye kapanır (cancel olayı, reason: "portal"). Penceredeki <one-form>'da kaydedilmemiş değişiklik varsa soruyu bileşen kendisi sorar (aşağıdaki madde) ve cancel olayı ancak kullanıcı değişiklikleri atmayı kabul ettikten sonra gelir; bu yüzden cancel olayında ikinci bir soru sormayın ve preventDefault() çağırmayın, yoksa kullanıcının kabul ettiği kapanma geri çevrilir. preventDefault() yalnız <one-form> dışında tuttuğunuz bir durum için (ör. süren bir yükleme) pencereyi açık tutar.
  • Ekleme ve düzenleme penceresi: <one-form> pencerenin içine konur. Form kaydedilince pencere 'saved' ile, formda Vazgeç'e basılınca '' ile kendiliğinden kapanır (keep-open özniteliği bunu kapatır). Kayıt sürerken formda yeni bir değişiklik yapılmışsa pencere kapanmaz: o değişiklik gönderilmemiştir ve görünür kalır. Formda kaydedilmemiş değişiklik varken pencere kapatılmak istenirse (Escape, kapat düğmesi, karartmaya tıklama) önce "değişiklikler kaybolacak" onayı sorulur; kabul edilirse form son kaydedilen haline döner. Altbilgideki değersiz data-one-close düğmesi ("Kapat") de vazgeçme sayılır ve aynı soruyu sorar; değerli olan (data-one-close="tamam") sonuç olarak doğrudan kapatır.
    js
    var penc = document.getElementById('talepPenceresi'), form = document.getElementById('talepFormu')
    document.getElementById('yeniTalep').addEventListener('click', function () {
      form.setAttribute('action', '/api/requests'); form.setAttribute('method', 'POST')
      form.value = {}
      penc.label = { tr: 'Yeni talep', en: 'New request' }
      penc.show()
    })
    table.addEventListener('rowclick', function (e) {
      form.setAttribute('action', '/api/requests/' + encodeURIComponent(e.detail.row.id)); form.setAttribute('method', 'PATCH')
      form.value = e.detail.row
      penc.label = { tr: 'Talebi düzenle', en: 'Edit request' }
      penc.show()
    })
    form.addEventListener('saved', function () { table.reload() })   // pencere kendiliğinden kapanır
  • Onay penceresi: accept-label ve reject-label verin (severity="danger" silme gibi işlemler için); show() 'accept' ya da 'reject' döner. Portal içindeyken bu pencere Portal'ın kendi onay penceresiyle sorulur ve içerik DÜZ METİN olarak gider; onay iletisini kısa ve düz yazın. Biçimli içerikli bir soru gerekiyorsa onay öznitelikleri olmadan genel pencere kullanın, düğmeleri data-one-close="evet" gibi kendiniz koyun.
  • Basit evet/hayır için await one.confirm({ message, severity: 'danger', acceptLabel: 'Sil' }) yeterlidir.

Silme ve pasife alma (zorunlu kural)

One uygulamalarında silme her zaman yumuşaktır ve silme ile pasife alma her zaman onay penceresi ister. one-ci bu iki kuralı yayında tarar ve uymayan kalıbı uyarı olarak gösterir; yayın sürer. Kural yine zorunludur: tarama bir sözdizimi taramasıdır, her biçimi yakalamaz ve bazen yanlış uyarı verir, bu yüzden yayını durdurmaz. Uyarıyı yok saymayın; yanlış uyarıysa aşağıdaki gerekçeli yorumla kapatın.

  • Silme: kaydı yok etmeyin, deleted_at alanını doldurun. Hazır veri katmanı (createCrudHandler) bunu kendisi yapar. Kodda ya da migrations/ altındaki bir SQL dosyasında DELETE FROM görülürse (büyük ya da küçük harf; iki sözcük arasında SQL yorumu olsa da, tablo adı kodla kurulsa da) uyarı verilir.
  • Silme isteği: one.remove('/api/kayitlar/' + id, { message: 'Kayıt silinecek. Devam etmek istiyor musunuz?' }) kullanın. Önce Portal'ın onay penceresini açar, kullanıcı kabul ederse DELETE gönderir ve yanıtı döner; vazgeçerse null döner ve istek gitmez. Onay sorulmadan gönderilen DELETE isteği uyarı verir. Kendi onayınızı soruyorsanız istek onayın kabul dalında olmalı ya da ret dalı işlevden çıkmalıdır (if (ok === false) return gibi karşılaştırmalı yazım da kabul edilir; onay sonucunu tutan değişkene sonradan başka değer atanırsa, sonuca bir işlem eklenirse (|| true) ya da aynı ad iç bir işlevin parametresi olursa onay sayılmaz; ok && audit(), fetch(...) geçmez, çünkü virgülden sonraki istek onaydan bağımsız çalışır; if (!ok) return fetch(...) de geçmez, çünkü istek ret dalının kendisidir; onay koşulsuz sorulmalıdır, if (x) ok = await one.confirm(...) sayılmaz); axios.delete(...), axios?.delete(...) ya da axios['delete'](...) gibi HTTP istemcisi çağrıları, tür açıklamalı yöntem değişkeni (const method: string = 'DELETE') ve parçalardan birleşen yöntem ('DE' + 'LETE') de silme isteği sayılır. Şablon dizgisinde yazılan sayfa betiğinin TAMAMI yorum olan satırı yorum sayılır.
  • Pasife alma: <one-form> düzenlenen kayıtta (method PATCH ya da PUT) active ya da is_active adlı açık/kapalı alanı açıktan kapalıya çevrilince kaydetmeden önce onay sorar. Başka adlı bir alan için alan tanımına confirmOff: { tr: '...', en: '...' } yazın. Pasife almayı kendi düğmenizle yapıyorsanız önce one.confirm(...) sorun.
  • İstisna: kalıcı silme ya da onaysız istek gerçekten gerekiyorsa (ya da uyarı yanlışsa) aynı ya da bir önceki satıra gerekçeli YORUM yazın; yorum uyarıyı kapatır: // one-allow-hard-delete: <en az 10 karakter gerekçe> ya da // one-allow-unconfirmed-delete: <gerekçe>; migration dosyasında -- one-allow-hard-delete: <gerekçe>. İşaret yalnız yorumda geçerlidir ve gerekçe yorumun kendi metninden sayılır (bir dizenin içindeki işaret ya da yorumdan sonra gelen kod sayılmaz; yalnız boşluk ya da beş emoji on karakter değildir). Uygulanmış bir migration'a yalnız yorum eklemek o migration'ı değişmiş saymaz. Veri modelinde (one.data.json ya da createCrudHandler'a koddan verilen model) kalıcı silme "softDelete": false ile birlikte "hardDeleteReason": "<gerekçe>" ister; gerekçesiz model kayıt uçlarında yapılandırma hatası verir ve one data generate durur. Bu kural uyarı değildir: model bir beyandır, tarama değildir.

Simgeler

Simge olarak emoji ya da ok/üçgen karakteri (çift yönlü ok, ▲, ▼, ×, ✓) kullanmayın: bazı platformlarda renkli emoji olarak çizilir ve Portal'la uyumsuz görünür. Hazır bileşenler kendi simgelerini SVG olarak çizer; kendi simgeniz gerekiyorsa satır içi <svg> (çizgi rengi currentColor) kullanın. one-ci tek başına simge olarak kullanılan bu karakterleri uyarır; CSS'te content: '×' gibi çizilen karakter de aynı uyarıyı alır.

Bildirim

Ayrı bileşen yoktur: one.toast({ severity: 'success', summary: 'Kaydedildi' }). Portal içinde Portal çizer; yerel geliştirmede sayfanın köşesinde görünür.

İpucu, eylem menüsü, avatar

html
<one-tooltip text="En çok 20 karakter" text-en="At most 20 characters"><button class="one-btn one-btn-text" type="button">?</button></one-tooltip>
<one-menu id="satir" compact label="Satır işlemleri"></one-menu>
<one-avatar name="Şule Yıldız" src="/api/photo/42"></one-avatar>
js
var menu = document.getElementById('satir')
menu.items = [{ id: 'edit', label: { tr: 'Düzenle', en: 'Edit' } }, { separator: true }, { id: 'delete', label: { tr: 'Sil', en: 'Delete' }, danger: true }]
menu.addEventListener('select', function (e) { if (e.detail.id === 'delete') removeRow() })

İpucunun tetikleyicisi odaklanabilir olmalıdır (düğme, bağlantı); önemli bilgiyi ipucuna koymayın.

Sekmeler ve akordeon

html
<one-tabs label="Talep ayrıntısı">
  <section data-label="Genel" data-label-en="General">...</section>
  <section data-label="Geçmiş" data-label-en="History" data-tab="history">...</section>
</one-tabs>
<one-accordion>
  <div data-label="Kimler görebilir?" data-open>...</div>
  <div data-label="Veriler nerede?">...</div>
</one-accordion>

Sekmeler içerik içi gruplama içindir; uygulamanın sayfaları için Portal menüsünü (navigation) kullanın.

Ayrıntı

Bütün özellikler, öznitelikler, olaylar ve tipler: SDK başvurusu içinde "Hazır arayüz bileşenleri". Görsel dil ve köprü: aynı belgede "Portal köprüsü ve görsel dil".

Bu konunun yapay zeka araçları için yazılmış sürümü (Markdown): /docs/ui-components.md

Fikrinizi uygulamaya dönüştürmeye hazır mısınız?

Kurulum metnini yapay zeka aracınıza yapıştırın; aracınız önce ne yapmak istediğinizi sorar.