Toast bileşeni oluşturma

Uyarlanabilir ve erişilebilir durum mesajı bileşeninin nasıl oluşturulacağına dair temel bir genel bakış.

Bu gönderide, bir durum mesajı bileşeni oluşturma ile ilgili düşüncenizi paylaşmak istiyorum. Şunu deneyin: demo.

Demo

Video kullanmayı tercih ederseniz bu gönderinin YouTube versiyonunu kullanabilirsiniz:

Genel Bakış

Kısa iletiler, kullanıcılara yönelik etkileşimsiz, pasif ve eşzamansız kısa mesajlardır. Bunlar genellikle kullanıcıyı bilgilendirmek için bir arayüz geri bildirim kalıbı olarak kullanılır bir eylemin sonuçları hakkında.

Etkileşimler

Kısa iletiler bildirimlerden farklıdır. uyarılar ve istemler çünkü etkileşimli değildir; kapatılmak veya ısrar etmek amaçlanmamıştır. Bildirimler daha önemli bilgiler sağlar, eşzamanlı mesajlaşmayı kullanarak etkileşim veya sistem düzeyinde mesajlar (sayfa düzeyi yerine) gerektirir. Kısa mesajlar diğer bildirim stratejilerinden daha pasiftir.

Brüt kar

İlgili içeriği oluşturmak için kullanılan <output> öğesi, tost için iyi bir seçimdir çünkü okuyucular. Doğru HTML, JavaScript ile geliştirmemiz için güvenli bir temel sağlar ve ve çok sayıda JavaScript bulunacak.

Kadeh kaldırın

<output class="gui-toast">Item added to cart</output>

Daha fazla dahil role="status" ekleyerek. Bu, kullanıcılara tarayıcı <output> öğelerine dolaylı rol bakın.

<output role="status" class="gui-toast">Item added to cart</output>

Tost kutusu

Aynı anda birden fazla durum mesajı gösterilebilir. Birden fazla öğeyi aynı anda bir kap kullanılır. Bu kapsayıcı, aynı zamanda kısa kadeh kaldırın.

<section class="gui-toast-group">
  <output role="status">Wizard Rose added to cart</output>
  <output role="status">Self Watering Pot added to cart</output>
</section>

Düzenler

Tostları inset-block-end eklenir ve daha fazla kısa mesaj eklenirse, bunlar ekran kenarından üst üste yığılır.

GUI kapsayıcısı

Kısa ileti kapsayıcısı, kısa mesajları sunmak için gereken tüm düzen çalışmalarını yapar. İnsanların fixed öğesini görüntü alanına ekler ve mantıksal özelliği kullanır inset ile sabitlenecek kenarlara ek olarak aynı block-end kenarından biraz padding ekleyin.

.gui-toast-group {
  position: fixed;
  z-index: 1;
  inset-block-end: 0;
  inset-inline: 0;
  padding-block-end: 5vh;
}

Geliştirici Araçları kutu boyutunun ve dolgusunun .gui-toast-container öğesinin üzerine yerleştirildiği ekran görüntüsü.

Bildirim kapsayıcısı, kendisini görüntü alanının içinde konumlandırmanın yanı sıra, tostları hizalayıp dağıtabilen ızgara kapsayıcısı. Öğeler aşağıdaki gibi ortalanır: justify-content içeren ve justify-items ile ayrı ayrı ortalanmış. Kadehlerin dokunmaması için biraz gap atın.

.gui-toast-group {
  display: grid;
  justify-items: center;
  justify-content: center;
  gap: 1vh;
}

Durum mesajı grubunda CSS ızgara yer paylaşımı içeren ekran görüntüsü (bu sefer)
alt öğeler arasındaki boşluğu ve boşlukları vurgulayarak.

GUI Kısaltması

Bir tostun biraz padding, bazı köşeleri daha yumuşak border-radius, ve bir min() fonksiyonu yardımcı olabilir. Aşağıdaki CSS'deki duyarlı boyut kısa mesaj ek açıklamalarının görüntü alanının% 90'ından fazlasını 25ch.

.gui-toast {
  max-inline-size: min(25ch, 90vw);
  padding-block: .5ch;
  padding-inline: 1ch;
  border-radius: 3px;
  font-size: 1rem;
}

Dolgu ve kenarlık içeren tek bir .gui-toast öğesinin ekran görüntüsü
yarıçap gösteriliyor.

Stiller

