MODULO 4.3

💬 Dialog UI

Como o Claude Code renderiza todos os elementos interativos de UI no terminal usando React e Ink, desde launchers ate primitivos de design system.

7
Topicos
~50
Minutos
Deep
Nivel
Source
Tipo
1

🏗️ Arquitetura de 4 Camadas

Layer 1: Launchers (dialogLaunchers.tsx)

Funcoes async retornando Promises tipadas

Layer 2: Helpers (interactiveHelpers.tsx)

Wrappers showDialog / showSetupDialog

Layer 3: Design System

Primitivos: Dialog, Pane, PermissionDialog

Layer 4: Feature Components

Requests de permissao tool-specific e paginas de wizard

2

🎨 Primitivos do Design System

🗔️

Dialog

Chrome padrao para interacoes confirm/cancel

📋

Pane

Regiao sem borda para telas de slash-command

🔒

PermissionDialog

Frame especializado para requests de permissao de tools

3

🛡️ Permission Requests

BashPermissionRequest e o mais complexo, com integracao de classifier, regras de "allow prefix", avisos de comandos destrutivos e fallback para sandbox.

⚡ ClassifierCheckingSubtitle

Extraido porque um clock de shimmer a 20fps re-renderizaria a arvore inteira de 535 linhas a cada 50ms. A extracao isola o re-render apenas ao subtitle.

4

🎛️ CustomSelect Widget

Widget de input universal com duas variantes:

TextOption

Opcao padrao com label e valor

InputOption

Embute campo de texto ao vivo dentro da lista de selecao

5

🧙 Wizard Pattern

WizardProvider -- State container
useWizard -- Hook para navegacao
WizardDialogLayout -- Chrome per-step com titulo auto-computado
WizardNavigationFooter -- Footer contextual
6

🗺️ Arquitetura Completa

flowchart TD
    A["main.tsx\nsetupScreens()"] -->|"await"| B["dialogLaunchers.tsx\nlaunchXxx(root, props)"]
    B -->|"dynamic import"| C["Component Module\ne.g. SnapshotUpdateDialog"]
    B -->|"calls"| D["interactiveHelpers.tsx\nshowSetupDialog()"]
    D -->|"wraps in"| E["AppStateProvider\n+ KeybindingSetup"]
    E -->|"root.render()"| F["Dialog / PermissionDialog / Pane\ndesign-system primitives"]
    F --> G["Feature Component\ne.g. InvalidSettingsDialog,\nBashPermissionRequest"]
    G --> H["CustomSelect\nor TextInput"]
    H -->|"user selects"| I["done(result)\nresolves Promise"]
    I -->|"returns typed value"| A
                    
7

🔄 Ciclo de Vida do Dialog

sequenceDiagram
    participant M as main.tsx
    participant DL as dialogLaunchers.tsx
    participant IH as interactiveHelpers.tsx
    participant R as Ink Root
    participant C as Dialog Component
    participant U as User
    M->>DL: await launchXxxDialog(root, props)
    DL->>DL: dynamic import(component)
    DL->>IH: showSetupDialog(root, renderer)
    IH->>R: root.render(AppStateProvider + KeybindingSetup)
    R->>C: mount Dialog/PermissionDialog with keybindings
    C->>U: display in terminal
    U-->>C: keypress (Enter / Esc / arrow)
    C->>C: useKeybinding fires
    C->>IH: done(selectedValue)
    IH->>DL: Promise resolves with typed value
    DL->>M: returns typed result
                    

📋 Resumo do Modulo

Dialogos se tornam funcoes async retornando Promises tipadas
showSetupDialog e o unico local onde AppStateProvider e KeybindingSetup sao adicionados
isCancelActive resolve conflitos de text input
Permission requests usam roteamento por switch unico
Wizards gerenciam seu proprio ciclo de vida de saida
Modulo Anterior Proximo Modulo