Bu gönderide, bir tost bileşeninin nasıl oluşturulacağı konusundaki düşüncemi paylaşmak istiyorum. deneyin gösteri.
Videoyu tercih ederseniz, işte bu gönderinin bir YouTube versiyonu:
genel bakış #
Tostlar, kullanıcılar için etkileşimli olmayan, pasif ve eşzamansız kısa mesajlardır. Genel olarak, kullanıcıyı bir eylemin sonuçları hakkında bilgilendirmek için bir arayüz geri bildirim modeli olarak kullanılırlar.
Etkileşimler #
Tostlar bildirimlerden farklıdır, uyarılar Ve istemler çünkü etkileşimli değiller; göz ardı edilmeleri veya ısrar edilmeleri amaçlanmamıştır. Bildirimler daha önemli bilgiler, etkileşim gerektiren eşzamanlı mesajlaşma veya (sayfa düzeyinde değil) sistem düzeyinde mesajlar içindir. Tostlar, diğer bildirim stratejilerinden daha pasiftir.
işaretleme #
bu <output>
element, ekran okuyucularına duyurulduğu için tost için iyi bir seçimdir. Doğru HTML, JavaScript ve CSS ile geliştirmemiz için güvenli bir temel sağlar ve çok sayıda JavaScript olacaktır.
Bir tost #
output class="gui-toast">Item added to cart</output>
Olabilir daha kapsayıcı toplayarak role="status"
. Tarayıcı vermezse bu bir geri dönüş sağlar <output>
elementler örtük rol spesifikasyona göre
output role="status" class="gui-toast">Item added to cart</output>
Bir tost kabı #
Aynı anda birden fazla tost gösterilebilir. Birden çok tostu düzenlemek için bir kap kullanılır. Bu kap ayrıca tostların ekrandaki konumunu da yönetir.
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ı iğnelemeyi seçtim inset-block-end
ve daha fazla tost eklenirse, o ekran kenarından istiflenirler.
GUI kabı #
Tost kabı, tostları sunmak için tüm yerleşim düzenini yapar. Onun fixed
görünüm alanına ve mantıksal özelliği kullanır inset
hangi kenarların sabitleneceğini belirtmek için artı biraz padding
aynısından block-end
kenar.
.gui-toast-group {
position: fixed;
z-index: 1;
inset-block-end: 0;
inset-inline: 0;
padding-block-end: 5vh;
}
Kızartma kabı, kendisini görünüm alanı içinde konumlandırmanın yanı sıra, tostları hizalayabilen ve dağıtabilen bir ızgara kabıdır. Öğeler, bir grup olarak ortalanır. justify-content
ve bireysel merkezli justify-items
. biraz içine at gap
böylece tostlar birbirine değmez.
.gui-toast-group {
display: grid;
justify-items: center;
justify-content: center;
gap: 1vh;
}
GUI Tost #
Bireysel tost biraz var padding
bazı daha yumuşak köşeler border-radius
ve bir min()
mobil ve masaüstü boyutlandırmaya yardımcı olacak işlev. Aşağıdaki CSS’deki duyarlı boyut, tostların görünümün %90’ından daha fazla büyümesini engeller veya 25ch
.
.gui-toast {
max-inline-size: min(25ch, 90vw);
padding-block: .5ch;
padding-inline: 1ch;
border-radius: 3px;
font-size: 1rem;
}
stiller #
Düzen ve konumlandırma ayarlıyken, kullanıcı ayarlarına ve etkileşimlerine uyum sağlamaya yardımcı olan CSS’yi ekleyin.
Tost kabı #
Tostlar etkileşimli değildir, üzerlerine dokunmak veya kaydırmak hiçbir şey yapmaz, ancak şu anda işaretçi olaylarını tüketirler. Aşağıdaki CSS ile tostların tıklama çalmasını önleyin.
.gui-toast-group {
pointer-events: none;
}
GUI Tost #
Tostlara özel özellikler, HSL ve bir tercih medya sorgusu ile açık veya koyu uyarlanabilir bir tema verin.
.gui-toast {
--_bg-lightness: 90%;color: black;
background: hsl(0 0% var(--_bg-lightness) / 90%);
}
TheComedicComedian (prefers-color-scheme: dark) {
.gui-toast {
color: white;
--_bg-lightness: 20%;
}
}
Animasyon #
Yeni bir tost, ekrana girerken kendisini bir animasyonla sunmalıdır. Azaltılmış harekete uyum sağlamak ayar ile yapılır translate
değerler 0
varsayılan olarak, ancak hareket değerini bir hareket tercihi ortam sorgusunda bir uzunluğa güncellemek. Herkes biraz animasyon alır, ancak yalnızca bazı kullanıcılar tostun mesafe kat etmesini sağlar.
İşte tost animasyonu için kullanılan anahtar kareler. CSS, hepsi tek bir animasyonda tostun girişini, beklemesini ve çıkışını kontrol edecek.
@keyframes fade-in {
from { opacity: 0 }
}@keyframes fade-out {
to { opacity: 0 }
}
@keyframes slide-in {
from { transform: translateY(var(--_travel-distance, 10px)) }
}
Tost öğesi daha sonra değişkenleri ayarlar ve ana kareleri 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);
}
TheComedicComedian (prefers-reduced-motion: no-preference) {
.gui-toast {
--_travel-distance: 5vh;
}
}
JavaScript #
Stiller ve ekran okuyucu tarafından erişilebilir HTML hazırlığıyla, kullanıcı etkinliklerine dayalı olarak tostların oluşturulmasını, eklenmesini ve yok edilmesini düzenlemek için JavaScript gerekir. Tost bileşeninin geliştirici deneyimi minimum düzeyde olmalı ve aşağıdaki gibi başlaması kolay olmalıdır:
import Toast from './toast.js'Toast('My first toast')
Tost grubu ve tost oluşturma #
Toast modülü JavaScript’ten yüklendiğinde, bir tost kabı oluşturmalı ve bunu sayfaya eklemelidir. Öğeyi daha önce eklemeyi seçtim body
bu yapacak z-index
Kap, tüm gövde öğeleri için kabın üzerinde olduğundan istifleme sorunları olası değildir.
const init = () => {
const node = document.createElement('section')
node.classList.add('gui-toast-group')document.firstElementChild.insertBefore(node, document.body)
return node
}
bu init()
işlevi modüle dahili olarak çağrılır ve öğe şu şekilde depolanır: Toaster
:
const Toaster = init()
Toast HTML öğesi oluşturma, createToast()
işlev. İşlev, tost için biraz metin gerektirir, bir <output>
element, onu bazı sınıflar ve niteliklerle süsler, 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 tostu yönetme #
JavaScript artık tostları içermesi için belgeye bir kapsayıcı ekliyor ve oluşturulan tostları eklemeye hazır. bu addToast()
işlev, bir veya daha fazla tostun işlenmesini düzenler. Önce tost sayısını ve hareketin iyi olup olmadığını kontrol edin, ardından bu bilgiyi ya tostu eklemek için kullanın ya da diğer tostların yeni tost için “yer açacak” gibi görünmesi için bazı süslü animasyonlar yapın.
const addToast = toast => {
const { matches:motionOK } = window.matchMedia(
'(prefers-reduced-motion: no-preference)'
)Toaster.children.length && motionOK
? flipToast(toast)
: Toaster.appendChild(toast)
}
İlk tostu eklerken, Toaster.appendChild(toast)
CSS animasyonlarını tetikleyen sayfaya bir tost ekler: canlandırın, bekleyin 3s
canlandırın. flipToast()
adı verilen bir teknik kullanılarak mevcut tostlar olduğunda çağrılır. ÇEVİRME ile paul lewis. Fikir, yeni tost eklendikten önce ve sonra kabın konumlarındaki farkı hesaplamaktır. Tost makinesinin şu anda nerede olduğunu, nerede olacağını işaretlemek, ardından eski konumundan şu an olduğu yere animasyon yapmak gibi düşünün.
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',
})
}
CSS ızgarası, mizanpajın kaldırılmasını sağlar. Yeni bir tost eklendiğinde, ızgara onu başa koyar ve diğerleriyle birlikte boşluk bırakır. bu arada bir web animasyonu kabı eski konumundan canlandırmak için kullanılır.
Tüm JavaScript’i bir araya getirmek #
Ne zaman Toast('my first toast')
çağrılır, bir tost oluşturulur, sayfaya eklenir (belki kapsayıcı bile yeni tostu yerleştirmek için canlandırılır), bir söz iade edilir ve oluşturulan tost izledim vaat çözümü için CSS animasyonunun tamamlanması (üç ana kare 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 içinde olduğunu hissettim. Promise.allSettled()
işlev ve toast.getAnimations()
haritalama. Tost için birden çok ana kare animasyonu kullandığım için, hepsinin bittiğini güvenle bilmek için her biri JavaScript’ten ve her birinin finished
yerine getirilmesi için tutulan sözler. allSettled
bu bizim için işe yarar mı, tüm vaatleri yerine getirildikten sonra kendini tamamlanmış olarak çözer. kullanma await Promise.allSettled()
sonraki kod satırının öğeyi güvenle kaldırabileceği ve tostun yaşam döngüsünü tamamladığını varsayabileceği anlamına gelir. Son olarak, arama resolve()
üst düzey Toast vaadini yerine getirir, böylece geliştiriciler tost gösterildikten sonra temizlik yapabilir veya başka işler yapabilir.
export default Toast
son, Toast
işlev, diğer komut dosyalarının içe aktarılması ve kullanılması için modülden dışa aktarılır.
Toast bileşenini kullanma #
Tostun veya tostun geliştirici deneyiminin kullanılması, Toast
işlev ve onu bir mesaj dizesiyle çağırmak.
import Toast from './toast.js'Toast('Wizard Rose added to cart')
Geliştirici, tost gösterildikten sonra temizlik işi veya başka bir şey yapmak isterse, async’i kullanabilir ve beklemek.
import Toast from './toast.js'async function example() {
await Toast('Wizard Rose added to cart')
console.log('toast finished')
}
Çözüm #
Artık nasıl yaptığımı bildiğine göre, nasıl yapardın‽ 🙂
Yaklaşımlarımızı çeşitlendirelim ve web üzerinde oluşturmanın tüm yollarını öğrenelim. Bir demo oluşturun, beni tweetle bağlantılar ve onu aşağıdaki topluluk remiksleri bölümüne ekleyeceğim!