Düzen ve konumlandırma ayarlandığında kullanıcıya uyum sağlamanıza yardımcı olacak CSS'yi ekleyin Ayarlar ve etkileşimler.

Tost kabı

Kısa mesajlar etkileşimli değildir, bunlara dokunmak veya hızlıca kaydırmak bir şey yapmaz, ancak kullanıcılar işaretçi etkinliklerini kullanır. Tostların çalmasını önleyin aşağıdaki CSS ile yapılan tıklama sayısı.

.gui-toast-group {
  pointer-events: none;
}

GUI Kısaltması

Kısa açıklamalar özel özellikler, HSL ve tercih edilen medya sorgusudur.

.gui-toast {
  --_bg-lightness: 90%;

  color: black;
  background: hsl(0 0% var(--_bg-lightness) / 90%);
}

@media (prefers-color-scheme: dark) {
  .gui-toast {
    color: white;
    --_bg-lightness: 20%;
  }
}

Animasyon

Yeni bir kısa mesaj, ekrana girerken animasyonla görünmelidir. translate değerlerinin 0 değerine ayarlanmasıyla azalan hareketi karşılamaya olanak tanır. varsayılan olarak ancak bir hareket tercihi medyasında hareket değerinin bir uzunluğa güncellenmesi sorgu . Animasyonlar herkes tarafından görüntüleniyor, ancak bazı kullanıcılarda hesaplayabilirsiniz.

Burada, durum mesajı animasyonu için kullanılan animasyon kareleri gösterilmektedir. CSS, kontrol panelinde giriş, bekleme ve kısa mesaj çıkışını tek bir animasyonda bulabilirsiniz.

@keyframes fade-in {
  from { opacity: 0 }
}

@keyframes fade-out {
  to { opacity: 0 }
}

@keyframes slide-in {
  from { transform: translateY(var(--_travel-distance, 10px)) }
}

Ardından, durum mesajı öğesi değişkenleri ayarlar ve animasyon karelerini düzenler.

.gui-toast {
  --_duration: 3s;
  --_travel-distance: 0;

  will-change: transform;
  animation: 
    fade-in .3s ease,
    slide-in .3s ease,
    fade-out .3s ease var(--_duration);
}

@media (prefers-reduced-motion: no-preference) {
  .gui-toast {
    --_travel-distance: 5vh;
  }
}

JavaScript

Stiller ve ekran okuyucu tarafından erişilebilir HTML hazır olduğunda, kullanıcıya bağlı olarak tostların oluşturulmasını, eklenmesini ve imha edilmesini düzenler etkinlikler. Durum mesajı bileşeninin geliştirici deneyimi minimum düzeyde olmalıdır ve aşağıdaki gibi kolayca başlayabilirsiniz:

import Toast from './toast.js'

Toast('My first toast')

Kısa mesaj grubu ve kısa iletiler oluşturuluyor

Toast modülü JavaScript'ten yüklendiğinde bir durum mesajı kapsayıcısı oluşturmalıdır ve sayfaya ekleyin. Öğeyi body tarihinden önce eklemeyi seçtim. Bu işlem Kapsayıcı şu kadar süre boyunca kapsayıcının üzerinde olduğundan, z-index yığma sorunu olması pek olası değil tüm gövde öğeleri.

const init = () => {
  const node = document.createElement('section')
  node.classList.add('gui-toast-group')

  document.firstElementChild.insertBefore(node, document.body)
  return node
}

Başlık ve gövde etiketleri arasındaki bildirim grubunun ekran görüntüsü.

init() işlevi, modülün içinde çağrılmakta ve öğe depolanmaktadır. Toaster olarak:

const Toaster = init()

Toast HTML öğesi oluşturma işlemi createToast() işleviyle yapılır. İlgili içeriği oluşturmak için kullanılan işlevi, durum mesajı için bazı metin gerektirir, bir <output> öğesi oluşturur ve metni bazı sınıflar ve özelliklerle ekler, metni ayarlar ve düğümü döndürür.

const createToast = text => {
  const node = document.createElement('output')
  
  node.innerText = text
  node.classList.add('gui-toast')
  node.setAttribute('role', 'status')

  return node
}

Bir veya daha fazla ileti dizisini yönetmek

JavaScript artık dokümana tostlar içeren bir kapsayıcı ekler ve hazır tostlar eklenmeye hazır. addToast() işlevi, birini işlemeyi düzenler kadeh kaldırın. Önce kadeh kaldırma sayısını ve hareketin uygun olup olmadığını kontrol edin bu bilgileri kullanarak kadeh kaldırın Böylece diğer kısa mesajlar "yer aç"mış gibi görünür. yeni kadeh kaldırın.

