Tworzenie komponentu toastu

Podstawowe omówienie tworzenia adaptacyjnego i przystępnego komponentu toast.

W tym poście przedstawię sposoby tworzenia komponentu toast. Wypróbuj demo.

Demonstracja
.

Jeśli wolisz film, oto wersja tego posta w YouTube:

Omówienie

Komunikaty to nieinteraktywne, pasywne i asynchroniczne krótkie wiadomości skierowane do użytkowników. Zasadniczo służą one jako wzorzec do przekazywania informacji zwrotnych dla użytkownika o wynikach działań.

Interakcje

Powiadomienia to coś innego niż powiadomienia, alerty oraz podpowiedzi, ponieważ nie są interaktywne; nie należy ich odrzucać ani utrzymywać. Powiadomienia służą do przekazywania ważnych informacji, synchronicznego przesyłania komunikatów wymaga interakcji lub komunikatów na poziomie systemu (a nie na poziomie strony). Tosty są bardziej pasywne niż inne strategie powiadamiania o zbieraniu danych.

Markup

<output> to dobry wybór w przypadku toastu, ponieważ informuje on, że ma się pojawić na ekranie. czytelników. Prawidłowy kod HTML to dla nas bezpieczna baza do ulepszania języka JavaScript i CSS i dużo JavaScriptu.

Tost

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

Może być bardziej włącznie po dodaniu role="status". Zapewnia to zastępcza, jeśli przeglądarka nie przekaże elementom <output> wartości domyślnej rola zgodnie ze specyfikacją.

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

Tosta

Jednocześnie może być wyświetlany więcej niż jeden tost. Aby zarządzać wieloma tosty, używany jest pojemnik. Ten kontener obsługuje również położenie elementów wyświetlanie powiadomień na ekranie.

<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>

Układy

przypinałem tosty inset-block-end i jeśli dodano więcej powiadomień, są one nakładane od krawędzi ekranu.

Kontener GUI

Kontener toatów wykonuje wszystkie zadania związane z układem prezentacji. Jest fixed do widocznego obszaru i używa właściwości logicznej. inset, aby określić, krawędzie do przypięcia oraz trochę padding od tej samej krawędzi block-end.

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

Zrzut ekranu z rozmiarem pola w Narzędziach deweloperskich i dopełnieniem nałożonym na element .gui-toast-container.

Pozycja ta sama nie tylko w widocznym obszarze, ale i w jednym z funkcji: kontener siatki, który może wyrównywać i rozpowszechniać powiadomienia. Elementy są wyśrodkowane jako grupa z justify-content i pojedynczo wyśrodkowana z justify-items. Dodaj trochę gap, żeby tosty nie dotknęły.

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

Zrzut ekranu z nakładką siatki CSS w grupie powiadomień, tym razem
uwydatnienia odstępów i luk między wyświetlanymi elementami podrzędnymi.

Tosty GUI

W pojedynczym toście jest padding, a w niektórych łagodniejsze rogi border-radius, i min(), aby pomagają w dostosowaniu rozmiarów telefonów i komputerów. Rozmiar elastyczny w tym kodzie CSS zapobiega rozszerzaniu się tostów na więcej niż 90% widocznego obszaru lub 25ch

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

Zrzut ekranu przedstawiający pojedynczy element .gui-toast z dopełnieniem i obramowaniem
widoczny jest promień.

Style

Po ustawieniu układu i pozycjonowania dodaj CSS, który pomaga dostosować ustawieniach i interakcjach.

Tost

Tosty nie są interaktywne. Klikanie czy przesuwanie palcem po nich nie ma sensu, ale wykorzystują zdarzenia wskaźników. Nie dopuść do kradzieży toatów z tą usługą porównywania cen.

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

Tosty GUI

Nadaj wzniesieniom jasny lub ciemny motyw adaptacyjny za pomocą właściwości niestandardowych, HSL i w zapytaniu o wybrane media.

.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%;
  }
}

Animacja

Nowy tost powinien wyświetlać się w postaci animacji w momencie, gdy pojawia się na ekranie. Zmniejszony ruch można dostosować, ustawiając translate na 0 przez , ale zaktualizowanie wartości ruchu do określonej długości w multimediach z preferencjami ruchu . Każdy otrzyma jakąś animację, ale tylko niektórzy użytkownicy na odległość.

Tutaj są klatki kluczowe używane w animacji wyświetlanej w wyskakującym okienku. CSS będzie kontrolować wejście, oczekiwanie i wyjście z tosty – wszystko w jednej animacji.

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

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

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

Następnie ustawia zmienne i administruje klatkami kluczowymi.

.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

