Docs›Componentes (Admin)›mad-avatar-field
Componentes (Admin)

mad-avatar-field

Foto de perfil com layout circular compacto.

Campo de formulário específico para foto de perfil/usuário. Layout horizontal: círculo à esquerda, botões e dicas à direita. Auto-salva via form->save($record) igual ao <mad-image-field> e <mad-file-field>.

Use este componente em telas de perfil/configurações/cadastro de usuário. Para imagens gerais (produto, capa, banner) use <mad-image-field>. Para o componente de display (avatar circular em listas, headers), veja <mad-avatar> — são dois componentes distintos.

Props

Prop Tipo Default Descrição
name string '' Nome do campo (obrigatório)
label string '' Label superior
description string '' Texto secundário abaixo do label
value string '' Valor atual (path/URL/base64)
size string '96px' Diâmetro do círculo (normalizado por CssUnits::length — 96 vira 96px)
accept string 'image/png,image/jpeg' MIME types aceitos
max-size string '5MB' Tamanho máximo (KB, MB, GB)
btn-text string 'Trocar foto' Texto do botão de upload
btn-remove string 'Remover' Texto do botão de remover
removable bool true Habilita o botão de remover
storage string '' disk (filesystem) ou db (BLOB base64 no banco)
folder string 'uploads' Diretório destino (storage="disk")
name-column string '' Coluna para o nome original do arquivo
file-name string 'prefix' Modo do nome: prefix, unique, original, record
width string '' Largura CSS do wrapper (ex: '320px')
max-width string '' max-width CSS do wrapper
hint string '' Texto de ajuda
error string '' Mensagem de erro
required bool false Campo obrigatório
disabled bool false Campo desabilitado
attrs string '' Atributos HTML extras

Upload simples (base64)

<mad-avatar-field name="foto" label="Foto de perfil" />

Storage automático (disco)

<mad-avatar-field name="photo" label="Profile photo"
    description="Esta foto será exibida no seu perfil"
    storage="disk" folder="uploads/avatars" name-column="photo_name"
    accept="image/png,image/jpeg,image/webp" max-size="2MB" />
use Illuminate\Support\Facades\DB;

// Controller — zero código de arquivo
public function onSave(): MadResponse
{
    DB::connection('business')->transaction(function () {
        $user = SystemUsers::findOrNew($this->registroId);
        $this->form->save($user);
        // $user->photo      = 'uploads/avatars/uniqid_foto.jpg'
        // $user->photo_name = 'foto.jpg'
    });

    return (new MadResponse())->toast('Salvo!', 'success')->closeDrawer();
}

Onde o arquivo realmente é gravado

Com storage="disk" o componente não escreve no filesystem direto — todo o I/O passa pelo Storage/Flysystem do Laravel (Mad\Service\MadUploadStorage):

  • Disco default: mad_uploads, declarado em config/filesystems.php, apontando para storage/app/mad.
  • Para mandar os uploads para outro destino (S3, MinIO, etc), configure MAD_UPLOAD_DISK (lido via config('mad.uploads.disk')). O disco precisa existir em config/filesystems.php — apontar para um disco inexistente lança exception explícita no boot do upload.
  • O que vai para o banco é sempre o path relativo (ex. uploads/avatars/652f_foto.jpg), nunca um caminho absoluto — por isso trocar o disco não invalida os registros já gravados.
  • folder é validado em tempo de render por MadUploadPath::assertValidFolder() — path traversal (..) e caminho absoluto abortam o render com erro nomeando o campo, em vez de gravar fora da raiz.

O preview não aponta para o arquivo: o componente gera a URL por mad_download_url($path), uma URL de download assinada servida pelo MadDownloadController. Isso é o que permite o avatar funcionar igual com disco local e com S3 privado — e é o motivo de nunca montar <img src="storage/..."> à mão para o valor do campo.

Storage automático (BLOB no banco)

<mad-avatar-field name="photo_blob" label="Foto"
    storage="db" name-column="photo_name" />
// onEdit — extrair BLOB para tmp
$this->form->loadBlob($user, 'photo_blob', 'photo_name');
$this->form->fill($user);

// onSave
$this->form->save($user);

Com valor pré-carregado

<mad-avatar-field name="photo" label="Foto"
    :value="$user->photo"
    storage="disk" folder="uploads/avatars" />

Callback ao selecionar (mad:change)

Mesma API do mad-file-field / mad-image-field — recebe o path temporário.

<mad-avatar-field name="photo" label="Foto"
    storage="disk" folder="uploads/avatars"
    mad:change="onPhotoChange" />
public function onPhotoChange(string $tempPath): void
{
    $size = getimagesize($tempPath);
    $this->form->set('dimensoes', $size[0] . 'x' . $size[1]);
}

Dentro de form-section

<mad-form submit="onSave">
    <mad-form-section title="Perfil" icon="user">
        <mad-avatar-field name="photo" label="Foto de perfil"
            description="JPG, PNG ou WebP. Máximo 2MB."
            storage="disk" folder="uploads/avatars" name-column="photo_name"
            accept="image/png,image/jpeg,image/webp" max-size="2MB" />

        <mad-form-grid :cols="2">
            <mad-input-field name="nome" label="Nome" required />
            <mad-input-field name="email" label="Email" />
        </mad-form-grid>
    </mad-form-section>

    <mad-form-actions>
        <mad-btn type="submit" variant="primary" icon="save">Salvar</mad-btn>
    </mad-form-actions>
</mad-form>

Quando usar avatar-field vs image-field

Cenário Usar
Foto de perfil de usuário / cadastro de pessoa <mad-avatar-field>
Imagem de produto / capa / banner / qualquer imagem geral <mad-image-field>
Precisa de crop, rotate, zoom, câmera <mad-image-field>
Layout horizontal compacto (círculo + botão + dicas) <mad-avatar-field>

NUNCA fazer

{{-- ERRADO: usar mad-input-field type="file" para foto de perfil --}}
<mad-input-field name="photo" label="Foto" type="file" />

{{-- CERTO --}}
<mad-avatar-field name="photo" label="Foto" storage="disk" folder="uploads/avatars" />

{{-- ERRADO: usar mad-image-field para foto de perfil simples --}}
<mad-image-field name="photo" label="Foto" storage="disk" folder="uploads/avatars" />

{{-- CERTO: avatar-field tem o layout circular já pronto --}}
<mad-avatar-field name="photo" label="Foto" storage="disk" folder="uploads/avatars" />

{{-- ERRADO: código de arquivo manual no controller --}}
move_uploaded_file($_FILES['photo']['tmp_name'], $dest);
$user->photo = $dest;

{{-- CERTO: declarar storage e usar form->save --}}
{{-- Blade: <mad-avatar-field storage="disk" folder="uploads/avatars" /> --}}
$this->form->save($user);