CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-mantine--modals

Modals manager based on Mantine components providing context-based modal state management with confirmation, context, and content modals.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

context-modals.mddocs/

Context Modals

Predefined reusable modal components registered with the provider for consistent modal experiences.

Capabilities

Open Context Modal

Opens a predefined modal component by key with custom properties.

/**
 * Opens a predefined context modal by key
 * @param payload - Modal key, configuration, and inner props
 * @returns Modal ID for future reference
 */
function openContextModal<TKey extends MantineModal>(
  payload: OpenContextModal<Parameters<MantineModals[TKey]>[0]['innerProps']> & { modal: TKey }
): string;

interface OpenContextModal<CustomProps extends Record<string, any> = {}> extends ModalSettings {
  /** Custom props passed to the modal component */
  innerProps: CustomProps;
}

Usage Examples:

import { openContextModal } from "@mantine/modals";

// Open registered context modal
openContextModal({
  modal: "userProfile",
  title: "User Profile",
  innerProps: {
    userId: "123",
    editable: true,
  },
});

// Context modal with custom modal properties
openContextModal({
  modal: "deleteConfirmation",
  title: "Delete Item",
  size: "sm",
  centered: true,
  innerProps: {
    itemName: "Important Document",
    itemType: "document",
    onConfirm: () => deleteDocument("doc-123"),
  },
});

Update Context Modal

Updates properties of an existing context modal.

/**
 * Updates properties of an existing context modal
 * @param payload - Modal ID and updated properties
 */
function updateContextModal(
  payload: { modalId: string } & Partial<OpenContextModal<any>>
): void;

Usage Examples:

import { openContextModal, updateContextModal } from "@mantine/modals";

// Open context modal
const modalId = openContextModal({
  modal: "dataEditor",
  modalId: "editor-1",
  title: "Edit Data",
  innerProps: {
    data: initialData,
    readOnly: false,
  },
});

// Update inner props
updateContextModal({
  modalId: "editor-1",
  innerProps: {
    data: updatedData,
    readOnly: true, // Make read-only
  },
});

// Update modal properties
updateContextModal({
  modalId: "editor-1",
  title: "View Data (Read Only)",
  size: "lg",
});

Context Modal Component

Interface for creating context modal components.

/**
 * Props interface for context modal components
 */
interface ContextModalProps<T extends Record<string, any> = {}> {
  /** Modal context providing access to modal methods */
  context: ModalsContextProps;
  /** Custom props passed when opening the modal */
  innerProps: T;
  /** Unique modal instance ID */
  id: string;
}

Creating Context Modals:

import { ContextModalProps } from "@mantine/modals";
import { Button, Text, TextInput, Stack } from "@mantine/core";

// User profile modal component
interface UserProfileProps {
  userId: string;
  editable?: boolean;
  onSave?: (data: any) => void;
}

const UserProfileModal: React.FC<ContextModalProps<UserProfileProps>> = ({
  context,
  id,
  innerProps,
}) => {
  const [userData, setUserData] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    // Load user data
    loadUser(innerProps.userId).then((data) => {
      setUserData(data);
      setLoading(false);
    });
  }, [innerProps.userId]);

  const handleSave = async () => {
    if (innerProps.onSave) {
      await innerProps.onSave(userData);
    }
    context.closeModal(id);
  };

  if (loading) {
    return <Text>Loading user profile...</Text>;
  }

  return (
    <Stack>
      <TextInput
        label="Name"
        value={userData.name}
        disabled={!innerProps.editable}
        onChange={(e) => setUserData({ ...userData, name: e.target.value })}
      />
      <TextInput
        label="Email"
        value={userData.email}
        disabled={!innerProps.editable}
        onChange={(e) => setUserData({ ...userData, email: e.target.value })}
      />
      
      {innerProps.editable && (
        <Button.Group>
          <Button variant="default" onClick={() => context.closeModal(id)}>
            Cancel
          </Button>
          <Button onClick={handleSave}>
            Save Changes
          </Button>
        </Button.Group>
      )}
      
      {!innerProps.editable && (
        <Button onClick={() => context.closeModal(id)}>
          Close
        </Button>
      )}
    </Stack>
  );
};

Registration and Type Safety

Register context modals with the provider and ensure type safety.

Provider Registration:

import { ModalsProvider } from "@mantine/modals";

// Register context modals
<ModalsProvider
  modals={{
    userProfile: UserProfileModal,
    deleteConfirmation: DeleteConfirmationModal,
    dataEditor: DataEditorModal,
  }}
>
  <App />
</ModalsProvider>

Module Augmentation for Type Safety:

// types/modals.ts
import { ContextModalProps } from "@mantine/modals";

declare module "@mantine/modals" {
  interface MantineModalsOverride {
    modals: {
      userProfile: ContextModalProps<{
        userId: string;
        editable?: boolean;
        onSave?: (data: any) => void;
      }>;
      deleteConfirmation: ContextModalProps<{
        itemName: string;
        itemType: string;
        onConfirm: () => void;
      }>;
      dataEditor: ContextModalProps<{
        data: any;
        readOnly?: boolean;
        onSubmit?: (data: any) => void;
      }>;
    };
  }
}

Advanced Context Modal Patterns

Complex context modal usage patterns and techniques.

Dynamic Modal Loading:

// Lazy-loaded context modal
const LazyFormModal = lazy(() => import("./FormModal"));

const DynamicFormModal: React.FC<ContextModalProps<{ formType: string }>> = (props) => {
  return (
    <Suspense fallback={<Text>Loading form...</Text>}>
      <LazyFormModal {...props} />
    </Suspense>
  );
};

// Register dynamic modal
<ModalsProvider
  modals={{
    dynamicForm: DynamicFormModal,
  }}
>
  <App />
</ModalsProvider>

Modal Communication:

// Modal that opens other modals
const ParentModal: React.FC<ContextModalProps<{ data: any }>> = ({
  context,
  id,
  innerProps,
}) => {
  const openChildModal = () => {
    context.openContextModal("childModal", {
      title: "Child Modal",
      innerProps: {
        parentId: id,
        data: innerProps.data,
        onComplete: (result) => {
          // Handle child modal completion
          updateContextModal({
            modalId: id,
            innerProps: {
              ...innerProps,
              data: { ...innerProps.data, ...result },
            },
          });
        },
      },
    });
  };

  return (
    <div>
      <Text>Parent Modal Content</Text>
      <Button onClick={openChildModal}>Open Child Modal</Button>
      <Button onClick={() => context.closeModal(id)}>Close</Button>
    </div>
  );
};

Context Modal with State Synchronization:

// Modal that syncs with external state
const SyncedModal: React.FC<ContextModalProps<{ 
  storeId: string;
  onStateChange: (state: any) => void;
}>> = ({ context, id, innerProps }) => {
  const [localState, setLocalState] = useState({});

  // Sync changes back to parent
  useEffect(() => {
    innerProps.onStateChange?.(localState);
  }, [localState]);

  // Listen for external updates
  useEffect(() => {
    const unsubscribe = subscribeToStore(innerProps.storeId, (newState) => {
      setLocalState(newState);
    });
    return unsubscribe;
  }, [innerProps.storeId]);

  return (
    <div>
      {/* Modal content that updates localState */}
    </div>
  );
};

docs

basic-modals.md

confirm-modals.md

context-modals.md

hook-usage.md

index.md

provider-setup.md

tile.json