const addToast = toast => {
  const { matches:motionOK } = window.matchMedia(
    '(prefers-reduced-motion: no-preference)'
  )

  Toaster.children.length && motionOK
    ? flipToast(toast)
    : Toaster.appendChild(toast)
}

İlk kızarmış ekstreyi eklerken Toaster.appendChild(toast), CSS animasyonlarını tetikleyen sayfa: animasyon ekle, 3s bekle, canlandır. flipToast(), bir teknik kullanılarak mevcut durum iletileri olduğunda çağrılır adı FLIP - Paul Lewis'a dokunun. Buradaki fikir, aradaki farkın yeni durum mesajı eklenmeden önce ve eklendikten sonra yer alır. Bunu, ekmek kızartma makinesinin şu anda nerede olduğunu ve nereye gideceğini işaretlemek gibi düşünün. animasyon oluşturma çabasıdır.

const flipToast = toast => {
  // FIRST
  const first = Toaster.offsetHeight

  // add new child to change container size
  Toaster.appendChild(toast)

  // LAST
  const last = Toaster.offsetHeight

  // INVERT
  const invert = last - first

  // PLAY
  const animation = Toaster.animate([
    { transform: `translateY(${invert}px)` },
    { transform: 'translateY(0)' }
  ], {
    duration: 150,
    easing: 'ease-out',
  })
}

Düzeni kaldırma işlemini CSS ızgarası yapar. Yeni bir tost eklendiğinde, ızgara tarafından konur en başa ekleyin ve diğerleriyle boşluklar belirleyin. Aynı zamanda, web'de animasyon kapsayıcıya eski konumdan animasyon eklemek için kullanılır.

Tüm JavaScript kodlarını bir araya getirme

Toast('my first toast') çağrıldığında bir durum mesajı oluşturulur ve sayfaya eklenir (belki de kapsayıcı yeni kadrajı yansıtacak şekilde canlandırılıyor olabilir), vadet döndürülür ve oluşturulan kısa mesaj izlendi: Söz konusu çözünürlük için CSS animasyon tamamlama (üç animasyon karesi animasyonu).

const Toast = text => {
  let toast = createToast(text)
  addToast(toast)

  return new Promise(async (resolve, reject) => {
    await Promise.allSettled(
      toast.getAnimations().map(animation => 
        animation.finished
      )
    )
    Toaster.removeChild(toast)
    resolve() 
  })
}

Bu kodun kafa karıştırıcı kısmının Promise.allSettled() işlevinde olduğunu hissettim ve toast.getAnimations() eşleme. Birden fazla animasyon karesi animasyonu kullandığımdan kadeh kaldırma için, hepsinin bittiğini emin olmak için, her birinin JavaScript'ten istendiğinde finished vaatleri yerine getirmek için kullanılır. allSettled ve tüm vaatlerinden sonra kendini tamamlanmış olarak çözüme kavuşturmak bizim için işe yarıyor mu? karşılandı. await Promise.allSettled() kullanılması, kod, öğeyi güvenli bir şekilde kaldırabilir ve kısa iletinin yaşam döngüsü boyunca geçerlidir. Son olarak, resolve() işlevinin çağrılması üst düzey Toast vaadini yerine getirir. geliştiriciler, durum mesajı gösterildikten sonra temizlik yapabilir veya başka işlemler yapabilir.

export default Toast

Son olarak, Toast işlevi modülden dışa aktarılır. içe aktarmanızı sağlar.

Toast bileşenini kullanma

Toast veya kısa ileti'nin geliştirici deneyimi, Toast işlevini kullanıp bir mesaj dizesiyle çağırabilirsiniz.

import Toast from './toast.js'

Toast('Wizard Rose added to cart')

Geliştirici, işi temizlemek gibi bir şey isterse, eş zamansız ve bekleyin.

import Toast from './toast.js'

async function example() {
  await Toast('Wizard Rose added to cart')
  console.log('toast finished')
}

Sonuç

Şimdi bunu nasıl yaptığımı öğrendiğinize göre siz nasıl ‽ 🙂

Gelin, yaklaşımlarımızı çeşitlendirelim ve web'de içerik geliştirmenin tüm yollarını öğrenelim. Bir demo oluşturup beni tweet'le bağlantıları eklerim aşağıdaki topluluk remiksleri bölümüne gidin!

Topluluk remiksleri