@clube-certo/front-commons
v1.0.3
Published
Biblioteca de componentes, funções e utils compartilhados para projetos Vue 3 do Clube Certo
Downloads
43
Maintainers
Readme
Front Commons - Biblioteca Vue 3
Biblioteca de componentes, funções e utils compartilhados para projetos Vue 3 do Clube Certo.
📦 Instalação
Via NPM (Recomendado)
npm install @clube-certo/front-commonsVia Git
npm install git+https://github.com/clubecerto/front-commons.git🚀 Uso
Importando Componentes
<template>
<div>
<AutoComplete
v-model="selectedUser"
:search-fn="searchUsers"
placeholder="Buscar usuário..."
/>
<Input
v-model="inputValue"
placeholder="Digite algo..."
type="text"
/>
</div>
</template>
<script setup>
import { ref } from "vue";
// Importação direta dos componentes Vue
import AutoComplete from "@clube-certo/front-commons/src/components/generic/AutoComplete.vue";
import Input from "@clube-certo/front-commons/src/components/generic/Input.vue";
const selectedUser = ref(null);
const inputValue = ref("");
const searchUsers = async (term) => {
// Implementar busca de usuários
return [];
};
</script>Importando Utilitários e Composables
// Importação de utilitários e composables (disponíveis no bundle principal)
import { formatCurrency, formatCPF, isValidEmail, httpClient, useApi, useLocalStorage } from "@clube-certo/front-commons";Usando Utilitários
import { formatCurrency, formatCPF, isValidEmail, httpClient } from "@clube-certo/front-commons";
// Formatação
const price = formatCurrency(1234.56); // R$ 1.234,56
const cpf = formatCPF("12345678901"); // 123.456.789-01
// Validação
const isValid = isValidEmail("[email protected]"); // true
// API
const response = await httpClient.get("/api/users");Usando Composables
<script setup>
import { ref } from "vue";
import { useApi, useLocalStorage, useValidation, useClipboard } from "@clube-certo/front-commons";
// API
const { data: users, loading, error } = useApi("/api/users");
// Storage
const [theme, setTheme] = useLocalStorage("theme", "light");
// Validação
const { data, errors, validate } = useValidation({
email: { required: true, pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/ },
password: { required: true, minLength: 8 },
});
// Clipboard
const { copy, copied } = useClipboard();
</script>📚 Documentação
Componentes Disponíveis
Componentes Genéricos
Formulários e Inputs
- AutoComplete - Campo de autocomplete com busca assíncrona e seleção de itens
- DatePicker - Seletor de data avançado com suporte a range, modo mês e formatos customizáveis
- Input - Campo de entrada versátil com máscaras, validação e tipos especiais (moeda, telefone, cor, CEP)
- InputCalendar - Calendário para seleção de data/hora com suporte a datetime
- Select - Dropdown altamente customizável com busca, múltipla seleção, agrupamento e modo simples/grupo
- Toggle - Switch segmentado com rótulos e ícones personalizáveis
- ValidatorErrors - Componente para exibição estruturada de erros de validação
- RichText - Editor de texto rico com toolbar customizável
Tabelas e Listas
- GenericTable - Tabela completa com paginação, ordenação, filtros, seleção múltipla e edição inline
- HeaderList - Cabeçalho de lista com controles de busca, filtros e botões de ação
- Pagination - Componente de paginação com informações detalhadas
Modais e Diálogos
- ConfirmDialog - Modal de confirmação com botões e estilos customizáveis
- GenericDialog - Modal genérico altamente configurável e reutilizável
- ModalFileReader - Modal avançado para importação e leitura de arquivos (Excel, CSV, OFX) com preview e edição
- SideForms - Formulários laterais deslizantes com posicionamento configurável
Visualização e Feedback
- Error - Página de erro com ilustração SVG animada
- Loader - Indicador de carregamento com overlay
- PhoneMockup - Simulação de notificação push em dispositivo móvel
- PhoneMockupFullscreen - Simulação completa de tela de aplicativo móvel com múltiplos templates
- Kanban - Board Kanban com drag & drop, filtros de coluna e estados customizáveis
Utilitários
- CopyText - Botão inteligente para copiar texto para clipboard com feedback
- ExcelExportModal - Modal completo para exportação de dados para Excel com seleção de colunas e renomeação
Upload e Mídia
- Dropzone - Área de upload com drag & drop, preview de arquivos e validação
- UploadIcon - Ícone dinâmico baseado no tipo de arquivo
Mapas
- Map - Componente de mapa interativo com Google Maps, círculos, polígonos e controles de zoom/raio
Exemplos de Uso dos Componentes Genéricos
AutoComplete
<template>
<AutoComplete
v-model="selectedUser"
:search-fn="searchUsers"
placeholder="Buscar usuário..."
label="name"
value="id"
/>
</template>
<script setup>
import { ref } from "vue";
import AutoComplete from "@clube-certo/front-commons/src/components/generic/AutoComplete.vue";
const selectedUser = ref(null);
const searchUsers = async (term) => {
const response = await fetch(`/api/users?search=${term}`);
return response.json();
};
</script>GenericTable
<template>
<GenericTable
:data="users"
:columns="columns"
:enable-pagination="true"
:enable-selection="true"
:editable="true"
:editable-columns-config="editableConfig"
@update:selectedItems="handleSelection"
/>
</template>
<script setup>
import { ref } from "vue";
import GenericTable from "@clube-certo/front-commons/src/components/generic/GenericTable.vue";
const users = ref([]);
const columns = [
{ accessorKey: "name", header: "Nome" },
{ accessorKey: "email", header: "Email" },
{ accessorKey: "status", header: "Status" },
];
const editableConfig = [
{ column: "name", type: "string" },
{
column: "status",
type: "select",
selectOptions: [
{ label: "Ativo", value: "active" },
{ label: "Inativo", value: "inactive" },
],
},
];
</script>Kanban
<template>
<Kanban
entity-name="tarefa"
:items="tasks"
id-item="id"
:status-list="statusList"
status-mapping="status"
@status-change="updateTaskStatus"
>
<template #default="{ item }">
<div class="task-card">
<h3>{{ item.title }}</h3>
<p>{{ item.description }}</p>
</div>
</template>
</Kanban>
</template>
<script setup>
import { ref } from "vue";
import Kanban from "@clube-certo/front-commons/src/components/generic/Kanban.vue";
const tasks = ref([]);
const statusList = [
{ value: 1, label: "A Fazer", cor: "#ff6b6b" },
{ value: 2, label: "Em Progresso", cor: "#4ecdc4" },
{ value: 3, label: "Concluído", cor: "#45b7d1" },
];
const updateTaskStatus = (newStatus, taskId) => {
// Atualizar status da tarefa
};
</script>ModalFileReader
<template>
<ModalFileReader
title="Importar Usuários"
type-file=".xlsx,.csv"
entity-search="users"
:search="true"
:mapping="{ nome: 'name', email: 'email' }"
@process-selected="processUsers"
@refetch-data="refreshData"
/>
</template>
<script setup>
import ModalFileReader from "@clube-certo/front-commons/src/components/generic/ModalFileReader.vue";
const processUsers = async (users) => {
try {
await api.post("/users/import", { users });
return { success: true };
} catch (error) {
return { error };
}
};
</script>DatePicker
<template>
<div>
<!-- Data simples -->
<DatePicker v-model="selectedDate" />
<!-- Seleção de mês -->
<DatePicker
v-model="selectedMonth"
:month="true"
/>
<!-- Range de datas -->
<DatePicker
v-model="dateRange"
:range="true"
:start="startDate"
:end="endDate"
@update:start="startDate = $event"
@update:end="endDate = $event"
/>
</div>
</template>
<script setup>
import { ref } from "vue";
import DatePicker from "@clube-certo/front-commons/src/components/generic/DatePicker.vue";
const selectedDate = ref(null);
const selectedMonth = ref(null);
const dateRange = ref(null);
const startDate = ref(null);
const endDate = ref(null);
</script>📋 Documentação Detalhada dos Componentes
AutoComplete
Descrição: Campo de autocomplete com busca assíncrona e seleção de itens.
Props:
modelValue(String/Number) - Valor selecionadoplaceHolder(String, default: 'Select framework...') - Texto placeholdernotFoundMessage(String, default: 'No framework found.') - Mensagem quando não encontra resultadossearchFn(Function) - Função de busca assíncronalabel(String, default: 'label') - Propriedade para exibição do textovalue(String, default: 'value') - Propriedade para o valordisabled(Boolean, default: false) - Desabilita o componente
Eventos:
update:modelValue- Emitido quando o valor é alterado
Exemplo:
<AutoComplete v-model="selectedUser" :search-fn="searchUsers" placeholder="Buscar usuário..." label="name" value="id" :disabled="false" />ConfirmDialog
Descrição: Modal de confirmação com botões e estilos customizáveis.
Props:
titulo(String, required) - Título do modaltextoConfirmacao(String, required) - Texto de confirmaçãolabelBotaoCancelar(String, default: 'Cancelar') - Texto do botão cancelarlabelBotaoConfirmar(String, default: 'Confirmar') - Texto do botão confirmarclassBotaoCancelar(String, default: 'bg-red-100 text-red-600') - Classes CSS do botão cancelarclassBotaoConfirmar(String, default: 'bg-green-600 text-white') - Classes CSS do botão confirmar
Eventos:
click:button-cancelar- Emitido ao clicar em cancelarclick:button-confirmar- Emitido ao clicar em confirmar
Slots:
button-trigger- Slot para o botão que abre o modal
CopyText
Descrição: Botão inteligente para copiar texto para clipboard com feedback.
Props:
text(String, required) - Texto a ser copiadolabel(String, default: '') - Rótulo do botãoshowIcon(Boolean, default: true) - Exibe ícone de cópiaentityName(String, default: 'Texto') - Nome da entidade para feedbackshowText(Boolean, default: true) - Exibe o texto no botão
Exemplo:
<CopyText text="Texto para copiar" label="Copiar:" entity-name="Código" :show-icon="true" :show-text="true" />DatePicker
Descrição: Seletor de data avançado com suporte a range, modo mês e formatos customizáveis.
Props:
modelValue(DateValue/String/DateRange) - Valor da dataplaceholder(String, default: 'Selecione uma data') - PlaceholderformatOptions(Object, default: { dateStyle: 'short' }) - Opções de formataçãolocale(String, default: 'pt-BR') - Localizaçãomonth(Boolean, default: false) - Modo seleção de mêsrange(Boolean, default: false) - Modo range de datasstart(DateValue) - Data inicial (modo range)end(DateValue) - Data final (modo range)
Eventos:
update:modelValue- Emitido quando o valor é alteradoupdate:start- Emitido quando a data inicial é alterada (modo range)update:end- Emitido quando a data final é alterada (modo range)
GenericTable
Descrição: Tabela completa com paginação, ordenação, filtros, seleção múltipla e edição inline.
Props:
data(Array, required) - Dados da tabelacolumns(Array) - Configuração das colunasautoGenerateColumns(Boolean, default: true) - Gerar colunas automaticamenteenablePagination(Boolean, default: true) - Habilitar paginaçãoinitialPageSize(Number, default: 50) - Tamanho inicial da páginaenableGlobalFilter(Boolean, default: true) - Habilitar busca globalenableSorting(Boolean, default: true) - Habilitar ordenaçãoenableSelection(Boolean, default: false) - Habilitar seleção múltiplaselectionKey(String, default: 'id') - Chave para seleçãoeditable(Boolean, default: false) - Habilitar ediçãoeditableColumnsConfig(Array) - Configuração de colunas editáveis
Eventos:
update:selectedItems- Emitido quando itens são selecionadosupdate:data- Emitido quando dados são editados
Input
Descrição: Campo de entrada versátil com máscaras, validação e tipos especiais.
Props:
modelValue(String) - Valor do inputtype(String, default: 'text') - Tipo do inputplaceholder(String) - Placeholdersize(String, default: 'default') - Tamanho do inputdisabled(Boolean, default: false) - Desabilitar inputreadonly(Boolean, default: false) - Somente leituramoney(Boolean, default: false) - Modo moedaphone(Boolean, default: false) - Modo telefonecolor(Boolean, default: false) - Modo corcep(Boolean, default: false) - Modo CEPdataMaska(String) - Máscara personalizadaicon(String) - Ícone do inputiconDir(String) - Direção do ícone ('left' ou 'right')
Eventos:
update:modelValue- Emitido quando o valor é alteradoblur- Emitido quando o input perde o foco
Kanban
Descrição: Board Kanban com drag & drop, filtros de coluna e estados customizáveis.
Props:
entityName(String, required) - Nome da entidadeitems(Array, required) - Lista de itensidItem(String, required) - Campo ID dos itensstatusList(Array, required) - Lista de status/colunasstatusMapping(String, required) - Mapeamento do campo statusonStatusChange(Function) - Função para alterar statusonStatusMutation(Function) - Função alternativa para alterar statuscardComponent(Component) - Componente do cardloading(Boolean, default: false) - Estado de carregamento
Eventos:
- Não emite eventos diretamente, usa as funções
onStatusChangeouonStatusMutation
Slots:
default- Slot para o conteúdo do card (recebe{ item })
Select
Descrição: Dropdown altamente customizável com busca, múltipla seleção e agrupamento.
Props:
modelValue(String/Number/Array) - Valor selecionadomultiple(Boolean, default: false) - Seleção múltiplaoptions(Array, required) - Opções do selectplaceholder(String, default: 'Selecione uma opção') - Placeholdermode(String, default: 'simple') - Modo ('simple' ou 'group')clearable(Boolean, default: true) - Permitir limpar seleçãosearch(Boolean, default: false) - Habilitar buscahideSelected(Boolean, default: false) - Ocultar itens selecionadoslabel(String, default: 'label') - Propriedade para labelvalue(String, default: 'value') - Propriedade para valorgroupName(String, default: 'group') - Propriedade para agrupamento
Eventos:
update:modelValue- Emitido quando o valor é alterado
ModalFileReader
Descrição: Modal avançado para importação e leitura de arquivos com preview e edição.
Props:
title(String, default: 'Importação de Arquivo') - Título do modaldescription(String) - Descrição do modaltypeFile(String, default: '.xls,.xlsx,.ofx,.csv,.numbers') - Tipos de arquivo aceitosentitySearch(String, default: 'noentity') - Entidade para buscasearch(Boolean, default: false) - Habilitar busca/comparaçãomapping(Object) - Mapeamento de colunasofxFilter(String) - Filtro para arquivos OFX ('all', 'expenses', 'revenues')editable(Boolean, default: false) - Habilitar ediçãoeditableColumnsConfig(Array) - Configuração de colunas editáveischunkSize(Number, default: 100) - Tamanho do chunk para importaçãochunkInterval(Number, default: 1000) - Intervalo entre chunksplanilhaModeloNome(String) - Nome da planilha modelodadosPlanilhaModelo(Array) - Dados da planilha modelo
Eventos:
process-selected- Emitido para processar itens selecionadosrefetch-data- Emitido para recarregar dados
Toggle
Descrição: Switch segmentado com rótulos e ícones personalizáveis.
Props:
modelValue(Boolean) - Valor do toggleleftLabel(String, default: 'One Way') - Rótulo da esquerdarightLabel(String, default: 'Return') - Rótulo da direitaleftIcon(String) - Ícone da esquerdarightIcon(String) - Ícone da direitadisabled(Boolean, default: false) - Desabilitar togglevariant(String, default: 'default') - Variante de cor
Eventos:
update:modelValue- Emitido quando o valor é alterado
Dropzone
Descrição: Área de upload com drag & drop, preview de arquivos e validação.
Props:
modelValue(Array, default: []) - Arquivos selecionadosmultiple(Boolean, default: false) - Múltiplos arquivospreviews(Array, default: []) - URLs de previewmode(String, default: 'drop') - Modo ('drop' ou 'preview')disabled(Boolean, default: false) - Desabilitar componenteaccept(String) - Tipos de arquivo aceitosmaxFileSize(Number, default: 5) - Tamanho máximo em MBmaxFiles(Number, default: 5) - Número máximo de arquivosshowSelectButton(Boolean, default: true) - Exibir botão de seleção
Eventos:
drop- Emitido quando arquivos são soltosupdate:modelValue- Emitido quando arquivos são alteradoserror- Emitido em caso de erro
Slots:
placeholder-img- Slot para imagem placeholdertitle- Slot para títulobutton- Slot para botão personalizadodescription- Slot para descriçãopreview- Slot para preview personalizado
Map
Descrição: Componente de mapa interativo com Google Maps, círculos e polígonos.
Props:
center(Object, default: { lat: 37.7749, lng: -122.4194 }) - Centro do mapanational(Boolean, default: false) - Modo nacionalzoom(Number, default: 13) - Zoom inicialgeolocations(Array, default: []) - Lista de geolocalizações
Eventos:
update:range- Emitido quando o raio é alterado
Funcionalidades:
- Controle de raio de disparo
- Controle de zoom
- Círculos e polígonos baseados em geolocalizações
- Detecção automática de localização
Utilitários
Formatação
formatCurrency(value, currency?, locale?)- Formatar moedaformatCPF(cpf)- Formatar CPFformatCNPJ(cnpj)- Formatar CNPJformatPhone(phone)- Formatar telefoneformatCEP(cep)- Formatar CEPformatDate(date, format?, locale?)- Formatar data
Cores
hexToHSL(hex)- Converte cor hexadecimal para formato HSLdarkenColor(hex, percent)- Escurece uma cor hexadecimal em uma porcentagem específicalightenColor(hex, percent)- Clareia uma cor hexadecimal em uma porcentagem específica
Exemplos de Uso das Funções de Cores
import { hexToHSL, darkenColor, lightenColor } from "@clube-certo/front-commons";
// Conversão de hexadecimal para HSL
const hslColor = hexToHSL("#00A24D"); // "123 100% 32%"
const hslFromShort = hexToHSL("#0A2"); // "123 100% 32%" (expande automaticamente)
// Escurecer uma cor
const darkerGreen = darkenColor("#00A24D", 20); // Escurece 20%
const muchDarker = darkenColor("#FF5733", 50); // Escurece 50%
// Clarear uma cor
const lighterGreen = lightenColor("#00A24D", 30); // Clareia 30%
const muchLighter = lightenColor("#FF5733", 60); // Clareia 60%
// Uso prático em temas dinâmicos
const primaryColor = "#007bff";
const hoverColor = darkenColor(primaryColor, 15);
const activeColor = darkenColor(primaryColor, 25);
const lightVariant = lightenColor(primaryColor, 40);
// Aplicação em CSS-in-JS ou estilos dinâmicos
const buttonStyles = {
backgroundColor: primaryColor,
":hover": {
backgroundColor: hoverColor,
},
":active": {
backgroundColor: activeColor,
},
};Validação
isValidEmail(email)- Validar emailisValidCPF(cpf)- Validar CPFisValidCNPJ(cnpj)- Validar CNPJisValidPhone(phone)- Validar telefoneisStrongPassword(password)- Validar senha forte
API
A biblioteca oferece um conjunto completo de utilitários para requisições HTTP baseados em Axios:
Funções Principais
get<T>(controllerName, action?, extraParams?)- Requisições GETgetQueryParams<T>(controllerName, action?, extraParams?)- GET com parâmetros customizadospost<T>(controllerName, action?, data, extraParams?)- Requisições POSTput<T>(controllerName, action?, data?, extraParams?)- Requisições PUTpatch<T>(controllerName, action?, data, extraParams?)- Requisições PATCHdel<T>(controllerName, action?, extraParams?, body?)- Requisições DELETEupload<T>(controllerName, action?, data, extraParams?)- Upload de arquivospostDownload(controllerName, action?, data, extraParams?)- Download de arquivos
Configuração e Autenticação
getDecodedToken()- Decodificar token JWT do localStoragesetAuthToken(token)- Configurar token de autorizaçãoremoveAuthToken()- Remover token de autorizaçãosetHeader(key, value)- Configurar header globalremoveHeader(key)- Remover headerhttpClient- Instância do Axios configurada
Utilitários Adicionais
retryRequest(requestFn, maxRetries?, delay?)- Retry automático de requisiçõescreatePaginationParams(page, limit)- Criar parâmetros de paginaçãoparsePaginationResponse<T>(response)- Processar resposta paginada
Exemplos de Uso
import { get, post, put, del, upload, setAuthToken, getDecodedToken } from "@clube-certo/front-commons";
// Configurar autenticação
setAuthToken("seu-jwt-token");
// Obter dados decodificados do token
const userData = getDecodedToken();
// Requisições básicas
const users = await get("users");
const user = await get("users", "123");
const newUser = await post("users", "", { name: "João", email: "[email protected]" });
const updatedUser = await put("users", "123", { name: "João Silva" });
await del("users", "123");
// Requisições com parâmetros
const filteredUsers = await get("users", "", {
page: 1,
itensPerPage: 10,
status: "active",
});
// Requisições com parâmetros customizados
const searchResults = await getQueryParams("search", "", [
{ key: "q", value: "termo de busca" },
{ key: "category", value: "produtos" },
]);
// Upload de arquivo
const formData = new FormData();
formData.append("file", file);
const uploadResult = await upload("files", "upload", formData);
// Download de arquivo
const blob = await postDownload("reports", "generate", {
type: "pdf",
filters: { startDate: "2023-01-01" },
});
// Retry automático
const dataWithRetry = await retryRequest(
() => get("unstable-endpoint"),
3, // máximo 3 tentativas
1000 // delay de 1 segundo
);Configuração de Ambiente
Configure a URL base da API através da variável de ambiente:
# .env
VITE_API_URL=https://api.exemplo.com/Se não configurada, será usado http://localhost:3030/ por padrão.
Storage
localStorage- Wrapper para localStoragesessionStorage- Wrapper para sessionStoragecookies- Utilitários para cookiesMemoryCache- Cache em memória com TTL
Toast Notifications
A biblioteca inclui utilitários completos para exibição de notificações toast usando vue3-toastify:
prepareToast(functionToCall, successMessage?, errorMessage?)- Executa função assíncrona com toasts automáticoserrorToast(errorMessage?, description?)- Exibe toast de errosuccessToast(successMessage?, description?)- Exibe toast de sucessoinfoToast(infoMessage?, description?)- Exibe toast informativowarningToast(warningMessage?, description?)- Exibe toast de avisocn(...inputs)- Combina classes CSS usando clsx e tailwind-merge
Configuração dos Toasts
Para usar os toasts, configure o vue3-toastify em sua aplicação:
// main.ts
import { createApp } from "vue";
import Vue3Toastify, { type ToastContainerOptions } from "vue3-toastify";
import "vue3-toastify/dist/index.css";
const app = createApp(App);
app.use(Vue3Toastify, {
autoClose: 3000,
// outras opções...
} as ToastContainerOptions);Exemplos de Uso dos Toasts
import { prepareToast, successToast, errorToast, warningToast, infoToast } from "@clube-certo/front-commons";
// Toast com função assíncrona
await prepareToast(() => api.saveData(data), "Dados salvos com sucesso!", "Erro ao salvar dados");
// Toasts simples
successToast("Operação realizada com sucesso!");
errorToast("Erro de validação", "O campo email é obrigatório");
warningToast("Sessão expirando", "Sua sessão expirará em 5 minutos");
infoToast("Nova funcionalidade", "Agora você pode exportar relatórios em PDF");Schemas de Validação (Zod)
A biblioteca inclui schemas de validação pré-configurados usando Zod para validação de dados comuns:
schemas.cpf- Validação de CPF brasileiroschemas.cnpj- Validação de CNPJ brasileiroschemas.email- Validação de emailschemas.fullName- Validação de nome completo (mínimo 2 palavras)schemas.cep- Validação de CEP no formato 99.999-999schemas.celular- Validação de celular no formato (99)99999-9999schemas.creditCard- Validação de cartão de créditoschemas.senha- Validação de senha forte (8+ caracteres, maiúscula, minúscula, número, especial)schemas.url- Validação de URL (http/https)schemas.money- Validação de valor monetário (formato 123.45)schemas.date- Validação de dataschemas.dateTime- Validação de data e hora (ISO 8601)schemas.calendar- Schema para datas de calendário
Exemplos de Uso dos Schemas
import { schemas } from "@clube-certo/front-commons";
// Validação de CPF
try {
const cpf = schemas.cpf.parse("123.456.789-01");
console.log("CPF válido:", cpf);
} catch (error) {
console.error("CPF inválido:", error.message);
}
// Validação de email
const emailResult = schemas.email.safeParse("[email protected]");
if (emailResult.success) {
console.log("Email válido:", emailResult.data);
} else {
console.error("Email inválido:", emailResult.error.issues);
}
// Validação de senha
const senhaResult = schemas.senha.safeParse("MinhaSenh@123");
if (senhaResult.success) {
console.log("Senha válida");
} else {
console.error("Senha inválida:", senhaResult.error.issues[0].message);
}
// Validação de valor monetário
const valorResult = schemas.money.safeParse("1234.56");
if (valorResult.success) {
console.log("Valor válido:", valorResult.data);
}
// Validação de nome completo
const nomeResult = schemas.fullName.safeParse("João Silva Santos");
if (nomeResult.success) {
console.log("Nome válido:", nomeResult.data);
}
// Validação de CNPJ
const cnpjResult = schemas.cnpj.safeParse("12.345.678/0001-90");
if (cnpjResult.success) {
console.log("CNPJ válido:", cnpjResult.data);
}
// Uso em formulários Vue com validação
import { z } from "zod";
const formSchema = z.object({
nome: schemas.fullName,
email: schemas.email,
cpf: schemas.cpf,
celular: schemas.celular,
senha: schemas.senha,
cep: schemas.cep,
valorPedido: schemas.money,
});
// Validação de objeto completo
const dadosFormulario = {
nome: "João Silva Santos",
email: "[email protected]",
cpf: "123.456.789-01",
celular: "(11)99999-9999",
senha: "MinhaSenh@123",
cep: "01234-567",
valorPedido: "150.00",
};
try {
const dadosValidados = formSchema.parse(dadosFormulario);
console.log("Formulário válido:", dadosValidados);
} catch (error) {
console.error("Erros de validação:", error.issues);
}Schemas Disponíveis
| Schema | Descrição | Formato Esperado | Exemplo |
| ------------ | ------------------ | ------------------------------------------------ | --------------------------------- |
| cpf | CPF brasileiro | Com ou sem máscara | "123.456.789-01" ou "12345678901" |
| cnpj | CNPJ brasileiro | Com ou sem máscara | "12.345.678/0001-90" |
| email | Email válido | Formato padrão | "[email protected]" |
| fullName | Nome completo | Mínimo 2 palavras, 5 caracteres | "João Silva" |
| cep | CEP brasileiro | Formato 99.999-999 | "01234-567" |
| celular | Celular brasileiro | Formato (99)99999-9999 | "(11)99999-9999" |
| creditCard | Cartão de crédito | 16 dígitos com ou sem traços | "1234-5678-9012-3456" |
| senha | Senha forte | 8+ chars, maiúscula, minúscula, número, especial | "MinhaSenh@123" |
| url | URL válida | Deve começar com http/https | "https://exemplo.com" |
| money | Valor monetário | Formato decimal | "1234.56" |
| date | Data válida | Qualquer formato de data válido | "2023-12-25" |
| dateTime | Data e hora | Formato ISO 8601 | "2023-12-25T10:30:00Z" |
| calendar | Data de calendário | Coerção para Date | Date object |
DOM
querySelector()- Seletor de elementoscreateElement()- Criar elementoscopyToClipboard()- Copiar para clipboardscrollToElement()- Scroll suavedebounce()- Debounce de funçõesthrottle()- Throttle de funções
Composables
useApi
const { data, loading, error, execute } = useApi("/api/endpoint");
const { post } = usePost("/api/create");
const { put } = usePut("/api/update");
const { remove } = useDelete("/api/delete");useStorage
const [value, setValue] = useLocalStorage("key", defaultValue);
const [sessionValue, setSessionValue] = useSessionStorage("key", defaultValue);useValidation
const { data, errors, isValid, validate } = useValidation(rules);useDebounce
const debouncedValue = useDebounce(value, 500);
const debouncedFn = useDebouncedFunction(fn, 300);useClipboard
const { copy, copied, isSupported } = useClipboard();useDevice
const { deviceType, isMobile, isTablet, orientation } = useDevice();🛠️ Desenvolvimento
Configuração do Ambiente
# Instalar dependências
npm install
# Executar em modo desenvolvimento
npm run dev
# Build da biblioteca
npm run build
# Executar testes
npm run test
# Lint do código
npm run lintEstrutura do Projeto
src/
├── components/ # Componentes Vue
├── composables/ # Composables do Vue 3
├── utils/ # Funções utilitárias
│ ├── api.ts # Utilitários de API
│ ├── dom.ts # Utilitários DOM
│ ├── format.ts # Formatação
│ ├── storage.ts # Armazenamento
│ └── validation.ts # Validação
├── types/ # Tipos TypeScript
└── index.ts # Exportações principais📦 Publicação no NPM
Pré-requisitos
Antes de publicar uma nova versão, certifique-se de estar logado no NPM:
# Login no NPM
npm login
# Credenciais:
# Username: clube-certo
# Password: [mesma senha da AWS]
# Email: [email associado à conta]Processo de Publicação
Atualizar o código e fazer commit das alterações:
git add . git commit -m "feat: descrição das alterações" git push origin mainAtualizar a versão no package.json:
# Para patch (correções de bugs): 1.0.0 -> 1.0.1 npm version patch # Para minor (novas funcionalidades): 1.0.0 -> 1.1.0 npm version minor # Para major (breaking changes): 1.0.0 -> 2.0.0 npm version majorGerar o build da biblioteca:
npm run buildPublicar no NPM:
npm publish --access publicFazer push da tag de versão:
git push origin --tags
Verificação da Publicação
Após a publicação, você pode verificar se a nova versão está disponível:
# Verificar versões disponíveis
npm view @clube-certo/front-commons versions --json
# Verificar informações da versão atual
npm view @clube-certo/front-commonsNotas Importantes
- ⚠️ Sempre teste localmente antes de publicar uma nova versão
- 📋 Documente as alterações no commit e considere manter um CHANGELOG
- 🔄 Use versionamento semântico (SemVer) para as versões
- 🧪 Execute os testes antes da publicação:
npm run test - 🔍 Verifique o lint antes da publicação:
npm run lint
📝 Contribuição
- Fork o projeto
- Crie uma branch para sua feature (
git checkout -b feature/nova-feature) - Commit suas mudanças (
git commit -am 'Adiciona nova feature') - Push para a branch (
git push origin feature/nova-feature) - Abra um Pull Request
📄 Licença
MIT © Clube Certo
