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

يأتي Discourse 3.1.0.beta6 مع واجهة برمجة تطبيقات (API) جديدة مبنية على مكوّن <DModal>. يُعدّ DModal جزءًا من حزمة واجهة المستخدم (UI kit) ويتم استيراده من discourse/ui-kit/d-modal.

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

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

تتم عرض النوافذ المنبثقة من خلال تضمين مكوّن <DModal> في قالب handlebars. إذا لم يكن لديك قالب مناسب بالفعل، فراجع Using Plugin Outlet Connectors from a Theme or Plugin.

ستبدو نافذة منبثقة بسيطة على النحو التالي:

<DButton
  @translatedLabel="Show Modal"
  @action={{fn (mut this.modalIsVisible) true}}
/>

{{#if this.modalIsVisible}}
  <DModal @title="My Modal" @closeModal={{fn (mut this.modalIsVisible) false}}>
    Hello world, this is some content in a modal
  </DModal>
{{/if}}

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

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

التغليف في مكوّن (Wrapping in a component)

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

// components/my-modal.gjs
<template>
  <DModal @title="My Modal" @closeModal={{@closeModal}}>
    Hello world, this is some content in a modal
  </DModal>
</template>

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

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

<DButton
  @translatedLabel="Show Modal"
  @action={{fn (mut this.modalIsVisible) true}}
/>

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

إضافة تذييل (Adding a footer)

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

<DModal @title="My Modal" @closeModal={{@closeModal}}>
  <:body>
    Hello world, this is some content in a modal
  </:body>
  <:footer>
    <DButton class="btn-primary" @translatedLabel="Submit" />
    <DModalCancel @close={{@closeModal}} />
  </:footer>
</DModal>

عرض نافذة منبثقة من سياق غير hbs (Rendering a modal from a non-hbs context)

من حيث المبدأ، يجب عرض كائنات <DModal> من داخل قالب Ember باستخدام التقنية التوضيحية (declarative technique) المُستعرضة أعلاه. إذا لم يكن ذلك ممكنًا لحالتك الاستخدام، فيمكن القيام بذلك عن طريق حقن خدمة modal واستدعاء modal.show().

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

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

// (inject the modal service in the relevant place)

// Add this call whenever you want to open the modal.
// A `@closeModal` argument will be passed to your component automatically.
this.modal.show(MyModal);

// Optionally, pass a '`model`' parameter. Passed as `@model` to your component.
// This can include data, and also actions/callbacks for your Modal to use.
this.modal.show(MyModal, {
  model: { topic: this.topic, someAction: this.someAction },
});

// `modal.show()` returns a promise, so you can wait for it to be closed
// It will resolve with the data passed to the `@closeModal` action
const result = await this.modal.show(MyModal);

مزيد من التخصيص! (More customizability!)

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

الحجج (Arguments)

الحجة (Arg) الغرض
@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 ما لم يكن التركيز في نموذج / textarea / select-kit.
@beforeClose async ({ initiatedBy }) => boolean. أعد false لإلغاء الإغلاق (مثل تأكيد النموذج المتسخ).
@hidden يوقف معالجة لوحة المفاتيح؛ يُستخدم عندما تكون نافذة منبثقة متداخلة في الأعلى.
@tagName "div" (افتراضي) أو "form". استخدم "form" للنماذج حتى يعمل الإرسال الأصلي.

الكتل (Blocks)

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

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

CSS

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

متوفر 4 معدّلات (modifiers):

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

هذا المستند مُدار بالإصدارات - اقترح تغييرات على github.

17 إعجابًا

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