---
name: modal_dialog
kind: component
lang: cpp
domain: core
version: "1.0.0"
purity: pure
signature: "bool fn_ui::modal_dialog_begin(const char* title, bool* open, ImVec2 size = ImVec2(0, 0)); void fn_ui::modal_dialog_end()"
description: "Popup modal centrada con titulo, estilo surface+border acorde con tokens, close con Escape o click en X. Patron begin/end."
tags: [imgui, modal, dialog, ui, form, tokens]
uses_functions: ["tokens_cpp_core"]
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: [imgui]
tested: true
tests:
  - "compiles and links against Catch2 (placeholder, visual cubierto en 0048)"
test_file_path: "cpp/tests/test_modal_dialog.cpp"
file_path: "cpp/functions/core/modal_dialog.cpp"
framework: imgui
params:
  - name: title
    desc: "Titulo visible en la cabecera del modal (tambien se usa como popup id de ImGui)"
  - name: open
    desc: "Puntero a bool que controla apertura (true abre, false cierra). Puede ser null si se gestiona el close desde dentro con ImGui::CloseCurrentPopup"
  - name: size
    desc: "Tamano fijo (x,y). (0,0) = autosize segun contenido"
output: "modal_dialog_begin devuelve true si el modal esta visible este frame; modal_dialog_end cierra siempre (llamar incondicionalmente)"
---

# modal_dialog

Popup modal centrada en el viewport con estilo consistente de tokens (`surface` bg, `border` 1px, `radius::md`, padding `lg`).

## Patron

```cpp
static bool show_add = false;
if (fn_ui::button("Add", ButtonVariant::Primary)) show_add = true;

if (fn_ui::modal_dialog_begin("Add App", &show_add, ImVec2(420, 0))) {
    static char name[128] = {};
    fn_ui::text_input("Name", name, sizeof(name));
    // ...
    if (fn_ui::button("Cancel", ButtonVariant::Subtle)) show_add = false;
    ImGui::SameLine();
    if (fn_ui::button("Create", ButtonVariant::Primary)) { do_create(); show_add = false; }
}
fn_ui::modal_dialog_end();
```

## Notas

- `modal_dialog_end` debe llamarse SIEMPRE, aunque `begin` devuelva false — hace pop de styles aunque no haya `EndPopup`.
- `AlwaysAutoResize` hace crecer el modal con el contenido hasta `size` si se pasa.
- Para forms multi-campo preferir `size.x > 0` fijo y `size.y = 0` (alto autosize).