Gdy style i kody HTML są gotowe do użycia w czytniku ekranu, JavaScript jest potrzebny, administruje tworzeniem, dodawaniem i zniszczeniem powiadomień na podstawie użytkownika zdarzeń. Doświadczenie programisty związane z komponentem powiadomienia powinno być minimalne, można łatwo rozpocząć, na przykład tak:

import Toast from './toast.js'

Toast('My first toast')

Tworzenie grupy powiadomień i powiadomień

Podczas wczytywania modułu powiadomień JavaScript za pomocą JavaScriptu musi on utworzyć kontener toastu. i dodaj go do strony. Zdecydowałem dodać element przed body, dzięki czemu Problemy z układem (z-index) są mało prawdopodobne, ponieważ kontener znajduje się nad kontenerem wszystkie elementy.

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

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

Zrzut ekranu pokazujący grupę powiadomień między tagami nagłówka i treści.

Funkcja init() jest wywoływana wewnętrznie dla modułu i umieszczona w miejscu, w którym znajduje się element. jako Toaster:

const Toaster = init()

Tworzenie toastowego elementu HTML wykonuje się za pomocą funkcji createToast(). funkcja wymaga tekstu do wyświetlenia, tworzy element <output>, go wraz z niektórymi klasami i atrybutami, ustawia tekst i zwraca węzeł.

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

  return node
}

Zarządzanie jednym lub wieloma tostaami

JavaScript dodaje teraz do dokumentu kontener na tosty. gotowe do dodania utworzonych powiadomień. Funkcja addToast() zarządza nią lub wielu powiadomień. Najpierw sprawdzam liczbę powiadomień i sprawdzam, czy ruch jest prawidłowy, na podstawie tych informacji w ten sposób sprawia, że inne powiadomienia wydają się „robić miejsce” za nowy toast.

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

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

Podczas dodawania pierwszego powiadomienia Toaster.appendChild(toast) doda toast do strona uruchamiająca animacje CSS: animacja, oczekiwanie 3s, animacja. Funkcja flipToast() jest wywoływana, gdy występują już powiadomienia, z wykorzystaniem techniki. pod tytułem FLIP, autor: Paul Lewisa. Chodzi o obliczenie różnicy w pozycjach kontenera, przed i po dodaniu nowego powiadomienia. To jak zaznaczenie, gdzie jest teraz Toster, gdzie ma być toster. dzięki animowaniu od miejsca, w którym się znajdują.

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',
  })
}

Siatka CSS podnosi układ. Po dodaniu nowego powiadomienia siatka wyświetla go i używa spacji z innymi. Tymczasem strona internetowa animacja jest służy do animowania kontenera od poprzedniej pozycji.

Wykorzystanie całego JavaScriptu w jedną całość

Po wywołaniu Toast('my first toast') następuje utworzenie toastu i dodanie go do strony. (może nawet pojemnik jest animowany, by zmieścić nowy tost), obietnica jest zwracany, a utworzony tost oglądał przez Ukończenie animacji CSS (3 animacje klatek kluczowych) dla uzyskania oczekiwanych wyników.

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() 
  })
}

Wydaje mi się, że myląca część tego kodu znajduje się w funkcji Promise.allSettled() i toast.getAnimations(). Ponieważ korzystam z wielu animacji klatek kluczowych podczas wzięcia udziału w toście i mieć pewność, że wszystkie kroki skończą, żądań z JavaScriptu, a poszczególne ich finished z obietnicą zaobserwowanych jako realizacja. allSettled czy to na nas działa, rozwiązuje się jako kompletne, zostały wypełnione. await Promise.allSettled() oznacza, że następny wiersz może bez obaw usunąć element i przyjąć, że toast zakończył cyklu życia usługi. Dzwonienie pod numer resolve() w pełni spełnia tę obietnicę Toast, po wyświetleniu komunikatu, programiści mogą wyczyścić jego pamięć lub zająć się czymś innym.

export default Toast

Na koniec funkcja Toast jest eksportowana z modułu, aby inne skrypty były w importowaniu i wykorzystywaniu.

Korzystanie z komponentu Toast

Aby to zrobić, importuj plik Toast i wywołaj ją za pomocą ciągu tekstowego.

import Toast from './toast.js'

Toast('Wizard Rose added to cart')

Jeśli programista chce posprzątać czy cokolwiek innego, po toście mogą używać funkcji asynchronicznych zaczekaj.

import Toast from './toast.js'

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

Podsumowanie

Wiesz już, jak to zrobiłem. Jak Ty? 🙂

Stosujmy różne podejścia i poznajmy sposoby budowania obecności w internecie. Utwórz wersję demonstracyjną, a potem dodaj linki do funkcji tweetuj mi. znajdziesz poniżej w sekcji z remiksami na karcie Społeczność.

Remiksy utworzone przez społeczność