استخدام واجهة برمجة تطبيقات DModal لعرض نوافذ منبثقة (المعروفة أيضًا باسم النوافذ المنبثقة أو الحوارات) في Discourse

يأتي Discourse 3.1.0.beta6 مع واجهة برمجة تطبيقات (API) جديدة تمامًا تعتمد على المكون DModal.

:information_source: هذه الواجهة تحل محل واجهة التحكم القديمة المعتمدة على المتحكمات (controllers)، والتي أصبحت الآن منتهية الصلاحية. إذا كان لديك نوافذ منبثقة (modals) قائمة تستخدم واجهات برمجة التطبيقات القديمة، فاطلع على دليل الهجرة هنا.

عرض نافذة منبثقة (Modal)

يتم عرض النوافذ المنبثقة بتضمين مكون DModal في قالب Handlebars. إذا لم يكن لديك قالب مناسب بالفعل، فاطلع على Using Plugin Outlet Connectors from a Theme or Plugin.

ستبدو نافذة منبثقة بسيطة شيئًا مثل هذا:

<DButton
  @translatedLabel="عرض النافذة المنبثقة"
  @action={{fn (mut this.modalIsVisible) true}}
/>

{{#if this.modalIsVisible}}
  <DModal @title="نافذتي المنبثقة" @closeModal={{fn (mut this.modalIsVisible) false}}>
    مرحبًا بالعالم، هذا محتوى داخل نافذة منبثقة
  </DModal>
{{/if}}

:information_source: تُستخدم دالة mut هنا كطريقة خاصة بـ hbs فقط لتعيين قيمة. يمكنك أيضًا تعيين modalIsVisible باستخدام أي طريقة Ember قياسية أخرى.

سيؤدي هذا المثال إلى إنشاء نافذة منبثقة بسيطة مثل هذه:

التغليف داخل مكون

قبل إدخال أي تعقيد إضافي، من الأفضل عادةً تغليف نافذتك المنبثقة الجديدة في تعريف مكون خاص بها. لنقم بنقل محتوى DModal داخل مكون جديد يُسمى MyModal.

// components/my-modal.gjs
<template>
  <DModal @title="نافذتي المنبثقة" @closeModal={{@closeModal}}>
    مرحبًا بالعالم، هذا محتوى داخل نافذة منبثقة
  </DModal>
</template>

سيؤدي ترقية ملف .gjs هذا إلى مكون قائم على الفئات (class-based component) إلى تمكينك من إدخال منطق وحالة أكثر تعقيدًا.

لاستخدام المكون الجديد، قم بتحديث موقع الاستدعاء للإشارة إليه، مع التأكد من تمرير حجة @closeModal.

<DButton
  @translatedLabel="عرض النافذة المنبثقة"
  @action={{fn (mut this.modalIsVisible) true}}
/>

{{#if this.modalIsVisible}}
  <MyModal @closeModal={{fn (mut this.modalIsVisible) false}} />
{{/if}}

إضافة تذييل

تحتوي العديد من النوافذ المنبثقة على نوع من نداءات اتخاذ الإجراء (call-to-action). في Discourse، تميل هذه العناصر إلى التواجد في أسفل النافذة المنبثقة. لتمكين ذلك، يحتوي DModal على عدد من «الكتل المسماة» التي يمكن عرض محتوى بداخلها. إليك المثال المحدّث ليشمل زرين في التذييل، أحدهما هو زر DModalCancel القياسي لدينا:

<DModal @title="نافذتي المنبثقة" @closeModal={{@closeModal}}>
  <:body>
    مرحبًا بالعالم، هذا محتوى داخل نافذة منبثقة
  </:body>
  <:footer>
    <DButton class="btn-primary" @translatedLabel="إرسال" />
    <DModalCancel @close={{@closeModal}} />
  </:footer>
</DModal>

عرض نافذة منبثقة من سياق غير hbs

من الناحية المثالية، يجب عرض экземпляرات DModal من داخل قالب Ember باستخدام التقنية التوضيحية المذكورة أعلاه. إذا لم يكن ذلك ممكنًا لحالتك الاستخدامية، فيمكن القيام بذلك عن طريق حقن خدمة modal واستدعاء modal.show().

تأكد من تغليف نافذتك المنبثقة في مكون خاص بها كما هو موضح أعلاه. ثم، قم بتشغيل النافذة المنبثقة عن طريق تمرير مرجع لفئة مكونك إلى showModal:

import MyModal from "discourse/components/my-modal";

// (قم بحقن خدمة modal في المكان المناسب)

// أضف هذا الاستدعاء كلما أردت فتح النافذة المنبثقة.
// سيتم تمرير حجة `@closeModal` إلى مكونك تلقائيًا.
this.modal.show(MyModal);

// اختياريًا، مرّر معلمة `model`. يتم تمريرها كمعلمة `@model` إلى مكونك.
// يمكن أن يشمل ذلك البيانات، بالإضافة إلى الإجراءات/الاستدعاءات التي يمكن لمكونك استخدامها.
this.modal.show(MyModal, {
  model: { topic: this.topic, someAction: this.someAction },
});

// يُرجع `modal.show()` وعدًا (promise)، لذا يمكنك الانتظار حتى يتم إغلاقه.
// سيتم حله بالبيانات الممررة إلى إجراء `@closeModal`.
const result = await this.modal.show(MyModal);

المزيد من التخصيص!

يحتوي DModal على عدد من الكتل المسماة والمعاملات.

المعاملات

المعامل الغرض
@closeModal مطلوب لظهور واجهة المستخدم للإغلاق (dismiss UI) على الإطلاق.
@title يعرض <h1 id="discourse-modal-title">؛ ويوصل aria-labelledby.
@subtitle نص صغير أسفل العنوان.
@flash / @flashType تنبيه مضمن في أعلى النافذة المنبثقة (DFlashMessage).
@hideHeader, @hideFooter إخفاء المناطق بأكملها.
@headerClass, @bodyClass فئة إضافية على غلاف الرأس/الجسم.
@dismissable القيمة الافتراضية صحيحة (true) عند تعيين @closeModal. يعطل زر Esc / النقر على الخلفية / زر X.
@autofocus القيمة الافتراضية صحيحة (true). يركز تلقائيًا على أول عنصر قابل للتركيز عبر dTrapTab.
@submitOnEnter القيمة الافتراضية صحيحة (true). يضغط Enter على .d-modal__footer .btn-primary ما لم يكن التركيز في نموذج / حقل نصي كبير / مجموعة اختيار.
@beforeClose async ({ initiatedBy }) => boolean. أعد false لإلغاء الإغلاق (مثل تأكيد نموذج غير محفوظ).
@hidden يوقف معالجة لوحة المفاتيح؛ يُستخدم عندما تكون نافذة منبثقة متداخلة في الأعلى.
@tagName "div" (افتراضي) أو "form". استخدم "form" للنماذج حتى يعمل الإرسال الأصلي.

الكتل

الكتلة الموقع متى تُستخدم
الافتراضي / :body منطقة المحتوى الرئيسية المنطقة الافتراضية
:aboveHeader أعلى القمة، قبل الرأس نادرًا ما تكون مطلوبة؛ للمحتوى الذي يجب أن يجلس فوق شريط العنوان (مثل لافتة).
:headerAboveTitle داخل الرأس، قبل العنوان موجودة ولكن غير مستخدمة. نادرًا ما تكون مطلوبة.
:belowModalTitle داخل .d-modal__title، بعد <h1> موقع ممتاز لمعلومات الميتا التكميلية.
:headerBelowTitle داخل الرأس، بعد كتلة العنوان علامات التبويب، أو شريط التنقل الفرعي، أو حقل البحث الذي هو جزء من الرأس.
:headerPrimaryAction الجانب الأيمن من الرأس على الجوال فقط يحل محل زر إغلاق X بإجراء أساسي (مثل «حفظ»). كما يعرض تلقائيًا زر «إلغاء» على اليسار ويضيف .--has-primary-action إلى الرأس.
:belowHeader بين الرأس والجسم محتوى تذييل فرعي دائم (مثل البحث) يقع خارج الجسم القابل للتمرير، لذا يكون العرض ثابتًا (sticky).
:aboveFooter بين الجسم والتذييل يتم قمعها عند تعيين @hideFooter. استخدمها للمحتوى المرتبط بالتذييل ولكنه يقع خارجه. نادرًا ما تُستخدم أيضًا.
:footer شريط الإجراءات السفلي الأزرار الأساسية والثانوية. الزر .btn-primary الأول هنا هو ما يضغطه Enter.
:belowFooter بعد التذييل نادرًا ما تكون مطلوبة؛ تتجاهل @hideFooter. مفيدة لنص الحالة خارج منطقة التذييل المحاطة بإطار.

المصادر: دليل الأنماط التفاعلي للمعاملات، و تنفيذ قالب d-modal للكتل المسماة.

CSS

استخدم فئات .d-modal كنقطة ارتكاز لتجاوز الأساسيات، وتجنب محدد .modal القديم.

تتوفر 4 معدلات:

  • .--large يحدد أقصى عرض إلى 800 بكسل (للجهاز المكتبي فقط)
  • .--max يحدد أقصى عرض إلى 90% من عرض الشاشة (للجهاز المكتبي فقط)
  • .has-search يحدد ارتفاعًا ثابتًا (80% من ارتفاع الشاشة): مخصص للنوافذ المنبثقة التي تحتوي على نظام بحث/تصفية لتجنب تغيير الارتفاع بناءً على طول النتائج (للجهاز المكتبي فقط)
  • .--stacked يجعل أزرار التذييل مكدسة (للجوال فقط)

يتم التحكم في إصدار هذا المستند - اقترح تغييرات على GitHub.

17 إعجابًا

تم تقسيم منشور إلى موضوع جديد: هل يمكنني عرض نافذة منبثقة من head_tag