jksantos/jetax
Jetax é um design system opinativo para a TALL Stack em PHP 8.4+ e Laravel 12+: rode o instalador e tenha sidebar, topbar, workspace e 60+ componentes Blade/Livewire prontos, com dark mode nativo, tipografia Manrope/Inter e tudo publicável para customização.
Versão major: alinha a forma dos componentes (raio, altura, padding, largura, borda, sombra,
glifo, caixa e cor de borda de estado) aos mockups do VetSoft no Claude Design. As divergências
medidas viraram as issues JETAX-029 a JETAX-047. Nenhuma chave existente de SIZES, STYLES,
COLORS ou GLYPH_SIZES foi removida, mas vários defaults visuais mudaram: os itens marcados com
[BREAKING] mudam a aparência ou o comportamento de quem usa a 3.x sem prop explícita, e o passo
a passo de cada um está no guia de migração UPGRADE.md.
md: 14 → 15 px (JETAX-030): Button::GLYPH_SIZES['md'] passa de text-[14px] a text-[15px], com e sem icon-only; sm (12 px) e lg (18 px) não mudam. Ver UPGRADE.mdsm vira h-[34px] com raio 8 px; md vira h-11 (44 px) no solid/soft e h-10 (40 px) com px-[18px] no outline; lg vira h-[52px] com raio 10 px; o só-ícone sm vira 34 px e o md ganha raio 10 px; a borda do outline passa de border-2 a border; size inválido segue a regra de variante inválida. Ver UPGRADE.mdModal::SIZES (JETAX-031): md passa de max-w-xl (576 px) a max-w-[560px] e lg de max-w-4xl (896 px) a max-w-[660px]; o painel ganha raio 14 px e a sombra do mockup; size inválido segue a regra de variante inválida. Ver UPGRADE.mdmax-w-md (448 px) a max-w-[460px], e os painéis ganham raio 14 px, borda border-outline-variant e a sombra do modal. Ver UPGRADE.mdrounded-xl → rounded-[10px], borda border-outline-variant nos dois temas e sem sombra no tema claro. Ver UPGRADE.mdborder-outline-variant e sem a sombra inline; células th e td com px-4 py-3.5. Ver UPGRADE.mdrounded-full → rounded-[6px], md com px-2 py-0.5 leading-[15px] e estilo status sem borda. Ver UPGRADE.mdpl-2.5 e borda padrão border-primary/18. Ver UPGRADE.mdrounded-lg → rounded-[8px] e padding horizontal px-4 → px-3. Ver UPGRADE.mdrounded-lg → rounded-[8px] e padding px-4 py-3 → p-2.5. Ver UPGRADE.mdp-12 → px-5 py-10. Ver UPGRADE.mdw-4 h-4 → w-[15px] h-[15px]. Ver UPGRADE.mdpl-[11px] no lugar de pl-3. Ver UPGRADE.mdborder border-outline-variant no lugar do ring-1, sombra do mockup, raio 10 px e p-1.5. Ver UPGRADE.mdpx-4 py-2.5 → px-2.5 py-2 rounded-[7px]. Ver UPGRADE.mdw-8 h-8 rounded-lg → min-w-[38px] h-[38px] rounded-[9px], com borda border-outline-variant fora da página atual. Ver UPGRADE.mdw-64 → w-[246px] com border-r no lugar da sombra lateral, textos por token de tema; o default de sidebar-width da topbar passa de 16rem a 246px. Ver UPGRADE.mdrounded-full → rounded-[999px]. Ver UPGRADE.mdmd:px-5 → md:px-[22px]. Ver UPGRADE.mdclass: os 67 componentes de template aplicam o class do consumidor num único elemento raiz, sem repetir o atributo em outro elemento. Antes, 16 deles descartavam o class ou o mandavam para um elemento internobg-surface-container-lowest), rating (text-outline-variant), toast-container (fundos sólidos do botão), tooltip (bg-inverse-surface text-surface) e upload deixam de usar literais slate/gray/red/emerald/whitesm, md e lg do botão com texto tinham altura por padding vertical, raio e borda do outline fora do mockupmd ficava 1 px menor que o do mockupModal::SIZES não tinha as larguras dos modais do mockup, e o painel tinha raio e sombra diferentesuppercase/tracking-wider e tinha raio, padding e borda fora do mockup$errors16px 12pxring, sombra, raio e padding fora do mockuprounded-full do [@theme](https://github.com/theme)) no lugar de pílulaModal::SIZES: chaves md-lg (600 px), xl (820 px), 2xl (1080 px) e 3xl (980 px), além de sm, md, lg e fullscreensize="field": Button::SIZES['field'] (40 px, a altura do campo, com texto ou icon-only) e Button::GLYPH_SIZES['field'] (text-[14px])Button::ICON_ONLY_GLYPH_SIZES: glifo do botão só de ícone por size (sm 14, md 15, field 14, lg 18 px); sem icon-only vale GLYPH_SIZEStext-case do badge: Badge::TEXT_CASES = ['upper', 'normal'], default upper; text-case="normal" tira uppercase e tracking-widerstate do select: Select::STATES = ['error'], mesmo nome e valor do state do input; state="error" pinta a borda de erro sem depender do $errorsstate do card: Card::STATES = ['error']; state="error" troca a borda por border-error/34size do empty-state: EmptyState::SIZES = ['md', 'sm'], default md; sm é o vazio de uma linhabordered do empty-state: moldura tracejada border-primary/18 com raio 10 pxflush da table: tabela sem moldura, para uso direto dentro de um cardlocal/testing, fallback com Log::warning nos demais)headerClass e footerClass para o consumidor sobrescrever classes do header/footer sem reimplementar o componentefooterClasses() (paridade com headerClasses())[@custom-variant](https://github.com/custom-variant) dark (&:where(.dark, .dark *)) no jetax.css — habilita class-based dark mode no pacote, sem depender da app consumidora declarar:root { --jetax-* } (42 tokens duplicados, sem uso). :root.dark agora sobrescreve --color-*, fazendo classes Tailwind (bg-primary, text-on-surface, etc.) responderem ao tema automaticamente--color-primary/--color-secondary em dark passam a #0D99FF; surface containers, outline e status colors realinhadosbg-[#161B2A] em dark, header com tipografia uppercase/tracking e separador sutildark:bg-sidebar/80), hovers e ícones alinhados ao design CRMbg-white sólidos, bg-slate-*, bg-gray-* e hex hardcodes legacydocs-layout: <body> ganha text-on-surface font-body antialiased para evitar texto invisível em dark modedark:text-[#hex] removidos--jetax-* (duplicação pura — nunca consumidos no pacote)perPage para per_page — o regex do JS em pagination.blade.php procurava per_page=, então o replace nunca encontrava o parâmetro e a mudança de itens por página não tinha efeitoper_page no config alterado de 15 para 10 — 15 não está entre as opções do seletor ([10, 25, 50, 100]), fazendo com que nenhuma opção ficasse visualmente selecionada na carga inicialapplyPagination() agora chama ->withPath(url()->current()) — sem isso, $paginator->url(1) retornava um caminho relativo (ex: admin/tenants?page=1) e o window.location.href resolvia relativo ao diretório atual, causando path duplicado (/admin/admin/tenants → 404)applyPagination() agora chama ->appends(['per_page' => $perPage]) — sem isso, per_page= não estava na URL inicial e o regex do onchange nunca encontrava o parâmetro, fazendo a primeira troca de "Linhas por página" não ter efeitoPrimeira release oficial do Jetax — design system TALL Stack para Laravel.
x-jetax-layout), Auth Layout, Sidebar, Topbar, Page Headerclass e script anti-FOUCjetax:check para detectar views publicadas desatualizadasjetax_config() para leitura de configHow can I help you explore Laravel packages today?