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

