Discourse 3.1.0.beta6 è dotato di una nuova API basata su componenti <DModal>. DModal fa parte del UI kit e viene importato da discourse/ui-kit/d-modal.
Questa API sostituisce la vecchia API basata su controller, che è ora deprecata. Se hai modali esistenti che utilizzano le vecchie API, consulta la guida alla migrazione qui.
Rendering di un Modale
I modali vengono renderizzati includendo il componente <DModal> in un template handlebars. Se non disponi già di un template adatto, consulta Using Plugin Outlet Connectors from a Theme or Plugin.
Un modale semplice potrebbe essere simile a questo:
<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}}
L’helper
mutviene utilizzato qui come metodo solo hbs per impostare un valore. È possibile impostaremodalIsVisibleanche utilizzando qualsiasi altro metodo standard di Ember.
Questo esempio creerà un modale semplice come questo:
Incapsulamento in un componente
Prima di introdurre ulteriore complessità, è generalmente meglio incapsulare il nuovo Modale nella propria definizione di Componente. Spostiamo la parte <DModal> all’interno di un nuovo componente <MyModal />
// components/my-modal.gjs
<template>
<DModal @title="My Modal" @closeModal={{@closeModal}}>
Hello world, this is some content in a modal
</DModal>
</template>
L’aggiornamento di questo file .gjs a un componente basato su classi consentirà di introdurre logiche e stati più complessi.
Per utilizzare il nuovo componente, aggiorna il punto di chiamata per fare riferimento ad esso, assicurandoti di passare un argomento @closeModal.
<DButton
@translatedLabel="Show Modal"
@action={{fn (mut this.modalIsVisible) true}}
/>
{{#if this.modalIsVisible}}
<MyModal @closeModal={{fn (mut this.modalIsVisible) false}} />
{{/if}}
Aggiunta di un footer
Molti modali hanno una sorta di invito all’azione (call-to-action). In Discourse, questi tendono a essere posizionati nella parte inferiore del modale. Per rendere possibile ciò, DModal dispone di diversi ‘blocchi nominati’ in cui è possibile renderizzare contenuto. Ecco l’esempio aggiornato per includere due pulsanti nel footer, uno dei quali è il nostro standard pulsante 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>
Rendering di un modale da un contesto non-hbs
Idealmente, le istanze di <DModal> dovrebbero essere renderizzate all’interno di un template Ember utilizzando la tecnica dichiarativa dimostrata sopra. Se ciò non è fattibile per il tuo caso d’uso, è possibile farlo iniettando il servizio modal e chiamando modal.show().
Assicurati di aver incapsulato il tuo modale in un proprio componente come descritto sopra. Quindi, attiva il modale passando un riferimento della tua classe di componente a showModal:
import MyModal from "discourse/components/my-modal";
// (inietta il servizio modal nel punto pertinente)
// Aggiungi questa chiamata ogni volta che vuoi aprire il modale.
// Un argomento `@closeModal` verrà passato automaticamente al tuo componente.
this.modal.show(MyModal);
// Opzionalmente, passa un parametro '`model`'. Viene passato come `@model` al tuo componente.
// Questo può includere dati e anche azioni/callback per il tuo Modale da utilizzare.
this.modal.show(MyModal, {
model: { topic: this.topic, someAction: this.someAction },
});
// `modal.show()` restituisce una promise, quindi puoi aspettare che venga chiuso
// Si risolverà con i dati passati all'azione `@closeModal`
const result = await this.modal.show(MyModal);
Maggiore personalizzazione!
<DModal> ha diversi blocchi nominati e argomenti.
Argomenti
| Arg | Scopo |
|---|---|
@closeModal |
Obbligatorio affinché la UI di chiusura venga visualizzata. |
@title |
Renderizza <h1 id="discourse-modal-title">; collega aria-labelledby. |
@subtitle |
Testo piccolo sotto il titolo. |
@flash / @flashType |
Avviso inline nella parte superiore del modale (DFlashMessage). |
@hideHeader, @hideFooter |
Nasconde intere regioni. |
@headerClass, @bodyClass |
Classe aggiuntiva su header/body wrapper. |
@dismissable |
Default true quando @closeModal è impostato. Disabilita Esc / click sul backdrop / X. |
@autofocus |
Default true. Mette a fuoco automaticamente il primo elemento focalizzabile tramite dTrapTab. |
@submitOnEnter |
Default true. Enter fa clic su .d-modal__footer .btn-primary a meno che il focus non sia in un form / textarea / select-kit. |
@beforeClose |
async ({ initiatedBy }) => boolean. Restituisci false per annullare la chiusura (es. conferma form sporco). |
@hidden |
Mette in pausa la gestione della tastiera; usato quando un modale annidato è in cima. |
@tagName |
"div" (default) o "form". Usa "form" per i form in modo che il submit nativo funzioni. |
Blocchi
| Block | Posizione | Quando usarlo |
|---|---|---|
default / :body |
Area di contenuto principale | Area predefinita |
:aboveHeader |
Molto in alto, prima dell’header | Raramente necessario; per contenuto che deve trovarsi sopra la barra del titolo (es. un banner). |
:headerAboveTitle |
All’interno dell’header, prima del titolo | Presente ma non utilizzato. Raramente necessario. |
:belowModalTitle |
All’interno di .d-modal__title, dopo <h1> |
Posizione eccellente per informazioni meta supplementari. |
:headerBelowTitle |
All’interno dell’header, dopo il blocco del titolo | Schede, sub-nav o input di ricerca che fanno parte dell’header. |
:headerPrimaryAction |
Lato destro dell’header solo su mobile | Sostituisce il pulsante di chiusura X con un’azione primaria (es. “Salva”). Renderizza anche automaticamente un pulsante “Annulla” a sinistra e aggiunge .--has-primary-action all’header. |
:belowHeader |
Tra header e body | Contenuto di sub-header persistente (es. ricerca) che è fuori dal corpo scorrevole, quindi display sticky. |
:aboveFooter |
Tra body e footer | Soppresso quando @hideFooter è impostato. Usato per contenuto legato al footer ma esterno ad esso. Anche raro. |
:footer |
Barra di azione inferiore | Pulsanti primari e secondari. Il primo .btn-primary qui è ciò che viene attivato da Enter. |
:belowFooter |
Dopo il footer | Raramente necessario; ignora @hideFooter. Utile per testo di stato fuori dall’area del footer con bordo. |
Fonti: lo styleguide interattivo per gli argomenti e l’implementazione del template d-modal per i blocchi nominati.
CSS
Usa le classi .d-modal come ancoraggio per sovrascrivere il core e evita il selettore legacy .modal.
Sono disponibili 4 modificatori:
- .
--largeimposta la larghezza massima a 800px (solo desktop) - .
--maximposta la larghezza massima a 90vw (solo desktop) - .
has-searchimposta l’altezza fissa (80vh): destinato a modali con sistema di ricerca/filtro per evitare variazioni di altezza basate sulla lunghezza dei risultati (solo desktop) .--stackedimposta i pulsanti del footer in impilamento (solo mobile)
Questo documento è sotto controllo di versione - suggerisci modifiche su github.

