نظرة عامة أساسية حول كيفية بناء مكوّن للخبز المحمّص التكيُّفي الذي يسهل الوصول إليه.
في هذه المشاركة، أود مشاركة التفكير حول كيفية بناء مكون نخب. ننصحك بالاطّلاع على العرض التوضيحي.
في ما يلي إصدار YouTube من هذه المشاركة إذا كنت تفضّل الفيديوهات:
نظرة عامة
إنّ إشعارات الخبز هي رسائل قصيرة غير تفاعلية وغير تفاعلية وغير متزامنة مخصصة للمستخدمين. تُستخدم بشكل عام كنمط لملاحظات الواجهة لإبلاغ المستخدم بنتائج إجراء ما.
التفاعلات
تختلف الإشعارات عن الإشعارات والتنبيهات والطلبات لأنّها ليست تفاعلية ولا يُقصد إغلاقها أو مواصلة إرسالها. تُستخدم الإشعارات للحصول على معلومات أكثر أهمية أو رسائل متزامنة تتطلّب تفاعلاً أو رسائل على مستوى النظام (بدلاً من مستوى الصفحة). تكون الإشعارات المحمصة أكثر سلبية من استراتيجيات الإشعارات الأخرى.
Markup
يُعد العنصر <output>
اختيارًا جيدًا للخبز المحمّص لأنّه يتم عرضه لقرّاء الشاشة. يوفر لنا ترميز HTML الصحيح قاعدة آمنة لتحسينه باستخدام JavaScript وCSS، وسيتوفّر لنا الكثير من محتوى JavaScript.
الخبز المحمّص
<output class="gui-toast">Item added to cart</output>
يمكن أن تكون أكثر
شمولية
من خلال إضافة role="status"
. ويوفّر هذا الإجراء إجراءً احتياطيًا إذا لم يمنح المتصفّح عناصر <output>
الدور الضمني وفقًا للمواصفات.
<output role="status" class="gui-toast">Item added to cart</output>
علبة الخبز المحمّص
يمكن عرض أكثر من إشعار واحد في الوقت نفسه. من أجل تنسيق عدة نخب، يتم استخدام حاوية. تتعامل هذه الحاوية أيضًا مع موضع الخبز المحمص على الشاشة.
<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>
التنسيقات
اخترتُ تثبيت نخب من inset-block-end
على إطار العرض، وإذا أضفت المزيد من الخبز المحمّص، ستظهر من حافة الشاشة.
حاوية الفاتورة الرسمية الموحّدة
تقوم حاوية الخبز المحمص بجميع أعمال التخطيط لتقديم الخبز المحمص. وتكون القيمة fixed
لإطار العرض واستخدام السمة المنطقية inset
لتحديد الحواف التي يجب تثبيتها، بالإضافة إلى جزء صغير من padding
من حافة block-end
نفسها.
.gui-toast-group {
position: fixed;
z-index: 1;
inset-block-end: 0;
inset-inline: 0;
padding-block-end: 5vh;
}
بالإضافة إلى وضع نفسه داخل إطار العرض، فإنّ حاوية الخبز المحمّص هي حاوية شبكة يمكنها محاذاة الخبز المحمّص وتوزيعه. يتم توسيط العناصر كمجموعة تحتوي على justify-content
ويتم توسيطها بشكل فردي باستخدام justify-items
.
أضِف القليل من gap
حتى لا يلمس الخبز المحمّص.
.gui-toast-group {
display: grid;
justify-items: center;
justify-content: center;
gap: 1vh;
}
الخبز المحمّص في واجهة المستخدم الرسومية
يحتوي الخبز المحمّص الفردي على padding
، وبعض الزوايا ناعمة مع border-radius
، ووظيفة min()
للمساعدة في تحديد حجم الأجهزة الجوّالة والكمبيوتر المكتبي. يمنع الحجم سريع الاستجابة في CSS التالي
زيادة عرض نخب بأكثر من 90% من إطار العرض أو 25ch
.
.gui-toast {
max-inline-size: min(25ch, 90vw);
padding-block: .5ch;
padding-inline: 1ch;
border-radius: 3px;
font-size: 1rem;
}
الأنماط
باستخدام إعدادات التنسيق والموضع، يمكنك إضافة CSS التي تساعد في التكيف مع إعدادات المستخدم وتفاعلاته.
حاوية الخبز المحمّص
إشعارات الخبز ليست تفاعلية، فالنقر عليها أو التمرير فوقها لا يفعل أي شيء، لكنها تستخدم حاليًا أحداث المؤشر. امنع الخبز المحمّص من سرقة النقرات باستخدام خدمة CSS التالية.
.gui-toast-group {
pointer-events: none;
}
الخبز المحمّص في واجهة المستخدم الرسومية
يمكنك تخصيص مظهر فاتح أو داكن تكيّفي للخبز المحمص مع خصائص مخصصة وHSL واستعلام عن وسائط مفضلة.
.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%;
}
}
Animation
يجب أن يقدم الخبز المحمّص الجديد نفسه مع رسم متحرك عند دخوله إلى الشاشة.
يتم توفير الحركة المخفّضة من خلال ضبط قيم translate
على 0
تلقائيًا،
مع تعديل قيمة الحركة إلى طول في طلب بحث وسائط مفضّلة للحركة . يحصل كل شخص على بعض الرسوم المتحركة، ولكن بعض المستخدمين فقط لديهم الخبز المحمّص
مسافة.
في ما يلي الإطارات الرئيسية المستخدمة في الصورة المتحركة التي تعرض الخبز المحمّص. وستتحكم CSS في الدخول والانتظار والخروج من الخبز المحمّص، كل ذلك في صورة متحركة واحدة.
@keyframes fade-in {
from { opacity: 0 }
}
@keyframes fade-out {
to { opacity: 0 }
}
@keyframes slide-in {
from { transform: translateY(var(--_travel-distance, 10px)) }
}
ومن ثم يعمل عنصر الإعلام المنبثق على إعداد المتغيرات وتنسيق الإطارات الرئيسية.
.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
نظرًا إلى تجهيز الأنماط ولغة HTML التي يمكن الوصول إليها من خلال قارئ الشاشة، تكون هناك حاجة إلى JavaScript لتنسيق عملية إنشاء نخب محمّص وإضافتها وإتلافها استنادًا إلى أحداث المستخدم. يجب أن تكون تجربة المطور لمكون الخبز المحمّص بسيطة ويسهل البدء بها، كما يلي:
import Toast from './toast.js'
Toast('My first toast')
إنشاء مجموعة الخبز المحمص ونخب
عند تحميل وحدة الإبلاغ عن المحتوى من JavaScript، يجب إنشاء حاوية نخب وإضافتها إلى الصفحة. لقد اخترت إضافة العنصر قبل body
، وسيؤدي ذلك إلى احتمال حدوث z-index
مشكلة في تكديس لأنّ الحاوية أعلى الحاوية
لجميع عناصر النص الأساسي.
const init = () => {
const node = document.createElement('section')
node.classList.add('gui-toast-group')
document.firstElementChild.insertBefore(node, document.body)
return node
}
يتم استدعاء الدالة init()
داخليًا إلى الوحدة النمطية، وتخزين العنصر في شكل Toaster
:
const Toaster = init()
يتم إنشاء عنصر HTML للنبيذ باستخدام الدالة createToast()
. تتطلب
الدالة بعض النص للخبز المحمّص، وتنشئ عنصر <output>
، وتزيّنه
ببعض الفئات والسمات، وتعين النص، وتُرجع العقدة.
const createToast = text => {
const node = document.createElement('output')
node.innerText = text
node.classList.add('gui-toast')
node.setAttribute('role', 'status')
return node
}
إدارة رسالة نخب واحدة أو أكثر
تضيف لغة JavaScript الآن حاوية إلى المستند لتحتوي على نخب، وهي جاهزة لإضافة نخب تم إنشاؤها. تتولى الدالة addToast()
تنسيق عملية التعامل مع
نخب واحد أو أكثر. يتم أولاً التحقق من عدد الخبز المحمّص، والتأكد مما إذا كانت الحركة على ما يرام،
ثم استخدام هذه المعلومات لإضافة الخبز المحمّص أو إنشاء بعض الرسوم المتحركة الرائعة حتى يبدو أن الخبز المحمّص الآخر "يفسح المجال" للخبز المحمّص الجديد.
const addToast = toast => {
const { matches:motionOK } = window.matchMedia(
'(prefers-reduced-motion: no-preference)'
)
Toaster.children.length && motionOK
? flipToast(toast)
: Toaster.appendChild(toast)
}
عند إضافة أول نخب محمّص، يضيف Toaster.appendChild(toast)
نخبًا إلى الصفحة، ما يؤدي إلى ظهور الصور المتحركة في CSS: إضافة "تحريك" و"انتظار 3s
" و"تحريك".
يتم استدعاء flipToast()
عند توفّر نخب محمّص حاليًا، وذلك باستخدام تقنية تُعرف باسم FLIP من قِبل بول
لويس. والفكرة هي حساب الفرق في مواضع
الوعاء، قبل إضافة الخبز المحمّص الجديد وبعده.
فكر في الأمر كأنه تحديد أين يوجد محمصة الخبز الآن، وأين ستكون، ثم الرسوم المتحركة
من حيث كانت إلى مكانها.
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 إلى تحسين التصميم. عند إضافة نخب جديد، تضعه الشبكة في البداية وتتباعده مع الأخرى. وفي الوقت نفسه، يتم استخدام صورة متحركة على الويب لتحريك الحاوية من موضعها القديم.
دمج كل رموز JavaScript
عند استدعاء Toast('my first toast')
، يتم إنشاء نخب وتضيفه إلى الصفحة (ربما يتم تحريك الحاوية حتى تتسع للخبز المحمّص الجديد)، ويتم عرض وعد، ويتم مشاهدة الإشعار المنبثق الذي تم إنشاؤه لاكتمال صور متحركة في CSS (الصور المتحركة الثلاثة للإطارات الرئيسية) للحصول على درجة الدقة المطلوبة.
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()
})
}
شعرتُ أن الجزء المحير من هذا الرمز البرمجي موجود في دالة Promise.allSettled()
وربط toast.getAnimations()
. بما أنني استخدمت العديد من الصور المتحركة في الإطارات الرئيسية
لتشغيل الخبز المحمّص، أعرف بثقة أنّ جميع هذه اللقطات قد انتهت، لذا يجب طلب كل منها من JavaScript وأنّ كل وعود من finished
تتم ملاحظتها باكتمالها.
إنّ allSettled
هذا مفيد بالنسبة إلينا، حيث يتبيّن لنا أنّه مكتملة بعد الوفاء بجميع
وعوده. يعني استخدام await Promise.allSettled()
أن السطر التالي من التعليمات البرمجية
يمكنه إزالة العنصر بثقة وافتراض اكتمال دورة حياة الخبز المحمّص. وأخيرًا، يلبّي استدعاء resolve()
وعد Toast العالي المستوى،
حتى يتمكّن المطوّرون من حذف البرامج غير المرغوب فيها أو تنفيذ أي مهام أخرى بعد عرض الإشعار.
export default Toast
أخيرًا، يتم تصدير الدالة Toast
من الوحدة النمطية، وذلك لاستيراد النصوص البرمجية الأخرى واستخدامها.
استخدام مكوِّن Toast
يتم استخدام إشعار التحمّص أو تجربة المطوّر في نموذج الخبز المحمّص من خلال استيراد دالة Toast
واستدعائها باستخدام سلسلة رسالة.
import Toast from './toast.js'
Toast('Wizard Rose added to cart')
إذا أراد مطوّر البرامج تنفيذ مهام تنظيف البيانات أو إنجاز تلك المهام، يمكنه استخدام وضع "المزامنة" وawait بعد ظهور إشعار "الإشعار المدفوع".
import Toast from './toast.js'
async function example() {
await Toast('Wizard Rose added to cart')
console.log('toast finished')
}
الخلاصة
الآن بعد أن عرفت كيف فعلت ذلك، كيف يمكنك‽ 🙂
دعونا ننويع أساليبنا ونتعلم جميع طرق الإنشاء على الويب. يمكنك إنشاء عرض توضيحي وروابط تغريدات لي وسنضيفها إلى قسم الريمكسات في المنتدى أدناه.
ريمكسات من المنتدى
- @_developit باستخدام HTML/CSS/JS: العرض التوضيحي والرمز
- Joost van der Sheee باستخدام HTML/CSS/JS: العرض التوضيحي والرمز