Modales
Les modales sont des boîtes de dialogue qui apparaissent au-dessus de la page actuelle, généralement utilisées pour les confirmations, les actions rapides ou les interactions ciblées qui nécessitent l’attention de l’utilisateur.
-
Les composants modaux doivent utiliser le suffixe
.modal.tsxpour indiquer clairement leur objectif et permettre une extraction correcte des clés de traduction. -
Utilisez les composants
Modalde Carbon (ModalHeader,ModalBody,ModalFooter) pour une structure modale cohérente. GardezModalHeaderetModalBodyau premier niveau du composant de modale, enveloppés dans un fragment, afin que le shell puisse dimensionner correctement la modale et faire défiler son corps :import { ModalHeader, ModalBody, ModalFooter } from '@carbon/react'; function DeleteModal({ close, itemId }: DeleteModalProps) { return ( <> <ModalHeader closeModal={close} title={t('deleteItem', "Supprimer l'élément")} /> <ModalBody> <p>{t('deleteConfirmation', 'Êtes-vous sûr de vouloir supprimer cet élément ?')}</p> </ModalBody> <ModalFooter> <Button kind="secondary" onClick={close}> {t('cancel', 'Annuler')} </Button> <Button kind="danger" onClick={handleDelete}> {t('delete', 'Supprimer')} </Button> </ModalFooter> </> ); } -
Utilisez les états de chargement dans les boutons d’action modaux pour fournir un retour pendant les opérations asynchrones :
const [isDeleting, setIsDeleting] = useState(false); <Button kind="danger" onClick={handleDelete} disabled={isDeleting}> {isDeleting ? ( <InlineLoading description={t('deleting', 'Suppression') + '...'} /> ) : ( <span>{t('delete', 'Supprimer')}</span> )} </Button> -
Les modales doivent gérer les erreurs avec élégance et les afficher en utilisant des snackbars. Préférez
async/awaitaux chaînes de promesses pour une meilleure lisibilité :const handleDelete = useCallback(async () => { setIsDeleting(true); try { await deleteItem(itemId); await mutate(); // Mettre à jour le cache SWR close(); showSnackbar({ isLowContrast: true, kind: 'success', title: t('itemDeleted', 'Élément supprimé'), }); } catch (error) { showSnackbar({ kind: 'error', title: t('errorDeletingItem', 'Erreur lors de la suppression de l'élément'), subtitle: error instanceof Error ? error.message : t('unknownError', 'Erreur inconnue'), }); } finally { setIsDeleting(false); } }, [itemId, close, mutate, t]); -
Utilisez
showModalde@openmrs/esm-frameworkpour lancer des modales programmatiquement. Le framework injecte une propclosedans la modale et renvoie également la même fonction de fermeture à l’appelant :import { showModal } from '@openmrs/esm-framework'; const handleOpenModal = () => { showModal('delete-item-modal', { itemId: '123', }); }; -
Exportez les composants modaux avec
getAsyncLifecyclepour le code splitting, puis enregistrez-les dans la sectionmodalsderoutes.json. Le nom passé àshowModaldoit correspondre à la valeurnamedansroutes.json, etcomponentdoit correspondre au nom du cycle de vie exporté :export const deleteItemModal = getAsyncLifecycle( () => import('./delete-item.modal'), options );{ "modals": [ { "name": "delete-item-modal", "component": "deleteItemModal" } ] } -
Utilisez les types de boutons appropriés pour les actions modales :
dangerpour les actions destructives (supprimer, retirer)primarypour les confirmations principalessecondarypour les actions d’annulation
<ModalFooter> <Button kind="secondary" onClick={close}> {t('cancel', 'Annuler')} </Button> <Button kind="danger" onClick={handleDelete}> {t('delete', 'Supprimer')} </Button> </ModalFooter>