Aller au contenu

Create Modal

Crée une nouvelle modal suivant le pattern useModals.

Arguments

  • name (requis) : Nom de la modal en PascalCase (ex: ConfirmPayment, SelectProperty)

Instructions

  1. Demander à l'utilisateur :
  2. La modal a-t-elle besoin de props (données à afficher) ?
  3. La modal a-t-elle un footer sticky (boutons d'action) ?
  4. Liste virtuelle ? → ModalList au lieu de Modal

  5. Créer le fichier dans :

  6. Shared : src/components/modals/{ModalName}.tsx
  7. Feature : src/screens/{feature}/components/{ModalName}.tsx

Templates

import { View } from "react-native";
import { Button } from "@bricks-common/uimmo/components/buttons";
import { Modal, useCloseModal } from "@bricks-common/uimmo/components/modals";
import { Text } from "@bricks-common/uimmo/components/Text";
import { useTranslation } from "react-i18next";

export const {{ModalName}} = () => {
  const { t } = useTranslation();
  const closeModal = useCloseModal();

  return (
    <Modal isVisible onClose={closeModal} title={t("modals.{{modalName}}.title")}>
      <View className="p-2xl gap-lg">
        <Text>{t("modals.{{modalName}}.description")}</Text>
        <Button onPress={closeModal} label={t("common.close")} />
      </View>
    </Modal>
  );
};
import { View } from "react-native";
import { Button } from "@bricks-common/uimmo/components/buttons";
import { Modal, useCloseModal } from "@bricks-common/uimmo/components/modals";
import { Text } from "@bricks-common/uimmo/components/Text";
import { useTranslation } from "react-i18next";

type {{ModalName}}Props = {
  propertyId: string;
  propertyName: string;
  onConfirm: () => void;
};

export const {{ModalName}} = ({ propertyId, propertyName, onConfirm }: {{ModalName}}Props) => {
  const { t } = useTranslation();
  const closeModal = useCloseModal();

  const handleConfirm = () => {
    onConfirm();
    closeModal();
  };

  return (
    <Modal isVisible onClose={closeModal} title={t("modals.{{modalName}}.title")}>
      <View className="p-2xl gap-lg">
        <Text>{t("modals.{{modalName}}.description", { name: propertyName })}</Text>
        <Button onPress={handleConfirm} label={t("common.confirm")} />
        <Button onPress={closeModal} label={t("common.cancel")} variant="secondary" />
      </View>
    </Modal>
  );
};
import { View } from "react-native";
import { Button } from "@bricks-common/uimmo/components/buttons";
import { Modal, ModalFooter, useCloseModal } from "@bricks-common/uimmo/components/modals";
import { Text } from "@bricks-common/uimmo/components/Text";
import { useTranslation } from "react-i18next";

type {{ModalName}}Props = {
  onConfirm: () => void;
};

export const {{ModalName}} = ({ onConfirm }: {{ModalName}}Props) => {
  const { t } = useTranslation();
  const closeModal = useCloseModal();

  const handleConfirm = () => {
    onConfirm();
    closeModal();
  };

  return (
    <Modal isVisible onClose={closeModal} title={t("modals.{{modalName}}.title")}>
      <View className="p-2xl gap-lg">
        <Text>{t("modals.{{modalName}}.description")}</Text>
      </View>
      <ModalFooter>
        <View className="flex-row gap-md">
          <Button onPress={closeModal} label={t("common.cancel")} variant="secondary" fill />
          <Button onPress={handleConfirm} label={t("common.confirm")} fill />
        </View>
      </ModalFooter>
    </Modal>
  );
};

Utilisation

Ouvrir la modal

import { useModals } from "@bricks-common/uimmo/components/modals";
import { {{ModalName}} } from "@components/modals/{{ModalName}}";

const MyComponent = () => {
  const { openModal } = useModals();

  const handleOpenModal = () => {
    openModal({{ModalName}});
    // ou avec props
    openModal({{ModalName}}, { propertyId: "123", onConfirm: handleConfirm });
  };

  return <Button onPress={handleOpenModal} label="Ouvrir" />;
};

Ajouter les traductions

Dans src/i18n/locales/fr.json :

{
  "modals": {
    "{{modalName}}": {
      "title": "Titre de la modal",
      "description": "Description de la modal"
    }
  }
}

Checklist finale

  • [ ] Modal créée avec Modal (ou ModalList pour une liste virtuelle)
  • [ ] useCloseModal pour fermer
  • [ ] Props typées si nécessaire
  • [ ] Traductions ajoutées
  • [ ] isVisible toujours true

Anti-patterns à éviter

// ❌ State local pour contrôler la modal
const [isOpen, setIsOpen] = useState(false);
<Modal isVisible={isOpen} />

// ✅ Utiliser useModals
const { openModal } = useModals();
openModal(MyModal);

// ❌ BottomSheetModal direct
<BottomSheetModal isVisible onClose={closeModal} />

// ✅ Modal + useModals
<Modal isVisible onClose={closeModal} />

Règles appliquées

  • front-conventions.mdc (section Modals)
  • front-i18n.mdc